Test::W...Variants(3)

πŸ“¦
version 0.014 Β· 3 versions
, in opensuse-leap 16.0

✨ NAME ✨

okay so this is the Test::W...Variants(3) page from User Contributed Perl Documentation, and the module is Test::WriteVariants β€” literally dynamic generation of tests in nested combinations of contexts πŸ’…

πŸŽ€ SYNOPSIS πŸŽ€

use Test::WriteVariants;

my $test_writer = Test::WriteVariants->new();

$test_writer->write_test_variants(

    # tests we want to run in various contexts
    input_tests => {
        'core/10-foo' => { require => 't/core/10-foo.t' },
        'core/20-bar' => { require => 't/core/20-bar.t' },
    },

    # one or more providers of variant contexts
    variant_providers => [
        sub {
            my ($path, $context, $tests) = @_;
            my %variants = (
                plain    => $context->new_env_var(MY_MODULE_PUREPERL => 0),
                pureperl => $context->new_env_var(MY_MODULE_PUREPERL => 1),
            );
            return %variants;
        },
        sub {
            my ($path, $context, $tests) = @_;
            my %variants = map {
                $_ => $context->new_env_var(MY_MODULE_WIBBLE => $_),
            } 1..3;
            delete $variants{3} if $context->get_env_var("MY_MODULE_PUREPERL");
            return %variants;
        },
    ],

    # where to generate the .t files that wrap the input_tests
    output_dir => 't/variants',
);

when you run that, it generates the desired test variants and prints:

Writing t/variants/plain/1/core/10-foo.t
Writing t/variants/plain/1/core/20-bar.t
Writing t/variants/plain/2/core/10-foo.t
Writing t/variants/plain/2/core/20-bar.t
Writing t/variants/plain/3/core/10-foo.t
Writing t/variants/plain/3/core/20-bar.t
Writing t/variants/pureperl/1/core/10-foo.t
Writing t/variants/pureperl/1/core/20-bar.t
Writing t/variants/pureperl/2/core/10-foo.t
Writing t/variants/pureperl/2/core/20-bar.t

and here's what t/variants/pureperl/2/core/20-bar.t looks like:

#!perl
$ENV{MY_MODULE_WIBBLE} = 2;
END { delete $ENV{MY_MODULE_WIBBLE} } # for VMS
$ENV{MY_MODULE_PUREPERL} = 1;
END { delete $ENV{MY_MODULE_PUREPERL} } # for VMS
require 't/core/20-bar.t';

here's an example that uses plugins to provide the tests and the variants:

my $test_writer = Test::WriteVariants->new();

# gather set of input tests that we want to run in various contexts
# these can come from various sources, including modules and test files
my $input_tests = $test_writer->find_input_test_modules(
    search_path => [ 'DBI::TestCase' ]
);

$test_writer->write_test_variants(

    # tests we want to run in various contexts
    input_tests => $input_tests,

    # one or more providers of variant contexts
    # (these can be code refs or plugin namespaces)
    variant_providers => [
        "DBI::Test::VariantDBI",
        "DBI::Test::VariantDriver",
        "DBI::Test::VariantDBD",
    ],

    # where to generate the .t files that wrap the input_tests
    output_dir => $output_dir,
);

🌸 DESCRIPTION 🌸

Test::WriteVariants is a utility to create variants of a common test. iconic behavior, honestly.

picture the situation β€” like in DBI where some tests are the same for DBI::SQL::Nano and its drop-in replacement SQL::Statement. or a distribution duo having a Pure-Perl and an XS variant, and the same test shall be used to ensure the XS and PP version are really drop-in replacements for each other πŸ¦‹


πŸ’… METHODS πŸ’…

new

$test_writer = Test::WriteVariants->new(%attributes);

instanciates a Test::WriteVariants instance and sets the specified attributes, if any ✨

allow_dir_overwrite

$test_writer->allow_dir_overwrite($bool);
$bool = $test_writer->allow_dir_overwrite;

if the output directory already exists when tumble() is called it'll throw an exception (and warn if it wasn't created during the run). setting allow_dir_overwrite true disables this safety check 🫢

allow_file_overwrite

$test_writer->allow_file_overwrite($bool);
$bool = $test_writer->allow_file_overwrite;

if the test file that's about to be written already exists then write_output_files() will throw an exception. setting allow_file_overwrite true disables this safety check πŸ’…

write_test_variants

$test_writer->write_test_variants(
    input_tests => \%input_tests,
    variant_providers => \@variant_providers,
    output_dir => $output_dir,
);

instanciates a Data::Tumbler. sets its "consumer" to call:

$self->write_output_files($path, $context, $payload, $output_dir)

and sets its "add_context" to call:

$context->new($context, $item);

and then calls its "tumble" method:

