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   774 use strict;
  35         85  
  35         1077  
3 35     35   180 use warnings;
  35         70  
  35         2768  
4              
5             our $VERSION = '1.302181';
6              
7 35     35   226 use Carp qw/croak/;
  35         74  
  35         1859  
8 35     35   240 use List::Util qw/first/;
  35         75  
  35         3049  
9              
10 35         338 use Test2::Util::HashBase qw{
11             <events
12              
13             +down_sig +down_buffer
14              
15             +up_into +up_sig +up_clear
16 35     35   248 };
  35         77  
17              
18             sub init {
19 3     3 0 6 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 58 my $self = shift;
26 32         48 my ($event) = @_;
27              
28             # No info, no squash
29 32 100       82 return unless $event->has_info;
30              
31             # Do not merge up if one of these is true
32 28 100   163   153 return if first { $event->$_ } qw/causes_fail has_assert has_bailout has_errors has_plan has_subtest/;
  163         421  
33              
34             # Signature if we can squash
35 27         124 return $event->trace_signature;
36             }
37              
38             sub process {
39 28     28 0 70 my $self = shift;
40 28         57 my ($event) = @_;
41              
42 28 100       63 return if $self->squash_up($event);
43 21 100       54 return if $self->squash_down($event);
44              
45 5         18 $self->flush_down($event);
46              
47 5         12 push @{$self->{+EVENTS}} => $event;
  5         13  
48              
49 5         25 return;
50             }
51              
52             sub squash_down {
53 21     21 0 29 my $self = shift;
54 21         41 my ($event) = @_;
55              
56 21 100       44 my $sig = $self->can_squash($event)
57             or return;
58              
59             $self->flush_down()
60 16 100 100     79 if $self->{+DOWN_SIG} && $self->{+DOWN_SIG} ne $sig;
61              
62 16   66     65 $self->{+DOWN_SIG} ||= $sig;
63 16         24 push @{$self->{+DOWN_BUFFER}} => $event;
  16         44  
64              
65 16         141 return 1;
66             }
67              
68             sub flush_down {
69 17     17 0 28 my $self = shift;
70 17         31 my ($into) = @_;
71              
72 17         38 my $sig = delete $self->{+DOWN_SIG};
73 17         30 my $buffer = delete $self->{+DOWN_BUFFER};
74              
75 17 100 66     63 return unless $buffer && @$buffer;
76              
77 14 100       35 my $fsig = $into ? $into->trace_signature : undef;
78              
79 14 100 66     42 if ($fsig && $fsig eq $sig) {
80 4         16 $self->squash($into, @$buffer);
81             }
82             else {
83 10 50       26 push @{$self->{+EVENTS}} => @$buffer if $buffer;
  10         35  
84             }
85             }
86              
87             sub clear_up {
88 28     28 0 37 my $self = shift;
89              
90 28 100       79 return unless $self->{+UP_CLEAR};
91              
92 3         8 delete $self->{+UP_INTO};
93 3         8 delete $self->{+UP_SIG};
94 3         7 delete $self->{+UP_CLEAR};
95             }
96              
97             sub squash_up {
98 28     28 0 44 my $self = shift;
99 28         44 my ($event) = @_;
100 35     35   316 no warnings 'uninitialized';
  35         90  
  35         11326  
101              
102 28         79 $self->clear_up;
103              
104 28 100       77 if ($event->has_assert) {
105 5 50       24 if(my $sig = $event->trace_signature) {
106 5         13 $self->{+UP_INTO} = $event;
107 5         11 $self->{+UP_SIG} = $sig;
108 5         14 $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       75 my $into = $self->{+UP_INTO} or return;
119              
120             # Next iteration should clear unless something below changes that
121 11         17 $self->{+UP_CLEAR} = 1;
122              
123             # Only merge into matching trace signatres
124 11         26 my $sig = $self->can_squash($event);
125 11 100       38 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         23 $self->squash($into, $event);
131              
132 7         72 return 1;
133             }
134              
135             sub squash {
136 11     11 0 19 my $self = shift;
137 11         25 my ($into, @from) = @_;
138 11         29 push @{$into->facet_data->{info}} => $_->info for @from;
  13         35  
139             }
140              
141             sub DESTROY {
142 3     3   12 my $self = shift;
143              
144 3 50       12 return unless $self->{+EVENTS};
145 3         11 $self->flush_down();
146 3         11 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