xref: /openbsd-src/gnu/usr.bin/perl/cpan/Test-Harness/t/source_handler.t (revision 5486feefcc8cb79b19e014ab332cc5dfd05b3b33)
1898184e3Ssthen#!/usr/bin/perl -w
2898184e3Ssthen
3898184e3SsthenBEGIN {
4898184e3Ssthen    unshift @INC, 't/lib';
5898184e3Ssthen}
6898184e3Ssthen
7898184e3Ssthenuse strict;
86fb12b70Safresh1use warnings;
9898184e3Ssthen
10*5486feefSafresh1use Test::More tests => 82;
11898184e3Ssthen
126fb12b70Safresh1use Config;
13898184e3Ssthenuse IO::File;
14898184e3Ssthenuse IO::Handle;
15898184e3Ssthenuse File::Spec;
16898184e3Ssthen
17898184e3Ssthenuse TAP::Parser::Source;
18898184e3Ssthenuse TAP::Parser::SourceHandler;
19898184e3Ssthen
20898184e3Ssthenmy $IS_WIN32 = ( $^O =~ /^(MS)?Win32$/ );
21898184e3Ssthenmy $HAS_SH   = -x '/bin/sh';
22898184e3Ssthenmy $HAS_ECHO = -x '/bin/echo';
23898184e3Ssthen
24898184e3Ssthenmy $dir = File::Spec->catdir(
25898184e3Ssthen    't',
26898184e3Ssthen    'source_tests'
27898184e3Ssthen);
28898184e3Ssthen
29898184e3Ssthenmy $perl = $^X;
30898184e3Ssthen
31898184e3Ssthenmy %file = map { $_ => File::Spec->catfile( $dir, $_ ) }
32898184e3Ssthen  qw( source source.1 source.bat source.pl source.sh source_args.sh source.t
33898184e3Ssthen  source.tap );
34898184e3Ssthen
35898184e3Ssthen# Abstract base class tests
36898184e3Ssthen{
37898184e3Ssthen    my $class  = 'TAP::Parser::SourceHandler';
38898184e3Ssthen    my $source = TAP::Parser::Source->new;
39898184e3Ssthen    my $error;
40898184e3Ssthen
41898184e3Ssthen    can_ok $class, 'can_handle';
42898184e3Ssthen    eval { $class->can_handle($source) };
43898184e3Ssthen    $error = $@;
44898184e3Ssthen    like $error, qr/^Abstract method 'can_handle'/,
45898184e3Ssthen      '... with an appropriate error message';
46898184e3Ssthen
47898184e3Ssthen    can_ok $class, 'make_iterator';
48898184e3Ssthen    eval { $class->make_iterator($source) };
49898184e3Ssthen    $error = $@;
50898184e3Ssthen    like $error, qr/^Abstract method 'make_iterator'/,
51898184e3Ssthen      '... with an appropriate error message';
52898184e3Ssthen}
53898184e3Ssthen
54898184e3Ssthen# Executable source tests
55898184e3Ssthen{
56898184e3Ssthen    my $class = 'TAP::Parser::SourceHandler::Executable';
57898184e3Ssthen    my $tests = {
58898184e3Ssthen        default_vote => 0,
59898184e3Ssthen        can_handle   => [
60898184e3Ssthen            {   name => '.sh',
61898184e3Ssthen                meta => {
62898184e3Ssthen                    is_file => 1,
63898184e3Ssthen                    file    => { lc_ext => '.sh' }
64898184e3Ssthen                },
65898184e3Ssthen                vote => 0,
66898184e3Ssthen            },
67898184e3Ssthen            {   name => '.bat',
68898184e3Ssthen                meta => {
69898184e3Ssthen                    is_file => 1,
70898184e3Ssthen                    file    => { lc_ext => '.bat' }
71898184e3Ssthen                },
72898184e3Ssthen                vote => 0.8,
73898184e3Ssthen            },
74898184e3Ssthen            {   name => 'executable bit',
75898184e3Ssthen                meta => {
76898184e3Ssthen                    is_file => 1,
77898184e3Ssthen                    file    => { lc_ext => '', execute => 1 }
78898184e3Ssthen                },
79898184e3Ssthen                vote => 0.25,
80898184e3Ssthen            },
81898184e3Ssthen            {   name => 'exec hash',
82898184e3Ssthen                raw  => { exec => 'foo' },
83898184e3Ssthen                meta => { is_hash => 1 },
84898184e3Ssthen                vote => 0.9,
85898184e3Ssthen            },
86898184e3Ssthen        ],
87898184e3Ssthen        make_iterator => [
88898184e3Ssthen            {   name => "valid executable",
89898184e3Ssthen                raw  => [
90898184e3Ssthen                    $perl, ( $ENV{PERL_CORE} ? '-I../../lib' : () ),
916fb12b70Safresh1                    (map { "-I$_" } split /$Config{path_sep}/, $ENV{PERL5LIB} || ''),
92898184e3Ssthen                    '-It/lib', '-T', $file{source}
93898184e3Ssthen                ],
94898184e3Ssthen                iclass        => 'TAP::Parser::Iterator::Process',
95898184e3Ssthen                output        => [ '1..1', 'ok 1 - source' ],
96898184e3Ssthen                assemble_meta => 1,
97898184e3Ssthen            },
98898184e3Ssthen            {   name  => "invalid source->raw",
99898184e3Ssthen                raw   => "$perl -It/lib $file{source}",
100898184e3Ssthen                error => qr/^No command found/,
101898184e3Ssthen            },
102898184e3Ssthen            {   name  => "non-existent source->raw",
103898184e3Ssthen                raw   => [],
104898184e3Ssthen                error => qr/^No command found/,
105898184e3Ssthen            },
106898184e3Ssthen            {   name        => $file{'source.sh'},
107898184e3Ssthen                raw         => \$file{'source.sh'},
108898184e3Ssthen                skip        => $HAS_SH && $HAS_ECHO ? 0 : 1,
109898184e3Ssthen                skip_reason => 'no /bin/sh, /bin/echo',
110898184e3Ssthen                iclass      => 'TAP::Parser::Iterator::Process',
111898184e3Ssthen                output        => [ '1..1', 'ok 1 - source.sh' ],
112898184e3Ssthen                assemble_meta => 1,
113898184e3Ssthen            },
114898184e3Ssthen            {   name        => $file{'source_args.sh'},
115898184e3Ssthen                raw         => { exec => [ $file{'source_args.sh'} ] },
116898184e3Ssthen                test_args   => ['foo'],
117898184e3Ssthen                skip        => $HAS_SH && $HAS_ECHO ? 0 : 1,
118898184e3Ssthen                skip_reason => 'no /bin/sh, /bin/echo',
119898184e3Ssthen                iclass      => 'TAP::Parser::Iterator::Process',
120898184e3Ssthen                output        => [ '1..1', 'ok 1 - source_args.sh foo' ],
121898184e3Ssthen                assemble_meta => 1,
122898184e3Ssthen            },
123898184e3Ssthen            {   name        => $file{'source.bat'},
124898184e3Ssthen                raw         => \$file{'source.bat'},
125898184e3Ssthen                skip        => $IS_WIN32 ? 0 : 1,
126898184e3Ssthen                skip_reason => 'not running Win32',
127898184e3Ssthen                iclass      => 'TAP::Parser::Iterator::Process',
128898184e3Ssthen                output        => [ '1..1', 'ok 1 - source.bat' ],
129898184e3Ssthen                assemble_meta => 1,
130898184e3Ssthen            },
131898184e3Ssthen        ],
132898184e3Ssthen    };
133898184e3Ssthen
134898184e3Ssthen    test_handler( $class, $tests );
135898184e3Ssthen}
136898184e3Ssthen
137898184e3Ssthen# Perl source tests
138898184e3Ssthen{
139898184e3Ssthen    my $class = 'TAP::Parser::SourceHandler::Perl';
140898184e3Ssthen    my $tests = {
141898184e3Ssthen        default_vote => 0,
142898184e3Ssthen        can_handle   => [
143898184e3Ssthen            {   name => '.t',
144898184e3Ssthen                meta => {
145898184e3Ssthen                    is_file => 1,
146898184e3Ssthen                    file    => { lc_ext => '.t', dir => '' }
147898184e3Ssthen                },
148898184e3Ssthen                vote => 0.8,
149898184e3Ssthen            },
150*5486feefSafresh1            {   name => '.t (no shebang)',
151*5486feefSafresh1                meta => {
152*5486feefSafresh1                    is_file => 1,
153*5486feefSafresh1                    file    => {
154*5486feefSafresh1                        lc_ext => '.t', dir => '', shebang => 'use strict;'
155*5486feefSafresh1                    }
156*5486feefSafresh1                },
157*5486feefSafresh1                vote => 0.8,
158*5486feefSafresh1            },
159898184e3Ssthen            {   name => '.pl',
160898184e3Ssthen                meta => {
161898184e3Ssthen                    is_file => 1,
162898184e3Ssthen                    file    => { lc_ext => '.pl', dir => '' }
163898184e3Ssthen                },
164898184e3Ssthen                vote => 0.9,
165898184e3Ssthen            },
166898184e3Ssthen            {   name => 't/.../file',
167898184e3Ssthen                meta => {
168898184e3Ssthen                    is_file => 1,
169898184e3Ssthen                    file    => { lc_ext => '', dir => 't' }
170898184e3Ssthen                },
171898184e3Ssthen                vote => 0.75,
172898184e3Ssthen            },
173898184e3Ssthen            {   name => '#!...perl',
174898184e3Ssthen                meta => {
175898184e3Ssthen                    is_file => 1,
176898184e3Ssthen                    file    => {
177898184e3Ssthen                        lc_ext => '', dir => '', shebang => '#!/usr/bin/perl'
178898184e3Ssthen                    }
179898184e3Ssthen                },
180898184e3Ssthen                vote => 0.9,
181898184e3Ssthen            },
182*5486feefSafresh1            {   name => '#!...sh',
183*5486feefSafresh1                meta => {
184*5486feefSafresh1                    is_file => 1,
185*5486feefSafresh1                    file    => {
186*5486feefSafresh1                        lc_ext => '', dir => '', shebang => '#!/bin/sh'
187*5486feefSafresh1                    }
188*5486feefSafresh1                },
189*5486feefSafresh1                vote => 0.3,
190*5486feefSafresh1            },
191*5486feefSafresh1            {   name => 'use strict;  # first line not shebang',
192*5486feefSafresh1                meta => {
193*5486feefSafresh1                    is_file => 1,
194*5486feefSafresh1                    file    => {
195*5486feefSafresh1                        lc_ext => '', dir => '', shebang => 'use strict;'
196*5486feefSafresh1                    }
197*5486feefSafresh1                },
198*5486feefSafresh1                vote => 0.25,
199*5486feefSafresh1            },
200898184e3Ssthen            {   name => 'file default',
201898184e3Ssthen                meta => {
202898184e3Ssthen                    is_file => 1,
203898184e3Ssthen                    file    => { lc_ext => '', dir => '' }
204898184e3Ssthen                },
205898184e3Ssthen                vote => 0.25,
206898184e3Ssthen            },
207898184e3Ssthen        ],
208898184e3Ssthen        make_iterator => [
209898184e3Ssthen            {   name          => $file{source},
210898184e3Ssthen                raw           => \$file{source},
211898184e3Ssthen                iclass        => 'TAP::Parser::Iterator::Process',
212898184e3Ssthen                output        => [ '1..1', 'ok 1 - source' ],
213898184e3Ssthen                assemble_meta => 1,
214898184e3Ssthen            },
215898184e3Ssthen        ],
216898184e3Ssthen    };
217898184e3Ssthen
218898184e3Ssthen    test_handler( $class, $tests );
219898184e3Ssthen
220898184e3Ssthen    # internals tests!
221898184e3Ssthen    {
222898184e3Ssthen        my $source = TAP::Parser::Source->new->raw( \$file{source} );
223898184e3Ssthen        $source->assemble_meta;
224898184e3Ssthen        my $iterator = $class->make_iterator($source);
225898184e3Ssthen        my @command  = @{ $iterator->{command} };
226898184e3Ssthen        ok( grep( $_ =~ /^['"]?-T['"]?$/, @command ),
227898184e3Ssthen            '... and it should find the taint switch'
228898184e3Ssthen        );
229898184e3Ssthen    }
230898184e3Ssthen}
231898184e3Ssthen
232898184e3Ssthen# Raw TAP source tests
233898184e3Ssthen{
234898184e3Ssthen    my $class = 'TAP::Parser::SourceHandler::RawTAP';
235898184e3Ssthen    my $tests = {
236898184e3Ssthen        default_vote => 0,
237898184e3Ssthen        can_handle   => [
238898184e3Ssthen            {   name => 'file',
239898184e3Ssthen                meta => { is_file => 1 },
240898184e3Ssthen                raw  => \'',
241898184e3Ssthen                vote => 0,
242898184e3Ssthen            },
243898184e3Ssthen            {   name          => 'scalar w/newlines',
244898184e3Ssthen                raw           => \"hello\nworld\n",
245898184e3Ssthen                vote          => 0.3,
246898184e3Ssthen                assemble_meta => 1,
247898184e3Ssthen            },
248898184e3Ssthen            {   name          => '1..10',
249898184e3Ssthen                raw           => \"1..10\n",
250898184e3Ssthen                vote          => 0.9,
251898184e3Ssthen                assemble_meta => 1,
252898184e3Ssthen            },
253898184e3Ssthen            {   name          => 'array',
254898184e3Ssthen                raw           => [ '1..1', 'ok 1' ],
255898184e3Ssthen                vote          => 0.5,
256898184e3Ssthen                assemble_meta => 1,
257898184e3Ssthen            },
258898184e3Ssthen        ],
259898184e3Ssthen        make_iterator => [
260898184e3Ssthen            {   name          => 'valid scalar',
261898184e3Ssthen                raw           => \"1..1\nok 1 - raw\n",
262898184e3Ssthen                iclass        => 'TAP::Parser::Iterator::Array',
263898184e3Ssthen                output        => [ '1..1', 'ok 1 - raw' ],
264898184e3Ssthen                assemble_meta => 1,
265898184e3Ssthen            },
266898184e3Ssthen            {   name          => 'valid array',
267898184e3Ssthen                raw           => [ '1..1', 'ok 1 - raw' ],
268898184e3Ssthen                iclass        => 'TAP::Parser::Iterator::Array',
269898184e3Ssthen                output        => [ '1..1', 'ok 1 - raw' ],
270898184e3Ssthen                assemble_meta => 1,
271898184e3Ssthen            },
272898184e3Ssthen        ],
273898184e3Ssthen    };
274898184e3Ssthen
275898184e3Ssthen    test_handler( $class, $tests );
276898184e3Ssthen}
277898184e3Ssthen
278898184e3Ssthen# Text file TAP source tests
279898184e3Ssthen{
280898184e3Ssthen    my $class = 'TAP::Parser::SourceHandler::File';
281898184e3Ssthen    my $tests = {
282898184e3Ssthen        default_vote => 0,
283898184e3Ssthen        can_handle   => [
284898184e3Ssthen            {   name => '.tap',
285898184e3Ssthen                meta => {
286898184e3Ssthen                    is_file => 1,
287898184e3Ssthen                    file    => { lc_ext => '.tap' }
288898184e3Ssthen                },
289898184e3Ssthen                vote => 0.9,
290898184e3Ssthen            },
291898184e3Ssthen            {   name => '.foo with config',
292898184e3Ssthen                meta => {
293898184e3Ssthen                    is_file => 1,
294898184e3Ssthen                    file    => { lc_ext => '.foo' }
295898184e3Ssthen                },
296898184e3Ssthen                config => { File => { extensions => ['.foo'] } },
297898184e3Ssthen                vote   => 0.9,
298898184e3Ssthen            },
299898184e3Ssthen        ],
300898184e3Ssthen        make_iterator => [
301898184e3Ssthen            {   name          => $file{'source.tap'},
302898184e3Ssthen                raw           => \$file{'source.tap'},
303898184e3Ssthen                iclass        => 'TAP::Parser::Iterator::Stream',
304898184e3Ssthen                output        => [ '1..1', 'ok 1 - source.tap' ],
305898184e3Ssthen                assemble_meta => 1,
306898184e3Ssthen            },
307898184e3Ssthen            {   name   => $file{'source.1'},
308898184e3Ssthen                raw    => \$file{'source.1'},
309898184e3Ssthen                config => { File => { extensions => ['.1'] } },
310898184e3Ssthen                iclass => 'TAP::Parser::Iterator::Stream',
311898184e3Ssthen                output        => [ '1..1', 'ok 1 - source.1' ],
312898184e3Ssthen                assemble_meta => 1,
313898184e3Ssthen            },
314898184e3Ssthen        ],
315898184e3Ssthen    };
316898184e3Ssthen
317898184e3Ssthen    test_handler( $class, $tests );
318898184e3Ssthen}
319898184e3Ssthen
320898184e3Ssthen# IO::Handle TAP source tests
321898184e3Ssthen{
322898184e3Ssthen    my $class = 'TAP::Parser::SourceHandler::Handle';
323898184e3Ssthen    my $tests = {
324898184e3Ssthen        default_vote => 0,
325898184e3Ssthen        can_handle   => [
326898184e3Ssthen            {   name => 'glob',
327898184e3Ssthen                meta => { is_glob => 1 },
328898184e3Ssthen                vote => 0.8,
329898184e3Ssthen            },
330898184e3Ssthen            {   name          => 'IO::Handle',
331898184e3Ssthen                raw           => IO::Handle->new,
332898184e3Ssthen                vote          => 0.9,
333898184e3Ssthen                assemble_meta => 1,
334898184e3Ssthen            },
335898184e3Ssthen        ],
336898184e3Ssthen        make_iterator => [
337898184e3Ssthen            {   name          => 'IO::Handle',
338898184e3Ssthen                raw           => IO::File->new( $file{'source.tap'} ),
339898184e3Ssthen                iclass        => 'TAP::Parser::Iterator::Stream',
340898184e3Ssthen                output        => [ '1..1', 'ok 1 - source.tap' ],
341898184e3Ssthen                assemble_meta => 1,
342898184e3Ssthen            },
343898184e3Ssthen        ],
344898184e3Ssthen    };
345898184e3Ssthen
346898184e3Ssthen    test_handler( $class, $tests );
347898184e3Ssthen}
348898184e3Ssthen
349898184e3Ssthen###############################################################################
350898184e3Ssthen# helper sub
351898184e3Ssthen
352898184e3Ssthensub test_handler {
353898184e3Ssthen    my ( $class, $tests ) = @_;
354898184e3Ssthen    my ($short_class) = ( $class =~ /\:\:(\w+)$/ );
355898184e3Ssthen
356898184e3Ssthen    use_ok $class;
357898184e3Ssthen    can_ok $class, 'can_handle', 'make_iterator';
358898184e3Ssthen
359898184e3Ssthen    {
360898184e3Ssthen        my $default_vote = $tests->{default_vote} || 0;
361898184e3Ssthen        my $source = TAP::Parser::Source->new;
362898184e3Ssthen        is( $class->can_handle($source), $default_vote,
363898184e3Ssthen            '... can_handle default vote'
364898184e3Ssthen        );
365898184e3Ssthen    }
366898184e3Ssthen
367898184e3Ssthen    for my $test ( @{ $tests->{can_handle} } ) {
368898184e3Ssthen        my $source = TAP::Parser::Source->new;
369898184e3Ssthen        $source->raw( $test->{raw} )       if $test->{raw};
370898184e3Ssthen        $source->meta( $test->{meta} )     if $test->{meta};
371898184e3Ssthen        $source->config( $test->{config} ) if $test->{config};
372898184e3Ssthen        $source->assemble_meta             if $test->{assemble_meta};
373898184e3Ssthen        my $vote = $test->{vote} || 0;
374898184e3Ssthen        my $name = $test->{name} || 'unnamed test';
375898184e3Ssthen        $name = "$short_class->can_handle( $name )";
376898184e3Ssthen        is( $class->can_handle($source), $vote, $name );
377898184e3Ssthen    }
378898184e3Ssthen
379898184e3Ssthen    for my $test ( @{ $tests->{make_iterator} } ) {
380898184e3Ssthen        my $name = $test->{name} || 'unnamed test';
381898184e3Ssthen        $name = "$short_class->make_iterator( $name )";
382898184e3Ssthen
383898184e3Ssthen        SKIP:
384898184e3Ssthen        {
385898184e3Ssthen            my $planned = 1;
386898184e3Ssthen            $planned += 1 + scalar @{ $test->{output} } if $test->{output};
387898184e3Ssthen            skip $test->{skip_reason}, $planned if $test->{skip};
388898184e3Ssthen
389898184e3Ssthen            my $source = TAP::Parser::Source->new;
390898184e3Ssthen            $source->raw( $test->{raw} )             if $test->{raw};
391898184e3Ssthen            $source->test_args( $test->{test_args} ) if $test->{test_args};
392898184e3Ssthen            $source->meta( $test->{meta} )           if $test->{meta};
393898184e3Ssthen            $source->config( $test->{config} )       if $test->{config};
394898184e3Ssthen            $source->assemble_meta if $test->{assemble_meta};
395898184e3Ssthen
396898184e3Ssthen            my $iterator = eval { $class->make_iterator($source) };
397898184e3Ssthen            my $e = $@;
398898184e3Ssthen            if ( my $error = $test->{error} ) {
399898184e3Ssthen                $e = '' unless defined $e;
400898184e3Ssthen                like $e, $error, "$name threw expected error";
401898184e3Ssthen                next;
402898184e3Ssthen            }
403898184e3Ssthen            elsif ($e) {
404898184e3Ssthen                fail("$name threw an unexpected error");
405898184e3Ssthen                diag($e);
406898184e3Ssthen                next;
407898184e3Ssthen            }
408898184e3Ssthen
409898184e3Ssthen            isa_ok $iterator, $test->{iclass}, $name;
410898184e3Ssthen            if ( $test->{output} ) {
411898184e3Ssthen                my $i = 1;
412898184e3Ssthen                for my $line ( @{ $test->{output} } ) {
413898184e3Ssthen                    is $iterator->next, $line, "... line $i";
414898184e3Ssthen                    $i++;
415898184e3Ssthen                }
416898184e3Ssthen                ok !$iterator->next, '... and we should have no more results';
417898184e3Ssthen            }
418898184e3Ssthen        }
419898184e3Ssthen    }
420898184e3Ssthen}
421