1package Test2::API::Context; 2use strict; 3use warnings; 4 5our $VERSION = '1.302190'; 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 my $hub = $self->{+HUB}; 440 $self->send_event( 441 'Diag', 442 message => $message, 443 ); 444} 445 446sub plan { 447 my ($self, $max, $directive, $reason) = @_; 448 $self->send_event('Plan', max => $max, directive => $directive, reason => $reason); 449} 450 451sub bail { 452 my ($self, $reason) = @_; 453 $self->send_event('Bail', reason => $reason); 454} 455 456sub _parse_event { 457 my $self = shift; 458 my $event = shift; 459 460 my $pkg; 461 if ($event =~ m/^\+(.*)/) { 462 $pkg = $1; 463 } 464 else { 465 $pkg = "Test2::Event::$event"; 466 } 467 468 unless ($LOADED{$pkg}) { 469 my $file = pkg_to_file($pkg); 470 my ($ok, $err) = try { require $file }; 471 $self->throw("Could not load event module '$pkg': $err") 472 unless $ok; 473 474 $LOADED{$pkg} = $pkg; 475 } 476 477 confess "'$pkg' is not a subclass of 'Test2::Event'" 478 unless $pkg->isa('Test2::Event'); 479 480 $LOADED{$event} = $pkg; 481 482 return $pkg; 483} 484 4851; 486 487__END__ 488 489=pod 490 491=encoding UTF-8 492 493=head1 NAME 494 495Test2::API::Context - Object to represent a testing context. 496 497=head1 DESCRIPTION 498 499The context object is the primary interface for authors of testing tools 500written with L<Test2>. The context object represents the context in 501which a test takes place (File and Line Number), and provides a quick way to 502generate events from that context. The context object also takes care of 503sending events to the correct L<Test2::Hub> instance. 504 505=head1 SYNOPSIS 506 507In general you will not be creating contexts directly. To obtain a context you 508should always use C<context()> which is exported by the L<Test2::API> module. 509 510 use Test2::API qw/context/; 511 512 sub my_ok { 513 my ($bool, $name) = @_; 514 my $ctx = context(); 515 516 if ($bool) { 517 $ctx->pass($name); 518 } 519 else { 520 $ctx->fail($name); 521 } 522 523 $ctx->release; # You MUST do this! 524 return $bool; 525 } 526 527Context objects make it easy to wrap other tools that also use context. Once 528you grab a context, any tool you call before releasing your context will 529inherit it: 530 531 sub wrapper { 532 my ($bool, $name) = @_; 533 my $ctx = context(); 534 $ctx->diag("wrapping my_ok"); 535 536 my $out = my_ok($bool, $name); 537 $ctx->release; # You MUST do this! 538 return $out; 539 } 540 541=head1 CRITICAL DETAILS 542 543=over 4 544 545=item you MUST always use the context() sub from Test2::API 546 547Creating your own context via C<< Test2::API::Context->new() >> will almost never 548produce a desirable result. Use C<context()> which is exported by L<Test2::API>. 549 550There are a handful of cases where a tool author may want to create a new 551context by hand, which is why the C<new> method exists. Unless you really know 552what you are doing you should avoid this. 553 554=item You MUST always release the context when done with it 555 556Releasing the context tells the system you are done with it. This gives it a 557chance to run any necessary callbacks or cleanup tasks. If you forget to 558release the context it will try to detect the problem and warn you about it. 559 560=item You MUST NOT pass context objects around 561 562When you obtain a context object it is made specifically for your tool and any 563tools nested within. If you pass a context around you run the risk of polluting 564other tools with incorrect context information. 565 566If you are certain that you want a different tool to use the same context you 567may pass it a snapshot. C<< $ctx->snapshot >> will give you a shallow clone of 568the context that is safe to pass around or store. 569 570=item You MUST NOT store or cache a context for later 571 572As long as a context exists for a given hub, all tools that try to get a 573context will get the existing instance. If you try to store the context you 574will pollute other tools with incorrect context information. 575 576If you are certain that you want to save the context for later, you can use a 577snapshot. C<< $ctx->snapshot >> will give you a shallow clone of the context 578that is safe to pass around or store. 579 580C<context()> has some mechanisms to protect you if you do cause a context to 581persist beyond the scope in which it was obtained. In practice you should not 582rely on these protections, and they are fairly noisy with warnings. 583 584=item You SHOULD obtain your context as soon as possible in a given tool 585 586You never know what tools you call from within your own tool will need a 587context. Obtaining the context early ensures that nested tools can find the 588context you want them to find. 589 590=back 591 592=head1 METHODS 593 594=over 4 595 596=item $ctx->done_testing; 597 598Note that testing is finished. If no plan has been set this will generate a 599Plan event. 600 601=item $clone = $ctx->snapshot() 602 603This will return a shallow clone of the context. The shallow clone is safe to 604store for later. 605 606=item $ctx->release() 607 608This will release the context. This runs cleanup tasks, and several important 609hooks. It will also restore C<$!>, C<$?>, and C<$@> to what they were when the 610context was created. 611 612B<Note:> If a context is acquired more than once an internal refcount is kept. 613C<release()> decrements the ref count, none of the other actions of 614C<release()> will occur unless the refcount hits 0. This means only the last 615call to C<release()> will reset C<$?>, C<$!>, C<$@>,and run the cleanup tasks. 616 617=item $ctx->throw($message) 618 619This will throw an exception reporting to the file and line number of the 620context. This will also release the context for you. 621 622=item $ctx->alert($message) 623 624This will issue a warning from the file and line number of the context. 625 626=item $stack = $ctx->stack() 627 628This will return the L<Test2::API::Stack> instance the context used to find 629the current hub. 630 631=item $hub = $ctx->hub() 632 633This will return the L<Test2::Hub> instance the context recognizes as the 634current one to which all events should be sent. 635 636=item $dbg = $ctx->trace() 637 638This will return the L<Test2::EventFacet::Trace> instance used by the context. 639 640=item $ctx->do_in_context(\&code, @args); 641 642Sometimes you have a context that is not current, and you want things to use it 643as the current one. In these cases you can call 644C<< $ctx->do_in_context(sub { ... }) >>. The codeblock will be run, and 645anything inside of it that looks for a context will find the one on which the 646method was called. 647 648This B<DOES NOT> affect context on other hubs, only the hub used by the context 649will be affected. 650 651 my $ctx = ...; 652 $ctx->do_in_context(sub { 653 my $ctx = context(); # returns the $ctx the sub is called on 654 }); 655 656B<Note:> The context will actually be cloned, the clone will be used instead of 657the original. This allows the thread id, process id, and error variables to be correct without 658modifying the original context. 659 660=item $ctx->restore_error_vars() 661 662This will set C<$!>, C<$?>, and C<$@> to what they were when the context was 663created. There is no localization or anything done here, calling this method 664will actually set these vars. 665 666=item $! = $ctx->errno() 667 668The (numeric) value of C<$!> when the context was created. 669 670=item $? = $ctx->child_error() 671 672The value of C<$?> when the context was created. 673 674=item $@ = $ctx->eval_error() 675 676The value of C<$@> when the context was created. 677 678=back 679 680=head2 EVENT PRODUCTION METHODS 681 682B<Which one do I use?> 683 684The C<pass*> and C<fail*> are optimal if they meet your situation, using one of 685them will always be the most optimal. That said they are optimal by eliminating 686many features. 687 688Method such as C<ok>, and C<note> are shortcuts for generating common 1-task 689events based on the old API, however they are forward compatible, and easy to 690use. If these meet your needs then go ahead and use them, but please check back 691often for alternatives that may be added. 692 693If you want to generate new style events, events that do many things at once, 694then you want the C<*ev2*> methods. These let you directly specify which facets 695you wish to use. 696 697=over 4 698 699=item $event = $ctx->pass() 700 701=item $event = $ctx->pass($name) 702 703This will send and return an L<Test2::Event::Pass> event. You may optionally 704provide a C<$name> for the assertion. 705 706The L<Test2::Event::Pass> is a specially crafted and optimized event, using 707this will help the performance of passing tests. 708 709=item $true = $ctx->pass_and_release() 710 711=item $true = $ctx->pass_and_release($name) 712 713This is a combination of C<pass()> and C<release()>. You can use this if you do 714not plan to do anything with the context after sending the event. This helps 715write more clear and compact code. 716 717 sub shorthand { 718 my ($bool, $name) = @_; 719 my $ctx = context(); 720 return $ctx->pass_and_release($name) if $bool; 721 722 ... Handle a failure ... 723 } 724 725 sub longform { 726 my ($bool, $name) = @_; 727 my $ctx = context(); 728 729 if ($bool) { 730 $ctx->pass($name); 731 $ctx->release; 732 return 1; 733 } 734 735 ... Handle a failure ... 736 } 737 738=item my $event = $ctx->fail() 739 740=item my $event = $ctx->fail($name) 741 742=item my $event = $ctx->fail($name, @diagnostics) 743 744This lets you send an L<Test2::Event::Fail> event. You may optionally provide a 745C<$name> and C<@diagnostics> messages. 746 747Diagnostics messages can be simple strings, data structures, or instances of 748L<Test2::EventFacet::Info::Table> (which are converted inline into the 749L<Test2::EventFacet::Info> structure). 750 751=item my $false = $ctx->fail_and_release() 752 753=item my $false = $ctx->fail_and_release($name) 754 755=item my $false = $ctx->fail_and_release($name, @diagnostics) 756 757This is a combination of C<fail()> and C<release()>. This can be used to write 758clearer and shorter code. 759 760 sub shorthand { 761 my ($bool, $name) = @_; 762 my $ctx = context(); 763 return $ctx->fail_and_release($name) unless $bool; 764 765 ... Handle a success ... 766 } 767 768 sub longform { 769 my ($bool, $name) = @_; 770 my $ctx = context(); 771 772 unless ($bool) { 773 $ctx->pass($name); 774 $ctx->release; 775 return 1; 776 } 777 778 ... Handle a success ... 779 } 780 781 782=item $event = $ctx->ok($bool, $name) 783 784=item $event = $ctx->ok($bool, $name, \@on_fail) 785 786B<NOTE:> Use of this method is discouraged in favor of C<pass()> and C<fail()> 787which produce L<Test2::Event::Pass> and L<Test2::Event::Fail> events. These 788newer event types are faster and less crufty. 789 790This will create an L<Test2::Event::Ok> object for you. If C<$bool> is false 791then an L<Test2::Event::Diag> event will be sent as well with details about the 792failure. If you do not want automatic diagnostics you should use the 793C<send_event()> method directly. 794 795The third argument C<\@on_fail>) is an optional set of diagnostics to be sent in 796the event of a test failure. Unlike with C<fail()> these diagnostics must be 797plain strings, data structures are not supported. 798 799=item $event = $ctx->note($message) 800 801Send an L<Test2::Event::Note>. This event prints a message to STDOUT. 802 803=item $event = $ctx->diag($message) 804 805Send an L<Test2::Event::Diag>. This event prints a message to STDERR. 806 807=item $event = $ctx->plan($max) 808 809=item $event = $ctx->plan(0, 'SKIP', $reason) 810 811This can be used to send an L<Test2::Event::Plan> event. This event 812usually takes either a number of tests you expect to run. Optionally you can 813set the expected count to 0 and give the 'SKIP' directive with a reason to 814cause all tests to be skipped. 815 816=item $event = $ctx->skip($name, $reason); 817 818Send an L<Test2::Event::Skip> event. 819 820=item $event = $ctx->bail($reason) 821 822This sends an L<Test2::Event::Bail> event. This event will completely 823terminate all testing. 824 825=item $event = $ctx->send_ev2(%facets) 826 827This lets you build and send a V2 event directly from facets. The event is 828returned after it is sent. 829 830This example sends a single assertion, a note (comment for stdout in 831Test::Builder talk) and sets the plan to 1. 832 833 my $event = $ctx->send_event( 834 plan => {count => 1}, 835 assert => {pass => 1, details => "A passing assert"}, 836 info => [{tag => 'NOTE', details => "This is a note"}], 837 ); 838 839=item $event = $ctx->build_e2(%facets) 840 841This is the same as C<send_ev2()>, except it builds and returns the event 842without sending it. 843 844=item $event = $ctx->send_ev2_and_release($Type, %parameters) 845 846This is a combination of C<send_ev2()> and C<release()>. 847 848 sub shorthand { 849 my $ctx = context(); 850 return $ctx->send_ev2_and_release(assert => {pass => 1, details => 'foo'}); 851 } 852 853 sub longform { 854 my $ctx = context(); 855 my $event = $ctx->send_ev2(assert => {pass => 1, details => 'foo'}); 856 $ctx->release; 857 return $event; 858 } 859 860=item $event = $ctx->send_event($Type, %parameters) 861 862B<It is better to use send_ev2() in new code.> 863 864This lets you build and send an event of any type. The C<$Type> argument should 865be the event package name with C<Test2::Event::> left off, or a fully 866qualified package name prefixed with a '+'. The event is returned after it is 867sent. 868 869 my $event = $ctx->send_event('Ok', ...); 870 871or 872 873 my $event = $ctx->send_event('+Test2::Event::Ok', ...); 874 875=item $event = $ctx->build_event($Type, %parameters) 876 877B<It is better to use build_ev2() in new code.> 878 879This is the same as C<send_event()>, except it builds and returns the event 880without sending it. 881 882=item $event = $ctx->send_event_and_release($Type, %parameters) 883 884B<It is better to use send_ev2_and_release() in new code.> 885 886This is a combination of C<send_event()> and C<release()>. 887 888 sub shorthand { 889 my $ctx = context(); 890 return $ctx->send_event_and_release(Pass => { name => 'foo' }); 891 } 892 893 sub longform { 894 my $ctx = context(); 895 my $event = $ctx->send_event(Pass => { name => 'foo' }); 896 $ctx->release; 897 return $event; 898 } 899 900=back 901 902=head1 HOOKS 903 904There are 2 types of hooks, init hooks, and release hooks. As the names 905suggest, these hooks are triggered when contexts are created or released. 906 907=head2 INIT HOOKS 908 909These are called whenever a context is initialized. That means when a new 910instance is created. These hooks are B<NOT> called every time something 911requests a context, just when a new one is created. 912 913=head3 GLOBAL 914 915This is how you add a global init callback. Global callbacks happen for every 916context for any hub or stack. 917 918 Test2::API::test2_add_callback_context_init(sub { 919 my $ctx = shift; 920 ... 921 }); 922 923=head3 PER HUB 924 925This is how you add an init callback for all contexts created for a given hub. 926These callbacks will not run for other hubs. 927 928 $hub->add_context_init(sub { 929 my $ctx = shift; 930 ... 931 }); 932 933=head3 PER CONTEXT 934 935This is how you specify an init hook that will only run if your call to 936C<context()> generates a new context. The callback will be ignored if 937C<context()> is returning an existing context. 938 939 my $ctx = context(on_init => sub { 940 my $ctx = shift; 941 ... 942 }); 943 944=head2 RELEASE HOOKS 945 946These are called whenever a context is released. That means when the last 947reference to the instance is about to be destroyed. These hooks are B<NOT> 948called every time C<< $ctx->release >> is called. 949 950=head3 GLOBAL 951 952This is how you add a global release callback. Global callbacks happen for every 953context for any hub or stack. 954 955 Test2::API::test2_add_callback_context_release(sub { 956 my $ctx = shift; 957 ... 958 }); 959 960=head3 PER HUB 961 962This is how you add a release callback for all contexts created for a given 963hub. These callbacks will not run for other hubs. 964 965 $hub->add_context_release(sub { 966 my $ctx = shift; 967 ... 968 }); 969 970=head3 PER CONTEXT 971 972This is how you add release callbacks directly to a context. The callback will 973B<ALWAYS> be added to the context that gets returned, it does not matter if a 974new one is generated, or if an existing one is returned. 975 976 my $ctx = context(on_release => sub { 977 my $ctx = shift; 978 ... 979 }); 980 981=head1 THIRD PARTY META-DATA 982 983This object consumes L<Test2::Util::ExternalMeta> which provides a consistent 984way for you to attach meta-data to instances of this class. This is useful for 985tools, plugins, and other extensions. 986 987=head1 SOURCE 988 989The source code repository for Test2 can be found at 990F<http://github.com/Test-More/test-more/>. 991 992=head1 MAINTAINERS 993 994=over 4 995 996=item Chad Granum E<lt>exodist@cpan.orgE<gt> 997 998=back 999 1000=head1 AUTHORS 1001 1002=over 4 1003 1004=item Chad Granum E<lt>exodist@cpan.orgE<gt> 1005 1006=item Kent Fredric E<lt>kentnl@cpan.orgE<gt> 1007 1008=back 1009 1010=head1 COPYRIGHT 1011 1012Copyright 2020 Chad Granum E<lt>exodist@cpan.orgE<gt>. 1013 1014This program is free software; you can redistribute it and/or 1015modify it under the same terms as Perl itself. 1016 1017See F<http://dev.perl.org/licenses/> 1018 1019=cut 1020