Test2::Manual::Anatomy::Event - The internals of events
Events are how tools effect global state, and pass information along to the harness, or the human running the tests.
Before proceeding it is important that you know some history of events. Initially there was an event API, and an event would implement the API to produce an effect. This API proved to be lossy and inflexible. Recently the 'facet' system was introduced, and makes up for the shortcoming and inflexibility of the old API.
All events must still implement the old API, but that can be largely automated if you use the facet system effectively. Likewise essential facets can often be deduced from events that only implement the old API, though their information maybe less complete.
All event objects must subclass Test2::Event. If you inherit from this base class, and implement the old API properly, facets will be generated for you for free. On the other hand you can inherit from this, and also import Test2::Util::Facets2Legacy which will instead rely on your facet data, and deduce the old API from them.
All new events MUST
implement both APIs one way or the other. A common way to do this is to simply implement both APIs directly in your event.
Here is a good template for a new event:
package Test2::Event::Mine;
use strict;
use warnings;
use parent 'Test2::Event';
use Test2::Util::Facets2Legacy ':ALL';
sub facet_data {
my $self = shift;
# Adds 'about', 'amnesty', and 'trace' facets
my $out = $self->common_facet_data;
# Add any additional facets to the $out hashref
...
return $out;
}
1;
The new API is a single method: facet_data()
. This method must return a hashref where each key is specific to a facet type, and the value is either a facet hashref, or an array of hashrefs. Some facets MUST
be lone hashrefs, others MUST
be hashrefs inside an arrayref.
The standard facet types are as follows:
Documented in Test2::EventFacet::Assert. An event may only have one.
The 'details' key is the name of the assertion.
The 'pass' key denotes a passing or failing assertion.
The 'no_debug' key tells any harness or formatter that diagnostics should not be added automatically to a failing assertion (used when there are custom diagnostics instead).
The 'number' key is for harness use, never set it yourself.
Documented in Test2::EventFacet::About. An event may only have one.
'details' is a human readable string describing the overall event.
'no_display' means that a formatter/harness should hide the event.
'package' is the package of the event the facet describes (IE: Test2::Event::Ok)
Documented in Test2::EventFacet::Amnesty. An event may have multiple.
This event is how things like 'todo' are implemented. Amnesty prevents a failing assertion from causing a global test failure.
'details' is a human readable description of why the failure is being granted amnesty (IE The 'todo' reason)
'tag' is a short human readable string, or category for the amnesty. This is typically 'TODO' or 'SKIP'.
'inherited' is true if the amnesty was applied in a parent context (true if this test is run in a subtest that is marked todo).
Documented in Test2::EventFacet::Control. An event may have one.
This facet is used to apply extra behavior when the event is processed.
'details' is a human readable explanation for the behavior.
'global' true if this event should be forwarded to, and processed by, all hubs everywhere. (bail-out uses this)
'terminate' this should either be undef, or an integer. When defined this will cause the test to exit with the specific exit code.
'halt' is used to signal any harness that no further test files should be run (bail-out uses this).
'has_callback' is set to true if the event has a callback sub defined.
'encoding' used to tell the formatter what encoding to use.
Documented in Test2::EventFacet::Error. An event may have multiple.
'details' is a human readable explanation of the error.
'tag' is a short human readable category for the error.
'fail' is true if the error should cause test failure. If this is false the error is simply informative, but not fatal.
Documented in Test2::EventFacet::Info. An event may have multiple.
This is how diag and note are implemented.
'details' human readable message.
'tag' short category for the message, such as 'diag' or 'note'.
'debug' is true if the message is diagnostics in nature, this is the main difference between a note and a diag.
'important' is true if the message is not diagnostics, but is important to have it shown anyway. This is primarily used to communicate with a harness.
Documented in Test2::EventFacet::Parent. An event may have one.
This is used by subtests.
'details' human readable name of the subtest.
'hid' subtest hub id.
'children' an arrayref containing facet_data instances from all child events.
'buffered' true if it was a buffered subtest.
Documented in Test2::EventFacet::Plan. An event may have one.
'details' is a human readable string describing the plan (for instance, why a test is skipped)
'count' is the number of expected assertions (0 for skip)
'skip' is true if the plan is to skip the test.
'none' used for Test::More's 'no_plan' plan.
Documented in