std/c/src/: Fix hardcoded year in std.1.man + fix alignment in main()
[sunny256-utils.git] / tests / sort-sqlite.t
blob7297339d9b93cd862a70168b81e2bf39e513bf7b
1 #!/usr/bin/env perl
3 #=======================================================================
4 # sort-sqlite.t
5 # File ID: b5f7d80e-70ff-11e5-96fa-fefdb24f8e10
7 # Test suite for sort-sqlite(1).
9 # Character set: UTF-8
10 # ©opyleft 2015– Ø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;
24 use IPC::Open3;
26 local $| = 1;
28 our $CMDB = "sort-sqlite";
29 our $CMD = "../$CMDB";
30 our $SQLITE = "sqlite3";
32 our %Opt = (
34 'all' => 0,
35 'help' => 0,
36 'quiet' => 0,
37 'todo' => 0,
38 'verbose' => 0,
39 'version' => 0,
43 our $progname = $0;
44 $progname =~ s/^.*\/(.*?)$/$1/;
45 our $VERSION = '0.0.0';
47 my %descriptions = ();
49 Getopt::Long::Configure('bundling');
50 GetOptions(
52 'all|a' => \$Opt{'all'},
53 'help|h' => \$Opt{'help'},
54 'quiet|q+' => \$Opt{'quiet'},
55 'todo|t' => \$Opt{'todo'},
56 'verbose|v+' => \$Opt{'verbose'},
57 'version' => \$Opt{'version'},
59 ) || die("$progname: Option error. Use -h for help.\n");
61 $Opt{'verbose'} -= $Opt{'quiet'};
62 $Opt{'help'} && usage(0);
63 if ($Opt{'version'}) {
64 print_version();
65 exit(0);
68 my $sql_error = 0;
70 exit(main());
72 sub main {
73 # {{{
74 my $Retval = 0;
76 diag(sprintf('========== Executing %s v%s ==========',
77 $progname, $VERSION));
79 if ($Opt{'todo'} && !$Opt{'all'}) {
80 goto todo_section;
83 =pod
85 testcmd("$CMD command", # {{{
86 <<'END',
87 [expected stdout]
88 END
89 '',
91 'description',
94 # }}}
96 =cut
98 diag('Testing -h (--help) option...');
99 likecmd("$CMD -h", # {{{
100 '/ Show this help/i',
101 '/^$/',
103 'Option -h prints help screen',
106 # }}}
107 diag('Testing -v (--verbose) option...');
108 likecmd("$CMD -hv", # {{{
109 '/^\n\S+ \d+\.\d+\.\d+/s',
110 '/^$/',
112 'Option -v with -h returns version number and help screen',
115 # }}}
116 diag('Testing --version option...');
117 likecmd("$CMD --version", # {{{
118 '/^\S+ \d+\.\d+\.\d+/',
119 '/^$/',
121 'Option --version returns version number',
124 # }}}
125 ok(chdir("sort-sqlite-files"), "chdir sort-sqlite-files");
126 $CMD = "../$CMD";
127 testcmd("tar xzf sqlite-dbs.tar.gz", # {{{
131 "Untar sqlite-dbs.tar.gz",
134 # }}}
135 ok(chdir("sqlite-dbs"), "chdir sqlite-dbs");
136 $CMD = "../$CMD";
137 testcmd("$CMD -c abc.def non-existing.sqlite", # {{{
139 "sort-sqlite: non-existing.sqlite: File is not readable by you or is not a regular file\n",
141 "Try to open a non-existing file",
144 # }}}
145 testcmd("$CMD unsorted1.sqlite", # {{{
147 "sort-sqlite: Missing -c/--column option\n",
149 "Missing -c/--column option",
152 # }}}
153 likecmd("$CMD -c non.existing unsorted1.sqlite", # {{{
154 '/^$/',
155 '/^.*sort-sqlite: unsorted1.sqlite: sqlite3 error, aborting\n$/s',
157 "Try to sort unsorted1.sqlite with unknown table and column",
160 # }}}
161 is(sqlite_dump("unsorted1.sqlite"), # {{{
162 <<END,
163 CREATE TABLE t (
164 a TEXT
171 "unsorted1.sqlite is not modified",
174 # }}}
175 testcmd("$CMD -c t.a unsorted1.sqlite", # {{{
179 "Sort unsorted1.sqlite",
182 # }}}
183 is(sqlite_dump("unsorted1.sqlite"), # {{{
184 <<END,
185 CREATE TABLE t (
186 a TEXT
193 "unsorted1.sqlite looks ok",
196 # }}}
197 ok(-f "unsorted1.sqlite.20151012T164244Z.bck", "Backup file 1 exists");
198 testcmd("$CMD -v --column t.a -c u.a unsorted2.sqlite " .
199 "unsorted3.sqlite", # {{{
201 "sort-sqlite: Sorting unsorted2.sqlite\n" .
202 "sort-sqlite: Sorting unsorted3.sqlite\n",
204 "Sort several tables in unsorted2.sqlite",
207 # }}}
208 is(sqlite_dump("unsorted2.sqlite"), # {{{
209 <<END,
210 CREATE TABLE u (
211 a TEXT
213 CREATE TABLE t (
214 a TEXT
223 u|aa
224 u|→
226 "unsorted2.sqlite looks ok",
229 # }}}
230 is(sqlite_dump("unsorted3.sqlite"), # {{{
231 <<END,
232 CREATE TABLE u (
233 a TEXT
235 CREATE TABLE one (
236 single TEXT
238 CREATE TABLE t (
239 a TEXT
241 one|z
249 u|aa
250 u|→
252 "unsorted3.sqlite looks ok",
255 # }}}
256 testcmd("$CMD -c t.a unsorted4.sqlite --column u.a", # {{{
260 "Sort unsorted4.sqlite, entries have several lines",
263 # }}}
264 ok(-f "unsorted4.sqlite.20161103T235439Z.bck", "Backup file 4 exists");
265 is(sqlite_dump("unsorted4.sqlite"), # {{{
266 <<END,
267 CREATE TABLE u (
268 a TEXT
270 CREATE TABLE t (
271 a TEXT
273 t|\n\nanother\n\nmulti\nline\n
279 u|aa
280 u|multi\nline\nhere
281 u|→
283 "unsorted4.sqlite looks ok",
286 # }}}
287 ok(-f "unsorted2.sqlite.20151012T164437Z.bck", "Backup file 2 exists");
288 ok(-f "unsorted3.sqlite.20151012T181141Z.bck", "Backup file 3 exists");
289 ok(unlink("unsorted1.sqlite"), "Delete unsorted1.sqlite");
290 ok(unlink("unsorted2.sqlite"), "Delete unsorted2.sqlite");
291 ok(unlink("unsorted3.sqlite"), "Delete unsorted3.sqlite");
292 ok(unlink("unsorted4.sqlite"), "Delete unsorted4.sqlite");
293 ok(unlink("unsorted1.sqlite.20151012T164244Z.bck"), "Delete backup 1");
294 ok(unlink("unsorted2.sqlite.20151012T164437Z.bck"), "Delete backup 2");
295 ok(unlink("unsorted3.sqlite.20151012T181141Z.bck"), "Delete backup 3");
296 ok(unlink("unsorted4.sqlite.20161103T235439Z.bck"), "Delete backup 4");
297 ok(chdir(".."), "chdir ..");
298 ok(rmdir("sqlite-dbs"), "rmdir sqlite-dbs");
300 todo_section:
303 if ($Opt{'all'} || $Opt{'todo'}) {
304 diag('Running TODO tests...'); # {{{
306 TODO: {
308 local $TODO = '';
309 # Insert TODO tests here.
312 # TODO tests }}}
315 diag('Testing finished.');
316 return $Retval;
317 # }}}
318 } # main()
320 sub sql {
321 # {{{
322 my ($db, $sql) = @_;
323 my @retval = ();
325 msg(5, "sql(): db = '$db'");
326 local(*CHLD_IN, *CHLD_OUT, *CHLD_ERR);
328 $sql_error = 0;
329 my $pid = open3(*CHLD_IN, *CHLD_OUT, *CHLD_ERR, $SQLITE, $db) or (
330 $sql_error = 1,
331 msg(0, "sql(): open3() error: $!"),
332 return("sql() error"),
334 msg(5, "sql(): sql = '$sql'");
335 print(CHLD_IN "$sql\n") or msg(0, "sql(): print CHLD_IN error: $!");
336 close(CHLD_IN);
337 @retval = <CHLD_OUT>;
338 msg(5, "sql(): retval = '" . join('|', @retval) . "'");
339 my @child_stderr = <CHLD_ERR>;
340 if (scalar(@child_stderr)) {
341 msg(1, "$SQLITE error: " . join('', @child_stderr));
342 $sql_error = 1;
344 return(join('', @retval));
345 # }}}
346 } # sql()
348 sub sqlite_dump {
349 # Return contents of database file {{{
350 my $File = shift;
352 return sql($File, <<END);
353 .nullvalue NULL
354 .schema
355 SELECT 'one', * FROM one;
356 SELECT 't', * FROM t;
357 SELECT 'u', * FROM u;
359 # }}}
360 } # sqlite_dump()
362 sub testcmd {
363 # {{{
364 my ($Cmd, $Exp_stdout, $Exp_stderr, $Exp_retval, $Desc) = @_;
365 defined($descriptions{$Desc}) &&
366 BAIL_OUT("testcmd(): '$Desc' description is used twice");
367 $descriptions{$Desc} = 1;
368 my $stderr_cmd = '';
369 my $cmd_outp_str = $Opt{'verbose'} >= 1 ? "\"$Cmd\" - " : '';
370 my $Txt = join('', $cmd_outp_str, defined($Desc) ? $Desc : '');
371 my $TMP_STDERR = "$CMDB-stderr.tmp";
372 my $retval = 1;
374 if (defined($Exp_stderr)) {
375 $stderr_cmd = " 2>$TMP_STDERR";
377 $retval &= is(`$Cmd$stderr_cmd`, $Exp_stdout, "$Txt (stdout)");
378 my $ret_val = $?;
379 if (defined($Exp_stderr)) {
380 $retval &= is(file_data($TMP_STDERR), $Exp_stderr, "$Txt (stderr)");
381 unlink($TMP_STDERR);
382 } else {
383 diag("Warning: stderr not defined for '$Txt'");
385 $retval &= is($ret_val >> 8, $Exp_retval, "$Txt (retval)");
387 return $retval;
388 # }}}
389 } # testcmd()
391 sub likecmd {
392 # {{{
393 my ($Cmd, $Exp_stdout, $Exp_stderr, $Exp_retval, $Desc) = @_;
394 defined($descriptions{$Desc}) &&
395 BAIL_OUT("likecmd(): '$Desc' description is used twice");
396 $descriptions{$Desc} = 1;
397 my $stderr_cmd = '';
398 my $cmd_outp_str = $Opt{'verbose'} >= 1 ? "\"$Cmd\" - " : '';
399 my $Txt = join('', $cmd_outp_str, defined($Desc) ? $Desc : '');
400 my $TMP_STDERR = "$CMDB-stderr.tmp";
401 my $retval = 1;
403 if (defined($Exp_stderr)) {
404 $stderr_cmd = " 2>$TMP_STDERR";
406 $retval &= like(`$Cmd$stderr_cmd`, $Exp_stdout, "$Txt (stdout)");
407 my $ret_val = $?;
408 if (defined($Exp_stderr)) {
409 $retval &= like(file_data($TMP_STDERR), $Exp_stderr, "$Txt (stderr)");
410 unlink($TMP_STDERR);
411 } else {
412 diag("Warning: stderr not defined for '$Txt'");
414 $retval &= is($ret_val >> 8, $Exp_retval, "$Txt (retval)");
416 return $retval;
417 # }}}
418 } # likecmd()
420 sub file_data {
421 # Return file content as a string {{{
422 my $File = shift;
423 my $Txt;
425 open(my $fp, '<', $File) or return undef;
426 local $/ = undef;
427 $Txt = <$fp>;
428 close($fp);
429 return $Txt;
430 # }}}
431 } # file_data()
433 sub print_version {
434 # Print program version {{{
435 print("$progname $VERSION\n");
436 return;
437 # }}}
438 } # print_version()
440 sub usage {
441 # Send the help message to stdout {{{
442 my $Retval = shift;
444 if ($Opt{'verbose'}) {
445 print("\n");
446 print_version();
448 print(<<"END");
450 Usage: $progname [options]
452 Contains tests for the $CMDB(1) program.
454 Options:
456 -a, --all
457 Run all tests, also TODOs.
458 -h, --help
459 Show this help.
460 -q, --quiet
461 Be more quiet. Can be repeated to increase silence.
462 -t, --todo
463 Run only the TODO tests.
464 -v, --verbose
465 Increase level of verbosity. Can be repeated.
466 --version
467 Print version information.
470 exit($Retval);
471 # }}}
472 } # usage()
474 sub msg {
475 # Print a status message to stderr based on verbosity level {{{
476 my ($verbose_level, $Txt) = @_;
478 $verbose_level > $Opt{'verbose'} && return;
479 print(STDERR "$progname: $Txt\n");
480 return;
481 # }}}
482 } # msg()
484 __END__
486 # This program is free software; you can redistribute it and/or modify
487 # it under the terms of the GNU General Public License as published by
488 # the Free Software Foundation; either version 2 of the License, or (at
489 # your option) any later version.
491 # This program is distributed in the hope that it will be useful, but
492 # WITHOUT ANY WARRANTY; without even the implied warranty of
493 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
494 # See the GNU General Public License for more details.
496 # You should have received a copy of the GNU General Public License
497 # along with this program.
498 # If not, see L<http://www.gnu.org/licenses/>.
500 # vim: set fenc=UTF-8 ft=perl fdm=marker ts=4 sw=4 sts=4 et fo+=w :