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