From e9ad20576c65c48b3b988bf520830e17e6df39a9 Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Sat, 6 Apr 2024 11:59:23 +0100 Subject: [PATCH] t/unstow.t: convert to use subtests --- t/unstow.t | 561 ++++++++++++++++++++++++++--------------------------- 1 file changed, 275 insertions(+), 286 deletions(-) diff --git a/t/unstow.t b/t/unstow.t index 5e96dde..15288c9 100755 --- a/t/unstow.t +++ b/t/unstow.t @@ -22,7 +22,7 @@ use strict; use warnings; -use Test::More tests => 39; +use Test::More tests => 32; use Test::Output; use English qw(-no_match_vars); @@ -34,332 +34,321 @@ cd("$TEST_DIR/target"); # Note that each of the following tests use a distinct set of files -my $stow; -my %conflicts; +subtest("unstow a simple tree minimally", sub { + plan tests => 3; + my $stow = new_Stow(); -# -# unstow a simple tree minimally -# -$stow = new_Stow(); + make_path('../stow/pkg1/bin1'); + make_file('../stow/pkg1/bin1/file1'); + make_link('bin1', '../stow/pkg1/bin1'); -make_path('../stow/pkg1/bin1'); -make_file('../stow/pkg1/bin1/file1'); -make_link('bin1', '../stow/pkg1/bin1'); + $stow->plan_unstow('pkg1'); + $stow->process_tasks(); + is($stow->get_conflict_count, 0); + ok(-f '../stow/pkg1/bin1/file1'); + ok(! -e 'bin1' => 'unstow a simple tree'); +}); -$stow->plan_unstow('pkg1'); -$stow->process_tasks(); -ok( - $stow->get_conflict_count == 0 && - -f '../stow/pkg1/bin1/file1' && ! -e 'bin1' - => 'unstow a simple tree' -); +subtest("unstow a simple tree from an existing directory", sub { + plan tests => 3; + my $stow = new_Stow(); -# -# unstow a simple tree from an existing directory -# -$stow = new_Stow(); + make_path('lib2'); + make_path('../stow/pkg2/lib2'); + make_file('../stow/pkg2/lib2/file2'); + make_link('lib2/file2', '../../stow/pkg2/lib2/file2'); + $stow->plan_unstow('pkg2'); + $stow->process_tasks(); + is($stow->get_conflict_count, 0); + ok(-f '../stow/pkg2/lib2/file2'); + ok(-d 'lib2' + => 'unstow simple tree from a pre-existing directory' + ); +}); -make_path('lib2'); -make_path('../stow/pkg2/lib2'); -make_file('../stow/pkg2/lib2/file2'); -make_link('lib2/file2', '../../stow/pkg2/lib2/file2'); -$stow->plan_unstow('pkg2'); -$stow->process_tasks(); -ok( - $stow->get_conflict_count == 0 && - -f '../stow/pkg2/lib2/file2' && -d 'lib2' - => 'unstow simple tree from a pre-existing directory' -); +subtest("fold tree after unstowing", sub { + plan tests => 3; + my $stow = new_Stow(); -# -# fold tree after unstowing -# -$stow = new_Stow(); + make_path('bin3'); -make_path('bin3'); + make_path('../stow/pkg3a/bin3'); + make_file('../stow/pkg3a/bin3/file3a'); + make_link('bin3/file3a' => '../../stow/pkg3a/bin3/file3a'); # emulate stow -make_path('../stow/pkg3a/bin3'); -make_file('../stow/pkg3a/bin3/file3a'); -make_link('bin3/file3a' => '../../stow/pkg3a/bin3/file3a'); # emulate stow + make_path('../stow/pkg3b/bin3'); + make_file('../stow/pkg3b/bin3/file3b'); + make_link('bin3/file3b' => '../../stow/pkg3b/bin3/file3b'); # emulate stow + $stow->plan_unstow('pkg3b'); + $stow->process_tasks(); + is($stow->get_conflict_count, 0); + ok(-l 'bin3'); + is(readlink('bin3'), '../stow/pkg3a/bin3' + => 'fold tree after unstowing' + ); +}); -make_path('../stow/pkg3b/bin3'); -make_file('../stow/pkg3b/bin3/file3b'); -make_link('bin3/file3b' => '../../stow/pkg3b/bin3/file3b'); # emulate stow -$stow->plan_unstow('pkg3b'); -$stow->process_tasks(); -ok( - $stow->get_conflict_count == 0 && - -l 'bin3' && - readlink('bin3') eq '../stow/pkg3a/bin3' - => 'fold tree after unstowing' -); +subtest("existing link is owned by stow but is invalid so it gets removed anyway", sub { + plan tests => 2; + my $stow = new_Stow(); -# -# existing link is owned by stow but is invalid so it gets removed anyway -# -$stow = new_Stow(); + make_path('bin4'); + make_path('../stow/pkg4/bin4'); + make_file('../stow/pkg4/bin4/file4'); + make_invalid_link('bin4/file4', '../../stow/pkg4/bin4/does-not-exist'); -make_path('bin4'); -make_path('../stow/pkg4/bin4'); -make_file('../stow/pkg4/bin4/file4'); -make_invalid_link('bin4/file4', '../../stow/pkg4/bin4/does-not-exist'); + $stow->plan_unstow('pkg4'); + $stow->process_tasks(); + is($stow->get_conflict_count, 0); + ok(! -e 'bin4/file4' + => q(remove invalid link owned by stow) + ); +}); -$stow->plan_unstow('pkg4'); -$stow->process_tasks(); -ok( - $stow->get_conflict_count == 0 && - ! -e 'bin4/file4' - => q(remove invalid link owned by stow) -); +subtest("Existing link is not owned by stow", sub { + plan tests => 1; + my $stow = new_Stow(); -# -# Existing link is not owned by stow -# -$stow = new_Stow(); + make_path('../stow/pkg5/bin5'); + make_invalid_link('bin5', '../not-stow'); -make_path('../stow/pkg5/bin5'); -make_invalid_link('bin5', '../not-stow'); + $stow->plan_unstow('pkg5'); + my %conflicts = $stow->get_conflicts; + like( + $conflicts{unstow}{pkg5}[-1], + qr(existing target is not owned by stow) + => q(existing link not owned by stow) + ); +}); -$stow->plan_unstow('pkg5'); -%conflicts = $stow->get_conflicts; -like( - $conflicts{unstow}{pkg5}[-1], - qr(existing target is not owned by stow) - => q(existing link not owned by stow) -); +subtest("Target already exists, is owned by stow, but points to a different package", sub { + plan tests => 3; + my $stow = new_Stow(); -# -# Target already exists, is owned by stow, but points to a different package -# -$stow = new_Stow(); + make_path('bin6'); + make_path('../stow/pkg6a/bin6'); + make_file('../stow/pkg6a/bin6/file6'); + make_link('bin6/file6', '../../stow/pkg6a/bin6/file6'); -make_path('bin6'); -make_path('../stow/pkg6a/bin6'); -make_file('../stow/pkg6a/bin6/file6'); -make_link('bin6/file6', '../../stow/pkg6a/bin6/file6'); + make_path('../stow/pkg6b/bin6'); + make_file('../stow/pkg6b/bin6/file6'); -make_path('../stow/pkg6b/bin6'); -make_file('../stow/pkg6b/bin6/file6'); + $stow->plan_unstow('pkg6b'); + is($stow->get_conflict_count, 0); + ok(-l 'bin6/file6'); + is( + readlink('bin6/file6'), + '../../stow/pkg6a/bin6/file6' + => q(ignore existing link that points to a different package) + ); +}); -$stow->plan_unstow('pkg6b'); -ok( - $stow->get_conflict_count == 0 && - -l 'bin6/file6' && - readlink('bin6/file6') eq '../../stow/pkg6a/bin6/file6' - => q(ignore existing link that points to a different package) -); +subtest("Don't unlink anything under the stow directory", sub { + plan tests => 4; + make_path('stow'); # make out stow dir a subdir of target + my $stow = new_Stow(dir => 'stow'); -# -# Don't unlink anything under the stow directory -# -make_path('stow'); # make out stow dir a subdir of target -$stow = new_Stow(dir => 'stow'); + # emulate stowing into ourself (bizarre corner case or accident) + make_path('stow/pkg7a/stow/pkg7b'); + make_file('stow/pkg7a/stow/pkg7b/file7b'); + make_link('stow/pkg7b', '../stow/pkg7a/stow/pkg7b'); -# emulate stowing into ourself (bizarre corner case or accident) -make_path('stow/pkg7a/stow/pkg7b'); -make_file('stow/pkg7a/stow/pkg7b/file7b'); -make_link('stow/pkg7b', '../stow/pkg7a/stow/pkg7b'); + $stow->plan_unstow('pkg7b'); + is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg7b'); + is($stow->get_conflict_count, 0); + ok(-l 'stow/pkg7b'); + is( + readlink('stow/pkg7b'), + '../stow/pkg7a/stow/pkg7b' + => q(don't unlink any nodes under the stow directory) + ); +}); -$stow->plan_unstow('pkg7b'); -is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg7b'); -ok( - $stow->get_conflict_count == 0 && - -l 'stow/pkg7b' && - readlink('stow/pkg7b') eq '../stow/pkg7a/stow/pkg7b' - => q(don't unlink any nodes under the stow directory) -); +subtest("Don't unlink any nodes under another stow directory", sub { + plan tests => 5; + my $stow = new_Stow(dir => 'stow'); + + make_path('stow2'); # make our alternate stow dir a subdir of target + make_file('stow2/.stow'); + + # emulate stowing into ourself (bizarre corner case or accident) + make_path('stow/pkg8a/stow2/pkg8b'); + make_file('stow/pkg8a/stow2/pkg8b/file8b'); + make_link('stow2/pkg8b', '../stow/pkg8a/stow2/pkg8b'); + + stderr_like( + sub { $stow->plan_unstow('pkg8a'); }, + qr/WARNING: skipping marked Stow directory stow2/ + => "unstowing from ourself should skip stow" + ); + is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg8a'); + is($stow->get_conflict_count, 0); + ok(-l 'stow2/pkg8b'); + is( + readlink('stow2/pkg8b'), + '../stow/pkg8a/stow2/pkg8b' + => q(don't unlink any nodes under another stow directory) + ); +}); + +subtest("overriding already stowed documentation", sub { + plan tests => 2; + my $stow = new_Stow(override => ['man9', 'info9']); + make_file('stow/.stow'); + + make_path('../stow/pkg9a/man9/man1'); + make_file('../stow/pkg9a/man9/man1/file9.1'); + make_path('man9/man1'); + make_link('man9/man1/file9.1' => '../../../stow/pkg9a/man9/man1/file9.1'); # emulate stow + + make_path('../stow/pkg9b/man9/man1'); + make_file('../stow/pkg9b/man9/man1/file9.1'); + $stow->plan_unstow('pkg9b'); + $stow->process_tasks(); + is($stow->get_conflict_count, 0); + ok(!-l 'man9/man1/file9.1' + => 'overriding existing documentation files' + ); +}); + +subtest("deferring to already stowed documentation", sub { + plan tests => 3; + my $stow = new_Stow(defer => ['man10', 'info10']); + + make_path('../stow/pkg10a/man10/man1'); + make_file('../stow/pkg10a/man10/man1/file10a.1'); + make_path('man10/man1'); + make_link('man10/man1/file10a.1' => '../../../stow/pkg10a/man10/man1/file10a.1'); + + # need this to block folding + make_path('../stow/pkg10b/man10/man1'); + make_file('../stow/pkg10b/man10/man1/file10b.1'); + make_link('man10/man1/file10b.1' => '../../../stow/pkg10b/man10/man1/file10b.1'); -# -# Don't unlink any nodes under another stow directory -# -$stow = new_Stow(dir => 'stow'); + make_path('../stow/pkg10c/man10/man1'); + make_file('../stow/pkg10c/man10/man1/file10a.1'); + $stow->plan_unstow('pkg10c'); + is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg10c'); + is($stow->get_conflict_count, 0); + is( + readlink('man10/man1/file10a.1'), + '../../../stow/pkg10a/man10/man1/file10a.1' + => 'defer to existing documentation files' + ); +}); -make_path('stow2'); # make our alternate stow dir a subdir of target -make_file('stow2/.stow'); +subtest("Ignore temp files", sub { + plan tests => 2; + my $stow = new_Stow(ignore => ['~', '\.#.*']); -# emulate stowing into ourself (bizarre corner case or accident) -make_path('stow/pkg8a/stow2/pkg8b'); -make_file('stow/pkg8a/stow2/pkg8b/file8b'); -make_link('stow2/pkg8b', '../stow/pkg8a/stow2/pkg8b'); + 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_path('man12/man1'); + make_link('man12/man1/file12.1' => '../../../stow/pkg12/man12/man1/file12.1'); -stderr_like( - sub { $stow->plan_unstow('pkg8a'); }, - qr/WARNING: skipping marked Stow directory stow2/ - => "unstowing from ourself should skip stow" -); -is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg8a'); -ok( - $stow->get_conflict_count == 0 && - -l 'stow2/pkg8b' && - readlink('stow2/pkg8b') eq '../stow/pkg8a/stow2/pkg8b' - => q(don't unlink any nodes under another stow directory) -); + $stow->plan_unstow('pkg12'); + $stow->process_tasks(); + is($stow->get_conflict_count, 0); + ok(!-e 'man12/man1/file12.1' => 'ignore temp files'); +}); -# -# overriding already stowed documentation -# -$stow = new_Stow(override => ['man9', 'info9']); -make_file('stow/.stow'); +subtest("Unstow an already unstowed package", sub { + plan tests => 2; + my $stow = new_Stow(); + $stow->plan_unstow('pkg12'); + is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg12'); + is( + $stow->get_conflict_count, 0 + => 'unstow already unstowed package pkg12' + ); +}); -make_path('../stow/pkg9a/man9/man1'); -make_file('../stow/pkg9a/man9/man1/file9.1'); -make_path('man9/man1'); -make_link('man9/man1/file9.1' => '../../../stow/pkg9a/man9/man1/file9.1'); # emulate stow +subtest("Unstow a never stowed package", sub { + plan tests => 2; -make_path('../stow/pkg9b/man9/man1'); -make_file('../stow/pkg9b/man9/man1/file9.1'); -$stow->plan_unstow('pkg9b'); -$stow->process_tasks(); -ok( - $stow->get_conflict_count == 0 && - !-l 'man9/man1/file9.1' - => 'overriding existing documentation files' -); + eval { remove_dir("$TEST_DIR/target"); }; + mkdir("$TEST_DIR/target"); -# -# deferring to already stowed documentation -# -$stow = new_Stow(defer => ['man10', 'info10']); + my $stow = new_Stow(); + $stow->plan_unstow('pkg12'); + is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg12 which was never stowed'); + is( + $stow->get_conflict_count, + 0 + => 'unstow never stowed package pkg12' + ); +}); -make_path('../stow/pkg10a/man10/man1'); -make_file('../stow/pkg10a/man10/man1/file10a.1'); -make_path('man10/man1'); -make_link('man10/man1/file10a.1' => '../../../stow/pkg10a/man10/man1/file10a.1'); +subtest("Unstowing when target contains a real file shouldn't be an issue", sub { + plan tests => 3; + make_file('man12/man1/file12.1'); -# need this to block folding -make_path('../stow/pkg10b/man10/man1'); -make_file('../stow/pkg10b/man10/man1/file10b.1'); -make_link('man10/man1/file10b.1' => '../../../stow/pkg10b/man10/man1/file10b.1'); + my $stow = new_Stow(); + $stow->plan_unstow('pkg12'); + is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg12 for third time'); + my %conflicts = $stow->get_conflicts; + is($stow->get_conflict_count, 1); + like( + $conflicts{unstow}{pkg12}[0], + qr!existing target is neither a link nor a directory: man12/man1/file12\.1! + => 'unstow pkg12 for third time' + ); +}); +subtest("unstow a simple tree minimally when cwd isn't target", sub { + plan tests => 3; + cd('../..'); + my $stow = new_Stow(dir => "$TEST_DIR/stow", target => "$TEST_DIR/target"); -make_path('../stow/pkg10c/man10/man1'); -make_file('../stow/pkg10c/man10/man1/file10a.1'); -$stow->plan_unstow('pkg10c'); -is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg10c'); -ok( - $stow->get_conflict_count == 0 && - readlink('man10/man1/file10a.1') eq '../../../stow/pkg10a/man10/man1/file10a.1' - => 'defer to existing documentation files' -); + make_path("$TEST_DIR/stow/pkg13/bin13"); + make_file("$TEST_DIR/stow/pkg13/bin13/file13"); + make_link("$TEST_DIR/target/bin13", '../stow/pkg13/bin13'); -# -# Ignore temp files -# -$stow = new_Stow(ignore => ['~', '\.#.*']); + $stow->plan_unstow('pkg13'); + $stow->process_tasks(); + is($stow->get_conflict_count, 0); + ok(-f "$TEST_DIR/stow/pkg13/bin13/file13"); + ok(! -e "$TEST_DIR/target/bin13" => 'unstow a simple tree'); +}); -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_path('man12/man1'); -make_link('man12/man1/file12.1' => '../../../stow/pkg12/man12/man1/file12.1'); +subtest("unstow a simple tree minimally with absolute stow dir when cwd isn't target", sub { + plan tests => 3; + my $stow = new_Stow(dir => canon_path("$TEST_DIR/stow"), + target => "$TEST_DIR/target"); -$stow->plan_unstow('pkg12'); -$stow->process_tasks(); -ok( - $stow->get_conflict_count == 0 && - !-e 'man12/man1/file12.1' - => 'ignore temp files' -); + make_path("$TEST_DIR/stow/pkg14/bin14"); + make_file("$TEST_DIR/stow/pkg14/bin14/file14"); + make_link("$TEST_DIR/target/bin14", '../stow/pkg14/bin14'); -# -# Unstow an already unstowed package -# -$stow = new_Stow(); -$stow->plan_unstow('pkg12'); -is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg12'); -ok( - $stow->get_conflict_count == 0 - => 'unstow already unstowed package pkg12' -); + $stow->plan_unstow('pkg14'); + $stow->process_tasks(); + is($stow->get_conflict_count, 0); + ok(-f "$TEST_DIR/stow/pkg14/bin14/file14"); + ok(! -e "$TEST_DIR/target/bin14" + => 'unstow a simple tree with absolute stow dir' + ); +}); -# -# Unstow a never stowed package -# +subtest("unstow a simple tree minimally with absolute stow AND target dirs when cwd isn't target", sub { + plan tests => 3; + my $stow = new_Stow(dir => canon_path("$TEST_DIR/stow"), + target => canon_path("$TEST_DIR/target")); -eval { remove_dir("$TEST_DIR/target"); }; -mkdir("$TEST_DIR/target"); + make_path("$TEST_DIR/stow/pkg15/bin15"); + make_file("$TEST_DIR/stow/pkg15/bin15/file15"); + make_link("$TEST_DIR/target/bin15", '../stow/pkg15/bin15'); -$stow = new_Stow(); -$stow->plan_unstow('pkg12'); -is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg12 which was never stowed'); -ok( - $stow->get_conflict_count == 0 - => 'unstow never stowed package pkg12' -); - -# -# Unstowing when target contains a real file shouldn't be an issue. -# -make_file('man12/man1/file12.1'); - -$stow = new_Stow(); -$stow->plan_unstow('pkg12'); -is($stow->get_tasks, 0, 'no tasks to process when unstowing pkg12 for third time'); -%conflicts = $stow->get_conflicts; -ok( - $stow->get_conflict_count == 1 && - $conflicts{unstow}{pkg12}[0] - =~ m!existing target is neither a link nor a directory: man12/man1/file12\.1! - => 'unstow pkg12 for third time' -); - -# -# unstow a simple tree minimally when cwd isn't target -# -cd('../..'); -$stow = new_Stow(dir => "$TEST_DIR/stow", target => "$TEST_DIR/target"); - -make_path("$TEST_DIR/stow/pkg13/bin13"); -make_file("$TEST_DIR/stow/pkg13/bin13/file13"); -make_link("$TEST_DIR/target/bin13", '../stow/pkg13/bin13'); - -$stow->plan_unstow('pkg13'); -$stow->process_tasks(); -ok( - $stow->get_conflict_count == 0 && - -f "$TEST_DIR/stow/pkg13/bin13/file13" && ! -e "$TEST_DIR/target/bin13" - => 'unstow a simple tree' -); - -# -# unstow a simple tree minimally with absolute stow dir when cwd isn't -# target -# -$stow = new_Stow(dir => canon_path("$TEST_DIR/stow"), - target => "$TEST_DIR/target"); - -make_path("$TEST_DIR/stow/pkg14/bin14"); -make_file("$TEST_DIR/stow/pkg14/bin14/file14"); -make_link("$TEST_DIR/target/bin14", '../stow/pkg14/bin14'); - -$stow->plan_unstow('pkg14'); -$stow->process_tasks(); -ok( - $stow->get_conflict_count == 0 && - -f "$TEST_DIR/stow/pkg14/bin14/file14" && ! -e "$TEST_DIR/target/bin14" - => 'unstow a simple tree with absolute stow dir' -); - -# -# unstow a simple tree minimally with absolute stow AND target dirs -# when cwd isn't target -# -$stow = new_Stow(dir => canon_path("$TEST_DIR/stow"), - target => canon_path("$TEST_DIR/target")); - -make_path("$TEST_DIR/stow/pkg15/bin15"); -make_file("$TEST_DIR/stow/pkg15/bin15/file15"); -make_link("$TEST_DIR/target/bin15", '../stow/pkg15/bin15'); - -$stow->plan_unstow('pkg15'); -$stow->process_tasks(); -ok( - $stow->get_conflict_count == 0 && - -f "$TEST_DIR/stow/pkg15/bin15/file15" && ! -e "$TEST_DIR/target/bin15" - => 'unstow a simple tree with absolute stow and target dirs' -); + $stow->plan_unstow('pkg15'); + $stow->process_tasks(); + is($stow->get_conflict_count, 0); + ok(-f "$TEST_DIR/stow/pkg15/bin15/file15"); + ok(! -e "$TEST_DIR/target/bin15" + => 'unstow a simple tree with absolute stow and target dirs' + ); +}); # # unstow a tree with no-folding enabled - @@ -427,7 +416,7 @@ foreach my $pkg (qw{a b}) { create_and_stow_pkg('no-folding', $pkg); } -$stow = new_Stow('no-folding' => 1); +my $stow = new_Stow('no-folding' => 1); $stow->plan_unstow('no-folding-b'); is_deeply([ $stow->get_conflicts ], [] => 'no conflicts with --no-folding'); use Data::Dumper;