#!/usr/bin/perl -w
use strict;
use warnings;
use Test2::Bundle::Extended;
use Test2::Tools::Explain;
use Test2::Plugin::NoWarnings;
use Test::MockFile qw< nostrict >;
use Overload::FileCheck qw/:check/;
use Errno qw/ELOOP/;
use Cwd ();
# Assures testers don't mess up with our hard coded perms expectations.
umask 022;
note "_abs_path_to_file";
my $cwd = Cwd::getcwd();
is( Test::MockFile::_abs_path_to_file("0"), "$cwd/0", "no / prefix makes prepends path on it." );
is( Test::MockFile::_abs_path_to_file("/lib"), "/lib", "/lib is /lib" );
is( Test::MockFile::_abs_path_to_file(), undef, "undef is undef" );
note "_fh_to_file";
my @mocked_files;
push @mocked_files, Test::MockFile->file( '/foo/bar', "" );
push @mocked_files, Test::MockFile->file( '/bar/foo', "" );
open( my $fh, "<", "/foo/bar" ) or die;
open( my $fh2, "<", "/bar/foo" ) or die;
is( Test::MockFile::_fh_to_file(), undef, "_fh_to_file()" );
is( Test::MockFile::_fh_to_file(0), undef, "_fh_to_file(0)" );
is( Test::MockFile::_fh_to_file(''), undef, "_fh_to_file('')" );
is( Test::MockFile::_fh_to_file(' '), undef, "_fh_to_file(' ')" );
is( Test::MockFile::_fh_to_file('/etc/passwd'), undef, "_fh_to_file('/etc/passwd')" );
is( Test::MockFile::_fh_to_file($fh), '/foo/bar', "_fh_to_file(\$fh)" );
is( Test::MockFile::_fh_to_file($fh2), '/bar/foo', "_fh_to_file(\$fh2)" );
close $fh;
close $fh2;
is( Test::MockFile::_fh_to_file($fh), undef, "_fh_to_file(\$fh) when closed." );
note "_find_file_or_fh";
push @mocked_files, Test::MockFile->symlink( '/foo/bar', '/abc' );
is( Test::MockFile::_find_file_or_fh('/abc'), '/abc', "_find_file_or_fh('/abc')" );
is( Test::MockFile::_find_file_or_fh( '/abc', 1 ), '/foo/bar', "_find_file_or_fh('/abc', 1) - follow" );
push @mocked_files, Test::MockFile->symlink( '/not/a/file', '/broken_link' );
is( Test::MockFile::_find_file_or_fh( '/broken_link', 1 ), Test::MockFile::BROKEN_SYMLINK(), "_find_file_or_fh('/broken_link', 1) is undef when /broken_link is mocked." );
push @mocked_files, Test::MockFile->symlink( '/aaa', '/bbb' );
push @mocked_files, Test::MockFile->symlink( '/bbb', '/aaa' );
is( Test::MockFile::_find_file_or_fh( '/aaa', 1 ), Test::MockFile::CIRCULAR_SYMLINK(), "_find_file_or_fh('/aaaa', 1) - with circular links" );
is( $! + 0, ELOOP, '$! is ELOOP' );
note "_mock_stat";
is( Test::MockFile::_mock_stat( 'lstat', "/lib" ), FALLBACK_TO_REAL_OP(), "An unmocked file will return FALLBACK_TO_REAL_OP() to tell XS to handle it" );
like( dies { Test::MockFile::_mock_stat() }, qr/^_mock_stat called without a stat type at /, "no args fails cause we should have gotten a stat type." );
like( dies { Test::MockFile::_mock_stat( 'notastat', '' ) }, qr/^Unexpected stat type 'notastat' at /, "An unknown stat type fails cause this should never happen." );
is( Test::MockFile::_mock_stat( 'lstat', "" ), FALLBACK_TO_REAL_OP(), "empty string passes to XS" );
is( Test::MockFile::_mock_stat( 'stat', ' ' ), FALLBACK_TO_REAL_OP(), "A space string passes to XS" );
my $basic_stat_return = array {
item 0;
item 0;
item 0100644;
item 0;
item match qr/^[0-9]+$/;
item match qr/^[0-9\s]+$/;
item 0;
item 0;
item match qr/^[0-9]{3,}$/;
item match qr/^[0-9]{3,}$/;
item match qr/^[0-9]{3,}$/;
item 4096;
item 1;
};
is( Test::MockFile::_mock_stat( 'lstat', '/foo/bar' ), $basic_stat_return, "/foo/bar mock stat" );
is( Test::MockFile::_mock_stat( 'stat', '/aaa' ), [], "/aaa mock stat when looped." );
is( $! + 0, ELOOP, "Throws an ELOOP error" );
push @mocked_files, Test::MockFile->file('/foo/baz'); # Missing file but mocked.
is( Test::MockFile::_mock_stat( 'lstat', '/foo/baz' ), [], "/foo/baz mock stat when missing." );
my $symlink_lstat_return = array {
item 0;
item 0;
item 0127777;
item 0;
item match qr/^[0-9]+$/;
item match qr/^[0-9\s]+$/;
item 0;
item 1;
item match qr/^[0-9]{3,}$/;
item match qr/^[0-9]{3,}$/;
item match qr/^[0-9]{3,}$/;
item 4096;
item 1;
};
is( Test::MockFile::_mock_stat( 'lstat', '/broken_link' ), $symlink_lstat_return, "lstat on /broken_link returns the stat on the symlink itself." );
is( Test::MockFile::_mock_stat( 'stat', '/broken_link' ), [], "stat on /broken_link is an empty array since what it points to doesn't exist." );
{
my $exe = q[/tmp/custom.exe];
my $tmp = Test::MockFile->file( $exe, " ", { mode => 0700 } );
ok -x $exe, "mocked file is executable";
my (
$dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
$atime, $mtime, $ctime, $blksize, $blocks
) = stat($exe);
is $uid, $>, 'default uid is current UID';
note "GID $gid";
is $gid, int $), 'default fid is current GID';
}
{
# make sure directories with trailing slash are not ignored by stat by accident
my $dir = Test::MockFile->dir('/quux');
mkdir $dir->path();
ok( -d ( $dir->path() ), 'Directory /quux exists' );
ok( -d ( $dir->path() . '/' ), 'Directory /quux/ also exists' );
}
done_testing();
exit;