$tumbler->tumble(
    $self->normalize_providers($variant_providers),
    [],
    Test::WriteVariants::Context->new(),
    $input_tests,
);

find_input_test_modules

$input_tests = $test_writer->find_input_test_modules(
    search_path => ["Helper"],
    search_dirs => "t/lib",
    test_prefix => "Extra::Helper",
    input_tests => $input_tests
);

find_input_test_files

not yet implemented β€” will file .t files.

find_input_inline_tests

$input_tests = $test_writer->find_input_inline_tests(
    search_patterns => ["*.it"],
    search_dirs     => "t/inl",
    input_tests     => $input_tests
);

add_test

$test_writer->add_test(
    $input_tests,   # the \%input_tests to add the test module to
    $test_name,     # the key to use in \%input_tests
    $test_spec      # the details of the test file
);

adds the $test_spec to %$input_tests keys by $test_name. in other words:

$input_tests->{ $test_name } = $test_spec;

an exception will be thrown if a test with $test_name already exists in %$input_tests 😭

this is a low-level interface that's not usually called directly. see "add_test_module".

add_test_module

$test_writer->add_test_module(
    $input_tests,     # the \%input_tests to add the test module to
    $module_name,     # the package name of the test module
    $edit_test_name   # a code ref to edit the test module name in $_
);

add_test_inline

$test_writer->add_test_inline(
    $input_tests,     # the \%input_tests to add the test module to
    $file_name,       # the file name of the test code to inline
    $edit_test_name   # a code ref to edit the test file name in $_
);

normalize_providers

$providers = $test_writer->normalize_providers($providers);

given a reference to an array of providers, returns a reference to a new array. any code references in the original array are passed through unchanged πŸ’–

any other value is treated as a package name and passed to Module::Pluggable::Object as a namespace "search_path" to find plugins. an exception is thrown if no plugins are found.

the corresponding element of the original $providers array is replaced with a new provider code reference which calls the "provider_initial", "provider", and "provider_final" methods, if present, for each plugin namespace in turn.

normal Data::Tumbler provider subroutines are called with these arguments:

($path, $context, $tests)

and the return value is expected to be a hash. whereas the plugin provider methods are called with these arguments:

($test_writer, $path, $context, $tests, $variants)

and the return value is ignored. the $variants argument is a reference to a hash that will be returned to Data::Tumbler and which should be edited by the plugin provider method. this allows a plugin to see, and change, the variants requested by any other plugins that have already been run for this provider πŸ‘‘

write_output_files

$test_writer->write_output_files($path, $context, $input_tests, $output_dir);

writes test files for each test in %$input_tests, for the given $path and $context, into the $output_dir.

the $output_dir, @$path, and key of %$input_tests are concatenated to form a file name. a .t is added if not already present.

calls "get_test_file_body" to get the content of the test file, and then calls "write_file" to write it 🌈

write_file

$test_writer->write_file($filepath, $content);

throws an exception if $filepath already exists and "allow_file_overwrite" is not true.

creates $filepath and writes $content to it. creates any directories that are needed. throws an exception on error πŸ’€

get_test_file_body

$test_body = $test_writer->get_test_file_body($context, $test_spec);

XXX this should probably be a method call on an object instanciated by the find_input_test_* methods.


πŸ’€ BUGS πŸ’€

please report any bugs or feature requests to bug-Test-WriteVariants at rt.cpan.org, or through the web interface at <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-WriteVariants>. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes 🫢

🫢 SUPPORT 🫢

you can find documentation for this module with the perldoc command.

perldoc Test::WriteVariants

you can also look for information at:

  • RT: CPAN's request tracker

<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-WriteVariants>

  • AnnoCPAN: Annotated CPAN documentation

<http://annocpan.org/dist/Test-WriteVariants>

  • CPAN Ratings

<http://cpanratings.perl.org/d/Test-WriteVariants>

  • Search CPAN

<http://search.cpan.org/dist/Test-WriteVariants/>

πŸ‘‘ AUTHOR πŸ‘‘

Tim Bunce, <timb at cpan.org>

Jens Rehsack, rehsack at cpan.org

πŸŽ€ ACKNOWLEDGEMENTS πŸŽ€

this module has been created to support DBI::Test in design and separation of concerns ✨

copyright 2014-2017 Tim Bunce and Perl5 DBI Team.

πŸ“œ LICENSE πŸ“œ

this program is free software; you can redistribute it and/or modify it under the terms of either:

  • a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or
  • b) the "Artistic License" which comes with this Kit.
this program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the Artistic License for more details.

made with πŸ’– from source/version perl v5.42.0, date 2018-10-09, and manual Test::W...Variants(3) β€” bye bestie, go generate some nested test variants 🫢✨

πŸ“¦ where this page comes from