//===--- StdlibUnittest.swift.gyb -----------------------------*- swift -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

%{
from gyb_stdlib_unittest_support import TRACE, stackTrace, trace
}%

import SwiftPrivate
import SwiftPrivatePthreadExtras
import SwiftPrivateLibcExtras

#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
import Darwin
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
import Glibc
#endif

#if _runtime(_ObjC)
import ObjectiveC
#endif

public struct SourceLoc {
  public let file: String
  public let line: UInt
  public let comment: String?

  public init(_ file: String, _ line: UInt, comment: String? = nil) {
    self.file = file
    self.line = line
    self.comment = comment
  }

  public func withCurrentLoc(
    _ file: String = #file, line: UInt = #line
  ) -> SourceLocStack {
    return SourceLocStack(self).with(SourceLoc(file, line))
  }
}

public struct SourceLocStack {
  let locs: [SourceLoc]

  public init() {
    locs = []
  }

  public init(_ loc: SourceLoc) {
    locs = [loc]
  }

  init(_locs: [SourceLoc]) {
    locs = _locs
  }

  var isEmpty: Bool {
    return locs.isEmpty
  }

  public func with(_ loc: SourceLoc) -> SourceLocStack {
    var locs = self.locs
    locs.append(loc)
    return SourceLocStack(_locs: locs)
  }

  public func pushIf(
    _ showFrame: Bool, file: String, line: UInt
  ) -> SourceLocStack {
    return showFrame ? self.with(SourceLoc(file, line)) : self
  }

  public func withCurrentLoc(
    file: String = #file, line: UInt = #line
  ) -> SourceLocStack {
    return with(SourceLoc(file, line))
  }

  public func print() {
    let top = locs.first!
    Swift.print("check failed at \(top.file), line \(top.line)")
    _printStackTrace(SourceLocStack(_locs: Array(locs.dropFirst())))
  }
}

func _printStackTrace(_ stackTrace: SourceLocStack?) {
  guard let s = stackTrace, !s.locs.isEmpty else { return }
  print("stacktrace:")
  for (i, loc) in s.locs.reversed().enumerated() {
    let comment = (loc.comment != nil) ? " ; \(loc.comment!)" : ""
    print("  #\(i): \(loc.file):\(loc.line)\(comment)")
  }
}

// FIXME: these variables should be atomic, since multiple threads can call
// `expect*()` functions.
var _anyExpectFailed = false
var _seenExpectCrash = false

/// Run `body` and expect a failure to happen.
///
/// The check passes iff `body` triggers one or more failures.
public func expectFailure(${TRACE}, invoking body: () -> Void) {
  let startAnyExpectFailed = _anyExpectFailed
  _anyExpectFailed = false
  body()
  let endAnyExpectFailed = _anyExpectFailed
  _anyExpectFailed = false
  expectTrue(
    endAnyExpectFailed, "running `body` should produce an expected failure",
    stackTrace: ${stackTrace}
  )
  _anyExpectFailed = _anyExpectFailed || startAnyExpectFailed
}

public func identity(_ element: OpaqueValue<Int>) -> OpaqueValue<Int> {
  return element
}

public func identityEq(_ element: MinimalEquatableValue) -> MinimalEquatableValue {
  return element
}

public func identityComp(_ element: MinimalComparableValue)
  -> MinimalComparableValue {
  return element
}

public func expectEqual<T : Equatable>(_ expected: T, _ actual: T, ${TRACE}) {
  expectEqualTest(expected, actual, ${trace}, showFrame: false) {$0 == $1}
}

public func expectEqual<T : Equatable, U : Equatable>(
  _ expected: (T, U), _ actual: (T, U), ${TRACE}) {
  expectEqualTest(expected.0, actual.0, ${trace}, showFrame: false) {$0 == $1}
  expectEqualTest(expected.1, actual.1, ${trace}, showFrame: false) {$0 == $1}
}

public func expectEqual<T : Equatable, U : Equatable, V : Equatable>(
  _ expected: (T, U, V), _ actual: (T, U, V), ${TRACE}) {
  expectEqualTest(expected.0, actual.0, ${trace}, showFrame: false) {$0 == $1}
  expectEqualTest(expected.1, actual.1, ${trace}, showFrame: false) {$0 == $1}
  expectEqualTest(expected.2, actual.2, ${trace}, showFrame: false) {$0 == $1}
}

public func expectationFailure(
  _ reason: String,
  trace message: String,
  stackTrace: SourceLocStack) {
  _anyExpectFailed = true
  stackTrace.print()
  print(reason, terminator: reason == "" ? "" : "\n")
  print(message, terminator: message == "" ? "" : "\n")
}

// Renamed to avoid collision with expectEqual(_, _, TRACE).
// See <rdar://26058520> Generic type constraints incorrectly applied to
// functions with the same name
public func expectEqualTest<T>(
  _ expected: T, _ actual: T, ${TRACE}, sameValue equal: (T, T) -> Bool
) {
  if !equal(expected, actual) {
    expectationFailure(
      "expected: \(String(reflecting: expected)) (of type \(String(reflecting: type(of: expected))))\n"
      + "actual: \(String(reflecting: actual)) (of type \(String(reflecting: type(of: actual))))",
      trace: ${trace}
    )
  }
}

public func expectNotEqual<T : Equatable>(_ expected: T, _ actual: T, ${TRACE}) {
  if expected == actual {
    expectationFailure(
      "unexpected value: \"\(actual)\" (of type \(String(reflecting: type(of: actual))))",
      trace: ${trace}
    )
  }
}

// Cannot write a sane set of overloads using generics because of:
// <rdar://problem/17015923> Array -> NSArray implicit conversion insanity
public func expectOptionalEqual<T : Equatable>(
  _ expected: T, _ actual: T?, ${TRACE}
) {
  expectOptionalEqual(expected, actual, ${trace}, showFrame: false) {$0 == $1}
}

public func expectOptionalEqual<T>(
  _ expected: T, _ actual: T?, ${TRACE}, sameValue equal: (T, T) -> Bool
) {
  if (actual == nil) || !equal(expected, actual!) {
    expectationFailure(
      "expected: \"\(expected)\" (of type \(String(reflecting: type(of: expected))))\n"
      + "actual: \"\(actual)\" (of type \(String(reflecting: type(of: actual))))",
      trace: ${trace})
  }
}

public func expectEqual<T : Equatable>(_ expected: T?, _ actual: T?, ${TRACE}) {
  if expected != actual {
    expectationFailure(
      "expected: \"\(expected)\" (of type \(String(reflecting: type(of: expected))))\n"
      + "actual: \"\(actual)\" (of type \(String(reflecting: type(of: actual))))",
      trace: ${trace})
  }
}

public func expectNotEqual<T : Equatable>(
  _ expected: T?, _ actual: T?, ${TRACE}
) {
  if expected == actual {
    expectationFailure(
      "unexpected value: \"\(actual)\" (of type \(String(reflecting: type(of: actual))))",
      trace: ${trace})
  }
}

// Array<T> is not Equatable if T is.  Provide additional overloads.
// Same for Dictionary.
%for (Generic, EquatableType) in [
%    ('<T : Equatable>', 'ContiguousArray<T>'),
%    ('<T : Equatable>', 'ArraySlice<T>'),
%    ('<T : Equatable>', 'Array<T>'),
%    ('<T, U : Equatable>', 'Dictionary<T, U>')]:

public func expectEqual${Generic}(
  _ expected: ${EquatableType}, _ actual: ${EquatableType}, ${TRACE}
) {
  expectEqualTest(expected, actual, ${trace}, showFrame: false) { $0 == $1 }
}

public func expectOptionalEqual${Generic}(
    _ expected: ${EquatableType}, _ actual: ${EquatableType}?, ${TRACE}) {
  if (actual == nil) || expected != actual! {
    expectationFailure(
      "expected: \"\(expected)\" (of type \(String(reflecting: type(of: expected))))"
      + "actual: \"\(actual)\" (of type \(String(reflecting: type(of: actual))))",
      trace: ${trace})
  }
}

%end

public func expectLT<T : Comparable>(_ lhs: T, _ rhs: T, ${TRACE}) {
  if !(lhs < rhs) {
    expectationFailure("\(lhs) < \(rhs)", trace: ${trace})
  }
}

public func expectLE<T : Comparable>(_ lhs: T, _ rhs: T, ${TRACE}) {
  if !(lhs <= rhs) {
    expectationFailure("\(lhs) <= \(rhs)", trace: ${trace})
  }
}

public func expectGT<T : Comparable>(_ lhs: T, _ rhs: T, ${TRACE}) {
  if !(lhs > rhs) {
    expectationFailure("\(lhs) > \(rhs)", trace: ${trace})
  }
}

public func expectGE<T : Comparable>(_ lhs: T, _ rhs: T, ${TRACE}) {
  if !(lhs >= rhs) {
    expectationFailure("\(lhs) >= \(rhs)", trace: ${trace})
  }
}

% for OtherRange in ['Range', 'CountableRange', 'ClosedRange', 'CountableClosedRange']:
extension Range
%   if 'Countable' in OtherRange:
  where
  Bound : Comparable & _Strideable, Bound.Stride : SignedInteger
%   end
{
  internal func _contains(_ other: ${OtherRange}<Bound>) -> Bool {
    if other.lowerBound < lowerBound { return false }
%   if 'Closed' in OtherRange:
    if upperBound <= other.upperBound { return false }
%   else:
    if upperBound < other.upperBound { return false }
%   end
    return true
  }
}
% end

