<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package Test2::API::InterceptResult::Squasher;
use strict;
use warnings;

our $VERSION = '1.302199';

use Carp qw/croak/;
use List::Util qw/first/;

use Test2::Util::HashBase qw{
    &lt;events

    +down_sig +down_buffer

    +up_into +up_sig +up_clear
};

sub init {
    my $self = shift;

    croak "'events' is a required attribute"  unless $self-&gt;{+EVENTS};
}

sub can_squash {
    my $self = shift;
    my ($event) = @_;

    # No info, no squash
    return unless $event-&gt;has_info;

    # Do not merge up if one of these is true
    return if first { $event-&gt;$_ } 'causes_fail', 'has_assert', 'has_bailout', 'has_errors', 'has_plan', 'has_subtest';

    # Signature if we can squash
    return $event-&gt;trace_signature;
}

sub process {
    my $self = shift;
    my ($event) = @_;

    return if $self-&gt;squash_up($event);
    return if $self-&gt;squash_down($event);

    $self-&gt;flush_down($event);

    push @{$self-&gt;{+EVENTS}} =&gt; $event;

    return;
}

sub squash_down {
    my $self = shift;
    my ($event) = @_;

    my $sig = $self-&gt;can_squash($event)
        or return;

    $self-&gt;flush_down()
        if $self-&gt;{+DOWN_SIG} &amp;&amp; $self-&gt;{+DOWN_SIG} ne $sig;

    $self-&gt;{+DOWN_SIG} ||= $sig;
    push @{$self-&gt;{+DOWN_BUFFER}} =&gt; $event;

    return 1;
}

sub flush_down {
    my $self = shift;
    my ($into) = @_;

    my $sig    = delete $self-&gt;{+DOWN_SIG};
    my $buffer = delete $self-&gt;{+DOWN_BUFFER};

    return unless $buffer &amp;&amp; @$buffer;

    my $fsig = $into ? $into-&gt;trace_signature : undef;

    if ($fsig &amp;&amp; $fsig eq $sig) {
        $self-&gt;squash($into, @$buffer);
    }
    else {
        push @{$self-&gt;{+EVENTS}} =&gt; @$buffer if $buffer;
    }
}

sub clear_up {
    my $self = shift;

    return unless $self-&gt;{+UP_CLEAR};

    delete $self-&gt;{+UP_INTO};
    delete $self-&gt;{+UP_SIG};
    delete $self-&gt;{+UP_CLEAR};
}

sub squash_up {
    my $self = shift;
    my ($event) = @_;
    no warnings 'uninitialized';

    $self-&gt;clear_up;

    if ($event-&gt;has_assert) {
        if(my $sig = $event-&gt;trace_signature) {
            $self-&gt;{+UP_INTO}  = $event;
            $self-&gt;{+UP_SIG}   = $sig;
            $self-&gt;{+UP_CLEAR} = 0;
        }
        else {
            $self-&gt;{+UP_CLEAR} = 1;
            $self-&gt;clear_up;
        }

        return;
    }

    my $into = $self-&gt;{+UP_INTO} or return;

    # Next iteration should clear unless something below changes that
    $self-&gt;{+UP_CLEAR} = 1;

    # Only merge into matching trace signatres
    my $sig = $self-&gt;can_squash($event);
    return unless $sig eq $self-&gt;{+UP_SIG};

    # OK Merge! Do not clear merge in case the return event is also a matching sig diag-only
    $self-&gt;{+UP_CLEAR} = 0;

    $self-&gt;squash($into, $event);

    return 1;
}

sub squash {
    my $self = shift;
    my ($into, @from) = @_;
    push @{$into-&gt;facet_data-&gt;{info}} =&gt; $_-&gt;info for @from;
}

sub DESTROY {
    my $self = shift;

    return unless $self-&gt;{+EVENTS};
    $self-&gt;flush_down();
    return;
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Test2::API::InterceptResult::Squasher - Encapsulation of the algorithm that
squashes diags into assertions.

=head1 DESCRIPTION

Internal use only, please ignore.

=head1 SOURCE

The source code repository for Test2 can be found at
L&lt;https://github.com/Test-More/test-more/&gt;.

=head1 MAINTAINERS

=over 4

=item Chad Granum E&lt;lt&gt;exodist@cpan.orgE&lt;gt&gt;

=back

=head1 AUTHORS

=over 4

=item Chad Granum E&lt;lt&gt;exodist@cpan.orgE&lt;gt&gt;

=back

=head1 COPYRIGHT

Copyright 2020 Chad Granum E&lt;lt&gt;exodist@cpan.orgE&lt;gt&gt;.

This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

See L&lt;https://dev.perl.org/licenses/&gt;

=cut
</pre></body></html>