File Coverage

blib/lib/Test/Stream/Workflow/Unit.pm
Criterion Covered Total %
statement 101 101 100.0
branch 33 42 78.5
condition 37 46 80.4
subroutine 19 19 100.0
pod 6 7 85.7
total 196 215 91.1


line stmt bran cond sub pod time code
1             package Test::Stream::Workflow::Unit;
2 95     95   1043 use strict;
  95         191  
  95         2461  
3 95     95   468 use warnings;
  95         180  
  95         2227  
4              
5 95     95   484 use Test::Stream::Sync;
  95         186  
  95         1920  
6 95     95   545 use Test::Stream::Context();
  95         184  
  95         1659  
7 95     95   526 use Test::Stream::DebugInfo;
  95         215  
  95         2778  
8              
9 95     95   514 use Carp qw/confess/;
  95         250  
  95         4390  
10 95     95   499 use Scalar::Util qw/reftype/;
  95         183  
  95         5949  
11              
12             use Test::Stream::HashBase(
13 95         952 accessors => [qw{
14             name meta type wrap stash
15             package file start_line end_line
16             post
17             modify
18             buildup
19             primary
20             teardown
21             is_root
22             }],
23 95     95   532 );
  95         211  
24              
25             sub init {
26 344   100 344 0 1794 $_[0]->{+META} ||= {};
27              
28 344         946 for (NAME, PACKAGE, FILE, START_LINE, END_LINE) {
29 1716 100       5544 confess "$_ is a required attribute" unless defined $_[0]->{$_}
30             }
31              
32 343   100     1878 $_[0]->{+STASH} ||= {};
33             }
34              
35             sub contains {
36 14     14 1 31 my $self = shift;
37 14         24 my ($thing) = @_;
38 14         19 my ($file, $line, $name);
39 14 100       68 if ($thing =~ m/^(\S+) (\d+)$/) {
    100          
40 2         7 ($file, $line) = ($1, $2);
41             }
42             elsif ($thing =~ m/^\d+$/) {
43 6         11 $line = $thing;
44             }
45             else {
46 6         10 $name = $thing;
47             }
48              
49 14         32 return $self->_contains($file, $line, $name);
50             }
51              
52             sub _contains {
53 16     16   21 my $self = shift;
54 16         23 my ($file, $line, $name) = @_;
55              
56 16   100     55 my $name_ok = !defined($name) || $self->{+NAME} eq $name;
57 16   100     40 my $file_ok = !defined($file) || $self->{+FILE} eq $file;
58              
59             my $line_ok = !defined($line) || (
60             $line >= $self->{+START_LINE}
61 16   66     83 && ($self->{+END_LINE} . "" eq 'EOF' || $line <= $self->{+END_LINE})
62             );
63              
64 16         18 my $child_ok = 0;
65 16         40 for my $stash (MODIFY(), BUILDUP(), PRIMARY(), TEARDOWN()) {
66 64   100     328 my $set = $self->$stash || next;
67 2 50 33     22 next unless ref $set && reftype($set) eq 'ARRAY';
68 2         5 for my $unit (@$set) {
69 2 100       7 $child_ok = 1 if $unit->_contains($file, $line, $name);
70             }
71             }
72              
73 16   66     234 return $child_ok || ($name_ok && $file_ok && $line_ok);
74             }
75              
76             sub do_post {
77 54     54 1 263 my $self = shift;
78              
79 54 100       283 my $post = delete $self->{+POST} or return;
80 19         101 $_->($self) for @$post;
81             }
82              
83             for my $type (MODIFY(), BUILDUP(), PRIMARY(), TEARDOWN()) {
84 95     95   603 no strict 'refs';
  95         225  
  95         4907  
85             *{"add_$type"} = sub {
86 95     95   526 use strict;
  95         217  
  95         64708  
87 264     264   433 my $self = shift;
88 264   100     873 $self->{$type} ||= [];
89 264         344 push @{$self->{$type}} => @_;
  264         1668  
90             };
91             }
92              
93             sub adjust_lines {
94 29     29 1 66 my $self = shift;
95              
96 29         57 my $start = $self->{+START_LINE};
97 29         53 my $end = $self->{+END_LINE};
98              
99 29         82 for my $stash (MODIFY(), BUILDUP(), PRIMARY(), TEARDOWN()) {
100 116 100       366 my $list = $self->{$stash} or next;
101 42 50       108 next unless ref $list;
102 42 50       170 next unless reftype($list) eq 'ARRAY';
103 42 50       104 next unless @$list;
104              
105 42 50       115 my $top = $list->[0] or next;
106              
107 42         140 my $c_start = $top->start_line;
108 42         218 my $c_end = $top->end_line;
109              
110 42 100 33     499 $start = $c_start
      66        
111             if defined($c_start)
112             && $c_start =~ m/^\d+$/
113             && $c_start < $start;
114              
115 42 50 33     229 next if $end && "$end" eq 'EOF';
116 42 50       99 next unless defined $c_end;
117              
118 42 100 100     469 $end = $c_end
      100        
119             if ($c_end =~ m/^\d+$/ && $c_end > $end)
120             || "$c_end" eq 'EOF';
121             }
122              
123 29 100       101 if ("$end" eq 'EOF') {
124 1 50       10 $start -= 1 if $start != $self->{+START_LINE};
125             }
126             else {
127 28 100 100     157 $start -= 1 if $start != $end && $start != $self->{+START_LINE};
128 28 100 100     167 $end += 1 if $end != $start && $end != $self->{+END_LINE};
129             }
130              
131 29         58 $self->{+START_LINE} = $start;
132 29         85 $self->{+END_LINE} = $end;
133             }
134              
135             sub add_post {
136 27     27 1 63 my $self = shift;
137 27 50       96 confess "post units only apply to group units"
138             unless $self->type eq 'group';
139 27   100     247 $self->{post} ||= [];
140 27         40 push @{$self->{post}} => @_;
  27         106  
141             }
142              
143             sub debug {
144 745     745 1 1067 my $self = shift;
145              
146 745         2098 my $stack = Test::Stream::Sync->stack;
147 745         2125 my $hub = $stack->top;
148              
149             return Test::Stream::DebugInfo->new(
150             frame => [@$self{qw/package file start_line name/}],
151             skip => $self->meta->{skip},
152 745         4261 detail => "in block '$self->{+NAME}' defined in $self->{+FILE} (Approx) lines $self->{+START_LINE} -> $self->{+END_LINE}",
153             $hub->debug_todo,
154             );
155             }
156              
157             sub context {
158 745     745 1 1099 my $self = shift;
159              
160 745         2964 my $stack = Test::Stream::Sync->stack;
161 745         2459 my $hub = $stack->top;
162              
163 745         1061 my $ref;
164 745 100       2205 if(my $todo = $self->meta->{todo}) {
165 9         77 $ref = $hub->set_todo($todo);
166             }
167              
168 745         4175 my $dbg = $self->debug;
169              
170 745         4121 my $ctx = Test::Stream::Context->new(
171             stack => $stack,
172             hub => $hub,
173             debug => $dbg,
174             );
175              
176             # Stash the todo ref in the context so that it goes away with the context
177 745         1350 $ctx->{_todo_ref} = $ref;
178              
179 745         2044 return $ctx;
180             }
181              
182             1;
183              
184             __END__