.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.ie \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. nr % 0
. rr F
.\}
.el \{\
. de IX
..
.\}
.\" ========================================================================
.\"
.IX Title "Test2::Manual::Anatomy::Event 3"
.TH Test2::Manual::Anatomy::Event 3 "2019-05-18" "perl v5.10.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
Test2::Manual::Anatomy::Event \- The internals of events
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
Events are how tools effect global state, and pass information along to the
harness, or the human running the tests.
.SH "HISTORY"
.IX Header "HISTORY"
Before proceeding it is important that you know some history of events.
Initially there was an event \s-1API\s0, and an event would implement the \s-1API\s0 to
produce an effect. This \s-1API\s0 proved to be lossy and inflexible. Recently the
\&'facet' system was introduced, and makes up for the shortcoming and
inflexibility of the old \s-1API\s0.
.PP
All events must still implement the old \s-1API\s0, 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 \s-1API\s0, though their information
maybe less complete.
.SH "THE EVENT OBJECT"
.IX Header "THE EVENT OBJECT"
All event objects must subclass Test2::Event. If you inherit from this base
class, and implement the old \s-1API\s0 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 \s-1API\s0 from them.
.PP
All new events \f(CW\*(C`MUST\*(C'\fR implement both APIs one way or the other. A common way
to do this is to simply implement both APIs directly in your event.
.PP
Here is a good template for a new event:
.PP
.Vb 3
\& package Test2::Event::Mine;
\& use strict;
\& use warnings;
\&
\& use parent \*(AqTest2::Event\*(Aq;
\& use Test2::Util::Facets2Legacy \*(Aq:ALL\*(Aq;
\&
\& sub facet_data {
\& my $self = shift;
\&
\& # Adds \*(Aqabout\*(Aq, \*(Aqamnesty\*(Aq, and \*(Aqtrace\*(Aq facets
\& my $out = $self\->common_facet_data;
\&
\& # Add any additional facets to the $out hashref
\& ...
\&
\& return $out;
\& }
\&
\& 1;
.Ve
.SH "THE FACET API"
.IX Header "THE FACET API"
The new \s-1API\s0 is a single method: \f(CW\*(C`facet_data()\*(C'\fR. 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 \f(CW\*(C`MUST\*(C'\fR be lone hashrefs,
others \f(CW\*(C`MUST\*(C'\fR be hashrefs inside an arrayref.
.PP
The \fIstandard\fR facet types are as follows:
.ie n .IP "assert => {details => $name, pass => $bool, no_debug => $bool, number => $maybe_int}" 4
.el .IP "assert => {details => \f(CW$name\fR, pass => \f(CW$bool\fR, no_debug => \f(CW$bool\fR, number => \f(CW$maybe_int\fR}" 4
.IX Item "assert => {details => $name, pass => $bool, no_debug => $bool, number => $maybe_int}"
Documented in Test2::EventFacet::Assert. An event may only have one.
.Sp
The 'details' key is the name of the assertion.
.Sp
The 'pass' key denotes a passing or failing assertion.
.Sp
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).
.Sp
The 'number' key is for harness use, never set it yourself.
.ie n .IP "about => {details => $string, no_display => $bool, package => $pkg}" 4
.el .IP "about => {details => \f(CW$string\fR, no_display => \f(CW$bool\fR, package => \f(CW$pkg\fR}" 4
.IX Item "about => {details => $string, no_display => $bool, package => $pkg}"
Documented in Test2::EventFacet::About. An event may only have one.
.Sp
\&'details' is a human readable string describing the overall event.
.Sp
\&'no_display' means that a formatter/harness should hide the event.
.Sp
\&'package' is the package of the event the facet describes (\s-1IE:\s0 Test2::Event::Ok)
.ie n .IP "amnesty => [{details => $string, tag => $short_string, inherited => $bool}]" 4
.el .IP "amnesty => [{details => \f(CW$string\fR, tag => \f(CW$short_string\fR, inherited => \f(CW$bool\fR}]" 4
.IX Item "amnesty => [{details => $string, tag => $short_string, inherited => $bool}]"
Documented in Test2::EventFacet::Amnesty. An event may have multiple.
.Sp
This event is how things like 'todo' are implemented. Amnesty prevents a
failing assertion from causing a global test failure.
.Sp
\&'details' is a human readable description of why the failure is being granted
amnesty (\s-1IE\s0 The 'todo' reason)
.Sp
\&'tag' is a short human readable string, or category for the amnesty. This is
typically '\s-1TODO\s0' or '\s-1SKIP\s0'.
.Sp
\&'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).
.ie n .IP "control => {details => $string, global => $bool, terminate => $maybe_int, halt => $bool, has_callback => $bool, encoding => $enc}" 4
.el .IP "control => {details => \f(CW$string\fR, global => \f(CW$bool\fR, terminate => \f(CW$maybe_int\fR, halt => \f(CW$bool\fR, has_callback => \f(CW$bool\fR, encoding => \f(CW$enc\fR}" 4
.IX Item "control => {details => $string, global => $bool, terminate => $maybe_int, halt => $bool, has_callback => $bool, encoding => $enc}"
Documented in Test2::EventFacet::Control. An event may have one.
.Sp
This facet is used to apply extra behavior when the event is processed.
.Sp
\&'details' is a human readable explanation for the behavior.
.Sp
\&'global' true if this event should be forwarded to, and processed by, all hubs
everywhere. (bail-out uses this)
.Sp
\&'terminate' this should either be undef, or an integer. When defined this will
cause the test to exit with the specific exit code.
.Sp
\&'halt' is used to signal any harness that no further test files should be run
(bail-out uses this).
.Sp
\&'has_callback' is set to true if the event has a callback sub defined.
.Sp
\&'encoding' used to tell the formatter what encoding to use.
.ie n .IP "errors => [{details => $string, tag => $short_string, fail => $bool}]" 4
.el .IP "errors => [{details => \f(CW$string\fR, tag => \f(CW$short_string\fR, fail => \f(CW$bool\fR}]" 4
.IX Item "errors => [{details => $string, tag => $short_string, fail => $bool}]"
Documented in Test2::EventFacet::Error. An event may have multiple.
.Sp
\&'details' is a human readable explanation of the error.
.Sp
\&'tag' is a short human readable category for the error.
.Sp
\&'fail' is true if the error should cause test failure. If this is false the
error is simply informative, but not fatal.
.ie n .IP "info => [{details => $string, tag => $short_string, debug => $bool, important => $bool}]" 4
.el .IP "info => [{details => \f(CW$string\fR, tag => \f(CW$short_string\fR, debug => \f(CW$bool\fR, important => \f(CW$bool\fR}]" 4
.IX Item "info => [{details => $string, tag => $short_string, debug => $bool, important => $bool}]"
Documented in Test2::EventFacet::Info. An event may have multiple.
.Sp
This is how diag and note are implemented.
.Sp
\&'details' human readable message.
.Sp
\&'tag' short category for the message, such as 'diag' or 'note'.
.Sp
\&'debug' is true if the message is diagnostics in nature, this is the main
difference between a note and a diag.
.Sp
\&'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.
.ie n .IP "parent => {details => $string, hid => $hid, children => [...], buffered => 1}" 4
.el .IP "parent => {details => \f(CW$string\fR, hid => \f(CW$hid\fR, children => [...], buffered => 1}" 4
.IX Item "parent => {details => $string, hid => $hid, children => [...], buffered => 1}"
Documented in Test2::EventFacet::Parent. An event may have one.
.Sp
This is used by subtests.
.Sp
\&'details' human readable name of the subtest.
.Sp
\&'hid' subtest hub id.
.Sp
\&'children' an arrayref containing facet_data instances from all child events.
.Sp
\&'buffered' true if it was a buffered subtest.
.ie n .IP "plan => {details => $string, count => $int, skip => $bool, none => $bool}" 4
.el .IP "plan => {details => \f(CW$string\fR, count => \f(CW$int\fR, skip => \f(CW$bool\fR, none => \f(CW$bool\fR}" 4
.IX Item "plan => {details => $string, count => $int, skip => $bool, none => $bool}"
Documented in Test2::EventFacet::Plan. An event may have one.
.Sp
\&'details' is a human readable string describing the plan (for instance, why a
test is skipped)
.Sp
\&'count' is the number of expected assertions (0 for skip)
.Sp
\&'skip' is true if the plan is to skip the test.
.Sp
\&'none' used for Test::More's 'no_plan' plan.
.ie n .IP "trace => {details => $string, frame => [$pkg, $file, $line, $sub], pid => $int, tid => $int, cid => $cid, hid => $hid, nested => $int, buffered => $bool}" 4
.el .IP "trace => {details => \f(CW$string\fR, frame => [$pkg, \f(CW$file\fR, \f(CW$line\fR, \f(CW$sub\fR], pid => \f(CW$int\fR, tid => \f(CW$int\fR, cid => \f(CW$cid\fR, hid => \f(CW$hid\fR, nested => \f(CW$int\fR, buffered => \f(CW$bool\fR}" 4
.IX Item "trace => {details => $string, frame => [$pkg, $file, $line, $sub], pid => $int, tid => $int, cid => $cid, hid => $hid, nested => $int, buffered => $bool}"
Documented in Test2::EventFacet::Trace. An event may have one.
.Sp
This is how debugging information is tracked. This is taken from the context
object at event creation.
.Sp
\&'details' human readable debug message (otherwise generated from frame)
.Sp
\&'frame' first 4 fields returned by caller:
\&\f(CW\*(C`[$package, $file, $line, $subname]\*(C'\fR.
.Sp
\&'pid' the process id in which the event was created.
.Sp
\&'tid' the thread is in which the event was created.
.Sp
\&'cid' the id of the context used to create the event.
.Sp
\&'hid' the id of the hub to which the event was sent.
.Sp
\&'nest' subtest nesting depth of the event.
.Sp
\&'buffered' is true if the event was generated inside a buffered subtest.
.PP
Note that \s-1ALL\s0 facet types have a 'details' key that may have a string. This
string should always be human readable, and should be an explanation for the
facet. For an assertion this is the test name. For a plan this is the reason
for the plan (such as skip reason). For info it is the human readable
diagnostics message.
.SS "\s-1CUSTOM\s0 \s-1FACETS\s0"
.IX Subsection "CUSTOM FACETS"
You can write custom facet types as well, simply add a new key to the hash and
populated it. The general rule is that any code looking at the facets should
ignore any it does not understand.
.PP
Optionally you can also create a package to document your custom facet. The
package should be proper object, and may have additional methods to help work
with your facet.
.PP
.Vb 1
\& package Test2::EventFacet::MyFacet;
\&
\& use parent \*(AqTest2::EventFacet\*(Aq;
\&
\& sub facet_key { \*(Aqmyfacet\*(Aq }
\& sub is_list { 0 }
\&
\& 1;
.Ve
.PP
Your facet package should always be under the Test2::EventFacet:: namespace if
you want any tools to automatically find it. The last part of the namespace
should be the non-plural name of your facet with only the first word
capitalized.
.ie n .IP "$string = $facet_class\->facet_key" 4
.el .IP "\f(CW$string\fR = \f(CW$facet_class\fR\->facet_key" 4
.IX Item "$string = $facet_class->facet_key"
The key for your facet should be the same as the last section of
the namespace, but all lowercase. You \fImay\fR append 's' to the key if your
facet is a list type.
.ie n .IP "$bool = $facet_class\->is_list" 4
.el .IP "\f(CW$bool\fR = \f(CW$facet_class\fR\->is_list" 4
.IX Item "$bool = $facet_class->is_list"
True if an event should put these facets in a list:
.Sp
.Vb 1
\& { myfacet => [{}, {}] }
.Ve
.Sp
False if an event may only have one of this type of facet at a time:
.Sp
.Vb 1
\& { myfacet => {} }
.Ve
.PP
\fI\s-1EXAMPLES\s0\fR
.IX Subsection "EXAMPLES"
.PP
The assert facet is not a list type, so its implementation would look like this:
.PP
.Vb 3
\& package Test2::EventFacet::Assert;
\& sub facet_key { \*(Aqassert\*(Aq }
\& sub is_list { 0 }
.Ve
.PP
The amnesty facet is a list type, but amnesty does not need 's' appended to
make it plural:
.PP
.Vb 3
\& package Test2::EventFacet::Amnesty;
\& sub facet_key { \*(Aqamnesty\*(Aq }
\& sub is_list { 1 }
.Ve
.PP
The error facet is a list type, and appending 's' makes error plural as errors.
This means the package name is '::Error', but the key is 'errors'.
.PP
.Vb 3
\& package Test2::EventFacet::Error;
\& sub facet_key { \*(Aqerrors\*(Aq }
\& sub is_list { 1 }
.Ve
.PP
\&\fBNote\fR Do not worry too much about getting the key/pluralization wrong. Most
tools will use Module::Pluggable to load all facet types and build a hash
linking keys to packages and so on, working backwards. This means, in general,
that even if you get it wrong any tool that \s-1NEEDS\s0 the package for the facet
will find it.
.PP
\&\fBNote2:\fR In practice most tools completely ignore the facet packages, and work
with the facet data directly in its raw structure. This is by design and
recommended. The facet data is intended to be serialized frequently and passed
around. When facets are concerned, data is important, classes and methods are
not.
.SH "THE OLD API"
.IX Header "THE OLD API"
The old \s-1API\s0 was simply a set of methods you were required to implement:
.ie n .IP "$bool = $e\->causes_fail" 4
.el .IP "\f(CW$bool\fR = \f(CW$e\fR\->causes_fail" 4
.IX Item "$bool = $e->causes_fail"
Returns true if this event should result in a test failure. In general this
should be false.
.ie n .IP "$bool = $e\->increments_count" 4
.el .IP "\f(CW$bool\fR = \f(CW$e\fR\->increments_count" 4
.IX Item "$bool = $e->increments_count"
Should be true if this event should result in a test count increment.
.ie n .IP "$e\->callback($hub)" 4
.el .IP "\f(CW$e\fR\->callback($hub)" 4
.IX Item "$e->callback($hub)"
If your event needs to have extra effects on the Test2::Hub you can override
this method.
.Sp
This is called \fB\s-1BEFORE\s0\fR your event is passed to the formatter.
.ie n .IP "$num = $e\->nested" 4
.el .IP "\f(CW$num\fR = \f(CW$e\fR\->nested" 4
.IX Item "$num = $e->nested"
If this event is nested inside of other events, this should be the depth of
nesting. (This is mainly for subtests)
.ie n .IP "$bool = $e\->global" 4
.el .IP "\f(CW$bool\fR = \f(CW$e\fR\->global" 4
.IX Item "$bool = $e->global"
Set this to true if your event is global, that is \s-1ALL\s0 threads and processes
should see it no matter when or where it is generated. This is not a common
thing to want, it is used by bail-out and skip_all to end testing.
.ie n .IP "$code = $e\->terminate" 4
.el .IP "\f(CW$code\fR = \f(CW$e\fR\->terminate" 4
.IX Item "$code = $e->terminate"
This is called \fB\s-1AFTER\s0\fR your event has been passed to the formatter. This
should normally return undef, only change this if your event should cause the
test to exit immediately.
.Sp
If you want this event to cause the test to exit you should return the exit
code here. Exit code of 0 means exit success, any other integer means exit with
failure.
.Sp
This is used by Test2::Event::Plan to exit 0 when the plan is
\&'skip_all'. This is also used by Test2::Event:Bail to force the test
to exit with a failure.
.Sp
This is called after the event has been sent to the formatter in order to
ensure the event is seen and understood.
.ie n .IP "$msg = $e\->summary" 4
.el .IP "\f(CW$msg\fR = \f(CW$e\fR\->summary" 4
.IX Item "$msg = $e->summary"
This is intended to be a human readable summary of the event. This should
ideally only be one line long, but you can use multiple lines if necessary. This
is intended for human consumption. You do not need to make it easy for machines
to understand.
.Sp
The default is to simply return the event package name.
.ie n .IP "($count, $directive, $reason) = $e\->\fIsets_plan()\fR" 4
.el .IP "($count, \f(CW$directive\fR, \f(CW$reason\fR) = \f(CW$e\fR\->\fIsets_plan()\fR" 4
.IX Item "($count, $directive, $reason) = $e->sets_plan()"
Check if this event sets the testing plan. It will return an empty list if it
does not. If it does set the plan it will return a list of 1 to 3 items in
order: Expected Test Count, Test Directive, Reason for directive.
.ie n .IP "$bool = $e\->diagnostics" 4
.el .IP "\f(CW$bool\fR = \f(CW$e\fR\->diagnostics" 4
.IX Item "$bool = $e->diagnostics"
True if the event contains diagnostics info. This is useful because a
non-verbose harness may choose to hide events that are not in this category.
Some formatters may choose to send these to \s-1STDERR\s0 instead of \s-1STDOUT\s0 to ensure
they are seen.
.ie n .IP "$bool = $e\->no_display" 4
.el .IP "\f(CW$bool\fR = \f(CW$e\fR\->no_display" 4
.IX Item "$bool = $e->no_display"
False by default. This will return true on events that should not be displayed
by formatters.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
Test2::Manual \- Primary index of the manual.
.SH "SOURCE"
.IX Header "SOURCE"
The source code repository for Test2\-Manual can be found at
\&\fIhttps://github.com/Test\-More/Test2\-Suite/\fR.
.SH "MAINTAINERS"
.IX Header "MAINTAINERS"
.IP "Chad Granum <exodist@cpan.org>" 4
.IX Item "Chad Granum <exodist@cpan.org>"
.SH "AUTHORS"
.IX Header "AUTHORS"
.PD 0
.IP "Chad Granum <exodist@cpan.org>" 4
.IX Item "Chad Granum <exodist@cpan.org>"
.PD
.SH "COPYRIGHT"
.IX Header "COPYRIGHT"
Copyright 2018 Chad Granum <exodist@cpan.org>.
.PP
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
.PP
See \fIhttp://dev.perl.org/licenses/\fR
Copyright 2K16 - 2K18 Indonesian Hacker Rulez