summaryrefslogtreecommitdiff
path: root/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test
diff options
context:
space:
mode:
Diffstat (limited to 'systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test')
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Fatal.pm30
-rwxr-xr-xsystems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/HACKING.pod264
-rwxr-xr-xsystems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Harness.pm618
-rwxr-xr-xsystems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Needs.pm8
-rwxr-xr-xsystems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Warnings.pm587
5 files changed, 1496 insertions, 11 deletions
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Fatal.pm b/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Fatal.pm
index 4fd0e2f361..2d90b3a6ee 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Fatal.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Fatal.pm
@@ -2,7 +2,7 @@ use strict;
use warnings;
package Test::Fatal;
# ABSTRACT: incredibly simple helpers for testing code with exceptions
-$Test::Fatal::VERSION = '0.016';
+$Test::Fatal::VERSION = '0.017';
#pod =head1 SYNOPSIS
#pod
#pod use Test::More;
@@ -105,7 +105,7 @@ our @EXPORT_OK = qw(exception success dies_ok lives_ok);
#pod exception_like(sub { }, [ qr/foo/, 'foo appears in the exception' ] );
#pod
#pod To aid in avoiding the problem where the pattern is seen in the exception
-#pod because of the call stack, C<$Carp::MAxArgNums> is locally set to -1 when the
+#pod because of the call stack, C<$Carp::MaxArgNums> is locally set to -1 when the
#pod code block is called. If you really don't want that, set it back to whatever
#pod value you like at the beginning of the code block. Obviously, this solution
#pod doens't affect all possible ways that args of subroutines in the call stack
@@ -197,7 +197,7 @@ sub success (&;@) {
#pod =func lives_ok
#pod
#pod Exported only by request, these two functions run a given block of code, and
-#pod provide TAP output indicating if it did, or did not throw an exception.
+#pod provide TAP output indicating if it did, or did not throw an exception.
#pod These provide an easy upgrade path for replacing existing unit tests based on
#pod C<Test::Exception>.
#pod
@@ -270,7 +270,7 @@ Test::Fatal - incredibly simple helpers for testing code with exceptions
=head1 VERSION
-version 0.016
+version 0.017
=head1 SYNOPSIS
@@ -311,6 +311,16 @@ false positives if exceptions use stack traces that show arguments. For a more
magical approach involving globally overriding C<caller>, see
L<Test::Exception>.
+=head1 PERL VERSION
+
+This library should run on perls released even a long time ago. It should work
+on any version of perl released in the last five years.
+
+Although it may work on older versions of perl, no guarantee is made that the
+minimum required version will not be increased. The version may be increased
+for any reason, and there is no promise that patches will be accepted to lower
+the minimum required perl.
+
=head1 FUNCTIONS
=head2 exception
@@ -366,7 +376,7 @@ arguments in an array reference to hide the literal text from a stack trace:
exception_like(sub { }, [ qr/foo/, 'foo appears in the exception' ] );
To aid in avoiding the problem where the pattern is seen in the exception
-because of the call stack, C<$Carp::MAxArgNums> is locally set to -1 when the
+because of the call stack, C<$Carp::MaxArgNums> is locally set to -1 when the
code block is called. If you really don't want that, set it back to whatever
value you like at the beginning of the code block. Obviously, this solution
doens't affect all possible ways that args of subroutines in the call stack
@@ -407,7 +417,7 @@ success blocks may sometimes help organize complex testing.
=head2 lives_ok
Exported only by request, these two functions run a given block of code, and
-provide TAP output indicating if it did, or did not throw an exception.
+provide TAP output indicating if it did, or did not throw an exception.
These provide an easy upgrade path for replacing existing unit tests based on
C<Test::Exception>.
@@ -423,11 +433,11 @@ use Test::Fatal's C<exception> routine.
=head1 AUTHOR
-Ricardo Signes <rjbs@cpan.org>
+Ricardo Signes <cpan@semiotic.systems>
=head1 CONTRIBUTORS
-=for stopwords David Golden Graham Knop Jesse Luehrs Joel Bernstein Karen Etheridge
+=for stopwords David Golden Graham Knop Jesse Luehrs Joel Bernstein Karen Etheridge Ricardo Signes
=over 4
@@ -451,6 +461,10 @@ Joel Bernstein <joel@fysh.org>
Karen Etheridge <ether@cpan.org>
+=item *
+
+Ricardo Signes <rjbs@semiotic.systems>
+
=back
=head1 COPYRIGHT AND LICENSE
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/HACKING.pod b/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/HACKING.pod
new file mode 100755
index 0000000000..91b33011a0
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/HACKING.pod
@@ -0,0 +1,264 @@
+
+# this is in pod format (try `perldoc HACKING.pod`)
+
+=pod
+
+=head1 NAME
+
+HACKING.pod - contributing to TAP::Harness
+
+=head1 ABOUT
+
+This is the guide for TAP::Harness internals contributors (developers,
+testers, documenters.)
+
+If you are looking for more information on how to I<use> TAP::Harness,
+you probably want
+L<http://testanything.org/testing-with-tap/perl/tap-parser-cookbook.html>
+instead.
+
+=head1 Getting Started
+
+See the resources section in I<META.yml> or I<Build.PL> for links to the
+project mailing list, bug tracker, svn repository, etc.
+
+For ease of reference, at the time of writing the SVN repository was at:
+
+ http://svn.hexten.net/tapx
+
+To get the latest version of trunk:
+
+ git clone git://github.com/Perl-Toolchain-Gang/Test-Harness.git
+
+For best results, read the rest of this file, check RT for bugs which
+scratch your itch, join the mailing list, etc.
+
+=head1 Formatting
+
+=head2 perltidy
+
+The project comes with a C<.perltidyrc>, which perltidy will
+automatically use if the project root is your working directory. This
+is setup by default to read and write the perl code on a pipe. To
+configure your editor:
+
+=over 4
+
+=item * vim
+
+In C<.vimrc>, you can add the following lines:
+
+ nnoremap <Leader>pt :%!perltidy -q<cr> " only work in 'normal' mode
+ vnoremap <Leader>pt :!perltidy -q<cr> " only work in 'visual' mode
+
+In other words, if your C<Leader> is a backslash, you can type C<\pt> to
+reformat the file using the C<.perltidyrc>. If you are in visual mode
+(selecting lines with shift-v), then only the code you have currently have
+selected will be reformatted.
+
+=item * emacs
+
+For emacs, you can use this snippet from Sam Tregar
+(L<http://use.perl.org/~samtregar/journal/30185>):
+
+ (defun perltidy-region ()
+ "Run perltidy on the current region."
+ (interactive)
+ (save-excursion
+ (shell-command-on-region (point) (mark) "perltidy -q" nil t)
+ (cperl-mode)))
+
+ (defun perltidy-all ()
+ "Run perltidy on the current region."
+ (interactive)
+ (let ((p (point)))
+ (save-excursion
+ (shell-command-on-region (point-min) (point-max) "perltidy -q" nil t)
+ )
+ (goto-char p)
+ (cperl-mode)))
+
+ (global-set-key "\M-t" `perltidy-region)
+ (global-set-key "\M-T" `perltidy-all)
+
+=back
+
+=head1 Tests and Coverage
+
+...
+
+=for eric_not_it
+ TODO link to a good guide on writing tests for TAP::Parser
+
+=head1 Writing for Compatibility
+
+...
+
+=for eric_not_it
+ TODO explain no bundling, PERL_CORE, etc
+
+=head1 Use TAP::Object
+
+TAP::Object is the common base class to all TAP::* modules, and should be for
+any that you write.
+
+=head1 Exception Handling
+
+Exceptions should be raised with L<Carp>:
+
+ require Carp;
+ Carp::croak("Unsupported syntax version: $version");
+
+ require Carp;
+ Carp::confess("Unsupported syntax version: $version");
+
+=head1 Deprecation cycle
+
+Any I<documented> sub that needs to be changed or removed (and would therefore
+cause a backwards-compat issue) must go through a deprecation cycle to give
+developers a chance to adjust:
+
+ 1. Document the deprecation
+ 2. Carp a suitable message
+ 3. Release
+ 4. Change the code
+ 5. Release
+
+=head1 Documentation
+
+The end-user and API documentation is all in the 'lib/' directory. In
+.pm files, the pod is "inline" to the code. See L<perlpod> for more
+about pod.
+
+=head2 Pod Commands
+
+For compatibility's sake, we do not use the =head3 and =head4 commands.
+
+=over
+
+=item C<=head1 SECTION>
+
+Sections begin with an C<=head1> command and are all-caps.
+
+=for eric_not_it
+ I guess... Mixed case messes with various pod hacking tools.
+
+ NAME
+ VERSION
+ SYNOPSIS
+ CONSTRUCTOR
+ METHODS
+ CLASS METHODS
+ SOME OTHER SORT OF METHODS
+ SEE ALSO
+
+=item C<=head2 method>
+
+=for eric_not_it
+ The following is how I would do it, but opposite of what we have.
+
+The C<=head2> command documents a method. The name of the method should have no adornment (e.g. don't CE<lt>method> or CE<lt>method($list, $of, $params)>.)
+
+These sections should begin with a short description of what the method
+does, followed by one or more examples of usage. If needed, elaborate
+on the subtleties of the parameters and context after (and/or between)
+the example(s).
+
+ =head2 this_method
+
+ This method does some blah blah blah.
+
+ my @answer = $thing->this_method(@arguments);
+
+ =head2 that_thing
+
+ Returns true if the thing is true.
+
+ if($thing->that_thing) {
+ ...
+ }
+
+=item C<=item parameter>
+
+Use C<=item> commands for method arguments and parameters (and etc.) In
+most html pod formatters, these I<do not> get added to the
+table-of-contents at the top of the page.
+
+=back
+
+=head2 Pod Formatting Codes
+
+=over
+
+=item LE<lt>Some::Module>
+
+Be careful of the wording of C<LE<lt>Some::ModuleE<gt>>. Older pod
+formatters would render this as "the Some::Module manpage", so it is
+best to either word your links as "C<(see E<lt>Some::ModuleE<gt> for
+details.)>" or use the "explicit rendering" form of
+"C<E<lt>Some::Module|Some::ModuleE<gt>>".
+
+=back
+
+=head2 VERSION
+
+The version numbers are updated by L<Perl::Version>.
+
+=head2 DEVELOPER DOCS/NOTES
+
+The following "formats" are used with C<=begin>/C<=end> and C<=for>
+commands for pod which is not part of the public end-user/API
+documentation.
+
+=over
+
+=item note
+
+Use this if you are uncertain about a change to some pod or think it
+needs work.
+
+ =head2 some_method
+
+ ...
+
+ =for note
+ This is either falsely documented or a bug -- see ...
+
+=item developer
+
+ =begin developer
+
+ Long-winded explanation of why some code is the way it is or various
+ other subtleties which might incite head-scratching and WTF'ing.
+
+ =end developer
+
+=item deprecated
+
+ =for deprecated
+ removed in 0.09, kill by ~0.25
+
+=back
+
+=head1 Committing to Subversion
+
+If you have commit access, please bear this in mind.
+
+Development is done either on trunk or a branch, as appropriate:
+
+If it's something that might be controversial, break the build or take a long
+time (more than a couple of weeks) to complete then it'd probably be
+appropriate to branch. Otherwise it can go in trunk.
+
+If in doubt discuss it on the mailing list before you commit.
+
+=cut
+
+=for developer
+... or whatever. I'm just making stuff up here. If any of this is
+wrong, please correct it. To the extent that there is an "official
+policy", it should be written down. --Eric
+
+=cut
+
+# vim:ts=2:sw=2:et:sta
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Harness.pm b/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Harness.pm
new file mode 100755
index 0000000000..33e57fcc84
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Harness.pm
@@ -0,0 +1,618 @@
+package Test::Harness;
+
+use 5.006;
+
+use strict;
+use warnings;
+
+use constant IS_WIN32 => ( $^O =~ /^(MS)?Win32$/ );
+use constant IS_VMS => ( $^O eq 'VMS' );
+
+use TAP::Harness ();
+use TAP::Parser::Aggregator ();
+use TAP::Parser::Source ();
+use TAP::Parser::SourceHandler::Perl ();
+
+use Text::ParseWords qw(shellwords);
+
+use Config;
+use base 'Exporter';
+
+# $ML $Last_ML_Print
+
+BEGIN {
+ eval q{use Time::HiRes 'time'};
+ our $has_time_hires = !$@;
+}
+
+=head1 NAME
+
+Test::Harness - Run Perl standard test scripts with statistics
+
+=head1 VERSION
+
+Version 3.48
+
+=cut
+
+our $VERSION = '3.48';
+
+# Backwards compatibility for exportable variable names.
+*verbose = *Verbose;
+*switches = *Switches;
+*debug = *Debug;
+
+$ENV{HARNESS_ACTIVE} = 1;
+$ENV{HARNESS_VERSION} = $VERSION;
+
+END {
+
+ # For VMS.
+ delete $ENV{HARNESS_ACTIVE};
+ delete $ENV{HARNESS_VERSION};
+}
+
+our @EXPORT = qw(&runtests);
+our @EXPORT_OK = qw(&execute_tests $verbose $switches);
+
+our $Verbose = $ENV{HARNESS_VERBOSE} || 0;
+our $Debug = $ENV{HARNESS_DEBUG} || 0;
+our $Switches = '-w';
+our $Columns = $ENV{HARNESS_COLUMNS} || $ENV{COLUMNS} || 80;
+$Columns--; # Some shells have trouble with a full line of text.
+our $Timer = $ENV{HARNESS_TIMER} || 0;
+our $Color = $ENV{HARNESS_COLOR} || 0;
+our $IgnoreExit = $ENV{HARNESS_IGNORE_EXIT} || 0;
+
+=head1 SYNOPSIS
+
+ use Test::Harness;
+
+ runtests(@test_files);
+
+=head1 DESCRIPTION
+
+Although, for historical reasons, the L<Test::Harness> distribution
+takes its name from this module it now exists only to provide
+L<TAP::Harness> with an interface that is somewhat backwards compatible
+with L<Test::Harness> 2.xx. If you're writing new code consider using
+L<TAP::Harness> directly instead.
+
+Emulation is provided for C<runtests> and C<execute_tests> but the
+pluggable 'Straps' interface that previous versions of L<Test::Harness>
+supported is not reproduced here. Straps is now available as a stand
+alone module: L<Test::Harness::Straps>.
+
+See L<TAP::Parser>, L<TAP::Harness> for the main documentation for this
+distribution.
+
+=head1 FUNCTIONS
+
+The following functions are available.
+
+=head2 runtests( @test_files )
+
+This runs all the given I<@test_files> and divines whether they passed
+or failed based on their output to STDOUT (details above). It prints
+out each individual test which failed along with a summary report and
+a how long it all took.
+
+It returns true if everything was ok. Otherwise it will C<die()> with
+one of the messages in the DIAGNOSTICS section.
+
+=cut
+
+sub _has_taint {
+ my $test = shift;
+ return TAP::Parser::SourceHandler::Perl->get_taint(
+ TAP::Parser::Source->shebang($test) );
+}
+
+sub _aggregate {
+ my ( $harness, $aggregate, @tests ) = @_;
+
+ # Don't propagate to our children
+ local $ENV{HARNESS_OPTIONS};
+
+ _apply_extra_INC($harness);
+ _aggregate_tests( $harness, $aggregate, @tests );
+}
+
+# Make sure the child sees all the extra junk in @INC
+sub _apply_extra_INC {
+ my $harness = shift;
+
+ $harness->callback(
+ parser_args => sub {
+ my ( $args, $test ) = @_;
+ push @{ $args->{switches} }, map {"-I$_"} _filtered_inc();
+ }
+ );
+}
+
+sub _aggregate_tests {
+ my ( $harness, $aggregate, @tests ) = @_;
+ $aggregate->start();
+ $harness->aggregate_tests( $aggregate, @tests );
+ $aggregate->stop();
+
+}
+
+sub runtests {
+ my @tests = @_;
+
+ # shield against -l
+ local ( $\, $, );
+
+ my $harness = _new_harness();
+ my $aggregate = TAP::Parser::Aggregator->new();
+
+ local $ENV{PERL_USE_UNSAFE_INC} = 1 if not exists $ENV{PERL_USE_UNSAFE_INC};
+ _aggregate( $harness, $aggregate, @tests );
+
+ $harness->formatter->summary($aggregate);
+
+ my $total = $aggregate->total;
+ my $passed = $aggregate->passed;
+ my $failed = $aggregate->failed;
+
+ my @parsers = $aggregate->parsers;
+
+ my $num_bad = 0;
+ for my $parser (@parsers) {
+ $num_bad++ if $parser->has_problems;
+ }
+
+ die(sprintf(
+ "Failed %d/%d test programs. %d/%d subtests failed.\n",
+ $num_bad, scalar @parsers, $failed, $total
+ )
+ ) if $num_bad;
+
+ return $total && $total == $passed;
+}
+
+sub _canon {
+ my @list = sort { $a <=> $b } @_;
+ my @ranges = ();
+ my $count = scalar @list;
+ my $pos = 0;
+
+ while ( $pos < $count ) {
+ my $end = $pos + 1;
+ $end++ while $end < $count && $list[$end] <= $list[ $end - 1 ] + 1;
+ push @ranges, ( $end == $pos + 1 )
+ ? $list[$pos]
+ : join( '-', $list[$pos], $list[ $end - 1 ] );
+ $pos = $end;
+ }
+
+ return join( ' ', @ranges );
+}
+
+sub _new_harness {
+ my $sub_args = shift || {};
+
+ my ( @lib, @switches );
+ my @opt = map { shellwords($_) } grep { defined } $Switches, $ENV{HARNESS_PERL_SWITCHES};
+ while ( my $opt = shift @opt ) {
+ if ( $opt =~ /^ -I (.*) $ /x ) {
+ push @lib, length($1) ? $1 : shift @opt;
+ }
+ else {
+ push @switches, $opt;
+ }
+ }
+
+ # Do things the old way on VMS...
+ push @lib, _filtered_inc() if IS_VMS;
+
+ # If $Verbose isn't numeric default to 1. This helps core.
+ my $verbosity = ( $Verbose ? ( $Verbose !~ /\d/ ) ? 1 : $Verbose : 0 );
+
+ my $args = {
+ timer => $Timer,
+ directives => our $Directives,
+ lib => \@lib,
+ switches => \@switches,
+ color => $Color,
+ verbosity => $verbosity,
+ ignore_exit => $IgnoreExit,
+ };
+
+ $args->{stdout} = $sub_args->{out}
+ if exists $sub_args->{out};
+
+ my $class = $ENV{HARNESS_SUBCLASS} || 'TAP::Harness';
+ if ( defined( my $env_opt = $ENV{HARNESS_OPTIONS} ) ) {
+ for my $opt ( split /:/, $env_opt ) {
+ if ( $opt =~ /^j(\d*)$/ ) {
+ $args->{jobs} = $1 || 9;
+ }
+ elsif ( $opt eq 'c' ) {
+ $args->{color} = 1;
+ }
+ elsif ( $opt =~ m/^f(.*)$/ ) {
+ my $fmt = $1;
+ $fmt =~ s/-/::/g;
+ $args->{formatter_class} = $fmt;
+ }
+ elsif ( $opt =~ m/^a(.*)$/ ) {
+ my $archive = $1;
+ $class = "TAP::Harness::Archive";
+ $args->{archive} = $archive;
+ }
+ else {
+ die "Unknown HARNESS_OPTIONS item: $opt\n";
+ }
+ }
+ }
+
+ return TAP::Harness->_construct( $class, $args );
+}
+
+# Get the parts of @INC which are changed from the stock list AND
+# preserve reordering of stock directories.
+sub _filtered_inc {
+ my @inc = grep { !ref } @INC; #28567
+
+ if (IS_VMS) {
+
+ # VMS has a 255-byte limit on the length of %ENV entries, so
+ # toss the ones that involve perl_root, the install location
+ @inc = grep !/perl_root/i, @inc;
+
+ }
+ elsif (IS_WIN32) {
+
+ # Lose any trailing backslashes in the Win32 paths
+ s/[\\\/]+$// for @inc;
+ }
+
+ my @default_inc = _default_inc();
+
+ my @new_inc;
+ my %seen;
+ for my $dir (@inc) {
+ next if $seen{$dir}++;
+
+ if ( $dir eq ( $default_inc[0] || '' ) ) {
+ shift @default_inc;
+ }
+ else {
+ push @new_inc, $dir;
+ }
+
+ shift @default_inc while @default_inc and $seen{ $default_inc[0] };
+ }
+
+ return @new_inc;
+}
+
+{
+
+ # Cache this to avoid repeatedly shelling out to Perl.
+ my @inc;
+
+ sub _default_inc {
+ return @inc if @inc;
+
+ local $ENV{PERL5LIB};
+ local $ENV{PERLLIB};
+
+ my $perl = $ENV{HARNESS_PERL} || $^X;
+
+ # Avoid using -l for the benefit of Perl 6
+ chomp( @inc = `"$perl" -e "print join qq[\\n], \@INC, q[]"` );
+ return @inc;
+ }
+}
+
+sub _check_sequence {
+ my @list = @_;
+ my $prev;
+ while ( my $next = shift @list ) {
+ return if defined $prev && $next <= $prev;
+ $prev = $next;
+ }
+
+ return 1;
+}
+
+sub execute_tests {
+ my %args = @_;
+
+ my $harness = _new_harness( \%args );
+ my $aggregate = TAP::Parser::Aggregator->new();
+
+ my %tot = (
+ bonus => 0,
+ max => 0,
+ ok => 0,
+ bad => 0,
+ good => 0,
+ files => 0,
+ tests => 0,
+ sub_skipped => 0,
+ todo => 0,
+ skipped => 0,
+ bench => undef,
+ );
+
+ # Install a callback so we get to see any plans the
+ # harness executes.
+ $harness->callback(
+ made_parser => sub {
+ my $parser = shift;
+ $parser->callback(
+ plan => sub {
+ my $plan = shift;
+ if ( $plan->directive eq 'SKIP' ) {
+ $tot{skipped}++;
+ }
+ }
+ );
+ }
+ );
+
+ local $ENV{PERL_USE_UNSAFE_INC} = 1 if not exists $ENV{PERL_USE_UNSAFE_INC};
+ _aggregate( $harness, $aggregate, @{ $args{tests} } );
+
+ $tot{bench} = $aggregate->elapsed;
+ my @tests = $aggregate->descriptions;
+
+ # TODO: Work out the circumstances under which the files
+ # and tests totals can differ.
+ $tot{files} = $tot{tests} = scalar @tests;
+
+ my %failedtests = ();
+ my %todo_passed = ();
+
+ for my $test (@tests) {
+ my ($parser) = $aggregate->parsers($test);
+
+ my @failed = $parser->failed;
+
+ my $wstat = $parser->wait;
+ my $estat = $parser->exit;
+ my $planned = $parser->tests_planned;
+ my @errors = $parser->parse_errors;
+ my $passed = $parser->passed;
+ my $actual_passed = $parser->actual_passed;
+
+ my $ok_seq = _check_sequence( $parser->actual_passed );
+
+ # Duplicate exit, wait status semantics of old version
+ $estat ||= '' unless $wstat;
+ $wstat ||= '';
+
+ $tot{max} += ( $planned || 0 );
+ $tot{bonus} += $parser->todo_passed;
+ $tot{ok} += $passed > $actual_passed ? $passed : $actual_passed;
+ $tot{sub_skipped} += $parser->skipped;
+ $tot{todo} += $parser->todo;
+
+ if ( @failed || $estat || @errors ) {
+ $tot{bad}++;
+
+ my $huh_planned = $planned ? undef : '??';
+ my $huh_errors = $ok_seq ? undef : '??';
+
+ $failedtests{$test} = {
+ 'canon' => $huh_planned
+ || $huh_errors
+ || _canon(@failed)
+ || '??',
+ 'estat' => $estat,
+ 'failed' => $huh_planned
+ || $huh_errors
+ || scalar @failed,
+ 'max' => $huh_planned || $planned,
+ 'name' => $test,
+ 'wstat' => $wstat
+ };
+ }
+ else {
+ $tot{good}++;
+ }
+
+ my @todo = $parser->todo_passed;
+ if (@todo) {
+ $todo_passed{$test} = {
+ 'canon' => _canon(@todo),
+ 'estat' => $estat,
+ 'failed' => scalar @todo,
+ 'max' => scalar $parser->todo,
+ 'name' => $test,
+ 'wstat' => $wstat
+ };
+ }
+ }
+
+ return ( \%tot, \%failedtests, \%todo_passed );
+}
+
+=head2 execute_tests( tests => \@test_files, out => \*FH )
+
+Runs all the given C<@test_files> (just like C<runtests()>) but
+doesn't generate the final report. During testing, progress
+information will be written to the currently selected output
+filehandle (usually C<STDOUT>), or to the filehandle given by the
+C<out> parameter. The I<out> is optional.
+
+Returns a list of two values, C<$total> and C<$failed>, describing the
+results. C<$total> is a hash ref summary of all the tests run. Its
+keys and values are this:
+
+ bonus Number of individual todo tests unexpectedly passed
+ max Number of individual tests ran
+ ok Number of individual tests passed
+ sub_skipped Number of individual tests skipped
+ todo Number of individual todo tests
+
+ files Number of test files ran
+ good Number of test files passed
+ bad Number of test files failed
+ tests Number of test files originally given
+ skipped Number of test files skipped
+
+If C<< $total->{bad} == 0 >> and C<< $total->{max} > 0 >>, you've
+got a successful test.
+
+C<$failed> is a hash ref of all the test scripts that failed. Each key
+is the name of a test script, each value is another hash representing
+how that script failed. Its keys are these:
+
+ name Name of the test which failed
+ estat Script's exit value
+ wstat Script's wait status
+ max Number of individual tests
+ failed Number which failed
+ canon List of tests which failed (as string).
+
+C<$failed> should be empty if everything passed.
+
+=cut
+
+1;
+__END__
+
+=head1 EXPORT
+
+C<&runtests> is exported by C<Test::Harness> by default.
+
+C<&execute_tests>, C<$verbose>, C<$switches> and C<$debug> are
+exported upon request.
+
+=head1 ENVIRONMENT VARIABLES THAT TAP::HARNESS::COMPATIBLE SETS
+
+C<Test::Harness> sets these before executing the individual tests.
+
+=over 4
+
+=item C<HARNESS_ACTIVE>
+
+This is set to a true value. It allows the tests to determine if they
+are being executed through the harness or by any other means.
+
+=item C<HARNESS_VERSION>
+
+This is the version of C<Test::Harness>.
+
+=back
+
+=head1 ENVIRONMENT VARIABLES THAT AFFECT TEST::HARNESS
+
+=over 4
+
+=item C<HARNESS_PERL_SWITCHES>
+
+Setting this adds perl command line switches to each test file run.
+
+For example, C<HARNESS_PERL_SWITCHES=-T> will turn on taint mode.
+C<HARNESS_PERL_SWITCHES=-MDevel::Cover> will run C<Devel::Cover> for
+each test.
+
+C<-w> is always set. You can turn this off in the test with C<BEGIN {
+$^W = 0 }>.
+
+=item C<HARNESS_TIMER>
+
+Setting this to true will make the harness display the number of
+milliseconds each test took. You can also use F<prove>'s C<--timer>
+switch.
+
+=item C<HARNESS_VERBOSE>
+
+If true, C<Test::Harness> will output the verbose results of running
+its tests. Setting C<$Test::Harness::verbose> will override this,
+or you can use the C<-v> switch in the F<prove> utility.
+
+=item C<HARNESS_OPTIONS>
+
+Provide additional options to the harness. Currently supported options are:
+
+=over
+
+=item C<< j<n> >>
+
+Run <n> (default 9) parallel jobs.
+
+=item C<< c >>
+
+Try to color output. See L<TAP::Formatter::Base/"new">.
+
+=item C<< a<file.tgz> >>
+
+Will use L<TAP::Harness::Archive> as the harness class, and save the TAP to
+C<file.tgz>
+
+=item C<< fPackage-With-Dashes >>
+
+Set the formatter_class of the harness being run. Since the C<HARNESS_OPTIONS>
+is separated by C<:>, we use C<-> instead.
+
+=back
+
+Multiple options may be separated by colons:
+
+ HARNESS_OPTIONS=j9:c make test
+
+=item C<HARNESS_SUBCLASS>
+
+Specifies a TAP::Harness subclass to be used in place of TAP::Harness.
+
+=item C<HARNESS_SUMMARY_COLOR_SUCCESS>
+
+Determines the L<Term::ANSIColor> for the summary in case it is successful.
+This color defaults to C<'green'>.
+
+=item C<HARNESS_SUMMARY_COLOR_FAIL>
+
+Determines the L<Term::ANSIColor> for the failure in case it is successful.
+This color defaults to C<'red'>.
+
+=back
+
+=head1 Taint Mode
+
+Normally when a Perl program is run in taint mode the contents of the
+C<PERL5LIB> environment variable do not appear in C<@INC>.
+
+Because C<PERL5LIB> is often used during testing to add build
+directories to C<@INC> C<Test::Harness> passes the names of any
+directories found in C<PERL5LIB> as -I switches. The net effect of this
+is that C<PERL5LIB> is honoured even in taint mode.
+
+=head1 SEE ALSO
+
+L<TAP::Harness>
+
+=head1 BUGS
+
+Please report any bugs or feature requests to
+C<bug-test-harness at rt.cpan.org>, or through the web interface at
+L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-Harness>. I will be
+notified, and then you'll automatically be notified of progress on your bug
+as I make changes.
+
+=head1 AUTHORS
+
+Andy Armstrong C<< <andy@hexten.net> >>
+
+L<Test::Harness> 2.64 (maintained by Andy Lester and on which this
+module is based) has this attribution:
+
+ Either Tim Bunce or Andreas Koenig, we don't know. What we know for
+ sure is, that it was inspired by Larry Wall's F<TEST> script that came
+ with perl distributions for ages. Numerous anonymous contributors
+ exist. Andreas Koenig held the torch for many years, and then
+ Michael G Schwern.
+
+=head1 LICENCE AND COPYRIGHT
+
+Copyright (c) 2007-2011, Andy Armstrong C<< <andy@hexten.net> >>. All rights reserved.
+
+This module is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself. See L<perlartistic>.
+
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Needs.pm b/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Needs.pm
index 22660a154e..4f0e5956b0 100755
--- a/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Needs.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Needs.pm
@@ -2,7 +2,7 @@ package Test::Needs;
use strict;
use warnings;
no warnings 'once';
-our $VERSION = '0.002009';
+our $VERSION = '0.002010';
$VERSION =~ tr/_//d;
BEGIN {
@@ -175,27 +175,29 @@ sub _fail_or_skip {
my $tb = Test::Builder->new;
my $has_plan = Test::Builder->can('has_plan') ? 'has_plan'
: sub { $_[0]->expected_tests || eval { $_[0]->current_test($_[0]->current_test); 'no_plan' } };
+ my $tests = $tb->current_test;
if ($fail) {
$tb->plan(tests => 1)
unless $tb->$has_plan;
+ $tests++;
$tb->ok(0, "Test::Needs modules available");
$tb->diag($message);
}
else {
my $plan = $tb->$has_plan;
- my $tests = $tb->current_test;
if ($plan || $tests) {
my $skips
= $plan && $plan ne 'no_plan' ? $plan - $tests : 1;
$tb->skip("Test::Needs modules not available")
for 1 .. $skips;
+ $tests += $skips;
Test::Builder->can('note') ? $tb->note($message) : print "# $message\n";
}
else {
$tb->skip_all($message);
}
}
- $tb->done_testing
+ $tb->done_testing($tests)
if Test::Builder->can('done_testing');
die bless {} => 'Test::Builder::Exception'
if Test::Builder->can('parent') && $tb->parent;
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Warnings.pm b/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Warnings.pm
new file mode 100755
index 0000000000..d2dd6507e6
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/tlperl/site/lib/Test/Warnings.pm
@@ -0,0 +1,587 @@
+use strict;
+use warnings;
+package Test::Warnings; # git description: v0.032-4-ge6f3f36
+# vim: set ts=8 sts=2 sw=2 tw=100 et :
+# ABSTRACT: Test for warnings and the lack of them
+# KEYWORDS: testing tests warnings
+
+our $VERSION = '0.033';
+
+use parent 'Exporter';
+use Test::Builder;
+
+our @EXPORT_OK = qw(
+ allow_warnings allowing_warnings
+ had_no_warnings
+ warnings warning
+ allow_patterns
+ disallow_patterns
+);
+our %EXPORT_TAGS = ( all => \@EXPORT_OK );
+
+my $warnings_allowed;
+my $forbidden_warnings_found;
+my $done_testing_called;
+my $no_end_test;
+my $fail_on_warning;
+my $report_warnings;
+my @collected_warnings;
+my @allowed_patterns;
+
+sub import {
+ my $class = shift @_;
+
+ my %names; @names{@_} = ();
+ # END block will check for this status
+ $no_end_test = exists $names{':no_end_test'};
+ # __WARN__ handler will check for this status
+ $fail_on_warning = exists $names{':fail_on_warning'};
+ # Collect and report warnings at the end
+ $report_warnings = exists $names{':report_warnings'};
+
+ delete @names{qw(:no_end_test :fail_on_warning :report_warnings)};
+ __PACKAGE__->export_to_level(1, $class, keys %names);
+}
+
+# swap this out for testing this module only!
+my $tb;
+sub _builder(;$) {
+ if (not @_) {
+ $tb ||= Test::Builder->new;
+ return $tb;
+ }
+
+ $tb = shift;
+}
+
+my $_orig_warn_handler = $SIG{__WARN__};
+$SIG{__WARN__} = sub {
+ if ($warnings_allowed or grep +($_[0] =~ $_), @allowed_patterns) {
+ Test::Builder->new->note($_[0]);
+ }
+ else {
+ $forbidden_warnings_found++;
+ push @collected_warnings, $_[0] if $report_warnings;
+
+ # TODO: this doesn't handle blessed coderefs... does anyone care?
+ goto &$_orig_warn_handler if $_orig_warn_handler
+ and ( (ref $_orig_warn_handler eq 'CODE')
+ or ($_orig_warn_handler ne 'DEFAULT'
+ and $_orig_warn_handler ne 'IGNORE'
+ and defined &$_orig_warn_handler));
+
+ if ($_[0] =~ /\n$/) {
+ warn $_[0];
+ } else {
+ require Carp;
+ Carp::carp($_[0]);
+ }
+ _builder->ok(0, 'unexpected warning') if $fail_on_warning;
+ }
+};
+
+sub warnings(;&) {
+ # if someone manually does warnings->import in the same namespace this is
+ # imported into, this sub will be called. in that case, just return the
+ # string "warnings" so it calls the correct method.
+ if (!@_) {
+ return 'warnings';
+ }
+ my $code = shift;
+ my @warnings;
+ local $SIG{__WARN__} = sub {
+ push @warnings, shift;
+ };
+ $code->();
+ @warnings;
+}
+
+sub warning(&) {
+ my @warnings = &warnings(@_);
+ return @warnings == 1 ? $warnings[0] : \@warnings;
+}
+
+if (Test::Builder->can('done_testing')) {
+ # monkeypatch Test::Builder::done_testing:
+ # check for any forbidden warnings, and record that we have done so
+ # so we do not check again via END
+
+ no strict 'refs';
+ my $orig = *{'Test::Builder::done_testing'}{CODE};
+ no warnings 'redefine';
+ *{'Test::Builder::done_testing'} = sub {
+ # only do this at the end of all tests, not at the end of a subtest
+ my $builder = _builder;
+ my $in_subtest_sub = $builder->can('in_subtest');
+ if (not $no_end_test
+ and not ($in_subtest_sub ? $builder->$in_subtest_sub : $builder->parent)) {
+ local $Test::Builder::Level = $Test::Builder::Level + 3;
+ had_no_warnings('no (unexpected) warnings (via done_testing)');
+ $done_testing_called = 1;
+ }
+
+ $orig->(@_);
+ };
+}
+
+if ($INC{'Test2/Tools/Basic.pm'}) {
+ # monkeypatch Test2::Tools::Basic::done_testing:
+ # check for any forbidden warnings, and record that we have done so
+ # so we do not check again via END
+
+ no strict 'refs';
+ my $orig = *{'Test2::Tools::Basic::done_testing'}{CODE};
+ no warnings 'redefine';
+ *{'Test2::Tools::Basic::done_testing'} = sub {
+ if (not $no_end_test) {
+ # we could use $ctx to create the test, which means not having to adjust Level,
+ # but then we need to make _builder Test2-compatible, which seems like a PITA.
+ local $Test::Builder::Level = $Test::Builder::Level + 3;
+ had_no_warnings('no (unexpected) warnings (via done_testing)');
+ $done_testing_called = 1;
+ }
+
+ $orig->(@_);
+ };
+}
+
+END {
+ if (not $no_end_test
+ and not $done_testing_called
+ # skip this if there is no plan and no tests have been run (e.g.
+ # compilation tests of this module!)
+ and (_builder->expected_tests or _builder->current_test > 0)
+ ) {
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+ had_no_warnings('no (unexpected) warnings (via END block)');
+ }
+}
+
+# setter
+sub allow_warnings(;$) {
+ $warnings_allowed = @_ || defined $_[0] ? $_[0] : 1;
+}
+
+# getter
+sub allowing_warnings() { $warnings_allowed }
+
+# call at any time to assert no (unexpected) warnings so far
+sub had_no_warnings(;$) {
+ if ($ENV{PERL_TEST_WARNINGS_ONLY_REPORT_WARNINGS}) {
+ $forbidden_warnings_found
+ and _builder->diag("Found $forbidden_warnings_found warnings but allowing them because PERL_TEST_WARNINGS_ONLY_REPORT_WARNINGS is set");
+ }
+ else {
+ _builder->ok(!$forbidden_warnings_found, shift || 'no (unexpected) warnings');
+ }
+ if (($report_warnings or $ENV{PERL_TEST_WARNINGS_ONLY_REPORT_WARNINGS})
+ and $forbidden_warnings_found) {
+ _builder->diag("Got the following unexpected warnings:");
+ for my $i (1 .. @collected_warnings) {
+ _builder->diag(" $i: $collected_warnings[ $i - 1 ]");
+ }
+ }
+}
+
+# pass one or more regexes (in qr format)
+# when called in void context, lasting effect is universal
+# otherwise, returns objects: when they go out of scope, the effect is removed
+# (warning disallowed again).
+sub allow_patterns(@) {
+ push @allowed_patterns, @_;
+ return if not defined wantarray;
+ return [ map +Test::Warnings::TemporaryWarning->new($_), @_ ];
+}
+
+sub disallow_patterns(@) {
+ foreach my $pattern (@_) {
+ @allowed_patterns = grep +($_ ne $pattern), @allowed_patterns;
+ }
+}
+
+package # hide from PAUSE
+ Test::Warnings::TemporaryWarning;
+
+sub new {
+ my ($class, $pattern) = @_;
+ bless \$pattern, $class;
+}
+
+sub DESTROY {
+ Test::Warnings::disallow_patterns(${$_[0]});
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test::Warnings - Test for warnings and the lack of them
+
+=head1 VERSION
+
+version 0.033
+
+=head1 SYNOPSIS
+
+ use Test::More;
+ use Test::Warnings;
+
+ pass('yay!');
+ done_testing;
+
+emits TAP:
+
+ ok 1 - yay!
+ ok 2 - no (unexpected) warnings (via done_testing)
+ 1..2
+
+and:
+
+ use Test::More tests => 3;
+ use Test::Warnings 0.005 ':all';
+
+ pass('yay!');
+ like(warning { warn "oh noes!" }, qr/^oh noes/, 'we warned');
+
+emits TAP:
+
+ ok 1 - yay!
+ ok 2 - we warned
+ ok 3 - no (unexpected) warnings (via END block)
+ 1..3
+
+=head1 DESCRIPTION
+
+If you've ever tried to use L<Test::NoWarnings> to confirm there are no warnings
+generated by your tests, combined with the convenience of C<done_testing> to
+not have to declare a
+L<test count|Test::More/I love it-when-a-plan-comes-together>,
+you'll have discovered that these two features do not play well together,
+as the test count will be calculated I<before> the warnings test is run,
+resulting in a TAP error. (See C<examples/test_nowarnings.pl> in this
+distribution for a demonstration.)
+
+This module is intended to be used as a drop-in replacement for
+L<Test::NoWarnings>: it also adds an extra test, but runs this test I<before>
+C<done_testing> calculates the test count, rather than after. It does this by
+hooking into C<done_testing> as well as via an C<END> block. You can declare
+a plan, or not, and things will still Just Work.
+
+It is actually equivalent to:
+
+ use Test::NoWarnings 1.04 ':early';
+
+as warnings are still printed normally as they occur. You are safe, and
+enthusiastically encouraged, to perform a global search-replace of the above
+with C<use Test::Warnings;> whether or not your tests have a plan.
+
+It can also be used as a replacement for L<Test::Warn>, if you wish to test
+the content of expected warnings; read on to find out how.
+
+=head1 FUNCTIONS
+
+The following functions are available for import (not included by default; you
+can also get all of them by importing the tag C<:all>):
+
+=head2 C<< allow_warnings([bool]) >> - EXPERIMENTAL - MAY BE REMOVED
+
+When passed a true value, or no value at all, subsequent warnings will not
+result in a test failure; when passed a false value, subsequent warnings will
+result in a test failure. Initial value is C<false>.
+
+When warnings are allowed, any warnings will instead be emitted via
+L<Test::Builder::note|Test::Builder/Output>.
+
+=head2 C<allowing_warnings> - EXPERIMENTAL - MAY BE REMOVED
+
+Returns whether we are currently allowing warnings (set by C<allow_warnings>
+as described above).
+
+=head2 C<< had_no_warnings(<optional test name>) >>
+
+Tests whether there have been any warnings so far, not preceded by an
+C<allowing_warnings> call. It is run
+automatically at the end of all tests, but can also be called manually at any
+time, as often as desired.
+
+=head2 C<< warnings( { code } ) >>
+
+Given a code block, runs the block and returns a list of all the
+(not previously allowed via C<allow_warnings>) warnings issued within. This
+lets you test for the presence of warnings that you not only would I<allow>,
+but I<must> be issued. Testing functions are not provided; given the strings
+returned, you can test these yourself using your favourite testing functions,
+such as L<Test::More::is|Test::More/is> or L<Test::Deep::cmp_deeply|Test::Deep/cmp_deeply>.
+
+You can use this construct as a replacement for
+L<Test::Warn::warnings_are|Test::Warn/warnings_are>:
+
+ is_deeply(
+ [ warnings { ... } ],
+ [
+ 'warning message 1',
+ 'warning message 2',
+ ],
+ 'got expected warnings',
+ );
+
+or, to replace L<Test::Warn::warnings_like|Test::Warn/warnings_like>:
+
+ cmp_deeply(
+ [ warnings { ... } ],
+ bag( # ordering of messages doesn't matter
+ re(qr/warning message 1/),
+ re(qr/warning message 2/),
+ ),
+ 'got expected warnings (in any order)',
+ );
+
+Warnings generated by this code block are I<NOT> propagated further. However,
+since they are returned from this function with their filename and line
+numbers intact, you can re-issue them yourself immediately after calling
+C<warnings(...)>, if desired.
+
+Note that C<use Test::Warnings 'warnings'> will give you a C<warnings>
+subroutine in your namespace (most likely C<main>, if you're writing a test),
+so you (or things you load) can't subsequently do C<< warnings->import >> --
+it will result in the error: "Not enough arguments for
+Test::Warnings::warnings at ..., near "warnings->import"". To work around
+this, either use the fully-qualified form (C<Test::warnings>) or make your
+calls to the C<warnings> package first.
+
+=head2 C<< warning( { code } ) >>
+
+Same as C<< warnings( { code } ) >>, except a scalar is always returned - the
+single warning produced, if there was one, or an arrayref otherwise -- which
+can be more convenient to use than C<warnings()> if you are expecting exactly
+one warning.
+
+However, you are advised to capture the result from C<warning()> into a temp
+variable so you can dump its value if it doesn't contain what you expect.
+e.g. with this test:
+
+ like(
+ warning { foo() },
+ qr/^this is a warning/,
+ 'got a warning from foo()',
+ );
+
+if you get two warnings (or none) back instead of one, you'll get an
+arrayref, which will result in an unhelpful test failure message like:
+
+ # Failed test 'got a warning from foo()'
+ # at t/mytest.t line 10.
+ # 'ARRAY(0xdeadbeef)'
+ # doesn't match '(?^:^this is a warning)'
+
+So instead, change your test to:
+
+ my $warning = warning { foo() };
+ like(
+ $warning,
+ qr/^this is a warning/,
+ 'got a warning from foo()',
+ ) or diag 'got warning(s): ', explain($warning);
+
+=head2 allow_patterns
+
+ allow_patterns(qr/always allow this warning/);
+ {
+ my $temp = allow_patterns(qr/only allow in this scope/, qr/another temporary warning/);
+ ... stuff ...
+ }
+
+Given one or more regular expressions, in C<qr/.../> form, add them to the allow-list (warnings will
+be emitted with C<note> rather than triggering the warning handler). If the return value is saved in
+a local variable, the warning exemption will only be in effect for that local scope (the addition is
+reversed at the end of the scope); otherwise, the effect is global.
+
+=head2 disallow_patterns
+
+Given one or more regular expressions, in C<qr/.../> form, remove it from the allow-list. The
+pattern must exactly match a pattern previously provided to L</allow_patterns>.
+
+=head1 IMPORT OPTIONS
+
+=head2 C<:all>
+
+Imports all functions listed above
+
+=head2 C<:no_end_test>
+
+Disables the addition of a C<had_no_warnings> test
+via C<END> or C<done_testing>
+
+=head2 C<:fail_on_warning>
+
+=for stopwords unexempted
+
+When used, fail immediately when an unexempted warning is generated (as opposed to waiting until
+L</had_no_warnings> or C<done_testing> is called).
+
+I recommend you only turn this option on when debugging a test, to see where a surprise warning is coming from,
+and rely on the end-of-tests check otherwise.
+
+=head2 C<:report_warnings>
+
+When used, C<had_no_warnings()> will print all the unexempted warning content, in case it had been suppressed
+earlier by other captures (such as L<Test::Output/stderr_like> or L<Capture::Tiny/capture>).
+
+=head1 OTHER OPTIONS
+
+You can temporarily turn off the failure behaviour of this module, swapping it out for reporting
+(see C<:report_warnings> above) with:
+
+ $ENV{PERL_TEST_WARNINGS_ONLY_REPORT_WARNINGS} = 1;
+
+This can be useful for working around problematic modules that have warnings in newer Perl versions.
+
+=head1 CAVEATS
+
+=for stopwords smartmatch TODO irc
+
+Sometimes new warnings can appear in Perl that should B<not> block
+installation -- for example, smartmatch was recently deprecated in
+perl 5.17.11, so now any distribution that uses smartmatch and also
+tests for warnings cannot be installed under 5.18.0. You might want to
+consider only making warnings fail tests in an author environment -- you can
+do this with the L<if> pragma:
+
+ use if $ENV{AUTHOR_TESTING} || $ENV{RELEASE_TESTING}, 'Test::Warnings';
+
+In future versions of this module, when interfaces are added to test the
+content of warnings, there will likely be additional sugar available to
+indicate that warnings should be checked only in author tests (or TODO when
+not in author testing), but will still provide exported subs. Comments are
+enthusiastically solicited - drop me an email, write up an RT ticket, or come
+by C<#perl-qa> on irc!
+
+=for stopwords Achtung
+
+B<Achtung!> This is not a great idea:
+
+ sub warning_like(&$;$) {
+ my ($code, $pattern, $name) = @_;
+ like( &warning($code), $pattern, $name );
+ }
+
+ warning_like( { ... }, qr/foo/, 'foo appears in the warning' );
+
+If the code in the C<{ ... }> is going to warn with a stack trace with the
+arguments to each subroutine in its call stack (for example via C<Carp::cluck>),
+the test name, "foo appears in the warning" will itself be matched by the
+regex (see F<examples/warning_like.t>). Instead, write this:
+
+ like( warning { ... }, qr/foo/, 'foo appears in the warning' );
+
+=head1 CAVEATS
+
+If you are using another module that sets its own warning handler (for example L<Devel::Confess> or
+L<diagnostics>) your results may be mixed, as those handlers will interfere with this module's
+ability to properly detect and capture warnings in their original form.
+
+=head1 TO DO (or: POSSIBLE FEATURES COMING IN FUTURE RELEASES)
+
+=over
+
+=item * C<< allow_warnings(qr/.../) >> - allow some warnings and not others
+
+=for stopwords subtest subtests
+
+=item * more sophisticated handling in subtests - if we save some state on the
+L<Test::Builder> object itself, we can allow warnings in a subtest and then
+the state will revert when the subtest ends, as well as check for warnings at
+the end of every subtest via C<done_testing>.
+
+=item * sugar for making failures TODO when testing outside an author
+environment
+
+=back
+
+=head1 SEE ALSO
+
+=for stopwords YANWT
+
+=over 4
+
+=item *
+
+L<Test::NoWarnings>
+
+=item *
+
+L<Test::FailWarnings>
+
+=item *
+
+L<blogs.perl.org: YANWT (Yet Another No-Warnings Tester)|http://blogs.perl.org/users/ether/2013/03/yanwt-yet-another-no-warnings-tester.html>
+
+=item *
+
+L<strictures> - which makes all warnings fatal in tests, hence lessening the need for special warning testing
+
+=item *
+
+L<Test::Warn>
+
+=item *
+
+L<Test::Fatal>
+
+=back
+
+=head1 SUPPORT
+
+Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=Test-Warnings>
+(or L<bug-Test-Warnings@rt.cpan.org|mailto:bug-Test-Warnings@rt.cpan.org>).
+
+There is also a mailing list available for users of this distribution, at
+L<http://lists.perl.org/list/perl-qa.html>.
+
+There is also an irc channel available for users of this distribution, at
+L<C<#perl> on C<irc.perl.org>|irc://irc.perl.org/#perl-qa>.
+
+I am also usually active on irc, as 'ether' at C<irc.perl.org> and C<irc.libera.chat>.
+
+=head1 AUTHOR
+
+Karen Etheridge <ether@cpan.org>
+
+=head1 CONTRIBUTORS
+
+=for stopwords Graham Knop A. Sinan Unur Leon Timmermans Tina Mueller
+
+=over 4
+
+=item *
+
+Graham Knop <haarg@haarg.org>
+
+=item *
+
+A. Sinan Unur <nanis@cpan.org>
+
+=item *
+
+Leon Timmermans <fawaka@gmail.com>
+
+=item *
+
+Tina Mueller <cpan2@tinita.de>
+
+=back
+
+=head1 COPYRIGHT AND LICENCE
+
+This software is copyright (c) 2013 by Karen Etheridge.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut