//===--- Lazy.swift - Tests for LazySequence and LazyCollection -----------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
// RUN: %target-run-simple-swiftgyb
// REQUIRES: executable_test


import StdlibUnittest
import StdlibCollectionUnittest

% from gyb_stdlib_support import TRAVERSALS, collectionForTraversal

var LazyTestSuite = TestSuite("Lazy")

protocol TestProtocol1 {}

//===----------------------------------------------------------------------===//
// repeatElement(), Repeated<Element>
//===----------------------------------------------------------------------===//

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

LazyTestSuite.test("Repeated/AssociatedTypes") {
  typealias Subject = Repeated<OpaqueValue<Int>>
  expectRandomAccessCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: IndexingIterator<Subject>.self,
    subSequenceType: RandomAccessSlice<Subject>.self,
    indexType: Int.self,
    indexDistanceType: Int.self,
    indicesType: CountableRange<Int>.self)
}

LazyTestSuite.test("repeatedValue()/TypeInference") {
  var r = repeatElement(OpaqueValue(42), count: 42)
  expectType(Repeated<OpaqueValue<Int>>.self, &r)
}

LazyTestSuite.test("repeatedValue()/NegativeCount") {
  expectCrashLater()
  _ = repeatElement(OpaqueValue(42), count: -1)
}

LazyTestSuite.test("Repeated")
  .forEach(in: [ 0, 1, 3 ]) {
  count in

  let c = repeatElement(OpaqueValue(42), count: count)
  expectEqual(0, c.startIndex)
  expectEqual(count, c.endIndex)
  expectEqual(count, c.count)
  expectEqual(42, c.repeatedValue.value)

  let expected = (0..<count).map { _ in OpaqueValue(42) }
  checkRandomAccessCollection(
    expected, c)
    { $0.value == $1.value }
}

// FIXME: trap tests.

//===----------------------------------------------------------------------===//
// IteratorOverOne
//===----------------------------------------------------------------------===//

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

LazyTestSuite.test("IteratorOverOne") {
  checkIterator(
    [] as Array<OpaqueValue<Int>>,
    IteratorOverOne(_elements: nil as Optional<OpaqueValue<Int>>))
  { $0.value == $1.value }

  checkIterator(
    [ OpaqueValue(42) ] as Array<OpaqueValue<Int>>,
    IteratorOverOne(_elements: OpaqueValue(42)))
  { $0.value == $1.value }
}

//===----------------------------------------------------------------------===//
// CollectionOfOne
//===----------------------------------------------------------------------===//

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

LazyTestSuite.test("CollectionOfOne") {
  let c = CollectionOfOne(OpaqueValue(42))
  expectEqual(0, c.startIndex)
  expectEqual(1, c.endIndex)
  expectEqual(0..<1, c.indices)

  checkRandomAccessCollection(
    [ OpaqueValue(42) ], c) { $0.value == $1.value }
}

LazyTestSuite.test("CollectionOfOne/AssociatedTypes") {
  typealias Subject = CollectionOfOne<OpaqueValue<Int>>
  expectRandomAccessCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: IteratorOverOne<OpaqueValue<Int>>.self,
    subSequenceType: MutableRandomAccessSlice<Subject>.self,
    indexType: Int.self,
    indexDistanceType: Int.self,
    indicesType: CountableRange<Int>.self)
}

% for (name, operation, indices) in [
%   ('index(after:)', '_ = c.index(after: i)', '-2, -1, 1, 2'),
%   ('index(before:)', '_ = c.index(before: i)', '-1, 0, 2'),
%   ('subscript(Index)/Get', '_ = c[i]', '-2, -1, 1, 2'),
%   ('subscript(Index)/Set', 'c[i] = OpaqueValue(42)', '-2, -1, 1, 2'),
% ]:
LazyTestSuite.test("CollectionOfOne/${name}")
  .forEach(in: [${indices}]) {
  i in

  var c = CollectionOfOne<OpaqueValue<Int>>(OpaqueValue(42))
  expectCrashLater()
  ${operation}
}
% end

LazyTestSuite.test("CollectionOfOne/index(after:), index(before:)") {
  let c = CollectionOfOne<OpaqueValue<Int>>(OpaqueValue(42))
  expectEqual(1, c.index(after: 0))
  expectEqual(0, c.index(before: 1))
}

LazyTestSuite.test("CollectionOfOne/subscript(Index)/Get/Set/NoTrap") {
  var c = CollectionOfOne<OpaqueValue<Int>>(OpaqueValue(42))
  c[0] = OpaqueValue(4242)
  expectEqual(4242, c[0].value)
  expectEqualSequence([OpaqueValue(4242)], c) { $0.value == $1.value }
}

% for (name, operation) in [
%   ('subscript(Range<Index>)/Get', '_ = c[r]'),
%   ('subscript(Range<Index>)/Set', 'c[r] = slice'),
% ]:
LazyTestSuite.test("CollectionOfOne/${name}/Trap")
  .forEach(in: [
    -1 ..< -1, -1..<0, -1..<1, 1..<2, 2..<2,
  ] as [Range<Int>]) {
  r in
  var c = CollectionOfOne<OpaqueValue<Int>>(OpaqueValue(42))
  let slice = r.count == 0 ? c[0..<0] : c[0..<1]
  expectCrashLater()
  ${operation}
}
% end

LazyTestSuite.test("CollectionOfOne/subscript(Range<Index>)/Set/DifferentLength/Trap")
  .forEach(in: [ 0..<0, 0..<1, 1..<1 ] as [Range<Int>]) {
  r in
  var c = CollectionOfOne<OpaqueValue<Int>>(OpaqueValue(42))
  let slice = r.count == 0 ? c[0..<1] : c[0..<0]
  expectCrashLater()
  c[r] = slice
}

LazyTestSuite.test("CollectionOfOne/subscript(Range<Index>)/Get/Set/Empty/NoTrap") {
  var c = CollectionOfOne<OpaqueValue<Int>>(OpaqueValue(42))
  let slice0 = c[0..<0]
  let slice1 = c[1..<1]
  checkRandomAccessCollection([], slice0) { $0.value == $1.value }
  checkRandomAccessCollection([], slice1) { $0.value == $1.value }
  c[0..<0] = slice0
  c[0..<0] = slice1
  c[1..<1] = slice0
  c[1..<1] = slice1
  expectEqualSequence([OpaqueValue(42)], c) { $0.value == $1.value }
}

