diff --git a/.gitignore b/.gitignore index 77cf7e0..07d5e7f 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,22 @@ pm_to_blib Test-MockFile-* Test-MockFile-*.tar.gz .DS_Store + +# VIM - https://github.com/github/gitignore/blob/main/Global/Vim.gitignore +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] +# Session +Session.vim +Sessionx.vim +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ diff --git a/lib/Test/MockFile/FileHandle.pm b/lib/Test/MockFile/FileHandle.pm index 74a5539..7396a05 100644 --- a/lib/Test/MockFile/FileHandle.pm +++ b/lib/Test/MockFile/FileHandle.pm @@ -402,10 +402,6 @@ Arguments passed are:C<( $self, $pos, $whence )> Moves the location of our current tell location. -B<$whence is UNIMPLEMENTED>: Open a ticket in -L if you need -this feature. - No L exists on this method. @@ -415,17 +411,34 @@ exists on this method. sub SEEK { my ( $self, $pos, $whence ) = @_; - if ($whence) { - die('Unimplemented'); - } my $file_size = length $self->{'data'}->{'contents'}; return if $file_size < $pos; - $self->{'tell'} = $pos; + my $new_pos; + + my $SEEK_SET = 0; + my $SEEK_CUR = 1; + my $SEEK_END = 2; - return $pos == 0 ? '0 but true' : $pos; + if ($whence == $SEEK_SET) { + $new_pos = $pos; + } elsif ($whence == $SEEK_CUR) { + $new_pos = $self->{'tell'} + $pos; + } elsif ($whence == $SEEK_END) { + $new_pos = $file_size + $pos; + } else { + die('Invalid whence value'); + } + + if ($new_pos < 0 || $new_pos > $file_size) { + return 0; + } + + $self->{'tell'} = $new_pos; + return $new_pos == 0 ? '0 but true' : $new_pos; } + =head2 TELL Returns the numeric location we are in the file. The C tells us diff --git a/t/sysopen.t b/t/sysopen.t index f0023f9..59d95c2 100644 --- a/t/sysopen.t +++ b/t/sysopen.t @@ -83,6 +83,21 @@ is( \%Test::MockFile::files_being_mocked, {}, "No mock files are in cache" ) or ok( seek( $fh, 0, 0 ), 0, "Seek to start of file returns true" ); is( sysseek( $fh, 0, 0 ), "0 but true", "sysseek to start of file returns '0 but true' to make it so." ); ok( sysseek( $fh, 0, 0 ), "sysseek to start of file returns true when checked with ok()" ); + + ok( sysseek( $fh, 5, 0 ), "sysseek to position 5 returns true." ); + ok( sysseek( $fh, 10, 1 ), "Seek 10 bytes forward from the current position." ); + is( sysseek( $fh, 0, 1 ), 15, "Current position is 15 bytes from start." ); + + $buf = ""; + is( sysread( $fh, $buf, 2, 0 ), 2, "Read 2 bytes from current position (10)." ); + is( $buf, "PQ", "Line is as expected." ); + + ok( sysseek( $fh, -5, 2 ), "Seek 5 bytes back from end of file." ); + is( sysseek( $fh, 0, 1 ), 46, "Current position is 46 bytes from start." ); + + $buf = ""; + is( sysread( $fh, $buf, 3, 0 ), 3, "Read 3 bytes from current position (46)." ); + is( $buf, "vwx", "Line is as expected." ); } { @@ -122,6 +137,23 @@ is( \%Test::MockFile::files_being_mocked, {}, "No mock files are in cache" ) or is( sysseek( $fh, 0, 0 ), "0 but true", "sysseek to start of file returns '0 but true' to make it so." ); ok( sysseek( $fh, 0, 0 ), "sysseek to start of file returns true when checked with ok()" ); + ok( sysseek( $fh, 5, 0 ), "sysseek to position 5 returns true." ); + ok( sysseek( $fh, 10, 1 ), "Seek 10 bytes forward from the current position." ); + is( sysseek( $fh, 0, 1 ), 15, "Current position is 15 bytes from start." ); + + $buf = ""; + is( sysread( $fh, $buf, 2, 0 ), 2, "Read 2 bytes from current position (10)." ); + is( $buf, "PQ", "Line is as expected." ); + + ok( sysseek( $fh, -5, 2 ), "Seek 5 bytes back from end of file." ); + is( sysseek( $fh, 0, 1 ), 46, "Current position is 46 bytes from start." ); + + $buf = ""; + is( sysread( $fh, $buf, 3, 0 ), 3, "Read 3 bytes from current position (46)." ); + is( $buf, "vwx", "Line is as expected." ); + + like( dies { sysseek( $fh, 10, 3 ) }, qr/Invalid whence value/, "Dies when given an invalid whence value." ); + close $fh; undef $bar; }