diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:43:11 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:43:11 +0000 |
commit | fc22b3d6507c6745911b9dfcc68f1e665ae13dbc (patch) | |
tree | ce1e3bce06471410239a6f41282e328770aa404a /upstream/debian-unstable/man3/Test2::API::Context.3perl | |
parent | Initial commit. (diff) | |
download | manpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.tar.xz manpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.zip |
Adding upstream version 4.22.0.upstream/4.22.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'upstream/debian-unstable/man3/Test2::API::Context.3perl')
-rw-r--r-- | upstream/debian-unstable/man3/Test2::API::Context.3perl | 611 |
1 files changed, 611 insertions, 0 deletions
diff --git a/upstream/debian-unstable/man3/Test2::API::Context.3perl b/upstream/debian-unstable/man3/Test2::API::Context.3perl new file mode 100644 index 00000000..2a1febab --- /dev/null +++ b/upstream/debian-unstable/man3/Test2::API::Context.3perl @@ -0,0 +1,611 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. +.ie n \{\ +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{\ +. if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" ======================================================================== +.\" +.IX Title "Test2::API::Context 3perl" +.TH Test2::API::Context 3perl 2024-01-12 "perl v5.38.2" "Perl Programmers Reference Guide" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH NAME +Test2::API::Context \- Object to represent a testing context. +.SH DESCRIPTION +.IX Header "DESCRIPTION" +The context object is the primary interface for authors of testing tools +written with Test2. The context object represents the context in +which a test takes place (File and Line Number), and provides a quick way to +generate events from that context. The context object also takes care of +sending events to the correct Test2::Hub instance. +.SH SYNOPSIS +.IX Header "SYNOPSIS" +In general you will not be creating contexts directly. To obtain a context you +should always use \f(CWcontext()\fR which is exported by the Test2::API module. +.PP +.Vb 1 +\& use Test2::API qw/context/; +\& +\& sub my_ok { +\& my ($bool, $name) = @_; +\& my $ctx = context(); +\& +\& if ($bool) { +\& $ctx\->pass($name); +\& } +\& else { +\& $ctx\->fail($name); +\& } +\& +\& $ctx\->release; # You MUST do this! +\& return $bool; +\& } +.Ve +.PP +Context objects make it easy to wrap other tools that also use context. Once +you grab a context, any tool you call before releasing your context will +inherit it: +.PP +.Vb 4 +\& sub wrapper { +\& my ($bool, $name) = @_; +\& my $ctx = context(); +\& $ctx\->diag("wrapping my_ok"); +\& +\& my $out = my_ok($bool, $name); +\& $ctx\->release; # You MUST do this! +\& return $out; +\& } +.Ve +.SH "CRITICAL DETAILS" +.IX Header "CRITICAL DETAILS" +.IP "you MUST always use the \fBcontext()\fR sub from Test2::API" 4 +.IX Item "you MUST always use the context() sub from Test2::API" +Creating your own context via \f(CW\*(C`Test2::API::Context\->new()\*(C'\fR will almost never +produce a desirable result. Use \f(CWcontext()\fR which is exported by Test2::API. +.Sp +There are a handful of cases where a tool author may want to create a new +context by hand, which is why the \f(CW\*(C`new\*(C'\fR method exists. Unless you really know +what you are doing you should avoid this. +.IP "You MUST always release the context when done with it" 4 +.IX Item "You MUST always release the context when done with it" +Releasing the context tells the system you are done with it. This gives it a +chance to run any necessary callbacks or cleanup tasks. If you forget to +release the context it will try to detect the problem and warn you about it. +.IP "You MUST NOT pass context objects around" 4 +.IX Item "You MUST NOT pass context objects around" +When you obtain a context object it is made specifically for your tool and any +tools nested within. If you pass a context around you run the risk of polluting +other tools with incorrect context information. +.Sp +If you are certain that you want a different tool to use the same context you +may pass it a snapshot. \f(CW\*(C`$ctx\->snapshot\*(C'\fR will give you a shallow clone of +the context that is safe to pass around or store. +.IP "You MUST NOT store or cache a context for later" 4 +.IX Item "You MUST NOT store or cache a context for later" +As long as a context exists for a given hub, all tools that try to get a +context will get the existing instance. If you try to store the context you +will pollute other tools with incorrect context information. +.Sp +If you are certain that you want to save the context for later, you can use a +snapshot. \f(CW\*(C`$ctx\->snapshot\*(C'\fR will give you a shallow clone of the context +that is safe to pass around or store. +.Sp +\&\f(CWcontext()\fR has some mechanisms to protect you if you do cause a context to +persist beyond the scope in which it was obtained. In practice you should not +rely on these protections, and they are fairly noisy with warnings. +.IP "You SHOULD obtain your context as soon as possible in a given tool" 4 +.IX Item "You SHOULD obtain your context as soon as possible in a given tool" +You never know what tools you call from within your own tool will need a +context. Obtaining the context early ensures that nested tools can find the +context you want them to find. +.SH METHODS +.IX Header "METHODS" +.ie n .IP $ctx\->done_testing; 4 +.el .IP \f(CW$ctx\fR\->done_testing; 4 +.IX Item "$ctx->done_testing;" +Note that testing is finished. If no plan has been set this will generate a +Plan event. +.ie n .IP "$clone = $ctx\->\fBsnapshot()\fR" 4 +.el .IP "\f(CW$clone\fR = \f(CW$ctx\fR\->\fBsnapshot()\fR" 4 +.IX Item "$clone = $ctx->snapshot()" +This will return a shallow clone of the context. The shallow clone is safe to +store for later. +.ie n .IP $ctx\->\fBrelease()\fR 4 +.el .IP \f(CW$ctx\fR\->\fBrelease()\fR 4 +.IX Item "$ctx->release()" +This will release the context. This runs cleanup tasks, and several important +hooks. It will also restore \f(CW$!\fR, \f(CW$?\fR, and \f(CW$@\fR to what they were when the +context was created. +.Sp +\&\fBNote:\fR If a context is acquired more than once an internal refcount is kept. +\&\f(CWrelease()\fR decrements the ref count, none of the other actions of +\&\f(CWrelease()\fR will occur unless the refcount hits 0. This means only the last +call to \f(CWrelease()\fR will reset \f(CW$?\fR, \f(CW$!\fR, \f(CW$@\fR,and run the cleanup tasks. +.ie n .IP $ctx\->throw($message) 4 +.el .IP \f(CW$ctx\fR\->throw($message) 4 +.IX Item "$ctx->throw($message)" +This will throw an exception reporting to the file and line number of the +context. This will also release the context for you. +.ie n .IP $ctx\->alert($message) 4 +.el .IP \f(CW$ctx\fR\->alert($message) 4 +.IX Item "$ctx->alert($message)" +This will issue a warning from the file and line number of the context. +.ie n .IP "$stack = $ctx\->\fBstack()\fR" 4 +.el .IP "\f(CW$stack\fR = \f(CW$ctx\fR\->\fBstack()\fR" 4 +.IX Item "$stack = $ctx->stack()" +This will return the Test2::API::Stack instance the context used to find +the current hub. +.ie n .IP "$hub = $ctx\->\fBhub()\fR" 4 +.el .IP "\f(CW$hub\fR = \f(CW$ctx\fR\->\fBhub()\fR" 4 +.IX Item "$hub = $ctx->hub()" +This will return the Test2::Hub instance the context recognizes as the +current one to which all events should be sent. +.ie n .IP "$dbg = $ctx\->\fBtrace()\fR" 4 +.el .IP "\f(CW$dbg\fR = \f(CW$ctx\fR\->\fBtrace()\fR" 4 +.IX Item "$dbg = $ctx->trace()" +This will return the Test2::EventFacet::Trace instance used by the context. +.ie n .IP "$ctx\->do_in_context(\e&code, @args);" 4 +.el .IP "\f(CW$ctx\fR\->do_in_context(\e&code, \f(CW@args\fR);" 4 +.IX Item "$ctx->do_in_context(&code, @args);" +Sometimes you have a context that is not current, and you want things to use it +as the current one. In these cases you can call +\&\f(CW\*(C`$ctx\->do_in_context(sub { ... })\*(C'\fR. The codeblock will be run, and +anything inside of it that looks for a context will find the one on which the +method was called. +.Sp +This \fBDOES NOT\fR affect context on other hubs, only the hub used by the context +will be affected. +.Sp +.Vb 4 +\& my $ctx = ...; +\& $ctx\->do_in_context(sub { +\& my $ctx = context(); # returns the $ctx the sub is called on +\& }); +.Ve +.Sp +\&\fBNote:\fR The context will actually be cloned, the clone will be used instead of +the original. This allows the thread id, process id, and error variables to be correct without +modifying the original context. +.ie n .IP $ctx\->\fBrestore_error_vars()\fR 4 +.el .IP \f(CW$ctx\fR\->\fBrestore_error_vars()\fR 4 +.IX Item "$ctx->restore_error_vars()" +This will set \f(CW$!\fR, \f(CW$?\fR, and \f(CW$@\fR to what they were when the context was +created. There is no localization or anything done here, calling this method +will actually set these vars. +.ie n .IP "$! = $ctx\->\fBerrno()\fR" 4 +.el .IP "$! = \f(CW$ctx\fR\->\fBerrno()\fR" 4 +.IX Item "$! = $ctx->errno()" +The (numeric) value of \f(CW$!\fR when the context was created. +.ie n .IP "$? = $ctx\->\fBchild_error()\fR" 4 +.el .IP "$? = \f(CW$ctx\fR\->\fBchild_error()\fR" 4 +.IX Item "$? = $ctx->child_error()" +The value of \f(CW$?\fR when the context was created. +.ie n .IP "$@ = $ctx\->\fBeval_error()\fR" 4 +.el .IP "$@ = \f(CW$ctx\fR\->\fBeval_error()\fR" 4 +.IX Item "$@ = $ctx->eval_error()" +The value of \f(CW$@\fR when the context was created. +.SS "EVENT PRODUCTION METHODS" +.IX Subsection "EVENT PRODUCTION METHODS" +\&\fBWhich one do I use?\fR +.PP +The \f(CW\*(C`pass*\*(C'\fR and \f(CW\*(C`fail*\*(C'\fR are optimal if they meet your situation, using one of +them will always be the most optimal. That said they are optimal by eliminating +many features. +.PP +Method such as \f(CW\*(C`ok\*(C'\fR, and \f(CW\*(C`note\*(C'\fR are shortcuts for generating common 1\-task +events based on the old API, however they are forward compatible, and easy to +use. If these meet your needs then go ahead and use them, but please check back +often for alternatives that may be added. +.PP +If you want to generate new style events, events that do many things at once, +then you want the \f(CW\*(C`*ev2*\*(C'\fR methods. These let you directly specify which facets +you wish to use. +.ie n .IP "$event = $ctx\->\fBpass()\fR" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->\fBpass()\fR" 4 +.IX Item "$event = $ctx->pass()" +.PD 0 +.ie n .IP "$event = $ctx\->pass($name)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->pass($name)" 4 +.IX Item "$event = $ctx->pass($name)" +.PD +This will send and return an Test2::Event::Pass event. You may optionally +provide a \f(CW$name\fR for the assertion. +.Sp +The Test2::Event::Pass is a specially crafted and optimized event, using +this will help the performance of passing tests. +.ie n .IP "$true = $ctx\->\fBpass_and_release()\fR" 4 +.el .IP "\f(CW$true\fR = \f(CW$ctx\fR\->\fBpass_and_release()\fR" 4 +.IX Item "$true = $ctx->pass_and_release()" +.PD 0 +.ie n .IP "$true = $ctx\->pass_and_release($name)" 4 +.el .IP "\f(CW$true\fR = \f(CW$ctx\fR\->pass_and_release($name)" 4 +.IX Item "$true = $ctx->pass_and_release($name)" +.PD +This is a combination of \f(CWpass()\fR and \f(CWrelease()\fR. You can use this if you do +not plan to do anything with the context after sending the event. This helps +write more clear and compact code. +.Sp +.Vb 4 +\& sub shorthand { +\& my ($bool, $name) = @_; +\& my $ctx = context(); +\& return $ctx\->pass_and_release($name) if $bool; +\& +\& ... Handle a failure ... +\& } +\& +\& sub longform { +\& my ($bool, $name) = @_; +\& my $ctx = context(); +\& +\& if ($bool) { +\& $ctx\->pass($name); +\& $ctx\->release; +\& return 1; +\& } +\& +\& ... Handle a failure ... +\& } +.Ve +.ie n .IP "my $event = $ctx\->\fBfail()\fR" 4 +.el .IP "my \f(CW$event\fR = \f(CW$ctx\fR\->\fBfail()\fR" 4 +.IX Item "my $event = $ctx->fail()" +.PD 0 +.ie n .IP "my $event = $ctx\->fail($name)" 4 +.el .IP "my \f(CW$event\fR = \f(CW$ctx\fR\->fail($name)" 4 +.IX Item "my $event = $ctx->fail($name)" +.ie n .IP "my $event = $ctx\->fail($name, @diagnostics)" 4 +.el .IP "my \f(CW$event\fR = \f(CW$ctx\fR\->fail($name, \f(CW@diagnostics\fR)" 4 +.IX Item "my $event = $ctx->fail($name, @diagnostics)" +.PD +This lets you send an Test2::Event::Fail event. You may optionally provide a +\&\f(CW$name\fR and \f(CW@diagnostics\fR messages. +.Sp +Diagnostics messages can be simple strings, data structures, or instances of +Test2::EventFacet::Info::Table (which are converted inline into the +Test2::EventFacet::Info structure). +.ie n .IP "my $false = $ctx\->\fBfail_and_release()\fR" 4 +.el .IP "my \f(CW$false\fR = \f(CW$ctx\fR\->\fBfail_and_release()\fR" 4 +.IX Item "my $false = $ctx->fail_and_release()" +.PD 0 +.ie n .IP "my $false = $ctx\->fail_and_release($name)" 4 +.el .IP "my \f(CW$false\fR = \f(CW$ctx\fR\->fail_and_release($name)" 4 +.IX Item "my $false = $ctx->fail_and_release($name)" +.ie n .IP "my $false = $ctx\->fail_and_release($name, @diagnostics)" 4 +.el .IP "my \f(CW$false\fR = \f(CW$ctx\fR\->fail_and_release($name, \f(CW@diagnostics\fR)" 4 +.IX Item "my $false = $ctx->fail_and_release($name, @diagnostics)" +.PD +This is a combination of \f(CWfail()\fR and \f(CWrelease()\fR. This can be used to write +clearer and shorter code. +.Sp +.Vb 4 +\& sub shorthand { +\& my ($bool, $name) = @_; +\& my $ctx = context(); +\& return $ctx\->fail_and_release($name) unless $bool; +\& +\& ... Handle a success ... +\& } +\& +\& sub longform { +\& my ($bool, $name) = @_; +\& my $ctx = context(); +\& +\& unless ($bool) { +\& $ctx\->pass($name); +\& $ctx\->release; +\& return 1; +\& } +\& +\& ... Handle a success ... +\& } +.Ve +.ie n .IP "$event = $ctx\->ok($bool, $name)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->ok($bool, \f(CW$name\fR)" 4 +.IX Item "$event = $ctx->ok($bool, $name)" +.PD 0 +.ie n .IP "$event = $ctx\->ok($bool, $name, \e@on_fail)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->ok($bool, \f(CW$name\fR, \e@on_fail)" 4 +.IX Item "$event = $ctx->ok($bool, $name, @on_fail)" +.PD +\&\fBNOTE:\fR Use of this method is discouraged in favor of \f(CWpass()\fR and \f(CWfail()\fR +which produce Test2::Event::Pass and Test2::Event::Fail events. These +newer event types are faster and less crufty. +.Sp +This will create an Test2::Event::Ok object for you. If \f(CW$bool\fR is false +then an Test2::Event::Diag event will be sent as well with details about the +failure. If you do not want automatic diagnostics you should use the +\&\f(CWsend_event()\fR method directly. +.Sp +The third argument \f(CW\*(C`\e@on_fail\*(C'\fR) is an optional set of diagnostics to be sent in +the event of a test failure. Unlike with \f(CWfail()\fR these diagnostics must be +plain strings, data structures are not supported. +.ie n .IP "$event = $ctx\->note($message)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->note($message)" 4 +.IX Item "$event = $ctx->note($message)" +Send an Test2::Event::Note. This event prints a message to STDOUT. +.ie n .IP "$event = $ctx\->diag($message)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->diag($message)" 4 +.IX Item "$event = $ctx->diag($message)" +Send an Test2::Event::Diag. This event prints a message to STDERR. +.ie n .IP "$event = $ctx\->plan($max)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->plan($max)" 4 +.IX Item "$event = $ctx->plan($max)" +.PD 0 +.ie n .IP "$event = $ctx\->plan(0, 'SKIP', $reason)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->plan(0, 'SKIP', \f(CW$reason\fR)" 4 +.IX Item "$event = $ctx->plan(0, 'SKIP', $reason)" +.PD +This can be used to send an Test2::Event::Plan event. This event +usually takes either a number of tests you expect to run. Optionally you can +set the expected count to 0 and give the 'SKIP' directive with a reason to +cause all tests to be skipped. +.ie n .IP "$event = $ctx\->skip($name, $reason);" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->skip($name, \f(CW$reason\fR);" 4 +.IX Item "$event = $ctx->skip($name, $reason);" +Send an Test2::Event::Skip event. +.ie n .IP "$event = $ctx\->bail($reason)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->bail($reason)" 4 +.IX Item "$event = $ctx->bail($reason)" +This sends an Test2::Event::Bail event. This event will completely +terminate all testing. +.ie n .IP "$event = $ctx\->send_ev2(%facets)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->send_ev2(%facets)" 4 +.IX Item "$event = $ctx->send_ev2(%facets)" +This lets you build and send a V2 event directly from facets. The event is +returned after it is sent. +.Sp +This example sends a single assertion, a note (comment for stdout in +Test::Builder talk) and sets the plan to 1. +.Sp +.Vb 5 +\& my $event = $ctx\->send_event( +\& plan => {count => 1}, +\& assert => {pass => 1, details => "A passing assert"}, +\& info => [{tag => \*(AqNOTE\*(Aq, details => "This is a note"}], +\& ); +.Ve +.ie n .IP "$event = $ctx\->build_e2(%facets)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->build_e2(%facets)" 4 +.IX Item "$event = $ctx->build_e2(%facets)" +This is the same as \f(CWsend_ev2()\fR, except it builds and returns the event +without sending it. +.ie n .IP "$event = $ctx\->send_ev2_and_release($Type, %parameters)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->send_ev2_and_release($Type, \f(CW%parameters\fR)" 4 +.IX Item "$event = $ctx->send_ev2_and_release($Type, %parameters)" +This is a combination of \f(CWsend_ev2()\fR and \f(CWrelease()\fR. +.Sp +.Vb 4 +\& sub shorthand { +\& my $ctx = context(); +\& return $ctx\->send_ev2_and_release(assert => {pass => 1, details => \*(Aqfoo\*(Aq}); +\& } +\& +\& sub longform { +\& my $ctx = context(); +\& my $event = $ctx\->send_ev2(assert => {pass => 1, details => \*(Aqfoo\*(Aq}); +\& $ctx\->release; +\& return $event; +\& } +.Ve +.ie n .IP "$event = $ctx\->send_event($Type, %parameters)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->send_event($Type, \f(CW%parameters\fR)" 4 +.IX Item "$event = $ctx->send_event($Type, %parameters)" +\&\fBIt is better to use send_ev2() in new code.\fR +.Sp +This lets you build and send an event of any type. The \f(CW$Type\fR argument should +be the event package name with \f(CW\*(C`Test2::Event::\*(C'\fR left off, or a fully +qualified package name prefixed with a '+'. The event is returned after it is +sent. +.Sp +.Vb 1 +\& my $event = $ctx\->send_event(\*(AqOk\*(Aq, ...); +.Ve +.Sp +or +.Sp +.Vb 1 +\& my $event = $ctx\->send_event(\*(Aq+Test2::Event::Ok\*(Aq, ...); +.Ve +.ie n .IP "$event = $ctx\->build_event($Type, %parameters)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->build_event($Type, \f(CW%parameters\fR)" 4 +.IX Item "$event = $ctx->build_event($Type, %parameters)" +\&\fBIt is better to use build_ev2() in new code.\fR +.Sp +This is the same as \f(CWsend_event()\fR, except it builds and returns the event +without sending it. +.ie n .IP "$event = $ctx\->send_event_and_release($Type, %parameters)" 4 +.el .IP "\f(CW$event\fR = \f(CW$ctx\fR\->send_event_and_release($Type, \f(CW%parameters\fR)" 4 +.IX Item "$event = $ctx->send_event_and_release($Type, %parameters)" +\&\fBIt is better to use send_ev2_and_release() in new code.\fR +.Sp +This is a combination of \f(CWsend_event()\fR and \f(CWrelease()\fR. +.Sp +.Vb 4 +\& sub shorthand { +\& my $ctx = context(); +\& return $ctx\->send_event_and_release(Pass => { name => \*(Aqfoo\*(Aq }); +\& } +\& +\& sub longform { +\& my $ctx = context(); +\& my $event = $ctx\->send_event(Pass => { name => \*(Aqfoo\*(Aq }); +\& $ctx\->release; +\& return $event; +\& } +.Ve +.SH HOOKS +.IX Header "HOOKS" +There are 2 types of hooks, init hooks, and release hooks. As the names +suggest, these hooks are triggered when contexts are created or released. +.SS "INIT HOOKS" +.IX Subsection "INIT HOOKS" +These are called whenever a context is initialized. That means when a new +instance is created. These hooks are \fBNOT\fR called every time something +requests a context, just when a new one is created. +.PP +\fIGLOBAL\fR +.IX Subsection "GLOBAL" +.PP +This is how you add a global init callback. Global callbacks happen for every +context for any hub or stack. +.PP +.Vb 4 +\& Test2::API::test2_add_callback_context_init(sub { +\& my $ctx = shift; +\& ... +\& }); +.Ve +.PP +\fIPER HUB\fR +.IX Subsection "PER HUB" +.PP +This is how you add an init callback for all contexts created for a given hub. +These callbacks will not run for other hubs. +.PP +.Vb 4 +\& $hub\->add_context_init(sub { +\& my $ctx = shift; +\& ... +\& }); +.Ve +.PP +\fIPER CONTEXT\fR +.IX Subsection "PER CONTEXT" +.PP +This is how you specify an init hook that will only run if your call to +\&\f(CWcontext()\fR generates a new context. The callback will be ignored if +\&\f(CWcontext()\fR is returning an existing context. +.PP +.Vb 4 +\& my $ctx = context(on_init => sub { +\& my $ctx = shift; +\& ... +\& }); +.Ve +.SS "RELEASE HOOKS" +.IX Subsection "RELEASE HOOKS" +These are called whenever a context is released. That means when the last +reference to the instance is about to be destroyed. These hooks are \fBNOT\fR +called every time \f(CW\*(C`$ctx\->release\*(C'\fR is called. +.PP +\fIGLOBAL\fR +.IX Subsection "GLOBAL" +.PP +This is how you add a global release callback. Global callbacks happen for every +context for any hub or stack. +.PP +.Vb 4 +\& Test2::API::test2_add_callback_context_release(sub { +\& my $ctx = shift; +\& ... +\& }); +.Ve +.PP +\fIPER HUB\fR +.IX Subsection "PER HUB" +.PP +This is how you add a release callback for all contexts created for a given +hub. These callbacks will not run for other hubs. +.PP +.Vb 4 +\& $hub\->add_context_release(sub { +\& my $ctx = shift; +\& ... +\& }); +.Ve +.PP +\fIPER CONTEXT\fR +.IX Subsection "PER CONTEXT" +.PP +This is how you add release callbacks directly to a context. The callback will +\&\fBALWAYS\fR be added to the context that gets returned, it does not matter if a +new one is generated, or if an existing one is returned. +.PP +.Vb 4 +\& my $ctx = context(on_release => sub { +\& my $ctx = shift; +\& ... +\& }); +.Ve +.SH "THIRD PARTY META-DATA" +.IX Header "THIRD PARTY META-DATA" +This object consumes Test2::Util::ExternalMeta which provides a consistent +way for you to attach meta-data to instances of this class. This is useful for +tools, plugins, and other extensions. +.SH SOURCE +.IX Header "SOURCE" +The source code repository for Test2 can be found at +\&\fIhttp://github.com/Test\-More/test\-more/\fR. +.SH MAINTAINERS +.IX Header "MAINTAINERS" +.IP "Chad Granum <exodist@cpan.org>" 4 +.IX Item "Chad Granum <exodist@cpan.org>" +.SH AUTHORS +.IX Header "AUTHORS" +.PD 0 +.IP "Chad Granum <exodist@cpan.org>" 4 +.IX Item "Chad Granum <exodist@cpan.org>" +.IP "Kent Fredric <kentnl@cpan.org>" 4 +.IX Item "Kent Fredric <kentnl@cpan.org>" +.PD +.SH COPYRIGHT +.IX Header "COPYRIGHT" +Copyright 2020 Chad Granum <exodist@cpan.org>. +.PP +This program is free software; you can redistribute it and/or +modify it under the same terms as Perl itself. +.PP +See \fIhttp://dev.perl.org/licenses/\fR |