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