xref: /openbsd-src/gnu/usr.bin/perl/cpan/Test-Harness/t/source_handler.t (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1#!/usr/bin/perl -w
2
3BEGIN {
4    unshift @INC, 't/lib';
5}
6
7use strict;
8
9use Test::More tests => 79;
10
11use IO::File;
12use IO::Handle;
13use File::Spec;
14
15use TAP::Parser::Source;
16use TAP::Parser::SourceHandler;
17
18my $IS_WIN32 = ( $^O =~ /^(MS)?Win32$/ );
19my $HAS_SH   = -x '/bin/sh';
20my $HAS_ECHO = -x '/bin/echo';
21
22my $dir = File::Spec->catdir(
23    't',
24    'source_tests'
25);
26
27my $perl = $^X;
28
29my %file = map { $_ => File::Spec->catfile( $dir, $_ ) }
30  qw( source source.1 source.bat source.pl source.sh source_args.sh source.t
31  source.tap );
32
33# Abstract base class tests
34{
35    my $class  = 'TAP::Parser::SourceHandler';
36    my $source = TAP::Parser::Source->new;
37    my $error;
38
39    can_ok $class, 'can_handle';
40    eval { $class->can_handle($source) };
41    $error = $@;
42    like $error, qr/^Abstract method 'can_handle'/,
43      '... with an appropriate error message';
44
45    can_ok $class, 'make_iterator';
46    eval { $class->make_iterator($source) };
47    $error = $@;
48    like $error, qr/^Abstract method 'make_iterator'/,
49      '... with an appropriate error message';
50}
51
52# Executable source tests
53{
54    my $class = 'TAP::Parser::SourceHandler::Executable';
55    my $tests = {
56        default_vote => 0,
57        can_handle   => [
58            {   name => '.sh',
59                meta => {
60                    is_file => 1,
61                    file    => { lc_ext => '.sh' }
62                },
63                vote => 0,
64            },
65            {   name => '.bat',
66                meta => {
67                    is_file => 1,
68                    file    => { lc_ext => '.bat' }
69                },
70                vote => 0.8,
71            },
72            {   name => 'executable bit',
73                meta => {
74                    is_file => 1,
75                    file    => { lc_ext => '', execute => 1 }
76                },
77                vote => 0.25,
78            },
79            {   name => 'exec hash',
80                raw  => { exec => 'foo' },
81                meta => { is_hash => 1 },
82                vote => 0.9,
83            },
84        ],
85        make_iterator => [
86            {   name => "valid executable",
87                raw  => [
88                    $perl, ( $ENV{PERL_CORE} ? '-I../../lib' : () ),
89                    '-It/lib', '-T', $file{source}
90                ],
91                iclass        => 'TAP::Parser::Iterator::Process',
92                output        => [ '1..1', 'ok 1 - source' ],
93                assemble_meta => 1,
94            },
95            {   name  => "invalid source->raw",
96                raw   => "$perl -It/lib $file{source}",
97                error => qr/^No command found/,
98            },
99            {   name  => "non-existent source->raw",
100                raw   => [],
101                error => qr/^No command found/,
102            },
103            {   name        => $file{'source.sh'},
104                raw         => \$file{'source.sh'},
105                skip        => $HAS_SH && $HAS_ECHO ? 0 : 1,
106                skip_reason => 'no /bin/sh, /bin/echo',
107                iclass      => 'TAP::Parser::Iterator::Process',
108                output        => [ '1..1', 'ok 1 - source.sh' ],
109                assemble_meta => 1,
110            },
111            {   name        => $file{'source_args.sh'},
112                raw         => { exec => [ $file{'source_args.sh'} ] },
113                test_args   => ['foo'],
114                skip        => $HAS_SH && $HAS_ECHO ? 0 : 1,
115                skip_reason => 'no /bin/sh, /bin/echo',
116                iclass      => 'TAP::Parser::Iterator::Process',
117                output        => [ '1..1', 'ok 1 - source_args.sh foo' ],
118                assemble_meta => 1,
119            },
120            {   name        => $file{'source.bat'},
121                raw         => \$file{'source.bat'},
122                skip        => $IS_WIN32 ? 0 : 1,
123                skip_reason => 'not running Win32',
124                iclass      => 'TAP::Parser::Iterator::Process',
125                output        => [ '1..1', 'ok 1 - source.bat' ],
126                assemble_meta => 1,
127            },
128        ],
129    };
130
131    test_handler( $class, $tests );
132}
133
134# Perl source tests
135{
136    my $class = 'TAP::Parser::SourceHandler::Perl';
137    my $tests = {
138        default_vote => 0,
139        can_handle   => [
140            {   name => '.t',
141                meta => {
142                    is_file => 1,
143                    file    => { lc_ext => '.t', dir => '' }
144                },
145                vote => 0.8,
146            },
147            {   name => '.pl',
148                meta => {
149                    is_file => 1,
150                    file    => { lc_ext => '.pl', dir => '' }
151                },
152                vote => 0.9,
153            },
154            {   name => 't/.../file',
155                meta => {
156                    is_file => 1,
157                    file    => { lc_ext => '', dir => 't' }
158                },
159                vote => 0.75,
160            },
161            {   name => '#!...perl',
162                meta => {
163                    is_file => 1,
164                    file    => {
165                        lc_ext => '', dir => '', shebang => '#!/usr/bin/perl'
166                    }
167                },
168                vote => 0.9,
169            },
170            {   name => 'file default',
171                meta => {
172                    is_file => 1,
173                    file    => { lc_ext => '', dir => '' }
174                },
175                vote => 0.25,
176            },
177        ],
178        make_iterator => [
179            {   name          => $file{source},
180                raw           => \$file{source},
181                iclass        => 'TAP::Parser::Iterator::Process',
182                output        => [ '1..1', 'ok 1 - source' ],
183                assemble_meta => 1,
184            },
185        ],
186    };
187
188    test_handler( $class, $tests );
189
190    # internals tests!
191    {
192        my $source = TAP::Parser::Source->new->raw( \$file{source} );
193        $source->assemble_meta;
194        my $iterator = $class->make_iterator($source);
195        my @command  = @{ $iterator->{command} };
196        ok( grep( $_ =~ /^['"]?-T['"]?$/, @command ),
197            '... and it should find the taint switch'
198        );
199    }
200}
201
202# Raw TAP source tests
203{
204    my $class = 'TAP::Parser::SourceHandler::RawTAP';
205    my $tests = {
206        default_vote => 0,
207        can_handle   => [
208            {   name => 'file',
209                meta => { is_file => 1 },
210                raw  => \'',
211                vote => 0,
212            },
213            {   name          => 'scalar w/newlines',
214                raw           => \"hello\nworld\n",
215                vote          => 0.3,
216                assemble_meta => 1,
217            },
218            {   name          => '1..10',
219                raw           => \"1..10\n",
220                vote          => 0.9,
221                assemble_meta => 1,
222            },
223            {   name          => 'array',
224                raw           => [ '1..1', 'ok 1' ],
225                vote          => 0.5,
226                assemble_meta => 1,
227            },
228        ],
229        make_iterator => [
230            {   name          => 'valid scalar',
231                raw           => \"1..1\nok 1 - raw\n",
232                iclass        => 'TAP::Parser::Iterator::Array',
233                output        => [ '1..1', 'ok 1 - raw' ],
234                assemble_meta => 1,
235            },
236            {   name          => 'valid array',
237                raw           => [ '1..1', 'ok 1 - raw' ],
238                iclass        => 'TAP::Parser::Iterator::Array',
239                output        => [ '1..1', 'ok 1 - raw' ],
240                assemble_meta => 1,
241            },
242        ],
243    };
244
245    test_handler( $class, $tests );
246}
247
248# Text file TAP source tests
249{
250    my $class = 'TAP::Parser::SourceHandler::File';
251    my $tests = {
252        default_vote => 0,
253        can_handle   => [
254            {   name => '.tap',
255                meta => {
256                    is_file => 1,
257                    file    => { lc_ext => '.tap' }
258                },
259                vote => 0.9,
260            },
261            {   name => '.foo with config',
262                meta => {
263                    is_file => 1,
264                    file    => { lc_ext => '.foo' }
265                },
266                config => { File => { extensions => ['.foo'] } },
267                vote   => 0.9,
268            },
269        ],
270        make_iterator => [
271            {   name          => $file{'source.tap'},
272                raw           => \$file{'source.tap'},
273                iclass        => 'TAP::Parser::Iterator::Stream',
274                output        => [ '1..1', 'ok 1 - source.tap' ],
275                assemble_meta => 1,
276            },
277            {   name   => $file{'source.1'},
278                raw    => \$file{'source.1'},
279                config => { File => { extensions => ['.1'] } },
280                iclass => 'TAP::Parser::Iterator::Stream',
281                output        => [ '1..1', 'ok 1 - source.1' ],
282                assemble_meta => 1,
283            },
284        ],
285    };
286
287    test_handler( $class, $tests );
288}
289
290# IO::Handle TAP source tests
291{
292    my $class = 'TAP::Parser::SourceHandler::Handle';
293    my $tests = {
294        default_vote => 0,
295        can_handle   => [
296            {   name => 'glob',
297                meta => { is_glob => 1 },
298                vote => 0.8,
299            },
300            {   name          => 'IO::Handle',
301                raw           => IO::Handle->new,
302                vote          => 0.9,
303                assemble_meta => 1,
304            },
305        ],
306        make_iterator => [
307            {   name          => 'IO::Handle',
308                raw           => IO::File->new( $file{'source.tap'} ),
309                iclass        => 'TAP::Parser::Iterator::Stream',
310                output        => [ '1..1', 'ok 1 - source.tap' ],
311                assemble_meta => 1,
312            },
313        ],
314    };
315
316    test_handler( $class, $tests );
317}
318
319###############################################################################
320# helper sub
321
322sub test_handler {
323    my ( $class, $tests ) = @_;
324    my ($short_class) = ( $class =~ /\:\:(\w+)$/ );
325
326    use_ok $class;
327    can_ok $class, 'can_handle', 'make_iterator';
328
329    {
330        my $default_vote = $tests->{default_vote} || 0;
331        my $source = TAP::Parser::Source->new;
332        is( $class->can_handle($source), $default_vote,
333            '... can_handle default vote'
334        );
335    }
336
337    for my $test ( @{ $tests->{can_handle} } ) {
338        my $source = TAP::Parser::Source->new;
339        $source->raw( $test->{raw} )       if $test->{raw};
340        $source->meta( $test->{meta} )     if $test->{meta};
341        $source->config( $test->{config} ) if $test->{config};
342        $source->assemble_meta             if $test->{assemble_meta};
343        my $vote = $test->{vote} || 0;
344        my $name = $test->{name} || 'unnamed test';
345        $name = "$short_class->can_handle( $name )";
346        is( $class->can_handle($source), $vote, $name );
347    }
348
349    for my $test ( @{ $tests->{make_iterator} } ) {
350        my $name = $test->{name} || 'unnamed test';
351        $name = "$short_class->make_iterator( $name )";
352
353        SKIP:
354        {
355            my $planned = 1;
356            $planned += 1 + scalar @{ $test->{output} } if $test->{output};
357            skip $test->{skip_reason}, $planned if $test->{skip};
358
359            my $source = TAP::Parser::Source->new;
360            $source->raw( $test->{raw} )             if $test->{raw};
361            $source->test_args( $test->{test_args} ) if $test->{test_args};
362            $source->meta( $test->{meta} )           if $test->{meta};
363            $source->config( $test->{config} )       if $test->{config};
364            $source->assemble_meta if $test->{assemble_meta};
365
366            my $iterator = eval { $class->make_iterator($source) };
367            my $e = $@;
368            if ( my $error = $test->{error} ) {
369                $e = '' unless defined $e;
370                like $e, $error, "$name threw expected error";
371                next;
372            }
373            elsif ($e) {
374                fail("$name threw an unexpected error");
375                diag($e);
376                next;
377            }
378
379            isa_ok $iterator, $test->{iclass}, $name;
380            if ( $test->{output} ) {
381                my $i = 1;
382                for my $line ( @{ $test->{output} } ) {
383                    is $iterator->next, $line, "... line $i";
384                    $i++;
385                }
386                ok !$iterator->next, '... and we should have no more results';
387            }
388        }
389    }
390}
391