1 #============================================================= -*-Perl-*-
6 # Module defining a test harness which processes template input and
7 # then compares the output against pre-define expected output.
8 # Generates test output compatible with Test::Harness. This was
9 # originally the t/texpect.pl script.
12 # Andy Wardley <abw@wardley.org>
15 # Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
17 # This module is free software; you can redistribute it and/or
18 # modify it under the same terms as Perl itself.
20 #============================================================================
22 package Template::Test;
26 use Template qw( :template );
31 our @ISA = qw( Exporter );
32 our @EXPORT = qw( ntests ok is match flush skip_all test_expect callsign banner );
33 our @EXPORT_OK = ( 'assert' );
34 our %EXPORT_TAGS = ( all => [ @EXPORT_OK, @EXPORT ] );
37 our $REASON = 'not applicable on this platform';
39 our $EXTRA = 0; # any extra tests to come after test_expect()
40 our $PRESERVE = 0 # don't mangle newlines in output/expect
41 unless defined $PRESERVE;
43 our ($loaded, %callsign);
45 # always set binmode on Win32 machines so that any output generated
46 # is true to what we expect
47 $Template::BINMODE = ($^O eq 'MSWin32') ? 1 : 0;
50 my ($ntests, $ok_count);
54 # ensure flush() is called to print any cached results
59 #------------------------------------------------------------------------
62 # Declare how many (more) tests are expected to come. If ok() is called
63 # before ntests() then the results are cached instead of being printed
64 # to STDOUT. When ntests() is called, the total number of tests
65 # (including any cached) is known and the "1..$ntests" line can be
66 # printed along with the cached results. After that, calls to ok()
67 # generated printed output immediately.
68 #------------------------------------------------------------------------
72 # add any pre-declared extra tests, or pre-stored test @results, to
73 # the grand total of tests
74 $ntests += $EXTRA + scalar @results;
76 print $ntests ? "1..$ntests\n" : "1..$ntests # skip $REASON\n";
77 # flush cached results
78 foreach my $pre_test (@results) {
84 #------------------------------------------------------------------------
87 # Tests the value passed for truth and generates an "ok $n" or "not ok $n"
88 # line accordingly. If ntests() hasn't been called then we cached
89 # results for later, instead.
90 #------------------------------------------------------------------------
95 # cache results if ntests() not yet called
97 push(@results, [ $ok, $msg ]);
101 $msg = defined $msg ? " - $msg" : '';
103 print "ok ", $ok_count++, "$msg\n";
106 print STDERR "FAILED $ok_count: $msg\n" if defined $msg;
107 print "not ok ", $ok_count++, "$msg\n";
113 #------------------------------------------------------------------------
114 # assert($truth, $error)
116 # Test value for truth, die if false.
117 #------------------------------------------------------------------------
124 my ($pkg, $file, $line) = caller();
125 $err ||= "assert failed";
126 $err .= " at $file line $line\n";
131 #------------------------------------------------------------------------
132 # match( $result, $expect )
133 #------------------------------------------------------------------------
136 my ($result, $expect, $msg) = @_;
137 my $count = $ok_count ? $ok_count : scalar @results + 1;
139 # force stringification of $result to avoid 'no eq method' overload errors
140 $result = "$result" if ref $result;
142 if ($result eq $expect) {
146 print STDERR "FAILED $count:\n expect: [$expect]\n result: [$result]\n";
152 #------------------------------------------------------------------------
155 # Flush any tests results.
156 #------------------------------------------------------------------------
160 unless $ok_count || $NO_FLUSH;
164 #------------------------------------------------------------------------
167 # Skip all tests, setting $REASON to contain any message passed. Calls
168 # exit(0) which triggers flush() which generates a "1..0 # $REASON"
169 # string to keep to test harness happy.
170 #------------------------------------------------------------------------
173 $REASON = join('', @_);
178 #------------------------------------------------------------------------
179 # test_expect($input, $template, \%replace)
181 # This is the main testing sub-routine. The $input parameter should be a
182 # text string or a filehandle reference (e.g. GLOB or IO::Handle) from
183 # which the input text can be read. The input should contain a number
184 # of tests which are split up and processed individually, comparing the
185 # generated output against the expected output. Tests should be defined
196 # The number of tests is determined and ntests() is called to generate
197 # the "0..$n" line compatible with Test::Harness. Each test input is
198 # then processed by the Template object passed as the second parameter,
199 # $template. This may also be a hash reference containing configuration
200 # which are used to instantiate a Template object, or may be left
201 # undefined in which case a default Template object will be instantiated.
202 # The third parameter, also optional, may be a reference to a hash array
203 # defining template variables. This is passed to the template process()
205 #------------------------------------------------------------------------
208 my ($src, $tproc, $params) = @_;
210 my ($output, $expect, $match);
217 $input = ref $src ? <$src> : $src;
221 warn "Cannot read input text from $src\n";
225 # remove any comment lines
226 $input =~ s/^#.*?\n//gm;
228 # remove anything before '-- start --' and/or after '-- stop --'
229 $input = $' if $input =~ /\s*--\s*start\s*--\s*/;
230 $input = $` if $input =~ /\s*--\s*stop\s*--\s*/;
232 @tests = split(/^\s*--\s*test\s*--\s*\n/im, $input);
234 # if the first line of the file was '--test--' (optional) then the
235 # first test will be empty and can be discarded
236 shift(@tests) if $tests[0] =~ /^\s*$/;
238 ntests(3 + scalar(@tests) * 2);
240 # first test is that Template loaded OK, which it did
241 ok(1, 'running test_expect()');
243 # optional second param may contain a Template reference or a HASH ref
244 # of constructor options, or may be undefined
245 if (ref($tproc) eq 'HASH') {
246 # create Template object using hash of config items
247 $tproc = Template->new($tproc)
248 || die Template->error(), "\n";
250 elsif (ref($tproc) eq 'ARRAY') {
251 # list of [ name => $tproc, name => $tproc ], use first $tproc
252 $ttprocs = { @$tproc };
253 $tproc = $tproc->[1];
255 elsif (! ref $tproc) {
256 $tproc = Template->new()
257 || die Template->error(), "\n";
259 # otherwise, we assume it's a Template reference
261 # test: template processor created OK
262 ok($tproc, 'template processor is engaged');
264 # third test is that the input read ok, which it did
265 ok(1, 'input read and split into ' . scalar @tests . ' tests');
267 # the remaining tests are defined in @tests...
268 foreach $input (@tests) {
272 if ($input =~ s/^\s*-- name:? (.*?) --\s*\n//im) {
276 $name = "template text $count";
279 # split input by a line like "-- expect --"
281 split(/^\s*--\s*expect\s*--\s*\n/im, $input);
283 unless defined $expect;
287 # input text may be prefixed with "-- use name --" to indicate a
288 # Template object in the $ttproc hash which we should use
289 if ($input =~ s/^\s*--\s*use\s+(\S+)\s*--\s*\n//im) {
292 if ($ttlookup = $ttprocs->{ $ttname }) {
296 warn "no such template object to use: $ttname\n";
301 $tproc->process(\$input, $params, \$output) || do {
302 warn "Template process failed: ", $tproc->error(), "\n";
303 # report failure and automatically fail the expect match
304 ok(0, "$name process FAILED: " . subtext($input));
305 ok(0, '(obviously did not match expected)');
310 ok(1, "$name processed OK: " . subtext($input));
312 # another hack: if the '-- expect --' section starts with
313 # '-- process --' then we process the expected output
314 # before comparing it with the generated output. This is
315 # slightly twisted but it makes it possible to run tests
316 # where the expected output isn't static. See t/date.t for
319 if ($expect =~ s/^\s*--+\s*process\s*--+\s*\n//im) {
321 $tproc->process(\$expect, $params, \$out) || do {
322 warn("Template process failed (expect): ",
323 $tproc->error(), "\n");
324 # report failure and automatically fail the expect match
325 ok(0, "failed to process expected output ["
326 . subtext($expect) . ']');
332 # strip any trailing blank lines from expected and real output
333 foreach ($expect, $output) {
337 $match = ($expect eq $output) ? 1 : 0;
338 if (! $match || $DEBUG) {
339 print "MATCH FAILED\n"
342 my ($copyi, $copye, $copyo) = ($input, $expect, $output);
344 foreach ($copyi, $copye, $copyo) {
348 printf(" input: [%s]\nexpect: [%s]\noutput: [%s]\n",
349 $copyi, $copye, $copyo);
352 ok($match, $match ? "$name matched expected" : "$name did not match expected");
356 #------------------------------------------------------------------------
359 # Returns a hash array mapping lower a..z to their phonetic alphabet
361 #------------------------------------------------------------------------
365 @callsign{ 'a'..'z' } = qw(
366 alpha bravo charlie delta echo foxtrot golf hotel india
367 juliet kilo lima mike november oscar papa quebec romeo
368 sierra tango umbrella victor whisky x-ray yankee zulu );
373 #------------------------------------------------------------------------
376 # Prints a banner with the specified text if $DEBUG is set.
377 #------------------------------------------------------------------------
380 return unless $DEBUG;
381 my $text = join('', @_);
382 my $count = $ok_count ? $ok_count - 1 : scalar @results;
383 print "-" x 72, "\n$text ($count tests completed)\n", "-" x 72, "\n";
390 $text = substr($text, 0, 32) . '...' if length $text > 32;
402 Template::Test - Module for automating TT2 test scripts
408 $Template::Test::DEBUG = 0; # set this true to see each test running
409 $Template::Test::EXTRA = 2; # 2 extra tests follow test_expect()...
411 # ok() can be called any number of times before test_expect
414 # test_expect() splits $input into individual tests, processes each
415 # and compares generated output against expected output
416 test_expect($input, $template, \%replace );
418 # $input is text or filehandle (e.g. DATA section after __END__)
419 test_expect( $text );
420 test_expect( \*DATA );
422 # $template is a Template object or configuration hash
423 my $template_cfg = { ... };
424 test_expect( $input, $template_cfg );
425 my $template_obj = Template->new($template_cfg);
426 test_expect( $input, $template_obj );
428 # $replace is a hash reference of template variables
433 test_expect( $input, $template, $replace );
435 # ok() called after test_expect should be declared in $EXTRA (2)
441 The C<Template::Test> module defines the L<test_expect()> and other related
442 subroutines which can be used to automate test scripts for the
443 Template Toolkit. See the numerous tests in the F<t> sub-directory of
444 the distribution for examples of use.
446 =head1 PACKAGE SUBROUTINES
450 The C<test_expect()> subroutine splits an input document into a number
451 of separate tests, processes each one using the Template Toolkit and
452 then compares the generated output against an expected output, also
453 specified in the input document. It generates the familiar
454 C<ok>/C<not ok> output compatible with C<Test::Harness>.
456 The test input should be specified as a text string or a reference to
457 a filehandle (e.g. C<GLOB> or C<IO::Handle>) from which it can be read. In
458 particular, this allows the test input to be placed after the C<__END__>
459 marker and read via the C<DATA> filehandle.
466 # this is the first test (this is a comment)
468 blah blah blah [% foo %]
470 blah blah blah value_of_foo
472 # here's the second test (no surprise, so is this)
474 more blah blah [% bar %]
476 more blah blah value_of_bar
478 Blank lines between test sections are generally ignored. Any line starting
479 with C<#> is treated as a comment and is ignored.
481 The second and third parameters to C<test_expect()> are optional. The second
482 may be either a reference to a Template object which should be used to
483 process the template fragments, or a reference to a hash array containing
484 configuration values which should be used to instantiate a new Template
487 # pass reference to config hash
489 INCLUDE_PATH => '/here/there:/every/where',
492 test_expect(\*DATA, $config);
494 # or create Template object explicitly
495 my $template = Template->new($config);
496 test_expect(\*DATA, $template);
498 The third parameter may be used to reference a hash array of template
499 variable which should be defined when processing the tests. This is
500 passed to the L<Template> L<process()|Template#process()> method.
507 test_expect(\*DATA, $config, $replace);
509 The second parameter may be left undefined to specify a default L<Template>
512 test_expect(\*DATA, undef, $replace);
514 For testing the output of different L<Template> configurations, a
515 reference to a list of named L<Template> objects also may be passed as
516 the second parameter.
518 my $tt1 = Template->new({ ... });
519 my $tt2 = Template->new({ ... });
520 my @tts = [ one => $tt1, two => $tt1 ];
522 The first object in the list is used by default. Other objects may be
523 switched in with a 'C<-- use $name -->' marker. This should immediately
524 follow a 'C<-- test -->' line. That object will then be used for the rest
525 of the test, or until a different object is selected.
542 blah, blah, more blah
544 The C<test_expect()> sub counts the number of tests, and then calls L<ntests()>
545 to generate the familiar "C<1..$ntests\n>" test harness line. Each
546 test defined generates two test numbers. The first indicates
547 that the input was processed without error, and the second that the
548 output matches that expected.
550 Additional test may be run before C<test_expect()> by calling L<ok()>. These
551 test results are cached until L<ntests()> is called and the final number of
552 tests can be calculated. Then, the "C<1..$ntests>" line is output, along with
553 "C<ok $n>" / "C<not ok $n>" lines for each of the cached test result.
554 Subsequent calls to L<ok()> then generate an output line immediately.
556 my $something = SomeObject->new();
559 my $other = AnotherThing->new();
564 If any tests are to follow after C<test_expect()> is called then these
565 should be pre-declared by setting the C<$EXTRA> package variable. This
566 value (default: C<0>) is added to the grand total calculated by L<ntests()>.
567 The results of the additional tests are also registered by calling L<ok()>.
569 $Template::Test::EXTRA = 2;
571 # can call ok() any number of times before test_expect()
572 ok( $did_that_work );
576 # <some> number of tests...
577 test_expect(\*DATA, $config, $replace);
579 # here's those $EXTRA tests
580 ok( defined $some_result && ref $some_result eq 'ARRAY' );
581 ok( $some_result->[0] eq 'some expected value' );
583 If you don't want to call C<test_expect()> at all then you can call
584 C<ntests($n)> to declare the number of tests and generate the test
585 header line. After that, simply call L<ok()> for each test passing
586 a true or false values to indicate that the test passed or failed.
592 If you're really lazy, you can just call L<ok()> and not bother declaring
593 the number of tests at all. All tests results will be cached until the
594 end of the script and then printed in one go before the program exits.
599 You can identify only a specific part of the input file for testing
600 using the 'C<-- start -->' and 'C<-- stop -->' markers. Anything before the
601 first 'C<-- start -->' is ignored, along with anything after the next
602 'C<-- stop -->' marker.
605 this is test 1 (not performed)
607 this is test 1 (not performed)
622 Subroutine used to specify how many tests you're expecting to run.
626 Generates an "C<ok $n>" or "C<not ok $n>" message if C<$test> is true or false.
630 The logical inverse of L<ok()>. Prints an "C<ok $n>" message is C<$test> is
631 I<false> and vice-versa.
635 For historical reasons and general utility, the module also defines a
636 C<callsign()> subroutine which returns a hash mapping the letters C<a>
637 to C<z> to their phonetic alphabet equivalent (e.g. radio callsigns).
638 This is used by many of the test scripts as a known source of variable values.
640 test_expect(\*DATA, $config, callsign());
644 This subroutine prints a simple banner including any text passed as parameters.
645 The C<$DEBUG> variable must be set for it to generate any output.
647 banner('Testing something-or-other');
651 #------------------------------------------------------------
652 # Testing something-or-other (27 tests completed)
653 #------------------------------------------------------------
655 =head1 PACKAGE VARIABLES
659 The $DEBUG package variable can be set to enable debugging mode.
663 The $PRESERVE package variable can be set to stop the test_expect()
664 from converting newlines in the output and expected output into
665 the literal strings '\n'.
669 This module started its butt-ugly life as the C<t/texpect.pl> script. It
670 was cleaned up to became the C<Template::Test> module some time around
671 version 0.29. It underwent further cosmetic surgery for version 2.00
672 but still retains some remarkable rear-end resemblances.
674 Since then the C<Test::More> and related modules have appeared on CPAN
675 making this module mostly, but not entirely, redundant.
677 =head1 BUGS / KNOWN "FEATURES"
679 Imports all methods by default. This is generally a Bad Thing, but
680 this module is only used in test scripts (i.e. at build time) so a) we
681 don't really care and b) it saves typing.
683 The line splitter may be a bit dumb, especially if it sees lines like
684 C<-- this --> that aren't supposed to be special markers. So don't do that.
688 Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
692 Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
694 This module is free software; you can redistribute it and/or
695 modify it under the same terms as Perl itself.
705 # perl-indent-level: 4
706 # indent-tabs-mode: nil
709 # vim: expandtab shiftwidth=4: