Skip to content

Commit 7757ea0

Browse files
committed
Add all version range test cases
Signed-off-by: ziadhany <ziadhany2016@gmail.com>
1 parent d710d22 commit 7757ea0

2 files changed

Lines changed: 158 additions & 82 deletions

File tree

src/univers/version_range.py

Lines changed: 63 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,9 @@ def __contains__(self, version):
223223

224224
def __eq__(self, other):
225225
return (
226-
self.scheme == other.scheme
227-
and self.version_class == other.version_class
228-
and self.constraints == other.constraints
226+
self.scheme == other.scheme
227+
and self.version_class == other.version_class
228+
and self.constraints == other.constraints
229229
)
230230

231231

@@ -355,9 +355,9 @@ def from_native(cls, string):
355355
)
356356
else:
357357
if (
358-
constraint.endswith(".x")
359-
or constraint.startswith("~")
360-
or constraint.startswith("^")
358+
constraint.endswith(".x")
359+
or constraint.startswith("~")
360+
or constraint.startswith("^")
361361
):
362362
constraints.extend(
363363
get_npm_version_constraints_from_semver_npm_spec(
@@ -936,40 +936,72 @@ def from_native(cls, string):
936936
"""
937937
if string == "*":
938938
return cls(
939-
constraints=[VersionConstraint(comparator="*", version_class=cls.version_class)]
939+
constraints=(VersionConstraint(comparator="*", version_class=cls.version_class),)
940940
)
941941

942-
constraint_strings = string.split(",")
943942
constraints = []
943+
cleaned_string = remove_spaces(string).lower()
944+
for version in cleaned_string.split(","):
945+
if not version:
946+
raise InvalidVersionRange(f"InvalidVersionRange : {string}")
947+
948+
# wildcard
949+
if "*" in version:
950+
if "*" in version and not version.endswith("*") or constraints:
951+
raise InvalidVersionRange(
952+
f"Unsupported star in the middle of a version: it should be a trailing star only: {string}")
953+
954+
if version.endswith(".*.*"):
955+
version = version.replace(".*.*", ".*")
956+
957+
segments_count = len(version.split("."))
958+
lower_bound = cls.version_class(version.replace("*", "0"))
959+
if segments_count == 2:
960+
upper_bound = cls.version_class(str(lower_bound.next_major()))
961+
elif segments_count == 3:
962+
upper_bound = cls.version_class(str(lower_bound.next_minor()))
963+
else:
964+
raise InvalidVersionRange(f"Invalid version: not a semver version: {string}")
944965

945-
# caret
946-
if string.startswith("^"):
947-
string = string.replace("^", "=")
966+
vstart = VersionConstraint(comparator=">=", version=lower_bound)
967+
vend = VersionConstraint(comparator="<", version=upper_bound)
968+
constraints.extend([vstart, vend])
948969

949-
# tilde
950-
if string.startswith("~"):
951-
version = string.lstrip("~")
952-
lower_bound = CargoVersion(version)
953-
if lower_bound.minor == 0 and lower_bound.patch == 0:
954-
upper_bound = CargoVersion(str(lower_bound.value.next_major()))
955-
else:
956-
upper_bound = CargoVersion(str(lower_bound.value.next_minor()))
970+
# caret
971+
elif version.startswith("^"):
972+
version = version.lstrip("^")
973+
upper_bound = None
974+
lower_bound = cls.version_class(version)
975+
if (lower_bound.major != 0 or version == "0") and version != "0.0":
976+
upper_bound = cls.version_class(str(lower_bound.value.next_major()))
977+
else:
978+
if lower_bound.minor != 0 or version == "0.0":
979+
upper_bound = cls.version_class(str(lower_bound.value.next_minor()))
980+
elif lower_bound.patch != 0:
981+
upper_bound = cls.version_class(str(lower_bound.value.next_patch()))
957982

958-
return cls(
959-
constraints=(
960-
VersionConstraint(comparator=">=", version=lower_bound),
961-
VersionConstraint(comparator="<", version=upper_bound),
962-
)
963-
)
983+
vstart = VersionConstraint(comparator=">=", version=lower_bound)
984+
vend = VersionConstraint(comparator="<", version=upper_bound)
985+
constraints.extend([vstart, vend])
986+
987+
# tilde
988+
elif version.startswith("~"):
989+
version = version.lstrip("~")
990+
lower_bound = cls.version_class(version)
991+
if lower_bound.minor == 0 and lower_bound.patch == 0:
992+
upper_bound = cls.version_class(str(lower_bound.value.next_major()))
993+
else:
994+
upper_bound = cls.version_class(str(lower_bound.value.next_minor()))
995+
996+
vstart = VersionConstraint(comparator=">=", version=lower_bound)
997+
vend = VersionConstraint(comparator="<", version=upper_bound)
998+
constraints.extend([vstart, vend])
964999

965-
for constraint in constraint_strings:
966-
if not constraint:
967-
raise InvalidVersionRange
9681000
else:
969-
vs = VersionConstraint.split(string)
970-
version = cls.version_class(vs[1])
971-
constraint = VersionConstraint(comparator=vs[0], version=version)
1001+
comparator, version = VersionConstraint.split(version)
1002+
constraint = VersionConstraint(comparator=comparator, version=cls.version_class(version))
9721003
constraints.append(constraint)
1004+
9731005
return cls(constraints=tuple(constraints))
9741006

9751007

tests/test_cargo_version_range.py

Lines changed: 95 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,76 +7,120 @@
77
values = [
88
# https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
99
# caret
10-
["^1.2.3", [[["=", "1.2.3"]]], ["1.2.3"], ["1.2.4"]],
10+
["^1.2.3", [[]], ["1.2.3"], []],
1111
# tilde
12-
["~1.2.3", [[[">=", "1.2.3"], ["<", "1.3.0"]]], ["1.2.4"], ["2.0.1"]],
13-
["~1.2", [[[">=", "1.2.0"], ["<", "1.3.0"]]], ["1.2.5"], ["1.3.1"]],
14-
[
15-
"~1",
16-
[[[">=", "1.0.0"], ["<", "2.0.0"]]],
17-
["1.3.0", "1.8.1"],
18-
["2.1.0", "2.2"],
19-
], # tilde increment the major
12+
["~1.2.3", [[">=", "1.2.3"], ["<", "1.3.0"]], ["1.2.4"], ["2.0.1"]],
13+
["~1.2", [[">=", "1.2.0"], ["<", "1.3.0"]], ["1.2.5"], ["1.3.1"]],
14+
["~1", [[">=", "1.0.0"], ["<", "2.0.0"]], ["1.3.0", "1.8.1"], ["2.1.0", "2.2"]], # tilde increment the major
2015
# wildcard
21-
["*", [[[">=", "0.0.0"]]], ["1.0.0", "2.0.0"], []],
22-
# ["1.*", [[[">=", "1.0.0"]]], ["1.0.0"], ["2", "1.0.1"]],
23-
# ["1.2.*", [[[">=", "1.2.0"], ["<", "1.3.0"]]], ["1.2", "1.2.1"], ["2.1.0", "2.2"]],
16+
["*", [[">=", "0.0.0"]], ["1.0.0", "2.0.0"], []],
17+
["1.*", [], ["1.0.0"], ["2"]],
18+
["1.2.*", [[">=", "1.2.0"], ["<", "1.3.0"]], ["1.2", "1.2.1"], ["2.1.0", "2.2"]],
19+
2420
# https://github.com/dtolnay/semver/blob/master/tests/test_version_req.rs :
21+
22+
# test_basic
23+
# ["^1.0.0", [[]], ["1.0.0", "1.1.0", "1.0.1"], ["0.9.9", "0.10.0", "0.1.0", "1.0.0-pre", "1.0.1-pre"]],
24+
25+
# test_exact
2526
["=1.0.0", [["=", "1.0.0"]], ["1.0.0"], ["1.0.1", "0.9.9", "0.10.0", "0.1.0", "1.0.0-pre"]],
2627
["=0.9.0", [["=", "0.9.0"]], ["0.9.0"], ["0.9.1", "1.9.0", "0.0.9", "0.9.0-pre"]],
2728
["=0.0.2", [["=", "0.0.2"]], ["0.0.2"], ["0.0.1", "0.0.3", "0.0.2-pre"]],
28-
[
29-
"=0.1.0-beta2.a",
30-
[["=", "0.1.0-beta2.a"]],
31-
["0.1.0-beta2.a"],
32-
["0.9.1", "0.1.0", "0.1.1-beta2.a", "0.1.0-beta2"],
33-
],
29+
["=0.1.0-beta2.a", [["=", "0.1.0-beta2.a"]], ["0.1.0-beta2.a"], ["0.9.1", "0.1.0", "0.1.1-beta2.a", "0.1.0-beta2"]],
30+
# https://github.com/dtolnay/semver/blob/master/tests/test_version_req.rs#L73
3431
# ["=0.1.0+meta", [["=", "0.1.0+meta"]], ["0.1.0", "0.1.0+meta", "0.1.0+any"], []],
35-
# ["<1.0.0", [["<", "1.0.0"]], ["0.1.0", "0.0.1"], ["1.0.0", "1.0.0-beta", "1.0.1", "0.9.9-alpha"]],
36-
# [
37-
# "<= 2.1.0-alpha2",
38-
# [["<", "2.1.0-alpha2"], ["=", "2.1.0-alpha2"]],
39-
# ["2.1.0-alpha2", "2.1.0-alpha1", "2.0.0", "1.0.0"],
40-
# ["2.1.0", "2.2.0-alpha1", "2.0.0-alpha2", "1.0.0-alpha2"],
41-
# ],
42-
# [">1.0.0-alpha, <1.0.0", [[[">", "2.1.0-alpha2"], ["<", "1.0.0"]]], ["1.0.0-beta"], []],
43-
# [">1.0.0-alpha, <1.0", [[[">", "1.0.0-alpha"], ["<", "1.0"]]], ["1.0.0-beta"], []],
44-
# [">1.0.0-alpha, <1", [[[">", "1.0.0-alpha"], ["<", "1"]]], ["1.0.0-beta"], []],
45-
# [
46-
# ">=0.5.1-alpha3, <0.6",
47-
# [[[">", "0.5.1-alpha3"], ["=", "0.5.1-alpha3"], ["<", "0.6"]]],
48-
# ["0.5.1-alpha3", "0.5.1-alpha4", "0.5.1-beta", "0.5.1", "0.5.5"],
49-
# ["0.5.1-alpha1", "0.5.2-alpha3", "0.5.5-pre", "0.5.0-pre"],
50-
# ],
51-
["~1", [], ["1.0.0", "1.0.1", "1.1.1"], ["0.9.1", "2.9.0", "0.0.9"]],
52-
["~1.2", [], ["1.2.0", "1.2.1"], ["1.1.1", "1.3.0", "0.0.9"]],
53-
["~1.2.2", [], ["1.2.2", "1.2.4"], ["1.2.1", "1.9.0", "1.0.9", "2.0.1", "0.1.3"]],
54-
# [
55-
# "~1.2.3-beta.2",
56-
# [],
57-
# ["1.2.3", "1.2.4", "1.2.3-beta.2", "1.2.3-beta.4"],
58-
# ["1.3.3", "1.1.4", "1.2.3-beta.1", "1.2.4-beta.2"],
59-
# ],
32+
33+
# test_greater_than
34+
# [">= 1.0.0", [[]], ["1.0.0", "2.0.0"], ["0.1.0", "0.0.1", "1.0.0-pre", "2.0.0-pre"]],
35+
# [">= 2.1.0-alpha2", [[]], ["2.1.0-alpha2", "2.1.0-alpha3", "2.1.0", "3.0.0"], ["2.0.0", "2.1.0-alpha1", "2.0.0-alpha2", "3.0.0-alpha2"]],
36+
37+
# test_less_than
38+
# ["<1.0.0", [[]], ["0.1.0", "0.0.1"], ["1.0.0", "1.0.0-beta", "1.0.1", "0.9.9-alpha"]],
39+
# ["<= 2.1.0-alpha2", [[]], ["2.1.0-alpha2", "2.1.0-alpha1", "2.0.0", "1.0.0"], ["2.1.0", "2.2.0-alpha1", "2.0.0-alpha2", "1.0.0-alpha2"]],
40+
# [">1.0.0-alpha, <1.0.0", [[">", "2.1.0-alpha2"], ["<", "1.0.0"]], ["1.0.0-beta"], []],
41+
# [">1.0.0-alpha, <1.0", [[">", "1.0.0-alpha"], ["<", "1.0"]]], ["1.0.0-beta"], []],
42+
[">1.0.0-alpha, <1", [[">", "1.0.0-alpha"], ["<", "1"]], ["1.0.0-beta"], []],
43+
44+
# test_multiple
45+
["> 0.0.9, <= 2.5.3", [[]], ["0.0.10", "1.0.0", "2.5.3"], ["0.0.8", "2.5.4"]],
46+
# ["^0.3.0, ^0.4.0", [[]], [], ["0.0.8", "0.3.0", "0.4.0"]],
47+
# ["<=0.2.0, >=0.5.0", [[]], [], ["0.0.8", "0.3.0", "0.5.1"]],
48+
# ["^0.1.0, ^0.1.4, ^0.1.6", [[]], ["0.1.6", "0.1.9"], ["0.1.0", "0.1.4", "0.2.0"]],
49+
# [">=0.5.1-alpha3, <0.6", [[[">", "0.5.1-alpha3"], ["=", "0.5.1-alpha3"], ["<", "0.6"]]], ["0.5.1-alpha3", "0.5.1-alpha4", "0.5.1-beta", "0.5.1", "0.5.5"], ["0.5.1-alpha1", "0.5.2-alpha3", "0.5.5-pre", "0.5.0-pre"]],
50+
51+
# test_tilde
52+
["~1", [[]], ["1.0.0", "1.0.1", "1.1.1"], ["0.9.1", "2.9.0", "0.0.9"]],
53+
["~1.2", [[]], ["1.2.0", "1.2.1"], ["1.1.1", "1.3.0", "0.0.9"]],
54+
["~1.2.2", [[]], ["1.2.2", "1.2.4"], ["1.2.1", "1.9.0", "1.0.9", "2.0.1", "0.1.3"]],
55+
# ["~1.2.3-beta.2", [[]], ["1.2.3", "1.2.4", "1.2.3-beta.2", "1.2.3-beta.4"],
56+
# ["1.3.3", "1.1.4", "1.2.3-beta.1", "1.2.4-beta.2"]],
57+
58+
# test_caret
59+
# ["^1", [[]], ["1.1.2", "1.1.0", "1.2.1", "1.0.1"],
60+
# ["0.9.1", "2.9.0", "0.1.4", "1.0.0-beta1", "0.1.0-alpha", "1.0.1-pre"]],
61+
62+
["^1.1", [[]], ["1.1.2", "1.1.0", "1.2.1"],
63+
["0.9.1", "2.9.0", "1.0.1", "0.1.4"]],
64+
65+
# ["^1.1.2", [[]], ["1.1.2", "1.1.4", "1.2.1"],
66+
# ["0.9.1", "2.9.0", "1.1.1", "0.0.1", "1.1.2-alpha1", "1.1.3-alpha1", "2.9.0-alpha1"]],
67+
68+
# ["^0.1.2", [[]], ["0.1.2", "0.1.4"],
69+
# ["0.9.1", "2.9.0", "1.1.1", "0.0.1", "0.1.2-beta", "0.1.3-alpha", "0.2.0-pre"]],
70+
71+
# ["^0.5.1-alpha3", [[]], ["0.5.1-alpha3", "0.5.1-alpha4", "0.5.1-beta", "0.5.1", "0.5.5", ],
72+
# ["0.5.1-alpha1", "0.5.2-alpha3", "0.5.5-pre", "0.5.0-pre", "0.6.0"]],
73+
74+
["^0.0.2", [[]], ["0.0.2"],
75+
["0.9.1", "2.9.0", "1.1.1", "0.0.1", "0.1.4"]],
76+
77+
# ["^0.0", [[]], ["0.0.2", "0.0.0"],
78+
# ["0.9.1", "2.9.0", "1.1.1", "0.0.1", "0.1.4"]],
79+
80+
["^0", [[]], ["0.9.1", "0.0.2", "0.0.0"],
81+
["2.9.0", "1.1.1"]],
82+
83+
# ["^1.4.2-beta.5", [[]], ["1.4.2", "1.4.3", "1.4.2-beta.5", "1.4.2-beta.6", "1.4.2-c"],
84+
# ["0.9.9", "2.0.0", "1.4.2-alpha", "1.4.2-beta.4", "1.4.3-beta.5"]],
85+
86+
# test_wildcard
87+
# https://github.com/dtolnay/semver/blob/master/tests/test_version_req.rs#L272
88+
# ["*", [[]], ["0.9.1", "2.9.0", "0.0.9", "1.0.1", "1.1.1"],
89+
# ["1.0.0-pre"]],
90+
91+
# ["1.*", [[]], ["1.2.0", "1.2.1", "1.1.1", "1.3.0"],
92+
# ["0.0.9", "1.2.0-pre"]],
93+
94+
# ["1.2.*", [[]], ["1.2.0", "1.2.2", "1.2.4"],
95+
# ["1.9.0", "1.0.9", "2.0.1", "0.1.3", "1.2.2-pre"]],
96+
97+
# test_pre
98+
# ["=2.1.1-really.0", [[]], ["2.1.1-really.0"], []]
99+
100+
# test_cargo3202
101+
["0.*.*", [[]], ["0.5.0"], []]
102+
60103
]
61104

105+
62106
error_list = [
63107
"> 0.1.0,",
64108
"> 0.3.0, ,",
65109
# "1.2.3 - 2.3.4",
66110
# "> 0.0.9 <= 2.5.3",
67111
# "=1.2.3 || =2.3.4",
68112
# "1.1 || =1.2.3",
69-
# "6.* || 8.* || >= 10.*",
113+
"6.* || 8.* || >= 10.*",
70114
# ">= >= 0.0.2",
71115
# ">== 0.0.2",
72116
# "a.0.0",
73117
# "1.0.0-",
74118
# ">=",
75-
# "*.1",
76-
# "1.*.1",
77-
# ">=1.*.1",
78-
# "*, 0.20.0-any",
79-
# "0.20.0-any, *" "0.20.0-any, *, 1.0",
119+
"*.1",
120+
"1.*.1",
121+
">=1.*.1",
122+
"*, 0.20.0-any",
123+
"0.20.0-any, *" "0.20.0-any, *, 1.0",
80124
]
81125

82126

@@ -93,6 +137,6 @@ def test_range(version_range, conditions, versions_in, versions_out):
93137

94138

95139
def test_error():
96-
for i in error_list:
140+
for version_range in error_list:
97141
with pytest.raises(InvalidVersionRange):
98-
CargoVersionRange.from_native(i)
142+
CargoVersionRange.from_native(version_range)

0 commit comments

Comments
 (0)