LazyTestSuite.test("CollectionOfOne/{CustomDebugStringConvertible,CustomReflectable}") {
  let c = CollectionOfOne(CustomPrintableValue(42))
  expectPrinted("CollectionOfOne((value: 42).debugDescription)", c)
  expectDebugPrinted("CollectionOfOne((value: 42).debugDescription)", c)
  expectDumped(
    "▿ CollectionOfOne((value: 42).debugDescription)\n" +
    "  ▿ element: (value: 42).debugDescription\n" +
    "    - value: 42\n" +
    "    - identity: 0\n",
    c)
}

//===----------------------------------------------------------------------===//
// EmptyCollection
//===----------------------------------------------------------------------===//

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

LazyTestSuite.test("EmptyCollection") {
  let c = EmptyCollection<OpaqueValue<Int>>()
  expectEqual(0, c.startIndex)
  expectEqual(0, c.endIndex)
  expectEqual(0..<0, c.indices)

  checkRandomAccessCollection([], c) { $0.value == $1.value }
}

LazyTestSuite.test("EmptyCollection/CustomReflectable") {
  let c = EmptyCollection<OpaqueValue<Int>>()
  expectPrinted("EmptyCollection<OpaqueValue<Int>>()", c)
  expectDebugPrinted("Swift.EmptyCollection<StdlibUnittest.OpaqueValue<Swift.Int>>()", c)
  expectDumped(
    "- Swift.EmptyCollection<StdlibUnittest.OpaqueValue<Swift.Int>>\n",
    c)
}

LazyTestSuite.test("EmptyCollection/Equatable") {
  let instances = [ EmptyCollection<OpaqueValue<Int>>() ]
  checkEquatable(instances, oracle: { $0 == $1 })
}

LazyTestSuite.test("EmptyCollection/AssociatedTypes") {
  typealias Subject = EmptyCollection<OpaqueValue<Int>>
  expectRandomAccessCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: EmptyIterator<OpaqueValue<Int>>.self,
    subSequenceType: Subject.self,
    indexType: Int.self,
    indexDistanceType: Int.self,
    indicesType: CountableRange<Int>.self)
}

% for (name, operation) in [
%   ('index(after:)', '_ = c.index(after: i)'),
%   ('index(before:)', '_ = c.index(before: i)'),
%   ('subscript(Index)/Get', '_ = c[i]'),
%   ('subscript(Index)/Set', 'c[i] = OpaqueValue(42)'),
% ]:
LazyTestSuite.test("EmptyCollection/${name}")
  .forEach(in: [-1, 0, 1]) {
  i in

  var c = EmptyCollection<OpaqueValue<Int>>()
  expectCrashLater()
  ${operation}
}
% end

% for (name, operation) in [
%   ('subscript(Range<Index>)/Get', '_ = c[r]'),
%   ('subscript(Range<Index>)/Set', 'c[r] = c'),
% ]:
LazyTestSuite.test("EmptyCollection/${name}/Trap")
  .forEach(in: [-1 ..< -1, -1..<0, -1..<1, 0..<1, 1..<1] as [Range<Int>]) {
  r in
  var c = EmptyCollection<OpaqueValue<Int>>()
  // Access is guarded by a _debugPrecondition in EmptyCollection
  if _isDebugAssertConfiguration() {
    expectCrashLater()
  }
  ${operation}
}

LazyTestSuite.test("EmptyCollection/${name}/NoTrap") {
  var c = EmptyCollection<OpaqueValue<Int>>()
  let r: Range<Int> = 0..<0
  ${operation}
  expectEqualSequence([], c[0..<0]) { $0.value == $1.value }
}
% end

LazyTestSuite.test("EmptyCollection/index(_:offsetBy:)/Trap")
  .forEach(in: [
    (-1, -1), (-1, 0), (-1, 1),
    (0, 1), (0, -1),
    (1, -1), (1, 0), (1, 1),
  ]) {
  (i, offset) in
  let c = EmptyCollection<OpaqueValue<Int>>()
  // Access is guarded by a _debugPrecondition in EmptyCollection
  if _isDebugAssertConfiguration() {
    expectCrashLater()
  }
  _ = c.index(i, offsetBy: offset)
}

LazyTestSuite.test("EmptyCollection/index(_:offsetBy:)/NoTrap") {
  let c = EmptyCollection<OpaqueValue<Int>>()
  expectEqual(c.startIndex, c.index(c.startIndex, offsetBy: 0))
}

LazyTestSuite.test("EmptyCollection/index(_:offsetBy:limitedBy:)/Trap")
  .forEach(in: [
    (-1, 0, 0), (-1, 1, 0),
    (0, 0, -1), (0, 0, 1),
    (1, -1, 0), (1, 0, 0), (1, 0, 1),
  ]) {
  (i, offset, limit) in
  let c = EmptyCollection<OpaqueValue<Int>>()
  // Access is guarded by a _debugPrecondition in EmptyCollection
  if _isDebugAssertConfiguration() {
    expectCrashLater()
  }
  _ = c.index(i, offsetBy: offset, limitedBy: limit)
}

LazyTestSuite.test("EmptyCollection/index(_:offsetBy:limitedBy:)/NoTrap")
  .forEach(in: [
    -10, -1, 0, 1, 10,
  ]) {
  offset in
  let c = EmptyCollection<OpaqueValue<Int>>()
  let result =
    c.index(c.startIndex, offsetBy: offset, limitedBy: c.startIndex)
  if offset == 0 {
    expectOptionalEqual(c.startIndex, result)
  } else {
    expectNil(result)
  }
}

LazyTestSuite.test("EmptyCollection/distance(from:to:)/Trap")
  .forEach(in: [
    (-1, -1), (-1, 0), (-1, 1),
    (0, 1), (0, -1),
    (1, -1), (1, 0), (1, 1),
  ]) {
  (start, end) in
  let c = EmptyCollection<OpaqueValue<Int>>()
  // Access is guarded by a _debugPrecondition in EmptyCollection
  if _isDebugAssertConfiguration() {
    expectCrashLater()
  }
  _ = c.distance(from: start, to: end)
}

LazyTestSuite.test("EmptyCollection/distance(from:to:)/NoTrap") {
  let c = EmptyCollection<OpaqueValue<Int>>()
  expectEqual(0, c.distance(from: 0, to: 0))
}

LazyTestSuite.test("EmptyCollection/_failEarlyRangeCheck/NoTrap") {
  let c = EmptyCollection<OpaqueValue<Int>>()
  c._failEarlyRangeCheck(0, bounds: 0..<0)
  c._failEarlyRangeCheck(0..<0, bounds: 0..<0)
}

