File Coverage

blib/lib/Test2/API/InterceptResult/Squasher.pm
Criterion Covered Total %
statement 81 83 97.5
branch 30 34 88.2
condition 9 12 75.0
subroutine 16 16 100.0
pod 0 8 0.0
total 136 153 88.8


line stmt bran cond sub pod time code
1             package Test2::API::InterceptResult::Squasher;
2 35     35   808 use strict;
  35         102  
  35         1077  
3 35     35   186 use warnings;
  35         71  
  35         1632  
4              
5             our $VERSION = '1.302180';
6              
7 35     35   220 use Carp qw/croak/;
  35         86  
  35         1866  
8 35     35   236 use List::Util qw/first/;
  35         98  
  35         2667  
9              
10 35         323 use Test2::Util::HashBase qw{
11            
12              
13             +down_sig +down_buffer
14              
15             +up_into +up_sig +up_clear
16 35     35   267 };
  35         88  
17              
18             sub init {
19 3     3 0 7 my $self = shift;
20              
21 3 50       17 croak "'events' is a required attribute" unless $self->{+EVENTS};
22             }
23              
24             sub can_squash {
25 32     32 0 52 my $self = shift;
26 32         53 my ($event) = @_;
27              
28             # No info, no squash
29 32 100       85 return unless $event->has_info;
30              
31             # Do not merge up if one of these is true
32 28 100   163   150 return if first { $event->$_ } qw/causes_fail has_assert has_bailout has_errors has_plan has_subtest/;
  163         447  
33              
34             # Signature if we can squash
35 27         126 return $event->trace_signature;
36             }
37              
38             sub process {
39 28     28 0 71 my $self = shift;
40 28         56 my ($event) = @_;
41              
42 28 100       71 return if $self->squash_up($event);
43 21 100       51 return if $self->squash_down($event);
44              
45 5         17 $self->flush_down($event);
46              
47 5         10 push @{$self->{+EVENTS}} => $event;
  5         14  
48              
49 5         25 return;
50             }
51              
52             sub squash_down {
53 21     21 0 32 my $self = shift;
54 21         42 my ($event) = @_;
55              
56 21 100       40 my $sig = $self->can_squash($event)
57             or return;
58              
59             $self->flush_down()
60 16 100 100     77 if $self->{+DOWN_SIG} && $self->{+DOWN_SIG} ne $sig;
61              
62 16   66     76 $self->{+DOWN_SIG} ||= $sig;
63 16         25 push @{$self->{+DOWN_BUFFER}} => $event;
  16         42  
64              
65 16         142 return 1;
66             }
67              
68             sub flush_down {
69 17     17 0 28 my $self = shift;
70 17         31 my ($into) = @_;
71              
72 17         37 my $sig = delete $self->{+DOWN_SIG};
73 17         32 my $buffer = delete $self->{+DOWN_BUFFER};
74              
75 17 100 66     62 return unless $buffer && @$buffer;
76              
77 14 100       32 my $fsig = $into ? $into->trace_signature : undef;
78              
79 14 100 66     44 if ($fsig && $fsig eq $sig) {
80 4         16 $self->squash($into, @$buffer);
81             }
82             else {
83 10 50       24 push @{$self->{+EVENTS}} => @$buffer if $buffer;
  10         37  
84             }
85             }
86              
87             sub clear_up {
88 28     28 0 47 my $self = shift;
89              
90 28 100       76 return unless $self->{+UP_CLEAR};
91              
92 3         9 delete $self->{+UP_INTO};
93 3         6 delete $self->{+UP_SIG};
94 3         6 delete $self->{+UP_CLEAR};
95             }
96              
97             sub squash_up {
98 28     28 0 43 my $self = shift;
99 28         47 my ($event) = @_;
100 35     35   309 no warnings 'uninitialized';
  35         110  
  35         11083  
101              
102 28         71 $self->clear_up;
103              
104 28 100       80 if ($event->has_assert) {
105 5 50       15 if(my $sig = $event->trace_signature) {
106 5         14 $self->{+UP_INTO} = $event;
107 5         11 $self->{+UP_SIG} = $sig;
108 5         12 $self->{+UP_CLEAR} = 0;
109             }
110             else {
111 0         0 $self->{+UP_CLEAR} = 1;
112 0         0 $self->clear_up;
113             }
114              
115 5         17 return;
116             }
117              
118 23 100       73 my $into = $self->{+UP_INTO} or return;
119              
120             # Next iteration should clear unless something below changes that
121 11         20 $self->{+UP_CLEAR} = 1;
122              
123             # Only merge into matching trace signatres
124 11         24 my $sig = $self->can_squash($event);
125 11 100       43 return unless $sig eq $self->{+UP_SIG};
126              
127             # OK Merge! Do not clear merge in case the return event is also a matching sig diag-only
128 7         16 $self->{+UP_CLEAR} = 0;
129              
130 7         22 $self->squash($into, $event);
131              
132 7         70 return 1;
133             }
134              
135             sub squash {
136 11     11 0 20 my $self = shift;
137 11         27 my ($into, @from) = @_;
138 11         30 push @{$into->facet_data->{info}} => $_->info for @from;
  13         34  
139             }
140              
141             sub DESTROY {
142 3     3   12 my $self = shift;
143              
144 3 50       11 return unless $self->{+EVENTS};
145 3         11 $self->flush_down();
146 3         11 return;
147             }
148              
149             1;
150              
151             __END__