diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd86475..72dbd0f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: run-tests: strategy: matrix: - swift-version: [5.6, 5.7, 5.8, 5.9] + swift-version: [5.7, 5.8, 5.9] runs-on: ubuntu-20.04 steps: - uses: fwal/setup-swift@v1 diff --git a/Package.swift b/Package.swift index bf4aa0c..b456797 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.6 +// swift-tools-version:5.7 // Copyright Dave Verwer, Sven A. Schmidt, and other contributors. // @@ -18,6 +18,12 @@ import PackageDescription let package = Package( name: "SemanticVersion", + platforms: [ + .iOS(.v16), + .macOS(.v13), + .watchOS(.v9), + .tvOS(.v16), + ], products: [ .library( name: "SemanticVersion", diff --git a/Sources/SemanticVersion/NSRegularExpression+ext.swift b/Sources/SemanticVersion/NSRegularExpression+ext.swift deleted file mode 100644 index a7baa7a..0000000 --- a/Sources/SemanticVersion/NSRegularExpression+ext.swift +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright Dave Verwer, Sven A. Schmidt, and other contributors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import Foundation - - -extension NSRegularExpression { - convenience init(_ pattern: String, options: NSRegularExpression.Options) { - do { - try self.init(pattern: pattern, options: options) - } catch { - preconditionFailure("Illegal regular expression: \(pattern).") - } - } -} - - -extension NSRegularExpression { - func matches(_ string: String) -> Bool { - let range = NSRange(string.startIndex..., in: string) - return firstMatch(in: string, options: [], range: range) != nil - } - - func matchGroups(_ string: String, options: NSRegularExpression.Options = []) -> [String] { - let range = NSRange(string.startIndex..., in: string) - guard let match = firstMatch(in: string, options: [], range: range) else { return [] } - - // Skip over index 0 which is the range of the whole match - return (1...numberOfCaptureGroups).map { - if let r = Range(match.range(at: $0), in: string) { - return String(string[r]) - } else { - return "" - } - } - } -} diff --git a/Sources/SemanticVersion/SemanticVersion.swift b/Sources/SemanticVersion/SemanticVersion.swift index 2e72cf6..407f029 100644 --- a/Sources/SemanticVersion/SemanticVersion.swift +++ b/Sources/SemanticVersion/SemanticVersion.swift @@ -55,36 +55,14 @@ extension SemanticVersion: LosslessStringConvertible { /// Initialize a version from a string. Returns `nil` if the string is not a semantic version. /// - Parameter string: Version string. public init?(_ string: String) { -#if swift(>=5.7) - if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { - guard let match = string.wholeMatch(of: semVerPattern), - let major = Int(match.output.major), - let minor = Int(match.output.minor), - let patch = Int(match.output.patch) - else { return nil } - let preRelease = match.output.prerelease.flatMap({String($0)}) ?? "" - let build = match.output.buildmetadata.flatMap({String($0)}) ?? "" - self = .init(major, minor, patch, preRelease, build) - } else { - let groups = semVerRegex.matchGroups(string) - guard - groups.count == semVerRegex.numberOfCaptureGroups, - let major = Int(groups[0]), - let minor = Int(groups[1]), - let patch = Int(groups[2]) - else { return nil } - self = .init(major, minor, patch, groups[3], groups[4]) - } -#else - let groups = semVerRegex.matchGroups(string) - guard - groups.count == semVerRegex.numberOfCaptureGroups, - let major = Int(groups[0]), - let minor = Int(groups[1]), - let patch = Int(groups[2]) + guard let match = string.wholeMatch(of: semVerPattern), + let major = Int(match.output.major), + let minor = Int(match.output.minor), + let patch = Int(match.output.patch) else { return nil } - self = .init(major, minor, patch, groups[3], groups[4]) -#endif + let preRelease = match.output.prerelease.flatMap({String($0)}) ?? "" + let build = match.output.buildmetadata.flatMap({String($0)}) ?? "" + self = .init(major, minor, patch, preRelease, build) } public var description: String { @@ -186,10 +164,6 @@ extension SemanticVersion: Sendable {} // Linked from https://semver.org -#if swift(>=5) - -#if swift(>=5.7) -@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) let semVerPattern = ##/ ^ v? # SPI extension: allow leading 'v' @@ -213,56 +187,3 @@ v? # SPI extension: allow leading 'v' )? $ /## -#endif - -let semVerRegex = NSRegularExpression(#""" -^ -v? # SPI extension: allow leading 'v' -(?0|[1-9]\d*) -\. -(?0|[1-9]\d*) -\. -(?0|[1-9]\d*) -(?:- - (? - (?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*) - (?:\. - (?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*) - ) - *) -)? -(?:\+ - (?[0-9a-zA-Z-]+ - (?:\.[0-9a-zA-Z-]+) - *) -)? -$ -"""#, options: [.allowCommentsAndWhitespace]) - -#else - -let semVerRegex = NSRegularExpression(""" -^ -v? # SPI extension: allow leading 'v' -(?0|[1-9]\\d*) -\\. -(?0|[1-9]\\d*) -\\. -(?0|[1-9]\\d*) -(?:- - (? - (?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*) - (?:\\. - (?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*) - ) - *) -)? -(?:\\+ - (?[0-9a-zA-Z-]+ - (?:\\.[0-9a-zA-Z-]+) - *) -)? -$ -""", options: [.allowCommentsAndWhitespace]) - -#endif diff --git a/Tests/SemanticVersionTests/SemanticVersionTests.swift b/Tests/SemanticVersionTests/SemanticVersionTests.swift index 5766d60..e4ecdfc 100644 --- a/Tests/SemanticVersionTests/SemanticVersionTests.swift +++ b/Tests/SemanticVersionTests/SemanticVersionTests.swift @@ -17,177 +17,86 @@ import XCTest final class SemanticVersionTests: XCTestCase { - - func test_semVerRegex_valid() throws { - XCTAssert(semVerRegex.matches("0.0.4")) - XCTAssert(semVerRegex.matches("1.2.3")) - XCTAssert(semVerRegex.matches("10.20.30")) - XCTAssert(semVerRegex.matches("1.1.2-prerelease+meta")) - XCTAssert(semVerRegex.matches("1.1.2+meta")) - XCTAssert(semVerRegex.matches("1.1.2+meta-valid")) - XCTAssert(semVerRegex.matches("1.0.0-alpha")) - XCTAssert(semVerRegex.matches("1.0.0-beta")) - XCTAssert(semVerRegex.matches("1.0.0-alpha.beta")) - XCTAssert(semVerRegex.matches("1.0.0-alpha.beta.1")) - XCTAssert(semVerRegex.matches("1.0.0-alpha.1")) - XCTAssert(semVerRegex.matches("1.0.0-alpha0.valid")) - XCTAssert(semVerRegex.matches("1.0.0-alpha.0valid")) - XCTAssert(semVerRegex.matches("1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay")) - XCTAssert(semVerRegex.matches("1.0.0-rc.1+build.1")) - XCTAssert(semVerRegex.matches("2.0.0-rc.1+build.123")) - XCTAssert(semVerRegex.matches("1.2.3-beta")) - XCTAssert(semVerRegex.matches("10.2.3-DEV-SNAPSHOT")) - XCTAssert(semVerRegex.matches("1.2.3-SNAPSHOT-123")) - XCTAssert(semVerRegex.matches("1.0.0")) - XCTAssert(semVerRegex.matches("2.0.0")) - XCTAssert(semVerRegex.matches("1.1.7")) - XCTAssert(semVerRegex.matches("2.0.0+build.1848")) - XCTAssert(semVerRegex.matches("2.0.1-alpha.1227")) - XCTAssert(semVerRegex.matches("1.0.0-alpha+beta")) - XCTAssert(semVerRegex.matches("1.2.3----RC-SNAPSHOT.12.9.1--.12+788")) - XCTAssert(semVerRegex.matches("1.2.3----R-S.12.9.1--.12+meta")) - XCTAssert(semVerRegex.matches("1.2.3----RC-SNAPSHOT.12.9.1--.12")) - XCTAssert(semVerRegex.matches("1.0.0+0.build.1-rc.10000aaa-kk-0.1")) - XCTAssert(semVerRegex.matches("99999999999999999999999.999999999999999999.99999999999999999")) - XCTAssert(semVerRegex.matches("1.0.0-0A.is.legal")) - } - -#if swift(>=5.7) func test_semVerPattern_valid() throws { - if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { - XCTAssertNotNil("0.0.4".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("0.0.4".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.2.3".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("10.20.30".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.1.2-prerelease+meta".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.1.2+meta".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.1.2+meta-valid".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.0.0-alpha".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.0.0-beta".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.0.0-alpha.beta".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.0.0-alpha.beta.1".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.0.0-alpha.1".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.0.0-alpha0.valid".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.0.0-alpha.0valid".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.0.0-rc.1+build.1".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("2.0.0-rc.1+build.123".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.2.3-beta".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("10.2.3-DEV-SNAPSHOT".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.2.3-SNAPSHOT-123".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.0.0".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("2.0.0".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.1.7".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("2.0.0+build.1848".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("2.0.1-alpha.1227".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.0.0-alpha+beta".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.2.3----RC-SNAPSHOT.12.9.1--.12+788".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.2.3----R-S.12.9.1--.12+meta".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.2.3----RC-SNAPSHOT.12.9.1--.12".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.0.0+0.build.1-rc.10000aaa-kk-0.1".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("99999999999999999999999.999999999999999999.99999999999999999".wholeMatch(of: semVerPattern)) - XCTAssertNotNil("1.0.0-0A.is.legal".wholeMatch(of: semVerPattern)) - } + XCTAssertNotNil("0.0.4".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("0.0.4".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.2.3".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("10.20.30".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.1.2-prerelease+meta".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.1.2+meta".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.1.2+meta-valid".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.0.0-alpha".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.0.0-beta".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.0.0-alpha.beta".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.0.0-alpha.beta.1".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.0.0-alpha.1".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.0.0-alpha0.valid".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.0.0-alpha.0valid".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.0.0-rc.1+build.1".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("2.0.0-rc.1+build.123".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.2.3-beta".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("10.2.3-DEV-SNAPSHOT".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.2.3-SNAPSHOT-123".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.0.0".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("2.0.0".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.1.7".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("2.0.0+build.1848".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("2.0.1-alpha.1227".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.0.0-alpha+beta".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.2.3----RC-SNAPSHOT.12.9.1--.12+788".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.2.3----R-S.12.9.1--.12+meta".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.2.3----RC-SNAPSHOT.12.9.1--.12".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.0.0+0.build.1-rc.10000aaa-kk-0.1".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("99999999999999999999999.999999999999999999.99999999999999999".wholeMatch(of: semVerPattern)) + XCTAssertNotNil("1.0.0-0A.is.legal".wholeMatch(of: semVerPattern)) } -#endif func test_allow_leading_v() throws { - XCTAssert(semVerRegex.matches("v0.0.4")) - -#if swift(>=5.7) - if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { - XCTAssert("v0.0.4".contains(semVerPattern)) - } -#endif - } - - func test_semVerRegex_invalid() throws { - XCTAssertFalse(semVerRegex.matches("1")) - XCTAssertFalse(semVerRegex.matches("1.2")) - XCTAssertFalse(semVerRegex.matches("1.2.3-0123")) - XCTAssertFalse(semVerRegex.matches("1.2.3-0123.0123")) - XCTAssertFalse(semVerRegex.matches("1.1.2+.123")) - XCTAssertFalse(semVerRegex.matches("+invalid")) - XCTAssertFalse(semVerRegex.matches("-invalid")) - XCTAssertFalse(semVerRegex.matches("-invalid+invalid")) - XCTAssertFalse(semVerRegex.matches("-invalid.01")) - XCTAssertFalse(semVerRegex.matches("alpha")) - XCTAssertFalse(semVerRegex.matches("alpha.beta")) - XCTAssertFalse(semVerRegex.matches("alpha.beta.1")) - XCTAssertFalse(semVerRegex.matches("alpha.1")) - XCTAssertFalse(semVerRegex.matches("alpha+beta")) - XCTAssertFalse(semVerRegex.matches("alpha_beta")) - XCTAssertFalse(semVerRegex.matches("alpha.")) - XCTAssertFalse(semVerRegex.matches("alpha..")) - XCTAssertFalse(semVerRegex.matches("beta")) - XCTAssertFalse(semVerRegex.matches("1.0.0-alpha_beta")) - XCTAssertFalse(semVerRegex.matches("-alpha.")) - XCTAssertFalse(semVerRegex.matches("1.0.0-alpha..")) - XCTAssertFalse(semVerRegex.matches("1.0.0-alpha..1")) - XCTAssertFalse(semVerRegex.matches("1.0.0-alpha...1")) - XCTAssertFalse(semVerRegex.matches("1.0.0-alpha....1")) - XCTAssertFalse(semVerRegex.matches("1.0.0-alpha.....1")) - XCTAssertFalse(semVerRegex.matches("1.0.0-alpha......1")) - XCTAssertFalse(semVerRegex.matches("1.0.0-alpha.......1")) - XCTAssertFalse(semVerRegex.matches("01.1.1")) - XCTAssertFalse(semVerRegex.matches("1.01.1")) - XCTAssertFalse(semVerRegex.matches("1.1.01")) - XCTAssertFalse(semVerRegex.matches("1.2")) - XCTAssertFalse(semVerRegex.matches("1.2.3.DEV")) - XCTAssertFalse(semVerRegex.matches("1.2-SNAPSHOT")) - XCTAssertFalse(semVerRegex.matches("1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788")) - XCTAssertFalse(semVerRegex.matches("1.2-RC-SNAPSHOT")) - XCTAssertFalse(semVerRegex.matches("-1.0.3-gamma+b7718")) - XCTAssertFalse(semVerRegex.matches("+justmeta")) - XCTAssertFalse(semVerRegex.matches("9.8.7+meta+meta")) - XCTAssertFalse(semVerRegex.matches("9.8.7-whatever+meta+meta")) + XCTAssert("v0.0.4".contains(semVerPattern)) } -#if swift(>=5.7) func test_semVerPattern_invalid() throws { - if #available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) { - XCTAssertFalse("1".contains(semVerPattern)) - XCTAssertFalse("1.2".contains(semVerPattern)) - XCTAssertFalse("1.2.3-0123".contains(semVerPattern)) - XCTAssertFalse("1.2.3-0123.0123".contains(semVerPattern)) - XCTAssertFalse("1.1.2+.123".contains(semVerPattern)) - XCTAssertFalse("+invalid".contains(semVerPattern)) - XCTAssertFalse("-invalid".contains(semVerPattern)) - XCTAssertFalse("-invalid+invalid".contains(semVerPattern)) - XCTAssertFalse("-invalid.01".contains(semVerPattern)) - XCTAssertFalse("alpha".contains(semVerPattern)) - XCTAssertFalse("alpha.beta".contains(semVerPattern)) - XCTAssertFalse("alpha.beta.1".contains(semVerPattern)) - XCTAssertFalse("alpha.1".contains(semVerPattern)) - XCTAssertFalse("alpha+beta".contains(semVerPattern)) - XCTAssertFalse("alpha_beta".contains(semVerPattern)) - XCTAssertFalse("alpha.".contains(semVerPattern)) - XCTAssertFalse("alpha..".contains(semVerPattern)) - XCTAssertFalse("beta".contains(semVerPattern)) - XCTAssertFalse("1.0.0-alpha_beta".contains(semVerPattern)) - XCTAssertFalse("-alpha.".contains(semVerPattern)) - XCTAssertFalse("1.0.0-alpha..".contains(semVerPattern)) - XCTAssertFalse("1.0.0-alpha..1".contains(semVerPattern)) - XCTAssertFalse("1.0.0-alpha...1".contains(semVerPattern)) - XCTAssertFalse("1.0.0-alpha....1".contains(semVerPattern)) - XCTAssertFalse("1.0.0-alpha.....1".contains(semVerPattern)) - XCTAssertFalse("1.0.0-alpha......1".contains(semVerPattern)) - XCTAssertFalse("1.0.0-alpha.......1".contains(semVerPattern)) - XCTAssertFalse("01.1.1".contains(semVerPattern)) - XCTAssertFalse("1.01.1".contains(semVerPattern)) - XCTAssertFalse("1.1.01".contains(semVerPattern)) - XCTAssertFalse("1.2".contains(semVerPattern)) - XCTAssertFalse("1.2.3.DEV".contains(semVerPattern)) - XCTAssertFalse("1.2-SNAPSHOT".contains(semVerPattern)) - XCTAssertFalse("1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788".contains(semVerPattern)) - XCTAssertFalse("1.2-RC-SNAPSHOT".contains(semVerPattern)) - XCTAssertFalse("-1.0.3-gamma+b7718".contains(semVerPattern)) - XCTAssertFalse("+justmeta".contains(semVerPattern)) - XCTAssertFalse("9.8.7+meta+meta".contains(semVerPattern)) - XCTAssertFalse("9.8.7-whatever+meta+meta".contains(semVerPattern)) - } + XCTAssertFalse("1".contains(semVerPattern)) + XCTAssertFalse("1.2".contains(semVerPattern)) + XCTAssertFalse("1.2.3-0123".contains(semVerPattern)) + XCTAssertFalse("1.2.3-0123.0123".contains(semVerPattern)) + XCTAssertFalse("1.1.2+.123".contains(semVerPattern)) + XCTAssertFalse("+invalid".contains(semVerPattern)) + XCTAssertFalse("-invalid".contains(semVerPattern)) + XCTAssertFalse("-invalid+invalid".contains(semVerPattern)) + XCTAssertFalse("-invalid.01".contains(semVerPattern)) + XCTAssertFalse("alpha".contains(semVerPattern)) + XCTAssertFalse("alpha.beta".contains(semVerPattern)) + XCTAssertFalse("alpha.beta.1".contains(semVerPattern)) + XCTAssertFalse("alpha.1".contains(semVerPattern)) + XCTAssertFalse("alpha+beta".contains(semVerPattern)) + XCTAssertFalse("alpha_beta".contains(semVerPattern)) + XCTAssertFalse("alpha.".contains(semVerPattern)) + XCTAssertFalse("alpha..".contains(semVerPattern)) + XCTAssertFalse("beta".contains(semVerPattern)) + XCTAssertFalse("1.0.0-alpha_beta".contains(semVerPattern)) + XCTAssertFalse("-alpha.".contains(semVerPattern)) + XCTAssertFalse("1.0.0-alpha..".contains(semVerPattern)) + XCTAssertFalse("1.0.0-alpha..1".contains(semVerPattern)) + XCTAssertFalse("1.0.0-alpha...1".contains(semVerPattern)) + XCTAssertFalse("1.0.0-alpha....1".contains(semVerPattern)) + XCTAssertFalse("1.0.0-alpha.....1".contains(semVerPattern)) + XCTAssertFalse("1.0.0-alpha......1".contains(semVerPattern)) + XCTAssertFalse("1.0.0-alpha.......1".contains(semVerPattern)) + XCTAssertFalse("01.1.1".contains(semVerPattern)) + XCTAssertFalse("1.01.1".contains(semVerPattern)) + XCTAssertFalse("1.1.01".contains(semVerPattern)) + XCTAssertFalse("1.2".contains(semVerPattern)) + XCTAssertFalse("1.2.3.DEV".contains(semVerPattern)) + XCTAssertFalse("1.2-SNAPSHOT".contains(semVerPattern)) + XCTAssertFalse("1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788".contains(semVerPattern)) + XCTAssertFalse("1.2-RC-SNAPSHOT".contains(semVerPattern)) + XCTAssertFalse("-1.0.3-gamma+b7718".contains(semVerPattern)) + XCTAssertFalse("+justmeta".contains(semVerPattern)) + XCTAssertFalse("9.8.7+meta+meta".contains(semVerPattern)) + XCTAssertFalse("9.8.7-whatever+meta+meta".contains(semVerPattern)) } -#endif func test_init() throws { XCTAssertEqual(SemanticVersion("1.2.3"), SemanticVersion(1, 2, 3))