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   648 use strict;
  95         103  
  95         2054  
3 95     95   277 use warnings;
  95         102  
  95         1629  
4              
5 95     95   288 use Test::Stream::Sync();
  95         107  
  95         985  
6 95     95   288 use Test::Stream::Context();
  95         116  
  95         941  
7 95     95   319 use Test::Stream::DebugInfo();
  95         102  
  95         1392  
8              
9 95     95   286 use Carp qw/confess/;
  95         97  
  95         3484  
10 95     95   343 use Scalar::Util qw/reftype/;
  95         126  
  95         4539  
11              
12             use Test::Stream::HashBase(
13 95         668 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   342 );
  95         122  
24              
25             sub init {
26 346   100 346 0 1278 $_[0]->{+META} ||= {};
27              
28 346         660 for (NAME, PACKAGE, FILE, START_LINE, END_LINE) {
29 1726 100       2985 confess "$_ is a required attribute" unless defined $_[0]->{$_}
30             }
31              
32 345   100     1585 $_[0]->{+STASH} ||= {};
33             }
34              
35             sub contains {
36 14     14 1 19 my $self = shift;
37 14         12 my ($thing) = @_;
38 14         10 my ($file, $line, $name);
39 14 100       57 if ($thing =~ m/^(\S+) (\d+)$/) {
    100          
40 2         5 ($file, $line) = ($1, $2);
41             }
42             elsif ($thing =~ m/^\d+$/) {
43 6         7 $line = $thing;
44             }
45             else {
46 6         7 $name = $thing;
47             }
48              
49 14         22 return $self->_contains($file, $line, $name);
50             }
51              
52             sub _contains {
53 16     16   11 my $self = shift;
54 16         15 my ($file, $line, $name) = @_;
55              
56 16   100     40 my $name_ok = !defined($name) || $self->{+NAME} eq $name;
57 16   100     24 my $file_ok = !defined($file) || $self->{+FILE} eq $file;
58              
59             my $line_ok = !defined($line) || (
60             $line >= $self->{+START_LINE}
61 16   66     50 && ($self->{+END_LINE} . "" eq 'EOF' || $line <= $self->{+END_LINE})
62             );
63              
64 16         17 my $child_ok = 0;
65 16         23 for my $stash (MODIFY(), BUILDUP(), PRIMARY(), TEARDOWN()) {
66 64   100     194 my $set = $self->$stash || next;
67 2 50 33     22 next unless ref $set && reftype($set) eq 'ARRAY';
68 2         3 for my $unit (@$set) {
69 2 100       7 $child_ok = 1 if $unit->_contains($file, $line, $name);
70             }
71             }
72              
73 16   66     146 return $child_ok || ($name_ok && $file_ok && $line_ok);
74             }
75              
76             sub do_post {
77 54     54 1 184 my $self = shift;
78              
79 54 100       218 my $post = delete $self->{+POST} or return;
80 19         58 $_->($self) for @$post;
81             }
82              
83             for my $type (MODIFY(), BUILDUP(), PRIMARY(), TEARDOWN()) {
84 95     95   500 no strict 'refs';
  95         158  
  95         4090  
85             *{"add_$type"} = sub {
86 95     95   336 use strict;
  95         127  
  95         42996  
87 266     266   254 my $self = shift;
88 266   100     677 $self->{$type} ||= [];
89 266         203 push @{$self->{$type}} => @_;
  266         1326  
90             };
91             }
92              
93             sub adjust_lines {
94 29     29 1 55 my $self = shift;
95              
96 29         36 my $start = $self->{+START_LINE};
97 29         36 my $end = $self->{+END_LINE};
98              
99 29         58 for my $stash (MODIFY(), BUILDUP(), PRIMARY(), TEARDOWN()) {
100 116 100       227 my $list = $self->{$stash} or next;
101 42 50       74 next unless ref $list;
102 42 50       116 next unless reftype($list) eq 'ARRAY';
103 42 50       73 next unless @$list;
104              
105 42 50       76 my $top = $list->[0] or next;
106              
107 42         87 my $c_start = $top->start_line;
108 42         137 my $c_end = $top->end_line;
109              
110 42 100 33     390 $start = $c_start
      66        
111             if defined($c_start)
112             && $c_start =~ m/^\d+$/
113             && $c_start < $start;
114              
115 42 50 33     148 next if $end && "$end" eq 'EOF';
116 42 50       70 next unless defined $c_end;
117              
118 42 100 100     298 $end = $c_end
      100        
119             if ($c_end =~ m/^\d+$/ && $c_end > $end)
120             || "$c_end" eq 'EOF';
121             }
122              
123 29 100       80 if ("$end" eq 'EOF') {
124 1 50       13 $start -= 1 if $start != $self->{+START_LINE};
125             }
126             else {
127 28 100 100     153 $start -= 1 if $start != $end && $start != $self->{+START_LINE};
128 28 100 100     121 $end += 1 if $end != $start && $end != $self->{+END_LINE};
129             }
130              
131 29         37 $self->{+START_LINE} = $start;
132 29         55 $self->{+END_LINE} = $end;
133             }
134              
135             sub add_post {
136 27     27 1 45 my $self = shift;
137 27 50       60 confess "post units only apply to group units"
138             unless $self->type eq 'group';
139 27   100     163 $self->{post} ||= [];
140 27         24 push @{$self->{post}} => @_;
  27         67  
141             }
142              
143             sub debug {
144 747     747 1 565 my $self = shift;
145              
146 747         1270 my $stack = Test::Stream::Sync->stack;
147 747         1175 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 747         2689 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 747     747 1 633 my $self = shift;
159              
160 747         1871 my $stack = Test::Stream::Sync->stack;
161 747         1588 my $hub = $stack->top;
162              
163 747         563 my $ref;
164 747 100       1314 if(my $todo = $self->meta->{todo}) {
165 9         56 $ref = $hub->set_todo($todo);
166             }
167              
168 747         2543 my $dbg = $self->debug;
169              
170 747         2520 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 747         776 $ctx->{_todo_ref} = $ref;
178              
179 747         1171 return $ctx;
180             }
181              
182             1;
183              
184             __END__