POD::Tested - Test the code in your POD and generates POD.
my $parser = POD::Tested->new(@options); $parser->parse_from_file($input_file) ; #or $parser->parse_from_filehandle($input_filehandle) ; write_file($output, $parser->GetPOD()) ;
This module lets you write POD documents that are testable. It also let's you generate pod sections dynamically.
Any verbatim section (indented section) is considered part of the POD and the code to be tested. See the not_tested tag for verbatim sections that are not code.
I wrote this module because I wanted a mechanism to verify the code I write in my POD. Code changes, output changes and I would like my documentation to always be up to date.
The installation procedure should install a pod_tested.pl that you can use to verify your POD. This module is very simple to use and has but a few commands. Since it's rather difficult to explain simple things, I'll use an example based approach.
Please give me feedback on the documentation or some examples and I'll integrate them in module's documentation.
=head1 Config::Hierarchical cookbook =head2 Simple usage Some Text =cut
Let's run the above POD through pod_tested.pl.
$> perl pod_tested.pl -input simple.pod -output simple.tested.pod # Generating POD in 'simple.tested.pod'. # No tests run! $> cat simple.tested.pod =head1 cookbook =head2 Simple usage Some Text =cut
=head1 cookbook =head2 Simple usage Some Text =begin hidden my $cc = 'cc' ; my $expected_cc = 'cc' ; is($cc, $expected_cc, 'expected value') ; =end hidden
$> perl pod_tested.pl -input test.pod -output test.tested.pod # output from 'script/test.pod:9': ok 1 - expected value # Generating POD in 'test.tested.pod'. 1..1
The Generated POD output goes to the output file you specified. You get the test output on your terminal. The POD would look like:
=head1 cookbook =head2 Simple usage Some Text =cut
Note that your test code is not part of the generated POD.
Most often we want to show an example in the POD and verify it.
=head1 Config::Hierarchical cookbook =head2 Simple usage Some text use Config::Hierarchical ; my $config = new Config::Hierarchical(); $config->Set(NAME => 'CC', VALUE => 'acc') ; $config->Set(NAME => 'CC', VALUE => 'gcc') ; my $cc_value = $config->Get(NAME => 'CC') ; print "CC = '$cc_value'\n" ; =begin hidden my $expected_output = 'gcc' ; is($cc_value, $expected_output, 'expected value') ; =end hidden =cut
$> perl pod_tested.pl -input common.pod -output common.tested.pod # output from 'script/common.pod:9': CC = 'gcc' # output from 'script/common.pod:24': ok 1 - expected value # Generating POD in 'common.tested.pod'. 1..1
The POD is:
=head1 Config::Hierarchical cookbook =head2 Simple usage Some text use Config::Hierarchical ; my $config = new Config::Hierarchical(); $config->Set(NAME => 'CC', VALUE => 'acc') ; $config->Set(NAME => 'CC', VALUE => 'gcc') ; my $cc_value = $config->Get(NAME => 'CC') ; print "CC = '$cc_value'\n" ; =cut
=head1 cookbook =head2 Simple usage Some Text =begin hidden my $cc = 'cc' ; my $expected_cc = 'cc' ; is($cc_value, $expected_output) ; =end hidden
$> perl pod_tested.pl -input test.pod -output test.tested.pod Global symbol "$cc_value" requires explicit package name at 'script/test.pod' line 12, <$in_fh> line 15. Global symbol "$expected_output" requires explicit package name at 'script/test.pod' line 12, <$in_fh> line 15. at script/pod_tested.pl line 31 # Looks like your test died before it could output anything.
Oops! This is a rather common error, copy/pasting code and modifying it for pod.
The following pod:
=head1 HEADER my $cc = ; my $expected_cc = 'cc' ; is($cc, $expected_cc) ; =cut
produces:
syntax error at 'script/error_1.pod' line 9, at EOF at script/pod_tested.pl line 31 # Looks like your test died before it could output anything.
while:
=head1 HEADER sub error { 1/0 } error() ; =cut
Illegal division by zero at 'script/error_2.pod' line 5, <$in_fh> line 10. at script/pod_tested.pl line 31 # Looks like your test died before it could output anything.
=head1 HEADER Some text my $cc_value = 'CC' ; print "CC = '$cc_value'\n" ; More text or code examples. =begin not_tested # this section is not part of the test but is part of the POD my $non_tested_code = 1 ; DoSomething() ; =end not_tested =begin hidden my $expected_output = 'gcc' ; is($cc_value, $expected_output) ; =end hidden =cut
The example above defines a variable in a section and uses it in another section.
the output would be:
# output from 'script/context.pod:7': CC = 'CC' # output from 'script/context.pod:20': not ok 1 # Failed test at 'script/context.pod' line 21. # got: 'CC' # expected: 'gcc' # No POD output will be generated. # Failed tests: 1. 1..1 # Looks like you failed 1 test of 1.
Note that any test fails and the output file already exists, pod_tested will rename the existing file so there is little risk for using an invalid file.
=head1 HEADER =head2 Example 1 my $cc_value = 'CC' ; <Some explaination about test 1 here> =begin hidden is($cc_value, 'CC') ; =end hidden =head2 Example 2 my $cc_value = 'ABC' ; <Some explaination about test 2 here> =begin hidden is($cc_value, 'ABC') ; =end hidden =cut
Running the above pod gives the following output:
# output from 'script/new_context_error.pod:7': # output from 'script/new_context_error.pod:16': ok 1 - expected value "my" variable $cc_value masks earlier declaration in same scope at 'script/new_context_error.pod' line 24, <$in_fh> line 27. # output from 'script/new_context_error.pod:24': # output from 'script/new_context_error.pod:32': ok 2 - expected value # Generating POD in 'new_context_error.tested.pod'. 1..2
Local variables are kept between test sections. What we want is two separate section. This can be achieved with =for POD::Tested reset
=head1 HEADER = head2 Example 1 my $cc_value = 'CC' ; <Some explaination about test 1 here> =begin hidden is($cc_value, 'CC') ; =end hidden =head2 Example 2 =for POD::Tested reset my $cc_value = 'ABC' ; <Some explaination about test 2 here> =begin hidden is($cc_value, 'ABC') ; =end hidden =cut
Gives:
# output from 'script/new_context.pod:7': # output from 'script/new_context.pod:15': ok 1 - expected value # output from 'script/new_context.pod:25': # output from 'script/new_context.pod:33': ok 2 - expected value # Generating POD in 'new_contex.tested.pod'. 1..2
and this POD:
=head1 HEADER = head2 Example 1 my $cc_value = 'CC' ; <Some explaination about test 1 here> =head2 Example 2 my $cc_value = 'ABC' ; <Some explaination about test 2 here> =cut
So far we have code in pod that we can test and the code itself is kept as part of the generated POD. Let's add the result of some code execution to the POD. We'll use generate_pod to achieve that.
=head1 Config::Hierarchical cookbook =head2 Simple usage use Config::Hierarchical ; my $config = new Config::Hierarchical(); $config->Set(NAME => 'CC', VALUE => 'acc') ; my $cc_value = $config->Get(NAME => 'CC') ; print "CC = '$cc_value'\n" ; Result: =begin hidden my $expected_output = 'acc' ; is($cc_value, $expected_output) ; generate_pod(" CC = '$expected_output'\n\n") ; generate_pod($config->GetHistoryDump(NAME => 'CC')) ; =end hidden =cut
running this gives this output:
# output from 'script/generate_pod.pod:10': CC = 'acc' # output from 'script/generate_pod.pod:24': ok 1 - expected value # Generating POD in 'generate_pod.tested.pod.pod'. 1..1
and the generated POD looks like:
=head1 Config::Hierarchical cookbook =head2 Simple usage use Config::Hierarchical ; my $config = new Config::Hierarchical(); $config->Set(NAME => 'CC', VALUE => 'acc') ; my $cc_value = $config->Get(NAME => 'CC') ; print "CC = '$cc_value'\n" ; Result: CC = 'acc' History for variable 'CC' from config 'Anonymous' created at ''script/generate_pod.pod':13': `- 0 |- EVENT = CREATE AND SET. value = 'acc', category = 'CURRENT' at ''script/generate_pod.pod':14', status = OK. `- TIME = 0 =cut
you don't need to copy/paste output from your modules into your POD as you can generate it directly.
simply use the modules you need in a =begin hidden section.
=begin hidden use Test::Some::Great::Module ; =end hidden
You must, in the new sub, pass what your POD source is with one of the following options:
FILE_HANDLE
FILE
STRING
Other options:
VERBOSE
Set to true to display extra information when parsing and testing POD.
VERBOSE_POD_GENERATION
Set to true to display the POD added through generate_pod().
NOT_TESTED
The tag that is used to declare a section that are not common to the POD and the tests.
default value is:
qr/\s*not_tested/xmi
HIDDEN_TAG
The tag that is used to declare a test section.
qr/\s*hidden/xmi
RESET_TAG
The tag that is used to reset the lexical context. Type is a qr.
qr/\s*POD::Tested\s+reset/xmi
DEFAULT_TEST_MODULES
the test modules loaded when POD::Tested starts.
use Test::More ; use Test::Block qw($Plan); use Test::Exception ; use Test::Warn ; plan qw(no_plan) unless(defined Test::More->builder->has_plan());
if you use Test::More, which you should, the last line is necessary only when POD::Tested is installed or tested.
Handles POD commands. See Pod::Parser for more information.
Not to be used directly.
Handles POD verbatim sections. See Pod::Parser for more information.
Handles POD textblocks. See Pod::Parser for more information.
Returns the result of parsing and testing your POD. You can pass the result to pod2html or other pod transformers.
None so far.
Khemir Nadim ibn Hamouda CPAN ID: NKH mailto:nadim@khemir.net
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
You can find documentation for this module with the perldoc command.
perldoc POD::Tested
You can also look for information at:
AnnoCPAN: Annotated CPAN documentation
http://annocpan.org/dist/POD-Tested
RT: CPAN's request tracker
Please report any bugs or feature requests to L <bug-pod-tested@rt.cpan.org>.
We will be notified, and then you'll automatically be notified of progress on your bug as we make changes.
Search CPAN
http://search.cpan.org/dist/POD-Tested
Test::Inline
Test::Pod::Snippets
Lexical::Persistence
http://chainsawblues.vox.com/library/post/writing-a-perl-repl-part-3---lexical-environments.html
To install POD::Tested, copy and paste the appropriate command in to your terminal.
cpanm
cpanm POD::Tested
CPAN shell
perl -MCPAN -e shell install POD::Tested
For more information on module installation, please visit the detailed CPAN module installation guide.