//===----------------------------------------------------------------------===//
// EmptyIterator
//===----------------------------------------------------------------------===//

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

LazyTestSuite.test("EmptyIterator") {
  checkIterator(
    [] as Array<OpaqueValue<Int>>,
    EmptyIterator<OpaqueValue<Int>>())
    { $0.value == $1.value }
}

// FIXME: trap tests.

//===----------------------------------------------------------------------===//
// lazy
//===----------------------------------------------------------------------===//

LazyTestSuite.test("isEmpty") {
  expectTrue((0..<0).lazy.isEmpty)
  expectFalse((0...0).lazy.isEmpty)
}

LazyTestSuite.test("first") {
  expectOptionalEqual(7, (7..<42).lazy.first)
}

LazyTestSuite.test("first empty") {
  expectNil((7..<7).lazy.first)
}

LazyTestSuite.test("last") {
  expectOptionalEqual(41, (7..<42).lazy.last)
}

LazyTestSuite.test("last empty") {
  expectNil((7..<7).lazy.last)
}

//===----------------------------------------------------------------------===//
// LazySequence
//===----------------------------------------------------------------------===//

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

LazyTestSuite.test("LazySequence<Sequence>/underestimatedCount") {
  let s = MinimalSequence(
    elements: [ 0, 30, 10, 90 ].map(OpaqueValue.init),
    underestimatedCount: .value(42))
  var lazySeq = s.lazy
  expectType(LazySequence<MinimalSequence<OpaqueValue<Int>>>.self, &lazySeq)
  expectEqual(42, lazySeq.underestimatedCount)
}

% for Traversal in TRAVERSALS:
%   TraversalCollection = collectionForTraversal(Traversal)

LazyTestSuite.test("LazySequence<${TraversalCollection}>/underestimatedCount") {
  let s = Minimal${TraversalCollection}(
    elements: [ 0, 30, 10, 90 ].map(OpaqueValue.init),
    underestimatedCount: .value(42))
  var lazySeq = s.lazy
  expectType(
    Lazy${TraversalCollection}<
      Minimal${TraversalCollection}<OpaqueValue<Int>>
    >.self,
    &lazySeq)
  expectEqual(42, lazySeq.underestimatedCount)
}

% end

//===----------------------------------------------------------------------===//
// MapSequence
//===----------------------------------------------------------------------===//

LazyTestSuite.test("MapSequence<Sequence>/underestimatedCount") {
  let s = MinimalSequence(
    elements: [ 0, 30, 10, 90 ].map(OpaqueValue.init),
    underestimatedCount: .value(42))
  var lazyMap = s.lazy.map { OpaqueValue(Int32($0.value)) }
  expectType(
    LazyMapSequence<MinimalSequence<OpaqueValue<Int>>, OpaqueValue<Int32>>.self,
    &lazyMap)
  expectEqual(42, lazyMap.underestimatedCount)
}

struct SequenceWithCustomUnderestimatedCount : Sequence {
  init(_ data: [Int]) {
    self._data = MinimalSequence(elements: data.map(OpaqueValue.init))
  }

  func makeIterator() -> MinimalSequence<OpaqueValue<Int>>.Iterator {
    return _data.makeIterator()
  }

  var underestimatedCount: Int {
    SequenceWithCustomUnderestimatedCount.timesUnderestimatedCountWasCalled += 1
    return _data.underestimatedCount
  }

  static var timesUnderestimatedCountWasCalled: Int = 0

  let _data: MinimalSequence<OpaqueValue<Int>>
}

LazyTestSuite.test("LazySequence.array") {
  SequenceWithCustomUnderestimatedCount.timesUnderestimatedCountWasCalled = 0

  let base = SequenceWithCustomUnderestimatedCount([ 0, 30, 10, 90 ])

  expectEqual([ 0, 30, 10, 90 ], base.lazy.map { $0.value })

  // Lazy sequences should use underestimated count to preallocate array
  // storage.
  expectEqual(1, SequenceWithCustomUnderestimatedCount.timesUnderestimatedCountWasCalled)

  expectEqualSequence(
    [], Array(base).map { $0.value }, "sequence should be consumed")
}

% for Traversal in TRAVERSALS:
%   TraversalCollection = collectionForTraversal(Traversal)

LazyTestSuite.test("MapCollection<${TraversalCollection}>/underestimatedCount") {
  let s = Minimal${TraversalCollection}(
    elements: [ 0, 30, 10, 90 ].map(OpaqueValue.init),
    underestimatedCount: .value(42))
  var lazyMap = s.lazy.map {
    (input: OpaqueValue<Int>) -> OpaqueValue<Int32> in
    OpaqueValue(Int32(input.value))
  }
  expectType(
    LazyMap${TraversalCollection}<
      Minimal${TraversalCollection}<OpaqueValue<Int>>, OpaqueValue<Int32>
    >.self,
    &lazyMap)
  expectEqual(42, lazyMap.underestimatedCount)
}

% end

//===----------------------------------------------------------------------===//
// LazyCollection
//===----------------------------------------------------------------------===//

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

%for (Traversal, ReversedType) in [
%    ('Forward', None),
%    ('Bidirectional', 'ReversedCollection'),
%    ('RandomAccess', 'ReversedRandomAccessCollection')
%]:
%  TraversalCollection = collectionForTraversal(Traversal)

LazyTestSuite.test("Lazy${TraversalCollection}.array") {
  let base = Minimal${TraversalCollection}(
    elements: [ 0, 30, 10, 90 ], underestimatedCount: .value(42))
  let arrayFromLazy = Array(base.lazy)

  expectEqual([ 0, 30, 10, 90 ], arrayFromLazy)

  // Lazy collections should not use underestimated count to preallocate array
  // storage, since they have access to real count instead.
  expectLE(4, arrayFromLazy.capacity)
  expectGE(40, arrayFromLazy.capacity)
}

%  if ReversedType is not None:

LazyTestSuite.test("Lazy${TraversalCollection}.reversed") {
  let base = Minimal${TraversalCollection}(
    elements: [ 0, 30, 10, 90 ].map(OpaqueValue.init),
    underestimatedCount: .value(42))
  var reversed = base.lazy.reversed()
  expectType(
    Lazy${TraversalCollection}<
      ${ReversedType}<Minimal${TraversalCollection}<OpaqueValue<Int>>>
    >.self, &reversed)

  let expected: [OpaqueValue<Int>] = [ 90, 10, 30, 0 ].map(OpaqueValue.init)
  check${Traversal}Collection(expected, reversed) { $0.value == $1.value }

  var reversedTwice = reversed.reversed()
  expectType(
    Lazy${TraversalCollection}<
      ${ReversedType}<${ReversedType}<
        Minimal${TraversalCollection}<OpaqueValue<Int>>
      >>>.self, &reversedTwice)

  check${Traversal}Collection(
    [ 0, 30, 10, 90 ].map(OpaqueValue.init) as [OpaqueValue<Int>],
    reversedTwice) { $0.value == $1.value }
}

