File Coverage

blib/lib/Text/TestBase/SubTest.pm
Criterion Covered Total %
statement 68 69 98.5
branch 7 8 87.5
condition 4 8 50.0
subroutine 14 14 100.0
pod 2 2 100.0
total 95 101 94.0


line stmt bran cond sub pod time code
1             package Text::TestBase::SubTest;
2 15     15   296895 use strict;
  15         28  
  15         505  
3 15     15   69 use warnings;
  15         30  
  15         527  
4 15     15   419 use 5.008001;
  15         53  
  15         785  
5 15     15   3676 use parent qw(Text::TestBase);
  15         1352  
  15         84  
6 15     15   33668 use Text::TestBase::SubTest::Node::Block;
  15         34  
  15         388  
7 15     15   9785 use Text::TestBase::SubTest::Node::SubTest;
  15         41  
  15         409  
8 15     15   10141 use Text::TestBase::SubTest::Node::Root;
  15         39  
  15         539  
9              
10             use Class::Accessor::Lite (
11 15         265 rw => [qw/subtest_delim/],
12 15     15   83 );
  15         29  
13 15     15   1028 use Carp ();
  15         25  
  15         11388  
14             our $VERSION = '0.5';
15              
16             sub new {
17 20     20 1 15991 my $class = shift;
18 20         203 my $self = $class->SUPER::new(@_);
19 20         357 $self->{subtest_delim} = '###';
20 20         62 $self->{block_class} = 'Text::TestBase::SubTest::Node::Block';
21 20         101 return $self;
22             }
23              
24             sub parse {
25 19     19 1 48 my ($self, $spec) = @_;
26 19         143 my $block_delim = $self->block_delim;
27 19         316 my $subtest_delim = $self->subtest_delim;
28 19         241 my $root = Text::TestBase::SubTest::Node::Root->new;
29 19         45 my $lineno = 1;
30 19         39 my $indent = do {
31 19         186 my @m = $spec =~ /^(\s{2,}|\t)/m;
32 19 100       111 $m[0] || ' ';
33             };
34              
35 19         1337 $spec =~ s/
36             ^(
37             [ \t]* \Q${subtest_delim}\E.*?
38             (?= ^[ \t]* \Q${block_delim}\E | ^[ \t]* \Q${subtest_delim}\E | \z )
39             )
40             | ^(
41             [ \t]* \Q${block_delim}\E .*?
42             (?= ^[ \t]* \Q${block_delim}\E | ^[ \t]* \Q${subtest_delim}\E | \z )
43             )
44             | ^( [^\n]* \n )
45             /
46             # subtest
47 223 100       936 if ($1) {
    100          
    50          
48 33         67 my $hunk = _unindent($1);
49 33         249 my $subtest = $self->_make_subtest($hunk, $lineno);
50 33   33     97 my $prev_subtest = $root->last_subtest( depth => _depth($1, $indent) - 1 ) || $root;
51              
52 33         45 $lineno++;
53 33         100 $prev_subtest->append_child($subtest);
54              
55             # block
56             } elsif ($2) {
57 30         91 my $hunk = _unindent($2);
58 30         203 my $block = $self->_make_block($hunk, $lineno);
59 30   33     8159 my $prev_subtest = $root->last_subtest( depth => _depth($2, $indent) - 1 ) || $root;
60              
61 30         152 $hunk =~ s!\n!$lineno++!ge;
  140         293  
62 30         172 $prev_subtest->append_child($block);
63              
64             } elsif ($3) {
65 160         171 $lineno++;
66             }
67 223         1056 '';
68             /msgxe;
69              
70 19         144 return $root;
71             }
72              
73             sub _make_subtest {
74 33     33   57 my ($self, $hunk, $lineno) = @_;
75 33         80 my $subtest_delim = $self->subtest_delim;
76             # TODO:
77             # * common filter
78             # * exception
79 33         300 my ($name) = $hunk =~ /^$subtest_delim\s+(.+)$/;
80 33         134 return Text::TestBase::SubTest::Node::SubTest->new(
81             name => $name,
82             _lineno => $lineno,
83             );
84 0         0 return $name;
85             }
86              
87             sub _unindent {
88 63     63   130 my $text = shift;
89 63         231 my ($indent) = $text =~ /^((?:[ \t])*)/;
90 63         800 $text =~ s/^$indent//mg;
91 63         194 return $text;
92             }
93              
94             sub _depth {
95 63     63   315 my ($str, $indent) = @_;
96 63         644 my ($captured) = $str =~ /^($indent*)/;
97 63   100     262 $captured ||= '';
98 63         622 return (length($captured) / length($indent)) + 1;
99             }
100              
101             1;