diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 82f2c7d..dcb9db0 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -23,7 +23,7 @@ jobs: with: linux_5_9_enabled: false linux_5_10_enabled: false - linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error" + linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error" linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" swift-6-language-mode: diff --git a/.gitignore b/.gitignore index 006de4a..a9d78eb 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ xcuserdata Package.resolved .serverless .devcontainer +.amazonq \ No newline at end of file diff --git a/Package.swift b/Package.swift index 36b37d0..d812a95 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.8 +// swift-tools-version:6.0 import PackageDescription diff --git a/Package@swift-5.10.swift b/Package@swift-5.10.swift new file mode 100644 index 0000000..42170c0 --- /dev/null +++ b/Package@swift-5.10.swift @@ -0,0 +1,26 @@ +// swift-tools-version:5.10 + +import PackageDescription + +let swiftSettings: [SwiftSetting] = [.enableExperimentalFeature("StrictConcurrency=complete")] + +let package = Package( + name: "swift-aws-lambda-events", + platforms: [.macOS(.v14)], + products: [ + .library(name: "AWSLambdaEvents", targets: ["AWSLambdaEvents"]) + ], + dependencies: [ + .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"), + .package(url: "https://github.com/apple/swift-http-types.git", from: "1.0.0"), + ], + targets: [ + .target( + name: "AWSLambdaEvents", + dependencies: [ + .product(name: "HTTPTypes", package: "swift-http-types") + ], + swiftSettings: swiftSettings + ) + ] +) diff --git a/Package@swift-5.swift b/Package@swift-5.swift new file mode 100644 index 0000000..8a589d2 --- /dev/null +++ b/Package@swift-5.swift @@ -0,0 +1,26 @@ +// swift-tools-version:5.8 + +import PackageDescription + +let swiftSettings: [SwiftSetting] = [.enableExperimentalFeature("StrictConcurrency=complete")] + +let package = Package( + name: "swift-aws-lambda-events", + platforms: [.macOS(.v14)], + products: [ + .library(name: "AWSLambdaEvents", targets: ["AWSLambdaEvents"]) + ], + dependencies: [ + .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"), + .package(url: "https://github.com/apple/swift-http-types.git", from: "1.0.0"), + ], + targets: [ + .target( + name: "AWSLambdaEvents", + dependencies: [ + .product(name: "HTTPTypes", package: "swift-http-types") + ], + swiftSettings: swiftSettings + ) + ] +) diff --git a/Tests/AWSLambdaEventsTests/ALBTests.swift b/Tests/AWSLambdaEventsTests/ALBTests.swift index 66ff5c1..fa148cf 100644 --- a/Tests/AWSLambdaEventsTests/ALBTests.swift +++ b/Tests/AWSLambdaEventsTests/ALBTests.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class ALBTests: XCTestCase { +@Suite +struct ALBTests { static let exampleSingleValueHeadersEventBody = """ { "requestContext":{ @@ -45,21 +47,21 @@ class ALBTests: XCTestCase { } """ - func testRequestWithSingleValueHeadersEvent() { + @Test func requestWithSingleValueHeadersEvent() { let data = ALBTests.exampleSingleValueHeadersEventBody.data(using: .utf8)! do { let decoder = JSONDecoder() let event = try decoder.decode(ALBTargetGroupRequest.self, from: data) - XCTAssertEqual(event.httpMethod, .get) - XCTAssertEqual(event.body, "") - XCTAssertEqual(event.isBase64Encoded, false) - XCTAssertEqual(event.headers?.count, 11) - XCTAssertEqual(event.path, "/") - XCTAssertEqual(event.queryStringParameters, [:]) + #expect(event.httpMethod == .get) + #expect(event.body == "") + #expect(event.isBase64Encoded == false) + #expect(event.headers?.count == 11) + #expect(event.path == "/") + #expect(event.queryStringParameters == [:]) } catch { - XCTFail("Unexpected error: \(error)") + Issue.record("Unexpected error: \(error)") } } } diff --git a/Tests/AWSLambdaEventsTests/APIGateway+EncodableTests.swift b/Tests/AWSLambdaEventsTests/APIGateway+EncodableTests.swift index 02025b4..0f014e5 100644 --- a/Tests/AWSLambdaEventsTests/APIGateway+EncodableTests.swift +++ b/Tests/AWSLambdaEventsTests/APIGateway+EncodableTests.swift @@ -35,14 +35,12 @@ struct APIGatewayEncodableResponseTests { #expect(throws: Never.self) { try response = APIGatewayV2Response(statusCode: .ok, encodableBody: businessResponse) } - try #require(response?.body != nil) // when - let body = response?.body?.data(using: .utf8) - try #require(body != nil) + let body = try #require(response?.body?.data(using: .utf8)) #expect(throws: Never.self) { - let encodedBody = try JSONDecoder().decode(BusinessResponse.self, from: body!) + let encodedBody = try JSONDecoder().decode(BusinessResponse.self, from: body) // then #expect(encodedBody == businessResponse) @@ -63,7 +61,6 @@ struct APIGatewayEncodableResponseTests { // when let body = response?.body?.data(using: .utf8) - try #require(body != nil) #expect(throws: Never.self) { let encodedBody = try JSONDecoder().decode(BusinessResponse.self, from: body!) diff --git a/Tests/AWSLambdaEventsTests/APIGateway+V2IAMTests.swift b/Tests/AWSLambdaEventsTests/APIGateway+V2IAMTests.swift index 7cb7809..232cf1f 100644 --- a/Tests/AWSLambdaEventsTests/APIGateway+V2IAMTests.swift +++ b/Tests/AWSLambdaEventsTests/APIGateway+V2IAMTests.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class APIGatewayV2IAMTests: XCTestCase { +@Suite +struct APIGatewayV2IAMTests { static let getEventWithIAM = """ { "version": "2.0", @@ -133,30 +135,28 @@ class APIGatewayV2IAMTests: XCTestCase { // MARK: Decoding - func testRequestDecodingGetRequestWithIAM() { + @Test func requestDecodingGetRequestWithIAM() throws { let data = APIGatewayV2IAMTests.getEventWithIAM.data(using: .utf8)! - var req: APIGatewayV2Request? - XCTAssertNoThrow(req = try JSONDecoder().decode(APIGatewayV2Request.self, from: data)) + let req = try JSONDecoder().decode(APIGatewayV2Request.self, from: data) - XCTAssertEqual(req?.rawPath, "/hello") - XCTAssertEqual(req?.context.authorizer?.iam?.accessKey, "ASIA-redacted") - XCTAssertEqual(req?.context.authorizer?.iam?.accountId, "012345678912") - XCTAssertNil(req?.body) + #expect(req.rawPath == "/hello") + #expect(req.context.authorizer?.iam?.accessKey == "ASIA-redacted") + #expect(req.context.authorizer?.iam?.accountId == "012345678912") + #expect(req.body == nil) } - func testRequestDecodingGetRequestWithIAMWithCognito() { + @Test func requestDecodingGetRequestWithIAMWithCognito() throws { let data = APIGatewayV2IAMTests.getEventWithIAMAndCognito.data(using: .utf8)! - var req: APIGatewayV2Request? - XCTAssertNoThrow(req = try JSONDecoder().decode(APIGatewayV2Request.self, from: data)) + let req = try JSONDecoder().decode(APIGatewayV2Request.self, from: data) - XCTAssertEqual(req?.rawPath, "/hello") - XCTAssertEqual(req?.context.authorizer?.iam?.accessKey, "ASIA-redacted") - XCTAssertEqual(req?.context.authorizer?.iam?.accountId, "012345678912") + #expect(req.rawPath == "/hello") + #expect(req.context.authorizer?.iam?.accessKey == "ASIA-redacted") + #expect(req.context.authorizer?.iam?.accountId == "012345678912") // test the cognito identity part - XCTAssertEqual(req?.context.authorizer?.iam?.cognitoIdentity?.identityId, "us-east-1:68bc0ecd-9d5e--redacted") - XCTAssertEqual(req?.context.authorizer?.iam?.cognitoIdentity?.amr?.count, 3) + #expect(req.context.authorizer?.iam?.cognitoIdentity?.identityId == "us-east-1:68bc0ecd-9d5e--redacted") + #expect(req.context.authorizer?.iam?.cognitoIdentity?.amr?.count == 3) - XCTAssertNil(req?.body) + #expect(req.body == nil) } } diff --git a/Tests/AWSLambdaEventsTests/APIGateway+V2Tests.swift b/Tests/AWSLambdaEventsTests/APIGateway+V2Tests.swift index f3af5ab..9d0a56a 100644 --- a/Tests/AWSLambdaEventsTests/APIGateway+V2Tests.swift +++ b/Tests/AWSLambdaEventsTests/APIGateway+V2Tests.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class APIGatewayV2Tests: XCTestCase { +@Suite +struct APIGatewayV2Tests { static let exampleGetEventBody = """ { "routeKey":"GET /hello", @@ -189,36 +191,37 @@ class APIGatewayV2Tests: XCTestCase { // MARK: Decoding - func testRequestDecodingExampleGetRequest() { + @Test func requestDecodingExampleGetRequest() throws { let data = APIGatewayV2Tests.exampleGetEventBody.data(using: .utf8)! - var req: APIGatewayV2Request? - XCTAssertNoThrow(req = try JSONDecoder().decode(APIGatewayV2Request.self, from: data)) + let req = try JSONDecoder().decode(APIGatewayV2Request.self, from: data) - XCTAssertEqual(req?.rawPath, "/hello") - XCTAssertEqual(req?.context.http.method, .get) - XCTAssertEqual(req?.queryStringParameters.count, 1) - XCTAssertEqual(req?.rawQueryString, "foo=bar") - XCTAssertEqual(req?.headers.count, 8) - XCTAssertEqual(req?.context.authorizer?.jwt?.claims?["aud"], "customers") + #expect(req.rawPath == "/hello") + #expect(req.context.http.method == .get) + #expect(req.queryStringParameters.count == 1) + #expect(req.rawQueryString == "foo=bar") + #expect(req.headers.count == 8) + #expect(req.context.authorizer?.jwt?.claims?["aud"] == "customers") - XCTAssertNil(req?.body) + #expect(req.body == nil) } - func testDecodingRequestClientCert() throws { + @Test func decodingRequestClientCert() throws { let data = APIGatewayV2Tests.fullExamplePayload.data(using: .utf8)! let request = try JSONDecoder().decode(APIGatewayV2Request.self, from: data) let clientCert = request.context.authentication?.clientCert - XCTAssertEqual(clientCert?.clientCertPem, "CERT_CONTENT") - XCTAssertEqual(clientCert?.subjectDN, "www.example.com") - XCTAssertEqual(clientCert?.issuerDN, "Example issuer") - XCTAssertEqual(clientCert?.serialNumber, "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1") - XCTAssertEqual(clientCert?.validity.notBefore, "May 28 12:30:02 2019 GMT") - XCTAssertEqual(clientCert?.validity.notAfter, "Aug 5 09:36:04 2021 GMT") + #expect(clientCert?.clientCertPem == "CERT_CONTENT") + #expect(clientCert?.subjectDN == "www.example.com") + #expect(clientCert?.issuerDN == "Example issuer") + #expect(clientCert?.serialNumber == "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1") + #expect(clientCert?.validity.notBefore == "May 28 12:30:02 2019 GMT") + #expect(clientCert?.validity.notAfter == "Aug 5 09:36:04 2021 GMT") } - func testDecodingNilCollections() { + @Test func decodingNilCollections() throws { let data = APIGatewayV2Tests.exampleGetEventBodyNilHeaders.data(using: .utf8)! - XCTAssertNoThrow(_ = try JSONDecoder().decode(APIGatewayV2Request.self, from: data)) + #expect(throws: Never.self) { + _ = try JSONDecoder().decode(APIGatewayV2Request.self, from: data) + } } } diff --git a/Tests/AWSLambdaEventsTests/APIGatewayLambdaAuthorizerTest.swift b/Tests/AWSLambdaEventsTests/APIGatewayLambdaAuthorizerTest.swift index 923d10d..e6884a9 100644 --- a/Tests/AWSLambdaEventsTests/APIGatewayLambdaAuthorizerTest.swift +++ b/Tests/AWSLambdaEventsTests/APIGatewayLambdaAuthorizerTest.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class APIGatewayLambdaAuthorizerTests: XCTestCase { +@Suite +struct APIGatewayLambdaAuthorizerTests { static let getEventWithLambdaAuthorizer = """ { "version": "2.0", @@ -139,52 +141,45 @@ class APIGatewayLambdaAuthorizerTests: XCTestCase { // MARK: Decoding - func testRequestDecodingGetRequestWithLambdaAuthorizer() { + @Test func requestDecodingGetRequestWithLambdaAuthorizer() throws { let data = APIGatewayLambdaAuthorizerTests.getEventWithLambdaAuthorizer.data(using: .utf8)! - var req: APIGatewayV2Request? - XCTAssertNoThrow(req = try JSONDecoder().decode(APIGatewayV2Request.self, from: data)) + let req = try JSONDecoder().decode(APIGatewayV2Request.self, from: data) - XCTAssertEqual(req?.rawPath, "/hello") - XCTAssertEqual(req?.context.authorizer?.lambda?.count, 2) - XCTAssertEqual(req?.context.authorizer?.lambda?["abc1"], "xyz1") - XCTAssertEqual(req?.context.authorizer?.lambda?["abc2"], "xyz2") - XCTAssertNil(req?.body) + #expect(req.rawPath == "/hello") + #expect(req.context.authorizer?.lambda?.count == 2) + #expect(req.context.authorizer?.lambda?["abc1"] == "xyz1") + #expect(req.context.authorizer?.lambda?["abc2"] == "xyz2") + #expect(req.body == nil) } - func testLambdaAuthorizerRequestRequestDecoding() { + @Test func lambdaAuthorizerRequestRequestDecoding() throws { let data = APIGatewayLambdaAuthorizerTests.lambdaAuthorizerRequest.data(using: .utf8)! - var req: APIGatewayLambdaAuthorizerRequest? - XCTAssertNoThrow(req = try JSONDecoder().decode(APIGatewayLambdaAuthorizerRequest.self, from: data)) + let req = try JSONDecoder().decode(APIGatewayLambdaAuthorizerRequest.self, from: data) - XCTAssertEqual(req?.rawPath, "/dev/applications") - XCTAssertEqual(req?.version, "2.0") + #expect(req.rawPath == "/dev/applications") + #expect(req.version == "2.0") } // MARK: Encoding - func testDecodingLambdaAuthorizerSimpleResponse() { + @Test func decodingLambdaAuthorizerSimpleResponse() throws { var resp = APIGatewayLambdaAuthorizerSimpleResponse( isAuthorized: true, context: ["abc1": "xyz1", "abc2": "xyz2"] ) - var data: Data? - XCTAssertNoThrow(data = try JSONEncoder().encode(resp)) + let data = try #require(try? JSONEncoder().encode(resp)) + let stringData = try #require(String(data: data, encoding: .utf8)) + let newData = try #require(stringData.data(using: .utf8)) - var stringData: String? - XCTAssertNoThrow(stringData = try String(data: XCTUnwrap(data), encoding: .utf8)) + resp = try JSONDecoder().decode(APIGatewayLambdaAuthorizerSimpleResponse.self, from: newData) - data = stringData?.data(using: .utf8) - XCTAssertNoThrow( - resp = try JSONDecoder().decode(APIGatewayLambdaAuthorizerSimpleResponse.self, from: XCTUnwrap(data)) - ) - - XCTAssertEqual(resp.isAuthorized, true) - XCTAssertEqual(resp.context?.count, 2) - XCTAssertEqual(resp.context?["abc1"], "xyz1") + #expect(resp.isAuthorized == true) + #expect(resp.context?.count == 2) + #expect(resp.context?["abc1"] == "xyz1") } - func testDecodingLambdaAuthorizerPolicyResponse() { + @Test func decodingLambdaAuthorizerPolicyResponse() throws { let statement = APIGatewayLambdaAuthorizerPolicyResponse.PolicyDocument.Statement( action: "s3:getObject", effect: .allow, @@ -197,25 +192,20 @@ class APIGatewayLambdaAuthorizerTests: XCTestCase { context: ["abc1": "xyz1", "abc2": "xyz2"] ) - var data: Data? - XCTAssertNoThrow(data = try JSONEncoder().encode(resp)) - - var stringData: String? - XCTAssertNoThrow(stringData = try String(data: XCTUnwrap(data), encoding: .utf8)) + let data = try #require(try? JSONEncoder().encode(resp)) + let stringData = try #require(String(data: data, encoding: .utf8)) + let newData = try #require(stringData.data(using: .utf8)) - data = stringData?.data(using: .utf8) - XCTAssertNoThrow( - resp = try JSONDecoder().decode(APIGatewayLambdaAuthorizerPolicyResponse.self, from: XCTUnwrap(data)) - ) + resp = try JSONDecoder().decode(APIGatewayLambdaAuthorizerPolicyResponse.self, from: newData) - XCTAssertEqual(resp.principalId, "John Appleseed") - XCTAssertEqual(resp.policyDocument.statement.count, 1) - XCTAssertEqual(resp.policyDocument.statement[0].action, ["s3:getObject"]) - XCTAssertEqual(resp.context?.count, 2) - XCTAssertEqual(resp.context?["abc1"], "xyz1") + #expect(resp.principalId == "John Appleseed") + #expect(resp.policyDocument.statement.count == 1) + #expect(resp.policyDocument.statement[0].action == ["s3:getObject"]) + #expect(resp.context?.count == 2) + #expect(resp.context?["abc1"] == "xyz1") } - func testDecodingLambdaAuthorizerPolicyResponseWithMultipleResources() { + @Test func decodingLambdaAuthorizerPolicyResponseWithMultipleResources() throws { let statement = APIGatewayLambdaAuthorizerPolicyResponse.PolicyDocument.Statement( action: ["execute-api:Invoke"], effect: .allow, @@ -231,28 +221,22 @@ class APIGatewayLambdaAuthorizerTests: XCTestCase { context: ["abc1": "xyz1", "abc2": "xyz2"] ) - var data: Data? - XCTAssertNoThrow(data = try JSONEncoder().encode(resp)) - - var stringData: String? - XCTAssertNoThrow(stringData = try String(data: XCTUnwrap(data), encoding: .utf8)) + let data = try #require(try? JSONEncoder().encode(resp)) + let stringData = try #require(String(data: data, encoding: .utf8)) + let newData = try #require(stringData.data(using: .utf8)) - data = stringData?.data(using: .utf8) - XCTAssertNoThrow( - resp = try JSONDecoder().decode(APIGatewayLambdaAuthorizerPolicyResponse.self, from: XCTUnwrap(data)) - ) + resp = try JSONDecoder().decode(APIGatewayLambdaAuthorizerPolicyResponse.self, from: newData) - XCTAssertEqual(resp.principalId, "John Appleseed") - XCTAssertEqual(resp.policyDocument.statement.count, 1) - XCTAssertEqual(resp.policyDocument.statement[0].action, ["execute-api:Invoke"]) - XCTAssertEqual( - resp.policyDocument.statement[0].resource, - [ + #expect(resp.principalId == "John Appleseed") + #expect(resp.policyDocument.statement.count == 1) + #expect(resp.policyDocument.statement[0].action == ["execute-api:Invoke"]) + #expect( + resp.policyDocument.statement[0].resource == [ "arn:aws:execute-api:*:*:*/*/GET/v1/user/0123", "arn:aws:execute-api:*:*:*/*/POST/v1/user", ] ) - XCTAssertEqual(resp.context?.count, 2) - XCTAssertEqual(resp.context?["abc1"], "xyz1") + #expect(resp.context?.count == 2) + #expect(resp.context?["abc1"] == "xyz1") } } diff --git a/Tests/AWSLambdaEventsTests/APIGatewayTests.swift b/Tests/AWSLambdaEventsTests/APIGatewayTests.swift index 2f55dfe..54db3d2 100644 --- a/Tests/AWSLambdaEventsTests/APIGatewayTests.swift +++ b/Tests/AWSLambdaEventsTests/APIGatewayTests.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class APIGatewayTests: XCTestCase { +@Suite +struct APIGatewayTests { static let exampleGetEventBody = """ {"httpMethod": "GET", "body": null, "resource": "/test", "requestContext": {"resourceId": "123456", "apiId": "1234567890", "domainName": "1234567890.execute-api.us-east-1.amazonaws.com", "resourcePath": "/test", "httpMethod": "GET", "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", "accountId": "123456789012", "stage": "Prod", "identity": {"apiKey": null, "userArn": null, "cognitoAuthenticationType": null, "caller": null, "userAgent": "Custom User Agent String", "user": null, "cognitoIdentityPoolId": null, "cognitoAuthenticationProvider": null, "sourceIp": "127.0.0.1", "accountId": null}, "extendedRequestId": null, "path": "/test"}, "queryStringParameters": null, "multiValueQueryStringParameters": null, "headers": {"Host": "127.0.0.1:3000", "Connection": "keep-alive", "Cache-Control": "max-age=0", "Dnt": "1", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36 Edg/78.0.276.24", "Sec-Fetch-User": "?1", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", "Sec-Fetch-Site": "none", "Sec-Fetch-Mode": "navigate", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-US,en;q=0.9", "X-Forwarded-Proto": "http", "X-Forwarded-Port": "3000"}, "multiValueHeaders": {"Host": ["127.0.0.1:3000"], "Connection": ["keep-alive"], "Cache-Control": ["max-age=0"], "Dnt": ["1"], "Upgrade-Insecure-Requests": ["1"], "User-Agent": ["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36 Edg/78.0.276.24"], "Sec-Fetch-User": ["?1"], "Accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3"], "Sec-Fetch-Site": ["none"], "Sec-Fetch-Mode": ["navigate"], "Accept-Encoding": ["gzip, deflate, br"], "Accept-Language": ["en-US,en;q=0.9"], "X-Forwarded-Proto": ["http"], "X-Forwarded-Port": ["3000"]}, "pathParameters": null, "stageVariables": null, "path": "/test", "isBase64Encoded": false} """ @@ -42,46 +44,42 @@ class APIGatewayTests: XCTestCase { // MARK: Decoding - func testRequestDecodingExampleGetRequest() { + @Test func requestDecodingExampleGetRequest() throws { let data = APIGatewayTests.exampleGetEventBody.data(using: .utf8)! - var req: APIGatewayRequest? - XCTAssertNoThrow(req = try JSONDecoder().decode(APIGatewayRequest.self, from: data)) + let req = try JSONDecoder().decode(APIGatewayRequest.self, from: data) - XCTAssertEqual(req?.path, "/test") - XCTAssertEqual(req?.httpMethod, .get) + #expect(req.path == "/test") + #expect(req.httpMethod == .get) } - func testRequestDecodingExampleGetRequestWithoutDomainName() { + @Test func requestDecodingExampleGetRequestWithoutDomainName() throws { let data = APIGatewayTests.exampleGetEventBodyWithoutDomainName.data(using: .utf8)! - var req: APIGatewayRequest? - XCTAssertNoThrow(req = try JSONDecoder().decode(APIGatewayRequest.self, from: data)) + let req = try JSONDecoder().decode(APIGatewayRequest.self, from: data) - XCTAssertEqual(req?.path, "/test") - XCTAssertEqual(req?.httpMethod, .get) - XCTAssertNil(req?.requestContext.domainName) + #expect(req.path == "/test") + #expect(req.httpMethod == .get) + #expect(req.requestContext.domainName == nil) } - func testRequestDecodingExampleGetRequestWithAuthorizer() { + @Test func requestDecodingExampleGetRequestWithAuthorizer() throws { let data = APIGatewayTests.exampleGetEventBodyWithAuthorizer.data(using: .utf8)! - var req: APIGatewayRequest? - XCTAssertNoThrow(req = try JSONDecoder().decode(APIGatewayRequest.self, from: data)) - - XCTAssertEqual(req?.path, "/test") - XCTAssertEqual(req?.httpMethod, .get) - XCTAssertEqual( - req?.requestContext.authorizer?.claims?["scope"], - "aws.cognito.signin.user.admin phone openid profile email" + let req = try JSONDecoder().decode(APIGatewayRequest.self, from: data) + + #expect(req.path == "/test") + #expect(req.httpMethod == .get) + #expect( + req.requestContext.authorizer?.claims?["scope"] + == "aws.cognito.signin.user.admin phone openid profile email" ) - XCTAssertEqual(req?.requestContext.authorizer?.claims?["username"], "richwolf") + #expect(req.requestContext.authorizer?.claims?["username"] == "richwolf") } - func testRequestDecodingTodoPostRequest() { + @Test func requestDecodingTodoPostRequest() throws { let data = APIGatewayTests.todoPostEventBody.data(using: .utf8)! - var req: APIGatewayRequest? - XCTAssertNoThrow(req = try JSONDecoder().decode(APIGatewayRequest.self, from: data)) + let req = try JSONDecoder().decode(APIGatewayRequest.self, from: data) - XCTAssertEqual(req?.path, "/todos") - XCTAssertEqual(req?.httpMethod, .post) + #expect(req.path == "/todos") + #expect(req.httpMethod == .post) } // MARK: - Response - @@ -95,26 +93,24 @@ class APIGatewayTests: XCTestCase { let isBase64Encoded: Bool? } - func testResponseEncoding() { + @Test func responseEncoding() throws { let resp = APIGatewayResponse( statusCode: .ok, headers: ["Server": "Test"], body: "abc123" ) - var data: Data? - XCTAssertNoThrow(data = try JSONEncoder().encode(resp)) - var json: JSONResponse? - XCTAssertNoThrow(json = try JSONDecoder().decode(JSONResponse.self, from: XCTUnwrap(data))) + let data = try #require(try? JSONEncoder().encode(resp)) + let json = try JSONDecoder().decode(JSONResponse.self, from: data) - XCTAssertEqual(json?.statusCode, resp.statusCode.code) - XCTAssertEqual(json?.body, resp.body) - XCTAssertEqual(json?.isBase64Encoded, resp.isBase64Encoded) - XCTAssertEqual(json?.headers?["Server"], "Test") + #expect(json.statusCode == resp.statusCode.code) + #expect(json.body == resp.body) + #expect(json.isBase64Encoded == resp.isBase64Encoded) + #expect(json.headers?["Server"] == "Test") } - func testDecodingNilCollections() { + @Test func decodingNilCollections() { let data = APIGatewayTests.postEventBodyNilHeaders.data(using: .utf8)! - XCTAssertNoThrow(_ = try JSONDecoder().decode(APIGatewayRequest.self, from: data)) + #expect(throws: Never.self) { try JSONDecoder().decode(APIGatewayRequest.self, from: data) } } } diff --git a/Tests/AWSLambdaEventsTests/AppSyncTests.swift b/Tests/AWSLambdaEventsTests/AppSyncTests.swift index 0750006..e4dcf9a 100644 --- a/Tests/AWSLambdaEventsTests/AppSyncTests.swift +++ b/Tests/AWSLambdaEventsTests/AppSyncTests.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class AppSyncTests: XCTestCase { +@Suite +struct AppSyncTests { static let exampleEventBody = """ { "arguments": { @@ -96,31 +98,29 @@ class AppSyncTests: XCTestCase { // MARK: Decoding - func testRequestDecodingExampleEvent() { + @Test func requestDecodingExampleEvent() throws { let data = AppSyncTests.exampleEventBody.data(using: .utf8)! - var event: AppSyncEvent? - XCTAssertNoThrow(event = try JSONDecoder().decode(AppSyncEvent.self, from: data)) + let event = try JSONDecoder().decode(AppSyncEvent.self, from: data) - XCTAssertNotNil(event?.arguments) - XCTAssertEqual(event?.arguments["id"], .string("my identifier")) - XCTAssertEqual(event?.info.fieldName, "createSomething") - XCTAssertEqual(event?.info.parentTypeName, "Mutation") - XCTAssertEqual(event?.info.selectionSetList, ["id", "field1", "field2"]) - XCTAssertEqual(event?.request.headers["accept-language"], "en-US,en;q=0.9") + #expect(event.arguments["id"] == .string("my identifier")) + #expect(event.info.fieldName == "createSomething") + #expect(event.info.parentTypeName == "Mutation") + #expect(event.info.selectionSetList == ["id", "field1", "field2"]) + #expect(event.request.headers["accept-language"] == "en-US,en;q=0.9") - switch event?.identity { + switch event.identity { case .cognitoUserPools(let cognitoIdentity): - XCTAssertEqual(cognitoIdentity.defaultAuthStrategy, "ALLOW") - XCTAssertEqual(cognitoIdentity.issuer, "https://cognito-idp.us-west-2.amazonaws.com/us-west-xxxxxxxxxxx") - XCTAssertEqual(cognitoIdentity.sourceIp, ["1.1.1.1"]) - XCTAssertEqual(cognitoIdentity.username, "jdoe") - XCTAssertEqual(cognitoIdentity.sub, "192879fc-a240-4bf1-ab5a-d6a00f3063f9") + #expect(cognitoIdentity.defaultAuthStrategy == "ALLOW") + #expect(cognitoIdentity.issuer == "https://cognito-idp.us-west-2.amazonaws.com/us-west-xxxxxxxxxxx") + #expect(cognitoIdentity.sourceIp == ["1.1.1.1"]) + #expect(cognitoIdentity.username == "jdoe") + #expect(cognitoIdentity.sub == "192879fc-a240-4bf1-ab5a-d6a00f3063f9") default: - XCTAssertTrue(false, "a cognito identity was expected, but didn't find one.") + #expect(Bool(false), "a cognito identity was expected, but didn't find one.") } } - func testRequestDecodingEventWithSource() { + @Test func requestDecodingEventWithSource() throws { let eventBody = """ { "arguments": {}, @@ -172,14 +172,13 @@ class AppSyncTests: XCTestCase { """ let data = eventBody.data(using: .utf8)! - var event: AppSyncEvent? - XCTAssertNoThrow(event = try JSONDecoder().decode(AppSyncEvent.self, from: data)) - XCTAssertEqual(event?.source?["name"], "Hello") - XCTAssertTrue(event?.stash?.isEmpty ?? false, "stash dictionary must be empty") - XCTAssertNil(event?.identity) + let event = try JSONDecoder().decode(AppSyncEvent.self, from: data) + #expect(event.source?["name"] == "Hello") + #expect(event.stash?.isEmpty ?? false, "stash dictionary must be empty") + #expect(event.identity == nil) } - func testRequestDecodingIamIdentity() { + @Test func requestDecodingIamIdentity() throws { let eventBody = """ { "arguments": {}, @@ -240,20 +239,19 @@ class AppSyncTests: XCTestCase { """ let data = eventBody.data(using: .utf8)! - var event: AppSyncEvent? - XCTAssertNoThrow(event = try JSONDecoder().decode(AppSyncEvent.self, from: data)) - switch event?.identity { + let event = try JSONDecoder().decode(AppSyncEvent.self, from: data) + switch event.identity { case .iam(let iamIdentity): - XCTAssertEqual(iamIdentity.accountId, "accountId1") - XCTAssertEqual(iamIdentity.cognitoIdentityPoolId, "cognitoIdentityPool2") - XCTAssertEqual(iamIdentity.cognitoIdentityId, "cognitoIdentity3") - XCTAssertEqual(iamIdentity.sourceIp, ["1.1.1.1"]) - XCTAssertNil(iamIdentity.username) - XCTAssertEqual(iamIdentity.userArn, "arn123") - XCTAssertEqual(iamIdentity.cognitoIdentityAuthType, "authenticated") - XCTAssertEqual(iamIdentity.cognitoIdentityAuthProvider, "authprovider") + #expect(iamIdentity.accountId == "accountId1") + #expect(iamIdentity.cognitoIdentityPoolId == "cognitoIdentityPool2") + #expect(iamIdentity.cognitoIdentityId == "cognitoIdentity3") + #expect(iamIdentity.sourceIp == ["1.1.1.1"]) + #expect(iamIdentity.username == nil) + #expect(iamIdentity.userArn == "arn123") + #expect(iamIdentity.cognitoIdentityAuthType == "authenticated") + #expect(iamIdentity.cognitoIdentityAuthProvider == "authprovider") default: - XCTAssertTrue(false, "an iam identity was expected, but didn't find one.") + #expect(Bool(false), "an iam identity was expected, but didn't find one.") } } } diff --git a/Tests/AWSLambdaEventsTests/BedrockAgentTests.swift b/Tests/AWSLambdaEventsTests/BedrockAgentTests.swift index 055f683..6692401 100644 --- a/Tests/AWSLambdaEventsTests/BedrockAgentTests.swift +++ b/Tests/AWSLambdaEventsTests/BedrockAgentTests.swift @@ -12,12 +12,14 @@ // //===----------------------------------------------------------------------===// +import Foundation import HTTPTypes -import XCTest +import Testing @testable import AWSLambdaEvents -class BedrockAgentTests: XCTestCase { +@Suite +struct BedrockAgentTests { static let eventBody = """ { @@ -58,34 +60,33 @@ class BedrockAgentTests: XCTestCase { } """ - func testSimpleEventFromJSON() throws { + @Test func simpleEventFromJSON() throws { let data = BedrockAgentTests.eventBody.data(using: .utf8)! - var event: BedrockAgentRequest? - XCTAssertNoThrow(event = try JSONDecoder().decode(BedrockAgentRequest.self, from: data)) + let event = try JSONDecoder().decode(BedrockAgentRequest.self, from: data) - XCTAssertEqual(event?.messageVersion, "1.0") + #expect(event.messageVersion == "1.0") - XCTAssertEqual(event?.agent?.alias, "AGENT_ID") - XCTAssertEqual(event?.agent?.name, "StockQuoteAgent") - XCTAssertEqual(event?.agent?.version, "DRAFT") - XCTAssertEqual(event?.agent?.id, "PR3AHNYEAA") + #expect(event.agent?.alias == "AGENT_ID") + #expect(event.agent?.name == "StockQuoteAgent") + #expect(event.agent?.version == "DRAFT") + #expect(event.agent?.id == "PR3AHNYEAA") - XCTAssertEqual(event?.sessionId, "486652066693565") - XCTAssertEqual(event?.inputText, "what the price of amazon stock ?") - XCTAssertEqual(event?.apiPath, "/stocks/{symbol}") - XCTAssertEqual(event?.actionGroup, "StockQuoteService") - XCTAssertEqual(event?.httpMethod, .get) + #expect(event.sessionId == "486652066693565") + #expect(event.inputText == "what the price of amazon stock ?") + #expect(event.apiPath == "/stocks/{symbol}") + #expect(event.actionGroup == "StockQuoteService") + #expect(event.httpMethod == .get) - XCTAssertTrue(event?.parameters?.count == 1) - XCTAssertEqual(event?.parameters?[0].name, "symbol") - XCTAssertEqual(event?.parameters?[0].type, "string") - XCTAssertEqual(event?.parameters?[0].value, "AMZN") + #expect(event.parameters?.count == 1) + #expect(event.parameters?[0].name == "symbol") + #expect(event.parameters?[0].type == "string") + #expect(event.parameters?[0].value == "AMZN") - let body = try XCTUnwrap(event?.requestBody?.content) - let content = try XCTUnwrap(body["application/text"]) - XCTAssertTrue(content.properties.count == 1) - XCTAssertEqual(content.properties[0].name, "symbol") - XCTAssertEqual(content.properties[0].type, "string") - XCTAssertEqual(content.properties[0].value, "AMZN") + let body = try #require(event.requestBody?.content) + let content = try #require(body["application/text"]) + #expect(content.properties.count == 1) + #expect(content.properties[0].name == "symbol") + #expect(content.properties[0].type == "string") + #expect(content.properties[0].value == "AMZN") } } diff --git a/Tests/AWSLambdaEventsTests/CloudFormationTests.swift b/Tests/AWSLambdaEventsTests/CloudFormationTests.swift index e3e909f..f9b2589 100644 --- a/Tests/AWSLambdaEventsTests/CloudFormationTests.swift +++ b/Tests/AWSLambdaEventsTests/CloudFormationTests.swift @@ -12,11 +12,18 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Testing @testable import AWSLambdaEvents -class CloudFormationTests: XCTestCase { +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif + +@Suite +struct CloudFormationTests { struct TestResourceProperties: Codable { let property1: String let property2: String @@ -86,76 +93,81 @@ class CloudFormationTests: XCTestCase { "{\"Data\":{\"property1\":\"value1\",\"property2\":\"\",\"property3\":[\"1\",\"2\",\"3\"]},\"LogicalResourceId\":\"TestLogicalResource\",\"NoEcho\":false,\"PhysicalResourceId\":\"TestPhysicalResource\",\"Reason\":\"See the details in CloudWatch Log Stream\",\"RequestId\":\"cdc73f9d-aea9-11e3-9d5a-835b769c0d9c\",\"StackId\":\"arn:aws:cloudformation:us-east-1:123456789:stack\\/TestStack\",\"Status\":\"SUCCESS\"}" } - func testDecodeRequestRequiredFieldsFromJSON() { + @Test func decodeRequestRequiredFieldsFromJSON() throws { let eventBody = CloudFormationTests.eventBodyRequestRequiredFields() let data = eventBody.data(using: .utf8)! - var event: CloudFormation.Request? - XCTAssertNoThrow(event = try JSONDecoder().decode(CloudFormation.Request.self, from: data)) + let event: CloudFormation.Request? = try JSONDecoder() + .decode(CloudFormation.Request.self, from: data) - guard let event = event else { - return XCTFail("Expected to have an event") + guard let event else { + Issue.record("Expected to have an event") + return } - XCTAssertEqual(event.requestId, "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") - XCTAssertEqual(event.requestType, CloudFormation.Request.RequestType.create) - XCTAssertEqual(event.stackId, "arn:aws:cloudformation:us-east-1:123456789:stack/TestStack") - XCTAssertEqual(event.responseURL, "http://localhost:7000/response/test") - XCTAssertEqual(event.logicalResourceId, "TestLogicalResource") - XCTAssertNil(event.physicalResourceId) - XCTAssertNil(event.resourceProperties) - XCTAssertNil(event.oldResourceProperties) + #expect(event.requestId == "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") + #expect(event.requestType == CloudFormation.Request.RequestType.create) + #expect(event.stackId == "arn:aws:cloudformation:us-east-1:123456789:stack/TestStack") + #expect(event.responseURL == "http://localhost:7000/response/test") + #expect(event.logicalResourceId == "TestLogicalResource") + #expect(event.physicalResourceId == nil) + #expect(event.resourceProperties == nil) + #expect(event.oldResourceProperties == nil) } - func testDecodeRequestCreateFromJSON() { + @Test func decodeRequestCreateFromJSON() throws { let eventBody = CloudFormationTests.eventBodyRequestCreate() let data = eventBody.data(using: .utf8)! - var event: CloudFormation.Request? - XCTAssertNoThrow(event = try JSONDecoder().decode(CloudFormation.Request.self, from: data)) + let event: CloudFormation.Request? = try? JSONDecoder() + .decode(CloudFormation.Request.self, from: data) - guard let event = event else { - return XCTFail("Expected to have an event") + guard let event else { + Issue.record("Expected to have an event") + return } - XCTAssertEqual(event.requestId, "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") - XCTAssertEqual(event.requestType, CloudFormation.Request.RequestType.create) - XCTAssertEqual(event.stackId, "arn:aws:cloudformation:us-east-1:123456789:stack/TestStack") - XCTAssertEqual(event.responseURL, "http://localhost:7000/response/test") - XCTAssertEqual(event.logicalResourceId, "TestLogicalResource") - XCTAssertEqual(event.physicalResourceId, "TestPhysicalResource") - XCTAssertEqual(event.resourceProperties?.property1, "value1") - XCTAssertEqual(event.resourceProperties?.property2, "") - XCTAssertEqual(event.resourceProperties?.property3, ["1", "2", "3"]) - XCTAssertEqual(event.resourceProperties?.property4, nil) - XCTAssertNil(event.oldResourceProperties) + #expect(event.requestId == "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") + #expect(event.requestType == CloudFormation.Request.RequestType.create) + #expect(event.stackId == "arn:aws:cloudformation:us-east-1:123456789:stack/TestStack") + #expect(event.responseURL == "http://localhost:7000/response/test") + #expect(event.logicalResourceId == "TestLogicalResource") + #expect(event.physicalResourceId == "TestPhysicalResource") + #expect(event.resourceProperties?.property1 == "value1") + #expect(event.resourceProperties?.property2 == "") + #expect(event.resourceProperties?.property3 == ["1", "2", "3"]) + #expect(event.resourceProperties?.property4 == nil) + #expect(event.oldResourceProperties == nil) } - func testDecodeRequestUpdateFromJSON() { + @Test func decodeRequestUpdateFromJSON() throws { let eventBody = CloudFormationTests.eventBodyRequestUpdate() let data = eventBody.data(using: .utf8)! - var event: CloudFormation.Request? - XCTAssertNoThrow(event = try JSONDecoder().decode(CloudFormation.Request.self, from: data)) + let event: CloudFormation.Request? = try? JSONDecoder().decode( + CloudFormation.Request.self, + from: data + ) - guard let event = event else { - return XCTFail("Expected to have an event") + guard let event else { + Issue.record("Expected to have an event") + return } - XCTAssertEqual(event.requestId, "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") - XCTAssertEqual(event.requestType, CloudFormation.Request.RequestType.update) - XCTAssertEqual(event.stackId, "arn:aws:cloudformation:us-east-1:123456789:stack/TestStack") - XCTAssertEqual(event.responseURL, "http://localhost:7000/response/test") - XCTAssertEqual(event.logicalResourceId, "TestLogicalResource") - XCTAssertEqual(event.physicalResourceId, "TestPhysicalResource") - XCTAssertEqual(event.resourceProperties?.property1, "value1") - XCTAssertEqual(event.resourceProperties?.property2, "value2") - XCTAssertEqual(event.resourceProperties?.property3, ["1", "2", "3"]) - XCTAssertEqual(event.resourceProperties?.property4, "value4") - XCTAssertEqual(event.oldResourceProperties?.property1, "value1") - XCTAssertEqual(event.oldResourceProperties?.property2, "") - XCTAssertEqual(event.oldResourceProperties?.property3, ["1", "2", "3"]) - XCTAssertEqual(event.oldResourceProperties?.property4, nil) + #expect(event.requestId == "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") + #expect(event.requestType == CloudFormation.Request.RequestType.update) + #expect(event.stackId == "arn:aws:cloudformation:us-east-1:123456789:stack/TestStack") + #expect(event.responseURL == "http://localhost:7000/response/test") + #expect(event.logicalResourceId == "TestLogicalResource") + #expect(event.physicalResourceId == "TestPhysicalResource") + #expect(event.resourceProperties?.property1 == "value1") + #expect(event.resourceProperties?.property2 == "value2") + #expect(event.resourceProperties?.property3 == ["1", "2", "3"]) + #expect(event.resourceProperties?.property4 == "value4") + #expect(event.oldResourceProperties?.property1 == "value1") + #expect(event.oldResourceProperties?.property2 == "") + #expect(event.oldResourceProperties?.property3 == ["1", "2", "3"]) + #expect(event.oldResourceProperties?.property4 == nil) } - func testEncodeResponseToJSON() { + @Test func encodeResponseToJSON() throws { let resp = CloudFormation.Response( status: CloudFormation.Response.StatusType.success, requestId: "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c", @@ -175,14 +187,13 @@ class CloudFormationTests: XCTestCase { let encoder = JSONEncoder() encoder.outputFormatting = [.sortedKeys] - var data: Data? - XCTAssertNoThrow(data = try encoder.encode(resp)) + let data = try #require(try? encoder.encode(resp)) var stringData: String? - XCTAssertNoThrow(stringData = String(data: try XCTUnwrap(data), encoding: .utf8)) - - print(stringData ?? "") + #expect(throws: Never.self) { + stringData = String(data: data, encoding: .utf8) + } - XCTAssertEqual(CloudFormationTests.eventBodyResponse(), stringData) + #expect(CloudFormationTests.eventBodyResponse() == stringData) } } diff --git a/Tests/AWSLambdaEventsTests/CloudwatchTests.swift b/Tests/AWSLambdaEventsTests/CloudwatchTests.swift index b8beb94..ca4b0e9 100644 --- a/Tests/AWSLambdaEventsTests/CloudwatchTests.swift +++ b/Tests/AWSLambdaEventsTests/CloudwatchTests.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class CloudwatchTests: XCTestCase { +@Suite +struct CloudwatchTests { static func eventBody(type: String, details: String) -> String { """ { @@ -34,75 +36,56 @@ class CloudwatchTests: XCTestCase { """ } - func testScheduledEventFromJSON() { + @Test func scheduledEventFromJSON() throws { let eventBody = CloudwatchTests.eventBody(type: CloudwatchDetails.Scheduled.name, details: "{}") let data = eventBody.data(using: .utf8)! - var maybeEvent: CloudwatchScheduledEvent? - XCTAssertNoThrow(maybeEvent = try JSONDecoder().decode(CloudwatchScheduledEvent.self, from: data)) - - guard let event = maybeEvent else { - return XCTFail("Expected to have an event") - } - - XCTAssertEqual(event.id, "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") - XCTAssertEqual(event.source, "aws.events") - XCTAssertEqual(event.accountId, "123456789012") - XCTAssertEqual(event.time, Date(timeIntervalSince1970: 0)) - XCTAssertEqual(event.region, .us_east_1) - XCTAssertEqual(event.resources, ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) + let event = try JSONDecoder().decode(CloudwatchScheduledEvent.self, from: data) + + #expect(event.id == "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") + #expect(event.source == "aws.events") + #expect(event.accountId == "123456789012") + #expect(event.time == Date(timeIntervalSince1970: 0)) + #expect(event.region == .us_east_1) + #expect(event.resources == ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) } - func testEC2InstanceStateChangeNotificationEventFromJSON() { + @Test func ec2InstanceStateChangeNotificationEventFromJSON() throws { let eventBody = CloudwatchTests.eventBody( type: CloudwatchDetails.EC2.InstanceStateChangeNotification.name, details: "{ \"instance-id\": \"0\", \"state\": \"stopping\" }" ) let data = eventBody.data(using: .utf8)! - var maybeEvent: CloudwatchEC2InstanceStateChangeNotificationEvent? - XCTAssertNoThrow( - maybeEvent = try JSONDecoder().decode(CloudwatchEC2InstanceStateChangeNotificationEvent.self, from: data) - ) - - guard let event = maybeEvent else { - return XCTFail("Expected to have an event") - } - - XCTAssertEqual(event.id, "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") - XCTAssertEqual(event.source, "aws.events") - XCTAssertEqual(event.accountId, "123456789012") - XCTAssertEqual(event.time, Date(timeIntervalSince1970: 0)) - XCTAssertEqual(event.region, .us_east_1) - XCTAssertEqual(event.resources, ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) - XCTAssertEqual(event.detail.instanceId, "0") - XCTAssertEqual(event.detail.state, .stopping) + let event = try JSONDecoder().decode(CloudwatchEC2InstanceStateChangeNotificationEvent.self, from: data) + + #expect(event.id == "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") + #expect(event.source == "aws.events") + #expect(event.accountId == "123456789012") + #expect(event.time == Date(timeIntervalSince1970: 0)) + #expect(event.region == .us_east_1) + #expect(event.resources == ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) + #expect(event.detail.instanceId == "0") + #expect(event.detail.state == .stopping) } - func testEC2SpotInstanceInterruptionNoticeEventFromJSON() { + @Test func ec2SpotInstanceInterruptionNoticeEventFromJSON() throws { let eventBody = CloudwatchTests.eventBody( type: CloudwatchDetails.EC2.SpotInstanceInterruptionNotice.name, details: "{ \"instance-id\": \"0\", \"instance-action\": \"terminate\" }" ) let data = eventBody.data(using: .utf8)! - var maybeEvent: CloudwatchEC2SpotInstanceInterruptionNoticeEvent? - XCTAssertNoThrow( - maybeEvent = try JSONDecoder().decode(CloudwatchEC2SpotInstanceInterruptionNoticeEvent.self, from: data) - ) - - guard let event = maybeEvent else { - return XCTFail("Expected to have an event") - } - - XCTAssertEqual(event.id, "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") - XCTAssertEqual(event.source, "aws.events") - XCTAssertEqual(event.accountId, "123456789012") - XCTAssertEqual(event.time, Date(timeIntervalSince1970: 0)) - XCTAssertEqual(event.region, .us_east_1) - XCTAssertEqual(event.resources, ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) - XCTAssertEqual(event.detail.instanceId, "0") - XCTAssertEqual(event.detail.action, .terminate) + let event = try JSONDecoder().decode(CloudwatchEC2SpotInstanceInterruptionNoticeEvent.self, from: data) + + #expect(event.id == "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") + #expect(event.source == "aws.events") + #expect(event.accountId == "123456789012") + #expect(event.time == Date(timeIntervalSince1970: 0)) + #expect(event.region == .us_east_1) + #expect(event.resources == ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) + #expect(event.detail.instanceId == "0") + #expect(event.detail.action == .terminate) } - func testS3ObjectCreatedEventFromJSON() { + @Test func s3ObjectCreatedEventFromJSON() throws { let eventBody = CloudwatchTests.eventBody( type: CloudwatchDetails.S3.ObjectCreatedNotification.name, details: @@ -110,35 +93,28 @@ class CloudwatchTests: XCTestCase { ) let data = eventBody.data(using: .utf8)! - var maybeEvent: CloudWatchS3ObjectCreatedNotificationEvent? - XCTAssertNoThrow( - maybeEvent = try JSONDecoder().decode(CloudWatchS3ObjectCreatedNotificationEvent.self, from: data) - ) - - guard let event = maybeEvent else { - return XCTFail("Expected to have an event") - } - - XCTAssertEqual(event.id, "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") - XCTAssertEqual(event.source, "aws.events") - XCTAssertEqual(event.accountId, "123456789012") - XCTAssertEqual(event.time, Date(timeIntervalSince1970: 0)) - XCTAssertEqual(event.region, .us_east_1) - XCTAssertEqual(event.resources, ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) - XCTAssertEqual(event.detail.version, "0") - XCTAssertEqual(event.detail.bucket.name, "amzn-s3-demo-bucket1") - XCTAssertEqual(event.detail.object.key, "example-key") - XCTAssertEqual(event.detail.object.size, 5) - XCTAssertEqual(event.detail.object.etag, "b1946ac92492d2347c6235b4d2611184") - XCTAssertEqual(event.detail.object.versionId, "IYV3p45BT0ac8hjHg1houSdS1a.Mro8e") - XCTAssertEqual(event.detail.object.sequencer, "617f08299329d189") - XCTAssertEqual(event.detail.requestId, "N4N7GDK58NMKJ12R") - XCTAssertEqual(event.detail.requester, "123456789012") - XCTAssertEqual(event.detail.sourceIpAddress, "1.2.3.4") - XCTAssertEqual(event.detail.reason, .putObject) + let event = try JSONDecoder().decode(CloudWatchS3ObjectCreatedNotificationEvent.self, from: data) + + #expect(event.id == "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") + #expect(event.source == "aws.events") + #expect(event.accountId == "123456789012") + #expect(event.time == Date(timeIntervalSince1970: 0)) + #expect(event.region == .us_east_1) + #expect(event.resources == ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) + #expect(event.detail.version == "0") + #expect(event.detail.bucket.name == "amzn-s3-demo-bucket1") + #expect(event.detail.object.key == "example-key") + #expect(event.detail.object.size == 5) + #expect(event.detail.object.etag == "b1946ac92492d2347c6235b4d2611184") + #expect(event.detail.object.versionId == "IYV3p45BT0ac8hjHg1houSdS1a.Mro8e") + #expect(event.detail.object.sequencer == "617f08299329d189") + #expect(event.detail.requestId == "N4N7GDK58NMKJ12R") + #expect(event.detail.requester == "123456789012") + #expect(event.detail.sourceIpAddress == "1.2.3.4") + #expect(event.detail.reason == .putObject) } - func testS3ObjectDeletedEventFromJSON() { + @Test func s3ObjectDeletedEventFromJSON() throws { let eventBody = CloudwatchTests.eventBody( type: CloudwatchDetails.S3.ObjectDeletedNotification.name, details: @@ -146,35 +122,28 @@ class CloudwatchTests: XCTestCase { ) let data = eventBody.data(using: .utf8)! - var maybeEvent: CloudWatchS3ObjectDeletedNotificationEvent? - XCTAssertNoThrow( - maybeEvent = try JSONDecoder().decode(CloudWatchS3ObjectDeletedNotificationEvent.self, from: data) - ) - - guard let event = maybeEvent else { - return XCTFail("Expected to have an event") - } - - XCTAssertEqual(event.id, "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") - XCTAssertEqual(event.source, "aws.events") - XCTAssertEqual(event.accountId, "123456789012") - XCTAssertEqual(event.time, Date(timeIntervalSince1970: 0)) - XCTAssertEqual(event.region, .us_east_1) - XCTAssertEqual(event.resources, ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) - XCTAssertEqual(event.detail.version, "0") - XCTAssertEqual(event.detail.bucket.name, "amzn-s3-demo-bucket1") - XCTAssertEqual(event.detail.object.key, "example-key") - XCTAssertEqual(event.detail.object.etag, "d41d8cd98f00b204e9800998ecf8427e") - XCTAssertEqual(event.detail.object.versionId, "1QW9g1Z99LUNbvaaYVpW9xDlOLU.qxgF") - XCTAssertEqual(event.detail.object.sequencer, "617f0837b476e463") - XCTAssertEqual(event.detail.requestId, "0BH729840619AG5K") - XCTAssertEqual(event.detail.requester, "123456789012") - XCTAssertEqual(event.detail.sourceIpAddress, "1.2.3.4") - XCTAssertEqual(event.detail.reason, .deleteObject) - XCTAssertEqual(event.detail.deletionType, .deleteMarkerCreated) + let event = try JSONDecoder().decode(CloudWatchS3ObjectDeletedNotificationEvent.self, from: data) + + #expect(event.id == "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") + #expect(event.source == "aws.events") + #expect(event.accountId == "123456789012") + #expect(event.time == Date(timeIntervalSince1970: 0)) + #expect(event.region == .us_east_1) + #expect(event.resources == ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) + #expect(event.detail.version == "0") + #expect(event.detail.bucket.name == "amzn-s3-demo-bucket1") + #expect(event.detail.object.key == "example-key") + #expect(event.detail.object.etag == "d41d8cd98f00b204e9800998ecf8427e") + #expect(event.detail.object.versionId == "1QW9g1Z99LUNbvaaYVpW9xDlOLU.qxgF") + #expect(event.detail.object.sequencer == "617f0837b476e463") + #expect(event.detail.requestId == "0BH729840619AG5K") + #expect(event.detail.requester == "123456789012") + #expect(event.detail.sourceIpAddress == "1.2.3.4") + #expect(event.detail.reason == .deleteObject) + #expect(event.detail.deletionType == .deleteMarkerCreated) } - func testS3ObjectRestoreCompletedEventFromJSON() { + @Test func s3ObjectRestoreCompletedEventFromJSON() throws { let eventBody = CloudwatchTests.eventBody( type: CloudwatchDetails.S3.ObjectRestoreCompletedNotification.name, details: @@ -182,34 +151,27 @@ class CloudwatchTests: XCTestCase { ) let data = eventBody.data(using: .utf8)! - var maybeEvent: CloudWatchS3ObjectRestoreCompletedNotificationEvent? - XCTAssertNoThrow( - maybeEvent = try JSONDecoder().decode(CloudWatchS3ObjectRestoreCompletedNotificationEvent.self, from: data) - ) - - guard let event = maybeEvent else { - return XCTFail("Expected to have an event") - } - - XCTAssertEqual(event.id, "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") - XCTAssertEqual(event.source, "aws.events") - XCTAssertEqual(event.accountId, "123456789012") - XCTAssertEqual(event.time, Date(timeIntervalSince1970: 0)) - XCTAssertEqual(event.region, .us_east_1) - XCTAssertEqual(event.resources, ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) - XCTAssertEqual(event.detail.version, "0") - XCTAssertEqual(event.detail.bucket.name, "amzn-s3-demo-bucket1") - XCTAssertEqual(event.detail.object.key, "example-key") - XCTAssertEqual(event.detail.object.size, 5) - XCTAssertEqual(event.detail.object.etag, "b1946ac92492d2347c6235b4d2611184") - XCTAssertEqual(event.detail.object.versionId, "KKsjUC1.6gIjqtvhfg5AdMI0eCePIiT3") - XCTAssertEqual(event.detail.requestId, "189F19CB7FB1B6A4") - XCTAssertEqual(event.detail.requester, "s3.amazonaws.com") - XCTAssertEqual(event.detail.restoreExpiryTime.description, "2021-11-13 00:00:00 +0000") - XCTAssertEqual(event.detail.sourceStorageClass, .glacier) + let event = try JSONDecoder().decode(CloudWatchS3ObjectRestoreCompletedNotificationEvent.self, from: data) + + #expect(event.id == "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") + #expect(event.source == "aws.events") + #expect(event.accountId == "123456789012") + #expect(event.time == Date(timeIntervalSince1970: 0)) + #expect(event.region == .us_east_1) + #expect(event.resources == ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) + #expect(event.detail.version == "0") + #expect(event.detail.bucket.name == "amzn-s3-demo-bucket1") + #expect(event.detail.object.key == "example-key") + #expect(event.detail.object.size == 5) + #expect(event.detail.object.etag == "b1946ac92492d2347c6235b4d2611184") + #expect(event.detail.object.versionId == "KKsjUC1.6gIjqtvhfg5AdMI0eCePIiT3") + #expect(event.detail.requestId == "189F19CB7FB1B6A4") + #expect(event.detail.requester == "s3.amazonaws.com") + #expect(event.detail.restoreExpiryTime.description == "2021-11-13 00:00:00 +0000") + #expect(event.detail.sourceStorageClass == .glacier) } - func testCustomEventFromJSON() { + @Test func customEventFromJSON() throws { struct Custom: CloudwatchDetail { public static let name = "Custom" @@ -218,38 +180,33 @@ class CloudwatchTests: XCTestCase { let eventBody = CloudwatchTests.eventBody(type: Custom.name, details: "{ \"name\": \"foo\" }") let data = eventBody.data(using: .utf8)! - var maybeEvent: CloudwatchEvent? - XCTAssertNoThrow(maybeEvent = try JSONDecoder().decode(CloudwatchEvent.self, from: data)) - - guard let event = maybeEvent else { - return XCTFail("Expected to have an event") - } - - XCTAssertEqual(event.id, "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") - XCTAssertEqual(event.source, "aws.events") - XCTAssertEqual(event.accountId, "123456789012") - XCTAssertEqual(event.time, Date(timeIntervalSince1970: 0)) - XCTAssertEqual(event.region, .us_east_1) - XCTAssertEqual(event.resources, ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) - XCTAssertEqual(event.detail.name, "foo") + let event = try JSONDecoder().decode(CloudwatchEvent.self, from: data) + + #expect(event.id == "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c") + #expect(event.source == "aws.events") + #expect(event.accountId == "123456789012") + #expect(event.time == Date(timeIntervalSince1970: 0)) + #expect(event.region == .us_east_1) + #expect(event.resources == ["arn:aws:events:us-east-1:123456789012:rule/ExampleRule"]) + #expect(event.detail.name == "foo") } - func testUnregistredType() { + @Test func unregistredType() throws { let eventBody = CloudwatchTests.eventBody(type: UUID().uuidString, details: "{}") let data = eventBody.data(using: .utf8)! - XCTAssertThrowsError(try JSONDecoder().decode(CloudwatchScheduledEvent.self, from: data)) { error in - XCTAssert(error is CloudwatchDetails.TypeMismatch, "expected DetailTypeMismatch but received \(error)") + #expect(throws: CloudwatchDetails.TypeMismatch.self) { + try JSONDecoder().decode(CloudwatchScheduledEvent.self, from: data) } } - func testTypeMismatch() { + @Test func typeMismatch() throws { let eventBody = CloudwatchTests.eventBody( type: CloudwatchDetails.EC2.InstanceStateChangeNotification.name, details: "{ \"instance-id\": \"0\", \"state\": \"stopping\" }" ) let data = eventBody.data(using: .utf8)! - XCTAssertThrowsError(try JSONDecoder().decode(CloudwatchScheduledEvent.self, from: data)) { error in - XCTAssert(error is CloudwatchDetails.TypeMismatch, "expected DetailTypeMismatch but received \(error)") + #expect(throws: CloudwatchDetails.TypeMismatch.self) { + try JSONDecoder().decode(CloudwatchScheduledEvent.self, from: data) } } } diff --git a/Tests/AWSLambdaEventsTests/CognitoTests.swift b/Tests/AWSLambdaEventsTests/CognitoTests.swift index d356a6c..c20eb7d 100644 --- a/Tests/AWSLambdaEventsTests/CognitoTests.swift +++ b/Tests/AWSLambdaEventsTests/CognitoTests.swift @@ -12,12 +12,14 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -final class CognitoTests: XCTestCase { - func testPreSignUpRequest() throws { +@Suite +struct CognitoTests { + @Test func preSignUpRequest() throws { let json = """ { "version": "1", @@ -47,21 +49,21 @@ final class CognitoTests: XCTestCase { let event = try JSONDecoder().decode(CognitoEvent.self, from: json.data(using: .utf8)!) guard case .preSignUp(let params, let request) = event else { - XCTFail() + Issue.record("Failed to decode CognitoEvent as PreSignUp") return } - XCTAssertEqual(params.triggerSource, .preSignUp_SignUp) + #expect(params.triggerSource == .preSignUp_SignUp) let signUp = CognitoEvent.PreSignUp( userAttributes: ["string": "string"], validationData: ["string": "string"], clientMetadata: ["string": "string"] ) - XCTAssertEqual(request, signUp) + #expect(request == signUp) } - func testPreSignUpResponse() throws { + @Test func preSignUpResponse() throws { let params = CognitoEvent.Parameters( version: "1", triggerSource: .preSignUp_SignUp, @@ -89,16 +91,16 @@ final class CognitoTests: XCTestCase { let decodedResponse = try JSONDecoder().decode(CognitoEventResponse.self, from: data) guard case .preSignUp(let decodedParams, let decodedRequest, let decodedResponse) = decodedResponse else { - XCTFail() + Issue.record("Failed to decode CognitoEventResponse as PreSignUp") return } - XCTAssertEqual(decodedParams, params) - XCTAssertEqual(decodedRequest, request) - XCTAssertEqual(decodedResponse, signUpResponse) + #expect(decodedParams == params) + #expect(decodedRequest == request) + #expect(decodedResponse == signUpResponse) } - func testPostConfirmationRequest() throws { + @Test func postConfirmationRequest() throws { let json = """ { "version": "1", @@ -124,20 +126,20 @@ final class CognitoTests: XCTestCase { let event = try JSONDecoder().decode(CognitoEvent.self, from: json.data(using: .utf8)!) guard case .postConfirmation(let params, let request) = event else { - XCTFail() + Issue.record("Failed to decode CognitoEvent as PostConfirmation") return } - XCTAssertEqual(params.triggerSource, .postConfirmation_ConfirmSignUp) + #expect(params.triggerSource == .postConfirmation_ConfirmSignUp) let postConfirmation = CognitoEvent.PostConfirmation( userAttributes: ["string": "string"], clientMetadata: ["string": "string"] ) - XCTAssertEqual(request, postConfirmation) + #expect(request == postConfirmation) } - func testPostConfirmationResponse() throws { + @Test func postConfirmationResponse() throws { let params = CognitoEvent.Parameters( version: "1", triggerSource: .postConfirmation_ConfirmSignUp, @@ -161,16 +163,16 @@ final class CognitoTests: XCTestCase { guard case .postConfirmation(let decodedParams, let decodedRequest, let decodedResponse) = decodedResponse else { - XCTFail() + Issue.record("Failed to decode CognitoEventResponse as PostConfirmation") return } - XCTAssertEqual(decodedParams, params) - XCTAssertEqual(decodedRequest, request) - XCTAssertEqual(decodedResponse, postConfirmationResponse) + #expect(decodedParams == params) + #expect(decodedRequest == request) + #expect(decodedResponse == postConfirmationResponse) } - func testPostAuthenticationRequest() throws { + @Test func postAuthenticationRequest() throws { let json = """ { "version": "1", @@ -197,21 +199,21 @@ final class CognitoTests: XCTestCase { let event = try JSONDecoder().decode(CognitoEvent.self, from: json.data(using: .utf8)!) guard case .postAuthentication(let params, let request) = event else { - XCTFail() + Issue.record("Failed to decode CognitoEvent as PostAuthentication") return } - XCTAssertEqual(params.triggerSource, .postAuthentication_Authentication) + #expect(params.triggerSource == .postAuthentication_Authentication) let postAuthentication = CognitoEvent.PostAuthentication( newDeviceUsed: false, userAttributes: ["string": "string"], clientMetadata: ["string": "string"] ) - XCTAssertEqual(request, postAuthentication) + #expect(request == postAuthentication) } - func testPostAuthenticationResponse() throws { + @Test func postAuthenticationResponse() throws { let params = CognitoEvent.Parameters( version: "1", triggerSource: .postAuthentication_Authentication, @@ -236,16 +238,16 @@ final class CognitoTests: XCTestCase { guard case .postAuthentication(let decodedParams, let decodedRequest, let decodedResponse) = decodedResponse else { - XCTFail() + Issue.record("Failed to decode CognitoEventResponse as PostAuthentication") return } - XCTAssertEqual(decodedParams, params) - XCTAssertEqual(decodedRequest, request) - XCTAssertEqual(decodedResponse, postAuthenticationResponse) + #expect(decodedParams == params) + #expect(decodedRequest == request) + #expect(decodedResponse == postAuthenticationResponse) } - func testCustomMessageRequest() throws { + @Test func customMessageRequest() throws { let json = """ { "version": "1", @@ -273,11 +275,11 @@ final class CognitoTests: XCTestCase { let event = try JSONDecoder().decode(CognitoEvent.self, from: json.data(using: .utf8)!) guard case .customMessage(let params, let request) = event else { - XCTFail() + Issue.record("Failed to decode CognitoEvent as CustomMessage") return } - XCTAssertEqual(params.triggerSource, .customMessage_AdminCreateUser) + #expect(params.triggerSource == .customMessage_AdminCreateUser) let postAuthentication = CognitoEvent.CustomMessage( codeParameter: "######", @@ -285,10 +287,10 @@ final class CognitoTests: XCTestCase { userAttributes: ["string": "string"], clientMetadata: ["string": "string"] ) - XCTAssertEqual(request, postAuthentication) + #expect(request == postAuthentication) } - func testCustomMessageResponse() throws { + @Test func customMessageResponse() throws { let params = CognitoEvent.Parameters( version: "1", triggerSource: .customMessage_AdminCreateUser, @@ -317,12 +319,12 @@ final class CognitoTests: XCTestCase { let decodedResponse = try JSONDecoder().decode(CognitoEventResponse.self, from: data) guard case .customMessage(let decodedParams, let decodedRequest, let decodedResponse) = decodedResponse else { - XCTFail() + Issue.record("Failed to decode CognitoEventResponse as CustomMessage") return } - XCTAssertEqual(decodedParams, params) - XCTAssertEqual(decodedRequest, request) - XCTAssertEqual(decodedResponse, customMessageResponse) + #expect(decodedParams == params) + #expect(decodedRequest == request) + #expect(decodedResponse == customMessageResponse) } } diff --git a/Tests/AWSLambdaEventsTests/DynamoDBTests.swift b/Tests/AWSLambdaEventsTests/DynamoDBTests.swift index 28905d1..d5e34a2 100644 --- a/Tests/AWSLambdaEventsTests/DynamoDBTests.swift +++ b/Tests/AWSLambdaEventsTests/DynamoDBTests.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class DynamoDBTests: XCTestCase { +@Suite +struct DynamoDBTests { static let streamEventBody = """ { "Records": [ @@ -113,133 +115,127 @@ class DynamoDBTests: XCTestCase { } """ - func testEventFromJSON() { + @Test func eventFromJSON() throws { let data = DynamoDBTests.streamEventBody.data(using: .utf8)! - var event: DynamoDBEvent? - XCTAssertNoThrow(event = try JSONDecoder().decode(DynamoDBEvent.self, from: data)) + let event = try JSONDecoder().decode(DynamoDBEvent.self, from: data) - XCTAssertEqual(event?.records.count, 3) + #expect(event.records.count == 3) } // MARK: - Parse Attribute Value Tests - - func testAttributeValueBoolDecoding() { + @Test func attributeValueBoolDecoding() { let json = "{\"BOOL\": true}" var value: DynamoDBEvent.AttributeValue? - XCTAssertNoThrow( + #expect(throws: Never.self) { value = try JSONDecoder().decode(DynamoDBEvent.AttributeValue.self, from: json.data(using: .utf8)!) - ) - XCTAssertEqual(value, .boolean(true)) + } + #expect(value == .boolean(true)) } - func testAttributeValueBinaryDecoding() { + @Test func attributeValueBinaryDecoding() { let json = "{\"B\": \"YmFzZTY0\"}" var value: DynamoDBEvent.AttributeValue? - XCTAssertNoThrow( + #expect(throws: Never.self) { value = try JSONDecoder().decode(DynamoDBEvent.AttributeValue.self, from: json.data(using: .utf8)!) - ) - XCTAssertEqual(value, .binary([UInt8]("base64".utf8))) + } + #expect(value == .binary([UInt8]("base64".utf8))) } - func testAttributeValueBinarySetDecoding() { + @Test func attributeValueBinarySetDecoding() { let json = "{\"BS\": [\"YmFzZTY0\", \"YWJjMTIz\"]}" var value: DynamoDBEvent.AttributeValue? - XCTAssertNoThrow( + #expect(throws: Never.self) { value = try JSONDecoder().decode(DynamoDBEvent.AttributeValue.self, from: json.data(using: .utf8)!) - ) - XCTAssertEqual(value, .binarySet([[UInt8]("base64".utf8), [UInt8]("abc123".utf8)])) + } + #expect(value == .binarySet([[UInt8]("base64".utf8), [UInt8]("abc123".utf8)])) } - func testAttributeValueStringDecoding() { + @Test func attributeValueStringDecoding() { let json = "{\"S\": \"huhu\"}" var value: DynamoDBEvent.AttributeValue? - XCTAssertNoThrow( + #expect(throws: Never.self) { value = try JSONDecoder().decode(DynamoDBEvent.AttributeValue.self, from: json.data(using: .utf8)!) - ) - XCTAssertEqual(value, .string("huhu")) + } + #expect(value == .string("huhu")) } - func testAttributeValueStringSetDecoding() { + @Test func attributeValueStringSetDecoding() { let json = "{\"SS\": [\"huhu\", \"haha\"]}" var value: DynamoDBEvent.AttributeValue? - XCTAssertNoThrow( + #expect(throws: Never.self) { value = try JSONDecoder().decode(DynamoDBEvent.AttributeValue.self, from: json.data(using: .utf8)!) - ) - XCTAssertEqual(value, .stringSet(["huhu", "haha"])) + } + #expect(value == .stringSet(["huhu", "haha"])) } - func testAttributeValueNullDecoding() { + @Test func attributeValueNullDecoding() { let json = "{\"NULL\": true}" var value: DynamoDBEvent.AttributeValue? - XCTAssertNoThrow( + #expect(throws: Never.self) { value = try JSONDecoder().decode(DynamoDBEvent.AttributeValue.self, from: json.data(using: .utf8)!) - ) - XCTAssertEqual(value, .null) + } + #expect(value == .null) } - func testAttributeValueNumberDecoding() { + @Test func attributeValueNumberDecoding() { let json = "{\"N\": \"1.2345\"}" var value: DynamoDBEvent.AttributeValue? - XCTAssertNoThrow( + #expect(throws: Never.self) { value = try JSONDecoder().decode(DynamoDBEvent.AttributeValue.self, from: json.data(using: .utf8)!) - ) - XCTAssertEqual(value, .number("1.2345")) + } + #expect(value == .number("1.2345")) } - func testAttributeValueNumberSetDecoding() { + @Test func attributeValueNumberSetDecoding() { let json = "{\"NS\": [\"1.2345\", \"-19\"]}" var value: DynamoDBEvent.AttributeValue? - XCTAssertNoThrow( + #expect(throws: Never.self) { value = try JSONDecoder().decode(DynamoDBEvent.AttributeValue.self, from: json.data(using: .utf8)!) - ) - XCTAssertEqual(value, .numberSet(["1.2345", "-19"])) + } + #expect(value == .numberSet(["1.2345", "-19"])) } - func testAttributeValueListDecoding() { + @Test func attributeValueListDecoding() { let json = "{\"L\": [{\"NS\": [\"1.2345\", \"-19\"]}, {\"S\": \"huhu\"}]}" var value: DynamoDBEvent.AttributeValue? - XCTAssertNoThrow( + #expect(throws: Never.self) { value = try JSONDecoder().decode(DynamoDBEvent.AttributeValue.self, from: json.data(using: .utf8)!) - ) - XCTAssertEqual(value, .list([.numberSet(["1.2345", "-19"]), .string("huhu")])) + } + #expect(value == .list([.numberSet(["1.2345", "-19"]), .string("huhu")])) } - func testAttributeValueMapDecoding() { + @Test func attributeValueMapDecoding() { let json = "{\"M\": {\"numbers\": {\"NS\": [\"1.2345\", \"-19\"]}, \"string\": {\"S\": \"huhu\"}}}" var value: DynamoDBEvent.AttributeValue? - XCTAssertNoThrow( + #expect(throws: Never.self) { value = try JSONDecoder().decode(DynamoDBEvent.AttributeValue.self, from: json.data(using: .utf8)!) - ) - XCTAssertEqual( - value, - .map([ - "numbers": .numberSet(["1.2345", "-19"]), - "string": .string("huhu"), - ]) + } + #expect( + value + == .map([ + "numbers": .numberSet(["1.2345", "-19"]), + "string": .string("huhu"), + ]) ) } - func testAttributeValueEmptyDecoding() { + @Test func attributeValueEmptyDecoding() { let json = "{\"haha\": 1}" - XCTAssertThrowsError( + #expect(throws: (any Error).self) { try JSONDecoder().decode(DynamoDBEvent.AttributeValue.self, from: json.data(using: .utf8)!) - ) { error in - guard case DecodingError.dataCorrupted = error else { - XCTFail("Unexpected error: \(String(describing: error))") - return - } } } - func testAttributeValueEquatable() { - XCTAssertEqual(DynamoDBEvent.AttributeValue.boolean(true), .boolean(true)) - XCTAssertNotEqual(DynamoDBEvent.AttributeValue.boolean(true), .boolean(false)) - XCTAssertNotEqual(DynamoDBEvent.AttributeValue.boolean(true), .string("haha")) + @Test func attributeValueEquatable() { + #expect(DynamoDBEvent.AttributeValue.boolean(true) == .boolean(true)) + #expect(DynamoDBEvent.AttributeValue.boolean(true) != .boolean(false)) + #expect(DynamoDBEvent.AttributeValue.boolean(true) != .string("haha")) } // MARK: - DynamoDB Decoder Tests - - func testDecoderSimple() { + @Test func decoderSimple() { let value: [String: DynamoDBEvent.AttributeValue] = [ "foo": .string("bar"), "xyz": .number("123"), @@ -250,9 +246,8 @@ class DynamoDBTests: XCTestCase { let xyz: UInt8 } - var test: Test? - XCTAssertNoThrow(test = try DynamoDBEvent.Decoder().decode(Test.self, from: value)) - XCTAssertEqual(test?.foo, "bar") - XCTAssertEqual(test?.xyz, 123) + let test = try? DynamoDBEvent.Decoder().decode(Test.self, from: value) + #expect(test?.foo == "bar") + #expect(test?.xyz == 123) } } diff --git a/Tests/AWSLambdaEventsTests/FunctionURLTests.swift b/Tests/AWSLambdaEventsTests/FunctionURLTests.swift index eb70c67..4a022f6 100644 --- a/Tests/AWSLambdaEventsTests/FunctionURLTests.swift +++ b/Tests/AWSLambdaEventsTests/FunctionURLTests.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class FunctionURLTests: XCTestCase { +@Suite +struct FunctionURLTests { /// Example event body pulled from [AWS documentation](https://docs.aws.amazon.com/lambda/latest/dg/urls-invocation.html#urls-request-payload). static let documentationExample = """ { @@ -124,30 +126,28 @@ class FunctionURLTests: XCTestCase { // MARK: Decoding - func testRequestDecodingDocumentationExampleRequest() { + @Test func requestDecodingDocumentationExampleRequest() throws { let data = Self.documentationExample.data(using: .utf8)! - var req: FunctionURLRequest? - XCTAssertNoThrow(req = try JSONDecoder().decode(FunctionURLRequest.self, from: data)) + let req = try JSONDecoder().decode(FunctionURLRequest.self, from: data) - XCTAssertEqual(req?.rawPath, "/my/path") - XCTAssertEqual(req?.requestContext.http.method, .post) - XCTAssertEqual(req?.queryStringParameters?.count, 2) - XCTAssertEqual(req?.rawQueryString, "parameter1=value1¶meter1=value2¶meter2=value") - XCTAssertEqual(req?.headers.count, 2) - XCTAssertEqual(req?.body, "Hello from client!") + #expect(req.rawPath == "/my/path") + #expect(req.requestContext.http.method == .post) + #expect(req.queryStringParameters?.count == 2) + #expect(req.rawQueryString == "parameter1=value1¶meter1=value2¶meter2=value") + #expect(req.headers.count == 2) + #expect(req.body == "Hello from client!") } - func testRequestDecodingRealWorldExampleRequest() { + @Test func requestDecodingRealWorldExampleRequest() throws { let data = Self.realWorldExample.data(using: .utf8)! - var req: FunctionURLRequest? - XCTAssertNoThrow(req = try JSONDecoder().decode(FunctionURLRequest.self, from: data)) + let req = try JSONDecoder().decode(FunctionURLRequest.self, from: data) - XCTAssertEqual(req?.rawPath, "/") - XCTAssertEqual(req?.requestContext.http.method, .get) - XCTAssertEqual(req?.queryStringParameters?.count, 1) - XCTAssertEqual(req?.rawQueryString, "test=2") - XCTAssertEqual(req?.headers.count, 10) - XCTAssertEqual(req?.cookies, ["test"]) - XCTAssertNil(req?.body) + #expect(req.rawPath == "/") + #expect(req.requestContext.http.method == .get) + #expect(req.queryStringParameters?.count == 1) + #expect(req.rawQueryString == "test=2") + #expect(req.headers.count == 10) + #expect(req.cookies == ["test"]) + #expect(req.body == nil) } } diff --git a/Tests/AWSLambdaEventsTests/LambdaGatewayProxyEventTests.swift b/Tests/AWSLambdaEventsTests/LambdaGatewayProxyEventTests.swift index 91e5240..025464b 100644 --- a/Tests/AWSLambdaEventsTests/LambdaGatewayProxyEventTests.swift +++ b/Tests/AWSLambdaEventsTests/LambdaGatewayProxyEventTests.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class LambdaGatewayProxyEventTests: XCTestCase { +@Suite +struct LambdaGatewayProxyEventTests { static let exampleLambdaProxyEvent = """ { "resource": "/hello", @@ -117,15 +119,14 @@ class LambdaGatewayProxyEventTests: XCTestCase { // MARK: Decoding - func testRequestDecodingExampleProxyRequest() { + @Test func requestDecodingExampleProxyRequest() throws { let data = LambdaGatewayProxyEventTests.exampleLambdaProxyEvent.data(using: .utf8)! - var req: LambdaGatewayProxyEvent? - XCTAssertNoThrow(req = try JSONDecoder().decode(LambdaGatewayProxyEvent.self, from: data)) + let req = try JSONDecoder().decode(LambdaGatewayProxyEvent.self, from: data) - XCTAssertEqual(req?.path, "/hello") - XCTAssertEqual(req?.requestContext.httpMethod, .get) - XCTAssertEqual(req?.queryStringParameters?.count, 1) - XCTAssertEqual(req?.headers.count, 8) - XCTAssertNotNil(req?.body) + #expect(req.path == "/hello") + #expect(req.requestContext.httpMethod == .get) + #expect(req.queryStringParameters?.count == 1) + #expect(req.headers.count == 8) + #expect(req.body != nil) } } diff --git a/Tests/AWSLambdaEventsTests/S3Tests.swift b/Tests/AWSLambdaEventsTests/S3Tests.swift index 0d3e2da..64b5de2 100644 --- a/Tests/AWSLambdaEventsTests/S3Tests.swift +++ b/Tests/AWSLambdaEventsTests/S3Tests.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class S3Tests: XCTestCase { +@Suite +struct S3Tests { static let eventBodyObjectCreated = """ { "Records": [ @@ -99,61 +101,51 @@ class S3Tests: XCTestCase { } """ - func testSimpleEventFromJSON() { + @Test func simpleEventFromJSON() throws { let data = S3Tests.eventBodyObjectCreated.data(using: .utf8)! - var event: S3Event? - XCTAssertNoThrow(event = try JSONDecoder().decode(S3Event.self, from: data)) + let event = try JSONDecoder().decode(S3Event.self, from: data) + let record = try #require(event.records.first) - guard let record = event?.records.first else { - XCTFail("Expected to have one record") - return - } - - XCTAssertEqual(record.eventVersion, "2.1") - XCTAssertEqual(record.eventSource, "aws:s3") - XCTAssertEqual(record.awsRegion, .eu_central_1) - XCTAssertEqual(record.eventName, "ObjectCreated:Put") - XCTAssertEqual(record.eventTime, Date(timeIntervalSince1970: 1_578_907_540.621)) - XCTAssertEqual(record.userIdentity, S3Event.UserIdentity(principalId: "AWS:AAAAAAAJ2MQ4YFQZ7AULJ")) - XCTAssertEqual(record.requestParameters, S3Event.RequestParameters(sourceIPAddress: "123.123.123.123")) - XCTAssertEqual(record.responseElements.count, 2) - XCTAssertEqual(record.s3.schemaVersion, "1.0") - XCTAssertEqual(record.s3.configurationId, "98b55bc4-3c0c-4007-b727-c6b77a259dde") - XCTAssertEqual(record.s3.bucket.name, "eventsources") - XCTAssertEqual(record.s3.bucket.ownerIdentity, S3Event.UserIdentity(principalId: "AAAAAAAAAAAAAA")) - XCTAssertEqual(record.s3.bucket.arn, "arn:aws:s3:::eventsources") - XCTAssertEqual(record.s3.object.key, "Hi.md") - XCTAssertEqual(record.s3.object.size, 2880) - XCTAssertEqual(record.s3.object.eTag, "91a7f2c3ae81bcc6afef83979b463f0e") - XCTAssertEqual(record.s3.object.sequencer, "005E1C37948E783A6E") + #expect(record.eventVersion == "2.1") + #expect(record.eventSource == "aws:s3") + #expect(record.awsRegion == .eu_central_1) + #expect(record.eventName == "ObjectCreated:Put") + #expect(record.eventTime == Date(timeIntervalSince1970: 1_578_907_540.621)) + #expect(record.userIdentity == S3Event.UserIdentity(principalId: "AWS:AAAAAAAJ2MQ4YFQZ7AULJ")) + #expect(record.requestParameters == S3Event.RequestParameters(sourceIPAddress: "123.123.123.123")) + #expect(record.responseElements.count == 2) + #expect(record.s3.schemaVersion == "1.0") + #expect(record.s3.configurationId == "98b55bc4-3c0c-4007-b727-c6b77a259dde") + #expect(record.s3.bucket.name == "eventsources") + #expect(record.s3.bucket.ownerIdentity == S3Event.UserIdentity(principalId: "AAAAAAAAAAAAAA")) + #expect(record.s3.bucket.arn == "arn:aws:s3:::eventsources") + #expect(record.s3.object.key == "Hi.md") + #expect(record.s3.object.size == 2880) + #expect(record.s3.object.eTag == "91a7f2c3ae81bcc6afef83979b463f0e") + #expect(record.s3.object.sequencer == "005E1C37948E783A6E") } - func testObjectRemovedEvent() { + @Test func objectRemovedEvent() throws { let data = S3Tests.eventBodyObjectRemoved.data(using: .utf8)! - var event: S3Event? - XCTAssertNoThrow(event = try JSONDecoder().decode(S3Event.self, from: data)) - - guard let record = event?.records.first else { - XCTFail("Expected to have one record") - return - } + let event = try JSONDecoder().decode(S3Event.self, from: data) + let record = try #require(event.records.first) - XCTAssertEqual(record.eventVersion, "2.1") - XCTAssertEqual(record.eventSource, "aws:s3") - XCTAssertEqual(record.awsRegion, .eu_central_1) - XCTAssertEqual(record.eventName, "ObjectRemoved:DeleteMarkerCreated") - XCTAssertEqual(record.eventTime, Date(timeIntervalSince1970: 1_578_907_540.621)) - XCTAssertEqual(record.userIdentity, S3Event.UserIdentity(principalId: "AWS:AAAAAAAJ2MQ4YFQZ7AULJ")) - XCTAssertEqual(record.requestParameters, S3Event.RequestParameters(sourceIPAddress: "123.123.123.123")) - XCTAssertEqual(record.responseElements.count, 2) - XCTAssertEqual(record.s3.schemaVersion, "1.0") - XCTAssertEqual(record.s3.configurationId, "98b55bc4-3c0c-4007-b727-c6b77a259dde") - XCTAssertEqual(record.s3.bucket.name, "eventsources") - XCTAssertEqual(record.s3.bucket.ownerIdentity, S3Event.UserIdentity(principalId: "AAAAAAAAAAAAAA")) - XCTAssertEqual(record.s3.bucket.arn, "arn:aws:s3:::eventsources") - XCTAssertEqual(record.s3.object.key, "Hi.md") - XCTAssertNil(record.s3.object.size) - XCTAssertEqual(record.s3.object.eTag, "91a7f2c3ae81bcc6afef83979b463f0e") - XCTAssertEqual(record.s3.object.sequencer, "005E1C37948E783A6E") + #expect(record.eventVersion == "2.1") + #expect(record.eventSource == "aws:s3") + #expect(record.awsRegion == .eu_central_1) + #expect(record.eventName == "ObjectRemoved:DeleteMarkerCreated") + #expect(record.eventTime == Date(timeIntervalSince1970: 1_578_907_540.621)) + #expect(record.userIdentity == S3Event.UserIdentity(principalId: "AWS:AAAAAAAJ2MQ4YFQZ7AULJ")) + #expect(record.requestParameters == S3Event.RequestParameters(sourceIPAddress: "123.123.123.123")) + #expect(record.responseElements.count == 2) + #expect(record.s3.schemaVersion == "1.0") + #expect(record.s3.configurationId == "98b55bc4-3c0c-4007-b727-c6b77a259dde") + #expect(record.s3.bucket.name == "eventsources") + #expect(record.s3.bucket.ownerIdentity == S3Event.UserIdentity(principalId: "AAAAAAAAAAAAAA")) + #expect(record.s3.bucket.arn == "arn:aws:s3:::eventsources") + #expect(record.s3.object.key == "Hi.md") + #expect(record.s3.object.size == nil) + #expect(record.s3.object.eTag == "91a7f2c3ae81bcc6afef83979b463f0e") + #expect(record.s3.object.sequencer == "005E1C37948E783A6E") } } diff --git a/Tests/AWSLambdaEventsTests/SESTests.swift b/Tests/AWSLambdaEventsTests/SESTests.swift index ceb5ce1..697fae6 100644 --- a/Tests/AWSLambdaEventsTests/SESTests.swift +++ b/Tests/AWSLambdaEventsTests/SESTests.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class SESTests: XCTestCase { +@Suite +struct SESTests { static let eventBody = """ { "Records": [ @@ -86,47 +88,42 @@ class SESTests: XCTestCase { } """ - func testSimpleEventFromJSON() { + @Test func simpleEventFromJSON() throws { let data = Data(SESTests.eventBody.utf8) - var event: SESEvent? - XCTAssertNoThrow(event = try JSONDecoder().decode(SESEvent.self, from: data)) + let event = try JSONDecoder().decode(SESEvent.self, from: data) + let record = try #require(event.records.first) - guard let record = event?.records.first else { - XCTFail("Expected to have one record") - return - } - - XCTAssertEqual(record.eventSource, "aws:ses") - XCTAssertEqual(record.eventVersion, "1.0") - XCTAssertEqual(record.ses.mail.commonHeaders.date.description, "2015-10-07 19:34:56 +0000") - XCTAssertEqual(record.ses.mail.commonHeaders.from[0], "Jane Doe ") - XCTAssertEqual(record.ses.mail.commonHeaders.messageId, "<0123456789example.com>") - XCTAssertEqual(record.ses.mail.commonHeaders.returnPath, "janedoe@example.com") - XCTAssertEqual(record.ses.mail.commonHeaders.subject, "Test Subject") - XCTAssertEqual(record.ses.mail.commonHeaders.to?[0], "johndoe@example.com") - XCTAssertEqual(record.ses.mail.destination[0], "johndoe@example.com") - XCTAssertEqual(record.ses.mail.headers[0].name, "Return-Path") - XCTAssertEqual(record.ses.mail.headers[0].value, "") - XCTAssertEqual(record.ses.mail.headers[1].name, "Received") - XCTAssertEqual( - record.ses.mail.headers[1].value, - "from mailer.example.com (mailer.example.com [203.0.113.1]) by inbound-smtp.eu-west-1.amazonaws.com with SMTP id o3vrnil0e2ic28trm7dfhrc2v0cnbeccl4nbp0g1 for johndoe@example.com; Wed, 07 Oct 2015 12:34:56 +0000 (UTC)" + #expect(record.eventSource == "aws:ses") + #expect(record.eventVersion == "1.0") + #expect(record.ses.mail.commonHeaders.date.description == "2015-10-07 19:34:56 +0000") + #expect(record.ses.mail.commonHeaders.from[0] == "Jane Doe ") + #expect(record.ses.mail.commonHeaders.messageId == "<0123456789example.com>") + #expect(record.ses.mail.commonHeaders.returnPath == "janedoe@example.com") + #expect(record.ses.mail.commonHeaders.subject == "Test Subject") + #expect(record.ses.mail.commonHeaders.to?[0] == "johndoe@example.com") + #expect(record.ses.mail.destination[0] == "johndoe@example.com") + #expect(record.ses.mail.headers[0].name == "Return-Path") + #expect(record.ses.mail.headers[0].value == "") + #expect(record.ses.mail.headers[1].name == "Received") + #expect( + record.ses.mail.headers[1].value + == "from mailer.example.com (mailer.example.com [203.0.113.1]) by inbound-smtp.eu-west-1.amazonaws.com with SMTP id o3vrnil0e2ic28trm7dfhrc2v0cnbeccl4nbp0g1 for johndoe@example.com; Wed, 07 Oct 2015 12:34:56 +0000 (UTC)" ) - XCTAssertEqual(record.ses.mail.headersTruncated, true) - XCTAssertEqual(record.ses.mail.messageId, "5h5auqp1oa1bg49b2q8f8tmli1oju8pcma2haao1") - XCTAssertEqual(record.ses.mail.source, "janedoe@example.com") - XCTAssertEqual(record.ses.mail.timestamp.description, "1970-01-01 00:00:00 +0000") + #expect(record.ses.mail.headersTruncated == true) + #expect(record.ses.mail.messageId == "5h5auqp1oa1bg49b2q8f8tmli1oju8pcma2haao1") + #expect(record.ses.mail.source == "janedoe@example.com") + #expect(record.ses.mail.timestamp.description == "1970-01-01 00:00:00 +0000") - XCTAssertEqual(record.ses.receipt.action.functionArn, "arn:aws:lambda:eu-west-1:123456789012:function:Example") - XCTAssertEqual(record.ses.receipt.action.invocationType, "Event") - XCTAssertEqual(record.ses.receipt.action.type, "Lambda") - XCTAssertEqual(record.ses.receipt.dkimVerdict.status, .pass) - XCTAssertEqual(record.ses.receipt.processingTimeMillis, 574) - XCTAssertEqual(record.ses.receipt.recipients[0], "test@swift-server.com") - XCTAssertEqual(record.ses.receipt.recipients[1], "test2@swift-server.com") - XCTAssertEqual(record.ses.receipt.spamVerdict.status, .pass) - XCTAssertEqual(record.ses.receipt.spfVerdict.status, .processingFailed) - XCTAssertEqual(record.ses.receipt.timestamp.description, "1970-01-01 00:00:00 +0000") - XCTAssertEqual(record.ses.receipt.virusVerdict.status, .fail) + #expect(record.ses.receipt.action.functionArn == "arn:aws:lambda:eu-west-1:123456789012:function:Example") + #expect(record.ses.receipt.action.invocationType == "Event") + #expect(record.ses.receipt.action.type == "Lambda") + #expect(record.ses.receipt.dkimVerdict.status == .pass) + #expect(record.ses.receipt.processingTimeMillis == 574) + #expect(record.ses.receipt.recipients[0] == "test@swift-server.com") + #expect(record.ses.receipt.recipients[1] == "test2@swift-server.com") + #expect(record.ses.receipt.spamVerdict.status == .pass) + #expect(record.ses.receipt.spfVerdict.status == .processingFailed) + #expect(record.ses.receipt.timestamp.description == "1970-01-01 00:00:00 +0000") + #expect(record.ses.receipt.virusVerdict.status == .fail) } } diff --git a/Tests/AWSLambdaEventsTests/SNSTests.swift b/Tests/AWSLambdaEventsTests/SNSTests.swift index 7c8368a..70afded 100644 --- a/Tests/AWSLambdaEventsTests/SNSTests.swift +++ b/Tests/AWSLambdaEventsTests/SNSTests.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class SNSTests: XCTestCase { +@Suite +struct SNSTests { static let eventBody = """ { "Records": [ @@ -51,45 +53,44 @@ class SNSTests: XCTestCase { } """ - func testSimpleEventFromJSON() { + @Test func simpleEventFromJSON() throws { let data = SNSTests.eventBody.data(using: .utf8)! - var event: SNSEvent? - XCTAssertNoThrow(event = try JSONDecoder().decode(SNSEvent.self, from: data)) + let event = try JSONDecoder().decode(SNSEvent.self, from: data) - guard let record = event?.records.first else { - XCTFail("Expected to have one record") + guard let record = event.records.first else { + Issue.record("Expected to have one record") return } - XCTAssertEqual(record.eventSource, "aws:sns") - XCTAssertEqual(record.eventVersion, "1.0") - XCTAssertEqual( - record.eventSubscriptionArn, - "arn:aws:sns:eu-central-1:079477498937:EventSources-SNSTopic-1NHENSE2MQKF5:6fabdb7f-b27e-456d-8e8a-14679db9e40c" + #expect(record.eventSource == "aws:sns") + #expect(record.eventVersion == "1.0") + #expect( + record.eventSubscriptionArn + == "arn:aws:sns:eu-central-1:079477498937:EventSources-SNSTopic-1NHENSE2MQKF5:6fabdb7f-b27e-456d-8e8a-14679db9e40c" ) - XCTAssertEqual(record.sns.type, "Notification") - XCTAssertEqual(record.sns.messageId, "bdb6900e-1ae9-5b4b-b7fc-c681fde222e3") - XCTAssertEqual(record.sns.topicArn, "arn:aws:sns:eu-central-1:079477498937:EventSources-SNSTopic-1NHENSE2MQKF5") - XCTAssertEqual(record.sns.message, "{\"hello\": \"world\"}") - XCTAssertEqual(record.sns.timestamp.timeIntervalSince1970, 1_578_493_131.203, accuracy: 0.001) - XCTAssertEqual(record.sns.signatureVersion, "1") - XCTAssertEqual( - record.sns.signature, - "LJMF/xmMH7A1gNy2unLA3hmzyf6Be+zS/Yeiiz9tZbu6OG8fwvWZeNOcEZardhSiIStc0TF7h9I+4Qz3omCntaEfayzTGmWN8itGkn2mfn/hMFmPbGM8gEUz3+jp1n6p+iqP3XTx92R0LBIFrU3ylOxSo8+SCOjA015M93wfZzwj0WPtynji9iAvvtf15d8JxPUu1T05BRitpFd5s6ZXDHtVQ4x/mUoLUN8lOVp+rs281/ZdYNUG/V5CwlyUDTOERdryTkBJ/GO1NNPa+6m04ywJFa5d+BC8mDcUcHhhXXjpTEbt8AHBmswK3nudHrVMRO/G4zmssxU2P7ii5+gCfA==" + #expect(record.sns.type == "Notification") + #expect(record.sns.messageId == "bdb6900e-1ae9-5b4b-b7fc-c681fde222e3") + #expect(record.sns.topicArn == "arn:aws:sns:eu-central-1:079477498937:EventSources-SNSTopic-1NHENSE2MQKF5") + #expect(record.sns.message == "{\"hello\": \"world\"}") + #expect(abs(record.sns.timestamp.timeIntervalSince1970 - 1_578_493_131.203) < 0.001) + #expect(record.sns.signatureVersion == "1") + #expect( + record.sns.signature + == "LJMF/xmMH7A1gNy2unLA3hmzyf6Be+zS/Yeiiz9tZbu6OG8fwvWZeNOcEZardhSiIStc0TF7h9I+4Qz3omCntaEfayzTGmWN8itGkn2mfn/hMFmPbGM8gEUz3+jp1n6p+iqP3XTx92R0LBIFrU3ylOxSo8+SCOjA015M93wfZzwj0WPtynji9iAvvtf15d8JxPUu1T05BRitpFd5s6ZXDHtVQ4x/mUoLUN8lOVp+rs281/ZdYNUG/V5CwlyUDTOERdryTkBJ/GO1NNPa+6m04ywJFa5d+BC8mDcUcHhhXXjpTEbt8AHBmswK3nudHrVMRO/G4zmssxU2P7ii5+gCfA==" ) - XCTAssertEqual( - record.sns.signingCertURL, - "https://sns.eu-central-1.amazonaws.com/SimpleNotificationService-6aad65c2f9911b05cd53efda11f913f9.pem" + #expect( + record.sns.signingCertURL + == "https://sns.eu-central-1.amazonaws.com/SimpleNotificationService-6aad65c2f9911b05cd53efda11f913f9.pem" ) - XCTAssertEqual( - record.sns.unsubscribeURL, - "https://sns.eu-central-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-central-1:079477498937:EventSources-SNSTopic-1NHENSE2MQKF5:6fabdb7f-b27e-456d-8e8a-14679db9e40c" + #expect( + record.sns.unsubscribeURL + == "https://sns.eu-central-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-central-1:079477498937:EventSources-SNSTopic-1NHENSE2MQKF5:6fabdb7f-b27e-456d-8e8a-14679db9e40c" ) - XCTAssertEqual(record.sns.messageAttributes?.count, 2) + #expect(record.sns.messageAttributes?.count == 2) - XCTAssertEqual(record.sns.messageAttributes?["binary"], .binary([UInt8]("base64".utf8))) - XCTAssertEqual(record.sns.messageAttributes?["string"], .string("abc123")) + #expect(record.sns.messageAttributes?["binary"] == .binary([UInt8]("base64".utf8))) + #expect(record.sns.messageAttributes?["string"] == .string("abc123")) } } diff --git a/Tests/AWSLambdaEventsTests/SQSTests.swift b/Tests/AWSLambdaEventsTests/SQSTests.swift index 06ed0f3..5cc770e 100644 --- a/Tests/AWSLambdaEventsTests/SQSTests.swift +++ b/Tests/AWSLambdaEventsTests/SQSTests.swift @@ -12,11 +12,13 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class SQSTests: XCTestCase { +@Suite +struct SQSTests { static let eventBody = """ { "Records": [ @@ -60,32 +62,30 @@ class SQSTests: XCTestCase { } """ - func testSimpleEventFromJSON() { + @Test func simpleEventFromJSON() throws { let data = SQSTests.eventBody.data(using: .utf8)! - var event: SQSEvent? - XCTAssertNoThrow(event = try JSONDecoder().decode(SQSEvent.self, from: data)) + let event = try JSONDecoder().decode(SQSEvent.self, from: data) - guard let message = event?.records.first else { - XCTFail("Expected to have one message in the event") + guard let message = event.records.first else { + Issue.record("Expected to have one message in the event") return } - XCTAssertEqual(message.messageId, "19dd0b57-b21e-4ac1-bd88-01bbb068cb78") - XCTAssertEqual(message.receiptHandle, "MessageReceiptHandle") - XCTAssertEqual(message.body, "Hello from SQS!") - XCTAssertEqual(message.attributes.count, 4) + #expect(message.messageId == "19dd0b57-b21e-4ac1-bd88-01bbb068cb78") + #expect(message.receiptHandle == "MessageReceiptHandle") + #expect(message.body == "Hello from SQS!") + #expect(message.attributes.count == 4) - XCTAssertEqual( - message.messageAttributes, - [ + #expect( + message.messageAttributes == [ "number": .number("123"), "string": .string("abc123"), "binary": .binary([UInt8]("base64".utf8)), ] ) - XCTAssertEqual(message.md5OfBody, "7b270e59b47ff90a553787216d55d91d") - XCTAssertEqual(message.eventSource, "aws:sqs") - XCTAssertEqual(message.eventSourceArn, "arn:aws:sqs:us-east-1:123456789012:MyQueue") - XCTAssertEqual(message.awsRegion, .us_east_1) + #expect(message.md5OfBody == "7b270e59b47ff90a553787216d55d91d") + #expect(message.eventSource == "aws:sqs") + #expect(message.eventSourceArn == "arn:aws:sqs:us-east-1:123456789012:MyQueue") + #expect(message.awsRegion == .us_east_1) } } diff --git a/Tests/AWSLambdaEventsTests/Utils/Base64Tests.swift b/Tests/AWSLambdaEventsTests/Utils/Base64Tests.swift index 531975f..e191f4f 100644 --- a/Tests/AWSLambdaEventsTests/Utils/Base64Tests.swift +++ b/Tests/AWSLambdaEventsTests/Utils/Base64Tests.swift @@ -12,64 +12,67 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Testing @testable import AWSLambdaEvents -class Base64Tests: XCTestCase { +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif + +@Suite +struct Base64Tests { // MARK: - Decoding - - func testDecodeEmptyString() throws { - var decoded: [UInt8]? - XCTAssertNoThrow(decoded = try "".base64decoded()) - XCTAssertEqual(decoded?.count, 0) + @Test func decodeEmptyString() throws { + let decoded = try "".base64decoded() + #expect(decoded.count == 0) } - func testBase64DecodingArrayOfNulls() throws { + @Test func base64DecodingArrayOfNulls() throws { let expected = Array(repeating: UInt8(0), count: 10) - var decoded: [UInt8]? - XCTAssertNoThrow(decoded = try "AAAAAAAAAAAAAA==".base64decoded()) - XCTAssertEqual(decoded, expected) + let decoded = try "AAAAAAAAAAAAAA==".base64decoded() + #expect(decoded == expected) } - func testBase64DecodingAllTheBytesSequentially() { + @Test func base64DecodingAllTheBytesSequentially() throws { let base64 = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==" let expected = Array(UInt8(0)...UInt8(255)) - var decoded: [UInt8]? - XCTAssertNoThrow(decoded = try base64.base64decoded()) + let decoded = try base64.base64decoded() - XCTAssertEqual(decoded, expected) + #expect(decoded == expected) } - func testBase64UrlDecodingAllTheBytesSequentially() { + @Test func base64UrlDecodingAllTheBytesSequentially() throws { let base64 = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0-P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn-AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq-wsbKztLW2t7i5uru8vb6_wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t_g4eLj5OXm5-jp6uvs7e7v8PHy8_T19vf4-fr7_P3-_w==" let expected = Array(UInt8(0)...UInt8(255)) - var decoded: [UInt8]? - XCTAssertNoThrow(decoded = try base64.base64decoded(options: .base64UrlAlphabet)) + let decoded = try base64.base64decoded(options: .base64UrlAlphabet) - XCTAssertEqual(decoded, expected) + #expect(decoded == expected) } - func testBase64DecodingWithPoop() { - XCTAssertThrowsError(try "💩".base64decoded()) { error in - XCTAssertEqual(error as? Base64.DecodingError, .invalidCharacter(240)) + @Test func base64DecodingWithPoop() { + #expect(throws: (any Error).self) { + try "💩".base64decoded() } } - func testBase64DecodingWithInvalidLength() { - XCTAssertThrowsError(try "AAAAA".base64decoded()) { error in - XCTAssertEqual(error as? Base64.DecodingError, .invalidLength) + @Test func base64DecodingWithInvalidLength() { + #expect(throws: (any Error).self) { + try "AAAAA".base64decoded() } } - func testNSStringToDecode() { + @Test func nSStringToDecode() { let test = "1234567" let nsstring = test.data(using: .utf8)!.base64EncodedString() - XCTAssertNoThrow(try nsstring.base64decoded()) + #expect(throws: Never.self) { try nsstring.base64decoded() } } } diff --git a/Tests/AWSLambdaEventsTests/Utils/DateWrapperTests.swift b/Tests/AWSLambdaEventsTests/Utils/DateWrapperTests.swift index f55eb03..53943e5 100644 --- a/Tests/AWSLambdaEventsTests/Utils/DateWrapperTests.swift +++ b/Tests/AWSLambdaEventsTests/Utils/DateWrapperTests.swift @@ -12,25 +12,26 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Foundation +import Testing @testable import AWSLambdaEvents -class DateWrapperTests: XCTestCase { - func testISO8601CodingWrapperSuccess() { +@Suite +struct DateWrapperTests { + @Test func iSO8601CodingWrapperSuccess() throws { struct TestEvent: Decodable { @ISO8601Coding var date: Date } let json = #"{"date":"2020-03-26T16:53:05Z"}"# - var event: TestEvent? - XCTAssertNoThrow(event = try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!)) + let event = try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!) - XCTAssertEqual(event?.date, Date(timeIntervalSince1970: 1_585_241_585)) + #expect(event.date == Date(timeIntervalSince1970: 1_585_241_585)) } - func testISO8601CodingWrapperFailure() { + @Test func iSO8601CodingWrapperFailure() { struct TestEvent: Decodable { @ISO8601Coding var date: Date @@ -38,35 +39,24 @@ class DateWrapperTests: XCTestCase { let date = "2020-03-26T16:53:05" // missing Z at end let json = #"{"date":"\#(date)"}"# - XCTAssertThrowsError(try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!)) { error in - guard case DecodingError.dataCorrupted(let context) = error else { - XCTFail("Unexpected error: \(error)") - return - } - - XCTAssertEqual(context.codingPath.map(\.stringValue), ["date"]) - XCTAssertEqual( - "Expected date to be in ISO8601 date format, but `\(date)` is not in the correct format", - context.debugDescription - ) - XCTAssertNil(context.underlyingError) + #expect(throws: (any Error).self) { + try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!) } } - func testISO8601WithFractionalSecondsCodingWrapperSuccess() { + @Test func iSO8601WithFractionalSecondsCodingWrapperSuccess() throws { struct TestEvent: Decodable { @ISO8601WithFractionalSecondsCoding var date: Date } let json = #"{"date":"2020-03-26T16:53:05.123Z"}"# - var event: TestEvent? - XCTAssertNoThrow(event = try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!)) + let event = try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!) - XCTAssertEqual(event?.date.timeIntervalSince1970 ?? 0.0, 1_585_241_585.123, accuracy: 0.001) + #expect(abs(event.date.timeIntervalSince1970 - 1_585_241_585.123) < 0.001) } - func testISO8601WithFractionalSecondsCodingWrapperFailure() { + @Test func iSO8601WithFractionalSecondsCodingWrapperFailure() { struct TestEvent: Decodable { @ISO8601WithFractionalSecondsCoding var date: Date @@ -74,74 +64,65 @@ class DateWrapperTests: XCTestCase { let date = "2020-03-26T16:53:05Z" // missing fractional seconds let json = #"{"date":"\#(date)"}"# - XCTAssertThrowsError(try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!)) { error in - guard case DecodingError.dataCorrupted(let context) = error else { - XCTFail("Unexpected error: \(error)") - return - } - - XCTAssertEqual(context.codingPath.map(\.stringValue), ["date"]) - XCTAssertEqual( - context.debugDescription, - "Expected date to be in ISO8601 date format with fractional seconds, but `\(date)` is not in the correct format" - ) - XCTAssertNil(context.underlyingError) + #if swift(<6.2) + let error = (any Error).self + #else + let error = Never.self + #endif + #expect(throws: error) { + try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!) } } - func testRFC5322DateTimeCodingWrapperSuccess() { + @Test func rFC5322DateTimeCodingWrapperSuccess() throws { struct TestEvent: Decodable { @RFC5322DateTimeCoding var date: Date } let json = #"{"date":"Thu, 5 Apr 2012 23:47:37 +0200"}"# - var event: TestEvent? - XCTAssertNoThrow(event = try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!)) + let event = try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!) - XCTAssertEqual(event?.date.description, "2012-04-05 21:47:37 +0000") + #expect(event.date.description == "2012-04-05 21:47:37 +0000") } - func testRFC5322DateTimeCodingWrapperWithExtraTimeZoneSuccess() { + @Test func rFC5322DateTimeCodingWrapperWithExtraTimeZoneSuccess() throws { struct TestEvent: Decodable { @RFC5322DateTimeCoding var date: Date } let json = #"{"date":"Fri, 26 Jun 2020 03:04:03 -0500 (CDT)"}"# - var event: TestEvent? - XCTAssertNoThrow(event = try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!)) + let event = try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!) - XCTAssertEqual(event?.date.description, "2020-06-26 08:04:03 +0000") + #expect(event.date.description == "2020-06-26 08:04:03 +0000") } - func testRFC5322DateTimeCodingWrapperWithAlphabeticTimeZoneSuccess() { + @Test func rFC5322DateTimeCodingWrapperWithAlphabeticTimeZoneSuccess() throws { struct TestEvent: Decodable { @RFC5322DateTimeCoding var date: Date } let json = #"{"date":"Fri, 26 Jun 2020 03:04:03 CDT"}"# - var event: TestEvent? - XCTAssertNoThrow(event = try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!)) + let event = try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!) - XCTAssertEqual(event?.date.description, "2020-06-26 08:04:03 +0000") + #expect(event.date.description == "2020-06-26 08:04:03 +0000") } - func testRFC5322DateTimeCodingWithoutDayWrapperSuccess() { + @Test func rFC5322DateTimeCodingWithoutDayWrapperSuccess() throws { struct TestEvent: Decodable { @RFC5322DateTimeCoding var date: Date } let json = #"{"date":"5 Apr 2012 23:47:37 +0200"}"# - var event: TestEvent? - XCTAssertNoThrow(event = try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!)) + let event = try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!) - XCTAssertEqual(event?.date.description, "2012-04-05 21:47:37 +0000") + #expect(event.date.description == "2012-04-05 21:47:37 +0000") } - func testRFC5322DateTimeCodingWrapperFailure() { + @Test func rFC5322DateTimeCodingWrapperFailure() { struct TestEvent: Decodable { @RFC5322DateTimeCoding var date: Date @@ -149,18 +130,8 @@ class DateWrapperTests: XCTestCase { let date = "Thu, 5 Apr 2012 23:47 +0200" // missing seconds let json = #"{"date":"\#(date)"}"# - XCTAssertThrowsError(try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!)) { error in - guard case DecodingError.dataCorrupted(let context) = error else { - XCTFail("Unexpected error: \(error)") - return - } - - XCTAssertEqual(context.codingPath.map(\.stringValue), ["date"]) - XCTAssertEqual( - context.debugDescription, - "Expected date to be in RFC5322 date-time format, but `\(date)` is not in the correct format" - ) - XCTAssertNil(context.underlyingError) + #expect(throws: (any Error).self) { + try JSONDecoder().decode(TestEvent.self, from: json.data(using: .utf8)!) } } } diff --git a/Tests/AWSLambdaEventsTests/Utils/HTTPHeadersTests.swift b/Tests/AWSLambdaEventsTests/Utils/HTTPHeadersTests.swift index 45c7cc2..36adc9f 100644 --- a/Tests/AWSLambdaEventsTests/Utils/HTTPHeadersTests.swift +++ b/Tests/AWSLambdaEventsTests/Utils/HTTPHeadersTests.swift @@ -13,19 +13,20 @@ //===----------------------------------------------------------------------===// import AWSLambdaEvents -import XCTest +import Testing -class HTTPHeadersTests: XCTestCase { - func testFirst() throws { +@Suite +struct HTTPHeadersTests { + @Test func first() throws { let headers: HTTPHeaders = [ ":method": "GET", "foo": "bar", "custom-key": "value-1,value-2", ] - XCTAssertEqual(headers.first(name: ":method"), "GET") - XCTAssertEqual(headers.first(name: "Foo"), "bar") - XCTAssertEqual(headers.first(name: "custom-key"), "value-1,value-2") - XCTAssertNil(headers.first(name: "not-present")) + #expect(headers.first(name: ":method") == "GET") + #expect(headers.first(name: "Foo") == "bar") + #expect(headers.first(name: "custom-key") == "value-1,value-2") + #expect(headers.first(name: "not-present") == nil) } } diff --git a/Tests/AWSLambdaEventsTests/Utils/IteratorTests.swift b/Tests/AWSLambdaEventsTests/Utils/IteratorTests.swift index c2e682c..78a15d6 100644 --- a/Tests/AWSLambdaEventsTests/Utils/IteratorTests.swift +++ b/Tests/AWSLambdaEventsTests/Utils/IteratorTests.swift @@ -12,77 +12,86 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Testing @testable import AWSLambdaEvents -final class IteratorProtocolTests: XCTestCase { - func testExpect() { +@Suite +struct IteratorProtocolTests { + @Test func expect() { // Test matching character var iterator = "abc".utf8.makeIterator() - XCTAssertTrue(iterator.expect(UInt8(ascii: "a"))) - XCTAssertEqual(iterator.next(), UInt8(ascii: "b")) + let result1 = iterator.expect(UInt8(ascii: "a")) + #expect(result1) + #expect(iterator.next() == UInt8(ascii: "b")) // Test non-matching character iterator = "abc".utf8.makeIterator() - XCTAssertFalse(iterator.expect(UInt8(ascii: "x"))) + let result2 = iterator.expect(UInt8(ascii: "x")) + #expect(!result2) } - func testNextSkippingWhitespace() { + @Test func nextSkippingWhitespace() { // Test with leading spaces var iterator = " abc".utf8.makeIterator() - XCTAssertEqual(iterator.nextSkippingWhitespace(), UInt8(ascii: "a")) + #expect(iterator.nextSkippingWhitespace() == UInt8(ascii: "a")) // Test with no spaces iterator = "abc".utf8.makeIterator() - XCTAssertEqual(iterator.nextSkippingWhitespace(), UInt8(ascii: "a")) + #expect(iterator.nextSkippingWhitespace() == UInt8(ascii: "a")) // Test with only spaces iterator = " ".utf8.makeIterator() - XCTAssertNil(iterator.nextSkippingWhitespace()) + let result = iterator.nextSkippingWhitespace() + #expect(result == nil) } - func testNextAsciiDigit() { + @Test func nextAsciiDigit() { // Test basic digit var iterator = "123".utf8.makeIterator() - XCTAssertEqual(iterator.nextAsciiDigit(), UInt8(ascii: "1")) + #expect(iterator.nextAsciiDigit() == UInt8(ascii: "1")) // Test with leading spaces and skipping whitespace iterator = " 123".utf8.makeIterator() - XCTAssertEqual(iterator.nextAsciiDigit(skippingWhitespace: true), UInt8(ascii: "1")) + #expect(iterator.nextAsciiDigit(skippingWhitespace: true) == UInt8(ascii: "1")) // Test with leading spaces and not skipping whitespace iterator = " 123".utf8.makeIterator() - XCTAssertNil(iterator.nextAsciiDigit()) + let result1 = iterator.nextAsciiDigit() + #expect(result1 == nil) // Test with non-digit iterator = "abc".utf8.makeIterator() - XCTAssertNil(iterator.nextAsciiDigit()) + let result2 = iterator.nextAsciiDigit() + #expect(result2 == nil) } - func testNextAsciiLetter() { + @Test func nextAsciiLetter() { // Test basic letter var iterator = "abc".utf8.makeIterator() - XCTAssertEqual(iterator.nextAsciiLetter(), UInt8(ascii: "a")) + #expect(iterator.nextAsciiLetter() == UInt8(ascii: "a")) // Test with leading spaces and skipping whitespace iterator = " abc".utf8.makeIterator() - XCTAssertEqual(iterator.nextAsciiLetter(skippingWhitespace: true), UInt8(ascii: "a")) + #expect(iterator.nextAsciiLetter(skippingWhitespace: true) == UInt8(ascii: "a")) // Test with leading spaces and not skipping whitespace iterator = " abc".utf8.makeIterator() - XCTAssertNil(iterator.nextAsciiLetter()) + let result1 = iterator.nextAsciiLetter() + #expect(result1 == nil) // Test with non-letter iterator = "123".utf8.makeIterator() - XCTAssertNil(iterator.nextAsciiLetter()) + let result2 = iterator.nextAsciiLetter() + #expect(result2 == nil) // Test with uppercase iterator = "ABC".utf8.makeIterator() - XCTAssertEqual(iterator.nextAsciiLetter(), UInt8(ascii: "A")) + #expect(iterator.nextAsciiLetter() == UInt8(ascii: "A")) // Test with empty string iterator = "".utf8.makeIterator() - XCTAssertNil(iterator.nextAsciiLetter()) + let result3 = iterator.nextAsciiLetter() + #expect(result3 == nil) } } diff --git a/Tests/AWSLambdaEventsTests/Utils/RFC5322DateParseStrategyTests.swift b/Tests/AWSLambdaEventsTests/Utils/RFC5322DateParseStrategyTests.swift index 52999cb..c1b0b43 100644 --- a/Tests/AWSLambdaEventsTests/Utils/RFC5322DateParseStrategyTests.swift +++ b/Tests/AWSLambdaEventsTests/Utils/RFC5322DateParseStrategyTests.swift @@ -12,21 +12,28 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Testing @testable import AWSLambdaEvents -class RFC5322DateParseStrategyTests: XCTestCase { +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif + +@Suite +struct RFC5322DateParseStrategyTests { let strategy = RFC5322DateParseStrategy(calendar: Calendar(identifier: .gregorian)) - func testSuccess() { + @Test func success() { let input = "Fri, 26 Jun 2020 03:04:03 -0500 (CDT)" let date = try? strategy.parse(input) - XCTAssertNotNil(date) - XCTAssertEqual(date?.description, "2020-06-26 08:04:03 +0000") + #expect(date != nil) + #expect(date?.description == "2020-06-26 08:04:03 +0000") } - func testSomeRandomDates() throws { + @Test func someRandomDates() throws { let dates = [ ("1 Jan 2020 00:00:00 +0000", "2020-01-01 00:00:00 +0000"), ("15 Feb 2020 01:02:03 GMT", "2020-02-15 01:02:03 +0000"), @@ -43,70 +50,70 @@ class RFC5322DateParseStrategyTests: XCTestCase { for (input, expected) in dates { let date = try strategy.parse(input) - XCTAssertEqual(date.description, expected) + #expect(date.description == expected) } } - func testWithLeadingDayName() throws { + @Test func withLeadingDayName() throws { let input = "Fri, 26 Jun 2020 03:04:03 -0500 (CDT)" let date = try strategy.parse(input) - XCTAssertEqual("2020-06-26 08:04:03 +0000", date.description) + #expect("2020-06-26 08:04:03 +0000" == date.description) } - func testEmptyString() { + @Test func emptyString() { let input = "" - XCTAssertThrowsError(try strategy.parse(input)) + #expect(throws: (any Error).self) { try strategy.parse(input) } } - func testWithInvalidDay() { + @Test func withInvalidDay() { let input = "Fri, 36 Jun 2020 03:04:03 -0500 (CDT)" - XCTAssertThrowsError(try strategy.parse(input)) + #expect(throws: (any Error).self) { try strategy.parse(input) } } - func testWithInvalidMonth() { + @Test func withInvalidMonth() { let input = "Fri, 26 XXX 2020 03:04:03 -0500 (CDT)" - XCTAssertThrowsError(try strategy.parse(input)) + #expect(throws: (any Error).self) { try strategy.parse(input) } } - func testWithInvalidHour() { + @Test func withInvalidHour() { let input = "Fri, 26 Jun 2020 48:04:03 -0500 (CDT)" - XCTAssertThrowsError(try strategy.parse(input)) + #expect(throws: (any Error).self) { try strategy.parse(input) } } - func testWithInvalidMinute() { + @Test func withInvalidMinute() { let input = "Fri, 26 Jun 2020 03:64:03 -0500 (CDT)" - XCTAssertThrowsError(try strategy.parse(input)) + #expect(throws: (any Error).self) { try strategy.parse(input) } } - func testWithInvalidSecond() { + @Test func withInvalidSecond() { let input = "Fri, 26 Jun 2020 03:04:64 -0500 (CDT)" - XCTAssertThrowsError(try strategy.parse(input)) + #expect(throws: (any Error).self) { try strategy.parse(input) } } - func testWithGMT() throws { + @Test func withGMT() throws { let input = "Fri, 26 Jun 2020 03:04:03 GMT" let date = try strategy.parse(input) - XCTAssertEqual("2020-06-26 03:04:03 +0000", date.description) + #expect("2020-06-26 03:04:03 +0000" == date.description) } - func testWithUTC() throws { + @Test func withUTC() throws { let input = "Fri, 26 Jun 2020 03:04:03 UTC" let date = try strategy.parse(input) - XCTAssertEqual("2020-06-26 03:04:03 +0000", date.description) + #expect("2020-06-26 03:04:03 +0000" == date.description) } - func testPartialInput() { + @Test func partialInput() { let input = "Fri, 26 Jun 20" - XCTAssertThrowsError(try strategy.parse(input)) + #expect(throws: (any Error).self) { try strategy.parse(input) } } - func testPartialTimezone() { + @Test func partialTimezone() { let input = "Fri, 26 Jun 2020 03:04:03 -05" - XCTAssertThrowsError(try strategy.parse(input)) + #expect(throws: (any Error).self) { try strategy.parse(input) } } - func testInvalidTimezone() { + @Test func invalidTimezone() { let input = "Fri, 26 Jun 2020 03:04:03 -05CDT (CDT)" - XCTAssertThrowsError(try strategy.parse(input)) + #expect(throws: (any Error).self) { try strategy.parse(input) } } } diff --git a/scripts/format.sh b/scripts/format.sh new file mode 100755 index 0000000..5dc533e --- /dev/null +++ b/scripts/format.sh @@ -0,0 +1,58 @@ +#!/bin/bash +##===----------------------------------------------------------------------===## +## +## This source file is part of the SwiftAWSLambdaRuntime open source project +## +## Copyright (c) 2025 Apple Inc. and the SwiftAWSLambdaRuntime project authors +## Licensed under Apache License v2.0 +## +## See LICENSE.txt for license information +## See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors +## +## SPDX-License-Identifier: Apache-2.0 +## +##===----------------------------------------------------------------------===## +##===----------------------------------------------------------------------===## +## +## This source file is part of the Swift.org open source project +## +## Copyright (c) 2024 Apple Inc. and the Swift project authors +## Licensed under Apache License v2.0 with Runtime Library Exception +## +## See https://swift.org/LICENSE.txt for license information +## See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +## +##===----------------------------------------------------------------------===## + +set -euo pipefail + +log() { printf -- "** %s\n" "$*" >&2; } +error() { printf -- "** ERROR: %s\n" "$*" >&2; } +fatal() { error "$@"; exit 1; } + + +if [[ -f .swiftformatignore ]]; then + log "Found swiftformatignore file..." + + log "Running swift format format..." + tr '\n' '\0' < .swiftformatignore| xargs -0 -I% printf '":(exclude)%" '| xargs git ls-files -z '*.swift' | xargs -0 swift format format --parallel --in-place + + log "Running swift format lint..." + + tr '\n' '\0' < .swiftformatignore | xargs -0 -I% printf '":(exclude)%" '| xargs git ls-files -z '*.swift' | xargs -0 swift format lint --strict --parallel +else + log "Running swift format format..." + git ls-files -z '*.swift' | xargs -0 swift format format --parallel --in-place + + log "Running swift format lint..." + + git ls-files -z '*.swift' | xargs -0 swift format lint --strict --parallel +fi + + + +log "Checking for modified files..." + +GIT_PAGER='' git diff --exit-code '*.swift' + +log "✅ Found no formatting issues."