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.
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.
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/>.
21 use IPC
::Cmd
qw(can_run);
23 use Dpkg
::ErrorHandling
;
27 report_options
(quiet_warnings
=> 1);
38 plan tests
=> scalar(@tests) * (3 * scalar(@ops) + 4) + 27;
40 my $have_dpkg = can_run
('dpkg');
43 my ($a, $cmp, $b) = @_;
46 spawn
(exec => [ 'dpkg', '--compare-versions', '--', $a, $cmp, $b ],
47 error_to_string
=> \
$stderr, wait_child
=> 1, nocheck
=> 1);
48 diag
("dpkg --compare-versions error=$?: $stderr") if $?
and $?
!= 256;
54 my ($a, $cmp, $b) = @_;
55 return $a < $b if $cmp eq '<<';
56 return $a lt $b if $cmp eq 'lt';
57 return $a <= $b if $cmp eq '<=' or $cmp eq '<';
58 return $a le $b if $cmp eq 'le';
59 return $a == $b if $cmp eq '=';
60 return $a eq $b if $cmp eq 'eq';
61 return $a >= $b if $cmp eq '>=' or $cmp eq '>';
62 return $a ge $b if $cmp eq 'ge';
63 return $a > $b if $cmp eq '>>';
64 return $a gt $b if $cmp eq 'gt';
70 '<=' => 1, 'le' => 1, '<' => 1,
72 '>=' => 0, 'ge' => 0, '>' => 0,
77 '<=' => 1, 'le' => 1, '<' => 1,
79 '>=' => 1, 'ge' => 1, '>' => 1,
84 '<=' => 0, 'le' => 0, '<' => 0,
86 '>=' => 1, 'ge' => 1, '>' => 1,
91 # Handling of empty/invalid versions
92 my $empty = Dpkg
::Version
->new('');
93 ok
($empty eq '', "Dpkg::Version->new('') eq ''");
94 ok
($empty->as_string() eq '', "Dpkg::Version->new('')->as_string() eq ''");
95 ok
(!$empty->is_valid(), 'empty version is invalid');
96 $empty = Dpkg
::Version
->new('-0');
97 ok
($empty eq '', "Dpkg::Version->new('-0') eq '-0'");
98 ok
($empty->as_string() eq '-0', "Dpkg::Version->new('-0')->as_string() eq '-0'");
99 ok
(!$empty->is_valid(), 'empty upstream version is invalid');
100 $empty = Dpkg
::Version
->new('0:-0');
101 ok
($empty eq '0:-0', "Dpkg::Version->new('0:-0') eq '0:-0'");
102 ok
($empty->as_string() eq '0:-0', "Dpkg::Version->new('0:-0')->as_string() eq '0:-0'");
103 ok
(!$empty->is_valid(), 'empty upstream version with epoch is invalid');
104 $empty = Dpkg
::Version
->new(':1.0');
105 ok
($empty eq ':1.0', "Dpkg::Version->new(':1.0') eq ':1.0'");
106 ok
($empty->as_string() eq ':1.0', "Dpkg::Version->new(':1.0')->as_string() eq ':1.0'");
107 ok
(!$empty->is_valid(), 'empty epoch is invalid');
108 $empty = Dpkg
::Version
->new('1.0-');
109 ok
($empty eq '1.0-', "Dpkg::Version->new('1.0-') eq '1.0-'");
110 ok
($empty->as_string() eq '1.0-', "Dpkg::Version->new('1.0-')->as_string() eq '1.0-'");
111 ok
(!$empty->is_valid(), 'empty revision is invalid');
112 my $ver = Dpkg
::Version
->new('10a:5.2');
113 ok
(!$ver->is_valid(), 'bad epoch is invalid');
114 ok
(!$ver, 'bool eval of invalid leads to false');
115 ok
($ver eq '10a:5.2', 'invalid still same string 1/2');
116 $ver = Dpkg
::Version
->new('5.2@3-2');
117 ok
($ver eq '5.2@3-2', 'invalid still same string 2/2');
118 ok
(!$ver->is_valid(), 'illegal character is invalid');
119 $ver = Dpkg
::Version
->new('foo5.2');
120 ok
(!$ver->is_valid(), 'version does not start with digit 1/2');
121 $ver = Dpkg
::Version
->new('0:foo5.2');
122 ok
(!$ver->is_valid(), 'version does not start with digit 2/2');
124 # Native and non-native versions
125 $ver = Dpkg
::Version
->new('1.0');
126 ok
($ver->is_native(), 'upstream version is native');
127 $ver = Dpkg
::Version
->new('1:1.0');
128 ok
($ver->is_native(), 'upstream version w/ epoch is native');
129 $ver = Dpkg
::Version
->new('1:1.0:1.0');
130 ok
($ver->is_native(), 'upstream version w/ epoch and colon is native');
131 $ver = Dpkg
::Version
->new('1.0-1');
132 ok
(!$ver->is_native(), 'upstream version w/ revision is not native');
133 $ver = Dpkg
::Version
->new('1.0-1.0-1');
134 ok
(!$ver->is_native(), 'upstream version w/ dash and revision is not native');
137 foreach my $case (@tests) {
138 my ($a, $b, $res) = split ' ', $case;
139 my $va = Dpkg
::Version
->new($a, check
=> 1);
140 my $vb = Dpkg
::Version
->new($b, check
=> 1);
142 is
("$va", $a, "String representation of Dpkg::Version($a) is $a");
143 is
("$vb", $b, "String representation of Dpkg::Version($b) is $b");
145 is
(version_compare
($a, $b), $res, "$a cmp $b => $res");
146 is
($va <=> $vb, $res, "Dpkg::Version($a) <=> Dpkg::Version($b) => $res");
147 foreach my $op (@ops) {
148 my $norm_op = version_normalize_relation
($op);
149 if ($truth->{$res}{$op}) {
150 ok
(version_compare_relation
($a, $norm_op, $b), "$a $op $b => true");
151 ok
(obj_vercmp
($va, $op, $vb), "Dpkg::Version($a) $op Dpkg::Version($b) => true");
154 skip
'dpkg not available', 1 if not $have_dpkg;
156 ok
(dpkg_vercmp
($a, $op, $b), "dpkg --compare-versions -- $a $op $b => true");
159 ok
(!version_compare_relation
($a, $norm_op, $b), "$a $op $b => false");
160 ok
(!obj_vercmp
($va, $op, $vb), "Dpkg::Version($a) $op Dpkg::Version($b) => false");
163 skip
'dpkg not available', 1 if not $have_dpkg;
165 ok
(!dpkg_vercmp
($a, $op, $b), "dpkg --compare-versions -- $a $op $b => false");
187 0foo
~foo
+Bar
0foo
~foo
+bar
-1
190 12345+that
-really
-is
-some
-ver
-0 12345+that
-really
-is
-some
-ver
-10 -1
195 0foo1bar
-1 0foobar
-1 -1
197 0foo2
.0
.0 0foo2
.10
.0 -1
204 0.9j
-20080306-4 0.9i
-20070324-2 1
205 1.2.0~b7
-1 1.2.0~b6
-1 1
207 0.0.9+dfsg1
-1 0.0.8+dfsg1
-3 1
208 4.6.99+svn6582
-1 4.6.99+svn6496
-1 1
210 0.9.9~pre122
-1 0.9.9~pre111
-1 1
211 2:2.3.2-2+lenny2
2:2.3.2-2 1
213 1.0.1+gpl
-1 1.0.1-2 1