null, "b" => null]], [[], ["a" => null, "b" => null]], [[null], ["a" => null, "b" => null]], ["a", ["a" => "a", "b" => null]], [["a"], ["a" => "a", "b" => null]], [["a", "b"], ["a" => "a", "b" => "b"]], # associatif [["a" => "a"], ["a" => "a", "b" => null]], [["b" => "b"], ["b" => "b", "a" => null]], [["a" => "a", "b" => "b"], ["a" => "a", "b" => "b"]], [["b" => "b", "a" => "a"], ["b" => "b", "a" => "a"]], # mix séquentiel / associatif [["a" => "a", "b"], ["a" => "a", "b" => "b"]], [["a", "b" => "b"], ["b" => "b", "a" => "a"]], # avec extra [["a", "b", "x"], ["a" => "a", "b" => "b", "x"]], [["a", "b", "y" => "y"], ["y" => "y", "a" => "a", "b" => "b"]], [["a" => "a", "b" => "b", "x"], ["a" => "a", "b" => "b", "x"]], [["a" => "a", "b" => "b", "y" => "y"], ["a" => "a", "b" => "b", "y" => "y"]], [["a" => "a", "b" => "b", "x", "y" => "y"], ["a" => "a", "b" => "b", "y" => "y", "x"]], ]; const SCHEMA_DATA2 = [ # sequentiel ["k", null, ["a" => "k", "b" => null]], ["k", [], ["a" => "k", "b" => null]], ["k", [null], ["a" => "k", "b" => null]], ["k", "a", ["a" => "k", "b" => "a"]], ["k", ["a"], ["a" => "k", "b" => "a"]], ["k", ["a", "b"], ["a" => "k", "b" => "a", "b"]], # associatif ["k", ["a" => "a"], ["a" => "a", "b" => null]], ["k", ["b" => "b"], ["b" => "b", "a" => "k"]], ["k", ["a" => "a", "b" => "b"], ["a" => "a", "b" => "b"]], ["k", ["b" => "b", "a" => "a"], ["b" => "b", "a" => "a"]], # mix séquentiel / associatif ["k", ["a" => "a", "b"], ["a" => "a", "b" => "b"]], ["k", ["a", "b" => "b"], ["b" => "b", "a" => "k", "a"]], # avec extra ["k", ["a", "b", "x"], ["a" => "k", "b" => "a", "b", "x"]], ["k", ["a", "b", "y" => "y"], ["y" => "y", "a" => "k", "b" => "a", "b"]], ["k", ["a" => "a", "b" => "b", "x"], ["a" => "a", "b" => "b", "x"]], ["k", ["a" => "a", "b" => "b", "y" => "y"], ["a" => "a", "b" => "b", "y" => "y"]], ["k", ["a" => "a", "b" => "b", "x", "y" => "y"], ["a" => "a", "b" => "b", "y" => "y", "x"]], ]; function testSchema() { $schema = [ "a" => null, "b" => null, ]; $index = 0; foreach (self::SCHEMA_DATA1 as [$data, $result]) { md::ensure_schema($data, $schema); self::assertSame($result, $data, "at SCHEMA_DATA1[$index]"); $index++; } $index = 0; foreach (self::SCHEMA_DATA2 as [$key, $data, $result]) { md::ensure_schema($data, $schema, $key); self::assertSame($result, $data, "at SCHEMA_DATA2[$index]"); $index++; } } ############################################################################# function testRecursiveSchema() { $item_schema = [ "id" => null, "name" => null, ]; $schema = [ "item" => ["array", "default", "schema" => $item_schema], "items" => ["array[]", "default", "schema" => $item_schema], "nitem" => ["?array", "default", "schema" => $item_schema], "nitems" => ["?array[]", "default", "schema" => $item_schema], ]; $data = null; md::ensure_schema($data, $schema); self::assertSame([ "item" => ["id" => "default", "name" => null], "items" => [["id" => "default", "name" => null]], "nitem" => ["id" => "default", "name" => null], "nitems" => [["id" => "default", "name" => null]], ], $data); $data = [false, false, false, false]; md::ensure_schema($data, $schema); self::assertSame([ "item" => ["id" => "default", "name" => null], "items" => [["id" => "default", "name" => null]], "nitem" => ["id" => "default", "name" => null], "nitems" => [["id" => "default", "name" => null]], ], $data); $data = [null, null, null, null]; md::ensure_schema($data, $schema); self::assertSame([ "item" => ["id" => "default", "name" => null], "items" => [["id" => "default", "name" => null]], "nitem" => null, "nitems" => null, ], $data); $data = ["id", "id", "id", "id"]; md::ensure_schema($data, $schema); self::assertSame([ "item" => ["id" => "id", "name" => null], "items" => [["id" => "id", "name" => null]], "nitem" => ["id" => "id", "name" => null], "nitems" => [["id" => "id", "name" => null]], ], $data); } ############################################################################# function testTypes() { $schema = [ "regular" => [null, "default"], "boolt" => ["bool", true], "boolf" => ["bool", false], "booln" => ["bool", null], "nboolt" => ["?bool", true], "nboolf" => ["?bool", false], "nbooln" => ["?bool", null], "mixed" => ["mixed", "default"], ]; $data = []; md::ensure_schema($data, $schema); self::assertSame([ "regular" => "default", "boolt" => true, "boolf" => false, "booln" => false, "nboolt" => true, "nboolf" => false, "nbooln" => null, "mixed" => "default", ], $data); $data = [ false, false, false, false, false, false, false, false, ]; md::ensure_schema($data, $schema); self::assertSame([ "regular" => "default", "boolt" => false, "boolf" => false, "booln" => false, "nboolt" => false, "nboolf" => false, "nbooln" => false, "mixed" => false, ], $data); $data = [ null, null, null, null, null, null, null, null, ]; md::ensure_schema($data, $schema); self::assertSame([ "regular" => null, "boolt" => true, "boolf" => false, "booln" => false, "nboolt" => null, "nboolf" => null, "nbooln" => null, "mixed" => null, ], $data); $data = [ "x", "x", "x", "x", "x", "x", "x", "x", ]; md::ensure_schema($data, $schema); self::assertSame([ "regular" => "x", "boolt" => true, "boolf" => true, "booln" => true, "nboolt" => true, "nboolf" => true, "nbooln" => true, "mixed" => "x", ], $data); } function testArrayToString() { $schema = ["value" => "string"]; $data = ["value" => "one"]; md::ensure_schema($data, $schema); self::assertSame(["value" => "one"], $data); $data = ["value" => ["one", "two"]]; md::ensure_schema($data, $schema); self::assertSame(["value" => "one two"], $data); $data = ["value" => ["one", "two" => false, "three" => true]]; md::ensure_schema($data, $schema); self::assertSame(["value" => "one three"], $data); } ############################################################################# function testRequired() { $schema = [ "required" => [null, "required" => true], "nullable" => [null, 1], ]; $data = null; self::assertException(ValueException::class, function() use (&$data, $schema) { md::ensure_schema($data, $schema, null, true); }); self::assertSame(["required" => null, "nullable" => 1], $data); $data = []; self::assertException(ValueException::class, function() use (&$data, $schema) { md::ensure_schema($data, $schema, null, true); }); self::assertSame(["required" => null, "nullable" => 1], $data); $data = [null]; self::assertException(ValueException::class, function() use (&$data, $schema) { md::ensure_schema($data, $schema, null, true); }); self::assertSame(["required" => null, "nullable" => 1], $data); $data = [false]; self::assertException(ValueException::class, function() use (&$data, $schema) { md::ensure_schema($data, $schema, null, true); }); self::assertSame(["required" => null, "nullable" => 1], $data); $data = ["x"]; self::assertNotException(function() use (&$data, $schema) { md::ensure_schema($data, $schema, null, true); }); self::assertSame(["required" => "x", "nullable" => 1], $data); $data = ["x", "y", "z"]; self::assertNotException(function() use (&$data, $schema) { md::ensure_schema($data, $schema, null, true); }); self::assertSame(["required" => "x", "nullable" => "y", "z"], $data); $data = ["x", false, "z"]; self::assertNotException(function() use (&$data, $schema) { md::ensure_schema($data, $schema, null, true); }); self::assertSame(["required" => "x", "nullable" => 1, "z"], $data); } ############################################################################# const GET_DATA = [ [null, [ "a" => null, "b" => "b", ]], [false, [ "a" => "a", "b" => "b", ]], [1, [ "a" => 1, "b" => "b", ]], [[], [ "a" => "a", "b" => "b", ]], [[null], [ "a" => null, "b" => "b", ]], [[false], [ "a" => "a", "b" => "b", ]], [[1], [ "a" => 1, "b" => "b", ]], [[1, 2], [ "a" => 1, "b" => 2, ]], [["a" => 1], [ "a" => 1, "b" => "b", ]], [["b" => 2], [ "a" => "a", "b" => 2, ]], [["a" => 1, "b" => 2], [ "a" => 1, "b" => 2, ]], [["b" => 2, "a" => 1], [ "a" => 1, "b" => 2, ]], ]; function testGet() { $schema = [ "a" => [null, "a"], "b" => [null, "b"], ]; $i = 0; foreach (self::GET_DATA as [$data, $results]) { $j = 0; foreach ($results as $key => $expected) { $actual = md::get($data, $key, $schema); self::assertSame($expected, $actual, "at GET_DATA[$i][$j]"); $j++; } $i++; } # test default $data = []; self::assertSame("a", md::get($data, "a", $schema)); self::assertSame("A", md::get($data, "a", $schema, "A")); $data = ["a" => "x"]; self::assertSame("x", md::get($data, "a", $schema)); self::assertSame("x", md::get($data, "a", $schema, "A")); } ############################################################################# const GET_VALUES_DATA = [ [null, [], []], [["a", "b"], [], ["a", "b"]], [["a" => "a"], ["a" => "a"], []], [["b" => "b"], ["b" => "b"], []], [["a" => "a", "b" => "b"], ["a" => "a", "b" => "b"], []], [["b" => "b", "a" => "a"], ["a" => "a", "b" => "b"], []], ]; function testGetValues() { $schema = [ "a" => null, "b" => null, ]; $i = 0; foreach (self::GET_VALUES_DATA as [$data, $xvalues, $xothers]) { $values = md::get_values($data, $schema); self::assertSame($xvalues, $values, "values at GET_VALUES_DATA[$i]"); $others = md::get_others($data, $schema); self::assertSame($xothers, $others, "others at GET_VALUES_DATA[$i]"); $i++; } } }