std.t: create_file(): Use `>` as separate parameter in open()
[sunny256-utils.git] / tests / sortxml.t
blobb482e851e70a0bba8f0ac82cb7f3436af148a182
1 #!/usr/bin/env perl
3 #=======================================================================
4 # sortxml.t
5 # File ID: 8c064bc0-1463-11de-b31f-000475e441b9
7 # Test suite for sortxml(1).
9 # Character set: UTF-8
10 # ©opyleft 2009– Øyvind A. Holm <sunny@sunbase.org>
11 # License: GNU General Public License version 2 or later, see end of
12 # file for legal stuff.
13 #=======================================================================
15 use strict;
16 use warnings;
18 BEGIN {
19 use Test::More qw{no_plan};
20 # use_ok() goes here
23 use Getopt::Long;
25 local $| = 1;
27 our $CMD_BASENAME = "sortxml";
28 our $CMD = "../$CMD_BASENAME";
30 our %Opt = (
32 'all' => 0,
33 'help' => 0,
34 'quiet' => 0,
35 'todo' => 0,
36 'verbose' => 0,
37 'version' => 0,
41 our $progname = $0;
42 $progname =~ s/^.*\/(.*?)$/$1/;
43 our $VERSION = '0.0.0';
45 my %descriptions = ();
47 Getopt::Long::Configure('bundling');
48 GetOptions(
50 'all|a' => \$Opt{'all'},
51 'help|h' => \$Opt{'help'},
52 'quiet|q+' => \$Opt{'quiet'},
53 'todo|t' => \$Opt{'todo'},
54 'verbose|v+' => \$Opt{'verbose'},
55 'version' => \$Opt{'version'},
57 ) || die("$progname: Option error. Use -h for help.\n");
59 $Opt{'verbose'} -= $Opt{'quiet'};
60 $Opt{'help'} && usage(0);
61 if ($Opt{'version'}) {
62 print_version();
63 exit(0);
66 exit(main());
68 sub main {
69 # {{{
70 my $Retval = 0;
72 diag(sprintf('========== Executing %s v%s ==========',
73 $progname, $VERSION));
75 if ($Opt{'todo'} && !$Opt{'all'}) {
76 goto todo_section;
79 =pod
81 testcmd("$CMD command", # {{{
82 <<'END',
83 [expected stdout]
84 END
85 '',
87 'description',
90 # }}}
92 =cut
94 diag('Testing -h (--help) option...');
95 likecmd("$CMD -h", # {{{
96 '/ Show this help/i',
97 '/^$/',
99 'Option -h prints help screen',
102 # }}}
103 diag('Testing -v (--verbose) option...');
104 likecmd("$CMD -hv", # {{{
105 '/^\n\S+ \d+\.\d+\.\d+/s',
106 '/^$/',
108 'Option -v with -h returns version number and help screen',
111 # }}}
112 diag('Testing --version option...');
113 likecmd("$CMD --version", # {{{
114 '/^\S+ \d+\.\d+\.\d+/',
115 '/^$/',
117 'Option --version returns version number',
120 # }}}
121 diag("Test sorting...");
122 testcmd("$CMD -s b sortxml-files/a.xml", # {{{
123 <<END,
124 <?xml version="1.0" encoding="UTF-8"?>
125 <!DOCTYPE a [
126 <!ELEMENT a (b)+>
127 <!ELEMENT b (c , d?)>
128 <!ELEMENT c (#PCDATA)>
129 <!ELEMENT d (#PCDATA)>
133 <c>abc</c>
134 <d>dsfv</d>
135 </b>
137 <c>add</c>
138 </b>
140 <c>ba</c>
141 </b>
143 <c>bbb</c>
144 <d>gurgle</d>
145 </b>
147 <c>bbb</c>
148 <d>gurgle</d>
149 </b>
151 <c>ggg</c>
152 <d>fgh</d>
153 </b>
155 <c>ggg</c>
156 <d>pdfg</d>
157 </b>
159 <c>zsd</c>
160 </b>
161 </a>
165 "Sorting XML document",
168 # }}}
169 testcmd("$CMD -s b sortxml-files/oneliners.xml", # {{{
170 <<END,
171 <?xml version="1.0" encoding="UTF-8"?>
172 <!DOCTYPE a [
173 <!ELEMENT a (b)+>
174 <!ELEMENT b (c , d?)>
175 <!ELEMENT c (#PCDATA)>
176 <!ELEMENT d (#PCDATA)>
179 <b> <c>abc</c> <d>dsfv</d> </b>
180 <b> <c>add</c> </b>
181 <b> <c>ba</c> </b>
182 <b> <c>bbb</c> <d>gurgle</d> </b>
183 <b> <c>ggg</c> <d>fgh</d> </b>
184 <b> <c>ggg</c> <d>pdfg</d> </b>
185 <b> <c>zsd</c> </b>
186 </a>
190 "XML uses oneliners",
193 # }}}
194 diag("Test reverse sorting...");
195 testcmd("$CMD -s b -r sortxml-files/a.xml", # {{{
196 <<END,
197 <?xml version="1.0" encoding="UTF-8"?>
198 <!DOCTYPE a [
199 <!ELEMENT a (b)+>
200 <!ELEMENT b (c , d?)>
201 <!ELEMENT c (#PCDATA)>
202 <!ELEMENT d (#PCDATA)>
206 <c>zsd</c>
207 </b>
209 <c>ggg</c>
210 <d>pdfg</d>
211 </b>
213 <c>ggg</c>
214 <d>fgh</d>
215 </b>
217 <c>bbb</c>
218 <d>gurgle</d>
219 </b>
221 <c>bbb</c>
222 <d>gurgle</d>
223 </b>
225 <c>ba</c>
226 </b>
228 <c>add</c>
229 </b>
231 <c>abc</c>
232 <d>dsfv</d>
233 </b>
234 </a>
238 "Reverse sort XML document",
241 # }}}
242 testcmd("$CMD -s b -r sortxml-files/oneliners.xml", # {{{
243 <<END,
244 <?xml version="1.0" encoding="UTF-8"?>
245 <!DOCTYPE a [
246 <!ELEMENT a (b)+>
247 <!ELEMENT b (c , d?)>
248 <!ELEMENT c (#PCDATA)>
249 <!ELEMENT d (#PCDATA)>
252 <b> <c>zsd</c> </b>
253 <b> <c>ggg</c> <d>pdfg</d> </b>
254 <b> <c>ggg</c> <d>fgh</d> </b>
255 <b> <c>bbb</c> <d>gurgle</d> </b>
256 <b> <c>ba</c> </b>
257 <b> <c>add</c> </b>
258 <b> <c>abc</c> <d>dsfv</d> </b>
259 </a>
263 "Reverse sort onelined XML",
266 # }}}
267 diag('Testing -u (--unique) option...');
268 testcmd("$CMD -s b -u sortxml-files/a.xml", # {{{
269 <<END,
270 <?xml version="1.0" encoding="UTF-8"?>
271 <!DOCTYPE a [
272 <!ELEMENT a (b)+>
273 <!ELEMENT b (c , d?)>
274 <!ELEMENT c (#PCDATA)>
275 <!ELEMENT d (#PCDATA)>
279 <c>abc</c>
280 <d>dsfv</d>
281 </b>
283 <c>add</c>
284 </b>
286 <c>ba</c>
287 </b>
289 <c>bbb</c>
290 <d>gurgle</d>
291 </b>
293 <c>ggg</c>
294 <d>fgh</d>
295 </b>
297 <c>ggg</c>
298 <d>pdfg</d>
299 </b>
301 <c>zsd</c>
302 </b>
303 </a>
307 "Duplicated <b> removed",
310 # }}}
312 todo_section:
315 if ($Opt{'all'} || $Opt{'todo'}) {
316 diag('Running TODO tests...'); # {{{
318 TODO: {
320 local $TODO = '';
321 # Insert TODO tests here.
324 # TODO tests }}}
327 diag('Testing finished.');
328 return $Retval;
329 # }}}
330 } # main()
332 sub testcmd {
333 # {{{
334 my ($Cmd, $Exp_stdout, $Exp_stderr, $Exp_retval, $Desc) = @_;
335 defined($descriptions{$Desc}) &&
336 BAIL_OUT("testcmd(): '$Desc' description is used twice");
337 $descriptions{$Desc} = 1;
338 my $stderr_cmd = '';
339 my $cmd_outp_str = $Opt{'verbose'} >= 1 ? "\"$Cmd\" - " : '';
340 my $Txt = join('', $cmd_outp_str, defined($Desc) ? $Desc : '');
341 my $TMP_STDERR = "$CMD_BASENAME-stderr.tmp";
342 my $retval = 1;
344 if (defined($Exp_stderr)) {
345 $stderr_cmd = " 2>$TMP_STDERR";
347 $retval &= is(`$Cmd$stderr_cmd`, $Exp_stdout, "$Txt (stdout)");
348 my $ret_val = $?;
349 if (defined($Exp_stderr)) {
350 $retval &= is(file_data($TMP_STDERR), $Exp_stderr, "$Txt (stderr)");
351 unlink($TMP_STDERR);
352 } else {
353 diag("Warning: stderr not defined for '$Txt'");
355 $retval &= is($ret_val >> 8, $Exp_retval, "$Txt (retval)");
357 return $retval;
358 # }}}
359 } # testcmd()
361 sub likecmd {
362 # {{{
363 my ($Cmd, $Exp_stdout, $Exp_stderr, $Exp_retval, $Desc) = @_;
364 defined($descriptions{$Desc}) &&
365 BAIL_OUT("likecmd(): '$Desc' description is used twice");
366 $descriptions{$Desc} = 1;
367 my $stderr_cmd = '';
368 my $cmd_outp_str = $Opt{'verbose'} >= 1 ? "\"$Cmd\" - " : '';
369 my $Txt = join('', $cmd_outp_str, defined($Desc) ? $Desc : '');
370 my $TMP_STDERR = "$CMD_BASENAME-stderr.tmp";
371 my $retval = 1;
373 if (defined($Exp_stderr)) {
374 $stderr_cmd = " 2>$TMP_STDERR";
376 $retval &= like(`$Cmd$stderr_cmd`, $Exp_stdout, "$Txt (stdout)");
377 my $ret_val = $?;
378 if (defined($Exp_stderr)) {
379 $retval &= like(file_data($TMP_STDERR), $Exp_stderr, "$Txt (stderr)");
380 unlink($TMP_STDERR);
381 } else {
382 diag("Warning: stderr not defined for '$Txt'");
384 $retval &= is($ret_val >> 8, $Exp_retval, "$Txt (retval)");
386 return $retval;
387 # }}}
388 } # likecmd()
390 sub file_data {
391 # Return file content as a string {{{
392 my $File = shift;
393 my $Txt;
395 open(my $fp, '<', $File) or return undef;
396 local $/ = undef;
397 $Txt = <$fp>;
398 close($fp);
399 return $Txt;
400 # }}}
401 } # file_data()
403 sub print_version {
404 # Print program version {{{
405 print("$progname $VERSION\n");
406 return;
407 # }}}
408 } # print_version()
410 sub usage {
411 # Send the help message to stdout {{{
412 my $Retval = shift;
414 if ($Opt{'verbose'}) {
415 print("\n");
416 print_version();
418 print(<<"END");
420 Usage: $progname [options]
422 Contains tests for the $CMD_BASENAME(1) program.
424 Options:
426 -a, --all
427 Run all tests, also TODOs.
428 -h, --help
429 Show this help.
430 -q, --quiet
431 Be more quiet. Can be repeated to increase silence.
432 -t, --todo
433 Run only the TODO tests.
434 -v, --verbose
435 Increase level of verbosity. Can be repeated.
436 --version
437 Print version information.
440 exit($Retval);
441 # }}}
442 } # usage()
444 sub msg {
445 # Print a status message to stderr based on verbosity level {{{
446 my ($verbose_level, $Txt) = @_;
448 $verbose_level > $Opt{'verbose'} && return;
449 print(STDERR "$progname: $Txt\n");
450 return;
451 # }}}
452 } # msg()
454 __END__
456 # This program is free software; you can redistribute it and/or modify
457 # it under the terms of the GNU General Public License as published by
458 # the Free Software Foundation; either version 2 of the License, or (at
459 # your option) any later version.
461 # This program is distributed in the hope that it will be useful, but
462 # WITHOUT ANY WARRANTY; without even the implied warranty of
463 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
464 # See the GNU General Public License for more details.
466 # You should have received a copy of the GNU General Public License
467 # along with this program.
468 # If not, see L<http://www.gnu.org/licenses/>.
470 # vim: set fenc=UTF-8 ft=perl fdm=marker ts=4 sw=4 sts=4 et fo+=w :