This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
If the downstream caller wants block mode, and we're in line mode,
[perl5.git] / t / op / incfilter.t
1 #!./perl -w
2
3 # Tests for the source filters in coderef-in-@INC
4
5 BEGIN {
6     chdir 't' if -d 't';
7     @INC = qw(. ../lib);
8     unless (find PerlIO::Layer 'perlio') {
9         print "1..0 # Skip: not perlio\n";
10         exit 0;
11     }
12     require "test.pl";
13 }
14 use strict;
15 use Filter::Util::Call;
16
17 plan(tests => 108);
18
19 unshift @INC, sub {
20     no warnings 'uninitialized';
21     ref $_[1] eq 'ARRAY' ? @{$_[1]} : $_[1];
22 };
23
24 my $fh;
25
26 open $fh, "<", \'pass("Can return file handles from \@INC");';
27 do $fh or die;
28
29 my @origlines = ("# This is a blank line\n",
30                  "pass('Can return generators from \@INC');\n",
31                  "pass('Which return multiple lines');\n",
32                  "1",
33                  );
34 my @lines = @origlines;
35 sub generator {
36     $_ = shift @lines;
37     # Return of 0 marks EOF
38     return defined $_ ? 1 : 0;
39 };
40
41 do \&generator or die;
42
43 @lines = @origlines;
44 # Check that the array dereferencing works ready for the more complex tests:
45 do [\&generator] or die;
46
47 do [sub {
48         my $param = $_[1];
49         is (ref $param, 'ARRAY', "Got our parameter");
50         $_ = shift @$param;
51         return defined $_ ? 1 : 0;
52     }, ["pass('Can return generators which take state');\n",
53         "pass('And return multiple lines');\n",
54         ]] or die;
55    
56
57 open $fh, "<", \'fail("File handles and filters work from \@INC");';
58
59 do [$fh, sub {s/fail/pass/; return;}] or die;
60
61 open $fh, "<", \'fail("File handles and filters with state work from \@INC");';
62
63 do [$fh, sub {s/$_[1]/pass/; return;}, 'fail'] or die;
64
65 print "# 2 tests with pipes from subprocesses.\n";
66
67 open $fh, 'echo pass|' or die $!;
68
69 do $fh or die;
70
71 open $fh, 'echo fail|' or die $!;
72
73 do [$fh, sub {s/$_[1]/pass/; return;}, 'fail'] or die;
74
75 sub rot13_filter {
76     filter_add(sub {
77                    my $status = filter_read();
78                    tr/A-Za-z/N-ZA-Mn-za-m/;
79                    $status;
80                })
81 }
82
83 open $fh, "<", \<<'EOC';
84 BEGIN {rot13_filter};
85 cnff("This will rot13'ed prepend");
86 EOC
87
88 do $fh or die;
89
90 open $fh, "<", \<<'EOC';
91 ORTVA {ebg13_svygre};
92 pass("This will rot13'ed twice");
93 EOC
94
95 do [$fh, sub {tr/A-Za-z/N-ZA-Mn-za-m/; return;}] or die;
96
97 my $count = 32;
98 sub prepend_rot13_filter {
99     filter_add(sub {
100                    my $previous = defined $_ ? $_ : '';
101                    # Filters should append to any existing data in $_
102                    # But (logically) shouldn't filter it twice.
103                    my $test = "fzrt!";
104                    $_ = $test;
105                    my $status = filter_read();
106                    my $got = substr $_, 0, length $test, '';
107                    is $got, $test, "Upstream didn't alter existing data";
108                    tr/A-Za-z/N-ZA-Mn-za-m/;
109                    $_ = $previous . $_;
110                    die "Looping infinitely" unless $count--;
111                    $status;
112                })
113 }
114
115 open $fh, "<", \<<'EOC';
116 ORTVA {cercraq_ebg13_svygre};
117 pass("This will rot13'ed twice");
118 EOC
119
120 do [$fh, sub {tr/A-Za-z/N-ZA-Mn-za-m/; return;}] or die;
121
122 # This generates a heck of a lot of oks, but I think it's necessary.
123 my $amount = 1;
124 sub prepend_block_counting_filter {
125     filter_add(sub {
126                    my $output = defined $_ ? $_ : '';
127                    my $count = 256;
128                    while (--$count) {
129                        $_ = '';
130                        my $status = filter_read($amount);
131                        cmp_ok (length $_, '<=', $amount, "block mode works?");
132                        $output .= $_;
133                        if ($status <= 0 or /\n/s) {
134                            $_ = $output;
135                            return $status;
136                        }
137                    }
138                    die "Looping infinitely";
139                           
140                })
141 }
142
143 open $fh, "<", \<<'EOC';
144 BEGIN {prepend_block_counting_filter};
145 pass("one by one");
146 pass("and again");
147 EOC
148
149 do [$fh, sub {return;}] or die;
150
151 open $fh, "<", \<<'EOC';
152 BEGIN {prepend_block_counting_filter};
153 pas("SSS make s fast SSS");
154 EOC
155
156 do [$fh, sub {s/s/ss/gs; s/([\nS])/$1$1$1/gs; return;}] or die;