<commit_before>//
//  Common.swift
//  ReactiveKit
//
//  Created by <NAME> on 14/04/16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import XCTest
import ReactiveKit

extension Event {

  func isEqualTo(_ event: Event<Element, Error>) -> Bool {

    switch (self, event) {
    case (.completed, .completed):
      return true
    case (.failed, .failed):
      return true
    case (.next(let left), .next(let right)):
      if let left = left as? Int, let right = right as? Int {
        return left == right
      } else if let left = left as? [Int], let right = right as? [Int] {
        return left == right
      } else if let left = left as? (Int?, Int), let right = right as? (Int?, Int) {
        return left.0 == right.0 && left.1 == right.1
      } else if let left = left as? String, let right = right as? String {
        return left == right
      } else if let left = left as? [String], let right = right as? [String] {
        return left == right
      } else {
        fatalError("Cannot compare that element type. \(left)")
      }
    default:
        return false
    }
  }
}

extension SignalProtocol {

  func expectNext(_ expectedElements: [Element],
                  expectation: XCTestExpectation? = nil,
                  file: StaticString = #file, line: UInt = #line) {
    expect(expectedElements.map { .next($0) } + [.completed], expectation: expectation, file: file, line: line)
  }

  func expect(_ expectedEvents: [Event<Element, Error>],
              expectation: XCTestExpectation? = nil,
              file: StaticString = #file, line: UInt = #line) {
    var eventsToProcess = expectedEvents
    var receivedEvents: [Event<Element, Error>] = []
    let _ = observe { event in
      receivedEvents.append(event)
      if eventsToProcess.count == 0 {
        XCTFail("Got more events than expected.")
        return
      }
      let expected = eventsToProcess.removeFirst()
      XCTAssert(event.isEqualTo(expected), "(Got \(receivedEvents) instead of \(expectedEvents))", file: file, line: line)
      if eventsToProcess.count == 0 {
        expectation?.fulfill()
      }
    }
  }
}

class Scheduler {
  private var availableRuns = 0
  private var scheduledBlocks: [() -> Void] = []
  private(set) var numberOfRuns = 0

  func context(_ block: @escaping () -> Void) {
    self.scheduledBlocks.append(block)
    tryRun()
  }

  func runOne() {
    guard availableRuns < Int.max else { return }
    availableRuns += 1
    tryRun()<commit_msg>Add expectAsync<commit_after>//
//  Common.swift
//  ReactiveKit
//
//  Created by <NAME> on 14/04/16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import XCTest
import ReactiveKit

extension Event {

  func isEqualTo(_ event: Event<Element, Error>) -> Bool {

    switch (self, event) {
    case (.completed, .completed):
      return true
    case (.failed, .failed):
      return true
    case (.next(let left), .next(let right)):
      if let left = left as? Int, let right = right as? Int {
        return left == right
      } else if let left = left as? [Int], let right = right as? [Int] {
        return left == right
      } else if let left = left as? (Int?, Int), let right = right as? (Int?, Int) {
        return left.0 == right.0 && left.1 == right.1
      } else if let left = left as? String, let right = right as? String {
        return left == right
      } else if let left = left as? [String], let right = right as? [String] {
        return left == right
      } else {
        fatalError("Cannot compare that element type. \(left)")
      }
    default:
        return false
    }
  }
}

extension SignalProtocol {

  func expectNext(_ expectedElements: [Element],
                  expectation: XCTestExpectation? = nil,
                  file: StaticString = #file, line: UInt = #line) {
    expect(expectedElements.map { .next($0) } + [.completed], expectation: expectation, file: file, line: line)
  }

  func expect(_ expectedEvents: [Event<Element, Error>],
              expectation: XCTestExpectation? = nil,
              file: StaticString = #file, line: UInt = #line) {
    var eventsToProcess = expectedEvents
    var receivedEvents: [Event<Element, Error>] = []
    let _ = observe { event in
      receivedEvents.append(event)
      if eventsToProcess.count == 0 {
        XCTFail("Got more events than expected.")
        return
      }
      let expected = eventsToProcess.removeFirst()
      XCTAssert(event.isEqualTo(expected), "(Got \(receivedEvents) instead of \(expectedEvents))", file: file, line: line)
      if eventsToProcess.count == 0 {
        expectation?.fulfill()
      }
    }
  }
  
  func expectNextAsync(_ expectedElements: [Element],
                       expectation: XCTestExpectation,
                       file: StaticString = #file, line: UInt = #line) {
    expectAsync(expectedElements.map { .next($0) } + [.completed], expectation: expectation, file: file, line: line)
  }
  
  func expectAsync(_ expectedEvents: [Event<Element, Error>],
                   expectation: XCTestExpectation,
                   file: StaticString = #file, line: UInt = #line) {
    var eventsToProcess = expectedEvents
    var receivedEvents: [Event<Element, Error>] = []
    let _ = observe { event in
      receivedEvents.append(event)
      if eventsToProcess.count == 0 {
        XCTFail("Got more events than expected.")
        return
      }
      let expected = eventsToProcess.removeFirst()
      XCTAssert(event.isEqualTo(expected), "(Got \(receivedEvents) instead of \(expectedEvents))", file: file, line: line)
      if eventsToProcess.count == 0 {
        expectation.fulfill()
      }
    }
  }
}

class Scheduler {
  private var availableRuns = 0
  private var scheduledBlocks: [() -> Void] = []
  private(set) var numberOfRuns = 0

  func context(_ block: @escaping () -> Void) {
    self.scheduledBlocks.append(block)
    tryRun()
  }

  func runOne() {
    guard availableRuns < Int.max else { return }
    availableRuns += 1
    tryRun()
{'fraction_non_alphanumeric': 0.12221112221112221, 'fraction_numerical': 0.00715950715950716, 'mean_word_length': 2.4702484113229346, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3813824', 'n_tokens_mistral': 1810, 'n_tokens_neox': 1732, 'n_words': 552}