From 646305d4038aa362b9ef63508439a9f198652224 Mon Sep 17 00:00:00 2001 From: Econa77 Date: Sun, 14 Aug 2022 03:06:33 +0900 Subject: [PATCH 1/5] Rerunning tests that were not run in SPM --- APIKit.xcodeproj/project.pbxproj | 26 ++++++++++++------- Package.swift | 5 ++-- .../MultipartFormDataParametersTests.swift | 12 +++++---- Tests/APIKitTests/{ => Resources}/test.json | 0 4 files changed, 27 insertions(+), 16 deletions(-) rename Tests/APIKitTests/{ => Resources}/test.json (100%) diff --git a/APIKit.xcodeproj/project.pbxproj b/APIKit.xcodeproj/project.pbxproj index 8fc0f748..16ded583 100644 --- a/APIKit.xcodeproj/project.pbxproj +++ b/APIKit.xcodeproj/project.pbxproj @@ -21,7 +21,6 @@ 7F698E5A1D9D680C00F1561D /* URLSessionAdapterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F698E481D9D680C00F1561D /* URLSessionAdapterTests.swift */; }; 7F698E5B1D9D680C00F1561D /* SessionCallbackQueueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F698E491D9D680C00F1561D /* SessionCallbackQueueTests.swift */; }; 7F698E5C1D9D680C00F1561D /* SessionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F698E4A1D9D680C00F1561D /* SessionTests.swift */; }; - 7F698E5D1D9D680C00F1561D /* test.json in Resources */ = {isa = PBXBuildFile; fileRef = 7F698E4B1D9D680C00F1561D /* test.json */; }; 7F698E5E1D9D680C00F1561D /* TestRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F698E4D1D9D680C00F1561D /* TestRequest.swift */; }; 7F698E5F1D9D680C00F1561D /* TestSessionAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F698E4E1D9D680C00F1561D /* TestSessionAdapter.swift */; }; 7F698E601D9D680C00F1561D /* TestSessionTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F698E4F1D9D680C00F1561D /* TestSessionTask.swift */; }; @@ -48,6 +47,7 @@ 7F7048F11D9D8A12003C99F6 /* SessionTaskError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F7048EE1D9D8A12003C99F6 /* SessionTaskError.swift */; }; 7F7048F31D9D8A1F003C99F6 /* URLEncodedSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F7048F21D9D8A1F003C99F6 /* URLEncodedSerialization.swift */; }; 7FA1690D1D9D8C80006C982B /* HTTPStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FA1690C1D9D8C80006C982B /* HTTPStub.swift */; }; + C5FF1DC128A80FFD0059573D /* test.json in Resources */ = {isa = PBXBuildFile; fileRef = C5FF1DC028A80FFD0059573D /* test.json */; }; ECA831481DE4DDBF004EB1B5 /* ProtobufDataParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA831471DE4DDBF004EB1B5 /* ProtobufDataParser.swift */; }; ECA8314A1DE4DEBE004EB1B5 /* ProtobufDataParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA831491DE4DEBE004EB1B5 /* ProtobufDataParserTests.swift */; }; ECA8314C1DE4E677004EB1B5 /* ProtobufBodyParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECA8314B1DE4E677004EB1B5 /* ProtobufBodyParameters.swift */; }; @@ -100,7 +100,6 @@ 7F698E481D9D680C00F1561D /* URLSessionAdapterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLSessionAdapterTests.swift; sourceTree = ""; }; 7F698E491D9D680C00F1561D /* SessionCallbackQueueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SessionCallbackQueueTests.swift; sourceTree = ""; }; 7F698E4A1D9D680C00F1561D /* SessionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SessionTests.swift; sourceTree = ""; }; - 7F698E4B1D9D680C00F1561D /* test.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = test.json; sourceTree = ""; }; 7F698E4D1D9D680C00F1561D /* TestRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestRequest.swift; sourceTree = ""; }; 7F698E4E1D9D680C00F1561D /* TestSessionAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestSessionAdapter.swift; sourceTree = ""; }; 7F698E4F1D9D680C00F1561D /* TestSessionTask.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestSessionTask.swift; sourceTree = ""; }; @@ -129,6 +128,7 @@ 7F7048F21D9D8A1F003C99F6 /* URLEncodedSerialization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = URLEncodedSerialization.swift; path = Sources/APIKit/Serializations/URLEncodedSerialization.swift; sourceTree = SOURCE_ROOT; }; 7F8ECDFD1B6A799E00234E04 /* Demo.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Demo.playground; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; 7FA1690C1D9D8C80006C982B /* HTTPStub.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPStub.swift; sourceTree = ""; }; + C5FF1DC028A80FFD0059573D /* test.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = test.json; sourceTree = ""; }; ECA831471DE4DDBF004EB1B5 /* ProtobufDataParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ProtobufDataParser.swift; path = Sources/APIKit/DataParser/ProtobufDataParser.swift; sourceTree = SOURCE_ROOT; }; ECA831491DE4DEBE004EB1B5 /* ProtobufDataParserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProtobufDataParserTests.swift; sourceTree = ""; }; ECA8314B1DE4E677004EB1B5 /* ProtobufBodyParameters.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ProtobufBodyParameters.swift; path = Sources/APIKit/BodyParameters/ProtobufBodyParameters.swift; sourceTree = SOURCE_ROOT; }; @@ -201,8 +201,8 @@ ECA8314B1DE4E677004EB1B5 /* ProtobufBodyParameters.swift */, 7F7048D81D9D89FB003C99F6 /* AbstractInputStream.m */, ); - path = APIKit/BodyParameters; name = BodyParameters; + path = APIKit/BodyParameters; sourceTree = ""; }; 7F18BD161C9730ED003A31DF /* Serializations */ = { @@ -210,8 +210,8 @@ children = ( 7F7048F21D9D8A1F003C99F6 /* URLEncodedSerialization.swift */, ); - path = APIKit/Serializations; name = Serializations; + path = APIKit/Serializations; sourceTree = ""; }; 7F45FCD31A94D02C006863BB = { @@ -245,6 +245,7 @@ 7F698E401D9D680C00F1561D /* DataParserType */, 7F698E461D9D680C00F1561D /* SessionAdapterType */, 7F698E4C1D9D680C00F1561D /* TestComponents */, + C5FF1DBF28A80FFD0059573D /* Resources */, 7F698E611D9D681500F1561D /* Supporting Files */, ); path = APIKitTests; @@ -297,7 +298,6 @@ isa = PBXGroup; children = ( 7F698E441D9D680C00F1561D /* Info.plist */, - 7F698E4B1D9D680C00F1561D /* test.json */, ); name = "Supporting Files"; sourceTree = ""; @@ -336,8 +336,8 @@ 7F7048D41D9D89F2003C99F6 /* SessionAdapter.swift */, 7F7048D51D9D89F2003C99F6 /* URLSessionAdapter.swift */, ); - path = APIKit/SessionAdapter; name = SessionAdapter; + path = APIKit/SessionAdapter; sourceTree = ""; }; 7FA19A3D1C9CBF2A005D25AE /* Error */ = { @@ -347,8 +347,8 @@ 7F7048EC1D9D8A12003C99F6 /* RequestError.swift */, 7F7048ED1D9D8A12003C99F6 /* ResponseError.swift */, ); - path = APIKit/Error; name = Error; + path = APIKit/Error; sourceTree = ""; }; 7FA19A441C9CC9A2005D25AE /* DataParser */ = { @@ -360,8 +360,16 @@ ECA831471DE4DDBF004EB1B5 /* ProtobufDataParser.swift */, 7F7048E71D9D8A08003C99F6 /* StringDataParser.swift */, ); - path = APIKit/DataParser; name = DataParser; + path = APIKit/DataParser; + sourceTree = ""; + }; + C5FF1DBF28A80FFD0059573D /* Resources */ = { + isa = PBXGroup; + children = ( + C5FF1DC028A80FFD0059573D /* test.json */, + ); + path = Resources; sourceTree = ""; }; /* End PBXGroup section */ @@ -464,7 +472,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 7F698E5D1D9D680C00F1561D /* test.json in Resources */, + C5FF1DC128A80FFD0059573D /* test.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Package.swift b/Package.swift index a9bf0445..e55d20b6 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.0 +// swift-tools-version:5.3 import PackageDescription let package = Package( @@ -18,7 +18,8 @@ let package = Package( ), .testTarget( name: "APIKitTests", - dependencies: ["APIKit"] + dependencies: ["APIKit"], + resources: [.process("Resources")] ), ], swiftLanguageVersions: [.v5] diff --git a/Tests/APIKitTests/BodyParametersType/MultipartFormDataParametersTests.swift b/Tests/APIKitTests/BodyParametersType/MultipartFormDataParametersTests.swift index 4a0536dc..9cedcf04 100644 --- a/Tests/APIKitTests/BodyParametersType/MultipartFormDataParametersTests.swift +++ b/Tests/APIKitTests/BodyParametersType/MultipartFormDataParametersTests.swift @@ -71,11 +71,14 @@ class MultipartFormDataParametersTests: XCTestCase { // MARK: Values - // Skip test cases that uses files until SwiftPM supports resources. - #if !SWIFT_PACKAGE - func testFileValue() { - let fileURL = Bundle(for: type(of: self)).url(forResource: "test", withExtension: "json")! let part = try! MultipartFormDataBodyParameters.Part(fileURL: fileURL, name: "test") + func testFileValue() throws { + #if SWIFT_PACKAGE + let bundle = Bundle.module + #else + let bundle = Bundle(for: type(of: self)) + #endif + let fileURL = try XCTUnwrap(bundle.url(forResource: "test", withExtension: "json")) let parameters = MultipartFormDataBodyParameters(parts: [part]) do { @@ -103,7 +106,6 @@ class MultipartFormDataParametersTests: XCTestCase { XCTFail() } } - #endif func testStringValue() { let part = try! MultipartFormDataBodyParameters.Part(value: "abcdef", name: "foo") diff --git a/Tests/APIKitTests/test.json b/Tests/APIKitTests/Resources/test.json similarity index 100% rename from Tests/APIKitTests/test.json rename to Tests/APIKitTests/Resources/test.json From 872402da2035058d568ac8a2d9f169eab8b4e826 Mon Sep 17 00:00:00 2001 From: Econa77 Date: Sun, 14 Aug 2022 03:09:18 +0900 Subject: [PATCH 2/5] Improve tests that throw errors --- .../JSONBodyParametersTests.swift | 47 ++--- .../MultipartFormDataParametersTests.swift | 175 ++++++++---------- .../ProtobufBodyParametersTests.swift | 22 +-- .../URLEncodedSerializationTests.swift | 23 +-- Tests/APIKitTests/Combine/CombineTests.swift | 4 +- .../FormURLEncodedDataParserTests.swift | 21 +-- .../DataParserType/JSONDataParserTests.swift | 16 +- .../ProtobufDataParserTests.swift | 19 +- .../StringDataParserTests.swift | 15 +- Tests/APIKitTests/RequestTests.swift | 41 ++-- .../SessionCallbackQueueTests.swift | 10 +- Tests/APIKitTests/SessionTests.swift | 4 +- 12 files changed, 158 insertions(+), 239 deletions(-) diff --git a/Tests/APIKitTests/BodyParametersType/JSONBodyParametersTests.swift b/Tests/APIKitTests/BodyParametersType/JSONBodyParametersTests.swift index 512eb749..0bc9b535 100644 --- a/Tests/APIKitTests/BodyParametersType/JSONBodyParametersTests.swift +++ b/Tests/APIKitTests/BodyParametersType/JSONBodyParametersTests.swift @@ -3,58 +3,47 @@ import XCTest import APIKit class JSONBodyParametersTests: XCTestCase { - func testJSONSuccess() { + func testJSONSuccess() throws { let object = ["foo": 1, "bar": 2, "baz": 3] let parameters = JSONBodyParameters(JSONObject: object) XCTAssertEqual(parameters.contentType, "application/json") - do { - guard case .data(let data) = try parameters.buildEntity() else { - XCTFail() - return - } - - let dictionary = try JSONSerialization.jsonObject(with: data, options: []) - XCTAssertEqual((dictionary as? [String: Int])?["foo"], 1) - XCTAssertEqual((dictionary as? [String: Int])?["bar"], 2) - XCTAssertEqual((dictionary as? [String: Int])?["baz"], 3) - } catch { + guard case .data(let data) = try parameters.buildEntity() else { XCTFail() + return } + let dictionary = try JSONSerialization.jsonObject(with: data, options: []) + XCTAssertEqual((dictionary as? [String: Int])?["foo"], 1) + XCTAssertEqual((dictionary as? [String: Int])?["bar"], 2) + XCTAssertEqual((dictionary as? [String: Int])?["baz"], 3) } func testJSONFailure() { let object = NSObject() let parameters = JSONBodyParameters(JSONObject: object) - do { - try _ = parameters.buildEntity() - XCTFail() - } catch { + XCTAssertThrowsError(try parameters.buildEntity()) { error in let nserror = error as NSError XCTAssertEqual(nserror.domain, NSCocoaErrorDomain) XCTAssertEqual(nserror.code, 3840) } } - func testDictionaryLiteral() { + func testDictionaryLiteral() throws { let object = ["foo": 1, "bar": 2, "baz": 3] let parameters1: JSONBodyParameters = .init(JSONObject: object) let parameters2: JSONBodyParameters = ["foo": 1, "bar": 2, "baz": 3] - do { - guard case .data(let data1) = try parameters1.buildEntity(), - case .data(let data2) = try parameters2.buildEntity() else { - XCTFail() - return - } - let dictionary1 = try JSONSerialization.jsonObject(with: data1, options: []) - let dictionary2 = try JSONSerialization.jsonObject(with: data2, options: []) - XCTAssertEqual((dictionary1 as? [String: Int])?["foo"], (dictionary2 as? [String: Int])?["foo"]) - XCTAssertEqual((dictionary1 as? [String: Int])?["bar"], (dictionary2 as? [String: Int])?["bar"]) - XCTAssertEqual((dictionary1 as? [String: Int])?["baz"], (dictionary2 as? [String: Int])?["baz"]) - } catch { + + guard case .data(let data1) = try parameters1.buildEntity(), + case .data(let data2) = try parameters2.buildEntity() else { XCTFail() + return } + let dictionary1 = try JSONSerialization.jsonObject(with: data1, options: []) + let dictionary2 = try JSONSerialization.jsonObject(with: data2, options: []) + XCTAssertEqual((dictionary1 as? [String: Int])?["foo"], (dictionary2 as? [String: Int])?["foo"]) + XCTAssertEqual((dictionary1 as? [String: Int])?["bar"], (dictionary2 as? [String: Int])?["bar"]) + XCTAssertEqual((dictionary1 as? [String: Int])?["baz"], (dictionary2 as? [String: Int])?["baz"]) } } diff --git a/Tests/APIKitTests/BodyParametersType/MultipartFormDataParametersTests.swift b/Tests/APIKitTests/BodyParametersType/MultipartFormDataParametersTests.swift index 9cedcf04..faf68949 100644 --- a/Tests/APIKitTests/BodyParametersType/MultipartFormDataParametersTests.swift +++ b/Tests/APIKitTests/BodyParametersType/MultipartFormDataParametersTests.swift @@ -4,74 +4,65 @@ import XCTest class MultipartFormDataParametersTests: XCTestCase { // MARK: Entity - func testDataEntitySuccess() { - let value1 = "1".data(using: .utf8)! - let value2 = "2".data(using: .utf8)! + func testDataEntitySuccess() throws { + let value1 = try XCTUnwrap("1".data(using: .utf8)) + let value2 = try XCTUnwrap("2".data(using: .utf8)) let parameters = MultipartFormDataBodyParameters(parts: [ MultipartFormDataBodyParameters.Part(data: value1, name: "foo"), MultipartFormDataBodyParameters.Part(data: value2, name: "bar"), ]) - do { - guard case .data(let data) = try parameters.buildEntity() else { - XCTFail() - return - } - - let encodedData = String(data: data, encoding:.utf8)! - let returnCode = "\r\n" - - let pattern = "^multipart/form-data; boundary=([\\w.]+)$" - let regexp = try NSRegularExpression(pattern: pattern, options: []) - let range = NSRange(location: 0, length: parameters.contentType.count) - let match = regexp.matches(in: parameters.contentType, options: [], range: range) - XCTAssertTrue(match.count > 0) - - let boundary = (parameters.contentType as NSString).substring(with: match.first!.range(at: 1)) - XCTAssertEqual(parameters.contentType, "multipart/form-data; boundary=\(boundary)") - XCTAssertEqual(encodedData, "--\(boundary)\(returnCode)Content-Disposition: form-data; name=\"foo\"\(returnCode)\(returnCode)1\(returnCode)--\(boundary)\(returnCode)Content-Disposition: form-data; name=\"bar\"\(returnCode)\(returnCode)2\(returnCode)--\(boundary)--\(returnCode)") - } catch { + guard case .data(let data) = try parameters.buildEntity() else { XCTFail() + return } + let encodedData = try XCTUnwrap(String(data: data, encoding:.utf8)) + let returnCode = "\r\n" + + let pattern = "^multipart/form-data; boundary=([\\w.]+)$" + let regexp = try NSRegularExpression(pattern: pattern, options: []) + let range = NSRange(location: 0, length: parameters.contentType.count) + let match = regexp.matches(in: parameters.contentType, options: [], range: range) + XCTAssertTrue(match.count > 0) + + let firstRange = try XCTUnwrap(match.first?.range(at: 1)) + let boundary = (parameters.contentType as NSString).substring(with: firstRange) + XCTAssertEqual(parameters.contentType, "multipart/form-data; boundary=\(boundary)") + XCTAssertEqual(encodedData, "--\(boundary)\(returnCode)Content-Disposition: form-data; name=\"foo\"\(returnCode)\(returnCode)1\(returnCode)--\(boundary)\(returnCode)Content-Disposition: form-data; name=\"bar\"\(returnCode)\(returnCode)2\(returnCode)--\(boundary)--\(returnCode)") } - func testInputStreamEntitySuccess() { - let value1 = "1".data(using: .utf8)! - let value2 = "2".data(using: .utf8)! + func testInputStreamEntitySuccess() throws { + let value1 = try XCTUnwrap("1".data(using: .utf8)) + let value2 = try XCTUnwrap("2".data(using: .utf8)) let parameters = MultipartFormDataBodyParameters(parts: [ MultipartFormDataBodyParameters.Part(data: value1, name: "foo"), MultipartFormDataBodyParameters.Part(data: value2, name: "bar"), ], entityType: .inputStream) - do { - guard case .inputStream(let inputStream) = try parameters.buildEntity() else { - XCTFail() - return - } - - let data = try Data(inputStream: inputStream) - let encodedData = String(data: data, encoding:.utf8)! - let returnCode = "\r\n" - - let pattern = "^multipart/form-data; boundary=([\\w.]+)$" - let regexp = try NSRegularExpression(pattern: pattern, options: []) - let range = NSRange(location: 0, length: parameters.contentType.count) - let match = regexp.matches(in: parameters.contentType, options: [], range: range) - XCTAssertTrue(match.count > 0) - - let boundary = (parameters.contentType as NSString).substring(with: match.first!.range(at: 1)) - XCTAssertEqual(parameters.contentType, "multipart/form-data; boundary=\(boundary)") - XCTAssertEqual(encodedData, "--\(boundary)\(returnCode)Content-Disposition: form-data; name=\"foo\"\(returnCode)\(returnCode)1\(returnCode)--\(boundary)\(returnCode)Content-Disposition: form-data; name=\"bar\"\(returnCode)\(returnCode)2\(returnCode)--\(boundary)--\(returnCode)") - } catch { + guard case .inputStream(let inputStream) = try parameters.buildEntity() else { XCTFail() + return } + let data = try Data(inputStream: inputStream) + let encodedData = try XCTUnwrap(String(data: data, encoding:.utf8)) + let returnCode = "\r\n" + + let pattern = "^multipart/form-data; boundary=([\\w.]+)$" + let regexp = try NSRegularExpression(pattern: pattern, options: []) + let range = NSRange(location: 0, length: parameters.contentType.count) + let match = regexp.matches(in: parameters.contentType, options: [], range: range) + XCTAssertTrue(match.count > 0) + + let firstRange = try XCTUnwrap(match.first?.range(at: 1)) + let boundary = (parameters.contentType as NSString).substring(with: firstRange) + XCTAssertEqual(parameters.contentType, "multipart/form-data; boundary=\(boundary)") + XCTAssertEqual(encodedData, "--\(boundary)\(returnCode)Content-Disposition: form-data; name=\"foo\"\(returnCode)\(returnCode)1\(returnCode)--\(boundary)\(returnCode)Content-Disposition: form-data; name=\"bar\"\(returnCode)\(returnCode)2\(returnCode)--\(boundary)--\(returnCode)") } // MARK: Values - let part = try! MultipartFormDataBodyParameters.Part(fileURL: fileURL, name: "test") func testFileValue() throws { #if SWIFT_PACKAGE let bundle = Bundle.module @@ -79,82 +70,64 @@ class MultipartFormDataParametersTests: XCTestCase { let bundle = Bundle(for: type(of: self)) #endif let fileURL = try XCTUnwrap(bundle.url(forResource: "test", withExtension: "json")) + let part = try MultipartFormDataBodyParameters.Part(fileURL: fileURL, name: "test") let parameters = MultipartFormDataBodyParameters(parts: [part]) - do { - guard case .data(let data) = try parameters.buildEntity() else { - XCTFail() - return - } - - let testData = try! Data(contentsOf: fileURL) - let testString = String(data: testData, encoding: .utf8)! - - let encodedData = String(data: data, encoding:.utf8)! - let returnCode = "\r\n" - - let pattern = "^multipart/form-data; boundary=([\\w.]+)$" - let regexp = try NSRegularExpression(pattern: pattern, options: []) - let range = NSRange(location: 0, length: parameters.contentType.count) - let match = regexp.matches(in: parameters.contentType, options: [], range: range) - XCTAssertTrue(match.count > 0) - - let boundary = (parameters.contentType as NSString).substring(with: match.first!.range(at: 1)) - XCTAssertEqual(parameters.contentType, "multipart/form-data; boundary=\(boundary)") - XCTAssertEqual(encodedData, "--\(boundary)\(returnCode)Content-Disposition: form-data; name=\"test\"; filename=\"test.json\"\r\nContent-Type: application/json\(returnCode)\(returnCode)\(testString)\(returnCode)--\(boundary)--\(returnCode)") - } catch { + guard case .data(let data) = try parameters.buildEntity() else { XCTFail() + return } + let testData = try Data(contentsOf: fileURL) + let testString = try XCTUnwrap(String(data: testData, encoding: .utf8)) + + let encodedData = try XCTUnwrap(String(data: data, encoding:.utf8)) + let returnCode = "\r\n" + + let pattern = "^multipart/form-data; boundary=([\\w.]+)$" + let regexp = try NSRegularExpression(pattern: pattern, options: []) + let range = NSRange(location: 0, length: parameters.contentType.count) + let match = regexp.matches(in: parameters.contentType, options: [], range: range) + XCTAssertTrue(match.count > 0) + + let firstRange = try XCTUnwrap(match.first?.range(at: 1)) + let boundary = (parameters.contentType as NSString).substring(with: firstRange) + XCTAssertEqual(parameters.contentType, "multipart/form-data; boundary=\(boundary)") + XCTAssertEqual(encodedData, "--\(boundary)\(returnCode)Content-Disposition: form-data; name=\"test\"; filename=\"test.json\"\r\nContent-Type: application/json\(returnCode)\(returnCode)\(testString)\(returnCode)--\(boundary)--\(returnCode)") } - func testStringValue() { - let part = try! MultipartFormDataBodyParameters.Part(value: "abcdef", name: "foo") + func testStringValue() throws { + let part = try MultipartFormDataBodyParameters.Part(value: "abcdef", name: "foo") let parameters = MultipartFormDataBodyParameters(parts: [part]) - do { - guard case .data(let data) = try parameters.buildEntity() else { - XCTFail() - return - } - - let string = String(data: data, encoding:.utf8)! - XCTAssertEqual(string, "--\(parameters.boundary)\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\nabcdef\r\n--\(parameters.boundary)--\r\n") - } catch { + guard case .data(let data) = try parameters.buildEntity() else { XCTFail() + return } + let string = String(data: data, encoding:.utf8) + XCTAssertEqual(string, "--\(parameters.boundary)\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\nabcdef\r\n--\(parameters.boundary)--\r\n") } - func testIntValue() { - let part = try! MultipartFormDataBodyParameters.Part(value: 123, name: "foo") + func testIntValue() throws { + let part = try MultipartFormDataBodyParameters.Part(value: 123, name: "foo") let parameters = MultipartFormDataBodyParameters(parts: [part]) - do { - guard case .data(let data) = try parameters.buildEntity() else { - XCTFail() - return - } - - let string = String(data: data, encoding:.utf8)! - XCTAssertEqual(string, "--\(parameters.boundary)\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\n123\r\n--\(parameters.boundary)--\r\n") - } catch { + guard case .data(let data) = try parameters.buildEntity() else { XCTFail() + return } + let string = String(data: data, encoding:.utf8) + XCTAssertEqual(string, "--\(parameters.boundary)\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\n123\r\n--\(parameters.boundary)--\r\n") } - func testDoubleValue() { - let part = try! MultipartFormDataBodyParameters.Part(value: 3.14, name: "foo") + func testDoubleValue() throws { + let part = try MultipartFormDataBodyParameters.Part(value: 3.14, name: "foo") let parameters = MultipartFormDataBodyParameters(parts: [part]) - do { - guard case .data(let data) = try parameters.buildEntity() else { - XCTFail() - return - } - - let string = String(data: data, encoding:.utf8)! - XCTAssertEqual(string, "--\(parameters.boundary)\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\n3.14\r\n--\(parameters.boundary)--\r\n") - } catch { + guard case .data(let data) = try parameters.buildEntity() else { XCTFail() + return } + let string = String(data: data, encoding:.utf8) + XCTAssertEqual(string, "--\(parameters.boundary)\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\n3.14\r\n--\(parameters.boundary)--\r\n") } } diff --git a/Tests/APIKitTests/BodyParametersType/ProtobufBodyParametersTests.swift b/Tests/APIKitTests/BodyParametersType/ProtobufBodyParametersTests.swift index e58102d3..3f5da8b4 100644 --- a/Tests/APIKitTests/BodyParametersType/ProtobufBodyParametersTests.swift +++ b/Tests/APIKitTests/BodyParametersType/ProtobufBodyParametersTests.swift @@ -3,26 +3,18 @@ import XCTest import APIKit class ProtobufBodyParametersTests: XCTestCase { - func testProtobufSuccess() { - // Temporarily gated due to https://openradar.appspot.com/49262697 - if #available(macOS 10.11, *) { + func testProtobufSuccess() throws { let object = NSKeyedArchiver.archivedData(withRootObject: ["foo": 1, "bar": 2, "baz": 3]) let parameters = ProtobufBodyParameters(protobufObject: object) XCTAssertEqual(parameters.contentType, "application/protobuf") - do { - guard case .data(let data) = try parameters.buildEntity() else { - XCTFail() - return - } - - let dictionary = NSKeyedUnarchiver.unarchiveObject(with: data) as? [String: Int] - XCTAssertEqual(dictionary?["foo"], 1) - XCTAssertEqual(dictionary?["bar"], 2) - XCTAssertEqual(dictionary?["baz"], 3) - } catch { + guard case .data(let data) = try parameters.buildEntity() else { XCTFail() + return } - } + let dictionary = NSKeyedUnarchiver.unarchiveObject(with: data) as? [String: Int] + XCTAssertEqual(dictionary?["foo"], 1) + XCTAssertEqual(dictionary?["bar"], 2) + XCTAssertEqual(dictionary?["baz"], 3) } } diff --git a/Tests/APIKitTests/BodyParametersType/URLEncodedSerializationTests.swift b/Tests/APIKitTests/BodyParametersType/URLEncodedSerializationTests.swift index 89702e4d..64d33cf4 100644 --- a/Tests/APIKitTests/BodyParametersType/URLEncodedSerializationTests.swift +++ b/Tests/APIKitTests/BodyParametersType/URLEncodedSerializationTests.swift @@ -4,21 +4,18 @@ import APIKit class URLEncodedSerializationTests: XCTestCase { // MARK: NSData -> Any - func testObjectFromData() { - let data = "key1=value1&key2=value2".data(using: .utf8)! + func testObjectFromData() throws { + let data = try XCTUnwrap("key1=value1&key2=value2".data(using: .utf8)) let object = try? URLEncodedSerialization.object(from: data, encoding: .utf8) XCTAssertEqual(object?["key1"], "value1") XCTAssertEqual(object?["key2"], "value2") } - func testInvalidFormatString() { + func testInvalidFormatString() throws { let string = "key==value&" - do { - let data = string.data(using: .utf8)! - try _ = URLEncodedSerialization.object(from: data, encoding: .utf8) - XCTFail() - } catch { + let data = try XCTUnwrap(string.data(using: .utf8)) + XCTAssertThrowsError(try URLEncodedSerialization.object(from: data, encoding: .utf8)) { error in guard let error = error as? URLEncodedSerialization.Error, case .invalidFormatString(let invalidString) = error else { XCTFail() @@ -33,10 +30,7 @@ class URLEncodedSerializationTests: XCTestCase { var bytes = [UInt8]([0xed, 0xa0, 0x80]) // U+D800 (high surrogate) let data = Data(bytes: &bytes, count: bytes.count) - do { - try _ = URLEncodedSerialization.object(from: data, encoding: .utf8) - XCTFail() - } catch { + XCTAssertThrowsError(try URLEncodedSerialization.object(from: data, encoding: .utf8)) { error in guard let error = error as? URLEncodedSerialization.Error, case .cannotGetStringFromData(let invalidData, let encoding) = error else { XCTFail() @@ -59,10 +53,7 @@ class URLEncodedSerializationTests: XCTestCase { func testNonDictionaryObject() { let dictionaries = [["hey": "yo"]] as Any - do { - try _ = URLEncodedSerialization.data(from: dictionaries, encoding: .utf8) - XCTFail() - } catch { + XCTAssertThrowsError(try URLEncodedSerialization.data(from: dictionaries, encoding: .utf8)) { error in guard let error = error as? URLEncodedSerialization.Error, case .cannotCastObjectToDictionary(let object) = error else { XCTFail() diff --git a/Tests/APIKitTests/Combine/CombineTests.swift b/Tests/APIKitTests/Combine/CombineTests.swift index a253067b..32c548b9 100644 --- a/Tests/APIKitTests/Combine/CombineTests.swift +++ b/Tests/APIKitTests/Combine/CombineTests.swift @@ -23,9 +23,9 @@ final class CombineTests: XCTestCase { cancellables = [] } - func testSuccess() { + func testSuccess() throws { let dictionary = ["key": "value"] - adapter.data = try! JSONSerialization.data(withJSONObject: dictionary, options: []) + adapter.data = try XCTUnwrap(JSONSerialization.data(withJSONObject: dictionary, options: [])) let expectation = self.expectation(description: "wait for response") let request = TestRequest() diff --git a/Tests/APIKitTests/DataParserType/FormURLEncodedDataParserTests.swift b/Tests/APIKitTests/DataParserType/FormURLEncodedDataParserTests.swift index 8bf66a77..cb2f5357 100644 --- a/Tests/APIKitTests/DataParserType/FormURLEncodedDataParserTests.swift +++ b/Tests/APIKitTests/DataParserType/FormURLEncodedDataParserTests.swift @@ -8,20 +8,16 @@ class FormURLEncodedDataParserTests: XCTestCase { XCTAssertEqual(parser.contentType, "application/x-www-form-urlencoded") } - func testURLSuccess() { + func testURLSuccess() throws { let string = "foo=1&bar=2&baz=3" let data = string.data(using: .utf8, allowLossyConversion: false)! let parser = FormURLEncodedDataParser(encoding: .utf8) - do { - let object = try parser.parse(data: data) - let dictionary = object as? [String: String] - XCTAssertEqual(dictionary?["foo"], "1") - XCTAssertEqual(dictionary?["bar"], "2") - XCTAssertEqual(dictionary?["baz"], "3") - } catch { - XCTFail() - } + let object = try parser.parse(data: data) + let dictionary = object as? [String: String] + XCTAssertEqual(dictionary?["foo"], "1") + XCTAssertEqual(dictionary?["bar"], "2") + XCTAssertEqual(dictionary?["baz"], "3") } func testInvalidString() { @@ -29,10 +25,7 @@ class FormURLEncodedDataParserTests: XCTestCase { let data = Data(bytes: &bytes, count: bytes.count) let parser = FormURLEncodedDataParser(encoding: .utf8) - do { - try _ = parser.parse(data: data) - XCTFail() - } catch { + XCTAssertThrowsError(try parser.parse(data: data)) { error in guard let error = error as? FormURLEncodedDataParser.Error, case .cannotGetStringFromData(let invalidData) = error else { XCTFail() diff --git a/Tests/APIKitTests/DataParserType/JSONDataParserTests.swift b/Tests/APIKitTests/DataParserType/JSONDataParserTests.swift index e7faaca4..3cf81427 100644 --- a/Tests/APIKitTests/DataParserType/JSONDataParserTests.swift +++ b/Tests/APIKitTests/DataParserType/JSONDataParserTests.swift @@ -8,19 +8,15 @@ class JSONDataParserTests: XCTestCase { XCTAssertEqual(parser.contentType, "application/json") } - func testJSONSuccess() { + func testJSONSuccess() throws { let string = "{\"foo\": 1, \"bar\": 2, \"baz\": 3}" let data = string.data(using: .utf8, allowLossyConversion: false)! let parser = JSONDataParser(readingOptions: []) - do { - let object = try parser.parse(data: data) - let dictionary = object as? [String: Int] - XCTAssertEqual(dictionary?["foo"], 1) - XCTAssertEqual(dictionary?["bar"], 2) - XCTAssertEqual(dictionary?["baz"], 3) - } catch { - XCTFail() - } + let object = try parser.parse(data: data) + let dictionary = object as? [String: Int] + XCTAssertEqual(dictionary?["foo"], 1) + XCTAssertEqual(dictionary?["bar"], 2) + XCTAssertEqual(dictionary?["baz"], 3) } } diff --git a/Tests/APIKitTests/DataParserType/ProtobufDataParserTests.swift b/Tests/APIKitTests/DataParserType/ProtobufDataParserTests.swift index 968b31e0..6752bee9 100644 --- a/Tests/APIKitTests/DataParserType/ProtobufDataParserTests.swift +++ b/Tests/APIKitTests/DataParserType/ProtobufDataParserTests.swift @@ -8,21 +8,14 @@ class ProtobufDataParserTests: XCTestCase { XCTAssertEqual(parser.contentType, "application/protobuf") } - func testProtobufSuccess() { - // Temporarily gated due to https://openradar.appspot.com/49262697 - if #available(macOS 10.11, *) { + func testProtobufSuccess() throws { let data = NSKeyedArchiver.archivedData(withRootObject: ["foo": 1, "bar": 2, "baz": 3]) let parser = ProtobufDataParser() - do { - let object = try parser.parse(data: data) as! Data - let dictionary = NSKeyedUnarchiver.unarchiveObject(with: object) as? [String: Int] - XCTAssertEqual(dictionary?["foo"], 1) - XCTAssertEqual(dictionary?["bar"], 2) - XCTAssertEqual(dictionary?["baz"], 3) - } catch { - XCTFail() - } - } + let object = try XCTUnwrap(try parser.parse(data: data) as? Data) + let dictionary = NSKeyedUnarchiver.unarchiveObject(with: object) as? [String: Int] + XCTAssertEqual(dictionary?["foo"], 1) + XCTAssertEqual(dictionary?["bar"], 2) + XCTAssertEqual(dictionary?["baz"], 3) } } diff --git a/Tests/APIKitTests/DataParserType/StringDataParserTests.swift b/Tests/APIKitTests/DataParserType/StringDataParserTests.swift index 0dc0255a..d932501a 100644 --- a/Tests/APIKitTests/DataParserType/StringDataParserTests.swift +++ b/Tests/APIKitTests/DataParserType/StringDataParserTests.swift @@ -8,17 +8,13 @@ class StringDataParserTests: XCTestCase { XCTAssertNil(parser.contentType) } - func testParseData() { + func testParseData() throws { let string = "abcdef" let data = string.data(using: .utf8, allowLossyConversion: false)! let parser = StringDataParser(encoding: .utf8) - do { - let object = try parser.parse(data: data) - XCTAssertEqual(object as? String, string) - } catch { - XCTFail() - } + let object = try parser.parse(data: data) + XCTAssertEqual(object as? String, string) } func testInvalidString() { @@ -26,10 +22,7 @@ class StringDataParserTests: XCTestCase { let data = Data(bytes: &bytes, count: bytes.count) let parser = StringDataParser(encoding: .utf8) - do { - try _ = parser.parse(data: data) - XCTFail() - } catch { + XCTAssertThrowsError(try parser.parse(data: data)) { error in guard let error = error as? StringDataParser.Error, case .invalidData(let invalidData) = error else { XCTFail() diff --git a/Tests/APIKitTests/RequestTests.swift b/Tests/APIKitTests/RequestTests.swift index bd10942b..88bfa72c 100644 --- a/Tests/APIKitTests/RequestTests.swift +++ b/Tests/APIKitTests/RequestTests.swift @@ -2,33 +2,33 @@ import XCTest import APIKit class RequestTests: XCTestCase { - func testJapanesesQueryParameters() { + func testJapanesesQueryParameters() throws { let request = TestRequest(parameters: ["q": "こんにちは"]) - let urlRequest = try? request.buildURLRequest() - XCTAssertEqual(urlRequest?.url?.query, "q=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF") + let urlRequest = try request.buildURLRequest() + XCTAssertEqual(urlRequest.url?.query, "q=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF") } - func testSymbolQueryParameters() { + func testSymbolQueryParameters() throws { let request = TestRequest(parameters: ["q": "!\"#$%&'()0=~|`{}*+<>?/_"]) - let urlRequest = try? request.buildURLRequest() - XCTAssertEqual(urlRequest?.url?.query, "q=%21%22%23%24%25%26%27%28%290%3D~%7C%60%7B%7D%2A%2B%3C%3E?/_") + let urlRequest = try request.buildURLRequest() + XCTAssertEqual(urlRequest.url?.query, "q=%21%22%23%24%25%26%27%28%290%3D~%7C%60%7B%7D%2A%2B%3C%3E?/_") } - func testNullQueryParameters() { + func testNullQueryParameters() throws { let request = TestRequest(parameters: ["null": NSNull()]) - let urlRequest = try? request.buildURLRequest() - XCTAssertEqual(urlRequest?.url?.query, "null") + let urlRequest = try request.buildURLRequest() + XCTAssertEqual(urlRequest.url?.query, "null") } - func testheaderFields() { + func testheaderFields() throws { let request = TestRequest(headerFields: ["Foo": "f", "Accept": "a", "Content-Type": "c"]) - let urlReqeust = try? request.buildURLRequest() - XCTAssertEqual(urlReqeust?.value(forHTTPHeaderField: "Foo"), "f") - XCTAssertEqual(urlReqeust?.value(forHTTPHeaderField: "Accept"), "a") - XCTAssertEqual(urlReqeust?.value(forHTTPHeaderField: "Content-Type"), "c") + let urlReqeust = try request.buildURLRequest() + XCTAssertEqual(urlReqeust.value(forHTTPHeaderField: "Foo"), "f") + XCTAssertEqual(urlReqeust.value(forHTTPHeaderField: "Accept"), "a") + XCTAssertEqual(urlReqeust.value(forHTTPHeaderField: "Content-Type"), "c") } - func testPOSTJSONRequest() { + func testPOSTJSONRequest() throws { let parameters: [Any] = [ ["id": "1"], ["id": "2"], @@ -38,10 +38,9 @@ class RequestTests: XCTestCase { let request = TestRequest(method: .post, parameters: parameters) XCTAssert((request.parameters as? [Any])?.count == 3) - let urlRequest = try? request.buildURLRequest() - XCTAssertNotNil(urlRequest?.httpBody) + let urlRequest = try request.buildURLRequest() - let json = urlRequest?.httpBody.flatMap { try? JSONSerialization.jsonObject(with: $0, options: []) } as? [AnyObject] + let json = urlRequest.httpBody.flatMap { try? JSONSerialization.jsonObject(with: $0, options: []) } as? [AnyObject] XCTAssertEqual(json?.count, 3) XCTAssertEqual((json?[0] as? [String: String])?["id"], "1") XCTAssertEqual((json?[1] as? [String: String])?["id"], "2") @@ -409,12 +408,12 @@ class RequestTests: XCTestCase { ) } - func testInterceptURLRequest() { - let url = URL(string: "https://example.com/customize")! + func testInterceptURLRequest() throws { + let url = try XCTUnwrap(URL(string: "https://example.com/customize")) let request = TestRequest() { _ in return URLRequest(url: url) } - XCTAssertEqual((try? request.buildURLRequest())?.url, url) + XCTAssertEqual(try request.buildURLRequest().url, url) } } diff --git a/Tests/APIKitTests/SessionCallbackQueueTests.swift b/Tests/APIKitTests/SessionCallbackQueueTests.swift index 66f2f494..b9d961f9 100644 --- a/Tests/APIKitTests/SessionCallbackQueueTests.swift +++ b/Tests/APIKitTests/SessionCallbackQueueTests.swift @@ -6,11 +6,11 @@ class SessionCallbackQueueTests: XCTestCase { var adapter: TestSessionAdapter! var session: Session! - override func setUp() { - super.setUp() + override func setUpWithError() throws { + try super.setUpWithError() adapter = TestSessionAdapter() - adapter.data = try! JSONSerialization.data(withJSONObject: ["key": "value"], options: []) + adapter.data = try XCTUnwrap(JSONSerialization.data(withJSONObject: ["key": "value"], options: [])) session = Session(adapter: adapter, callbackQueue: .main) } @@ -33,7 +33,7 @@ class SessionCallbackQueueTests: XCTestCase { session.send(request, callbackQueue: .sessionQueue) { result in // This depends on implementation of TestSessionAdapter - XCTAssert(Thread.isMainThread) + XCTAssertTrue(Thread.isMainThread) expectation.fulfill() } @@ -60,7 +60,7 @@ class SessionCallbackQueueTests: XCTestCase { session.send(request, callbackQueue: .dispatchQueue(dispatchQueue)) { result in // There is no way to test current dispatch queue. - XCTAssert(!Thread.isMainThread) + XCTAssertFalse(Thread.isMainThread) expectation.fulfill() } diff --git a/Tests/APIKitTests/SessionTests.swift b/Tests/APIKitTests/SessionTests.swift index d65a235e..fa9e4fb9 100644 --- a/Tests/APIKitTests/SessionTests.swift +++ b/Tests/APIKitTests/SessionTests.swift @@ -13,9 +13,9 @@ class SessionTests: XCTestCase { session = Session(adapter: adapter) } - func testSuccess() { + func testSuccess() throws { let dictionary = ["key": "value"] - adapter.data = try! JSONSerialization.data(withJSONObject: dictionary, options: []) + adapter.data = try XCTUnwrap(JSONSerialization.data(withJSONObject: dictionary, options: [])) let expectation = self.expectation(description: "wait for response") let request = TestRequest() From cf72a213a60ac0dce0401dac4499aeb58fe51482 Mon Sep 17 00:00:00 2001 From: Econa77 Date: Sun, 14 Aug 2022 03:21:48 +0900 Subject: [PATCH 3/5] Drop support for swift 5.3 and below --- .github/workflows/ci.yml | 11 ++++------- .swift-version | 1 - 2 files changed, 4 insertions(+), 8 deletions(-) delete mode 100644 .swift-version diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 76f4852f..57a55945 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,12 +30,9 @@ jobs: - xcode: "Xcode_12.5.1" runsOn: macOS-11 name: "macOS 11, Xcode 12.5.1, Swift 5.4.2" - - xcode: "Xcode_11.7" + - xcode: "Xcode_12" runsOn: macOS-10.15 - name: "macOS 10.15, Xcode 11.7, Swift 5.2.4" - - xcode: "Xcode_10.3" - runsOn: macOS-10.15 - name: "macOS 10.15, Xcode 10.3, Swift 5.0.1" + name: "macOS 10.15, Xcode 12.0.1, Swift 5.3" steps: - uses: actions/checkout@v2 with: @@ -65,9 +62,9 @@ jobs: - xcode: "Xcode_12.5.1" runsOn: macOS-11 name: "macOS 11, Xcode 12.5.1, Swift 5.4.2" - - xcode: "Xcode_11.7" + - xcode: "Xcode_12" runsOn: macOS-10.15 - name: "macOS 10.15, Xcode 11.7, Swift 5.2.4" + name: "macOS 10.15, Xcode 12.0.1, Swift 5.3" steps: - uses: actions/checkout@v2 - name: ${{ matrix.name }} diff --git a/.swift-version b/.swift-version deleted file mode 100644 index 819e07a2..00000000 --- a/.swift-version +++ /dev/null @@ -1 +0,0 @@ -5.0 From 6235703b893ace8d45c14ba34058967aed30234b Mon Sep 17 00:00:00 2001 From: Econa77 Date: Sun, 14 Aug 2022 03:33:54 +0900 Subject: [PATCH 4/5] Change commands depending on execution environment --- .github/workflows/ci.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57a55945..6f8a1880 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,15 +59,16 @@ jobs: - xcode: "Xcode_13.4.1" runsOn: macOS-12 name: "macOS 12, Xcode 13.4.1, Swift 5.6.1" + action: swift test -c debug - xcode: "Xcode_12.5.1" runsOn: macOS-11 name: "macOS 11, Xcode 12.5.1, Swift 5.4.2" + action: swift test -c debug - xcode: "Xcode_12" runsOn: macOS-10.15 name: "macOS 10.15, Xcode 12.0.1, Swift 5.3" + action: swift build -c debug steps: - uses: actions/checkout@v2 - name: ${{ matrix.name }} - run: | - swift build - swift test + run: ${{ matrix.action }} From b4903640d3081d728926d0f071d45c99a017cc3e Mon Sep 17 00:00:00 2001 From: Econa77 Date: Sun, 14 Aug 2022 03:36:39 +0900 Subject: [PATCH 5/5] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e6b06ebb..45c1bed7 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Session.send(request) { result in ## Requirements -- Swift 5.0 or later +- Swift 5.3 or later - iOS 9.0 or later - Mac OS 10.10 or later - watchOS 2.0 or later @@ -40,6 +40,8 @@ If you use Swift 2.2 or 2.3, try [APIKit 2.0.5](https://github.com/ishkawa/APIKi If you use Swift 4.2 or before, try [APIKit 4.1.0](https://github.com/ishkawa/APIKit/tree/4.1.0). +If you use Swift 5.2 or before, try [APIKit 5.3.0](https://github.com/ishkawa/APIKit/tree/5.3.0). + ## Installation #### [Carthage](https://github.com/Carthage/Carthage)