xref: /openbsd-src/gnu/usr.bin/perl/cpan/File-Path/t/FilePathTest.pm (revision 2e109fb9e8c0dc273648ddbc62f0a74abf9e098d)
1b8851fccSafresh1package FilePathTest;
2b8851fccSafresh1use strict;
3b8851fccSafresh1use warnings;
4b8851fccSafresh1use base 'Exporter';
5b8851fccSafresh1use SelectSaver;
6*2e109fb9Safresh1use Carp;
7b8851fccSafresh1use Cwd;
8b8851fccSafresh1use File::Spec::Functions;
9*2e109fb9Safresh1use File::Path ();
10*2e109fb9Safresh1use Test::More ();
11b8851fccSafresh1
12*2e109fb9Safresh1our @EXPORT_OK = qw(
13*2e109fb9Safresh1    _run_for_warning
14*2e109fb9Safresh1    _run_for_verbose
15b8851fccSafresh1    _cannot_delete_safe_mode
16*2e109fb9Safresh1    _verbose_expected
17*2e109fb9Safresh1    create_3_level_subdirs
18*2e109fb9Safresh1    cleanup_3_level_subdirs
19014083a1Safresh1);
20c0dd97bfSafresh1
21*2e109fb9Safresh1sub _basedir {
22*2e109fb9Safresh1  return catdir(
23*2e109fb9Safresh1      curdir(),
24*2e109fb9Safresh1      sprintf( 'test-%x-%x-%x', time, $$, rand(99999) ),
25*2e109fb9Safresh1  );
26b8851fccSafresh1}
27b8851fccSafresh1
28b8851fccSafresh1sub _run_for_warning {
29b8851fccSafresh1  my $coderef = shift;
30b8851fccSafresh1  my $warn = '';
31b8851fccSafresh1  local $SIG{__WARN__} = sub { $warn .= shift };
32b8851fccSafresh1  &$coderef;
33b8851fccSafresh1  return $warn;
34b8851fccSafresh1}
35b8851fccSafresh1
36b8851fccSafresh1sub _run_for_verbose {
37b8851fccSafresh1  my $coderef = shift;
38b8851fccSafresh1  my $stdout = '';
39b8851fccSafresh1  {
40b8851fccSafresh1    my $guard = SelectSaver->new(_ref_to_fh(\$stdout));
41b8851fccSafresh1    &$coderef;
42b8851fccSafresh1  }
43b8851fccSafresh1  return $stdout;
44b8851fccSafresh1}
45b8851fccSafresh1
46b8851fccSafresh1sub _ref_to_fh {
47b8851fccSafresh1  my $output = shift;
48b8851fccSafresh1  open my $fh, '>', $output;
49b8851fccSafresh1  return $fh;
50b8851fccSafresh1}
51b8851fccSafresh1
52b8851fccSafresh1# Whether a directory can be deleted without modifying permissions varies
53b8851fccSafresh1# by platform and by current privileges, so we really have to do the same
54b8851fccSafresh1# check the module does in safe mode to determine that.
55b8851fccSafresh1
56b8851fccSafresh1sub _cannot_delete_safe_mode {
57b8851fccSafresh1  my $path = shift;
58b8851fccSafresh1  return $^O eq 'VMS'
59b8851fccSafresh1         ? !&VMS::Filespec::candelete($path)
60b8851fccSafresh1         : !-w $path;
61b8851fccSafresh1}
62b8851fccSafresh1
63b8851fccSafresh1# What verbose mode reports depends on what it can do in safe mode.
64b8851fccSafresh1# Plus on VMS, mkpath may report what it's operating on in a
65b8851fccSafresh1# different format from the format of the path passed to it.
66b8851fccSafresh1
67b8851fccSafresh1sub _verbose_expected {
68b8851fccSafresh1  my ($function, $path, $safe_mode, $base) = @_;
69b8851fccSafresh1  my $expected;
70b8851fccSafresh1
71b8851fccSafresh1  if ($function =~ m/^(mkpath|make_path)$/) {
72b8851fccSafresh1    # On VMS, mkpath reports in Unix format.  Maddeningly, it
73b8851fccSafresh1    # reports the top-level directory without a trailing slash
74b8851fccSafresh1    # and everything else with.
75b8851fccSafresh1    if ($^O eq 'VMS') {
76b8851fccSafresh1      $path = VMS::Filespec::unixify($path);
77b8851fccSafresh1      $path =~ s/\/$// if defined $base && $base;
78b8851fccSafresh1    }
79b8851fccSafresh1    $expected = "mkdir $path\n";
80b8851fccSafresh1  }
81b8851fccSafresh1  elsif ($function =~ m/^(rmtree|remove_tree)$/) {
82b8851fccSafresh1    # N.B. Directories must still/already exist for this to work.
83b8851fccSafresh1    $expected = $safe_mode && _cannot_delete_safe_mode($path)
84b8851fccSafresh1              ? "skipped $path\n"
85b8851fccSafresh1              : "rmdir $path\n";
86b8851fccSafresh1  }
87b8851fccSafresh1  elsif ($function =~ m/^(unlink)$/) {
88b8851fccSafresh1    $expected = "unlink $path\n";
89b8851fccSafresh1    $expected =~ s/\n\z/\.\n/ if $^O eq 'VMS';
90b8851fccSafresh1  }
91b8851fccSafresh1  else {
92b8851fccSafresh1    die "Unknown function $function in _verbose_expected";
93b8851fccSafresh1  }
94b8851fccSafresh1  return $expected;
95b8851fccSafresh1}
96b8851fccSafresh1
97b8851fccSafresh1BEGIN {
98b8851fccSafresh1  if ($] < 5.008000) {
99b8851fccSafresh1    eval qq{#line @{[__LINE__+1]} "@{[__FILE__]}"\n} . <<'END' or die $@;
100b8851fccSafresh1      no warnings 'redefine';
101b8851fccSafresh1      use Symbol ();
102b8851fccSafresh1
103b8851fccSafresh1      sub _ref_to_fh {
104b8851fccSafresh1        my $output = shift;
105b8851fccSafresh1        my $fh = Symbol::gensym();
106b8851fccSafresh1        tie *$fh, 'StringIO', $output;
107b8851fccSafresh1        return $fh;
108b8851fccSafresh1      }
109b8851fccSafresh1
110b8851fccSafresh1      package StringIO;
111b8851fccSafresh1      sub TIEHANDLE { bless [ $_[1] ], $_[0] }
112b8851fccSafresh1      sub CLOSE    { @{$_[0]} = (); 1 }
113b8851fccSafresh1      sub PRINT    { ${ $_[0][0] } .= $_[1] }
114b8851fccSafresh1      sub PRINTF   { ${ $_[0][0] } .= sprintf $_[1], @_[2..$#_] }
115b8851fccSafresh1      1;
116b8851fccSafresh1END
117b8851fccSafresh1  }
118b8851fccSafresh1}
119b8851fccSafresh1
120*2e109fb9Safresh1sub create_3_level_subdirs {
121*2e109fb9Safresh1    my @dirnames = @_;
122*2e109fb9Safresh1    my %seen = map {$_ => 1} @dirnames;
123*2e109fb9Safresh1    croak "Need 3 distinct names for subdirectories"
124*2e109fb9Safresh1        unless scalar(keys %seen) == 3;
125*2e109fb9Safresh1    my $tdir = File::Spec::Functions::tmpdir();
126*2e109fb9Safresh1    my $least_deep      = catdir($tdir, $dirnames[0]);
127*2e109fb9Safresh1    my $next_deepest    = catdir($least_deep, $dirnames[1]);
128*2e109fb9Safresh1    my $deepest         = catdir($next_deepest, $dirnames[2]);
129*2e109fb9Safresh1    return ($least_deep, $next_deepest, $deepest);
130*2e109fb9Safresh1}
131*2e109fb9Safresh1
132*2e109fb9Safresh1sub cleanup_3_level_subdirs {
133*2e109fb9Safresh1    # runs 2 tests
134*2e109fb9Safresh1    my $least_deep = shift;
135*2e109fb9Safresh1    croak "Must provide path of least subdirectory"
136*2e109fb9Safresh1        unless (length($least_deep) and (-d $least_deep));
137*2e109fb9Safresh1    my $x;
138*2e109fb9Safresh1    my $opts = { error => \$x };
139*2e109fb9Safresh1    File::Path::remove_tree($least_deep, $opts);
140*2e109fb9Safresh1    Test::More::ok(! -d $least_deep, "directory '$least_deep' removed, as expected");
141*2e109fb9Safresh1    Test::More::is(scalar(@{$x}), 0, "no error messages using remove_tree() with \$opts");
142*2e109fb9Safresh1}
143*2e109fb9Safresh1
144b8851fccSafresh11;
145