Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

impreoved undefined value validation and removed experimental status …

…from Validator::Custom::loose_data method
  • Loading branch information...
commit b526d656cd8e0e6e7894da4262c33d4d39b45b6c 1 parent 89ce7cf
Yuki Kimoto authored
16 Changes
View
@@ -1,6 +1,22 @@
+0.1426
+ - improved undefined value validation
0.1425
- added EXPERIMENTAL Validator::Custom::Result loose_data method
- can set code reference to rule default option to get data at read time.
+ - changed backword compatible policy
+ ------------------------------------------------------------------------
+ If a functionality is DEPRECATED, you can know it by DEPRECATED warnings
+ except for attribute method.
+ You can check all DEPRECATED functionalities by document.
+ DEPRECATED functionality is removed after five years,
+ but if at least one person use the functionality and tell me that thing
+ I extend one year each time you tell me it.
+
+ EXPERIMENTAL functionality will be changed without warnings.
+ ------------------------------------------------------------------------
+
+EXPERIMENTAL functionality will be changed without warnings.
+
0.1424
- added to_array filter
0.1422
2  Makefile.PL
View
@@ -13,7 +13,7 @@ WriteMakefile(
PL_FILES => {},
PREREQ_PM => {
'Test::More' => 0,
- 'Object::Simple' => 3.0616
+ 'Object::Simple' => 3.0621
},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'Validator-Custom-*' },
77 lib/Validator/Custom.pm
View
@@ -1,26 +1,16 @@
package Validator::Custom;
-
-our $VERSION = '0.1425';
-
+use Object::Simple -base;
use 5.008001;
-use strict;
-use warnings;
-
-use base 'Object::Simple';
+our $VERSION = '0.1426';
use Carp 'croak';
use Validator::Custom::Constraint;
use Validator::Custom::Result;
-# Object::Simple "dual_attr" is deprecated. Don't use "dual_attr".
-# I rest this for the promiss of keeping backword compatible.
-__PACKAGE__->dual_attr('constraints', default => sub { {} },
- inherit => 'hash_copy');
-__PACKAGE__->attr('data_filter');
-__PACKAGE__->attr(error_stock => 1);
-__PACKAGE__->attr('rule');
+has ['data_filter', 'rule'],
+ error_stock => 1;
-__PACKAGE__->attr(syntax => <<'EOS');
+has syntax => <<'EOS';
### Syntax of validation rule
my $rule = [ # 1 Rule is array ref
key => [ # 2 Constraints is array ref
@@ -675,8 +665,10 @@ sub _rule_syntax {
}
# DEPRECATED!
-__PACKAGE__->attr(shared_rule => sub { [] });
-
+has shared_rule => sub { [] };
+# DEPRECATED!
+__PACKAGE__->dual_attr('constraints', default => sub { {} },
+ inherit => 'hash_copy');
1;
=head1 NAME
@@ -716,6 +708,10 @@ Validator::Custom - Validate user input easily
my $messages = $result->messages_to_hash;
}
}
+ my $valid_data = $result->data;
+ my $raw_data = $result->raw_data;
+ my $loose_data = $result->loose_data;
+
=head1 DESCRIPTION
@@ -985,10 +981,10 @@ Blank.
=head2 C<decimal>
- my $data = {num1 => '123.45678', num2 => '1.45'};
+ my $data = {num1 => '123', num2 => '1.45'};
my $rule => [
num1 => [
- 'decimal'
+ {'decimal' => 3}
],
num2 => [
{'decimal' => [1, 2]}
@@ -1013,13 +1009,16 @@ Defined.
my $data = {mail1 => 'a@somehost.com', mail2 => 'a@somehost.com'};
my $rule => [
- [qw/mail1 mail2/] => [
+ {mail => ['mail1', 'mail2']} => [
'duplication'
]
];
Check if the two data are same or not.
+Note that if one value is not defined or both values are not defined,
+result of validation is false.
+
=head2 C<equal_to>
my $data = {price => 1000};
@@ -1320,11 +1319,41 @@ Trim leading white space.
Trim trailing white space.
-=head1 STABILITY
+=head1 DEPRECATED FUNCTIONALITIES
-All methods in these documentations
-(except for EXPERIMENTAL marking ones)
-keep backword compatible in the future.
+L<Validator::Custom>
+
+ # Atrribute methods
+ shared_rule # Removed at 2017/1/1
+
+ # Methods
+ __PACKAGE__->constraints(...); # Call constraints method as class method
+ # Removed at 2017/1/1
+L<Validator::Custom::Result>
+
+ # Attribute methods
+ error_infos # Removed at 2017/1/1
+
+ # Methods
+ add_error_info # Removed at 2017/1/1
+ error # Removed at 2017/1/1
+ errors # Removed at 2017/1/1
+ errors_to_hash # Removed at 2017/1/1
+ invalid_keys # Removed at 2017/1/1
+ remove_error_info# Removed at 2017/1/1
+
+=head1 BACKWORD COMPATIBLE POLICY
+
+If a functionality is DEPRECATED, you can know it by DEPRECATED warnings
+except for attribute method.
+You can check all DEPRECATED functionalities by document.
+DEPRECATED functionality is removed after five years,
+but if at least one person use the functionality and tell me that thing
+I extend one year each time you tell me it.
+
+EXPERIMENTAL functionality will be changed without warnings.
+
+This policy is changed at 2011/6/28
=head1 AUTHOR
41 lib/Validator/Custom/Constraint.pm
View
@@ -8,7 +8,7 @@ use Carp 'croak';
# Carp trust relationship
push @Validator::Custom::CARP_NOT, __PACKAGE__;
-sub ascii { $_[0] =~ /^[\x21-\x7E]+$/ ? 1 : 0 }
+sub ascii { defined $_[0] && $_[0] =~ /^[\x21-\x7E]+$/ ? 1 : 0 }
sub between {
my ($value, $args) = @_;
@@ -17,11 +17,11 @@ sub between {
croak "Constraint 'between' needs two numeric arguments"
unless defined($start) && $start =~ /^\d+$/ && defined($end) && $end =~ /^\d+$/;
- return 0 unless $value =~ /^\d+$/;
+ return 0 unless defined $value && $value =~ /^\d+$/;
return $value >= $start && $value <= $end ? 1 : 0;
}
-sub blank { $_[0] eq '' }
+sub blank { defined $_[0] && $_[0] eq '' }
sub date_to_timepiece {
my $value = shift;
@@ -34,6 +34,9 @@ sub date_to_timepiece {
my $mon = $value->[1];
my $mday = $value->[2];
+ return [0, undef]
+ unless defined $year && defined $mon && defined $mday;
+
unless ($year =~ /^\d{1,4}$/ && $mon =~ /^\d{1,2}$/
&& $mday =~ /^\d{1,2}$/)
{
@@ -53,7 +56,7 @@ sub date_to_timepiece {
return $@ ? [0, undef] : [1, $tp];
}
else {
- $value ||= '';
+ $value = '' unless defined $value;
$value =~ s/[^\d]//g;
return [0, undef] unless $value =~ /^\d{8}$/;
@@ -76,12 +79,16 @@ sub datetime_to_timepiece {
# To Time::Piece object
if (ref $value eq 'ARRAY') {
- my $year = $value->[0] || '';
- my $mon = $value->[1] || '';
- my $mday = $value->[2] || '';
- my $hour = $value->[3] || '';
- my $min = $value->[4] || '';
- my $sec = $value->[5] || '';
+ my $year = $value->[0];
+ my $mon = $value->[1];
+ my $mday = $value->[2];
+ my $hour = $value->[3];
+ my $min = $value->[4];
+ my $sec = $value->[5];
+
+ return [0, undef]
+ unless defined $year && defined $mon && defined $mday
+ && defined $hour && defined $min && defined $sec;
unless ($year =~ /^\d{1,4}$/ && $mon =~ /^\d{1,2}$/
&& $mday =~ /^\d{1,2}$/ && $hour =~ /^\d{1,2}$/
@@ -104,7 +111,7 @@ sub datetime_to_timepiece {
return $@ ? [0, undef] : [1, $tp];
}
else {
- $value ||= '';
+ $value = '' unless defined $value;
$value =~ s/[^\d]//g;
return [0, undef] unless $value =~ /^\d{14}$/;
@@ -133,7 +140,7 @@ sub decimal {
croak "Constraint 'decimal' needs one or two numeric arguments"
unless $digits->[0] =~ /^\d+$/ && $digits->[1] =~ /^\d+$/;
- return 0 unless $value =~ /^\d+(\.\d+)?$/;
+ return 0 unless defined $value && $value =~ /^\d+(\.\d+)?$/;
my $reg = qr/^\d{1,$digits->[0]}(\.\d{0,$digits->[1]})?$/;
return $value =~ /$reg/ ? 1 : 0;
}
@@ -141,9 +148,7 @@ sub decimal {
sub duplication {
my $values = shift;
- croak "Constraint 'duplication' needs two keys of data"
- unless defined $values->[0] && defined $values->[1];
-
+ return 0 unless defined $values->[0] && defined $values->[1];
return $values->[0] eq $values->[1] ? [1, $values->[0]] : 0;
}
@@ -153,7 +158,7 @@ sub equal_to {
croak "Constraint 'equal_to' needs a numeric argument"
unless defined $target && $target =~ /^\d+$/;
- return 0 unless $value =~ /^\d+$/;
+ return 0 unless defined $value && $value =~ /^\d+$/;
return $value == $target ? 1 : 0;
}
@@ -163,12 +168,12 @@ sub greater_than {
croak "Constraint 'greater_than' needs a numeric argument"
unless defined $target && $target =~ /^\d+$/;
- return 0 unless $value =~ /^\d+$/;
+ return 0 unless defined $value && $value =~ /^\d+$/;
return $value > $target ? 1 : 0;
}
sub http_url {
- return $_[0] =~ /^s?https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+$/ ? 1 : 0;
+ return defined $_[0] && $_[0] =~ /^s?https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+$/ ? 1 : 0;
}
sub int { $_[0] =~ /^\-?[\d]+$/ ? 1 : 0 }
48 lib/Validator/Custom/Result.pm
View
@@ -1,16 +1,12 @@
package Validator::Custom::Result;
-
-use strict;
-use warnings;
-
-use base 'Object::Simple';
+use Object::Simple -base;
use Carp 'croak';
# Attrbutes
-__PACKAGE__->attr(data => sub { {} });
-__PACKAGE__->attr(missing_params => sub { [] });
-__PACKAGE__->attr(raw_data => sub { {} });
+has data => sub { {} },
+ missing_params => sub { [] },
+ raw_data => sub { {} };
# Default message
our $DEFAULT_MESSAGE = 'Error message not specified';
@@ -141,41 +137,47 @@ sub to_hash {
return $result;
}
-### Deprecated attributes and methods
-
-__PACKAGE__->attr(error_infos => sub { {} });
+# DEPRECATED!
+has error_infos => sub { {} };
+# DEPRECATED!
sub add_error_info {
my $self = shift;
-
+ warn "add_error_info method is DEPRECATED!";
# Merge
my $error_infos = ref $_[0] eq 'HASH' ? $_[0] : {@_};
$self->error_infos({%{$self->error_infos}, %$error_infos});
-
return $self;
}
-
-sub error { shift->message(@_) }
-
+# DEPRECATED!
+sub error {
+ warn "error_info method is DEPRECATED!";
+ shift->message(@_)
+}
+# DEPRECATED!
sub errors {
+ warn "errors method is DEPRECATED!";
return wantarray
? @{shift->messages(@_)}
: shift->messages(@_);
}
-
-sub errors_to_hash { shift->messages_to_hash(@_) }
-
+# DEPRECATED!
+sub errors_to_hash {
+ warn "errors_to_hash method is DEPRECATED!";
+ shift->messages_to_hash(@_)
+}
+# DEPRECATED!
sub invalid_keys {
+ warn "invalid_keys method is DEPRECATED!";
return wantarray
? @{shift->invalid_rule_keys(@_)}
: shift->invalid_rule_keys(@_);
}
-
+# DEPRECATED!
sub remove_error_info {
my ($self, $key) = @_;
-
+ warn "remove_error_info method is DEPRECATED!";
# Remove
delete $self->error_infos->{$key};
-
return $self;
}
@@ -310,7 +312,7 @@ names specified in the rule is found in the data.
Check if one paramter is valid.
-=head2 C<loose_data> EXPERIMENTAL
+=head2 C<loose_data>
my $loose_data = $result->loose_data;
63 t/validator-custom-required-timepiece.t
View
@@ -269,3 +269,66 @@ $rule = [
$result = $vc->validate($data, $rule);
ok(!$result->is_ok);
+test 'undefined value validation';
+$data = {key1 => '2011', key2 => '10', key3 => '14', key4 => undef};
+$rule = [
+ {date1 => [qw/key1 key2 key3/]} => [
+ 'date_to_timepiece'
+ ],
+ {date2 => [qw/key1 key2 key4/]} => [
+ 'date_to_timepiece'
+ ],
+ {date3 => [qw/key1 key4 key3/]} => [
+ 'date_to_timepiece'
+ ],
+ {date4 => [qw/key4 key2 key3/]} => [
+ 'date_to_timepiece'
+ ],
+ 'key4' => [
+ 'date_to_timepiece'
+ ]
+];
+$result = $vc->validate($data, $rule);
+ok($result->is_valid('date1'));
+ok(!$result->is_valid('date2'));
+ok(!$result->is_valid('date3'));
+ok(!$result->is_valid('date4'));
+ok(!$result->is_valid('key4'));
+
+$data = {key1 => '2011', key2 => '10', key3 => '14', key4 => '10',
+ key5 => '10', key6 => '10', key7 => undef};
+$rule = [
+ {date1 => [qw/key1 key2 key3 key4 key5 key6/]} => [
+ 'datetime_to_timepiece'
+ ],
+ {date2 => [qw/key1 key2 key3 key4 key5 key7/]} => [
+ 'datetime_to_timepiece'
+ ],
+ {date3 => [qw/key1 key2 key3 key4 key7 key6/]} => [
+ 'datetime_to_timepiece'
+ ],
+ {date4 => [qw/key1 key2 key3 key7 key5 key6/]} => [
+ 'datetime_to_timepiece'
+ ],
+ {date5 => [qw/key1 key2 key7 key4 key5 key6/]} => [
+ 'datetime_to_timepiece'
+ ],
+ {date6 => [qw/key1 key7 key3 key4 key5 key6/]} => [
+ 'datetime_to_timepiece'
+ ],
+ {date7 => [qw/key7 key2 key3 key4 key5 key6/]} => [
+ 'datetime_to_timepiece'
+ ],
+ 'key7' => [
+ 'datetime_to_timepiece'
+ ]
+];
+$result = $vc->validate($data, $rule);
+ok($result->is_valid('date1'));
+ok(!$result->is_valid('date2'));
+ok(!$result->is_valid('date3'));
+ok(!$result->is_valid('date4'));
+ok(!$result->is_valid('date5'));
+ok(!$result->is_valid('date6'));
+ok(!$result->is_valid('date7'));
+ok(!$result->is_valid('key7'));
175 t/validator-custom.t
View
@@ -4,6 +4,7 @@ use strict;
use warnings;
use lib 't/validator-custom';
+$SIG{__WARN__} = sub { warn $_[0] unless $_[0] =~ /DEPRECATED!/ };
sub test {print "# $_[0]\n"}
my $value;
@@ -948,32 +949,6 @@ foreach my $info (@infos) {
# exception
my @exception_infos = (
[
- 'duplication value1 undefined',
- {
- k1_1 => undef,
- k1_2 => 'a',
- },
- [
- [qw/k1_1 k1_2/] => [
- ['duplication']
- ],
- ],
- qr/\QConstraint 'duplication' needs two keys of data/
- ],
- [
- 'duplication value2 undefined',
- {
- k2_1 => 'a',
- k2_2 => undef,
- },
- [
- [qw/k2_1 k2_2/] => [
- ['duplication']
- ]
- ],
- qr/\QConstraint 'duplication' needs two keys of data/
- ],
- [
'length need parameter',
{
k1 => 'a',
@@ -1202,11 +1177,11 @@ test 'trim';
}
test 'Carp trust relationship';
-$data = {a => undef, b => undef};
+$data = {a => undef};
$vc = Validator::Custom->new;
$rule = [
- {pass => [qw/a b/]} => [
- 'duplication'
+ a => [
+ 'decimal'
]
];
eval{$vc->validate($data, $rule)};
@@ -1798,3 +1773,145 @@ $rule = [
];
$result = $vc->validate($data, $rule);
is_deeply($result->loose_data->{key1}, 5);
+
+test 'undefined value';
+$vc = Validator::Custom->new;
+$data = {key1 => undef, key2 => '', key3 => 'a'};
+$rule = [
+ key1 => [
+ 'ascii'
+ ],
+ key2 => [
+ 'ascii'
+ ],
+ key3 => [
+ 'ascii'
+ ]
+];
+$result = $vc->validate($data, $rule);
+ok(!$result->is_valid('key1'));
+ok(!$result->is_valid('key2'));
+ok($result->is_valid('key3'));
+
+$data = {key1 => undef, key2 => '', key3 => '2'};
+$rule = [
+ key1 => [
+ {between => [1, 3]}
+ ],
+ key2 => [
+ {between => [1, 3]}
+ ],
+ key3 => [
+ {between => [1, 3]}
+ ]
+];
+$result = $vc->validate($data, $rule);
+ok(!$result->is_valid('key1'));
+ok(!$result->is_valid('key2'));
+ok($result->is_valid('key3'));
+
+$data = {key1 => undef, key2 => ''};
+$rule = [
+ key1 => [
+ 'blank'
+ ],
+ key2 => [
+ 'blank'
+ ]
+];
+$result = $vc->validate($data, $rule);
+ok(!$result->is_valid('key1'));
+ok($result->is_valid('key2'));
+
+$data = {key1 => undef, key2 => '', key3 => '2.1'};
+$rule = [
+ key1 => [
+ {decimal => 1}
+ ],
+ key2 => [
+ {decimal => 1}
+ ],
+ key3 => [
+ {decimal => [1, 1]}
+ ]
+];
+$result = $vc->validate($data, $rule);
+ok(!$result->is_valid('key1'));
+ok(!$result->is_valid('key2'));
+ok($result->is_valid('key3'));
+
+$data = {key1 => 'a', key2 => 'a', key3 => '', key4 => '', key5 => undef, key6 => undef};
+$rule = [
+ {'key1-2' => ['key1', 'key2']} => [
+ 'duplication'
+ ],
+ {'key3-4' => ['key3', 'key4']} => [
+ 'duplication'
+ ],
+ {'key1-5' => ['key1', 'key5']} => [
+ 'duplication'
+ ],
+ {'key5-1' => ['key5', 'key1']} => [
+ 'duplication'
+ ],
+ {'key5-6' => ['key5', 'key6']} => [
+ 'duplication'
+ ],
+];
+$result = $vc->validate($data, $rule);
+ok($result->is_valid('key1-2'));
+ok($result->is_valid('key3-4'));
+ok(!$result->is_valid('key1-5'));
+ok(!$result->is_valid('key5-1'));
+ok(!$result->is_valid('key5-6'));
+
+$data = {key1 => undef, key2 => '', key3 => '1'};
+$rule = [
+ key1 => [
+ {equal_to => 1}
+ ],
+ key2 => [
+ {equal_to => 1}
+ ],
+ key3 => [
+ {equal_to => 1}
+ ]
+];
+$result = $vc->validate($data, $rule);
+ok(!$result->is_valid('key1'));
+ok(!$result->is_valid('key2'));
+ok($result->is_valid('key3'));
+
+$data = {key1 => undef, key2 => '', key3 => '5'};
+$rule = [
+ key1 => [
+ {greater_than => 1}
+ ],
+ key2 => [
+ {greater_than => 1}
+ ],
+ key3 => [
+ {greater_than => 1}
+ ]
+];
+$result = $vc->validate($data, $rule);
+ok(!$result->is_valid('key1'));
+ok(!$result->is_valid('key2'));
+ok($result->is_valid('key3'));
+
+$data = {key1 => undef, key2 => '', key3 => 'http://aaa.com'};
+$rule = [
+ key1 => [
+ 'http_url'
+ ],
+ key2 => [
+ 'http_url'
+ ],
+ key3 => [
+ 'http_url'
+ ]
+];
+$result = $vc->validate($data, $rule);
+ok(!$result->is_valid('key1'));
+ok(!$result->is_valid('key2'));
+ok($result->is_valid('key3'));
Please sign in to comment.
Something went wrong with that request. Please try again.