TEST2::API::INTERCEPTRESULT(3perl)

✨ Test2::API::InterceptResult ✨

okay bestie, you found the 3perl page for Test2::API::InterceptResult, straight out of the Perl Programmers Reference Guide πŸ’… and like. it's a whole mood. come sit with me.


πŸŽ€ NAME πŸŽ€

Test2::API::InterceptResult β€” Representation of a list of events. that's it. that's the girl. a list of events with a little bow on it 🎁


🌸 DESCRIPTION 🌸

So this class? It represents a list of events, normally the ones you get back from intercept() over in Test2::API. πŸ¦‹

It's made for people who want to verify the results of the test tools they write. Yes, that means you. You're building your own test tool. Iconic behavior, honestly πŸ‘‘

It gives you methods to normalize, summarize, or map that list of events. and the way that the output of these operations makes verifying your testing tools and the events they generate significantly easier?? unmatched. In most cases it spares you from needing a deep understanding of the event/facet model, which β€” ngl β€” is the part where everyone's eyes glaze over 😭 so this is genuinely a gift.


✨ SYNOPSIS ✨

Usually you get an instance of this class when you use intercept() from Test2::API. like, that's the standard origin story.

use Test2::V1 '-iPp';
use Test2::API qw/intercept/;

my $events = intercept {
    ok(1, "pass");
    ok(0, "fail");
    todo "broken" => sub { ok(0, "fixme") };
    plan 3;
};

# This is typically the most useful construct
# squash_info() merges assertions and diagnostics that are associated
#   (and returns a new instance with the modifications)
# flatten() condenses the facet data into the key details for each event
#   (and returns those structures in an arrayref)
is(
    $events->squash_info->flatten(),
    [
        {
            causes_failure => 0,

            name => 'pass',
            pass => 1,

            trace_file => 'xxx.t',
            trace_line => 5,
        },
        {
            causes_failure => 1,

            name => 'fail',
            pass => 0,

            trace_file => 'xxx.t',
            trace_line => 6,

            # There can be more than one diagnostics message so this is
            # always an array when present.
            diag => ["Failed test 'fail'\nat xxx.t line 6."],
        },
        {
            causes_failure => 0,

            name => 'fixme',
            pass => 0,

            trace_file => 'xxx.t',
            trace_line => 7,

            # There can be more than one diagnostics message or todo
            # reason, so these are always an array when present.
            todo => ['broken'],

            # Diag message was turned into a note since the assertion was
            # TODO
            note => ["Failed test 'fixme'\nat xxx.t line 7."],
        },
        {
            causes_failure => 0,

            plan => 3,

            trace_file => 'xxx.t',
            trace_line => 8,
        },
    ],
    "Flattened events look like we expect"
);

and if you want the full tea on what flatten() actually hands you for each individual event, go read Test2::API::InterceptResult::Event. it explains everything 🫢


πŸ¦‹ METHODS πŸ¦‹

Please note that no methods modify the original instance unless asked to do so. She respects boundaries. we love that πŸ’–

πŸ’œ CONSTRUCTION πŸ’œ

  • $events = Test2::API::InterceptResult->new(@EVENTS)
  • $events = Test2::API::InterceptResult->new_from_ref(\@EVENTS)

These two make you a shiny new Test2::API::InterceptResult instance out of the events you hand over.

In the first form you get back a new blessed arrayref. In the new_from_ref form, the reference you pass in is directly blessed β€” no copy, she just puts the crown on the thing you brought πŸ‘‘

Both of these will throw an exception if called in void context. This matters mainly for the filtering methods listed below, because those normally return a new instance. If you call them in void context it probably means someone meant to filter the original in place, and so they throw an exception instead of silently doing nothing. the compiler is looking out for you fr fr πŸ’€
  • $clone = $events->clone()

Makes a clone of the original events. Heads up: this is a deep copy, the entire structure gets duplicated. It uses "dclone" from Storable to pull off the deep clone. no shortcuts, no shared refs, full duplicate energy ✨

🌈 NORMALIZATION 🌈

  • @events = $events->event_list

Returns all the events, in list form. that's the whole thing. simple. gorgeous.

  • $hub = $events->hub

Returns a new Test2::Hub instance that has processed all the events contained in the instance. Which is a whole easy way for you to peek at the state changes your events cause πŸ‘€

  • $state = $events->state

Returns a summary of the state of a hub after processing all the events. Behold:

{
    count        => 2,      # Number of assertions made
    failed       => 1,      # Number of test failures seen
    is_passing   => 0,      # Boolean, true if the test would be passing
                            # after the events are processed.

    plan         => 2,      # Plan, either a number, undef, 'SKIP', or 'NO PLAN'
    follows_plan => 1,      # True if there is a plan and it was followed.
                            # False if the plan and assertions did not
                            # match, undef if no plan was present in the
                            # event list.

    bailed_out   => undef,  # undef unless there was a bail-out in the
                            # events in which case this will be a string
                            # explaining why there was a bailout, if no
                            # reason was given this will simply be set to
                            # true (1).

    skip_reason  => undef,  # If there was a skip_all this will give the
                            # reason.
}
  • $new = $events->upgrade
  • $events->upgrade(in_place => $BOOL)
