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               $ctx->ok($bool, $name);
26               $ctx->release; # You MUST do this!
27               return $bool;
28           }
29
30       Context objects make it easy to wrap other tools that also use context.
31       Once you grab a context, any tool you call before releasing your
32       context will inherit it:
33
34           sub wrapper {
35               my ($bool, $name) = @_;
36               my $ctx = context();
37               $ctx->diag("wrapping my_ok");
38
39               my $out = my_ok($bool, $name);
40               $ctx->release; # You MUST do this!
41               return $out;
42           }
43

CRITICAL DETAILS

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

METHODS

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

HOOKS

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

THIRD PARTY META-DATA

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

SOURCE

437       The source code repository for Test2 can be found at
438       http://github.com/Test-More/test-more/.
439

MAINTAINERS

441       Chad Granum <exodist@cpan.org>
442

AUTHORS

444       Chad Granum <exodist@cpan.org>
445       Kent Fredric <kentnl@cpan.org>
446
448       Copyright 2018 Chad Granum <exodist@cpan.org>.
449
450       This program is free software; you can redistribute it and/or modify it
451       under the same terms as Perl itself.
452
453       See http://dev.perl.org/licenses/
454
455
456
457perl v5.26.3                      2018-03-30            Test2::API::Context(3)
Impressum