%  end

%end

//===----------------------------------------------------------------------===//
// ReversedCollection
//===----------------------------------------------------------------------===//

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

//===----------------------------------------------------------------------===//
// ReversedIndex
//===----------------------------------------------------------------------===//

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

//===----------------------------------------------------------------------===//
// RandomAccessReversedCollection
//===----------------------------------------------------------------------===//

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

//===----------------------------------------------------------------------===//
// ReversedRandomAccessIndex
//===----------------------------------------------------------------------===//

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

var tests = TestSuite("NewLazy")

tests.test("LazySequence/Sequence") {
  let expected = (0..<100).map(OpaqueValue.init)
  var actual = MinimalSequence(elements: expected).lazy

  expectType(
    LazySequence<MinimalSequence<OpaqueValue<Int>>>.self, &actual)

  // Asking for .lazy again doesn't re-wrap the type
  var again = actual.lazy
  expectType(
    LazySequence<MinimalSequence<OpaqueValue<Int>>>.self, &again)

  var elements = actual.elements

  // Expect .elements to strip a lazy wrapper
  expectType(MinimalSequence<OpaqueValue<Int>>.self, &elements)

  checkSequence(expected, actual, resiliencyChecks: .none) {
    $0.value == $1.value
  }
}

func expectSequencePassthrough<
  S : LazySequenceProtocol,
  Base : Sequence
>(_ s: S, base: Base, arbitraryElement: S.Iterator.Element, count: Int)
where Base : LoggingType,
Base.Iterator.Element == S.Iterator.Element {
  let baseType = type(of: base)

  SequenceLog.makeIterator.expectIncrement(baseType) { _ = s.makeIterator() }
  SequenceLog.underestimatedCount.expectIncrement(baseType) {
    _ = s.underestimatedCount
  }
  SequenceLog._customContainsEquatableElement.expectIncrement(baseType) {
    _ = s._customContainsEquatableElement(arbitraryElement)
  }
  SequenceLog._copyToContiguousArray.expectIncrement(baseType) {
    _ = s._copyToContiguousArray()
  }

  SequenceLog._copyContents.expectIncrement(baseType) { () -> Void in
    let ptr = UnsafeMutablePointer<S.Iterator.Element>.allocate(capacity: count)
    let buf = UnsafeMutableBufferPointer(start: ptr, count: count)
    var (remainders,writtenUpTo) = s._copyContents(initializing: buf)
    expectTrue(remainders.next() == nil, 
      "_copyContents returned unwritten elements")
    expectTrue(writtenUpTo == buf.endIndex, 
      "_copyContents failed to use entire buffer")
    ptr.deinitialize(count: count)
    ptr.deallocate(capacity: count)
  }
}

tests.test("LazySequence/Passthrough") {
  // Test that operations that might be optimized are passed
  // through to the underlying sequence.
  let a = (0..<100).map(OpaqueValue.init)
  let base = LoggingSequence(wrapping: a)

  expectSequencePassthrough(
    base.lazy,
    base: base, arbitraryElement: OpaqueValue(0), count: a.count)
}

% for Traversal in TRAVERSALS:
%   TraversalCollection = collectionForTraversal(Traversal)

tests.test("Lazy${TraversalCollection}/Collection") {
  let expected = (0..<100).map(OpaqueValue.init)
  let base = Minimal${TraversalCollection}(elements: expected)
  var actual = base.lazy

  expectType(Lazy${TraversalCollection}<
    Minimal${TraversalCollection}<OpaqueValue<Int>>
  >.self, &actual)

  // Asking for .lazy again doesn't re-wrap the type
  var again = actual.lazy
  expectType(Lazy${TraversalCollection}<
    Minimal${TraversalCollection}<OpaqueValue<Int>>
  >.self, &again)

  checkOneLevelOf${Traversal}Collection(
    expected, base.lazy, resiliencyChecks: .none
  ) { $0.value == $1.value }

  var elements = base.lazy.elements
  expectType(Minimal${TraversalCollection}<OpaqueValue<Int>>.self, &elements)
}

% end

tests.test("LazyCollection/Passthrough") {
  let expected = (0..<100).map(OpaqueValue.init)
  let base = LoggingCollection(wrapping: expected)

  expectSequencePassthrough(
    base.lazy,
    base: base.lazy._base,
    arbitraryElement: OpaqueValue(0),
    count: Int(expected.count))

  let s = base.lazy
  let baseType = type(of: base)
  let startIndex = CollectionLog.startIndex.expectIncrement(baseType) {
    s.startIndex
  }

  let endIndex = CollectionLog.endIndex.expectIncrement(baseType) {
    s.endIndex
  }

  CollectionLog.subscriptIndex.expectIncrement(baseType) { _ = s[startIndex] }
  CollectionLog.subscriptRange.expectUnchanged(baseType) {
    _ = s[startIndex..<endIndex]
  }
  CollectionLog.isEmpty.expectIncrement(baseType) { _ = s.isEmpty }
  CollectionLog.count.expectIncrement(baseType) { _ = s.count }
  CollectionLog._customIndexOfEquatableElement.expectIncrement(baseType) {
    _ = s._customIndexOfEquatableElement(OpaqueValue(0))
  }
  CollectionLog.first.expectIncrement(baseType) { _ = s.first }
}

//===--- Map --------------------------------------------------------------===//

tests.test("LazyMapSequence") {
  let base = MinimalSequence(
    elements: [2, 3, 5, 7, 11].map(OpaqueValue.init)).lazy

  var calls = 0
  var mapped = base.map {
    (x: OpaqueValue<Int>) -> OpaqueValue<Double> in
    calls += 1
    return OpaqueValue(Double(x.value) / 2.0)
  }

  expectEqual(0, calls)

  expectType(
    LazyMapSequence<
      MinimalSequence<OpaqueValue<Int>>,
      OpaqueValue<Double>>.self,
    &mapped)

  let expected = [ 1.0, 1.5, 2.5, 3.5, 5.5 ].map(OpaqueValue.init)

  checkSequence(expected, mapped, resiliencyChecks: .none) {
    $0.value == $1.value
  }

  expectEqual(expected.count, calls)
}

