summaryrefslogtreecommitdiff
path: root/cpan/Test-Simple/lib/Test2/API/Context.pm
diff options
context:
space:
mode:
Diffstat (limited to 'cpan/Test-Simple/lib/Test2/API/Context.pm')
-rw-r--r--cpan/Test-Simple/lib/Test2/API/Context.pm242
1 files changed, 198 insertions, 44 deletions
diff --git a/cpan/Test-Simple/lib/Test2/API/Context.pm b/cpan/Test-Simple/lib/Test2/API/Context.pm
index 7660fa69ea..db803c03c6 100644
--- a/cpan/Test-Simple/lib/Test2/API/Context.pm
+++ b/cpan/Test-Simple/lib/Test2/API/Context.pm
@@ -2,14 +2,14 @@ package Test2::API::Context;
use strict;
use warnings;
-our $VERSION = '1.302073';
+our $VERSION = '1.302096';
use Carp qw/confess croak longmess/;
use Scalar::Util qw/weaken blessed/;
use Test2::Util qw/get_tid try pkg_to_file get_tid/;
-use Test2::Util::Trace();
+use Test2::EventFacet::Trace();
use Test2::API();
# Preload some key event types
@@ -19,7 +19,7 @@ my %LOADED = (
my $file = "Test2/Event/$_.pm";
require $file unless $INC{$file};
( $pkg => $pkg, $_ => $pkg )
- } qw/Ok Diag Note Info Plan Bail Exception Waiting Skip Subtest/
+ } qw/Ok Diag Note Plan Bail Exception Waiting Skip Subtest Pass Fail/
);
use Test2::Util::ExternalMeta qw/meta get_meta set_meta delete_meta/;
@@ -155,9 +155,7 @@ sub do_in_context {
# We need to update the pid/tid and error vars.
my $clone = $self->snapshot;
@$clone{+ERRNO, +EVAL_ERROR, +CHILD_ERROR} = ($!, $@, $?);
- $clone->{+TRACE} = $clone->{+TRACE}->snapshot;
- $clone->{+TRACE}->set_pid($$);
- $clone->{+TRACE}->set_tid(get_tid());
+ $clone->{+TRACE} = $clone->{+TRACE}->snapshot(pid => $$, tid => get_tid());
my $hub = $clone->{+HUB};
my $hid = $hub->hid;
@@ -202,6 +200,13 @@ sub alert {
$self->trace->alert($msg);
}
+sub send_event_and_release {
+ my $self = shift;
+ my $out = $self->send_event(@_);
+ $self->release;
+ return $out;
+}
+
sub send_event {
my $self = shift;
my $event = shift;
@@ -209,12 +214,19 @@ sub send_event {
my $pkg = $LOADED{$event} || $self->_parse_event($event);
- my $e = $pkg->new(
- trace => $self->{+TRACE}->snapshot,
- %args,
- );
+ my $e;
+ {
+ local $Carp::CarpLevel = $Carp::CarpLevel + 1;
+ $e = $pkg->new(
+ trace => $self->{+TRACE}->snapshot,
+ %args,
+ );
+ }
- ${$self->{+_ABORTED}}++ if $self->{+_ABORTED} && defined $e->terminate;
+ if ($self->{+_ABORTED}) {
+ my $f = $e->facet_data;
+ ${$self->{+_ABORTED}}++ if $f->{control}->{halt} || defined($f->{control}->{terminate}) || defined($e->terminate);
+ }
$self->{+HUB}->send($e);
}
@@ -225,12 +237,81 @@ sub build_event {
my $pkg = $LOADED{$event} || $self->_parse_event($event);
+ local $Carp::CarpLevel = $Carp::CarpLevel + 1;
$pkg->new(
trace => $self->{+TRACE}->snapshot,
%args,
);
}
+sub pass {
+ my $self = shift;
+ my ($name) = @_;
+
+ my $e = bless(
+ {
+ trace => bless({%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
+ name => $name,
+ },
+ "Test2::Event::Pass"
+ );
+
+ $self->{+HUB}->send($e);
+ return $e;
+}
+
+sub pass_and_release {
+ my $self = shift;
+ my ($name) = @_;
+
+ my $e = bless(
+ {
+ trace => bless({%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
+ name => $name,
+ },
+ "Test2::Event::Pass"
+ );
+
+ $self->{+HUB}->send($e);
+ $self->release;
+ return 1;
+}
+
+sub fail {
+ my $self = shift;
+ my ($name, @diag) = @_;
+
+ my $e = bless(
+ {
+ trace => bless({%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
+ name => $name,
+ },
+ "Test2::Event::Fail"
+ );
+
+ $e->add_info({tag => 'DIAG', debug => 1, details => $_}) for @diag;
+ $self->{+HUB}->send($e);
+ return $e;
+}
+
+sub fail_and_release {
+ my $self = shift;
+ my ($name, @diag) = @_;
+
+ my $e = bless(
+ {
+ trace => bless({%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
+ name => $name,
+ },
+ "Test2::Event::Fail"
+ );
+
+ $e->add_info({tag => 'DIAG', debug => 1, details => $_}) for @diag;
+ $self->{+HUB}->send($e);
+ $self->release;
+ return 0;
+}
+
sub ok {
my $self = shift;
my ($pass, $name, $on_fail) = @_;
@@ -238,7 +319,7 @@ sub ok {
my $hub = $self->{+HUB};
my $e = bless {
- trace => bless( {%{$self->{+TRACE}}}, 'Test2::Util::Trace'),
+ trace => bless( {%{$self->{+TRACE}}}, 'Test2::EventFacet::Trace'),
pass => $pass,
name => $name,
}, 'Test2::Event::Ok';
@@ -250,14 +331,7 @@ sub ok {
$self->failure_diag($e);
if ($on_fail && @$on_fail) {
- for my $of (@$on_fail) {
- if (ref($of) eq 'CODE' || (blessed($of) && $of->can('render'))) {
- $self->info($of, diagnostics => 1);
- }
- else {
- $self->diag($of);
- }
- }
+ $self->diag($_) for @$on_fail;
}
return $e;
@@ -267,13 +341,6 @@ sub failure_diag {
my $self = shift;
my ($e) = @_;
- # This behavior is inherited from Test::Builder which injected a newline at
- # the start of the first diagnostics when the harness is active, but not
- # verbose. This is important to keep the diagnostics from showing up
- # appended to the existing line, which is hard to read. In a verbose
- # harness there is no need for this.
- my $prefix = $ENV{HARNESS_ACTIVE} && !$ENV{HARNESS_IS_VERBOSE} ? "\n" : "";
-
# Figure out the debug info, this is typically the file name and line
# number, but can also be a custom message. If no trace object is provided
# then we have nothing useful to display.
@@ -284,8 +351,8 @@ sub failure_diag {
# Create the initial diagnostics. If the test has a name we put the debug
# info on a second line, this behavior is inherited from Test::Builder.
my $msg = defined($name)
- ? qq[${prefix}Failed test '$name'\n$debug.\n]
- : qq[${prefix}Failed test $debug.\n];
+ ? qq[Failed test '$name'\n$debug.\n]
+ : qq[Failed test $debug.\n];
$self->diag($msg);
}
@@ -302,12 +369,6 @@ sub skip {
);
}
-sub info {
- my $self = shift;
- my ($renderer, %params) = @_;
- $self->send_event('Info', renderer => $renderer, %params);
-}
-
sub note {
my $self = shift;
my ($message) = @_;
@@ -509,7 +570,7 @@ current one to which all events should be sent.
=item $dbg = $ctx->trace()
-This will return the L<Test2::Util::Trace> instance used by the context.
+This will return the L<Test2::EventFacet::Trace> instance used by the context.
=item $ctx->do_in_context(\&code, @args);
@@ -555,23 +616,100 @@ The value of C<$@> when the context was created.
=over 4
+=item $event = $ctx->pass()
+
+=item $event = $ctx->pass($name)
+
+This will send and return an L<Test2::Event::Pass> event. You may optionally
+provide a C<$name> for the assertion.
+
+The L<Test2::Event::Pass> is a specially crafted and optimized event, using
+this will help the performance of passing tests.
+
+=item $true = $ctx->pass_and_release()
+
+=item $true = $ctx->pass_and_release($name)
+
+This is a combination of C<pass()> and C<release()>. 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.
+
+ 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 ...
+ }
+
+=item my $event = $ctx->fail()
+
+=item my $event = $ctx->fail($name)
+
+=item my $event = $ctx->fail($name, @diagnostics)
+
+This lets you send an L<Test2::Event::Fail> event. You may optionally provide a
+C<$name> and C<@diagnostics> messages.
+
+=item my $false = $ctx->fail_and_release()
+
+=item my $false = $ctx->fail_and_release($name)
+
+=item my $false = $ctx->fail_and_release($name, @diagnostics)
+
+This is a combination of C<fail()> and C<release()>. This can be used to write
+clearer and shorter code.
+
+ 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 ...
+ }
+
+
=item $event = $ctx->ok($bool, $name)
=item $event = $ctx->ok($bool, $name, \@on_fail)
+B<NOTE:> Use of this method is discouraged in favor of C<pass()> and C<fail()>
+which produce L<Test2::Event::Pass> and L<Test2::Event::Fail> events. These
+newer event types are faster and less crufty.
+
This will create an L<Test2::Event::Ok> object for you. If C<$bool> is false
then an L<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
C<send_event()> method directly.
The third argument C<\@on_fail>) is an optional set of diagnostics to be sent in
-the event of a test failure. Plain strings will be sent as
-L<Test2::Event::Diag> events. References will be used to construct
-L<Test2::Event::Info> events with C<< diagnostics => 1 >>.
-
-=item $event = $ctx->info($renderer, diagnostics => $bool, %other_params)
-
-Send an L<Test2::Event::Info>.
+the event of a test failure.
=item $event = $ctx->note($message)
@@ -617,6 +755,22 @@ or
This is the same as C<send_event()>, except it builds and returns the event
without sending it.
+=item $event = $ctx->send_event_and_release($Type, %parameters)
+
+This is a combination of C<send_event()> and C<release()>.
+
+ sub shorthand {
+ my $ctx = context();
+ return $ctx->send_event_and_release(Pass => { name => 'foo' });
+ }
+
+ sub longform {
+ my $ctx = context();
+ my $event = $ctx->send_event(Pass => { name => 'foo' });
+ $ctx->release;
+ return $event;
+ }
+
=back
=head1 HOOKS
@@ -729,7 +883,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.