From 962c9b2c1b6a7a015ab50a1f37f992c9a5e20f0e Mon Sep 17 00:00:00 2001 From: Martin Kim Dung-Pham Date: Thu, 25 Jan 2024 21:45:15 +0100 Subject: [PATCH 1/2] Add async Assertion content --- Sources/Rorschach/Assertion.swift | 14 ++++++++++++-- Sources/Rorschach/Then.swift | 9 +++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Sources/Rorschach/Assertion.swift b/Sources/Rorschach/Assertion.swift index 392f78d..03b3102 100644 --- a/Sources/Rorschach/Assertion.swift +++ b/Sources/Rorschach/Assertion.swift @@ -12,14 +12,24 @@ import XCTest public struct Assertion { let title: String? - private let content: () -> Void + private var content: (() -> Void)? + private var asyncContent: (() async -> Void)? + + public init(_ title: String? = nil, content: @escaping () async -> Void) { + self.title = title + self.asyncContent = content + } public init(_ title: String? = nil, content: @escaping () -> Void) { self.title = title self.content = content } + public func assert() async { + await asyncContent?() + } + public func assert() { - content() + content?() } } diff --git a/Sources/Rorschach/Then.swift b/Sources/Rorschach/Then.swift index 4dd6ee5..8fdd3f4 100644 --- a/Sources/Rorschach/Then.swift +++ b/Sources/Rorschach/Then.swift @@ -21,6 +21,11 @@ public struct Then { } var contentOnlyTitle: String? + public init(_ title: String, content: @escaping () async -> Void) { + contentOnlyTitle = title + assertion = Assertion(content: content) + } + public init(_ title: String, content: @escaping () -> Void) { contentOnlyTitle = title assertion = Assertion(content: content) @@ -30,6 +35,10 @@ public struct Then { assertion = content() } + func assert() async { + await assertion?.assert() + } + func assert() { assertion?.assert() } From 182e1098e7624ffcccb4db7e5d2f483e02d30517 Mon Sep 17 00:00:00 2001 From: Martin Kim Dung-Pham Date: Sun, 28 Jan 2024 20:00:49 +0100 Subject: [PATCH 2/2] Async and throwing assertions --- Package.swift | 3 +- Sources/Rorschach/Assertion.swift | 10 ++--- Sources/Rorschach/Then.swift | 10 ++--- Sources/Rorschach/XCTestCase+BDDStyle.swift | 20 +++++---- Tests/RorschachTests/AssertionTests.swift | 46 +++++++++++++++++++++ 5 files changed, 68 insertions(+), 21 deletions(-) create mode 100644 Tests/RorschachTests/AssertionTests.swift diff --git a/Package.swift b/Package.swift index de8e5dc..584bc70 100644 --- a/Package.swift +++ b/Package.swift @@ -5,7 +5,8 @@ import PackageDescription let package = Package( name: "rorschach", platforms: [ - .iOS(.v13) + .iOS(.v13), + .macOS(.v10_15) ], products: [ .library( diff --git a/Sources/Rorschach/Assertion.swift b/Sources/Rorschach/Assertion.swift index 03b3102..c9dae76 100644 --- a/Sources/Rorschach/Assertion.swift +++ b/Sources/Rorschach/Assertion.swift @@ -13,11 +13,11 @@ public struct Assertion { let title: String? private var content: (() -> Void)? - private var asyncContent: (() async -> Void)? + private var asyncThrowingContent: (() async throws -> Void)? - public init(_ title: String? = nil, content: @escaping () async -> Void) { + public init(_ title: String? = nil, content: @escaping () async throws -> Void) { self.title = title - self.asyncContent = content + self.asyncThrowingContent = content } public init(_ title: String? = nil, content: @escaping () -> Void) { @@ -25,8 +25,8 @@ public struct Assertion { self.content = content } - public func assert() async { - await asyncContent?() + public func assert() async throws { + try await asyncThrowingContent?() } public func assert() { diff --git a/Sources/Rorschach/Then.swift b/Sources/Rorschach/Then.swift index 8fdd3f4..6d98ac7 100644 --- a/Sources/Rorschach/Then.swift +++ b/Sources/Rorschach/Then.swift @@ -21,7 +21,7 @@ public struct Then { } var contentOnlyTitle: String? - public init(_ title: String, content: @escaping () async -> Void) { + public init(_ title: String, content: @escaping () async throws -> Void) { contentOnlyTitle = title assertion = Assertion(content: content) } @@ -35,11 +35,7 @@ public struct Then { assertion = content() } - func assert() async { - await assertion?.assert() - } - - func assert() { - assertion?.assert() + func assert() async throws { + try await assertion?.assert() } } diff --git a/Sources/Rorschach/XCTestCase+BDDStyle.swift b/Sources/Rorschach/XCTestCase+BDDStyle.swift index 8e367b8..4ed4fd5 100644 --- a/Sources/Rorschach/XCTestCase+BDDStyle.swift +++ b/Sources/Rorschach/XCTestCase+BDDStyle.swift @@ -32,7 +32,7 @@ public protocol Expecting { /// } /// } /// ``` - func expect(@ExpectationBuilder _ content: () -> (given: Given, when: When, then: Then)) + func expect(@ExpectationBuilder _ content: @escaping () -> (given: Given, when: When, then: Then)) /// A test's expectation containing only the ``When`` and the ``Then`` sections. /// @@ -49,13 +49,13 @@ public protocol Expecting { /// } /// ``` - func expect(@ExpectationBuilder _ content: () -> (when: When, then: Then)) + func expect(@ExpectationBuilder _ content: @escaping () -> (when: When, then: Then)) } /// This extension adds support for test expectations to _XCTestCase_. extension XCTestCase: Expecting { - public func expect(@ExpectationBuilder _ content: () -> (given: Given, when: When, then: Then)) { + public func expect(@ExpectationBuilder _ content: @escaping () -> (given: Given, when: When, then: Then)) { XCTContext.runActivity(named: content().given.title ) { _ in content().given.execute() @@ -65,19 +65,23 @@ extension XCTestCase: Expecting { content().when.execute() } - XCTContext.runActivity(named: content().then.title ) { _ in - content().then.assert() + _ = XCTContext.runActivity(named: content().then.title ) { _ in + Task { + try await content().then.assert() + } } } - public func expect(@ExpectationBuilder _ content: () -> (when: When, then: Then)) { + public func expect(@ExpectationBuilder _ content: @escaping () -> (when: When, then: Then)) { XCTContext.runActivity(named: content().when.title ) { _ in content().when.execute() } - XCTContext.runActivity(named: content().then.title ) { _ in - content().then.assert() + _ = XCTContext.runActivity(named: content().then.title ) { _ in + Task { + try await content().then.assert() + } } } diff --git a/Tests/RorschachTests/AssertionTests.swift b/Tests/RorschachTests/AssertionTests.swift new file mode 100644 index 0000000..6d20e91 --- /dev/null +++ b/Tests/RorschachTests/AssertionTests.swift @@ -0,0 +1,46 @@ +// +// AssertionTests.swift +// +// +// Created by Martin Kim Dung-Pham on 25.01.24. +// + +import Foundation +import XCTest + +@testable import Rorschach + +class AssertionTests: XCTestCase { + + func testDefault() { + let expectation = expectation(description: "") + + let sut = Assertion("abc") { + _ = "" + expectation.fulfill() + } + + sut.assert() + + wait(for: [expectation], timeout: 0.1) + XCTAssertEqual(sut.title, "abc") + } + + func testThrowing() async throws { + let expectation = expectation(description: "") + + let sut = Assertion("abc") { + _ = try JSONDecoder().decode([String: String].self, from: self.json) + expectation.fulfill() + } + + try await sut.assert() + + await fulfillment(of: [expectation]) + XCTAssertEqual(sut.title, "abc") + } + + private let json = """ + {"a":"A"} + """.data(using: .utf8)! +}