Commit | Line | Data |
---|---|---|
1479465f GJ |
1 | #!/usr/bin/perl |
2 | # | |
3 | # This program is free software; you can redistribute it and/or modify | |
4 | # it under the terms of the GNU General Public License as published by | |
5 | # the Free Software Foundation; either version 2 of the License, or | |
6 | # (at your option) any later version. | |
7 | # | |
8 | # This program is distributed in the hope that it will be useful, | |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
12 | # | |
13 | # You should have received a copy of the GNU General Public License | |
14 | # along with this program. If not, see <https://www.gnu.org/licenses/>. | |
15 | ||
16 | use strict; | |
17 | use warnings; | |
18 | ||
19 | use Test::More; | |
20 | ||
21 | use Dpkg::ErrorHandling; | |
22 | use Dpkg::IPC; | |
23 | ||
24 | report_options(quiet_warnings => 1); | |
25 | ||
26 | my @tests = <DATA>; | |
27 | my @ops = ('<', '<<', 'lt', | |
28 | '<=', 'le', | |
29 | '=', 'eq', | |
30 | '>=', 'ge', | |
31 | '>', '>>', 'gt'); | |
32 | ||
33 | plan tests => scalar(@tests) * (3 * scalar(@ops) + 4) + 30; | |
34 | ||
35 | sub dpkg_vercmp { | |
36 | my ($a, $cmp, $b) = @_; | |
37 | my $stderr; | |
38 | ||
39 | spawn(exec => [ 'dpkg', '--compare-versions', '--', $a, $cmp, $b ], | |
40 | error_to_string => \$stderr, wait_child => 1, nocheck => 1); | |
41 | diag("dpkg --compare-versions error=$?: $stderr") if $? and $? != 256; | |
42 | ||
43 | return $? == 0; | |
44 | } | |
45 | ||
46 | sub obj_vercmp { | |
47 | my ($a, $cmp, $b) = @_; | |
48 | return $a < $b if $cmp eq '<<'; | |
49 | return $a lt $b if $cmp eq 'lt'; | |
50 | return $a <= $b if $cmp eq '<=' or $cmp eq '<'; | |
51 | return $a le $b if $cmp eq 'le'; | |
52 | return $a == $b if $cmp eq '='; | |
53 | return $a eq $b if $cmp eq 'eq'; | |
54 | return $a >= $b if $cmp eq '>=' or $cmp eq '>'; | |
55 | return $a ge $b if $cmp eq 'ge'; | |
56 | return $a > $b if $cmp eq '>>'; | |
57 | return $a gt $b if $cmp eq 'gt'; | |
58 | } | |
59 | ||
60 | use_ok('Dpkg::Version'); | |
61 | ||
62 | my $truth = { | |
63 | '-1' => { | |
64 | '<<' => 1, 'lt' => 1, | |
65 | '<=' => 1, 'le' => 1, '<' => 1, | |
66 | '=' => 0, 'eq' => 0, | |
67 | '>=' => 0, 'ge' => 0, '>' => 0, | |
68 | '>>' => 0, 'gt' => 0, | |
69 | }, | |
70 | '0' => { | |
71 | '<<' => 0, 'lt' => 0, | |
72 | '<=' => 1, 'le' => 1, '<' => 1, | |
73 | '=' => 1, 'eq' => 1, | |
74 | '>=' => 1, 'ge' => 1, '>' => 1, | |
75 | '>>' => 0, 'gt' => 0, | |
76 | }, | |
77 | '1' => { | |
78 | '<<' => 0, 'lt' => 0, | |
79 | '<=' => 0, 'le' => 0, '<' => 0, | |
80 | '=' => 0, 'eq' => 0, | |
81 | '>=' => 1, 'ge' => 1, '>' => 1, | |
82 | '>>' => 1, 'gt' => 1, | |
83 | }, | |
84 | }; | |
85 | ||
86 | # Handling of empty/invalid versions | |
87 | my $empty = Dpkg::Version->new(''); | |
88 | ok($empty eq '', "Dpkg::Version->new('') eq ''"); | |
89 | ok($empty->as_string() eq '', "Dpkg::Version->new('')->as_string() eq ''"); | |
90 | ok(!$empty->is_valid(), 'empty version is invalid'); | |
91 | $empty = Dpkg::Version->new('-0'); | |
92 | ok($empty eq '', "Dpkg::Version->new('-0') eq '-0'"); | |
93 | ok($empty->as_string() eq '-0', "Dpkg::Version->new('-0')->as_string() eq '-0'"); | |
94 | ok(!$empty->is_valid(), 'empty upstream version is invalid'); | |
95 | $empty = Dpkg::Version->new('0:-0'); | |
96 | ok($empty eq '0:-0', "Dpkg::Version->new('0:-0') eq '0:-0'"); | |
97 | ok($empty->as_string() eq '0:-0', "Dpkg::Version->new('0:-0')->as_string() eq '0:-0'"); | |
98 | ok(!$empty->is_valid(), 'empty upstream version with epoch is invalid'); | |
99 | $empty = Dpkg::Version->new(':1.0'); | |
100 | ok($empty eq ':1.0', "Dpkg::Version->new(':1.0') eq ':1.0'"); | |
101 | ok($empty->as_string() eq ':1.0', "Dpkg::Version->new(':1.0')->as_string() eq ':1.0'"); | |
102 | ok(!$empty->is_valid(), 'empty epoch is invalid'); | |
103 | $empty = Dpkg::Version->new('1.0-'); | |
104 | ok($empty eq '1.0-', "Dpkg::Version->new('1.0-') eq '1.0-'"); | |
105 | ok($empty->as_string() eq '1.0-', "Dpkg::Version->new('1.0-')->as_string() eq '1.0-'"); | |
106 | ok(!$empty->is_valid(), 'empty revision is invalid'); | |
107 | my $ver = Dpkg::Version->new('10a:5.2'); | |
108 | ok(!$ver->is_valid(), 'bad epoch is invalid'); | |
109 | ok(!$ver, 'bool eval of invalid leads to false'); | |
110 | ok($ver eq '10a:5.2', 'invalid still same string 1/2'); | |
111 | $ver = Dpkg::Version->new('5.2@3-2'); | |
112 | ok($ver eq '5.2@3-2', 'invalid still same string 2/2'); | |
113 | ok(!$ver->is_valid(), 'illegal character is invalid'); | |
114 | $ver = Dpkg::Version->new('foo5.2'); | |
115 | ok(!$ver->is_valid(), 'version does not start with digit 1/2'); | |
116 | $ver = Dpkg::Version->new('0:foo5.2'); | |
117 | ok(!$ver->is_valid(), 'version does not start with digit 2/2'); | |
118 | ||
119 | # Native and non-native versions | |
120 | $ver = Dpkg::Version->new('1.0'); | |
121 | ok($ver->is_native(), 'upstream version is native'); | |
122 | $ver = Dpkg::Version->new('1:1.0'); | |
123 | ok($ver->is_native(), 'upstream version w/ epoch is native'); | |
124 | $ver = Dpkg::Version->new('1:1.0:1.0'); | |
125 | ok($ver->is_native(), 'upstream version w/ epoch and colon is native'); | |
126 | $ver = Dpkg::Version->new('1.0-1'); | |
127 | ok(!$ver->is_native(), 'upstream version w/ revision is not native'); | |
128 | $ver = Dpkg::Version->new('1.0-1.0-1'); | |
129 | ok(!$ver->is_native(), 'upstream version w/ dash and revision is not native'); | |
130 | ||
131 | # Other tests | |
132 | $ver = Dpkg::Version->new('1.2.3-4'); | |
133 | is($ver || 'default', '1.2.3-4', 'bool eval returns string representation'); | |
134 | $ver = Dpkg::Version->new('0'); | |
135 | is($ver || 'default', 'default', 'bool eval of version 0 is still false...'); | |
136 | ||
137 | # Comparisons | |
138 | foreach my $case (@tests) { | |
139 | my ($a, $b, $res) = split ' ', $case; | |
140 | my $va = Dpkg::Version->new($a, check => 1); | |
141 | my $vb = Dpkg::Version->new($b, check => 1); | |
142 | ||
143 | is("$va", $a, "String representation of Dpkg::Version($a) is $a"); | |
144 | is("$vb", $b, "String representation of Dpkg::Version($b) is $b"); | |
145 | ||
146 | is(version_compare($a, $b), $res, "$a cmp $b => $res"); | |
147 | is($va <=> $vb, $res, "Dpkg::Version($a) <=> Dpkg::Version($b) => $res"); | |
148 | foreach my $op (@ops) { | |
149 | my $norm_op = version_normalize_relation($op); | |
150 | if ($truth->{$res}{$op}) { | |
151 | ok(version_compare_relation($a, $norm_op, $b), "$a $op $b => true"); | |
152 | ok(obj_vercmp($va, $op, $vb), "Dpkg::Version($a) $op Dpkg::Version($b) => true"); | |
153 | ok(dpkg_vercmp($a, $op, $b), "dpkg --compare-versions -- $a $op $b => true"); | |
154 | } else { | |
155 | ok(!version_compare_relation($a, $norm_op, $b), "$a $op $b => false"); | |
156 | ok(!obj_vercmp($va, $op, $vb), "Dpkg::Version($a) $op Dpkg::Version($b) => false"); | |
157 | ok(!dpkg_vercmp($a, $op, $b), "dpkg --compare-versions -- $a $op $b => false"); | |
158 | } | |
159 | } | |
160 | } | |
161 | ||
162 | __DATA__ | |
163 | 1.0-1 2.0-2 -1 | |
164 | 2.2~rc-4 2.2-1 -1 | |
165 | 2.2-1 2.2~rc-4 1 | |
166 | 1.0000-1 1.0-1 0 | |
167 | 1 0:1 0 | |
168 | 0 0:0-0 0 | |
169 | 2:2.5 1:7.5 1 | |
170 | 1:0foo 0foo 1 | |
171 | 0:0foo 0foo 0 | |
172 | 0foo 0foo 0 | |
173 | 0foo-0 0foo 0 | |
174 | 0foo 0foo-0 0 | |
175 | 0foo 0fo 1 | |
176 | 0foo-0 0foo+ -1 | |
177 | 0foo~1 0foo -1 | |
178 | 0foo~foo+Bar 0foo~foo+bar -1 | |
179 | 0foo~~ 0foo~ -1 | |
180 | 1~ 1 -1 | |
181 | 12345+that-really-is-some-ver-0 12345+that-really-is-some-ver-10 -1 | |
182 | 0foo-0 0foo-01 -1 | |
183 | 0foo.bar 0foobar 1 | |
184 | 0foo.bar 0foo1bar 1 | |
185 | 0foo.bar 0foo0bar 1 | |
186 | 0foo1bar-1 0foobar-1 -1 | |
187 | 0foo2.0 0foo2 1 | |
188 | 0foo2.0.0 0foo2.10.0 -1 | |
189 | 0foo2.0 0foo2.0.0 -1 | |
190 | 0foo2.0 0foo2.10 -1 | |
191 | 0foo2.1 0foo2.10 -1 | |
192 | 1.09 1.9 0 | |
193 | 1.0.8+nmu1 1.0.8 1 | |
194 | 3.11 3.10+nmu1 1 | |
195 | 0.9j-20080306-4 0.9i-20070324-2 1 | |
196 | 1.2.0~b7-1 1.2.0~b6-1 1 | |
197 | 1.011-1 1.06-2 1 | |
198 | 0.0.9+dfsg1-1 0.0.8+dfsg1-3 1 | |
199 | 4.6.99+svn6582-1 4.6.99+svn6496-1 1 | |
200 | 53 52 1 | |
201 | 0.9.9~pre122-1 0.9.9~pre111-1 1 | |
202 | 2:2.3.2-2+lenny2 2:2.3.2-2 1 | |
203 | 1:3.8.1-1 3.8.GA-1 1 | |
204 | 1.0.1+gpl-1 1.0.1-2 1 | |
205 | 1a 1000a -1 |