```{index} single: Test2::V1 ``` # Test2::V1 V1 edition of the Test2 recommended bundle. ## DESCRIPTION This is the first sequel to [Test2::V0](V0.md). This module is recommended over [Test2::V0](V0.md) for new tests. ### Key differences from [Test2::V0](V0.md) - Only 1 export by default: T2() - No pragmas by default - srand and utf8 are not enabled by default - Easy to still import everything - East to still enable pragmas ## NAMING, USING, DEPENDING This bundle should not change in a _severely_ incompatible way. Some minor breaking changes, specially bugfixes, may be allowed. If breaking changes are needed then a new `Test2::V#` module should be released instead. Adding new optional exports, and new methods on the T2() handle are not considered breaking changes, and are allowed without bumping the V# number. Adding new plugin shortcuts is also allowed, but they cannot be added to the `-P` or `-plugins` shortcuts without a bump in V# number. As new `V#` modules are released old ones _may_ be moved to different cpan distributions. You should always use a specific bundle version and list that version in your distributions testing requirements. You should never simply list [Test2::Suite](Suite.md) as your modules dep, instead list the specific bundle, or tools and plugins you use directly in your metadata. See the "JUSTIFICATION" section for an explanation of why [Test2::V1](V1.md) was created. ## SYNOPSIS ### RECOMMENDED ```perl use Test2::V1 -utf8; T2->ok(1, "pass"); T2->is({1 => 1}, {1 => 1}, "Structures Match"); ## Note that prototypes do not work in method form: my @foo = (1, 2, 3); T2->is(scalar(@foo), 3, "Needed to force scalar context"); T2->done_testing; ``` ### WORK LIKE V0 DID ```perl use Test2::V1 -ipP; ok(1, "pass"); is({1 => 1}, {1 => 1}, "Structures Match"); my @foo = (1, 2, 3); is(@foo, 3, "Prototype forces @foo into scalar context"); ## You still have access to T2 T2->ok(1, "Another Pass"); done_testing; ``` The `-ipP` argument is short for `-include, -pragmas, -plugins` which together enable all pragmas, plugins, and import all symbols. **Note:** The order in which `i`, `p`, and `P` appear is not important; `-Ppi` and `-piP` and any other order are all perfectly valid. ### IMPORT ARGUMENT GUIDE - `-P` or `-plugins` Shortcut to include the following plugins: [Test2::Plugin::UTF8](Plugin/UTF8.md), [Test2::Plugin::SRand](Plugin/SRand.md), [Test2::Plugin::ExitSummary](Plugin/ExitSummary.md). - `-p` or `-pragmas` Shortcut to enable the following pragmas: `strict`, `warnings`. - `-i` or `-import` Shortcut to import all possible exports. - `-x` Shortcut to import any sub that has '&' in its prototype, things like `dies { ... }`, `warns { ... }`, etc. While these can be used in method form: `T2->dies(sub { ... })` it is a little less convenient than having them imported. '-x' will import all of these, and any added in the future or included via an `-include => ...` import argument. - `-ipP`, `-pPi`, `-pP`, `-Pix`, etc.. The `i`, `p`, `P`, and `x` short options may all be grouped in any order following a single dash. - `@EXPORT_LIST` Any arguments provided that are not prefixed with a `-` will be assumed to be export requests. If there is an exported sub by the given name it will be imported into your namespace. If there is no such sub an exception will be thrown. - `!EXPORT_NAME` You can prefix an export name with `!` to exclude it at import time. This is really only usedul when combined with `-import` or `-i`. - `EXPORT_NAME => { -as => "ALT_NAME" }` - `EXPORT_NAME => { -prefix => "PREFIX_" }` - `EXPORT_NAME => { -postfix => "_POSTFIX" }` You may specify a hashref after an export name to rename it, or add a prefix/postfix to the name. ### RENAMING IMPORTS ```perl use Test2::V1 '-import', '!ok', ok => {-as => 'my_ok'}; ``` Explanation: - '-import' Bring in ALL imports, no need to list them all by hand. - '!ok' Do not import `ok()` (remove it from the list added by '-import') - ok => {-as => 'my\_ok'} Actually, go ahead and import `ok()` but under the name `my_ok()`. If you did not add the `'!ok'` argument then you would have both `ok()` and `my_ok()` ## PRAGMAS AND PLUGINS **NO PRAGMAS ARE ENABLED BY DEFAULT** **ONLY THE EXIT SUMMARY PLUGIN IS STILL ENABLED BY DEFAULT** This is a significant departure from [Test2::V0](V0.md). You can enable all of these with the `-pP` argument, which is short for `-plugins, -pragmas`. `P` is short for plugins, and `p` is short for pragmas. When using the single-letter form they may both be together following a single dash, and can be in any order. They may also be combined with `i` to bring in all imports. `-p` or `-P` ont heir own are also perfectly valid. - strict You can enable this with any of these arguments: `-strict`, `-p`, `-pragmas`. This enables strict for you. - warnings You can enable this with any of these arguments: `-warnings`, `-p`, `-pragmas`. This enables warnings for you. - srand You can enable this in multiple ways: ```perl use Test2::V1 -srand use Test2::V1 -P use Test2::V1 -plugins ``` See [Test2::Plugin::SRand](Plugin/SRand.md). This will set the random seed to today's date. You can also set a random seed: ```perl use Test2::V1 -srand => { seed => 'my seed' }; ``` - utf8 You can enable this in multiple ways: ```perl use Test2::V1 -utf8 use Test2::V1 -P use Test2::V1 -plugins ``` See [Test2::Plugin::UTF8](Plugin/UTF8.md). This will set the file, and all output handles (including formatter handles), to utf8. This will turn on the utf8 pragma for the current scope. - summary This is turned on by default. You can avoid enabling it at import this way: ```perl use Test2::V1 -summary => 0; ``` See [Test2::Plugin::ExitSummary](Plugin/ExitSummary.md). This plugin has no configuration. ## ENVIRONMENT VARIABLES See [Test2::Env](Env.md) for a list of meaningful environment variables. ## API FUNCTIONS See [Test2::API](API.md) for these - $ctx = T2->context() - $events = T2->intercept(sub { ... }); ## THE T2() HANDLE The `T2()` subroutine imported into your namespace returns an instance of [Test2::V1::Handle](V1/Handle.md). This gives you a handle on all the tools included by default. It also creates a completely new namespace for use by your test that can have additional tools added to it. ### ADDING/OVERRIDING TOOLS IN YOUR T2 HANDLE ```perl ## Method 1 use Test2::V1 T2 => { include => [ ['Test2::Tools::MyTool', 'my_tool', 'my_other_tool'], ['Data::Dumper', 'Dumper'], ], }; ## Method 2 use Test2::V1 T2 => { include => { 'Test2::Tools::MyTool' => ['my_tool', 'my_other_tool'], 'Data::Dumper' => 'Dumper', }, }; ## Method 3 (This also works with a hashref instead of an arrayref) use Test2::V1 -include => [ ['Test2::Tools::MyTool', 'my_tool', 'my_other_tool'], ['Data::Dumper', 'Dumper'], ]; ## Method 4 T2->include('Test2::Tools::MyTool', 'my_tool', 'my_other_tool'); T2->include('Data::Dumper', 'Dumper'); ## Using them: T2->my_tool(...); T2->Dumper({hi => 'there'}); ``` Note that you MAY override original tools such as ok(), note(), etc. by importing different copies this way. The first time you do this there should be no warnings or errors. If you pull in multiple tools of the same name an redefine warning is likely. This also effects exports: ```perl use Test2::V1 -import, -include => ['Data::Dumper']; print Dumper("Dumper can be imported from your include!"); ``` ### OTHER HANDLE OPTIONS ```perl use Test2::V1 T2 => { include => $ARRAYREF_OR_HASHREF, namespace => $NAMESPACE, base => $BASE_PACKAGE // 'Test2::V1::Base', stomp => $BOOL, }; ``` - include => $ARRAYREF\_OR\_HASHREF See "ADDING TOOLS TO YOUR T2 HANDLE". - namespace => $NAMESPACE Normally a new namespace will be generated for you. You **CANNOT** rely on the package name being anything specific unless you provide your own. The namespace here will be where any tools you 'include' will be imported into. It will also have its base class set to the base class you specify, or the [Test2::V1::Base](V1/Base.md) module if you do not provide any. If this namespace already has any symbols defined in it an exception will be thrown unless the `stomp` argument is set to true (not recommended). - stomp => $BOOL Used to allow the handle to stomp on an existing namespace (NOT RECOMMENDED). - base => $BASE Set the base class from which functions should be inherited. Normally this is set to [Test2::V1::Base](V1/Base.md). Another interesting use case is to have multiple handles that use eachothers namespaces as base classes: ```perl use Test2::V1; use Test2::V1::Handle( 'T3', base => T2->HANDLE_NAMESPACE, include => {'Alt::Ok' => 'ok'}; ); T3->ok(1, "This uses ok() from Alt::Ok, but all other -> methods are the original"); T3->done_testing(); # Uses the original done_testing ``` ## EXAMPLE USE CASES ### OVERRIDING INCLUDED TOOLS WITH ALTERNATES Lets say you want to use the [Test2::Warnings](https://metacpan.org/pod/Test2::Warnings) version of `warning()`, `warnings()` instead of the [Test2::Tools::Warnings](Tools/Warnings.md) versions, and also wanted to import everything else [Test2::Warnings](https://metacpan.org/pod/Test2::Warnings) provides. ```perl use Test2::V1 -import, -include => ['Test2::Warnings']; ``` The `-include => ['Test2::Warnings']` option means we want to import the default set of imports from [Test2::Warnings](https://metacpan.org/pod/Test2::Warnings) into our `T2()` handle's private namespace. This will override any methods that were also previously defined by default. The `-import` option means we want to import all subs into the current namespace. This includes anything we got from [Test2::Warnings](https://metacpan.org/pod/Test2::Warnings), and we will get the [Test2::Warnings](https://metacpan.org/pod/Test2::Warnings) version of those subs. ```perl like( warning { warn 'xxx' }, # This is the Test2::Warnings version of 'warning' qr/xxx/, "Got expected warning" ); ``` ## TOOLS ### TARGET _Added to Test::V1 in 1.302217._ See [Test2::Tools::Target](Tools/Target.md). You can specify a target class with the `-target` import argument. If you do not provide a target then `$CLASS` and `CLASS()` will not be imported. ```perl use Test2::V1 -target => 'My::Class'; print $CLASS; # My::Class print CLASS(); # My::Class ``` Or you can specify names: ```perl use Test2::V1 -target => { pkg => 'Some::Package' }; pkg()->xxx; # Call 'xxx' on Some::Package $pkg->xxx; # Same ``` - $CLASS Package variable that contains the target class name. - $class = CLASS() Constant function that returns the target class name. ### DEFER See [Test2::Tools::Defer](Tools/Defer.md). - def $func => @args; _Added to Test::V1 in 1.302217._ - do\_def() _Added to Test::V1 in 1.302217._ ### BASIC See [Test2::Tools::Basic](Tools/Basic.md). - ok($bool, $name) - ok($bool, $name, @diag) _Added to Test::V1 in 1.302217._ - pass($name) - pass($name, @diag) _Added to Test::V1 in 1.302217._ - fail($name) - fail($name, @diag) _Added to Test::V1 in 1.302217._ - diag($message) _Added to Test::V1 in 1.302217._ - note($message) _Added to Test::V1 in 1.302217._ - $todo = todo($reason) - todo $reason => sub { ... } _Added to Test::V1 in 1.302217._ - skip($reason, $count) _Added to Test::V1 in 1.302217._ - plan($count) _Added to Test::V1 in 1.302217._ - skip\_all($reason) _Added to Test::V1 in 1.302217._ - done\_testing() _Added to Test::V1 in 1.302217._ - bail\_out($reason) _Added to Test::V1 in 1.302217._ ### COMPARE See [Test2::Tools::Compare](Tools/Compare.md). - is($got, $want, $name) _Added to Test::V1 in 1.302217._ - isnt($got, $do\_not\_want, $name) _Added to Test::V1 in 1.302217._ - like($got, qr/match/, $name) _Added to Test::V1 in 1.302217._ - unlike($got, qr/mismatch/, $name) _Added to Test::V1 in 1.302217._ - $check = match(qr/pattern/) _Added to Test::V1 in 1.302217._ - $check = mismatch(qr/pattern/) _Added to Test::V1 in 1.302217._ - $check = validator(sub { return $bool }) _Added to Test::V1 in 1.302217._ - $check = hash { ... } _Added to Test::V1 in 1.302217._ - $check = array { ... } _Added to Test::V1 in 1.302217._ - $check = bag { ... } _Added to Test::V1 in 1.302217._ - $check = object { ... } _Added to Test::V1 in 1.302217._ - $check = meta { ... } _Added to Test::V1 in 1.302217._ - $check = number($num) _Added to Test::V1 in 1.302217._ - $check = string($str) _Added to Test::V1 in 1.302217._ - $check = bool($bool) _Added to Test::V1 in 1.302217._ - $check = check\_isa($class\_name) _Added to Test::V1 in 1.302217._ - $check = in\_set(@things) _Added to Test::V1 in 1.302217._ - $check = not\_in\_set(@things) _Added to Test::V1 in 1.302217._ - $check = check\_set(@things) _Added to Test::V1 in 1.302217._ - $check = item($thing) _Added to Test::V1 in 1.302217._ - $check = item($idx => $thing) _Added to Test::V1 in 1.302217._ - $check = field($name => $val) _Added to Test::V1 in 1.302217._ - $check = call($method => $expect) _Added to Test::V1 in 1.302217._ - $check = call\_list($method => $expect) _Added to Test::V1 in 1.302217._ - $check = call\_hash($method => $expect) _Added to Test::V1 in 1.302217._ - $check = prop($name => $expect) _Added to Test::V1 in 1.302217._ - $check = check($thing) _Added to Test::V1 in 1.302217._ - $check = T() _Added to Test::V1 in 1.302217._ - $check = F() _Added to Test::V1 in 1.302217._ - $check = D() _Added to Test::V1 in 1.302217._ - $check = DF() _Added to Test::V1 in 1.302217._ - $check = E() _Added to Test::V1 in 1.302217._ - $check = DNE() _Added to Test::V1 in 1.302217._ - $check = FDNE() _Added to Test::V1 in 1.302217._ - $check = U() _Added to Test::V1 in 1.302217._ - $check = L() _Added to Test::V1 in 1.302217._ - $check = exact\_ref($ref) _Added to Test::V1 in 1.302217._ - end() _Added to Test::V1 in 1.302217._ - etc() _Added to Test::V1 in 1.302217._ - filter\_items { grep { ... } @\_ } _Added to Test::V1 in 1.302217._ - $check = event $type => ... _Added to Test::V1 in 1.302217._ - @checks = fail\_events $type => ... _Added to Test::V1 in 1.302217._ ### CLASSIC COMPARE See [Test2::Tools::ClassicCompare](Tools/ClassicCompare.md). - cmp\_ok($got, $op, $want, $name) _Added to Test::V1 in 1.302217._ ### SUBTEST See [Test2::Tools::Subtest](Tools/Subtest.md). - subtest $name => sub { ... }; _Added to Test::V1 in 1.302217._ (Note: This is called `subtest_buffered()` in the Tools module.) ### CLASS See [Test2::Tools::Class](Tools/Class.md). - can\_ok($thing, @methods) _Added to Test::V1 in 1.302217._ - isa\_ok($thing, @classes) _Added to Test::V1 in 1.302217._ - DOES\_ok($thing, @roles) _Added to Test::V1 in 1.302217._ ### ENCODING See [Test2::Tools::Encoding](Tools/Encoding.md). - set\_encoding($encoding) _Added to Test::V1 in 1.302217._ ### EXPORTS See [Test2::Tools::Exports](Tools/Exports.md). - imported\_ok('function', '$scalar', ...) _Added to Test::V1 in 1.302217._ - not\_imported\_ok('function', '$scalar', ...) _Added to Test::V1 in 1.302217._ ### REF See [Test2::Tools::Ref](Tools/Ref.md). - ref\_ok($ref, $type) _Added to Test::V1 in 1.302217._ - ref\_is($got, $want) _Added to Test::V1 in 1.302217._ - ref\_is\_not($got, $do\_not\_want) _Added to Test::V1 in 1.302217._ See [Test2::Tools::Refcount](Tools/Refcount.md). - is\_refcount($ref, $count, $description) _Added to Test::V1 in 1.302217._ - is\_oneref($ref, $description) _Added to Test::V1 in 1.302217._ - $count = refcount($ref) _Added to Test::V1 in 1.302217._ ### MOCK See [Test2::Tools::Mock](Tools/Mock.md). - $control = mock ... _Added to Test::V1 in 1.302217._ - $bool = mocked($thing) _Added to Test::V1 in 1.302217._ ### EXCEPTION See [Test2::Tools::Exception](Tools/Exception.md). - $exception = dies { ... } _Added to Test::V1 in 1.302217._ - $bool = lives { ... } _Added to Test::V1 in 1.302217._ - $bool = try\_ok { ... } _Added to Test::V1 in 1.302217._ ### WARNINGS See [Test2::Tools::Warnings](Tools/Warnings.md). - $count = warns { ... } _Added to Test::V1 in 1.302217._ - $warning = warning { ... } _Added to Test::V1 in 1.302217._ - $warnings\_ref = warnings { ... } _Added to Test::V1 in 1.302217._ - $bool = no\_warnings { ... } _Added to Test::V1 in 1.302217._ ## JUSTIFICATION [Test2::V0](V0.md) is a rich set of tools. But it made several assumptions about how it would be used. The assumptions are fairly good for new users writing simple scripts, but they can get in the way in many cases. ### PROBLEMS WITH V0 - Assumptions of strict/warnings Many people would put custom strict/warnings settings at the top of their tests, only to have them wiped out when they use [Test2::V0](V0.md). - Assumptions of UTF8 Occasionally you do not want this assumption. The way it impacts all your regular and test handles, as well as how your source is read, can be a problem if you are not working with UTF8, or have other plans entirly. - Huge default set of exports, which can grow Sometimes you want to keep your namespace clean. Sometimes you import a tool that does not conflict with anything in [Test2::V0](V0.md), then we go and add a new tool which conflicts with yours! We make a point not to break/remove exports, but there is no such commitment about adding new ones. Now the only default export is `T2()` which gives you a handle where all the tools we expose are provided as methods. You can also use the [T2](https://metacpan.org/pod/T2) module (Not bundled with Test-Simple) for use with an identical number of keystrokes, which allow you to leverage the prototypes on the original tool subroutines. ## SOURCE The source code repository for Test2-Suite can be found at `https://github.com/Test-More/test-more/`. ## MAINTAINERS - Chad Granum ## AUTHORS - Chad Granum ## COPYRIGHT Copyright Chad Granum . This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See `http://dev.perl.org/licenses/` ## Modules - [`Test2::V1::Base`](V1/Base.md) - Base namespace used for [Test2::Handle](Handle.md) objects created via [Test2::V1](V1.md). - [`Test2::V1::Handle`](V1/Handle.md) - V1 subclass of [Test2::Handle](Handle.md). ```{toctree} :hidden: :maxdepth: 1 V1/Base V1/Handle ```