diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 22a4ddf..34fc58a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,17 +11,19 @@ jobs: name: Swift ${{ matrix.swift }} on ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, macos-latest] - swift: ["5.7", "5.8", "5.9", "5.10"] + os: [ubuntu-22.04, macos-latest] + swift: ["5.7", "5.8", "5.9", "5.10", "6.0.0", "6.1.0"] runs-on: ${{ matrix.os }} steps: - name: Setup Swift - uses: swift-actions/setup-swift@v2.1.0 + uses: swift-actions/setup-swift@v2.3.0 with: swift-version: ${{ matrix.swift }} - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Build run: swift build - name: Run tests run: swift test + - name: Swift Package Registry + uses: twodayslate/swift-package-registry@v0.0.2 diff --git a/Package.swift b/Package.swift index 3c69c17..61f01a0 100644 --- a/Package.swift +++ b/Package.swift @@ -1,10 +1,10 @@ -// swift-tools-version: 5.9 +// swift-tools-version: 6.0 import PackageDescription let package = Package( name: "BinaryCodable", - platforms: [.macOS(.v10_13), .iOS(.v11), .tvOS(.v11), .watchOS(.v4)], + platforms: [.macOS(.v10_13), .iOS(.v12), .tvOS(.v12), .watchOS(.v4)], products: [ .library( name: "BinaryCodable", @@ -21,5 +21,5 @@ let package = Package( name: "BinaryCodableTests", dependencies: ["BinaryCodable"]), ], - swiftLanguageVersions: [.v5] + swiftLanguageModes: [.v6] ) diff --git a/Package@swift-5.9.swift b/Package@swift-5.9.swift new file mode 100644 index 0000000..3c69c17 --- /dev/null +++ b/Package@swift-5.9.swift @@ -0,0 +1,25 @@ +// swift-tools-version: 5.9 + +import PackageDescription + +let package = Package( + name: "BinaryCodable", + platforms: [.macOS(.v10_13), .iOS(.v11), .tvOS(.v11), .watchOS(.v4)], + products: [ + .library( + name: "BinaryCodable", + targets: ["BinaryCodable"]), + ], + dependencies: [ + .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0") + ], + targets: [ + .target( + name: "BinaryCodable", + dependencies: []), + .testTarget( + name: "BinaryCodableTests", + dependencies: ["BinaryCodable"]), + ], + swiftLanguageVersions: [.v5] +) diff --git a/Tests/BinaryCodableTests/ArrayEncodingTests.swift b/Tests/BinaryCodableTests/ArrayEncodingTests.swift index 3ef795f..81ac7a0 100644 --- a/Tests/BinaryCodableTests/ArrayEncodingTests.swift +++ b/Tests/BinaryCodableTests/ArrayEncodingTests.swift @@ -207,8 +207,8 @@ final class ArrayEncodingTests: XCTestCase { self.measure { do { - let data = try BinaryEncoder.encode(value) - print(data.count) + let _ = try BinaryEncoder.encode(value) + //print(data.count) } catch { XCTFail(error.localizedDescription) } diff --git a/Tests/BinaryCodableTests/BoolTests.swift b/Tests/BinaryCodableTests/BoolTests.swift index 4d3d4f9..db5de1a 100644 --- a/Tests/BinaryCodableTests/BoolTests.swift +++ b/Tests/BinaryCodableTests/BoolTests.swift @@ -70,16 +70,21 @@ final class BoolTests: XCTestCase { } func testUnkeyedWithBool() throws { - GenericTestStruct.encode { encoder in - var container = encoder.unkeyedContainer() - try container.encode(true) - } - GenericTestStruct.decode { decoder in - var container = try decoder.unkeyedContainer() - let value = try container.decode(Bool.self) - XCTAssertEqual(value, true) + + struct UnkeyedWithBool: SomeCodable { + + static func encode(_ encoder: any Encoder) throws { + var container = encoder.unkeyedContainer() + try container.encode(true) + } + + static func decode(_ decoder: any Decoder) throws { + var container = try decoder.unkeyedContainer() + let value = try container.decode(Bool.self) + XCTAssertEqual(value, true) + } } + + try compare(UnkeyedWithBool()) } - - } diff --git a/Tests/BinaryCodableTests/CodingPathTests.swift b/Tests/BinaryCodableTests/CodingPathTests.swift index 1ae532a..27defb5 100644 --- a/Tests/BinaryCodableTests/CodingPathTests.swift +++ b/Tests/BinaryCodableTests/CodingPathTests.swift @@ -7,34 +7,45 @@ import XCTest final class CodingPathTests: XCTestCase { func testCodingPathAtRoot() throws { - GenericTestStruct.encode { encoder in - // Need to set some value, otherwise encoding will fail - var container = encoder.singleValueContainer() - try container.encode(0) - XCTAssertEqual(encoder.codingPath, []) + + struct Root: SomeCodable { + + static func encode(_ encoder: any Encoder) throws { + // Need to set some value, otherwise encoding will fail + var container = encoder.singleValueContainer() + try container.encode(0) + XCTAssertEqual(encoder.codingPath, []) + } + + static func decode(_ decoder: any Decoder) throws { + XCTAssertEqual(decoder.codingPath, []) + } } - GenericTestStruct.decode { decoder in - XCTAssertEqual(decoder.codingPath, []) - } - try compare(GenericTestStruct()) + try compare(Root()) } func testCodingPathInKeyedContainer() throws { enum SomeKey: Int, CodingKey { case value = 1 } - GenericTestStruct.encode { encoder in - XCTAssertEqual(encoder.codingPath, []) - var container = encoder.container(keyedBy: SomeKey.self) - let unkeyed = container.nestedUnkeyedContainer(forKey: .value) - XCTAssertEqual(unkeyed.codingPath, [1]) - } - GenericTestStruct.decode { decoder in - XCTAssertEqual(decoder.codingPath, []) - let container = try decoder.container(keyedBy: SomeKey.self) - let unkeyed = try container.nestedUnkeyedContainer(forKey: .value) - XCTAssertEqual(unkeyed.codingPath, [1]) + + struct Keyed: SomeCodable { + + static func encode(_ encoder: any Encoder) throws { + XCTAssertEqual(encoder.codingPath, []) + var container = encoder.container(keyedBy: SomeKey.self) + let unkeyed = container.nestedUnkeyedContainer(forKey: .value) + XCTAssertEqual(unkeyed.codingPath, [1]) + } + + static func decode(_ decoder: any Decoder) throws { + XCTAssertEqual(decoder.codingPath, []) + let container = try decoder.container(keyedBy: SomeKey.self) + let unkeyed = try container.nestedUnkeyedContainer(forKey: .value) + XCTAssertEqual(unkeyed.codingPath, [1]) + } } - try compare(GenericTestStruct()) + + try compare(Keyed()) } } diff --git a/Tests/BinaryCodableTests/Helper.swift b/Tests/BinaryCodableTests/Helper.swift index b5c4e77..4503ca6 100644 --- a/Tests/BinaryCodableTests/Helper.swift +++ b/Tests/BinaryCodableTests/Helper.swift @@ -2,62 +2,24 @@ import Foundation import XCTest @testable import BinaryCodable -struct GenericTestStruct: Codable, Equatable { - - init() { - - } - - init(from decoder: Decoder) throws { - try GenericTestStruct.decodingRoutine(decoder) - } - - func encode(to encoder: Encoder) throws { - try GenericTestStruct.encodingRoutine(encoder) - } - - private static nonisolated(unsafe) var _encodingRoutine: (Encoder) throws -> Void = { _ in } - - private static nonisolated(unsafe) var _decodingRoutine: (Decoder) throws -> Void = { _ in } +protocol SomeCodable: Codable, Equatable { - private static let encodeSemaphore = DispatchSemaphore(value: 1) + init() - static var encodingRoutine: (Encoder) throws -> Void { - get { - encodeSemaphore.wait() - let value = _encodingRoutine - encodeSemaphore.signal() - return value - } - set { - encodeSemaphore.wait() - _encodingRoutine = newValue - encodeSemaphore.signal() - } - } - - private static let decodeSemaphore = DispatchSemaphore(value: 1) + static func encode(_ encoder: Encoder) throws -> () - static var decodingRoutine: (Decoder) throws -> Void { - get { - decodeSemaphore.wait() - let value = _decodingRoutine - decodeSemaphore.signal() - return value - } - set { - decodeSemaphore.wait() - _decodingRoutine = newValue - decodeSemaphore.signal() - } - } + static func decode(_ decoder: Decoder) throws -> () +} - static func encode(_ block: @escaping (Encoder) throws -> Void) { - encodingRoutine = block +extension SomeCodable { + + init(from decoder: any Decoder) throws { + try Self.decode(decoder) + self.init() } - - static func decode(_ block: @escaping (Decoder) throws -> Void) { - decodingRoutine = block + + func encode(to encoder: any Encoder) throws { + try Self.encode(encoder) } } @@ -89,9 +51,9 @@ extension XCTestCase { let data = try encoder.encode(value) if let expected { XCTAssertEqual(Array(data), expected) - } else { - print("Encoded data: \(Array(data))") - } + }// else { + // print("Encoded data: \(Array(data))") + //} let decoder = BinaryDecoder() let decoded = try decoder.decode(T.self, from: data) diff --git a/Tests/BinaryCodableTests/KeyedEncodingTests.swift b/Tests/BinaryCodableTests/KeyedEncodingTests.swift index 9a9f2a1..ff80eac 100644 --- a/Tests/BinaryCodableTests/KeyedEncodingTests.swift +++ b/Tests/BinaryCodableTests/KeyedEncodingTests.swift @@ -187,32 +187,38 @@ final class KeyedEncodingTests: XCTestCase { case value = 1 case opt = 2 } - GenericTestStruct.encode { encoder in - var container = encoder.container(keyedBy: Keys.self) - let value: String? = nil - try container.encodeIfPresent(value, forKey: .value) - try container.encodeNil(forKey: .opt) - } - GenericTestStruct.decode { decoder in - let container = try decoder.container(keyedBy: Keys.self) - XCTAssertFalse(container.contains(.value)) - // Nil is not encoded - XCTAssertFalse(container.contains(.opt)) - - let s = try container.decodeIfPresent(String.self, forKey: .value) - XCTAssertEqual(s, nil) - - let optIsNil = try container.decodeNil(forKey: .opt) - XCTAssertTrue(optIsNil) - let opt = try container.decodeIfPresent(Bool.self, forKey: .opt) - XCTAssertNil(opt) - do { - _ = try container.decode(Bool.self, forKey: .opt) - XCTFail() - } catch { - + + struct NilEncoder: SomeCodable { + + static func encode(_ encoder: any Encoder) throws { + var container = encoder.container(keyedBy: Keys.self) + let value: String? = nil + try container.encodeIfPresent(value, forKey: .value) + try container.encodeNil(forKey: .opt) + } + + static func decode(_ decoder: any Decoder) throws { + let container = try decoder.container(keyedBy: Keys.self) + XCTAssertFalse(container.contains(.value)) + // Nil is not encoded + XCTAssertFalse(container.contains(.opt)) + + let s = try container.decodeIfPresent(String.self, forKey: .value) + XCTAssertEqual(s, nil) + + let optIsNil = try container.decodeNil(forKey: .opt) + XCTAssertTrue(optIsNil) + let opt = try container.decodeIfPresent(Bool.self, forKey: .opt) + XCTAssertNil(opt) + do { + _ = try container.decode(Bool.self, forKey: .opt) + XCTFail() + } catch { + + } } } - try compare(GenericTestStruct(), to: []) + + try compare(NilEncoder()) } } diff --git a/Tests/BinaryCodableTests/PropertyWrapperCodingTests.swift b/Tests/BinaryCodableTests/PropertyWrapperCodingTests.swift index 11cd82c..c46ce5c 100644 --- a/Tests/BinaryCodableTests/PropertyWrapperCodingTests.swift +++ b/Tests/BinaryCodableTests/PropertyWrapperCodingTests.swift @@ -72,10 +72,10 @@ final class PropertyWrapperCodingTests: XCTestCase { // If the suffix differs, this error is specific to the individual test case, // so report it on the call-side - XCTAssertEqual(Array(data.suffix(from: bytePrefix.count)), byteSuffix, file: file, line: line) + XCTAssertEqual(Array(data.suffix(from: bytePrefix.count)), byteSuffix, file: (file), line: line) let decodedWrapper: KeyedWrapper = try BinaryDecoder.decode(from: data) - XCTAssertEqual(decodedWrapper, wrapper, file: file, line: line) + XCTAssertEqual(decodedWrapper, wrapper, file: (file), line: line) } func testOptionalWrappedStringSome() throws { diff --git a/Tests/BinaryCodableTests/SequenceEncoderTests.swift b/Tests/BinaryCodableTests/SequenceEncoderTests.swift index 9e1ef10..fd65887 100644 --- a/Tests/BinaryCodableTests/SequenceEncoderTests.swift +++ b/Tests/BinaryCodableTests/SequenceEncoderTests.swift @@ -7,7 +7,7 @@ final class SequenceEncoderTests: XCTestCase { let encoder = BinaryStreamEncoder() let bytes = try input.mapAndJoin(encoder.encode) - print(Array(bytes)) + //print(Array(bytes)) let decoder = BinaryStreamDecoder() decoder.add(bytes) diff --git a/Tests/BinaryCodableTests/UnkeyedContainerTests.swift b/Tests/BinaryCodableTests/UnkeyedContainerTests.swift index 2f4e3c9..f1b233e 100644 --- a/Tests/BinaryCodableTests/UnkeyedContainerTests.swift +++ b/Tests/BinaryCodableTests/UnkeyedContainerTests.swift @@ -4,36 +4,41 @@ import BinaryCodable final class UnkeyedContainerTests: XCTestCase { func testCountAndIndexInUnkeyedContainer() throws { - GenericTestStruct.encode { encoder in - var container = encoder.unkeyedContainer() - try container.encode(true) - try container.encode("Some") - try container.encode(123) - } - - GenericTestStruct.decode { decoder in - var container = try decoder.unkeyedContainer() - if let count = container.count { - XCTAssertEqual(count, 3) - } else { - XCTFail("No count in unkeyed container") + + struct Unkeyed: SomeCodable { + + static func encode(_ encoder: any Encoder) throws { + var container = encoder.unkeyedContainer() + try container.encode(true) + try container.encode("Some") + try container.encode(123) } - XCTAssertEqual(container.currentIndex, 0) - XCTAssertEqual(container.isAtEnd, false) + + static func decode(_ decoder: any Decoder) throws { + var container = try decoder.unkeyedContainer() + if let count = container.count { + XCTAssertEqual(count, 3) + } else { + XCTFail("No count in unkeyed container") + } + XCTAssertEqual(container.currentIndex, 0) + XCTAssertEqual(container.isAtEnd, false) - XCTAssertEqual(try container.decode(Bool.self), true) - XCTAssertEqual(container.currentIndex, 1) - XCTAssertEqual(container.isAtEnd, false) + XCTAssertEqual(try container.decode(Bool.self), true) + XCTAssertEqual(container.currentIndex, 1) + XCTAssertEqual(container.isAtEnd, false) - XCTAssertEqual(try container.decode(String.self), "Some") - XCTAssertEqual(container.currentIndex, 2) - XCTAssertEqual(container.isAtEnd, false) + XCTAssertEqual(try container.decode(String.self), "Some") + XCTAssertEqual(container.currentIndex, 2) + XCTAssertEqual(container.isAtEnd, false) - XCTAssertEqual(try container.decode(Int.self), 123) - XCTAssertEqual(container.currentIndex, 3) - XCTAssertEqual(container.isAtEnd, true) + XCTAssertEqual(try container.decode(Int.self), 123) + XCTAssertEqual(container.currentIndex, 3) + XCTAssertEqual(container.isAtEnd, true) + } } - try compare(GenericTestStruct()) + + try compare(Unkeyed()) } func testIntSet() throws { diff --git a/Tests/BinaryCodableTests/UserInfoTests.swift b/Tests/BinaryCodableTests/UserInfoTests.swift index b316d0b..10d5092 100644 --- a/Tests/BinaryCodableTests/UserInfoTests.swift +++ b/Tests/BinaryCodableTests/UserInfoTests.swift @@ -4,35 +4,41 @@ import BinaryCodable final class UserInfoTests: XCTestCase { func testUserInfoAvailableInEncoderAndDecoder() throws { - let key = CodingUserInfoKey(rawValue: "SomeKey")! let value = true - - GenericTestStruct.encode { encoder in - var container = encoder.singleValueContainer() - if let value = encoder.userInfo[key] as? Bool { - XCTAssertTrue(value) - } else { - XCTFail() + + let key = CodingUserInfoKey(rawValue: "SomeKey")! + + struct Unkeyed: SomeCodable { + + static let key = CodingUserInfoKey(rawValue: "SomeKey")! + + static func encode(_ encoder: any Encoder) throws { + var container = encoder.singleValueContainer() + if let value = encoder.userInfo[key] as? Bool { + XCTAssertTrue(value) + } else { + XCTFail() + } + try container.encode(false) } - try container.encode(false) - } - - GenericTestStruct.decode { decoder in - let container = try decoder.singleValueContainer() - if let value = decoder.userInfo[key] as? Bool { - XCTAssertTrue(value) - } else { - XCTFail() + + static func decode(_ decoder: any Decoder) throws { + let container = try decoder.singleValueContainer() + if let value = decoder.userInfo[key] as? Bool { + XCTAssertTrue(value) + } else { + XCTFail() + } + let decoded = try container.decode(Bool.self) + XCTAssertEqual(decoded, false) } - let decoded = try container.decode(Bool.self) - XCTAssertEqual(decoded, false) } var encoder = BinaryEncoder() encoder.userInfo[key] = value - let encoded = try encoder.encode(GenericTestStruct()) + let encoded = try encoder.encode(Unkeyed()) var decoder = BinaryDecoder() decoder.userInfo[key] = value - _ = try decoder.decode(GenericTestStruct.self, from: encoded) + _ = try decoder.decode(Unkeyed.self, from: encoded) } }