1Test2::API::Context(3)User Contributed Perl DocumentationTest2::API::Context(3)
2
3
4

NAME

6       Test2::API::Context - Object to represent a testing context.
7

DESCRIPTION

9       The context object is the primary interface for authors of testing
10       tools written with Test2. The context object represents the context in
11       which a test takes place (File and Line Number), and provides a quick
12       way to generate events from that context. The context object also takes
13       care of sending events to the correct Test2::Hub instance.
14

SYNOPSIS

16       In general you will not be creating contexts directly. To obtain a
17       context you should always use "context()" which is exported by the
18       Test2::API module.
19
20           use Test2::API qw/context/;
21
22           sub my_ok {
23               my ($bool, $name) = @_;
24               my $ctx = context();
25
26               if ($bool) {
27                   $ctx->pass($name);
28               }
29               else {
30                   $ctx->fail($name);
31               }
32
33               $ctx->release; # You MUST do this!
34               return $bool;
35           }
36
37       Context objects make it easy to wrap other tools that also use context.
38       Once you grab a context, any tool you call before releasing your
39       context will inherit it:
40
41           sub wrapper {
42               my ($bool, $name) = @_;
43               my $ctx = context();
44               $ctx->diag("wrapping my_ok");
45
46               my $out = my_ok($bool, $name);
47               $ctx->release; # You MUST do this!
48               return $out;
49           }
50

CRITICAL DETAILS

52       you MUST always use the context() sub from Test2::API
53           Creating your own context via "Test2::API::Context->new()" will
54           almost never produce a desirable result. Use "context()" which is
55           exported by Test2::API.
56
57           There are a handful of cases where a tool author may want to create
58           a new context by hand, which is why the "new" method exists. Unless
59           you really know what you are doing you should avoid this.
60
61       You MUST always release the context when done with it
62           Releasing the context tells the system you are done with it. This
63           gives it a chance to run any necessary callbacks or cleanup tasks.
64           If you forget to release the context it will try to detect the
65           problem and warn you about it.
66
67       You MUST NOT pass context objects around
68           When you obtain a context object it is made specifically for your
69           tool and any tools nested within. If you pass a context around you
70           run the risk of polluting other tools with incorrect context
71           information.
72
73           If you are certain that you want a different tool to use the same
74           context you may pass it a snapshot. "$ctx->snapshot" will give you
75           a shallow clone of the context that is safe to pass around or
76           store.
77
78       You MUST NOT store or cache a context for later
79           As long as a context exists for a given hub, all tools that try to
80           get a context will get the existing instance. If you try to store
81           the context you will pollute other tools with incorrect context
82           information.
83
84           If you are certain that you want to save the context for later, you
85           can use a snapshot. "$ctx->snapshot" will give you a shallow clone
86           of the context that is safe to pass around or store.
87
88           "context()" has some mechanisms to protect you if you do cause a
89           context to persist beyond the scope in which it was obtained. In
90           practice you should not rely on these protections, and they are
91           fairly noisy with warnings.
92
93       You SHOULD obtain your context as soon as possible in a given tool
94           You never know what tools you call from within your own tool will
95           need a context. Obtaining the context early ensures that nested
96           tools can find the context you want them to find.
97

METHODS