% for Range in ['Range', 'CountableRange', 'ClosedRange', 'CountableClosedRange']:
public func expectTrapping<Bound>(
  _ point: Bound, in range: ${Range}<Bound>, ${TRACE}
) {
  if !range.contains(point) {
    expectationFailure("\(point) in \(range)", trace: ${trace})
    _trappingExpectationFailedCallback()
  }
}

public func expectTrapping<Bound>(
  _ subRange: ${Range}<Bound>, in range: Range<Bound>, ${TRACE}
) {
  if !range._contains(subRange) {
    expectationFailure("\(subRange) in \(range)", trace: ${trace})
    _trappingExpectationFailedCallback()
  }
}
% end

extension ClosedRange {
  internal func _contains(_ other: ClosedRange<Bound>) -> Bool {
    if other.lowerBound < lowerBound { return false }
    if upperBound < other.upperBound { return false }
    return true
  }
}

public func expectTrapping<Bound>(
  _ subRange: ClosedRange<Bound>, in range: ClosedRange<Bound>, ${TRACE}
) {
  if !range._contains(subRange) {
    expectationFailure("\(subRange) in \(range)", trace: ${trace})
    _trappingExpectationFailedCallback()
  }
}

public func expectType<T>(_: T.Type, _ x: inout T) {}
public func expectEqualType<T>(_: T.Type, _: T.Type) {}

public func expectSequenceType<X : Sequence>(_ x: X) -> X
  where
  X.SubSequence : Sequence,
  X.SubSequence.Iterator.Element == X.Iterator.Element,
  X.SubSequence.SubSequence == X.SubSequence {
  return x
}

% for Mutable in ['', 'Mutable']:
public func expect${Mutable}CollectionType<X : ${Mutable}Collection>(
  _ x: X.Type
) where
  // FIXME(ABI)(compiler limitation): there should be no constraints in
  // the 'where' clause, all of these should be required by the protocol.
  X.SubSequence : Collection,
  X.SubSequence.Iterator.Element == X.Iterator.Element,
  X.SubSequence.Index == X.Index,
  // X.SubSequence.Indices == X.Indices, // FIXME: can't have this constraint now.
  X.SubSequence.SubSequence == X.SubSequence,
  X.Indices : Collection,
  X.Indices.Iterator.Element == X.Index,
  X.Indices.Index == X.Index,
  X.Indices.SubSequence == X.Indices {}
% end

/// A slice is a `Collection` that when sliced returns an instance of
/// itself.
public func expectSliceType<X : Collection>(
  _ sliceType: X.Type
) where X.SubSequence == X {}

/// A mutable slice is a `MutableCollection` that when sliced returns an
/// instance of itself.
public func expectMutableSliceType<X : MutableCollection>(
  _ mutableSliceType: X.Type
) where X.SubSequence == X {}

/// Check that all associated types of a `Sequence` are what we expect them
/// to be.
public func expectSequenceAssociatedTypes<X : Sequence>(
  sequenceType: X.Type,
  iteratorType: X.Iterator.Type,
  subSequenceType: X.SubSequence.Type
) where
  // FIXME(ABI)(compiler limitation): there should be no constraints in
  // the 'where' clause, all of these should be required by the protocol.
  X.SubSequence : Sequence,
  X.SubSequence.Iterator.Element == X.Iterator.Element,
  // X.SubSequence.Indices == X.Indices, // FIXME(ABI): can't have this constraint now.
  X.SubSequence.SubSequence == X.SubSequence {}

/// Check that all associated types of a `Collection` are what we expect them
/// to be.
public func expectCollectionAssociatedTypes<X : Collection>(
  collectionType: X.Type,
  iteratorType: X.Iterator.Type,
  subSequenceType: X.SubSequence.Type,
  indexType: X.Index.Type,
  indexDistanceType: X.IndexDistance.Type,
  indicesType: X.Indices.Type
) where
  // FIXME(ABI)(compiler limitation): there should be no constraints in
  // the 'where' clause, all of these should be required by the protocol.
  X._Element == X.Iterator.Element,
  X.SubSequence : Collection,
  X.SubSequence.Iterator.Element == X.Iterator.Element,
  X.SubSequence.Index == X.Index,
  // X.SubSequence.Indices == X.Indices, // FIXME(ABI): can't have this constraint now.
  X.SubSequence.SubSequence == X.SubSequence,
  X.Indices : Collection,
  X.Indices.Iterator.Element == X.Index,
  X.Indices.Index == X.Index,
  X.Indices.SubSequence == X.Indices {}

/// Check that all associated types of a `BidirectionalCollection` are what we
/// expect them to be.
public func expectBidirectionalCollectionAssociatedTypes<X : BidirectionalCollection>(
  collectionType: X.Type,
  iteratorType: X.Iterator.Type,
  subSequenceType: X.SubSequence.Type,
  indexType: X.Index.Type,
  indexDistanceType: X.IndexDistance.Type,
  indicesType: X.Indices.Type
) where
  // FIXME(ABI)(compiler limitation): there should be no constraints in
  // the 'where' clause, all of these should be required by the protocol.
  X._Element == X.Iterator.Element,
  X.SubSequence : BidirectionalCollection,
  X.SubSequence.Iterator.Element == X.Iterator.Element,
  X.SubSequence.Index == X.Index,
  // X.SubSequence.Indices == X.Indices, // FIXME(ABI): can't have this constraint now.
  X.SubSequence.SubSequence == X.SubSequence,
  X.Indices : BidirectionalCollection,
  X.Indices.Iterator.Element == X.Index,
  X.Indices.Index == X.Index,
  X.Indices.SubSequence == X.Indices {}

/// Check that all associated types of a `RandomAccessCollection` are what we
/// expect them to be.
public func expectRandomAccessCollectionAssociatedTypes<X : RandomAccessCollection>(
  collectionType: X.Type,
  iteratorType: X.Iterator.Type,
  subSequenceType: X.SubSequence.Type,
  indexType: X.Index.Type,
  indexDistanceType: X.IndexDistance.Type,
  indicesType: X.Indices.Type
) where
  // FIXME(ABI)(compiler limitation): there should be no constraints in
  // the 'where' clause, all of these should be required by the protocol.
  X._Element == X.Iterator.Element,
  X.SubSequence : RandomAccessCollection,
  X.SubSequence.Iterator.Element == X.Iterator.Element,
  X.SubSequence.Index == X.Index,
  // X.SubSequence.Indices == X.Indices, // FIXME(ABI): can't have this constraint now.
  X.SubSequence.SubSequence == X.SubSequence,
  X.Indices : RandomAccessCollection,
  X.Indices.Iterator.Element == X.Index,
  X.Indices.Index == X.Index,
  X.Indices.SubSequence == X.Indices {}
  
public struct AssertionResult : CustomStringConvertible {
  init(isPass: Bool) {
    self._isPass = isPass
  }

  public func withDescription(_ description: String) -> AssertionResult {
    var result = self
    result.description += description
    return result
  }

  let _isPass: Bool

  public var description: String = ""
}

public func assertionSuccess() -> AssertionResult {
  return AssertionResult(isPass: true)
}

public func assertionFailure() -> AssertionResult {
  return AssertionResult(isPass: false)
}

public func expectUnreachable(${TRACE}) {
  expectationFailure("this code should not be executed", trace: ${trace})
}

public func expectUnreachableCatch(_ error: Error, ${TRACE}) {
  expectationFailure(
    "error should not be thrown: \"\(error)\"", trace: ${trace})
}

public func expectTrue(_ actual: AssertionResult, ${TRACE}) {
  if !actual._isPass {
    expectationFailure("expected: true", trace: ${trace})
  }
}

public func expectFalse(_ actual: AssertionResult, ${TRACE}) {
  if actual._isPass {
    expectationFailure("expected: false", trace: ${trace})
  }
}

public func expectTrue(_ actual: Bool, ${TRACE}) {
  if !actual {
    expectationFailure("expected: true", trace: ${trace})
  }
}

public func expectFalse(_ actual: Bool, ${TRACE}) {
  if actual {
    expectationFailure("expected: false", trace: ${trace})
  }
}

public func expectEmpty<T>(_ value: T?, ${TRACE}) {
  if value != nil {
    expectationFailure(
      "expected optional to be empty\nactual: \"\(value)\"", trace: ${trace})
  }
}

@discardableResult
public func expectNotEmpty<T>(_ value: T?, ${TRACE}) -> T? {
  if value == nil {
    expectationFailure("expected optional to be non-empty", trace: ${trace})
  }
  return value
}

public func expectCrashLater() {
  print("\(_stdlibUnittestStreamPrefix);expectCrash;\(_anyExpectFailed)")

  var stderr = _Stderr()
  print("\(_stdlibUnittestStreamPrefix);expectCrash", to: &stderr)

  _seenExpectCrash = true
}

func _defaultTestSuiteFailedCallback() {
  abort()
}

var _testSuiteFailedCallback: () -> Void = _defaultTestSuiteFailedCallback

public func _setTestSuiteFailedCallback(_ callback: @escaping () -> Void) {
  _testSuiteFailedCallback = callback
}

func _defaultTrappingExpectationFailedCallback() {
  abort()
}

var _trappingExpectationFailedCallback: () -> Void
  = _defaultTrappingExpectationFailedCallback

public func _setTrappingExpectationFailedCallback(callback: @escaping () -> Void) {
  _trappingExpectationFailedCallback = callback
}

extension ProcessTerminationStatus {
  var isSwiftTrap: Bool {
    switch self {
    case .exit(_):
      return false
    case .signal(let signal):
      return CInt(signal) == SIGILL || CInt(signal) == SIGTRAP
    default:
      // This default case is needed for standard library builds where
      // resilience is enabled
      return false
    }
  }
}

func _stdlib_getline() -> String? {
  var result: [UInt8] = []
  while true {
    let c = getchar()
    if c == EOF {
      if result.isEmpty {
        return nil
      }
      return String._fromWellFormedCodeUnitSequence(UTF8.self, input: result)
    }
    if c == CInt(UnicodeScalar("\n").value) {
      return String._fromWellFormedCodeUnitSequence(UTF8.self, input: result)
    }
    result.append(UInt8(c))
  }
}

func _printDebuggingAdvice(_ fullTestName: String) {
  print("To debug, run:")
  var invocation = [CommandLine.arguments[0]]
  let interpreter = getenv("SWIFT_INTERPRETER")
  if interpreter != nil {
    if let interpreterCmd = String(validatingUTF8: interpreter!) {
        invocation.insert(interpreterCmd, at: 0)
    }
  }
  print("$ \(invocation.joined(separator: " ")) " +
    "--stdlib-unittest-in-process --stdlib-unittest-filter \"\(fullTestName)\"")
}

var _allTestSuites: [TestSuite] = []
var _testSuiteNameToIndex: [String : Int] = [:]

let _stdlibUnittestStreamPrefix = "__STDLIB_UNITTEST__"
let _crashedPrefix = "CRASHED:"

@_silgen_name("swift_stdlib_installTrapInterceptor")
func _stdlib_installTrapInterceptor()

#if _runtime(_ObjC)
@objc protocol _StdlibUnittestNSException {
  @objc optional var name: AnyObject { get }
}
#endif

func _childProcess() {
  _stdlib_installTrapInterceptor()

#if _runtime(_ObjC)
  objc_setUncaughtExceptionHandler {
    let exception = $0! as AnyObject
    var stderr = _Stderr()
    let maybeNSException =
        unsafeBitCast(exception, to: _StdlibUnittestNSException.self)
    if let name = maybeNSException.name {
      print("*** [StdlibUnittest] Terminating due to uncaught exception " +
        "\(name): \(exception)",
        to: &stderr)
    } else {
      print("*** [StdlibUnittest] Terminating due to uncaught exception: " +
        "\(exception)",
        to: &stderr)      
    }
  }
#endif

  while let line = _stdlib_getline() {
    let parts = line._split(separator: ";")

    if parts[0] == _stdlibUnittestStreamPrefix {
      precondition(parts[1] == "shutdown")
      return
    }

    let testSuiteName = parts[0]
    let testName = parts[1]
    var testParameter: Int?
    if parts.count > 2 {
      testParameter = Int(parts[2])!
    } else {
      testParameter = nil
    }

    let testSuite = _allTestSuites[_testSuiteNameToIndex[testSuiteName]!]
    _anyExpectFailed = false
    testSuite._runTest(name: testName, parameter: testParameter)

    print("\(_stdlibUnittestStreamPrefix);end;\(_anyExpectFailed)")

    var stderr = _Stderr()
    print("\(_stdlibUnittestStreamPrefix);end", to: &stderr)

    if !testSuite._testByName(testName).canReuseChildProcessAfterTest {
      return
    }
  }
}

struct _ParentProcess {
  internal var _pid: pid_t? = nil
  internal var _childStdin: _FDOutputStream = _FDOutputStream(fd: -1)
  internal var _childStdout: _FDInputStream = _FDInputStream(fd: -1)
  internal var _childStderr: _FDInputStream = _FDInputStream(fd: -1)

  internal var _runTestsInProcess: Bool
  internal var _filter: String?
  internal var _args: [String]

  init(runTestsInProcess: Bool, args: [String], filter: String?) {
    self._runTestsInProcess = runTestsInProcess
    self._filter = filter
    self._args = args
  }

  mutating func _spawnChild() {
    let params = ["--stdlib-unittest-run-child"] + _args
    let (pid, childStdinFD, childStdoutFD, childStderrFD) = spawnChild(params)
    _pid = pid
    _childStdin = _FDOutputStream(fd: childStdinFD)
    _childStdout = _FDInputStream(fd: childStdoutFD)
    _childStderr = _FDInputStream(fd: childStderrFD)
  }

  mutating func _waitForChild() -> ProcessTerminationStatus {
    let status = posixWaitpid(_pid!)
    _pid = nil
    _childStdin.close()
    _childStdout.close()
    _childStderr.close()
    _childStdin = _FDOutputStream(fd: -1)
    _childStdout = _FDInputStream(fd: -1)
    _childStderr = _FDInputStream(fd: -1)
    return status
  }

  internal mutating func _readFromChild(
    onStdoutLine: (String) -> (done: Bool, Void),
    onStderrLine: (String) -> (done: Bool, Void)
  ) {
    var readfds = _stdlib_fd_set()
    var writefds = _stdlib_fd_set()
    var errorfds = _stdlib_fd_set()
    var done = false
    while !((_childStdout.isEOF && _childStderr.isEOF) || done) {
      readfds.zero()
      errorfds.zero()
      if !_childStdout.isEOF {
        readfds.set(_childStdout.fd)
        errorfds.set(_childStdout.fd)
      }
      if !_childStderr.isEOF {
        readfds.set(_childStderr.fd)
        errorfds.set(_childStderr.fd)
      }
      var ret: CInt
      repeat {
        ret = _stdlib_select(&readfds, &writefds, &errorfds, nil)
      } while ret == -1  &&  errno == EINTR
      if ret <= 0 {
        fatalError("select() returned an error")
      }
      if readfds.isset(_childStdout.fd) || errorfds.isset(_childStdout.fd) {
        _childStdout.read()
        while let line = _childStdout.getline() {
          (done: done, ()) = onStdoutLine(line)
        }
        continue
      }
      if readfds.isset(_childStderr.fd) || errorfds.isset(_childStderr.fd) {
        _childStderr.read()
        while let line = _childStderr.getline() {
          (done: done, ()) = onStderrLine(line)
        }
        continue
      }
    }
  }

  /// Returns the values of the corresponding variables in the child process.
  internal mutating func _runTestInChild(
    _ testSuite: TestSuite,
    _ testName: String,
    parameter: Int?
  ) -> (anyExpectFailed: Bool, seenExpectCrash: Bool,
        status: ProcessTerminationStatus?,
        crashStdout: [String], crashStderr: [String]) {
    if _pid == nil {
      _spawnChild()
    }

    print("\(testSuite.name);\(testName)", terminator: "", to: &_childStdin)
    if let parameter = parameter {
      print(";", terminator: "", to: &_childStdin)
      print(parameter, terminator: "", to: &_childStdin)
    }
    print("", to: &_childStdin)

    let currentTest = testSuite._testByName(testName)
    if let stdinText = currentTest.stdinText {
      print(stdinText, terminator: "", to: &_childStdin)
    }
    if currentTest.stdinEndsWithEOF {
      _childStdin.close()
    }

    var stdoutSeenCrashDelimiter = false
    var stderrSeenCrashDelimiter = false
    var stdoutEnd = false
    var stderrEnd = false
    var capturedCrashStdout: [String] = []
    var capturedCrashStderr: [String] = []
    var anyExpectFailedInChild = false

    func processLine(_ line: String, isStdout: Bool) -> (done: Bool, Void) {
      var line = line
      if let index = findSubstring(line, _stdlibUnittestStreamPrefix) {
        let controlMessage =
            line[index..<line.endIndex]._split(separator: ";")
        switch controlMessage[1] {
        case "expectCrash":
          if isStdout {
            stdoutSeenCrashDelimiter = true
            anyExpectFailedInChild = controlMessage[2] == "true"
          } else {
            stderrSeenCrashDelimiter = true
          }
        case "end":
          if isStdout {
            stdoutEnd = true
            anyExpectFailedInChild = controlMessage[2] == "true"
          } else {
            stderrEnd = true
          }
        default:
          fatalError("unexpected message")
        }
        line = line[line.startIndex..<index]
        if line.isEmpty {
          return (done: stdoutEnd && stderrEnd, ())
        }
      }
      if isStdout {
        if stdoutSeenCrashDelimiter {
          capturedCrashStdout.append(line)
        }
      } else {
        if stderrSeenCrashDelimiter {
          capturedCrashStderr.append(line)
          if findSubstring(line, _crashedPrefix) != nil {
            line = "OK: saw expected \"\(line.lowercased())\""
          }
        }
      }
      if isStdout {
        print("stdout>>> \(line)")
      } else {
        print("stderr>>> \(line)")
      }
      return (done: stdoutEnd && stderrEnd, ())
    }

    _readFromChild(
      onStdoutLine: { processLine($0, isStdout: true) },
      onStderrLine: { processLine($0, isStdout: false) })

    // Check if the child has sent us "end" markers for the current test.
    if stdoutEnd && stderrEnd {
      var status: ProcessTerminationStatus? = nil
      if !testSuite._testByName(testName).canReuseChildProcessAfterTest {
        status = _waitForChild()
        switch status! {
        case .exit(0):
          status = nil
        default:
          ()
        }
      }
      return (
        anyExpectFailedInChild,
        stdoutSeenCrashDelimiter || stderrSeenCrashDelimiter, status,
        capturedCrashStdout, capturedCrashStderr)
    }

    // We reached EOF on stdout and stderr and we did not see "end" markers, so
    // it looks like child crashed (of course it could have closed the file
    // descriptors, but we assume it did not, since it prevent further
    // communication with the parent).
    let status = _waitForChild()
    return (
      anyExpectFailedInChild,
      stdoutSeenCrashDelimiter || stderrSeenCrashDelimiter, status,
      capturedCrashStdout, capturedCrashStderr)
  }

