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
|
use v5.14;
use warnings;
package TAP::Parser::Iterator::PherkinStream 0.87;
=head1 NAME
TAP::Parser::Iterator::PherkinStream - Stream with TAP from async BDD process
=head1 VERSION
version 0.87
=cut
use base 'TAP::Parser::Iterator';
use IO::Select;
sub _initialize {
my ($self, $out_fh, $err_fh, $pherkin, $child_pid) = @_;
$self->{pherkin} = $pherkin;
$self->{child_pid} = $child_pid;
$self->{sel} = IO::Select->new($out_fh, $err_fh);
$self->{out_fh} = $out_fh;
$self->{err_fh} = $err_fh;
return $self;
}
sub _finish {
my $self = shift;
$self->{pherkin}->_post_run();
if ($self->{child_pid}) {
waitpid $self->{child_pid}, 0; # reap child process
$self->{wait} = $?;
$self->{exit} = $? >> 8;
}
return $self;
}
sub wait { shift->{wait} }
sub exit { shift->{exit} }
sub _next {
my $self = shift;
my @buf = ();
my $part = '';
return sub {
return shift @buf if @buf;
while (my @ready = $self->{sel}->can_read) {
for my $fh (@ready) {
my $stderr = '';
READ:
{
my $got = sysread $fh, my ($chunk), 2048;
if ($got == 0) {
$self->{sel}->remove($fh);
}
elsif ($fh == $self->{err_fh}) {
$stderr .= $chunk;
my @lines = split(/\n/, $stderr, -1);
$stderr = pop @lines;
for my $line (@lines) {
utf8::decode($line);
print STDERR $line . "\n";
}
goto READ if $got == 2048;
utf8::decode($stderr)
or die 'Subprocess provided non-utf8 data';
print STDERR $stderr . "\n";
}
else {
$part .= $chunk;
push @buf, split(/\n/, $part, -1);
$part = pop @buf;
my $rv = shift @buf;
if (defined $rv) {
utf8::decode($rv)
or die 'Subprocess provided non-utf8 data';
return $rv;
}
}
}
}
}
if ($part) {
$part = '';
return $part;
}
$self->_finish;
return;
};
}
sub next_raw {
my $self = shift;
$self->{_next} ||= $self->_next;
return $self->{_next}->();
}
sub get_select_handles {
my $self = shift;
# return our handle in case it's a socket or pipe (select()-able)
return ( $self->{out_fh}, $self->{err_fh});
}
1;
|