Note: This normally returns a new instance, leaving the original untouched. If you call it in void context it will throw an exception. If you want to modify the original you must pass in the "in_place => 1" option. You may call this in void context when you ask to modify it in place. And the in-place form returns the instance that was modified, so you can chain methods like a boss πŸ’…

This creates a clone of the list where all events have been converted into Test2::API::InterceptResult::Event instances. This is extremely helpful, because Test2::API::InterceptResult::Event provides a much better interface for working with events. It lets you avoid thinking about legacy event types entirely. main character energy for real.

It also means your tests against the list aren't fragile if the tool you're testing randomly changes what type of events it generates β€” IE changing from Test2::Event::Ok to Test2::Event::Pass; both make assertions and both will normalize to identical (or close enough) Test2::API::InterceptResult::Event instances. slay.

Really, you almost always want this. The only reason it isn't done automatically is to make sure the intercept() tool stays backwards compatible. considerate of them, honestly 🫢

  • $new = $events->squash_info
  • $events->squash_info(in_place => $BOOL)
Note: This normally returns a new instance, leaving the original unchanged. If you call it in void context it will throw an exception. If you want to modify the original you must pass in the "in_place => 1" option. You may call this in void context when you ask to modify it in place. The in-place form returns the instance that was modified, so you can chain methods 🌸
Note: All events in the new or modified instance will be converted to Test2::API::InterceptResult::Event instances. There is no way to avoid this β€” the squash operation requires the upgraded event class. periodt.

Test::More and many other legacy tools would send notes, diags, and assertions as separate events. A subtest in Test::More would send a note with the subtest name, the subtest assertion, and finally a diagnostics event if the subtest failed. This method normalizes things by squashing the note and diag into the same event as the subtest β€” and to be clear, this is different from putting them into the subtest, which is not what happens. read that twice bestie πŸ™ˆ

🧚 FILTERING 🧚

Note: These normally return new instances, leaving the originals unchanged. If you call them in void context they will throw exceptions. If you want to modify the originals you must pass in the "in_place => 1" option. You may call these in void context when you ask to modify them in place. The in-place forms return the instance that was modified so you can chain methods πŸ’œ

⭐ %PARAMS

These all accept the same 2 optional parameters:

  • in_place => $BOOL β€” When true, the method will modify the instance in place instead of returning a new instance.
  • args => \@ARGS β€” If you want to pass parameters into the event method being used for filtering, you do it right here.

πŸ“ METHODS

  • $events->grep($CALL, %PARAMS)

This is essentially:

Test2::API::InterceptResult->new(
    grep { $_->$CALL( @{$PARAMS{args}} ) } $self->event_list,
);
Note: $CALL is called on an upgraded version of the event, though the events returned will be the original ones, not the upgraded ones. sneaky but fair.

$CALL may be either the name of a method on Test2::API::InterceptResult::Event, or a coderef.

  • $events->asserts(%PARAMS)

This is essentially:

$events->grep(has_assert => @{$PARAMS{args}})

It returns a new instance containing only the events that made assertions. ✨

  • $events->subtests(%PARAMS)

This is essentially:

$events->grep(has_subtest => @{$PARAMS{args}})

It returns a new instance containing only the events that have subtests. πŸŽ€

  • $events->diags(%PARAMS)

This is essentially:

$events->grep(has_diags => @{$PARAMS{args}})

It returns a new instance containing only the events that have diags. πŸ”₯

  • $events->notes(%PARAMS)

This is essentially:

$events->grep(has_notes => @{$PARAMS{args}})

It returns a new instance containing only the events that have notes. 🌸

  • $events->errors(%PARAMS)
Note: Errors are NOT failing assertions. Failing assertions are a different thing. don't conflate them bestie, i'm begging 😭

This is essentially:

$events->grep(has_errors => @{$PARAMS{args}})

It returns a new instance containing only the events that have errors. πŸ’€

  • $events->plans(%PARAMS)

This is essentially:

$events->grep(has_plan => @{$PARAMS{args}})

It returns a new instance containing only the events that set the plan. πŸ‘‘

  • $events->causes_fail(%PARAMS)
  • $events->causes_failure(%PARAMS)

These are essentially:

$events->grep(causes_fail    => @{$PARAMS{args}})
$events->grep(causes_failure => @{$PARAMS{args}})
Note: causes_fail() and causes_failure() are both aliases for each other in events, so these methods are effectively aliases here as well. two names, one vibe, no cap πŸ’…

