//===--- 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: Slice<Subject>.self,
    indexType: 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: Slice<Subject>.self,
    indexType: 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,
    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(
    LazyMapCollection<
      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', 'ReversedCollection')
%]:
%  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 ReversedCollection
    where Base : TestProtocol1, Base : RandomAccessCollection {
  var _baseIsTestProtocol1: Bool {
    fatalError("not implemented")
  }
}

//===----------------------------------------------------------------------===//
// ReversedIndex for RandomAccessCollections
//===----------------------------------------------------------------------===//

// Check that the generic parameter is called 'Base'.
extension ReversedIndex
    where Base : TestProtocol1, Base : RandomAccessCollection {
  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()
  }
}

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(
    LazyMapCollection<
      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,
    subSequenceType: LazyMapCollection<Base.SubSequence, OpaqueValue<Int32>>.self,
    indexType: Base.Index.self,
    indicesType: Base.Indices.self)
}

tests.test("LazyMapBidirectionalCollection/AssociatedTypes") {
  typealias Base = MinimalBidirectionalCollection<OpaqueValue<Int>>
  typealias Subject = LazyMapCollection<Base, OpaqueValue<Int32>>
  expectBidirectionalCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: LazyMapIterator<Base.Iterator, OpaqueValue<Int32>>.self,
    subSequenceType: LazyMapCollection<Base.SubSequence, OpaqueValue<Int32>>.self,
    indexType: Base.Index.self,
    indicesType: Base.Indices.self)
}

tests.test("LazyMapRandomAccessCollection/AssociatedTypes") {
  typealias Base = MinimalRandomAccessCollection<OpaqueValue<Int>>
  typealias Subject = LazyMapCollection<Base, OpaqueValue<Int32>>
  expectRandomAccessCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: LazyMapIterator<Base.Iterator, OpaqueValue<Int32>>.self,
    subSequenceType: LazyMapCollection<Base.SubSequence, OpaqueValue<Int32>>.self,
    indexType: Base.Index.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(
      LazyMapCollection<
        MinimalBidirectionalCollection<OpaqueValue<Int>>,
        OpaqueValue<Int8>
      >.self,
      &mapped)
  }
  do {
    var mapped = MinimalRandomAccessCollection(elements: baseArray)
      .lazy.map { _ in OpaqueValue<Int8>(0) }
    expectType(
      LazyMapCollection<
        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",
    "foobar".reversed())

  // Check that the reverse collection is still eager
  do {
    var calls = 0
    _ = "foobar".reversed().map { _ in calls += 1 }
    expectEqual("foobar".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 = LazyMapCollection<[Int], Int>
    ExpectType<Base>.test(base)

    typealias LazyReversedBase = LazyCollection<ReversedCollection<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 {
    let base = "foobar".lazy.map { $0 }
    typealias Base = LazyMapCollection<String, Character>
    ExpectType<Base>.test(base)

    typealias LazyReversedBase = LazyCollection<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", 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,
    subSequenceType: LazyFilterCollection<Base.SubSequence>.self,
    indexType: Base.Index.self,
    indicesType: DefaultIndices<Subject>.self)
}

tests.test("LazyFilterBidirectionalCollection/AssociatedTypes") {
  typealias Base = MinimalBidirectionalCollection<OpaqueValue<Int>>
  typealias Subject = LazyFilterCollection<Base>
  expectBidirectionalCollectionAssociatedTypes(
    collectionType: Subject.self,
    iteratorType: LazyFilterIterator<Base.Iterator>.self,
    subSequenceType: LazyFilterCollection<Base.SubSequence>.self,
    indexType: Base.Index.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(
      LazyFilterCollection<
        MinimalBidirectionalCollection<OpaqueValue<Int>>
      >.self,
      &filtered)
  }
  do {
    var filtered = MinimalRandomAccessCollection(elements: baseArray)
      .lazy.filter { _ in true }
    expectType(
      LazyFilterCollection<
        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,
    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: Slice<Subject>.self,
    indexType: LazyPrefixWhileIndex<Base>.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,
    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: Slice<Subject>.self,
    indexType: LazyDropWhileIndex<Base>.self,
    indicesType: DefaultBidirectionalIndices<Subject>.self)
}

runAllTests()