tests.test("MapSequence/Passthrough") {
  let expected = (0..<100).map(OpaqueValue.init)
  let base = LoggingSequence(wrapping: expected)
  let mapped = base.lazy.map { OpaqueValue(Double($0.value) / 2.0) }
  CollectionLog.underestimatedCount.expectIncrement(type(of: base)) {
    _ = mapped.underestimatedCount
  }
  // Not exactly passthrough because we wrap the result
  CollectionLog.makeIterator.expectIncrement(type(of: base)) {
    _ = mapped.makeIterator()
  }
}

% for Traversal in TRAVERSALS:
%   TraversalCollection = collectionForTraversal(Traversal)

tests.test("LazyMap${TraversalCollection}/Collection") {
  let base = Minimal${TraversalCollection}(
    elements: [2, 3, 5, 7, 11].map(OpaqueValue.init)).lazy

  var calls = 0
  var mapped = base.map {
    (x: OpaqueValue<Int>) -> OpaqueValue<Double> in
    calls += 1
    return OpaqueValue(Double(x.value) / 2.0)
  }
  expectEqual(0, calls)

  expectType(
    LazyMap${TraversalCollection}<
      Minimal${TraversalCollection}<OpaqueValue<Int>>,
      OpaqueValue<Double>>.self,
    &mapped)

  let expected = [ 1.0, 1.5, 2.5, 3.5, 5.5 ].map(OpaqueValue.init)

  check${Traversal}Collection(expected, mapped, resiliencyChecks: .none) {
    $0.value == $1.value
  }

  // check${Traversal}Collection makes multiple passes over the input,
  // so we test that each element was transformed *at least* once.
  expectLE(expected.count, calls)
}

%end

tests.test("LazyMapCollection/Passthrough") {
  let expected = (0..<100).map(OpaqueValue.init)
  let base = LoggingCollection(wrapping: expected)
  let mapped = base.lazy.map { OpaqueValue(Double($0.value) / 2.0) }

  let startIndex = CollectionLog.startIndex.expectIncrement(type(of: base)) {
    mapped.startIndex
  }
  _ = CollectionLog.endIndex.expectIncrement(type(of: base)) {
    mapped.endIndex
  }
  // Not exactly passthrough, because mapping transforms the result
  CollectionLog.subscriptIndex.expectIncrement(type(of: base)) {
    _ = mapped[startIndex]
  }
  CollectionLog.isEmpty.expectIncrement(type(of: base)) {
    _ = mapped.isEmpty
  }
  CollectionLog.first.expectIncrement(type(of: base)) {
    _ = mapped.first
  }
  CollectionLog.underestimatedCount.expectIncrement(type(of: base)) {
    _ = mapped.underestimatedCount
  }
  // Not exactly passthrough because we wrap the result
  CollectionLog.makeIterator.expectIncrement(type(of: base)) {
    _ = mapped.makeIterator()
  }
}

tests.test("LazyMapSequence/AssociatedTypes") {
  typealias Base = MinimalSequence<OpaqueValue<Int>>
  typealias Subject = LazyMapSequence<Base, OpaqueValue<Int32>>
  expectSequenceAssociatedTypes(
    sequenceType: Subject.self,
    iteratorType: LazyMapIterator<Base.Iterator, OpaqueValue<Int32>>.self,
    subSequenceType: AnySequence<OpaqueValue<Int32>>.self)
}

tests.test("LazyMapCollection/AssociatedTypes") {
  typealias Base = MinimalCollection<OpaqueValue<Int>>
  typealias Subject = LazyMapCollection<Base, OpaqueValue<Int32>>
  expectCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: LazyMapIterator<Base.Iterator, OpaqueValue<Int32>>.self,
    // FIXME(ABI)#77 (Associated Types with where clauses): SubSequence should be `LazyMapCollection<Base.Slice>`.
    subSequenceType: Slice<Subject>.self,
    indexType: Base.Index.self,
    indexDistanceType: Base.IndexDistance.self,
    indicesType: Base.Indices.self)
}

tests.test("LazyMapBidirectionalCollection/AssociatedTypes") {
  typealias Base = MinimalBidirectionalCollection<OpaqueValue<Int>>
  typealias Subject = LazyMapBidirectionalCollection<Base, OpaqueValue<Int32>>
  expectBidirectionalCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: LazyMapIterator<Base.Iterator, OpaqueValue<Int32>>.self,
    // FIXME(ABI)#78 (Associated Types with where clauses): SubSequence should be `LazyMapBidirectionalCollection<Base.Slice>`.
    subSequenceType: BidirectionalSlice<Subject>.self,
    indexType: Base.Index.self,
    indexDistanceType: Base.IndexDistance.self,
    indicesType: Base.Indices.self)
}

tests.test("LazyMapRandomAccessCollection/AssociatedTypes") {
  typealias Base = MinimalRandomAccessCollection<OpaqueValue<Int>>
  typealias Subject = LazyMapRandomAccessCollection<Base, OpaqueValue<Int32>>
  expectRandomAccessCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: LazyMapIterator<Base.Iterator, OpaqueValue<Int32>>.self,
    // FIXME(ABI)#79 (Associated Types with where clauses): SubSequence should be `LazyMapRandomAccessCollection<Base.Slice>`.
    subSequenceType: RandomAccessSlice<Subject>.self,
    indexType: Base.Index.self,
    indexDistanceType: Base.IndexDistance.self,
    indicesType: Base.Indices.self)
}

tests.test("lazy.mapped/TypeInference") {
  let baseArray: [OpaqueValue<Int>] = (0..<10).map(OpaqueValue.init)
  do {
    var mapped = MinimalSequence(elements: baseArray)
      .lazy.map { _ in OpaqueValue<Int8>(0) }
    expectType(
      LazyMapSequence<
        MinimalSequence<OpaqueValue<Int>>,
        OpaqueValue<Int8>
      >.self,
      &mapped)
  }
  do {
    var mapped = MinimalCollection(elements: baseArray)
      .lazy.map { _ in OpaqueValue<Int8>(0) }
    expectType(
      LazyMapCollection<
        MinimalCollection<OpaqueValue<Int>>,
        OpaqueValue<Int8>
      >.self,
      &mapped)
  }
  do {
    var mapped = MinimalBidirectionalCollection(elements: baseArray)
      .lazy.map { _ in OpaqueValue<Int8>(0) }
    expectType(
      LazyMapBidirectionalCollection<
        MinimalBidirectionalCollection<OpaqueValue<Int>>,
        OpaqueValue<Int8>
      >.self,
      &mapped)
  }
  do {
    var mapped = MinimalRandomAccessCollection(elements: baseArray)
      .lazy.map { _ in OpaqueValue<Int8>(0) }
    expectType(
      LazyMapRandomAccessCollection<
        MinimalRandomAccessCollection<OpaqueValue<Int>>,
        OpaqueValue<Int8>
      >.self,
      &mapped)
  }
}