  internal mutating func _shutdownChild() -> (failed: Bool, Void) {
    if _pid == nil {
      // The child process is not running.  Report that it didn't fail during
      // shutdown.
      return (failed: false, ())
    }
    print("\(_stdlibUnittestStreamPrefix);shutdown", to: &_childStdin)

    var childCrashed = false

    func processLine(_ line: String, isStdout: Bool) -> (done: Bool, Void) {
      if isStdout {
        print("stdout>>> \(line)")
      } else {
        if findSubstring(line, _crashedPrefix) != nil {
          childCrashed = true
        }
        print("stderr>>> \(line)")
      }
      return (done: false, ())
    }

    _readFromChild(
      onStdoutLine: { processLine($0, isStdout: true) },
      onStderrLine: { processLine($0, isStdout: false) })

    let status = _waitForChild()
    switch status {
    case .exit(0):
      return (failed: childCrashed, ())
    default:
      print("Abnormal child process termination: \(status).")
      return (failed: true, ())
    }
  }

  internal enum _TestStatus {
    case skip([TestRunPredicate])
    case pass
    case fail
    case uxPass
    case xFail
  }

  internal mutating func runOneTest(
    fullTestName: String,
    testSuite: TestSuite,
    test t: TestSuite._Test,
    testParameter: Int?
  ) -> _TestStatus {
    let activeSkips = t.getActiveSkipPredicates()
    if !activeSkips.isEmpty {
      return .skip(activeSkips)
    }

    let activeXFails = t.getActiveXFailPredicates()
    let expectXFail = !activeXFails.isEmpty
    let activeXFailsText = expectXFail ? " (XFAIL: \(activeXFails))" : ""
    print("[ RUN      ] \(fullTestName)\(activeXFailsText)")

    var expectCrash = false
    var childTerminationStatus: ProcessTerminationStatus? = nil
    var crashStdout: [String] = []
    var crashStderr: [String] = []
    if _runTestsInProcess {
      if t.stdinText != nil {
        print("The test \(fullTestName) requires stdin input and can't be run in-process, marking as failed")
        _anyExpectFailed = true
      } else {
        _anyExpectFailed = false
        testSuite._runTest(name: t.name, parameter: testParameter)
      }
    } else {
      (_anyExpectFailed, expectCrash, childTerminationStatus, crashStdout,
       crashStderr) =
        _runTestInChild(testSuite, t.name, parameter: testParameter)
    }

    // Determine if the test passed, not taking XFAILs into account.
    var testPassed = false
    switch (childTerminationStatus, expectCrash) {
    case (.none, false):
      testPassed = !_anyExpectFailed

    case (.none, true):
      testPassed = false
      print("expecting a crash, but the test did not crash")

    case (.some(_), false):
      testPassed = false
      print("the test crashed unexpectedly")

    case (.some(_), true):
      testPassed = !_anyExpectFailed
    }
    if testPassed && t.crashOutputMatches.count > 0 {
      // If we still think that the test passed, check if the crash
      // output matches our expectations.
      let crashOutput = crashStdout + crashStderr
      for expectedSubstring in t.crashOutputMatches {
        var found = false
        for s in crashOutput {
          if findSubstring(s, expectedSubstring) != nil {
            found = true
            break
          }
        }
        if !found {
          print("did not find expected string after crash: \(expectedSubstring.debugDescription)")
          testPassed = false
        }
      }
    }

    // Apply XFAILs.
    switch (testPassed, expectXFail) {
    case (true, false):
      return .pass

    case (true, true):
      return .uxPass

    case (false, false):
      return .fail

    case (false, true):
      return .xFail
    }
  }

  mutating func run() {
    if let filter = _filter {
      print("StdlibUnittest: using filter: \(filter)")
    }
    for testSuite in _allTestSuites {
      var uxpassedTests: [String] = []
      var failedTests: [String] = []
      var skippedTests: [String] = []
      for t in testSuite._tests {
        for testParameter in t.parameterValues {
          var testName = t.name
          if let testParameter = testParameter {
            testName += "/"
            testName += String(testParameter)
          }
          let fullTestName = "\(testSuite.name).\(testName)"
          if let filter = _filter,
             findSubstring(fullTestName, filter) == nil {

            continue
          }

          switch runOneTest(
            fullTestName: fullTestName,
            testSuite: testSuite,
            test: t,
            testParameter: testParameter
          ) {
          case .skip(let activeSkips):
            skippedTests.append(testName)
            print("[ SKIP     ] \(fullTestName) (skip: \(activeSkips))")

          case .pass:
            print("[       OK ] \(fullTestName)")

          case .uxPass:
            uxpassedTests.append(testName)
            print("[   UXPASS ] \(fullTestName)")

          case .fail:
            failedTests.append(testName)
            print("[     FAIL ] \(fullTestName)")

          case .xFail:
            print("[    XFAIL ] \(fullTestName)")
          }
        }
      }

      if !uxpassedTests.isEmpty || !failedTests.isEmpty {
        print("\(testSuite.name): Some tests failed, aborting")
        print("UXPASS: \(uxpassedTests)")
        print("FAIL: \(failedTests)")
        print("SKIP: \(skippedTests)")
        if !uxpassedTests.isEmpty {
          _printDebuggingAdvice(uxpassedTests[0])
        }
        if !failedTests.isEmpty {
          _printDebuggingAdvice(failedTests[0])
        }
        _testSuiteFailedCallback()
      } else {
        print("\(testSuite.name): All tests passed")
      }
    }
    let (failed: failedOnShutdown, ()) = _shutdownChild()
    if failedOnShutdown {
      print("The child process failed during shutdown, aborting.")
      _testSuiteFailedCallback()
    }
  }
}

// Track repeated calls to runAllTests() and/or runNoTests().
// Complain if a file runs no tests without calling runNoTests().
struct PersistentState {
  static var runAllTestsWasCalled: Bool = false
  static var runNoTestsWasCalled: Bool = false
  static var ranSomething: Bool = false
  static var complaintInstalled = false

  static func complainIfNothingRuns() {
    if !complaintInstalled {
      complaintInstalled = true
      atexit {
        if !PersistentState.ranSomething {
          print("Ran no tests and runNoTests() was not called. Aborting. ")
          print("Did you forget to call runAllTests()?")
          _testSuiteFailedCallback()
        }
      }
    }
  }
}


// Call runNoTests() if you want to deliberately run no tests.
public func runNoTests() {
  if PersistentState.runAllTestsWasCalled {
    print("runNoTests() called after runAllTests(). Aborting.")
    _testSuiteFailedCallback()
    return
  }
  if PersistentState.runNoTestsWasCalled {
    print("runNoTests() called twice. Aborting.")
    _testSuiteFailedCallback()
    return
  }
  PersistentState.runNoTestsWasCalled = true
  PersistentState.ranSomething = true
}

public func runAllTests() {
  if PersistentState.runNoTestsWasCalled {
    print("runAllTests() called after runNoTests(). Aborting.")
    _testSuiteFailedCallback()
    return
  }
  if PersistentState.runAllTestsWasCalled {
    print("runAllTests() called twice. Aborting.")
    _testSuiteFailedCallback()
    return
  }
  PersistentState.runAllTestsWasCalled = true
  PersistentState.ranSomething = true

#if _runtime(_ObjC)
  autoreleasepool {
    _stdlib_initializeReturnAutoreleased()
  }
#endif

  let _isChildProcess: Bool =
    CommandLine.arguments.contains("--stdlib-unittest-run-child")

  if _isChildProcess {
    _childProcess()
  } else {
    var runTestsInProcess: Bool = false
    var filter: String? = nil
    var args = [String]()
    var i = 0
    i += 1 // Skip the name of the executable.
    while i < CommandLine.arguments.count {
      let arg = CommandLine.arguments[i]
      if arg == "--stdlib-unittest-in-process" {
        runTestsInProcess = true
        i += 1
        continue
      }
      if arg == "--stdlib-unittest-filter" {
        filter = CommandLine.arguments[i + 1]
        i += 2
        continue
      }
      if arg == "--help" {
        let message =
"optional arguments:\n" +
"--stdlib-unittest-in-process\n" +
"                        run tests in-process without intercepting crashes.\n" +
"                        Useful for running under a debugger.\n" +
"--stdlib-unittest-filter FILTER-STRING\n" +
"                        only run tests whose names contain FILTER-STRING as\n" +
"                        a substring."
        print(message)
        return
      }

      // Pass through unparsed arguments to the child process.
      args.append(CommandLine.arguments[i])

      i += 1
    }

    var parent = _ParentProcess(
      runTestsInProcess: runTestsInProcess, args: args, filter: filter)
    parent.run()
  }
}

#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER

@_silgen_name("swift_leaks_startTrackingObjects")
func startTrackingObjects(_: UnsafePointer<CChar>)
@_silgen_name("swift_leaks_stopTrackingObjects")
func stopTrackingObjects(_: UnsafePointer<CChar>) -> Int

#endif

public final class TestSuite {
  public init(_ name: String) {
    self.name = name
    _precondition(
      _testNameToIndex[name] == nil,
      "test suite with the same name already exists")
    _allTestSuites.append(self)
    _testSuiteNameToIndex[name] = _allTestSuites.count - 1
    PersistentState.complainIfNothingRuns()
  }