...and yeah bestie, it hands you back a new instance that contains only the events that cause failure. Nothing else. Just the drama. πŸ’…


πŸ—ΊοΈ MAPPING (the glow-up section) πŸ—ΊοΈ

Okay so real talk: these methods ALWAYS return an arrayref. Always. No exceptions, no surprises, no "oops it's undef today". πŸŽ€

Note: No methods on Test2::API::InterceptResult::Event alter the event in any way. Like, zero. They're all looks, no touch. πŸ™ˆ

Important Notes about Events

Test2::API::InterceptResult::Event was tailor-made to be used in event-lists. Stitched with love, fr fr. 🧡✨

Most methods that are not applicable to a given event will just return an empty list. So you do not need to sit there stressing about unwanted "undef" values or exceptions getting thrown at you. Mapping over event methods is an intended use case β€” that's literally what it's for β€” so it works beautifully to produce lists. It's giving designed-for-this. πŸ‘‘

Exceptions to the rule (the ones that will actually do something spicy) πŸ”₯

  • Some methods, such as "causes_fail", always return a boolean true or false for all events. Every single one. No empty-list behaviour here.
  • Any method prefixed with "the_" is out here conveying the intent that the event should have exactly 1 of something. So bestie, if that condition isn't true, they will throw an exception. Exactly one means exactly one. Periodt. πŸ’€

$arrayref = $events->map($CALL, %PARAMS)

This is essentially:

[ map { $_->$CALL(@{ $PARAMS{args} }) } $events->upgrade->event_list ];

And $CALL may be either the name of a method on Test2::API::InterceptResult::Event, or a coderef. Either one, your choice, main character energy. πŸ¦‹


$arrayref = $events->flatten(%PARAMS)

This is essentially:

[ map { $_->flatten(@{ $PARAMS{args} }) } $events->upgrade->event_list ];

It returns a new list of flattened structures. 🌸

See Test2::API::InterceptResult::Event for the deets on what flatten() actually returns, iykyk.


$arrayref = $events->briefs(%PARAMS)

This is essentially:

[ map { $_->briefs(@{ $PARAMS{args} }) } $events->upgrade->event_list ];

It returns a new list of event briefs. πŸ“

See Test2::API::InterceptResult::Event for the deets on what brief() returns.


$arrayref = $events->summaries(%PARAMS)

This is essentially:

[ map { $_->summaries(@{ $PARAMS{args} }) } $events->upgrade->event_list ];

It returns a new list of event summaries. ⭐

See Test2::API::InterceptResult::Event for the deets on what summary() returns.


$arrayref = $events->subtest_results(%PARAMS)

This is essentially:

[ map { $_->subtest_result(@{ $PARAMS{args} }) } $events->upgrade->event_list ];

It returns a new list of event summaries. (Yes, it says summaries. That's what the page says, bestie, and I don't make the rules. 🀷)

See Test2::API::InterceptResult::Event for the deets on what subtest_result() returns.


$arrayref = $events->diag_messages(%PARAMS)

This is essentially:

[ map { $_->diag_messages(@{ $PARAMS{args} }) } $events->upgrade->event_list ];

It returns a new list of diagnostic messages (strings). 🩺🌸

See Test2::API::InterceptResult::Event for the deets on what diag_messages() returns.


$arrayref = $events->note_messages(%PARAMS)

This is essentially:

[ map { $_->note_messages(@{ $PARAMS{args} }) } $events->upgrade->event_list ];

It returns a new list of notification messages (strings). πŸ””

See Test2::API::InterceptResult::Event for the deets on what note_messages() returns.


$arrayref = $events->error_messages(%PARAMS)

This is essentially:

[ map { $_->error_messages(@{ $PARAMS{args} }) } $events->upgrade->event_list ];

It returns a new list of error messages (strings). πŸ’€πŸ’–

See Test2::API::InterceptResult::Event for the deets on what error_messages() returns.


πŸ“¦ SOURCE πŸ“¦

The source code repository for Test2 can be found at <https://github.com/Test-More/test-more/>.

(Go on, click it. The source is right there, no gatekeeping. 🫢)


πŸ‘‘ MAINTAINERS πŸ‘‘

Chad Granum <exodist@cpan.org>


✨ AUTHORS ✨

Chad Granum <exodist@cpan.org>


Copyright Chad Granum <exodist@cpan.org>.

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

See <https://dev.perl.org/licenses/>



Okay that's the whole page, you made it to the end, I'm so proud of you πŸ₯ΉπŸ’œ This one shipped as part of perl v5.44.0, dated 2026-10-17, page Test2:...tResult(3perl) β€” go forth and map over those events, bestie. Slay. πŸ’…πŸŒˆ

πŸ“¦ where this page comes from
  • arch rolling: perl 5.44.0-1 Β· Artistic-1.0-Perl AND GPL-1.0-or-later
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms