15759b3d2Safresh1package Test2::Event; 25759b3d2Safresh1use strict; 35759b3d2Safresh1use warnings; 45759b3d2Safresh1 5*5486feefSafresh1our $VERSION = '1.302199'; 65759b3d2Safresh1 75759b3d2Safresh1use Scalar::Util qw/blessed reftype/; 85759b3d2Safresh1use Carp qw/croak/; 95759b3d2Safresh1 10f3efcd01Safresh1use Test2::Util::HashBase qw/trace -amnesty uuid -_eid -hubs/; 115759b3d2Safresh1use Test2::Util::ExternalMeta qw/meta get_meta set_meta delete_meta/; 12f3efcd01Safresh1use Test2::Util qw/pkg_to_file gen_uid/; 135759b3d2Safresh1 145759b3d2Safresh1use Test2::EventFacet::About(); 155759b3d2Safresh1use Test2::EventFacet::Amnesty(); 165759b3d2Safresh1use Test2::EventFacet::Assert(); 175759b3d2Safresh1use Test2::EventFacet::Control(); 185759b3d2Safresh1use Test2::EventFacet::Error(); 195759b3d2Safresh1use Test2::EventFacet::Info(); 205759b3d2Safresh1use Test2::EventFacet::Meta(); 215759b3d2Safresh1use Test2::EventFacet::Parent(); 225759b3d2Safresh1use Test2::EventFacet::Plan(); 235759b3d2Safresh1use Test2::EventFacet::Trace(); 245759b3d2Safresh1use Test2::EventFacet::Hub(); 255759b3d2Safresh1 265759b3d2Safresh1# Legacy tools will expect this to be loaded now 275759b3d2Safresh1require Test2::Util::Trace; 285759b3d2Safresh1 295759b3d2Safresh1my %LOADED_FACETS = ( 305759b3d2Safresh1 'about' => 'Test2::EventFacet::About', 315759b3d2Safresh1 'amnesty' => 'Test2::EventFacet::Amnesty', 325759b3d2Safresh1 'assert' => 'Test2::EventFacet::Assert', 335759b3d2Safresh1 'control' => 'Test2::EventFacet::Control', 345759b3d2Safresh1 'errors' => 'Test2::EventFacet::Error', 355759b3d2Safresh1 'info' => 'Test2::EventFacet::Info', 365759b3d2Safresh1 'meta' => 'Test2::EventFacet::Meta', 375759b3d2Safresh1 'parent' => 'Test2::EventFacet::Parent', 385759b3d2Safresh1 'plan' => 'Test2::EventFacet::Plan', 395759b3d2Safresh1 'trace' => 'Test2::EventFacet::Trace', 405759b3d2Safresh1 'hubs' => 'Test2::EventFacet::Hub', 415759b3d2Safresh1); 425759b3d2Safresh1 435759b3d2Safresh1sub FACET_TYPES { sort values %LOADED_FACETS } 445759b3d2Safresh1 455759b3d2Safresh1sub load_facet { 465759b3d2Safresh1 my $class = shift; 475759b3d2Safresh1 my ($facet) = @_; 485759b3d2Safresh1 495759b3d2Safresh1 return $LOADED_FACETS{$facet} if exists $LOADED_FACETS{$facet}; 505759b3d2Safresh1 515759b3d2Safresh1 my @check = ($facet); 525759b3d2Safresh1 if ('s' eq substr($facet, -1, 1)) { 535759b3d2Safresh1 push @check => substr($facet, 0, -1); 545759b3d2Safresh1 } 555759b3d2Safresh1 else { 565759b3d2Safresh1 push @check => $facet . 's'; 575759b3d2Safresh1 } 585759b3d2Safresh1 595759b3d2Safresh1 my $found; 605759b3d2Safresh1 for my $check (@check) { 615759b3d2Safresh1 my $mod = "Test2::EventFacet::" . ucfirst($facet); 625759b3d2Safresh1 my $file = pkg_to_file($mod); 635759b3d2Safresh1 next unless eval { require $file; 1 }; 645759b3d2Safresh1 $found = $mod; 655759b3d2Safresh1 last; 665759b3d2Safresh1 } 675759b3d2Safresh1 685759b3d2Safresh1 return undef unless $found; 695759b3d2Safresh1 $LOADED_FACETS{$facet} = $found; 705759b3d2Safresh1} 715759b3d2Safresh1 725759b3d2Safresh1sub causes_fail { 0 } 735759b3d2Safresh1sub increments_count { 0 } 745759b3d2Safresh1sub diagnostics { 0 } 755759b3d2Safresh1sub no_display { 0 } 765759b3d2Safresh1sub subtest_id { undef } 775759b3d2Safresh1 785759b3d2Safresh1sub callback { } 795759b3d2Safresh1 805759b3d2Safresh1sub terminate { () } 815759b3d2Safresh1sub global { () } 825759b3d2Safresh1sub sets_plan { () } 835759b3d2Safresh1 845759b3d2Safresh1sub summary { ref($_[0]) } 855759b3d2Safresh1 865759b3d2Safresh1sub related { 875759b3d2Safresh1 my $self = shift; 885759b3d2Safresh1 my ($event) = @_; 895759b3d2Safresh1 905759b3d2Safresh1 my $tracea = $self->trace or return undef; 915759b3d2Safresh1 my $traceb = $event->trace or return undef; 925759b3d2Safresh1 935759b3d2Safresh1 my $uuida = $tracea->uuid; 945759b3d2Safresh1 my $uuidb = $traceb->uuid; 955759b3d2Safresh1 if ($uuida && $uuidb) { 965759b3d2Safresh1 return 1 if $uuida eq $uuidb; 975759b3d2Safresh1 return 0; 985759b3d2Safresh1 } 995759b3d2Safresh1 1005759b3d2Safresh1 my $siga = $tracea->signature or return undef; 1015759b3d2Safresh1 my $sigb = $traceb->signature or return undef; 1025759b3d2Safresh1 1035759b3d2Safresh1 return 1 if $siga eq $sigb; 1045759b3d2Safresh1 return 0; 1055759b3d2Safresh1} 1065759b3d2Safresh1 1075759b3d2Safresh1sub add_hub { 1085759b3d2Safresh1 my $self = shift; 1095759b3d2Safresh1 unshift @{$self->{+HUBS}} => @_; 1105759b3d2Safresh1} 1115759b3d2Safresh1 1125759b3d2Safresh1sub add_amnesty { 1135759b3d2Safresh1 my $self = shift; 1145759b3d2Safresh1 1155759b3d2Safresh1 for my $am (@_) { 1165759b3d2Safresh1 $am = {%$am} if ref($am) ne 'ARRAY'; 1175759b3d2Safresh1 $am = Test2::EventFacet::Amnesty->new($am); 1185759b3d2Safresh1 1195759b3d2Safresh1 push @{$self->{+AMNESTY}} => $am; 1205759b3d2Safresh1 } 1215759b3d2Safresh1} 1225759b3d2Safresh1 123f3efcd01Safresh1sub eid { $_[0]->{+_EID} ||= gen_uid() } 124f3efcd01Safresh1 1255759b3d2Safresh1sub common_facet_data { 1265759b3d2Safresh1 my $self = shift; 1275759b3d2Safresh1 1285759b3d2Safresh1 my %out; 1295759b3d2Safresh1 1305759b3d2Safresh1 $out{about} = {package => ref($self) || undef}; 1315759b3d2Safresh1 if (my $uuid = $self->uuid) { 1325759b3d2Safresh1 $out{about}->{uuid} = $uuid; 1335759b3d2Safresh1 } 1345759b3d2Safresh1 135f3efcd01Safresh1 $out{about}->{eid} = $self->{+_EID} || $self->eid; 136f3efcd01Safresh1 1375759b3d2Safresh1 if (my $trace = $self->trace) { 1385759b3d2Safresh1 $out{trace} = { %$trace }; 1395759b3d2Safresh1 } 1405759b3d2Safresh1 1415759b3d2Safresh1 if (my $hubs = $self->hubs) { 1425759b3d2Safresh1 $out{hubs} = $hubs; 1435759b3d2Safresh1 } 1445759b3d2Safresh1 1455759b3d2Safresh1 $out{amnesty} = [map {{ %{$_} }} @{$self->{+AMNESTY}}] 1465759b3d2Safresh1 if $self->{+AMNESTY}; 1475759b3d2Safresh1 1485759b3d2Safresh1 if (my $meta = $self->meta_facet_data) { 1495759b3d2Safresh1 $out{meta} = $meta; 1505759b3d2Safresh1 } 1515759b3d2Safresh1 1525759b3d2Safresh1 return \%out; 1535759b3d2Safresh1} 1545759b3d2Safresh1 1555759b3d2Safresh1sub meta_facet_data { 1565759b3d2Safresh1 my $self = shift; 1575759b3d2Safresh1 1585759b3d2Safresh1 my $key = Test2::Util::ExternalMeta::META_KEY(); 1595759b3d2Safresh1 1605759b3d2Safresh1 my $hash = $self->{$key} or return undef; 1615759b3d2Safresh1 return {%$hash}; 1625759b3d2Safresh1} 1635759b3d2Safresh1 1645759b3d2Safresh1sub facet_data { 1655759b3d2Safresh1 my $self = shift; 1665759b3d2Safresh1 1675759b3d2Safresh1 my $out = $self->common_facet_data; 1685759b3d2Safresh1 1695759b3d2Safresh1 $out->{about}->{details} = $self->summary || undef; 1705759b3d2Safresh1 $out->{about}->{no_display} = $self->no_display || undef; 1715759b3d2Safresh1 1725759b3d2Safresh1 # Might be undef, we want to preserve that 1735759b3d2Safresh1 my $terminate = $self->terminate; 1745759b3d2Safresh1 $out->{control} = { 1755759b3d2Safresh1 global => $self->global || 0, 1765759b3d2Safresh1 terminate => $terminate, 1775759b3d2Safresh1 has_callback => $self->can('callback') == \&callback ? 0 : 1, 1785759b3d2Safresh1 }; 1795759b3d2Safresh1 1805759b3d2Safresh1 $out->{assert} = { 1815759b3d2Safresh1 no_debug => 1, # Legacy behavior 1825759b3d2Safresh1 pass => $self->causes_fail ? 0 : 1, 1835759b3d2Safresh1 details => $self->summary, 1845759b3d2Safresh1 } if $self->increments_count; 1855759b3d2Safresh1 1865759b3d2Safresh1 $out->{parent} = {hid => $self->subtest_id} if $self->subtest_id; 1875759b3d2Safresh1 1885759b3d2Safresh1 if (my @plan = $self->sets_plan) { 1895759b3d2Safresh1 $out->{plan} = {}; 1905759b3d2Safresh1 1915759b3d2Safresh1 $out->{plan}->{count} = $plan[0] if defined $plan[0]; 1925759b3d2Safresh1 $out->{plan}->{details} = $plan[2] if defined $plan[2]; 1935759b3d2Safresh1 1945759b3d2Safresh1 if ($plan[1]) { 1955759b3d2Safresh1 $out->{plan}->{skip} = 1 if $plan[1] eq 'SKIP'; 1965759b3d2Safresh1 $out->{plan}->{none} = 1 if $plan[1] eq 'NO PLAN'; 1975759b3d2Safresh1 } 1985759b3d2Safresh1 1995759b3d2Safresh1 $out->{control}->{terminate} ||= 0 if $out->{plan}->{skip}; 2005759b3d2Safresh1 } 2015759b3d2Safresh1 2025759b3d2Safresh1 if ($self->causes_fail && !$out->{assert}) { 2035759b3d2Safresh1 $out->{errors} = [ 2045759b3d2Safresh1 { 2055759b3d2Safresh1 tag => 'FAIL', 2065759b3d2Safresh1 fail => 1, 2075759b3d2Safresh1 details => $self->summary, 2085759b3d2Safresh1 } 2095759b3d2Safresh1 ]; 2105759b3d2Safresh1 } 2115759b3d2Safresh1 2125759b3d2Safresh1 my %IGNORE = (trace => 1, about => 1, control => 1); 2135759b3d2Safresh1 my $do_info = !grep { !$IGNORE{$_} } keys %$out; 2145759b3d2Safresh1 2155759b3d2Safresh1 if ($do_info && !$self->no_display && $self->diagnostics) { 2165759b3d2Safresh1 $out->{info} = [ 2175759b3d2Safresh1 { 2185759b3d2Safresh1 tag => 'DIAG', 2195759b3d2Safresh1 debug => 1, 2205759b3d2Safresh1 details => $self->summary, 2215759b3d2Safresh1 } 2225759b3d2Safresh1 ]; 2235759b3d2Safresh1 } 2245759b3d2Safresh1 2255759b3d2Safresh1 return $out; 2265759b3d2Safresh1} 2275759b3d2Safresh1 2285759b3d2Safresh1sub facets { 2295759b3d2Safresh1 my $self = shift; 2305759b3d2Safresh1 my %out; 2315759b3d2Safresh1 2325759b3d2Safresh1 my $data = $self->facet_data; 2335759b3d2Safresh1 my @errors = $self->validate_facet_data($data); 2345759b3d2Safresh1 die join "\n" => @errors if @errors; 2355759b3d2Safresh1 2365759b3d2Safresh1 for my $facet (keys %$data) { 2375759b3d2Safresh1 my $class = $self->load_facet($facet); 2385759b3d2Safresh1 my $val = $data->{$facet}; 2395759b3d2Safresh1 2405759b3d2Safresh1 unless($class) { 2415759b3d2Safresh1 $out{$facet} = $val; 2425759b3d2Safresh1 next; 2435759b3d2Safresh1 } 2445759b3d2Safresh1 2455759b3d2Safresh1 my $is_list = reftype($val) eq 'ARRAY' ? 1 : 0; 2465759b3d2Safresh1 if ($is_list) { 2475759b3d2Safresh1 $out{$facet} = [map { $class->new($_) } @$val]; 2485759b3d2Safresh1 } 2495759b3d2Safresh1 else { 2505759b3d2Safresh1 $out{$facet} = $class->new($val); 2515759b3d2Safresh1 } 2525759b3d2Safresh1 } 2535759b3d2Safresh1 2545759b3d2Safresh1 return \%out; 2555759b3d2Safresh1} 2565759b3d2Safresh1 2575759b3d2Safresh1sub validate_facet_data { 2585759b3d2Safresh1 my $class_or_self = shift; 2595759b3d2Safresh1 my ($f, %params); 2605759b3d2Safresh1 2615759b3d2Safresh1 $f = shift if @_ && (reftype($_[0]) || '') eq 'HASH'; 2625759b3d2Safresh1 %params = @_; 2635759b3d2Safresh1 2645759b3d2Safresh1 $f ||= $class_or_self->facet_data if blessed($class_or_self); 2655759b3d2Safresh1 croak "No facet data" unless $f; 2665759b3d2Safresh1 2675759b3d2Safresh1 my @errors; 2685759b3d2Safresh1 2695759b3d2Safresh1 for my $k (sort keys %$f) { 2705759b3d2Safresh1 my $fclass = $class_or_self->load_facet($k); 2715759b3d2Safresh1 2725759b3d2Safresh1 push @errors => "Could not find a facet class for facet '$k'" 2735759b3d2Safresh1 if $params{require_facet_class} && !$fclass; 2745759b3d2Safresh1 2755759b3d2Safresh1 next unless $fclass; 2765759b3d2Safresh1 2775759b3d2Safresh1 my $v = $f->{$k}; 2785759b3d2Safresh1 next unless defined($v); # undef is always fine 2795759b3d2Safresh1 2805759b3d2Safresh1 my $is_list = $fclass->is_list(); 2815759b3d2Safresh1 my $got_list = reftype($v) eq 'ARRAY' ? 1 : 0; 2825759b3d2Safresh1 2835759b3d2Safresh1 push @errors => "Facet '$k' should be a list, but got a single item ($v)" 2845759b3d2Safresh1 if $is_list && !$got_list; 2855759b3d2Safresh1 2865759b3d2Safresh1 push @errors => "Facet '$k' should not be a list, but got a a list ($v)" 2875759b3d2Safresh1 if $got_list && !$is_list; 2885759b3d2Safresh1 } 2895759b3d2Safresh1 2905759b3d2Safresh1 return @errors; 2915759b3d2Safresh1} 2925759b3d2Safresh1 2935759b3d2Safresh1sub nested { 2945759b3d2Safresh1 my $self = shift; 2955759b3d2Safresh1 2965759b3d2Safresh1 Carp::cluck("Use of Test2::Event->nested() is deprecated, use Test2::Event->trace->nested instead") 2975759b3d2Safresh1 if $ENV{AUTHOR_TESTING}; 2985759b3d2Safresh1 2995759b3d2Safresh1 if (my $hubs = $self->{+HUBS}) { 3005759b3d2Safresh1 return $hubs->[0]->{nested} if @$hubs; 3015759b3d2Safresh1 } 3025759b3d2Safresh1 3035759b3d2Safresh1 my $trace = $self->{+TRACE} or return undef; 3045759b3d2Safresh1 return $trace->{nested}; 3055759b3d2Safresh1} 3065759b3d2Safresh1 3075759b3d2Safresh1sub in_subtest { 3085759b3d2Safresh1 my $self = shift; 3095759b3d2Safresh1 3105759b3d2Safresh1 Carp::cluck("Use of Test2::Event->in_subtest() is deprecated, use Test2::Event->trace->hid instead") 3115759b3d2Safresh1 if $ENV{AUTHOR_TESTING}; 3125759b3d2Safresh1 3135759b3d2Safresh1 my $hubs = $self->{+HUBS}; 3145759b3d2Safresh1 if ($hubs && @$hubs) { 3155759b3d2Safresh1 return undef unless $hubs->[0]->{nested}; 3165759b3d2Safresh1 return $hubs->[0]->{hid} 3175759b3d2Safresh1 } 3185759b3d2Safresh1 3195759b3d2Safresh1 my $trace = $self->{+TRACE} or return undef; 3205759b3d2Safresh1 return undef unless $trace->{nested}; 3215759b3d2Safresh1 return $trace->{hid}; 3225759b3d2Safresh1} 3235759b3d2Safresh1 3245759b3d2Safresh11; 3255759b3d2Safresh1 3265759b3d2Safresh1__END__ 3275759b3d2Safresh1 3285759b3d2Safresh1=pod 3295759b3d2Safresh1 3305759b3d2Safresh1=encoding UTF-8 3315759b3d2Safresh1 3325759b3d2Safresh1=head1 NAME 3335759b3d2Safresh1 3345759b3d2Safresh1Test2::Event - Base class for events 3355759b3d2Safresh1 3365759b3d2Safresh1=head1 DESCRIPTION 3375759b3d2Safresh1 3385759b3d2Safresh1Base class for all event objects that get passed through 3395759b3d2Safresh1L<Test2>. 3405759b3d2Safresh1 3415759b3d2Safresh1=head1 SYNOPSIS 3425759b3d2Safresh1 3435759b3d2Safresh1 package Test2::Event::MyEvent; 3445759b3d2Safresh1 use strict; 3455759b3d2Safresh1 use warnings; 3465759b3d2Safresh1 3475759b3d2Safresh1 # This will make our class an event subclass (required) 3485759b3d2Safresh1 use base 'Test2::Event'; 3495759b3d2Safresh1 3505759b3d2Safresh1 # Add some accessors (optional) 3515759b3d2Safresh1 # You are not obligated to use HashBase, you can use any object tool you 3525759b3d2Safresh1 # want, or roll your own accessors. 3535759b3d2Safresh1 use Test2::Util::HashBase qw/foo bar baz/; 3545759b3d2Safresh1 3555759b3d2Safresh1 # Use this if you want the legacy API to be written for you, for this to 3565759b3d2Safresh1 # work you will need to implement a facet_data() method. 3575759b3d2Safresh1 use Test2::Util::Facets2Legacy; 3585759b3d2Safresh1 3595759b3d2Safresh1 # Chance to initialize some defaults 3605759b3d2Safresh1 sub init { 3615759b3d2Safresh1 my $self = shift; 3625759b3d2Safresh1 # no other args in @_ 3635759b3d2Safresh1 3645759b3d2Safresh1 $self->set_foo('xxx') unless defined $self->foo; 3655759b3d2Safresh1 3665759b3d2Safresh1 ... 3675759b3d2Safresh1 } 3685759b3d2Safresh1 3695759b3d2Safresh1 # This is the new way for events to convey data to the Test2 system 3705759b3d2Safresh1 sub facet_data { 3715759b3d2Safresh1 my $self = shift; 3725759b3d2Safresh1 3735759b3d2Safresh1 # Get common facets such as 'about', 'trace' 'amnesty', and 'meta' 3745759b3d2Safresh1 my $facet_data = $self->common_facet_data(); 3755759b3d2Safresh1 3765759b3d2Safresh1 # Are you making an assertion? 3775759b3d2Safresh1 $facet_data->{assert} = {pass => 1, details => 'my assertion'}; 3785759b3d2Safresh1 ... 3795759b3d2Safresh1 3805759b3d2Safresh1 return $facet_data; 3815759b3d2Safresh1 } 3825759b3d2Safresh1 3835759b3d2Safresh1 1; 3845759b3d2Safresh1 3855759b3d2Safresh1=head1 METHODS 3865759b3d2Safresh1 3875759b3d2Safresh1=head2 GENERAL 3885759b3d2Safresh1 3895759b3d2Safresh1=over 4 3905759b3d2Safresh1 3915759b3d2Safresh1=item $trace = $e->trace 3925759b3d2Safresh1 3935759b3d2Safresh1Get a snapshot of the L<Test2::EventFacet::Trace> as it was when this event was 3945759b3d2Safresh1generated 3955759b3d2Safresh1 3965759b3d2Safresh1=item $bool_or_undef = $e->related($e2) 3975759b3d2Safresh1 3985759b3d2Safresh1Check if 2 events are related. In this case related means their traces share a 3995759b3d2Safresh1signature meaning they were created with the same context (or at the very least 4005759b3d2Safresh1by contexts which share an id, which is the same thing unless someone is doing 4015759b3d2Safresh1something very bad). 4025759b3d2Safresh1 4035759b3d2Safresh1This can be used to reliably link multiple events created by the same tool. For 4045759b3d2Safresh1instance a failing test like C<ok(0, "fail"> will generate 2 events, one being 4055759b3d2Safresh1a L<Test2::Event::Ok>, the other being a L<Test2::Event::Diag>, both of these 4065759b3d2Safresh1events are related having been created under the same context and by the same 4075759b3d2Safresh1initial tool (though multiple tools may have been nested under the initial 4085759b3d2Safresh1one). 4095759b3d2Safresh1 4105759b3d2Safresh1This will return C<undef> if the relationship cannot be checked, which happens 4115759b3d2Safresh1if either event has an incomplete or missing trace. This will return C<0> if 4125759b3d2Safresh1the traces are complete, but do not match. C<1> will be returned if there is a 4135759b3d2Safresh1match. 4145759b3d2Safresh1 4155759b3d2Safresh1=item $e->add_amnesty({tag => $TAG, details => $DETAILS}); 4165759b3d2Safresh1 4175759b3d2Safresh1This can be used to add amnesty to this event. Amnesty only effects failing 4185759b3d2Safresh1assertions in most cases, but some formatters may display them for passing 4195759b3d2Safresh1assertions, or even non-assertions as well. 4205759b3d2Safresh1 4215759b3d2Safresh1Amnesty will prevent a failed assertion from causing the overall test to fail. 4225759b3d2Safresh1In other words it marks a failure as expected and allowed. 4235759b3d2Safresh1 4245759b3d2Safresh1B<Note:> This is how 'TODO' is implemented under the hood. TODO is essentially 4255759b3d2Safresh1amnesty with the 'TODO' tag. The details are the reason for the TODO. 4265759b3d2Safresh1 4275759b3d2Safresh1=item $uuid = $e->uuid 4285759b3d2Safresh1 4295759b3d2Safresh1If UUID tagging is enabled (See L<Test::API>) then any event that has made its 4305759b3d2Safresh1way through a hub will be tagged with a UUID. A newly created event will not 4315759b3d2Safresh1yet be tagged in most cases. 4325759b3d2Safresh1 4335759b3d2Safresh1=item $class = $e->load_facet($name) 4345759b3d2Safresh1 4355759b3d2Safresh1This method is used to load a facet by name (or key). It will attempt to load 4365759b3d2Safresh1the facet class, if it succeeds it will return the class it loaded. If it fails 4375759b3d2Safresh1it will return C<undef>. This caches the result at the class level so that 4385759b3d2Safresh1future calls will be faster. 4395759b3d2Safresh1 4405759b3d2Safresh1The C<$name> variable should be the key used to access the facet in a facets 4415759b3d2Safresh1hashref. For instance the assertion facet has the key 'assert', the information 4425759b3d2Safresh1facet has the 'info' key, and the error facet has the key 'errors'. You may 4435759b3d2Safresh1include or omit the 's' at the end of the name, the method is smart enough to 4445759b3d2Safresh1try both the 's' and no-'s' forms, it will check what you provided first, and 4455759b3d2Safresh1if that is not found it will add or strip the 's and try again. 4465759b3d2Safresh1 4475759b3d2Safresh1=item @classes = $e->FACET_TYPES() 4485759b3d2Safresh1 4495759b3d2Safresh1=item @classes = Test2::Event->FACET_TYPES() 4505759b3d2Safresh1 4515759b3d2Safresh1This returns a list of all facets that have been loaded using the 4525759b3d2Safresh1C<load_facet()> method. This will not return any classes that have not been 4535759b3d2Safresh1loaded, or have been loaded directly without a call to C<load_facet()>. 4545759b3d2Safresh1 4555759b3d2Safresh1B<Note:> The core facet types are automatically loaded and populated in this 4565759b3d2Safresh1list. 4575759b3d2Safresh1 4585759b3d2Safresh1=back 4595759b3d2Safresh1 4605759b3d2Safresh1=head2 NEW API 4615759b3d2Safresh1 4625759b3d2Safresh1=over 4 4635759b3d2Safresh1 4645759b3d2Safresh1=item $hashref = $e->common_facet_data(); 4655759b3d2Safresh1 4665759b3d2Safresh1This can be used by subclasses to generate a starting facet data hashref. This 4675759b3d2Safresh1will populate the hashref with the trace, meta, amnesty, and about facets. 4685759b3d2Safresh1These facets are nearly always produced the same way for all events. 4695759b3d2Safresh1 4705759b3d2Safresh1=item $hashref = $e->facet_data() 4715759b3d2Safresh1 4725759b3d2Safresh1If you do not override this then the default implementation will attempt to 4735759b3d2Safresh1generate facets from the legacy API. This generation is limited only to what 4745759b3d2Safresh1the legacy API can provide. It is recommended that you override this method and 4755759b3d2Safresh1write out explicit facet data. 4765759b3d2Safresh1 4775759b3d2Safresh1=item $hashref = $e->facets() 4785759b3d2Safresh1 4795759b3d2Safresh1This takes the hashref from C<facet_data()> and blesses each facet into the 4805759b3d2Safresh1proper C<Test2::EventFacet::*> subclass. If no class can be found for any given 4815759b3d2Safresh1facet it will be passed along unchanged. 4825759b3d2Safresh1 4835759b3d2Safresh1=item @errors = $e->validate_facet_data(); 4845759b3d2Safresh1 4855759b3d2Safresh1=item @errors = $e->validate_facet_data(%params); 4865759b3d2Safresh1 4875759b3d2Safresh1=item @errors = $e->validate_facet_data(\%facets, %params); 4885759b3d2Safresh1 4895759b3d2Safresh1=item @errors = Test2::Event->validate_facet_data(%params); 4905759b3d2Safresh1 4915759b3d2Safresh1=item @errors = Test2::Event->validate_facet_data(\%facets, %params); 4925759b3d2Safresh1 4935759b3d2Safresh1This method will validate facet data and return a list of errors. If no errors 4945759b3d2Safresh1are found this will return an empty list. 4955759b3d2Safresh1 4965759b3d2Safresh1This can be called as an object method with no arguments, in which case the 4975759b3d2Safresh1C<facet_data()> method will be called to get the facet data to be validated. 4985759b3d2Safresh1 4995759b3d2Safresh1When used as an object method the C<\%facet_data> argument may be omitted. 5005759b3d2Safresh1 5015759b3d2Safresh1When used as a class method the C<\%facet_data> argument is required. 5025759b3d2Safresh1 5035759b3d2Safresh1Remaining arguments will be slurped into a C<%params> hash. 5045759b3d2Safresh1 5055759b3d2Safresh1Currently only 1 parameter is defined: 5065759b3d2Safresh1 5075759b3d2Safresh1=over 4 5085759b3d2Safresh1 5095759b3d2Safresh1=item require_facet_class => $BOOL 5105759b3d2Safresh1 5115759b3d2Safresh1When set to true (default is false) this will reject any facets where a facet 5125759b3d2Safresh1class cannot be found. Normally facets without classes are assumed to be custom 5135759b3d2Safresh1and are ignored. 5145759b3d2Safresh1 5155759b3d2Safresh1=back 5165759b3d2Safresh1 5175759b3d2Safresh1=back 5185759b3d2Safresh1 5195759b3d2Safresh1=head3 WHAT ARE FACETS? 5205759b3d2Safresh1 5215759b3d2Safresh1Facets are how events convey their purpose to the Test2 internals and 5225759b3d2Safresh1formatters. An event without facets will have no intentional effect on the 5235759b3d2Safresh1overall test state, and will not be displayed at all by most formatters, except 5245759b3d2Safresh1perhaps to say that an event of an unknown type was seen. 5255759b3d2Safresh1 5265759b3d2Safresh1Facets are produced by the C<facet_data()> subroutine, which you should 5275759b3d2Safresh1nearly-always override. C<facet_data()> is expected to return a hashref where 5285759b3d2Safresh1each key is the facet type, and the value is either a hashref with the data for 529de8cc8edSafresh1that facet, or an array of hashrefs. Some facets must be defined as single 5305759b3d2Safresh1hashrefs, some must be defined as an array of hashrefs, No facets allow both. 5315759b3d2Safresh1 5325759b3d2Safresh1C<facet_data()> B<MUST NOT> bless the data it returns, the main hashref, and 533de8cc8edSafresh1nested facet hashrefs B<MUST> be bare, though items contained within each 5345759b3d2Safresh1facet may be blessed. The data returned by this method B<should> also be copies 5355759b3d2Safresh1of the internal data in order to prevent accidental state modification. 5365759b3d2Safresh1 5375759b3d2Safresh1C<facets()> takes the data from C<facet_data()> and blesses it into the 5385759b3d2Safresh1C<Test2::EventFacet::*> packages. This is rarely used however, the EventFacet 5395759b3d2Safresh1packages are primarily for convenience and documentation. The EventFacet 5405759b3d2Safresh1classes are not used at all internally, instead the raw data is used. 5415759b3d2Safresh1 5425759b3d2Safresh1Here is a list of facet types by package. The packages are not used internally, 5435759b3d2Safresh1but are where the documentation for each type is kept. 5445759b3d2Safresh1 5455759b3d2Safresh1B<Note:> Every single facet type has the C<'details'> field. This field is 5465759b3d2Safresh1always intended for human consumption, and when provided, should explain the 5475759b3d2Safresh1'why' for the facet. All other fields are facet specific. 5485759b3d2Safresh1 5495759b3d2Safresh1=over 4 5505759b3d2Safresh1 5515759b3d2Safresh1=item about => {...} 5525759b3d2Safresh1 5535759b3d2Safresh1L<Test2::EventFacet::About> 5545759b3d2Safresh1 5555759b3d2Safresh1This contains information about the event itself such as the event package 5565759b3d2Safresh1name. The C<details> field for this facet is an overall summary of the event. 5575759b3d2Safresh1 5585759b3d2Safresh1=item assert => {...} 5595759b3d2Safresh1 5605759b3d2Safresh1L<Test2::EventFacet::Assert> 5615759b3d2Safresh1 5625759b3d2Safresh1This facet is used if an assertion was made. The C<details> field of this facet 5635759b3d2Safresh1is the description of the assertion. 5645759b3d2Safresh1 5655759b3d2Safresh1=item control => {...} 5665759b3d2Safresh1 5675759b3d2Safresh1L<Test2::EventFacet::Control> 5685759b3d2Safresh1 5695759b3d2Safresh1This facet is used to tell the L<Test2::Event::Hub> about special actions the 5705759b3d2Safresh1event causes. Things like halting all testing, terminating the current test, 5715759b3d2Safresh1etc. In this facet the C<details> field explains why any special action was 5725759b3d2Safresh1taken. 5735759b3d2Safresh1 5745759b3d2Safresh1B<Note:> This is how bail-out is implemented. 5755759b3d2Safresh1 5765759b3d2Safresh1=item meta => {...} 5775759b3d2Safresh1 5785759b3d2Safresh1L<Test2::EventFacet::Meta> 5795759b3d2Safresh1 5805759b3d2Safresh1The meta facet contains all the meta-data attached to the event. In this case 5815759b3d2Safresh1the C<details> field has no special meaning, but may be present if something 5825759b3d2Safresh1sets the 'details' meta-key on the event. 5835759b3d2Safresh1 5845759b3d2Safresh1=item parent => {...} 5855759b3d2Safresh1 5865759b3d2Safresh1L<Test2::EventFacet::Parent> 5875759b3d2Safresh1 5885759b3d2Safresh1This facet contains nested events and similar details for subtests. In this 5895759b3d2Safresh1facet the C<details> field will typically be the name of the subtest. 5905759b3d2Safresh1 5915759b3d2Safresh1=item plan => {...} 5925759b3d2Safresh1 5935759b3d2Safresh1L<Test2::EventFacet::Plan> 5945759b3d2Safresh1 5955759b3d2Safresh1This facet tells the system that a plan has been set. The C<details> field of 5965759b3d2Safresh1this is usually left empty, but when present explains why the plan is what it 5975759b3d2Safresh1is, this is most useful if the plan is to skip-all. 5985759b3d2Safresh1 5995759b3d2Safresh1=item trace => {...} 6005759b3d2Safresh1 6015759b3d2Safresh1L<Test2::EventFacet::Trace> 6025759b3d2Safresh1 6035759b3d2Safresh1This facet contains information related to when and where the event was 6045759b3d2Safresh1generated. This is how the test file and line number of a failure is known. 6055759b3d2Safresh1This facet can also help you to tell if tests are related. 6065759b3d2Safresh1 6075759b3d2Safresh1In this facet the C<details> field overrides the "failed at test_file.t line 6085759b3d2Safresh142." message provided on assertion failure. 6095759b3d2Safresh1 6105759b3d2Safresh1=item amnesty => [{...}, ...] 6115759b3d2Safresh1 6125759b3d2Safresh1L<Test2::EventFacet::Amnesty> 6135759b3d2Safresh1 6145759b3d2Safresh1The amnesty facet is a list instead of a single item, this is important as 6155759b3d2Safresh1amnesty can come from multiple places at once. 6165759b3d2Safresh1 6175759b3d2Safresh1For each instance of amnesty the C<details> field explains why amnesty was 6185759b3d2Safresh1granted. 6195759b3d2Safresh1 6205759b3d2Safresh1B<Note:> Outside of formatters amnesty only acts to forgive a failing 6215759b3d2Safresh1assertion. 6225759b3d2Safresh1 6235759b3d2Safresh1=item errors => [{...}, ...] 6245759b3d2Safresh1 6255759b3d2Safresh1L<Test2::EventFacet::Error> 6265759b3d2Safresh1 6275759b3d2Safresh1The errors facet is a list instead of a single item, any number of errors can 6285759b3d2Safresh1be listed. In this facet C<details> describes the error, or may contain the raw 6295759b3d2Safresh1error message itself (such as an exception). In perl exception may be blessed 6305759b3d2Safresh1objects, as such the raw data for this facet may contain nested items which are 6315759b3d2Safresh1blessed. 6325759b3d2Safresh1 6335759b3d2Safresh1Not all errors are considered fatal, there is a C<fail> field that must be set 6345759b3d2Safresh1for an error to cause the test to fail. 6355759b3d2Safresh1 6365759b3d2Safresh1B<Note:> This facet is unique in that the field name is 'errors' while the 6375759b3d2Safresh1package is 'Error'. This is because this is the only facet type that is both a 6385759b3d2Safresh1list, and has a name where the plural is not the same as the singular. This may 6395759b3d2Safresh1cause some confusion, but I feel it will be less confusing than the 6405759b3d2Safresh1alternative. 6415759b3d2Safresh1 6425759b3d2Safresh1=item info => [{...}, ...] 6435759b3d2Safresh1 6445759b3d2Safresh1L<Test2::EventFacet::Info> 6455759b3d2Safresh1 6465759b3d2Safresh1The 'info' facet is a list instead of a single item, any quantity of extra 6475759b3d2Safresh1information can be attached to an event. Some information may be critical 6485759b3d2Safresh1diagnostics, others may be simply commentary in nature, this is determined by 6495759b3d2Safresh1the C<debug> flag. 6505759b3d2Safresh1 6515759b3d2Safresh1For this facet the C<details> flag is the info itself. This info may be a 6525759b3d2Safresh1string, or it may be a data structure to display. This is one of the few facet 6535759b3d2Safresh1types that may contain blessed items. 6545759b3d2Safresh1 6555759b3d2Safresh1=back 6565759b3d2Safresh1 6575759b3d2Safresh1=head2 LEGACY API 6585759b3d2Safresh1 6595759b3d2Safresh1=over 4 6605759b3d2Safresh1 6615759b3d2Safresh1=item $bool = $e->causes_fail 6625759b3d2Safresh1 6635759b3d2Safresh1Returns true if this event should result in a test failure. In general this 6645759b3d2Safresh1should be false. 6655759b3d2Safresh1 6665759b3d2Safresh1=item $bool = $e->increments_count 6675759b3d2Safresh1 6685759b3d2Safresh1Should be true if this event should result in a test count increment. 6695759b3d2Safresh1 6705759b3d2Safresh1=item $e->callback($hub) 6715759b3d2Safresh1 6725759b3d2Safresh1If your event needs to have extra effects on the L<Test2::Hub> you can override 6735759b3d2Safresh1this method. 6745759b3d2Safresh1 6755759b3d2Safresh1This is called B<BEFORE> your event is passed to the formatter. 6765759b3d2Safresh1 6775759b3d2Safresh1=item $num = $e->nested 6785759b3d2Safresh1 6795759b3d2Safresh1If this event is nested inside of other events, this should be the depth of 6805759b3d2Safresh1nesting. (This is mainly for subtests) 6815759b3d2Safresh1 6825759b3d2Safresh1=item $bool = $e->global 6835759b3d2Safresh1 6845759b3d2Safresh1Set this to true if your event is global, that is ALL threads and processes 6855759b3d2Safresh1should see it no matter when or where it is generated. This is not a common 6865759b3d2Safresh1thing to want, it is used by bail-out and skip_all to end testing. 6875759b3d2Safresh1 6885759b3d2Safresh1=item $code = $e->terminate 6895759b3d2Safresh1 6905759b3d2Safresh1This is called B<AFTER> your event has been passed to the formatter. This 6915759b3d2Safresh1should normally return undef, only change this if your event should cause the 6925759b3d2Safresh1test to exit immediately. 6935759b3d2Safresh1 6945759b3d2Safresh1If you want this event to cause the test to exit you should return the exit 6955759b3d2Safresh1code here. Exit code of 0 means exit success, any other integer means exit with 6965759b3d2Safresh1failure. 6975759b3d2Safresh1 6985759b3d2Safresh1This is used by L<Test2::Event::Plan> to exit 0 when the plan is 6995759b3d2Safresh1'skip_all'. This is also used by L<Test2::Event:Bail> to force the test 7005759b3d2Safresh1to exit with a failure. 7015759b3d2Safresh1 7025759b3d2Safresh1This is called after the event has been sent to the formatter in order to 7035759b3d2Safresh1ensure the event is seen and understood. 7045759b3d2Safresh1 7055759b3d2Safresh1=item $msg = $e->summary 7065759b3d2Safresh1 7075759b3d2Safresh1This is intended to be a human readable summary of the event. This should 7085759b3d2Safresh1ideally only be one line long, but you can use multiple lines if necessary. This 7095759b3d2Safresh1is intended for human consumption. You do not need to make it easy for machines 7105759b3d2Safresh1to understand. 7115759b3d2Safresh1 7125759b3d2Safresh1The default is to simply return the event package name. 7135759b3d2Safresh1 7145759b3d2Safresh1=item ($count, $directive, $reason) = $e->sets_plan() 7155759b3d2Safresh1 7165759b3d2Safresh1Check if this event sets the testing plan. It will return an empty list if it 7175759b3d2Safresh1does not. If it does set the plan it will return a list of 1 to 3 items in 7185759b3d2Safresh1order: Expected Test Count, Test Directive, Reason for directive. 7195759b3d2Safresh1 7205759b3d2Safresh1=item $bool = $e->diagnostics 7215759b3d2Safresh1 7225759b3d2Safresh1True if the event contains diagnostics info. This is useful because a 7235759b3d2Safresh1non-verbose harness may choose to hide events that are not in this category. 7245759b3d2Safresh1Some formatters may choose to send these to STDERR instead of STDOUT to ensure 7255759b3d2Safresh1they are seen. 7265759b3d2Safresh1 7275759b3d2Safresh1=item $bool = $e->no_display 7285759b3d2Safresh1 7295759b3d2Safresh1False by default. This will return true on events that should not be displayed 7305759b3d2Safresh1by formatters. 7315759b3d2Safresh1 7325759b3d2Safresh1=item $id = $e->in_subtest 7335759b3d2Safresh1 7345759b3d2Safresh1If the event is inside a subtest this should have the subtest ID. 7355759b3d2Safresh1 7365759b3d2Safresh1=item $id = $e->subtest_id 7375759b3d2Safresh1 7385759b3d2Safresh1If the event is a final subtest event, this should contain the subtest ID. 7395759b3d2Safresh1 7405759b3d2Safresh1=back 7415759b3d2Safresh1 7425759b3d2Safresh1=head1 THIRD PARTY META-DATA 7435759b3d2Safresh1 7445759b3d2Safresh1This object consumes L<Test2::Util::ExternalMeta> which provides a consistent 7455759b3d2Safresh1way for you to attach meta-data to instances of this class. This is useful for 7465759b3d2Safresh1tools, plugins, and other extensions. 7475759b3d2Safresh1 7485759b3d2Safresh1=head1 SOURCE 7495759b3d2Safresh1 7505759b3d2Safresh1The source code repository for Test2 can be found at 751*5486feefSafresh1L<https://github.com/Test-More/test-more/>. 7525759b3d2Safresh1 7535759b3d2Safresh1=head1 MAINTAINERS 7545759b3d2Safresh1 7555759b3d2Safresh1=over 4 7565759b3d2Safresh1 7575759b3d2Safresh1=item Chad Granum E<lt>exodist@cpan.orgE<gt> 7585759b3d2Safresh1 7595759b3d2Safresh1=back 7605759b3d2Safresh1 7615759b3d2Safresh1=head1 AUTHORS 7625759b3d2Safresh1 7635759b3d2Safresh1=over 4 7645759b3d2Safresh1 7655759b3d2Safresh1=item Chad Granum E<lt>exodist@cpan.orgE<gt> 7665759b3d2Safresh1 7675759b3d2Safresh1=back 7685759b3d2Safresh1 7695759b3d2Safresh1=head1 COPYRIGHT 7705759b3d2Safresh1 771256a93a4Safresh1Copyright 2020 Chad Granum E<lt>exodist@cpan.orgE<gt>. 7725759b3d2Safresh1 7735759b3d2Safresh1This program is free software; you can redistribute it and/or 7745759b3d2Safresh1modify it under the same terms as Perl itself. 7755759b3d2Safresh1 776*5486feefSafresh1See L<https://dev.perl.org/licenses/> 7775759b3d2Safresh1 7785759b3d2Safresh1=cut 779