  // This method is prohibited from inlining because inlining the test harness
  // into the test is not interesting from the runtime performance perspective.
  // And it does not really make the test cases more effectively at testing the
  // optimizer from a correctness prospective. On the contrary, it sometimes
  // severely affects the compile time of the test code.
  @inline(never)
  public func test(
    _ name: String,
    file: String = #file, line: UInt = #line,
    _ testFunction: @escaping () -> Void
  ) {
    _TestBuilder(testSuite: self, name: name, loc: SourceLoc(file, line))
    .code(testFunction)
  }

  // This method is prohibited from inlining because inlining the test harness
  // into the test is not interesting from the runtime performance perspective.
  // And it does not really make the test cases more effectively at testing the
  // optimizer from a correctness prospective. On the contrary, it sometimes
  // severely affects the compile time of the test code.
  @inline(never)
  public func test(
    _ name: String, file: String = #file, line: UInt = #line
  ) -> _TestBuilder {
    return _TestBuilder(testSuite: self, name: name, loc: SourceLoc(file, line))
  }

  public func setUp(_ code: @escaping () -> Void) {
    _precondition(_testSetUpCode == nil, "set-up code already set")
    _testSetUpCode = code
  }

  public func tearDown(_ code: @escaping () -> Void) {
    _precondition(_testTearDownCode == nil, "tear-down code already set")
    _testTearDownCode = code
  }

  func _runTest(name testName: String, parameter: Int?) {
    PersistentState.ranSomething = true
    for r in _allResettables {
      r.reset()
    }
    LifetimeTracked.instances = 0
    if let f = _testSetUpCode {
      f()
    }
    let test = _testByName(testName)

#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
    startTrackingObjects(name)
#endif

    switch test.code {
    case .single(let code):
      precondition(
        parameter == nil,
        "can't pass parameters to non-parameterized tests")
      code()
    case .parameterized(code: let code, _):
      code(parameter!)
    }

#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
    _ = stopTrackingObjects(name)
#endif

    if let f = _testTearDownCode {
      f()
    }
    expectEqual(
      0, LifetimeTracked.instances, "Found leaked LifetimeTracked instances.",
      file: test.testLoc.file, line: test.testLoc.line)
  }

  func _testByName(_ testName: String) -> _Test {
    return _tests[_testNameToIndex[testName]!]
  }

  internal enum _TestCode {
    case single(code: () -> Void)
    case parameterized(code: (Int) -> Void, count: Int)
  }

  internal struct _Test {
    let name: String
    let testLoc: SourceLoc
    let xfail: [TestRunPredicate]
    let skip: [TestRunPredicate]
    let stdinText: String?
    let stdinEndsWithEOF: Bool
    let crashOutputMatches: [String]
    let code: _TestCode

    /// Whether the test harness should stop reusing the child process after
    /// running this test.
    var canReuseChildProcessAfterTest: Bool {
      return stdinText == nil
    }

    func getActiveXFailPredicates() -> [TestRunPredicate] {
      return xfail.filter { $0.evaluate() }
    }

    func getActiveSkipPredicates() -> [TestRunPredicate] {
      return skip.filter { $0.evaluate() }
    }

    var parameterValues: [Int?] {
      switch code {
      case .single:
        return [nil]
      case .parameterized(code: _, count: let count):
        return (0..<count).map { $0 }
      }
    }
  }

  public struct _TestBuilder {
    let _testSuite: TestSuite
    var _name: String
    var _data: _Data = _Data()

    internal final class _Data {
      var _xfail: [TestRunPredicate] = []
      var _skip: [TestRunPredicate] = []
      var _stdinText: String? = nil
      var _stdinEndsWithEOF: Bool = false
      var _crashOutputMatches: [String] = []
      var _testLoc: SourceLoc? = nil
    }

    init(testSuite: TestSuite, name: String, loc: SourceLoc) {
      _testSuite = testSuite
      _name = name
      _data._testLoc = loc
    }

    public func xfail(_ predicate: TestRunPredicate) -> _TestBuilder {
      _data._xfail.append(predicate)
      return self
    }

    public func skip(_ predicate: TestRunPredicate) -> _TestBuilder {
      _data._skip.append(predicate)
      return self
    }

    public func stdin(_ stdinText: String, eof: Bool = false) -> _TestBuilder {
      _data._stdinText = stdinText
      _data._stdinEndsWithEOF = eof
      return self
    }

    public func crashOutputMatches(_ string: String) -> _TestBuilder {
      _data._crashOutputMatches.append(string)
      return self
    }

    internal func _build(_ testCode: _TestCode) {
      _testSuite._tests.append(
        _Test(
          name: _name, testLoc: _data._testLoc!, xfail: _data._xfail,
          skip: _data._skip,
          stdinText: _data._stdinText,
          stdinEndsWithEOF: _data._stdinEndsWithEOF,
          crashOutputMatches: _data._crashOutputMatches,
          code: testCode))
      _testSuite._testNameToIndex[_name] = _testSuite._tests.count - 1
    }

    public func code(_ testFunction: @escaping () -> Void) {
      _build(.single(code: testFunction))
    }

    public func forEach<Data>(
      in parameterSets: [Data],
      testFunction: @escaping (Data) -> Void
    ) {
      _build(.parameterized(
        code: { (i: Int) in testFunction(parameterSets[i]) },
        count: parameterSets.count))
    }
  }

  var name: String
  var _tests: [_Test] = []

  /// Code that is run before every test.
  var _testSetUpCode: (() -> Void)?

  /// Code that is run after every test.
  var _testTearDownCode: (() -> Void)?

  /// Maps test name to index in `_tests`.
  var _testNameToIndex: [String : Int] = [:]
}

#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
@_silgen_name("swift_stdlib_getSystemVersionPlistProperty")
func _stdlib_getSystemVersionPlistPropertyImpl(
  _ propertyName: UnsafePointer<CChar>) -> UnsafePointer<CChar>?

func _stdlib_getSystemVersionPlistProperty(_ propertyName: String) -> String? {
  let cs = _stdlib_getSystemVersionPlistPropertyImpl(propertyName)
  return cs.map(String.init(cString:))
}
#endif

public enum OSVersion : CustomStringConvertible {
  case osx(major: Int, minor: Int, bugFix: Int)
  case iOS(major: Int, minor: Int, bugFix: Int)
  case tvOS(major: Int, minor: Int, bugFix: Int)
  case watchOS(major: Int, minor: Int, bugFix: Int)
  case iOSSimulator
  case tvOSSimulator
  case watchOSSimulator
  case linux
  case freeBSD
  case android
  case ps4

  public var description: String {
    switch self {
    case .osx(let major, let minor, let bugFix):
      return "OS X \(major).\(minor).\(bugFix)"
    case .iOS(let major, let minor, let bugFix):
      return "iOS \(major).\(minor).\(bugFix)"
    case .tvOS(let major, let minor, let bugFix):
      return "TVOS \(major).\(minor).\(bugFix)"
    case .watchOS(let major, let minor, let bugFix):
      return "watchOS \(major).\(minor).\(bugFix)"
    case .iOSSimulator:
      return "iOSSimulator"
    case .tvOSSimulator:
      return "TVOSSimulator"
    case .watchOSSimulator:
      return "watchOSSimulator"
    case .linux:
      return "Linux"
    case .freeBSD:
      return "FreeBSD"
    case .ps4:
      return "PS4"
    case .android:
      return "Android"
    }
  }
}

func _parseDottedVersion(_ s: String) -> [Int] {
  return Array(s._split(separator: ".").lazy.map { Int($0)! })
}

public func _parseDottedVersionTriple(_ s: String) -> (Int, Int, Int) {
  var array = _parseDottedVersion(s)
  if array.count >= 4 {
    fatalError("unexpected version")
  }
  return (
    array.count >= 1 ? array[0] : 0,
    array.count >= 2 ? array[1] : 0,
    array.count >= 3 ? array[2] : 0)
}

func _getOSVersion() -> OSVersion {
#if os(iOS) && (arch(i386) || arch(x86_64))
  // On simulator, the plist file that we try to read turns out to be host's
  // plist file, which indicates OS X.
  //
  // FIXME: how to get the simulator version *without* UIKit?
  return .iOSSimulator
#elseif os(tvOS) && (arch(i386) || arch(x86_64))
  return .tvOSSimulator
#elseif os(watchOS) && (arch(i386) || arch(x86_64))
  return .watchOSSimulator
#elseif os(Linux)
  return .linux
#elseif os(FreeBSD)
  return .freeBSD
#elseif os(PS4)
  return .ps4
#elseif os(Android)
  return .android
#else
  let productVersion = _stdlib_getSystemVersionPlistProperty("ProductVersion")!
  let (major, minor, bugFix) = _parseDottedVersionTriple(productVersion)
  #if os(OSX)
  return .osx(major: major, minor: minor, bugFix: bugFix)
  #elseif os(iOS)
  return .iOS(major: major, minor: minor, bugFix: bugFix)
  #elseif os(tvOS)
  return .tvOS(major: major, minor: minor, bugFix: bugFix)
  #elseif os(watchOS)
  return .watchOS(major: major, minor: minor, bugFix: bugFix)
  #else
  fatalError("could not determine OS version")
  #endif
#endif
}

var _runningOSVersion: OSVersion = _getOSVersion()
var _overrideOSVersion: OSVersion? = nil

/// Override the OS version for testing.
public func _setOverrideOSVersion(_ v: OSVersion) {
  _overrideOSVersion = v
}

func _getRunningOSVersion() -> OSVersion {
  // Allow overriding the OS version for testing.
  return _overrideOSVersion ?? _runningOSVersion
}

public enum TestRunPredicate : CustomStringConvertible {
  case custom(() -> Bool, reason: String)

  case always(/*reason:*/ String)
  case never

