summaryrefslogtreecommitdiff
path: root/cpan/podlators/t
diff options
context:
space:
mode:
Diffstat (limited to 'cpan/podlators/t')
-rw-r--r--cpan/podlators/t/basic.t117
-rw-r--r--cpan/podlators/t/data/basic.cap (renamed from cpan/podlators/t/basic.cap)0
-rw-r--r--cpan/podlators/t/data/basic.clr (renamed from cpan/podlators/t/basic.clr)0
-rw-r--r--cpan/podlators/t/data/basic.man (renamed from cpan/podlators/t/basic.man)0
-rw-r--r--cpan/podlators/t/data/basic.ovr (renamed from cpan/podlators/t/basic.ovr)0
-rw-r--r--cpan/podlators/t/data/basic.pod (renamed from cpan/podlators/t/basic.pod)0
-rw-r--r--cpan/podlators/t/data/basic.txt (renamed from cpan/podlators/t/basic.txt)0
-rw-r--r--cpan/podlators/t/data/perl.conf7
-rw-r--r--cpan/podlators/t/data/snippets/README45
-rw-r--r--cpan/podlators/t/data/snippets/man/cpp20
-rw-r--r--cpan/podlators/t/data/snippets/man/utf8-nonbreaking17
-rw-r--r--cpan/podlators/t/data/snippets/man/utf8-verbatim31
-rw-r--r--cpan/podlators/t/data/snippets/text/cpp20
-rw-r--r--cpan/podlators/t/data/termcap8
-rw-r--r--cpan/podlators/t/devise-date.t15
-rw-r--r--cpan/podlators/t/docs/pod-spelling.t66
-rw-r--r--cpan/podlators/t/docs/pod.t65
-rw-r--r--cpan/podlators/t/docs/synopsis.t60
-rw-r--r--cpan/podlators/t/filehandle.t110
-rw-r--r--cpan/podlators/t/general/basic.t108
-rw-r--r--cpan/podlators/t/general/filehandle.t82
-rw-r--r--cpan/podlators/t/general/pod-parser.t83
-rw-r--r--cpan/podlators/t/lib/Test/Podlators.pm510
-rw-r--r--cpan/podlators/t/lib/Test/RRA.pm235
-rw-r--r--cpan/podlators/t/lib/Test/RRA/Config.pm215
-rw-r--r--cpan/podlators/t/man-heading.t90
-rw-r--r--cpan/podlators/t/man-options.t286
-rw-r--r--cpan/podlators/t/man-perlio.t135
-rw-r--r--cpan/podlators/t/man-utf8.t133
-rw-r--r--cpan/podlators/t/man/basic.t (renamed from cpan/podlators/t/man.t)11
-rw-r--r--cpan/podlators/t/man/devise-date.t56
-rw-r--r--cpan/podlators/t/man/devise-title.t32
-rw-r--r--cpan/podlators/t/man/empty.t (renamed from cpan/podlators/t/man-empty.t)2
-rw-r--r--cpan/podlators/t/man/heading.t94
-rw-r--r--cpan/podlators/t/man/options.t273
-rw-r--r--cpan/podlators/t/man/utf8-io.t50
-rw-r--r--cpan/podlators/t/parselink/basic.t (renamed from cpan/podlators/t/parselink.t)2
-rw-r--r--cpan/podlators/t/pod-parser.t78
-rw-r--r--cpan/podlators/t/pod-spelling.t75
-rw-r--r--cpan/podlators/t/pod.t14
-rw-r--r--cpan/podlators/t/style/minimum-version.t47
-rw-r--r--cpan/podlators/t/style/module-version.t315
-rw-r--r--cpan/podlators/t/style/strict.t56
-rw-r--r--cpan/podlators/t/text/basic.t (renamed from cpan/podlators/t/text.t)2
-rw-r--r--cpan/podlators/t/text/color.t (renamed from cpan/podlators/t/color.t)2
-rw-r--r--cpan/podlators/t/text/empty.t (renamed from cpan/podlators/t/text-empty.t)2
-rw-r--r--cpan/podlators/t/text/encoding.t (renamed from cpan/podlators/t/text-encoding.t)33
-rw-r--r--cpan/podlators/t/text/options.t (renamed from cpan/podlators/t/text-options.t)19
-rw-r--r--cpan/podlators/t/text/overstrike.t (renamed from cpan/podlators/t/overstrike.t)2
-rw-r--r--cpan/podlators/t/text/perlio.t (renamed from cpan/podlators/t/text-perlio.t)24
-rw-r--r--cpan/podlators/t/text/termcap.t (renamed from cpan/podlators/t/termcap.t)26
-rw-r--r--cpan/podlators/t/text/utf8.t (renamed from cpan/podlators/t/text-utf8.t)22
52 files changed, 2601 insertions, 1094 deletions
diff --git a/cpan/podlators/t/basic.t b/cpan/podlators/t/basic.t
deleted file mode 100644
index 4103ed6e19..0000000000
--- a/cpan/podlators/t/basic.t
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/usr/bin/perl -w
-#
-# basic.t -- Basic tests for podlators.
-#
-# Copyright 2001, 2002, 2004, 2006, 2009, 2012
-# Russ Allbery <rra@stanford.edu>
-#
-# This program is free software; you may redistribute it and/or modify it
-# under the same terms as Perl itself.
-
-BEGIN {
- chdir 't' if -d 't';
- if ($ENV{PERL_CORE}) {
- @INC = '../lib';
- }
- unshift (@INC, '../blib/lib');
- $| = 1;
-}
-
-use strict;
-
-use Test::More tests => 15;
-
-BEGIN {
- use_ok ('Pod::Man');
- use_ok ('Pod::Text');
- use_ok ('Pod::Text::Overstrike');
- use_ok ('Pod::Text::Termcap');
-}
-
-# Find the path to the test source files. This requires some fiddling when
-# these tests are run as part of Perl core.
-sub source_path {
- my $file = shift;
- if ($ENV{PERL_CORE}) {
- require File::Spec;
- my $updir = File::Spec->updir;
- my $dir = File::Spec->catdir ($updir, 'lib', 'Pod', 't');
- return File::Spec->catfile ($dir, $file);
- } else {
- return $file;
- }
-}
-
-# Hard-code a few values to try to get reproducible results.
-$ENV{COLUMNS} = 80;
-$ENV{TERM} = 'xterm';
-$ENV{TERMCAP} = 'xterm:co=80:do=^J:md=\E[1m:us=\E[4m:me=\E[m';
-
-# Map of translators to file extensions to find the formatted output to
-# compare against.
-my %translators = ('Pod::Man' => 'man',
- 'Pod::Text' => 'txt',
- 'Pod::Text::Color' => 'clr',
- 'Pod::Text::Overstrike' => 'ovr',
- 'Pod::Text::Termcap' => 'cap');
-
-# Set default options to match those of pod2man and pod2text.
-our %options = (sentence => 0);
-
-for my $module (sort keys %translators) {
- SKIP: {
- if ($module eq 'Pod::Text::Color') {
- eval { require Term::ANSIColor };
- skip 'Term::ANSIColor not found', 3 if $@;
- require_ok ('Pod::Text::Color');
- }
- my $parser = $module->new (%options);
- isa_ok ($parser, $module, 'Parser object');
-
- # For Pod::Man, strip out the autogenerated header up to the .TH title
- # line. That means that we don't check those things; oh well. The
- # header changes with each version change or touch of the input file.
- open (OUT, "> out$$.tmp") or die "Cannot create out$$.tmp: $!\n";
- $parser->parse_from_file (source_path ('basic.pod'), \*OUT);
- close OUT;
- if ($module eq 'Pod::Man') {
- open (TMP, "out$$.tmp") or die "Cannot open out$$.tmp: $!\n";
- open (OUTPUT, "> out$$.$translators{$module}")
- or die "Cannot create out$$.$translators{$module}: $!\n";
- local $_;
- while (<TMP>) { last if /^\.nh/ }
- print OUTPUT while <TMP>;
- close OUTPUT;
- close TMP;
- 1 while unlink "out$$.tmp";
- } else {
- rename ("out$$.tmp", "out$$.$translators{$module}")
- or die "Cannot rename out$$.tmp: $!\n";
- }
-
- # Slurp the output and expected output and compare them.
- my ($master, $output);
- {
- local $/;
- open (MASTER, source_path ("basic.$translators{$module}"))
- or die "Cannot open basic.$translators{$module}: $!\n";
- open (OUTPUT, "out$$.$translators{$module}")
- or die "Cannot open out$$.$translators{$module}: $!\n";
- $master = <MASTER>;
- $output = <OUTPUT>;
- close MASTER;
- close OUTPUT;
- }
-
- # OS/390 is EBCDIC, which uses a different character for ESC
- # apparently. Try to convert so that the test still works.
- if ($^O eq 'os390' and $module eq 'Pod::Text::Termcap') {
- $output =~ tr/\033/\047/;
- }
- if (ok ($master eq $output, "$module output is correct")) {
- 1 while unlink "out$$.$translators{$module}";
- } else {
- diag ("Non-matching output left in out$$.$translators{$module}\n");
- }
- }
-}
diff --git a/cpan/podlators/t/basic.cap b/cpan/podlators/t/data/basic.cap
index 20fc1e561c..20fc1e561c 100644
--- a/cpan/podlators/t/basic.cap
+++ b/cpan/podlators/t/data/basic.cap
diff --git a/cpan/podlators/t/basic.clr b/cpan/podlators/t/data/basic.clr
index f98857187a..f98857187a 100644
--- a/cpan/podlators/t/basic.clr
+++ b/cpan/podlators/t/data/basic.clr
diff --git a/cpan/podlators/t/basic.man b/cpan/podlators/t/data/basic.man
index 43874b6e87..43874b6e87 100644
--- a/cpan/podlators/t/basic.man
+++ b/cpan/podlators/t/data/basic.man
diff --git a/cpan/podlators/t/basic.ovr b/cpan/podlators/t/data/basic.ovr
index bb124a0bd4..bb124a0bd4 100644
--- a/cpan/podlators/t/basic.ovr
+++ b/cpan/podlators/t/data/basic.ovr
diff --git a/cpan/podlators/t/basic.pod b/cpan/podlators/t/data/basic.pod
index 949b3a8886..949b3a8886 100644
--- a/cpan/podlators/t/basic.pod
+++ b/cpan/podlators/t/data/basic.pod
diff --git a/cpan/podlators/t/basic.txt b/cpan/podlators/t/data/basic.txt
index 986e98a1cd..986e98a1cd 100644
--- a/cpan/podlators/t/basic.txt
+++ b/cpan/podlators/t/data/basic.txt
diff --git a/cpan/podlators/t/data/perl.conf b/cpan/podlators/t/data/perl.conf
new file mode 100644
index 0000000000..8b76b1c8fb
--- /dev/null
+++ b/cpan/podlators/t/data/perl.conf
@@ -0,0 +1,7 @@
+# Configuration for Perl tests. -*- perl -*-
+
+# Default minimum version requirement.
+$MINIMUM_VERSION = '5.006';
+
+# File must end with this line.
+1;
diff --git a/cpan/podlators/t/data/snippets/README b/cpan/podlators/t/data/snippets/README
new file mode 100644
index 0000000000..0e7252daa4
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/README
@@ -0,0 +1,45 @@
+The files in this directory are used by the test suite to exercise various
+behavior of Pod::Man or Pod::Text. They use a pseudo-ini-file syntax with
+free-form sections, normally an input and an output section and possibly
+others.
+
+Sections start with the section type in []. The contents are normally
+just free-form. The exception is an [options] section, where the contents
+are key/value pairs, where the key is separated from the value with
+whitespace.
+
+Valid sections are:
+
+ [name]
+ The name of this test for status reporting
+
+ [options]
+ key value
+ key value
+
+ [input]
+ POD input source.
+
+ [output]
+ The results of running some formatter on the input.
+
+ [errors]
+ Errors reported to standard error when running some formatter on the
+ input.
+
+ [exception]
+ The text of an exception (with the file and line number information
+ stripped) thrown by running some formatter on the input.
+
+Files are organized into subdirectories named after the formatter, namely
+man (Pod::Man), text (Pod::Text), color (Pod::Text::Color), overstrike
+(Pod::Text::Overstrike), and termcap (Pod::Text::Termcap).
+
+-----
+
+Copyright 2015 Russ Allbery <rra@cpan.org>
+
+Copying and distribution of this file, with or without modification, are
+permitted in any medium without royalty provided the copyright notice and
+this notice are preserved. This file is offered as-is, without any
+warranty.
diff --git a/cpan/podlators/t/data/snippets/man/cpp b/cpan/podlators/t/data/snippets/man/cpp
new file mode 100644
index 0000000000..177aeeeb89
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/cpp
@@ -0,0 +1,20 @@
+[name]
+Special handling of C++
+
+[input]
+=head1 NAME
+
+gcc - GNU project C and C++ compiler
+
+=head1 C++ NOTES
+
+Other mentions of C++.
+
+=cut
+
+[output]
+.SH "NAME"
+gcc \- GNU project C and C++ compiler
+.SH "\*(C+ NOTES"
+.IX Header " NOTES"
+Other mentions of \*(C+.
diff --git a/cpan/podlators/t/data/snippets/man/utf8-nonbreaking b/cpan/podlators/t/data/snippets/man/utf8-nonbreaking
new file mode 100644
index 0000000000..8198a77ece
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/utf8-nonbreaking
@@ -0,0 +1,17 @@
+[name]
+UTF-8 non-breaking space
+
+[options]
+utf8 1
+
+[input]
+=encoding utf-8
+
+=head1 SE<lt>E<gt> output with UTF-8
+
+This is S<non-breaking output>.
+
+[output]
+.SH "S<> output with UTF\-8"
+.IX Header "S<> output with UTF-8"
+This is non-breaking output.
diff --git a/cpan/podlators/t/data/snippets/man/utf8-verbatim b/cpan/podlators/t/data/snippets/man/utf8-verbatim
new file mode 100644
index 0000000000..0eea4ccb53
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/utf8-verbatim
@@ -0,0 +1,31 @@
+[name]
+UTF-8 handling in verbatim text
+
+[options]
+utf8 1
+
+[input]
+=encoding utf-8
+
+=head1 BEYONCÉ
+
+Beyoncé! Beyoncé! Beyoncé!!
+
+ Beyoncé! Beyoncé!
+ Beyoncé! Beyoncé!
+ Beyoncé! Beyoncé!
+
+Older versions did not convert Beyoncé in verbatim.
+
+[output]
+.SH "BEYONCÉ"
+.IX Header "BEYONCÉ"
+Beyoncé! Beyoncé! Beyoncé!!
+.PP
+.Vb 3
+\& Beyoncé! Beyoncé!
+\& Beyoncé! Beyoncé!
+\& Beyoncé! Beyoncé!
+.Ve
+.PP
+Older versions did not convert Beyoncé in verbatim.
diff --git a/cpan/podlators/t/data/snippets/text/cpp b/cpan/podlators/t/data/snippets/text/cpp
new file mode 100644
index 0000000000..b78877798f
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/text/cpp
@@ -0,0 +1,20 @@
+[name]
+Special handling of C++
+
+[input]
+=head1 NAME
+
+gcc - GNU project C and C++ compiler
+
+=head1 C++ NOTES
+
+Other mentions of C++.
+
+=cut
+
+[output]
+NAME
+ gcc - GNU project C and C++ compiler
+
+C++ NOTES
+ Other mentions of C++.
diff --git a/cpan/podlators/t/data/termcap b/cpan/podlators/t/data/termcap
new file mode 100644
index 0000000000..80948156ca
--- /dev/null
+++ b/cpan/podlators/t/data/termcap
@@ -0,0 +1,8 @@
+# Simple termcap file. -*- conf -*-
+#
+# Term::Cap 1.16 will try to fall back to infocmp or a dumb terminal setting
+# unless termcap_path() finds a path to a termcap file. This is a bug in
+# Term::Cap (see <https://rt.cpan.org/Public/Bug/Display.html?id=96695>), but
+# provide this file anyway to ensure the test suite will still run.
+
+xterm:co=#80:do=^J:md=\E[1m:us=\E[4m:me=\E[m
diff --git a/cpan/podlators/t/devise-date.t b/cpan/podlators/t/devise-date.t
deleted file mode 100644
index 3cce9f5b01..0000000000
--- a/cpan/podlators/t/devise-date.t
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/perl -w
-
-# In order for MakeMaker to build in the core, nothing can use
-# Fcntl which includes POSIX. devise_date()'s use of strftime()
-# was replaced. This tests that it's identical.
-
-use strict;
-
-use Test::More tests => 1;
-
-use Pod::Man;
-use POSIX qw(strftime);
-
-my $parser = Pod::Man->new;
-is $parser->devise_date, strftime("%Y-%m-%d", localtime);
diff --git a/cpan/podlators/t/docs/pod-spelling.t b/cpan/podlators/t/docs/pod-spelling.t
new file mode 100644
index 0000000000..6debd42027
--- /dev/null
+++ b/cpan/podlators/t/docs/pod-spelling.t
@@ -0,0 +1,66 @@
+#!/usr/bin/perl
+#
+# Check for spelling errors in POD documentation.
+#
+# The canonical version of this file is maintained in the rra-c-util package,
+# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2013, 2014
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::More;
+use Test::RRA qw(skip_unless_author use_prereq);
+
+# Only run this test for the module author since the required stopwords are
+# too sensitive to the exact spell-checking program and dictionary.
+skip_unless_author('Spelling tests');
+
+# Load prerequisite modules.
+use_prereq('Test::Spelling');
+
+# Check all POD in the Perl distribution. Add the examples directory if it
+# exists. Also add any files in usr/bin or usr/sbin, which are widely used in
+# Stanford-internal packages.
+my @files = all_pod_files();
+if (-d 'examples') {
+ push(@files, all_pod_files('examples'));
+}
+for my $dir (qw(usr/bin usr/sbin)) {
+ if (-d $dir) {
+ push(@files, glob("$dir/*"));
+ }
+}
+
+# We now have a list of all files to check, so output a plan and run the
+# tests. We can't use all_pod_files_spelling_ok because it refuses to check
+# non-Perl files and Stanford-internal packages have a lot of shell scripts
+# with POD documentation.
+plan tests => scalar(@files);
+for my $file (@files) {
+ pod_file_spelling_ok($file);
+}
diff --git a/cpan/podlators/t/docs/pod.t b/cpan/podlators/t/docs/pod.t
new file mode 100644
index 0000000000..674ce30094
--- /dev/null
+++ b/cpan/podlators/t/docs/pod.t
@@ -0,0 +1,65 @@
+#!/usr/bin/perl
+#
+# Check all POD documents for POD formatting errors.
+#
+# The canonical version of this file is maintained in the rra-c-util package,
+# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2012, 2013, 2014
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::More;
+use Test::RRA qw(skip_unless_automated use_prereq);
+
+# Skip this test for normal user installs, although pod2man may still fail.
+skip_unless_automated('POD syntax tests');
+
+# Load prerequisite modules.
+use_prereq('Test::Pod');
+
+# Check all POD in the Perl distribution. Add the examples directory if it
+# exists. Also add any files in usr/bin or usr/sbin, which are widely used in
+# Stanford-internal packages.
+my @files = all_pod_files();
+if (-d 'examples') {
+ push(@files, all_pod_files('examples'));
+}
+for my $dir (qw(usr/bin usr/sbin)) {
+ if (-d $dir) {
+ push(@files, glob("$dir/*"));
+ }
+}
+
+# We now have a list of all files to check, so output a plan and run the
+# tests. We can't use all_pod_files_ok because it refuses to check non-Perl
+# files and Stanford-internal packages have a lot of shell scripts with POD
+# documentation.
+plan tests => scalar(@files);
+for my $file (@files) {
+ pod_file_ok($file);
+}
diff --git a/cpan/podlators/t/docs/synopsis.t b/cpan/podlators/t/docs/synopsis.t
new file mode 100644
index 0000000000..3d5b44a20f
--- /dev/null
+++ b/cpan/podlators/t/docs/synopsis.t
@@ -0,0 +1,60 @@
+#!/usr/bin/perl
+#
+# Check the SYNOPSIS section of the documentation for syntax errors.
+#
+# The canonical version of this file is maintained in the rra-c-util package,
+# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2013, 2014
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::More;
+use Test::RRA qw(skip_unless_automated use_prereq);
+
+# Skip for normal user installs since this doesn't affect functionality.
+skip_unless_automated('Synopsis syntax tests');
+
+# Load prerequisite modules.
+use_prereq('Perl::Critic::Utils');
+use_prereq('Test::Synopsis');
+
+# The default Test::Synopsis all_synopsis_ok() function requires that the
+# module be in a lib directory. Use Perl::Critic::Utils to find the modules
+# in blib, or lib if it doesn't exist. However, strip out anything in
+# blib/script, since scripts use a different SYNOPSIS syntax.
+my @files = Perl::Critic::Utils::all_perl_files('blib');
+@files = grep { !m{blib/script/}xms } @files;
+if (!@files) {
+ @files = Perl::Critic::Utils::all_perl_files('lib');
+}
+plan tests => scalar @files;
+
+# Run the actual tests.
+for my $file (@files) {
+ synopsis_ok($file);
+}
diff --git a/cpan/podlators/t/filehandle.t b/cpan/podlators/t/filehandle.t
deleted file mode 100644
index 8c074162a2..0000000000
--- a/cpan/podlators/t/filehandle.t
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/usr/bin/perl -w
-#
-# filehandle.t -- Test the parse_from_filehandle interface.
-#
-# Copyright 2006, 2009, 2012 by Russ Allbery <rra@stanford.edu>
-#
-# This program is free software; you may redistribute it and/or modify it
-# under the same terms as Perl itself.
-
-BEGIN {
- chdir 't' if -d 't';
- if ($ENV{PERL_CORE}) {
- @INC = '../lib';
- }
- unshift (@INC, '../blib/lib');
- $| = 1;
-}
-
-use strict;
-
-use Test::More tests => 6;
-
-BEGIN {
- use_ok ('Pod::Man');
- use_ok ('Pod::Text');
-}
-
-my $man = Pod::Man->new;
-isa_ok ($man, 'Pod::Man', 'Pod::Man parser object');
-my $text = Pod::Text->new;
-isa_ok ($text, 'Pod::Text', 'Pod::Text parser object');
-while (<DATA>) {
- next until $_ eq "###\n";
- open (TMP, "> tmp$$.pod") or die "Cannot create tmp.pod: $!\n";
- while (<DATA>) {
- last if $_ eq "###\n";
- print TMP $_;
- }
- close TMP;
-
- # Test Pod::Man output.
- open (IN, "< tmp$$.pod") or die "Cannot open tmp$$.pod: $!\n";
- open (OUT, "> out$$.tmp") or die "Cannot create out$$.tmp: $!\n";
- $man->parse_from_filehandle (\*IN, \*OUT);
- close IN;
- close OUT;
- open (OUT, "out$$.tmp") or die "Cannot open out$$.tmp: $!\n";
- while (<OUT>) { last if /^\.nh/ }
- my $output;
- {
- local $/;
- $output = <OUT>;
- }
- close OUT;
- my $expected = '';
- while (<DATA>) {
- last if $_ eq "###\n";
- $expected .= $_;
- }
- is ($output, $expected, 'Pod::Man output is correct');
-
- # Test Pod::Text output.
- open (IN, "< tmp$$.pod") or die "Cannot open tmp$$.pod: $!\n";
- open (OUT, "> out$$.tmp") or die "Cannot create out$$.tmp: $!\n";
- $text->parse_from_filehandle (\*IN, \*OUT);
- close IN;
- close OUT;
- open (OUT, "out$$.tmp") or die "Cannot open out$$.tmp: $!\n";
- {
- local $/;
- $output = <OUT>;
- }
- close OUT;
- 1 while unlink ("tmp$$.pod", "out$$.tmp");
- $expected = '';
- while (<DATA>) {
- last if $_ eq "###\n";
- $expected .= $_;
- }
- is ($output, $expected, 'Pod::Text output is correct');
-}
-
-# Below the marker are bits of POD, corresponding expected nroff output, and
-# corresponding expected text output. The input and output are separated by
-# lines containing only ###.
-
-__DATA__
-
-###
-=head1 NAME
-
-gcc - GNU project C and C++ compiler
-
-=head1 C++ NOTES
-
-Other mentions of C++.
-###
-.SH "NAME"
-gcc \- GNU project C and C++ compiler
-.SH "\*(C+ NOTES"
-.IX Header " NOTES"
-Other mentions of \*(C+.
-###
-NAME
- gcc - GNU project C and C++ compiler
-
-C++ NOTES
- Other mentions of C++.
-
-###
diff --git a/cpan/podlators/t/general/basic.t b/cpan/podlators/t/general/basic.t
new file mode 100644
index 0000000000..9b676cc8c5
--- /dev/null
+++ b/cpan/podlators/t/general/basic.t
@@ -0,0 +1,108 @@
+#!/usr/bin/perl
+#
+# Basic tests for podlators.
+#
+# This test case uses a single sample file and runs it through all available
+# formatting modules, comparing the results to known-good output that's
+# included with the package. This provides a general sanity check that the
+# modules are working properly.
+#
+# New regression tests and special cases should probably not be added to the
+# sample input file, since updating all the output files is painful. Instead,
+# the machinery to run small POD snippets through the specific formatter being
+# tested should probably be used instead.
+#
+# Copyright 2001, 2002, 2004, 2006, 2009, 2012, 2014, 2015
+# Russ Allbery <rra@cpan.org>
+#
+# This program is free software; you may redistribute it and/or modify it
+# under the same terms as Perl itself.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use File::Spec;
+use Test::More tests => 15;
+use Test::Podlators qw(slurp);
+
+# Check that all the modules can be loaded.
+BEGIN {
+ use_ok('Pod::Man');
+ use_ok('Pod::Text');
+ use_ok('Pod::Text::Color');
+ use_ok('Pod::Text::Overstrike');
+ use_ok('Pod::Text::Termcap');
+}
+
+# Flush output, since otherwise our diag messages come after other tests.
+local $| = 1;
+
+# Hard-code configuration for Term::Cap to get predictable results.
+local $ENV{COLUMNS} = 80;
+local $ENV{TERM} = 'xterm';
+local $ENV{TERMPATH} = File::Spec->catfile('t', 'data', 'termcap');
+local $ENV{TERMCAP} = 'xterm:co=#80:do=^J:md=\\E[1m:us=\\E[4m:me=\\E[m';
+
+# Find the source of the test file.
+my $INPUT = File::Spec->catfile('t', 'data', 'basic.pod');
+
+# Map of translators to the file containing the formatted output to compare
+# against.
+my %OUTPUT = (
+ 'Pod::Man' => File::Spec->catfile('t', 'data', 'basic.man'),
+ 'Pod::Text' => File::Spec->catfile('t', 'data', 'basic.txt'),
+ 'Pod::Text::Color' => File::Spec->catfile('t', 'data', 'basic.clr'),
+ 'Pod::Text::Overstrike' => File::Spec->catfile('t', 'data', 'basic.ovr'),
+ 'Pod::Text::Termcap' => File::Spec->catfile('t', 'data', 'basic.cap'),
+);
+
+# Options to pass to all formatting modules. Match the pod2text default.
+my @OPTIONS = (sentence => 0);
+
+# Walk through teach of the modules and format the sample file, checking to
+# ensure the results match the pre-generated file.
+for my $module (sort keys %OUTPUT) {
+ my $parser = $module->new(@OPTIONS);
+ isa_ok($parser, $module, 'parser object');
+
+ # Run the formatting module. Store the output into a Perl variable
+ # instead of a file.
+ my $got;
+ $parser->output_string(\$got);
+ $parser->parse_file($INPUT);
+
+ # If the test module is Pod::Man, strip off the header. This test does
+ # not attempt to compare it, since it contains version numbers that
+ # change.
+ if ($module eq 'Pod::Man') {
+ $got =~ s{ \A .* \n [.]nh \n }{}xms;
+ }
+
+ # OS/390 is EBCDIC, which apparently uses a different character for ESC.
+ # Try to convert so that the test still works.
+ if ($^O eq 'os390' && $module eq 'Pod::Text::Termcap') {
+ $got =~ tr{\033}{\047};
+ }
+
+ # Check the output. If it doesn't match, save the erroneous output in a
+ # file for later inspection.
+ my $expected = slurp($OUTPUT{$module});
+ if (!ok($got eq $expected, "$module output is correct")) {
+ my ($suffix) = ($OUTPUT{$module} =~ m{ [.] ([^.]+) \z }xms);
+ my $tmpdir = File::Spec->catdir('t', 'tmp');
+ if (!-d $tmpdir) {
+ mkdir($tmpdir, 0777);
+ }
+ my $outfile = File::Spec->catfile('t', 'tmp', "out$$.$suffix");
+ open(my $output, '>', $outfile)
+ or BAIL_OUT("cannot create $outfile for failed output: $!");
+ print {$output} $got
+ or BAIL_OUT("cannot write failed output to $outfile: $!");
+ close($output)
+ or BAIL_OUT("cannot write failed output to $outfile: $!");
+ diag("Non-matching output left in $outfile");
+ }
+}
diff --git a/cpan/podlators/t/general/filehandle.t b/cpan/podlators/t/general/filehandle.t
new file mode 100644
index 0000000000..f726db23fe
--- /dev/null
+++ b/cpan/podlators/t/general/filehandle.t
@@ -0,0 +1,82 @@
+#!/usr/bin/perl
+#
+# Test the parse_from_filehandle method.
+#
+# This backward compatibility interface is not provided by Pod::Simple, so
+# Pod::Man and Pod::Text had to implement it directly. Test to be sure it's
+# working properly.
+#
+# Copyright 2006, 2009, 2012, 2014, 2015 Russ Allbery <rra@cpan.org>
+#
+# This program is free software; you may redistribute it and/or modify it
+# under the same terms as Perl itself.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use File::Spec;
+use Test::More tests => 4;
+use Test::Podlators qw(read_snippet slurp);
+
+# Ensure the modules load properly.
+BEGIN {
+ use_ok('Pod::Man');
+ use_ok('Pod::Text');
+}
+
+# Create a temporary directory to use for output, but don't fail if it already
+# exists. If we failed to create it, we'll fail later on. We unfortunately
+# have to create files on disk to easily create file handles for testing.
+my $tmpdir = File::Spec->catdir('t', 'tmp');
+if (!-d $tmpdir) {
+ mkdir($tmpdir, 0777);
+}
+
+# Load the tests.
+my $man_data_ref = read_snippet('man/cpp');
+my $text_data_ref = read_snippet('text/cpp');
+
+# Write the POD source to a temporary file for the input file handle.
+my $infile = File::Spec->catfile('t', 'tmp', "tmp$$.pod");
+open(my $input, '>', $infile) or BAIL_OUT("cannot create $infile: $!");
+print {$input} $man_data_ref->{input}
+ or BAIL_OUT("cannot write to $infile: $!");
+close($input) or BAIL_OUT("cannot write to $infile: $!");
+
+# Write the Pod::Man output to a file.
+my $outfile = File::Spec->catfile('t', 'tmp', "tmp$$.man");
+open($input, '<', $infile) or BAIL_OUT("cannot open $infile: $!");
+open(my $output, '>', $outfile) or BAIL_OUT("cannot open $outfile: $!");
+my $parser = Pod::Man->new;
+$parser->parse_from_filehandle($input, $output);
+close($input) or BAIL_OUT("cannot read from $infile: $!");
+close($output) or BAIL_OUT("cannot write to $outfile: $!");
+
+# Read the output back in and compare it.
+my $got = slurp($outfile, 'man');
+is($got, $man_data_ref->{output}, 'Pod::Man output');
+
+# Clean up the temporary output file.
+unlink($outfile);
+
+# Now, do the same drill with Pod::Text. Parse the input to a temporary file.
+$outfile = File::Spec->catfile('t', 'tmp', "tmp$$.txt");
+open($input, '<', $infile) or BAIL_OUT("cannot open $infile: $!");
+open($output, '>', $outfile) or BAIL_OUT("cannot open $outfile: $!");
+$parser = Pod::Text->new;
+$parser->parse_from_filehandle($input, $output);
+close($input) or BAIL_OUT("cannot read from $infile: $!");
+close($output) or BAIL_OUT("cannot write to $outfile: $!");
+
+# Read the output back in and compare it. Pod::Text adds a trailing blank
+# line that we need to strip out.
+$got = slurp($outfile);
+$got =~ s{ \n \s+ \z }{\n}xms;
+is($got, $text_data_ref->{output}, 'Pod::Text output');
+
+# Clean up temporary files.
+unlink($infile, $outfile);
+rmdir($tmpdir);
diff --git a/cpan/podlators/t/general/pod-parser.t b/cpan/podlators/t/general/pod-parser.t
new file mode 100644
index 0000000000..b8adc88503
--- /dev/null
+++ b/cpan/podlators/t/general/pod-parser.t
@@ -0,0 +1,83 @@
+#!/usr/bin/perl -w
+#
+# Tests for backward compatibility with Pod::Parser.
+#
+# Copyright 2006, 2008, 2009, 2012, 2015 by Russ Allbery <rra@cpan.org>
+#
+# This program is free software; you may redistribute it and/or modify it
+# under the same terms as Perl itself.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use File::Spec;
+use Test::More tests => 7;
+use Test::Podlators qw(slurp);
+
+# Ensure the modules load properly.
+BEGIN {
+ use_ok('Pod::Man');
+ use_ok('Pod::Text');
+}
+
+# Create a temporary directory to use for output, but don't fail if it already
+# exists. If we failed to create it, we'll fail later on. We unfortunately
+# have to create files on disk to easily create file handles for testing.
+my $tmpdir = File::Spec->catdir('t', 'tmp');
+if (!-d $tmpdir) {
+ mkdir($tmpdir, 0777);
+}
+
+# Create some test POD to use to test the -cutting option.
+my $infile = File::Spec->catfile('t', 'tmp', "tmp$$.pod");
+open(my $input, '>', $infile) or BAIL_OUT("cannot create $infile: $!");
+print {$input} "Some random B<text>.\n"
+ or BAIL_OUT("cannot write to $infile: $!");
+close($input) or BAIL_OUT("cannot write to $infile: $!");
+
+# Test the -cutting option with Pod::Man.
+my $parser = Pod::Man->new;
+isa_ok($parser, 'Pod::Man', 'Pod::Man parser object');
+my $outfile = File::Spec->catfile('t', 'tmp', "tmp$$.man");
+open(my $output, '>', $outfile) or BAIL_OUT("cannot open $outfile: $!");
+$parser->parse_from_file({ -cutting => 0 }, $infile, $output);
+close($output) or BAIL_OUT("cannot write to $outfile: $!");
+my $got = slurp($outfile, 'man');
+is($got, "Some random \\fBtext\\fR.\n", 'Pod::Man -cutting output');
+unlink($outfile);
+
+# Likewise for Pod::Text.
+$parser = Pod::Text->new;
+isa_ok($parser, 'Pod::Text', 'Pod::Text parser object');
+$outfile = File::Spec->catfile('t', 'tmp', "tmp$$.txt");
+open($output, '>', $outfile) or BAIL_OUT("cannot open $outfile: $!");
+$parser->parse_from_file({ -cutting => 0 }, $infile, $output);
+close($output) or BAIL_OUT("cannot write to $outfile: $!");
+$got = slurp($outfile);
+is($got, " Some random text.\n\n", 'Pod::Text -cutting output');
+unlink($outfile);
+
+# Rewrite the input file to be fully valid POD since we won't use -cutting.
+unlink($infile);
+open($input, '>', $infile) or BAIL_OUT("cannot create $infile: $!");
+print {$input} "=pod\n\nSome random B<text>.\n"
+ or BAIL_OUT("cannot write to $infile: $!");
+close($input) or BAIL_OUT("cannot write to $infile: $!");
+
+# Now test the pod2text function with a single output. This will send the
+# results to standard output, so we need to redirect that to a file.
+open($output, '>', $outfile) or BAIL_OUT("cannot open $outfile: $!");
+open(my $save_stdout, '>&', STDOUT) or BAIL_OUT("cannot dup stdout: $!");
+open(STDOUT, '>&', $output) or BAIL_OUT("cannot redirect stdout: $!");
+pod2text($infile);
+close($output) or BAIL_OUT("cannot write to $outfile: $!");
+open(STDOUT, '>&', $save_stdout) or BAIL_OUT("cannot fix stdout: $!");
+close($save_stdout) or BAIL_OUT("cannot close saved stdout: $!");
+$got = slurp($outfile);
+is($got, " Some random text.\n\n", 'Pod::Text pod2text function');
+
+# Clean up.
+unlink($infile, $outfile);
diff --git a/cpan/podlators/t/lib/Test/Podlators.pm b/cpan/podlators/t/lib/Test/Podlators.pm
new file mode 100644
index 0000000000..77945574ec
--- /dev/null
+++ b/cpan/podlators/t/lib/Test/Podlators.pm
@@ -0,0 +1,510 @@
+# Helper functions to test the podlators distribution.
+#
+# This module is an internal implementation detail of the podlators test
+# suite. It provides some supporting functions to make it easier to write
+# tests.
+#
+# Copyright 2015 Russ Allbery <rra@cpan.org>
+#
+# This program is free software; you may redistribute it and/or modify it
+# under the same terms as Perl itself.
+
+package Test::Podlators;
+
+use 5.006;
+use strict;
+use warnings;
+
+use Encode qw(decode encode);
+use Exporter;
+use File::Spec;
+use Test::More;
+
+# For Perl 5.006 compatibility.
+## no critic (ClassHierarchies::ProhibitExplicitISA)
+
+# Declare variables that should be set in BEGIN for robustness.
+our (@EXPORT_OK, @ISA, $VERSION);
+
+# Set $VERSION and everything export-related in a BEGIN block for robustness
+# against circular module loading (not that we load any modules, but
+# consistency is good).
+BEGIN {
+ @ISA = qw(Exporter);
+ $VERSION = '2.00';
+ @EXPORT_OK = qw(
+ read_snippet read_test_data slurp test_snippet test_snippet_with_io
+ );
+}
+
+# The file handle used to capture STDERR while we mess with file descriptors.
+my $OLD_STDERR;
+
+# The file name used to capture standard error output.
+my $SAVED_STDERR;
+
+# Internal function to clean up the standard error output file. The "1 while"
+# construct is for VMS, in case there are multiple versions of the file.
+sub _stderr_cleanup {
+ if ($SAVED_STDERR && -f $SAVED_STDERR) {
+ unlink($SAVED_STDERR);
+ }
+ my $tmpdir = File::Spec->catdir('t', 'tmp');
+ if (-d $tmpdir) {
+ rmdir($tmpdir);
+ }
+ return;
+}
+
+# Remove saved standard error on exit, even if we have an abnormal exit.
+END {
+ _stderr_cleanup();
+}
+
+# Internal function to redirect stderr to a file. Stores the name in
+# $SAVED_STDERR.
+sub _stderr_save {
+ my $tmpdir = File::Spec->catdir('t', 'tmp');
+ if (!-d $tmpdir) {
+ mkdir('t/tmp', 0777) or BAIL_OUT("cannot create t/tmp: $!");
+ }
+ my $path = File::Spec->catfile($tmpdir, "out$$.err");
+
+ ## no critic(InputOutput::RequireBriefOpen)
+ open($OLD_STDERR, '>&', STDERR) or BAIL_OUT("cannot dup STDERR: $!");
+ open(STDERR, '>', $path) or BAIL_OUT("cannot redirect STDERR: $!");
+ ## use critic
+
+ $SAVED_STDERR = $path;
+ return;
+}
+
+# Internal function to restore stderr.
+#
+# Returns: The contents of the stderr file.
+sub _stderr_restore {
+ return if !$SAVED_STDERR;
+ close(STDERR) or BAIL_OUT("cannot close STDERR: $!");
+ open(STDERR, '>&', $OLD_STDERR) or BAIL_OUT("cannot dup STDERR: $!");
+ close($OLD_STDERR) or BAIL_OUT("cannot close redirected STDERR: $!");
+ my $stderr = slurp($SAVED_STDERR);
+ _stderr_cleanup();
+ return $stderr;
+}
+
+# Read one test snippet from the provided relative file name and return it.
+# For the format, see t/data/snippets/README.
+#
+# $path - Relative path to read test data from
+#
+# Returns: Reference to hash of test data with the following keys:
+# name - Name of the test for status reporting
+# options - Hash of options
+# input - The input block of the test data
+# output - The output block of the test data
+# errors - Expected errors
+# exception - Text of exception (with file and line stripped)
+sub read_snippet {
+ my ($path) = @_;
+ $path = File::Spec->catfile('t', 'data', 'snippets', $path);
+ my %data;
+
+ # Read the sections and store them in the %data hash.
+ my ($line, $section);
+ open(my $fh, '<', $path) or BAIL_OUT("cannot open $path: $!");
+ while (defined($line = <$fh>)) {
+ $line = decode('UTF-8', $line);
+ if ($line =~ m{ \A \s* \[ (\S+) \] \s* \z }xms) {
+ $section = $1;
+ } elsif ($section) {
+ $data{$section} ||= q{};
+ $data{$section} .= $line;
+ }
+ }
+ close($fh) or BAIL_OUT("cannot close $path: $!");
+
+ # Strip trailing blank lines from all sections.
+ for my $section (keys %data) {
+ $data{$section} =~ s{ \n\s+ \z }{\n}xms;
+ }
+
+ # Clean up the name section by removing newlines and extra space.
+ if ($data{name}) {
+ $data{name} =~ s{ \A \s+ }{}xms;
+ $data{name} =~ s{ \s+ \z }{}xms;
+ $data{name} =~ s{ \s+ }{ }xmsg;
+ }
+
+ # Turn the options section into a hash.
+ if ($data{options}) {
+ my @lines = split(m{ \n }xms, $data{options});
+ delete $data{options};
+ for my $optline (@lines) {
+ next if $optline !~ m{ \S }xms;
+ my ($option, $value) = split(q{ }, $optline, 2);
+ if (defined($value)) {
+ chomp($value);
+ } else {
+ $value = q{};
+ }
+ $data{options}{$option} = $value;
+ }
+ }
+
+ # Return the results.
+ return \%data;
+}
+
+# Read one set of test data from the provided file handle and return it.
+# There are several different possible formats, which are specified by the
+# format option.
+#
+# The data read from the file handle will be ignored until a line consisting
+# solely of "###" is found. Then, two or more blocks separated by "###" are
+# read, ending with another line of "###". There will always be at least an
+# input and an output block, and may be more blocks based on the format
+# configuration.
+#
+# $fh - File handle to read the data from
+# $format_ref - Reference to a hash of options describing the data
+# errors - Set to true to read expected errors after the output section
+# options - Set to true to read a hash of options as the first data block
+#
+# Returns: Reference to hash of test data with the following keys:
+# input - The input block of the test data
+# output - The output block of the test data
+# errors - Expected errors if errors was set in $format_ref
+# options - Hash of options if options was set in $format_ref
+# or returns undef if no more test data is found.
+sub read_test_data {
+ my ($fh, $format_ref) = @_;
+ $format_ref ||= {};
+ my %data;
+
+ # Find the first block of test data.
+ my $line;
+ while (defined($line = <$fh>)) {
+ last if $line eq "###\n";
+ }
+ if (!defined($line)) {
+ return;
+ }
+
+ # If the format contains the options key, read the options into a hash.
+ if ($format_ref->{options}) {
+ while (defined($line = <$fh>)) {
+ last if $line eq "###\n";
+ my ($option, $value) = split(q{ }, $line, 2);
+ if (defined($value)) {
+ chomp($value);
+ } else {
+ $value = q{};
+ }
+ $data{options}{$option} = $value;
+ }
+ }
+
+ # Read the input and output sections.
+ my @sections = qw(input output);
+ if ($format_ref->{errors}) {
+ push(@sections, 'errors');
+ }
+ for my $key (@sections) {
+ $data{$key} = q{};
+ while (defined($line = <$fh>)) {
+ last if $line eq "###\n";
+ $data{$key} .= $line;
+ }
+ }
+ return \%data;
+}
+
+# Slurp output data back from a file handle. It would be nice to use
+# Perl6::Slurp, but this is a core module, so we have to implement our own
+# wheels. BAIL_OUT is called on any failure to read the file.
+#
+# $file - File to read
+# $strip - If set to "man", strip out the Pod::Man header
+#
+# Returns: Contents of the file, possibly stripped
+sub slurp {
+ my ($file, $strip) = @_;
+ open(my $fh, '<', $file) or BAIL_OUT("cannot open $file: $!");
+
+ # If told to strip the man header, do so.
+ if (defined($strip) && $strip eq 'man') {
+ while (defined(my $line = <$fh>)) {
+ last if $line eq ".nh\n";
+ }
+ }
+
+ # Read the rest of the file and return it.
+ my $data = do { local $/ = undef; <$fh> };
+ close($fh) or BAIL_OUT("cannot read from $file: $!");
+ return $data;
+}
+
+# Test a formatter on a particular POD snippet. This does all the work of
+# loading the snippet, creating the formatter, running it, and checking the
+# results, and reports those results with Test::More.
+#
+# $class - Class name of the formatter, as a string
+# $snippet - Path to the snippet file defining the test
+sub test_snippet {
+ my ($class, $snippet) = @_;
+ my $data_ref = read_snippet($snippet);
+
+ # Create the formatter object.
+ my $parser = $class->new(%{ $data_ref->{options} }, name => 'TEST');
+ isa_ok($parser, $class, 'Parser object');
+
+ # Save stderr to a temporary file and then run the parser, storing the
+ # output into a Perl variable.
+ my $errors = _stderr_save();
+ my $got;
+ $parser->output_string(\$got);
+ eval { $parser->parse_string_document($data_ref->{input}) };
+ my $exception = $@;
+ my $stderr = _stderr_restore();
+
+ # If we were testing Pod::Man, strip off everything prior to .nh from the
+ # output so that we aren't testing the generated header.
+ if ($class eq 'Pod::Man') {
+ $got =~ s{ \A .* \n [.]nh \n }{}xms;
+ }
+
+ # Check the output, errors, and any exception.
+ is($got, $data_ref->{output}, "$data_ref->{name}: output");
+ if ($data_ref->{errors}) {
+ is($stderr, $data_ref->{errors}, "$data_ref->{name}: errors");
+ }
+ if ($data_ref->{exception} || $exception) {
+ if ($exception) {
+ $exception =~ s{ [ ] at [ ] .* }{}xms;
+ }
+ is($exception, $data_ref->{exception}, "$data_ref->{name}: exception");
+ }
+ return;
+}
+
+# Test a formatter with I/O streams on a particular POD snippet. This does
+# all the work of loading the snippet, creating the formatter, running it, and
+# checking the results, and reports those results with Test::More. It's
+# similar to test_snippet, but uses input and output temporary files instead
+# to test encoding layers and also checks the Pod::Man accent output.
+#
+# $class - Class name of the formatter, as a string
+# $snippet - Path to the snippet file defining the test
+# $options_ref - Hash of options with the following keys:
+# perlio_utf8 - Set to 1 to set a PerlIO UTF-8 encoding on the output file
+sub test_snippet_with_io {
+ my ($class, $snippet, $options_ref) = @_;
+ my $data_ref = read_snippet($snippet);
+
+ # Create the formatter object.
+ my $parser = $class->new(%{ $data_ref->{options} }, name => 'TEST');
+ isa_ok($parser, $class, 'Parser object');
+
+ # Write the input POD to a temporary file prefaced by the encoding
+ # directive.
+ my $tmpdir = File::Spec->catdir('t', 'tmp');
+ if (!-d $tmpdir) {
+ mkdir($tmpdir, 0777);
+ }
+ my $input_file = File::Spec->catfile('t', 'tmp', "tmp$$.pod");
+ open(my $input, '>', $input_file)
+ or BAIL_OUT("cannot create $input_file: $!");
+ print {$input} encode('UTF-8', $data_ref->{input})
+ or BAIL_OUT("cannot write to $input_file: $!");
+ close($input) or BAIL_OUT("cannot flush output to $input_file: $!");
+
+ # Create an output file and parse from the input file to the output file.
+ my $output_file = File::Spec->catfile('t', 'tmp', "out$$.tmp");
+ open(my $output, '>', $output_file)
+ or BAIL_OUT("cannot create $output_file: $!");
+ if ($options_ref->{perlio_utf8}) {
+ ## no critic (BuiltinFunctions::ProhibitStringyEval)
+ ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
+ eval 'binmode($output, ":encoding(utf-8)")';
+ ## use critic
+ }
+
+ # Parse the input file into the output file.
+ $parser->parse_from_file($input_file, $output);
+ close($output) or BAIL_OUT("cannot flush output to $output_file: $!");
+
+ # Read back in the results, checking to ensure that we didn't output the
+ # accent definitions if we wrote UTF-8 output.
+ open(my $results, '<', $output_file)
+ or BAIL_OUT("cannot open $output_file: $!");
+ my ($line, $saw_accents);
+ while (defined($line = <$results>)) {
+ $line = decode('UTF-8', $line);
+ if ($line =~ m{ Accent [ ] mark [ ] definitions }xms) {
+ $saw_accents = 1;
+ }
+ last if $line =~ m{ \A [.]nh }xms;
+ }
+ my $saw = do { local $/ = undef; <$results> };
+ $saw = decode('UTF-8', $saw);
+ close($results) or BAIL_OUT("cannot close output file: $!");
+
+ # Clean up.
+ unlink($input_file, $output_file);
+
+ # Check the accent definitions and the output.
+ my $perlio = $options_ref->{perlio_utf8} ? ' (PerlIO)' : q{};
+ is(
+ $saw_accents,
+ $data_ref->{options}{utf8} ? undef : 1,
+ "$data_ref->{name}: accent definitions$perlio"
+ );
+ is($saw, $data_ref->{output}, "$data_ref->{name}: output$perlio");
+ return;
+}
+
+1;
+__END__
+
+=for stopwords
+Allbery podlators PerlIO UTF-8 formatter FH whitespace
+
+=head1 NAME
+
+Test::Podlators - Helper functions for podlators tests
+
+=head1 SYNOPSIS
+
+ use Test::Podlators qw(read_test_data);
+
+ # Read the next block of test data, including options.
+ my $data = read_test_data(\*DATA, { options => 1 });
+
+=head1 DESCRIPTION
+
+This module collects various utility functions that are useful for writing
+test cases for the podlators distribution. It is not intended to be, and
+probably isn't, useful outside of the test suite for that module.
+
+=head1 FUNCTIONS
+
+None of these functions are imported by default. The ones used by a script
+should be explicitly imported.
+
+=over 4
+
+=item read_snippet(PATH[, OPTIONS])
+
+Read one test snippet from the provided relative file name and return it. The
+path should be relative to F<t/data/snippets>. For the format, see
+F<t/data/snippets/README>.
+
+OPTIONS, if present, is a hash that currently supports only one key: C<utf8>,
+to set a PerlIO input encoding layer of UTF-8 when reading the snippet.
+
+The result will be a hash with the following keys:
+
+=over 4
+
+=item name
+
+The name of the test, for reporting purposes.
+
+=item options
+
+A hash of any options to values, if any options were specified.
+
+=item input
+
+Input POD to try formatting.
+
+=item output
+
+The expected output.
+
+=item errors
+
+Expected errors from the POD formatter.
+
+=item exception
+
+An expected exception from the POD formatter, with the file and line
+information stripped from the end of the exception.
+
+=back
+
+=item read_test_data(FH, FORMAT)
+
+Reads a block of test data from FH, looking for test information according to
+the description provided in FORMAT. All data prior to the first line
+consisting of only C<###> will be ignored. Then, the test data must consist
+of two or more blocks separated by C<###> and ending in a final C<###> line.
+
+FORMAT is optional, in which case the block of test data should be just input
+text and output text. If provided, it should be a reference to a hash with
+one or more of the following keys:
+
+=over 4
+
+=item options
+
+If set, the first block of data in the test description is a set of options in
+the form of a key, whitespace, and a value, one per line. The value may be
+missing, in which case the value associated with the key is the empty string.
+
+=back
+
+The return value is a hash with at least some of the following keys:
+
+=over 4
+
+=item input
+
+The input data for the test. This is always present.
+
+=item options
+
+If C<options> is set in the FORMAT argument, this is the hash of keys and
+values in the options section of the test data.
+
+=item output
+
+The output data for the test. This is always present.
+
+=back
+
+=item slurp(FILE[, STRIP])
+
+Read the contents of FILE and return it as a string. If STRIP is set to
+C<man>, strip off any Pod::Man header from the file before returning it.
+
+=item test_snippet(CLASS, SNIPPET)
+
+Test a formatter on a particular POD snippet. This does all the work of
+loading the snippet, creating the formatter by instantiating CLASS, running
+it, and checking the results. Results are reported with Test::More.
+
+=item test_snippet_with_io(CLASS, SNIPPET[, OPTIONS])
+
+The same as test_snippet(), except, rather than parsing the input into a
+string buffer, this function uses real, temporary input and output files.
+This can be used to test I/O layer handling and proper encoding.
+
+OPTIONS, if present, is a reference to a hash of options. Currently, only
+one key is supported: C<perlio>, which, if set to true, will set a PerlIO
+UTF-8 encoding layer on the output file before writing to it.
+
+=back
+
+=head1 AUTHOR
+
+Russ Allbery <rra@cpan.org>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2015 Russ Allbery <rra@cpan.org>
+
+This program is free software; you may redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=cut
diff --git a/cpan/podlators/t/lib/Test/RRA.pm b/cpan/podlators/t/lib/Test/RRA.pm
new file mode 100644
index 0000000000..3870cc151b
--- /dev/null
+++ b/cpan/podlators/t/lib/Test/RRA.pm
@@ -0,0 +1,235 @@
+# Helper functions for test programs written in Perl.
+#
+# This module provides a collection of helper functions used by test programs
+# written in Perl. This is a general collection of functions that can be used
+# by both C packages with Automake and by stand-alone Perl modules. See
+# Test::RRA::Automake for additional functions specifically for C Automake
+# distributions.
+
+package Test::RRA;
+
+use 5.006;
+use strict;
+use warnings;
+
+use Exporter;
+use Test::More;
+
+# For Perl 5.006 compatibility.
+## no critic (ClassHierarchies::ProhibitExplicitISA)
+
+# Declare variables that should be set in BEGIN for robustness.
+our (@EXPORT_OK, @ISA, $VERSION);
+
+# Set $VERSION and everything export-related in a BEGIN block for robustness
+# against circular module loading (not that we load any modules, but
+# consistency is good).
+BEGIN {
+ @ISA = qw(Exporter);
+ @EXPORT_OK = qw(skip_unless_author skip_unless_automated use_prereq);
+
+ # This version should match the corresponding rra-c-util release, but with
+ # two digits for the minor version, including a leading zero if necessary,
+ # so that it will sort properly.
+ $VERSION = '5.09';
+}
+
+# Skip this test unless author tests are requested. Takes a short description
+# of what tests this script would perform, which is used in the skip message.
+# Calls plan skip_all, which will terminate the program.
+#
+# $description - Short description of the tests
+#
+# Returns: undef
+sub skip_unless_author {
+ my ($description) = @_;
+ if (!$ENV{AUTHOR_TESTING}) {
+ plan skip_all => "$description only run for author";
+ }
+ return;
+}
+
+# Skip this test unless doing automated testing or release testing. This is
+# used for tests that should be run by CPAN smoke testing or during releases,
+# but not for manual installs by end users. Takes a short description of what
+# tests this script would perform, which is used in the skip message. Calls
+# plan skip_all, which will terminate the program.
+#
+# $description - Short description of the tests
+#
+# Returns: undef
+sub skip_unless_automated {
+ my ($description) = @_;
+ for my $env (qw(AUTOMATED_TESTING RELEASE_TESTING AUTHOR_TESTING)) {
+ return if $ENV{$env};
+ }
+ plan skip_all => "$description normally skipped";
+ return;
+}
+
+# Attempt to load a module and skip the test if the module could not be
+# loaded. If the module could be loaded, call its import function manually.
+# If the module could not be loaded, calls plan skip_all, which will terminate
+# the program.
+#
+# The special logic here is based on Test::More and is required to get the
+# imports to happen in the caller's namespace.
+#
+# $module - Name of the module to load
+# @imports - Any arguments to import, possibly including a version
+#
+# Returns: undef
+sub use_prereq {
+ my ($module, @imports) = @_;
+
+ # If the first import looks like a version, pass it as a bare string.
+ my $version = q{};
+ if (@imports >= 1 && $imports[0] =~ m{ \A \d+ (?: [.][\d_]+ )* \z }xms) {
+ $version = shift(@imports);
+ }
+
+ # Get caller information to put imports in the correct package.
+ my ($package) = caller;
+
+ # Do the import with eval, and try to isolate it from the surrounding
+ # context as much as possible. Based heavily on Test::More::_eval.
+ ## no critic (BuiltinFunctions::ProhibitStringyEval)
+ ## no critic (ValuesAndExpressions::ProhibitImplicitNewlines)
+ my ($result, $error, $sigdie);
+ {
+ local $@ = undef;
+ local $! = undef;
+ local $SIG{__DIE__} = undef;
+ $result = eval qq{
+ package $package;
+ use $module $version \@imports;
+ 1;
+ };
+ $error = $@;
+ $sigdie = $SIG{__DIE__} || undef;
+ }
+
+ # If the use failed for any reason, skip the test.
+ if (!$result || $error) {
+ my $name = length($version) > 0 ? "$module $version" : $module;
+ plan skip_all => "$name required for test";
+ }
+
+ # If the module set $SIG{__DIE__}, we cleared that via local. Restore it.
+ ## no critic (Variables::RequireLocalizedPunctuationVars)
+ if (defined($sigdie)) {
+ $SIG{__DIE__} = $sigdie;
+ }
+ return;
+}
+
+1;
+__END__
+
+=for stopwords
+Allbery Allbery's DESC bareword sublicense MERCHANTABILITY NONINFRINGEMENT
+rra-c-util
+
+=head1 NAME
+
+Test::RRA - Support functions for Perl tests
+
+=head1 SYNOPSIS
+
+ use Test::RRA
+ qw(skip_unless_author skip_unless_automated use_prereq);
+
+ # Skip this test unless author tests are requested.
+ skip_unless_author('Coding style tests');
+
+ # Skip this test unless doing automated or release testing.
+ skip_unless_automated('POD syntax tests');
+
+ # Load modules, skipping the test if they're not available.
+ use_prereq('Perl6::Slurp', 'slurp');
+ use_prereq('Test::Script::Run', '0.04');
+
+=head1 DESCRIPTION
+
+This module collects utility functions that are useful for Perl test
+scripts. It assumes Russ Allbery's Perl module layout and test
+conventions and will only be useful for other people if they use the
+same conventions.
+
+=head1 FUNCTIONS
+
+None of these functions are imported by default. The ones used by a
+script should be explicitly imported.
+
+=over 4
+
+=item skip_unless_author(DESC)
+
+Checks whether AUTHOR_TESTING is set in the environment and skips the
+whole test (by calling C<plan skip_all> from Test::More) if it is not.
+DESC is a description of the tests being skipped. A space and C<only run
+for author> will be appended to it and used as the skip reason.
+
+=item skip_unless_automated(DESC)
+
+Checks whether AUTHOR_TESTING, AUTOMATED_TESTING, or RELEASE_TESTING are
+set in the environment and skips the whole test (by calling C<plan
+skip_all> from Test::More) if they are not. This should be used by tests
+that should not run during end-user installs of the module, but which
+should run as part of CPAN smoke testing and release testing.
+
+DESC is a description of the tests being skipped. A space and C<normally
+skipped> will be appended to it and used as the skip reason.
+
+=item use_prereq(MODULE[, VERSION][, IMPORT ...])
+
+Attempts to load MODULE with the given VERSION and import arguments. If
+this fails for any reason, the test will be skipped (by calling C<plan
+skip_all> from Test::More) with a skip reason saying that MODULE is
+required for the test.
+
+VERSION will be passed to C<use> as a version bareword if it looks like a
+version number. The remaining IMPORT arguments will be passed as the
+value of an array.
+
+=back
+
+=head1 AUTHOR
+
+Russ Allbery <eagle@eyrie.org>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2013, 2014 The Board of Trustees of the Leland Stanford Junior
+University
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+=head1 SEE ALSO
+
+Test::More(3), Test::RRA::Automake(3), Test::RRA::Config(3)
+
+This module is maintained in the rra-c-util package. The current version
+is available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>.
+
+The functions to control when tests are run use environment variables
+defined by the L<Lancaster
+Consensus|https://github.com/Perl-Toolchain-Gang/toolchain-site/blob/master/lancaster-consensus.md>.
+
+=cut
diff --git a/cpan/podlators/t/lib/Test/RRA/Config.pm b/cpan/podlators/t/lib/Test/RRA/Config.pm
new file mode 100644
index 0000000000..7c29f1a829
--- /dev/null
+++ b/cpan/podlators/t/lib/Test/RRA/Config.pm
@@ -0,0 +1,215 @@
+# Configuration for Perl test cases.
+#
+# In order to reuse the same Perl test cases in multiple packages, I use a
+# configuration file to store some package-specific data. This module loads
+# that configuration and provides the namespace for the configuration
+# settings.
+
+package Test::RRA::Config;
+
+use 5.006;
+use strict;
+use warnings;
+
+# For Perl 5.006 compatibility.
+## no critic (ClassHierarchies::ProhibitExplicitISA)
+
+use Exporter;
+use Test::More;
+
+# Declare variables that should be set in BEGIN for robustness.
+our (@EXPORT_OK, @ISA, $VERSION);
+
+# Set $VERSION and everything export-related in a BEGIN block for robustness
+# against circular module loading (not that we load any modules, but
+# consistency is good).
+BEGIN {
+ @ISA = qw(Exporter);
+ @EXPORT_OK = qw(
+ $COVERAGE_LEVEL @COVERAGE_SKIP_TESTS @CRITIC_IGNORE $LIBRARY_PATH
+ $MINIMUM_VERSION %MINIMUM_VERSION @POD_COVERAGE_EXCLUDE @STRICT_IGNORE
+ @STRICT_PREREQ
+ );
+
+ # This version should match the corresponding rra-c-util release, but with
+ # two digits for the minor version, including a leading zero if necessary,
+ # so that it will sort properly.
+ $VERSION = '5.09';
+}
+
+# If BUILD or SOURCE are set in the environment, look for data/perl.conf under
+# those paths for a C Automake package. Otherwise, look in t/data/perl.conf
+# for a standalone Perl module. Don't use Test::RRA::Automake since it may
+# not exist.
+our $PATH;
+for my $base ($ENV{BUILD}, $ENV{SOURCE}, 't') {
+ next if !defined($base);
+ my $path = "$base/data/perl.conf";
+ if (-r $path) {
+ $PATH = $path;
+ last;
+ }
+}
+if (!defined($PATH)) {
+ BAIL_OUT('cannot find data/perl.conf');
+}
+
+# Pre-declare all of our variables and set any defaults.
+our $COVERAGE_LEVEL = 100;
+our @COVERAGE_SKIP_TESTS;
+our @CRITIC_IGNORE;
+our $LIBRARY_PATH;
+our $MINIMUM_VERSION = '5.008';
+our %MINIMUM_VERSION;
+our @POD_COVERAGE_EXCLUDE;
+our @STRICT_IGNORE;
+our @STRICT_PREREQ;
+
+# Load the configuration.
+if (!do($PATH)) {
+ my $error = $@ || $! || 'loading file did not return true';
+ BAIL_OUT("cannot load data/perl.conf: $error");
+}
+
+1;
+__END__
+
+=for stopwords
+Allbery rra-c-util Automake perlcritic .libs namespace subdirectory
+sublicense MERCHANTABILITY NONINFRINGEMENT
+
+=head1 NAME
+
+Test::RRA::Config - Perl test configuration
+
+=head1 SYNOPSIS
+
+ use Test::RRA::Config qw($MINIMUM_VERSION);
+ print "Required Perl version is $MINIMUM_VERSION\n";
+
+=head1 DESCRIPTION
+
+Test::RRA::Config encapsulates per-package configuration for generic Perl
+test programs that are shared between multiple packages using the
+rra-c-util infrastructure. It handles locating and loading the test
+configuration file for both C Automake packages and stand-alone Perl
+modules.
+
+Test::RRA::Config looks for a file named F<data/perl.conf> relative to the
+root of the test directory. That root is taken from the environment
+variables BUILD or SOURCE (in that order) if set, which will be the case
+for C Automake packages using C TAP Harness. If neither is set, it
+expects the root of the test directory to be a directory named F<t>
+relative to the current directory, which will be the case for stand-alone
+Perl modules.
+
+The following variables are supported:
+
+=over 4
+
+=item $COVERAGE_LEVEL
+
+The coverage level achieved by the test suite for Perl test coverage
+testing using Test::Strict, as a percentage. The test will fail if test
+coverage less than this percentage is achieved. If not given, defaults
+to 100.
+
+=item @COVERAGE_SKIP_TESTS
+
+Directories under F<t> whose tests should be skipped when doing coverage
+testing. This can be tests that won't contribute to coverage or tests
+that don't run properly under Devel::Cover for some reason (such as ones
+that use taint checking). F<docs> and F<style> will always be skipped
+regardless of this setting.
+
+=item @CRITIC_IGNORE
+
+Additional directories to ignore when doing recursive perlcritic testing.
+The contents of this directory must be either top-level directory names or
+directory names starting with F<tests/>.
+
+=item $LIBRARY_PATH
+
+Add this directory (or a F<.libs> subdirectory) relative to the top of the
+source tree to LD_LIBRARY_PATH when checking the syntax of Perl modules.
+This may be required to pick up libraries that are used by in-tree Perl
+modules so that Perl scripts can pass a syntax check.
+
+=item $MINIMUM_VERSION
+
+Default minimum version requirement for included Perl scripts. If not
+given, defaults to 5.008.
+
+=item %MINIMUM_VERSION
+
+Minimum version exceptions for specific directories. The keys should be
+minimum versions of Perl to enforce. The value for each key should be a
+reference to an array of either top-level directory names or directory
+names starting with F<tests/>. All files in those directories will have
+that minimum Perl version constraint imposed instead of $MINIMUM_VERSION.
+
+=item @POD_COVERAGE_EXCLUDE
+
+Regexes that match method names that should be excluded from POD coverage
+testing. Normally, all methods have to be documented in the POD for a
+Perl module, but methods matching any of these regexes will be considered
+private and won't require documentation.
+
+=item @STRICT_IGNORE
+
+Additional directories to ignore when doing recursive Test::Strict testing
+for C<use strict> and C<use warnings>. The contents of this directory
+must be either top-level directory names or directory names starting with
+F<tests/>.
+
+=item @STRICT_PREREQ
+
+A list of Perl modules that have to be available in order to do meaningful
+Test::Strict testing. If any of the modules cannot be loaded via C<use>,
+Test::Strict checking will be skipped. There is currently no way to
+require specific versions of the modules.
+
+=back
+
+No variables are exported by default, but the variables can be imported
+into the local namespace to avoid long variable names.
+
+=head1 AUTHOR
+
+Russ Allbery <eagle@eyrie.org>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2013, 2014 The Board of Trustees of the Leland Stanford Junior
+University
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+=head1 SEE ALSO
+
+perlcritic(1), Test::MinimumVersion(3), Test::RRA(3),
+Test::RRA::Automake(3), Test::Strict(3)
+
+This module is maintained in the rra-c-util package. The current version
+is available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>.
+
+The C TAP Harness test driver and libraries for TAP-based C testing are
+available from L<http://www.eyrie.org/~eagle/software/c-tap-harness/>.
+
+=cut
diff --git a/cpan/podlators/t/man-heading.t b/cpan/podlators/t/man-heading.t
deleted file mode 100644
index fa4792c3cb..0000000000
--- a/cpan/podlators/t/man-heading.t
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/usr/bin/perl -w
-#
-# man-options.t -- Additional tests for Pod::Man options.
-#
-# Copyright 2002, 2004, 2006, 2008, 2009, 2012 Russ Allbery <rra@stanford.edu>
-#
-# This program is free software; you may redistribute it and/or modify it
-# under the same terms as Perl itself.
-
-BEGIN {
- chdir 't' if -d 't';
- if ($ENV{PERL_CORE}) {
- @INC = '../lib';
- }
- unshift (@INC, '../blib/lib');
- $| = 1;
-}
-
-use strict;
-
-use Test::More tests => 7;
-BEGIN { use_ok ('Pod::Man') }
-
-my $n = 1;
-while (<DATA>) {
- my %options;
- next until $_ eq "###\n";
- while (<DATA>) {
- last if $_ eq "###\n";
- my ($option, $value) = split (' ', $_, 2);
- chomp $value;
- $options{$option} = $value;
- }
- open (TMP, '> tmp.pod') or die "Cannot create tmp.pod: $!\n";
- print TMP "=head1 NAME\n\ntest - Test man page\n";
- close TMP;
- my $parser = Pod::Man->new (%options);
- isa_ok ($parser, 'Pod::Man', 'Parser object');
- open (OUT, "> out$$.tmp") or die "Cannot create out$$.tmp: $!\n";
- $parser->parse_from_file ('tmp.pod', \*OUT);
- close OUT;
- open (TMP, "out$$.tmp") or die "Cannot open out$$.tmp: $!\n";
- my $heading;
- while (<TMP>) {
- if (/^\.TH/) {
- $heading = $_;
- last;
- }
- }
- close TMP;
- 1 while unlink ('tmp.pod', "out$$.tmp");
- my $expected = '';
- while (<DATA>) {
- last if $_ eq "###\n";
- $expected .= $_;
- }
- is ($heading, $expected, "Heading is correct for test $n");
- $n++;
-}
-
-# Below the marker are sets of options and the corresponding expected .TH line
-# from the man page. This is used to test specific features or problems with
-# Pod::Man. The options and output are separated by lines containing only
-# ###.
-
-__DATA__
-
-###
-date 2009-01-17
-release 1.0
-###
-.TH TMP 1 "2009-01-17" "1.0" "User Contributed Perl Documentation"
-###
-
-###
-date 2009-01-17
-name TEST
-section 8
-release 2.0-beta
-###
-.TH TEST 8 "2009-01-17" "2.0-beta" "User Contributed Perl Documentation"
-###
-
-###
-date 2009-01-17
-release 1.0
-center Testing Documentation
-###
-.TH TMP 1 "2009-01-17" "1.0" "Testing Documentation"
-###
diff --git a/cpan/podlators/t/man-options.t b/cpan/podlators/t/man-options.t
deleted file mode 100644
index 898abb9dde..0000000000
--- a/cpan/podlators/t/man-options.t
+++ /dev/null
@@ -1,286 +0,0 @@
-#!/usr/bin/perl -w
-#
-# Additional tests for Pod::Man options.
-#
-# Copyright 2002, 2004, 2006, 2008, 2009, 2012, 2013
-# Russ Allbery <rra@stanford.edu>
-#
-# This program is free software; you may redistribute it and/or modify it
-# under the same terms as Perl itself.
-
-BEGIN {
- chdir 't' if -d 't';
- if ($ENV{PERL_CORE}) {
- @INC = '../lib';
- }
- unshift (@INC, '../blib/lib');
- $| = 1;
-}
-
-use strict;
-
-use Test::More tests => 28;
-BEGIN { use_ok ('Pod::Man') }
-
-# Redirect stderr to a file.
-sub stderr_save {
- open (OLDERR, '>&STDERR') or die "Can't dup STDERR: $!\n";
- open (STDERR, "> out$$.err") or die "Can't redirect STDERR: $!\n";
-}
-
-# Restore stderr.
-sub stderr_restore {
- close STDERR;
- open (STDERR, '>&OLDERR') or die "Can't dup STDERR: $!\n";
- close OLDERR;
-}
-
-my $n = 1;
-while (<DATA>) {
- my %options;
- next until $_ eq "###\n";
- while (<DATA>) {
- last if $_ eq "###\n";
- my ($option, $value) = split;
- $options{$option} = $value;
- }
- open (TMP, "> tmp$$.pod") or die "Cannot create tmp$$.pod: $!\n";
- while (<DATA>) {
- last if $_ eq "###\n";
- print TMP $_;
- }
- close TMP;
- my $parser = Pod::Man->new (%options);
- isa_ok ($parser, 'Pod::Man', 'Parser object');
- open (OUT, "> out$$.tmp") or die "Cannot create out$$.tmp: $!\n";
- stderr_save;
- eval { $parser->parse_from_file ("tmp$$.pod", \*OUT) };
- my $exception = $@;
- stderr_restore;
- close OUT;
- my $accents = 0;
- open (TMP, "out$$.tmp") or die "Cannot open out$$.tmp: $!\n";
- while (<TMP>) {
- last if /^\.nh/;
- }
- my $output;
- {
- local $/;
- $output = <TMP>;
- }
- close TMP;
- 1 while unlink ("tmp$$.pod", "out$$.tmp");
- my $expected = '';
- while (<DATA>) {
- last if $_ eq "###\n";
- $expected .= $_;
- }
- is ($output, $expected, "Output correct for test $n");
- open (ERR, "out$$.err") or die "Cannot open out.err: $!\n";
- my $errors;
- {
- local $/;
- $errors = <ERR>;
- }
- close ERR;
- $errors =~ s/\Qtmp$$.pod/tmp.pod/g;
- 1 while unlink ("out$$.err");
- if ($exception) {
- $exception =~ s/ at .*//;
- $errors .= "EXCEPTION: $exception";
- }
- $expected = '';
- while (<DATA>) {
- last if $_ eq "###\n";
- $expected .= $_;
- }
- is ($errors, $expected, "Errors are correct for test $n");
- $n++;
-}
-
-# Below the marker are bits of POD and corresponding expected text output and
-# error output. This is used to test specific features or problems with
-# Pod::Man. The options, input, output, and errors are separated by lines
-# containing only ###.
-
-__DATA__
-
-###
-fixed CR
-fixedbold CY
-fixeditalic CW
-fixedbolditalic CX
-###
-=head1 FIXED FONTS
-
-C<foo B<bar I<baz>> I<bay>>
-###
-.SH "FIXED FONTS"
-.IX Header "FIXED FONTS"
-\&\f(CR\*(C`foo \f(CYbar \f(CXbaz\f(CY\f(CR \f(CWbay\f(CR\*(C'\fR
-###
-###
-
-###
-###
-=over 4
-
-=item Foo
-
-Bar.
-
-=head1 NEXT
-###
-.IP "Foo" 4
-.IX Item "Foo"
-Bar.
-.SH "NEXT"
-.IX Header "NEXT"
-.SH "POD ERRORS"
-.IX Header "POD ERRORS"
-Hey! \fBThe above document had some coding errors, which are explained below:\fR
-.IP "Around line 7:" 4
-.IX Item "Around line 7:"
-You forgot a '=back' before '=head1'
-###
-###
-
-###
-stderr 1
-###
-=over 4
-
-=item Foo
-
-Bar.
-
-=head1 NEXT
-###
-.IP "Foo" 4
-.IX Item "Foo"
-Bar.
-.SH "NEXT"
-.IX Header "NEXT"
-###
-tmp.pod around line 7: You forgot a '=back' before '=head1'
-###
-
-###
-nourls 1
-###
-=head1 URL suppression
-
-L<anchor|http://www.example.com/>
-###
-.SH "URL suppression"
-.IX Header "URL suppression"
-anchor
-###
-###
-
-###
-errors stderr
-###
-=over 4
-
-=item Foo
-
-Bar.
-
-=head1 NEXT
-###
-.IP "Foo" 4
-.IX Item "Foo"
-Bar.
-.SH "NEXT"
-.IX Header "NEXT"
-###
-tmp.pod around line 7: You forgot a '=back' before '=head1'
-###
-
-###
-errors die
-###
-=over 4
-
-=item Foo
-
-Bar.
-
-=head1 NEXT
-###
-.IP "Foo" 4
-.IX Item "Foo"
-Bar.
-.SH "NEXT"
-.IX Header "NEXT"
-###
-tmp.pod around line 7: You forgot a '=back' before '=head1'
-EXCEPTION: POD document had syntax errors
-###
-
-###
-errors pod
-###
-=over 4
-
-=item Foo
-
-Bar.
-
-=head1 NEXT
-###
-.IP "Foo" 4
-.IX Item "Foo"
-Bar.
-.SH "NEXT"
-.IX Header "NEXT"
-.SH "POD ERRORS"
-.IX Header "POD ERRORS"
-Hey! \fBThe above document had some coding errors, which are explained below:\fR
-.IP "Around line 7:" 4
-.IX Item "Around line 7:"
-You forgot a '=back' before '=head1'
-###
-###
-
-###
-errors none
-###
-=over 4
-
-=item Foo
-
-Bar.
-
-=head1 NEXT
-###
-.IP "Foo" 4
-.IX Item "Foo"
-Bar.
-.SH "NEXT"
-.IX Header "NEXT"
-###
-###
-
-###
-errors none
-###
-=over 4
-
-=item foo
-
-Not a bullet.
-
-=item *
-
-Also not a bullet.
-
-=back
-###
-.IP "foo" 4
-.IX Item "foo"
-Not a bullet.
-.IP "*" 4
-Also not a bullet.
-###
diff --git a/cpan/podlators/t/man-perlio.t b/cpan/podlators/t/man-perlio.t
deleted file mode 100644
index e6aad3aeeb..0000000000
--- a/cpan/podlators/t/man-perlio.t
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/usr/bin/perl -w
-#
-# man-perlio.t -- Test Pod::Man with a PerlIO UTF-8 encoding layer.
-#
-# Copyright 2002, 2004, 2006, 2008, 2009, 2010, 2012
-# Russ Allbery <rra@stanford.edu>
-#
-# This program is free software; you may redistribute it and/or modify it
-# under the same terms as Perl itself.
-
-BEGIN {
- chdir 't' if -d 't';
- if ($ENV{PERL_CORE}) {
- @INC = '../lib';
- }
- unshift (@INC, '../blib/lib');
- $| = 1;
-}
-
-use strict;
-
-use Test::More;
-
-# UTF-8 support requires Perl 5.8 or later.
-BEGIN {
- if ($] < 5.008) {
- plan skip_all => 'Perl 5.8 required for UTF-8 support';
- } else {
- plan tests => 7;
- }
-}
-BEGIN { use_ok ('Pod::Man') }
-
-# Force UTF-8 on all relevant file handles. Do this inside eval in case the
-# encoding parameter doesn't work.
-eval { binmode (\*DATA, ':encoding(utf-8)') };
-eval { binmode (\*STDOUT, ':encoding(utf-8)') };
-my $builder = Test::More->builder;
-eval { binmode ($builder->output, ':encoding(utf-8)') };
-eval { binmode ($builder->failure_output, ':encoding(utf-8)') };
-
-my $n = 1;
-while (<DATA>) {
- my %options;
- next until $_ eq "###\n";
- while (<DATA>) {
- last if $_ eq "###\n";
- my ($option, $value) = split;
- $options{$option} = $value;
- }
- open (TMP, "> tmp$$.pod") or die "Cannot create tmp$$.pod: $!\n";
- eval { binmode (\*TMP, ':encoding(utf-8)') };
- print TMP "=encoding utf-8\n\n";
- while (<DATA>) {
- last if $_ eq "###\n";
- print TMP $_;
- }
- close TMP;
- my $parser = Pod::Man->new (%options);
- isa_ok ($parser, 'Pod::Man', 'Parser object');
- open (OUT, "> out$$.tmp") or die "Cannot create out$$.tmp: $!\n";
- eval { binmode (\*OUT, ':encoding(utf-8)') };
- $parser->parse_from_file ("tmp$$.pod", \*OUT);
- close OUT;
- my $accents = 0;
- open (TMP, "out$$.tmp") or die "Cannot open out$$.tmp: $!\n";
- eval { binmode (\*TMP, ':encoding(utf-8)') };
- while (<TMP>) {
- $accents = 1 if /Accent mark definitions/;
- last if /^\.nh/;
- }
- my $output;
- {
- local $/;
- $output = <TMP>;
- }
- close TMP;
- 1 while unlink ("tmp$$.pod", "out$$.tmp");
- if ($options{utf8}) {
- ok (!$accents, "Saw no accent definitions for test $n");
- } else {
- ok ($accents, "Saw accent definitions for test $n");
- }
- my $expected = '';
- while (<DATA>) {
- last if $_ eq "###\n";
- $expected .= $_;
- }
- is ($output, $expected, "Output correct for test $n");
- $n++;
-}
-
-# Below the marker are bits of POD and corresponding expected text output.
-# This is used to test specific features or problems with Pod::Man. The
-# input and output are separated by lines containing only ###.
-
-__DATA__
-
-###
-utf8 1
-###
-=head1 BEYONCÉ
-
-Beyoncé! Beyoncé! Beyoncé!!
-
- Beyoncé! Beyoncé!
- Beyoncé! Beyoncé!
- Beyoncé! Beyoncé!
-
-Older versions did not convert Beyoncé in verbatim.
-###
-.SH "BEYONCÉ"
-.IX Header "BEYONCÉ"
-Beyoncé! Beyoncé! Beyoncé!!
-.PP
-.Vb 3
-\& Beyoncé! Beyoncé!
-\& Beyoncé! Beyoncé!
-\& Beyoncé! Beyoncé!
-.Ve
-.PP
-Older versions did not convert Beyoncé in verbatim.
-###
-
-###
-utf8 1
-###
-=head1 SE<lt>E<gt> output with UTF-8
-
-This is S<non-breaking output>.
-###
-.SH "S<> output with UTF\-8"
-.IX Header "S<> output with UTF-8"
-This is non-breaking output.
-###
diff --git a/cpan/podlators/t/man-utf8.t b/cpan/podlators/t/man-utf8.t
deleted file mode 100644
index c0d9ba859d..0000000000
--- a/cpan/podlators/t/man-utf8.t
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/usr/bin/perl -w
-#
-# man-utf8.t -- Test Pod::Man with UTF-8 input.
-#
-# Copyright 2002, 2004, 2006, 2008, 2009, 2012 Russ Allbery <rra@stanford.edu>
-#
-# This program is free software; you may redistribute it and/or modify it
-# under the same terms as Perl itself.
-
-BEGIN {
- chdir 't' if -d 't';
- if ($ENV{PERL_CORE}) {
- @INC = '../lib';
- }
- unshift (@INC, '../blib/lib');
- $| = 1;
-}
-
-use strict;
-
-use Test::More;
-
-# UTF-8 support requires Perl 5.8 or later.
-BEGIN {
- if ($] < 5.008) {
- plan skip_all => 'Perl 5.8 required for UTF-8 support';
- } else {
- plan tests => 7;
- }
-}
-BEGIN { use_ok ('Pod::Man') }
-
-# Force UTF-8 on all relevant file handles. Do this inside eval in case the
-# encoding parameter doesn't work.
-eval { binmode (\*DATA, ':encoding(utf-8)') };
-eval { binmode (\*STDOUT, ':encoding(utf-8)') };
-my $builder = Test::More->builder;
-eval { binmode ($builder->output, ':encoding(utf-8)') };
-eval { binmode ($builder->failure_output, ':encoding(utf-8)') };
-
-my $n = 1;
-while (<DATA>) {
- my %options;
- next until $_ eq "###\n";
- while (<DATA>) {
- last if $_ eq "###\n";
- my ($option, $value) = split;
- $options{$option} = $value;
- }
- open (TMP, "> tmp$$.pod") or die "Cannot create tmp$$.pod: $!\n";
- eval { binmode (\*TMP, ':encoding(utf-8)') };
- print TMP "=encoding utf-8\n\n";
- while (<DATA>) {
- last if $_ eq "###\n";
- print TMP $_;
- }
- close TMP;
- my $parser = Pod::Man->new (%options);
- isa_ok ($parser, 'Pod::Man', 'Parser object');
- open (OUT, "> out$$.tmp") or die "Cannot create out$$.tmp: $!\n";
- $parser->parse_from_file ("tmp$$.pod", \*OUT);
- close OUT;
- my $accents = 0;
- open (TMP, "out$$.tmp") or die "Cannot open out$$.tmp: $!\n";
- eval { binmode (\*TMP, ':encoding(utf-8)') };
- while (<TMP>) {
- $accents = 1 if /Accent mark definitions/;
- last if /^\.nh/;
- }
- my $output;
- {
- local $/;
- $output = <TMP>;
- }
- close TMP;
- 1 while unlink ("tmp$$.pod", "out$$.tmp");
- if ($options{utf8}) {
- ok (!$accents, "Saw no accent definitions for test $n");
- } else {
- ok ($accents, "Saw accent definitions for test $n");
- }
- my $expected = '';
- while (<DATA>) {
- last if $_ eq "###\n";
- $expected .= $_;
- }
- is ($output, $expected, "Output correct for test $n");
- $n++;
-}
-
-# Below the marker are bits of POD and corresponding expected text output.
-# This is used to test specific features or problems with Pod::Man. The
-# input and output are separated by lines containing only ###.
-
-__DATA__
-
-###
-utf8 1
-###
-=head1 BEYONCÉ
-
-Beyoncé! Beyoncé! Beyoncé!!
-
- Beyoncé! Beyoncé!
- Beyoncé! Beyoncé!
- Beyoncé! Beyoncé!
-
-Older versions did not convert Beyoncé in verbatim.
-###
-.SH "BEYONCÉ"
-.IX Header "BEYONCÉ"
-Beyoncé! Beyoncé! Beyoncé!!
-.PP
-.Vb 3
-\& Beyoncé! Beyoncé!
-\& Beyoncé! Beyoncé!
-\& Beyoncé! Beyoncé!
-.Ve
-.PP
-Older versions did not convert Beyoncé in verbatim.
-###
-
-###
-utf8 1
-###
-=head1 SE<lt>E<gt> output with UTF-8
-
-This is S<non-breaking output>.
-###
-.SH "S<> output with UTF\-8"
-.IX Header "S<> output with UTF-8"
-This is non-breaking output.
-###
diff --git a/cpan/podlators/t/man.t b/cpan/podlators/t/man/basic.t
index 0645d93203..118f22a972 100644
--- a/cpan/podlators/t/man.t
+++ b/cpan/podlators/t/man/basic.t
@@ -2,8 +2,8 @@
#
# Additional specialized tests for Pod::Man.
#
-# Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2012, 2013
-# Russ Allbery <rra@stanford.edu>
+# Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2012, 2013, 2014
+# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
# under the same terms as Perl itself.
@@ -33,9 +33,10 @@ while (<DATA>) {
open (TMP, "> tmp$$.pod") or die "Cannot create tmp$$.pod: $!\n";
# We have a test in ISO 8859-1 encoding. Make sure that nothing strange
- # happens if Perl thinks the world is Unicode. Wrap this in eval so that
- # older versions of Perl don't croak.
- eval { binmode (\*TMP, ':encoding(iso-8859-1)') if $have_encoding };
+ # happens if Perl thinks the world is Unicode. Hide this in a string eval
+ # so that older versions of Perl don't croak and minimum-version tests
+ # still pass.
+ eval 'binmode (\*TMP, ":encoding(iso-8859-1)")' if $have_encoding;
while (<DATA>) {
last if $_ eq "###\n";
diff --git a/cpan/podlators/t/man/devise-date.t b/cpan/podlators/t/man/devise-date.t
new file mode 100644
index 0000000000..b05b76f03c
--- /dev/null
+++ b/cpan/podlators/t/man/devise-date.t
@@ -0,0 +1,56 @@
+#!/usr/bin/perl
+#
+# In order for MakeMaker to build in the core, nothing can use Fcntl which
+# includes POSIX. devise_date()'s use of strftime() was replaced. This tests
+# that it's identical. It also tests special handling of the POD_MAN_DATE
+# environment variable.
+
+use 5.006;
+use strict;
+use warnings;
+
+use Pod::Man;
+use POSIX qw(strftime);
+
+use Test::More tests => 6;
+
+# Start with environment variables affecting the date stripped.
+local $ENV{SOURCE_DATE_EPOCH};
+local $ENV{POD_MAN_DATE};
+
+# Check that the results of device_date matches strftime. There is no input
+# file name, so this will use the current time.
+my $parser = Pod::Man->new;
+is(
+ $parser->devise_date,
+ strftime('%Y-%m-%d', gmtime()),
+ 'devise_date matches strftime'
+);
+
+# Set the override environment variable and ensure that it's honored.
+local $ENV{POD_MAN_DATE} = '2014-01-01';
+is($parser->devise_date, '2014-01-01', 'devise_date honors POD_MAN_DATE');
+
+# Check that an empty environment variable is honored.
+local $ENV{POD_MAN_DATE} = q{};
+is($parser->devise_date, q{}, 'devise_date honors empty POD_MAN_DATE');
+
+# Set another environment variable and ensure that it's honored.
+local $ENV{POD_MAN_DATE};
+local $ENV{SOURCE_DATE_EPOCH} = 1439390140;
+is($parser->devise_date, '2015-08-12', 'devise_date honors SOURCE_DATE_EPOCH');
+
+# Check that POD_MAN_DATE overrides SOURCE_DATE_EPOCH
+local $ENV{POD_MAN_DATE} = '2013-01-01';
+local $ENV{SOURCE_DATE_EPOCH} = 1482676620;
+is($parser->devise_date, '2013-01-01',
+ 'devise_date honors POD_MAN_DATE over SOURCE_DATE_EPOCH');
+
+# Check that an invalid SOURCE_DATE_EPOCH is not accepted
+local $ENV{POD_MAN_DATE};
+local $ENV{SOURCE_DATE_EPOCH} = '1482676620B';
+is(
+ $parser->devise_date,
+ strftime('%Y-%m-%d', gmtime()),
+ 'devise_date ignores invalid SOURCE_DATE_EPOCH'
+);
diff --git a/cpan/podlators/t/man/devise-title.t b/cpan/podlators/t/man/devise-title.t
new file mode 100644
index 0000000000..d102aa584f
--- /dev/null
+++ b/cpan/podlators/t/man/devise-title.t
@@ -0,0 +1,32 @@
+#!/usr/bin/perl
+#
+# Tests for the automatic determination of the manual page title if not
+# specified via options to pod2man or the Pod::Man constructor.
+
+use 5.006;
+use strict;
+use warnings;
+
+use File::Spec;
+use IO::File;
+use Test::More tests => 3;
+
+BEGIN {
+ use_ok('Pod::Man');
+}
+
+# Create a parser and set it up with an input source. There isn't a way to do
+# this in Pod::Simple without actually parsing the document, so send the
+# output to a string that we'll ignore.
+my $path = File::Spec->catfile('t', 'data', 'basic.pod');
+my $handle = IO::File->new($path, 'r');
+my $parser = Pod::Man->new(errors => 'pod');
+my $output;
+$parser->output_string(\$output);
+$parser->parse_file($handle);
+
+# Check the results of devise_title for this. We should get back STDIN, and
+# we should have reported an error.
+my ($name, $section) = $parser->devise_title;
+is($name, 'STDIN', 'devise_title uses STDIN for file handle input');
+ok($parser->errors_seen, '...and errors were seen');
diff --git a/cpan/podlators/t/man-empty.t b/cpan/podlators/t/man/empty.t
index 1e094c8527..613b339b5b 100644
--- a/cpan/podlators/t/man-empty.t
+++ b/cpan/podlators/t/man/empty.t
@@ -2,7 +2,7 @@
#
# man-empty.t -- Test Pod::Man with a document that produces only errors.
#
-# Copyright 2013 Russ Allbery <rra@stanford.edu>
+# Copyright 2013 Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
# under the same terms as Perl itself.
diff --git a/cpan/podlators/t/man/heading.t b/cpan/podlators/t/man/heading.t
new file mode 100644
index 0000000000..323fd62abf
--- /dev/null
+++ b/cpan/podlators/t/man/heading.t
@@ -0,0 +1,94 @@
+#!/usr/bin/perl
+#
+# Additional tests for Pod::Man heading generation.
+#
+# Copyright 2002, 2004, 2006, 2008, 2009, 2012, 2015
+# Russ Allbery <rra@cpan.org>
+#
+# This program is free software; you may redistribute it and/or modify it
+# under the same terms as Perl itself.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::More tests => 9;
+use Test::Podlators qw(read_test_data);
+
+BEGIN {
+ use_ok('Pod::Man');
+}
+
+# Loop through all the test data, generate output, and compare it to the
+# desired output data.
+while (defined(my $data = read_test_data(\*DATA, { options => 1 }))) {
+ my $parser = Pod::Man->new(%{ $data->{options} });
+ isa_ok($parser, 'Pod::Man', 'Parser object');
+
+ # Run the parser, storing the output into a Perl variable.
+ my $got;
+ $parser->output_string(\$got);
+ $parser->parse_string_document($data->{input});
+
+ # Extract just the heading line.
+ my ($heading) = ($got =~ m{^ ([.]TH [^\n]+ \n)}xms);
+
+ # Compare the results.
+ is($heading, $data->{output});
+}
+
+# Below the marker are sets of options, the input data, and the corresponding
+# expected .TH line from the man page. The options and output are separated
+# by lines containing only ###.
+
+__DATA__
+
+###
+date 2009-01-17
+release 1.0
+###
+=head1 NAME
+
+test - Test man page
+###
+.TH STDIN 1 "2009-01-17" "1.0" "User Contributed Perl Documentation"
+###
+
+###
+date 2009-01-17
+name TEST
+section 8
+release 2.0-beta
+###
+=head1 NAME
+
+test - Test man page
+###
+.TH TEST 8 "2009-01-17" "2.0-beta" "User Contributed Perl Documentation"
+###
+
+###
+date 2009-01-17
+release 1.0
+center Testing Documentation
+###
+=head1 NAME
+
+test - Test man page
+###
+.TH STDIN 1 "2009-01-17" "1.0" "Testing Documentation"
+###
+
+###
+date
+release
+center
+###
+=head1 NAME
+
+test - Test man page
+###
+.TH STDIN 1 "" "" ""
+###
diff --git a/cpan/podlators/t/man/options.t b/cpan/podlators/t/man/options.t
new file mode 100644
index 0000000000..7d48b5afc3
--- /dev/null
+++ b/cpan/podlators/t/man/options.t
@@ -0,0 +1,273 @@
+#!/usr/bin/perl -w
+#
+# Additional tests for Pod::Man options.
+#
+# Copyright 2002, 2004, 2006, 2008, 2009, 2012, 2013, 2015
+# Russ Allbery <rra@cpan.org>
+#
+# This program is free software; you may redistribute it and/or modify it
+# under the same terms as Perl itself.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::More tests => 31;
+use Test::Podlators qw(read_test_data slurp);
+
+BEGIN {
+ use_ok ('Pod::Man');
+}
+
+# Redirect stderr to a file. Return the name of the file that stores standard
+# error.
+sub stderr_save {
+ open(OLDERR, '>&STDERR') or die "Can't dup STDERR: $!\n";
+ open(STDERR, "> out$$.err") or die "Can't redirect STDERR: $!\n";
+ return "out$$.err";
+}
+
+# Restore stderr.
+sub stderr_restore {
+ close(STDERR);
+ open(STDERR, '>&OLDERR') or die "Can't dup STDERR: $!\n";
+ close(OLDERR);
+}
+
+# Loop through all the test data, generate output, and compare it to the
+# desired output data.
+my %options = (options => 1, errors => 1);
+my $n = 1;
+while (defined(my $data_ref = read_test_data(\*DATA, \%options))) {
+ my $parser = Pod::Man->new(%{ $data_ref->{options} }, name => 'TEST');
+ isa_ok($parser, 'Pod::Man', 'Parser object');
+
+ # Save stderr to a temporary file and then run the parser, storing the
+ # output into a Perl variable.
+ my $errors = stderr_save();
+ my $got;
+ $parser->output_string(\$got);
+ eval { $parser->parse_string_document($data_ref->{input}) };
+ my $exception = $@;
+ stderr_restore();
+
+ # Strip off everything prior to .nh from the output so that we aren't
+ # testing the generated header, and then check the output.
+ $got =~ s{ \A .* \n [.]nh \n }{}xms;
+ is($got, $data_ref->{output}, "Output for test $n");
+
+ # Collect the errors and add any exception, marking it with EXCEPTION.
+ # Then, compare that to the expected errors. The "1 while" construct is
+ # for VMS, in case there are multiple versions of the file.
+ my $got_errors = slurp($errors);
+ 1 while unlink($errors);
+ if ($exception) {
+ $exception =~ s{ [ ] at [ ] .* }{}xms;
+ $got_errors .= "EXCEPTION: $exception\n";
+ }
+ is($got_errors, $data_ref->{errors}, "Errors for test $n");
+ $n++;
+}
+
+# Below the marker are bits of POD and corresponding expected text output and
+# error output. The options, input, output, and errors are separated by lines
+# containing only ###.
+
+__DATA__
+
+###
+fixed CR
+fixedbold CY
+fixeditalic CW
+fixedbolditalic CX
+###
+=head1 FIXED FONTS
+
+C<foo B<bar I<baz>> I<bay>>
+###
+.SH "FIXED FONTS"
+.IX Header "FIXED FONTS"
+\&\f(CR\*(C`foo \f(CYbar \f(CXbaz\f(CY\f(CR \f(CWbay\f(CR\*(C'\fR
+###
+###
+
+###
+###
+=over 4
+
+=item Foo
+
+Bar.
+
+=head1 NEXT
+###
+.IP "Foo" 4
+.IX Item "Foo"
+Bar.
+.SH "NEXT"
+.IX Header "NEXT"
+.SH "POD ERRORS"
+.IX Header "POD ERRORS"
+Hey! \fBThe above document had some coding errors, which are explained below:\fR
+.IP "Around line 7:" 4
+.IX Item "Around line 7:"
+You forgot a '=back' before '=head1'
+###
+###
+
+###
+stderr 1
+###
+=over 4
+
+=item Foo
+
+Bar.
+
+=head1 NEXT
+###
+.IP "Foo" 4
+.IX Item "Foo"
+Bar.
+.SH "NEXT"
+.IX Header "NEXT"
+###
+Pod input around line 7: You forgot a '=back' before '=head1'
+###
+
+###
+nourls 1
+###
+=head1 URL suppression
+
+L<anchor|http://www.example.com/>
+###
+.SH "URL suppression"
+.IX Header "URL suppression"
+anchor
+###
+###
+
+###
+errors stderr
+###
+=over 4
+
+=item Foo
+
+Bar.
+
+=head1 NEXT
+###
+.IP "Foo" 4
+.IX Item "Foo"
+Bar.
+.SH "NEXT"
+.IX Header "NEXT"
+###
+Pod input around line 7: You forgot a '=back' before '=head1'
+###
+
+###
+errors die
+###
+=over 4
+
+=item Foo
+
+Bar.
+
+=head1 NEXT
+###
+.IP "Foo" 4
+.IX Item "Foo"
+Bar.
+.SH "NEXT"
+.IX Header "NEXT"
+###
+Pod input around line 7: You forgot a '=back' before '=head1'
+EXCEPTION: POD document had syntax errors
+###
+
+###
+errors pod
+###
+=over 4
+
+=item Foo
+
+Bar.
+
+=head1 NEXT
+###
+.IP "Foo" 4
+.IX Item "Foo"
+Bar.
+.SH "NEXT"
+.IX Header "NEXT"
+.SH "POD ERRORS"
+.IX Header "POD ERRORS"
+Hey! \fBThe above document had some coding errors, which are explained below:\fR
+.IP "Around line 7:" 4
+.IX Item "Around line 7:"
+You forgot a '=back' before '=head1'
+###
+###
+
+###
+errors none
+###
+=over 4
+
+=item Foo
+
+Bar.
+
+=head1 NEXT
+###
+.IP "Foo" 4
+.IX Item "Foo"
+Bar.
+.SH "NEXT"
+.IX Header "NEXT"
+###
+###
+
+###
+errors none
+###
+=over 4
+
+=item foo
+
+Not a bullet.
+
+=item *
+
+Also not a bullet.
+
+=back
+###
+.IP "foo" 4
+.IX Item "foo"
+Not a bullet.
+.IP "*" 4
+Also not a bullet.
+###
+###
+
+###
+quotes \(lq"\(rq"
+###
+=head1 FOO C<BAR> BAZ
+
+Foo C<bar> baz.
+###
+.ie n .SH "FOO \(lq""BAR\(rq"" BAZ"
+.el .SH "FOO \f(CWBAR\fP BAZ"
+.IX Header "FOO BAR BAZ"
+Foo \f(CW\*(C`bar\*(C'\fR baz.
+###
+###
diff --git a/cpan/podlators/t/man/utf8-io.t b/cpan/podlators/t/man/utf8-io.t
new file mode 100644
index 0000000000..858f8f7e0a
--- /dev/null
+++ b/cpan/podlators/t/man/utf8-io.t
@@ -0,0 +1,50 @@
+#!/usr/bin/perl -w
+#
+# Test Pod::Man UTF-8 handling, with and without PerlIO.
+#
+# Copyright 2002, 2004, 2006, 2008, 2009, 2010, 2012, 2014, 2015
+# Russ Allbery <rra@cpan.org>
+#
+# This program is free software; you may redistribute it and/or modify it
+# under the same terms as Perl itself.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::More;
+use Test::Podlators qw(test_snippet_with_io);
+
+# UTF-8 support requires Perl 5.8 or later.
+BEGIN {
+ if ($] < 5.008) {
+ plan skip_all => 'Perl 5.8 required for UTF-8 support';
+ } else {
+ plan tests => 13;
+ }
+}
+
+# Load the module.
+BEGIN {
+ use_ok('Pod::Man');
+}
+
+# Force UTF-8 on all relevant file handles. Hide this in a string eval so
+# that older versions of Perl don't croak and minimum-version tests still
+# pass.
+#
+## no critic (BuiltinFunctions::ProhibitStringyEval)
+## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
+eval 'binmode(\*STDOUT, ":encoding(utf-8)")';
+my $builder = Test::More->builder;
+eval 'binmode($builder->output, ":encoding(utf-8)")';
+eval 'binmode($builder->failure_output, ":encoding(utf-8)")';
+## use critic
+
+# For each of the UTF-8 snippets, check them with and without PerlIO layers.
+for my $snippet (qw(utf8-nonbreaking utf8-verbatim)) {
+ test_snippet_with_io('Pod::Man', "man/$snippet");
+ test_snippet_with_io('Pod::Man', "man/$snippet", { perlio_utf8 => 1 });
+}
diff --git a/cpan/podlators/t/parselink.t b/cpan/podlators/t/parselink/basic.t
index 828b2ec8e1..d06a3b5ea1 100644
--- a/cpan/podlators/t/parselink.t
+++ b/cpan/podlators/t/parselink/basic.t
@@ -2,7 +2,7 @@
#
# parselink.t -- Tests for Pod::ParseLink.
#
-# Copyright 2001, 2009 by Russ Allbery <rra@stanford.edu>
+# Copyright 2001, 2009 by Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
# under the same terms as Perl itself.
diff --git a/cpan/podlators/t/pod-parser.t b/cpan/podlators/t/pod-parser.t
deleted file mode 100644
index 6394731e14..0000000000
--- a/cpan/podlators/t/pod-parser.t
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/perl -w
-#
-# pod-parser.t -- Tests for backward compatibility with Pod::Parser.
-#
-# Copyright 2006, 2008, 2009, 2012 by Russ Allbery <rra@stanford.edu>
-#
-# This program is free software; you may redistribute it and/or modify it
-# under the same terms as Perl itself.
-
-BEGIN {
- chdir 't' if -d 't';
- if ($ENV{PERL_CORE}) {
- @INC = '../lib';
- }
- unshift (@INC, '../blib/lib');
- $| = 1;
-}
-
-use strict;
-
-use Test::More tests => 7;
-BEGIN {
- use_ok ('Pod::Man');
- use_ok ('Pod::Text');
-}
-
-my $parser = Pod::Man->new;
-isa_ok ($parser, 'Pod::Man', 'Pod::Man parser object');
-open (TMP, "> tmp$$.pod") or die "Cannot create tmp$$.pod: $!\n";
-print TMP "Some random B<text>.\n";
-close TMP;
-open (OUT, "> out$$.tmp") or die "Cannot create out$$.tmp: $!\n";
-$parser->parse_from_file ({ -cutting => 0 }, "tmp$$.pod", \*OUT);
-close OUT;
-open (OUT, "out$$.tmp") or die "Cannot open out$$.tmp: $!\n";
-while (<OUT>) { last if /^\.nh/ }
-my $output;
-{
- local $/;
- $output = <OUT>;
-}
-close OUT;
-is ($output, "Some random \\fBtext\\fR.\n", 'Pod::Man -cutting output');
-
-$parser = Pod::Text->new;
-isa_ok ($parser, 'Pod::Text', 'Pod::Text parser object');
-open (OUT, "> out$$.tmp") or die "Cannot create out$$.tmp: $!\n";
-$parser->parse_from_file ({ -cutting => 0 }, "tmp$$.pod", \*OUT);
-close OUT;
-open (OUT, "out$$.tmp") or die "Cannot open out$$.tmp: $!\n";
-{
- local $/;
- $output = <OUT>;
-}
-close OUT;
-is ($output, " Some random text.\n\n", 'Pod::Text -cutting output');
-
-# Test the pod2text function, particularly with only one argument.
-open (TMP, "> tmp$$.pod") or die "Cannot create tmp$$.pod: $!\n";
-print TMP "=pod\n\nSome random B<text>.\n";
-close TMP;
-open (OUT, "> out$$.tmp") or die "Cannot create out$$.tmp: $!\n";
-open (SAVE, '>&STDOUT') or die "Cannot dup stdout: $!\n";
-open (STDOUT, '>&OUT') or die "Cannot replace stdout: $!\n";
-pod2text ("tmp$$.pod");
-close OUT;
-open (STDOUT, '>&SAVE') or die "Cannot fix stdout: $!\n";
-close SAVE;
-open (OUT, "out$$.tmp") or die "Cannot open out$$.tmp: $!\n";
-{
- local $/;
- $output = <OUT>;
-}
-close OUT;
-is ($output, " Some random text.\n\n", 'Pod::Text pod2text function');
-
-1 while unlink ("tmp$$.pod", "out$$.tmp");
-exit 0;
diff --git a/cpan/podlators/t/pod-spelling.t b/cpan/podlators/t/pod-spelling.t
deleted file mode 100644
index d3ab858f9e..0000000000
--- a/cpan/podlators/t/pod-spelling.t
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/perl -w
-#
-# Check for spelling errors in POD documentation
-#
-# Checks all POD files in the tree for spelling problems using Pod::Spell and
-# either aspell or ispell. aspell is preferred. This test is disabled unless
-# RRA_MAINTAINER_TESTS is set, since spelling dictionaries vary too much
-# between environments.
-#
-# Copyright 2008, 2009 Russ Allbery <rra@stanford.edu>
-#
-# This program is free software; you may redistribute it and/or modify it
-# under the same terms as Perl itself.
-
-use strict;
-use Test::More;
-
-# Skip all spelling tests unless the maintainer environment variable is set.
-plan skip_all => 'Spelling tests only run for maintainer'
- unless $ENV{RRA_MAINTAINER_TESTS};
-
-# Load required Perl modules.
-eval 'use Test::Pod 1.00';
-plan skip_all => 'Test::Pod 1.00 required for testing POD' if $@;
-eval 'use Pod::Spell';
-plan skip_all => 'Pod::Spell required to test POD spelling' if $@;
-
-# Locate a spell-checker. hunspell is not currently supported due to its lack
-# of support for contractions (at least in the version in Debian).
-my @spell;
-my %options = (aspell => [ qw(-d en_US --home-dir=./ list) ],
- ispell => [ qw(-d american -l -p /dev/null) ]);
-SEARCH: for my $program (qw/aspell ispell/) {
- for my $dir (split ':', $ENV{PATH}) {
- if (-x "$dir/$program") {
- @spell = ("$dir/$program", @{ $options{$program} });
- }
- last SEARCH if @spell;
- }
-}
-plan skip_all => 'aspell or ispell required to test POD spelling'
- unless @spell;
-
-# Prerequisites are satisfied, so we're going to do some testing. Figure out
-# what POD files we have and from that develop our plan.
-$| = 1;
-my @pod = all_pod_files ();
-plan tests => scalar @pod;
-
-# Finally, do the checks.
-for my $pod (@pod) {
- my $child = open (CHILD, '-|');
- if (not defined $child) {
- die "Cannot fork: $!\n";
- } elsif ($child == 0) {
- my $pid = open (SPELL, '|-', @spell) or die "Cannot run @spell: $!\n";
- open (POD, '<', $pod) or die "Cannot open $pod: $!\n";
- my $parser = Pod::Spell->new;
- $parser->parse_from_filehandle (\*POD, \*SPELL);
- close POD;
- close SPELL;
- exit ($? >> 8);
- } else {
- my @words = <CHILD>;
- close CHILD;
- SKIP: {
- skip "@spell failed for $pod", 1 unless $? == 0;
- for (@words) {
- s/^\s+//;
- s/\s+$//;
- }
- is ("@words", '', $pod);
- }
- }
-}
diff --git a/cpan/podlators/t/pod.t b/cpan/podlators/t/pod.t
deleted file mode 100644
index e570e18bb4..0000000000
--- a/cpan/podlators/t/pod.t
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/perl -w
-#
-# Test POD formatting.
-#
-# Copyright 2009 Russ Allbery <rra@stanford.edu>
-#
-# This program is free software; you may redistribute it and/or modify it
-# under the same terms as Perl itself.
-
-use strict;
-use Test::More;
-eval 'use Test::Pod 1.00';
-plan skip_all => "Test::Pod 1.00 required for testing POD" if $@;
-all_pod_files_ok ();
diff --git a/cpan/podlators/t/style/minimum-version.t b/cpan/podlators/t/style/minimum-version.t
new file mode 100644
index 0000000000..e4eeafd209
--- /dev/null
+++ b/cpan/podlators/t/style/minimum-version.t
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+#
+# Check that too-new features of Perl are not being used.
+#
+# The canonical version of this file is maintained in the rra-c-util package,
+# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2013, 2014
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::More;
+use Test::RRA qw(skip_unless_automated use_prereq);
+use Test::RRA::Config qw($MINIMUM_VERSION);
+
+# Skip for normal user installs since this doesn't affect functionality.
+skip_unless_automated('Minimum version tests');
+
+# Load prerequisite modules.
+use_prereq('Test::MinimumVersion');
+
+# Check all files in the Perl distribution.
+all_minimum_version_ok($MINIMUM_VERSION);
diff --git a/cpan/podlators/t/style/module-version.t b/cpan/podlators/t/style/module-version.t
new file mode 100644
index 0000000000..0de70c4ee9
--- /dev/null
+++ b/cpan/podlators/t/style/module-version.t
@@ -0,0 +1,315 @@
+#!/usr/bin/perl
+#
+# Check or update the version of Perl modules.
+#
+# Examines all module files (*.pm) under the lib directory and verifies that
+# the package is set to the same value as the current version number as
+# determined by the MYMETA.json file at the top of the source distribution.
+#
+# When given the --update option, instead fixes all of the Perl modules found
+# to have the correct version.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Carp qw(croak);
+use File::Find qw(find);
+use Getopt::Long qw(GetOptions);
+use Test::More;
+use Test::RRA qw(skip_unless_automated use_prereq);
+
+# If we have options, we're being run from the command line and always load
+# our prerequisite modules. Otherwise, check if we have necessary
+# prerequisites and should run as a test suite.
+if (@ARGV) {
+ require JSON::PP;
+ require Perl6::Slurp;
+ Perl6::Slurp->import;
+} else {
+ skip_unless_automated('Module version tests');
+ use_prereq('JSON::PP');
+ use_prereq('Perl6::Slurp');
+}
+
+# A regular expression matching the version string for a module using the
+# package syntax from Perl 5.12 and later. $1 will contain all of the line
+# contents prior to the actual version string, $2 will contain the version
+# itself, and $3 will contain the rest of the line.
+our $REGEX_VERSION_PACKAGE = qr{
+ ( # prefix ($1)
+ \A \s* # whitespace
+ package \s+ # package keyword
+ [\w\:\']+ \s+ # package name
+ )
+ ( v? [\d._]+ ) # the version number itself ($2)
+ ( # suffix ($3)
+ \s* ;
+ )
+}xms;
+
+# A regular expression matching a $VERSION string in a module. $1 will
+# contain all of the line contents prior to the actual version string, $2 will
+# contain the version itself, and $3 will contain the rest of the line.
+our $REGEX_VERSION_OLD = qr{
+ ( # prefix ($1)
+ \A .* # any prefix, such as "our"
+ [\$*] # scalar or typeglob
+ [\w\:\']*\b # optional package name
+ VERSION\b # version variable
+ \s* = \s* # assignment
+ )
+ [\"\']? # optional leading quote
+ ( v? [\d._]+ ) # the version number itself ($2)
+ [\"\']? # optional trailing quote
+ ( # suffix ($3)
+ \s*
+ ;
+ )
+}xms;
+
+# Find all the Perl modules shipped in this package, if any, and returns the
+# list of file names.
+#
+# $dir - The root directory to search, lib by default
+#
+# Returns: List of file names
+sub module_files {
+ my ($dir) = @_;
+ $dir ||= 'lib';
+ return if !-d $dir;
+ my @files;
+ my $wanted = sub {
+ if ($_ eq 'blib') {
+ $File::Find::prune = 1;
+ return;
+ }
+ if (m{ [.] pm \z }xms) {
+ push(@files, $File::Find::name);
+ }
+ return;
+ };
+ find($wanted, $dir);
+ return @files;
+}
+
+# Given a module file, read it for the version value and return the value.
+#
+# $file - File to check, which should be a Perl module
+#
+# Returns: The version of the module
+# Throws: Text exception on I/O failure or inability to find version
+sub module_version {
+ my ($file) = @_;
+ open(my $data, q{<}, $file) or die "$0: cannot open $file: $!\n";
+ while (defined(my $line = <$data>)) {
+ if ( $line =~ $REGEX_VERSION_PACKAGE
+ || $line =~ $REGEX_VERSION_OLD)
+ {
+ my ($prefix, $version, $suffix) = ($1, $2, $3);
+ close($data) or die "$0: error reading from $file: $!\n";
+ return $version;
+ }
+ }
+ close($data) or die "$0: error reading from $file: $!\n";
+ die "$0: cannot find version number in $file\n";
+}
+
+# Return the current version of the distribution from MYMETA.json in the
+# current directory.
+#
+# Returns: The version number of the distribution
+# Throws: Text exception if MYMETA.json is not found or doesn't contain a
+# version
+sub dist_version {
+ my $json = JSON::PP->new->utf8(1);
+ my $metadata = $json->decode(scalar(slurp('MYMETA.json')));
+ my $version = $metadata->{version};
+ if (!defined($version)) {
+ die "$0: cannot find version number in MYMETA.json\n";
+ }
+ return $version;
+}
+
+# Given a module file and the new version for that module, update the version
+# in that module to the new one.
+#
+# $file - Perl module file whose version should be updated
+# $version - The new version number
+#
+# Returns: undef
+# Throws: Text exception on I/O failure or inability to find version
+sub update_module_version {
+ my ($file, $version) = @_;
+ open(my $in, q{<}, $file) or die "$0: cannot open $file: $!\n";
+ open(my $out, q{>}, "$file.new")
+ or die "$0: cannot create $file.new: $!\n";
+
+ # If the version starts with v, use it without quotes. Otherwise, quote
+ # it to prevent removal of trailing zeroes.
+ if ($version !~ m{ \A v }xms) {
+ $version = "'$version'";
+ }
+
+ # Scan for the version and replace it.
+ SCAN:
+ while (defined(my $line = <$in>)) {
+ if ( $line =~ s{ $REGEX_VERSION_PACKAGE }{$1$version$3}xms
+ || $line =~ s{ $REGEX_VERSION_OLD }{$1$version$3}xms)
+ {
+ print {$out} $line or die "$0: cannot write to $file.new: $!\n";
+ last SCAN;
+ }
+ print {$out} $line or die "$0: cannot write to $file.new: $!\n";
+ }
+
+ # Copy the rest of the input file to the output file.
+ print {$out} <$in> or die "$0: cannot write to $file.new: $!\n";
+ close($out) or die "$0: cannot flush $file.new: $!\n";
+ close($in) or die "$0: error reading from $file: $!\n";
+
+ # All done. Rename the new file over top of the old file.
+ rename("$file.new", $file)
+ or die "$0: cannot rename $file.new to $file: $!\n";
+ return;
+}
+
+# Act as a test suite. Find all of the Perl modules in the package, if any,
+# and check that the version for each module matches the version of the
+# distribution. Reports results with Test::More and sets up a plan based on
+# the number of modules found.
+#
+# Returns: undef
+# Throws: Text exception on fatal errors
+sub test_versions {
+ my $dist_version = dist_version();
+ my @modules = module_files();
+
+ # Output the plan. Skip the test if there were no modules found.
+ if (@modules) {
+ plan tests => scalar(@modules);
+ } else {
+ plan skip_all => 'No Perl modules found';
+ return;
+ }
+
+ # For each module, get the module version and compare.
+ for my $module (@modules) {
+ my $module_version = module_version($module);
+ is($module_version, $dist_version, "Version for $module");
+ }
+ return;
+}
+
+# Update the versions of all modules to the current distribution version.
+#
+# Returns: undef
+# Throws: Text exception on fatal errors
+sub update_versions {
+ my $version = dist_version();
+ my @modules = module_files();
+ for my $module (@modules) {
+ update_module_version($module, $version);
+ }
+ return;
+}
+
+# Main routine. We run as either a test suite or as a script to update all of
+# the module versions, selecting based on whether we got the -u / --update
+# command-line option.
+my $update;
+Getopt::Long::config('bundling', 'no_ignore_case');
+GetOptions('update|u' => \$update) or exit 1;
+if ($update) {
+ update_versions();
+} else {
+ test_versions();
+}
+exit 0;
+__END__
+
+=for stopwords
+Allbery sublicense MERCHANTABILITY NONINFRINGEMENT CPAN
+
+=head1 NAME
+
+module-version.t - Check or update versions of Perl modules
+
+=head1 SYNOPSIS
+
+B<module-version.t> [B<--update>]
+
+=head1 REQUIREMENTS
+
+Perl 5.6.0 or later, the Perl6::Slurp module, and the JSON::PP Perl
+module, both of which are available from CPAN. JSON::PP is also included
+in Perl core in Perl 5.14 and later.
+
+=head1 DESCRIPTION
+
+This script has a dual purpose as either a test script or a utility
+script. The intent is to assist with maintaining consistent versions in a
+Perl distribution, supporting both the package keyword syntax introduced
+in Perl 5.12 or the older explicit setting of a $VERSION variable.
+
+As a test, it reads the current version of a package from the
+F<MYMETA.json> file in the current directory (which should be the root of
+the distribution) and then looks for any Perl modules in F<lib>. If it
+finds any, it checks that the version number of the Perl module matches
+the version number of the package from the F<MYMETA.json> file. These
+test results are reported with Test::More, suitable for any TAP harness.
+
+As a utility script, when run with the B<--update> option, it similarly
+finds all Perl modules in F<lib> and then rewrites their version setting
+to match the version of the package as determined from the F<MYMETA.json>
+file.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-u>, B<--update>
+
+Rather than test the Perl modules for the correct version, update all
+Perl modules found in the tree under F<lib> to the current version
+from the C<MYMETA.json> file.
+
+=back
+
+=head1 AUTHOR
+
+Russ Allbery <eagle@eyrie.org>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2013, 2014 The Board of Trustees of the Leland Stanford Junior
+University
+
+Copyright 2014, 2015 Russ Allbery <eagle@eyrie.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+=head1 SEE ALSO
+
+This module is maintained in the rra-c-util package. The current version
+is available from L<http://www.eyrie.org/~eagle/software/rra-c-util/>.
+
+=cut
diff --git a/cpan/podlators/t/style/strict.t b/cpan/podlators/t/style/strict.t
new file mode 100644
index 0000000000..7137b15226
--- /dev/null
+++ b/cpan/podlators/t/style/strict.t
@@ -0,0 +1,56 @@
+#!/usr/bin/perl
+#
+# Test Perl code for strict, warnings, and syntax.
+#
+# The canonical version of this file is maintained in the rra-c-util package,
+# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2013, 2014
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use File::Spec;
+use Test::RRA qw(skip_unless_automated use_prereq);
+
+# Skip for normal user installs since this doesn't affect functionality.
+skip_unless_automated('Strictness tests');
+
+# Load prerequisite modules.
+use_prereq('Test::Strict');
+
+# Test everything in the distribution directory except the Build and
+# Makefile.PL scripts generated by Module::Build. We also want to check use
+# warnings.
+$Test::Strict::TEST_SKIP = ['Build', 'Makefile.PL'];
+$Test::Strict::TEST_WARNINGS = 1;
+all_perl_files_ok(File::Spec->curdir);
+
+# Hack to suppress "used only once" warnings.
+END {
+ $Test::Strict::TEST_SKIP = [];
+ $Test::Strict::TEST_WARNINGS = 0;
+}
diff --git a/cpan/podlators/t/text.t b/cpan/podlators/t/text/basic.t
index 223e0b0d90..1d274c3e5c 100644
--- a/cpan/podlators/t/text.t
+++ b/cpan/podlators/t/text/basic.t
@@ -3,7 +3,7 @@
# text.t -- Additional specialized tests for Pod::Text.
#
# Copyright 2002, 2004, 2006, 2007, 2008, 2009, 2012
-# Russ Allbery <rra@stanford.edu>
+# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
# under the same terms as Perl itself.
diff --git a/cpan/podlators/t/color.t b/cpan/podlators/t/text/color.t
index 4fd1bd1e79..c2e13335ad 100644
--- a/cpan/podlators/t/color.t
+++ b/cpan/podlators/t/text/color.t
@@ -3,7 +3,7 @@
# color.t -- Additional specialized tests for Pod::Text::Color.
#
# Copyright 2002, 2004, 2006, 2009, 2012, 2013
-# Russ Allbery <rra@stanford.edu>
+# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
# under the same terms as Perl itself.
diff --git a/cpan/podlators/t/text-empty.t b/cpan/podlators/t/text/empty.t
index 2164a75748..0b8823a3e5 100644
--- a/cpan/podlators/t/text-empty.t
+++ b/cpan/podlators/t/text/empty.t
@@ -2,7 +2,7 @@
#
# text-empty.t -- Test Pod::Text with a document that produces only errors.
#
-# Copyright 2013 Russ Allbery <rra@stanford.edu>
+# Copyright 2013 Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
# under the same terms as Perl itself.
diff --git a/cpan/podlators/t/text-encoding.t b/cpan/podlators/t/text/encoding.t
index d096b37b05..7fe7401d59 100644
--- a/cpan/podlators/t/text-encoding.t
+++ b/cpan/podlators/t/text/encoding.t
@@ -2,8 +2,8 @@
#
# text-encoding.t -- Test Pod::Text with various weird encoding combinations.
#
-# Copyright 2002, 2004, 2006, 2007, 2008, 2009, 2012
-# Russ Allbery <rra@stanford.edu>
+# Copyright 2002, 2004, 2006, 2007, 2008, 2009, 2012, 2015
+# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
# under the same terms as Perl itself.
@@ -26,7 +26,7 @@ BEGIN {
if ($] < 5.008) {
plan skip_all => 'Perl 5.8 required for encoding support';
} else {
- plan tests => 5;
+ plan tests => 7;
}
}
BEGIN { use_ok ('Pod::Text') }
@@ -127,3 +127,30 @@ I can eat glass
See <http://www.columbia.edu/kermit/utf8.html>
###
+
+###
+=pod
+
+=head1 NAME
+
+This is the first ascii text
+
+=encoding utf8
+
+=over 4
+
+=item ⇒This is the first non-ascii text⇐
+
+This is the second ascii text
+
+=back
+
+=cut
+###
+NAME
+ This is the first ascii text
+
+ ⇒This is the first non-ascii text⇐
+ This is the second ascii text
+
+###
diff --git a/cpan/podlators/t/text-options.t b/cpan/podlators/t/text/options.t
index 06bf081843..3338aa63c2 100644
--- a/cpan/podlators/t/text-options.t
+++ b/cpan/podlators/t/text/options.t
@@ -2,8 +2,8 @@
#
# Additional tests for Pod::Text options.
#
-# Copyright 2002, 2004, 2006, 2008, 2009, 2012, 2013
-# Russ Allbery <rra@stanford.edu>
+# Copyright 2002, 2004, 2006, 2008, 2009, 2012, 2013, 2015
+# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
# under the same terms as Perl itself.
@@ -19,7 +19,7 @@ BEGIN {
use strict;
-use Test::More tests => 34;
+use Test::More tests => 37;
BEGIN { use_ok ('Pod::Text') }
# Redirect stderr to a file.
@@ -351,3 +351,16 @@ Bar.
NEXT
###
###
+
+###
+quotes <<<>>>
+###
+=head1 FOO C<BAR> BAZ
+
+Foo C<bar> baz.
+###
+FOO <<<BAR>>> BAZ
+ Foo <<<bar>>> baz.
+
+###
+###
diff --git a/cpan/podlators/t/overstrike.t b/cpan/podlators/t/text/overstrike.t
index 13ee2c87d3..c5496bb871 100644
--- a/cpan/podlators/t/overstrike.t
+++ b/cpan/podlators/t/text/overstrike.t
@@ -3,7 +3,7 @@
# overstrike.t -- Additional specialized tests for Pod::Text::Overstrike.
#
# Copyright 2002, 2004, 2006, 2009, 2012, 2013
-# Russ Allbery <rra@stanford.edu>
+# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
# under the same terms as Perl itself.
diff --git a/cpan/podlators/t/text-perlio.t b/cpan/podlators/t/text/perlio.t
index fe50ca1856..c95f682b68 100644
--- a/cpan/podlators/t/text-perlio.t
+++ b/cpan/podlators/t/text/perlio.t
@@ -2,8 +2,8 @@
#
# text-perlio.t -- Test Pod::Text with a PerlIO UTF-8 encoding layer.
#
-# Copyright 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2012
-# Russ Allbery <rra@stanford.edu>
+# Copyright 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2012, 2014
+# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
# under the same terms as Perl itself.
@@ -31,18 +31,22 @@ BEGIN {
}
BEGIN { use_ok ('Pod::Text') }
+# Force UTF-8 on all relevant file handles. Hide this in a string eval so
+# that older versions of Perl don't croak and minimum-version tests still
+# pass.
+eval 'binmode (\*DATA, ":encoding(utf-8)")';
+eval 'binmode (\*STDOUT, ":encoding(utf-8)")';
+my $builder = Test::More->builder;
+eval 'binmode ($builder->output, ":encoding(utf-8)")';
+eval 'binmode ($builder->failure_output, ":encoding(utf-8)")';
+
my $parser = Pod::Text->new (utf8 => 1);
isa_ok ($parser, 'Pod::Text', 'Parser object');
my $n = 1;
-eval { binmode (\*DATA, ':encoding(utf-8)') };
-eval { binmode (\*STDOUT, ':encoding(utf-8)') };
-my $builder = Test::More->builder;
-eval { binmode ($builder->output, ':encoding(utf-8)') };
-eval { binmode ($builder->failure_output, ':encoding(utf-8)') };
while (<DATA>) {
next until $_ eq "###\n";
open (TMP, "> tmp$$.pod") or die "Cannot create tmp$$.pod: $!\n";
- eval { binmode (\*TMP, ':encoding(utf-8)') };
+ eval 'binmode (\*TMP, ":encoding(utf-8)")';
print TMP "=encoding UTF-8\n\n";
while (<DATA>) {
last if $_ eq "###\n";
@@ -50,11 +54,11 @@ while (<DATA>) {
}
close TMP;
open (OUT, "> out$$.tmp") or die "Cannot create out$$.tmp: $!\n";
- eval { binmode (\*OUT, ':encoding(utf-8)') };
+ eval 'binmode (\*OUT, ":encoding(utf-8)")';
$parser->parse_from_file ("tmp$$.pod", \*OUT);
close OUT;
open (TMP, "out$$.tmp") or die "Cannot open out$$.tmp: $!\n";
- eval { binmode (\*TMP, ':encoding(utf-8)') };
+ eval 'binmode (\*TMP, ":encoding(utf-8)")';
my $output;
{
local $/;
diff --git a/cpan/podlators/t/termcap.t b/cpan/podlators/t/text/termcap.t
index d751bad613..4b30c62fc3 100644
--- a/cpan/podlators/t/termcap.t
+++ b/cpan/podlators/t/text/termcap.t
@@ -2,8 +2,8 @@
#
# termcap.t -- Additional specialized tests for Pod::Text::Termcap.
#
-# Copyright 2002, 2004, 2006, 2009, 2012, 2013
-# Russ Allbery <rra@stanford.edu>
+# Copyright 2002, 2004, 2006, 2009, 2012, 2013, 2014
+# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
# under the same terms as Perl itself.
@@ -19,13 +19,29 @@ BEGIN {
use strict;
+use File::Spec;
use Test::More tests => 4;
+
BEGIN { use_ok ('Pod::Text::Termcap') }
+# Find the path to the test source files. This requires some fiddling when
+# these tests are run as part of Perl core.
+sub source_path {
+ my $file = shift;
+ if ($ENV{PERL_CORE}) {
+ my $updir = File::Spec->updir;
+ my $dir = File::Spec->catdir ($updir, 'lib', 'Pod', 't', 'data');
+ return File::Spec->catfile ($dir, $file);
+ } else {
+ return File::Spec->catfile ('data', $file);
+ }
+}
+
# Hard-code a few values to try to get reproducible results.
-$ENV{COLUMNS} = 80;
-$ENV{TERM} = 'xterm';
-$ENV{TERMCAP} = 'xterm:co=80:do=^J:md=\E[1m:us=\E[4m:me=\E[m';
+$ENV{COLUMNS} = 80;
+$ENV{TERM} = 'xterm';
+$ENV{TERMPATH} = source_path ('termcap');
+$ENV{TERMCAP} = 'xterm:co=#80:do=^J:md=\E[1m:us=\E[4m:me=\E[m';
my $parser = Pod::Text::Termcap->new;
isa_ok ($parser, 'Pod::Text::Termcap', 'Parser module');
diff --git a/cpan/podlators/t/text-utf8.t b/cpan/podlators/t/text/utf8.t
index 822f1ea31f..e468c57d0d 100644
--- a/cpan/podlators/t/text-utf8.t
+++ b/cpan/podlators/t/text/utf8.t
@@ -2,8 +2,8 @@
#
# text-utf8.t -- Test Pod::Text with UTF-8 input.
#
-# Copyright 2002, 2004, 2006, 2007, 2008, 2009, 2012
-# Russ Allbery <rra@stanford.edu>
+# Copyright 2002, 2004, 2006, 2007, 2008, 2009, 2012, 2014
+# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
# under the same terms as Perl itself.
@@ -31,18 +31,22 @@ BEGIN {
}
BEGIN { use_ok ('Pod::Text') }
+# Force UTF-8 on all relevant file handles. Hide this in a string eval so
+# that older versions of Perl don't croak and minimum-version tests still
+# pass.
+eval 'binmode (\*DATA, ":encoding(utf-8)")';
+eval 'binmode (\*STDOUT, ":encoding(utf-8)")';
+my $builder = Test::More->builder;
+eval 'binmode ($builder->output, ":encoding(utf-8)")';
+eval 'binmode ($builder->failure_output, ":encoding(utf-8)")';
+
my $parser = Pod::Text->new;
isa_ok ($parser, 'Pod::Text', 'Parser object');
my $n = 1;
-eval { binmode (\*DATA, ':encoding(utf-8)') };
-eval { binmode (\*STDOUT, ':encoding(utf-8)') };
-my $builder = Test::More->builder;
-eval { binmode ($builder->output, ':encoding(utf-8)') };
-eval { binmode ($builder->failure_output, ':encoding(utf-8)') };
while (<DATA>) {
next until $_ eq "###\n";
open (TMP, "> tmp$$.pod") or die "Cannot create tmp$$.pod: $!\n";
- eval { binmode (\*TMP, ':encoding(utf-8)') };
+ eval 'binmode (\*TMP, ":encoding(utf-8)")';
print TMP "=encoding UTF-8\n\n";
while (<DATA>) {
last if $_ eq "###\n";
@@ -53,7 +57,7 @@ while (<DATA>) {
$parser->parse_from_file ("tmp$$.pod", \*OUT);
close OUT;
open (TMP, "out$$.tmp") or die "Cannot open out$$.tmp: $!\n";
- eval { binmode (\*TMP, ':encoding(utf-8)') };
+ eval 'binmode (\*TMP, ":encoding(utf-8)")';
my $output;
{
local $/;