0
  0   ˆl–Ü4ý(ÈT¾R( JjãL©‹FÿÇ„i×]_‹uÐb&=LV[(ÂÆ ?÷     package Test::File;
use strict;

use vars qw(@EXPORT $VERSION);

use Carp            qw(carp);
use Exporter        qw(import);
use File::Spec;
use Test::Builder;
use XSLoader;

@EXPORT = qw(
	file_exists_ok file_not_exists_ok
	file_empty_ok file_not_empty_ok file_size_ok file_max_size_ok
	file_min_size_ok file_readable_ok file_not_readable_ok
	file_writeable_ok file_writable_ok file_not_writeable_ok file_not_writable_ok
	file_executable_ok file_not_executable_ok
	file_mode_is file_mode_isnt
	file_mode_has file_mode_hasnt
	file_is_symlink_ok 	file_is_not_symlink_ok
	symlink_target_exists_ok symlink_target_is
	symlink_target_dangles_ok
	dir_exists_ok dir_contains_ok
	link_count_is_ok link_count_gt_ok link_count_lt_ok
	owner_is owner_isnt
	group_is group_isnt
	file_line_count_is file_line_count_isnt file_line_count_between
	file_contains_like file_contains_unlike
	file_contains_utf8_like file_contains_utf8_unlike
	file_contains_encoded_like file_contains_encoded_unlike
	file_mtime_gt_ok file_mtime_lt_ok file_mtime_age_ok
	);

$VERSION = '1.993';
XSLoader::load(__PACKAGE__, $VERSION) if $^O eq 'MSWin32';

my $Test = Test::Builder->new();

=encoding utf8

=head1 NAME

Test::File -- test file attributes

=head1 SYNOPSIS

  use Test::File;

=head1 DESCRIPTION

This modules provides a collection of test utilities for file
attributes.

Some file attributes depend on the owner of the process testing the
file in the same way the file test operators do.  For instance, root
(or super-user or Administrator) may always be able to read files no
matter the permissions.

Some attributes don't make sense outside of Unix, either, so some
tests automatically skip if they think they won't work on the
platform.  If you have a way to make these functions work on Windows,
for instance, please send me a patch. :) If you want to pretend to be
Windows on a non-Windows machine (for instance, to test C<skip()>),
you can set the C<PRETEND_TO_BE_WINDOWS> environment variable.

The optional NAME parameter for every function allows you to specify a
name for the test.  If not supplied, a reasonable default will be
generated.

=head2 Functions

=over 4

=cut

sub _is_plain_file {
	my $filename = _normalize( shift );

	my $message = do {
		   if( ! -e $filename ) { "does not exist" }
		elsif( ! -f _ )         { "is not a plain file" }
		elsif( -d _ )           { "is a directory"  }
		else { () }
		};

	if( $message ) {
		$Test->diag( "file [$filename] $message");
		return 0;
		}

	return 1;
	}

sub _normalize {
	my $file = shift;
	return unless defined $file;

	return $file =~ m|/|
		? File::Spec->catfile( split m|/|, $file )
		: $file;
	}

sub _win32 {
	return 0 if $^O eq 'darwin';
	return $ENV{PRETEND_TO_BE_WIN32} if defined $ENV{PRETEND_TO_BE_WIN32};
	return $^O =~ m/Win/ || $^O eq 'msys';
	}

# returns true if symlinks can't exist
BEGIN {
	my $cannot_symlink;

	sub _no_symlinks_here {
		return $cannot_symlink if defined $cannot_symlink;

		$cannot_symlink = ! do {
			eval {
				symlink("","");                 # symlink exist in perl
				_IsSymlinkCreationAllowed()		# symlink is ok in current session
				}
		};
	}

	sub _IsSymlinkCreationAllowed {
		if ($^O eq 'MSWin32') {
			#
			# Bare copy of Perl's Win32::IsSymlinkCreationAllowed but with Test::File::Win32 namespace instead of Win32
			#
			my(undef, $major, $minor, $build) = Test::File::Win32::GetOSVersion();

			# Vista was the first Windows version with symlink support
			return !!0 if $major < 6;

			# Since Windows 10 1703, enabling the developer mode allows to create
			# symlinks regardless of process privileges
			if ($major > 10 || ($major == 10 && ($minor > 0 || $build > 15063))) {
				return !!1 if Test::File::Win32::IsDeveloperModeEnabled();
			}

			my $privs = Test::File::Win32::GetProcessPrivileges();

			return !!0 unless $privs;

			# It doesn't matter if the permission is enabled or not, it just has to
			# exist. CreateSymbolicLink() will automatically enable it when needed.
			return exists $privs->{SeCreateSymbol