File Coverage

blib/lib/Test/Base/SubTest.pm
Criterion Covered Total %
statement 91 99 91.9
branch 18 22 81.8
condition 11 17 64.7
subroutine 19 20 95.0
pod 4 4 100.0
total 143 162 88.2


line stmt bran cond sub pod time code
1             package Test::Base::SubTest;
2 11     11   21670 use strict;
  11         20  
  11         371  
3 11     11   53 use warnings;
  11         15  
  11         279  
4 11     11   1142 use utf8;
  11         26  
  11         50  
5 11     11   29863 use parent qw(Exporter);
  11         3781  
  11         51  
6             our @EXPORT = (@Test::More::EXPORT, qw/filters blocks register_filter run run_is run_is_deeply/);
7              
8             our $VERSION = '0.5';
9              
10 11         41 use parent qw/
11             Test::Base::Less
12             Test::Builder::Module Exporter
13 11     11   1048 /;
  11         21  
14 11     11   421943 use Test::More;
  11         33  
  11         93  
15 11     11   3689 use Carp qw/croak/;
  11         23  
  11         789  
16 11     11   12715 use Text::TestBase::SubTest;
  11         32  
  11         701  
17              
18             my $SKIP;
19              
20 0     0 1 0 sub blocks() { croak 'block() is not supported. Use run{} instead.' }
21              
22             {
23 11     11   60 no warnings 'once';
  11         21  
  11         11520  
24             *filters = \&Test::Base::Less::filters;
25             *register_filter = \&Test::Base::Less::register_filter;
26             }
27              
28             sub run(&) {
29 6     6 1 781 my $code = shift;
30              
31 6         31 my $content = _get_data_section();
32 6         98 my $node = Text::TestBase::SubTest->new->parse($content);
33              
34             _exec_each_test($node, sub {
35 11     11   19 my $block = shift;
36 11         48 $code->($block);
37 6         195 });
38             }
39              
40             sub run_is {
41 3     3 1 113 my ($a, $b) = @_;
42 3   100     18 $a ||= 'input';
43 3   100     14 $b ||= 'expected';
44 3         14 my $content = _get_data_section();
45 3         43 my $node = Text::TestBase::SubTest->new->parse($content);
46              
47             _exec_each_test($node, sub {
48 6     6   11 my $block = shift;
49 6   66     52 __PACKAGE__->builder->is_eq(
50             $block->get_section($a),
51             $block->get_section($b),
52             $block->name || 'L: ' . $block->get_lineno
53             );
54 3         71 });
55             }
56              
57             sub run_is_deeply($$) {
58 1     1 1 38 my ($a, $b) = @_;
59 1   50     4 $a ||= 'input';
60 1   50     4 $b ||= 'expected';
61 1         3 my $package = scalar(caller(0));
62              
63 1         5 my $content = _get_data_section();
64 1         14 my $node = Text::TestBase::SubTest->new->parse($content);
65              
66             _exec_each_test($node, sub {
67 1     1   1 my $block = shift;
68 1         3 local $Test::Builder::Level = $Test::Builder::Level + 1;
69 1   33     3 Test::More::is_deeply(
70             $block->get_section($a),
71             $block->get_section($b),
72             $block->name || 'L: ' . $block->get_lineno
73             );
74 1         20 });
75             }
76              
77             sub _exec_each_test {
78 13     13   30 my ($subtest, $code) = @_;
79              
80             my $executer = sub {
81 13     13   1693 for my $node (@{ $subtest->child_nodes }) {
  13         94  
82 23 100       6929 if ($node->is_subtest) {
83 3         8 _exec_each_test($node, $code);
84             } else {
85 20 100       452 next if $SKIP;
86              
87 19         130 my @names = $node->get_section_names;
88 19         145 for my $section_name (@names) {
89 32         222 my @data = $node->get_section($section_name);
90 32 100       322 if (my $filter_names = $Test::Base::Less::FILTER_MAP{$section_name}) {
91 14         27 for my $filter_stuff (@$filter_names) {
92 17 100       166 if (ref $filter_stuff eq 'CODE') { # filters { input => [\&code] };
93 4         22 @data = $filter_stuff->(@data);
94             } else { # filters { input => [qw/eval/] };
95 13         27 my $filter = $Test::Base::Less::FILTERS{$filter_stuff};
96 13 50       34 unless ($filter) {
97 0         0 Carp::croak "Unknown filter name: $filter_stuff";
98             }
99 13         46 @data = $filter->(@data);
100             }
101             }
102             }
103 32         696 $node->set_section($section_name => @data);
104             }
105 19 50       239 if ($node->has_section('ONLY')) {
106 0         0 Carp::croak "Sorry, section 'ONLY' is not implemented... Patches welcome.";
107 0         0 __PACKAGE__->builder->diag("I found ONLY: maybe you're debugging?");
108 0         0 $SKIP = 1;
109 0         0 $code->($node);
110 0         0 next;
111             }
112 19 100       167 if ($node->has_section('SKIP')) {
113 1         7 next;
114             }
115 18 100       129 if ($node->has_section('LAST')) {
116 1         6 $SKIP = 1;
117 1         2 $code->($node);
118 1         454 next;
119             }
120              
121 17         121 $code->($node);
122             }
123             }
124 13         85 };
125 13 100       61 if ($subtest->is_root) {
126 10         34 $executer->();
127             } else {
128 3 50       7 return if $SKIP;
129 3   66     26 __PACKAGE__->builder->subtest(
130             ($subtest->name || 'L: ' . $subtest->get_lineno) => $executer
131             );
132             }
133             }
134              
135             sub _get_data_section {
136 10     10   46 my $package = scalar(caller(1));
137 11     11   72 my $d = do { no strict 'refs'; \*{"${package}::DATA"} };
  11         22  
  11         1630  
  10         19  
  10         22  
  10         65  
138 10 50       65 unless (defined fileno $d) {
139 0         0 Carp::croak("Missing __DATA__ section in $package.");
140             }
141 10         130 seek $d, 0, 0;
142              
143 10         353 return join '', <$d>;
144             }
145              
146             1;
147             __END__