cpan/Test-Harness/lib/TAP/Parser/SourceHandler/File.pm
cpan/Test-Harness/lib/TAP/Parser/SourceHandler/Handle.pm
cpan/Test-Harness/lib/TAP/Parser/SourceHandler/Perl.pm
-cpan/Test-Harness/lib/TAP/Parser/SourceHandler/pgTAP.pm
cpan/Test-Harness/lib/TAP/Parser/SourceHandler.pm A parser for Test Anything Protocol
cpan/Test-Harness/lib/TAP/Parser/SourceHandler/RawTAP.pm
cpan/Test-Harness/lib/TAP/Parser/Source.pm A parser for Test Anything Protocol
cpan/Test-Harness/t/lib/MyPerlSourceHandler.pm Test::Harness test
cpan/Test-Harness/t/lib/MyResultFactory.pm Module for testing Test::Harness
cpan/Test-Harness/t/lib/MyResult.pm Module for testing Test::Harness
-cpan/Test-Harness/t/lib/MyShebangger.pm Test::Harness test
cpan/Test-Harness/t/lib/MySourceHandler.pm Test::Harness test
cpan/Test-Harness/t/lib/NoFork.pm Module for testing Test::Harness
cpan/Test-Harness/t/lib/NOP.pm Module for testing Test::Harness
cpan/Test-Harness/t/lib/TAP/Harness/TestSubclass.pm
cpan/Test-Harness/t/lib/TAP/Parser/SubclassTest.pm Module for testing Test::Harness
cpan/Test-Harness/t/multiplexer.t Test::Harness test
+cpan/Test-Harness/t/nested.t Test::Harness test
cpan/Test-Harness/t/nofork-mux.t Test::Harness test
cpan/Test-Harness/t/nofork.t Test::Harness test
cpan/Test-Harness/t/object.t Test::Harness test
cpan/Test-Harness/t/proverc.t Test::Harness test
cpan/Test-Harness/t/proverun.t Test::Harness test
cpan/Test-Harness/t/prove.t Test::Harness test
+cpan/Test-Harness/t/proveversion.t Test::Harness test
cpan/Test-Harness/t/regression.t Test::Harness test
cpan/Test-Harness/t/results.t Test::Harness test
cpan/Test-Harness/t/sample-tests/bailout Test data for Test::Harness
cpan/Test-Harness/t/sample-tests/simple Test data for Test::Harness
cpan/Test-Harness/t/sample-tests/simple_fail Test data for Test::Harness
cpan/Test-Harness/t/sample-tests/simple_yaml Test data for Test::Harness
+cpan/Test-Harness/t/sample-tests/simple_yaml_missing_version13 Test data for Test::Harness
cpan/Test-Harness/t/sample-tests/skip Test data for Test::Harness
cpan/Test-Harness/t/sample-tests/skipall Test data for Test::Harness
cpan/Test-Harness/t/sample-tests/skipall_nomsg Test data for Test::Harness
cpan/Test-Harness/t/sample-tests/version_old Test data for Test::Harness
cpan/Test-Harness/t/sample-tests/vms_nit Test data for Test::Harness
cpan/Test-Harness/t/sample-tests/with_comments Test data for Test::Harness
+cpan/Test-Harness/t/sample-tests/yaml_late_plan Test data for Test::Harness
cpan/Test-Harness/t/sample-tests/zero_valid Test data for Test::Harness
cpan/Test-Harness/t/scheduler.t Test::Harness test
cpan/Test-Harness/t/source_handler.t Test::Harness test
cpan/Test-Harness/t/source_tests/harness_complain Test data for Test::Harness
cpan/Test-Harness/t/source_tests/harness_directives Test data for Test::Harness
cpan/Test-Harness/t/source_tests/harness_failure Test data for Test::Harness
-cpan/Test-Harness/t/source_tests/psql Test::Harness test
cpan/Test-Harness/t/source_tests/psql.bat Test::Harness test
cpan/Test-Harness/t/source_tests/source Test data for Test::Harness
cpan/Test-Harness/t/source_tests/source.1 Test::Harness test
+cpan/Test-Harness/t/source_tests/source_args.sh Test::Harness test
cpan/Test-Harness/t/source_tests/source.bat Test::Harness test
cpan/Test-Harness/t/source_tests/source.pl Test::Harness test
cpan/Test-Harness/t/source_tests/source.sh Test::Harness test
'Test::Harness' =>
{
'MAINTAINER' => 'andya',
- 'DISTRIBUTION' => 'ANDYA/Test-Harness-3.21.tar.gz',
+ 'DISTRIBUTION' => 'ANDYA/Test-Harness-3.22.tar.gz',
'FILES' => q[cpan/Test-Harness],
'EXCLUDED' => [ qr{^examples/},
qr{^inc/},
configpm
configure.gnu
cpan/Test-Harness/t/source_tests/source.sh
+cpan/Test-Harness/t/source_tests/source_args.sh
embed.pl
installperl
installman
Revision history for Test-Harness
+3.22 2010-08-14
+ - Allow TAP::Parser to recognize a nested BAIL_OUT directive.
+ - Add brief HOWTO for creating and running pgTAP tests to
+ TAP::Parser::SourceHandler::pgTAP.
+ - Fix trailing plan + embedded YAML + TAP 13 case. Thanks to
+ Steffen Schwigon. #54518.
+ - Numerous spelling fixes. Thanks to Ville Skyttä.
+ - Add new option --tapversion for prove to set the default
+ assumed TAP version. Thanks to Steffen Schwigon.
+ - Fixed tests to run successfully under Devel::Cover. Thanks to
+ Phillipe Bruhat.
+ - Fixed injection of test args to work with general executables
+ as well as Perl scripts (#59186).
+ - Allow multiple --ext=.foo arguments to prove, to allow running
+ different types of tests in the same prove run.
+ - App::Prove::extension() is now App::Prove::extensions(), and
+ returns an arrayref of extensions, rather than a single scalar.
+ The same change has been made to App::Prove::State::extension().
+ - Preserve old semantics for test scripts with a shebang line
+ by favouring Perl as the intepreter for any file with a
+ shebang (#59457).
+ - Add --trap (summary on Ctrl-C) option to prove (#59427).
+ - Removed TAP::Parser::SourceHandler::pgTAP. Find it in its own
+ distribution on CPAN.
+ - Source options to prove can now be specified so as to be passed to
+ the source as a hash reference, eg:
+
+ prove --source XYZ --xyz-option pset=foo=bar
+
+ Ths "pset" option will be passed as a hash reference with the key
+ "foo" and the value "bar".
+
3.21 2010-01-30
- Add test to ensure we're not depending on a module we no
longer ship.
bin/prove
-Build.PL
Changes
Changes-2.64
examples/analyze_tests.pl
lib/TAP/Parser/SourceHandler/File.pm
lib/TAP/Parser/SourceHandler/Handle.pm
lib/TAP/Parser/SourceHandler/Perl.pm
-lib/TAP/Parser/SourceHandler/pgTAP.pm
lib/TAP/Parser/SourceHandler/RawTAP.pm
lib/TAP/Parser/Utils.pm
lib/TAP/Parser/YAMLish/Reader.pm
lib/TAP/Parser/YAMLish/Writer.pm
lib/Test/Harness.pm
+Makefile.PL
MANIFEST
MANIFEST.CUMMULATIVE
META.yml
+NotBuild.PL
perlcriticrc
README
t/000-load.t
t/lib/MyPerlSourceHandler.pm
t/lib/MyResult.pm
t/lib/MyResultFactory.pm
-t/lib/MyShebangger.pm
t/lib/MySourceHandler.pm
t/lib/NoFork.pm
t/lib/NOP.pm
t/lib/Test/More.pm
t/lib/Test/Simple.pm
t/multiplexer.t
+t/nested.t
t/nofork-mux.t
t/nofork.t
t/object.t
t/proverc.t
t/proverc/emptyexec
t/proverun.t
+t/proveversion.t
t/regression.t
t/results.t
t/sample-tests/bailout
t/sample-tests/simple
t/sample-tests/simple_fail
t/sample-tests/simple_yaml
+t/sample-tests/simple_yaml_missing_version13
t/sample-tests/skip
t/sample-tests/skip_nomsg
t/sample-tests/skipall
t/sample-tests/version_old
t/sample-tests/vms_nit
t/sample-tests/with_comments
+t/sample-tests/yaml_late_plan
t/sample-tests/zero_valid
t/scheduler.t
t/source.t
t/source_tests/harness_complain
t/source_tests/harness_directives
t/source_tests/harness_failure
-t/source_tests/psql
t/source_tests/psql.bat
t/source_tests/source
t/source_tests/source.1
t/source_tests/source.sh
t/source_tests/source.t
t/source_tests/source.tap
+t/source_tests/source_args.sh
t/spool.t
t/state.t
t/state_results.t
MANIFEST.CUMMULATIVE
META.yml
Makefile.PL
+NotBuild.PL
README
TODO
+Test-Harness-3.22/Changes
+Test-Harness-3.22/Changes-2.64
+Test-Harness-3.22/HACKING.pod
+Test-Harness-3.22/MANIFEST
+Test-Harness-3.22/MANIFEST.CUMMULATIVE
+Test-Harness-3.22/META.yml
+Test-Harness-3.22/Makefile.PL
+Test-Harness-3.22/NotBuild.PL
+Test-Harness-3.22/README
+Test-Harness-3.22/bin/prove
+Test-Harness-3.22/examples/README
+Test-Harness-3.22/examples/analyze_tests.pl
+Test-Harness-3.22/examples/bin/forked_tests.pl
+Test-Harness-3.22/examples/bin/test_html.pl
+Test-Harness-3.22/examples/bin/tprove_gtk
+Test-Harness-3.22/examples/harness-hook/hook.pl
+Test-Harness-3.22/examples/harness-hook/lib/Harness/Hook.pm
+Test-Harness-3.22/examples/my_exec
+Test-Harness-3.22/examples/silent-harness.pl
+Test-Harness-3.22/examples/t/10-stuff.t
+Test-Harness-3.22/examples/t/ruby.t
+Test-Harness-3.22/examples/test_urls.txt
+Test-Harness-3.22/inc/MyBuilder.pm
+Test-Harness-3.22/lib/App/Prove.pm
+Test-Harness-3.22/lib/App/Prove/State.pm
+Test-Harness-3.22/lib/App/Prove/State/Result.pm
+Test-Harness-3.22/lib/App/Prove/State/Result/Test.pm
+Test-Harness-3.22/lib/TAP/Base.pm
+Test-Harness-3.22/lib/TAP/Formatter/Base.pm
+Test-Harness-3.22/lib/TAP/Formatter/Color.pm
+Test-Harness-3.22/lib/TAP/Formatter/Console.pm
+Test-Harness-3.22/lib/TAP/Formatter/Console/ParallelSession.pm
+Test-Harness-3.22/lib/TAP/Formatter/Console/Session.pm
+Test-Harness-3.22/lib/TAP/Formatter/File.pm
+Test-Harness-3.22/lib/TAP/Formatter/File/Session.pm
+Test-Harness-3.22/lib/TAP/Formatter/Session.pm
+Test-Harness-3.22/lib/TAP/Harness.pm
+Test-Harness-3.22/lib/TAP/Harness/Beyond.pod
+Test-Harness-3.22/lib/TAP/Object.pm
+Test-Harness-3.22/lib/TAP/Parser.pm
+Test-Harness-3.22/lib/TAP/Parser/Aggregator.pm
+Test-Harness-3.22/lib/TAP/Parser/Grammar.pm
+Test-Harness-3.22/lib/TAP/Parser/Iterator.pm
+Test-Harness-3.22/lib/TAP/Parser/Iterator/Array.pm
+Test-Harness-3.22/lib/TAP/Parser/Iterator/Process.pm
+Test-Harness-3.22/lib/TAP/Parser/Iterator/Stream.pm
+Test-Harness-3.22/lib/TAP/Parser/IteratorFactory.pm
+Test-Harness-3.22/lib/TAP/Parser/Multiplexer.pm
+Test-Harness-3.22/lib/TAP/Parser/Result.pm
+Test-Harness-3.22/lib/TAP/Parser/Result/Bailout.pm
+Test-Harness-3.22/lib/TAP/Parser/Result/Comment.pm
+Test-Harness-3.22/lib/TAP/Parser/Result/Plan.pm
+Test-Harness-3.22/lib/TAP/Parser/Result/Pragma.pm
+Test-Harness-3.22/lib/TAP/Parser/Result/Test.pm
+Test-Harness-3.22/lib/TAP/Parser/Result/Unknown.pm
+Test-Harness-3.22/lib/TAP/Parser/Result/Version.pm
+Test-Harness-3.22/lib/TAP/Parser/Result/YAML.pm
+Test-Harness-3.22/lib/TAP/Parser/ResultFactory.pm
+Test-Harness-3.22/lib/TAP/Parser/Scheduler.pm
+Test-Harness-3.22/lib/TAP/Parser/Scheduler/Job.pm
+Test-Harness-3.22/lib/TAP/Parser/Scheduler/Spinner.pm
+Test-Harness-3.22/lib/TAP/Parser/Source.pm
+Test-Harness-3.22/lib/TAP/Parser/SourceHandler.pm
+Test-Harness-3.22/lib/TAP/Parser/SourceHandler/Executable.pm
+Test-Harness-3.22/lib/TAP/Parser/SourceHandler/File.pm
+Test-Harness-3.22/lib/TAP/Parser/SourceHandler/Handle.pm
+Test-Harness-3.22/lib/TAP/Parser/SourceHandler/Perl.pm
+Test-Harness-3.22/lib/TAP/Parser/SourceHandler/RawTAP.pm
+Test-Harness-3.22/lib/TAP/Parser/Utils.pm
+Test-Harness-3.22/lib/TAP/Parser/YAMLish/Reader.pm
+Test-Harness-3.22/lib/TAP/Parser/YAMLish/Writer.pm
+Test-Harness-3.22/lib/Test/Harness.pm
+Test-Harness-3.22/perlcriticrc
+Test-Harness-3.22/t/000-load.t
+Test-Harness-3.22/t/aggregator.t
+Test-Harness-3.22/t/bailout.t
+Test-Harness-3.22/t/base.t
+Test-Harness-3.22/t/callbacks.t
+Test-Harness-3.22/t/compat/env.t
+Test-Harness-3.22/t/compat/failure.t
+Test-Harness-3.22/t/compat/inc-propagation.t
+Test-Harness-3.22/t/compat/inc_taint.t
+Test-Harness-3.22/t/compat/nonumbers.t
+Test-Harness-3.22/t/compat/regression.t
+Test-Harness-3.22/t/compat/subclass.t
+Test-Harness-3.22/t/compat/switches.t
+Test-Harness-3.22/t/compat/test-harness-compat.t
+Test-Harness-3.22/t/compat/version.t
+Test-Harness-3.22/t/console.t
+Test-Harness-3.22/t/data/catme.1
+Test-Harness-3.22/t/data/proverc
+Test-Harness-3.22/t/data/sample.yml
+Test-Harness-3.22/t/errors.t
+Test-Harness-3.22/t/file.t
+Test-Harness-3.22/t/glob-to-regexp.t
+Test-Harness-3.22/t/grammar.t
+Test-Harness-3.22/t/harness-bailout.t
+Test-Harness-3.22/t/harness-subclass.t
+Test-Harness-3.22/t/harness.t
+Test-Harness-3.22/t/iterator_factory.t
+Test-Harness-3.22/t/iterators.t
+Test-Harness-3.22/t/lib/App/Prove/Plugin/Dummy.pm
+Test-Harness-3.22/t/lib/App/Prove/Plugin/Dummy2.pm
+Test-Harness-3.22/t/lib/Dev/Null.pm
+Test-Harness-3.22/t/lib/EmptyParser.pm
+Test-Harness-3.22/t/lib/IO/c55Capture.pm
+Test-Harness-3.22/t/lib/MyCustom.pm
+Test-Harness-3.22/t/lib/MyFileSourceHandler.pm
+Test-Harness-3.22/t/lib/MyGrammar.pm
+Test-Harness-3.22/t/lib/MyIterator.pm
+Test-Harness-3.22/t/lib/MyPerlSourceHandler.pm
+Test-Harness-3.22/t/lib/MyResult.pm
+Test-Harness-3.22/t/lib/MyResultFactory.pm
+Test-Harness-3.22/t/lib/MySourceHandler.pm
+Test-Harness-3.22/t/lib/NOP.pm
+Test-Harness-3.22/t/lib/NoFork.pm
+Test-Harness-3.22/t/lib/TAP/Harness/TestSubclass.pm
+Test-Harness-3.22/t/lib/TAP/Parser/SubclassTest.pm
+Test-Harness-3.22/t/lib/Test/Builder.pm
+Test-Harness-3.22/t/lib/Test/Builder/Module.pm
+Test-Harness-3.22/t/lib/Test/More.pm
+Test-Harness-3.22/t/lib/Test/Simple.pm
+Test-Harness-3.22/t/lib/if.pm
+Test-Harness-3.22/t/multiplexer.t
+Test-Harness-3.22/t/nested.t
+Test-Harness-3.22/t/nofork-mux.t
+Test-Harness-3.22/t/nofork.t
+Test-Harness-3.22/t/object.t
+Test-Harness-3.22/t/parse.t
+Test-Harness-3.22/t/parser-config.t
+Test-Harness-3.22/t/parser-subclass.t
+Test-Harness-3.22/t/perl5lib.t
+Test-Harness-3.22/t/premature-bailout.t
+Test-Harness-3.22/t/process.t
+Test-Harness-3.22/t/prove.t
+Test-Harness-3.22/t/proveenv.t
+Test-Harness-3.22/t/proverc.t
+Test-Harness-3.22/t/proverc/emptyexec
+Test-Harness-3.22/t/proverun.t
+Test-Harness-3.22/t/proveversion.t
+Test-Harness-3.22/t/regression.t
+Test-Harness-3.22/t/results.t
+Test-Harness-3.22/t/sample-tests/bailout
+Test-Harness-3.22/t/sample-tests/bignum
+Test-Harness-3.22/t/sample-tests/bignum_many
+Test-Harness-3.22/t/sample-tests/combined
+Test-Harness-3.22/t/sample-tests/combined_compat
+Test-Harness-3.22/t/sample-tests/delayed
+Test-Harness-3.22/t/sample-tests/descriptive
+Test-Harness-3.22/t/sample-tests/descriptive_trailing
+Test-Harness-3.22/t/sample-tests/die
+Test-Harness-3.22/t/sample-tests/die_head_end
+Test-Harness-3.22/t/sample-tests/die_last_minute
+Test-Harness-3.22/t/sample-tests/die_unfinished
+Test-Harness-3.22/t/sample-tests/duplicates
+Test-Harness-3.22/t/sample-tests/echo
+Test-Harness-3.22/t/sample-tests/empty
+Test-Harness-3.22/t/sample-tests/escape_eol
+Test-Harness-3.22/t/sample-tests/escape_hash
+Test-Harness-3.22/t/sample-tests/head_end
+Test-Harness-3.22/t/sample-tests/head_fail
+Test-Harness-3.22/t/sample-tests/inc_taint
+Test-Harness-3.22/t/sample-tests/junk_before_plan
+Test-Harness-3.22/t/sample-tests/lone_not_bug
+Test-Harness-3.22/t/sample-tests/no_nums
+Test-Harness-3.22/t/sample-tests/no_output
+Test-Harness-3.22/t/sample-tests/out_err_mix
+Test-Harness-3.22/t/sample-tests/out_of_order
+Test-Harness-3.22/t/sample-tests/schwern
+Test-Harness-3.22/t/sample-tests/schwern-todo-quiet
+Test-Harness-3.22/t/sample-tests/segfault
+Test-Harness-3.22/t/sample-tests/sequence_misparse
+Test-Harness-3.22/t/sample-tests/shbang_misparse
+Test-Harness-3.22/t/sample-tests/simple
+Test-Harness-3.22/t/sample-tests/simple_fail
+Test-Harness-3.22/t/sample-tests/simple_yaml
+Test-Harness-3.22/t/sample-tests/simple_yaml_missing_version13
+Test-Harness-3.22/t/sample-tests/skip
+Test-Harness-3.22/t/sample-tests/skip_nomsg
+Test-Harness-3.22/t/sample-tests/skipall
+Test-Harness-3.22/t/sample-tests/skipall_nomsg
+Test-Harness-3.22/t/sample-tests/skipall_v13
+Test-Harness-3.22/t/sample-tests/space_after_plan
+Test-Harness-3.22/t/sample-tests/stdout_stderr
+Test-Harness-3.22/t/sample-tests/strict
+Test-Harness-3.22/t/sample-tests/switches
+Test-Harness-3.22/t/sample-tests/taint
+Test-Harness-3.22/t/sample-tests/taint_warn
+Test-Harness-3.22/t/sample-tests/todo
+Test-Harness-3.22/t/sample-tests/todo_inline
+Test-Harness-3.22/t/sample-tests/todo_misparse
+Test-Harness-3.22/t/sample-tests/too_many
+Test-Harness-3.22/t/sample-tests/version_good
+Test-Harness-3.22/t/sample-tests/version_late
+Test-Harness-3.22/t/sample-tests/version_old
+Test-Harness-3.22/t/sample-tests/vms_nit
+Test-Harness-3.22/t/sample-tests/with_comments
+Test-Harness-3.22/t/sample-tests/yaml_late_plan
+Test-Harness-3.22/t/sample-tests/zero_valid
+Test-Harness-3.22/t/scheduler.t
+Test-Harness-3.22/t/source.t
+Test-Harness-3.22/t/source_handler.t
+Test-Harness-3.22/t/source_tests/harness
+Test-Harness-3.22/t/source_tests/harness_badtap
+Test-Harness-3.22/t/source_tests/harness_complain
+Test-Harness-3.22/t/source_tests/harness_directives
+Test-Harness-3.22/t/source_tests/harness_failure
+Test-Harness-3.22/t/source_tests/psql.bat
+Test-Harness-3.22/t/source_tests/source
+Test-Harness-3.22/t/source_tests/source.1
+Test-Harness-3.22/t/source_tests/source.bat
+Test-Harness-3.22/t/source_tests/source.pl
+Test-Harness-3.22/t/source_tests/source.sh
+Test-Harness-3.22/t/source_tests/source.t
+Test-Harness-3.22/t/source_tests/source.tap
+Test-Harness-3.22/t/source_tests/source_args.sh
+Test-Harness-3.22/t/spool.t
+Test-Harness-3.22/t/state.t
+Test-Harness-3.22/t/state_results.t
+Test-Harness-3.22/t/streams.t
+Test-Harness-3.22/t/subclass_tests/non_perl_source
+Test-Harness-3.22/t/subclass_tests/perl_source
+Test-Harness-3.22/t/taint.t
+Test-Harness-3.22/t/testargs.t
+Test-Harness-3.22/t/unicode.t
+Test-Harness-3.22/t/utils.t
+Test-Harness-3.22/t/yamlish-output.t
+Test-Harness-3.22/t/yamlish-writer.t
+Test-Harness-3.22/t/yamlish.t
+Test-Harness-3.22/xt/author/pod-coverage.t
+Test-Harness-3.22/xt/author/pod.t
+Test-Harness-3.22/xt/author/stdin.t
+Test-Harness-3.22/xt/perls/harness_perl.t
+Test-Harness-3.22/xt/perls/sample-tests/perl_version
bin/prove
bin/runtests
examples/README
lib/TAP/Parser/SourceHandler/Handle.pm
lib/TAP/Parser/SourceHandler/Perl.pm
lib/TAP/Parser/SourceHandler/RawTAP.pm
-lib/TAP/Parser/SourceHandler/pgTAP.pm
lib/TAP/Parser/Utils.pm
lib/TAP/Parser/YAML.pm
lib/TAP/Parser/YAMLish/Reader.pm
t/lib/MyPerlSourceHandler.pm
t/lib/MyResult.pm
t/lib/MyResultFactory.pm
-t/lib/MyShebangger.pm
t/lib/MySource.pm
t/lib/MySourceHandler.pm
t/lib/NOP.pm
t/lib/Test/Simple.pm
t/lib/if.pm
t/multiplexer.t
+t/nested.t
t/nofork-mux.t
t/nofork.t
t/object.t
t/proverc.t
t/proverc/emptyexec
t/proverun.t
+t/proveversion.t
t/regression.t
t/results.t
t/sample-tests/bailout
t/sample-tests/simple
t/sample-tests/simple_fail
t/sample-tests/simple_yaml
+t/sample-tests/simple_yaml_missing_version13
t/sample-tests/skip
t/sample-tests/skip_nomsg
t/sample-tests/skipall
t/sample-tests/version_old
t/sample-tests/vms_nit
t/sample-tests/with_comments
+t/sample-tests/yaml_late_plan
t/sample-tests/zero_valid
t/scheduler.t
t/source.t
t/source_tests/source.sh
t/source_tests/source.t
t/source_tests/source.tap
+t/source_tests/source_args.sh
t/source_tests/varsource
t/spool.t
t/state.t
-p, --parse Show full list of TAP parse errors, if any.
--directives Only show results with TODO or SKIP directives.
--timer Print elapsed time after each test.
+ --trap Trap Ctrl-C and print summary on interrupt.
--normalize Normalize TAP output in verbose output
-T Enable tainting checks.
-t Enable tainting warnings.
get confused. Use this option only if you understand the consequences
and can live with the risk.
+=head2 C<--trap>
+
+The C<--trap> option will attempt to trap SIGINT (Ctrl-C) during a test
+run and display the test summary even if the run is interrupted
+
=head2 C<--state>
You can ask C<prove> to remember the state of previous test runs and
prove --source MyCustom \
--source Perl --perl-option 'foo=bar baz' --perl-option avg=0.278 \
--source File --file-option extensions=.txt --file-option extensions=.tmp t
+ --source pgTAP --pgtap-option pset=format=html --pgtap-option pset=border=2
Each C<--$source-option> option must specify a key/value pair separated by an
C<=>. If an option can take multiple values, just specify it multiple times,
-as with the C<extensions=> examples above.
+as with the C<extensions=> examples above. If the option should be a hash
+reference, specify the value as a second pair separated by a C<=>, as in the
+C<pset=> examples above (escape C<=> with a backslash).
All C<--sources> are combined into a hash, and passed to L<TAP::Harness/new>'s
C<sources> parameter.
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
formatter harness includes modules plugins jobs lib merge parse quiet
really_quiet recurse backwards shuffle taint_fail taint_warn timer
verbose warnings_fail warnings_warn show_help show_man show_version
- state_class test_args state dry extension ignore_exit rules state_manager
- normalize sources
+ state_class test_args state dry extensions ignore_exit rules state_manager
+ normalize sources tapversion trap
);
__PACKAGE__->mk_methods(@ATTR);
}
# Don't add coderefs to GetOptions
GetOptions(
- 'v|verbose' => \$self->{verbose},
- 'f|failures' => \$self->{failures},
- 'o|comments' => \$self->{comments},
- 'l|lib' => \$self->{lib},
- 'b|blib' => \$self->{blib},
- 's|shuffle' => \$self->{shuffle},
- 'color!' => \$self->{color},
- 'colour!' => \$self->{color},
- 'count!' => \$self->{show_count},
- 'c' => \$self->{color},
- 'D|dry' => \$self->{dry},
- 'ext=s' => \$self->{extension},
- 'harness=s' => \$self->{harness},
- 'ignore-exit' => \$self->{ignore_exit},
- 'source=s@' => $self->{sources},
- 'formatter=s' => \$self->{formatter},
- 'r|recurse' => \$self->{recurse},
- 'reverse' => \$self->{backwards},
- 'p|parse' => \$self->{parse},
- 'q|quiet' => \$self->{quiet},
- 'Q|QUIET' => \$self->{really_quiet},
- 'e|exec=s' => \$self->{exec},
- 'm|merge' => \$self->{merge},
- 'I=s@' => $self->{includes},
- 'M=s@' => $self->{modules},
- 'P=s@' => $self->{plugins},
- 'state=s@' => $self->{state},
- 'directives' => \$self->{directives},
- 'h|help|?' => \$self->{show_help},
- 'H|man' => \$self->{show_man},
- 'V|version' => \$self->{show_version},
- 'a|archive=s' => \$self->{archive},
- 'j|jobs=i' => \$self->{jobs},
- 'timer' => \$self->{timer},
- 'T' => \$self->{taint_fail},
- 't' => \$self->{taint_warn},
- 'W' => \$self->{warnings_fail},
- 'w' => \$self->{warnings_warn},
- 'normalize' => \$self->{normalize},
- 'rules=s@' => $self->{rules},
+ 'v|verbose' => \$self->{verbose},
+ 'f|failures' => \$self->{failures},
+ 'o|comments' => \$self->{comments},
+ 'l|lib' => \$self->{lib},
+ 'b|blib' => \$self->{blib},
+ 's|shuffle' => \$self->{shuffle},
+ 'color!' => \$self->{color},
+ 'colour!' => \$self->{color},
+ 'count!' => \$self->{show_count},
+ 'c' => \$self->{color},
+ 'D|dry' => \$self->{dry},
+ 'ext=s@' => \$self->{extensions},
+ 'harness=s' => \$self->{harness},
+ 'ignore-exit' => \$self->{ignore_exit},
+ 'source=s@' => $self->{sources},
+ 'formatter=s' => \$self->{formatter},
+ 'r|recurse' => \$self->{recurse},
+ 'reverse' => \$self->{backwards},
+ 'p|parse' => \$self->{parse},
+ 'q|quiet' => \$self->{quiet},
+ 'Q|QUIET' => \$self->{really_quiet},
+ 'e|exec=s' => \$self->{exec},
+ 'm|merge' => \$self->{merge},
+ 'I=s@' => $self->{includes},
+ 'M=s@' => $self->{modules},
+ 'P=s@' => $self->{plugins},
+ 'state=s@' => $self->{state},
+ 'directives' => \$self->{directives},
+ 'h|help|?' => \$self->{show_help},
+ 'H|man' => \$self->{show_man},
+ 'V|version' => \$self->{show_version},
+ 'a|archive=s' => \$self->{archive},
+ 'j|jobs=i' => \$self->{jobs},
+ 'timer' => \$self->{timer},
+ 'T' => \$self->{taint_fail},
+ 't' => \$self->{taint_warn},
+ 'W' => \$self->{warnings_fail},
+ 'w' => \$self->{warnings_warn},
+ 'normalize' => \$self->{normalize},
+ 'rules=s@' => $self->{rules},
+ 'tapversion=s' => \$self->{tapversion},
+ 'trap' => \$self->{trap},
) or croak('Unable to continue');
# Stash the remainder of argv for later
my %args;
+ $args{trap} = 1 if $self->trap;
+
if ( defined $self->color ? $self->color : $self->_color_default ) {
$args{color} = 1;
}
$args{exec} = [ split( /\s+/, $self->exec ) ]
if ( defined( $self->exec ) );
+ $args{version} = $self->tapversion if defined( $self->tapversion );
+
if ( defined( my $test_args = $self->test_args ) ) {
$args{test_args} = $test_args;
}
my %config;
Getopt::Long::GetOptions(
"$opt_name-option=s%" => sub {
- my ( undef, $k, $v ) = @_;
- if ( exists $config{$k} ) {
- $config{$k} = [ $config{$k} ]
- unless ref $config{$k} eq 'ARRAY';
- push @{ $config{$k} } => $v;
- }
- else {
- $config{$k} = $v;
+ my ( $name, $k, $v ) = @_;
+ if ($v =~ /(?<!\\)=/) {
+ # It's a hash option.
+ croak "Option $name must be consistently used as a hash"
+ if exists $config{$k} && ref $config{$k} ne 'HASH';
+ $config{$k} ||= {};
+ my ($hk, $hv) = split /(?<!\\)=/, $v, 2;
+ $config{$k}{$hk} = $hv;
+ } else {
+ $v =~ s/\\=/=/g;
+ if ( exists $config{$k} ) {
+ $config{$k} = [ $config{$k} ]
+ unless ref $config{$k} eq 'ARRAY';
+ push @{ $config{$k} } => $v;
+ }
+ else {
+ $config{$k} = $v;
+ }
}
}
);
my $self = shift;
my $state = $self->state_manager;
- my $ext = $self->extension;
- $state->extension($ext) if defined $ext;
+ my $ext = $self->extensions;
+ $state->extensions($ext) if defined $ext;
if ( defined( my $state_switch = $self->state ) ) {
$state->apply_switch(@$state_switch);
}
=item C<exec>
-=item C<extension>
+=item C<extensions>
=item C<failures>
=item C<warnings_warn>
+=item C<tapversion>
+
+=item C<trap>
+
=back
=head1 PLUGINS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
The filename of the data store holding the data that App::Prove::State reads.
-=item * C<extension> (optional)
+=item * C<extensions> (optional)
-The test name extension. Defaults to C<.t>.
+The test name extensions. Defaults to C<.t>.
=item * C<result_class> (optional)
my %args = %{ shift || {} };
my $self = bless {
- select => [],
- seq => 1,
- store => delete $args{store},
- extension => ( delete $args{extension} || '.t' ),
- result_class =>
- ( delete $args{result_class} || 'App::Prove::State::Result' ),
+ select => [],
+ seq => 1,
+ store => delete $args{store},
+ extensions => ( delete $args{extensions} || ['.t'] ),
+ result_class => ( delete $args{result_class} || 'App::Prove::State::Result' ),
}, $class;
$self->{_} = $self->result_class->new(
=cut
-=head2 C<extension>
+=head2 C<extensions>
-Get or set the extension files must have in order to be considered
-tests. Defaults to '.t'.
+Get or set the list of extensions that files must have in order to be
+considered tests. Defaults to ['.t'].
=cut
-sub extension {
+sub extensions {
my $self = shift;
- $self->{extension} = shift if @_;
- return $self->{extension};
+ $self->{extensions} = shift if @_;
+ return $self->{extensions};
}
=head2 C<results>
# Do globbing on Win32.
@argv = map { glob "$_" } @argv if NEED_GLOB;
- my $extension = $self->{extension};
+ my $extensions = $self->{extensions};
for my $arg (@argv) {
if ( '-' eq $arg ) {
push @tests,
sort -d $arg
? $recurse
- ? $self->_expand_dir_recursive( $arg, $extension )
- : glob( File::Spec->catfile( $arg, "*$extension" ) )
+ ? $self->_expand_dir_recursive( $arg, $extensions )
+ : map { glob( File::Spec->catfile( $arg, "*$_" ) ) } @{$extensions}
: $arg;
}
return @tests;
}
sub _expand_dir_recursive {
- my ( $self, $dir, $extension ) = @_;
+ my ( $self, $dir, $extensions ) = @_;
my @tests;
+ my $ext_string = join( '|', map { quotemeta } @{$extensions} );
+
find(
{ follow => 1, #21938
follow_skip => 2,
wanted => sub {
- -f
- && /\Q$extension\E$/
+ -f
+ && /(?:$ext_string)$/
&& push @tests => $File::Find::name;
}
},
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
use constant GOT_TIME_HIRES => do {
eval 'use Time::HiRes qw(time);';
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
$harness->summary( $aggregate );
-C<summary> prints the summary report after all tests are run. The argument is
-an aggregate.
+C<summary> prints the summary report after all tests are run. The first
+argument is an aggregate to summarise. An optional second argument may
+be set to a true value to indicate that the summary is being output as a
+result of an interrupted test run.
=cut
sub summary {
- my ( $self, $aggregate ) = @_;
+ my ( $self, $aggregate, $interrupted ) = @_;
return if $self->silent;
$self->_output( $self->_format_now(), "\n" );
}
+ $self->_failure_output("Test run interrupted!\n")
+ if $interrupted;
+
# TODO: Check this condition still works when all subtests pass but
# the exit status is nonzero
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 METHODS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
$ENV{HARNESS_ACTIVE} = 1;
$ENV{HARNESS_VERSION} = $VERSION;
ignore_exit => sub { shift; shift },
rules => sub { shift; shift },
sources => sub { shift; shift },
+ version => sub { shift; shift },
+ trap => sub { shift; shift },
);
for my $method ( sort keys %VALIDATION_FOR ) {
The name of the class to use to aggregate test results. The default is
L<TAP::Parser::Aggregator>.
+=item * C<version>
+
+I<NEW to 3.22>.
+
+Assume this TAP version for L<TAP::Parser> instead of default TAP
+version 12.
+
=item * C<formatter_class>
The name of the class to use to format output. The default is
A filehandle for catching standard output.
+=item * C<trap>
+
+Attempt to print summary information if run is interrupted by
+SIGINT (Ctrl-C).
+
=back
Any keys for which the value is C<undef> will be ignored.
$self->_make_callback( 'before_runtests', $aggregate );
$aggregate->start;
- $self->aggregate_tests( $aggregate, @tests );
- $aggregate->stop;
- $self->summary($aggregate);
- $self->_make_callback( 'after_runtests', $aggregate );
+ my $finish = sub {
+ my $interrupted = shift;
+ $aggregate->stop;
+ $self->summary( $aggregate, $interrupted );
+ $self->_make_callback( 'after_runtests', $aggregate );
+ };
+ my $run = sub {
+ $self->aggregate_tests( $aggregate, @tests );
+ $finish->();
+ };
+
+ if ( $self->trap ) {
+ local $SIG{INT} = sub {
+ print "\n";
+ $finish->(1);
+ exit;
+ };
+ $run->();
+ }
+ else {
+ $run->();
+ }
return $aggregate;
}
=cut
sub summary {
- my ( $self, $aggregate ) = @_;
- $self->formatter->summary($aggregate);
+ my ( $self, @args ) = @_;
+ $self->formatter->summary(@args);
}
sub _after_test {
$args{spool} = $self->_open_spool($test_prog);
$args{merge} = $self->merge;
$args{ignore_exit} = $self->ignore_exit;
+ $args{version} = $self->version if $self->version;
if ( my $exec = $self->exec ) {
$args{exec}
use base qw( TAP::Harness ); use YAML;
sub summary {
- my ( $self, $aggregate ) = @_; print Dump( $aggregate );
+ my ( $self, $aggregate ) = @_;
+ print Dump( $aggregate );
$self->SUPER::summary( $aggregate );
}
my $app = App::Prove->new;
- # Use custom TAP::Harness subclass $app->harness( 'My::TAP::Harness'
- );
+ # Use custom TAP::Harness subclass
+ $app->harness( 'My::TAP::Harness' );
$app->process_args( @ARGV ); exit( $app->run ? 0 : 1 );
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
my $DEFAULT_TAP_VERSION = 12;
my $MAX_TAP_VERSION = 13;
my %initialize = (
version => $DEFAULT_TAP_VERSION,
plan => '', # the test plan (e.g., 1..3)
- tap => '', # the TAP
tests_run => 0, # actual current test numbers
- results => [], # TAP parser results
skipped => [], #
todo => [], #
passed => [], #
my $iterator = delete $args{iterator};
$iterator ||= delete $args{stream}; # deprecated
my $tap = delete $args{tap};
+ my $version = delete $args{version};
my $raw_source = delete $args{source};
my $sources = delete $args{sources};
my $exec = delete $args{exec};
}
elsif ($exec) {
$type = 'exec ' . $exec->[0];
- $source->raw( { exec => [ @$exec, @$test_args ] } );
+ $source->raw( { exec => $exec } );
}
elsif ($raw_source) {
$type = 'source ' . ref($raw_source) || $raw_source;
$self->{$k} = 'ARRAY' eq ref $v ? [] : $v;
}
+ $self->version($version) if $version;
$self->_iterator($iterator);
$self->_spool($spool);
$self->ignore_exit($ignore_exit);
Returns a list of pragmas each of which is a + or - followed by the
pragma name.
-=head2 C<commment> methods
+=head2 C<comment> methods
if ( $result->is_comment ) { ... }
my $explanation = $result->explanation;
If a test had either a C<TODO> or C<SKIP> directive, this method will return
-the accompanying explantion, if present.
+the accompanying explanation, if present.
not ok 17 - 'Pigs can fly' # TODO not enough acid
Once the parser is done, this will return the wait status. If the parser ran
an executable, it returns the wait status of the executable. Otherwise, this
-mererely returns the C<exit> status.
+merely returns the C<exit> status.
=head2 C<ignore_exit>
UNPLANNED_AFTER_TEST => {
test => { act => sub { }, continue => 'UNPLANNED' },
plan => { act => sub { }, continue => 'UNPLANNED' },
- yaml => { goto => 'PLANNED' },
+ yaml => { goto => 'UNPLANNED' },
},
);
If you're looking for an EBNF grammar, see L<TAP::Parser::Grammar>.
-=head1 BACKWARDS COMPATABILITY
+=head1 BACKWARDS COMPATIBILITY
-The Perl-QA list attempted to ensure backwards compatability with
+The Perl-QA list attempted to ensure backwards compatibility with
L<Test::Harness>. However, there are some minor differences.
=head2 Differences
=item 3
-Note that C<TAP::Parser> is designed to be the central 'maker' - ie: it is
+Note that C<TAP::Parser> is designed to be the central "maker" - ie: it is
responsible for creating most new objects in the C<TAP::Parser::*> namespace.
This makes it possible for you to have a single point of configuring what
-subclasses should be used, which in turn means that in many cases you'll find
+subclasses should be used, which means that in many cases you'll find
you only need to sub-class one of the parser's components.
The exception to this rule are I<SourceHandlers> & I<Iterators>, but those are
-both created with customizeable I<IteratorFactory>.
+both created with customizable I<IteratorFactory>.
=item 4
By subclassing, you may end up overriding undocumented methods. That's not
a bad thing per se, but be forewarned that undocumented methods may change
without warning from one release to the next - we cannot guarantee backwards
-compatability. If any I<documented> method needs changing, it will be
+compatibility. If any I<documented> method needs changing, it will be
deprecated first, and changed in a later release.
=back
=head3 Sources
A TAP parser consumes input from a single I<raw source> of TAP, which could come
-from anywhere (a file, an executable, a database, an io handle, a uri, etc..).
+from anywhere (a file, an executable, a database, an IO handle, a URI, etc..).
The source gets bundled up in a L<TAP::Parser::Source> object which gathers some
meta data about it. The parser then uses a L<TAP::Parser::IteratorFactory> to
determine which L<TAP::Parser::SourceHandler> to use to turn the raw source
A TAP parser uses I<iterators> to loop through the I<stream> of TAP read in
from the I<source> it was given. There are a few types of Iterators available
by default, all sub-classes of L<TAP::Parser::Iterator>. Choosing which
-iterator to use is the responsibility of the I<siterator factory>, though it
+iterator to use is the responsibility of the I<iterator factory>, though it
simply delegates to the I<Source Handler> it uses.
If you're writing your own L<TAP::Parser::SourceHandler>, you may need to
=head3 Grammar
-L<TAP::Parser::Grammar> is the heart of the parser - it tokenizes the TAP
+L<TAP::Parser::Grammar> is the heart of the parser. It tokenizes the TAP
input I<stream> and produces results. If you need to customize its behaviour
you should probably familiarize yourself with the source first. Enough
lecturing.
If you need to customize the objects on creation, subclass L<TAP::Parser> and
override L</make_grammar>
-=head1 ACKNOWLEDGEMENTS
+=head1 ACKNOWLEDGMENTS
All of the following have helped. Bug reports, patches, (im)moral
support, or just words of encouragement have all been forthcoming.
=item * Cosimo Streppone
+=item * Ville Skyttä
+
=back
=head1 AUTHORS
Lee Johnson <notfadeaway at btinternet dot com>
+Philippe Bruhat <book@cpan.org>
+
=head1 BUGS
Please report any bugs or feature requests to
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
},
},
bailout => {
- syntax => qr/^Bail out!\s*(.*)/,
+ syntax => qr/^\s*Bail out!\s*(.*)/,
handler => sub {
my ( $self, $line ) = @_;
my $explanation = $1;
For the same reason that we don't apply regexes to streams, we're not using a
formal grammar here. Instead, we parse the TAP in lines.
-For purposes for forward compatability, any result which does not match the
+For purposes for forward compatibility, any result which does not match the
following grammar is currently referred to as
L<TAP::Parser::Result::Unknown>. It is I<not> a parse error.
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 NAME
-TAP::Parser::Iterator::Process - Iterator for proccess-based TAP sources
+TAP::Parser::Iterator::Process - Iterator for process-based TAP sources
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
- # abstract class - not meany to be used directly
+ # abstract class - not meant to be used directly
# see TAP::Parser::ResultFactory for preferred usage
# directly:
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
my $explanation = $result->explanation;
If a test had either a C<TODO> or C<SKIP> directive, this method will return
-the accompanying explantion, if present.
+the accompanying explanation, if present.
not ok 17 - 'Pigs can fly' # TODO not enough acid
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head2 DESCRIPTION
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
It's important to point out that if you want your subclass to be automatically
used by L<TAP::Parser> you'll have to and make sure it gets loaded somehow.
If you're using L<prove> you can write an L<App::Prove> plugin. If you're
-using L<TAP::Parser> or L<TAP::Harness> directly (eg. through a custom script,
+using L<TAP::Parser> or L<TAP::Harness> directly (e.g. through a custom script,
L<ExtUtils::MakeMaker>, or L<Module::Build>) you can use the C<config> option
which will cause L<TAP::Parser::IteratorFactory/load_sources> to load your
subclass).
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
This is an I<executable> L<TAP::Parser::SourceHandler> - it has 2 jobs:
-1. Figure out if the L<TAP::Parser::Source> it's given is an executable command
-(L</can_handle>).
+1. Figure out if the L<TAP::Parser::Source> it's given is an executable
+ command (L</can_handle>).
2. Creates an iterator for executable commands (L</make_iterator>).
-Unless you're writing a plugin or subclassing L<TAP::Parser>, you probably
-won't need to use this module directly.
+Unless you're writing a plugin or subclassing L<TAP::Parser>, you
+probably won't need to use this module directly.
=head1 METHODS
my $vote = $class->can_handle( $source );
-Only votes if $source looks like an executable file. Casts the following votes:
+Only votes if $source looks like an executable file. Casts the
+following votes:
0.9 if it's a hash with an 'exec' key
- 0.8 if it's a .sh file
0.8 if it's a .bat file
0.75 if it's got an execute bit set
my $file = $meta->{file};
# Note: we go in low so we can be out-voted
- return 0.8 if $file->{lc_ext} eq '.sh';
return 0.8 if $file->{lc_ext} eq '.bat';
- return 0.7 if $file->{execute};
+ return 0.25 if $file->{execute};
}
elsif ( $meta->{is_hash} ) {
return 0.9 if $src->raw->{exec};
$class->_autoflush( \*STDOUT );
$class->_autoflush( \*STDERR );
+ push @command, @{ $source->test_args || [] };
+
return $class->iterator_class->new(
{ command => \@command,
merge => $source->merge
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
Only votes if $source looks like a file. Casts the following votes:
0.9 if it has a shebang ala "#!...perl"
+ 0.75 if it has any shebang
0.8 if it's a .t file
0.9 if it's a .pl file
0.75 if it's in a 't' directory
if ( my $shebang = $file->{shebang} ) {
return 0.9 if $shebang =~ /^#!.*\bperl/;
+ # We favour Perl as the interpreter for any shebang to preserve
+ # previous semantics: we used to execute everything via Perl and
+ # relied on it to pass the shebang off to the appropriate
+ # interpreter.
+ return 0.3;
}
return 0.8 if $file->{lc_ext} eq '.t'; # vote higher than Executable
=cut
+sub _autoflush_stdhandles {
+ my ($class) = @_;
+
+ $class->_autoflush( \*STDOUT );
+ $class->_autoflush( \*STDERR );
+}
+
sub make_iterator {
my ( $class, $source ) = @_;
my $meta = $source->meta;
$class->_croak("Cannot find ($perl_script)") unless $meta->{is_file};
# TODO: does this really need to be done here?
- $class->_autoflush( \*STDOUT );
- $class->_autoflush( \*STDERR );
+ $class->_autoflush_stdhandles;
+
+ my ( $libs, $switches )
+ = $class->_mangle_switches(
+ $class->_filter_libs( $class->_switches($source) ) );
+
+ $class->_run( $source, $libs, $switches );
+}
+
+sub _mangle_switches {
+ my ( $class, $libs, $switches ) = @_;
+
+ # Taint mode ignores environment variables so we must retranslate
+ # PERL5LIB as -I switches and place PERL5OPT on the command line
+ # in order that it be seen.
+ if ( grep { $_ eq "-T" || $_ eq "-t" } @{$switches} ) {
+ return (
+ $libs,
+ [ @{$switches},
+ $class->_libs2switches($libs),
+ split_shell( $ENV{PERL5OPT} )
+ ],
+ );
+ }
+
+ return ( $libs, $switches );
+}
+
+sub _filter_libs {
+ my ( $class, @switches ) = @_;
- my @switches = $class->_switches($source);
my $path_sep = $Config{path_sep};
my $path_re = qr{$path_sep};
my @libs;
my @filtered_switches;
for (@switches) {
- if ( !/$path_re/ && / ^ ['"]? -I ['"]? (.*?) ['"]? $ /x ) {
+ if ( !/$path_re/ && m/ ^ ['"]? -I ['"]? (.*?) ['"]? $ /x ) {
push @libs, $1;
}
else {
push @filtered_switches, $_;
}
}
- @switches = @filtered_switches;
+
+ return \@libs, \@filtered_switches;
+}
+
+sub _iterator_hooks {
+ my ( $class, $source, $libs ) = @_;
my $setup = sub {
- if (@libs) {
- $ENV{PERL5LIB}
- = join( $path_sep, grep {defined} @libs, $ENV{PERL5LIB} );
+ if ( @{$libs} ) {
+ $ENV{PERL5LIB} = join(
+ $Config{path_sep}, grep {defined} @{$libs},
+ $ENV{PERL5LIB}
+ );
}
};
}
};
- # Taint mode ignores environment variables so we must retranslate
- # PERL5LIB as -I switches and place PERL5OPT on the command line
- # in order that it be seen.
- if ( grep { $_ eq "-T" || $_ eq "-t" } @switches ) {
- push @switches, $class->_libs2switches(@libs);
- push @switches, split_shell( $ENV{PERL5OPT} );
- }
+ return ( $setup, $teardown );
+}
+
+sub _run {
+ my ( $class, $source, $libs, $switches ) = @_;
- my @command = $class->_get_command_for_switches( $source, @switches )
+ my @command = $class->_get_command_for_switches( $source, $switches )
or $class->_croak("No command found!");
+ my ( $setup, $teardown ) = $class->_iterator_hooks( $source, $libs );
+
+ return $class->_create_iterator( $source, \@command, $setup, $teardown );
+}
+
+sub _create_iterator {
+ my ( $class, $source, $command, $setup, $teardown ) = @_;
+
return TAP::Parser::Iterator::Process->new(
- { command => \@command,
+ { command => $command,
merge => $source->merge,
setup => $setup,
teardown => $teardown,
}
sub _get_command_for_switches {
- my ( $class, $source, @switches ) = @_;
+ my ( $class, $source, $switches ) = @_;
my $file = ${ $source->raw };
my @args = @{ $source->test_args || [] };
my $command = $class->get_perl;
# XXX don't need to quote if we treat the parts as atoms (except maybe vms)
#$file = qq["$file"] if ( $file =~ /\s/ ) && ( $file !~ /^".*"$/ );
- my @command = ( $command, @switches, $file, @args );
+ my @command = ( $command, @{$switches}, $file, @args );
return @command;
}
sub _libs2switches {
my $class = shift;
- return map {"-I$_"} grep {$_} @_;
+ return map {"-I$_"} grep {$_} @{ $_[0] };
}
=head3 C<get_taint>
sub _switches {
my ( $class, $source ) = @_;
my $file = ${ $source->raw };
- my @args = @{ $source->test_args || [] };
my @switches = @{ $source->switches || [] };
my $shebang = $source->meta->{file}->{shebang};
return unless defined $shebang;
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
+++ /dev/null
-package TAP::Parser::SourceHandler::pgTAP;
-
-use strict;
-use vars qw($VERSION @ISA);
-
-use TAP::Parser::IteratorFactory ();
-use TAP::Parser::Iterator::Process ();
-
-@ISA = qw(TAP::Parser::SourceHandler);
-TAP::Parser::IteratorFactory->register_handler(__PACKAGE__);
-
-=head1 NAME
-
-TAP::Parser::SourceHandler::pgTAP - Stream TAP from pgTAP test scripts
-
-=head1 VERSION
-
-Version 3.21
-
-=cut
-
-$VERSION = '3.21';
-
-=head1 SYNOPSIS
-
-In F<Build.PL> for your application with pgTAP tests in F<t/*.pg>:
-
- Module::Build->new(
- module_name => 'MyApp',
- test_file_exts => [qw(.t .pg)],
- use_tap_harness => 1,
- tap_harness_args => {
- sources => {
- Perl => undef,
- pgTAP => {
- dbname => 'try',
- username => 'postgres',
- suffix => '.pg',
- },
- }
- },
- build_requires => {
- 'Module::Build' => '0.30',
- 'TAP::Parser::SourceHandler::pgTAP' => '3.19',
- },
- )->create_build_script;
-
-If you're using L<C<prove>|prove>:
-
- prove --source Perl \
- --source pgTAP --pgtap-option dbname=try \
- --pgtap-option username=postgres \
- --pgtap-option suffix=.pg
-
-Direct use:
-
- use TAP::Parser::Source;
- use TAP::Parser::SourceHandler::pgTAP;
-
- my $source = TAP::Parser::Source->new->raw(\'mytest.pg');
- $source->config({ pgTAP => {
- dbname => 'testing',
- username => 'postgres',
- suffix => '.pg',
- });
- $source->assemble_meta;
-
- my $class = 'TAP::Parser::SourceHandler::pgTAP';
- my $vote = $class->can_handle( $source );
- my $iter = $class->make_iterator( $source );
-
-=head1 DESCRIPTION
-
-This source handler executes pgTAP tests. It does two things:
-
-=over
-
-=item 1.
-
-Looks at the L<TAP::Parser::Source> passed to it to determine whether or not
-the source in question is in fact a pgTAP test (L</can_handle>).
-
-=item 2.
-
-Creates an iterator that will call C<psql> to run the pgTAP tests
-(L</make_iterator>).
-
-=back
-
-Unless you're writing a plugin or subclassing L<TAP::Parser>, you probably
-won't need to use this module directly.
-
-=head1 METHODS
-
-=head2 Class Methods
-
-=head3 C<can_handle>
-
- my $vote = $class->can_handle( $source );
-
-Looks at the source to determine whether or not it's a pgTAP test file and
-returns a score for how likely it is in fact a pgTAP test file. The scores are
-as follows:
-
- 1 if it has a suffix equal to that in the "suffix" config
- 1 if its suffix is ".pg"
- 0.8 if its suffix is ".sql"
- 0.75 if its suffix is ".s"
-
-The latter two scores are subject to change, so try to name your pgTAP tests
-ending in ".pg" or specify a suffix in the configuration to be sure.
-
-=cut
-
-sub can_handle {
- my ( $class, $source ) = @_;
- my $meta = $source->meta;
-
- return 0 unless $meta->{is_file};
-
- my $suf = $meta->{file}{lc_ext};
-
- # If the config specifies a suffix, it's required.
- if ( my $config = $source->config_for('pgTAP') ) {
- if ( defined $config->{suffix} ) {
- return $suf eq $config->{suffix} ? 1 : 0;
- }
- }
-
- # Otherwise, return a score for our supported suffixes.
- my %score_for = (
- '.pg' => 0.9,
- '.sql' => 0.8,
- '.s' => 0.75,
- );
- return $score_for{$suf} || 0;
-}
-
-=head3 C<make_iterator>
-
- my $iterator = $class->make_iterator( $source );
-
-Returns a new L<TAP::Parser::Iterator::Process> for the source. C<<
-$source->raw >> must be either a file name or a scalar reference to the file
-name.
-
-The pgTAP tests are run by executing C<psql>, the PostgreSQL command-line
-utility. A number of arguments are passed to it, many of which you can effect
-by setting up the source source configuration. The configuration must be a
-hash reference, and supports the following keys:
-
-=over
-
-=item C<psql>
-
-The path to the C<psql> command. Defaults to simply "psql", which should work
-well enough if it's in your path.
-
-=item C<dbname>
-
-The database to which to connect to run the tests. Defaults to the value of
-the C<$PGDATABASE> environment variable or, if not set, to the system
-username.
-
-=item C<username>
-
-The PostgreSQL username to use to connect to PostgreSQL. If not specified, no
-username will be used, in which case C<psql> will fall back on either the
-C<$PGUSER> environment variable or, if not set, the system username.
-
-=item C<host>
-
-Specifies the host name of the machine to which to connect to the PostgreSQL
-server. If the value begins with a slash, it is used as the directory for the
-Unix-domain socket. Defaults to the value of the C<$PGDATABASE> environment
-variable or, if not set, the local host.
-
-=item C<port>
-
-Specifies the TCP port or the local Unix-domain socket file extension on which
-the server is listening for connections. Defaults to the value of the
-C<$PGPORT> environment variable or, if not set, to the port specified at the
-time C<psql> was compiled, usually 5432.
-
-=begin comment
-
-=item C<search_path>
-
-The schema search path to use during the execution of the tests. Useful for
-overriding the default search path and you have pgTAP installed in a schema
-not included in that search path.
-
-=end comment
-
-=back
-
-=cut
-
-sub make_iterator {
- my ( $class, $source ) = @_;
- my $config = $source->config_for('pgTAP');
-
- my @command = ( $config->{psql} || 'psql' );
- push @command, qw(
- --no-psqlrc
- --no-align
- --quiet
- --pset pager=
- --pset tuples_only=true
- --set ON_ERROR_ROLLBACK=1
- --set ON_ERROR_STOP=1
- );
-
- for (qw(username host port dbname)) {
- push @command, "--$_" => $config->{$_} if defined $config->{$_};
- }
-
- my $fn = ref $source->raw ? ${ $source->raw } : $source->raw;
- $class->_croak(
- 'No such file or directory: ' . ( defined $fn ? $fn : '' ) )
- unless $fn && -e $fn;
-
- push @command, '--file', $fn;
-
- # XXX I'd like a way to be able to specify environment variables to set when
- # the iterator executes the command...
- # local $ENV{PGOPTIONS} = "--search_path=$config->{search_path}"
- # if $config->{search_path};
-
- return TAP::Parser::Iterator::Process->new(
- { command => \@command,
- merge => $source->merge
- }
- );
-}
-
-=head1 SEE ALSO
-
-L<TAP::Object>,
-L<TAP::Parser>,
-L<TAP::Parser::IteratorFactory>,
-L<TAP::Parser::SourceHandler>,
-L<TAP::Parser::SourceHandler::Executable>,
-L<TAP::Parser::SourceHandler::Perl>,
-L<TAP::Parser::SourceHandler::File>,
-L<TAP::Parser::SourceHandler::Handle>,
-L<TAP::Parser::SourceHandler::RawTAP>
-
-=head1 AUTHOR
-
-David E. Wheeler <dwheeler@cpan.org>
-
-=cut
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
=head1 SYNOPSIS
use TAP::Object ();
@ISA = 'TAP::Object';
-$VERSION = '3.21';
+$VERSION = '3.22';
# TODO:
# Handle blessed object syntax
=head1 VERSION
-Version 3.21
+Version 3.22
=head1 SYNOPSIS
use TAP::Object ();
@ISA = 'TAP::Object';
-$VERSION = '3.21';
+$VERSION = '3.22';
my $ESCAPE_CHAR = qr{ [ \x00-\x1f \" ] }x;
my $ESCAPE_KEY = qr{ (?: ^\W ) | $ESCAPE_CHAR }x;
=head1 VERSION
-Version 3.21
+Version 3.22
=head1 SYNOPSIS
=head1 VERSION
-Version 3.21
+Version 3.22
=cut
-$VERSION = '3.21';
+$VERSION = '3.22';
# Backwards compatibility for exportable variable names.
*verbose = *Verbose;
_aggregate_tests( $harness, $aggregate, @tests );
}
-# Make sure the child seens all the extra junk in @INC
+# Make sure the child sees all the extra junk in @INC
sub _apply_extra_INC {
my $harness = shift;
use Test::More (
$^O eq 'VMS' ? ( skip_all => 'VMS' )
: has_crazy_patch() ? ( skip_all => 'Incompatible @INC patch' )
+ : exists $ENV{HARNESS_PERL_SWITCHES}
+ ? ( skip_all => 'Someone messed with HARNESS_PERL_SWITCHES' )
: ( tests => 2 )
);
#!/usr/bin/perl -w
BEGIN {
- use lib 't/lib';
+ use lib 't/lib';
}
use strict;
tie *NULL, 'Dev::Null' or die $!;
select NULL;
- my ( $tot, $failed ) = Test::Harness::execute_tests(
- tests => [
- 't/sample-tests/inc_taint'
- ]
- );
+ my ( $tot, $failed )
+ = Test::Harness::execute_tests( tests => ['t/sample-tests/inc_taint'] );
select STDOUT;
ok( _all_ok($tot), 'tests with taint on preserve @INC' );
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
# unset this global when self-testing ('testcover' and etc issue)
local $ENV{HARNESS_PERL_SWITCHES};
-my $TEST_DIR
- = 't/sample-tests';
+my $TEST_DIR = 't/sample-tests';
{
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
my $HARNESS = 'TAP::Harness';
-my $source_tests
- = 't/source_tests';
-my $sample_tests
- = 't/sample-tests';
+my $source_tests = 't/source_tests';
+my $sample_tests = 't/sample-tests';
plan tests => 56;
my $status = pop @output;
my $expected_status = qr{^Result: PASS$};
my $summary = pop @output;
- my $expected_summary = qr{^Files=1, Tests=1, \d+ wallclock secs};
+ my $expected_summary = qr{^Files=1, Tests=1, +\d+ wallclock secs};
is_deeply \@output, \@expected, '... the output should be correct';
like $status, $expected_status,
$status = pop @output;
$expected_status = qr{^Result: PASS$};
$summary = pop @output;
- $expected_summary = qr{^Files=1, Tests=1, \d+ wallclock secs};
+ $expected_summary = qr{^Files=1, Tests=1, +\d+ wallclock secs};
is_deeply \@output, \@expected, '... the output should be correct';
like $status, $expected_status,
$status = pop @output;
$expected_status = qr{^Result: PASS$};
$summary = pop @output;
- $expected_summary = qr{^Files=2, Tests=2, \d+ wallclock secs};
+ $expected_summary = qr{^Files=2, Tests=2, +\d+ wallclock secs};
is_deeply \@output, \@expected, '... the output should be correct';
like $status, $expected_status,
$status = pop @output;
$expected_status = qr{^Result: PASS$};
$summary = pop @output;
- $expected_summary = qr/^Files=1, Tests=1, \d+ wallclock secs/;
+ $expected_summary = qr/^Files=1, Tests=1, +\d+ wallclock secs/;
is_deeply \@output, \@expected, '... the output should be correct';
like $status, $expected_status,
$status = pop @output;
$expected_status = qr{^Result: PASS$};
$summary = pop @output;
- $expected_summary = qr/^Files=1, Tests=1, \d+ wallclock secs/;
+ $expected_summary = qr/^Files=1, Tests=1, +\d+ wallclock secs/;
is_deeply \@output, \@expected, '... the output should be correct';
like $status, $expected_status,
$status = pop @output;
$summary = pop @output;
- $expected_summary = qr/^Files=1, Tests=3, \d+ wallclock secs/;
+ $expected_summary = qr/^Files=1, Tests=3, +\d+ wallclock secs/;
is_deeply \@output, \@expected, '... the output should be correct';
like $summary, $expected_summary,
$summary = pop @output;
like $status, qr{^Result: FAIL$}, '... the status line should be correct';
- $expected_summary = qr/^Files=1, Tests=2, \d+ wallclock secs/;
+ $expected_summary = qr/^Files=1, Tests=2, +\d+ wallclock secs/;
is_deeply \@output, \@expected, '... and the output should be correct';
# check the status output for no tests
$summary = pop @output;
like $status, qr{^Result: FAIL$}, '... the status line should be correct';
- $expected_summary = qr/^Files=1, Tests=2, \d+ wallclock secs/;
+ $expected_summary = qr/^Files=1, Tests=2, +\d+ wallclock secs/;
is_deeply \@output, \@expected, '... and the output should be correct';
# coverage testing for _should_show_comments
$summary = pop @output;
like $status, qr{^Result: FAIL$}, '... the status line should be correct';
- $expected_summary = qr/^Files=1, Tests=2, \d+ wallclock secs/;
+ $expected_summary = qr/^Files=1, Tests=2, +\d+ wallclock secs/;
is_deeply \@output, \@expected, '... and the output should be correct';
# coverage testing for _should_show_comments and _should_show_failures
$summary = pop @output;
like $status, qr{^Result: FAIL$}, '... the status line should be correct';
- $expected_summary = qr/^Files=1, Tests=2, \d+ wallclock secs/;
+ $expected_summary = qr/^Files=1, Tests=2, +\d+ wallclock secs/;
is_deeply \@output, \@expected, '... and the output should be correct';
#XXXX
use strict;
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use Test::More tests => 94;
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
my $HARNESS = 'TAP::Harness';
-my $source_tests
- = 't/source_tests';
-my $sample_tests
- = 't/sample-tests';
+my $source_tests = 't/source_tests';
+my $sample_tests = 't/sample-tests';
plan tests => 128;
my $status = pop @output;
my $expected_status = qr{^Result: PASS$};
my $summary = pop @output;
- my $expected_summary = qr{^Files=1, Tests=1, \d+ wallclock secs};
+ my $expected_summary = qr{^Files=1, Tests=1, +\d+ wallclock secs};
is_deeply \@output, \@expected, '... and the output should be correct';
like $status, $expected_status,
$status = pop @output;
$expected_status = qr{^Result: PASS$};
$summary = pop @output;
- $expected_summary = qr{^Files=1, Tests=1, \d+ wallclock secs};
+ $expected_summary = qr{^Files=1, Tests=1, +\d+ wallclock secs};
is_deeply \@output, \@expected, '... and the output should be correct';
like $status, $expected_status,
$status = pop @output;
$expected_status = qr{^Result: PASS$};
$summary = pop @output;
- $expected_summary = qr{^Files=2, Tests=2, \d+ wallclock secs};
+ $expected_summary = qr{^Files=2, Tests=2, +\d+ wallclock secs};
is_deeply \@output, \@expected, '... and the output should be correct';
like $status, $expected_status,
$status = pop @output;
$expected_status = qr{^Result: PASS$};
$summary = pop @output;
- $expected_summary = qr/^Files=1, Tests=1, \d+ wallclock secs/;
+ $expected_summary = qr/^Files=1, Tests=1, +\d+ wallclock secs/;
is_deeply \@output, \@expected, '... and the output should be correct';
like $status, $expected_status,
$status = pop @output;
$expected_status = qr{^Result: PASS$};
$summary = pop @output;
- $expected_summary = qr/^Files=1, Tests=1, \d+ wallclock secs/;
+ $expected_summary = qr/^Files=1, Tests=1, +\d+ wallclock secs/;
is_deeply \@output, \@expected, '... and the output should be correct';
like $status, $expected_status,
$status = pop @output;
$summary = pop @output;
- $expected_summary = qr/^Files=1, Tests=3, \d+ wallclock secs/;
+ $expected_summary = qr/^Files=1, Tests=3, +\d+ wallclock secs/;
is_deeply \@output, \@expected, '... and the output should be correct';
like $summary, $expected_summary,
like $status, qr{^Result: FAIL$},
'... and the status line should be correct';
- $expected_summary = qr/^Files=1, Tests=2, \d+ wallclock secs/;
+ $expected_summary = qr/^Files=1, Tests=2, +\d+ wallclock secs/;
is_deeply \@output, \@expected, '... and the output should be correct';
# check the status output for no tests
like $status, qr{^Result: FAIL$},
'... and the status line should be correct';
- $expected_summary = qr/^Files=1, Tests=2, \d+ wallclock secs/;
+ $expected_summary = qr/^Files=1, Tests=2, +\d+ wallclock secs/;
is_deeply \@output, \@expected, '... and the output should be correct';
#XXXX
}
);
- eval {
- _runtests(
- $harness,
- 't/data/catme.1'
- );
- };
+ eval { _runtests( $harness, 't/data/catme.1' ); };
my @output = tied($$capture)->dump;
my $status = pop @output;
{ verbosity => -2,
stdout => $capture,
exec => sub {
- open my $fh,
- 't/data/catme.1';
+ open my $fh, 't/data/catme.1';
return $fh;
},
}
# coverage tests for the basically untested T::H::_open_spool
- my @spool = (
- 't', 'spool'
- );
+ my @spool = ( 't', 'spool' );
$ENV{PERL_TEST_HARNESS_DUMP_TAP} = File::Spec->catfile(@spool);
# now given that we're going to be writing stuff to the file system, make sure we have
##
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
iterator => 'TAP::Parser::Iterator::Process',
},
{ file => 'source.sh',
- handler => 'TAP::Parser::SourceHandler::Executable',
+ handler => 'TAP::Parser::SourceHandler::Perl',
iterator => 'TAP::Parser::Iterator::Process',
},
{ file => 'source.bat',
+++ /dev/null
-package MyShebangger;
-
-use strict;
-use warnings;
-
-use Config;
-
-=head1 NAME
-
-MyShebangger - Encapsulate EUMM / MB shebang magic
-
-=item fix_shebang
-
- fix_shebang($file_in, $file_out);
-
-Inserts the sharpbang or equivalent magic number at the start of a file.
-
-=cut
-
-# stolen from ExtUtils::MakeMaker which said:
-# stolen from the pink Camel book, more or less
-sub fix_shebang {
- my ( $file_in, $file_out ) = @_;
-
- my ($does_shbang) = $Config{'sharpbang'} =~ /^\s*\#\!/;
-
- open my $fixin, '<', $file_in or die "Can't process '$file_in': $!";
- local $/ = "\n";
- chomp( my $line = <$fixin> );
-
- die "$file_in doesn't have a shebang line"
- unless $line =~ s/^\s*\#!\s*//;
-
- # Now figure out the interpreter name.
- my ( $cmd, $arg ) = split ' ', $line, 2;
- $cmd =~ s!^.*/!!;
-
- my $interpreter;
-
- die "$file_in is not perl"
- unless $cmd =~ m{^perl(?:\z|[^a-z])};
-
- if ($ENV{PERL_CORE}) {
- $interpreter = $^X;
- }
- elsif ( $Config{startperl} =~ m,^\#!.*/perl, ) {
- $interpreter = $Config{startperl};
- $interpreter =~ s,^\#!,,;
- }
- else {
- $interpreter = $Config{perlpath};
- }
-
- die "Can't figure out which interpreter to use."
- unless defined $interpreter;
-
- # Figure out how to invoke interpreter on this machine.
- my $shb = '';
-
- # this is probably value-free on DOSISH platforms
- my $shb_line = join ' ', grep defined, $interpreter, $arg;
- $shb .= "$Config{'sharpbang'}$shb_line\n"
- if $does_shbang;
- $shb .= qq{
-eval 'exec $shb_line -S \$0 \${1+"\$\@"}'
- if 0; # not running under some shell
-} unless $^O eq 'MSWin32'; # this won't work on win32, so don't
-
- open my $fixout, ">", "$file_out"
- or die "Can't create new $file_out: $!\n";
-
- # Print out the new #! line (or equivalent).
- local $\;
- local $/;
- print $fixout $shb, <$fixin>;
- close $fixin;
- close $fixout;
-
- system("$Config{'eunicefix'} $file_out") if $Config{'eunicefix'} ne ':';
- chmod 0755, $file_out; # ignore failure
-}
-
-{
- my @cleanup = ();
- my $seq = 1;
- END { unlink @cleanup }
-
- sub make_perl_executable {
- my $file = shift;
- my $tmp_file = "${file}_${$}_$seq.pl";
- $seq++;
- fix_shebang( $file, $tmp_file );
- push @cleanup, $tmp_file;
- return $tmp_file;
- }
-}
-1;
--- /dev/null
+#!/usr/bin/perl -wT
+
+use strict;
+use lib 't/lib';
+
+use Test::More tests => 5;
+
+use TAP::Parser;
+
+my $tap = <<'END_TAP';
+1..2
+ok 1 - input file opened
+... this is junk
+ Bail out! We ran out of foobar.
+END_TAP
+my $parser = TAP::Parser->new( { tap => $tap } );
+isa_ok $parser, 'TAP::Parser',
+ '... we should be able to parse bailed out tests';
+
+my @results;
+while ( my $result = $parser->next ) {
+ push @results => $result;
+}
+my $bailout = pop @results;
+ok $bailout->is_bailout, 'We should be able to parse a nested bailout';
+is $bailout->as_string, 'We ran out of foobar.',
+ '... and as_string() should return the explanation';
+is $bailout->raw, ' Bail out! We ran out of foobar.',
+ '... and raw() should return the explanation';
+is $bailout->explanation, 'We ran out of foobar.',
+ '... and it should have the correct explanation';
#!/usr/bin/perl -w
BEGIN {
- use lib 't/lib';
+ use lib 't/lib';
}
use strict;
use NoFork;
-require(
- 't/multiplexer.t' );
+require('t/multiplexer.t');
# NOTE maybe a good candidate for xt/author or something.
BEGIN {
- use lib 't/lib';
+ use lib 't/lib';
}
use strict;
stdout => $capture,
}
);
- $harness->runtests(
- 't/sample-tests/simple' );
+ $harness->runtests('t/sample-tests/simple');
my @output = tied($$capture)->dump;
is pop @output, "Result: PASS\n", 'status OK';
- pop @output; # get rid of summary line
+ pop @output; # get rid of summary line
is( $output[-1], "All tests successful.\n", 'ran with no fork' );
}
use strict;
BEGIN {
- use lib 't/lib';
+ use lib 't/lib';
}
use Test::More tests => 294;
# Check source => $filehandle
can_ok $PARSER, 'new';
-open my $fh,
- 't/data/catme.1';
+open my $fh, 't/data/catme.1';
$parser = $PARSER->new( { source => $fh } );
isa_ok $parser, $PARSER, '... and calling it should succeed';
ok @results = _get_results($parser), 'The parser should return results';
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
use_ok('MyGrammar');
use_ok('MyResultFactory');
-my @t_path = ();
-my $source = catfile( @t_path, 't', 'source_tests', 'source' );
+my @t_path = ();
+my $source = catfile( @t_path, 't', 'source_tests', 'source' );
my %customize = (
grammar_class => 'MyGrammar',
result_factory_class => 'MyResultFactory',
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
use App::Prove;
use Getopt::Long;
+use TAP::Parser::Utils qw( split_shell );
+
package FakeProve;
use vars qw( @ISA );
# list of attributes
@ATTR = qw(
- archive argv blib color directives exec extension failures
+ archive argv blib color directives exec extensions failures
formatter harness includes lib merge parse quiet really_quiet
recurse backwards shuffle taint_fail taint_warn verbose
warnings_fail warnings_warn
args => {
argv => [qw( one two three )],
},
- proverc => 't/proverc/emptyexec',
+ proverc => 't/proverc/emptyexec',
switches => [$dummy_test],
expect => { exec => '' },
runlog => [
],
},
+ # Specify an oddball extension
+ { name => 'Switch --ext=.wango',
+ switches => [ '--ext=.wango' ],
+ expect => { extensions => ['.wango'] },
+ runlog => [
+ [ '_runtests',
+ { verbosity => 0,
+ show_count => 1,
+ },
+ 'TAP::Harness',
+ ]
+ ],
+ },
+
+ # Handle multiple extensions
+ { name => 'Switch --ext=.foo --ext=.bar',
+ switches => [ '--ext=.foo', '--ext=.bar', ],
+ expect => { extensions => ['.foo','.bar'] },
+ runlog => [
+ [ '_runtests',
+ { verbosity => 0,
+ show_count => 1,
+ },
+ 'TAP::Harness',
+ ]
+ ],
+ },
+
# Source handlers
{ name => 'Switch --source simple',
args => { argv => [qw( one two three )] },
'--source', 'File',
'--file-option', 'extensions=.txt',
'--file-option', 'extensions=.tmp',
+ '--file-option', 'hash=this=that',
+ '--file-option', 'hash=foo=bar',
+ '--file-option', 'sep=foo\\=bar',
$dummy_test
],
expect => {
sources => {
Perl => { foo => 'bar baz', avg => 0.278 },
MyCustom => {},
- File => { extensions => [ '.txt', '.tmp' ] },
+ File => {
+ extensions => [ '.txt', '.tmp' ],
+ hash => { this => 'that', foo => 'bar'},
+ sep => 'foo=bar',
+ },
},
},
runlog => [
{ sources => {
Perl => { foo => 'bar baz', avg => 0.278 },
MyCustom => {},
- File => { extensions => [ '.txt', '.tmp' ] },
+ File => {
+ extensions => [ '.txt', '.tmp' ],
+ hash => { this => 'that', foo => 'bar'},
+ sep => 'foo=bar',
+ },
},
verbosity => 0,
show_count => 1,
$extra->($gotlog);
}
+ # adapt our expectations if HARNESS_PERL_SWITCHES is set
+ push @{ $runlog->[0][1]{switches} },
+ split_shell( $ENV{HARNESS_PERL_SWITCHES} )
+ if $ENV{HARNESS_PERL_SWITCHES};
+
unless (
is_deeply $gotlog, $runlog,
"$name: run results match"
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
use Test::More;
use File::Spec;
use App::Prove;
+use TAP::Parser::Utils qw( split_shell );
my @SCHEDULE;
BEGIN {
- my $t_dir = File::Spec->catdir(
- 't'
- );
+ my $t_dir = File::Spec->catdir('t');
# to add a new test to proverun, just list the name of the file in
# t/sample-tests and a name for the test. The rest is handled
{ merge => undef,
command => [
'PERL',
+ $ENV{HARNESS_PERL_SWITCHES}
+ ? split_shell( $ENV{HARNESS_PERL_SWITCHES} )
+ : (),
$_->{file},
],
setup => \'CODE',
--- /dev/null
+#!/usr/bin/perl -w
+
+BEGIN {
+ unshift @INC, 't/lib';
+}
+
+sub _has_TAP_Formatter_HTML {
+ eval "use TAP::Formatter::HTML";
+ return $@ ? 0 : 1;
+}
+
+use strict;
+use Test::More tests => 1;
+use IO::c55Capture; # for util
+
+SKIP: {
+ skip "requires TAP::Formatter::HTML", 1 unless _has_TAP_Formatter_HTML();
+
+ my $ans = util::stdout_of(
+ sub {
+ system( $^X,
+ "bin/prove",
+ "-l",
+ "--formatter=TAP::Formatter::HTML",
+ "--tapversion=13",
+ "t/sample-tests/simple_yaml_missing_version13"
+ ) and die "error $?";
+ }
+ );
+ like(
+ $ans, qr/li class="yml"/,
+ "prove --tapversion=13 simple_yaml_missing_version13"
+ );
+}
#!/usr/bin/perl -w
BEGIN {
- push @INC, 't/lib';
+ push @INC, 't/lib';
}
use strict;
wait => 0,
version => 12,
},
+ yaml_late_plan => {
+ results => [
+ { is_version => TRUE,
+ raw => 'TAP version 13',
+ },
+ { actual_passed => TRUE,
+ is_actual_ok => TRUE,
+ passed => TRUE,
+ is_ok => TRUE,
+ is_test => TRUE,
+ has_skip => FALSE,
+ has_todo => FALSE,
+ number => 1,
+ description => "- test suite started",
+ },
+ { actual_passed => TRUE,
+ is_actual_ok => TRUE,
+ passed => TRUE,
+ is_ok => TRUE,
+ is_test => TRUE,
+ has_skip => FALSE,
+ has_todo => FALSE,
+ number => 2,
+ description => "- bogomips",
+ },
+ { is_yaml => TRUE,
+ data => { 'Bogomips' => '5226.88' },
+ raw =>
+ " ---\n Bogomips: 5226.88\n ...",
+ },
+ { actual_passed => TRUE,
+ is_actual_ok => TRUE,
+ passed => TRUE,
+ is_ok => TRUE,
+ is_test => TRUE,
+ has_skip => FALSE,
+ has_todo => FALSE,
+ number => 3,
+ description => "- test suite finished",
+ },
+ { is_plan => TRUE,
+ raw => '1..3',
+ tests_planned => 3,
+ passed => TRUE,
+ is_ok => TRUE,
+ },
+ ],
+ plan => '1..3',
+ passed => [ 1 .. 3 ],
+ actual_passed => [ 1 .. 3 ],
+ failed => [],
+ actual_failed => [],
+ todo => [],
+ todo_passed => [],
+ skipped => [],
+ good_plan => TRUE,
+ is_good_plan => TRUE,
+ tests_planned => 3,
+ tests_run => 3,
+ parse_errors => [],
+ 'exit' => 0,
+ wait => 0,
+ version => 13,
+ },
);
my %HANDLER_FOR = (
--- /dev/null
+print <<DUMMY_TEST;
+1..5
+ok 1
+ok 2
+ ---
+ -
+ fnurk: skib
+ ponk: gleeb
+ -
+ bar: krup
+ foo: plink
+ ...
+ok 3
+ok 4
+ ---
+ expected:
+ - 1
+ - 2
+ - 4
+ got:
+ - 1
+ - pong
+ - 4
+ ...
+ok 5
+DUMMY_TEST
--- /dev/null
+print <<DUMMY_TEST;
+TAP version 13
+ok - test suite started
+ok - bogomips
+ ---
+ Bogomips: 5226.88
+ ...
+ok - test suite finished
+1..3
+DUMMY_TEST
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
use_ok('TAP::Parser::Source');
+sub ct($) {
+ my $hash = shift;
+ if ( $ENV{PERL_CORE} ) {
+ delete $hash->{is_symlink};
+ delete $hash->{lstat};
+ }
+ return $hash;
+}
+
# Basic tests
{
my $source = TAP::Parser::Source->new;
# separate meta->file to break up the test
my $file = delete $meta->{file};
is_deeply(
- $meta,
- { is_scalar => 1,
+ ct $meta,
+ ct {is_scalar => 1,
has_newlines => 0,
length => length($test),
is_object => 0,
isnt( delete $file->{write}, undef, '... file->write set' );
isnt( delete $file->{execute}, undef, '... file->execute set' );
is_deeply(
- $file,
- { basename => 'source.t',
+ ct $file,
+ ct {basename => 'source.t',
ext => '.t',
lc_ext => '.t',
shebang => '#!/usr/bin/perl',
is_dir => 0,
is_file => 1,
is_symlink => 0,
- sticky => 0,
- setgid => 0,
- setuid => 0,
+ # Fix for bizarre -k bug in Strawberry Perl
+ sticky => ( -k $test )[-1] ? 1 : 0,
+ setgid => -g $test ? 1 : 0,
+ setuid => -u $test ? 1 : 0,
},
'... file->* set'
);
# dir test
{
- my $test = File::Spec->catfile($dir);
+ my $test = $dir;
my $source = TAP::Parser::Source->new;
$source->raw( \$test );
# separate meta->file to break up the test
my $file = delete $meta->{file};
is_deeply(
- $meta,
- { is_scalar => 1,
+ ct $meta,
+ ct {is_scalar => 1,
has_newlines => 0,
length => length($test),
is_object => 0,
isnt( delete $file->{write}, undef, '... file->write set' );
isnt( delete $file->{execute}, undef, '... file->execute set' );
is_deeply(
- $file,
- { basename => 'source_tests',
+ ct $file,
+ ct {basename => 'source_tests',
ext => '',
lc_ext => '',
text => 0,
is_dir => 1,
is_file => 0,
is_symlink => 0,
- sticky => 0,
- setgid => 0,
- setuid => 0,
+ sticky => ( -k $test )[-1] ? 1 : 0,
+ setgid => -g $test ? 1 : 0,
+ setuid => -u $test ? 1 : 0,
},
'... file->* set'
);
# separate meta->file to break up the test
my $file = delete $meta->{file};
is_deeply(
- $meta,
- { is_scalar => 1,
+ ct $meta,
+ ct {is_scalar => 1,
has_newlines => 0,
length => length($symlink),
is_object => 0,
isnt( delete $file->{write}, undef, '... file->write set' );
isnt( delete $file->{execute}, undef, '... file->execute set' );
is_deeply(
- $file,
- { basename => 'source_link.T',
+ ct $file,
+ ct {basename => 'source_link.T',
ext => '.T',
lc_ext => '.t',
shebang => '#!/usr/bin/perl',
is_dir => 0,
is_file => 1,
is_symlink => 1,
- sticky => 0,
- setgid => 0,
- setuid => 0,
+ sticky => ( -k $symlink )[-1] ? 1 : 0,
+ setgid => -g $symlink ? 1 : 0,
+ setuid => -u $symlink ? 1 : 0,
},
'... file->* set'
);
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
-use Test::More tests => 123;
+use Test::More tests => 79;
use IO::File;
use IO::Handle;
use File::Spec;
-use MyShebangger;
use TAP::Parser::Source;
use TAP::Parser::SourceHandler;
my $perl = $^X;
my %file = map { $_ => File::Spec->catfile( $dir, $_ ) }
- qw( source source.1 source.bat source.pl source.sh source.t source.tap );
+ qw( source source.1 source.bat source.pl source.sh source_args.sh source.t
+ source.tap );
# Abstract base class tests
{
is_file => 1,
file => { lc_ext => '.sh' }
},
- vote => 0.8,
+ vote => 0,
},
{ name => '.bat',
meta => {
is_file => 1,
file => { lc_ext => '', execute => 1 }
},
- vote => 0.7,
+ vote => 0.25,
},
{ name => 'exec hash',
raw => { exec => 'foo' },
},
],
make_iterator => [
- { name => "valid executable",
- raw => [ $perl, ($ENV{PERL_CORE} ? '-I../../lib' : ()), '-It/lib', '-T', $file{source} ],
- iclass => 'TAP::Parser::Iterator::Process',
+ { name => "valid executable",
+ raw => [
+ $perl, ( $ENV{PERL_CORE} ? '-I../../lib' : () ),
+ '-It/lib', '-T', $file{source}
+ ],
+ iclass => 'TAP::Parser::Iterator::Process',
output => [ '1..1', 'ok 1 - source' ],
assemble_meta => 1,
},
output => [ '1..1', 'ok 1 - source.sh' ],
assemble_meta => 1,
},
+ { name => $file{'source_args.sh'},
+ raw => { exec => [ $file{'source_args.sh'} ] },
+ test_args => [ 'foo' ],
+ skip => $HAS_SH && $HAS_ECHO ? 0 : 1,
+ skip_reason => 'no /bin/sh, /bin/echo',
+ iclass => 'TAP::Parser::Iterator::Process',
+ output => [ '1..1', 'ok 1 - source_args.sh foo' ],
+ assemble_meta => 1,
+ },
{ name => $file{'source.bat'},
raw => \$file{'source.bat'},
skip => $IS_WIN32 ? 0 : 1,
test_handler( $class, $tests );
}
-# pgTAP source tests
-{
- my $class = 'TAP::Parser::SourceHandler::pgTAP';
- my $test = File::Spec->catfile( $dir, 'source.t' );
- my $psql = File::Spec->catfile( $dir, 'psql' );
- if ( $^O eq 'MSWin32' ) {
- $psql .= '.bat';
- }
- else {
- $psql = MyShebangger::make_perl_executable($psql);
- }
- my @command = qw(
- --no-psqlrc
- --no-align
- --quiet
- --pset pager=
- --pset tuples_only=true
- --set ON_ERROR_ROLLBACK=1
- --set ON_ERROR_STOP=1
- );
- my $tests = {
- default_vote => 0,
- can_handle => [
- { name => '.pg',
- meta => {
- is_file => 1,
- file => { lc_ext => '.pg' }
- },
- config => {},
- vote => 0.9,
- },
- { name => '.sql',
- meta => {
- is_file => 1,
- file => { lc_ext => '.sql' }
- },
- config => {},
- vote => 0.8,
- },
- { name => '.s',
- meta => {
- is_file => 1,
- file => { lc_ext => '.s' }
- },
- config => {},
- vote => 0.75,
- },
- { name => 'config_suffix',
- meta => {
- is_file => 1,
- file => { lc_ext => '.foo' }
- },
- config => { pgTAP => { suffix => '.foo' } },
- vote => 1,
- },
- { name => 'not_file',
- meta => {
- is_file => 0,
- },
- vote => 0,
- },
- ],
- make_iterator => [
- { name => 'psql',
- raw => \$test,
- config => { pgTAP => { psql => $psql } },
- iclass => 'TAP::Parser::Iterator::Process',
- output => [ @command, '--file', $test ],
- },
- { name => 'config',
- raw => $test,
- config => {
- pgTAP => {
- psql => $psql,
- username => 'who',
- host => 'f',
- port => 2,
- dbname => 'fred',
- }
- },
- iclass => 'TAP::Parser::Iterator::Process',
- output => [
- @command,
- qw(--username who --host f --port 2 --dbname fred --file),
- $test
- ],
- },
- { name => 'error',
- raw => 'blah.pg',
- iclass => 'TAP::Parser::Iterator::Process',
- error => qr/^No such file or directory: blah[.]pg/,
- },
- { name => 'undef error',
- raw => undef,
- iclass => 'TAP::Parser::Iterator::Process',
- error => qr/^No such file or directory: /,
- },
- ],
- };
-
- test_handler( $class, $tests );
-}
-
-exit;
-
###############################################################################
# helper sub
my $source = TAP::Parser::Source->new;
$source->raw( $test->{raw} ) if $test->{raw};
+ $source->test_args( $test->{test_args} ) if $test->{test_args};
$source->meta( $test->{meta} ) if $test->{meta};
$source->config( $test->{config} ) if $test->{config};
$source->assemble_meta if $test->{assemble_meta};
+++ /dev/null
-#!/usr/bin/perl
-
-print $_, $/ for @ARGV;
@rem = '--*-Perl-*--
@echo off
-if (%PERL_CORE%)==() set PERL_CORE=perl
-if not exist %PERL_CORE% set PERL_CORE=perl
if "%OS%" == "Windows_NT" goto WinNT
-%PERL_CORE% -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
+perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
goto endofperl
:WinNT
-%PERL_CORE% -x -S %0 %*
+perl -x -S %0 %*
if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl
if %errorlevel% == 9009 echo You do not have Perl in your PATH.
if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul
--- /dev/null
+#!/bin/sh
+echo "1..1"
+echo "ok 1 - source_args.sh $1"
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
# test T::H::_open_spool and _close_spool - these are good examples
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
use strict;
#!/usr/bin/perl -w
BEGIN {
- unshift @INC, 't/lib';
+ unshift @INC, 't/lib';
}
# Test that options in PERL5OPT are propogated to tainted tests
}
{
- local $ENV{PERL5OPT} = $ENV{PERL_CORE} ? '-I../../lib -Mstrict' : '-Mstrict';
+ local $ENV{PERL5OPT}
+ = $ENV{PERL_CORE} ? '-I../../lib -Mstrict' : '-Mstrict';
run_test_file(<<'END');
#!/usr/bin/perl -T
use strict;
use lib 't/lib';
-use Test::More tests => 21;
+use Test::More;
use File::Spec;
use TAP::Parser;
use TAP::Harness;
use App::Prove;
+diag( "\n\n", bigness( join ' ', @ARGV ), "\n\n" ) if @ARGV;
+
+my @cleanup = ();
+END { unlink @cleanup }
+
my $test = File::Spec->catfile(
't',
'sample-tests',
'echo'
);
-diag( "\n\n", bigness( join ' ', @ARGV ), "\n\n" ) if @ARGV;
+my @test = ( [ perl => $test ], make_shell_test($test) );
+
+plan tests => @test * 8 + 5;
sub echo_ok {
- my $options = shift;
- my @args = @_;
- my $parser = TAP::Parser->new( { %$options, test_args => \@args } );
- my @got = ();
+ my ( $type, $options ) = ( shift, shift );
+ my $name = join( ', ', sort keys %$options ) . ", $type";
+ my @args = @_;
+ my $parser = TAP::Parser->new( { %$options, test_args => \@args } );
+ my @got = ();
while ( my $result = $parser->next ) {
push @got, $result;
}
my $plan = shift @got;
- ok $plan->is_plan;
- for (@got) {
- is $_->description, shift(@args),
- join( ', ', keys %$options ) . ": option passed OK";
+ ok $plan->is_plan, "$name: is_plan";
+ is_deeply [ map { $_->description } @got ], [@args],
+ "$name: option passed OK";
+}
+
+for my $t (@test) {
+ my ( $type, $test ) = @$t;
+ for my $args ( [qw( yes no maybe )], [qw( 1 2 3 )] ) {
+ echo_ok( $type, { source => $test }, @$args );
+ echo_ok( $type, { exec => [ $^X, $test ] }, @$args );
}
}
-for my $args ( [qw( yes no maybe )], [qw( 1 2 3 )] ) {
- echo_ok( { source => $test }, @$args );
- echo_ok( { exec => [ $^X, $test ] }, @$args );
+sub make_shell_test {
+ my $test = shift;
+ my $shell = '/bin/sh';
+ return unless -x $shell;
+ my $script = "shell_$$.sh";
+
+ push @cleanup, $script;
+ {
+ open my $sh, '>', $script;
+ print $sh "#!$shell\n\n";
+ print $sh "$^X '$test' \$*\n";
+ }
+ chmod 0777, $script;
+ return unless -x $script;
+ return [ shell => $script ];
}
{