xref: /openbsd-src/gnu/usr.bin/perl/cpan/Test-Simple/lib/Test2/API/Context.pm (revision 46035553bfdd96e63c94e32da0210227ec2e3cf1)
1package Test2::API::Context;
2use strict;
3use warnings;
4
5our $VERSION = '1.302162';
6
7
8use Carp qw/confess croak/;
9use Scalar::Util qw/weaken blessed/;
10use Test2::Util qw/get_tid try pkg_to_file get_tid/;
11
12use Test2::EventFacet::Trace();
13use Test2::API();
14
15# Preload some key event types
16my %LOADED = (
17    map {
18        my $pkg  = "Test2::Event::$_";
19        my $file = "Test2/Event/$_.pm";
20        require $file unless $INC{$file};
21        ( $pkg => $pkg, $_ => $pkg )
22    } qw/Ok Diag Note Plan Bail Exception Waiting Skip Subtest Pass Fail V2/
23);
24
25use Test2::Util::ExternalMeta qw/meta get_meta set_meta delete_meta/;
26use Test2::Util::HashBase qw{
27    stack hub trace _on_release _depth _is_canon _is_spawn _aborted
28    errno eval_error child_error thrown
29};
30
31# Private, not package vars
32# It is safe to cache these.
33my $ON_RELEASE = Test2::API::_context_release_callbacks_ref();
34my $CONTEXTS   = Test2::API::_contexts_ref();
35
36sub init {
37    my $self = shift;
38
39    confess "The 'trace' attribute is required"
40        unless $self->{+TRACE};
41
42    confess "The 'hub' attribute is required"
43        unless $self->{+HUB};
44
45    $self->{+_DEPTH} = 0 unless defined $self->{+_DEPTH};
46
47    $self->{+ERRNO}       = $! unless exists $self->{+ERRNO};
48    $self->{+EVAL_ERROR}  = $@ unless exists $self->{+EVAL_ERROR};
49    $self->{+CHILD_ERROR} = $? unless exists $self->{+CHILD_ERROR};
50}
51
52sub snapshot { bless {%{$_[0]}, _is_canon => undef, _is_spawn => undef, _aborted => undef}, __PACKAGE__ }
53
54sub restore_error_vars {
55    my $self = shift;
56    ($!, $@, $?) = @$self{+ERRNO, +EVAL_ERROR, +CHILD_ERROR};
57}
58
59sub DESTROY {
60    return unless $_[0]->{+_IS_CANON} || $_[0]->{+_IS_SPAWN};
61    return if $_[0]->{+_ABORTED} && ${$_[0]->{+_ABORTED}};
62    my ($self) = @_;
63
64    my $hub = $self->{+HUB};
65    my $hid = $hub->{hid};
66
67    # Do not show the warning if it looks like an exception has been thrown, or
68    # if the context is not local to this process or thread.
69    {
70        # Sometimes $@ is uninitialized, not a problem in this case so do not
71        # show the warning about using eq.
72        no warnings 'uninitialized';
73        if($self->{+EVAL_ERROR} eq $@ && $hub->is_local) {
74            my $frame = $self->{+_IS_SPAWN} || $self->{+TRACE}->frame;
75            warn <<"            EOT";
76A context appears to have been destroyed without first calling release().
77Based on \$@ it does not look like an exception was thrown (this is not always
78a reliable test)
79
80This is a problem because the global error variables (\$!, \$@, and \$?) will
81not be restored. In addition some release callbacks will not work properly from
82inside a DESTROY method.
83
84Here are the context creation details, just in case a tool forgot to call
85release():
86  File: $frame->[1]
87  Line: $frame->[2]
88  Tool: $frame->[3]
89
90Cleaning up the CONTEXT stack...
91            EOT
92        }
93    }
94
95    return if $self->{+_IS_SPAWN};
96
97    # Remove the key itself to avoid a slow memory leak
98    delete $CONTEXTS->{$hid};
99    $self->{+_IS_CANON} = undef;
100
101    if (my $cbk = $self->{+_ON_RELEASE}) {
102        $_->($self) for reverse @$cbk;
103    }
104    if (my $hcbk = $hub->{_context_release}) {
105        $_->($self) for reverse @$hcbk;
106    }
107    $_->($self) for reverse @$ON_RELEASE;
108}
109
110# release exists to implement behaviors like die-on-fail. In die-on-fail you
111# want to die after a failure, but only after diagnostics have been reported.
112# The ideal time for the die to happen is when the context is released.
113# Unfortunately die does not work in a DESTROY block.
114sub release {
115    my ($self) = @_;
116
117    ($!, $@, $?) = @$self{+ERRNO, +EVAL_ERROR, +CHILD_ERROR} and return if $self->{+THROWN};
118
119    ($!, $@, $?) = @$self{+ERRNO, +EVAL_ERROR, +CHILD_ERROR} and return $self->{+_IS_SPAWN} = undef
120        if $self->{+_IS_SPAWN};
121
122    croak "release() should not be called on context that is neither canon nor a child"
123        unless $self->{+_IS_CANON};
124
125    my $hub = $self->{+HUB};
126    my $hid = $hub->{hid};
127
128    croak "context thinks it is canon, but it is not"
129        unless $CONTEXTS->{$hid} && $CONTEXTS->{$hid} == $self;
130
131    # Remove the key itself to avoid a slow memory leak
132    $self->{+_IS_CANON} = undef;
133    delete $CONTEXTS->{$hid};
134
135    if (my $cbk = $self->{+_ON_RELEASE}) {
136        $_->($self) for reverse @$cbk;
137    }
138    if (my $hcbk = $hub->{_context_release}) {
139        $_->($self) for reverse @$hcbk;
140    }
141    $_->($self) for reverse @$ON_RELEASE;
142
143    # Do this last so that nothing else changes them.
144    # If one of the hooks dies then these do not get restored, this is
145    # intentional
146    ($!, $@, $?) = @$self{+ERRNO, +EVAL_ERROR, +CHILD_ERROR};
147
148    return;
149}
150
151sub do_in_context {
152    my $self = shift;
153    my ($sub, @args) = @_;
154
155    # We need to update the pid/tid and error vars.
156    my $clone = $self->snapshot;
157    @$clone{+ERRNO, +EVAL_ERROR, +CHILD_ERROR} = ($!, $@, $?);
158    $clone->{+TRACE} = $clone->{+TRACE}->snapshot(pid => $$, tid => get_tid());
159
160    my $hub = $clone->{+HUB};
161    my $hid = $hub->hid;
162
163    my $old = $CONTEXTS->{$hid};
164
165    $clone->{+_IS_CANON} = 1;
166    $CONTEXTS->{$hid} = $clone;
167    weaken($CONTEXTS->{$hid});
168    my ($ok, $err) = &try($sub, @args);
169    my ($rok, $rerr) = try { $clone->release };
170    delete $clone->{+_IS_CANON};
171
172    if ($old) {
173        $CONTEXTS->{$hid} = $old;
174        weaken($CONTEXTS->{$hid});
175    }
176    else {
177        delete $CONTEXTS->{$hid};
178    }
179
180    die $err  unless $ok;
181    die $rerr unless $rok;
182}
183
184sub done_testing {
185    my $self = shift;
186    $self->hub->finalize($self->trace, 1);
187    return;
188}
189
190sub throw {
191    my ($self, $msg) = @_;
192    $self->{+THROWN} = 1;
193    ${$self->{+_ABORTED}}++ if $self->{+_ABORTED};
194    $self->release if $self->{+_IS_CANON} || $self->{+_IS_SPAWN};
195    $self->trace->throw($msg);
196}
197
198sub alert {
199    my ($self, $msg) = @_;
200    $self->trace->alert($msg);
201}
202
203sub send_ev2_and_release {
204    my $self = shift;
205    my $out  = $self->send_ev2(@_);
206    $self->release;
207    return $out;
208}
209
210sub send_ev2 {
211    my $self = shift;
212
213    my $e;
214    {
215        local $Carp::CarpLevel = $Carp::CarpLevel + 1;
216        $e = Test2::Event::V2->new(
217            trace => $self->{+TRACE}->snapshot,
218            @_,
219        );
220    }
221
222    if ($self->{+_ABORTED}) {
223        my $f = $e->facet_data;
224        ${$self->{+_ABORTED}}++ if $f->{control}->{halt} || defined($f->{control}->{terminate}) || defined($e->terminate);
225    }
226    $self->{+HUB}->send($e);
227}
228
229sub build_ev2 {
230    my $self = shift;
231
232    local $Carp::CarpLevel = $Carp::CarpLevel + 1;
233    Test2::Event::V2->new(
234        trace => $self->{+TRACE}->snapshot,
235        @_,
236    );
237}
238
239sub send_event_and_release {
240    my $self = shift;
241    my $out = $self->send_event(@_);
242    $self->release;
243    return $out;
244}
245
246sub send_event {
247    my $self  = shift;
248    my $event = shift;
249    my %args  = @_;
250
251    my $pkg = $LOADED{$event} || $self->_parse_event($event);
252
253    my $e;
254    {
255        local $Carp::CarpLevel = $Carp::CarpLevel + 1;
256        $e = $pkg->new(
257            trace => $self->{+TRACE}->snapshot,
258            %args,
259        );
260    }
261
262    if ($self->{+_ABORTED}) {
263        my $f = $e->facet_data;
264        ${$self->{+_ABORTED}}++ if $f->{control}->{halt} || defined($f->{control}->{terminate}) || defined($e->terminate);
265    }
266    $self->{+HUB}->send($e);
267}
268
269sub build_event {
270    my $self  = shift;
271    my $event = shift;
272    my %args  = @_;
273
274    my $pkg = $LOADED{$event} || $self->_parse_event($event);
275
276    local $Carp::CarpLevel = $Carp::CarpLevel + 1;
277    $pkg->new(
278        trace => $self->{+TRACE}->snapshot,
279        %args,
280    );
281}
282
283sub pass {
284    my $self = shift;
285    my ($name) = @_;
286
287    my $e = bless(
288        {
289            trace => bless({%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
290            name  => $name,
291        },
292        "Test2::Event::Pass"
293    );
294
295    $self->{+HUB}->send($e);
296    return $e;
297}
298
299sub pass_and_release {
300    my $self = shift;
301    my ($name) = @_;
302
303    my $e = bless(
304        {
305            trace => bless({%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
306            name  => $name,
307        },
308        "Test2::Event::Pass"
309    );
310
311    $self->{+HUB}->send($e);
312    $self->release;
313    return 1;
314}
315
316sub fail {
317    my $self = shift;
318    my ($name, @diag) = @_;
319
320    my $e = bless(
321        {
322            trace => bless({%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
323            name  => $name,
324        },
325        "Test2::Event::Fail"
326    );
327
328    for my $msg (@diag) {
329        if (ref($msg) eq 'Test2::EventFacet::Info::Table') {
330            $e->add_info({tag => 'DIAG', debug => 1, $msg->info_args});
331        }
332        else {
333            $e->add_info({tag => 'DIAG', debug => 1, details => $msg});
334        }
335    }
336
337    $self->{+HUB}->send($e);
338    return $e;
339}
340
341sub fail_and_release {
342    my $self = shift;
343    my ($name, @diag) = @_;
344
345    my $e = bless(
346        {
347            trace => bless({%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
348            name  => $name,
349        },
350        "Test2::Event::Fail"
351    );
352
353    for my $msg (@diag) {
354        if (ref($msg) eq 'Test2::EventFacet::Info::Table') {
355            $e->add_info({tag => 'DIAG', debug => 1, $msg->info_args});
356        }
357        else {
358            $e->add_info({tag => 'DIAG', debug => 1, details => $msg});
359        }
360    }
361
362    $self->{+HUB}->send($e);
363    $self->release;
364    return 0;
365}
366
367sub ok {
368    my $self = shift;
369    my ($pass, $name, $on_fail) = @_;
370
371    my $hub = $self->{+HUB};
372
373    my $e = bless {
374        trace => bless( {%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
375        pass  => $pass,
376        name  => $name,
377    }, 'Test2::Event::Ok';
378    $e->init;
379
380    $hub->send($e);
381    return $e if $pass;
382
383    $self->failure_diag($e);
384
385    if ($on_fail && @$on_fail) {
386        $self->diag($_) for @$on_fail;
387    }
388
389    return $e;
390}
391
392sub failure_diag {
393    my $self = shift;
394    my ($e) = @_;
395
396    # Figure out the debug info, this is typically the file name and line
397    # number, but can also be a custom message. If no trace object is provided
398    # then we have nothing useful to display.
399    my $name  = $e->name;
400    my $trace = $e->trace;
401    my $debug = $trace ? $trace->debug : "[No trace info available]";
402
403    # Create the initial diagnostics. If the test has a name we put the debug
404    # info on a second line, this behavior is inherited from Test::Builder.
405    my $msg = defined($name)
406        ? qq[Failed test '$name'\n$debug.\n]
407        : qq[Failed test $debug.\n];
408
409    $self->diag($msg);
410}
411
412sub skip {
413    my $self = shift;
414    my ($name, $reason, @extra) = @_;
415    $self->send_event(
416        'Skip',
417        name => $name,
418        reason => $reason,
419        pass => 1,
420        @extra,
421    );
422}
423
424sub note {
425    my $self = shift;
426    my ($message) = @_;
427    $self->send_event('Note', message => $message);
428}
429
430sub diag {
431    my $self = shift;
432    my ($message) = @_;
433    my $hub = $self->{+HUB};
434    $self->send_event(
435        'Diag',
436        message => $message,
437    );
438}
439
440sub plan {
441    my ($self, $max, $directive, $reason) = @_;
442    $self->send_event('Plan', max => $max, directive => $directive, reason => $reason);
443}
444
445sub bail {
446    my ($self, $reason) = @_;
447    $self->send_event('Bail', reason => $reason);
448}
449
450sub _parse_event {
451    my $self = shift;
452    my $event = shift;
453
454    my $pkg;
455    if ($event =~ m/^\+(.*)/) {
456        $pkg = $1;
457    }
458    else {
459        $pkg = "Test2::Event::$event";
460    }
461
462    unless ($LOADED{$pkg}) {
463        my $file = pkg_to_file($pkg);
464        my ($ok, $err) = try { require $file };
465        $self->throw("Could not load event module '$pkg': $err")
466            unless $ok;
467
468        $LOADED{$pkg} = $pkg;
469    }
470
471    confess "'$pkg' is not a subclass of 'Test2::Event'"
472        unless $pkg->isa('Test2::Event');
473
474    $LOADED{$event} = $pkg;
475
476    return $pkg;
477}
478
4791;
480
481__END__
482
483=pod
484
485=encoding UTF-8
486
487=head1 NAME
488
489Test2::API::Context - Object to represent a testing context.
490
491=head1 DESCRIPTION
492
493The context object is the primary interface for authors of testing tools
494written with L<Test2>. The context object represents the context in
495which a test takes place (File and Line Number), and provides a quick way to
496generate events from that context. The context object also takes care of
497sending events to the correct L<Test2::Hub> instance.
498
499=head1 SYNOPSIS
500
501In general you will not be creating contexts directly. To obtain a context you
502should always use C<context()> which is exported by the L<Test2::API> module.
503
504    use Test2::API qw/context/;
505
506    sub my_ok {
507        my ($bool, $name) = @_;
508        my $ctx = context();
509
510        if ($bool) {
511            $ctx->pass($name);
512        }
513        else {
514            $ctx->fail($name);
515        }
516
517        $ctx->release; # You MUST do this!
518        return $bool;
519    }
520
521Context objects make it easy to wrap other tools that also use context. Once
522you grab a context, any tool you call before releasing your context will
523inherit it:
524
525    sub wrapper {
526        my ($bool, $name) = @_;
527        my $ctx = context();
528        $ctx->diag("wrapping my_ok");
529
530        my $out = my_ok($bool, $name);
531        $ctx->release; # You MUST do this!
532        return $out;
533    }
534
535=head1 CRITICAL DETAILS
536
537=over 4
538
539=item you MUST always use the context() sub from Test2::API
540
541Creating your own context via C<< Test2::API::Context->new() >> will almost never
542produce a desirable result. Use C<context()> which is exported by L<Test2::API>.
543
544There are a handful of cases where a tool author may want to create a new
545context by hand, which is why the C<new> method exists. Unless you really know
546what you are doing you should avoid this.
547
548=item You MUST always release the context when done with it
549
550Releasing the context tells the system you are done with it. This gives it a
551chance to run any necessary callbacks or cleanup tasks. If you forget to
552release the context it will try to detect the problem and warn you about it.
553
554=item You MUST NOT pass context objects around
555
556When you obtain a context object it is made specifically for your tool and any
557tools nested within. If you pass a context around you run the risk of polluting
558other tools with incorrect context information.
559
560If you are certain that you want a different tool to use the same context you
561may pass it a snapshot. C<< $ctx->snapshot >> will give you a shallow clone of
562the context that is safe to pass around or store.
563
564=item You MUST NOT store or cache a context for later
565
566As long as a context exists for a given hub, all tools that try to get a
567context will get the existing instance. If you try to store the context you
568will pollute other tools with incorrect context information.
569
570If you are certain that you want to save the context for later, you can use a
571snapshot. C<< $ctx->snapshot >> will give you a shallow clone of the context
572that is safe to pass around or store.
573
574C<context()> has some mechanisms to protect you if you do cause a context to
575persist beyond the scope in which it was obtained. In practice you should not
576rely on these protections, and they are fairly noisy with warnings.
577
578=item You SHOULD obtain your context as soon as possible in a given tool
579
580You never know what tools you call from within your own tool will need a
581context. Obtaining the context early ensures that nested tools can find the
582context you want them to find.
583
584=back
585
586=head1 METHODS
587
588=over 4
589
590=item $ctx->done_testing;
591
592Note that testing is finished. If no plan has been set this will generate a
593Plan event.
594
595=item $clone = $ctx->snapshot()
596
597This will return a shallow clone of the context. The shallow clone is safe to
598store for later.
599
600=item $ctx->release()
601
602This will release the context. This runs cleanup tasks, and several important
603hooks. It will also restore C<$!>, C<$?>, and C<$@> to what they were when the
604context was created.
605
606B<Note:> If a context is acquired more than once an internal refcount is kept.
607C<release()> decrements the ref count, none of the other actions of
608C<release()> will occur unless the refcount hits 0. This means only the last
609call to C<release()> will reset C<$?>, C<$!>, C<$@>,and run the cleanup tasks.
610
611=item $ctx->throw($message)
612
613This will throw an exception reporting to the file and line number of the
614context. This will also release the context for you.
615
616=item $ctx->alert($message)
617
618This will issue a warning from the file and line number of the context.
619
620=item $stack = $ctx->stack()
621
622This will return the L<Test2::API::Stack> instance the context used to find
623the current hub.
624
625=item $hub = $ctx->hub()
626
627This will return the L<Test2::Hub> instance the context recognizes as the
628current one to which all events should be sent.
629
630=item $dbg = $ctx->trace()
631
632This will return the L<Test2::EventFacet::Trace> instance used by the context.
633
634=item $ctx->do_in_context(\&code, @args);
635
636Sometimes you have a context that is not current, and you want things to use it
637as the current one. In these cases you can call
638C<< $ctx->do_in_context(sub { ... }) >>. The codeblock will be run, and
639anything inside of it that looks for a context will find the one on which the
640method was called.
641
642This B<DOES NOT> affect context on other hubs, only the hub used by the context
643will be affected.
644
645    my $ctx = ...;
646    $ctx->do_in_context(sub {
647        my $ctx = context(); # returns the $ctx the sub is called on
648    });
649
650B<Note:> The context will actually be cloned, the clone will be used instead of
651the original. This allows the thread id, process id, and error variables to be correct without
652modifying the original context.
653
654=item $ctx->restore_error_vars()
655
656This will set C<$!>, C<$?>, and C<$@> to what they were when the context was
657created. There is no localization or anything done here, calling this method
658will actually set these vars.
659
660=item $! = $ctx->errno()
661
662The (numeric) value of C<$!> when the context was created.
663
664=item $? = $ctx->child_error()
665
666The value of C<$?> when the context was created.
667
668=item $@ = $ctx->eval_error()
669
670The value of C<$@> when the context was created.
671
672=back
673
674=head2 EVENT PRODUCTION METHODS
675
676B<Which one do I use?>
677
678The C<pass*> and C<fail*> are optimal if they meet your situation, using one of
679them will always be the most optimal. That said they are optimal by eliminating
680many features.
681
682Method such as C<ok>, and C<note> are shortcuts for generating common 1-task
683events based on the old API, however they are forward compatible, and easy to
684use. If these meet your needs then go ahead and use them, but please check back
685often for alternatives that may be added.
686
687If you want to generate new style events, events that do many things at once,
688then you want the C<*ev2*> methods. These let you directly specify which facets
689you wish to use.
690
691=over 4
692
693=item $event = $ctx->pass()
694
695=item $event = $ctx->pass($name)
696
697This will send and return an L<Test2::Event::Pass> event. You may optionally
698provide a C<$name> for the assertion.
699
700The L<Test2::Event::Pass> is a specially crafted and optimized event, using
701this will help the performance of passing tests.
702
703=item $true = $ctx->pass_and_release()
704
705=item $true = $ctx->pass_and_release($name)
706
707This is a combination of C<pass()> and C<release()>. You can use this if you do
708not plan to do anything with the context after sending the event. This helps
709write more clear and compact code.
710
711    sub shorthand {
712        my ($bool, $name) = @_;
713        my $ctx = context();
714        return $ctx->pass_and_release($name) if $bool;
715
716        ... Handle a failure ...
717    }
718
719    sub longform {
720        my ($bool, $name) = @_;
721        my $ctx = context();
722
723        if ($bool) {
724            $ctx->pass($name);
725            $ctx->release;
726            return 1;
727        }
728
729        ... Handle a failure ...
730    }
731
732=item my $event = $ctx->fail()
733
734=item my $event = $ctx->fail($name)
735
736=item my $event = $ctx->fail($name, @diagnostics)
737
738This lets you send an L<Test2::Event::Fail> event. You may optionally provide a
739C<$name> and C<@diagnostics> messages.
740
741Diagnostics messages can be simple strings, data structures, or instances of
742L<Test2::EventFacet::Info::Table> (which are converted inline into the
743L<Test2::EventFacet::Info> structure).
744
745=item my $false = $ctx->fail_and_release()
746
747=item my $false = $ctx->fail_and_release($name)
748
749=item my $false = $ctx->fail_and_release($name, @diagnostics)
750
751This is a combination of C<fail()> and C<release()>. This can be used to write
752clearer and shorter code.
753
754    sub shorthand {
755        my ($bool, $name) = @_;
756        my $ctx = context();
757        return $ctx->fail_and_release($name) unless $bool;
758
759        ... Handle a success ...
760    }
761
762    sub longform {
763        my ($bool, $name) = @_;
764        my $ctx = context();
765
766        unless ($bool) {
767            $ctx->pass($name);
768            $ctx->release;
769            return 1;
770        }
771
772        ... Handle a success ...
773    }
774
775
776=item $event = $ctx->ok($bool, $name)
777
778=item $event = $ctx->ok($bool, $name, \@on_fail)
779
780B<NOTE:> Use of this method is discouraged in favor of C<pass()> and C<fail()>
781which produce L<Test2::Event::Pass> and L<Test2::Event::Fail> events. These
782newer event types are faster and less crufty.
783
784This will create an L<Test2::Event::Ok> object for you. If C<$bool> is false
785then an L<Test2::Event::Diag> event will be sent as well with details about the
786failure. If you do not want automatic diagnostics you should use the
787C<send_event()> method directly.
788
789The third argument C<\@on_fail>) is an optional set of diagnostics to be sent in
790the event of a test failure. Unlike with C<fail()> these diagnostics must be
791plain strings, data structures are not supported.
792
793=item $event = $ctx->note($message)
794
795Send an L<Test2::Event::Note>. This event prints a message to STDOUT.
796
797=item $event = $ctx->diag($message)
798
799Send an L<Test2::Event::Diag>. This event prints a message to STDERR.
800
801=item $event = $ctx->plan($max)
802
803=item $event = $ctx->plan(0, 'SKIP', $reason)
804
805This can be used to send an L<Test2::Event::Plan> event. This event
806usually takes either a number of tests you expect to run. Optionally you can
807set the expected count to 0 and give the 'SKIP' directive with a reason to
808cause all tests to be skipped.
809
810=item $event = $ctx->skip($name, $reason);
811
812Send an L<Test2::Event::Skip> event.
813
814=item $event = $ctx->bail($reason)
815
816This sends an L<Test2::Event::Bail> event. This event will completely
817terminate all testing.
818
819=item $event = $ctx->send_ev2(%facets)
820
821This lets you build and send a V2 event directly from facets. The event is
822returned after it is sent.
823
824This example sends a single assertion, a note (comment for stdout in
825Test::Builder talk) and sets the plan to 1.
826
827    my $event = $ctx->send_event(
828        plan   => {count => 1},
829        assert => {pass  => 1, details => "A passing assert"},
830        info => [{tag => 'NOTE', details => "This is a note"}],
831    );
832
833=item $event = $ctx->build_e2(%facets)
834
835This is the same as C<send_ev2()>, except it builds and returns the event
836without sending it.
837
838=item $event = $ctx->send_ev2_and_release($Type, %parameters)
839
840This is a combination of C<send_ev2()> and C<release()>.
841
842    sub shorthand {
843        my $ctx = context();
844        return $ctx->send_ev2_and_release(assert => {pass => 1, details => 'foo'});
845    }
846
847    sub longform {
848        my $ctx = context();
849        my $event = $ctx->send_ev2(assert => {pass => 1, details => 'foo'});
850        $ctx->release;
851        return $event;
852    }
853
854=item $event = $ctx->send_event($Type, %parameters)
855
856B<It is better to use send_ev2() in new code.>
857
858This lets you build and send an event of any type. The C<$Type> argument should
859be the event package name with C<Test2::Event::> left off, or a fully
860qualified package name prefixed with a '+'. The event is returned after it is
861sent.
862
863    my $event = $ctx->send_event('Ok', ...);
864
865or
866
867    my $event = $ctx->send_event('+Test2::Event::Ok', ...);
868
869=item $event = $ctx->build_event($Type, %parameters)
870
871B<It is better to use build_ev2() in new code.>
872
873This is the same as C<send_event()>, except it builds and returns the event
874without sending it.
875
876=item $event = $ctx->send_event_and_release($Type, %parameters)
877
878B<It is better to use send_ev2_and_release() in new code.>
879
880This is a combination of C<send_event()> and C<release()>.
881
882    sub shorthand {
883        my $ctx = context();
884        return $ctx->send_event_and_release(Pass => { name => 'foo' });
885    }
886
887    sub longform {
888        my $ctx = context();
889        my $event = $ctx->send_event(Pass => { name => 'foo' });
890        $ctx->release;
891        return $event;
892    }
893
894=back
895
896=head1 HOOKS
897
898There are 2 types of hooks, init hooks, and release hooks. As the names
899suggest, these hooks are triggered when contexts are created or released.
900
901=head2 INIT HOOKS
902
903These are called whenever a context is initialized. That means when a new
904instance is created. These hooks are B<NOT> called every time something
905requests a context, just when a new one is created.
906
907=head3 GLOBAL
908
909This is how you add a global init callback. Global callbacks happen for every
910context for any hub or stack.
911
912    Test2::API::test2_add_callback_context_init(sub {
913        my $ctx = shift;
914        ...
915    });
916
917=head3 PER HUB
918
919This is how you add an init callback for all contexts created for a given hub.
920These callbacks will not run for other hubs.
921
922    $hub->add_context_init(sub {
923        my $ctx = shift;
924        ...
925    });
926
927=head3 PER CONTEXT
928
929This is how you specify an init hook that will only run if your call to
930C<context()> generates a new context. The callback will be ignored if
931C<context()> is returning an existing context.
932
933    my $ctx = context(on_init => sub {
934        my $ctx = shift;
935        ...
936    });
937
938=head2 RELEASE HOOKS
939
940These are called whenever a context is released. That means when the last
941reference to the instance is about to be destroyed. These hooks are B<NOT>
942called every time C<< $ctx->release >> is called.
943
944=head3 GLOBAL
945
946This is how you add a global release callback. Global callbacks happen for every
947context for any hub or stack.
948
949    Test2::API::test2_add_callback_context_release(sub {
950        my $ctx = shift;
951        ...
952    });
953
954=head3 PER HUB
955
956This is how you add a release callback for all contexts created for a given
957hub. These callbacks will not run for other hubs.
958
959    $hub->add_context_release(sub {
960        my $ctx = shift;
961        ...
962    });
963
964=head3 PER CONTEXT
965
966This is how you add release callbacks directly to a context. The callback will
967B<ALWAYS> be added to the context that gets returned, it does not matter if a
968new one is generated, or if an existing one is returned.
969
970    my $ctx = context(on_release => sub {
971        my $ctx = shift;
972        ...
973    });
974
975=head1 THIRD PARTY META-DATA
976
977This object consumes L<Test2::Util::ExternalMeta> which provides a consistent
978way for you to attach meta-data to instances of this class. This is useful for
979tools, plugins, and other extensions.
980
981=head1 SOURCE
982
983The source code repository for Test2 can be found at
984F<http://github.com/Test-More/test-more/>.
985
986=head1 MAINTAINERS
987
988=over 4
989
990=item Chad Granum E<lt>exodist@cpan.orgE<gt>
991
992=back
993
994=head1 AUTHORS
995
996=over 4
997
998=item Chad Granum E<lt>exodist@cpan.orgE<gt>
999
1000=item Kent Fredric E<lt>kentnl@cpan.orgE<gt>
1001
1002=back
1003
1004=head1 COPYRIGHT
1005
1006Copyright 2019 Chad Granum E<lt>exodist@cpan.orgE<gt>.
1007
1008This program is free software; you can redistribute it and/or
1009modify it under the same terms as Perl itself.
1010
1011See F<http://dev.perl.org/licenses/>
1012
1013=cut
1014