// -*- 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))
  }
}

//===----------------------------------------------------------------------===//
// 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))
  }
}

//===----------------------------------------------------------------------===//
// withContiguousStorageIfAvailable()
//===----------------------------------------------------------------------===//
SequenceTypeTests.test("withContiguousMutableStorageIfAvailable")
.code {
  let s = [ 1, 2, 3 ].map(OpaqueValue.init)
  let tester = SequenceLog.dispatchTester(s)
  let result = tester.withContiguousStorageIfAvailable { buf in
    buf.reduce(0) { $0 + $1.value }
  }
  expectEqual(6, result)
  expectCustomizable(tester, tester.log.withContiguousStorageIfAvailable)
}

//===----------------------------------------------------------------------===//
// _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()
