File: open.t

package info (click to toggle)
libtest-mockfile-perl 0.037-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 436 kB
  • sloc: perl: 4,110; makefile: 7
file content (156 lines) | stat: -rw-r--r-- 5,168 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/perl -w

use strict;
use warnings;

use Test::More;
use Errno qw/ENOENT/;

use File::Temp qw/tempfile/;

use Test::MockFile qw< nostrict >;    # Everything below this can have its open overridden.

my $test_string = "abcd\nefgh\n";
my ( $fh_real, $filename ) = tempfile();
print $fh_real $test_string;

note "-------------- REAL MODE --------------";
my $open_return = open( $fh_real, '<:stdio', $filename );
is( $open_return, 1,        "Open a real file bypassing PERLIO" );
is( <$fh_real>,   "abcd\n", " ... line 1" );
is( <$fh_real>,   "efgh\n", " ... line 2" );
is( <$fh_real>,   undef,    " ... EOF" );

close $fh_real;
undef $fh_real;
unlink $filename;

note "-------------- MOCK MODE --------------";
my $bar = Test::MockFile->file( $filename, $test_string );
$open_return = open( $fh_real, '<:stdio', $filename );
is( $open_return, 1,        "Open a mocked file bypassing PERLIO" );
is( <$fh_real>,   "abcd\n", " ... line 1" );
is( <$fh_real>,   "efgh\n", " ... line 2" );
is( <$fh_real>,   undef,    " ... EOF" );

close $fh_real;
ok( -e $filename, "Real file is there" );
undef $bar;

ok( !-e $filename, "Real file is not there" );

note "Following symlinks for open";
my $mock_file = Test::MockFile->file( $filename, $test_string );
my $mock_link = Test::MockFile->symlink( $filename, '/qwerty' );

{
    is( open( my $fh, '<', '/qwerty' ), 1,        "Open a mocked file via its symlink" );
    is( <$fh>,                          "abcd\n", " ... line 1" );
    is( <$fh>,                          "efgh\n", " ... line 2" );
    is( <$fh>,                          undef,    " ... EOF" );
    close $fh;
}

{
    $mock_file->unlink;
    is( open( my $fh, '<', '/qwerty' ), undef,  "Open a mocked file via its symlink when the file is missing fails." );
    is( $! + 0,                         ENOENT, '$! is ENOENT' );
}

subtest(
    'open modes' => sub {
        foreach my $write_mode (qw( > >> )) {
            my $open_str = $write_mode . '/debug.log';
            my $file     = Test::MockFile->file( '/debug.log', '' );
            my $fh;

            $! = 0;
            ok( open( $fh, $open_str ), "Two-arg $write_mode open works" );
            is( $! + 0, 0, 'No error' );

            $! = 0;
            ok( close($fh), 'Successfully closed open handle' );
            is( $! + 0, 0, 'No error' );
        }

        foreach my $read_mode ( '<', '' ) {
            my $open_str = $read_mode . '/debug.log';
            my $file     = Test::MockFile->file( '/debug.log', '' );
            my $fh;

            $! = 0;
            ok( open( $fh, $open_str ), "Two-arg $read_mode open works" );
            is( $open_str, "${read_mode}/debug.log", "arg not changed" );
            is( $! + 0,    0,                        'No error' );

            $! = 0;
            ok( close($fh), 'Successfully closed open handle' );
            is( $! + 0, 0, 'No error' );
        }

        foreach my $multi_mode (qw( +< +> )) {
            my $open_str = $multi_mode . '/debug.log';
            my $file     = Test::MockFile->file( '/debug.log', '' );
            my $fh;

            $! = 0;
            ok( open( $fh, $open_str ), "Two-arg $multi_mode open fails" );
            is( $! + 0, 0, 'No error' );

            $! = 0;
            ok( open( $fh, $multi_mode, '/debug.log' ), "Three-arg $multi_mode open fails" );
            is( $! + 0, 0, 'No error' );
        }

        # Pipe open pass-through
        my ( $fh, $tempfile ) = tempfile( 'CLEANUP' => 1 );
        my $pipefh;

        # Three-arg pipe write
        ok( open( $pipefh, '|-', "echo hello >> $tempfile" ), 'Succesful three-arg pipe open write' );

        # No point testing $! because it will correctly be set to ESPIPE (29, illegal seek)

        $! = 0;
        ok( close($pipefh), 'Successfully closed pipe' );
        is( $! + 0, 0, 'No error' );

        # Two-arg pipe write
        ok( open( $pipefh, "|echo world >> $tempfile" ), 'Succesful two-arg pipe open write' );

        # No point testing $! because it will correctly be set to ESPIPE (29, illegal seek)

        $! = 0;
        ok( close($pipefh), 'Successfully closed pipe' );
        is( $! + 0, 0, 'No error' );

        # Three-arg pipe write
        ok( open( $pipefh, '-|', "cat $tempfile" ), 'Succesful three-arg pipe open read' );

        # No point testing $! because it will correctly be set to ESPIPE (29, illegal seek)

        my $out = <$pipefh>;
        is( $out, "hello\n", 'Succesfully read from pipe with three-arg' );

        ok( close($pipefh), 'Successfully closed pipe' );

        # No point testing $! because it will correctly be set to ESPIPE (29, illegal seek)

        # Two-arg pipe write
        $out = '';
        ok( open( $pipefh, "cat $tempfile|" ), 'Succesful two-arg pipe open read' );

        # No point testing $! because it will correctly be set to ESPIPE (29, illegal seek)

        $out = <$pipefh>;
        $out .= <$pipefh>;
        is( $out, "hello\nworld\n", 'Succesfully read from pipe with two-arg' );

        $! = 0;
        ok( close($pipefh), 'Successfully closed pipe' );
        is( $! + 0, 0, 'No error' );
    }
);

done_testing();
exit;