diff --git a/.github/workflows/IPSWDownloads.yml b/.github/workflows/IPSWDownloads.yml index d55ca89..140d168 100644 --- a/.github/workflows/IPSWDownloads.yml +++ b/.github/workflows/IPSWDownloads.yml @@ -17,10 +17,10 @@ jobs: runs-on: [ubuntu-20.04, ubuntu-22.04] swift-version: [5.9] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache swift package modules id: cache-spm-linux - uses: actions/cache@v3 + uses: actions/cache@v4 env: cache-name: SPM with: @@ -37,7 +37,7 @@ jobs: run: echo "RELEASE_NAME=$(lsb_release -sc)" >> $GITHUB_ENV - name: Cache swift id: cache-swift-linux - uses: actions/cache@v3 + uses: actions/cache@v4 env: cache-name: swift with: @@ -83,17 +83,17 @@ jobs: watchOSVersion: "10.2" watchName: "Apple Watch Series 9 (45mm)" iPhoneName: "iPhone 15 Pro" - - runs-on: macos-13-xlarge + - runs-on: macos-13 xcode: "/Applications/Xcode_15.2.app" iOSVersion: "17.2" watchOSVersion: "10.2" watchName: "Apple Watch Ultra 2 (49mm)" iPhoneName: "iPhone 15 Pro Max" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache swift package modules id: cache-spm-macos - uses: actions/cache@v3 + uses: actions/cache@v4 env: cache-name: cache-spm with: @@ -106,7 +106,7 @@ jobs: - name: Cache mint if: ${{ github.event_name == 'pull_request' && ( github.base_ref == 'main' || endsWith( github.ref_name , 'Prep') ) && matrix.xcode == '/Applications/Xcode_15.2.app' }} id: cache-mint - uses: actions/cache@v3 + uses: actions/cache@v4 env: cache-name: cache-mint with: @@ -125,16 +125,8 @@ jobs: run: | brew update brew install mint - # - name: Initialize CodeQL - # if: startsWith(matrix.xcode,'/Applications/Xcode_15.1') - # uses: github/codeql-action/init@v3 - # with: - # languages: ${{ matrix.language }} - name: Build run: swift build - # - name: Perform CodeQL Analysis - # if: startsWith(matrix.xcode,'/Applications/Xcode_15.1') - # uses: github/codeql-action/analyze@v3 - name: Run Swift Package tests run: swift test -v --enable-code-coverage - uses: sersoft-gmbh/swift-coverage-action@v4 diff --git a/.swiftformat b/.swiftformat index 9a8c2b4..ae26e16 100644 --- a/.swiftformat +++ b/.swiftformat @@ -1,5 +1,5 @@ --indent 2 ---header strip +--header "\n .*?\.swift\n IPSWDownloads\n\n Created by {file}\n Copyright © {year} BrightDigit.\n\n Permission is hereby granted, free of charge, to any person\n obtaining a copy of this software and associated documentation\n files (the “Software”), to deal in the Software without\n restriction, including without limitation the rights to use,\n copy, modify, merge, publish, distribute, sublicense, and/or\n sell copies of the Software, and to permit persons to whom the\n Software is furnished to do so, subject to the following\n conditions:\n \n The above copyright notice and this permission notice shall be\n included in all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,\n EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n OTHER DEALINGS IN THE SOFTWARE.\n" --commas inline --disable wrapMultilineStatementBraces, redundantInternal --extensionacl on-declarations diff --git a/.swiftlint.yml b/.swiftlint.yml index 3425645..1be2cc7 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -24,7 +24,6 @@ opt_in_rules: - explicit_top_level_acl - fallthrough - fatal_error_message - - file_header - file_name - file_name_no_space - file_types_order diff --git a/Package.resolved b/Package.resolved index 6ebeb54..b5db432 100644 --- a/Package.resolved +++ b/Package.resolved @@ -68,8 +68,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-openapi-runtime", "state" : { - "revision" : "fd101c320185313bbf9c5a45b827b17eda9ff18a", - "version" : "1.1.0" + "revision" : "76951d77a0609599d2dc233e7e40808a74767c6a", + "version" : "1.3.2" } }, { diff --git a/README.md b/README.md index d03d58e..314dcd6 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Provides a Swift-friendly API into the API for [IPSW Downloads](http://ipsw.me). [![Codecov](https://img.shields.io/codecov/c/github/brightdigit/IPSWDownloads)](https://codecov.io/gh/brightdigit/IPSWDownloads) [![CodeFactor](https://www.codefactor.io/repository/github/brightdigit/IPSWDownloads/badge)](https://www.codefactor.io/repository/github/brightdigit/IPSWDownloads) -[![codebeat badge](https://codebeat.co/badges/a891b07c-4cdb-42cf-a97c-bfae45b378d6)](https://codebeat.co/projects/github-com-brightdigit-IPSWDownloads-main) +[![codebeat badge](https://codebeat.co/badges/a891b07c-4cdb-42cf-a97c-bfae45b378d6)](https://codebeat.co/projects/github-com-brightdigit-ipswdownloads-main) [![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability/brightdigit/IPSWDownloads)](https://codeclimate.com/github/brightdigit/IPSWDownloads) [![Code Climate technical debt](https://img.shields.io/codeclimate/tech-debt/brightdigit/IPSWDownloads?label=debt)](https://codeclimate.com/github/brightdigit/IPSWDownloads) [![Code Climate issues](https://img.shields.io/codeclimate/issues/brightdigit/IPSWDownloads)](https://codeclimate.com/github/brightdigit/IPSWDownloads) diff --git a/Sources/IPSWDownloads/Board.swift b/Sources/IPSWDownloads/Board.swift index 59e1144..b8c06ad 100644 --- a/Sources/IPSWDownloads/Board.swift +++ b/Sources/IPSWDownloads/Board.swift @@ -1,29 +1,62 @@ // -// File.swift +// Board.swift +// IPSWDownloads // +// Created by Board.swift +// Copyright © 2024 BrightDigit. // -// Created by Leo Dion on 1/11/24. +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: // +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + import Foundation +/// A struct representing a board with configuration details. public struct Board { + /// The configuration of the board. public let boardconfig: String + + /// The platform information of the board. public let platform: String - /// The CHIP tag is a 16-bit unsigned integer - /// that denotes the type of chip the firmware is to be installed to. - /// It is one of the few tags that is not read from the fuses, - /// but is instead hardcoded in the bootchain. - /// It is used to prevent incompatible firmwares from being installed; - /// different processors may have their MMIO registers in different locations. + /// The CHIP tag is a 16-bit unsigned integer that denotes the type of chip + /// the firmware is to be installed to. It is one of the few tags that is not + /// read from the fuses but is instead hardcoded in the bootchain. It is used + /// to prevent incompatible firmwares from being installed; different processors + /// may have their MMIO registers in different locations. public let cpid: Int - /// The Board ID of a device - /// (also known as BORD, BDID, or ApBoardId) is a value - /// (usually represented as `uint8\_t`) - /// hat represents multiple characteristics of the logic board + /// The Board ID of a device (also known as BORD, BDID, or ApBoardId) is a value + /// (usually represented as `uint8_t`) that represents multiple characteristics + /// of the logic board. public let bdid: Int + /// Initializes a new Board instance with the provided parameters. + /// + /// - Parameters: + /// - boardconfig: The configuration of the board. + /// - platform: The platform information of the board. + /// - cpid: The CHIP tag representing the type of chip for firmware installation. + /// - bdid: The Board ID of the device + /// representing characteristics of the logic board. public init(boardconfig: String, platform: String, cpid: Int, bdid: Int) { self.boardconfig = boardconfig self.platform = platform @@ -33,6 +66,9 @@ public struct Board { } extension Board { + /// Initializes a new Board instance from a given `Components.Schemas.Board` component. + /// + /// - Parameter component: The component containing board details. internal init(component: Components.Schemas.Board) { self.init( boardconfig: component.boardconfig, diff --git a/Sources/IPSWDownloads/Data.swift b/Sources/IPSWDownloads/Data.swift new file mode 100644 index 0000000..2f61a4b --- /dev/null +++ b/Sources/IPSWDownloads/Data.swift @@ -0,0 +1,56 @@ +// +// Data.swift +// IPSWDownloads +// +// Created by Data.swift +// Copyright © 2024 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import Foundation +extension Data { + internal init(hexString: String) throws { + var data = Data(capacity: hexString.count / 2) + + var index = hexString.startIndex + while index < hexString.endIndex { + let byteString = hexString[index ..< hexString.index(index, offsetBy: 2)] + if let byte = UInt8(byteString, radix: 16) { + data.append(byte) + } else { + throw RuntimeError.invalidDataHexString(hexString) + } + index = hexString.index(index, offsetBy: 2) + } + + self = data + } + + internal init?(hexString: String, emptyIsNil: Bool) throws { + if emptyIsNil, hexString.isEmpty { + return nil + } + + try self.init(hexString: hexString) + } +} diff --git a/Sources/IPSWDownloads/Device.swift b/Sources/IPSWDownloads/Device.swift index 002c4b3..93fe93f 100644 --- a/Sources/IPSWDownloads/Device.swift +++ b/Sources/IPSWDownloads/Device.swift @@ -1,17 +1,55 @@ // -// File.swift +// Device.swift +// IPSWDownloads // +// Created by Device.swift +// Copyright © 2024 BrightDigit. // -// Created by Leo Dion on 1/11/24. +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: // +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + import Foundation +/// A struct representing an Apple device along with its firmware and supported boards. public struct Device { + /// The name of the Apple device. public let name: String + + /// The unique identifier of the Apple device. public let identifier: String + + /// The list of firmware versions supported by the device. public let firmwares: [Firmware] + + /// The list of boards supported by the device. public let boards: [Board] + /// Initializes a new Device instance with the provided parameters. + /// + /// - Parameters: + /// - name: The name of the Apple device. + /// - identifier: The unique identifier of the Apple device. + /// - firmwares: The list of firmware versions supported by the device. + /// - boards: The list of boards supported by the device. public init(name: String, identifier: String, firmwares: [Firmware], boards: [Board]) { self.name = name self.identifier = identifier @@ -21,6 +59,11 @@ public struct Device { } extension Device { + /// Initializes a new Device instance + /// from a given `Components.Schemas.Device` component. + /// + /// - Parameter component: The component containing device details. + /// - Throws: An error if there is an issue initializing the device. internal init(component: Components.Schemas.Device) throws { try self.init( name: component.name, diff --git a/Sources/IPSWDownloads/Firmware.swift b/Sources/IPSWDownloads/Firmware.swift index a6ed03d..03eaa3c 100644 --- a/Sources/IPSWDownloads/Firmware.swift +++ b/Sources/IPSWDownloads/Firmware.swift @@ -1,29 +1,85 @@ // -// File.swift +// Firmware.swift +// IPSWDownloads // +// Created by Firmware.swift +// Copyright © 2024 BrightDigit. // -// Created by Leo Dion on 1/11/24. +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: // +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + import Foundation +/// A struct representing firmware details of a device. public struct Firmware { + /// The unique identifier of the firmware. public let identifier: String + + /// The version of the operating system associated with the firmware. public let version: OperatingSystemVersion + + /// The build ID of the firmware. public let buildid: String - public let sha1sum: String - public let md5sum: String + + /// The SHA-1 checksum of the firmware. + public let sha1sum: Data? + + /// The MD5 checksum of the firmware. + public let md5sum: Data? + + /// The size of the firmware file in bytes. public let filesize: Int + + /// The URL where the firmware can be downloaded. public let url: URL + + /// The release date of the firmware. public let releasedate: Date + + /// The upload date of the firmware. public let uploaddate: Date + + /// A flag indicating whether the firmware is signed. public let signed: Bool + /// Initializes a new Firmware instance with the provided parameters. + /// + /// - Parameters: + /// - identifier: The unique identifier of the firmware. + /// - version: The version of the operating system associated with the firmware. + /// - buildid: The build ID of the firmware. + /// - sha1sum: The SHA-1 checksum of the firmware. + /// - md5sum: The MD5 checksum of the firmware. + /// - filesize: The size of the firmware file in bytes. + /// - url: The URL where the firmware can be downloaded. + /// - releasedate: The release date of the firmware. + /// - uploaddate: The upload date of the firmware. + /// - signed: A flag indicating whether the firmware is signed. public init( identifier: String, version: OperatingSystemVersion, buildid: String, - sha1sum: String, - md5sum: String, + sha1sum: Data?, + md5sum: Data?, filesize: Int, url: URL, releasedate: Date, @@ -44,13 +100,18 @@ public struct Firmware { } extension Firmware { + /// Initializes a new Firmware instance + /// from a given `Components.Schemas.Firmware` component. + /// + /// - Parameter component: The component containing firmware details. + /// - Throws: An error if there is an issue initializing the firmware. internal init(component: Components.Schemas.Firmware) throws { try self.init( identifier: component.identifier, version: OperatingSystemVersion(string: component.version), buildid: component.buildid, - sha1sum: component.sha1sum, - md5sum: component.md5sum, + sha1sum: Data(hexString: component.sha1sum, emptyIsNil: true), + md5sum: Data(hexString: component.md5sum, emptyIsNil: true), filesize: component.filesize, url: URL(validatingURL: component.url), releasedate: component.releasedate, diff --git a/Sources/IPSWDownloads/FirmwareType.swift b/Sources/IPSWDownloads/FirmwareType.swift index 7285d08..2b80090 100644 --- a/Sources/IPSWDownloads/FirmwareType.swift +++ b/Sources/IPSWDownloads/FirmwareType.swift @@ -1,9 +1,32 @@ // -// File.swift +// FirmwareType.swift +// IPSWDownloads // +// Created by FirmwareType.swift +// Copyright © 2024 BrightDigit. // -// Created by Leo Dion on 1/11/24. +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: // +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + import Foundation /// Type of Firmware file. diff --git a/Sources/IPSWDownloads/IPSWDownloads.docc/IPSWDownloads.md b/Sources/IPSWDownloads/IPSWDownloads.docc/IPSWDownloads.md new file mode 100644 index 0000000..4167406 --- /dev/null +++ b/Sources/IPSWDownloads/IPSWDownloads.docc/IPSWDownloads.md @@ -0,0 +1,20 @@ +# ``IPSWDownloads`` + +Summary + +## Overview + +Text + +## Topics + +### Client + +- ``IPSWDownloads`` + +### Models + +- ``Device`` +- ``Firmware`` +- ``Board`` +- ``FirmwareType`` diff --git a/Sources/IPSWDownloads/IPSWDownloads.swift b/Sources/IPSWDownloads/IPSWDownloads.swift index 532cc67..e852613 100644 --- a/Sources/IPSWDownloads/IPSWDownloads.swift +++ b/Sources/IPSWDownloads/IPSWDownloads.swift @@ -1,9 +1,32 @@ // -// File.swift +// IPSWDownloads.swift +// IPSWDownloads // +// Created by IPSWDownloads.swift +// Copyright © 2024 BrightDigit. // -// Created by Leo Dion on 1/11/24. +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: // +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + import Foundation import OpenAPIRuntime diff --git a/Sources/IPSWDownloads/OperatingSystemVersion.swift b/Sources/IPSWDownloads/OperatingSystemVersion.swift index 81a1d06..1fc8536 100644 --- a/Sources/IPSWDownloads/OperatingSystemVersion.swift +++ b/Sources/IPSWDownloads/OperatingSystemVersion.swift @@ -1,3 +1,32 @@ +// +// OperatingSystemVersion.swift +// IPSWDownloads +// +// Created by OperatingSystemVersion.swift +// Copyright © 2024 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + import Foundation extension OperatingSystemVersion { diff --git a/Sources/IPSWDownloads/RuntimeError.swift b/Sources/IPSWDownloads/RuntimeError.swift index 33b8372..4cefb55 100644 --- a/Sources/IPSWDownloads/RuntimeError.swift +++ b/Sources/IPSWDownloads/RuntimeError.swift @@ -1,12 +1,36 @@ // -// File.swift +// RuntimeError.swift +// IPSWDownloads // +// Created by RuntimeError.swift +// Copyright © 2024 BrightDigit. // -// Created by Leo Dion on 1/11/24. +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: // +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + import Foundation internal enum RuntimeError: Error { case invalidURL(String) case invalidVersion(String) + case invalidDataHexString(String) } diff --git a/Sources/IPSWDownloads/URL.swift b/Sources/IPSWDownloads/URL.swift index 855ef01..98d4c0f 100644 --- a/Sources/IPSWDownloads/URL.swift +++ b/Sources/IPSWDownloads/URL.swift @@ -1,9 +1,32 @@ // -// File.swift +// URL.swift +// IPSWDownloads // +// Created by URL.swift +// Copyright © 2024 BrightDigit. // -// Created by Leo Dion on 1/11/24. +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: // +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + import Foundation extension URL { diff --git a/Tests/IPSWDownloadsTests/DataTest.swift b/Tests/IPSWDownloadsTests/DataTest.swift new file mode 100644 index 0000000..f5fe7c7 --- /dev/null +++ b/Tests/IPSWDownloadsTests/DataTest.swift @@ -0,0 +1,89 @@ +// +// DataTest.swift +// IPSWDownloads +// +// Created by DataTest.swift +// Copyright © 2024 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +import Foundation +@testable import IPSWDownloads +import XCTest + +extension String { + static let validHexCharacters = "0123456789abcdefABCDEF" + + static func random(ofLength length: Int, validCharacters: String) -> String { + guard !validCharacters.isEmpty else { + return "" + } + + var randomString = "" + + for _ in 0 ..< length { + let randomIndex = Int.random(in: 0 ..< validCharacters.count) + let character = validCharacters[validCharacters.index(validCharacters.startIndex, offsetBy: randomIndex)] + randomString.append(character) + } + + return randomString + } +} + +public class DataTests: XCTestCase { + func testInitStringValid() throws { + let validCount = Int.random(in: 20 ... 50) + let values: [String] = (0 ..< validCount).map { _ in + Int.random(in: 5 ... 25) + }.map { length in + .random(ofLength: length * 2, validCharacters: String.validHexCharacters) + } + + for value in values { + _ = try Data(hexString: value) + try XCTAssertNotNil(Data(hexString: value, emptyIsNil: true)) + try XCTAssertNotNil(Data(hexString: value, emptyIsNil: false)) + } + } + + func testInitStringInvalid() throws { + let invalidCount = Int.random(in: 20 ... 50) + let strings: [String] = (0 ..< invalidCount).map { _ in + UUID().uuidString + } + for string in strings { + var actual: String? + do { + _ = try Data(hexString: string) + } catch let RuntimeError.invalidDataHexString(value) { + actual = value + } + XCTAssertEqual(string, actual) + } + } + + func testInitStringEmpty() throws { + try XCTAssertNil(Data(hexString: "", emptyIsNil: true)) + } +} diff --git a/Tests/IPSWDownloadsTests/IPSWDownloadsTest.swift b/Tests/IPSWDownloadsTests/IPSWDownloadsTest.swift index d8da57e..f22804d 100644 --- a/Tests/IPSWDownloadsTests/IPSWDownloadsTest.swift +++ b/Tests/IPSWDownloadsTests/IPSWDownloadsTest.swift @@ -1,3 +1,32 @@ +// +// IPSWDownloadsTest.swift +// IPSWDownloads +// +// Created by IPSWDownloadsTest.swift +// Copyright © 2024 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + import IPSWDownloads import OpenAPIURLSession import XCTest @@ -10,7 +39,7 @@ final class IPSWDownloadsTest: XCTestCase { client = IPSWDownloads(transport: URLSessionTransport()) } - func testExample() async throws { + func testDeviceWithIdentifier() async throws { let device = try await client.device(withIdentifier: "VirtualMac2,1", type: .ipsw) XCTAssertEqual(device.identifier, "VirtualMac2,1") XCTAssertGreaterThan(device.firmwares.count, 10) diff --git a/Tests/IPSWDownloadsTests/OperatingSystemVersionTest.swift b/Tests/IPSWDownloadsTests/OperatingSystemVersionTest.swift index 031017b..cd4b1c0 100644 --- a/Tests/IPSWDownloadsTests/OperatingSystemVersionTest.swift +++ b/Tests/IPSWDownloadsTests/OperatingSystemVersionTest.swift @@ -1,3 +1,32 @@ +// +// OperatingSystemVersionTest.swift +// IPSWDownloads +// +// Created by OperatingSystemVersionTest.swift +// Copyright © 2024 BrightDigit. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + @testable import IPSWDownloads import XCTest @@ -45,8 +74,8 @@ public class OperatingSystemVersionTests: XCTestCase { } func testInitStringInvalid() throws { - let validCount = Int.random(in: 20 ... 50) - let strings: [String] = (0 ..< validCount).map { _ in + let invalidCount = Int.random(in: 20 ... 50) + let strings: [String] = (0 ..< invalidCount).map { _ in UUID().uuidString } for string in strings {