File Coverage

blib/lib/Test/Inline/Section.pm
Criterion Covered Total %
statement 126 138 91.3
branch 41 58 70.6
condition 22 36 61.1
subroutine 25 26 96.1
pod 14 14 100.0
total 228 272 83.8


line stmt bran cond sub pod time code
1             package Test::Inline::Section;
2              
3             =pod
4              
5             =head1 NAME
6              
7             Test::Inline::Section - Implements a section of tests
8              
9             =head1 DESCRIPTION
10              
11             This class implements a single section of tests. That is, a section of POD
12             beginning with C<=begin test> or C<=begin testing>.
13              
14             =head2 Types of Sections
15              
16             There are two types of code sections. The first, beginning with
17             C<=begin testing ...>, contains a set of tests and other code to be executed
18             at any time (within a set of specifyable constraints). The second, labelled
19             C<=begin testing SETUP>, contains code to be executed at the beginning of the
20             test script, before any of the other sections are executed. This allows
21             any needed variables or environment to be set up before the tests are run.
22             You can have more than one setup section, and they will be written to the
23             test file in order of appearance.
24              
25             =head2 Test Section Header Syntax
26              
27             Some examples of the different types of test headers are as follows.
28              
29             # Normal anonymous test
30             =begin testing
31            
32             ok( $foo == $bar, 'This is a test' );
33            
34             =end testing
35            
36             # A named test. Also provides the number of tests to run.
37             # Any test section can specify the number of tests.
38             =begin testing my_method 1
39            
40             ok( $foo->my_method, '->my_method returns true' );
41            
42             =end testing
43            
44             # A named test with pre-requisites.
45             # Note that ONLY named tests can have pre-requisites
46             =begin testing this after my_method foo bar other_method Other::Class
47            
48             ok( $foo->this, '->this returns true' );
49            
50             =end testing
51              
52             The first example shows a normal anonymous test. All anonymous test sections
53             are considered low priority, and we be run, in order of appearance, AFTER all
54             named tests have been run.
55              
56             Any and all arguments used after "testing" must be in the form of simple
57             space seperated words. The first word is considered the "name" of the test.
58             The intended use for these is generally to create one named test section for
59             each function or method, but you can name them as you please. Test names
60             B be unique, and B case sensitive.
61              
62             After the name, you can provide the word "after" and provide a list of other
63             named tests that must be completed first in order to run this test. This is
64             provided so that when errors are encounted, they are probably the result of
65             this method or set of tests, and not in some other method that this one
66             relies on. It makes debugging a lot easier. The word after is only a
67             keyword when after the test name, so you can use a test name of after as well.
68             The following are both legal
69              
70             =begin testing after after that
71             =begin testing this after after
72              
73             The easiest and recommended way of labeling the tests is simple to name all
74             tests after their methods, and put as a pre-requisite any other methods that
75             the method you are testing calls. Test::Inline will take care of writing the
76             tests to the test script in the correct order. Please note you can NOT define
77             circular relationships in the prerequisites, or an error will occur.
78              
79             If a number is provided as the last value, it will be taken to mean the
80             number of actual tests that will occur during the test section. While
81             preparing to write the test files, the processor will try to use these
82             to try to determine the number of files to write. If ALL test sections to
83             be written to a particular file have a test count, then the script will
84             use the total of these as a basic for providing Test::More with a plan.
85              
86             If ANY test sections to be written to a file do not have a test count, the
87             test file with use C.
88              
89             Finally, Test::Inline will try to be forgiving in it's parsing of the tests.
90             any missing prerequisites will be ignored. Also, as long as it does not
91             break a prerequisite, all named tests will be attempted to be run in their
92             order of appearance.
93              
94             =head1 METHODS
95              
96             =cut
97              
98 12     12   59 use strict;
  12         20  
  12         348  
99 12     12   59 use List::Util ();
  12         17  
  12         205  
100 12     12   53 use Params::Util qw{_ARRAY};
  12         17  
  12         511  
101 12     12   55 use Algorithm::Dependency::Item ();
  12         17  
  12         238  
102              
103 12     12   52 use vars qw{$VERSION @ISA $errstr};
  12         33  
  12         922  
