-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This introduces a predicate that can be used for comparing if given a version is contained inside a version range pattern
- Loading branch information
Showing
3 changed files
with
122 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
61 changes: 61 additions & 0 deletions
61
version/src/main/java/io/smallrye/common/version/VersionRange.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package io.smallrye.common.version; | ||
|
||
import static io.smallrye.common.version.Messages.msg; | ||
|
||
import java.util.function.Predicate; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
/** | ||
* A {@link VersionRange} is a predicate that tests if a version string is within a specified range. | ||
*/ | ||
public class VersionRange implements Predicate<String> { | ||
|
||
/** | ||
* Range in format "[1.0,2.0)" | ||
*/ | ||
private static final Pattern RANGE_PATTERN = Pattern.compile("([\\[\\(])(.*),(.*)([\\]\\)])"); | ||
|
||
private final VersionScheme versionScheme; | ||
private final Bound lowerBound; | ||
private final Bound upperBound; | ||
|
||
public VersionRange(VersionScheme versionScheme, String rangePattern) { | ||
this.versionScheme = versionScheme; | ||
// Range pattern is in format "[1.0,2.0)" | ||
Matcher matcher = RANGE_PATTERN.matcher(rangePattern); | ||
if (!matcher.matches()) { | ||
throw msg.invalidRangePattern(rangePattern); | ||
} | ||
this.lowerBound = new Bound(matcher.group(2), matcher.group(1).charAt(0) == '['); | ||
this.upperBound = new Bound(matcher.group(3), matcher.group(4).charAt(0) == ']'); | ||
} | ||
|
||
@Override | ||
public boolean test(String s) { | ||
if (lowerBound != null && !lowerBound.version.isBlank()) { | ||
int comparison = versionScheme.compare(s, lowerBound.version); | ||
if (comparison < 0 || (!lowerBound.inclusive && comparison == 0)) { | ||
return false; | ||
} | ||
} | ||
if (upperBound != null && !upperBound.version.isBlank()) { | ||
int comparison = versionScheme.compare(s, upperBound.version); | ||
if (comparison > 0 || (!upperBound.inclusive && comparison == 0)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
private class Bound { | ||
|
||
private final String version; | ||
private final boolean inclusive; | ||
|
||
public Bound(String version, boolean inclusive) { | ||
this.version = version; | ||
this.inclusive = inclusive; | ||
} | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
version/src/test/java/io/smallrye/common/version/VersionRangeTest.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package io.smallrye.common.version; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
class VersionRangeTest { | ||
|
||
@Test | ||
void testVersionRangeWithInclusive() { | ||
VersionRange versionRange = new VersionRange(VersionScheme.MAVEN, "[1.0,2.0]"); | ||
assertTrue(versionRange.test("1.0.0")); | ||
assertTrue(versionRange.test("1.1.0")); | ||
assertTrue(versionRange.test("1.899.0")); | ||
assertTrue(versionRange.test("2.0")); | ||
assertTrue(versionRange.test("2.0.0")); | ||
assertFalse(versionRange.test("2.0.1")); | ||
} | ||
|
||
@Test | ||
void testVersionRangeWithExclusive() { | ||
VersionRange versionRange = new VersionRange(VersionScheme.MAVEN, "(1.0,2.0)"); | ||
assertFalse(versionRange.test("1.0.0")); | ||
assertTrue(versionRange.test("1.1.0")); | ||
assertTrue(versionRange.test("1.899.0")); | ||
assertFalse(versionRange.test("2.0")); | ||
assertFalse(versionRange.test("2.0.0")); | ||
assertFalse(versionRange.test("2.0.1")); | ||
} | ||
|
||
@Test | ||
void testVersionRangeWithLowerBoundExclusive() { | ||
VersionRange versionRange = new VersionRange(VersionScheme.MAVEN, "(1.0,2.0]"); | ||
assertFalse(versionRange.test("1.0.0")); | ||
assertTrue(versionRange.test("1.1.0")); | ||
assertTrue(versionRange.test("1.899.0")); | ||
assertTrue(versionRange.test("2.0")); | ||
assertTrue(versionRange.test("2.0.0")); | ||
assertFalse(versionRange.test("2.0.1")); | ||
} | ||
|
||
@Test | ||
void testVersionRangeWithUpperBoundExclusive() { | ||
VersionRange versionRange = new VersionRange(VersionScheme.MAVEN, "[1.0,2.0)"); | ||
assertTrue(versionRange.test("1.0.0")); | ||
assertTrue(versionRange.test("1.1.0")); | ||
assertTrue(versionRange.test("1.899.0")); | ||
assertFalse(versionRange.test("2.0")); | ||
assertFalse(versionRange.test("2.0.0")); | ||
assertFalse(versionRange.test("2.0.1")); | ||
} | ||
|
||
@Test | ||
public void testVersionRangeWithInvalidRangePattern() { | ||
assertThrows(VersionSyntaxException.class, () -> new VersionRange(VersionScheme.MAVEN, "1.0,2.0"), | ||
"Invalid range pattern: 1.0,2.0"); | ||
} | ||
} |