Skip to content

Commit

Permalink
feat: testing improvements (#38)
Browse files Browse the repository at this point in the history
* feat: testing improvements

* feat: remove swiftlint
  • Loading branch information
reddavis authored Aug 6, 2022
1 parent f7b6c72 commit 29f33b5
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 72 deletions.
20 changes: 0 additions & 20 deletions .github/workflows/swiftlint.yml

This file was deleted.

34 changes: 0 additions & 34 deletions .swiftlint.yml

This file was deleted.

4 changes: 4 additions & 0 deletions Asynchrone.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@
dependencies = (
);
name = AsynchroneTests;
packageProductDependencies = (
);
productName = AsynchroneTests;
productReference = A4C361B4276A5EF200511525 /* AsynchroneTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
Expand Down Expand Up @@ -430,6 +432,8 @@
Base,
);
mainGroup = A4C361A0276A5EF200511525;
packageReferences = (
);
productRefGroup = A4C361AB276A5EF200511525 /* Products */;
projectDirPath = "";
projectRoot = "";
Expand Down
62 changes: 52 additions & 10 deletions AsynchroneTests/Supporting Files/Assertion.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
import XCTest

/// Asserts that an async expression is not `nil`, and returns its unwrapped value.
///
/// Generates a failure when `expression == nil`.
///
/// - Parameters:
/// - expression: An expression of type `T?` to compare against `nil`.
/// Its type will determine the type of the returned value.
/// - message: An optional description of the failure.
/// - file: The file in which failure occurred. Defaults to the file name of the test case in which this function was called.
/// - line: The line number on which failure occurred. Defaults to the line number on which this function was called.
/// - Returns: A value of type `T`, the result of evaluating and unwrapping the given `expression`.
/// - Throws: An error when `expression == nil`. It will also rethrow any error thrown while evaluating the given expression.
func XCTAsyncUnwrap<T>(
_ expression: () async throws -> T?,
_ message: @autoclosure () -> String = "",
file: StaticString = #filePath,
line: UInt = #line
) async throws -> T {
let value = try await expression()
return try XCTUnwrap(value, message(), file: file, line: line)
}

/// Assert two expressions are eventually equal.
/// - Parameters:
/// - expressionA: Expression A
Expand All @@ -8,14 +30,14 @@ import XCTest
/// - file: The file where this assertion is being called. Defaults to `#filePath`.
/// - line: The line in the file where this assertion is being called. Defaults to `#line`.
func XCTAssertEventuallyEqual<T: Equatable>(
_ expressionA: @escaping @autoclosure () -> T?,
_ expressionB: @escaping @autoclosure () -> T?,
_ expressionA: @autoclosure @escaping () -> T?,
_ expressionB: @autoclosure @escaping () -> T?,
timeout: TimeInterval = 5.0,
file: StaticString = #filePath,
line: UInt = #line
) async {
let timeoutDate = Date(timeIntervalSinceNow: timeout)

while true {
let resultA = expressionA()
let resultB = expressionB()
Expand All @@ -39,7 +61,7 @@ func XCTAssertEventuallyEqual<T: Equatable>(
return
// False but still within timeout limit.
case false:
try? await Task.sleep(nanoseconds: 10000000)
try? await Task.sleep(nanoseconds: 1000000)
}
}
}
Expand All @@ -51,15 +73,15 @@ func XCTAssertEventuallyEqual<T: Equatable>(
/// - timeout: Time to wait for store state changes. Defaults to `5`
/// - file: The file where this assertion is being called. Defaults to `#filePath`.
/// - line: The line in the file where this assertion is being called. Defaults to `#line`.
func XCTAsyncAssertEventuallyEqual<T: Equatable>(
func XCTAssertEventuallyEqual<T: Equatable>(
_ expressionA: @escaping () async -> T?,
_ expressionB: @escaping () async -> T?,
timeout: TimeInterval = 5.0,
file: StaticString = #filePath,
line: UInt = #line
) async {
let timeoutDate = Date(timeIntervalSinceNow: timeout)

while true {
let resultA = await expressionA()
let resultB = await expressionB()
Expand All @@ -83,18 +105,38 @@ func XCTAsyncAssertEventuallyEqual<T: Equatable>(
return
// False but still within timeout limit.
case false:
try? await Task.sleep(nanoseconds: 10000000)
try? await Task.sleep(nanoseconds: 1000000)
}
}
}

/// Assert a value is eventually true.
/// - Parameters:
/// - expression: The value to assert eventually is true.
/// - timeout: Time to wait for store state changes. Defaults to `5`
/// - file: The file where this assertion is being called. Defaults to `#filePath`.
/// - line: The line in the file where this assertion is being called. Defaults to `#line`.
func XCTAssertEventuallyTrue(
_ expression: @escaping @autoclosure () -> Bool,
timeout: TimeInterval = 5.0,
file: StaticString = #filePath,
line: UInt = #line
) async {
await XCTAssertEventuallyEqual(
expression(),
true,
timeout: timeout,
file: file,
line: line
)
}

/// Assert an async closure thorws an error.
/// - Parameters:
/// - closure: The closure.
/// - file: The file where this assertion is being called. Defaults to `#filePath`.
/// - line: The line in the file where this assertion is being called. Defaults to `#line`.
public func XCTAsyncAssertThrow<T>(
func XCTAsyncAssertThrow<T>(
_ closure: () async throws -> T,
file: StaticString = #filePath,
line: UInt = #line
Expand All @@ -114,7 +156,7 @@ public func XCTAsyncAssertThrow<T>(
/// - closure: The closure.
/// - file: The file where this assertion is being called. Defaults to `#filePath`.
/// - line: The line in the file where this assertion is being called. Defaults to `#line`.
public func XCTAsyncAssertNoThrow<T>(
func XCTAsyncAssertNoThrow<T>(
_ closure: () async throws -> T,
file: StaticString = #filePath,
line: UInt = #line
Expand All @@ -135,7 +177,7 @@ public func XCTAsyncAssertNoThrow<T>(
/// - closure: The closure.
/// - file: The file where this assertion is being called. Defaults to `#filePath`.
/// - line: The line in the file where this assertion is being called. Defaults to `#line`.
public func XCTAsyncAssertNil<T>(
func XCTAsyncAssertNil<T>(
_ closure: () async -> T?,
file: StaticString = #filePath,
line: UInt = #line
Expand Down
11 changes: 7 additions & 4 deletions AsynchroneTests/Tests/Extensions/AsyncSequenceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,22 @@ final class AsyncSequenceTests: XCTestCase {
}

func testSinkWithFinishedCompletion() async {
let completionExpectation = self.expectation(description: "Completion called")
var values: [Int] = []
self.sequence.sink(
receiveValue: { values.append($0) },
receiveCompletion: {
switch $0 {
case .failure(let error):
XCTFail("Invalid completion case: Failure \(error)")
case .finished:()
case .finished:
completionExpectation.fulfill()
}
}
)

await XCTAssertEventuallyEqual(values, [1, 2, 3])
await self.waitForExpectations(timeout: 5.0, handler: nil)
XCTAssertEqual(values, [1, 2, 3])
}

func testSinkWithFailedCompletion() async {
Expand All @@ -99,7 +102,7 @@ final class AsyncSequenceTests: XCTestCase {
)

await self.waitForExpectations(timeout: 5.0, handler: nil)
await XCTAssertEventuallyEqual(values, [1, 2, 3])
XCTAssertEqual(values, [1, 2, 3])
}

func testSinkWithCancellation() async {
Expand All @@ -125,6 +128,6 @@ final class AsyncSequenceTests: XCTestCase {

task.cancel()
await self.waitForExpectations(timeout: 5.0, handler: nil)
await XCTAssertEventuallyEqual(values, [1])
XCTAssertEqual(values, [1])
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ final class DebounceAsyncSequenceTests: XCTestCase {
override func setUpWithError() throws {
self.stream = AsyncStream<Int> { continuation in
continuation.yield(0)
try? await Task.sleep(seconds: 0.1)
continuation.yield(1)
try? await Task.sleep(seconds: 0.1)
try? await Task.sleep(seconds: 0.2)
continuation.yield(2)
continuation.yield(3)
continuation.yield(4)
continuation.yield(5)
try? await Task.sleep(seconds: 0.1)
try? await Task.sleep(seconds: 0.2)
continuation.finish()
}
}
Expand All @@ -28,7 +27,7 @@ final class DebounceAsyncSequenceTests: XCTestCase {
.debounce(for: 0.1)
.collect()

XCTAssertEqual(values, [0, 1, 5])
XCTAssertEqual(values, [1, 5])
}

func testDebounceWithNoValues() async {
Expand Down

0 comments on commit 29f33b5

Please sign in to comment.