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   764 use strict;
  35         86  
  35         1147  
3 35     35   230 use warnings;
  35         71  
  35         1689  
4              
5             our $VERSION = '1.302182';
6              
7 35     35   265 use Carp qw/croak/;
  35         74  
  35         1805  
8 35     35   244 use List::Util qw/first/;
  35         76  
  35         2869  
9              
10 35         328 use Test2::Util::HashBase qw{
11             <events
12              
13             +down_sig +down_buffer
14              
15             +up_into +up_sig +up_clear
16 35     35   267 };
  35         82  
17              
18             sub init {
19 3     3 0 9 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 51 my $self = shift;
26 32         51 my ($event) = @_;
27              
28             # No info, no squash
29 32 100       80 return unless $event->has_info;
30              
31             # Do not merge up if one of these is true
32 28 100   163   149 return if first { $event->$_ } 'causes_fail', 'has_assert', 'has_bailout', 'has_errors', 'has_plan', 'has_subtest';
  163         433  
33              
34             # Signature if we can squash
35 27         116 return $event->trace_signature;
36             }
37              
38             sub process {
39 28     28 0 74 my $self = shift;
40 28         56 my ($event) = @_;
41              
42 28 100       67 return if $self->squash_up($event);
43 21 100       52 return if $self->squash_down($event);
44              
45 5         16 $self->flush_down($event);
46              
47 5         9 push @{$self->{+EVENTS}} => $event;
  5         14  
48              
49 5         26 return;
50             }
51              
52             sub squash_down {
53 21     21 0 34 my $self = shift;
54 21         35 my ($event) = @_;
55              
56 21 100       46 my $sig = $self->can_squash($event)
57             or return;
58              
59             $self->flush_down()
60 16 100 100     73 if $self->{+DOWN_SIG} && $self->{+DOWN_SIG} ne $sig;
61              
62 16   66     66 $self->{+DOWN_SIG} ||= $sig;
63 16         26 push @{$self->{+DOWN_BUFFER}} => $event;
  16         40  
64              
65 16         155 return 1;
66             }
67              
68             sub flush_down {
69 17     17 0 30 my $self = shift;
70 17         32 my ($into) = @_;
71              
72 17         37 my $sig = delete $self->{+DOWN_SIG};
73 17         35 my $buffer = delete $self->{+DOWN_BUFFER};
74              
75 17 100 66     58 return unless $buffer && @$buffer;
76              
77 14 100       33 my $fsig = $into ? $into->trace_signature : undef;
78              
79 14 100 66     48 if ($fsig && $fsig eq $sig) {
80 4         16 $self->squash($into, @$buffer);
81             }
82             else {
83 10 50       36 push @{$self->{+EVENTS}} => @$buffer if $buffer;
  10         41  
84             }
85             }
86              
87             sub clear_up {
88 28     28 0 45 my $self = shift;
89              
90 28 100       78 return unless $self->{+UP_CLEAR};
91              
92 3         7 delete $self->{+UP_INTO};
93 3         5 delete $self->{+UP_SIG};
94 3         8 delete $self->{+UP_CLEAR};
95             }
96              
97             sub squash_up {
98 28     28 0 43 my $self = shift;
99 28         42 my ($event) = @_;
100 35     35   324 no warnings 'uninitialized';
  35         95  
  35         11120  
101              
102 28         75 $self->clear_up;
103              
104 28 100       74 if ($event->has_assert) {
105 5 50       19 if(my $sig = $event->trace_signature) {
106 5         14 $self->{+UP_INTO} = $event;
107 5         12 $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         16 return;
116             }
117              
118 23 100       70 my $into = $self->{+UP_INTO} or return;
119              
120             # Next iteration should clear unless something below changes that
121 11         22 $self->{+UP_CLEAR} = 1;
122              
123             # Only merge into matching trace signatres
124 11         25 my $sig = $self->can_squash($event);
125 11 100       42 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         15 $self->{+UP_CLEAR} = 0;
129              
130 7         21 $self->squash($into, $event);
131              
132 7         67 return 1;
133             }
134              
135             sub squash {
136 11     11 0 23 my $self = shift;
137 11         24 my ($into, @from) = @_;
138 11         26 push @{$into->facet_data->{info}} => $_->info for @from;
  13         34  
139             }
140              
141             sub DESTROY {
142 3     3   15 my $self = shift;
143              
144 3 50       16 return unless $self->{+EVENTS};
145 3         11 $self->flush_down();
146 3         10 return;
147             }
148              
149             1;
150              
151             __END__
152              
153             =pod
154              
155             =encoding UTF-8
156              
157             =head1 NAME
158              
159             Test2::API::InterceptResult::Squasher - Encapsulation of the algorithm that
160             squashes diags into assertions.
161              
162             =head1 DESCRIPTION
163              
164             Internal use only, please ignore.
165              
166             =head1 SOURCE
167              
168             The source code repository for Test2 can be found at
169             F<http://github.com/Test-More/test-more/>.
170              
171             =head1 MAINTAINERS
172              
173             =over 4
174              
175             =item Chad Granum E<lt>exodist@cpan.orgE<gt>
176              
177             =back
178              
179             =head1 AUTHORS
180              
181             =over 4
182              
183             =item Chad Granum E<lt>exodist@cpan.orgE<gt>
184              
185             =back
186              
187             =head1 COPYRIGHT
188              
189             Copyright 2020 Chad Granum E<lt>exodist@cpan.orgE<gt>.
190              
191             This program is free software; you can redistribute it and/or
192             modify it under the same terms as Perl itself.
193              
194             See F<http://dev.perl.org/licenses/>
195              
196             =cut