Yesterday I realized how we can finally have nested TAP and make it backwards compatible. Today I've forked Schwern's Test::More and hacked in nested TAP.
#!/usr/bin/env perl
use strict;
use warnings;
use lib '../lib';
# Gotta have a plan!
use Test::More tests => 3;
ok 1;
subtest 'some name' => sub {
my $num_tests = 2 + int( rand(3) );
# random plans!
plan tests => $num_tests;
ok 1 for 1 .. $num_tests - 1;
subtest 'some name' => sub {
# or no plans!
plan 'no_plan';
ok 1 for 1 .. 2 + int( rand(3) );
};
};
ok 1;
Note how we have random plans and no plans, but we can still have a top-level assertion of the number of tests. The output looks something like this:
1..3
ok 1
1..3
ok 1
ok 2
ok 1
ok 2
ok 3
ok 4
1..4
ok 3 - some name
ok 2 - some name
ok 3
ok
All tests successful.
Files=1, Tests=3, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.02 cusr 0.00 csys = 0.04 CPU)
Result: PASS
Note that due to how TAP is specified, that's backwards-compatible with older versions of TAP and the current Test::Harness handles this just fine. Andy Armstrong is now working on being able to offer better parsing tools to understand nested TAP.
There is a Test::Builder interface for this, too.
my $builder = Test::Builder->new;
$builder->plan(tests => 7);
for( 1 .. 3 ) {
$builder->ok( $_, "We're on $_" );
$builder->diag("We ran $_");
}
{
my $indented = $builder->child;
$indented->plan('no_plan');
for( 1 .. 1+int(rand(5)) ) {
$indented->ok( 1, "We're on $_" );
}
$indented->finalize;
}
for( 7, 8, 9 ) {
$builder->ok( $_, "We're on $_" );
}
Eventually we'll add support for being able to compose nested TAP from external sources, but that might require a "TAP envelope" (long story). For now, though, we're ignoring that and focusing on this drool-worthy feature.
So far the Hackathon has been very profitable.