Skip to content

Commit 03840ad

Browse files
authored
Merge pull request #381 from mattpolzin/update-ci-matrices
test swift 6. test more macos versions. fix tests for latest Foundation changes.
2 parents 4991b7e + 80119a3 commit 03840ad

File tree

13 files changed

+159
-16
lines changed

13 files changed

+159
-16
lines changed

.github/workflows/tests.yml

+10-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ jobs:
5757
- swift:5.9-jammy
5858
- swift:5.10-focal
5959
- swift:5.10-jammy
60+
- swift:6.0-focal
61+
- swift:6.0-jammy
62+
- swift:6.0-noble
6063
- swiftlang/swift:nightly-focal
6164
- swiftlang/swift:nightly-jammy
6265
container: ${{ matrix.image }}
@@ -66,7 +69,13 @@ jobs:
6669
- name: Run tests
6770
run: swift test
6871
osx:
69-
runs-on: macOS-12
72+
strategy:
73+
fail-fast: false
74+
matrix:
75+
os:
76+
- macos-14
77+
- macos-15
78+
runs-on: ${{ matrix.os }}
7079
steps:
7180
- name: Select latest available Xcode
7281
uses: maxim-lobanov/setup-xcode@v1

Sources/OpenAPIKit/JSONReference.swift

+13-1
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,19 @@ extension JSONReference: Decodable {
469469
}
470470
self = .internal(internalReference)
471471
} else {
472-
guard let externalReference = URL(string: referenceString) else {
472+
let externalReferenceCandidate: URL?
473+
#if canImport(FoundationEssentials)
474+
externalReferenceCandidate = URL(string: referenceString, encodingInvalidCharacters: false)
475+
#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
476+
if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
477+
externalReferenceCandidate = URL(string: referenceString, encodingInvalidCharacters: false)
478+
} else {
479+
externalReferenceCandidate = URL(string: referenceString)
480+
}
481+
#else
482+
externalReferenceCandidate = URL(string: referenceString)
483+
#endif
484+
guard let externalReference = externalReferenceCandidate else {
473485
throw InconsistencyError(
474486
subjectName: "JSON Reference",
475487
details: "Failed to parse a valid URI for a JSON Reference from '\(referenceString)'",

Sources/OpenAPIKit/Utility/Container+DecodeURLAsString.swift

+26-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,19 @@ import Foundation
1111
extension KeyedDecodingContainerProtocol {
1212
internal func decodeURLAsString(forKey key: Self.Key) throws -> URL {
1313
let string = try decode(String.self, forKey: key)
14-
guard let url = URL(string: string) else {
14+
let urlCandidate: URL?
15+
#if canImport(FoundationEssentials)
16+
urlCandidate = URL(string: string, encodingInvalidCharacters: false)
17+
#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
18+
if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
19+
urlCandidate = URL(string: string, encodingInvalidCharacters: false)
20+
} else {
21+
urlCandidate = URL(string: string)
22+
}
23+
#else
24+
urlCandidate = URL(string: string)
25+
#endif
26+
guard let url = urlCandidate else {
1527
throw InconsistencyError(
1628
subjectName: key.stringValue,
1729
details: "If specified, must be a valid URL",
@@ -26,7 +38,19 @@ extension KeyedDecodingContainerProtocol {
2638
return nil
2739
}
2840

29-
guard let url = URL(string: string) else {
41+
let urlCandidate: URL?
42+
#if canImport(FoundationEssentials)
43+
urlCandidate = URL(string: string, encodingInvalidCharacters: false)
44+
#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
45+
if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
46+
urlCandidate = URL(string: string, encodingInvalidCharacters: false)
47+
} else {
48+
urlCandidate = URL(string: string)
49+
}
50+
#else
51+
urlCandidate = URL(string: string)
52+
#endif
53+
guard let url = urlCandidate else {
3054
throw InconsistencyError(
3155
subjectName: key.stringValue,
3256
details: "If specified, must be a valid URL",

Sources/OpenAPIKit30/JSONReference.swift

+13-1
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,19 @@ extension JSONReference: Decodable {
333333
}
334334
self = .internal(internalReference)
335335
} else {
336-
guard let externalReference = URL(string: referenceString) else {
336+
let externalReferenceCandidate: URL?
337+
#if canImport(FoundationEssentials)
338+
externalReferenceCandidate = URL(string: referenceString, encodingInvalidCharacters: false)
339+
#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
340+
if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
341+
externalReferenceCandidate = URL(string: referenceString, encodingInvalidCharacters: false)
342+
} else {
343+
externalReferenceCandidate = URL(string: referenceString)
344+
}
345+
#else
346+
externalReferenceCandidate = URL(string: referenceString)
347+
#endif
348+
guard let externalReference = externalReferenceCandidate else {
337349
throw InconsistencyError(
338350
subjectName: "JSON Reference",
339351
details: "Failed to parse a valid URI for a JSON Reference from '\(referenceString)'",

Sources/OpenAPIKit30/Utility/Container+DecodeURLAsString.swift

+26-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,19 @@ import Foundation
1111
extension KeyedDecodingContainerProtocol {
1212
internal func decodeURLAsString(forKey key: Self.Key) throws -> URL {
1313
let string = try decode(String.self, forKey: key)
14-
guard let url = URL(string: string) else {
14+
let urlCandidate: URL?
15+
#if canImport(FoundationEssentials)
16+
urlCandidate = URL(string: string, encodingInvalidCharacters: false)
17+
#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
18+
if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
19+
urlCandidate = URL(string: string, encodingInvalidCharacters: false)
20+
} else {
21+
urlCandidate = URL(string: string)
22+
}
23+
#else
24+
urlCandidate = URL(string: string)
25+
#endif
26+
guard let url = urlCandidate else {
1527
throw InconsistencyError(
1628
subjectName: key.stringValue,
1729
details: "If specified, must be a valid URL",
@@ -26,7 +38,19 @@ extension KeyedDecodingContainerProtocol {
2638
return nil
2739
}
2840

29-
guard let url = URL(string: string) else {
41+
let urlCandidate: URL?
42+
#if canImport(FoundationEssentials)
43+
urlCandidate = URL(string: string, encodingInvalidCharacters: false)
44+
#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
45+
if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
46+
urlCandidate = URL(string: string, encodingInvalidCharacters: false)
47+
} else {
48+
urlCandidate = URL(string: string)
49+
}
50+
#else
51+
urlCandidate = URL(string: string)
52+
#endif
53+
guard let url = urlCandidate else {
3054
throw InconsistencyError(
3155
subjectName: key.stringValue,
3256
details: "If specified, must be a valid URL",

Sources/OpenAPIKitCore/URLTemplate/URLTemplate.swift

+13-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,19 @@ public struct URLTemplate: Hashable, RawRepresentable {
7474
/// Templated URLs with variables in them will not be valid URLs
7575
/// and are therefore guaranteed to return `nil`.
7676
public var url: URL? {
77-
return URL(string: rawValue)
77+
let urlCandidate: URL?
78+
#if canImport(FoundationEssentials)
79+
urlCandidate = URL(string: rawValue, encodingInvalidCharacters: false)
80+
#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
81+
if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
82+
urlCandidate = URL(string: rawValue, encodingInvalidCharacters: false)
83+
} else {
84+
urlCandidate = URL(string: rawValue)
85+
}
86+
#else
87+
urlCandidate = URL(string: rawValue)
88+
#endif
89+
return urlCandidate
7890
}
7991

8092
/// Get the names of all variables in the URL Template.

Sources/OpenAPIKitCore/Utility/Container+DecodeURLAsString.swift

+26-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,19 @@ import Foundation
1010
extension KeyedDecodingContainerProtocol {
1111
internal func decodeURLAsString(forKey key: Self.Key) throws -> URL {
1212
let string = try decode(String.self, forKey: key)
13-
guard let url = URL(string: string) else {
13+
let urlCandidate: URL?
14+
#if canImport(FoundationEssentials)
15+
urlCandidate = URL(string: string, encodingInvalidCharacters: false)
16+
#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
17+
if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
18+
urlCandidate = URL(string: string, encodingInvalidCharacters: false)
19+
} else {
20+
urlCandidate = URL(string: string)
21+
}
22+
#else
23+
urlCandidate = URL(string: string)
24+
#endif
25+
guard let url = urlCandidate else {
1426
throw InconsistencyError(
1527
subjectName: key.stringValue,
1628
details: "If specified, must be a valid URL",
@@ -25,7 +37,19 @@ extension KeyedDecodingContainerProtocol {
2537
return nil
2638
}
2739

28-
guard let url = URL(string: string) else {
40+
let urlCandidate: URL?
41+
#if canImport(FoundationEssentials)
42+
urlCandidate = URL(string: string, encodingInvalidCharacters: false)
43+
#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
44+
if #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) {
45+
urlCandidate = URL(string: string, encodingInvalidCharacters: false)
46+
} else {
47+
urlCandidate = URL(string: string)
48+
}
49+
#else
50+
urlCandidate = URL(string: string)
51+
#endif
52+
guard let url = urlCandidate else {
2953
throw InconsistencyError(
3054
subjectName: key.stringValue,
3155
details: "If specified, must be a valid URL",

Tests/OpenAPIKit30RealSpecSuite/GitHubAPITests.swift

+4-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ final class GitHubAPICampatibilityTests: XCTestCase {
3636
}
3737
}
3838

39-
func test_successfullyParsedDocument() {
39+
func test_successfullyParsedDocument() throws {
40+
#if os(Linux) && compiler(>=6.0)
41+
throw XCTSkip("Swift bug causes CI failure currently (line 48): failed - The operation could not be completed. The file doesn’t exist.")
42+
#endif
4043
switch githubAPI {
4144
case nil:
4245
XCTFail("Did not attempt to pull GitHub API documentation like expected.")

Tests/OpenAPIKit30RealSpecSuite/GoogleBooksAPITests.swift

+4-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ final class GoogleBooksAPICampatibilityTests: XCTestCase {
3131
}
3232
}
3333

34-
func test_successfullyParsedDocument() {
34+
func test_successfullyParsedDocument() throws {
35+
#if os(Linux) && compiler(>=6.0)
36+
throw XCTSkip("Swift bug causes CI failure currently (line 48): failed - The operation could not be completed. The file doesn’t exist.")
37+
#endif
3538
switch booksAPI {
3639
case nil:
3740
XCTFail("Did not attempt to pull Google Books API documentation like expected.")

Tests/OpenAPIKit30RealSpecSuite/PetStoreAPITests.swift

+4-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ final class PetStoreAPICampatibilityTests: XCTestCase {
3131
}
3232
}
3333

34-
func test_successfullyParsedDocument() {
34+
func test_successfullyParsedDocument() throws {
35+
#if os(Linux) && compiler(>=6.0)
36+
throw XCTSkip("Swift bug causes CI failure currently (line 48): failed - The operation could not be completed. The file doesn’t exist.")
37+
#endif
3538
switch petStoreAPI {
3639
case nil:
3740
XCTFail("Did not attempt to pull Pet Store API documentation like expected.")

Tests/OpenAPIKit30RealSpecSuite/TomTomAPITests.swift

+4-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ final class TomTomAPICampatibilityTests: XCTestCase {
3131
}
3232
}
3333

34-
func test_successfullyParsedDocument() {
34+
func test_successfullyParsedDocument() throws {
35+
#if os(Linux) && compiler(>=6.0)
36+
throw XCTSkip("Swift bug causes CI failure currently (line 43): failed - The operation could not be completed. The file doesn’t exist.")
37+
#endif
3538
switch tomtomAPI {
3639
case nil:
3740
XCTFail("Did not attempt to pull TomTom API documentation like expected.")

Tests/OpenAPIKit30Tests/Validator/Validation+ConvenienceTests.swift

+8-1
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ final class ValidationConvenienceTests: XCTestCase {
318318
)
319319
}
320320

321-
func test_subject_unwrapAndlookup() {
321+
func test_subject_unwrapAndlookup() throws {
322322
let v = Validation<OpenAPI.Parameter>(
323323
description: "parameter is named test",
324324
check: \.name == "test"
@@ -358,6 +358,13 @@ final class ValidationConvenienceTests: XCTestCase {
358358
XCTAssertFalse(
359359
unwrapAndLookup(\OpenAPI.Document.paths["/test"]?.pathItemValue?.parameters[2], thenApply: v)(context).isEmpty
360360
)
361+
#if os(macOS)
362+
if #available(macOS 15.0, *) {
363+
// this is just here because if #unavailable inside this block causes a compilation failure prior to Swift 5.6 on Linux :/
364+
} else {
365+
throw XCTSkip("Skipping due to Swift/macOS bug resulting in error (line 368): throwing \"std::bad_alloc: std::bad_alloc\"")
366+
}
367+
#endif
361368
// nil keypath
362369
XCTAssertFalse(
363370
unwrapAndLookup(\OpenAPI.Document.paths["/test2"]?.pathItemValue?.parameters.first, thenApply: v)(context).isEmpty

Tests/OpenAPIKitTests/Validator/Validation+ConvenienceTests.swift

+8-1
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ final class ValidationConvenienceTests: XCTestCase {
318318
)
319319
}
320320

321-
func test_subject_unwrapAndlookup() {
321+
func test_subject_unwrapAndlookup() throws {
322322
let v = Validation<OpenAPI.Parameter>(
323323
description: "parameter is named test",
324324
check: \.name == "test"
@@ -358,6 +358,13 @@ final class ValidationConvenienceTests: XCTestCase {
358358
XCTAssertFalse(
359359
unwrapAndLookup(\OpenAPI.Document.paths["/test"]?.pathItemValue?.parameters[2], thenApply: v)(context).isEmpty
360360
)
361+
#if os(macOS)
362+
if #available(macOS 15.0, *) {
363+
// this is just here because if #unavailable inside this block causes a compilation failure prior to Swift 5.6 on Linux :/
364+
} else {
365+
throw XCTSkip("Skipping due to Swift/macOS bug resulting in error (line 368): throwing \"std::bad_alloc: std::bad_alloc\"")
366+
}
367+
#endif
361368
// nil keypath
362369
XCTAssertFalse(
363370
unwrapAndLookup(\OpenAPI.Document.paths["/test2"]?.pathItemValue?.parameters.first, thenApply: v)(context).isEmpty

0 commit comments

Comments
 (0)