mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
81 lines
2.3 KiB
Swift
81 lines
2.3 KiB
Swift
// RUN: %target-run-simple-swift
|
|
// REQUIRES: executable_test
|
|
|
|
import StdlibUnittest
|
|
import StdlibCollectionUnittest
|
|
|
|
var UnfoldTests = TestSuite("UnfoldSequence")
|
|
|
|
UnfoldTests.test("sequence(state:next:)") {
|
|
// FIXME: The full type signatures on these closures should not be
|
|
// necessary, but at the moment the compiler gives very confusing errors if
|
|
// we don't have them.
|
|
|
|
let s0 = sequence(state: 1, next: { (val: inout Int) -> Int? in
|
|
defer { val *= 2 }; return val > 16 ? nil : val
|
|
})
|
|
checkSequence([1,2,4,8,16], s0)
|
|
|
|
let s1 = sequence(state: (), next: { (_: inout ()) -> Int? in 1 })
|
|
checkSequence([1, 1, 1], s1.prefix(3))
|
|
|
|
let s2 = sequence(state: (1..<6).makeIterator(), next: {
|
|
(iter: inout CountableRange<Int>.Iterator) in
|
|
iter.next()
|
|
})
|
|
checkSequence(1..<6, s2)
|
|
|
|
// Make sure we don't evaluate any step in advance
|
|
var calls = 0
|
|
var s3 = sequence(state: 0, next: { (val: inout Int) -> Int? in
|
|
calls += 1; val += 1; return val
|
|
})
|
|
for i in 1..<6 {
|
|
expectEqual(i, s3.next())
|
|
expectEqual(i, calls)
|
|
}
|
|
|
|
// Make sure we don't invoke next() after it returns nil
|
|
calls = 0
|
|
var s4 = sequence(state: 1, next : { (val: inout Int) -> Int? in
|
|
calls += 1; defer { val *= 2 }; return val > 16 ? nil : val
|
|
})
|
|
checkSequence([1,2,4,8,16], s4)
|
|
expectEqual(6, calls)
|
|
|
|
let s5 = sequence(state: (), next: { (_: inout ()) -> Int? in nil })
|
|
checkSequence([], s5)
|
|
|
|
// This is similar to s0 except calling the `next` closure after it returns
|
|
// nil starts returning values again.
|
|
let s6 = sequence(state: 1, next: { (val: inout Int) -> Int? in
|
|
defer { val *= 2 }
|
|
return val == 32 ? nil : val
|
|
})
|
|
checkSequence([1,2,4,8,16], s6)
|
|
}
|
|
|
|
UnfoldTests.test("sequence(first:next:)") {
|
|
let s0 = sequence(first: 1, next: { $0 < 50 ? $0 * 2 : nil })
|
|
expectEqualSequence([1, 2, 4, 8, 16, 32, 64], s0)
|
|
|
|
// Make sure we don't evaluate any step in advance
|
|
var calls = 0
|
|
var s1 = sequence(first: 0, next: { calls += 1; return $0 + 1 })
|
|
for i in 0..<5 {
|
|
expectEqual(i, s1.next())
|
|
expectEqual(i, calls)
|
|
}
|
|
|
|
// Make sure we don't invoke next() after it returns nil
|
|
calls = 0
|
|
let s2 = sequence(first: 1, next: {
|
|
calls += 1
|
|
return $0 >= 16 ? nil : $0 * 2
|
|
})
|
|
checkSequence([1,2,4,8,16], s2)
|
|
expectEqual(5, calls)
|
|
}
|
|
|
|
runAllTests()
|