diff --git a/.swiftformat b/.swiftformat index 4cc3482..b2c3655 100644 --- a/.swiftformat +++ b/.swiftformat @@ -11,4 +11,5 @@ # rules ---disable preferForLoop,hoistAwait +--disable preferForLoop + diff --git a/Sources/SwiftPolyglotCore/SwiftPolyglotError.swift b/Sources/SwiftPolyglotCore/SwiftPolyglotError.swift index e89f4eb..9e95462 100644 --- a/Sources/SwiftPolyglotCore/SwiftPolyglotError.swift +++ b/Sources/SwiftPolyglotCore/SwiftPolyglotError.swift @@ -5,6 +5,8 @@ enum SwiftPolyglotError: Error { case unsupportedVariation(variation: String) } +extension SwiftPolyglotError: Equatable {} + extension SwiftPolyglotError: LocalizedError { public var errorDescription: String? { switch self { diff --git a/Tests/SwiftPolyglotCoreTests/SwiftPolyglotCoreTests.swift b/Tests/SwiftPolyglotCoreTests/SwiftPolyglotCoreTests.swift index 081e88d..448ab9c 100644 --- a/Tests/SwiftPolyglotCoreTests/SwiftPolyglotCoreTests.swift +++ b/Tests/SwiftPolyglotCoreTests/SwiftPolyglotCoreTests.swift @@ -21,7 +21,7 @@ final class SwiftPolyglotCoreTests: XCTestCase { isRunningInAGitHubAction: false ) - await XCTAssertNoThrowAsync(try await swiftPolyglotCore.run()) + await XCTAssertNoThrowAsync(swiftPolyglotCore.run) } func testStringCatalogVariationsFullyTranslated() async throws { @@ -43,7 +43,7 @@ final class SwiftPolyglotCoreTests: XCTestCase { isRunningInAGitHubAction: false ) - await XCTAssertNoThrowAsync(try await swiftPolyglotCore.run()) + await XCTAssertNoThrowAsync(swiftPolyglotCore.run) } func testStringCatalogWithMissingTranslations() async throws { @@ -65,7 +65,7 @@ final class SwiftPolyglotCoreTests: XCTestCase { isRunningInAGitHubAction: false ) - await XCTAssertThrowsErrorAsync(try await swiftPolyglotCore.run()) + await XCTAssertThrowsErrorAsync(swiftPolyglotCore.run, SwiftPolyglotError.missingTranslations) } func testStringCatalogWithMissingVariations() async throws { @@ -87,6 +87,6 @@ final class SwiftPolyglotCoreTests: XCTestCase { isRunningInAGitHubAction: false ) - await XCTAssertThrowsErrorAsync(try await swiftPolyglotCore.run()) + await XCTAssertThrowsErrorAsync(swiftPolyglotCore.run, SwiftPolyglotError.missingTranslations) } } diff --git a/Tests/SwiftPolyglotCoreTests/XCTest+AsyncThrowingExpression.swift b/Tests/SwiftPolyglotCoreTests/XCTest+AsyncThrowingExpression.swift index 90fec5f..24b0e15 100644 --- a/Tests/SwiftPolyglotCoreTests/XCTest+AsyncThrowingExpression.swift +++ b/Tests/SwiftPolyglotCoreTests/XCTest+AsyncThrowingExpression.swift @@ -5,33 +5,23 @@ import XCTest /// /// Example usage: /// -/// await assertNoThrowAsync( -/// try await sut.function() -/// ) { error in -/// XCTAssertEqual(error as? MyError, MyError.specificError) -/// } +/// await assertNoThrowAsync(sut.function) /// /// - Parameters: /// - expression: An asynchronous expression that can throw an error. -/// - message: An optional description of a failure. +/// - failureMessage: An optional description of a failure. /// - file: The file where the failure occurs. The default is the file path of the test case where this function is being called. /// - line: The line number where the failure occurs. The default is the line number where this function is being called. public func XCTAssertNoThrowAsync( - _ expression: @autoclosure () async throws -> some Any, - _ message: @autoclosure () -> String = "", + _ expression: () async throws -> some Any, + failureMessage: String = "Asynchronous call did throw an error.", file: StaticString = #filePath, line: UInt = #line ) async { do { _ = try await expression() } catch { - // expected no error to be thrown, but it was - let customMessage = message() - if customMessage.isEmpty { - XCTFail("Asynchronous call did throw an error.", file: file, line: line) - } else { - XCTFail(customMessage, file: file, line: line) - } + XCTFail(failureMessage, file: file, line: line) } } @@ -40,37 +30,33 @@ public func XCTAssertNoThrowAsync( /// /// Example usage: /// -/// await assertThrowsAsyncError( -/// try await sut.function() -/// ) { error in -/// XCTAssertEqual(error as? MyError, MyError.specificError) -/// } +/// await assertThrowsAsyncError(sut.function, MyError.specificError) /// /// - Parameters: /// - expression: An asynchronous expression that can throw an error. -/// - message: An optional description of a failure. +/// - errorThrown: The error type that should be thrown. +/// - failureMessage: An optional description of a failure. /// - file: The file where the failure occurs. The default is the file path of the test case where this function is being called. /// - line: The line number where the failure occurs. The default is the line number where this function is being called. -/// - errorHandler: An optional handler for errors that `expression` throws. /// -/// from: https://gitlab.com/-/snippets/2567566 -public func XCTAssertThrowsErrorAsync( - _ expression: @autoclosure () async throws -> some Any, - _ message: @autoclosure () -> String = "", +/// from: https://arturgruchala.com/testing-async-await-exceptions/ +func XCTAssertThrowsErrorAsync( + _ expression: () async throws -> some Any, + _ errorThrown: E, + failureMessage: String = "Asynchronous call did not throw an error.", file: StaticString = #filePath, - line: UInt = #line, - _ errorHandler: (_ error: any Error) -> Void = { _ in } -) async { + line: UInt = #line +) async where E: Equatable, E: Error { do { _ = try await expression() - // expected error to be thrown, but it was not - let customMessage = message() - if customMessage.isEmpty { - XCTFail("Asynchronous call did not throw an error.", file: file, line: line) - } else { - XCTFail(customMessage, file: file, line: line) - } + XCTFail(failureMessage, file: file, line: line) } catch { - errorHandler(error) + XCTAssertEqual( + error as? E, + errorThrown, + "Asynchronous call did not throw the given error \"\(errorThrown)\".", + file: file, + line: line + ) } }