104             BEGIN {
105 12     12   23 $VERSION = '2.213';
106 12         215 @ISA = 'Algorithm::Dependency::Item';
107 12         46149 $errstr = '';
108             }
109              
110              
111              
112              
113              
114             #####################################################################
115             # Constructor and Parsing
116              
117             =pod
118              
119             =head2 new
120              
121             my $Section = Test::Inline::Section->new( $pod );
122              
123             The C constructor takes a string of POD, which must be a single section
124             of relevant pod ( preferably produced by L ),
125             and creates a new section object for it.
126              
127             Returns a new C object if passed POD in the form
128             C<=begin testing ...>. Returns C on error.
129              
130             =cut
131              
132             my $RE_begin = qr/=begin\s+(?:test|testing)/;
133             my $RE_example = qr/=for\s+example\s+begin/;
134              
135             sub new {
136 57     57 1 4384 $errstr = '';
137 57         83 my $class = shift;
138 57 50       969 my $pod = $_[0] =~ /^(?:$RE_begin|$RE_example)\b/ ? shift :
139             return $class->_error("Test section does not begin with =begin test[ing]");
140 57         103 my $context = shift;
141              
142             # Split into lines
143 57         972 my @lines = split /(?:\015{1,2}\012|\015|\012)/, $pod;
144              
145             # Handle =for example seperately
146 57 100       386 if ( $pod =~ /^$RE_example\b/ ) {
147 1         5 return $class->_example( \@lines, $context );
148             }
149              
150             # Get the begin paragraph ( yes, paragraph. NOT line )
151 56         85 my $begin = '';
152 56   66     346 while ( @lines and $lines[0] !~ /^\s*$/ ) {
153 56 50       124 $begin .= ' ' if $begin;
154 56         369 $begin .= shift @lines;
155             }
156              
157             # Remove the trailing end tag
158 56 50 33     413 if ( @lines and $lines[-1] =~ /^=end\s+(?:test|testing)\b/o ) {
159 56         80 pop @lines;
160             }
161              
162             # Do some cleaning up and checking
163 56         187 $class->_trim_empty_lines( \@lines );
164 56 100       178 $class->_check_nesting( \@lines, $begin ) or return undef;
165              
166             # Create the basic object
167 57         608 my $self = bless {
168             begin => $begin,
169 55         101 content => join( '', map { "$_\n" } @lines ),
170             setup => '', # Is this a setup section
171             example => '', # Is this an example section
172             context => $context, # Package context
173             name => undef, # The name of the test
174             tests => undef, # undef means unknown test count
175             after => {}, # Other named methods this should be after
176             classes => {}, # Other classes this should be after
177             }, $class;
178              
179             # Start processing the begin line
180 55         222 my @parts = split /\s+/, $begin;
181              
182             # Remove the =begin
183 55         96 shift @parts;
184              
185             # If the line contains a number then this is part of the tests
186 55         174 foreach my $i ( 0 .. $#parts ) {
187 191 100       603 next unless $parts[$i] =~ /^(0|[1-9]\d*)$/;
188 43         176 $self->{tests} = splice @parts, $i, 1;
189 43         70 last;
190             }
191              
192             # Handle setup sections via =begin test setup or =begin testing SETUP
193 55 50 66     277 if ( @parts == 2 and $parts[0] eq 'test' and $parts[1] eq 'setup' ) {
      33        
194 0         0 $self->{setup} = 1;
195             }
196 55 100 66     348 if ( @parts >= 2 and $parts[0] eq 'testing' and $parts[1] eq 'SETUP' ) {
      100        
197 9         25 $self->{setup} = 1;
198             }
199              
200             # Any other form of =begin test is not allowed
201 55 50 33     174 if ( $parts[0] eq 'test' and ! $self->{setup} ) {
202             # Unknown =begin test line
203 0         0 return $class->_error("Unsupported '=begin test' line '$begin'");
204             }
205              
206             # Remove the "testing" word
207 55         62 shift @parts;
208              
209             # If there are no remaining parts, we are anonymous,
210             # and can just return as is.
211 55 100       183 return $self unless @parts;
212              
213             # Make sure all remaining parts are only words
214 46 50       76 if ( grep { ! /^[\w:]+$/ } @parts ) {
  93         359  
215 0         0 return $class->_error("Found something other than words: $begin");
216             }
217              
218             # The first word is our name and must match the perl
219             # format for a method name.
220 46 100       1714 if ( $self->{setup} ) {
221 9         24 shift @parts;
222             } else {
223 37         82 $self->{name} = shift @parts;
224 37 50       210 unless ( $self->{name} =~ /^[^\W\d]\w*$/ ) {
225 0         0 return $class->_error("'$self->{name}' is not a valid test name: $begin");
226             }
227             }
228 46 100       225 return $self unless @parts;
229              
230             # The next word MUST be "after"
231 19 50       54 unless ( shift @parts eq 'after' ) {
232 0         0 return $class->_error("Word after test name is something other than 'after': $begin");
233             }
234              
235             # The remaining words are our dependencies.
236             # Simple words chunks are method dependencies, and anything
237             # containing :: (including at the end) is a dependency on
238             # another module that should be part of the testing process.
239 19         46 foreach my $part ( @parts ) {
240 28 100       111 if ( $part =~ /^[^\W\d]\w*$/ ) {
    50          
241 26 50       58 if ( $self->setup ) {
242 0         0 return $class->_error("SETUP sections can only have class dependencies");
243             }
244 26         99 $self->{after}->{$part} = 1;
245             } elsif ( $part =~ /::/ ) {
246 2         5 $part =~ s/::$//; # Strip trailing ::
247 2         10 $self->{classes}->{$part} = 1;
248             } else {
249 0         0 return $class->_error("Unknown dependency '$part' in begin line: $begin");
250             }
251             }
252              
253 19         90 $self;
254             }
255              
256             # Handle the creation of example sections
257             sub _example {
258 1     1   3 my $class = shift;
259 1         2 my @lines = @{shift()};
  1         4  
260 1         2 my $context = shift;
261              
262             # Get the begin paragraph ( yes, paragraph. NOT line )
263 1         2 my $begin = '';
264 1   66     10 while ( @lines and $lines[0] !~ /^\s*$/ ) {
265 1 50       4 $begin .= ' ' if $begin;
266 1         7 $begin .= shift @lines;
267             }
268              
269             # Remove the trailing end tag
270 1 50 33     12 if ( @lines and $lines[-1] =~ /^=for\s+example\s+end\b/o ) {
271 1         1 pop @lines;
272             }
273              
274             # Remove any leading and trailing empty lines
275 1         5 $class->_trim_empty_lines( \@lines );
276 1 50       4 $class->_check_nesting( \@lines, $begin ) or return undef;
277              
278             # Create the basic object
279 2         20 my $self = bless {
280             begin => $begin,
281 1         3 content => join( '', map { "$_\n" } @lines ),
282             setup => '', # Is this a setup section
283             example => 1, # Is this an example section
284             context => $context, # Package context
285             name => undef, # Examples arn't named
286             tests => 1, # An example always consumes 1 test
287             after => {}, # Other named methods this should be after
288             classes => {}, # Other classes this should be after
289             }, $class;
290              
291 1         7 $self;
292             }
293              
294             sub _error {
295 1     1   4 $errstr = join ': ', @_;
296 1         19 undef;
297             }
298              
299             sub _short {
300 2     2   5 my $either = shift;
301 2         3 my $string = shift;
302 2         4 chomp $string;
303 2         5 $string =~ s/\n/ /g;
304 2 50       6 if ( length($string) > 30 ) {
305 0         0 $string = substr($string, 27);
306 0         0 $string =~ s/\s+$//;
307 0         0 $string .= '...';
308             }
309 2         5 $string;
310             }
311              
312             sub _check_nesting {
313 57     57   107 my ($class, $lines, $begin) = @_;
314              
315             # In the remaining lines there shouldn't be any lines
316             # that look like a POD tag. If there is there is probably
317             # a nesting problem.
318 57     62   404 my $bad_line = List::Util::first { /^=\w+/ } @$lines;
  62         144  
319 57 100       223 if ( $bad_line ) {
320 1         5 $bad_line = $class->_short($bad_line);
321 1         4 $begin = $class->_short($begin);
322 1         7 return $class->_error(
323             "POD statement '$bad_line' illegally nested inside of section '$begin'"
324             );
325             }
326              
327 56         164 1;
328             }
329              
330             sub _trim_empty_lines {
331 57     57   81 my $lines = $_[1];
332 57   66     329 while ( @$lines and $lines->[0] eq '' ) { shift @$lines }
  57         249  
333 57   66     272 while ( @$lines and $lines->[-1] eq '' ) { pop @$lines }
  57         263  
334 57         88 1;
335             }
336              
337              
338              
339              
340              
341             #####################################################################
342             # Main Methods
343              
344             =pod
345              
346             =head2 parse
347              
348             my $SectionList = Test::Inline::Section( @elements );
349              
350             Since version 1.50 L has been extracting package statements
351             so that as the sections are extracted, we can determine which sections
352             belong to which packages, and seperate them accordingly.
353              
354             The C method takes B of the elements from a file, and returns
355             all of the Sections. By doing it here, we can track the package context
356             and set it in the Sections.
357              
358             =cut
359              
360             sub parse {
361 17     17 1 44 $errstr = '';
362 17         31 my $class = shift;
363 17 50       93 my $elements = _ARRAY(shift) or return undef;
364 17         35 my @Sections = ();
365              
366             # Iterate over the elements and maintain package contexts
367 17         37 my $context = '';
368 17         44 foreach my $element ( @$elements ) {
369 71 100       212 if ( $element =~ /^package\s+([\w:']+)/ ) {
370 21         82 $context = $1;
371 21         46 next;
372             }
373              
374             # Handle weird unexpected elements
375 50 50       164 unless ( $element =~ /^=/ ) {
376 0         0 return $class->_error("Unexpected element '$element'");
377             }
378              
379             # Hand off to the Section constructor
380 50 100       151 my $Section = Test::Inline::Section->new( $element, $context ) or return undef;
381 49         144 push @Sections, $Section;
382             }
383              
384 16 50       117 @Sections ? \@Sections : undef;
385             }
386              
387             =pod
388              
389             =head2 setup
390              
391             my $run_first = $Section->setup;
392              
393             The C accessor indicates that this section is a "setup" section,
394             to be run at the beginning of the generated test script.
395              
396             Returns true if this is a setup section, false otherwise.
397              
398             =cut
399              
400 173     173 1 2825 sub setup { $_[0]->{setup} }
401              
402             =pod
403              
404             =head2 example
405              
406             my $just_compile = $Section->example;
407              
408             The C accessor indicates that this section is an "example"
409             section, to be compile-tested instead of run.
410              
411             Returns true if this is an example section, false otherwise.
412              
413             =cut
414              
415 44     44 1 172 sub example { $_[0]->{example} }
416              
417             =pod
418              
419             =head2 context
420              
421             The C method returns the package context of the unit test section,
422             or false if the unit test section appeared out of context.
423              
424             =cut
425              
426 54     54 1 214 sub context { $_[0]->{context} }
427              
428             =pod
429              
430             =head2 name
431              
432             The C method returns the name of the test section,
433             or false if the test if anonymous.
434              
435             =cut
436              
437 485 100   485 1 2568 sub name { defined $_[0]->{name} and $_[0]->{name} }
438              
439             =pod
440              
441             =head2 tests
442              
443             The C method returns the number of Test::Builder-compatible
444             tests that will run within the test section. Returns C if the
445             number of tests is unknown.
446              
447             =cut
448              
449 202     202 1 804 sub tests { $_[0]->{tests} }
450              
451             =pod
452              
453             =head2 begin
454              
455             For use mainly in debugging, the C method returns the literal string
456             of the begin line/paragraph.
457              
458             =cut
459              
460 0     0 1 0 sub begin { $_[0]->{begin} }
461              
462             =pod
463              
464             =head2 anonymous
465              
466             my $is_anonymous = $Section->anonymous;
467              
468             The C method returns true if the test section is an unnamed
469             anonymous section, or false if it is a named section or a setup section.
470              
471             =cut
472              
473             sub anonymous {
474 29     29 1 40 my $self = shift;
475 29   100     160 ! (defined $self->{name} or $self->{setup});
476             }
477              
478             =pod
479              
480             =head2 after
481              
482             my @names = $Section->after;
483              
484             The C method returns the list of other named tests that this
485             test section says it should be run after.
486              
487             Returns a list of test name, or the null list C<()> if the test does
488             not have to run after any other named tests.
489              
490             =cut
491              
492             sub after {
493 130     130 1 945 keys %{$_[0]->{after}};
  130         698  
494             }
495              
496             =pod
497              
498             =head2 classes
499              
500             my @classes = $Section->classes;
501              
502             The C method returns the list of test classes that the test depends
503             on, and should be run before the tests. These values are used to determine the
504             set of class-level dependencies for the entire test file.
505              
506             Returns a list of class names, or the null list C<()> if the test does
507             not have any class-level dependencies.
508              
509             =cut
510              
511             sub classes {
512 47     47 1 309 keys %{$_[0]->{classes}};
  47         199  
513             }
514              
515             =pod
516              
517             =head2 content
518              
519             my $code = $Section->content;
520              
521             The C method returns the actual testing code contents of the
522             section, with the leading C<=begin> and trailing C<=end> removed.
523              
524             Returns a string containing the code, or the null string C<""> if the
525             section was empty.
526              
527             =cut
528              
529 91     91 1 452 sub content { $_[0]->{content} }
530              
531              
532              
533              
534              
535             #####################################################################
536             # Implementing the Algorithm::Dependency::Item interface
537              
538             # The ->depends method we have works the same as for
539             # Algorithm::Dependency::Item already, so we just need to implement
540             # it's ->id method, which is the same as our ->name method
541              
542 18     18 1 72 sub id { $_[0]->name }
543 125     125 1 574 sub depends { $_[0]->after }
544              
545             1;
546              
547             =pod
548              
549             =head1 SUPPORT
550              
551             See the main L section.
552              
553             =head1 AUTHOR
554              
555             Adam Kennedy Eadamk@cpan.orgE, L
556              
557             =head1 COPYRIGHT
558              
559             Copyright 2004 - 2013 Adam Kennedy.
560              
561             This program is free software; you can redistribute
562             it and/or modify it under the same terms as Perl itself.
563              
564             The full text of the license can be found in the
565             LICENSE file included with this module.
566              
567             =cut