4 use vars qw($VERSION @ISA);
7 use TAP::Parser::Grammar ();
8 use TAP::Parser::Result ();
9 use TAP::Parser::Source ();
10 use TAP::Parser::Source::Perl ();
11 use TAP::Parser::Iterator ();
18 TAP::Parser - Parse L<TAP|Test::Harness::TAP> output
28 my $DEFAULT_TAP_VERSION = 12;
29 my $MAX_TAP_VERSION = 13;
31 $ENV{TAP_VERSION} = $MAX_TAP_VERSION;
36 delete $ENV{TAP_VERSION};
39 BEGIN { # making accessors
62 # another tiny performance hack
63 if ( $method =~ /^_/ ) {
66 return $self->{$method} unless @_;
69 unless ( ( ref $self ) =~ /^TAP::Parser/ ) {
70 Carp::croak("$method() may not be set externally");
73 $self->{$method} = shift;
79 return $self->{$method} unless @_;
80 $self->{$method} = shift;
84 } # done making accessors
90 my $parser = TAP::Parser->new( { source => $source } );
92 while ( my $result = $parser->next ) {
93 print $result->as_string;
98 C<TAP::Parser> is designed to produce a proper parse of TAP output. For
99 an example of how to run tests through this module, see the simple
100 harnesses C<examples/>.
102 There's a wiki dedicated to the Test Anything Protocol:
104 L<http://testanything.org>
106 It includes the TAP::Parser Cookbook:
108 L<http://testanything.org/wiki/index.php/TAP::Parser_Cookbook>
116 my $parser = TAP::Parser->new(\%args);
118 Returns a new C<TAP::Parser> object.
120 The arguments should be a hashref with I<one> of the following keys:
126 This is the preferred method of passing arguments to the constructor. To
127 determine how to handle the source, the following steps are taken.
129 If the source contains a newline, it's assumed to be a string of raw TAP
132 If the source is a reference, it's assumed to be something to pass to
133 the L<TAP::Parser::Iterator::Stream> constructor. This is used
134 internally and you should not use it.
136 Otherwise, the parser does a C<-e> check to see if the source exists. If so,
137 it attempts to execute the source and read the output as a stream. This is by
138 far the preferred method of using the parser.
140 foreach my $file ( @test_files ) {
141 my $parser = TAP::Parser->new( { source => $file } );
142 # do stuff with the parser
147 The value should be the complete TAP output.
151 If passed an array reference, will attempt to create the iterator by
152 passing a L<TAP::Parser::Source> object to
153 L<TAP::Parser::Iterator::Source>, using the array reference strings as
154 the command arguments to L<IPC::Open3::open3|IPC::Open3>:
156 exec => [ '/usr/bin/ruby', 't/my_test.rb' ]
158 Note that C<source> and C<exec> are mutually exclusive.
162 The following keys are optional.
168 If present, each callback corresponding to a given result type will be called
169 with the result as the argument if the C<run> method is used:
172 test => \&test_callback,
173 plan => \&plan_callback,
174 comment => \&comment_callback,
175 bailout => \&bailout_callback,
176 unknown => \&unknown_callback,
179 my $aggregator = TAP::Parser::Aggregator->new;
180 foreach my $file ( @test_files ) {
181 my $parser = TAP::Parser->new(
184 callbacks => \%callbacks,
188 $aggregator->add( $file, $parser );
193 If using a Perl file as a source, optional switches may be passed which will
194 be used when invoking the perl executable.
196 my $parser = TAP::Parser->new( {
197 source => $test_file,
203 Used in conjunction with the C<source> option to supply a reference to
204 an C<@ARGV> style array of arguments to pass to the test program.
208 If passed a filehandle will write a copy of all parsed TAP to that handle.
212 If false, STDERR is not captured (though it is 'relayed' to keep it
213 somewhat synchronized with STDOUT.)
215 If true, STDERR and STDOUT are the same filehandle. This may cause
216 breakage if STDERR contains anything resembling TAP format, but does
217 allow exact synchronization.
219 Subtleties of this behavior may be platform-dependent and may change in
226 # new implementation supplied by TAP::Base
228 ##############################################################################
230 =head2 Instance Methods
234 my $parser = TAP::Parser->new( { source => $file } );
235 while ( my $result = $parser->next ) {
236 print $result->as_string, "\n";
239 This method returns the results of the parsing, one result at a time. Note
240 that it is destructive. You can't rewind and examine previous results.
242 If callbacks are used, they will be issued before this call returns.
244 Each result returned is a subclass of L<TAP::Parser::Result>. See that
245 module and related classes for more information on how to use them.
251 return ( $self->{_iter} ||= $self->_iter )->();
254 ##############################################################################
260 This method merely runs the parser and parses all of the TAP.
266 while ( defined( my $result = $self->next ) ) {
274 # of the following, anything beginning with an underscore is strictly
275 # internal and should not be exposed.
277 version => $DEFAULT_TAP_VERSION,
278 plan => '', # the test plan (e.g., 1..3)
280 tests_run => 0, # actual current test numbers
281 results => [], # TAP parser results
286 actual_failed => [], # how many tests really failed
287 actual_passed => [], # how many tests really passed
288 todo_passed => [], # tests which unexpectedly succeed
289 parse_errors => [], # perfect TAP should have none
292 # We seem to have this list hanging around all over the place. We could
293 # probably get it from somewhere else to avoid the repetition.
294 my @legal_callback = qw(
308 my ( $self, $arg_for ) = @_;
310 # everything here is basically designed to convert any TAP source to a
314 my %args = %{ $arg_for || {} };
316 $self->SUPER::_initialize( \%args, \@legal_callback );
318 my $stream = delete $args{stream};
319 my $tap = delete $args{tap};
320 my $source = delete $args{source};
321 my $exec = delete $args{exec};
322 my $merge = delete $args{merge};
323 my $spool = delete $args{spool};
324 my $switches = delete $args{switches};
325 my @test_args = @{ delete $args{test_args} || [] };
327 if ( 1 < grep {defined} $stream, $tap, $source, $exec ) {
329 "You may only choose one of 'exec', 'stream', 'tap' or 'source'"
333 if ( my @excess = sort keys %args ) {
334 $self->_croak("Unknown options: @excess");
338 $stream = TAP::Parser::Iterator->new( [ split "\n" => $tap ] );
341 my $source = TAP::Parser::Source->new;
342 $source->source( [ @$exec, @test_args ] );
343 $source->merge($merge); # XXX should just be arguments?
344 $stream = $source->get_stream;
347 if ( my $ref = ref $source ) {
348 $stream = TAP::Parser::Iterator->new($source);
350 elsif ( -e $source ) {
352 my $perl = TAP::Parser::Source::Perl->new;
354 $perl->switches($switches)
357 $perl->merge($merge); # XXX args to new()?
359 $perl->source( [ $source, @test_args ] );
361 $stream = $perl->get_stream;
364 $self->_croak("Cannot determine source for $source");
369 $self->_croak('PANIC: could not determine stream');
372 while ( my ( $k, $v ) = each %initialize ) {
373 $self->{$k} = 'ARRAY' eq ref $v ? [] : $v;
376 $self->_stream($stream);
377 my $grammar = TAP::Parser::Grammar->new($stream);
378 $grammar->set_version( $self->version );
379 $self->_grammar($grammar);
380 $self->_spool($spool);
382 $self->start_time( $self->get_time );
388 =head1 INDIVIDUAL RESULTS
390 If you've read this far in the docs, you've seen this:
392 while ( my $result = $parser->next ) {
393 print $result->as_string;
396 Each result returned is a L<TAP::Parser::Result> subclass, referred to as
401 Basically, you fetch individual results from the TAP. The six types, with
402 examples of each, are as follows:
416 ok 3 - We should start with some foobar!
420 # Hope we don't use up the foobar.
424 Bail out! We ran out of foobar!
428 ... yo, this ain't TAP! ...
432 Each result fetched is a result object of a different type. There are common
433 methods to each result object and different types may have methods unique to
434 their type. Sometimes a type method may be overridden in a subclass, but its
435 use is guaranteed to be identical.
437 =head2 Common type methods
441 Returns the type of result, such as C<comment> or C<test>.
445 Prints a string representation of the token. This might not be the exact
446 output, however. Tests will have test numbers added if not present, TODO and
447 SKIP directives will be capitalized and, in general, things will be cleaned
448 up. If you need the original text for the token, see the C<raw> method.
452 Returns the original line of text which was parsed.
456 Indicates whether or not this is the test plan line.
460 Indicates whether or not this is a test line.
464 Indicates whether or not this is a comment. Comments will generally only
465 appear in the TAP stream if STDERR is merged to STDOUT. See the
470 Indicates whether or not this is bailout line.
474 Indicates whether or not the current item is a YAML block.
478 Indicates whether or not the current line could be parsed.
482 if ( $result->is_ok ) { ... }
484 Reports whether or not a given result has passed. Anything which is B<not> a
485 test result returns true. This is merely provided as a convenient shortcut
486 which allows you to do this:
488 my $parser = TAP::Parser->new( { source => $source } );
489 while ( my $result = $parser->next ) {
490 # only print failing results
491 print $result->as_string unless $result->is_ok;
494 =head2 C<plan> methods
496 if ( $result->is_plan ) { ... }
498 If the above evaluates as true, the following methods will be available on the
503 if ( $result->is_plan ) {
507 This is merely a synonym for C<as_string>.
509 =head3 C<tests_planned>
511 my $planned = $result->tests_planned;
513 Returns the number of tests planned. For example, a plan of C<1..17> will
514 cause this method to return '17'.
518 my $directive = $result->directive;
520 If a SKIP directive is included with the plan, this method will return it.
522 1..0 # SKIP: why bother?
524 =head3 C<explanation>
526 my $explanation = $result->explanation;
528 If a SKIP directive was included with the plan, this method will return the
531 =head2 C<commment> methods
533 if ( $result->is_comment ) { ... }
535 If the above evaluates as true, the following methods will be available on the
540 if ( $result->is_comment ) {
541 my $comment = $result->comment;
542 print "I have something to say: $comment";
545 =head2 C<bailout> methods
547 if ( $result->is_bailout ) { ... }
549 If the above evaluates as true, the following methods will be available on the
552 =head3 C<explanation>
554 if ( $result->is_bailout ) {
555 my $explanation = $result->explanation;
556 print "We bailed out because ($explanation)";
559 If, and only if, a token is a bailout token, you can get an "explanation" via
560 this method. The explanation is the text after the mystical "Bail out!" words
561 which appear in the tap output.
563 =head2 C<unknown> methods
565 if ( $result->is_unknown ) { ... }
567 There are no unique methods for unknown results.
569 =head2 C<test> methods
571 if ( $result->is_test ) { ... }
573 If the above evaluates as true, the following methods will be available on the
578 my $ok = $result->ok;
580 Returns the literal text of the C<ok> or C<not ok> status.
584 my $test_number = $result->number;
586 Returns the number of the test, even if the original TAP output did not supply
589 =head3 C<description>
591 my $description = $result->description;
593 Returns the description of the test, if any. This is the portion after the
594 test number but before the directive.
598 my $directive = $result->directive;
600 Returns either C<TODO> or C<SKIP> if either directive was present for a test
603 =head3 C<explanation>
605 my $explanation = $result->explanation;
607 If a test had either a C<TODO> or C<SKIP> directive, this method will return
608 the accompanying explantion, if present.
610 not ok 17 - 'Pigs can fly' # TODO not enough acid
612 For the above line, the explanation is I<not enough acid>.
616 if ( $result->is_ok ) { ... }
618 Returns a boolean value indicating whether or not the test passed. Remember
619 that for TODO tests, the test always passes.
621 B<Note:> this was formerly C<passed>. The latter method is deprecated and
622 will issue a warning.
624 =head3 C<is_actual_ok>
626 if ( $result->is_actual_ok ) { ... }
628 Returns a boolean value indicating whether or not the test passed, regardless
631 B<Note:> this was formerly C<actual_passed>. The latter method is deprecated
632 and will issue a warning.
634 =head3 C<is_unplanned>
636 if ( $test->is_unplanned ) { ... }
638 If a test number is greater than the number of planned tests, this method will
639 return true. Unplanned tests will I<always> return false for C<is_ok>,
640 regardless of whether or not the test C<has_todo> (see
641 L<TAP::Parser::Result::Test> for more information about this).
645 if ( $result->has_skip ) { ... }
647 Returns a boolean value indicating whether or not this test had a SKIP
652 if ( $result->has_todo ) { ... }
654 Returns a boolean value indicating whether or not this test had a TODO
657 Note that TODO tests I<always> pass. If you need to know whether or not
658 they really passed, check the C<is_actual_ok> method.
662 if ( $parser->in_todo ) { ... }
664 True while the most recent result was a TODO. Becomes true before the
665 TODO result is returned and stays true until just before the next non-
666 TODO test is returned.
670 After parsing the TAP, there are many methods available to let you dig through
671 the results and determine what is meaningful to you.
673 =head2 Individual Results
675 These results refer to individual tests which are run.
679 my @passed = $parser->passed; # the test numbers which passed
680 my $passed = $parser->passed; # the number of tests which passed
682 This method lets you know which (or how many) tests passed. If a test failed
683 but had a TODO directive, it will be counted as a passed test.
687 sub passed { @{ shift->{passed} } }
691 my @failed = $parser->failed; # the test numbers which failed
692 my $failed = $parser->failed; # the number of tests which failed
694 This method lets you know which (or how many) tests failed. If a test passed
695 but had a TODO directive, it will B<NOT> be counted as a failed test.
699 sub failed { @{ shift->{failed} } }
701 =head3 C<actual_passed>
703 # the test numbers which actually passed
704 my @actual_passed = $parser->actual_passed;
706 # the number of tests which actually passed
707 my $actual_passed = $parser->actual_passed;
709 This method lets you know which (or how many) tests actually passed,
710 regardless of whether or not a TODO directive was found.
714 sub actual_passed { @{ shift->{actual_passed} } }
715 *actual_ok = \&actual_passed;
719 This method is a synonym for C<actual_passed>.
721 =head3 C<actual_failed>
723 # the test numbers which actually failed
724 my @actual_failed = $parser->actual_failed;
726 # the number of tests which actually failed
727 my $actual_failed = $parser->actual_failed;
729 This method lets you know which (or how many) tests actually failed,
730 regardless of whether or not a TODO directive was found.
734 sub actual_failed { @{ shift->{actual_failed} } }
736 ##############################################################################
740 my @todo = $parser->todo; # the test numbers with todo directives
741 my $todo = $parser->todo; # the number of tests with todo directives
743 This method lets you know which (or how many) tests had TODO directives.
747 sub todo { @{ shift->{todo} } }
749 =head3 C<todo_passed>
751 # the test numbers which unexpectedly succeeded
752 my @todo_passed = $parser->todo_passed;
754 # the number of tests which unexpectedly succeeded
755 my $todo_passed = $parser->todo_passed;
757 This method lets you know which (or how many) tests actually passed but were
758 declared as "TODO" tests.
762 sub todo_passed { @{ shift->{todo_passed} } }
764 ##############################################################################
766 =head3 C<todo_failed>
768 # deprecated in favor of 'todo_passed'. This method was horribly misnamed.
770 This was a badly misnamed method. It indicates which TODO tests unexpectedly
771 succeeded. Will now issue a warning and call C<todo_passed>.
777 '"todo_failed" is deprecated. Please use "todo_passed". See the docs.';
783 my @skipped = $parser->skipped; # the test numbers with SKIP directives
784 my $skipped = $parser->skipped; # the number of tests with SKIP directives
786 This method lets you know which (or how many) tests had SKIP directives.
790 sub skipped { @{ shift->{skipped} } }
792 =head2 Summary Results
794 These results are "meta" information about the total results of an individual
799 my $plan = $parser->plan;
801 Returns the test plan, if found.
805 Deprecated. Use C<is_good_plan> instead.
810 warn 'good_plan() is deprecated. Please use "is_good_plan()"';
814 ##############################################################################
816 =head3 C<is_good_plan>
818 if ( $parser->is_good_plan ) { ... }
820 Returns a boolean value indicating whether or not the number of tests planned
821 matches the number of tests run.
823 B<Note:> this was formerly C<good_plan>. The latter method is deprecated and
824 will issue a warning.
826 And since we're on that subject ...
828 =head3 C<tests_planned>
830 print $parser->tests_planned;
832 Returns the number of tests planned, according to the plan. For example, a
833 plan of '1..17' will mean that 17 tests were planned.
837 print $parser->tests_run;
839 Returns the number of tests which actually were run. Hopefully this will
840 match the number of C<< $parser->tests_planned >>.
844 Returns a true value (actually the reason for skipping) if all tests
849 Returns the time when the Parser was created.
853 Returns the time when the end of TAP input was seen.
855 =head3 C<has_problems>
857 if ( $parser->has_problems ) {
861 This is a 'catch-all' method which returns true if any tests have currently
862 failed, any TODO tests unexpectedly succeeded, or any parse errors occurred.
870 || $self->parse_errors
879 Once the parser is done, this will return the version number for the
880 parsed TAP. Version numbers were introduced with TAP version 13 so if no
881 version number is found version 12 is assumed.
887 Once the parser is done, this will return the exit status. If the parser ran
888 an executable, it returns the exit status of the executable.
894 Once the parser is done, this will return the wait status. If the parser ran
895 an executable, it returns the wait status of the executable. Otherwise, this
896 mererely returns the C<exit> status.
898 =head3 C<parse_errors>
900 my @errors = $parser->parse_errors; # the parser errors
901 my $errors = $parser->parse_errors; # the number of parser_errors
903 Fortunately, all TAP output is perfect. In the event that it is not, this
904 method will return parser errors. Note that a junk line which the parser does
905 not recognize is C<not> an error. This allows this parser to handle future
906 versions of TAP. The following are all TAP errors reported by the parser:
910 =item * Misplaced plan
912 The plan (for example, '1..5'), must only come at the beginning or end of the
919 =item * More than one plan
922 ok 1 - input file opened
923 not ok 2 - first line of the input valid # todo some data
924 ok 3 read the rest of the file
927 Right. Very funny. Don't do that.
929 =item * Test numbers out of sequence
932 ok 1 - input file opened
933 not ok 2 - first line of the input valid # todo some data
934 ok 2 read the rest of the file
936 That last test line above should have the number '3' instead of '2'.
938 Note that it's perfectly acceptable for some lines to have test numbers and
939 others to not have them. However, when a test number is found, it must be in
940 sequence. The following is also an error:
943 ok 1 - input file opened
944 not ok - first line of the input valid # todo some data
945 ok 2 read the rest of the file
950 ok - input file opened
951 not ok - first line of the input valid # todo some data
952 ok 3 read the rest of the file
958 sub parse_errors { @{ shift->{parse_errors} } }
961 my ( $self, $error ) = @_;
962 push @{ $self->{parse_errors} } => $error;
966 sub _make_state_table {
969 my %planned_todo = ();
971 # These transitions are defaults for all states
972 my %state_globals = (
979 'If TAP version is present it must be the first line of output'
985 # Provides default elements for transitions
986 my %state_defaults = (
990 $self->tests_planned( $plan->tests_planned );
991 $self->plan( $plan->plan );
992 if ( $plan->has_skip ) {
993 $self->skip_all( $plan->explanation
994 || '(no reason given)' );
997 $planned_todo{$_}++ for @{ $plan->todo_list };
1004 my ( $number, $tests_run )
1005 = ( $test->number, ++$self->{tests_run} );
1008 if ( defined $number && delete $planned_todo{$number} ) {
1009 $test->set_directive('TODO');
1012 my $has_todo = $test->has_todo;
1014 $self->in_todo($has_todo);
1015 if ( defined( my $tests_planned = $self->tests_planned ) ) {
1016 if ( $tests_run > $tests_planned ) {
1017 $test->is_unplanned(1);
1022 if ( $number != $tests_run ) {
1023 my $count = $tests_run;
1024 $self->_add_error( "Tests out of sequence. Found "
1025 . "($number) but expected ($count)" );
1029 $test->_number( $number = $tests_run );
1032 push @{ $self->{todo} } => $number if $has_todo;
1033 push @{ $self->{todo_passed} } => $number
1034 if $test->todo_passed;
1035 push @{ $self->{skipped} } => $number
1038 push @{ $self->{ $test->is_ok ? 'passed' : 'failed' } } =>
1054 # Each state contains a hash the keys of which match a token type. For
1056 # type there may be:
1057 # act A coderef to run
1058 # goto The new state to move to. Stay in this state if
1060 # continue Goto the new state and run the new state for the
1067 my $ver_num = $version->version;
1068 if ( $ver_num <= $DEFAULT_TAP_VERSION ) {
1069 my $ver_min = $DEFAULT_TAP_VERSION + 1;
1071 "Explicit TAP version must be at least "
1072 . "$ver_min. Got version $ver_num" );
1073 $ver_num = $DEFAULT_TAP_VERSION;
1075 if ( $ver_num > $MAX_TAP_VERSION ) {
1077 "TAP specified version $ver_num but "
1078 . "we don't know about versions later "
1079 . "than $MAX_TAP_VERSION" );
1080 $ver_num = $MAX_TAP_VERSION;
1082 $self->version($ver_num);
1083 $self->_grammar->set_version($ver_num);
1087 plan => { goto => 'PLANNED' },
1088 test => { goto => 'UNPLANNED' },
1091 plan => { goto => 'PLANNED' },
1092 test => { goto => 'UNPLANNED' },
1095 test => { goto => 'PLANNED_AFTER_TEST' },
1100 'More than one plan found in TAP output');
1104 PLANNED_AFTER_TEST => {
1105 test => { goto => 'PLANNED_AFTER_TEST' },
1106 plan => { act => sub { }, continue => 'PLANNED' },
1107 yaml => { goto => 'PLANNED' },
1113 my $line = $self->plan;
1115 "Plan ($line) must be at the beginning "
1116 . "or end of the TAP output" );
1117 $self->is_good_plan(0);
1119 continue => 'PLANNED'
1121 plan => { continue => 'PLANNED' },
1124 test => { goto => 'UNPLANNED_AFTER_TEST' },
1125 plan => { goto => 'GOT_PLAN' },
1127 UNPLANNED_AFTER_TEST => {
1128 test => { act => sub { }, continue => 'UNPLANNED' },
1129 plan => { act => sub { }, continue => 'UNPLANNED' },
1130 yaml => { goto => 'PLANNED' },
1134 # Apply globals and defaults to state table
1135 for my $name ( sort keys %states ) {
1137 # Merge with globals
1138 my $st = { %state_globals, %{ $states{$name} } };
1141 for my $next ( sort keys %{$st} ) {
1142 if ( my $default = $state_defaults{$next} ) {
1143 for my $def ( sort keys %{$default} ) {
1144 $st->{$next}->{$def} ||= $default->{$def};
1149 # Stuff back in table
1150 $states{$name} = $st;
1156 =head3 C<get_select_handles>
1158 Get an a list of file handles which can be passed to C<select> to
1159 determine the readiness of this parser.
1163 sub get_select_handles { shift->_stream->get_select_handles }
1167 my $stream = $self->_stream;
1168 my $spool = $self->_spool;
1169 my $grammar = $self->_grammar;
1171 my $state_table = $self->_make_state_table;
1173 # Make next_state closure
1174 my $next_state = sub {
1176 my $type = $token->type;
1179 my $state_spec = $state_table->{$state}
1180 or die "Illegal state: $state";
1182 if ( my $next = $state_spec->{$type} ) {
1183 if ( my $act = $next->{act} ) {
1186 if ( my $cont = $next->{continue} ) {
1190 elsif ( my $goto = $next->{goto} ) {
1198 # Handle end of stream - which means either pop a block or finish
1199 my $end_handler = sub {
1200 $self->exit( $stream->exit );
1201 $self->wait( $stream->wait );
1206 # Finally make the closure that we return. For performance reasons
1207 # there are two versions of the returned function: one that handles
1208 # callbacks and one that does not.
1209 if ( $self->_has_callbacks ) {
1211 my $result = eval { $grammar->tokenize };
1212 $self->_add_error($@) if $@;
1214 if ( defined $result ) {
1215 $result = $next_state->($result);
1217 if ( my $code = $self->_callback_for( $result->type ) ) {
1218 $_->($result) for @{$code};
1221 $self->_make_callback( 'ELSE', $result );
1224 $self->_make_callback( 'ALL', $result );
1226 # Echo TAP to spool file
1227 print {$spool} $result->raw, "\n" if $spool;
1230 $result = $end_handler->();
1231 $self->_make_callback( 'EOF', $result )
1232 unless defined $result;
1240 my $result = eval { $grammar->tokenize };
1241 $self->_add_error($@) if $@;
1243 if ( defined $result ) {
1244 $result = $next_state->($result);
1246 # Echo TAP to spool file
1247 print {$spool} $result->raw, "\n" if $spool;
1250 $result = $end_handler->();
1261 $self->end_time( $self->get_time );
1264 if ( !$self->plan ) {
1265 $self->_add_error('No plan found in TAP output');
1268 $self->is_good_plan(1) unless defined $self->is_good_plan;
1270 if ( $self->tests_run != ( $self->tests_planned || 0 ) ) {
1271 $self->is_good_plan(0);
1272 if ( defined( my $planned = $self->tests_planned ) ) {
1273 my $ran = $self->tests_run;
1275 "Bad plan. You planned $planned tests but ran $ran.");
1278 if ( $self->tests_run != ( $self->passed + $self->failed ) ) {
1280 # this should never happen
1281 my $actual = $self->tests_run;
1282 my $passed = $self->passed;
1283 my $failed = $self->failed;
1284 $self->_croak( "Panic: planned test count ($actual) did not equal "
1285 . "sum of passed ($passed) and failed ($failed) tests!" );
1288 $self->is_good_plan(0) unless defined $self->is_good_plan;
1292 =head3 C<delete_spool>
1294 Delete and return the spool.
1296 my $fh = $parser->delete_spool;
1303 return delete $self->{_spool};
1306 ##############################################################################
1310 As mentioned earlier, a "callback" key may be added to the
1311 C<TAP::Parser> constructor. If present, each callback corresponding to a
1312 given result type will be called with the result as the argument if the
1313 C<run> method is used. The callback is expected to be a subroutine
1314 reference (or anonymous subroutine) which is invoked with the parser
1315 result as its argument.
1318 test => \&test_callback,
1319 plan => \&plan_callback,
1320 comment => \&comment_callback,
1321 bailout => \&bailout_callback,
1322 unknown => \&unknown_callback,
1325 my $aggregator = TAP::Parser::Aggregator->new;
1326 foreach my $file ( @test_files ) {
1327 my $parser = TAP::Parser->new(
1330 callbacks => \%callbacks,
1334 $aggregator->add( $file, $parser );
1337 Callbacks may also be added like this:
1339 $parser->callback( test => \&test_callback );
1340 $parser->callback( plan => \&plan_callback );
1342 The following keys allowed for callbacks. These keys are case-sensitive.
1348 Invoked if C<< $result->is_test >> returns true.
1352 Invoked if C<< $result->is_version >> returns true.
1356 Invoked if C<< $result->is_plan >> returns true.
1360 Invoked if C<< $result->is_comment >> returns true.
1364 Invoked if C<< $result->is_unknown >> returns true.
1368 Invoked if C<< $result->is_yaml >> returns true.
1372 Invoked if C<< $result->is_unknown >> returns true.
1376 If a result does not have a callback defined for it, this callback will
1377 be invoked. Thus, if all of the previous result types are specified as
1378 callbacks, this callback will I<never> be invoked.
1382 This callback will always be invoked and this will happen for each
1383 result after one of the above callbacks is invoked. For example, if
1384 L<Term::ANSIColor> is loaded, you could use the following to color your
1390 if ( $test->is_ok && not $test->directive ) {
1391 # normal passing test
1392 print color 'green';
1394 elsif ( !$test->is_ok ) { # even if it's TODO
1395 print color 'white on_red';
1397 elsif ( $test->has_skip ) {
1398 print color 'white on_blue';
1401 elsif ( $test->has_todo ) {
1402 print color 'white';
1406 # plan, comment, and so on (anything which isn't a test line)
1407 print color 'black on_white';
1411 print shift->as_string;
1412 print color 'reset';
1419 Invoked when there are no more lines to be parsed. Since there is no
1420 accompanying L<TAP::Parser::Result> object the C<TAP::Parser> object is
1427 If you're looking for an EBNF grammar, see L<TAP::Parser::Grammar>.
1429 =head1 BACKWARDS COMPATABILITY
1431 The Perl-QA list attempted to ensure backwards compatability with
1432 L<Test::Harness>. However, there are some minor differences.
1440 A little-known feature of L<Test::Harness> is that it supported TODO
1444 ok 1 - We have liftoff
1445 not ok 2 - Anti-gravity device activated
1447 Under L<Test::Harness>, test number 2 would I<pass> because it was
1448 listed as a TODO test on the plan line. However, we are not aware of
1449 anyone actually using this feature and hard-coding test numbers is
1450 discouraged because it's very easy to add a test and break the test
1451 number sequence. This makes test suites very fragile. Instead, the
1452 following should be used:
1455 ok 1 - We have liftoff
1456 not ok 2 - Anti-gravity device activated # TODO
1458 =item * 'Missing' tests
1460 It rarely happens, but sometimes a harness might encounter
1469 L<Test::Harness> would report tests 3-14 as having failed. For the
1470 C<TAP::Parser>, these tests are not considered failed because they've
1471 never run. They're reported as parse failures (tests out of sequence).
1475 =head1 ACKNOWLEDGEMENTS
1477 All of the following have helped. Bug reports, patches, (im)moral
1478 support, or just words of encouragement have all been forthcoming.
1482 =item * Michael Schwern
1492 =item * Torsten Schoenfeld
1498 =item * Adam Kennedy
1502 =item * Adrian Howard
1506 =item * Andreas J. Koenig
1508 =item * Florian Ragwitz
1512 =item * Mark Stosberg
1520 Curtis "Ovid" Poe <ovid@cpan.org>
1522 Andy Armstong <andy@hexten.net>
1524 Eric Wilhelm @ <ewilhelm at cpan dot org>
1526 Michael Peters <mpeters at plusthree dot com>
1528 Leif Eriksen <leif dot eriksen at bigpond dot com>
1532 Please report any bugs or feature requests to
1533 C<bug-tapx-parser@rt.cpan.org>, or through the web interface at
1534 L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=TAP-Parser>.
1535 We will be notified, and then you'll automatically be notified of
1536 progress on your bug as we make changes.
1538 Obviously, bugs which include patches are best. If you prefer, you can
1539 patch against bleed by via anonymous checkout of the latest version:
1541 svn checkout http://svn.hexten.net/tapx
1543 =head1 COPYRIGHT & LICENSE
1545 Copyright 2006-2007 Curtis "Ovid" Poe, all rights reserved.
1547 This program is free software; you can redistribute it and/or modify it
1548 under the same terms as Perl itself.