Imported Upstream version 1.18
gregor herrmann
8 years ago
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | 4 | |
5 | use Module::Build 0.3601; | |
5 | use Module::Build 0.28; | |
6 | 6 | |
7 | 7 | |
8 | 8 | my %module_build_args = ( |
9 | 9 | "build_requires" => { |
10 | "Module::Build" => "0.3601" | |
10 | "Module::Build" => "0.28" | |
11 | 11 | }, |
12 | 12 | "c_source" => "c", |
13 | 13 | "configure_requires" => { |
14 | "Module::Build" => "0.3601" | |
14 | "Module::Build" => "0.28" | |
15 | 15 | }, |
16 | 16 | "dist_abstract" => "Validate method/function parameters", |
17 | 17 | "dist_author" => [ |
19 | 19 | "Ilya Martynov <ilya\@martynov.org>" |
20 | 20 | ], |
21 | 21 | "dist_name" => "Params-Validate", |
22 | "dist_version" => "1.13", | |
22 | "dist_version" => "1.18", | |
23 | 23 | "license" => "artistic_2", |
24 | 24 | "module_name" => "Params::Validate", |
25 | 25 | "recommends" => {}, |
40 | 40 | "script_files" => [], |
41 | 41 | "test_requires" => { |
42 | 42 | "Devel::Peek" => 0, |
43 | "ExtUtils::MakeMaker" => 0, | |
43 | 44 | "File::Spec" => 0, |
44 | 45 | "File::Temp" => 0, |
46 | "IO::Handle" => 0, | |
47 | "IPC::Open3" => 0, | |
45 | 48 | "Test::Fatal" => 0, |
46 | "Test::More" => "0.88", | |
49 | "Test::More" => "0.96", | |
47 | 50 | "Test::Requires" => 0, |
48 | 51 | "Tie::Array" => 0, |
49 | 52 | "Tie::Hash" => 0, |
56 | 59 | |
57 | 60 | my %fallback_build_requires = ( |
58 | 61 | "Devel::Peek" => 0, |
62 | "ExtUtils::MakeMaker" => 0, | |
59 | 63 | "File::Spec" => 0, |
60 | 64 | "File::Temp" => 0, |
61 | "Module::Build" => "0.3601", | |
65 | "IO::Handle" => 0, | |
66 | "IPC::Open3" => 0, | |
67 | "Module::Build" => "0.28", | |
62 | 68 | "Test::Fatal" => 0, |
63 | "Test::More" => "0.88", | |
69 | "Test::More" => "0.96", | |
64 | 70 | "Test::Requires" => 0, |
65 | 71 | "Tie::Array" => 0, |
66 | 72 | "Tie::Hash" => 0, |
0 | 1.18 2015-02-13 | |
1 | ||
2 | - We no longer attempt to save and restore an existing $SIG{__DIE__} hook | |
3 | before calling a validation callback. This uses undocumented black magic | |
4 | poking at the Perl interpreter guts, which seems to cause sporadic | |
5 | segfaults. Reported by David Wheeler with help from Andreas Koenig. RT | |
6 | #102112. | |
7 | ||
8 | ||
9 | 1.17 2015-01-08 | |
10 | ||
11 | - More XS fixes. Simplified how we localize $@ in the XS code and fixed error | |
12 | with Perls compiled with -DDEBUGGING. Reported by Lars Dɪᴇᴄᴋᴏᴡ. RT #101416. | |
13 | ||
14 | ||
15 | 1.16 2015-01-07 | |
16 | ||
17 | - The changes in 1.14 introduced a memory leak any time a callback was called | |
18 | and it did not throw an error that was a reference. This affected the | |
19 | DateTime constructor and probably many other things. Reported by David | |
20 | Kayal. RT #101380. | |
21 | ||
22 | ||
23 | 1.15 2015-01-01 | |
24 | ||
25 | - No changes from 1.14 | |
26 | ||
27 | ||
28 | 1.14 2014-12-20 (TRIAL RELEASE) | |
29 | ||
30 | - Callbacks can now die to provide a custom error message or exception | |
31 | object. Requested by multiple people. Addresses RT #95701 and will allow | |
32 | MooseX::Params::Validate to use messages provided by the type object. | |
33 | ||
34 | ||
0 | 35 | 1.13 2014-06-28 |
1 | 36 | |
2 | 37 | - Fix my brain damage so that this code compiles with Perl 5.14. |
0 | ||
1 | 0 | This is the Perl distribution Params-Validate. |
2 | 1 | |
3 | 2 | Installing Params-Validate is straightforward. |
0 | This software is Copyright (c) 2014 by Dave Rolsky and Ilya Martynov. | |
0 | This software is Copyright (c) 2001 - 2015 by Dave Rolsky and Ilya Martynov. | |
1 | 1 | |
2 | 2 | This is free software, licensed under: |
3 | 3 |
0 | # This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.019. | |
0 | # This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.031. | |
1 | 1 | Build.PL |
2 | 2 | Changes |
3 | 3 | INSTALL |
5 | 5 | MANIFEST |
6 | 6 | META.json |
7 | 7 | META.yml |
8 | README | |
8 | README.md | |
9 | 9 | TODO |
10 | _build/auto_features | |
11 | _build/build_params | |
12 | _build/cleanup | |
13 | _build/config_data | |
14 | _build/features | |
15 | _build/magicnum | |
16 | _build/notes | |
17 | _build/prereqs | |
18 | _build/runtime_params | |
19 | 10 | benchmarks/basic |
20 | 11 | c/ppport.h |
12 | cpanfile | |
21 | 13 | dist.ini |
22 | 14 | inc/MyModuleBuild.pm |
23 | 15 | lib/Attribute/Params/Validate.pm |
28 | 20 | lib/Params/Validate/XS.xs |
29 | 21 | lib/Params/ValidatePP.pm |
30 | 22 | lib/Params/ValidateXS.pm |
23 | perlcriticrc | |
24 | perltidyrc | |
25 | t/00-compile.t | |
26 | t/00-report-prereqs.dd | |
27 | t/00-report-prereqs.t | |
31 | 28 | t/01-validate.t |
32 | 29 | t/02-noop.t |
33 | 30 | t/03-attribute.t |
62 | 59 | t/33-keep-errsv.t |
63 | 60 | t/34-recursive-validation.t |
64 | 61 | t/35-default-xs-bug.t |
65 | t/35-large-arrays.t | |
62 | t/36-large-arrays.t | |
63 | t/37-exports.t | |
64 | t/38-callback-message.t | |
65 | t/author-eol.t | |
66 | t/author-no-tabs.t | |
67 | t/author-pod-spell.t | |
66 | 68 | t/lib/PVTests.pm |
67 | 69 | t/lib/PVTests/Callbacks.pm |
68 | 70 | t/lib/PVTests/Defaults.pm |
70 | 72 | t/lib/PVTests/Standard.pm |
71 | 73 | t/lib/PVTests/With.pm |
72 | 74 | t/release-cpan-changes.t |
73 | t/release-eol.t | |
74 | t/release-no-tabs.t | |
75 | t/release-memory-leak.t | |
75 | 76 | t/release-pod-coverage.t |
76 | 77 | t/release-pod-linkcheck.t |
77 | 78 | t/release-pod-no404s.t |
78 | t/release-pod-spell.t | |
79 | 79 | t/release-pod-syntax.t |
80 | t/release-portability.t | |
80 | 81 | t/release-pp-01-validate.t |
81 | 82 | t/release-pp-02-noop.t |
82 | 83 | t/release-pp-03-attribute.t |
111 | 112 | t/release-pp-33-keep-errsv.t |
112 | 113 | t/release-pp-34-recursive-validation.t |
113 | 114 | t/release-pp-35-default-xs-bug.t |
114 | t/release-pp-35-large-arrays.t | |
115 | t/release-pp-36-large-arrays.t | |
116 | t/release-pp-37-exports.t | |
117 | t/release-pp-38-callback-message.t | |
115 | 118 | t/release-pp-is-loaded.t |
119 | t/release-synopsis.t | |
120 | t/release-test-version.t | |
116 | 121 | t/release-xs-is-loaded.t |
117 | 122 | t/release-xs-segfault.t |
123 | tidyall.ini | |
124 | weaver.ini |
4 | 4 | "Ilya Martynov <ilya@martynov.org>" |
5 | 5 | ], |
6 | 6 | "dynamic_config" : 0, |
7 | "generated_by" : "Dist::Zilla version 5.019, CPAN::Meta::Converter version 2.120921", | |
7 | "generated_by" : "Dist::Zilla version 5.031, CPAN::Meta::Converter version 2.143240", | |
8 | 8 | "license" : [ |
9 | 9 | "artistic_2" |
10 | 10 | ], |
11 | 11 | "meta-spec" : { |
12 | 12 | "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", |
13 | "version" : "2" | |
13 | "version" : 2 | |
14 | 14 | }, |
15 | 15 | "name" : "Params-Validate", |
16 | 16 | "prereqs" : { |
17 | 17 | "build" : { |
18 | 18 | "requires" : { |
19 | "Module::Build" : "0.3601" | |
19 | "Module::Build" : "0.28" | |
20 | 20 | } |
21 | 21 | }, |
22 | 22 | "configure" : { |
23 | 23 | "requires" : { |
24 | "Module::Build" : "0.3601" | |
24 | "Module::Build" : "0.28" | |
25 | 25 | } |
26 | 26 | }, |
27 | 27 | "develop" : { |
28 | 28 | "requires" : { |
29 | "Test::More" : "0", | |
29 | "Perl::Critic" : "1.123", | |
30 | "Perl::Tidy" : "20140711", | |
31 | "Pod::Coverage::TrustPod" : "0", | |
32 | "Readonly" : "1.03", | |
33 | "Scalar::Util" : "1.20", | |
34 | "Test::CPAN::Changes" : "0.19", | |
35 | "Test::EOL" : "0", | |
36 | "Test::LeakTrace" : "0.15", | |
37 | "Test::More" : "0.96", | |
30 | 38 | "Test::NoTabs" : "0", |
31 | "Test::Pod" : "1.41" | |
39 | "Test::Pod" : "1.41", | |
40 | "Test::Pod::Coverage" : "1.08", | |
41 | "Test::Spelling" : "0.12", | |
42 | "Test::Synopsis" : "0", | |
43 | "Test::Taint" : "0.02", | |
44 | "Test::Version" : "1" | |
32 | 45 | } |
33 | 46 | }, |
34 | 47 | "runtime" : { |
47 | 60 | } |
48 | 61 | }, |
49 | 62 | "test" : { |
63 | "recommends" : { | |
64 | "CPAN::Meta" : "2.120900" | |
65 | }, | |
50 | 66 | "requires" : { |
51 | 67 | "Devel::Peek" : "0", |
68 | "ExtUtils::MakeMaker" : "0", | |
52 | 69 | "File::Spec" : "0", |
53 | 70 | "File::Temp" : "0", |
71 | "IO::Handle" : "0", | |
72 | "IPC::Open3" : "0", | |
54 | 73 | "Test::Fatal" : "0", |
55 | "Test::More" : "0.88", | |
74 | "Test::More" : "0.96", | |
56 | 75 | "Test::Requires" : "0", |
57 | 76 | "Tie::Array" : "0", |
58 | 77 | "Tie::Hash" : "0", |
62 | 81 | } |
63 | 82 | } |
64 | 83 | }, |
84 | "provides" : { | |
85 | "Attribute::Params::Validate" : { | |
86 | "file" : "lib/Attribute/Params/Validate.pm", | |
87 | "version" : "1.18" | |
88 | }, | |
89 | "Params::Validate" : { | |
90 | "file" : "lib/Params/Validate.pm", | |
91 | "version" : "1.18" | |
92 | }, | |
93 | "Params::Validate::Constants" : { | |
94 | "file" : "lib/Params/Validate/Constants.pm", | |
95 | "version" : "1.18" | |
96 | }, | |
97 | "Params::Validate::PP" : { | |
98 | "file" : "lib/Params/Validate/PP.pm", | |
99 | "version" : "1.18" | |
100 | }, | |
101 | "Params::Validate::XS" : { | |
102 | "file" : "lib/Params/Validate/XS.pm", | |
103 | "version" : "1.18" | |
104 | } | |
105 | }, | |
65 | 106 | "release_status" : "stable", |
66 | 107 | "resources" : { |
67 | 108 | "bugtracker" : { |
68 | 109 | "mailto" : "bug-params-validate@rt.cpan.org", |
69 | "web" : "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Params-Validate" | |
70 | }, | |
110 | "web" : "http://rt.cpan.org/Public/Dist/Display.html?Name=Params-Validate" | |
111 | }, | |
112 | "homepage" : "http://metacpan.org/release/Params-Validate", | |
71 | 113 | "repository" : { |
72 | 114 | "type" : "git", |
73 | "url" : "git://git.urth.org/Params-Validate.git", | |
74 | "web" : "http://git.urth.org/Params-Validate.git" | |
115 | "url" : "git://github.com/autarch/Params-Validate.git", | |
116 | "web" : "https://github.com/autarch/Params-Validate" | |
75 | 117 | } |
76 | 118 | }, |
77 | "version" : "1.13" | |
119 | "version" : "1.18", | |
120 | "x_Dist_Zilla" : { | |
121 | "perl" : { | |
122 | "version" : "5.020001" | |
123 | }, | |
124 | "plugins" : [ | |
125 | { | |
126 | "class" : "Dist::Zilla::Plugin::Authority", | |
127 | "name" : "@DROLSKY/Authority", | |
128 | "version" : "1.009" | |
129 | }, | |
130 | { | |
131 | "class" : "Dist::Zilla::Plugin::AutoPrereqs", | |
132 | "name" : "@DROLSKY/AutoPrereqs", | |
133 | "version" : "5.031" | |
134 | }, | |
135 | { | |
136 | "class" : "Dist::Zilla::Plugin::CopyFilesFromBuild", | |
137 | "name" : "@DROLSKY/CopyFilesFromBuild", | |
138 | "version" : "0.150250" | |
139 | }, | |
140 | { | |
141 | "class" : "Dist::Zilla::Plugin::Git::GatherDir", | |
142 | "config" : { | |
143 | "Dist::Zilla::Plugin::GatherDir" : { | |
144 | "exclude_filename" : [ | |
145 | "Makefile.PL", | |
146 | "README.md", | |
147 | "Build.PL", | |
148 | "LICENSE", | |
149 | "cpanfile" | |
150 | ], | |
151 | "exclude_match" : [], | |
152 | "follow_symlinks" : "0", | |
153 | "include_dotfiles" : "0", | |
154 | "prefix" : "", | |
155 | "prune_directory" : [], | |
156 | "root" : "." | |
157 | }, | |
158 | "Dist::Zilla::Plugin::Git::GatherDir" : { | |
159 | "include_untracked" : "0" | |
160 | }, | |
161 | "Dist::Zilla::Role::Git::Repo" : { | |
162 | "repo_root" : "." | |
163 | } | |
164 | }, | |
165 | "name" : "@DROLSKY/Git::GatherDir", | |
166 | "version" : "2.029" | |
167 | }, | |
168 | { | |
169 | "class" : "Dist::Zilla::Plugin::GitHub::Meta", | |
170 | "name" : "@DROLSKY/GitHub::Meta", | |
171 | "version" : "0.40" | |
172 | }, | |
173 | { | |
174 | "class" : "Dist::Zilla::Plugin::GitHub::Update", | |
175 | "name" : "@DROLSKY/GitHub::Update", | |
176 | "version" : "0.40" | |
177 | }, | |
178 | { | |
179 | "class" : "Dist::Zilla::Plugin::MetaResources", | |
180 | "name" : "@DROLSKY/MetaResources", | |
181 | "version" : "5.031" | |
182 | }, | |
183 | { | |
184 | "class" : "Dist::Zilla::Plugin::MetaProvides::Package", | |
185 | "config" : { | |
186 | "Dist::Zilla::Plugin::MetaProvides::Package" : { | |
187 | "finder_objects" : [ | |
188 | { | |
189 | "class" : "Dist::Zilla::Plugin::FinderCode", | |
190 | "name" : "@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM", | |
191 | "version" : "5.031" | |
192 | } | |
193 | ] | |
194 | }, | |
195 | "Dist::Zilla::Role::MetaProvider::Provider" : { | |
196 | "inherit_missing" : "1", | |
197 | "inherit_version" : "1", | |
198 | "meta_noindex" : "1" | |
199 | } | |
200 | }, | |
201 | "name" : "@DROLSKY/MetaProvides::Package", | |
202 | "version" : "2.003001" | |
203 | }, | |
204 | { | |
205 | "class" : "Dist::Zilla::Plugin::NextRelease", | |
206 | "name" : "@DROLSKY/NextRelease", | |
207 | "version" : "5.031" | |
208 | }, | |
209 | { | |
210 | "class" : "Dist::Zilla::Plugin::Prereqs", | |
211 | "config" : { | |
212 | "Dist::Zilla::Plugin::Prereqs" : { | |
213 | "phase" : "test", | |
214 | "type" : "requires" | |
215 | } | |
216 | }, | |
217 | "name" : "@DROLSKY/Test::More with subtest()", | |
218 | "version" : "5.031" | |
219 | }, | |
220 | { | |
221 | "class" : "Dist::Zilla::Plugin::Prereqs", | |
222 | "config" : { | |
223 | "Dist::Zilla::Plugin::Prereqs" : { | |
224 | "phase" : "develop", | |
225 | "type" : "requires" | |
226 | } | |
227 | }, | |
228 | "name" : "@DROLSKY/Modules for use with tidyall", | |
229 | "version" : "5.031" | |
230 | }, | |
231 | { | |
232 | "class" : "Dist::Zilla::Plugin::PromptIfStale", | |
233 | "config" : { | |
234 | "Dist::Zilla::Plugin::PromptIfStale" : { | |
235 | "check_all_plugins" : "1", | |
236 | "check_all_prereqs" : "1", | |
237 | "modules" : [], | |
238 | "phase" : "release", | |
239 | "skip" : [ | |
240 | "Dist::Zilla::Plugin::DROLSKY::Contributors", | |
241 | "Dist::Zilla::Plugin::DROLSKY::License", | |
242 | "Dist::Zilla::Plugin::DROLSKY::TidyAll" | |
243 | ] | |
244 | } | |
245 | }, | |
246 | "name" : "@DROLSKY/PromptIfStale", | |
247 | "version" : "0.038" | |
248 | }, | |
249 | { | |
250 | "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod", | |
251 | "name" : "@DROLSKY/README.md in build", | |
252 | "version" : "0.150250" | |
253 | }, | |
254 | { | |
255 | "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod", | |
256 | "name" : "@DROLSKY/README.md in root", | |
257 | "version" : "0.150250" | |
258 | }, | |
259 | { | |
260 | "class" : "Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable", | |
261 | "name" : "@DROLSKY/Test::Pod::Coverage::Configurable", | |
262 | "version" : "0.03" | |
263 | }, | |
264 | { | |
265 | "class" : "Dist::Zilla::Plugin::Test::PodSpelling", | |
266 | "name" : "@DROLSKY/Test::PodSpelling", | |
267 | "version" : "2.006008" | |
268 | }, | |
269 | { | |
270 | "class" : "Dist::Zilla::Plugin::Test::ReportPrereqs", | |
271 | "name" : "@DROLSKY/Test::ReportPrereqs", | |
272 | "version" : "0.020" | |
273 | }, | |
274 | { | |
275 | "class" : "Dist::Zilla::Plugin::Test::Version", | |
276 | "name" : "@DROLSKY/Test::Version", | |
277 | "version" : "0.003001" | |
278 | }, | |
279 | { | |
280 | "class" : "Dist::Zilla::Plugin::ManifestSkip", | |
281 | "name" : "@DROLSKY/ManifestSkip", | |
282 | "version" : "5.031" | |
283 | }, | |
284 | { | |
285 | "class" : "Dist::Zilla::Plugin::MetaYAML", | |
286 | "name" : "@DROLSKY/MetaYAML", | |
287 | "version" : "5.031" | |
288 | }, | |
289 | { | |
290 | "class" : "Dist::Zilla::Plugin::License", | |
291 | "name" : "@DROLSKY/License", | |
292 | "version" : "5.031" | |
293 | }, | |
294 | { | |
295 | "class" : "Dist::Zilla::Plugin::ExtraTests", | |
296 | "name" : "@DROLSKY/ExtraTests", | |
297 | "version" : "5.031" | |
298 | }, | |
299 | { | |
300 | "class" : "Dist::Zilla::Plugin::ExecDir", | |
301 | "name" : "@DROLSKY/ExecDir", | |
302 | "version" : "5.031" | |
303 | }, | |
304 | { | |
305 | "class" : "Dist::Zilla::Plugin::ShareDir", | |
306 | "name" : "@DROLSKY/ShareDir", | |
307 | "version" : "5.031" | |
308 | }, | |
309 | { | |
310 | "class" : "Dist::Zilla::Plugin::Manifest", | |
311 | "name" : "@DROLSKY/Manifest", | |
312 | "version" : "5.031" | |
313 | }, | |
314 | { | |
315 | "class" : "Dist::Zilla::Plugin::CheckVersionIncrement", | |
316 | "name" : "@DROLSKY/CheckVersionIncrement", | |
317 | "version" : "0.121750" | |
318 | }, | |
319 | { | |
320 | "class" : "Dist::Zilla::Plugin::TestRelease", | |
321 | "name" : "@DROLSKY/TestRelease", | |
322 | "version" : "5.031" | |
323 | }, | |
324 | { | |
325 | "class" : "Dist::Zilla::Plugin::ConfirmRelease", | |
326 | "name" : "@DROLSKY/ConfirmRelease", | |
327 | "version" : "5.031" | |
328 | }, | |
329 | { | |
330 | "class" : "Dist::Zilla::Plugin::UploadToCPAN", | |
331 | "name" : "@DROLSKY/UploadToCPAN", | |
332 | "version" : "5.031" | |
333 | }, | |
334 | { | |
335 | "class" : "Dist::Zilla::Plugin::CheckPrereqsIndexed", | |
336 | "name" : "@DROLSKY/CheckPrereqsIndexed", | |
337 | "version" : "0.015" | |
338 | }, | |
339 | { | |
340 | "class" : "Dist::Zilla::Plugin::CPANFile", | |
341 | "name" : "@DROLSKY/CPANFile", | |
342 | "version" : "5.031" | |
343 | }, | |
344 | { | |
345 | "class" : "Dist::Zilla::Plugin::DROLSKY::Contributors", | |
346 | "name" : "@DROLSKY/DROLSKY::Contributors", | |
347 | "version" : "0.32" | |
348 | }, | |
349 | { | |
350 | "class" : "Dist::Zilla::Plugin::DROLSKY::License", | |
351 | "name" : "@DROLSKY/DROLSKY::License", | |
352 | "version" : "0.32" | |
353 | }, | |
354 | { | |
355 | "class" : "Dist::Zilla::Plugin::DROLSKY::TidyAll", | |
356 | "name" : "@DROLSKY/DROLSKY::TidyAll", | |
357 | "version" : "0.32" | |
358 | }, | |
359 | { | |
360 | "class" : "Dist::Zilla::Plugin::Git::CheckFor::CorrectBranch", | |
361 | "config" : { | |
362 | "Dist::Zilla::Role::Git::Repo" : { | |
363 | "repo_root" : "." | |
364 | } | |
365 | }, | |
366 | "name" : "@DROLSKY/Git::CheckFor::CorrectBranch", | |
367 | "version" : "0.011" | |
368 | }, | |
369 | { | |
370 | "class" : "Dist::Zilla::Plugin::Git::CheckFor::MergeConflicts", | |
371 | "config" : { | |
372 | "Dist::Zilla::Role::Git::Repo" : { | |
373 | "repo_root" : "." | |
374 | } | |
375 | }, | |
376 | "name" : "@DROLSKY/Git::CheckFor::MergeConflicts", | |
377 | "version" : "0.011" | |
378 | }, | |
379 | { | |
380 | "class" : "Dist::Zilla::Plugin::Git::Contributors", | |
381 | "config" : { | |
382 | "Dist::Zilla::Plugin::Git::Contributors" : { | |
383 | "include_authors" : "0", | |
384 | "include_releaser" : "1", | |
385 | "order_by" : "name", | |
386 | "paths" : [] | |
387 | } | |
388 | }, | |
389 | "name" : "@DROLSKY/Git::Contributors", | |
390 | "version" : "0.009" | |
391 | }, | |
392 | { | |
393 | "class" : "Dist::Zilla::Plugin::InstallGuide", | |
394 | "name" : "@DROLSKY/InstallGuide", | |
395 | "version" : "1.200006" | |
396 | }, | |
397 | { | |
398 | "class" : "Dist::Zilla::Plugin::Meta::Contributors", | |
399 | "name" : "@DROLSKY/Meta::Contributors", | |
400 | "version" : "0.001" | |
401 | }, | |
402 | { | |
403 | "class" : "Dist::Zilla::Plugin::MetaConfig", | |
404 | "name" : "@DROLSKY/MetaConfig", | |
405 | "version" : "5.031" | |
406 | }, | |
407 | { | |
408 | "class" : "Dist::Zilla::Plugin::MetaJSON", | |
409 | "name" : "@DROLSKY/MetaJSON", | |
410 | "version" : "5.031" | |
411 | }, | |
412 | { | |
413 | "class" : "Dist::Zilla::Plugin::RewriteVersion", | |
414 | "name" : "@DROLSKY/RewriteVersion", | |
415 | "version" : "0.009" | |
416 | }, | |
417 | { | |
418 | "class" : "Dist::Zilla::Plugin::SurgicalPodWeaver", | |
419 | "config" : { | |
420 | "Dist::Zilla::Plugin::PodWeaver" : { | |
421 | "finder" : [ | |
422 | ":InstallModules", | |
423 | ":ExecFiles" | |
424 | ], | |
425 | "plugins" : [ | |
426 | { | |
427 | "class" : "Pod::Weaver::Plugin::EnsurePod5", | |
428 | "name" : "@CorePrep/EnsurePod5", | |
429 | "version" : "4.010" | |
430 | }, | |
431 | { | |
432 | "class" : "Pod::Weaver::Plugin::H1Nester", | |
433 | "name" : "@CorePrep/H1Nester", | |
434 | "version" : "4.010" | |
435 | }, | |
436 | { | |
437 | "class" : "Pod::Weaver::Section::Name", | |
438 | "name" : "Name", | |
439 | "version" : "4.010" | |
440 | }, | |
441 | { | |
442 | "class" : "Pod::Weaver::Section::Version", | |
443 | "name" : "Version", | |
444 | "version" : "4.010" | |
445 | }, | |
446 | { | |
447 | "class" : "Pod::Weaver::Section::Region", | |
448 | "name" : "prelude", | |
449 | "version" : "4.010" | |
450 | }, | |
451 | { | |
452 | "class" : "Pod::Weaver::Section::Generic", | |
453 | "name" : "SYNOPSIS", | |
454 | "version" : "4.010" | |
455 | }, | |
456 | { | |
457 | "class" : "Pod::Weaver::Section::Generic", | |
458 | "name" : "DESCRIPTION", | |
459 | "version" : "4.010" | |
460 | }, | |
461 | { | |
462 | "class" : "Pod::Weaver::Section::Leftovers", | |
463 | "name" : "Leftovers", | |
464 | "version" : "4.010" | |
465 | }, | |
466 | { | |
467 | "class" : "Pod::Weaver::Section::Region", | |
468 | "name" : "postlude", | |
469 | "version" : "4.010" | |
470 | }, | |
471 | { | |
472 | "class" : "Pod::Weaver::Section::Authors", | |
473 | "name" : "Authors", | |
474 | "version" : "4.010" | |
475 | }, | |
476 | { | |
477 | "class" : "Pod::Weaver::Section::Contributors", | |
478 | "name" : "Contributors", | |
479 | "version" : "0.009" | |
480 | }, | |
481 | { | |
482 | "class" : "Pod::Weaver::Section::Legal", | |
483 | "name" : "Legal", | |
484 | "version" : "4.010" | |
485 | } | |
486 | ] | |
487 | } | |
488 | }, | |
489 | "name" : "@DROLSKY/SurgicalPodWeaver", | |
490 | "version" : "0.0023" | |
491 | }, | |
492 | { | |
493 | "class" : "Dist::Zilla::Plugin::PodSyntaxTests", | |
494 | "name" : "@DROLSKY/PodSyntaxTests", | |
495 | "version" : "5.031" | |
496 | }, | |
497 | { | |
498 | "class" : "Dist::Zilla::Plugin::Test::CPAN::Changes", | |
499 | "name" : "@DROLSKY/Test::CPAN::Changes", | |
500 | "version" : "0.009" | |
501 | }, | |
502 | { | |
503 | "class" : "Dist::Zilla::Plugin::Test::Compile", | |
504 | "config" : { | |
505 | "Dist::Zilla::Plugin::Test::Compile" : { | |
506 | "bail_out_on_fail" : "0", | |
507 | "fail_on_warning" : "author", | |
508 | "fake_home" : "0", | |
509 | "filename" : "t/00-compile.t", | |
510 | "module_finder" : [ | |
511 | ":InstallModules" | |
512 | ], | |
513 | "needs_display" : "0", | |
514 | "phase" : "test", | |
515 | "script_finder" : [ | |
516 | ":ExecFiles" | |
517 | ], | |
518 | "skips" : [] | |
519 | } | |
520 | }, | |
521 | "name" : "@DROLSKY/Test::Compile", | |
522 | "version" : "2.051" | |
523 | }, | |
524 | { | |
525 | "class" : "Dist::Zilla::Plugin::Test::EOL", | |
526 | "config" : { | |
527 | "Dist::Zilla::Plugin::Test::EOL" : { | |
528 | "filename" : "xt/author/eol.t", | |
529 | "finder" : [ | |
530 | ":InstallModules", | |
531 | ":ExecFiles", | |
532 | ":TestFiles" | |
533 | ], | |
534 | "trailing_whitespace" : "1" | |
535 | } | |
536 | }, | |
537 | "name" : "@DROLSKY/Test::EOL", | |
538 | "version" : "0.17" | |
539 | }, | |
540 | { | |
541 | "class" : "Dist::Zilla::Plugin::Test::NoTabs", | |
542 | "config" : { | |
543 | "Dist::Zilla::Plugin::Test::NoTabs" : { | |
544 | "filename" : "xt/author/no-tabs.t", | |
545 | "finder" : [ | |
546 | ":InstallModules", | |
547 | ":ExecFiles", | |
548 | ":TestFiles" | |
549 | ] | |
550 | } | |
551 | }, | |
552 | "name" : "@DROLSKY/Test::NoTabs", | |
553 | "version" : "0.13" | |
554 | }, | |
555 | { | |
556 | "class" : "Dist::Zilla::Plugin::Test::Pod::LinkCheck", | |
557 | "name" : "@DROLSKY/Test::Pod::LinkCheck", | |
558 | "version" : "1.001" | |
559 | }, | |
560 | { | |
561 | "class" : "Dist::Zilla::Plugin::Test::Pod::No404s", | |
562 | "name" : "@DROLSKY/Test::Pod::No404s", | |
563 | "version" : "1.001" | |
564 | }, | |
565 | { | |
566 | "class" : "Dist::Zilla::Plugin::Test::Portability", | |
567 | "name" : "@DROLSKY/Test::Portability", | |
568 | "version" : "2.000006" | |
569 | }, | |
570 | { | |
571 | "class" : "Dist::Zilla::Plugin::Test::Synopsis", | |
572 | "name" : "@DROLSKY/Test::Synopsis", | |
573 | "version" : "2.000006" | |
574 | }, | |
575 | { | |
576 | "class" : "Dist::Zilla::Plugin::Git::Check", | |
577 | "config" : { | |
578 | "Dist::Zilla::Plugin::Git::Check" : { | |
579 | "untracked_files" : "die" | |
580 | }, | |
581 | "Dist::Zilla::Role::Git::DirtyFiles" : { | |
582 | "allow_dirty" : [ | |
583 | "Makefile.PL", | |
584 | "README.md", | |
585 | "Build.PL", | |
586 | "LICENSE", | |
587 | "cpanfile", | |
588 | "Changes", | |
589 | "CONTRIBUTING.md" | |
590 | ], | |
591 | "allow_dirty_match" : [], | |
592 | "changelog" : "Changes" | |
593 | }, | |
594 | "Dist::Zilla::Role::Git::Repo" : { | |
595 | "repo_root" : "." | |
596 | } | |
597 | }, | |
598 | "name" : "@DROLSKY/Git::Check", | |
599 | "version" : "2.029" | |
600 | }, | |
601 | { | |
602 | "class" : "Dist::Zilla::Plugin::Git::Commit", | |
603 | "config" : { | |
604 | "Dist::Zilla::Plugin::Git::Commit" : { | |
605 | "add_files_in" : [], | |
606 | "commit_msg" : "v%v%n%n%c", | |
607 | "time_zone" : "local" | |
608 | }, | |
609 | "Dist::Zilla::Role::Git::DirtyFiles" : { | |
610 | "allow_dirty" : [ | |
611 | "Makefile.PL", | |
612 | "README.md", | |
613 | "Build.PL", | |
614 | "LICENSE", | |
615 | "cpanfile", | |
616 | "Changes", | |
617 | "CONTRIBUTING.md" | |
618 | ], | |
619 | "allow_dirty_match" : [], | |
620 | "changelog" : "Changes" | |
621 | }, | |
622 | "Dist::Zilla::Role::Git::Repo" : { | |
623 | "repo_root" : "." | |
624 | } | |
625 | }, | |
626 | "name" : "@DROLSKY/commit generated files", | |
627 | "version" : "2.029" | |
628 | }, | |
629 | { | |
630 | "class" : "Dist::Zilla::Plugin::Git::Tag", | |
631 | "config" : { | |
632 | "Dist::Zilla::Plugin::Git::Tag" : { | |
633 | "branch" : null, | |
634 | "signed" : 0, | |
635 | "tag" : "v1.18", | |
636 | "tag_format" : "v%v", | |
637 | "tag_message" : "v%v", | |
638 | "time_zone" : "local" | |
639 | }, | |
640 | "Dist::Zilla::Role::Git::Repo" : { | |
641 | "repo_root" : "." | |
642 | } | |
643 | }, | |
644 | "name" : "@DROLSKY/Git::Tag", | |
645 | "version" : "2.029" | |
646 | }, | |
647 | { | |
648 | "class" : "Dist::Zilla::Plugin::Git::Push", | |
649 | "config" : { | |
650 | "Dist::Zilla::Plugin::Git::Push" : { | |
651 | "push_to" : [ | |
652 | "origin" | |
653 | ], | |
654 | "remotes_must_exist" : 1 | |
655 | }, | |
656 | "Dist::Zilla::Role::Git::Repo" : { | |
657 | "repo_root" : "." | |
658 | } | |
659 | }, | |
660 | "name" : "@DROLSKY/Git::Push", | |
661 | "version" : "2.029" | |
662 | }, | |
663 | { | |
664 | "class" : "Dist::Zilla::Plugin::BumpVersionAfterRelease", | |
665 | "name" : "@DROLSKY/BumpVersionAfterRelease", | |
666 | "version" : "0.009" | |
667 | }, | |
668 | { | |
669 | "class" : "Dist::Zilla::Plugin::Git::Commit", | |
670 | "config" : { | |
671 | "Dist::Zilla::Plugin::Git::Commit" : { | |
672 | "add_files_in" : [], | |
673 | "commit_msg" : "Bump version after release", | |
674 | "time_zone" : "local" | |
675 | }, | |
676 | "Dist::Zilla::Role::Git::DirtyFiles" : { | |
677 | "allow_dirty" : [ | |
678 | "dist.ini", | |
679 | "Changes" | |
680 | ], | |
681 | "allow_dirty_match" : [ | |
682 | "(?^:.+)" | |
683 | ], | |
684 | "changelog" : "Changes" | |
685 | }, | |
686 | "Dist::Zilla::Role::Git::Repo" : { | |
687 | "repo_root" : "." | |
688 | } | |
689 | }, | |
690 | "name" : "@DROLSKY/commit version bump", | |
691 | "version" : "2.029" | |
692 | }, | |
693 | { | |
694 | "class" : "Dist::Zilla::Plugin::Git::Push", | |
695 | "config" : { | |
696 | "Dist::Zilla::Plugin::Git::Push" : { | |
697 | "push_to" : [ | |
698 | "origin" | |
699 | ], | |
700 | "remotes_must_exist" : 1 | |
701 | }, | |
702 | "Dist::Zilla::Role::Git::Repo" : { | |
703 | "repo_root" : "." | |
704 | } | |
705 | }, | |
706 | "name" : "@DROLSKY/push version bump", | |
707 | "version" : "2.029" | |
708 | }, | |
709 | { | |
710 | "class" : "Dist::Zilla::Plugin::Prereqs", | |
711 | "config" : { | |
712 | "Dist::Zilla::Plugin::Prereqs" : { | |
713 | "phase" : "develop", | |
714 | "type" : "requires" | |
715 | } | |
716 | }, | |
717 | "name" : "DevelopRequires", | |
718 | "version" : "5.031" | |
719 | }, | |
720 | { | |
721 | "class" : "inc::MyModuleBuild", | |
722 | "config" : { | |
723 | "Dist::Zilla::Role::TestRunner" : { | |
724 | "default_jobs" : 1 | |
725 | } | |
726 | }, | |
727 | "name" : "=inc::MyModuleBuild", | |
728 | "version" : null | |
729 | }, | |
730 | { | |
731 | "class" : "Dist::Zilla::Plugin::PurePerlTests", | |
732 | "name" : "PurePerlTests", | |
733 | "version" : "0.04" | |
734 | }, | |
735 | { | |
736 | "class" : "Dist::Zilla::Plugin::FinderCode", | |
737 | "name" : ":InstallModules", | |
738 | "version" : "5.031" | |
739 | }, | |
740 | { | |
741 | "class" : "Dist::Zilla::Plugin::FinderCode", | |
742 | "name" : ":IncModules", | |
743 | "version" : "5.031" | |
744 | }, | |
745 | { | |
746 | "class" : "Dist::Zilla::Plugin::FinderCode", | |
747 | "name" : ":TestFiles", | |
748 | "version" : "5.031" | |
749 | }, | |
750 | { | |
751 | "class" : "Dist::Zilla::Plugin::FinderCode", | |
752 | "name" : ":ExecFiles", | |
753 | "version" : "5.031" | |
754 | }, | |
755 | { | |
756 | "class" : "Dist::Zilla::Plugin::FinderCode", | |
757 | "name" : ":ShareFiles", | |
758 | "version" : "5.031" | |
759 | }, | |
760 | { | |
761 | "class" : "Dist::Zilla::Plugin::FinderCode", | |
762 | "name" : ":MainModule", | |
763 | "version" : "5.031" | |
764 | }, | |
765 | { | |
766 | "class" : "Dist::Zilla::Plugin::FinderCode", | |
767 | "name" : ":AllFiles", | |
768 | "version" : "5.031" | |
769 | }, | |
770 | { | |
771 | "class" : "Dist::Zilla::Plugin::FinderCode", | |
772 | "name" : ":NoFiles", | |
773 | "version" : "5.031" | |
774 | }, | |
775 | { | |
776 | "class" : "Dist::Zilla::Plugin::FinderCode", | |
777 | "name" : "@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM", | |
778 | "version" : "5.031" | |
779 | } | |
780 | ], | |
781 | "zilla" : { | |
782 | "class" : "Dist::Zilla::Dist::Builder", | |
783 | "config" : { | |
784 | "is_trial" : "0" | |
785 | }, | |
786 | "version" : "5.031" | |
787 | } | |
788 | }, | |
789 | "x_authority" : "cpan:DROLSKY", | |
790 | "x_contributors" : [ | |
791 | "J.R. Mash <jmash.code@gmail.com>", | |
792 | "Olivier Mengué <dolmen@cpan.org>" | |
793 | ] | |
78 | 794 | } |
79 | 795 |
3 | 3 | - 'Dave Rolsky <autarch@urth.org>' |
4 | 4 | - 'Ilya Martynov <ilya@martynov.org>' |
5 | 5 | build_requires: |
6 | Devel::Peek: 0 | |
7 | File::Spec: 0 | |
8 | File::Temp: 0 | |
9 | Module::Build: 0.3601 | |
10 | Test::Fatal: 0 | |
11 | Test::More: 0.88 | |
12 | Test::Requires: 0 | |
13 | Tie::Array: 0 | |
14 | Tie::Hash: 0 | |
15 | base: 0 | |
16 | lib: 0 | |
17 | overload: 0 | |
6 | Devel::Peek: '0' | |
7 | ExtUtils::MakeMaker: '0' | |
8 | File::Spec: '0' | |
9 | File::Temp: '0' | |
10 | IO::Handle: '0' | |
11 | IPC::Open3: '0' | |
12 | Module::Build: '0.28' | |
13 | Test::Fatal: '0' | |
14 | Test::More: '0.96' | |
15 | Test::Requires: '0' | |
16 | Tie::Array: '0' | |
17 | Tie::Hash: '0' | |
18 | base: '0' | |
19 | lib: '0' | |
20 | overload: '0' | |
18 | 21 | configure_requires: |
19 | Module::Build: 0.3601 | |
22 | Module::Build: '0.28' | |
20 | 23 | dynamic_config: 0 |
21 | generated_by: 'Dist::Zilla version 5.019, CPAN::Meta::Converter version 2.120921' | |
24 | generated_by: 'Dist::Zilla version 5.031, CPAN::Meta::Converter version 2.143240' | |
22 | 25 | license: artistic_2 |
23 | 26 | meta-spec: |
24 | 27 | url: http://module-build.sourceforge.net/META-spec-v1.4.html |
25 | version: 1.4 | |
28 | version: '1.4' | |
26 | 29 | name: Params-Validate |
30 | provides: | |
31 | Attribute::Params::Validate: | |
32 | file: lib/Attribute/Params/Validate.pm | |
33 | version: '1.18' | |
34 | Params::Validate: | |
35 | file: lib/Params/Validate.pm | |
36 | version: '1.18' | |
37 | Params::Validate::Constants: | |
38 | file: lib/Params/Validate/Constants.pm | |
39 | version: '1.18' | |
40 | Params::Validate::PP: | |
41 | file: lib/Params/Validate/PP.pm | |
42 | version: '1.18' | |
43 | Params::Validate::XS: | |
44 | file: lib/Params/Validate/XS.pm | |
45 | version: '1.18' | |
27 | 46 | requires: |
28 | Attribute::Handlers: 0.79 | |
29 | Carp: 0 | |
30 | Exporter: 0 | |
31 | Module::Implementation: 0 | |
32 | Scalar::Util: 1.10 | |
33 | XSLoader: 0 | |
34 | attributes: 0 | |
35 | perl: 5.008001 | |
36 | strict: 0 | |
37 | vars: 0 | |
38 | warnings: 0 | |
47 | Attribute::Handlers: '0.79' | |
48 | Carp: '0' | |
49 | Exporter: '0' | |
50 | Module::Implementation: '0' | |
51 | Scalar::Util: '1.10' | |
52 | XSLoader: '0' | |
53 | attributes: '0' | |
54 | perl: '5.008001' | |
55 | strict: '0' | |
56 | vars: '0' | |
57 | warnings: '0' | |
39 | 58 | resources: |
40 | bugtracker: http://rt.cpan.org/NoAuth/Bugs.html?Dist=Params-Validate | |
41 | repository: git://git.urth.org/Params-Validate.git | |
42 | version: 1.13 | |
59 | bugtracker: http://rt.cpan.org/Public/Dist/Display.html?Name=Params-Validate | |
60 | homepage: http://metacpan.org/release/Params-Validate | |
61 | repository: git://github.com/autarch/Params-Validate.git | |
62 | version: '1.18' | |
63 | x_Dist_Zilla: | |
64 | perl: | |
65 | version: '5.020001' | |
66 | plugins: | |
67 | - | |
68 | class: Dist::Zilla::Plugin::Authority | |
69 | name: '@DROLSKY/Authority' | |
70 | version: '1.009' | |
71 | - | |
72 | class: Dist::Zilla::Plugin::AutoPrereqs | |
73 | name: '@DROLSKY/AutoPrereqs' | |
74 | version: '5.031' | |
75 | - | |
76 | class: Dist::Zilla::Plugin::CopyFilesFromBuild | |
77 | name: '@DROLSKY/CopyFilesFromBuild' | |
78 | version: '0.150250' | |
79 | - | |
80 | class: Dist::Zilla::Plugin::Git::GatherDir | |
81 | config: | |
82 | Dist::Zilla::Plugin::GatherDir: | |
83 | exclude_filename: | |
84 | - Makefile.PL | |
85 | - README.md | |
86 | - Build.PL | |
87 | - LICENSE | |
88 | - cpanfile | |
89 | exclude_match: [] | |
90 | follow_symlinks: '0' | |
91 | include_dotfiles: '0' | |
92 | prefix: '' | |
93 | prune_directory: [] | |
94 | root: . | |
95 | Dist::Zilla::Plugin::Git::GatherDir: | |
96 | include_untracked: '0' | |
97 | Dist::Zilla::Role::Git::Repo: | |
98 | repo_root: . | |
99 | name: '@DROLSKY/Git::GatherDir' | |
100 | version: '2.029' | |
101 | - | |
102 | class: Dist::Zilla::Plugin::GitHub::Meta | |
103 | name: '@DROLSKY/GitHub::Meta' | |
104 | version: '0.40' | |
105 | - | |
106 | class: Dist::Zilla::Plugin::GitHub::Update | |
107 | name: '@DROLSKY/GitHub::Update' | |
108 | version: '0.40' | |
109 | - | |
110 | class: Dist::Zilla::Plugin::MetaResources | |
111 | name: '@DROLSKY/MetaResources' | |
112 | version: '5.031' | |
113 | - | |
114 | class: Dist::Zilla::Plugin::MetaProvides::Package | |
115 | config: | |
116 | Dist::Zilla::Plugin::MetaProvides::Package: | |
117 | finder_objects: | |
118 | - | |
119 | class: Dist::Zilla::Plugin::FinderCode | |
120 | name: '@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM' | |
121 | version: '5.031' | |
122 | Dist::Zilla::Role::MetaProvider::Provider: | |
123 | inherit_missing: '1' | |
124 | inherit_version: '1' | |
125 | meta_noindex: '1' | |
126 | name: '@DROLSKY/MetaProvides::Package' | |
127 | version: '2.003001' | |
128 | - | |
129 | class: Dist::Zilla::Plugin::NextRelease | |
130 | name: '@DROLSKY/NextRelease' | |
131 | version: '5.031' | |
132 | - | |
133 | class: Dist::Zilla::Plugin::Prereqs | |
134 | config: | |
135 | Dist::Zilla::Plugin::Prereqs: | |
136 | phase: test | |
137 | type: requires | |
138 | name: '@DROLSKY/Test::More with subtest()' | |
139 | version: '5.031' | |
140 | - | |
141 | class: Dist::Zilla::Plugin::Prereqs | |
142 | config: | |
143 | Dist::Zilla::Plugin::Prereqs: | |
144 | phase: develop | |
145 | type: requires | |
146 | name: '@DROLSKY/Modules for use with tidyall' | |
147 | version: '5.031' | |
148 | - | |
149 | class: Dist::Zilla::Plugin::PromptIfStale | |
150 | config: | |
151 | Dist::Zilla::Plugin::PromptIfStale: | |
152 | check_all_plugins: '1' | |
153 | check_all_prereqs: '1' | |
154 | modules: [] | |
155 | phase: release | |
156 | skip: | |
157 | - Dist::Zilla::Plugin::DROLSKY::Contributors | |
158 | - Dist::Zilla::Plugin::DROLSKY::License | |
159 | - Dist::Zilla::Plugin::DROLSKY::TidyAll | |
160 | name: '@DROLSKY/PromptIfStale' | |
161 | version: '0.038' | |
162 | - | |
163 | class: Dist::Zilla::Plugin::ReadmeAnyFromPod | |
164 | name: '@DROLSKY/README.md in build' | |
165 | version: '0.150250' | |
166 | - | |
167 | class: Dist::Zilla::Plugin::ReadmeAnyFromPod | |
168 | name: '@DROLSKY/README.md in root' | |
169 | version: '0.150250' | |
170 | - | |
171 | class: Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable | |
172 | name: '@DROLSKY/Test::Pod::Coverage::Configurable' | |
173 | version: '0.03' | |
174 | - | |
175 | class: Dist::Zilla::Plugin::Test::PodSpelling | |
176 | name: '@DROLSKY/Test::PodSpelling' | |
177 | version: '2.006008' | |
178 | - | |
179 | class: Dist::Zilla::Plugin::Test::ReportPrereqs | |
180 | name: '@DROLSKY/Test::ReportPrereqs' | |
181 | version: '0.020' | |
182 | - | |
183 | class: Dist::Zilla::Plugin::Test::Version | |
184 | name: '@DROLSKY/Test::Version' | |
185 | version: '0.003001' | |
186 | - | |
187 | class: Dist::Zilla::Plugin::ManifestSkip | |
188 | name: '@DROLSKY/ManifestSkip' | |
189 | version: '5.031' | |
190 | - | |
191 | class: Dist::Zilla::Plugin::MetaYAML | |
192 | name: '@DROLSKY/MetaYAML' | |
193 | version: '5.031' | |
194 | - | |
195 | class: Dist::Zilla::Plugin::License | |
196 | name: '@DROLSKY/License' | |
197 | version: '5.031' | |
198 | - | |
199 | class: Dist::Zilla::Plugin::ExtraTests | |
200 | name: '@DROLSKY/ExtraTests' | |
201 | version: '5.031' | |
202 | - | |
203 | class: Dist::Zilla::Plugin::ExecDir | |
204 | name: '@DROLSKY/ExecDir' | |
205 | version: '5.031' | |
206 | - | |
207 | class: Dist::Zilla::Plugin::ShareDir | |
208 | name: '@DROLSKY/ShareDir' | |
209 | version: '5.031' | |
210 | - | |
211 | class: Dist::Zilla::Plugin::Manifest | |
212 | name: '@DROLSKY/Manifest' | |
213 | version: '5.031' | |
214 | - | |
215 | class: Dist::Zilla::Plugin::CheckVersionIncrement | |
216 | name: '@DROLSKY/CheckVersionIncrement' | |
217 | version: '0.121750' | |
218 | - | |
219 | class: Dist::Zilla::Plugin::TestRelease | |
220 | name: '@DROLSKY/TestRelease' | |
221 | version: '5.031' | |
222 | - | |
223 | class: Dist::Zilla::Plugin::ConfirmRelease | |
224 | name: '@DROLSKY/ConfirmRelease' | |
225 | version: '5.031' | |
226 | - | |
227 | class: Dist::Zilla::Plugin::UploadToCPAN | |
228 | name: '@DROLSKY/UploadToCPAN' | |
229 | version: '5.031' | |
230 | - | |
231 | class: Dist::Zilla::Plugin::CheckPrereqsIndexed | |
232 | name: '@DROLSKY/CheckPrereqsIndexed' | |
233 | version: '0.015' | |
234 | - | |
235 | class: Dist::Zilla::Plugin::CPANFile | |
236 | name: '@DROLSKY/CPANFile' | |
237 | version: '5.031' | |
238 | - | |
239 | class: Dist::Zilla::Plugin::DROLSKY::Contributors | |
240 | name: '@DROLSKY/DROLSKY::Contributors' | |
241 | version: '0.32' | |
242 | - | |
243 | class: Dist::Zilla::Plugin::DROLSKY::License | |
244 | name: '@DROLSKY/DROLSKY::License' | |
245 | version: '0.32' | |
246 | - | |
247 | class: Dist::Zilla::Plugin::DROLSKY::TidyAll | |
248 | name: '@DROLSKY/DROLSKY::TidyAll' | |
249 | version: '0.32' | |
250 | - | |
251 | class: Dist::Zilla::Plugin::Git::CheckFor::CorrectBranch | |
252 | config: | |
253 | Dist::Zilla::Role::Git::Repo: | |
254 | repo_root: . | |
255 | name: '@DROLSKY/Git::CheckFor::CorrectBranch' | |
256 | version: '0.011' | |
257 | - | |
258 | class: Dist::Zilla::Plugin::Git::CheckFor::MergeConflicts | |
259 | config: | |
260 | Dist::Zilla::Role::Git::Repo: | |
261 | repo_root: . | |
262 | name: '@DROLSKY/Git::CheckFor::MergeConflicts' | |
263 | version: '0.011' | |
264 | - | |
265 | class: Dist::Zilla::Plugin::Git::Contributors | |
266 | config: | |
267 | Dist::Zilla::Plugin::Git::Contributors: | |
268 | include_authors: '0' | |
269 | include_releaser: '1' | |
270 | order_by: name | |
271 | paths: [] | |
272 | name: '@DROLSKY/Git::Contributors' | |
273 | version: '0.009' | |
274 | - | |
275 | class: Dist::Zilla::Plugin::InstallGuide | |
276 | name: '@DROLSKY/InstallGuide' | |
277 | version: '1.200006' | |
278 | - | |
279 | class: Dist::Zilla::Plugin::Meta::Contributors | |
280 | name: '@DROLSKY/Meta::Contributors' | |
281 | version: '0.001' | |
282 | - | |
283 | class: Dist::Zilla::Plugin::MetaConfig | |
284 | name: '@DROLSKY/MetaConfig' | |
285 | version: '5.031' | |
286 | - | |
287 | class: Dist::Zilla::Plugin::MetaJSON | |
288 | name: '@DROLSKY/MetaJSON' | |
289 | version: '5.031' | |
290 | - | |
291 | class: Dist::Zilla::Plugin::RewriteVersion | |
292 | name: '@DROLSKY/RewriteVersion' | |
293 | version: '0.009' | |
294 | - | |
295 | class: Dist::Zilla::Plugin::SurgicalPodWeaver | |
296 | config: | |
297 | Dist::Zilla::Plugin::PodWeaver: | |
298 | finder: | |
299 | - ':InstallModules' | |
300 | - ':ExecFiles' | |
301 | plugins: | |
302 | - | |
303 | class: Pod::Weaver::Plugin::EnsurePod5 | |
304 | name: '@CorePrep/EnsurePod5' | |
305 | version: '4.010' | |
306 | - | |
307 | class: Pod::Weaver::Plugin::H1Nester | |
308 | name: '@CorePrep/H1Nester' | |
309 | version: '4.010' | |
310 | - | |
311 | class: Pod::Weaver::Section::Name | |
312 | name: Name | |
313 | version: '4.010' | |
314 | - | |
315 | class: Pod::Weaver::Section::Version | |
316 | name: Version | |
317 | version: '4.010' | |
318 | - | |
319 | class: Pod::Weaver::Section::Region | |
320 | name: prelude | |
321 | version: '4.010' | |
322 | - | |
323 | class: Pod::Weaver::Section::Generic | |
324 | name: SYNOPSIS | |
325 | version: '4.010' | |
326 | - | |
327 | class: Pod::Weaver::Section::Generic | |
328 | name: DESCRIPTION | |
329 | version: '4.010' | |
330 | - | |
331 | class: Pod::Weaver::Section::Leftovers | |
332 | name: Leftovers | |
333 | version: '4.010' | |
334 | - | |
335 | class: Pod::Weaver::Section::Region | |
336 | name: postlude | |
337 | version: '4.010' | |
338 | - | |
339 | class: Pod::Weaver::Section::Authors | |
340 | name: Authors | |
341 | version: '4.010' | |
342 | - | |
343 | class: Pod::Weaver::Section::Contributors | |
344 | name: Contributors | |
345 | version: '0.009' | |
346 | - | |
347 | class: Pod::Weaver::Section::Legal | |
348 | name: Legal | |
349 | version: '4.010' | |
350 | name: '@DROLSKY/SurgicalPodWeaver' | |
351 | version: '0.0023' | |
352 | - | |
353 | class: Dist::Zilla::Plugin::PodSyntaxTests | |
354 | name: '@DROLSKY/PodSyntaxTests' | |
355 | version: '5.031' | |
356 | - | |
357 | class: Dist::Zilla::Plugin::Test::CPAN::Changes | |
358 | name: '@DROLSKY/Test::CPAN::Changes' | |
359 | version: '0.009' | |
360 | - | |
361 | class: Dist::Zilla::Plugin::Test::Compile | |
362 | config: | |
363 | Dist::Zilla::Plugin::Test::Compile: | |
364 | bail_out_on_fail: '0' | |
365 | fail_on_warning: author | |
366 | fake_home: '0' | |
367 | filename: t/00-compile.t | |
368 | module_finder: | |
369 | - ':InstallModules' | |
370 | needs_display: '0' | |
371 | phase: test | |
372 | script_finder: | |
373 | - ':ExecFiles' | |
374 | skips: [] | |
375 | name: '@DROLSKY/Test::Compile' | |
376 | version: '2.051' | |
377 | - | |
378 | class: Dist::Zilla::Plugin::Test::EOL | |
379 | config: | |
380 | Dist::Zilla::Plugin::Test::EOL: | |
381 | filename: xt/author/eol.t | |
382 | finder: | |
383 | - ':InstallModules' | |
384 | - ':ExecFiles' | |
385 | - ':TestFiles' | |
386 | trailing_whitespace: '1' | |
387 | name: '@DROLSKY/Test::EOL' | |
388 | version: '0.17' | |
389 | - | |
390 | class: Dist::Zilla::Plugin::Test::NoTabs | |
391 | config: | |
392 | Dist::Zilla::Plugin::Test::NoTabs: | |
393 | filename: xt/author/no-tabs.t | |
394 | finder: | |
395 | - ':InstallModules' | |
396 | - ':ExecFiles' | |
397 | - ':TestFiles' | |
398 | name: '@DROLSKY/Test::NoTabs' | |
399 | version: '0.13' | |
400 | - | |
401 | class: Dist::Zilla::Plugin::Test::Pod::LinkCheck | |
402 | name: '@DROLSKY/Test::Pod::LinkCheck' | |
403 | version: '1.001' | |
404 | - | |
405 | class: Dist::Zilla::Plugin::Test::Pod::No404s | |
406 | name: '@DROLSKY/Test::Pod::No404s' | |
407 | version: '1.001' | |
408 | - | |
409 | class: Dist::Zilla::Plugin::Test::Portability | |
410 | name: '@DROLSKY/Test::Portability' | |
411 | version: '2.000006' | |
412 | - | |
413 | class: Dist::Zilla::Plugin::Test::Synopsis | |
414 | name: '@DROLSKY/Test::Synopsis' | |
415 | version: '2.000006' | |
416 | - | |
417 | class: Dist::Zilla::Plugin::Git::Check | |
418 | config: | |
419 | Dist::Zilla::Plugin::Git::Check: | |
420 | untracked_files: die | |
421 | Dist::Zilla::Role::Git::DirtyFiles: | |
422 | allow_dirty: | |
423 | - Makefile.PL | |
424 | - README.md | |
425 | - Build.PL | |
426 | - LICENSE | |
427 | - cpanfile | |
428 | - Changes | |
429 | - CONTRIBUTING.md | |
430 | allow_dirty_match: [] | |
431 | changelog: Changes | |
432 | Dist::Zilla::Role::Git::Repo: | |
433 | repo_root: . | |
434 | name: '@DROLSKY/Git::Check' | |
435 | version: '2.029' | |
436 | - | |
437 | class: Dist::Zilla::Plugin::Git::Commit | |
438 | config: | |
439 | Dist::Zilla::Plugin::Git::Commit: | |
440 | add_files_in: [] | |
441 | commit_msg: v%v%n%n%c | |
442 | time_zone: local | |
443 | Dist::Zilla::Role::Git::DirtyFiles: | |
444 | allow_dirty: | |
445 | - Makefile.PL | |
446 | - README.md | |
447 | - Build.PL | |
448 | - LICENSE | |
449 | - cpanfile | |
450 | - Changes | |
451 | - CONTRIBUTING.md | |
452 | allow_dirty_match: [] | |
453 | changelog: Changes | |
454 | Dist::Zilla::Role::Git::Repo: | |
455 | repo_root: . | |
456 | name: '@DROLSKY/commit generated files' | |
457 | version: '2.029' | |
458 | - | |
459 | class: Dist::Zilla::Plugin::Git::Tag | |
460 | config: | |
461 | Dist::Zilla::Plugin::Git::Tag: | |
462 | branch: ~ | |
463 | signed: 0 | |
464 | tag: v1.18 | |
465 | tag_format: v%v | |
466 | tag_message: v%v | |
467 | time_zone: local | |
468 | Dist::Zilla::Role::Git::Repo: | |
469 | repo_root: . | |
470 | name: '@DROLSKY/Git::Tag' | |
471 | version: '2.029' | |
472 | - | |
473 | class: Dist::Zilla::Plugin::Git::Push | |
474 | config: | |
475 | Dist::Zilla::Plugin::Git::Push: | |
476 | push_to: | |
477 | - origin | |
478 | remotes_must_exist: 1 | |
479 | Dist::Zilla::Role::Git::Repo: | |
480 | repo_root: . | |
481 | name: '@DROLSKY/Git::Push' | |
482 | version: '2.029' | |
483 | - | |
484 | class: Dist::Zilla::Plugin::BumpVersionAfterRelease | |
485 | name: '@DROLSKY/BumpVersionAfterRelease' | |
486 | version: '0.009' | |
487 | - | |
488 | class: Dist::Zilla::Plugin::Git::Commit | |
489 | config: | |
490 | Dist::Zilla::Plugin::Git::Commit: | |
491 | add_files_in: [] | |
492 | commit_msg: 'Bump version after release' | |
493 | time_zone: local | |
494 | Dist::Zilla::Role::Git::DirtyFiles: | |
495 | allow_dirty: | |
496 | - dist.ini | |
497 | - Changes | |
498 | allow_dirty_match: | |
499 | - (?^:.+) | |
500 | changelog: Changes | |
501 | Dist::Zilla::Role::Git::Repo: | |
502 | repo_root: . | |
503 | name: '@DROLSKY/commit version bump' | |
504 | version: '2.029' | |
505 | - | |
506 | class: Dist::Zilla::Plugin::Git::Push | |
507 | config: | |
508 | Dist::Zilla::Plugin::Git::Push: | |
509 | push_to: | |
510 | - origin | |
511 | remotes_must_exist: 1 | |
512 | Dist::Zilla::Role::Git::Repo: | |
513 | repo_root: . | |
514 | name: '@DROLSKY/push version bump' | |
515 | version: '2.029' | |
516 | - | |
517 | class: Dist::Zilla::Plugin::Prereqs | |
518 | config: | |
519 | Dist::Zilla::Plugin::Prereqs: | |
520 | phase: develop | |
521 | type: requires | |
522 | name: DevelopRequires | |
523 | version: '5.031' | |
524 | - | |
525 | class: inc::MyModuleBuild | |
526 | config: | |
527 | Dist::Zilla::Role::TestRunner: | |
528 | default_jobs: 1 | |
529 | name: =inc::MyModuleBuild | |
530 | version: ~ | |
531 | - | |
532 | class: Dist::Zilla::Plugin::PurePerlTests | |
533 | name: PurePerlTests | |
534 | version: '0.04' | |
535 | - | |
536 | class: Dist::Zilla::Plugin::FinderCode | |
537 | name: ':InstallModules' | |
538 | version: '5.031' | |
539 | - | |
540 | class: Dist::Zilla::Plugin::FinderCode | |
541 | name: ':IncModules' | |
542 | version: '5.031' | |
543 | - | |
544 | class: Dist::Zilla::Plugin::FinderCode | |
545 | name: ':TestFiles' | |
546 | version: '5.031' | |
547 | - | |
548 | class: Dist::Zilla::Plugin::FinderCode | |
549 | name: ':ExecFiles' | |
550 | version: '5.031' | |
551 | - | |
552 | class: Dist::Zilla::Plugin::FinderCode | |
553 | name: ':ShareFiles' | |
554 | version: '5.031' | |
555 | - | |
556 | class: Dist::Zilla::Plugin::FinderCode | |
557 | name: ':MainModule' | |
558 | version: '5.031' | |
559 | - | |
560 | class: Dist::Zilla::Plugin::FinderCode | |
561 | name: ':AllFiles' | |
562 | version: '5.031' | |
563 | - | |
564 | class: Dist::Zilla::Plugin::FinderCode | |
565 | name: ':NoFiles' | |
566 | version: '5.031' | |
567 | - | |
568 | class: Dist::Zilla::Plugin::FinderCode | |
569 | name: '@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM' | |
570 | version: '5.031' | |
571 | zilla: | |
572 | class: Dist::Zilla::Dist::Builder | |
573 | config: | |
574 | is_trial: '0' | |
575 | version: '5.031' | |
576 | x_authority: cpan:DROLSKY | |
577 | x_contributors: | |
578 | - 'J.R. Mash <jmash.code@gmail.com>' | |
579 | - 'Olivier Mengué <dolmen@cpan.org>' |
0 | ||
1 | ||
2 | This archive contains the distribution Params-Validate, | |
3 | version 1.13: | |
4 | ||
5 | Validate method/function parameters | |
6 | ||
7 | This software is Copyright (c) 2014 by Dave Rolsky and Ilya Martynov. | |
8 | ||
9 | This is free software, licensed under: | |
10 | ||
11 | The Artistic License 2.0 (GPL Compatible) | |
12 | ||
13 | ||
14 | This README file was generated by Dist::Zilla::Plugin::Readme v5.019. | |
15 |
0 | NAME | |
1 | ||
2 | Params::Validate - Validate method/function parameters | |
3 | ||
4 | VERSION | |
5 | ||
6 | version 1.18 | |
7 | ||
8 | SYNOPSIS | |
9 | ||
10 | use Params::Validate qw(:all); | |
11 | ||
12 | # takes named params (hash or hashref) | |
13 | sub foo { | |
14 | validate( | |
15 | @_, { | |
16 | foo => 1, # mandatory | |
17 | bar => 0, # optional | |
18 | } | |
19 | ); | |
20 | } | |
21 | ||
22 | # takes positional params | |
23 | sub bar { | |
24 | # first two are mandatory, third is optional | |
25 | validate_pos( @_, 1, 1, 0 ); | |
26 | } | |
27 | ||
28 | sub foo2 { | |
29 | validate( | |
30 | @_, { | |
31 | foo => | |
32 | # specify a type | |
33 | { type => ARRAYREF }, | |
34 | bar => | |
35 | # specify an interface | |
36 | { can => [ 'print', 'flush', 'frobnicate' ] }, | |
37 | baz => { | |
38 | type => SCALAR, # a scalar ... | |
39 | # ... that is a plain integer ... | |
40 | regex => qr/^\d+$/, | |
41 | callbacks => { # ... and smaller than 90 | |
42 | 'less than 90' => sub { shift() < 90 }, | |
43 | }, | |
44 | } | |
45 | } | |
46 | ); | |
47 | } | |
48 | ||
49 | sub callback_with_custom_error { | |
50 | validate( | |
51 | @_, | |
52 | { | |
53 | foo => callbacks => { | |
54 | 'is an integer' => sub { | |
55 | return 1 if $_[0] =~ /^-?[1-9][0-9]*$/; | |
56 | die "$_[0] is not a valid integer value"; | |
57 | }, | |
58 | } | |
59 | } | |
60 | ); | |
61 | } | |
62 | ||
63 | sub with_defaults { | |
64 | my %p = validate( | |
65 | @_, { | |
66 | # required | |
67 | foo => 1, | |
68 | # $p{bar} will be 99 if bar is not given. bar is now | |
69 | # optional. | |
70 | bar => { default => 99 } | |
71 | } | |
72 | ); | |
73 | } | |
74 | ||
75 | sub pos_with_defaults { | |
76 | my @p = validate_pos( @_, 1, { default => 99 } ); | |
77 | } | |
78 | ||
79 | sub sets_options_on_call { | |
80 | my %p = validate_with( | |
81 | params => \@_, | |
82 | spec => { foo => { type => SCALAR, default => 2 } }, | |
83 | normalize_keys => sub { $_[0] =~ s/^-//; lc $_[0] }, | |
84 | ); | |
85 | } | |
86 | ||
87 | DESCRIPTION | |
88 | ||
89 | The Params::Validate module allows you to validate method or function | |
90 | call parameters to an arbitrary level of specificity. At the simplest | |
91 | level, it is capable of validating the required parameters were given | |
92 | and that no unspecified additional parameters were passed in. | |
93 | ||
94 | It is also capable of determining that a parameter is of a specific | |
95 | type, that it is an object of a certain class hierarchy, that it | |
96 | possesses certain methods, or applying validation callbacks to | |
97 | arguments. | |
98 | ||
99 | EXPORT | |
100 | ||
101 | The module always exports the validate() and validate_pos() functions. | |
102 | ||
103 | It also has an additional function available for export, validate_with, | |
104 | which can be used to validate any type of parameters, and set various | |
105 | options on a per-invocation basis. | |
106 | ||
107 | In addition, it can export the following constants, which are used as | |
108 | part of the type checking. These are SCALAR, ARRAYREF, HASHREF, | |
109 | CODEREF, GLOB, GLOBREF, and SCALARREF, UNDEF, OBJECT, BOOLEAN, and | |
110 | HANDLE. These are explained in the section on Type Validation. | |
111 | ||
112 | The constants are available via the export tag :types. There is also an | |
113 | :all tag which includes all of the constants as well as the | |
114 | validation_options() function. | |
115 | ||
116 | PARAMETER VALIDATION | |
117 | ||
118 | The validation mechanisms provided by this module can handle both named | |
119 | or positional parameters. For the most part, the same features are | |
120 | available for each. The biggest difference is the way that the | |
121 | validation specification is given to the relevant subroutine. The other | |
122 | difference is in the error messages produced when validation checks | |
123 | fail. | |
124 | ||
125 | When handling named parameters, the module will accept either a hash or | |
126 | a hash reference. | |
127 | ||
128 | Subroutines expecting named parameters should call the validate() | |
129 | subroutine like this: | |
130 | ||
131 | validate( | |
132 | @_, { | |
133 | parameter1 => validation spec, | |
134 | parameter2 => validation spec, | |
135 | ... | |
136 | } | |
137 | ); | |
138 | ||
139 | Subroutines expecting positional parameters should call the | |
140 | validate_pos() subroutine like this: | |
141 | ||
142 | validate_pos( @_, { validation spec }, { validation spec } ); | |
143 | ||
144 | Mandatory/Optional Parameters | |
145 | ||
146 | If you just want to specify that some parameters are mandatory and | |
147 | others are optional, this can be done very simply. | |
148 | ||
149 | For a subroutine expecting named parameters, you would do this: | |
150 | ||
151 | validate( @_, { foo => 1, bar => 1, baz => 0 } ); | |
152 | ||
153 | This says that the "foo" and "bar" parameters are mandatory and that | |
154 | the "baz" parameter is optional. The presence of any other parameters | |
155 | will cause an error. | |
156 | ||
157 | For a subroutine expecting positional parameters, you would do this: | |
158 | ||
159 | validate_pos( @_, 1, 1, 0, 0 ); | |
160 | ||
161 | This says that you expect at least 2 and no more than 4 parameters. If | |
162 | you have a subroutine that has a minimum number of parameters but can | |
163 | take any maximum number, you can do this: | |
164 | ||
165 | validate_pos( @_, 1, 1, (0) x (@_ - 2) ); | |
166 | ||
167 | This will always be valid as long as at least two parameters are given. | |
168 | A similar construct could be used for the more complex validation | |
169 | parameters described further on. | |
170 | ||
171 | Please note that this: | |
172 | ||
173 | validate_pos( @_, 1, 1, 0, 1, 1 ); | |
174 | ||
175 | makes absolutely no sense, so don't do it. Any zeros must come at the | |
176 | end of the validation specification. | |
177 | ||
178 | In addition, if you specify that a parameter can have a default, then | |
179 | it is considered optional. | |
180 | ||
181 | Type Validation | |
182 | ||
183 | This module supports the following simple types, which can be exported | |
184 | as constants: | |
185 | ||
186 | * SCALAR | |
187 | ||
188 | A scalar which is not a reference, such as 10 or 'hello'. A parameter | |
189 | that is undefined is not treated as a scalar. If you want to allow | |
190 | undefined values, you will have to specify SCALAR | UNDEF. | |
191 | ||
192 | * ARRAYREF | |
193 | ||
194 | An array reference such as [1, 2, 3] or \@foo. | |
195 | ||
196 | * HASHREF | |
197 | ||
198 | A hash reference such as { a => 1, b => 2 } or \%bar. | |
199 | ||
200 | * CODEREF | |
201 | ||
202 | A subroutine reference such as \&foo_sub or sub { print "hello" }. | |
203 | ||
204 | * GLOB | |
205 | ||
206 | This one is a bit tricky. A glob would be something like *FOO, but | |
207 | not \*FOO, which is a glob reference. It should be noted that this | |
208 | trick: | |
209 | ||
210 | my $fh = do { local *FH; }; | |
211 | ||
212 | makes $fh a glob, not a glob reference. On the other hand, the return | |
213 | value from Symbol::gensym is a glob reference. Either can be used as | |
214 | a file or directory handle. | |
215 | ||
216 | * GLOBREF | |
217 | ||
218 | A glob reference such as \*FOO. See the GLOB entry above for more | |
219 | details. | |
220 | ||
221 | * SCALARREF | |
222 | ||
223 | A reference to a scalar such as \$x. | |
224 | ||
225 | * UNDEF | |
226 | ||
227 | An undefined value | |
228 | ||
229 | * OBJECT | |
230 | ||
231 | A blessed reference. | |
232 | ||
233 | * BOOLEAN | |
234 | ||
235 | This is a special option, and is just a shortcut for UNDEF | SCALAR. | |
236 | ||
237 | * HANDLE | |
238 | ||
239 | This option is also special, and is just a shortcut for GLOB | | |
240 | GLOBREF. However, it seems likely that most people interested in | |
241 | either globs or glob references are likely to really be interested in | |
242 | whether the parameter in question could be a valid file or directory | |
243 | handle. | |
244 | ||
245 | To specify that a parameter must be of a given type when using named | |
246 | parameters, do this: | |
247 | ||
248 | validate( | |
249 | @_, { | |
250 | foo => { type => SCALAR }, | |
251 | bar => { type => HASHREF } | |
252 | } | |
253 | ); | |
254 | ||
255 | If a parameter can be of more than one type, just use the bitwise or | |
256 | (|) operator to combine them. | |
257 | ||
258 | validate( @_, { foo => { type => GLOB | GLOBREF } ); | |
259 | ||
260 | For positional parameters, this can be specified as follows: | |
261 | ||
262 | validate_pos( @_, { type => SCALAR | ARRAYREF }, { type => CODEREF } ); | |
263 | ||
264 | Interface Validation | |
265 | ||
266 | To specify that a parameter is expected to have a certain set of | |
267 | methods, we can do the following: | |
268 | ||
269 | validate( | |
270 | @_, { | |
271 | foo => | |
272 | # just has to be able to ->bar | |
273 | { can => 'bar' } | |
274 | } | |
275 | ); | |
276 | ||
277 | ... or ... | |
278 | ||
279 | validate( | |
280 | @_, { | |
281 | foo => | |
282 | # must be able to ->bar and ->print | |
283 | { can => [qw( bar print )] } | |
284 | } | |
285 | ); | |
286 | ||
287 | Class Validation | |
288 | ||
289 | A word of warning. When constructing your external interfaces, it is | |
290 | probably better to specify what methods you expect an object to have | |
291 | rather than what class it should be of (or a child of). This will make | |
292 | your API much more flexible. | |
293 | ||
294 | With that said, if you want to validate that an incoming parameter | |
295 | belongs to a class (or child class) or classes, do: | |
296 | ||
297 | validate( | |
298 | @_, | |
299 | { foo => { isa => 'My::Frobnicator' } } | |
300 | ); | |
301 | ||
302 | ... or ... | |
303 | ||
304 | validate( | |
305 | @_, | |
306 | # must be both, not either! | |
307 | { foo => { isa => [qw( My::Frobnicator IO::Handle )] } } | |
308 | ); | |
309 | ||
310 | Regex Validation | |
311 | ||
312 | If you want to specify that a given parameter must match a specific | |
313 | regular expression, this can be done with "regex" spec key. For | |
314 | example: | |
315 | ||
316 | validate( | |
317 | @_, | |
318 | { foo => { regex => qr/^\d+$/ } } | |
319 | ); | |
320 | ||
321 | The value of the "regex" key may be either a string or a pre-compiled | |
322 | regex created via qr. | |
323 | ||
324 | If the value being checked against a regex is undefined, the regex is | |
325 | explicitly checked against the empty string ('') instead, in order to | |
326 | avoid "Use of uninitialized value" warnings. | |
327 | ||
328 | The Regexp::Common module on CPAN is an excellent source of regular | |
329 | expressions suitable for validating input. | |
330 | ||
331 | Callback Validation | |
332 | ||
333 | If none of the above are enough, it is possible to pass in one or more | |
334 | callbacks to validate the parameter. The callback will be given the | |
335 | value of the parameter as its first argument. Its second argument will | |
336 | be all the parameters, as a reference to either a hash or array. | |
337 | Callbacks are specified as hash reference. The key is an id for the | |
338 | callback (used in error messages) and the value is a subroutine | |
339 | reference, such as: | |
340 | ||
341 | validate( | |
342 | @_, | |
343 | { | |
344 | foo => { | |
345 | callbacks => { | |
346 | 'smaller than a breadbox' => sub { shift() < $breadbox }, | |
347 | 'green or blue' => sub { | |
348 | return 1 if $_[0] eq 'green' || $_[0] eq 'blue'; | |
349 | die "$_[0] is not green or blue!"; | |
350 | } | |
351 | } | |
352 | } | |
353 | } | |
354 | ); | |
355 | ||
356 | validate( | |
357 | @_, { | |
358 | foo => { | |
359 | callbacks => { | |
360 | 'bigger than baz' => sub { $_[0] > $_[1]->{baz} } | |
361 | } | |
362 | } | |
363 | } | |
364 | ); | |
365 | ||
366 | The callback should return a true value if the value is valid. If not, | |
367 | it can return false or die. If you return false, a generic error | |
368 | message will be thrown by Params::Validate. | |
369 | ||
370 | If your callback dies instead you can provide a custom error message. | |
371 | If the callback dies with a plain string, this string will be appended | |
372 | to an exception message generated by Params::Validate. If the callback | |
373 | dies with a reference (blessed or not), then this will be rethrown | |
374 | as-is by Params::Validate. | |
375 | ||
376 | Untainting | |
377 | ||
378 | If you want values untainted, set the "untaint" key in a spec hashref | |
379 | to a true value, like this: | |
380 | ||
381 | my %p = validate( | |
382 | @_, { | |
383 | foo => { type => SCALAR, untaint => 1 }, | |
384 | bar => { type => ARRAYREF } | |
385 | } | |
386 | ); | |
387 | ||
388 | This will untaint the "foo" parameter if the parameters are valid. | |
389 | ||
390 | Note that untainting is only done if all parameters are valid. Also, | |
391 | only the return values are untainted, not the original values passed | |
392 | into the validation function. | |
393 | ||
394 | Asking for untainting of a reference value will not do anything, as | |
395 | Params::Validate will only attempt to untaint the reference itself. | |
396 | ||
397 | Mandatory/Optional Revisited | |
398 | ||
399 | If you want to specify something such as type or interface, plus the | |
400 | fact that a parameter can be optional, do this: | |
401 | ||
402 | validate( | |
403 | @_, { | |
404 | foo => { type => SCALAR }, | |
405 | bar => { type => ARRAYREF, optional => 1 } | |
406 | } | |
407 | ); | |
408 | ||
409 | or this for positional parameters: | |
410 | ||
411 | validate_pos( | |
412 | @_, | |
413 | { type => SCALAR }, | |
414 | { type => ARRAYREF, optional => 1 } | |
415 | ); | |
416 | ||
417 | By default, parameters are assumed to be mandatory unless specified as | |
418 | optional. | |
419 | ||
420 | Dependencies | |
421 | ||
422 | It also possible to specify that a given optional parameter depends on | |
423 | the presence of one or more other optional parameters. | |
424 | ||
425 | validate( | |
426 | @_, { | |
427 | cc_number => { | |
428 | type => SCALAR, | |
429 | optional => 1, | |
430 | depends => [ 'cc_expiration', 'cc_holder_name' ], | |
431 | }, | |
432 | cc_expiration { type => SCALAR, optional => 1 }, | |
433 | cc_holder_name { type => SCALAR, optional => 1 }, | |
434 | } | |
435 | ); | |
436 | ||
437 | In this case, "cc_number", "cc_expiration", and "cc_holder_name" are | |
438 | all optional. However, if "cc_number" is provided, then "cc_expiration" | |
439 | and "cc_holder_name" must be provided as well. | |
440 | ||
441 | This allows you to group together sets of parameters that all must be | |
442 | provided together. | |
443 | ||
444 | The validate_pos() version of dependencies is slightly different, in | |
445 | that you can only depend on one other parameter. Also, if for example, | |
446 | the second parameter 2 depends on the fourth parameter, then it implies | |
447 | a dependency on the third parameter as well. This is because if the | |
448 | fourth parameter is required, then the user must also provide a third | |
449 | parameter so that there can be four parameters in total. | |
450 | ||
451 | Params::Validate will die if you try to depend on a parameter not | |
452 | declared as part of your parameter specification. | |
453 | ||
454 | Specifying defaults | |
455 | ||
456 | If the validate() or validate_pos() functions are called in a list | |
457 | context, they will return a hash or containing the original parameters | |
458 | plus defaults as indicated by the validation spec. | |
459 | ||
460 | If the function is not called in a list context, providing a default in | |
461 | the validation spec still indicates that the parameter is optional. | |
462 | ||
463 | The hash or array returned from the function will always be a copy of | |
464 | the original parameters, in order to leave @_ untouched for the calling | |
465 | function. | |
466 | ||
467 | Simple examples of defaults would be: | |
468 | ||
469 | my %p = validate( @_, { foo => 1, bar => { default => 99 } } ); | |
470 | ||
471 | my @p = validate_pos( @_, 1, { default => 99 } ); | |
472 | ||
473 | In scalar context, a hash reference or array reference will be | |
474 | returned, as appropriate. | |
475 | ||
476 | USAGE NOTES | |
477 | ||
478 | Validation failure | |
479 | ||
480 | By default, when validation fails Params::Validate calls | |
481 | Carp::confess(). This can be overridden by setting the on_fail option, | |
482 | which is described in the "GLOBAL" OPTIONS section. | |
483 | ||
484 | Method calls | |
485 | ||
486 | When using this module to validate the parameters passed to a method | |
487 | call, you will probably want to remove the class/object from the | |
488 | parameter list before calling validate() or validate_pos(). If your | |
489 | method expects named parameters, then this is necessary for the | |
490 | validate() function to actually work, otherwise @_ will not be usable | |
491 | as a hash, because it will first have your object (or class) followed | |
492 | by a set of keys and values. | |
493 | ||
494 | Thus the idiomatic usage of validate() in a method call will look | |
495 | something like this: | |
496 | ||
497 | sub method { | |
498 | my $self = shift; | |
499 | ||
500 | my %params = validate( | |
501 | @_, { | |
502 | foo => 1, | |
503 | bar => { type => ARRAYREF }, | |
504 | } | |
505 | ); | |
506 | } | |
507 | ||
508 | Speeding Up Validation | |
509 | ||
510 | In most cases, the validation spec will remain the same for each call | |
511 | to a subroutine. In that case, you can speed up validation by defining | |
512 | the validation spec just once, rather than on each call to the | |
513 | subroutine: | |
514 | ||
515 | my %spec = ( ... ); | |
516 | sub foo { | |
517 | my %params = validate( @_, \%spec ); | |
518 | } | |
519 | ||
520 | You can also use the state feature to do this: | |
521 | ||
522 | use feature 'state'; | |
523 | ||
524 | sub foo { | |
525 | state $spec = { ... }; | |
526 | my %params = validate( @_, $spec ); | |
527 | } | |
528 | ||
529 | "GLOBAL" OPTIONS | |
530 | ||
531 | Because the API for the validate() and validate_pos() functions does | |
532 | not make it possible to specify any options other than the validation | |
533 | spec, it is possible to set some options as pseudo-'globals'. These | |
534 | allow you to specify such things as whether or not the validation of | |
535 | named parameters should be case sensitive, for one example. | |
536 | ||
537 | These options are called pseudo-'globals' because these settings are | |
538 | only applied to calls originating from the package that set the | |
539 | options. | |
540 | ||
541 | In other words, if I am in package Foo and I call validation_options(), | |
542 | those options are only in effect when I call validate() from package | |
543 | Foo. | |
544 | ||
545 | While this is quite different from how most other modules operate, I | |
546 | feel that this is necessary in able to make it possible for one | |
547 | module/application to use Params::Validate while still using other | |
548 | modules that also use Params::Validate, perhaps with different options | |
549 | set. | |
550 | ||
551 | The downside to this is that if you are writing an app with a standard | |
552 | calling style for all functions, and your app has ten modules, each | |
553 | module must include a call to validation_options(). You could of course | |
554 | write a module that all your modules use which uses various trickery to | |
555 | do this when imported. | |
556 | ||
557 | Options | |
558 | ||
559 | * normalize_keys => $callback | |
560 | ||
561 | This option is only relevant when dealing with named parameters. | |
562 | ||
563 | This callback will be used to transform the hash keys of both the | |
564 | parameters and the parameter spec when validate() or validate_with() | |
565 | are called. | |
566 | ||
567 | Any alterations made by this callback will be reflected in the | |
568 | parameter hash that is returned by the validation function. For | |
569 | example: | |
570 | ||
571 | sub foo { | |
572 | return validate_with( | |
573 | params => \@_, | |
574 | spec => { foo => { type => SCALAR } }, | |
575 | normalize_keys => | |
576 | sub { my $k = shift; $k =~ s/^-//; return uc $k }, | |
577 | ); | |
578 | ||
579 | } | |
580 | ||
581 | %p = foo( foo => 20 ); | |
582 | ||
583 | # $p{FOO} is now 20 | |
584 | ||
585 | %p = foo( -fOo => 50 ); | |
586 | ||
587 | # $p{FOO} is now 50 | |
588 | ||
589 | The callback must return a defined value. | |
590 | ||
591 | If a callback is given then the deprecated "ignore_case" and | |
592 | "strip_leading" options are ignored. | |
593 | ||
594 | * allow_extra => $boolean | |
595 | ||
596 | If true, then the validation routine will allow extra parameters not | |
597 | named in the validation specification. In the case of positional | |
598 | parameters, this allows an unlimited number of maximum parameters | |
599 | (though a minimum may still be set). Defaults to false. | |
600 | ||
601 | * on_fail => $callback | |
602 | ||
603 | If given, this callback will be called whenever a validation check | |
604 | fails. It will be called with a single parameter, which will be a | |
605 | string describing the failure. This is useful if you wish to have | |
606 | this module throw exceptions as objects rather than as strings, for | |
607 | example. | |
608 | ||
609 | This callback is expected to die() internally. If it does not, the | |
610 | validation will proceed onwards, with unpredictable results. | |
611 | ||
612 | The default is to simply use the Carp module's confess() function. | |
613 | ||
614 | * stack_skip => $number | |
615 | ||
616 | This tells Params::Validate how many stack frames to skip when | |
617 | finding a subroutine name to use in error messages. By default, it | |
618 | looks one frame back, at the immediate caller to validate() or | |
619 | validate_pos(). If this option is set, then the given number of | |
620 | frames are skipped instead. | |
621 | ||
622 | * ignore_case => $boolean | |
623 | ||
624 | DEPRECATED | |
625 | ||
626 | This is only relevant when dealing with named parameters. If it is | |
627 | true, then the validation code will ignore the case of parameter | |
628 | names. Defaults to false. | |
629 | ||
630 | * strip_leading => $characters | |
631 | ||
632 | DEPRECATED | |
633 | ||
634 | This too is only relevant when dealing with named parameters. If this | |
635 | is given then any parameters starting with these characters will be | |
636 | considered equivalent to parameters without them entirely. For | |
637 | example, if this is specified as '-', then -foo and foo would be | |
638 | considered identical. | |
639 | ||
640 | PER-INVOCATION OPTIONS | |
641 | ||
642 | The validate_with() function can be used to set the options listed | |
643 | above on a per-invocation basis. For example: | |
644 | ||
645 | my %p = validate_with( | |
646 | params => \@_, | |
647 | spec => { | |
648 | foo => { type => SCALAR }, | |
649 | bar => { default => 10 } | |
650 | }, | |
651 | allow_extra => 1, | |
652 | ); | |
653 | ||
654 | In addition to the options listed above, it is also possible to set the | |
655 | option "called", which should be a string. This string will be used in | |
656 | any error messages caused by a failure to meet the validation spec. | |
657 | ||
658 | This subroutine will validate named parameters as a hash if the "spec" | |
659 | parameter is a hash reference. If it is an array reference, the | |
660 | parameters are assumed to be positional. | |
661 | ||
662 | my %p = validate_with( | |
663 | params => \@_, | |
664 | spec => { | |
665 | foo => { type => SCALAR }, | |
666 | bar => { default => 10 } | |
667 | }, | |
668 | allow_extra => 1, | |
669 | called => 'The Quux::Baz class constructor', | |
670 | ); | |
671 | ||
672 | my @p = validate_with( | |
673 | params => \@_, | |
674 | spec => [ | |
675 | { type => SCALAR }, | |
676 | { default => 10 } | |
677 | ], | |
678 | allow_extra => 1, | |
679 | called => 'The Quux::Baz class constructor', | |
680 | ); | |
681 | ||
682 | DISABLING VALIDATION | |
683 | ||
684 | If the environment variable PERL_NO_VALIDATION is set to something | |
685 | true, then validation is turned off. This may be useful if you only | |
686 | want to use this module during development but don't want the speed hit | |
687 | during production. | |
688 | ||
689 | The only error that will be caught will be when an odd number of | |
690 | parameters are passed into a function/method that expects a hash. | |
691 | ||
692 | If you want to selectively turn validation on and off at runtime, you | |
693 | can directly set the $Params::Validate::NO_VALIDATION global variable. | |
694 | It is strongly recommended that you localize any changes to this | |
695 | variable, because other modules you are using may expect validation to | |
696 | be on when they execute. For example: | |
697 | ||
698 | { | |
699 | local $Params::Validate::NO_VALIDATION = 1; | |
700 | ||
701 | # no error | |
702 | foo( bar => 2 ); | |
703 | } | |
704 | ||
705 | # error | |
706 | foo( bar => 2 ); | |
707 | ||
708 | sub foo { | |
709 | my %p = validate( @_, { foo => 1 } ); | |
710 | ...; | |
711 | } | |
712 | ||
713 | But if you want to shoot yourself in the foot and just turn it off, go | |
714 | ahead! | |
715 | ||
716 | TAINT MODE | |
717 | ||
718 | The XS implementation of this module has some problems Under taint mode | |
719 | with version of Perl before 5.14. If validation fails, then instead of | |
720 | getting the expected error message you'll get a message like "Insecure | |
721 | dependency in eval_sv". This can be worked around by either untainting | |
722 | the arguments yourself, using the pure Perl implementation, or | |
723 | upgrading your Perl. | |
724 | ||
725 | LIMITATIONS | |
726 | ||
727 | Right now there is no way (short of a callback) to specify that | |
728 | something must be of one of a list of classes, or that it must possess | |
729 | one of a list of methods. If this is desired, it can be added in the | |
730 | future. | |
731 | ||
732 | Ideally, there would be only one validation function. If someone | |
733 | figures out how to do this, please let me know. | |
734 | ||
735 | SUPPORT | |
736 | ||
737 | Please submit bugs and patches to the CPAN RT system at | |
738 | http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Params%3A%3AValidate or | |
739 | via email at bug-params-validate@rt.cpan.org. | |
740 | ||
741 | Support questions can be sent to Dave at autarch@urth.org. | |
742 | ||
743 | DONATIONS | |
744 | ||
745 | If you'd like to thank me for the work I've done on this module, please | |
746 | consider making a "donation" to me via PayPal. I spend a lot of free | |
747 | time creating free software, and would appreciate any support you'd | |
748 | care to offer. | |
749 | ||
750 | Please note that I am not suggesting that you must do this in order for | |
751 | me to continue working on this particular software. I will continue to | |
752 | do so, inasmuch as I have in the past, for as long as it interests me. | |
753 | ||
754 | Similarly, a donation made in this way will probably not make me work | |
755 | on this software much more, unless I get so many donations that I can | |
756 | consider working on free software full time, which seems unlikely at | |
757 | best. | |
758 | ||
759 | To donate, log into PayPal and send money to autarch@urth.org or use | |
760 | the button on this page: http://www.urth.org/~autarch/fs-donation.html | |
761 | ||
762 | AUTHORS | |
763 | ||
764 | * Dave Rolsky <autarch@urth.org> | |
765 | ||
766 | * Ilya Martynov <ilya@martynov.org> | |
767 | ||
768 | CONTRIBUTORS | |
769 | ||
770 | * J.R. Mash <jmash.code@gmail.com> | |
771 | ||
772 | * Olivier Mengué <dolmen@cpan.org> | |
773 | ||
774 | COPYRIGHT AND LICENSE | |
775 | ||
776 | This software is Copyright (c) 2001 - 2015 by Dave Rolsky and Ilya | |
777 | Martynov. | |
778 | ||
779 | This is free software, licensed under: | |
780 | ||
781 | The Artistic License 2.0 (GPL Compatible) | |
782 |
0 | do{ my $x = [ | |
1 | { | |
2 | 'ARGV' => [] | |
3 | }, | |
4 | {}, | |
5 | { | |
6 | 'verbose' => undef, | |
7 | 'dist_suffix' => undef, | |
8 | 'PL_files' => undef, | |
9 | 'pollute' => undef, | |
10 | 'metafile2' => 'META.json', | |
11 | 'bindoc_dirs' => [ | |
12 | 'blib/script' | |
13 | ], | |
14 | 'conflicts' => {}, | |
15 | 'recommends' => {}, | |
16 | 'scripts' => undef, | |
17 | 'pod_files' => undef, | |
18 | 'config_dir' => '_build', | |
19 | 'dist_version' => 42, | |
20 | 'sign' => undef, | |
21 | 'recurse_into' => [], | |
22 | 'build_bat' => 0, | |
23 | 'extra_linker_flags' => [], | |
24 | 'build_class' => 'Module::Build', | |
25 | 'prereq_action_types' => [ | |
26 | 'requires', | |
27 | 'build_requires', | |
28 | 'conflicts', | |
29 | 'recommends' | |
30 | ], | |
31 | 'base_dir' => '/home/autarch/projects/Params-Validate', | |
32 | 'allow_mb_mismatch' => 0, | |
33 | 'xs_files' => undef, | |
34 | 'destdir' => undef, | |
35 | 'metafile' => 'META.yml', | |
36 | 'mb_version' => '0.38', | |
37 | 'use_tap_harness' => 0, | |
38 | 'test_file_exts' => [ | |
39 | '.t' | |
40 | ], | |
41 | 'dist_name' => 'Params-Validate', | |
42 | 'has_config_data' => undef, | |
43 | 'install_base' => undef, | |
44 | 'module_name' => 'Params::Validate', | |
45 | '_have_c_compiler' => 1, | |
46 | 'recursive_test_files' => 1, | |
47 | 'libdoc_dirs' => [ | |
48 | 'blib/lib', | |
49 | 'blib/arch' | |
50 | ], | |
51 | 'perl' => '/home/autarch/perl5/perlbrew/perls/perl-5.14.2/bin/perl', | |
52 | 'dist_author' => undef, | |
53 | 'bundle_inc' => [], | |
54 | 'use_rcfile' => 1, | |
55 | 'configure_requires' => {}, | |
56 | 'test_files' => undef, | |
57 | 'dist_abstract' => 'Whatever', | |
58 | 'create_readme' => undef, | |
59 | 'prefix_relpaths' => {}, | |
60 | 'share_dir' => undef, | |
61 | 'debug' => undef, | |
62 | 'meta_merge' => {}, | |
63 | 'get_options' => {}, | |
64 | 'dist_version_from' => undef, | |
65 | '_added_to_INC' => [], | |
66 | 'auto_configure_requires' => 1, | |
67 | 'create_license' => undef, | |
68 | 'debugger' => undef, | |
69 | 'html_css' => '', | |
70 | 'cpan_client' => 'cpan', | |
71 | 'mymetafile2' => 'MYMETA.json', | |
72 | 'bundle_inc_preload' => [], | |
73 | 'build_elements' => [ | |
74 | 'PL', | |
75 | 'support', | |
76 | 'pm', | |
77 | 'xs', | |
78 | 'share_dir', | |
79 | 'pod', | |
80 | 'script' | |
81 | ], | |
82 | 'release_status' => 'stable', | |
83 | 'needs_compiler' => 1, | |
84 | 'orig_dir' => '/home/autarch/projects/Params-Validate', | |
85 | 'include_dirs' => [], | |
86 | 'installdirs' => 'site', | |
87 | 'mymetafile' => 'MYMETA.yml', | |
88 | 'create_makefile_pl' => undef, | |
89 | 'dynamic_config' => 1, | |
90 | 'magic_number' => undef, | |
91 | 'install_sets' => {}, | |
92 | 'tap_harness_args' => {}, | |
93 | 'install_base_relpaths' => {}, | |
94 | 'create_packlist' => 1, | |
95 | 'meta_add' => {}, | |
96 | 'requires' => {}, | |
97 | 'install_path' => {}, | |
98 | 'pm_files' => undef, | |
99 | 'quiet' => undef, | |
100 | 'script_files' => undef, | |
101 | 'extra_compiler_flags' => [ | |
102 | '-Wall' | |
103 | ], | |
104 | 'build_script' => 'Build', | |
105 | 'original_prefix' => {}, | |
106 | 'c_source' => 'c', | |
107 | 'program_name' => undef, | |
108 | 'autosplit' => undef, | |
109 | 'license' => 'artistic_2', | |
110 | 'build_requires' => { | |
111 | 'ExtUtils::CBuilder' => 0 | |
112 | }, | |
113 | 'config' => undef, | |
114 | 'blib' => 'blib', | |
115 | 'prefix' => undef | |
116 | } | |
117 | ]; | |
118 | $x; }⏎ |
0 | do{ my $x = { | |
1 | 'blib/arch/auto/Params/Validate/XS/XS.bs' => 1, | |
2 | 'lib/Params/Validate/XS.c' => 1, | |
3 | 'blib/arch/auto/Params/Validate/XS/XS.so' => 1, | |
4 | 'lib/Params/Validate/XS.o' => 1, | |
5 | 'blib' => 1 | |
6 | }; | |
7 | $x; }⏎ |
0 | do{ my $x = { | |
1 | 'build_requires' => { | |
2 | 'ExtUtils::CBuilder' => 0 | |
3 | }, | |
4 | 'conflicts' => {}, | |
5 | 'requires' => {}, | |
6 | 'recommends' => {} | |
7 | }; | |
8 | $x; }⏎ |
0 | requires "Attribute::Handlers" => "0.79"; | |
1 | requires "Carp" => "0"; | |
2 | requires "Exporter" => "0"; | |
3 | requires "Module::Implementation" => "0"; | |
4 | requires "Scalar::Util" => "1.10"; | |
5 | requires "XSLoader" => "0"; | |
6 | requires "attributes" => "0"; | |
7 | requires "perl" => "5.008001"; | |
8 | requires "strict" => "0"; | |
9 | requires "vars" => "0"; | |
10 | requires "warnings" => "0"; | |
11 | ||
12 | on 'build' => sub { | |
13 | requires "Module::Build" => "0.28"; | |
14 | }; | |
15 | ||
16 | on 'test' => sub { | |
17 | requires "Devel::Peek" => "0"; | |
18 | requires "ExtUtils::MakeMaker" => "0"; | |
19 | requires "File::Spec" => "0"; | |
20 | requires "File::Temp" => "0"; | |
21 | requires "IO::Handle" => "0"; | |
22 | requires "IPC::Open3" => "0"; | |
23 | requires "Test::Fatal" => "0"; | |
24 | requires "Test::More" => "0.96"; | |
25 | requires "Test::Requires" => "0"; | |
26 | requires "Tie::Array" => "0"; | |
27 | requires "Tie::Hash" => "0"; | |
28 | requires "base" => "0"; | |
29 | requires "lib" => "0"; | |
30 | requires "overload" => "0"; | |
31 | }; | |
32 | ||
33 | on 'test' => sub { | |
34 | recommends "CPAN::Meta" => "2.120900"; | |
35 | }; | |
36 | ||
37 | on 'configure' => sub { | |
38 | requires "Module::Build" => "0.28"; | |
39 | }; | |
40 | ||
41 | on 'develop' => sub { | |
42 | requires "Perl::Critic" => "1.123"; | |
43 | requires "Perl::Tidy" => "20140711"; | |
44 | requires "Pod::Coverage::TrustPod" => "0"; | |
45 | requires "Readonly" => "1.03"; | |
46 | requires "Scalar::Util" => "1.20"; | |
47 | requires "Test::CPAN::Changes" => "0.19"; | |
48 | requires "Test::EOL" => "0"; | |
49 | requires "Test::LeakTrace" => "0.15"; | |
50 | requires "Test::More" => "0.96"; | |
51 | requires "Test::NoTabs" => "0"; | |
52 | requires "Test::Pod" => "1.41"; | |
53 | requires "Test::Pod::Coverage" => "1.08"; | |
54 | requires "Test::Spelling" => "0.12"; | |
55 | requires "Test::Synopsis" => "0"; | |
56 | requires "Test::Taint" => "0.02"; | |
57 | requires "Test::Version" => "1"; | |
58 | }; |
2 | 2 | author = Ilya Martynov <ilya@martynov.org> |
3 | 3 | license = Artistic_2_0 |
4 | 4 | copyright_holder = Dave Rolsky and Ilya Martynov |
5 | copyright_year = 2001 | |
5 | 6 | |
6 | version = 1.13 | |
7 | [@DROLSKY] | |
8 | dist = Params-Validate | |
9 | next_release_width = 7 | |
10 | pod_coverage_trustme = Params::Validate => qr/^(?:UNKNOWN|set_options|validate(?:_pos|_with)?|validation_options)$/ | |
11 | pod_coverage_skip = Params::Validate::Constants | |
12 | pod_coverage_skip = Params::Validate::PP | |
13 | pod_coverage_skip = Params::Validate::XS | |
14 | pod_coverage_skip = Params::ValidatePP | |
15 | pod_coverage_skip = Params::ValidateXS | |
16 | prereqs_skip = ClassCan | |
17 | prereqs_skip = ClassISA | |
18 | prereqs_skip = Tie::StdArray | |
19 | prereqs_skip = Tie::StdHash | |
20 | stopwords = API | |
21 | stopwords = CPAN | |
22 | stopwords = GLOBREF | |
23 | stopwords = OO | |
24 | stopwords = PayPal | |
25 | stopwords = SCALARREF | |
26 | stopwords = ValidatePos | |
27 | stopwords = baz | |
28 | stopwords = onwards | |
29 | stopwords = pre | |
30 | stopwords = runtime | |
31 | -remove = MakeMaker | |
32 | -remove = Test::TidyAll | |
7 | 33 | |
8 | [NextRelease] | |
9 | format = %-7v %{yyyy-MM-dd}d | |
10 | ||
11 | [@Filter] | |
12 | -bundle = @Basic | |
13 | -remove = MakeMaker | |
14 | ||
15 | [PruneFiles] | |
16 | filenames = Build.PL | |
34 | [Prereqs / DevelopRequires] | |
35 | Readonly = 1.03 | |
36 | Scalar::Util = 1.20 | |
37 | Test::LeakTrace = 0.15 | |
38 | Test::More = 0.96 | |
39 | Test::Taint = 0.02 | |
17 | 40 | |
18 | 41 | ; authordep Dist::Zilla::Plugin::ModuleBuild::XSOrPP |
19 | 42 | [=inc::MyModuleBuild] |
20 | 43 | |
21 | 44 | [PurePerlTests] |
22 | 45 | env_var = PV_TEST_PERL |
23 | ||
24 | [InstallGuide] | |
25 | [MetaJSON] | |
26 | ||
27 | [MetaResources] | |
28 | bugtracker.web = http://rt.cpan.org/NoAuth/Bugs.html?Dist=Params-Validate | |
29 | bugtracker.mailto = bug-params-validate@rt.cpan.org | |
30 | repository.url = git://git.urth.org/Params-Validate.git | |
31 | repository.web = http://git.urth.org/Params-Validate.git | |
32 | repository.type = git | |
33 | ||
34 | [SurgicalPodWeaver] | |
35 | ||
36 | [PkgVersion] | |
37 | ||
38 | [EOLTests] | |
39 | [PodSyntaxTests] | |
40 | [Test::CPAN::Changes] | |
41 | [Test::NoTabs] | |
42 | [Test::Pod::LinkCheck] | |
43 | [Test::Pod::No404s] | |
44 | ||
45 | [AutoPrereqs] | |
46 | skip = ClassCan | |
47 | skip = ClassISA | |
48 | skip = Tie::StdArray | |
49 | skip = Tie::StdHash | |
50 | ||
51 | [CheckPrereqsIndexed] | |
52 | ||
53 | [@Git] |
0 | 0 | package Attribute::Params::Validate; |
1 | $Attribute::Params::Validate::VERSION = '1.13'; | |
1 | ||
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | ||
5 | our $VERSION = '1.18'; | |
4 | 6 | |
5 | 7 | use attributes; |
6 | 8 | |
97 | 99 | |
98 | 100 | =head1 VERSION |
99 | 101 | |
100 | version 1.13 | |
102 | version 1.18 | |
101 | 103 | |
102 | 104 | =head1 SYNOPSIS |
103 | 105 | |
107 | 109 | # foo is mandatory, bar is optional |
108 | 110 | sub foo : Validate( foo => 1, bar => 0 ) |
109 | 111 | { |
110 | ... | |
112 | # insert code here | |
111 | 113 | } |
112 | 114 | |
113 | 115 | # takes positional params |
114 | 116 | # first two are mandatory, third is optional |
115 | 117 | sub bar : ValidatePos( 1, 1, 0 ) |
116 | 118 | { |
117 | ... | |
119 | # insert code here | |
118 | 120 | } |
119 | 121 | |
120 | 122 | # for some reason Perl insists that the entire attribute be on one line |
121 | 123 | sub foo2 : Validate( foo => { type => ARRAYREF }, bar => { can => [ 'print', 'flush', 'frobnicate' ] }, baz => { type => SCALAR, callbacks => { 'numbers only' => sub { shift() =~ /^\d+$/ }, 'less than 90' => sub { shift() < 90 } } } ) |
122 | 124 | { |
123 | ... | |
125 | # insert code here | |
124 | 126 | } |
125 | 127 | |
126 | 128 | # note that this is marked as a method. This is very important! |
127 | 129 | sub baz : Validate( foo => { type => ARRAYREF }, bar => { isa => 'Frobnicator' } ) method |
128 | 130 | { |
129 | ... | |
131 | # insert code here | |
130 | 132 | } |
131 | 133 | |
132 | 134 | =head1 DESCRIPTION |
196 | 198 | |
197 | 199 | =head1 COPYRIGHT AND LICENSE |
198 | 200 | |
199 | This software is Copyright (c) 2014 by Dave Rolsky and Ilya Martynov. | |
201 | This software is Copyright (c) 2001 - 2015 by Dave Rolsky and Ilya Martynov. | |
200 | 202 | |
201 | 203 | This is free software, licensed under: |
202 | 204 |
0 | 0 | package Params::Validate::Constants; |
1 | $Params::Validate::Constants::VERSION = '1.13'; | |
1 | ||
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | ||
5 | our $VERSION = '1.18'; | |
4 | 6 | |
5 | 7 | our @ISA = 'Exporter'; |
6 | 8 |
0 | 0 | package Params::Validate::PP; |
1 | $Params::Validate::PP::VERSION = '1.13'; | |
1 | ||
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | ||
5 | our $VERSION = '1.18'; | |
4 | 6 | |
5 | 7 | use Params::Validate::Constants; |
6 | 8 | use Scalar::Util 1.10 (); |
42 | 44 | |
43 | 45 | # if the spec is bigger that's where we can start adding |
44 | 46 | # defaults |
45 | for ( my $x = $#p + 1 ; $x <= $#specs ; $x++ ) { | |
47 | for ( my $x = $#p + 1; $x <= $#specs; $x++ ) { | |
46 | 48 | $p[$x] = $specs[$x]->{default} |
47 | 49 | if ref $specs[$x] && exists $specs[$x]->{default}; |
48 | 50 | } |
345 | 347 | if (@missing) { |
346 | 348 | my $called = _get_called(); |
347 | 349 | |
348 | my $missing = join ', ', map { "'$_'" } @missing; | |
350 | my $missing = join ', ', map {"'$_'"} @missing; | |
349 | 351 | $options->{on_fail}->( "Mandatory parameter" |
350 | 352 | . ( @missing > 1 ? 's' : '' ) |
351 | 353 | . " $missing missing in call to $called\n" ); |
494 | 496 | foreach ( ref $spec->{isa} ? @{ $spec->{isa} } : $spec->{isa} ) { |
495 | 497 | unless ( |
496 | 498 | do { |
497 | local $@; | |
499 | local $@ = q{}; | |
498 | 500 | eval { $value->isa($_) }; |
499 | 501 | } |
500 | 502 | ) { |
501 | 503 | my $is = ref $value ? ref $value : 'plain scalar'; |
502 | my $article1 = $_ =~ /^[aeiou]/i ? 'an' : 'a'; | |
504 | my $article1 = $_ =~ /^[aeiou]/i ? 'an' : 'a'; | |
503 | 505 | my $article2 = $is =~ /^[aeiou]/i ? 'an' : 'a'; |
504 | 506 | |
505 | 507 | my $called = _get_called(1); |
515 | 517 | foreach ( ref $spec->{can} ? @{ $spec->{can} } : $spec->{can} ) { |
516 | 518 | unless ( |
517 | 519 | do { |
518 | local $@; | |
520 | local $@ = q{}; | |
519 | 521 | eval { $value->can($_) }; |
520 | 522 | } |
521 | 523 | ) { |
545 | 547 | ); |
546 | 548 | } |
547 | 549 | |
548 | unless ( $spec->{callbacks}{$_}->( $value, $params ) ) { | |
550 | my $ok; | |
551 | my $e = do { | |
552 | local $@ = q{}; | |
553 | local $SIG{__DIE__} = undef; | |
554 | $ok = eval { $spec->{callbacks}{$_}->( $value, $params ) }; | |
555 | $@; | |
556 | }; | |
557 | ||
558 | if ( !$ok ) { | |
549 | 559 | my $called = _get_called(1); |
550 | 560 | |
551 | $options->{on_fail} | |
552 | ->("$id to $called did not pass the '$_' callback\n"); | |
561 | my $msg; | |
562 | if ( ref $e ) { | |
563 | $msg = $e; | |
564 | } | |
565 | else { | |
566 | $msg = "$id to $called did not pass the '$_' callback"; | |
567 | $msg .= ": $e" if length $e; | |
568 | $msg .= "\n"; | |
569 | } | |
570 | $options->{on_fail}->($msg); | |
553 | 571 | } |
554 | 572 | } |
555 | 573 | } |
0 | 0 | package Params::Validate::XS; |
1 | $Params::Validate::XS::VERSION = '1.13'; | |
1 | ||
2 | 2 | use strict; |
3 | 3 | use warnings; |
4 | ||
5 | our $VERSION = '1.18'; | |
4 | 6 | |
5 | 7 | use Carp; |
6 | 8 |
2 | 2 | #include "EXTERN.h" |
3 | 3 | #include "perl.h" |
4 | 4 | #include "XSUB.h" |
5 | #define NEED_eval_pv | |
6 | #define NEED_sv_2pv_flags | |
7 | 5 | #include "ppport.h" |
8 | 6 | |
9 | 7 | #ifdef __GNUC__ |
74 | 72 | } STMT_END |
75 | 73 | |
76 | 74 | |
75 | static SV *module; | |
76 | void peek(SV *thing) | |
77 | { | |
78 | if (NULL == module) { | |
79 | module = newSVpv("Devel::Peek", 0); | |
80 | load_module(PERL_LOADMOD_NOIMPORT, module, NULL); | |
81 | } | |
82 | ||
83 | { | |
84 | dSP; | |
85 | ENTER; | |
86 | SAVETMPS; | |
87 | ||
88 | PUSHMARK(SP); | |
89 | XPUSHs(thing); | |
90 | PUTBACK; | |
91 | ||
92 | (void)call_pv("Devel::Peek::Dump", G_VOID); | |
93 | ||
94 | SPAGAIN; | |
95 | ||
96 | PUTBACK; | |
97 | FREETMPS; | |
98 | LEAVE; | |
99 | } | |
100 | } | |
101 | ||
77 | 102 | INLINE static bool |
78 | 103 | no_validation() { |
79 | 104 | SV* no_v; |
84 | 109 | |
85 | 110 | return SvTRUE(no_v); |
86 | 111 | } |
87 | ||
88 | 112 | |
89 | 113 | /* return type string that corresponds to typemask */ |
90 | 114 | INLINE static SV* |
137 | 161 | |
138 | 162 | return buffer; |
139 | 163 | } |
140 | ||
141 | 164 | |
142 | 165 | /* compute numberic datatype for variable */ |
143 | 166 | INLINE static IV |
201 | 224 | return UNKNOWN; |
202 | 225 | } |
203 | 226 | |
204 | ||
205 | 227 | /* get an article for given string */ |
206 | 228 | INLINE static const char* |
207 | 229 | article(SV* string) { |
223 | 245 | return "a"; |
224 | 246 | } |
225 | 247 | |
226 | ||
227 | 248 | /* raises exception either using user-defined callback or using |
228 | 249 | built-in method */ |
229 | 250 | static void |
239 | 260 | on_fail = NULL; |
240 | 261 | } |
241 | 262 | |
242 | /* use user defined callback if available */ | |
243 | if (on_fail) { | |
263 | { | |
244 | 264 | dSP; |
265 | ENTER; | |
266 | SAVETMPS; | |
245 | 267 | PUSHMARK(SP); |
246 | XPUSHs(message); | |
268 | mXPUSHs(message); | |
247 | 269 | PUTBACK; |
248 | call_sv(on_fail, G_DISCARD); | |
249 | } | |
250 | else { | |
251 | /* by default resort to Carp::confess for error reporting */ | |
252 | dSP; | |
253 | PUSHMARK(SP); | |
254 | XPUSHs(message); | |
270 | ||
271 | /* use user defined callback if available */ | |
272 | if (on_fail) { | |
273 | call_sv(on_fail, G_DISCARD); | |
274 | } | |
275 | else { | |
276 | /* by default resort to Carp::confess for error reporting */ | |
277 | call_pv("Carp::confess", G_DISCARD); | |
278 | } | |
279 | ||
280 | /* We shouldn't get here if the thing we just called dies, but it | |
281 | doesn't hurt to be careful. */ | |
282 | SPAGAIN; | |
255 | 283 | PUTBACK; |
256 | call_pv("Carp::confess", G_DISCARD); | |
284 | FREETMPS; | |
285 | LEAVE; | |
257 | 286 | } |
258 | 287 | |
259 | 288 | return; |
261 | 290 | |
262 | 291 | /* get called subroutine fully qualified name */ |
263 | 292 | static SV* |
264 | get_called(HV* options) { | |
293 | get_caller(HV* options) { | |
265 | 294 | SV** temp; |
266 | 295 | |
267 | 296 | if ((temp = hv_fetch(options, "called", 6, 0))) { |
268 | 297 | SvGETMAGIC(*temp); |
298 | SvREFCNT_inc(*temp); | |
269 | 299 | return *temp; |
270 | 300 | } |
271 | 301 | else { |
320 | 350 | if (SvTYPE(caller) == SVt_NULL) { |
321 | 351 | sv_setpv(caller, "(unknown"); |
322 | 352 | } |
353 | ||
354 | /* This will be decremented by the code that asked for this value, but | |
355 | we need to do this here because the return value of caller() is | |
356 | mortal and has a refcnt of 1. */ | |
357 | SvREFCNT_inc(caller); | |
323 | 358 | #endif |
324 | 359 | |
325 | 360 | return caller; |
326 | 361 | } |
327 | 362 | } |
328 | ||
329 | 363 | |
330 | 364 | /* $value->isa alike validation */ |
331 | 365 | static IV |
332 | 366 | validate_isa(SV* value, SV* package, SV* id, HV* options) { |
333 | SV* buffer; | |
334 | 367 | IV ok = 1; |
335 | 368 | |
336 | 369 | if (! value) { |
374 | 407 | } |
375 | 408 | |
376 | 409 | if (! ok) { |
377 | buffer = sv_2mortal(newSVsv(id)); | |
410 | SV *caller = get_caller(options); | |
411 | SV* buffer = newSVsv(id); | |
378 | 412 | sv_catpv(buffer, " to "); |
379 | sv_catsv(buffer, get_called(options)); | |
413 | sv_catsv(buffer, caller); | |
414 | SvREFCNT_dec(caller); | |
380 | 415 | sv_catpv(buffer, " was not "); |
381 | 416 | sv_catpv(buffer, article(package)); |
382 | 417 | sv_catpv(buffer, " '"); |
397 | 432 | return 1; |
398 | 433 | } |
399 | 434 | |
400 | ||
401 | 435 | static IV |
402 | 436 | validate_can(SV* value, SV* method, SV* id, HV* options) { |
403 | 437 | IV ok = 1; |
443 | 477 | } |
444 | 478 | |
445 | 479 | if (! ok) { |
446 | SV* buffer; | |
447 | ||
448 | buffer = sv_2mortal(newSVsv(id)); | |
480 | SV* buffer = newSVsv(id); | |
481 | SV *caller = get_caller(options); | |
449 | 482 | sv_catpv(buffer, " to "); |
450 | sv_catsv(buffer, get_called(options)); | |
483 | sv_catsv(buffer, caller); | |
484 | SvREFCNT_dec(caller); | |
451 | 485 | sv_catpv(buffer, " does not have the method: '"); |
452 | 486 | sv_catsv(buffer, method); |
453 | 487 | sv_catpv(buffer, "'\n"); |
495 | 529 | if ( ! ( SvOK(*temp) |
496 | 530 | && looks_like_number(*temp) |
497 | 531 | && SvIV(*temp) > 0 ) ) { |
498 | SV* buffer; | |
499 | ||
500 | buffer = sv_2mortal(newSVsv(id)); | |
532 | ||
533 | SV* buffer = newSVsv(id); | |
501 | 534 | sv_catpv( buffer, " has a type specification which is not a number. It is "); |
502 | 535 | if ( SvOK(*temp) ) { |
503 | 536 | sv_catpv( buffer, "a string - " ); |
514 | 547 | SvGETMAGIC(*temp); |
515 | 548 | type = get_type(value); |
516 | 549 | if (! (type & SvIV(*temp))) { |
517 | SV* buffer; | |
550 | SV* buffer = newSVsv(id); | |
551 | SV *caller = get_caller(options); | |
518 | 552 | SV* is; |
519 | 553 | SV* allowed; |
520 | 554 | |
521 | buffer = sv_2mortal(newSVsv(id)); | |
522 | 555 | sv_catpv(buffer, " to "); |
523 | sv_catsv(buffer, get_called(options)); | |
556 | sv_catsv(buffer, caller); | |
557 | SvREFCNT_dec(caller); | |
524 | 558 | sv_catpv(buffer, " was "); |
525 | 559 | is = typemask_to_string(type); |
526 | 560 | allowed = typemask_to_string(SvIV(*temp)); |
530 | 564 | sv_catpv(buffer, "', which is not one of the allowed types: "); |
531 | 565 | sv_catsv(buffer, allowed); |
532 | 566 | sv_catpv(buffer, "\n"); |
567 | ||
533 | 568 | validation_failure(buffer, options); |
534 | 569 | } |
535 | 570 | } |
592 | 627 | |
593 | 628 | /* let callbacks to do their tests */ |
594 | 629 | if ((temp = hv_fetch(spec, "callbacks", 9, 0))) { |
630 | HE* he; | |
631 | ||
595 | 632 | SvGETMAGIC(*temp); |
596 | if (SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVHV) { | |
597 | HE* he; | |
598 | ||
599 | hv_iterinit((HV*) SvRV(*temp)); | |
600 | while ((he = hv_iternext((HV*) SvRV(*temp)))) { | |
601 | if (SvROK(HeVAL(he)) && SvTYPE(SvRV(HeVAL(he))) == SVt_PVCV) { | |
602 | dSP; | |
603 | ||
604 | SV* ret; | |
605 | IV ok; | |
606 | IV count; | |
607 | ||
608 | ENTER; | |
609 | SAVETMPS; | |
610 | ||
611 | PUSHMARK(SP); | |
612 | EXTEND(SP, 2); | |
613 | PUSHs(value); | |
614 | PUSHs(sv_2mortal(newRV_inc(params))); | |
615 | PUTBACK; | |
616 | ||
617 | count = call_sv(SvRV(HeVAL(he)), G_SCALAR); | |
618 | ||
619 | SPAGAIN; | |
620 | ||
621 | if (! count) | |
622 | croak("Validation callback did not return anything"); | |
623 | ||
624 | ret = POPs; | |
625 | SvGETMAGIC(ret); | |
626 | ok = SvTRUE(ret); | |
627 | ||
628 | PUTBACK; | |
629 | FREETMPS; | |
630 | LEAVE; | |
631 | ||
632 | if (! ok) { | |
633 | SV* buffer; | |
634 | ||
635 | buffer = sv_2mortal(newSVsv(id)); | |
633 | if (!(SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVHV)) { | |
634 | SV* buffer = newSVpv("'callbacks' validation parameter for '", 0); | |
635 | SV *caller = get_caller(options); | |
636 | ||
637 | sv_catsv(buffer, caller); | |
638 | SvREFCNT_dec(caller); | |
639 | sv_catpv(buffer, " must be a hash reference\n"); | |
640 | validation_failure(buffer, options); | |
641 | } | |
642 | ||
643 | hv_iterinit((HV*) SvRV(*temp)); | |
644 | while ((he = hv_iternext((HV*) SvRV(*temp)))) { | |
645 | SV* ret; | |
646 | IV ok; | |
647 | IV count; | |
648 | SV *err; | |
649 | ||
650 | if (!(SvROK(HeVAL(he)) && SvTYPE(SvRV(HeVAL(he))) == SVt_PVCV)) { | |
651 | SV* buffer = newSVpv("callback '", 0); | |
652 | SV *caller = get_caller(options); | |
653 | ||
654 | sv_catsv(buffer, HeSVKEY_force(he)); | |
655 | sv_catpv(buffer, "' for "); | |
656 | sv_catsv(buffer, caller); | |
657 | SvREFCNT_dec(caller); | |
658 | sv_catpv(buffer, " is not a subroutine reference\n"); | |
659 | validation_failure(buffer, options); | |
660 | } | |
661 | ||
662 | { | |
663 | dSP; | |
664 | ENTER; | |
665 | SAVETMPS; | |
666 | ||
667 | PUSHMARK(SP); | |
668 | EXTEND(SP, 2); | |
669 | PUSHs(value); | |
670 | mPUSHs(newRV_inc(params)); | |
671 | PUTBACK; | |
672 | ||
673 | /* local $@ = q{}; */ | |
674 | save_scalar(PL_errgv); | |
675 | sv_setpv(ERRSV, ""); | |
676 | ||
677 | count = call_sv(SvRV(HeVAL(he)), G_EVAL|G_SCALAR); | |
678 | ||
679 | SPAGAIN; | |
680 | ||
681 | if (!count) { | |
682 | croak("Validation callback did not return anything"); | |
683 | } | |
684 | ||
685 | ret = POPs; | |
686 | SvGETMAGIC(ret); | |
687 | ok = SvTRUE(ret); | |
688 | ||
689 | err = newSV(0); | |
690 | SvSetSV_nosteal(err, ERRSV); | |
691 | ||
692 | PUTBACK; | |
693 | FREETMPS; | |
694 | LEAVE; | |
695 | ||
696 | if (! ok) { | |
697 | if (SvROK(err)) { | |
698 | validation_failure(err, options); | |
699 | } | |
700 | else { | |
701 | SV* buffer = newSVsv(id); | |
702 | SV *caller = get_caller(options); | |
703 | ||
636 | 704 | sv_catpv(buffer, " to "); |
637 | sv_catsv(buffer, get_called(options)); | |
705 | sv_catsv(buffer, caller); | |
706 | SvREFCNT_dec(caller); | |
638 | 707 | sv_catpv(buffer, " did not pass the '"); |
639 | 708 | sv_catsv(buffer, HeSVKEY_force(he)); |
640 | sv_catpv(buffer, "' callback\n"); | |
709 | sv_catpv(buffer, "' callback"); | |
710 | if (SvLEN(err) > 0) { | |
711 | sv_catpv(buffer, ": "); | |
712 | sv_catsv(buffer, err); | |
713 | } | |
714 | sv_catpv(buffer, "\n"); | |
641 | 715 | validation_failure(buffer, options); |
642 | 716 | } |
643 | 717 | } |
644 | 718 | else { |
645 | SV* buffer; | |
646 | ||
647 | buffer = sv_2mortal(newSVpv("callback '", 0)); | |
648 | sv_catsv(buffer, HeSVKEY_force(he)); | |
649 | sv_catpv(buffer, "' for "); | |
650 | sv_catsv(buffer, get_called(options)); | |
651 | sv_catpv(buffer, " is not a subroutine reference\n"); | |
652 | validation_failure(buffer, options); | |
653 | } | |
654 | } | |
655 | } | |
656 | else { | |
657 | SV* buffer; | |
658 | ||
659 | buffer = sv_2mortal(newSVpv("'callbacks' validation parameter for '", 0)); | |
660 | sv_catsv(buffer, get_called(options)); | |
661 | sv_catpv(buffer, " must be a hash reference\n"); | |
662 | validation_failure(buffer, options); | |
719 | SvREFCNT_dec(err); | |
720 | } | |
721 | } | |
663 | 722 | } |
664 | 723 | } |
665 | 724 | |
690 | 749 | } |
691 | 750 | |
692 | 751 | if (!has_regex) { |
693 | SV* buffer; | |
694 | ||
695 | buffer = sv_2mortal(newSVpv("'regex' validation parameter for '", 0)); | |
696 | sv_catsv(buffer, get_called(options)); | |
752 | SV* buffer = newSVpv("'regex' validation parameter for '", 0); | |
753 | SV *caller = get_caller(options); | |
754 | ||
755 | sv_catsv(buffer, caller); | |
756 | SvREFCNT_dec(caller); | |
697 | 757 | sv_catpv(buffer, " must be a string or qr// regex\n"); |
698 | 758 | validation_failure(buffer, options); |
699 | 759 | } |
709 | 769 | PUTBACK; |
710 | 770 | |
711 | 771 | if (!ok) { |
712 | SV* buffer; | |
713 | ||
714 | buffer = sv_2mortal(newSVsv(id)); | |
772 | SV* buffer = newSVsv(id); | |
773 | SV *caller = get_caller(options); | |
774 | ||
715 | 775 | sv_catpv(buffer, " to "); |
716 | sv_catsv(buffer, get_called(options)); | |
776 | sv_catsv(buffer, caller); | |
777 | SvREFCNT_dec(caller); | |
717 | 778 | sv_catpv(buffer, " did not pass regex check\n"); |
718 | 779 | validation_failure(buffer, options); |
719 | 780 | } |
727 | 788 | |
728 | 789 | return 1; |
729 | 790 | } |
730 | ||
731 | 791 | |
732 | 792 | /* merges one hash into another (not deep copy) */ |
733 | 793 | static void |
744 | 804 | } |
745 | 805 | } |
746 | 806 | |
747 | ||
748 | 807 | /* convert array to hash */ |
749 | 808 | static IV |
750 | 809 | convert_array2hash(AV* in, HV* options, HV* out) { |
753 | 812 | |
754 | 813 | len = av_len(in); |
755 | 814 | if (len > -1 && len % 2 != 1) { |
756 | SV* buffer; | |
757 | buffer = sv_2mortal(newSVpv("Odd number of parameters in call to ", 0)); | |
758 | sv_catsv(buffer, get_called(options)); | |
815 | SV* buffer = newSVpv("Odd number of parameters in call to ", 0); | |
816 | SV *caller = get_caller(options); | |
817 | ||
818 | sv_catsv(buffer, caller); | |
819 | SvREFCNT_dec(caller); | |
759 | 820 | sv_catpv(buffer, " when named parameters were expected\n"); |
760 | 821 | |
761 | 822 | validation_failure(buffer, options); |
827 | 888 | return ret; |
828 | 889 | } |
829 | 890 | |
830 | ||
831 | 891 | static SV* |
832 | 892 | normalize_one_key(SV* key, SV* normalize_func, SV* strip_leading, IV ignore_case) { |
833 | 893 | SV* copy; |
884 | 944 | return copy; |
885 | 945 | } |
886 | 946 | |
887 | ||
888 | 947 | static HV* |
889 | 948 | normalize_hash_keys(HV* p, SV* normalize_func, SV* strip_leading, IV ignore_case) { |
890 | 949 | SV* normalized; |
914 | 973 | return norm_p; |
915 | 974 | } |
916 | 975 | |
917 | ||
918 | 976 | static IV |
919 | 977 | validate_pos_depends(AV* p, AV* specs, HV* options) { |
920 | 978 | IV p_idx; |
921 | 979 | SV** depends; |
922 | 980 | SV** p_spec; |
923 | SV* buffer; | |
924 | 981 | |
925 | 982 | for (p_idx = 0; p_idx <= av_len(p); p_idx++) { |
926 | 983 | p_spec = av_fetch(specs, p_idx, 0); |
939 | 996 | } |
940 | 997 | |
941 | 998 | if (av_len(p) < SvIV(*depends) -1) { |
942 | ||
943 | buffer = | |
944 | sv_2mortal(newSVpvf("Parameter #%d depends on parameter #%d, which was not given", | |
945 | (int) p_idx + 1, | |
946 | (int) SvIV(*depends))); | |
999 | SV *buffer = | |
1000 | newSVpvf("Parameter #%d depends on parameter #%d, which was not given", | |
1001 | (int) p_idx + 1, | |
1002 | (int) SvIV(*depends)); | |
947 | 1003 | |
948 | 1004 | validation_failure(buffer, options); |
949 | 1005 | } |
950 | 1006 | } |
951 | 1007 | } |
1008 | ||
952 | 1009 | return 1; |
953 | 1010 | } |
954 | ||
955 | 1011 | |
956 | 1012 | static IV |
957 | 1013 | validate_named_depends(HV* p, HV* specs, HV* options) { |
1026 | 1082 | /* if we got here, the spec was correct. we just |
1027 | 1083 | * need to issue a regular validation failure |
1028 | 1084 | */ |
1029 | buffer = sv_2mortal(newSVpv( "Parameter '", 0)); | |
1085 | buffer = newSVpv( "Parameter '", 0); | |
1030 | 1086 | sv_catsv(buffer, HeSVKEY_force(he1)); |
1031 | 1087 | sv_catpv(buffer, "' depends on parameter '"); |
1032 | 1088 | sv_catsv(buffer, depend_name); |
1040 | 1096 | return 1; |
1041 | 1097 | } |
1042 | 1098 | |
1043 | ||
1044 | 1099 | void |
1045 | 1100 | cat_string_representation(SV* buffer, SV* value) { |
1046 | 1101 | if(SvOK(value)) { |
1053 | 1108 | } |
1054 | 1109 | } |
1055 | 1110 | |
1056 | ||
1057 | 1111 | void |
1058 | 1112 | apply_defaults(HV *ret, HV *p, HV *specs, AV *missing) { |
1059 | 1113 | HE* he; |
1116 | 1170 | } |
1117 | 1171 | } |
1118 | 1172 | } |
1119 | ||
1120 | 1173 | |
1121 | 1174 | static IV |
1122 | 1175 | validate(HV* p, HV* specs, HV* options, HV* ret) { |
1238 | 1291 | } |
1239 | 1292 | |
1240 | 1293 | if (av_len(unmentioned) > -1) { |
1241 | SV* buffer; | |
1242 | ||
1243 | buffer = sv_2mortal(newSVpv("The following parameter", 0)); | |
1294 | SV* buffer = newSVpv("The following parameter", 0); | |
1295 | SV *caller = get_caller(options); | |
1296 | ||
1244 | 1297 | if (av_len(unmentioned) != 0) { |
1245 | 1298 | sv_catpv(buffer, "s were "); |
1246 | 1299 | } |
1248 | 1301 | sv_catpv(buffer, " was "); |
1249 | 1302 | } |
1250 | 1303 | sv_catpv(buffer, "passed in the call to "); |
1251 | sv_catsv(buffer, get_called(options)); | |
1304 | sv_catsv(buffer, caller); | |
1305 | SvREFCNT_dec(caller); | |
1252 | 1306 | sv_catpv(buffer, " but "); |
1253 | 1307 | if (av_len(unmentioned) != 0) { |
1254 | 1308 | sv_catpv(buffer, "were "); |
1277 | 1331 | apply_defaults(ret, p, specs, missing); |
1278 | 1332 | |
1279 | 1333 | if (av_len(missing) > -1) { |
1280 | SV* buffer; | |
1281 | ||
1282 | buffer = sv_2mortal(newSVpv("Mandatory parameter", 0)); | |
1334 | SV* buffer = newSVpv("Mandatory parameter", 0); | |
1335 | SV *caller = get_caller(options); | |
1336 | ||
1283 | 1337 | if (av_len(missing) > 0) { |
1284 | 1338 | sv_catpv(buffer, "s "); |
1285 | 1339 | } |
1295 | 1349 | } |
1296 | 1350 | } |
1297 | 1351 | sv_catpv(buffer, " missing in call to "); |
1298 | sv_catsv(buffer, get_called(options)); | |
1352 | sv_catsv(buffer, caller); | |
1353 | SvREFCNT_dec(caller); | |
1299 | 1354 | sv_catpv(buffer, "\n"); |
1300 | 1355 | |
1301 | 1356 | validation_failure(buffer, options); |
1309 | 1364 | |
1310 | 1365 | return 1; |
1311 | 1366 | } |
1312 | ||
1313 | 1367 | |
1314 | 1368 | static SV* |
1315 | 1369 | validate_pos_failure(IV pnum, IV min, IV max, HV* options) { |
1325 | 1379 | allow_extra = 0; |
1326 | 1380 | } |
1327 | 1381 | |
1328 | buffer = sv_2mortal(newSViv(pnum + 1)); | |
1382 | buffer = newSViv(pnum + 1); | |
1329 | 1383 | if (pnum != 0) { |
1330 | 1384 | sv_catpv(buffer, " parameters were passed to "); |
1331 | 1385 | } |
1332 | 1386 | else { |
1333 | 1387 | sv_catpv(buffer, " parameter was passed to "); |
1334 | 1388 | } |
1335 | sv_catsv(buffer, get_called(options)); | |
1389 | sv_catsv(buffer, get_caller(options)); | |
1336 | 1390 | sv_catpv(buffer, " but "); |
1337 | 1391 | if (!allow_extra) { |
1338 | 1392 | if (min != max) { |
1354 | 1408 | |
1355 | 1409 | return buffer; |
1356 | 1410 | } |
1357 | ||
1358 | 1411 | |
1359 | 1412 | /* Given a single parameter spec and a corresponding complex spec form |
1360 | 1413 | of it (which must be false if the spec is not complex), return true |
1380 | 1433 | } |
1381 | 1434 | return TRUE; |
1382 | 1435 | } |
1383 | ||
1384 | 1436 | |
1385 | 1437 | static IV |
1386 | 1438 | validate_pos(AV* p, AV* specs, HV* options, AV* ret) { |
1534 | 1586 | } |
1535 | 1587 | } |
1536 | 1588 | else { |
1537 | SV* buffer; | |
1538 | ||
1539 | buffer = validate_pos_failure(av_len(p), min, av_len(specs), options); | |
1540 | ||
1589 | SV* buffer = validate_pos_failure(av_len(p), min, av_len(specs), options); | |
1541 | 1590 | validation_failure(buffer, options); |
1542 | 1591 | } |
1543 | 1592 | } |
1550 | 1599 | |
1551 | 1600 | return 1; |
1552 | 1601 | } |
1553 | ||
1554 | 1602 | |
1555 | 1603 | MODULE = Params::Validate::XS PACKAGE = Params::Validate::XS |
1556 | 1604 | |
1631 | 1679 | XSRETURN(0); |
1632 | 1680 | } |
1633 | 1681 | |
1634 | ||
1635 | 1682 | SvGETMAGIC(p); |
1636 | 1683 | if (!SvROK(p) || !(SvTYPE(SvRV(p)) == SVt_PVAV)) { |
1637 | 1684 | croak("Expecting array reference as first parameter"); |
1638 | 1685 | } |
1639 | ||
1640 | 1686 | |
1641 | 1687 | specs = (AV*) sv_2mortal((SV*) newAV()); |
1642 | 1688 | av_extend(specs, items); |
1647 | 1693 | } |
1648 | 1694 | } |
1649 | 1695 | |
1650 | ||
1651 | 1696 | if (GIMME_V != G_VOID) { |
1652 | 1697 | ret = (AV*) sv_2mortal((SV*) newAV()); |
1653 | 1698 | } |
1654 | 1699 | |
1655 | ||
1656 | 1700 | if (! validate_pos((AV*) SvRV(p), specs, get_options(NULL), ret)) { |
1657 | 1701 | XSRETURN(0); |
1658 | 1702 | } |
1659 | ||
1660 | 1703 | |
1661 | 1704 | RETURN_ARRAY(ret); |
1662 | 1705 |
0 | 0 | package Params::Validate; |
1 | $Params::Validate::VERSION = '1.13'; | |
1 | ||
2 | 2 | use 5.008001; |
3 | 3 | |
4 | 4 | use strict; |
5 | 5 | use warnings; |
6 | ||
7 | our $VERSION = '1.18'; | |
6 | 8 | |
7 | 9 | use Exporter; |
8 | 10 | use Module::Implementation; |
12 | 14 | |
13 | 15 | our @ISA = 'Exporter'; |
14 | 16 | |
15 | my %tags = ( | |
16 | types => [ | |
17 | qw( | |
18 | SCALAR | |
19 | ARRAYREF | |
20 | HASHREF | |
21 | CODEREF | |
22 | GLOB | |
23 | GLOBREF | |
24 | SCALARREF | |
25 | HANDLE | |
26 | BOOLEAN | |
27 | UNDEF | |
28 | OBJECT | |
29 | ) | |
30 | ], | |
17 | my @types = qw( | |
18 | SCALAR | |
19 | ARRAYREF | |
20 | HASHREF | |
21 | CODEREF | |
22 | GLOB | |
23 | GLOBREF | |
24 | SCALARREF | |
25 | HANDLE | |
26 | BOOLEAN | |
27 | UNDEF | |
28 | OBJECT | |
31 | 29 | ); |
32 | 30 | |
33 | 31 | our %EXPORT_TAGS = ( |
34 | 32 | 'all' => [ |
35 | 33 | qw( validate validate_pos validation_options validate_with ), |
36 | map { @{ $tags{$_} } } keys %tags | |
34 | @types | |
37 | 35 | ], |
38 | %tags, | |
36 | types => \@types, | |
39 | 37 | ); |
40 | 38 | |
41 | 39 | our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} }, 'set_options' ); |
76 | 74 | |
77 | 75 | =head1 VERSION |
78 | 76 | |
79 | version 1.13 | |
77 | version 1.18 | |
80 | 78 | |
81 | 79 | =head1 SYNOPSIS |
82 | 80 | |
119 | 117 | ); |
120 | 118 | } |
121 | 119 | |
120 | sub callback_with_custom_error { | |
121 | validate( | |
122 | @_, | |
123 | { | |
124 | foo => callbacks => { | |
125 | 'is an integer' => sub { | |
126 | return 1 if $_[0] =~ /^-?[1-9][0-9]*$/; | |
127 | die "$_[0] is not a valid integer value"; | |
128 | }, | |
129 | } | |
130 | } | |
131 | ); | |
132 | } | |
133 | ||
122 | 134 | sub with_defaults { |
123 | 135 | my %p = validate( |
124 | 136 | @_, { |
125 | 137 | # required |
126 | 138 | foo => 1, |
127 | # $p{bar} will be 99 if bar is not given. bar is now | |
139 | # $p{bar} will be 99 if bar is not given. bar is now | |
128 | 140 | # optional. |
129 | 141 | bar => { default => 99 } |
130 | 142 | } |
146 | 158 | =head1 DESCRIPTION |
147 | 159 | |
148 | 160 | The Params::Validate module allows you to validate method or function |
149 | call parameters to an arbitrary level of specificity. At the simplest | |
161 | call parameters to an arbitrary level of specificity. At the simplest | |
150 | 162 | level, it is capable of validating the required parameters were given |
151 | 163 | and that no unspecified additional parameters were passed in. |
152 | 164 | |
165 | 177 | parameters, and set various options on a per-invocation basis. |
166 | 178 | |
167 | 179 | In addition, it can export the following constants, which are used as |
168 | part of the type checking. These are C<SCALAR>, C<ARRAYREF>, | |
180 | part of the type checking. These are C<SCALAR>, C<ARRAYREF>, | |
169 | 181 | C<HASHREF>, C<CODEREF>, C<GLOB>, C<GLOBREF>, and C<SCALARREF>, |
170 | C<UNDEF>, C<OBJECT>, C<BOOLEAN>, and C<HANDLE>. These are explained | |
182 | C<UNDEF>, C<OBJECT>, C<BOOLEAN>, and C<HANDLE>. These are explained | |
171 | 183 | in the section on L<Type Validation|Params::Validate/Type Validation>. |
172 | 184 | |
173 | The constants are available via the export tag C<:types>. There is | |
185 | The constants are available via the export tag C<:types>. There is | |
174 | 186 | also an C<:all> tag which includes all of the constants as well as the |
175 | 187 | C<validation_options()> function. |
176 | 188 | |
189 | =encoding UTF-8 | |
190 | ||
177 | 191 | =head1 PARAMETER VALIDATION |
178 | 192 | |
179 | 193 | The validation mechanisms provided by this module can handle both |
180 | named or positional parameters. For the most part, the same features | |
181 | are available for each. The biggest difference is the way that the | |
182 | validation specification is given to the relevant subroutine. The | |
194 | named or positional parameters. For the most part, the same features | |
195 | are available for each. The biggest difference is the way that the | |
196 | validation specification is given to the relevant subroutine. The | |
183 | 197 | other difference is in the error messages produced when validation |
184 | 198 | checks fail. |
185 | 199 | |
212 | 226 | validate( @_, { foo => 1, bar => 1, baz => 0 } ); |
213 | 227 | |
214 | 228 | This says that the "foo" and "bar" parameters are mandatory and that |
215 | the "baz" parameter is optional. The presence of any other | |
229 | the "baz" parameter is optional. The presence of any other | |
216 | 230 | parameters will cause an error. |
217 | 231 | |
218 | 232 | For a subroutine expecting positional parameters, you would do this: |
226 | 240 | validate_pos( @_, 1, 1, (0) x (@_ - 2) ); |
227 | 241 | |
228 | 242 | This will always be valid as long as at least two parameters are |
229 | given. A similar construct could be used for the more complex | |
243 | given. A similar construct could be used for the more complex | |
230 | 244 | validation parameters described further on. |
231 | 245 | |
232 | 246 | Please note that this: |
233 | 247 | |
234 | 248 | validate_pos( @_, 1, 1, 0, 1, 1 ); |
235 | 249 | |
236 | makes absolutely no sense, so don't do it. Any zeros must come at the | |
250 | makes absolutely no sense, so don't do it. Any zeros must come at the | |
237 | 251 | end of the validation specification. |
238 | 252 | |
239 | 253 | In addition, if you specify that a parameter can have a default, then |
248 | 262 | |
249 | 263 | =item * SCALAR |
250 | 264 | |
251 | A scalar which is not a reference, such as C<10> or C<'hello'>. A | |
252 | parameter that is undefined is B<not> treated as a scalar. If you | |
265 | A scalar which is not a reference, such as C<10> or C<'hello'>. A | |
266 | parameter that is undefined is B<not> treated as a scalar. If you | |
253 | 267 | want to allow undefined values, you will have to specify C<SCALAR | |
254 | 268 | UNDEF>. |
255 | 269 | |
267 | 281 | |
268 | 282 | =item * GLOB |
269 | 283 | |
270 | This one is a bit tricky. A glob would be something like C<*FOO>, but | |
271 | not C<\*FOO>, which is a glob reference. It should be noted that this | |
284 | This one is a bit tricky. A glob would be something like C<*FOO>, but | |
285 | not C<\*FOO>, which is a glob reference. It should be noted that this | |
272 | 286 | trick: |
273 | 287 | |
274 | 288 | my $fh = do { local *FH; }; |
275 | 289 | |
276 | makes C<$fh> a glob, not a glob reference. On the other hand, the | |
277 | return value from C<Symbol::gensym> is a glob reference. Either can | |
290 | makes C<$fh> a glob, not a glob reference. On the other hand, the | |
291 | return value from C<Symbol::gensym> is a glob reference. Either can | |
278 | 292 | be used as a file or directory handle. |
279 | 293 | |
280 | 294 | =item * GLOBREF |
281 | 295 | |
282 | A glob reference such as C<\*FOO>. See the L<GLOB|GLOB> entry above | |
296 | A glob reference such as C<\*FOO>. See the L<GLOB|GLOB> entry above | |
283 | 297 | for more details. |
284 | 298 | |
285 | 299 | =item * SCALARREF |
301 | 315 | =item * HANDLE |
302 | 316 | |
303 | 317 | This option is also special, and is just a shortcut for C<GLOB | |
304 | GLOBREF>. However, it seems likely that most people interested in | |
318 | GLOBREF>. However, it seems likely that most people interested in | |
305 | 319 | either globs or glob references are likely to really be interested in |
306 | 320 | whether the parameter in question could be a valid file or directory |
307 | 321 | handle. |
352 | 366 | |
353 | 367 | =head2 Class Validation |
354 | 368 | |
355 | A word of warning. When constructing your external interfaces, it is | |
369 | A word of warning. When constructing your external interfaces, it is | |
356 | 370 | probably better to specify what methods you expect an object to |
357 | have rather than what class it should be of (or a child of). This | |
371 | have rather than what class it should be of (or a child of). This | |
358 | 372 | will make your API much more flexible. |
359 | 373 | |
360 | 374 | With that said, if you want to validate that an incoming parameter |
376 | 390 | =head2 Regex Validation |
377 | 391 | |
378 | 392 | If you want to specify that a given parameter must match a specific |
379 | regular expression, this can be done with "regex" spec key. For | |
393 | regular expression, this can be done with "regex" spec key. For | |
380 | 394 | example: |
381 | 395 | |
382 | 396 | validate( |
397 | 411 | =head2 Callback Validation |
398 | 412 | |
399 | 413 | If none of the above are enough, it is possible to pass in one or more |
400 | callbacks to validate the parameter. The callback will be given the | |
401 | B<value> of the parameter as its first argument. Its second argument | |
414 | callbacks to validate the parameter. The callback will be given the | |
415 | B<value> of the parameter as its first argument. Its second argument | |
402 | 416 | will be all the parameters, as a reference to either a hash or array. |
403 | Callbacks are specified as hash reference. The key is an id for the | |
417 | Callbacks are specified as hash reference. The key is an id for the | |
404 | 418 | callback (used in error messages) and the value is a subroutine |
405 | 419 | reference, such as: |
406 | 420 | |
407 | 421 | validate( |
408 | @_, { | |
422 | @_, | |
423 | { | |
409 | 424 | foo => { |
410 | 425 | callbacks => { |
411 | 426 | 'smaller than a breadbox' => sub { shift() < $breadbox }, |
412 | 'green or blue' => | |
413 | sub { $_[0] eq 'green' || $_[0] eq 'blue' } | |
427 | 'green or blue' => sub { | |
428 | return 1 if $_[0] eq 'green' || $_[0] eq 'blue'; | |
429 | die "$_[0] is not green or blue!"; | |
430 | } | |
414 | 431 | } |
415 | 432 | } |
416 | ); | |
433 | } | |
434 | ); | |
417 | 435 | |
418 | 436 | validate( |
419 | 437 | @_, { |
424 | 442 | } |
425 | 443 | } |
426 | 444 | ); |
445 | ||
446 | The callback should return a true value if the value is valid. If not, it can | |
447 | return false or die. If you return false, a generic error message will be | |
448 | thrown by C<Params::Validate>. | |
449 | ||
450 | If your callback dies instead you can provide a custom error message. If the | |
451 | callback dies with a plain string, this string will be appended to an | |
452 | exception message generated by C<Params::Validate>. If the callback dies with | |
453 | a reference (blessed or not), then this will be rethrown as-is by | |
454 | C<Params::Validate>. | |
427 | 455 | |
428 | 456 | =head2 Untainting |
429 | 457 | |
487 | 515 | ); |
488 | 516 | |
489 | 517 | In this case, "cc_number", "cc_expiration", and "cc_holder_name" are |
490 | all optional. However, if "cc_number" is provided, then | |
518 | all optional. However, if "cc_number" is provided, then | |
491 | 519 | "cc_expiration" and "cc_holder_name" must be provided as well. |
492 | 520 | |
493 | 521 | This allows you to group together sets of parameters that all must be |
494 | 522 | provided together. |
495 | 523 | |
496 | 524 | The C<validate_pos()> version of dependencies is slightly different, |
497 | in that you can only depend on one other parameter. Also, if for | |
525 | in that you can only depend on one other parameter. Also, if for | |
498 | 526 | example, the second parameter 2 depends on the fourth parameter, then |
499 | it implies a dependency on the third parameter as well. This is | |
527 | it implies a dependency on the third parameter as well. This is | |
500 | 528 | because if the fourth parameter is required, then the user must also |
501 | 529 | provide a third parameter so that there can be four parameters in |
502 | 530 | total. |
531 | 559 | =head2 Validation failure |
532 | 560 | |
533 | 561 | By default, when validation fails C<Params::Validate> calls |
534 | C<Carp::confess()>. This can be overridden by setting the C<on_fail> | |
562 | C<Carp::confess()>. This can be overridden by setting the C<on_fail> | |
535 | 563 | option, which is described in the L<"GLOBAL" OPTIONS|"GLOBAL" OPTIONS> |
536 | 564 | section. |
537 | 565 | |
583 | 611 | |
584 | 612 | Because the API for the C<validate()> and C<validate_pos()> functions does not |
585 | 613 | make it possible to specify any options other than the validation spec, it is |
586 | possible to set some options as pseudo-'globals'. These allow you to specify | |
614 | possible to set some options as pseudo-'globals'. These allow you to specify | |
587 | 615 | such things as whether or not the validation of named parameters should be |
588 | 616 | case sensitive, for one example. |
589 | 617 | |
620 | 648 | C<validate_with()> are called. |
621 | 649 | |
622 | 650 | Any alterations made by this callback will be reflected in the |
623 | parameter hash that is returned by the validation function. For | |
651 | parameter hash that is returned by the validation function. For | |
624 | 652 | example: |
625 | 653 | |
626 | 654 | sub foo { |
649 | 677 | =item * allow_extra => $boolean |
650 | 678 | |
651 | 679 | If true, then the validation routine will allow extra parameters not |
652 | named in the validation specification. In the case of positional | |
680 | named in the validation specification. In the case of positional | |
653 | 681 | parameters, this allows an unlimited number of maximum parameters |
654 | (though a minimum may still be set). Defaults to false. | |
682 | (though a minimum may still be set). Defaults to false. | |
655 | 683 | |
656 | 684 | =item * on_fail => $callback |
657 | 685 | |
658 | 686 | If given, this callback will be called whenever a validation check |
659 | fails. It will be called with a single parameter, which will be a | |
660 | string describing the failure. This is useful if you wish to have | |
687 | fails. It will be called with a single parameter, which will be a | |
688 | string describing the failure. This is useful if you wish to have | |
661 | 689 | this module throw exceptions as objects rather than as strings, for |
662 | 690 | example. |
663 | 691 | |
664 | This callback is expected to C<die()> internally. If it does not, the | |
692 | This callback is expected to C<die()> internally. If it does not, the | |
665 | 693 | validation will proceed onwards, with unpredictable results. |
666 | 694 | |
667 | 695 | The default is to simply use the Carp module's C<confess()> function. |
669 | 697 | =item * stack_skip => $number |
670 | 698 | |
671 | 699 | This tells Params::Validate how many stack frames to skip when finding |
672 | a subroutine name to use in error messages. By default, it looks one | |
700 | a subroutine name to use in error messages. By default, it looks one | |
673 | 701 | frame back, at the immediate caller to C<validate()> or |
674 | C<validate_pos()>. If this option is set, then the given number of | |
702 | C<validate_pos()>. If this option is set, then the given number of | |
675 | 703 | frames are skipped instead. |
676 | 704 | |
677 | 705 | =item * ignore_case => $boolean |
678 | 706 | |
679 | 707 | DEPRECATED |
680 | 708 | |
681 | This is only relevant when dealing with named parameters. If it is | |
709 | This is only relevant when dealing with named parameters. If it is | |
682 | 710 | true, then the validation code will ignore the case of parameter |
683 | names. Defaults to false. | |
711 | names. Defaults to false. | |
684 | 712 | |
685 | 713 | =item * strip_leading => $characters |
686 | 714 | |
687 | 715 | DEPRECATED |
688 | 716 | |
689 | This too is only relevant when dealing with named parameters. If this | |
717 | This too is only relevant when dealing with named parameters. If this | |
690 | 718 | is given then any parameters starting with these characters will be |
691 | considered equivalent to parameters without them entirely. For | |
719 | considered equivalent to parameters without them entirely. For | |
692 | 720 | example, if this is specified as '-', then C<-foo> and C<foo> would be |
693 | 721 | considered identical. |
694 | 722 | |
697 | 725 | =head1 PER-INVOCATION OPTIONS |
698 | 726 | |
699 | 727 | The C<validate_with()> function can be used to set the options listed |
700 | above on a per-invocation basis. For example: | |
728 | above on a per-invocation basis. For example: | |
701 | 729 | |
702 | 730 | my %p = validate_with( |
703 | 731 | params => \@_, |
709 | 737 | ); |
710 | 738 | |
711 | 739 | In addition to the options listed above, it is also possible to set |
712 | the option "called", which should be a string. This string will be | |
740 | the option "called", which should be a string. This string will be | |
713 | 741 | used in any error messages caused by a failure to meet the validation |
714 | 742 | spec. |
715 | 743 | |
716 | 744 | This subroutine will validate named parameters as a hash if the "spec" |
717 | parameter is a hash reference. If it is an array reference, the | |
745 | parameter is a hash reference. If it is an array reference, the | |
718 | 746 | parameters are assumed to be positional. |
719 | 747 | |
720 | 748 | my %p = validate_with( |
740 | 768 | =head1 DISABLING VALIDATION |
741 | 769 | |
742 | 770 | If the environment variable C<PERL_NO_VALIDATION> is set to something |
743 | true, then validation is turned off. This may be useful if you only | |
771 | true, then validation is turned off. This may be useful if you only | |
744 | 772 | want to use this module during development but don't want the speed |
745 | 773 | hit during production. |
746 | 774 | |
749 | 777 | |
750 | 778 | If you want to selectively turn validation on and off at runtime, you |
751 | 779 | can directly set the C<$Params::Validate::NO_VALIDATION> global |
752 | variable. It is B<strongly> recommended that you B<localize> any | |
780 | variable. It is B<strongly> recommended that you B<localize> any | |
753 | 781 | changes to this variable, because other modules you are using may |
754 | expect validation to be on when they execute. For example: | |
782 | expect validation to be on when they execute. For example: | |
755 | 783 | |
756 | 784 | { |
757 | 785 | local $Params::Validate::NO_VALIDATION = 1; |
783 | 811 | |
784 | 812 | Right now there is no way (short of a callback) to specify that |
785 | 813 | something must be of one of a list of classes, or that it must possess |
786 | one of a list of methods. If this is desired, it can be added in the | |
814 | one of a list of methods. If this is desired, it can be added in the | |
787 | 815 | future. |
788 | 816 | |
789 | Ideally, there would be only one validation function. If someone | |
817 | Ideally, there would be only one validation function. If someone | |
790 | 818 | figures out how to do this, please let me know. |
791 | 819 | |
792 | 820 | =head1 SUPPORT |
832 | 860 | |
833 | 861 | =back |
834 | 862 | |
863 | =head1 CONTRIBUTORS | |
864 | ||
865 | =for stopwords J.R. Mash Olivier Mengué | |
866 | ||
867 | =over 4 | |
868 | ||
869 | =item * | |
870 | ||
871 | J.R. Mash <jmash.code@gmail.com> | |
872 | ||
873 | =item * | |
874 | ||
875 | Olivier Mengué <dolmen@cpan.org> | |
876 | ||
877 | =back | |
878 | ||
835 | 879 | =head1 COPYRIGHT AND LICENSE |
836 | 880 | |
837 | This software is Copyright (c) 2014 by Dave Rolsky and Ilya Martynov. | |
881 | This software is Copyright (c) 2001 - 2015 by Dave Rolsky and Ilya Martynov. | |
838 | 882 | |
839 | 883 | This is free software, licensed under: |
840 | 884 |
0 | package Params::Validate; | |
1 | $Params::Validate::VERSION = '1.13'; | |
0 | package # hide from PAUSE | |
1 | Params::Validate; | |
2 | ||
3 | our $VERSION = '1.18'; | |
4 | ||
2 | 5 | BEGIN { $ENV{PARAMS_VALIDATE_IMPLEMENTATION} = 'PP' } |
3 | 6 | use Params::Validate; |
4 | 7 |
0 | package Params::Validate; | |
1 | $Params::Validate::VERSION = '1.13'; | |
0 | package # hide from PAUSE | |
1 | Params::Validate; | |
2 | ||
3 | our $VERSION = '1.18'; | |
4 | ||
2 | 5 | BEGIN { $ENV{PARAMS_VALIDATE_IMPLEMENTATION} = 'XS' } |
3 | 6 | use Params::Validate; |
4 | 7 |
0 | severity = 3 | |
1 | verbose = 11 | |
2 | theme = core + pbp + bugs + maintenance + cosmetic + complexity + security + tests + moose | |
3 | ||
4 | exclude = Subroutines::ProhibitCallsToUndeclaredSubs | |
5 | ||
6 | [BuiltinFunctions::ProhibitStringySplit] | |
7 | severity = 3 | |
8 | ||
9 | [CodeLayout::RequireTrailingCommas] | |
10 | severity = 3 | |
11 | ||
12 | [ControlStructures::ProhibitCStyleForLoops] | |
13 | severity = 3 | |
14 | ||
15 | [InputOutput::RequireCheckedSyscalls] | |
16 | functions = :builtins | |
17 | exclude_functions = sleep | |
18 | severity = 3 | |
19 | ||
20 | [RegularExpressions::ProhibitComplexRegexes] | |
21 | max_characters = 200 | |
22 | ||
23 | [RegularExpressions::ProhibitUnusualDelimiters] | |
24 | severity = 3 | |
25 | ||
26 | [Subroutines::ProhibitUnusedPrivateSubroutines] | |
27 | private_name_regex = _(?!build)\w+ | |
28 | ||
29 | [TestingAndDebugging::ProhibitNoWarnings] | |
30 | allow = redefine | |
31 | ||
32 | [ValuesAndExpressions::ProhibitEmptyQuotes] | |
33 | severity = 3 | |
34 | ||
35 | [ValuesAndExpressions::ProhibitInterpolationOfLiterals] | |
36 | severity = 3 | |
37 | ||
38 | [ValuesAndExpressions::RequireUpperCaseHeredocTerminator] | |
39 | severity = 3 | |
40 | ||
41 | [Variables::ProhibitPackageVars] | |
42 | add_packages = Carp Test::Builder | |
43 | ||
44 | [-Subroutines::RequireFinalReturn] | |
45 | ||
46 | [-ErrorHandling::RequireCarping] | |
47 | ||
48 | # No need for /xsm everywhere | |
49 | [-RegularExpressions::RequireDotMatchAnything] | |
50 | [-RegularExpressions::RequireExtendedFormatting] | |
51 | [-RegularExpressions::RequireLineBoundaryMatching] | |
52 | ||
53 | # http://stackoverflow.com/questions/2275317/why-does-perlcritic-dislike-using-shift-to-populate-subroutine-variables | |
54 | [-Subroutines::RequireArgUnpacking] | |
55 | ||
56 | # "use v5.14" is more readable than "use 5.014" | |
57 | [-ValuesAndExpressions::ProhibitVersionStrings] |
0 | -l=78 | |
1 | -i=4 | |
2 | -ci=4 | |
3 | -se | |
4 | -b | |
5 | -bar | |
6 | -boc | |
7 | -vt=0 | |
8 | -vtc=0 | |
9 | -cti=0 | |
10 | -pt=1 | |
11 | -bt=1 | |
12 | -sbt=1 | |
13 | -bbt=1 | |
14 | -nolq | |
15 | -npro | |
16 | -nsfs | |
17 | --blank-lines-before-packages=0 | |
18 | --opening-hash-brace-right | |
19 | --no-outdent-long-comments | |
20 | -wbb="% + - * / x != == >= <= =~ !~ < > | & >= < = **= += *= &= <<= &&= -= /= |= >>= ||= .= %= ^= x=" |
0 | use 5.006; | |
1 | use strict; | |
2 | use warnings; | |
3 | ||
4 | # this test was generated with Dist::Zilla::Plugin::Test::Compile 2.051 | |
5 | ||
6 | use Test::More; | |
7 | ||
8 | plan tests => 7 + ($ENV{AUTHOR_TESTING} ? 1 : 0); | |
9 | ||
10 | my @module_files = ( | |
11 | 'Attribute/Params/Validate.pm', | |
12 | 'Params/Validate.pm', | |
13 | 'Params/Validate/Constants.pm', | |
14 | 'Params/Validate/PP.pm', | |
15 | 'Params/Validate/XS.pm', | |
16 | 'Params/ValidatePP.pm', | |
17 | 'Params/ValidateXS.pm' | |
18 | ); | |
19 | ||
20 | ||
21 | ||
22 | # no fake home requested | |
23 | ||
24 | my $inc_switch = -d 'blib' ? '-Mblib' : '-Ilib'; | |
25 | ||
26 | use File::Spec; | |
27 | use IPC::Open3; | |
28 | use IO::Handle; | |
29 | ||
30 | open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!"; | |
31 | ||
32 | my @warnings; | |
33 | for my $lib (@module_files) | |
34 | { | |
35 | # see L<perlfaq8/How can I capture STDERR from an external command?> | |
36 | my $stderr = IO::Handle->new; | |
37 | ||
38 | my $pid = open3($stdin, '>&STDERR', $stderr, $^X, $inc_switch, '-e', "require q[$lib]"); | |
39 | binmode $stderr, ':crlf' if $^O eq 'MSWin32'; | |
40 | my @_warnings = <$stderr>; | |
41 | waitpid($pid, 0); | |
42 | is($?, 0, "$lib loaded ok"); | |
43 | ||
44 | if (@_warnings) | |
45 | { | |
46 | warn @_warnings; | |
47 | push @warnings, @_warnings; | |
48 | } | |
49 | } | |
50 | ||
51 | ||
52 | ||
53 | is(scalar(@warnings), 0, 'no warnings found') | |
54 | or diag 'got warnings: ', ( Test::More->can('explain') ? Test::More::explain(\@warnings) : join("\n", '', @warnings) ) if $ENV{AUTHOR_TESTING}; | |
55 | ||
56 |
0 | do { my $x = { | |
1 | 'build' => { | |
2 | 'requires' => { | |
3 | 'Module::Build' => '0.28' | |
4 | } | |
5 | }, | |
6 | 'configure' => { | |
7 | 'requires' => { | |
8 | 'Module::Build' => '0.28' | |
9 | } | |
10 | }, | |
11 | 'develop' => { | |
12 | 'requires' => { | |
13 | 'Perl::Critic' => '1.123', | |
14 | 'Perl::Tidy' => '20140711', | |
15 | 'Pod::Coverage::TrustPod' => '0', | |
16 | 'Readonly' => '1.03', | |
17 | 'Scalar::Util' => '1.20', | |
18 | 'Test::CPAN::Changes' => '0.19', | |
19 | 'Test::EOL' => '0', | |
20 | 'Test::LeakTrace' => '0.15', | |
21 | 'Test::More' => '0.96', | |
22 | 'Test::NoTabs' => '0', | |
23 | 'Test::Pod' => '1.41', | |
24 | 'Test::Pod::Coverage' => '1.08', | |
25 | 'Test::Spelling' => '0.12', | |
26 | 'Test::Synopsis' => '0', | |
27 | 'Test::Taint' => '0.02', | |
28 | 'Test::Version' => '1' | |
29 | } | |
30 | }, | |
31 | 'runtime' => { | |
32 | 'requires' => { | |
33 | 'Attribute::Handlers' => '0.79', | |
34 | 'Carp' => '0', | |
35 | 'Exporter' => '0', | |
36 | 'Module::Implementation' => '0', | |
37 | 'Scalar::Util' => '1.10', | |
38 | 'XSLoader' => '0', | |
39 | 'attributes' => '0', | |
40 | 'perl' => '5.008001', | |
41 | 'strict' => '0', | |
42 | 'vars' => '0', | |
43 | 'warnings' => '0' | |
44 | } | |
45 | }, | |
46 | 'test' => { | |
47 | 'recommends' => { | |
48 | 'CPAN::Meta' => '2.120900' | |
49 | }, | |
50 | 'requires' => { | |
51 | 'Devel::Peek' => '0', | |
52 | 'ExtUtils::MakeMaker' => '0', | |
53 | 'File::Spec' => '0', | |
54 | 'File::Temp' => '0', | |
55 | 'IO::Handle' => '0', | |
56 | 'IPC::Open3' => '0', | |
57 | 'Test::Fatal' => '0', | |
58 | 'Test::More' => '0.96', | |
59 | 'Test::Requires' => '0', | |
60 | 'Tie::Array' => '0', | |
61 | 'Tie::Hash' => '0', | |
62 | 'base' => '0', | |
63 | 'lib' => '0', | |
64 | 'overload' => '0' | |
65 | } | |
66 | } | |
67 | }; | |
68 | $x; | |
69 | }⏎ |
0 | #!perl | |
1 | ||
2 | use strict; | |
3 | use warnings; | |
4 | ||
5 | # This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.020 | |
6 | ||
7 | use Test::More tests => 1; | |
8 | ||
9 | use ExtUtils::MakeMaker; | |
10 | use File::Spec; | |
11 | ||
12 | # from $version::LAX | |
13 | my $lax_version_re = | |
14 | qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )? | |
15 | | | |
16 | (?:\.[0-9]+) (?:_[0-9]+)? | |
17 | ) | (?: | |
18 | v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )? | |
19 | | | |
20 | (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)? | |
21 | ) | |
22 | )/x; | |
23 | ||
24 | # hide optional CPAN::Meta modules from prereq scanner | |
25 | # and check if they are available | |
26 | my $cpan_meta = "CPAN::Meta"; | |
27 | my $cpan_meta_pre = "CPAN::Meta::Prereqs"; | |
28 | my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic | |
29 | ||
30 | # Verify requirements? | |
31 | my $DO_VERIFY_PREREQS = 1; | |
32 | ||
33 | sub _max { | |
34 | my $max = shift; | |
35 | $max = ( $_ > $max ) ? $_ : $max for @_; | |
36 | return $max; | |
37 | } | |
38 | ||
39 | sub _merge_prereqs { | |
40 | my ($collector, $prereqs) = @_; | |
41 | ||
42 | # CPAN::Meta::Prereqs object | |
43 | if (ref $collector eq $cpan_meta_pre) { | |
44 | return $collector->with_merged_prereqs( | |
45 | CPAN::Meta::Prereqs->new( $prereqs ) | |
46 | ); | |
47 | } | |
48 | ||
49 | # Raw hashrefs | |
50 | for my $phase ( keys %$prereqs ) { | |
51 | for my $type ( keys %{ $prereqs->{$phase} } ) { | |
52 | for my $module ( keys %{ $prereqs->{$phase}{$type} } ) { | |
53 | $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module}; | |
54 | } | |
55 | } | |
56 | } | |
57 | ||
58 | return $collector; | |
59 | } | |
60 | ||
61 | my @include = qw( | |
62 | ||
63 | ); | |
64 | ||
65 | my @exclude = qw( | |
66 | ||
67 | ); | |
68 | ||
69 | # Add static prereqs to the included modules list | |
70 | my $static_prereqs = do 't/00-report-prereqs.dd'; | |
71 | ||
72 | # Merge all prereqs (either with ::Prereqs or a hashref) | |
73 | my $full_prereqs = _merge_prereqs( | |
74 | ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ), | |
75 | $static_prereqs | |
76 | ); | |
77 | ||
78 | # Add dynamic prereqs to the included modules list (if we can) | |
79 | my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; | |
80 | if ( $source && $HAS_CPAN_META ) { | |
81 | if ( my $meta = eval { CPAN::Meta->load_file($source) } ) { | |
82 | $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs); | |
83 | } | |
84 | } | |
85 | else { | |
86 | $source = 'static metadata'; | |
87 | } | |
88 | ||
89 | my @full_reports; | |
90 | my @dep_errors; | |
91 | my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs; | |
92 | ||
93 | # Add static includes into a fake section | |
94 | for my $mod (@include) { | |
95 | $req_hash->{other}{modules}{$mod} = 0; | |
96 | } | |
97 | ||
98 | for my $phase ( qw(configure build test runtime develop other) ) { | |
99 | next unless $req_hash->{$phase}; | |
100 | next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING}); | |
101 | ||
102 | for my $type ( qw(requires recommends suggests conflicts modules) ) { | |
103 | next unless $req_hash->{$phase}{$type}; | |
104 | ||
105 | my $title = ucfirst($phase).' '.ucfirst($type); | |
106 | my @reports = [qw/Module Want Have/]; | |
107 | ||
108 | for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) { | |
109 | next if $mod eq 'perl'; | |
110 | next if grep { $_ eq $mod } @exclude; | |
111 | ||
112 | my $file = $mod; | |
113 | $file =~ s{::}{/}g; | |
114 | $file .= ".pm"; | |
115 | my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC; | |
116 | ||
117 | my $want = $req_hash->{$phase}{$type}{$mod}; | |
118 | $want = "undef" unless defined $want; | |
119 | $want = "any" if !$want && $want == 0; | |
120 | ||
121 | my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required"; | |
122 | ||
123 | if ($prefix) { | |
124 | my $have = MM->parse_version( File::Spec->catfile($prefix, $file) ); | |
125 | $have = "undef" unless defined $have; | |
126 | push @reports, [$mod, $want, $have]; | |
127 | ||
128 | if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) { | |
129 | if ( $have !~ /\A$lax_version_re\z/ ) { | |
130 | push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)"; | |
131 | } | |
132 | elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) { | |
133 | push @dep_errors, "$mod version '$have' is not in required range '$want'"; | |
134 | } | |
135 | } | |
136 | } | |
137 | else { | |
138 | push @reports, [$mod, $want, "missing"]; | |
139 | ||
140 | if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) { | |
141 | push @dep_errors, "$mod is not installed ($req_string)"; | |
142 | } | |
143 | } | |
144 | } | |
145 | ||
146 | if ( @reports ) { | |
147 | push @full_reports, "=== $title ===\n\n"; | |
148 | ||
149 | my $ml = _max( map { length $_->[0] } @reports ); | |
150 | my $wl = _max( map { length $_->[1] } @reports ); | |
151 | my $hl = _max( map { length $_->[2] } @reports ); | |
152 | ||
153 | if ($type eq 'modules') { | |
154 | splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl]; | |
155 | push @full_reports, map { sprintf(" %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports; | |
156 | } | |
157 | else { | |
158 | splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl]; | |
159 | push @full_reports, map { sprintf(" %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports; | |
160 | } | |
161 | ||
162 | push @full_reports, "\n"; | |
163 | } | |
164 | } | |
165 | } | |
166 | ||
167 | if ( @full_reports ) { | |
168 | diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports; | |
169 | } | |
170 | ||
171 | if ( @dep_errors ) { | |
172 | diag join("\n", | |
173 | "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n", | |
174 | "The following REQUIRED prerequisites were not satisfied:\n", | |
175 | @dep_errors, | |
176 | "\n" | |
177 | ); | |
178 | } | |
179 | ||
180 | pass; | |
181 | ||
182 | # vim: ts=4 sts=4 sw=4 et: |
53 | 53 | params => $arglist{$args}, |
54 | 54 | spec => $speclist{$spec}, |
55 | 55 | expect => ( |
56 | $ignore_case ? $ok_sub | |
56 | $ignore_case ? $ok_sub | |
57 | 57 | : $args eq $spec ? $ok_sub |
58 | : $nok_sub | |
58 | : $nok_sub | |
59 | 59 | ), |
60 | 60 | ignore_case => $ignore_case |
61 | 61 | }; |
41 | 41 | # positive, no depends (single, multiple) |
42 | 42 | my @args = ( bar => 1 ); |
43 | 43 | eval { validate( @args, \%spec ) }; |
44 | is( $@, q{}, | |
45 | "validate() multiple depends(1): no depends, single arg, positive" ); | |
44 | is( | |
45 | $@, q{}, | |
46 | "validate() multiple depends(1): no depends, single arg, positive" | |
47 | ); | |
46 | 48 | |
47 | 49 | @args = ( bar => 1, baz => 1 ); |
48 | 50 | eval { validate( @args, \%spec ) }; |
60 | 62 | @args = ( foo => 1, bar => 1 ); |
61 | 63 | eval { validate( @args, \%spec ) }; |
62 | 64 | |
63 | ok( $@, | |
65 | ok( | |
66 | $@, | |
64 | 67 | "validate() multiple depends(4.a): with depends, negative, multiple missing" |
65 | 68 | ); |
66 | 69 | like( |
72 | 75 | @args = ( foo => 1 ); |
73 | 76 | eval { validate( @args, \%spec ) }; |
74 | 77 | |
75 | ok( $@, | |
78 | ok( | |
79 | $@, | |
76 | 80 | "validate() multiple depends(5.a): with depends, negative, multiple missing" |
77 | 81 | ); |
78 | 82 | like( |
116 | 120 | my @args = qw(1 1); |
117 | 121 | eval { validate_pos( @args, @spec ) }; |
118 | 122 | |
119 | is( $@, q{}, | |
120 | "validate_pos() single depends (1): with depends, positive" ); | |
123 | is( | |
124 | $@, q{}, | |
125 | "validate_pos() single depends (1): with depends, positive" | |
126 | ); | |
121 | 127 | } |
122 | 128 | |
123 | 129 | { |
147 | 153 | my @args = qw(1); |
148 | 154 | eval { validate_pos( @args, @spec ) }; |
149 | 155 | |
150 | ok( $@, | |
156 | ok( | |
157 | $@, | |
151 | 158 | "validate_pos() multiple depends (1.a): with depends, bad args negative" |
152 | 159 | ); |
153 | 160 | like( |
4 | 4 | use Test::More; |
5 | 5 | |
6 | 6 | { |
7 | ||
8 | 7 | package Tie::SimpleArray; |
9 | 8 | use Tie::Array; |
10 | 9 | use base 'Tie::StdArray'; |
25 | 24 | |
26 | 25 | eval { validate( @p, \%spec ) }; |
27 | 26 | warn $@ if $@; |
28 | is( $@, q{}, | |
27 | is( | |
28 | $@, q{}, | |
29 | 29 | 'validate() call succeeded with tied params array and regular hashref spec' |
30 | 30 | ); |
31 | 31 | } |
42 | 42 | |
43 | 43 | eval { validate( @p, \%spec ) }; |
44 | 44 | warn $@ if $@; |
45 | is( $@, q{}, | |
45 | is( | |
46 | $@, q{}, | |
46 | 47 | 'validate() call succeeded with regular params array and tied hashref spec' |
47 | 48 | ); |
48 | 49 | } |
59 | 60 | |
60 | 61 | eval { validate( @p, \%spec ) }; |
61 | 62 | warn $@ if $@; |
62 | is( $@, q{}, | |
63 | is( | |
64 | $@, q{}, | |
63 | 65 | 'validate() call succeeded with tied params array and tied hashref spec' |
64 | 66 | ); |
65 | 67 | } |
73 | 75 | |
74 | 76 | eval { validate_pos( @p, \%spec ) }; |
75 | 77 | warn $@ if $@; |
76 | is( $@, q{}, | |
78 | is( | |
79 | $@, q{}, | |
77 | 80 | 'validate_pos() call succeeded with tied params array and regular hashref spec' |
78 | 81 | ); |
79 | 82 | } |
90 | 93 | |
91 | 94 | eval { validate_pos( @p, \%spec ) }; |
92 | 95 | warn $@ if $@; |
93 | is( $@, q{}, | |
96 | is( | |
97 | $@, q{}, | |
94 | 98 | 'validate_pos() call succeeded with regular params array and tied hashref spec' |
95 | 99 | ); |
96 | 100 | } |
107 | 111 | |
108 | 112 | eval { validate_pos( @p, \%spec ) }; |
109 | 113 | warn $@ if $@; |
110 | is( $@, q{}, | |
114 | is( | |
115 | $@, q{}, | |
111 | 116 | 'validate_pos() call succeeded with tied params array and tied hashref spec' |
112 | 117 | ); |
113 | 118 | } |
8 | 8 | |
9 | 9 | eval { validate( @p, { foo => { type => 'SCALAR' } }, ); }; |
10 | 10 | |
11 | like( $@, | |
11 | like( | |
12 | $@, | |
12 | 13 | qr/\QThe 'foo' parameter ("1") has a type specification which is not a number. It is a string - SCALAR/ |
13 | 14 | ); |
14 | 15 | } |
18 | 19 | |
19 | 20 | eval { validate( @p, { foo => { type => undef } }, ); }; |
20 | 21 | |
21 | like( $@, | |
22 | like( | |
23 | $@, | |
22 | 24 | qr/\QThe 'foo' parameter ("1") has a type specification which is not a number. It is undef/ |
23 | 25 | ); |
24 | 26 |
28 | 28 | |
29 | 29 | sub v { |
30 | 30 | validate( |
31 | @_, | |
32 | { | |
31 | @_, { | |
33 | 32 | foo => { type => SCALAR | SCALARREF }, |
34 | 33 | }, |
35 | 34 | ); |
27 | 27 | # catch die signal |
28 | 28 | local $SIG{__DIE__} = sub { |
29 | 29 | |
30 | # we died from within Params::Validate (because of wrong_Arg) we call | |
31 | # Foo::test_foo with OK args, but it'll die, because | |
32 | # Params::ValidatePP::options is still set to the options of the Bar | |
33 | # package, and so it won't retreive the one from Foo. | |
30 | # we died from within Params::Validate (because of wrong_Arg) we | |
31 | # call Foo::test_foo with OK args, but it'll die, because | |
32 | # Params::Validate::PP::options is still set to the options of the | |
33 | # Bar package, and so it won't retreive the one from Foo. | |
34 | 34 | Foo::test_foo( arg1 => 1, extra_arg => 2 ); |
35 | 35 | }; |
36 | 36 |
0 | use strict; | |
1 | use warnings; | |
2 | ||
3 | use Test::Fatal; | |
4 | use Test::More; | |
5 | ||
6 | { | |
7 | package Foo; | |
8 | ||
9 | use Params::Validate qw( validate ARRAYREF ); | |
10 | ||
11 | sub v1 { | |
12 | my %p = validate( | |
13 | @_, | |
14 | { | |
15 | array => { | |
16 | callbacks => { | |
17 | 'checking array contents' => sub { | |
18 | for my $x ( @{ $_[0] } ) { | |
19 | return 0 unless defined $x && !ref $x; | |
20 | } | |
21 | return 1; | |
22 | }, | |
23 | } | |
24 | } | |
25 | } | |
26 | ); | |
27 | return $p{array}; | |
28 | } | |
29 | } | |
30 | ||
31 | { | |
32 | for my $size ( 100, 1_000, 100_000 ) { | |
33 | my @array = ('x') x $size; | |
34 | is_deeply( | |
35 | Foo::v1( array => \@array ), | |
36 | \@array, | |
37 | "validate() handles $size element array correctly" | |
38 | ); | |
39 | } | |
40 | } | |
41 | ||
42 | done_testing(); |
0 | use strict; | |
1 | use warnings; | |
2 | ||
3 | use Test::Fatal; | |
4 | use Test::More; | |
5 | ||
6 | { | |
7 | package Foo; | |
8 | ||
9 | use Params::Validate qw( validate ARRAYREF ); | |
10 | ||
11 | sub v1 { | |
12 | my %p = validate( | |
13 | @_, { | |
14 | array => { | |
15 | callbacks => { | |
16 | 'checking array contents' => sub { | |
17 | for my $x ( @{ $_[0] } ) { | |
18 | return 0 unless defined $x && !ref $x; | |
19 | } | |
20 | return 1; | |
21 | }, | |
22 | } | |
23 | } | |
24 | } | |
25 | ); | |
26 | return $p{array}; | |
27 | } | |
28 | } | |
29 | ||
30 | { | |
31 | for my $size ( 100, 1_000, 100_000 ) { | |
32 | my @array = ('x') x $size; | |
33 | is_deeply( | |
34 | Foo::v1( array => \@array ), | |
35 | \@array, | |
36 | "validate() handles $size element array correctly" | |
37 | ); | |
38 | } | |
39 | } | |
40 | ||
41 | done_testing(); |
0 | use strict; | |
1 | use warnings; | |
2 | ||
3 | use Test::More; | |
4 | use Params::Validate (); | |
5 | ||
6 | my @types = qw( | |
7 | SCALAR | |
8 | ARRAYREF | |
9 | HASHREF | |
10 | CODEREF | |
11 | GLOB | |
12 | GLOBREF | |
13 | SCALARREF | |
14 | HANDLE | |
15 | BOOLEAN | |
16 | UNDEF | |
17 | OBJECT | |
18 | ); | |
19 | ||
20 | my @subs = qw( | |
21 | validate | |
22 | validate_pos | |
23 | validation_options | |
24 | validate_with | |
25 | ); | |
26 | ||
27 | is_deeply( | |
28 | [ sort @Params::Validate::EXPORT_OK ], | |
29 | [ sort @types, @subs, 'set_options' ], | |
30 | '@EXPORT_OK' | |
31 | ); | |
32 | ||
33 | is_deeply( | |
34 | [ sort keys %Params::Validate::EXPORT_TAGS ], | |
35 | [qw( all types )], | |
36 | 'keys %EXPORT_TAGS' | |
37 | ); | |
38 | ||
39 | is_deeply( | |
40 | [ sort @{ $Params::Validate::EXPORT_TAGS{all} } ], | |
41 | [ sort @types, @subs ], | |
42 | '$EXPORT_TAGS{all}', | |
43 | ); | |
44 | ||
45 | is_deeply( | |
46 | [ sort @{ $Params::Validate::EXPORT_TAGS{types} } ], | |
47 | [ sort @types ], | |
48 | '$EXPORT_TAGS{types}', | |
49 | ); | |
50 | ||
51 | done_testing(); |
0 | use strict; | |
1 | use warnings; | |
2 | ||
3 | use Test::More; | |
4 | use Params::Validate qw( validate ); | |
5 | ||
6 | { | |
7 | my $e = _test_args( | |
8 | pos_int => 42, | |
9 | string => 'foo', | |
10 | ); | |
11 | is( | |
12 | $e, | |
13 | q{}, | |
14 | 'no error with good args' | |
15 | ); | |
16 | } | |
17 | ||
18 | { | |
19 | my $e = _test_args( | |
20 | pos_int => 42, | |
21 | string => [], | |
22 | ); | |
23 | like( | |
24 | $e, | |
25 | qr/The 'string' parameter \("ARRAY\(.+\)"\) to main::validate1 did not pass the 'string' callback: ARRAY\(.+\) is not a string/, | |
26 | 'got error for bad string' | |
27 | ); | |
28 | } | |
29 | ||
30 | { | |
31 | my $e = _test_args( | |
32 | pos_int => 0, | |
33 | string => 'foo', | |
34 | ); | |
35 | like( | |
36 | $e, | |
37 | qr/\QThe 'pos_int' parameter ("0") to main::validate1 did not pass the 'pos_int' callback: 0 is not a positive integer/, | |
38 | 'got error for bad pos int (0)' | |
39 | ); | |
40 | } | |
41 | ||
42 | { | |
43 | my $e = _test_args( | |
44 | pos_int => 'bar', | |
45 | string => 'foo', | |
46 | ); | |
47 | like( | |
48 | $e, | |
49 | qr/\QThe 'pos_int' parameter ("bar") to main::validate1 did not pass the 'pos_int' callback: bar is not a positive integer/, | |
50 | 'got error for bad pos int (bar)' | |
51 | ); | |
52 | } | |
53 | ||
54 | { | |
55 | my $e = do { | |
56 | local $@; | |
57 | eval { validate2( string => [] ); }; | |
58 | $@; | |
59 | }; | |
60 | ||
61 | is_deeply( | |
62 | $e, | |
63 | { error => 'not a string' }, | |
64 | 'ref thrown by callback is preserved, not stringified' | |
65 | ); | |
66 | } | |
67 | ||
68 | sub _test_args { | |
69 | local $@; | |
70 | eval { validate1(@_) }; | |
71 | return $@; | |
72 | } | |
73 | ||
74 | sub validate1 { | |
75 | validate( | |
76 | @_, { | |
77 | pos_int => { | |
78 | callbacks => { | |
79 | pos_int => sub { | |
80 | $_[0] =~ /^[1-9][0-9]*$/ | |
81 | or die "$_[0] is not a positive integer\n"; | |
82 | }, | |
83 | }, | |
84 | }, | |
85 | string => { | |
86 | callbacks => { | |
87 | string => sub { | |
88 | ( defined $_[0] && !ref $_[0] && length $_[0] ) | |
89 | or die "$_[0] is not a string\n"; | |
90 | }, | |
91 | }, | |
92 | }, | |
93 | } | |
94 | ); | |
95 | } | |
96 | ||
97 | sub validate2 { | |
98 | validate( | |
99 | @_, { | |
100 | string => { | |
101 | callbacks => { | |
102 | string => sub { | |
103 | ( defined $_[0] && !ref $_[0] && length $_[0] ) | |
104 | or die { error => 'not a string' }; | |
105 | }, | |
106 | }, | |
107 | }, | |
108 | } | |
109 | ); | |
110 | } | |
111 | ||
112 | done_testing(); |
0 | ||
1 | BEGIN { | |
2 | unless ($ENV{AUTHOR_TESTING}) { | |
3 | require Test::More; | |
4 | Test::More::plan(skip_all => 'these tests are for testing by the author'); | |
5 | } | |
6 | } | |
7 | ||
8 | use strict; | |
9 | use warnings; | |
10 | ||
11 | # this test was generated with Dist::Zilla::Plugin::Test::EOL 0.17 | |
12 | ||
13 | use Test::More 0.88; | |
14 | use Test::EOL; | |
15 | ||
16 | my @files = ( | |
17 | 'lib/Attribute/Params/Validate.pm', | |
18 | 'lib/Params/Validate.pm', | |
19 | 'lib/Params/Validate/Constants.pm', | |
20 | 'lib/Params/Validate/PP.pm', | |
21 | 'lib/Params/Validate/XS.pm', | |
22 | 'lib/Params/ValidatePP.pm', | |
23 | 'lib/Params/ValidateXS.pm', | |
24 | 't/00-compile.t', | |
25 | 't/00-report-prereqs.dd', | |
26 | 't/00-report-prereqs.t', | |
27 | 't/01-validate.t', | |
28 | 't/02-noop.t', | |
29 | 't/03-attribute.t', | |
30 | 't/04-defaults.t', | |
31 | 't/05-noop_default.t', | |
32 | 't/06-options.t', | |
33 | 't/07-with.t', | |
34 | 't/08-noop_with.t', | |
35 | 't/09-regex.t', | |
36 | 't/10-noop_regex.t', | |
37 | 't/11-cb.t', | |
38 | 't/12-noop_cb.t', | |
39 | 't/13-taint.t', | |
40 | 't/14-no_validate.t', | |
41 | 't/15-case.t', | |
42 | 't/16-normalize.t', | |
43 | 't/17-callbacks.t', | |
44 | 't/18-depends.t', | |
45 | 't/19-untaint.t', | |
46 | 't/21-can.t', | |
47 | 't/22-overload-can-bug.t', | |
48 | 't/23-readonly.t', | |
49 | 't/24-tied.t', | |
50 | 't/25-undef-regex.t', | |
51 | 't/26-isa.t', | |
52 | 't/27-string-as-type.t', | |
53 | 't/28-readonly-return.t', | |
54 | 't/29-taint-mode.t', | |
55 | 't/30-hashref-alteration.t', | |
56 | 't/31-incorrect-spelling.t', | |
57 | 't/32-regex-as-value.t', | |
58 | 't/33-keep-errsv.t', | |
59 | 't/34-recursive-validation.t', | |
60 | 't/35-default-xs-bug.t', | |
61 | 't/36-large-arrays.t', | |
62 | 't/37-exports.t', | |
63 | 't/38-callback-message.t', | |
64 | 't/author-eol.t', | |
65 | 't/author-no-tabs.t', | |
66 | 't/author-pod-spell.t', | |
67 | 't/lib/PVTests.pm', | |
68 | 't/lib/PVTests/Callbacks.pm', | |
69 | 't/lib/PVTests/Defaults.pm', | |
70 | 't/lib/PVTests/Regex.pm', | |
71 | 't/lib/PVTests/Standard.pm', | |
72 | 't/lib/PVTests/With.pm', | |
73 | 't/release-cpan-changes.t', | |
74 | 't/release-memory-leak.t', | |
75 | 't/release-pod-coverage.t', | |
76 | 't/release-pod-linkcheck.t', | |
77 | 't/release-pod-no404s.t', | |
78 | 't/release-pod-syntax.t', | |
79 | 't/release-portability.t', | |
80 | 't/release-pp-01-validate.t', | |
81 | 't/release-pp-02-noop.t', | |
82 | 't/release-pp-03-attribute.t', | |
83 | 't/release-pp-04-defaults.t', | |
84 | 't/release-pp-05-noop_default.t', | |
85 | 't/release-pp-06-options.t', | |
86 | 't/release-pp-07-with.t', | |
87 | 't/release-pp-08-noop_with.t', | |
88 | 't/release-pp-09-regex.t', | |
89 | 't/release-pp-10-noop_regex.t', | |
90 | 't/release-pp-11-cb.t', | |
91 | 't/release-pp-12-noop_cb.t', | |
92 | 't/release-pp-13-taint.t', | |
93 | 't/release-pp-14-no_validate.t', | |
94 | 't/release-pp-15-case.t', | |
95 | 't/release-pp-16-normalize.t', | |
96 | 't/release-pp-17-callbacks.t', | |
97 | 't/release-pp-18-depends.t', | |
98 | 't/release-pp-19-untaint.t', | |
99 | 't/release-pp-21-can.t', | |
100 | 't/release-pp-22-overload-can-bug.t', | |
101 | 't/release-pp-23-readonly.t', | |
102 | 't/release-pp-24-tied.t', | |
103 | 't/release-pp-25-undef-regex.t', | |
104 | 't/release-pp-26-isa.t', | |
105 | 't/release-pp-27-string-as-type.t', | |
106 | 't/release-pp-28-readonly-return.t', | |
107 | 't/release-pp-29-taint-mode.t', | |
108 | 't/release-pp-30-hashref-alteration.t', | |
109 | 't/release-pp-31-incorrect-spelling.t', | |
110 | 't/release-pp-32-regex-as-value.t', | |
111 | 't/release-pp-33-keep-errsv.t', | |
112 | 't/release-pp-34-recursive-validation.t', | |
113 | 't/release-pp-35-default-xs-bug.t', | |
114 | 't/release-pp-36-large-arrays.t', | |
115 | 't/release-pp-37-exports.t', | |
116 | 't/release-pp-38-callback-message.t', | |
117 | 't/release-pp-is-loaded.t', | |
118 | 't/release-synopsis.t', | |
119 | 't/release-test-version.t', | |
120 | 't/release-xs-is-loaded.t', | |
121 | 't/release-xs-segfault.t' | |
122 | ); | |
123 | ||
124 | eol_unix_ok($_, { trailing_whitespace => 1 }) foreach @files; | |
125 | done_testing; |
0 | ||
1 | BEGIN { | |
2 | unless ($ENV{AUTHOR_TESTING}) { | |
3 | require Test::More; | |
4 | Test::More::plan(skip_all => 'these tests are for testing by the author'); | |
5 | } | |
6 | } | |
7 | ||
8 | use strict; | |
9 | use warnings; | |
10 | ||
11 | # this test was generated with Dist::Zilla::Plugin::Test::NoTabs 0.13 | |
12 | ||
13 | use Test::More 0.88; | |
14 | use Test::NoTabs; | |
15 | ||
16 | my @files = ( | |
17 | 'lib/Attribute/Params/Validate.pm', | |
18 | 'lib/Params/Validate.pm', | |
19 | 'lib/Params/Validate/Constants.pm', | |
20 | 'lib/Params/Validate/PP.pm', | |
21 | 'lib/Params/Validate/XS.pm', | |
22 | 'lib/Params/ValidatePP.pm', | |
23 | 'lib/Params/ValidateXS.pm', | |
24 | 't/00-compile.t', | |
25 | 't/00-report-prereqs.dd', | |
26 | 't/00-report-prereqs.t', | |
27 | 't/01-validate.t', | |
28 | 't/02-noop.t', | |
29 | 't/03-attribute.t', | |
30 | 't/04-defaults.t', | |
31 | 't/05-noop_default.t', | |
32 | 't/06-options.t', | |
33 | 't/07-with.t', | |
34 | 't/08-noop_with.t', | |
35 | 't/09-regex.t', | |
36 | 't/10-noop_regex.t', | |
37 | 't/11-cb.t', | |
38 | 't/12-noop_cb.t', | |
39 | 't/13-taint.t', | |
40 | 't/14-no_validate.t', | |
41 | 't/15-case.t', | |
42 | 't/16-normalize.t', | |
43 | 't/17-callbacks.t', | |
44 | 't/18-depends.t', | |
45 | 't/19-untaint.t', | |
46 | 't/21-can.t', | |
47 | 't/22-overload-can-bug.t', | |
48 | 't/23-readonly.t', | |
49 | 't/24-tied.t', | |
50 | 't/25-undef-regex.t', | |
51 | 't/26-isa.t', | |
52 | 't/27-string-as-type.t', | |
53 | 't/28-readonly-return.t', | |
54 | 't/29-taint-mode.t', | |
55 | 't/30-hashref-alteration.t', | |
56 | 't/31-incorrect-spelling.t', | |
57 | 't/32-regex-as-value.t', | |
58 | 't/33-keep-errsv.t', | |
59 | 't/34-recursive-validation.t', | |
60 | 't/35-default-xs-bug.t', | |
61 | 't/36-large-arrays.t', | |
62 | 't/37-exports.t', | |
63 | 't/38-callback-message.t', | |
64 | 't/author-eol.t', | |
65 | 't/author-no-tabs.t', | |
66 | 't/author-pod-spell.t', | |
67 | 't/lib/PVTests.pm', | |
68 | 't/lib/PVTests/Callbacks.pm', | |
69 | 't/lib/PVTests/Defaults.pm', | |
70 | 't/lib/PVTests/Regex.pm', | |
71 | 't/lib/PVTests/Standard.pm', | |
72 | 't/lib/PVTests/With.pm', | |
73 | 't/release-cpan-changes.t', | |
74 | 't/release-memory-leak.t', | |
75 | 't/release-pod-coverage.t', | |
76 | 't/release-pod-linkcheck.t', | |
77 | 't/release-pod-no404s.t', | |
78 | 't/release-pod-syntax.t', | |
79 | 't/release-portability.t', | |
80 | 't/release-pp-01-validate.t', | |
81 | 't/release-pp-02-noop.t', | |
82 | 't/release-pp-03-attribute.t', | |
83 | 't/release-pp-04-defaults.t', | |
84 | 't/release-pp-05-noop_default.t', | |
85 | 't/release-pp-06-options.t', | |
86 | 't/release-pp-07-with.t', | |
87 | 't/release-pp-08-noop_with.t', | |
88 | 't/release-pp-09-regex.t', | |
89 | 't/release-pp-10-noop_regex.t', | |
90 | 't/release-pp-11-cb.t', | |
91 | 't/release-pp-12-noop_cb.t', | |
92 | 't/release-pp-13-taint.t', | |
93 | 't/release-pp-14-no_validate.t', | |
94 | 't/release-pp-15-case.t', | |
95 | 't/release-pp-16-normalize.t', | |
96 | 't/release-pp-17-callbacks.t', | |
97 | 't/release-pp-18-depends.t', | |
98 | 't/release-pp-19-untaint.t', | |
99 | 't/release-pp-21-can.t', | |
100 | 't/release-pp-22-overload-can-bug.t', | |
101 | 't/release-pp-23-readonly.t', | |
102 | 't/release-pp-24-tied.t', | |
103 | 't/release-pp-25-undef-regex.t', | |
104 | 't/release-pp-26-isa.t', | |
105 | 't/release-pp-27-string-as-type.t', | |
106 | 't/release-pp-28-readonly-return.t', | |
107 | 't/release-pp-29-taint-mode.t', | |
108 | 't/release-pp-30-hashref-alteration.t', | |
109 | 't/release-pp-31-incorrect-spelling.t', | |
110 | 't/release-pp-32-regex-as-value.t', | |
111 | 't/release-pp-33-keep-errsv.t', | |
112 | 't/release-pp-34-recursive-validation.t', | |
113 | 't/release-pp-35-default-xs-bug.t', | |
114 | 't/release-pp-36-large-arrays.t', | |
115 | 't/release-pp-37-exports.t', | |
116 | 't/release-pp-38-callback-message.t', | |
117 | 't/release-pp-is-loaded.t', | |
118 | 't/release-synopsis.t', | |
119 | 't/release-test-version.t', | |
120 | 't/release-xs-is-loaded.t', | |
121 | 't/release-xs-segfault.t' | |
122 | ); | |
123 | ||
124 | notabs_ok($_) foreach @files; | |
125 | done_testing; |
0 | ||
1 | BEGIN { | |
2 | unless ($ENV{AUTHOR_TESTING}) { | |
3 | require Test::More; | |
4 | Test::More::plan(skip_all => 'these tests are for testing by the author'); | |
5 | } | |
6 | } | |
7 | ||
8 | use strict; | |
9 | use warnings; | |
10 | use Test::More; | |
11 | ||
12 | # generated by Dist::Zilla::Plugin::Test::PodSpelling 2.006008 | |
13 | use Test::Spelling 0.12; | |
14 | use Pod::Wordlist; | |
15 | ||
16 | ||
17 | add_stopwords(<DATA>); | |
18 | all_pod_files_spelling_ok( qw( bin lib ) ); | |
19 | __DATA__ | |
20 | DROLSKY | |
21 | DROLSKY's | |
22 | Rolsky | |
23 | Rolsky's | |
24 | API | |
25 | CPAN | |
26 | GLOBREF | |
27 | OO | |
28 | PayPal | |
29 | SCALARREF | |
30 | ValidatePos | |
31 | baz | |
32 | onwards | |
33 | pre | |
34 | runtime | |
35 | Dave | |
36 | autarch | |
37 | Ilya | |
38 | Martynov | |
39 | ilya | |
40 | and | |
41 | Mash | |
42 | jmash | |
43 | Olivier | |
44 | Mengué | |
45 | dolmen | |
46 | lib | |
47 | Attribute | |
48 | Params | |
49 | Validate | |
50 | Constants | |
51 | PP | |
52 | XS | |
53 | ValidatePP | |
54 | ValidateXS |
156 | 156 | sub bar { |
157 | 157 | my @params = ( 1, 2 ); |
158 | 158 | |
159 | return validate_pos( @params, 1, { default => 99 }, { default => 42 }, | |
160 | { default => 0 } ); | |
159 | return validate_pos( | |
160 | @params, 1, { default => 99 }, { default => 42 }, | |
161 | { default => 0 } | |
162 | ); | |
161 | 163 | } |
162 | 164 | |
163 | 165 | 1; |
672 | 672 | |
673 | 673 | if ( eval { %{ $test->{return} } } ) { |
674 | 674 | my %r = @r; |
675 | is_deeply( \%r, $test->{return}, | |
676 | "check return value for $sub - hash" ); | |
675 | is_deeply( | |
676 | \%r, $test->{return}, | |
677 | "check return value for $sub - hash" | |
678 | ); | |
677 | 679 | } |
678 | 680 | else { |
679 | is_deeply( \@r, $test->{return}, | |
680 | "check return value for $sub - array" ); | |
681 | is_deeply( | |
682 | \@r, $test->{return}, | |
683 | "check return value for $sub - array" | |
684 | ); | |
681 | 685 | } |
682 | 686 | } |
683 | 687 |
7 | 7 | } |
8 | 8 | |
9 | 9 | |
10 | use Test::More; | |
11 | eval 'use Test::CPAN::Changes'; | |
12 | plan skip_all => 'Test::CPAN::Changes required for this test' if $@; | |
13 | changes_ok(); | |
10 | use strict; | |
11 | use warnings; | |
12 | ||
13 | use Test::More 0.96 tests => 2; | |
14 | use_ok('Test::CPAN::Changes'); | |
15 | subtest 'changes_ok' => sub { | |
16 | changes_file_ok('Changes'); | |
17 | }; | |
14 | 18 | done_testing(); |
0 | ||
1 | BEGIN { | |
2 | unless ($ENV{RELEASE_TESTING}) { | |
3 | require Test::More; | |
4 | Test::More::plan(skip_all => 'these tests are for release candidate testing'); | |
5 | } | |
6 | } | |
7 | ||
8 | use strict; | |
9 | use warnings; | |
10 | use Test::More; | |
11 | ||
12 | eval 'use Test::EOL'; | |
13 | plan skip_all => 'Test::EOL required' if $@; | |
14 | ||
15 | all_perl_files_ok({ trailing_whitespace => 1 }); |
0 | ||
1 | BEGIN { | |
2 | unless ($ENV{RELEASE_TESTING}) { | |
3 | require Test::More; | |
4 | Test::More::plan(skip_all => 'these tests are for release candidate testing'); | |
5 | } | |
6 | } | |
7 | ||
8 | use strict; | |
9 | use warnings; | |
10 | ||
11 | use Test::More; | |
12 | ||
13 | BEGIN { | |
14 | plan skip_all => q{Test::LeakTrace doesn't install with blead (as of 5.21.8)} | |
15 | if $] >= 5.021008; | |
16 | } | |
17 | ||
18 | use Test::LeakTrace qw( no_leaks_ok ); | |
19 | ||
20 | use Params::Validate qw( validate ); | |
21 | ||
22 | subtest( | |
23 | 'callback with default error' => sub { | |
24 | no_leaks_ok( sub { val1( foo => 42 ); }, 'validation passes' ); | |
25 | local $TODO = 'Not sure if all the leaks are in Carp or not'; | |
26 | no_leaks_ok( | |
27 | sub { | |
28 | eval { val1( foo => 'forty two' ) }; | |
29 | }, | |
30 | 'validation fails' | |
31 | ); | |
32 | }, | |
33 | ); | |
34 | ||
35 | subtest( | |
36 | 'callback that dies with string' => sub { | |
37 | no_leaks_ok( sub { val2( foo => 42 ); }, 'validation passes' ); | |
38 | local $TODO = 'Not sure if all the leaks are in Carp or not'; | |
39 | no_leaks_ok( | |
40 | sub { | |
41 | eval { val2( foo => 'forty two' ) }; | |
42 | }, | |
43 | 'validation fails' | |
44 | ); | |
45 | }, | |
46 | ); | |
47 | ||
48 | subtest( | |
49 | 'callback that dies with object' => sub { | |
50 | no_leaks_ok( sub { val3( foo => 42 ); }, 'validation passes' ); | |
51 | no_leaks_ok( | |
52 | sub { | |
53 | eval { val3( foo => 'forty two' ) }; | |
54 | }, | |
55 | 'validation fails' | |
56 | ); | |
57 | }, | |
58 | ); | |
59 | ||
60 | done_testing(); | |
61 | ||
62 | sub val1 { | |
63 | validate( | |
64 | @_, | |
65 | { | |
66 | foo => { | |
67 | callbacks => { | |
68 | 'is int' => sub { $_[0] =~ /^[0-9]+$/ } | |
69 | } | |
70 | }, | |
71 | }, | |
72 | ); | |
73 | } | |
74 | ||
75 | sub val2 { | |
76 | validate( | |
77 | @_, | |
78 | { | |
79 | foo => { | |
80 | callbacks => { | |
81 | 'is int' => sub { | |
82 | $_[0] =~ /^[0-9]+$/ or die "$_[0] is not an integer"; | |
83 | } | |
84 | } | |
85 | }, | |
86 | }, | |
87 | ); | |
88 | } | |
89 | ||
90 | sub val3 { | |
91 | validate( | |
92 | @_, | |
93 | { | |
94 | foo => { | |
95 | callbacks => { | |
96 | 'is int' => sub { | |
97 | $_[0] =~ /^[0-9]+$/ | |
98 | or die { error => "$_[0] is not an integer" }; | |
99 | } | |
100 | } | |
101 | }, | |
102 | }, | |
103 | ); | |
104 | } |
0 | ||
1 | BEGIN { | |
2 | unless ($ENV{RELEASE_TESTING}) { | |
3 | require Test::More; | |
4 | Test::More::plan(skip_all => 'these tests are for release candidate testing'); | |
5 | } | |
6 | } | |
7 | ||
8 | use strict; | |
9 | use warnings; | |
10 | ||
11 | # this test was generated with Dist::Zilla::Plugin::Test::NoTabs 0.07 | |
12 | ||
13 | use Test::More 0.88; | |
14 | use Test::NoTabs; | |
15 | ||
16 | my @files = ( | |
17 | 'lib/Attribute/Params/Validate.pm', | |
18 | 'lib/Params/Validate.pm', | |
19 | 'lib/Params/Validate/Constants.pm', | |
20 | 'lib/Params/Validate/PP.pm', | |
21 | 'lib/Params/Validate/XS.pm', | |
22 | 'lib/Params/ValidatePP.pm', | |
23 | 'lib/Params/ValidateXS.pm', | |
24 | 't/01-validate.t', | |
25 | 't/02-noop.t', | |
26 | 't/03-attribute.t', | |
27 | 't/04-defaults.t', | |
28 | 't/05-noop_default.t', | |
29 | 't/06-options.t', | |
30 | 't/07-with.t', | |
31 | 't/08-noop_with.t', | |
32 | 't/09-regex.t', | |
33 | 't/10-noop_regex.t', | |
34 | 't/11-cb.t', | |
35 | 't/12-noop_cb.t', | |
36 | 't/13-taint.t', | |
37 | 't/14-no_validate.t', | |
38 | 't/15-case.t', | |
39 | 't/16-normalize.t', | |
40 | 't/17-callbacks.t', | |
41 | 't/18-depends.t', | |
42 | 't/19-untaint.t', | |
43 | 't/21-can.t', | |
44 | 't/22-overload-can-bug.t', | |
45 | 't/23-readonly.t', | |
46 | 't/24-tied.t', | |
47 | 't/25-undef-regex.t', | |
48 | 't/26-isa.t', | |
49 | 't/27-string-as-type.t', | |
50 | 't/28-readonly-return.t', | |
51 | 't/29-taint-mode.t', | |
52 | 't/30-hashref-alteration.t', | |
53 | 't/31-incorrect-spelling.t', | |
54 | 't/32-regex-as-value.t', | |
55 | 't/33-keep-errsv.t', | |
56 | 't/34-recursive-validation.t', | |
57 | 't/35-default-xs-bug.t', | |
58 | 't/35-large-arrays.t', | |
59 | 't/lib/PVTests.pm', | |
60 | 't/lib/PVTests/Callbacks.pm', | |
61 | 't/lib/PVTests/Defaults.pm', | |
62 | 't/lib/PVTests/Regex.pm', | |
63 | 't/lib/PVTests/Standard.pm', | |
64 | 't/lib/PVTests/With.pm', | |
65 | 't/release-cpan-changes.t', | |
66 | 't/release-eol.t', | |
67 | 't/release-no-tabs.t', | |
68 | 't/release-pod-coverage.t', | |
69 | 't/release-pod-linkcheck.t', | |
70 | 't/release-pod-no404s.t', | |
71 | 't/release-pod-spell.t', | |
72 | 't/release-pod-syntax.t', | |
73 | 't/release-pp-01-validate.t', | |
74 | 't/release-pp-02-noop.t', | |
75 | 't/release-pp-03-attribute.t', | |
76 | 't/release-pp-04-defaults.t', | |
77 | 't/release-pp-05-noop_default.t', | |
78 | 't/release-pp-06-options.t', | |
79 | 't/release-pp-07-with.t', | |
80 | 't/release-pp-08-noop_with.t', | |
81 | 't/release-pp-09-regex.t', | |
82 | 't/release-pp-10-noop_regex.t', | |
83 | 't/release-pp-11-cb.t', | |
84 | 't/release-pp-12-noop_cb.t', | |
85 | 't/release-pp-13-taint.t', | |
86 | 't/release-pp-14-no_validate.t', | |
87 | 't/release-pp-15-case.t', | |
88 | 't/release-pp-16-normalize.t', | |
89 | 't/release-pp-17-callbacks.t', | |
90 | 't/release-pp-18-depends.t', | |
91 | 't/release-pp-19-untaint.t', | |
92 | 't/release-pp-21-can.t', | |
93 | 't/release-pp-22-overload-can-bug.t', | |
94 | 't/release-pp-23-readonly.t', | |
95 | 't/release-pp-24-tied.t', | |
96 | 't/release-pp-25-undef-regex.t', | |
97 | 't/release-pp-26-isa.t', | |
98 | 't/release-pp-27-string-as-type.t', | |
99 | 't/release-pp-28-readonly-return.t', | |
100 | 't/release-pp-29-taint-mode.t', | |
101 | 't/release-pp-30-hashref-alteration.t', | |
102 | 't/release-pp-31-incorrect-spelling.t', | |
103 | 't/release-pp-32-regex-as-value.t', | |
104 | 't/release-pp-33-keep-errsv.t', | |
105 | 't/release-pp-34-recursive-validation.t', | |
106 | 't/release-pp-35-default-xs-bug.t', | |
107 | 't/release-pp-35-large-arrays.t', | |
108 | 't/release-pp-is-loaded.t', | |
109 | 't/release-xs-is-loaded.t', | |
110 | 't/release-xs-segfault.t' | |
111 | ); | |
112 | ||
113 | notabs_ok($_) foreach @files; | |
114 | done_testing; |
0 | #!perl | |
0 | 1 | |
1 | 2 | BEGIN { |
2 | 3 | unless ($ENV{RELEASE_TESTING}) { |
5 | 6 | } |
6 | 7 | } |
7 | 8 | |
8 | use strict; | |
9 | use warnings; | |
9 | # This file was automatically generated by Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable. | |
10 | 10 | |
11 | use Test::More; | |
11 | use Test::Pod::Coverage 1.08; | |
12 | use Test::More 0.88; | |
12 | 13 | |
13 | eval "use Test::Pod::Coverage 1.04"; | |
14 | plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" | |
15 | if $@; | |
14 | BEGIN { | |
15 | if ( $] <= 5.008008 ) { | |
16 | plan skip_all => 'These tests require Pod::Coverage::TrustPod, which only works with Perl 5.8.9+'; | |
17 | } | |
18 | } | |
19 | use Pod::Coverage::TrustPod; | |
16 | 20 | |
17 | pod_coverage_ok( | |
18 | 'Params::Validate', { | |
19 | trustme => [ | |
20 | qr/(?:UNKNOWN|set_options|validate(?:_pos|_with)?|validation_options)/ | |
21 | ] | |
22 | } | |
23 | ); | |
21 | my %skip = map { $_ => 1 } qw( Params::Validate::Constants Params::Validate::PP Params::Validate::XS Params::ValidatePP Params::ValidateXS ); | |
22 | ||
23 | my @modules; | |
24 | for my $module ( all_modules() ) { | |
25 | next if $skip{$module}; | |
26 | ||
27 | push @modules, $module; | |
28 | } | |
29 | ||
30 | plan skip_all => 'All the modules we found were excluded from POD coverage test.' | |
31 | unless @modules; | |
32 | ||
33 | plan tests => scalar @modules; | |
34 | ||
35 | my %trustme = ( | |
36 | 'Params::Validate' => [ | |
37 | qr/^(?:UNKNOWN|set_options|validate(?:_pos|_with)?|validation_options)$/ | |
38 | ] | |
39 | ); | |
40 | ||
41 | for my $module ( sort @modules ) { | |
42 | pod_coverage_ok( | |
43 | $module, | |
44 | { | |
45 | coverage_class => 'Pod::Coverage::TrustPod', | |
46 | trustme => $trustme{$module} || [], | |
47 | }, | |
48 | "pod coverage for $module" | |
49 | ); | |
50 | } | |
24 | 51 | |
25 | 52 | done_testing(); |
0 | ||
1 | BEGIN { | |
2 | unless ($ENV{RELEASE_TESTING}) { | |
3 | require Test::More; | |
4 | Test::More::plan(skip_all => 'these tests are for release candidate testing'); | |
5 | } | |
6 | } | |
7 | ||
8 | use strict; | |
9 | use warnings; | |
10 | ||
11 | use Test::More; | |
12 | ||
13 | eval "use Test::Spelling"; | |
14 | plan skip_all => "Test::Spelling required for testing POD coverage" | |
15 | if $@; | |
16 | ||
17 | my @stopwords; | |
18 | for (<DATA>) { | |
19 | chomp; | |
20 | push @stopwords, $_ | |
21 | unless /\A (?: \# | \s* \z)/msx; # skip comments, whitespace | |
22 | } | |
23 | ||
24 | add_stopwords(@stopwords); | |
25 | set_spell_cmd('aspell list -l en'); | |
26 | ||
27 | # This prevents a weird segfault from the aspell command - see | |
28 | # https://bugs.launchpad.net/ubuntu/+source/aspell/+bug/71322 | |
29 | local $ENV{LC_ALL} = 'C'; | |
30 | all_pod_files_spelling_ok(); | |
31 | ||
32 | __DATA__ | |
33 | API | |
34 | CPAN | |
35 | GLOBREF | |
36 | Martynov | |
37 | OO | |
38 | PayPal | |
39 | Rolsky | |
40 | SCALARREF | |
41 | ValidatePos | |
42 | baz | |
43 | onwards | |
44 | pre | |
45 | runtime |
0 | #!perl | |
1 | ||
2 | BEGIN { | |
3 | unless ($ENV{RELEASE_TESTING}) { | |
4 | require Test::More; | |
5 | Test::More::plan(skip_all => 'these tests are for release candidate testing'); | |
6 | } | |
7 | } | |
8 | ||
9 | ||
10 | use strict; | |
11 | use warnings; | |
12 | ||
13 | use Test::More; | |
14 | ||
15 | eval 'use Test::Portability::Files'; | |
16 | plan skip_all => 'Test::Portability::Files required for testing portability' | |
17 | if $@; | |
18 | ||
19 | run_tests(); |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
65 | 65 | params => $arglist{$args}, |
66 | 66 | spec => $speclist{$spec}, |
67 | 67 | expect => ( |
68 | $ignore_case ? $ok_sub | |
68 | $ignore_case ? $ok_sub | |
69 | 69 | : $args eq $spec ? $ok_sub |
70 | : $nok_sub | |
70 | : $nok_sub | |
71 | 71 | ), |
72 | 72 | ignore_case => $ignore_case |
73 | 73 | }; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
53 | 53 | # positive, no depends (single, multiple) |
54 | 54 | my @args = ( bar => 1 ); |
55 | 55 | eval { validate( @args, \%spec ) }; |
56 | is( $@, q{}, | |
57 | "validate() multiple depends(1): no depends, single arg, positive" ); | |
56 | is( | |
57 | $@, q{}, | |
58 | "validate() multiple depends(1): no depends, single arg, positive" | |
59 | ); | |
58 | 60 | |
59 | 61 | @args = ( bar => 1, baz => 1 ); |
60 | 62 | eval { validate( @args, \%spec ) }; |
72 | 74 | @args = ( foo => 1, bar => 1 ); |
73 | 75 | eval { validate( @args, \%spec ) }; |
74 | 76 | |
75 | ok( $@, | |
77 | ok( | |
78 | $@, | |
76 | 79 | "validate() multiple depends(4.a): with depends, negative, multiple missing" |
77 | 80 | ); |
78 | 81 | like( |
84 | 87 | @args = ( foo => 1 ); |
85 | 88 | eval { validate( @args, \%spec ) }; |
86 | 89 | |
87 | ok( $@, | |
90 | ok( | |
91 | $@, | |
88 | 92 | "validate() multiple depends(5.a): with depends, negative, multiple missing" |
89 | 93 | ); |
90 | 94 | like( |
128 | 132 | my @args = qw(1 1); |
129 | 133 | eval { validate_pos( @args, @spec ) }; |
130 | 134 | |
131 | is( $@, q{}, | |
132 | "validate_pos() single depends (1): with depends, positive" ); | |
135 | is( | |
136 | $@, q{}, | |
137 | "validate_pos() single depends (1): with depends, positive" | |
138 | ); | |
133 | 139 | } |
134 | 140 | |
135 | 141 | { |
159 | 165 | my @args = qw(1); |
160 | 166 | eval { validate_pos( @args, @spec ) }; |
161 | 167 | |
162 | ok( $@, | |
168 | ok( | |
169 | $@, | |
163 | 170 | "validate_pos() multiple depends (1.a): with depends, bad args negative" |
164 | 171 | ); |
165 | 172 | like( |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
16 | 16 | use Test::More; |
17 | 17 | |
18 | 18 | { |
19 | ||
20 | 19 | package Overloaded; |
21 | 20 | |
22 | 21 | use overload 'bool' => sub {0}; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
16 | 16 | use Test::More; |
17 | 17 | |
18 | 18 | { |
19 | ||
20 | 19 | package Tie::SimpleArray; |
21 | 20 | use Tie::Array; |
22 | 21 | use base 'Tie::StdArray'; |
37 | 36 | |
38 | 37 | eval { validate( @p, \%spec ) }; |
39 | 38 | warn $@ if $@; |
40 | is( $@, q{}, | |
39 | is( | |
40 | $@, q{}, | |
41 | 41 | 'validate() call succeeded with tied params array and regular hashref spec' |
42 | 42 | ); |
43 | 43 | } |
54 | 54 | |
55 | 55 | eval { validate( @p, \%spec ) }; |
56 | 56 | warn $@ if $@; |
57 | is( $@, q{}, | |
57 | is( | |
58 | $@, q{}, | |
58 | 59 | 'validate() call succeeded with regular params array and tied hashref spec' |
59 | 60 | ); |
60 | 61 | } |
71 | 72 | |
72 | 73 | eval { validate( @p, \%spec ) }; |
73 | 74 | warn $@ if $@; |
74 | is( $@, q{}, | |
75 | is( | |
76 | $@, q{}, | |
75 | 77 | 'validate() call succeeded with tied params array and tied hashref spec' |
76 | 78 | ); |
77 | 79 | } |
85 | 87 | |
86 | 88 | eval { validate_pos( @p, \%spec ) }; |
87 | 89 | warn $@ if $@; |
88 | is( $@, q{}, | |
90 | is( | |
91 | $@, q{}, | |
89 | 92 | 'validate_pos() call succeeded with tied params array and regular hashref spec' |
90 | 93 | ); |
91 | 94 | } |
102 | 105 | |
103 | 106 | eval { validate_pos( @p, \%spec ) }; |
104 | 107 | warn $@ if $@; |
105 | is( $@, q{}, | |
108 | is( | |
109 | $@, q{}, | |
106 | 110 | 'validate_pos() call succeeded with regular params array and tied hashref spec' |
107 | 111 | ); |
108 | 112 | } |
119 | 123 | |
120 | 124 | eval { validate_pos( @p, \%spec ) }; |
121 | 125 | warn $@ if $@; |
122 | is( $@, q{}, | |
126 | is( | |
127 | $@, q{}, | |
123 | 128 | 'validate_pos() call succeeded with tied params array and tied hashref spec' |
124 | 129 | ); |
125 | 130 | } |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
20 | 20 | |
21 | 21 | eval { validate( @p, { foo => { type => 'SCALAR' } }, ); }; |
22 | 22 | |
23 | like( $@, | |
23 | like( | |
24 | $@, | |
24 | 25 | qr/\QThe 'foo' parameter ("1") has a type specification which is not a number. It is a string - SCALAR/ |
25 | 26 | ); |
26 | 27 | } |
30 | 31 | |
31 | 32 | eval { validate( @p, { foo => { type => undef } }, ); }; |
32 | 33 | |
33 | like( $@, | |
34 | like( | |
35 | $@, | |
34 | 36 | qr/\QThe 'foo' parameter ("1") has a type specification which is not a number. It is undef/ |
35 | 37 | ); |
36 | 38 |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
40 | 40 | |
41 | 41 | sub v { |
42 | 42 | validate( |
43 | @_, | |
44 | { | |
43 | @_, { | |
45 | 44 | foo => { type => SCALAR | SCALARREF }, |
46 | 45 | }, |
47 | 46 | ); |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
39 | 39 | # catch die signal |
40 | 40 | local $SIG{__DIE__} = sub { |
41 | 41 | |
42 | # we died from within Params::Validate (because of wrong_Arg) we call | |
43 | # Foo::test_foo with OK args, but it'll die, because | |
44 | # Params::ValidatePP::options is still set to the options of the Bar | |
45 | # package, and so it won't retreive the one from Foo. | |
42 | # we died from within Params::Validate (because of wrong_Arg) we | |
43 | # call Foo::test_foo with OK args, but it'll die, because | |
44 | # Params::Validate::PP::options is still set to the options of the | |
45 | # Bar package, and so it won't retreive the one from Foo. | |
46 | 46 | Foo::test_foo( arg1 => 1, extra_arg => 2 ); |
47 | 47 | }; |
48 | 48 |
3 | 3 | |
4 | 4 | BEGIN { |
5 | 5 | unless ( $ENV{RELEASE_TESTING} ) { |
6 | plan skip_all => 'these tests are for testing by the release'; | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | $ENV{PV_TEST_PERL} = 1; |
0 | ||
1 | ||
2 | use Test::More; | |
3 | ||
4 | BEGIN { | |
5 | unless ( $ENV{RELEASE_TESTING} ) { | |
6 | plan skip_all => 'these tests are for testing by the release'; | |
7 | } | |
8 | ||
9 | $ENV{PV_TEST_PERL} = 1; | |
10 | } | |
11 | ||
12 | use strict; | |
13 | use warnings; | |
14 | ||
15 | use Test::Fatal; | |
16 | use Test::More; | |
17 | ||
18 | { | |
19 | package Foo; | |
20 | ||
21 | use Params::Validate qw( validate ARRAYREF ); | |
22 | ||
23 | sub v1 { | |
24 | my %p = validate( | |
25 | @_, | |
26 | { | |
27 | array => { | |
28 | callbacks => { | |
29 | 'checking array contents' => sub { | |
30 | for my $x ( @{ $_[0] } ) { | |
31 | return 0 unless defined $x && !ref $x; | |
32 | } | |
33 | return 1; | |
34 | }, | |
35 | } | |
36 | } | |
37 | } | |
38 | ); | |
39 | return $p{array}; | |
40 | } | |
41 | } | |
42 | ||
43 | { | |
44 | for my $size ( 100, 1_000, 100_000 ) { | |
45 | my @array = ('x') x $size; | |
46 | is_deeply( | |
47 | Foo::v1( array => \@array ), | |
48 | \@array, | |
49 | "validate() handles $size element array correctly" | |
50 | ); | |
51 | } | |
52 | } | |
53 | ||
54 | done_testing(); | |
55 |
0 | ||
1 | ||
2 | use Test::More; | |
3 | ||
4 | BEGIN { | |
5 | unless ( $ENV{RELEASE_TESTING} ) { | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | } | |
8 | ||
9 | $ENV{PV_TEST_PERL} = 1; | |
10 | } | |
11 | ||
12 | use strict; | |
13 | use warnings; | |
14 | ||
15 | use Test::Fatal; | |
16 | use Test::More; | |
17 | ||
18 | { | |
19 | package Foo; | |
20 | ||
21 | use Params::Validate qw( validate ARRAYREF ); | |
22 | ||
23 | sub v1 { | |
24 | my %p = validate( | |
25 | @_, { | |
26 | array => { | |
27 | callbacks => { | |
28 | 'checking array contents' => sub { | |
29 | for my $x ( @{ $_[0] } ) { | |
30 | return 0 unless defined $x && !ref $x; | |
31 | } | |
32 | return 1; | |
33 | }, | |
34 | } | |
35 | } | |
36 | } | |
37 | ); | |
38 | return $p{array}; | |
39 | } | |
40 | } | |
41 | ||
42 | { | |
43 | for my $size ( 100, 1_000, 100_000 ) { | |
44 | my @array = ('x') x $size; | |
45 | is_deeply( | |
46 | Foo::v1( array => \@array ), | |
47 | \@array, | |
48 | "validate() handles $size element array correctly" | |
49 | ); | |
50 | } | |
51 | } | |
52 | ||
53 | done_testing(); | |
54 |
0 | ||
1 | ||
2 | use Test::More; | |
3 | ||
4 | BEGIN { | |
5 | unless ( $ENV{RELEASE_TESTING} ) { | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | } | |
8 | ||
9 | $ENV{PV_TEST_PERL} = 1; | |
10 | } | |
11 | ||
12 | use strict; | |
13 | use warnings; | |
14 | ||
15 | use Test::More; | |
16 | use Params::Validate (); | |
17 | ||
18 | my @types = qw( | |
19 | SCALAR | |
20 | ARRAYREF | |
21 | HASHREF | |
22 | CODEREF | |
23 | GLOB | |
24 | GLOBREF | |
25 | SCALARREF | |
26 | HANDLE | |
27 | BOOLEAN | |
28 | UNDEF | |
29 | OBJECT | |
30 | ); | |
31 | ||
32 | my @subs = qw( | |
33 | validate | |
34 | validate_pos | |
35 | validation_options | |
36 | validate_with | |
37 | ); | |
38 | ||
39 | is_deeply( | |
40 | [ sort @Params::Validate::EXPORT_OK ], | |
41 | [ sort @types, @subs, 'set_options' ], | |
42 | '@EXPORT_OK' | |
43 | ); | |
44 | ||
45 | is_deeply( | |
46 | [ sort keys %Params::Validate::EXPORT_TAGS ], | |
47 | [qw( all types )], | |
48 | 'keys %EXPORT_TAGS' | |
49 | ); | |
50 | ||
51 | is_deeply( | |
52 | [ sort @{ $Params::Validate::EXPORT_TAGS{all} } ], | |
53 | [ sort @types, @subs ], | |
54 | '$EXPORT_TAGS{all}', | |
55 | ); | |
56 | ||
57 | is_deeply( | |
58 | [ sort @{ $Params::Validate::EXPORT_TAGS{types} } ], | |
59 | [ sort @types ], | |
60 | '$EXPORT_TAGS{types}', | |
61 | ); | |
62 | ||
63 | done_testing(); | |
64 |
0 | ||
1 | ||
2 | use Test::More; | |
3 | ||
4 | BEGIN { | |
5 | unless ( $ENV{RELEASE_TESTING} ) { | |
6 | plan skip_all => 'these tests are for release testing'; | |
7 | } | |
8 | ||
9 | $ENV{PV_TEST_PERL} = 1; | |
10 | } | |
11 | ||
12 | use strict; | |
13 | use warnings; | |
14 | ||
15 | use Test::More; | |
16 | use Params::Validate qw( validate ); | |
17 | ||
18 | { | |
19 | my $e = _test_args( | |
20 | pos_int => 42, | |
21 | string => 'foo', | |
22 | ); | |
23 | is( | |
24 | $e, | |
25 | q{}, | |
26 | 'no error with good args' | |
27 | ); | |
28 | } | |
29 | ||
30 | { | |
31 | my $e = _test_args( | |
32 | pos_int => 42, | |
33 | string => [], | |
34 | ); | |
35 | like( | |
36 | $e, | |
37 | qr/The 'string' parameter \("ARRAY\(.+\)"\) to main::validate1 did not pass the 'string' callback: ARRAY\(.+\) is not a string/, | |
38 | 'got error for bad string' | |
39 | ); | |
40 | } | |
41 | ||
42 | { | |
43 | my $e = _test_args( | |
44 | pos_int => 0, | |
45 | string => 'foo', | |
46 | ); | |
47 | like( | |
48 | $e, | |
49 | qr/\QThe 'pos_int' parameter ("0") to main::validate1 did not pass the 'pos_int' callback: 0 is not a positive integer/, | |
50 | 'got error for bad pos int (0)' | |
51 | ); | |
52 | } | |
53 | ||
54 | { | |
55 | my $e = _test_args( | |
56 | pos_int => 'bar', | |
57 | string => 'foo', | |
58 | ); | |
59 | like( | |
60 | $e, | |
61 | qr/\QThe 'pos_int' parameter ("bar") to main::validate1 did not pass the 'pos_int' callback: bar is not a positive integer/, | |
62 | 'got error for bad pos int (bar)' | |
63 | ); | |
64 | } | |
65 | ||
66 | { | |
67 | my $e = do { | |
68 | local $@; | |
69 | eval { validate2( string => [] ); }; | |
70 | $@; | |
71 | }; | |
72 | ||
73 | is_deeply( | |
74 | $e, | |
75 | { error => 'not a string' }, | |
76 | 'ref thrown by callback is preserved, not stringified' | |
77 | ); | |
78 | } | |
79 | ||
80 | sub _test_args { | |
81 | local $@; | |
82 | eval { validate1(@_) }; | |
83 | return $@; | |
84 | } | |
85 | ||
86 | sub validate1 { | |
87 | validate( | |
88 | @_, { | |
89 | pos_int => { | |
90 | callbacks => { | |
91 | pos_int => sub { | |
92 | $_[0] =~ /^[1-9][0-9]*$/ | |
93 | or die "$_[0] is not a positive integer\n"; | |
94 | }, | |
95 | }, | |
96 | }, | |
97 | string => { | |
98 | callbacks => { | |
99 | string => sub { | |
100 | ( defined $_[0] && !ref $_[0] && length $_[0] ) | |
101 | or die "$_[0] is not a string\n"; | |
102 | }, | |
103 | }, | |
104 | }, | |
105 | } | |
106 | ); | |
107 | } | |
108 | ||
109 | sub validate2 { | |
110 | validate( | |
111 | @_, { | |
112 | string => { | |
113 | callbacks => { | |
114 | string => sub { | |
115 | ( defined $_[0] && !ref $_[0] && length $_[0] ) | |
116 | or die { error => 'not a string' }; | |
117 | }, | |
118 | }, | |
119 | }, | |
120 | } | |
121 | ); | |
122 | } | |
123 | ||
124 | done_testing(); | |
125 |
0 | #!perl | |
1 | ||
2 | BEGIN { | |
3 | unless ($ENV{RELEASE_TESTING}) { | |
4 | require Test::More; | |
5 | Test::More::plan(skip_all => 'these tests are for release candidate testing'); | |
6 | } | |
7 | } | |
8 | ||
9 | ||
10 | use Test::Synopsis; | |
11 | ||
12 | all_synopsis_ok(); |
0 | ||
1 | BEGIN { | |
2 | unless ($ENV{RELEASE_TESTING}) { | |
3 | require Test::More; | |
4 | Test::More::plan(skip_all => 'these tests are for release candidate testing'); | |
5 | } | |
6 | } | |
7 | ||
8 | use strict; | |
9 | use warnings; | |
10 | use Test::More; | |
11 | ||
12 | # generated by Dist::Zilla::Plugin::Test::Version 0.003001 | |
13 | use Test::Version; | |
14 | ||
15 | my @imports = ( 'version_all_ok' ); | |
16 | ||
17 | my $params = { | |
18 | is_strict => 1, | |
19 | has_version => 1, | |
20 | }; | |
21 | ||
22 | push @imports, $params | |
23 | if version->parse( $Test::Version::VERSION ) >= version->parse('1.002'); | |
24 | ||
25 | ||
26 | Test::Version->import(@imports); | |
27 | ||
28 | version_all_ok; | |
29 | done_testing; |
0 | [PerlTidy] | |
1 | select = **/*.{pl,pm,t,psgi} | |
2 | ignore = t/00-* | |
3 | ignore = t/author-* | |
4 | ignore = t/release-* | |
5 | ignore = blib/**/* | |
6 | ignore = .build/**/* | |
7 | ignore = Params-Validate-*/**/* | |
8 | argv = --profile=$ROOT/perltidyrc | |
9 | ||
10 | [PerlCritic] | |
11 | select = **/*.{pl,pm,t,psgi} | |
12 | ignore = t/00-* | |
13 | ignore = t/author-* | |
14 | ignore = t/release-* | |
15 | ignore = blib/**/* | |
16 | ignore = .build/**/* | |
17 | ignore = Params-Validate-*/**/* | |
18 | argv = --profile $ROOT/perlcriticrc --program-extensions .pl --program-extensions .t --program-extensions .psgi |