// -*- swift -*-
// RUN: %target-run-simple-swiftgyb
// REQUIRES: executable_test

% import os.path
% import gyb

import StdlibUnittest
import StdlibCollectionUnittest


// Extend LoggingSequence to shadow the new operation.  When
// requirements are added to a protocol 'P', there should be an
// implementation in 'InstrumentedP' that does some bookkeeping for
// testing (like counting calls to the operation) and then dispatches
// to the same operation on its 'base' member.  InstrumentedSequence
// already contains implementations of all the Sequence
// requirements.

var _nonCustomizableOperation = TypeIndexed(0)
extension SequenceLog {
  static var nonCustomizableOperation : TypeIndexed<Int> {
    get {return _nonCustomizableOperation}
    set {_nonCustomizableOperation = newValue}
  }
}

extension LoggingSequence {
  func nonCustomizableOperation() {
    Log.nonCustomizableOperation[type(of: self)] += 1
    return base.nonCustomizableOperation()
  }
}

// Add a non-customizable operation to sequence
extension Sequence {
  func nonCustomizableOperation() {}
}

var SequenceTypeTests = TestSuite("Sequence")

//===----------------------------------------------------------------------===//

// FIXME: add tests for:
//
// - Array, ContiguousArray and ArraySlice as inputs.  These types special-case
// a lot of collection behavior for performance reasons.  Not to even mention
// that these are important types to test in any case.
//
// - NaN behavior of floating point types, combined with these generic
// algorithms, should make sense if possible.  For example,
// [1.0, Double.nan].starts(with: [1.0, 2.0]) should be false.

//===----------------------------------------------------------------------===//
// min(), max()
//===----------------------------------------------------------------------===//

% for algorithmKind in ['min', 'max']:
%   AlgorithmKind = algorithmKind.capitalize()

SequenceTypeTests.test("${algorithmKind}/WhereElementIsComparable") {
  for test in minMaxTests {
    let s = MinimalSequence<MinimalComparableValue>(
      elements: test.sequence.enumerated().map {
        MinimalComparableValue($1, identity: $0)
      })
    var maybeResult = s.${algorithmKind}()
    expectType(Optional<MinimalComparableValue>.self, &maybeResult)
    if let result = maybeResult {
      expectEqual(
        test.expected${AlgorithmKind}Value!, result.value,
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expected${AlgorithmKind}Index!, result.identity,
        stackTrace: SourceLocStack().with(test.loc))
    } else {
      expectNil(
        test.expected${AlgorithmKind}Value,
        stackTrace: SourceLocStack().with(test.loc))
      expectNil(
        test.expected${AlgorithmKind}Index,
        stackTrace: SourceLocStack().with(test.loc))
    }
    expectEqual([], s.map { $0.value }, "sequence should be consumed")
  }
}

SequenceTypeTests.test("${algorithmKind}/Predicate") {
  for test in minMaxTests {
    let s = MinimalSequence<OpaqueValue<Int>>(
      elements: test.sequence.enumerated().map {
        OpaqueValue($1, identity: $0)
      })
    var timesClosureWasCalled = 0
    var maybeResult = s.${algorithmKind} {
      (lhs, rhs) -> Bool in
      timesClosureWasCalled += 1
      return lhs.value < rhs.value
    }
    expectType(Optional<OpaqueValue<Int>>.self, &maybeResult)
    if let result = maybeResult {
      expectEqual(
        test.expected${AlgorithmKind}Value!, result.value,
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expected${AlgorithmKind}Index!, result.identity,
        stackTrace: SourceLocStack().with(test.loc))
    } else {
      expectNil(
        test.expected${AlgorithmKind}Value,
        stackTrace: SourceLocStack().with(test.loc))
      expectNil(
        test.expected${AlgorithmKind}Index,
        stackTrace: SourceLocStack().with(test.loc))
    }
    expectEqual([], s.map { $0.value }, "sequence should be consumed")
    expectEqual(
      max(0, test.sequence.count - 1), timesClosureWasCalled,
      "max() should be eager and should only call its predicate"
      + " once per element")
  }
}

% end


//===----------------------------------------------------------------------===//
// IteratorSequence
//===----------------------------------------------------------------------===//

// Check that the generic parameter is called 'Base'.
protocol TestProtocol1 {}

extension IteratorSequence where Base : TestProtocol1 {
  var _baseIsTestProtocol1: Bool {
    fatalError("not implemented")
  }
}

//===--- Demonstrate technique for testing generic dispatching ------------===//
// A counter we can use to record calls to our non-customizable operation

