Skip to content

Instantly share code, notes, and snippets.

@mjdescy
Created June 6, 2018 17:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjdescy/a805b5b4c49ed79fb240d3886815d5a2 to your computer and use it in GitHub Desktop.
Save mjdescy/a805b5b4c49ed79fb240d3886815d5a2 to your computer and use it in GitHub Desktop.
Semantic Version Number struct (Swift 4.1)
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: Comparable {
public static func <(lhs: SemanticVersionNumber, rhs: SemanticVersionNumber) -> Bool {
return (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 {
return "\(major).\(minor).\(patch)"
}
}
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 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