99       $ctx->done_testing;
100           Note that testing is finished. If no plan has been set this will
101           generate a Plan event.
102
103       $clone = $ctx->snapshot()
104           This will return a shallow clone of the context. The shallow clone
105           is safe to store for later.
106
107       $ctx->release()
108           This will release the context. This runs cleanup tasks, and several
109           important hooks. It will also restore $!, $?, and $@ to what they
110           were when the context was created.
111
112           Note: If a context is acquired more than once an internal refcount
113           is kept.  "release()" decrements the ref count, none of the other
114           actions of "release()" will occur unless the refcount hits 0. This
115           means only the last call to "release()" will reset $?, $!, $@,and
116           run the cleanup tasks.
117
118       $ctx->throw($message)
119           This will throw an exception reporting to the file and line number
120           of the context. This will also release the context for you.
121
122       $ctx->alert($message)
123           This will issue a warning from the file and line number of the
124           context.
125
126       $stack = $ctx->stack()
127           This will return the Test2::API::Stack instance the context used to
128           find the current hub.
129
130       $hub = $ctx->hub()
131           This will return the Test2::Hub instance the context recognizes as
132           the current one to which all events should be sent.
133
134       $dbg = $ctx->trace()
135           This will return the Test2::EventFacet::Trace instance used by the
136           context.
137
138       $ctx->do_in_context(\&code, @args);
139           Sometimes you have a context that is not current, and you want
140           things to use it as the current one. In these cases you can call
141           "$ctx->do_in_context(sub { ... })". The codeblock will be run, and
142           anything inside of it that looks for a context will find the one on
143           which the method was called.
144
145           This DOES NOT affect context on other hubs, only the hub used by
146           the context will be affected.
147
148               my $ctx = ...;
149               $ctx->do_in_context(sub {
150                   my $ctx = context(); # returns the $ctx the sub is called on
151               });
152
153           Note: The context will actually be cloned, the clone will be used
154           instead of the original. This allows the thread id, process id, and
155           error variables to be correct without modifying the original
156           context.
157
158       $ctx->restore_error_vars()
159           This will set $!, $?, and $@ to what they were when the context was
160           created. There is no localization or anything done here, calling
161           this method will actually set these vars.
162
163       $! = $ctx->errno()
164           The (numeric) value of $! when the context was created.
165
166       $? = $ctx->child_error()
167           The value of $? when the context was created.
168
169       $@ = $ctx->eval_error()
170           The value of $@ when the context was created.
171
172   EVENT PRODUCTION METHODS
173       Which one do I use?
174
175       The "pass*" and "fail*" are optimal if they meet your situation, using
176       one of them will always be the most optimal. That said they are optimal
177       by eliminating many features.
178
179       Method such as "ok", and "note" are shortcuts for generating common
180       1-task events based on the old API, however they are forward
181       compatible, and easy to use. If these meet your needs then go ahead and
182       use them, but please check back often for alternatives that may be
183       added.
184
185       If you want to generate new style events, events that do many things at
186       once, then you want the "*ev2*" methods. These let you directly specify
187       which facets you wish to use.
188
189       $event = $ctx->pass()
190       $event = $ctx->pass($name)
191           This will send and return an Test2::Event::Pass event. You may
192           optionally provide a $name for the assertion.
193
194           The Test2::Event::Pass is a specially crafted and optimized event,
195           using this will help the performance of passing tests.
196
197       $true = $ctx->pass_and_release()
198       $true = $ctx->pass_and_release($name)
199           This is a combination of "pass()" and "release()". You can use this
200           if you do not plan to do anything with the context after sending
201           the event. This helps write more clear and compact code.
202
203               sub shorthand {
204                   my ($bool, $name) = @_;
205                   my $ctx = context();
206                   return $ctx->pass_and_release($name) if $bool;
207
208                   ... Handle a failure ...
209               }
210
211               sub longform {
212                   my ($bool, $name) = @_;
213                   my $ctx = context();
214
215                   if ($bool) {
216                       $ctx->pass($name);
217                       $ctx->release;
218                       return 1;
219                   }
220
221                   ... Handle a failure ...
222               }
223
224       my $event = $ctx->fail()
225       my $event = $ctx->fail($name)
226       my $event = $ctx->fail($name, @diagnostics)
227           This lets you send an Test2::Event::Fail event. You may optionally
228           provide a $name and @diagnostics messages.
229
230           Diagnostics messages can be simple strings, data structures, or
231           instances of Test2::EventFacet::Info::Table (which are converted
232           inline into the Test2::EventFacet::Info structure).
233
234       my $false = $ctx->fail_and_release()
235       my $false = $ctx->fail_and_release($name)
236       my $false = $ctx->fail_and_release($name, @diagnostics)
237           This is a combination of "fail()" and "release()". This can be used
238           to write clearer and shorter code.
239
240               sub shorthand {
241                   my ($bool, $name) = @_;
242                   my $ctx = context();
243                   return $ctx->fail_and_release($name) unless $bool;
244
245                   ... Handle a success ...
246               }
247
248               sub longform {
249                   my ($bool, $name) = @_;
250                   my $ctx = context();
251
252                   unless ($bool) {
253                       $ctx->pass($name);
254                       $ctx->release;
255                       return 1;
256                   }
257
258                   ... Handle a success ...
259               }
260
261       $event = $ctx->ok($bool, $name)
262       $event = $ctx->ok($bool, $name, \@on_fail)
263           NOTE: Use of this method is discouraged in favor of "pass()" and
264           "fail()" which produce Test2::Event::Pass and Test2::Event::Fail
265           events. These newer event types are faster and less crufty.
266
267           This will create an Test2::Event::Ok object for you. If $bool is
268           false then an Test2::Event::Diag event will be sent as well with
269           details about the failure. If you do not want automatic diagnostics
270           you should use the "send_event()" method directly.
271
272           The third argument "\@on_fail") is an optional set of diagnostics
273           to be sent in the event of a test failure. Unlike with "fail()"
274           these diagnostics must be plain strings, data structures are not
275           supported.
276
277       $event = $ctx->note($message)
278           Send an Test2::Event::Note. This event prints a message to STDOUT.
279
280       $event = $ctx->diag($message)
281           Send an Test2::Event::Diag. This event prints a message to STDERR.
282
283       $event = $ctx->plan($max)
284       $event = $ctx->plan(0, 'SKIP', $reason)
285           This can be used to send an Test2::Event::Plan event. This event
286           usually takes either a number of tests you expect to run.
287           Optionally you can set the expected count to 0 and give the 'SKIP'
288           directive with a reason to cause all tests to be skipped.
289
290       $event = $ctx->skip($name, $reason);
291           Send an Test2::Event::Skip event.
292
293       $event = $ctx->bail($reason)
294           This sends an Test2::Event::Bail event. This event will completely
295           terminate all testing.
296
297       $event = $ctx->send_ev2(%facets)
298           This lets you build and send a V2 event directly from facets. The
299           event is returned after it is sent.
300
301           This example sends a single assertion, a note (comment for stdout
302           in Test::Builder talk) and sets the plan to 1.
303
304               my $event = $ctx->send_event(
305                   plan   => {count => 1},
306                   assert => {pass  => 1, details => "A passing assert"},
307                   info => [{tag => 'NOTE', details => "This is a note"}],
308               );
309
310       $event = $ctx->build_e2(%facets)
311           This is the same as "send_ev2()", except it builds and returns the
312           event without sending it.
313
314       $event = $ctx->send_ev2_and_release($Type, %parameters)
315           This is a combination of "send_ev2()" and "release()".
316
317               sub shorthand {
318                   my $ctx = context();
319                   return $ctx->send_ev2_and_release(assert => {pass => 1, details => 'foo'});
320               }
321
322               sub longform {
323                   my $ctx = context();
324                   my $event = $ctx->send_ev2(assert => {pass => 1, details => 'foo'});
325                   $ctx->release;
326                   return $event;
327               }
328
329       $event = $ctx->send_event($Type, %parameters)
330           It is better to use send_ev2() in new code.
331
332           This lets you build and send an event of any type. The $Type
333           argument should be the event package name with "Test2::Event::"
334           left off, or a fully qualified package name prefixed with a '+'.
335           The event is returned after it is sent.
336
337               my $event = $ctx->send_event('Ok', ...);
338
339           or
340
341               my $event = $ctx->send_event('+Test2::Event::Ok', ...);
342
343       $event = $ctx->build_event($Type, %parameters)
344           It is better to use build_ev2() in new code.
345
346           This is the same as "send_event()", except it builds and returns
347           the event without sending it.
348
349       $event = $ctx->send_event_and_release($Type, %parameters)
350           It is better to use send_ev2_and_release() in new code.
351
352           This is a combination of "send_event()" and "release()".
353
354               sub shorthand {
355                   my $ctx = context();
356                   return $ctx->send_event_and_release(Pass => { name => 'foo' });
357               }
358
359               sub longform {
360                   my $ctx = context();
361                   my $event = $ctx->send_event(Pass => { name => 'foo' });
362                   $ctx->release;
363                   return $event;
364               }
365

