|
Line 0
Link Here
|
| 0 |
- |
1 |
#!/usr/bin/perl |
|
|
2 |
|
| 3 |
# Copyright 2023 Rijksmuseum |
| 4 |
# |
| 5 |
# This file is part of Koha. |
| 6 |
# |
| 7 |
# Koha is free software; you can redistribute it and/or modify it |
| 8 |
# under the terms of the GNU General Public License as published by |
| 9 |
# the Free Software Foundation; either version 3 of the License, or |
| 10 |
# (at your option) any later version. |
| 11 |
# |
| 12 |
# Koha is distributed in the hope that it will be useful, but |
| 13 |
# WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 |
# GNU General Public License for more details. |
| 16 |
# |
| 17 |
# You should have received a copy of the GNU General Public License |
| 18 |
# along with Koha; if not, see <http://www.gnu.org/licenses>. |
| 19 |
|
| 20 |
use Modern::Perl; |
| 21 |
use Data::Dumper qw( Dumper ); |
| 22 |
use Test::More tests => 5; |
| 23 |
use Test::Exception; |
| 24 |
use Test::Warn; |
| 25 |
use Try::Tiny; |
| 26 |
|
| 27 |
use Koha::Validator; |
| 28 |
use Koha::Email; |
| 29 |
|
| 30 |
our $validator; |
| 31 |
|
| 32 |
subtest 'new' => sub { |
| 33 |
plan tests => 2; |
| 34 |
|
| 35 |
$validator = Koha::Validator->new; |
| 36 |
is( ref($validator), 'Koha::Validator', 'Object type' ); |
| 37 |
is( $validator->option('throw_exception'), 1, 'Check if option has default value' ); |
| 38 |
}; |
| 39 |
|
| 40 |
subtest 'option' => sub { |
| 41 |
plan tests => 10; |
| 42 |
|
| 43 |
is( ref( $validator->option ), 'Koha::Validator', 'Called option without parameters' ); |
| 44 |
is( $validator->option('a'), undef, 'Check unknown option' ); |
| 45 |
is( $validator->option('break_on_error'), 1, 'Check option break_on_error' ); |
| 46 |
is( $validator->option('replace_inline'), 0, 'Check option replace_inline' ); |
| 47 |
|
| 48 |
is( ref $validator->option( a => 1 ), 'Koha::Validator', 'Trying to set unknown option' ); |
| 49 |
is( $validator->option('a'), undef, 'Check unknown option again' ); |
| 50 |
|
| 51 |
$validator->option( a => 1, b => 2, replace_inline => 3, REPLACE_INLINE => 0 ); # last uc option incorrect |
| 52 |
is( $validator->option('replace_inline'), 1, 'Check option replace_inline after setting with hash' ); |
| 53 |
$validator->option( { a => 1, b => 2, break_on_error => 0, replace_inline => undef } ); |
| 54 |
is( $validator->option('replace_inline'), 0, 'Check option replace_inline after setting with hashref' ); |
| 55 |
is( $validator->option( reset => 1 )->option('break_on_error'), 1, 'break_on_error has been reset' ); |
| 56 |
throws_ok { $validator->option( a => 1, b => 2, 3 ) } 'Koha::Exceptions::BadParameter', 'Bad number of parameters'; |
| 57 |
}; |
| 58 |
|
| 59 |
subtest 'load' => sub { |
| 60 |
plan tests => 15; |
| 61 |
|
| 62 |
throws_ok { $validator->load } 'Koha::Exceptions::BadParameter', |
| 63 |
'No input for load'; |
| 64 |
throws_ok { $validator->load('wrong') } 'Koha::Exceptions::BadParameter', |
| 65 |
'Wrong input for load'; |
| 66 |
throws_ok { $validator->load( { defaultrule => undef } ) } 'Koha::Exceptions::BadParameter', |
| 67 |
'Rule should not be undefined'; |
| 68 |
throws_ok { $validator->load( { defaultrule => 'test' } ) } 'Koha::Exceptions::BadParameter', |
| 69 |
'The alias \'test\' cannot be resolved'; |
| 70 |
|
| 71 |
$validator->option( throw_exception => 0, allow_missing_rules => 1 ); |
| 72 |
|
| 73 |
is( ref $validator->load( { defaultrule => {} } ), 'Koha::Validator', 'Load returned object' ); |
| 74 |
ok( $validator->check( { 1 => 2 } ), 'Checked hash with empty defaultrule' ); |
| 75 |
ok( $validator->check( [ 1, 2 ] ), 'Checked array with empty defaultrule' ); |
| 76 |
$validator->load( { defaultrule => { code => sub { 1 } } } ); |
| 77 |
ok( $validator->check( { 1 => 2 } ), 'Checked hash with true sub' ); |
| 78 |
ok( $validator->check( [ 1, 2 ] ), 'Checked array with true sub' ); |
| 79 |
$validator->load( { defaultrule => { code => sub { } } } ); |
| 80 |
ok( !$validator->check( { 1 => 2 } ), 'Checked hash with false sub' ); |
| 81 |
ok( !$validator->check( [ 1, 2 ] ), 'Checked array with false sub' ); |
| 82 |
|
| 83 |
$validator->unload->load( { my_column => { values => [ 2, 3 ] } } ); |
| 84 |
ok( $validator->check( [1] ), 'Checked array without defaultrule' ); |
| 85 |
ok( $validator->check( { my_column => 3 } ), 'Checked hash with single rule' ); |
| 86 |
|
| 87 |
# Add standard rules, overwrite |
| 88 |
$Koha::Validator::standard_rules = { rule1 => { regexp => qr/\D/ }, rule2 => { defaultvalue => 1 } }; |
| 89 |
ok( $validator->unload->check( { rule1 => '2a' } ), 'Standard rule applied' ); |
| 90 |
$validator->load( { rule1 => { postfilter => sub { 2 } } } ); |
| 91 |
is_deeply( |
| 92 |
$validator->check( { rule1 => '2a', rule2 => undef } ), { rule1 => 2, rule2 => 1 }, |
| 93 |
'Rule1 overwritten' |
| 94 |
); |
| 95 |
$Koha::Validator::standard_rules = {}; |
| 96 |
|
| 97 |
$validator->unload->option( reset => 1 ); |
| 98 |
}; |
| 99 |
|
| 100 |
subtest 'check' => sub { |
| 101 |
plan tests => 19; |
| 102 |
|
| 103 |
throws_ok { $validator->check } 'Koha::Exceptions::BadParameter', 'No values to check'; |
| 104 |
throws_ok { $validator->check(1) } 'Koha::Exceptions::BadParameter', 'Check does only accept hashref or arrayref'; |
| 105 |
ok( $validator->check( {} ), 'Empty hash validated' ); |
| 106 |
ok( $validator->check( [] ), 'Empty list validated' ); |
| 107 |
|
| 108 |
subtest 'arrayref' => sub { |
| 109 |
$validator->load( { defaultrule => { values => [ 1, 2, 3 ] } } )->option( throw_exception => 0 ); |
| 110 |
ok( $validator->check( [ 1, 2, '2', 3, '1' ] ), 'Check array of integers and characters with defaultrule' ); |
| 111 |
|
| 112 |
my $code = sub { |
| 113 |
my ( $value, $index ) = @_; |
| 114 |
return ( $value == 2 or $value == 3 ) if $index == 0; |
| 115 |
return $value == 2 if $index == 1; |
| 116 |
return $value =~ qr/test/ if $index == 2; |
| 117 |
return 0 if $index == 3; |
| 118 |
return 0; |
| 119 |
}; |
| 120 |
$validator->load( { defaultrule => { ref => '', code => $code } } ); |
| 121 |
|
| 122 |
ok( !$validator->check( [ 1, ] ), 'Checked array with one element' ); |
| 123 |
is( $validator->errors(0), 'CODE', 'Check error' ); |
| 124 |
ok( $validator->check( [ 3, ] ), 'Checked another array with one element' ); |
| 125 |
ok( !$validator->check( [ [1] ] ), 'Checked another array with one nested arrayref' ); |
| 126 |
ok( !$validator->check( [ 2, 3 ] ), 'Checked array with two elements, fallback fails on index 1' ); |
| 127 |
is( $validator->errors(1), 'CODE', 'Check error for two elements array' ); |
| 128 |
ok( $validator->check( [ 2, '2', 'testcase' ] ), 'Checked array with three elements' ); |
| 129 |
ok( !$validator->check( [ 2, '2', 'textcase' ] ), 'Checked another array with three elements' ); |
| 130 |
is( $validator->errors(2), 'CODE', 'Check error for three elements array' ); |
| 131 |
ok( !$validator->check( [ 2, '2', 'testcase', 'index3' ] ), 'Checked array with four elements' ); |
| 132 |
is( $validator->errors(3), 'CODE', 'Check error for four elements array' ); |
| 133 |
|
| 134 |
$validator->unload->option( reset => 1 ); |
| 135 |
}; |
| 136 |
|
| 137 |
subtest 'hashref' => sub { |
| 138 |
my $rules = { |
| 139 |
digits_only => { regexp => qr/^\d+$/ }, |
| 140 |
email => { code => sub { Koha::Email->is_valid( $_[0] ) } }, |
| 141 |
test01 => 'digits_only', |
| 142 |
test02 => { values => [ 1, 2 ] }, |
| 143 |
test03 => { code => sub { 0 } }, |
| 144 |
test04 => 'email', |
| 145 |
test05 => { regexp => qr/test/ }, |
| 146 |
}; |
| 147 |
$validator->load($rules); |
| 148 |
my $data = { test01 => 2, test02 => 1, test04 => 'marcel@test.nl', test05 => 'includes test word' }; |
| 149 |
try { $validator->check($data); ok( 1, 'validator green' ) } |
| 150 |
catch { ok(0) }; |
| 151 |
is( $validator->errors, 0, 'No errors encountered' ); |
| 152 |
|
| 153 |
$data = { test01 => 2, test02 => 1, test03 => 'nomatterwhat' }; |
| 154 |
try { $validator->check($data); ok(0) } |
| 155 |
catch { ok( 1, 'validator red' ) }; |
| 156 |
is( $validator->errors('test03'), 'CODE', 'Check error code for test03' ); |
| 157 |
|
| 158 |
my $code = sub { return Koha::Email->is_valid( $_[0] ) && $_[0] !~ /[\`]/ }; |
| 159 |
$validator->load( { defaultrule => 'email', email => { code => $code } } ); |
| 160 |
$data = { email => 'withbacktick`ls`@test.com' }; |
| 161 |
try { $validator->check($data); ok(0) } |
| 162 |
catch { is( $validator->errors('email'), 'CODE', 'validator red for email with backticks' ) }; |
| 163 |
ok( $validator->check( { emailpro => 'john@doe.com' } ), 'John Doe never fails' ); |
| 164 |
$validator->unload->option( reset => 1 ); |
| 165 |
}; |
| 166 |
|
| 167 |
subtest 'mandatory' => sub { |
| 168 |
$validator->option( throw_exception => 0 ); |
| 169 |
$validator->load( { test => { mandatory => 1 }, test2 => {}, test3 => { mandatory => 0 } } ); |
| 170 |
ok( !$validator->check( {} ), 'Missing test column' ); |
| 171 |
is( $validator->errors('test'), 'MANDATORY', 'Check field' ); |
| 172 |
ok( $validator->check( { test => 1, test2 => 0 } ), 'only test should be present' ); |
| 173 |
$validator->unload->option( reset => 1 ); |
| 174 |
}; |
| 175 |
|
| 176 |
subtest 'ref' => sub { |
| 177 |
$validator->option( break_on_error => 0, throw_exception => 0 ); |
| 178 |
$validator->load( { a => { ref => q{} }, b => { ref => 'HASH' }, c => {}, d => { ref => [1] } } ); |
| 179 |
ok( !$validator->check( { a => [], b => q{}, c => 1 } ), 'a and b should fail' ); |
| 180 |
is_deeply( $validator->errors( code => 'REF' ), [ 'a', 'b' ], 'Check wrong fields' ); |
| 181 |
ok( !$validator->check( { d => 1 } ), 'Wrong ref definition, scalar expected' ); |
| 182 |
$validator->unload->option( reset => 1 ); |
| 183 |
}; |
| 184 |
|
| 185 |
subtest 'defaultvalue' => sub { |
| 186 |
$validator->load( { defaultrule => { defaultvalue => 1 } } ); |
| 187 |
is_deeply( $validator->check( [ undef, q{}, 0, 2 ] ), [ 1, q{}, 0, 2 ], 'defaultvalue on array' ); |
| 188 |
is_deeply( $validator->check( { a => undef, b => q{} } ), { a => 1, b => q{} }, 'defaultvalue on hash' ); |
| 189 |
$validator->unload; |
| 190 |
}; |
| 191 |
|
| 192 |
subtest 'prefilter' => sub { |
| 193 |
$validator->load( { test => { prefilter => sub { $_[0] =~ s/\s//g; $_[0] } } } ); |
| 194 |
is_deeply( $validator->check( { test => 'a b c ' } ), { test => 'abc' }, 'Prefilter removed spaces' ); |
| 195 |
$validator->load( { test => { prefilter => undef } } ); |
| 196 |
throws_ok { $validator->check( { test => 'a b c ' } ) } 'Koha::Exceptions::BadParameter', |
| 197 |
'Wrong prefilter, no coderef'; |
| 198 |
$validator->unload; |
| 199 |
}; |
| 200 |
|
| 201 |
subtest 'values' => sub { |
| 202 |
$validator->option( break_on_error => 0, throw_exception => 0 ); |
| 203 |
|
| 204 |
# Note: values for a and b are bad definitions! |
| 205 |
$validator->load( { a => { values => undef }, b => { values => 1 }, c => { values => [ 10, 20 ] } } ); |
| 206 |
$validator->check( { a => 1, b => 1, c => 1 } ); |
| 207 |
is_deeply( $validator->errors( code => 'VALUES' ), [ 'a', 'b', 'c' ], 'a, b and c failed' ); |
| 208 |
$validator->unload; |
| 209 |
$validator->load( { defaultrule => { values => [ 1, 2 ] }, c => { values => [3] } } ); |
| 210 |
ok( $validator->check( { a => 1, b => 2, c => 3 } ), 'All passed now' ); |
| 211 |
|
| 212 |
$validator->unload->option( reset => 1 ); |
| 213 |
}; |
| 214 |
|
| 215 |
subtest 'regexp' => sub { |
| 216 |
$validator->option( break_on_error => 0 ); |
| 217 |
$validator->load( { defaultrule => { regexp => '/test/i' } } ); # bad defined |
| 218 |
try { $validator->check( [1] ); ok(0) } |
| 219 |
catch { ok( 1, 'Bad regex definition' ) }; |
| 220 |
$validator->load( { defaultrule => { regexp => qr/\d\D/ } } ); |
| 221 |
try { $validator->check( [ '123', '1b', 'ab2' ] ); ok(0) } |
| 222 |
catch { ok( 1, 'Should fail on some elements' ) }; |
| 223 |
is_deeply( $validator->errors( code => 'REGEXP' ), [ 0, 2 ], 'Two elements failed' ); |
| 224 |
$validator->unload->option( reset => 1 ); |
| 225 |
}; |
| 226 |
|
| 227 |
subtest 'code' => sub { |
| 228 |
$validator->load( { test1 => { code => undef }, test2 => { code => 1 } } ); # bad defined |
| 229 |
try { $validator->check( { test1 => 1 } ); ok(0) } |
| 230 |
catch { ok( 1, 'Should fail on code undef' ) }; |
| 231 |
try { $validator->check( { test2 => 2 } ); ok(0) } |
| 232 |
catch { ok( 1, 'Should fail on code == 1' ) }; |
| 233 |
$validator->load( |
| 234 |
{ defaultrule => { code => sub { $_[0] =~ /a/ } }, test2 => { code => sub { $_[0] =~ /b/ } } } ); |
| 235 |
my $res = $validator->check( { test => 'Aa', test2 => 'bB' } ); |
| 236 |
$validator->unload; |
| 237 |
}; |
| 238 |
|
| 239 |
subtest 'postfilter' => sub { |
| 240 |
$validator->option( throw_exception => 0 ); |
| 241 |
$validator->load( |
| 242 |
{ |
| 243 |
defaultrule => { |
| 244 |
prefilter => sub { $_[0] =~ s/\s//g; $_[0] }, |
| 245 |
postfilter => sub { uc $_[0] }, |
| 246 |
}, |
| 247 |
test => {}, |
| 248 |
test3 => { |
| 249 |
postfilter => sub { die }, |
| 250 |
}, |
| 251 |
} |
| 252 |
); |
| 253 |
my $results = $validator->check( { test => 'a b c ', test2 => 'd e' } ); |
| 254 |
is( $results->{test}, 'a b c ', 'Field \'test\' does not hit postfilter' ); |
| 255 |
is( $results->{test2}, 'DE', 'Test2 passed postfilter of defaultrule' ); |
| 256 |
|
| 257 |
# what if postfilter crashes |
| 258 |
ok( !$validator->check( { test => 'a b c ', test2 => 'd e', test3 => 'f g' } ), 'Should stumble over die' ); |
| 259 |
is( $validator->errors('test3'), 'POSTFILTER', 'Check which field did not validate' ); |
| 260 |
|
| 261 |
$validator->unload->option( reset => 1 ); |
| 262 |
}; |
| 263 |
|
| 264 |
subtest 'allow_missing_rules' => sub { |
| 265 |
$validator->option( allow_missing_rules => 1, throw_exception => 0 ); |
| 266 |
$validator->load( { test => { regexp => qr/\d/ } } ); |
| 267 |
ok( $validator->check( { test => 2 } ), 'Validated' ); |
| 268 |
ok( $validator->check( { tezt => 3 } ), 'No rule for tezt is allowed here' ); |
| 269 |
$validator->option( allow_missing_rules => 0 ); |
| 270 |
ok( !$validator->check( { tezt => 3 } ), 'No rule for tezt no longer allowed' ); |
| 271 |
$validator->unload->option( reset => 1 ); |
| 272 |
}; |
| 273 |
|
| 274 |
subtest 'break_on_error' => sub { |
| 275 |
$validator->option( throw_exception => 0 ); |
| 276 |
$validator->load( { a => { values => [ 1, 2 ] }, b => { values => [ 2, 3 ] } } ); |
| 277 |
ok( !$validator->check( { a => 0, b => 0 } ), 'Wrong values for a and b' ); |
| 278 |
is_deeply( $validator->errors( array => 1 ), ['a'], 'Stopped when a was wrong' ); |
| 279 |
$validator->option( break_on_error => 0 ); |
| 280 |
ok( !$validator->check( { a => 0, b => 0 } ), 'Check a and b again' ); |
| 281 |
is_deeply( $validator->errors( array => 1 ), [ 'a', 'b' ], 'Found a and b now' ); |
| 282 |
$validator->unload->option( reset => 1 ); |
| 283 |
}; |
| 284 |
|
| 285 |
subtest 'replace_inline' => sub { |
| 286 |
$validator->option( replace_inline => 0, throw_exception => 0 ); |
| 287 |
$validator->load( { defaultrule => { ref => q{}, postfilter => sub { $_[0] + 1 } } } ); |
| 288 |
|
| 289 |
my $array = [ 1, 2 ]; |
| 290 |
my $hash = { a => 1, b => 2 }; |
| 291 |
is_deeply( $validator->check($array), [ 2, 3 ], 'Check results array' ); |
| 292 |
is_deeply( $validator->check($hash), { a => 2, b => 3 }, 'Check results hash' ); |
| 293 |
is_deeply( $array, [ 1, 2 ], 'Original array untouched' ); |
| 294 |
is_deeply( $hash, { a => 1, b => 2 }, 'Original hash untouched' ); |
| 295 |
|
| 296 |
$validator->option( replace_inline => 1 ); |
| 297 |
|
| 298 |
# First, add an invalid argument (reference); check and test if not modified |
| 299 |
$array = [ 1, 2, {} ]; |
| 300 |
$hash = { a => 1, b => 2, c => [] }; |
| 301 |
ok( !$validator->check($array), 'Array does no longer validate' ); |
| 302 |
ok( !$validator->check($hash), 'Hash does no longer validate' ); |
| 303 |
is_deeply( $array, [ 1, 2, {} ], 'Original array untouched' ); |
| 304 |
is_deeply( $hash, { a => 1, b => 2, c => [] }, 'Original hash untouched' ); |
| 305 |
|
| 306 |
# Pass valid content, and test if modified |
| 307 |
$array = [ 1, 2 ]; |
| 308 |
$hash = { a => 1, b => 2 }; |
| 309 |
$validator->check($array); |
| 310 |
$validator->check($hash); |
| 311 |
is_deeply( $array, [ 2, 3 ], 'Original array modified' ); |
| 312 |
is_deeply( $hash, { a => 2, b => 3 }, 'Original hash modified' ); |
| 313 |
|
| 314 |
$validator->unload->option( reset => 1 ); |
| 315 |
}; |
| 316 |
|
| 317 |
subtest 'restrict_postfilter' => sub { |
| 318 |
# Example of 3 fields, a == b + c; note that validations starts with a.. |
| 319 |
# Postfilter can only validate by throwing an exception. |
| 320 |
my $code = sub { my ( $val, $idx, $res ) = @_; die unless $res->{a} == $res->{b} + $val; $val }; |
| 321 |
$validator->load( { a => {}, b => {}, c => { postfilter => $code } } ); |
| 322 |
ok( $validator->check( { a => 3, b => 2, c => 1 } ), 'Passes' ); |
| 323 |
try { $validator->check( { a => 4, b => 2, c => 1 } ); ok(0) } |
| 324 |
catch { ok( 1, 'Should fail' ) }; |
| 325 |
|
| 326 |
# Now try to make postfilter correct/enforce the value of a (restrict_postfilter on) |
| 327 |
$code = sub { my ( $val, $idx, $res ) = @_; $res->{a} = $res->{b} + $val; $val }; |
| 328 |
$validator->load( { a => {}, b => {}, c => { postfilter => $code } } ); |
| 329 |
my $res = $validator->check( { a => 4, b => 2, c => 1 } ); |
| 330 |
is( $res->{a}, 4, 'Postfilter failed to adjust the value of a' ); |
| 331 |
# Correct attempt: restrict_postfilter off |
| 332 |
$validator->option( restrict_postfilter => 0 ); |
| 333 |
$res = $validator->check( { a => 4, b => 2, c => 1 } ); |
| 334 |
is( $res->{a}, 3, 'Postfilter did adjust the value of a, restrict_postfilter off' ); |
| 335 |
|
| 336 |
$validator->unload->option( reset => 1 ); |
| 337 |
}; |
| 338 |
|
| 339 |
subtest 'throw_exception' => sub { |
| 340 |
try { $validator->check( [1] ); ok(0) } |
| 341 |
catch { ok( 1, 'Exception for array without defaultrule' ) }; |
| 342 |
$validator->option( throw_exception => 0 ); |
| 343 |
my $res; |
| 344 |
lives_ok { $res = $validator->check( [1] ) } 'No exception for same check'; |
| 345 |
is( $res, undef, 'Returned undef' ); |
| 346 |
$validator->unload->option( reset => 1 ); |
| 347 |
}; |
| 348 |
}; |
| 349 |
|
| 350 |
subtest 'errors' => sub { |
| 351 |
plan tests => 14; |
| 352 |
$validator->option( throw_exception => 0 ); |
| 353 |
$validator->load( |
| 354 |
{ |
| 355 |
defaultrule => { ref => q{}, values => [ 1, 2 ], regexp => qr/[3-9]/ }, |
| 356 |
test => { mandatory => 1, code => sub { } } |
| 357 |
} |
| 358 |
); |
| 359 |
ok( !$validator->check( [ 0, {}, 2 ] ), 'Three elements should fail' ); |
| 360 |
is( $validator->errors, 1, 'Check error count, break on' ); |
| 361 |
is( $validator->errors(0), 'VALUES', 'Check error of index 0, break on' ); |
| 362 |
is_deeply( $validator->errors( hash => 1 ), { 0 => 'VALUES' }, 'Check hash of errors, break on' ); |
| 363 |
is_deeply( $validator->errors( list => 1 ), [0], 'Check list of errors, break on' ); |
| 364 |
is_deeply( $validator->errors( code => 'REF' ), [], 'Check list of errors for REF, break on' ); |
| 365 |
is_deeply( $validator->errors( code => 'VALUES' ), [0], 'Check list of errors for VALUES, break on' ); |
| 366 |
|
| 367 |
$validator->option( break_on_error => 0 ); |
| 368 |
ok( !$validator->check( [ 0, {}, 2 ] ), 'Three elements should fail again' ); |
| 369 |
is( $validator->errors, 3, 'Check error count, break off' ); |
| 370 |
is( $validator->errors(2), 'REGEXP', 'Check error of index 2, break off' ); |
| 371 |
is_deeply( |
| 372 |
$validator->errors( hash => 1 ), { 0 => 'VALUES', 1 => 'REF', 2 => 'REGEXP' }, |
| 373 |
'Check hash of errors, break off' |
| 374 |
); |
| 375 |
is_deeply( $validator->errors( array => 1 ), [ 0, 1, 2 ], 'Check array of errors, break off' ); |
| 376 |
is_deeply( $validator->errors( code => 'REF' ), [1], 'Check list of errors for REF, break off' ); |
| 377 |
is_deeply( $validator->errors( code => 'CODE' ), [], 'Check list of errors for CODE, break off' ); |
| 378 |
$validator->unload->option( reset => 1 ); |
| 379 |
}; |