Test2:...:Event(3perl)

πŸ’– Test2::API::InterceptResult::Event πŸ’–

From the Perl Programmers Reference Guide β€” Test2:...:Event(3perl)

✨ NAME ✨

Test2::API::InterceptResult::Event β€” it's literally a representation of an event for use in testing other test tools. Periodt.


🌸 DESCRIPTION 🌸

So intercept { ... } from Test2::API gives you back a Test2::API::InterceptResult β€” which is a blessed arrayref full of Test2::API::InterceptResult::Event objects. πŸ’β€β™€οΈ

This POD is all about the methods on these event objects. They're mainly there so you can use them when you're testing your own test tools. You're welcome. 🫢


πŸŽ€ SYNOPSIS πŸŽ€

Okay bestie, here's the vibe:

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

my $events = intercept {
    ok(1, "A passing assertion");
    plan(1);
};

# This will convert all events into instances of
# Test2::API::InterceptResult::Event. Until we do this they are the
# original Test::Event::* instances
$events->upgrade(in_place => 1);

# Now we can get individual events in this form
my $assert = $events->[0];
my $plan   = $events->[1];

# Or we can operate on all events at once:
my $flattened = $events->flatten;
is(
    $flattened,
    [
      {
        causes_failure => 0,

        name => 'A passing assertion',
        pass => 1,

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

        plan => 1,

        trace_file => 'xxx.t',
        trace_line => 6,
      },
    ],
    "Flattened both events and returned an arrayref of the results
);

Note: the last line is missing a closing quote β€” that's how the original is, so we keep it exactly. πŸ’…


🧚 METHODS 🧚

🚨 !!! IMPORTANT NOTES ON DESIGN !!! 🚨

Okay so listen up, because this is important. Pay attention to what these methods return. A lot of them return a scalar when it makes sense, or an empty list when it doesn't (not undef, okay?). Many also always return a list of 0 or more items. Some always return a scalar. And here's the thing: none of these methods care about context β€” their behavior is the same whether you call them in scalar, list, or void context. No cap.

Why? Because this class was designed to be used in a list and to generate more lists in bulk operations. Sometimes in a map you want nothing to show up for the event, and you don't want an undef sitting there instead. In general, single event instances aren't going to be used alone, though you can do that if you want.

As a general rule, any method prefixed with "the_" means the event should have exactly one of the specified item. If there are zero, or more than one, it throws an exception. So don't play yourself. πŸ’€

πŸ¦‹ ATTRIBUTES πŸ¦‹

  • $hashref = $event->facet_data β€” This gives you back the facet data hashref. It's literally all Test2 cares about for any given event. ✨
  • $class = $event->result_class β€” This is normally Test2::API::InterceptResult. It gets set at construction so that subtest results can be turned into instances of it on demand. Slay.

πŸŽ€ DUPLICATION πŸŽ€

  • $copy = $event->clone β€” Creates a deep copy of the event. Modifying either event will not affect the other. So you can go wild. πŸ’…

🌈 CONDENSED MULTI-FACET DATA 🌈

  • $bool = $event->causes_failure
  • $bool = $event->causes_fail β€” These are both aliases of the same functionality.

This always returns either a true value or a false value. It never returns a list.

This method may be relatively slow (but still super fast) because it figures out pass or fail by creating an instance of Test2::Hub and asking it to process the event, then asks the hub for its pass/fail state. This is slower than building in logic to do the check, but it's more reliable because it always tells you what the hub thinks, so the logic will never be out of date relative to the Test2 logic that actually cares. πŸ’―

  • STRING_OR_EMPTY_LIST = $event->brief β€” Not all events have a brief. Some events aren't rendered by the formatter, others have no "brief" data worth seeing. When that happens, an empty list is returned. This is done on purpose so you can use it in a map operation without undef being included in the result.

When a brief can be generated, it's always a single 1-line string, returned as-is, not in a list.

Possible briefs:

# From control facets
"BAILED OUT"
"BAILED OUT: $why"

# From error facets
"ERROR"
"ERROR: $message"
"ERROR: $partial_message [...]"
"ERRORS: $first_error_message [...]"

# From assert facets
"PASS"
"FAIL"
"PASS with amnesty"
"FAIL with amnesty"

# From plan facets
"PLAN $count"
"NO PLAN"
"SKIP ALL"
"SKIP ALL: $why"

