This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Update to the latest Test-Simple cpan dist
authorChad Granum <exodist7@gmail.com>
Tue, 10 May 2016 14:44:27 +0000 (07:44 -0700)
committerTony Cook <tony@develop-help.com>
Wed, 11 May 2016 23:32:16 +0000 (09:32 +1000)
230 files changed:
MANIFEST
Makefile.SH
cpan/Test-Simple/lib/Test/Builder.pm
cpan/Test-Simple/lib/Test/Builder/Formatter.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test/Builder/Module.pm
cpan/Test-Simple/lib/Test/Builder/Tester.pm
cpan/Test-Simple/lib/Test/Builder/Tester/Color.pm
cpan/Test-Simple/lib/Test/Builder/TodoDiag.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test/FAQ.pod [new file with mode: 0644]
cpan/Test-Simple/lib/Test/More.pm
cpan/Test-Simple/lib/Test/Simple.pm
cpan/Test-Simple/lib/Test/Tester.pm
cpan/Test-Simple/lib/Test/Tester/Capture.pm
cpan/Test-Simple/lib/Test/Tester/CaptureRunner.pm
cpan/Test-Simple/lib/Test/Tester/Delegate.pm
cpan/Test-Simple/lib/Test/use/ok.pm
cpan/Test-Simple/lib/Test2.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/API.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/API/Breakage.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/API/Context.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/API/Instance.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/API/Stack.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Event.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Event/Bail.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Event/Diag.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Event/Exception.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Event/Note.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Event/Ok.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Event/Plan.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Event/Skip.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Event/Subtest.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Event/Waiting.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Formatter.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Formatter/TAP.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Hub.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Hub/Interceptor.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Hub/Interceptor/Terminator.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Hub/Subtest.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/IPC.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/IPC/Driver.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/IPC/Driver/Files.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Transition.pod [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Util.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Util/ExternalMeta.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Util/HashBase.pm [new file with mode: 0644]
cpan/Test-Simple/lib/Test2/Util/Trace.pm [new file with mode: 0644]
cpan/Test-Simple/lib/ok.pm
cpan/Test-Simple/t/00compile.t [new file with mode: 0644]
cpan/Test-Simple/t/Builder/fork_with_new_stdout.t [deleted file]
cpan/Test-Simple/t/Legacy/00test_harness_check.t [moved from cpan/Test-Simple/t/00test_harness_check.t with 100% similarity]
cpan/Test-Simple/t/Legacy/01-basic.t [moved from cpan/Test-Simple/t/01-basic.t with 100% similarity]
cpan/Test-Simple/t/Legacy/478-cmp_ok_hash.t [moved from cpan/Test-Simple/t/478-cmp_ok_hash.t with 100% similarity]
cpan/Test-Simple/t/Legacy/BEGIN_require_ok.t [moved from cpan/Test-Simple/t/BEGIN_require_ok.t with 100% similarity]
cpan/Test-Simple/t/Legacy/BEGIN_use_ok.t [moved from cpan/Test-Simple/t/BEGIN_use_ok.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Bugs/600.t [new file with mode: 0644]
cpan/Test-Simple/t/Legacy/Bugs/629.t [new file with mode: 0644]
cpan/Test-Simple/t/Legacy/Builder/Builder.t [moved from cpan/Test-Simple/t/Builder/Builder.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/carp.t [moved from cpan/Test-Simple/t/Builder/carp.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/create.t [moved from cpan/Test-Simple/t/Builder/create.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/current_test.t [moved from cpan/Test-Simple/t/Builder/current_test.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/current_test_without_plan.t [moved from cpan/Test-Simple/t/Builder/current_test_without_plan.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/details.t [moved from cpan/Test-Simple/t/Builder/details.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/done_testing.t [moved from cpan/Test-Simple/t/Builder/done_testing.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/done_testing_double.t [moved from cpan/Test-Simple/t/Builder/done_testing_double.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/done_testing_plan_mismatch.t [moved from cpan/Test-Simple/t/Builder/done_testing_plan_mismatch.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/done_testing_with_no_plan.t [moved from cpan/Test-Simple/t/Builder/done_testing_with_no_plan.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/done_testing_with_number.t [moved from cpan/Test-Simple/t/Builder/done_testing_with_number.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/done_testing_with_plan.t [moved from cpan/Test-Simple/t/Builder/done_testing_with_plan.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/fork_with_new_stdout.t [new file with mode: 0644]
cpan/Test-Simple/t/Legacy/Builder/has_plan.t [moved from cpan/Test-Simple/t/Builder/has_plan.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/has_plan2.t [moved from cpan/Test-Simple/t/Builder/has_plan2.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/is_fh.t [moved from cpan/Test-Simple/t/Builder/is_fh.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/is_passing.t [moved from cpan/Test-Simple/t/Builder/is_passing.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/maybe_regex.t [moved from cpan/Test-Simple/t/Builder/maybe_regex.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/no_diag.t [moved from cpan/Test-Simple/t/Builder/no_diag.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/no_ending.t [moved from cpan/Test-Simple/t/Builder/no_ending.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/no_header.t [moved from cpan/Test-Simple/t/Builder/no_header.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/no_plan_at_all.t [moved from cpan/Test-Simple/t/Builder/no_plan_at_all.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/ok_obj.t [moved from cpan/Test-Simple/t/Builder/ok_obj.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/output.t [moved from cpan/Test-Simple/t/Builder/output.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/reset.t [moved from cpan/Test-Simple/t/Builder/reset.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/reset_outputs.t [moved from cpan/Test-Simple/t/Builder/reset_outputs.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Builder/try.t [moved from cpan/Test-Simple/t/Builder/try.t with 100% similarity]
cpan/Test-Simple/t/Legacy/More.t [moved from cpan/Test-Simple/t/More.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Regression/637.t [new file with mode: 0644]
cpan/Test-Simple/t/Legacy/Simple/load.t [moved from cpan/Test-Simple/t/Simple/load.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Test2/Subtest.t [new file with mode: 0644]
cpan/Test-Simple/t/Legacy/Tester/tbt_01basic.t [moved from cpan/Test-Simple/t/Tester/tbt_01basic.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Tester/tbt_02fhrestore.t [moved from cpan/Test-Simple/t/Tester/tbt_02fhrestore.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Tester/tbt_03die.t [moved from cpan/Test-Simple/t/Tester/tbt_03die.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Tester/tbt_04line_num.t [moved from cpan/Test-Simple/t/Tester/tbt_04line_num.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Tester/tbt_05faildiag.t [moved from cpan/Test-Simple/t/Tester/tbt_05faildiag.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Tester/tbt_06errormess.t [moved from cpan/Test-Simple/t/Tester/tbt_06errormess.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Tester/tbt_07args.t [moved from cpan/Test-Simple/t/Tester/tbt_07args.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Tester/tbt_08subtest.t [moved from cpan/Test-Simple/t/Tester/tbt_08subtest.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Tester/tbt_09do.t [moved from cpan/Test-Simple/t/Tester/tbt_09do.t with 100% similarity]
cpan/Test-Simple/t/Legacy/Tester/tbt_09do_script.pl [moved from cpan/Test-Simple/t/Tester/tbt_09do_script.pl with 100% similarity]
cpan/Test-Simple/t/Legacy/auto.t [moved from cpan/Test-Simple/t/auto.t with 96% similarity]
cpan/Test-Simple/t/Legacy/bad_plan.t [moved from cpan/Test-Simple/t/bad_plan.t with 100% similarity]
cpan/Test-Simple/t/Legacy/bail_out.t [moved from cpan/Test-Simple/t/bail_out.t with 81% similarity]
cpan/Test-Simple/t/Legacy/buffer.t [moved from cpan/Test-Simple/t/buffer.t with 100% similarity]
cpan/Test-Simple/t/Legacy/c_flag.t [moved from cpan/Test-Simple/t/c_flag.t with 100% similarity]
cpan/Test-Simple/t/Legacy/capture.t [moved from cpan/Test-Simple/t/capture.t with 100% similarity]
cpan/Test-Simple/t/Legacy/check_tests.t [moved from cpan/Test-Simple/t/check_tests.t with 100% similarity]
cpan/Test-Simple/t/Legacy/circular_data.t [moved from cpan/Test-Simple/t/circular_data.t with 100% similarity]
cpan/Test-Simple/t/Legacy/cmp_ok.t [moved from cpan/Test-Simple/t/cmp_ok.t with 100% similarity]
cpan/Test-Simple/t/Legacy/depth.t [moved from cpan/Test-Simple/t/depth.t with 95% similarity]
cpan/Test-Simple/t/Legacy/diag.t [moved from cpan/Test-Simple/t/diag.t with 93% similarity]
cpan/Test-Simple/t/Legacy/died.t [moved from cpan/Test-Simple/t/died.t with 95% similarity]
cpan/Test-Simple/t/Legacy/dont_overwrite_die_handler.t [moved from cpan/Test-Simple/t/dont_overwrite_die_handler.t with 73% similarity]
cpan/Test-Simple/t/Legacy/eq_set.t [moved from cpan/Test-Simple/t/eq_set.t with 100% similarity]
cpan/Test-Simple/t/Legacy/exit.t [moved from cpan/Test-Simple/t/exit.t with 100% similarity]
cpan/Test-Simple/t/Legacy/explain.t [moved from cpan/Test-Simple/t/explain.t with 100% similarity]
cpan/Test-Simple/t/Legacy/explain_err_vars.t [new file with mode: 0644]
cpan/Test-Simple/t/Legacy/extra.t [moved from cpan/Test-Simple/t/extra.t with 100% similarity]
cpan/Test-Simple/t/Legacy/extra_one.t [moved from cpan/Test-Simple/t/extra_one.t with 100% similarity]
cpan/Test-Simple/t/Legacy/fail-like.t [moved from cpan/Test-Simple/t/fail-like.t with 97% similarity]
cpan/Test-Simple/t/Legacy/fail-more.t [moved from cpan/Test-Simple/t/fail-more.t with 100% similarity]
cpan/Test-Simple/t/Legacy/fail.t [moved from cpan/Test-Simple/t/fail.t with 100% similarity]
cpan/Test-Simple/t/Legacy/fail_one.t [moved from cpan/Test-Simple/t/fail_one.t with 100% similarity]
cpan/Test-Simple/t/Legacy/filehandles.t [moved from cpan/Test-Simple/t/filehandles.t with 100% similarity]
cpan/Test-Simple/t/Legacy/fork.t [new file with mode: 0644]
cpan/Test-Simple/t/Legacy/harness_active.t [moved from cpan/Test-Simple/t/harness_active.t with 100% similarity]
cpan/Test-Simple/t/Legacy/import.t [moved from cpan/Test-Simple/t/import.t with 100% similarity]
cpan/Test-Simple/t/Legacy/is_deeply_dne_bug.t [moved from cpan/Test-Simple/t/is_deeply_dne_bug.t with 100% similarity]
cpan/Test-Simple/t/Legacy/is_deeply_fail.t [moved from cpan/Test-Simple/t/is_deeply_fail.t with 100% similarity]
cpan/Test-Simple/t/Legacy/is_deeply_with_threads.t [moved from cpan/Test-Simple/t/is_deeply_with_threads.t with 85% similarity]
cpan/Test-Simple/t/Legacy/missing.t [moved from cpan/Test-Simple/t/missing.t with 100% similarity]
cpan/Test-Simple/t/Legacy/new_ok.t [moved from cpan/Test-Simple/t/new_ok.t with 100% similarity]
cpan/Test-Simple/t/Legacy/no_plan.t [moved from cpan/Test-Simple/t/no_plan.t with 100% similarity]
cpan/Test-Simple/t/Legacy/no_tests.t [moved from cpan/Test-Simple/t/no_tests.t with 95% similarity]
cpan/Test-Simple/t/Legacy/note.t [moved from cpan/Test-Simple/t/note.t with 100% similarity]
cpan/Test-Simple/t/Legacy/overload.t [moved from cpan/Test-Simple/t/overload.t with 100% similarity]
cpan/Test-Simple/t/Legacy/overload_threads.t [moved from cpan/Test-Simple/t/overload_threads.t with 91% similarity]
cpan/Test-Simple/t/Legacy/plan.t [moved from cpan/Test-Simple/t/plan.t with 100% similarity]
cpan/Test-Simple/t/Legacy/plan_bad.t [moved from cpan/Test-Simple/t/plan_bad.t with 100% similarity]
cpan/Test-Simple/t/Legacy/plan_is_noplan.t [moved from cpan/Test-Simple/t/plan_is_noplan.t with 100% similarity]
cpan/Test-Simple/t/Legacy/plan_no_plan.t [moved from cpan/Test-Simple/t/plan_no_plan.t with 100% similarity]
cpan/Test-Simple/t/Legacy/plan_shouldnt_import.t [moved from cpan/Test-Simple/t/plan_shouldnt_import.t with 100% similarity]
cpan/Test-Simple/t/Legacy/plan_skip_all.t [moved from cpan/Test-Simple/t/plan_skip_all.t with 100% similarity]
cpan/Test-Simple/t/Legacy/require_ok.t [moved from cpan/Test-Simple/t/require_ok.t with 100% similarity]
cpan/Test-Simple/t/Legacy/run_test.t [moved from cpan/Test-Simple/t/run_test.t with 100% similarity]
cpan/Test-Simple/t/Legacy/simple.t [moved from cpan/Test-Simple/t/simple.t with 100% similarity]
cpan/Test-Simple/t/Legacy/skip.t [moved from cpan/Test-Simple/t/skip.t with 100% similarity]
cpan/Test-Simple/t/Legacy/skipall.t [moved from cpan/Test-Simple/t/skipall.t with 100% similarity]
cpan/Test-Simple/t/Legacy/strays.t [new file with mode: 0644]
cpan/Test-Simple/t/Legacy/subtest/args.t [moved from cpan/Test-Simple/t/subtest/args.t with 80% similarity]
cpan/Test-Simple/t/Legacy/subtest/bail_out.t [moved from cpan/Test-Simple/t/subtest/bail_out.t with 84% similarity]
cpan/Test-Simple/t/Legacy/subtest/basic.t [moved from cpan/Test-Simple/t/subtest/basic.t with 87% similarity]
cpan/Test-Simple/t/Legacy/subtest/die.t [moved from cpan/Test-Simple/t/subtest/die.t with 100% similarity]
cpan/Test-Simple/t/Legacy/subtest/do.t [moved from cpan/Test-Simple/t/subtest/do.t with 83% similarity]
cpan/Test-Simple/t/Legacy/subtest/events.t [new file with mode: 0644]
cpan/Test-Simple/t/Legacy/subtest/for_do_t.test [moved from cpan/Test-Simple/t/subtest/for_do_t.test with 100% similarity]
cpan/Test-Simple/t/Legacy/subtest/fork.t [moved from cpan/Test-Simple/t/subtest/fork.t with 57% similarity]
cpan/Test-Simple/t/Legacy/subtest/implicit_done.t [moved from cpan/Test-Simple/t/subtest/implicit_done.t with 100% similarity]
cpan/Test-Simple/t/Legacy/subtest/line_numbers.t [moved from cpan/Test-Simple/t/subtest/line_numbers.t with 94% similarity]
cpan/Test-Simple/t/Legacy/subtest/plan.t [moved from cpan/Test-Simple/t/subtest/plan.t with 100% similarity]
cpan/Test-Simple/t/Legacy/subtest/predicate.t [moved from cpan/Test-Simple/t/subtest/predicate.t with 95% similarity]
cpan/Test-Simple/t/Legacy/subtest/singleton.t [moved from cpan/Test-Simple/t/subtest/singleton.t with 100% similarity]
cpan/Test-Simple/t/Legacy/subtest/threads.t [moved from cpan/Test-Simple/t/subtest/threads.t with 56% similarity]
cpan/Test-Simple/t/Legacy/subtest/todo.t [moved from cpan/Test-Simple/t/subtest/todo.t with 98% similarity]
cpan/Test-Simple/t/Legacy/subtest/wstat.t [moved from cpan/Test-Simple/t/subtest/wstat.t with 100% similarity]
cpan/Test-Simple/t/Legacy/tbm_doesnt_set_exported_to.t [moved from cpan/Test-Simple/t/tbm_doesnt_set_exported_to.t with 100% similarity]
cpan/Test-Simple/t/Legacy/thread_taint.t [moved from cpan/Test-Simple/t/thread_taint.t with 100% similarity]
cpan/Test-Simple/t/Legacy/threads.t [moved from cpan/Test-Simple/t/threads.t with 67% similarity]
cpan/Test-Simple/t/Legacy/todo.t [moved from cpan/Test-Simple/t/todo.t with 99% similarity]
cpan/Test-Simple/t/Legacy/undef.t [moved from cpan/Test-Simple/t/undef.t with 100% similarity]
cpan/Test-Simple/t/Legacy/use_ok.t [moved from cpan/Test-Simple/t/use_ok.t with 100% similarity]
cpan/Test-Simple/t/Legacy/useing.t [moved from cpan/Test-Simple/t/useing.t with 100% similarity]
cpan/Test-Simple/t/Legacy/utf8.t [moved from cpan/Test-Simple/t/utf8.t with 98% similarity]
cpan/Test-Simple/t/Legacy/versions.t [moved from cpan/Test-Simple/t/versions.t with 100% similarity]
cpan/Test-Simple/t/Legacy_And_Test2/builder_loaded_late.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/acceptance/try_it_done_testing.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/acceptance/try_it_fork.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/acceptance/try_it_no_plan.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/acceptance/try_it_plan.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/acceptance/try_it_skip.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/acceptance/try_it_threads.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/acceptance/try_it_todo.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/behavior/Subtest_buffer_formatter.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/behavior/Subtest_events.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/behavior/Subtest_plan.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/behavior/Taint.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/behavior/err_var.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/behavior/init_croak.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/behavior/nested_context_exception.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/behavior/no_load_api.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/legacy/TAP.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/API.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/API/Breakage.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/API/Context.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/API/Instance.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/API/Stack.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Event.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Event/Bail.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Event/Diag.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Event/Exception.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Event/Note.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Event/Ok.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Event/Plan.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Event/Skip.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Event/Subtest.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Event/Waiting.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Formatter/TAP.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Hub.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Hub/Interceptor.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Hub/Interceptor/Terminator.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Hub/Subtest.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/IPC.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/IPC/Driver.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/IPC/Driver/Files.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Util.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Util/ExternalMeta.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Util/HashBase.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/modules/Util/Trace.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/regression/gh_16.t [new file with mode: 0644]
cpan/Test-Simple/t/Test2/regression/ipc_files_abort_exit.t [new file with mode: 0644]
cpan/Test-Simple/t/dependents.t [deleted file]
cpan/Test-Simple/t/fork.t [deleted file]
cpan/Test-Simple/t/lib/MyTest.pm [moved from cpan/Test-Simple/t/MyTest.pm with 100% similarity]
cpan/Test-Simple/t/lib/SmallTest.pm [moved from cpan/Test-Simple/t/SmallTest.pm with 100% similarity]
cpan/Test-Simple/t/regression/642_persistent_end.t [new file with mode: 0644]
cpan/Test-Simple/t/regression/no_name_in_subtest.t [new file with mode: 0644]
cpan/Test-Simple/t/subtest/exceptions.t [deleted file]
cpan/Test-Simple/t/tools.pl [new file with mode: 0644]
cpan/Test-Simple/t/tools.t [new file with mode: 0644]
ext/XS-APItest/t/svpeek.t
lib/.gitignore
win32/Makefile
win32/makefile.mk

index 4d9ab9f..cc7d29c 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -2460,11 +2460,44 @@ cpan/Test-Harness/t/yamlish-output.t                    Test::Harness test
 cpan/Test-Harness/t/yamlish.t                          Test::Harness test
 cpan/Test-Harness/t/yamlish-writer.t                   Test::Harness test
 cpan/Test-Simple/lib/ok.pm
+cpan/Test-Simple/lib/Test2/API/Breakage.pm
+cpan/Test-Simple/lib/Test2/API/Context.pm
+cpan/Test-Simple/lib/Test2/API/Instance.pm
+cpan/Test-Simple/lib/Test2/API.pm
+cpan/Test-Simple/lib/Test2/API/Stack.pm
+cpan/Test-Simple/lib/Test2/Event/Bail.pm
+cpan/Test-Simple/lib/Test2/Event/Diag.pm
+cpan/Test-Simple/lib/Test2/Event/Exception.pm
+cpan/Test-Simple/lib/Test2/Event/Note.pm
+cpan/Test-Simple/lib/Test2/Event/Ok.pm
+cpan/Test-Simple/lib/Test2/Event/Plan.pm
+cpan/Test-Simple/lib/Test2/Event.pm
+cpan/Test-Simple/lib/Test2/Event/Skip.pm
+cpan/Test-Simple/lib/Test2/Event/Subtest.pm
+cpan/Test-Simple/lib/Test2/Event/Waiting.pm
+cpan/Test-Simple/lib/Test2/Formatter.pm
+cpan/Test-Simple/lib/Test2/Formatter/TAP.pm
+cpan/Test-Simple/lib/Test2/Hub/Interceptor.pm
+cpan/Test-Simple/lib/Test2/Hub/Interceptor/Terminator.pm
+cpan/Test-Simple/lib/Test2/Hub.pm
+cpan/Test-Simple/lib/Test2/Hub/Subtest.pm
+cpan/Test-Simple/lib/Test2/IPC/Driver/Files.pm
+cpan/Test-Simple/lib/Test2/IPC/Driver.pm
+cpan/Test-Simple/lib/Test2/IPC.pm
+cpan/Test-Simple/lib/Test2.pm
+cpan/Test-Simple/lib/Test2/Transition.pod
+cpan/Test-Simple/lib/Test2/Util/ExternalMeta.pm
+cpan/Test-Simple/lib/Test2/Util/HashBase.pm
+cpan/Test-Simple/lib/Test2/Util.pm
+cpan/Test-Simple/lib/Test2/Util/Trace.pm
+cpan/Test-Simple/lib/Test/Builder/Formatter.pm
 cpan/Test-Simple/lib/Test/Builder/IO/Scalar.pm
 cpan/Test-Simple/lib/Test/Builder/Module.pm
 cpan/Test-Simple/lib/Test/Builder.pm
 cpan/Test-Simple/lib/Test/Builder/Tester/Color.pm
 cpan/Test-Simple/lib/Test/Builder/Tester.pm
+cpan/Test-Simple/lib/Test/Builder/TodoDiag.pm
+cpan/Test-Simple/lib/Test/FAQ.pod
 cpan/Test-Simple/lib/Test/More.pm
 cpan/Test-Simple/lib/Test/Simple.pm
 cpan/Test-Simple/lib/Test/Tester/Capture.pm
@@ -2473,73 +2506,137 @@ cpan/Test-Simple/lib/Test/Tester/Delegate.pm
 cpan/Test-Simple/lib/Test/Tester.pm
 cpan/Test-Simple/lib/Test/Tutorial.pod
 cpan/Test-Simple/lib/Test/use/ok.pm
-cpan/Test-Simple/t/00test_harness_check.t
-cpan/Test-Simple/t/01-basic.t
-cpan/Test-Simple/t/478-cmp_ok_hash.t
-cpan/Test-Simple/t/auto.t
-cpan/Test-Simple/t/bad_plan.t
-cpan/Test-Simple/t/bail_out.t
-cpan/Test-Simple/t/BEGIN_require_ok.t
-cpan/Test-Simple/t/BEGIN_use_ok.t
-cpan/Test-Simple/t/buffer.t
-cpan/Test-Simple/t/Builder/Builder.t
-cpan/Test-Simple/t/Builder/carp.t
-cpan/Test-Simple/t/Builder/create.t
-cpan/Test-Simple/t/Builder/current_test.t
-cpan/Test-Simple/t/Builder/current_test_without_plan.t
-cpan/Test-Simple/t/Builder/details.t
-cpan/Test-Simple/t/Builder/done_testing_double.t
-cpan/Test-Simple/t/Builder/done_testing_plan_mismatch.t
-cpan/Test-Simple/t/Builder/done_testing.t
-cpan/Test-Simple/t/Builder/done_testing_with_no_plan.t
-cpan/Test-Simple/t/Builder/done_testing_with_number.t
-cpan/Test-Simple/t/Builder/done_testing_with_plan.t
-cpan/Test-Simple/t/Builder/fork_with_new_stdout.t
-cpan/Test-Simple/t/Builder/has_plan2.t
-cpan/Test-Simple/t/Builder/has_plan.t
-cpan/Test-Simple/t/Builder/is_fh.t
-cpan/Test-Simple/t/Builder/is_passing.t
-cpan/Test-Simple/t/Builder/maybe_regex.t
-cpan/Test-Simple/t/Builder/no_diag.t
-cpan/Test-Simple/t/Builder/no_ending.t
-cpan/Test-Simple/t/Builder/no_header.t
-cpan/Test-Simple/t/Builder/no_plan_at_all.t
-cpan/Test-Simple/t/Builder/ok_obj.t
-cpan/Test-Simple/t/Builder/output.t
-cpan/Test-Simple/t/Builder/reset_outputs.t
-cpan/Test-Simple/t/Builder/reset.t
-cpan/Test-Simple/t/Builder/try.t
-cpan/Test-Simple/t/capture.t
-cpan/Test-Simple/t/c_flag.t
-cpan/Test-Simple/t/check_tests.t
-cpan/Test-Simple/t/circular_data.t
-cpan/Test-Simple/t/cmp_ok.t
-cpan/Test-Simple/t/dependents.t
-cpan/Test-Simple/t/depth.t
-cpan/Test-Simple/t/diag.t
-cpan/Test-Simple/t/died.t
-cpan/Test-Simple/t/dont_overwrite_die_handler.t
-cpan/Test-Simple/t/eq_set.t
-cpan/Test-Simple/t/exit.t
-cpan/Test-Simple/t/explain.t
-cpan/Test-Simple/t/extra_one.t
-cpan/Test-Simple/t/extra.t
-cpan/Test-Simple/t/fail-like.t
-cpan/Test-Simple/t/fail-more.t
-cpan/Test-Simple/t/fail_one.t
-cpan/Test-Simple/t/fail.t
-cpan/Test-Simple/t/filehandles.t
-cpan/Test-Simple/t/fork.t
-cpan/Test-Simple/t/harness_active.t
-cpan/Test-Simple/t/import.t
-cpan/Test-Simple/t/is_deeply_dne_bug.t
-cpan/Test-Simple/t/is_deeply_fail.t
-cpan/Test-Simple/t/is_deeply_with_threads.t
+cpan/Test-Simple/t/00compile.t
+cpan/Test-Simple/t/Legacy/00test_harness_check.t
+cpan/Test-Simple/t/Legacy/01-basic.t
+cpan/Test-Simple/t/Legacy/478-cmp_ok_hash.t
+cpan/Test-Simple/t/Legacy_And_Test2/builder_loaded_late.t
+cpan/Test-Simple/t/Legacy/auto.t
+cpan/Test-Simple/t/Legacy/bad_plan.t
+cpan/Test-Simple/t/Legacy/bail_out.t
+cpan/Test-Simple/t/Legacy/BEGIN_require_ok.t
+cpan/Test-Simple/t/Legacy/BEGIN_use_ok.t
+cpan/Test-Simple/t/Legacy/buffer.t
+cpan/Test-Simple/t/Legacy/Bugs/600.t
+cpan/Test-Simple/t/Legacy/Bugs/629.t
+cpan/Test-Simple/t/Legacy/Builder/Builder.t
+cpan/Test-Simple/t/Legacy/Builder/carp.t
+cpan/Test-Simple/t/Legacy/Builder/create.t
+cpan/Test-Simple/t/Legacy/Builder/current_test.t
+cpan/Test-Simple/t/Legacy/Builder/current_test_without_plan.t
+cpan/Test-Simple/t/Legacy/Builder/details.t
+cpan/Test-Simple/t/Legacy/Builder/done_testing_double.t
+cpan/Test-Simple/t/Legacy/Builder/done_testing_plan_mismatch.t
+cpan/Test-Simple/t/Legacy/Builder/done_testing.t
+cpan/Test-Simple/t/Legacy/Builder/done_testing_with_no_plan.t
+cpan/Test-Simple/t/Legacy/Builder/done_testing_with_number.t
+cpan/Test-Simple/t/Legacy/Builder/done_testing_with_plan.t
+cpan/Test-Simple/t/Legacy/Builder/fork_with_new_stdout.t
+cpan/Test-Simple/t/Legacy/Builder/has_plan2.t
+cpan/Test-Simple/t/Legacy/Builder/has_plan.t
+cpan/Test-Simple/t/Legacy/Builder/is_fh.t
+cpan/Test-Simple/t/Legacy/Builder/is_passing.t
+cpan/Test-Simple/t/Legacy/Builder/maybe_regex.t
+cpan/Test-Simple/t/Legacy/Builder/no_diag.t
+cpan/Test-Simple/t/Legacy/Builder/no_ending.t
+cpan/Test-Simple/t/Legacy/Builder/no_header.t
+cpan/Test-Simple/t/Legacy/Builder/no_plan_at_all.t
+cpan/Test-Simple/t/Legacy/Builder/ok_obj.t
+cpan/Test-Simple/t/Legacy/Builder/output.t
+cpan/Test-Simple/t/Legacy/Builder/reset_outputs.t
+cpan/Test-Simple/t/Legacy/Builder/reset.t
+cpan/Test-Simple/t/Legacy/Builder/try.t
+cpan/Test-Simple/t/Legacy/capture.t
+cpan/Test-Simple/t/Legacy/c_flag.t
+cpan/Test-Simple/t/Legacy/check_tests.t
+cpan/Test-Simple/t/Legacy/circular_data.t
+cpan/Test-Simple/t/Legacy/cmp_ok.t
+cpan/Test-Simple/t/Legacy/depth.t
+cpan/Test-Simple/t/Legacy/diag.t
+cpan/Test-Simple/t/Legacy/died.t
+cpan/Test-Simple/t/Legacy/dont_overwrite_die_handler.t
+cpan/Test-Simple/t/Legacy/eq_set.t
+cpan/Test-Simple/t/Legacy/exit.t
+cpan/Test-Simple/t/Legacy/explain_err_vars.t
+cpan/Test-Simple/t/Legacy/explain.t
+cpan/Test-Simple/t/Legacy/extra_one.t
+cpan/Test-Simple/t/Legacy/extra.t
+cpan/Test-Simple/t/Legacy/fail-like.t
+cpan/Test-Simple/t/Legacy/fail-more.t
+cpan/Test-Simple/t/Legacy/fail_one.t
+cpan/Test-Simple/t/Legacy/fail.t
+cpan/Test-Simple/t/Legacy/filehandles.t
+cpan/Test-Simple/t/Legacy/fork.t
+cpan/Test-Simple/t/Legacy/harness_active.t
+cpan/Test-Simple/t/Legacy/import.t
+cpan/Test-Simple/t/Legacy/is_deeply_dne_bug.t
+cpan/Test-Simple/t/Legacy/is_deeply_fail.t
+cpan/Test-Simple/t/Legacy/is_deeply_with_threads.t
+cpan/Test-Simple/t/Legacy/missing.t
+cpan/Test-Simple/t/Legacy/More.t
+cpan/Test-Simple/t/Legacy/new_ok.t
+cpan/Test-Simple/t/Legacy/no_plan.t
+cpan/Test-Simple/t/Legacy/no_tests.t
+cpan/Test-Simple/t/Legacy/note.t
+cpan/Test-Simple/t/Legacy/overload.t
+cpan/Test-Simple/t/Legacy/overload_threads.t
+cpan/Test-Simple/t/Legacy/plan_bad.t
+cpan/Test-Simple/t/Legacy/plan_is_noplan.t
+cpan/Test-Simple/t/Legacy/plan_no_plan.t
+cpan/Test-Simple/t/Legacy/plan_shouldnt_import.t
+cpan/Test-Simple/t/Legacy/plan_skip_all.t
+cpan/Test-Simple/t/Legacy/plan.t
+cpan/Test-Simple/t/Legacy/Regression/637.t
+cpan/Test-Simple/t/Legacy/require_ok.t
+cpan/Test-Simple/t/Legacy/run_test.t
+cpan/Test-Simple/t/Legacy/Simple/load.t
+cpan/Test-Simple/t/Legacy/simple.t
+cpan/Test-Simple/t/Legacy/skipall.t
+cpan/Test-Simple/t/Legacy/skip.t
+cpan/Test-Simple/t/Legacy/strays.t
+cpan/Test-Simple/t/Legacy/subtest/args.t
+cpan/Test-Simple/t/Legacy/subtest/bail_out.t
+cpan/Test-Simple/t/Legacy/subtest/basic.t
+cpan/Test-Simple/t/Legacy/subtest/die.t
+cpan/Test-Simple/t/Legacy/subtest/do.t
+cpan/Test-Simple/t/Legacy/subtest/events.t
+cpan/Test-Simple/t/Legacy/subtest/for_do_t.test
+cpan/Test-Simple/t/Legacy/subtest/fork.t
+cpan/Test-Simple/t/Legacy/subtest/implicit_done.t
+cpan/Test-Simple/t/Legacy/subtest/line_numbers.t
+cpan/Test-Simple/t/Legacy/subtest/plan.t
+cpan/Test-Simple/t/Legacy/subtest/predicate.t
+cpan/Test-Simple/t/Legacy/subtest/singleton.t
+cpan/Test-Simple/t/Legacy/subtest/threads.t
+cpan/Test-Simple/t/Legacy/subtest/todo.t
+cpan/Test-Simple/t/Legacy/subtest/wstat.t
+cpan/Test-Simple/t/Legacy/tbm_doesnt_set_exported_to.t
+cpan/Test-Simple/t/Legacy/Test2/Subtest.t
+cpan/Test-Simple/t/Legacy/Tester/tbt_01basic.t
+cpan/Test-Simple/t/Legacy/Tester/tbt_02fhrestore.t
+cpan/Test-Simple/t/Legacy/Tester/tbt_03die.t
+cpan/Test-Simple/t/Legacy/Tester/tbt_04line_num.t
+cpan/Test-Simple/t/Legacy/Tester/tbt_05faildiag.t
+cpan/Test-Simple/t/Legacy/Tester/tbt_06errormess.t
+cpan/Test-Simple/t/Legacy/Tester/tbt_07args.t
+cpan/Test-Simple/t/Legacy/Tester/tbt_08subtest.t
+cpan/Test-Simple/t/Legacy/Tester/tbt_09do_script.pl
+cpan/Test-Simple/t/Legacy/Tester/tbt_09do.t
+cpan/Test-Simple/t/Legacy/threads.t
+cpan/Test-Simple/t/Legacy/thread_taint.t
+cpan/Test-Simple/t/Legacy/todo.t
+cpan/Test-Simple/t/Legacy/undef.t
+cpan/Test-Simple/t/Legacy/useing.t
+cpan/Test-Simple/t/Legacy/use_ok.t
+cpan/Test-Simple/t/Legacy/utf8.t
+cpan/Test-Simple/t/Legacy/versions.t
 cpan/Test-Simple/t/lib/Dev/Null.pm
 cpan/Test-Simple/t/lib/Dummy.pm
 cpan/Test-Simple/t/lib/MyOverload.pm
+cpan/Test-Simple/t/lib/MyTest.pm
 cpan/Test-Simple/t/lib/NoExporter.pm
 cpan/Test-Simple/t/lib/SigDie.pm
+cpan/Test-Simple/t/lib/SmallTest.pm
 cpan/Test-Simple/t/lib/Test/Builder/NoOutput.pm
 cpan/Test-Simple/t/lib/Test/Simple/Catch.pm
 cpan/Test-Simple/t/lib/Test/Simple/sample_tests/death_in_eval.plx
@@ -2559,63 +2656,55 @@ cpan/Test-Simple/t/lib/Test/Simple/sample_tests/too_few_fail.plx
 cpan/Test-Simple/t/lib/Test/Simple/sample_tests/too_few.plx
 cpan/Test-Simple/t/lib/Test/Simple/sample_tests/two_fail.plx
 cpan/Test-Simple/t/lib/TieOut.pm
-cpan/Test-Simple/t/missing.t
-cpan/Test-Simple/t/More.t
-cpan/Test-Simple/t/MyTest.pm
-cpan/Test-Simple/t/new_ok.t
-cpan/Test-Simple/t/no_plan.t
-cpan/Test-Simple/t/no_tests.t
-cpan/Test-Simple/t/note.t
-cpan/Test-Simple/t/overload.t
-cpan/Test-Simple/t/overload_threads.t
-cpan/Test-Simple/t/plan_bad.t
-cpan/Test-Simple/t/plan_is_noplan.t
-cpan/Test-Simple/t/plan_no_plan.t
-cpan/Test-Simple/t/plan_shouldnt_import.t
-cpan/Test-Simple/t/plan_skip_all.t
-cpan/Test-Simple/t/plan.t
-cpan/Test-Simple/t/require_ok.t
-cpan/Test-Simple/t/run_test.t
-cpan/Test-Simple/t/Simple/load.t
-cpan/Test-Simple/t/simple.t
-cpan/Test-Simple/t/skipall.t
-cpan/Test-Simple/t/skip.t
-cpan/Test-Simple/t/SmallTest.pm
-cpan/Test-Simple/t/subtest/args.t
-cpan/Test-Simple/t/subtest/bail_out.t
-cpan/Test-Simple/t/subtest/basic.t
-cpan/Test-Simple/t/subtest/die.t
-cpan/Test-Simple/t/subtest/do.t
-cpan/Test-Simple/t/subtest/exceptions.t
-cpan/Test-Simple/t/subtest/for_do_t.test
-cpan/Test-Simple/t/subtest/fork.t
-cpan/Test-Simple/t/subtest/implicit_done.t
-cpan/Test-Simple/t/subtest/line_numbers.t
-cpan/Test-Simple/t/subtest/plan.t
-cpan/Test-Simple/t/subtest/predicate.t
-cpan/Test-Simple/t/subtest/singleton.t
-cpan/Test-Simple/t/subtest/threads.t
-cpan/Test-Simple/t/subtest/todo.t
-cpan/Test-Simple/t/subtest/wstat.t
-cpan/Test-Simple/t/tbm_doesnt_set_exported_to.t
-cpan/Test-Simple/t/Tester/tbt_01basic.t
-cpan/Test-Simple/t/Tester/tbt_02fhrestore.t
-cpan/Test-Simple/t/Tester/tbt_03die.t
-cpan/Test-Simple/t/Tester/tbt_04line_num.t
-cpan/Test-Simple/t/Tester/tbt_05faildiag.t
-cpan/Test-Simple/t/Tester/tbt_06errormess.t
-cpan/Test-Simple/t/Tester/tbt_07args.t
-cpan/Test-Simple/t/Tester/tbt_08subtest.t
-cpan/Test-Simple/t/Tester/tbt_09do_script.pl
-cpan/Test-Simple/t/Tester/tbt_09do.t
-cpan/Test-Simple/t/threads.t
-cpan/Test-Simple/t/thread_taint.t
-cpan/Test-Simple/t/todo.t
-cpan/Test-Simple/t/undef.t
-cpan/Test-Simple/t/useing.t
-cpan/Test-Simple/t/use_ok.t
-cpan/Test-Simple/t/utf8.t
-cpan/Test-Simple/t/versions.t
+cpan/Test-Simple/t/regression/642_persistent_end.t
+cpan/Test-Simple/t/regression/no_name_in_subtest.t
+cpan/Test-Simple/t/Test2/acceptance/try_it_done_testing.t
+cpan/Test-Simple/t/Test2/acceptance/try_it_fork.t
+cpan/Test-Simple/t/Test2/acceptance/try_it_no_plan.t
+cpan/Test-Simple/t/Test2/acceptance/try_it_plan.t
+cpan/Test-Simple/t/Test2/acceptance/try_it_skip.t
+cpan/Test-Simple/t/Test2/acceptance/try_it_threads.t
+cpan/Test-Simple/t/Test2/acceptance/try_it_todo.t
+cpan/Test-Simple/t/Test2/behavior/err_var.t
+cpan/Test-Simple/t/Test2/behavior/init_croak.t
+cpan/Test-Simple/t/Test2/behavior/nested_context_exception.t
+cpan/Test-Simple/t/Test2/behavior/no_load_api.t
+cpan/Test-Simple/t/Test2/behavior/Subtest_buffer_formatter.t
+cpan/Test-Simple/t/Test2/behavior/Subtest_events.t
+cpan/Test-Simple/t/Test2/behavior/Subtest_plan.t
+cpan/Test-Simple/t/Test2/behavior/Taint.t
+cpan/Test-Simple/t/Test2/legacy/TAP.t
+cpan/Test-Simple/t/Test2/modules/API/Breakage.t
+cpan/Test-Simple/t/Test2/modules/API/Context.t
+cpan/Test-Simple/t/Test2/modules/API/Instance.t
+cpan/Test-Simple/t/Test2/modules/API/Stack.t
+cpan/Test-Simple/t/Test2/modules/API.t
+cpan/Test-Simple/t/Test2/modules/Event/Bail.t
+cpan/Test-Simple/t/Test2/modules/Event/Diag.t
+cpan/Test-Simple/t/Test2/modules/Event/Exception.t
+cpan/Test-Simple/t/Test2/modules/Event/Note.t
+cpan/Test-Simple/t/Test2/modules/Event/Ok.t
+cpan/Test-Simple/t/Test2/modules/Event/Plan.t
+cpan/Test-Simple/t/Test2/modules/Event/Skip.t
+cpan/Test-Simple/t/Test2/modules/Event/Subtest.t
+cpan/Test-Simple/t/Test2/modules/Event.t
+cpan/Test-Simple/t/Test2/modules/Event/Waiting.t
+cpan/Test-Simple/t/Test2/modules/Formatter/TAP.t
+cpan/Test-Simple/t/Test2/modules/Hub/Interceptor.t
+cpan/Test-Simple/t/Test2/modules/Hub/Interceptor/Terminator.t
+cpan/Test-Simple/t/Test2/modules/Hub/Subtest.t
+cpan/Test-Simple/t/Test2/modules/Hub.t
+cpan/Test-Simple/t/Test2/modules/IPC/Driver/Files.t
+cpan/Test-Simple/t/Test2/modules/IPC/Driver.t
+cpan/Test-Simple/t/Test2/modules/IPC.t
+cpan/Test-Simple/t/Test2/modules/Util/ExternalMeta.t
+cpan/Test-Simple/t/Test2/modules/Util/HashBase.t
+cpan/Test-Simple/t/Test2/modules/Util.t
+cpan/Test-Simple/t/Test2/modules/Util/Trace.t
+cpan/Test-Simple/t/Test2/regression/gh_16.t
+cpan/Test-Simple/t/Test2/regression/ipc_files_abort_exit.t
+cpan/Test-Simple/t/tools.pl
+cpan/Test-Simple/t/tools.t
 cpan/Text-Balanced/lib/Text/Balanced.pm        Text::Balanced
 cpan/Text-Balanced/t/01_compile.t      See if Text::Balanced works
 cpan/Text-Balanced/t/02_extbrk.t       See if Text::Balanced works
index 2a50977..f398359 100755 (executable)
@@ -1375,22 +1375,25 @@ _cleaner2:
        -rmdir lib/autodie/exception lib/autodie/Scope lib/autodie lib/XS
        -rmdir lib/Win32API lib/VMS lib/Unicode/Collate/Locale
        -rmdir lib/Unicode/Collate/CJK lib/Unicode/Collate lib/Tie/Hash
-       -rmdir lib/Thread lib/Text lib/Test/use lib/Test/Tester
-       -rmdir lib/Test/Builder/Tester lib/Test/Builder/IO lib/Test/Builder
-       -rmdir lib/Test lib/Term lib/TAP/Parser/YAMLish
-       -rmdir lib/TAP/Parser/SourceHandler lib/TAP/Parser/Scheduler
-       -rmdir lib/TAP/Parser/Result lib/TAP/Parser/Iterator lib/TAP/Parser
-       -rmdir lib/TAP/Harness lib/TAP/Formatter/File
-       -rmdir lib/TAP/Formatter/Console lib/TAP/Formatter lib/TAP
-       -rmdir lib/Sys/Syslog lib/Sys lib/Sub lib/Search lib/Scalar
-       -rmdir lib/Pod/Text lib/Pod/Simple lib/Pod/Perldoc lib/PerlIO/via
-       -rmdir lib/PerlIO lib/Perl lib/Parse/CPAN lib/Parse lib/Params
-       -rmdir lib/Net/FTP lib/Module/Load lib/Module/CoreList lib/Module
-       -rmdir lib/Memoize lib/Math/BigInt lib/Math/BigFloat lib/Math lib/MIME
-       -rmdir lib/Locale/Maketext lib/Locale/Codes lib/Locale lib/List/Util
-       -rmdir lib/List lib/JSON/PP lib/JSON lib/IPC lib/IO/Uncompress/Adapter
-       -rmdir lib/IO/Uncompress lib/IO/Socket lib/IO/Compress/Zlib
-       -rmdir lib/IO/Compress/Zip lib/IO/Compress/Gzip lib/IO/Compress/Base
+       -rmdir lib/Thread lib/Text lib/Test2/Util lib/Test2/IPC/Driver
+       -rmdir lib/Test2/IPC lib/Test2/Hub/Interceptor lib/Test2/Hub
+       -rmdir lib/Test2/Formatter lib/Test2/Event lib/Test2/API lib/Test2
+       -rmdir lib/Test/use lib/Test/Tester lib/Test/Builder/Tester
+       -rmdir lib/Test/Builder/IO lib/Test/Builder lib/Test lib/Term
+       -rmdir lib/TAP/Parser/YAMLish lib/TAP/Parser/SourceHandler
+       -rmdir lib/TAP/Parser/Scheduler lib/TAP/Parser/Result
+       -rmdir lib/TAP/Parser/Iterator lib/TAP/Parser lib/TAP/Harness
+       -rmdir lib/TAP/Formatter/File lib/TAP/Formatter/Console
+       -rmdir lib/TAP/Formatter lib/TAP lib/Sys/Syslog lib/Sys lib/Sub
+       -rmdir lib/Search lib/Scalar lib/Pod/Text lib/Pod/Simple
+       -rmdir lib/Pod/Perldoc lib/PerlIO/via lib/PerlIO lib/Perl
+       -rmdir lib/Parse/CPAN lib/Parse lib/Params lib/Net/FTP lib/Module/Load
+       -rmdir lib/Module/CoreList lib/Module lib/Memoize lib/Math/BigInt
+       -rmdir lib/Math/BigFloat lib/Math lib/MIME lib/Locale/Maketext
+       -rmdir lib/Locale/Codes lib/Locale lib/List/Util lib/List lib/JSON/PP
+       -rmdir lib/JSON lib/IPC lib/IO/Uncompress/Adapter lib/IO/Uncompress
+       -rmdir lib/IO/Socket lib/IO/Compress/Zlib lib/IO/Compress/Zip
+       -rmdir lib/IO/Compress/Gzip lib/IO/Compress/Base
        -rmdir lib/IO/Compress/Adapter lib/IO/Compress lib/IO
        -rmdir lib/I18N/LangTags lib/I18N lib/Hash/Util lib/Hash lib/HTTP
        -rmdir lib/Filter/Util lib/Filter lib/File/Spec lib/ExtUtils/Typemaps
index a8e7bd9..892d609 100644 (file)
@@ -4,8 +4,7 @@ use 5.006;
 use strict;
 use warnings;
 
-our $VERSION = '1.001014';
-$VERSION = eval $VERSION;    ## no critic (BuiltinFunctions::ProhibitStringyEval)
+our $VERSION = '1.302015';
 
 BEGIN {
     if( $] < 5.008 ) {
@@ -13,516 +12,404 @@ BEGIN {
     }
 }
 
+use overload();
 
+use Scalar::Util qw/blessed reftype weaken/;
+
+use Test2::Util qw/USE_THREADS try get_tid/;
+use Test2::API qw/context release/;
 # Make Test::Builder thread-safe for ithreads.
 BEGIN {
-    use Config;
-    # Load threads::shared when threads are turned on.
-    # 5.8.0's threads are so busted we no longer support them.
-    if( $] >= 5.008001 && $Config{useithreads} && $INC{'threads.pm'} ) {
-        require threads::shared;
-
-        # Hack around YET ANOTHER threads::shared bug.  It would
-        # occasionally forget the contents of the variable when sharing it.
-        # So we first copy the data, then share, then put our copy back.
-        *share = sub (\[$@%]) {
-            my $type = ref $_[0];
-            my $data;
-
-            if( $type eq 'HASH' ) {
-                %$data = %{ $_[0] };
-            }
-            elsif( $type eq 'ARRAY' ) {
-                @$data = @{ $_[0] };
-            }
-            elsif( $type eq 'SCALAR' ) {
-                $$data = ${ $_[0] };
-            }
-            else {
-                die( "Unknown type: " . $type );
-            }
-
-            $_[0] = &threads::shared::share( $_[0] );
-
-            if( $type eq 'HASH' ) {
-                %{ $_[0] } = %$data;
-            }
-            elsif( $type eq 'ARRAY' ) {
-                @{ $_[0] } = @$data;
-            }
-            elsif( $type eq 'SCALAR' ) {
-                ${ $_[0] } = $$data;
-            }
-            else {
-                die( "Unknown type: " . $type );
-            }
+    warn "Test::Builder was loaded after Test2 initialization, this is not recommended."
+        if Test2::API::test2_init_done() || Test2::API::test2_load_done();
 
-            return $_[0];
-        };
-    }
-    # 5.8.0's threads::shared is busted when threads are off
-    # and earlier Perls just don't have that module at all.
-    else {
-        *share = sub { return $_[0] };
-        *lock  = sub { 0 };
+    if (USE_THREADS) {
+        require Test2::IPC;
+        require Test2::IPC::Driver::Files;
+        Test2::IPC::Driver::Files->import;
+        Test2::API::test2_ipc_enable_polling();
+        Test2::API::test2_no_wait(1);
+        Test2::API::test2_ipc_enable_shm();
     }
 }
 
-=head1 NAME
-
-Test::Builder - Backend for building test libraries
+use Test2::Event::Subtest;
+use Test2::Hub::Subtest;
 
-=head1 SYNOPSIS
+use Test::Builder::Formatter;
+use Test::Builder::TodoDiag;
 
-  package My::Test::Module;
-  use base 'Test::Builder::Module';
+our $Level = 1;
+our $Test = Test::Builder->new;
 
-  my $CLASS = __PACKAGE__;
+# Non-TB tools normally expect 0 added to the level. $Level is normally 1. So
+# we only want the level to change if $Level != 1.
+# TB->ctx compensates for this later.
+Test2::API::test2_add_callback_context_aquire(sub {$_[0]->{level} += $Level - 1});
 
-  sub ok {
-      my($test, $name) = @_;
-      my $tb = $CLASS->builder;
+Test2::API::test2_add_callback_exit(sub { $Test->_ending(@_) });
 
-      $tb->ok($test, $name);
-  }
+Test2::API::test2_ipc()->set_no_fatal(1) if USE_THREADS;
 
+sub _add_ts_hooks {
+    my $self = shift;
+    my $hub = $self->{Stack}->top;
 
-=head1 DESCRIPTION
+    # Take a reference to the hash key, we do this to avoid closing over $self
+    # which is the singleton. We use a reference because the value could change
+    # in rare cases.
+    my $epkgr = \$self->{Exported_To};
 
-L<Test::Simple> and L<Test::More> have proven to be popular testing modules,
-but they're not always flexible enough.  Test::Builder provides a
-building block upon which to write your own test libraries I<which can
-work together>.
+    #$hub->add_context_aquire(sub {$_[0]->{level} += $Level - 1});
 
-=head2 Construction
+    $hub->filter(sub {
+        my ($active_hub, $e) = @_;
 
-=over 4
+        my $epkg = $$epkgr;
+        my $cpkg = $e->{trace} ? $e->{trace}->{frame}->[0] : undef;
 
-=item B<new>
+        no strict 'refs';
+        no warnings 'once';
+        my $todo;
+        $todo = ${"$cpkg\::TODO"} if $cpkg;
+        $todo = ${"$epkg\::TODO"} if $epkg && !$todo;
 
-  my $Test = Test::Builder->new;
+        return $e unless $todo;
 
-Returns a Test::Builder object representing the current state of the
-test.
 
-Since you only run one test per program C<new> always returns the same
-Test::Builder object.  No matter how many times you call C<new()>, you're
-getting the same object.  This is called a singleton.  This is done so that
-multiple modules share such global information as the test counter and
-where test output is going.
+        # Turn a diag into a todo diag
+        return Test::Builder::TodoDiag->new(%$e) if ref($e) eq 'Test2::Event::Diag';
 
-If you want a completely new Test::Builder object different from the
-singleton, use C<create>.
+        # Set todo on ok's
+        if ($hub == $active_hub && $e->isa('Test2::Event::Ok')) {
+            $e->set_todo($todo);
+            $e->set_effective_pass(1);
 
-=cut
+            if (my $result = $e->get_meta(__PACKAGE__)) {
+                $result->{reason} ||= $todo;
+                $result->{type}   ||= 'todo';
+                $result->{ok}       = 1;
+            }
+        }
 
-our $Test = Test::Builder->new;
+        return $e;
+    });
+}
 
 sub new {
     my($class) = shift;
-    $Test ||= $class->create;
+    unless($Test) {
+        my $ctx = context();
+        $Test = $class->create(singleton => 1);
+        $ctx->release;
+    }
     return $Test;
 }
 
-=item B<create>
-
-  my $Test = Test::Builder->create;
-
-Ok, so there can be more than one Test::Builder object and this is how
-you get it.  You might use this instead of C<new()> if you're testing
-a Test::Builder based module, but otherwise you probably want C<new>.
-
-B<NOTE>: the implementation is not complete.  C<level>, for example, is
-still shared amongst B<all> Test::Builder objects, even ones created using
-this method.  Also, the method name may change in the future.
-
-=cut
-
 sub create {
     my $class = shift;
+    my %params = @_;
 
     my $self = bless {}, $class;
-    $self->reset;
+    if ($params{singleton}) {
+        $self->{Stack} = Test2::API::test2_stack();
+    }
+    else {
+        $self->{Stack} = Test2::API::Stack->new;
+        $self->{Stack}->new_hub(
+            formatter => Test::Builder::Formatter->new,
+            ipc       => Test2::API::test2_ipc(),
+        );
+    }
+    $self->reset(%params);
+    $self->_add_ts_hooks;
 
     return $self;
 }
 
-
-# Copy an object, currently a shallow.
-# This does *not* bless the destination.  This keeps the destructor from
-# firing when we're just storing a copy of the object to restore later.
-sub _copy {
-    my($src, $dest) = @_;
-
-    %$dest = %$src;
-    _share_keys($dest);
-
-    return;
+sub ctx {
+    my $self = shift;
+    context(
+        # 1 for our frame, another for the -1 off of $Level in our hook at the top.
+        level   => 2,
+        fudge   => 1,
+        stack   => $self->{Stack},
+        hub     => $self->{Hub},
+        wrapped => 1,
+        @_
+    );
 }
 
+sub parent {
+    my $self = shift;
+    my $ctx = $self->ctx;
+    my $chub = $self->{Hub} || $ctx->hub;
+    $ctx->release;
 
-=item B<child>
-
-  my $child = $builder->child($name_of_child);
-  $child->plan( tests => 4 );
-  $child->ok(some_code());
-  ...
-  $child->finalize;
-
-Returns a new instance of C<Test::Builder>.  Any output from this child will
-be indented four spaces more than the parent's indentation.  When done, the
-C<finalize> method I<must> be called explicitly.
-
-Trying to create a new child with a previous child still active (i.e.,
-C<finalize> not called) will C<croak>.
+    my $parent = $chub->meta(__PACKAGE__, {})->{parent};
 
-Trying to run a test when you have an open child will also C<croak> and cause
-the test suite to fail.
+    return undef unless $parent;
 
-=cut
+    return bless {
+        Original_Pid => $$,
+        Stack => $self->{Stack},
+        Hub => $parent,
+    }, blessed($self);
+}
 
 sub child {
     my( $self, $name ) = @_;
 
-    if( $self->{Child_Name} ) {
-        $self->croak("You already have a child named ($self->{Child_Name}) running");
-    }
+    $name ||= "Child of " . $self->name;
+    my $ctx = $self->ctx;
 
-    my $parent_in_todo = $self->in_todo;
+    my $parent = $ctx->hub;
+    my $pmeta = $parent->meta(__PACKAGE__, {});
+    $self->croak("You already have a child named ($pmeta->{child}) running")
+        if $pmeta->{child};
+
+    $pmeta->{child} = $name;
 
     # Clear $TODO for the child.
     my $orig_TODO = $self->find_TODO(undef, 1, undef);
 
-    my $class = ref $self;
-    my $child = $class->create;
-
-    # Add to our indentation
-    $child->_indent( $self->_indent . '    ' );
+    my $subevents = [];
 
-    # Make the child use the same outputs as the parent
-    for my $method (qw(output failure_output todo_output)) {
-        $child->$method( $self->$method );
-    }
+    my $hub = $ctx->stack->new_hub(
+        class => 'Test2::Hub::Subtest',
+    );
 
-    # Ensure the child understands if they're inside a TODO
-    if( $parent_in_todo ) {
-        $child->failure_output( $self->todo_output );
-    }
+    $hub->filter(sub {
+        my ($active_hub, $e) = @_;
 
-    # This will be reset in finalize. We do this here lest one child failure
-    # cause all children to fail.
-    $child->{Child_Error} = $?;
-    $?                    = 0;
-    $child->{Parent}      = $self;
-    $child->{Parent_TODO} = $orig_TODO;
-    $child->{Name}        = $name || "Child of " . $self->name;
-    $self->{Child_Name}   = $child->name;
-    return $child;
-}
+        # Turn a diag into a todo diag
+        return Test::Builder::TodoDiag->new(%$e) if ref($e) eq 'Test2::Event::Diag';
 
+        return $e;
+    }) if $orig_TODO;
 
-=item B<subtest>
+    $hub->listen(sub { push @$subevents => $_[1] });
 
-    $builder->subtest($name, \&subtests, @args);
+    $hub->set_nested( $parent->isa('Test2::Hub::Subtest') ? $parent->nested + 1 : 1 );
 
-See documentation of C<subtest> in Test::More.  
+    my $meta = $hub->meta(__PACKAGE__, {});
+    $meta->{Name} = $name;
+    $meta->{TODO} = $orig_TODO;
+    $meta->{TODO_PKG} = $ctx->trace->package;
+    $meta->{parent} = $parent;
+    $meta->{Test_Results} = [];
+    $meta->{subevents} = $subevents;
+    $meta->{subtest_id} = $hub->id;
 
-C<subtest> also, and optionally, accepts arguments which will be passed to the
-subtests reference.
+    $self->_add_ts_hooks;
 
-=cut
+    $ctx->release;
+    return bless { Original_Pid => $$, Stack => $self->{Stack}, Hub => $hub }, blessed($self);
+}
 
-sub subtest {
+sub finalize {
     my $self = shift;
-    my($name, $subtests, @args) = @_;
-
-    if ('CODE' ne ref $subtests) {
-        $self->croak("subtest()'s second argument must be a code ref");
-    }
-
-    # Turn the child into the parent so anyone who has stored a copy of
-    # the Test::Builder singleton will get the child.
-    my $error;
-    my $child;
-    my $parent = {};
-    {
-        # child() calls reset() which sets $Level to 1, so we localize
-        # $Level first to limit the scope of the reset to the subtest.
-        local $Test::Builder::Level = $Test::Builder::Level + 1;
+    my $ok = 1;
+    ($ok) = @_ if @_;
 
-        # Store the guts of $self as $parent and turn $child into $self.
-        $child  = $self->child($name);
-        _copy($self,  $parent);
-        _copy($child, $self);
-
-        my $run_the_subtests = sub {
-            # Add subtest name for clarification of starting point
-            $self->note("Subtest: $name");
-            $subtests->(@args);
-            $self->done_testing unless $self->_plan_handled;
-            1;
-        };
+    my $st_ctx = $self->ctx;
+    my $chub = $self->{Hub} || return $st_ctx->release;
 
-        if( !eval { $run_the_subtests->() } ) {
-            $error = $@;
-        }
+    my $meta = $chub->meta(__PACKAGE__, {});
+    if ($meta->{child}) {
+        $self->croak("Can't call finalize() with child ($meta->{child}) active");
     }
 
-    # Restore the parent and the copied child.
-    _copy($self,   $child);
-    _copy($parent, $self);
-
-    # Restore the parent's $TODO
-    $self->find_TODO(undef, 1, $child->{Parent_TODO});
-
-    # Die *after* we restore the parent.
-    die $error if $error and !eval { $error->isa('Test::Builder::Exception') };
-
-    local $Test::Builder::Level = $Test::Builder::Level + 1;
-    my $finalize = $child->finalize;
-
-    $self->BAIL_OUT($child->{Bailed_Out_Reason}) if $child->{Bailed_Out};
-
-    return $finalize;
-}
-
-=begin _private
-
-=item B<_plan_handled>
-
-    if ( $Test->_plan_handled ) { ... }
-
-Returns true if the developer has explicitly handled the plan via:
-
-=over 4
-
-=item * Explicitly setting the number of tests
-
-=item * Setting 'no_plan'
-
-=item * Set 'skip_all'.
-
-=back
-
-This is currently used in subtests when we implicitly call C<< $Test->done_testing >>
-if the developer has not set a plan.
-
-=end _private
-
-=cut
-
-sub _plan_handled {
-    my $self = shift;
-    return $self->{Have_Plan} || $self->{No_Plan} || $self->{Skip_All};
-}
-
-
-=item B<finalize>
+    local $? = 0;     # don't fail if $subtests happened to set $? nonzero
 
-  my $ok = $child->finalize;
+    $self->{Stack}->pop($chub);
 
-When your child is done running tests, you must call C<finalize> to clean up
-and tell the parent your pass/fail status.
+    $self->find_TODO($meta->{TODO_PKG}, 1, $meta->{TODO});
 
-Calling C<finalize> on a child with open children will C<croak>.
+    my $parent = $self->parent;
+    my $ctx = $parent->ctx;
+    my $trace = $ctx->trace;
+    delete $ctx->hub->meta(__PACKAGE__, {})->{child};
 
-If the child falls out of scope before C<finalize> is called, a failure
-diagnostic will be issued and the child is considered to have failed.
+    $chub->finalize($trace, 1)
+        if $ok
+        && $chub->count
+        && !$chub->no_ending
+        && !$chub->ended;
 
-No attempt to call methods on a child after C<finalize> is called is
-guaranteed to succeed.
+    my $plan   = $chub->plan || 0;
+    my $count  = $chub->count;
+    my $failed = $chub->failed;
 
-Calling this on the root builder is a no-op.
+    my $num_extra = $plan =~ m/\D/ ? 0 : $count - $plan;
+    if ($count && $num_extra != 0) {
+        my $s = $plan == 1 ? '' : 's';
+        $st_ctx->diag(<<"FAIL");
+Looks like you planned $plan test$s but ran $count.
+FAIL
+    }
 
-=cut
+    if ($failed) {
+        my $s = $failed == 1 ? '' : 's';
 
-sub finalize {
-    my $self = shift;
+        my $qualifier = $num_extra == 0 ? '' : ' run';
 
-    return unless $self->parent;
-    if( $self->{Child_Name} ) {
-        $self->croak("Can't call finalize() with child ($self->{Child_Name}) active");
+        $st_ctx->diag(<<"FAIL");
+Looks like you failed $failed test$s of $count$qualifier.
+FAIL
     }
 
-    local $? = 0;     # don't fail if $subtests happened to set $? nonzero
-    $self->_ending;
-
-    # XXX This will only be necessary for TAP envelopes (we think)
-    #$self->_print( $self->is_passing ? "PASS\n" : "FAIL\n" );
+    $st_ctx->release;
 
-    local $Test::Builder::Level = $Test::Builder::Level + 1;
-    my $ok = 1;
-    $self->parent->{Child_Name} = undef;
-    unless ($self->{Bailed_Out}) {
-        if ( $self->{Skip_All} ) {
-            $self->parent->skip($self->{Skip_All}, $self->name);
+    unless ($chub->bailed_out) {
+        my $plan = $chub->plan;
+        if ( $plan && $plan eq 'SKIP' ) {
+            $parent->skip($chub->skip_reason, $meta->{Name});
         }
-        elsif ( not @{ $self->{Test_Results} } ) {
-            $self->parent->ok( 0, sprintf q[No tests run for subtest "%s"], $self->name );
+        elsif ( !$chub->count ) {
+            $parent->ok( 0, sprintf q[No tests run for subtest "%s"], $meta->{Name} );
         }
         else {
-            $self->parent->ok( $self->is_passing, $self->name );
+            $parent->{subevents}  = $meta->{subevents};
+            $parent->{subtest_id} = $meta->{subtest_id};
+            $parent->ok( $chub->is_passing, $meta->{Name} );
         }
     }
-    $? = $self->{Child_Error};
-    delete $self->{Parent};
 
-    return $self->is_passing;
+    $ctx->release;
+    return $chub->is_passing;
 }
 
-sub _indent      {
+sub subtest {
     my $self = shift;
-
-    if( @_ ) {
-        $self->{Indent} = shift;
+    my ($name, $code, @args) = @_;
+    my $ctx = $self->ctx;
+    $ctx->throw("subtest()'s second argument must be a code ref")
+        unless $code && reftype($code) eq 'CODE';
+
+    $name ||= "Child of " . $self->name;
+
+    $ctx->note("Subtest: $name");
+
+    my $child = $self->child($name);
+
+    my $start_pid = $$;
+    my $st_ctx;
+    my ($ok, $err, $finished, $child_error);
+    T2_SUBTEST_WRAPPER: {
+        my $ctx = $self->ctx;
+        $st_ctx = $ctx->snapshot;
+        $ctx->release;
+        $ok = eval { local $Level = 1; $code->(@args); 1 };
+        ($err, $child_error) = ($@, $?);
+
+        # They might have done 'BEGIN { skip_all => "whatever" }'
+        if (!$ok && $err =~ m/Label not found for "last T2_SUBTEST_WRAPPER"/) {
+            $ok  = undef;
+            $err = undef;
+        }
+        else {
+            $finished = 1;
+        }
     }
 
-    return $self->{Indent};
-}
-
-=item B<parent>
+    if ($start_pid != $$ && !$INC{'Test/Sync/IPC.pm'}) {
+        warn $ok ? "Forked inside subtest, but subtest never finished!\n" : $err;
+        exit 255;
+    }
 
- if ( my $parent = $builder->parent ) {
-     ...
- }
+    my $trace = $ctx->trace;
 
-Returns the parent C<Test::Builder> instance, if any.  Only used with child
-builders for nested TAP.
+    if (!$finished) {
+        if(my $bailed = $st_ctx->hub->bailed_out) {
+            my $chub = $child->{Hub};
+            $self->{Stack}->pop($chub);
+            $ctx->bail($bailed->reason);
+        }
+        my $code = $st_ctx->hub->exit_code;
+        $ok = !$code;
+        $err = "Subtest ended with exit code $code" if $code;
+    }
 
-=cut
+    my $st_hub  = $st_ctx->hub;
+    my $plan  = $st_hub->plan;
+    my $count = $st_hub->count;
 
-sub parent { shift->{Parent} }
+    if (!$count && (!defined($plan) || "$plan" ne 'SKIP')) {
+        $st_ctx->plan(0) unless defined $plan;
+        $st_ctx->diag('No tests run!');
+    }
 
-=item B<name>
+    $child->finalize($ok);
 
diag $builder->name;
   $ctx->release;
 
-Returns the name of the current builder.  Top level builders default to C<$0>
-(the name of the executable).  Child builders are named via the C<child>
-method.  If no name is supplied, will be named "Child of $parent->name".
+    die $err unless $ok;
 
-=cut
+    $? = $child_error if defined $child_error;
 
-sub name { shift->{Name} }
+    return $st_hub->is_passing;
+}
 
-sub DESTROY {
+sub name {
     my $self = shift;
-    if ( $self->parent and $$ == $self->{Original_Pid} ) {
-        my $name = $self->name;
-        $self->diag(<<"FAIL");
-Child ($name) exited without calling finalize()
-FAIL
-        $self->parent->{In_Destroy} = 1;
-        $self->parent->ok(0, $name);
-    }
+    my $ctx = $self->ctx;
+    release $ctx, $ctx->hub->meta(__PACKAGE__, {})->{Name};
 }
 
-=item B<reset>
-
-  $Test->reset;
-
-Reinitializes the Test::Builder singleton to its original state.
-Mostly useful for tests run in persistent environments where the same
-test might be run multiple times in the same process.
-
-=cut
-
-our $Level;
-
 sub reset {    ## no critic (Subroutines::ProhibitBuiltinHomonyms)
-    my($self) = @_;
+    my ($self, %params) = @_;
+
+    Test2::API::test2_set_is_end(0);
 
     # We leave this a global because it has to be localized and localizing
     # hash keys is just asking for pain.  Also, it was documented.
     $Level = 1;
 
-    $self->{Name}         = $0;
-    $self->is_passing(1);
-    $self->{Ending}       = 0;
-    $self->{Have_Plan}    = 0;
-    $self->{No_Plan}      = 0;
-    $self->{Have_Output_Plan} = 0;
-    $self->{Done_Testing} = 0;
-
     $self->{Original_Pid} = $$;
-    $self->{Child_Name}   = undef;
-    $self->{Indent}     ||= '';
-
-    $self->{Curr_Test} = 0;
-    $self->{Test_Results} = &share( [] );
-
-    $self->{Exported_To}    = undef;
-    $self->{Expected_Tests} = 0;
 
-    $self->{Skip_All} = 0;
-
-    $self->{Use_Nums} = 1;
-
-    $self->{No_Header} = 0;
-    $self->{No_Ending} = 0;
-
-    $self->{Todo}       = undef;
-    $self->{Todo_Stack} = [];
-    $self->{Start_Todo} = 0;
-    $self->{Opened_Testhandles} = 0;
+    my $ctx = $self->ctx;
+    unless ($params{singleton}) {
+        $ctx->hub->reset_state();
+        $ctx->hub->set_pid($$);
+        $ctx->hub->set_tid(get_tid);
+    }
 
-    $self->_share_keys;
-    $self->_dup_stdhandles;
+    my $meta = $ctx->hub->meta(__PACKAGE__, {});
+    %$meta = (
+        Name         => $0,
+        Ending       => 0,
+        Done_Testing => undef,
+        Skip_All     => 0,
+        Test_Results => [],
+    );
 
-    return;
-}
+    $self->{Exported_To} = undef;
 
+    $self->{Orig_Handles} ||= do {
+        my $format = $ctx->hub->format;
+        my $out;
+        if ($format && $format->isa('Test2::Formatter::TAP')) {
+            $out = $format->handles;
+        }
+        $out ? [@$out] : [];
+    };
 
-# Shared scalar values are lost when a hash is copied, so we have
-# a separate method to restore them.
-# Shared references are retained across copies.
-sub _share_keys {
-    my $self = shift;
+    $self->use_numbers(1);
+    $self->no_header(0);
+    $self->no_ending(0);
+    $self->reset_outputs;
 
-    share( $self->{Curr_Test} );
+    $ctx->release;
 
     return;
 }
 
 
-=back
-
-=head2 Setting up tests
-
-These methods are for setting up tests and declaring how many there
-are.  You usually only want to call one of these methods.
-
-=over 4
-
-=item B<plan>
-
-  $Test->plan('no_plan');
-  $Test->plan( skip_all => $reason );
-  $Test->plan( tests => $num_tests );
-
-A convenient way to set up your tests.  Call this and Test::Builder
-will print the appropriate headers and take the appropriate actions.
-
-If you call C<plan()>, don't call any of the other methods below.
-
-If a child calls "skip_all" in the plan, a C<Test::Builder::Exception> is
-thrown.  Trap this error, call C<finalize()> and don't run any more tests on
-the child.
-
- my $child = $Test->child('some child');
- eval { $child->plan( $condition ? ( skip_all => $reason ) : ( tests => 3 )  ) };
- if ( eval { $@->isa('Test::Builder::Exception') } ) {
-    $child->finalize;
-    return;
- }
- # run your tests
-
-=cut
-
 my %plan_cmds = (
-    no_plan     => \&no_plan,
-    skip_all    => \&skip_all,
-    tests       => \&_plan_tests,
+    no_plan  => \&no_plan,
+    skip_all => \&skip_all,
+    tests    => \&_plan_tests,
 );
 
 sub plan {
@@ -530,9 +417,12 @@ sub plan {
 
     return unless $cmd;
 
-    local $Level = $Level + 1;
+    my $ctx = $self->ctx;
+    my $hub = $ctx->hub;
 
-    $self->croak("You tried to plan twice") if $self->{Have_Plan};
+    $ctx->throw("You tried to plan twice") if $hub->plan;
+
+    local $Level = $Level + 1;
 
     if( my $method = $plan_cmds{$cmd} ) {
         local $Level = $Level + 1;
@@ -540,241 +430,150 @@ sub plan {
     }
     else {
         my @args = grep { defined } ( $cmd, $arg );
-        $self->croak("plan() doesn't understand @args");
+        $ctx->throw("plan() doesn't understand @args");
     }
 
-    return 1;
+    release $ctx, 1;
 }
 
 
 sub _plan_tests {
     my($self, $arg) = @_;
 
+    my $ctx = $self->ctx;
+
     if($arg) {
         local $Level = $Level + 1;
-        return $self->expected_tests($arg);
+        $self->expected_tests($arg);
     }
     elsif( !defined $arg ) {
-        $self->croak("Got an undefined number of tests");
+        $ctx->throw("Got an undefined number of tests");
     }
     else {
-        $self->croak("You said to run 0 tests");
+        $ctx->throw("You said to run 0 tests");
     }
 
-    return;
+    $ctx->release;
 }
 
-=item B<expected_tests>
-
-    my $max = $Test->expected_tests;
-    $Test->expected_tests($max);
-
-Gets/sets the number of tests we expect this test to run and prints out
-the appropriate headers.
-
-=cut
 
 sub expected_tests {
     my $self = shift;
     my($max) = @_;
 
+    my $ctx = $self->ctx;
+
     if(@_) {
         $self->croak("Number of tests must be a positive integer.  You gave it '$max'")
           unless $max =~ /^\+?\d+$/;
 
-        $self->{Expected_Tests} = $max;
-        $self->{Have_Plan}      = 1;
-
-        $self->_output_plan($max) unless $self->no_header;
+        $ctx->plan($max);
     }
-    return $self->{Expected_Tests};
-}
 
-=item B<no_plan>
+    my $hub = $ctx->hub;
 
-  $Test->no_plan;
+    $ctx->release;
 
-Declares that this test will run an indeterminate number of tests.
+    my $plan = $hub->plan;
+    return 0 unless $plan;
+    return 0 if $plan =~ m/\D/;
+    return $plan;
+}
 
-=cut
 
 sub no_plan {
     my($self, $arg) = @_;
 
-    $self->carp("no_plan takes no arguments") if $arg;
+    my $ctx = $self->ctx;
 
-    $self->{No_Plan}   = 1;
-    $self->{Have_Plan} = 1;
+    $ctx->alert("no_plan takes no arguments") if $arg;
 
-    return 1;
-}
+    $ctx->hub->plan('NO PLAN');
 
-=begin private
+    release $ctx, 1;
+}
 
-=item B<_output_plan>
 
-  $tb->_output_plan($max);
-  $tb->_output_plan($max, $directive);
-  $tb->_output_plan($max, $directive => $reason);
+sub done_testing {
+    my($self, $num_tests) = @_;
 
-Handles displaying the test plan.
+    my $ctx = $self->ctx;
 
-If a C<$directive> and/or C<$reason> are given they will be output with the
-plan.  So here's what skipping all tests looks like:
+    my $meta = $ctx->hub->meta(__PACKAGE__, {});
 
-    $tb->_output_plan(0, "SKIP", "Because I said so");
+    if ($meta->{Done_Testing}) {
+        my ($file, $line) = @{$meta->{Done_Testing}}[1,2];
+        local $ctx->hub->{ended}; # OMG This is awful.
+        $self->ok(0, "done_testing() was already called at $file line $line");
+        $ctx->release;
+        return;
+    }
+    $meta->{Done_Testing} = [$ctx->trace->call];
 
-It sets C<< $tb->{Have_Output_Plan} >> and will croak if the plan was already
-output.
+    my $plan = $ctx->hub->plan;
+    my $count = $ctx->hub->count;
 
-=end private
-
-=cut
-
-sub _output_plan {
-    my($self, $max, $directive, $reason) = @_;
-
-    $self->carp("The plan was already output") if $self->{Have_Output_Plan};
-
-    my $plan = "1..$max";
-    $plan .= " # $directive" if defined $directive;
-    $plan .= " $reason"      if defined $reason;
-
-    $self->_print("$plan\n");
-
-    $self->{Have_Output_Plan} = 1;
-
-    return;
-}
-
-
-=item B<done_testing>
-
-  $Test->done_testing();
-  $Test->done_testing($num_tests);
-
-Declares that you are done testing, no more tests will be run after this point.
-
-If a plan has not yet been output, it will do so.
-
-$num_tests is the number of tests you planned to run.  If a numbered
-plan was already declared, and if this contradicts, a failing test
-will be run to reflect the planning mistake.  If C<no_plan> was declared,
-this will override.
-
-If C<done_testing()> is called twice, the second call will issue a
-failing test.
-
-If C<$num_tests> is omitted, the number of tests run will be used, like
-no_plan.
-
-C<done_testing()> is, in effect, used when you'd want to use C<no_plan>, but
-safer. You'd use it like so:
-
-    $Test->ok($a == $b);
-    $Test->done_testing();
-
-Or to plan a variable number of tests:
-
-    for my $test (@tests) {
-        $Test->ok($test);
-    }
-    $Test->done_testing(scalar @tests);
-
-=cut
-
-sub done_testing {
-    my($self, $num_tests) = @_;
-
-    # If done_testing() specified the number of tests, shut off no_plan.
+    # If done_testing() specified the number of tests, shut off no_plan
     if( defined $num_tests ) {
-        $self->{No_Plan} = 0;
+        $ctx->plan($num_tests) if !$plan || $plan eq 'NO PLAN';
+    }
+    elsif ($count && defined $num_tests && $count != $num_tests) {
+        $self->ok(0, "planned to run @{[ $self->expected_tests ]} but done_testing() expects $num_tests");
     }
     else {
         $num_tests = $self->current_test;
     }
 
-    if( $self->{Done_Testing} ) {
-        my($file, $line) = @{$self->{Done_Testing}}[1,2];
-        $self->ok(0, "done_testing() was already called at $file line $line");
-        return;
-    }
-
-    $self->{Done_Testing} = [caller];
-
     if( $self->expected_tests && $num_tests != $self->expected_tests ) {
         $self->ok(0, "planned to run @{[ $self->expected_tests ]} ".
                      "but done_testing() expects $num_tests");
     }
-    else {
-        $self->{Expected_Tests} = $num_tests;
-    }
-
-    $self->_output_plan($num_tests) unless $self->{Have_Output_Plan};
-
-    $self->{Have_Plan} = 1;
 
-    # The wrong number of tests were run
-    $self->is_passing(0) if $self->{Expected_Tests} != $self->{Curr_Test};
+    $ctx->plan($num_tests) if $ctx->hub->plan && $ctx->hub->plan eq 'NO PLAN';
 
-    # No tests were run
-    $self->is_passing(0) if $self->{Curr_Test} == 0;
+    $ctx->hub->finalize($ctx->trace, 1);
 
-    return 1;
+    release $ctx, 1;
 }
 
 
-=item B<has_plan>
-
-  $plan = $Test->has_plan
-
-Find out whether a plan has been defined. C<$plan> is either C<undef> (no plan
-has been set), C<no_plan> (indeterminate # of tests) or an integer (the number
-of expected tests).
-
-=cut
-
 sub has_plan {
     my $self = shift;
 
-    return( $self->{Expected_Tests} ) if $self->{Expected_Tests};
-    return('no_plan') if $self->{No_Plan};
+    my $ctx = $self->ctx;
+    my $plan = $ctx->hub->plan;
+    $ctx->release;
+
+    return( $plan ) if $plan && $plan !~ m/\D/;
+    return('no_plan') if $plan && $plan eq 'NO PLAN';
     return(undef);
 }
 
-=item B<skip_all>
-
-  $Test->skip_all;
-  $Test->skip_all($reason);
-
-Skips all the tests, using the given C<$reason>.  Exits immediately with 0.
-
-=cut
 
 sub skip_all {
     my( $self, $reason ) = @_;
 
-    $self->{Skip_All} = $self->parent ? $reason : 1;
+    my $ctx = $self->ctx;
 
-    $self->_output_plan(0, "SKIP", $reason) unless $self->no_header;
-    if ( $self->parent ) {
-        die bless {} => 'Test::Builder::Exception';
-    }
-    exit(0);
-}
-
-=item B<exported_to>
+    $ctx->hub->meta(__PACKAGE__, {})->{Skip_All} = $reason || 1;
 
-  my $pack = $Test->exported_to;
-  $Test->exported_to($pack);
-
-Tells Test::Builder what package you exported your functions to.
+    # Work around old perl bug
+    if ($] < 5.020000) {
+        my $begin = 0;
+        my $level = 0;
+        while (my @call = caller($level++)) {
+            last unless @call && $call[0];
+            next unless $call[3] =~ m/::BEGIN$/;
+            $begin++;
+            last;
+        }
+        # HACK!
+        die 'Label not found for "last T2_SUBTEST_WRAPPER"' if $begin && $ctx->hub->meta(__PACKAGE__, {})->{parent};
+    }
 
-This method isn't terribly useful since modules which share the same
-Test::Builder object might get exported to different packages and only
-the last one will be honored.
+    $ctx->plan(0, SKIP => $reason);
+}
 
-=cut
 
 sub exported_to {
     my( $self, $pack ) = @_;
@@ -785,171 +584,126 @@ sub exported_to {
     return $self->{Exported_To};
 }
 
-=back
-
-=head2 Running tests
-
-These actually run the tests, analogous to the functions in Test::More.
-
-They all return true if the test passed, false if the test failed.
-
-C<$name> is always optional.
-
-=over 4
-
-=item B<ok>
-
-  $Test->ok($test, $name);
-
-Your basic test.  Pass if C<$test> is true, fail if $test is false.  Just
-like Test::Simple's C<ok()>.
-
-=cut
 
 sub ok {
     my( $self, $test, $name ) = @_;
 
-    if ( $self->{Child_Name} and not $self->{In_Destroy} ) {
-        $name = 'unnamed test' unless defined $name;
-        $self->is_passing(0);
-        $self->croak("Cannot run test ($name) with active children");
-    }
+    my $ctx = $self->ctx;
+
     # $test might contain an object which we don't want to accidentally
     # store, so we turn it into a boolean.
     $test = $test ? 1 : 0;
 
-    lock $self->{Curr_Test};
-    $self->{Curr_Test}++;
-
     # In case $name is a string overloaded object, force it to stringify.
-    $self->_unoverload_str( \$name );
+    no  warnings qw/uninitialized numeric/;
+    $name = "$name" if defined $name;
 
-    $self->diag(<<"ERR") if defined $name and $name =~ /^[\d\s]+$/;
+    # Profiling showed that the regex here was a huge time waster, doing the
+    # numeric addition first cuts our profile time from ~300ms to ~50ms
+    $self->diag(<<"    ERR") if 0 + $name && $name =~ /^[\d\s]+$/;
     You named your test '$name'.  You shouldn't use numbers for your test names.
     Very confusing.
-ERR
-
-    # Capture the value of $TODO for the rest of this ok() call
-    # so it can more easily be found by other routines.
-    my $todo    = $self->todo();
-    my $in_todo = $self->in_todo;
-    local $self->{Todo} = $todo if $in_todo;
-
-    $self->_unoverload_str( \$todo );
-
-    my $out;
-    my $result = &share( {} );
-
-    unless($test) {
-        $out .= "not ";
-        @$result{ 'ok', 'actual_ok' } = ( ( $self->in_todo ? 1 : 0 ), 0 );
-    }
-    else {
-        @$result{ 'ok', 'actual_ok' } = ( 1, $test );
-    }
-
-    $out .= "ok";
-    $out .= " $self->{Curr_Test}" if $self->use_numbers;
-
-    if( defined $name ) {
-        $name =~ s|#|\\#|g;    # # in a name can confuse Test::Harness.
-        $out .= " - $name";
-        $result->{name} = $name;
-    }
-    else {
-        $result->{name} = '';
-    }
-
-    if( $self->in_todo ) {
-        $out .= " # TODO $todo";
-        $result->{reason} = $todo;
-        $result->{type}   = 'todo';
-    }
-    else {
-        $result->{reason} = '';
-        $result->{type}   = '';
-    }
+    ERR
+    use warnings qw/uninitialized numeric/;
+
+    my $trace = $ctx->{trace};
+    my $hub   = $ctx->{hub};
+
+    my $result = {
+        ok => $test,
+        actual_ok => $test,
+        reason => '',
+        type => '',
+        (name => defined($name) ? $name : ''),
+    };
 
-    $self->{Test_Results}[ $self->{Curr_Test} - 1 ] = $result;
-    $out .= "\n";
+    $hub->{_meta}->{+__PACKAGE__}->{Test_Results}[ $hub->{count} ] = $result;
 
-    $self->_print($out);
+    my $orig_name = $name;
 
-    unless($test) {
-        my $msg = $self->in_todo ? "Failed (TODO)" : "Failed";
-        $self->_print_to_fh( $self->_diag_fh, "\n" ) if $ENV{HARNESS_ACTIVE};
+    # The regex form is ~250ms, the index form is ~50ms
+    #$name && $name =~ m/(?:#|\n)/ && ($name =~ s|#|\\#|g, $name =~ s{\n}{\n# }sg);
+    $name && (
+        (index($name, "#" ) >= 0 && $name =~ s|#|\\#|g),
+        (index($name, "\n") >= 0 && $name =~ s{\n}{\n# }sg)
+    );
 
-        my( undef, $file, $line ) = $self->caller;
-        if( defined $name ) {
-            $self->diag(qq[  $msg test '$name'\n]);
-            $self->diag(qq[  at $file line $line.\n]);
-        }
-        else {
-            $self->diag(qq[  $msg test at $file line $line.\n]);
-        }
+    my @attrs;
+    my $subevents  = delete $self->{subevents};
+    my $subtest_id = delete $self->{subtest_id};
+    my $epkg = 'Test2::Event::Ok';
+    if ($subevents) {
+        $epkg = 'Test2::Event::Subtest';
+        push @attrs => (subevents => $subevents, subtest_id => $subtest_id);
     }
 
-    $self->is_passing(0) unless $test || $self->in_todo;
+    my $e = bless {
+        trace => bless( {%$trace}, 'Test2::Util::Trace'),
+        pass  => $test,
+        name  => $name,
+        _meta => {'Test::Builder' => $result},
+        effective_pass => $test,
+        @attrs,
+    }, $epkg;
+    $hub->send($e);
 
-    # Check that we haven't violated the plan
-    $self->_check_is_passing_plan();
+    $self->_ok_debug($trace, $orig_name) unless($test);
 
-    return $test ? 1 : 0;
+    $ctx->release;
+    return $test;
 }
 
-
-# Check that we haven't yet violated the plan and set
-# is_passing() accordingly
-sub _check_is_passing_plan {
+sub _ok_debug {
     my $self = shift;
+    my ($trace, $orig_name) = @_;
 
-    my $plan = $self->has_plan;
-    return unless defined $plan;        # no plan yet defined
-    return unless $plan !~ /\D/;        # no numeric plan
-    $self->is_passing(0) if $plan < $self->{Curr_Test};
-}
-
+    my $is_todo = defined($self->todo);
 
-sub _unoverload {
-    my $self = shift;
-    my $type = shift;
+    my $msg = $is_todo ? "Failed (TODO)" : "Failed";
 
-    $self->_try(sub { require overload; }, die_on_fail => 1);
+    my $dfh = $self->_diag_fh;
+    print $dfh "\n" if $ENV{HARNESS_ACTIVE} && $dfh;
 
-    foreach my $thing (@_) {
-        if( $self->_is_object($$thing) ) {
-            if( my $string_meth = overload::Method( $$thing, $type ) ) {
-                $$thing = $$thing->$string_meth();
-            }
-        }
+    my (undef, $file, $line) = $trace->call;
+    if (defined $orig_name) {
+        $self->diag(qq[  $msg test '$orig_name'\n]);
+        $self->diag(qq[  at $file line $line.\n]);
+    }
+    else {
+        $self->diag(qq[  $msg test at $file line $line.\n]);
     }
+}
 
-    return;
+sub _diag_fh {
+    my $self = shift;
+    local $Level = $Level + 1;
+    return $self->in_todo ? $self->todo_output : $self->failure_output;
 }
 
-sub _is_object {
-    my( $self, $thing ) = @_;
+sub _unoverload {
+    my ($self, $type, $thing) = @_;
 
-    return $self->_try( sub { ref $thing && $thing->isa('UNIVERSAL') } ) ? 1 : 0;
+    return unless ref $$thing;
+    return unless blessed($$thing) || scalar $self->_try(sub{ $$thing->isa('UNIVERSAL') });
+    my $string_meth = overload::Method( $$thing, $type ) || return;
+    $$thing = $$thing->$string_meth();
 }
 
 sub _unoverload_str {
     my $self = shift;
 
-    return $self->_unoverload( q[""], @_ );
+    $self->_unoverload( q[""], $_ ) for @_;
 }
 
 sub _unoverload_num {
     my $self = shift;
 
-    $self->_unoverload( '0+', @_ );
+    $self->_unoverload( '0+', $_ ) for @_;
 
     for my $val (@_) {
         next unless $self->_is_dualvar($$val);
         $$val = $$val + 0;
     }
-
-    return;
 }
 
 # This is a hack to detect a dualvar such as $!
@@ -964,28 +718,12 @@ sub _is_dualvar {
     return ($numval != 0 and $numval ne $val ? 1 : 0);
 }
 
-=item B<is_eq>
-
-  $Test->is_eq($got, $expected, $name);
-
-Like Test::More's C<is()>.  Checks if C<$got eq $expected>.  This is the
-string version.
-
-C<undef> only ever matches another C<undef>.
-
-=item B<is_num>
-
-  $Test->is_num($got, $expected, $name);
-
-Like Test::More's C<is()>.  Checks if C<$got == $expected>.  This is the
-numeric version.
-
-C<undef> only ever matches another C<undef>.
-
-=cut
 
 sub is_eq {
     my( $self, $got, $expect, $name ) = @_;
+
+    my $ctx = $self->ctx;
+
     local $Level = $Level + 1;
 
     if( !defined $got || !defined $expect ) {
@@ -994,14 +732,17 @@ sub is_eq {
 
         $self->ok( $test, $name );
         $self->_is_diag( $got, 'eq', $expect ) unless $test;
+        $ctx->release;
         return $test;
     }
 
-    return $self->cmp_ok( $got, 'eq', $expect, $name );
+    release $ctx, $self->cmp_ok( $got, 'eq', $expect, $name );
 }
 
+
 sub is_num {
     my( $self, $got, $expect, $name ) = @_;
+    my $ctx = $self->ctx;
     local $Level = $Level + 1;
 
     if( !defined $got || !defined $expect ) {
@@ -1010,12 +751,14 @@ sub is_num {
 
         $self->ok( $test, $name );
         $self->_is_diag( $got, '==', $expect ) unless $test;
+        $ctx->release;
         return $test;
     }
 
-    return $self->cmp_ok( $got, '==', $expect, $name );
+    release $ctx, $self->cmp_ok( $got, '==', $expect, $name );
 }
 
+
 sub _diag_fmt {
     my( $self, $type, $val ) = @_;
 
@@ -1036,6 +779,7 @@ sub _diag_fmt {
     return;
 }
 
+
 sub _is_diag {
     my( $self, $got, $type, $expect ) = @_;
 
@@ -1061,24 +805,10 @@ sub _isnt_diag {
 DIAGNOSTIC
 }
 
-=item B<isnt_eq>
-
-  $Test->isnt_eq($got, $dont_expect, $name);
-
-Like L<Test::More>'s C<isnt()>.  Checks if C<$got ne $dont_expect>.  This is
-the string version.
-
-=item B<isnt_num>
-
-  $Test->isnt_num($got, $dont_expect, $name);
-
-Like L<Test::More>'s C<isnt()>.  Checks if C<$got ne $dont_expect>.  This is
-the numeric version.
-
-=cut
 
 sub isnt_eq {
     my( $self, $got, $dont_expect, $name ) = @_;
+    my $ctx = $self->ctx;
     local $Level = $Level + 1;
 
     if( !defined $got || !defined $dont_expect ) {
@@ -1087,14 +817,16 @@ sub isnt_eq {
 
         $self->ok( $test, $name );
         $self->_isnt_diag( $got, 'ne' ) unless $test;
+        $ctx->release;
         return $test;
     }
 
-    return $self->cmp_ok( $got, 'ne', $dont_expect, $name );
+    release $ctx, $self->cmp_ok( $got, 'ne', $dont_expect, $name );
 }
 
 sub isnt_num {
     my( $self, $got, $dont_expect, $name ) = @_;
+    my $ctx = $self->ctx;
     local $Level = $Level + 1;
 
     if( !defined $got || !defined $dont_expect ) {
@@ -1103,52 +835,32 @@ sub isnt_num {
 
         $self->ok( $test, $name );
         $self->_isnt_diag( $got, '!=' ) unless $test;
+        $ctx->release;
         return $test;
     }
 
-    return $self->cmp_ok( $got, '!=', $dont_expect, $name );
+    release $ctx, $self->cmp_ok( $got, '!=', $dont_expect, $name );
 }
 
-=item B<like>
-
-  $Test->like($thing, qr/$regex/, $name);
-  $Test->like($thing, '/$regex/', $name);
-
-Like L<Test::More>'s C<like()>.  Checks if $thing matches the given C<$regex>.
-
-=item B<unlike>
-
-  $Test->unlike($thing, qr/$regex/, $name);
-  $Test->unlike($thing, '/$regex/', $name);
-
-Like L<Test::More>'s C<unlike()>.  Checks if $thing B<does not match> the
-given C<$regex>.
-
-=cut
 
 sub like {
     my( $self, $thing, $regex, $name ) = @_;
+    my $ctx = $self->ctx;
 
     local $Level = $Level + 1;
-    return $self->_regex_ok( $thing, $regex, '=~', $name );
+
+    release $ctx, $self->_regex_ok( $thing, $regex, '=~', $name );
 }
 
 sub unlike {
     my( $self, $thing, $regex, $name ) = @_;
+    my $ctx = $self->ctx;
 
     local $Level = $Level + 1;
-    return $self->_regex_ok( $thing, $regex, '!~', $name );
-}
-
-=item B<cmp_ok>
 
-  $Test->cmp_ok($thing, $type, $that, $name);
-
-Works just like L<Test::More>'s C<cmp_ok()>.
-
-    $Test->cmp_ok($big_num, '!=', $other_big_num);
+    release $ctx, $self->_regex_ok( $thing, $regex, '!~', $name );
+}
 
-=cut
 
 my %numeric_cmps = map { ( $_, 1 ) } ( "<", "<=", ">", ">=", "==", "!=", "<=>" );
 
@@ -1157,9 +869,10 @@ my %cmp_ok_bl = map { ( $_, 1 ) } ( "=", "+=", ".=", "x=", "^=", "|=", "||=", "&
 
 sub cmp_ok {
     my( $self, $got, $type, $expect, $name ) = @_;
+    my $ctx = $self->ctx;
 
     if ($cmp_ok_bl{$type}) {
-        $self->croak("$type is not a valid comparison operator in cmp_ok()");
+        $ctx->throw("$type is not a valid comparison operator in cmp_ok()");
     }
 
     my ($test, $succ);
@@ -1169,7 +882,7 @@ sub cmp_ok {
 
         local( $@, $!, $SIG{__DIE__} );    # isolate eval
 
-        my($pack, $file, $line) = $self->caller();
+        my($pack, $file, $line) = $ctx->trace->call();
 
         # This is so that warnings come out at the caller's level
         $succ = eval qq[
@@ -1209,7 +922,7 @@ END
             $self->_cmp_diag( $got, $type, $expect );
         }
     }
-    return $ok;
+    return release $ctx, $ok;
 }
 
 sub _cmp_diag {
@@ -1237,182 +950,71 @@ sub _caller_context {
     return $code;
 }
 
-=back
-
 
-=head2 Other Testing Methods
+sub BAIL_OUT {
+    my( $self, $reason ) = @_;
 
-These are methods which are used in the course of writing a test but are not themselves tests.
+    my $ctx = $self->ctx;
 
-=over 4
+    $self->{Bailed_Out} = 1;
 
-=item B<BAIL_OUT>
+    $ctx->bail($reason);
+}
 
-    $Test->BAIL_OUT($reason);
 
-Indicates to the L<Test::Harness> that things are going so badly all
-testing should terminate.  This includes running any additional test
-scripts.
+{
+    no warnings 'once';
+    *BAILOUT = \&BAIL_OUT;
+}
 
-It will exit with 255.
+sub skip {
+    my( $self, $why, $name ) = @_;
+    $why ||= '';
+    $name = '' unless defined $name;
+    $self->_unoverload_str( \$why );
 
-=cut
+    my $ctx = $self->ctx;
 
-sub BAIL_OUT {
-    my( $self, $reason ) = @_;
+    $ctx->hub->meta(__PACKAGE__, {})->{Test_Results}[ $ctx->hub->count ] = {
+        'ok'      => 1,
+        actual_ok => 1,
+        name      => $name,
+        type      => 'skip',
+        reason    => $why,
+    };
 
-    $self->{Bailed_Out} = 1;
+    $name =~ s|#|\\#|g;    # # in a name can confuse Test::Harness.
+    $name =~ s{\n}{\n# }sg;
+    $why =~ s{\n}{\n# }sg;
 
-    if ($self->parent) {
-        $self->{Bailed_Out_Reason} = $reason;
-        $self->no_ending(1);
-        die bless {} => 'Test::Builder::Exception';
-    }
+    my $tctx = $ctx->snapshot;
+    $tctx->skip('', $why);
 
-    $self->_print("Bail out!  $reason");
-    exit 255;
+    return release $ctx, 1;
 }
 
-=for deprecated
-BAIL_OUT() used to be BAILOUT()
-
-=cut
-
-{
-    no warnings 'once';
-    *BAILOUT = \&BAIL_OUT;
-}
-
-=item B<skip>
-
-    $Test->skip;
-    $Test->skip($why);
-
-Skips the current test, reporting C<$why>.
-
-=cut
-
-sub skip {
-    my( $self, $why, $name ) = @_;
-    $why ||= '';
-    $name = '' unless defined $name;
-    $self->_unoverload_str( \$why );
-
-    lock( $self->{Curr_Test} );
-    $self->{Curr_Test}++;
-
-    $self->{Test_Results}[ $self->{Curr_Test} - 1 ] = &share(
-        {
-            'ok'      => 1,
-            actual_ok => 1,
-            name      => $name,
-            type      => 'skip',
-            reason    => $why,
-        }
-    );
-
-    my $out = "ok";
-    $out .= " $self->{Curr_Test}" if $self->use_numbers;
-    $out .= " # skip";
-    $out .= " $why"               if length $why;
-    $out .= "\n";
-
-    $self->_print($out);
-
-    return 1;
-}
-
-=item B<todo_skip>
-
-  $Test->todo_skip;
-  $Test->todo_skip($why);
-
-Like C<skip()>, only it will declare the test as failing and TODO.  Similar
-to
-
-    print "not ok $tnum # TODO $why\n";
-
-=cut
 
 sub todo_skip {
     my( $self, $why ) = @_;
     $why ||= '';
 
-    lock( $self->{Curr_Test} );
-    $self->{Curr_Test}++;
-
-    $self->{Test_Results}[ $self->{Curr_Test} - 1 ] = &share(
-        {
-            'ok'      => 1,
-            actual_ok => 0,
-            name      => '',
-            type      => 'todo_skip',
-            reason    => $why,
-        }
-    );
+    my $ctx = $self->ctx;
 
-    my $out = "not ok";
-    $out .= " $self->{Curr_Test}" if $self->use_numbers;
-    $out .= " # TODO & SKIP $why\n";
+    $ctx->hub->meta(__PACKAGE__, {})->{Test_Results}[ $ctx->hub->count ] = {
+        'ok'      => 1,
+        actual_ok => 0,
+        name      => '',
+        type      => 'todo_skip',
+        reason    => $why,
+    };
 
-    $self->_print($out);
+    $why =~ s{\n}{\n# }sg;
+    my $tctx = $ctx->snapshot;
+    $tctx->send_event( 'Skip', todo => $why, todo_diag => 1, reason => $why, pass => 0);
 
-    return 1;
+    return release $ctx, 1;
 }
 
-=begin _unimplemented
-
-=item B<skip_rest>
-
-  $Test->skip_rest;
-  $Test->skip_rest($reason);
-
-Like C<skip()>, only it skips all the rest of the tests you plan to run
-and terminates the test.
-
-If you're running under C<no_plan>, it skips once and terminates the
-test.
-
-=end _unimplemented
-
-=back
-
-
-=head2 Test building utility methods
-
-These methods are useful when writing your own test methods.
-
-=over 4
-
-=item B<maybe_regex>
-
-  $Test->maybe_regex(qr/$regex/);
-  $Test->maybe_regex('/$regex/');
-
-This method used to be useful back when Test::Builder worked on Perls
-before 5.6 which didn't have qr//.  Now its pretty useless.
-
-Convenience method for building testing functions that take regular
-expressions as arguments.
-
-Takes a quoted regular expression produced by C<qr//>, or a string
-representing a regular expression.
-
-Returns a Perl value which may be used instead of the corresponding
-regular expression, or C<undef> if its argument is not recognised.
-
-For example, a version of C<like()>, sans the useful diagnostic messages,
-could be written as:
-
-  sub laconic_like {
-      my ($self, $thing, $regex, $name) = @_;
-      my $usable_regex = $self->maybe_regex($regex);
-      die "expecting regex, found '$regex'\n"
-          unless $usable_regex;
-      $self->ok($thing =~ m/$usable_regex/, $name);
-  }
-
-=cut
 
 sub maybe_regex {
     my( $self, $regex ) = @_;
@@ -1494,46 +1096,942 @@ DIAGNOSTIC
     return $ok;
 }
 
-# I'm not ready to publish this.  It doesn't deal with array return
-# values from the code or context.
 
-=begin private
+sub is_fh {
+    my $self     = shift;
+    my $maybe_fh = shift;
+    return 0 unless defined $maybe_fh;
+
+    return 1 if ref $maybe_fh  eq 'GLOB';    # its a glob ref
+    return 1 if ref \$maybe_fh eq 'GLOB';    # its a glob
+
+    return eval { $maybe_fh->isa("IO::Handle") } ||
+           eval { tied($maybe_fh)->can('TIEHANDLE') };
+}
+
+
+sub level {
+    my( $self, $level ) = @_;
+
+    if( defined $level ) {
+        $Level = $level;
+    }
+    return $Level;
+}
+
+
+sub use_numbers {
+    my( $self, $use_nums ) = @_;
+
+    my $ctx = $self->ctx;
+    my $format = $ctx->hub->format;
+    unless ($format && $format->can('no_numbers') && $format->can('set_no_numbers')) {
+        warn "The current formatter does not support 'use_numbers'" if $format;
+        return release $ctx, 0;
+    }
+
+    $format->set_no_numbers(!$use_nums) if defined $use_nums;
+
+    return release $ctx, $format->no_numbers ? 0 : 1;
+}
+
+BEGIN {
+    for my $method (qw(no_header no_diag)) {
+        my $set = "set_$method";
+        my $code = sub {
+            my( $self, $no ) = @_;
+
+            my $ctx = $self->ctx;
+            my $format = $ctx->hub->format;
+            unless ($format && $format->isa('Test2::Formatter::TAP') && $format->can($set)) {
+                warn "The current formatter does not support '$method'" if $format;
+                $ctx->release;
+                return
+            }
+
+            $format->$set($no) if defined $no;
+
+            return release $ctx, $format->$method ? 1 : 0;
+        };
+
+        no strict 'refs';    ## no critic
+        *$method = $code;
+    }
+}
+
+sub no_ending {
+    my( $self, $no ) = @_;
+
+    my $ctx = $self->ctx;
+
+    $ctx->hub->set_no_ending($no) if defined $no;
+
+    return release $ctx, $ctx->hub->no_ending;
+}
+
+sub diag {
+    my $self = shift;
+    return unless @_;
+
+    my $ctx = $self->ctx;
+    $ctx->diag(join '' => map {defined($_) ? $_ : 'undef'} @_);
+    $ctx->release;
+}
+
+
+sub note {
+    my $self = shift;
+    return unless @_;
+
+    my $ctx = $self->ctx;
+    $ctx->note(join '' => map {defined($_) ? $_ : 'undef'} @_);
+    $ctx->release;
+}
+
+
+sub explain {
+    my $self = shift;
+
+    local ($@, $!);
+    require Data::Dumper;
+
+    return map {
+        ref $_
+          ? do {
+            my $dumper = Data::Dumper->new( [$_] );
+            $dumper->Indent(1)->Terse(1);
+            $dumper->Sortkeys(1) if $dumper->can("Sortkeys");
+            $dumper->Dump;
+          }
+          : $_
+    } @_;
+}
+
+
+sub output {
+    my( $self, $fh ) = @_;
+
+    my $ctx = $self->ctx;
+    my $format = $ctx->hub->format;
+    $ctx->release;
+    return unless $format && $format->isa('Test2::Formatter::TAP');
+
+    $format->handles->[Test2::Formatter::TAP::OUT_STD()] = $self->_new_fh($fh)
+        if defined $fh;
+
+    return $format->handles->[Test2::Formatter::TAP::OUT_STD()];
+}
+
+sub failure_output {
+    my( $self, $fh ) = @_;
+
+    my $ctx = $self->ctx;
+    my $format = $ctx->hub->format;
+    $ctx->release;
+    return unless $format && $format->isa('Test2::Formatter::TAP');
+
+    $format->handles->[Test2::Formatter::TAP::OUT_ERR()] = $self->_new_fh($fh)
+        if defined $fh;
+
+    return $format->handles->[Test2::Formatter::TAP::OUT_ERR()];
+}
+
+sub todo_output {
+    my( $self, $fh ) = @_;
+
+    my $ctx = $self->ctx;
+    my $format = $ctx->hub->format;
+    $ctx->release;
+    return unless $format && $format->isa('Test::Builder::Formatter');
+
+    $format->handles->[Test::Builder::Formatter::OUT_TODO()] = $self->_new_fh($fh)
+        if defined $fh;
+
+    return $format->handles->[Test::Builder::Formatter::OUT_TODO()];
+}
+
+sub _new_fh {
+    my $self = shift;
+    my($file_or_fh) = shift;
+
+    my $fh;
+    if( $self->is_fh($file_or_fh) ) {
+        $fh = $file_or_fh;
+    }
+    elsif( ref $file_or_fh eq 'SCALAR' ) {
+        # Scalar refs as filehandles was added in 5.8.
+        if( $] >= 5.008 ) {
+            open $fh, ">>", $file_or_fh
+              or $self->croak("Can't open scalar ref $file_or_fh: $!");
+        }
+        # Emulate scalar ref filehandles with a tie.
+        else {
+            $fh = Test::Builder::IO::Scalar->new($file_or_fh)
+              or $self->croak("Can't tie scalar ref $file_or_fh");
+        }
+    }
+    else {
+        open $fh, ">", $file_or_fh
+          or $self->croak("Can't open test output log $file_or_fh: $!");
+        _autoflush($fh);
+    }
+
+    return $fh;
+}
+
+sub _autoflush {
+    my($fh) = shift;
+    my $old_fh = select $fh;
+    $| = 1;
+    select $old_fh;
+
+    return;
+}
+
+
+sub reset_outputs {
+    my $self = shift;
+
+    my $ctx = $self->ctx;
+    my $format = $ctx->hub->format;
+    $ctx->release;
+    return unless $format && $format->isa('Test2::Formatter::TAP');
+    $format->set_handles([@{$self->{Orig_Handles}}]) if $self->{Orig_Handles};
+
+    return;
+}
+
+
+sub carp {
+    my $self = shift;
+    my $ctx = $self->ctx;
+    $ctx->alert(join "", @_);
+    $ctx->release;
+}
+
+sub croak {
+    my $self = shift;
+    my $ctx = $self->ctx;
+    $ctx->throw(join "", @_);
+    $ctx->release;
+}
+
+
+sub current_test {
+    my( $self, $num ) = @_;
+
+    my $ctx = $self->ctx;
+    my $hub = $ctx->hub;
+
+    if( defined $num ) {
+        $hub->set_count($num);
+
+        # If the test counter is being pushed forward fill in the details.
+        my $test_results = $ctx->hub->meta(__PACKAGE__, {})->{Test_Results};
+        if( $num > @$test_results ) {
+            my $start = @$test_results ? @$test_results : 0;
+            for( $start .. $num - 1 ) {
+                $test_results->[$_] = {
+                    'ok'      => 1,
+                    actual_ok => undef,
+                    reason    => 'incrementing test number',
+                    type      => 'unknown',
+                    name      => undef
+                };
+            }
+        }
+        # If backward, wipe history.  Its their funeral.
+        elsif( $num < @$test_results ) {
+            $#{$test_results} = $num - 1;
+        }
+    }
+    return release $ctx, $hub->count;
+}
+
+
+sub is_passing {
+    my $self = shift;
+
+    my $ctx = $self->ctx;
+    my $hub = $ctx->hub;
+
+    if( @_ ) {
+        my ($bool) = @_;
+        $hub->set_failed(0) if $bool;
+        $hub->is_passing($bool);
+    }
+
+    return release $ctx, $hub->is_passing;
+}
+
+
+sub summary {
+    my($self) = shift;
+
+    my $ctx = $self->ctx;
+    my $data = $ctx->hub->meta(__PACKAGE__, {})->{Test_Results};
+    $ctx->release;
+    return map { $_->{'ok'} } @$data;
+}
+
+
+sub details {
+    my $self = shift;
+    my $ctx = $self->ctx;
+    my $data = $ctx->hub->meta(__PACKAGE__, {})->{Test_Results};
+    $ctx->release;
+    return @$data;
+}
+
+
+sub find_TODO {
+    my( $self, $pack, $set, $new_value ) = @_;
+
+    my $ctx = $self->ctx;
+
+    $pack ||= $ctx->trace->package || $self->exported_to;
+    $ctx->release;
+
+    return unless $pack;
+
+    no strict 'refs';    ## no critic
+    no warnings 'once';
+    my $old_value = ${ $pack . '::TODO' };
+    $set and ${ $pack . '::TODO' } = $new_value;
+    return $old_value;
+}
+
+sub todo {
+    my( $self, $pack ) = @_;
+
+    local $Level = $Level + 1;
+    my $ctx = $self->ctx;
+    $ctx->release;
+
+    my $meta = $ctx->hub->meta(__PACKAGE__, {todo => []})->{todo};
+    return $meta->[-1]->[1] if $meta && @$meta;
+
+    $pack ||= $ctx->trace->package;
+
+    return unless $pack;
+
+    no strict 'refs';    ## no critic
+    no warnings 'once';
+    return ${ $pack . '::TODO' };
+}
+
+sub in_todo {
+    my $self = shift;
+
+    local $Level = $Level + 1;
+    my $ctx = $self->ctx;
+    $ctx->release;
+
+    my $meta = $ctx->hub->meta(__PACKAGE__, {todo => []})->{todo};
+    return 1 if $meta && @$meta;
+
+    my $pack = $ctx->trace->package || return 0;
+
+    no strict 'refs';    ## no critic
+    no warnings 'once';
+    my $todo = ${ $pack . '::TODO' };
+
+    return 0 unless defined $todo;
+    return 0 if "$todo" eq '';
+    return 1;
+}
+
+sub todo_start {
+    my $self = shift;
+    my $message = @_ ? shift : '';
+
+    my $ctx = $self->ctx;
+
+    my $hub = $ctx->hub;
+    my $filter = $hub->filter(sub {
+        my ($active_hub, $e) = @_;
+
+        # Turn a diag into a todo diag
+        return Test::Builder::TodoDiag->new(%$e) if ref($e) eq 'Test2::Event::Diag';
+
+        # Set todo on ok's
+        if ($hub == $active_hub && $e->isa('Test2::Event::Ok')) {
+            $e->set_todo($message);
+            $e->set_effective_pass(1);
+
+            if (my $result = $e->get_meta(__PACKAGE__)) {
+                $result->{reason} ||= $message;
+                $result->{type}   ||= 'todo';
+                $result->{ok}       = 1;
+            }
+        }
+
+        return $e;
+    }, inherit => 1);
+
+    push @{$ctx->hub->meta(__PACKAGE__, {todo => []})->{todo}} => [$filter, $message];
+
+    $ctx->release;
+
+    return;
+}
+
+sub todo_end {
+    my $self = shift;
+
+    my $ctx = $self->ctx;
+
+    my $set = pop @{$ctx->hub->meta(__PACKAGE__, {todo => []})->{todo}};
+
+    $ctx->throw('todo_end() called without todo_start()') unless $set;
+
+    $ctx->hub->unfilter($set->[0]);
+
+    $ctx->release;
+
+    return;
+}
+
+
+sub caller {    ## no critic (Subroutines::ProhibitBuiltinHomonyms)
+    my( $self ) = @_;
+
+    my $ctx = $self->ctx;
+
+    my $trace = $ctx->trace;
+    $ctx->release;
+    return wantarray ? $trace->call : $trace->package;
+}
+
+
+sub _try {
+    my( $self, $code, %opts ) = @_;
+
+    my $error;
+    my $return;
+    {
+        local $!;               # eval can mess up $!
+        local $@;               # don't set $@ in the test
+        local $SIG{__DIE__};    # don't trip an outside DIE handler.
+        $return = eval { $code->() };
+        $error = $@;
+    }
+
+    die $error if $error and $opts{die_on_fail};
+
+    return wantarray ? ( $return, $error ) : $return;
+}
+
+sub _ending {
+    my $self = shift;
+    my ($ctx, $real_exit_code, $new) = @_;
+
+    unless ($ctx) {
+        my $octx = $self->ctx;
+        $ctx = $octx->snapshot;
+        $octx->release;
+    }
+
+    return if $ctx->hub->no_ending;
+    return if $ctx->hub->meta(__PACKAGE__, {})->{Ending}++;
+
+    # Don't bother with an ending if this is a forked copy.  Only the parent
+    # should do the ending.
+    return unless $self->{Original_Pid} == $$;
+
+    my $hub = $ctx->hub;
+    return if $hub->bailed_out;
+
+    my $plan  = $hub->plan;
+    my $count = $hub->count;
+    my $failed = $hub->failed;
+    return unless $plan || $count || $failed;
+
+    # Ran tests but never declared a plan or hit done_testing
+    if( !$hub->plan and $hub->count ) {
+        $self->diag("Tests were run but no plan was declared and done_testing() was not seen.");
+
+        if($real_exit_code) {
+            $self->diag(<<"FAIL");
+Looks like your test exited with $real_exit_code just after $count.
+FAIL
+            $$new ||= $real_exit_code;
+            return;
+        }
+
+        # But if the tests ran, handle exit code.
+        if($failed > 0) {
+            my $exit_code = $failed <= 254 ? $failed : 254;
+            $$new ||= $exit_code;
+            return;
+        }
+
+        $$new ||= 254;
+        return;
+    }
+
+    if ($real_exit_code && !$count) {
+        $self->diag("Looks like your test exited with $real_exit_code before it could output anything.");
+        $$new ||= $real_exit_code;
+        return;
+    }
+
+    return if $plan && "$plan" eq 'SKIP';
+
+    if (!$count) {
+        $self->diag('No tests run!');
+        $$new ||= 255;
+        return;
+    }
+
+    if ($real_exit_code) {
+        $self->diag(<<"FAIL");
+Looks like your test exited with $real_exit_code just after $count.
+FAIL
+        $$new ||= $real_exit_code;
+        return;
+    }
+
+    if ($plan eq 'NO PLAN') {
+        $ctx->plan( $count );
+        $plan = $hub->plan;
+    }
+
+    # Figure out if we passed or failed and print helpful messages.
+    my $num_extra = $count - $plan;
+
+    if ($num_extra != 0) {
+        my $s = $plan == 1 ? '' : 's';
+        $self->diag(<<"FAIL");
+Looks like you planned $plan test$s but ran $count.
+FAIL
+    }
+
+    if ($failed) {
+        my $s = $failed == 1 ? '' : 's';
+
+        my $qualifier = $num_extra == 0 ? '' : ' run';
+
+        $self->diag(<<"FAIL");
+Looks like you failed $failed test$s of $count$qualifier.
+FAIL
+    }
+
+    my $exit_code = 0;
+    if ($failed) {
+        $exit_code = $failed <= 254 ? $failed : 254;
+    }
+    elsif ($num_extra != 0) {
+        $exit_code = 255;
+    }
+
+    $$new ||= $exit_code;
+    return;
+}
+
+# Some things used this even though it was private... I am looking at you
+# Test::Builder::Prefix...
+sub _print_comment {
+    my( $self, $fh, @msgs ) = @_;
+
+    return if $self->no_diag;
+    return unless @msgs;
+
+    # Prevent printing headers when compiling (i.e. -c)
+    return if $^C;
+
+    # Smash args together like print does.
+    # Convert undef to 'undef' so its readable.
+    my $msg = join '', map { defined($_) ? $_ : 'undef' } @msgs;
+
+    # Escape the beginning, _print will take care of the rest.
+    $msg =~ s/^/# /;
+
+    local( $\, $", $, ) = ( undef, ' ', '' );
+    print $fh $msg;
+
+    return 0;
+}
+
+# This is used by Test::SharedFork to turn on IPC after the fact. Not
+# documenting because I do not want it used. The method name is borrowed from
+# Test::Builder 2
+# Once Test2 stuff goes stable this method will be removed and Test::SharedFork
+# will be made smarter.
+sub coordinate_forks {
+    my $self = shift;
+
+    {
+        local ($@, $!);
+        require Test2::IPC;
+    }
+    Test2::IPC->import;
+    Test2::API::test2_ipc_enable_polling();
+    my $ipc = Test2::IPC::apply_ipc($self->{Stack});
+    $ipc->set_no_fatal(1);
+    Test2::API::test2_no_wait(1);
+    Test2::API::test2_ipc_enable_shm();
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Test::Builder - Backend for building test libraries
+
+=head1 SYNOPSIS
+
+  package My::Test::Module;
+  use base 'Test::Builder::Module';
+
+  my $CLASS = __PACKAGE__;
+
+  sub ok {
+      my($test, $name) = @_;
+      my $tb = $CLASS->builder;
+
+      $tb->ok($test, $name);
+  }
+
+
+=head1 DESCRIPTION
+
+L<Test::Simple> and L<Test::More> have proven to be popular testing modules,
+but they're not always flexible enough.  Test::Builder provides a
+building block upon which to write your own test libraries I<which can
+work together>.
+
+=head2 Construction
+
+=over 4
+
+=item B<new>
+
+  my $Test = Test::Builder->new;
+
+Returns a Test::Builder object representing the current state of the
+test.
+
+Since you only run one test per program C<new> always returns the same
+Test::Builder object.  No matter how many times you call C<new()>, you're
+getting the same object.  This is called a singleton.  This is done so that
+multiple modules share such global information as the test counter and
+where test output is going.
+
+If you want a completely new Test::Builder object different from the
+singleton, use C<create>.
+
+=item B<create>
+
+  my $Test = Test::Builder->create;
+
+Ok, so there can be more than one Test::Builder object and this is how
+you get it.  You might use this instead of C<new()> if you're testing
+a Test::Builder based module, but otherwise you probably want C<new>.
+
+B<NOTE>: the implementation is not complete.  C<level>, for example, is
+still shared amongst B<all> Test::Builder objects, even ones created using
+this method.  Also, the method name may change in the future.
+
+=item B<subtest>
+
+    $builder->subtest($name, \&subtests, @args);
+
+See documentation of C<subtest> in Test::More.
+
+C<subtest> also, and optionally, accepts arguments which will be passed to the
+subtests reference.
+
+=item B<name>
+
+ diag $builder->name;
+
+Returns the name of the current builder.  Top level builders default to C<$0>
+(the name of the executable).  Child builders are named via the C<child>
+method.  If no name is supplied, will be named "Child of $parent->name".
+
+=item B<reset>
+
+  $Test->reset;
+
+Reinitializes the Test::Builder singleton to its original state.
+Mostly useful for tests run in persistent environments where the same
+test might be run multiple times in the same process.
+
+=back
+
+=head2 Setting up tests
+
+These methods are for setting up tests and declaring how many there
+are.  You usually only want to call one of these methods.
+
+=over 4
+
+=item B<plan>
+
+  $Test->plan('no_plan');
+  $Test->plan( skip_all => $reason );
+  $Test->plan( tests => $num_tests );
+
+A convenient way to set up your tests.  Call this and Test::Builder
+will print the appropriate headers and take the appropriate actions.
+
+If you call C<plan()>, don't call any of the other methods below.
+
+If a child calls "skip_all" in the plan, a C<Test::Builder::Exception> is
+thrown.  Trap this error, call C<finalize()> and don't run any more tests on
+the child.
+
+ my $child = $Test->child('some child');
+ eval { $child->plan( $condition ? ( skip_all => $reason ) : ( tests => 3 )  ) };
+ if ( eval { $@->isa('Test::Builder::Exception') } ) {
+    $child->finalize;
+    return;
+ }
+ # run your tests
+
+
+=item B<expected_tests>
+
+    my $max = $Test->expected_tests;
+    $Test->expected_tests($max);
+
+Gets/sets the number of tests we expect this test to run and prints out
+the appropriate headers.
+
+
+=item B<no_plan>
+
+  $Test->no_plan;
+
+Declares that this test will run an indeterminate number of tests.
+
+
+=item B<done_testing>
+
+  $Test->done_testing();
+  $Test->done_testing($num_tests);
+
+Declares that you are done testing, no more tests will be run after this point.
+
+If a plan has not yet been output, it will do so.
+
+$num_tests is the number of tests you planned to run.  If a numbered
+plan was already declared, and if this contradicts, a failing test
+will be run to reflect the planning mistake.  If C<no_plan> was declared,
+this will override.
+
+If C<done_testing()> is called twice, the second call will issue a
+failing test.
+
+If C<$num_tests> is omitted, the number of tests run will be used, like
+no_plan.
+
+C<done_testing()> is, in effect, used when you'd want to use C<no_plan>, but
+safer. You'd use it like so:
+
+    $Test->ok($a == $b);
+    $Test->done_testing();
+
+Or to plan a variable number of tests:
+
+    for my $test (@tests) {
+        $Test->ok($test);
+    }
+    $Test->done_testing(scalar @tests);
+
+
+=item B<has_plan>
+
+  $plan = $Test->has_plan
+
+Find out whether a plan has been defined. C<$plan> is either C<undef> (no plan
+has been set), C<no_plan> (indeterminate # of tests) or an integer (the number
+of expected tests).
+
+=item B<skip_all>
+
+  $Test->skip_all;
+  $Test->skip_all($reason);
+
+Skips all the tests, using the given C<$reason>.  Exits immediately with 0.
+
+=item B<exported_to>
+
+  my $pack = $Test->exported_to;
+  $Test->exported_to($pack);
+
+Tells Test::Builder what package you exported your functions to.
+
+This method isn't terribly useful since modules which share the same
+Test::Builder object might get exported to different packages and only
+the last one will be honored.
+
+=back
+
+=head2 Running tests
+
+These actually run the tests, analogous to the functions in Test::More.
+
+They all return true if the test passed, false if the test failed.
+
+C<$name> is always optional.
+
+=over 4
+
+=item B<ok>
+
+  $Test->ok($test, $name);
+
+Your basic test.  Pass if C<$test> is true, fail if $test is false.  Just
+like Test::Simple's C<ok()>.
+
+=item B<is_eq>
+
+  $Test->is_eq($got, $expected, $name);
+
+Like Test::More's C<is()>.  Checks if C<$got eq $expected>.  This is the
+string version.
+
+C<undef> only ever matches another C<undef>.
+
+=item B<is_num>
+
+  $Test->is_num($got, $expected, $name);
+
+Like Test::More's C<is()>.  Checks if C<$got == $expected>.  This is the
+numeric version.
+
+C<undef> only ever matches another C<undef>.
+
+=item B<isnt_eq>
+
+  $Test->isnt_eq($got, $dont_expect, $name);
+
+Like L<Test::More>'s C<isnt()>.  Checks if C<$got ne $dont_expect>.  This is
+the string version.
+
+=item B<isnt_num>
+
+  $Test->isnt_num($got, $dont_expect, $name);
+
+Like L<Test::More>'s C<isnt()>.  Checks if C<$got ne $dont_expect>.  This is
+the numeric version.
+
+=item B<like>
+
+  $Test->like($thing, qr/$regex/, $name);
+  $Test->like($thing, '/$regex/', $name);
+
+Like L<Test::More>'s C<like()>.  Checks if $thing matches the given C<$regex>.
+
+=item B<unlike>
+
+  $Test->unlike($thing, qr/$regex/, $name);
+  $Test->unlike($thing, '/$regex/', $name);
+
+Like L<Test::More>'s C<unlike()>.  Checks if $thing B<does not match> the
+given C<$regex>.
+
+=item B<cmp_ok>
+
+  $Test->cmp_ok($thing, $type, $that, $name);
+
+Works just like L<Test::More>'s C<cmp_ok()>.
+
+    $Test->cmp_ok($big_num, '!=', $other_big_num);
+
+=back
+
+=head2 Other Testing Methods
+
+These are methods which are used in the course of writing a test but are not themselves tests.
+
+=over 4
+
+=item B<BAIL_OUT>
+
+    $Test->BAIL_OUT($reason);
+
+Indicates to the L<Test::Harness> that things are going so badly all
+testing should terminate.  This includes running any additional test
+scripts.
+
+It will exit with 255.
+
+=for deprecated
+BAIL_OUT() used to be BAILOUT()
+
+=item B<skip>
+
+    $Test->skip;
+    $Test->skip($why);
+
+Skips the current test, reporting C<$why>.
+
+=item B<todo_skip>
+
+  $Test->todo_skip;
+  $Test->todo_skip($why);
+
+Like C<skip()>, only it will declare the test as failing and TODO.  Similar
+to
+
+    print "not ok $tnum # TODO $why\n";
+
+=begin _unimplemented
+
+=item B<skip_rest>
+
+  $Test->skip_rest;
+  $Test->skip_rest($reason);
+
+Like C<skip()>, only it skips all the rest of the tests you plan to run
+and terminates the test.
+
+If you're running under C<no_plan>, it skips once and terminates the
+test.
+
+=end _unimplemented
+
+=back
+
 
-=item B<_try>
+=head2 Test building utility methods
 
-    my $return_from_code          = $Test->try(sub { code });
-    my($return_from_code, $error) = $Test->try(sub { code });
+These methods are useful when writing your own test methods.
 
-Works like eval BLOCK except it ensures it has no effect on the rest
-of the test (ie. C<$@> is not set) nor is effected by outside
-interference (ie. C<$SIG{__DIE__}>) and works around some quirks in older
-Perls.
+=over 4
 
-C<$error> is what would normally be in C<$@>.
+=item B<maybe_regex>
 
-It is suggested you use this in place of eval BLOCK.
+  $Test->maybe_regex(qr/$regex/);
+  $Test->maybe_regex('/$regex/');
 
-=cut
+This method used to be useful back when Test::Builder worked on Perls
+before 5.6 which didn't have qr//.  Now its pretty useless.
 
-sub _try {
-    my( $self, $code, %opts ) = @_;
+Convenience method for building testing functions that take regular
+expressions as arguments.
 
-    my $error;
-    my $return;
-    {
-        local $!;               # eval can mess up $!
-        local $@;               # don't set $@ in the test
-        local $SIG{__DIE__};    # don't trip an outside DIE handler.
-        $return = eval { $code->() };
-        $error = $@;
-    }
+Takes a quoted regular expression produced by C<qr//>, or a string
+representing a regular expression.
 
-    die $error if $error and $opts{die_on_fail};
+Returns a Perl value which may be used instead of the corresponding
+regular expression, or C<undef> if its argument is not recognised.
 
-    return wantarray ? ( $return, $error ) : $return;
-}
+For example, a version of C<like()>, sans the useful diagnostic messages,
+could be written as:
 
-=end private
+  sub laconic_like {
+      my ($self, $thing, $regex, $name) = @_;
+      my $usable_regex = $self->maybe_regex($regex);
+      die "expecting regex, found '$regex'\n"
+          unless $usable_regex;
+      $self->ok($thing =~ m/$usable_regex/, $name);
+  }
 
 
 =item B<is_fh>
@@ -1544,17 +2042,6 @@ Determines if the given C<$thing> can be used as a filehandle.
 
 =cut
 
-sub is_fh {
-    my $self     = shift;
-    my $maybe_fh = shift;
-    return 0 unless defined $maybe_fh;
-
-    return 1 if ref $maybe_fh  eq 'GLOB';    # its a glob ref
-    return 1 if ref \$maybe_fh eq 'GLOB';    # its a glob
-
-    return eval { $maybe_fh->isa("IO::Handle") } ||
-           eval { tied($maybe_fh)->can('TIEHANDLE') };
-}
 
 =back
 
@@ -1585,17 +2072,6 @@ localized:
 
 To be polite to other functions wrapping your own you usually want to increment C<$Level> rather than set it to a constant.
 
-=cut
-
-sub level {
-    my( $self, $level ) = @_;
-
-    if( defined $level ) {
-        $Level = $level;
-    }
-    return $Level;
-}
-
 =item B<use_numbers>
 
     $Test->use_numbers($on_or_off);
@@ -1617,17 +2093,6 @@ when threads or forking is involved.
 
 Defaults to on.
 
-=cut
-
-sub use_numbers {
-    my( $self, $use_nums ) = @_;
-
-    if( defined $use_nums ) {
-        $self->{Use_Nums} = $use_nums;
-    }
-    return $self->{Use_Nums};
-}
-
 =item B<no_diag>
 
     $Test->no_diag($no_diag);
@@ -1650,24 +2115,6 @@ If this is true, none of that will be done.
 
 If set to true, no "1..N" header will be printed.
 
-=cut
-
-foreach my $attribute (qw(No_Header No_Ending No_Diag)) {
-    my $method = lc $attribute;
-
-    my $code = sub {
-        my( $self, $no ) = @_;
-
-        if( defined $no ) {
-            $self->{$attribute} = $no;
-        }
-        return $self->{$attribute};
-    };
-
-    no strict 'refs';    ## no critic
-    *{ __PACKAGE__ . '::' . $method } = $code;
-}
-
 =back
 
 =head2 Output
@@ -1703,14 +2150,6 @@ a failing test (C<ok() || diag()>) it "passes through" the failure.
 =for blame transfer
 Mark Fowler <mark@twoshortplanks.com>
 
-=cut
-
-sub diag {
-    my $self = shift;
-
-    $self->_print_comment( $self->_diag_fh, @_ );
-}
-
 =item B<note>
 
     $Test->note(@msgs);
@@ -1718,43 +2157,6 @@ sub diag {
 Like C<diag()>, but it prints to the C<output()> handle so it will not
 normally be seen by the user except in verbose mode.
 
-=cut
-
-sub note {
-    my $self = shift;
-
-    $self->_print_comment( $self->output, @_ );
-}
-
-sub _diag_fh {
-    my $self = shift;
-
-    local $Level = $Level + 1;
-    return $self->in_todo ? $self->todo_output : $self->failure_output;
-}
-
-sub _print_comment {
-    my( $self, $fh, @msgs ) = @_;
-
-    return if $self->no_diag;
-    return unless @msgs;
-
-    # Prevent printing headers when compiling (i.e. -c)
-    return if $^C;
-
-    # Smash args together like print does.
-    # Convert undef to 'undef' so its readable.
-    my $msg = join '', map { defined($_) ? $_ : 'undef' } @msgs;
-
-    # Escape the beginning, _print will take care of the rest.
-    $msg =~ s/^/# /;
-
-    local $Level = $Level + 1;
-    $self->_print_to_fh( $fh, $msg );
-
-    return 0;
-}
-
 =item B<explain>
 
     my @dump = $Test->explain(@msgs);
@@ -1768,64 +2170,6 @@ or
 
     is_deeply($have, $want) || note explain $have;
 
-=cut
-
-sub explain {
-    my $self = shift;
-
-    return map {
-        ref $_
-          ? do {
-            $self->_try(sub { require Data::Dumper }, die_on_fail => 1);
-
-            my $dumper = Data::Dumper->new( [$_] );
-            $dumper->Indent(1)->Terse(1);
-            $dumper->Sortkeys(1) if $dumper->can("Sortkeys");
-            $dumper->Dump;
-          }
-          : $_
-    } @_;
-}
-
-=begin _private
-
-=item B<_print>
-
-    $Test->_print(@msgs);
-
-Prints to the C<output()> filehandle.
-
-=end _private
-
-=cut
-
-sub _print {
-    my $self = shift;
-    return $self->_print_to_fh( $self->output, @_ );
-}
-
-sub _print_to_fh {
-    my( $self, $fh, @msgs ) = @_;
-
-    # Prevent printing headers when only compiling.  Mostly for when
-    # tests are deparsed with B::Deparse
-    return if $^C;
-
-    my $msg = join '', @msgs;
-    my $indent = $self->_indent;
-
-    local( $\, $", $, ) = ( undef, ' ', '' );
-
-    # Escape each line after the first with a # so we don't
-    # confuse Test::Harness.
-    $msg =~ s{\n(?!\z)}{\n$indent# }sg;
-
-    # Stick a newline on the end if it needs it.
-    $msg .= "\n" unless $msg =~ /\n\z/;
-
-    return print $fh $indent, $msg;
-}
-
 =item B<output>
 
 =item B<failure_output>
@@ -1838,151 +2182,24 @@ sub _print_to_fh {
     $Test->output(\$scalar);
 
 These methods control where Test::Builder will print its output.
-They take either an open C<$filehandle>, a C<$filename> to open and write to
-or a C<$scalar> reference to append to.  It will always return a C<$filehandle>.
-
-B<output> is where normal "ok/not ok" test output goes.
-
-Defaults to STDOUT.
-
-B<failure_output> is where diagnostic output on test failures and
-C<diag()> goes.  It is normally not read by Test::Harness and instead is
-displayed to the user.
-
-Defaults to STDERR.
-
-C<todo_output> is used instead of C<failure_output()> for the
-diagnostics of a failing TODO test.  These will not be seen by the
-user.
-
-Defaults to STDOUT.
-
-=cut
-
-sub output {
-    my( $self, $fh ) = @_;
-
-    if( defined $fh ) {
-        $self->{Out_FH} = $self->_new_fh($fh);
-    }
-    return $self->{Out_FH};
-}
-
-sub failure_output {
-    my( $self, $fh ) = @_;
-
-    if( defined $fh ) {
-        $self->{Fail_FH} = $self->_new_fh($fh);
-    }
-    return $self->{Fail_FH};
-}
-
-sub todo_output {
-    my( $self, $fh ) = @_;
-
-    if( defined $fh ) {
-        $self->{Todo_FH} = $self->_new_fh($fh);
-    }
-    return $self->{Todo_FH};
-}
-
-sub _new_fh {
-    my $self = shift;
-    my($file_or_fh) = shift;
-
-    my $fh;
-    if( $self->is_fh($file_or_fh) ) {
-        $fh = $file_or_fh;
-    }
-    elsif( ref $file_or_fh eq 'SCALAR' ) {
-        # Scalar refs as filehandles was added in 5.8.
-        if( $] >= 5.008 ) {
-            open $fh, ">>", $file_or_fh
-              or $self->croak("Can't open scalar ref $file_or_fh: $!");
-        }
-        # Emulate scalar ref filehandles with a tie.
-        else {
-            $fh = Test::Builder::IO::Scalar->new($file_or_fh)
-              or $self->croak("Can't tie scalar ref $file_or_fh");
-        }
-    }
-    else {
-        open $fh, ">", $file_or_fh
-          or $self->croak("Can't open test output log $file_or_fh: $!");
-        _autoflush($fh);
-    }
-
-    return $fh;
-}
-
-sub _autoflush {
-    my($fh) = shift;
-    my $old_fh = select $fh;
-    $| = 1;
-    select $old_fh;
-
-    return;
-}
-
-my( $Testout, $Testerr );
-
-sub _dup_stdhandles {
-    my $self = shift;
-
-    $self->_open_testhandles;
-
-    # Set everything to unbuffered else plain prints to STDOUT will
-    # come out in the wrong order from our own prints.
-    _autoflush($Testout);
-    _autoflush( \*STDOUT );
-    _autoflush($Testerr);
-    _autoflush( \*STDERR );
-
-    $self->reset_outputs;
-
-    return;
-}
-
-sub _open_testhandles {
-    my $self = shift;
-
-    return if $self->{Opened_Testhandles};
-
-    # We dup STDOUT and STDERR so people can change them in their
-    # test suites while still getting normal test output.
-    open( $Testout, ">&STDOUT" ) or die "Can't dup STDOUT:  $!";
-    open( $Testerr, ">&STDERR" ) or die "Can't dup STDERR:  $!";
-
-    $self->_copy_io_layers( \*STDOUT, $Testout );
-    $self->_copy_io_layers( \*STDERR, $Testerr );
-
-    $self->{Opened_Testhandles} = 1;
-
-    return;
-}
+They take either an open C<$filehandle>, a C<$filename> to open and write to
+or a C<$scalar> reference to append to.  It will always return a C<$filehandle>.
 
-sub _copy_io_layers {
-    my( $self, $src, $dst ) = @_;
+B<output> is where normal "ok/not ok" test output goes.
 
-    $self->_try(
-        sub {
-            require PerlIO;
-            my @src_layers = PerlIO::get_layers($src);
+Defaults to STDOUT.
 
-            _apply_layers($dst, @src_layers) if @src_layers;
-        }
-    );
+B<failure_output> is where diagnostic output on test failures and
+C<diag()> goes.  It is normally not read by Test::Harness and instead is
+displayed to the user.
 
-    return;
-}
+Defaults to STDERR.
 
-sub _apply_layers {
-    my ($fh, @layers) = @_;
-    my %seen;
-    my @unique = grep { $_ ne 'unix' and !$seen{$_}++ } @layers;
-    binmode($fh, join(":", "", "raw", @unique));
-}
+C<todo_output> is used instead of C<failure_output()> for the
+diagnostics of a failing TODO test.  These will not be seen by the
+user.
 
+Defaults to STDOUT.
 
 =item reset_outputs
 
@@ -1990,18 +2207,6 @@ sub _apply_layers {
 
 Resets all the output filehandles back to their defaults.
 
-=cut
-
-sub reset_outputs {
-    my $self = shift;
-
-    $self->output        ($Testout);
-    $self->failure_output($Testerr);
-    $self->todo_output   ($Testout);
-
-    return;
-}
-
 =item carp
 
   $tb->carp(@message);
@@ -2016,26 +2221,6 @@ point where the original test function was called (C<< $tb->caller >>).
 Dies with C<@message> but the message will appear to come from the
 point where the original test function was called (C<< $tb->caller >>).
 
-=cut
-
-sub _message_at_caller {
-    my $self = shift;
-
-    local $Level = $Level + 1;
-    my( $pack, $file, $line ) = $self->caller;
-    return join( "", @_ ) . " at $file line $line.\n";
-}
-
-sub carp {
-    my $self = shift;
-    return warn $self->_message_at_caller(@_);
-}
-
-sub croak {
-    my $self = shift;
-    return die $self->_message_at_caller(@_);
-}
-
 
 =back
 
@@ -2056,38 +2241,6 @@ If set forward, the details of the missing tests are filled in as 'unknown'.
 if set backward, the details of the intervening tests are deleted.  You
 can erase history if you really want to.
 
-=cut
-
-sub current_test {
-    my( $self, $num ) = @_;
-
-    lock( $self->{Curr_Test} );
-    if( defined $num ) {
-        $self->{Curr_Test} = $num;
-
-        # If the test counter is being pushed forward fill in the details.
-        my $test_results = $self->{Test_Results};
-        if( $num > @$test_results ) {
-            my $start = @$test_results ? @$test_results : 0;
-            for( $start .. $num - 1 ) {
-                $test_results->[$_] = &share(
-                    {
-                        'ok'      => 1,
-                        actual_ok => undef,
-                        reason    => 'incrementing test number',
-                        type      => 'unknown',
-                        name      => undef
-                    }
-                );
-            }
-        }
-        # If backward, wipe history.  Its their funeral.
-        elsif( $num < @$test_results ) {
-            $#{$test_results} = $num - 1;
-        }
-    }
-    return $self->{Curr_Test};
-}
 
 =item B<is_passing>
 
@@ -2104,18 +2257,6 @@ test to it and start passing.
 
 Don't think about it too much.
 
-=cut
-
-sub is_passing {
-    my $self = shift;
-
-    if( @_ ) {
-        $self->{Is_Passing} = shift;
-    }
-
-    return $self->{Is_Passing};
-}
-
 
 =item B<summary>
 
@@ -2126,13 +2267,6 @@ This is a logical pass/fail, so todos are passes.
 
 Of course, test #1 is $tests[0], etc...
 
-=cut
-
-sub summary {
-    my($self) = shift;
-
-    return map { $_->{'ok'} } @{ $self->{Test_Results} };
-}
 
 =item B<details>
 
@@ -2140,7 +2274,7 @@ sub summary {
 
 Like C<summary()>, but with a lot more detail.
 
-    $tests[$test_num - 1] = 
+    $tests[$test_num - 1] =
             { 'ok'       => is the test considered a pass?
               actual_ok  => did it literally say 'ok'?
               name       => name of the test (if any)
@@ -2181,12 +2315,6 @@ result in this structure:
         reason    => 'insufficient donuts'
       };
 
-=cut
-
-sub details {
-    my $self = shift;
-    return @{ $self->{Test_Results} };
-}
 
 =item B<todo>
 
@@ -2210,20 +2338,6 @@ Sometimes there is some confusion about where C<todo()> should be looking
 for the C<$TODO> variable.  If you want to be sure, tell it explicitly
 what $pack to use.
 
-=cut
-
-sub todo {
-    my( $self, $pack ) = @_;
-
-    return $self->{Todo} if defined $self->{Todo};
-
-    local $Level = $Level + 1;
-    my $todo = $self->find_TODO($pack);
-    return $todo if defined $todo;
-
-    return '';
-}
-
 =item B<find_TODO>
 
     my $todo_reason = $Test->find_TODO();
@@ -2237,35 +2351,12 @@ old value:
 
     my $old_reason = $Test->find_TODO($pack, 1, $new_reason);
 
-=cut
-
-sub find_TODO {
-    my( $self, $pack, $set, $new_value ) = @_;
-
-    $pack = $pack || $self->caller(1) || $self->exported_to;
-    return unless $pack;
-
-    no strict 'refs';    ## no critic
-    my $old_value = ${ $pack . '::TODO' };
-    $set and ${ $pack . '::TODO' } = $new_value;
-    return $old_value;
-}
-
 =item B<in_todo>
 
     my $in_todo = $Test->in_todo;
 
 Returns true if the test is currently inside a TODO block.
 
-=cut
-
-sub in_todo {
-    my $self = shift;
-
-    local $Level = $Level + 1;
-    return( defined $self->{Todo} || $self->find_TODO ) ? 1 : 0;
-}
-
 =item B<todo_start>
 
     $Test->todo_start();
@@ -2307,20 +2398,6 @@ guaranteed and its use is also discouraged:
 
 Pick one style or another of "TODO" to be on the safe side.
 
-=cut
-
-sub todo_start {
-    my $self = shift;
-    my $message = @_ ? shift : '';
-
-    $self->{Start_Todo}++;
-    if( $self->in_todo ) {
-        push @{ $self->{Todo_Stack} } => $self->todo;
-    }
-    $self->{Todo} = $message;
-
-    return;
-}
 
 =item C<todo_end>
 
@@ -2329,27 +2406,6 @@ sub todo_start {
 Stops running tests as "TODO" tests.  This method is fatal if called without a
 preceding C<todo_start> method call.
 
-=cut
-
-sub todo_end {
-    my $self = shift;
-
-    if( !$self->{Start_Todo} ) {
-        $self->croak('todo_end() called without todo_start()');
-    }
-
-    $self->{Start_Todo}--;
-
-    if( $self->{Start_Todo} && @{ $self->{Todo_Stack} } ) {
-        $self->{Todo} = pop @{ $self->{Todo_Stack} };
-    }
-    else {
-        delete $self->{Todo};
-    }
-
-    return;
-}
-
 =item B<caller>
 
     my $package = $Test->caller;
@@ -2362,233 +2418,8 @@ C<$height> will be added to the C<level()>.
 
 If C<caller()> winds up off the top of the stack it report the highest context.
 
-=cut
-
-sub caller {    ## no critic (Subroutines::ProhibitBuiltinHomonyms)
-    my( $self, $height ) = @_;
-    $height ||= 0;
-
-    my $level = $self->level + $height + 1;
-    my @caller;
-    do {
-        @caller = CORE::caller( $level );
-        $level--;
-    } until @caller;
-    return wantarray ? @caller : $caller[0];
-}
-
-=back
-
-=cut
-
-=begin _private
-
-=over 4
-
-=item B<_sanity_check>
-
-  $self->_sanity_check();
-
-Runs a bunch of end of test sanity checks to make sure reality came
-through ok.  If anything is wrong it will die with a fairly friendly
-error message.
-
-=cut
-
-#'#
-sub _sanity_check {
-    my $self = shift;
-
-    $self->_whoa( $self->{Curr_Test} < 0, 'Says here you ran a negative number of tests!' );
-    $self->_whoa( $self->{Curr_Test} != @{ $self->{Test_Results} },
-        'Somehow you got a different number of results than tests ran!' );
-
-    return;
-}
-
-=item B<_whoa>
-
-  $self->_whoa($check, $description);
-
-A sanity check, similar to C<assert()>.  If the C<$check> is true, something
-has gone horribly wrong.  It will die with the given C<$description> and
-a note to contact the author.
-
-=cut
-
-sub _whoa {
-    my( $self, $check, $desc ) = @_;
-    if($check) {
-        local $Level = $Level + 1;
-        $self->croak(<<"WHOA");
-WHOA!  $desc
-This should never happen!  Please contact the author immediately!
-WHOA
-    }
-
-    return;
-}
-
-=item B<_my_exit>
-
-  _my_exit($exit_num);
-
-Perl seems to have some trouble with exiting inside an C<END> block.
-5.6.1 does some odd things.  Instead, this function edits C<$?>
-directly.  It should B<only> be called from inside an C<END> block.
-It doesn't actually exit, that's your job.
-
-=cut
-
-sub _my_exit {
-    $? = $_[0];    ## no critic (Variables::RequireLocalizedPunctuationVars)
-
-    return 1;
-}
-
 =back
 
-=end _private
-
-=cut
-
-sub _ending {
-    my $self = shift;
-    return if $self->no_ending;
-    return if $self->{Ending}++;
-
-    my $real_exit_code = $?;
-
-    # Don't bother with an ending if this is a forked copy.  Only the parent
-    # should do the ending.
-    if( $self->{Original_Pid} != $$ ) {
-        return;
-    }
-
-    # Ran tests but never declared a plan or hit done_testing
-    if( !$self->{Have_Plan} and $self->{Curr_Test} ) {
-        $self->is_passing(0);
-        $self->diag("Tests were run but no plan was declared and done_testing() was not seen.");
-
-        if($real_exit_code) {
-            $self->diag(<<"FAIL");
-Looks like your test exited with $real_exit_code just after $self->{Curr_Test}.
-FAIL
-            $self->is_passing(0);
-            _my_exit($real_exit_code) && return;
-        }
-
-        # But if the tests ran, handle exit code.
-        my $test_results = $self->{Test_Results};
-        if(@$test_results) {
-            my $num_failed = grep !$_->{'ok'}, @{$test_results}[ 0 .. $self->{Curr_Test} - 1 ];
-            if ($num_failed > 0) {
-
-                my $exit_code = $num_failed <= 254 ? $num_failed : 254;
-                _my_exit($exit_code) && return;
-            }
-        }
-        _my_exit(254) && return;
-    }
-
-    # Exit if plan() was never called.  This is so "require Test::Simple"
-    # doesn't puke.
-    if( !$self->{Have_Plan} ) {
-        return;
-    }
-
-    # Don't do an ending if we bailed out.
-    if( $self->{Bailed_Out} ) {
-        $self->is_passing(0);
-        return;
-    }
-    # Figure out if we passed or failed and print helpful messages.
-    my $test_results = $self->{Test_Results};
-    if(@$test_results) {
-        # The plan?  We have no plan.
-        if( $self->{No_Plan} ) {
-            $self->_output_plan($self->{Curr_Test}) unless $self->no_header;
-            $self->{Expected_Tests} = $self->{Curr_Test};
-        }
-
-        # Auto-extended arrays and elements which aren't explicitly
-        # filled in with a shared reference will puke under 5.8.0
-        # ithreads.  So we have to fill them in by hand. :(
-        my $empty_result = &share( {} );
-        for my $idx ( 0 .. $self->{Expected_Tests} - 1 ) {
-            $test_results->[$idx] = $empty_result
-              unless defined $test_results->[$idx];
-        }
-
-        my $num_failed = grep !$_->{'ok'}, @{$test_results}[ 0 .. $self->{Curr_Test} - 1 ];
-
-        my $num_extra = $self->{Curr_Test} - $self->{Expected_Tests};
-
-        if( $num_extra != 0 ) {
-            my $s = $self->{Expected_Tests} == 1 ? '' : 's';
-            $self->diag(<<"FAIL");
-Looks like you planned $self->{Expected_Tests} test$s but ran $self->{Curr_Test}.
-FAIL
-            $self->is_passing(0);
-        }
-
-        if($num_failed) {
-            my $num_tests = $self->{Curr_Test};
-            my $s = $num_failed == 1 ? '' : 's';
-
-            my $qualifier = $num_extra == 0 ? '' : ' run';
-
-            $self->diag(<<"FAIL");
-Looks like you failed $num_failed test$s of $num_tests$qualifier.
-FAIL
-            $self->is_passing(0);
-        }
-
-        if($real_exit_code) {
-            $self->diag(<<"FAIL");
-Looks like your test exited with $real_exit_code just after $self->{Curr_Test}.
-FAIL
-            $self->is_passing(0);
-            _my_exit($real_exit_code) && return;
-        }
-
-        my $exit_code;
-        if($num_failed) {
-            $exit_code = $num_failed <= 254 ? $num_failed : 254;
-        }
-        elsif( $num_extra != 0 ) {
-            $exit_code = 255;
-        }
-        else {
-            $exit_code = 0;
-        }
-
-        _my_exit($exit_code) && return;
-    }
-    elsif( $self->{Skip_All} ) {
-        _my_exit(0) && return;
-    }
-    elsif($real_exit_code) {
-        $self->diag(<<"FAIL");
-Looks like your test exited with $real_exit_code before it could output anything.
-FAIL
-        $self->is_passing(0);
-        _my_exit($real_exit_code) && return;
-    }
-    else {
-        $self->diag("No tests run!\n");
-        $self->is_passing(0);
-        _my_exit(255) && return;
-    }
-
-    $self->is_passing(0);
-    $self->_whoa( 1, "We fell off the end of _ending()" );
-}
-
-END {
-    $Test->_ending if defined $Test;
-}
-
 =head1 EXIT CODES
 
 If all your tests passed, Test::Builder will exit with zero (which is
@@ -2665,8 +2496,3 @@ This program is free software; you can redistribute it and/or
 modify it under the same terms as Perl itself.
 
 See F<http://www.perl.com/perl/misc/Artistic.html>
-
-=cut
-
-1;
-
diff --git a/cpan/Test-Simple/lib/Test/Builder/Formatter.pm b/cpan/Test-Simple/lib/Test/Builder/Formatter.pm
new file mode 100644 (file)
index 0000000..f458f13
--- /dev/null
@@ -0,0 +1,112 @@
+package Test::Builder::Formatter;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+use base 'Test2::Formatter::TAP';
+
+use Test2::Util::HashBase qw/no_header no_diag/;
+
+BEGIN {
+    *OUT_STD = Test2::Formatter::TAP->can('OUT_STD');
+    *OUT_ERR = Test2::Formatter::TAP->can('OUT_ERR');
+
+    my $todo = OUT_ERR() + 1;
+    *OUT_TODO = sub() { $todo };
+}
+
+__PACKAGE__->register_event('Test::Builder::TodoDiag', 'event_todo_diag');
+
+sub init {
+    my $self = shift;
+    $self->SUPER::init(@_);
+    $self->{+HANDLES}->[OUT_TODO] = $self->{+HANDLES}->[OUT_STD];
+}
+
+sub event_todo_diag {
+    my $self = shift;
+    my @out = $self->event_diag(@_);
+    $out[0]->[0] = OUT_TODO();
+    return @out;
+}
+
+sub event_diag {
+    my $self = shift;
+    return if $self->{+NO_DIAG};
+    return $self->SUPER::event_diag(@_);
+}
+
+sub event_plan {
+    my $self = shift;
+    return if $self->{+NO_HEADER};
+    return $self->SUPER::event_plan(@_);
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test::Builder::Formatter - Test::Builder subclass of Test2::Formatter::TAP
+
+=head1 DESCRIPTION
+
+This is what takes events and turns them into TAP.
+
+=head1 SYNOPSIS
+
+    use Test::Builder; # Loads Test::Builder::Formatter for you
+
+=head1 METHODS
+
+=over 4
+
+=item $f->event_todo_diag
+
+Additional method used to process L<Test::Builder::TodoDiag> events.
+
+=item $f->event_diag
+
+=item $f->event_plan
+
+These override the parent class methods to do nothing if C<no_header> is set.
+
+=back
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
index 2322d8a..8f30974 100644 (file)
@@ -7,8 +7,7 @@ use Test::Builder 1.00;
 require Exporter;
 our @ISA = qw(Exporter);
 
-our $VERSION = '1.001014';
-$VERSION = eval $VERSION;      ## no critic (BuiltinFunctions::ProhibitStringyEval)
+our $VERSION = '1.302015';
 
 
 =head1 NAME
@@ -22,7 +21,7 @@ Test::Builder::Module - Base class for test modules
 
   my $CLASS = __PACKAGE__;
 
-  use base 'Test::Builder::Module';
+  use parent 'Test::Builder::Module';
   @EXPORT = qw(ok);
 
   sub ok ($;$) {
index b0554b8..3b1f53e 100644 (file)
@@ -1,7 +1,7 @@
 package Test::Builder::Tester;
 
 use strict;
-our $VERSION = "1.28";
+our $VERSION = '1.302015';
 
 use Test::Builder 0.99;
 use Symbol;
@@ -104,16 +104,26 @@ my $original_is_passing;
 my $original_output_handle;
 my $original_failure_handle;
 my $original_todo_handle;
+my $original_formatter;
 
 my $original_harness_env;
 
 # function that starts testing and redirects the filehandles for now
 sub _start_testing {
+    # Hack for things that conditioned on Test-Stream being loaded
+    $INC{'Test/Stream.pm'} ||= 'fake' if $INC{'Test/Moose/More.pm'};
     # even if we're running under Test::Harness pretend we're not
     # for now.  This needed so Test::Builder doesn't add extra spaces
     $original_harness_env = $ENV{HARNESS_ACTIVE} || 0;
     $ENV{HARNESS_ACTIVE} = 0;
 
+    my $hub = $t->{Hub} || Test2::API::test2_stack->top;
+    $original_formatter = $hub->format;
+    unless ($original_formatter && $original_formatter->isa('Test::Builder::Formatter')) {
+        my $fmt = Test::Builder::Formatter->new;
+        $hub->format($fmt);
+    }
+
     # remember what the handles were set to
     $original_output_handle  = $t->output();
     $original_failure_handle = $t->failure_output();
@@ -304,6 +314,8 @@ will function normally and cause success/errors for L<Test::Harness>.
 =cut
 
 sub test_test {
+    # END the hack
+    delete $INC{'Test/Stream.pm'} if $INC{'Test/Stream.pm'} && $INC{'Test/Stream.pm'} eq 'fake';
     # decode the arguments as described in the pod
     my $mess;
     my %args;
@@ -321,6 +333,10 @@ sub test_test {
     croak "Not testing.  You must declare output with a test function first."
       unless $testing;
 
+
+    my $hub = $t->{Hub} || Test2::API::test2_stack->top;
+    $hub->format($original_formatter);
+
     # okay, reconnect the test suite back to the saved handles
     $t->output($original_output_handle);
     $t->failure_output($original_failure_handle);
@@ -487,8 +503,9 @@ sub expect {
 sub _account_for_subtest {
     my( $self, $check ) = @_;
 
-    # Since we ship with Test::Builder, calling a private method is safe...ish.
-    return ref($check) ? $check : $t->_indent . $check;
+    my $hub = $t->{Stack}->top;
+    my $nesting = $hub->isa('Test2::Hub::Subtest') ? $hub->nested : 0;
+    return ref($check) ? $check : ('    ' x $nesting) . $check;
 }
 
 sub _translate_Failed_check {
@@ -563,6 +580,33 @@ sub complaint {
         }
     }
 
+    my @got = split "\n", $got;
+    my @wanted = split "\n", $wanted;
+
+    $got = "";
+    $wanted = "";
+
+    while (@got || @wanted) {
+        my $g = shift @got    || "";
+        my $w = shift @wanted || "";
+        if ($g ne $w) {
+            if($g =~ s/(\s+)$/    |> /g) {
+                $g .= ($_ eq ' ' ? '_' : '\t') for split '', $1;
+            }
+            if($w =~ s/(\s+)$/    |> /g) {
+                $w .= ($_ eq ' ' ? '_' : '\t') for split '', $1;
+            }
+            $g = "> $g";
+            $w = "> $w";
+        }
+        else {
+            $g = "  $g";
+            $w = "  $w";
+        }
+        $got = $got ? "$got\n$g" : $g;
+        $wanted = $wanted ? "$wanted\n$w" : $w;
+    }
+
     return "$type is:\n" . "$got\nnot:\n$wanted\nas expected";
 }
 
index 9a89310..8913412 100644 (file)
@@ -1,7 +1,7 @@
 package Test::Builder::Tester::Color;
 
 use strict;
-our $VERSION = "1.290001";
+our $VERSION = '1.302015';
 
 require Test::Builder::Tester;
 
diff --git a/cpan/Test-Simple/lib/Test/Builder/TodoDiag.pm b/cpan/Test-Simple/lib/Test/Builder/TodoDiag.pm
new file mode 100644 (file)
index 0000000..d22fb33
--- /dev/null
@@ -0,0 +1,61 @@
+package Test::Builder::TodoDiag;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+use base 'Test2::Event::Diag';
+
+sub diagnostics { 0 }
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test::Builder::TodoDiag - Test::Builder subclass of Test2::Event::Diag
+
+=head1 DESCRIPTION
+
+This is used to encapsulate diag messages created inside TODO.
+
+=head1 SYNOPSIS
+
+You do not need to use this directly.
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test/FAQ.pod b/cpan/Test-Simple/lib/Test/FAQ.pod
new file mode 100644 (file)
index 0000000..2f81fe0
--- /dev/null
@@ -0,0 +1,371 @@
+=pod
+
+=head1 NAME
+
+Test::FAQ - Frequently Asked Questions about testing with Perl
+
+=head1 DESCRIPTION
+
+Frequently Asked Questions about testing in general and specific
+issues with Perl.
+
+=head2 Is there any tutorial on testing?
+
+L<Test::Tutorial>
+
+=head2 Are there any modules for testing?
+
+A whole bunch.  Start with L<Test::Simple> then move onto Test::More.
+
+Then go onto L<http://search.cpan.org> and search for "Test".
+
+=head2 Are there any modules for testing web pages/CGI programs?
+
+L<Test::WWW::Mechanize>, L<Test::WWW::Selenium>
+
+=head2 Are there any modules for testing external programs?
+
+L<Test::Cmd>
+
+=head2 Can you do xUnit/JUnit style testing in Perl?
+
+Yes, L<Test::Class> allows you to write test methods while continuing to
+use all the usual CPAN testing modules.  It is the best and most
+perlish way to do xUnit style testing.
+
+L<Test::Unit> is a more direct port of XUnit to Perl, but it does not use
+the Perl conventions and does not play well with other CPAN testing
+modules.  As of this writing, it is abandoned.  B<Do not use>.
+
+The L<Test::Inline> (aka L<Pod::Tests>) is worth mentioning as it allows you to
+put tests into the POD in the same file as the code.
+
+
+=head2 How do I test my module is backwards/forwards compatible?
+
+First, install a bunch of perls of commonly used versions.  At the
+moment, you could try these
+
+    5.7.2
+    5.6.1
+    5.005_03
+    5.004_05
+
+if you're feeling brave, you might want to have on hand these
+
+    bleadperl
+    5.6.0
+    5.004_04
+    5.004
+
+going back beyond 5.003 is probably beyond the call of duty.
+
+You can then add something like this to your F<Makefile.PL>.  It
+overrides the L<ExtUtils::MakeMaker> C<test_via_harness()> method to run the tests
+against several different versions of Perl.
+
+    # If PERL_TEST_ALL is set, run "make test" against 
+    # other perls as well as the current perl.
+    {
+        package MY;
+
+        sub test_via_harness {
+            my($self, $orig_perl, $tests) = @_;
+
+            # names of your other perl binaries.
+            my @other_perls = qw(perl5.004_05 perl5.005_03 perl5.7.2);
+
+            my @perls = ($orig_perl);
+            push @perls, @other_perls if $ENV{PERL_TEST_ALL};
+
+            my $out;
+            foreach my $perl (@perls) {
+                $out .= $self->SUPER::test_via_harness($perl, $tests);
+            }
+
+            return $out;
+        }
+    }
+
+and re-run your F<Makefile.PL> with the C<PERL_TEST_ALL> environment
+variable set
+
+    PERL_TEST_ALL=1 perl Makefile.PL
+
+now C<make test> will run against each of your other perls.
+
+
+=head2 If I'm testing Foo::Bar, where do I put tests for Foo::Bar::Baz?
+
+=head2 How do I know when my tests are good enough?
+
+A: Use tools for measuring the code coverage of your tests, e.g. how many of
+your source code lines/subs/expressions/paths are executed (aka covered) by
+the test suite. The more, the better, of course, although you may not
+be able achieve 100%. If your testsuite covers under 100%, then
+the rest of your code is, basically, untested. Which means it may work in
+surprising ways (e.g. doesn't do things like they are intended or
+documented), have bugs (e.g. return wrong results) or it may not work at
+all.
+
+=head2 How do I measure the coverage of my test suite?
+
+L<Devel::Cover>
+
+=head2 How do I get tests to run in a certain order?
+
+Tests run in alphabetical order, so simply name your test files in the order
+you want them to run.  Numbering your test files works, too.
+
+    t/00_compile.t
+    t/01_config.t
+    t/zz_teardown.t
+
+0 runs first, z runs last.
+
+To achieve a specific order, try L<Test::Manifest>.
+
+Typically you do B<not> want your tests to require being run in a
+certain order, but it can be useful to do a compile check first or to
+run the tests on a very basic module before everything else.  This
+gives you early information if a basic module fails which will bring
+everything else down.
+
+Another use is if you have a suite wide setup/teardown, such as
+creating and delete a large test database, which may be too
+expensive to do for every test.
+
+We recommend B<against> numbering every test file.  For most files
+this ordering will be arbitrary and the leading number obscures the
+real name of the file.  See L<What should I name my test files?> for
+more information.
+
+
+=head2 What should I name my tests?
+
+=head2 What should I name my test files?
+
+A test filename serves three purposes:
+
+Most importantly, it serves to identify what is being tested.  Each
+test file should test a clear piece of functionality.  This could be
+at single class, a single method, even a single bug.
+
+The order in which tests are run is usually dictated by the filename.
+See L<How do I get tests to run in a certain order?> for details.
+
+Finally, the grouping of tests into common bits of functionality can
+be achieved by directory and filenames.  For example, all the tests
+for L<Test::Builder> are in the F<t/Builder/> directory.
+
+As an example, F<t/Builder/reset.t> contains the tests for
+C<< Test::Builder->reset >>.  F<t/00compile.t> checks that everything
+compiles, and it will run first.  F<t/dont_overwrite_die_handler.t>
+checks that we don't overwrite the C<< $SIG{__DIE__} >> handler.
+
+
+=head2 How do I deal with tests that sometimes pass and sometimes fail?
+
+=head2 How do I test with a database/network/server that the user may or may not have?
+
+=head2 What's a good way to test lists?
+
+C<is_deeply()> from L<Test::More> as well as L<Test::Deep>.
+
+=head2 Is there such a thing as untestable code?
+
+There's always compile/export checks.
+
+Code must be written with testability in mind.  Separation of form and
+functionality.
+
+=head2 What do I do when I can't make the code do the same thing twice?
+
+Force it to do the same thing twice.
+
+Even a random number generator can be tested.
+
+=head2 How do I test a GUI?
+
+=head2 How do I test an image generator?
+
+=head2 How do I test that my code handles failures gracefully?
+
+=head2 How do I check the right warnings are issued?
+
+L<Test::Warn>
+
+=head2 How do I test code that prints?
+
+L<Test::Output>
+
+=head2 I want to test that my code dies when I do X
+
+L<Test::Exception>
+
+=head2 I want to print out more diagnostic info on failure.
+
+C<ok(...) || diag "...";>
+
+=head2 How can I simulate failures to make sure that my code does the Right Thing in the face of them?
+
+
+=head2 Why use an ok() function?
+
+On Tue, Aug 28, 2001 at 02:12:46PM +0100, Robin Houston wrote:
+> Michael Schwern wrote:
+> > Ah HA!  I've been wondering why nobody ever thinks to write a simple
+> > ok() function for their tests!  perlhack has bad testing advice.
+> 
+> Could you explain the advantage of having a "simple ok() function"?
+
+Because writing:
+
+    print "not " unless some thing worked;
+    print "ok $test\n";  $test++;
+
+gets rapidly annoying.  This is why we made up subroutines in the
+first place.  It also looks like hell and obscures the real purpose.
+
+Besides, that will cause problems on VMS.
+
+
+> As somebody who has spent many painful hours debugging test failures,
+> I'm intimately familiar with the _disadvantages_. When you run the
+> test, you know that "test 113 failed". That's all you know, in general.
+
+Second advantage is you can easily upgrade the C<ok()> function to fix
+this, either by slapping this line in:
+
+        printf "# Failed test at line %d\n", (caller)[2];
+
+or simply junking the whole thing and switching to L<Test::Simple> or
+L<Test::More>, which does all sorts of nice diagnostics-on-failure for
+you.  Its C<ok()> function is backwards compatible with the above.
+
+There's some issues with using L<Test::Simple> to test really basic Perl
+functionality, you have to choose on a per test basis.  Since
+L<Test::Simple> doesn't use C<pack()> it's safe for F<t/op/pack.t> to use
+L<Test::Simple>.  I just didn't want to make the perlhack patching
+example too complicated.
+
+
+=head2 Dummy Mode
+
+> One compromise would be to use a test-generating script, which allows
+> the tests to be structured simply and _generates_ the actual test
+> code. One could then grep the generated test script to locate the
+> failing code.
+
+This is a very interesting, and very common, response to the problem.
+I'm going to make some observations about reactions to testing,
+they're not specific to you.
+
+If you've ever read the Bastard Operator From Hell series, you'll
+recall the Dummy Mode.
+
+    The words "power surging" and "drivers" have got her.  People hear
+    words like that and go into Dummy Mode and do ANYTHING you say.  I
+    could tell her to run naked across campus with a powercord rammed
+    up her backside and she'd probably do it...  Hmmm...
+
+There seems to be a Dummy Mode WRT testing.  An otherwise competent
+person goes to write a test and they suddenly forget all basic
+programming practice.
+
+
+The reasons for using an C<ok()> function above are the same reasons to
+use functions in general, we should all know them.  We'd laugh our
+heads off at code that repeated as much as your average test does.
+These are newbie mistakes.
+
+And the normal 'can do' flair seems to disappear.  I know Robin.  I
+*know* that in any other situation he would have come up with the
+C<caller()> trick in about 15 seconds flat.  Instead weird, elaborate,
+inelegant hacks are thought up to solve the simplest problems.
+
+
+I guess there are certain programming idioms that are foreign enough
+to throw your brain into reverse if you're not ready for them.  Like
+trying to think in Lisp, for example.  Or being presented with OO for
+the first time.  I guess writing test is one of those.
+
+
+=head2 How do I use Test::More without depending on it?
+
+Install L<Test::More> into F<t/lib> under your source directory.  Then in your tests
+say C<use lib 't/lib'>.
+
+=head2 How do I deal with threads and forking?
+
+=head2 Why do I need more than ok?
+
+Since every test can be reduced to checking if a statement is true,
+C<ok()> can test everything.  But C<ok()> doesn't tell you why the test
+failed.  For that you need to tell the test more... which is why 
+you need L<Test::More>.
+
+    ok $pirate->name eq "Roberts", "person's name";
+
+    not ok 1 - person's name
+    # Failed test at pirates.t line 23.
+
+If the above fails, you don't know what C<< $person->name >> returned.
+You have to go in and add a C<diag> call.  This is time consuming.  If
+it's a heisenbug, it might not fail again!  If it's a user reporting a
+test failure, they might not be bothered to hack the tests to give you
+more information.
+
+    is $person->name, "Roberts", "person's name";
+
+    not ok 1 - person's name
+    # Failed test at pirates.t line 23.
+    #        got: 'Wesley'
+    #   expected: 'Roberts'
+
+Using C<is> from L<Test::More> you now know what value you got and
+what value you expected.
+
+The most useful functions in L<Test::More> are C<is()>, C<like()> and C<is_deeply()>.
+
+
+=head2 What's wrong with C<print $test ? "ok" : "not ok">?
+
+=head2 How do I check for an infinite loop?
+
+On Mon, Mar 18, 2002 at 03:57:55AM -0500, Mark-Jason Dominus wrote:
+> 
+> Michael The Schwern <schwern@pobox.com> says:
+> > Use alarm and skip the test if $Config{d_alarm} is false (see
+> > t/op/alarm.t for an example).  If you think the infinite loop is due
+> > to a programming glitch, as opposed to a cross-platform issue, this
+> > will be enough.
+> 
+> Thanks very much!
+> 
+
+=head2 How can I check that flock works?
+
+=head2 How do I use the comparison functions of a testing module without it being a test?
+
+Any testing function based on L<Test::Builder>, most are, can be quieted so it does
+not do any testing.  It simply returns true or false.  Use the following code...
+
+    use Test::More;     # or any testing module
+    
+    use Test::Builder;
+    use File::Spec;
+
+    # Get the internal Test::Builder object
+    my $tb = Test::Builder->new;
+
+    $tb->plan("no_plan");
+    
+    # Keep Test::Builder from displaying anything
+    $tb->no_diag(1);
+    $tb->no_ending(1);
+    $tb->no_header(1);
+    $tb->output( File::Spec->devnull );
+
+    # Now you can use the testing function.
+    print is_deeply( "foo", "bar" ) ? "Yes" : "No";
index 4bab267..89814bb 100644 (file)
@@ -17,8 +17,7 @@ sub _carp {
     return warn @_, " at $file line $line\n";
 }
 
-our $VERSION = '1.001014';
-$VERSION = eval $VERSION;    ## no critic (BuiltinFunctions::ProhibitStringyEval)
+our $VERSION = '1.302015';
 
 use Test::Builder::Module 0.99;
 our @ISA    = qw(Test::Builder::Module);
@@ -1293,10 +1292,13 @@ sub skip {
     my( $why, $how_many ) = @_;
     my $tb = Test::More->builder;
 
-    unless( defined $how_many ) {
-        # $how_many can only be avoided when no_plan is in use.
+    # If the plan is set, and is static, then skip needs a count. If the plan
+    # is 'no_plan' we are fine. As well if plan is undefined then we are
+    # waiting for done_testing.
+    unless (defined $how_many) {
+        my $plan = $tb->has_plan;
         _carp "skip() needs to know \$how_many tests are in the block"
-          unless $tb->has_plan eq 'no_plan';
+            if $plan && $plan =~ m/^\d+$/;
         $how_many = 1;
     }
 
@@ -1903,8 +1905,6 @@ comes from.
 
 =head2 BUNDLES
 
-L<Bundle::Test> installs a whole bunch of useful test modules.
-
 L<Test::Most> Most commonly needed test functions and features.
 
 =head1 AUTHORS
index 56457b4..f0a685f 100644 (file)
@@ -4,8 +4,7 @@ use 5.006;
 
 use strict;
 
-our $VERSION = '1.001014';
-$VERSION = eval $VERSION;    ## no critic (BuiltinFunctions::ProhibitStringyEval)
+our $VERSION = '1.302015';
 
 use Test::Builder::Module 0.99;
 our @ISA    = qw(Test::Builder::Module);
index a5f1ccf..e8785b0 100644 (file)
@@ -16,9 +16,10 @@ use Test::Tester::Delegate;
 
 require Exporter;
 
-use vars qw( @ISA @EXPORT $VERSION );
+use vars qw( @ISA @EXPORT );
+
+our $VERSION = '1.302015';
 
-$VERSION = "0.114";
 @EXPORT = qw( run_tests check_tests check_test cmp_results show_space );
 @ISA = qw( Exporter );
 
index 00e12e6..0217e98 100644 (file)
@@ -2,6 +2,9 @@ use strict;
 
 package Test::Tester::Capture;
 
+our $VERSION = '1.302015';
+
+
 use Test::Builder;
 
 use vars qw( @ISA );
@@ -42,6 +45,8 @@ sub new
 sub ok {
        my($self, $test, $name) = @_;
 
+       my $ctx = $self->ctx;
+
        # $test might contain an object which we don't want to accidentally
        # store, so we turn it into a boolean.
        $test = $test ? 1 : 0;
@@ -51,7 +56,7 @@ sub ok {
 
        my($pack, $file, $line) = $self->caller;
 
-       my $todo = $self->todo($pack);
+       my $todo = $self->todo();
 
        my $result = {};
        share($result);
@@ -92,6 +97,8 @@ sub ok {
        $result->{_level} = $Test::Builder::Level;
        $result->{_depth} = Test::Tester::find_run_tests();
 
+       $ctx->release;
+
        return $test ? 1 : 0;
 }
 
@@ -99,6 +106,8 @@ sub skip {
        my($self, $why) = @_;
        $why ||= '';
 
+       my $ctx = $self->ctx;
+
        lock($Curr_Test);
        $Curr_Test++;
 
@@ -116,6 +125,7 @@ sub skip {
        );
        $Test_Results[$Curr_Test-1] = \%result;
 
+       $ctx->release;
        return 1;
 }
 
@@ -123,6 +133,8 @@ sub todo_skip {
        my($self, $why) = @_;
        $why ||= '';
 
+       my $ctx = $self->ctx;
+
        lock($Curr_Test);
        $Curr_Test++;
 
@@ -141,6 +153,7 @@ sub todo_skip {
 
        $Test_Results[$Curr_Test-1] = \%result;
 
+       $ctx->release;
        return 1;
 }
 
@@ -151,6 +164,8 @@ sub diag {
        # Prevent printing headers when compiling (i.e. -c)
        return if $^C;
 
+       my $ctx = $self->ctx;
+
        # Escape each line with a #.
        foreach (@msgs) {
                $_ = 'undef' unless defined;
@@ -162,6 +177,7 @@ sub diag {
 
        $result->{diag} .= join("", @msgs);
 
+       $ctx->release;
        return 0;
 }
 
index f14a4c1..defd2f1 100644 (file)
@@ -3,6 +3,9 @@ use strict;
 
 package Test::Tester::CaptureRunner;
 
+our $VERSION = '1.302015';
+
+
 use Test::Tester::Capture;
 require Exporter;
 
index 7ddb921..6bcfc54 100644 (file)
@@ -3,6 +3,9 @@ use warnings;
 
 package Test::Tester::Delegate;
 
+our $VERSION = '1.302015';
+
+
 use vars '$AUTOLOAD';
 
 sub new
index 87d7cc5..40b6690 100644 (file)
@@ -1,6 +1,8 @@
 package Test::use::ok;
 use 5.005;
-$Test::use::ok::VERSION = '0.16';
+
+our $VERSION = '1.302015';
+
 
 __END__
 
diff --git a/cpan/Test-Simple/lib/Test2.pm b/cpan/Test-Simple/lib/Test2.pm
new file mode 100644 (file)
index 0000000..ac12b0e
--- /dev/null
@@ -0,0 +1,157 @@
+package Test2;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2 - Framework for writing test tools that all work together.
+
+=head1 DESCRIPTION
+
+Test2 is a new testing framework produced by forking L<Test::Builder>,
+completely refactoring it, adding many new features and capabilities.
+
+=head1 GETTING STARTED
+
+If you are interested in writing tests using new tools then you should look at
+L<Test2::Suite>. L<Test::Suite> is a seperate cpan distribution that contains
+many tools implemented on Test2.
+
+If you are interested in writing new tools you should take a look at
+L<Test2::API> first.
+
+=head1 NAMESPACE LAYOUT
+
+This describes the namespace layout for the Test2 ecosystem. Not all the
+namespaces listed here are part of the Test2 distribution, some are implemented
+in L<Test2::Suite>.
+
+=head2 Test2::Tools::
+
+This namespace is for sets of tools. Modules in this namespace should export
+tools like C<ok()> and C<is()>. Most things written for Test2 should go here.
+Modules in this namespace B<MUST NOT> export subs from other tools. See the
+L</Test2::Bundle::> namespace if you want to do that.
+
+=head2 Test2::Plugin::
+
+This namespace is for plugins. Plugins are modules that change or enhance the
+behavior of Test2. An example of a plugin is a module that sets the encoding to
+utf8 globally. Another example is a module that causes a bail-out event after
+the first test failure.
+
+=head2 Test2::Bundle::
+
+This namespace is for bundles of tools and plugins. Loading one of these may
+load multiple tools and plugins. Modules in this namespace should not implement
+tools directly. In general modules in this namespace should load tools and
+plugins, then re-export things into the consumers namespace.
+
+=head2 Test2::Require::
+
+This namespace is for modules that cause a test to be skipped when conditions
+do not allow it to run. Examples would be modules that skip the test on older
+perls, or when non-essential modules have not been installed.
+
+=head2 Test2::Formatter::
+
+Formatters live under this namespace. L<Test2::Formatter::TAP> is the only
+formatter currently. It is acceptible for third party distributions to create
+new formatters under this namespace.
+
+=head2 Test2::Event::
+
+Events live under this namespace. It is considered acceptible for third party
+distributions to add new event types in this namespace.
+
+=head2 Test2::Hub::
+
+Hub subclasses (and some hub utility objects) live under this namespace. It is
+perfectly reasonable for third party distributions to add new hub subclasses in
+this namespace.
+
+=head2 Test2::IPC::
+
+The IPC subsystem lives in this namespace. There are not many good reasons to
+add anything to this namespace, with exception of IPC drivers.
+
+=head3 Test2::IPC::Driver::
+
+IPC drivers live in this namespace. It is fine to create new IPC drivers and to
+put them in this namespace.
+
+=head2 Test2::Util::
+
+This namespace is for general utilities used by testing tools. Please be
+considerate when adding new modules to this namespace.
+
+=head2 Test2::API::
+
+This is for Test2 API and related packages.
+
+=head2 Test2::
+
+The Test2:: namespace is intended for extentions and frameworks. Tools,
+Plugins, etc should not go directly into this namespace. However extentions
+that are used to build tools and plugins may go here.
+
+In short: If the module exports anything that should be run directly by a test
+script it should probably NOT go directly into C<Test2::XXX>.
+
+=head1 SEE ALSO
+
+L<Test2::API> - Primary API functions.
+
+L<Test2::API::Context> - Detailed documentation of the context object.
+
+L<Test2::IPC> - The IPC system used for threading/fork support.
+
+L<Test2::Formatter> - Formatters such as TAP live here.
+
+L<Test2::Event> - Events live in this namespace.
+
+L<Test2::Hub> - All events eventually funnel through a hub. Custom hubs are how
+C<intercept()> and C<run_subtest()> are implemented.
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/API.pm b/cpan/Test-Simple/lib/Test2/API.pm
new file mode 100644 (file)
index 0000000..32cd49a
--- /dev/null
@@ -0,0 +1,1275 @@
+package Test2::API;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+my $INST;
+my $ENDING = 0;
+sub test2_set_is_end { ($ENDING) = @_ ? @_ : (1) }
+sub test2_get_is_end { $ENDING }
+
+use Test2::API::Instance(\$INST);
+# Set the exit status
+END {
+    test2_set_is_end(); # See gh #16
+    $INST->set_exit();
+}
+
+# See gh #16
+{
+    no warnings;
+    INIT { eval 'END { test2_set_is_end() }; 1' or die $@ }
+}
+
+BEGIN {
+    no warnings 'once';
+    if($] ge '5.014' || $ENV{T2_CHECK_DEPTH} || $Test2::API::DO_DEPTH_CHECK) {
+        *DO_DEPTH_CHECK = sub() { 1 };
+    }
+    else {
+        *DO_DEPTH_CHECK = sub() { 0 };
+    }
+}
+
+use Test2::Util::Trace();
+
+use Test2::Hub::Subtest();
+use Test2::Hub::Interceptor();
+use Test2::Hub::Interceptor::Terminator();
+
+use Test2::Event::Ok();
+use Test2::Event::Diag();
+use Test2::Event::Note();
+use Test2::Event::Plan();
+use Test2::Event::Bail();
+use Test2::Event::Exception();
+use Test2::Event::Waiting();
+use Test2::Event::Skip();
+use Test2::Event::Subtest();
+
+use Carp qw/carp croak confess longmess/;
+use Scalar::Util qw/blessed weaken/;
+use Test2::Util qw/get_tid/;
+
+our @EXPORT_OK = qw{
+    context release
+    context_do
+    no_context
+    intercept
+    run_subtest
+
+    test2_init_done
+    test2_load_done
+
+    test2_set_is_end
+    test2_get_is_end
+
+    test2_pid
+    test2_tid
+    test2_stack
+    test2_no_wait
+
+    test2_add_callback_context_aquire
+    test2_add_callback_context_acquire
+    test2_add_callback_context_init
+    test2_add_callback_context_release
+    test2_add_callback_exit
+    test2_add_callback_post_load
+    test2_list_context_aquire_callbacks
+    test2_list_context_acquire_callbacks
+    test2_list_context_init_callbacks
+    test2_list_context_release_callbacks
+    test2_list_exit_callbacks
+    test2_list_post_load_callbacks
+
+    test2_ipc
+    test2_ipc_drivers
+    test2_ipc_add_driver
+    test2_ipc_polling
+    test2_ipc_disable_polling
+    test2_ipc_enable_polling
+    test2_ipc_get_pending
+    test2_ipc_set_pending
+    test2_ipc_enable_shm
+
+    test2_formatter
+    test2_formatters
+    test2_formatter_add
+    test2_formatter_set
+};
+use base 'Exporter';
+
+# There is a use-cycle between API and API/Context. Context needs to use some
+# API functions as the package is compiling. Test2::API::context() needs
+# Test2::API::Context to be loaded, but we cannot 'require' the module there as
+# it causes a very noticable performance impact with how often context() is
+# called.
+#
+# This will make sure that Context.pm is loaded the first time this module is
+# imported, then the regular import method is swapped into place.
+sub import {
+    require Test2::API::Context unless $INC{'Test2/API/Context.pm'};
+
+    {
+        no warnings 'redefine';
+        *import = \&Exporter::import;
+    }
+
+    goto &import;
+}
+
+my $STACK       = $INST->stack;
+my $CONTEXTS    = $INST->contexts;
+my $INIT_CBS    = $INST->context_init_callbacks;
+my $ACQUIRE_CBS = $INST->context_acquire_callbacks;
+
+sub test2_init_done { $INST->finalized }
+sub test2_load_done { $INST->loaded }
+
+sub test2_pid     { $INST->pid }
+sub test2_tid     { $INST->tid }
+sub test2_stack   { $INST->stack }
+sub test2_no_wait {
+    $INST->set_no_wait(@_) if @_;
+    $INST->no_wait;
+}
+
+sub test2_add_callback_context_acquire   { $INST->add_context_acquire_callback(@_) }
+sub test2_add_callback_context_aquire    { $INST->add_context_acquire_callback(@_) }
+sub test2_add_callback_context_init      { $INST->add_context_init_callback(@_) }
+sub test2_add_callback_context_release   { $INST->add_context_release_callback(@_) }
+sub test2_add_callback_exit              { $INST->add_exit_callback(@_) }
+sub test2_add_callback_post_load         { $INST->add_post_load_callback(@_) }
+sub test2_list_context_aquire_callbacks  { @{$INST->context_acquire_callbacks} }
+sub test2_list_context_acquire_callbacks { @{$INST->context_acquire_callbacks} }
+sub test2_list_context_init_callbacks    { @{$INST->context_init_callbacks} }
+sub test2_list_context_release_callbacks { @{$INST->context_release_callbacks} }
+sub test2_list_exit_callbacks            { @{$INST->exit_callbacks} }
+sub test2_list_post_load_callbacks       { @{$INST->post_load_callbacks} }
+
+sub test2_ipc                 { $INST->ipc }
+sub test2_ipc_add_driver      { $INST->add_ipc_driver(@_) }
+sub test2_ipc_drivers         { @{$INST->ipc_drivers} }
+sub test2_ipc_polling         { $INST->ipc_polling }
+sub test2_ipc_enable_polling  { $INST->enable_ipc_polling }
+sub test2_ipc_disable_polling { $INST->disable_ipc_polling }
+sub test2_ipc_get_pending     { $INST->get_ipc_pending }
+sub test2_ipc_set_pending     { $INST->set_ipc_pending(@_) }
+sub test2_ipc_enable_shm      { $INST->ipc_enable_shm }
+
+sub test2_formatter     { $INST->formatter }
+sub test2_formatters    { @{$INST->formatters} }
+sub test2_formatter_add { $INST->add_formatter(@_) }
+sub test2_formatter_set {
+    my ($formatter) = @_;
+    croak "No formatter specified" unless $formatter;
+    croak "Global Formatter already set" if $INST->formatter_set;
+    $INST->set_formatter($formatter);
+}
+
+# Private, for use in Test2::API::Context
+sub _contexts_ref                  { $INST->contexts }
+sub _context_acquire_callbacks_ref { $INST->context_acquire_callbacks }
+sub _context_init_callbacks_ref    { $INST->context_init_callbacks }
+sub _context_release_callbacks_ref { $INST->context_release_callbacks }
+
+# Private, for use in Test2::IPC
+sub _set_ipc { $INST->set_ipc(@_) }
+
+sub context_do(&;@) {
+    my $code = shift;
+    my @args = @_;
+
+    my $ctx = context(level => 1);
+
+    my $want = wantarray;
+
+    my @out;
+    my $ok = eval {
+        $want          ? @out    = $code->($ctx, @args) :
+        defined($want) ? $out[0] = $code->($ctx, @args) :
+                                   $code->($ctx, @args) ;
+        1;
+    };
+    my $err = $@;
+
+    $ctx->release;
+
+    die $err unless $ok;
+
+    return @out    if $want;
+    return $out[0] if defined $want;
+    return;
+}
+
+sub no_context(&;$) {
+    my ($code, $hid) = @_;
+    $hid ||= $STACK->top->hid;
+
+    my $ctx = $CONTEXTS->{$hid};
+    delete $CONTEXTS->{$hid};
+    my $ok = eval { $code->(); 1 };
+    my $err = $@;
+
+    $CONTEXTS->{$hid} = $ctx;
+    weaken($CONTEXTS->{$hid});
+
+    die $err unless $ok;
+
+    return;
+};
+
+sub context {
+    # We need to grab these before anything else to ensure they are not
+    # changed.
+    my ($errno, $eval_error, $child_error) = (0 + $!, $@, $?);
+
+    my %params = (level => 0, wrapped => 0, @_);
+
+    # If something is getting a context then the sync system needs to be
+    # considered loaded...
+    $INST->load unless $INST->{loaded};
+
+    croak "context() called, but return value is ignored"
+        unless defined wantarray;
+
+    my $stack   = $params{stack} || $STACK;
+    my $hub     = $params{hub}   || @$stack ? $stack->[-1] : $stack->top;
+    my $hid     = $hub->{hid};
+    my $current = $CONTEXTS->{$hid};
+
+    $_->(\%params) for @$ACQUIRE_CBS;
+    map $_->(\%params), @{$hub->{_context_acquire}} if $hub->{_context_acquire};
+
+    # This is for https://github.com/Test-More/test-more/issues/16
+    # and https://rt.perl.org/Public/Bug/Display.html?id=127774
+    my $phase = ${^GLOBAL_PHASE} || 'NA';
+    my $end_phase = $ENDING || $phase eq 'END' || $phase eq 'DESTRUCT';
+
+    my $level = 1 + $params{level};
+    my ($pkg, $file, $line, $sub) = $end_phase ? caller(0) : caller($level);
+    unless ($pkg || $end_phase) {
+        confess "Could not find context at depth $level" unless $params{fudge};
+        ($pkg, $file, $line, $sub) = caller(--$level) while ($level >= 0 && !$pkg);
+    }
+
+    my $depth = $level;
+    $depth++ while DO_DEPTH_CHECK && !$end_phase && (!$current || $depth <= $current->{_depth} + $params{wrapped}) && caller($depth + 1);
+    $depth -= $params{wrapped};
+    my $depth_ok = !DO_DEPTH_CHECK || $end_phase || !$current || $current->{_depth} < $depth;
+
+    if ($current && $params{on_release} && $depth_ok) {
+        $current->{_on_release} ||= [];
+        push @{$current->{_on_release}} => $params{on_release};
+    }
+
+    # I know this is ugly....
+    ($!, $@, $?) = ($errno, $eval_error, $child_error) and return bless(
+        {
+            %$current,
+            _is_canon   => undef,
+            errno       => $errno,
+            eval_error  => $eval_error,
+            child_error => $child_error,
+            _is_spawn   => [$pkg, $file, $line, $sub],
+        },
+        'Test2::API::Context'
+    ) if $current && $depth_ok;
+
+    # Handle error condition of bad level
+    if ($current) {
+        unless (${$current->{_aborted}}) {
+            _canon_error($current, [$pkg, $file, $line, $sub, $depth])
+                unless $current->{_is_canon};
+
+            _depth_error($current, [$pkg, $file, $line, $sub, $depth])
+                unless $depth_ok;
+        }
+
+        $current->release if $current->{_is_canon};
+
+        delete $CONTEXTS->{$hid};
+    }
+
+    # Directly bless the object here, calling new is a noticable performance
+    # hit with how often this needs to be called.
+    my $trace = bless(
+        {
+            frame => [$pkg, $file, $line, $sub],
+            pid   => $$,
+            tid   => get_tid(),
+        },
+        'Test2::Util::Trace'
+    );
+
+    # Directly bless the object here, calling new is a noticable performance
+    # hit with how often this needs to be called.
+    my $aborted = 0;
+    $current = bless(
+        {
+            _aborted     => \$aborted,
+            stack        => $stack,
+            hub          => $hub,
+            trace        => $trace,
+            _is_canon    => 1,
+            _depth       => $depth,
+            errno        => $errno,
+            eval_error   => $eval_error,
+            child_error  => $child_error,
+            $params{on_release} ? (_on_release => [$params{on_release}]) : (),
+        },
+        'Test2::API::Context'
+    );
+
+    $CONTEXTS->{$hid} = $current;
+    weaken($CONTEXTS->{$hid});
+
+    $_->($current) for @$INIT_CBS;
+    map $_->($current), @{$hub->{_context_init}} if $hub->{_context_init};
+
+    $params{on_init}->($current) if $params{on_init};
+
+    ($!, $@, $?) = ($errno, $eval_error, $child_error);
+
+    return $current;
+}
+
+sub _depth_error {
+    _existing_error(@_, <<"    EOT");
+context() was called to retrieve an existing context, however the existing
+context was created in a stack frame at the same, or deeper level. This usually
+means that a tool failed to release the context when it was finished.
+    EOT
+}
+
+sub _canon_error {
+    _existing_error(@_, <<"    EOT");
+context() was called to retrieve an existing context, however the existing
+context has an invalid internal state (!_canon_count). This should not normally
+happen unless something is mucking about with internals...
+    EOT
+}
+
+sub _existing_error {
+    my ($ctx, $details, $msg) = @_;
+    my ($pkg, $file, $line, $sub, $depth) = @$details;
+
+    my $oldframe = $ctx->{trace}->frame;
+    my $olddepth = $ctx->{_depth};
+
+    my $mess = longmess();
+
+    warn <<"    EOT";
+$msg
+Old context details:
+   File: $oldframe->[1]
+   Line: $oldframe->[2]
+   Tool: $oldframe->[3]
+  Depth: $olddepth
+
+New context details:
+   File: $file
+   Line: $line
+   Tool: $sub
+  Depth: $depth
+
+Trace: $mess
+
+Removing the old context and creating a new one...
+    EOT
+}
+
+sub release($;$) {
+    $_[0]->release;
+    return $_[1];
+}
+
+sub intercept(&) {
+    my $code = shift;
+
+    my $ctx = context();
+
+    my $ipc;
+    if (my $global_ipc = test2_ipc()) {
+        my $driver = blessed($global_ipc);
+        $ipc = $driver->new;
+    }
+
+    my $hub = Test2::Hub::Interceptor->new(
+        ipc => $ipc,
+        no_ending => 1,
+    );
+
+    my @events;
+    $hub->listen(sub { push @events => $_[1] });
+
+    $ctx->stack->top; # Make sure there is a top hub before we begin.
+    $ctx->stack->push($hub);
+
+    # Do not use 'try' cause it localizes __DIE__
+    my ($ok, $err);
+    {
+        $ok = eval { $code->(hub => $hub, context => $ctx->snapshot); 1 };
+        $err = $@;
+    }
+
+    $hub->cull;
+    $ctx->stack->pop($hub);
+
+    my $trace = $ctx->trace;
+    $ctx->release;
+
+    die $err unless $ok
+        || (blessed($err) && $err->isa('Test2::Hub::Interceptor::Terminator'));
+
+    $hub->finalize($trace, 1)
+        if $ok
+        && !$hub->no_ending
+        && !$hub->ended;
+
+    return \@events;
+}
+
+sub run_subtest {
+    my ($name, $code, $params, @args) = @_;
+
+    $params = { buffered => $params } unless ref $params;
+    my $buffered = delete $params->{buffered};
+
+    my $ctx = context();
+
+    $ctx->note($name) unless $buffered;
+
+    my $parent = $ctx->hub;
+
+    my $stack = $ctx->stack || $STACK;
+    my $hub = $stack->new_hub(
+        class => 'Test2::Hub::Subtest',
+        %$params,
+    );
+
+    my @events;
+    $hub->set_nested( $parent->isa('Test2::Hub::Subtest') ? $parent->nested + 1 : 1 );
+    $hub->listen(sub { push @events => $_[1] });
+
+    if ($buffered) {
+        if (my $format = $hub->format) {
+            my $hide = $format->can('hide_buffered') ? $format->hide_buffered : 1;
+            $hub->format(undef) if $hide;
+        }
+    }
+
+    my ($ok, $err, $finished);
+    T2_SUBTEST_WRAPPER: {
+        # Do not use 'try' cause it localizes __DIE__
+        $ok = eval { $code->(@args); 1 };
+        $err = $@;
+
+        # They might have done 'BEGIN { skip_all => "whatever" }'
+        if (!$ok && $err =~ m/Label not found for "last T2_SUBTEST_WRAPPER"/) {
+            $ok  = undef;
+            $err = undef;
+        }
+        else {
+            $finished = 1;
+        }
+    }
+    $stack->pop($hub);
+
+    my $trace = $ctx->trace;
+
+    if (!$finished) {
+        if(my $bailed = $hub->bailed_out) {
+            $ctx->bail($bailed->reason);
+        }
+        my $code = $hub->exit_code;
+        $ok = !$code;
+        $err = "Subtest ended with exit code $code" if $code;
+    }
+
+    $hub->finalize($trace, 1)
+        if $ok
+        && !$hub->no_ending
+        && !$hub->ended;
+
+    my $pass = $ok && $hub->is_passing;
+    my $e = $ctx->build_event(
+        'Subtest',
+        pass       => $pass,
+        name       => $name,
+        subtest_id => $hub->id,
+        buffered   => $buffered,
+        subevents  => \@events,
+    );
+
+    my $plan_ok = $hub->check_plan;
+
+    $ctx->hub->send($e);
+
+    $ctx->failure_diag($e) unless $e->pass;
+
+    $ctx->diag("Caught exception in subtest: $err") unless $ok;
+
+    $ctx->diag("Bad subtest plan, expected " . $hub->plan . " but ran " . $hub->count)
+        if defined($plan_ok) && !$plan_ok;
+
+    $ctx->release;
+    return $pass;
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::API - Primary interface for writing Test2 based testing tools.
+
+=head1 ***INTERNALS NOTE***
+
+B<The internals of this package are subject to change at any time!> The public
+methods provided will not change in backwords incompatible ways (once there is
+a stable release), but the underlying implementation details might.
+B<Do not break encapsulation here!>
+
+Currently the implementation is to create a single instance of the
+L<Test2::API::Instance> Object. All class methods defer to the single
+instance. There is no public access to the singleton, and that is intentional.
+The class methods provided by this package provide the only functionality
+publicly exposed.
+
+This is done primarily to avoid the problems Test::Builder had by exposing its
+singleton. We do not want anyone to replace this singleton, rebless it, or
+directly muck with its internals. If you need to do something, and cannot
+because of the restrictions placed here then please report it as an issue. If
+possible we will create a way for you to implement your functionality without
+exposing things that should not be exposed.
+
+=head1 DESCRIPTION
+
+This package exports all the functions necessary to write and/or verify testing
+tools. Using these building blocks you can begin writing test tools very
+quickly. You are also provided with tools that help you to test the tools you
+write.
+
+=head1 SYNOPSYS
+
+=head2 WRITING A TOOL
+
+The C<context()> method is your primary interface into the Test2 framework.
+
+    package My::Ok;
+    use Test2::API qw/context/;
+
+    our @EXPORT = qw/my_ok/;
+    use base 'Exporter';
+
+    # Just like ok() from Test::More
+    sub my_ok($;$) {
+        my ($bool, $name) = @_;
+        my $ctx = context(); # Get a context
+        $ctx->ok($bool, $name);
+        $ctx->release; # Release the context
+        return $bool;
+    }
+
+See L<Test2::API::Context> for a list of methods avabilable on the context object.
+
+=head2 TESTING YOUR TOOLS
+
+The C<intercept { ... }> tool lets you temporarily intercept all events
+generated by the test system:
+
+    use Test2::API qw/intercept/;
+
+    use My::Ok qw/my_ok/;
+
+    my $events = intercept {
+        # These events are not displayed
+        my_ok(1, "pass");
+        my_ok(0, "fail");
+    };
+
+    my_ok(@$events == 2, "got 2 events, the pass and the fail");
+    my_ok($events->[0]->pass, "first event passed");
+    my_ok(!$events->[1]->pass, "second event failed");
+
+=head2 OTHER API FUNCTIONS
+
+    use Test2::API qw{
+        test2_init_done
+        test2_stack
+        test2_set_is_end
+        test2_get_is_end
+        test2_ipc
+        test2_formatter_set
+        test2_formatter
+    };
+
+    my $init  = test2_init_done();
+    my $stack = test2_stack();
+    my $ipc   = test2_ipc();
+
+    test2_formatter_set($FORMATTER)
+    my $formatter = test2_formatter();
+
+    ... And others ...
+
+=head1 MAIN API EXPORTS
+
+All exports are optional, you must specify subs to import.
+
+    use Test2::API qw/context intercept run_subtest/;
+
+This is the list of exports that are most commonly needed. If you are simply
+writing a tool then this is probably all you need. If you need something and
+you cannot find it here then you can also look at L</OTHER API EXPORTS>.
+
+These exports lack the 'test2_' prefix because of how important/common they
+are. Exports in the L</OTHER API EXPORTS> section have the 'test2_' prefix to
+ensure they stand out.
+
+=head2 context(...)
+
+Usage:
+
+=over 4
+
+=item $ctx = context()
+
+=item $ctx = context(%params)
+
+=back
+
+The C<context()> function will always return the current context to you. If
+there is already a context active it will be returned. If there is not an
+active context one will be generated. When a context is generated it will
+default to using the file and line number where the currently running sub was
+called from.
+
+Please see L<Test2::API::Context/"CRITICAL DETAILS"> for important rules about
+what you can and cannot do with a context once it is obtained.
+
+B<Note> This function will throw an exception if you ignore the context object
+it returns.
+
+B<Note> On perls 5.14+ a depth check is used to insure there are no context
+leaks. This cannot be safely done on older perls due to
+L<https://rt.perl.org/Public/Bug/Display.html?id=127774>
+You can forcefully enable it either by setting C<$ENV{T2_CHECK_DEPTH} = 1> or
+C<$Test2::API::DO_DEPTH_CHECK = 1> B<BEFORE> loading L<Test2::API>.
+
+=head3 OPTIONAL PARAMETERS
+
+All parameters to C<context> are optional.
+
+=over 4
+
+=item level => $int
+
+If you must obtain a context in a sub deper than your entry point you can use
+this to tell it how many EXTRA stack frames to look back. If this option is not
+provided the default of C<0> is used.
+
+    sub third_party_tool {
+        my $sub = shift;
+        ... # Does not obtain a context
+        $sub->();
+        ...
+    }
+
+    third_party_tool(sub {
+        my $ctx = context(level => 1);
+        ...
+        $ctx->release;
+    });
+
+=item wrapped => $int
+
+Use this if you need to write your own tool that wraps a call to C<context()>
+with the intent that it should return a context object.
+
+    sub my_context {
+        my %params = ( wrapped => 0, @_ );
+        $params{wrapped}++;
+        my $ctx = context(%params);
+        ...
+        return $ctx;
+    }
+
+    sub my_tool {
+        my $ctx = my_context();
+        ...
+        $ctx->release;
+    }
+
+If you do not do this than tools you call that also check for a context will
+notice that the context they grabbed was created at the same stack depth, which
+will trigger protective measures that warn you and destroy the existing
+context.
+
+=item stack => $stack
+
+Normally C<context()> looks at the global hub stack. If you are maintaining
+your own L<Test2::API::Stack> instance you may pass it in to be used
+instead of the global one.
+
+=item hub => $hub
+
+Use this parameter if you want to obtain the context for a specific hub instead
+of whatever one happens to be at the top of the stack.
+
+=item on_init => sub { ... }
+
+This lets you provide a callback sub that will be called B<ONLY> if your call
+to C<context()> generated a new context. The callback B<WILL NOT> be called if
+C<context()> is returning an existing context. The only argument passed into
+the callback will be the context object itself.
+
+    sub foo {
+        my $ctx = context(on_init => sub { 'will run' });
+
+        my $inner = sub {
+            # This callback is not run since we are getting the existing
+            # context from our parent sub.
+            my $ctx = context(on_init => sub { 'will NOT run' });
+            $ctx->release;
+        }
+        $inner->();
+
+        $ctx->release;
+    }
+
+=item on_release => sub { ... }
+
+This lets you provide a callback sub that will be called when the context
+instance is released. This callback will be added to the returned context even
+if an existing context is returned. If multiple calls to context add callbacks
+then all will be called in reverse order when the context is finally released.
+
+    sub foo {
+        my $ctx = context(on_release => sub { 'will run second' });
+
+        my $inner = sub {
+            my $ctx = context(on_release => sub { 'will run first' });
+
+            # Neither callback runs on this release
+            $ctx->release;
+        }
+        $inner->();
+
+        # Both callbacks run here.
+        $ctx->release;
+    }
+
+=back
+
+=head2 release($;$)
+
+Usage:
+
+=over 4
+
+=item release $ctx;
+
+=item release $ctx, ...;
+
+=back
+
+This is intended as a shortcut that lets you release your context and return a
+value in one statement. This function will get your context, and an optional
+return value. It will release your context, then return your value. Scalar
+context is always assumed.
+
+    sub tool {
+        my $ctx = context();
+        ...
+
+        return release $ctx, 1;
+    }
+
+This tool is most useful when you want to return the value you get from calling
+a function that needs to see the current context:
+
+    my $ctx = context();
+    my $out = some_tool(...);
+    $ctx->release;
+    return $out;
+
+We can combine the last 3 lines of the above like so:
+
+    my $ctx = context();
+    release $ctx, some_tool(...);
+
+=head2 context_do(&;@)
+
+Usage:
+
+    sub my_tool {
+        context_do {
+            my $ctx = shift;
+
+            my (@args) = @_;
+
+            $ctx->ok(1, "pass");
+
+            ...
+
+            # No need to call $ctx->release, done for you on scope exit.
+        } @_;
+    }
+
+Using this inside your test tool takes care of a lot of boilerplate for you. It
+will ensure a context is acquired. It will capture and rethrow any exception. It
+will insure the context is released when you are done. It preserves the
+subroutine call context (array, scalar, void).
+
+This is the safest way to write a test tool. The only 2 downsides to this are a
+slight performance decrease, and some extra indentation in your source. If the
+indentation is a problem for you then you can take a peek at the next section.
+
+=head2 no_context(&;$)
+
+Usage:
+
+=over 4
+
+=item no_context { ... };
+
+=item no_context { ... } $hid;
+
+    sub my_tool(&) {
+        my $code = shift;
+        my $ctx = context();
+        ...
+
+        no_context {
+            # Things in here will not see our current context, they get a new
+            # one.
+
+            $code->();
+        };
+
+        ...
+        $ctx->release;
+    };
+
+=back
+
+This tool will hide a context for the provided block of code. This means any
+tools run inside the block will get a completely new context if they acquire
+one. The new context will be inherited by tools nested below the one that
+acquired it.
+
+This will normally hide the current context for the top hub. If you need to
+hide the context for a different hub you can pass in the optional C<$hid>
+parameter.
+
+=head2 intercept(&)
+
+Usage:
+
+    my $events = intercept {
+        ok(1, "pass");
+        ok(0, "fail");
+        ...
+    };
+
+This function takes a codeblock as its only argument, and it has a prototype.
+It will execute the codeblock, intercepting any generated events in the
+process. It will return an array reference with all the generated event
+objects. All events should be subclasses of L<Test2::Event>.
+
+This is a very low-level subtest tool. This is useful for writing tools which
+produce subtests. This is not intended for people simply writing tests.
+
+=head2 run_subtest(...)
+
+Usage:
+
+    run_subtest($NAME, \&CODE, $BUFFERED, @ARGS)
+
+    # or
+
+    run_subtest($NAME, \&CODE, \%PARAMS, @ARGS)
+
+This will run the provided codeblock with the args in C<@args>. This codeblock
+will be run as a subtest. A subtest is an isolated test state that is condensed
+into a single L<Test2::Event::Subtest> event, which contains all events
+generated inside the subtest.
+
+=head3 ARGUMENTS:
+
+=over 4
+
+=item $NAME
+
+The name of the subtest.
+
+=item \&CODE
+
+The code to run inside the subtest.
+
+=item $BUFFERED or \%PARAMS
+
+If this is a simple scalar then it will be treated as a boolean for the
+'buffered' setting. If this is a hash reference then it wil be used as a
+parameters hash. The param hash will be used for hub construction (with the
+'buffered' key removed).
+
+If this is true, or a hashref with a true value for the 'buffered' key, then
+the subtest will be buffered.
+
+=item @ARGS
+
+Any extra arguments you want passed into the subtest code.
+
+=back
+
+=head3 BUFFERED VS UNBUFFERED (OR STREAMED)
+
+Normally all events inside and outside a subtest are sent to the formatter
+immedietly by the hub. Sometimes it is desirable to hold off sending events
+within a subtest until the subtest is complete. This usually depends on the
+formatter being used.
+
+=over 4
+
+=item Things not effected by this flag
+
+In both cases events are generated and stored in an array. This array is
+eventually used to populate the C<subevents> attribute on the
+L<Test2::Event::Subtest> event that is generated at the end of the subtest.
+This flag has no effect on this part, it always happens.
+
+At the end of the subtest the final L<Test2::Event::Subtest> event is sent to
+the formatter.
+
+=item Things that are effected by this flag
+
+The C<buffered> attribute of the L<Test2::Event::Subtest> event will be set to
+the value of this flag. This means any formatter, listener, etc which looks at
+the event will know if it was buffered.
+
+=item Things that are formatter dependant
+
+Events within a buffered subtest may or may not be sent to the formatter as
+they happen. If a formatter fails to specify then the default is to B<NOT SEND>
+the events as they are generated, instead the formatter can pull them from the
+C<subevents> attribute.
+
+A formatter can specify by implementing the C<hide_buffered()> method. If this
+method returns true then events generated inside a buffered subtest will not be
+sent independantly of the final subtest event.
+
+=back
+
+An example of how this is used is the L<Test2::Formatter::TAP> formatter. For
+unbuffered subtests the events are rendered as they are generated. At the end
+of the subtest the final subtest event is rendered, but the C<subevents>
+attribute is ignored. For buffered subtests the opposite occurs, the events are
+NOT rendered as they are generated, instead the C<subevents> attribute is used
+to render them all at once. This is useful when running subtests tests in
+parallel, without it the subtests would be garbled.
+
+=head1 OTHER API EXPORTS
+
+Exports in this section are not commonly needed. These all have the 'test2_'
+prefix to help ensure they stand out. You should look at the L</MAIN API
+EXPORTS> section before looking here. This section is one where "Great power
+comes with great responsiblity". It is possible to break things badly if you
+are not careful with these.
+
+All exports are optional, you need to list which ones you want at import time:
+
+    use Test2::API qw/test2_init_done .../;
+
+=head2 STATUS AND INITIALIZATION STATE
+
+These provide access to internal state and object instances.
+
+=over 4
+
+=item $bool = test2_init_done()
+
+This will return true if the stack and ipc instances have already been
+initialized. It will return false if they have not. Init happens as late as
+possible, it happens as soon as a tool requests the ipc instance, the
+formatter, or the stack.
+
+=item $bool = test2_load_done()
+
+This will simply return the boolean value of the loaded flag. If Test2 has
+finished loading this will be true, otherwise false. Loading is considered
+complete the first time a tool requests a context.
+
+=item test2_set_is_end()
+
+=item test2_set_is_end($bool)
+
+This is used to toggle Test2's belief that the END phase has already started.
+With no arguments this will set it to true. With arguments it will set it to
+the first argument's value.
+
+This is used to prevent the use of C<caller()> in END blocks which can cause
+segfaults. This is only necessary in some persistent environments that may have
+multiple END phases.
+
+=item $bool = test2_get_is_end()
+
+Check if test2 believes it is the END phase.
+
+=item $stack = test2_stack()
+
+This will return the global L<Test2::API::Stack> instance. If this has not
+yet been initialized it will be initialized now.
+
+=item $bool = test2_no_wait()
+
+=item test2_no_wait($bool)
+
+This can be used to get/set the no_wait status. Waiting is turned on by
+default. Waiting will cause the parent process/thread to wait until all child
+processes and threads are finished before exiting. You will almost never want
+to turn this off.
+
+=back
+
+=head2 BEHAVIOR HOOKS
+
+These are hooks that allow you to add custom behavior to actions taken by Test2
+and tools built on top of it.
+
+=over 4
+
+=item test2_add_callback_exit(sub { ... })
+
+This can be used to add a callback that is called after all testing is done. This
+is too late to add additional results, the main use of this callback is to set the
+exit code.
+
+    test2_add_callback_exit(
+        sub {
+            my ($context, $exit, \$new_exit) = @_;
+            ...
+        }
+    );
+
+The C<$context> passed in will be an instance of L<Test2::API::Context>. The
+C<$exit> argument will be the original exit code before anything modified it.
+C<$$new_exit> is a reference to the new exit code. You may modify this to
+change the exit code. Please note that C<$$new_exit> may already be different
+from C<$exit>
+
+=item test2_add_callback_post_load(sub { ... })
+
+Add a callback that will be called when Test2 is finished loading. This
+means the callback will be run once, the first time a context is obtained.
+If Test2 has already finished loading then the callback will be run immedietly.
+
+=item test2_add_callback_context_acquire(sub { ... })
+
+Add a callback that will be called every time someone tries to acquire a
+context. This will be called on EVERY call to C<context()>. It gets a single
+argument, a reference the the hash of parameters being used the construct the
+context. This is your chance to change the parameters by directly altering the
+hash.
+
+    test2_add_callback_context_acquire(sub {
+        my $params = shift;
+        $params->{level}++;
+    });
+
+This is a very scary API function. Please do not use this unless you need to.
+This is here for L<Test::Builder> and backwards compatibility. This has you
+directly manipulate the hash instead of returning a new one for performance
+reasons.
+
+=item test2_add_callback_context_init(sub { ... })
+
+Add a callback that will be called every time a new context is created. The
+callback will receive the newly created context as its only argument.
+
+=item test2_add_callback_context_release(sub { ... })
+
+Add a callback that will be called every time a context is released. The
+callback will receive the released context as its only argument.
+
+=item @list = test2_list_context_acquire_callbacks()
+
+Return all the context acquire callback references.
+
+=item @list = test2_list_context_init_callbacks()
+
+Returns all the context init callback references.
+
+=item @list = test2_list_context_release_callbacks()
+
+Returns all the context release callback references.
+
+=item @list = test2_list_exit_callbacks()
+
+Returns all the exit callback references.
+
+=item @list = test2_list_post_load_callbacks()
+
+Returns all the post load callback references.
+
+=back
+
+=head2 IPC AND CONCURRENCY
+
+These let you access, or specify, the IPC system internals.
+
+=over 4
+
+=item $ipc = test2_ipc()
+
+This will return the global L<Test2::IPC::Driver> instance. If this has not yet
+been initialized it will be initialized now.
+
+=item test2_ipc_add_driver($DRIVER)
+
+Add an IPC driver to the list. This will add the driver to the start of the
+list.
+
+=item @drivers = test2_ipc_drivers()
+
+Get the list of IPC drivers.
+
+=item $bool = test2_ipc_polling()
+
+Check if polling is enabled.
+
+=item test2_ipc_enable_polling()
+
+Turn on polling. This will cull events from other processes and threads every
+time a context is created.
+
+=item test2_ipc_disable_polling()
+
+Turn off IPC polling.
+
+=item test2_ipc_enable_shm()
+
+Turn on IPC shm. Only some IPC drivers use this, and most will turn it on
+themselves.
+
+=item test2_ipc_set_pending($uniq_val)
+
+Tell other processes and events that an event is pending. C<$uniq_val> should
+be a unique value no other thread/process will generate.
+
+B<Note:> After calling this C<test2_ipc_get_pending()> will return 1. This is
+intentional, and not avoidable.
+
+=item $pending = test2_ipc_get_pending()
+
+This returns -1 if there is no way to check (assume yes)
+
+This returns 0 if there are (most likely) no pending events.
+
+This returns 1 if there are (likely) pending events. Upon return it will reset,
+nothing else will be able to see that there were pending events.
+
+=back
+
+=head2 MANAGING FORMATTERS
+
+These let you access, or specify, the formatters that can/should be used.
+
+=over 4
+
+=item $formatter = test2_formatter
+
+This will return the global formatter class. This is not an instance. By
+default the formatter is set to L<Test2::Formatter::TAP>.
+
+You can override this default using the C<T2_FORMATTER> environment variable.
+
+Normally 'Test2::Formatter::' is prefixed to the value in the
+environment variable:
+
+    $ T2_FORMATTER='TAP' perl test.t     # Use the Test2::Formatter::TAP formatter
+    $ T2_FORMATTER='Foo' perl test.t     # Use the Test2::Formatter::Foo formatter
+
+If you want to specify a full module name you use the '+' prefix:
+
+    $ T2_FORMATTER='+Foo::Bar' perl test.t     # Use the Foo::Bar formatter
+
+=item test2_formatter_set($class_or_instance)
+
+Set the global formatter class. This can only be set once. B<Note:> This will
+override anything specified in the 'T2_FORMATTER' environment variable.
+
+=item @formatters = test2_formatters()
+
+Get a list of all loaded formatters.
+
+=item test2_formatter_add($class_or_instance)
+
+Add a formatter to the list. Last formatter added is used at initialization. If
+this is called after initialization a warning will be issued.
+
+=back
+
+=head1 OTHER EXAMPLES
+
+See the C</Examples/> directory included in this distribution.
+
+=head1 SEE ALSO
+
+L<Test2::API::Context> - Detailed documentation of the context object.
+
+L<Test2::IPC> - The IPC system used for threading/fork support.
+
+L<Test2::Formatter> - Formatters such as TAP live here.
+
+L<Test2::Event> - Events live in this namespace.
+
+L<Test2::Hub> - All events eventually funnel through a hub. Custom hubs are how
+C<intercept()> and C<run_subtest()> are implemented.
+
+=head1 MAGIC
+
+This package has an END block. This END block is responsible for setting the
+exit code based on the test results. This end block also calls the callbacks that
+can be added to this package.
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/API/Breakage.pm b/cpan/Test-Simple/lib/Test2/API/Breakage.pm
new file mode 100644 (file)
index 0000000..c0cbc24
--- /dev/null
@@ -0,0 +1,172 @@
+package Test2::API::Breakage;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use Test2::Util qw/pkg_to_file/;
+
+our @EXPORT_OK = qw{
+    upgrade_suggested
+    upgrade_required
+    known_broken
+};
+use base 'Exporter';
+
+sub upgrade_suggested {
+    return (
+        'Test::Exception'    => '0.42',
+        'Test::FITesque'     => '0.04',
+        'Test::Module::Used' => '0.2.5',
+        'Test::Moose::More'  => '0.025',
+    );
+}
+
+sub upgrade_required {
+    return (
+        'Test::Builder::Clutch'   => '0.07',
+        'Test::Dist::VersionSync' => '1.1.4',
+        'Test::Modern'            => '0.012',
+        'Test::SharedFork'        => '0.34',
+        'Test::Alien'             => '0.04',
+
+        'Test::Clustericious::Cluster' => '0.30',
+    );
+}
+
+sub known_broken {
+    return (
+        'Net::BitTorrent'       => '0.052',
+        'Test::Able'            => '0.11',
+        'Test::Aggregate'       => '0.373',
+        'Test::Flatten'         => '0.11',
+        'Test::Group'           => '0.20',
+        'Test::More::Prefix'    => '0.005',
+        'Test::ParallelSubtest' => '0.05',
+        'Test::Pretty'          => '0.32',
+        'Test::Wrapper'         => '0.3.0',
+
+        'Test::DBIx::Class::Schema'      => '1.0.9',
+        'Log::Dispatch::Config::TestLog' => '0.02',
+    );
+}
+
+# Not reportable:
+# Device::Chip => 0.07   - Tests will not pass, but not broken if already installed, also no fixed version we can upgrade to.
+
+sub report {
+    my $class = shift;
+    my ($require) = @_;
+
+    my %suggest  = __PACKAGE__->upgrade_suggested();
+    my %required = __PACKAGE__->upgrade_required();
+    my %broken   = __PACKAGE__->known_broken();
+
+    my @warn;
+    for my $mod (keys %suggest) {
+        my $file = pkg_to_file($mod);
+        next unless $INC{$file} || ($require && eval { require $file; 1 });
+        my $want = $suggest{$mod};
+        next if eval { $mod->VERSION($want); 1 };
+        push @warn => " * Module '$mod' is outdated, we recommed updating above $want.";
+    }
+
+    for my $mod (keys %required) {
+        my $file = pkg_to_file($mod);
+        next unless $INC{$file} || ($require && eval { require $file; 1 });
+        my $want = $required{$mod};
+        next if eval { $mod->VERSION($want); 1 };
+        push @warn => " * Module '$mod' is outdated and known to be broken, please update to $want or higher.";
+    }
+
+    for my $mod (keys %broken) {
+        my $file = pkg_to_file($mod);
+        next unless $INC{$file} || ($require && eval { require $file; 1 });
+        my $tested = $broken{$mod};
+        push @warn => " * Module '$mod' is known to be broken in version $tested and below, newer versions have not been tested. You have: " . $mod->VERSION;
+    }
+
+    return @warn;
+}
+
+1;
+
+__END__
+
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::API::Breakage - What breaks at what version
+
+=head1 DESCRIPTION
+
+This module provides lists of modules that are broken, or have been broken in
+the past, when upgrading L<Test::Builder> to use L<Test2>.
+
+=head1 FUNCTIONS
+
+These can be imported, or called as methods on the class.
+
+=over 4
+
+=item %mod_ver = upgrade_suggested()
+
+=item %mod_ver = Test2::API::Breakage->upgrade_suggested()
+
+This returns key/value pairs. The key is the module name, the value is the
+version number. If the installed version of the module is at or below the
+specified one then an upgrade would be a good idea, but not strictly necessary.
+
+=item %mod_ver = upgrade_required()
+
+=item %mod_ver = Test2::API::Breakage->upgrade_required()
+
+This returns key/value pairs. The key is the module name, the value is the
+version number. If the installed version of the module is at or below the
+specified one then an upgrade is required for the module to work properly.
+
+=item %mod_ver = known_broken()
+
+=item %mod_ver = Test2::API::Breakage->known_broken()
+
+This returns key/value pairs. The key is the module name, the value is the
+version number. If the installed version of the module is at or below the
+specified one then the module will not work. A newer version may work, but is
+not tested or verified.
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/API/Context.pm b/cpan/Test-Simple/lib/Test2/API/Context.pm
new file mode 100644 (file)
index 0000000..80f57b6
--- /dev/null
@@ -0,0 +1,713 @@
+package Test2::API::Context;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use Carp qw/confess croak longmess/;
+use Scalar::Util qw/weaken/;
+use Test2::Util qw/get_tid try pkg_to_file get_tid/;
+
+use Test2::Util::Trace();
+use Test2::API();
+
+# Preload some key event types
+my %LOADED = (
+    map {
+        my $pkg  = "Test2::Event::$_";
+        my $file = "Test2/Event/$_.pm";
+        require $file unless $INC{$file};
+        ( $pkg => $pkg, $_ => $pkg )
+    } qw/Ok Diag Note Plan Bail Exception Waiting Skip Subtest/
+);
+
+use Test2::Util::ExternalMeta qw/meta get_meta set_meta delete_meta/;
+use Test2::Util::HashBase qw{
+    stack hub trace _on_release _depth _is_canon _is_spawn _aborted
+    errno eval_error child_error
+};
+
+# Private, not package vars
+# It is safe to cache these.
+my $ON_RELEASE = Test2::API::_context_release_callbacks_ref();
+my $CONTEXTS   = Test2::API::_contexts_ref();
+
+sub init {
+    my $self = shift;
+
+    confess "The 'trace' attribute is required"
+        unless $self->{+TRACE};
+
+    confess "The 'hub' attribute is required"
+        unless $self->{+HUB};
+
+    $self->{+_DEPTH} = 0 unless defined $self->{+_DEPTH};
+
+    $self->{+ERRNO}       = $! unless exists $self->{+ERRNO};
+    $self->{+EVAL_ERROR}  = $@ unless exists $self->{+EVAL_ERROR};
+    $self->{+CHILD_ERROR} = $? unless exists $self->{+CHILD_ERROR};
+}
+
+sub snapshot { bless {%{$_[0]}, _is_canon => undef, _is_spawn => undef, _aborted => undef}, __PACKAGE__ }
+
+sub restore_error_vars {
+    my $self = shift;
+    ($!, $@, $?) = @$self{+ERRNO, +EVAL_ERROR, +CHILD_ERROR};
+}
+
+sub DESTROY {
+    return unless $_[0]->{+_IS_CANON} || $_[0]->{+_IS_SPAWN};
+    return if $_[0]->{+_ABORTED} && ${$_[0]->{+_ABORTED}};
+    my ($self) = @_;
+
+    my $hub = $self->{+HUB};
+    my $hid = $hub->{hid};
+
+    # Do not show the warning if it looks like an exception has been thrown, or
+    # if the context is not local to this process or thread.
+    if($self->{+EVAL_ERROR} eq $@ && $hub->is_local) {
+        my $frame = $self->{+_IS_SPAWN} || $self->{+TRACE}->frame;
+        warn <<"        EOT";
+A context appears to have been destroyed without first calling release().
+Based on \$@ it does not look like an exception was thrown (this is not always
+a reliable test)
+
+This is a problem because the global error variables (\$!, \$@, and \$?) will
+not be restored. In addition some release callbacks will not work properly from
+inside a DESTROY method.
+
+Here are the context creation details, just in case a tool forgot to call
+release():
+  File: $frame->[1]
+  Line: $frame->[2]
+  Tool: $frame->[3]
+
+Cleaning up the CONTEXT stack...
+        EOT
+    }
+
+    return if $self->{+_IS_SPAWN};
+
+    # Remove the key itself to avoid a slow memory leak
+    delete $CONTEXTS->{$hid};
+    $self->{+_IS_CANON} = undef;
+
+    if (my $cbk = $self->{+_ON_RELEASE}) {
+        $_->($self) for reverse @$cbk;
+    }
+    if (my $hcbk = $hub->{_context_release}) {
+        $_->($self) for reverse @$hcbk;
+    }
+    $_->($self) for reverse @$ON_RELEASE;
+}
+
+# release exists to implement behaviors like die-on-fail. In die-on-fail you
+# want to die after a failure, but only after diagnostics have been reported.
+# The ideal time for the die to happen is when the context is released.
+# Unfortunately die does not work in a DESTROY block.
+sub release {
+    my ($self) = @_;
+
+    ($!, $@, $?) = @$self{+ERRNO, +EVAL_ERROR, +CHILD_ERROR} and return $self->{+_IS_SPAWN} = undef
+        if $self->{+_IS_SPAWN};
+
+    croak "release() should not be called on context that is neither canon nor a child"
+        unless $self->{+_IS_CANON};
+
+    my $hub = $self->{+HUB};
+    my $hid = $hub->{hid};
+
+    croak "context thinks it is canon, but it is not"
+        unless $CONTEXTS->{$hid} && $CONTEXTS->{$hid} == $self;
+
+    # Remove the key itself to avoid a slow memory leak
+    $self->{+_IS_CANON} = undef;
+    delete $CONTEXTS->{$hid};
+
+    if (my $cbk = $self->{+_ON_RELEASE}) {
+        $_->($self) for reverse @$cbk;
+    }
+    if (my $hcbk = $hub->{_context_release}) {
+        $_->($self) for reverse @$hcbk;
+    }
+    $_->($self) for reverse @$ON_RELEASE;
+
+    # Do this last so that nothing else changes them.
+    # If one of the hooks dies then these do not get restored, this is
+    # intentional
+    ($!, $@, $?) = @$self{+ERRNO, +EVAL_ERROR, +CHILD_ERROR};
+
+    return;
+}
+
+sub do_in_context {
+    my $self = shift;
+    my ($sub, @args) = @_;
+
+    # We need to update the pid/tid and error vars.
+    my $clone = $self->snapshot;
+    @$clone{+ERRNO, +EVAL_ERROR, +CHILD_ERROR} = ($!, $@, $?);
+    $clone->{+TRACE} = $clone->{+TRACE}->snapshot;
+    $clone->{+TRACE}->set_pid($$);
+    $clone->{+TRACE}->set_tid(get_tid());
+
+    my $hub = $clone->{+HUB};
+    my $hid = $hub->hid;
+
+    my $old = $CONTEXTS->{$hid};
+
+    $clone->{+_IS_CANON} = 1;
+    $CONTEXTS->{$hid} = $clone;
+    weaken($CONTEXTS->{$hid});
+    my ($ok, $err) = &try($sub, @args);
+    my ($rok, $rerr) = try { $clone->release };
+    delete $clone->{+_IS_CANON};
+
+    if ($old) {
+        $CONTEXTS->{$hid} = $old;
+        weaken($CONTEXTS->{$hid});
+    }
+    else {
+        delete $CONTEXTS->{$hid};
+    }
+
+    die $err  unless $ok;
+    die $rerr unless $rok;
+}
+
+sub done_testing {
+    my $self = shift;
+    $self->hub->finalize($self->trace, 1);
+    return;
+}
+
+sub throw {
+    my ($self, $msg) = @_;
+    ${$self->{+_ABORTED}}++ if $self->{+_ABORTED};
+    $self->release if $self->{+_IS_CANON} || $self->{+_IS_SPAWN};
+    $self->trace->throw($msg);
+}
+
+sub alert {
+    my ($self, $msg) = @_;
+    $self->trace->alert($msg);
+}
+
+sub send_event {
+    my $self  = shift;
+    my $event = shift;
+    my %args  = @_;
+
+    my $pkg = $LOADED{$event} || $self->_parse_event($event);
+
+    $self->{+HUB}->send(
+        $pkg->new(
+            trace => $self->{+TRACE}->snapshot,
+            %args,
+        )
+    );
+}
+
+sub build_event {
+    my $self  = shift;
+    my $event = shift;
+    my %args  = @_;
+
+    my $pkg = $LOADED{$event} || $self->_parse_event($event);
+
+    $pkg->new(
+        trace => $self->{+TRACE}->snapshot,
+        %args,
+    );
+}
+
+sub ok {
+    my $self = shift;
+    my ($pass, $name, $diag) = @_;
+
+    my $hub = $self->{+HUB};
+
+    my $e = bless {
+        trace => bless( {%{$self->{+TRACE}}}, 'Test2::Util::Trace'),
+        pass  => $pass,
+        name  => $name,
+    }, 'Test2::Event::Ok';
+    $e->init;
+
+    $hub->send($e);
+    return $e if $pass;
+
+    $self->failure_diag($e);
+
+    if ($diag && @$diag) {
+        $self->diag($_) for @$diag
+    }
+
+    return $e;
+}
+
+sub failure_diag {
+    my $self = shift;
+    my ($e) = @_;
+
+    # This behavior is inherited from Test::Builder which injected a newline at
+    # the start of the first diagnostics when the harness is active, but not
+    # verbose. This is important to keep the diagnostics from showing up
+    # appended to the existing line, which is hard to read. In a verbose
+    # harness there is no need for this.
+    my $prefix = $ENV{HARNESS_ACTIVE} && !$ENV{HARNESS_IS_VERBOSE} ? "\n" : "";
+
+    # Figure out the debug info, this is typically the file name and line
+    # number, but can also be a custom message. If no trace object is provided
+    # then we have nothing useful to display.
+    my $name  = $e->name;
+    my $trace = $e->trace;
+    my $debug = $trace ? $trace->debug : "[No trace info available]";
+
+    # Create the initial diagnostics. If the test has a name we put the debug
+    # info on a second line, this behavior is inherited from Test::Builder.
+    my $msg = defined($name)
+        ? qq[${prefix}Failed test '$name'\n$debug.\n]
+        : qq[${prefix}Failed test $debug.\n];
+
+    $self->diag($msg);
+}
+
+sub skip {
+    my $self = shift;
+    my ($name, $reason, @extra) = @_;
+    $self->send_event(
+        'Skip',
+        name => $name,
+        reason => $reason,
+        pass => 1,
+        @extra,
+    );
+}
+
+sub note {
+    my $self = shift;
+    my ($message) = @_;
+    $self->send_event('Note', message => $message);
+}
+
+sub diag {
+    my $self = shift;
+    my ($message) = @_;
+    my $hub = $self->{+HUB};
+    $self->send_event(
+        'Diag',
+        message => $message,
+    );
+}
+
+sub plan {
+    my ($self, $max, $directive, $reason) = @_;
+    ${$self->{+_ABORTED}}++ if $self->{+_ABORTED} && $directive && $directive =~ m/^(SKIP|skip_all)$/;
+    $self->send_event('Plan', max => $max, directive => $directive, reason => $reason);
+}
+
+sub bail {
+    my ($self, $reason) = @_;
+    ${$self->{+_ABORTED}}++ if $self->{+_ABORTED};
+    $self->send_event('Bail', reason => $reason);
+}
+
+sub _parse_event {
+    my $self = shift;
+    my $event = shift;
+
+    my $pkg;
+    if ($event =~ m/^\+(.*)/) {
+        $pkg = $1;
+    }
+    else {
+        $pkg = "Test2::Event::$event";
+    }
+
+    unless ($LOADED{$pkg}) {
+        my $file = pkg_to_file($pkg);
+        my ($ok, $err) = try { require $file };
+        $self->throw("Could not load event module '$pkg': $err")
+            unless $ok;
+
+        $LOADED{$pkg} = $pkg;
+    }
+
+    confess "'$pkg' is not a subclass of 'Test2::Event'"
+        unless $pkg->isa('Test2::Event');
+
+    $LOADED{$event} = $pkg;
+
+    return $pkg;
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::API::Context - Object to represent a testing context.
+
+=head1 DESCRIPTION
+
+The context object is the primary interface for authors of testing tools
+written with L<Test2>. The context object represents the context in
+which a test takes place (File and Line Number), and provides a quick way to
+generate events from that context. The context object also takes care of
+sending events to the correct L<Test2::Hub> instance.
+
+=head1 SYNOPSIS
+
+In general you will not be creating contexts directly. To obtain a context you
+should always use C<context()> which is exported by the L<Test2::API> module.
+
+    use Test2::API qw/context/;
+
+    sub my_ok {
+        my ($bool, $name) = @_;
+        my $ctx = context();
+        $ctx->ok($bool, $name);
+        $ctx->release; # You MUST do this!
+        return $bool;
+    }
+
+Context objects make it easy to wrap other tools that also use context. Once
+you grab a context, any tool you call before releasing your context will
+inherit it:
+
+    sub wrapper {
+        my ($bool, $name) = @_;
+        my $ctx = context();
+        $ctx->diag("wrapping my_ok");
+
+        my $out = my_ok($bool, $name);
+        $ctx->release; # You MUST do this!
+        return $out;
+    }
+
+=head1 CRITICAL DETAILS
+
+=over 4
+
+=item you MUST always use the context() sub from Test2::API
+
+Creating your own context via C<< Test2::API::Context->new() >> will almost never
+produce a desirable result. Use C<context()> which is exported by L<Test2>.
+
+There are a handful of cases where a tool author may want to create a new
+context by hand, which is why the C<new> method exists. Unless you really know
+what you are doing you should avoid this.
+
+=item You MUST always release the context when done with it
+
+Releasing the context tells the system you are done with it. This gives it a
+chance to run any necessary callbacks or cleanup tasks. If you forget to
+release the context it will try to detect the problem and warn you about it.
+
+=item You MUST NOT pass context objects around
+
+When you obtain a context object it is made specifically for your tool and any
+tools nested within. If you pass a context around you run the risk of polluting
+other tools with incorrect context information.
+
+If you are certain that you want a different tool to use the same context you
+may pass it a snapshot. C<< $ctx->snapshot >> will give you a shallow clone of
+the context that is safe to pass around or store.
+
+=item You MUST NOT store or cache a context for later
+
+As long as a context exists for a given hub, all tools that try to get a
+context will get the existing instance. If you try to store the context you
+will pollute other tools with incorrect context information.
+
+If you are certain that you want to save the context for later, you can use a
+snapshot. C<< $ctx->snapshot >> will give you a shallow clone of the context
+that is safe to pass around or store.
+
+C<context()> has some mechanisms to protect you if you do cause a context to
+persist beyond the scope in which it was obtained. In practice you should not
+rely on these protections, and they are fairly noisy with warnings.
+
+=item You SHOULD obtain your context as soon as possible in a given tool
+
+You never know what tools you call from within your own tool will need a
+context. Obtaining the context early ensures that nested tools can find the
+context you want them to find.
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item $ctx->done_testing;
+
+Note that testing is finished. If no plan has been set this will generate a
+Plan event.
+
+=item $clone = $ctx->snapshot()
+
+This will return a shallow clone of the context. The shallow clone is safe to
+store for later.
+
+=item $ctx->release()
+
+This will release the context. This runs cleanup tasks, and several important
+hooks. It will also restore C<$!>, C<$?>, and C<$@> to what they were when the
+context was created.
+
+B<Note:> If a context is acquired more than once an internal refcount is kept.
+C<release()> decrements the ref count, none of the other actions of
+C<release()> will occur unless the refcount hits 0. This means only the last
+call to C<release()> will reset C<$?>, C<$!>, C<$@>,and run the cleanup tasks.
+
+=item $ctx->throw($message)
+
+This will throw an exception reporting to the file and line number of the
+context. This will also release the context for you.
+
+=item $ctx->alert($message)
+
+This will issue a warning from the file and line number of the context.
+
+=item $stack = $ctx->stack()
+
+This will return the L<Test2::API::Stack> instance the context used to find
+the current hub.
+
+=item $hub = $ctx->hub()
+
+This will return the L<Test2::Hub> instance the context recognises as
+the current one to which all events should be sent.
+
+=item $dbg = $ctx->trace()
+
+This will return the L<Test2::Util::Trace> instance used by the context.
+
+=item $ctx->do_in_context(\&code, @args);
+
+Sometimes you have a context that is not current, and you want things to use it
+as the current one. In these cases you can call
+C<< $ctx->do_in_context(sub { ... }) >>. The codeblock will be run, and
+anything inside of it that looks for a context will find the one on which the
+method was called.
+
+This B<DOES NOT> affect context on other hubs, only the hub used by the context
+will be affected.
+
+    my $ctx = ...;
+    $ctx->do_in_context(sub {
+        my $ctx = context(); # returns the $ctx the sub is called on
+    });
+
+B<Note:> The context will actually be cloned, the clone will be used instead of
+the original. This allows the TID, PID, and error vars to be correct without
+modifying the original context.
+
+=item $ctx->restore_error_vars()
+
+This will set C<$!>, C<$?>, and C<$@> to what they were when the context was
+created. There is no localization or anything done here, calling this method
+will actually set these vars.
+
+=item $! = $ctx->errno()
+
+The (numeric) value of C<$!> when the context was created.
+
+=item $? = $ctx->child_error()
+
+The value of C<$?> when the context was created.
+
+=item $@ = $ctx->eval_error()
+
+The value of C<$@> when the context was created.
+
+=back
+
+=head2 EVENT PRODUCTION METHODS
+
+=over 4
+
+=item $event = $ctx->ok($bool, $name)
+
+=item $event = $ctx->ok($bool, $name, \@diag)
+
+This will create an L<Test2::Event::Ok> object for you. If C<$bool> is false
+then an L<Test2::Event::Diag> event will be sent as well with details about the
+failure. If you do not want automatic diagnostics you should use the
+C<send_event()> method directly.
+
+The C<\@diag> can contain diagnostics messages you wish to have displayed in the
+event of a failure. For a passing test the diagnostics array will be ignored.
+
+=item $event = $ctx->note($message)
+
+Send an L<Test2::Event::Note>. This event prints a message to STDOUT.
+
+=item $event = $ctx->diag($message)
+
+Send an L<Test2::Event::Diag>. This event prints a message to STDERR.
+
+=item $event = $ctx->plan($max)
+
+=item $event = $ctx->plan(0, 'SKIP', $reason)
+
+This can be used to send an L<Test2::Event::Plan> event. This event
+usually takes either a number of tests you expect to run. Optionally you can
+set the expected count to 0 and give the 'SKIP' directive with a reason to
+cause all tests to be skipped.
+
+=item $event = $ctx->skip($name, $reason);
+
+Send an L<Test2::Event::Skip> event.
+
+=item $event = $ctx->bail($reason)
+
+This sends an L<Test2::Event::Bail> event. This event will completely
+terminate all testing.
+
+=item $event = $ctx->send_event($Type, %parameters)
+
+This lets you build and send an event of any type. The C<$Type> argument should
+be the event package name with C<Test2::Event::> left off, or a fully
+qualified package name prefixed with a '+'. The event is returned after it is
+sent.
+
+    my $event = $ctx->send_event('Ok', ...);
+
+or
+
+    my $event = $ctx->send_event('+Test2::Event::Ok', ...);
+
+=item $event = $ctx->build_event($Type, %parameters)
+
+This is the same as C<send_event()>, except it builds and returns the event
+without sending it.
+
+=back
+
+=head1 HOOKS
+
+There are 2 types of hooks, init hooks, and release hooks. As the names
+suggest, these hooks are triggered when contexts are created or released.
+
+=head2 INIT HOOKS
+
+These are called whenever a context is initialized. That means when a new
+instance is created. These hooks are B<NOT> called every time something
+requests a context, just when a new one is created.
+
+=head3 GLOBAL
+
+This is how you add a global init callback. Global callbacks happen for every
+context for any hub or stack.
+
+    Test2::API::test2_add_callback_context_init(sub {
+        my $ctx = shift;
+        ...
+    });
+
+=head3 PER HUB
+
+This is how you add an init callback for all contexts created for a given hub.
+These callbacks will not run for other hubs.
+
+    $hub->add_context_init(sub {
+        my $ctx = shift;
+        ...
+    });
+
+=head3 PER CONTEXT
+
+This is how you specify an init hook that will only run if your call to
+C<context()> generates a new context. The callback will be ignored if
+C<context()> is returning an existing context.
+
+    my $ctx = context(on_init => sub {
+        my $ctx = shift;
+        ...
+    });
+
+=head2 RELEASE HOOKS
+
+These are called whenever a context is released. That means when the last
+reference to the instance is about to be destroyed. These hooks are B<NOT>
+called every time C<< $ctx->release >> is called.
+
+=head3 GLOBAL
+
+This is how you add a global release callback. Global callbacks happen for every
+context for any hub or stack.
+
+    Test2::API::test2_add_callback_context_release(sub {
+        my $ctx = shift;
+        ...
+    });
+
+=head3 PER HUB
+
+This is how you add a release callback for all contexts created for a given
+hub. These callbacks will not run for other hubs.
+
+    $hub->add_context_release(sub {
+        my $ctx = shift;
+        ...
+    });
+
+=head3 PER CONTEXT
+
+This is how you add release callbacks directly to a context. The callback will
+B<ALWAYS> be added to the context that gets returned, it does not matter if a
+new one is generated, or if an existing one is returned.
+
+    my $ctx = context(on_release => sub {
+        my $ctx = shift;
+        ...
+    });
+
+=head1 THIRD PARTY META-DATA
+
+This object consumes L<Test2::Util::ExternalMeta> which provides a consistent
+way for you to attach meta-data to instances of this class. This is useful for
+tools, plugins, and other extentions.
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=item Kent Fredric E<lt>kentnl@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/API/Instance.pm b/cpan/Test-Simple/lib/Test2/API/Instance.pm
new file mode 100644 (file)
index 0000000..f73e399
--- /dev/null
@@ -0,0 +1,729 @@
+package Test2::API::Instance;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+our @CARP_NOT = qw/Test2::API Test2::API::Instance Test2::IPC::Driver Test2::Formatter/;
+use Carp qw/confess carp/;
+use Scalar::Util qw/reftype/;
+
+use Test2::Util qw/get_tid USE_THREADS CAN_FORK pkg_to_file try/;
+
+use Test2::Util::Trace();
+use Test2::API::Stack();
+
+use Test2::Util::HashBase qw{
+    pid tid
+    no_wait
+    finalized loaded
+    ipc stack formatter
+    contexts
+
+    ipc_shm_size
+    ipc_shm_last
+    ipc_shm_id
+    ipc_polling
+    ipc_drivers
+    formatters
+
+    exit_callbacks
+    post_load_callbacks
+    context_acquire_callbacks
+    context_init_callbacks
+    context_release_callbacks
+};
+
+# Wrap around the getters that should call _finalize.
+BEGIN {
+    for my $finalizer (IPC, FORMATTER) {
+        my $orig = __PACKAGE__->can($finalizer);
+        my $new  = sub {
+            my $self = shift;
+            $self->_finalize unless $self->{+FINALIZED};
+            $self->$orig;
+        };
+
+        no strict 'refs';
+        no warnings 'redefine';
+        *{$finalizer} = $new;
+    }
+}
+
+sub import {
+    my $class = shift;
+    return unless @_;
+    my ($ref) = @_;
+    $$ref = $class->new;
+}
+
+sub init { $_[0]->reset }
+
+sub reset {
+    my $self = shift;
+
+    $self->{+PID} = $$;
+    $self->{+TID} = get_tid();
+    $self->{+CONTEXTS}    = {};
+
+    $self->{+IPC_DRIVERS} = [];
+    $self->{+IPC_POLLING} = undef;
+
+    $self->{+FORMATTERS} = [];
+    $self->{+FORMATTER}  = undef;
+
+    $self->{+FINALIZED} = undef;
+    $self->{+IPC}       = undef;
+
+    $self->{+NO_WAIT} = 0;
+    $self->{+LOADED}  = 0;
+
+    $self->{+EXIT_CALLBACKS}            = [];
+    $self->{+POST_LOAD_CALLBACKS}       = [];
+    $self->{+CONTEXT_ACQUIRE_CALLBACKS} = [];
+    $self->{+CONTEXT_INIT_CALLBACKS}    = [];
+    $self->{+CONTEXT_RELEASE_CALLBACKS} = [];
+
+    $self->{+STACK} = Test2::API::Stack->new;
+}
+
+sub _finalize {
+    my $self = shift;
+    my ($caller) = @_;
+    $caller ||= [caller(1)];
+
+    $self->{+FINALIZED} = $caller;
+
+    unless ($self->{+FORMATTER}) {
+        my ($formatter, $source);
+        if ($ENV{T2_FORMATTER}) {
+            $source = "set by the 'T2_FORMATTER' environment variable";
+
+            if ($ENV{T2_FORMATTER} =~ m/^(\+)?(.*)$/) {
+                $formatter = $1 ? $2 : "Test2::Formatter::$2"
+            }
+            else {
+                $formatter = '';
+            }
+        }
+        elsif (@{$self->{+FORMATTERS}}) {
+            ($formatter) = @{$self->{+FORMATTERS}};
+            $source = "Most recently added";
+        }
+        else {
+            $formatter = 'Test2::Formatter::TAP';
+            $source    = 'default formatter';
+        }
+
+        unless (ref($formatter) || $formatter->can('write')) {
+            my $file = pkg_to_file($formatter);
+            my ($ok, $err) = try { require $file };
+            unless ($ok) {
+                my $line   = "* COULD NOT LOAD FORMATTER '$formatter' ($source) *";
+                my $border = '*' x length($line);
+                die "\n\n  $border\n  $line\n  $border\n\n$err";
+            }
+        }
+
+        $self->{+FORMATTER} = $formatter;
+    }
+
+    # Turn on IPC if threads are on, drivers are reigstered, or the Test2::IPC
+    # module is loaded.
+    return unless USE_THREADS || $INC{'Test2/IPC.pm'} || @{$self->{+IPC_DRIVERS}};
+
+    # Turn on polling by default, people expect it.
+    $self->enable_ipc_polling;
+
+    unless (@{$self->{+IPC_DRIVERS}}) {
+        my ($ok, $error) = try { require Test2::IPC::Driver::Files };
+        die $error unless $ok;
+        push @{$self->{+IPC_DRIVERS}} => 'Test2::IPC::Driver::Files';
+    }
+
+    for my $driver (@{$self->{+IPC_DRIVERS}}) {
+        next unless $driver->can('is_viable') && $driver->is_viable;
+        $self->{+IPC} = $driver->new or next;
+        $self->ipc_enable_shm if $self->{+IPC}->use_shm;
+        return;
+    }
+
+    die "IPC has been requested, but no viable drivers were found. Aborting...\n";
+}
+
+sub formatter_set { $_[0]->{+FORMATTER} ? 1 : 0 }
+
+sub add_formatter {
+    my $self = shift;
+    my ($formatter) = @_;
+    unshift @{$self->{+FORMATTERS}} => $formatter;
+
+    return unless $self->{+FINALIZED};
+
+    # Why is the @CARP_NOT entry not enough?
+    local %Carp::Internal = %Carp::Internal;
+    $Carp::Internal{'Test2::Formatter'} = 1;
+
+    carp "Formatter $formatter loaded too late to be used as the global formatter";
+}
+
+sub add_context_acquire_callback {
+    my $self =  shift;
+    my ($code) = @_;
+
+    my $rtype = reftype($code) || "";
+
+    confess "Context-acquire callbacks must be coderefs"
+        unless $code && $rtype eq 'CODE';
+
+    push @{$self->{+CONTEXT_ACQUIRE_CALLBACKS}} => $code;
+}
+
+sub add_context_init_callback {
+    my $self =  shift;
+    my ($code) = @_;
+
+    my $rtype = reftype($code) || "";
+
+    confess "Context-init callbacks must be coderefs"
+        unless $code && $rtype eq 'CODE';
+
+    push @{$self->{+CONTEXT_INIT_CALLBACKS}} => $code;
+}
+
+sub add_context_release_callback {
+    my $self =  shift;
+    my ($code) = @_;
+
+    my $rtype = reftype($code) || "";
+
+    confess "Context-release callbacks must be coderefs"
+        unless $code && $rtype eq 'CODE';
+
+    push @{$self->{+CONTEXT_RELEASE_CALLBACKS}} => $code;
+}
+
+sub add_post_load_callback {
+    my $self = shift;
+    my ($code) = @_;
+
+    my $rtype = reftype($code) || "";
+
+    confess "Post-load callbacks must be coderefs"
+        unless $code && $rtype eq 'CODE';
+
+    push @{$self->{+POST_LOAD_CALLBACKS}} => $code;
+    $code->() if $self->{+LOADED};
+}
+
+sub load {
+    my $self = shift;
+    unless ($self->{+LOADED}) {
+        # This is for https://github.com/Test-More/test-more/issues/16
+        # and https://rt.perl.org/Public/Bug/Display.html?id=127774
+        # END blocks run in reverse order. This insures the END block is loaded
+        # as late as possible. It will not solve all cases, but it helps.
+        eval "END { Test2::API::test2_set_is_end() }; 1" or die $@;
+
+        $self->{+LOADED} = 1;
+        $_->() for @{$self->{+POST_LOAD_CALLBACKS}};
+    }
+    return $self->{+LOADED};
+}
+
+sub add_exit_callback {
+    my $self = shift;
+    my ($code) = @_;
+    my $rtype = reftype($code) || "";
+
+    confess "End callbacks must be coderefs"
+        unless $code && $rtype eq 'CODE';
+
+    push @{$self->{+EXIT_CALLBACKS}} => $code;
+}
+
+sub add_ipc_driver {
+    my $self = shift;
+    my ($driver) = @_;
+    unshift @{$self->{+IPC_DRIVERS}} => $driver;
+
+    return unless $self->{+FINALIZED};
+
+    # Why is the @CARP_NOT entry not enough?
+    local %Carp::Internal = %Carp::Internal;
+    $Carp::Internal{'Test2::IPC::Driver'} = 1;
+
+    carp "IPC driver $driver loaded too late to be used as the global ipc driver";
+}
+
+sub enable_ipc_polling {
+    my $self = shift;
+
+    $self->add_context_init_callback(
+        # This is called every time a context is created, it needs to be fast.
+        # $_[0] is a context object
+        sub {
+            return unless $self->{+IPC_POLLING};
+            return $_[0]->{hub}->cull unless $self->{+IPC_SHM_ID};
+
+            my $val;
+            {
+                shmread($self->{+IPC_SHM_ID}, $val, 0, $self->{+IPC_SHM_SIZE}) or return;
+
+                return if $val eq $self->{+IPC_SHM_LAST};
+                $self->{+IPC_SHM_LAST} = $val;
+            }
+
+            $_[0]->{hub}->cull;
+        }
+    ) unless defined $self->ipc_polling;
+
+    $self->set_ipc_polling(1);
+}
+
+sub ipc_enable_shm {
+    my $self = shift;
+
+    return 1 if defined $self->{+IPC_SHM_ID};
+
+    my ($ok, $err) = try {
+        require IPC::SysV;
+
+        my $ipc_key = IPC::SysV::IPC_PRIVATE();
+        my $shm_size = $self->{+IPC}->can('shm_size') ? $self->{+IPC}->shm_size : 64;
+        my $shm_id = shmget($ipc_key, $shm_size, 0666) or die;
+
+        my $initial = 'a' x $shm_size;
+        shmwrite($shm_id, $initial, 0, $shm_size) or die;
+
+        $self->{+IPC_SHM_SIZE} = $shm_size;
+        $self->{+IPC_SHM_ID}   = $shm_id;
+        $self->{+IPC_SHM_LAST} = $initial;
+    };
+
+    return $ok;
+}
+
+sub ipc_free_shm {
+    my $self = shift;
+
+    my $id = delete $self->{+IPC_SHM_ID};
+    return unless defined $id;
+
+    shmctl($id, IPC::SysV::IPC_RMID(), 0);
+}
+
+sub get_ipc_pending {
+    my $self = shift;
+    return -1 unless defined $self->{+IPC_SHM_ID};
+    my $val;
+    shmread($self->{+IPC_SHM_ID}, $val, 0, $self->{+IPC_SHM_SIZE}) or return -1;
+    return 0 if $val eq $self->{+IPC_SHM_LAST};
+    $self->{+IPC_SHM_LAST} = $val;
+    return 1;
+}
+
+sub set_ipc_pending {
+    my $self = shift;
+
+    return undef unless defined $self->{+IPC_SHM_ID};
+
+    my ($val) = @_;
+
+    confess "value is required for set_ipc_pending"
+        unless $val;
+
+    shmwrite($self->{+IPC_SHM_ID}, $val, 0, $self->{+IPC_SHM_SIZE});
+}
+
+sub disable_ipc_polling {
+    my $self = shift;
+    return unless defined $self->{+IPC_POLLING};
+    $self->{+IPC_POLLING} = 0;
+}
+
+sub _ipc_wait {
+    my $fail = 0;
+
+    while (CAN_FORK) {
+        my $pid = CORE::wait();
+        my $err = $?;
+        last if $pid == -1;
+        next unless $err;
+        $fail++;
+        $err = $err >> 8;
+        warn "Process $pid did not exit cleanly (status: $err)\n";
+    }
+
+    if (USE_THREADS) {
+        for my $t (threads->list()) {
+            $t->join;
+            # In older threads we cannot check if a thread had an error unless
+            # we control it and its return.
+            my $err = $t->can('error') ? $t->error : undef;
+            next unless $err;
+            my $tid = $t->tid();
+            $fail++;
+            chomp($err);
+            warn "Thread $tid did not end cleanly: $err\n";
+        }
+    }
+
+    return 0 unless $fail;
+    return 255;
+}
+
+sub DESTROY {
+    my $self = shift;
+
+    return unless $self->{+PID} == $$;
+    return unless $self->{+TID} == get_tid();
+
+    shmctl($self->{+IPC_SHM_ID}, IPC::SysV::IPC_RMID(), 0)
+        if defined $self->{+IPC_SHM_ID};
+}
+
+sub set_exit {
+    my $self = shift;
+
+    my $exit     = $?;
+    my $new_exit = $exit;
+
+    if ($INC{'Test/Builder.pm'} && $Test::Builder::VERSION ne $Test2::API::VERSION) {
+        print STDERR <<"        EOT";
+
+********************************************************************************
+*                                                                              *
+*            Test::Builder -- Test2::API version mismatch detected             *
+*                                                                              *
+********************************************************************************
+   Test2::API Version: $Test2::API::VERSION
+Test::Builder Version: $Test::Builder::VERSION
+
+This is not a supported configuration, you will have problems.
+
+        EOT
+    }
+
+    for my $ctx (values %{$self->{+CONTEXTS}}) {
+        next unless $ctx;
+
+        next if $ctx->_aborted && ${$ctx->_aborted};
+
+        # Only worry about contexts in this PID
+        my $trace = $ctx->trace || next;
+        next unless $trace->pid == $$;
+
+        # Do not worry about contexts that have no hub
+        my $hub = $ctx->hub  || next;
+
+        # Do not worry if the state came to a sudden end.
+        next if $hub->bailed_out;
+        next if defined $hub->skip_reason;
+
+        # now we worry
+        $trace->alert("context object was never released! This means a testing tool is behaving very badly");
+
+        $exit     = 255;
+        $new_exit = 255;
+    }
+
+    if ($self->{+PID} != $$ or $self->{+TID} != get_tid()) {
+        $? = $exit;
+        return;
+    }
+
+    my @hubs = $self->{+STACK} ? $self->{+STACK}->all : ();
+
+    if (@hubs and $self->{+IPC} and !$self->{+NO_WAIT}) {
+        local $?;
+        my %seen;
+        for my $hub (reverse @hubs) {
+            my $ipc = $hub->ipc or next;
+            next if $seen{$ipc}++;
+            $ipc->waiting();
+        }
+
+        my $ipc_exit = _ipc_wait();
+        $new_exit ||= $ipc_exit;
+    }
+
+    # None of this is necessary if we never got a root hub
+    if(my $root = shift @hubs) {
+        my $trace = Test2::Util::Trace->new(
+            frame  => [__PACKAGE__, __FILE__, 0, __PACKAGE__ . '::END'],
+            detail => __PACKAGE__ . ' END Block finalization',
+        );
+        my $ctx = Test2::API::Context->new(
+            trace => $trace,
+            hub   => $root,
+        );
+
+        if (@hubs) {
+            $ctx->diag("Test ended with extra hubs on the stack!");
+            $new_exit  = 255;
+        }
+
+        unless ($root->no_ending) {
+            local $?;
+            $root->finalize($trace) unless $root->ended;
+            $_->($ctx, $exit, \$new_exit) for @{$self->{+EXIT_CALLBACKS}};
+            $new_exit ||= $root->failed;
+        }
+    }
+
+    $new_exit = 255 if $new_exit > 255;
+
+    if ($new_exit) {
+        require Test2::API::Breakage;
+        my @warn = Test2::API::Breakage->report();
+
+        if (@warn) {
+            print STDERR "\nYou have loaded versions of test modules known to have problems with Test2.\nThis could explain some test failures.\n";
+            print STDERR "$_\n" for @warn;
+            print STDERR "\n";
+        }
+    }
+
+    $? = $new_exit;
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::API::Instance - Object used by Test2::API under the hood
+
+=head1 DESCRIPTION
+
+This object encapsulates the global shared state tracked by
+L<Test2>. A single global instance of this package is stored (and
+obscured) by the L<Test2::API> package.
+
+There is no reason to directly use this package. This package is documented for
+completeness. This package can change, or go away completely at any time.
+Directly using, or monkeypatching this package is not supported in any way
+shape or form.
+
+=head1 SYNOPSIS
+
+    use Test2::API::Instance;
+
+    my $obj = Test2::API::Instance->new;
+
+=over 4
+
+=item $pid = $obj->pid
+
+PID of this instance.
+
+=item $obj->tid
+
+Thread ID of this instance.
+
+=item $obj->reset()
+
+Reset the object to defaults.
+
+=item $obj->load()
+
+Set the internal state to loaded, and run and stored post-load callbacks.
+
+=item $bool = $obj->loaded
+
+Check if the state is set to loaded.
+
+=item $arrayref = $obj->post_load_callbacks
+
+Get the post-load callbacks.
+
+=item $obj->add_post_load_callback(sub { ... })
+
+Add a post-load callback. If C<load()> has already been called then the callback will
+be immedietly executed. If C<load()> has not been called then the callback will be
+stored and executed later when C<load()> is called.
+
+=item $hashref = $obj->contexts()
+
+Get a hashref of all active contexts keyed by hub id.
+
+=item $arrayref = $obj->context_acquire_callbacks
+
+Get all context acquire callbacks.
+
+=item $arrayref = $obj->context_init_callbacks
+
+Get all context init callbacks.
+
+=item $arrayref = $obj->context_release_callbacks
+
+Get all context release callbacks.
+
+=item $obj->add_context_init_callback(sub { ... })
+
+Add a context init callback. Subs are called every time a context is created. Subs
+get the newly created context as their only argument.
+
+=item $obj->add_context_release_callback(sub { ... })
+
+Add a context release callback. Subs are called every time a context is released. Subs
+get the released context as their only argument. These callbacks should not
+call release on the context.
+
+=item $obj->set_exit()
+
+This is intended to be called in an C<END { ... }> block. This will look at
+test state and set $?. This will also call any end callbacks, and wait on child
+processes/threads.
+
+=item $obj->ipc_enable_shm()
+
+Turn on SHM for IPC (if possible)
+
+=item $shm_id = $obj->ipc_shm_id()
+
+If SHM is enabled for IPC this will be the shm_id for it.
+
+=item $shm_size = $obj->ipc_shm_size()
+
+If SHM is enabled for IPC this will be the size of it.
+
+=item $shm_last_val = $obj->ipc_shm_last()
+
+If SHM is enabled for IPC this will return the last SHM value seen.
+
+=item $obj->set_ipc_pending($val)
+
+use the IPC SHM to tell other processes and threads there is a pending event.
+C<$val> should be a unique value no other thread/process will generate.
+
+B<Note:> This will also make the current process see a pending event. It does
+not set C<ipc_shm_last()>, this is important because doing so could hide a
+previous change.
+
+=item $pending = $obj->get_ipc_pending()
+
+This returns -1 if SHM is not enabled for IPC.
+
+This returns 0 if the SHM value matches the last known value, which means there
+are no pending events.
+
+This returns 1 if the SHM value has changed, which means there are probably
+pending events.
+
+When 1 is returned this will set C<< $obj->ipc_shm_last() >>.
+
+=item $drivers = $obj->ipc_drivers
+
+Get the list of IPC drivers.
+
+=item $obj->add_ipc_driver($DRIVER_CLASS)
+
+Add an IPC driver to the list. The most recently added IPC driver will become
+the global one during initialization. If a driver is added after initialization
+has occurred a warning will be generated:
+
+    "IPC driver $driver loaded too late to be used as the global ipc driver"
+
+=item $bool = $obj->ipc_polling
+
+Check if polling is enabled.
+
+=item $obj->enable_ipc_polling
+
+Turn on polling. This will cull events from other processes and threads every
+time a context is created.
+
+=item $obj->disable_ipc_polling
+
+Turn off IPC polling.
+
+=item $bool = $obj->no_wait
+
+=item $bool = $obj->set_no_wait($bool)
+
+Get/Set no_wait. This option is used to turn off process/thread waiting at exit.
+
+=item $arrayref = $obj->exit_callbacks
+
+Get the exit callbacks.
+
+=item $obj->add_exit_callback(sub { ... })
+
+Add an exit callback. This callback will be called by C<set_exit()>.
+
+=item $bool = $obj->finalized
+
+Check if the object is finalized. Finalization happens when either C<ipc()>,
+C<stack()>, or C<format()> are called on the object. Once finalization happens
+these fields are considered unchangeable (not enforced here, enforced by
+L<Test2>).
+
+=item $ipc = $obj->ipc
+
+Get the one true IPC instance.
+
+=item $stack = $obj->stack
+
+Get the one true hub stack.
+
+=item $formatter = $obj->formatter
+
+Get the global formatter. By default this is the C<'Test2::Formatter::TAP'>
+package. This could be any package that implements the C<write()> method. This
+can also be an instantiated object.
+
+=item $bool = $obj->formatter_set()
+
+Check if a formatter has been set.
+
+=item $obj->add_formatter($class)
+
+=item $obj->add_formatter($obj)
+
+Add a formatter. The most recently added formatter will become the global one
+during initialization. If a formatter is added after initialization has occurred
+a warning will be generated:
+
+    "Formatter $formatter loaded too late to be used as the global formatter"
+
+=back
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/API/Stack.pm b/cpan/Test-Simple/lib/Test2/API/Stack.pm
new file mode 100644 (file)
index 0000000..0bc25ec
--- /dev/null
@@ -0,0 +1,220 @@
+package Test2::API::Stack;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use Test2::Hub();
+
+use Carp qw/confess/;
+
+sub new {
+    my $class = shift;
+    return bless [], $class;
+}
+
+sub new_hub {
+    my $self = shift;
+    my %params = @_;
+
+    my $class = delete $params{class} || 'Test2::Hub';
+
+    my $hub = $class->new(%params);
+
+    if (@$self) {
+        $hub->inherit($self->[-1], %params);
+    }
+    else {
+        require Test2::API;
+        $hub->format(Test2::API::test2_formatter()->new)
+            unless $hub->format || exists($params{formatter});
+
+        my $ipc = Test2::API::test2_ipc();
+        if ($ipc && !$hub->ipc && !exists($params{ipc})) {
+            $hub->set_ipc($ipc);
+            $ipc->add_hub($hub->hid);
+        }
+    }
+
+    push @$self => $hub;
+
+    $hub;
+}
+
+sub top {
+    my $self = shift;
+    return $self->new_hub unless @$self;
+    return $self->[-1];
+}
+
+sub peek {
+    my $self = shift;
+    return @$self ? $self->[-1] : undef;
+}
+
+sub cull {
+    my $self = shift;
+    $_->cull for reverse @$self;
+}
+
+sub all {
+    my $self = shift;
+    return @$self;
+}
+
+sub clear {
+    my $self = shift;
+    @$self = ();
+}
+
+# Do these last without keywords in order to prevent them from getting used
+# when we want the real push/pop.
+
+{
+    no warnings 'once';
+
+    *push = sub {
+        my $self = shift;
+        my ($hub) = @_;
+        $hub->inherit($self->[-1]) if @$self;
+        push @$self => $hub;
+    };
+
+    *pop = sub {
+        my $self = shift;
+        my ($hub) = @_;
+        confess "No hubs on the stack"
+            unless @$self;
+        confess "You cannot pop the root hub"
+            if 1 == @$self;
+        confess "Hub stack mismatch, attempted to pop incorrect hub"
+            unless $self->[-1] == $hub;
+        pop @$self;
+    };
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::API::Stack - Object to manage a stack of L<Test2::Hub>
+instances.
+
+=head1 ***INTERNALS NOTE***
+
+B<The internals of this package are subject to change at any time!> The public
+methods provided will not change in backwords incompatible ways, but the
+underlying implementation details might. B<Do not break encapsulation here!>
+
+=head1 DESCRIPTION
+
+This module is used to represent and manage a stack of L<Test2::Hub>
+objects. Hubs are usually in a stack so that you can push a new hub into place
+that can intercept and handle events differently than the primary hub.
+
+=head1 SYNOPSIS
+
+    my $stack = Test2::API::Stack->new;
+    my $hub = $stack->top;
+
+=head1 METHODS
+
+=over 4
+
+=item $stack = Test2::API::Stack->new()
+
+This will create a new empty stack instance. All arguments are ignored.
+
+=item $hub = $stack->new_hub()
+
+=item $hub = $stack->new_hub(%params)
+
+=item $hub = $stack->new_hub(%params, class => $class)
+
+This will generate a new hub and push it to the top of the stack. Optionally
+you can provide arguments that will be passed into the constructor for the
+L<Test2::Hub> object.
+
+If you specify the C<< 'class' => $class >> argument, the new hub will be an
+instance of the specified class.
+
+Unless your parameters specify C<'formatter'> or C<'ipc'> arguments, the
+formatter and ipc instance will be inherited from the current top hub. You can
+set the parameters to C<undef> to avoid having a formatter or ipc instance.
+
+If there is no top hub, and you do not ask to leave ipc and formatter undef,
+then a new formatter will be created, and the IPC instance from
+L<Test2::API> will be used.
+
+=item $hub = $stack->top()
+
+This will return the top hub from the stack. If there is no top hub yet this
+will create it.
+
+=item $hub = $stack->peek()
+
+This will return the top hub from the stack. If there is no top hub yet this
+will return undef.
+
+=item $stack->cull
+
+This will call C<< $hub->cull >> on all hubs in the stack.
+
+=item @hubs = $stack->all
+
+This will return all the hubs in the stack as a list.
+
+=item $stack->clear
+
+This will completely remove all hubs from the stack. Normally you do not want
+to do this, but there are a few valid reasons for it.
+
+=item $stack->push($hub)
+
+This will push the new hub onto the stack.
+
+=item $stack->pop($hub)
+
+This will pop a hub from the stack, if the hub at the top of the stack does not
+match the hub you expect (passed in as an argument) it will throw an exception.
+
+=back
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/Event.pm b/cpan/Test-Simple/lib/Test2/Event.pm
new file mode 100644 (file)
index 0000000..67e6f77
--- /dev/null
@@ -0,0 +1,215 @@
+package Test2::Event;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use Test2::Util::HashBase qw/trace nested in_subtest subtest_id/;
+use Test2::Util::ExternalMeta qw/meta get_meta set_meta delete_meta/;
+
+sub causes_fail      { 0 }
+sub increments_count { 0 }
+sub diagnostics      { 0 }
+sub no_display       { 0 }
+
+sub callback { }
+
+sub terminate { () }
+sub global    { () }
+sub sets_plan { () }
+
+sub summary { ref($_[0]) }
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Event - Base class for events
+
+=head1 DESCRIPTION
+
+Base class for all event objects that get passed through
+L<Test2>.
+
+=head1 SYNOPSIS
+
+    package Test2::Event::MyEvent;
+    use strict;
+    use warnings;
+
+    # This will make our class an event subclass (required)
+    use base 'Test2::Event';
+
+    # Add some accessors (optional)
+    # You are not obligated to use HashBase, you can use any object tool you
+    # want, or roll your own accessors.
+    use Test2::Util::HashBase qw/foo bar baz/;
+
+    # Chance to initialize some defaults
+    sub init {
+        my $self = shift;
+        # no other args in @_
+
+        $self->set_foo('xxx') unless defined $self->foo;
+
+        ...
+    }
+
+    1;
+
+=head1 METHODS
+
+=over 4
+
+=item $trace = $e->trace
+
+Get a snapshot of the L<Test2::Util::Trace> as it was when this event was
+generated
+
+=item $bool = $e->causes_fail
+
+Returns true if this event should result in a test failure. In general this
+should be false.
+
+=item $bool = $e->increments_count
+
+Should be true if this event should result in a test count increment.
+
+=item $e->callback($hub)
+
+If your event needs to have extra effects on the L<Test2::Hub> you can override
+this method.
+
+This is called B<BEFORE> your event is passed to the formatter.
+
+=item $call = $e->created
+
+Get the C<caller()> details from when the event was generated. This is usually
+inside a tools package. This is typically used for debugging.
+
+=item $num = $e->nested
+
+If this event is nested inside of other events, this should be the depth of
+nesting. (This is mainly for subtests)
+
+=item $bool = $e->global
+
+Set this to true if your event is global, that is ALL threads and processes
+should see it no matter when or where it is generated. This is not a common
+thing to want, it is used by bail-out and skip_all to end testing.
+
+=item $code = $e->terminate
+
+This is called B<AFTER> your event has been passed to the formatter. This
+should normally return undef, only change this if your event should cause the
+test to exit immedietly.
+
+If you want this event to cause the test to exit you should return the exit
+code here. Exit code of 0 means exit success, any other integer means exit with
+failure.
+
+This is used by L<Test2::Event::Plan> to exit 0 when the plan is
+'skip_all'. This is also used by L<Test2::Event:Bail> to force the test
+to exit with a failure.
+
+This is called after the event has been sent to the formatter in order to
+ensure the event is seen and understood.
+
+=item $todo = $e->todo
+
+=item $e->set_todo($todo)
+
+Get/Set the todo reason on the event. Any value other than C<undef> makes the
+event 'TODO'.
+
+Not all events make use of this field, but they can all have it set/cleared.
+
+=item $bool = $e->diag_todo
+
+=item $e->diag_todo($todo)
+
+True if this event should be considered 'TODO' for diagnostics purposes. This
+essentially means that any message that would go to STDERR will go to STDOUT
+instead so that a harness will hide it outside of verbose mode.
+
+=item $msg = $e->summary
+
+This is intended to be a human readable summary of the event. This should
+ideally only be 1-line long, but you can use multiple lines if necessary. This
+is intended for human consumption, you do not need to make it easy for machines
+to understand.
+
+The default is to simply return the event package name.
+
+=item ($count, $directive, $reason) = $e->sets_plan()
+
+Check if this event sets the testing plan. It will return an empty list if it
+does not. If it does set the plan it will return a list of 1 to 3 items in
+order: Expected Test Count, Test Directive, Reason for directive.
+
+=item $bool = $e->diagnostics
+
+True if the event contains diagnostics info. This is useful because a
+non-verbose harness may choose to hide events that are not in this category.
+Some formatters may choose to send these to STDERR instead of STDOUT to ensure
+they are seen.
+
+=item $bool = $e->no_display
+
+False by default. This will return true on events that should not be displayed
+by formatters.
+
+=item $id = $e->in_subtest
+
+If the event is inside a subtest this should have the subtest ID.
+
+=item $id = $e->subtest_id
+
+If the event is a final subtes event, this should contain the subtest ID.
+
+=back
+
+=head1 THIRD PARTY META-DATA
+
+This object consumes L<Test2::Util::ExternalMeta> which provides a consistent
+way for you to attach meta-data to instances of this class. This is useful for
+tools, plugins, and other extentions.
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/Event/Bail.pm b/cpan/Test-Simple/lib/Test2/Event/Bail.pm
new file mode 100644 (file)
index 0000000..875ba0a
--- /dev/null
@@ -0,0 +1,102 @@
+package Test2::Event::Bail;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use base 'Test2::Event';
+use Test2::Util::HashBase qw{reason};
+
+sub callback {
+    my $self = shift;
+    my ($hub) = @_;
+
+    $hub->set_bailed_out($self);
+}
+
+# Make sure the tests terminate
+sub terminate { 255 };
+
+sub global { 1 };
+
+sub causes_fail { 1 }
+
+sub summary {
+    my $self = shift;
+    return "Bail out!  " . $self->{+REASON}
+        if $self->{+REASON};
+
+    return "Bail out!";
+}
+
+sub diagnostics { 1 }
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Event::Bail - Bailout!
+
+=head1 DESCRIPTION
+
+The bailout event is generated when things go horribly wrong and you need to
+halt all testing in the current file.
+
+=head1 SYNOPSIS
+
+    use Test2::API qw/context/;
+    use Test2::Event::Bail;
+
+    my $ctx = context();
+    my $event = $ctx->bail('Stuff is broken');
+
+=head1 METHODS
+
+Inherits from L<Test2::Event>. Also defines:
+
+=over 4
+
+=item $reason = $e->reason
+
+The reason for the bailout.
+
+=back
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/Event/Diag.pm b/cpan/Test-Simple/lib/Test2/Event/Diag.pm
new file mode 100644 (file)
index 0000000..af5790c
--- /dev/null
@@ -0,0 +1,83 @@
+package Test2::Event::Diag;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use base 'Test2::Event';
+use Test2::Util::HashBase qw/message/;
+
+sub init {
+    $_[0]->{+MESSAGE} = 'undef' unless defined $_[0]->{+MESSAGE};
+}
+
+sub summary { $_[0]->{+MESSAGE} }
+
+sub diagnostics { 1 }
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Event::Diag - Diag event type
+
+=head1 DESCRIPTION
+
+Diagnostics messages, typically rendered to STDERR.
+
+=head1 SYNOPSIS
+
+    use Test2::API qw/context/;
+    use Test2::Event::Diag;
+
+    my $ctx = context();
+    my $event = $ctx->diag($message);
+
+=head1 ACCESSORS
+
+=over 4
+
+=item $diag->message
+
+The message for the diag.
+
+=back
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/Event/Exception.pm b/cpan/Test-Simple/lib/Test2/Event/Exception.pm
new file mode 100644 (file)
index 0000000..3504a24
--- /dev/null
@@ -0,0 +1,88 @@
+package Test2::Event::Exception;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use base 'Test2::Event';
+use Test2::Util::HashBase qw{error};
+
+sub causes_fail { 1 }
+
+sub summary {
+    my $self = shift;
+    chomp(my $msg = "Exception: " . $self->{+ERROR});
+    return $msg;
+}
+
+sub diagnostics { 1 }
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Event::Exception - Exception event
+
+=head1 DESCRIPTION
+
+An exception event will display to STDERR, and will prevent the overall test
+file from passing.
+
+=head1 SYNOPSIS
+
+    use Test2::API qw/context/;
+    use Test2::Event::Exception;
+
+    my $ctx = context();
+    my $event = $ctx->send_event('Exception', error => 'Stuff is broken');
+
+=head1 METHODS
+
+Inherits from L<Test2::Event>. Also defines:
+
+=over 4
+
+=item $reason = $e->error
+
+The reason for the exception.
+
+=back
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/Event/Note.pm b/cpan/Test-Simple/lib/Test2/Event/Note.pm
new file mode 100644 (file)
index 0000000..aea9951
--- /dev/null
@@ -0,0 +1,81 @@
+package Test2::Event::Note;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use base 'Test2::Event';
+use Test2::Util::HashBase qw/message/;
+
+sub init {
+    $_[0]->{+MESSAGE} = 'undef' unless defined $_[0]->{+MESSAGE};
+}
+
+sub summary { $_[0]->{+MESSAGE} }
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Event::Note - Note event type
+
+=head1 DESCRIPTION
+
+Notes, typically rendered to STDOUT.
+
+=head1 SYNOPSIS
+
+    use Test2::API qw/context/;
+    use Test2::Event::Note;
+
+    my $ctx = context();
+    my $event = $ctx->Note($message);
+
+=head1 ACCESSORS
+
+=over 4
+
+=item $note->message
+
+The message for the note.
+
+=back
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/Event/Ok.pm b/cpan/Test-Simple/lib/Test2/Event/Ok.pm
new file mode 100644 (file)
index 0000000..b467f70
--- /dev/null
@@ -0,0 +1,149 @@
+package Test2::Event::Ok;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use base 'Test2::Event';
+use Test2::Util::HashBase qw{
+    pass effective_pass name todo
+};
+
+sub init {
+    my $self = shift;
+
+    # Do not store objects here, only true or false
+    $self->{+PASS} = $self->{+PASS} ? 1 : 0;
+    $self->{+EFFECTIVE_PASS} = $self->{+PASS} || (defined($self->{+TODO}) ? 1 : 0);
+
+    my $name = $self->{+NAME} or return;
+    return unless index($name, '#') != -1 || index($name, "\n") != -1;
+    $self->trace->throw("'$name' is not a valid name, names must not contain '#' or newlines.")
+}
+
+{
+    no warnings 'redefine';
+    sub set_todo {
+        my $self = shift;
+        my ($todo) = @_;
+        $self->{+TODO} = $todo;
+        $self->{+EFFECTIVE_PASS} = defined($todo) ? 1 : $self->{+PASS};
+    }
+}
+
+sub increments_count { 1 };
+
+sub causes_fail { !$_[0]->{+EFFECTIVE_PASS} }
+
+sub summary {
+    my $self = shift;
+
+    my $name = $self->{+NAME} || "Nameless Assertion";
+
+    my $todo = $self->{+TODO};
+    if ($todo) {
+        $name .= " (TODO: $todo)";
+    }
+    elsif (defined $todo) {
+        $name .= " (TODO)"
+    }
+
+    return $name;
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Event::Ok - Ok event type
+
+=head1 DESCRIPTION
+
+Ok events are generated whenever you run a test that produces a result.
+Examples are C<ok()>, and C<is()>.
+
+=head1 SYNOPSIS
+
+    use Test2::API qw/context/;
+    use Test2::Event::Ok;
+
+    my $ctx = context();
+    my $event = $ctx->ok($bool, $name, \@diag);
+
+or:
+
+    my $ctx   = context();
+    my $event = $ctx->send_event(
+        'Ok',
+        pass => $bool,
+        name => $name,
+        diag => \@diag
+    );
+
+=head1 ACCESSORS
+
+=over 4
+
+=item $rb = $e->pass
+
+The original true/false value of whatever was passed into the event (but
+reduced down to 1 or 0).
+
+=item $name = $e->name
+
+Name of the test.
+
+=item $diag = $e->diag
+
+An arrayref full of diagnostics strings to print in the event of a failure.
+
+=item $b = $e->effective_pass
+
+This is the true/false value of the test after TODO and similar modifiers are
+taken into account.
+
+=item $b = $e->allow_bad_name
+
+This relaxes the test name checks such that they allow characters that can
+confuse a TAP parser.
+
+=back
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/Event/Plan.pm b/cpan/Test-Simple/lib/Test2/Event/Plan.pm
new file mode 100644 (file)
index 0000000..12f5d6b
--- /dev/null
@@ -0,0 +1,160 @@
+package Test2::Event::Plan;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use base 'Test2::Event';
+use Test2::Util::HashBase qw{max directive reason};
+
+use Carp qw/confess/;
+
+my %ALLOWED = (
+    'SKIP'    => 1,
+    'NO PLAN' => 1,
+);
+
+sub init {
+    if ($_[0]->{+DIRECTIVE}) {
+        $_[0]->{+DIRECTIVE} = 'SKIP'    if $_[0]->{+DIRECTIVE} eq 'skip_all';
+        $_[0]->{+DIRECTIVE} = 'NO PLAN' if $_[0]->{+DIRECTIVE} eq 'no_plan';
+
+        confess "'" . $_[0]->{+DIRECTIVE} . "' is not a valid plan directive"
+            unless $ALLOWED{$_[0]->{+DIRECTIVE}};
+    }
+    else {
+        confess "Cannot have a reason without a directive!"
+            if defined $_[0]->{+REASON};
+
+        confess "No number of tests specified"
+            unless defined $_[0]->{+MAX};
+
+        confess "Plan test count '" . $_[0]->{+MAX}  . "' does not appear to be a valid positive integer"
+            unless $_[0]->{+MAX} =~ m/^\d+$/;
+
+        $_[0]->{+DIRECTIVE} = '';
+    }
+}
+
+sub sets_plan {
+    my $self = shift;
+    return (
+        $self->{+MAX},
+        $self->{+DIRECTIVE},
+        $self->{+REASON},
+    );
+}
+
+sub callback {
+    my $self = shift;
+    my ($hub) = @_;
+
+    $hub->plan($self->{+DIRECTIVE} || $self->{+MAX});
+
+    return unless $self->{+DIRECTIVE};
+
+    $hub->set_skip_reason($self->{+REASON} || 1) if $self->{+DIRECTIVE} eq 'SKIP';
+}
+
+sub terminate {
+    my $self = shift;
+    # On skip_all we want to terminate the hub
+    return 0 if $self->{+DIRECTIVE} && $self->{+DIRECTIVE} eq 'SKIP';
+    return undef;
+}
+
+sub summary {
+    my $self = shift;
+    my $max = $self->{+MAX};
+    my $directive = $self->{+DIRECTIVE};
+    my $reason = $self->{+REASON};
+
+    return "Plan is $max assertions"
+        if $max || !$directive;
+
+    return "Plan is '$directive', $reason"
+        if $reason;
+
+    return "Plan is '$directive'";
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Event::Plan - The event of a plan
+
+=head1 DESCRIPTION
+
+Plan events are fired off whenever a plan is declared, done testing is called,
+or a subtext completes.
+
+=head1 SYNOPSIS
+
+    use Test2::API qw/context/;
+    use Test2::Event::Plan;
+
+    my $ctx = context();
+
+    # Plan for 10 tests to run
+    my $event = $ctx->plan(10);
+
+    # Plan to skip all tests (will exit 0)
+    $ctx->plan(0, skip_all => "These tests need to be skipped");
+
+=head1 ACCESSORS
+
+=over 4
+
+=item $num = $plan->max
+
+Get the number of expected tests
+
+=item $dir = $plan->directive
+
+Get the directive (such as TODO, skip_all, or no_plan).
+
+=item $reason = $plan->reason
+
+Get the reason for the directive.
+
+=back
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/Event/Skip.pm b/cpan/Test-Simple/lib/Test2/Event/Skip.pm
new file mode 100644 (file)
index 0000000..9f9ae92
--- /dev/null
@@ -0,0 +1,108 @@
+package Test2::Event::Skip;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use base 'Test2::Event::Ok';
+use Test2::Util::HashBase qw{reason};
+
+sub init {
+    my $self = shift;
+    $self->SUPER::init;
+    $self->{+EFFECTIVE_PASS} = 1;
+}
+
+sub causes_fail { 0 }
+
+sub summary {
+    my $self = shift;
+    my $out = $self->SUPER::summary(@_);
+
+    if (my $reason = $self->reason) {
+        $out .= " (SKIP: $reason)";
+    }
+    else {
+        $out .= " (SKIP)";
+    }
+
+    return $out;
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Event::Skip - Skip event type
+
+=head1 DESCRIPTION
+
+Skip events bump test counts just like L<Test2::Event::Ok> events, but
+they can never fail.
+
+=head1 SYNOPSIS
+
+    use Test2::API qw/context/;
+    use Test2::Event::Skip;
+
+    my $ctx = context();
+    my $event = $ctx->skip($name, $reason);
+
+or:
+
+    my $ctx   = context();
+    my $event = $ctx->send_event(
+        'Skip',
+        name   => $name,
+        reason => $reason,
+    );
+
+=head1 ACCESSORS
+
+=over 4
+
+=item $reason = $e->reason
+
+The original true/false value of whatever was passed into the event (but
+reduced down to 1 or 0).
+
+=back
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://www.perl.com/perl/misc/Artistic.html>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/Event/Subtest.pm b/cpan/Test-Simple/lib/Test2/Event/Subtest.pm
new file mode 100644 (file)
index 0000000..1784f05
--- /dev/null
@@ -0,0 +1,97 @@
+package Test2::Event::Subtest;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use base 'Test2::Event::Ok';
+use Test2::Util::HashBase qw{subevents buffered subtest_id};
+
+sub init {
+    my $self = shift;
+    $self->SUPER::init();
+    $self->{+SUBEVENTS} ||= [];
+}
+
+sub summary {
+    my $self = shift;
+
+    my $name = $self->{+NAME} || "Nameless Subtest";
+
+    my $todo = $self->{+TODO};
+    if ($todo) {
+        $name .= " (TODO: $todo)";
+    }
+    elsif (defined $todo) {
+        $name .= " (TODO)"
+    }
+
+    return $name;
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Event::Subtest - Event for subtest types
+
+=head1 DESCRIPTION
+
+This class represents a subtest. This class is a subclass of
+L<Test2::Event::Ok>.
+
+=head1 ACCESSORS
+
+This class inherits from L<Test2::Event::Ok>.
+
+=over 4
+
+=item $arrayref = $e->subevents
+
+Returns the arrayref containing all the events from the subtest
+
+=item $bool = $e->buffered
+
+True if the subtest is buffered, that is all subevents render at once. If this
+is false it means all subevents render as they are produced.
+
+=back
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/Event/Waiting.pm b/cpan/Test-Simple/lib/Test2/Event/Waiting.pm
new file mode 100644 (file)
index 0000000..c77891d
--- /dev/null
@@ -0,0 +1,61 @@
+package Test2::Event::Waiting;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use base 'Test2::Event';
+
+sub global { 1 };
+
+sub summary { "IPC is waiting for children to finish..." }
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Event::Waiting - Tell all procs/threads it is time to be done
+
+=head1 DESCRIPTION
+
+This event has no data of its own. This event is sent out by the IPC system
+when the main process/thread is ready to end.
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/Formatter.pm b/cpan/Test-Simple/lib/Test2/Formatter.pm
new file mode 100644 (file)
index 0000000..0c8a09f
--- /dev/null
@@ -0,0 +1,94 @@
+package Test2::Formatter;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+my %ADDED;
+sub import {
+    my $class = shift;
+    return if $class eq __PACKAGE__;
+    return if $ADDED{$class}++;
+    require Test2::API;
+    Test2::API::test2_formatter_add($class);
+}
+
+sub hide_buffered { 1 }
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Formatter - Namespace for formatters.
+
+=head1 DESCRIPTION
+
+This is the namespace for formatters. This is an empty package.
+
+=head1 CREATING FORMATTERS
+
+A formatter is any package or object with a C<write($event, $num)> method.
+
+    package Test2::Formatter::Foo;
+    use strict;
+    use warnings;
+
+    sub write {
+        my $self_or_class = shift;
+        my ($event, $assert_num) = @_;
+        ...
+    }
+
+    sub hide_buffered { 1 }
+
+    1;
+
+The C<write> method is a method, so it either gets a class or instance. The 2
+arguments are the C<$event> object it should record, and the C<$assert_num>
+which is the number of the current assertion (ok), or the last assertion if
+this even is not itself an assertion. The assertion number may be any inyeger 0
+or greator, and may be undefined in some cases.
+
+The C<hide_buffered()> method must return a boolean. This is used to tell
+buffered subtests whether or not to send it events as they are being buffered.
+See L<Test2::API/"run_subtest(...)"> for more information.
+
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/Formatter/TAP.pm b/cpan/Test-Simple/lib/Test2/Formatter/TAP.pm
new file mode 100644 (file)
index 0000000..3020b8c
--- /dev/null
@@ -0,0 +1,501 @@
+package Test2::Formatter::TAP;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use Test2::Util::HashBase qw{
+    no_numbers handles _encoding
+};
+
+sub OUT_STD() { 0 }
+sub OUT_ERR() { 1 }
+
+use Carp qw/croak/;
+
+use base 'Test2::Formatter';
+
+my %CONVERTERS = (
+    'Test2::Event::Ok'        => 'event_ok',
+    'Test2::Event::Skip'      => 'event_skip',
+    'Test2::Event::Note'      => 'event_note',
+    'Test2::Event::Diag'      => 'event_diag',
+    'Test2::Event::Bail'      => 'event_bail',
+    'Test2::Event::Exception' => 'event_exception',
+    'Test2::Event::Subtest'   => 'event_subtest',
+    'Test2::Event::Plan'      => 'event_plan',
+);
+
+# Initial list of converters are safe for direct hash access cause we control them.
+my %SAFE_TO_ACCESS_HASH = %CONVERTERS;
+
+sub register_event {
+    my $class = shift;
+    my ($type, $convert) = @_;
+    croak "Event type is a required argument" unless $type;
+    croak "Event type '$type' already registered" if $CONVERTERS{$type};
+    croak "The second argument to register_event() must be a code reference or method name"
+        unless $convert && (ref($convert) eq 'CODE' || $class->can($convert));
+    $CONVERTERS{$type} = $convert;
+}
+
+_autoflush(\*STDOUT);
+_autoflush(\*STDERR);
+
+sub init {
+    my $self = shift;
+
+    $self->{+HANDLES} ||= $self->_open_handles;
+    if(my $enc = delete $self->{encoding}) {
+        $self->encoding($enc);
+    }
+}
+
+sub hide_buffered { 1 }
+
+sub encoding {
+    my $self = shift;
+
+    if (@_) {
+        my ($enc) = @_;
+        my $handles = $self->{+HANDLES};
+
+        # https://rt.perl.org/Public/Bug/Display.html?id=31923
+        # If utf8 is requested we use ':utf8' instead of ':encoding(utf8)' in
+        # order to avoid the thread segfault.
+        if ($enc =~ m/^utf-?8$/i) {
+            binmode($_, ":utf8") for @$handles;
+        }
+        else {
+            binmode($_, ":encoding($enc)") for @$handles;
+        }
+        $self->{+_ENCODING} = $enc;
+    }
+
+    return $self->{+_ENCODING};
+}
+
+if ($^C) {
+    no warnings 'redefine';
+    *write = sub {};
+}
+sub write {
+    my ($self, $e, $num) = @_;
+
+    my $type = ref($e);
+
+    my $converter = $CONVERTERS{$type} || 'event_other';
+    my @tap = $self->$converter($e, $self->{+NO_NUMBERS} ? undef : $num) or return;
+
+    my $handles = $self->{+HANDLES};
+    my $nesting = ($SAFE_TO_ACCESS_HASH{$type} ? $e->{nested} : $e->nested) || 0;
+    my $indent = '    ' x $nesting;
+
+    # Local is expensive! Only do it if we really need to.
+    local($\, $,) = (undef, '') if $\ || $,;
+    for my $set (@tap) {
+        no warnings 'uninitialized';
+        my ($hid, $msg) = @$set;
+        next unless $msg;
+        my $io = $handles->[$hid] or next;
+
+        $msg =~ s/^/$indent/mg if $nesting;
+        print $io $msg;
+    }
+}
+
+sub _open_handles {
+    my $self = shift;
+
+    open( my $out, '>&', STDOUT ) or die "Can't dup STDOUT:  $!";
+    open( my $err, '>&', STDERR ) or die "Can't dup STDERR:  $!";
+
+    _autoflush($out);
+    _autoflush($err);
+
+    return [$out, $err];
+}
+
+sub _autoflush {
+    my($fh) = pop;
+    my $old_fh = select $fh;
+    $| = 1;
+    select $old_fh;
+}
+
+sub event_tap {
+    my $self = shift;
+    my ($e, $num) = @_;
+
+    my $converter = $CONVERTERS{ref($e)} or return;
+
+    $num = undef if $self->{+NO_NUMBERS};
+
+    return $self->$converter($e, $num);
+}
+
+sub event_ok {
+    my $self = shift;
+    my ($e, $num) = @_;
+
+    # We use direct hash access for performance. OK events are so common we
+    # need this to be fast.
+    my ($name, $todo) = @{$e}{qw/name todo/};
+    my $in_todo = defined($todo);
+
+    my $out = "";
+    $out .= "not " unless $e->{pass};
+    $out .= "ok";
+    $out .= " $num" if defined($num);
+    $out .= " - $name" if defined $name;
+    $out .= " # TODO" if $in_todo;
+    $out .= " $todo" if defined($todo) && length($todo);
+
+    # The primary line of TAP, if the test passed this is all we need.
+    return([OUT_STD, "$out\n"]);
+}
+
+sub event_skip {
+    my $self = shift;
+    my ($e, $num) = @_;
+
+    my $name   = $e->name;
+    my $reason = $e->reason;
+    my $todo   = $e->todo;
+
+    my $out = "";
+    $out .= "not " unless $e->{pass};
+    $out .= "ok";
+    $out .= " $num" if defined $num;
+    $out .= " - $name" if $name;
+    if (defined($todo)) {
+        $out .= " # TODO & SKIP"
+    }
+    else {
+        $out .= " # skip";
+    }
+    $out .= " $reason" if defined($reason) && length($reason);
+
+    return([OUT_STD, "$out\n"]);
+}
+
+sub event_note {
+    my $self = shift;
+    my ($e, $num) = @_;
+
+    chomp(my $msg = $e->message);
+    $msg =~ s/^/# /;
+    $msg =~ s/\n/\n# /g;
+
+    return [OUT_STD, "$msg\n"];
+}
+
+sub event_diag {
+    my $self = shift;
+    my ($e, $num) = @_;
+
+    chomp(my $msg = $e->message);
+    $msg =~ s/^/# /;
+    $msg =~ s/\n/\n# /g;
+
+    return [OUT_ERR, "$msg\n"];
+}
+
+sub event_bail {
+    my $self = shift;
+    my ($e, $num) = @_;
+
+    return if $e->nested;
+
+    return [
+        OUT_STD,
+        "Bail out!  " . $e->reason . "\n",
+    ];
+}
+
+sub event_exception {
+    my $self = shift;
+    my ($e, $num) = @_;
+    return [ OUT_ERR, $e->error ];
+}
+
+sub event_subtest {
+    my $self = shift;
+    my ($e, $num) = @_;
+
+    # A 'subtest' is a subclass of 'ok'. Let the code that renders 'ok' render
+    # this event.
+    my ($ok, @diag) = $self->event_ok($e, $num);
+
+    # If the subtest is not buffered then the sub-events have already been
+    # rendered, we can go ahead and return.
+    return ($ok, @diag) unless $e->buffered;
+
+    # In a verbose harness we indent the diagnostics from the 'Ok' event since
+    # they will appear inside the subtest braces. This helps readability. In a
+    # non-verbose harness we do nto do this because it is less readable.
+    if ($ENV{HARNESS_IS_VERBOSE}) {
+        # index 0 is the filehandle, index 1 is the message we want to indent.
+        $_->[1] =~ s/^(.*\S.*)$/    $1/mg for @diag;
+    }
+
+    # Add the trailing ' {' to the 'ok' line of TAP output.
+    $ok->[1] =~ s/\n/ {\n/;
+
+    # Render the sub-events, we use our own counter for these.
+    my $count = 0;
+    my @subs = map {
+        # Bump the count for any event that should bump it.
+        $count++ if $_->increments_count;
+
+        # This indents all output lines generated for the sub-events.
+        # index 0 is the filehandle, index 1 is the message we want to indent.
+        map { $_->[1] =~ s/^(.*\S.*)$/    $1/mg; $_ } $self->event_tap($_, $count);
+    } @{$e->subevents};
+
+    return (
+        $ok,                # opening ok - name {
+        @diag,              #   diagnostics if the subtest failed
+        @subs,              #   All the inner-event lines
+        [OUT_STD(), "}\n"], # } (closing brace)
+    );
+}
+
+sub event_plan {
+    my $self = shift;
+    my ($e, $num) = @_;
+
+    my $directive = $e->directive;
+    return if $directive && $directive eq 'NO PLAN';
+
+    my $reason = $e->reason;
+    $reason =~ s/\n/\n# /g if $reason;
+
+    my $plan = "1.." . $e->max;
+    if ($directive) {
+        $plan .= " # $directive";
+        $plan .= " $reason" if defined $reason;
+    }
+
+    return [OUT_STD, "$plan\n"];
+}
+
+sub event_other {
+    my $self = shift;
+    my ($e, $num) = @_;
+    return if $e->no_display;
+
+    my @out;
+
+    if (my ($max, $directive, $reason) = $e->sets_plan) {
+        my $plan = "1..$max";
+        $plan .= " # $directive" if $directive;
+        $plan .= " $reason" if defined $reason;
+        push @out => [OUT_STD, "$plan\n"];
+    }
+
+    if ($e->increments_count) {
+        my $ok = "";
+        $ok .= "not " if $e->causes_fail;
+        $ok .= "ok";
+        $ok .= " $num" if defined($num);
+        $ok .= " - " . $e->summary if $e->summary;
+
+        push @out => [OUT_STD, "$ok\n"];
+    }
+    else { # Comment
+        my $handle =  ($e->causes_fail || $e->diagnostics) ? OUT_ERR : OUT_STD;
+        my $summary = $e->summary || ref($e);
+        chomp($summary);
+        $summary =~ s/^/# /smg;
+        push @out => [$handle, "$summary\n"];
+    }
+
+    return @out;
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Formatter::TAP - Standard TAP formatter
+
+=head1 DESCRIPTION
+
+This is what takes events and turns them into TAP.
+
+=head1 SYNOPSIS
+
+    use Test2::Formatter::TAP;
+    my $tap = Test2::Formatter::TAP->new();
+
+    # Switch to utf8
+    $tap->encoding('utf8');
+
+    $tap->write($event, $number); # Output an event
+
+=head1 METHODS
+
+=over 4
+
+=item $bool = $tap->no_numbers
+
+=item $tap->set_no_numbers($bool)
+
+Use to turn numbers on and off.
+
+=item $arrayref = $tap->handles
+
+=item $tap->set_handles(\@handles);
+
+Can be used to get/set the filehandles. Indexes are identified by the
+C<OUT_STD> and C<OUT_ERR> constants.
+
+=item $encoding = $tap->encoding
+
+=item $tap->encoding($encoding)
+
+Get or set the encoding. By default no encoding is set, the original settings
+of STDOUT and STDERR are used.
+
+This directly modifies the stored filehandles, it does not create new ones.
+
+=item $tap->write($e, $num)
+
+Write an event to the console.
+
+=item Test2::Formatter::TAP->register_event($pkg, sub { ... });
+
+In general custom events are not supported. There are however occasions where
+you might want to write a custom event type that results in TAP output. In
+order to do this you use the C<register_event()> class method.
+
+    package My::Event;
+    use Test2::Formatter::TAP;
+
+    use base 'Test2::Event';
+    use Test2::Util::HashBase accessors => [qw/pass name diag note/];
+
+    Test2::Formatter::TAP->register_event(
+        __PACKAGE__,
+        sub {
+            my $self = shift;
+            my ($e, $num) = @_;
+            return (
+                [Test2::Formatter::TAP::OUT_STD, "ok $num - " . $e->name . "\n"],
+                [Test2::Formatter::TAP::OUT_ERR, "# " . $e->name . " " . $e->diag . "\n"],
+                [Test2::Formatter::TAP::OUT_STD, "# " . $e->name . " " . $e->note . "\n"],
+            );
+        }
+    );
+
+    1;
+
+=back
+
+=head2 EVENT METHODS
+
+All these methods require the event itself. Optionally they can all except a
+test number.
+
+All methods return a list of array-refs. Each array-ref will have 2 items, the
+first is an integer identifying an output handle, the second is a string that
+should be written to the handle.
+
+=over 4
+
+=item @out = $TAP->event_ok($e)
+
+=item @out = $TAP->event_ok($e, $num)
+
+Process an L<Test2::Event::Ok> event.
+
+=item @out = $TAP->event_plan($e)
+
+=item @out = $TAP->event_plan($e, $num)
+
+Process an L<Test2::Event::Plan> event.
+
+=item @out = $TAP->event_note($e)
+
+=item @out = $TAP->event_note($e, $num)
+
+Process an L<Test2::Event::Note> event.
+
+=item @out = $TAP->event_diag($e)
+
+=item @out = $TAP->event_diag($e, $num)
+
+Process an L<Test2::Event::Diag> event.
+
+=item @out = $TAP->event_bail($e)
+
+=item @out = $TAP->event_bail($e, $num)
+
+Process an L<Test2::Event::Bail> event.
+
+=item @out = $TAP->event_exception($e)
+
+=item @out = $TAP->event_exception($e, $num)
+
+Process an L<Test2::Event::Exception> event.
+
+=item @out = $TAP->event_skip($e)
+
+=item @out = $TAP->event_skip($e, $num)
+
+Process an L<Test2::Event::Skip> event.
+
+=item @out = $TAP->event_subtest($e)
+
+=item @out = $TAP->event_subtest($e, $num)
+
+Process an L<Test2::Event::Subtest> event.
+
+=item @out = $TAP->event_other($e, $num)
+
+Fallback for unregistered event types. It uses the L<Test2::Event> api to
+convert the event to TAP.
+
+=back
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=item Kent Fredric E<lt>kentnl@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/cpan/Test-Simple/lib/Test2/Hub.pm b/cpan/Test-Simple/lib/Test2/Hub.pm
new file mode 100644 (file)
index 0000000..1d49977
--- /dev/null
@@ -0,0 +1,800 @@
+package Test2::Hub;
+use strict;
+use warnings;
+
+our $VERSION = '1.302015';
+
+
+use Carp qw/carp croak confess/;
+use Test2::Util qw/get_tid/;
+
+use Scalar::Util qw/weaken/;
+
+use Test2::Util::ExternalMeta qw/meta get_meta set_meta delete_meta/;
+use Test2::Util::HashBase qw{
+    pid tid hid ipc
+    no_ending
+    _filters
+    _pre_filters
+    _listeners
+    _follow_ups
+    _formatter
+    _context_acquire
+    _context_init
+    _context_release
+
+    count
+    failed
+    ended
+    bailed_out
+    _passing
+    _plan
+    skip_reason
+};
+
+my $ID_POSTFIX = 1;
+sub init {
+    my $self = shift;
+
+    $self->{+PID} = $$;
+    $self->{+TID} = get_tid();
+    $self->{+HID} = join '-', $self->{+PID}, $self->{+TID}, $ID_POSTFIX++;
+
+    $self->{+COUNT}    = 0;
+    $self->{+FAILED}   = 0;
+    $self->{+_PASSING} = 1;
+
+    if (my $formatter = delete $self->{formatter}) {
+        $self->format($formatter);
+    }
+
+    if (my $ipc = $self->{+IPC}) {
+        $ipc->add_hub($self->{+HID});
+    }
+}
+
+sub reset_state {
+    my $self = shift;
+
+    $self->{+COUNT} = 0;
+    $self->{+FAILED} = 0;
+    $self->{+_PASSING} = 1;
+
+    delete $self->{+_PLAN};
+    delete $self->{+ENDED};
+    delete $self->{+BAILED_OUT};
+    delete $self->{+SKIP_REASON};
+}
+
+sub inherit {
+    my $self = shift;
+    my ($from, %params) = @_;
+
+    $self->{+_FORMATTER} = $from->{+_FORMATTER}
+        unless $self->{+_FORMATTER} || exists($params{formatter});
+
+    if ($from->{+IPC} && !$self->{+IPC} && !exists($params{ipc})) {
+        my $ipc = $from->{+IPC};
+        $self->{+IPC} = $ipc;
+        $ipc->add_hub($self->{+HID});
+    }
+
+    if (my $ls = $from->{+_LISTENERS}) {
+        push @{$self->{+_LISTENERS}} => grep { $_->{inherit} } @$ls;
+    }
+
+    if (my $fs = $from->{+_FILTERS}) {
+        push @{$self->{+_FILTERS}} => grep { $_->{inherit} } @$fs;
+    }
+}
+
+sub format {
+    my $self = shift;
+
+    my $old = $self->{+_FORMATTER};
+    ($self->{+_FORMATTER}) = @_ if @_;
+
+    return $old;
+}
+
+sub is_local {
+    my $self = shift;
+    return $$ == $self->{+PID}
+        && get_tid() == $self->{+TID};
+}
+
+sub listen {
+    my $self = shift;
+    my ($sub, %params) = @_;
+
+    carp "Useless addition of a listener in a child process or thread!"
+        if $$ != $self->{+PID} || get_tid() != $self->{+TID};
+
+    croak "listen only takes coderefs for arguments, got '$sub'"
+        unless ref $sub && ref $sub eq 'CODE';
+
+    push @{$self->{+_LISTENERS}} => { %params, code => $sub };
+
+    $sub; # Intentional return.
+}
+
+sub unlisten {
+    my $self = shift;
+
+    carp "Useless removal of a listener in a child process or thread!"
+        if $$ != $self->{+PID} || get_tid() != $self->{+TID};
+
+    my %subs = map {$_ => $_} @_;
+
+    @{$self->{+_LISTENERS}} = grep { !$subs{$_->{code}} } @{$self->{+_LISTENERS}};
+}
+
+sub filter {
+    my $self = shift;
+    my ($sub, %params) = @_;
+
+    carp "Useless addition of a filter in a child process or thread!"
+        if $$ != $self->{+PID} || get_tid() != $self->{+TID};
+
+    croak "filter only takes coderefs for arguments, got '$sub'"
+        unless ref $sub && ref $sub eq 'CODE';
+
+    push @{$self->{+_FILTERS}} => { %params, code => $sub };
+
+    $sub; # Intentional Return
+}
+
+sub unfilter {
+    my $self = shift;
+    carp "Useless removal of a filter in a child process or thread!"
+        if $$ != $self->{+PID} || get_tid() != $self->{+TID};
+    my %subs = map {$_ => $_} @_;
+    @{$self->{+_FILTERS}} = grep { !$subs{$_->{code}} } @{$self->{+_FILTERS}};
+}
+
+sub pre_filter {
+    my $self = shift;
+    my ($sub, %params) = @_;
+
+    croak "pre_filter only takes coderefs for arguments, got '$sub'"
+        unless ref $sub && ref $sub eq 'CODE';
+
+    push @{$self->{+_PRE_FILTERS}} => { %params, code => $sub };
+
+    $sub; # Intentional Return
+}
+
+sub pre_unfilter {
+    my $self = shift;
+    my %subs = map {$_ => $_} @_;
+    @{$self->{+_PRE_FILTERS}} = grep { !$subs{$_->{code}} } @{$self->{+_PRE_FILTERS}};
+}
+
+sub follow_up {
+    my $self = shift;
+    my ($sub) = @_;
+
+    carp "Useless addition of a follow-up in a child process or thread!"
+        if $$ != $self->{+PID} || get_tid() != $self->{+TID};
+
+    croak "follow_up only takes coderefs for arguments, got '$sub'"
+        unless ref $sub && ref $sub eq 'CODE';
+
+    push @{$self->{+_FOLLOW_UPS}} => $sub;
+}
+
+*add_context_aquire = \&add_context_acquire;
+sub add_context_acquire {
+    my $self = shift;
+    my ($sub) = @_;
+
+    croak "add_context_acquire only takes coderefs for arguments, got '$sub'"
+        unless ref $sub && ref $sub eq 'CODE';
+
+    push @{$self->{+_CONTEXT_ACQUIRE}} => $sub;
+
+    $sub; # Intentional return.
+}
+
+*remove_context_aquire = \&remove_context_acquire;
+sub remove_context_acquire {
+    my $self = shift;
+    my %subs = map {$_ => $_} @_;
+    @{$self->{+_CONTEXT_ACQUIRE}} = grep { !$subs{$_} == $_