I recently posted about a TAP parser in 40 lines of code. Because I just uploaded a new Test::TAP (general cleanup and a pre-5.6 bug), I now have it in 30 lines of code without golfing. I could make it even shorter if I wanted to, but why?
sub _tap_failed {
my $tap = shift;
my $plan_re = qr/1\.\.(\d+)/;
my $test_re = qr/(?:not )?ok/;
my $failed;
my $core_tap = '';
foreach ( split "\n" => $tap ) {
if (/^not ok/) { # TODO tests are not failures
$failed++
unless m/^ ( [^\\\#]* (?: \\. [^\\\#]* )* )
\# \s* TODO \b \s* (.*) $/ix
}
$core_tap .= "$_\n" if /^(?:$plan_re|$test_re)/;
}
my $plan;
if ( $core_tap =~ /^$plan_re/ or $core_tap =~ /$plan_re$/ ) {
$plan = $1;
}
return 'No plan found' unless defined $plan;
return "Failed $failed out of $plan tests" if $failed;
my $plans_found = 0;
$plans_found++ while $core_tap =~ /^$plan_re/gm;
return "$plans_found plans found" if $plans_found > 1;
my $tests = 0;
$tests++ while $core_tap =~ /^$test_re/gm;
return "Planned $plan tests and found $tests tests" if $tests != $plan;
return;
}