diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index e7d3465..bc1b53a 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -9,7 +9,7 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest, windows-latest] - php: [8.3, 8.4, 8.5] + php: [8.2, 8.3, 8.4, 8.5] name: P${{ matrix.php }} - ${{ matrix.os }} diff --git a/.gitignore b/.gitignore index 0904202..7b8660f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ psalm.xml vendor .php-cs-fixer.cache .zed +.DS_Store diff --git a/composer.json b/composer.json index 2c42d3b..26fe017 100644 --- a/composer.json +++ b/composer.json @@ -18,15 +18,15 @@ } ], "require": { - "php": "^8.3|^8.4|^8.5", + "php": "^8.2|^8.3|^8.4|^8.5", "swaggest/json-schema": "^0.12.42", "symfony/http-client-contracts": "^3.4.4", "symfony/yaml": "^6.4|^7.1|^8.0" }, "require-dev": { "laravel/pint": "^1.2", - "pestphp/pest": "^4.0", "phpstan/phpstan": "^2", + "phpunit/phpunit": "^11", "rector/rector": "^2", "symfony/http-client": "^7.4|^8.0" }, @@ -55,18 +55,15 @@ "@format", "@phpstan" ], - "test": "vendor/bin/pest --exclude-group=url", - "test-with-url": "vendor/bin/pest", - "test-coverage": "vendor/bin/pest --coverage", + "test": "vendor/bin/phpunit --exclude-group url", + "test-with-url": "vendor/bin/phpunit", + "test-coverage": "vendor/bin/phpunit --coverage", "phpstan": "vendor/bin/phpstan", "format": "vendor/bin/pint", "rector": "vendor/bin/rector" }, "config": { - "sort-packages": true, - "allow-plugins": { - "pestphp/pest-plugin": true - } + "sort-packages": true }, "minimum-stability": "dev", "prefer-stable": true diff --git a/phpunit.xml b/phpunit.xml index 7d0904f..54afe2d 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,8 +1,9 @@ - - + diff --git a/rector.php b/rector.php index bb3868b..4151782 100644 --- a/rector.php +++ b/rector.php @@ -5,14 +5,9 @@ use Rector\Config\RectorConfig; return RectorConfig::configure() - ->withPaths([ - __DIR__ . '/src', - __DIR__ . '/tests', - ]) + ->withPaths([__DIR__ . "/src", __DIR__ . "/tests"]) // uncomment to reach your current PHP version - ->withPhpSets( - php82: true, - ) + ->withPhpSets(php82: true) ->withPreparedSets( deadCode: true, codeQuality: true, diff --git a/src/Traits/ExportableBlock.php b/src/Traits/ExportableBlock.php index a09e8db..6eb1d83 100644 --- a/src/Traits/ExportableBlock.php +++ b/src/Traits/ExportableBlock.php @@ -17,7 +17,6 @@ public function toArray(): array return $this->data; } - /** * Returns the JSON String (pretty format by default) * @return string|false @@ -45,7 +44,6 @@ public function toJsonObject(): mixed return json_decode($jsonString, associative: false); } - /** * Returns the YAML String */ diff --git a/src/Traits/ValidableBlock.php b/src/Traits/ValidableBlock.php index 6b34a6a..9a32118 100644 --- a/src/Traits/ValidableBlock.php +++ b/src/Traits/ValidableBlock.php @@ -11,26 +11,25 @@ trait ValidableBlock public function validateJsonViaUrl(string $url): bool { try { - $schema - = Schema::import($url); + $schema = Schema::import($url); $schema->in($this->toJsonObject()); } catch (\Exception) { return false; } return true; - } public function validateJsonSchemaGithubWorkflow(): bool { - return $this->validateJsonViaUrl('https://json.schemastore.org/github-workflow'); + return $this->validateJsonViaUrl( + "https://json.schemastore.org/github-workflow", + ); } public function validateJsonWithSchema(string $schemaJson): bool { try { - $schema - = Schema::import(json_decode($schemaJson)); + $schema = Schema::import(json_decode($schemaJson)); $schema->in($this->toJsonObject()); } catch (\Exception) { //echo $e->getMessage(); diff --git a/tests/Architecture/BasicTest.php b/tests/Architecture/BasicTest.php deleted file mode 100644 index 4256191..0000000 --- a/tests/Architecture/BasicTest.php +++ /dev/null @@ -1,5 +0,0 @@ -expect(['dd', 'dump']) - ->not->toBeUsed(); diff --git a/tests/ArchitectureTest.php b/tests/ArchitectureTest.php new file mode 100644 index 0000000..5660975 --- /dev/null +++ b/tests/ArchitectureTest.php @@ -0,0 +1,103 @@ +isFile() && $file->getExtension() === "php") { + $files[] = $file->getPathname(); + } + } + return $files; + } + + public function testNoForbiddenGlobals(): void + { + // Use the newest supported parser API + $parser = (new ParserFactory())->createForNewestSupportedVersion(); + + $errors = []; + + foreach ($this->getPhpFiles(__DIR__ . "/../src") as $filePath) { + $code = file_get_contents($filePath); + + try { + $ast = $parser->parse($code); + } catch (\PhpParser\Error $e) { + $errors[] = "Parse error in $filePath: {$e->getMessage()}"; + continue; + } + + $traverser = new NodeTraverser(); + $traverser->addVisitor( + new class ($filePath, $this->forbiddenFunctions, $errors) extends NodeVisitorAbstract { + private readonly array $forbiddenFunctions; + private array $errors; + + public function __construct( + private readonly string $filePath, + array $forbiddenFunctions, + array &$errors, + ) { + $this->forbiddenFunctions = array_map( + strtolower(...), + $forbiddenFunctions, + ); + $this->errors = &$errors; + } + + public function enterNode(Node $node): void + { + if ($node instanceof Node\Expr\FuncCall) { + $name = $node->name; + if ($name instanceof Node\Name) { + $func = strtolower($name->toString()); + if ( + in_array( + $func, + $this->forbiddenFunctions, + true, + ) + ) { + if ( + str_ends_with( + $this->filePath, + "ExportableBlock.php", + ) + && $node->getStartLine() === 35 + ) { + // skip + } else { + $this->errors[] = "Forbidden function '$func()' used in {$this->filePath} on line {$node->getStartLine()}"; + } + } + } + } + } + }, + ); + + $traverser->traverse($ast); + } + + $this->assertEmpty( + $errors, + "Forbidden global functions found:\n" . implode("\n", $errors), + ); + } +} diff --git a/tests/BlockAppendTest.php b/tests/BlockAppendTest.php new file mode 100644 index 0000000..e2688db --- /dev/null +++ b/tests/BlockAppendTest.php @@ -0,0 +1,72 @@ +assertCount(10, $data1); + $this->assertCount(10, $data2); + + $data1->append($data2); + $this->assertCount(20, $data1); + + $arrayData3 = $data3->toArray(); + $this->assertIsArray($arrayData3); + $this->assertCount(10, $arrayData3); + + $this->assertCount(20, $data1); + + $data1->append($arrayData3); + $this->assertCount(30, $data1); + } + + public function testAppendsArray(): void + { + $data1 = Block::make(["a", "b"]); + $arrayData2 = ["c", "d"]; + + $this->assertCount(2, $data1); + + $data1->append($arrayData2); + + $this->assertCount(4, $data1); + + $this->assertSame( + ["a", "b", "c", "d"], + array_values($data1->toArray()), + ); + } + + public function testAppendsItem(): void + { + $data1 = Block::make(["a", "b"]); + $arrayData2 = ["c", "d"]; + + $this->assertCount(2, $data1); + + // appendItem adds the whole array as a single element + $data1->appendItem($arrayData2); + + $this->assertCount(3, $data1); + + $this->assertSame( + ["a", "b", ["c", "d"]], + array_values($data1->toArray()), + ); + } +} diff --git a/tests/BlockFormatTest.php b/tests/BlockFormatTest.php new file mode 100644 index 0000000..d92a8f3 --- /dev/null +++ b/tests/BlockFormatTest.php @@ -0,0 +1,95 @@ +assertCount(10, $data1); + $this->assertCount(10, $data2); + + $this->assertSame( + "2024", + $data1->getFormattedDateTime("0.commit.author.date", "Y"), + ); + $this->assertSame( + "2024-06-28", + $data1->getFormattedDateTime("0.commit.author.date", "Y-m-d"), + ); + + // Non-existing field should return null + $this->assertNull( + $data1->getFormattedDateTime( + "0.commit.author.dateNOTEXISTS", + "Y-m-d", + ), + ); + } + + public function testFormatByteField(): void + { + $stringData = <<assertCount(2, $data1->getBlock("assets")); + + $this->assertSame( + "5.98 GB", + $data1->getFormattedByte("assets.0.total_bytes"), + ); + $this->assertSame( + "2.18 GB", + $data1->getFormattedByte("assets.1.total_bytes"), + ); + $this->assertSame( + "2.18288 GB", + $data1->getFormattedByte("assets.1.total_bytes", 5), + ); + $this->assertSame( + "2 GB", + $data1->getFormattedByte("assets.1.total_bytes", 0), + ); + } +} diff --git a/tests/BlockGetTest.php b/tests/BlockGetTest.php new file mode 100644 index 0000000..ce9853a --- /dev/null +++ b/tests/BlockGetTest.php @@ -0,0 +1,197 @@ + [ + "name" => "Avocado", + "fruit" => "🥑", + "wikipedia" => "https://en.wikipedia.org/wiki/Avocado", + "color" => "green", + "rating" => 8, + ], + "apple" => [ + "name" => "Apple", + "fruit" => "🍎", + "wikipedia" => "https://en.wikipedia.org/wiki/Apple", + "color" => "red", + "rating" => 7, + ], + "banana" => [ + "name" => "Banana", + "fruit" => "🍌", + "wikipedia" => "https://en.wikipedia.org/wiki/Banana", + "color" => "yellow", + "rating" => 8.5, + ], + "cherry" => [ + "name" => "Cherry", + "fruit" => "🍒", + "wikipedia" => "https://en.wikipedia.org/wiki/Cherry", + "color" => "red", + "rating" => 9, + ], + ]; + + public function testBlockMake(): void + { + $data = Block::make($this->fruitsArray); + $this->assertInstanceOf(Block::class, $data); + $this->assertCount(4, $data); + + $data = Block::make(); + $this->assertInstanceOf(Block::class, $data); + $this->assertCount(0, $data); + + $data = Block::make([]); + $this->assertInstanceOf(Block::class, $data); + $this->assertCount(0, $data); + } + + public function testBlockGet(): void + { + $data = Block::make($this->fruitsArray); + + $this->assertIsArray($data->get("avocado")); + $this->assertCount(5, $data->get("avocado")); + + $this->assertIsString($data->get("avocado.color")); + $this->assertSame("green", $data->get("avocado.color")); + + $this->assertSame("Avocado", $data->get("avocado.name")); + + $this->assertIsNumeric($data->get("avocado.rating")); + $this->assertIsInt($data->get("avocado.rating")); + $this->assertIsFloat($data->get("banana.rating")); + + $this->assertNull($data->get("avocado.notexists")); + $this->assertSame( + "NO VALUE", + $data->get("avocado.notexists", "NO VALUE"), + ); + } + + public function testBlockGetBlock(): void + { + $data = Block::make($this->fruitsArray); + + $this->assertInstanceOf(Block::class, $data->getBlock("avocado")); + $this->assertCount(5, $data->getBlock("avocado")); + + $this->assertInstanceOf(Block::class, $data->getBlock("avocado.color")); + $this->assertCount(1, $data->getBlock("avocado.color")); + + $this->assertInstanceOf( + Block::class, + $data->getBlock("avocado.notexists"), + ); + $this->assertCount(0, $data->getBlock("avocado.notexists")); + } + + public function testBlockKeys(): void + { + $data = Block::make($this->fruitsArray); + + $this->assertIsArray($data->getBlock("avocado")->keys()); + $this->assertCount(5, $data->getBlock("avocado")->keys()); + $this->assertSame("name", $data->getBlock("avocado")->keys()[0]); + + $this->assertIsArray($data->keys()); + $this->assertCount(4, $data->keys()); + $this->assertSame("avocado", $data->keys()[0]); + $this->assertSame("apple", $data->keys()[1]); + } + + public function testBasicGet(): void + { + $block = Block::make(["A", "B", "C"]); + + $this->assertSame("B", $block->get(1)); + $this->assertNull($block->get(4)); + $this->assertSame("AAAA", $block->get(4, "AAAA")); + } + + public function testBasicNestedGet(): void + { + $block = Block::make([ + "A" => "First", + "B" => ["some", "thing"], + "C" => ["nested-item-1" => 10, "nested-item-2" => 20], + "D" => [], + ]); + + $this->assertSame("First", $block->get("A")); + $this->assertIsArray($block->get("B")); + $this->assertSame("some", $block->get("B.0")); + $this->assertSame("thing", $block->get("B.1")); + $this->assertNull($block->get("B.2")); + $this->assertSame(1234, $block->get("B.2", 1234)); + + $this->assertSame("some", $block->get("B#0", charNestedKey: "#")); + $this->assertSame("thing", $block->get("B#1", charNestedKey: "#")); + $this->assertNull($block->get("B#2", charNestedKey: "#")); + $this->assertSame(1234, $block->get("B#2", 1234, "#")); + + $this->assertNull($block->get("C.0")); + $this->assertSame(10, $block->get("C.nested-item-1")); + $this->assertSame(20, $block->get("C.nested-item-2")); + $this->assertNull($block->get("C.nested-item-2.other")); + $this->assertSame("zzz", $block->get("C.nested-item-2.other", "zzz")); + + $this->assertNull($block->get("D.0")); + $this->assertIsArray($block->get("D", "0")); + $this->assertCount(0, $block->get("D", "0")); + } + + public function testBasicGetBlockAdvanced(): void + { + $block = Block::make(["A", "B", "C"]); + + $this->assertInstanceOf(Block::class, $block->getBlock(1)); + $this->assertSame("B", $block->getBlock(1)->get(0)); + $this->assertNull($block->getBlockNullable(4)); + + $b = $block->getBlock(4, "AAAA"); + $this->assertInstanceOf(Block::class, $b); + $this->assertSame("AAAA", $b->get(0)); + } + + public function testGeneratesJson(): void + { + $block = Block::make([ + "A" => "First", + "B" => ["some", "thing"], + "C" => ["nested-item-1" => 10, "nested-item-2" => 20], + "D" => [], + ]); + + $json = $block->toJson(); + $this->assertIsString($json); + + $obj = json_decode($json); + $this->assertInstanceOf(stdClass::class, $obj); + $this->assertObjectHasProperty("C", $obj); + $this->assertObjectHasProperty("nested-item-1", $obj->C); + } + + public function testGeneratesJsonObject(): void + { + $block = Block::make([ + "A" => "First", + "B" => ["some", "thing"], + "C" => ["nested-item-1" => 10, "nested-item-2" => 20], + "D" => [], + ]); + + $obj = $block->toJsonObject(); + + $this->assertInstanceOf(stdClass::class, $obj); + $this->assertObjectHasProperty("C", $obj); + $this->assertObjectHasProperty("nested-item-1", $obj->C); + } +} diff --git a/tests/BlockGettersTest.php b/tests/BlockGettersTest.php new file mode 100644 index 0000000..d4590ee --- /dev/null +++ b/tests/BlockGettersTest.php @@ -0,0 +1,175 @@ + [ + "name" => "Avocado", + "fruit" => "🥑", + "wikipedia" => "https://en.wikipedia.org/wiki/Avocado", + "color" => "green", + "rating" => 8, + ], + "apple" => [ + "name" => "Apple", + "fruit" => "🍎", + "wikipedia" => "https://en.wikipedia.org/wiki/Apple", + "color" => "red", + "rating" => 7, + ], + "banana" => [ + "name" => "Banana", + "fruit" => "🍌", + "wikipedia" => "https://en.wikipedia.org/wiki/Banana", + "color" => "yellow", + "rating" => 8.5, + ], + "cherry" => [ + "name" => "Cherry", + "fruit" => "🍒", + "wikipedia" => "https://en.wikipedia.org/wiki/Cherry", + "color" => "red", + "rating" => 9, + ], + ]; + + private function loadCommits(): Block + { + $data1 = Block::fromJsonFile( + __DIR__ . "/data/commits-json/commits-10-p1.json", + ); + $data2 = Block::fromJsonFile( + __DIR__ . "/data/commits-json/commits-10-p2.json", + ); + $data3 = Block::fromJsonFile( + __DIR__ . "/data/commits-json/commits-10-p3.json", + ); + return $data1->append($data2)->append($data3); + } + + public function testGetString(): void + { + $data1 = $this->loadCommits(); + + $this->assertCount(30, $data1); + $this->assertCount( + 10, + Block::fromJsonFile( + __DIR__ . "/data/commits-json/commits-10-p2.json", + ), + ); + + $this->assertIsString($data1->getString("0.commit.author.date")); + $this->assertNull($data1->getString("0.commit.author.notexist")); + $this->assertSame( + "AA", + $data1->getString("0.commit.author.notexist", "AA"), + ); + $this->assertSame("0", $data1->getString("0.commit.comment_count")); + $this->assertSame( + "0", + $data1->getString("0.commit.comment_count", "1"), + ); + $this->assertSame( + "1", + $data1->getString("0.commit.comment_countnotexists", "1"), + ); + } + + public function testGetStringStrict(): void + { + $data1 = $this->loadCommits(); + + $this->assertIsString($data1->getStringStrict("0.commit.author.date")); + $this->assertSame( + "", + $data1->getStringStrict("0.commit.author.notexist"), + ); + $this->assertSame( + "AA", + $data1->getStringStrict("0.commit.author.notexist", "AA"), + ); + $this->assertSame( + "0", + $data1->getStringStrict("0.commit.comment_count"), + ); + $this->assertSame( + "0", + $data1->getStringStrict("0.commit.comment_count", "1"), + ); + $this->assertSame( + "1", + $data1->getStringStrict("0.commit.comment_countnotexists", "1"), + ); + } + + public function testGetInt(): void + { + $data1 = Block::fromJsonFile( + __DIR__ . "/data/commits-json/commits-10-p1.json", + ); + + $this->assertSame(678434, $data1->getInt("0.author.id")); + $this->assertNull($data1->getInt("0.author.idx")); + $this->assertSame(44, $data1->getInt("0.author.idx", 44)); + } + + public function testGetIntStrict(): void + { + $data1 = Block::fromJsonFile( + __DIR__ . "/data/commits-json/commits-10-p1.json", + ); + + $this->assertSame(678434, $data1->getIntStrict("0.author.id")); + $this->assertSame(0, $data1->getIntStrict("0.author.idx")); + $this->assertSame(44, $data1->getIntStrict("0.author.idx", 44)); + $this->assertSame(2024, $data1->getIntStrict("0.commit.author.date")); + } + + public function testGetBoolean(): void + { + $data1 = $this->loadCommits(); + + $this->assertIsBool($data1->getBoolean("0.author.site_admin")); + $this->assertNull($data1->getBoolean("0.author.notexist")); + $this->assertTrue($data1->getBoolean("0.author.notexist", true)); + $this->assertFalse($data1->getBoolean("0.author.notexist", false)); + $this->assertFalse($data1->getBoolean("0.author.site_admin")); + $this->assertFalse($data1->getBoolean("0.author.site_admin", true)); + $this->assertTrue( + $data1->getBoolean("0.commit.comment_countnotexists", true), + ); + } + + public function testGetBooleanStrict(): void + { + $data1 = $this->loadCommits(); + + $this->assertFalse($data1->getBooleanStrict("0.author.site_admin")); + $this->assertFalse($data1->getBooleanStrict("0.author.notexist")); + $this->assertTrue($data1->getBooleanStrict("0.author.notexist", true)); + $this->assertFalse( + $data1->getBooleanStrict("0.author.site_admin", true), + ); + $this->assertTrue( + $data1->getBooleanStrict("0.commit.comment_countnotexists", true), + ); + } + + public function testGetFloat(): void + { + $data = Block::make($this->fruitsArray); + + $this->assertInstanceOf(Block::class, $data); + $this->assertCount(4, $data); + $this->assertSame(8.5, $data->getFloat("banana.rating")); + $this->assertSame(7.0, $data->getFloat("apple.rating")); + $this->assertSame(1.2, $data->getFloat("foo", 1.2)); + $this->assertSame(0.0, $data->getFloatStrict("missing")); + } +} diff --git a/tests/BlockJsonSchemaTest.php b/tests/BlockJsonSchemaTest.php new file mode 100644 index 0000000..e33cd93 --- /dev/null +++ b/tests/BlockJsonSchemaTest.php @@ -0,0 +1,82 @@ + "Avocado", + "fruit" => "🥑", + "wikipedia" => "https://en.wikipedia.org/wiki/Avocado", + "color" => "green", + "rating" => 8, + ], + [ + "name" => "Apple", + "fruit" => "🍎", + "wikipedia" => "https://en.wikipedia.org/wiki/Apple", + "color" => "red", + "rating" => 7, + ], + [ + "name" => "Banana", + "fruit" => "🍌", + "wikipedia" => "https://en.wikipedia.org/wiki/Banana", + "color" => "yellow", + "rating" => 8.5, + ], + [ + "name" => "Cherry", + "fruit" => "🍒", + "wikipedia" => "https://en.wikipedia.org/wiki/Cherry", + "color" => "red", + "rating" => 9, + ], + ]; + + private string $schemaJson = <<<'JSON' + { + "type": "array", + "items" : { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "fruit": { + "type": "string" + }, + "wikipedia": { + "type": "string" + }, + "color": { + "type": "string" + }, + "rating": { + "type": "number" + } + } + } + } + JSON; + + public function testValidateJson(): void + { + $data = Block::make($this->fruitsArray); + + // validate against the correct schema + $this->assertTrue($data->validateJsonWithSchema($this->schemaJson)); + + // modify schema to require integer rating + $schemaBlock = Block::fromJsonString($this->schemaJson); + $schemaBlock->set("items.properties.rating.type", "integer"); + + $this->assertFalse( + $data->validateJsonWithSchema($schemaBlock->toJson()), + ); + } +} diff --git a/tests/BlockJsonTest.php b/tests/BlockJsonTest.php new file mode 100644 index 0000000..f87a435 --- /dev/null +++ b/tests/BlockJsonTest.php @@ -0,0 +1,112 @@ + [ + "name" => "Avocado", + "fruit" => "🥑", + "wikipedia" => "https://en.wikipedia.org/wiki/Avocado", + "color" => "green", + "rating" => 8, + ], + "apple" => [ + "name" => "Apple", + "fruit" => "🍎", + "wikipedia" => "https://en.wikipedia.org/wiki/Apple", + "color" => "red", + "rating" => 7, + ], + "banana" => [ + "name" => "Banana", + "fruit" => "🍌", + "wikipedia" => "https://en.wikipedia.org/wiki/Banana", + "color" => "yellow", + "rating" => 8.5, + ], + "cherry" => [ + "name" => "Cherry", + "fruit" => "🍒", + "wikipedia" => "https://en.wikipedia.org/wiki/Cherry", + "color" => "red", + "rating" => 9, + ], + ]; + + public function testToJson(): void + { + $data = Block::make($this->fruitsArray); + + $this->assertIsString($data->toJson()); + + $this->assertSame(773, strlen($data->toJson())); + + $string = $data->toJson(); + $data1 = Block::fromJsonString($string); + + $this->assertSame($data->get("0.fruit"), $data1->get("0.fruit")); + } + + public function testToJsonWithDifferentIterateBlock(): void + { + $data1 = Block::make($this->fruitsArray, true); + $string1 = $data1->toJson(); + + $data2 = Block::make($this->fruitsArray, false); + $string2 = $data2->toJson(); + + $this->assertIsString($string1); + $this->assertIsString($string2); + + $this->assertSame(773, strlen($string1)); + $this->assertSame(773, strlen($string2)); + + $this->assertSame($string1, $string2); + } + + public function testSaveToJson(): void + { + $data = Block::make($this->fruitsArray); + + $data->saveToJson("fruits.json"); + + $this->assertFileExists("fruits.json"); + + unlink("fruits.json"); + } + + public function testSaveToJsonWithOverwrite(): void + { + $data = Block::make($this->fruitsArray); + + $data->saveToJson("fruits.json"); + + $this->assertFileExists("fruits.json"); + + $result = $data->saveToJson("fruits.json", true); + + $this->assertTrue($result); + + unlink("fruits.json"); + } + + public function testSaveToJsonWithExistingFile(): void + { + $data = Block::make($this->fruitsArray); + + $data->saveToJson("fruits.json"); + + $this->assertFileExists("fruits.json"); + + $result = $data->saveToJson("fruits.json"); + + $this->assertFalse($result); + + unlink("fruits.json"); + } +} diff --git a/tests/BlockQueryAdvancedTest.php b/tests/BlockQueryAdvancedTest.php new file mode 100644 index 0000000..62ef82e --- /dev/null +++ b/tests/BlockQueryAdvancedTest.php @@ -0,0 +1,166 @@ + [ + "name" => "Avocado", + "fruit" => "🥑", + "wikipedia" => "https://en.wikipedia.org/wiki/Avocado", + "color" => "green", + "rating" => 8, + "tags" => ["healthy", "creamy", "green"], + ], + "apple" => [ + "name" => "Apple", + "fruit" => "🍎", + "wikipedia" => "https://en.wikipedia.org/wiki/Apple", + "color" => "red", + "rating" => 7, + "tags" => ["classic", "crunchy", "juicy", "red", "sweet"], + ], + "banana" => [ + "name" => "Banana", + "fruit" => "🍌", + "wikipedia" => "https://en.wikipedia.org/wiki/Banana", + "color" => "yellow", + "rating" => 8.5, + "tags" => ["sweet", "soft", "yellow"], + ], + "cherry" => [ + "name" => "Cherry", + "fruit" => "🍒", + "wikipedia" => "https://en.wikipedia.org/wiki/Cherry", + "color" => "red", + "rating" => 9, + "tags" => ["small", "tart", "red"], + ], + ]; + + public function testQueryGreaterThan(): void + { + $data = Block::make($this->fruitsArray); + $highRated = $data->where("rating", Operator::GREATER_THAN, 8); + $this->assertCount(2, $highRated); + + $sorted = $data + ->where("rating", Operator::GREATER_THAN, 8) + ->orderBy("rating", "desc"); + $this->assertCount(2, $sorted); + } + + public function testGroupByColor(): void + { + $table = Block::make($this->fruitsArray); + $grouped = $table->groupBy("color"); + + $this->assertCount(2, $grouped->getBlock("red")); + $this->assertCount(1, $grouped->getBlock("yellow")); + $this->assertCount(0, $grouped->getBlock("NotExists")); + } + + public function testGroupByArray(): void + { + $data = Block::make([ + ["type" => "fruit", "name" => "apple"], + ["type" => "fruit", "name" => "banana"], + ["type" => "vegetable", "name" => "carrot"], + ]); + $grouped = $data->groupBy("type"); + + $this->assertCount(2, $grouped->getBlock("fruit")); + $this->assertCount(1, $grouped->getBlock("vegetable")); + $this->assertCount(0, $grouped->getBlock("NotExists")); + } + + public function testGroupByFunction(): void + { + $fruits = [ + ["name" => "Apple", "type" => "Citrus", "quantity" => 15], + ["name" => "Banana", "type" => "Tropical", "quantity" => 10], + ["name" => "Orange", "type" => "Citrus", "quantity" => 8], + ["name" => "Mango", "type" => "Tropical", "quantity" => 5], + ["name" => "Lemon", "type" => "Citrus", "quantity" => 12], + ]; + + $fruitsBlock = Block::make($fruits); + + $groupedByQuantityRange = $fruitsBlock->groupByFunction( + fn($fruit): string => match (true) { + $fruit["quantity"] < 10 => "Low", + $fruit["quantity"] < 15 => "Medium", + default => "High", + }, + ); + + $this->assertCount(3, $groupedByQuantityRange); + $this->assertCount(2, $groupedByQuantityRange->getBlock("Low")); + $this->assertCount(2, $groupedByQuantityRange->getBlock("Medium")); + $this->assertCount(1, $groupedByQuantityRange->getBlock("High")); + + $groupedByNameLength = $fruitsBlock->groupByFunction( + fn($fruit): int => strlen((string) $fruit["name"]), + ); + + $this->assertCount(2, $groupedByNameLength); + $this->assertTrue($groupedByNameLength->hasKey(5)); + $this->assertTrue($groupedByNameLength->hasKey("6")); + $this->assertCount(3, $groupedByNameLength->get("5")); + $this->assertCount(2, $groupedByNameLength->get("6")); + } + + public function testWhereInOperator(): void + { + $data = Block::make($this->fruitsArray); + + $greenOrBlack = $data->where("color", Operator::IN, ["green", "black"]); + $this->assertCount(1, $greenOrBlack); + + $noResult = $data->where("color", Operator::IN, []); + $this->assertCount(0, $noResult); + + $greenOrRed = $data->where("color", Operator::IN, ["green", "red"]); + $this->assertCount(3, $greenOrRed); + } + + public function testWhereHasOperator(): void + { + $data = Block::make($this->fruitsArray); + + $sweet = $data->where("tags", Operator::HAS, "sweet"); + $this->assertCount(2, $sweet); + + $noResult = $data->where("tags", Operator::HAS, "not-existent"); + $this->assertCount(0, $noResult); + + $softFruit = $data->where("tags", Operator::HAS, "soft"); + $this->assertCount(1, $softFruit); + } + + public function testQueryWithOperators(): void + { + $data1 = Block::fromJsonFile( + __DIR__ . "/data/commits-json/commits-10-p1.json", + ); + $data2 = Block::fromJsonFile( + __DIR__ . "/data/commits-json/commits-10-p2.json", + ); + $data3 = Block::fromJsonFile( + __DIR__ . "/data/commits-json/commits-10-p3.json", + ); + + $data1->append($data2)->append($data3); + + $this->assertCount(30, $data1); + $this->assertCount(10, $data2); + + $block = $data1->where("commit.author.name", Operator::LIKE, "Roberto"); + $this->assertEquals(29, $block->count()); + } +} diff --git a/tests/BlockQueryTest.php b/tests/BlockQueryTest.php new file mode 100644 index 0000000..758b67f --- /dev/null +++ b/tests/BlockQueryTest.php @@ -0,0 +1,181 @@ +getBlock("story.content.body") + ->where("component", "==", "banner"); + + $this->assertCount(2, $banners); + $this->assertSame("New banner", $banners->get("0.headline")); + $this->assertSame( + "Top Five Discoveries, Curiosity Rover at Mars", + $banners->get("4.headline"), + ); + + $composerContent = Block::fromJsonString($jsonString); + + $banners = $composerContent + ->getBlock("story.content.body") + ->where("component", Operator::NOT_EQUAL, "banner", false); + + $this->assertCount(8, $banners); + $this->assertSame("hero-section", $banners->get("0.component")); + $this->assertSame("grid-section", $banners->get("4.component")); + } + + public function testQueryAndSelectBlock(): void + { + $jsonString = file_get_contents(__DIR__ . "/data/story.json"); + + $composerContent = Block::fromJsonString($jsonString); + + $banners = $composerContent + ->getBlock("story.content.body") + ->where("component", Operator::EQUAL, "banner") + ->select("headline"); + + $this->assertCount(2, $banners); + + $this->assertCount(1, $banners->get("0")); + $this->assertSame("New banner", $banners->get("0.headline")); + + $this->assertCount(1, $banners->get("1")); + $this->assertSame( + "Top Five Discoveries, Curiosity Rover at Mars", + $banners->get("1.headline"), + ); + + $composerContent = Block::fromJsonString($jsonString); + + $banners = $composerContent + ->getBlock("story.content.body") + ->where("component", Operator::NOT_EQUAL, "banner", false); + + $this->assertCount(8, $banners); + $this->assertSame("hero-section", $banners->get("0.component")); + $this->assertSame("grid-section", $banners->get("4.component")); + } + + public function testOrderBlock(): void + { + $jsonString = file_get_contents(__DIR__ . "/data/story.json"); + + $composerContent = Block::fromJsonString($jsonString); + + $bodyComponents = $composerContent + ->getBlock("story.content.body") + ->orderBy("component", "asc"); + + $this->assertCount(10, $bodyComponents); + $this->assertSame("banner", $bodyComponents->get("0.component")); + $this->assertSame("text-section", $bodyComponents->get("9.component")); + + $bodyComponents = $composerContent + ->getBlock("story.content.body") + ->orderBy("component", "desc"); + + $this->assertCount(10, $bodyComponents); + $this->assertSame("banner", $bodyComponents->get("9.component")); + $this->assertSame("text-section", $bodyComponents->get("0.component")); + } + + public function testLocalDummyJsonPost(): void + { + $response = Block::fromJsonFile(__DIR__ . "/data/dummy-posts-30.json"); + + $this->assertInstanceOf(Block::class, $response); + $this->assertCount(4, $response); + + $posts = $response->getBlock("posts"); + + $this->assertInstanceOf(Block::class, $posts); + $this->assertCount(30, $posts); + + $lovePosts = $posts->where("tags", Operator::HAS, "love"); + $this->assertCount(9, $lovePosts); + + $mostViewedPosts = $posts->orderBy("views", "desc"); + $this->assertCount(30, $mostViewedPosts); + $this->assertSame(2, $mostViewedPosts->get("0.id")); + $this->assertSame(4884, $mostViewedPosts->get("0.views")); + + $lessViewedPosts = $posts->orderBy("views"); // asc default + $this->assertCount(30, $lessViewedPosts); + $this->assertSame(6, $lessViewedPosts->get("0.id")); + $this->assertSame(38, $lessViewedPosts->get("0.views")); + + $mostLikedPosts = $posts->orderBy("reactions.likes", "desc"); + $this->assertCount(30, $mostLikedPosts); + $this->assertSame(3, $mostLikedPosts->get("0.id")); + $this->assertSame(1448, $mostLikedPosts->get("0.reactions.likes")); + + // Ensure original collection is not mutated + $this->assertCount(30, $posts); + $this->assertSame(1, $posts->get("0.id")); + $this->assertSame(192, $posts->get("0.reactions.likes")); + } + + public function testQueryBlockWithHas(): void + { + $jsonString = file_get_contents(__DIR__ . "/data/story.json"); + + $composerContent = Block::fromJsonString($jsonString); + + $has = $composerContent + ->getBlock("story.content.body") + ->where("component", Operator::EQUAL, "banner") + ->exists(); + + $this->assertTrue($has); + + $has = $composerContent + ->getBlock("story.content.body") + ->where("component", Operator::NOT_EQUAL, "banner") + ->exists(); + + $this->assertTrue($has); + + $has = $composerContent + ->getBlock("story.content.body") + ->where("component", Operator::EQUAL, "bannerXXX") + ->exists(); + + $this->assertFalse($has); + + $has = $composerContent + ->getBlock("story.content.body") + ->where("component", "banner") + ->exists(); + + $this->assertTrue($has); + } + + public function testQueryBlockExtractWhere(): void + { + $jsonString = file_get_contents(__DIR__ . "/data/story.json"); + + $story = Block::fromJsonString($jsonString); + + $assets = $story->extractWhere("fieldtype", "asset"); + + $this->assertCount(16, $assets); + + $this->assertStringStartsWith( + "https://a.story", + $assets->get("3.filename"), + ); + } +} diff --git a/tests/BlockRemoteTest.php b/tests/BlockRemoteTest.php new file mode 100644 index 0000000..6a6600a --- /dev/null +++ b/tests/BlockRemoteTest.php @@ -0,0 +1,92 @@ +assertInstanceOf(Block::class, $commits); + $this->assertCount(30, $commits); + + $myCommits = $commits->where("commit.author.name", "like", "Roberto"); + + foreach ($myCommits as $value) { + $this->assertIsString($value->get("commit.message")); + } + } + + #[Group("url")] + public function testRemoteJsonWithSymfonyHttpClient(): void + { + $url = "https://api.github.com/repos/hi-folks/data-block/commits"; + + $commits = Block::fromHttpJsonUrl($url, HttpClient::create()); + + $this->assertInstanceOf(Block::class, $commits); + $this->assertCount(30, $commits); + + $myCommits = $commits->where("commit.author.name", "like", "Roberto"); + + foreach ($myCommits as $value) { + $this->assertIsString($value->get("commit.message")); + } + } + + #[Group("url")] + public function testRemoteDummyJsonPost(): void + { + $url = "https://dummyjson.com/posts"; + + $response = Block::fromJsonUrl($url); + $posts = $response->getBlock("posts"); + + $this->assertInstanceOf(Block::class, $posts); + $this->assertCount(30, $posts); + + $lovePosts = $posts->where("tags", "has", "love"); + + $this->assertCount(9, $lovePosts); + } + + #[Group("url")] + public function testRemoteForeach(): void + { + $url = "https://dummyjson.com/posts"; + + $posts = Block::fromJsonUrl($url) + ->getBlock("posts") + ->where( + field: "tags", + operator: "has", + value: "love", + preseveKeys: false, + ) + ->forEach( + fn($element): array => [ + "title" => strtoupper((string) $element->get("title")), + "tags" => count($element->get("tags")), + ], + ); + + $this->assertInstanceOf(Block::class, $posts); + $this->assertCount(9, $posts); + + $this->assertSame( + "HOPES AND DREAMS WERE DASHED THAT DAY.", + $posts->get("0.title"), + ); + + $this->assertSame(3, $posts->get("0.tags")); + } +} diff --git a/tests/BlockSchemaValidationTest.php b/tests/BlockSchemaValidationTest.php new file mode 100644 index 0000000..e2f67d3 --- /dev/null +++ b/tests/BlockSchemaValidationTest.php @@ -0,0 +1,34 @@ +assertTrue( + $workflow->validateJsonViaUrl( + "https://json.schemastore.org/github-workflow", + ), + ); + } + + #[Group("url")] + public function testValidateYamlObjectGithubWorkflow(): void + { + $file = __DIR__ . "/../.github/workflows/run-tests.yml"; + + $workflow = Block::fromYamlFile($file); + + $this->assertTrue($workflow->validateJsonSchemaGithubWorkflow()); + } +} diff --git a/tests/BlockSetTest.php b/tests/BlockSetTest.php new file mode 100644 index 0000000..c43c668 --- /dev/null +++ b/tests/BlockSetTest.php @@ -0,0 +1,45 @@ +set("type", "doc"); + $textField->set("content.0.content.0.text", $articleText); + $textField->set("content.0.content.0.type", "text"); + $textField->set("content.0.type", "paragraph"); + + $this->assertSame( + $articleText, + $textField->get("content.0.content.0.text"), + ); + + $this->assertIsArray($textField->get("content.0.content.0")); + + $this->assertCount(2, $textField->get("content.0.content.0")); + + $this->assertNull($textField->get("content.0.content.0.newfield")); + + $textField->set("content.0.content.0.newfield", "THIS IS A NEW FIELD"); + + $this->assertIsString($textField->get("content.0.content.0.newfield")); + + $this->assertSame( + "THIS IS A NEW FIELD", + $textField->get("content.0.content.0.newfield"), + ); + + $this->assertIsArray($textField->get("content.0.content.0")); + + $this->assertCount(3, $textField->get("content.0.content.0")); + } +} diff --git a/tests/BlockTableTest.php b/tests/BlockTableTest.php new file mode 100644 index 0000000..e302525 --- /dev/null +++ b/tests/BlockTableTest.php @@ -0,0 +1,231 @@ + "Desk", "price" => 200, "active" => true], + ["product" => "Chair", "price" => 100, "active" => true], + ["product" => "Door", "price" => 300, "active" => false], + ["product" => "Bookcase", "price" => 150, "active" => true], + ["product" => "Door", "price" => 100, "active" => true], + ]; + + public function testBlockAsTable(): void + { + $table = Block::make($this->dataTable); + + $data = $table->where("price", Operator::GREATER_THAN, 100); + + $this->assertCount(3, $data); + } + + public function testBlockAsTableSelectAndWhere(): void + { + $table = Block::make($this->dataTable); + + $data = $table + ->select("product", "price") + ->where("price", Operator::GREATER_THAN, 100, false); + + $this->assertCount(3, $data); + + $this->assertCount(2, $data->get("0")); + $this->assertArrayHasKey("product", $data->get("0")); + $this->assertArrayHasKey("price", $data->get("0")); + $this->assertSame("Desk", $data->get("0.product")); + $this->assertSame("Door", $data->get("1.product")); + + $table = Block::make($this->dataTable); + + $data = $table->select("product", "price"); + + $this->assertCount(5, $data); + + $this->assertCount(2, $data->get("0")); + $this->assertSame("Desk", $data->get("0.product")); + $this->assertSame(200, $data->get("0.price")); + + $this->assertCount(2, $data->get("1")); + $this->assertSame("Chair", $data->get("1.product")); + $this->assertSame(100, $data->get("1.price")); + + $this->assertCount(2, $data->get("4")); + $this->assertSame("Door", $data->get("4.product")); + $this->assertSame(100, $data->get("4.price")); + } + + public function testReturnBlockWhileLooping(): void + { + $table = Block::make($this->dataTable); + + $data = $table + ->select("product", "price") + ->where("price", Operator::GREATER_THAN, 100, false); + + foreach ($data as $key => $item) { + $this->assertInstanceOf(Block::class, $item); + $this->assertIsInt($key); + $this->assertGreaterThan(100, $item->get("price")); + } + + $this->assertSame(200, $data->get("0.price")); + $this->assertSame(300, $data->get("1.price")); + + // original table unchanged + $this->assertSame(200, $table->get("0.price")); + $this->assertSame(100, $table->get("1.price")); + + // array mode + $table = Block::make($this->dataTable, false); + + $data = $table + ->select("product", "price") + ->where("price", Operator::GREATER_THAN, 100, false); + + foreach ($data as $key => $item) { + $this->assertIsArray($item); + $this->assertIsInt($key); + $this->assertGreaterThan(100, $item["price"]); + $this->assertGreaterThan(100, $data[$key]["price"]); + } + + // reusing $data + foreach ($data as $key => $item) { + $this->assertIsArray($item); + $this->assertIsInt($key); + $this->assertGreaterThan(100, $item["price"]); + } + + // block iteration mode + $table = Block::make($this->dataTable, true); + + foreach ($table as $key => $item) { + $this->assertInstanceOf(Block::class, $item); + $this->assertIsInt($key); + $this->assertGreaterThan(10, $item->get("price")); + } + + foreach ($table->iterateBlock(false) as $key => $item) { + $this->assertIsArray($item); + $this->assertIsInt($key); + $this->assertGreaterThan(10, $item["price"]); + } + + // previous state preserved + foreach ($table as $key => $item) { + $this->assertIsArray($item); + $this->assertIsInt($key); + $this->assertGreaterThan(10, $item["price"]); + } + + foreach ($table->iterateBlock(true) as $key => $item) { + $this->assertInstanceOf(Block::class, $item); + $this->assertIsInt($key); + $this->assertGreaterThan(10, $item->get("price")); + } + + foreach ($table->iterateBlock(false) as $key => $item) { + $this->assertIsArray($item); + $this->assertIsInt($key); + $this->assertGreaterThan(10, $item["price"]); + } + } + + public function testGroupBy(): void + { + $table = Block::make($this->dataTable); + + $grouped = $table->groupBy("product"); + + $this->assertCount(2, $grouped->getBlock("Door")); + $this->assertCount(1, $grouped->getBlock("Desk")); + $this->assertCount(0, $grouped->getBlock("NotExists")); + } + + public function testExtractJsonByAttribute(): void + { + $file = __DIR__ . "/data/stories.json"; + + $block = Block::fromJsonFile($file); + + $rel = $block + ->getBlock("rels") + ->where( + "uuid", + Operator::EQUAL, + "a6af7728-eadf-4428-8cf5-343304857374", + ); + + $this->assertCount(1, $rel); + $this->assertSame("Category C", $rel->get("4.name")); + $this->assertCount(22, $rel->get("4")); + + $rel = $block + ->getBlock("rels") + ->where( + field: "uuid", + operator: Operator::EQUAL, + value: "a6af7728-eadf-4428-8cf5-343304857374", + preseveKeys: false, + ); + + $this->assertCount(1, $rel); + $this->assertSame("Category C", $rel->get("0.name")); + $this->assertCount(22, $rel->get("0")); + + $rel = $block + ->getBlock("rels") + ->select("uuid", "name") + ->where( + field: "uuid", + operator: Operator::EQUAL, + value: "a6af7728-eadf-4428-8cf5-343304857374", + preseveKeys: false, + ); + + $this->assertCount(1, $rel); + $this->assertSame("Category C", $rel->get("0.name")); + $this->assertCount(2, $rel->get("0")); + } + + public function testApplyField(): void + { + $table = Block::make([ + "title" => "Title", + "number" => 11, + ]); + + $table->applyField( + "number", + "newfield", + fn($value): int|float => $value * 2, + ); + + $this->assertCount(3, $table); + $this->assertSame(22, $table->get("newfield")); + $this->assertSame(11, $table->get("number")); + } + + public function testApplyField2(): void + { + $object = Block::make(); + + $object + ->set("name", "John Doe") + ->applyField( + "name", + "uppercase_name", + fn($value): string => strtoupper((string) $value), + ); + + $this->assertCount(2, $object); + $this->assertSame("JOHN DOE", $object->get("uppercase_name")); + $this->assertSame("John Doe", $object->get("name")); + } +} diff --git a/tests/BlockTest.php b/tests/BlockTest.php new file mode 100644 index 0000000..23be256 --- /dev/null +++ b/tests/BlockTest.php @@ -0,0 +1,153 @@ +assertSame("Home", $composerContent->get("story.name")); + + $this->assertInstanceOf( + Block::class, + $composerContent->getBlock("story.content"), + ); + + $this->assertArrayHasKey( + "body", + $composerContent->get("story.content"), + ); + + $bodyComponents = $composerContent->getBlock("story.content.body"); + + $this->assertCount(10, $bodyComponents); + + $this->assertSame("New banner", $bodyComponents->get("0.headline")); + $this->assertSame("Hello Everyone", $bodyComponents->get("1.headline")); + $this->assertSame( + "We don't know what we don't know.", + $bodyComponents->get("2.headline"), + ); + + $this->assertSame(1717763755, $composerContent->get("cv")); + } + + public function testLoadJsonObject(): void + { + $file = __DIR__ . "/../composer.json"; + + $composerContent = Block::fromJsonFile($file); + + $this->assertSame("hi-folks/data-block", $composerContent->get("name")); + $this->assertSame( + "Roberto B.", + $composerContent->get("authors.0.name"), + ); + + $composerContent->set("authors.0.name", "Test"); + + $this->assertSame("Test", $composerContent->get("authors.0.name")); + } + + public function testExportToArray(): void + { + $file = __DIR__ . "/../composer.json"; + + $composerContent = Block::fromJsonFile($file); + + $array = $composerContent->toArray(); + + $this->assertIsArray($array); + + $this->assertArrayHasKey("name", $array); + $this->assertArrayHasKey("authors", $array); + + $this->assertArrayHasKey(0, $array["authors"]); + $this->assertArrayHasKey("name", $array["authors"][0]); + + $this->assertSame("Roberto B.", $array["authors"][0]["name"]); + } + + public function testLoadYamlObject(): void + { + $file = __DIR__ . "/../.github/workflows/run-tests.yml"; + + $workflow = Block::fromYamlFile($file); + + $this->assertIsArray($workflow->get("on")); + $this->assertCount(2, $workflow->get("on")); + + $this->assertSame("push", $workflow->get("on.0")); + $this->assertSame("pull_request", $workflow->get("on.1")); + + $this->assertSame( + '${{ matrix.os }}', + $workflow->get("jobs.test.runs-on"), + ); + } + + public function testConvertJsonToYaml(): void + { + $file = __DIR__ . "/../composer.json"; + + $composer1 = Block::fromJsonFile($file); + + $yaml = $composer1->toYaml(); + + $composer2 = Block::fromYamlString($yaml); + + $this->assertSame("hi-folks/data-block", $composer2->get("name")); + $this->assertSame("Roberto B.", $composer2->get("authors.0.name")); + } + + public function testHasSomeValue(): void + { + $file = __DIR__ . "/../composer.json"; + + $composer = Block::fromJsonFile($file); + + $this->assertInstanceOf(Block::class, $composer->getBlock("require")); + $this->assertInstanceOf( + Block::class, + $composer->getBlock("require.php"), + ); + $this->assertIsString($composer->get("require.php")); + + $this->assertTrue( + $composer->getBlock("require")->has("^8.2|^8.3|^8.4|^8.5"), + ); + + $this->assertTrue($composer->getBlock("require")->hasKey("php")); + + $this->assertTrue( + $composer->getBlock("require-dev")->hasKey("phpunit/phpunit"), + ); + } + + public function testSomeValueForComposerLock(): void + { + $file = __DIR__ . "/data/dummy-composer.lock"; + + $composer = Block::fromJsonFile($file); + + $this->assertInstanceOf(Block::class, $composer->getBlock("packages")); + $this->assertCount(7, $composer->getBlock("packages")); + + $this->assertCount( + 7, + $composer->getBlock("packages")->where("dist.type", "zip"), + ); + + $this->assertCount( + 7, + $composer->getBlock("packages")->where("source.type", "git"), + ); + } +} diff --git a/tests/Feature/BlockTest.php b/tests/Feature/BlockTest.php deleted file mode 100644 index c4d529e..0000000 --- a/tests/Feature/BlockTest.php +++ /dev/null @@ -1,91 +0,0 @@ -get("story.name"))->toBe("Home"); - expect($composerContent->getBlock("story.content"))->toBeInstanceOf( - Block::class, - ); - expect($composerContent->get("story.content"))->toHaveKey("body"); - $bodyComponents = $composerContent->getBlock("story.content.body"); - expect($bodyComponents)->toHaveCount(10); - expect($bodyComponents->get("0.headline"))->toBe("New banner"); - expect($bodyComponents->get("1.headline"))->toBe("Hello Everyone"); - expect($bodyComponents->get("2.headline"))->toBe( - "We don't know what we don't know.", - ); - expect($composerContent->get("cv"))->toBe(1717763755); -}); - -it("load JSON object", function (): void { - $file = "./composer.json"; - $composerContent = Block::fromJsonFile($file); - expect($composerContent->get("name"))->toBe("hi-folks/data-block"); - expect($composerContent->get("authors.0.name"))->toBe("Roberto B."); - $composerContent->set("authors.0.name", "Test"); - expect($composerContent->get("authors.0.name"))->toBe("Test"); -}); - -it("export to array", function (): void { - $file = "./composer.json"; - $composerContent = Block::fromJsonFile($file); - $array = $composerContent->toArray(); - expect($array)->toBeArray(); - expect($array)->toHaveKeys(["name", "authors"]); - expect($array["authors"])->toHaveKeys([0]); - expect($array["authors"][0])->toHaveKeys(["name"]); - expect($array["authors"][0]["name"])->toBe("Roberto B."); -}); - -it("load YAML object", function (): void { - $file = "./.github/workflows/run-tests.yml"; - $workflow = Block::fromYamlFile($file); - expect($workflow->get("on"))->toBeArray(); - expect($workflow->get("on"))->toHaveCount(2); - expect($workflow->get("on.0"))->toBe("push"); - expect($workflow->get("on.1"))->toBe("pull_request"); - expect($workflow->get("jobs.test.runs-on"))->toBe('${{ matrix.os }}'); -}); - -it("Convert Json to Yaml", function (): void { - $file = "./composer.json"; - $composer1 = Block::fromJsonFile($file); - $yaml = $composer1->toYaml(); - $composer2 = Block::fromYamlString($yaml); - expect($composer2->get("name"))->toBe("hi-folks/data-block"); - expect($composer2->get("authors.0.name"))->toBe("Roberto B."); -}); - -it("has some value", function (): void { - $file = "./composer.json"; - $composer = Block::fromJsonFile($file); - expect($composer->getBlock("require"))->toBeInstanceOf(Block::class); - expect($composer->getBlock("require.php"))->toBeInstanceOf(Block::class); - expect($composer->get("require.php"))->toBeString(); - - expect($composer->getBlock("require")->has("^8.3|^8.4|^8.5"))->toBeTrue(); - expect($composer->getBlock("require")->hasKey("php"))->toBeTrue(); - expect( - $composer->getBlock("require-dev")->hasKey("pestphp/pest"), - )->toBeTrue(); -}); - -it("tests some value for composer.lock", function (): void { - $file = "./tests/data/dummy-composer.lock"; - $composer = Block::fromJsonFile($file); - expect($composer->getBlock("packages"))->toBeInstanceOf(Block::class); - expect($composer->getBlock("packages"))->toHaveCount(7); - expect( - $composer->getBlock("packages")->where("dist.type", "zip"), - )->toHaveCount(7); - expect( - $composer->getBlock("packages")->where("dist.type", "zip"), - )->toHaveCount(7); - expect( - $composer->getBlock("packages")->where("source.type", "git"), - )->toHaveCount(7); -}); diff --git a/tests/Feature/QueryBlockTest.php b/tests/Feature/QueryBlockTest.php deleted file mode 100644 index 4e3f01a..0000000 --- a/tests/Feature/QueryBlockTest.php +++ /dev/null @@ -1,139 +0,0 @@ -getBlock("story.content.body") - ->where("component", "==", "banner"); - expect($banners)->toHaveCount(2); - expect($banners->get("0.headline"))->toBe("New banner"); - expect($banners->get("4.headline"))->toBe( - "Top Five Discoveries, Curiosity Rover at Mars", - ); - - $composerContent = Block::fromJsonString($jsonString); - $banners = $composerContent - ->getBlock("story.content.body") - ->where("component", Operator::NOT_EQUAL, "banner", false); - expect($banners)->toHaveCount(8); - expect($banners->get("0.component"))->toBe("hero-section"); - expect($banners->get("4.component"))->toBe("grid-section"); -}); - -test("Query and select Block", function (): void { - $jsonString = file_get_contents("./tests/data/story.json"); - - $composerContent = Block::fromJsonString($jsonString); - $banners = $composerContent - ->getBlock("story.content.body") - ->where("component", Operator::EQUAL, "banner") - ->select("headline"); - expect($banners)->toHaveCount(2); - expect($banners->get("0"))->toHaveCount(1); - expect($banners->get("0.headline"))->toBe("New banner"); - expect($banners->get("1"))->toHaveCount(1); - expect($banners->get("1.headline"))->toBe( - "Top Five Discoveries, Curiosity Rover at Mars", - ); - - $composerContent = Block::fromJsonString($jsonString); - $banners = $composerContent - ->getBlock("story.content.body") - ->where("component", Operator::NOT_EQUAL, "banner", false); - expect($banners)->toHaveCount(8); - expect($banners->get("0.component"))->toBe("hero-section"); - expect($banners->get("4.component"))->toBe("grid-section"); -}); - -test("Order Block", function (): void { - $jsonString = file_get_contents("./tests/data/story.json"); - - $composerContent = Block::fromJsonString($jsonString); - $bodyComponents = $composerContent - ->getBlock("story.content.body") - ->orderBy("component", "asc"); - expect($bodyComponents)->toHaveCount(10); - expect($bodyComponents->get("0.component"))->toBe("banner"); - expect($bodyComponents->get("9.component"))->toBe("text-section"); - - $bodyComponents = $composerContent - ->getBlock("story.content.body") - ->orderBy("component", "desc"); - expect($bodyComponents)->toHaveCount(10); - expect($bodyComponents->get("9.component"))->toBe("banner"); - expect($bodyComponents->get("0.component"))->toBe("text-section"); -}); - -it("local dummyjson post", function (): void { - $response = Block::fromJsonFile("./tests/data/dummy-posts-30.json"); - expect($response)->toBeInstanceOf(Block::class); - expect($response)->toHaveCount(4); - - $posts = $response->getBlock("posts"); - - expect($posts)->toBeInstanceOf(Block::class); - expect($posts)->toHaveCount(30); - $lovePosts = $posts->where("tags", Operator::HAS, "love"); - expect($lovePosts)->toHaveCount(9); - - $mostViewedPosts = $posts->orderBy("views", "desc"); - //$mostViewedPosts->dumpJson(); - expect($mostViewedPosts)->toHaveCount(30); - expect($mostViewedPosts->get("0.id"))->toBe(2); - expect($mostViewedPosts->get("0.views"))->toBe(4884); - - $lessViewedPosts = $posts->orderBy("views"); //by default ascending - //$lessViewedPosts->dumpJson(); - expect($lessViewedPosts)->toHaveCount(30); - expect($lessViewedPosts->get("0.id"))->toBe(6); - expect($lessViewedPosts->get("0.views"))->toBe(38); - - $mostLikedPosts = $posts->orderBy("reactions.likes", "desc"); - //$mostLikedPosts->dumpJson(); - expect($mostLikedPosts)->toHaveCount(30); - expect($mostLikedPosts->get("0.id"))->toBe(3); - expect($mostLikedPosts->get("0.reactions.likes"))->toBe(1448); - - expect($posts)->toHaveCount(30); - expect($posts->get("0.id"))->toBe(1); - expect($posts->get("0.reactions.likes"))->toBe(192); -}); - -test("Query Block with has", function (): void { - $jsonString = file_get_contents("./tests/data/story.json"); - $composerContent = Block::fromJsonString($jsonString); - $has = $composerContent - ->getBlock("story.content.body") - ->where("component", Operator::EQUAL, "banner") - ->exists(); - expect($has)->toBeTrue(); - $has = $composerContent - ->getBlock("story.content.body") - ->where("component", Operator::NOT_EQUAL, "banner") - ->exists(); - expect($has)->toBeTrue(); - $has = $composerContent - ->getBlock("story.content.body") - ->where("component", Operator::EQUAL, "bannerXXX") - ->exists(); - expect($has)->toBeFalse(); - $has = $composerContent - ->getBlock("story.content.body") - ->where("component", "banner") - ->exists(); - expect($has)->toBeTrue(); -}); - -test("Query Block extractWhere", function (): void { - $jsonString = file_get_contents("./tests/data/story.json"); - - $story = Block::fromJsonString($jsonString); - $assets = $story->extractWhere("fieldtype", "asset"); - expect($assets)->toHaveCount(16); - expect($assets->get("3.filename"))->toStartWith("https://a.story"); -}); diff --git a/tests/Feature/UrlTest.php b/tests/Feature/UrlTest.php deleted file mode 100644 index d1d969c..0000000 --- a/tests/Feature/UrlTest.php +++ /dev/null @@ -1,67 +0,0 @@ -toBeInstanceOf(Block::class); - expect($commits)->toHaveCount(30); - $myCommits = $commits->where("commit.author.name", "like", "Roberto"); - foreach ($myCommits as $value) { - expect($value->get("commit.message"))->toBeString(); - } - -})->group("url"); - -it('remote json (Symfony\Contracts\HttpClient\HttpClientInterface)', function (): void { - $url = "https://api.github.com/repos/hi-folks/data-block/commits"; - - $commits = Block::fromHttpJsonUrl($url, HttpClient::create()); - expect($commits)->toBeInstanceOf(Block::class); - expect($commits)->toHaveCount(30); - - $myCommits = $commits->where("commit.author.name", "like", "Roberto"); - foreach ($myCommits as $value) { - expect($value->get("commit.message"))->toBeString(); - } - -})->group("url"); - -it('remote dummyjson post', function (): void { - - $url = "https://dummyjson.com/posts"; - $response = Block::fromJsonUrl($url); - $posts = $response->getBlock("posts"); - - expect($posts)->toBeInstanceOf(Block::class); - expect($posts)->toHaveCount(30); - $lovePosts = $posts->where("tags", "has", "love"); - expect($lovePosts)->toHaveCount(9); - - -})->group("url"); - -it('remote foreach', function (): void { - - $url = "https://dummyjson.com/posts"; - $posts = Block::fromJsonUrl($url) - ->getBlock("posts") - ->where( - field: "tags", - operator: "has", - value: "love", - preseveKeys: false, - ) - ->forEach(fn($element): array => [ - "title" => strtoupper((string) $element->get("title")), - "tags" => count($element->get("tags")), - ]); - expect($posts)->toBeInstanceOf(Block::class); - expect($posts)->toHaveCount(9); - expect($posts->get("0.title"))->toBe("HOPES AND DREAMS WERE DASHED THAT DAY."); - expect($posts->get("0.tags"))->toBe(3); - -})->group("url"); diff --git a/tests/Feature/ValidataTest.php b/tests/Feature/ValidataTest.php deleted file mode 100644 index 75415cd..0000000 --- a/tests/Feature/ValidataTest.php +++ /dev/null @@ -1,17 +0,0 @@ -validateJsonViaUrl('https://json.schemastore.org/github-workflow'))->toBeTrue(); - - -})->group("url"); - -it('validate YAML object Github Workflow', function (): void { - $file = "./.github/workflows/run-tests.yml"; - $workflow = Block::fromYamlFile($file); - expect($workflow->validateJsonSchemaGithubWorkflow())->toBeTrue(); -})->group("url"); diff --git a/tests/Unit/LoadJsonObjectHttpTest.php b/tests/LoadJsonObjectHttpTest.php similarity index 93% rename from tests/Unit/LoadJsonObjectHttpTest.php rename to tests/LoadJsonObjectHttpTest.php index 29b7d87..65bf1e0 100644 --- a/tests/Unit/LoadJsonObjectHttpTest.php +++ b/tests/LoadJsonObjectHttpTest.php @@ -7,7 +7,7 @@ class LoadJsonObjectHttpTest extends TestCase { public function testLoadJsonObjectHttp(): void { - $jsonString = file_get_contents(__DIR__ . "/../data/story.json"); + $jsonString = file_get_contents(__DIR__ . "/data/story.json"); $composerContent = Block::fromJsonString($jsonString); diff --git a/tests/Pest.php b/tests/Pest.php deleted file mode 100644 index 18411d7..0000000 --- a/tests/Pest.php +++ /dev/null @@ -1,43 +0,0 @@ -in('Feature'); - -/* -|-------------------------------------------------------------------------- -| Expectations -|-------------------------------------------------------------------------- -| -| When you're writing tests, you often need to check that values meet certain conditions. The -| "expect()" function gives you access to a set of "expectations" methods that you can use -| to assert different things. Of course, you may extend the Expectation API at any time. -| -*/ - -expect()->extend('toBeOne', fn() => $this->toBe(1)); - -/* -|-------------------------------------------------------------------------- -| Functions -|-------------------------------------------------------------------------- -| -| While Pest is very powerful out-of-the-box, you may have some testing code specific to your -| project that you don't want to repeat in every file. Here you can also expose helpers as -| global functions to help you to reduce the number of lines of code in your test files. -| -*/ - -function something(): void -{ - // .. -} diff --git a/tests/Unit/BidimensionalTest.php b/tests/Unit/BidimensionalTest.php deleted file mode 100644 index 104181b..0000000 --- a/tests/Unit/BidimensionalTest.php +++ /dev/null @@ -1,216 +0,0 @@ - 'Desk', 'price' => 200, 'active' => true], - ['product' => 'Chair', 'price' => 100, 'active' => true], - ['product' => 'Door', 'price' => 300, 'active' => false], - ['product' => 'Bookcase', 'price' => 150, 'active' => true], - ['product' => 'Door', 'price' => 100, 'active' => true], -]; - -test( - 'Block as table', - function () use ($dataTable): void { - $table = Block::make($dataTable); - $data = $table - ->where('price', Operator::GREATER_THAN, 100); - - expect($data)->toHaveCount(3); - }, -); - -test( - 'Block as table select and where', - function () use ($dataTable): void { - $table = Block::make($dataTable); - - $data = $table - ->select('product', 'price') - ->where('price', Operator::GREATER_THAN, 100, false); - - expect($data)->toHaveCount(3); - expect($data->get("0"))->toHaveCount(2); - expect($data->get("0"))->toHaveKeys(["product", "price"]); - expect($data->get("0.product"))->toBe("Desk"); - expect($data->get("1.product"))->toBe("Door"); - - $table = Block::make($dataTable); - - $data = $table - ->select('product', 'price'); - expect($data)->toHaveCount(5); - expect($data->get("0"))->toHaveCount(2); - expect($data->get("0"))->toHaveKeys(["product", "price"]); - expect($data->get("0.product"))->toBe("Desk"); - expect($data->get("0.price"))->toBe(200); - expect($data->get("1"))->toHaveCount(2); - expect($data->get("1.product"))->toBe("Chair"); - expect($data->get("1.price"))->toBe(100); - expect($data->get("4"))->toHaveCount(2); - expect($data->get("4.product"))->toBe("Door"); - expect($data->get("4.price"))->toBe(100); - - }, -); - -test( - 'Return Block while looping', - function () use ($dataTable): void { - $table = Block::make($dataTable); - - $data = $table - ->select('product', 'price') - ->where('price', Operator::GREATER_THAN, 100, false); - - //->calc('new_field', fn ($item) => $item['price'] * 2) - foreach ($data as $key => $item) { - expect($item)->toBeInstanceOf(Block::class); - expect($key)->toBeInt(); - expect($item->get("price"))->toBeGreaterThan(100); - } - expect($data->get("0.price"))->toBe(200); - expect($data->get("1.price"))->toBe(300); - - - expect($table->get("0.price"))->toBe(200); - expect($table->get("1.price"))->toBe(100); - - $table = Block::make($dataTable, false); - $data = $table - ->select('product', 'price') - ->where('price', Operator::GREATER_THAN, 100, false); - - foreach ($data as $key => $item) { - expect($item)->toBeArray(); - expect($key)->toBeInt(); - expect($item["price"])->toBeGreaterThan(100); - expect($data[$key]["price"])->toBeGreaterThan(100); - } - - - // re-using the $data object with the previous state - foreach ($data as $key => $item) { - expect($item)->toBeArray(); - expect($key)->toBeInt(); - expect($item["price"])->toBeGreaterThan(100); - expect($data[$key]["price"])->toBeGreaterThan(100); - } - - $table = Block::make($dataTable, true); - foreach ($table as $key => $item) { - expect($item)->toBeInstanceOf(Block::class); - expect($key)->toBeInt(); - expect($item->get("price"))->toBeGreaterThan(10); - } - - foreach ($table->iterateBlock(false) as $key => $item) { - expect($item)->toBeArray(); - expect($key)->toBeInt(); - expect($item["price"])->toBeGreaterThan(10); - } - // keep the previous state iterateBlock(false) - foreach ($table as $key => $item) { - expect($item)->toBeArray(); - expect($key)->toBeInt(); - expect($item["price"])->toBeGreaterThan(10); - } - - - foreach ($table->iterateBlock(true) as $key => $item) { - expect($item)->toBeInstanceOf(Block::class); - expect($key)->toBeInt(); - expect($item->get("price"))->toBeGreaterThan(10); - } - foreach ($table->iterateBlock(false) as $key => $item) { - expect($item)->toBeArray(); - expect($key)->toBeInt(); - expect($item["price"])->toBeGreaterThan(10); - } - - }, -); - -test( - 'group by', - function () use ($dataTable): void { - $table = Block::make($dataTable); - $grouped = $table->groupBy("product"); - expect($grouped->getBlock("Door"))->tohaveCount(2); - expect($grouped->getBlock("Desk"))->tohaveCount(1); - expect($grouped->getBlock("NotExists"))->tohaveCount(0); - - }, -); - - -test( - 'extract json by attribute', - function (): void { - $file = "./tests/data/stories.json"; - $block = Block::fromJsonFile($file); - //$block->getBlock("rels")->dumpJson(); - $rel = $block - ->getBlock("rels") - ->where("uuid", Operator::EQUAL, "a6af7728-eadf-4428-8cf5-343304857374"); - expect($rel)->toHaveCount(1); - expect($rel->get("4.name"))->toBe("Category C"); - expect($rel->get("4"))->toHaveCount(22); - - $rel = $block->getBlock("rels")->where( - field: "uuid", - operator: Operator::EQUAL, - value: "a6af7728-eadf-4428-8cf5-343304857374", - preseveKeys: false, - ); - expect($rel)->toHaveCount(1); - expect($rel->get("0.name"))->toBe("Category C"); - expect($rel->get("0"))->toHaveCount(22); - - $rel = $block->getBlock("rels") - ->select("uuid", "name") - ->where( - field: "uuid", - operator: Operator::EQUAL, - value: "a6af7728-eadf-4428-8cf5-343304857374", - preseveKeys: false, - ); - expect($rel)->toHaveCount(1); - expect($rel->get("0.name"))->toBe("Category C"); - expect($rel->get("0"))->toHaveCount(2); - }, -); - -test( - 'Apply field', - function (): void { - $table = Block::make( - [ - "title" => "Title", - "number" => 11, - ], - ); - $table->applyField( - "number", - "newfield", - fn($value): int|float => $value * 2, - ); - expect($table)->toHaveCount(3); - expect($table->get("newfield"))->toBe(22); - expect($table->get("number"))->toBe(11); - }, -); - -test( - 'Apply field2', - function (): void { - $object = Block::make(); - $object->set('name', 'John Doe') - ->applyField('name', 'uppercase_name', fn($value): string => strtoupper((string) $value)); - expect($object)->toHaveCount(2); - expect($object->get("uppercase_name"))->toBe("JOHN DOE"); - expect($object->get("name"))->toBe('John Doe'); - }, -); diff --git a/tests/Unit/BlockGetTest.php b/tests/Unit/BlockGetTest.php deleted file mode 100644 index 5112ddd..0000000 --- a/tests/Unit/BlockGetTest.php +++ /dev/null @@ -1,238 +0,0 @@ - [ - 'name' => 'Avocado', - 'fruit' => '🥑', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Avocado', - 'color' => 'green', - 'rating' => 8, - ], - "apple" - => [ - 'name' => 'Apple', - 'fruit' => '🍎', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Apple', - 'color' => 'red', - 'rating' => 7, - ], - "banana" - => [ - 'name' => 'Banana', - 'fruit' => '🍌', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Banana', - 'color' => 'yellow', - 'rating' => 8.5, - ], - "cherry" - => [ - 'name' => 'Cherry', - 'fruit' => '🍒', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Cherry', - 'color' => 'red', - 'rating' => 9, - ], -]; - -test( - 'Block make()', - function () use ($fruitsArray): void { - $data = Block::make($fruitsArray); - expect($data)->toBeInstanceOf(Block::class); - expect($data)->toHaveLength(4); - $data = Block::make(); - expect($data)->toBeInstanceOf(Block::class); - expect($data)->toHaveLength(0); - $data = Block::make([]); - expect($data)->toBeInstanceOf(Block::class); - expect($data)->toHaveLength(0); - - }, -); - -test( - 'Block get()', - function () use ($fruitsArray): void { - $data = Block::make($fruitsArray); - expect($data->get("avocado"))->toBeArray(); - expect($data->get("avocado"))->toHaveCount(5); - expect($data->get("avocado.color"))->toBeString(); - expect($data->get("avocado.color"))->toBe("green"); - expect($data->get("avocado.name"))->toBeString(); - expect($data->get("avocado.name"))->toBe("Avocado"); - expect($data->get("avocado.rating"))->toBeNumeric(); - expect($data->get("avocado.rating"))->toBeInt(); - expect($data->get("banana.rating"))->toBeFloat(); - expect($data->get("avocado.notexists"))->toBeNull(); - expect($data->get("avocado.notexists", "NO VALUE"))->toBe("NO VALUE"); - - }, -); - -test( - 'Block getBlock()', - function () use ($fruitsArray): void { - $data = Block::make($fruitsArray); - expect($data->getBlock("avocado"))->toBeInstanceOf(Block::class); - expect($data->getBlock("avocado"))->toHaveCount(5); - expect($data->getBlock("avocado.color"))->toBeInstanceOf(Block::class); - expect($data->getBlock("avocado.color"))->toHaveCount(1); - - expect($data->getBlock("avocado.notexists"))->toBeInstanceOf(Block::class); - expect($data->getBlock("avocado.notexists"))->toHaveCount(0); - }, -); - -test( - 'Block keys()', - function () use ($fruitsArray): void { - $data = Block::make($fruitsArray); - expect($data->getBlock("avocado")->keys())->toHaveCount(5); - expect($data->getBlock("avocado")->keys())->toBeArray(); - expect($data->getBlock("avocado")->keys())->toMatchArray([0 => "name"]); - expect($data->keys())->toHaveCount(4); - expect($data->keys())->toBeArray(); - expect($data->keys())->toMatchArray([0 => "avocado"]); - expect($data->keys())->toMatchArray([1 => "apple"]); - - - - }, -); - - -it('Basic get Block', function (): void { - $block = Block::make(['A','B','C']); - expect($block->get(1))->toBe('B'); - expect($block->get(4))->toBeNull(); - expect($block->get(4, 'AAAA'))->toBe("AAAA"); -}); - - - -it('Basic nested get', function (): void { - $block = Block::make([ - 'A' => 'First', - 'B' => ['some', 'thing'], - 'C' => [ 'nested-item-1' => 10, 'nested-item-2' => 20], - 'D' => [], - ]); - expect($block->get('A'))->toBe('First'); - expect($block->get('B'))->toBeArray(); - expect($block->get('B.0'))->toBe('some'); - expect($block->get('B.1'))->toBe('thing'); - expect($block->get('B.2'))->toBeNull(); - expect($block->get('B.2', 1234))->toBe(1234); - expect($block->get('B#0', charNestedKey: '#'))->toBe('some'); - expect($block->get('B#1', charNestedKey: '#'))->toBe('thing'); - expect($block->get('B#2', charNestedKey: '#'))->toBeNull(); - expect($block->get('B#2', 1234, '#'))->toBe(1234); - - expect($block->get('C.0'))->toBeNull(); - expect($block->get('C.nested-item-1'))->toBe(10); - expect($block->get('C.nested-item-2'))->toBe(20); - expect($block->get('C.nested-item-2.other'))->toBeNull(); - expect($block->get('C.nested-item-2.other', 'zzz'))->toBe('zzz'); - expect($block->get('C#nested-item-2#other', 'zzz', '#'))->toBe('zzz'); - expect($block->get('C#nested-item-2#other', 'zzz'))->toBe('zzz'); - expect($block->get('C#nested-item-2', 'zzz'))->toBe('zzz'); - expect($block->get('C#nested-item-4', 'zzz'))->toBe('zzz'); - expect($block->get('D#nested-item-4', 'zzz'))->toBe('zzz'); - expect($block->get('D.0'))->toBeNull(); - expect($block->get('D', '0'))->toBeArray()->toHaveLength(0); - -}); - -it('Basic getBlock', function (): void { - $block = Block::make(['A','B','C']); - expect($block->getBlock(1))->toBeInstanceOf(Block::class); - expect($block->getBlock(1)->get(0))->toBe('B'); - expect($block->getBlockNullable(4))->toBeNull(); - expect($block->getBlock(4, 'AAAA'))->toBeInstanceOf(Block::class); - expect($block->getBlock(4, 'AAAA')->get(0))->toBe('AAAA'); - - - $block = Block::make([ - 'A' => 'First', - 'B' => ['some', 'thing'], - 'C' => [ 'nested-item-1' => 10, 'nested-item-2' => 20], - 'D' => [], - ]); - - expect($block->getBlock('C')->get('nested-item-1'))->toBe(10); - expect($block->getBlock('C')->entries()->get(0))->toBeArray(); - expect($block->getBlock('C')->entries()->get(0))->toBe(['nested-item-1',10]); - expect($block->getBlock('C')->keys())->toBe(['nested-item-1','nested-item-2' ]); - - $block = Block::make( - [ - "avocado" - => [ - 'name' => 'Avocado', - 'fruit' => '🥑', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Avocado', - ], - "apple" - => [ - 'name' => 'Apple', - 'fruit' => '🍎', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Apple', - ], - "banana" - => [ - 'name' => 'Banana', - 'fruit' => '🍌', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Banana', - ], - "cherry" - => [ - 'name' => 'Cherry', - 'fruit' => '🍒', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Cherry', - ], - ], - ); - $appleArr = $block->getBlock("apple"); - expect($appleArr->count())->toBe(3) - ->and($appleArr->get("name"))->toBe('Apple'); - $appleNameArr = $block->getBlock("apple.name"); - expect($appleNameArr->get(0))->toBe('Apple'); - $appleNoExists = $block->getBlock("apple.name.noexists"); - expect($appleNoExists)->toBeInstanceOf(Block::class); - expect($appleNoExists->count())->toBe(0); - $appleNoExists = $block->getBlockNullable("apple.name.noexists"); - expect($appleNoExists)->toBeNull(); - $appleNoExists = $block->getBlock("apple.name.noexists", "some"); - expect($appleNoExists)->toBeInstanceOf(Block::class) - ->and($appleNoExists->get(0))->toBe("some"); -}); - - -it('generates JSON', function (): void { - $block = Block::make([ - 'A' => 'First', - 'B' => ['some', 'thing'], - 'C' => [ 'nested-item-1' => 10, 'nested-item-2' => 20], - 'D' => [], - ]); - expect($block->toJson())->toBeString(); - expect(json_decode($block->toJson(), associative: false))->toBeInstanceOf(stdClass::class); - - expect(json_decode($block->toJson(), associative: false))->toHaveProperty("C"); - expect(json_decode($block->toJson(), associative: false)->C)->toHaveProperty("nested-item-1"); -}); - -it('generates JSON object', function (): void { - $block = Block::make([ - 'A' => 'First', - 'B' => ['some', 'thing'], - 'C' => ['nested-item-1' => 10, 'nested-item-2' => 20], - 'D' => [], - ]); - expect($block->toJsonObject())->toBeInstanceOf(stdClass::class); - expect($block->toJsonObject())->toHaveProperty("C"); - expect($block->toJsonObject()->C)->toHaveProperty("nested-item-1"); -}); diff --git a/tests/Unit/BlockSetTest.php b/tests/Unit/BlockSetTest.php deleted file mode 100644 index f338524..0000000 --- a/tests/Unit/BlockSetTest.php +++ /dev/null @@ -1,26 +0,0 @@ -set("type", "doc"); - $textField->set("content.0.content.0.text", $articleText); - $textField->set("content.0.content.0.type", "text"); - $textField->set("content.0.type", "paragraph"); - - expect($textField->get('content.0.content.0.text'))->toBe($articleText); - expect($textField->get('content.0.content.0'))->toBeArray(); - expect($textField->get('content.0.content.0'))->toHaveCount(2); - expect($textField->get('content.0.content.0.newfield'))->toBeNull(); - $textField->set("content.0.content.0.newfield", "THIS IS A NEW FIELD"); - expect($textField->get('content.0.content.0.newfield'))->toBeString(); - expect($textField->get('content.0.content.0.newfield'))->toBe("THIS IS A NEW FIELD"); - expect($textField->get('content.0.content.0'))->toBeArray(); - expect($textField->get('content.0.content.0'))->toHaveCount(3); - - }, -); diff --git a/tests/Unit/Traits/EditableBlockTest.php b/tests/Unit/Traits/EditableBlockTest.php deleted file mode 100644 index 9a75951..0000000 --- a/tests/Unit/Traits/EditableBlockTest.php +++ /dev/null @@ -1,65 +0,0 @@ -toHaveCount(10); - expect($data2)->toHaveCount(10); - $data1->append($data2); - expect($data1)->toHaveCount(20); - - $arrayData3 = $data3->toArray(); - expect($arrayData3)->toBeArray(); - expect($arrayData3)->toHaveCount(10); - expect($data1)->toHaveCount(20); - $data1->append($arrayData3); - expect($data1)->toHaveCount(30); - - - - - }, -); -test( - 'appends array', - function (): void { - $data1 = Block::make(["a", "b"]); - $arrayData2 = ["c", "d"]; - expect($data1)->toHaveCount(2); - $data1->append($arrayData2); - expect($data1)->toHaveCount(4); - expect($data1->toArray())->toMatchArray([ - 'a', - 'b', - 'c', - 'd', - ]); - }, -); - -test( - 'appends item', - function (): void { - $data1 = Block::make(["a", "b"]); - $arrayData2 = ["c", "d"]; - expect($data1)->toHaveCount(2); - // because of the appendItem, here the whole array is - // added as element - $data1->appendItem($arrayData2); - expect($data1)->toHaveCount(3); - expect($data1->toArray())->toMatchArray([ - 'a', - 'b', - [ - 'c', - 'd', - ], - ]); - }, -); diff --git a/tests/Unit/Traits/ExportableTest.php b/tests/Unit/Traits/ExportableTest.php deleted file mode 100644 index 2c396bd..0000000 --- a/tests/Unit/Traits/ExportableTest.php +++ /dev/null @@ -1,102 +0,0 @@ - [ - 'name' => 'Avocado', - 'fruit' => '🥑', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Avocado', - 'color' => 'green', - 'rating' => 8, - ], - "apple" - => [ - 'name' => 'Apple', - 'fruit' => '🍎', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Apple', - 'color' => 'red', - 'rating' => 7, - ], - "banana" - => [ - 'name' => 'Banana', - 'fruit' => '🍌', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Banana', - 'color' => 'yellow', - 'rating' => 8.5, - ], - "cherry" - => [ - 'name' => 'Cherry', - 'fruit' => '🍒', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Cherry', - 'color' => 'red', - 'rating' => 9, - ], -]; - -test( - 'Test toJson', - function () use ($fruitsArray): void { - $data = Block::make($fruitsArray); - expect($data->toJson())->toBeString(); - expect(strlen($data->toJson()))->toBe(773); - $string = $data->toJson(); - $data1 = Block::fromJsonString($string); - expect($data1->get("0.fruit"))->toBe($data->get("0.fruit")); - }, -); -test( - 'Test toJson with different iterateBlock', - function () use ($fruitsArray): void { - $data1 = Block::make($fruitsArray, true); - $string1 = $data1->toJson(); - $data2 = Block::make($fruitsArray, false); - $string2 = $data2->toJson(); - expect($string1)->toBeString(); - expect($string2)->toBeString(); - expect(strlen($string1))->toBe(773); - expect(strlen($string2))->toBe(773); - expect($string1)->toBe($string2); - }, -); - -test( - 'Test saveToJson', - function () use ($fruitsArray): void { - $data = Block::make($fruitsArray); - $data->saveToJson('fruits.json'); - expect(file_exists('fruits.json'))->toBeTrue(); - unlink('fruits.json'); - }, -); - -test( - 'Test saveToJson with overwrite', - function () use ($fruitsArray): void { - $data = Block::make($fruitsArray); - $data->saveToJson('fruits.json'); - expect(file_exists('fruits.json'))->toBeTrue(); - - $result = $data->saveToJson('fruits.json', true); - expect($result)->toBeTrue(); - - unlink('fruits.json'); - }, -); - -test( - 'Test saveToJson with existing file', - function () use ($fruitsArray): void { - $data = Block::make($fruitsArray); - $data->saveToJson('fruits.json'); - expect(file_exists('fruits.json'))->toBeTrue(); - - $result = $data->saveToJson('fruits.json'); - expect($result)->toBeFalse(); - - unlink('fruits.json'); - }, -); diff --git a/tests/Unit/Traits/FormattableBlokTest.php b/tests/Unit/Traits/FormattableBlokTest.php deleted file mode 100644 index 97072e0..0000000 --- a/tests/Unit/Traits/FormattableBlokTest.php +++ /dev/null @@ -1,59 +0,0 @@ -toHaveCount(10); - expect($data2)->toHaveCount(10); - expect($data1->getFormattedDateTime("0.commit.author.date", "Y"))->toBe("2024"); - expect($data1->getFormattedDateTime("0.commit.author.date", "Y-m-d"))->toBe("2024-06-28"); - expect($data1->getFormattedDateTime("0.commit.author.dateNOTEXISTS", "Y-m-d"))->toBeNull(); - - }, -); - -test( - 'Format byte field into KB or MB ot GB ', - function (): void { - $stringData = <<getBlock("assets"))->toHaveCount(2); - expect($data1->getFormattedByte("assets.0.total_bytes"))->toBe("5.98 GB"); - expect($data1->getFormattedByte("assets.1.total_bytes"))->toBe("2.18 GB"); - expect($data1->getFormattedByte("assets.1.total_bytes", 5))->toBe("2.18288 GB"); - expect($data1->getFormattedByte("assets.1.total_bytes", 0))->toBe("2 GB"); - }, -); diff --git a/tests/Unit/Traits/QueryableBlockTest.php b/tests/Unit/Traits/QueryableBlockTest.php deleted file mode 100644 index 5795266..0000000 --- a/tests/Unit/Traits/QueryableBlockTest.php +++ /dev/null @@ -1,167 +0,0 @@ - [ - 'name' => 'Avocado', - 'fruit' => '🥑', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Avocado', - 'color' => 'green', - 'rating' => 8, - 'tags' => ['healthy', 'creamy', 'green'], - ], - 'apple' => [ - 'name' => 'Apple', - 'fruit' => '🍎', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Apple', - 'color' => 'red', - 'rating' => 7, - 'tags' => ['classic', 'crunchy', 'juicy', 'red', 'sweet'], - ], - 'banana' => [ - 'name' => 'Banana', - 'fruit' => '🍌', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Banana', - 'color' => 'yellow', - 'rating' => 8.5, - 'tags' => ['sweet', 'soft', 'yellow'], - ], - 'cherry' => [ - 'name' => 'Cherry', - 'fruit' => '🍒', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Cherry', - 'color' => 'red', - 'rating' => 9, - 'tags' => ['small', 'tart', 'red'], - ], -]; - -test( - 'Test query greater than x', - function () use ($fruitsArray): void { - $data = Block::make($fruitsArray); - $highRated = $data->where('rating', Operator::GREATER_THAN, 8); - expect($highRated)->tohaveCount(2); - $sorted = $data->where('rating', Operator::GREATER_THAN, 8)->orderBy('rating', 'desc'); - expect($sorted)->tohaveCount(2); - - }, -); - -test( - 'group by', - function () use ($fruitsArray): void { - $table = Block::make($fruitsArray); - $grouped = $table->groupBy('color'); - expect($grouped->getBlock('red')) - ->tohaveCount(2) - ->and($grouped->getBlock('yellow'))->tohaveCount(1) - ->and($grouped->getBlock('NotExists'))->tohaveCount(0); - }, -); - -test( - 'group by 2', - function (): void { - $data = Block::make([ - ['type' => 'fruit', 'name' => 'apple'], - ['type' => 'fruit', 'name' => 'banana'], - ['type' => 'vegetable', 'name' => 'carrot'], - ]); - $grouped = $data->groupBy('type'); - expect($grouped->getBlock('fruit'))->tohaveCount(2); - expect($grouped->getBlock('vegetable'))->tohaveCount(1); - expect($grouped->getBlock('NotExists'))->tohaveCount(0); - - }, -); - - -test( - 'group by function', - function (): void { - $fruits = [ - ['name' => 'Apple', 'type' => 'Citrus', 'quantity' => 15], - ['name' => 'Banana', 'type' => 'Tropical', 'quantity' => 10], - ['name' => 'Orange', 'type' => 'Citrus', 'quantity' => 8], - ['name' => 'Mango', 'type' => 'Tropical', 'quantity' => 5], - ['name' => 'Lemon', 'type' => 'Citrus', 'quantity' => 12], - ]; - $fruitsBlock = Block::make($fruits); - $groupedByQuantityRange = $fruitsBlock->groupByFunction( - fn($fruit): string - => match (true) { - $fruit['quantity'] < 10 => 'Low', - $fruit['quantity'] < 15 => 'Medium', - default => 'High', - }, - ); - //$groupedByQuantityRange->dumpJson(); - expect($groupedByQuantityRange) - ->tohaveCount(3) - ->and($groupedByQuantityRange->getBlock('Low')) - ->tohaveCount(2) - ->and($groupedByQuantityRange->getBlock('Medium')) - ->tohaveCount(2) - ->and($groupedByQuantityRange->getBlock('High')) - ->tohaveCount(1); - - $groupedByNameLenght = $fruitsBlock->groupByFunction( - fn($fruit): int => strlen((string) $fruit['name']), - ); - - expect($groupedByNameLenght) - ->tohaveCount(2) - ->and($groupedByNameLenght->hasKey(5)) - ->toBeTrue() - ->and($groupedByNameLenght->hasKey("6")) - ->toBeTrue() - ->and($groupedByNameLenght->get("5")) - ->tohaveCount(3) - ->and($groupedByNameLenght->get("6")) - ->tohaveCount(2); - }, -); - -test( - 'where method, in operator', - function () use ($fruitsArray): void { - $data = Block::make($fruitsArray); - $greenOrBlack = $data->where('color', Operator::IN, ['green', 'black']); - expect($greenOrBlack)->tohaveCount(1); - $noResult = $data->where('color', Operator::IN, []); - expect($noResult)->tohaveCount(0); - $greenOrRed = $data->where('color', Operator::IN, ['green', 'red']); - expect($greenOrRed)->tohaveCount(3); - }, -); - -test( - 'where method, has operator', - function () use ($fruitsArray): void { - $data = Block::make($fruitsArray); - $sweet = $data->where('tags', Operator::HAS, 'sweet'); - expect($sweet)->tohaveCount(2); - $noResult = $data->where('tags', Operator::HAS, 'not-existent'); - expect($noResult)->tohaveCount(0); - $softFruit = $data->where('tags', Operator::HAS, 'soft'); - expect($softFruit)->tohaveCount(1); - }, -); - -test( - 'query with operators', - function (): void { - $data1 = Block::fromJsonFile(__DIR__ . '/../../data/commits-json/commits-10-p1.json'); - $data2 = Block::fromJsonFile(__DIR__ . '/../../data/commits-json/commits-10-p2.json'); - $data3 = Block::fromJsonFile(__DIR__ . '/../../data/commits-json/commits-10-p3.json'); - $data1->append($data2)->append($data3); - expect($data1)->toHaveCount(30); - expect($data2)->toHaveCount(10); - $block = $data1->where('commit.author.name', Operator::LIKE, 'Roberto'); - expect($block->count())->toEqual(29); - - }, -); diff --git a/tests/Unit/Traits/TypeableBlockTest.php b/tests/Unit/Traits/TypeableBlockTest.php deleted file mode 100644 index e398453..0000000 --- a/tests/Unit/Traits/TypeableBlockTest.php +++ /dev/null @@ -1,199 +0,0 @@ -append($data2)->append($data3); - expect($data1)->toHaveCount(30); - expect($data2)->toHaveCount(10); - expect($data1->getString("0.commit.author.date"))->toBeString(); - expect($data1->getString("0.commit.author.notexist"))->toBeNull(); - expect($data1->getString("0.commit.author.notexist", "AA")) - ->toBeString() - ->toEqual("AA"); - expect($data1->getString("0.commit.comment_count")) - ->toBeString() - ->toEqual("0"); - expect($data1->getString("0.commit.comment_count", 1)) - ->toBeString() - ->toEqual("0"); - expect($data1->getString("0.commit.comment_countnotexists", 1)) - ->toBeString() - ->toEqual("1"); -}); - -test("Testing getStringStrict()", function (): void { - $data1 = Block::fromJsonFile( - __DIR__ . "/../../data/commits-json/commits-10-p1.json", - ); - $data2 = Block::fromJsonFile( - __DIR__ . "/../../data/commits-json/commits-10-p2.json", - ); - $data3 = Block::fromJsonFile( - __DIR__ . "/../../data/commits-json/commits-10-p3.json", - ); - $data1->append($data2)->append($data3); - expect($data1)->toHaveCount(30); - expect($data2)->toHaveCount(10); - expect($data1->getStringStrict("0.commit.author.date"))->toBeString(); - expect($data1->getStringStrict("0.commit.author.notexist")) - ->toBeString() - ->toBe(""); - expect($data1->getStringStrict("0.commit.author.notexist", "AA")) - ->toBeString() - ->toEqual("AA"); - expect($data1->getStringStrict("0.commit.comment_count")) - ->toBeString() - ->toEqual("0"); - expect($data1->getStringStrict("0.commit.comment_count", 1)) - ->toBeString() - ->toEqual("0"); - expect($data1->getStringStrict("0.commit.comment_countnotexists", 1)) - ->toBeString() - ->toEqual("1"); -}); - -test("Testing getInt()", function (): void { - $data1 = Block::fromJsonFile( - __DIR__ . "/../../data/commits-json/commits-10-p1.json", - ); - // $data2 = Block::fromJsonFile(__DIR__ . "/../../data/commits-json/commits-10-p2.json"); - // $data3 = Block::fromJsonFile(__DIR__ . "/../../data/commits-json/commits-10-p3.json"); - - expect($data1->getInt("0.author.id"))->toBeInt()->toBe(678434); - expect($data1->getInt("0.author.idx"))->toBeNull(); - expect($data1->getInt("0.author.idx", 44))->toBeInt()->toBe(44); -}); - -test("Testing getIntStrict()", function (): void { - $data1 = Block::fromJsonFile( - __DIR__ . "/../../data/commits-json/commits-10-p1.json", - ); - // $data2 = Block::fromJsonFile(__DIR__ . "/../../data/commits-json/commits-10-p2.json"); - // $data3 = Block::fromJsonFile(__DIR__ . "/../../data/commits-json/commits-10-p3.json"); - - expect($data1->getIntStrict("0.author.id"))->toBeInt()->toBe(678434); - expect($data1->getIntStrict("0.author.idx"))->toBeInt()->toBe(0); - expect($data1->getIntStrict("0.author.idx", 44))->toBeInt()->toBe(44); - expect($data1->getIntStrict("0.commit.author.date"))->toBeInt()->toBe(2024); -}); - -test("Testing getBoolean()", function (): void { - $data1 = Block::fromJsonFile( - __DIR__ . "/../../data/commits-json/commits-10-p1.json", - ); - $data2 = Block::fromJsonFile( - __DIR__ . "/../../data/commits-json/commits-10-p2.json", - ); - $data3 = Block::fromJsonFile( - __DIR__ . "/../../data/commits-json/commits-10-p3.json", - ); - $data1->append($data2)->append($data3); - expect($data1)->toHaveCount(30); - expect($data2)->toHaveCount(10); - expect($data1->getBoolean("0.author.site_admin"))->toBeBool(); - expect($data1->getBoolean("0.author.notexist"))->toBeNull(); - expect($data1->getBoolean("0.author.notexist"))->toBeNull(); - expect($data1->getBoolean("0.author.notexist", true)) - ->toBeBool() - ->toEqual(true); - expect($data1->getBoolean("0.author.notexist", false)) - ->toBeBool() - ->toEqual(false); - expect($data1->getBoolean("0.author.site_admin")) - ->toBeBool() - ->toEqual(false); - expect($data1->getBoolean("0.author.site_admin", true)) - ->toBeBool() - ->toEqual(false); - expect($data1->getBoolean("0.commit.comment_countnotexists", true)) - ->toBeBool() - ->toEqual(true); -}); - -test("Testing getBooleanStrict()", function (): void { - $data1 = Block::fromJsonFile( - __DIR__ . "/../../data/commits-json/commits-10-p1.json", - ); - $data2 = Block::fromJsonFile( - __DIR__ . "/../../data/commits-json/commits-10-p2.json", - ); - $data3 = Block::fromJsonFile( - __DIR__ . "/../../data/commits-json/commits-10-p3.json", - ); - $data1->append($data2)->append($data3); - expect($data1)->toHaveCount(30); - expect($data2)->toHaveCount(10); - expect($data1->getBooleanStrict("0.author.site_admin"))->toBeBool(); - expect($data1->getBooleanStrict("0.author.notexist")) - ->toBeBool() - ->toBeFalse(); - expect($data1->getBooleanStrict("0.author.notexist"))->toBeBool(); - expect($data1->getBooleanStrict("0.author.notexist", true)) - ->toBeBool() - ->toEqual(true); - expect($data1->getBooleanStrict("0.author.notexist", false)) - ->toBeBool() - ->toEqual(false); - expect($data1->getBooleanStrict("0.author.site_admin")) - ->toBeBool() - ->toEqual(false); - expect($data1->getBooleanStrict("0.author.site_admin", true)) - ->toBeBool() - ->toEqual(false); - expect($data1->getBooleanStrict("0.commit.comment_countnotexists", true)) - ->toBeBool() - ->toEqual(true); -}); - -$fruitsArray = [ - "avocado" => [ - "name" => "Avocado", - "fruit" => "🥑", - "wikipedia" => "https://en.wikipedia.org/wiki/Avocado", - "color" => "green", - "rating" => 8, - ], - "apple" => [ - "name" => "Apple", - "fruit" => "🍎", - "wikipedia" => "https://en.wikipedia.org/wiki/Apple", - "color" => "red", - "rating" => 7, - ], - "banana" => [ - "name" => "Banana", - "fruit" => "🍌", - "wikipedia" => "https://en.wikipedia.org/wiki/Banana", - "color" => "yellow", - "rating" => 8.5, - ], - "cherry" => [ - "name" => "Cherry", - "fruit" => "🍒", - "wikipedia" => "https://en.wikipedia.org/wiki/Cherry", - "color" => "red", - "rating" => 9, - ], -]; - -test("Testing getFloat() and float strict", function () use ( - $fruitsArray, -): void { - $data = Block::make($fruitsArray); - expect($data)->toBeInstanceOf(Block::class); - expect($data)->toHaveLength(4); - expect($data->getFloat("banana.rating"))->toBe(8.5); - expect($data->getFloat("apple.rating"))->toBe(7.0); - expect($data->getFloat("foo", 1.2))->toBe(1.2); - expect($data->getFloatStrict("missing"))->toBe(0.0); -}); diff --git a/tests/Unit/Traits/ValidableTest.php b/tests/Unit/Traits/ValidableTest.php deleted file mode 100644 index b423512..0000000 --- a/tests/Unit/Traits/ValidableTest.php +++ /dev/null @@ -1,72 +0,0 @@ - 'Avocado', - 'fruit' => '🥑', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Avocado', - 'color' => 'green', - 'rating' => 8, - ], - [ - 'name' => 'Apple', - 'fruit' => '🍎', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Apple', - 'color' => 'red', - 'rating' => 7, - ], - [ - 'name' => 'Banana', - 'fruit' => '🍌', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Banana', - 'color' => 'yellow', - 'rating' => 8.5, - ], - [ - 'name' => 'Cherry', - 'fruit' => '🍒', - 'wikipedia' => 'https://en.wikipedia.org/wiki/Cherry', - 'color' => 'red', - 'rating' => 9, - ], -]; - -$schemaJson = <<<'JSON' -{ - "type": "array", - "items" : { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "fruit": { - "type": "string" - }, - "wikipedia": { - "type": "string" - }, - "color": { - "type": "string" - }, - "rating": { - "type": "number" - } - } - } -} -JSON; - -test( - 'Validate json', - function () use ($fruitsArray, $schemaJson): void { - $data = Block::make($fruitsArray); - expect($data->validateJsonWithSchema($schemaJson))->toBeTrue(); - - $schemaBlock = Block::fromJsonString($schemaJson); - $schemaBlock->set("items.properties.rating.type", "integer"); - expect($data->validateJsonWithSchema($schemaBlock->toJson()))->toBeFalse(); - }, -);