File Coverage

blib/lib/Test2/Hub.pm
Criterion Covered Total %
statement 301 302 99.6
branch 141 156 90.3
condition 105 136 77.2
subroutine 37 37 100.0
pod 20 27 74.0
total 604 658 91.7


line stmt bran cond sub pod time code
1             package Test2::Hub;
2 246     246   3958 use strict;
  246         500  
  246         7888  
3 246     246   1641 use warnings;
  246         461  
  246         11108  
4              
5             our $VERSION = '1.302182';
6              
7              
8 246     246   1455 use Carp qw/carp croak confess/;
  246         520  
  246         15686  
9 246     246   2094 use Test2::Util qw/get_tid gen_uid/;
  246         574  
  246         13326  
10              
11 246     246   1665 use Scalar::Util qw/weaken/;
  246         496  
  246         12518  
12 246     246   1594 use List::Util qw/first/;
  246         637  
  246         28338  
13              
14 246     246   102059 use Test2::Util::ExternalMeta qw/meta get_meta set_meta delete_meta/;
  246         598  
  246         19809  
15 246         1513 use Test2::Util::HashBase qw{
16             pid tid hid ipc
17             nested buffered
18             no_ending
19             _filters
20             _pre_filters
21             _listeners
22             _follow_ups
23             _formatter
24             _context_acquire
25             _context_init
26             _context_release
27              
28             uuid
29             active
30             count
31             failed
32             ended
33             bailed_out
34             _passing
35             _plan
36             skip_reason
37 246     246   2098 };
  246         479  
38              
39             my $UUID_VIA;
40              
41             sub init {
42 729     729 0 1545 my $self = shift;
43              
44 729         3497 $self->{+PID} = $$;
45 729         1960 $self->{+TID} = get_tid();
46 729         4025 $self->{+HID} = gen_uid();
47              
48 729   66     3683 $UUID_VIA ||= Test2::API::_add_uuid_via_ref();
49 729 100       2313 $self->{+UUID} = ${$UUID_VIA}->('hub') if $$UUID_VIA;
  4         10  
50              
51 729 100       2895 $self->{+NESTED} = 0 unless defined $self->{+NESTED};
52 729 100       2527 $self->{+BUFFERED} = 0 unless defined $self->{+BUFFERED};
53              
54 729         1806 $self->{+COUNT} = 0;
55 729         1628 $self->{+FAILED} = 0;
56 729         2142 $self->{+_PASSING} = 1;
57              
58 729 100       2373 if (my $formatter = delete $self->{formatter}) {
59 52         218 $self->format($formatter);
60             }
61              
62 729 100       2807 if (my $ipc = $self->{+IPC}) {
63 15         63 $ipc->add_hub($self->{+HID});
64             }
65             }
66              
67 235     235 0 2845 sub is_subtest { 0 }
68              
69             sub _tb_reset {
70 55     55   164 my $self = shift;
71              
72             # Nothing to do
73 55 100 66     503 return if $self->{+PID} == $$ && $self->{+TID} == get_tid();
74              
75 1         32 $self->{+PID} = $$;
76 1         22 $self->{+TID} = get_tid();
77 1         25 $self->{+HID} = gen_uid();
78              
79 1 50       32 if (my $ipc = $self->{+IPC}) {
80 0         0 $ipc->add_hub($self->{+HID});
81             }
82             }
83              
84             sub reset_state {
85 58     58 1 169 my $self = shift;
86              
87 58         160 $self->{+COUNT} = 0;
88 58         133 $self->{+FAILED} = 0;
89 58         177 $self->{+_PASSING} = 1;
90              
91 58         151 delete $self->{+_PLAN};
92 58         121 delete $self->{+ENDED};
93 58         114 delete $self->{+BAILED_OUT};
94 58         150 delete $self->{+SKIP_REASON};
95             }
96              
97             sub inherit {
98 292     292 0 551 my $self = shift;
99 292         632 my ($from, %params) = @_;
100              
101 292   50     1540 $self->{+NESTED} ||= 0;
102              
103             $self->{+_FORMATTER} = $from->{+_FORMATTER}
104 292 100 66     1558 unless $self->{+_FORMATTER} || exists($params{formatter});
105              
106 292 100 66     1097 if ($from->{+IPC} && !$self->{+IPC} && !exists($params{ipc})) {
      100        
107 24         55 my $ipc = $from->{+IPC};
108 24         55 $self->{+IPC} = $ipc;
109 24         103 $ipc->add_hub($self->{+HID});
110             }
111              
112 292 100       907 if (my $ls = $from->{+_LISTENERS}) {
113 53         91 push @{$self->{+_LISTENERS}} => grep { $_->{inherit} } @$ls;
  53         229  
  55         200  
114             }
115              
116 292 100       803 if (my $pfs = $from->{+_PRE_FILTERS}) {
117 173         251 push @{$self->{+_PRE_FILTERS}} => grep { $_->{inherit} } @$pfs;
  173         519  
  253         665  
118             }
119              
120 292 100       1150 if (my $fs = $from->{+_FILTERS}) {
121 12         21 push @{$self->{+_FILTERS}} => grep { $_->{inherit} } @$fs;
  12         48  
  6         30  
122             }
123             }
124              
125             sub format {
126 3485     3485 1 6068 my $self = shift;
127              
128 3485         5972 my $old = $self->{+_FORMATTER};
129 3485 100       8405 ($self->{+_FORMATTER}) = @_ if @_;
130              
131 3485         9984 return $old;
132             }
133              
134             sub is_local {
135 127     127 0 256 my $self = shift;
136             return $$ == $self->{+PID}
137 127   66     1081 && get_tid() == $self->{+TID};
138             }
139              
140             sub listen {
141 343     343 1 644 my $self = shift;
142 343         836 my ($sub, %params) = @_;
143              
144             carp "Useless addition of a listener in a child process or thread!"
145 343 50 33     1973 if $$ != $self->{+PID} || get_tid() != $self->{+TID};
146              
147 343 100 66     2017 croak "listen only takes coderefs for arguments, got '$sub'"
148             unless ref $sub && ref $sub eq 'CODE';
149              
150 342         586 push @{$self->{+_LISTENERS}} => { %params, code => $sub };
  342         1492  
151              
152 342         915 $sub; # Intentional return.
153             }
154              
155             sub unlisten {
156 1     1 1 8 my $self = shift;
157              
158             carp "Useless removal of a listener in a child process or thread!"
159 1 50 33     23 if $$ != $self->{+PID} || get_tid() != $self->{+TID};
160              
161 1         5 my %subs = map {$_ => $_} @_;
  1         10  
162              
163 1         4 @{$self->{+_LISTENERS}} = grep { !$subs{$_->{code}} } @{$self->{+_LISTENERS}};
  1         5  
  2         8  
  1         8  
164             }
165              
166             sub filter {
167 11     11 1 77 my $self = shift;
168 11         51 my ($sub, %params) = @_;
169              
170             carp "Useless addition of a filter in a child process or thread!"
171 11 50 33     115 if $$ != $self->{+PID} || get_tid() != $self->{+TID};
172              
173 11 100 66     192 croak "filter only takes coderefs for arguments, got '$sub'"
174             unless ref $sub && ref $sub eq 'CODE';
175              
176 10         18 push @{$self->{+_FILTERS}} => { %params, code => $sub };
  10         67  
177              
178 10         52 $sub; # Intentional Return
179             }
180              
181             sub unfilter {
182 2     2 1 13 my $self = shift;
183             carp "Useless removal of a filter in a child process or thread!"
184 2 50 33     30 if $$ != $self->{+PID} || get_tid() != $self->{+TID};
185 2         11 my %subs = map {$_ => $_} @_;
  2         15  
186 2         8 @{$self->{+_FILTERS}} = grep { !$subs{$_->{code}} } @{$self->{+_FILTERS}};
  2         15  
  3         21  
  2         12  
187             }
188              
189             sub pre_filter {
190 482     482 1 1258 my $self = shift;
191 482         1729 my ($sub, %params) = @_;
192              
193 482 100 66     3110 croak "pre_filter only takes coderefs for arguments, got '$sub'"
194             unless ref $sub && ref $sub eq 'CODE';
195              
196 481         1065 push @{$self->{+_PRE_FILTERS}} => { %params, code => $sub };
  481         2776  
197              
198 481         2059 $sub; # Intentional Return
199             }
200              
201             sub pre_unfilter {
202 93     93 1 167 my $self = shift;
203 93         229 my %subs = map {$_ => $_} @_;
  93         421  
204 93         171 @{$self->{+_PRE_FILTERS}} = grep { !$subs{$_->{code}} } @{$self->{+_PRE_FILTERS}};
  93         364  
  211         589  
  93         218  
205             }
206              
207             sub follow_up {
208 4     4 0 32 my $self = shift;
209 4         10 my ($sub) = @_;
210              
211             carp "Useless addition of a follow-up in a child process or thread!"
212 4 50 33     22 if $$ != $self->{+PID} || get_tid() != $self->{+TID};
213              
214 4 100 66     386 croak "follow_up only takes coderefs for arguments, got '$sub'"
215             unless ref $sub && ref $sub eq 'CODE';
216              
217 2         4 push @{$self->{+_FOLLOW_UPS}} => $sub;
  2         10  
218             }
219              
220             *add_context_aquire = \&add_context_acquire;
221             sub add_context_acquire {
222 1     1 1 9 my $self = shift;
223 1         2 my ($sub) = @_;
224              
225 1 50 33     6 croak "add_context_acquire only takes coderefs for arguments, got '$sub'"
226             unless ref $sub && ref $sub eq 'CODE';
227              
228 1         2 push @{$self->{+_CONTEXT_ACQUIRE}} => $sub;
  1         15  
229              
230 1         5 $sub; # Intentional return.
231             }
232              
233             *remove_context_aquire = \&remove_context_acquire;
234             sub remove_context_acquire {
235 1     1 1 6 my $self = shift;
236 1         2 my %subs = map {$_ => $_} @_;
  1         5  
237 1         2 @{$self->{+_CONTEXT_ACQUIRE}} = grep { !$subs{$_} == $_ } @{$self->{+_CONTEXT_ACQUIRE}};
  1         3  
  1         4  
  1         4  
238             }
239              
240             sub add_context_init {
241 1     1 1 11 my $self = shift;
242 1         3 my ($sub) = @_;
243              
244 1 50 33     8 croak "add_context_init only takes coderefs for arguments, got '$sub'"
245             unless ref $sub && ref $sub eq 'CODE';
246              
247 1         3 push @{$self->{+_CONTEXT_INIT}} => $sub;
  1         4  
248              
249 1         4 $sub; # Intentional return.
250             }
251              
252             sub remove_context_init {
253 1     1 1 10 my $self = shift;
254 1         17 my %subs = map {$_ => $_} @_;
  1         6  
255 1         3 @{$self->{+_CONTEXT_INIT}} = grep { !$subs{$_} == $_ } @{$self->{+_CONTEXT_INIT}};
  1         5  
  1         6  
  1         4  
256             }
257              
258             sub add_context_release {
259 1     1 1 8 my $self = shift;
260 1         3 my ($sub) = @_;
261              
262 1 50 33     5 croak "add_context_release only takes coderefs for arguments, got '$sub'"
263             unless ref $sub && ref $sub eq 'CODE';
264              
265 1         3 push @{$self->{+_CONTEXT_RELEASE}} => $sub;
  1         3  
266              
267 1         3 $sub; # Intentional return.
268             }
269              
270             sub remove_context_release {
271 1     1 1 6 my $self = shift;
272 1         3 my %subs = map {$_ => $_} @_;
  1         4  
273 1         3 @{$self->{+_CONTEXT_RELEASE}} = grep { !$subs{$_} == $_ } @{$self->{+_CONTEXT_RELEASE}};
  1         5  
  1         3  
  1         3  
274             }
275              
276             sub send {
277 6019     6019 1 12088 my $self = shift;
278 6019         10852 my ($e) = @_;
279              
280 6019         26309 $e->eid;
281              
282             $e->add_hub(
283             {
284             details => ref($self),
285              
286             buffered => $self->{+BUFFERED},
287             hid => $self->{+HID},
288             nested => $self->{+NESTED},
289             pid => $self->{+PID},
290             tid => $self->{+TID},
291             uuid => $self->{+UUID},
292              
293 6019 100       61155 ipc => $self->{+IPC} ? 1 : 0,
294             }
295             );
296              
297 6019 100       15542 $e->set_uuid(${$UUID_VIA}->('event')) if $$UUID_VIA;
  43         98  
298              
299 6019 100       14006 if ($self->{+_PRE_FILTERS}) {
300 3798         5298 for (@{$self->{+_PRE_FILTERS}}) {
  3798         8718  
301 5279         16849 $e = $_->{code}->($self, $e);
302 5279 100       13483 return unless $e;
303             }
304             }
305              
306 6016   100     21214 my $ipc = $self->{+IPC} || return $self->process($e);
307              
308 692 100       2432 if($e->global) {
309 1         7 $ipc->send($self->{+HID}, $e, 'GLOBAL');
310 1         6 return $self->process($e);
311             }
312              
313             return $ipc->send($self->{+HID}, $e)
314 691 100 66     3449 if $$ != $self->{+PID} || get_tid() != $self->{+TID};
315              
316 681         1795 $self->process($e);
317             }
318              
319             sub process {
320 6074     6074 1 9849 my $self = shift;
321 6074         11421 my ($e) = @_;
322              
323 6074 100       13086 if ($self->{+_FILTERS}) {
324 18         31 for (@{$self->{+_FILTERS}}) {
  18         58  
325 17         70 $e = $_->{code}->($self, $e);
326 17 100       146 return unless $e;
327             }
328             }
329              
330             # Optimize the most common case
331 6065         12221 my $type = ref($e);
332 6065 100 100     24862 if ($type eq 'Test2::Event::Pass' || ($type eq 'Test2::Event::Ok' && $e->{pass})) {
      100        
333 3573         6892 my $count = ++($self->{+COUNT});
334 3573 100       19162 $self->{+_FORMATTER}->write($e, $count) if $self->{+_FORMATTER};
335              
336 3573 100       10251 if ($self->{+_LISTENERS}) {
337 826         1299 $_->{code}->($self, $e, $count) for @{$self->{+_LISTENERS}};
  826         3439  
338             }
339              
340 3573         11099 return $e;
341             }
342              
343 2492         8076 my $f = $e->facet_data;
344              
345 2492         4309 my $fail = 0;
346 2492 100 100     8277 $fail = 1 if $f->{assert} && !$f->{assert}->{pass};
347 2492 100 100     6468 $fail = 1 if $f->{errors} && grep { $_->{fail} } @{$f->{errors}};
  8         29  
  6         19  
348 2492 100       5499 $fail = 0 if $f->{amnesty};
349              
350 2492 100       5571 $self->{+COUNT}++ if $f->{assert};
351 2492 100 100     6024 $self->{+FAILED}++ if $fail && $f->{assert};
352 2492 100       5246 $self->{+_PASSING} = 0 if $fail;
353              
354 2492 100       6270 my $code = $f->{control} ? $f->{control}->{terminate} : undef;
355 2492         4146 my $count = $self->{+COUNT};
356              
357 2492 100       5853 if (my $plan = $f->{plan}) {
358 550 100       2688 if ($plan->{skip}) {
    100          
359 24         132 $self->plan('SKIP');
360 24   100     205 $self->set_skip_reason($plan->{details} || 1);
361 24   50     160 $code ||= 0;
362             }
363             elsif ($plan->{none}) {
364 1         5 $self->plan('NO PLAN');
365             }
366             else {
367 525         2254 $self->plan($plan->{count});
368             }
369             }
370              
371 2492 50 66     8037 $e->callback($self) if $f->{control} && $f->{control}->{has_callback};
372              
373 2492 100       12133 $self->{+_FORMATTER}->write($e, $count, $f) if $self->{+_FORMATTER};
374              
375 2492 100       7002 if ($self->{+_LISTENERS}) {
376 773         1394 $_->{code}->($self, $e, $count, $f) for @{$self->{+_LISTENERS}};
  773         3275  
377             }
378              
379 2492 100 100     10893 if ($f->{control} && $f->{control}->{halt}) {
380 11   100     44 $code ||= 255;
381 11         61 $self->set_bailed_out($e);
382             }
383              
384 2492 100       5922 if (defined $code) {
385 35 100       400 $self->{+_FORMATTER}->terminate($e, $f) if $self->{+_FORMATTER};
386 35         181 $self->terminate($code, $e, $f);
387             }
388              
389 2462         24987 return $e;
390             }
391              
392             sub terminate {
393 15     15 0 44 my $self = shift;
394 15         43 my ($code) = @_;
395 15         270 exit($code);
396             }
397              
398             sub cull {
399 1223     1223 1 2404 my $self = shift;
400              
401 1223   100     3674 my $ipc = $self->{+IPC} || return;
402 744 100 66     3629 return if $self->{+PID} != $$ || $self->{+TID} != get_tid();
403              
404             # No need to do IPC checks on culled events
405 737         2533 $self->process($_) for $ipc->cull($self->{+HID});
406             }
407              
408             sub finalize {
409 469     469 0 1166 my $self = shift;
410 469         1235 my ($trace, $do_plan) = @_;
411              
412 469         2248 $self->cull();
413              
414 469         1173 my $plan = $self->{+_PLAN};
415 469         1247 my $count = $self->{+COUNT};
416 469         1152 my $failed = $self->{+FAILED};
417 469         993 my $active = $self->{+ACTIVE};
418              
419             # return if NOTHING was done.
420 469 100 66     4068 unless ($active || $do_plan || defined($plan) || $count || $failed) {
      100        
      100        
      100        
421 12 50       118 $self->{+_FORMATTER}->finalize($plan, $count, $failed, 0, $self->is_subtest) if $self->{+_FORMATTER};
422 12         37 return;
423             }
424              
425 457 100       1788 unless ($self->{+ENDED}) {
426 454 100       1646 if ($self->{+_FOLLOW_UPS}) {
427 2         4 $_->($trace, $self) for reverse @{$self->{+_FOLLOW_UPS}};
  2         12  
428             }
429              
430             # These need to be refreshed now
431 454         1210 $plan = $self->{+_PLAN};
432 454         1006 $count = $self->{+COUNT};
433 454         928 $failed = $self->{+FAILED};
434              
435 454 100 100     4070 if (($plan && $plan eq 'NO PLAN') || ($do_plan && !$plan)) {
      100        
      100        
436 313         2590 $self->send(
437             Test2::Event::Plan->new(
438             trace => $trace,
439             max => $count,
440             )
441             );
442             }
443 454         2071 $plan = $self->{+_PLAN};
444             }
445              
446 457         2183 my $frame = $trace->frame;
447 457 100       1665 if($self->{+ENDED}) {
448 3         8 my (undef, $ffile, $fline) = @{$self->{+ENDED}};
  3         12  
449 3         11 my (undef, $sfile, $sline) = @$frame;
450              
451 3         27 die <<" EOT"
452             Test already ended!
453             First End: $ffile line $fline
454             Second End: $sfile line $sline
455             EOT
456             }
457              
458 454         1371 $self->{+ENDED} = $frame;
459 454         1882 my $pass = $self->is_passing(); # Generate the final boolean.
460              
461 454 100       2718 $self->{+_FORMATTER}->finalize($plan, $count, $failed, $pass, $self->is_subtest) if $self->{+_FORMATTER};
462              
463 454         1424 return $pass;
464             }
465              
466             sub is_passing {
467 2198     2198 1 4021 my $self = shift;
468              
469 2198 100       5035 ($self->{+_PASSING}) = @_ if @_;
470              
471             # If we already failed just return 0.
472 2198 100       5797 my $pass = $self->{+_PASSING} or return 0;
473 1773 100       4005 return $self->{+_PASSING} = 0 if $self->{+FAILED};
474              
475 1766         2918 my $count = $self->{+COUNT};
476 1766         2781 my $ended = $self->{+ENDED};
477 1766         2905 my $plan = $self->{+_PLAN};
478              
479 1766 100 100     6310 return $pass if !$count && $plan && $plan =~ m/^SKIP$/;
      100        
480              
481 1725 100 100     7122 return $self->{+_PASSING} = 0
      100        
482             if $ended && (!$count || !$plan);
483              
484 1696 100 100     10465 return $pass unless $plan && $plan =~ m/^\d+$/;
485              
486 1550 100       3675 if ($ended) {
487 872 100       2292 return $self->{+_PASSING} = 0 if $count != $plan;
488             }
489             else {
490 678 100       1255 return $self->{+_PASSING} = 0 if $count > $plan;
491             }
492              
493 1546         5118 return $pass;
494             }
495              
496             sub plan {
497 1967     1967 1 3638 my $self = shift;
498              
499 1967 100       7603 return $self->{+_PLAN} unless @_;
500              
501 582         1584 my ($plan) = @_;
502              
503 582 50       1767 confess "You cannot unset the plan"
504             unless defined $plan;
505              
506             confess "You cannot change the plan"
507 582 100 100     2716 if $self->{+_PLAN} && $self->{+_PLAN} !~ m/^NO PLAN$/;
508              
509 581 100       4401 confess "'$plan' is not a valid plan! Plan must be an integer greater than 0, 'NO PLAN', or 'SKIP'"
510             unless $plan =~ m/^(\d+|NO PLAN|SKIP)$/;
511              
512 580         1945 $self->{+_PLAN} = $plan;
513             }
514              
515             sub check_plan {
516 124     124 1 260 my $self = shift;
517              
518 124 50       363 return undef unless $self->{+ENDED};
519 124   100     361 my $plan = $self->{+_PLAN} || return undef;
520              
521 115 50       633 return 1 if $plan !~ m/^\d+$/;
522              
523 115 100       512 return 1 if $plan == $self->{+COUNT};
524 1         4 return 0;
525             }
526              
527             sub DESTROY {
528 465     465   1891 my $self = shift;
529 465   100     15462 my $ipc = $self->{+IPC} || return;
530 51 100       312 return unless $$ == $self->{+PID};
531 50 50       153 return unless get_tid() == $self->{+TID};
532 50         269 $ipc->drop_hub($self->{+HID});
533             }
534              
535             1;
536              
537             __END__
538              
539             =pod
540              
541             =encoding UTF-8
542              
543             =head1 NAME
544              
545             Test2::Hub - The conduit through which all events flow.
546              
547             =head1 SYNOPSIS
548              
549             use Test2::Hub;
550              
551             my $hub = Test2::Hub->new();
552             $hub->send(...);
553              
554             =head1 DESCRIPTION
555              
556             The hub is the place where all events get processed and handed off to the
557             formatter. The hub also tracks test state, and provides several hooks into the
558             event pipeline.
559              
560             =head1 COMMON TASKS
561              
562             =head2 SENDING EVENTS
563              
564             $hub->send($event)
565              
566             The C<send()> method is used to issue an event to the hub. This method will
567             handle thread/fork sync, filters, listeners, TAP output, etc.
568              
569             =head2 ALTERING OR REMOVING EVENTS
570              
571             You can use either C<filter()> or C<pre_filter()>, depending on your
572             needs. Both have identical syntax, so only C<filter()> is shown here.
573              
574             $hub->filter(sub {
575             my ($hub, $event) = @_;
576              
577             my $action = get_action($event);
578              
579             # No action should be taken
580             return $event if $action eq 'none';
581              
582             # You want your filter to remove the event
583             return undef if $action eq 'delete';
584              
585             if ($action eq 'do_it') {
586             my $new_event = copy_event($event);
587             ... Change your copy of the event ...
588             return $new_event;
589             }
590              
591             die "Should not happen";
592             });
593              
594             By default, filters are not inherited by child hubs. That means if you start a
595             subtest, the subtest will not inherit the filter. You can change this behavior
596             with the C<inherit> parameter:
597              
598             $hub->filter(sub { ... }, inherit => 1);
599              
600             =head2 LISTENING FOR EVENTS
601              
602             $hub->listen(sub {
603             my ($hub, $event, $number) = @_;
604              
605             ... do whatever you want with the event ...
606              
607             # return is ignored
608             });
609              
610             By default listeners are not inherited by child hubs. That means if you start a
611             subtest, the subtest will not inherit the listener. You can change this behavior
612             with the C<inherit> parameter:
613              
614             $hub->listen(sub { ... }, inherit => 1);
615              
616              
617             =head2 POST-TEST BEHAVIORS
618              
619             $hub->follow_up(sub {
620             my ($trace, $hub) = @_;
621              
622             ... do whatever you need to ...
623              
624             # Return is ignored
625             });
626              
627             follow_up subs are called only once, either when done_testing is called, or in
628             an END block.
629              
630             =head2 SETTING THE FORMATTER
631              
632             By default an instance of L<Test2::Formatter::TAP> is created and used.
633              
634             my $old = $hub->format(My::Formatter->new);
635              
636             Setting the formatter will REPLACE any existing formatter. You may set the
637             formatter to undef to prevent output. The old formatter will be returned if one
638             was already set. Only one formatter is allowed at a time.
639              
640             =head1 METHODS
641              
642             =over 4
643              
644             =item $hub->send($event)
645              
646             This is where all events enter the hub for processing.
647              
648             =item $hub->process($event)
649              
650             This is called by send after it does any IPC handling. You can use this to
651             bypass the IPC process, but in general you should avoid using this.
652              
653             =item $old = $hub->format($formatter)
654              
655             Replace the existing formatter instance with a new one. Formatters must be
656             objects that implement a C<< $formatter->write($event) >> method.
657              
658             =item $sub = $hub->listen(sub { ... }, %optional_params)
659              
660             You can use this to record all events AFTER they have been sent to the
661             formatter. No changes made here will be meaningful, except possibly to other
662             listeners.
663              
664             $hub->listen(sub {
665             my ($hub, $event, $number) = @_;
666              
667             ... do whatever you want with the event ...
668              
669             # return is ignored
670             });
671              
672             Normally listeners are not inherited by child hubs such as subtests. You can
673             add the C<< inherit => 1 >> parameter to allow a listener to be inherited.
674              
675             =item $hub->unlisten($sub)
676              
677             You can use this to remove a listen callback. You must pass in the coderef
678             returned by the C<listen()> method.
679              
680             =item $sub = $hub->filter(sub { ... }, %optional_params)
681              
682             =item $sub = $hub->pre_filter(sub { ... }, %optional_params)
683              
684             These can be used to add filters. Filters can modify, replace, or remove events
685             before anything else can see them.
686              
687             $hub->filter(
688             sub {
689             my ($hub, $event) = @_;
690              
691             return $event; # No Changes
692             return; # Remove the event
693              
694             # Or you can modify an event before returning it.
695             $event->modify;
696             return $event;
697             }
698             );
699              
700             If you are not using threads, forking, or IPC then the only difference between
701             a C<filter> and a C<pre_filter> is that C<pre_filter> subs run first. When you
702             are using threads, forking, or IPC, pre_filters happen to events before they
703             are sent to their destination proc/thread, ordinary filters happen only in the
704             destination hub/thread.
705              
706             You cannot add a regular filter to a hub if the hub was created in another
707             process or thread. You can always add a pre_filter.
708              
709             =item $hub->unfilter($sub)
710              
711             =item $hub->pre_unfilter($sub)
712              
713             These can be used to remove filters and pre_filters. The C<$sub> argument is
714             the reference returned by C<filter()> or C<pre_filter()>.
715              
716             =item $hub->follow_op(sub { ... })
717              
718             Use this to add behaviors that are called just before the hub is finalized. The
719             only argument to your codeblock will be a L<Test2::EventFacet::Trace> instance.
720              
721             $hub->follow_up(sub {
722             my ($trace, $hub) = @_;
723              
724             ... do whatever you need to ...
725              
726             # Return is ignored
727             });
728              
729             follow_up subs are called only once, ether when done_testing is called, or in
730             an END block.
731              
732             =item $sub = $hub->add_context_acquire(sub { ... });
733              
734             Add a callback that will be called every time someone tries to acquire a
735             context. It gets a single argument, a reference of the hash of parameters
736             being used the construct the context. This is your chance to change the
737             parameters by directly altering the hash.
738              
739             test2_add_callback_context_acquire(sub {
740             my $params = shift;
741             $params->{level}++;
742             });
743              
744             This is a very scary API function. Please do not use this unless you need to.
745             This is here for L<Test::Builder> and backwards compatibility. This has you
746             directly manipulate the hash instead of returning a new one for performance
747             reasons.
748              
749             B<Note> Using this hook could have a huge performance impact.
750              
751             The coderef you provide is returned and can be used to remove the hook later.
752              
753             =item $hub->remove_context_acquire($sub);
754              
755             This can be used to remove a context acquire hook.
756              
757             =item $sub = $hub->add_context_init(sub { ... });
758              
759             This allows you to add callbacks that will trigger every time a new context is
760             created for the hub. The only argument to the sub will be the
761             L<Test2::API::Context> instance that was created.
762              
763             B<Note> Using this hook could have a huge performance impact.
764              
765             The coderef you provide is returned and can be used to remove the hook later.
766              
767             =item $hub->remove_context_init($sub);
768              
769             This can be used to remove a context init hook.
770              
771             =item $sub = $hub->add_context_release(sub { ... });
772              
773             This allows you to add callbacks that will trigger every time a context for
774             this hub is released. The only argument to the sub will be the
775             L<Test2::API::Context> instance that was released. These will run in reverse
776             order.
777              
778             B<Note> Using this hook could have a huge performance impact.
779              
780             The coderef you provide is returned and can be used to remove the hook later.
781              
782             =item $hub->remove_context_release($sub);
783              
784             This can be used to remove a context release hook.
785              
786             =item $hub->cull()
787              
788             Cull any IPC events (and process them).
789              
790             =item $pid = $hub->pid()
791              
792             Get the process id under which the hub was created.
793              
794             =item $tid = $hub->tid()
795              
796             Get the thread id under which the hub was created.
797              
798             =item $hud = $hub->hid()
799              
800             Get the identifier string of the hub.
801              
802             =item $uuid = $hub->uuid()
803              
804             If UUID tagging is enabled (see L<Test2::API>) then the hub will have a UUID.
805              
806             =item $ipc = $hub->ipc()
807              
808             Get the IPC object used by the hub.
809              
810             =item $hub->set_no_ending($bool)
811              
812             =item $bool = $hub->no_ending
813              
814             This can be used to disable auto-ending behavior for a hub. The auto-ending
815             behavior is triggered by an end block and is used to cull IPC events, and
816             output the final plan if the plan was 'NO PLAN'.
817              
818             =item $bool = $hub->active
819              
820             =item $hub->set_active($bool)
821              
822             These are used to get/set the 'active' attribute. When true this attribute will
823             force C<< hub->finalize() >> to take action even if there is no plan, and no
824             tests have been run. This flag is useful for plugins that add follow-up
825             behaviors that need to run even if no events are seen.
826              
827             =back
828              
829             =head2 STATE METHODS
830              
831             =over 4
832              
833             =item $hub->reset_state()
834              
835             Reset all state to the start. This sets the test count to 0, clears the plan,
836             removes the failures, etc.
837              
838             =item $num = $hub->count
839              
840             Get the number of tests that have been run.
841              
842             =item $num = $hub->failed
843              
844             Get the number of failures (Not all failures come from a test fail, so this
845             number can be larger than the count).
846              
847             =item $bool = $hub->ended
848              
849             True if the testing has ended. This MAY return the stack frame of the tool that
850             ended the test, but that is not guaranteed.
851              
852             =item $bool = $hub->is_passing
853              
854             =item $hub->is_passing($bool)
855              
856             Check if the overall test run is a failure. Can also be used to set the
857             pass/fail status.
858              
859             =item $hub->plan($plan)
860              
861             =item $plan = $hub->plan
862              
863             Get or set the plan. The plan must be an integer larger than 0, the string
864             'NO PLAN', or the string 'SKIP'.
865              
866             =item $bool = $hub->check_plan
867              
868             Check if the plan and counts match, but only if the tests have ended. If tests
869             have not ended this will return undef, otherwise it will be a true/false.
870              
871             =back
872              
873             =head1 THIRD PARTY META-DATA
874              
875             This object consumes L<Test2::Util::ExternalMeta> which provides a consistent
876             way for you to attach meta-data to instances of this class. This is useful for
877             tools, plugins, and other extensions.
878              
879             =head1 SOURCE
880              
881             The source code repository for Test2 can be found at
882             F<http://github.com/Test-More/test-more/>.
883              
884             =head1 MAINTAINERS
885              
886             =over 4
887              
888             =item Chad Granum E<lt>exodist@cpan.orgE<gt>
889              
890             =back
891              
892             =head1 AUTHORS
893              
894             =over 4
895              
896             =item Chad Granum E<lt>exodist@cpan.orgE<gt>
897              
898             =back
899              
900             =head1 COPYRIGHT
901              
902             Copyright 2020 Chad Granum E<lt>exodist@cpan.orgE<gt>.
903              
904             This program is free software; you can redistribute it and/or
905             modify it under the same terms as Perl itself.
906              
907             See F<http://dev.perl.org/licenses/>
908              
909             =cut