397 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			397 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
namespace nulib\schema\_assoc;
 | 
						|
 | 
						|
use nulib\ext\yaml;
 | 
						|
use nulib\tests\TestCase;
 | 
						|
use nulib\ValueException;
 | 
						|
use nulib\schema\_scalar\ScalarSchemaTest;
 | 
						|
use nulib\schema\Schema;
 | 
						|
use PHPStan\Type\Enum\EnumCaseObjectType;
 | 
						|
 | 
						|
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);
 | 
						|
  }
 | 
						|
}
 |