#!/usr/bin/perl -w # Test todo subtests. # # A subtest in a todo context should have all of its diagnostic output # redirected to the todo output destination, but individual tests # within the subtest should not become todo tests themselves. BEGIN { if( $ENV{PERL_CORE} ) { chdir 't'; @INC = ( '../lib', 'lib' ); } else { unshift @INC, 't/lib'; } } use strict; use warnings; use Test::More; use Test::Builder; use Test::Builder::Tester; # Formatting may change if we're running under Test::Harness. $ENV{HARNESS_ACTIVE} = 0; our %line; # Repeat each test for various combinations of the todo reason, # the mechanism by which it is set and $Level. our @test_combos; foreach my $level (1, 2, 3) { push @test_combos, ['$TODO', 'Reason', $level], ['todo_start', 'Reason', $level], ['todo_start', '', $level], ['todo_start', 0, $level]; } plan tests => 8 * @test_combos; sub test_subtest_in_todo { my ($name, $code, $want_out, $no_tests_run) = @_; my $xxx = $no_tests_run ? 'No tests run for subtest "xxx"' : 'xxx'; chomp $want_out; my @outlines = split /\n/, $want_out; foreach my $combo (@test_combos) { my ($set_via, $todo_reason, $level) = @$combo; test_out( @outlines, "not ok 1 - $xxx # TODO $todo_reason", "# Failed (TODO) test '$xxx'", "# at $0 line $line{xxx}.", "not ok 2 - regular todo test # TODO $todo_reason", "# Failed (TODO) test 'regular todo test'", "# at $0 line $line{reg}.", ); { local $TODO = $set_via eq '$TODO' ? $todo_reason : undef; if ($set_via eq 'todo_start') { Test::Builder->new->todo_start($todo_reason); } subtest_at_level( 'xxx', $code, $level); BEGIN{ $line{xxx} = __LINE__ } ok 0, 'regular todo test'; BEGIN{ $line{reg} = __LINE__ } if ($set_via eq 'todo_start') { Test::Builder->new->todo_end; } } test_test("$name ($level), todo [$todo_reason] set via $set_via"); } } package Foo; # If several stack frames are in package 'main' then $Level # could be wrong and $main::TODO might still be found. Using # another package makes the tests more sensitive. sub main::subtest_at_level { my ($name, $code, $level) = @_; if ($level > 1) { local $Test::Builder::Level = $Test::Builder::Level + 1; main::subtest_at_level($name, $code, $level-1); } else { Test::Builder->new->subtest($name => $code); } } package main; test_subtest_in_todo("plan, no tests run", sub { plan tests => 2; }, < 17; ok 0, 'failme'; BEGIN { $line{fail2} = __LINE__ } }, <new->todo_start('Inner2'); ok 0, 'failing TODO b'; BEGIN{ $line{ftb} = __LINE__ } ok 1, 'unexpected pass b'; Test::Builder->new->todo_end; ok 0, 'inner test 3'; BEGIN{ $line{in3} = __LINE__ } }, <