395 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			395 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| namespace nulib\schema\_assoc;
 | |
| 
 | |
| use nulib\schema\_scalar\ScalarSchemaTest;
 | |
| use nulib\schema\Schema;
 | |
| use nulib\tests\TestCase;
 | |
| use nulib\ValueException;
 | |
| 
 | |
| class AssocSchemaTest extends TestCase {
 | |
|   const NULL_SCHEMA = [
 | |
|     "" => [
 | |
|       "assoc",
 | |
|       "compute_func" => null,
 | |
|       "validate_func" => null,
 | |
|       "ensure_array" => null,
 | |
|       "ensure_assoc" => null,
 | |
|       "ensure_keys" => null,
 | |
|       "ensure_order" => null,
 | |
|     ],
 | |
|     "schema" => null,
 | |
|     "type" => [null],
 | |
|     "default" => null,
 | |
|     "title" => null,
 | |
|     "required" => false,
 | |
|     "nullable" => true,
 | |
|     "desc" => null,
 | |
|     "analyzer_func" => null,
 | |
|     "extractor_func" => null,
 | |
|     "parser_func" => null,
 | |
|     "normalizer_func" => null,
 | |
|     "messages" => null,
 | |
|     "formatter_func" => null,
 | |
|     "format" => null,
 | |
|     "size" => null,
 | |
|     "precision" => null,
 | |
|     "name" => null,
 | |
|     "pkey" => null,
 | |
|     "header" => null,
 | |
|     "computed" => null,
 | |
|   ];
 | |
| 
 | |
|   static function schema(array $definition, array $keyDefinitions): array {
 | |
|     $definition = array_merge(self::NULL_SCHEMA, $definition, ["schema" => []]);
 | |
|     foreach ($keyDefinitions as $key => $keydef) {
 | |
|       $definition["schema"][$key] = array_merge(ScalarSchemaTest::NULL_SCHEMA, $keydef);
 | |
|     }; unset($subdef);
 | |
|     return $definition;
 | |
|   }
 | |
| 
 | |
|   function testNormalize() {
 | |
|     self::assertSame(self::schema([
 | |
|       "type" => ["array"], "nullable" => true,
 | |
|     ], [
 | |
|       "s" => [
 | |
|         "type" => ["string"], "nullable" => false,
 | |
|         "name" => "s", "pkey" => "s", "header" => "s",
 | |
|       ],
 | |
|     ]), AssocSchema::normalize_definition(["s" => "string"]));
 | |
| 
 | |
|     self::assertSame(self::schema([
 | |
|       "type" => ["array"], "nullable" => true,
 | |
|     ], [
 | |
|       "s" => [
 | |
|         "type" => ["string"], "nullable" => false,
 | |
|         "name" => "s", "pkey" => "s", "header" => "s",
 | |
|       ],
 | |
|       "i" => [
 | |
|         "type" => ["int"], "nullable" => false,
 | |
|         "name" => "i", "pkey" => "i", "header" => "i",
 | |
|       ],
 | |
|       "b" => [
 | |
|         "type" => ["bool"], "nullable" => false,
 | |
|         "name" => "b", "pkey" => "b", "header" => "b",
 | |
|       ],
 | |
|     ]), AssocSchema::normalize_definition([
 | |
|       "s" => "string",
 | |
|       "i" => "int",
 | |
|       "b" => "bool",
 | |
|     ]));
 | |
|   }
 | |
| 
 | |
|   function testConstructor() {
 | |
|     $schema = new AssocSchema([
 | |
|       "s" => "string",
 | |
|       "i" => "int",
 | |
|       "b" => "bool",
 | |
|     ]);
 | |
|     self::assertSame(self::schema([
 | |
|       "type" => ["array"], "nullable" => true,
 | |
|     ], [
 | |
|       "s" => [
 | |
|         "type" => ["string"], "nullable" => false,
 | |
|         "name" => "s", "pkey" => "s", "header" => "s",
 | |
|       ],
 | |
|       "i" => [
 | |
|         "type" => ["int"], "nullable" => false,
 | |
|         "name" => "i", "pkey" => "i", "header" => "i",
 | |
|       ],
 | |
|       "b" => [
 | |
|         "type" => ["bool"], "nullable" => false,
 | |
|         "name" => "b", "pkey" => "b", "header" => "b",
 | |
|       ],
 | |
|     ]), $schema->getDefinition());
 | |
|     //yaml::dump($schema->getDefinition());
 | |
|   }
 | |
| 
 | |
|   function testWrapper() {
 | |
|     $schema = new AssocSchema([
 | |
|       "s" => "?string",
 | |
|       "i" => "?int",
 | |
|       "b" => "?bool",
 | |
|     ]);
 | |
|     $array = ["s" => "  string  ", "i" => "  42 ", "b" => false];
 | |
|     $schema->getWrapper($array);
 | |
|     self::assertSame([
 | |
|       "s" => "string",
 | |
|       "i" => 42,
 | |
|       "b" => false,
 | |
|     ], $array);
 | |
| 
 | |
|     ###########################################################################
 | |
|     $schema = new AssocSchema([
 | |
|       "s" => "string",
 | |
|       "i" => "int",
 | |
|       "b" => "bool",
 | |
|     ]);
 | |
| 
 | |
|     $array = ["s" => "  string  "];
 | |
|     $schema->getWrapper($array);
 | |
|     self::assertSame([
 | |
|       "s" => "string",
 | |
|       "i" => 0,
 | |
|       "b" => false,
 | |
|     ], $array);
 | |
| 
 | |
|     $array = ["b" => false, "s" => "  string  "];
 | |
|     $schema->getWrapper($array);
 | |
|     self::assertSame([
 | |
|       "s" => "string",
 | |
|       "i" => 0,
 | |
|       "b" => false,
 | |
|     ], $array);
 | |
| 
 | |
|     $array = ["s" => "  string  "];
 | |
|     $schema->getWrapper($array, null, ["ensure_order" => false]);
 | |
|     self::assertSame([
 | |
|       "s" => "string",
 | |
|       "i" => 0,
 | |
|       "b" => false,
 | |
|     ], $array);
 | |
| 
 | |
|     $array = ["b" => false, "s" => "  string  "];
 | |
|     $schema->getWrapper($array, null, ["ensure_order" => false]);
 | |
|     self::assertSame([
 | |
|       "b" => false,
 | |
|       "s" => "string",
 | |
|       "i" => 0,
 | |
|     ], $array);
 | |
| 
 | |
|     $array = ["s" => "  string  "];
 | |
|     $schema->getWrapper($array, null, ["ensure_keys" => false]);
 | |
|     self::assertSame([
 | |
|       "s" => "string",
 | |
|     ], $array);
 | |
| 
 | |
|     $array = ["b" => false, "s" => "  string  "];
 | |
|     $schema->getWrapper($array, null, ["ensure_keys" => false]);
 | |
|     self::assertSame([
 | |
|       "s" => "string",
 | |
|       "b" => false,
 | |
|     ], $array);
 | |
| 
 | |
|     // false équivaut à absent, sauf pour "b" qui est de type bool
 | |
|     $array = ["s" => false, "i" => false, "b" => false];
 | |
|     $schema->getWrapper($array, null, ["ensure_keys" => true]);
 | |
|     self::assertSame([
 | |
|       "s" => "",
 | |
|       "i" => 0,
 | |
|       "b" => false,
 | |
|     ], $array);
 | |
| 
 | |
|     $array = ["s" => false, "i" => false, "b" => false];
 | |
|     $schema->getWrapper($array, null, ["ensure_keys" => false]);
 | |
|     self::assertSame([
 | |
|       "b" => false,
 | |
|     ], $array);
 | |
|   }
 | |
| 
 | |
|   const STRING_SCHEMA = [
 | |
|     "s" => "string",
 | |
|     "f" => "string",
 | |
|     "m" => "string",
 | |
|   ];
 | |
| 
 | |
|   const NSTRING_SCHEMA = [
 | |
|     "s" => "?string",
 | |
|     "f" => "?string",
 | |
|     "m" => "?string",
 | |
|   ];
 | |
| 
 | |
|   const RSTRING_SCHEMA = [
 | |
|     "s" => ["string", "required" => true],
 | |
|     "f" => ["string", "required" => true],
 | |
|     "m" => ["string", "required" => true],
 | |
|   ];
 | |
| 
 | |
|   const RNSTRING_SCHEMA = [
 | |
|     "s" => ["?string", "required" => true],
 | |
|     "f" => ["?string", "required" => true],
 | |
|     "m" => ["?string", "required" => true],
 | |
|   ];
 | |
| 
 | |
|   const STRINGS = ["s" => "string", "f" => false];
 | |
|   const NSTRINGS = ["s" => null, "f" => null];
 | |
| 
 | |
|   function testString() {
 | |
|     /** @var AssocSchema $schema */
 | |
|     $schema = Schema::ns(self::STRING_SCHEMA);
 | |
| 
 | |
|     $array = self::STRINGS;
 | |
|     $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | |
|     self::assertSame(["s" => "string", "f" => "", "m" => ""], $array);
 | |
|     $result = $wrapper->getResult("s");
 | |
|     self::assertTrue($result->normalized);
 | |
|     $result = $wrapper->getResult("f");
 | |
|     self::assertTrue($result->present);
 | |
|     self::assertFalse($result->available);
 | |
|     $result = $wrapper->getResult("m");
 | |
|     self::assertFalse($result->present);
 | |
| 
 | |
|     self::assertNotException(function() use ($schema) {
 | |
|       $array = self::STRINGS;
 | |
|       $schema->getWrapper($array);
 | |
|     });
 | |
| 
 | |
|     $array = self::NSTRINGS;
 | |
|     $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | |
|     self::assertSame(["s" => null, "f" => null, "m" => ""], $array);
 | |
|     $result = $wrapper->getResult("s");
 | |
|     self::assertFalse($result->valid);
 | |
|     self::assertSame("null", $result->messageKey);
 | |
|     $result = $wrapper->getResult("f");
 | |
|     self::assertFalse($result->valid);
 | |
|     self::assertSame("null", $result->messageKey);
 | |
|     $result = $wrapper->getResult("m");
 | |
|     self::assertFalse($result->present);
 | |
| 
 | |
|     self::assertException(ValueException::class, function() use ($schema) {
 | |
|       $array = self::NSTRINGS;
 | |
|       $schema->getWrapper($array);
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   function testNstring() {
 | |
|     /** @var AssocSchema $schema */
 | |
|     $schema = Schema::ns(self::NSTRING_SCHEMA);
 | |
| 
 | |
|     $array = self::STRINGS;
 | |
|     $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | |
|     self::assertSame(["s" => "string", "f" => null, "m" => null], $array);
 | |
|     $result = $wrapper->getResult("s");
 | |
|     self::assertTrue($result->normalized);
 | |
|     $result = $wrapper->getResult("f");
 | |
|     self::assertTrue($result->present);
 | |
|     self::assertFalse($result->available);
 | |
|     $result = $wrapper->getResult("m");
 | |
|     self::assertFalse($result->present);
 | |
| 
 | |
|     self::assertNotException(function() use ($schema) {
 | |
|       $array = self::STRINGS;
 | |
|       $schema->getWrapper($array);
 | |
|     });
 | |
| 
 | |
|     $array = self::NSTRINGS;
 | |
|     $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | |
|     self::assertSame(["s" => null, "f" => null, "m" => null], $array);
 | |
|     $result = $wrapper->getResult("s");
 | |
|     self::assertTrue($result->normalized);
 | |
|     $result = $wrapper->getResult("f");
 | |
|     self::assertTrue($result->normalized);
 | |
|     $result = $wrapper->getResult("m");
 | |
|     self::assertFalse($result->present);
 | |
| 
 | |
|     self::assertNotException(function() use ($schema) {
 | |
|       $array = self::NSTRINGS;
 | |
|       $schema->getWrapper($array);
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   function testRstring() {
 | |
|     /** @var AssocSchema $schema */
 | |
|     $schema = Schema::ns(self::RSTRING_SCHEMA);
 | |
| 
 | |
|     $array = self::STRINGS;
 | |
|     $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | |
|     self::assertSame(["s" => "string", "f" => "", "m" => ""], $array);
 | |
|     $result = $wrapper->getResult("s");
 | |
|     self::assertTrue($result->normalized);
 | |
|     $result = $wrapper->getResult("f");
 | |
|     self::assertTrue($result->present);
 | |
|     self::assertFalse($result->available);
 | |
|     self::assertSame("unavailable", $result->messageKey);
 | |
|     $result = $wrapper->getResult("m");
 | |
|     self::assertFalse($result->present);
 | |
|     self::assertSame("missing", $result->messageKey);
 | |
| 
 | |
|     self::assertException(ValueException::class, function() use ($schema) {
 | |
|       $array = self::STRINGS;
 | |
|       $schema->getWrapper($array);
 | |
|     });
 | |
| 
 | |
|     $array = self::NSTRINGS;
 | |
|     $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | |
|     self::assertSame(["s" => null, "f" => null, "m" => ""], $array);
 | |
|     $result = $wrapper->getResult("s");
 | |
|     self::assertFalse($result->valid);
 | |
|     self::assertSame("null", $result->messageKey);
 | |
|     $result = $wrapper->getResult("f");
 | |
|     self::assertFalse($result->valid);
 | |
|     self::assertSame("null", $result->messageKey);
 | |
|     $result = $wrapper->getResult("m");
 | |
|     self::assertFalse($result->present);
 | |
|     self::assertSame("missing", $result->messageKey);
 | |
| 
 | |
|     self::assertException(ValueException::class, function() use ($schema) {
 | |
|       $array = self::NSTRINGS;
 | |
|       $schema->getWrapper($array);
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   function testRnstring() {
 | |
|     /** @var AssocSchema $schema */
 | |
|     $schema = Schema::ns(self::RNSTRING_SCHEMA);
 | |
| 
 | |
|     $array = self::STRINGS;
 | |
|     $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | |
|     self::assertSame(["s" => "string", "f" => null, "m" => null], $array);
 | |
|     $result = $wrapper->getResult("s");
 | |
|     self::assertTrue($result->normalized);
 | |
|     $result = $wrapper->getResult("f");
 | |
|     self::assertTrue($result->present);
 | |
|     self::assertFalse($result->available);
 | |
|     self::assertSame("unavailable", $result->messageKey);
 | |
|     $result = $wrapper->getResult("m");
 | |
|     self::assertFalse($result->present);
 | |
|     self::assertSame("missing", $result->messageKey);
 | |
| 
 | |
|     self::assertException(ValueException::class, function() use ($schema) {
 | |
|       $array = self::STRINGS;
 | |
|       $schema->getWrapper($array);
 | |
|     });
 | |
| 
 | |
|     $array = self::NSTRINGS;
 | |
|     $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | |
|     self::assertSame(["s" => null, "f" => null, "m" => null], $array);
 | |
|     $result = $wrapper->getResult("s");
 | |
|     self::assertTrue($result->normalized);
 | |
|     $result = $wrapper->getResult("f");
 | |
|     self::assertTrue($result->normalized);
 | |
|     $result = $wrapper->getResult("m");
 | |
|     self::assertFalse($result->present);
 | |
|     self::assertSame("missing", $result->messageKey);
 | |
| 
 | |
|     self::assertException(ValueException::class, function() use ($schema) {
 | |
|       $array = self::NSTRINGS;
 | |
|       $schema->getWrapper($array);
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   function testMessage() {
 | |
|     $schema = new AssocSchema([
 | |
|       "rs" => ["string", "required" => true],
 | |
|       "i" => ["int"],
 | |
|     ]);
 | |
| 
 | |
|     $value = [];
 | |
|     $result = $schema->getWrapper($value, null, ["throw" => false])->getResult(null);
 | |
|     $expectedMessage = <<<EOT
 | |
| rs: vous devez spécifier cette valeur
 | |
| EOT;
 | |
|     self::assertSame($expectedMessage, $result->message);
 | |
| 
 | |
|     $value = [
 | |
|       "rs" => null,
 | |
|       "i" => "abc",
 | |
|     ];
 | |
|     $result = $schema->getWrapper($value, null, ["throw" => false])->getResult(null);
 | |
|     $expectedMessage = <<<EOT
 | |
| rs: cette valeur ne doit pas être nulle
 | |
| i: une valeur numérique entière est attendue
 | |
| EOT;
 | |
|     self::assertSame($expectedMessage, $result->message);
 | |
|   }
 | |
| }
 |