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
CommitLineData
bde61959
NC
1#!./perl -w
2
3# Tests for the source filters in coderef-in-@INC
4
5BEGIN {
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}
14use strict;
5675696b 15use Filter::Util::Call;
bde61959 16
937b367d 17plan(tests => 108);
bde61959
NC
18
19unshift @INC, sub {
20 no warnings 'uninitialized';
21 ref $_[1] eq 'ARRAY' ? @{$_[1]} : $_[1];
22};
23
24my $fh;
25
26open $fh, "<", \'pass("Can return file handles from \@INC");';
5675696b 27do $fh or die;
bde61959
NC
28
29my @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 );
34my @lines = @origlines;
35sub generator {
36 $_ = shift @lines;
37 # Return of 0 marks EOF
38 return defined $_ ? 1 : 0;
39};
40
5675696b 41do \&generator or die;
bde61959
NC
42
43@lines = @origlines;
44# Check that the array dereferencing works ready for the more complex tests:
5675696b 45do [\&generator] or die;
bde61959
NC
46
47do [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",
5675696b 54 ]] or die;
bde61959
NC
55
56
57open $fh, "<", \'fail("File handles and filters work from \@INC");';
58
bccf3f3d 59do [$fh, sub {s/fail/pass/; return;}] or die;
bde61959
NC
60
61open $fh, "<", \'fail("File handles and filters with state work from \@INC");';
62
bccf3f3d 63do [$fh, sub {s/$_[1]/pass/; return;}, 'fail'] or die;
5675696b
NC
64
65print "# 2 tests with pipes from subprocesses.\n";
66
67open $fh, 'echo pass|' or die $!;
68
69do $fh or die;
70
71open $fh, 'echo fail|' or die $!;
72
bccf3f3d 73do [$fh, sub {s/$_[1]/pass/; return;}, 'fail'] or die;
5675696b
NC
74
75sub 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
83open $fh, "<", \<<'EOC';
84BEGIN {rot13_filter};
85cnff("This will rot13'ed prepend");
86EOC
87
88do $fh or die;
89
90open $fh, "<", \<<'EOC';
91ORTVA {ebg13_svygre};
92pass("This will rot13'ed twice");
93EOC
94
bccf3f3d 95do [$fh, sub {tr/A-Za-z/N-ZA-Mn-za-m/; return;}] or die;
5675696b
NC
96
97my $count = 32;
98sub 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();
5675696b
NC
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
115open $fh, "<", \<<'EOC';
116ORTVA {cercraq_ebg13_svygre};
117pass("This will rot13'ed twice");
118EOC
119
bccf3f3d 120do [$fh, sub {tr/A-Za-z/N-ZA-Mn-za-m/; return;}] or die;
937b367d
NC
121
122# This generates a heck of a lot of oks, but I think it's necessary.
123my $amount = 1;
124sub 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
143open $fh, "<", \<<'EOC';
144BEGIN {prepend_block_counting_filter};
145pass("one by one");
146pass("and again");
147EOC
148
149do [$fh, sub {return;}] or die;
150
151open $fh, "<", \<<'EOC';
152BEGIN {prepend_block_counting_filter};
153pas("SSS make s fast SSS");
154EOC
155
156do [$fh, sub {s/s/ss/gs; s/([\nS])/$1$1$1/gs; return;}] or die;