doc: Move Perl version baseline as the first perl coding style subsection
[dpkg.git] / scripts / t / Dpkg_Substvars.t
blob61ac0276bc80ddb06224c7d17e193e0888fb12ae
1 #!/usr/bin/perl
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/>.
16 use strict;
17 use warnings;
19 use Test::More tests => 56;
20 use Test::Dpkg qw(:paths);
22 use Dpkg ();
23 use Dpkg::Arch qw(get_host_arch);
25 $ENV{DEB_BUILD_ARCH} = 'amd64';
26 $ENV{DEB_HOST_ARCH} = 'amd64';
28 use_ok('Dpkg::Substvars');
30 my $datadir = test_get_data_path();
32 my $output;
33 my $expected;
35 my $s = Dpkg::Substvars->new();
37 $s->load("$datadir/substvars1");
39 # simple value tests
40 is($s->get('var1'), 'Some value', 'var1');
41 is($s->get('var2'), 'Some other value', 'var2');
42 is($s->get('var3'), 'Yet another value', 'var3');
43 is($s->get('var4'), undef, 'no var4');
44 is($s->get('optional-var5'), 'Optionally used value', 'optional-var5');
46 # Set automatic variable
47 $s->set_as_auto('var_auto', 'auto');
48 is($s->get('var_auto'), 'auto', 'get var_auto');
50 $expected = <<'VARS';
51 optional-var5?=Optionally used value
52 var1=Some value
53 var2=Some other value
54 var3=Yet another value
55 VARS
56 is($s->output(), $expected, 'No automatic variables output');
58 # overriding
59 $s->set('var1', 'New value');
60 is($s->get('var1'), 'New value', 'var1 updated');
62 # deleting
63 $s->delete('var3');
64 is($s->get('var3'), undef, 'var3 deleted');
66 # default variables
67 is($s->get('Newline'), "\n", 'newline');
68 is($s->get('Space'), ' ', 'space');
69 is($s->get('Tab'), "\t", 'tab');
70 is($s->get('dpkg:Version'), $Dpkg::PROGVERSION, 'dpkg version 1');
72 # special variables
73 is($s->get('Arch'), undef, 'no arch');
74 $s->set_arch_substvars();
75 is($s->get('Arch'), get_host_arch(), 'arch');
77 is($s->get('vendor:Id'), undef, 'no vendor id');
78 is($s->get('vendor:Name'), undef, 'no vendor name');
79 $s->set_vendor_substvars();
80 is($s->get('vendor:Id'), 'debian', 'vendor id');
81 is($s->get('vendor:Name'), 'Debian', 'vendor name');
83 is($s->get($_), undef, 'no ' . $_) for qw/binary:Version source:Version source:Upstream-Version/;
84 $s->set_version_substvars('1:2.3.4~5-6.7.8~nmu9', '1:2.3.4~5-6.7.8~nmu9+bin0');
85 is($s->get('binary:Version'), '1:2.3.4~5-6.7.8~nmu9+bin0', 'binary:Version');
86 is($s->get('source:Version'), '1:2.3.4~5-6.7.8~nmu9', 'source:Version');
87 is($s->get('source:Upstream-Version'), '1:2.3.4~5', 'source:Upstream-Version');
88 $s->set_version_substvars('2.3.4~5-6.7.8~nmu9+b1', '1:2.3.4~5-6.7.8~nmu9+b1');
89 is($s->get('binary:Version'), '1:2.3.4~5-6.7.8~nmu9+b1', 'binary:Version');
90 is($s->get('source:Version'), '2.3.4~5-6.7.8~nmu9', 'source:Version');
91 is($s->get('source:Upstream-Version'), '2.3.4~5', 'source:Upstream-Version');
92 $s->set_version_substvars('1:2.3.4~5-6.7.8~nmu9+b0');
93 is($s->get('binary:Version'), '1:2.3.4~5-6.7.8~nmu9+b0', 'binary:Version');
94 is($s->get('source:Version'), '1:2.3.4~5-6.7.8~nmu9', 'source:Version');
95 is($s->get('source:Upstream-Version'), '1:2.3.4~5', 'source:Upstream-Version');
97 is($s->get($_), undef, 'no ' . $_) foreach qw(source:Synopsis source:Extended-Description);
98 $s->set_desc_substvars("short synopsis\nthis is the long\nextended text\n");
99 is($s->get('source:Synopsis'), 'short synopsis', 'contents of source:Synopsis');
100 is($s->get('source:Extended-Description'), "this is the long\nextended text\n",
101 'contents of source:Extended-Description');
103 my %ctrl_fields = (
104 'Some-Field' => 'some-value',
105 'Other-Field' => 'other-value',
106 'Alter-Field' => 'alter-value',
108 is($s->get($_), undef, 'no ' . $_) foreach sort keys %ctrl_fields;
109 $s->set_field_substvars(\%ctrl_fields, 'ctrl');
110 is($s->get('ctrl:Some-Field'), 'some-value', 'contents of ctrl:Some-Field');
111 is($s->get('ctrl:Other-Field'), 'other-value', 'contents of ctrl:Other-Field');
112 is($s->get('ctrl:Alter-Field'), 'alter-value', 'contents of ctrl:Alter-Field');
114 # Direct replace: few
115 is($s->substvars('This is a string ${var1} with variables ${binary:Version}'),
116 'This is a string New value with variables 1:2.3.4~5-6.7.8~nmu9+b0',
117 'direct replace, few times');
119 # Direct replace: many times (more than the recursive limit)
120 $s->set('dr', 'feed');
121 is($s->substvars('${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}' .
122 '${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}' .
123 '${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}' .
124 '${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}' .
125 '${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}' .
126 '${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}${dr}'),
127 'feedfeedfeedfeedfeedfeedfeedfeedfeedfeed' .
128 'feedfeedfeedfeedfeedfeedfeedfeedfeedfeed' .
129 'feedfeedfeedfeedfeedfeedfeedfeedfeedfeed' .
130 'feedfeedfeedfeedfeedfeedfeedfeedfeedfeed' .
131 'feedfeedfeedfeedfeedfeedfeedfeedfeedfeed' .
132 'feedfeedfeedfeedfeedfeedfeedfeedfeedfeed',
133 'direct replace, many times');
135 # Add a test prefix to error and warning messages.
136 $s->set_msg_prefix('test ');
138 $output = q{};
139 $SIG{__WARN__} = sub { $output .= $_[0] };
140 is($s->substvars('This is a string with unknown variable ${blubb}'),
141 'This is a string with unknown variable ',
142 'substvars missing');
143 delete $SIG{__WARN__};
144 is($output,
145 'Dpkg_Substvars.t: warning: test substitution variable ${blubb} used, but is not defined' . "\n",
146 'missing variables warning');
148 # Recursive replace: Simple.
149 $s->set('rvar', 'recursive ${var1}');
150 is($s->substvars('This is a string with ${rvar}'),
151 'This is a string with recursive New value',
152 'recursive replace simple');
154 # Recursive replace: Constructed variables.
155 $s->set('partref', 'recursive result');
156 $s->set('part1', '${pa');
157 $s->set('part2', 'rtr');
158 $s->set('part3', 'ef}');
159 is($s->substvars('Constructed ${part1}${part2}${part3} replace'),
160 'Constructed recursive result replace',
161 'recursive constructed variable');
163 # Recursive replace: Cycle.
164 $s->set('ref0', '${ref1}');
165 $s->set('ref1', '${ref2}');
166 $s->set('ref2', '${ref0}');
168 eval {
169 $s->substvars('Cycle reference ${ref0}');
172 $output = $@ // q{};
173 is($output,
174 'Dpkg_Substvars.t: error: test too many ${ref0} substitutions ' .
175 "(recursive?) in 'Cycle reference \${ref1}'\n",
176 'recursive cyclic expansion is limited');
178 # Recursive replace: Billion laughs.
179 $s->set('ex0', ':)');
180 $s->set('ex1', '${ex0}${ex0}${ex0}${ex0}${ex0}${ex0}${ex0}${ex0}${ex0}${ex0}');
181 $s->set('ex2', '${ex1}${ex1}${ex1}${ex1}${ex1}${ex1}${ex1}${ex1}${ex1}${ex1}');
182 $s->set('ex3', '${ex2}${ex2}${ex2}${ex2}${ex2}${ex2}${ex2}${ex2}${ex2}${ex2}');
183 $s->set('ex4', '${ex3}${ex3}${ex3}${ex3}${ex3}${ex3}${ex3}${ex3}${ex3}${ex3}');
184 $s->set('ex5', '${ex4}${ex4}${ex4}${ex4}${ex4}${ex4}${ex4}${ex4}${ex4}${ex4}');
185 $s->set('ex6', '${ex5}${ex5}${ex5}${ex5}${ex5}${ex5}${ex5}${ex5}${ex5}${ex5}');
186 $s->set('ex7', '${ex6}${ex6}${ex6}${ex6}${ex6}${ex6}${ex6}${ex6}${ex6}${ex6}');
187 $s->set('ex8', '${ex7}${ex7}${ex7}${ex7}${ex7}${ex7}${ex7}${ex7}${ex7}${ex7}');
188 $s->set('ex9', '${ex8}${ex8}${ex8}${ex8}${ex8}${ex8}${ex8}${ex8}${ex8}${ex8}');
190 eval {
191 $s->substvars('Billion laughs ${ex9}');
194 $output = $@ // q{};
195 is($output,
196 'Dpkg_Substvars.t: error: test too many ${ex1} substitutions ' .
197 "(recursive?) in 'Billion laughs :):):):):):):):):):):):):):)" .
198 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
199 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
200 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
201 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
202 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
203 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
204 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
205 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
206 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
207 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
208 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
209 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
210 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
211 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
212 ':):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)' .
213 ':):):):):):):):):):):):):):):):):):):):):):):):):):)' .
214 '${ex0}${ex0}${ex0}${ex0}${ex0}${ex0}${ex0}${ex0}${ex0}${ex0}' .
215 '${ex2}${ex2}${ex2}${ex2}${ex2}' .
216 '${ex3}${ex3}${ex3}${ex3}${ex3}${ex3}${ex3}${ex3}${ex3}' .
217 '${ex4}${ex4}${ex4}${ex4}${ex4}${ex4}${ex4}${ex4}${ex4}' .
218 '${ex5}${ex5}${ex5}${ex5}${ex5}${ex5}${ex5}${ex5}${ex5}' .
219 '${ex6}${ex6}${ex6}${ex6}${ex6}${ex6}${ex6}${ex6}${ex6}' .
220 '${ex7}${ex7}${ex7}${ex7}${ex7}${ex7}${ex7}${ex7}${ex7}' .
221 '${ex8}${ex8}${ex8}${ex8}${ex8}${ex8}${ex8}${ex8}${ex8}' .
222 "'\n",
223 'recursive or exponential expansion is limited');
225 # Strange input
226 is($s->substvars('Nothing to $ ${substitute here}, is it ${}?, it ${is'),
227 'Nothing to $ ${substitute here}, is it ${}?, it ${is',
228 'substvars strange');
230 # Warnings about unused variables
231 $output = '';
232 $SIG{__WARN__} = sub { $output .= $_[0] };
233 $s->warn_about_unused();
234 delete $SIG{__WARN__};
235 is($output,
236 'Dpkg_Substvars.t: warning: test substitution variable ${var2} unused, but is defined' . "\n",
237 'unused variables warnings');
239 # Disable warnings for a certain variable
240 $s->set_as_used('var_used', 'used');
241 $s->mark_as_used('var2');
242 $output = '';
243 $SIG{__WARN__} = sub { $output .= $_[0] };
244 $s->warn_about_unused();
245 delete $SIG{__WARN__};
246 is($output, '', 'disabled unused variables warnings');
248 $s->delete('var_used');
250 # Variable filters
251 my $sf;
253 $expected = <<'VARS';
254 name3=Yet another value
255 name4=Name value
256 otherprefix:var7=Quux
257 var1=Some value
258 var2=Some other value
259 VARS
260 $sf = Dpkg::Substvars->new("$datadir/substvars2");
261 $sf->filter(remove => sub { $_[0] =~ m/^prefix:/ });
262 is($sf->output(), $expected, 'Filter remove variables');
264 $expected = <<'VARS';
265 otherprefix:var7=Quux
266 prefix:var5=Foo
267 var1=Some value
268 var2=Some other value
269 VARS
270 $sf = Dpkg::Substvars->new("$datadir/substvars2");
271 $sf->filter(keep => sub { $_[0] =~ m/var/ });
272 is($sf->output(), $expected, 'Filter keep variables');
274 $expected = <<'VARS';
275 prefix:name6=Bar
276 VARS
277 $sf = Dpkg::Substvars->new("$datadir/substvars2");
278 $sf->filter(remove => sub { $_[0] =~ m/var/ },
279 keep => sub { $_[0] =~ m/^prefix:/ });
280 is($sf->output(), $expected, 'Filter keep and remove variables');