Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions lib/Test/MockFile.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1422,7 +1422,6 @@ When creating mocked files or directories, we default their stats to:
'mtime' => $now, # stat[9]
'ctime' => $now, # stat[10]
'blksize' => 4096, # stat[11]
'fileno' => undef, # fileno()
} );

You'll notice that mode, size, and blocks have been left out of this.
Expand Down Expand Up @@ -1464,7 +1463,6 @@ sub _default_mock_attrs {
'mtime' => $now, # stat[9]
'ctime' => $now, # stat[10]
'blksize' => 4096, # stat[11]
'fileno' => undef, # fileno()
'tty' => 0,
'readlink' => '',
'path' => undef,
Expand Down Expand Up @@ -1535,8 +1533,6 @@ sub new {
$self->{'nlink'} = ( $self->{'mode'} & S_IFMT ) == S_IFDIR ? 2 : 1;
}

$self->{'fileno'} //= _unused_fileno();

$files_being_mocked{$path} = $self;
Scalar::Util::weaken( $files_being_mocked{$path} );

Expand Down Expand Up @@ -2281,10 +2277,6 @@ sub stat {
);
}

sub _unused_fileno {
return 900; # TODO
}

=head2 readlink

Optional Arg: $readlink
Expand Down
15 changes: 7 additions & 8 deletions lib/Test/MockFile/FileHandle.pm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ my $files_being_mocked;
$files_being_mocked = \%Test::MockFile::files_being_mocked;
}

my $_next_fileno = 900;

=head1 NAME

Test::MockFile::FileHandle - Provides a class for L<Test::MockFile> to
Expand Down Expand Up @@ -75,6 +77,7 @@ sub TIEHANDLE {
'read' => $mode =~ m/r/ ? 1 : 0,
'write' => $mode =~ m/w/ ? 1 : 0,
'append' => $mode =~ m/a/ ? 1 : 0,
'fileno' => $_next_fileno++,
}, $class;

# This ref count can't hold the object from getting released.
Expand Down Expand Up @@ -578,19 +581,15 @@ sub OPEN {

=head2 FILENO

B<UNIMPLEMENTED>: Open a ticket in
L<github|https://github.com/cpanel/Test-MockFile/issues> if you need
this feature.

No L<perldoc
documentation|http://perldoc.perl.org/perltie.html#Tying-FileHandles>
exists on this method.
Returns the unique file descriptor number assigned to this handle when
it was opened. Each C<open()> call gets its own fileno, mirroring real
kernel behavior.

=cut

sub FILENO {
my ($self) = @_;
die 'fileno is purposefully unsupported';
return $self->{'fileno'};
}

=head2 SEEK
Expand Down
36 changes: 30 additions & 6 deletions t/fileno.t
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,37 @@ my $file = Test::MockFile->file( '/foo', '' );
my $fh;
ok( lives( sub { open $fh, '<', '/foo' } ), 'Opened file' );

like(
dies( sub { fileno $fh } ),
qr/\Qfileno is purposefully unsupported\E/xms,
'Refuse to support fileno',
);
# fileno should return a value for mocked file handles
ok( defined fileno($fh), 'fileno returns a defined value for a mocked fh' );

ok( lives( sub { close $fh } ), 'Opened file' );
ok( lives( sub { close $fh } ), 'Closed file' );

# Each open() should get a unique fileno, even on the same mocked file.
# This mirrors real behavior where fileno is a property of open(), not the file.
subtest 'unique fileno per open filehandle' => sub {
my $mock_a = Test::MockFile->file( '/unique_a', 'aaa' );
my $mock_b = Test::MockFile->file( '/unique_b', 'bbb' );

open my $fh_a, '<', '/unique_a' or die;
open my $fh_b, '<', '/unique_b' or die;
open my $fh_a2, '<', '/unique_a' or die; # second open of same file

my @filenos = map { fileno($_) } ( $fh_a, $fh_b, $fh_a2 );

# All three should be defined
ok( defined $filenos[0], 'fileno for fh_a is defined' );
ok( defined $filenos[1], 'fileno for fh_b is defined' );
ok( defined $filenos[2], 'fileno for fh_a2 is defined' );

# All three should be distinct (even the two opens of /unique_a)
isnt( $filenos[0], $filenos[1], 'fh_a and fh_b have different filenos' );
isnt( $filenos[0], $filenos[2], 'fh_a and fh_a2 have different filenos' );
isnt( $filenos[1], $filenos[2], 'fh_b and fh_a2 have different filenos' );

close $fh_a;
close $fh_b;
close $fh_a2;
};

done_testing();
exit;
Loading