From 1526e16534a86014c07821e1f9541cd7845be26f Mon Sep 17 00:00:00 2001 From: Ben Leggiero Date: Mon, 25 Oct 2021 15:46:36 -0600 Subject: [PATCH 1/2] #29: Added `.matches(_:ignoring:)` This allows two semantic versions to be compared without regarding certain identifiers - Also moved `Comparable` conformance to a new file; placed new code there - Also moved `Comparable` tests to a new file; placed new tests there --- .../Semantic Version + Comparable.swift | 127 +++++++++ Sources/SemVer/Semantic Version.swift | 69 +---- Tests/LinuxMain.swift | 3 +- .../SemVerTests/SemVer+Comparable Tests.swift | 249 ++++++++++++++++++ Tests/SemVerTests/SemVerTests.swift | 174 ------------ Tests/SemVerTests/XCTestManifests.swift | 1 + 6 files changed, 381 insertions(+), 242 deletions(-) create mode 100644 Sources/SemVer/Semantic Version + Comparable.swift create mode 100644 Tests/SemVerTests/SemVer+Comparable Tests.swift diff --git a/Sources/SemVer/Semantic Version + Comparable.swift b/Sources/SemVer/Semantic Version + Comparable.swift new file mode 100644 index 0000000..a38eb06 --- /dev/null +++ b/Sources/SemVer/Semantic Version + Comparable.swift @@ -0,0 +1,127 @@ +// +// Semantic Version + Comparable.swift +// SemVer +// +// Created by Ky Leggiero on 2021-10-25. +// Copyright © 2021 Ben "Ky" Leggiero BH-1-PS. +// + +import Foundation + + + +extension SemanticVersion: Comparable { + + /// All of the fields of this `SemanticVersion` that should be used for comparison, + /// in order so that the first one takes the highest precedence + public var orderedComparableIdentifiers: [Identifier] { + var orderedComparableFields: [Identifier] = [major, minor, patch] + if let preRelease = preRelease { + orderedComparableFields.append(preRelease) + } + return orderedComparableFields + } + + + /// Implements Semantic Version precedence + /// + /// https://semver.org/spec/v2.0.0.html#spec-item-11 + /// + /// - Parameters: + /// - lhs: The first semantic version to compare + /// - rhs: The second semantic version to compare + /// + /// - Returns: `true` iff the left has lower precedence than the right + public static func <(lhs: SemanticVersion, rhs: SemanticVersion) -> Bool { + if lhs.major < rhs.major + || (lhs.major == rhs.major && lhs.minor < rhs.minor) + || (lhs.major == rhs.major && lhs.minor == rhs.minor && lhs.patch < rhs.patch) + { + return true + } + + if let lhsPreRelease = lhs.preRelease { + if let rhsPreRelease = rhs.preRelease { + return lhsPreRelease < rhsPreRelease + } + else { + return true + } + } + else { + return false + } + } + + + /// Determines whether the given two semantic versions are equivalent. Equivalence is implied by the precedence + /// rules laid out in SemVer 2.0.0 paragraph 11: https://semver.org/spec/v2.0.0.html#spec-item-11 + /// + /// Remember that build metadata does not factor into equality. For example, `"1.2.3+45" == "1.2.3+67"`. + /// + /// - Parameters: + /// - lhs: The first version to compare + /// - rhs: The second version to compare + /// + /// - Returns: `true` if the two versions are equivalent + public static func ==(lhs: SemanticVersion, rhs: SemanticVersion) -> Bool { + return lhs.major == rhs.major + && lhs.minor == rhs.minor + && lhs.patch == rhs.patch + && isEquivalent(lhs.preRelease, rhs.preRelease, isEquivalentToNil: { $0 == "" }) + // According to https://semver.org/spec/v2.0.0.html#spec-item-11, "Build metadata does not figure into precedence" + } + + + /// Compares this semantic version to the other, ignoring the given set of identifiers + /// + /// - Parameters: + /// - other: The other version to compare this one against + /// - ignoring: The identifiers of each version to be ignored in this comparison + /// + /// - Returns: `true` iff this and the given versions match when ignoring the specified identifiers + public func matches(_ other: SemVer, ignoring ignoredIdentifiers: IgnorableIdentifiers) -> Bool { + self.removing(ignoredIdentifiers) + == other.removing(ignoredIdentifiers) + } + + + + /// Returns a copy of this version where the specified identifiers are removed or set to `0` + /// + /// - Parameter ignoredIdentifiers: The identifiers to remove or set to `0` + /// - Returns: A copy of this version without the specified identifiers + private func removing(_ ignoredIdentifiers: IgnorableIdentifiers) -> Self { + var copy = self + + switch ignoredIdentifiers { + case .minorAndPatchAndPreRelease: + copy._minor = 0 + fallthrough + + case .patchAndPreRelease: + copy._patch = 0 + fallthrough + + case .preRelease: + copy.preRelease = nil + } + + return copy + } + + + + /// An identifier which can be ignored + public enum IgnorableIdentifiers { + + /// Ignore the pre-release identifier (treat `1.2.3-Beta` as equal to `1.2.3`) + case preRelease + + /// Ignore the patch and pre-release identifiers (treat `1.2.3` as equal to `1.2.99`; treat `1.2.3-Beta` as equal to `1.2.0`) + case patchAndPreRelease + + /// Ignore the minor, patch, and pre-release identifiers (treat `1.2.3` as equal to `1.99.42`; treat `1.2.3` as equal to `1.2.99`; treat `1.2.3-Beta` as equal to `1.2.0`) + case minorAndPatchAndPreRelease + } +} diff --git a/Sources/SemVer/Semantic Version.swift b/Sources/SemVer/Semantic Version.swift index 18cd781..58a791d 100644 --- a/Sources/SemVer/Semantic Version.swift +++ b/Sources/SemVer/Semantic Version.swift @@ -45,10 +45,10 @@ public struct SemanticVersion { private var _major: Major /// Holds the raw, unmanaged value for `minor` - private var _minor: Minor + internal var _minor: Minor /// Holds the raw, unmanaged value for `patch` - private var _patch: Patch + internal var _patch: Patch /// The MAJOR version; increment this when you make incompatible API changes. @@ -441,71 +441,6 @@ extension SemanticVersion: LosslessStringConvertible { -extension SemanticVersion: Comparable { - - /// All of the fields of this `SemanticVersion` that should be used for comparison, - /// in order so that the first one takes the highest precedence - public var orderedComparableIdentifiers: [Identifier] { - var orderedComparableFields: [Identifier] = [major, minor, patch] - if let preRelease = preRelease { - orderedComparableFields.append(preRelease) - } - return orderedComparableFields - } - - - /// Implements Semantic Version precedence - /// - /// https://semver.org/spec/v2.0.0.html#spec-item-11 - /// - /// - Parameters: - /// - lhs: The first semantic version to compare - /// - rhs: The second semantic version to compare - /// - /// - Returns: `true` iff the left has lower precedence than the right - public static func <(lhs: SemanticVersion, rhs: SemanticVersion) -> Bool { - if lhs.major < rhs.major - || (lhs.major == rhs.major && lhs.minor < rhs.minor) - || (lhs.major == rhs.major && lhs.minor == rhs.minor && lhs.patch < rhs.patch) - { - return true - } - - if let lhsPreRelease = lhs.preRelease { - if let rhsPreRelease = rhs.preRelease { - return lhsPreRelease < rhsPreRelease - } - else { - return true - } - } - else { - return false - } - } - - - /// Determines whether the given two semantic versions are equivalent. Equivalence is implied by the precedence - /// rules laid out in SemVer 2.0.0 paragraph 11: https://semver.org/spec/v2.0.0.html#spec-item-11 - /// - /// Remember that build metadata does not factor into equality. For example, `"1.2.3+45" == "1.2.3+67"`. - /// - /// - Parameters: - /// - lhs: The first version to compare - /// - rhs: The second version to compare - /// - /// - Returns: `true` if the two versions are equivalent - public static func ==(lhs: SemanticVersion, rhs: SemanticVersion) -> Bool { - return lhs.major == rhs.major - && lhs.minor == rhs.minor - && lhs.patch == rhs.patch - && isEquivalent(lhs.preRelease, rhs.preRelease, isEquivalentToNil: { $0 == "" }) - // According to https://semver.org/spec/v2.0.0.html#spec-item-11, "Build metadata does not figure into precedence" - } -} - - - /// The PRE-RELEASE extension; this identifies versions that are available before being declared stable. /// /// Identifiers MUST comprise only ASCII alphanumerics and hyphen `[0-9A-Za-z-]`. diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index f365bd2..298fd88 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -6,4 +6,5 @@ isTesting = true XCTMain(SemVerTests.allTests + SemVerHashableTests.allTests - + SemVerMutationTests.allTests) + + SemVerMutationTests.allTests + + SemVerComparableTests.allTests) diff --git a/Tests/SemVerTests/SemVer+Comparable Tests.swift b/Tests/SemVerTests/SemVer+Comparable Tests.swift new file mode 100644 index 0000000..d94f4ac --- /dev/null +++ b/Tests/SemVerTests/SemVer+Comparable Tests.swift @@ -0,0 +1,249 @@ +// +// SemVer+Comparable Tests.swift +// SemVerTests +// +// Created by Ky Leggiero on 2021-10-25. +// + +import XCTest +import SemVer + + + +class SemVerComparableTests: SemVerTestClass { + + // MARK: - Precedence + + func testPrecedence() { + + // MARK: Less than + + XCTAssertLessThan(SemVer("0.0.1")!, SemVer("0.1.0")!) + XCTAssertLessThan(SemVer("0.0.99999")!, SemVer("0.1.0")!) + XCTAssertLessThan(SemVer("0.0.1")!, SemVer("1.0.0")!) + XCTAssertLessThan(SemVer("0.1.0")!, SemVer("1.0.0")!) + XCTAssertLessThan(SemVer("0.0.1")!, SemVer("1.1.0")!) + XCTAssertLessThan(SemVer("0.1.0")!, SemVer("1.1.0")!) + XCTAssertLessThan(SemVer("0.1.1")!, SemVer("1.1.0")!) + XCTAssertLessThan(SemVer("1.0.0")!, SemVer("2.0.0")!) + XCTAssertLessThan(SemVer("2.0.0")!, SemVer("2.1.0")!) + XCTAssertLessThan(SemVer("2.1.0")!, SemVer("2.1.1")!) + XCTAssertLessThan(SemVer("2.0.0")!, SemVer("12.0.0")!) + + XCTAssertLessThan(SemVer("1.0.0-alpha")!, SemVer("1.0.0")!) + XCTAssertLessThan(SemVer("1.0.0-alpha")!, SemVer("1.0.0-alpha.1")!) + XCTAssertLessThan(SemVer("1.0.0-alpha.1")!, SemVer("1.0.0-alpha.beta")!) + XCTAssertLessThan(SemVer("1.0.0-alpha.1")!, SemVer("1.0.0-beta")!) + XCTAssertLessThan(SemVer("1.0.0-beta")!, SemVer("1.0.0-beta.2")!) + XCTAssertLessThan(SemVer("1.0.0-beta.2")!, SemVer("1.0.0-beta.11")!) + XCTAssertLessThan(SemVer("1.0.0-beta.11")!, SemVer("1.0.0-rc.1")!) + XCTAssertLessThan(SemVer("1.0.0-rc.1")!, SemVer("1.0.0")!) + + // MARK: Greater than + + XCTAssertGreaterThan(SemVer("0.1.0")!, SemVer("0.0.1")!) + XCTAssertGreaterThan(SemVer("0.1.0")!, SemVer("0.0.99999")!) + XCTAssertGreaterThan(SemVer("1.0.0")!, SemVer("0.0.1")!) + XCTAssertGreaterThan(SemVer("1.0.0")!, SemVer("0.1.0")!) + XCTAssertGreaterThan(SemVer("1.1.0")!, SemVer("0.0.1")!) + XCTAssertGreaterThan(SemVer("1.1.0")!, SemVer("0.1.0")!) + XCTAssertGreaterThan(SemVer("1.1.0")!, SemVer("0.1.1")!) + XCTAssertGreaterThan(SemVer("2.0.0")!, SemVer("1.0.0")!) + XCTAssertGreaterThan(SemVer("2.1.0")!, SemVer("2.0.0")!) + XCTAssertGreaterThan(SemVer("2.1.1")!, SemVer("2.1.0")!) + XCTAssertGreaterThan(SemVer("12.0.0")!, SemVer("2.0.0")!) + + XCTAssertGreaterThan(SemVer("1.0.0")!, SemVer("1.0.0-alpha")!) + XCTAssertGreaterThan(SemVer("1.0.0-alpha.1")!, SemVer("1.0.0-alpha")!) + XCTAssertGreaterThan(SemVer("1.0.0-alpha.beta")!, SemVer("1.0.0-alpha.1")!) + XCTAssertGreaterThan(SemVer("1.0.0-beta")!, SemVer("1.0.0-alpha.1")!) + XCTAssertGreaterThan(SemVer("1.0.0-beta.2")!, SemVer("1.0.0-beta")!) + XCTAssertGreaterThan(SemVer("1.0.0-beta.11")!, SemVer("1.0.0-beta.2")!) + XCTAssertGreaterThan(SemVer("1.0.0-rc.1")!, SemVer("1.0.0-beta.11")!) + XCTAssertGreaterThan(SemVer("1.0.0")!, SemVer("1.0.0-rc.1")!) + + + // MARK: < + + XCTAssertTrue(SemVer("0.0.1")! < SemVer("0.1.0")!) + XCTAssertTrue(SemVer("0.0.99999")! < SemVer("0.1.0")!) + XCTAssertTrue(SemVer("0.0.1")! < SemVer("1.0.0")!) + XCTAssertTrue(SemVer("0.1.0")! < SemVer("1.0.0")!) + XCTAssertTrue(SemVer("0.0.1")! < SemVer("1.1.0")!) + XCTAssertTrue(SemVer("0.1.0")! < SemVer("1.1.0")!) + XCTAssertTrue(SemVer("0.1.1")! < SemVer("1.1.0")!) + XCTAssertTrue(SemVer("1.0.0")! < SemVer("2.0.0")!) + XCTAssertTrue(SemVer("2.0.0")! < SemVer("2.1.0")!) + XCTAssertTrue(SemVer("2.1.0")! < SemVer("2.1.1")!) + XCTAssertTrue(SemVer("2.0.0")! < SemVer("12.0.0")!) + + XCTAssertFalse(SemVer("0.0.1")! > SemVer("0.1.0")!) + XCTAssertFalse(SemVer("0.0.99999")! > SemVer("0.1.0")!) + XCTAssertFalse(SemVer("0.0.1")! > SemVer("1.0.0")!) + XCTAssertFalse(SemVer("0.1.0")! > SemVer("1.0.0")!) + XCTAssertFalse(SemVer("0.0.1")! > SemVer("1.1.0")!) + XCTAssertFalse(SemVer("0.1.0")! > SemVer("1.1.0")!) + XCTAssertFalse(SemVer("0.1.1")! > SemVer("1.1.0")!) + XCTAssertFalse(SemVer("1.0.0")! > SemVer("2.0.0")!) + XCTAssertFalse(SemVer("2.0.0")! > SemVer("2.1.0")!) + XCTAssertFalse(SemVer("2.1.0")! > SemVer("2.1.1")!) + XCTAssertFalse(SemVer("2.0.0")! > SemVer("12.0.0")!) + + XCTAssertTrue(SemVer("1.0.0-alpha")! < SemVer("1.0.0")!) + XCTAssertTrue(SemVer("1.0.0-alpha")! < SemVer("1.0.0-alpha.1")!) + XCTAssertTrue(SemVer("1.0.0-alpha.1")! < SemVer("1.0.0-alpha.beta")!) + XCTAssertTrue(SemVer("1.0.0-alpha.1")! < SemVer("1.0.0-beta")!) + XCTAssertTrue(SemVer("1.0.0-beta")! < SemVer("1.0.0-beta.2")!) + XCTAssertTrue(SemVer("1.0.0-beta.2")! < SemVer("1.0.0-beta.11")!) + XCTAssertTrue(SemVer("1.0.0-beta.11")! < SemVer("1.0.0-rc.1")!) + XCTAssertTrue(SemVer("1.0.0-rc.1")! < SemVer("1.0.0")!) + + XCTAssertFalse(SemVer("1.0.0-alpha")! > SemVer("1.0.0")!) + XCTAssertFalse(SemVer("1.0.0-alpha")! > SemVer("1.0.0-alpha.1")!) + XCTAssertFalse(SemVer("1.0.0-alpha.1")! > SemVer("1.0.0-alpha.beta")!) + XCTAssertFalse(SemVer("1.0.0-alpha.1")! > SemVer("1.0.0-beta")!) + XCTAssertFalse(SemVer("1.0.0-beta")! > SemVer("1.0.0-beta.2")!) + XCTAssertFalse(SemVer("1.0.0-beta.2")! > SemVer("1.0.0-beta.11")!) + XCTAssertFalse(SemVer("1.0.0-beta.11")! > SemVer("1.0.0-rc.1")!) + XCTAssertFalse(SemVer("1.0.0-rc.1")! > SemVer("1.0.0")!) + + // MARK: > + + XCTAssertTrue(SemVer("0.1.0")! > SemVer("0.0.1")!) + XCTAssertTrue(SemVer("0.1.0")! > SemVer("0.0.99999")!) + XCTAssertTrue(SemVer("1.0.0")! > SemVer("0.0.1")!) + XCTAssertTrue(SemVer("1.0.0")! > SemVer("0.1.0")!) + XCTAssertTrue(SemVer("1.1.0")! > SemVer("0.0.1")!) + XCTAssertTrue(SemVer("1.1.0")! > SemVer("0.1.0")!) + XCTAssertTrue(SemVer("1.1.0")! > SemVer("0.1.1")!) + XCTAssertTrue(SemVer("2.0.0")! > SemVer("1.0.0")!) + XCTAssertTrue(SemVer("2.1.0")! > SemVer("2.0.0")!) + XCTAssertTrue(SemVer("2.1.1")! > SemVer("2.1.0")!) + XCTAssertTrue(SemVer("12.0.0")! > SemVer("2.0.0")!) + + XCTAssertFalse(SemVer("0.1.0")! < SemVer("0.0.1")!) + XCTAssertFalse(SemVer("0.1.0")! < SemVer("0.0.99999")!) + XCTAssertFalse(SemVer("1.0.0")! < SemVer("0.0.1")!) + XCTAssertFalse(SemVer("1.0.0")! < SemVer("0.1.0")!) + XCTAssertFalse(SemVer("1.1.0")! < SemVer("0.0.1")!) + XCTAssertFalse(SemVer("1.1.0")! < SemVer("0.1.0")!) + XCTAssertFalse(SemVer("1.1.0")! < SemVer("0.1.1")!) + XCTAssertFalse(SemVer("2.0.0")! < SemVer("1.0.0")!) + XCTAssertFalse(SemVer("2.1.0")! < SemVer("2.0.0")!) + XCTAssertFalse(SemVer("2.1.1")! < SemVer("2.1.0")!) + XCTAssertFalse(SemVer("12.0.0")! < SemVer("2.0.0")!) + + XCTAssertTrue(SemVer("1.0.0")! > SemVer("1.0.0-alpha")!) + XCTAssertTrue(SemVer("1.0.0-alpha.1")! > SemVer("1.0.0-alpha")!) + XCTAssertTrue(SemVer("1.0.0-alpha.beta")! > SemVer("1.0.0-alpha.1")!) + XCTAssertTrue(SemVer("1.0.0-beta")! > SemVer("1.0.0-alpha.1")!) + XCTAssertTrue(SemVer("1.0.0-beta.2")! > SemVer("1.0.0-beta")!) + XCTAssertTrue(SemVer("1.0.0-beta.11")! > SemVer("1.0.0-beta.2")!) + XCTAssertTrue(SemVer("1.0.0-rc.1")! > SemVer("1.0.0-beta.11")!) + XCTAssertTrue(SemVer("1.0.0")! > SemVer("1.0.0-rc.1")!) + + XCTAssertFalse(SemVer("1.0.0")! < SemVer("1.0.0-alpha")!) + XCTAssertFalse(SemVer("1.0.0-alpha.1")! < SemVer("1.0.0-alpha")!) + XCTAssertFalse(SemVer("1.0.0-alpha.beta")! < SemVer("1.0.0-alpha.1")!) + XCTAssertFalse(SemVer("1.0.0-beta")! < SemVer("1.0.0-alpha.1")!) + XCTAssertFalse(SemVer("1.0.0-beta.2")! < SemVer("1.0.0-beta")!) + XCTAssertFalse(SemVer("1.0.0-beta.11")! < SemVer("1.0.0-beta.2")!) + XCTAssertFalse(SemVer("1.0.0-rc.1")! < SemVer("1.0.0-beta.11")!) + XCTAssertFalse(SemVer("1.0.0")! < SemVer("1.0.0-rc.1")!) + + + // MARK: Proof of fix of #7 + // https://github.com/RougeWare/Swift-SemVer/issues/7 + XCTAssertTrue(SemVer(10,0,0)! < SemVer(11,0,0)!) + XCTAssertTrue(SemVer(11,0,0)! > SemVer(10,0,0)!) + + XCTAssertFalse(SemVer(10,0,0)! > SemVer(11,0,0)!) + XCTAssertFalse(SemVer(11,0,0)! < SemVer(10,0,0)!) + } + + + + // MARK: - Equivalence + + func testEquivalence() { + XCTAssertEqual(SemVer(major: 1, minor: 0, patch: 0), SemVer(major: 1, minor: 0, patch: 0)) + XCTAssertEqual(SemVer("1.0.0"), SemVer(major: 1, minor: 0, patch: 0)) + XCTAssertEqual(SemVer("1.0.0"), SemVer("1.0.0")) + // According to https://semver.org/spec/v2.0.0.html#spec-item-11, "Build metadata does not figure into precedence" + XCTAssertEqual(SemVer("1.0+543"), SemVer("1.0+345")) + XCTAssertEqual(SemVer(major: 2, minor: 0, patch: 0, preRelease: ["RC", 1]), SemVer(2,0,0, preRelease: ["RC",1])) + XCTAssertEqual(SemVer(2,0,0, preRelease: ["RC",1]), SemVer("2.0.0-RC.1")) + XCTAssertEqual(SemVer("2.0.0-RC.1"), SemVer("2.0.0-RC.1")) + XCTAssertEqual(SemVer("2.0.0-RC.1+543"), SemVer(major: 2, minor: 0, patch: 0, preRelease: ["RC", 1], build: 543)) + XCTAssertEqual(SemVer("2.0.0-RC.1+543"), SemVer(major: 2, minor: 0, patch: 0, preRelease: ["RC", 1], build: "543")) + XCTAssertEqual(SemVer("2.0.0-RC.1+543"), SemVer(major: 2, minor: 0, patch: 0, preRelease: ["RC", 1], build: [543])) + XCTAssertEqual(SemVer("2.0.0-RC.1+543"), SemVer(major: 2, minor: 0, patch: 0, preRelease: ["RC", 1], build: ["543"])) + } + + + func testAdvancedEquality() { + XCTAssertEqual(SemVer(1,2,3), SemVer("1.2.3")) + XCTAssertEqual(SemVer(1,2,3), SemVer("1.2.3+12")) + XCTAssertEqual(SemVer(1,2,3, build: 12), SemVer("1.2.3")) + XCTAssertEqual(SemVer(1,2,3, build: 12), SemVer(1,2,3)) + XCTAssertEqual(SemVer(1,2,3, build: 12), SemVer("1.2.3+12")) + } + + + + // MARK: - Ignoring components + + // MARK: Pre-Release + + func testCompareIgnoringPreRelease() { + XCTAssertTrue(SemVer(0,0,3).matches(SemVer(0,0,3), ignoring: .preRelease)) + XCTAssertTrue(SemVer(0,2,3).matches(SemVer(0,2,3), ignoring: .preRelease)) + XCTAssertTrue(SemVer(1,2,3).matches(SemVer(1,2,3), ignoring: .preRelease)) + XCTAssertTrue(SemVer("1.2.3-Beta")!.matches(SemVer(1,2,3), ignoring: .preRelease)) + XCTAssertTrue(SemVer("1.2.3-Beta")!.matches(SemVer("1.2.3-Alpha")!, ignoring: .preRelease)) + } + + + func testCompareIgnoringPatch() { + XCTAssertTrue(SemVer(0,0,3).matches(SemVer(0,0,3), ignoring: .patchAndPreRelease)) + XCTAssertTrue(SemVer(0,2,3).matches(SemVer(0,2,3), ignoring: .patchAndPreRelease)) + XCTAssertTrue(SemVer(1,2,3).matches(SemVer(1,2,3), ignoring: .patchAndPreRelease)) + + XCTAssertTrue(SemVer(1,2,3, preRelease: "Beta")!.matches(SemVer(1,2,0), ignoring: .patchAndPreRelease)) + XCTAssertTrue(SemVer(1,2,3, preRelease: "Beta")!.matches(SemVer(1,2,3), ignoring: .patchAndPreRelease)) + XCTAssertTrue(SemVer(1,2,3, preRelease: "Beta")!.matches(SemVer(1,2,99), ignoring: .patchAndPreRelease)) + XCTAssertTrue(SemVer(1,2,99, preRelease: "Beta")!.matches(SemVer(1,2,3), ignoring: .patchAndPreRelease)) + + XCTAssertTrue(SemVer(1,2,3, preRelease: "Beta")!.matches(SemVer(1,2,0, preRelease: "Alpha")!, ignoring: .patchAndPreRelease)) + XCTAssertTrue(SemVer(1,2,3, preRelease: "Beta")!.matches(SemVer(1,2,3, preRelease: "Alpha")!, ignoring: .patchAndPreRelease)) + } + + + func testCompareIgnoringMinor() { + XCTAssertTrue(SemVer(0,0,3).matches(SemVer(0,0,3), ignoring: .minorAndPatchAndPreRelease)) + XCTAssertTrue(SemVer(0,2,3).matches(SemVer(0,2,3), ignoring: .minorAndPatchAndPreRelease)) + XCTAssertTrue(SemVer(1,2,3).matches(SemVer(1,2,3), ignoring: .minorAndPatchAndPreRelease)) + + XCTAssertTrue(SemVer(1,2,3, preRelease: "Beta")!.matches(SemVer(1,0,0), ignoring: .minorAndPatchAndPreRelease)) + XCTAssertTrue(SemVer(1,2,3, preRelease: "Beta")!.matches(SemVer(1,2,0), ignoring: .minorAndPatchAndPreRelease)) + XCTAssertTrue(SemVer(1,2,3, preRelease: "Beta")!.matches(SemVer(1,2,3), ignoring: .minorAndPatchAndPreRelease)) + XCTAssertTrue(SemVer(1,2,3, preRelease: "Beta")!.matches(SemVer(1,99,99), ignoring: .minorAndPatchAndPreRelease)) + XCTAssertTrue(SemVer(1,99,99, preRelease: "Beta")!.matches(SemVer(1,2,3), ignoring: .minorAndPatchAndPreRelease)) + + XCTAssertTrue(SemVer(1,2,3, preRelease: "Beta")!.matches(SemVer(1,0,0, preRelease: "Alpha")!, ignoring: .minorAndPatchAndPreRelease)) + XCTAssertTrue(SemVer(1,2,3, preRelease: "Beta")!.matches(SemVer(1,2,0, preRelease: "Alpha")!, ignoring: .minorAndPatchAndPreRelease)) + XCTAssertTrue(SemVer(1,2,3, preRelease: "Beta")!.matches(SemVer(1,2,3, preRelease: "Alpha")!, ignoring: .minorAndPatchAndPreRelease)) + } + + + + static let allTests = [ + ("testPrecedence", testPrecedence), + ("testEquivalence", testEquivalence), + ("testAdvancedEquality", testAdvancedEquality), + ("testCompareIgnoringPreRelease", testCompareIgnoringPreRelease), + ("testCompareIgnoringPatch", testCompareIgnoringPatch), + ("testCompareIgnoringMinor", testCompareIgnoringMinor), + ] +} + diff --git a/Tests/SemVerTests/SemVerTests.swift b/Tests/SemVerTests/SemVerTests.swift index be3f6ac..5a767e4 100644 --- a/Tests/SemVerTests/SemVerTests.swift +++ b/Tests/SemVerTests/SemVerTests.swift @@ -41,169 +41,6 @@ class SemVerTests: SemVerTestClass { // MARK: - Precedence - func testPrecedence() { - - // MARK: Less than - - XCTAssertLessThan(SemVer("0.0.1")!, SemVer("0.1.0")!) - XCTAssertLessThan(SemVer("0.0.99999")!, SemVer("0.1.0")!) - XCTAssertLessThan(SemVer("0.0.1")!, SemVer("1.0.0")!) - XCTAssertLessThan(SemVer("0.1.0")!, SemVer("1.0.0")!) - XCTAssertLessThan(SemVer("0.0.1")!, SemVer("1.1.0")!) - XCTAssertLessThan(SemVer("0.1.0")!, SemVer("1.1.0")!) - XCTAssertLessThan(SemVer("0.1.1")!, SemVer("1.1.0")!) - XCTAssertLessThan(SemVer("1.0.0")!, SemVer("2.0.0")!) - XCTAssertLessThan(SemVer("2.0.0")!, SemVer("2.1.0")!) - XCTAssertLessThan(SemVer("2.1.0")!, SemVer("2.1.1")!) - XCTAssertLessThan(SemVer("2.0.0")!, SemVer("12.0.0")!) - - XCTAssertLessThan(SemVer("1.0.0-alpha")!, SemVer("1.0.0")!) - XCTAssertLessThan(SemVer("1.0.0-alpha")!, SemVer("1.0.0-alpha.1")!) - XCTAssertLessThan(SemVer("1.0.0-alpha.1")!, SemVer("1.0.0-alpha.beta")!) - XCTAssertLessThan(SemVer("1.0.0-alpha.1")!, SemVer("1.0.0-beta")!) - XCTAssertLessThan(SemVer("1.0.0-beta")!, SemVer("1.0.0-beta.2")!) - XCTAssertLessThan(SemVer("1.0.0-beta.2")!, SemVer("1.0.0-beta.11")!) - XCTAssertLessThan(SemVer("1.0.0-beta.11")!, SemVer("1.0.0-rc.1")!) - XCTAssertLessThan(SemVer("1.0.0-rc.1")!, SemVer("1.0.0")!) - - // MARK: Greater than - - XCTAssertGreaterThan(SemVer("0.1.0")!, SemVer("0.0.1")!) - XCTAssertGreaterThan(SemVer("0.1.0")!, SemVer("0.0.99999")!) - XCTAssertGreaterThan(SemVer("1.0.0")!, SemVer("0.0.1")!) - XCTAssertGreaterThan(SemVer("1.0.0")!, SemVer("0.1.0")!) - XCTAssertGreaterThan(SemVer("1.1.0")!, SemVer("0.0.1")!) - XCTAssertGreaterThan(SemVer("1.1.0")!, SemVer("0.1.0")!) - XCTAssertGreaterThan(SemVer("1.1.0")!, SemVer("0.1.1")!) - XCTAssertGreaterThan(SemVer("2.0.0")!, SemVer("1.0.0")!) - XCTAssertGreaterThan(SemVer("2.1.0")!, SemVer("2.0.0")!) - XCTAssertGreaterThan(SemVer("2.1.1")!, SemVer("2.1.0")!) - XCTAssertGreaterThan(SemVer("12.0.0")!, SemVer("2.0.0")!) - - XCTAssertGreaterThan(SemVer("1.0.0")!, SemVer("1.0.0-alpha")!) - XCTAssertGreaterThan(SemVer("1.0.0-alpha.1")!, SemVer("1.0.0-alpha")!) - XCTAssertGreaterThan(SemVer("1.0.0-alpha.beta")!, SemVer("1.0.0-alpha.1")!) - XCTAssertGreaterThan(SemVer("1.0.0-beta")!, SemVer("1.0.0-alpha.1")!) - XCTAssertGreaterThan(SemVer("1.0.0-beta.2")!, SemVer("1.0.0-beta")!) - XCTAssertGreaterThan(SemVer("1.0.0-beta.11")!, SemVer("1.0.0-beta.2")!) - XCTAssertGreaterThan(SemVer("1.0.0-rc.1")!, SemVer("1.0.0-beta.11")!) - XCTAssertGreaterThan(SemVer("1.0.0")!, SemVer("1.0.0-rc.1")!) - - - // MARK: < - - XCTAssertTrue(SemVer("0.0.1")! < SemVer("0.1.0")!) - XCTAssertTrue(SemVer("0.0.99999")! < SemVer("0.1.0")!) - XCTAssertTrue(SemVer("0.0.1")! < SemVer("1.0.0")!) - XCTAssertTrue(SemVer("0.1.0")! < SemVer("1.0.0")!) - XCTAssertTrue(SemVer("0.0.1")! < SemVer("1.1.0")!) - XCTAssertTrue(SemVer("0.1.0")! < SemVer("1.1.0")!) - XCTAssertTrue(SemVer("0.1.1")! < SemVer("1.1.0")!) - XCTAssertTrue(SemVer("1.0.0")! < SemVer("2.0.0")!) - XCTAssertTrue(SemVer("2.0.0")! < SemVer("2.1.0")!) - XCTAssertTrue(SemVer("2.1.0")! < SemVer("2.1.1")!) - XCTAssertTrue(SemVer("2.0.0")! < SemVer("12.0.0")!) - - XCTAssertFalse(SemVer("0.0.1")! > SemVer("0.1.0")!) - XCTAssertFalse(SemVer("0.0.99999")! > SemVer("0.1.0")!) - XCTAssertFalse(SemVer("0.0.1")! > SemVer("1.0.0")!) - XCTAssertFalse(SemVer("0.1.0")! > SemVer("1.0.0")!) - XCTAssertFalse(SemVer("0.0.1")! > SemVer("1.1.0")!) - XCTAssertFalse(SemVer("0.1.0")! > SemVer("1.1.0")!) - XCTAssertFalse(SemVer("0.1.1")! > SemVer("1.1.0")!) - XCTAssertFalse(SemVer("1.0.0")! > SemVer("2.0.0")!) - XCTAssertFalse(SemVer("2.0.0")! > SemVer("2.1.0")!) - XCTAssertFalse(SemVer("2.1.0")! > SemVer("2.1.1")!) - XCTAssertFalse(SemVer("2.0.0")! > SemVer("12.0.0")!) - - XCTAssertTrue(SemVer("1.0.0-alpha")! < SemVer("1.0.0")!) - XCTAssertTrue(SemVer("1.0.0-alpha")! < SemVer("1.0.0-alpha.1")!) - XCTAssertTrue(SemVer("1.0.0-alpha.1")! < SemVer("1.0.0-alpha.beta")!) - XCTAssertTrue(SemVer("1.0.0-alpha.1")! < SemVer("1.0.0-beta")!) - XCTAssertTrue(SemVer("1.0.0-beta")! < SemVer("1.0.0-beta.2")!) - XCTAssertTrue(SemVer("1.0.0-beta.2")! < SemVer("1.0.0-beta.11")!) - XCTAssertTrue(SemVer("1.0.0-beta.11")! < SemVer("1.0.0-rc.1")!) - XCTAssertTrue(SemVer("1.0.0-rc.1")! < SemVer("1.0.0")!) - - XCTAssertFalse(SemVer("1.0.0-alpha")! > SemVer("1.0.0")!) - XCTAssertFalse(SemVer("1.0.0-alpha")! > SemVer("1.0.0-alpha.1")!) - XCTAssertFalse(SemVer("1.0.0-alpha.1")! > SemVer("1.0.0-alpha.beta")!) - XCTAssertFalse(SemVer("1.0.0-alpha.1")! > SemVer("1.0.0-beta")!) - XCTAssertFalse(SemVer("1.0.0-beta")! > SemVer("1.0.0-beta.2")!) - XCTAssertFalse(SemVer("1.0.0-beta.2")! > SemVer("1.0.0-beta.11")!) - XCTAssertFalse(SemVer("1.0.0-beta.11")! > SemVer("1.0.0-rc.1")!) - XCTAssertFalse(SemVer("1.0.0-rc.1")! > SemVer("1.0.0")!) - - // MARK: > - - XCTAssertTrue(SemVer("0.1.0")! > SemVer("0.0.1")!) - XCTAssertTrue(SemVer("0.1.0")! > SemVer("0.0.99999")!) - XCTAssertTrue(SemVer("1.0.0")! > SemVer("0.0.1")!) - XCTAssertTrue(SemVer("1.0.0")! > SemVer("0.1.0")!) - XCTAssertTrue(SemVer("1.1.0")! > SemVer("0.0.1")!) - XCTAssertTrue(SemVer("1.1.0")! > SemVer("0.1.0")!) - XCTAssertTrue(SemVer("1.1.0")! > SemVer("0.1.1")!) - XCTAssertTrue(SemVer("2.0.0")! > SemVer("1.0.0")!) - XCTAssertTrue(SemVer("2.1.0")! > SemVer("2.0.0")!) - XCTAssertTrue(SemVer("2.1.1")! > SemVer("2.1.0")!) - XCTAssertTrue(SemVer("12.0.0")! > SemVer("2.0.0")!) - - XCTAssertFalse(SemVer("0.1.0")! < SemVer("0.0.1")!) - XCTAssertFalse(SemVer("0.1.0")! < SemVer("0.0.99999")!) - XCTAssertFalse(SemVer("1.0.0")! < SemVer("0.0.1")!) - XCTAssertFalse(SemVer("1.0.0")! < SemVer("0.1.0")!) - XCTAssertFalse(SemVer("1.1.0")! < SemVer("0.0.1")!) - XCTAssertFalse(SemVer("1.1.0")! < SemVer("0.1.0")!) - XCTAssertFalse(SemVer("1.1.0")! < SemVer("0.1.1")!) - XCTAssertFalse(SemVer("2.0.0")! < SemVer("1.0.0")!) - XCTAssertFalse(SemVer("2.1.0")! < SemVer("2.0.0")!) - XCTAssertFalse(SemVer("2.1.1")! < SemVer("2.1.0")!) - XCTAssertFalse(SemVer("12.0.0")! < SemVer("2.0.0")!) - - XCTAssertTrue(SemVer("1.0.0")! > SemVer("1.0.0-alpha")!) - XCTAssertTrue(SemVer("1.0.0-alpha.1")! > SemVer("1.0.0-alpha")!) - XCTAssertTrue(SemVer("1.0.0-alpha.beta")! > SemVer("1.0.0-alpha.1")!) - XCTAssertTrue(SemVer("1.0.0-beta")! > SemVer("1.0.0-alpha.1")!) - XCTAssertTrue(SemVer("1.0.0-beta.2")! > SemVer("1.0.0-beta")!) - XCTAssertTrue(SemVer("1.0.0-beta.11")! > SemVer("1.0.0-beta.2")!) - XCTAssertTrue(SemVer("1.0.0-rc.1")! > SemVer("1.0.0-beta.11")!) - XCTAssertTrue(SemVer("1.0.0")! > SemVer("1.0.0-rc.1")!) - - XCTAssertFalse(SemVer("1.0.0")! < SemVer("1.0.0-alpha")!) - XCTAssertFalse(SemVer("1.0.0-alpha.1")! < SemVer("1.0.0-alpha")!) - XCTAssertFalse(SemVer("1.0.0-alpha.beta")! < SemVer("1.0.0-alpha.1")!) - XCTAssertFalse(SemVer("1.0.0-beta")! < SemVer("1.0.0-alpha.1")!) - XCTAssertFalse(SemVer("1.0.0-beta.2")! < SemVer("1.0.0-beta")!) - XCTAssertFalse(SemVer("1.0.0-beta.11")! < SemVer("1.0.0-beta.2")!) - XCTAssertFalse(SemVer("1.0.0-rc.1")! < SemVer("1.0.0-beta.11")!) - XCTAssertFalse(SemVer("1.0.0")! < SemVer("1.0.0-rc.1")!) - - - // MARK: Proof of fix of #7 - // https://github.com/RougeWare/Swift-SemVer/issues/7 - XCTAssertTrue(SemVer(10,0,0)! < SemVer(11,0,0)!) - XCTAssertTrue(SemVer(11,0,0)! > SemVer(10,0,0)!) - - XCTAssertFalse(SemVer(10,0,0)! > SemVer(11,0,0)!) - XCTAssertFalse(SemVer(11,0,0)! < SemVer(10,0,0)!) - } - - - func testEquivalence() { - XCTAssertEqual(SemVer(major: 1, minor: 0, patch: 0), SemVer(major: 1, minor: 0, patch: 0)) - XCTAssertEqual(SemVer("1.0.0"), SemVer(major: 1, minor: 0, patch: 0)) - XCTAssertEqual(SemVer("1.0.0"), SemVer("1.0.0")) - // According to https://semver.org/spec/v2.0.0.html#spec-item-11, "Build metadata does not figure into precedence" - XCTAssertEqual(SemVer("1.0+543"), SemVer("1.0+345")) - XCTAssertEqual(SemVer(major: 2, minor: 0, patch: 0, preRelease: ["RC", 1]), SemVer(2,0,0, preRelease: ["RC",1])) - XCTAssertEqual(SemVer(2,0,0, preRelease: ["RC",1]), SemVer("2.0.0-RC.1")) - XCTAssertEqual(SemVer("2.0.0-RC.1"), SemVer("2.0.0-RC.1")) - XCTAssertEqual(SemVer("2.0.0-RC.1+543"), SemVer(major: 2, minor: 0, patch: 0, preRelease: ["RC", 1], build: 543)) - XCTAssertEqual(SemVer("2.0.0-RC.1+543"), SemVer(major: 2, minor: 0, patch: 0, preRelease: ["RC", 1], build: "543")) - XCTAssertEqual(SemVer("2.0.0-RC.1+543"), SemVer(major: 2, minor: 0, patch: 0, preRelease: ["RC", 1], build: [543])) - XCTAssertEqual(SemVer("2.0.0-RC.1+543"), SemVer(major: 2, minor: 0, patch: 0, preRelease: ["RC", 1], build: ["543"])) - } - func testInvalid() { XCTAssertNil(SemVer("Obviously Bad")) @@ -231,21 +68,10 @@ class SemVerTests: SemVerTestClass { } - func testAdvancedEquality() { - XCTAssertEqual(SemVer(1,2,3), SemVer("1.2.3")) - XCTAssertEqual(SemVer(1,2,3), SemVer("1.2.3+12")) - XCTAssertEqual(SemVer(1,2,3, build: 12), SemVer("1.2.3")) - XCTAssertEqual(SemVer(1,2,3, build: 12), SemVer(1,2,3)) - XCTAssertEqual(SemVer(1,2,3, build: 12), SemVer("1.2.3+12")) - } - static let allTests = [ ("testDescription", testDescription), ("testFromString", testFromString), - ("testPrecedence", testPrecedence), - ("testEquivalence", testEquivalence), ("testInvalid", testInvalid), - ("testAdvancedEquality", testAdvancedEquality), ] } diff --git a/Tests/SemVerTests/XCTestManifests.swift b/Tests/SemVerTests/XCTestManifests.swift index 3911b09..ef5ef5a 100644 --- a/Tests/SemVerTests/XCTestManifests.swift +++ b/Tests/SemVerTests/XCTestManifests.swift @@ -8,6 +8,7 @@ public func allTests() -> [XCTestCaseEntry] { testCase(SemVerTests.allTests), testCase(SemVerHashableTests.allTests), testCase(SemVerMutationTests.allTests), + testCase(SemVerComparableTests.allTests), ] } #endif From ab7a8fe9a7686424b4f2bcce3ad0b752354df43e Mon Sep 17 00:00:00 2001 From: Ben Leggiero Date: Mon, 25 Oct 2021 16:11:23 -0600 Subject: [PATCH 2/2] Janitorial work - Updated README - Noted test-proven SemVer implementation - Added examples of subtly-bad semantic versions - Added note about `Codable` conformance - Updated header comments - Added missing watchOS platform - Added `SemVerCodableTests` to non-Xcode test files - Added tests checking subtly-wrong SemVer strings --- Package.swift | 1 + README.md | 25 +++++++++++++------ .../SemVer/Semantic Version + Codable.swift | 1 + Tests/LinuxMain.swift | 1 + Tests/SemVerTests/SemVer+Codable Tests.swift | 10 +++++++- Tests/SemVerTests/SemVer+Hashable Tests.swift | 2 +- Tests/SemVerTests/SemVerTests.swift | 3 +++ Tests/SemVerTests/XCTestManifests.swift | 1 + 8 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Package.swift b/Package.swift index a3406f2..d53edfe 100644 --- a/Package.swift +++ b/Package.swift @@ -9,6 +9,7 @@ let package = Package( .macOS(.v10_10), .iOS(.v11), .tvOS(.v11), + .watchOS(.v4), ], products: [ // Products define the executables and libraries produced by a package, and make them visible to other packages. diff --git a/README.md b/README.md index 76f52dd..f7b6aa1 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,22 @@ # Swift Semantic Versioning # -A small library that implements [SemVer 2.0.0](https://semver.org/spec/v2.0.0.html), which is copyrighted to Tom Preston-Werner CC BY 3.0. This is designed to be simple to use and to easily fit into any Swift codebase. +A small library that perfectly implements [SemVer 2.0.0](https://semver.org/spec/v2.0.0.html), which is copyrighted to Tom Preston-Werner CC BY 3.0. This is designed to be simple to use and to easily fit into any Swift codebase. This is designed to be as easy as possible to use. You may use the extremely-verbose and explicit initializer which labels every parameter, or the one that does the same thing but excludes the labels, or the one that simply takes any valid SemVer string and gently fails to `nil` if that string is invalid. You are encouraged to use whichever one of these suits the needs at the time of use. Some examples are included in the unit tests. -Keep in mind that the pre-release and build extensions can be easily represented as string- and integer-literals. For instance, `SemVer(1,2,0, SemVer.Build(identifiers: ["123", "4"]))` has the same result as `SemVer(1,2,0, "123.4")` and `SemVer(1,2,0, [123,4])`. Again, this is done for ease-of-use. `SemVer` itself would also be expressible by a string literal, but it has too many resrictions so a failable initializer is presented instead. +Keep in mind that the pre-release and build extensions can be easily represented as string- and integer-literals. For instance, `SemVer(1,2,0, build: SemVer.Build(identifiers: ["123", "4"]))` has the same result as `SemVer(1,2,0, build: "123.4")` and `SemVer(1,2,0, build: [123,4])`. Again, this is done for ease-of-use. `SemVer` itself would also be expressible by a string literal, but it has too many resrictions so a failable initializer conforming to `LosslessStringConvertible` is presented instead, just like `Int`. -This also already conforms to `Comparable`, since comparison and precedence are a major part of the spec. +This also already conforms to `Comparable` since comparison and precedence are a major part of the spec, and to `Codable` since the encoding of semantic versions is clear and simple. -# Examples # + +## Proven Strong ## + +[`500` test assertions](./Tests/SemVerTests) prove that this library behaves precisely as described, conforming completely to the SemVer 2.0.0 spec. + + + +## Examples ## + Let's say you have a release candidate of version 2.0.0 of your app. The following are all equivalent: ```swift @@ -34,21 +42,24 @@ a `nil` object: nil == SemVer("Obviously Bad") nil == SemVer("1") nil == SemVer("1.2") -nil == SemVer("-2.0") +nil == SemVer("-2.0.0") nil == SemVer("2.0-β") nil == SemVer("2.0-beta_1") nil == SemVer("1.-2") nil == SemVer("1.2.-3") nil == SemVer("1.2.3.4") +nil == SemVer("1.2.3-😱") ``` -# License # + +## License ## + This is licensed under [BH-1-PS](https://github.com/BlueHuskyStudios/Licenses/blob/master/Licenses/BH-1-PS.txt). -# Requirements # +## Requirements ## This package requires: - Swift 5.1 or newer diff --git a/Sources/SemVer/Semantic Version + Codable.swift b/Sources/SemVer/Semantic Version + Codable.swift index c63a395..63571e2 100644 --- a/Sources/SemVer/Semantic Version + Codable.swift +++ b/Sources/SemVer/Semantic Version + Codable.swift @@ -3,6 +3,7 @@ // SemVer // // Created by Ky Leggiero on 2021-10-18. +// Copyright © 2021 Ben "Ky" Leggiero BH-1-PS. // import Foundation diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index 298fd88..2a4bcf7 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -7,4 +7,5 @@ isTesting = true XCTMain(SemVerTests.allTests + SemVerHashableTests.allTests + SemVerMutationTests.allTests + + SemVerCodableTests.allTests + SemVerComparableTests.allTests) diff --git a/Tests/SemVerTests/SemVer+Codable Tests.swift b/Tests/SemVerTests/SemVer+Codable Tests.swift index 866f21a..4641bc2 100644 --- a/Tests/SemVerTests/SemVer+Codable Tests.swift +++ b/Tests/SemVerTests/SemVer+Codable Tests.swift @@ -1,6 +1,6 @@ // // SemVer+Codable Tests.swift -// +// SemVerTests // // Created by Ky Leggiero on 2021-10-18. // @@ -89,6 +89,14 @@ class SemVerCodableTests: SemVerTestClass { XCTAssertEqual(SemVer(01,2,3, preRelease: ["RC","4"], build: [567])!, try encodeDecode(SemVer(01,2,3, preRelease: ["RC","4"], build: [567])!)) XCTAssertEqual(SemVer("1.2.3-RC.4+567")!, try encodeDecode(SemVer("1.2.3-RC.4+567")!)) } + + + + static let allTests = [ + ("testEncode", testEncode), + ("testDecode", testDecode), + ("testEncodeDecode", testEncodeDecode), + ] } diff --git a/Tests/SemVerTests/SemVer+Hashable Tests.swift b/Tests/SemVerTests/SemVer+Hashable Tests.swift index e1cfa38..53d0f2b 100644 --- a/Tests/SemVerTests/SemVer+Hashable Tests.swift +++ b/Tests/SemVerTests/SemVer+Hashable Tests.swift @@ -1,6 +1,6 @@ // // SemVer+Hashable Tests.swift -// SemVer +// SemVerTests // // Created by Ben Leggiero on 2020-04-19. // Copyright © 2021 Ben Leggiero BH-1-PS. diff --git a/Tests/SemVerTests/SemVerTests.swift b/Tests/SemVerTests/SemVerTests.swift index 5a767e4..8fbbbe9 100644 --- a/Tests/SemVerTests/SemVerTests.swift +++ b/Tests/SemVerTests/SemVerTests.swift @@ -51,11 +51,14 @@ class SemVerTests: SemVerTestClass { XCTAssertNil(SemVer("1.2-RC.4+567")) XCTAssertNil(SemVer("1.2-RC+567.8")) XCTAssertNil(SemVer("-2.0")) + XCTAssertNil(SemVer("-2.0.0")) XCTAssertNil(SemVer("2.0-β")) XCTAssertNil(SemVer("2.0-beta_1")) XCTAssertNil(SemVer("1.-2")) XCTAssertNil(SemVer("1.2.-3")) XCTAssertNil(SemVer("1.2.3.4")) + XCTAssertNil(SemVer("1.2.3-😱")) + XCTAssertNil(SemVer("1.2.3-semántice")) // Proof of fix of #14: https://github.com/RougeWare/Swift-SemVer/issues/14 XCTAssertNil(SemVer(1,0,0, preRelease: "01")) diff --git a/Tests/SemVerTests/XCTestManifests.swift b/Tests/SemVerTests/XCTestManifests.swift index ef5ef5a..205fc6b 100644 --- a/Tests/SemVerTests/XCTestManifests.swift +++ b/Tests/SemVerTests/XCTestManifests.swift @@ -8,6 +8,7 @@ public func allTests() -> [XCTestCaseEntry] { testCase(SemVerTests.allTests), testCase(SemVerHashableTests.allTests), testCase(SemVerMutationTests.allTests), + testCase(SemVerCodableTests.allTests), testCase(SemVerComparableTests.allTests), ] }