  case osxAny(/*reason:*/ String)
  case osxMajor(Int, reason: String)
  case osxMinor(Int, Int, reason: String)
  case osxMinorRange(Int, ClosedRange<Int>, reason: String)
  case osxBugFix(Int, Int, Int, reason: String)
  case osxBugFixRange(Int, Int, ClosedRange<Int>, reason: String)

  case iOSAny(/*reason:*/ String)
  case iOSMajor(Int, reason: String)
  case iOSMinor(Int, Int, reason: String)
  case iOSMinorRange(Int, ClosedRange<Int>, reason: String)
  case iOSBugFix(Int, Int, Int, reason: String)
  case iOSBugFixRange(Int, Int, ClosedRange<Int>, reason: String)

  case iOSSimulatorAny(/*reason:*/ String)

  case tvOSAny(/*reason:*/ String)
  case tvOSMajor(Int, reason: String)
  case tvOSMinor(Int, Int, reason: String)
  case tvOSMinorRange(Int, ClosedRange<Int>, reason: String)
  case tvOSBugFix(Int, Int, Int, reason: String)
  case tvOSBugFixRange(Int, Int, ClosedRange<Int>, reason: String)

  case tvOSSimulatorAny(/*reason:*/ String)

  case watchOSAny(/*reason:*/ String)
  case watchOSMajor(Int, reason: String)
  case watchOSMinor(Int, Int, reason: String)
  case watchOSMinorRange(Int, ClosedRange<Int>, reason: String)
  case watchOSBugFix(Int, Int, Int, reason: String)
  case watchOSBugFixRange(Int, Int, ClosedRange<Int>, reason: String)

  case watchOSSimulatorAny(/*reason:*/ String)

  case linuxAny(reason: String)

  case freeBSDAny(reason: String)

  case ps4Any(reason: String)

  case androidAny(reason: String)

  case objCRuntime(/*reason:*/ String)
  case nativeRuntime(/*reason:*/ String)

  public var description: String {
    switch self {
    case .custom(_, let reason):
      return "Custom(reason: \(reason))"

    case .always(let reason):
      return "Always(reason: \(reason))"
    case .never:
      return ""

    case .osxAny(let reason):
      return "osx(*, reason: \(reason))"
    case .osxMajor(let major, let reason):
      return "osx(\(major).*, reason: \(reason))"
    case .osxMinor(let major, let minor, let reason):
      return "osx(\(major).\(minor), reason: \(reason))"
    case .osxMinorRange(let major, let minorRange, let reason):
      return "osx(\(major).[\(minorRange)], reason: \(reason))"
    case .osxBugFix(let major, let minor, let bugFix, let reason):
      return "osx(\(major).\(minor).\(bugFix), reason: \(reason))"
    case .osxBugFixRange(let major, let minor, let bugFixRange, let reason):
      return "osx(\(major).\(minor).[\(bugFixRange)], reason: \(reason))"

    case .iOSAny(let reason):
      return "iOS(*, reason: \(reason))"
    case .iOSMajor(let major, let reason):
      return "iOS(\(major).*, reason: \(reason))"
    case .iOSMinor(let major, let minor, let reason):
      return "iOS(\(major).\(minor), reason: \(reason))"
    case .iOSMinorRange(let major, let minorRange, let reason):
      return "iOS(\(major).[\(minorRange)], reason: \(reason))"
    case .iOSBugFix(let major, let minor, let bugFix, let reason):
      return "iOS(\(major).\(minor).\(bugFix), reason: \(reason))"
    case .iOSBugFixRange(let major, let minor, let bugFixRange, let reason):
      return "iOS(\(major).\(minor).[\(bugFixRange)], reason: \(reason))"

    case .iOSSimulatorAny(let reason):
      return "iOSSimulatorAny(*, reason: \(reason))"

    case .tvOSAny(let reason):
      return "tvOS(*, reason: \(reason))"
    case .tvOSMajor(let major, let reason):
      return "tvOS(\(major).*, reason: \(reason))"
    case .tvOSMinor(let major, let minor, let reason):
      return "tvOS(\(major).\(minor), reason: \(reason))"
    case .tvOSMinorRange(let major, let minorRange, let reason):
      return "tvOS(\(major).[\(minorRange)], reason: \(reason))"
    case .tvOSBugFix(let major, let minor, let bugFix, let reason):
      return "tvOS(\(major).\(minor).\(bugFix), reason: \(reason))"
    case .tvOSBugFixRange(let major, let minor, let bugFixRange, let reason):
      return "tvOS(\(major).\(minor).[\(bugFixRange)], reason: \(reason))"

    case .tvOSSimulatorAny(let reason):
      return "tvOSSimulatorAny(*, reason: \(reason))"

    case .watchOSAny(let reason):
      return "watchOS(*, reason: \(reason))"
    case .watchOSMajor(let major, let reason):
      return "watchOS(\(major).*, reason: \(reason))"
    case .watchOSMinor(let major, let minor, let reason):
      return "watchOS(\(major).\(minor), reason: \(reason))"
    case .watchOSMinorRange(let major, let minorRange, let reason):
      return "watchOS(\(major).[\(minorRange)], reason: \(reason))"
    case .watchOSBugFix(let major, let minor, let bugFix, let reason):
      return "watchOS(\(major).\(minor).\(bugFix), reason: \(reason))"
    case .watchOSBugFixRange(let major, let minor, let bugFixRange, let reason):
      return "watchOS(\(major).\(minor).[\(bugFixRange)], reason: \(reason))"

    case .watchOSSimulatorAny(let reason):
      return "watchOSSimulatorAny(*, reason: \(reason))"

    case .linuxAny(reason: let reason):
      return "linuxAny(*, reason: \(reason))"

    case .androidAny(reason: let reason):
      return "androidAny(*, reason: \(reason))"

    case .freeBSDAny(reason: let reason):
      return "freeBSDAny(*, reason: \(reason))"

    case .ps4Any(reason: let reason):
      return "ps4Any(*, reason: \(reason))"

    case .objCRuntime(let reason):
      return "Objective-C runtime, reason: \(reason))"
    case .nativeRuntime(let reason):
      return "Native runtime (no ObjC), reason: \(reason))"
    }
  }

  public func evaluate() -> Bool {
    switch self {
    case .custom(let predicate, _):
      return predicate()

    case .always:
      return true
    case .never:
      return false

    case .osxAny:
      switch _getRunningOSVersion() {
      case .osx:
        return true
      default:
        return false
      }

    case .osxMajor(let major, _):
      switch _getRunningOSVersion() {
      case .osx(major, _, _):
        return true
      default:
        return false
      }

    case .osxMinor(let major, let minor, _):
      switch _getRunningOSVersion() {
      case .osx(major, minor, _):
        return true
      default:
        return false
      }

    case .osxMinorRange(let major, let minorRange, _):
      switch _getRunningOSVersion() {
      case .osx(major, let runningMinor, _):
        return minorRange.contains(runningMinor)
      default:
        return false
      }

    case .osxBugFix(let major, let minor, let bugFix, _):
      switch _getRunningOSVersion() {
      case .osx(major, minor, bugFix):
        return true
      default:
        return false
      }

    case .osxBugFixRange(let major, let minor, let bugFixRange, _):
      switch _getRunningOSVersion() {
      case .osx(major, minor, let runningBugFix):
        return bugFixRange.contains(runningBugFix)
      default:
        return false
      }

    case .iOSAny:
      switch _getRunningOSVersion() {
      case .iOS:
        return true
      default:
        return false
      }

    case .iOSMajor(let major, _):
      switch _getRunningOSVersion() {
      case .iOS(major, _, _):
        return true
      default:
        return false
      }

    case .iOSMinor(let major, let minor, _):
      switch _getRunningOSVersion() {
      case .iOS(major, minor, _):
        return true
      default:
        return false
      }

    case .iOSMinorRange(let major, let minorRange, _):
      switch _getRunningOSVersion() {
      case .iOS(major, let runningMinor, _):
        return minorRange.contains(runningMinor)
      default:
        return false
      }

    case .iOSBugFix(let major, let minor, let bugFix, _):
      switch _getRunningOSVersion() {
      case .iOS(major, minor, bugFix):
        return true
      default:
        return false
      }

    case .iOSBugFixRange(let major, let minor, let bugFixRange, _):
      switch _getRunningOSVersion() {
      case .iOS(major, minor, let runningBugFix):
        return bugFixRange.contains(runningBugFix)
      default:
        return false
      }

    case .iOSSimulatorAny:
      switch _getRunningOSVersion() {
      case .iOSSimulator:
        return true
      default:
        return false
      }

    case .tvOSAny:
      switch _getRunningOSVersion() {
      case .tvOS:
        return true
      default:
        return false
      }

    case .tvOSMajor(let major, _):
      switch _getRunningOSVersion() {
      case .tvOS(major, _, _):
        return true
      default:
        return false
      }

    case .tvOSMinor(let major, let minor, _):
      switch _getRunningOSVersion() {
      case .tvOS(major, minor, _):
        return true
      default:
        return false
      }

    case .tvOSMinorRange(let major, let minorRange, _):
      switch _getRunningOSVersion() {
      case .tvOS(major, let runningMinor, _):
        return minorRange.contains(runningMinor)
      default:
        return false
      }

    case .tvOSBugFix(let major, let minor, let bugFix, _):
      switch _getRunningOSVersion() {
      case .tvOS(major, minor, bugFix):
        return true
      default:
        return false
      }

    case .tvOSBugFixRange(let major, let minor, let bugFixRange, _):
      switch _getRunningOSVersion() {
      case .tvOS(major, minor, let runningBugFix):
        return bugFixRange.contains(runningBugFix)
      default:
        return false
      }

    case .tvOSSimulatorAny:
      switch _getRunningOSVersion() {
      case .tvOSSimulator:
        return true
      default:
        return false
      }

    case .watchOSAny:
      switch _getRunningOSVersion() {
      case .watchOS:
        return true
      default:
        return false
      }

    case .watchOSMajor(let major, _):
      switch _getRunningOSVersion() {
      case .watchOS(major, _, _):
        return true
      default:
        return false
      }

    case .watchOSMinor(let major, let minor, _):
      switch _getRunningOSVersion() {
      case .watchOS(major, minor, _):
        return true
      default:
        return false
      }

    case .watchOSMinorRange(let major, let minorRange, _):
      switch _getRunningOSVersion() {
      case .watchOS(major, let runningMinor, _):
        return minorRange.contains(runningMinor)
      default:
        return false
      }

    case .watchOSBugFix(let major, let minor, let bugFix, _):
      switch _getRunningOSVersion() {
      case .watchOS(major, minor, bugFix):
        return true
      default:
        return false
      }

    case .watchOSBugFixRange(let major, let minor, let bugFixRange, _):
      switch _getRunningOSVersion() {
      case .watchOS(major, minor, let runningBugFix):
        return bugFixRange.contains(runningBugFix)
      default:
        return false
      }

    case .watchOSSimulatorAny:
      switch _getRunningOSVersion() {
      case .watchOSSimulator:
        return true
      default:
        return false
      }

    case .linuxAny:
      switch _getRunningOSVersion() {
      case .linux:
        return true
      default:
        return false
      }

    case .androidAny:
      switch _getRunningOSVersion() {
      case .android:
        return true
      default:
        return false
      }

    case .freeBSDAny:
      switch _getRunningOSVersion() {
      case .freeBSD:
        return true
      default:
        return false
      }

    case .ps4Any:
      switch _getRunningOSVersion() {
      case .ps4:
        return true
      default:
        return false
      }

    case .objCRuntime:
#if _runtime(_ObjC)
      return true
#else
      return false
#endif

    case .nativeRuntime:
#if _runtime(_ObjC)
      return false
#else
      return true
#endif
    }
  }
}

