3 #=======================================================================
5 # File ID: 3e1ac1d2-14cc-11e5-810f-000df06acc56
7 # Test suite for git-wip(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 = "git-wip";
28 our $CMD = "../$CMDB";
33 'git' => defined($ENV{'GITWIP_GIT'}) ?
$ENV{'GITWIP_GIT'} : 'git',
43 $progname =~ s/^.*\/(.*?)$/$1/;
44 our $VERSION = '0.0.0';
46 my %descriptions = ();
48 Getopt
::Long
::Configure
('bundling');
51 'all|a' => \
$Opt{'all'},
52 'git|g=s' => \
$Opt{'git'},
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'}) {
74 diag
(sprintf('========== Executing %s v%s ==========',
75 $progname, $VERSION));
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 # git(1) refuses to commit if user.email or user.name isn't defined,
124 # so abort if that's how things are.
125 like
(`git config --get user.email`,
127 'user.email is defined in Git') ||
128 BAIL_OUT
('user.email is not defined in Git');
129 like
(`git config --get user.name`,
131 'user.name is defined in Git') ||
132 BAIL_OUT
('user.name is not defined in Git');
134 my $Tmptop = "tmp-git-wip-t-$$-" . substr(rand, 2, 8);
135 diag
("Creating tempdir...");
136 ok
(mkdir($Tmptop), "mkdir [Tmptop]") or
137 die("$progname: $Tmptop: Cannot create directory: $!\n");
138 ok
(chdir($Tmptop), "chdir [Tmptop]") or
139 die("$progname: $Tmptop: Cannot chdir: $!\n");
141 diag
("Initialise repository...");
142 ok
(mkdir("repo"), "mkdir repo");
143 ok
(chdir("repo"), "chdir repo") || BAIL_OUT
("Cannot chdir repo");
144 likecmd
("$Opt{'git'} init", # {{{
148 'Initialise Git repository',
152 likecmd
("../../$CMD", # {{{
154 '/fatal: ambiguous argument \'HEAD\': ' .
155 'unknown revision or path not in the working tree\./s',
157 'master doesn\'t exist yet',
161 create_empty_commit
("Init");
162 testcmd
("$Opt{'git'} branch", # {{{
170 commit_new_file
("file1.txt");
171 is
(commit_log
(''), <<END, "Commit log with file1.txt is ok"); # {{{
172 04c774c04d6f3c4915c535077c24bc00dba82828 Add file1.txt
173 4b825dc642cb6eb9a060e54bf8d69288fbee4904 Init
177 diag
("Test without arguments...");
178 testcmd
("../../$CMD", # {{{
180 "Switched to branch 'wip'\n",
182 "Command without arguments uses default 'wip' branch",
186 testcmd
("../../$CMD", # {{{
188 "Switched to branch 'wip.wip'\n",
190 "No args again, create wip.wip",
194 diag
("Test -D option...");
195 likecmd
("../../$CMD -D", # {{{
196 '/^wip\\nAlready up[ \-]to[ \-]date.*Deleted branch wip\.wip.*$/s',
197 '/^Switched to branch \'wip\'\\n$/',
199 "Delete empty branch with -D",
203 diag
("Test -m option...");
204 create_and_switch_to_subbranch
('add-files', 'wip.add-files');
205 is
(commit_log
(''), <<END, "Commit log is unchanged since file1.txt"); # {{{
206 04c774c04d6f3c4915c535077c24bc00dba82828 Add file1.txt
207 4b825dc642cb6eb9a060e54bf8d69288fbee4904 Init
211 commit_new_file
("file2.txt");
212 commit_new_file
("file3.txt");
213 is
(commit_log
(''), <<END, "Commit log with file3.txt is ok"); # {{{
214 5c0f1e77ac82fe0d382b312202a467446d5948f4 Add file3.txt
215 9ddbad632f192f4edd053709b3aaedc95bd9ac0e Add file2.txt
216 04c774c04d6f3c4915c535077c24bc00dba82828 Add file1.txt
217 4b825dc642cb6eb9a060e54bf8d69288fbee4904 Init
221 likecmd
("../../$CMD -m", # {{{
222 '/^wip\\nMerge made by .*'
223 . ' create mode 100644 file2\.txt\\n'
224 . ' create mode 100644 file3\.txt\\n'
225 . 'Deleted branch wip\.add-files .*'
227 '/^Switched to branch \'wip\'\\n$/',
229 "Merge wip.add-files to parent (wip)",
233 is
(commit_log
(''), <<END, "Commit log after -m is ok"); # {{{
234 5c0f1e77ac82fe0d382b312202a467446d5948f4 Merge branch 'wip.add-files' into wip
235 5c0f1e77ac82fe0d382b312202a467446d5948f4 Add file3.txt
236 9ddbad632f192f4edd053709b3aaedc95bd9ac0e Add file2.txt
237 04c774c04d6f3c4915c535077c24bc00dba82828 Add file1.txt
238 4b825dc642cb6eb9a060e54bf8d69288fbee4904 Init
242 create_and_switch_to_subbranch
('more-files', 'wip.more-files');
243 commit_new_file
("file4.txt");
244 diag
("Test -p option...");
245 likecmd
("../../$CMD -p", # {{{
247 '/^Switched to branch \'wip\'\\n$/',
253 testcmd
("$Opt{'git'} branch", # {{{
261 "Branches after -p looks fine",
265 likecmd
("echo y | ../../$CMD -p", # {{{
267 '/^git-wip: Type \'y\' \+ Enter to set active branch ' .
268 'to \'master\' \(git checkout\)\.\.\.' .
269 'Switched to branch \'master\'$/',
271 'If -p option and no parent, checkout master',
275 testcmd
("$Opt{'git'} branch", # {{{
283 "Check current branch status after -p to master",
287 likecmd
("../../$CMD", # {{{
289 '/^fatal: [Aa] branch named \'wip\' already exists\.?\n$/',
291 "wip branch already exists",
295 testcmd
("$Opt{'git'} branch", # {{{
303 "We're still on master because \"wip\" already exists",
307 likecmd
("$Opt{'git'} checkout wip.more-files", # {{{
309 '/^Switched to branch \'wip\.more-files\'\\n$/',
311 "Go back to wip.more-files",
315 commit_new_file
("file5.txt");
316 is
(commit_log
(''), <<END, "Commit log with file5.txt is ok"); # {{{
317 375860ebe00ccc64321c2ade0c1525e7428458fa Add file5.txt
318 6c4c1a3c2c479e74e02394040d6da63046c1458c Add file4.txt
319 5c0f1e77ac82fe0d382b312202a467446d5948f4 Merge branch 'wip.add-files' into wip
320 5c0f1e77ac82fe0d382b312202a467446d5948f4 Add file3.txt
321 9ddbad632f192f4edd053709b3aaedc95bd9ac0e Add file2.txt
322 04c774c04d6f3c4915c535077c24bc00dba82828 Add file1.txt
323 4b825dc642cb6eb9a060e54bf8d69288fbee4904 Init
327 diag
("Testing -s option...");
328 likecmd
("../../$CMD -s", # {{{
329 '/^wip\\nUpdating [0-9a-f]+\.\.[0-9a-f]+\\n' .
330 'Fast(-| )forward\\n' .
331 'Squash commit -- not updating HEAD\\n' .
333 ' create mode 100644 file4\.txt\\n' .
334 ' create mode 100644 file5\.txt\\n' .
336 '/^Switched to branch \'wip\'\\n$/',
338 "Squash wip.more-files to parent with -s",
342 is
(commit_log
(''), <<END, "Commit log after squash (-s) is ok"); # {{{
343 5c0f1e77ac82fe0d382b312202a467446d5948f4 Merge branch 'wip.add-files' into wip
344 5c0f1e77ac82fe0d382b312202a467446d5948f4 Add file3.txt
345 9ddbad632f192f4edd053709b3aaedc95bd9ac0e Add file2.txt
346 04c774c04d6f3c4915c535077c24bc00dba82828 Add file1.txt
347 4b825dc642cb6eb9a060e54bf8d69288fbee4904 Init
351 likecmd
("$Opt{'git'} commit -m 'Squash wip.more-files into wip'", # {{{
352 '/^\[wip [0-9a-f]+\] Squash wip\.more-files into wip\\n' .
353 ' 2 files changed, 2 insertions\(\+\)(, 0 deletions\(-\))?\\n' .
354 ' create mode 100644 file4\.txt\\n' .
355 ' create mode 100644 file5\.txt\\n$' .
359 "Commit squashed changes",
363 is
(commit_log
(''), <<END, "Commit log after squash commit is ok"); # {{{
364 375860ebe00ccc64321c2ade0c1525e7428458fa Squash wip.more-files into wip
365 5c0f1e77ac82fe0d382b312202a467446d5948f4 Merge branch 'wip.add-files' into wip
366 5c0f1e77ac82fe0d382b312202a467446d5948f4 Add file3.txt
367 9ddbad632f192f4edd053709b3aaedc95bd9ac0e Add file2.txt
368 04c774c04d6f3c4915c535077c24bc00dba82828 Add file1.txt
369 4b825dc642cb6eb9a060e54bf8d69288fbee4904 Init
373 likecmd
("echo y | ../../$CMD -m", # {{{
376 . ' create mode 100644 file2\.txt\\n'
377 . ' create mode 100644 file3\.txt\\n'
378 . ' create mode 100644 file4\.txt\\n'
379 . ' create mode 100644 file5\.txt\\n'
380 . 'Deleted branch wip \(was [0-9a-f]+\)\.\\n$'
382 '/^git-wip: Type \'y\' \+ Enter to merge wip to master\.\.\.' .
383 'Switched to branch \'master\'\\n$/',
385 "Merge wip to master with -m",
389 is
(commit_log
(''), <<END, "Commit log after -m"); # {{{
390 375860ebe00ccc64321c2ade0c1525e7428458fa Merge branch 'wip'
391 375860ebe00ccc64321c2ade0c1525e7428458fa Squash wip.more-files into wip
392 5c0f1e77ac82fe0d382b312202a467446d5948f4 Merge branch 'wip.add-files' into wip
393 5c0f1e77ac82fe0d382b312202a467446d5948f4 Add file3.txt
394 9ddbad632f192f4edd053709b3aaedc95bd9ac0e Add file2.txt
395 04c774c04d6f3c4915c535077c24bc00dba82828 Add file1.txt
396 4b825dc642cb6eb9a060e54bf8d69288fbee4904 Init
400 likecmd
("echo y | ../../$CMD -m", # {{{
402 '/^Is already on master, nowhere to merge branch\\n$/',
404 "Option -m on master doesn't work",
408 likecmd
("echo y | ../../$CMD -s", # {{{
410 '/^Is already on master, nowhere to squash branch\\n$/',
416 diag
("Test for unknown options...");
417 likecmd
("../../$CMD -W", # {{{
419 '/^git-wip: -W: Unknown option\\n$/',
421 "It doesn't recognise -W",
425 likecmd
("../../$CMD -e", # {{{
427 '/^git-wip: -e: Unknown option\\n$/',
429 "It doesn't recognise -e (used by echo)",
433 diag
("Cleaning up temp files...");
434 ok
(chdir(".."), "chdir .."); # From $Tmptop/repo/
435 likecmd
("rm -rf repo", # {{{
443 ok
(chdir(".."), "chdir .."); # From $Tmptop/
445 ok
(-d
$Tmptop, "[Tmptop] exists");
446 ok
(rmdir($Tmptop), "rmdir([Tmptop])");
447 ok
(!-e
$Tmptop, "Tempdir is gone");
452 if ($Opt{'all'} || $Opt{'todo'}) {
453 diag
('Running TODO tests...'); # {{{
458 # Insert TODO tests here.
464 diag
('Testing finished.');
469 sub create_and_switch_to_subbranch
{
471 my ($branch, $exp_branch) = @_;
472 testcmd
("../../$CMD $branch",
474 "Switched to branch '$exp_branch'\n",
476 "Create subbranch '$branch' and checkout '$exp_branch'",
480 } # create_and_switch_to_subbranch()
486 open(my $pipefp, "$Opt{'git'} log --format='%T %s' --topo-order $ref |") or
487 return("'$Opt{'git'} log' pipe error: $!\n");
496 sub commit_new_file
{
499 ok
(!-e
$file, "$file doesn't exist");
500 ok
(open(my $outfp, ">$file"), "Create file '$file'");
501 ok
(print($outfp "This is $file\n"), "Add content to $file");
502 ok
(close($outfp), "Close $file");
503 ok
(-f
$file, "$file exists and is a regular file");
504 is
(file_data
($file), "This is $file\n", "Contents of $file is ok");
505 testcmd
("$Opt{'git'} add \"$file\"",
509 "$Opt{'git'} add $file",
511 likecmd
("$Opt{'git'} commit -m \"Add $file\"",
515 "$Opt{'git'} commit (add $file)",
518 } # commit_new_file()
520 sub create_empty_commit
{
523 likecmd
("$Opt{'git'} commit --allow-empty -m \"$msg\"",
524 '/.*/', '/.*/', 0, "Create empty commit");
527 } # create_empty_commit()
531 my ($Cmd, $Exp_stdout, $Exp_stderr, $Exp_retval, $Desc) = @_;
532 defined($descriptions{$Desc}) &&
533 BAIL_OUT
("testcmd(): '$Desc' description is used twice");
534 $descriptions{$Desc} = 1;
536 my $cmd_outp_str = $Opt{'verbose'} >= 1 ?
"\"$Cmd\" - " : '';
537 my $Txt = join('', $cmd_outp_str, defined($Desc) ?
$Desc : '');
538 my $TMP_STDERR = "$CMDB-stderr.tmp";
541 if (defined($Exp_stderr)) {
542 $stderr_cmd = " 2>$TMP_STDERR";
544 $retval &= is
(`$Cmd$stderr_cmd`, $Exp_stdout, "$Txt (stdout)");
546 if (defined($Exp_stderr)) {
547 $retval &= is
(file_data
($TMP_STDERR), $Exp_stderr, "$Txt (stderr)");
550 diag
("Warning: stderr not defined for '$Txt'");
552 $retval &= is
($ret_val >> 8, $Exp_retval, "$Txt (retval)");
560 my ($Cmd, $Exp_stdout, $Exp_stderr, $Exp_retval, $Desc) = @_;
561 defined($descriptions{$Desc}) &&
562 BAIL_OUT
("likecmd(): '$Desc' description is used twice");
563 $descriptions{$Desc} = 1;
565 my $cmd_outp_str = $Opt{'verbose'} >= 1 ?
"\"$Cmd\" - " : '';
566 my $Txt = join('', $cmd_outp_str, defined($Desc) ?
$Desc : '');
567 my $TMP_STDERR = "$CMDB-stderr.tmp";
570 if (defined($Exp_stderr)) {
571 $stderr_cmd = " 2>$TMP_STDERR";
573 $retval &= like
(`$Cmd$stderr_cmd`, $Exp_stdout, "$Txt (stdout)");
575 if (defined($Exp_stderr)) {
576 $retval &= like
(file_data
($TMP_STDERR), $Exp_stderr, "$Txt (stderr)");
579 diag
("Warning: stderr not defined for '$Txt'");
581 $retval &= is
($ret_val >> 8, $Exp_retval, "$Txt (retval)");
588 # Return file content as a string {{{
592 open(my $fp, '<', $File) or return undef;
601 # Print program version {{{
602 print("$progname $VERSION\n");
608 # Send the help message to stdout {{{
611 if ($Opt{'verbose'}) {
617 Usage: $progname [options]
619 Contains tests for the $CMDB(1) program.
624 Run all tests, also TODOs.
626 Specify alternative git executable to use. Used to execute the tests
627 with different git versions. This can also be set with the GITWIP_GIT
628 environment variable.
632 Be more quiet. Can be repeated to increase silence.
634 Run only the TODO tests.
636 Increase level of verbosity. Can be repeated.
638 Print version information.
646 # Print a status message to stderr based on verbosity level {{{
647 my ($verbose_level, $Txt) = @_;
649 $verbose_level > $Opt{'verbose'} && return;
650 print(STDERR
"$progname: $Txt\n");
657 # This program is free software; you can redistribute it and/or modify
658 # it under the terms of the GNU General Public License as published by
659 # the Free Software Foundation; either version 2 of the License, or (at
660 # your option) any later version.
662 # This program is distributed in the hope that it will be useful, but
663 # WITHOUT ANY WARRANTY; without even the implied warranty of
664 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
665 # See the GNU General Public License for more details.
667 # You should have received a copy of the GNU General Public License
668 # along with this program.
669 # If not, see L<http://www.gnu.org/licenses/>.
671 # vim: set fenc=UTF-8 ft=perl fdm=marker ts=4 sw=4 sts=4 et fo+=w :