Created
October 11, 2018 00:27
-
-
Save aufflick/1d4b27307d3002b9897d0e5266006f46 to your computer and use it in GitHub Desktop.
XCTest Expectation bug
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import XCTest | |
import Foundation | |
class GCDTestTests: XCTestCase { | |
func testGCDDeterminism() { | |
// Just for sanity, confirming *everything* is happening on the serial main thread. | |
assert(Thread.isMainThread) | |
var seen = [Int]() | |
for _ in 0..<1_000 { | |
let expectations = (0..<100).map { self.expectation(description: "Expect \($0)") } | |
let observation = Observation { (value) in | |
seen.append(value) | |
expectations[value].fulfill() | |
} | |
let publisher = Publisher() | |
publisher.addObserver(observer: observation) | |
for i in 0..<100 { | |
publisher.publish { i } | |
} | |
wait(for: expectations, timeout: 2, enforceOrder: true) | |
} | |
var prev = -1 | |
for value in seen { | |
if value != prev + 1 { | |
print("out of order prev: \(prev) value: \(value)") | |
} | |
prev = value == 99 ? -1 : value | |
} | |
} | |
} | |
class Publisher { | |
var observers = [Observation]() | |
let queue = DispatchQueue(label: "publisher queue", target: DispatchQueue.main) | |
init() {} | |
func addObserver(observer: Observation) { | |
observers.append(observer) | |
} | |
func publish(_ work: @escaping () throws -> (Int)) { | |
self.queue.async { | |
do { | |
let value = try work() | |
for observer in self.observers { | |
observer.apply(value) | |
} | |
} catch { | |
preconditionFailure() | |
} | |
} | |
} | |
} | |
class Observation { | |
let observation: (Int) -> Void | |
let queue = DispatchQueue(label: "observation queue", target: DispatchQueue.main) | |
init(observation: @escaping (Int) -> Void) { | |
self.observation = observation | |
} | |
func apply(_ value: Int) { | |
self.queue.async { | |
self.observation(value) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Test reliably produces the output:
:0: error: -[iOSGCDDeterminismTestTests.GCDTestTests testGCDDeterminism] : Failed due to expectation fulfilled in incorrect order.
But no values are out of order.