%import inspect %import os.path %import sys %sys.path = [os.path.split(inspect.getframeinfo(inspect.currentframe()).filename)[0] or '.'] + sys.path % for Kind in Kinds: %Minimal = 'Minimal' + Kind ${Test}.test("flatMap/${Kind}/Lazy") { for test in flatMapTests { let s = ${Minimal}>( elements: test.sequence.map(OpaqueValue.init)) let closureLifetimeTracker = LifetimeTracked(0) var timesClosureWasCalled = 0 var result = s.lazy.flatMap { (element: OpaqueValue) -> ${Minimal}> in _blackHole(closureLifetimeTracker) timesClosureWasCalled += 1 return ${Minimal}>( elements: test.transform(element.value).map { OpaqueValue(Int32($0)) }) } expectEqual(0, timesClosureWasCalled, "Unexpected eagerness") % if Kind == 'Sequence': check${Kind}( test.expected.map(OpaqueValue.init), result, stackTrace: SourceLocStack().with(test.loc), resiliencyChecks: .none ) { $0.value == $1.value } expectEqual( test.sequence.count, timesClosureWasCalled, "iterating forward the result of the lazy flatMap() should call " + "the closure only once for element") % else: _ = Array(result) /* FIXME: this check is failing. This is a fundamental problem with lazy flatMap(). Investigate other Collection schemes: indices are compositions of offsets expectEqual( test.sequence.count, timesClosureWasCalled, "iterating forward the result of the lazy flatMap() should call " + "the closure only once for element") */ // FIXME: we are not calling check${Kind} because of the same issue again. // expectEqualSequence( test.expected.map(OpaqueValue.init), result, stackTrace: SourceLocStack().with(test.loc) ) { $0.value == $1.value } % end % if Kind == 'Sequence': expectTrue(Array(s).isEmpty, "sequence should be consumed") expectEqual( test.sequence.count, timesClosureWasCalled, "iterating a lazy flatMap() should call the predicate" + "once per element") % end } } % end