diff options
Diffstat (limited to 'cpan/Test-Simple/lib/Test2/Hub.pm')
-rw-r--r-- | cpan/Test-Simple/lib/Test2/Hub.pm | 100 |
1 files changed, 76 insertions, 24 deletions
diff --git a/cpan/Test-Simple/lib/Test2/Hub.pm b/cpan/Test-Simple/lib/Test2/Hub.pm index 324f1a87bb..9169f0bb6c 100644 --- a/cpan/Test-Simple/lib/Test2/Hub.pm +++ b/cpan/Test-Simple/lib/Test2/Hub.pm @@ -2,17 +2,19 @@ package Test2::Hub; use strict; use warnings; -our $VERSION = '1.302073'; +our $VERSION = '1.302096'; use Carp qw/carp croak confess/; use Test2::Util qw/get_tid ipc_separator/; use Scalar::Util qw/weaken/; +use List::Util qw/first/; use Test2::Util::ExternalMeta qw/meta get_meta set_meta delete_meta/; use Test2::Util::HashBase qw{ pid tid hid ipc + nested buffered no_ending _filters _pre_filters @@ -41,6 +43,9 @@ sub init { $self->{+TID} = get_tid(); $self->{+HID} = join ipc_separator, $self->{+PID}, $self->{+TID}, $ID_POSTFIX++; + $self->{+NESTED} = 0 unless defined $self->{+NESTED}; + $self->{+BUFFERED} = 0 unless defined $self->{+BUFFERED}; + $self->{+COUNT} = 0; $self->{+FAILED} = 0; $self->{+_PASSING} = 1; @@ -56,6 +61,21 @@ sub init { sub is_subtest { 0 } +sub _tb_reset { + my $self = shift; + + # Nothing to do + return if $self->{+PID} == $$ && $self->{+TID} == get_tid(); + + $self->{+PID} = $$; + $self->{+TID} = get_tid(); + $self->{+HID} = join ipc_separator, $self->{+PID}, $self->{+TID}, $ID_POSTFIX++; + + if (my $ipc = $self->{+IPC}) { + $ipc->add_hub($self->{+HID}); + } +} + sub reset_state { my $self = shift; @@ -73,6 +93,8 @@ sub inherit { my $self = shift; my ($from, %params) = @_; + $self->{+NESTED} ||= 0; + $self->{+_FORMATTER} = $from->{+_FORMATTER} unless $self->{+_FORMATTER} || exists($params{formatter}); @@ -281,32 +303,63 @@ sub process { } } + # Optimize the most common case my $type = ref($e); - my $is_ok = $type eq 'Test2::Event::Ok'; - my $no_fail = $type eq 'Test2::Event::Diag' || $type eq 'Test2::Event::Note'; - my $causes_fail = $is_ok ? !$e->{effective_pass} : $no_fail ? 0 : $e->causes_fail; - my $counted = $is_ok || (!$no_fail && $e->increments_count); + if ($type eq 'Test2::Event::Pass' || ($type eq 'Test2::Event::Ok' && $e->{pass})) { + my $count = ++($self->{+COUNT}); + $self->{+_FORMATTER}->write($e, $count) if $self->{+_FORMATTER}; - $self->{+COUNT}++ if $counted; - $self->{+FAILED}++ if $causes_fail && $counted; - $self->{+_PASSING} = 0 if $causes_fail; + if ($self->{+_LISTENERS}) { + $_->{code}->($self, $e, $count) for @{$self->{+_LISTENERS}}; + } + + return $e; + } + + my $f = $e->facet_data; - my $callback = $e->callback($self) unless $is_ok || $no_fail; + my $fail = 0; + $fail = 1 if $f->{assert} && !$f->{assert}->{pass}; + $fail = 1 if $f->{error} && $f->{error}->{fail}; + $fail = 0 if $f->{amnesty}; + $self->{+COUNT}++ if $f->{assert}; + $self->{+FAILED}++ if $fail && $f->{assert}; + $self->{+_PASSING} = 0 if $fail; + + my $code = $f->{control}->{terminate}; my $count = $self->{+COUNT}; - $self->{+_FORMATTER}->write($e, $count) if $self->{+_FORMATTER}; + if (my $plan = $f->{plan}) { + if ($plan->{skip}) { + $self->plan('SKIP'); + $self->set_skip_reason($plan->{details} || 1); + $code ||= 0; + } + elsif ($plan->{none}) { + $self->plan('NO PLAN'); + } + else { + $self->plan($plan->{count}); + } + } + + $e->callback($self) if $f->{control}->{has_callback}; + + $self->{+_FORMATTER}->write($e, $count, $f) if $self->{+_FORMATTER}; if ($self->{+_LISTENERS}) { - $_->{code}->($self, $e, $count) for @{$self->{+_LISTENERS}}; + $_->{code}->($self, $e, $count, $f) for @{$self->{+_LISTENERS}}; } - return $e if $is_ok || $no_fail; + if ($f->{control}->{halt}) { + $code ||= 255; + $self->set_bailed_out($e); + } - my $code = $e->terminate; if (defined $code) { - $self->{+_FORMATTER}->terminate($e) if $self->{+_FORMATTER}; - $self->terminate($code, $e); + $self->{+_FORMATTER}->terminate($e, $f) if $self->{+_FORMATTER}; + $self->terminate($code, $e, $f); } return $e; @@ -339,11 +392,11 @@ sub finalize { my $failed = $self->{+FAILED}; my $active = $self->{+ACTIVE}; - # return if NOTHING was done. - unless ($active || $do_plan || defined($plan) || $count || $failed) { - $self->{+_FORMATTER}->finalize($plan, $count, $failed, 0, $self->is_subtest) if $self->{+_FORMATTER}; - return; - } + # return if NOTHING was done. + unless ($active || $do_plan || defined($plan) || $count || $failed) { + $self->{+_FORMATTER}->finalize($plan, $count, $failed, 0, $self->is_subtest) if $self->{+_FORMATTER}; + return; + } unless ($self->{+ENDED}) { if ($self->{+_FOLLOW_UPS}) { @@ -381,7 +434,7 @@ Second End: $sfile line $sline $self->{+ENDED} = $frame; my $pass = $self->is_passing(); # Generate the final boolean. - $self->{+_FORMATTER}->finalize($plan, $count, $failed, $pass, $self->is_subtest) if $self->{+_FORMATTER}; + $self->{+_FORMATTER}->finalize($plan, $count, $failed, $pass, $self->is_subtest) if $self->{+_FORMATTER}; return $pass; } @@ -452,7 +505,6 @@ sub DESTROY { my $ipc = $self->{+IPC} || return; return unless $$ == $self->{+PID}; return unless get_tid() == $self->{+TID}; - $ipc->drop_hub($self->{+HID}); } @@ -640,7 +692,7 @@ the reference returned by C<filter()> or C<pre_filter()>. =item $hub->follow_op(sub { ... }) Use this to add behaviors that are called just before the hub is finalized. The -only argument to your codeblock will be a L<Test2::Util::Trace> instance. +only argument to your codeblock will be a L<Test2::EventFacet::Trace> instance. $hub->follow_up(sub { my ($trace, $hub) = @_; @@ -819,7 +871,7 @@ F<http://github.com/Test-More/test-more/>. =head1 COPYRIGHT -Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>. +Copyright 2017 Chad Granum E<lt>exodist@cpan.orgE<gt>. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. |