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.

Unfortuantely the other thing it does well is shatter backwards
compatibility so I'd like it to do something significantly more.


> 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__

Reply via email to