chiark / gitweb /
lib/dpkg/tarfn.c: Kludge `tar_header_decode' to handle spurious `errno'.
[dpkg] / scripts / t / Dpkg_Version.t
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