On 11/03/07, Michael G Schwern <[EMAIL PROTECTED]> wrote:
Fergal Daly wrote:
> You're suggesting that each call to extend the plan verifies that the
> previous plan has been executed fully? That does not allow nesting.
Yes, nesting is what this proposal does which cannot be done now.
Groups without nesting gives me subroutines with a max stack of depth
of 1. It's almost more annoying than it is useful.
Unfortuantely the other thing it does well is shatter backwards
compatibility so I'd like it to do something significantly more.
How does it do this? I understand that an old harness will not be able
to parse it - it will be upset by the sub-plans and the dotted test
numbers) but if we know we're running under an old harness then we can
just fall back to plan-at-the-end and diagnostics.
This brings up something else. Future harnesses should probably set
I_UNDERSTAND_TAP_VERSIONS="1,5,8,10-22"
so we know what we can output. If that's not set then we need to stick
to plainest TAP.
Is there something in the proposal that prevents us continuing to
output TAP just as today for a test script with no blocks?
F
> There's also the issue of passing important error messages as text
> embedded in diags.
Once we have a diagnostic syntax that will not be as much of an issue.
> Finally, it doesn't help with counting. Take this example
>
> use Test::More tests => 10;
>
> my @tests = (...); # ten things
>
> for my $t (@test) {
> is($t, foo);
> }
>
> now if I want to change this to
>
> for my $t (@test) {
> is($t, foo);
> is($t, bar);
> }
>
> I must update the global plan and start multiplying things. With
> blocks I can just do
>
> for my $t (@test) {
> block {
> plan 2;
> is($t, foo);
> is($t, bar);
> }
> }
>
> becase the plan of each block is counted as a single test in it's
> enclosing block. With plan extensions I would either do
>
> use Test::More tests => 10;
>
> my @tests = (...); # ten things
>
> for my $t (@test) {
> is($t, foo);
> extend 1;
> is($t, bar);
> }
>
> which is clearly broken and will cause lots of confusion when you
> squirrel your tests away in subroutines. Or
>
> use Test::More tests => 0;
>
> my @tests = (...); # ten things
>
> for my $t (@test) {
> extend 2;
> is($t, foo);
> is($t, bar);
> }
>
> which will happily exit early with 0 tests run and no errors,
There seems to be the assumption that you must have an initial global count.
Why can't there be a syntax like so?
use Test::More import => ["!plan"];
use AsYouGo;
plan "as_you_go";
for my $t (@test) {
extend 2;
is($t, "foo");
is($t, "bar");
}
Where "as_you_go" requires you to declare at least one plan extension before
exiting. And yes, it can tell if you didn't run any tests.
The attached proof-of-concept implements it. I had to poke at the guts of
TB to do it, there's no way to extend the plan without printing the plan, so
it would need a minor TB patch. But its very straight forward.
package AsYouGo;
use strict;
use warnings;
use base qw(Test::Builder::Module);
our @EXPORT = qw(plan extend);
my $Extended = 0;
my $Is_As_You_Go = 0;
use CLASS;
sub plan {
my($plan) = shift;
my $tb = $CLASS->builder;
if( $plan eq "as_you_go" ) {
$Is_As_You_Go = 1;
$tb->plan("no_plan");
}
else { # pass through to TB
$tb->plan(@_);
}
}
sub extend {
my($extra_tests) = shift;
my $tb = $CLASS->builder;
print "# Extending plan by $extra_tests\n";
$extra_tests-- unless $Extended; # there's already one
# TB doesn't have a way to extend the plan without printing the plan.
$tb->{Expected_Tests} += $extra_tests;
$Extended = 1;
1;
}
END {
if( $Is_As_You_Go && !$Extended ) {
die "# An as_you_go plan declared but never extended!\n";
}
}
1;
__END__