Note that only the first applicable brief is returned. This is essentially a poor-mans TAP that only includes facets that could (but not necessarily do) cause a failure.

  • $hashref = $event->flatten
  • $hashref = $event->flatten(include_subevents => 1) β€” This ALWAYS returns a hashref. It puts all the most useful data for the most interesting facets into a single hashref for easy validation.

If there are no meaningful facets, it returns an empty hashref.

If given the 'include_subevents' parameter, it will also include subtest data:

Here is a list of EVERY possible field. If a field is not applicable, it will not be present.

always present

causes_failure => 1,    # Always present

Present if the event has a trace facet

trace_line    => 42,
trace_file    => 'Foo/Bar.pm',
trace_details => 'Extra trace details',    # usually not present

If an assertion is present

pass => 0,
name => "1 + 1 = 2, so math works",

If a plan is present:

plan => $count_or_SKIP_ALL_or_NO_PLAN,

If amnesty facets are present You get an array for each type that is present.

todo => [    # Yes you could be under multiple todos, this will list them all.
    "I will fix this later",
    "I promise to fix these",
],

skip => ["This will format the main drive, do not run"],

... => ["Other amnesty"]

If Info (note/diag) facets are present You get an arrayref for any that are present, the key is not defined if they are not present.

diag => [
    "Test failed at Foo/Bar.pm line 42",
    "You forgot to tie your boots",
],

note => ["Your boots are red"],

...  => ["Other info"],

If error facets are present Always an arrayref

error => [
    "non fatal error (does not cause test failure, just an FYI",
    "FATAL: This is a fatal error (causes failure)",
],

# Errors can have alternative tags, but in practice are always 'error',
# listing this for completeness.
... => [ ... ]

Present if the event is a subtest

subtest => {
    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 => "foo",    # if there was a bail-out in the
                            # events in 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 => "foo",   # If there was a skip_all this will give the
                            # reason.
},

if (include_subtest => 1) was provided as a parameter then the following will be included. This is the result of turning all subtest child events into an Test2::API::InterceptResult instance and calling the "flatten" method on it.

subevents => Test2::API::InterceptResult->new(@child_events)->flatten(...),

If a bail-out is being requested If no reason was given this will be set to 1.

bailed_out => "reason",
  • $hashref = $event->summary() β€” This returns a limited summary. See flatten(), which is usually a better option.
{
    brief => $event->brief || '',

    causes_failure => $event->causes_failure,

    trace_line    => $event->trace_line,
    trace_file    => $event->trace_file,
    trace_tool    => $event->trace_subname,
    trace_details => $event->trace_details,

    facets => [ sort keys(%{$event->{+FACET_DATA}}) ],
}

πŸ’Ž DIRECT ARBITRARY FACET ACCESS πŸ’Ž

  • @list_of_facets = $event->facet($name) β€” This always returns a list of 0 or more items. It fetches the facet instances from the event. For facets like 'assert' this will always return 0 or 1 item. For events like 'info' (diags, notes) this will return 0 or more instances, once for each instance of the facet.

These will be blessed into the proper Test2::EventFacet subclass. If no subclass can be found, it will be blessed as an Test2::API::InterceptResult::Facet generic facet class.

  • $undef_or_facet = $event->the_facet($name) β€” If you know you'll have exactly 1 instance of a facet, you can call this. If you're correct and there's exactly one instance, it always returns the hashref. If there are 0 instances, it returns undef, not an empty list. If there are more than 1 instance, it throws an exception because your assumption was incorrect. πŸ™ˆ

πŸ” TRACE FACET πŸ”

  • @list_of_facets = $event->trace β€” TODO
  • $undef_or_hashref = $event->the_trace β€” This returns the trace hashref, or undef if it's not present.
  • $undef_or_arrayref = $event->frame β€” If a trace is present, and has a caller frame, this will be an arrayref:
  • $event->trace β€” hands you back [$package, $file, $line, $subname]. If the trace isn't present, or it has no caller frame, you get undef. No caller, no trace, no problem. πŸ€·β€β™€οΈ
  • $undef_or_string = $event->trace_details β€” this is usually undef, but every so often it's a string that overrides the file/line number debugging that a trace normally gives you when a test fails. It's giving "actually, the real tea is over here" energy. πŸ’…
  • $undef_or_string = $event->trace_package β€” same as (caller())[0], aka the first element of the trace frame. Will be undef if it's not present. πŸ‘‘
  • $undef_or_string = $event->trace_file β€” same as (caller())[1], the second element of the trace frame. Will be undef if it's not present.
  • $undef_or_integer = $event->trace_line β€” same as (caller())[2], the third element of the trace frame. Will be undef if it's not present.
  • $undef_or_string = $event->trace_subname $undef_or_string = $event->trace_tool β€” these are aliases for the exact same thing. Same as (caller($level))[4], the fourth element of the trace frame. Will be undef if it's not present. fr fr.
  • $undef_or_string = $event->trace_signature β€” a string that's a unique signature for the trace. If a single context generates multiple events, they'll all have the same signature. You can use this to tie assertions and diagnostics sent as separate events back together after the fact. Matchy-matchy, iconic. πŸ”₯

