diff --git a/build/api/core/Checker.php b/build/api/core/Checker.php index d46ed15..fa786dd 100644 --- a/build/api/core/Checker.php +++ b/build/api/core/Checker.php @@ -48,12 +48,15 @@ /* [2] Si de type ARRAY(type_elements) =========================================================*/ - if( preg_match('/^array<(.+)>$/', $type, $match) ){ + if( preg_match('/^array(?:<(.+)>)?$/', $type, $match) ){ // Si c'est pas un tableau on retourne une erreur if( !is_array($value) ) return false; + // Si c'est un tableau et que 'array' recu + if( $type == 'array' ) + return true; $elements_type = $match[1]; @@ -78,7 +81,7 @@ // Entier positif (id dans BDD) case 'id': - return $checker && is_numeric($value) && $value <= 2147483647 && $value >= 0; + return $checker && is_numeric($value) && intval($value) == $value && $value <= 2147483647 && $value >= 0; break; // String quelconque (peut etre vide) @@ -92,7 +95,7 @@ // Hash sha1/md5 case 'hash': - return $checker && is_string($value) && preg_match('/^[\da-f]+$/i', $value) && (strlen($value) == 64 || strlen($value) == 128); + return $checker && is_string($value) && preg_match('/^[\da-f]+$/i', $value) && in_array(strlen($value), [64,128]); break; case 'alphanumeric': @@ -104,7 +107,7 @@ break; case 'status': - return $checker && is_numeric($value) && floor($value) == $value && $value >= 0 && $value <= 100; + return $checker && is_numeric($value) && intval($value) == $value && $value >= 0 && $value <= 100; break; case 'rfid': diff --git a/spec/build/api/core/CheckerSpec.php b/spec/build/api/core/CheckerSpec.php index 74ae886..cbd3f79 100644 --- a/spec/build/api/core/CheckerSpec.php +++ b/spec/build/api/core/CheckerSpec.php @@ -12,7 +12,7 @@ ---------------------------------------------------------*/ context('* unknown type', function(){ - it('do not pass unknown type with any value', function(){ + it('fail with any value', function(){ expect(Checker::run('unknown_type', 'someString' ))->toBeFalsy(); expect(Checker::run('unknown_type', 123 ))->toBeFalsy(); @@ -30,7 +30,7 @@ ---------------------------------------------------------*/ context('* mixed', function(){ - it('pass type="mixed" with any type', function(){ + it('pass with any type', function(){ expect(Checker::run('mixed', 'someString' ))->toBeTruthy(); expect(Checker::run('mixed', 123 ))->toBeTruthy(); @@ -41,7 +41,7 @@ }); - it('do not pass type="mixed" with null', function(){ + it('fail with null', function(){ expect(Checker::run('mixed', null))->toBeFalsy(); @@ -53,28 +53,53 @@ ---------------------------------------------------------*/ context('* id', function(){ - it('pass type="id" whith any integer number (string or int)', function(){ + it('pass when numeric (int or string)', function(){ - expect(Checker::run('id', '123' ))->toBeTruthy(); - expect(Checker::run('id', 123 ))->toBeTruthy(); + $int = 12; + $string = '12'; + + expect($int)->toBeA('int'); + expect(Checker::run('id', $int))->toBeTruthy(); + + expect($string)->toBeA('string'); + expect(Checker::run('id', $string))->toBeTruthy(); }); - it('do not pass type="id" whith decimal value (string or int)', function(){ + it('pass when decimal with 0 as decimal part (double or string)', function(){ - expect(Checker::run('id', '1.23' ))->toBeFalsy(); - expect(Checker::run('id', 1.23 ))->toBeFalsy(); + $int = 12.0; + $string = '12.0'; + + expect($int)->toBeA('double'); + expect(Checker::run('id', $int))->toBeTruthy(); + + expect($string)->toBeA('string'); + expect(Checker::run('id', $string))->toBeTruthy(); }); - it('pass type="id" whith boundaries', function(){ + it('fail when decimal (double or string)', function(){ + + $int = 12.5; + $string = '12.5'; + + expect($int)->toBeA('double'); + expect(Checker::run('id', $int))->toBeFalsy(); + + expect($string)->toBeA('string'); + expect(Checker::run('id', $string))->toBeFalsy(); + + }); + + it('pass at boundaries', function(){ expect(Checker::run('id', 0 ))->toBeTruthy(); expect(Checker::run('id', 2147483647 ))->toBeTruthy(); }); - it('do not pass type="id" whith not match out-of-boundaries', function(){ + it('fail with out-of-boundaries', function(){ expect(Checker::run('id', 0-1 ))->toBeFalsy(); expect(Checker::run('id', 2147483647+1 ))->toBeFalsy(); @@ -87,14 +112,14 @@ ---------------------------------------------------------*/ context('* text', function(){ - it('pass type="text" with any string', function(){ + it('pass with any string', function(){ expect(Checker::run('text', '123' ))->toBeTruthy(); expect(Checker::run('text', '123'.'123' ))->toBeTruthy(); }); - it('pass type="text" with empty string', function(){ + it('pass with empty string', function(){ $empty_str = ''; expect($empty_str)->toHaveLength(0); @@ -102,14 +127,30 @@ }); - it('do not pass type="text" when not string', function(){ + it('fail when not a string', function(){ - expect(Checker::run('text', [] ))->toBeFalsy(); - expect(Checker::run('text', 1 ))->toBeFalsy(); - expect(Checker::run('text', 1.23 ))->toBeFalsy(); - expect(Checker::run('text', true ))->toBeFalsy(); - expect(Checker::run('text', false ))->toBeFalsy(); - expect(Checker::run('text', new StdClass() ))->toBeFalsy(); + $vars = [ + 'array' => [], + 'int' => 1, + 'double' => 1.23, + 'boolean' => true, + 'object' => new StdClass(), + 'null' => null + ]; + + foreach($vars as $type=>$value){ + + expect($value)->toBeA($type); + expect(Checker::run('text', $value))->toBeFalsy(); + + } + + // expect(Checker::run('text', [] ))->toBeFalsy(); + // expect(Checker::run('text', 1 ))->toBeFalsy(); + // expect(Checker::run('text', 1.23 ))->toBeFalsy(); + // expect(Checker::run('text', true ))->toBeFalsy(); + // expect(Checker::run('text', false ))->toBeFalsy(); + // expect(Checker::run('text', new StdClass() ))->toBeFalsy(); }); @@ -120,7 +161,6 @@ context('* hash', function(){ given('sizes', function(){ return [ - 40 => 'sha1', 64 => 'sha256', 128 => 'sha512' ]; @@ -128,7 +168,7 @@ }); - it('do not pass when -40/64/128 char hash', function(){ + it('fail when -64/128 char hash', function(){ foreach($this->sizes as $size=>$sha){ @@ -142,7 +182,7 @@ }); - it('pass when 40/64/128 char hash', function(){ + it('pass when 64/128 char hash', function(){ foreach($this->sizes as $size=>$sha){ @@ -155,7 +195,7 @@ }); - it('do not pass when +40/64/128 char hash', function(){ + it('fail when +64/128 char hash', function(){ foreach($this->sizes as $size=>$sha){ @@ -169,7 +209,7 @@ }); - it('do not pass when incorrect character', function(){ + it('fail when incorrect character', function(){ $hash = hash('sha256', 'someClearText'); $hash[1] = 'g'; @@ -184,7 +224,7 @@ ---------------------------------------------------------*/ context('* mail', function(){ - it('do not pass type="mail" with out-of-boundaries elements match', function(){ + it('fail with out-of-boundaries elements', function(){ expect(Checker::run('mail', '@b.cd'))->toBeFalsy(); expect(Checker::run('mail', 'a@.cd'))->toBeFalsy(); @@ -193,7 +233,7 @@ }); - it('pass type="mail" with max length', function(){ + it('pass with max length', function(){ $mail = str_repeat('a', 45).'@b.cd'; @@ -202,7 +242,7 @@ }); - it('do not pass type="mail" with more than max length', function(){ + it('fail with more than max length', function(){ $mail = str_repeat('a', 46).'@b.cd'; @@ -211,7 +251,7 @@ }); - it('pass type="mail" with minimum match', function(){ + it('pass with minimum match', function(){ expect(Checker::run('mail', 'a@b.cd'))->toBeTruthy(); expect(Checker::run('mail', 'a@b.cdef'))->toBeTruthy(); @@ -236,19 +276,19 @@ }); - it('do not pass when not alphanumeric (space/,)', function(){ + it('fail when not alphanumeric (space/,)', function(){ expect(Checker::run('alphanumeric', 'abcz0129-. '))->toBeFalsy(); expect(Checker::run('alphanumeric', 'abcz0129-.,'))->toBeFalsy(); }); - it('do not pass when empty', function(){ + it('pass when empty', function(){ $str = ''; expect($str)->toBeEmpty(); - expect(Checker::run('alphanumeric', $str))->toBeFalsy(); + expect(Checker::run('alphanumeric', $str))->toBeTruthy(); }); @@ -259,29 +299,26 @@ ---------------------------------------------------------*/ context('* letters', function(){ - it('pass when letters (letters/space/-)', function(){ + it('pass when : letter/number/space/./-/_', function(){ - expect(Checker::run('letters', 'abcz- - -a'))->toBeTruthy(); + expect(Checker::run('letters', 'abcz-0.9_a'))->toBeTruthy(); }); + it('pass when unicode', function(){ - it('do not pass when unicode', function(){ - - expect(Checker::run('letters', 'çèééàôò'))->toBeFalsy(); + expect(Checker::run('letters', 'çèééàôò'))->toBeTruthy(); }); - it('do not pass when not letters (./,/numbers)', function(){ + it('fail when not letters (,/;)', function(){ - expect(Checker::run('letters', 'abcz- - -a0'))->toBeFalsy(); - expect(Checker::run('letters', 'abcz- - -a9'))->toBeFalsy(); - expect(Checker::run('letters', 'abcz- - -a,'))->toBeFalsy(); - expect(Checker::run('letters', 'abcz- - -a.'))->toBeFalsy(); + expect(Checker::run('letters', 'abcz-0.9_a,'))->toBeFalsy(); + expect(Checker::run('letters', 'abcz-0.9_a;'))->toBeFalsy(); }); - it('do not pass when empty', function(){ + it('fail when empty', function(){ $str = ''; @@ -292,9 +329,537 @@ }); + /* (9) rfid + ---------------------------------------------------------*/ + context('* rfid', function(){ + + it('pass when 4 block id', function(){ + + expect(Checker::run('rfid', 'AB-CD-EF-09'))->toBeTruthy(); + + }); + + it('fail when 4 block id but lowercase', function(){ + + expect(Checker::run('rfid', 'ab-cd-ef-09'))->toBeFalsy(); + + }); + + it('pass when 6 block id', function(){ + + expect(Checker::run('rfid', 'AB-CD-EF-09-18-27'))->toBeTruthy(); + + }); + + it('fail when 4 block id but lowercase', function(){ + + expect(Checker::run('rfid', 'ab-cd-ef-09-18-27'))->toBeFalsy(); + + }); + + it('fail when 6 block id', function(){ + + expect(Checker::run('rfid', 'B-CD-EF-01-23-45'))->toBeFalsy(); + expect(Checker::run('rfid', 'AB-D-EF-01-23-45'))->toBeFalsy(); + expect(Checker::run('rfid', 'AB-CD-F-01-23-45'))->toBeFalsy(); + expect(Checker::run('rfid', 'AB-CD-EF-1-23-45'))->toBeFalsy(); + expect(Checker::run('rfid', 'AB-CD-EF-01-3-45'))->toBeFalsy(); + expect(Checker::run('rfid', 'AB-CD-EF-01-23-5'))->toBeFalsy(); + expect(Checker::run('rfid', 'ABCD-EF-01-23-45'))->toBeFalsy(); + expect(Checker::run('rfid', 'AB-CDEF-01-23-45'))->toBeFalsy(); + expect(Checker::run('rfid', 'AB-CD-EF01-23-45'))->toBeFalsy(); + expect(Checker::run('rfid', 'AB-CD-EF-0123-45'))->toBeFalsy(); + expect(Checker::run('rfid', 'AB-CD-EF-01-2345'))->toBeFalsy(); + + }); + + it('fail when incorrect char', function(){ + + expect(Checker::run('rfid', 'AB-CD-EG-01'))->toBeFalsy(); + expect(Checker::run('rfid', 'AB-CD-EH-01-23-45'))->toBeFalsy(); + + }); + + }); + + /* (10) Status + ---------------------------------------------------------*/ + context('* status', function(){ + + it('pass when numeric (int or string)', function(){ + + $int = 12; + $string = '12'; + + expect($int)->toBeA('int'); + expect(Checker::run('status', $int))->toBeTruthy(); + + expect($string)->toBeA('string'); + expect(Checker::run('status', $string))->toBeTruthy(); + + }); + + it('pass when decimal with 0 as decimal part (double or string)', function(){ + + $int = 12.0; + $string = '12.0'; + + expect($int)->toBeA('double'); + expect(Checker::run('status', $int))->toBeTruthy(); + + expect($string)->toBeA('string'); + expect(Checker::run('status', $string))->toBeTruthy(); + + }); + + it('fail when decimal (double or string)', function(){ + + $int = 12.5; + $string = '12.5'; + + expect($int)->toBeA('double'); + expect(Checker::run('status', $int))->toBeFalsy(); + + expect($string)->toBeA('string'); + expect(Checker::run('status', $string))->toBeFalsy(); + + }); + + it('pass when boundaries', function(){ + + expect(Checker::run('status', 0))->toBeTruthy(); + expect(Checker::run('status', '0'))->toBeTruthy(); + expect(Checker::run('status', 0.0))->toBeTruthy(); + expect(Checker::run('status', '0.0'))->toBeTruthy(); + + expect(Checker::run('status', 100))->toBeTruthy(); + expect(Checker::run('status', '100'))->toBeTruthy(); + expect(Checker::run('status', 100.0))->toBeTruthy(); + expect(Checker::run('status', '100.0'))->toBeTruthy(); + }); + + it('fail when out-of-boundaries', function(){ + + expect(Checker::run('status', -1))->toBeFalsy(); + expect(Checker::run('status', '-1'))->toBeFalsy(); + expect(Checker::run('status', -1.0))->toBeFalsy(); + expect(Checker::run('status', '-1.0'))->toBeFalsy(); + + expect(Checker::run('status', 101))->toBeFalsy(); + expect(Checker::run('status', '101'))->toBeFalsy(); + expect(Checker::run('status', 101.0))->toBeFalsy(); + expect(Checker::run('status', '101.0'))->toBeFalsy(); + }); + + }); + + /* (11) Boolean + ---------------------------------------------------------*/ + context('* boolean', function(){ + + it('pass when real boolean true/false', function(){ + + expect(Checker::run('boolean', true))->toBeTruthy(); + expect(Checker::run('boolean', false))->toBeTruthy(); + + }); + + it('faise when false boolean (int, string)', function(){ + + expect(Checker::run('boolean', 1))->toBeFalsy(); + expect(Checker::run('boolean', 0))->toBeFalsy(); + expect(Checker::run('boolean', ''))->toBeFalsy(); + expect(Checker::run('boolean', []))->toBeFalsy(); + + }); + + }); + + /* (12) Object + ---------------------------------------------------------*/ + context('* object', function(){ + + it('fail when empty real object', function(){ + + $obj = new StdClass(); + + expect((array) $obj)->toBeEmpty(); + expect(Checker::run('object', $obj))->toBeFalsy(); + + }); + + it('pass when non-empty real object', function(){ + + $obj = new StdClass(); + $obj->a = 10; + + expect((array) $obj)->not->toBeEmpty(); + expect(Checker::run('object', $obj))->toBeTruthy(); + + }); + + it('faise when false object (assoc. array)', function(){ + + expect(Checker::run('object', ['a'=>function(){}]))->toBeFalsy(); + + }); + + }); + + /* (13) Json + ---------------------------------------------------------*/ + context('* json', function(){ + + it('pass when valid json string', function(){ + + expect(Checker::run('json', '{}'))->toBeTruthy(); + expect(Checker::run('json', '{"a": true}'))->toBeTruthy(); + + }); + + it('fail when not a string', function(){ + + expect(Checker::run('json', 123 ))->toBeFalsy(); + expect(Checker::run('json', [1, 2] ))->toBeFalsy(); + expect(Checker::run('json', true ))->toBeFalsy(); + expect(Checker::run('json', false ))->toBeFalsy(); + expect(Checker::run('json', new StdClass() ))->toBeFalsy(); + expect(Checker::run('json', null ))->toBeFalsy(); + + }); + + it('fail when invalid json string', function(){ + + expect(Checker::run('json', ''))->toBeFalsy(); + expect(Checker::run('json', '{;}'))->toBeFalsy(); + expect(Checker::run('json', '{"a": true}.'))->toBeFalsy(); + + }); + + }); + + /* (14) numeric + ---------------------------------------------------------*/ + context('* numeric', function(){ + + it('pass when numeric (int, double, negative_int, or string)', function(){ + + $values = [ 0, 10, -10, 0.5, -1.5, '0', '10', '-10', '0.5', '-1.5' ]; + + foreach($values as $value) + expect(Checker::run('numeric', $value))->toBeTruthy(); + + }); + + it('pass when $value == null', function(){ + + $values = [ 0, '', [] ]; + + foreach($values as $value){ + + expect($value)->toEqual(null); + expect(Checker::run('numeric', $value))->toBeTruthy(); + + } + + }); + + it('pass when $value == "null"', function(){ + + expect(Checker::run('numeric', 'null'))->toBeTruthy(); + + }); + + }); + + /* (15) Varchar + ---------------------------------------------------------*/ + context('* varchar(start,stop)', function(){ + + given('values', function(){ return [ + 'ab', + 'abcdef', + 'abcdefkls023213\'/\\5\'7;658' + ]; + }); + + it('pass when boundaries matches', function(){ + + foreach($this->values as $value){ + $min = 0; + $max = strlen($value)+1; + expect(Checker::run("varchar($min,$max)", $value))->toBeTruthy(); + + } + }); + + it('pass when boundaries matches min length', function(){ + + foreach($this->values as $value){ + $min = strlen($value); + $max = strlen($value)+1; + expect(Checker::run("varchar($min,$max)", $value))->toBeTruthy(); + + } + }); + + it('pass when boundaries matches max length', function(){ + + foreach($this->values as $value){ + $min = 0; + $max = strlen($value); + expect(Checker::run("varchar($min,$max)", $value))->toBeTruthy(); + + } + }); + + it('fail when boundaries are over min length', function(){ + + foreach($this->values as $value){ + $min = strlen($value)+1; + $max = strlen($value)+2; + + expect($min)->toBeGreaterThan(strlen($value)); + expect(Checker::run("varchar($min,$max)", $value))->toBeFalsy(); + + } + + }); + + it('fail when boundaries are under max length', function(){ + + foreach($this->values as $value){ + $min = strlen($value)-2; + $max = strlen($value)-1; + + expect($max)->toBeLessThan(strlen($value)); + expect(Checker::run("varchar($min,$max)", $value))->toBeFalsy(); + + } + + }); + + }); + + /* (16) Varchar + flag + ---------------------------------------------------------*/ + context('* varchar(start,stop,letters)', function(){ + + given('values', function(){ return [ + 'ab123-23', + 'abcdef__-0.9', + 'abcz-0.9_a' + ]; + }); + + given('notletters', function(){ return [ + 'abcdefkls023213\'/\\5\'7;658', + 'abc;658', + 'abc$658' + ]; + }); + + it('pass when boundaries matches', function(){ + + foreach($this->values as $value){ + $min = 0; + $max = strlen($value)+1; + expect(Checker::run("varchar($min,$max,letters)", $value))->toBeTruthy(); + + } + }); + + it('pass when boundaries matches min length', function(){ + + foreach($this->values as $value){ + $min = strlen($value); + $max = strlen($value)+1; + expect(Checker::run("varchar($min,$max,letters)", $value))->toBeTruthy(); + + } + }); + + it('pass when boundaries matches max length', function(){ + + foreach($this->values as $value){ + $min = 0; + $max = strlen($value); + expect(Checker::run("varchar($min,$max,letters)", $value))->toBeTruthy(); + + } + }); + + it('fail when boundaries are over min length', function(){ + + foreach($this->values as $value){ + $min = strlen($value)+1; + $max = strlen($value)+2; + + expect($min)->toBeGreaterThan(strlen($value)); + expect(Checker::run("varchar($min,$max,letters)", $value))->toBeFalsy(); + + } + + }); + + it('fail when boundaries are under max length', function(){ + + foreach($this->values as $value){ + $min = strlen($value)-2; + $max = strlen($value)-1; + + expect($max)->toBeLessThan(strlen($value)); + expect(Checker::run("varchar($min,$max,letters)", $value))->toBeFalsy(); + + } + + }); + it('fail when boundaries matches + not letters (incorrect flag check)', function(){ + + foreach($this->notletters as $value){ + $min = 0; + $max = strlen($value)+1; + expect(Checker::run("varchar($min,$max,letters)", $value))->toBeFalsy(); + + } + }); + + it('fail when boundaries matches min length + not letters (incorrect flag check)', function(){ + + foreach($this->notletters as $value){ + $min = strlen($value); + $max = strlen($value)+1; + expect(Checker::run("varchar($min,$max,letters)", $value))->toBeFalsy(); + + } + }); + + it('fail when boundaries matches max length + not letters (incorrect flag check)', function(){ + + foreach($this->notletters as $value){ + $min = 0; + $max = strlen($value); + expect(Checker::run("varchar($min,$max,letters)", $value))->toBeFalsy(); + + } + }); + + it('fail when boundaries are over min length + not letters (incorrect flag check)', function(){ + + foreach($this->notletters as $value){ + $min = strlen($value)+1; + $max = strlen($value)+2; + + expect($min)->toBeGreaterThan(strlen($value)); + expect(Checker::run("varchar($min,$max,letters)", $value))->toBeFalsy(); + + } + + }); + + it('fail when boundaries are under max length', function(){ + + foreach($this->notletters as $value){ + $min = strlen($value)-2; + $max = strlen($value)-1; + + expect($max)->toBeLessThan(strlen($value)); + expect(Checker::run("varchar($min,$max,letters)", $value))->toBeFalsy(); + + } + + }); + + }); + + /* (17) Array + ---------------------------------------------------------*/ + context('* array', function(){ + + it('pass when empty array', function(){ + + $arr = []; + + expect($arr)->toBeA('array'); + expect($arr)->toBeEmpty(); + expect(Checker::run('array', $arr))->toBeTruthy(); + + }); + + it('pass when empty array (whatever subtype)', function(){ + + $arr = []; + + expect($arr)->toBeA('array'); + expect($arr)->toBeEmpty(); + + expect(Checker::run('array', $arr))->toBeTruthy(); + expect(Checker::run('array', $arr))->toBeTruthy(); + expect(Checker::run('array', $arr))->toBeTruthy(); + + }); + + it('pass when recursive empty arrays', function(){ + + $arr = [[], []]; + + expect($arr)->toBeA('array'); + expect($arr[0])->toBeA('array'); + expect($arr[1])->toBeA('array'); + expect($arr[0])->toBeEmpty(); + expect($arr[1])->toBeEmpty(); + + expect(Checker::run('array', $arr))->toBeTruthy(); + expect(Checker::run('array', $arr))->toBeTruthy(); + expect(Checker::run('array', $arr))->toBeTruthy(); + + }); + + it('pass when recursive array', function(){ + + $arr = [0, 1, 2, 2147483647]; + + foreach($arr as $id) + expect(Checker::run('id', $id))->toBeTruthy(); + + expect($arr)->toBeA('array'); + expect(Checker::run('array', $arr))->toBeTruthy(); + expect(Checker::run('array', $arr))->toBeTruthy(); + expect(Checker::run('array', $arr))->toBeTruthy(); + + }); + + it('fail when recursive array', function(){ + + // last boundary + $arr = [1, 2, 3, 4, 2147483647+1]; + expect(Checker::run('id', $arr[4]))->toBeFalsy(); + expect(Checker::run('array', $arr))->toBeFalsy(); + + // middle wrong + $arr = [1, 2, 2147483647+1, 3, 4]; + expect(Checker::run('id', $arr[2]))->toBeFalsy(); + expect(Checker::run('array', $arr))->toBeFalsy(); + + // first wrong + $arr = [2147483647+1, 1, 2, 3, 4]; + expect(Checker::run('id', $arr[0]))->toBeFalsy(); + + expect(Checker::run('array', $arr))->toBeFalsy(); + + // all wrong + foreach([-1, -2, -3, 2.3, 2147483647+1] as $id) + expect(Checker::run('id', $id))->toBeFalsy(); + + expect(Checker::run('array', $arr))->toBeFalsy(); + + }); + + }); + });