Skip Menu |

This queue is for tickets about the FormValidator-Simple CPAN distribution.

Report information
The Basics
Id: 19667
Status: open
Priority: 0/
Queue: FormValidator-Simple

People
Owner: Nobody in particular
Requestors: tkp [...] kirkdesigns.co.uk
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.16
Fixed in: (no value)



Subject: FormValidator::Simple eats up the profile
when passing a profile into FV::Simple, FormValidator::Simple::Profile::init seems to eat it... never to be seen again! It's due to the use of splice in _init in FormValidator::Simple::Profile: sub _init { my($self, $prof) = @_; while ( my($keys, $constraints) = splice(@$prof, 0, 2) ) { my $record = FormValidator::Simple::Profile::Record->new; $record->set_keys($keys); $record->set_constraints($constraints); $self->append($record); } } I have a little test case which illustrates the problem: *************** *** 23,25 **** --- 23,34 ---- ok(!$r2->invalid('text')); ok($r2->invalid('int')); + + my $profile = [ + text => [qw/NOT_BLANK INT/], + int => [qw/NOT_BLANK INT/], + ]; + + is(scalar @$profile, 4); + my $r3 = FormValidator::Simple->check( $q => $profile ); + is(scalar @$profile, 4);
On Fri Jun 02 20:23:39 2006, guest wrote: Show quoted text
> when passing a profile into FV::Simple, > FormValidator::Simple::Profile::init seems to eat it... never to be seen > again! > > It's due to the use of splice in _init in FormValidator::Simple::Profile: > > sub _init { > my($self, $prof) = @_; > while ( my($keys, $constraints) = splice(@$prof, 0, 2) ) { > my $record = FormValidator::Simple::Profile::Record->new; > $record->set_keys($keys); > $record->set_constraints($constraints); > $self->append($record); > } > } > > I have a little test case which illustrates the problem: > > *************** > *** 23,25 **** > --- 23,34 ---- > > ok(!$r2->invalid('text')); > ok($r2->invalid('int')); > + > + my $profile = [ > + text => [qw/NOT_BLANK INT/], > + int => [qw/NOT_BLANK INT/], > + ]; > + > + is(scalar @$profile, 4); > + my $r3 = FormValidator::Simple->check( $q => $profile ); > + is(scalar @$profile, 4); >
Attached is a patch that resolves RT issues: 21224, 20658, 19667
Index: Changes =================================================================== --- Changes (revision 3) +++ Changes (working copy) @@ -1,5 +1,8 @@ Revision history for Perl extension FormValidator::Simple. + - fixed Profile _init from eating profiles via slice + - set_messages on object now overrides messages set on class + 0.16 Tue May 16 10:19:00 2006 - added DATETIME_FORMAT and DATETIME_STRPTIME validation Thanks to Masahiro Nagano and fbis. @@ -16,10 +19,10 @@ fixed to use Scalar::Util::blessed instead of UNIVERSAL::isa because of its unexpected work on perl 5.8.0. Thanks to Toru Yamaguchi - + allow to handle 0 on 'BETWEEN' validation Thanks to Masahiro Nagano. - + 0.14 Mon Mar 13 03:19:00 2006 - added UINT validation Thanks to Tokuhirom. Index: lib/FormValidator/Simple.pm =================================================================== --- lib/FormValidator/Simple.pm (revision 3) +++ lib/FormValidator/Simple.pm (working copy) @@ -1,8 +1,9 @@ package FormValidator::Simple; use strict; -use base qw/Class::Accessor::Fast Class::Data::Inheritable/; +use base qw/Class::Accessor::Fast Class::Data::Inheritable Class::Data::Accessor/; use Class::Inspector; use UNIVERSAL::require; +use Scalar::Util qw/blessed/; use FormValidator::Simple::Results; use FormValidator::Simple::Exception; use FormValidator::Simple::Data; @@ -13,10 +14,9 @@ our $VERSION = '0.16'; -__PACKAGE__->mk_accessors(qw/data prof results/); +__PACKAGE__->mk_classaccessors(qw/data prof results/); +__PACKAGE__->mk_classaccessor(messages => FormValidator::Simple::Messages->new); -__PACKAGE__->mk_classdata( messages => FormValidator::Simple::Messages->new ); - sub import { my $class = shift; foreach my $plugin (@_) { @@ -55,14 +55,22 @@ sub set_messages { my ($proto, $file) = @_; my $class = ref $proto || $proto; - $class->messages->load($file); + + if (blessed $proto) { + $proto->messages(FormValidator::Simple::Messages->new)->load($file); + $proto->results( FormValidator::Simple::Results->new( + messages => $proto->messages, + ) ); + } else { + $class->messages->load($file); + }; } sub set_message_format { my ($proto, $format) = @_; $format ||= ''; - my $class = ref $proto || $proto; - $class->messages->format($format); + + $proto->messages->format($format); } sub new { @@ -77,8 +85,9 @@ my ($self, @args) = @_; my $class = ref $self; $class->set_option(@args); + $self->results( FormValidator::Simple::Results->new( - messages => $class->messages, + messages => $self->messages, ) ); } @@ -100,7 +109,7 @@ sub check { my ($proto, $input, $prof, $options) = @_; $options ||= {}; - my $self = ref $proto ? $proto : $proto->new(%$options); + my $self = blessed $proto ? $proto : $proto->new(%$options); my $data = FormValidator::Simple::Data->new($input); my $prof_setting = FormValidator::Simple::Profile->new($prof); @@ -531,8 +540,6 @@ { some_data => [qw/param1 param2 param3/] } => ['ANY'] ] ); -=back - =item IN_ARRAY check if the food ordered is in menu Index: lib/FormValidator/Simple/Profile.pm =================================================================== --- lib/FormValidator/Simple/Profile.pm (revision 3) +++ lib/FormValidator/Simple/Profile.pm (working copy) @@ -6,9 +6,11 @@ sub _init { my($self, $prof) = @_; - while ( my($keys, $constraints) = splice(@$prof, 0, 2) ) { + + for (my $i = 0; $i <= $#{$prof}; $i += 2) { + my ($key, $constraints) = ($prof->[$i], $prof->[$i+1]); my $record = FormValidator::Simple::Profile::Record->new; - $record->set_keys($keys); + $record->set_keys($key); $record->set_constraints($constraints); $self->append($record); } Index: Makefile.PL =================================================================== --- Makefile.PL (revision 3) +++ Makefile.PL (working copy) @@ -6,6 +6,7 @@ 'Class::Accessor' => 0.22, 'Class::Inspector' => 1.13, 'Class::Data::Inheritable' => 0.04, + 'Class::Data::Accessor' => 0, 'UNIVERSAL::require' => 0.10, 'Mail::Address' => 0, 'Email::Valid' => 0.15, Index: META.yml =================================================================== --- META.yml (revision 3) +++ META.yml (working copy) @@ -7,6 +7,7 @@ requires: Class::Accessor: 0.22 Class::Data::Inheritable: 0.04 + Class::Data::Accessor: 0 Class::Inspector: 1.13 Date::Calc: 5.4 DateTime::Format::Strptime: 1.07 Index: t/07_simple.t =================================================================== --- t/07_simple.t (revision 3) +++ t/07_simple.t (working copy) @@ -1,5 +1,5 @@ use strict; -use Test::More tests => 23; +use Test::More tests => 24; use CGI; BEGIN { use_ok("FormValidator::Simple"); } @@ -64,3 +64,16 @@ ok($results3->invalid('hoge')); ok($results3->invalid( hoge => 'HOGE' )); + +# make sure check doesn't eat the profile +my $profile = [ + text => [qw/NOT_BLANK INT/], + int => [qw/NOT_BLANK INT/], +]; + +my $r3 = FormValidator::Simple->check( $q => $profile ); +is_deeply($profile, [ + text => [qw/NOT_BLANK INT/], + int => [qw/NOT_BLANK INT/], +]); + Index: t/22_messages.t =================================================================== --- t/22_messages.t (revision 3) +++ t/22_messages.t (working copy) @@ -1,9 +1,9 @@ use strict; -use Test::More tests => 6; +use Test::More tests => 16; BEGIN{ use_ok("FormValidator::Simple") } use CGI; -FormValidator::Simple->set_messages( { +my $data = { DEFAULT => { data4 => { DEFAULT => 'input data4', @@ -22,8 +22,10 @@ NOT_BLANK => 'input data3', }, }, -} ); +}; +FormValidator::Simple->set_messages( $data ); + my $q = CGI->new; $q->param( data1 => 'hoge' ); $q->param( data2 => '123' ); @@ -44,3 +46,58 @@ is($messages->[3], 'input data3'); is($messages->[4], 'input data4'); + +# check that messages on object don't trash class messages +my $fvs = FormValidator::Simple->new; + +# inherit the classes messages +is_deeply(FormValidator::Simple->messages->{_data}, $data); + +# set your own +my $objdata = { + object => { + object1 => { + NOT_BLANK => 'not blank for object1', + }, + object2 => { + LENGTH => 'length wrong for object2', + } + } +}; + +# object has its messages +$fvs->set_messages( $objdata ); +is_deeply($fvs->messages->{_data}, $objdata); + +# class should be in tact +is_deeply(FormValidator::Simple->messages->{_data}, $data); + + +my $oq = CGI->new; +$oq->param( object1 => '' ); +$oq->param( object2 => 'abcdef' ); + +my $or = $fvs->check( $oq => [ + object1 => [ [qw/NOT_BLANK/] ], + object2 => [ [qw/LENGTH 1 2/] ] +] ); + +my $omessages = $or->messages('object'); +is($omessages->[0], 'not blank for object1'); +is($omessages->[1], 'length wrong for object2'); + + +# make sure the class verison still works: +my $nr = FormValidator::Simple->check( $q => [ + data1 => [qw/NOT_BLANK INT/, [qw/LENGTH 0 3/] ], + data2 => [qw/NOT_BLANK ASCII/, [qw/LENGTH 5/]], + data3 => [qw/NOT_BLANK/], + data4 => [qw/NOT_BLANK/], +] ); + +my $nmessages = $nr->messages('test'); +is($nmessages->[0], 'input integer for data1'); +is($nmessages->[1], 'data1 has wrong length'); +is($nmessages->[2], 'default error for data2'); +is($nmessages->[3], 'input data3'); +is($nmessages->[4], 'input data4');