//===--- Reverse ----------------------------------------------------------===//
tests.test("ReversedCollection") {
  let expected = Array(stride(from: 11, through: 0, by: -1))
  let r = 0..<12
  checkRandomAccessCollection(
    expected,
    r.reversed())

  // Check that the reverse collection is still eager
  do {
    var calls = 0
    _ = r.reversed().map { _ in calls += 1 }
    expectEqual(r.count, calls)
  }

  checkBidirectionalCollection(
    "raboof".characters,
    "foobar".characters.reversed())

  // Check that the reverse collection is still eager
  do {
    var calls = 0
    _ = "foobar".characters.reversed().map { _ in calls += 1 }
    expectEqual("foobar".characters.count, calls)
  }
}

enum _Void {}
struct ExpectType<T> {
  static func test(_: T){ print("T") }
  static func test(_: Any) { fatalError() }
  static func test(_: Any) -> _Void { fatalError() }
}

tests.test("ReversedCollection/Lazy") {
  // Check that reversing a lazy collection, or lazy-ing a reverse
  // collection, produces the same lazy reverse collection.
  do {

    let base = Array(stride(from: 11, through: 0, by: -1)).lazy.map { $0 }

    typealias Base = LazyMapRandomAccessCollection<[Int], Int>
    ExpectType<Base>.test(base)

    typealias LazyReversedBase = LazyRandomAccessCollection<
      ReversedRandomAccessCollection<Base>>

    let reversed = base.reversed()
    ExpectType<LazyReversedBase>.test(reversed)

    var calls = 0
    let reversedAndMapped = reversed.map { (x) -> Int in calls += 1; return x }
    expectEqual(0, calls)
    checkRandomAccessCollection(0...11, reversedAndMapped)
    expectNotEqual(0, calls)
  }

  do {
    typealias Expected = LazyBidirectionalCollection<
      ReversedCollection<String.CharacterView>
    >

    let base = "foobar".characters.lazy.map { $0 }
    typealias Base = LazyMapBidirectionalCollection<
      String.CharacterView, Character>
    ExpectType<Base>.test(base)

    typealias LazyReversedBase = LazyBidirectionalCollection<
      ReversedCollection<Base>>

    let reversed = base.reversed()
    ExpectType<LazyReversedBase>.test(reversed)

    var calls = 0
    let reversedAndMapped = reversed.map { (x) -> Character in calls += 1; return x }
    expectEqual(0, calls)
    checkBidirectionalCollection("raboof".characters, reversedAndMapped)
    expectNotEqual(0, calls)
  }
}

// Given a couple of sequences backed by FilterGenerator's, check that
// the first selects even numbers and the second selects odd numbers,
// both from an underlying sequence of whole numbers.
func checkFilterIteratorBase<  S : Sequence, I>(_ s1: S, _ s2: S)
where S.Iterator == LazyFilterIterator<I>, I.Element == OpaqueValue<Int> {
  var iter1 = s1.makeIterator()
  expectEqual(0, iter1.next()!.value)
  expectEqual(2, iter1.next()!.value)
  expectEqual(4, iter1.next()!.value)
  var h1 = iter1.base
  expectEqual(5, h1.next()!.value)
  expectEqual(6, h1.next()!.value)
  expectEqual(7, h1.next()!.value)

  var iter2 = s2.makeIterator()
  expectEqual(1, iter2.next()!.value)
  expectEqual(3, iter2.next()!.value)
  expectEqual(5, iter2.next()!.value)
  var h2 = iter2.base
  expectEqual(6, h2.next()!.value)
  expectEqual(7, h2.next()!.value)
  expectEqual(8, h2.next()!.value)
}

tests.test("LazyFilterSequence") {
  let base = (0..<100).map(OpaqueValue.init)

  var calls = 0
  var filtered = MinimalSequence(elements: base).lazy.filter {
    x in calls += 1;
    return x.value % 2 == 0
  }
  expectEqual(calls, 0, "filtering was eager!")

  ExpectType<
    LazyFilterSequence<MinimalSequence<OpaqueValue<Int>>>
  >.test(filtered)

  let evens = stride(from: 0, to: 100, by: 2).map(OpaqueValue.init)
  checkSequence(evens, filtered, resiliencyChecks: .none) {
    $0.value == $1.value
  }
  expectEqual(100, calls)

  // Check that it works when the first element doesn't satisfy the predicate
  let odds = stride(from: 1, to: 100, by: 2).map(OpaqueValue.init)
  filtered =
    MinimalSequence(elements: base).lazy.filter { $0.value % 2 != 0 }
  checkSequence(odds, filtered, resiliencyChecks: .none) {
    $0.value == $1.value
  }

  // Try again using explicit construction
  filtered = LazyFilterSequence(
    _base: MinimalSequence(elements: base),
    { x in calls += 1; return x.value % 2 == 0})

  expectEqual(100, calls)

  // Check that it constructs the same sequence
  checkSequence(evens, filtered, resiliencyChecks: .none) {
    $0.value == $1.value
  }

  expectEqual(200, calls)

  checkFilterIteratorBase(
    MinimalSequence(elements: base).lazy.filter { $0.value % 2 == 0 },
    MinimalSequence(elements: base).lazy.filter { $0.value % 2 != 0 })
}

tests.test("LazyFilterIndex/base") {
  let base = MinimalCollection(elements: (0..<100).map(OpaqueValue.init))
  let evens = base.lazy.filter { $0.value % 2 == 0 }
  let odds = base.lazy.filter { $0.value % 2 != 0 }

  expectEqual(base.startIndex, evens.startIndex)
  expectEqual(base.index(after: base.startIndex), odds.startIndex)

  expectEqual(
    base.index(after: base.index(after: base.startIndex)),
    evens.index(after: evens.startIndex))

  expectEqual(
    base.index(after: base.index(after: base.index(after: base.startIndex))),
    odds.index(after: odds.startIndex))
}

