File Coverage

blib/lib/TAP/Harness.pm
Criterion Covered Total %
statement 239 275 86.9
branch 77 104 74.0
condition 17 23 73.9
subroutine 34 35 97.1
pod 6 6 100.0
total 373 443 84.2


line stmt bran cond sub pod time code
1             package TAP::Harness;
2              
3 19     19   86748 use strict;
  19         27  
  19         487  
4 19     19   69 use warnings;
  19         22  
  19         466  
5 19     19   78 use Carp;
  19         30  
  19         1204  
6              
7 19     19   76 use File::Spec;
  19         22  
  19         488  
8 19     19   90 use File::Path;
  19         22  
  19         925  
9 19     19   6797 use IO::Handle;
  19         61737  
  19         790  
10              
11 19     19   87 use base 'TAP::Base';
  19         21  
  19         7446  
12              
13             =head1 NAME
14              
15             TAP::Harness - Run test scripts with statistics
16              
17             =head1 VERSION
18              
19             Version 3.38
20              
21             =cut
22              
23             our $VERSION = '3.38';
24              
25             $ENV{HARNESS_ACTIVE} = 1;
26             $ENV{HARNESS_VERSION} = $VERSION;
27              
28             END {
29              
30             # For VMS.
31 19     19   2358 delete $ENV{HARNESS_ACTIVE};
32 19         97 delete $ENV{HARNESS_VERSION};
33             }
34              
35             =head1 DESCRIPTION
36              
37             This is a simple test harness which allows tests to be run and results
38             automatically aggregated and output to STDOUT.
39              
40             =head1 SYNOPSIS
41              
42             use TAP::Harness;
43             my $harness = TAP::Harness->new( \%args );
44             $harness->runtests(@tests);
45              
46             =cut
47              
48             my %VALIDATION_FOR;
49             my @FORMATTER_ARGS;
50              
51             sub _error {
52 153     153   137 my $self = shift;
53 153 50       491 return $self->{error} unless @_;
54 0         0 $self->{error} = shift;
55             }
56              
57             BEGIN {
58              
59 19     19   59 @FORMATTER_ARGS = qw(
60             directives verbosity timer failures comments errors stdout color
61             show_count normalize
62             );
63              
64             %VALIDATION_FOR = (
65             lib => sub {
66 45         67 my ( $self, $libs ) = @_;
67 45 100       170 $libs = [$libs] unless 'ARRAY' eq ref $libs;
68              
69 45         108 return [ map {"-I$_"} @$libs ];
  9         25  
70             },
71 44         64 switches => sub { shift; shift },
  44         52  
72 7         8 exec => sub { shift; shift },
  7         9  
73 1         2 merge => sub { shift; shift },
  1         1  
74 1         1 aggregator_class => sub { shift; shift },
  1         2  
75 6         8 formatter_class => sub { shift; shift },
  6         7  
76 1         1 multiplexer_class => sub { shift; shift },
  1         2  
77 1         2 parser_class => sub { shift; shift },
  1         3  
78 1         1 scheduler_class => sub { shift; shift },
  1         3  
79 0         0 formatter => sub { shift; shift },
  0         0  
80 2         3 jobs => sub { shift; shift },
  2         3  
81 2         4 test_args => sub { shift; shift },
  2         5  
82 40         48 ignore_exit => sub { shift; shift },
  40         57  
83 0         0 rules => sub { shift; shift },
  0         0  
84 0         0 rulesfile => sub { shift; shift },
  0         0  
85 2         6 sources => sub { shift; shift },
  2         5  
86 0         0 version => sub { shift; shift },
  0         0  
87 0         0 trap => sub { shift; shift },
  0         0  
88 19         529 );
89              
90 19         185 for my $method ( sort keys %VALIDATION_FOR ) {
91 19     19   95 no strict 'refs';
  19         25  
  19         3165  
92 342 100 100     904 if ( $method eq 'lib' || $method eq 'switches' ) {
93 38         95 *{$method} = sub {
94 527     527   1314 my $self = shift;
95 527 100       736 unless (@_) {
96 436   100     806 $self->{$method} ||= [];
97             return wantarray
98 216         437 ? @{ $self->{$method} }
99 436 100       1064 : $self->{$method};
100             }
101 91 100       193 $self->_croak("Too many arguments to method '$method'")
102             if @_ > 1;
103 90         87 my $args = shift;
104 90 100       180 $args = [$args] unless ref $args;
105 90         137 $self->{$method} = $args;
106 90         107 return $self;
107 38         113 };
108             }
109             else {
110 304         744 *{$method} = sub {
111 3091     3091   2277 my $self = shift;
112 3091 100       9070 return $self->{$method} unless @_;
113 663         1781 $self->{$method} = shift;
114 304         490 };
115             }
116             }
117              
118 19         45 for my $method (@FORMATTER_ARGS) {
119 19     19   75 no strict 'refs';
  19         17  
  19         1096  
120 190         32679 *{$method} = sub {
121 11     11   18 my $self = shift;
122 11         16 return $self->formatter->$method(@_);
123 190         399 };
124             }
125             }
126              
127             ##############################################################################
128              
129             =head1 METHODS
130              
131             =head2 Class Methods
132              
133             =head3 C
134              
135             my %args = (
136             verbosity => 1,
137             lib => [ 'lib', 'blib/lib', 'blib/arch' ],
138             )
139             my $harness = TAP::Harness->new( \%args );
140              
141             The constructor returns a new C object. It accepts an
142             optional hashref whose allowed keys are:
143              
144             =over 4
145              
146             =item * C
147              
148             Set the verbosity level:
149              
150             1 verbose Print individual test results to STDOUT.
151             0 normal
152             -1 quiet Suppress some test output (mostly failures
153             while tests are running).
154             -2 really quiet Suppress everything but the tests summary.
155             -3 silent Suppress everything.
156              
157             =item * C
158              
159             Append run time for each test to output. Uses L if
160             available.
161              
162             =item * C
163              
164             Show test failures (this is a no-op if C is selected).
165              
166             =item * C
167              
168             Show test comments (this is a no-op if C is selected).
169              
170             =item * C
171              
172             Update the running test count during testing.
173              
174             =item * C
175              
176             Set to a true value to normalize the TAP that is emitted in verbose modes.
177              
178             =item * C
179              
180             Accepts a scalar value or array ref of scalar values indicating which
181             paths to allowed libraries should be included if Perl tests are
182             executed. Naturally, this only makes sense in the context of tests
183             written in Perl.
184              
185             =item * C
186              
187             Accepts a scalar value or array ref of scalar values indicating which
188             switches should be included if Perl tests are executed. Naturally, this
189             only makes sense in the context of tests written in Perl.
190              
191             =item * C
192              
193             A reference to an C<@INC> style array of arguments to be passed to each
194             test program.
195              
196             test_args => ['foo', 'bar'],
197              
198             if you want to pass different arguments to each test then you should
199             pass a hash of arrays, keyed by the alias for each test:
200              
201             test_args => {
202             my_test => ['foo', 'bar'],
203             other_test => ['baz'],
204             }
205              
206             =item * C
207              
208             Attempt to produce color output.
209              
210             =item * C
211              
212             Typically, Perl tests are run through this. However, anything which
213             spits out TAP is fine. You can use this argument to specify the name of
214             the program (and optional switches) to run your tests with:
215              
216             exec => ['/usr/bin/ruby', '-w']
217              
218             You can also pass a subroutine reference in order to determine and
219             return the proper program to run based on a given test script. The
220             subroutine reference should expect the TAP::Harness object itself as the
221             first argument, and the file name as the second argument. It should
222             return an array reference containing the command to be run and including
223             the test file name. It can also simply return C, in which case
224             TAP::Harness will fall back on executing the test script in Perl:
225              
226             exec => sub {
227             my ( $harness, $test_file ) = @_;
228              
229             # Let Perl tests run.
230             return undef if $test_file =~ /[.]t$/;
231             return [ qw( /usr/bin/ruby -w ), $test_file ]
232             if $test_file =~ /[.]rb$/;
233             }
234              
235             If the subroutine returns a scalar with a newline or a filehandle, it
236             will be interpreted as raw TAP or as a TAP stream, respectively.
237              
238             =item * C
239              
240             If C is true the harness will create parsers that merge STDOUT
241             and STDERR together for any processes they start.
242              
243             =item * C
244              
245             I.
246              
247             If set, C must be a hashref containing the names of the
248             Ls to load and/or configure. The values are a
249             hash of configuration that will be accessible to the source handlers via
250             L.
251              
252             For example:
253              
254             sources => {
255             Perl => { exec => '/path/to/custom/perl' },
256             File => { extensions => [ '.tap', '.txt' ] },
257             MyCustom => { some => 'config' },
258             }
259              
260             The C parameter affects how C, C and C parameters
261             are handled.
262              
263             For more details, see the C parameter in L,
264             L, and L.
265              
266             =item * C
267              
268             The name of the class to use to aggregate test results. The default is
269             L.
270              
271             =item * C
272              
273             I.
274              
275             Assume this TAP version for L instead of default TAP
276             version 12.
277              
278             =item * C
279              
280             The name of the class to use to format output. The default is
281             L, or L if the output
282             isn't a TTY.
283              
284             =item * C
285              
286             The name of the class to use to multiplex tests during parallel testing.
287             The default is L.
288              
289             =item * C
290              
291             The name of the class to use to parse TAP. The default is
292             L.
293              
294             =item * C
295              
296             The name of the class to use to schedule test execution. The default is
297             L.
298              
299             =item * C
300              
301             If set C must be an object that is capable of formatting the
302             TAP output. See L for an example.
303              
304             =item * C
305              
306             If parse errors are found in the TAP output, a note of this will be
307             made in the summary report. To see all of the parse errors, set this
308             argument to true:
309              
310             errors => 1
311              
312             =item * C
313              
314             If set to a true value, only test results with directives will be
315             displayed. This overrides other settings such as C or
316             C.
317              
318             =item * C
319              
320             If set to a true value instruct C to ignore exit and wait
321             status from test scripts.
322              
323             =item * C
324              
325             The maximum number of parallel tests to run at any time. Which tests
326             can be run in parallel is controlled by C. The default is to
327             run only one test at a time.
328              
329             =item * C
330              
331             A reference to a hash of rules that control which tests may be executed in
332             parallel. If no rules are declared and L is available,
333             C attempts to load rules from a YAML file specified by the
334             C parameter. If no rules file exists, the default is for all
335             tests to be eligible to be run in parallel.
336              
337             Here some simple examples. For the full details of the data structure
338             and the related glob-style pattern matching, see
339             L.
340              
341             # Run all tests in sequence, except those starting with "p"
342             $harness->rules({
343             par => 't/p*.t'
344             });
345              
346             # Equivalent YAML file
347             ---
348             par: t/p*.t
349              
350             # Run all tests in parallel, except those starting with "p"
351             $harness->rules({
352             seq => [
353             { seq => 't/p*.t' },
354             { par => '**' },
355             ],
356             });
357              
358             # Equivalent YAML file
359             ---
360             seq:
361             - seq: t/p*.t
362             - par: **
363              
364             # Run some startup tests in sequence, then some parallel tests than some
365             # teardown tests in sequence.
366             $harness->rules({
367             seq => [
368             { seq => 't/startup/*.t' },
369             { par => ['t/a/*.t','t/b/*.t','t/c/*.t'], }
370             { seq => 't/shutdown/*.t' },
371             ],
372              
373             });
374              
375             # Equivalent YAML file
376             ---
377             seq:
378             - seq: t/startup/*.t
379             - par:
380             - t/a/*.t
381             - t/b/*.t
382             - t/c/*.t
383             - seq: t/shutdown/*.t
384              
385             This is an experimental feature and the interface may change.
386              
387             =item * C
388              
389             This specifies where to find a YAML file of test scheduling rules. If not
390             provided, it looks for a default file to use. It first checks for a file given
391             in the C environment variable, then it checks for
392             F and then F.
393              
394             =item * C
395              
396             A filehandle for catching standard output.
397              
398             =item * C
399              
400             Attempt to print summary information if run is interrupted by
401             SIGINT (Ctrl-C).
402              
403             =back
404              
405             Any keys for which the value is C will be ignored.
406              
407             =cut
408              
409             # new supplied by TAP::Base
410              
411             {
412             my @legal_callback = qw(
413             parser_args
414             made_parser
415             before_runtests
416             after_runtests
417             after_test
418             );
419              
420             my %default_class = (
421             aggregator_class => 'TAP::Parser::Aggregator',
422             formatter_class => 'TAP::Formatter::Console',
423             multiplexer_class => 'TAP::Parser::Multiplexer',
424             parser_class => 'TAP::Parser',
425             scheduler_class => 'TAP::Parser::Scheduler',
426             );
427              
428             sub _initialize {
429 86     86   146 my ( $self, $arg_for ) = @_;
430 86   100     214 $arg_for ||= {};
431              
432 86         377 $self->SUPER::_initialize( $arg_for, \@legal_callback );
433 86         372 my %arg_for = %$arg_for; # force a shallow copy
434              
435 86         850 for my $name ( sort keys %VALIDATION_FOR ) {
436 1548         1118 my $property = delete $arg_for{$name};
437 1548 100       2025 if ( defined $property ) {
438 153         243 my $validate = $VALIDATION_FOR{$name};
439              
440 153         350 my $value = $self->$validate($property);
441 153 50       336 if ( $self->_error ) {
442 0         0 $self->_croak;
443             }
444 153         409 $self->$name($value);
445             }
446             }
447              
448 86 100       242 $self->jobs(1) unless defined $self->jobs;
449              
450 86 50       221 if ( ! defined $self->rules ) {
451 86         208 $self->_maybe_load_rulesfile;
452             }
453              
454             local $default_class{formatter_class} = 'TAP::Formatter::File'
455 86 50 100     856 unless -t ( $arg_for{stdout} || \*STDOUT ) && !$ENV{HARNESS_NOTTY};
      33        
456              
457 86         331 while ( my ( $attr, $class ) = each %default_class ) {
458 430   66     854 $self->$attr( $self->$attr() || $class );
459             }
460              
461 86 50       165 unless ( $self->formatter ) {
462              
463             # This is a little bodge to preserve legacy behaviour. It's
464             # pretty horrible that we know which args are destined for
465             # the formatter.
466 86         154 my %formatter_args = ( jobs => $self->jobs );
467 86         218 for my $name (@FORMATTER_ARGS) {
468 860 100       1349 if ( defined( my $property = delete $arg_for{$name} ) ) {
469 176         246 $formatter_args{$name} = $property;
470             }
471             }
472              
473             $self->formatter(
474 86         176 $self->_construct( $self->formatter_class, \%formatter_args )
475             );
476             }
477              
478 84 100       378 if ( my @props = sort keys %arg_for ) {
479 1         7 $self->_croak("Unknown arguments to TAP::Harness::new (@props)");
480             }
481              
482 83         460 return $self;
483             }
484              
485             sub _maybe_load_rulesfile {
486 86     86   106 my ($self) = @_;
487              
488             my ($rulesfile) = defined $self->rulesfile ? $self->rulesfile :
489             defined($ENV{HARNESS_RULESFILE}) ? $ENV{HARNESS_RULESFILE} :
490 86 50       179 grep { -r } qw(./testrules.yml t/testrules.yml);
  172 50       1163  
491              
492 86 50 33     247 if ( defined $rulesfile && -r $rulesfile ) {
493 0 0       0 if ( ! eval { require CPAN::Meta::YAML; 1} ) {
  0         0  
  0         0  
494 0         0 warn "CPAN::Meta::YAML required to process $rulesfile" ;
495 0         0 return;
496             }
497 0 0       0 my $layer = $] lt "5.008" ? "" : ":encoding(UTF-8)";
498 0 0       0 open my $fh, "<$layer", $rulesfile
499             or die "Couldn't open $rulesfile: $!";
500 0         0 my $yaml_text = do { local $/; <$fh> };
  0         0  
  0         0  
501 0 0       0 my $yaml = CPAN::Meta::YAML->read_string($yaml_text)
502             or die CPAN::Meta::YAML->errstr;
503 0         0 $self->rules( $yaml->[0] );
504             }
505 86         112 return;
506             }
507             }
508              
509             ##############################################################################
510              
511             =head2 Instance Methods
512              
513             =head3 C
514              
515             $harness->runtests(@tests);
516              
517             Accepts an array of C<@tests> to be run. This should generally be the
518             names of test files, but this is not required. Each element in C<@tests>
519             will be passed to C as a C. See
520             L for more information.
521              
522             It is possible to provide aliases that will be displayed in place of the
523             test name by supplying the test as a reference to an array containing
524             C<< [ $test, $alias ] >>:
525              
526             $harness->runtests( [ 't/foo.t', 'Foo Once' ],
527             [ 't/foo.t', 'Foo Twice' ] );
528              
529             Normally it is an error to attempt to run the same test twice. Aliases
530             allow you to overcome this limitation by giving each run of the test a
531             unique name.
532              
533             Tests will be run in the order found.
534              
535             If the environment variable C is defined it
536             should name a directory into which a copy of the raw TAP for each test
537             will be written. TAP is written to files named for each test.
538             Subdirectories will be created as needed.
539              
540             Returns a L containing the test results.
541              
542             =cut
543              
544             sub runtests {
545 44     44 1 36775 my ( $self, @tests ) = @_;
546              
547 44         122 my $aggregate = $self->_construct( $self->aggregator_class );
548              
549 44         190 $self->_make_callback( 'before_runtests', $aggregate );
550 44         117 $aggregate->start;
551             my $finish = sub {
552 42     42   59 my $interrupted = shift;
553 42         192 $aggregate->stop;
554 42         568 $self->summary( $aggregate, $interrupted );
555 42         358 $self->_make_callback( 'after_runtests', $aggregate );
556 44         663 };
557             my $run = sub {
558 44     44   119 $self->aggregate_tests( $aggregate, @tests );
559 42         98 $finish->();
560 44         120 };
561              
562 44 50       137 if ( $self->trap ) {
563             local $SIG{INT} = sub {
564 0     0   0 print "\n";
565 0         0 $finish->(1);
566 0         0 exit;
567 0         0 };
568 0         0 $run->();
569             }
570             else {
571 44         70 $run->();
572             }
573              
574 42         361 return $aggregate;
575             }
576              
577             =head3 C
578              
579             $harness->summary( $aggregator );
580              
581             Output the summary for a L.
582              
583             =cut
584              
585             sub summary {
586 42     42 1 70 my ( $self, @args ) = @_;
587 42         83 $self->formatter->summary(@args);
588             }
589              
590             sub _after_test {
591 105     105   170 my ( $self, $aggregate, $job, $parser ) = @_;
592              
593 105         355 $self->_make_callback( 'after_test', $job->as_array_ref, $parser );
594 105         270 $aggregate->add( $job->description, $parser );
595             }
596              
597             sub _bailout {
598 2     2   4 my ( $self, $result ) = @_;
599 2         5 my $explanation = $result->explanation;
600 2 50       141 die "FAILED--Further testing stopped"
601             . ( $explanation ? ": $explanation\n" : ".\n" );
602             }
603              
604             sub _aggregate_parallel {
605 1     1   1 my ( $self, $aggregate, $scheduler ) = @_;
606              
607 1         2 my $jobs = $self->jobs;
608 1         2 my $mux = $self->_construct( $self->multiplexer_class );
609              
610             RESULT: {
611              
612             # Keep multiplexer topped up
613 1         1 FILL:
614 5         13 while ( $mux->parsers < $jobs ) {
615 6         17 my $job = $scheduler->get_job;
616              
617             # If we hit a spinner stop filling and start running.
618 6 100 66     21 last FILL if !defined $job || $job->is_spinner;
619              
620 1         3 my ( $parser, $session ) = $self->make_parser($job);
621 1         10 $mux->add( $parser, [ $session, $job ] );
622             }
623              
624 5 50       11 if ( my ( $parser, $stash, $result ) = $mux->next ) {
625 5         10 my ( $session, $job ) = @$stash;
626 5 50       10 if ( defined $result ) {
627 5         21 $session->result($result);
628 5 100       17 $self->_bailout($result) if $result->is_bailout;
629             }
630             else {
631              
632             # End of parser. Automatically removed from the mux.
633 0         0 $self->finish_parser( $parser, $session );
634 0         0 $self->_after_test( $aggregate, $job, $parser );
635 0         0 $job->finish;
636             }
637 4         12 redo RESULT;
638             }
639             }
640              
641 0         0 return;
642             }
643              
644             sub _aggregate_single {
645 78     78   119 my ( $self, $aggregate, $scheduler ) = @_;
646              
647             JOB:
648 78         190 while ( my $job = $scheduler->get_job ) {
649 106 50       279 next JOB if $job->is_spinner;
650              
651 106         271 my ( $parser, $session ) = $self->make_parser($job);
652              
653 106         456 while ( defined( my $result = $parser->next ) ) {
654 435         1249 $session->result($result);
655 435 100       964 if ( $result->is_bailout ) {
656              
657             # Keep reading until input is exhausted in the hope
658             # of allowing any pending diagnostics to show up.
659 1         5 1 while $parser->next;
660 1         4 $self->_bailout($result);
661             }
662             }
663              
664 105         453 $self->finish_parser( $parser, $session );
665 105         363 $self->_after_test( $aggregate, $job, $parser );
666 105         342 $job->finish;
667             }
668              
669 77         128 return;
670             }
671              
672             =head3 C
673              
674             $harness->aggregate_tests( $aggregate, @tests );
675              
676             Run the named tests and display a summary of result. Tests will be run
677             in the order found.
678              
679             Test results will be added to the supplied L.
680             C may be called multiple times to run several sets of
681             tests. Multiple C instances may be used to pass results
682             to a single aggregator so that different parts of a complex test suite
683             may be run using different C settings. This is useful, for
684             example, in the case where some tests should run in parallel but others
685             are unsuitable for parallel execution.
686              
687             my $formatter = TAP::Formatter::Console->new;
688             my $ser_harness = TAP::Harness->new( { formatter => $formatter } );
689             my $par_harness = TAP::Harness->new(
690             { formatter => $formatter,
691             jobs => 9
692             }
693             );
694             my $aggregator = TAP::Parser::Aggregator->new;
695              
696             $aggregator->start();
697             $ser_harness->aggregate_tests( $aggregator, @ser_tests );
698             $par_harness->aggregate_tests( $aggregator, @par_tests );
699             $aggregator->stop();
700             $formatter->summary($aggregator);
701              
702             Note that for simpler testing requirements it will often be possible to
703             replace the above code with a single call to C.
704              
705             Each element of the C<@tests> array is either:
706              
707             =over
708              
709             =item * the source name of a test to run
710              
711             =item * a reference to a [ source name, display name ] array
712              
713             =back
714              
715             In the case of a perl test suite, typically I are simply the file
716             names of the test scripts to run.
717              
718             When you supply a separate display name it becomes possible to run a
719             test more than once; the display name is effectively the alias by which
720             the test is known inside the harness. The harness doesn't care if it
721             runs the same test more than once when each invocation uses a
722             different name.
723              
724             =cut
725              
726             sub aggregate_tests {
727 79     79 1 152 my ( $self, $aggregate, @tests ) = @_;
728              
729 79         179 my $jobs = $self->jobs;
730 79         233 my $scheduler = $self->make_scheduler(@tests);
731              
732             # #12458
733 79 100       513 local $ENV{HARNESS_IS_VERBOSE} = 1
734             if $self->formatter->verbosity > 0;
735              
736             # Formatter gets only names.
737 79         164 $self->formatter->prepare( map { $_->description } $scheduler->get_all );
  107         221  
738              
739 79 100       286 if ( $self->jobs > 1 ) {
740 1         3 $self->_aggregate_parallel( $aggregate, $scheduler );
741             }
742             else {
743 78         214 $self->_aggregate_single( $aggregate, $scheduler );
744             }
745              
746 77         531 return;
747             }
748              
749             sub _add_descriptions {
750 84     84   3612 my $self = shift;
751              
752             # Turn unwrapped scalars into anonymous arrays and copy the name as
753             # the description for tests that have only a name.
754 122 100       537 return map { @$_ == 1 ? [ $_->[0], $_->[0] ] : $_ }
755 84 100       147 map { 'ARRAY' eq ref $_ ? $_ : [$_] } @_;
  122         402  
756             }
757              
758             =head3 C
759              
760             Called by the harness when it needs to create a
761             L. Override in a subclass to provide an
762             alternative scheduler. C is passed the list of tests
763             that was passed to C.
764              
765             =cut
766              
767             sub make_scheduler {
768 79     79 1 148 my ( $self, @tests ) = @_;
769 79         170 return $self->_construct(
770             $self->scheduler_class,
771             tests => [ $self->_add_descriptions(@tests) ],
772             rules => $self->rules
773             );
774             }
775              
776             =head3 C
777              
778             Gets or sets the number of concurrent test runs the harness is
779             handling. By default, this value is 1 -- for parallel testing, this
780             should be set higher.
781              
782             =cut
783              
784             ##############################################################################
785              
786             sub _get_parser_args {
787 107     107   116 my ( $self, $job ) = @_;
788 107         251 my $test_prog = $job->filename;
789 107         189 my %args = ();
790              
791 107 100       236 $args{sources} = $self->sources if $self->sources;
792              
793 107         123 my @switches;
794 107 50       249 @switches = $self->lib if $self->lib;
795 107 50       243 push @switches => $self->switches if $self->switches;
796 107         299 $args{switches} = \@switches;
797 107         258 $args{spool} = $self->_open_spool($test_prog);
798 107         211 $args{merge} = $self->merge;
799 107         233 $args{ignore_exit} = $self->ignore_exit;
800 107 50       235 $args{version} = $self->version if $self->version;
801              
802 107 100       224 if ( my $exec = $self->exec ) {
803             $args{exec}
804 7 100       24 = ref $exec eq 'CODE'
805             ? $exec->( $self, $test_prog )
806             : [ @$exec, $test_prog ];
807 7 100 100     90 if ( not defined $args{exec} ) {
    100          
808 1         3 $args{source} = $test_prog;
809             }
810             elsif ( ( ref( $args{exec} ) || "" ) ne "ARRAY" ) {
811 2         7 $args{source} = delete $args{exec};
812             }
813             }
814             else {
815 100         178 $args{source} = $test_prog;
816             }
817              
818 107 100       226 if ( defined( my $test_args = $self->test_args ) ) {
819              
820 2 100       9 if ( ref($test_args) eq 'HASH' ) {
821              
822             # different args for each test
823 1 50       7 if ( exists( $test_args->{ $job->description } ) ) {
824 1         4 $test_args = $test_args->{ $job->description };
825             }
826             else {
827 0         0 $self->_croak( "TAP::Harness Can't find test_args for "
828             . $job->description );
829             }
830             }
831              
832 2         5 $args{test_args} = $test_args;
833             }
834              
835 107         276 return \%args;
836             }
837              
838             =head3 C
839              
840             Make a new parser and display formatter session. Typically used and/or
841             overridden in subclasses.
842              
843             my ( $parser, $session ) = $harness->make_parser;
844              
845             =cut
846              
847             sub make_parser {
848 107     107 1 138 my ( $self, $job ) = @_;
849              
850 107         241 my $args = $self->_get_parser_args($job);
851 107         303 $self->_make_callback( 'parser_args', $args, $job->as_array_ref );
852 107         350 my $parser = $self->_construct( $self->parser_class, $args );
853              
854 107         852 $self->_make_callback( 'made_parser', $parser, $job->as_array_ref );
855 107         559 my $session = $self->formatter->open_test( $job->description, $parser );
856              
857 107         1003 return ( $parser, $session );
858             }
859              
860             =head3 C
861              
862             Terminate use of a parser. Typically used and/or overridden in
863             subclasses. The parser isn't destroyed as a result of this.
864              
865             =cut
866              
867             sub finish_parser {
868 105     105 1 180 my ( $self, $parser, $session ) = @_;
869              
870 105         366 $session->close_test;
871 105         752 $self->_close_spool($parser);
872              
873 105         117 return $parser;
874             }
875              
876             sub _open_spool {
877 108     108   382 my $self = shift;
878 108         135 my $test = shift;
879              
880 108 100       364 if ( my $spool_dir = $ENV{PERL_TEST_HARNESS_DUMP_TAP} ) {
881              
882 2         16 my $spool = File::Spec->catfile( $spool_dir, $test );
883              
884             # Make the directory
885 2         46 my ( $vol, $dir, undef ) = File::Spec->splitpath($spool);
886 2         29 my $path = File::Spec->catpath( $vol, $dir, '' );
887 2         4 eval { mkpath($path) };
  2         619  
888 2 50       10 $self->_croak($@) if $@;
889              
890 2         19 my $spool_handle = IO::Handle->new;
891 2 100       96 open( $spool_handle, ">$spool" )
892             or $self->_croak(" Can't write $spool ( $! ) ");
893              
894 1         4 return $spool_handle;
895             }
896              
897 106         186 return;
898             }
899              
900             sub _close_spool {
901 106     106   148 my $self = shift;
902 106         149 my ($parser) = @_;
903              
904 106 100       293 if ( my $spool_handle = $parser->delete_spool ) {
905 2 100       44 close($spool_handle)
906             or $self->_croak(" Error closing TAP spool file( $! ) \n ");
907             }
908              
909 105         126 return;
910             }
911              
912             sub _croak {
913 4     4   28 my ( $self, $message ) = @_;
914 4 50       11 unless ($message) {
915 0         0 $message = $self->_error;
916             }
917 4         20 $self->SUPER::_croak($message);
918              
919 0           return;
920             }
921              
922             1;
923              
924             __END__