✨ ASSERT FACET ✨

  • $bool = $event->has_assert β€” returns true if the event has an assert facet, false if it doesn't. Simple vibe check. βœ…
  • $undef_or_hashref = $event->the_assert β€” returns the assert facet if it's there, undef if it's not.
  • @list_of_facets = $event->assert β€” TODO (we'll get there, bestie, promise πŸ’–)
  • EMPTY_LIST_OR_STRING = $event->assert_brief β€” returns a string giving a brief of the assertion if an assertion is present. Returns an empty list if no assertion is present. It's either a whole summary or literally nothing. Periodt.

✨ SUBTESTS (PARENT FACET) ✨

  • $bool = $event->has_subtest β€” true if a subtest is present in this event.
  • $undef_or_hashref = $event->the_subtest β€” get the one subtest if it's present, otherwise undef.
  • @list_of_facets = $event->subtest β€” TODO (same energy, still pending πŸ™ˆ)
  • EMPTY_LIST_OR_OBJECT = $event->subtest_result β€” returns an empty list if there's no subtest. Otherwise, get an instance of Test2::API::InterceptResult representing the subtest. It's giving "here's your whole subtest wrapped up cute." πŸŽ€

✨ CONTROL FACET (BAILOUT, ENCODING) ✨

  • $bool = $event->has_bailout β€” true if there was a bailout. Bailout means we're OUT. πŸšͺπŸ’¨
  • $undef_hashref = $event->the_bailout β€” return the control facet if it requested a bailout.
  • EMPTY_LIST_OR_HASHREF = $event->bailout β€” get a list of 0 or 1 hashrefs. The hashref will be the control facet if a bail-out was requested.
  • EMPTY_LIST_OR_STRING = $event->bailout_brief β€” get the brief of the bailout if present.
  • EMPTY_LIST_OR_STRING = $event->bailout_reason β€” get the reason for the bailout, an empty string if no reason was provided, or an empty list if there was no bailout. No bailout, no reason, no list. That's the rule. πŸ€·β€β™€οΈ

✨ PLAN FACET ✨

TODO (bestie, this section is literally just a TODO. We're waiting on it. πŸ’€)

  • $bool = $event->has_plan
  • $undef_or_hashref = $event->the_plan
  • @list_if_hashrefs = $event->plan
  • EMPTY_LIST_OR_STRING $event->plan_brief

✨ AMNESTY FACET (TODO AND SKIP) ✨

TODO (again, just a TODO. It's giving "coming soon" energy. πŸ¦‹)

  • $event->has_amnesty
  • $event->the_amnesty
  • $event->amnesty
  • $event->amnesty_reasons
  • $event->has_todos
  • $event->todos
  • $event->todo_reasons
  • $event->has_skips
  • $event->skips
  • $event->skip_reasons
  • $event->has_other_amnesty
  • $event->other_amnesty
  • $event->other_amnesty_reasons

✨ ERROR FACET (CAPTURED EXCEPTIONS) ✨

TODO (yes, another TODO. We love a placeholder. 🫢)

  • $event->has_errors
  • $event->the_errors
  • $event->errors
  • $event->error_messages
  • $event->error_brief

✨ INFO FACET (DIAG, NOTE) ✨

TODO (the final TODO of the page, and honestly? Iconic. ✨)

  • $event->has_info
  • $event->the_info
  • $event->info
  • $event->info_messages
  • $event->has_diags
  • $event->diags
  • $event->diag_messages
  • $event->has_notes
  • $event->notes
  • $event->note_messages
  • $event->has_other_info
  • $event->other_info
  • $event->other_info_messages

🌈 SOURCE 🌈

The source code repository for Test2 can be found at <https://github.com/Test-More/test-more/>. Go star it, bestie. ⭐

πŸ‘‘ 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/>


And that's the whole page, bestie. This was Test2::...::Event(3perl) from Perl v5.44.0, dated 2026-10-17. You read the whole thing. You're literally the main character. 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