-
-
Save mikemahony/7c7a4b2caf24d10c19c0f79765ede2f6 to your computer and use it in GitHub Desktop.
Semantic Version Number struct (Swift 4.1)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Foundation | |
| public struct SemanticVersionNumber: Equatable { | |
| public let major: Int | |
| public let minor: Int | |
| public let patch: Int | |
| public init?(version: String) { | |
| let components = version.split(separator: ".") | |
| guard components.count == 3 else { return nil } | |
| self.init(major: String(components[0]), | |
| minor: String(components[1]), | |
| patch: String(components[2])) | |
| } | |
| public init?(major: String, minor: String, patch: String) { | |
| guard | |
| let majorAsInt = Int(major), | |
| let minorAsInt = Int(minor), | |
| let patchAsInt = Int(patch) | |
| else { | |
| return nil | |
| } | |
| self.init(major: majorAsInt, | |
| minor: minorAsInt, | |
| patch: patchAsInt) | |
| } | |
| public init(major: Int, minor: Int, patch: Int) { | |
| self.major = major | |
| self.minor = minor | |
| self.patch = patch | |
| } | |
| } | |
| extension SemanticVersionNumber: Codable { | |
| public init(from decoder: Decoder) throws { | |
| let str = try decoder.singleValueContainer().decode(String.self) | |
| self.init(version: str)! | |
| } | |
| } | |
| extension SemanticVersionNumber: Comparable { | |
| public static func < (lhs: SemanticVersionNumber, rhs: SemanticVersionNumber) -> Bool { | |
| (lhs.major < rhs.major) | |
| || (lhs.major == rhs.major && lhs.minor < rhs.minor) | |
| || (lhs.major == rhs.major && lhs.minor == rhs.minor && lhs.patch < rhs.patch) | |
| } | |
| } | |
| extension SemanticVersionNumber: CustomStringConvertible { | |
| public var description: String { | |
| "\(major).\(minor).\(patch)" | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Foundation | |
| import XCTest | |
| public class SemanticVersionNumberTests: XCTestCase { | |
| func testInitFromStringWhenStringIsMalformedVerionNumberWithMoreThanThreeNumbers() { | |
| let value = SemanticVersionNumber(version: "1.2.3.4") | |
| XCTAssertNil(value) | |
| } | |
| func testInitFromStringWhenStringIsMalformedVerionNumberWithLessThanThreeNumbers() { | |
| let value = SemanticVersionNumber(version: "1.2") | |
| XCTAssertNil(value) | |
| } | |
| func testInitFromStringWhenStringIsMalformedVerionNumberWithNonNumbers() { | |
| let value = SemanticVersionNumber(version: "1.2.X") | |
| XCTAssertNil(value) | |
| } | |
| func testInitFromStringWhenStringIsWellFormedVersionNumber() { | |
| let value = SemanticVersionNumber(version: "1.2.3") | |
| let expectedValue = SemanticVersionNumber(major: 1, minor: 2, patch: 3) | |
| XCTAssertEqual(value, expectedValue) | |
| } | |
| func testInitFromStringWhenStringIsWellFormedVersionNumberAllZeroes() { | |
| let value = SemanticVersionNumber(version: "0.0.0") | |
| let expectedValue = SemanticVersionNumber(major: 0, minor: 0, patch: 0) | |
| XCTAssertEqual(value, expectedValue) | |
| } | |
| func testInitFromJsonDeserialization() { | |
| struct Dcdbl: Decodable { | |
| var version: SemanticVersionNumber | |
| } | |
| let value = try! JSONDecoder() | |
| .decode( | |
| Dcdbl.self, | |
| from: #"{ "version": "1.2.3" }"#.data(using: .utf8)! | |
| ) | |
| let expectedValue = SemanticVersionNumber(major: 1, minor: 2, patch: 3) | |
| XCTAssertEqual(value.version, expectedValue) | |
| } | |
| func testConvertToString() { | |
| let s = SemanticVersionNumber(major: 2, minor: 11, patch: 3) | |
| let value = String(describing: s) | |
| let expectedValue = "2.11.3" | |
| XCTAssertEqual(value, expectedValue) | |
| } | |
| func testEqualityWhenEqual() { | |
| let lhs = SemanticVersionNumber(major: 2, minor: 11, patch: 3) | |
| let rhs = SemanticVersionNumber(major: 2, minor: 11, patch: 3) | |
| XCTAssertEqual(lhs, rhs) | |
| } | |
| func testEqualityWhenNotEqual() { | |
| let lhs = SemanticVersionNumber(major: 2, minor: 11, patch: 3) | |
| let rhs = SemanticVersionNumber(major: 2, minor: 0, patch: 4) | |
| XCTAssertNotEqual(lhs, rhs) | |
| } | |
| func testComparisonWhenLHSLessThanRHS() { | |
| let lhs = SemanticVersionNumber(major: 2, minor: 0, patch: 4) | |
| let rhs = SemanticVersionNumber(major: 2, minor: 11, patch: 3) | |
| XCTAssertLessThan(lhs, rhs) | |
| } | |
| func testComparisonWhenLHSGreaterThanRHS() { | |
| let lhs = SemanticVersionNumber(major: 2, minor: 11, patch: 3) | |
| let rhs = SemanticVersionNumber(major: 2, minor: 0, patch: 4) | |
| XCTAssertGreaterThan(lhs, rhs) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment