1Test::WriteVariants(3)User Contributed Perl DocumentationTest::WriteVariants(3)
2
3
4

NAME

6       Test::WriteVariants - Dynamic generation of tests in nested
7       combinations of contexts
8

SYNOPSIS

10           use Test::WriteVariants;
11
12           my $test_writer = Test::WriteVariants->new();
13
14           $test_writer->write_test_variants(
15
16               # tests we want to run in various contexts
17               input_tests => {
18                   'core/10-foo' => { require => 't/core/10-foo.t' },
19                   'core/20-bar' => { require => 't/core/20-bar.t' },
20               },
21
22               # one or more providers of variant contexts
23               variant_providers => [
24                   sub {
25                       my ($path, $context, $tests) = @_;
26                       my %variants = (
27                           plain    => $context->new_env_var(MY_MODULE_PUREPERL => 0),
28                           pureperl => $context->new_env_var(MY_MODULE_PUREPERL => 1),
29                       );
30                       return %variants;
31                   },
32                   sub {
33                       my ($path, $context, $tests) = @_;
34                       my %variants = map {
35                           $_ => $context->new_env_var(MY_MODULE_WIBBLE => $_),
36                       } 1..3;
37                       delete $variants{3} if $context->get_env_var("MY_MODULE_PUREPERL");
38                       return %variants;
39                   },
40               ],
41
42               # where to generate the .t files that wrap the input_tests
43               output_dir => 't/variants',
44           );
45
46       When run that generates the desired test variants:
47
48           Writing t/variants/plain/1/core/10-foo.t
49           Writing t/variants/plain/1/core/20-bar.t
50           Writing t/variants/plain/2/core/10-foo.t
51           Writing t/variants/plain/2/core/20-bar.t
52           Writing t/variants/plain/3/core/10-foo.t
53           Writing t/variants/plain/3/core/20-bar.t
54           Writing t/variants/pureperl/1/core/10-foo.t
55           Writing t/variants/pureperl/1/core/20-bar.t
56           Writing t/variants/pureperl/2/core/10-foo.t
57           Writing t/variants/pureperl/2/core/20-bar.t
58
59       Here's what t/variants/pureperl/2/core/20-bar.t looks like:
60
61           #!perl
62           $ENV{MY_MODULE_WIBBLE} = 2;
63           END { delete $ENV{MY_MODULE_WIBBLE} } # for VMS
64           $ENV{MY_MODULE_PUREPERL} = 1;
65           END { delete $ENV{MY_MODULE_PUREPERL} } # for VMS
66           require 't/core/20-bar.t';
67
68       Here's an example that uses plugins to provide the tests and the
69       variants:
70
71           my $test_writer = Test::WriteVariants->new();
72
73           # gather set of input tests that we want to run in various contexts
74           # these can come from various sources, including modules and test files
75           my $input_tests = $test_writer->find_input_test_modules(
76               search_path => [ 'DBI::TestCase' ]
77           );
78
79           $test_writer->write_test_variants(
80
81               # tests we want to run in various contexts
82               input_tests => $input_tests,
83
84               # one or more providers of variant contexts
85               # (these can be code refs or plugin namespaces)
86               variant_providers => [
87                   "DBI::Test::VariantDBI",
88                   "DBI::Test::VariantDriver",
89                   "DBI::Test::VariantDBD",
90               ],
91
92               # where to generate the .t files that wrap the input_tests
93               output_dir => $output_dir,
94           );
95

DESCRIPTION

97       Test::WriteVariants is a utility to create variants of a common test.
98
99       Given the situation - like in DBI where some tests are the same for
100       DBI::SQL::Nano and it's drop-in replacement SQL::Statement.  Or a
101       distribution duo having a Pure-Perl and an XS variant - and the same
102       test shall be used to ensure XS and PP version are really drop-in
103       replacements for each other.
104

METHODS

106   new
107           $test_writer = Test::WriteVariants->new(%attributes);
108
109       Instanciates a Test::WriteVariants instance and sets the specified
110       attributes, if any.
111
112   allow_dir_overwrite
113           $test_writer->allow_dir_overwrite($bool);
114           $bool = $test_writer->allow_dir_overwrite;
115
116       If the output directory already exists when tumble() is called it'll
117       throw an exception (and warn if it wasn't created during the run).
118       Setting allow_dir_overwrite true disables this safety check.
119
120   allow_file_overwrite
121           $test_writer->allow_file_overwrite($bool);
122           $bool = $test_writer->allow_file_overwrite;
123
124       If the test file that's about to be written already exists then
125       write_output_files() will throw an exception.  Setting
126       allow_file_overwrite true disables this safety check.
127
128   write_test_variants
129           $test_writer->write_test_variants(
130               input_tests => \%input_tests,
131               variant_providers => \@variant_providers,
132               output_dir => $output_dir,
133           );
134
135       Instanciates a Data::Tumbler. Sets its "consumer" to call:
136
137           $self->write_output_files($path, $context, $payload, $output_dir)
138
139       and sets its "add_context" to call:
140
141           $context->new($context, $item);
142
143       and then calls its "tumble" method:
144
145           $tumbler->tumble(
146               $self->normalize_providers($variant_providers),
147               [],
148               Test::WriteVariants::Context->new(),
149               $input_tests,
150           );
151
152   find_input_test_modules
153           $input_tests = $test_writer->find_input_test_modules(
154               search_path => ["Helper"],
155               search_dirs => "t/lib",
156               test_prefix => "Extra::Helper",
157               input_tests => $input_tests
158           );
159
160   find_input_test_files
161       Not yet implemented - will file .t files.
162
163   find_input_inline_tests
164           $input_tests = $test_writer->find_input_inline_tests(
165               search_patterns => ["*.it"],
166               search_dirs     => "t/inl",
167               input_tests     => $input_tests
168           );
169
170   add_test
171           $test_writer->add_test(
172               $input_tests,   # the \%input_tests to add the test module to
173               $test_name,     # the key to use in \%input_tests
174               $test_spec      # the details of the test file
175           );
176
177       Adds the $test_spec to %$input_tests keys by $test_name. In other
178       words:
179
180           $input_tests->{ $test_name } = $test_spec;
181
182       An exception will be thrown if a test with $test_name already exists in
183       %$input_tests.
184
185       This is a low-level interface that's not usually called directly.  See
186       "add_test_module".
187
188   add_test_module
189           $test_writer->add_test_module(
190               $input_tests,     # the \%input_tests to add the test module to
191               $module_name,     # the package name of the test module
192               $edit_test_name   # a code ref to edit the test module name in $_
193           );
194
195   add_test_inline
196           $test_writer->add_test_inline(
197               $input_tests,     # the \%input_tests to add the test module to
198               $file_name,       # the file name of the test code to inline
199               $edit_test_name   # a code ref to edit the test file name in $_
200           );
201
202   normalize_providers
203           $providers = $test_writer->normalize_providers($providers);
204
205       Given a reference to an array of providers, returns a reference to a
206       new array.  Any code references in the original array are passed
207       through unchanged.
208
209       Any other value is treated as a package name and passed to
210       Module::Pluggable::Object as a namespace "search_path" to find plugins.
211       An exception is thrown if no plugins are found.
212
213       The corresponding element of the original $providers array is replaced
214       with a new provider code reference which calls the "provider_initial",
215       "provider", and "provider_final" methods, if present, for each plugin
216       namespace in turn.
217
218       Normal Data::Tumbler provider subroutines are called with these
219       arguments:
220
221           ($path, $context, $tests)
222
223       and the return value is expected to be a hash.  Whereas the plugin
224       provider methods are called with these arguments:
225
226           ($test_writer, $path, $context, $tests, $variants)
227
228       and the return value is ignored. The $variants argument is a reference
229       to a hash that will be returned to Data::Tumbler and which should be
230       edited by the plugin provider method. This allows a plugin to see, and
231       change, the variants requested by any other plugins that have already
232       been run for this provider.
233
234   write_output_files
235           $test_writer->write_output_files($path, $context, $input_tests, $output_dir);
236
237       Writes test files for each test in %$input_tests, for the given $path
238       and $context, into the $output_dir.
239
240       The $output_dir, @$path, and key of %$input_tests are concatenated to
241       form a file name. A ".t" is added if not already present.
242
243       Calls "get_test_file_body" to get the content of the test file, and
244       then calls "write_file" to write it.
245
246   write_file
247           $test_writer->write_file($filepath, $content);
248
249       Throws an exception if $filepath already exists and
250       "allow_file_overwrite" is not true.
251
252       Creates $filepath and writes $content to it.  Creates any directories
253       that are needed.  Throws an exception on error.
254
255   get_test_file_body
256           $test_body = $test_writer->get_test_file_body($context, $test_spec);
257
258       XXX This should probably be a method call on an object instanciated by
259       the find_input_test_* methods.
260

BUGS

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

SUPPORT

269       You can find documentation for this module with the perldoc command.
270
271           perldoc Test::WriteVariants
272
273       You can also look for information at:
274
275       •   RT: CPAN's request tracker
276
277           <http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-WriteVariants>
278
279       •   AnnoCPAN: Annotated CPAN documentation
280
281           <http://annocpan.org/dist/Test-WriteVariants>
282
283       •   CPAN Ratings
284
285           <http://cpanratings.perl.org/d/Test-WriteVariants>
286
287       •   Search CPAN
288
289           <http://search.cpan.org/dist/Test-WriteVariants/>
290

AUTHOR

292       Tim Bunce, "<timb at cpan.org>"
293
294       Jens Rehsack, "rehsack at cpan.org"
295

ACKNOWLEDGEMENTS

297       This module has been created to support DBI::Test in design and
298       separation of concerns.
299
301       Copyright 2014-2017 Tim Bunce and Perl5 DBI Team.
302

LICENSE

304       This program is free software; you can redistribute it and/or modify it
305       under the terms of either:
306
307               a) the GNU General Public License as published by the Free
308               Software Foundation; either version 1, or (at your option) any
309               later version, or
310
311               b) the "Artistic License" which comes with this Kit.
312
313       This program is distributed in the hope that it will be useful, but
314       WITHOUT ANY WARRANTY; without even the implied warranty of
315       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See either the
316       GNU General Public License or the Artistic License for more details.
317
318
319
320perl v5.38.0                      2023-07-21            Test::WriteVariants(3)
Impressum