|
Packit |
a6a12c |
#!/usr/bin/perl -w
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
use strict;
|
|
Packit |
a6a12c |
use warnings;
|
|
Packit |
a6a12c |
use lib 't/lib';
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
use Test::More tests => 76;
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
use File::Spec;
|
|
Packit |
a6a12c |
use TAP::Parser;
|
|
Packit |
a6a12c |
use TAP::Parser::Iterator::Array;
|
|
Packit |
a6a12c |
use Config;
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
sub array_ref_from {
|
|
Packit |
a6a12c |
my $string = shift;
|
|
Packit |
a6a12c |
my @lines = split /\n/ => $string;
|
|
Packit |
a6a12c |
return \@lines;
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
# we slurp __DATA__ and then reset it so we don't have to duplicate our TAP
|
|
Packit |
a6a12c |
my $offset = tell DATA;
|
|
Packit |
a6a12c |
my $tap = do { local $/; <DATA> };
|
|
Packit |
a6a12c |
seek DATA, $offset, 0;
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
my $did_setup = 0;
|
|
Packit |
a6a12c |
my $did_teardown = 0;
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
my $setup = sub { $did_setup++ };
|
|
Packit |
a6a12c |
my $teardown = sub { $did_teardown++ };
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
package NoForkProcess;
|
|
Packit |
a6a12c |
use base qw( TAP::Parser::Iterator::Process );
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
sub _use_open3 {return}
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
package main;
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
my @schedule = (
|
|
Packit |
a6a12c |
{ name => 'Process',
|
|
Packit |
a6a12c |
subclass => 'TAP::Parser::Iterator::Process',
|
|
Packit |
a6a12c |
source => {
|
|
Packit |
a6a12c |
command => [
|
|
Packit |
a6a12c |
$^X,
|
|
Packit |
a6a12c |
File::Spec->catfile(
|
|
Packit |
a6a12c |
't',
|
|
Packit |
a6a12c |
'sample-tests',
|
|
Packit |
a6a12c |
'out_err_mix'
|
|
Packit |
a6a12c |
)
|
|
Packit |
a6a12c |
],
|
|
Packit |
a6a12c |
merge => 1,
|
|
Packit |
a6a12c |
setup => $setup,
|
|
Packit |
a6a12c |
teardown => $teardown,
|
|
Packit |
a6a12c |
},
|
|
Packit |
a6a12c |
after => sub {
|
|
Packit |
a6a12c |
is $did_setup, 1, "setup called";
|
|
Packit |
a6a12c |
is $did_teardown, 1, "teardown called";
|
|
Packit |
a6a12c |
},
|
|
Packit |
a6a12c |
need_open3 => 15,
|
|
Packit |
a6a12c |
},
|
|
Packit |
a6a12c |
{ name => 'Array',
|
|
Packit |
a6a12c |
subclass => 'TAP::Parser::Iterator::Array',
|
|
Packit |
a6a12c |
source => array_ref_from($tap),
|
|
Packit |
a6a12c |
},
|
|
Packit |
a6a12c |
{ name => 'Stream',
|
|
Packit |
a6a12c |
subclass => 'TAP::Parser::Iterator::Stream',
|
|
Packit |
a6a12c |
source => \*DATA,
|
|
Packit |
a6a12c |
},
|
|
Packit |
a6a12c |
{ name => 'Process (Perl -e)',
|
|
Packit |
a6a12c |
subclass => 'TAP::Parser::Iterator::Process',
|
|
Packit |
a6a12c |
source =>
|
|
Packit |
a6a12c |
{ command => [ $^X, '-e', 'print qq/one\ntwo\n\nthree\n/' ] },
|
|
Packit |
a6a12c |
},
|
|
Packit |
a6a12c |
{ name => 'Process (NoFork)',
|
|
Packit |
a6a12c |
subclass => 'TAP::Parser::Iterator::Process',
|
|
Packit |
a6a12c |
class => 'NoForkProcess',
|
|
Packit |
a6a12c |
source =>
|
|
Packit |
a6a12c |
{ command => [ $^X, '-e', 'print qq/one\ntwo\n\nthree\n/' ] },
|
|
Packit |
a6a12c |
},
|
|
Packit |
a6a12c |
);
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
sub _can_open3 {
|
|
Packit |
a6a12c |
return $Config{d_fork};
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
for my $test (@schedule) {
|
|
Packit |
a6a12c |
SKIP: {
|
|
Packit |
a6a12c |
my $name = $test->{name};
|
|
Packit |
a6a12c |
my $need_open3 = $test->{need_open3};
|
|
Packit |
a6a12c |
skip "No open3", $need_open3 if $need_open3 && !_can_open3();
|
|
Packit |
a6a12c |
my $subclass = $test->{subclass};
|
|
Packit |
a6a12c |
my $source = $test->{source};
|
|
Packit |
a6a12c |
my $class = $test->{class};
|
|
Packit |
a6a12c |
my $iterator
|
|
Packit |
a6a12c |
= $class
|
|
Packit |
a6a12c |
? $class->new($source)
|
|
Packit |
a6a12c |
: make_iterator($source);
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
ok $iterator, "$name: We should be able to create a new iterator";
|
|
Packit |
a6a12c |
isa_ok $iterator, 'TAP::Parser::Iterator',
|
|
Packit |
a6a12c |
'... and the object it returns';
|
|
Packit |
a6a12c |
isa_ok $iterator, $subclass, '... and the object it returns';
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
can_ok $iterator, 'exit';
|
|
Packit |
a6a12c |
ok !defined $iterator->exit,
|
|
Packit |
a6a12c |
"$name: ... and it should be undef before we are done ($subclass)";
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
can_ok $iterator, 'next';
|
|
Packit |
a6a12c |
is $iterator->next, 'one',
|
|
Packit |
a6a12c |
"$name: next() should return the first result";
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
is $iterator->next, 'two',
|
|
Packit |
a6a12c |
"$name: next() should return the second result";
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
is $iterator->next, '',
|
|
Packit |
a6a12c |
"$name: next() should return the third result";
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
is $iterator->next, 'three',
|
|
Packit |
a6a12c |
"$name: next() should return the fourth result";
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
ok !defined $iterator->next,
|
|
Packit |
a6a12c |
"$name: next() should return undef after it is empty";
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
is $iterator->exit, 0,
|
|
Packit |
a6a12c |
"$name: ... and exit should now return 0 ($subclass)";
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
is $iterator->wait, 0,
|
|
Packit |
a6a12c |
"$name: wait should also now return 0 ($subclass)";
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
if ( my $after = $test->{after} ) {
|
|
Packit |
a6a12c |
$after->();
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
{
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
# coverage tests for the ctor
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
my $iterator = make_iterator( IO::Handle->new );
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
isa_ok $iterator, 'TAP::Parser::Iterator::Stream';
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
my @die;
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
eval {
|
|
Packit |
a6a12c |
local $SIG{__DIE__} = sub { push @die, @_ };
|
|
Packit |
a6a12c |
make_iterator( \1 ); # a ref to a scalar
|
|
Packit |
a6a12c |
};
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
is @die, 1, 'coverage of error case';
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
like pop @die, qr/Can't iterate with a SCALAR/,
|
|
Packit |
a6a12c |
'...and we died as expected';
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
{
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
# coverage test for VMS case
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
my $iterator = make_iterator(
|
|
Packit |
a6a12c |
[ 'not ',
|
|
Packit |
a6a12c |
'ok 1 - I hate VMS',
|
|
Packit |
a6a12c |
]
|
|
Packit |
a6a12c |
);
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
is $iterator->next, 'not ok 1 - I hate VMS',
|
|
Packit |
a6a12c |
'coverage of VMS line-splitting case';
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
# coverage test for VMS case - nothing after 'not'
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
$iterator = make_iterator(
|
|
Packit |
a6a12c |
[ 'not ',
|
|
Packit |
a6a12c |
]
|
|
Packit |
a6a12c |
);
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
is $iterator->next, 'not ', '...and we find "not" by itself';
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
SKIP: {
|
|
Packit |
a6a12c |
skip "No open3", 4 unless _can_open3();
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
# coverage testing for TAP::Parser::Iterator::Process ctor
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
my @die;
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
eval {
|
|
Packit |
a6a12c |
local $SIG{__DIE__} = sub { push @die, @_ };
|
|
Packit |
a6a12c |
make_iterator( {} );
|
|
Packit |
a6a12c |
};
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
is @die, 1, 'coverage testing for TPI::Process';
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
like pop @die, qr/Must supply a command to execute/,
|
|
Packit |
a6a12c |
'...and we died as expected';
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
my $parser = make_iterator(
|
|
Packit |
a6a12c |
{ command => [
|
|
Packit |
a6a12c |
$^X,
|
|
Packit |
a6a12c |
File::Spec->catfile( 't', 'sample-tests', 'out_err_mix' )
|
|
Packit |
a6a12c |
],
|
|
Packit |
a6a12c |
merge => 1,
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
);
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
is $parser->{err}, '', 'confirm we set err to empty string';
|
|
Packit |
a6a12c |
is $parser->{sel}, undef, '...and selector to undef';
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
# And then we read from the parser to sidestep the Mac OS / open3
|
|
Packit |
a6a12c |
# bug which frequently throws an error here otherwise.
|
|
Packit |
a6a12c |
$parser->next;
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
sub make_iterator {
|
|
Packit |
a6a12c |
my $thing = shift;
|
|
Packit |
a6a12c |
my $ref = ref $thing;
|
|
Packit |
a6a12c |
if ( $ref eq 'GLOB' || UNIVERSAL::isa( $ref, 'IO::Handle' ) ) {
|
|
Packit |
a6a12c |
return TAP::Parser::Iterator::Stream->new($thing);
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
elsif ( $ref eq 'ARRAY' ) {
|
|
Packit |
a6a12c |
return TAP::Parser::Iterator::Array->new($thing);
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
elsif ( $ref eq 'HASH' ) {
|
|
Packit |
a6a12c |
return TAP::Parser::Iterator::Process->new($thing);
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
else {
|
|
Packit |
a6a12c |
die "Can't iterate with a $ref";
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
}
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
__DATA__
|
|
Packit |
a6a12c |
one
|
|
Packit |
a6a12c |
two
|
|
Packit |
a6a12c |
|
|
Packit |
a6a12c |
three
|