//
// Semantic tests for protocol conformance
//

/// Test that the elements of `instances` satisfy the semantic
/// requirements of `Equatable`, using `oracle` to generate equality
/// expectations from pairs of positions in `instances`.
///
/// - Note: `oracle` is also checked for conformance to the
///   laws.
public func checkEquatable<Instances : Collection>(
  _ instances: Instances,
  oracle: (Instances.Index, Instances.Index) -> Bool,
  ${TRACE}
) where
  Instances.Iterator.Element : Equatable,
  // FIXME(compiler limitation): these constraints should be applied to
  // associated types of Collection.
  Instances.Indices.Iterator.Element == Instances.Index
{
  let indices = Array(instances.indices)
  _checkEquatableImpl(
    Array(instances),
    oracle: { oracle(indices[$0], indices[$1]) })
}

internal func _checkEquatableImpl<Instance : Equatable>(
  _ instances: [Instance],
  oracle: (Int, Int) -> Bool,
  ${TRACE}
) {
  // For each index (which corresponds to an instance being tested) track the
  // set of equal instances.
  var transitivityScoreboard: [Box<Set<Int>>] =
    instances.indices.map { _ in Box(Set()) }

  // TODO: swift-3-indexing-model: add tests for this function.
  for i in instances.indices {
    let x = instances[i]
    expectTrue(oracle(i, i), "bad oracle: broken reflexivity at index \(i)")

    for j in instances.indices {
      let y = instances[j]

      let predictedXY = oracle(i, j)
      expectEqual(
        predictedXY, oracle(j, i),
        "bad oracle: broken symmetry between indices \(i), \(j)")

      let isEqualXY = x == y
      expectEqual(
        predictedXY, isEqualXY,
        "lhs (at index \(i)): \(x)\nrhs (at index \(j)): \(y)",
        stackTrace: ${stackTrace})

      // Not-equal is an inverse of equal.
      expectNotEqual(
        isEqualXY, x != y,
        "lhs (at index \(i)): \(x)\nrhs (at index \(j)): \(y)",
        stackTrace: ${stackTrace})

      // Check transitivity of the predicate represented by the oracle.
      // If we are adding the instance `j` into an equivalence set, check that
      // it is equal to every other instance in the set.
      if predictedXY && i < j && transitivityScoreboard[i].value.insert(j).inserted {
        if transitivityScoreboard[i].value.count == 1 {
          transitivityScoreboard[i].value.insert(i)
        }
        for k in transitivityScoreboard[i].value {
          expectTrue(
            oracle(j, k),
            "bad oracle: broken transitivity at indices \(i), \(j), \(k)")
            // No need to check equality between actual values, we will check
            // them with the checks above.
        }
        precondition(transitivityScoreboard[j].value.isEmpty)
        transitivityScoreboard[j] = transitivityScoreboard[i]
      }
    }
  }
}


public func checkEquatable<T : Equatable>(
  _ expectedEqual: Bool, _ lhs: T, _ rhs: T, ${TRACE}
) {
  checkEquatable(
    [lhs, rhs],
    oracle: { expectedEqual || $0 == $1 }, ${trace}, showFrame: false)
}

/// Test that the elements of `instances` satisfy the semantic
/// requirements of `Hashable`, using `equalityOracle` to generate
/// equality expectations from pairs of positions in `instances`.
public func checkHashable<Instances : Collection>(
  _ instances: Instances,
  equalityOracle: (Instances.Index, Instances.Index) -> Bool,
  ${TRACE}
) where
  Instances.Iterator.Element : Hashable,
  // FIXME(compiler limitation): these constraints should be applied to
  // associated types of Collection.
  Instances.Indices.Iterator.Element == Instances.Index {
  
  checkEquatable(instances, oracle: equalityOracle, ${trace})
  
  for i in instances.indices {
    let x = instances[i]
    for j in instances.indices {
      let y = instances[j]
      if x == y {
        expectEqual(
          x.hashValue, y.hashValue,
          "lhs (at index \(i)): \(x)\nrhs (at index \(j)): \(y)",
          stackTrace: ${stackTrace})
      }
    }
  }
}

public func checkHashable<T : Hashable>(
  _ expectedEqual: Bool, _ lhs: T, _ rhs: T, ${TRACE}
) {
  checkHashable(
    [lhs, rhs], equalityOracle: { expectedEqual || $0 == $1 }, ${trace})
}

public enum ExpectedComparisonResult {
  case lt, eq, gt

  public func isLT() -> Bool {
    return self == .lt
  }

  public func isEQ() -> Bool {
    return self == .eq
  }

  public func isGT() -> Bool {
    return self == .gt
  }

  public func isLE() -> Bool {
    return isLT() || isEQ()
  }

  public func isGE() -> Bool {
    return isGT() || isEQ()
  }

  public func isNE() -> Bool {
    return !isEQ()
  }

  public func flip() -> ExpectedComparisonResult {
    switch self {
    case .lt:
      return .gt
    case .eq:
      return .eq
    case .gt:
      return .lt
    }
  }
}

extension ExpectedComparisonResult : CustomStringConvertible {
  public var description: String {
    switch self {
    case .lt:
      return "<"
    case .eq:
      return "=="
    case .gt:
      return ">"
    }
  }
}

/// Test that the elements of `instances` satisfy the semantic
/// requirements of `Comparable`, using `oracle` to generate comparison
/// expectations from pairs of positions in `instances`.
///
/// - Note: `oracle` is also checked for conformance to the
///   laws.
public func checkComparable<Instances : Collection>(
  _ instances: Instances,
  oracle: (Instances.Index, Instances.Index) -> ExpectedComparisonResult,
  ${TRACE}
) where
  Instances.Iterator.Element : Comparable,
  // FIXME(compiler limitation): these constraints should be applied to
  // associated types of Collection.
  Instances.Indices.Iterator.Element == Instances.Index {
  
  // Also checks that equality is consistent with comparison and that
  // the oracle obeys the equality laws
  checkEquatable(instances, oracle: { oracle($0, $1).isEQ() }, ${trace})
  
  for i in instances.indices {
    let x = instances[i]

    expectFalse(x < x, ${trace})
    expectFalse(x > x, ${trace})
    expectTrue(x <= x, ${trace})
    expectTrue(x >= x, ${trace})
    
    for j in instances.indices where i != j {
      let y = instances[j]
      
      let expected = oracle(i, j)
      
      expectEqual(
        expected.flip(), oracle(j, i),
        "bad oracle: missing antisymmetry: "
        + "(\(String(reflecting: i)), \(String(reflecting: j)))",
        stackTrace: ${stackTrace})
      
      expectEqual(expected.isLT(), x < y, ${trace})
      expectEqual(expected.isLE(), x <= y, ${trace})
      expectEqual(expected.isGE(), x >= y, ${trace})
      expectEqual(expected.isGT(), x > y, ${trace})
      
      for k in instances.indices {
        let expected2 = oracle(j, k)
        if expected == expected2 {
          expectEqual(
            expected, oracle(i, k),
            "bad oracle: missing transitivity "
            + "(\(String(reflecting: i)), \(String(reflecting: j)), "
            + "\(String(reflecting: k)))", stackTrace: ${stackTrace})
        }
      }
    }
  }
}