tests.test("LazyFilterCollection") {
  let base = MinimalCollection(elements: (0..<100).map(OpaqueValue.init))

  var calls = 0
  let filtered = base.lazy.filter {
    x in calls += 1;
    return x.value % 2 == 0
  }
  expectEqual(calls, 0, "filtering was eager!")

  ExpectType<
    LazyFilterCollection<MinimalCollection<OpaqueValue<Int>>>
  >.test(filtered)

  checkOneLevelOfForwardCollection(
    stride(from: 0, to: 100, by: 2).map(OpaqueValue.init), filtered,
    resiliencyChecks: .none
  ) {
    $0.value == $1.value
  }

  expectGE(calls, 100)
  let oldCalls = calls
  _ = filtered.first
  expectLT(oldCalls, calls)
  expectGE(oldCalls + 2, calls)

  checkFilterIteratorBase(
    base.lazy.filter { $0.value % 2 == 0 },
    base.lazy.filter { $0.value % 2 != 0 })
}

tests.test("LazyFilterSequence/AssociatedTypes") {
  typealias Base = MinimalSequence<OpaqueValue<Int>>
  typealias Subject = LazyFilterSequence<Base>
  expectSequenceAssociatedTypes(
    sequenceType: Subject.self,
    iteratorType: LazyFilterIterator<Base.Iterator>.self,
    subSequenceType: AnySequence<OpaqueValue<Int>>.self)
}

tests.test("LazyFilterCollection/AssociatedTypes") {
  typealias Base = MinimalCollection<OpaqueValue<Int>>
  typealias Subject = LazyFilterCollection<Base>
  expectCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: LazyFilterIterator<Base.Iterator>.self,
    // FIXME(ABI)#80 (Associated Types with where clauses): SubSequence should be `LazyFilterCollection<Base.Slice>`.
    subSequenceType: Slice<Subject>.self,
    indexType: LazyFilterIndex<Base>.self,
    indexDistanceType: Base.IndexDistance.self,
    indicesType: DefaultIndices<Subject>.self)
}

tests.test("LazyFilterBidirectionalCollection/AssociatedTypes") {
  typealias Base = MinimalBidirectionalCollection<OpaqueValue<Int>>
  typealias Subject = LazyFilterBidirectionalCollection<Base>
  expectBidirectionalCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: LazyFilterIterator<Base.Iterator>.self,
    // FIXME(ABI)#81 (Associated Types with where clauses): SubSequence should be `LazyFilterBidirectionalCollection<Base.Slice>`.
    subSequenceType: BidirectionalSlice<Subject>.self,
    indexType: LazyFilterIndex<Base>.self,
    indexDistanceType: Base.IndexDistance.self,
    indicesType: DefaultBidirectionalIndices<Subject>.self)
}

tests.test("lazy.filter/TypeInference") {
  let baseArray: [OpaqueValue<Int>] = (0..<10).map(OpaqueValue.init)
  do {
    var filtered = MinimalSequence(elements: baseArray)
      .lazy.filter { _ in true }
    expectType(
      LazyFilterSequence<MinimalSequence<OpaqueValue<Int>>>.self,
      &filtered)
  }
  do {
    var filtered = MinimalCollection(elements: baseArray)
      .lazy.filter { _ in true }
    expectType(
      LazyFilterCollection<MinimalCollection<OpaqueValue<Int>>>.self,
      &filtered)
  }
  do {
    var filtered = MinimalBidirectionalCollection(elements: baseArray)
      .lazy.filter { _ in true }
    expectType(
      LazyFilterBidirectionalCollection<
        MinimalBidirectionalCollection<OpaqueValue<Int>>
      >.self,
      &filtered)
  }
  do {
    var filtered = MinimalRandomAccessCollection(elements: baseArray)
      .lazy.filter { _ in true }
    expectType(
      LazyFilterBidirectionalCollection<
        MinimalRandomAccessCollection<OpaqueValue<Int>>
      >.self,
      &filtered)
  }
}

do {
  struct Sample {
    var expected: CountableRange<Int>
    var data: [CountableRange<Int>]
  }

  let flattenSamples: [Sample] = [
    Sample(
      expected: 0..<8, data: [ 1..<1, 0..<5, 7..<7, 5..<7, 7..<8 ]),
    Sample(expected: 0..<8, data: [ 0..<5, 7..<7, 5..<7, 7..<8 ]),
    Sample(
      expected: 0..<8, data: [ 1..<1, 0..<5, 7..<7, 5..<7, 7..<8, 11..<11 ]),
    Sample(
      expected: 0..<16, data: [ 0..<10, 14..<14, 10..<14, 14..<16, 22..<22 ]),
    Sample(expected: 0..<0, data: [ 11..<11 ]),
    Sample(expected: 0..<0, data: [ 3..<3, 11..<11 ]),
    Sample(expected: 0..<0, data: []),
  ]

  for sample in flattenSamples {
    let expected = sample.expected
    let data = sample.data

    tests.test("FlattenSequence/\(data)") {
      var base = MinimalSequence(
        elements: data.map { MinimalSequence(elements: $0) })
      checkSequence(expected, base.joined(), resiliencyChecks: .none)

      // Checking that flatten doesn't introduce laziness

      // checkSequence consumed base, so reassign
      base = MinimalSequence(
        elements: data.map { MinimalSequence(elements: $0) })
      let flattened = base.joined()
      var calls = 0
      _ = flattened.map { _ in calls += 1 }
      expectEqual(
        expected.count, calls,
        "unexpected laziness in \(type(of: flattened))")
    }

    tests.test("FlattenSequence/Lazy/\(data)") {
      // Checking that flatten doesn't remove laziness
      let base = MinimalSequence(
        elements: data.map { MinimalSequence(elements: $0) }
      ).lazy.map { $0 }

      let flattened = base.joined()
      var calls = 0
      _ = flattened.map { _ in calls += 1 }
      expectEqual(0, calls, "unexpected eagerness in \(type(of: flattened))")
    }

  % for Traversal in 'Forward', 'Bidirectional':
  %   TraversalCollection = collectionForTraversal(Traversal)
    tests.test("Flatten${TraversalCollection}/\(data)") {
      let base = Minimal${TraversalCollection}(
        elements: data.map { Minimal${TraversalCollection}(elements: $0) })

      let flattened = base.joined()
      check${Traversal}Collection(expected, flattened, resiliencyChecks: .none)

      // Checking that flatten doesn't introduce laziness
      var calls = 0
      _ = flattened.map { _ in calls += 1 }
      expectLE(
        expected.count, calls,
        "unexpected laziness in \(type(of: flattened))")
    }

    tests.test("Flatten${TraversalCollection}/Lazy\(data)") {
      // Checking that flatten doesn't remove laziness
      let base = Minimal${TraversalCollection}(
        elements: data.map { Minimal${TraversalCollection}(elements: $0) }
      ).lazy.map { $0 }

      let flattened = base.joined()

      var calls = 0
      _ = flattened.map { _ in calls += 1 }
      expectEqual(0, calls, "unexpected eagerness in \(type(of: flattened))")
    }
  % end
  }
}

