3 #=======================================================================
5 # File ID: dd33f796-6a8c-11e5-8a5b-fefdb24f8e10
7 # Test suite for edit-sqlite3(1).
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 #=======================================================================
19 use Test
::More
qw{no_plan
};
27 our $CMDB = "edit-sqlite3";
28 our $CMD = "../$CMDB";
42 $progname =~ s/^.*\/(.*?)$/$1/;
43 our $VERSION = '0.0.0';
45 my %descriptions = ();
47 Getopt
::Long
::Configure
('bundling');
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'}) {
72 diag
(sprintf('========== Executing %s v%s ==========',
73 $progname, $VERSION));
75 $ENV{'EDITOR'} = 'cat';
77 if ($Opt{'todo'} && !$Opt{'all'}) {
83 testcmd("$CMD command", # {{{
96 diag
('Testing -h (--help) option...');
97 likecmd
("$CMD -h", # {{{
101 'Option -h prints help screen',
105 diag
('Testing -v (--verbose) option...');
106 likecmd
("$CMD -h -v", # {{{
107 '/^\n\S+ \d+\.\d+\.\d+/s',
110 'Option -v with -h returns version number and help screen',
114 diag
('Testing --version option...');
115 likecmd
("$CMD --version", # {{{
116 '/^\S+ \d+\.\d+\.\d+/',
119 'Option --version returns version number',
123 likecmd
('sqlite3 --version', # {{{
127 'sqlite3 is available',
128 ) || BAIL_OUT
('sqlite3 is not available');
131 ok
(chdir('edit-sqlite3-files'), 'chdir edit-sqlite3-files');
132 testcmd
("tar xzf sqlite-databases.tar.gz", # {{{
136 'Untar sqlite-databases.tar.gz',
141 testcmd
("$CMD", # {{{
143 "edit-sqlite3: No SQLite database specified\n",
145 'No database specified',
149 testcmd
("$CMD nonexisting_db", # {{{
151 "edit-sqlite3: nonexisting_db: File not found or is not a regular file\n",
153 'Non-existing database specified',
157 testcmd
("$CMD sqlite-databases", # {{{
159 "edit-sqlite3: sqlite-databases: File not found or is not a regular file\n",
161 'Specify directory as SQLite database',
165 ok
(chdir('sqlite-databases'), 'chdir sqlite-databases');
167 testcmd
("$CMD -n ok.sqlite", # {{{
169 "edit-sqlite3: ok.sqlite: File would be edited\n",
171 'Specify valid SQLite database with -n',
175 likecmd
("$CMD --dry-run invalid.sqlite", # {{{
177 '/edit-sqlite3: invalid\.sqlite: SQLite database contains errors/',
179 'Specify invalid SQLite db with --dry-run',
183 diag
('Test file permissions...');
185 skip
("Running tests as root", 13) unless ($<);
186 ok
(chmod(0444, 'ok.sqlite'), 'Make ok.sqlite read-only');
187 testcmd
("$CMD ok.sqlite", # {{{
189 "edit-sqlite3: ok.sqlite: File is not writable by you\n",
191 'File is not writable, abort',
195 ok
(chmod(0222, 'ok.sqlite'), 'Make ok.sqlite unreadable');
196 testcmd
("$CMD ok.sqlite", # {{{
198 "edit-sqlite3: ok.sqlite: File is not readable by you\n",
200 'File is not readable, abort',
204 ok
(chmod(0000, 'ok.sqlite'),
205 'Make ok.sqlite unreadable and unwritable');
206 testcmd
("$CMD ok.sqlite", # {{{
208 "edit-sqlite3: ok.sqlite: File is not readable by you\n",
210 'File is not readable nor writable, abort',
214 ok
(chmod(0644, 'ok.sqlite'), 'Restore permissions of ok.sqlite');
216 diag
('Abort if the file is a symlink...');
217 ok
(symlink('ok.sqlite', 'symlink-to-file.sqlite'), 'Create symlink to ok.sqlite');
218 testcmd
("$CMD -n symlink-to-file.sqlite", # {{{
220 "edit-sqlite3: symlink-to-file.sqlite: File is a symlink\n",
222 'File is a symlink to a regular file, abort',
226 ok
(unlink('symlink-to-file.sqlite'), 'Delete symlink-to-file.sqlite');
227 ok
(symlink('.', 'symlink-to-dir.sqlite'), 'Create symlink to \'.\'');
228 testcmd
("$CMD --dry-run symlink-to-dir.sqlite", # {{{
230 "edit-sqlite3: symlink-to-dir.sqlite: File is a symlink\n",
232 'File is a symlink to a directory, abort',
236 ok
(unlink('symlink-to-dir.sqlite'), 'Delete symlink-to-dir.sqlite');
237 ok
(symlink('nonexisting', 'symlink-to-nonexisting.sqlite'), 'Create symlink to nonexisting');
238 testcmd
("$CMD --dry-run symlink-to-nonexisting.sqlite", # {{{
240 "edit-sqlite3: symlink-to-nonexisting.sqlite: File is a symlink\n",
242 'File is a symlink to a non-existing file, abort',
246 ok
(unlink('symlink-to-nonexisting.sqlite'), 'Delete symlink-to-nonexisting.sqlite');
247 diag
('Test empty and undefined $EDITOR environment variable...');
249 testcmd
("$CMD ok.sqlite", # {{{
251 "edit-sqlite3: \$EDITOR environment variable is not defined\n",
253 '$EDITOR environment variable is empty',
257 $ENV{'EDITOR'} = undef;
258 testcmd
("$CMD ok.sqlite", # {{{
260 "edit-sqlite3: \$EDITOR environment variable is not defined\n",
262 '$EDITOR environment variable is undefined',
266 diag
('Test without --dry-run...');
267 $ENV{'EDITOR'} = 'cat';
268 likecmd
("$CMD invalid.sqlite", # {{{
270 '/edit-sqlite3: invalid\.sqlite: SQLite database contains errors/',
272 'Specify invalid SQLite db without --dry-run',
276 testcmd
("$CMD ok.sqlite", # {{{
279 PRAGMA foreign_keys=OFF;
281 CREATE TABLE t (a integer);
286 'Valid db without --dry-run',
290 my $bckfile = glob("ok.sqlite.2*.bck");
291 testcmd
("sqlite3 $bckfile .dump", # {{{
293 PRAGMA foreign_keys=OFF;
295 CREATE TABLE t (a integer);
300 'Data of backup file is identical to ok.sqlite',
304 ok
(unlink($bckfile), 'Remove backup file');
305 create_file
('ok.sqlite.sql', <<END); # {{{
306 PRAGMA foreign_keys=OFF;
308 dCREATE TABLE t (a integer);
313 likecmd
("echo q | $CMD ok.sqlite", # {{{
316 . 'PRAGMA foreign_keys=OFF;\n'
317 . 'BEGIN TRANSACTION;\n'
318 . 'dCREATE TABLE t \(a integer\);\n'
323 . 'edit-sqlite3: Press Enter to edit again, or q to abort\.\.\.'
326 'Display "edit again" message if invalid SQL',
331 ok
(unlink('ok.sqlite.sql'), 'Delete ok.sqlite.sql');
332 ok
(unlink(glob("ok.sqlite.2*.bck")), 'Delete backup file');
333 ok
(unlink('invalid.sqlite'), 'Delete invalid.sqlite');
334 ok
(unlink('ok.sqlite'), 'Delete ok.sqlite');
335 ok
(chdir('..'), 'chdir ..');
336 ok
(rmdir('sqlite-databases'), 'rmdir sqlite-databases');
341 if ($Opt{'all'} || $Opt{'todo'}) {
342 diag
('Running TODO tests...'); # {{{
347 # Insert TODO tests here.
353 diag
('Testing finished.');
360 my ($Cmd, $Exp_stdout, $Exp_stderr, $Exp_retval, $Desc) = @_;
361 defined($descriptions{$Desc}) &&
362 BAIL_OUT
("testcmd(): '$Desc' description is used twice");
363 $descriptions{$Desc} = 1;
365 my $cmd_outp_str = $Opt{'verbose'} >= 1 ?
"\"$Cmd\" - " : '';
366 my $Txt = join('', $cmd_outp_str, defined($Desc) ?
$Desc : '');
367 my $TMP_STDERR = "$CMDB-stderr.tmp";
370 if (defined($Exp_stderr)) {
371 $stderr_cmd = " 2>$TMP_STDERR";
373 $retval &= is
(`$Cmd$stderr_cmd`, $Exp_stdout, "$Txt (stdout)");
375 if (defined($Exp_stderr)) {
376 $retval &= is
(file_data
($TMP_STDERR), $Exp_stderr, "$Txt (stderr)");
379 diag
("Warning: stderr not defined for '$Txt'");
381 $retval &= is
($ret_val >> 8, $Exp_retval, "$Txt (retval)");
389 my ($Cmd, $Exp_stdout, $Exp_stderr, $Exp_retval, $Desc) = @_;
390 defined($descriptions{$Desc}) &&
391 BAIL_OUT
("likecmd(): '$Desc' description is used twice");
392 $descriptions{$Desc} = 1;
394 my $cmd_outp_str = $Opt{'verbose'} >= 1 ?
"\"$Cmd\" - " : '';
395 my $Txt = join('', $cmd_outp_str, defined($Desc) ?
$Desc : '');
396 my $TMP_STDERR = "$CMDB-stderr.tmp";
399 if (defined($Exp_stderr)) {
400 $stderr_cmd = " 2>$TMP_STDERR";
402 $retval &= like
(`$Cmd$stderr_cmd`, $Exp_stdout, "$Txt (stdout)");
404 if (defined($Exp_stderr)) {
405 $retval &= like
(file_data
($TMP_STDERR), $Exp_stderr, "$Txt (stderr)");
408 diag
("Warning: stderr not defined for '$Txt'");
410 $retval &= is
($ret_val >> 8, $Exp_retval, "$Txt (retval)");
417 # Return file content as a string {{{
421 open(my $fp, '<', $File) or return undef;
430 # Create new file and fill it with data {{{
431 my ($file, $text) = @_;
433 if (open(my $fp, ">$file")) {
439 "$file was successfully created",
442 return($retval); # 0 if error, 1 if ok
447 # Print program version {{{
448 print("$progname $VERSION\n");
454 # Send the help message to stdout {{{
457 if ($Opt{'verbose'}) {
463 Usage: $progname [options]
465 Contains tests for the $CMDB(1) program.
470 Run all tests, also TODOs.
474 Be more quiet. Can be repeated to increase silence.
476 Run only the TODO tests.
478 Increase level of verbosity. Can be repeated.
480 Print version information.
488 # Print a status message to stderr based on verbosity level {{{
489 my ($verbose_level, $Txt) = @_;
491 $verbose_level > $Opt{'verbose'} && return;
492 print(STDERR
"$progname: $Txt\n");
499 # This program is free software; you can redistribute it and/or modify
500 # it under the terms of the GNU General Public License as published by
501 # the Free Software Foundation; either version 2 of the License, or (at
502 # your option) any later version.
504 # This program is distributed in the hope that it will be useful, but
505 # WITHOUT ANY WARRANTY; without even the implied warranty of
506 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
507 # See the GNU General Public License for more details.
509 # You should have received a copy of the GNU General Public License
510 # along with this program.
511 # If not, see L<http://www.gnu.org/licenses/>.
513 # vim: set fenc=UTF-8 ft=perl fdm=marker ts=4 sw=4 sts=4 et fo+=w :