Codebase list libdata-formvalidator-perl / upstream/4.88
New upstream version 4.88 Damyan Ivanov 6 years ago
84 changed file(s) with 4326 addition(s) and 3111 deletion(s). Raw diff Collapse all Expand all
+0
-66
Build.PL less more
0 shift(@ARGV) if $ARGV[0] eq 'Build'; # accomodate with CPAN autoinstall
1 use Module::Build;
2
3 my $class = Module::Build->subclass(
4 class => 'Data::FormValidator::Builder',
5 code => q{
6 sub ACTION_dist {
7 my $self = shift;
8 `perldoc -t lib/Data/FormValidator.pm>README`;
9 $self->SUPER::ACTION_dist;
10 }
11
12 sub ACTION_cover {
13 my $self = shift;
14 $self->depends_on('build');
15
16 system qw( cover -delete );
17
18 # sometimes we get failing tests, which makes Test::Harness
19 # die. catch that
20 eval {
21 local $ENV{PERL5OPT} = "-MDevel::Cover=-summary,0";
22 $self->ACTION_test(@_);
23 };
24 system qw( cover -report html );
25 }
26 },
27 );
28
29
30 $class->new(
31 # Makefile.PL is maintained manually now because the 5.8 requirement wasn't getting
32 # translated automatically.
33 # create_makefile_pl => 'traditional',
34 dist_author => 'Mark Stosberg <mark@summersault.com>',
35 module_name => 'Data::FormValidator',
36 license => 'perl',
37 configure_requires => { 'Module::Build' => 0.38 },
38 requires => {
39 # In 5.6, t/upload* was failing.
40 # rjbs says "It relies on CGI relying on 5.008 glob stringification behavior"
41 perl => '5.008',
42 'Image::Size' => 0,
43 'Test::More' => 0,
44 'Date::Calc' => 5.0,
45 'File::MMagic' => 1.17,
46 'MIME::Types' => 1.005,
47 'Regexp::Common' => 0,
48 'overload' => 0,
49 'Perl6::Junction' => 1.10,
50 'Scalar::Util' => 0,
51 'Email::Valid' => 0,
52 },
53 build_requires => {
54 # For testing
55 'CGI' => 3.48,
56 },
57 meta_merge => {
58 resources =>
59 { repository => 'http://mark.stosberg.com/darcs_hive/dfv/', },
60 no_index => {
61 'package' => ['Data::FormValidator::Constraints::RegexpCommon'],
62 },
63 },
64 )->create_build_script;
65
0 4.88 August 28th, 2017
1
2 [MAINTENANCE]
3 - Address "." being removed from @INC by using absolute filepaths - thanks Kent Fredric!
4
5 4.87 May 14th, 2017
6
7 [MAINTENANCE]
8 - Update cc routine to recognize new 2 series Mastercards
9
10 4.86 March 26th, 2017
11 [NEW FEATURES]
12 - Add three new profile methods: depedencies_regexp, dependent_optional, dependent_require_some
13
14 [MAINTENANCE]
15 - Bump VERSION in all classes to 5.85
16
17 4.85 Feb 25th, 2017
18
19 [MAINTENANCE]
20 - Bump VERSION in all classes to 5.85
21
22 4.84 Feb 25th, 2017
23
24 [MAINTENANCE]
25 - Various test file warning fixes
26 - Change conditional loading of CGI to require version 4.35 or higher (4ce9ac9e)
27
28 4.83 Feb 23rd, 2017
29
30 [MAINTENANCE]
31 - Re-release of 4.82: tarball was missing files as "make dist" errored when it didn't find MANIFEST
32 - Deleted unused Perl6 files
33
34 4.82 Feb 23rd, 2017
35
36 [MAINTENANCE]
37 - Made CGI dependency optional
38 - Replaced Build.PL with Makefile.PL
39 - Updated Makefile.PL constraints
40 - Removed dependency on Perl6::Junctions
41 - Moved the code to GitHub
42 - Applied patches from: RT 77765, 78443, 10489
43 - Added shebang, warnings pragma to all test scripts
44 - Perltidied tests scripts
45 - Replaced is_tainted() sub with Scalar::Util::tainted()
046
147 4.81 Jul 19th, 2013
248
0 Build.PL
10 Changes
21 lib/Data/FormValidator.pm
32 lib/Data/FormValidator/Constraints.pm
65 lib/Data/FormValidator/ConstraintsFactory.pm
76 lib/Data/FormValidator/Filters.pm
87 lib/Data/FormValidator/Results.pm
8 Makefile.PL
99 MANIFEST This list of files
1010 MANIFEST.SKIP
11 README.pod
1112 RELEASE_NOTES
1213 t/00_base.t
1314 t/02_code_ref.t
8081 t/ValidatorPackagesTest2.pm
8182 test/00_base.badformat
8283 test/00_base.profile
83 META.yml
84 META.json
84 META.yml Module YAML meta-data (added by MakeMaker)
85 META.json Module JSON meta-data (added by MakeMaker)
2727 lib/Perl6
2828 rejects
2929 ^Build$
30
30 \.git
3131
3232 ^MYMETA.yml$
3333 ^MYMETA\.json$
00 {
1 "abstract" : "Validates user input (usually from an HTML form) based\non input profile.",
1 "abstract" : "Validates user input (usually from an HTML form) based on input profile.",
22 "author" : [
3 "Mark Stosberg <mark@summersault.com>"
3 "David Farrell <dfarrell@cpan.org>"
44 ],
55 "dynamic_config" : 1,
6 "generated_by" : "Module::Build version 0.38, CPAN::Meta::Converter version 2.120921",
6 "generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010",
77 "license" : [
88 "perl_5"
99 ],
1313 },
1414 "name" : "Data-FormValidator",
1515 "no_index" : {
16 "directory" : [
17 "t",
18 "inc"
19 ],
1620 "package" : [
1721 "Data::FormValidator::Constraints::RegexpCommon"
1822 ]
2024 "prereqs" : {
2125 "build" : {
2226 "requires" : {
23 "CGI" : "3.48"
27 "ExtUtils::MakeMaker" : "0"
2428 }
2529 },
2630 "configure" : {
2731 "requires" : {
28 "Module::Build" : "0.38"
32 "ExtUtils::MakeMaker" : "0"
2933 }
3034 },
3135 "runtime" : {
3337 "Date::Calc" : "5",
3438 "Email::Valid" : "0",
3539 "File::MMagic" : "1.17",
40 "File::Spec" : "0",
3641 "Image::Size" : "0",
3742 "MIME::Types" : "1.005",
38 "Perl6::Junction" : "1.1",
39 "Regexp::Common" : "0",
43 "Regexp::Common" : "0.03",
4044 "Scalar::Util" : "0",
4145 "Test::More" : "0",
42 "overload" : "0",
4346 "perl" : "5.008"
4447 }
4548 }
4649 },
47 "provides" : {
48 "Data::FormValidator" : {
49 "file" : "lib/Data/FormValidator.pm",
50 "version" : "4.81"
51 },
52 "Data::FormValidator::Constraints" : {
53 "file" : "lib/Data/FormValidator/Constraints.pm",
54 "version" : "4.81"
55 },
56 "Data::FormValidator::Constraints::Dates" : {
57 "file" : "lib/Data/FormValidator/Constraints/Dates.pm",
58 "version" : "4.81"
59 },
60 "Data::FormValidator::Constraints::RegexpCommon" : {
61 "file" : "lib/Data/FormValidator/Results.pm",
62 "version" : 0
63 },
64 "Data::FormValidator::Constraints::Upload" : {
65 "file" : "lib/Data/FormValidator/Constraints/Upload.pm",
66 "version" : "4.81"
67 },
68 "Data::FormValidator::ConstraintsFactory" : {
69 "file" : "lib/Data/FormValidator/ConstraintsFactory.pm",
70 "version" : "4.81"
71 },
72 "Data::FormValidator::Filters" : {
73 "file" : "lib/Data/FormValidator/Filters.pm",
74 "version" : "4.81"
75 },
76 "Data::FormValidator::Results" : {
77 "file" : "lib/Data/FormValidator/Results.pm",
78 "version" : "4.81"
50 "release_status" : "stable",
51 "resources" : {
52 "repository" : {
53 "type" : "git",
54 "url" : "https://github.com/dnmfarrell/Data-FormValidator",
55 "web" : "https://github.com/dnmfarrell/Data-FormValidator"
7956 }
8057 },
81 "release_status" : "stable",
82 "resources" : {
83 "license" : [
84 "http://dev.perl.org/licenses/"
85 ],
86 "repository" : {
87 "url" : "http://mark.stosberg.com/darcs_hive/dfv/"
88 }
89 },
90 "version" : "4.81"
58 "version" : 4.88,
59 "x_serialization_backend" : "JSON::PP version 2.27400_02"
9160 }
00 ---
1 abstract: "Validates user input (usually from an HTML form) based\non input profile."
1 abstract: 'Validates user input (usually from an HTML form) based on input profile.'
22 author:
3 - 'Mark Stosberg <mark@summersault.com>'
3 - 'David Farrell <dfarrell@cpan.org>'
44 build_requires:
5 CGI: 3.48
5 ExtUtils::MakeMaker: '0'
66 configure_requires:
7 Module::Build: 0.38
7 ExtUtils::MakeMaker: '0'
88 dynamic_config: 1
9 generated_by: 'Module::Build version 0.38, CPAN::Meta::Converter version 2.120921'
9 generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010'
1010 license: perl
1111 meta-spec:
1212 url: http://module-build.sourceforge.net/META-spec-v1.4.html
13 version: 1.4
13 version: '1.4'
1414 name: Data-FormValidator
1515 no_index:
16 directory:
17 - t
18 - inc
1619 package:
1720 - Data::FormValidator::Constraints::RegexpCommon
18 provides:
19 Data::FormValidator:
20 file: lib/Data/FormValidator.pm
21 version: 4.81
22 Data::FormValidator::Constraints:
23 file: lib/Data/FormValidator/Constraints.pm
24 version: 4.81
25 Data::FormValidator::Constraints::Dates:
26 file: lib/Data/FormValidator/Constraints/Dates.pm
27 version: 4.81
28 Data::FormValidator::Constraints::RegexpCommon:
29 file: lib/Data/FormValidator/Results.pm
30 version: 0
31 Data::FormValidator::Constraints::Upload:
32 file: lib/Data/FormValidator/Constraints/Upload.pm
33 version: 4.81
34 Data::FormValidator::ConstraintsFactory:
35 file: lib/Data/FormValidator/ConstraintsFactory.pm
36 version: 4.81
37 Data::FormValidator::Filters:
38 file: lib/Data/FormValidator/Filters.pm
39 version: 4.81
40 Data::FormValidator::Results:
41 file: lib/Data/FormValidator/Results.pm
42 version: 4.81
4321 requires:
44 Date::Calc: 5
45 Email::Valid: 0
46 File::MMagic: 1.17
47 Image::Size: 0
48 MIME::Types: 1.005
49 Perl6::Junction: 1.1
50 Regexp::Common: 0
51 Scalar::Util: 0
52 Test::More: 0
53 overload: 0
54 perl: 5.008
22 Date::Calc: '5'
23 Email::Valid: '0'
24 File::MMagic: '1.17'
25 File::Spec: '0'
26 Image::Size: '0'
27 MIME::Types: '1.005'
28 Regexp::Common: '0.03'
29 Scalar::Util: '0'
30 Test::More: '0'
31 perl: '5.008'
5532 resources:
56 license: http://dev.perl.org/licenses/
57 repository: http://mark.stosberg.com/darcs_hive/dfv/
58 version: 4.81
33 repository: https://github.com/dnmfarrell/Data-FormValidator
34 version: 4.88
35 x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
0 use 5.008;
1 use ExtUtils::MakeMaker;
2
3 WriteMakefile(
4 NAME => 'Data::FormValidator',
5 VERSION_FROM => 'lib/Data/FormValidator.pm',
6 ABSTRACT_FROM => 'lib/Data/FormValidator.pm',
7 AUTHOR => 'David Farrell <dfarrell@cpan.org>',
8 LICENSE => 'perl',
9 PREREQ_PM => {
10 # In 5.6, t/upload* was failing.
11 # rjbs says "It relies on CGI relying on 5.008 glob stringification behavior"
12 'perl' => '5.008',
13 'Image::Size' => 0,
14 'Test::More' => 0,
15 'Date::Calc' => 5.0,
16 'File::MMagic' => 1.17,
17 'MIME::Types' => 1.005,
18 'Regexp::Common' => 0.03, # when ::whitespace was added
19 'Scalar::Util' => 0,
20 'Email::Valid' => 0,
21 'File::Spec' => 0,
22 },
23 (eval { ExtUtils::MakeMaker->VERSION(6.46) } ? (META_MERGE => {
24 'meta-spec' => { version => 2 },
25 resources => {
26 repository => {
27 type => 'git',
28 url => 'https://github.com/dnmfarrell/Data-FormValidator',
29 web => 'https://github.com/dnmfarrell/Data-FormValidator',
30 },
31 },
32 # this is a cuckoo package in Data::FormValidator::Results
33 no_index => {
34 package => ['Data::FormValidator::Constraints::RegexpCommon'],
35 }})
36 : ()
37 ),
38 );
0 =pod
1
2 =head1 NAME
3
4 Data::FormValidator - Validates user input (usually from an HTML form) based
5 on input profile.
6
7 =head1 SYNOPSIS
8
9 use Data::FormValidator;
10
11 my $results = Data::FormValidator->check(\%input_hash, \%dfv_profile);
12
13 if ($results->has_invalid or $results->has_missing) {
14 # do something with $results->invalid, $results->missing
15 # or $results->msgs
16 }
17 else {
18 # do something with $results->valid
19 }
20
21
22 =head1 DESCRIPTION
23
24 Data::FormValidator's main aim is to make input validation expressible in a
25 simple format.
26
27 Data::FormValidator lets you define profiles which declare the
28 required and optional fields and any constraints they might have.
29
30 The results are provided as an object, which makes it easy to handle
31 missing and invalid results, return error messages about which constraints
32 failed, or process the resulting valid data.
33
34
35 =cut
36
37 =head1 VALIDATING INPUT
38
39 =head2 check()
40
41 my $results = Data::FormValidator->check(\%input_hash, \%dfv_profile);
42
43 C<check> is the recommended method to use to validate forms. It returns its results as a
44 L<Data::FormValidator::Results|Data::FormValidator::Results> object. A
45 deprecated method C<validate> described below is also available, returning its results as an
46 array.
47
48 use Data::FormValidator;
49 my $results = Data::FormValidator->check(\%input_hash, \%dfv_profile);
50
51 Here, C<check()> is used as a class method, and takes two required parameters.
52
53 The first a reference to the data to be be validated. This can either be a hash
54 reference, or a CGI.pm-like object. In particular, the object must have a param()
55 method that works like the one in CGI.pm does. CGI::Simple and Apache::Request
56 objects are known to work in particular. Note that if you use a hash reference,
57 multiple values for a single key should be presented as an array reference.
58
59 The second argument is a reference to the profile you are validating.
60
61 =head2 validate()
62
63 my( $valids, $missings, $invalids, $unknowns ) =
64 Data::FormValidator->validate( \%input_hash, \%dfv_profile);
65
66 C<validate()> provides a deprecated alternative to C<check()>. It has the same input
67 syntax, but returns a four element array, described as follows
68
69 =over
70
71 =item valids
72
73 This is a hash reference to the valid fields which were submitted in
74 the data. The data may have been modified by the various filters specified.
75
76 =item missings
77
78 This is a reference to an array which contains the name of the missing
79 fields. Those are the fields that the user forget to fill or filled
80 with spaces. These fields may comes from the I<required> list or the
81 I<dependencies> list.
82
83 =item invalids
84
85 This is a reference to an array which contains the name of the fields which
86 failed one or more of their constraint checks. If there are no invalid fields,
87 an empty arrayref will be returned.
88
89 Fields defined with multiple constraints will have an array ref returned in the
90 @invalids array instead of a string. The first element in this array is the
91 name of the field, and the remaining fields are the names of the failed
92 constraints.
93
94 =item unknowns
95
96 This is a list of fields which are unknown to the profile. Whether or
97 not this indicates an error in the user input is application
98 dependent.
99
100 =back
101
102 =head2 new()
103
104 Using C<new()> is only needed for advanced usage, including these cases:
105
106 =over
107
108 =item o
109
110 Loading more than one profile at a time. Then you can select the profile you
111 want by name later with C<check()>. Here's an example:
112
113 my $dfv = Data::FormValidator->new({
114 profile_1 => { # usual profile definition here },
115 profile_2 => { # another profile definition },
116 });
117
118
119 As illustrated, multiple profiles are defined through a hash ref whose keys point
120 to profile definitions.
121
122 You can also load several profiles from a file, by defining several profiles as shown above
123 in an external file. Then just pass in the name of the file:
124
125 my $dfv = Data::FormValidator->new('/path/to/profiles.pl');
126
127 If the input profile is specified as a file name, the profiles will be reread
128 each time that the disk copy is modified.
129
130 Now when calling C<check()>, you just need to supply the profile name:
131
132 my $results = $dfv->check(\%input_hash,'profile_1');
133
134 =item o
135
136 Applying defaults to more than one input profile. There are some parts
137 of the validation profile that you might like to re-use for many form
138 validations.
139
140 To facilitate this, C<new()> takes a second argument, a hash reference. Here
141 the usual input profile definitions can be made. These will act as defaults for
142 any subsequent calls to C<check()> on this object.
143
144 Currently the logic for this is very simple. Any definition of a key in your
145 validation profile will completely overwrite your default value.
146
147 This means you can't define two keys for C<constraint_regexp_map> and expect
148 they will always be there. This kind of feature may be added in the future.
149
150 The exception here is definitions for your C<msgs> key. You will safely be
151 able to define some defaults for the top level keys within C<msgs> and not have
152 them clobbered just because C<msgs> was defined in a validation profile.
153
154 One way to use this feature is to create your own sub-class that always provides
155 your defaults to C<new()>.
156
157 Another option is to create your own wrapper routine which provides these defaults to
158 C<new()>. Here's an example of a routine you might put in a
159 L<CGI::Application|CGI::Application> super-class to make use of this feature:
160
161 # Always use the built-in CGI object as the form data
162 # and provide some defaults to new constructor
163 sub check_form {
164 my $self = shift;
165 my $profile = shift
166 || die 'check_form: missing required profile';
167
168 require Data::FormValidator;
169 my $dfv = Data::FormValidator->new({},{
170 # your defaults here
171 });
172 return $dfv->check($self->query,$profile);
173 }
174
175
176 =back
177
178
179 =cut
180
181 =head1 INPUT PROFILE SPECIFICATION
182
183 An input profile is a hash reference containing one or more of the following
184 keys.
185
186 Here is a very simple input profile. Examples of more advanced options are
187 described below.
188
189 use Data::FormValidator::Constraints qw(:closures);
190
191 my $profile = {
192 optional => [qw( company
193 fax
194 country )],
195
196 required => [qw( fullname
197 phone
198 email
199 address )],
200
201 constraint_methods => {
202 email => email(),
203 }
204 };
205
206
207 That defines some fields as optional, some as required, and defines that the
208 field named 'email' must pass the constraint named 'email'.
209
210 Here is a complete list of the keys available in the input profile, with
211 examples of each.
212
213 =head2 required
214
215 This is an array reference which contains the name of the fields which are
216 required. Any fields in this list which are not present or contain only
217 spaces will be reported as missing.
218
219 =head2 required_regexp
220
221 required_regexp => qr/city|state|zipcode/,
222
223 This is a regular expression used to specify additional field names for which values
224 will be required.
225
226 =head2 require_some
227
228 require_some => {
229 # require any two fields from this group
230 city_or_state_or_zipcode => [ 2, qw/city state zipcode/ ],
231 }
232
233 This is a reference to a hash which defines groups of fields where 1 or more
234 fields from the group should be required, but exactly which fields doesn't
235 matter. The keys in the hash are the group names. These are returned as
236 "missing" unless the required number of fields from the group has been filled
237 in. The values in this hash are array references. The first element in this
238 array should be the number of fields in the group that is required. If the
239 first field in the array is not an a digit, a default of "1" will be used.
240
241 =head2 optional
242
243 optional => [qw/meat coffee chocolate/],
244
245 This is an array reference which contains the name of optional fields.
246 These are fields which MAY be present and if they are, they will be
247 checked for valid input. Any fields not in optional or required list
248 will be reported as unknown.
249
250 =head2 optional_regexp
251
252 optional_regexp => qr/_province$/,
253
254 This is a regular expression used to specify additional fields which are
255 optional. For example, if you wanted all fields names that begin with I<user_>
256 to be optional, you could use the regular expression, /^user_/
257
258 =head2 dependencies
259
260 dependencies => {
261
262 # If cc_no is entered, make cc_type and cc_exp required
263 "cc_no" => [ qw( cc_type cc_exp ) ],
264
265 # if pay_type eq 'check', require check_no
266 "pay_type" => {
267 check => [ qw( check_no ) ],
268 }
269
270 # if cc_type is VISA or MASTERCARD require CVV
271 "cc_type" => sub {
272 my $dfv = shift;
273 my $type = shift;
274
275 return [ 'cc_cvv' ] if ($type eq "VISA" || $type eq "MASTERCARD");
276 return [ ];
277 },
278 },
279
280 This is for the case where an optional field has other requirements. The
281 dependent fields can be specified with an array reference.
282
283 If the dependencies are specified with a hash reference then the additional
284 constraint is added that the optional field must equal a key for the
285 dependencies to be added.
286
287 If the dependencies are specified as a code reference then the code will be
288 executed to determine the dependent fields. It is passed two parameters,
289 the object and the value of the field, and it should return an array reference
290 containing the list of dependent fields.
291
292 Any fields in the dependencies list that are missing when the target is present
293 will be reported as missing.
294
295 =head2 dependency_groups
296
297 dependency_groups => {
298 # if either field is filled in, they all become required
299 password_group => [qw/password password_confirmation/],
300 }
301
302 This is a hash reference which contains information about groups of
303 interdependent fields. The keys are arbitrary names that you create and
304 the values are references to arrays of the field names in each group.
305
306 =head2 dependencies_regexp
307
308 dependencies_regexp => {
309 qr/Line\d+\_ItemType$/ => sub {
310 my $dfv = shift;
311 my $itemtype = shift;
312 my $field = shift;
313
314 if ($type eq 'NeedsBatteries') {
315 my ($prefix, $suffix) = split(/\_/, $field);
316
317 return([$prefix . '_add_batteries]);
318 } else {
319 return([]);
320 }
321 },
322 },
323
324 This is a regular expression used to specify additional fields which are
325 dependent. For example, if you wanted to add dependencies for all fields which
326 meet a certain criteria (such as multiple items in a shopping cart) where you
327 do not know before hand how many of such fields you may have.
328
329 =head2 dependent_optionals
330
331 dependent_optionals => {
332 # If delivery_address is specified then delivery_notes becomes optional
333 "delivery_address" => [ qw( delivery_notes ) ],
334
335 # if delivery_type eq 'collection', collection_notes becomes optional
336 "delivery_type" => {
337 collection => [ qw( collection_notes ) ],
338 }
339
340 # if callback_type is "phone" or "email" then additional_notes becomes optional
341 "callback_type" => sub {
342 my $dfv = shift;
343 my $type = shift;
344
345 if ($type eq 'phone' || $type eq 'email') {
346 return(['additional_notes']);
347 } else {
348 return([]);
349 }
350 },
351 },
352
353 This is for the case where an optional field can trigger other optional fields.
354 The dependent optional fields can be specified with an array reference.
355
356 If the dependent optional fields are specified with a hash reference, then an
357 additional constraint is added that the optional field must equal a key for the
358 additional optional fields to be added.
359
360 If the dependent optional fields are specified as a code reference then the
361 code will be executed to determine the additional optional fields. It is passed
362 two parameters, the object and the value of the field, and it should return an
363 array reference containing the list of additional optional fields.
364
365 =head2 dependent_require_some
366
367 dependent_require_some => {
368 # require any fields from this group if AddressID is "new"
369 AddressID => sub {
370 my $dfv = shift;
371 my $value = shift;
372
373 if ($value eq 'new') {
374 return({
375 house_name_or_number => [ 1, 'HouseName', 'HouseNumber' ],
376 });
377 } else {
378 return;
379 }
380 },
381 }
382
383 Sometimes a field will need to trigger additional dependencies but you only
384 require some of the fields. You cannot set them all to be dependent as you
385 might only have some of them, and you cannot set them all to be optional as
386 you must have some of them. This method allows you to specify this in a
387 similar way to the equire_some method but dependent upon other values. In
388 the example above if the AddressID submitted is "new" then at least 1 of
389 HouseName and HouseNumber must also be supplied. See require_some for the
390 valid options for the return.
391
392 =head2 defaults
393
394 defaults => {
395 country => "USA",
396 },
397
398 This is a hash reference where keys are field names and
399 values are defaults to use if input for the field is missing.
400
401 The values can be code refs which will be used to calculate the
402 value if needed. These code refs will be passed in the DFV::Results
403 object as the only parameter.
404
405 The defaults are set shortly before the constraints are applied, and
406 will be returned with the other valid data.
407
408 =head2 defaults_regexp_map
409
410 defaults_regexp_map => {
411 qr/^opt_/ => 1,
412 },
413
414 This is a hash reference that maps regular expressions to default values to
415 use for matching optional or required fields.
416
417 It's useful if you have generated many checkbox fields with the similar names.
418 Since checkbox fields submit nothing at all when they are not checked, it's
419 useful to set defaults for them.
420
421 Note that it doesn't make sense to use a default for a field handled by
422 C<optional_regexp> or C<required_regexp>. When the field is not submitted,
423 there is no way to know that it should be optional or required, and thus there's
424 no way to know that a default should be set for it.
425
426 =head2 filters
427
428 # trim leading and trailing whitespace on all fields
429 filters => ['trim'],
430
431 This is a reference to an array of filters that will be applied to ALL optional
432 and required fields, B<before> any constraints are applied.
433
434 This can be the name of a built-in filter
435 (trim,digit,etc) or an anonymous subroutine which should take one parameter,
436 the field value and return the (possibly) modified value.
437
438 Filters modify the data returned through the results object, so use them carefully.
439
440 See L<Data::FormValidator::Filters> for details on the built-in filters.
441
442 =head2 field_filters
443
444 field_filters => {
445 cc_no => ['digit'],
446 },
447
448 A hash ref with field names as keys. Values are array references of built-in
449 filters to apply (trim,digit,etc) or an anonymous subroutine which should take
450 one parameter, the field value and return the (possibly) modified value.
451
452 Filters are applied B<before> any constraints are applied.
453
454 See L<Data::FormValidator::Filters> for details on the built-in filters.
455
456 =head2 field_filter_regexp_map
457
458 field_filter_regexp_map => {
459 # Upper-case the first letter of all fields that end in "_name"
460 qr/_name$/ => ['ucfirst'],
461 },
462
463 'field_filter_regexp_map' is used to apply filters to fields that match a
464 regular expression. This is a hash reference where the keys are the regular
465 expressions to use and the values are references to arrays of filters which
466 will be applied to specific input fields. Just as with 'field_filters', you
467 can you use a built-in filter or use a coderef to supply your own.
468
469 =head2 constraint_methods
470
471 use Data::FormValidator::Constraints qw(:closures);
472
473 constraint_methods => {
474 cc_no => cc_number({fields => ['cc_type']}),
475 cc_type => cc_type(),
476 cc_exp => cc_exp(),
477 },
478
479 A hash ref which contains the constraints that will be used to check whether or
480 not the field contains valid data.
481
482 B<Note:> To use the built-in constraints, they need to first be loaded into your
483 name space using the syntax above. (Unless you are using the old C<constraints> key,
484 documented in L<BACKWARDS COMPATIBILITY>).
485
486 The keys in this hash are field names. The values can be any of the following:
487
488 =over
489
490 =item o
491
492 A named constraint.
493
494 B<Example>:
495
496 my_zipcode_field => zip(),
497
498 See L<Data::FormValidator::Constraints> for the details of which
499 built-in constraints that are available.
500
501
502 =item o
503
504 A perl regular expression
505
506 B<Example>:
507
508 my_zipcode_field => qr/^\d{5}$/, # match exactly 5 digits
509
510 If this field is named in C<untaint_constraint_fields> or C<untaint_regexp_map>,
511 or C<untaint_all_constraints> is effective, be aware of the following: If you
512 write your own regular expressions and only match part of the string then
513 you'll only get part of the string in the valid hash. It is a good idea to
514 write you own constraints like /^regex$/. That way you match the whole string.
515
516 =item o
517
518 a subroutine reference, to supply custom code
519
520 This will check the input and return true or false depending on the input's validity.
521 By default, the constraint function receives a L<Data::FormValidator::Results>
522 object as its first argument, and the value to be validated as the second. To
523 validate a field based on more inputs than just the field itself, see
524 L<VALIDATING INPUT BASED ON MULTIPLE FIELDS>.
525
526 B<Examples>:
527
528 # Notice the use of 'pop'--
529 # the object is the first arg passed to the method
530 # while the value is the second, and last arg.
531 my_zipcode_field => sub { my $val = pop; return $val =~ '/^\d{5}$/' },
532
533 # OR you can reference a subroutine, which should work like the one above
534 my_zipcode_field => \&my_validation_routine,
535
536 # An example of setting the constraint name.
537 my_zipcode_field => sub {
538 my ($dfv, $val) = @_;
539 $dfv->set_current_constraint_name('my_constraint_name');
540 return $val =~ '/^\d{5}$/'
541 },
542
543 =item o
544
545 an array reference
546
547 An array reference is used to apply multiple constraints to a single
548 field. Any of the above options are valid entries the array.
549 See L<MULTIPLE CONSTRAINTS> below.
550
551 For more details see L<VALIDATING INPUT BASED ON MULTIPLE FIELDS>.
552
553 =back
554
555 =head2 constraint_method_regexp_map
556
557 use Data::FormValidator::Constraints qw(:closures);
558
559 # In your profile.
560 constraint_method_regexp_map => {
561 # All fields that end in _postcode have the 'postcode' constraint applied.
562 qr/_postcode$/ => postcode(),
563 },
564
565 A hash ref where the keys are the regular expressions to
566 use and the values are the constraints to apply.
567
568 If one or more constraints have already been defined for a given field using
569 C<constraint_methods>, C<constraint_method_regexp_map> will add an additional
570 constraint for that field for each regular expression that matches.
571
572 =head2 untaint_all_constraints
573
574 untaint_all_constraints => 1,
575
576 If this field is set, all form data that passes a constraint will be untainted.
577 The untainted data will be returned in the valid hash. Untainting is based on
578 the pattern match used by the constraint. Note that some constraint routines
579 may not provide untainting.
580
581 See L<Writing your own constraint routines|Data::FormValidator::Constraints/"WRITING YOUR OWN CONSTRAINT ROUTINES"> for more information.
582
583 This is overridden by C<untaint_constraint_fields> and C<untaint_regexp_map>.
584
585 =head2 untaint_constraint_fields
586
587 untaint_constraint_fields => [qw(zipcode state)],
588
589 Specifies that one or more fields will be untainted if they pass their
590 constraint(s). This can be set to a single field name or an array reference of
591 field names. The untainted data will be returned in the valid hash.
592
593 This overrides the untaint_all_constraints flag.
594
595 =head2 untaint_regexp_map
596
597 untaint_regexp_map => [qr/some_field_\d/],
598
599 Specifies that certain fields will be untainted if they pass their constraints
600 and match one of the regular expressions supplied. This can be set to a single
601 regex, or an array reference of regexes. The untainted data will be returned
602 in the valid hash.
603
604 The above example would untaint the fields named C<some_field_1>, and C<some_field_2>
605 but not C<some_field>.
606
607 This overrides the untaint_all_constraints flag.
608
609 =head2 missing_optional_valid
610
611 missing_optional_valid => 1
612
613 This can be set to a true value to cause optional fields with empty values to
614 be included in the valid hash. By default they are not included-- this is the
615 historical behavior.
616
617 This is an important flag if you are using the contents of an "update" form to
618 update a record in a database. Without using the option, fields that have been
619 set back to "blank" may fail to get updated.
620
621 =head2 validator_packages
622
623 # load all the constraints and filters from these modules
624 validator_packages => [qw(Data::FormValidator::Constraints::Upload)],
625
626 This key is used to define other packages which contain constraint routines or
627 filters. Set this key to a single package name, or an arrayref of several. All
628 of its constraint and filter routines beginning with 'match_', 'valid_' and
629 'filter_' will be imported into Data::FormValidator. This lets you reference
630 them in a constraint with just their name, just like built-in routines. You
631 can even override the provided validators.
632
633 See L<Writing your own constraint routines|Data::FormValidator::Constraints/"WRITING YOUR OWN CONSTRAINT ROUTINES">
634 documentation for more information
635
636 =head2 msgs
637
638 This key is used to define parameters related to formatting error messages
639 returned to the user.
640
641 By default, invalid fields have the message "Invalid" associated with them
642 while missing fields have the message "Missing" associated with them.
643
644 In the simplest case, nothing needs to be defined here, and the default values
645 will be used.
646
647 The default formatting applied is designed for display in an XHTML web page.
648 That formatting is as followings:
649
650 <span style="color:red;font-weight:bold" class="dfv_errors">* %s</span>
651
652 The C<%s> will be replaced with the message. The effect is that the message
653 will appear in bold red with an asterisk before it. This style can be overridden by simply
654 defining "dfv_errors" appropriately in a style sheet, or by providing a new format string.
655
656 Here's a more complex example that shows how to provide your own default message strings, as well
657 as providing custom messages per field, and handling multiple constraints:
658
659 msgs => {
660
661 # set a custom error prefix, defaults to none
662 prefix=> 'error_',
663
664 # Set your own "Missing" message, defaults to "Missing"
665 missing => 'Not Here!',
666
667 # Default invalid message, default's to "Invalid"
668 invalid => 'Problematic!',
669
670 # message separator for multiple messages
671 # Defaults to ' '
672 invalid_separator => ' <br /> ',
673
674 # formatting string, default given above.
675 format => 'ERROR: %s',
676
677 # Error messages, keyed by constraint name
678 # Your constraints must be named to use this.
679 constraints => {
680 'date_and_time' => 'Not a valid time format',
681 # ...
682 },
683
684 # This token will be included in the hash if there are
685 # any errors returned. This can be useful with templating
686 # systems like HTML::Template
687 # The 'prefix' setting does not apply here.
688 # defaults to undefined
689 any_errors => 'some_errors',
690 }
691
692 The hash that's prepared can be retrieved through the C<msgs> method
693 described in the L<Data::FormValidator::Results> documentation.
694
695 =head2 msgs - callback
696
697 I<This is a new feature. While it expected to be forward-compatible, it hasn't
698 yet received the testing the rest of the API has.>
699
700 If the built-in message generation doesn't suit you, it is also possible to
701 provide your own by specifying a code reference:
702
703 msgs => \&my_msgs_callback
704
705 This will be called as a L<Data::FormValidator::Results> method. It may
706 receive as arguments an additional hash reference of control parameters,
707 corresponding to the key names usually used in the C<msgs> area of the
708 profile. You can ignore this information if you'd like.
709
710 If you have an alternative error message handler you'd like to share, stick in
711 the C<Data::FormValidator::ErrMsgs> name space and upload it to CPAN.
712
713 =head2 debug
714
715 This method is used to print details about what is going on to STDERR.
716
717 Currently only level '1' is used. It provides information about which
718 fields matched constraint_regexp_map.
719
720 =head2 A shortcut for array refs
721
722 A number of parts of the input profile specification include array references
723 as their values. In any of these places, you can simply use a string if you
724 only need to specify one value. For example, instead of
725
726 filters => [ 'trim' ]
727
728 you can simply say
729
730 filters => 'trim'
731
732 =head2 A note on regular expression formats
733
734 In addition to using the preferred method of defining regular expressions
735 using C<qr>, a deprecated style of defining them as strings is also supported.
736
737 Preferred:
738
739 qr/this is great/
740
741 Deprecated, but supported
742
743 'm/this still works/'
744
745 =head1 VALIDATING INPUT BASED ON MULTIPLE FIELDS
746
747 You can pass more than one value into a constraint routine. For that, the
748 value of the constraint should be a hash reference. If you are creating your
749 own routines, be sure to read the section labeled
750 L<WRITING YOUR OWN CONSTRAINT ROUTINES>,
751 in the Data::FormValidator::Constraints documentation. It describes
752 a newer and more flexible syntax.
753
754 Using the original syntax, one key should be named C<constraint> and should
755 have a value set to the reference of the subroutine or the name of a built-in
756 validator. Another required key is C<params>. The value of the C<params> key
757 is a reference to an array of the other elements to use in the validation. If
758 the element is a scalar, it is assumed to be a field name. The field is known
759 to Data::FormValidator, the value will be filtered through any defined filters
760 before it is passed in. If the value is a reference, the reference is passed
761 directly to the routine. Don't forget to include the name of the field to
762 check in that list, if you are using this syntax.
763
764 B<Example>:
765
766 cc_no => {
767 constraint => "cc_number",
768 params => [ qw( cc_no cc_type ) ],
769 },
770
771
772 =head1 MULTIPLE CONSTRAINTS
773
774 Multiple constraints can be applied to a single field by defining the value of
775 the constraint to be an array reference. Each of the values in this array can
776 be any of the constraint types defined above.
777
778 When using multiple constraints it is important to return the name of the
779 constraint that failed so you can distinguish between them. To do that,
780 either use a named constraint, or use the hash ref method of defining a
781 constraint and include a C<name> key with a value set to the name of your
782 constraint. Here's an example:
783
784 my_zipcode_field => [
785 'zip',
786 {
787 constraint_method => '/^406/',
788 name => 'starts_with_406',
789 }
790 ],
791
792 You can use an array reference with a single constraint in it if you just want
793 to have the name of your failed constraint returned in the above fashion.
794
795 Read about the C<validate()> function above to see how multiple constraints
796 are returned differently with that method.
797
798
799 =cut
800
801 =pod
802
803 =head1 ADVANCED VALIDATION
804
805 For even more advanced validation, you will likely want to read the
806 documentation for other modules in this distribution, linked below. Also keep
807 in mind that the Data::FormValidator profile structure is just another data
808 structure. There is no reason why it needs to be defined statically. The
809 profile could also be built on the fly with custom Perl code.
810
811 =head1 BACKWARDS COMPATIBILITY
812
813 =head2 validate()
814
815 my( $valids, $missings, $invalids, $unknowns ) =
816 Data::FormValidator->validate( \%input_hash, \%dfv_profile);
817
818 C<validate()> provides a deprecated alternative to C<check()>. It has the same input
819 syntax, but returns a four element array, described as follows
820
821 =over
822
823 =item valids
824
825 This is a hash reference to the valid fields which were submitted in
826 the data. The data may have been modified by the various filters specified.
827
828 =item missings
829
830 This is a reference to an array which contains the name of the missing
831 fields. Those are the fields that the user forget to fill or filled
832 with spaces. These fields may comes from the I<required> list or the
833 I<dependencies> list.
834
835 =item invalids
836
837 This is a reference to an array which contains the name of the fields
838 which failed one or more of their constraint checks.
839
840 Fields defined with multiple constraints will have an array ref returned in the
841 @invalids array instead of a string. The first element in this array is the
842 name of the field, and the remaining fields are the names of the failed
843 constraints.
844
845 =item unknowns
846
847 This is a list of fields which are unknown to the profile. Whether or
848 not this indicates an error in the user input is application
849 dependent.
850
851 =back
852
853 =head2 constraints (profile key)
854
855 This is a supported but deprecated profile key. Using C<constraint_methods> is
856 recommended instead, which provides a simpler, more versatile interface.
857
858 constraints => {
859 cc_no => {
860 constraint => "cc_number",
861 params => [ qw( cc_no cc_type ) ],
862 },
863 cc_type => "cc_type",
864 cc_exp => "cc_exp",
865 },
866
867 A hash ref which contains the constraints that
868 will be used to check whether or not the field contains valid data.
869
870 The keys in this hash are field names. The values can be any of the following:
871
872 =over
873
874 =item o
875
876 A named constraint.
877
878 B<Example>:
879
880 my_zipcode_field => 'zip',
881
882 See L<Data::FormValidator::Constraints> for the details of which
883 built-in constraints that are available.
884
885 =back
886
887 =head2 hashref style of specifying constraints
888
889 Using a hash reference to specify a constraint is an older technique
890 used to name a constraint or supply multiple parameters.
891
892 Both of these interface issues are now better addressed with C<constraint_methods>
893 and C<$self-\>name_this('foo')>.
894
895 # supply multiple parameters
896 cc_no => {
897 constraint => "cc_number",
898 params => [ qw( cc_no cc_type ) ],
899 },
900
901 # name a constraint, useful for returning error messages
902 last_name => {
903 name => "ends_in_name",
904 constraint => qr/_name$/,
905 },
906
907 Using a hash reference for a constraint permits the passing of multiple
908 arguments. Required arguments are C<constraint> or C<constraint_method>.
909 Optional arguments are C<name> and C<params>.
910
911 A C<name> on a constraints 'glues' the constraint to its error message
912 in the validator profile (refer C<msgs> section below). If no C<name> is
913 given then it will default to the value of C<constraint> or
914 C<constraint_method> IF they are NOT a CODE ref or a RegExp ref.
915
916 The C<params> value is a reference to an array of the parameters to pass
917 to the constraint method.
918 If an element of the C<params> list is a scalar, it is assumed to be naming
919 a key of the %input_hash and that value is passed to the routine.
920 If the parameter is a reference, then it is treated literally and passed
921 unchanged to the routine.
922
923 If you are using the older C<constraint> over
924 the new C<constraint_method> then don't forget to include the name of the
925 field to check in the C<params> list. C<constraint_method> provides access
926 to this value via the C<get_current_*> methods
927 (refer L<Data::FormValidator::Constraints>)
928
929 For more details see L<VALIDATING INPUT BASED ON MULTIPLE FIELDS>.
930
931 =head2 constraint_regexp_map (profile key)
932
933 This is a supported but deprecated profile key. Using
934 C<constraint_methods_regexp_map> is recommended instead.
935
936 constraint_regexp_map => {
937 # All fields that end in _postcode have the 'postcode' constraint applied.
938 qr/_postcode$/ => 'postcode',
939 },
940
941 A hash ref where the keys are the regular expressions to
942 use and the values are the constraints to apply.
943
944 If one or more constraints have already been defined for a given field using
945 "constraints", constraint_regexp_map will add an additional constraint for that
946 field for each regular expression that matches.
947
948 =head1 SEE ALSO
949
950 B<Other modules in this distribution:>
951
952 L<Data::FormValidator::Constraints|Data::FormValidator::Constraints>
953
954 L<Data::FormValidator::Constraints::Dates|Data::FormValidator::Constraints::Dates>
955
956 L<Data::FormValidator::Constraints::Upload|Data::FormValidator::Constraints::Upload>
957
958 L<Data::FormValidator::ConstraintsFactory|Data::FormValidator::ConstraintsFactory>
959
960 L<Data::FormValidator::Filters|Data::FormValidator::Filters>
961
962 L<Data::FormValidator::Results|Data::FormValidator::Results>
963
964 B<A sample application by the maintainer:>
965
966 Validating Web Forms with Perl, L<http://mark.stosberg.com/Tech/perl/form-validation/>
967
968 B<Related modules:>
969
970 L<Data::FormValidator::Tutorial|Data::FormValidator::Tutorial>
971
972 L<Data::FormValidator::Util::HTML|Data::FormValidator::Util::HTML>
973
974 L<CGI::Application::ValidateRM|CGI::Application::ValidateRM>, a
975 CGI::Application & Data::FormValidator glue module
976
977 L<HTML::Template::Associate::FormValidator|HTML::Template::Associate::FormValidator> is designed
978 to make some kinds of integration with HTML::Template easier.
979
980 L<Params::Validate|Params::Validate> is useful for validating function parameters.
981
982 L<Regexp::Common|Regexp::Common>,
983 L<Data::Types|Data::Types>,
984 L<Data::Verify|Data::Verify>,
985 L<Email::Valid|Email::Valid>,
986 L<String::Checker|String::Checker>,
987 L<CGI::ArgChecker|CGI::ArgChecker>,
988 L<CGI::FormMagick::Validator|CGI::FormMagick::Validator>,
989 L<CGI::Validate|CGI::Validate>
990
991 B<Document Translations:>
992
993 Japanese: L<http://perldoc.jp/docs/modules/>
994
995 B<Distributions which include Data::FormValidator>
996
997 FreeBSD includes a port named B<p5-Data-FormValidator>
998
999 Debian GNU/Linux includes a port named B<libdata-formvalidator-perl>
1000
1001 =head1 CREDITS
1002
1003 Some of these input validation functions have been taken from MiniVend
1004 by Michael J. Heins.
1005
1006 The credit card checksum validation was taken from contribution by Bruce
1007 Albrecht to the MiniVend program.
1008
1009 =head1 BUGS
1010
1011 Bug reports and patches are welcome. Reports which include a failing Test::More
1012 style test are helpful and will receive priority.
1013
1014 L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Data-FormValidator>
1015
1016 =head1 CONTRIBUTING
1017
1018 This project is maintained on L<Github|https://github.com/dnmfarrell/Data-FormValidator>.
1019
1020 =head1 AUTHOR
1021
1022 Currently maintained by David Farrell <dfarrell@cpan.org>
1023
1024 Parts Copyright 2001-2006 by Mark Stosberg <mark at summersault.com>, (previous maintainer)
1025
1026 Copyright (c) 1999 Francis J. Lacoste and iNsu Innovations Inc. All rights reserved.
1027 (Original Author)
1028
1029 Parts Copyright 1996-1999 by Michael J. Heins <mike@heins.net>
1030
1031 Parts Copyright 1996-1999 by Bruce Albrecht <bruce.albrecht@seag.fingerhut.com>
1032
1033 =head1 LICENSE
1034
1035 This program is free software; you can redistribute it and/or modify
1036 it under the terms as perl itself.
1037
1038
1039 =cut
1040
1313 match_date_and_time
1414 );
1515
16 our $VERSION = '4.81';
16 our $VERSION = 4.88;
1717
1818 sub date_and_time {
1919 my $fmt = shift;
2323 image_min_dimensions
2424 );
2525
26 our $VERSION = 4.81;
26 our $VERSION = 4.88;
2727
2828 sub file_format {
2929 my %params = @_;
310310 else {
311311 return IO::File->new_from_fd(fileno($q->{$field}), 'r');
312312 }
313
314313 }
315314
316315 ## returns mime type if included as part of the send
2323 use strict;
2424 our $AUTOLOAD;
2525
26 our $VERSION = 4.81;
26 our $VERSION = 4.88;
2727
2828 BEGIN {
2929 use Carp;
411411 my $param = $dfv->get_current_constraint_field();
412412 my $value = $dfv->get_filtered_data()->{$param};
413413
414 my $num_values = scalar @$value;
415
416 return ($num_values >= $min) && ($num_values <= $max) if ref $value eq 'ARRAY';
417 return 1 if $min == 0 && $max >= 2; # scalar, size could be 1
418 return 0; # scalar, size can't be 1
414 if (ref($value) eq 'ARRAY') {
415 my $num_values = scalar @$value;
416
417 return(
418 (
419 $num_values >= $min
420 && $num_values <= $max
421 ) ? 1 : 0
422 );
423 } else {
424 if ($min <= 1 && $max >= 1) {
425 # Single value is allowed
426 return 1;
427 } else {
428 return 0;
429 }
430 }
419431 }
420432 }
421433
642654 return undef unless $card_type =~ /^[admv]/i;
643655
644656 return undef if ($card_type =~ /^v/i && substr($the_card, 0, 1) ne "4") ||
645 ($card_type =~ /^m/i && substr($the_card, 0, 1) ne "5") ||
657 ($card_type =~ /^m/i && substr($the_card, 0, 1) ne "5" &&
658 substr($the_card, 0, 1) ne "2") ||
646659 ($card_type =~ /^d/i && substr($the_card, 0, 4) ne "6011") ||
647660 ($card_type =~ /^a/i && substr($the_card, 0, 2) ne "34" &&
648661 substr($the_card, 0, 2) ne "37");
10681081
10691082 =item L<Data::FormValidator::Filters> - transform data before constraints are applied
10701083
1071 =item L<Data::FormValidator::ConstraintsFactory> - This is a historical collection of constraints that suffer from cumbersome names. They are worth reviewing though-- C<make_and_constraint> will allow to validate against a list of constraints and shortcircuit if the first one fails. That's perfect if the second constraint depends on the first one having passed.
1072 For a modern version of this toolkit, see L<Data::FormValidator::Constraints::MethodsFactory>.
1084 =item L<Data::FormValidator::ConstraintsFactory> - This is a historical collection of constraints that suffer from cumbersome names. They are worth reviewing though-- C<make_and_constraint> will allow one to validate against a list of constraints and shortcircuit if the first one fails. That's perfect if the second constraint depends on the first one having passed.
1085 For a modern version of this toolkit, see L<Data::FormValidator::Constraints::MethodsFactory>.
10731086
10741087 =item L<Data::FormValidator>
10751088
4444 =cut
4545
4646 BEGIN {
47 our $VERSION = 4.81;
47 our $VERSION = 4.88;
4848 our @EXPORT = ();
4949 our @EXPORT_OK = (qw/make_length_constraint/);
5050
1212 use Exporter 'import';
1313 use strict;
1414
15 our $VERSION = 4.81;
15 our $VERSION = 4.88;
1616
1717 our @EXPORT_OK = qw(
1818 filter_alphanum
1313 use strict;
1414
1515 package Data::FormValidator::Results;
16 use Perl6::Junction 'any';
1716 use Carp;
1817 use Symbol;
1918 use Data::FormValidator::Filters ':filters';
2221 'bool' => \&_bool_overload_based_on_success,
2322 fallback => 1;
2423
25 our $VERSION = 4.81;
24 our $VERSION = 4.88;
2625
2726 =pod
2827
188187 }
189188
190189 # handle "require_some"
190 while (my ($field, $dependent_require_some) = each %{$profile->{dependent_require_some}}) {
191 if (defined $valid{$field}) {
192 if (ref $dependent_require_some eq "CODE") {
193 for my $value (_arrayify($valid{$field})) {
194 my $returned_require_some = $dependent_require_some->($self, $value);
195
196 if (ref($returned_require_some) eq 'HASH') {
197 foreach my $key (keys %$returned_require_some) {
198 $profile->{require_some}->{$key} = $returned_require_some->{$key};
199 }
200 }
201 }
202 } else {
203 if (ref($dependent_require_some) eq 'HASH') {
204 foreach my $key (keys %$dependent_require_some) {
205 $profile->{require_some}->{$key} = $dependent_require_some->{$key};
206 }
207 }
208 }
209 }
210 }
211
191212 my %require_some;
192213 while ( my ( $field, $deps) = each %{$profile->{require_some}} ) {
193214 for my $dep (_arrayify($deps)){
264285 }
265286 }
266287
288 my $dependency_re;
289
290 foreach my $re (keys %{$profile->{dependencies_regexp}}) {
291 my $sub = _create_sub_from_RE($re);
292
293 $dependency_re->{$re} = {
294 sub => $sub,
295 value => $profile->{dependencies_regexp}->{$re},
296 };
297 }
298
299 if ($dependency_re) {
300 foreach my $k (keys %valid) {
301 foreach my $re (keys %$dependency_re) {
302 if ($dependency_re->{$re}->{sub}->($k)) {
303 my $deps = $dependency_re->{$re}->{value};
304
305 if (ref($deps) eq 'HASH') {
306 for my $key (keys %$deps) {
307 # Handle case of a key with a single value given as an arrayref
308 # There is probably a better, more general solution to this problem.
309 my $val_to_compare;
310
311 if ((ref $valid{$k} eq 'ARRAY') and (scalar @{ $valid{$k} } == 1)) {
312 $val_to_compare = $valid{$k}->[0];
313 } else {
314 $val_to_compare = $valid{$k}
315 }
316
317 if($val_to_compare eq $key){
318 for my $dep (_arrayify($deps->{$key})){
319 $required{$dep} = 1;
320 }
321 }
322 }
323 } elsif (ref $deps eq "CODE") {
324 for my $val (_arrayify($valid{$k})) {
325 my $returned_deps = $deps->($self, $val, $k);
326
327 for my $dep (_arrayify($returned_deps)) {
328 $required{$dep} = 1;
329 }
330 }
331 } else {
332 for my $dep (_arrayify($deps)){
333 $required{$dep} = 1;
334 }
335 }
336 }
337 }
338 }
339 }
340
341 # Check if the presence of some fields makes other fields optional.
342 while (my ($field, $dependent_optional) = each %{$profile->{dependent_optionals}} ) {
343 if (defined $valid{$field}) {
344 if (ref $dependent_optional eq "CODE") {
345 for my $value (_arrayify($valid{$field})) {
346 my $returned_optionals = $dependent_optional->($self, $value);
347
348
349
350 foreach my $optional (_arrayify($returned_optionals)) {
351 $optional{$optional} = 1;
352 }
353 }
354 } else {
355 foreach my $optional (_arrayify($dependent_optional)){
356 $optional{$optional} = 1;
357 }
358 }
359 }
360 }
361
267362 # Find unknown
268363 @unknown =
269364 grep { not (exists $optional{$_} or exists $required{$_} or exists $require_some{$_} ) } keys %valid;
851946
852947 # if it's a reference, return an array unless it points to an empty array. -mls
853948 if ( ref $val eq 'ARRAY' ) {
854 $^W = 0; # turn off warnings about undef
855 return ( any(@$val) ne undef ) ? @$val : ();
949 local $^W = 0; # turn off warnings about undef
950 return grep(defined, @$val) ? @$val : ();
856951 }
857952 # if it's a string, return an array unless the string is missing or empty. -mls
858953 else {
10701165 @v = $data->upload($k) || $data->param($k);
10711166 }
10721167 else {
1073 @v = $data->param($k);
1168 # insecure
1169 @v = $data->multi_param($k);
10741170 }
10751171
10761172 # we expect param to return an array if there are multiple values
33 # This file is part of Data::FormValidator.
44 #
55 # Author: Francis J. Lacoste
6 # Maintainer: Mark Stosberg <mark@stosberg.com>
6 # Previous Maintainer: Mark Stosberg <mark@stosberg.com>
7 # Maintainer: David Farrell <dfarrell@cpan.org>
78 #
89 # Copyright (C) 1999 Francis J. Lacoste, iNsu Innovations
910 # Parts Copyright 1996-1999 by Michael J. Heins
2223
2324 package Data::FormValidator;
2425 use Exporter 'import';
26 use File::Spec qw();
2527 use 5.008;
2628
27 use Perl6::Junction qw(any none);
2829 use Data::FormValidator::Results;
2930 *_arrayify = \&Data::FormValidator::Results::_arrayify;
3031 use Data::FormValidator::Filters ':filters';
3132 use Data::FormValidator::Constraints qw(:validators :matchers);
3233
33 our $VERSION = '4.81';
34 our $VERSION = 4.88;
3435
3536 our %EXPORT_TAGS = (
3637 filters => [qw/
122123 Data::FormValidator lets you define profiles which declare the
123124 required and optional fields and any constraints they might have.
124125
125 The results are provided as an object which makes it easy to handle
126 The results are provided as an object, which makes it easy to handle
126127 missing and invalid results, return error messages about which constraints
127128 failed, or process the resulting valid data.
128129
146147 $profiles = $profiles_or_file;
147148 }
148149 else {
149 $file = $profiles_or_file;
150 $file = File::Spec->rel2abs( $profiles_or_file );
150151 }
151152
152153
165166
166167 C<check> is the recommended method to use to validate forms. It returns its results as a
167168 L<Data::FormValidator::Results|Data::FormValidator::Results> object. A
168 deprecated method C<validate> is also available, returning its results as an
169 array described below.
169 deprecated method C<validate> described below is also available, returning its results as an
170 array.
170171
171172 use Data::FormValidator;
172173 my $results = Data::FormValidator->check(\%input_hash, \%dfv_profile);
474475 interdependent fields. The keys are arbitrary names that you create and
475476 the values are references to arrays of the field names in each group.
476477
478 =head2 dependencies_regexp
479
480 dependencies_regexp => {
481 qr/Line\d+\_ItemType$/ => sub {
482 my $dfv = shift;
483 my $itemtype = shift;
484 my $field = shift;
485
486 if ($type eq 'NeedsBatteries') {
487 my ($prefix, $suffix) = split(/\_/, $field);
488
489 return([$prefix . '_add_batteries]);
490 } else {
491 return([]);
492 }
493 },
494 },
495
496 This is a regular expression used to specify additional fields which are
497 dependent. For example, if you wanted to add dependencies for all fields which
498 meet a certain criteria (such as multiple items in a shopping cart) where you
499 do not know before hand how many of such fields you may have.
500
501 =head2 dependent_optionals
502
503 dependent_optionals => {
504 # If delivery_address is specified then delivery_notes becomes optional
505 "delivery_address" => [ qw( delivery_notes ) ],
506
507 # if delivery_type eq 'collection', collection_notes becomes optional
508 "delivery_type" => {
509 collection => [ qw( collection_notes ) ],
510 }
511
512 # if callback_type is "phone" or "email" then additional_notes becomes optional
513 "callback_type" => sub {
514 my $dfv = shift;
515 my $type = shift;
516
517 if ($type eq 'phone' || $type eq 'email') {
518 return(['additional_notes']);
519 } else {
520 return([]);
521 }
522 },
523 },
524
525 This is for the case where an optional field can trigger other optional fields.
526 The dependent optional fields can be specified with an array reference.
527
528 If the dependent optional fields are specified with a hash reference, then an
529 additional constraint is added that the optional field must equal a key for the
530 additional optional fields to be added.
531
532 If the dependent optional fields are specified as a code reference then the
533 code will be executed to determine the additional optional fields. It is passed
534 two parameters, the object and the value of the field, and it should return an
535 array reference containing the list of additional optional fields.
536
537 =head2 dependent_require_some
538
539 dependent_require_some => {
540 # require any fields from this group if AddressID is "new"
541 AddressID => sub {
542 my $dfv = shift;
543 my $value = shift;
544
545 if ($value eq 'new') {
546 return({
547 house_name_or_number => [ 1, 'HouseName', 'HouseNumber' ],
548 });
549 } else {
550 return;
551 }
552 },
553 }
554
555 Sometimes a field will need to trigger additional dependencies but you only
556 require some of the fields. You cannot set them all to be dependent as you
557 might only have some of them, and you cannot set them all to be optional as
558 you must have some of them. This method allows you to specify this in a
559 similar way to the equire_some method but dependent upon other values. In
560 the example above if the AddressID submitted is "new" then at least 1 of
561 HouseName and HouseNumber must also be supplied. See require_some for the
562 valid options for the return.
563
477564 =head2 defaults
478565
479566 defaults => {
866953 constraint and include a C<name> key with a value set to the name of your
867954 constraint. Here's an example:
868955
869 my_zipcode_field => [
870 'zip',
871 {
872 constraint => '/^406/',
873 name => 'starts_with_406',
874 }
875 ],
956 my_zipcode_field => [
957 'zip',
958 {
959 constraint_method => '/^406/',
960 name => 'starts_with_406',
961 }
962 ],
876963
877964 You can use an array reference with a single constraint in it if you just want
878965 to have the name of your failed constraint returned in the above fashion.
9221009 defaults
9231010 defaults_regexp_map
9241011 dependencies
1012 dependencies_regexp
9251013 dependency_groups
1014 dependent_optionals
1015 dependent_require_some
9261016 field_filter_regexp_map
9271017 field_filters
9281018 filters
9431033 # If any of the keys in the profile are not listed as
9441034 # valid keys here, we die with an error
9451035 for my $key (keys %$profile) {
946 push @invalid, $key unless ($key eq any(@valid_profile_keys));
1036 push @invalid, $key unless grep $key eq $_, @valid_profile_keys;
9471037 }
9481038
9491039 local $" = ', ';
9641054 # Could be improved by also naming the associated key for the bad value.
9651055 for my $key (grep { $profile->{$_} } qw/constraint_methods constraint_method_regexp_map/) {
9661056 for my $val (map { _arrayify($_) } values %{ $profile->{$key} }) {
967 if ((ref $val eq 'HASH') and ref $val->{constraint_method} eq none('CODE','Regexp')) {
1057 if (ref $val eq 'HASH' && !grep(ref $val->{constraint_method} eq $_, 'CODE','Regexp')) {
9681058 die "Value for constraint_method within hashref '$val->{constraint_method}' not a code reference or Regexp . Do you need func(), not 'func'?";
9691059 }
9701060 # Cases 1 through 4.
971 elsif (ref $val eq none('HASH','CODE','Regexp')) {
1061 elsif (!grep(ref $val eq $_, 'HASH','CODE','Regexp')) {
9721062 die "Value for constraint_method '$val' not a code reference or Regexp . Do you need func(), not 'func'?";
9731063 }
9741064 # Case 5.
9951085
9961086 for my $href (@constraint_hashrefs) {
9971087 for my $key (keys %$href) {
998 push @invalid, $key unless ($key eq any(@valid_constraint_hash_keys));
1088 push @invalid, $key unless grep $key eq $_, @valid_constraint_hash_keys;
9991089 }
10001090 }
10011091
10181108 /);
10191109 if (ref $profile->{msgs} eq 'HASH') {
10201110 for my $key (keys %{ $profile->{msgs} }) {
1021 push @invalid, $key unless ($key eq any(@valid_msgs_hash_keys));
1111 push @invalid, $key unless grep $key eq $_, @valid_msgs_hash_keys;
10221112 }
10231113 }
10241114 if (@invalid) {
11651255
11661256 =head2 constraint_regexp_map (profile key)
11671257
1168 This is a supported by deprecated profile key. Using
1258 This is a supported but deprecated profile key. Using
11691259 C<constraint_methods_regexp_map> is recommended instead.
11701260
11711261 constraint_regexp_map => {
12351325
12361326 =head1 CREDITS
12371327
1238 Some of those input validation functions have been taken from MiniVend
1328 Some of these input validation functions have been taken from MiniVend
12391329 by Michael J. Heins.
12401330
12411331 The credit card checksum validation was taken from contribution by Bruce
12441334 =head1 BUGS
12451335
12461336 Bug reports and patches are welcome. Reports which include a failing Test::More
1247 style test are helpful will receive priority.
1337 style test are helpful and will receive priority.
12481338
12491339 L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Data-FormValidator>
12501340
12511341 =head1 CONTRIBUTING
12521342
1253 This project is managed using the darcs source control system (
1254 http://www.darcs.net/ ). You can browse, pull and fork the repo here:
1255
1256 http://hub.darcs.net/markstos/Data--FormValidator
1257
1258 B<Support Mailing List>
1259
1260 If you have any questions, comments, or feature suggestions, post them to the
1261 support mailing list! To join the mailing list, visit
1262
1263 L<http://lists.sourceforge.net/lists/listinfo/cascade-dataform>
1264
1265 Messages about DFV sent directly to the maintainer may be redirected here.
1343 This project is maintained on L<Github|https://github.com/dnmfarrell/Data-FormValidator>.
12661344
12671345 =head1 AUTHOR
12681346
1269 Parts Copyright 2001-2006 by Mark Stosberg <mark at summersault.com>, (Current Maintainer)
1347 Currently maintained by David Farrell <dfarrell@cpan.org>
1348
1349 Parts Copyright 2001-2006 by Mark Stosberg <mark at summersault.com>, (previous maintainer)
12701350
12711351 Copyright (c) 1999 Francis J. Lacoste and iNsu Innovations Inc. All rights reserved.
12721352 (Original Author)
0
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
13 use Test::More tests => 5;
24
3 BEGIN {
5 BEGIN
6 {
47 use_ok('Data::FormValidator');
58 }
69
710 my $dfv;
8 eval { $dfv = Data::FormValidator->new({}, 'wrong'); };
9 like ($@, qr/must be a hash ref/, 'second argument must be a hash ref or die');
11 eval { $dfv = Data::FormValidator->new( {}, 'wrong' ); };
12 like( $@, qr/must be a hash ref/, 'second argument must be a hash ref or die' );
1013
11 eval {
12 $dfv = Data::FormValidator->new('test/00_base.WRONG');
13 my $results = $dfv->check({}, 'profile1');
14 eval {
15 $dfv = Data::FormValidator->new('test/00_base.WRONG');
16 my $results = $dfv->check( {}, 'profile1' );
1417 };
15 like($@, qr/no such file/i, 'bad profile file names should cause death');
18 like( $@, qr/no such file/i, 'bad profile file names should cause death' );
1619
17 eval {
18 $dfv = Data::FormValidator->new('test/00_base.badformat');
19 my $results = $dfv->check({}, 'profile1');
20 eval {
21 $dfv = Data::FormValidator->new('test/00_base.badformat');
22 my $results = $dfv->check( {}, 'profile1' );
2023 };
21 like($@, qr/return a hash ref/, 'profile files should return a hash ref');
24 like( $@, qr/return a hash ref/, 'profile files should return a hash ref' );
2225
2326 eval { $dfv = Data::FormValidator->new('test/00_base.profile'); };
2427
25 my $results = $dfv->check({}, 'profile1');
28 my $results = $dfv->check( {}, 'profile1' );
2629
27 ok(scalar $results->missing, 'loading a profile from a file works');
28
29
30
31
32
33
30 ok( scalar $results->missing, 'loading a profile from a file works' );
0
0 #!/usr/bin/env perl
11 use strict;
2
3 $^W = 1;
4
2 use warnings;
53 use Test::More tests => 8;
6
74 use Data::FormValidator;
85
96 my $input_profile = {
10 required => [ qw( email phone likes ) ],
11 optional => [ qq( toppings ) ],
12 constraints => {
13 email => "email",
14 phone => "phone",
15 likes => { constraint => sub {return 1;},
16 params => [ qw( likes email ) ],
17 },
18 },
19 dependencies => {
20 animal => [qw( species no_legs )],
21 plant => {
22 tree => [qw( trunk root )],
23 flower => [qw( petals stem )],
24 },
25 },
26 field_filters => {
27 email => sub {return $_[0];},
28 },
29 };
7 required => [qw( email phone likes )],
8 optional => [qq( toppings )],
9 constraints => {
10 email => "email",
11 phone => "phone",
12 likes => {
13 constraint => sub { return 1; },
14 params => [qw( likes email )],
15 },
16 },
17 dependencies => {
18 animal => [qw( species no_legs )],
19 plant => {
20 tree => [qw( trunk root )],
21 flower => [qw( petals stem )],
22 },
23 },
24 field_filters => {
25 email => sub { return $_[0]; },
26 },
27 };
3028
31 my $validator = new Data::FormValidator({default => $input_profile});
29 my $validator = new Data::FormValidator( { default => $input_profile } );
3230
33 my $input_hashref = {email => 'invalidemail',
34 phone => '201-999-9999',
35 likes => ['a','b'],
36 toppings => 'foo',
37 animal => 'goat',
38 plant => 'flower'};
31 my $input_hashref = {
32 email => 'invalidemail',
33 phone => '201-999-9999',
34 likes => [ 'a', 'b' ],
35 toppings => 'foo',
36 animal => 'goat',
37 plant => 'flower'
38 };
3939
40 my ($valids, $missings, $invalids, $unknowns);
40 my ( $valids, $missings, $invalids, $unknowns );
4141
42 eval{ ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default') };
42 eval
43 {
44 ( $valids, $missings, $invalids, $unknowns ) =
45 $validator->validate( $input_hashref, 'default' );
46 };
4347 is $@, '', 'survives';
4448
45 ok(exists $valids->{'phone'}, "phone is valid");
49 ok( exists $valids->{'phone'}, "phone is valid" );
4650
47 is($invalids->[0], 'email', 'email is invalid');
51 is( $invalids->[0], 'email', 'email is invalid' );
4852
4953 my %missings;
5054 @missings{@$missings} = ();
51 #print "@$missings\n";
52 ok(exists $missings{$_}) for (qw(species no_legs petals stem));
53 is(@$missings, 4);
54
55 ok( exists $missings{$_} ) for (qw(species no_legs petals stem));
56 is( @$missings, 4 );
0 #!/usr/bin/env perl
01 use strict;
1
2 $^W = 1;
3
4 use Test::More tests => 23;
2 use warnings;
3 use Test::More;
54 use Data::FormValidator;
65
76 # test profile
87 my $input_profile = {
9 dependencies => {
10 pay_type => {
11 Check => [qw( cc_num )],
12 # Value of Zero is used for test for a specific bug
13 0 => [qw( cc_num cc_exp cc_name )],
14 },
15 },
8 dependencies => {
9 pay_type => {
10 Check => [qw( cc_num )],
11
12 # Value of Zero is used for test for a specific bug
13 0 => [qw( cc_num cc_exp cc_name )],
14 },
15 },
1616 };
17 my $input_hashref = {pay_type=>'0'};
18
17 my $input_hashref = { pay_type => '0' };
1918
2019 ##
2120 ## Validate a complex dependency
2423 ##
2524 ## validate()
2625
27 my ($valids, $missings, $invalids, $unknowns);
28 my $validator = Data::FormValidator->new({default => $input_profile});
29 eval{
30 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
26 my ( $valids, $missings, $invalids, $unknowns );
27 my $validator = Data::FormValidator->new( { default => $input_profile } );
28 eval {
29 ( $valids, $missings, $invalids, $unknowns ) =
30 $validator->validate( $input_hashref, 'default' );
3131 };
32 ok(!$@, "no eval problems");
32 ok( !$@, "no eval problems" );
3333
34 my %missings = map {$_ => 1} @$missings;
35 ok($missings{cc_num}, "missing cc_num");
36 ok($missings{cc_exp}, "missing cc_exp");
37 ok($missings{cc_name}, "missing cc_name");
38
34 my %missings = map { $_ => 1 } @$missings;
35 ok( $missings{cc_num}, "missing cc_num" );
36 ok( $missings{cc_exp}, "missing cc_exp" );
37 ok( $missings{cc_name}, "missing cc_name" );
3938
4039 ##
4140 ## check()
4241
4342 my $result;
44 eval {
45 $result = $validator->check($input_hashref, 'default');
46 };
43 eval { $result = $validator->check( $input_hashref, 'default' ); };
4744
48 ok(!$@, "no eval problems");
49 isa_ok($result, "Data::FormValidator::Results", "returned object");
45 ok( !$@, "no eval problems" );
46 isa_ok( $result, "Data::FormValidator::Results", "returned object" );
5047
51 ok($result->has_missing, "has_missing returned true");
52 ok($result->missing('cc_num'), "missing('cc_num') returned true");
53 ok($result->missing('cc_exp'), "missing('cc_exp') returned true");
54 ok($result->missing('cc_name'), "missing('cc_name') returned true");
55
56
48 ok( $result->has_missing, "has_missing returned true" );
49 ok( $result->missing('cc_num'), "missing('cc_num') returned true" );
50 ok( $result->missing('cc_exp'), "missing('cc_exp') returned true" );
51 ok( $result->missing('cc_name'), "missing('cc_name') returned true" );
5752
5853 ##
5954 ## validate()
6055
61 $input_hashref = {pay_type=>'Check'
62 };
56 $input_hashref = { pay_type => 'Check' };
6357
64 eval{
65 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
58 eval {
59 ( $valids, $missings, $invalids, $unknowns ) =
60 $validator->validate( $input_hashref, 'default' );
6661 };
67 ok(!$@, "no eval problems");
62 ok( !$@, "no eval problems" );
6863
69 %missings = map {$_ => 1} @$missings;
70 ok($missings{cc_num}, 'missing cc_num');
71 ok(!$missings{cc_exp}, 'not missing cc_exp');
72 ok(!$missings{cc_name}, 'not missing cc_name');
73
64 %missings = map { $_ => 1 } @$missings;
65 ok( $missings{cc_num}, 'missing cc_num' );
66 ok( !$missings{cc_exp}, 'not missing cc_exp' );
67 ok( !$missings{cc_name}, 'not missing cc_name' );
7468
7569 ##
7670 ## check()
7771
7872 $result = undef;
79 eval {
80 $result = $validator->check($input_hashref, 'default');
81 };
73 eval { $result = $validator->check( $input_hashref, 'default' ); };
8274
83 ok(!$@, "no eval problems");
84 isa_ok($result, "Data::FormValidator::Results", "returned object");
75 ok( !$@, "no eval problems" );
76 isa_ok( $result, "Data::FormValidator::Results", "returned object" );
8577
86 ok($result->has_missing, "has_missing returned true");
87 ok($result->missing('cc_num'), "missing('cc_num') returned true");
88 is($result->missing('cc_exp'), undef, "missing('cc_exp') returned false");
89 is($result->missing('cc_name'), undef, "missing('cc_name') returned false");
78 ok( $result->has_missing, "has_missing returned true" );
79 ok( $result->missing('cc_num'), "missing('cc_num') returned true" );
80 is( $result->missing('cc_exp'), undef, "missing('cc_exp') returned false" );
81 is( $result->missing('cc_name'), undef, "missing('cc_name') returned false" );
9082
83 eval { require CGI;CGI->VERSION(4.35); };
84 SKIP:
85 {
86 skip 'CGI 4.35 or higher not found', 3 if $@;
9187
92
93 ## Now, some tests using a CGI.pm object as input
94 use CGI;
95 my $q = CGI->new('pay_type=0');
96 my $results;
97 eval {
98 $results = $validator->check($q, 'default');
99 };
100 ok($results->missing('cc_num'), 'using CGI.pm object for input');
101 is($result->missing('cc_exp'), undef, "missing('cc_exp') returned false");
102 is($result->missing('cc_name'), undef, "missing('cc_name') returned false");
103
104
105
106
88 my $q = CGI->new('pay_type=0');
89 my $results = $validator->check( $q, 'default' );
90 ok( $results->missing('cc_num'), 'using CGI.pm object for input' );
91 is( $result->missing('cc_exp'), undef, "missing('cc_exp') returned false" );
92 is( $result->missing('cc_name'), undef, "missing('cc_name') returned false" );
93 }
94 done_testing;
0 #!/usr/bin/env perl
01 use strict;
1 $^W = 1;
2
2 use warnings;
33 use Test::More tests => 4;
44
55 {
6 my $test_name =
7 "checks for correct behavior when 'required'
6 my $test_name = "checks for correct behavior when 'required'
87 is not specified; fails if _arrayify() does not return an empty list";
98
10 use Data::FormValidator;
11 my $input_profile = { optional => [ qw( email ) ] };
12 my $validator = Data::FormValidator->new({default => $input_profile});
9 use Data::FormValidator;
10 my $input_profile = { optional => [qw( email )] };
11 my $validator = Data::FormValidator->new( { default => $input_profile } );
1312
14 my $input_hashref = {email => 'bob@example.com' };
13 my $input_hashref = { email => 'bob@example.com' };
1514
16 my ($valids, $missings, $invalids, $unknowns);
17 eval{ ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default') };
18 is($@, '', $test_name);
19 is(@$missings, 0, $test_name);
15 my ( $valids, $missings, $invalids, $unknowns );
16 eval
17 {
18 ( $valids, $missings, $invalids, $unknowns ) =
19 $validator->validate( $input_hashref, 'default' );
20 };
21 is( $@, '', $test_name );
22 is( @$missings, 0, $test_name );
2023 }
2124
2225 {
23 my $test_name = "arrayref with first element undef";
24 use Data::FormValidator::Results;
26 my $test_name = "arrayref with first element undef";
27 use Data::FormValidator::Results;
2528
26 my $inputs = [ undef, 1, 2, 3, "Echo", "Foxtrot" ];
27 my $retval = Data::FormValidator::Results::_arrayify($inputs);
28 my @retval = Data::FormValidator::Results::_arrayify($inputs);
29 my $inputs = [ undef, 1, 2, 3, "Echo", "Foxtrot" ];
30 my $retval = Data::FormValidator::Results::_arrayify($inputs);
31 my @retval = Data::FormValidator::Results::_arrayify($inputs);
2932
30 is($retval, 6, "$test_name... in scalar context");
31 is_deeply(\@retval, $inputs, "$test_name..in list context");
33 is( $retval, 6, "$test_name... in scalar context" );
34 is_deeply( \@retval, $inputs, "$test_name..in list context" );
3235
3336 }
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More tests => 2;
4 use Data::FormValidator;
5
06 # performs a basic check to make sure valid_ip_address routine
17 # succeeds and fails when it should.
28 # by Mark Stosberg <mark@stosberg.com>
39
4 use strict;
10 my $input_profile = {
11 required => [qw( good_ip bad_ip )],
12 constraints => {
13 good_ip => 'ip_address',
14 bad_ip => 'ip_address',
15 } };
516
6 $^W = 1;
7
8 use Test::More tests => 2;
9
10 use Data::FormValidator;
11
12 my $input_profile = {
13 required => [ qw( good_ip bad_ip ) ],
14 constraints => {
15 good_ip => 'ip_address',
16 bad_ip => 'ip_address',
17 }
18 };
19
20 my $validator = new Data::FormValidator({default => $input_profile});
17 my $validator = new Data::FormValidator( { default => $input_profile } );
2118
2219 my $input_hashref = {
23 'good_ip' => '127.0.0.1',
24 'bad_ip' => '300.23.1.1',
25 };
26
27 my ($valids, $missings, $invalids, $unknowns);
28
29 eval{
30 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
20 'good_ip' => '127.0.0.1',
21 'bad_ip' => '300.23.1.1',
3122 };
3223
33 ok(exists $valids->{'good_ip'});
24 my ( $valids, $missings, $invalids, $unknowns );
3425
35 is($invalids->[0], 'bad_ip');
26 eval {
27 ( $valids, $missings, $invalids, $unknowns ) =
28 $validator->validate( $input_hashref, 'default' );
29 };
3630
31 ok( exists $valids->{'good_ip'} );
32
33 is( $invalids->[0], 'bad_ip' );
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More tests => 5;
1 use strict;
2
3 $^W = 1;
4
54 use Data::FormValidator;
65
76 my $input_profile = {
8 required => [ qw( email_1 email_ok) ],
9 optional => [qw/ extra first_name last_name /],
10 constraint_regexp_map => {
11 '/^email/' => "email",
12 },
13 field_filter_regexp_map => {
14 '/_name$/' => 'ucfirst',
15 }
16 };
7 required => [qw( email_1 email_ok)],
8 optional => [qw/ extra first_name last_name /],
9 constraint_regexp_map => {
10 '/^email/' => "email",
11 },
12 field_filter_regexp_map => {
13 '/_name$/' => 'ucfirst',
14 } };
1715
18 my $validator = new Data::FormValidator({default => $input_profile});
16 my $validator = new Data::FormValidator( { default => $input_profile } );
1917
2018 my $input_hashref = {
21 email_1 => 'invalidemail',
22 email_ok => 'mark@stosberg.com',
23 extra => 'unrelated field',
24 first_name => 'mark',
25 last_name => 'stosberg',
19 email_1 => 'invalidemail',
20 email_ok => 'mark@stosberg.com',
21 extra => 'unrelated field',
22 first_name => 'mark',
23 last_name => 'stosberg',
2624 };
2725
28 my ($valids, $missings, $invalids, $unknowns);
26 my ( $valids, $missings, $invalids, $unknowns );
2927
30 eval{
31 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
28 eval {
29 ( $valids, $missings, $invalids, $unknowns ) =
30 $validator->validate( $input_hashref, 'default' );
3231 };
33 ok (not $@);
34 ok ($invalids->[0] eq 'email_1');
32 ok( not $@ );
33 ok( $invalids->[0] eq 'email_1' );
3534
36 ok ($valids->{'email_ok'}) ;
37 ok ($valids->{'extra'});
38 ok ($valids->{'first_name'} eq 'Mark' and $valids->{'last_name'} eq 'Stosberg');
35 ok( $valids->{'email_ok'} );
36 ok( $valids->{'extra'} );
37 ok( $valids->{'first_name'} eq 'Mark'
38 and $valids->{'last_name'} eq 'Stosberg' );
3939
40 # Tests below added 04/24/03 to test adding constraints to fields with existing constraints
40 # Tests below added 04/24/03 to test adding constraints to fields with existing constraints
4141 eval {
42 my ($valids,$missings,$invalids) = Data::FormValidator->validate(
43 # input
44 {
45 with_no_constraint => 'f1 text',
46 with_one_constraint => 'f2 text',
47 with_mult_constraint => 'f2 text',
48 },
49 # profile
50 {
51 required=>[qw/with_no_constraint with_one_constraint with_mult_constraint/],
52 constraints=> {
53 with_one_constraint => 'email',
54 with_mult_constraint => ['email','american_phone'],
55 },
56 constraint_regexp_map => {
57 '/^with/' => 'state',
58 },
59 msgs=>{},
60 }
61 )
42 my ( $valids, $missings, $invalids ) = Data::FormValidator->validate(
43
44 # input
45 {
46 with_no_constraint => 'f1 text',
47 with_one_constraint => 'f2 text',
48 with_mult_constraint => 'f2 text',
49 },
50
51 # profile
52 {
53 required =>
54 [qw/with_no_constraint with_one_constraint with_mult_constraint/],
55 constraints => {
56 with_one_constraint => 'email',
57 with_mult_constraint => [ 'email', 'american_phone' ],
58 },
59 constraint_regexp_map => {
60 '/^with/' => 'state',
61 },
62 msgs => {},
63 } );
6264 };
6365
64 TODO: {
65 local $TODO = 'rewrite when message system is rebuilt';
66 #ok (not $@) ir diag $@;
67 #like($invalids->{with_no_constraint}, qr/Invalid/ , '...with no existing constraints');
68 #ok(scalar @{ $invalids->{with_one_constraint} } eq 2, '...with one existing constraint');
69 #ok(scalar @{ $invalids->{with_mult_constraint} } eq 3,'...with two existing constraints');
70 };
66 TODO:
67 {
68 local $TODO = 'rewrite when message system is rebuilt';
69
70 #ok (not $@) ir diag $@;
71 #like($invalids->{with_no_constraint}, qr/Invalid/ , '...with no existing constraints');
72 #ok(scalar @{ $invalids->{with_one_constraint} } eq 2, '...with one existing constraint');
73 #ok(scalar @{ $invalids->{with_mult_constraint} } eq 3,'...with two existing constraints');
74 }
0
0 #!/usr/bin/env perl
11 use strict;
2
3 $^W = 1;
4
2 use warnings;
53 use Test::More tests => 4;
6
74 use Data::FormValidator;
85
96 my $input_profile = {
10 require_some => {
11 testing_default_to_1 => [qw/one missing1 missing2/],
12 '2_of_3_success' => [2,qw/blue green red/],
13 '2_of_3_fail' => [2,qw/foo bar zar/],
14 },
15 };
7 require_some => {
8 testing_default_to_1 => [qw/one missing1 missing2/],
9 '2_of_3_success' => [ 2, qw/blue green red/ ],
10 '2_of_3_fail' => [ 2, qw/foo bar zar/ ],
11 },
12 };
1613
17 my $validator = new Data::FormValidator({default => $input_profile});
14 my $validator = new Data::FormValidator( { default => $input_profile } );
1815
1916 my $input_hashref = {
20 one => 1,
21 blue => 1,
22 green => 1,
17 one => 1,
18 blue => 1,
19 green => 1,
2320 };
2421
25 my ($valids, $missings, $invalids, $unknowns);
22 my ( $valids, $missings, $invalids, $unknowns );
2623
27 eval{
28 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
24 eval {
25 ( $valids, $missings, $invalids, $unknowns ) =
26 $validator->validate( $input_hashref, 'default' );
2927 };
3028
31 ok($valids->{blue});
32 ok($valids->{green});
33 ok($valids->{one});
29 ok( $valids->{blue} );
30 ok( $valids->{green} );
31 ok( $valids->{one} );
3432
35 ok(grep {/2_of_3_fail/} @$missings);
36
37
33 ok( grep { /2_of_3_fail/ } @$missings );
0 #!/usr/bin/env perl
01 use strict;
1 #Check that the match_* routines are nominally working.
2
3 $^W = 1;
4
2 use warnings;
53 use Test::More tests => 26;
6
7
84 use Data::FormValidator qw(:validators :matchers);
95
6 #Check that the match_* routines are nominally working.
107 my $invalid = "fake value";
118
129 #For CC Exp test
1310 my @time = localtime(time);
1411
15 my %tests = (
16 match_american_phone => "555-555-5555",
17 match_cc_exp => "10/" . sprintf("%.2d", ($time[5] - 99)),
18 match_cc_type => "MasterCard",
19 match_email => 'foo@domain.com',
20 match_ip_address => "64.58.79.230",
21 match_phone => "123-456-7890",
22 match_postcode => "T2N 0E6",
23 match_province => "NB",
24 match_state => "CA",
25 match_state_or_province => "QC",
26 match_zip => "94112",
27 match_zip_or_postcode => "50112",
12 my %tests = (
13 match_american_phone => "555-555-5555",
14 match_cc_exp => "10/" . sprintf( "%.2d", ( $time[5] - 99 ) ),
15 match_cc_type => "MasterCard",
16 match_email => 'foo@domain.com',
17 match_ip_address => "64.58.79.230",
18 match_phone => "123-456-7890",
19 match_postcode => "T2N 0E6",
20 match_province => "NB",
21 match_state => "CA",
22 match_state_or_province => "QC",
23 match_zip => "94112",
24 match_zip_or_postcode => "50112",
2825 );
2926
3027 my $i = 1;
3128
32 foreach my $function (keys(%tests)) {
33 my $rv;
34 my $val = $tests{$function};
35 my $is_valid = "\$rv = $function('$val');";
36 my $not_valid = "\$rv = $function('$invalid');";
37
38 eval $is_valid;
39 ok(not $@ and ($rv eq $val)) or
40 diag sprintf("%-25s using %-16s", $function, "valid value. ");
41 $i++;
29 foreach my $function ( keys(%tests) )
30 {
31 my $rv;
32 my $val = $tests{$function};
33 my $is_valid = "\$rv = $function('$val');";
34 my $not_valid = "\$rv = $function('$invalid');";
4235
43 eval $not_valid;
44 ok(not $@ and not $rv) or
45 diag sprintf("%-25s using %-16s", $function, "invalid value. ");
46 $i++;
36 eval $is_valid;
37 ok( not $@ and ( $rv eq $val ) )
38 or diag sprintf( "%-25s using %-16s", $function, "valid value. " );
39 $i++;
40
41 eval $not_valid;
42 ok( not $@ and not $rv )
43 or diag sprintf( "%-25s using %-16s", $function, "invalid value. " );
44 $i++;
4745 }
48
46
4947 #Test cc_number separately since it takes multiple parameters
5048 my $rv;
5149 my $num = '4111111111111111';
5250 eval "\$rv = match_cc_number('$num', 'v')";
53 ok(not $@ and ($rv eq $num)) or
54 diag sprintf("%-25s using %-16s", "match_cc_number", "valid value. ");
51 ok( not $@ and ( $rv eq $num ) )
52 or diag sprintf( "%-25s using %-16s", "match_cc_number", "valid value. " );
5553
5654 eval "\$rv = match_cc_number('$invalid', 'm')";
57 ok(not $@ and not $rv) or
58 diag sprintf("%-25s using %-16s", "match_cc_number", "invalid value. ");
55 ok( not $@ and not $rv )
56 or diag sprintf( "%-25s using %-16s", "match_cc_number", "invalid value. " );
0
0 #!/usr/bin/env perl
11 use strict;
2 use lib ('.','../t','t/');
3
4 $^W = 1;
5
2 use warnings;
3 use lib ( '.', '../t', 't/' );
64 use Test::More tests => 8;
7
85 use Data::FormValidator;
96
107 my $input_profile = {
11 validator_packages => 'ValidatorPackagesTest1',
12 required => ['required_1','required_2','required_3'],
13 constraints => {
14 required_1 => 'single_validator_success_expected',
15 required_2 => 'single_validator_failure_expected',
16 },
17 field_filters => {
18 required_3 => 'single_filter_remove_whitespace',
19 },
20 };
8 validator_packages => 'ValidatorPackagesTest1',
9 required => [ 'required_1', 'required_2', 'required_3' ],
10 constraints => {
11 required_1 => 'single_validator_success_expected',
12 required_2 => 'single_validator_failure_expected',
13 },
14 field_filters => {
15 required_3 => 'single_filter_remove_whitespace',
16 },
17 };
2118
22 my $validator = new Data::FormValidator({default => $input_profile});
19 my $validator = new Data::FormValidator( { default => $input_profile } );
2320
2421 my $input_hashref = {
25 required_1 => 123,
26 required_2 => 'testing',
27 required_3 => ' has whitespace ',
22 required_1 => 123,
23 required_2 => 'testing',
24 required_3 => ' has whitespace ',
2825 };
2926
30 my ($valids, $missings, $invalids, $unknowns);
27 my ( $valids, $missings, $invalids, $unknowns );
3128
32 eval{
33 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
29 eval {
30 ( $valids, $missings, $invalids, $unknowns ) =
31 $validator->validate( $input_hashref, 'default' );
3432 };
35 ok(not $@) or
36 diag "eval error: $@";
33 ok( not $@ )
34 or diag "eval error: $@";
3735
38 ok(defined $valids->{required_1});
36 ok( defined $valids->{required_1} );
3937
4038 # Test to make sure that the field failed imported validator
41 ok(grep /required_2/, @$invalids);
39 ok( grep /required_2/, @$invalids );
4240
43 ok(defined $valids->{required_3});
41 ok( defined $valids->{required_3} );
4442
45 is($valids->{required_3}, 'has whitespace');
43 is( $valids->{required_3}, 'has whitespace' );
4644
4745 #### Now test importing from multiple packages
4846
4947 $input_profile = {
50 validator_packages => ['ValidatorPackagesTest1','ValidatorPackagesTest2'],
51 required => ['required_1','required_2'],
52 constraints => {
53 required_1 => 'single_validator_success_expected',
54 required_2 => 'multi_validator_success_expected',
55 },
56 };
48 validator_packages => [ 'ValidatorPackagesTest1', 'ValidatorPackagesTest2' ],
49 required => [ 'required_1', 'required_2' ],
50 constraints => {
51 required_1 => 'single_validator_success_expected',
52 required_2 => 'multi_validator_success_expected',
53 },
54 };
5755
58 $validator = new Data::FormValidator({default => $input_profile});
56 $validator = new Data::FormValidator( { default => $input_profile } );
5957
6058 $input_hashref = {
61 required_1 => 123,
62 required_2 => 'testing',
59 required_1 => 123,
60 required_2 => 'testing',
6361 };
6462
65 eval{
66 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
63 eval {
64 ( $valids, $missings, $invalids, $unknowns ) =
65 $validator->validate( $input_hashref, 'default' );
6766 };
6867
68 ok( defined $valids->{required_1} );
6969
70 ok(defined $valids->{required_1});
71
72 ok(defined $valids->{required_2});
70 ok( defined $valids->{required_2} );
7371
7472 # Now test calling 'validate' as a class method
7573 use Data::FormValidator;
7674
7775 eval {
78 my ($valid,$missing,$invalid) = Data::FormValidator->validate($input_hashref,{
79 required=>[qw/required_1/],
80 validator_packages=> 'Data::FormValidator',
81 });
76 my ( $valid, $missing, $invalid ) = Data::FormValidator->validate(
77 $input_hashref,
78 {
79 required => [qw/required_1/],
80 validator_packages => 'Data::FormValidator',
81 } );
8282 };
83 ok(not $@);
84
85
83 ok( not $@ );
0
0 #!/usr/bin/env perl
11 use strict;
2 use lib ('.','../t');
3
4 $^W = 1;
5
2 use warnings;
3 use lib ( '.', '../t' );
64 use Test::More tests => 1;
7
85 use Data::FormValidator;
96
107 my $input_profile = {
11 required => ['my_zipcode_field'],
12 constraints => {
13 my_zipcode_field => {
14 constraint => \&starts_with_402,
15 params => ['my_zipcode_field', \'cow'],
16 },
17 },
18 untaint_all_constraints=>1,
8 required => ['my_zipcode_field'],
9 constraints => {
10 my_zipcode_field => {
11 constraint => \&starts_with_402,
12 params => [ 'my_zipcode_field', \'cow' ],
13 },
14 },
15 untaint_all_constraints => 1,
1916
2017 };
2118
22 my $validator = new Data::FormValidator({default => $input_profile});
19 my $validator = new Data::FormValidator( { default => $input_profile } );
2320
24 my $input_hashref = {
25 my_zipcode_field => 'big brown',
26 };
21 my $input_hashref = { my_zipcode_field => 'big brown', };
2722
28 sub starts_with_402 {
29 my ($zip, $cow) = @_;
30 return "$zip $$cow";
23 sub starts_with_402
24 {
25 my ( $zip, $cow ) = @_;
26 return "$zip $$cow";
3127 }
3228
33 my ($valids, $missings, $invalids, $unknowns);
34 eval{
35 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
29 my ( $valids, $missings, $invalids, $unknowns );
30 eval {
31 ( $valids, $missings, $invalids, $unknowns ) =
32 $validator->validate( $input_hashref, 'default' );
3633 };
3734
3835 # Test to make sure that the constraint receives a literal value of an element passed by reference
39 is($valids->{my_zipcode_field}, 'big brown cow');
40
41
36 is( $valids->{my_zipcode_field}, 'big brown cow' );
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use lib ( '.', '../t' );
4 use Test::More;
5 use Data::FormValidator;
6
07 # This script tests whether a CGI.pm object can be used to provide the input data
1 # Mark Stosberg 02/16/03
8 # Mark Stosberg 02/16/03
29
3 use strict;
4 use lib ('.','../t');
5
6 $^W = 1;
7
8 use Test::More tests => 2;
10 eval { require CGI;CGI->VERSION(4.35); };
11 plan skip_all => 'CGI 4.35 or higher not found' if $@;
912
1013 my $q;
14 eval { $q = CGI->new( { my_zipcode_field => 'big brown' } ); };
15 ok( not $@ );
16
17 my $input_profile = { required => ['my_zipcode_field'], };
18
19 my $validator = new Data::FormValidator( { default => $input_profile } );
20
21 my ( $valids, $missings, $invalids, $unknowns );
1122 eval {
12 use CGI;
13 $q = CGI->new({ my_zipcode_field => 'big brown' });
14 };
15 ok(not $@);
16
17 use Data::FormValidator;
18
19 my $input_profile = {
20 required => ['my_zipcode_field'],
23 ( $valids, $missings, $invalids, $unknowns ) =
24 $validator->validate( $q, 'default' );
2125 };
2226
23 my $validator = new Data::FormValidator({default => $input_profile});
24
25 my ($valids, $missings, $invalids, $unknowns);
26 eval{
27 ($valids, $missings, $invalids, $unknowns) = $validator->validate($q, 'default');
28 };
29
30 is($valids->{my_zipcode_field}, 'big brown');
31
27 is( $valids->{my_zipcode_field}, 'big brown' );
28 done_testing;
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use lib ( '.', '../t' );
4 use Test::More tests => 8;
5 use Data::FormValidator;
6
07 # This script tests validating keys with multiple data
1 use strict;
2 use lib ('.','../t');
3
4 $^W = 1;
5
6 use Test::More tests => 8;
7
8 my $input_hash = {
9 single_value => ' Just One ',
10 multi_values => [' One ', ' Big ', ' Happy ', ' Family '],
11 re_multi_test => [qw/at the circus/],
12 constraint_multi_test => [qw/12345 22234 oops/],
8 my $input_hash = {
9 single_value => ' Just One ',
10 multi_values => [ ' One ', ' Big ', ' Happy ', ' Family ' ],
11 re_multi_test => [qw/at the circus/],
12 constraint_multi_test => [qw/12345 22234 oops/],
13 };
14 my $input_profile = {
15 required =>
16 [qw/single_value multi_values re_multi_test constraint_multi_test/],
17 filters => [qw/trim/],
18 field_filters => {
19 single_value => 'lc',
20 multi_values => 'uc',
21 },
22 field_filter_regexp_map => {
23 '/_multi_test$/' => 'ucfirst',
24 },
25 constraints => {
26 constraint_multi_test => 'zip',
27 },
1328 };
1429
30 my $validator = new Data::FormValidator( { default => $input_profile } );
1531
16 use Data::FormValidator;
17
18 my $input_profile = {
19 required => [qw/single_value multi_values re_multi_test constraint_multi_test/],
20 filters => [qw/trim/],
21 field_filters => {
22 single_value => 'lc',
23 multi_values => 'uc',
24 },
25 field_filter_regexp_map => {
26 '/_multi_test$/' => 'ucfirst',
27 },
28 constraints => {
29 constraint_multi_test => 'zip',
30 },
32 my ( $valids, $missings, $invalids, $unknowns );
33 eval {
34 ( $valids, $missings, $invalids, $unknowns ) =
35 $validator->validate( $input_hash, 'default' );
3136 };
3237
33 my $validator = new Data::FormValidator({default => $input_profile});
38 is( $valids->{single_value},
39 'just one', 'inconditional filters still work with single values' );
3440
35 my ($valids, $missings, $invalids, $unknowns);
36 eval{
37 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hash, 'default');
38 };
41 is( lc $valids->{multi_values}->[0],
42 lc 'one', 'inconditional filters work with multi values' );
3943
40 is($valids->{single_value},'just one',
41 'inconditional filters still work with single values'
42 );
44 is( $valids->{multi_values}->[0],
45 'ONE', 'field filters work with multiple values' );
4346
44 is(lc $valids->{multi_values}->[0],lc 'one',
45 'inconditional filters work with multi values'
46 );
47 is( $valids->{re_multi_test}->[0],
48 'At', 'Test the filters applied to multiple values by RE work' );
4749
48 is($valids->{multi_values}->[0],'ONE',
49 'field filters work with multiple values'
50 );
51
52 is($valids->{re_multi_test}->[0] ,'At',
53 'Test the filters applied to multiple values by RE work'
54 );
55
56 ok(!$valids->{constraint_multi_test},
57 'If any of the values fail the constraint, the field becomes invalid'
58 );
50 ok( !$valids->{constraint_multi_test},
51 'If any of the values fail the constraint, the field becomes invalid' );
5952
6053 my $r;
61 eval { $r = Data::FormValidator->check({ undef_multi => [undef] }, { required => 'undef_multi' }) };
54 eval
55 {
56 $r = Data::FormValidator->check( { undef_multi => [undef] },
57 { required => 'undef_multi' } );
58 };
6259 diag "error: $@" if $@;
63 ok($r->missing('undef_multi'), 'multi-valued field containing only undef should be missing');
60 ok( $r->missing('undef_multi'),
61 'multi-valued field containing only undef should be missing' );
6462
6563 my $v;
6664 eval { $v = $r->valid('undef_multi'); };
6765 diag "error: $@" if $@;
68 ok(!$v, 'multiple valued fields containing only undefined values should not be valid');
69
66 ok( !$v,
67 'multiple valued fields containing only undefined values should not be valid'
68 );
7069
7170 ###
7271
73 eval { $r = Data::FormValidator->check({
74 cc_type => ['Check'],
72 eval {
73 $r = Data::FormValidator->check( {
74 cc_type => ['Check'],
75 },
76 {
77 required => 'cc_type',
78 dependencies => {
79 cc_type => {
80 Check => [qw( cc_num )],
81 Visa => [qw( cc_num cc_exp cc_name )],
7582 },
76 {
77 required => 'cc_type',
78 dependencies => {
79 cc_type => {
80 Check => [qw( cc_num )],
81 Visa => [qw( cc_num cc_exp cc_name )],
82 },
83 },
84 }) };
83 },
84 } );
85 };
8586 diag "error: $@" if $@;
8687
87 ok($r->missing('cc_num'), 'a single valued array should still trigger the dependency check');
88 ok( $r->missing('cc_num'),
89 'a single valued array should still trigger the dependency check' );
0 #!/usr/bin/env perl
01 #!/usr/bin/perl -w
2 use strict;
3 use warnings;
4 use lib ( '.', '../t' );
5 use Test::More tests => 4;
6 use Data::FormValidator;
17
28 # This tests for some constraint related bugs found by Chris Spiegel
9 my $input_profile = {
10 required => [qw( email subroutine )],
11 constraints => {
12 subroutine => sub { 0 },
13 } };
314
4 use lib ('.','../t');
5
6 $^W = 1;
7
8 use Test::More tests => 4;
9
10 use strict;
11 use Data::FormValidator;
12
13 my $input_profile =
14 {
15 required => [ qw( email subroutine ) ],
16 constraints =>
17 {
18 subroutine => sub { 0 },
19 }
20 };
21
22 my $validator = new Data::FormValidator({default => $input_profile});
15 my $validator = new Data::FormValidator( { default => $input_profile } );
2316
2417 my $input_hashref = { subroutine => 'anything' };
2518
26 my ($valids, $missings, $invalids, $unknowns) = ({},[],[],[]);
19 my ( $valids, $missings, $invalids, $unknowns ) = ( {}, [], [], [] );
2720
28 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
21 ( $valids, $missings, $invalids, $unknowns ) =
22 $validator->validate( $input_hashref, 'default' );
2923
3024 # We need to make sure we do not get a reference back here
31 ok(not ref $invalids->[0]);
25 ok( not ref $invalids->[0] );
3226
33 $input_profile =
34 {
35 required => [ qw( email) ],
36 constraints =>
37 {
38 email =>
39 [
40 {
41 constraint => 'email',
42 name => 'Your email address is invalid.',
43 }
44 ],
45 }
46 };
27 $input_profile = {
28 required => [qw( email)],
29 constraints => {
30 email => [ {
31 constraint => 'email',
32 name => 'Your email address is invalid.',
33 }
34 ],
35 } };
4736
48 $validator = new Data::FormValidator({default => $input_profile});
37 $validator = new Data::FormValidator( { default => $input_profile } );
4938
5039 eval {
51 ($valids, $missings, $invalids, $unknowns) = $validator->validate({ email => 'invalid'}, 'default');
40 ( $valids, $missings, $invalids, $unknowns ) =
41 $validator->validate( { email => 'invalid' }, 'default' );
5242 };
53 is($@,'','survived eval');
43 is( $@, '', 'survived eval' );
5444
55 is($invalids->[0]->[0], 'email');
56 is($invalids->[0]->[1], 'Your email address is invalid.');
57
58
59
45 is( $invalids->[0]->[0], 'email' );
46 is( $invalids->[0]->[1], 'Your email address is invalid.' );
0 #!/usr/bin/perl -w
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use lib ( '.', '../t' );
4 use Test::More tests => 3;
5 use Data::FormValidator;
16
27 # This tests to make sure that we can use hashrefs and code refs as OK values in the input hash
38 # inspired by a patch from Boris Zentner
9 my $input_profile = { required => [qw( arrayref hashref coderef )], };
410
5 use lib ('.','../t');
11 my $validator = new Data::FormValidator( { default => $input_profile } );
612
7 $^W = 1;
8
9 use Test::More tests => 3;
10
11 use strict;
12 use Data::FormValidator;
13
14 my $input_profile =
15 {
16 required => [ qw( arrayref hashref coderef ) ],
13 my $input_hashref = {
14 arrayref => [ '', 1, 2 ],
15 hashref => { tofu => 'good' },
16 coderef => sub { return 'the answer is 42' },
1717 };
1818
19 my $validator = new Data::FormValidator({default => $input_profile});
19 my ( $valids, $missings, $invalids, $unknowns ) = ( {}, [], [], [] );
2020
21 my $input_hashref = {
22 arrayref => ['', 1,2],
23 hashref => {tofu => 'good'},
24 coderef => sub { return 'the answer is 42' },
25 };
26
27 my ($valids, $missings, $invalids, $unknowns) = ({},[],[],[]);
28
29 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
21 ( $valids, $missings, $invalids, $unknowns ) =
22 $validator->validate( $input_hashref, 'default' );
3023
3124 # empty strings in arrays should be set to "undef"
32 ok(not defined $valids->{arrayref}->[0]);
25 ok( not defined $valids->{arrayref}->[0] );
3326
3427 # hash refs and code refs should be ok.
35 is(ref $valids->{hashref}, 'HASH');
36 is(ref $valids->{coderef}, 'CODE');
37
38
39
28 is( ref $valids->{hashref}, 'HASH' );
29 is( ref $valids->{coderef}, 'CODE' );
0 #!/usr/bin/perl -w
1
2 # This tests to make sure that when we test $@, we are testing the right thing.
3 # inspired by a patch from dom@semantico.com
4 use lib ('.','../t');
5
6 $^W = 1;
7
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use lib ( '.', '../t' );
84 use Test::More tests => 1;
9
10 use strict;
115 use Data::FormValidator;
126
137 # So as to not trigger a require later on in the code.
148 require UNIVERSAL;
159
16 my $input_profile =
17 {
18 required => 'nothing',
19 };
10 # This tests to make sure that when we test $@, we are testing the right thing.
11 # inspired by a patch from dom@semantico.com
12 my $input_profile = { required => 'nothing', };
2013
21 my $validator = new Data::FormValidator({default => $input_profile});
14 my $validator = new Data::FormValidator( { default => $input_profile } );
2215
23 my $input_hashref = {
24 '1_required' => 1,
25 '1_optional' => 1,
16 my $input_hashref = {
17 '1_required' => 1,
18 '1_optional' => 1,
2619 };
2720
2821 eval {
29 # populate $@ to see if D::FV dies when it shouldn't
30 $@ = 'exceptional value';
31 my ($valids, $missings, $invalids, $unknowns) = ({},[],[],[]);
32 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
22 # populate $@ to see if D::FV dies when it shouldn't
23 $@ = 'exceptional value';
24 my ( $valids, $missings, $invalids, $unknowns ) = ( {}, [], [], [] );
25 ( $valids, $missings, $invalids, $unknowns ) =
26 $validator->validate( $input_hashref, 'default' );
3327 };
3428
35 unlike($@, qr/Error compiling regular expression/);
29 unlike( $@, qr/Error compiling regular expression/ );
3630
3731 # vim: set ai et sw=8 syntax=perl :
0 #!/usr/bin/env perl
01 use strict;
2 use warnings;
13 use Test::More tests => 3;
2 use lib ('.','../t');
4 use lib ( '.', '../t' );
5 use Data::FormValidator;
36
47 # Verify that multiple params passed to a constraint are being handled correctly
8 my $validator = new Data::FormValidator( {
9 default => {
10 required => [qw/my_zipcode_field my_other_field/],
11 constraints => {
12 my_zipcode_field => {
13 constraint => \&zipcode_check,
14 name => 'zipcode',
15 params => [ 'my_zipcode_field', 'my_other_field' ],
16 },
17 },
18 },
19 } );
520
6 $^W = 1;
21 my @args_for_check; # to control which args were given
722
8
9 use Data::FormValidator;
10
11 my $validator = new Data::FormValidator({
12 default =>
13 {
14 required => [ qw/my_zipcode_field my_other_field/],
15 constraints => {
16 my_zipcode_field => {
17 constraint => \&zipcode_check,
18 name => 'zipcode',
19 params => [ 'my_zipcode_field', 'my_other_field' ],
20 },
21 },
22 },
23 });
24
25 my @args_for_check; # to control which args were given
26
27 sub zipcode_check {
23 sub zipcode_check
24 {
2825 @args_for_check = @_;
29 if ($_[0] == 402015 and $_[1] eq 'mapserver_rulez') {
26 if ( $_[0] == 402015 and $_[1] eq 'mapserver_rulez' )
27 {
3028 return 1;
3129 }
3230 return 0;
3331 }
3432
35 my $input_hashref =
36 {
37 my_zipcode_field => '402015',
38 my_other_field => 'mapserver_rulez',
39 };
40
41 my ($valids, $missings, $invalids, $unknowns);
42
43 eval{
44 ($valids, $missings, $invalids, $unknowns) =
45 $validator->validate($input_hashref, 'default');
33 my $input_hashref = {
34 my_zipcode_field => '402015',
35 my_other_field => 'mapserver_rulez',
4636 };
4737
48 ok(not $@) or
49 diag "eval error: $@";
38 my ( $valids, $missings, $invalids, $unknowns );
5039
51 ok(not grep { (ref $_) eq 'ARRAY' } @$invalids) or
52 diag $#{$invalids};
40 eval {
41 ( $valids, $missings, $invalids, $unknowns ) =
42 $validator->validate( $input_hashref, 'default' );
43 };
5344
45 ok( not $@ )
46 or diag "eval error: $@";
5447
55 is_deeply(\@args_for_check, [402015,'mapserver_rulez']);
48 ok( not grep { ( ref $_ ) eq 'ARRAY' } @$invalids )
49 or diag $#{$invalids};
50
51 is_deeply( \@args_for_check, [ 402015, 'mapserver_rulez' ] );
5652
5753 # Local variables:
5854 # compile-command: "cd .. && make test"
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More tests => 7;
1
2 use Data::FormValidator;
4 use Data::FormValidator;
35
46 my %FORM = (
5 stick => 'big',
6 speak => 'softly',
7 mv => ['first','second'],
7 stick => 'big',
8 speak => 'softly',
9 mv => [ 'first', 'second' ],
810 );
911
10 my $results = Data::FormValidator->check(\%FORM,
11 {
12 required => [ 'stick', 'fromsub', 'whoami' ],
13 optional => ['mv', 'opt_1', 'opt_2', ],
14 defaults => {
15 fromsub => sub { return "got value from a subroutine"; },
16 },
17 defaults_regexp_map => {
18 qr/^opt_/ => 2,
19 },
20 }
12 my $results = Data::FormValidator->check(
13 \%FORM,
14 {
15 required => [ 'stick', 'fromsub', 'whoami' ],
16 optional => [ 'mv', 'opt_1', 'opt_2', ],
17 defaults => {
18 fromsub => sub { return "got value from a subroutine"; },
19 },
20 defaults_regexp_map => {
21 qr/^opt_/ => 2,
22 },
23 } );
24
25 ok( $results->valid('stick') eq 'big', 'using check() as class method' );
26 is( $results->valid('stick'),
27 $FORM{stick}, 'valid() returns single value in scalar context' );
28 my @mv = $results->valid('mv');
29 is_deeply( \@mv, $FORM{mv}, 'valid() returns multi-valued results' );
30 my @stick = $results->valid('stick');
31 is_deeply(
32 \@stick,
33 [ $FORM{stick} ],
34 'valid() returns single value in list context'
2135 );
22
23 ok($results->valid('stick') eq 'big','using check() as class method');
24 is($results->valid('stick'),$FORM{stick}, 'valid() returns single value in scalar context');
25 my @mv = $results->valid('mv');
26 is_deeply(\@mv,$FORM{mv}, 'valid() returns multi-valued results');
27 my @stick = $results->valid('stick');
28 is_deeply(\@stick,[ $FORM{stick} ], 'valid() returns single value in list context');
29 ok($results->valid('fromsub') eq "got value from a subroutine", 'usg CODE references as default values');
36 ok( $results->valid('fromsub') eq "got value from a subroutine",
37 'usg CODE references as default values' );
3038
3139 {
32 is( $results->valid('opt_1'), 2, "defaults_regexp works (case 1)");
33 is( $results->valid('opt_2'), 2, "defaults_regexp works (case 1)");
40 is( $results->valid('opt_1'), 2, "defaults_regexp works (case 1)" );
41 is( $results->valid('opt_2'), 2, "defaults_regexp works (case 1)" );
3442
3543 }
36
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More qw/no_plan/;
4 use Data::FormValidator;
5
06 # Testing new support for 'qr'. -mls
7 my %FORM = (
8 stick => 'big',
9 speak => 'softly',
110
2 use Test::More qw/no_plan/;
11 bad_email => 'doops',
12 good_email => 'great@domain.com',
313
4 use Data::FormValidator;
14 'short_name' => 'tim',
515
6 my %FORM = (
7 stick => 'big',
8 speak => 'softly',
16 'not_oops' => 'hoops',
917
10 bad_email => 'doops',
11 good_email => 'great@domain.com',
12
13 'short_name' => 'tim',
14
15 'not_oops' => 'hoops',
16
17 'untainted_with_qr' => 'Slimy',
18 'untainted_with_qr' => 'Slimy',
1819 );
1920
20 my $results = Data::FormValidator->check(\%FORM, {
21 required_regexp => qr/stick/,
22 optional_regexp => '/_email$/',
23 constraint_regexp_map => {
24 qr/email/ => 'email',
21 my $results = Data::FormValidator->check(
22 \%FORM,
23 {
24 required_regexp => qr/stick/,
25 optional_regexp => '/_email$/',
26 constraint_regexp_map => {
27 qr/email/ => 'email',
2528
26 },
27 field_filter_regexp_map => {
28 qr/_name$/ => 'ucfirst',
29 },
30 required => 'speak',
31 optional => [qw/short_name not_oops untainted_with_qr/],
32 constraints => {
33 not_oops => {
34 name => 'start_with_oop',
35 constraint => qr/^oop/,
36 },
37 untainted_with_qr => qr/(Slim)/,
38 speak => qr/quietly|softly/,
39 stick => qr/big|large/,
29 },
30 field_filter_regexp_map => {
31 qr/_name$/ => 'ucfirst',
32 },
33 required => 'speak',
34 optional => [qw/short_name not_oops untainted_with_qr/],
35 constraints => {
36 not_oops => {
37 name => 'start_with_oop',
38 constraint => qr/^oop/,
39 },
40 untainted_with_qr => qr/(Slim)/,
41 speak => qr/quietly|softly/,
42 stick => qr/big|large/,
4043
41 },
42 msgs => {
43 constraints => {
44 'start_with_oop' => 'testing named qr constraints',
45 }
44 },
45 msgs => {
46 constraints => {
47 'start_with_oop' => 'testing named qr constraints',
48 }
4649
47 },
48 untaint_constraint_fields => [qw/untainted_with_qr/],
49 });
50 },
51 untaint_constraint_fields => [qw/untainted_with_qr/],
52 } );
5053
51 ok ($results->valid('stick') eq 'big','using qr for regexp quoting');
52 ok ($results->valid('speak'),'using alternation with qr works');
53 ok ($results->valid('good_email'), 'expected to pass constraint');
54 ok ($results->invalid('bad_email'), 'expected to fail constraint');
55 is($results->valid('short_name'),'Tim', 'field_filter_regexp_map');
54 ok( $results->valid('stick') eq 'big', 'using qr for regexp quoting' );
55 ok( $results->valid('speak'), 'using alternation with qr works' );
56 ok( $results->valid('good_email'), 'expected to pass constraint' );
57 ok( $results->invalid('bad_email'), 'expected to fail constraint' );
58 is( $results->valid('short_name'), 'Tim', 'field_filter_regexp_map' );
5659
5760 my $msgs = $results->msgs;
58 like($msgs->{not_oops},qr/testing named/, 'named qr constraints');
61 like( $msgs->{not_oops}, qr/testing named/, 'named qr constraints' );
5962
60 is($results->valid('untainted_with_qr'),'Slim', 'untainting with qr');
61
62
63
64
65
63 is( $results->valid('untainted_with_qr'), 'Slim', 'untainting with qr' );
0 # Friendy error messages when quality_to_ref fails due to a typo. -mls 05/03/03
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More tests => 5;
4 use Data::FormValidator;
15
2 use Test::More tests => 5;
6 # Friendy error messages when quality_to_ref fails due to a typo. -mls 05/03/03
7 my %FORM = (
8 bad_email => 'oops',
9 good_email => 'great@domain.com',
310
4 use Data::FormValidator;
5
6 my %FORM = (
7 bad_email => 'oops',
8 good_email => 'great@domain.com',
9
10 'short_name' => 'tim',
11 'short_name' => 'tim',
1112 );
1213
1314 my $results;
1415
1516 eval {
16 $results = Data::FormValidator->check(\%FORM, {
17 required => 'good_email',
18 filters => 'grim', # testing filter typo
19 });
17 $results = Data::FormValidator->check(
18 \%FORM,
19 {
20 required => 'good_email',
21 filters => 'grim', # testing filter typo
22 } );
2023 };
21 like($@,qr/found named/, 'happy filters typo failure');
24 like( $@, qr/found named/, 'happy filters typo failure' );
2225
2326 eval {
24 $results = Data::FormValidator->check(\%FORM, {
25 required => 'good_email',
26 field_filters => {
27 'good_email' => 'grim', # testing filter typo
28 },
29 });
27 $results = Data::FormValidator->check(
28 \%FORM,
29 {
30 required => 'good_email',
31 field_filters => {
32 'good_email' => 'grim', # testing filter typo
33 },
34 } );
3035 };
31 like($@,qr/found named/, 'happy field_filters typo failure');
36 like( $@, qr/found named/, 'happy field_filters typo failure' );
3237
3338 eval {
34 $results = Data::FormValidator->check(\%FORM, {
35 required => 'good_email',
36 field_filter_regexp_map => {
37 qr/_email$/ => 'grim', # testing filter typo
38 },
39 });
39 $results = Data::FormValidator->check(
40 \%FORM,
41 {
42 required => 'good_email',
43 field_filter_regexp_map => {
44 qr/_email$/ => 'grim', # testing filter typo
45 },
46 } );
4047 };
41 like($@,qr/found named/, 'happy field_filter_regexp_map typo failure');
48 like( $@, qr/found named/, 'happy field_filter_regexp_map typo failure' );
4249
4350 eval {
44 $results = Data::FormValidator->check(\%FORM, {
45 required => 'good_email',
46 constraints => {
47 good_email => 'e-mail', # typo in constraint name
48 }
49 });
51 $results = Data::FormValidator->check(
52 \%FORM,
53 {
54 required => 'good_email',
55 constraints => {
56 good_email => 'e-mail', # typo in constraint name
57 } } );
5058 };
51 like($@,qr/found named/, 'happy constraints typo failure');
59 like( $@, qr/found named/, 'happy constraints typo failure' );
5260
5361 eval {
54 $results = Data::FormValidator->check(\%FORM, {
55 required => 'good_email',
56 untaint_all_constraints => 1,
57 constraints => {
58 good_email => 'e-mail', # typo in constraint name
59 }
60 });
62 $results = Data::FormValidator->check(
63 \%FORM,
64 {
65 required => 'good_email',
66 untaint_all_constraints => 1,
67 constraints => {
68 good_email => 'e-mail', # typo in constraint name
69 } } );
6170 };
62 like($@,qr/found named/, 'happy untainted constraints typo failure');
63
71 like( $@, qr/found named/, 'happy untainted constraints typo failure' );
0 # testing passing defaults to the new constructor. -mls 05/03/03
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More tests => 3;
4 use Data::FormValidator;
15
2 use Test::More tests => 3;
3 use strict;
6 # testing passing defaults to the new constructor. -mls 05/03/03
7 my %FORM = (
8 bad_email => 'oops',
9 good_email => 'great@domain.com',
410
5 use Data::FormValidator;
6
7 my %FORM = (
8 bad_email => 'oops',
9 good_email => 'great@domain.com',
10
11 'short_name' => 'tim',
11 'short_name' => 'tim',
1212 );
1313
14 my $dfv = Data::FormValidator->new({},{ missing_optional_valie => 1 });
14 my $dfv = Data::FormValidator->new( {}, { missing_optional_valie => 1 } );
1515
16 eval {
17 my $results = $dfv->check(\%FORM, {});
18 };
19 like($@,qr/Invalid input profile/, 'defaults are checked for syntax');
16 eval { my $results = $dfv->check( \%FORM, {} ); };
17 like( $@, qr/Invalid input profile/, 'defaults are checked for syntax' );
2018
19 $dfv = Data::FormValidator->new( {}, { missing_optional_valid => 1 } );
20 my $results = $dfv->check( \%FORM, {} );
21 ok(
22 $results->{profile}->{missing_optional_valid},
23 'testing defaults appearing in profile'
24 );
2125
22 $dfv = Data::FormValidator->new({},{ missing_optional_valid=>1 });
23 my $results = $dfv->check(\%FORM, {});
24 ok ($results->{profile}->{missing_optional_valid}, 'testing defaults appearing in profile');
26 $results = $dfv->check( \%FORM, { missing_optional_valid => 0 } );
2527
26 $results = $dfv->check(\%FORM, { missing_optional_valid=>0});
27
28 ok (!$results->{profile}->{missing_optional_valid}, 'testing overriding defaults');
29
30
31
32
33
28 ok( !$results->{profile}->{missing_optional_valid},
29 'testing overriding defaults' );
0 #!/usr/bin/perl -w
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More qw/no_plan/;
4 use Data::FormValidator;
5
16 # to test definedness of built-in filters and general functions, as reported: http://rt.cpan.org/Ticket/Display.html?id=2751
27
3 use Test::More qw/no_plan/;
4 use strict;
5
6 # Basic definedness testing
7 use Data::FormValidator;
8
98 # upgrade warn to die so we can catch it.
10 $SIG{__WARN__} = sub {die $_[0]};
9 $SIG{__WARN__} = sub { die $_[0] };
1110
1211 eval {
13 my $results = Data::FormValidator->check(
14 {
15 empty_array => [undef,undef],
16 very_empty => undef ,
17
18 },
19 {
20 required => [qw/very_empty empty_array/],
12 my $results = Data::FormValidator->check( {
13 empty_array => [ undef, undef ],
14 very_empty => undef,
2115
22 }
23 );
16 },
17 {
18 required => [qw/very_empty empty_array/],
19
20 } );
2421 };
25 ok(!$@, 'basic validation generates no warnings with -w') or diag $@;
26
22 ok( !$@, 'basic validation generates no warnings with -w' ) or diag $@;
2723
2824 use Data::FormValidator::Filters (qw/:filters/);
2925
30 for my $filter (grep {/^filter_/} keys %::) {
31 eval { $::{$filter}->(undef) };
32 ok(!$@, "uninitialized value in $filter filter generates no warning") or diag $@;
26 for my $filter ( grep { /^filter_/ } keys %:: )
27 {
28 eval { $::{$filter}->(undef) };
29 ok( !$@, "uninitialized value in $filter filter generates no warning" )
30 or diag $@;
3331 }
34
35
36
37
38
0 #!/usr/bin/perl
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
13 use Test::More 'no_plan';
2 use strict;
3 BEGIN {
4 use_ok('Data::FormValidator');
4
5 BEGIN
6 {
7 use_ok('Data::FormValidator');
58 }
69
7 use Data::FormValidator::Constraints qw(
8 FV_max_length
9 FV_min_length
10 FV_length_between
10 use Data::FormValidator::Constraints qw(
11 FV_max_length
12 FV_min_length
13 FV_length_between
1114 );
1215
13 my $result = Data::FormValidator->check({
14 first_names => 'Too long',
15 keywords => 'a',
16 ok => 'Good',
16 my $result = Data::FormValidator->check( {
17 first_names => 'Too long',
18 keywords => 'a',
19 ok => 'Good',
20 },
21 {
22 required => [qw/first_names keywords ok/],
23 constraint_methods => {
24 first_names => FV_max_length(3),
25 keywords => FV_length_between( 5, 8 ),
26 too_long => FV_min_length(3),
27 ok => {
28 constraint_method => FV_length_between( 3, 6 ),
29 name => 'ok_length',
30 }
31
1732 },
18 {
19 required => [qw/first_names keywords ok/],
20 constraint_methods => {
21 first_names => FV_max_length(3),
22 keywords => FV_length_between(5,8),
23 too_long => FV_min_length(3),
24 ok => {
25 constraint_method => FV_length_between(3,6),
26 name => 'ok_length',
27 }
33 msgs => {
34 constraints => {
35 ok_length => 'Not an OK length',
36 length => 'Wrong Length',
37 }
38 },
39 } );
2840
29 },
30 msgs => {
31 constraints => {
32 ok_length => 'Not an OK length',
33 length => 'Wrong Length',
34 }
35 },
36 });
37
38 ok(defined $result);
41 ok( defined $result );
3942
4043 # Test multi-line input: someone might be using this for a textarea or somesuch
4144
4245 my $multiline_result = Data::FormValidator->check(
43 my $expect = {
44 alpha => "apple\naeroplane\n", # 16 char
45 beta => "bus\nbuffalo\n", # 12 char
46 charlie => "cat\ncoconut\ncoffee\n", # 19 char
47 delta => "dog\ndinosaur\n", # 13 char
48 echo => "egg\nelephant\nemu\n", # 17 char
49 foxtrot => "flan\nfrog\n", # 10 char
50 golf => "giraffe\ngrapefruit\n", # 19 char
46 my $expect = {
47 alpha => "apple\naeroplane\n", # 16 char
48 beta => "bus\nbuffalo\n", # 12 char
49 charlie => "cat\ncoconut\ncoffee\n", # 19 char
50 delta => "dog\ndinosaur\n", # 13 char
51 echo => "egg\nelephant\nemu\n", # 17 char
52 foxtrot => "flan\nfrog\n", # 10 char
53 golf => "giraffe\ngrapefruit\n", # 19 char
54 },
55 {
56 required => [qw/alpha beta charlie delta echo foxtrot golf/],
57 untaint_all_constraints => 1,
58 constraint_methods => {
59 alpha => FV_max_length(16), # max length
60 beta => FV_max_length(11), # too long
61 charlie => FV_min_length(19), # just long enough
62 delta => FV_min_length(14), # too short
63 echo => FV_length_between( 16, 18 ), # just right
64 foxtrot => FV_length_between( 11, 13 ), # too short
65 golf => FV_length_between( 16, 18 ), # too long
5166 },
52 {
53 required => [qw/alpha beta charlie delta echo foxtrot golf/],
54 untaint_all_constraints => 1,
55 constraint_methods => {
56 alpha => FV_max_length(16), # max length
57 beta => FV_max_length(11), # too long
58 charlie => FV_min_length(19), # just long enough
59 delta => FV_min_length(14), # too short
60 echo => FV_length_between(16,18), # just right
61 foxtrot => FV_length_between(11,13), # too short
62 golf => FV_length_between(16,18), # too long
63 },
64 },
67 },
6568 );
6669
67 ok( $multiline_result->valid('alpha'), 'multiline FV_max_length in bounds' );
68 ok( $multiline_result->invalid('beta'), 'multiline FV_max_length too long' );
69 ok( $multiline_result->valid('charlie'), 'multiline FV_min_length in bounds' );
70 ok( $multiline_result->invalid('delta'), 'multiline FV_min_length too short' );
71 ok( $multiline_result->valid('echo'), 'multiline FV_length_between in bounds');
72 ok( $multiline_result->invalid('foxtrot'), 'multiline FV_length_between too short');
73 ok( $multiline_result->invalid('golf'), 'multiline FV_length_between too long' );
70 ok( $multiline_result->valid('alpha'), 'multiline FV_max_length in bounds' );
71 ok( $multiline_result->invalid('beta'), 'multiline FV_max_length too long' );
72 ok( $multiline_result->valid('charlie'), 'multiline FV_min_length in bounds' );
73 ok( $multiline_result->invalid('delta'), 'multiline FV_min_length too short' );
74 ok( $multiline_result->valid('echo'), 'multiline FV_length_between in bounds' );
75 ok(
76 $multiline_result->invalid('foxtrot'),
77 'multiline FV_length_between too short'
78 );
79 ok( $multiline_result->invalid('golf'),
80 'multiline FV_length_between too long' );
7481
7582 # check expected values for valid untainted fields
76 for my $field (qw( alpha charlie echo )) {
77 is( $multiline_result->valid($field), $expect->{$field}, "identity $field");
83 for my $field (qw( alpha charlie echo ))
84 {
85 is( $multiline_result->valid($field), $expect->{$field}, "identity $field" );
7886 }
7987
8088 # Test "long" results. Early implementations checked length with
8189 # regular expressions which limit length options to 32kb.
8290 # The 80000 char test string is an arbitrary length.
83 # good a value as any other. And it's pretty long.
91 # good a value as any other. And it's pretty long.
8492 # Just for good measure we'll use the unicode smiley character (as seen in
8593 # perluniintro) in our test string.
8694
87 my $smiley = "\x{263a}"; # Thats "smiling face, white" folks!
88 my $long_string = "x$smiley" x 40000; # results in a 80000 length string
89 my $long_result = Data::FormValidator->check(
90 {
91 alpha => $long_string,
92 beta => $long_string,
93 charlie => $long_string,
94 delta => $long_string,
95 echo => $long_string,
96 foxtrot => $long_string,
97 golf => $long_string,
95 my $smiley = "\x{263a}"; # Thats "smiling face, white" folks!
96 my $long_string = "x$smiley" x 40000; # results in a 80000 length string
97 my $long_result = Data::FormValidator->check( {
98 alpha => $long_string,
99 beta => $long_string,
100 charlie => $long_string,
101 delta => $long_string,
102 echo => $long_string,
103 foxtrot => $long_string,
104 golf => $long_string,
105 },
106 {
107 required => [qw/alpha beta charlie delta echo foxtrot golf/],
108 constraint_methods => {
109 alpha => FV_max_length(80000), # max length
110 beta => FV_max_length(79999), # too long
111 charlie => FV_min_length(80000), # just long enough
112 delta => FV_min_length(80001), # too short
113 echo => FV_length_between( 79999, 80001 ), # just right
114 foxtrot => FV_length_between( 80001, 80000 ), # too short
115 golf => FV_length_between( 70000, 79999 ), # too long
98116 },
99 {
100 required => [qw/alpha beta charlie delta echo foxtrot golf/],
101 constraint_methods => {
102 alpha => FV_max_length(80000), # max length
103 beta => FV_max_length(79999), # too long
104 charlie => FV_min_length(80000), # just long enough
105 delta => FV_min_length(80001), # too short
106 echo => FV_length_between(79999,80001), # just right
107 foxtrot => FV_length_between(80001,80000), # too short
108 golf => FV_length_between(70000,79999), # too long
109 },
110 },
117 },
111118 );
112119
113 ok( $long_result->valid('alpha'), 'long FV_max_length in bounds' );
114 ok( $long_result->invalid('beta'), 'long FV_max_length too long' );
115 ok( $long_result->valid('charlie'), 'long FV_min_length in bounds' );
116 ok( $long_result->invalid('delta'), 'long FV_min_length too short' );
117 ok( $long_result->valid('echo'), 'long FV_length_between in bounds');
118 ok( $long_result->invalid('foxtrot'), 'long FV_length_between too short');
120 ok( $long_result->valid('alpha'), 'long FV_max_length in bounds' );
121 ok( $long_result->invalid('beta'), 'long FV_max_length too long' );
122 ok( $long_result->valid('charlie'), 'long FV_min_length in bounds' );
123 ok( $long_result->invalid('delta'), 'long FV_min_length too short' );
124 ok( $long_result->valid('echo'), 'long FV_length_between in bounds' );
125 ok( $long_result->invalid('foxtrot'), 'long FV_length_between too short' );
119126 ok( $long_result->invalid('golf'), 'long FV_length_between too long' );
0 #!/usr/bin/perl
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More 'no_plan';
4 use Data::FormValidator;
15
2 use strict;
3 use Test::More 'no_plan';
6 my $dfv_standard_any_errors = Data::FormValidator->new( {} );
7 my $dfv_custom_any_errors =
8 Data::FormValidator->new( {}, { msgs => { any_errors => 'some_errors' } } );
49
5 use Data::FormValidator;
6 my $dfv_standard_any_errors = Data::FormValidator->new({});
7 my $dfv_custom_any_errors = Data::FormValidator->new({},{msgs => { any_errors => 'some_errors' }});
10 my %profile = ( required => 'foo', );
811
9 my %profile = (
10 required => 'foo',
11 );
12 my %good_input = ( 'foo' => 1, );
13 my %bad_input = ( 'bar' => 1, );
1214
13 my %good_input = (
14 'foo' => 1,
15 );
16 my %bad_input = (
17 'bar' => 1,
18 );
19
20 my ($results, $msgs);
15 my ( $results, $msgs );
2116
2217 # standard 'any_errors', good input
23 $results = $dfv_standard_any_errors->check(\%good_input, \%profile);
24 $msgs = $results->msgs;
18 $results = $dfv_standard_any_errors->check( \%good_input, \%profile );
19 $msgs = $results->msgs;
2520
26 ok($results, "[standard any_errors] good input passed");
27 ok(!keys %$msgs, "[standard any_errors] no error messages");
21 ok( $results, "[standard any_errors] good input passed" );
22 ok( !keys %$msgs, "[standard any_errors] no error messages" );
2823
2924 # standard 'any_errors', bad input
30 $results = $dfv_standard_any_errors->check(\%bad_input, \%profile);
31 $msgs = $results->msgs;
25 $results = $dfv_standard_any_errors->check( \%bad_input, \%profile );
26 $msgs = $results->msgs;
3227
33 ok(!$results, "[standard any_errors] bad input caught");
34 ok(keys %$msgs, "[standard any_errors] error messages reported");
35
28 ok( !$results, "[standard any_errors] bad input caught" );
29 ok( keys %$msgs, "[standard any_errors] error messages reported" );
3630
3731 # custom 'any_errors', good input
38 $results = $dfv_custom_any_errors->check(\%good_input, \%profile);
39 $msgs = $results->msgs;
32 $results = $dfv_custom_any_errors->check( \%good_input, \%profile );
33 $msgs = $results->msgs;
4034
41 ok($results, "[custom any_errors] good input passed");
42 ok(!keys %$msgs, "[custom any_errors] no error messages");
43 ok(!$msgs->{'some_errors'}, "[custom any_errors] 'some_errors' not reported");
35 ok( $results, "[custom any_errors] good input passed" );
36 ok( !keys %$msgs, "[custom any_errors] no error messages" );
37 ok( !$msgs->{'some_errors'}, "[custom any_errors] 'some_errors' not reported" );
4438
4539 # custom 'any_errors', bad input
46 $results = $dfv_custom_any_errors->check(\%bad_input, \%profile);
47 $msgs = $results->msgs;
40 $results = $dfv_custom_any_errors->check( \%bad_input, \%profile );
41 $msgs = $results->msgs;
4842
49 ok(!$results, "[custom any_errors] bad input caught");
50 ok(keys %$msgs, "[custom any_errors] error messages reported");
51 ok($msgs->{'some_errors'}, "[custom any_errors] 'some_errors' reported");
43 ok( !$results, "[custom any_errors] bad input caught" );
44 ok( keys %$msgs, "[custom any_errors] error messages reported" );
45 ok( $msgs->{'some_errors'}, "[custom any_errors] 'some_errors' reported" );
5246
53
54
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More qw/no_plan/;
14 use Data::FormValidator;
2 use strict;
35
46 {
5 local $@ = undef;
6 eval {
7 my $results = Data::FormValidator->check({},
8 {
9 msgs => {
10 my_field => 'foo',
11 },
12 }
13 );
14 };
15 like($@, qr/Invalid/, 'checking syntax of unknown msgs fields works');
7 local $@ = undef;
8 eval {
9 my $results = Data::FormValidator->check(
10 {},
11 {
12 msgs => {
13 my_field => 'foo',
14 },
15 } );
16 };
17 like( $@, qr/Invalid/, 'checking syntax of unknown msgs fields works' );
1618 }
1719
1820 my $results;
1921 eval {
20 $results = Data::FormValidator->check({},
22 $results = Data::FormValidator->check(
23 {},
2124 {
22 constraints => {
23 key => {
24 oops => 1,
25 },
25 constraints => {
26 key => {
27 oops => 1,
28 },
2629
27 },
28 }
29 );
30 },
31 } );
3032 };
3133
32 like($@, qr/Invalid/, 'checking syntax of constraint hashrefs works');
33
34 like( $@, qr/Invalid/, 'checking syntax of constraint hashrefs works' );
3435
3536 eval {
36 $results = Data::FormValidator->check({},
37 $results = Data::FormValidator->check(
38 {},
3739 {
38 constraint_regexp_map => {
39 qr/key/ => {
40 oops => 1,
41 },
40 constraint_regexp_map => {
41 qr/key/ => {
42 oops => 1,
43 },
4244
43 },
44 }
45 );
45 },
46 } );
4647 };
47 like($@, qr/Invalid/, 'checking syntax of constraint_regexp_map hashrefs works');
48
48 like( $@, qr/Invalid/,
49 'checking syntax of constraint_regexp_map hashrefs works' );
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More;
1 use strict;
4 use Data::FormValidator;
5 use Data::FormValidator::Constraints qw(
6 email
7 FV_eq_with
8 );
29
310 # Test that closures and custom messages work in combination.
411 # Addresses this reported bug: #73235: msgs lookup doesn't work for built in closures
512 # https://rt.cpan.org/Ticket/Display.html?id=73235
6
7 use Data::FormValidator;
8 use Data::FormValidator::Constraints qw(
9 email
10 FV_eq_with
13 my $result = Data::FormValidator->check(
14 { email => 'a', email_confirm => 'b' },
15 {
16 required => [qw( email email_confirm )],
17 constraint_methods => {
18 email => [ email(), FV_eq_with('email_confirm') ],
19 },
20 msgs => {
21 constraints => {
22 email => 'Invalid Email Address',
23 eq_with => 'Must match confirmation'
24 },
25 } } );
26 like(
27 $result->msgs->{email},
28 qr/Email Address/,
29 "custom message for email() works"
30 );
31 like(
32 $result->msgs->{email},
33 qr/Must Match/i,
34 "custom message for FV_eq_with() works"
1135 );
1236
13
14 my $result = Data::FormValidator->check(
15 { email => 'a', email_confirm => 'b'},
16 {
17 required => [qw( email email_confirm )],
18 constraint_methods => {
19 email => [ email(), FV_eq_with('email_confirm') ],
20 },
21 msgs => {
22 constraints => {
23 email => 'Invalid Email Address',
24 eq_with => 'Must match confirmation'
25 },
26 }
27 }
28 );
29 like($result->msgs->{email}, qr/Email Address/, "custom message for email() works");
30 like($result->msgs->{email}, qr/Must Match/i, "custom message for FV_eq_with() works");
31
3237 done_testing();
33
0 #!/usr/bin/perl
10
1 use strict;
2 use warnings;
23 use Test::More qw/no_plan/;
3
44 use Data::FormValidator;
55
6 my $result = Data::FormValidator->check({ field => 'value' }, {
7 required => 'field',
8 constraints => {
9 field => {
10 constraint_method => sub {
11 my $dfv = shift;
12 my $name = $dfv->get_current_constraint_name;
13 is($name, 'test_name', "get_current_constraint_name works");
14 },
15 name => 'test_name',
16 }
6 my $result = Data::FormValidator->check(
7 { field => 'value' },
8 {
9 required => 'field',
10 constraints => {
11 field => {
12 constraint_method => sub {
13 my $dfv = shift;
14 my $name = $dfv->get_current_constraint_name;
15 is( $name, 'test_name', "get_current_constraint_name works" );
1716 },
18 });
17 name => 'test_name',
18 }
19 },
20 } );
1921
2022 {
21 my $result = Data::FormValidator->check({
22 to_pass => 'value',
23 to_fail => 'value',
24 map_to_pass => 'value',
25 map_to_fail => 'value',
26 }, {
27 required => [qw/
28 to_pass
29 to_fail
30 map_to_pass
31 map_to_fail
32 /],
33 constraint_methods => {
34 to_pass => qr/value/,
35 to_fail => qr/wrong/,
36 },
37 constraint_method_regexp_map => {
38 qr/map_to_p.*/ => qr/value/,
39 qr/map_to_f.*/ => qr/fail/,
23 my $result = Data::FormValidator->check( {
24 to_pass => 'value',
25 to_fail => 'value',
26 map_to_pass => 'value',
27 map_to_fail => 'value',
28 },
29 {
30 required => [
31 qw/
32 to_pass
33 to_fail
34 map_to_pass
35 map_to_fail
36 /
37 ],
38 constraint_methods => {
39 to_pass => qr/value/,
40 to_fail => qr/wrong/,
41 },
42 constraint_method_regexp_map => {
43 qr/map_to_p.*/ => qr/value/,
44 qr/map_to_f.*/ => qr/fail/,
4045
41 },
42 });
46 },
47 } );
4348
44 ok ( $result->invalid('to_fail'), "using qr with constraint_method fails as expected");
45 ok ( $result->valid('to_pass'), "using qr with constraint_method succeeds as expected");
46 ok ( $result->invalid('map_to_fail'), "using qr with constraint_method_regexp_map fails as expected");
47 ok ( $result->valid('map_to_pass'), "using qr with constraint_method_regexp_map succeeds as expected");
49 ok( $result->invalid('to_fail'),
50 "using qr with constraint_method fails as expected" );
51 ok( $result->valid('to_pass'),
52 "using qr with constraint_method succeeds as expected" );
53 ok( $result->invalid('map_to_fail'),
54 "using qr with constraint_method_regexp_map fails as expected" );
55 ok( $result->valid('map_to_pass'),
56 "using qr with constraint_method_regexp_map succeeds as expected" );
4857 }
0 #!/usr/bin/perl
1 #
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More tests => 4;
4 use_ok('Data::FormValidator');
5
26 # in response to bug report 2006/10/25 by Brian E. Lozier <brian@massassi.net>
37 # test script by Evan A. Zacks <zackse@cpan.org>
48 #
59 # The problem was that when specifying constraint_methods in a profile and
610 # using the name of a built-in (e.g., "zip") as the constraint, the built-in
711 # (match_zip or valid_zip) ended up being called as a method rather than a
8 # function.
12 # function.
913 #
1014 # So now we throw an error if a non-code-ref is used with a constraint method.
11
12 use strict;
13
14 use Test::More tests => 4;
15
16 use_ok('Data::FormValidator');
17
1815 my $err_re = qr/not a code ref/;
1916
2017 {
2118 my %profile = (
22 required => ['zip'],
23 constraint_methods => {
24 zip => 'zip',
25 }
26 );
19 required => ['zip'],
20 constraint_methods => {
21 zip => 'zip',
22 } );
2723
28 my %data = (
29 zip => 56567
30 );
24 my %data = ( zip => 56567 );
3125
32 eval { my $r = Data::FormValidator->check(\%data, \%profile) };
33 like($@, $err_re,
34 "error thrown when given a string to constraint_method");
26 eval { my $r = Data::FormValidator->check( \%data, \%profile ) };
27 like( $@, $err_re, "error thrown when given a string to constraint_method" );
3528 }
3629
3730 {
3831 my %profile = (
39 required => ['zip'],
40 constraint_methods => {
41 zip => ['zip'],
42 }
43 );
32 required => ['zip'],
33 constraint_methods => {
34 zip => ['zip'],
35 } );
4436
4537 my %data = ( zip => 56567 );
4638
47 eval { my $r = Data::FormValidator->check(\%data, \%profile) };
48 like($@, $err_re,
49 "error thrown when given a string to constraint_method...even as part of a list.");
39 eval { my $r = Data::FormValidator->check( \%data, \%profile ) };
40 like( $@, $err_re,
41 "error thrown when given a string to constraint_method...even as part of a list."
42 );
5043 }
5144
5245 {
5346 my %profile = (
54 required => ['zip'],
55 untaint_all_constraints => 1,
56 constraint_methods => { zip => {} }
57 );
47 required => ['zip'],
48 untaint_all_constraints => 1,
49 constraint_methods => { zip => {} } );
5850
5951 my %data = ( zip => 56567 );
6052
61 eval { my $r = Data::FormValidator->check(\%data, \%profile) };
62 like($@, $err_re,
63 "error thrown when given a string to constraint_method...even as hash declaration.");
53 eval { my $r = Data::FormValidator->check( \%data, \%profile ) };
54 like( $@, $err_re,
55 "error thrown when given a string to constraint_method...even as hash declaration."
56 );
6457 }
0 #!perl
1 # For RT#45177
2
0 #!/usr/bin/env perl
31 use strict;
42 use warnings;
5
63 use Test::More 'no_plan';
74 use Data::FormValidator;
85
6 # For RT#45177
97 {
10 my $results = Data::FormValidator->check({ nine_is_ok => 9 }, {
11 required => [ 'nine_is_ok' ],
12 constraint_methods => { 'nine_is_ok' => qr/^(9)$/ },
13 untaint_all_constraints => 1,
14 });
15 is($results->valid('nine_is_ok'),9, "nine should be valid for 9 with capturing parens (untainted)");
8 my $results = Data::FormValidator->check(
9 { nine_is_ok => 9 },
10 {
11 required => ['nine_is_ok'],
12 constraint_methods => { 'nine_is_ok' => qr/^(9)$/ },
13 untaint_all_constraints => 1,
14 } );
15 is( $results->valid('nine_is_ok'),
16 9, "nine should be valid for 9 with capturing parens (untainted)" );
1617 }
1718 {
18 my $results = Data::FormValidator->check({ nine_is_ok => 9 }, {
19 required => [ 'nine_is_ok' ],
20 constraint_methods => { 'nine_is_ok' => qr/^9$/ },
21 untaint_all_constraints => 1,
22 });
23 is($results->valid('nine_is_ok'),9, "nine should be valid for 9 without capturing parens (untainted)");
19 my $results = Data::FormValidator->check(
20 { nine_is_ok => 9 },
21 {
22 required => ['nine_is_ok'],
23 constraint_methods => { 'nine_is_ok' => qr/^9$/ },
24 untaint_all_constraints => 1,
25 } );
26 is( $results->valid('nine_is_ok'),
27 9, "nine should be valid for 9 without capturing parens (untainted)" );
2428 }
2529 {
26 my $results = Data::FormValidator->check({ zero_is_ok => 0 }, {
27 required => [ 'zero_is_ok' ],
28 constraint_methods => { 'zero_is_ok' => qr/^0$/ },
29 untaint_all_constraints => 1,
30 });
31 is($results->valid('zero_is_ok'),0, "zero should be valid without capturing parens (untainted)");
30 my $results = Data::FormValidator->check(
31 { zero_is_ok => 0 },
32 {
33 required => ['zero_is_ok'],
34 constraint_methods => { 'zero_is_ok' => qr/^0$/ },
35 untaint_all_constraints => 1,
36 } );
37 is( $results->valid('zero_is_ok'),
38 0, "zero should be valid without capturing parens (untainted)" );
3239 }
3340 {
34 my $results = Data::FormValidator->check({ zero_is_ok => 0 }, {
35 required => [ 'zero_is_ok' ],
36 constraint_methods => { 'zero_is_ok' => qr/^(0)$/ },
37 untaint_all_constraints => 1,
38 });
39 is($results->valid('zero_is_ok'),0, "zero should be valid with capturing parens (untainted)");
41 my $results = Data::FormValidator->check(
42 { zero_is_ok => 0 },
43 {
44 required => ['zero_is_ok'],
45 constraint_methods => { 'zero_is_ok' => qr/^(0)$/ },
46 untaint_all_constraints => 1,
47 } );
48 is( $results->valid('zero_is_ok'),
49 0, "zero should be valid with capturing parens (untainted)" );
4050 }
4151 {
42 my $results = Data::FormValidator->check({ nine_is_ok => 9 }, {
43 required => [ 'nine_is_ok' ],
44 constraint_methods => { 'nine_is_ok' => qr/^(9)$/ },
45 });
46 is($results->valid('nine_is_ok'),9, "nine should be valid for 9 with capturing parens");
52 my $results = Data::FormValidator->check(
53 { nine_is_ok => 9 },
54 {
55 required => ['nine_is_ok'],
56 constraint_methods => { 'nine_is_ok' => qr/^(9)$/ },
57 } );
58 is( $results->valid('nine_is_ok'),
59 9, "nine should be valid for 9 with capturing parens" );
4760 }
4861 {
49 my $results = Data::FormValidator->check({ nine_is_ok => 9 }, {
50 required => [ 'nine_is_ok' ],
51 constraint_methods => { 'nine_is_ok' => qr/^9$/ },
52 });
53 is($results->valid('nine_is_ok'),9, "nine should be valid for 9 without capturing parens");
62 my $results = Data::FormValidator->check(
63 { nine_is_ok => 9 },
64 {
65 required => ['nine_is_ok'],
66 constraint_methods => { 'nine_is_ok' => qr/^9$/ },
67 } );
68 is( $results->valid('nine_is_ok'),
69 9, "nine should be valid for 9 without capturing parens" );
5470 }
5571 {
56 my $results = Data::FormValidator->check({ zero_is_ok => 0 }, {
57 required => [ 'zero_is_ok' ],
58 constraint_methods => { 'zero_is_ok' => qr/^0$/ },
59 });
60 is($results->valid('zero_is_ok'),0, "zero should be valid without capturing parens");
72 my $results = Data::FormValidator->check(
73 { zero_is_ok => 0 },
74 {
75 required => ['zero_is_ok'],
76 constraint_methods => { 'zero_is_ok' => qr/^0$/ },
77 } );
78 is( $results->valid('zero_is_ok'),
79 0, "zero should be valid without capturing parens" );
6180 }
6281 {
63 my $results = Data::FormValidator->check({ zero_is_ok => 0 }, {
64 required => [ 'zero_is_ok' ],
65 constraint_methods => { 'zero_is_ok' => qr/^(0)$/ },
66 });
67 is($results->valid('zero_is_ok'),0, "zero should be valid with capturing parens");
82 my $results = Data::FormValidator->check(
83 { zero_is_ok => 0 },
84 {
85 required => ['zero_is_ok'],
86 constraint_methods => { 'zero_is_ok' => qr/^(0)$/ },
87 } );
88 is( $results->valid('zero_is_ok'),
89 0, "zero should be valid with capturing parens" );
6890 }
69
70
71
72
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More (qw/no_plan/);
14 use Data::FormValidator;
25
36 my $profile = {
4 required => [qw( test1 )],
5 constraint_regexp_map => {
6 qr/^test/ => 'email',
7 },
7 required => [qw( test1 )],
8 constraint_regexp_map => {
9 qr/^test/ => 'email',
10 },
811 };
912
10 my $data = {
11 test1 => 'not an email',
12 };
13 my $data = { test1 => 'not an email', };
1314
14 my $results1 = Data::FormValidator->check($data, $profile);
15 my $c1 = {%{ $profile->{constraints} }};
16 my $results2 = Data::FormValidator->check($data, $profile);
17 my $c2 = {%{ $profile->{constraints} }};
15 my $results1 = Data::FormValidator->check( $data, $profile );
16 my $c1 = { %{ $profile->{constraints} } };
17 my $results2 = Data::FormValidator->check( $data, $profile );
18 my $c2 = { %{ $profile->{constraints} } };
1819
19 is_deeply($results1->{profile},$results2->{profile}, "constraints aren't duped when profile with constraint_regexp_map is reused");
20 is_deeply($c1,$c2, "constraints aren't duped when profile with constraint_regexp_map is reused");
20 is_deeply( $results1->{profile}, $results2->{profile},
21 "constraints aren't duped when profile with constraint_regexp_map is reused"
22 );
23 is_deeply( $c1, $c2,
24 "constraints aren't duped when profile with constraint_regexp_map is reused"
25 );
2126
2227 {
23 my $profile = {
24 required => [qw( test1 )],
25 field_filter_regexp_map => {
26 qr/^test/ => 'trim',
27 },
28 };
28 my $profile = {
29 required => [qw( test1 )],
30 field_filter_regexp_map => {
31 qr/^test/ => 'trim',
32 },
33 };
2934
30 my $data = {
31 test1 => ' not an email ',
32 };
35 my $data = { test1 => ' not an email ', };
3336
34 my $results1 = Data::FormValidator->check($data, $profile);
35 my $c1 = {%{ $profile->{constraints} }};
36 my $results2 = Data::FormValidator->check($data, $profile);
37 my $c2 = {%{ $profile->{constraints} }};
38 is_deeply($results1->{profile},$results2->{profile}, "field_filters aren't duped when profile with field_filter_regexp_map is reused");
39 is_deeply($c1,$c2, "field_filters aren't duped when profile with field_filter_regexp_map is reused");
37 my $results1 = Data::FormValidator->check( $data, $profile );
38 my $c1 = { %{ $profile->{constraints} } };
39 my $results2 = Data::FormValidator->check( $data, $profile );
40 my $c2 = { %{ $profile->{constraints} } };
41 is_deeply( $results1->{profile}, $results2->{profile},
42 "field_filters aren't duped when profile with field_filter_regexp_map is reused"
43 );
44 is_deeply( $c1, $c2,
45 "field_filters aren't duped when profile with field_filter_regexp_map is reused"
46 );
4047
4148 }
42
0 #!/usr/bin/perl
1
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
23 use Test::More qw/no_plan/;
3 use strict;
4
54 use Data::FormValidator;
65
76 my $input_profile = {
8 required => [ qw( number_field ) ],
9 constraints => {
10 number_field => {
11 name => 'number',
12 constraint => qr/^\d+$/,
13 }
14 }
7 required => [qw( number_field )],
8 constraints => {
9 number_field => {
10 name => 'number',
11 constraint => qr/^\d+$/,
12 } } };
13
14 my $input_hashref = { number_field => 0, };
15
16 my $results;
17 eval {
18 $results = Data::FormValidator->check( $input_hashref, $input_profile );
1519 };
1620
17 my $input_hashref = {
18 number_field => 0,
19 };
21 ok( !$@, 'survived validate' );
2022
21 my $results;
22 eval{
23 $results = Data::FormValidator->check($input_hashref, $input_profile);
24 };
25
26 ok(!$@, 'survived validate');
27
28 is($results->valid->{number_field},0, 'using 0 in a constraint regexp works');
23 is( $results->valid->{number_field}, 0,
24 'using 0 in a constraint regexp works' );
0 #!/usr/bin/perl
1
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
23 use Test::More;
3 use strict;
4
54 use Data::FormValidator;
65 use Data::FormValidator::Constraints qw(:closures);
76
87 my $input_profile = {
9 required => [ qw( number_field nan nan_typo ) ],
10 optional => [ qw( nan_name_this ) ],
11 constraint_methods => {
12 number_field => sub {
13 my ($self,$v) = @_;
14 #$self->set_current_constraint_name('number');
15 return ($v =~ m/^\d+$/);
16 },
17 nan => sub {
18 my ($self,$v) = @_;
19 $self->name_this('number');
20 return ($v =~ m/^\d+$/);
21 },
22 nan_typo => sub {
23 my ($self,$v) = @_;
24 $self->name_this('numer');
25 return ($v =~ m/^\d+$/);
26 },
27 nan_name_this => sub { my ($d,$v) = @_; $d->name_this('number'); return ($v =~ m/^\d+$/); },
8 required => [qw( number_field nan nan_typo )],
9 optional => [qw( nan_name_this )],
10 constraint_methods => {
11 number_field => sub {
12 my ( $self, $v ) = @_;
2813
14 #$self->set_current_constraint_name('number');
15 return ( $v =~ m/^\d+$/ );
2916 },
30 msgs => {
31 constraints => {
32 number => 'Must be a digit',
33 }
34 }
35 };
17 nan => sub {
18 my ( $self, $v ) = @_;
19 $self->name_this('number');
20 return ( $v =~ m/^\d+$/ );
21 },
22 nan_typo => sub {
23 my ( $self, $v ) = @_;
24 $self->name_this('numer');
25 return ( $v =~ m/^\d+$/ );
26 },
27 nan_name_this => sub {
28 my ( $d, $v ) = @_;
29 $d->name_this('number');
30 return ( $v =~ m/^\d+$/ );
31 },
32
33 },
34 msgs => {
35 constraints => {
36 number => 'Must be a digit',
37 } } };
3638
3739 my $input_hashref = {
38 number_field => 0,
39 nan => 'infinity',
40 nan_name_this => 'infinity',
40 number_field => 0,
41 nan => 'infinity',
42 nan_name_this => 'infinity',
4143 };
4244
4345 my $results;
44 eval{
45 $results = Data::FormValidator->check($input_hashref, $input_profile);
46 eval {
47 $results = Data::FormValidator->check( $input_hashref, $input_profile );
4648 };
47 is($@,'','survived eval');
48 is($results->valid()->{number_field},0, 'using 0 in a constraint regexp works');
49 is( $@, '', 'survived eval' );
50 is( $results->valid()->{number_field},
51 0, 'using 0 in a constraint regexp works' );
4952 my $msgs = $results->msgs();
50 like($msgs->{nan},qr/Must be a digit/, 'set_current_contraint_name succeeds');
51 like($msgs->{nan_name_this},qr/Must be a digit/, 'name_this succeeds');
53 like( $msgs->{nan}, qr/Must be a digit/,
54 'set_current_contraint_name succeeds' );
55 like( $msgs->{nan_name_this}, qr/Must be a digit/, 'name_this succeeds' );
5256
53 unlike($msgs->{nan_typo},qr/Must be a digit/, 'set_current_contraint_name doesn\'t work if you typo it');
57 unlike(
58 $msgs->{nan_typo},
59 qr/Must be a digit/,
60 'set_current_contraint_name doesn\'t work if you typo it'
61 );
5462
5563 done_testing();
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More 'no_plan';
1
24 use Data::FormValidator;
35 use Data::FormValidator::ConstraintsFactory 'make_length_constraint';
46
57 {
6 my $results = Data::FormValidator->check(
7 {
8 short_enough => 'doh',
9 too_long => "So long she's happy",
10 },
11 {
12 required => [qw/too_long short_enough/],
13 constraints => {
14 too_long => make_length_constraint(5),
15 short_enough => make_length_constraint(5),
16 }
17 }
18 );
8 my $results = Data::FormValidator->check( {
9 short_enough => 'doh',
10 too_long => "So long she's happy",
11 },
12 {
13 required => [qw/too_long short_enough/],
14 constraints => {
15 too_long => make_length_constraint(5),
16 short_enough => make_length_constraint(5),
17 } } );
1918
20 ok($results->valid('short_enough'), 'positive test for make_length_constraint()');
21 ok(! $results->valid('too_long'),'negative test for make_length_constraint()');
19 ok( $results->valid('short_enough'),
20 'positive test for make_length_constraint()' );
21 ok( !$results->valid('too_long'),
22 'negative test for make_length_constraint()' );
2223
2324 }
24
0 #!/usr/bin/perl
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More tests => 1;
4 use Data::FormValidator;
15
26 # this test checks that a failing constraint is only marked as invalid once
37
4 use Test::More tests => 1;
5 use Data::FormValidator;
6 use strict;
7
8 sub check_passwords {
9 my ( $dfv, $val ) = @_;
10 my $passwords = $dfv->{__INPUT_DATA}->{password};
11 if( ref( $passwords ) eq 'ARRAY' ) {
12 if( $$passwords[0] eq $$passwords[1] ) {
13 return 1;
14 }
15 return 0;
16 }
17 return 1;
8 sub check_passwords
9 {
10 my ( $dfv, $val ) = @_;
11 my $passwords = $dfv->{__INPUT_DATA}->{password};
12 if ( ref($passwords) eq 'ARRAY' )
13 {
14 if ( $$passwords[0] eq $$passwords[1] )
15 {
16 return 1;
17 }
18 return 0;
19 }
20 return 1;
1821 }
1922
20 my %data = (
21 'password' => ['123456','123457'],
23 my %data = ( 'password' => [ '123456', '123457' ], );
24
25 my %profile = (
26 optional => [qw/password/],
27 constraint_methods => {
28 password => \&check_passwords,
29 },
2230 );
2331
24 my %profile = (
25 optional => [qw/password/],
26 constraint_methods => {
27 password => \&check_passwords,
28 },
29 );
32 my $results = Data::FormValidator->check( \%data, \%profile );
3033
31 my $results = Data::FormValidator->check(\%data, \%profile);
32
33 my $invalid = $results->{invalid};
34 my $invalid = $results->{invalid};
3435 my $duplicated = {};
3536 my $has_duplicates;
36 foreach ( @{$invalid->{password}} ) {
37 if( exists $duplicated->{$_} ) {
38 $has_duplicates = 1;
39 last;
40 }
41 $duplicated->{$_} = 1;
37 foreach ( @{ $invalid->{password} } )
38 {
39 next unless $_;
40 if ( exists $duplicated->{$_} )
41 {
42 $has_duplicates = 1;
43 last;
44 }
45 $duplicated->{$_} = 1;
4246 }
43 ok(!$has_duplicates, 'constraint marked as invalid only once');
47 ok( !$has_duplicates, 'constraint marked as invalid only once' );
0 #!/usr/bin/perl
1
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
23 use Test::More;
3 use strict;
4 use Data::FormValidator;
5 use Data::FormValidator::Constraints qw(:closures);
46
57 # Test FV_num_values and FV_num_values_between
68
7 use Data::FormValidator;
8 use Data::FormValidator::Constraints qw(:closures);
9
10 my $results = Data::FormValidator->check(
11 {
12 num_values_pass => [qw(a b)],
13 num_values_fail => [qw(a b)],
9 my $results = Data::FormValidator->check( {
10 num_values_pass => [qw(a b)],
11 num_values_fail => [qw(a b)],
1412 num_values_between_pass => [qw(a)],
1513 num_values_between_fail => [qw(a b)],
16 },
17 {
18 optional_regexp => qr/.*/,
14 },
15 {
16 optional_regexp => qr/.*/,
1917 constraint_methods => {
20 num_values_pass => FV_num_values(2),
21 num_values_fail => FV_num_values(1),
22 num_values_between_pass => FV_num_values_between(1,2),
23 num_values_between_fail => FV_num_values_between(3,4),
24 }
25 });
18 num_values_pass => FV_num_values(2),
19 num_values_fail => FV_num_values(1),
20 num_values_between_pass => FV_num_values_between( 1, 2 ),
21 num_values_between_fail => FV_num_values_between( 3, 4 ),
22 } } );
2623
2724 my $valid = $results->valid;
28 ok($valid->{num_values_pass}, 'FV_num_values pass');
29 ok($valid->{num_values_between_pass}, 'FV_num_values_between pass');
25 ok( $valid->{num_values_pass}, 'FV_num_values pass' );
26 ok( $valid->{num_values_between_pass}, 'FV_num_values_between pass' );
3027
3128 my $invalid = $results->invalid;
32 ok($invalid->{num_values_fail}, 'FV_num_values fail - one value requested, two found');
33 ok($invalid->{num_values_between_fail}, 'FV_num_values_between fail');
29 ok( $invalid->{num_values_fail},
30 'FV_num_values fail - one value requested, two found' );
31 ok( $invalid->{num_values_between_fail}, 'FV_num_values_between fail' );
3432
3533 done_testing();
0 #!/usr/bin/perl
1
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use lib 'perllib';
24 use Test::More qw/no_plan/;
3 use strict;
4
5 use lib 'perllib';
6
75 use Data::FormValidator;
86
97 my $input_profile = {
10 required => [ 'email_field' ],
11 constraints => {
12 email_field => [ 'email' ],
13 }
14 };
8 required => ['email_field'],
9 constraints => {
10 email_field => ['email'],
11 } };
1512
16 my $input_hashref = {
17 email_field => 'test@bad_email',
18 };
19
20
13 my $input_hashref = { email_field => 'test@bad_email', };
2114
2215 my $results;
23 eval{
24 $results = Data::FormValidator->check($input_hashref, $input_profile);
16 eval {
17 $results = Data::FormValidator->check( $input_hashref, $input_profile );
2518 };
26 is($@, '', "Survived validate");
19 is( $@, '', "Survived validate" );
2720
2821 my @invalids = $results->invalid;
29 is(scalar @invalids, 1, "Correctly catches the bad field");
30 is($invalids[0], 'email_field', "The invalid field is listed correctly as 'email_field'");
31
32
22 is( scalar @invalids, 1, "Correctly catches the bad field" );
23 is( $invalids[0], 'email_field',
24 "The invalid field is listed correctly as 'email_field'" );
3325
3426 # Now add constraint_regexp_map to the profile, and we'll get a weird interaction...
3527
3628 my $regex = qr/^test/;
3729 $input_profile->{constraint_regexp_map} = { qr/email_/ => $regex };
3830
39 eval{
40 $results = Data::FormValidator->check($input_hashref, $input_profile);
31 eval {
32 $results = Data::FormValidator->check( $input_hashref, $input_profile );
4133 };
42 is($@, '', "Survived validate");
34 is( $@, '', "Survived validate" );
4335
4436 @invalids = $results->invalid;
45 is(scalar @invalids, 1, "Still correctly catches the bad field");
46 is($invalids[0], 'email_field', "The invalid field is still listed correctly as 'email_field'");
37 is( scalar @invalids, 1, "Still correctly catches the bad field" );
38 is( $invalids[0], 'email_field',
39 "The invalid field is still listed correctly as 'email_field'" );
4740
48 ok($input_hashref->{email_field} =~ $regex, "But perl agrees that the email address does match the regex");
41 ok( $input_hashref->{email_field} =~ $regex,
42 "But perl agrees that the email address does match the regex" );
0 #!/usr/bin/perl
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More tests => 7;
4 use Data::FormValidator;
15
26 # This test is to confirm that values are preserved
37 # for input data when used with multiple constraints
812 # relies on the order on which perl returns the keys
913 # from each %{ $profile->{constraints} }
1014
11 use Test::More tests => 7;
12 use Data::FormValidator;
13 use strict;
14
1515 my %data = (
16 'depart_date' => '2004',
17 'return_date' => '2005',
16 'depart_date' => '2004',
17 'return_date' => '2005',
1818 );
1919
2020 my %profile = (
21 required => [qw/
22 depart_date
23 return_date
24 /],
21 required => [
22 qw/
23 depart_date
24 return_date
25 /
26 ],
2527 field_filters => {
26 depart_date => sub { my $v = shift; $v =~ s/XXX//; $v; }
28 depart_date => sub { my $v = shift; $v =~ s/XXX//; $v; }
2729 },
2830 constraints => {
29 depart_date => {
30 name => 'expected_to_succeed',
31 params => [qw/depart_date return_date/],
32 constraint => sub {
33 my ($depart,$return) = @_;
34 Test::More::is($depart, '2004');
35 Test::More::is($return, '2005');
36 return ($depart < $return);
37 },
31 depart_date => {
32 name => 'expected_to_succeed',
33 params => [qw/depart_date return_date/],
34 constraint => sub {
35 my ( $depart, $return ) = @_;
36 Test::More::is( $depart, '2004' );
37 Test::More::is( $return, '2005' );
38 return ( $depart < $return );
3839 },
39 return_date => {
40 name => 'built_to_fail',
41 params => [qw/depart_date return_date/],
42 constraint => sub {
43 my ($depart,$return) = @_;
44 Test::More::is($depart, '2004');
45 Test::More::is($return, '2005');
46 return ($depart > $return);
47 },
40 },
41 return_date => {
42 name => 'built_to_fail',
43 params => [qw/depart_date return_date/],
44 constraint => sub {
45 my ( $depart, $return ) = @_;
46 Test::More::is( $depart, '2004' );
47 Test::More::is( $return, '2005' );
48 return ( $depart > $return );
4849 },
50 },
4951 },
5052 missing_optional_valid => 1,
51 msgs => {
52 format => 'error(%s)',
53 msgs => {
54 format => 'error(%s)',
5355 constraints => {
54 'valid_date' => 'bad date',
55 'depart_le_return' => 'depart is greater than return',
56 },
56 'valid_date' => 'bad date',
57 'depart_le_return' => 'depart is greater than return',
58 },
5759 },
5860 );
5961
62 my $results = Data::FormValidator->check( \%data, \%profile );
6063
61 my $results = Data::FormValidator->check(\%data, \%profile);
62
63 ok(!$results->valid('return_date'), 'first constraint applied intentionally fails');
64 ok($results->valid('depart_date'),
65 'second constraint still has access to value of field used in first failed constraint.');
66
64 ok( !$results->valid('return_date'),
65 'first constraint applied intentionally fails' );
66 ok( $results->valid('depart_date'),
67 'second constraint still has access to value of field used in first failed constraint.'
68 );
6769
6870 # The next test are to confirm when a constraint method returns 'undef'
6971 # that it causes no warnings to be issued
7072 {
71 my %profile = (
72 required => ['foo'],
73 constraints => {
74 foo => {
75 constraint => sub {
76 return;
77 },
78 },
73 my %profile = (
74 required => ['foo'],
75 constraints => {
76 foo => {
77 constraint => sub {
78 return;
7979 },
80 untaint_all_constraints => 1,
81 );
80 },
81 },
82 untaint_all_constraints => 1,
83 );
8284
83 my $err = '';
84 local *STDERR;
85 open STDERR, '>', \$err;
86 my $results = Data::FormValidator->check({ foo => 1}, \%profile);
87 is($err, '', 'no warnings emitted');
85 my $err = '';
86 local *STDERR;
87 open STDERR, '>', \$err;
88 my $results = Data::FormValidator->check( { foo => 1 }, \%profile );
89 is( $err, '', 'no warnings emitted' );
8890
8991 }
90
0 #!/usr/bin/env perl
01 use strict;
2 use warnings;
3 use Test::More tests => 25;
4 use Data::FormValidator;
5 use Data::FormValidator::Constraints qw(:closures);
6
17 # check credit card number validation (the cc_number constraint).
28 # note: this constraint is checked directly in 11_procedural_match.t and
39 # procedural_valid.t, but here we will test it indirectly through a profile
4
5 $^W = 1;
6
7 use Data::FormValidator;
8 use Data::FormValidator::Constraints qw(:closures);
9 use Test::More tests => 25;
1010
1111 my $dfv_profile_old = {
1212 required => [qw(credit_card_type credit_card_number)],
1313 constraints => {
1414 credit_card_number => {
1515 constraint => 'cc_number',
16 params => [ qw(credit_card_number credit_card_type) ],
16 params => [qw(credit_card_number credit_card_type)],
1717 },
1818 },
1919 };
2222 # http://www.verisign.com/support/payflow/manager/selfHelp/testCardNum.html
2323 # maps type => [ [ invalids ... ], [ valids ... ] ]
2424 my %cc_numbers = (
25 Visa => [ [ '4000111122223333', ],
26 [ '4111111111111111', '4012888888881881', ] ],
25 Visa =>
26 [ [ '4000111122223333', ], [ '4111111111111111', '4012888888881881', ] ],
2727
28 Mastercard => [ [ '5424111122223333', ],
29 [ '5105105105105100', '5555555555554444', ] ],
28 Mastercard =>
29 [ [ '5424111122223333', ], [ '5105105105105100', '5555555555554444', ] ],
3030
31 Discover => [ [ '6000111122223333', ],
32 [ '6011111111111117', '6011000990139424', ] ],
31 Discover =>
32 [ [ '6000111122223333', ], [ '6011111111111117', '6011000990139424', ] ],
3333
34 Amex => [ [ '371500001111222', ],
35 [ '378282246310005', '371449635398431', ] ],
34 Amex => [ [ '371500001111222', ], [ '378282246310005', '371449635398431', ] ],
3635 );
3736
38 while ( my ($card_type, $numbers) = each %cc_numbers ) {
39 foreach my $is_valid ( 0..1 ) {
40 foreach my $n ( @{ $numbers->[$is_valid] } ) {
41 my $msg = ($is_valid ? "Valid" : "Invalid") . ": $card_type/$n";
37 while ( my ( $card_type, $numbers ) = each %cc_numbers )
38 {
39 foreach my $is_valid ( 0 .. 1 )
40 {
41 foreach my $n ( @{ $numbers->[$is_valid] } )
42 {
43 my $msg = ( $is_valid ? "Valid" : "Invalid" ) . ": $card_type/$n";
4244 my $input = {
4345 credit_card_type => $card_type,
4446 credit_card_number => $n,
4951 }
5052 }
5153
52 my $dfv_profile_new = eval {
53 {
54 my $dfv_profile_new = eval { {
5455 required => [qw(credit_card_type credit_card_number)],
5556 constraint_methods => {
56 credit_card_number => cc_number({fields => ['credit_card_type']}),
57 credit_card_number => cc_number( { fields => ['credit_card_type'] } ),
5758 },
58 }
59 };
5960 };
6061
61 ok( ! $@, "cc_number subroutine runs without error" );
62 ok( !$@, "cc_number subroutine runs without error" );
6263
6364 # broken cc_number subroutine in older dfv
64 SKIP: {
65 SKIP:
66 {
6567 skip "(Older DFV has broken cc_number subroutine)", 12 if $@;
6668
67 while ( my ($card_type, $numbers) = each %cc_numbers ) {
68 foreach my $is_valid ( 0..1 ) {
69 foreach my $n ( @{ $numbers->[$is_valid] } ) {
70 my $msg = ($is_valid ? "Valid" : "Invalid") . ": $card_type/$n";
69 while ( my ( $card_type, $numbers ) = each %cc_numbers )
70 {
71 foreach my $is_valid ( 0 .. 1 )
72 {
73 foreach my $n ( @{ $numbers->[$is_valid] } )
74 {
75 my $msg = ( $is_valid ? "Valid" : "Invalid" ) . ": $card_type/$n";
7176 my $input = {
7277 credit_card_type => $card_type,
7378 credit_card_number => $n,
8186
8287 ##
8388
84 sub validate_q {
89 sub validate_q
90 {
8591 my ( $data, $profile ) = @_;
8692
87 my $dfv_result = eval {
88 Data::FormValidator->check($data, $profile);
89 };
93 my $dfv_result = eval { Data::FormValidator->check( $data, $profile ); };
9094
91 if( $@ ) {
95 if ($@)
96 {
9297 diag "Failed check [$@]";
9398 return;
9499 }
95100
96 return ($dfv_result->has_invalid || $dfv_result->has_missing) ? 0 : 1;
101 return ( $dfv_result->has_invalid || $dfv_result->has_missing ) ? 0 : 1;
97102 }
0 #!/usr/bin/perl -w
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
13 use Test::More;
24
35 eval { require Date::Calc; };
46
5 if( $@ ) {
6 plan skip_all => 'Date::Calc required for date testing';
7 if ($@)
8 {
9 plan skip_all => 'Date::Calc required for date testing';
710 }
8 else {
9 plan 'no_plan';
11 else
12 {
13 plan 'no_plan';
1014 }
1115
1216 require Data::FormValidator::Constraints::Dates;
1317
1418 use strict;
1519
16 my $format = Data::FormValidator::Constraints::Dates::_prepare_date_format('MM/DD/YYYY hh?:mm:ss pp');
20 my $format = Data::FormValidator::Constraints::Dates::_prepare_date_format(
21 'MM/DD/YYYY hh?:mm:ss pp');
1722
18 my ($date,$year, $month, $day, $hour, $min, $sec) = Data::FormValidator::Constraints::Dates::_parse_date_format($format, '12/02/2003 1:01:03 PM');
19 ok ($date eq '12/02/2003 1:01:03 PM','returning untainted date');
20 ok ($year == 2003, 'basic date prepare and parse test');
21 ok ($month == 12);
22 ok ($day == 2);
23 ok ($hour == 13);
24 ok ($min == 1);
25 ok ($sec == 3);
23 my ( $date, $year, $month, $day, $hour, $min, $sec ) =
24 Data::FormValidator::Constraints::Dates::_parse_date_format( $format,
25 '12/02/2003 1:01:03 PM' );
26 ok( $date eq '12/02/2003 1:01:03 PM', 'returning untainted date' );
27 ok( $year == 2003, 'basic date prepare and parse test' );
28 ok( $month == 12 );
29 ok( $day == 2 );
30 ok( $hour == 13 );
31 ok( $min == 1 );
32 ok( $sec == 3 );
2633
2734 # Now try again, leaving out PM, which may trigger a warning when it shouldn't
28 $format = Data::FormValidator::Constraints::Dates::_prepare_date_format('MM/DD/YYYY hh?:mm:ss');
29 ($date,$year, $month, $day, $hour, $min, $sec) = Data::FormValidator::Constraints::Dates::_parse_date_format($format, '12/02/2003 1:01:03');
30 is($date,'12/02/2003 1:01:03','returning untainted date');
31 ok ($year == 2003, 'basic date prepare and parse test');
32 ok ($month == 12, 'month');
33 ok ($day == 2,'day');
34 ok ($hour == 1,'hour');
35 ok ($min == 1,'min');
36 ok ($sec == 3,'sec');
35 $format = Data::FormValidator::Constraints::Dates::_prepare_date_format(
36 'MM/DD/YYYY hh?:mm:ss');
37 ( $date, $year, $month, $day, $hour, $min, $sec ) =
38 Data::FormValidator::Constraints::Dates::_parse_date_format( $format,
39 '12/02/2003 1:01:03' );
40 is( $date, '12/02/2003 1:01:03', 'returning untainted date' );
41 ok( $year == 2003, 'basic date prepare and parse test' );
42 ok( $month == 12, 'month' );
43 ok( $day == 2, 'day' );
44 ok( $hour == 1, 'hour' );
45 ok( $min == 1, 'min' );
46 ok( $sec == 3, 'sec' );
3747
3848 use Data::FormValidator;
3949
4050 my $simple_profile = {
41 required => [qw/date_and_time_field_bad date_and_time_field_good/],
42 validator_packages => [qw/Data::FormValidator::Constraints::Dates/],
43 constraints => {
44 'date_and_time_field_good' => {
45 constraint_method => 'date_and_time',
46 params=>[\'MM/DD/YYYY hh:mm pp'],
47 },
48 'date_and_time_field_bad' => {
49 constraint_method => 'date_and_time',
50 params=>[\'MM/DD/YYYY hh:mm pp'],
51 },
52 },
53 untaint_constraint_fields=>[qw/date_and_time_field/],
51 required => [qw/date_and_time_field_bad date_and_time_field_good/],
52 validator_packages => [qw/Data::FormValidator::Constraints::Dates/],
53 constraints => {
54 'date_and_time_field_good' => {
55 constraint_method => 'date_and_time',
56 params => [ \'MM/DD/YYYY hh:mm pp' ],
57 },
58 'date_and_time_field_bad' => {
59 constraint_method => 'date_and_time',
60 params => [ \'MM/DD/YYYY hh:mm pp' ],
61 },
62 },
63 untaint_constraint_fields => [qw/date_and_time_field/],
5464 };
5565
5666 my $simple_data = {
57 date_and_time_field_good => '12/04/2003 02:00 PM',
58 date_and_time_field_bad => 'slug',
59 };
67 date_and_time_field_good => '12/04/2003 02:00 PM',
68 date_and_time_field_bad => 'slug',
69 };
6070
71 my $validator = new Data::FormValidator( {
72 simple => $simple_profile,
73 } );
6174
62 my $validator = new Data::FormValidator({
63 simple => $simple_profile,
64 });
75 my ( $valids, $missings, $invalids, $unknowns ) = ( {}, [], {}, [] );
76 eval {
77 ( $valids, $missings, $invalids, $unknowns ) =
78 $validator->validate( $simple_data, 'simple' );
79 };
80 ok( ( not $@ ), 'eval' )
81 or diag $@;
82 ok( $valids->{date_and_time_field_good}, 'expecting date_and_time success' );
83 ok( ( grep /date_and_time_field_bad/, @$invalids ),
84 'expecting date_and_time failure' );
6585
66 my ($valids, $missings, $invalids, $unknowns) = ({},[],{},[]);
67 eval{
68 ($valids, $missings, $invalids, $unknowns) = $validator->validate($simple_data, 'simple');
69 };
70 ok ((not $@), 'eval') or
71 diag $@;
72 ok ($valids->{date_and_time_field_good}, 'expecting date_and_time success');
73 ok ((grep /date_and_time_field_bad/, @$invalids), 'expecting date_and_time failure');
74
75 {
76 my $format = Data::FormValidator::Constraints::Dates::_prepare_date_format('MMDDYYYY');
77 my ($date,$year, $month, $day, $hour, $min, $sec) =
78 Data::FormValidator::Constraints::Dates::_parse_date_format($format, '12022003');
79 ok ($date eq '12022003','returning date');
80 ok ($year == 2003, 'basic date prepare and parse test');
81 ok ($month == 12);
82 ok ($day == 2);
86 {
87 my $format =
88 Data::FormValidator::Constraints::Dates::_prepare_date_format('MMDDYYYY');
89 my ( $date, $year, $month, $day, $hour, $min, $sec ) =
90 Data::FormValidator::Constraints::Dates::_parse_date_format( $format,
91 '12022003' );
92 ok( $date eq '12022003', 'returning date' );
93 ok( $year == 2003, 'basic date prepare and parse test' );
94 ok( $month == 12 );
95 ok( $day == 2 );
8396 }
0 #!/usr/bin/perl -w
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
13 use Test::More;
2
3 eval { require Date::Calc; };
4 if( $@ ) {
5 plan skip_all => 'Date::Calc required for date testing';
6 }
7 else {
8 plan 'no_plan';
9 }
10
11 require Data::FormValidator::Constraints::Dates;
12
13 use strict;
14
15 use strict;
16
17 my $format = Data::FormValidator::Constraints::Dates::_prepare_date_format('MM/DD/YYYY hh?:mm:ss pp');
18
19 my ($date,$year, $month, $day, $hour, $min, $sec) = Data::FormValidator::Constraints::Dates::_parse_date_format($format, '12/02/2003 1:01:03 PM');
20 ok ($date eq '12/02/2003 1:01:03 PM','returning untainted date');
21 ok ($year == 2003, 'basic date prepare and parse test');
22 ok ($month == 12);
23 ok ($day == 2);
24 ok ($hour == 13);
25 ok ($min == 1);
26 ok ($sec == 3);
27
28 # Now try again, leaving out PM, which may trigger a warning when it shouldn't
29 $format = Data::FormValidator::Constraints::Dates::_prepare_date_format('MM/DD/YYYY hh?:mm:ss');
30 ($date,$year, $month, $day, $hour, $min, $sec) = Data::FormValidator::Constraints::Dates::_parse_date_format($format, '12/02/2003 1:01:03');
31 is($date,'12/02/2003 1:01:03','returning untainted date');
32 ok ($year == 2003, 'basic date prepare and parse test');
33 ok ($month == 12, 'month');
34 ok ($day == 2,'day');
35 ok ($hour == 1,'hour');
36 ok ($min == 1,'min');
37 ok ($sec == 3,'sec');
38
394 use Data::FormValidator;
405 use Data::FormValidator::Constraints::Dates qw( date_and_time );
416
7 eval { require Date::Calc; };
8 if ($@)
9 {
10 plan skip_all => 'Date::Calc required for date testing';
11 }
12 else
13 {
14 plan 'no_plan';
15 }
16
17 my $format = Data::FormValidator::Constraints::Dates::_prepare_date_format(
18 'MM/DD/YYYY hh?:mm:ss pp');
19
20 my ( $date, $year, $month, $day, $hour, $min, $sec ) =
21 Data::FormValidator::Constraints::Dates::_parse_date_format( $format,
22 '12/02/2003 1:01:03 PM' );
23 ok( $date eq '12/02/2003 1:01:03 PM', 'returning untainted date' );
24 ok( $year == 2003, 'basic date prepare and parse test' );
25 ok( $month == 12 );
26 ok( $day == 2 );
27 ok( $hour == 13 );
28 ok( $min == 1 );
29 ok( $sec == 3 );
30
31 # Now try again, leaving out PM, which may trigger a warning when it shouldn't
32 $format = Data::FormValidator::Constraints::Dates::_prepare_date_format(
33 'MM/DD/YYYY hh?:mm:ss');
34 ( $date, $year, $month, $day, $hour, $min, $sec ) =
35 Data::FormValidator::Constraints::Dates::_parse_date_format( $format,
36 '12/02/2003 1:01:03' );
37 is( $date, '12/02/2003 1:01:03', 'returning untainted date' );
38 ok( $year == 2003, 'basic date prepare and parse test' );
39 ok( $month == 12, 'month' );
40 ok( $day == 2, 'day' );
41 ok( $hour == 1, 'hour' );
42 ok( $min == 1, 'min' );
43 ok( $sec == 3, 'sec' );
44
4245 my $simple_profile = {
43 required => [qw/date_and_time_field_bad date_and_time_field_good/],
44 validator_packages => [qw/Data::FormValidator::Constraints::Dates/],
45 constraint_methods => {
46 'date_and_time_field_good' => date_and_time('MM/DD/YYYY hh:mm pp'),
47 'date_and_time_field_bad' => date_and_time('MM/DD/YYYY hh:mm pp'),
48 },
49 untaint_constraint_fields=>[qw/date_and_time_field/],
46 required => [qw/date_and_time_field_bad date_and_time_field_good/],
47 validator_packages => [qw/Data::FormValidator::Constraints::Dates/],
48 constraint_methods => {
49 'date_and_time_field_good' => date_and_time('MM/DD/YYYY hh:mm pp'),
50 'date_and_time_field_bad' => date_and_time('MM/DD/YYYY hh:mm pp'),
51 },
52 untaint_constraint_fields => [qw/date_and_time_field/],
5053 };
5154
5255 my $simple_data = {
53 date_and_time_field_good => '12/04/2003 02:00 PM',
54 date_and_time_field_bad => 'slug',
55 };
56 date_and_time_field_good => '12/04/2003 02:00 PM',
57 date_and_time_field_bad => 'slug',
58 };
5659
60 my $validator = new Data::FormValidator( {
61 simple => $simple_profile,
62 } );
5763
58 my $validator = new Data::FormValidator({
59 simple => $simple_profile,
60 });
61
62 my ($valids, $missings, $invalids, $unknowns) = ({},[],{},[]);
63 eval{
64 ($valids, $missings, $invalids, $unknowns) = $validator->validate($simple_data, 'simple');
64 my ( $valids, $missings, $invalids, $unknowns ) = ( {}, [], {}, [] );
65 eval {
66 ( $valids, $missings, $invalids, $unknowns ) =
67 $validator->validate( $simple_data, 'simple' );
6568 };
66 ok ((not $@), 'eval') or
67 diag $@;
68 ok ($valids->{date_and_time_field_good}, 'expecting date_and_time success');
69 ok ((grep /date_and_time_field_bad/, @$invalids), 'expecting date_and_time failure');
69 ok( ( not $@ ), 'eval' )
70 or diag $@;
71 ok( $valids->{date_and_time_field_good}, 'expecting date_and_time success' );
72 ok( ( grep /date_and_time_field_bad/, @$invalids ),
73 'expecting date_and_time failure' );
7074
7175 {
72 my $r = Data::FormValidator->check({
73 # Testing leap years
74 date_and_time_field_good => '02/29/2008',
75 date_and_time_field_bad_pat => '02/29/2008',
76 leap_seventy_six => '02/29/1976',
77 },
76 my $r = Data::FormValidator->check( {
77 # Testing leap years
78 date_and_time_field_good => '02/29/2008',
79 date_and_time_field_bad_pat => '02/29/2008',
80 leap_seventy_six => '02/29/1976',
81 },
7882 {
79 required => [qw/date_and_time_field_good date_and_time_field_bad_pat/],
80 constraint_methods => {
81 'date_and_time_field_good' => date_and_time('MM/DD/YY(?:YY)?'),
82 # This pattern actually tests with a 3 digit year, not a four digit year, and fails
83 # on the date 02/29/2008, because 02/29/200 doesn't exist.
84 'date_and_time_field_bad_pat' => date_and_time('MM/DD/YYY?Y?'),
85 'leap_seventy_six' => date_and_time('MM/DD/YY(?:YY)?'),
86 },
87 });
88 my $valid = $r->valid;
89 ok ($valid->{date_and_time_field_good}, '02/29/2008 should pass MM/DD/YY(?:YY)?');
83 required => [qw/date_and_time_field_good date_and_time_field_bad_pat/],
84 constraint_methods => {
85 'date_and_time_field_good' => date_and_time('MM/DD/YY(?:YY)?'),
9086
91 TODO: {
92 local $TODO = "leap year bug?";
93 ok ($valid->{leap_seventy_six}, '02/29/1976 should pass MM/DD/YY(?:YY)?');
94 };
87 # This pattern actually tests with a 3 digit year, not a four digit year, and fails
88 # on the date 02/29/2008, because 02/29/200 doesn't exist.
89 'date_and_time_field_bad_pat' => date_and_time('MM/DD/YYY?Y?'),
90 'leap_seventy_six' => date_and_time('MM/DD/YY(?:YY)?'),
91 },
92 } );
93 my $valid = $r->valid;
94 ok(
95 $valid->{date_and_time_field_good},
96 '02/29/2008 should pass MM/DD/YY(?:YY)?'
97 );
9598
96 # This one fails not because the date is bad, but because the pattern is not sensible
97 # It would be better to detect that the pattern was bad and fail that way, of course.
98 ok ( $r->invalid('date_and_time_field_bad_pat'), "02/29/2008 should fail MM/DD/YYY?Y?" );
99 TODO:
100 {
101 local $TODO = "leap year bug?";
102 ok( $valid->{leap_seventy_six}, '02/29/1976 should pass MM/DD/YY(?:YY)?' );
103 }
99104
105 # This one fails not because the date is bad, but because the pattern is not sensible
106 # It would be better to detect that the pattern was bad and fail that way, of course.
107 ok(
108 $r->invalid('date_and_time_field_bad_pat'),
109 "02/29/2008 should fail MM/DD/YYY?Y?"
110 );
100111 }
0 #!/usr/bin/env perl
01 use strict;
1
2 $^W = 1;
3
2 use warnings;
43 use Test::More tests => 18;
54 use Data::FormValidator;
65
7 my %code_results = ( );
8 my $input_hashref = { };
6 my %code_results = ();
7 my $input_hashref = {};
98 my $input_profile = {
10 dependencies => {
11 cc_type => sub {
12 my $dfv = shift;
13 my $type = shift;
14
15 return [ 'cc_cvv' ] if ($type eq "VISA" || $type eq "MASTERCARD");
16 return [ ];
17 },
9 dependencies => {
10 cc_type => sub {
11 my $dfv = shift;
12 my $type = shift;
1813
19 code_checker => sub {
20 my($dfv, $val) = @_;
14 return ['cc_cvv'] if ( $type eq "VISA" || $type eq "MASTERCARD" );
15 return [];
16 },
2117
22 $code_results{'code_called'} = 1;
23 $code_results{'num_args'} = @_;
24 $code_results{'value'} = $val;
25 $code_results{'dfv_obj'} = $dfv;
18 code_checker => sub {
19 my ( $dfv, $val ) = @_;
2620
27 return [ ];
28 },
21 $code_results{'code_called'} = 1;
22 $code_results{'num_args'} = @_;
23 $code_results{'value'} = $val;
24 $code_results{'dfv_obj'} = $dfv;
25
26 return [];
2927 },
28 },
3029 };
3130
32 my $validator = Data::FormValidator->new({default => $input_profile});
31 my $validator = Data::FormValidator->new( { default => $input_profile } );
3332 my $result;
34
3533
3634 ##
3735 ## Validate a coderef dependency
3836 ##
39
4037
4138 ## Check that the code actually gets called.
4239 #############################################################################
4340
4441 $input_hashref->{code_checker} = 'test';
4542 $result = undef;
46 eval { $result = $validator->check($input_hashref, 'default'); };
43 eval { $result = $validator->check( $input_hashref, 'default' ); };
4744
48 ok(!$@, "checking that dependency coderef is called");
49 ok($code_results{code_called}, " code was called");
50 is($code_results{num_args}, 2, " code received 2 args");
51 is($code_results{value}, 'test', " received correct value");
52 ok($code_results{dfv_obj}, " received dfv object");
53 isa_ok($code_results{dfv_obj}, 'Data::FormValidator::Results',
54 " dfv object");
45 ok( !$@, "checking that dependency coderef is called" );
46 ok( $code_results{code_called}, " code was called" );
47 is( $code_results{num_args}, 2, " code received 2 args" );
48 is( $code_results{value}, 'test', " received correct value" );
49 ok( $code_results{dfv_obj}, " received dfv object" );
50 isa_ok( $code_results{dfv_obj}, 'Data::FormValidator::Results',
51 " dfv object" );
5552
5653 delete $input_hashref->{code_checker};
57
5854
5955 ## Value that should cause a missing dependency.
6056 #############################################################################
6157
6258 $input_hashref->{cc_type} = 'VISA';
6359 $result = undef;
64 eval { $result = $validator->check($input_hashref, 'default'); };
60 eval { $result = $validator->check( $input_hashref, 'default' ); };
6561
66 ok(!$@, "checking a value that has a depenency");
67 isa_ok($result, "Data::FormValidator::Results", " returned object");
68 ok($result->has_missing, " has_missing returned true");
69 ok($result->missing('cc_cvv'), " missing('cc_cvv') returned true");
70
62 ok( !$@, "checking a value that has a depenency" );
63 isa_ok( $result, "Data::FormValidator::Results", " returned object" );
64 ok( $result->has_missing, " has_missing returned true" );
65 ok( $result->missing('cc_cvv'), " missing('cc_cvv') returned true" );
7166
7267 ## Value that should NOT cause a missing dependency.
7368 #############################################################################
7469
7570 $input_hashref->{cc_type} = 'AMEX';
7671 $result = undef;
77 eval { $result = $validator->check($input_hashref, 'default'); };
72 eval { $result = $validator->check( $input_hashref, 'default' ); };
7873
79 ok(!$@, "checking a value that has no dependencies");
80 isa_ok($result, "Data::FormValidator::Results", " returned object");
81 ok(!$result->has_missing, " has_missing returned false");
82 is($result->missing('cc_cvv'), undef, " missing('cc_cvv') returned false");
83
74 ok( !$@, "checking a value that has no dependencies" );
75 isa_ok( $result, "Data::FormValidator::Results", " returned object" );
76 ok( !$result->has_missing, " has_missing returned false" );
77 is( $result->missing('cc_cvv'), undef, " missing('cc_cvv') returned false" );
8478
8579 ## Test with multiple values
8680 #############################################################################
8781
8882 $input_hashref->{cc_type} = [ 'AMEX', 'VISA' ];
8983 $result = undef;
90 eval { $result = $validator->check($input_hashref, 'default'); };
84 eval { $result = $validator->check( $input_hashref, 'default' ); };
9185
92 ok(!$@, "checking multiple values");
93 isa_ok($result, "Data::FormValidator::Results", " returned object");
94 ok($result->has_missing, " has_missing returned true");
95 is($result->missing('cc_cvv'), 1, " missing('cc_cvv') returned true");
86 ok( !$@, "checking multiple values" );
87 isa_ok( $result, "Data::FormValidator::Results", " returned object" );
88 ok( $result->has_missing, " has_missing returned true" );
89 is( $result->missing('cc_cvv'), 1, " missing('cc_cvv') returned true" );
0 #!/usr/bin/env perl
01 use strict;
2 use warnings;
3 use Test::More;
4 use Data::FormValidator;
15
2 $^W = 1;
3
4 use Test::More 'no_plan'; #tests => 23;
5 use Data::FormValidator;
6 use CGI;
7
6 eval { require CGI;CGI->VERSION(4.35); };
7 plan skip_all => 'CGI 4.35 or higher not found' if $@;
88
99 # test profile
1010 my $input_profile = {
11 dependency_groups => {
12 password => [qw/pass1 pass2/],
13 },
11 dependency_groups => {
12 password => [qw/pass1 pass2/],
13 },
1414 };
15 my $input_hashref = {pass1=>'foo'};
15 my $input_hashref = { pass1 => 'foo' };
1616
17 my ($valids, $missings, $invalids, $unknowns);
17 my ( $valids, $missings, $invalids, $unknowns );
1818 my $result;
1919 my @fields = (qw/pass1 pass2/);
20 my $validator = Data::FormValidator->new({default => $input_profile});
20 my $validator = Data::FormValidator->new( { default => $input_profile } );
2121
22 foreach my $fields ( [qw/pass1 pass2/], [qw/pass2 pass1/] )
23 {
24 my ( $good, $bad ) = @$fields;
25 $input_hashref = { $good => 'foo' };
2226
27 ##
28 ## validate()
2329
24 foreach my $fields ([qw/pass1 pass2/], [qw/pass2 pass1/]) {
25 my ($good, $bad) = @$fields;
26 $input_hashref = {$good => 'foo'};
30 eval {
31 ( $valids, $missings, $invalids, $unknowns ) =
32 $validator->validate( $input_hashref, 'default' );
33 };
34 ok( !$@, "no eval problems" );
2735
28 ##
29 ## validate()
36 my %missings = map { $_ => 1 } @$missings;
37 is( $valids->{$good}, $input_hashref->{$good}, "[$good] valid" );
38 ok( $missings{$bad}, "missing [$bad]" );
3039
31 eval{
32 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
33 };
34 ok(!$@, "no eval problems");
40 ##
41 ## check()
3542
36 my %missings = map {$_ => 1} @$missings;
37 is($valids->{$good}, $input_hashref->{$good}, "[$good] valid");
38 ok($missings{$bad}, "missing [$bad]");
43 my $q = CGI->new("$good=foo");
44 foreach my $input ( $input_hashref, $q )
45 {
46 eval { $result = $validator->check( $input, 'default' ); };
3947
48 ok( !$@, "no eval problems" );
49 isa_ok( $result, "Data::FormValidator::Results", "returned object" );
4050
41 ##
42 ## check()
43
44 my $q = CGI->new("$good=foo");
45 foreach my $input ($input_hashref, $q) {
46 eval {
47 $result = $validator->check($input, 'default');
48 };
49
50 ok(!$@, "no eval problems");
51 isa_ok($result, "Data::FormValidator::Results", "returned object");
52
53 ok($result->has_missing, "has_missing returned true");
54 ok($result->missing($bad), "missing($bad) returned true");
55 ok(!$result->missing($good), "missing($good) returned false");
56 ok($result->valid($good), "valid($good) returned true");
57 ok(!$result->valid($bad), "valid($bad) returned true");
58 }
51 ok( $result->has_missing, "has_missing returned true" );
52 ok( $result->missing($bad), "missing($bad) returned true" );
53 ok( !$result->missing($good), "missing($good) returned false" );
54 ok( $result->valid($good), "valid($good) returned true" );
55 ok( !$result->valid($bad), "valid($bad) returned true" );
56 }
5957 }
58 done_testing;
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use lib ( '.', '../t' );
4 use Test::More tests => 4;
5 use Data::FormValidator;
6
07 # This test is a for a bug where a value doesn't get filtered when it should
1 # The bug was discovered by Jeff Till, and he contributed this test, too.
8 # The bug was discovered by Jeff Till, and he contributed this test, too.
9 # Verify that multiple params passed to a constraint are being filtered
10 my $validator = new Data::FormValidator( {
11 default => {
12 filters => ['trim'],
13 required => [qw/my_junk_field my_other_field/],
14 constraints => {
15 my_junk_field => {
16 constraint => \&letters_2_var,
17 name => 'zipcode',
218
3 use strict;
4 use Test::More tests => 4;
5 use lib ('.','../t');
6
7 # Verify that multiple params passed to a constraint are being filtered
19 },
20 my_other_field => \&letters,
21 },
22 },
23 } );
824
9 $^W = 1;
10
11
12 use Data::FormValidator;
13
14 my $validator = new Data::FormValidator({
15 default =>
16 {
17 filters => [ 'trim' ],
18 required => [ qw/my_junk_field my_other_field/],
19 constraints => {
20 my_junk_field => {
21 constraint => \&letters_2_var,
22 name => 'zipcode',
23
24 },
25 my_other_field => \&letters,
26 },
27 },
28 });
29
30 sub letters_2_var {
31 if ($_[0] =~ /^[a-z]+$/i) {
32 return 1;
33 }
34 return 0;
35 }
36
37 sub letters{
38 if($_[0] =~ /^[a-z]+$/i){
25 sub letters_2_var
26 {
27 if ( $_[0] =~ /^[a-z]+$/i )
28 {
3929 return 1;
4030 }
4131 return 0;
4232 }
4333
44 my $input_hashref =
34 sub letters
35 {
36 if ( $_[0] =~ /^[a-z]+$/i )
4537 {
46 my_junk_field => 'foo ',
47 my_other_field => ' bar',
48 };
49
50 my ($valids, $missings, $invalids, $unknowns) =
51 $validator->validate($input_hashref, 'default');
52
53 is_deeply($invalids, [], "all fields are valid");
54
55 { # RT#13078
56 my $res;
57 eval {
58 $res = Data::FormValidator->check({
59 local_filter => ' needs@trimmed.com ',
60 global_filter_field => ' needs@trimmed.com ',
61 },
62 {
63 required => [ 'local_filter', 'global_filter_field' ],
64 filters => [ sub { my $v = shift; $v =~ s/needs/global/g; $v }, ],
65 field_filters => {
66 local_filter => 'trim',
67 },
68 constraints => {
69 local_filter => [
70 'email',
71 {
72 constraint => sub {
73 my $val = shift;
74 return ($val eq 'global@trimmed.com');
75 },
76 params => ['local_filter'],
77 }
78 ],
79 global_filter_field => [
80 sub {
81 my $val = shift;
82 if ($val eq ' global@trimmed.com ') {
83 return 1;
84 }
85 else {
86 warn "without param got: '$val', expected 'global\@trimmed.com'";
87 return undef;
88 }
89 },
90 {
91 constraint => sub {
92 my $val = shift;
93 if ($val eq ' global@trimmed.com ') {
94 return 1;
95 }
96 else {
97 warn " using param got: '$val', expected 'global\@trimmed.com'";
98 return undef;
99 }
100 },
101 params => ['global_filter_field'],
102 },
103 ]
104 },
105 });
106 };
107 is($@,'', 'survived eval');
108
109 eval { ok($res->valid('local_filter')," when passed through param, local filters are applied."); };
110 eval { ok($res->valid('global_filter_field')," when passed through param, global filters are applied."); };
111
112
38 return 1;
39 }
40 return 0;
11341 }
11442
43 my $input_hashref = {
44 my_junk_field => 'foo ',
45 my_other_field => ' bar',
46 };
47
48 my ( $valids, $missings, $invalids, $unknowns ) =
49 $validator->validate( $input_hashref, 'default' );
50
51 is_deeply( $invalids, [], "all fields are valid" );
52
53 { # RT#13078
54 my $res;
55 eval {
56 $res = Data::FormValidator->check( {
57 local_filter => ' needs@trimmed.com ',
58 global_filter_field => ' needs@trimmed.com ',
59 },
60 {
61 required => [ 'local_filter', 'global_filter_field' ],
62 filters => [ sub { my $v = shift; $v =~ s/needs/global/g; $v }, ],
63 field_filters => {
64 local_filter => 'trim',
65 },
66 constraints => {
67 local_filter => [
68 'email',
69 {
70 constraint => sub {
71 my $val = shift;
72 return ( $val eq 'global@trimmed.com' );
73 },
74 params => ['local_filter'],
75 }
76 ],
77 global_filter_field => [
78 sub {
79 my $val = shift;
80 if ( $val eq ' global@trimmed.com ' )
81 {
82 return 1;
83 }
84 else
85 {
86 warn
87 "without param got: '$val', expected 'global\@trimmed.com'";
88 return undef;
89 }
90 },
91 {
92 constraint => sub {
93 my $val = shift;
94 if ( $val eq ' global@trimmed.com ' )
95 {
96 return 1;
97 }
98 else
99 {
100 warn
101 " using param got: '$val', expected 'global\@trimmed.com'";
102 return undef;
103 }
104 },
105 params => ['global_filter_field'],
106 },
107 ]
108 },
109 } );
110 };
111 is( $@, '', 'survived eval' );
112
113 eval
114 {
115 ok( $res->valid('local_filter'),
116 " when passed through param, local filters are applied." );
117 };
118 eval
119 {
120 ok( $res->valid('global_filter_field'),
121 " when passed through param, global filters are applied." );
122 };
123 }
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More 'no_plan';
14 use Data::FormValidator::Filters (qw/:filters/);
2 use strict;
35
4 {
5 my $comma_splitter = FV_split(',');
6 is_deeply( $comma_splitter->('a,b'), [qw/a b/], "FV_split with two values");
7 is_deeply( $comma_splitter->('a'), [qw/a/], "FV_split with one value");
8 is_deeply( $comma_splitter->(),undef, "FV_split with no values");
6 {
7 my $comma_splitter = FV_split(',');
8 is_deeply( $comma_splitter->('a,b'), [qw/a b/], "FV_split with two values" );
9 is_deeply( $comma_splitter->('a'), [qw/a/], "FV_split with one value" );
10 is_deeply( $comma_splitter->(), undef, "FV_split with no values" );
911 }
1012
1113 {
12 my $replacer = FV_replace(qr/^a/,'b');
13 is( $replacer->('aa'), 'ba', 'FV_replace positive test');
14 is( $replacer->('XX'), 'XX', 'FV_replace negative test');
14 my $replacer = FV_replace( qr/^a/, 'b' );
15 is( $replacer->('aa'), 'ba', 'FV_replace positive test' );
16 is( $replacer->('XX'), 'XX', 'FV_replace negative test' );
1517
16 my $replacer = FV_replace(qr/^a/i,'b');
17 is( $replacer->('AA'), 'bA', 'FV_replace positive test');
18 $replacer = FV_replace( qr/^a/i, 'b' );
19 is( $replacer->('AA'), 'bA', 'FV_replace positive test' );
1820 }
1921
22 is( filter_dollars('There is $0.11e money in here somewhere'),
23 '0.11', "filter_dollars works as expected" );
2024
25 TODO:
26 {
27 local $TODO = 'all these broken filters need to be dealt with.';
28 is( filter_dollars('0.111'), '0.11',
29 "filter_dollars removes trailing numbers" );
2130
22 is( filter_dollars('There is $0.11e money in here somewhere'),
23 '0.11',
24 "filter_dollars works as expected");
31 is( filter_neg_integer('9-'), 'a9-',
32 "filter_neg_integer should leave string without a negative integer alone."
33 );
2534
26 TODO: {
27 local $TODO = 'all these broken filters need to be dealt with.';
28 is( filter_dollars('0.111'),
29 '0.11',
30 "filter_dollars removes trailing numbers");
35 is( filter_pos_integer('a9+'),
36 '9', "filter_pos_integer should care which side a + is on." );
3137
32 is( filter_neg_integer('9-'),
33 'a9-',
34 "filter_neg_integer should leave string without a negative integer alone.");
38 is( filter_integer('a9+'), '9',
39 "filter_integer should care which side a + is on." );
3540
36 is( filter_pos_integer('a9+'),
37 '9',
38 "filter_pos_integer should care which side a + is on.");
41 is( filter_decimal('1,000.23'),
42 '1000.23', "filter_decimal should handle commas correctly" );
3943
40 is( filter_integer('a9+'),
41 '9',
42 "filter_integer should care which side a + is on.");
44 is( filter_pos_decimal('1,000.23'),
45 '1000.23', "filter_pos_decimal should handle commas correctly" );
4346
44 is( filter_decimal('1,000.23'),
45 '1000.23',
46 "filter_decimal should handle commas correctly");
47
48 is( filter_pos_decimal('1,000.23'),
49 '1000.23',
50 "filter_pos_decimal should handle commas correctly");
51
52 is( filter_neg_decimal('-1,000.23'),
53 '-1000.23',
54 "filter_neg_decimal should handle commas correctly");
47 is( filter_neg_decimal('-1,000.23'),
48 '-1000.23', "filter_neg_decimal should handle commas correctly" );
5549 }
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More qw/no_plan/;
14 use Data::FormValidator;
25
47
58 # Testing an internal function here, so it's OK if this test starts
69 # to fail because the API changes
7 my %out = Data::FormValidator::Results::_get_input_as_hash({},\%h);
10 my %out = Data::FormValidator::Results::_get_input_as_hash( {}, \%h );
811
9 isnt($h{key},$out{key},"after copying structure, values should have different memory addresses");
10
12 isnt( $h{key}, $out{key},
13 "after copying structure, values should have different memory addresses" );
1114
1215 {
13 Data::FormValidator->check(
14 \%h,
15 { required => [ 'key' ],
16 filters => [ 'trim' ],
17 });
16 Data::FormValidator->check(
17 \%h,
18 {
19 required => ['key'],
20 filters => ['trim'],
21 } );
1822
19 is($h{key}[0], ' value1 ', "filters shouldn't modify data in arrayrefs");
23 is( $h{key}[0], ' value1 ', "filters shouldn't modify data in arrayrefs" );
2024 }
21
22
23
24
25
0 #!/usr/bin/env perl
01 use strict;
2 use warnings;
13 use Test::More tests => 4;
24 use Data::FormValidator;
35 use Data::FormValidator::Constraints qw(FV_eq_with);
46
57 # Empty data/empty results; make sure fcn call works fine
6 access_filtered_data_no_data: {
7 my $results = Data::FormValidator->check( {}, {} );
8 my $filtered = $results->get_filtered_data();
9 is_deeply( $filtered, {}, 'get_filtered_data works for empty hashref' );
8 access_filtered_data_no_data:
9 {
10 my $results = Data::FormValidator->check( {}, {} );
11 my $filtered = $results->get_filtered_data();
12 is_deeply( $filtered, {}, 'get_filtered_data works for empty hashref' );
1013 }
1114
1215 # Test to make sure that we can access filtered data and that it looks right.
13 access_filtered_data: {
14 my $data = {
15 'password' => ' foo ',
16 'confirm' => ' foo ',
17 };
18 my $expect_filtered_data = {
19 'password' => 'foo',
20 'confirm' => 'foo',
21 };
22 my $profile = {
23 'required' => [qw( password confirm )],
24 'filters' => 'trim',
25 };
26 my $results = Data::FormValidator->check( $data, $profile );
27 my $filtered = $results->get_filtered_data();
28 is_deeply( $filtered, $expect_filtered_data, 'get_filtered_data returns correct filtered data' );
16 access_filtered_data:
17 {
18 my $data = {
19 'password' => ' foo ',
20 'confirm' => ' foo ',
21 };
22 my $expect_filtered_data = {
23 'password' => 'foo',
24 'confirm' => 'foo',
25 };
26 my $profile = {
27 'required' => [qw( password confirm )],
28 'filters' => 'trim',
29 };
30 my $results = Data::FormValidator->check( $data, $profile );
31 my $filtered = $results->get_filtered_data();
32 is_deeply( $filtered, $expect_filtered_data,
33 'get_filtered_data returns correct filtered data' );
2934 }
3035
3136 # RT#22589; FV_eq_with uses 'get_filtered_data()'
32 rt22589: {
33 my $data = {
34 'password' => ' foo ',
35 'confirm' => ' foo ',
36 };
37 my $profile = {
38 'required' => [qw( password confirm )],
39 'filters' => 'trim',
40 'constraint_methods' => {
41 'confirm' => FV_eq_with('password'),
42 },
43 };
44 my $results = Data::FormValidator->check( $data, $profile );
45 ok( $results->valid('password'), 'password valid' );
46 ok( $results->valid('confirm'), 'confirm valid' );
37 rt22589:
38 {
39 my $data = {
40 'password' => ' foo ',
41 'confirm' => ' foo ',
42 };
43 my $profile = {
44 'required' => [qw( password confirm )],
45 'filters' => 'trim',
46 'constraint_methods' => {
47 'confirm' => FV_eq_with('password'),
48 },
49 };
50 my $results = Data::FormValidator->check( $data, $profile );
51 ok( $results->valid('password'), 'password valid' );
52 ok( $results->valid('confirm'), 'confirm valid' );
4753 }
0 use Test::More qw/no_plan/;
1
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More;
24 use Data::FormValidator;
35
6 eval { require CGI;CGI->VERSION(4.35); };
7 plan skip_all => 'CGI 4.35 or higher not found' if $@;
8
49 {
5 my $results = Data::FormValidator->check({},{});
6 is_deeply($results->get_input_data, {}, 'get_input_data works for empty hashref' );
10 my $results = Data::FormValidator->check( {}, {} );
11 is_deeply( $results->get_input_data, {},
12 'get_input_data works for empty hashref' );
713 }
814
9 use CGI;
10 my $q = CGI->new( { key => 'value' });
11 my $results = Data::FormValidator->check($q,{});
15 my $q = CGI->new( { key => 'value' } );
16 my $results = Data::FormValidator->check( $q, {} );
1217
13 is_deeply($results->get_input_data, $q, 'get_input_data works for CGI object' );
18 is_deeply( $results->get_input_data, $q,
19 'get_input_data works for CGI object' );
1420
1521 {
16 my $href = $results->get_input_data(as_hashref => 1);
17 is_deeply($href , { key => 'value' }, 'get_input_data( as_hashref => 1 ) works for CGI object' );
22 my $href = $results->get_input_data( as_hashref => 1 );
23 is_deeply(
24 $href,
25 { key => 'value' },
26 'get_input_data( as_hashref => 1 ) works for CGI object'
27 );
1828 }
19
20
21
29 done_testing;
0 # Tests for missing_optional_valid
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
13 use Test::More 'no_plan';
2 use strict;
3
4 $^W = 1;
5
64 use Data::FormValidator;
75
6 # Tests for missing_optional_valid
87 my $input_profile = {
9 required => [ qw( email_1 email_ok) ],
10 optional => ['filled','not_filled'],
11 constraint_regexp_map => {
12 '/^email/' => "email",
13 },
14 constraints => {
15 not_filled => 'phone',
16 },
17 missing_optional_valid => 1,
18 };
8 required => [qw( email_1 email_ok)],
9 optional => [ 'filled', 'not_filled' ],
10 constraint_regexp_map => {
11 '/^email/' => "email",
12 },
13 constraints => {
14 not_filled => 'phone',
15 },
16 missing_optional_valid => 1,
17 };
1918
20 my $validator = new Data::FormValidator({default => $input_profile});
19 my $validator = new Data::FormValidator( { default => $input_profile } );
2120
2221 my $input_hashref = {
23 email_1 => 'invalidemail',
24 email_ok => 'mark@stosberg.com',
25 filled => 'dog',
26 not_filled => '',
27 should_be_unknown => 1,
22 email_1 => 'invalidemail',
23 email_ok => 'mark@stosberg.com',
24 filled => 'dog',
25 not_filled => '',
26 should_be_unknown => 1,
2827 };
2928
30 my ($valids, $missings, $invalids, $unknowns);
29 my ( $valids, $missings, $invalids, $unknowns );
3130
32 eval{
33 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
31 eval {
32 ( $valids, $missings, $invalids, $unknowns ) =
33 $validator->validate( $input_hashref, 'default' );
3434 };
35 is($@,'',"survived eval");
35 is( $@, '', "survived eval" );
3636
37 # "not_filled" should appear valids now.
38 ok (exists $valids->{'not_filled'});
39
37 # "not_filled" should appear valids now.
38 ok( exists $valids->{'not_filled'} );
4039
4140 # "should_be_unknown" should be still be unknown
42 ok($unknowns->[0] eq 'should_be_unknown');
41 ok( $unknowns->[0] eq 'should_be_unknown' );
4342
44 eval {
45 require CGI;
46 };
47 SKIP: {
48 skip 'CGI.pm not found', 3 if $@;
43 eval { require CGI;CGI->VERSION(4.35); };
44 SKIP:
45 {
46 skip 'CGI 4.35 or higher not found', 3 if $@;
4947
50 my $q = CGI->new($input_hashref);
51 my ($valids, $missings, $invalids, $unknowns);
52 eval{
53 ($valids, $missings, $invalids, $unknowns) = $validator->validate($q, 'default');
54 };
48 my $q = CGI->new($input_hashref);
49 my ( $valids, $missings, $invalids, $unknowns );
50 eval {
51 ( $valids, $missings, $invalids, $unknowns ) =
52 $validator->validate( $q, 'default' );
53 };
5554
56 ok (not $@);
55 ok( not $@ );
5756
58 # "not_filled" should appear valids now.
59 ok (exists $valids->{'not_filled'});
57 # "not_filled" should appear valids now.
58 ok( exists $valids->{'not_filled'} );
6059
61 # "should_be_unknown" should be still be unknown
62 ok($unknowns->[0] eq 'should_be_unknown');
60 # "should_be_unknown" should be still be unknown
61 ok( $unknowns->[0] eq 'should_be_unknown' );
6362
64 };
65
66 {
67 my $res = Data::FormValidator->check(
68 { a => 1,
69 b => undef,
70 # c is completely missing
71 },
72 { optional => [ qw/a b c/ ],
73 missing_optional_valid => 1 } );
74
75 is(join(',',sort $res->valid()),'a,b', "optional fields have to at least exist to be valid" );
7663 }
7764
7865 {
79 my $data = {
80 optional_invalid => 'invalid'
81 };
66 my $res = Data::FormValidator->check( {
67 a => 1,
68 b => undef,
8269
83 my $profile = {
84 optional => [qw/optional_invalid/],
85 constraints => {
86 optional_invalid => qr/^valid$/
87 },
88 missing_optional_valid => 1
89 };
70 # c is completely missing
71 },
72 {
73 optional => [qw/a b c/],
74 missing_optional_valid => 1
75 } );
9076
91 my $results = Data::FormValidator->check($data, $profile);
92 my $valid = $results->valid();
93 my $invalid = $results->invalid();
94 ok( exists $invalid->{'optional_invalid'}, 'optional_invalid is invalid');
95 ok( !exists $valid->{'optional_invalid'}, 'optional_invalid is not valid');
77 is( join( ',', sort $res->valid() ),
78 'a,b', "optional fields have to at least exist to be valid" );
9679 }
80
81 {
82 my $data = { optional_invalid => 'invalid' };
83
84 my $profile = {
85 optional => [qw/optional_invalid/],
86 constraints => {
87 optional_invalid => qr/^valid$/
88 },
89 missing_optional_valid => 1
90 };
91
92 my $results = Data::FormValidator->check( $data, $profile );
93 my $valid = $results->valid();
94 my $invalid = $results->invalid();
95 ok( exists $invalid->{'optional_invalid'}, 'optional_invalid is invalid' );
96 ok( !exists $valid->{'optional_invalid'}, 'optional_invalid is not valid' );
97 }
+188
-195
t/msgs.t less more
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More qw/no_plan/;
1 use strict;
2
34 use Data::FormValidator;
45
56 my $simple_profile = {
6 required => [qw/req_1 req_2/],
7 optional => [qw/opt_1/],
8 constraints => {
9 req_1 => 'email'
10 },
11 msgs=>{},
7 required => [qw/req_1 req_2/],
8 optional => [qw/opt_1/],
9 constraints => {
10 req_1 => 'email'
11 },
12 msgs => {},
1213 };
1314
14 my $simple_data = {
15 req_1 => 'not_an_email',
16 };
15 my $simple_data = { req_1 => 'not_an_email', };
1716
1817 my $prefix_profile = {
19 required => [qw/req_1 req_2/],
20 optional => [qw/opt_1/],
21 constraints => {
22 req_1 => 'email'
23 },
24 msgs=>{
25 prefix=>'',
26 any_errors=>'err__',
27 },
18 required => [qw/req_1 req_2/],
19 optional => [qw/opt_1/],
20 constraints => {
21 req_1 => 'email'
22 },
23 msgs => {
24 prefix => '',
25 any_errors => 'err__',
26 },
2827 };
2928
3029 my $input_profile = {
31 required => [ qw(admin prefork sleep rounds) ],
32 constraints => {
33 admin => "email",
34 prefork => sub {
35 my $val = shift;
36 if ($val =~ /^\d$/) {
37 if ($val > 1 and $val <9) {
38 return $val;
39 }
40 }
41 return 0;
42 },
43 sleep => [
44 'email',
45 {
46 name => 'min',
47 constraint => sub {
48 my $val = shift;
49 if ($val > 0) {
50 return $val;
51 } else {
52 return 0;
53 }
54 }
55 },
56 {
57 name => 'max',
58 constraint => sub {
59 my $val = shift;
60 if ($val < 11) {
61 return $val;
62 } else {
63 return 0;
64 }
65 }
66 }
67 ],
68 rounds => [
69 {
70 name => 'min',
71 constraint => sub {
72 my $val = shift;
73 if ($val > 19) {
74 return $val;
75 } else {
76 return 0;
77 }
78 }
79 },
80 {
81 name => 'max',
82 constraint => sub {
83 my $val = shift;
84 if ($val < 101) {
85 return $val;
86 } else {
87 return 0;
88 }
89 }
90 }
91 ]
92 },
93 msgs => {
94 missing => 'Test-Missing',
95 invalid => 'Test-Invalid',
96 invalid_seperator=> ' ## ',
97
98 constraints => {
99 max => 'needs to be lesser than 11',
100 min => 'needs to be greater than 0'
101 },
102 format => 'ERROR: %s',
103 prefix => 'error_',
104 }
105 };
106
107 my $validator = new Data::FormValidator({
108 simple => $simple_profile,
109 default => $input_profile,
110 prefix => $prefix_profile,
111 });
112
113 my $input_hashref = {admin=> 'invalidemail', prefork=> 9, sleep => 11, rounds=>8};
30 required => [qw(admin prefork sleep rounds)],
31 constraints => {
32 admin => "email",
33 prefork => sub {
34 my $val = shift;
35 if ( $val =~ /^\d$/ )
36 {
37 if ( $val > 1 and $val < 9 )
38 {
39 return $val;
40 }
41 }
42 return 0;
43 },
44 sleep => [
45 'email',
46 {
47 name => 'min',
48 constraint => sub {
49 my $val = shift;
50 if ( $val > 0 )
51 {
52 return $val;
53 }
54 else
55 {
56 return 0;
57 }
58 }
59 },
60 {
61 name => 'max',
62 constraint => sub {
63 my $val = shift;
64 if ( $val < 11 )
65 {
66 return $val;
67 }
68 else
69 {
70 return 0;
71 }
72 }
73 }
74 ],
75 rounds => [ {
76 name => 'min',
77 constraint => sub {
78 my $val = shift;
79 if ( $val > 19 )
80 {
81 return $val;
82 }
83 else
84 {
85 return 0;
86 }
87 }
88 },
89 {
90 name => 'max',
91 constraint => sub {
92 my $val = shift;
93 if ( $val < 101 )
94 {
95 return $val;
96 }
97 else
98 {
99 return 0;
100 }
101 }
102 } ]
103 },
104 msgs => {
105 missing => 'Test-Missing',
106 invalid => 'Test-Invalid',
107 invalid_seperator => ' ## ',
108
109 constraints => {
110 max => 'needs to be lesser than 11',
111 min => 'needs to be greater than 0'
112 },
113 format => 'ERROR: %s',
114 prefix => 'error_',
115 } };
116
117 my $validator = new Data::FormValidator( {
118 simple => $simple_profile,
119 default => $input_profile,
120 prefix => $prefix_profile,
121 } );
122
123 my $input_hashref =
124 { admin => 'invalidemail', prefork => 9, sleep => 11, rounds => 8 };
114125
115126 my $results;
116 eval{
117 $results = $validator->check($simple_data, 'simple');
118 };
119 ok (not $@);
120
121 TODO: {
122 local $TODO= 'need to test for msgs() called before validate';
123 # msgs() should return emit a warning and return undef if the hash
124 # structure it points to is undefined. However, if it points to an
125 # empty hash, then maybe there are just no messages.
126 };
127 eval { $results = $validator->check( $simple_data, 'simple' ); };
128 ok( not $@ );
129
130 TODO:
131 {
132 local $TODO = 'need to test for msgs() called before validate';
133
134 # msgs() should return emit a warning and return undef if the hash
135 # structure it points to is undefined. However, if it points to an
136 # empty hash, then maybe there are just no messages.
137 }
127138
128139 # testing simple msg definition, $self->msgs should be returned as a hash ref
129140 my $msgs;
130 eval {
131 $msgs = $results->msgs;
132 };
133 ok((not $@), 'existence of msgs method' ) or
134 diag $@;
135
136
137 ok (ref $msgs eq 'HASH', 'invalid fields returned as hash in simple case');
138
139
140 like ($msgs->{req_1}, qr/Invalid/, 'default invalid message');
141 like ($msgs->{req_2}, qr/Missing/, 'default missing message');
142 like ($msgs->{req_1}, qr/span/, 'default formatting');
143
141 eval { $msgs = $results->msgs; };
142 ok( ( not $@ ), 'existence of msgs method' )
143 or diag $@;
144
145 ok( ref $msgs eq 'HASH', 'invalid fields returned as hash in simple case' );
146
147 like( $msgs->{req_1}, qr/Invalid/, 'default invalid message' );
148 like( $msgs->{req_2}, qr/Missing/, 'default missing message' );
149 like( $msgs->{req_1}, qr/span/, 'default formatting' );
144150
145151 # testing single constraints and single error case
146 eval{
147 $results = $validator->check($input_hashref, 'default');
148 };
149 is($@,'', 'survived eval');
152 eval { $results = $validator->check( $input_hashref, 'default' ); };
153 is( $@, '', 'survived eval' );
150154 $msgs = $results->msgs;
151155
152 like($msgs->{error_sleep} ,qr/lesser.*Test|Test.*lesser/, 'multiple constraints constraint definition');
153
154 eval{
155 $results = $validator->check($simple_data, 'prefix');
156 };
157 is($@,'','survived eval');
158
159 $msgs = $results->msgs({format => 'Control-Test: %s'});
160
161 ok(defined $msgs->{req_1}, 'using default prefix');
162 is(keys %$msgs, 3, 'size of msgs hash'); # 2 errors plus 1 prefix
163 ok(defined $msgs->{err__}, 'any_errors');
164 like($msgs->{req_1},qr/Control/,'passing controls to method');
156 like( $msgs->{error_sleep}, qr/lesser.*Test|Test.*lesser/,
157 'multiple constraints constraint definition' );
158
159 eval { $results = $validator->check( $simple_data, 'prefix' ); };
160 is( $@, '', 'survived eval' );
161
162 $msgs = $results->msgs( { format => 'Control-Test: %s' } );
163
164 ok( defined $msgs->{req_1}, 'using default prefix' );
165 is( keys %$msgs, 3, 'size of msgs hash' ); # 2 errors plus 1 prefix
166 ok( defined $msgs->{err__}, 'any_errors' );
167 like( $msgs->{req_1}, qr/Control/, 'passing controls to method' );
165168
166169 # See what happens when msgs is called with it does not appeare in the profile
167 my @basic_input = (
168 {
169 field_1 => 'email',
170 },
171 {
172 required => 'field_1',
173
174 });
170 my @basic_input = ( {
171 field_1 => 'email',
172 },
173 {
174 required => 'field_1',
175
176 } );
175177 $results = Data::FormValidator->check(@basic_input);
176178 eval { $results->msgs };
177 ok ((not $@), 'calling msgs method without hash definition');
179 ok( ( not $@ ), 'calling msgs method without hash definition' );
178180
179181 ###
180 {
181 my $test_name = 'Spelling "separator" correctly should work OK.';
182 my $results = Data::FormValidator->check(
183 {
184 field => 'value',
185 },
186 {
187 required => [qw/field/],
188 constraints => {
189 field => ['email','province'],
190 },
191 msgs => {
192 invalid_separator=> ' ## ',
193 },
194 }
195 );
196
197 my $msgs = $results->msgs;
198 like($msgs->{field},qr/##/,$test_name);
182 {
183 my $test_name = 'Spelling "separator" correctly should work OK.';
184 my $results = Data::FormValidator->check( {
185 field => 'value',
186 },
187 {
188 required => [qw/field/],
189 constraints => {
190 field => [ 'email', 'province' ],
191 },
192 msgs => {
193 invalid_separator => ' ## ',
194 },
195 } );
196
197 my $msgs = $results->msgs;
198 like( $msgs->{field}, qr/##/, $test_name );
199199 }
200200
201 ###
201 ###
202202 {
203 my $test_name = 'A callback can be used for msgs';
204 my $results = Data::FormValidator->check(
205 {
206 field => 'value',
207 },
208 {
209 required => [qw/field/],
210 constraints => {
211 field => ['email','province'],
212 },
213 msgs => sub { { field => 'callback!' } },
214 }
215 );
216
217 my $msgs = $results->msgs;
218 like($msgs->{field},qr/callback/,$test_name);
203 my $test_name = 'A callback can be used for msgs';
204 my $results = Data::FormValidator->check( {
205 field => 'value',
206 },
207 {
208 required => [qw/field/],
209 constraints => {
210 field => [ 'email', 'province' ],
211 },
212 msgs => sub { { field => 'callback!' } },
213 } );
214
215 my $msgs = $results->msgs;
216 like( $msgs->{field}, qr/callback/, $test_name );
219217
220218 }
221
222
223
224
225
0
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
13 use Data::FormValidator;
24 use Test::More tests => 8;
3 use strict;
4 use lib ('.','../t');
5 use lib ( '.', '../t' );
56
67 my $input_profile = {
7 required => ['my_zipcode_field'],
8 constraints => {
9 my_zipcode_field => [
10 'zip',
11 {
12 constraint => '/^406/',
13 name => 'starts_with_406',
14 }
15 ],
16 },
8 required => ['my_zipcode_field'],
9 constraints => {
10 my_zipcode_field => [
11 'zip',
12 {
13 constraint => '/^406/',
14 name => 'starts_with_406',
15 }
16 ],
17 },
1718 };
1819
19 my $validator = new Data::FormValidator({default => $input_profile});
20 my $validator = new Data::FormValidator( { default => $input_profile } );
2021
2122 my $input_hashref = {
22 my_zipcode_field => '402015', # born to lose
23 my_zipcode_field => '402015', # born to lose
2324 };
2425
25 my ($valids, $missings, $invalids, $unknowns);
26 my ( $valids, $missings, $invalids, $unknowns );
2627
27 eval{
28 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
28 eval {
29 ( $valids, $missings, $invalids, $unknowns ) =
30 $validator->validate( $input_hashref, 'default' );
2931 };
3032
31 ok(!$@, 'survived eval');
33 ok( !$@, 'survived eval' );
3234
33 ok((grep { (ref $_) eq 'ARRAY' } @$invalids));
34
35 ok( ( grep { ( ref $_ ) eq 'ARRAY' } @$invalids ) );
3536
3637 # Test that the array ref in the invalids array contains three elements,
3738 my @zip_failures;
38 for (@$invalids) {
39 if (ref $_ eq 'ARRAY') {
40 if (scalar @$_ == 3) {
41 @zip_failures = @$_;
42 # This is cheesy, and could be further refactored.
43 ok(1);
44 last;
45 }
46 }
39 for (@$invalids)
40 {
41 if ( ref $_ eq 'ARRAY' )
42 {
43 if ( scalar @$_ == 3 )
44 {
45 @zip_failures = @$_;
46
47 # This is cheesy, and could be further refactored.
48 ok(1);
49 last;
50 }
51 }
4752 }
4853
4954 # Test that the first element of the array is 'my_zipcode_field'
5055 my $t = shift @zip_failures;
5156
52 ok($t eq 'my_zipcode_field');
57 ok( $t eq 'my_zipcode_field' );
5358
5459 # Test that the two elements are 'zip' and 'starts_with_406'
55 ok(eq_set(\@zip_failures, [qw/zip starts_with_406/]));
56
57
60 ok( eq_set( \@zip_failures, [qw/zip starts_with_406/] ) );
5861
5962 # The next three tests are to confirm that an input field is deleted
6063 # from the valids under the following conditions
6467
6568 my %data = (
6669 multiple => 'to fail',
70
6771 #multiple => [qw{this multi-value input will fail on the constraint below}],
68 single => 'to pass',
72 single => 'to pass',
6973 );
7074
7175 my %profile = (
72 required => [qw/
73 multiple
74 single
75 /],
76 required => [
77 qw/
78 multiple
79 single
80 /
81 ],
7682 constraints => {
77 multiple => [
78 { name => 'constraint_1', constraint => qr/\w/ }, # pass
79 { name => 'constraint_2', constraint => qr/\d/ }, # force fail
80 ],
83 multiple => [
84 { name => 'constraint_1', constraint => qr/\w/ }, # pass
85 { name => 'constraint_2', constraint => qr/\d/ }, # force fail
86 ],
8187 },
8288 );
8389
90 my $results = Data::FormValidator->check( \%data, \%profile );
8491
85 my $results = Data::FormValidator->check(\%data, \%profile);
86
87 ok(!$results->valid('multiple'), "expect 'multiple' not to appear in valid");
88 is_deeply($results->invalid('multiple'), ['constraint_2'], "list of failed constraints for 'multiple'");
89 is($results->valid('single'), 'to pass', "single is valid");
92 ok( !$results->valid('multiple'), "expect 'multiple' not to appear in valid" );
93 is_deeply( $results->invalid('multiple'),
94 ['constraint_2'], "list of failed constraints for 'multiple'" );
95 is( $results->valid('single'), 'to pass', "single is valid" );
0 #!/usr/bin/env perl
01 use strict;
2 use warnings;
13 use Test::More;
24 use Data::FormValidator;
3 plan(tests => 5);
5
6 eval { require CGI;CGI->VERSION(4.35); };
7 plan skip_all => 'CGI 4.35 or higher not found' if $@;
48
59 # Test that constrants can refer to fields that are not mentioned
610 # in 'required' or 'optional'
711
812 my $profile = {
9 required => [qw(foo)],
10 optional => [qw(bar)],
11 constraints => {
12 foo => {
13 constraint => sub {
14 if( defined $_[0] && defined $_[1] ) {
15 return $_[0] eq $_[1];
16 } else {
17 return;
18 }
19 },
20 params => [qw(foo baz)],
21 },
13 required => [qw(foo)],
14 optional => [qw(bar)],
15 constraints => {
16 foo => {
17 constraint => sub {
18 if ( defined $_[0] && defined $_[1] )
19 {
20 return $_[0] eq $_[1];
21 }
22 else
23 {
24 return;
25 }
26 },
27 params => [qw(foo baz)],
2228 },
29 },
2330 };
2431 my $input = {
25 foo => 'stuff',
26 bar => 'other stuff',
27 baz => 'stuff',
32 foo => 'stuff',
33 bar => 'other stuff',
34 baz => 'stuff',
2835 };
2936
30 my $results = Data::FormValidator->check($input, $profile);
31 ok(! $results->has_invalid(), 'no_invalids' );
32 ok( $results->valid('foo'), 'foo valid');
37 my $results = Data::FormValidator->check( $input, $profile );
38 ok( !$results->has_invalid(), 'no_invalids' );
39 ok( $results->valid('foo'), 'foo valid' );
3340
3441 {
35 # with CGI object as input.
36 use CGI;
37 my $q = CGI->new($input);
38 my $results;
39 eval { $results = Data::FormValidator->check($q, $profile); };
40 is ($@, '', 'survived eval');
41 ok(! $results->has_invalid(), 'no_invalids' );
42 ok( $results->valid('foo'), 'foo valid');
42 # with CGI object as input.
43 my $q = CGI->new($input);
44 my $results;
45 eval { $results = Data::FormValidator->check( $q, $profile ); };
46 is( $@, '', 'survived eval' );
47 ok( !$results->has_invalid(), 'no_invalids' );
48 ok( $results->valid('foo'), 'foo valid' );
4349
4450 }
4551
52 done_testing;
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More;
4 use File::Spec;
5 use File::Find;
16
27 # Check our Pod
38 # The test was provided by Andy Lester,
49 # who stole it from Brian D. Foy
510 # Thanks to both !
6
7 use File::Spec;
8 use File::Find;
9 use strict;
1011
1112 eval {
1213 require Test::Pod;
1516
1617 my @files;
1718
18 if ($@) {
19 if ($@)
20 {
1921 plan skip_all => "Test::Pod required for testing POD";
2022 }
21 elsif ($Test::Pod::VERSION < 0.95) {
23 elsif ( $Test::Pod::VERSION < 0.95 )
24 {
2225 plan skip_all => "Test::Pod 0.95 required for testing POD";
2326 }
24 else {
27 else
28 {
2529 my $blib = File::Spec->catfile(qw(blib lib));
26 find(\&wanted, $blib, 'lib');
30 find( \&wanted, $blib, 'lib' );
2731 plan tests => scalar @files;
28 foreach my $file (@files) {
32 foreach my $file (@files)
33 {
2934 pod_file_ok($file);
3035 }
3136 }
3237
33 sub wanted {
38 sub wanted
39 {
3440 push @files, $File::Find::name if /\.p(l|m|od)$/;
3541 }
0 #!/usr/bin/env perl
01 use strict;
1 #Check that the valid_* routines are nominally working.
2
3 $^W = 1;
4
2 use warnings;
53 use Test::More qw/no_plan/;
6
74 use Data::FormValidator qw(:validators :matchers);
85
9
10
6 #Check that the valid_* routines are nominally working.
117 my $invalid = "fake value";
128
139 #For CC Exp test
1410 my @time = localtime(time);
1511
16 my %tests = (
17 valid_american_phone => "555-555-5555",
18 valid_cc_exp => "10/" . sprintf("%.2d", ($time[5] - 99)),
19 valid_cc_type => "MasterCard",
20 valid_email => 'foo@domain.com',
21 valid_ip_address => "64.58.79.230",
22 valid_phone => "123-456-7890",
23 valid_postcode => "T2N 0E6",
24 valid_province => "NB",
25 valid_state => "CA",
26 valid_state_or_province => "QC",
27 valid_zip => "94112",
28 valid_zip_or_postcode => "50112",
12 my %tests = (
13 valid_american_phone => "555-555-5555",
14 valid_cc_exp => "10/" . sprintf( "%.2d", ( $time[5] - 99 ) ),
15 valid_cc_type => "MasterCard",
16 valid_email => 'foo@domain.com',
17 valid_ip_address => "64.58.79.230",
18 valid_phone => "123-456-7890",
19 valid_postcode => "T2N 0E6",
20 valid_province => "NB",
21 valid_state => "CA",
22 valid_state_or_province => "QC",
23 valid_zip => "94112",
24 valid_zip_or_postcode => "50112",
2925 );
3026
3127 my $i = 1;
3228
33 foreach my $function (keys(%tests)) {
34 my $rv;
35 my $val = $tests{$function};
36 my $is_valid = "\$rv = $function('$val');";
37 my $not_valid = "\$rv = $function('$invalid');";
38
39 eval $is_valid;
40 ok(not $@ and $rv == 1) or
41 diag $@;
42 #diag sprintf("%-25s using %-16s", $function, "(valid value)");
43 $i++;
29 foreach my $function ( keys(%tests) )
30 {
31 my $rv;
32 my $val = $tests{$function};
33 my $is_valid = "\$rv = $function('$val');";
34 my $not_valid = "\$rv = $function('$invalid');";
4435
45 eval $not_valid;
46 ok(not $@ and not $rv) or
47 diag sprintf("%-25s using %-16s", $function, "(invalid value)");
48 $i++;
36 eval $is_valid;
37 ok( not $@ and $rv == 1 )
38 or diag $@;
39
40 #diag sprintf("%-25s using %-16s", $function, "(valid value)");
41 $i++;
42
43 eval $not_valid;
44 ok( not $@ and not $rv )
45 or diag sprintf( "%-25s using %-16s", $function, "(invalid value)" );
46 $i++;
4947 }
50
48
5149 #Test cc_number separately since it takes multiple parameters
5250 {
53 my $rv;
54 my $num = '4111111111111111';
51 my $rv;
52 my $num = '4111111111111111';
5553
56 eval "\$rv = match_cc_number('$num', 'v')";
57 ok(not $@ and ($rv eq $num)) or
58 diag sprintf("%-25s using %-16s", "match_cc_number", "valid value. ");
54 eval "\$rv = match_cc_number('$num', 'v')";
55 ok( not $@ and ( $rv eq $num ) )
56 or diag sprintf( "%-25s using %-16s", "match_cc_number", "valid value. " );
5957
60 eval "\$rv = valid_cc_number('$invalid', 'm')";
61 ok(not $@ and not $rv) or
62 diag sprintf("%-25s using %-16s", "valid_cc_number", "(invalid value)");
58 eval "\$rv = valid_cc_number('$invalid', 'm')";
59 ok( not $@ and not $rv )
60 or diag sprintf
61 ( "%-25s using %-16s", "valid_cc_number", "(invalid value)" );
6362 }
6463
6564 $i++;
6766
6867 #Test fake validation routine
6968 {
70 my $rv;
71 eval "\$rv = valid_foobar('$invalid', 'm')";
69 my $rv;
70 eval "\$rv = valid_foobar('$invalid', 'm')";
7271
73 ok($@) or
74 diag sprintf("%-25s", "Fake Valid Routine");
72 ok($@)
73 or diag sprintf( "%-25s", "Fake Valid Routine" );
7574 }
7675
77 ok(! valid_email('pretty_b;ue_eyes16@cpan.org'), 'semi-colons in e-mail aren\'t valid');
78 ok(! valid_email('Ollie 102@cpan.org'), 'spaces in e-mail aren\'t valid');
76 ok(
77 !valid_email('pretty_b;ue_eyes16@cpan.org'),
78 'semi-colons in e-mail aren\'t valid'
79 );
80 ok( !valid_email('Ollie 102@cpan.org'), 'spaces in e-mail aren\'t valid' );
7981
80 ok(! valid_email('mark@summersualt.com\0mark@summersault.com'), "including a null in an e-mail is not valid.");
81
82 ok(
83 !valid_email('mark@summersualt.com\0mark@summersault.com'),
84 "including a null in an e-mail is not valid."
85 );
8286
8387 my $address_1 = 'mark';
84 isnt($address_1, valid_email($address_1), "'$address_1' is not a valid e-mail");
88 isnt( $address_1, valid_email($address_1),
89 "'$address_1' is not a valid e-mail" );
8590
8691 my $address_2 = 'Mark Stosberg <mark@summersault.com>';
87 ok(! valid_email($address_2), "'$address_2' is not a valid e-mail");
92 ok( !valid_email($address_2), "'$address_2' is not a valid e-mail" );
8893
8994 my $address_3 = 'mark@summersault.com';
90 ok(valid_email($address_3), "'$address_3' is a valid e-mail");
95 ok( valid_email($address_3), "'$address_3' is a valid e-mail" );
9196
9297 my $address_6 = 'Mark.Stosberg@summersault.com';
93 ok(valid_email($address_6), "'$address_6' is a valid e-mail");
98 ok( valid_email($address_6), "'$address_6' is a valid e-mail" );
9499
95100 my $address_7 = 'Mark_Stosberg@summersault.com';
96 ok(valid_email($address_7), "'$address_7' is a valid e-mail");
101 ok( valid_email($address_7), "'$address_7' is a valid e-mail" );
97102
98103 my $addr_8 = "Mark_O'Doul\@summersault.com";
99 ok(valid_email($addr_8), "'$addr_8' is a valid e-mail");
100
101
102
103
104
105
106
104 ok( valid_email($addr_8), "'$addr_8' is a valid e-mail" );
0
0 #!/usr/bin/env perl
11 use strict;
2
3 $^W = 1;
4
2 use warnings;
53 use Test::More tests => 1;
6
74 use Data::FormValidator;
85
96 my $input_profile = {
10 required => [ qw( email_1 email_ok) ],
11 optional => ['filled','not_filled'],
12 constraint_regexp_map => {
13 '/^email/' => "email",
14 },
15 constraints => {
16 not_filled => 'phone',
17 },
18 missing_optional_valid => 1,
19 bad_key_which_should_trigger_error=>1,
20 another_bad_key_which_should_trigger_error=>1,
21 };
7 required => [qw( email_1 email_ok)],
8 optional => [ 'filled', 'not_filled' ],
9 constraint_regexp_map => {
10 '/^email/' => "email",
11 },
12 constraints => {
13 not_filled => 'phone',
14 },
15 missing_optional_valid => 1,
16 bad_key_which_should_trigger_error => 1,
17 another_bad_key_which_should_trigger_error => 1,
18 };
2219
23 my $validator = new Data::FormValidator({default => $input_profile});
20 my $validator = new Data::FormValidator( { default => $input_profile } );
2421
2522 my $input_hashref = {
26 email_1 => 'invalidemail',
27 email_ok => 'mark@stosberg.com',
28 filled => 'dog',
29 not_filled => '',
30 should_be_unknown => 1,
23 email_1 => 'invalidemail',
24 email_ok => 'mark@stosberg.com',
25 filled => 'dog',
26 not_filled => '',
27 should_be_unknown => 1,
3128 };
3229
33 my ($valids, $missings, $invalids, $unknowns);
30 my ( $valids, $missings, $invalids, $unknowns );
3431
35 eval{
36 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
32 eval {
33 ( $valids, $missings, $invalids, $unknowns ) =
34 $validator->validate( $input_hashref, 'default' );
3735 };
3836
39 ok(not $@
40 or
41 $@ =~ qr/\QInvalid input profile: keys not recognised [bad_key_which_should_trigger_error, another_bad_key_which_should_trigger_error]/
42 or
43 $@ =~ qr/\QInvalid input profile: keys not recognised [another_bad_key_which_should_trigger_error, bad_key_which_should_trigger_error]/
44 ) || warn $@;
37 ok(
38 not $@
39 or $@ =~
40 qr/\QInvalid input profile: keys not recognised [bad_key_which_should_trigger_error, another_bad_key_which_should_trigger_error]/
41 or $@ =~
42 qr/\QInvalid input profile: keys not recognised [another_bad_key_which_should_trigger_error, bad_key_which_should_trigger_error]/
43 ) || warn $@;
4544
46
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More tests => 10;
4 use Data::FormValidator;
5
06 # Integration with Regexp::Common;
1
2 use Test::More tests => 10;
3
4 use Data::FormValidator;
5
67 my %FORM = (
7 bad_ip => '127 0 0 1',
8 good_ip => '127.0.0.1',
9 embedded_ip => 'The address is 127.0.0.1 or something close to that',
8 bad_ip => '127 0 0 1',
9 good_ip => '127.0.0.1',
10 embedded_ip => 'The address is 127.0.0.1 or something close to that',
1011 );
1112
1213 my $results;
1314
1415 eval {
15 $results = Data::FormValidator->check(\%FORM, {
16 required => [qw/good_ip bad_ip/],
17 constraint_regexp_map => {
18 qr/_ip$/ => 'RE_net_IPv4',
16 $results = Data::FormValidator->check(
17 \%FORM,
18 {
19 required => [qw/good_ip bad_ip/],
20 constraint_regexp_map => {
21 qr/_ip$/ => 'RE_net_IPv4',
1922
20 }
21 });
23 } } );
2224 };
23 ok((not $@), 'runtime errors') or diag $@;
24 ok($results->valid->{good_ip}, 'good ip');
25 ok($results->invalid->{bad_ip}, 'bad ip');
25 ok( ( not $@ ), 'runtime errors' ) or diag $@;
26 ok( $results->valid->{good_ip}, 'good ip' );
27 ok( $results->invalid->{bad_ip}, 'bad ip' );
2628
29 $results = Data::FormValidator->check(
30 \%FORM,
31 {
32 untaint_all_constraints => 1,
33 required => [qw/good_ip bad_ip/],
34 constraint_regexp_map => {
35 qr/_ip$/ => 'RE_net_IPv4',
2736
28 $results = Data::FormValidator->check(\%FORM, {
29 untaint_all_constraints => 1,
30 required => [qw/good_ip bad_ip/],
31 constraint_regexp_map => {
32 qr/_ip$/ => 'RE_net_IPv4',
37 } } );
3338
34 }
35 });
36
37
38 ok((not $@), 'runtime errors') or diag $@;
39 ok($results->valid->{good_ip}, 'good ip with tainting');
40 ok($results->invalid->{bad_ip}, 'bad ip with tainting');
39 ok( ( not $@ ), 'runtime errors' ) or diag $@;
40 ok( $results->valid->{good_ip}, 'good ip with tainting' );
41 ok( $results->invalid->{bad_ip}, 'bad ip with tainting' );
4142
4243 # Test passing flags
43 $results = Data::FormValidator->check(\%FORM, {
44 required => [qw/good_ip bad_ip/],
45 constraint_regexp_map => {
46 qr/_ip$/ => {
47 constraint => 'RE_net_IPv4_dec',
48 params => [ \'-sep'=> \' ' ],
49 }
50 }
51 });
44 $results = Data::FormValidator->check(
45 \%FORM,
46 {
47 required => [qw/good_ip bad_ip/],
48 constraint_regexp_map => {
49 qr/_ip$/ => {
50 constraint => 'RE_net_IPv4_dec',
51 params => [ \'-sep' => \' ' ],
52 } } } );
5253
54 ok( ( not $@ ), 'runtime errors' ) or diag $@;
5355
54 ok((not $@), 'runtime errors') or diag $@;
5556 # Here we are trying passing a parameter which should reverse
5657 # the notion of which one expect to succeed.
57 ok($results->valid->{bad_ip}, 'expecting success with params');
58 ok($results->invalid->{good_ip}, 'expecting failure with params');
59
58 ok( $results->valid->{bad_ip}, 'expecting success with params' );
59 ok( $results->invalid->{good_ip}, 'expecting failure with params' );
6060
6161 # Testing end-to-end matching
62 $results = Data::FormValidator->check(\%FORM, {
63 required => [qw/embedded_ip/],
64 constraint_regexp_map => {
65 qr/_ip$/ => 'RE_net_IPv4',
66 }
67 });
62 $results = Data::FormValidator->check(
63 \%FORM,
64 {
65 required => [qw/embedded_ip/],
66 constraint_regexp_map => {
67 qr/_ip$/ => 'RE_net_IPv4',
68 } } );
6869 my $invalid = scalar $results->invalid || {};
69 ok($invalid->{embedded_ip}, 'testing that the RE must match from end-to-end');
70
70 ok( $invalid->{embedded_ip}, 'testing that the RE must match from end-to-end' );
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More tests => 13;
4 use Data::FormValidator;
5
06 # Integration with Regexp::Common;
17
2 use Test::More tests => 13;
3
4 use Data::FormValidator;
5
68 my %FORM = (
7 bad_ip => '127 0 0 1',
8 good_ip => '127.0.0.1',
9 embedded_ip => 'The address is 127.0.0.1 or something close to that',
10 valid_int => 0,
9 bad_ip => '127 0 0 1',
10 good_ip => '127.0.0.1',
11 embedded_ip => 'The address is 127.0.0.1 or something close to that',
12 valid_int => 0,
1113 );
1214
1315 my $results;
1416
15 BEGIN { use_ok('Data::FormValidator::Constraints', qw/:regexp_common/) }
17 BEGIN { use_ok( 'Data::FormValidator::Constraints', qw/:regexp_common/ ) }
1618
1719 eval {
18 $results = Data::FormValidator->check(\%FORM, {
19 required => [qw/good_ip bad_ip valid_int/],
20 constraint_method_regexp_map => {
21 qr/_ip$/ => FV_net_IPv4(),
22 },
23 constraint_methods => {
24 valid_int => FV_num_int(),
25 }
26 });
20 $results = Data::FormValidator->check(
21 \%FORM,
22 {
23 required => [qw/good_ip bad_ip valid_int/],
24 constraint_method_regexp_map => {
25 qr/_ip$/ => FV_net_IPv4(),
26 },
27 constraint_methods => {
28 valid_int => FV_num_int(),
29 } } );
2730 };
28 is($@,'', 'survived eval');
29 ok($results->valid->{good_ip}, 'good ip');
30 ok($results->invalid->{bad_ip}, 'bad ip');
31 is($results->valid->{valid_int},0, 'zero is valid int');
31 is( $@, '', 'survived eval' );
32 ok( $results->valid->{good_ip}, 'good ip' );
33 ok( $results->invalid->{bad_ip}, 'bad ip' );
34 is( $results->valid->{valid_int}, 0, 'zero is valid int' );
3235
36 $results = Data::FormValidator->check(
37 \%FORM,
38 {
39 untaint_all_constraints => 1,
40 required => [qw/good_ip bad_ip valid_int/],
41 constraint_method_regexp_map => {
42 qr/_ip$/ => FV_net_IPv4(),
43 },
44 constraint_methods => {
45 valid_int => FV_num_int(),
46 } } );
3347
34 $results = Data::FormValidator->check(\%FORM, {
35 untaint_all_constraints => 1,
36 required => [qw/good_ip bad_ip valid_int/],
37 constraint_method_regexp_map => {
38 qr/_ip$/ => FV_net_IPv4(),
39 },
40 constraint_methods => {
41 valid_int => FV_num_int(),
42 }
43 });
44
45
46 is($@,'', 'survived eval');
47 ok($results->valid->{good_ip}, 'good ip with tainting');
48 ok($results->invalid->{bad_ip}, 'bad ip with tainting');
49 is($results->valid->{valid_int},0, 'zero is valid int with untainting');
48 is( $@, '', 'survived eval' );
49 ok( $results->valid->{good_ip}, 'good ip with tainting' );
50 ok( $results->invalid->{bad_ip}, 'bad ip with tainting' );
51 is( $results->valid->{valid_int}, 0, 'zero is valid int with untainting' );
5052
5153 # Test passing flags
52 $results = Data::FormValidator->check(\%FORM, {
53 required => [qw/good_ip bad_ip/],
54 constraint_method_regexp_map => {
55 qr/_ip$/ => FV_net_IPv4_dec(-sep => ' '),
56 }
57 });
54 $results = Data::FormValidator->check(
55 \%FORM,
56 {
57 required => [qw/good_ip bad_ip/],
58 constraint_method_regexp_map => {
59 qr/_ip$/ => FV_net_IPv4_dec( -sep => ' ' ),
60 } } );
5861
62 ok( ( not $@ ), 'runtime errors' ) or diag $@;
5963
60 ok((not $@), 'runtime errors') or diag $@;
6164 # Here we are trying passing a parameter which should reverse
6265 # the notion of which one expect to succeed.
63 ok($results->valid->{bad_ip}, 'expecting success with params');
64 ok($results->invalid->{good_ip}, 'expecting failure with params');
65
66 ok( $results->valid->{bad_ip}, 'expecting success with params' );
67 ok( $results->invalid->{good_ip}, 'expecting failure with params' );
6668
6769 # Testing end-to-end matching
68 $results = Data::FormValidator->check(\%FORM, {
69 required => [qw/embedded_ip/],
70 constraint_method_regexp_map => {
71 qr/_ip$/ => FV_net_IPv4(),
72 }
73 });
70 $results = Data::FormValidator->check(
71 \%FORM,
72 {
73 required => [qw/embedded_ip/],
74 constraint_method_regexp_map => {
75 qr/_ip$/ => FV_net_IPv4(),
76 } } );
7477 my $invalid = scalar $results->invalid || {};
75 ok($invalid->{embedded_ip}, 'testing that the RE must match from end-to-end');
76
78 ok( $invalid->{embedded_ip}, 'testing that the RE must match from end-to-end' );
0 #!perl
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
13 use Test::More 'no_plan';
2
34 use Data::FormValidator;
4 use Data::FormValidator::Constraints qw(
5 FV_max_length
5 use Data::FormValidator::Constraints qw(
6 FV_max_length
67 );
78
8 my $result = Data::FormValidator->check({
9 first_names => 'Too long',
9 my $result = Data::FormValidator->check( {
10 first_names => 'Too long',
11 },
12 {
13 required => [qw/first_names/],
14 constraint_methods => {
15 first_names => {
16 constraint_method => FV_max_length(3),
17 name => 'custom_length',
18 }
1019 },
11 {
12 required => [qw/first_names/],
13 constraint_methods => {
14 first_names => {
15 constraint_method => FV_max_length(3),
16 name => 'custom_length',
17 }
18 },
19 msgs => {
20 constraints => {
21 custom_length => 'Custom length msg',
22 }
23 },
24 });
20 msgs => {
21 constraints => {
22 custom_length => 'Custom length msg',
23 }
24 },
25 } );
2526
26 like( $result->msgs->{'first_names'}, qr/Custom length msg/, "built-ins can have custom names" );
27
28
27 like(
28 $result->msgs->{'first_names'},
29 qr/Custom length msg/,
30 "built-ins can have custom names"
31 );
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More tests => 4;
14 use Data::FormValidator;
25
36 my %FORM = (
4 good => '1',
5 extra => '2',
7 good => '1',
8 extra => '2',
69 );
710
8 my $results = Data::FormValidator->check(\%FORM,
9 {
10 required => 'good',
11 }
12 );
11 my $results = Data::FormValidator->check(
12 \%FORM,
13 {
14 required => 'good',
15 } );
1316
14 ok($results->success, 'success with unknown');
17 ok( $results->success, 'success with unknown' );
1518
1619 {
17 my $false;
18 $results || ($false = 1);
19 ok(!$false, "returns true in bool context on success");
20 my $false;
21 $results || ( $false = 1 );
22 ok( !$false, "returns true in bool context on success" );
2023 }
2124
2225 # test an unsuccessful success
2326 $FORM{bad} = -1;
2427 $results = Data::FormValidator->check(
25 \%FORM,
26 {
27 required => [qw(good bad)],
28 optional => [qw(extra)],
29 constraints => {
30 good => sub { return shift > 0 },
31 bad => sub { return shift > 0 },
32 },
28 \%FORM,
29 {
30 required => [qw(good bad)],
31 optional => [qw(extra)],
32 constraints => {
33 good => sub { return shift > 0 },
34 bad => sub { return shift > 0 },
3335 },
36 },
3437 );
3538
36 ok(!$results->success, 'not success()');
39 ok( !$results->success, 'not success()' );
3740
3841 {
39 my $false;
40 $results || ($false = 1);
41 ok($false, "returns false in bool context on not success");
42 my $false;
43 $results || ( $false = 1 );
44 ok( $false, "returns false in bool context on not success" );
4245 }
43
0
0 #!/usr/bin/env perl
11 use strict;
2
3 $^W = 1;
4
2 use warnings;
53 use Test::More tests => 3;
6
74 use Data::FormValidator;
85
96 my $input_profile = {
10 required => [ qw( email phone likes ) ],
11 optional => [ qq( toppings ) ],
12 constraints => {
13 email => "email",
14 phone => "phone",
15 }
16 };
7 required => [qw( email phone likes )],
8 optional => [qq( toppings )],
9 constraints => {
10 email => "email",
11 phone => "phone",
12 } };
1713
18 my $validator = new Data::FormValidator({default => $input_profile});
14 my $validator = new Data::FormValidator( { default => $input_profile } );
1915
20 my $input_hashref = {email => 'invalidemail',
21 phone => '201-999-9999',
22 likes => ['a','b'],
23 toppings => 'foo'};
16 my $input_hashref = {
17 email => 'invalidemail',
18 phone => '201-999-9999',
19 likes => [ 'a', 'b' ],
20 toppings => 'foo'
21 };
2422
25 my ($valids, $missings, $invalids, $unknowns) = ({},[],[],[]);
23 my ( $valids, $missings, $invalids, $unknowns ) = ( {}, [], [], [] );
2624
27 eval{
28 ($valids, $missings, $invalids, $unknowns) = $validator->validate($input_hashref, 'default');
25 eval {
26 ( $valids, $missings, $invalids, $unknowns ) =
27 $validator->validate( $input_hashref, 'default' );
2928 };
30 is($@,'', 'survived eval');
29 is( $@, '', 'survived eval' );
3130
32 ok(exists $valids->{'phone'}, "phone is valid" );
31 ok( exists $valids->{'phone'}, "phone is valid" );
3332
34 is($invalids->[0], 'email')
35
36
33 is( $invalids->[0], 'email' )
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More;
14 use Data::FormValidator;
25
3 eval { require Template; require Template::Stash; };
6 eval { require Template; require Template::Stash; };
47 plan skip_all => 'Template Toolkit required' if $@;
58 plan tests => 1;
69
7 my $results = Data::FormValidator->check( {}, {required => 1} );
10 my $results = Data::FormValidator->check( {}, { required => 1 } );
811
912 my $tt = Template->new( STASH => Template::Stash->new );
1013
11 $tt->process( \'[% form.missing %]', {form => $results}, \my $out );
14 $tt->process( \'[% form.missing %]', { form => $results }, \my $out );
1215
13 ok(not $tt->error);
14
16 ok( not $tt->error );
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More tests => 1;
14 use Data::FormValidator;
2 use strict;
35
4 my ( $valid, $missing, $invalid, $unknown ) = Data::FormValidator->validate({}, {} );
5 ok( (ref $invalid eq 'ARRAY'), "no invalid fields are returned as an arrayref");
6
6 my ( $valid, $missing, $invalid, $unknown ) =
7 Data::FormValidator->validate( {}, {} );
8 ok( ( ref $invalid eq 'ARRAY' ),
9 "no invalid fields are returned as an arrayref" );
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
03 use Test::More tests => 4;
1
2 use Data::FormValidator;
4 use Data::FormValidator;
35
46 my %FORM = (
5 stick => 'big',
6 speak => 'softly',
7 mv => ['first','second'],
7 stick => 'big',
8 speak => 'softly',
9 mv => [ 'first', 'second' ],
810 );
911
10 my $results = Data::FormValidator->check(\%FORM,
11 {
12 # required => 'stick',
13 # optional => 'mv',
12 my $results = Data::FormValidator->check(
13 \%FORM,
14 {
15 # required => 'stick',
16 # optional => 'mv',
1417
15 }
16 );
18 } );
1719
18 ok($results->unknown('stick') eq 'big','using check() as class method');
20 ok( $results->unknown('stick') eq 'big', 'using check() as class method' );
1921
20 is($results->unknown('stick'),$FORM{stick}, 'unknown() returns single value in scalar context');
22 is( $results->unknown('stick'),
23 $FORM{stick}, 'unknown() returns single value in scalar context' );
2124
2225 my @mv = $results->unknown('mv');
23 is_deeply(\@mv,$FORM{mv}, 'unknown() returns multi-valued results');
26 is_deeply( \@mv, $FORM{mv}, 'unknown() returns multi-valued results' );
2427
2528 my @stick = $results->unknown('stick');
26 is_deeply(\@stick,[ $FORM{stick} ], 'unknown() returns single value in list context');
27
29 is_deeply(
30 \@stick,
31 [ $FORM{stick} ],
32 'unknown() returns single value in list context'
33 );
0 #!/usr/bin/perl -wT
1
0 #!/usr/bin/env perl -wT
21 use strict;
3
42 use Test::More (tests => 55);
53 use Data::FormValidator;
64 use Data::FormValidator::Constraints qw/
75 :closures
86 FV_max_length
97 /;
10
11 # A gift from Andy Lester, this trick shows me where eval's die.
8 use Scalar::Util 'tainted';
9
10 # A gift from Andy Lester, this trick shows me where eval's die.
1211 use Carp;
1312 $SIG{__WARN__} = \&carp;
1413 $SIG{__DIE__} = \&confess;
1514
1615 $ENV{PATH} = "/bin/";
17
18 sub is_tainted {
19 my $val = shift;
20 # What does kill do here? -mls
21 return !eval { $val++, kill 0; 1; };
22 }
2316
2417 my $data1 = {
2518 firstname => $ARGV[0], #Jim
147140
148141 is($@,'','avoided eval error');
149142 ok($valid->{firstname}, 'found firstname');
150 ok(! is_tainted($valid->{firstname}), 'firstname is untainted');
143 ok(! tainted($valid->{firstname}), 'firstname is untainted');
151144 is($valid->{firstname},$data1->{firstname}, 'firstname has expected value');
152145
153146
158151
159152 is($@,'','avoided eval error');
160153 ok($valid->{lastname});
161 ok(!is_tainted($valid->{lastname}));
154 ok(!tainted($valid->{lastname}));
162155 is($valid->{lastname},$data2->{lastname});
163156
164157 ok($valid->{email1});
165 ok(!is_tainted($valid->{email1}));
158 ok(!tainted($valid->{email1}));
166159 is($valid->{email1},$data2->{email1});
167160
168161 ok($valid->{email2});
169 ok(is_tainted($valid->{email2}), 'email2 is tainted');
162 ok(tainted($valid->{email2}), 'email2 is tainted');
170163 is($valid->{email2},$data2->{email2});
171164
172165 # Rules2 with closures
177170 $valid = $result->valid();
178171
179172 ok($valid->{email1}, "found email1 in \%valid") || warn Dumper ($data2,$result);
180 ok(!is_tainted($valid->{email1}), "email one is not tainted");
173 ok(!tainted($valid->{email1}), "email one is not tainted");
181174 is($valid->{email1},$data2->{email1}, "email1 identity");
182175 }
183176
188181 ok(!$@);
189182
190183 ok($valid->{ip_address});
191 ok(!is_tainted($valid->{ip_address}));
184 ok(!tainted($valid->{ip_address}));
192185 is($valid->{ip_address},$data3->{ip_address});
193186
194187 #in this case we're expecting no match
196189 is($invalid->[0], 'cats_name', 'cats_name fails constraint');
197190
198191 ok($valid->{dogs_name});
199 ok(!is_tainted($valid->{dogs_name}));
192 ok(!tainted($valid->{dogs_name}));
200193 is($valid->{dogs_name},$data3->{dogs_name});
201194
202195 # Rules # 4
203196 eval { ( $valid, $missing, $invalid, $unknown ) = $validator->validate( $data4, "rules4"); };
204197 ok(!$@, 'avoided eval error');
205198
206 ok(!is_tainted($valid->{zip_field1}->[0]),
199 ok(!tainted($valid->{zip_field1}->[0]),
207200 'zip_field1 should be untainted');
208201
209 ok(is_tainted($valid->{zip_field2}->[0]),
202 ok(tainted($valid->{zip_field2}->[0]),
210203 'zip_field2 should be tainted');
211204
212205
232225 eval { ( $valid, $missing, $invalid, $unknown ) = $validator->validate( $data5, "rules5"); };
233226 ok(!$@, 'avoided eval error');
234227 ok($valid->{zip_field1}, "zip_field1 should be valid");
235 ok(!is_tainted($valid->{zip_field1}->[0]), 'zip_field1 should be untainted');
228 ok(!tainted($valid->{zip_field1}->[0]), 'zip_field1 should be untainted');
236229 ok($valid->{zip_field2}, "zip_field2 should be valid");
237 ok(!is_tainted($valid->{zip_field2}->[0]), 'zip_field2 should be untainted');
230 ok(!tainted($valid->{zip_field2}->[0]), 'zip_field2 should be untainted');
238231
239232 # Rules #6
240233 eval { ( $valid, $missing, $invalid, $unknown ) = $validator->validate( $data6, "rules6"); };
241234 ok(!$@, 'avoided eval error');
242235 ok($valid->{zip_field1}, "zip_field1 should be valid");
243 ok(!is_tainted($valid->{zip_field1}->[0]), 'zip_field1 should be untainted');
236 ok(!tainted($valid->{zip_field1}->[0]), 'zip_field1 should be untainted');
244237 ok($valid->{zip_field2}, "zip_field2 should be valid");
245 ok(!is_tainted($valid->{zip_field2}->[0]), 'zip_field2 should be untainted');
238 ok(!tainted($valid->{zip_field2}->[0]), 'zip_field2 should be untainted');
246239 ok($valid->{email1}, "email1 should be valid");
247 ok(!is_tainted($valid->{email1}), 'email1 should be untainted');
240 ok(!tainted($valid->{email1}), 'email1 should be untainted');
248241 ok($valid->{email2}, "email2 should be valid");
249 ok(!is_tainted($valid->{email2}), 'email2 should be untainted');
242 ok(!tainted($valid->{email2}), 'email2 should be untainted');
250243
251244 # Rules #7
252245 eval { ( $valid, $missing, $invalid, $unknown ) = $validator->validate( $data7, "rules7"); };
253246 ok(!$@, 'avoided eval error');
254247 ok($valid->{zip_field1}, "zip_field1 should be valid");
255 ok(!is_tainted($valid->{zip_field1}->[0]), 'zip_field1 should be untainted');
248 ok(!tainted($valid->{zip_field1}->[0]), 'zip_field1 should be untainted');
256249 ok($valid->{zip_field2}, "zip_field2 should be valid");
257 ok(!is_tainted($valid->{zip_field2}->[0]), 'zip_field2 should be untainted');
250 ok(!tainted($valid->{zip_field2}->[0]), 'zip_field2 should be untainted');
258251 ok($valid->{email1}, "email1 should be valid");
259 ok(!is_tainted($valid->{email1}), 'email1 should be untainted');
252 ok(!tainted($valid->{email1}), 'email1 should be untainted');
260253 ok($valid->{email2}, "email2 should be valid");
261 ok(!is_tainted($valid->{email2}), 'email2 should be untainted');
254 ok(!tainted($valid->{email2}), 'email2 should be untainted');
0 # A gift from Andy Lester, this trick shows me where eval's die.
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
13 use Carp;
4 use Config;
25 $SIG{__WARN__} = \&carp;
3 $SIG{__DIE__} = \&confess;
6 $SIG{__DIE__} = \&confess;
47
5 use Config;
6
7 my @args = ('-I./lib',
8 ( (defined($ENV{PERL5LIB}) && length($ENV{PERL5LIB}))
9 ?(map { "-I$_" } split(/$Config{path_sep}/, $ENV{PERL5LIB}))
10 : ()
11 ),
12 '-T',
13 './t/untaint.pl',
14 qw(Jim Beam jim@foo.bar james@bar.foo 132.10.10.2 Monroe Rufus 12345 oops 0)
8 # A gift from Andy Lester, this trick shows me where eval's die.
9 my @args = (
10 '-I./lib',
11 (
12 ( defined( $ENV{PERL5LIB} ) && length( $ENV{PERL5LIB} ) )
13 ? ( map { "-I$_" } split( /$Config{path_sep}/, $ENV{PERL5LIB} ) )
14 : ()
15 ),
16 '-T',
17 './t/untaint.pl',
18 qw(Jim Beam jim@foo.bar james@bar.foo 132.10.10.2 Monroe Rufus 12345 oops 0)
1519 );
1620
17 # We use $^X to make it easier to test with different versions of Perl.
18 system($^X, @args);
21 # We use $^X to make it easier to test with different versions of Perl.
22 system( $^X, @args );
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More;
4
5 BEGIN
6 {
7 eval { require CGI;CGI->VERSION(4.35); };
8 plan skip_all => 'CGI 4.35 or higher not found' if $@;
9 use_ok('CGI');
10 use_ok('Data::FormValidator::Constraints::Upload');
11 }
12
13 my $cgi_simple_test = 0;
14
15 eval { require CGI::Simple; };
16
17 if ($@)
18 {
19 diag "Skipping CGI::Simple Tests";
20 }
21 else
22 {
23 diag "Adding CGI::Simple tests";
24 $cgi_simple_test = 1;
25 }
26
027 #########################
128
2 use Test::More 'no_plan';
3 use strict;
4
5 BEGIN {
6 use_ok('CGI');
7 use_ok('Data::FormValidator::Constraints::Upload')
8 };
9
10 my $cgi_simple_test = 0;
11
12 eval {
13 require CGI::Simple;
14 };
15
16 if ($@) {
17 diag "Skipping CGI::Simple Tests";
18 }
19 else {
20 diag "Adding CGI::Simple tests";
21 $cgi_simple_test = 1;
22 }
23
24 #########################
25
2629 %ENV = (
27 %ENV,
28 'SCRIPT_NAME' => '/test.cgi',
29 'SERVER_NAME' => 'perl.org',
30 'HTTP_CONNECTION' => 'TE, close',
31 'REQUEST_METHOD' => 'POST',
32 'SCRIPT_URI' => 'http://www.perl.org/test.cgi',
33 'CONTENT_LENGTH' => 3129,
34 'SCRIPT_FILENAME' => '/home/usr/test.cgi',
35 'SERVER_SOFTWARE' => 'Apache/1.3.27 (Unix) ',
36 'HTTP_TE' => 'deflate,gzip;q=0.3',
37 'QUERY_STRING' => '',
38 'REMOTE_PORT' => '1855',
39 'HTTP_USER_AGENT' => 'Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)',
40 'SERVER_PORT' => '80',
41 'REMOTE_ADDR' => '127.0.0.1',
42 'CONTENT_TYPE' => 'multipart/form-data; boundary=xYzZY',
43 'SERVER_PROTOCOL' => 'HTTP/1.1',
44 'PATH' => '/usr/local/bin:/usr/bin:/bin',
45 'REQUEST_URI' => '/test.cgi',
46 'GATEWAY_INTERFACE' => 'CGI/1.1',
47 'SCRIPT_URL' => '/test.cgi',
48 'SERVER_ADDR' => '127.0.0.1',
49 'DOCUMENT_ROOT' => '/home/develop',
50 'HTTP_HOST' => 'www.perl.org'
30 %ENV,
31 'SCRIPT_NAME' => '/test.cgi',
32 'SERVER_NAME' => 'perl.org',
33 'HTTP_CONNECTION' => 'TE, close',
34 'REQUEST_METHOD' => 'POST',
35 'SCRIPT_URI' => 'http://www.perl.org/test.cgi',
36 'CONTENT_LENGTH' => 3129,
37 'SCRIPT_FILENAME' => '/home/usr/test.cgi',
38 'SERVER_SOFTWARE' => 'Apache/1.3.27 (Unix) ',
39 'HTTP_TE' => 'deflate,gzip;q=0.3',
40 'QUERY_STRING' => '',
41 'REMOTE_PORT' => '1855',
42 'HTTP_USER_AGENT' => 'Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)',
43 'SERVER_PORT' => '80',
44 'REMOTE_ADDR' => '127.0.0.1',
45 'CONTENT_TYPE' => 'multipart/form-data; boundary=xYzZY',
46 'SERVER_PROTOCOL' => 'HTTP/1.1',
47 'PATH' => '/usr/local/bin:/usr/bin:/bin',
48 'REQUEST_URI' => '/test.cgi',
49 'GATEWAY_INTERFACE' => 'CGI/1.1',
50 'SCRIPT_URL' => '/test.cgi',
51 'SERVER_ADDR' => '127.0.0.1',
52 'DOCUMENT_ROOT' => '/home/develop',
53 'HTTP_HOST' => 'www.perl.org'
5154 );
5255
5356 diag "testing with CGI.pm version: $CGI::VERSION";
54 diag "testing with CGI::Simple version: $CGI::Simple::VERSION" if $cgi_simple_test;
57 diag "testing with CGI::Simple version: $CGI::Simple::VERSION"
58 if $cgi_simple_test;
5559
5660 ## testing vars
5761 my $cgi_pm_q;
5862 my $cgi_simple_q;
5963
6064 ## setup input (need cleaner way)
61 open(IN,'<t/upload_post_text.txt') || die 'missing test file';
65 open( IN, '<t/upload_post_text.txt' ) || die 'missing test file';
6266 binmode(IN);
6367
64 *STDIN = *IN;
68 *STDIN = *IN;
6569 $cgi_pm_q = CGI->new;
6670 close(IN);
6771
6872 ## setup CGI::Simple testing
69 if ($cgi_simple_test) {
70 open(IN,'<t/upload_post_text.txt') || die 'missing test file';
71 binmode(IN);
72 *STDIN = *IN;
73 ## annoying context
74 $CGI::Simple::DISABLE_UPLOADS = 0;
75 # Repeat to avoid warning..
76 $CGI::Simple::DISABLE_UPLOADS = 0;
77 $cgi_simple_q = CGI::Simple->new();
78 close(IN);
73 if ($cgi_simple_test)
74 {
75 open( IN, '<t/upload_post_text.txt' ) || die 'missing test file';
76 binmode(IN);
77 *STDIN = *IN;
78 ## annoying context
79 $CGI::Simple::DISABLE_UPLOADS = 0;
80
81 # Repeat to avoid warning..
82 $CGI::Simple::DISABLE_UPLOADS = 0;
83 $cgi_simple_q = CGI::Simple->new();
84 close(IN);
7985 }
8086
8187 use Data::FormValidator;
8288 my $default = {
83 required=>[qw/hello_world does_not_exist_gif 100x100_gif 300x300_gif/],
84 validator_packages=> 'Data::FormValidator::Constraints::Upload',
85 constraints => {
86 'hello_world' => {
87 constraint_method => 'file_format',
88 params=>[],
89 },
90 'does_not_exist_gif' => {
91 constraint_method => 'file_format',
92 params=>[],
93 },
94 '100x100_gif' => [
95 {
96 constraint_method => 'file_format',
97 params=>[],
98 },
99 {
100 constraint_method => 'file_max_bytes',
101 params=>[],
102 }
103 ],
104 '300x300_gif' => {
105 constraint_method => 'file_max_bytes',
106 params => [\100],
107 },
108 },
109 };
89 required => [qw/hello_world does_not_exist_gif 100x100_gif 300x300_gif/],
90 validator_packages => 'Data::FormValidator::Constraints::Upload',
91 constraints => {
92 'hello_world' => {
93 constraint_method => 'file_format',
94 params => [],
95 },
96 'does_not_exist_gif' => {
97 constraint_method => 'file_format',
98 params => [],
99 },
100 '100x100_gif' => [ {
101 constraint_method => 'file_format',
102 params => [],
103 },
104 {
105 constraint_method => 'file_max_bytes',
106 params => [],
107 }
108 ],
109 '300x300_gif' => {
110 constraint_method => 'file_max_bytes',
111 params => [ \100 ],
112 },
113 },
114 };
110115
111116 ## same set of tests with each one (does this work?)
112 for my $q ($cgi_pm_q, $cgi_simple_q) {
113 next unless $q;
114 diag "Running tests with ", ref $q;
115
116 my $dfv = Data::FormValidator->new({ default => $default });
117 my $results;
118 eval { $results = $dfv->check($q, 'default'); };
119 is($@,'','survived eval');
120
121 my $valid = $results->valid;
122 my $invalid = $results->invalid; # as hash ref
123 my @invalids = $results->invalid;
124 my $missing = $results->missing;
125
126
127 # Test to make sure hello world fails because it is the wrong type
128 ok((grep {m/hello_world/} @invalids), 'expect format failure');
129
130 # should fail on empty/missing source file data
131 ok((grep {m/does_not_exist_gif/} @invalids), 'expect non-existent failure');
132
133 ok(
134 (exists $valid->{'100x100_gif'}, "valid")
135 , 'Make sure 100x100 passes because it is the right type and size'
136 );
137
138 my $meta = $results->meta('100x100_gif');
139 is(ref $meta, 'HASH', 'meta() returns hash ref');
140
141 ok($meta->{extension}, 'setting extension meta data');
142 ok($meta->{mime_type}, 'setting mime_type meta data');
143
144 ok((grep {m/300x300/} @invalids)
145 , '300x300 should fail because it exceeds max_bytes');
146
147 ok(($results->meta('100x100_gif')->{bytes} > 0), (ref $q).': setting bytes meta data') ;
148
149
150 # Revalidate to usefully re-use the same fields
151 my $profile_2 = {
152 required=>[qw/hello_world 100x100_gif 300x300_gif/],
153 validator_packages=> 'Data::FormValidator::Constraints::Upload',
154 constraints => {
155 '100x100_gif' => {
156 constraint_method => 'image_max_dimensions',
157 params => [\200,\200],
158 },
159 '300x300_gif' => {
160 constraint_method => 'image_max_dimensions',
161 params => [\200,\200],
162 },
163 },
164 };
165
166 $dfv = Data::FormValidator->new({ profile_2 => $profile_2});
167 eval {
168 $results = $dfv->check($q, 'profile_2');
169 };
170 ok(not $@) or diag $@;
171
172 $valid = $results->valid;
173 $invalid = $results->invalid; # as hash ref
174 @invalids = $results->invalid;
175 $missing = $results->missing;
176
177 ok(exists $valid->{'100x100_gif'}, 'expecting success with max_dimensions');
178 ok((grep /300x300/, @invalids), 'expecting failure with max_dimensions');
179
180 ok( $results->meta('100x100_gif')->{width} > 0, 'setting width as meta data');
181 ok( $results->meta('100x100_gif')->{width} > 0, 'setting height as meta data');
182
183 # Now test trying constraint_regxep_map
184 my $profile_3 = {
185 required=>[qw/hello_world 100x100_gif 300x300_gif/],
186 validator_packages=> 'Data::FormValidator::Constraints::Upload',
187 constraint_regexp_map => {
188 '/[13]00x[13]00_gif/' => {
189 constraint_method => 'image_max_dimensions',
190 params => [\200,\200],
191 }
192 }
193 };
194
195 $dfv = Data::FormValidator->new({ profile_3 => $profile_3});
196 ($valid,$missing,$invalid) = $dfv->validate($q, 'profile_3');
197
198 ok(exists $valid->{'100x100_gif'}, 'expecting success with max_dimensions using constraint_regexp_map');
199 ok((grep {m/300x300/} @$invalid), 'expecting failure with max_dimensions using constraint_regexp_map');
200
201 ## min test
202 my $profile_4 = {
203 required=>[qw/hello_world 100x100_gif 300x300_gif/],
204 validator_packages=> 'Data::FormValidator::Constraints::Upload',
205 constraints => {
206 '100x100_gif' => {
207 constraint_method => 'image_min_dimensions',
208 params => [\200,\200],
209 },
210 '300x300_gif' => {
211 constraint_method => 'image_min_dimensions',
212 params => [\200,\200],
213 },
214 },
215 };
216
217 $dfv = Data::FormValidator->new({ profile_4 => $profile_4});
218 eval {
219 $results = $dfv->check($q, 'profile_4');
220 };
221 ok(not $@) or diag $@;
222
223 $valid = $results->valid;
224 $invalid = $results->invalid; # as hash ref
225 @invalids = $results->invalid;
226 $missing = $results->missing;
227
228 ok(exists $valid->{'300x300_gif'}, 'expecting success with min_dimensions');
229 ok((grep /100x100/, @invalids), 'expecting failure with min_dimensions');
230
231 ## file type tests
232 ## with new interface
233 {
234 use Data::FormValidator::Constraints::Upload qw(file_format);
235
236 my $profile_5 = {
237 required=> [qw/hello_world 100x100_gif 300x300_gif/],
238 constraint_methods => {
239 '100x100_gif' => [ file_format( mime_types => [ qw(image/gif) ] ) ],
240 '300x300_gif' => [ file_format( mime_types => [ qw(image/png) ] ) ]
241 }
242 };
243
244 $dfv = Data::FormValidator->new({ profile_5 => $profile_5});
245 eval {
246 $results = $dfv->check($q, 'profile_5');
247 };
248
249 ok(not $@) or diag $@;
250
251 $valid = $results->valid;
252 $invalid = $results->invalid; # as hash ref
253 @invalids = $results->invalid;
254 $missing = $results->missing;
255
256 ok(exists $valid->{'100x100_gif'}, 'expecting success with mime_type');
257 ok((grep /300x300/, @invalids), 'expecting failure with mime_type');
258 }
259
260 ## range checks with new format
261 {
262 use Data::FormValidator::Constraints::Upload qw(image_max_dimensions image_min_dimensions);
263 my $profile_6 = {
264 required => [ qw/hello_world 100x100_gif 300x300_gif/ ],
265 constraint_methods => {
266 '100x100_gif' => [
267 image_max_dimensions(200, 200),
268 image_min_dimensions(110, 100)
269 ],
270 '300x300_gif' => [
271 image_max_dimensions(400, 400),
272 image_min_dimensions(245, 100)
273 ]
274 }
275 };
276
277 $dfv = Data::FormValidator->new({ profile_6 => $profile_6});
278 eval {
279 $results = $dfv->check($q, 'profile_6');
280 };
281 is($@,'','survived eval');
282
283 $valid = $results->valid;
284 $invalid = $results->invalid; # as hash ref
285 @invalids = $results->invalid;
286 $missing = $results->missing;
287
288 ok((grep /100x100/, @invalids), 'expecting failure with size range');
289 ok(exists $valid->{'300x300_gif'}, 'expecting success with size range');
290
291 }
117 for my $q ( $cgi_pm_q, $cgi_simple_q )
118 {
119 next unless $q;
120 diag "Running tests with ", ref $q;
121
122 my $dfv = Data::FormValidator->new( { default => $default } );
123 my $results;
124 eval { $results = $dfv->check( $q, 'default' ); };
125 is( $@, '', 'survived eval' );
126
127 my $valid = $results->valid;
128 my $invalid = $results->invalid; # as hash ref
129 my @invalids = $results->invalid;
130 my $missing = $results->missing;
131
132 # Test to make sure hello world fails because it is the wrong type
133 ok( ( grep { m/hello_world/ } @invalids ), 'expect format failure' );
134
135 # should fail on empty/missing source file data
136 ok( ( grep { m/does_not_exist_gif/ } @invalids ),
137 'expect non-existent failure' );
138
139 ok( ( exists $valid->{'100x100_gif'}, "valid" ),
140 'Make sure 100x100 passes because it is the right type and size' );
141
142 my $meta = $results->meta('100x100_gif');
143 is( ref $meta, 'HASH', 'meta() returns hash ref' );
144
145 ok( $meta->{extension}, 'setting extension meta data' );
146 ok( $meta->{mime_type}, 'setting mime_type meta data' );
147
148 ok( ( grep { m/300x300/ } @invalids ),
149 '300x300 should fail because it exceeds max_bytes' );
150
151 ok(
152 ( $results->meta('100x100_gif')->{bytes} > 0 ),
153 ( ref $q ) . ': setting bytes meta data'
154 );
155
156 # Revalidate to usefully re-use the same fields
157 my $profile_2 = {
158 required => [qw/hello_world 100x100_gif 300x300_gif/],
159 validator_packages => 'Data::FormValidator::Constraints::Upload',
160 constraints => {
161 '100x100_gif' => {
162 constraint_method => 'image_max_dimensions',
163 params => [ \200, \200 ],
164 },
165 '300x300_gif' => {
166 constraint_method => 'image_max_dimensions',
167 params => [ \200, \200 ],
168 },
169 },
170 };
171
172 $dfv = Data::FormValidator->new( { profile_2 => $profile_2 } );
173 eval { $results = $dfv->check( $q, 'profile_2' ); };
174 ok( not $@ ) or diag $@;
175
176 $valid = $results->valid;
177 $invalid = $results->invalid; # as hash ref
178 @invalids = $results->invalid;
179 $missing = $results->missing;
180
181 ok( exists $valid->{'100x100_gif'}, 'expecting success with max_dimensions' );
182 ok( ( grep /300x300/, @invalids ), 'expecting failure with max_dimensions' );
183
184 ok( $results->meta('100x100_gif')->{width} > 0,
185 'setting width as meta data' );
186 ok( $results->meta('100x100_gif')->{width} > 0,
187 'setting height as meta data' );
188
189 # Now test trying constraint_regxep_map
190 my $profile_3 = {
191 required => [qw/hello_world 100x100_gif 300x300_gif/],
192 validator_packages => 'Data::FormValidator::Constraints::Upload',
193 constraint_regexp_map => {
194 '/[13]00x[13]00_gif/' => {
195 constraint_method => 'image_max_dimensions',
196 params => [ \200, \200 ],
197 } } };
198
199 $dfv = Data::FormValidator->new( { profile_3 => $profile_3 } );
200 ( $valid, $missing, $invalid ) = $dfv->validate( $q, 'profile_3' );
201
202 ok( exists $valid->{'100x100_gif'},
203 'expecting success with max_dimensions using constraint_regexp_map' );
204 ok( ( grep { m/300x300/ } @$invalid ),
205 'expecting failure with max_dimensions using constraint_regexp_map' );
206
207 ## min test
208 my $profile_4 = {
209 required => [qw/hello_world 100x100_gif 300x300_gif/],
210 validator_packages => 'Data::FormValidator::Constraints::Upload',
211 constraints => {
212 '100x100_gif' => {
213 constraint_method => 'image_min_dimensions',
214 params => [ \200, \200 ],
215 },
216 '300x300_gif' => {
217 constraint_method => 'image_min_dimensions',
218 params => [ \200, \200 ],
219 },
220 },
221 };
222
223 $dfv = Data::FormValidator->new( { profile_4 => $profile_4 } );
224 eval { $results = $dfv->check( $q, 'profile_4' ); };
225 ok( not $@ ) or diag $@;
226
227 $valid = $results->valid;
228 $invalid = $results->invalid; # as hash ref
229 @invalids = $results->invalid;
230 $missing = $results->missing;
231
232 ok( exists $valid->{'300x300_gif'}, 'expecting success with min_dimensions' );
233 ok( ( grep /100x100/, @invalids ), 'expecting failure with min_dimensions' );
234
235 ## file type tests
236 ## with new interface
237 {
238 use Data::FormValidator::Constraints::Upload qw(file_format);
239
240 my $profile_5 = {
241 required => [qw/hello_world 100x100_gif 300x300_gif/],
242 constraint_methods => {
243 '100x100_gif' => [ file_format( mime_types => [qw(image/gif)] ) ],
244 '300x300_gif' => [ file_format( mime_types => [qw(image/png)] ) ] } };
245
246 $dfv = Data::FormValidator->new( { profile_5 => $profile_5 } );
247 eval { $results = $dfv->check( $q, 'profile_5' ); };
248
249 ok( not $@ ) or diag $@;
250
251 $valid = $results->valid;
252 $invalid = $results->invalid; # as hash ref
253 @invalids = $results->invalid;
254 $missing = $results->missing;
255
256 ok( exists $valid->{'100x100_gif'}, 'expecting success with mime_type' );
257 ok( ( grep /300x300/, @invalids ), 'expecting failure with mime_type' );
258 }
259
260 ## range checks with new format
261 {
262 use Data::FormValidator::Constraints::Upload
263 qw(image_max_dimensions image_min_dimensions);
264 my $profile_6 = {
265 required => [qw/hello_world 100x100_gif 300x300_gif/],
266 constraint_methods => {
267 '100x100_gif' => [
268 image_max_dimensions( 200, 200 ), image_min_dimensions( 110, 100 )
269 ],
270 '300x300_gif' => [
271 image_max_dimensions( 400, 400 ), image_min_dimensions( 245, 100 ) ] }
272 };
273
274 $dfv = Data::FormValidator->new( { profile_6 => $profile_6 } );
275 eval { $results = $dfv->check( $q, 'profile_6' ); };
276 is( $@, '', 'survived eval' );
277
278 $valid = $results->valid;
279 $invalid = $results->invalid; # as hash ref
280 @invalids = $results->invalid;
281 $missing = $results->missing;
282
283 ok( ( grep /100x100/, @invalids ), 'expecting failure with size range' );
284 ok( exists $valid->{'300x300_gif'}, 'expecting success with size range' );
285
286 }
292287
293288 } ## end of for loop
294289
295 ## end of tests
290 done_testing;
0 #########################
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More;
14
2 use Test::More 'no_plan';
3 use strict;
4 BEGIN {
5 use_ok('CGI');
6 use_ok('Data::FormValidator::Constraints::Upload')
7 };
5 BEGIN
6 {
7 eval { require CGI;CGI->VERSION(4.35); };
8 plan skip_all => 'CGI 4.35 or higher not found' if $@;
9 use_ok('CGI');
10 use_ok('Data::FormValidator::Constraints::Upload');
11 }
812
913 #########################
1014
1115 %ENV = (
12 %ENV,
13 'SCRIPT_NAME' => '/test.cgi',
14 'SERVER_NAME' => 'perl.org',
15 'HTTP_CONNECTION' => 'TE, close',
16 'REQUEST_METHOD' => 'POST',
17 'SCRIPT_URI' => 'http://www.perl.org/test.cgi',
18 'CONTENT_LENGTH' => 3129,
19 'SCRIPT_FILENAME' => '/home/usr/test.cgi',
20 'SERVER_SOFTWARE' => 'Apache/1.3.27 (Unix) ',
21 'HTTP_TE' => 'deflate,gzip;q=0.3',
22 'QUERY_STRING' => '',
23 'REMOTE_PORT' => '1855',
24 'HTTP_USER_AGENT' => 'Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)',
25 'SERVER_PORT' => '80',
26 'REMOTE_ADDR' => '127.0.0.1',
27 'CONTENT_TYPE' => 'multipart/form-data; boundary=xYzZY',
28 'SERVER_PROTOCOL' => 'HTTP/1.1',
29 'PATH' => '/usr/local/bin:/usr/bin:/bin',
30 'REQUEST_URI' => '/test.cgi',
31 'GATEWAY_INTERFACE' => 'CGI/1.1',
32 'SCRIPT_URL' => '/test.cgi',
33 'SERVER_ADDR' => '127.0.0.1',
34 'DOCUMENT_ROOT' => '/home/develop',
35 'HTTP_HOST' => 'www.perl.org'
16 %ENV,
17 'SCRIPT_NAME' => '/test.cgi',
18 'SERVER_NAME' => 'perl.org',
19 'HTTP_CONNECTION' => 'TE, close',
20 'REQUEST_METHOD' => 'POST',
21 'SCRIPT_URI' => 'http://www.perl.org/test.cgi',
22 'CONTENT_LENGTH' => 3129,
23 'SCRIPT_FILENAME' => '/home/usr/test.cgi',
24 'SERVER_SOFTWARE' => 'Apache/1.3.27 (Unix) ',
25 'HTTP_TE' => 'deflate,gzip;q=0.3',
26 'QUERY_STRING' => '',
27 'REMOTE_PORT' => '1855',
28 'HTTP_USER_AGENT' => 'Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)',
29 'SERVER_PORT' => '80',
30 'REMOTE_ADDR' => '127.0.0.1',
31 'CONTENT_TYPE' => 'multipart/form-data; boundary=xYzZY',
32 'SERVER_PROTOCOL' => 'HTTP/1.1',
33 'PATH' => '/usr/local/bin:/usr/bin:/bin',
34 'REQUEST_URI' => '/test.cgi',
35 'GATEWAY_INTERFACE' => 'CGI/1.1',
36 'SCRIPT_URL' => '/test.cgi',
37 'SERVER_ADDR' => '127.0.0.1',
38 'DOCUMENT_ROOT' => '/home/develop',
39 'HTTP_HOST' => 'www.perl.org'
3640 );
3741
3842 diag "testing with CGI.pm version: $CGI::VERSION";
3943
40 open(IN,'<t/upload_post_text.txt') || die 'missing test file';
44 open( IN, '<t/upload_post_text.txt' ) || die 'missing test file';
4145 binmode(IN);
4246
4347 *STDIN = *IN;
4549
4650 use Data::FormValidator;
4751 use Data::FormValidator::Constraints::Upload qw(
48 &file_format
49 &file_max_bytes
50 &image_max_dimensions
52 &file_format
53 &file_max_bytes
54 &image_max_dimensions
5155 );
5256
5357 my $default = {
54 required=>[qw/hello_world does_not_exist_gif 100x100_gif 300x300_gif/],
55 validator_packages=> 'Data::FormValidator::Constraints::Upload',
56 constraint_methods => {
57 'hello_world' => file_format(),
58 'does_not_exist_gif' => file_format(),
59 '100x100_gif' => [
60 file_format(),
61 file_max_bytes(),
62 ],
63 '300x300_gif' => file_max_bytes(100),
64 },
65 };
58 required => [qw/hello_world does_not_exist_gif 100x100_gif 300x300_gif/],
59 validator_packages => 'Data::FormValidator::Constraints::Upload',
60 constraint_methods => {
61 'hello_world' => file_format(),
62 'does_not_exist_gif' => file_format(),
63 '100x100_gif' => [ file_format(), file_max_bytes(), ],
64 '300x300_gif' => file_max_bytes(100),
65 },
66 };
6667
67 my $dfv = Data::FormValidator->new({ default => $default});
68 my $dfv = Data::FormValidator->new( { default => $default } );
6869 my ($results);
69 eval {
70 $results = $dfv->check($q, 'default');
71 };
72 is($@, '', 'survived eval');
70 eval { $results = $dfv->check( $q, 'default' ); };
71 is( $@, '', 'survived eval' );
7372
74 my $valid = $results->valid;
75 my $invalid = $results->invalid; # as hash ref
73 my $valid = $results->valid;
74 my $invalid = $results->invalid; # as hash ref
7675 my @invalids = $results->invalid;
77 my $missing = $results->missing;
78
76 my $missing = $results->missing;
7977
8078 # Test to make sure hello world fails because it is the wrong type
81 ok((grep {m/hello_world/} @invalids), 'expect format failure');
79 ok( ( grep { m/hello_world/ } @invalids ), 'expect format failure' );
8280
8381 # should fail on empty/missing source file data
84 ok((grep {m/does_not_exist_gif/} @invalids), 'expect non-existent failure');
85
82 ok( ( grep { m/does_not_exist_gif/ } @invalids ),
83 'expect non-existent failure' );
8684
8785 # Make sure 100x100 passes because it is the right type and size
88 ok(exists $valid->{'100x100_gif'});
86 ok( exists $valid->{'100x100_gif'} );
8987
9088 my $meta = $results->meta('100x100_gif');
91 is(ref $meta, 'HASH', 'meta() returns hash ref');
89 is( ref $meta, 'HASH', 'meta() returns hash ref' );
9290
93 ok($meta->{extension}, 'setting extension meta data');
94 ok($meta->{mime_type}, 'setting mime_type meta data');
91 ok( $meta->{extension}, 'setting extension meta data' );
92 ok( $meta->{mime_type}, 'setting mime_type meta data' );
9593
9694 # 300x300 should fail because it is too big
97 ok((grep {m/300x300/} @invalids), 'max_bytes');
95 ok( ( grep { m/300x300/ } @invalids ), 'max_bytes' );
9896
99 ok($results->meta('100x100_gif')->{bytes}>0, 'setting bytes meta data');
100
97 ok( $results->meta('100x100_gif')->{bytes} > 0, 'setting bytes meta data' );
10198
10299 # Revalidate to usefully re-use the same fields
103 my $profile_2 = {
104 required=>[qw/hello_world 100x100_gif 300x300_gif/],
105 validator_packages=> 'Data::FormValidator::Constraints::Upload',
106 constraint_methods => {
107 '100x100_gif' => image_max_dimensions(200,200),
108 '300x300_gif' => image_max_dimensions(200,200),
109 },
100 my $profile_2 = {
101 required => [qw/hello_world 100x100_gif 300x300_gif/],
102 validator_packages => 'Data::FormValidator::Constraints::Upload',
103 constraint_methods => {
104 '100x100_gif' => image_max_dimensions( 200, 200 ),
105 '300x300_gif' => image_max_dimensions( 200, 200 ),
106 },
110107 };
111108
112 $dfv = Data::FormValidator->new({ profile_2 => $profile_2});
113 eval {
114 $results = $dfv->check($q, 'profile_2');
115 };
116 is($@,'', 'survived eval');
109 $dfv = Data::FormValidator->new( { profile_2 => $profile_2 } );
110 eval { $results = $dfv->check( $q, 'profile_2' ); };
111 is( $@, '', 'survived eval' );
117112
118 $valid = $results->valid;
119 $invalid = $results->invalid; # as hash ref
113 $valid = $results->valid;
114 $invalid = $results->invalid; # as hash ref
120115 @invalids = $results->invalid;
121 $missing = $results->missing;
116 $missing = $results->missing;
122117
123 ok(exists $valid->{'100x100_gif'}, 'expecting success with max_dimensions');
124 ok((grep /300x300/, @invalids), 'expecting failure with max_dimensions');
118 ok( exists $valid->{'100x100_gif'}, 'expecting success with max_dimensions' );
119 ok( ( grep /300x300/, @invalids ), 'expecting failure with max_dimensions' );
125120
126 ok( $results->meta('100x100_gif')->{width} > 0, 'setting width as meta data');
127 ok( $results->meta('100x100_gif')->{width} > 0, 'setting height as meta data');
121 ok( $results->meta('100x100_gif')->{width} > 0, 'setting width as meta data' );
122 ok( $results->meta('100x100_gif')->{width} > 0, 'setting height as meta data' );
128123
129124 # Now test trying constraint_regxep_map
130 my $profile_3 = {
131 required=>[qw/hello_world 100x100_gif 300x300_gif/],
132 validator_packages=> 'Data::FormValidator::Constraints::Upload',
133 constraint_method_regexp_map => {
134 '/[13]00x[13]00_gif/' => image_max_dimensions(200,200),
135 }
136 };
125 my $profile_3 = {
126 required => [qw/hello_world 100x100_gif 300x300_gif/],
127 validator_packages => 'Data::FormValidator::Constraints::Upload',
128 constraint_method_regexp_map => {
129 '/[13]00x[13]00_gif/' => image_max_dimensions( 200, 200 ),
130 } };
137131
138 $dfv = Data::FormValidator->new({ profile_3 => $profile_3});
139 ($valid,$missing,$invalid) = $dfv->validate($q, 'profile_3');
132 $dfv = Data::FormValidator->new( { profile_3 => $profile_3 } );
133 ( $valid, $missing, $invalid ) = $dfv->validate( $q, 'profile_3' );
140134
141 ok(exists $valid->{'100x100_gif'}, 'expecting success with max_dimensions using constraint_regexp_map');
142 ok((grep {m/300x300/} @$invalid), 'expecting failure with max_dimensions using constraint_regexp_map');
135 ok( exists $valid->{'100x100_gif'},
136 'expecting success with max_dimensions using constraint_regexp_map' );
137 ok( ( grep { m/300x300/ } @$invalid ),
138 'expecting failure with max_dimensions using constraint_regexp_map' );
143139
144
140 done_testing;
0 #!/usr/bin/env perl
1 use strict;
2 use warnings;
3 use Test::More tests => 5;
4 use_ok('Data::FormValidator::Constraints::Upload');
5
06 # Exercise the _is_allowed_type() helper function
17
2 use Test::More tests => 5;
3 use strict;
4 use_ok('Data::FormValidator::Constraints::Upload');
5
68 # Test the negative case
7 isnt(
8 Data::FormValidator::Constraints::Upload::_is_allowed_type('foo'),
9 1, "'foo' not considered an allowed mime type"
10 );
9 isnt( Data::FormValidator::Constraints::Upload::_is_allowed_type('foo'),
10 1, "'foo' not considered an allowed mime type" );
1111
1212 # Reality check that a simple jpeg is allowed
13 is(
14 Data::FormValidator::Constraints::Upload::_is_allowed_type('image/jpeg'),
15 1, "'image/jpeg' is considered an allowed mime type"
16 );
13 is( Data::FormValidator::Constraints::Upload::_is_allowed_type('image/jpeg'),
14 1, "'image/jpeg' is considered an allowed mime type" );
1715
1816 # Check that we handle case insensitivity
19 is(
20 Data::FormValidator::Constraints::Upload::_is_allowed_type('image/JPEG'),
21 1, "'image/JPEG' is considered an allowed mime type"
22 );
17 is( Data::FormValidator::Constraints::Upload::_is_allowed_type('image/JPEG'),
18 1, "'image/JPEG' is considered an allowed mime type" );
2319
2420 # Also ensure progressive jpegs are allowed
25 is(
26 Data::FormValidator::Constraints::Upload::_is_allowed_type('image/pjpeg'),
27 1, "'image/pjpeg' is considered an allowed mime type"
28 );
29
21 is( Data::FormValidator::Constraints::Upload::_is_allowed_type('image/pjpeg'),
22 1, "'image/pjpeg' is considered an allowed mime type" );
Binary diff not shown