//===--- LazyPrefixWhile --------------------------------------------------===//

let prefixDropWhileTests: [(data: [Int], value: Int, pivot: Int)] = [
  ([],                       0,     0),
  ([0],                      0,     0),
  ([0],                     99,     1),
  ([0, 10],                  0,     0),
  ([0, 10],                 10,     1),
  ([0, 10],                 99,     2),
  ([0, 10, 20, 30, 40],      0,     0),
  ([0, 10, 20, 30, 40],     10,     1),
  ([0, 10, 20, 30, 40],     20,     2),
  ([0, 10, 20, 30, 40],     30,     3),
  ([0, 10, 20, 30, 40],     40,     4),
  ([0, 10, 20, 30, 40],     99,     5) ]

% for Kind in 'Sequence', 'Forward', 'Bidirectional':
%   Self = 'Sequence' if Kind == 'Sequence' else collectionForTraversal(Kind)
%   checkKind = 'ForwardCollection' if Kind == 'Forward' else Self
tests.test("LazyPrefixWhile${Self}").forEach(in: prefixDropWhileTests) {
  (data, value, pivot) in

  let base = Minimal${Self}(elements: data)

  var calls1 = 0
  let prefixed = base.lazy.prefix(while: { calls1 += 1; return $0 != value })
  let expected = data.prefix(upTo: pivot)
  expectEqual(0, calls1)
  check${checkKind}(expected, prefixed)

  var calls2 = 0
  _ = prefixed.map { _ in calls2 += 1 }
  expectEqual(0, calls2, "unexpected eagerness in \(type(of: prefixed))")

  % if Kind == 'Bidirectional':
  check${checkKind}(expected.reversed(), prefixed.reversed())
  % end
}
% end

tests.test("LazyPrefixWhileSequence/AssociatedTypes") {
  typealias Base = MinimalSequence<OpaqueValue<Int>>
  typealias Subject = LazyPrefixWhileSequence<Base>
  expectSequenceAssociatedTypes(
    sequenceType: Subject.self,
    iteratorType: LazyPrefixWhileIterator<Base.Iterator>.self,
    subSequenceType: AnySequence<OpaqueValue<Int>>.self)
}

tests.test("LazyPrefixWhileCollection/AssociatedTypes") {
  typealias Base = MinimalCollection<OpaqueValue<Int>>
  typealias Subject = LazyPrefixWhileCollection<Base>
  expectCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: LazyPrefixWhileIterator<Base.Iterator>.self,
    subSequenceType: Slice<Subject>.self,
    indexType: LazyPrefixWhileIndex<Base>.self,
    indexDistanceType: Base.IndexDistance.self,
    indicesType: DefaultIndices<Subject>.self)
}

tests.test("LazyPrefixWhileBidirectionalCollection/AssociatedTypes") {
  typealias Base = MinimalBidirectionalCollection<OpaqueValue<Int>>
  typealias Subject = LazyPrefixWhileBidirectionalCollection<Base>
  expectBidirectionalCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: LazyPrefixWhileIterator<Base.Iterator>.self,
    // FIXME(ABI)#82 (Associated Types with where clauses): SubSequence should be `LazyFilterBidirectionalCollection<Base.Slice>`.
    subSequenceType: BidirectionalSlice<Subject>.self,
    indexType: LazyPrefixWhileIndex<Base>.self,
    indexDistanceType: Base.IndexDistance.self,
    indicesType: DefaultBidirectionalIndices<Subject>.self)
}

//===--- LazyDropWhile ----------------------------------------------------===//

% for Kind in 'Sequence', 'Forward', 'Bidirectional':
%   Self = 'Sequence' if Kind == 'Sequence' else collectionForTraversal(Kind)
%   checkKind = 'ForwardCollection' if Kind == 'Forward' else Self
tests.test("LazyDropWhile${Self}").forEach(in: prefixDropWhileTests) {
  (data, value, pivot) in

  let base = Minimal${Self}(elements: data)

  var calls1 = 0
  let dropped = base.lazy.drop(while: { calls1 += 1; return $0 != value })
  let expected = data.suffix(from: pivot)
  expectEqual(0, calls1)
  check${checkKind}(expected, dropped)

  var calls2 = 0
  _ = dropped.map { _ in calls2 += 1 }
  expectEqual(0, calls2, "unexpected eagerness in \(type(of: dropped))")

  % if Kind == 'Bidirectional':
  check${checkKind}(expected.reversed(), dropped.reversed())
  % end
}
% end

tests.test("LazyDropWhileSequence/AssociatedTypes") {
  typealias Base = MinimalSequence<OpaqueValue<Int>>
  typealias Subject = LazyDropWhileSequence<Base>
  expectSequenceAssociatedTypes(
    sequenceType: Subject.self,
    iteratorType: LazyDropWhileIterator<Base.Iterator>.self,
    subSequenceType: AnySequence<OpaqueValue<Int>>.self)
}

tests.test("LazyDropWhileCollection/AssociatedTypes") {
  typealias Base = MinimalCollection<OpaqueValue<Int>>
  typealias Subject = LazyDropWhileCollection<Base>
  expectCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: LazyDropWhileIterator<Base.Iterator>.self,
    subSequenceType: Slice<Subject>.self,
    indexType: LazyDropWhileIndex<Base>.self,
    indexDistanceType: Base.IndexDistance.self,
    indicesType: DefaultIndices<Subject>.self)
}

tests.test("LazyDropWhileBidirectionalCollection/AssociatedTypes") {
  typealias Base = MinimalBidirectionalCollection<OpaqueValue<Int>>
  typealias Subject = LazyDropWhileBidirectionalCollection<Base>
  expectBidirectionalCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: LazyDropWhileIterator<Base.Iterator>.self,
    // FIXME(ABI)#83 (Associated Types with where clauses): SubSequence should be `LazyFilterBidirectionalCollection<Base.Slice>`.
    subSequenceType: BidirectionalSlice<Subject>.self,
    indexType: LazyDropWhileIndex<Base>.self,
    indexDistanceType: Base.IndexDistance.self,
    indicesType: DefaultBidirectionalIndices<Subject>.self)
}

runAllTests()