HOOKS

367       There are 2 types of hooks, init hooks, and release hooks. As the names
368       suggest, these hooks are triggered when contexts are created or
369       released.
370
371   INIT HOOKS
372       These are called whenever a context is initialized. That means when a
373       new instance is created. These hooks are NOT called every time
374       something requests a context, just when a new one is created.
375
376       GLOBAL
377
378       This is how you add a global init callback. Global callbacks happen for
379       every context for any hub or stack.
380
381           Test2::API::test2_add_callback_context_init(sub {
382               my $ctx = shift;
383               ...
384           });
385
386       PER HUB
387
388       This is how you add an init callback for all contexts created for a
389       given hub.  These callbacks will not run for other hubs.
390
391           $hub->add_context_init(sub {
392               my $ctx = shift;
393               ...
394           });
395
396       PER CONTEXT
397
398       This is how you specify an init hook that will only run if your call to
399       "context()" generates a new context. The callback will be ignored if
400       "context()" is returning an existing context.
401
402           my $ctx = context(on_init => sub {
403               my $ctx = shift;
404               ...
405           });
406
407   RELEASE HOOKS
408       These are called whenever a context is released. That means when the
409       last reference to the instance is about to be destroyed. These hooks
410       are NOT called every time "$ctx->release" is called.
411
412       GLOBAL
413
414       This is how you add a global release callback. Global callbacks happen
415       for every context for any hub or stack.
416
417           Test2::API::test2_add_callback_context_release(sub {
418               my $ctx = shift;
419               ...
420           });
421
422       PER HUB
423
424       This is how you add a release callback for all contexts created for a
425       given hub. These callbacks will not run for other hubs.
426
427           $hub->add_context_release(sub {
428               my $ctx = shift;
429               ...
430           });
431
432       PER CONTEXT
433
434       This is how you add release callbacks directly to a context. The
435       callback will ALWAYS be added to the context that gets returned, it
436       does not matter if a new one is generated, or if an existing one is
437       returned.
438
439           my $ctx = context(on_release => sub {
440               my $ctx = shift;
441               ...
442           });
443

THIRD PARTY META-DATA

445       This object consumes Test2::Util::ExternalMeta which provides a
446       consistent way for you to attach meta-data to instances of this class.
447       This is useful for tools, plugins, and other extensions.
448

SOURCE

450       The source code repository for Test2 can be found at
451       http://github.com/Test-More/test-more/.
452

MAINTAINERS

454       Chad Granum <exodist@cpan.org>
455

AUTHORS

457       Chad Granum <exodist@cpan.org>
458       Kent Fredric <kentnl@cpan.org>
459
461       Copyright 2019 Chad Granum <exodist@cpan.org>.
462
463       This program is free software; you can redistribute it and/or modify it
464       under the same terms as Perl itself.
465
466       See http://dev.perl.org/licenses/
467
468
469
470perl v5.30.0                      2019-09-06            Test2::API::Context(3)
Impressum