SequenceTypeTests.test("Demonstration/NotCustomizable") {
  let tester = SequenceLog.dispatchTester([OpaqueValue(1)])

  tester.nonCustomizableOperation()

  expectNotCustomizable(tester, tester.log.nonCustomizableOperation)
}

SequenceTypeTests.test("IteratorSequence/IteratorProtocol/empty") {
  do {
    let data: [OpaqueValue<Int>] = []
    let base = MinimalIterator(data)
    var iter = IteratorSequence(base)
    expectType(
      IteratorSequence<MinimalIterator<OpaqueValue<Int>>>.self,
      &iter)
    checkIterator(data, iter, resiliencyChecks: .none) { $0.value == $1.value }
  }
  do {
    let data: [OpaqueValue<Int>] = []
    let base = data.makeIterator()
    var iter = IteratorSequence(base)
    expectType(
      IteratorSequence<IndexingIterator<Array<OpaqueValue<Int>>>>.self,
      &iter)
    checkIterator(data, iter) { $0.value == $1.value }
  }
}

SequenceTypeTests.test("IteratorSequence/IteratorProtocol") {
  do {
    let data: [OpaqueValue<Int>] = []
    let base = MinimalIterator(data)
    var iter = IteratorSequence(base)
    expectType(
      IteratorSequence<MinimalIterator<OpaqueValue<Int>>>.self,
      &iter)
    checkIterator(data, iter, resiliencyChecks: .none) { $0.value == $1.value }
  }
  do {
    let data: [OpaqueValue<Int>] = []
    let base = data.makeIterator()
    var iter = IteratorSequence(base)
    expectType(
      IteratorSequence<IndexingIterator<Array<OpaqueValue<Int>>>>.self,
      &iter)
    checkIterator(data, iter) { $0.value == $1.value }
  }
}

SequenceTypeTests.test("IteratorSequence/Sequence/empty") {
  do {
    let data = [ 10, 20, 30 ].map(OpaqueValue.init)
    let base = MinimalIterator(data)
    var iter = IteratorSequence(base)
    expectType(
      IteratorSequence<MinimalIterator<OpaqueValue<Int>>>.self,
      &iter)
    checkSequence(data, iter, resiliencyChecks: .none) { $0.value == $1.value }
  }
  do {
    let data = [ 10, 20, 30 ].map(OpaqueValue.init)
    let base = data.makeIterator()
    var iter = IteratorSequence(base)
    expectType(
      IteratorSequence<IndexingIterator<Array<OpaqueValue<Int>>>>.self,
      &iter)
    checkSequence(data, iter) { $0.value == $1.value }
  }
}

SequenceTypeTests.test("IteratorSequence/Sequence") {
  do {
    let data = [ 10, 20, 30 ].map(OpaqueValue.init)
    let base = MinimalIterator(data)
    var iter = IteratorSequence(base)
    expectType(
      IteratorSequence<MinimalIterator<OpaqueValue<Int>>>.self,
      &iter)
    checkSequence(data, iter, resiliencyChecks: .none) { $0.value == $1.value }
  }
  do {
    let data = [ 10, 20, 30 ].map(OpaqueValue.init)
    let base = data.makeIterator()
    var iter = IteratorSequence(base)
    expectType(
      IteratorSequence<IndexingIterator<Array<OpaqueValue<Int>>>>.self,
      &iter)
    checkSequence(data, iter) { $0.value == $1.value }
  }
}

//===----------------------------------------------------------------------===//
// enumerated()
//===----------------------------------------------------------------------===//

// Check that the generic parameter is called 'Base'.
extension EnumeratedIterator where Base : TestProtocol1 {
  var _elementIsTestProtocol1: Bool {
    fatalError("not implemented")
  }
}

extension EnumeratedSequence where Base : TestProtocol1 {
  var _elementIsTestProtocol1: Bool {
    fatalError("not implemented")
  }
}

SequenceTypeTests.test("enumerated()") {
  typealias Element = (offset: Int, element: OpaqueValue<Int>)
  func compareElements(_ lhs: Element, rhs: Element) -> Bool {
    return lhs.0 == rhs.0 && lhs.1.value == rhs.1.value
  }

  for test in enumerateTests {
    let s = MinimalSequence<OpaqueValue<Int>>(
      elements: test.sequence.map(OpaqueValue.init))
    var result = s.enumerated()
    expectType(
      EnumeratedSequence<MinimalSequence<OpaqueValue<Int>>>.self,
      &result)

    checkSequence(
      test.expected.map {
        (offset: $0.0, element: OpaqueValue($0.1))
      } as [Element],
      result,
      resiliencyChecks: .none, sameValue: compareElements)
    expectEqual([], s.map { $0.value }, "sequence should be consumed")
  }
}

