summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlperl/lib/TAP/Harness.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlperl/lib/TAP/Harness.pm')
-rw-r--r--Master/tlpkg/tlperl/lib/TAP/Harness.pm283
1 files changed, 217 insertions, 66 deletions
diff --git a/Master/tlpkg/tlperl/lib/TAP/Harness.pm b/Master/tlpkg/tlperl/lib/TAP/Harness.pm
index 749e7af4166..2c663ae0204 100644
--- a/Master/tlpkg/tlperl/lib/TAP/Harness.pm
+++ b/Master/tlpkg/tlperl/lib/TAP/Harness.pm
@@ -19,11 +19,11 @@ TAP::Harness - Run test scripts with statistics
=head1 VERSION
-Version 3.17
+Version 3.23
=cut
-$VERSION = '3.17';
+$VERSION = '3.23';
$ENV{HARNESS_ACTIVE} = 1;
$ENV{HARNESS_VERSION} = $VERSION;
@@ -84,6 +84,9 @@ BEGIN {
test_args => sub { shift; shift },
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 ) {
@@ -192,6 +195,16 @@ only makes sense in the context of tests written in Perl.
A reference to an C<@INC> style array of arguments to be passed to each
test program.
+ test_args => ['foo', 'bar'],
+
+if you want to pass different arguments to each test then you should
+pass a hash of arrays, keyed by the alias for each test:
+
+ test_args => {
+ my_test => ['foo', 'bar'],
+ other_test => ['baz'],
+ }
+
=item * C<color>
Attempt to produce color output.
@@ -229,11 +242,41 @@ will be interpreted as raw TAP or as a TAP stream, respectively.
If C<merge> is true the harness will create parsers that merge STDOUT
and STDERR together for any processes they start.
+=item * C<sources>
+
+I<NEW to 3.18>.
+
+If set, C<sources> must be a hashref containing the names of the
+L<TAP::Parser::SourceHandler>s to load and/or configure. The values are a
+hash of configuration that will be accessible to to the source handlers via
+L<TAP::Parser::Source/config_for>.
+
+For example:
+
+ sources => {
+ Perl => { exec => '/path/to/custom/perl' },
+ File => { extensions => [ '.tap', '.txt' ] },
+ MyCustom => { some => 'config' },
+ }
+
+The C<sources> parameter affects how C<source>, C<tap> and C<exec> parameters
+are handled.
+
+For more details, see the C<sources> parameter in L<TAP::Parser/new>,
+L<TAP::Parser::Source>, and L<TAP::Parser::IteratorFactory>.
+
=item * C<aggregator_class>
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
@@ -306,6 +349,11 @@ interface may change.
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.
@@ -393,7 +441,7 @@ Any keys for which the value is C<undef> will be ignored.
$harness->runtests(@tests);
-Accepts and array of C<@tests> to be run. This should generally be the
+Accepts an array of C<@tests> to be run. This should generally be the
names of test files, but this is not required. Each element in C<@tests>
will be passed to C<TAP::Parser::new()> as a C<source>. See
L<TAP::Parser> for more information.
@@ -427,23 +475,43 @@ sub runtests {
$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;
}
=head3 C<summary>
-Output the summary for a TAP::Parser::Aggregator.
+ $harness->summary( $aggregator );
+
+Output the summary for a L<TAP::Parser::Aggregator>.
=cut
sub summary {
- my ( $self, $aggregate ) = @_;
- $self->formatter->summary($aggregate);
+ my ( $self, @args ) = @_;
+ $self->formatter->summary(@args);
}
sub _after_test {
@@ -533,7 +601,7 @@ sub _aggregate_single {
$harness->aggregate_tests( $aggregate, @tests );
Run the named tests and display a summary of result. Tests will be run
-in the order found.
+in the order found.
Test results will be added to the supplied L<TAP::Parser::Aggregator>.
C<aggregate_tests> may be called multiple times to run several sets of
@@ -561,20 +629,23 @@ are unsuitable for parallel execution.
Note that for simpler testing requirements it will often be possible to
replace the above code with a single call to C<runtests>.
-Each elements of the @tests array is either
+Each element of the C<@tests> array is either:
=over
-=item * the file name of a test script to run
+=item * the source name of a test to run
-=item * a reference to a [ file name, display name ] array
+=item * a reference to a [ source name, display name ] array
=back
+In the case of a perl test suite, typically I<source names> are simply the file
+names of the test scripts to run.
+
When you supply a separate display name it becomes possible to run a
test more than once; the display name is effectively the alias by which
the test is known inside the harness. The harness doesn't care if it
-runs the same script more than once when each invocation uses a
+runs the same test more than once when each invocation uses a
different name.
=cut
@@ -639,59 +710,13 @@ should be set higher.
##############################################################################
-=head1 SUBCLASSING
-
-C<TAP::Harness> is designed to be (mostly) easy to subclass. If you
-don't like how a particular feature functions, just override the
-desired methods.
-
-=head2 Methods
-
-TODO: This is out of date
-
-The following methods are ones you may wish to override if you want to
-subclass C<TAP::Harness>.
-
-=head3 C<summary>
-
- $harness->summary( \%args );
-
-C<summary> prints the summary report after all tests are run. The
-argument is a hashref with the following keys:
-
-=over 4
-
-=item * C<start>
-
-This is created with C<< Benchmark->new >> and it the time the tests
-started. You can print a useful summary time, if desired, with:
-
- $self->output(
- timestr( timediff( Benchmark->new, $start_time ), 'nop' ) );
-
-=item * C<tests>
-
-This is an array reference of all test names. To get the L<TAP::Parser>
-object for individual tests:
-
- my $aggregate = $args->{aggregate};
- my $tests = $args->{tests};
-
- for my $name ( @$tests ) {
- my ($parser) = $aggregate->parsers($test);
- ... do something with $parser
- }
-
-This is a bit clunky and will be cleaned up in a later release.
-
-=back
-
-=cut
-
sub _get_parser_args {
my ( $self, $job ) = @_;
my $test_prog = $job->filename;
my %args = ();
+
+ $args{sources} = $self->sources if $self->sources;
+
my @switches;
@switches = $self->lib if $self->lib;
push @switches => $self->switches if $self->switches;
@@ -699,6 +724,7 @@ sub _get_parser_args {
$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}
@@ -717,6 +743,19 @@ sub _get_parser_args {
}
if ( defined( my $test_args = $self->test_args ) ) {
+
+ if ( ref($test_args) eq 'HASH' ) {
+
+ # different args for each test
+ if ( exists( $test_args->{ $job->description } ) ) {
+ $test_args = $test_args->{ $job->description };
+ }
+ else {
+ $self->_croak( "TAP::Harness Can't find test_args for "
+ . $job->description );
+ }
+ }
+
$args{test_args} = $test_args;
}
@@ -807,6 +846,120 @@ sub _croak {
return;
}
+1;
+
+__END__
+
+##############################################################################
+
+=head1 CONFIGURING
+
+C<TAP::Harness> is designed to be easy to configure.
+
+=head2 Plugins
+
+C<TAP::Parser> plugins let you change the way TAP is I<input> to and I<output>
+from the parser.
+
+L<TAP::Parser::SourceHandler>s handle TAP I<input>. You can configure them
+and load custom handlers using the C<sources> parameter to L</new>.
+
+L<TAP::Formatter>s handle TAP I<output>. You can load custom formatters by
+using the C<formatter_class> parameter to L</new>. To configure a formatter,
+you currently need to instantiate it outside of L<TAP::Harness> and pass it in
+with the C<formatter> parameter to L</new>. This I<may> be addressed by adding
+a I<formatters> parameter to L</new> in the future.
+
+=head2 C<Module::Build>
+
+L<Module::Build> version C<0.30> supports C<TAP::Harness>.
+
+To load C<TAP::Harness> plugins, you'll need to use the C<tap_harness_args>
+parameter to C<new>, typically from your C<Build.PL>. For example:
+
+ Module::Build->new(
+ module_name => 'MyApp',
+ test_file_exts => [qw(.t .tap .txt)],
+ use_tap_harness => 1,
+ tap_harness_args => {
+ sources => {
+ MyCustom => {},
+ File => {
+ extensions => ['.tap', '.txt'],
+ },
+ },
+ formatter => 'TAP::Formatter::HTML',
+ },
+ build_requires => {
+ 'Module::Build' => '0.30',
+ 'TAP::Harness' => '3.18',
+ },
+ )->create_build_script;
+
+See L</new>
+
+=head2 C<ExtUtils::MakeMaker>
+
+L<ExtUtils::MakeMaker> does not support L<TAP::Harness> out-of-the-box.
+
+=head2 C<prove>
+
+L<prove> supports C<TAP::Harness> plugins, and has a plugin system of its
+own. See L<prove/FORMATTERS>, L<prove/SOURCE HANDLERS> and L<App::Prove>
+for more details.
+
+=head1 WRITING PLUGINS
+
+If you can't configure C<TAP::Harness> to do what you want, and you can't find
+an existing plugin, consider writing one.
+
+The two primary use cases supported by L<TAP::Harness> for plugins are I<input>
+and I<output>:
+
+=over 2
+
+=item Customize how TAP gets into the parser
+
+To do this, you can either extend an existing L<TAP::Parser::SourceHandler>,
+or write your own. It's a pretty simple API, and they can be loaded and
+configured using the C<sources> parameter to L</new>.
+
+=item Customize how TAP results are output from the parser
+
+To do this, you can either extend an existing L<TAP::Formatter>, or write your
+own. Writing formatters are a bit more involved than writing a
+I<SourceHandler>, as you'll need to understand the L<TAP::Parser> API. A
+good place to start is by understanding how L</aggregate_tests> works.
+
+Custom formatters can be loaded configured using the C<formatter_class>
+parameter to L</new>.
+
+=back
+
+=head1 SUBCLASSING
+
+If you can't configure C<TAP::Harness> to do exactly what you want, and writing
+a plugin isn't an option, consider extending it. It is designed to be (mostly)
+easy to subclass, though the cases when sub-classing is necessary should be few
+and far between.
+
+=head2 Methods
+
+The following methods are ones you may wish to override if you want to
+subclass C<TAP::Harness>.
+
+=over 4
+
+=item L</new>
+
+=item L</runtests>
+
+=item L</summary>
+
+=back
+
+=cut
+
=head1 REPLACING
If you like the C<prove> utility and L<TAP::Parser> but you want your
@@ -825,6 +978,4 @@ L<Test::Harness>
=cut
-1;
-
# vim:ts=4:sw=4:et:sta