Last active
August 5, 2020 10:46
-
-
Save RuiAAPeres/64cb7cacab5ec33f7a69aa3bc5545937 to your computer and use it in GitHub Desktop.
Unit Testing ReactiveSwift streams with Assertions (idea by @andersio)
This file contains 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 ReactiveSwift | |
import XCTest | |
private let counterFailure: (Int, Int) -> String = { count, maxCount in | |
return "Counter is currently at \(count) which higher than the max \(maxCount)" | |
} | |
private let timeoutFailure = "Expectation timeout" | |
private let infoTemplate: (String, String, Int) -> String = { fileName, functionName, lineNumber in | |
return "➡️ filename: \(fileName)\n ➡️ functionName: \(functionName)\n ➡️ lineNumber: \(lineNumber)" | |
} | |
private let failureTemplate: (String, String) -> String = { value, info in | |
return """ | |
\n❌❌❌❌❌ | |
👉 \(value) 👈 \n \(info) | |
❌❌❌❌❌ | |
""" | |
} | |
public extension SignalProducer where Error == Never { | |
func assertValues( | |
maxCount: Int = .max, | |
timeout: TimeInterval = 3, | |
fileName: String = #file, | |
functionName: String = #function, | |
lineNumber: Int = #line, | |
action: @escaping (Value, Int) -> Void | |
) { | |
let info = infoTemplate(fileName, functionName, lineNumber) | |
let expectation = XCTestExpectation(description: info) | |
expectation.expectedFulfillmentCount = maxCount | |
var _count = 1 | |
self.startWithValues { value in | |
guard _count <= maxCount else { | |
XCTFail(failureTemplate(counterFailure(_count, maxCount), info)) | |
expectation.fulfill() | |
return | |
} | |
action(value, _count) | |
expectation.fulfill() | |
_count += 1 | |
} | |
let result = XCTWaiter.wait(for: [expectation], timeout: timeout) | |
switch result { | |
case .timedOut: | |
XCTFail(failureTemplate(timeoutFailure, info)) | |
default: | |
break | |
} | |
} | |
} | |
public extension SignalProducer { | |
func assertResult( | |
maxCount: Int = .max, | |
timeout: TimeInterval = 3, | |
fileName: String = #file, | |
functionName: String = #function, | |
lineNumber: Int = #line, | |
action: @escaping (Result<Value, Error>, Int) -> Void | |
) { | |
let info = infoTemplate(fileName, functionName, lineNumber) | |
let expectation = XCTestExpectation(description: info) | |
expectation.expectedFulfillmentCount = maxCount | |
var _count = 1 | |
self.startWithResult { result in | |
guard _count <= maxCount else { | |
XCTFail(failureTemplate(counterFailure(_count, maxCount), info)) | |
expectation.fulfill() | |
return | |
} | |
action(result, _count) | |
expectation.fulfill() | |
_count += 1 | |
} | |
let result = XCTWaiter.wait(for: [expectation], timeout: timeout) | |
switch result { | |
case .timedOut: | |
XCTFail(failureTemplate(timeoutFailure, info)) | |
default: | |
break | |
} | |
} | |
func assertCompletion( | |
timeout: TimeInterval = 3, | |
fileName: String = #file, | |
functionName: String = #function, | |
lineNumber: Int = #line, | |
action: @escaping () -> Void | |
) { | |
let info = infoTemplate(fileName, functionName, lineNumber) | |
let expectation = XCTestExpectation(description: info) | |
self.startWithCompleted { | |
action() | |
expectation.fulfill() | |
} | |
let result = XCTWaiter.wait(for: [expectation], timeout: timeout) | |
switch result { | |
case .timedOut: | |
XCTFail(failureTemplate(timeoutFailure, info)) | |
default: | |
break | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment