Skip to content

Instantly share code, notes, and snippets.

@aufflick
Created October 11, 2018 00:27
Show Gist options
  • Save aufflick/1d4b27307d3002b9897d0e5266006f46 to your computer and use it in GitHub Desktop.
Save aufflick/1d4b27307d3002b9897d0e5266006f46 to your computer and use it in GitHub Desktop.
XCTest Expectation bug
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)
}
}
}
@aufflick
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment