Blame t/iterators.t

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