//===----------------------------------------------------------------------===//
// starts(with:)
//===----------------------------------------------------------------------===//

SequenceTypeTests.test("starts(with:)/WhereElementIsEquatable") {
  for test in startsWithTests {
    do {
      let s = MinimalSequence<MinimalEquatableValue>(
        elements: test.sequence.map(MinimalEquatableValue.init))
      let prefix = MinimalSequence<MinimalEquatableValue>(
        elements: test.prefix.map(MinimalEquatableValue.init))
      expectEqual(
        test.expected,
        s.starts(with: prefix),
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverSequence, s.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverPrefix, prefix.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
    }

    // Use different types for the sequence and prefix.
    do {
      let s = MinimalCollection<MinimalEquatableValue>(
        elements: test.sequence.map(MinimalEquatableValue.init))
      let prefix = MinimalSequence<MinimalEquatableValue>(
        elements: test.prefix.map(MinimalEquatableValue.init))
      expectEqual(
        test.expected,
        s.starts(with: prefix),
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.sequence, s.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverPrefix, prefix.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
    }
  }
}

SequenceTypeTests.test("starts(with:)/Predicate") {
  for test in startsWithTests {
    do {
      let s = MinimalSequence<OpaqueValue<Int>>(
        elements: test.sequence.map(OpaqueValue.init))
      let prefix = MinimalSequence<OpaqueValue<Int>>(
        elements: test.prefix.map(OpaqueValue.init))
      expectEqual(
        test.expected,
        s.starts(with: prefix) { $0.value == $1.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverSequence, s.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverPrefix, prefix.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
    }
    do {
      let s = MinimalSequence<OpaqueValue<Int>>(
        elements: test.sequence.map { OpaqueValue($0 * 2) })
      let prefix = MinimalSequence<OpaqueValue<Int>>(
        elements: test.prefix.map(OpaqueValue.init))
      expectEqual(
        test.expected,
        s.starts(with: prefix) { $0.value / 2 == $1.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverSequence, s.map { $0.value / 2 },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverPrefix, prefix.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
    }

    // Use different types for the sequence and prefix.
    do {
      let s = MinimalCollection<OpaqueValue<Int>>(
        elements: test.sequence.map(OpaqueValue.init))
      let prefix = MinimalSequence<OpaqueValue<Int>>(
        elements: test.prefix.map(OpaqueValue.init))
      expectEqual(
        test.expected,
        s.starts(with: prefix) { $0.value == $1.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.sequence, s.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverPrefix, prefix.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
    }
  }
}

//===----------------------------------------------------------------------===//
// equal()
//===----------------------------------------------------------------------===//

SequenceTypeTests.test("elementsEqual/WhereElementIsEquatable") {
  for test in elementsEqualTests {
    do {
      let s = MinimalSequence<MinimalEquatableValue>(
        elements: test.sequence.map(MinimalEquatableValue.init))
      let other = MinimalSequence<MinimalEquatableValue>(
        elements: test.other.map(MinimalEquatableValue.init))
      expectEqual(
        test.expected,
        s.elementsEqual(other),
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverSequence, s.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverOther, other.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
    }

    // Use different types for the sequence and other.
    do {
      let s = MinimalCollection<MinimalEquatableValue>(
        elements: test.sequence.map(MinimalEquatableValue.init))
      let other = MinimalSequence<MinimalEquatableValue>(
        elements: test.other.map(MinimalEquatableValue.init))
      expectEqual(
        test.expected,
        s.elementsEqual(other),
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.sequence, s.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverOther, other.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
    }
  }
}

SequenceTypeTests.test("elementsEqual/Predicate") {
  for test in elementsEqualTests {
    do {
      let s = MinimalSequence<OpaqueValue<Int>>(
        elements: test.sequence.map(OpaqueValue.init))
      let other = MinimalSequence<OpaqueValue<Int>>(
        elements: test.other.map(OpaqueValue.init))
      expectEqual(
        test.expected,
        s.elementsEqual(other) { $0.value == $1.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverSequence, s.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverOther, other.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
    }

    // Use different types for the sequence and other.
    do {
      let s = MinimalCollection<OpaqueValue<Int>>(
        elements: test.sequence.map(OpaqueValue.init))
      let other = MinimalSequence<OpaqueValue<Int>>(
        elements: test.other.map(OpaqueValue.init))
      expectEqual(
        test.expected,
        s.elementsEqual(other) { $0.value == $1.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.sequence, s.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverOther, other.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
    }
  }
}

//===----------------------------------------------------------------------===//
// lexicographicallyPrecedes()
//===----------------------------------------------------------------------===//

SequenceTypeTests.test("lexicographicallyPrecedes(_:)/WhereElementIsComparable") {
  for test in lexicographicallyPrecedesTests {
    do {
      let s = MinimalSequence<MinimalComparableValue>(
        elements: test.sequence.map(MinimalComparableValue.init))
      let other = MinimalSequence<MinimalComparableValue>(
        elements: test.other.map(MinimalComparableValue.init))
      expectEqual(
        test.expected.isLT(),
        s.lexicographicallyPrecedes(other),
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverSequence, s.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverOther, other.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
    }

    // Use different types for the sequence and other.
    do {
      let s = MinimalCollection<MinimalComparableValue>(
        elements: test.sequence.map(MinimalComparableValue.init))
      let other = MinimalSequence<MinimalComparableValue>(
        elements: test.other.map(MinimalComparableValue.init))
      expectEqual(
        test.expected.isLT(),
        s.lexicographicallyPrecedes(other),
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.sequence, s.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverOther, other.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
    }
  }
}

SequenceTypeTests.test("lexicographicallyPrecedes(_:)/Predicate") {
  for test in lexicographicallyPrecedesTests {
    do {
      let s = MinimalSequence<OpaqueValue<Int>>(
        elements: test.sequence.map(OpaqueValue.init))
      let other = MinimalSequence<OpaqueValue<Int>>(
        elements: test.other.map(OpaqueValue.init))
      expectEqual(
        test.expected.isLT(),
        s.lexicographicallyPrecedes(other) { $0.value < $1.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverSequence, s.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverOther, other.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
    }

    // Use different types for the sequence and other.
    do {
      let s = MinimalCollection<OpaqueValue<Int>>(
        elements: test.sequence.map(OpaqueValue.init))
      let other = MinimalSequence<OpaqueValue<Int>>(
        elements: test.other.map(OpaqueValue.init))
      expectEqual(
        test.expected.isLT(),
        s.lexicographicallyPrecedes(other) { $0.value < $1.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.sequence, s.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        test.expectedLeftoverOther, other.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
    }
  }
}

//===----------------------------------------------------------------------===//
// contains()
//===----------------------------------------------------------------------===//

typealias StrictSequenceOfEquatable = MinimalSequence<MinimalEquatableValue>

// FIXME: rename in StdlibUnittest
// typealias StrictSequence = MinimalSequence

SequenceTypeTests.test("contains/WhereElementIsEquatable/dispatch") {
  let tester = SequenceLog.dispatchTester([MinimalEquatableValue(1)])
  _ = tester.contains(MinimalEquatableValue(1))
  expectCustomizable(tester, tester.log._customContainsEquatableElement)
}

func callStaticContains(
  _ set: Set<MinimalHashableValue>,
  _ element: MinimalHashableValue
) -> Bool {
  return set.contains(element)
}

func callGenericContains<
  S : Sequence
>(_ sequence: S, _ element: S.Iterator.Element) -> Bool
where S.Iterator.Element : Equatable {
  return sequence.contains(element)
}

% for dispatch in ['Static', 'Generic']:

// FIXME: implement the same optimization for Dictionary.
// FIXME: move to the file where other Set tests live.
SequenceTypeTests.test("Set<T>.contains/CustomImplementation/${dispatch}") {
  for test in findTests {
    let s = Set<MinimalHashableValue>(
      test.sequence.map { MinimalHashableValue($0.value) })
    MinimalHashableValue.timesEqualEqualWasCalled = 0
    MinimalHashableValue.timesHashIntoWasCalled = 0
    expectEqual(
      test.expected != nil,
      call${dispatch}Contains(s, MinimalHashableValue(test.element.value)),
      stackTrace: SourceLocStack().with(test.loc))
    if test.sequence.isEmpty {
      expectEqual(
        0, MinimalHashableValue.timesEqualEqualWasCalled,
        stackTrace: SourceLocStack().with(test.loc))
      expectEqual(
        0, MinimalHashableValue.timesHashIntoWasCalled,
        stackTrace: SourceLocStack().with(test.loc))
    } else {
      expectNotEqual(
        0, MinimalHashableValue.timesHashIntoWasCalled,
        stackTrace: SourceLocStack().with(test.loc))
    }
    if test.expected != nil {
      expectNotEqual(
        0, MinimalHashableValue.timesEqualEqualWasCalled,
        stackTrace: SourceLocStack().with(test.loc))
    }
  }
}

% end

SequenceTypeTests.test("contains/Predicate") {
  for test in findTests {
    let s = MinimalSequence<OpaqueValue<Int>>(
      elements: test.sequence.map { OpaqueValue($0.value) })
    expectEqual(
      test.expected != nil,
      s.contains { $0.value == test.element.value },
      stackTrace: SourceLocStack().with(test.loc))
    expectEqual(
      test.expectedLeftoverSequence.map { $0.value }, s.map { $0.value },
      stackTrace: SourceLocStack().with(test.loc))
  }
}

SequenceTypeTests.test("allSatisfy/Predicate") {
  for test in findTests {
    let s = MinimalSequence<OpaqueValue<Int>>(
      elements: test.sequence.map { OpaqueValue($0.value) })
    expectEqual(
      test.expected == nil,
      s.allSatisfy { $0.value != test.element.value },
      stackTrace: SourceLocStack().with(test.loc))
    expectEqual(
      test.expectedLeftoverSequence.map { $0.value }, s.map { $0.value },
      stackTrace: SourceLocStack().with(test.loc))
  }
}

//===----------------------------------------------------------------------===//
// count(where:)
//===----------------------------------------------------------------------===//

SequenceTypeTests.test("count/Predicate") {
  for test in predicateCountTests {
    let s = MinimalSequence<OpaqueValue<Int>>(
      elements: test.sequence.map { OpaqueValue($0) })
    expectEqual(
      test.expected,
      s.count(where: { test.includeElement($0.value) }),
      stackTrace: SourceLocStack().with(test.loc))
  }
}

//===----------------------------------------------------------------------===//
// reduce()
//===----------------------------------------------------------------------===//

SequenceTypeTests.test("reduce") {
  for test in reduceTests {
    let s = MinimalSequence<OpaqueValue<Int>>(
      elements: test.sequence.map(OpaqueValue.init))
    var timesClosureWasCalled = 0
    let result = s.reduce(OpaqueValue<[Int]>([])) {
      (partialResult: OpaqueValue<[Int]>, element: OpaqueValue<Int>)
        -> OpaqueValue<[Int]> in
      timesClosureWasCalled += 1
      return OpaqueValue<[Int]>(partialResult.value + [element.value])
    }
    expectEqual(test.sequence, result.value)
    expectEqual([], s.map { $0.value }, "sequence should be consumed")
    expectEqual(
      test.sequence.count, timesClosureWasCalled,
      "reduce() should be eager and should only call its predicate"
      + "once per element")
  }
}

//===----------------------------------------------------------------------===//
// reversed()
//===----------------------------------------------------------------------===//

SequenceTypeTests.test("reverse/Sequence") {
  for test in reverseTests {
    let s = MinimalSequence<OpaqueValue<Int>>(
      elements: test.sequence.map(OpaqueValue.init))
    var result = s.reversed()
    expectType([OpaqueValue<Int>].self, &result)
    expectEqual(
      test.expected, result.map { $0.value },
      stackTrace: SourceLocStack().with(test.loc))
    expectEqual([], s.map { $0.value }, "sequence should be consumed")
  }
}

SequenceTypeTests.test("reverse/WhereIndexIsBidirectional,BidirectionalReverseView") {
  for test in reverseTests {
    let s = MinimalBidirectionalCollection<OpaqueValue<Int>>(
      elements: test.sequence.map(OpaqueValue.init))
    var result = s.reversed()
    expectType(
      ReversedCollection<MinimalBidirectionalCollection<OpaqueValue<Int>>>.self,
      &result)
    expectEqual(
      test.expected, result.map { $0.value },
      stackTrace: SourceLocStack().with(test.loc))

    // Check ReversedCollection's Collection conformance.
    checkBidirectionalCollection(
      test.expected.map(OpaqueValue.init) as [OpaqueValue<Int>],
      result) { $0.value == $1.value }
  }
}

SequenceTypeTests.test("reverse/WhereIndexIsRandomAccess,RandomAccessReverseView") {
  for test in reverseTests {
    let s = MinimalRandomAccessCollection<OpaqueValue<Int>>(
      elements: test.sequence.map(OpaqueValue.init))
    var result = s.reversed()
    expectType(
      ReversedCollection<MinimalRandomAccessCollection<OpaqueValue<Int>>>.self,
      &result)
    expectEqual(
      test.expected, result.map { $0.value },
      stackTrace: SourceLocStack().with(test.loc))

    // Check ReversedRandomAccessCollection Collection conformance.
    let expected = test.expected.map(OpaqueValue.init) as [OpaqueValue<Int>]
    checkRandomAccessCollection(expected, result) { $0.value == $1.value }
  }
}

//===----------------------------------------------------------------------===//
// filter()
//===----------------------------------------------------------------------===//

SequenceTypeTests.test("filter/Sequence/Semantics") {
  for test in filterTests {
    for underestimatedCountBehavior in [
      UnderestimatedCountBehavior.precise,
      UnderestimatedCountBehavior.half,
      UnderestimatedCountBehavior.value(0)
    ] {

      let s = DefaultedSequence<OpaqueValue<Int>>(
        elements: test.sequence.map(OpaqueValue.init),
        underestimatedCount: underestimatedCountBehavior)

      let closureLifetimeTracker = LifetimeTracked(0)
      expectEqual(1, LifetimeTracked.instances)
      var timesClosureWasCalled = 0
      var result = s.filter {
        (element) in
        _blackHole(closureLifetimeTracker)
        timesClosureWasCalled += 1
        return test.includeElement(element.value)
      }
      expectType([OpaqueValue<Int>].self, &result)
      expectEqual(test.expected, result.map { $0.value })
      expectEqual([], s.map { $0.value }, "sequence should be consumed")
      expectEqual(
        test.sequence.count, timesClosureWasCalled,
        "filter() should be eager and should only call its predicate"
        + "once per element")
      expectGE(
        2 * result.count, result.capacity,
        "filter() should not reserve capacity (it does not know how much the"
        + "predicate will filter out)")
    }
  }
}

//===----------------------------------------------------------------------===//
// map()
//===----------------------------------------------------------------------===//

var MinimalSequenceWithCustomMap_timesMapWasCalled: Int = 0

% for Implementation in ['Default', 'Custom']:

struct MinimalSequenceWith${Implementation}Map<Element> : Sequence {
  init(_ data: [Element], underestimatedCount: UnderestimatedCountBehavior) {
    self._data = MinimalSequence(
      elements: data, underestimatedCount: underestimatedCount)
  }

  func makeIterator() -> MinimalIterator<Element> {
    return _data.makeIterator()
  }

  var _data: MinimalSequence<Element>


%   if Implementation == 'Custom':

  static var timesMapWasCalled: Int {
    get {
      return MinimalSequenceWithCustomMap_timesMapWasCalled
    }
    set {
      MinimalSequenceWithCustomMap_timesMapWasCalled = newValue
    }
  }

  func map<T>(
    _ transform: (Element) throws -> T
  ) rethrows -> [T] {
    MinimalSequenceWithCustomMap.timesMapWasCalled += 1
    return try _data.map(transform)
  }

%   end
}

% end

func callStaticSequenceMap<T>(
  _ sequence: MinimalSequenceWithDefaultMap<OpaqueValue<Int>>,
  transform: (OpaqueValue<Int>) -> T
) -> [T] {
  var result = sequence.map(transform)
  expectType([T].self, &result)
  return result
}

func callStaticSequenceMap<T>(
  _ sequence: MinimalSequenceWithCustomMap<OpaqueValue<Int>>,
  transform: (OpaqueValue<Int>) -> T
) -> [T] {
  var result = sequence.map(transform)
  expectType([T].self, &result)
  return result
}

func callGenericSequenceMap<S : Sequence, T>(
  _ sequence: S,
  transform: (S.Iterator.Element) -> T
) -> [T] {
  var result = sequence.map(transform)
  expectType([T].self, &result)
  return result
}

% for dispatch in ['Static', 'Generic']:

SequenceTypeTests.test(
  "map/Sequence/${Implementation}Implementation/${dispatch}"
) {
  for test in mapTests {
    for underestimatedCountBehavior in [
      UnderestimatedCountBehavior.precise,
      UnderestimatedCountBehavior.half,
      UnderestimatedCountBehavior.value(0)
    ] {
      let s = MinimalSequenceWith${Implementation}Map<OpaqueValue<Int>>(
        test.sequence.map(OpaqueValue.init),
        underestimatedCount: underestimatedCountBehavior)
      let closureLifetimeTracker = LifetimeTracked(0)
      expectEqual(1, LifetimeTracked.instances)
      var timesClosureWasCalled = 0
      var result = call${dispatch}SequenceMap(s) {
        (element: OpaqueValue<Int>) -> OpaqueValue<Int32> in
        _blackHole(closureLifetimeTracker)
        timesClosureWasCalled += 1
        return OpaqueValue(Int32(test.transform(element.value)))
      }
      expectType([OpaqueValue<Int32>].self, &result)
      expectEqual(test.expected, result.map { $0.value })
      expectEqual([], s.map { $0.value }, "sequence should be consumed")
      expectEqual(        test.sequence.count, timesClosureWasCalled,
        "map() should be eager and should only call its predicate"
        + "once per element")
    }
  }
}

% end

//===----------------------------------------------------------------------===//
// flatMap()
//===----------------------------------------------------------------------===//

SequenceTypeTests.test("flatMap/Sequence") {
  for test in flatMapTests {
    for underestimatedCountBehavior in [
      UnderestimatedCountBehavior.precise,
      UnderestimatedCountBehavior.value(0)
    ] {
      let s = MinimalSequence<OpaqueValue<Int>>(
        elements: test.sequence.map(OpaqueValue.init),
        underestimatedCount: underestimatedCountBehavior)
      let closureLifetimeTracker = LifetimeTracked(0)
      var timesClosureWasCalled = 0
      var result = s.flatMap {
        (element: OpaqueValue<Int>) -> MinimalSequence<OpaqueValue<Int32>> in
        _blackHole(closureLifetimeTracker)
        timesClosureWasCalled += 1
        return MinimalSequence<OpaqueValue<Int32>>(
          elements: test.transform(element.value).map { OpaqueValue(Int32($0)) })
      }
      expectType([OpaqueValue<Int32>].self, &result)
      expectEqual(
        test.expected, result.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectTrue(Array(s).isEmpty, "sequence should be consumed")
      expectEqual(
        test.sequence.count, timesClosureWasCalled,
        "flatMap() should be eager and should only call its predicate"
        + "once per element")
      expectGE(
        2 * result.count, result.capacity,
        "flatMap() should not reserve capacity")
    }
  }
}

% TLazyFlatMapTest = gyb.parse_template(os.path.join(os.path.dirname(__file__), "Inputs/flatMap.gyb"))
% LazyFlatMapTest = gyb.execute_template(TLazyFlatMapTest, Test='SequenceTypeTests', Kinds=['Sequence'])
${LazyFlatMapTest}

SequenceTypeTests.test("flatMap/Sequence/TransformProducesOptional") {
  for test in flatMapToOptionalTests {
    for underestimatedCountBehavior in [
      UnderestimatedCountBehavior.precise,
      UnderestimatedCountBehavior.value(0)
    ] {
      let s = MinimalSequence<OpaqueValue<Int>>(
        elements: test.sequence.map(OpaqueValue.init),
        underestimatedCount: underestimatedCountBehavior)
      let closureLifetimeTracker = LifetimeTracked(0)
      expectEqual(1, LifetimeTracked.instances)
      var timesClosureWasCalled = 0
      var result = s.compactMap {
        (element: OpaqueValue<Int>) -> OpaqueValue<Int32>? in
        _blackHole(closureLifetimeTracker)
        timesClosureWasCalled += 1
        return test.transform(element.value).map { OpaqueValue(Int32($0)) }
      }
      expectType([OpaqueValue<Int32>].self, &result)
      expectEqual(
        test.expected, result.map { $0.value },
        stackTrace: SourceLocStack().with(test.loc))
      expectTrue(Array(s).isEmpty, "sequence should be consumed")
      expectEqual(
        test.sequence.count, timesClosureWasCalled,
        "flatMap() should be eager and should only call its predicate"
        + "once per element")
      expectGE(
        2 * result.count, result.capacity,
        "flatMap() should not reserve capacity")
    }
  }
}

//===----------------------------------------------------------------------===//
// zip()
//===----------------------------------------------------------------------===//

// Check generic parameter names.
extension Zip2Sequence.Iterator
  where Sequence1 : TestProtocol1, Sequence2 : TestProtocol1 {

  var _generator1IsTestProtocol1: Bool {
    fatalError("not implemented")
  }
}

// Check generic parameter names.
extension Zip2Sequence
  where Sequence1 : TestProtocol1, Sequence2 : TestProtocol1 {

  var _sequence1IsTestProtocol1: Bool {
    fatalError("not implemented")
  }
}

SequenceTypeTests.test("zip") {
  typealias Element = (OpaqueValue<Int>, OpaqueValue<Int32>)
  func compareElements(_ lhs: Element, rhs: Element) -> Bool {
    return lhs.0.value == rhs.0.value && lhs.1.value == rhs.1.value
  }

  for test in zipTests {
    let s = MinimalSequence<OpaqueValue<Int>>(
      elements: test.sequence.map(OpaqueValue.init))
    let other = MinimalSequence<OpaqueValue<Int32>>(
      elements: test.other.map(OpaqueValue.init))
    var result = zip(s, other)
    expectType(
      Zip2Sequence<MinimalSequence<OpaqueValue<Int>>, MinimalSequence<OpaqueValue<Int32>>>.self,
      &result)

    // Check for expected result and check the Zip2Sequence's Sequence
    // conformance.
    checkSequence(
      test.expected.map { (OpaqueValue($0), OpaqueValue($1)) }, result,
      stackTrace: SourceLocStack().with(test.loc), sameValue: compareElements)

    // Check leftovers *after* doing checkSequence(), not before, to ensure
    // that checkSequence() didn't force us to consume more elements than
    // needed.
    expectEqual(
      test.expectedLeftoverSequence, s.map { $0.value },
      stackTrace: SourceLocStack().with(test.loc))
    expectEqual(
      test.expectedLeftoverOther, other.map { $0.value },
      stackTrace: SourceLocStack().with(test.loc))
  }
}

//===----------------------------------------------------------------------===//
// underestimatedCount
//===----------------------------------------------------------------------===//

struct SequenceWithDefaultUnderestimatedCount : Sequence {
  init() {}

  func makeIterator() -> MinimalSequence<OpaqueValue<Int>>.Iterator {
    expectUnreachable()
    return MinimalSequence(
      elements: [ 1, 2, 3 ].map(OpaqueValue.init)
    ).makeIterator()
  }
}

SequenceTypeTests.test("underestimatedCount/Sequence/DefaultImplementation") {
  let s = SequenceWithDefaultUnderestimatedCount()
  expectEqual(0, callGenericUnderestimatedCount(s))
}

struct SequenceWithCustomUnderestimatedCount : Sequence {
  init(underestimatedCount: Int) {
    self._underestimatedCount = underestimatedCount
  }

  func makeIterator() -> MinimalSequence<OpaqueValue<Int>>.Iterator {
    expectUnreachable()
    return MinimalSequence(
      elements: [ 0xffff, 0xffff, 0xffff ].map(OpaqueValue.init)
    ).makeIterator()
  }

  var underestimatedCount: Int {
    return _underestimatedCount
  }

  let _underestimatedCount: Int
}

SequenceTypeTests.test("underestimatedCount/Sequence/CustomImplementation") {
  do {
    let s = SequenceWithCustomUnderestimatedCount(underestimatedCount: 5)
    expectEqual(5, callGenericUnderestimatedCount(s))
  }
  do {
    let s = SequenceWithCustomUnderestimatedCount(underestimatedCount: 42)
    expectEqual(42, callGenericUnderestimatedCount(s))
  }
}

//===----------------------------------------------------------------------===//
// _copyToContiguousArray()
//===----------------------------------------------------------------------===//
SequenceTypeTests.test("_copyToContiguousArray/OverestimatedCount")
  .skip(.custom(
    { _isFastAssertConfiguration() },
    reason: "this trap is not guaranteed to happen in -Ounchecked"))
  .code {
  let s = MinimalSequence<OpaqueValue<Int>>(
    elements: [ 1, 2, 3 ].map(OpaqueValue.init),
    underestimatedCount: .value(4))
  expectCrashLater()
  let array = s._copyToContiguousArray()
  _blackHole(array)
}

//===----------------------------------------------------------------------===//
// Standard sequence tests
//===----------------------------------------------------------------------===//

% for Base in ['DefaultedSequence', 'MinimalSequence']:
do {
  let resiliencyChecks = CollectionMisuseResiliencyChecks.all

  SequenceTypeTests.addSequenceTests(
    makeSequence: { (elements: [OpaqueValue<Int>]) in
      return ${Base}(elements: elements)
    },
    wrapValue: identity,
    extractValue: identity,
    makeSequenceOfEquatable: { (elements: [MinimalEquatableValue]) in
      return ${Base}(elements: elements)
    },
    wrapValueIntoEquatable: identityEq,
    extractValueFromEquatable: identityEq,
    resiliencyChecks: resiliencyChecks)
}
% end

runAllTests()
