Fugu
view release on metacpan or search on metacpan
t/fugu/repl.t view on Meta::CPAN
is( guarded( sub { $repl->read_line } ), 'first', 'line one' );
is( $repl->event, 'line', 'with the event line' );
is( guarded( sub { $repl->read_line } ), 'second', 'line two' );
is( output($out_r), '', 'and the plain mode writes no prompt' );
};
subtest 'the plain mode reads a line that arrives in pieces' => sub {
my ( $repl, $in_w, $out_r ) = repl();
my $pid = fork // die "fork: $!";
if ( $pid == 0 ) {
syswrite $in_w, 'first';
sleep 0.2;
syswrite $in_w, " half\n";
POSIX::_exit(0);
}
is( guarded( sub { $repl->read_line } ),
'first half', 'the pieces join into one line' );
waitpid $pid, 0;
};
subtest 'the plain mode reports eof' => sub {
my ( $repl, $in_w, $out_r ) = repl();
syswrite $in_w, "tail without a newline";
close $in_w;
is( guarded( sub { $repl->read_line } ),
'tail without a newline',
'an end of file still ends the last line' );
is( guarded( sub { $repl->read_line } ),
undef, 'then the input is empty' );
is( $repl->event, 'eof', 'with the event eof' );
};
subtest 'a watched handle that becomes readable ends the read' => sub {
pipe my $watch_r, my $watch_w or die "pipe: $!";
my ( $repl, $in_w, $out_r ) = repl( watch => [$watch_r] );
syswrite $watch_w, 'wake';
is( guarded( sub { $repl->read_line } ),
undef, 'the read ends without a line' );
is( $repl->event, 'watch', 'with the event watch' );
ok( $repl->ready_handle == $watch_r,
'and ready_handle names the handle' );
};
subtest 'a watched handle that closes ends the read' => sub {
pipe my $watch_r, my $watch_w or die "pipe: $!";
my ( $repl, $in_w, $out_r ) = repl( watch => [$watch_r] );
close $watch_w;
is( guarded( sub { $repl->read_line } ),
undef, 'the closed peer ends the read' );
is( $repl->event, 'watch', 'with the event watch' );
ok( $repl->ready_handle == $watch_r,
'and ready_handle names the handle' );
syswrite $in_w, "still alive\n";
is( guarded( sub { $repl->read_line } ),
undef, 'a closed handle stays readable' );
is( $repl->event, 'watch', 'so watch outranks the input' );
};
subtest 'ready_handle answers only after a watch event' => sub {
my ( $repl, $in_w, $out_r ) = repl();
syswrite $in_w, "a line\n";
guarded( sub { $repl->read_line } );
is( $repl->ready_handle, undef, 'a line event names no handle' );
};
subtest 'display_filter keeps the safe bytes' => sub {
is( Fugu::REPL::display_filter("plain text 09AZ~"),
'plain text 09AZ~', 'printable ASCII survives' );
is( Fugu::REPL::display_filter("one\ttab\nand a line feed\n"),
"one\ttab\nand a line feed\n",
'the tab and the line feed survive' );
};
subtest 'display_filter removes DEL and every C1 byte' => sub {
is( Fugu::REPL::display_filter("a\x7Fb"), 'ab', 'DEL disappears' );
is( Fugu::REPL::display_filter( 'a' . join( '', map {chr}
0x80 .. 0x9F ) . 'b' ),
'ab', 'every raw C1 byte disappears' );
is( Fugu::REPL::display_filter("a\xC2\x9Bb"),
'ab', 'a C1 control as a UTF-8 sequence disappears' );
};
subtest 'display_filter keeps a valid UTF-8 sequence whole' => sub {
is( Fugu::REPL::display_filter("h\xC3\xA9llo"),
"h\xC3\xA9llo", 'a two-byte sequence survives' );
is( Fugu::REPL::display_filter("cost \xE2\x82\xAC5"),
"cost \xE2\x82\xAC5", 'a three-byte sequence survives' );
is( Fugu::REPL::display_filter("\xF0\x9F\x90\xA1 fugu"),
"\xF0\x9F\x90\xA1 fugu", 'a four-byte sequence survives' );
};
subtest 'display_filter replaces an invalid byte with one mark' => sub {
is( Fugu::REPL::display_filter("a\xFFb"), 'a?b',
'a stray byte becomes one question mark' );
is( Fugu::REPL::display_filter("tail\xC3"),
'tail?', 'a cut sequence becomes one question mark' );
is( Fugu::REPL::display_filter("a\eb\rc"), 'a?b?c',
'an escape and a carriage return become marks' );
is( Fugu::REPL::display_filter("\xC3\xA9\xA9"),
"\xC3\xA9?", 'a lone continuation byte becomes a mark' );
};
subtest 'show writes the filtered bytes' => sub {
my ( $repl, $in_w, $out_r ) = repl();
is( $repl->show("safe\x1B[31m"), $repl, 'show returns the object' );
is( output($out_r), 'safe?[31m', 'and the output is filtered' );
};
subtest 'confirm answers no by default' => sub {
my ( $repl, $in_w, $out_r ) = repl();
( run in 1.339 second using v1.01-cache-2.11-cpan-302cb4679cc )