diff --git a/phpmon-tests/Versions/PhpVersionNumberTest.swift b/phpmon-tests/Versions/PhpVersionNumberTest.swift index 1f4b8c4..f8b904a 100644 --- a/phpmon-tests/Versions/PhpVersionNumberTest.swift +++ b/phpmon-tests/Versions/PhpVersionNumberTest.swift @@ -8,6 +8,7 @@ import XCTest +// swiftlint:disable type_body_length class PhpVersionNumberTest: XCTestCase { func testCanDeconstructPhpVersion() throws { @@ -287,4 +288,76 @@ class PhpVersionNumberTest: XCTestCase { .make(from: ["7.3.1", "7.2.9"]).all ) } + + func testCanCheckLessThanOrEqualConstraints() throws { + XCTAssertEqual( + PhpVersionNumberCollection + .make(from: ["7.4", "7.3", "7.2", "7.1", "7.0"]) + .matching(constraint: "<=7.2", strict: true), + PhpVersionNumberCollection + .make(from: ["7.2", "7.1", "7.0"]).all + ) + + XCTAssertEqual( + PhpVersionNumberCollection + .make(from: ["7.4", "7.3", "7.2", "7.1", "7.0"]) + .matching(constraint: "<=7.2.0", strict: true), + PhpVersionNumberCollection + .make(from: ["7.2", "7.1", "7.0"]).all + ) + + // Strict check (>7.2.5 is too new for 7.2 which resolves to 7.2.0) + XCTAssertEqual( + PhpVersionNumberCollection + .make(from: ["7.4", "7.3", "7.2", "7.1", "7.0"]) + .matching(constraint: "<=7.2.5", strict: true), + PhpVersionNumberCollection + .make(from: ["7.2", "7.1", "7.0"]).all + ) + + // Non-strict check (ignoring patch has no effect) + XCTAssertEqual( + PhpVersionNumberCollection + .make(from: ["7.4", "7.3", "7.2", "7.1", "7.0"]) + .matching(constraint: "<=7.2.5", strict: false), + PhpVersionNumberCollection + .make(from: ["7.2", "7.1", "7.0"]).all + ) + } + + func testCanCheckLessThanConstraints() throws { + XCTAssertEqual( + PhpVersionNumberCollection + .make(from: ["7.4", "7.3", "7.2", "7.1", "7.0"]) + .matching(constraint: "<7.2", strict: true), + PhpVersionNumberCollection + .make(from: ["7.1", "7.0"]).all + ) + + XCTAssertEqual( + PhpVersionNumberCollection + .make(from: ["7.4", "7.3", "7.2", "7.1", "7.0"]) + .matching(constraint: "<7.2.0", strict: true), + PhpVersionNumberCollection + .make(from: ["7.1", "7.0"]).all + ) + + // Strict check (>7.2.5 is too new for 7.2 which resolves to 7.2.0) + XCTAssertEqual( + PhpVersionNumberCollection + .make(from: ["7.4", "7.3", "7.2", "7.1", "7.0"]) + .matching(constraint: "<7.2.5", strict: true), + PhpVersionNumberCollection + .make(from: ["7.2", "7.1", "7.0"]).all + ) + + // Non-strict check (patch resolves to 7.2.999, which is bigger than 7.2.5) + XCTAssertEqual( + PhpVersionNumberCollection + .make(from: ["7.4", "7.3", "7.2", "7.1", "7.0"]) + .matching(constraint: "<7.2.5", strict: false), + PhpVersionNumberCollection + .make(from: ["7.1", "7.0"]).all + ) + } } diff --git a/phpmon/Common/PHP/PHP Version/PhpVersionNumber.swift b/phpmon/Common/PHP/PHP Version/PhpVersionNumber.swift index 398285c..c262b2c 100644 --- a/phpmon/Common/PHP/PHP Version/PhpVersionNumber.swift +++ b/phpmon/Common/PHP/PHP Version/PhpVersionNumber.swift @@ -87,6 +87,14 @@ public struct PhpVersionNumberCollection: Equatable { return self.versions.filter { $0.isNewerThan(version, strict) } } + if let version = PhpVersionNumber.make(from: constraint, type: .smallerThanOrEqual) { + return self.versions.filter { $0.isSameAs(version, strict) || $0.isOlderThan(version, strict)} + } + + if let version = PhpVersionNumber.make(from: constraint, type: .smallerThan) { + return self.versions.filter { $0.isOlderThan(version, strict)} + } + return [] } } @@ -120,12 +128,8 @@ public struct PhpVersionNumber: Equatable, Hashable { case tildeVersionRange = #"^~(?\d+).(?\d+).?(?\d+)?\z"# case greaterThanOrEqual = #"^>=(?\d+).(?\d+).?(?\d+)?\z"# case greaterThan = #"^>(?\d+).(?\d+).?(?\d+)?\z"# - - // TODO: (6.0) Handle these cases (even though I suspect these are uncommon) - /* case smallerThanOrEqual = #"^<=(?\d+).(?\d+).?(?\d+)?\z"# case smallerThan = #"^<(?\d+).(?\d+).?(?\d+)?\z"# - */ } public static func parse(_ text: String) throws -> Self { @@ -179,6 +183,15 @@ public struct PhpVersionNumber: Equatable, Hashable { ) } + internal func isOlderThan(_ version: PhpVersionNumber, _ strict: Bool) -> Bool { + return ( + self.major < version.major || + self.major == version.major && self.minor < version.minor || + self.major == version.major && self.minor == version.minor + && self.patch(strict) < version.patch(strict) + ) + } + internal func hasNewerMinorVersionOrPatch(_ version: PhpVersionNumber, _ strict: Bool) -> Bool { return self.major == version.major && (