#!/usr/bin/perl -w use strict; use warnings; use Test2::Bundle::Extended; use Test2::Tools::Explain; use Test2::Plugin::NoWarnings; use File::Temp qw/tempfile tempdir/; use File::Slurper (); use Fcntl; #use Errno qw/ENOENT EBADF/; use Test::MockFile qw< nostrict >; # Everything below this can have its open overridden. my ( undef, $filename ) = tempfile(); unlink $filename; { note "-------------- REAL MODE --------------"; is( sysopen( my $fh, $filename, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC ), 1, "Sysopen for write" ); my $str = join( "", "a" .. "z" ); is( syswrite( $fh, $str ), 26, "2 arg syswrite" ); my $str_cap = join( "", "A" .. "Y" ); is( syswrite( $fh, $str_cap, 13 ), 13, "3 arg syswrite" ); is( syswrite( $fh, $str_cap, 12, 13 ), 12, "4 arg syswrite" ); is( close $fh, 1, "sysclose \$fh" ); is( File::Slurper::read_binary($filename), $str . $str_cap, "file contents match what was written" ); unlink $filename; } { my $str = join( "", "a" .. "z" ); my $str_cap = join( "", "A" .. "Y" ); note "-------------- MOCK MODE --------------"; my $bar = Test::MockFile->file($filename); is( sysopen( my $fh, $filename, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC ), 1, "Sysopen for write" ); is( syswrite( $fh, $str ), 26, "2 arg syswrite" ); is( syswrite( $fh, $str_cap, 13 ), 13, "3 arg syswrite" ); is( syswrite( $fh, $str_cap, 12, 13 ), 12, "4 arg syswrite" ); is( close $fh, 1, "sysclose \$fh" ); is( $bar->contents, $str . $str_cap, "Fake file contents match what was written" ); undef $bar; ok( !-e $filename, "mocked $filename is not present after mock file goes offline" ); } is( \%Test::MockFile::files_being_mocked, {}, "No mock files are in cache" ) or die; { my $str = join( "", "a" .. "z" ); my $str_cap = join( "", "A" .. "Y" ); note "-------------- REAL MODE --------------"; File::Slurper::write_binary( $filename, $str_cap . $str ); is( sysopen( my $fh, $filename, O_RDONLY | O_NOFOLLOW ), 1, "Sysopen for read" ); my $buf = "blah"; is( sysread( $fh, $buf, 2, 4 ), 2, "Read 2 into buf at EOL" ); is( $buf, "blahAB", "Confirm 2 line read" ); is( sysread( $fh, $buf, 2, 0 ), 2, "Read into buf at pos 0 truncates the buffer." ); is( $buf, "CD", "Confirm 2 line read" ); $buf = "a" x 10; is( sysread( $fh, $buf, 0, 0 ), 0, "Read 0 into buf at pos 0 truncates the buffer completely." ); is( $buf, "", "Buffer is clear" ); $buf = "b" x 10; is( sysread( $fh, $buf, 2, 5 ), 2, "Read 2 into buf at pos 5 truncates after the buffer." ); is( $buf, "bbbbbEF", "Line is as expected." ); $buf = "c" x 2; is( sysread( $fh, $buf, 3, 6 ), 3, "Read 3 into buf after EOL for the buffer fills in zeroes." ); is( $buf, "cc\0\0\0\0GHI", "Buffer has null bytes in the middle of it." ); $buf = "d" x 5; is( seek( $fh, 49, 0 ), 1, "Seek to near EOF" ); is( sysread( $fh, $buf, 4 ), 2, "Read 2 into buf since we're at EOF" ); is( $buf, "yz", "Buffer is clear" ); 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()" ); } { my $str = join( "", "a" .. "z" ); my $str_cap = join( "", "A" .. "Y" ); note "-------------- MOCK MODE --------------"; my $bar = Test::MockFile->file( $filename, $str_cap . $str ); is( sysopen( my $fh, $filename, O_RDONLY | O_NOFOLLOW ), 1, "Sysopen for read" ); like( "$fh", qr/^IO::File=GLOB\(0x[0-9a-f]+\)$/, '$fh stringifies to a IO::File GLOB' ); my $buf = "blah"; is( sysread( $fh, $buf, 2, 4 ), 2, "Read 2 into buf at EOL" ); is( $buf, "blahAB", "Confirm 2 line read" ); is( sysread( $fh, $buf, 2, 0 ), 2, "Read into buf at pos 0 truncates the buffer." ); is( $buf, "CD", "Confirm 2 line read" ); $buf = "a" x 10; is( sysread( $fh, $buf, 0, 0 ), 0, "Read 0 into buf at pos 0 truncates the buffer completely." ); is( $buf, "", "Buffer is clear" ); $buf = "b" x 10; is( sysread( $fh, $buf, 2, 5 ), 2, "Read 2 into buf at pos 5 truncates after the buffer." ); is( $buf, "bbbbbEF", "Line is as expected." ); $buf = "c" x 2; is( sysread( $fh, $buf, 3, 6 ), 3, "Read 3 into buf after EOL for the buffer fills in zeroes." ); is( $buf, "cc\0\0\0\0GHI", "Buffer has null bytes in the middle of it." ); $buf = "d" x 5; is( seek( $fh, 49, 0 ), 49, "Seek to near EOF" ); is( sysread( $fh, $buf, 4 ), 2, "Read 2 into buf since we're at EOF" ); is( $buf, "yz", "Buffer is clear" ); 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()" ); close $fh; undef $bar; } { my $str = join( "", "a" .. "z" ); my $str_cap = join( "", "A" .. "Y" ); note "-------------- REAL MODE --------------"; File::Slurper::write_binary( $filename, $str_cap . $str ); is( sysopen( my $fh, $filename, O_RDONLY | O_NOFOLLOW ), 1, "Sysopen for read" ); my $buf; is( sysread( $fh, $buf, 2 ), 2, "Read 2 into buf when buf is undef." ); is( $buf, "AB", "Confirm 2 char is read" ); unlink $filename; } { my $str = join( "", "a" .. "z" ); my $str_cap = join( "", "A" .. "Y" ); note "-------------- MOCK MODE --------------"; my $bar = Test::MockFile->file( $filename, $str_cap . $str ); is( sysopen( my $fh, $filename, O_RDONLY | O_NOFOLLOW ), 1, "Sysopen for read" ); my $buf; is( sysread( $fh, $buf, 2 ), 2, "Read 2 into buf when buf is undef." ); is( $buf, "AB", "Confirm 2 char is read" ); } is( \%Test::MockFile::files_being_mocked, {}, "No mock files are in cache" ); done_testing(); exit;