Initial Commit
This commit is contained in:
88
database/perl/vendor/lib/Test2/Manual/Anatomy.pm
vendored
Normal file
88
database/perl/vendor/lib/Test2/Manual/Anatomy.pm
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
package Test2::Manual::Anatomy;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Anatomy - The hub for documentation of the inner workings of
|
||||
Test2 components.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This section covers internals of the Test2 architecture. This is useful
|
||||
information for toolbuilder, but is essential information for maintainers of
|
||||
Test2 itself.
|
||||
|
||||
=head1 END TO END
|
||||
|
||||
The L<Test2::Manual::Anatomy::EndToEnd> document is an overview of Test2 from load to finish.
|
||||
|
||||
=head1 EVENTS
|
||||
|
||||
The L<Test2::Manual::Anatomy::Event> document explains the internals of events.
|
||||
|
||||
=head1 THE CONTEXT
|
||||
|
||||
The L<Test2::Manual::Anatomy::Context> document explains how the
|
||||
L<Test2::API::Context> object works.
|
||||
|
||||
=head1 THE API AND THE API INSTANCE
|
||||
|
||||
The L<Test2::Manual::Anatomy::API> document explains the inner workings of the
|
||||
Test2 API.
|
||||
|
||||
=head1 HUBS
|
||||
|
||||
The L<Test2::Manual::Anatomy::Hubs> document explains the inner working of
|
||||
the Test2 hub stack, and the hubs therein.
|
||||
|
||||
=head1 THE IPC SYSTEM
|
||||
|
||||
The L<Test2::Manual::Anatomy::IPC> document describes the IPC system.
|
||||
|
||||
=head1 INTERNAL UTILITIES
|
||||
|
||||
The L<Test2::Manual::Anatomy::Utilities> document describes various utilities
|
||||
provided by the Test2 system.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
78
database/perl/vendor/lib/Test2/Manual/Anatomy/API.pm
vendored
Normal file
78
database/perl/vendor/lib/Test2/Manual/Anatomy/API.pm
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
package Test2::Manual::Anatomy::API;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Anatomy::API - Internals documentation for the API.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This document covers some of the internals of L<Test2::API>.
|
||||
|
||||
=head1 IMPLEMENTATION DETAILS
|
||||
|
||||
=head2 Test2::API
|
||||
|
||||
L<Test2::API> provides a functional interface to any test2 global state. This
|
||||
API should be preserved regardless of internal details of how and where the
|
||||
global state is stored.
|
||||
|
||||
This module itself does not store any state (with a few minor exceptions) but
|
||||
instead relies on L<Test2::API::Instance> to store state. This module is really
|
||||
intended to be the layer between the consumer and the implementation details.
|
||||
Ideally the implementation details can change any way they like, and this
|
||||
module can be updated to use the new details without breaking anything.
|
||||
|
||||
=head2 Test2::API::Instance
|
||||
|
||||
L<Test2::API::Instance> is where the global state is actually managed. This is
|
||||
an implementation detail, and should not be relied upon. It is entirely
|
||||
possible that L<Test2::API::Instance> could be removed completely, or changed
|
||||
in incompatible ways. Really these details are free to change so long as
|
||||
L<Test2::API> is not broken.
|
||||
|
||||
L<Test2::API::Instance> is fairly well documented, so no additionally
|
||||
documentation is needed for this manual page.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
114
database/perl/vendor/lib/Test2/Manual/Anatomy/Context.pm
vendored
Normal file
114
database/perl/vendor/lib/Test2/Manual/Anatomy/Context.pm
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
package Test2::Manual::Anatomy::Context;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Anatomy::Context - Internals documentation for the Context
|
||||
objects.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This document explains how the L<Test2::API::Context> object works.
|
||||
|
||||
=head1 WHAT IS THE CONTEXT OBJECT?
|
||||
|
||||
The context object is one of the key components of Test2, and makes many
|
||||
features possible that would otherwise be impossible. Every test tool starts by
|
||||
getting a context, and ends by releasing the context. A test tool does all its
|
||||
work between getting and releasing the context. The context instance is the
|
||||
primary interface for sending events to the Test2 stack. Finally the context
|
||||
system is responsible for tracking what file and line number a tool operates
|
||||
on, which is critical for debugging.
|
||||
|
||||
=head2 PRIMARY INTERFACE FOR TEST TOOLS
|
||||
|
||||
Nearly every Test2 based tool should start by calling C<$ctx =
|
||||
Test2::API::context()> in order to get a context object, and should end by
|
||||
calling C<< $ctx->release() >>. Once a tool has its context object it can call
|
||||
methods on the object to send events or have other effects. Nearly everything a
|
||||
test tool needs to do should be done through the context object.
|
||||
|
||||
=head2 TRACK FILE AND LINE NUMBERS FOR ERROR REPORTING
|
||||
|
||||
When you call C<Test2::API::Context> a new context object will be returned. If
|
||||
there is already a context object in effect (from a different point in the
|
||||
stack) you will get a clone of the existing one. If there is not already a
|
||||
current context then a completely new one will be generated. When a new context
|
||||
is generated Test2 will determine the file name and line number for your test
|
||||
code, these will be used when reporting any failures.
|
||||
|
||||
Typically the file and line number will be determined using C<caller()> to look
|
||||
at your tools caller. The C<$Test::Builder::Level> will be respected if
|
||||
detected, but is discouraged in favor of just using context objects at every
|
||||
level.
|
||||
|
||||
When calling C<Test2::API::Context()> you can specify the
|
||||
C<< level => $count >> arguments if you need to look at a deeper caller.
|
||||
|
||||
=head2 PRESERVE $?, $!, $^E AND $@
|
||||
|
||||
When you call C<Test2::API::context()> the current values of C<$?>, C<$!>,
|
||||
C<$^E>, and C<$@> are stored in the context object itself. Whenever the context
|
||||
is released the original values of these variables will be restored. This
|
||||
protects the variables from any side effects caused by testing tools.
|
||||
|
||||
=head2 FINALIZE THE API STATE
|
||||
|
||||
L<Test2::API> works via a hidden singleton instance of L<Test2::API::Instance>.
|
||||
The singleton has some state that is not set in stone until the last possible
|
||||
minute. The last possible minute happens to be the first time a context is
|
||||
acquired. State includes IPC instance, Formatter class, Root PID, etc.
|
||||
|
||||
=head2 FIND/CREATE THE CURRENT/ROOT HUB
|
||||
|
||||
L<Test2> has a stack of hubs, the stack can be accessed via
|
||||
L<Test2::API::test2_stack>. When you get a context it will find the current
|
||||
hub, if there is no current hub then the root one will be initialized.
|
||||
|
||||
=head2 PROVIDE HOOKS
|
||||
|
||||
There are hooks that run when contexts are created, found, and released. See
|
||||
L<Test2::API> for details on these hooks and how to use them.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
376
database/perl/vendor/lib/Test2/Manual/Anatomy/EndToEnd.pm
vendored
Normal file
376
database/perl/vendor/lib/Test2/Manual/Anatomy/EndToEnd.pm
vendored
Normal file
@@ -0,0 +1,376 @@
|
||||
package Test2::Manual::Anatomy::EndToEnd;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::EndToEnd - Overview of Test2 from load to finish.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a high level overview of everything from loading Test2 through the end
|
||||
of a test script.
|
||||
|
||||
=head1 WHAT HAPPENS WHEN I LOAD THE API?
|
||||
|
||||
use Test2::API qw/context/;
|
||||
|
||||
=over 4
|
||||
|
||||
=item A singleton instance of Test2::API::Instance is created.
|
||||
|
||||
You have no access to this, it is an implementation detail.
|
||||
|
||||
=item Several API functions are defined that use the singleton instance.
|
||||
|
||||
You can import these functions, or use them directly.
|
||||
|
||||
=item Then what?
|
||||
|
||||
It waits...
|
||||
|
||||
The API intentionally does as little as possible. At this point something can
|
||||
still change the formatter, load L<Test2::IPC>, or have other global effects
|
||||
that need to be done before the first L<Test2::API::Context> is created. Once
|
||||
the first L<Test2::API::Context> is created the API will finish initialization.
|
||||
|
||||
See L</"WHAT HAPPENS WHEN I ACQUIRE A CONTEXT?"> for more information.
|
||||
|
||||
=back
|
||||
|
||||
=head1 WHAT HAPPENS WHEN I USE A TOOL?
|
||||
|
||||
This section covers the basic workflow all tools such as C<ok()> must follow.
|
||||
|
||||
sub ok($$) {
|
||||
my ($bool, $name) = @_;
|
||||
|
||||
my $ctx = context();
|
||||
|
||||
my $event = $ctx->send_event('Ok', pass => $bool, name => $name);
|
||||
|
||||
...
|
||||
|
||||
$ctx->release;
|
||||
return $bool;
|
||||
}
|
||||
|
||||
ok(1, "1 is true");
|
||||
|
||||
=over 4
|
||||
|
||||
=item A tool function is run.
|
||||
|
||||
ok(1, "1 is true");
|
||||
|
||||
=item The tool acquires a context object.
|
||||
|
||||
my $ctx = context();
|
||||
|
||||
See L</"WHAT HAPPENS WHEN I ACQUIRE A CONTEXT?"> for more information.
|
||||
|
||||
=item The tool uses the context object to create, send, and return events.
|
||||
|
||||
See L</"WHAT HAPPENS WHEN I SEND AN EVENT?"> for more information.
|
||||
|
||||
my $event = $ctx->send_event('Ok', pass => $bool, name => $name);
|
||||
|
||||
=item When done the tool MUST release the context.
|
||||
|
||||
See L</"WHAT HAPPENS WHEN I RELEASE A CONTEXT?"> for more information.
|
||||
|
||||
$ctx->release();
|
||||
|
||||
=item The tool returns.
|
||||
|
||||
return $bool;
|
||||
|
||||
=back
|
||||
|
||||
=head1 WHAT HAPPENS WHEN I ACQUIRE A CONTEXT?
|
||||
|
||||
my $ctx = context();
|
||||
|
||||
These actions may not happen exactly in this order, but that is an
|
||||
implementation detail. For the purposes of this document this order is used to
|
||||
help the reader understand the flow.
|
||||
|
||||
=over 4
|
||||
|
||||
=item $!, $@, $? and $^E are captured and preserved.
|
||||
|
||||
Test2 makes a point to preserve the values of $!, $@, $? and $^E such that the test
|
||||
tools do not modify these variables unexpectedly. They are captured first thing
|
||||
so that they can be restored later.
|
||||
|
||||
=item The API state is changed to 'loaded'.
|
||||
|
||||
The 'loaded' state means that test tools have already started running. This is
|
||||
important as some plugins need to take effect before any tests are run. This
|
||||
state change only happens the first time a context is acquired, and may trigger
|
||||
some hooks defined by plugins to run.
|
||||
|
||||
=item The current hub is found.
|
||||
|
||||
A context attaches itself to the current L<Test2::Hub>. If there is no current
|
||||
hub then the root hub will be initialized. This will also initialize the hub
|
||||
stack if necessary.
|
||||
|
||||
=item Context acquire hooks fire.
|
||||
|
||||
It is possible to create global, or hub-specific hooks that fire whenever a
|
||||
context is acquired, these hooks will fire now. These hooks fire even if there
|
||||
is an existing context.
|
||||
|
||||
=item Any existing context is found.
|
||||
|
||||
If the current hub already has a context then a clone of it will be used
|
||||
instead of a completely new context. This is important because it allows nested
|
||||
tools to inherit the context used by parent tools.
|
||||
|
||||
=item Stack depth is measured.
|
||||
|
||||
Test2 makes a point to catch mistakes in how the context is used. The stack
|
||||
depth is used to accomplish this. If there is an existing context the depth
|
||||
will be checked against the one found here. If the old context has the same
|
||||
stack depth, or a shallower one, it means a tool is misbehaving and did not
|
||||
clean up the context when it was done, in which case the old context will be
|
||||
cleaned up, and a warning issued.
|
||||
|
||||
=item A new context is created (if no existing context was found)
|
||||
|
||||
If there is no existing context, a new one will be created using the data
|
||||
collected so far.
|
||||
|
||||
=item Context init hooks fire (if no existing context was found)
|
||||
|
||||
If a new context was created, context-creation hooks will fire.
|
||||
|
||||
=item $!, $@, $?, and $^E are restored.
|
||||
|
||||
We make sure $!, $@, $?, and $^E are unchanged at this point so that changes we
|
||||
made will not effect anything else. This is done in case something inside the
|
||||
context construction accidentally changed these vars.
|
||||
|
||||
=item The context is returned.
|
||||
|
||||
You have a shiney new context object, or a clone of the existing context.
|
||||
|
||||
=back
|
||||
|
||||
=head1 WHAT HAPPENS WHEN I SEND AN EVENT?
|
||||
|
||||
my $event = $ctx->send_event('Ok', pass => $bool, name => $name);
|
||||
|
||||
=over 4
|
||||
|
||||
=item The Test2::Event::Ok module is loaded.
|
||||
|
||||
The C<send_event()> method will automatically load any Event package necessary.
|
||||
Normally C<send_event()> will assume the first argument is an event class
|
||||
without the C<Test2::Event::> prefix, which it will add for you. If you want to
|
||||
use an event class that is in a different namespace you can prefix the class
|
||||
name with a C<+> to tell the tool that you are giving a fully qualified class
|
||||
name:
|
||||
|
||||
my $event = $ctx->send_event('+Fully::Qualified::Event', pass => $bool, name => $name);
|
||||
|
||||
=item A new instance of Test2::Event::Ok is created.
|
||||
|
||||
The event object is instantiated using the provided parameters.
|
||||
|
||||
=item The event object is sent to the hub.
|
||||
|
||||
The hub takes over from here.
|
||||
|
||||
=item The hub runs the event through any filters.
|
||||
|
||||
Filters are able to modify or remove events. Filters are run first, before the
|
||||
event can modify global test state.
|
||||
|
||||
=item The global test state is updated to reflect the event.
|
||||
|
||||
If the event effects test count then the count will be incremented. If the
|
||||
event causes failure then the failure count will be incremented. There are a
|
||||
couple other ways the global state can be effected as well.
|
||||
|
||||
=item The event is sent to the formatter
|
||||
|
||||
After the state is changed the hub will send the event to the formatter for
|
||||
rendering. This is where TAP is normally produced.
|
||||
|
||||
=item The event is sent to all listeners.
|
||||
|
||||
There can be any number of listeners that take action when events are
|
||||
processed, this happens now.
|
||||
|
||||
=back
|
||||
|
||||
=head1 WHAT HAPPENS WHEN I RELEASE A CONTEXT?
|
||||
|
||||
$ctx->release;
|
||||
|
||||
=over 4
|
||||
|
||||
=item The current context clone is released.
|
||||
|
||||
If your tool is nested inside another, then releasing will simply destroy the
|
||||
copy of the context, nothing else will happen.
|
||||
|
||||
=item If this was the canonical context, it will actually release
|
||||
|
||||
When a context is created it is considered 'canon'. Any context obtained by a
|
||||
nested tool will be considered a child context linked to the canonical one.
|
||||
Releasing child contexts does not do anything of note (but is still required).
|
||||
|
||||
=item Release hooks are called
|
||||
|
||||
Release hooks are the main motivation behind making the C<release()> method,
|
||||
and making it a required action on the part of test tools. These are hooks that
|
||||
we can have called when a tool is complete. This is how plugins like
|
||||
L<Test2::Plugin::DieOnFail> are implemented. If we simply had a destructor call
|
||||
the hooks then we would be unable to write this plugin as a C<die> inside of a
|
||||
destructor is useless.
|
||||
|
||||
=item The context is cleared
|
||||
|
||||
The main context data is cleared allowing the next tool to create a new
|
||||
context. This is important as the next tool very likely has a new line number.
|
||||
|
||||
=item $!, $@, $?, and $^E are restored
|
||||
|
||||
When a Test2 tool is complete it will restore $@, $!, $? and $^E to avoid action at
|
||||
a distance.
|
||||
|
||||
=back
|
||||
|
||||
=head1 WHAT HAPPENS WHEN I USE done_testing()?
|
||||
|
||||
done_testing();
|
||||
|
||||
=over 4
|
||||
|
||||
=item Any pending IPC events will be culled.
|
||||
|
||||
If IPC is turned on, a final culling will take place.
|
||||
|
||||
=item Follow-up hooks are run
|
||||
|
||||
The follow-up hooks are a way to run actions when a hub is complete. This is
|
||||
useful for adding cleanup tasks, or final tests to the end of a test.
|
||||
|
||||
=item The final plan event is generated and processed.
|
||||
|
||||
The final plan event will be produced using the current test count as the
|
||||
number of tests planned.
|
||||
|
||||
=item The current hub is finalized.
|
||||
|
||||
This will mark the hub is complete, and will not allow new events to be
|
||||
processed.
|
||||
|
||||
=back
|
||||
|
||||
=head1 WHAT HAPPENS WHEN A TEST SCRIPT IS DONE?
|
||||
|
||||
Test2 has some behaviors it runs in an C<END { ... }> block after tests are
|
||||
done running. This end block does some final checks to warn you if something
|
||||
went wrong. This end block also sets the exit value of the script.
|
||||
|
||||
=over 4
|
||||
|
||||
=item API Versions are checked.
|
||||
|
||||
A warning will be produced if L<Test::Builder> is loaded, but has a different
|
||||
version compared to L<Test2::API>. This situation can happen if you downgrade
|
||||
to an older Test-Simple distribution, and is a bad situation.
|
||||
|
||||
=item Any remaining context objects are cleaned up.
|
||||
|
||||
If there are leftover context objects they will need to be cleaned up. A
|
||||
leftover context is never a good thing, and usually requires a warning. A
|
||||
leftover context could also be the result of an exception being thrown which
|
||||
terminates the script, L<Test2> is fairly good at noticing this and not warning
|
||||
in these cases as the warning would simply be noise.
|
||||
|
||||
=item Child processes are sent a 'waiting' event.
|
||||
|
||||
If IPC is active, a waiting event is sent to all child processes.
|
||||
|
||||
=item The script will wait for all child processes and/or threads to complete.
|
||||
|
||||
This happens only when IPC is loaded, but Test::Builder is not. This behavior
|
||||
is useful, but would break compatibility for legacy tests.
|
||||
|
||||
=item The hub stack is cleaned up.
|
||||
|
||||
All hubs are finalized starting from the top. Leftover hubs are usually a bad
|
||||
thing, so a warning is produced if any are found.
|
||||
|
||||
=item The root hub is finalized.
|
||||
|
||||
This step is a no-op if C<done_testing()> was used. If needed this will mark
|
||||
the root hub as finished.
|
||||
|
||||
=item Exit callbacks are called.
|
||||
|
||||
This is a chance for plugins to modify the final exit value of the script.
|
||||
|
||||
=item The scripts exit value ($?) is set.
|
||||
|
||||
If the test encountered any failures this will be set to a non-zero value. If
|
||||
possible this will be set to the number of failures, or 255 if the number is
|
||||
larger than 255 (the max value allowed).
|
||||
|
||||
=item Broken module diagnostics
|
||||
|
||||
Test2 is aware of many modules which were broken by Test2's release. At this
|
||||
point the script will check if any known-broken modules were loaded, and warn
|
||||
you if they were.
|
||||
|
||||
B<Note:> This only happens if there were test failures. No broken module
|
||||
warnings are produced on a success.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
416
database/perl/vendor/lib/Test2/Manual/Anatomy/Event.pm
vendored
Normal file
416
database/perl/vendor/lib/Test2/Manual/Anatomy/Event.pm
vendored
Normal file
@@ -0,0 +1,416 @@
|
||||
package Test2::Manual::Anatomy::Event;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Anatomy::Event - The internals of events
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Events are how tools effect global state, and pass information along to the
|
||||
harness, or the human running the tests.
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
Before proceeding it is important that you know some history of events.
|
||||
Initially there was an event API, and an event would implement the API to
|
||||
produce an effect. This API proved to be lossy and inflexible. Recently the
|
||||
'facet' system was introduced, and makes up for the shortcoming and
|
||||
inflexibility of the old API.
|
||||
|
||||
All events must still implement the old API, but that can be largely automated
|
||||
if you use the facet system effectively. Likewise essential facets can often be
|
||||
deduced from events that only implement the old API, though their information
|
||||
maybe less complete.
|
||||
|
||||
=head1 THE EVENT OBJECT
|
||||
|
||||
All event objects must subclass L<Test2::Event>. If you inherit from this base
|
||||
class, and implement the old API properly, facets will be generated for you for
|
||||
free. On the other hand you can inherit from this, and also import
|
||||
L<Test2::Util::Facets2Legacy> which will instead rely on your facet data, and
|
||||
deduce the old API from them.
|
||||
|
||||
All new events C<MUST> implement both APIs one way or the other. A common way
|
||||
to do this is to simply implement both APIs directly in your event.
|
||||
|
||||
Here is a good template for a new event:
|
||||
|
||||
package Test2::Event::Mine;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use parent 'Test2::Event';
|
||||
use Test2::Util::Facets2Legacy ':ALL';
|
||||
|
||||
sub facet_data {
|
||||
my $self = shift;
|
||||
|
||||
# Adds 'about', 'amnesty', and 'trace' facets
|
||||
my $out = $self->common_facet_data;
|
||||
|
||||
# Add any additional facets to the $out hashref
|
||||
...
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 THE FACET API
|
||||
|
||||
The new API is a single method: C<facet_data()>. This method must return a
|
||||
hashref where each key is specific to a facet type, and the value is either a
|
||||
facet hashref, or an array of hashrefs. Some facets C<MUST> be lone hashrefs,
|
||||
others C<MUST> be hashrefs inside an arrayref.
|
||||
|
||||
The I<standard> facet types are as follows:
|
||||
|
||||
=over 4
|
||||
|
||||
=item assert => {details => $name, pass => $bool, no_debug => $bool, number => $maybe_int}
|
||||
|
||||
Documented in L<Test2::EventFacet::Assert>. An event may only have one.
|
||||
|
||||
The 'details' key is the name of the assertion.
|
||||
|
||||
The 'pass' key denotes a passing or failing assertion.
|
||||
|
||||
The 'no_debug' key tells any harness or formatter that diagnostics should not
|
||||
be added automatically to a failing assertion (used when there are custom
|
||||
diagnostics instead).
|
||||
|
||||
The 'number' key is for harness use, never set it yourself.
|
||||
|
||||
=item about => {details => $string, no_display => $bool, package => $pkg}
|
||||
|
||||
Documented in L<Test2::EventFacet::About>. An event may only have one.
|
||||
|
||||
'details' is a human readable string describing the overall event.
|
||||
|
||||
'no_display' means that a formatter/harness should hide the event.
|
||||
|
||||
'package' is the package of the event the facet describes (IE: L<Test2::Event::Ok>)
|
||||
|
||||
=item amnesty => [{details => $string, tag => $short_string, inherited => $bool}]
|
||||
|
||||
Documented in L<Test2::EventFacet::Amnesty>. An event may have multiple.
|
||||
|
||||
This event is how things like 'todo' are implemented. Amnesty prevents a
|
||||
failing assertion from causing a global test failure.
|
||||
|
||||
'details' is a human readable description of why the failure is being granted
|
||||
amnesty (IE The 'todo' reason)
|
||||
|
||||
'tag' is a short human readable string, or category for the amnesty. This is
|
||||
typically 'TODO' or 'SKIP'.
|
||||
|
||||
'inherited' is true if the amnesty was applied in a parent context (true if
|
||||
this test is run in a subtest that is marked todo).
|
||||
|
||||
=item control => {details => $string, global => $bool, terminate => $maybe_int, halt => $bool, has_callback => $bool, encoding => $enc}
|
||||
|
||||
Documented in L<Test2::EventFacet::Control>. An event may have one.
|
||||
|
||||
This facet is used to apply extra behavior when the event is processed.
|
||||
|
||||
'details' is a human readable explanation for the behavior.
|
||||
|
||||
'global' true if this event should be forwarded to, and processed by, all hubs
|
||||
everywhere. (bail-out uses this)
|
||||
|
||||
'terminate' this should either be undef, or an integer. When defined this will
|
||||
cause the test to exit with the specific exit code.
|
||||
|
||||
'halt' is used to signal any harness that no further test files should be run
|
||||
(bail-out uses this).
|
||||
|
||||
'has_callback' is set to true if the event has a callback sub defined.
|
||||
|
||||
'encoding' used to tell the formatter what encoding to use.
|
||||
|
||||
=item errors => [{details => $string, tag => $short_string, fail => $bool}]
|
||||
|
||||
Documented in L<Test2::EventFacet::Error>. An event may have multiple.
|
||||
|
||||
'details' is a human readable explanation of the error.
|
||||
|
||||
'tag' is a short human readable category for the error.
|
||||
|
||||
'fail' is true if the error should cause test failure. If this is false the
|
||||
error is simply informative, but not fatal.
|
||||
|
||||
=item info => [{details => $string, tag => $short_string, debug => $bool, important => $bool}]
|
||||
|
||||
Documented in L<Test2::EventFacet::Info>. An event may have multiple.
|
||||
|
||||
This is how diag and note are implemented.
|
||||
|
||||
'details' human readable message.
|
||||
|
||||
'tag' short category for the message, such as 'diag' or 'note'.
|
||||
|
||||
'debug' is true if the message is diagnostics in nature, this is the main
|
||||
difference between a note and a diag.
|
||||
|
||||
'important' is true if the message is not diagnostics, but is important to have
|
||||
it shown anyway. This is primarily used to communicate with a harness.
|
||||
|
||||
=item parent => {details => $string, hid => $hid, children => [...], buffered => 1}
|
||||
|
||||
Documented in L<Test2::EventFacet::Parent>. An event may have one.
|
||||
|
||||
This is used by subtests.
|
||||
|
||||
'details' human readable name of the subtest.
|
||||
|
||||
'hid' subtest hub id.
|
||||
|
||||
'children' an arrayref containing facet_data instances from all child events.
|
||||
|
||||
'buffered' true if it was a buffered subtest.
|
||||
|
||||
=item plan => {details => $string, count => $int, skip => $bool, none => $bool}
|
||||
|
||||
Documented in L<Test2::EventFacet::Plan>. An event may have one.
|
||||
|
||||
'details' is a human readable string describing the plan (for instance, why a
|
||||
test is skipped)
|
||||
|
||||
'count' is the number of expected assertions (0 for skip)
|
||||
|
||||
'skip' is true if the plan is to skip the test.
|
||||
|
||||
'none' used for Test::More's 'no_plan' plan.
|
||||
|
||||
=item trace => {details => $string, frame => [$pkg, $file, $line, $sub], pid => $int, tid => $int, cid => $cid, hid => $hid, nested => $int, buffered => $bool}
|
||||
|
||||
Documented in L<Test2::EventFacet::Trace>. An event may have one.
|
||||
|
||||
This is how debugging information is tracked. This is taken from the context
|
||||
object at event creation.
|
||||
|
||||
'details' human readable debug message (otherwise generated from frame)
|
||||
|
||||
'frame' first 4 fields returned by caller:
|
||||
C<[$package, $file, $line, $subname]>.
|
||||
|
||||
'pid' the process id in which the event was created.
|
||||
|
||||
'tid' the thread is in which the event was created.
|
||||
|
||||
'cid' the id of the context used to create the event.
|
||||
|
||||
'hid' the id of the hub to which the event was sent.
|
||||
|
||||
'nest' subtest nesting depth of the event.
|
||||
|
||||
'buffered' is true if the event was generated inside a buffered subtest.
|
||||
|
||||
=back
|
||||
|
||||
Note that ALL facet types have a 'details' key that may have a string. This
|
||||
string should always be human readable, and should be an explanation for the
|
||||
facet. For an assertion this is the test name. For a plan this is the reason
|
||||
for the plan (such as skip reason). For info it is the human readable
|
||||
diagnostics message.
|
||||
|
||||
=head2 CUSTOM FACETS
|
||||
|
||||
You can write custom facet types as well, simply add a new key to the hash and
|
||||
populated it. The general rule is that any code looking at the facets should
|
||||
ignore any it does not understand.
|
||||
|
||||
Optionally you can also create a package to document your custom facet. The
|
||||
package should be proper object, and may have additional methods to help work
|
||||
with your facet.
|
||||
|
||||
package Test2::EventFacet::MyFacet;
|
||||
|
||||
use parent 'Test2::EventFacet';
|
||||
|
||||
sub facet_key { 'myfacet' }
|
||||
sub is_list { 0 }
|
||||
|
||||
1;
|
||||
|
||||
Your facet package should always be under the Test2::EventFacet:: namespace if
|
||||
you want any tools to automatically find it. The last part of the namespace
|
||||
should be the non-plural name of your facet with only the first word
|
||||
capitalized.
|
||||
|
||||
=over 4
|
||||
|
||||
=item $string = $facet_class->facet_key
|
||||
|
||||
The key for your facet should be the same as the last section of
|
||||
the namespace, but all lowercase. You I<may> append 's' to the key if your
|
||||
facet is a list type.
|
||||
|
||||
=item $bool = $facet_class->is_list
|
||||
|
||||
True if an event should put these facets in a list:
|
||||
|
||||
{ myfacet => [{}, {}] }
|
||||
|
||||
False if an event may only have one of this type of facet at a time:
|
||||
|
||||
{ myfacet => {} }
|
||||
|
||||
=back
|
||||
|
||||
=head3 EXAMPLES
|
||||
|
||||
The assert facet is not a list type, so its implementation would look like this:
|
||||
|
||||
package Test2::EventFacet::Assert;
|
||||
sub facet_key { 'assert' }
|
||||
sub is_list { 0 }
|
||||
|
||||
The amnesty facet is a list type, but amnesty does not need 's' appended to
|
||||
make it plural:
|
||||
|
||||
package Test2::EventFacet::Amnesty;
|
||||
sub facet_key { 'amnesty' }
|
||||
sub is_list { 1 }
|
||||
|
||||
The error facet is a list type, and appending 's' makes error plural as errors.
|
||||
This means the package name is '::Error', but the key is 'errors'.
|
||||
|
||||
package Test2::EventFacet::Error;
|
||||
sub facet_key { 'errors' }
|
||||
sub is_list { 1 }
|
||||
|
||||
B<Note> Do not worry too much about getting the key/pluralization wrong. Most
|
||||
tools will use L<Module::Pluggable> to load all facet types and build a hash
|
||||
linking keys to packages and so on, working backwards. This means, in general,
|
||||
that even if you get it wrong any tool that NEEDS the package for the facet
|
||||
will find it.
|
||||
|
||||
B<Note2:> In practice most tools completely ignore the facet packages, and work
|
||||
with the facet data directly in its raw structure. This is by design and
|
||||
recommended. The facet data is intended to be serialized frequently and passed
|
||||
around. When facets are concerned, data is important, classes and methods are
|
||||
not.
|
||||
|
||||
=head1 THE OLD API
|
||||
|
||||
The old API was simply a set of methods you were required to implement:
|
||||
|
||||
=over 4
|
||||
|
||||
=item $bool = $e->causes_fail
|
||||
|
||||
Returns true if this event should result in a test failure. In general this
|
||||
should be false.
|
||||
|
||||
=item $bool = $e->increments_count
|
||||
|
||||
Should be true if this event should result in a test count increment.
|
||||
|
||||
=item $e->callback($hub)
|
||||
|
||||
If your event needs to have extra effects on the L<Test2::Hub> you can override
|
||||
this method.
|
||||
|
||||
This is called B<BEFORE> your event is passed to the formatter.
|
||||
|
||||
=item $num = $e->nested
|
||||
|
||||
If this event is nested inside of other events, this should be the depth of
|
||||
nesting. (This is mainly for subtests)
|
||||
|
||||
=item $bool = $e->global
|
||||
|
||||
Set this to true if your event is global, that is ALL threads and processes
|
||||
should see it no matter when or where it is generated. This is not a common
|
||||
thing to want, it is used by bail-out and skip_all to end testing.
|
||||
|
||||
=item $code = $e->terminate
|
||||
|
||||
This is called B<AFTER> your event has been passed to the formatter. This
|
||||
should normally return undef, only change this if your event should cause the
|
||||
test to exit immediately.
|
||||
|
||||
If you want this event to cause the test to exit you should return the exit
|
||||
code here. Exit code of 0 means exit success, any other integer means exit with
|
||||
failure.
|
||||
|
||||
This is used by L<Test2::Event::Plan> to exit 0 when the plan is
|
||||
'skip_all'. This is also used by L<Test2::Event:Bail> to force the test
|
||||
to exit with a failure.
|
||||
|
||||
This is called after the event has been sent to the formatter in order to
|
||||
ensure the event is seen and understood.
|
||||
|
||||
=item $msg = $e->summary
|
||||
|
||||
This is intended to be a human readable summary of the event. This should
|
||||
ideally only be one line long, but you can use multiple lines if necessary. This
|
||||
is intended for human consumption. You do not need to make it easy for machines
|
||||
to understand.
|
||||
|
||||
The default is to simply return the event package name.
|
||||
|
||||
=item ($count, $directive, $reason) = $e->sets_plan()
|
||||
|
||||
Check if this event sets the testing plan. It will return an empty list if it
|
||||
does not. If it does set the plan it will return a list of 1 to 3 items in
|
||||
order: Expected Test Count, Test Directive, Reason for directive.
|
||||
|
||||
=item $bool = $e->diagnostics
|
||||
|
||||
True if the event contains diagnostics info. This is useful because a
|
||||
non-verbose harness may choose to hide events that are not in this category.
|
||||
Some formatters may choose to send these to STDERR instead of STDOUT to ensure
|
||||
they are seen.
|
||||
|
||||
=item $bool = $e->no_display
|
||||
|
||||
False by default. This will return true on events that should not be displayed
|
||||
by formatters.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
120
database/perl/vendor/lib/Test2/Manual/Anatomy/Hubs.pm
vendored
Normal file
120
database/perl/vendor/lib/Test2/Manual/Anatomy/Hubs.pm
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
package Test2::Manual::Anatomy::Hubs;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Anatomy::Hubs - Internals documentation for the hub stack, and
|
||||
hubs.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This document describes the hub stack, and the hubs it contains. It explains
|
||||
why we have a stack, and when to add/remove hubs from it.
|
||||
|
||||
=head1 WHAT IS A HUB?
|
||||
|
||||
Test2 is an event system, tools generate events, those events are then
|
||||
processed to modify the testing state (number of tests, number of failures,
|
||||
etc). The hub is responsible for receiving and processing events to record the
|
||||
change in state. All events should eventually reach a destination hub.
|
||||
|
||||
The base hub is L<Test2::Hub>. All hub classes should inherit from the base hub
|
||||
class. The base hub class provides several hooks that allow you to monitor or
|
||||
modify events. Hubs are also responsible for forwarding events to the output
|
||||
formatter.
|
||||
|
||||
=head1 WHY DO WE HAVE A HUB STACK?
|
||||
|
||||
There are cases where it makes sense to have more than one hub:
|
||||
|
||||
=over 4
|
||||
|
||||
=item subtests
|
||||
|
||||
In Test2 subtests are implemented using the hub stack. When you start a subtest
|
||||
a new L<Test2::Hub::Subtest> instance is created and pushed to the stack. Once
|
||||
this is done all calls to C<Test2::API::context> will find the new hub and send
|
||||
all events to it. When the subtest tool is complete it will remove the new hub,
|
||||
and send a final subtest event to the parent hub.
|
||||
|
||||
=item testing your test tools
|
||||
|
||||
C<Test2::API::intercept()> is implemented using the hub stack. The
|
||||
C<Test2::API::intercept()> function will add an L<Test2::Hub::Interceptor>
|
||||
instance to the stack, any calls to L<Test2::API::context()> will find the new
|
||||
hub, and send it all events. The intercept hub is special in that is has no
|
||||
connection to the parent hub, and usually does not have a formatter.
|
||||
|
||||
=back
|
||||
|
||||
=head1 WHEN SHOULD I ADD A HUB TO THE STACK?
|
||||
|
||||
Any time you want to intercept or block events from effecting the test state.
|
||||
Adding a new hub is essentially a way to create a sandbox where you have
|
||||
absolute control over what events do. Adding a new hub insures that the main
|
||||
test state will not be effected.
|
||||
|
||||
=head1 WHERE IS THE STACK?
|
||||
|
||||
The stack is an instance of L<Test2::API::Stack>. You can access the global hub
|
||||
stack using C<Test2::API::test2_stack>.
|
||||
|
||||
=head1 WHAT ABOUT THE ROOT HUB?
|
||||
|
||||
The root hub is created automatically as needed. A call to
|
||||
C<< Test2::API::test2_stack->top() >> will create the root hub if it does not
|
||||
already exist.
|
||||
|
||||
=head1 HOW DO HUBS HANDLE IPC?
|
||||
|
||||
If the IPC system (L<Test2::IPC>) was not loaded, then IPC is not handled at
|
||||
all. Forking or creating new threads without the IPC system can cause
|
||||
unexpected problems.
|
||||
|
||||
All hubs track the PID and Thread ID that was current when they were created.
|
||||
If an event is sent to a hub in a new process/thread the hub will detect this
|
||||
and try to forward the event along to the correct process/thread. This is
|
||||
accomplished using the IPC system.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
90
database/perl/vendor/lib/Test2/Manual/Anatomy/IPC.pm
vendored
Normal file
90
database/perl/vendor/lib/Test2/Manual/Anatomy/IPC.pm
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
package Test2::Manual::Anatomy::IPC;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Anatomy::IPC - Manual for the IPC system.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This document describes the IPC system.
|
||||
|
||||
=head1 WHAT IS THE IPC SYSTEM
|
||||
|
||||
The IPC system is activated by loading L<Test2::IPC>. This makes hubs
|
||||
process/thread aware, and makes them forward events along to the parent
|
||||
process/thread as necessary.
|
||||
|
||||
=head1 HOW DOES THE IPC SYSTEM EFFECT EVERYTHING?
|
||||
|
||||
L<Test2::API> and L<Test2::API::Instance> have some behaviors that trigger if
|
||||
L<Test2::IPC> is loaded before the global state is initialized. Mainly an IPC
|
||||
driver will be initiated and stored in the global state.
|
||||
|
||||
If an IPC driver is initialized then all hubs will be initialized with a
|
||||
reference to the driver instance. If a hub has an IPC driver instance it will
|
||||
use it to forward events to parent processes and threads.
|
||||
|
||||
=head1 WHAT DOES AN IPC DRIVER DO?
|
||||
|
||||
An L<Test2::IPC::Driver> provides a way to send event data to a destination
|
||||
process+thread+hub (or to all globally). The driver must also provide a way for
|
||||
a process/thread/hub to read in any pending events that have been sent to it.
|
||||
|
||||
=head1 HOW DOES THE DEFAULT IPC DRIVER WORK?
|
||||
|
||||
The default IPC driver is L<Test2::API::Driver::Files>. This default driver,
|
||||
when initialized, starts by creating a temporary directory. Any time an event
|
||||
needs to be sent to another process/thread/hub, the event will be written to a
|
||||
file using L<Storable>. The file is written with the destination process,
|
||||
thread, and hub as part of the filename. All hubs will regularly check for
|
||||
pending IPC events and will process them.
|
||||
|
||||
This driver is further optimized using a small chunk of SHM. Any time a new
|
||||
event is sent via IPC the shm is updated to have a new value. Hubs will not
|
||||
bother checking for new IPC events unless the shm value has changed since their
|
||||
last poll. A result of this is that the IPC system is surprisingly fast, and
|
||||
does not waste time polling the hard drive when there are no pending events.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
76
database/perl/vendor/lib/Test2/Manual/Anatomy/Utilities.pm
vendored
Normal file
76
database/perl/vendor/lib/Test2/Manual/Anatomy/Utilities.pm
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
package Test2::Manual::Anatomy::Utilities;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Anatomy::Utilities - Overview of utilities for Test2.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a brief overview of the utilities provided by Test2.
|
||||
|
||||
=head1 Test2::Util
|
||||
|
||||
L<Test2::Util> provides functions to help you find out about the current
|
||||
system, or to run generic tasks that tend to be Test2 specific.
|
||||
|
||||
This utility provides things like an internal C<try {...}> implementation, and
|
||||
constants for things like threading and forking support.
|
||||
|
||||
=head1 Test2::Util::ExternalMeta
|
||||
|
||||
L<Test2::Util::ExternalMeta> allows you to quickly and easily attach meta-data
|
||||
to an object class.
|
||||
|
||||
=head1 Test2::Util::Facets2Legacy
|
||||
|
||||
L<Test2::Util::Facets2Legacy> is a set of functions you can import into a more
|
||||
recent event class to provide the classic event API.
|
||||
|
||||
=head1 Test2::Util::HashBase
|
||||
|
||||
L<Test2::Util::HashBase> is a local copy of L<Object::HashBase>. All object
|
||||
classes provided by L<Test2> use this to generate methods and accessors.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
143
database/perl/vendor/lib/Test2/Manual/Concurrency.pm
vendored
Normal file
143
database/perl/vendor/lib/Test2/Manual/Concurrency.pm
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
package Test2::Manual::Concurrency;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Concurrency - Documentation for Concurrency support.
|
||||
|
||||
=head1 FORKING
|
||||
|
||||
=head2 Test2
|
||||
|
||||
Test2 supports forking. For forking to work you need to load L<Test2::IPC>.
|
||||
|
||||
=head2 Test::Builder
|
||||
|
||||
L<Test::Builder> Did not used to support forking, but now that it is based on
|
||||
L<Test2> it does. L<Test2::IPC> must be loaded just as with L<Test2>.
|
||||
|
||||
=head2 Test2::Suite
|
||||
|
||||
L<Test2::Suite> tools should all work fine with I<true> forking unless
|
||||
otherwise noted. Pseudo-fork via threads (Windows and a few others) is not
|
||||
supported, but may work.
|
||||
|
||||
Patches will be accepted to repair any pseudo-fork issues, but for these to be
|
||||
used or tested they must be requested. Fork tests should not run on pseudo-fork
|
||||
systems unless they are requested with an environment var, or the
|
||||
AUTHOR_TESTING var. Pseudo-fork is fragile, and we do not want to block install
|
||||
due to a pseudo-fork flaw.
|
||||
|
||||
=head2 Test::SharedFork
|
||||
|
||||
L<Test::SharedFork> is currently support and maintained, though it is no longer
|
||||
necessary thanks to L<Test2::IPC>. If usage ever drops off then the module may
|
||||
be deprecated, but for now the policy is to not let it break. Currently it
|
||||
simply loads L<Test2::IPC> if it can, and falls back to the old methods on
|
||||
legacy installs.
|
||||
|
||||
=head2 Others
|
||||
|
||||
Individual authors are free to support or not support forking as they see fit.
|
||||
|
||||
=head1 THREADING
|
||||
|
||||
B<Note> This only applies to ithreads.
|
||||
|
||||
=head2 Test2
|
||||
|
||||
The core of Test2 supports threading so long as L<Test2::IPC> is loaded. Basic
|
||||
threading support (making sure events make it to the parent thread) is fully
|
||||
supported, and must not be broken.
|
||||
|
||||
Some times perl installs have broken threads (Some 5.10 versions compiled on
|
||||
newer gcc's will segv by simply starting a thread). This is beyond Test2's
|
||||
control, and not solvable in Test2. That said we strive for basic threading
|
||||
support on perl 5.8.1+.
|
||||
|
||||
If Test2 fails for threads on any perl 5.8 or above, and it is reasonably
|
||||
possible for Test2 to work around the issue, it should. (Patches and bug
|
||||
reports welcome).
|
||||
|
||||
=head2 Test::Builder
|
||||
|
||||
L<Test::Builder> has had thread support for a long time. With Test2 the
|
||||
mechanism for thread support was switched to L<Test2::IPC>. L<Test::Builder>
|
||||
should still support threads as much as it did before the switch to Test2.
|
||||
Support includes auto-enabling thread support if L<threads> is loaded before
|
||||
Test::Builder.
|
||||
|
||||
If there is a deviation between the new and old threading behavior then it is a
|
||||
bug (unless the old behavior itself can be classified as a bug.) Please report
|
||||
(or patch!) any such threading issues.
|
||||
|
||||
=head2 Test2::Suite
|
||||
|
||||
Tools in L<Test2::Suite> have minimal threading support. Most of these tools do
|
||||
not care/notice threading and simply work because L<Test2::IPC> handles it.
|
||||
Feel free to report any thread related bugs in Test2::Suite. Be aware though
|
||||
that these tools are not legacy, and have no pre-existing thread support, we
|
||||
reserve the right to refuse adding thread support to them.
|
||||
|
||||
=head3 Test2::Workflow
|
||||
|
||||
L<Test2::Workflow> has been merged into L<Test2::Suite>, so it gets addressed
|
||||
by this policy.
|
||||
|
||||
L<Test2::Workflow> has thread support, but you must ask for it. Thread tests
|
||||
for Test2::Workflow do not event run without setting either the AUTHOR_TESTING
|
||||
env var, or the T2_DO_THREAD_TESTS env var.
|
||||
|
||||
To use threads with Test2::Workflow you must set the T2_WORKFLOW_USE_THREADS
|
||||
env var.
|
||||
|
||||
If you do rely on threads with Test2::Workflow and find a bug please report it,
|
||||
but it will be given an ultra-low priority. Merging patches that fix threading
|
||||
issues will be given normal priority.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2> - Test2 itself.
|
||||
|
||||
L<Test2::Suite> - Initial tools built using L<Test2>.
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
115
database/perl/vendor/lib/Test2/Manual/Contributing.pm
vendored
Normal file
115
database/perl/vendor/lib/Test2/Manual/Contributing.pm
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
package Test2::Manual::Contributing;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Contributing - How to contribute to the Test2 project.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a short manual page dedicated to helping people who wish to contribute
|
||||
to the Test2 project.
|
||||
|
||||
=head1 WAYS TO HELP
|
||||
|
||||
=head2 REPORT BUGS
|
||||
|
||||
The easiest way to help is to report bugs when you find them. Bugs are a fact
|
||||
of life when writing or using software. If you use Test2 long enough you are
|
||||
likely to find a bug. When you find such a bug it would help us out if you
|
||||
would submit a ticket.
|
||||
|
||||
=head3 BUG TRACKERS
|
||||
|
||||
Always try to find the preferred bug tracker for the module that has the bug.
|
||||
Here are the big 3 for the main Test2 project:
|
||||
|
||||
=over 4
|
||||
|
||||
=item Test2/Test-Builder/Test-More
|
||||
|
||||
L<https://github.com/Test-More/test-more/issues>
|
||||
|
||||
=item Test2-Suite
|
||||
|
||||
L<https://github.com/Test-More/Test2-Suite/issues>
|
||||
|
||||
=item Test2-Harness
|
||||
|
||||
L<https://github.com/Test-More/Test2-Harness/issues>
|
||||
|
||||
=back
|
||||
|
||||
=head2 SUBMIT PATCHES
|
||||
|
||||
You are welcome to fix bugs you find, or from the tracker. We also often accept
|
||||
patches that add new features or update documentation. The preferred method of
|
||||
submitting patches is a github pull request, that said we also accept patches
|
||||
via email.
|
||||
|
||||
=head2 ADD/UPDATE DOCUMENTATION
|
||||
|
||||
Documentation can be flawed just like code can be. Documentation can also
|
||||
become outdated. If you see some incorrect documentation, or documentation that
|
||||
is missing, we would love to get a patch to fix it!
|
||||
|
||||
=head2 ANSWER QUESTIONS ON IRC/SLACK
|
||||
|
||||
We are always hanging out on L<irc://irc.perl.org>, the #perl-qa and #toolchain
|
||||
channels are a good place to find us.
|
||||
|
||||
There is also a Test2 slack channel: L<https://perl-test2.slack.com>.
|
||||
|
||||
=head2 WRITE NEW TOOLS USING TEST2
|
||||
|
||||
Writing a new tool using Test2 is always a good way to contribute. When you
|
||||
write a tool that you think is useful, it is nice to share it by putting it on
|
||||
CPAN.
|
||||
|
||||
=head2 PORT OLD TOOLS TO TEST2
|
||||
|
||||
The C<Test::*> namespace has been around for a long time, and has a LOT of
|
||||
tools. The C<Test2::Tools::*> namespace is fairly young, and has less tools.
|
||||
Finding a useful old tool with no modern equivalent, and writing a port is a
|
||||
very good use of your time.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
245
database/perl/vendor/lib/Test2/Manual/Testing.pm
vendored
Normal file
245
database/perl/vendor/lib/Test2/Manual/Testing.pm
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
package Test2::Manual::Testing;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Testing - Hub for documentation about writing tests with Test2.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This document outlines all the tutorials and POD that cover writing tests. This
|
||||
section does not cover any Test2 internals, nor does it cover how to write new
|
||||
tools, for that see L<Test2::Manual::Tooling>.
|
||||
|
||||
=head1 NAMESPACE MAP
|
||||
|
||||
When writing tests there are a couple namespaces to focus on:
|
||||
|
||||
=over 4
|
||||
|
||||
=item Test2::Tools::*
|
||||
|
||||
This is where toolsets can be found. A toolset exports functions that help you
|
||||
make assertions about your code. Toolsets will only export functions, they
|
||||
should not ever have extra/global effects.
|
||||
|
||||
=item Test2::Plugins::*
|
||||
|
||||
This is where plugins live. Plugins should not export anything, but instead
|
||||
will introduce or alter behaviors for Test2 in general. These behaviors may be
|
||||
lexically scoped, or they may be global.
|
||||
|
||||
=item Test2::Bundle::*
|
||||
|
||||
Bundles combine toolsets and plugins together to reduce your boilerplate. First
|
||||
time test writers are encouraged to start with the L<Test2::V0> bundle (which
|
||||
is an exception to the namespace rule as it does not live under
|
||||
C<Test2::Bundle::>). If you find yourself loading several plugins and toolsets
|
||||
over and over again you could benefit from writing your own bundle.
|
||||
|
||||
=item Test2::Require::*
|
||||
|
||||
This namespace contains modules that will cause a test to skip if specific
|
||||
conditions are not met. Use this if you have tests that only run on specific
|
||||
perl versions, or require external libraries that may not always be available.
|
||||
|
||||
=back
|
||||
|
||||
=head1 LISTING DEPENDENCIES
|
||||
|
||||
When you use L<Test2>, specifically things included in L<Test2::Suite> you need
|
||||
to list them in your modules test dependencies. It is important to note that
|
||||
you should list the tools/plugins/bundles you need, you should not simply list
|
||||
L<Test2::Suite> as your dependency. L<Test2::Suite> is a living distribution
|
||||
intended to represent the "current" best practices. As tools, plugins, and
|
||||
bundles evolve, old ones will become discouraged and potentially be moved from
|
||||
L<Test2::Suite> into their own distributions.
|
||||
|
||||
One goal of L<Test2::Suite> is to avoid breaking backwards compatibility.
|
||||
Another goal is to always improve by replacing bad designs with better ones.
|
||||
When necessary L<Test2::Suite> will break old modules out into separate dists
|
||||
and define new ones, typically with a new bundle. In short, if we feel the need
|
||||
to break something we will do so by creating a new bundle, and discouraging the
|
||||
old one, but we will not break the old one.
|
||||
|
||||
So for example, if you use L<Test2::V0>, and L<Dist::Zilla> you
|
||||
should have this in your config:
|
||||
|
||||
[Prereqs / TestRequires]
|
||||
Test2::V0 = 0.000060
|
||||
|
||||
You B<SHOULD NOT> do this:
|
||||
|
||||
[Prereqs / TestRequires]
|
||||
Test2::Suite = 0.000060
|
||||
|
||||
Because L<Test2::V0> might not always be part of L<Test2::Suite>.
|
||||
|
||||
When writing new tests you should often check L<Test2::Suite> to see what the
|
||||
current recommended bundle is.
|
||||
|
||||
=head3 Dist::Zilla
|
||||
|
||||
[Prereqs / TestRequires]
|
||||
Test2::V0 = 0.000060
|
||||
|
||||
=head3 ExtUtils::MakeMaker
|
||||
|
||||
my %WriteMakefileArgs = (
|
||||
...,
|
||||
"TEST_REQUIRES" => {
|
||||
"Test2::V0" => "0.000060"
|
||||
},
|
||||
...
|
||||
);
|
||||
|
||||
=head3 Module::Install
|
||||
|
||||
test_requires 'Test2::V0' => '0.000060';
|
||||
|
||||
=head3 Module::Build
|
||||
|
||||
my $build = Module::Build->new(
|
||||
...,
|
||||
test_requires => {
|
||||
"Test2::V0" => "0.000060",
|
||||
},
|
||||
...
|
||||
);
|
||||
|
||||
=head1 TUTORIALS
|
||||
|
||||
=head2 SIMPLE/INTRODUCTION TUTORIAL
|
||||
|
||||
L<Test2::Manual::Testing::Introduction> is an introduction to writing tests
|
||||
using the L<Test2> tools.
|
||||
|
||||
=head2 MIGRATING FROM TEST::BUILDER and TEST::MORE
|
||||
|
||||
L<Test2::Manual::Testing::Migrating> Is a tutorial for converting old tests
|
||||
that use L<Test::Builder> or L<Test::More> to the newer L<Test2> way of doing
|
||||
things.
|
||||
|
||||
=head2 ADVANCED PLANNING
|
||||
|
||||
L<Test2::Manual::Testing::Planning> is a tutorial on the many ways to set a
|
||||
plan.
|
||||
|
||||
=head2 TODO TESTS
|
||||
|
||||
L<Test2::Manual::Testing::Todo> is a tutorial for markings tests as TODO.
|
||||
|
||||
=head2 SUBTESTS
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head2 COMPARISONS
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head3 SIMPLE COMPARISONS
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head3 ADVANCED COMPARISONS
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head2 TESTING EXPORTERS
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head2 TESTING CLASSES
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head2 TRAPPING
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head3 TRAPPING EXCEPTIONS
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head3 TRAPPING WARNINGS
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head2 DEFERRED TESTING
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head2 MANAGING ENCODINGS
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head2 AUTO-ABORT ON FAILURE
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head2 CONTROLLING RANDOM BEHAVIOR
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head2 WRITING YOUR OWN BUNDLE
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head1 TOOLSET DOCUMENTATION
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head1 PLUGIN DOCUMENTATION
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head1 BUNDLE DOCUMENTATION
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head1 REQUIRE DOCUMENTATION
|
||||
|
||||
COMING SOON.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
293
database/perl/vendor/lib/Test2/Manual/Testing/Introduction.pm
vendored
Normal file
293
database/perl/vendor/lib/Test2/Manual/Testing/Introduction.pm
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
package Test2::Manual::Testing::Introduction;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Testing::Introduction - Introduction to testing with Test2.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This tutorial is a beginners introduction to testing. This will take you
|
||||
through writing a test file, making assertions, and running your test.
|
||||
|
||||
=head1 BOILERPLATE
|
||||
|
||||
=head2 THE TEST FILE
|
||||
|
||||
Test files typically are placed inside the C<t/> directory, and end with the
|
||||
C<.t> file extension.
|
||||
|
||||
C<t/example.t>:
|
||||
|
||||
use Test2::V0;
|
||||
|
||||
# Assertions will go here
|
||||
|
||||
done_testing;
|
||||
|
||||
This is all the boilerplate you need.
|
||||
|
||||
=over 4
|
||||
|
||||
=item use Test2::V0;
|
||||
|
||||
This loads a collection of testing tools that will be described later in the
|
||||
tutorial. This will also turn on C<strict> and C<warnings> for you.
|
||||
|
||||
=item done_testing;
|
||||
|
||||
This should always be at the end of your test files. This tells L<Test2> that
|
||||
you are done making assertions. This is important as C<test2> will assume the
|
||||
test did not complete successfully without this, or some other form of test
|
||||
"plan".
|
||||
|
||||
=back
|
||||
|
||||
=head2 DIST CONFIG
|
||||
|
||||
You should always list bundles and tools directly. You should not simply list
|
||||
L<Test2::Suite> and call it done, bundles and tools may be moved out of
|
||||
L<Test2::Suite> to their own dists at any time.
|
||||
|
||||
=head3 Dist::Zilla
|
||||
|
||||
[Prereqs / TestRequires]
|
||||
Test2::V0 = 0.000060
|
||||
|
||||
=head3 ExtUtils::MakeMaker
|
||||
|
||||
my %WriteMakefileArgs = (
|
||||
...,
|
||||
"TEST_REQUIRES" => {
|
||||
"Test2::V0" => "0.000060"
|
||||
},
|
||||
...
|
||||
);
|
||||
|
||||
=head3 Module::Install
|
||||
|
||||
test_requires 'Test2::V0' => '0.000060';
|
||||
|
||||
=head3 Module::Build
|
||||
|
||||
my $build = Module::Build->new(
|
||||
...,
|
||||
test_requires => {
|
||||
"Test2::V0" => "0.000060",
|
||||
},
|
||||
...
|
||||
);
|
||||
|
||||
=head1 MAKING ASSERTIONS
|
||||
|
||||
The most simple tool for making assertions is C<ok()>. C<ok()> lets you assert
|
||||
that a condition is true.
|
||||
|
||||
ok($CONDITION, "Description of the condition");
|
||||
|
||||
Here is a complete C<t/example.t>:
|
||||
|
||||
use Test2::V0;
|
||||
|
||||
ok(1, "1 is true, so this will pass");
|
||||
|
||||
done_testing;
|
||||
|
||||
=head1 RUNNING THE TEST
|
||||
|
||||
Test files are simply scripts. Just like any other script you can run the test
|
||||
directly with perl. Another option is to use a test "harness" which runs the
|
||||
test for you, and provides extra information and checks the scripts exit value
|
||||
for you.
|
||||
|
||||
=head2 RUN DIRECTLY
|
||||
|
||||
$ perl -Ilib t/example.t
|
||||
|
||||
Which should produce output like this:
|
||||
|
||||
# Seeded srand with seed '20161028' from local date.
|
||||
ok 1 - 1 is true, so this will pass
|
||||
1..1
|
||||
|
||||
If the test had failed (C<ok(0, ...)>) it would look like this:
|
||||
|
||||
# Seeded srand with seed '20161028' from local date.
|
||||
not ok 1 - 0 is false, so this will fail
|
||||
1..1
|
||||
|
||||
Test2 will also set the exit value of the script, a successful run will have an
|
||||
exit value of 0, a failed run will have a non-zero exit value.
|
||||
|
||||
=head2 USING YATH
|
||||
|
||||
The C<yath> command line tool is provided by L<Test2::Harness> which you may
|
||||
need to install yourself from cpan. C<yath> is the harness written specifically
|
||||
for L<Test2>.
|
||||
|
||||
$ yath -Ilib t/example.t
|
||||
|
||||
This will produce output similar to this:
|
||||
|
||||
( PASSED ) job 1 t/example.t
|
||||
|
||||
================================================================================
|
||||
|
||||
Run ID: 1508027909
|
||||
|
||||
All tests were successful!
|
||||
|
||||
You can also request verbose output with the C<-v> flag:
|
||||
|
||||
$ yath -Ilib -v t/example.t
|
||||
|
||||
Which produces:
|
||||
|
||||
( LAUNCH ) job 1 example.t
|
||||
( NOTE ) job 1 Seeded srand with seed '20171014' from local date.
|
||||
[ PASS ] job 1 + 1 is true, so this will pass
|
||||
[ PLAN ] job 1 Expected asserions: 1
|
||||
( PASSED ) job 1 example.t
|
||||
|
||||
================================================================================
|
||||
|
||||
Run ID: 1508028002
|
||||
|
||||
All tests were successful!
|
||||
|
||||
=head2 USING PROVE
|
||||
|
||||
The C<prove> command line tool is provided by the L<Test::Harness> module which
|
||||
comes with most versions of perl. L<Test::Harness> is dual-life, which means
|
||||
you can also install the latest version from cpan.
|
||||
|
||||
$ prove -Ilib t/example.t
|
||||
|
||||
This will produce output like this:
|
||||
|
||||
example.t .. ok
|
||||
All tests successful.
|
||||
Files=1, Tests=1, 0 wallclock secs ( 0.01 usr 0.00 sys + 0.05 cusr 0.00 csys = 0.06 CPU)
|
||||
Result: PASS
|
||||
|
||||
You can also request verbose output with the C<-v> flag:
|
||||
|
||||
$ prove -Ilib -v t/example.t
|
||||
|
||||
The verbose output looks like this:
|
||||
|
||||
example.t ..
|
||||
# Seeded srand with seed '20161028' from local date.
|
||||
ok 1 - 1 is true, so this will pass
|
||||
1..1
|
||||
ok
|
||||
All tests successful.
|
||||
Files=1, Tests=1, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.06 cusr 0.00 csys = 0.08 CPU)
|
||||
Result: PASS
|
||||
|
||||
=head1 THE "PLAN"
|
||||
|
||||
All tests need a "plan". The job of a plan is to make sure you ran all the
|
||||
tests you expected. The plan prevents a passing result from a test that exits
|
||||
before all the tests are run.
|
||||
|
||||
There are 2 primary ways to set the plan:
|
||||
|
||||
=over 4
|
||||
|
||||
=item done_testing()
|
||||
|
||||
The most common, and recommended way to set a plan is to add C<done_testing> at
|
||||
the end of your test file. This will automatically calculate the plan for you
|
||||
at the end of the test. If the test were to exit early then C<done_testing>
|
||||
would not run and no plan would be found, forcing a failure.
|
||||
|
||||
=item plan($COUNT)
|
||||
|
||||
The C<plan()> function allows you to specify an exact number of assertions you
|
||||
want to run. If you run too many or too few assertions then the plan will not
|
||||
match and it will be counted as a failure. The primary problem with this way of
|
||||
planning is that you need to add up the number of assertions, and adjust the
|
||||
count whenever you update the test file.
|
||||
|
||||
C<plan()> must be used before all assertions, or after all assertions, it
|
||||
cannot be done in the middle of making assertions.
|
||||
|
||||
=back
|
||||
|
||||
=head1 ADDITIONAL ASSERTION TOOLS
|
||||
|
||||
The L<Test2::V0> bundle provides a lot more than C<ok()>,
|
||||
C<plan()>, and C<done_testing()>. The biggest tools to note are:
|
||||
|
||||
=over 4
|
||||
|
||||
=item is($a, $b, $description)
|
||||
|
||||
C<is()> allows you to compare 2 structures and insure they are identical. You
|
||||
can use it for simple string comparisons, or even deep data structure
|
||||
comparisons.
|
||||
|
||||
is("foo", "foo", "Both strings are identical");
|
||||
|
||||
is(["foo", 1], ["foo", 1], "Both arrays contain the same elements");
|
||||
|
||||
=item like($a, $b, $description)
|
||||
|
||||
C<like()> is similar to C<is()> except that it only checks items listed on the
|
||||
right, it ignores any extra values found on the left.
|
||||
|
||||
like([1, 2, 3, 4], [1, 2, 3], "Passes, the extra element on the left is ignored");
|
||||
|
||||
You can also used regular expressions on the right hand side:
|
||||
|
||||
like("foo bar baz", qr/bar/, "The string matches the regex, this passes");
|
||||
|
||||
You can also nest the regexes:
|
||||
|
||||
like([1, 2, 'foo bar baz', 3], [1, 2, qr/bar/], "This passes");
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
420
database/perl/vendor/lib/Test2/Manual/Testing/Migrating.pm
vendored
Normal file
420
database/perl/vendor/lib/Test2/Manual/Testing/Migrating.pm
vendored
Normal file
@@ -0,0 +1,420 @@
|
||||
package Test2::Manual::Testing::Migrating;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Testing::Migrating - How to migrate existing tests from
|
||||
Test::More to Test2.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This tutorial covers the conversion of an existing test. This tutorial assumes
|
||||
you have a test written using L<Test::More>.
|
||||
|
||||
=head1 LEGACY TEST
|
||||
|
||||
This tutorial will be converting this example test one section at a time:
|
||||
|
||||
C<t/example.t>:
|
||||
|
||||
#####################
|
||||
# Boilerplate
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 14;
|
||||
|
||||
use_ok 'Scalar::Util';
|
||||
require_ok 'Exporter';
|
||||
|
||||
#####################
|
||||
# Simple assertions (no changes)
|
||||
|
||||
ok(1, "pass");
|
||||
|
||||
is("apple", "apple", "Simple string compare");
|
||||
|
||||
like("foo bar baz", qr/bar/, "Regex match");
|
||||
|
||||
#####################
|
||||
# Todo
|
||||
|
||||
{
|
||||
local $TODO = "These are todo";
|
||||
|
||||
ok(0, "oops");
|
||||
}
|
||||
|
||||
#####################
|
||||
# Deep comparisons
|
||||
|
||||
is_deeply([1, 2, 3], [1, 2, 3], "Deep comparison");
|
||||
|
||||
#####################
|
||||
# Comparing references
|
||||
|
||||
my $ref = [1];
|
||||
is($ref, $ref, "Check that we have the same ref both times");
|
||||
|
||||
#####################
|
||||
# Things that are gone
|
||||
|
||||
ok(eq_array([1], [1]), "array comparison");
|
||||
ok(eq_hash({a => 1}, {a => 1}), "hash comparison");
|
||||
ok(eq_set([1, 3, 2], [1, 2, 3]), "set comparison");
|
||||
|
||||
note explain([1, 2, 3]);
|
||||
|
||||
{
|
||||
package THING;
|
||||
sub new { bless({}, shift) }
|
||||
}
|
||||
|
||||
my $thing = new_ok('THING');
|
||||
|
||||
#####################
|
||||
# Tools that changed
|
||||
|
||||
isa_ok($thing, 'THING', '$thing');
|
||||
|
||||
can_ok(__PACKAGE__, qw/ok is/);
|
||||
|
||||
=head1 BOILERPLATE
|
||||
|
||||
BEFORE:
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 14;
|
||||
|
||||
use_ok 'Scalar::Util';
|
||||
require_ok 'Exporter';
|
||||
|
||||
AFTER:
|
||||
|
||||
use Test2::V0;
|
||||
plan(11);
|
||||
|
||||
use Scalar::Util;
|
||||
require Exporter;
|
||||
|
||||
=over 4
|
||||
|
||||
=item Replace Test::More with Test2::V0
|
||||
|
||||
L<Test2::V0> is the recommended bundle. In a full migration you
|
||||
will want to replace L<Test::More> with the L<Test2::V0> bundle.
|
||||
|
||||
B<Note:> You should always double check the latest L<Test2> to see if there is
|
||||
a new recommended bundle. When writing a new test you should always use the
|
||||
newest Test::V# module. Higher numbers are newer version.
|
||||
|
||||
=item Stop using use_ok()
|
||||
|
||||
C<use_ok()> has been removed. a C<use MODULE> statement will throw an exception
|
||||
on failure anyway preventing the test from passing.
|
||||
|
||||
If you I<REALLY> want/need to assert that the file loaded you can use the L<ok>
|
||||
module:
|
||||
|
||||
use ok 'Scalar::Util';
|
||||
|
||||
The main difference here is that there is a space instead of an underscore.
|
||||
|
||||
=item Stop using require_ok()
|
||||
|
||||
C<require_ok> has been removed just like C<use_ok>. There is no L<ok> module
|
||||
equivalent here. Just use C<require>.
|
||||
|
||||
=item Remove strict/warnings (optional)
|
||||
|
||||
The L<Test2::V0> bundle turns strict and warnings on for you.
|
||||
|
||||
=item Change where the plan is set
|
||||
|
||||
Test2 does not allow you to set the plan at import. In the old code you would
|
||||
pass C<< tests => 11 >> as an import argument. In L<Test2> you either need to
|
||||
use the C<plan()> function to set the plan, or use C<done_testing()> at the end
|
||||
of the test.
|
||||
|
||||
If your test already uses C<done_testing()> you can keep that and no plan
|
||||
changes are necessary.
|
||||
|
||||
B<Note:> We are also changing the plan from 14 to 11, that is because we
|
||||
dropped C<use_ok>, C<require_ok>, and we will be dropping one more later on.
|
||||
This is why C<done_testing()> is recommended over a set plan.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SIMPLE ASSERTIONS
|
||||
|
||||
The vast majority of assertions will not need any changes:
|
||||
|
||||
#####################
|
||||
# Simple assertions (no changes)
|
||||
|
||||
ok(1, "pass");
|
||||
|
||||
is("apple", "apple", "Simple string compare");
|
||||
|
||||
like("foo bar baz", qr/bar/, "Regex match");
|
||||
|
||||
=head1 TODO
|
||||
|
||||
{
|
||||
local $TODO = "These are todo";
|
||||
|
||||
ok(0, "oops");
|
||||
}
|
||||
|
||||
The C<$TODO> package variable is gone. You now have a C<todo()> function.
|
||||
|
||||
There are 2 ways this can be used:
|
||||
|
||||
=over 4
|
||||
|
||||
=item todo $reason => sub { ... }
|
||||
|
||||
todo "These are todo" => sub {
|
||||
ok(0, "oops");
|
||||
};
|
||||
|
||||
This is the cleanest way to do a todo. This will make all assertions inside the
|
||||
codeblock into TODO assertions.
|
||||
|
||||
=item { my $TODO = todo $reason; ... }
|
||||
|
||||
{
|
||||
my $TODO = todo "These are todo";
|
||||
|
||||
ok(0, "oops");
|
||||
}
|
||||
|
||||
This is a system that emulates the old way. Instead of modifying a global
|
||||
C<$TODO> variable you create a todo object with the C<todo()> function and
|
||||
assign it to a lexical variable. Once the todo object falls out of scope the
|
||||
TODO ends.
|
||||
|
||||
=back
|
||||
|
||||
=head1 DEEP COMPARISONS
|
||||
|
||||
is_deeply([1, 2, 3], [1, 2, 3], "Deep comparison");
|
||||
|
||||
Deep comparisons are easy, simply replace C<is_deeply()> with C<is()>.
|
||||
|
||||
is([1, 2, 3], [1, 2, 3], "Deep comparison");
|
||||
|
||||
=head1 COMPARING REFERENCES
|
||||
|
||||
my $ref = [1];
|
||||
is($ref, $ref, "Check that we have the same ref both times");
|
||||
|
||||
The C<is()> function provided by L<Test::More> forces both arguments into
|
||||
strings, which makes this a comparison of the reference addresses. L<Test2>'s
|
||||
C<is()> function is a deep comparison, so this will still pass, but fails to
|
||||
actually test what we want (that both references are the same exact ref, not
|
||||
just identical structures.)
|
||||
|
||||
We now have the C<ref_is()> function that does what we really want, it ensures
|
||||
both references are the same reference. This function does the job better than
|
||||
the original, which could be thrown off by string overloading.
|
||||
|
||||
my $ref = [1];
|
||||
ref_is($ref, $ref, "Check that we have the same ref both times");
|
||||
|
||||
=head1 TOOLS THAT ARE GONE
|
||||
|
||||
ok(eq_array([1], [1]), "array comparison");
|
||||
ok(eq_hash({a => 1}, {a => 1}), "hash comparison");
|
||||
ok(eq_set([1, 3, 2], [1, 2, 3]), "set comparison");
|
||||
|
||||
note explain([1, 2, 3]);
|
||||
|
||||
{
|
||||
package THING;
|
||||
sub new { bless({}, shift) }
|
||||
}
|
||||
|
||||
my $thing = new_ok('THING');
|
||||
|
||||
C<eq_array>, C<eq_hash> and C<eq_set> have been considered deprecated for a
|
||||
very long time, L<Test2> does not provide them at all. Instead you can just use
|
||||
C<is()>:
|
||||
|
||||
is([1], [1], "array comparison");
|
||||
is({a => 1}, {a => 1}, "hash comparison");
|
||||
|
||||
C<eq_set> is a tad more complicated, see L<Test2::Tools::Compare> for an
|
||||
explanation:
|
||||
|
||||
is([1, 3, 2], bag { item 1; item 2; item 3; end }, "set comparison");
|
||||
|
||||
C<explain()> has a rocky history. There have been arguments about how it should
|
||||
work. L<Test2> decided to simply not include C<explain()> to avoid the
|
||||
arguments. You can instead directly use Data::Dumper:
|
||||
|
||||
use Data::Dumper;
|
||||
note Dumper([1, 2, 3]);
|
||||
|
||||
C<new_ok()> is gone. The implementation was complicated, and did not add much
|
||||
value:
|
||||
|
||||
{
|
||||
package THING;
|
||||
sub new { bless({}, shift) }
|
||||
}
|
||||
|
||||
my $thing = THING->new;
|
||||
ok($thing, "made a new thing");
|
||||
|
||||
The complete section after the conversion is:
|
||||
|
||||
is([1], [1], "array comparison");
|
||||
is({a => 1}, {a => 1}, "hash comparison");
|
||||
is([1, 3, 2], bag { item 1; item 2; item 3; end }, "set comparison");
|
||||
|
||||
use Data::Dumper;
|
||||
note Dumper([1, 2, 3]);
|
||||
|
||||
{
|
||||
package THING;
|
||||
sub new { bless({}, shift) }
|
||||
}
|
||||
|
||||
my $thing = THING->new;
|
||||
ok($thing, "made a new thing");
|
||||
|
||||
=head1 TOOLS THAT HAVE CHANGED
|
||||
|
||||
isa_ok($thing, 'THING', '$thing');
|
||||
|
||||
can_ok(__PACKAGE__, qw/ok is/);
|
||||
|
||||
In L<Test::More> these functions are very confusing, and most people use them
|
||||
wrong!
|
||||
|
||||
C<isa_ok()> from L<Test::More> takes a thing, a class/reftype to check, and
|
||||
then uses the third argument as an alternative display name for the first
|
||||
argument (NOT a test name!).
|
||||
|
||||
C<can_ok()> from L<Test::More> is not consistent with C<isa_ok> as all
|
||||
arguments after the first are subroutine names.
|
||||
|
||||
L<Test2> fixes this by making both functions consistent and obvious:
|
||||
|
||||
isa_ok($thing, ['THING'], 'got a THING');
|
||||
|
||||
can_ok(__PACKAGE__, [qw/ok is/], "have expected subs");
|
||||
|
||||
You will note that both functions take a thing, an arrayref as the second
|
||||
argument, then a test name as the third argument.
|
||||
|
||||
=head1 FINAL VERSION
|
||||
|
||||
#####################
|
||||
# Boilerplate
|
||||
|
||||
use Test2::V0;
|
||||
plan(11);
|
||||
|
||||
use Scalar::Util;
|
||||
require Exporter;
|
||||
|
||||
#####################
|
||||
# Simple assertions (no changes)
|
||||
|
||||
ok(1, "pass");
|
||||
|
||||
is("apple", "apple", "Simple string compare");
|
||||
|
||||
like("foo bar baz", qr/bar/, "Regex match");
|
||||
|
||||
#####################
|
||||
# Todo
|
||||
|
||||
todo "These are todo" => sub {
|
||||
ok(0, "oops");
|
||||
};
|
||||
|
||||
#####################
|
||||
# Deep comparisons
|
||||
|
||||
is([1, 2, 3], [1, 2, 3], "Deep comparison");
|
||||
|
||||
#####################
|
||||
# Comparing references
|
||||
|
||||
my $ref = [1];
|
||||
ref_is($ref, $ref, "Check that we have the same ref both times");
|
||||
|
||||
#####################
|
||||
# Things that are gone
|
||||
|
||||
is([1], [1], "array comparison");
|
||||
is({a => 1}, {a => 1}, "hash comparison");
|
||||
|
||||
is([1, 3, 2], bag { item 1; item 2; item 3; end }, "set comparison");
|
||||
|
||||
use Data::Dumper;
|
||||
note Dumper([1, 2, 3]);
|
||||
|
||||
{
|
||||
package THING;
|
||||
sub new { bless({}, shift) }
|
||||
}
|
||||
|
||||
my $thing = THING->new;
|
||||
|
||||
#####################
|
||||
# Tools that changed
|
||||
|
||||
isa_ok($thing, ['THING'], 'got a THING');
|
||||
|
||||
can_ok(__PACKAGE__, [qw/ok is/], "have expected subs");
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
104
database/perl/vendor/lib/Test2/Manual/Testing/Planning.pm
vendored
Normal file
104
database/perl/vendor/lib/Test2/Manual/Testing/Planning.pm
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
package Test2::Manual::Testing::Planning;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Testing::Planning - The many ways to set a plan.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This tutorial covers the many ways of setting a plan.
|
||||
|
||||
=head1 TEST COUNT
|
||||
|
||||
The C<plan()> function is provided by L<Test2::Tools::Basic>. This function lets
|
||||
you specify an exact number of tests to run. This can be done at the start of
|
||||
testing, or at the end. This cannot be done partway through testing.
|
||||
|
||||
use Test2::Tools::Basic;
|
||||
plan(10); # 10 tests expected
|
||||
|
||||
...
|
||||
|
||||
=head1 DONE TESTING
|
||||
|
||||
The C<done_testing()> function is provided by L<Test2::Tools::Basic>. This
|
||||
function will automatically set the plan to the number of tests that were run.
|
||||
This must be used at the very end of testing.
|
||||
|
||||
use Test2::Tools::Basic;
|
||||
|
||||
...
|
||||
|
||||
done_testing();
|
||||
|
||||
=head1 SKIP ALL
|
||||
|
||||
The C<skip_all()> function is provided by L<Test2::Tools::Basic>. This function
|
||||
will set the plan to C<0>, and exit the test immediately. You may provide a skip
|
||||
reason that explains why the test should be skipped.
|
||||
|
||||
use Test2::Tools::Basic;
|
||||
skip_all("This test will not run here") if ...;
|
||||
|
||||
...
|
||||
|
||||
=head1 CUSTOM PLAN EVENT
|
||||
|
||||
A plan is simply an L<Test2::Event::Plan> event that gets sent to the current
|
||||
hub. You could always write your own tool to set the plan.
|
||||
|
||||
use Test2::API qw/context/;
|
||||
|
||||
sub set_plan {
|
||||
my $count = @_;
|
||||
|
||||
my $ctx = context();
|
||||
$ctx->send_event('Plan', max => $count);
|
||||
$ctx->release;
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
112
database/perl/vendor/lib/Test2/Manual/Testing/Todo.pm
vendored
Normal file
112
database/perl/vendor/lib/Test2/Manual/Testing/Todo.pm
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
package Test2::Manual::Testing::Todo;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Testing::Todo - Tutorial for marking tests as TODO.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This tutorial covers the process of marking tests as TODO. It also describes
|
||||
how TODO works under the hood.
|
||||
|
||||
=head1 THE TOOL
|
||||
|
||||
use Test2::Tools::Basic qw/todo/;
|
||||
|
||||
=head2 TODO BLOCK
|
||||
|
||||
This form is low-magic. All tests inside the block are marked as todo, tests
|
||||
outside the block are not todo. You do not need to do any variable management.
|
||||
The flaw with this form is that it adds a couple levels to the stack, which can
|
||||
break some high-magic tests.
|
||||
|
||||
Overall this is the preferred form unless you have a special case that requires
|
||||
the variable form.
|
||||
|
||||
todo "Reason for the todo" => sub {
|
||||
ok(0, "fail but todo");
|
||||
...
|
||||
};
|
||||
|
||||
=head2 TODO VARIABLE
|
||||
|
||||
This form maintains the todo scope for the life of the variable. This is useful
|
||||
for tests that are sensitive to scope changes. This closely emulates the
|
||||
L<Test::More> style which localized the C<$TODO> package variable. Once the
|
||||
variable is destroyed (set it to undef, scope end, etc) the TODO state ends.
|
||||
|
||||
my $todo = todo "Reason for the todo";
|
||||
ok(0, "fail but todo");
|
||||
...
|
||||
$todo = undef;
|
||||
|
||||
=head1 MANUAL TODO EVENTS
|
||||
|
||||
use Test2::API qw/context/;
|
||||
|
||||
sub todo_ok {
|
||||
my ($bool, $name, $todo) = @_;
|
||||
|
||||
my $ctx = context();
|
||||
$ctx->send_event('Ok', pass => $bool, effective_pass => 1, todo => $todo);
|
||||
$ctx->release;
|
||||
|
||||
return $bool;
|
||||
}
|
||||
|
||||
The L<Test2::Event::Ok> event has a C<todo> field which should have the todo
|
||||
reason. The event also has the C<pass> and C<effective_pass> fields. The
|
||||
C<pass> field is the actual pass/fail value. The C<effective_pass> is used to
|
||||
determine if the event is an actual failure (should always be set tot true with
|
||||
todo).
|
||||
|
||||
=head1 HOW THE TODO TOOLS WORK UNDER THE HOOD
|
||||
|
||||
The L<Test2::Todo> library gets the current L<Test2::Hub> instance and adds a
|
||||
filter. The filter that is added will set the todo and effective pass fields on
|
||||
any L<Test2::Event::Ok> events that pass through the hub. The filter also
|
||||
converts L<Test2::Event::Diag> events into L<Test2::Event::Note> events.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
120
database/perl/vendor/lib/Test2/Manual/Tooling.pm
vendored
Normal file
120
database/perl/vendor/lib/Test2/Manual/Tooling.pm
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
package Test2::Manual::Tooling;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Tooling - Manual page for tool authors.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This section covers writing new tools, plugins, and other Test2 components.
|
||||
|
||||
=head1 TOOL TUTORIALS
|
||||
|
||||
=head2 FIRST TOOL
|
||||
|
||||
L<Test2::Manual::Tooling::FirstTool> - Introduction to writing tools by cloning
|
||||
L<ok()>.
|
||||
|
||||
=head2 MOVING FROM Test::Builder
|
||||
|
||||
L<Test2::Manual::Tooling::TestBuilder> - This section maps Test::Builder
|
||||
methods to Test2 concepts.
|
||||
|
||||
=head2 NESTING TOOLS
|
||||
|
||||
L<Test2::Manual::Tooling::Nesting> - How to call other tools from your tool.
|
||||
|
||||
=head2 TOOLS WITH SUBTESTS
|
||||
|
||||
L<Test2::Manual::Tooling::Subtest> - How write tools that make use of subtests.
|
||||
|
||||
=head2 TESTING YOUR TEST TOOLS
|
||||
|
||||
L<Test2::Manual::Tooling::Testing> - How to write tests for your test tools.
|
||||
|
||||
=head1 PLUGIN TUTORIALS
|
||||
|
||||
=head2 TAKING ACTION WHEN A NEW TOOL STARTS
|
||||
|
||||
L<Test2::Manual::Tooling::Plugin::ToolStarts> - How to add behaviors that occur
|
||||
when a tool starts work.
|
||||
|
||||
=head2 TAKING ACTION AFTER A TOOL IS DONE
|
||||
|
||||
L<Test2::Manual::Tooling::Plugin::ToolCompletes> - How to add behaviors that
|
||||
occur when a tool completes work.
|
||||
|
||||
=head2 TAKING ACTION AT THE END OF TESTING
|
||||
|
||||
L<Test2::Manual::Tooling::Plugin::TestingDone> - How to add behaviors that
|
||||
occur when testing is complete (IE done_testing, or end of test).
|
||||
|
||||
=head2 TAKING ACTION JUST BEFORE EXIT
|
||||
|
||||
L<Test2::Manual::Tooling::Plugin::TestExit> - How to safely add pre-exit
|
||||
behaviors.
|
||||
|
||||
=head1 WRITING A SIMPLE JSONL FORMATTER
|
||||
|
||||
L<Test2::Manual::Tooling::Formatter> - How to write a custom formatter, in our
|
||||
case a JSONL formatter.
|
||||
|
||||
=head1 WHERE TO FIND HOOKS AND APIS
|
||||
|
||||
=over 4
|
||||
|
||||
=item global API
|
||||
|
||||
L<Test2::API> is the global API. This is primarily used by plugins that provide
|
||||
global behavior.
|
||||
|
||||
=item In hubs
|
||||
|
||||
L<Test2::Hub> is the base class for all hubs. This is where hooks for
|
||||
manipulating events, or running things at the end of testing live.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
145
database/perl/vendor/lib/Test2/Manual/Tooling/FirstTool.pm
vendored
Normal file
145
database/perl/vendor/lib/Test2/Manual/Tooling/FirstTool.pm
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
package Test2::Manual::Tooling::FirstTool;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Tooling::FirstTool - Write your first tool with Test2.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This tutorial will help you write your very first tool by cloning the C<ok()>
|
||||
tool.
|
||||
|
||||
=head1 COMPLETE CODE UP FRONT
|
||||
|
||||
package Test2::Tools::MyOk;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test2::API qw/context/;
|
||||
|
||||
use base 'Exporter';
|
||||
our @EXPORT = qw/ok/;
|
||||
|
||||
sub ok($;$@) {
|
||||
my ($bool, $name, @diag) = @_;
|
||||
|
||||
my $ctx = context();
|
||||
|
||||
return $ctx->pass_and_release($name) if $bool;
|
||||
return $ctx->fail_and_release($name, @diag);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 LINE BY LINE
|
||||
|
||||
=over 4
|
||||
|
||||
=item sub ok($;$@) {
|
||||
|
||||
In this case we are emulating the C<ok()> function exported by
|
||||
L<Test2::Tools::Basic>.
|
||||
|
||||
C<ok()> and similar test tools use prototypes to enforce argument parsing. Your
|
||||
test tools do not necessarily need prototypes, like any perl function you need
|
||||
to make the decision based on how it is used.
|
||||
|
||||
The prototype requires at least 1 argument, which will
|
||||
be forced into a scalar context. The second argument is optional, and is also
|
||||
forced to be scalar, it is the name of the test. Any remaining arguments are
|
||||
treated as diagnostics messages that will only be used if the test failed.
|
||||
|
||||
=item my ($bool, $name, @diag) = @_;
|
||||
|
||||
This line does not need much explanation, we are simply grabbing the args.
|
||||
|
||||
=item my $ctx = context();
|
||||
|
||||
This is a vital line in B<ALL> tools. The context object is the primary API for
|
||||
test tools. You B<MUST> get a context if you want to issue any events, such as
|
||||
making assertions. Further, the context is responsible for making sure failures
|
||||
are attributed to the correct file and line number.
|
||||
|
||||
B<Note:> A test function B<MUST> always release the context when it is done,
|
||||
you cannot simply let it fall out of scope and be garbage collected. Test2 does
|
||||
a pretty good job of yelling at you if you make this mistake.
|
||||
|
||||
B<Note:> You B<MUST NOT> ever store or pass around a I<real> context object. If
|
||||
you wish to hold on to a context for any reason you must use clone to make a
|
||||
copy C<< my $copy = $ctx->clone >>. The copy may be passed around or stored,
|
||||
but the original B<MUST> be released when you are done with it.
|
||||
|
||||
=item return $ctx->pass_and_release($name) if $bool;
|
||||
|
||||
When C<$bool> is true, this line uses the context object to issue a
|
||||
L<Test2::Event::Pass> event. Along with issuing the event this will also
|
||||
release the context object and return true.
|
||||
|
||||
This is short form for:
|
||||
|
||||
if($bool) {
|
||||
$ctx->pass($name);
|
||||
$ctx->release;
|
||||
return 1;
|
||||
}
|
||||
|
||||
=item return $ctx->fail_and_release($name, @diag);
|
||||
|
||||
This line issues a L<Test2::Event::Fail> event, releases the context object,
|
||||
and returns false. The fail event will include any diagnostics messages from
|
||||
the C<@diag> array.
|
||||
|
||||
This is short form for:
|
||||
|
||||
$ctx->fail($name, @diag);
|
||||
$ctx->release;
|
||||
return 0;
|
||||
|
||||
=back
|
||||
|
||||
=head1 CONTEXT OBJECT DOCUMENTATION
|
||||
|
||||
L<Test2::API::Context> is the place to read up on what methods the context
|
||||
provides.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
138
database/perl/vendor/lib/Test2/Manual/Tooling/Formatter.pm
vendored
Normal file
138
database/perl/vendor/lib/Test2/Manual/Tooling/Formatter.pm
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
package Test2::Manual::Tooling::Formatter;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Tooling::Formatter - How to write a custom formatter, in our
|
||||
case a JSONL formatter.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This tutorial explains a minimal formatter that outputs each event as a json
|
||||
string on its own line. A true formatter will probably be significantly more
|
||||
complicated, but this will give you the basics needed to get started.
|
||||
|
||||
=head1 COMPLETE CODE UP FRONT
|
||||
|
||||
package Test2::Formatter::MyFormatter;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use JSON::MaybeXS qw/encode_json/;
|
||||
|
||||
use base qw/Test2::Formatter/;
|
||||
|
||||
sub new { bless {}, shift }
|
||||
|
||||
sub encoding {};
|
||||
|
||||
sub write {
|
||||
my ($self, $e, $num, $f) = @_;
|
||||
$f ||= $e->facet_data;
|
||||
|
||||
print encode_json($f), "\n";
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 LINE BY LINE
|
||||
|
||||
=over 4
|
||||
|
||||
=item use base qw/Test2::Formatter/;
|
||||
|
||||
All formatters should inherit from L<Test2::Formatter>.
|
||||
|
||||
=item sub new { bless {}, shift }
|
||||
|
||||
Formatters need to be instantiable objects, this is a minimal C<new()> method.
|
||||
|
||||
=item sub encoding {};
|
||||
|
||||
For this example we leave this sub empty. In general you should implement this
|
||||
sub to make sure you honor situations where the encoding is set. L<Test2::V0>
|
||||
itself will try to set the encoding to UTF8.
|
||||
|
||||
=item sub write { ... }
|
||||
|
||||
The C<write()> method is the most important, each event is sent here.
|
||||
|
||||
=item my ($self, $e, $num, $f) = @_;
|
||||
|
||||
The C<write()> method receives 3 or 4 arguments, the fourth is optional.
|
||||
|
||||
=over 4
|
||||
|
||||
=item $self
|
||||
|
||||
The formatter itself.
|
||||
|
||||
=item $e
|
||||
|
||||
The event being written
|
||||
|
||||
=item $num
|
||||
|
||||
The most recent assertion number. If the event being processed is an assertion
|
||||
then this will have been bumped by 1 since the last call to write. For non
|
||||
assertions this number is set to the most recent assertion.
|
||||
|
||||
=item $f
|
||||
|
||||
This MAY be a hashref containing all the facet data from the event. More often
|
||||
then not this will be undefined. This is only set if the facet data was needed
|
||||
by the hub, and it usually is not.
|
||||
|
||||
=back
|
||||
|
||||
=item $f ||= $e->facet_data;
|
||||
|
||||
We want to dump the event facet data. This will set C<$f> to the facet data
|
||||
unless we already have the facet data.
|
||||
|
||||
=item print encode_json($f), "\n";
|
||||
|
||||
This line prints the JSON encoded facet data, and a newline.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
140
database/perl/vendor/lib/Test2/Manual/Tooling/Nesting.pm
vendored
Normal file
140
database/perl/vendor/lib/Test2/Manual/Tooling/Nesting.pm
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
package Test2::Manual::Tooling::Nesting;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Tooling::Nesting - Tutorial for using other tools within your
|
||||
own.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Sometimes you find yourself writing the same test pattern over and over, in
|
||||
such cases you may want to encapsulate the logic in a new test function that
|
||||
calls several tools together. This sounds easy enough, but can cause headaches
|
||||
if not done correctly.
|
||||
|
||||
=head1 NAIVE WAY
|
||||
|
||||
Lets say you find yourself writing the same test pattern over and over for multiple objects:
|
||||
|
||||
my $obj1 = $class1->new;
|
||||
is($obj1->foo, 'foo', "got foo");
|
||||
is($obj1->bar, 'bar', "got bar");
|
||||
|
||||
my $obj2 = $class1->new;
|
||||
is($obj2->foo, 'foo', "got foo");
|
||||
is($obj2->bar, 'bar', "got bar");
|
||||
|
||||
... 10x more times for classes 2-12
|
||||
|
||||
The naive way to do this is to write a C<check_class()> function like this:
|
||||
|
||||
sub check_class {
|
||||
my $class = shift;
|
||||
my $obj = $class->new;
|
||||
is($obj->foo, 'foo', "got foo");
|
||||
is($obj->bar, 'bar', "got bar");
|
||||
}
|
||||
|
||||
check_class($class1);
|
||||
check_class($class2);
|
||||
check_class($class3);
|
||||
...
|
||||
|
||||
This will appear to work fine, and you might not notice any problems,
|
||||
I<so long as the tests are passing.>
|
||||
|
||||
=head2 WHATS WRONG WITH IT?
|
||||
|
||||
The problems with the naive approach become obvious if things start to fail.
|
||||
The diagnostics that tell you what file and line the failure occurred on will be
|
||||
wrong. The failure will be reported to the line I<inside> C<check_class>, not
|
||||
to the line where C<check_class()> was called. This is problem because it
|
||||
leaves you with no idea which class is failing.
|
||||
|
||||
=head2 HOW TO FIX IT
|
||||
|
||||
Luckily this is extremely easy to fix. You need to acquire a context object at
|
||||
the start of your function, and release it at the end... yes it is that simple.
|
||||
|
||||
use Test2::API qw/context/;
|
||||
|
||||
sub check_class {
|
||||
my $class = shift;
|
||||
|
||||
my $ctx = context();
|
||||
|
||||
my $obj = $class->new;
|
||||
is($obj->foo, 'foo', "got foo");
|
||||
is($obj->bar, 'bar', "got bar");
|
||||
|
||||
$ctx->release;
|
||||
}
|
||||
|
||||
See, that was easy. With these 2 additional lines we know have proper file+line
|
||||
reporting. The nested tools will find the context we acquired here, and know to
|
||||
use it's file and line numbers.
|
||||
|
||||
=head3 THE OLD WAY (DO NOT DO THIS ANYMORE)
|
||||
|
||||
With L<Test::Builder> there was a global variables called
|
||||
C<$Test::Builder::Level> which helped solve this problem:
|
||||
|
||||
sub check_class {
|
||||
my $class = shift;
|
||||
|
||||
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
||||
|
||||
my $obj = $class->new;
|
||||
is($obj->foo, 'foo', "got foo");
|
||||
is($obj->bar, 'bar', "got bar");
|
||||
}
|
||||
|
||||
This variable worked well enough (and will still work) but was not very
|
||||
discoverable. Another problem with this variable is that it becomes cumbersome
|
||||
if you have a more deeply nested code structure called the nested tools, you
|
||||
might need to count stack frames, and hope they never change due to a third
|
||||
party module. The context solution has no such caveats.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
108
database/perl/vendor/lib/Test2/Manual/Tooling/Plugin/TestExit.pm
vendored
Normal file
108
database/perl/vendor/lib/Test2/Manual/Tooling/Plugin/TestExit.pm
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
package Test2::Manual::Tooling::Plugin::TestExit;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Tooling::Plugin::TestExit - How to safely add pre-exit
|
||||
behaviors.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This describes the correct/safe way to add pre-exit behaviors to tests via a
|
||||
custom plugin.
|
||||
|
||||
The naive way to attempt this would be to add an C<END { ... }> block. That can
|
||||
work, and may not cause problems.... On the other hand there are a lot of ways
|
||||
that can bite you. Describing all the potential problems of an END block, and
|
||||
how it might conflict with Test2 (Which has its own END block) is beyond the
|
||||
scope of this document.
|
||||
|
||||
=head1 COMPLETE CODE UP FRONT
|
||||
|
||||
package Test2::Plugin::MyPlugin;
|
||||
|
||||
use Test2::API qw{test2_add_callback_exit};
|
||||
|
||||
sub import {
|
||||
my $class = shift;
|
||||
|
||||
test2_add_callback_exit(sub {
|
||||
my ($ctx, $orig_code, $new_exit_code_ref) = @_;
|
||||
|
||||
return if $orig_code == 42;
|
||||
|
||||
$$new_exit_code_ref = 42;
|
||||
});
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 LINE BY LINE
|
||||
|
||||
=over 4
|
||||
|
||||
=item use Test2::API qw{test2_add_callback_exit};
|
||||
|
||||
This imports the C<(test2_add_callback_exit)> callback.
|
||||
|
||||
=item test2_add_callback_exit(sub { ... });
|
||||
|
||||
This adds our callback to be called before exiting.
|
||||
|
||||
=item my ($ctx, $orig_code, $new_exit_code_ref) = @_
|
||||
|
||||
The callback gets 3 arguments. First is a context object you may use. The
|
||||
second is the original exit code of the C<END> block Test2 is using. The third
|
||||
argument is a scalar reference which you may use to get the current exit code,
|
||||
or set a new one.
|
||||
|
||||
=item return if $orig_code == 42
|
||||
|
||||
This is a short-cut to do nothing if the original exit code was already 42.
|
||||
|
||||
=item $$new_exit_code_ref = 42
|
||||
|
||||
This changes the exit code to 42.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
121
database/perl/vendor/lib/Test2/Manual/Tooling/Plugin/TestingDone.pm
vendored
Normal file
121
database/perl/vendor/lib/Test2/Manual/Tooling/Plugin/TestingDone.pm
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
package Test2::Manual::Tooling::Plugin::TestingDone;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Tooling::Plugin::TestingDone - Run code when the test file is
|
||||
finished, or when done_testing is called.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a way to add behavior to the end of a test file. This code is run
|
||||
either when done_testing() is called, or when the test file has no more
|
||||
run-time code to run.
|
||||
|
||||
When triggered by done_testing() this will be run BEFORE the plan is calculated
|
||||
and sent. This means it IS safe to make test assertions in this callback.
|
||||
|
||||
=head1 COMPLETE CODE UP FRONT
|
||||
|
||||
package Test2::Plugin::MyPlugin;
|
||||
|
||||
use Test2::API qw{test2_add_callback_testing_done};
|
||||
|
||||
sub import {
|
||||
my $class = shift;
|
||||
|
||||
test2_add_callback_testing_done(sub {
|
||||
ok(!$some_global, '$some_global was not set');
|
||||
print "The test file is done, or done_testing was just called\n"
|
||||
});
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 LINE BY LINE
|
||||
|
||||
=over 4
|
||||
|
||||
=item use Test2::API qw{test2_add_callback_testing_done};
|
||||
|
||||
This imports the C<test2_add_callback_testing_done()> callback.
|
||||
|
||||
=item test2_add_callback_testing_done(sub { ... });
|
||||
|
||||
This adds our callback to be called when testing is done.
|
||||
|
||||
=item ok(!$some_global, '$some_global was not set')
|
||||
|
||||
It is safe to make assertions in this type of callback. This code simply
|
||||
asserts that some global was never set over the course of the test.
|
||||
|
||||
=item print "The test file is done, or done_testing was just called\n"
|
||||
|
||||
This prints a message when the callback is run.
|
||||
|
||||
=back
|
||||
|
||||
=head1 UNDER THE HOOD
|
||||
|
||||
Before test2_add_callback_testing_done() this kind of thing was still possible,
|
||||
but it was hard to get right, here is the code to do it:
|
||||
|
||||
test2_add_callback_post_load(sub {
|
||||
my $stack = test2_stack();
|
||||
|
||||
# Insure we have at least one hub, but we do not necessarily want the
|
||||
# one this returns.
|
||||
$stack->top;
|
||||
|
||||
# We want the root hub, not the top one.
|
||||
my ($root) = Test2::API::test2_stack->all;
|
||||
|
||||
# Make sure the hub does not believe nothing has happened.
|
||||
$root->set_active(1);
|
||||
|
||||
# Now we can add our follow-up code
|
||||
$root->follow_up(sub {
|
||||
# Your callback code here
|
||||
});
|
||||
});
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
94
database/perl/vendor/lib/Test2/Manual/Tooling/Plugin/ToolCompletes.pm
vendored
Normal file
94
database/perl/vendor/lib/Test2/Manual/Tooling/Plugin/ToolCompletes.pm
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
package Test2::Manual::Tooling::Plugin::ToolCompletes;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Tooling::Plugin::ToolCompletes - How to add behaviors that occur
|
||||
when a tool completes work.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This tutorial helps you understand how to add behaviors that occur when a tool
|
||||
is done with its work. All tools need to acquire and then release a context,
|
||||
for this tutorial we make use of the release hooks that are called every time a
|
||||
tool releases the context object.
|
||||
|
||||
=head1 COMPLETE CODE UP FRONT
|
||||
|
||||
package Test2::Plugin::MyPlugin;
|
||||
|
||||
use Test2::API qw{test2_add_callback_context_release};
|
||||
|
||||
sub import {
|
||||
my $class = shift;
|
||||
|
||||
test2_add_callback_context_release(sub {
|
||||
my $ctx_ref = shift;
|
||||
|
||||
print "Context was released\n";
|
||||
});
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 LINE BY LINE
|
||||
|
||||
=over 4
|
||||
|
||||
=item use Test2::API qw{test2_add_callback_context_release};
|
||||
|
||||
This imports the C<test2_add_callback_context_release()> callback.
|
||||
|
||||
=item test2_add_callback_context_release(sub { ... })
|
||||
|
||||
=item my $ctx_ref = shift
|
||||
|
||||
The coderefs for test2_add_callback_context_release() will receive exactly 1
|
||||
argument, the context being released.
|
||||
|
||||
=item print "Context was released\n"
|
||||
|
||||
Print a notification whenever the context is released.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
126
database/perl/vendor/lib/Test2/Manual/Tooling/Plugin/ToolStarts.pm
vendored
Normal file
126
database/perl/vendor/lib/Test2/Manual/Tooling/Plugin/ToolStarts.pm
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
package Test2::Manual::Tooling::Plugin::ToolStarts;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Tooling::Plugin::ToolStarts - How to add behaviors that occur
|
||||
when a tool starts work.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This tutorial will help you write plugins that have behavior when a tool
|
||||
starts. All tools should start by acquiring a context object. This tutorial
|
||||
shows you the hooks you can use to take advantage of the context acquisition.
|
||||
|
||||
=head1 COMPLETE CODE UP FRONT
|
||||
|
||||
package Test2::Plugin::MyPlugin;
|
||||
|
||||
use Test2::API qw{
|
||||
test2_add_callback_context_init
|
||||
test2_add_callback_context_acquire
|
||||
};
|
||||
|
||||
sub import {
|
||||
my $class = shift;
|
||||
|
||||
# Let us know every time a tool requests a context, and give us a
|
||||
# chance to modify the parameters before we find it.
|
||||
test2_add_callback_context_acquire(sub {
|
||||
my $params_ref = shift;
|
||||
|
||||
print "A tool has requested the context\n";
|
||||
});
|
||||
|
||||
# Callback every time a new context is created, not called if an
|
||||
# existing context is found.
|
||||
test2_add_callback_context_init(sub {
|
||||
my $ctx_ref = shift;
|
||||
|
||||
print "A new context was created\n";
|
||||
});
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 LINE BY LINE
|
||||
|
||||
=over 4
|
||||
|
||||
=item use Test2::API qw{test2_add_callback_context_init test2_add_callback_context_acquire};
|
||||
|
||||
This imports the C<test2_add_callback_context_init()> and
|
||||
C<test2_add_callback_context_acquire()> callbacks.
|
||||
|
||||
=item test2_add_callback_context_acquire(sub { ... })
|
||||
|
||||
This is where we add our callback for context acquisition. Every time
|
||||
C<Test2::API::context()> is called the callback will be run.
|
||||
|
||||
=item my $params_ref = shift
|
||||
|
||||
In the test2_add_callback_context_acquire() callbacks we get exactly 1
|
||||
argument, a reference to the parameters that C<context()> will use to find the
|
||||
context.
|
||||
|
||||
=item print "A tool has requested the context\n"
|
||||
|
||||
Print a notification whenever a tool asks for a context.
|
||||
|
||||
=item test2_add_callback_context_init(sub { ... })
|
||||
|
||||
Add our context init callback. These callbacks are triggered whenever a
|
||||
completely new context is created. This is not called if an existing context is
|
||||
found. In short this only fires off for the top level tool, not nested tools.
|
||||
|
||||
=item my $ctx_ref = shift
|
||||
|
||||
The coderefs for test2_add_callback_context_init() will receive exactly 1
|
||||
argument, the newly created context.
|
||||
|
||||
=item print "A new context was created\n"
|
||||
|
||||
Print a notification whenever a new context is created.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
164
database/perl/vendor/lib/Test2/Manual/Tooling/Subtest.pm
vendored
Normal file
164
database/perl/vendor/lib/Test2/Manual/Tooling/Subtest.pm
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
package Test2::Manual::Tooling::Subtest;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Tooling::Subtest - How to implement a tool that makes use of
|
||||
subtests.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Subtests are a nice way of making related events visually, and architecturally
|
||||
distinct.
|
||||
|
||||
=head1 WHICH TYPE OF SUBTEST DO I NEED?
|
||||
|
||||
There are 2 types of subtest. The first type is subtests with user-supplied
|
||||
coderefs, such as the C<subtest()> function itself. The second type is subtest
|
||||
that do not have any user supplied coderefs.
|
||||
|
||||
So which type do you need? The answer to that is simple, if you are going to
|
||||
let the user define the subtest with their own codeblock, you have the first
|
||||
type, otherwise you have the second.
|
||||
|
||||
In either case, you will still need use the same API function:
|
||||
C<Test2::API::run_subtest>.
|
||||
|
||||
=head2 SUBTEST WITH USER SUPPLIED CODEREF
|
||||
|
||||
This example will emulate the C<subtest> function.
|
||||
|
||||
use Test2::API qw/context run_subtest/;
|
||||
|
||||
sub my_subtest {
|
||||
my ($name, $code) = @_;
|
||||
|
||||
# Like any other tool, you need to acquire a context, if you do not then
|
||||
# things will not report the correct file and line number.
|
||||
my $ctx = context();
|
||||
|
||||
my $bool = run_subtest($name, $code);
|
||||
|
||||
$ctx->release;
|
||||
|
||||
return $bool;
|
||||
}
|
||||
|
||||
This looks incredibly simple... and it is. C<run_subtest()> does all the hard
|
||||
work for you. This will issue an L<Test2::Event::Subtest> event with the
|
||||
results of the subtest. The subtest event itself will report to the proper file
|
||||
and line number due to the context you acquired (even though it does not I<look>
|
||||
like you used the context.
|
||||
|
||||
C<run_subtest()> can take additional arguments:
|
||||
|
||||
run_subtest($name, $code, \%params, @args);
|
||||
|
||||
=over 4
|
||||
|
||||
=item @args
|
||||
|
||||
This allows you to pass arguments into the codeblock that gets run.
|
||||
|
||||
=item \%params
|
||||
|
||||
This is a hashref of parameters. Currently there are 3 possible parameters:
|
||||
|
||||
=over 4
|
||||
|
||||
=item buffered => $bool
|
||||
|
||||
This will turn the subtest into the new style buffered subtest. This type of
|
||||
subtest is recommended, but not default.
|
||||
|
||||
=item inherit_trace => $bool
|
||||
|
||||
This is used for tool-side coderefs.
|
||||
|
||||
=item no_fork => $bool
|
||||
|
||||
react to forking/threading inside the subtest itself. In general you are
|
||||
unlikely to need/want this parameter.
|
||||
|
||||
=back
|
||||
|
||||
=back
|
||||
|
||||
=head2 SUBTEST WITH TOOL-SIDE CODEREF
|
||||
|
||||
This is particularly useful if you want to turn a tool that wraps other tools
|
||||
into a subtest. For this we will be using the tool we created in
|
||||
L<Test2::Manual::Tooling::Nesting>.
|
||||
|
||||
use Test2::API qw/context run_subtest/;
|
||||
|
||||
sub check_class {
|
||||
my $class = shift;
|
||||
|
||||
my $ctx = context();
|
||||
|
||||
my $code = sub {
|
||||
my $obj = $class->new;
|
||||
is($obj->foo, 'foo', "got foo");
|
||||
is($obj->bar, 'bar', "got bar");
|
||||
};
|
||||
|
||||
my $bool = run_subtest($class, $code, {buffered => 1, inherit_trace => 1});
|
||||
|
||||
$ctx->release;
|
||||
|
||||
return $bool;
|
||||
}
|
||||
|
||||
The C<run_subtest()> function does all the heavy lifting for us. All we need
|
||||
to do is give the function a name, a coderef to run, and the
|
||||
C<< inherit_trace => 1 >> parameter. The C<< buffered => 1 >> parameter is
|
||||
optional, but recommended.
|
||||
|
||||
The C<inherit_trace> parameter tells the subtest tool that the contexts acquired
|
||||
inside the nested tools should use the same trace as the subtest itself. For
|
||||
user-supplied codeblocks you do not use inherit_trace because you want errors
|
||||
to report to the user-supplied file+line.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
171
database/perl/vendor/lib/Test2/Manual/Tooling/TestBuilder.pm
vendored
Normal file
171
database/perl/vendor/lib/Test2/Manual/Tooling/TestBuilder.pm
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
package Test2::Manual::Tooling::TestBuilder;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Tooling::TestBuilder - This section maps Test::Builder methods
|
||||
to Test2 concepts.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
With Test::Builder tools were encouraged to use methods on the Test::Builder
|
||||
singleton object. Test2 has a different approach, every tool should get a new
|
||||
L<Test2::API::Context> object, and call methods on that. This document maps
|
||||
several concepts from Test::Builder to Test2.
|
||||
|
||||
=head1 CONTEXT
|
||||
|
||||
First thing to do, stop using the Test::Builder singleton, in fact stop using
|
||||
or even loading Test::Builder. Instead of Test::Builder each tool you write
|
||||
should follow this template:
|
||||
|
||||
use Test2::API qw/context/;
|
||||
|
||||
sub my_tool {
|
||||
my $ctx = context();
|
||||
|
||||
... do work ...
|
||||
|
||||
$ctx->ok(1, "a passing assertion");
|
||||
|
||||
$ctx->release;
|
||||
|
||||
return $whatever;
|
||||
}
|
||||
|
||||
The original Test::Builder style was this:
|
||||
|
||||
use Test::Builder;
|
||||
my $tb = Test::Builder->new; # gets the singleton
|
||||
|
||||
sub my_tool {
|
||||
... do work ...
|
||||
|
||||
$tb->ok(1, "a passing assertion");
|
||||
|
||||
return $whatever;
|
||||
}
|
||||
|
||||
=head1 TEST BUILDER METHODS
|
||||
|
||||
=over 4
|
||||
|
||||
=item $tb->BAIL_OUT($reason)
|
||||
|
||||
The context object has a 'bail' method:
|
||||
|
||||
$ctx->bail($reason)
|
||||
|
||||
=item $tb->diag($string)
|
||||
|
||||
=item $tb->note($string)
|
||||
|
||||
The context object has diag and note methods:
|
||||
|
||||
$ctx->diag($string);
|
||||
$ctx->note($string);
|
||||
|
||||
=item $tb->done_testing
|
||||
|
||||
The context object has a done_testing method:
|
||||
|
||||
$ctx->done_testing;
|
||||
|
||||
Unlike the Test::Builder version, no arguments are allowed.
|
||||
|
||||
=item $tb->like
|
||||
|
||||
=item $tb->unlike
|
||||
|
||||
These are not part of context, instead look at L<Test2::Compare> and
|
||||
L<Test2::Tools::Compare>.
|
||||
|
||||
=item $tb->ok($bool, $name)
|
||||
|
||||
# Preferred
|
||||
$ctx->pass($name);
|
||||
$ctx->fail($name, @diag);
|
||||
|
||||
# Discouraged, but supported:
|
||||
$ctx->ok($bool, $name, \@failure_diags)
|
||||
|
||||
=item $tb->subtest
|
||||
|
||||
use the C<Test2::API::run_subtest()> function instead. See L<Test2::API> for documentation.
|
||||
|
||||
=item $tb->todo_start
|
||||
|
||||
=item $tb->todo_end
|
||||
|
||||
See L<Test2::Tools::Todo> instead.
|
||||
|
||||
=item $tb->output, $tb->failure_output, and $tb->todo_output
|
||||
|
||||
These are handled via formatters now. See L<Test2::Formatter> and
|
||||
L<Test2::Formatter::TAP>.
|
||||
|
||||
=back
|
||||
|
||||
=head1 LEVEL
|
||||
|
||||
L<Test::Builder> had the C<$Test::Builder::Level> variable that you could
|
||||
modify in order to set the stack depth. This was useful if you needed to nest
|
||||
tools and wanted to make sure your file and line number were correct. It was
|
||||
also frustrating and prone to errors. Some people never even discovered the
|
||||
level variable and always had incorrect line numbers when their tools would
|
||||
fail.
|
||||
|
||||
L<Test2> uses the context system, which solves the problem a better way. The
|
||||
top-most tool get a context, and holds on to it until it is done. Any tool
|
||||
nested under the first will find and use the original context instead of
|
||||
generating a new one. This means the level problem is solved for free, no
|
||||
variables to mess with.
|
||||
|
||||
L<Test2> is also smart enough to honor c<$Test::Builder::Level> if it is set.
|
||||
|
||||
=head1 TODO
|
||||
|
||||
L<Test::Builder> used the C<$TODO> package variable to set the TODO state. This
|
||||
was confusing, and easy to get wrong. See L<Test2::Tools::Todo> for the modern
|
||||
way to accomplish a TODO state.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
151
database/perl/vendor/lib/Test2/Manual/Tooling/Testing.pm
vendored
Normal file
151
database/perl/vendor/lib/Test2/Manual/Tooling/Testing.pm
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
package Test2::Manual::Tooling::Testing;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our $VERSION = '0.000139';
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test2::Manual::Tooling::Testing - Tutorial on how to test your testing tools.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Testing your test tools used to be a complex and difficult prospect. The old
|
||||
tools such as L<Test::Tester> and L<Test::Builder::Tester> were limited, and
|
||||
fragile. Test2 on the other hand was designed from the very start to be easily
|
||||
tested! This tutorial shows you how.
|
||||
|
||||
=head1 THE HOLY GRAIL OF TESTING YOUR TOOLS
|
||||
|
||||
The key to making Test2 easily testable (specially when compared to
|
||||
Test::Builder) is the C<intercept> function.
|
||||
|
||||
use Test2::API qw/intercept/;
|
||||
|
||||
my $events = intercept {
|
||||
ok(1, "pass");
|
||||
ok(0, "fail");
|
||||
|
||||
diag("A diag");
|
||||
};
|
||||
|
||||
The intercept function lets you use any test tools you want inside a codeblock.
|
||||
No events or contexts generated within the intercept codeblock will have any
|
||||
effect on the outside testing state. The C<intercept> function completely
|
||||
isolates the tools called within.
|
||||
|
||||
B<Note:> Plugins and things that effect global API state may not be fully
|
||||
isolated. C<intercept> is intended specifically for event isolation.
|
||||
|
||||
The C<intercept> function will return an arrayref containing all the events
|
||||
that were generated within the codeblock. You can now make any assertions you
|
||||
want about the events you expected your tools to generate.
|
||||
|
||||
[
|
||||
bless({...}, 'Test2::Event::Ok'), # pass
|
||||
bless({...}, 'Test2::Event::Ok'), # fail
|
||||
bless({...}, 'Test2::Event::Diag'), # Failure diagnostics (not always a second event)
|
||||
bless({...}, 'Test2::Event::Diag'), # custom 'A diag' message
|
||||
]
|
||||
|
||||
Most test tools eventually produce one or more events. To effectively verify
|
||||
the events you get from intercept you really should read up on how events work
|
||||
L<Test2::Manual::Anatomy::Event>. Once you know about events you can move on to
|
||||
the next section which points you at some helpers.
|
||||
|
||||
=head1 ADDITIONAL HELPERS
|
||||
|
||||
=head2 Test2::Tools::Tester
|
||||
|
||||
This is the most recent set of tools to help you test your events. To really
|
||||
understand these you should familiarize yourself with
|
||||
L<Test2::Manual::Anatomy::Event>. If you are going to be writing anything more
|
||||
than the most simple of tools you should know how events work.
|
||||
|
||||
The L<Test2::Tools::Tester> documentation is a good place for further reading.
|
||||
|
||||
=head2 Test2::Tools::HarnessTester
|
||||
|
||||
The L<Test2::Tools::HarnessTester> can export the C<summarize_events()> tool.
|
||||
This tool lets you run your event arrayref through L<Test2::Harness> so that you
|
||||
can get a pass/fail summary.
|
||||
|
||||
my $summary = summarize_events($events);
|
||||
|
||||
The summary looks like this:
|
||||
|
||||
{
|
||||
plan => $plan_facet, # the plan event facet
|
||||
pass => $bool, # true if the events result in a pass
|
||||
fail => $bool, # true if the events result in a fail
|
||||
errors => $error_count, # Number of error facets seen
|
||||
failures => $failure_count, # Number of failing assertions seen
|
||||
assertions => $assertion_count, # Total number of assertions seen
|
||||
}
|
||||
|
||||
=head2 Test2::Tools::Compare
|
||||
|
||||
B<DEPRECATED> These tools were written before the switch to faceted events.
|
||||
These will still work, but are no longer the recommended way to test your
|
||||
tools.
|
||||
|
||||
The L<Test2::Tools::Compare> library exports a handful of extras to help test
|
||||
events.
|
||||
|
||||
=over 4
|
||||
|
||||
=item event $TYPE => ...
|
||||
|
||||
Use in an array check against $events to check for a specific type of event
|
||||
with the properties you specify.
|
||||
|
||||
=item fail_events $TYPE => ...
|
||||
|
||||
Use when you expect a failing assertion of $TYPE. This will automatically check
|
||||
that the next event following it is a diagnostics message with the default
|
||||
failure text.
|
||||
|
||||
B<Note:> This is outdated as a single event may now possess both the failing
|
||||
assertion AND the failing text, such events will fail this test.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Test2::Manual> - Primary index of the manual.
|
||||
|
||||
=head1 SOURCE
|
||||
|
||||
The source code repository for Test2-Manual can be found at
|
||||
F<https://github.com/Test-More/Test2-Suite/>.
|
||||
|
||||
=head1 MAINTAINERS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item Chad Granum E<lt>exodist@cpan.orgE<gt>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2018 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.
|
||||
|
||||
See F<http://dev.perl.org/licenses/>
|
||||
|
||||
=cut
|
||||
Reference in New Issue
Block a user