public func checkComparable<T : Comparable>(
  _ expected: ExpectedComparisonResult, _ lhs: T, _ rhs: T, ${TRACE}
) {
  checkComparable(
    [lhs, rhs],
    oracle: { [[ .eq, expected], [ expected.flip(), .eq]][$0][$1] },
    ${trace})
}


/// Test that the elements of `instances` satisfy the semantic
/// requirements of `Strideable`, using `advanceOracle` and
/// 'distanceOracle' to generate expectations about the results of
/// `advanced(by:)` and `distance(to:)` from pairs of positions in
/// `instances` and `strides`.
///
/// - Note: `oracle` is also checked for conformance to the
///   laws.
public func checkStrideable<Instances : Collection, Strides : Collection>(
  _ instances: Instances, strides: Strides,
  distanceOracle:
    (Instances.Index, Instances.Index) -> Strides.Iterator.Element,
  advanceOracle:
    (Instances.Index, Strides.Index) -> Instances.Iterator.Element,
  ${TRACE}
) where
  Instances.Iterator.Element : Strideable,
  Instances.Iterator.Element.Stride == Strides.Iterator.Element,
  // FIXME(compiler limitation): these constraints should be applied to
  // associated types of Collection.
  Instances.Indices.Iterator.Element == Instances.Index,
  Strides.Indices.Iterator.Element == Strides.Index {

  checkComparable(
    instances,
    oracle: {
      let d = distanceOracle($1, $0);
      return d < 0 ? .lt : d == 0 ? .eq : .gt
    },
    ${trace})
  
  for i in instances.indices {
    let x = instances[i]
    expectEqual(x, x.advanced(by: 0))
    
    for j in strides.indices {
      let y = strides[j]
      expectEqual(advanceOracle(i, j), x.advanced(by: y))
    }

    for j in instances.indices {
      let y = instances[j]
      expectEqual(distanceOracle(i, j), x.distance(to: y))
    }
  }
}

public func checkLosslessStringConvertible<Instance>(
  _ instances: [Instance]
) where Instance : LosslessStringConvertible & Equatable {
  expectEqualFunctionsForDomain(instances, { $0 }, { Instance(String($0))! })
}

public func nthIndex<C: Collection>(_ x: C, _ n: Int) -> C.Index {
  return x.index(x.startIndex, offsetBy: numericCast(n))
}

public func nth<C: Collection>(_ x: C, _ n: Int) -> C.Iterator.Element {
  return x[nthIndex(x, n)]
}

public func expectEqualSequence<
  Expected: Sequence,
  Actual: Sequence
>(
  _ expected: Expected, _ actual: Actual, ${TRACE}
) where
  Expected.Iterator.Element == Actual.Iterator.Element,
  Expected.Iterator.Element : Equatable {
  
  expectEqualSequence(expected, actual, ${trace}) { $0 == $1 }
}

public func expectEqualSequence<
  Expected : Sequence,
  Actual : Sequence,
  T : Equatable,
  U : Equatable
>(
  _ expected: Expected, _ actual: Actual, ${TRACE}
) where
  Expected.Iterator.Element == Actual.Iterator.Element,
  Expected.Iterator.Element == (T, U) {

  expectEqualSequence(
    expected, actual, ${trace}) {
    (lhs: (T, U), rhs: (T, U)) -> Bool in
    lhs.0 == rhs.0 && lhs.1 == rhs.1
  }
}

public func expectEqualSequence<
  Expected: Sequence,
  Actual: Sequence
>(
  _ expected: Expected, _ actual: Actual, ${TRACE},
  sameValue: (Expected.Iterator.Element, Expected.Iterator.Element) -> Bool
) where
  Expected.Iterator.Element == Actual.Iterator.Element {

  if !expected.elementsEqual(actual, by: sameValue) {
    expectationFailure("expected elements: \"\(expected)\"\n"
      + "actual: \"\(actual)\" (of type \(String(reflecting: type(of: actual))))",
      trace: ${trace})
  }
}

public func expectEqualsUnordered<
  Expected : Sequence,
  Actual : Sequence
>(
  _ expected: Expected, _ actual: Actual, ${TRACE},
  compare: @escaping (Expected.Iterator.Element, Expected.Iterator.Element)
    -> ExpectedComparisonResult
) where
  Expected.Iterator.Element == Actual.Iterator.Element {
  
  let x: [Expected.Iterator.Element] =
    expected.sorted(by: compose(compare, { $0.isLT() }))
  let y: [Actual.Iterator.Element] =
    actual.sorted(by: compose(compare, { $0.isLT() }))
  expectEqualSequence(
    x, y, ${trace}, sameValue: compose(compare, { $0.isEQ() }))
}

public func expectEqualsUnordered<
  Expected : Sequence,
  Actual : Sequence
>(
  _ expected: Expected, _ actual: Actual, ${TRACE}
) where
  Expected.Iterator.Element == Actual.Iterator.Element,
  Expected.Iterator.Element : Comparable {

  expectEqualsUnordered(expected, actual, ${trace}) {
    $0 < $1 ? .lt : $0 == $1 ? .eq : .gt
  }
}

public func expectEqualsUnordered<T : Comparable>(
  _ expected: [T], _ actual: [T], ${TRACE}
) {
  let x = expected.sorted()
  let y = actual.sorted()
  expectEqualSequence(x, y, ${trace})
}

public func expectEqualsUnordered<
  T : Strideable
>(
  _ expected: Range<T>, _ actual: [T], ${TRACE}
) where T.Stride : SignedInteger {
  expectEqualsUnordered(
    CountableRange(uncheckedBounds:
      (lower: expected.lowerBound, upper: expected.upperBound)),
    actual,
    ${trace},
    showFrame: false)
}

public func expectEqualsUnordered<T : Strideable>(
  _ expected: CountableRange<T>, _ actual: [T], ${TRACE}
) {
  if numericCast(expected.count) != actual.count {
    expectationFailure("expected elements: \"\(expected)\"\n"
      + "actual: \"\(actual)\" (of type \(String(reflecting: type(of: actual))))",
      trace: ${trace})
  }
  let r = Range(uncheckedBounds:
    (lower: expected.lowerBound, upper: expected.upperBound))
  for e in actual {
    if !r.contains(e) {
      expectationFailure("expected elements: \"\(expected)\"\n"
        + "actual: \"\(actual)\" (of type \(String(reflecting: type(of: actual))))",
        trace: ${trace})
    }
  }
}

/// A nominal type that is equivalent to a tuple of two elements.
///
/// We need a nominal type because we can't add protocol conformances to
/// tuples.
struct Pair<T : Comparable> : Comparable {
  init(_ first: T, _ second: T) {
    self.first = first
    self.second = second
  }

  var first: T
  var second: T
}

func == <T>(lhs: Pair<T>, rhs: Pair<T>) -> Bool {
  return lhs.first == rhs.first && lhs.second == rhs.second
}

func < <T>(lhs: Pair<T>, rhs: Pair<T>) -> Bool {
  return [lhs.first, lhs.second].lexicographicallyPrecedes(
    [rhs.first, rhs.second])
}

public func expectEqualsUnordered<
  Expected : Sequence,
  Actual : Sequence,
  T : Comparable
>(
  _ expected: Expected, _ actual: Actual, ${TRACE}
) where
  Actual.Iterator.Element == (key: T, value: T),
  Expected.Iterator.Element == (T, T) {

  func comparePairLess(_ lhs: (T, T), rhs: (T, T)) -> Bool {
    return [lhs.0, lhs.1].lexicographicallyPrecedes([rhs.0, rhs.1])
  }

  let x: [(T, T)] =
    expected.sorted(by: comparePairLess)
  let y: [(T, T)] =
    actual.map { ($0.0, $0.1) }
      .sorted(by: comparePairLess)

  func comparePairEquals(_ lhs: (T, T), rhs: (key: T, value: T)) -> Bool {
    return lhs.0 == rhs.0 && lhs.1 == rhs.1
  }

  expectEqualSequence(x, y, ${trace}, sameValue: comparePairEquals)
}

public func expectEqualFunctionsForDomain<ArgumentType, Result : Equatable>(
    _ arguments: [ArgumentType], _ function1: (ArgumentType) -> Result,
    _ function2: (ArgumentType) -> Result
) {
  for a in arguments {
    let expected = function1(a)
    let actual = function2(a)
    expectEqual(expected, actual, "where the argument is: \(a)")
  }
}

public func expectEqualMethodsForDomain<
  SelfType, ArgumentType, Result : Equatable
>(
  _ selfs: [SelfType], _ arguments: [ArgumentType],
  _ function1: (SelfType) -> (ArgumentType) -> Result,
  _ function2: (SelfType) -> (ArgumentType) -> Result
) {
  for s in selfs {
    for a in arguments {
      let expected = function1(s)(a)
      let actual = function2(s)(a)
      expectEqual(
        expected, actual,
        "where the first argument is: \(s)\nand the second argument is: \(a)"
      )
    }
  }
}

public func expectEqualUnicodeScalars(
  _ expected: [UInt32], _ actual: String, ${TRACE}) {
  let actualUnicodeScalars = Array(
    actual.unicodeScalars.lazy.map { $0.value })
  
  if !expected.elementsEqual(actualUnicodeScalars) {
    expectationFailure(
      "expected elements: \"\(asHex(expected))\"\n"
      + "actual: \"\(asHex(actualUnicodeScalars))\"",
      trace: ${trace})
  }
}

func compose<A, B, C>(_ f: @escaping (A) -> B, _ g: @escaping (B) -> C) -> (A) -> C {
  return { a in
    return g(f(a))
  }
}

// ${'Local Variables'}:
// eval: (read-only-mode 1)
// End:
