I just wanted to bring up nested blocks and sub-plans again. I've been hacking around in Test::Builder and I've implemented something that works and does something that I think is useful. It allows you to write tests that have output like
1..5 ok 1 - pass ok 2 - fail 1..3 a nested set of tests ok 1 - some test ok 2 - some other test 1..2 and another layer ok 1 - more tests ok 2 - another ok 3 - block 'an another layer' ok 3 - block 'a nested set of tests' ok 4 - pass ok 5 - fail each sub block has it's own plan and the numbering starts from 1. When working out the plan for a block, you don't need to think about what happens inside it's sub blocks. This makes planning very easy. When each block finishes it will test that the plan was followed. Tarball is at http://www.fergaldaly.com/computer/Test-Builder/ Why would you want to do this? Simple example. use Test::More tests => 3; use MyCompany; is_valid_person(get_manager(), "manager"); is_valid_person(get_ceo(), "ceo"); is_valid_person(get_secretary(), "sec"); sub is_valid_person { my $person = shift; my $name = shift; my $block = Test::Builder::block("$name valid person?", tests => 17); isa($item, "Person", "is a person?"); like($item->name, qr/^\w+\s+\w$/, "std name"); # 15 more tests } The plan says 3 tests even though there are 3x17 = 34 tests but because the is_valid_person tests run in a sub block, they count as just 1 test and if we add a new test to that subroutine we just have to update the sub plan, not the main one. Also if we call is_valid_person() again, we just increase the main plan by 1, not by 17. So now you can have structured programming in test scripts. The output above is compatible with Test::Harness because TH ignores lines beginning with whitespace. If a test fails inside a sub block, the error will propogate all the way to the outermost block so TH will see it. So you can test this out without modifying TH, although it would be nice if TH understood this format. This was implemented in 2 stages. First Test::Builder was changed to store it's state in a hash instead of package lexicals. Then I added some methods to create blocks and track them. You can see the 2 patches at the above URL. I also knocked out thread safety because it was bugging me with strange errors. The whole nested blocks thing will never work nicely with threads anyway and since this is just proof of concept it's not too important for now. Comments? Suggestions? Any chance you would consider this Michael? F