Various improvements to tests (#52)

Various improvements to tests
This commit is contained in:
Adam Spiers 2019-06-28 16:48:59 +01:00 committed by GitHub
commit 6d195f95e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 446 additions and 364 deletions

28
NEWS
View file

@ -98,12 +98,7 @@ News file for Stow.
consistency. consistency.
- INSTALL.md now also documents how to build directly from git. - INSTALL.md now also documents how to build directly from git.
** Fixes for bugs and technical debt ** Fixes for bugs, tests, and other technical debt
*** Fix for test suite on Cygwin
Thanks to Lucas Theisen for this fix!
*** aclocal.m4 was updated using aclocal 1.15.1.
*** Add Docker files for convenient testing across multiple Perl versions *** Add Docker files for convenient testing across multiple Perl versions
@ -118,17 +113,28 @@ News file for Stow.
Thanks to Charles LeDoux for this! Thanks to Charles LeDoux for this!
*** Add Coveralls integration with GitHub
This means that test coverage analysis will be automatically be run
on any pull requests submitted to GitHub.
*** Set up continuous testing via Travis CI *** Set up continuous testing via Travis CI
This means that the test suite will be automatically run on any This means that the test suite will be automatically run on any
pull requests submitted to GitHub, as well as "make distcheck" pull requests submitted to GitHub, as well as "make distcheck"
and "./Build distcheck". and "./Build distcheck".
*** Add Coveralls integration with GitHub
This means that test coverage analysis will be automatically be run
on any pull requests submitted to GitHub.
*** Miscellaneous improvements to the test suite
These include proper testing of the distinct impact of ~/.stowrc
and .stowrc in the directory from which Stow is invoked.
*** Fix for test suite on Cygwin
Thanks to Lucas Theisen for this fix!
*** aclocal.m4 was updated using aclocal 1.15.1.
*** Miscellaneous fixes to the build and distribution process *** Miscellaneous fixes to the build and distribution process
*** Improve handling of directories with unusual names *** Improve handling of directories with unusual names

View file

@ -515,14 +515,14 @@ sub main {
#============================================================================ #============================================================================
sub process_options { sub process_options {
# Get cli options. # Get cli options.
my ($cli_options, my ($cli_options,
$pkgs_to_unstow, $pkgs_to_unstow,
$pkgs_to_stow) = parse_options(@ARGV); $pkgs_to_stow) = parse_options(@ARGV);
# Get the .stowrc options. # Get the .stowrc options.
# Note that rc_pkgs_to_unstow and rc_pkgs_to_stow are ignored. # Note that rc_pkgs_to_unstow and rc_pkgs_to_stow are ignored.
my ($rc_options, my ($rc_options,
$rc_pkgs_to_unstow, $rc_pkgs_to_unstow,
$rc_pkgs_to_stow) = get_config_file_options(); $rc_pkgs_to_stow) = get_config_file_options();
# Merge .stowrc and command line options. # Merge .stowrc and command line options.
@ -547,8 +547,8 @@ sub process_options {
# Example: parse_options(@ARGV) # Example: parse_options(@ARGV)
# Returns : (\%options, \@pkgs_to_unstow, \@pkgs_to_stow) # Returns : (\%options, \@pkgs_to_unstow, \@pkgs_to_stow)
# Throws : a fatal error if a bad command line option is given # Throws : a fatal error if a bad command line option is given
# Comments : Used for parsing both command line options and rc file. Used # Comments : Used for parsing both command line options and rc file. Used
# for parsing only. Sanity checks and post-processing belong in # for parsing only. Sanity checks and post-processing belong in
# process_options(). # process_options().
#============================================================================ #============================================================================
sub parse_options { sub parse_options {
@ -614,6 +614,7 @@ sub parse_options {
return (\%options, \@pkgs_to_unstow, \@pkgs_to_stow); return (\%options, \@pkgs_to_unstow, \@pkgs_to_stow);
} }
sub sanitize_path_options { sub sanitize_path_options {
my ($options) = @_; my ($options) = @_;

View file

@ -354,7 +354,9 @@ sub within_target_do {
# Parameters: $stow_path => relative path from current (i.e. target) directory # Parameters: $stow_path => relative path from current (i.e. target) directory
# : to the stow dir containing the package to be stowed # : to the stow dir containing the package to be stowed
# : $package => the package whose contents are being stowed # : $package => the package whose contents are being stowed
# : $target => subpath relative to package and target directories # : $target => subpath relative to package directory which needs
# : stowing as a symlink at subpath relative to target
# : directory.
# : $source => relative path from the (sub)dir of target # : $source => relative path from the (sub)dir of target
# : to symlink source # : to symlink source
# Returns : n/a # Returns : n/a
@ -415,7 +417,9 @@ sub stow_contents {
# Parameters: $stow_path => relative path from current (i.e. target) directory # Parameters: $stow_path => relative path from current (i.e. target) directory
# : to the stow dir containing the node to be stowed # : to the stow dir containing the node to be stowed
# : $package => the package containing the node being stowed # : $package => the package containing the node being stowed
# : $target => subpath relative to package and target directories # : $target => subpath relative to package directory of node which
# : needs stowing as a symlink at subpath relative to
# : target directory.
# : $source => relative path to symlink source from the dir of target # : $source => relative path to symlink source from the dir of target
# Returns : n/a # Returns : n/a
# Throws : fatal exception if a conflict arises # Throws : fatal exception if a conflict arises
@ -912,18 +916,20 @@ sub path_owned_by_package {
# Name : find_stowed_path() # Name : find_stowed_path()
# Purpose : determine whether the given link points to a member of a # Purpose : determine whether the given link points to a member of a
# : stowed package # : stowed package
# Parameters: $target => path to a symbolic link under current directory # Parameters: $target => path to a symbolic link under current directory.
# : Must share a common prefix with $self->{stow_path}
# : $source => where that link points to (needed because link # : $source => where that link points to (needed because link
# : might not exist yet due to two-phase approach, # : might not exist yet due to two-phase approach,
# : so we can't just call readlink()) # : so we can't just call readlink()). This must be
# : expressed relative to (the directory containing)
# : $target.
# Returns : ($path, $stow_path, $package) where $path and $stow_path are # Returns : ($path, $stow_path, $package) where $path and $stow_path are
# : relative from the current (i.e. target) directory. $path # : relative from the current (i.e. target) directory. $path
# : is the full relative path, $stow_path is the relative path # : is the full relative path, $stow_path is the relative path
# : to the stow directory, and $package is the name of the package. # : to the stow directory, and $package is the name of the package.
# : or ('', '', '') if link is not owned by stow # : or ('', '', '') if link is not owned by stow
# Throws : n/a # Throws : n/a
# Comments : Needs # Comments : Allow for stow dir not being under target dir.
# : Allow for stow dir not being under target dir.
# : We could put more logic under here for multiple stow dirs. # : We could put more logic under here for multiple stow dirs.
#============================================================================ #============================================================================
sub find_stowed_path { sub find_stowed_path {
@ -955,6 +961,12 @@ sub find_stowed_path {
# If no .stow file was found, we need to find out whether it's # If no .stow file was found, we need to find out whether it's
# owned by the current stow directory, in which case $path will be # owned by the current stow directory, in which case $path will be
# a prefix of $self->{stow_path}. # a prefix of $self->{stow_path}.
if (substr($path, 0, 1) eq '/' xor substr($self->{stow_path}, 0, 1) eq '/')
{
warn "BUG in find_stowed_path? Absolute/relative mismatch between " .
"Stow dir $self->{stow_path} and path $path";
}
my @stow_path = split m{/+}, $self->{stow_path}; my @stow_path = split m{/+}, $self->{stow_path};
# Strip off common prefixes until one is empty # Strip off common prefixes until one is empty
@ -971,7 +983,7 @@ sub find_stowed_path {
} }
my $package = shift @path; my $package = shift @path;
debug(4, " yes - by $package in " . join_paths(@path)); debug(4, " yes - by $package in " . join_paths(@path));
return ($path, $self->{stow_path}, $package); return ($path, $self->{stow_path}, $package);
} }

View file

@ -30,46 +30,46 @@ use Test::Output;
use English qw(-no_match_vars); use English qw(-no_match_vars);
init_test_dirs(); init_test_dirs();
cd("$OUT_DIR/target"); cd("$TEST_DIR/target");
# setup stow directory # setup stow directory
make_dir('stow'); make_path('stow');
make_file('stow/.stow'); make_file('stow/.stow');
# perl # perl
make_dir('stow/perl/bin'); make_path('stow/perl/bin');
make_file('stow/perl/bin/perl'); make_file('stow/perl/bin/perl');
make_file('stow/perl/bin/a2p'); make_file('stow/perl/bin/a2p');
make_dir('stow/perl/info'); make_path('stow/perl/info');
make_file('stow/perl/info/perl'); make_file('stow/perl/info/perl');
make_dir('stow/perl/lib/perl'); make_path('stow/perl/lib/perl');
make_dir('stow/perl/man/man1'); make_path('stow/perl/man/man1');
make_file('stow/perl/man/man1/perl.1'); make_file('stow/perl/man/man1/perl.1');
# emacs # emacs
make_dir('stow/emacs/bin'); make_path('stow/emacs/bin');
make_file('stow/emacs/bin/emacs'); make_file('stow/emacs/bin/emacs');
make_file('stow/emacs/bin/etags'); make_file('stow/emacs/bin/etags');
make_dir('stow/emacs/info'); make_path('stow/emacs/info');
make_file('stow/emacs/info/emacs'); make_file('stow/emacs/info/emacs');
make_dir('stow/emacs/libexec/emacs'); make_path('stow/emacs/libexec/emacs');
make_dir('stow/emacs/man/man1'); make_path('stow/emacs/man/man1');
make_file('stow/emacs/man/man1/emacs.1'); make_file('stow/emacs/man/man1/emacs.1');
#setup target directory #setup target directory
make_dir('bin'); make_path('bin');
make_link('bin/a2p', '../stow/perl/bin/a2p'); make_link('bin/a2p', '../stow/perl/bin/a2p');
make_link('bin/emacs', '../stow/emacs/bin/emacs'); make_link('bin/emacs', '../stow/emacs/bin/emacs');
make_link('bin/etags', '../stow/emacs/bin/etags'); make_link('bin/etags', '../stow/emacs/bin/etags');
make_link('bin/perl', '../stow/perl/bin/perl'); make_link('bin/perl', '../stow/perl/bin/perl');
make_dir('info'); make_path('info');
make_link('info/emacs', '../stow/emacs/info/emacs'); make_link('info/emacs', '../stow/emacs/info/emacs');
make_link('info/perl', '../stow/perl/info/perl'); make_link('info/perl', '../stow/perl/info/perl');
make_link('lib', 'stow/perl/lib'); make_link('lib', 'stow/perl/lib');
make_link('libexec', 'stow/emacs/libexec'); make_link('libexec', 'stow/emacs/libexec');
make_dir('man'); make_path('man');
make_dir('man/man1'); make_path('man/man1');
make_link('man/man1/emacs', '../../stow/emacs/man/man1/emacs.1'); make_link('man/man1/emacs', '../../stow/emacs/man/man1/emacs.1');
make_link('man/man1/perl', '../../stow/perl/man/man1/perl.1'); make_link('man/man1/perl', '../../stow/perl/man/man1/perl.1');

View file

@ -28,7 +28,7 @@ use English qw(-no_match_vars);
use testutil; use testutil;
init_test_dirs(); init_test_dirs();
cd("$OUT_DIR/target"); cd("$TEST_DIR/target");
my $stow; my $stow;
@ -39,7 +39,7 @@ my $stow;
# #
make_dir('../stow/pkg1/bin1'); make_path('../stow/pkg1/bin1');
make_file('../stow/pkg1/bin1/file1'); make_file('../stow/pkg1/bin1/file1');
make_link('bin1', '../stow/pkg1/bin1'); make_link('bin1', '../stow/pkg1/bin1');
@ -53,8 +53,8 @@ is(
# #
# cleanup a bad link in a simple tree # cleanup a bad link in a simple tree
# #
make_dir('bin2'); make_path('bin2');
make_dir('../stow/pkg2/bin2'); make_path('../stow/pkg2/bin2');
make_file('../stow/pkg2/bin2/file2a'); make_file('../stow/pkg2/bin2/file2a');
make_link('bin2/file2a', '../../stow/pkg2/bin2/file2a'); make_link('bin2/file2a', '../../stow/pkg2/bin2/file2a');
make_invalid_link('bin2/file2b', '../../stow/pkg2/bin2/file2b'); make_invalid_link('bin2/file2b', '../../stow/pkg2/bin2/file2b');
@ -69,8 +69,8 @@ is($stow->link_task_action('bin2/file2b'), 'remove', 'removal task for bad link'
# dont cleanup a bad link not owned by stow # dont cleanup a bad link not owned by stow
# #
make_dir('bin3'); make_path('bin3');
make_dir('../stow/pkg3/bin3'); make_path('../stow/pkg3/bin3');
make_file('../stow/pkg3/bin3/file3a'); make_file('../stow/pkg3/bin3/file3a');
make_link('bin3/file3a', '../../stow/pkg3/bin3/file3a'); make_link('bin3/file3a', '../../stow/pkg3/bin3/file3a');
make_invalid_link('bin3/file3b', '../../empty'); make_invalid_link('bin3/file3b', '../../empty');

View file

@ -32,15 +32,15 @@ init_test_dirs();
local @ARGV = ( local @ARGV = (
'-v', '-v',
'-d', "$OUT_DIR/stow", '-d', "$TEST_DIR/stow",
'-t', "$OUT_DIR/target", '-t', "$TEST_DIR/target",
'dummy' 'dummy'
); );
my ($options, $pkgs_to_delete, $pkgs_to_stow) = process_options(); my ($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
is($options->{verbose}, 1, 'verbose option'); is($options->{verbose}, 1, 'verbose option');
is($options->{dir}, "$OUT_DIR/stow", 'stow dir option'); is($options->{dir}, "$TEST_DIR/stow", 'stow dir option');
my $stow = new_Stow(%$options); my $stow = new_Stow(%$options);
@ -101,12 +101,12 @@ is_deeply($options->{ignore}, [ qr(~\z), qr(\.#.*\z) ] => 'ignore temp files');
# Check that expansion not applied. # Check that expansion not applied.
# #
local @ARGV = ( local @ARGV = (
"--target=$OUT_DIR/".'$HOME', "--target=$TEST_DIR/".'$HOME',
'dummy' 'dummy'
); );
make_dir("$OUT_DIR/".'$HOME'); make_path("$TEST_DIR/".'$HOME');
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options(); ($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
is($options->{target}, "$OUT_DIR/".'$HOME', 'no expansion'); is($options->{target}, "$TEST_DIR/".'$HOME', 'no expansion');
remove_dir("$OUT_DIR/".'$HOME'); remove_dir("$TEST_DIR/".'$HOME');
# vim:ft=perl # vim:ft=perl

View file

@ -27,7 +27,7 @@ use testutil;
use Test::More tests => 4; use Test::More tests => 4;
init_test_dirs(); init_test_dirs();
cd("$OUT_DIR/target"); cd("$TEST_DIR/target");
my $stow; my $stow;

View file

@ -30,7 +30,7 @@ use English qw(-no_match_vars);
use testutil; use testutil;
init_test_dirs(); init_test_dirs();
cd("$OUT_DIR/target"); cd("$TEST_DIR/target");
my $stow; my $stow;
@ -40,7 +40,7 @@ my $stow;
$stow = new_Stow(dir => '../stow', dotfiles => 1); $stow = new_Stow(dir => '../stow', dotfiles => 1);
make_dir('../stow/dotfiles'); make_path('../stow/dotfiles');
make_file('../stow/dotfiles/dot-foo'); make_file('../stow/dotfiles/dot-foo');
$stow->plan_stow('dotfiles'); $stow->plan_stow('dotfiles');
@ -57,7 +57,7 @@ is(
$stow = new_Stow(dir => '../stow', dotfiles => 0); $stow = new_Stow(dir => '../stow', dotfiles => 0);
make_dir('../stow/dotfiles'); make_path('../stow/dotfiles');
make_file('../stow/dotfiles/dot-foo'); make_file('../stow/dotfiles/dot-foo');
$stow->plan_stow('dotfiles'); $stow->plan_stow('dotfiles');
@ -75,7 +75,7 @@ is(
$stow = new_Stow(dir => '../stow', dotfiles => 1); $stow = new_Stow(dir => '../stow', dotfiles => 1);
make_dir('../stow/dotfiles/dot-emacs'); make_path('../stow/dotfiles/dot-emacs');
make_file('../stow/dotfiles/dot-emacs/init.el'); make_file('../stow/dotfiles/dot-emacs/init.el');
$stow->plan_stow('dotfiles'); $stow->plan_stow('dotfiles');
@ -93,10 +93,10 @@ is(
$stow = new_Stow(dir => '../stow', dotfiles => 1); $stow = new_Stow(dir => '../stow', dotfiles => 1);
make_dir('../stow/dotfiles'); make_path('../stow/dotfiles');
make_file('../stow/dotfiles/dot-'); make_file('../stow/dotfiles/dot-');
make_dir('../stow/dotfiles/dot-.'); make_path('../stow/dotfiles/dot-.');
make_file('../stow/dotfiles/dot-./foo'); make_file('../stow/dotfiles/dot-./foo');
$stow->plan_stow('dotfiles'); $stow->plan_stow('dotfiles');
@ -118,7 +118,7 @@ is(
$stow = new_Stow(dir => '../stow', dotfiles => 1); $stow = new_Stow(dir => '../stow', dotfiles => 1);
make_dir('../stow/dotfiles'); make_path('../stow/dotfiles');
make_file('../stow/dotfiles/dot-bar'); make_file('../stow/dotfiles/dot-bar');
make_link('.bar', '../stow/dotfiles/dot-bar'); make_link('.bar', '../stow/dotfiles/dot-bar');

View file

@ -28,30 +28,30 @@ use Test::More tests => 10;
use English qw(-no_match_vars); use English qw(-no_match_vars);
init_test_dirs(); init_test_dirs();
cd("$OUT_DIR/target"); cd("$TEST_DIR/target");
my $stow; my $stow;
## set up some fake packages to stow ## set up some fake packages to stow
# perl # perl
make_dir('stow/perl/bin'); make_path('stow/perl/bin');
make_file('stow/perl/bin/perl'); make_file('stow/perl/bin/perl');
make_file('stow/perl/bin/a2p'); make_file('stow/perl/bin/a2p');
make_dir('stow/perl/info'); make_path('stow/perl/info');
make_file('stow/perl/info/perl'); make_file('stow/perl/info/perl');
make_dir('stow/perl/lib/perl'); make_path('stow/perl/lib/perl');
make_dir('stow/perl/man/man1'); make_path('stow/perl/man/man1');
make_file('stow/perl/man/man1/perl.1'); make_file('stow/perl/man/man1/perl.1');
# emacs # emacs
make_dir('stow/emacs/bin'); make_path('stow/emacs/bin');
make_file('stow/emacs/bin/emacs'); make_file('stow/emacs/bin/emacs');
make_file('stow/emacs/bin/etags'); make_file('stow/emacs/bin/etags');
make_dir('stow/emacs/info'); make_path('stow/emacs/info');
make_file('stow/emacs/info/emacs'); make_file('stow/emacs/info/emacs');
make_dir('stow/emacs/libexec/emacs'); make_path('stow/emacs/libexec/emacs');
make_dir('stow/emacs/man/man1'); make_path('stow/emacs/man/man1');
make_file('stow/emacs/man/man1/emacs.1'); make_file('stow/emacs/man/man1/emacs.1');
# #
@ -81,9 +81,9 @@ remove_link('info');
remove_link('lib'); remove_link('lib');
remove_link('man'); remove_link('man');
make_dir('bin'); make_path('bin');
make_dir('lib'); make_path('lib');
make_dir('man/man1'); make_path('man/man1');
$stow = new_Stow(dir => 'stow'); $stow = new_Stow(dir => 'stow');
$stow->plan_stow('perl'); $stow->plan_stow('perl');
@ -157,8 +157,8 @@ ok(
# behaviour is the same as if the empty directory had nothing to do with stow # behaviour is the same as if the empty directory had nothing to do with stow
# #
make_dir('stow/pkg1a/bin1'); make_path('stow/pkg1a/bin1');
make_dir('stow/pkg1b/bin1'); make_path('stow/pkg1b/bin1');
make_file('stow/pkg1b/bin1/file1b'); make_file('stow/pkg1b/bin1/file1b');
$stow = new_Stow(dir => 'stow'); $stow = new_Stow(dir => 'stow');
@ -172,10 +172,10 @@ ok(-d 'bin1' => 'bug 1: stowing empty dirs');
# BUG 2: split open tree-folding symlinks pointing inside different stow # BUG 2: split open tree-folding symlinks pointing inside different stow
# directories # directories
# #
make_dir('stow2a/pkg2a/bin2'); make_path('stow2a/pkg2a/bin2');
make_file('stow2a/pkg2a/bin2/file2a'); make_file('stow2a/pkg2a/bin2/file2a');
make_file('stow2a/.stow'); make_file('stow2a/.stow');
make_dir('stow2b/pkg2b/bin2'); make_path('stow2b/pkg2b/bin2');
make_file('stow2b/pkg2b/bin2/file2b'); make_file('stow2b/pkg2b/bin2/file2b');
make_file('stow2b/.stow'); make_file('stow2b/.stow');

View file

@ -22,57 +22,59 @@
use strict; use strict;
use warnings; use warnings;
use testutil; use Test::More tests => 18;
use Test::More tests => 6; use testutil;
use Stow::Util qw(set_debug_level);
init_test_dirs(); init_test_dirs();
my $stow = new_Stow(dir => "$OUT_DIR/stow"); my $stow = new_Stow(dir => "$TEST_DIR/stow");
#set_debug_level(4);
is_deeply( my ($path, $stow_path, $package) =
[ $stow->find_stowed_path("$OUT_DIR/target/a/b/c", '../../../stow/a/b/c') ], $stow->find_stowed_path("$TEST_DIR/target/a/b/c", "../../../stow/a/b/c");
[ "$OUT_DIR/stow/a/b/c", "$OUT_DIR/stow", 'a' ] is($path, "$TEST_DIR/stow/a/b/c", "path");
=> 'from root' is($stow_path, "$TEST_DIR/stow", "stow path");
); is($package, "a", "package");
cd("$OUT_DIR/target"); cd("$TEST_DIR/target");
$stow->set_stow_dir('../stow'); $stow->set_stow_dir("../stow");
is_deeply( ($path, $stow_path, $package) =
[ $stow->find_stowed_path('a/b/c','../../../stow/a/b/c') ], $stow->find_stowed_path("a/b/c", "../../../stow/a/b/c");
[ '../stow/a/b/c', '../stow', 'a' ] is($path, "../stow/a/b/c", "path from target directory");
=> 'from target directory' is($stow_path, "../stow", "stow path from target directory");
); is($package, "a", "from target directory");
make_dir('stow'); make_path("stow");
cd('../..'); cd("../..");
$stow->set_stow_dir("$OUT_DIR/target/stow"); $stow->set_stow_dir("$TEST_DIR/target/stow");
is_deeply( ($path, $stow_path, $package) =
[ $stow->find_stowed_path("$OUT_DIR/target/a/b/c", '../../stow/a/b/c') ], $stow->find_stowed_path("$TEST_DIR/target/a/b/c", "../../stow/a/b/c");
[ "$OUT_DIR/target/stow/a/b/c", "$OUT_DIR/target/stow", 'a' ] is($path, "$TEST_DIR/target/stow/a/b/c", "path");
=> 'stow is subdir of target directory' is($stow_path, "$TEST_DIR/target/stow", "stow path");
); is($package, "a", "stow is subdir of target directory");
is_deeply( ($path, $stow_path, $package) =
[ $stow->find_stowed_path("$OUT_DIR/target/a/b/c",'../../empty') ], $stow->find_stowed_path("$TEST_DIR/target/a/b/c", "../../empty");
[ '', '', '' ] is($path, "", "empty path");
=> 'target is not stowed' is($stow_path, "", "empty stow path");
); is($package, "", "target is not stowed");
make_dir("$OUT_DIR/target/stow2"); make_path("$TEST_DIR/target/stow2");
make_file("$OUT_DIR/target/stow2/.stow"); make_file("$TEST_DIR/target/stow2/.stow");
is_deeply( ($path, $stow_path, $package) =
[ $stow->find_stowed_path("$OUT_DIR/target/a/b/c",'../../stow2/a/b/c') ], $stow->find_stowed_path("$TEST_DIR/target/a/b/c","../../stow2/a/b/c");
[ "$OUT_DIR/target/stow2/a/b/c", "$OUT_DIR/target/stow2", 'a' ] is($path, "$TEST_DIR/target/stow2/a/b/c", "path");
=> q(detect alternate stow directory) is($stow_path, "$TEST_DIR/target/stow2", "stow path");
); is($package, "a", "detect alternate stow directory");
# Possible corner case with rogue symlink pointing to ancestor of # Possible corner case with rogue symlink pointing to ancestor of
# stow dir. # stow dir.
is_deeply( ($path, $stow_path, $package) =
[ $stow->find_stowed_path("$OUT_DIR/target/a/b/c",'../../..') ], $stow->find_stowed_path("$TEST_DIR/target/a/b/c","../../..");
[ '', '', '' ] is($path, "", "path");
=> q(corner case - link points to ancestor of stow dir) is($stow_path, "", "stow path");
); is($package, "", "corner case - link points to ancestor of stow dir");

View file

@ -28,7 +28,7 @@ use Test::More tests => 4;
use English qw(-no_match_vars); use English qw(-no_match_vars);
init_test_dirs(); init_test_dirs();
cd("$OUT_DIR/target"); cd("$TEST_DIR/target");
my $stow = new_Stow(dir => '../stow'); my $stow = new_Stow(dir => '../stow');
@ -38,9 +38,9 @@ my $stow = new_Stow(dir => '../stow');
# can fold a simple tree # can fold a simple tree
# #
make_dir('../stow/pkg1/bin1'); make_path('../stow/pkg1/bin1');
make_file('../stow/pkg1/bin1/file1'); make_file('../stow/pkg1/bin1/file1');
make_dir('bin1'); make_path('bin1');
make_link('bin1/file1','../../stow/pkg1/bin1/file1'); make_link('bin1/file1','../../stow/pkg1/bin1/file1');
is( $stow->foldable('bin1'), '../stow/pkg1/bin1' => q(can fold a simple tree) ); is( $stow->foldable('bin1'), '../stow/pkg1/bin1' => q(can fold a simple tree) );
@ -49,9 +49,9 @@ is( $stow->foldable('bin1'), '../stow/pkg1/bin1' => q(can fold a simple tree) );
# can't fold an empty directory # can't fold an empty directory
# #
make_dir('../stow/pkg2/bin2'); make_path('../stow/pkg2/bin2');
make_file('../stow/pkg2/bin2/file2'); make_file('../stow/pkg2/bin2/file2');
make_dir('bin2'); make_path('bin2');
is( $stow->foldable('bin2'), '' => q(can't fold an empty directory) ); is( $stow->foldable('bin2'), '' => q(can't fold an empty directory) );
@ -59,9 +59,9 @@ is( $stow->foldable('bin2'), '' => q(can't fold an empty directory) );
# can't fold if dir contains a non-link # can't fold if dir contains a non-link
# #
make_dir('../stow/pkg3/bin3'); make_path('../stow/pkg3/bin3');
make_file('../stow/pkg3/bin3/file3'); make_file('../stow/pkg3/bin3/file3');
make_dir('bin3'); make_path('bin3');
make_link('bin3/file3','../../stow/pkg3/bin3/file3'); make_link('bin3/file3','../../stow/pkg3/bin3/file3');
make_file('bin3/non-link'); make_file('bin3/non-link');
@ -71,11 +71,11 @@ is( $stow->foldable('bin3'), '' => q(can't fold a dir containing non-links) );
# can't fold if links point to different directories # can't fold if links point to different directories
# #
make_dir('bin4'); make_path('bin4');
make_dir('../stow/pkg4a/bin4'); make_path('../stow/pkg4a/bin4');
make_file('../stow/pkg4a/bin4/file4a'); make_file('../stow/pkg4a/bin4/file4a');
make_link('bin4/file4a','../../stow/pkg4a/bin4/file4a'); make_link('bin4/file4a','../../stow/pkg4a/bin4/file4a');
make_dir('../stow/pkg4b/bin4'); make_path('../stow/pkg4b/bin4');
make_file('../stow/pkg4b/bin4/file4b'); make_file('../stow/pkg4b/bin4/file4b');
make_link('bin4/file4b','../../stow/pkg4b/bin4/file4b'); make_link('bin4/file4b','../../stow/pkg4b/bin4/file4b');

View file

@ -29,7 +29,7 @@ use testutil;
use Stow::Util qw(join_paths); use Stow::Util qw(join_paths);
init_test_dirs(); init_test_dirs();
cd("$OUT_DIR/target"); cd("$TEST_DIR/target");
my $stow = new_Stow(); my $stow = new_Stow();
@ -123,7 +123,7 @@ EOF
sub setup_package_local_list { sub setup_package_local_list {
my ($stow_path, $package, $list) = @_; my ($stow_path, $package, $list) = @_;
my $package_path = join_paths($stow_path, $package); my $package_path = join_paths($stow_path, $package);
make_dir($package_path); make_path($package_path);
my $local_ignore = join_paths($package_path, $Stow::LOCAL_IGNORE_FILE); my $local_ignore = join_paths($package_path, $Stow::LOCAL_IGNORE_FILE);
make_file($local_ignore, $list); make_file($local_ignore, $list);
$stow->invalidate_memoized_regexp($local_ignore); $stow->invalidate_memoized_regexp($local_ignore);
@ -278,7 +278,7 @@ sub test_ignore_via_stow {
my ($stow_path) = @_; my ($stow_path) = @_;
my $package = 'pkg1'; my $package = 'pkg1';
make_dir("$stow_path/$package/foo/bar"); make_path("$stow_path/$package/foo/bar");
make_file("$stow_path/$package/foo/bar/baz"); make_file("$stow_path/$package/foo/bar/baz");
setup_package_local_list($stow_path, $package, 'foo'); setup_package_local_list($stow_path, $package, 'foo');
@ -286,7 +286,7 @@ sub test_ignore_via_stow {
is($stow->get_tasks(), 0, 'top dir ignored'); is($stow->get_tasks(), 0, 'top dir ignored');
is($stow->get_conflicts(), 0, 'top dir ignored, no conflicts'); is($stow->get_conflicts(), 0, 'top dir ignored, no conflicts');
make_dir("foo"); make_path("foo");
for my $ignore ('bar', 'foo/bar', '/foo/bar', '^/foo/bar', '^/fo.+ar') { for my $ignore ('bar', 'foo/bar', '/foo/bar', '^/foo/bar', '^/fo.+ar') {
setup_package_local_list($stow_path, $package, $ignore); setup_package_local_list($stow_path, $package, $ignore);
$stow->plan_stow($package); $stow->plan_stow($package);

View file

@ -22,67 +22,144 @@
use strict; use strict;
use warnings; use warnings;
use Test::More tests => 23; use Test::More tests => 33;
use testutil; use testutil;
require 'stow'; require 'stow';
# stowrc file used for testing. # .stowrc files used for testing, relative to run_from/
my $RC_FILE = "$OUT_DIR/.stowrc"; my $CWD_RC_FILE = ".stowrc";
my $HOME_RC_FILE = "../.stowrc";
# Take the safe route and cowardly refuse to continue if there's # Take the safe route and cowardly refuse to continue if there's
# already a file at $RC_FILE. # already a file at $HOME_RC_FILE.
if (-e $RC_FILE) { if (-e $HOME_RC_FILE) {
die "RC file location $RC_FILE already exists!\n"; die "RC file location $HOME_RC_FILE already exists!\n";
} }
# Define the variable that will be used to write stowrc. my ($options, $pkgs_to_delete, $pkgs_to_stow);
my $rc_contents;
# Init testing directory structure and overwrite ENV{HOME} to prevent # Init testing directory structure and overwrite ENV{HOME} to prevent
# squashing existing stowrc file. # squashing existing .stowrc file.
init_test_dirs(); init_test_dirs();
# =========== RC Loading Tests =========== # =========== RC Loading Tests ===========
# Basic parsing and loading rc file tests. # Basic parsing and loading rc file tests.
# ======================================== # ========================================
my $orig_HOME = $ENV{HOME};
# #
# Test stowrc file with one options per line. # Test no .stowrc file anywhere
#
delete $ENV{HOME};
local @ARGV = ('dummy');
cd("$TEST_DIR/run_from");
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
is($options->{target}, "$ABS_TEST_DIR", "default --target with no .stowrc");
is($options->{dir}, "$ABS_TEST_DIR/run_from", "default -d with no .stowrc");
#
# Test .stowrc file in cwd with relative paths, and $HOME not defined
#
make_file($CWD_RC_FILE, <<HERE);
-d ../stow
--target ../target
HERE
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
is($options->{target}, "../target"
=> "relative --target from \$PWD/.stowrc");
is($options->{dir}, "../stow"
=> "relative -d from \$PWD/.stowrc");
$ENV{HOME} = $orig_HOME;
remove_file($CWD_RC_FILE);
#
# Test .stowrc file in cwd with absolute paths, and $HOME not defined
#
make_file($CWD_RC_FILE, <<HERE);
-d $ABS_TEST_DIR/stow
--target $ABS_TEST_DIR/target
HERE
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
is($options->{target}, "$ABS_TEST_DIR/target"
=> "absolute --target from \$PWD/.stowrc");
is($options->{dir}, "$ABS_TEST_DIR/stow"
=> "abs_test_dir -d from \$PWD/.stowrc");
$ENV{HOME} = $orig_HOME;
remove_file($CWD_RC_FILE);
#
# Test ~/.stowrc file with one relative option per line.
# #
local @ARGV = ('dummy'); local @ARGV = ('dummy');
$rc_contents = <<HERE; make_file($HOME_RC_FILE, <<HERE);
-d $OUT_DIR/stow -d ../stow
--target $OUT_DIR/target --target ../target
HERE HERE
make_file($RC_FILE, $rc_contents);
my ($options, $pkgs_to_delete, $pkgs_to_stow) = process_options(); ($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
is($options->{target}, "$OUT_DIR/target", "rc options different lines"); is($options->{target}, "../target", "--target from \$HOME/.stowrc");
is($options->{dir}, "$OUT_DIR/stow", "rc options different lines"); is($options->{dir}, "../stow", "-d from \$HOME/.stowrc");
# #
# Test that scalar cli option overwrites conflicting stowrc option. # Test ~/.stowrc file with one absolute option per line.
# #
local @ARGV = ('-d', "$OUT_DIR/stow",'dummy'); local @ARGV = ('dummy');
$rc_contents = <<HERE; make_file($HOME_RC_FILE, <<HERE);
-d $ABS_TEST_DIR/stow
--target $ABS_TEST_DIR/target
HERE
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
is($options->{target}, "$ABS_TEST_DIR/target"
=> "--target from \$HOME/.stowrc");
is($options->{dir}, "$ABS_TEST_DIR/stow"
=> "-d from \$HOME/.stowrc");
#
# Test ~/.stowrc file is overridden by .stowrc in cwd.
#
local @ARGV = ('dummy');
make_file($HOME_RC_FILE, <<HERE);
-d $ABS_TEST_DIR/stow-will-be-overridden
--target $ABS_TEST_DIR/target-will-be-overridden
HERE
make_file($CWD_RC_FILE, <<HERE);
-d $ABS_TEST_DIR/stow
--target $ABS_TEST_DIR/target
HERE
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
is($options->{target}, "$ABS_TEST_DIR/target"
=> "--target overridden by \$PWD/.stowrc");
is($options->{dir}, "$ABS_TEST_DIR/stow"
=> "-d overridden \$PWD/.stowrc");
unlink($CWD_RC_FILE) or die "Failed to unlink $CWD_RC_FILE";
#
# Test that scalar cli option overwrites conflicting ~/.stowrc option.
#
local @ARGV = ('-d', "$ABS_TEST_DIR/stow", 'dummy');
make_file($HOME_RC_FILE, <<HERE);
-d bad/path -d bad/path
HERE HERE
make_file($RC_FILE, $rc_contents);
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options(); ($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
is($options->{dir}, "$OUT_DIR/stow", "cli overwrite scalar rc option."); is($options->{dir}, "$ABS_TEST_DIR/stow", "cli overwrite scalar rc option.");
# #
# Test that list cli option merges with conflicting stowrc option. # Test that list cli option merges with conflicting .stowrc option.
# Documentation states that stowrc options are prepended to cli options. # Documentation states that .stowrc options are prepended to cli options.
# #
local @ARGV = ( local @ARGV = (
'--defer=man', '--defer=man',
'dummy' 'dummy'
); );
$rc_contents = <<HERE; make_file($HOME_RC_FILE, <<HERE);
--defer=info --defer=info
HERE HERE
make_file($RC_FILE, $rc_contents);
($options, $pkgs_to_delete, $pkgs_to_stow) = process_options(); ($options, $pkgs_to_delete, $pkgs_to_stow) = process_options();
is_deeply($options->{defer}, [qr(\Ainfo), qr(\Aman)], is_deeply($options->{defer}, [qr(\Ainfo), qr(\Aman)],
'defer man and info'); 'defer man and info');
@ -98,8 +175,8 @@ is_deeply($options->{defer}, [qr(\Ainfo), qr(\Aman)],
# Test environment variable expansion function. # Test environment variable expansion function.
# #
# Basic expansion # Basic expansion
is(expand_environment('$HOME/stow'), "$OUT_DIR/stow", 'expand $HOME'); is(expand_environment('$HOME/stow'), "$ABS_TEST_DIR/stow", 'expand $HOME');
is(expand_environment('${HOME}/stow'), "$OUT_DIR/stow", 'expand ${HOME}'); is(expand_environment('${HOME}/stow'), "$ABS_TEST_DIR/stow", 'expand ${HOME}');
delete $ENV{UNDEFINED}; # just in case delete $ENV{UNDEFINED}; # just in case
foreach my $var ('$UNDEFINED', '${UNDEFINED}') { foreach my $var ('$UNDEFINED', '${UNDEFINED}') {
@ -135,19 +212,18 @@ is(expand_tilde('\~/path'), '~/path', 'escaped tilde');
# #
# Test that environment variable expansion is applied. # Test that environment variable expansion is applied.
# #
$rc_contents = <<'HERE'; make_file($HOME_RC_FILE, <<'HERE');
--dir=$HOME/stow --dir=$HOME/stow
--target=$HOME/stow --target=$HOME/stow
--ignore=\$HOME --ignore=\$HOME
--defer=\$HOME --defer=\$HOME
--override=\$HOME --override=\$HOME
HERE HERE
make_file($RC_FILE, $rc_contents);
($options, $pkgs_to_delete, $pkgs_to_stow) = get_config_file_options(); ($options, $pkgs_to_delete, $pkgs_to_stow) = get_config_file_options();
is($options->{dir}, "$OUT_DIR/stow", is($options->{dir}, "$ABS_TEST_DIR/stow",
"apply environment expansion on stowrc --dir"); "apply environment expansion on \$HOME/.stowrc --dir");
is($options->{target}, "$OUT_DIR/stow", is($options->{target}, "$ABS_TEST_DIR/stow",
"apply environment expansion on stowrc --target"); "apply environment expansion on \$HOME/.stowrc --target");
is_deeply($options->{ignore}, [qr(\$HOME\z)], is_deeply($options->{ignore}, [qr(\$HOME\z)],
"environment expansion not applied on --ignore"); "environment expansion not applied on --ignore");
is_deeply($options->{defer}, [qr(\A\$HOME)], is_deeply($options->{defer}, [qr(\A\$HOME)],
@ -158,28 +234,28 @@ is_deeply($options->{override}, [qr(\A\$HOME)],
# #
# Test that tilde expansion is applied in correct places. # Test that tilde expansion is applied in correct places.
# #
$rc_contents = <<'HERE'; make_file($HOME_RC_FILE, <<'HERE');
--dir=~/stow --dir=~/stow
--target=~/stow --target=~/stow
--ignore=~/stow --ignore=~/stow
--defer=~/stow --defer=~/stow
--override=~/stow --override=~/stow
HERE HERE
make_file($RC_FILE, $rc_contents);
($options, $pkgs_to_delete, $pkgs_to_stow) = get_config_file_options(); ($options, $pkgs_to_delete, $pkgs_to_stow) = get_config_file_options();
is($options->{dir}, "$OUT_DIR/stow", is($options->{dir}, "$ABS_TEST_DIR/stow",
"apply environment expansion on stowrc --dir"); "apply tilde expansion on \$HOME/.stowrc --dir");
is($options->{target}, "$OUT_DIR/stow", is($options->{target}, "$ABS_TEST_DIR/stow",
"apply environment expansion on stowrc --target"); "apply tilde expansion on \$HOME/.stowrc --target");
is_deeply($options->{ignore}, [qr(~/stow\z)], is_deeply($options->{ignore}, [qr(~/stow\z)],
"environment expansion not applied on --ignore"); "tilde expansion not applied on --ignore");
is_deeply($options->{defer}, [qr(\A~/stow)], is_deeply($options->{defer}, [qr(\A~/stow)],
"environment expansion not applied on --defer"); "tilde expansion not applied on --defer");
is_deeply($options->{override}, [qr(\A~/stow)], is_deeply($options->{override}, [qr(\A~/stow)],
"environment expansion not applied on --override"); "tilde expansion not applied on --override");
#
# Clean up files used for testing. # Clean up files used for testing.
# #
unlink $RC_FILE or die "Unable to clean up $RC_FILE.\n"; unlink $HOME_RC_FILE or die "Unable to clean up $HOME_RC_FILE.\n";
remove_dir($OUT_DIR); remove_dir($ABS_TEST_DIR);

113
t/stow.t
View file

@ -26,11 +26,11 @@ use Test::More tests => 118;
use Test::Output; use Test::Output;
use English qw(-no_match_vars); use English qw(-no_match_vars);
use Stow::Util qw(canon_path); use Stow::Util qw(canon_path set_debug_level);
use testutil; use testutil;
init_test_dirs(); init_test_dirs();
cd("$OUT_DIR/target"); cd("$TEST_DIR/target");
my $stow; my $stow;
my %conflicts; my %conflicts;
@ -42,7 +42,7 @@ my %conflicts;
# #
$stow = new_Stow(dir => '../stow'); $stow = new_Stow(dir => '../stow');
make_dir('../stow/pkg1/bin1'); make_path('../stow/pkg1/bin1');
make_file('../stow/pkg1/bin1/file1'); make_file('../stow/pkg1/bin1/file1');
$stow->plan_stow('pkg1'); $stow->plan_stow('pkg1');
@ -59,9 +59,9 @@ is(
# #
$stow = new_Stow(); $stow = new_Stow();
make_dir('../stow/pkg2/lib2'); make_path('../stow/pkg2/lib2');
make_file('../stow/pkg2/lib2/file2'); make_file('../stow/pkg2/lib2/file2');
make_dir('lib2'); make_path('lib2');
$stow->plan_stow('pkg2'); $stow->plan_stow('pkg2');
$stow->process_tasks(); $stow->process_tasks();
@ -76,11 +76,11 @@ is(
# #
$stow = new_Stow(); $stow = new_Stow();
make_dir('../stow/pkg3a/bin3'); make_path('../stow/pkg3a/bin3');
make_file('../stow/pkg3a/bin3/file3a'); make_file('../stow/pkg3a/bin3/file3a');
make_link('bin3' => '../stow/pkg3a/bin3'); # emulate stow make_link('bin3' => '../stow/pkg3a/bin3'); # emulate stow
make_dir('../stow/pkg3b/bin3'); make_path('../stow/pkg3b/bin3');
make_file('../stow/pkg3b/bin3/file3b'); make_file('../stow/pkg3b/bin3/file3b');
$stow->plan_stow('pkg3b'); $stow->plan_stow('pkg3b');
@ -99,7 +99,7 @@ ok(
$stow = new_Stow(); $stow = new_Stow();
make_file('bin4'); # this is a file but named like a directory make_file('bin4'); # this is a file but named like a directory
make_dir('../stow/pkg4/bin4'); make_path('../stow/pkg4/bin4');
make_file('../stow/pkg4/bin4/file4'); make_file('../stow/pkg4/bin4/file4');
$stow->plan_stow('pkg4'); $stow->plan_stow('pkg4');
@ -119,7 +119,7 @@ ok(
$stow = new_Stow(); $stow = new_Stow();
make_file('bin4a'); # this is a file but named like a directory make_file('bin4a'); # this is a file but named like a directory
make_dir('../stow/pkg4a/bin4a'); make_path('../stow/pkg4a/bin4a');
make_file('../stow/pkg4a/bin4a/file4a'); make_file('../stow/pkg4a/bin4a/file4a');
$stow->plan_stow('pkg4a'); $stow->plan_stow('pkg4a');
@ -139,11 +139,11 @@ $stow = new_Stow();
# Populate target # Populate target
make_file('file4b', 'file4b - version originally in target'); make_file('file4b', 'file4b - version originally in target');
make_dir ('bin4b'); make_path ('bin4b');
make_file('bin4b/file4b', 'bin4b/file4b - version originally in target'); make_file('bin4b/file4b', 'bin4b/file4b - version originally in target');
# Populate # Populate
make_dir ('../stow/pkg4b/bin4b'); make_path ('../stow/pkg4b/bin4b');
make_file('../stow/pkg4b/file4b', 'file4b - version originally in stow package'); make_file('../stow/pkg4b/file4b', 'file4b - version originally in stow package');
make_file('../stow/pkg4b/bin4b/file4b', 'bin4b/file4b - version originally in stow package'); make_file('../stow/pkg4b/bin4b/file4b', 'bin4b/file4b - version originally in stow package');
@ -166,11 +166,11 @@ $stow = new_Stow(adopt => 1);
# Populate target # Populate target
make_file('file4c', "file4c - version originally in target\n"); make_file('file4c', "file4c - version originally in target\n");
make_dir ('bin4c'); make_path ('bin4c');
make_file('bin4c/file4c', "bin4c/file4c - version originally in target\n"); make_file('bin4c/file4c', "bin4c/file4c - version originally in target\n");
# Populate # Populate
make_dir ('../stow/pkg4c/bin4c'); make_path ('../stow/pkg4c/bin4c');
make_file('../stow/pkg4c/file4c', "file4c - version originally in stow package\n"); make_file('../stow/pkg4c/file4c', "file4c - version originally in stow package\n");
make_file('../stow/pkg4c/bin4c/file4c', "bin4c/file4c - version originally in stow package\n"); make_file('../stow/pkg4c/bin4c/file4c', "bin4c/file4c - version originally in stow package\n");
@ -194,9 +194,9 @@ for my $file ('file4c', 'bin4c/file4c') {
# #
$stow = new_Stow(); $stow = new_Stow();
make_dir('bin5'); make_path('bin5');
make_invalid_link('bin5/file5','../../empty'); make_invalid_link('bin5/file5','../../empty');
make_dir('../stow/pkg5/bin5/file5'); make_path('../stow/pkg5/bin5/file5');
$stow->plan_stow('pkg5'); $stow->plan_stow('pkg5');
%conflicts = $stow->get_conflicts(); %conflicts = $stow->get_conflicts();
@ -212,7 +212,7 @@ like(
$stow = new_Stow(); $stow = new_Stow();
make_invalid_link('file6','../stow/path-does-not-exist'); make_invalid_link('file6','../stow/path-does-not-exist');
make_dir('../stow/pkg6'); make_path('../stow/pkg6');
make_file('../stow/pkg6/file6'); make_file('../stow/pkg6/file6');
$stow->plan_stow('pkg6'); $stow->plan_stow('pkg6');
@ -228,12 +228,13 @@ is(
# (can't unfold) # (can't unfold)
# #
$stow = new_Stow(); $stow = new_Stow();
#set_debug_level(4);
make_dir('bin7'); make_path('bin7');
make_dir('../stow/pkg7a/bin7'); make_path('../stow/pkg7a/bin7');
make_file('../stow/pkg7a/bin7/node7'); make_file('../stow/pkg7a/bin7/node7');
make_link('bin7/node7','../../stow/pkg7a/bin7/node7'); make_link('bin7/node7','../../stow/pkg7a/bin7/node7');
make_dir('../stow/pkg7b/bin7/node7'); make_path('../stow/pkg7b/bin7/node7');
make_file('../stow/pkg7b/bin7/node7/file7'); make_file('../stow/pkg7b/bin7/node7/file7');
$stow->plan_stow('pkg7b'); $stow->plan_stow('pkg7b');
@ -249,11 +250,11 @@ like(
# #
$stow = new_Stow(); $stow = new_Stow();
make_dir('../stow/pkg8a/0'); make_path('../stow/pkg8a/0');
make_file('../stow/pkg8a/0/file8a'); make_file('../stow/pkg8a/0/file8a');
make_link('0' => '../stow/pkg8a/0'); # emulate stow make_link('0' => '../stow/pkg8a/0'); # emulate stow
make_dir('../stow/pkg8b/0'); make_path('../stow/pkg8b/0');
make_file('../stow/pkg8b/0/file8b'); make_file('../stow/pkg8b/0/file8b');
$stow->plan_stow('pkg8b'); $stow->plan_stow('pkg8b');
@ -271,12 +272,12 @@ ok(
# #
$stow = new_Stow(override => ['man9', 'info9']); $stow = new_Stow(override => ['man9', 'info9']);
make_dir('../stow/pkg9a/man9/man1'); make_path('../stow/pkg9a/man9/man1');
make_file('../stow/pkg9a/man9/man1/file9.1'); make_file('../stow/pkg9a/man9/man1/file9.1');
make_dir('man9/man1'); make_path('man9/man1');
make_link('man9/man1/file9.1' => '../../../stow/pkg9a/man9/man1/file9.1'); # emulate stow make_link('man9/man1/file9.1' => '../../../stow/pkg9a/man9/man1/file9.1'); # emulate stow
make_dir('../stow/pkg9b/man9/man1'); make_path('../stow/pkg9b/man9/man1');
make_file('../stow/pkg9b/man9/man1/file9.1'); make_file('../stow/pkg9b/man9/man1/file9.1');
$stow->plan_stow('pkg9b'); $stow->plan_stow('pkg9b');
@ -292,12 +293,12 @@ ok(
# #
$stow = new_Stow(defer => ['man10', 'info10']); $stow = new_Stow(defer => ['man10', 'info10']);
make_dir('../stow/pkg10a/man10/man1'); make_path('../stow/pkg10a/man10/man1');
make_file('../stow/pkg10a/man10/man1/file10.1'); make_file('../stow/pkg10a/man10/man1/file10.1');
make_dir('man10/man1'); make_path('man10/man1');
make_link('man10/man1/file10.1' => '../../../stow/pkg10a/man10/man1/file10.1'); # emulate stow make_link('man10/man1/file10.1' => '../../../stow/pkg10a/man10/man1/file10.1'); # emulate stow
make_dir('../stow/pkg10b/man10/man1'); make_path('../stow/pkg10b/man10/man1');
make_file('../stow/pkg10b/man10/man1/file10.1'); make_file('../stow/pkg10b/man10/man1/file10.1');
$stow->plan_stow('pkg10b'); $stow->plan_stow('pkg10b');
@ -313,11 +314,11 @@ ok(
# #
$stow = new_Stow(ignore => ['~', '\.#.*']); $stow = new_Stow(ignore => ['~', '\.#.*']);
make_dir('../stow/pkg11/man11/man1'); make_path('../stow/pkg11/man11/man1');
make_file('../stow/pkg11/man11/man1/file11.1'); make_file('../stow/pkg11/man11/man1/file11.1');
make_file('../stow/pkg11/man11/man1/file11.1~'); make_file('../stow/pkg11/man11/man1/file11.1~');
make_file('../stow/pkg11/man11/man1/.#file11.1'); make_file('../stow/pkg11/man11/man1/.#file11.1');
make_dir('man11/man1'); make_path('man11/man1');
$stow->plan_stow('pkg11'); $stow->plan_stow('pkg11');
$stow->process_tasks(); $stow->process_tasks();
@ -334,11 +335,11 @@ ok(
# #
$stow = new_Stow(); $stow = new_Stow();
make_dir('../stow/pkg12/lib12/'); make_path('../stow/pkg12/lib12/');
make_file('../stow/pkg12/lib12/lib.so.1'); make_file('../stow/pkg12/lib12/lib.so.1');
make_link('../stow/pkg12/lib12/lib.so', 'lib.so.1'); make_link('../stow/pkg12/lib12/lib.so', 'lib.so.1');
make_dir('lib12/'); make_path('lib12/');
$stow->plan_stow('pkg12'); $stow->plan_stow('pkg12');
$stow->process_tasks(); $stow->process_tasks();
@ -354,12 +355,12 @@ ok(
# #
$stow = new_Stow(); $stow = new_Stow();
make_dir('../stow/pkg13a/lib13/'); make_path('../stow/pkg13a/lib13/');
make_file('../stow/pkg13a/lib13/liba.so.1'); make_file('../stow/pkg13a/lib13/liba.so.1');
make_link('../stow/pkg13a/lib13/liba.so', 'liba.so.1'); make_link('../stow/pkg13a/lib13/liba.so', 'liba.so.1');
make_link('lib13','../stow/pkg13a/lib13'); make_link('lib13','../stow/pkg13a/lib13');
make_dir('../stow/pkg13b/lib13/'); make_path('../stow/pkg13b/lib13/');
make_file('../stow/pkg13b/lib13/libb.so.1'); make_file('../stow/pkg13b/lib13/libb.so.1');
make_link('../stow/pkg13b/lib13/libb.so', 'libb.so.1'); make_link('../stow/pkg13b/lib13/libb.so', 'libb.so.1');
@ -377,10 +378,10 @@ ok(
# #
# stowing to stow dir should fail # stowing to stow dir should fail
# #
make_dir('stow'); make_path('stow');
$stow = new_Stow(dir => 'stow'); $stow = new_Stow(dir => 'stow');
make_dir('stow/pkg14/stow/pkg15'); make_path('stow/pkg14/stow/pkg15');
make_file('stow/pkg14/stow/pkg15/node15'); make_file('stow/pkg14/stow/pkg15/node15');
capture_stderr(); capture_stderr();
@ -400,16 +401,16 @@ uncapture_stderr();
# stow a simple tree minimally when cwd isn't target # stow a simple tree minimally when cwd isn't target
# #
cd('../..'); cd('../..');
$stow = new_Stow(dir => "$OUT_DIR/stow", target => "$OUT_DIR/target"); $stow = new_Stow(dir => "$TEST_DIR/stow", target => "$TEST_DIR/target");
make_dir("$OUT_DIR/stow/pkg16/bin16"); make_path("$TEST_DIR/stow/pkg16/bin16");
make_file("$OUT_DIR/stow/pkg16/bin16/file16"); make_file("$TEST_DIR/stow/pkg16/bin16/file16");
$stow->plan_stow('pkg16'); $stow->plan_stow('pkg16');
$stow->process_tasks(); $stow->process_tasks();
is_deeply([ $stow->get_conflicts ], [], 'no conflicts with minimal stow'); is_deeply([ $stow->get_conflicts ], [], 'no conflicts with minimal stow');
is( is(
readlink("$OUT_DIR/target/bin16"), readlink("$TEST_DIR/target/bin16"),
'../stow/pkg16/bin16', '../stow/pkg16/bin16',
=> "minimal stow of a simple tree when cwd isn't target" => "minimal stow of a simple tree when cwd isn't target"
); );
@ -418,17 +419,17 @@ is(
# stow a simple tree minimally to absolute stow dir when cwd isn't # stow a simple tree minimally to absolute stow dir when cwd isn't
# target # target
# #
$stow = new_Stow(dir => canon_path("$OUT_DIR/stow"), $stow = new_Stow(dir => canon_path("$TEST_DIR/stow"),
target => "$OUT_DIR/target"); target => "$TEST_DIR/target");
make_dir("$OUT_DIR/stow/pkg17/bin17"); make_path("$TEST_DIR/stow/pkg17/bin17");
make_file("$OUT_DIR/stow/pkg17/bin17/file17"); make_file("$TEST_DIR/stow/pkg17/bin17/file17");
$stow->plan_stow('pkg17'); $stow->plan_stow('pkg17');
$stow->process_tasks(); $stow->process_tasks();
is_deeply([ $stow->get_conflicts ], [], 'no conflicts with minimal stow'); is_deeply([ $stow->get_conflicts ], [], 'no conflicts with minimal stow');
is( is(
readlink("$OUT_DIR/target/bin17"), readlink("$TEST_DIR/target/bin17"),
'../stow/pkg17/bin17', '../stow/pkg17/bin17',
=> "minimal stow of a simple tree with absolute stow dir" => "minimal stow of a simple tree with absolute stow dir"
); );
@ -437,17 +438,17 @@ is(
# stow a simple tree minimally with absolute stow AND target dirs when # stow a simple tree minimally with absolute stow AND target dirs when
# cwd isn't target # cwd isn't target
# #
$stow = new_Stow(dir => canon_path("$OUT_DIR/stow"), $stow = new_Stow(dir => canon_path("$TEST_DIR/stow"),
target => canon_path("$OUT_DIR/target")); target => canon_path("$TEST_DIR/target"));
make_dir("$OUT_DIR/stow/pkg18/bin18"); make_path("$TEST_DIR/stow/pkg18/bin18");
make_file("$OUT_DIR/stow/pkg18/bin18/file18"); make_file("$TEST_DIR/stow/pkg18/bin18/file18");
$stow->plan_stow('pkg18'); $stow->plan_stow('pkg18');
$stow->process_tasks(); $stow->process_tasks();
is_deeply([ $stow->get_conflicts ], [], 'no conflicts with minimal stow'); is_deeply([ $stow->get_conflicts ], [], 'no conflicts with minimal stow');
is( is(
readlink("$OUT_DIR/target/bin18"), readlink("$TEST_DIR/target/bin18"),
'../stow/pkg18/bin18', '../stow/pkg18/bin18',
=> "minimal stow of a simple tree with absolute stow and target dirs" => "minimal stow of a simple tree with absolute stow and target dirs"
); );
@ -458,38 +459,38 @@ is(
# folded directories should be split open (unfolded) where # folded directories should be split open (unfolded) where
# (and only where) necessary # (and only where) necessary
# #
cd("$OUT_DIR/target"); cd("$TEST_DIR/target");
sub create_pkg { sub create_pkg {
my ($id, $pkg) = @_; my ($id, $pkg) = @_;
my $stow_pkg = "../stow/$id-$pkg"; my $stow_pkg = "../stow/$id-$pkg";
make_dir ($stow_pkg); make_path ($stow_pkg);
make_file("$stow_pkg/$id-file-$pkg"); make_file("$stow_pkg/$id-file-$pkg");
# create a shallow hierarchy specific to this package which isn't # create a shallow hierarchy specific to this package which isn't
# yet stowed # yet stowed
make_dir ("$stow_pkg/$id-$pkg-only-new"); make_path ("$stow_pkg/$id-$pkg-only-new");
make_file("$stow_pkg/$id-$pkg-only-new/$id-file-$pkg"); make_file("$stow_pkg/$id-$pkg-only-new/$id-file-$pkg");
# create a deeper hierarchy specific to this package which isn't # create a deeper hierarchy specific to this package which isn't
# yet stowed # yet stowed
make_dir ("$stow_pkg/$id-$pkg-only-new2/subdir"); make_path ("$stow_pkg/$id-$pkg-only-new2/subdir");
make_file("$stow_pkg/$id-$pkg-only-new2/subdir/$id-file-$pkg"); make_file("$stow_pkg/$id-$pkg-only-new2/subdir/$id-file-$pkg");
make_link("$stow_pkg/$id-$pkg-only-new2/current", "subdir"); make_link("$stow_pkg/$id-$pkg-only-new2/current", "subdir");
# create a hierarchy specific to this package which is already # create a hierarchy specific to this package which is already
# stowed via a folded tree # stowed via a folded tree
make_dir ("$stow_pkg/$id-$pkg-only-old"); make_path ("$stow_pkg/$id-$pkg-only-old");
make_link("$id-$pkg-only-old", "$stow_pkg/$id-$pkg-only-old"); make_link("$id-$pkg-only-old", "$stow_pkg/$id-$pkg-only-old");
make_file("$stow_pkg/$id-$pkg-only-old/$id-file-$pkg"); make_file("$stow_pkg/$id-$pkg-only-old/$id-file-$pkg");
# create a shared hierarchy which this package uses # create a shared hierarchy which this package uses
make_dir ("$stow_pkg/$id-shared"); make_path ("$stow_pkg/$id-shared");
make_file("$stow_pkg/$id-shared/$id-file-$pkg"); make_file("$stow_pkg/$id-shared/$id-file-$pkg");
# create a partially shared hierarchy which this package uses # create a partially shared hierarchy which this package uses
make_dir ("$stow_pkg/$id-shared2/subdir-$pkg"); make_path ("$stow_pkg/$id-shared2/subdir-$pkg");
make_file("$stow_pkg/$id-shared2/$id-file-$pkg"); make_file("$stow_pkg/$id-shared2/$id-file-$pkg");
make_file("$stow_pkg/$id-shared2/subdir-$pkg/$id-file-$pkg"); make_file("$stow_pkg/$id-shared2/subdir-$pkg/$id-file-$pkg");
} }

View file

@ -26,7 +26,7 @@ use warnings;
use Carp qw(croak); use Carp qw(croak);
use File::Basename; use File::Basename;
use File::Path qw(remove_tree); use File::Path qw(make_path remove_tree);
use File::Spec; use File::Spec;
use IO::Scalar; use IO::Scalar;
use Test::More; use Test::More;
@ -36,19 +36,21 @@ use Stow::Util qw(parent canon_path);
use base qw(Exporter); use base qw(Exporter);
our @EXPORT = qw( our @EXPORT = qw(
$OUT_DIR $ABS_TEST_DIR
$TEST_DIR
$stderr $stderr
init_test_dirs init_test_dirs
cd cd
new_Stow new_compat_Stow new_Stow new_compat_Stow
make_dir make_link make_invalid_link make_file make_path make_link make_invalid_link make_file
remove_dir remove_link remove_dir remove_file remove_link
cat_file cat_file
is_link is_dir_not_symlink is_nonexistent_path is_link is_dir_not_symlink is_nonexistent_path
capture_stderr uncapture_stderr capture_stderr uncapture_stderr
); );
our $OUT_DIR = 'tmp-testing-trees'; our $TEST_DIR = 'tmp-testing-trees';
our $ABS_TEST_DIR = File::Spec->rel2abs('tmp-testing-trees');
our $stderr; our $stderr;
my $tied_err; my $tied_err;
@ -64,13 +66,17 @@ sub uncapture_stderr {
} }
sub init_test_dirs { sub init_test_dirs {
for my $dir ("$OUT_DIR/target", "$OUT_DIR/stow") { # Create a run_from/ subdirectory for tests which want to run
-d $dir and remove_tree($dir); # from a separate directory outside the Stow directory or
make_dir($dir); # target directory.
for my $dir ("target", "stow", "run_from") {
my $path = "$TEST_DIR/$dir";
-d $path and remove_tree($path);
make_path($path);
} }
# Don't let user's ~/.stow-global-ignore affect test results # Don't let user's ~/.stow-global-ignore affect test results
$ENV{HOME} = $OUT_DIR; $ENV{HOME} = $ABS_TEST_DIR;
} }
sub new_Stow { sub new_Stow {
@ -138,29 +144,6 @@ sub make_invalid_link {
make_link($target, $source, 1); make_link($target, $source, 1);
} }
#===== SUBROUTINE ===========================================================
# Name : make_dir()
# Purpose : create a directory and any requisite parents
# Parameters: $dir => path to the new directory
# Returns : n/a
# Throws : fatal error if the directory or any of its parents cannot be
# : created
# Comments : none
#============================================================================
sub make_dir {
my ($dir) = @_;
my @parents = ();
for my $part (split '/', $dir) {
my $path = join '/', @parents, $part;
if (not -d $path and not mkdir $path) {
die "could not create directory: $path ($!)\n";
}
push @parents, $part;
}
return;
}
#===== SUBROUTINE =========================================================== #===== SUBROUTINE ===========================================================
# Name : create_file() # Name : create_file()
# Purpose : create an empty file # Purpose : create an empty file

View file

@ -30,7 +30,7 @@ use testutil;
use Stow::Util qw(canon_path); use Stow::Util qw(canon_path);
init_test_dirs(); init_test_dirs();
cd("$OUT_DIR/target"); cd("$TEST_DIR/target");
# Note that each of the following tests use a distinct set of files # Note that each of the following tests use a distinct set of files
@ -42,7 +42,7 @@ my %conflicts;
# #
$stow = new_Stow(); $stow = new_Stow();
make_dir('../stow/pkg1/bin1'); make_path('../stow/pkg1/bin1');
make_file('../stow/pkg1/bin1/file1'); make_file('../stow/pkg1/bin1/file1');
make_link('bin1', '../stow/pkg1/bin1'); make_link('bin1', '../stow/pkg1/bin1');
@ -59,8 +59,8 @@ ok(
# #
$stow = new_Stow(); $stow = new_Stow();
make_dir('lib2'); make_path('lib2');
make_dir('../stow/pkg2/lib2'); make_path('../stow/pkg2/lib2');
make_file('../stow/pkg2/lib2/file2'); make_file('../stow/pkg2/lib2/file2');
make_link('lib2/file2', '../../stow/pkg2/lib2/file2'); make_link('lib2/file2', '../../stow/pkg2/lib2/file2');
$stow->plan_unstow('pkg2'); $stow->plan_unstow('pkg2');
@ -76,13 +76,13 @@ ok(
# #
$stow = new_Stow(); $stow = new_Stow();
make_dir('bin3'); make_path('bin3');
make_dir('../stow/pkg3a/bin3'); make_path('../stow/pkg3a/bin3');
make_file('../stow/pkg3a/bin3/file3a'); make_file('../stow/pkg3a/bin3/file3a');
make_link('bin3/file3a' => '../../stow/pkg3a/bin3/file3a'); # emulate stow make_link('bin3/file3a' => '../../stow/pkg3a/bin3/file3a'); # emulate stow
make_dir('../stow/pkg3b/bin3'); make_path('../stow/pkg3b/bin3');
make_file('../stow/pkg3b/bin3/file3b'); make_file('../stow/pkg3b/bin3/file3b');
make_link('bin3/file3b' => '../../stow/pkg3b/bin3/file3b'); # emulate stow make_link('bin3/file3b' => '../../stow/pkg3b/bin3/file3b'); # emulate stow
$stow->plan_unstow('pkg3b'); $stow->plan_unstow('pkg3b');
@ -99,8 +99,8 @@ ok(
# #
$stow = new_Stow(); $stow = new_Stow();
make_dir('bin4'); make_path('bin4');
make_dir('../stow/pkg4/bin4'); make_path('../stow/pkg4/bin4');
make_file('../stow/pkg4/bin4/file4'); make_file('../stow/pkg4/bin4/file4');
make_invalid_link('bin4/file4', '../../stow/pkg4/bin4/does-not-exist'); make_invalid_link('bin4/file4', '../../stow/pkg4/bin4/does-not-exist');
@ -117,7 +117,7 @@ ok(
# #
$stow = new_Stow(); $stow = new_Stow();
make_dir('../stow/pkg5/bin5'); make_path('../stow/pkg5/bin5');
make_invalid_link('bin5', '../not-stow'); make_invalid_link('bin5', '../not-stow');
$stow->plan_unstow('pkg5'); $stow->plan_unstow('pkg5');
@ -133,12 +133,12 @@ like(
# #
$stow = new_Stow(); $stow = new_Stow();
make_dir('bin6'); make_path('bin6');
make_dir('../stow/pkg6a/bin6'); make_path('../stow/pkg6a/bin6');
make_file('../stow/pkg6a/bin6/file6'); make_file('../stow/pkg6a/bin6/file6');
make_link('bin6/file6', '../../stow/pkg6a/bin6/file6'); make_link('bin6/file6', '../../stow/pkg6a/bin6/file6');
make_dir('../stow/pkg6b/bin6'); make_path('../stow/pkg6b/bin6');
make_file('../stow/pkg6b/bin6/file6'); make_file('../stow/pkg6b/bin6/file6');
$stow->plan_unstow('pkg6b'); $stow->plan_unstow('pkg6b');
@ -152,11 +152,11 @@ ok(
# #
# Don't unlink anything under the stow directory # Don't unlink anything under the stow directory
# #
make_dir('stow'); # make out stow dir a subdir of target make_path('stow'); # make out stow dir a subdir of target
$stow = new_Stow(dir => 'stow'); $stow = new_Stow(dir => 'stow');
# emulate stowing into ourself (bizarre corner case or accident) # emulate stowing into ourself (bizarre corner case or accident)
make_dir('stow/pkg7a/stow/pkg7b'); make_path('stow/pkg7a/stow/pkg7b');
make_file('stow/pkg7a/stow/pkg7b/file7b'); make_file('stow/pkg7a/stow/pkg7b/file7b');
make_link('stow/pkg7b', '../stow/pkg7a/stow/pkg7b'); make_link('stow/pkg7b', '../stow/pkg7a/stow/pkg7b');
@ -175,11 +175,11 @@ ok(
# #
$stow = new_Stow(dir => 'stow'); $stow = new_Stow(dir => 'stow');
make_dir('stow2'); # make our alternate stow dir a subdir of target make_path('stow2'); # make our alternate stow dir a subdir of target
make_file('stow2/.stow'); make_file('stow2/.stow');
# emulate stowing into ourself (bizarre corner case or accident) # emulate stowing into ourself (bizarre corner case or accident)
make_dir('stow/pkg8a/stow2/pkg8b'); make_path('stow/pkg8a/stow2/pkg8b');
make_file('stow/pkg8a/stow2/pkg8b/file8b'); make_file('stow/pkg8a/stow2/pkg8b/file8b');
make_link('stow2/pkg8b', '../stow/pkg8a/stow2/pkg8b'); make_link('stow2/pkg8b', '../stow/pkg8a/stow2/pkg8b');
@ -203,12 +203,12 @@ uncapture_stderr();
$stow = new_Stow(override => ['man9', 'info9']); $stow = new_Stow(override => ['man9', 'info9']);
make_file('stow/.stow'); make_file('stow/.stow');
make_dir('../stow/pkg9a/man9/man1'); make_path('../stow/pkg9a/man9/man1');
make_file('../stow/pkg9a/man9/man1/file9.1'); make_file('../stow/pkg9a/man9/man1/file9.1');
make_dir('man9/man1'); make_path('man9/man1');
make_link('man9/man1/file9.1' => '../../../stow/pkg9a/man9/man1/file9.1'); # emulate stow make_link('man9/man1/file9.1' => '../../../stow/pkg9a/man9/man1/file9.1'); # emulate stow
make_dir('../stow/pkg9b/man9/man1'); make_path('../stow/pkg9b/man9/man1');
make_file('../stow/pkg9b/man9/man1/file9.1'); make_file('../stow/pkg9b/man9/man1/file9.1');
$stow->plan_unstow('pkg9b'); $stow->plan_unstow('pkg9b');
$stow->process_tasks(); $stow->process_tasks();
@ -223,18 +223,18 @@ ok(
# #
$stow = new_Stow(defer => ['man10', 'info10']); $stow = new_Stow(defer => ['man10', 'info10']);
make_dir('../stow/pkg10a/man10/man1'); make_path('../stow/pkg10a/man10/man1');
make_file('../stow/pkg10a/man10/man1/file10a.1'); make_file('../stow/pkg10a/man10/man1/file10a.1');
make_dir('man10/man1'); make_path('man10/man1');
make_link('man10/man1/file10a.1' => '../../../stow/pkg10a/man10/man1/file10a.1'); make_link('man10/man1/file10a.1' => '../../../stow/pkg10a/man10/man1/file10a.1');
# need this to block folding # need this to block folding
make_dir('../stow/pkg10b/man10/man1'); make_path('../stow/pkg10b/man10/man1');
make_file('../stow/pkg10b/man10/man1/file10b.1'); make_file('../stow/pkg10b/man10/man1/file10b.1');
make_link('man10/man1/file10b.1' => '../../../stow/pkg10b/man10/man1/file10b.1'); make_link('man10/man1/file10b.1' => '../../../stow/pkg10b/man10/man1/file10b.1');
make_dir('../stow/pkg10c/man10/man1'); make_path('../stow/pkg10c/man10/man1');
make_file('../stow/pkg10c/man10/man1/file10a.1'); make_file('../stow/pkg10c/man10/man1/file10a.1');
$stow->plan_unstow('pkg10c'); $stow->plan_unstow('pkg10c');
is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg10c'); is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg10c');
@ -249,11 +249,11 @@ ok(
# #
$stow = new_Stow(ignore => ['~', '\.#.*']); $stow = new_Stow(ignore => ['~', '\.#.*']);
make_dir('../stow/pkg12/man12/man1'); make_path('../stow/pkg12/man12/man1');
make_file('../stow/pkg12/man12/man1/file12.1'); make_file('../stow/pkg12/man12/man1/file12.1');
make_file('../stow/pkg12/man12/man1/file12.1~'); make_file('../stow/pkg12/man12/man1/file12.1~');
make_file('../stow/pkg12/man12/man1/.#file12.1'); make_file('../stow/pkg12/man12/man1/.#file12.1');
make_dir('man12/man1'); make_path('man12/man1');
make_link('man12/man1/file12.1' => '../../../stow/pkg12/man12/man1/file12.1'); make_link('man12/man1/file12.1' => '../../../stow/pkg12/man12/man1/file12.1');
$stow->plan_unstow('pkg12'); $stow->plan_unstow('pkg12');
@ -279,8 +279,8 @@ ok(
# Unstow a never stowed package # Unstow a never stowed package
# #
eval { remove_dir("$OUT_DIR/target"); }; eval { remove_dir("$TEST_DIR/target"); };
mkdir("$OUT_DIR/target"); mkdir("$TEST_DIR/target");
$stow = new_Stow(); $stow = new_Stow();
$stow->plan_unstow('pkg12'); $stow->plan_unstow('pkg12');
@ -310,17 +310,17 @@ ok(
# unstow a simple tree minimally when cwd isn't target # unstow a simple tree minimally when cwd isn't target
# #
cd('../..'); cd('../..');
$stow = new_Stow(dir => "$OUT_DIR/stow", target => "$OUT_DIR/target"); $stow = new_Stow(dir => "$TEST_DIR/stow", target => "$TEST_DIR/target");
make_dir("$OUT_DIR/stow/pkg13/bin13"); make_path("$TEST_DIR/stow/pkg13/bin13");
make_file("$OUT_DIR/stow/pkg13/bin13/file13"); make_file("$TEST_DIR/stow/pkg13/bin13/file13");
make_link("$OUT_DIR/target/bin13", '../stow/pkg13/bin13'); make_link("$TEST_DIR/target/bin13", '../stow/pkg13/bin13');
$stow->plan_unstow('pkg13'); $stow->plan_unstow('pkg13');
$stow->process_tasks(); $stow->process_tasks();
ok( ok(
$stow->get_conflict_count == 0 && $stow->get_conflict_count == 0 &&
-f "$OUT_DIR/stow/pkg13/bin13/file13" && ! -e "$OUT_DIR/target/bin13" -f "$TEST_DIR/stow/pkg13/bin13/file13" && ! -e "$TEST_DIR/target/bin13"
=> 'unstow a simple tree' => 'unstow a simple tree'
); );
@ -328,18 +328,18 @@ ok(
# unstow a simple tree minimally with absolute stow dir when cwd isn't # unstow a simple tree minimally with absolute stow dir when cwd isn't
# target # target
# #
$stow = new_Stow(dir => canon_path("$OUT_DIR/stow"), $stow = new_Stow(dir => canon_path("$TEST_DIR/stow"),
target => "$OUT_DIR/target"); target => "$TEST_DIR/target");
make_dir("$OUT_DIR/stow/pkg14/bin14"); make_path("$TEST_DIR/stow/pkg14/bin14");
make_file("$OUT_DIR/stow/pkg14/bin14/file14"); make_file("$TEST_DIR/stow/pkg14/bin14/file14");
make_link("$OUT_DIR/target/bin14", '../stow/pkg14/bin14'); make_link("$TEST_DIR/target/bin14", '../stow/pkg14/bin14');
$stow->plan_unstow('pkg14'); $stow->plan_unstow('pkg14');
$stow->process_tasks(); $stow->process_tasks();
ok( ok(
$stow->get_conflict_count == 0 && $stow->get_conflict_count == 0 &&
-f "$OUT_DIR/stow/pkg14/bin14/file14" && ! -e "$OUT_DIR/target/bin14" -f "$TEST_DIR/stow/pkg14/bin14/file14" && ! -e "$TEST_DIR/target/bin14"
=> 'unstow a simple tree with absolute stow dir' => 'unstow a simple tree with absolute stow dir'
); );
@ -347,18 +347,18 @@ ok(
# unstow a simple tree minimally with absolute stow AND target dirs # unstow a simple tree minimally with absolute stow AND target dirs
# when cwd isn't target # when cwd isn't target
# #
$stow = new_Stow(dir => canon_path("$OUT_DIR/stow"), $stow = new_Stow(dir => canon_path("$TEST_DIR/stow"),
target => canon_path("$OUT_DIR/target")); target => canon_path("$TEST_DIR/target"));
make_dir("$OUT_DIR/stow/pkg15/bin15"); make_path("$TEST_DIR/stow/pkg15/bin15");
make_file("$OUT_DIR/stow/pkg15/bin15/file15"); make_file("$TEST_DIR/stow/pkg15/bin15/file15");
make_link("$OUT_DIR/target/bin15", '../stow/pkg15/bin15'); make_link("$TEST_DIR/target/bin15", '../stow/pkg15/bin15');
$stow->plan_unstow('pkg15'); $stow->plan_unstow('pkg15');
$stow->process_tasks(); $stow->process_tasks();
ok( ok(
$stow->get_conflict_count == 0 && $stow->get_conflict_count == 0 &&
-f "$OUT_DIR/stow/pkg15/bin15/file15" && ! -e "$OUT_DIR/target/bin15" -f "$TEST_DIR/stow/pkg15/bin15/file15" && ! -e "$TEST_DIR/target/bin15"
=> 'unstow a simple tree with absolute stow and target dirs' => 'unstow a simple tree with absolute stow and target dirs'
); );
@ -366,58 +366,58 @@ ok(
# unstow a tree with no-folding enabled - # unstow a tree with no-folding enabled -
# no refolding should take place # no refolding should take place
# #
cd("$OUT_DIR/target"); cd("$TEST_DIR/target");
sub create_and_stow_pkg { sub create_and_stow_pkg {
my ($id, $pkg) = @_; my ($id, $pkg) = @_;
my $stow_pkg = "../stow/$id-$pkg"; my $stow_pkg = "../stow/$id-$pkg";
make_dir ($stow_pkg); make_path ($stow_pkg);
make_file("$stow_pkg/$id-file-$pkg"); make_file("$stow_pkg/$id-file-$pkg");
# create a shallow hierarchy specific to this package and stow # create a shallow hierarchy specific to this package and stow
# via folding # via folding
make_dir ("$stow_pkg/$id-$pkg-only-folded"); make_path ("$stow_pkg/$id-$pkg-only-folded");
make_file("$stow_pkg/$id-$pkg-only-folded/file-$pkg"); make_file("$stow_pkg/$id-$pkg-only-folded/file-$pkg");
make_link("$id-$pkg-only-folded", "$stow_pkg/$id-$pkg-only-folded"); make_link("$id-$pkg-only-folded", "$stow_pkg/$id-$pkg-only-folded");
# create a deeper hierarchy specific to this package and stow # create a deeper hierarchy specific to this package and stow
# via folding # via folding
make_dir ("$stow_pkg/$id-$pkg-only-folded2/subdir"); make_path ("$stow_pkg/$id-$pkg-only-folded2/subdir");
make_file("$stow_pkg/$id-$pkg-only-folded2/subdir/file-$pkg"); make_file("$stow_pkg/$id-$pkg-only-folded2/subdir/file-$pkg");
make_link("$id-$pkg-only-folded2", make_link("$id-$pkg-only-folded2",
"$stow_pkg/$id-$pkg-only-folded2"); "$stow_pkg/$id-$pkg-only-folded2");
# create a shallow hierarchy specific to this package and stow # create a shallow hierarchy specific to this package and stow
# without folding # without folding
make_dir ("$stow_pkg/$id-$pkg-only-unfolded"); make_path ("$stow_pkg/$id-$pkg-only-unfolded");
make_file("$stow_pkg/$id-$pkg-only-unfolded/file-$pkg"); make_file("$stow_pkg/$id-$pkg-only-unfolded/file-$pkg");
make_dir ("$id-$pkg-only-unfolded"); make_path ("$id-$pkg-only-unfolded");
make_link("$id-$pkg-only-unfolded/file-$pkg", make_link("$id-$pkg-only-unfolded/file-$pkg",
"../$stow_pkg/$id-$pkg-only-unfolded/file-$pkg"); "../$stow_pkg/$id-$pkg-only-unfolded/file-$pkg");
# create a deeper hierarchy specific to this package and stow # create a deeper hierarchy specific to this package and stow
# without folding # without folding
make_dir ("$stow_pkg/$id-$pkg-only-unfolded2/subdir"); make_path ("$stow_pkg/$id-$pkg-only-unfolded2/subdir");
make_file("$stow_pkg/$id-$pkg-only-unfolded2/subdir/file-$pkg"); make_file("$stow_pkg/$id-$pkg-only-unfolded2/subdir/file-$pkg");
make_dir ("$id-$pkg-only-unfolded2/subdir"); make_path ("$id-$pkg-only-unfolded2/subdir");
make_link("$id-$pkg-only-unfolded2/subdir/file-$pkg", make_link("$id-$pkg-only-unfolded2/subdir/file-$pkg",
"../../$stow_pkg/$id-$pkg-only-unfolded2/subdir/file-$pkg"); "../../$stow_pkg/$id-$pkg-only-unfolded2/subdir/file-$pkg");
# create a shallow shared hierarchy which this package uses, and stow # create a shallow shared hierarchy which this package uses, and stow
# its contents without folding # its contents without folding
make_dir ("$stow_pkg/$id-shared"); make_path ("$stow_pkg/$id-shared");
make_file("$stow_pkg/$id-shared/file-$pkg"); make_file("$stow_pkg/$id-shared/file-$pkg");
make_dir ("$id-shared"); make_path ("$id-shared");
make_link("$id-shared/file-$pkg", make_link("$id-shared/file-$pkg",
"../$stow_pkg/$id-shared/file-$pkg"); "../$stow_pkg/$id-shared/file-$pkg");
# create a deeper shared hierarchy which this package uses, and stow # create a deeper shared hierarchy which this package uses, and stow
# its contents without folding # its contents without folding
make_dir ("$stow_pkg/$id-shared2/subdir"); make_path ("$stow_pkg/$id-shared2/subdir");
make_file("$stow_pkg/$id-shared2/file-$pkg"); make_file("$stow_pkg/$id-shared2/file-$pkg");
make_file("$stow_pkg/$id-shared2/subdir/file-$pkg"); make_file("$stow_pkg/$id-shared2/subdir/file-$pkg");
make_dir ("$id-shared2/subdir"); make_path ("$id-shared2/subdir");
make_link("$id-shared2/file-$pkg", make_link("$id-shared2/file-$pkg",
"../$stow_pkg/$id-shared2/file-$pkg"); "../$stow_pkg/$id-shared2/file-$pkg");
make_link("$id-shared2/subdir/file-$pkg", make_link("$id-shared2/subdir/file-$pkg",

View file

@ -22,6 +22,7 @@
use strict; use strict;
use warnings; use warnings;
use File::Spec qw(make_path);
use Test::More tests => 37; use Test::More tests => 37;
use Test::Output; use Test::Output;
use English qw(-no_match_vars); use English qw(-no_match_vars);
@ -30,7 +31,7 @@ use testutil;
use Stow::Util qw(canon_path); use Stow::Util qw(canon_path);
init_test_dirs(); init_test_dirs();
cd("$OUT_DIR/target"); cd("$TEST_DIR/target");
# Note that each of the following tests use a distinct set of files # Note that each of the following tests use a distinct set of files
@ -43,7 +44,7 @@ my %conflicts;
$stow = new_compat_Stow(); $stow = new_compat_Stow();
make_dir('../stow/pkg1/bin1'); make_path('../stow/pkg1/bin1');
make_file('../stow/pkg1/bin1/file1'); make_file('../stow/pkg1/bin1/file1');
make_link('bin1', '../stow/pkg1/bin1'); make_link('bin1', '../stow/pkg1/bin1');
@ -60,8 +61,8 @@ ok(
# #
$stow = new_compat_Stow(); $stow = new_compat_Stow();
make_dir('lib2'); make_path('lib2');
make_dir('../stow/pkg2/lib2'); make_path('../stow/pkg2/lib2');
make_file('../stow/pkg2/lib2/file2'); make_file('../stow/pkg2/lib2/file2');
make_link('lib2/file2', '../../stow/pkg2/lib2/file2'); make_link('lib2/file2', '../../stow/pkg2/lib2/file2');
$stow->plan_unstow('pkg2'); $stow->plan_unstow('pkg2');
@ -77,13 +78,13 @@ ok(
# #
$stow = new_compat_Stow(); $stow = new_compat_Stow();
make_dir('bin3'); make_path('bin3');
make_dir('../stow/pkg3a/bin3'); make_path('../stow/pkg3a/bin3');
make_file('../stow/pkg3a/bin3/file3a'); make_file('../stow/pkg3a/bin3/file3a');
make_link('bin3/file3a' => '../../stow/pkg3a/bin3/file3a'); # emulate stow make_link('bin3/file3a' => '../../stow/pkg3a/bin3/file3a'); # emulate stow
make_dir('../stow/pkg3b/bin3'); make_path('../stow/pkg3b/bin3');
make_file('../stow/pkg3b/bin3/file3b'); make_file('../stow/pkg3b/bin3/file3b');
make_link('bin3/file3b' => '../../stow/pkg3b/bin3/file3b'); # emulate stow make_link('bin3/file3b' => '../../stow/pkg3b/bin3/file3b'); # emulate stow
$stow->plan_unstow('pkg3b'); $stow->plan_unstow('pkg3b');
@ -100,8 +101,8 @@ ok(
# #
$stow = new_compat_Stow(); $stow = new_compat_Stow();
make_dir('bin4'); make_path('bin4');
make_dir('../stow/pkg4/bin4'); make_path('../stow/pkg4/bin4');
make_file('../stow/pkg4/bin4/file4'); make_file('../stow/pkg4/bin4/file4');
make_invalid_link('bin4/file4', '../../stow/pkg4/bin4/does-not-exist'); make_invalid_link('bin4/file4', '../../stow/pkg4/bin4/does-not-exist');
@ -118,7 +119,7 @@ ok(
# #
$stow = new_compat_Stow(); $stow = new_compat_Stow();
make_dir('../stow/pkg5/bin5'); make_path('../stow/pkg5/bin5');
make_invalid_link('bin5', '../not-stow'); make_invalid_link('bin5', '../not-stow');
$stow->plan_unstow('pkg5'); $stow->plan_unstow('pkg5');
@ -139,12 +140,12 @@ ok(
# #
$stow = new_compat_Stow(); $stow = new_compat_Stow();
make_dir('bin6'); make_path('bin6');
make_dir('../stow/pkg6a/bin6'); make_path('../stow/pkg6a/bin6');
make_file('../stow/pkg6a/bin6/file6'); make_file('../stow/pkg6a/bin6/file6');
make_link('bin6/file6', '../../stow/pkg6a/bin6/file6'); make_link('bin6/file6', '../../stow/pkg6a/bin6/file6');
make_dir('../stow/pkg6b/bin6'); make_path('../stow/pkg6b/bin6');
make_file('../stow/pkg6b/bin6/file6'); make_file('../stow/pkg6b/bin6/file6');
$stow->plan_unstow('pkg6b'); $stow->plan_unstow('pkg6b');
@ -158,11 +159,11 @@ ok(
# #
# Don't unlink anything under the stow directory # Don't unlink anything under the stow directory
# #
make_dir('stow'); # make out stow dir a subdir of target make_path('stow'); # make out stow dir a subdir of target
$stow = new_compat_Stow(dir => 'stow'); $stow = new_compat_Stow(dir => 'stow');
# emulate stowing into ourself (bizarre corner case or accident) # emulate stowing into ourself (bizarre corner case or accident)
make_dir('stow/pkg7a/stow/pkg7b'); make_path('stow/pkg7a/stow/pkg7b');
make_file('stow/pkg7a/stow/pkg7b/file7b'); make_file('stow/pkg7a/stow/pkg7b/file7b');
make_link('stow/pkg7b', '../stow/pkg7a/stow/pkg7b'); make_link('stow/pkg7b', '../stow/pkg7a/stow/pkg7b');
@ -185,11 +186,11 @@ uncapture_stderr();
# #
$stow = new_compat_Stow(dir => 'stow'); $stow = new_compat_Stow(dir => 'stow');
make_dir('stow2'); # make our alternate stow dir a subdir of target make_path('stow2'); # make our alternate stow dir a subdir of target
make_file('stow2/.stow'); make_file('stow2/.stow');
# emulate stowing into ourself (bizarre corner case or accident) # emulate stowing into ourself (bizarre corner case or accident)
make_dir('stow/pkg8a/stow2/pkg8b'); make_path('stow/pkg8a/stow2/pkg8b');
make_file('stow/pkg8a/stow2/pkg8b/file8b'); make_file('stow/pkg8a/stow2/pkg8b/file8b');
make_link('stow2/pkg8b', '../stow/pkg8a/stow2/pkg8b'); make_link('stow2/pkg8b', '../stow/pkg8a/stow2/pkg8b');
@ -224,12 +225,12 @@ sub check_protected_dirs_skipped {
$stow = new_compat_Stow(override => ['man9', 'info9']); $stow = new_compat_Stow(override => ['man9', 'info9']);
make_file('stow/.stow'); make_file('stow/.stow');
make_dir('../stow/pkg9a/man9/man1'); make_path('../stow/pkg9a/man9/man1');
make_file('../stow/pkg9a/man9/man1/file9.1'); make_file('../stow/pkg9a/man9/man1/file9.1');
make_dir('man9/man1'); make_path('man9/man1');
make_link('man9/man1/file9.1' => '../../../stow/pkg9a/man9/man1/file9.1'); # emulate stow make_link('man9/man1/file9.1' => '../../../stow/pkg9a/man9/man1/file9.1'); # emulate stow
make_dir('../stow/pkg9b/man9/man1'); make_path('../stow/pkg9b/man9/man1');
make_file('../stow/pkg9b/man9/man1/file9.1'); make_file('../stow/pkg9b/man9/man1/file9.1');
capture_stderr(); capture_stderr();
$stow->plan_unstow('pkg9b'); $stow->plan_unstow('pkg9b');
@ -246,18 +247,18 @@ check_protected_dirs_skipped();
# #
$stow = new_compat_Stow(defer => ['man10', 'info10']); $stow = new_compat_Stow(defer => ['man10', 'info10']);
make_dir('../stow/pkg10a/man10/man1'); make_path('../stow/pkg10a/man10/man1');
make_file('../stow/pkg10a/man10/man1/file10a.1'); make_file('../stow/pkg10a/man10/man1/file10a.1');
make_dir('man10/man1'); make_path('man10/man1');
make_link('man10/man1/file10a.1' => '../../../stow/pkg10a/man10/man1/file10a.1'); make_link('man10/man1/file10a.1' => '../../../stow/pkg10a/man10/man1/file10a.1');
# need this to block folding # need this to block folding
make_dir('../stow/pkg10b/man10/man1'); make_path('../stow/pkg10b/man10/man1');
make_file('../stow/pkg10b/man10/man1/file10b.1'); make_file('../stow/pkg10b/man10/man1/file10b.1');
make_link('man10/man1/file10b.1' => '../../../stow/pkg10b/man10/man1/file10b.1'); make_link('man10/man1/file10b.1' => '../../../stow/pkg10b/man10/man1/file10b.1');
make_dir('../stow/pkg10c/man10/man1'); make_path('../stow/pkg10c/man10/man1');
make_file('../stow/pkg10c/man10/man1/file10a.1'); make_file('../stow/pkg10c/man10/man1/file10a.1');
capture_stderr(); capture_stderr();
$stow->plan_unstow('pkg10c'); $stow->plan_unstow('pkg10c');
@ -274,11 +275,11 @@ check_protected_dirs_skipped();
# #
$stow = new_compat_Stow(ignore => ['~', '\.#.*']); $stow = new_compat_Stow(ignore => ['~', '\.#.*']);
make_dir('../stow/pkg12/man12/man1'); make_path('../stow/pkg12/man12/man1');
make_file('../stow/pkg12/man12/man1/file12.1'); make_file('../stow/pkg12/man12/man1/file12.1');
make_file('../stow/pkg12/man12/man1/file12.1~'); make_file('../stow/pkg12/man12/man1/file12.1~');
make_file('../stow/pkg12/man12/man1/.#file12.1'); make_file('../stow/pkg12/man12/man1/.#file12.1');
make_dir('man12/man1'); make_path('man12/man1');
make_link('man12/man1/file12.1' => '../../../stow/pkg12/man12/man1/file12.1'); make_link('man12/man1/file12.1' => '../../../stow/pkg12/man12/man1/file12.1');
capture_stderr(); capture_stderr();
@ -308,8 +309,8 @@ check_protected_dirs_skipped();
# Unstow a never stowed package # Unstow a never stowed package
# #
eval { remove_dir("$OUT_DIR/target"); }; eval { remove_dir("$TEST_DIR/target"); };
mkdir("$OUT_DIR/target"); mkdir("$TEST_DIR/target");
$stow = new_compat_Stow(); $stow = new_compat_Stow();
capture_stderr(); capture_stderr();
@ -343,17 +344,17 @@ check_protected_dirs_skipped();
# unstow a simple tree minimally when cwd isn't target # unstow a simple tree minimally when cwd isn't target
# #
cd('../..'); cd('../..');
$stow = new_Stow(dir => "$OUT_DIR/stow", target => "$OUT_DIR/target"); $stow = new_Stow(dir => "$TEST_DIR/stow", target => "$TEST_DIR/target");
make_dir("$OUT_DIR/stow/pkg13/bin13"); make_path("$TEST_DIR/stow/pkg13/bin13");
make_file("$OUT_DIR/stow/pkg13/bin13/file13"); make_file("$TEST_DIR/stow/pkg13/bin13/file13");
make_link("$OUT_DIR/target/bin13", '../stow/pkg13/bin13'); make_link("$TEST_DIR/target/bin13", '../stow/pkg13/bin13');
$stow->plan_unstow('pkg13'); $stow->plan_unstow('pkg13');
$stow->process_tasks(); $stow->process_tasks();
ok( ok(
$stow->get_conflict_count == 0 && $stow->get_conflict_count == 0 &&
-f "$OUT_DIR/stow/pkg13/bin13/file13" && ! -e "$OUT_DIR/target/bin13" -f "$TEST_DIR/stow/pkg13/bin13/file13" && ! -e "$TEST_DIR/target/bin13"
=> 'unstow a simple tree' => 'unstow a simple tree'
); );
@ -361,18 +362,18 @@ ok(
# unstow a simple tree minimally with absolute stow dir when cwd isn't # unstow a simple tree minimally with absolute stow dir when cwd isn't
# target # target
# #
$stow = new_Stow(dir => canon_path("$OUT_DIR/stow"), $stow = new_Stow(dir => canon_path("$TEST_DIR/stow"),
target => "$OUT_DIR/target"); target => "$TEST_DIR/target");
make_dir("$OUT_DIR/stow/pkg14/bin14"); make_path("$TEST_DIR/stow/pkg14/bin14");
make_file("$OUT_DIR/stow/pkg14/bin14/file14"); make_file("$TEST_DIR/stow/pkg14/bin14/file14");
make_link("$OUT_DIR/target/bin14", '../stow/pkg14/bin14'); make_link("$TEST_DIR/target/bin14", '../stow/pkg14/bin14');
$stow->plan_unstow('pkg14'); $stow->plan_unstow('pkg14');
$stow->process_tasks(); $stow->process_tasks();
ok( ok(
$stow->get_conflict_count == 0 && $stow->get_conflict_count == 0 &&
-f "$OUT_DIR/stow/pkg14/bin14/file14" && ! -e "$OUT_DIR/target/bin14" -f "$TEST_DIR/stow/pkg14/bin14/file14" && ! -e "$TEST_DIR/target/bin14"
=> 'unstow a simple tree with absolute stow dir' => 'unstow a simple tree with absolute stow dir'
); );
@ -380,18 +381,18 @@ ok(
# unstow a simple tree minimally with absolute stow AND target dirs # unstow a simple tree minimally with absolute stow AND target dirs
# when cwd isn't target # when cwd isn't target
# #
$stow = new_Stow(dir => canon_path("$OUT_DIR/stow"), $stow = new_Stow(dir => canon_path("$TEST_DIR/stow"),
target => canon_path("$OUT_DIR/target")); target => canon_path("$TEST_DIR/target"));
make_dir("$OUT_DIR/stow/pkg15/bin15"); make_path("$TEST_DIR/stow/pkg15/bin15");
make_file("$OUT_DIR/stow/pkg15/bin15/file15"); make_file("$TEST_DIR/stow/pkg15/bin15/file15");
make_link("$OUT_DIR/target/bin15", '../stow/pkg15/bin15'); make_link("$TEST_DIR/target/bin15", '../stow/pkg15/bin15');
$stow->plan_unstow('pkg15'); $stow->plan_unstow('pkg15');
$stow->process_tasks(); $stow->process_tasks();
ok( ok(
$stow->get_conflict_count == 0 && $stow->get_conflict_count == 0 &&
-f "$OUT_DIR/stow/pkg15/bin15/file15" && ! -e "$OUT_DIR/target/bin15" -f "$TEST_DIR/stow/pkg15/bin15/file15" && ! -e "$TEST_DIR/target/bin15"
=> 'unstow a simple tree with absolute stow and target dirs' => 'unstow a simple tree with absolute stow and target dirs'
); );