From 46b8abb00ac005025a1d67b066640a75fb430bf3 Mon Sep 17 00:00:00 2001 From: Pavel Buchnev Date: Mon, 22 Nov 2021 16:58:41 +0300 Subject: [PATCH] Addsunit tests for property renderers (#6) --- README.md | 6 + .../Renderer/ColumnsRenderer.php | 12 +- src/ConsoleRenderer/Renderer/KeysRenderer.php | 2 +- .../Renderer/MacrosRenderer.php | 4 +- .../Renderer/PropertyRenderer.php | 2 +- .../Renderer/RelationsRenderer.php | 3 +- .../Renderer/TitleRenderer.php | 17 +-- .../Renderer/ColumnsRendererTest.php | 102 ++++++++++++++++ .../Renderer/KeysRendererTest.php | 85 +++++++++++++ .../Renderer/PropertyRendererTest.php | 114 ++++++++++++++++++ .../Renderer/TitleRendererTest.php | 91 ++++++++++++++ .../Renderer/Fixture/console_output.stub.txt | 14 +-- .../Fixture/console_output_plain.stub.txt | 14 +-- ...ole_output_with_custom_properties.stub.txt | 14 +-- .../Renderer/OutputSchemaRendererTest.php | 2 + 15 files changed, 441 insertions(+), 41 deletions(-) create mode 100644 tests/Schema/Renderer/ConsoleRenderer/Renderer/ColumnsRendererTest.php create mode 100644 tests/Schema/Renderer/ConsoleRenderer/Renderer/KeysRendererTest.php create mode 100644 tests/Schema/Renderer/ConsoleRenderer/Renderer/PropertyRendererTest.php create mode 100644 tests/Schema/Renderer/ConsoleRenderer/Renderer/TitleRendererTest.php diff --git a/README.md b/README.md index 045213d..d6af68e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # Cycle ORM Schema renderer +[![Latest Stable Version](https://poser.pugx.org/cycle/schema-renderer/v/stable)](https://packagist.org/packages/cycle/schema-renderer) +[![build](https://github.com/cycle/schema-renderer/actions/workflows/main.yml/badge.svg)](https://github.com/cycle/schema-renderer/actions/workflows/main.yml) +[![static analysis](https://github.com/cycle/schema-renderer/actions/workflows/static.yml/badge.svg)](https://github.com/cycle/schema-renderer/actions/workflows/static.yml) +[![Codecov](https://codecov.io/gh/cycle/schema-renderer/branch/master/graph/badge.svg)](https://codecov.io/gh/cycle/schema-renderer/) +[![StyleCI](https://github.styleci.io/repos/401633317/shield?branch=master)](https://github.styleci.io/repos/401633317?branch=master) + This package may be used to render Cycle ORM Schema in a terminal or generate php representation. ## Installation diff --git a/src/ConsoleRenderer/Renderer/ColumnsRenderer.php b/src/ConsoleRenderer/Renderer/ColumnsRenderer.php index f6c1262..4322e94 100644 --- a/src/ConsoleRenderer/Renderer/ColumnsRenderer.php +++ b/src/ConsoleRenderer/Renderer/ColumnsRenderer.php @@ -17,14 +17,17 @@ public function render(Formatter $formatter, array $schema, string $role): ?stri $columns = $schema[SchemaInterface::COLUMNS] ?? []; $title = sprintf('%s:', $formatter->title('Fields')); - if (count($columns) === 0) { + if (! \is_array($columns) || count($columns) === 0) { return $title . ' ' . $formatter->error('not defined'); } + $padding = $formatter->title('') . ' '; + $rows[] = $title; $rows[] = sprintf( - ' (%s -> %s -> %s)', + '%s(%s -> %s -> %s)', + $padding, $formatter->property('property'), $formatter->column('db.field'), $formatter->typecast('typecast') @@ -35,12 +38,13 @@ public function render(Formatter $formatter, array $schema, string $role): ?stri foreach ($columns as $property => $field) { $typecast = $types[$property] ?? $types[$field] ?? null; $row = sprintf( - ' %s -> %s', + '%s%s -> %s', + $padding, $formatter->property((string)$property), $formatter->column($field) ); - if ($typecast !== null) { + if ($typecast !== null && $typecast !== [] && $typecast !== '') { $row .= sprintf( ' -> %s', $formatter->typecast(\implode('::', (array)$typecast)) diff --git a/src/ConsoleRenderer/Renderer/KeysRenderer.php b/src/ConsoleRenderer/Renderer/KeysRenderer.php index 4fb59b5..f8a5c73 100644 --- a/src/ConsoleRenderer/Renderer/KeysRenderer.php +++ b/src/ConsoleRenderer/Renderer/KeysRenderer.php @@ -30,7 +30,7 @@ public function render(Formatter $formatter, array $schema, string $role): ?stri $row = sprintf('%s: ', $formatter->title($this->title)); - if ($keys === null) { + if ($keys === null || $keys === '' || $keys === []) { return $this->required ? $row . $formatter->error('not defined') : null; } diff --git a/src/ConsoleRenderer/Renderer/MacrosRenderer.php b/src/ConsoleRenderer/Renderer/MacrosRenderer.php index 0828377..19c3ff0 100644 --- a/src/ConsoleRenderer/Renderer/MacrosRenderer.php +++ b/src/ConsoleRenderer/Renderer/MacrosRenderer.php @@ -12,7 +12,7 @@ class MacrosRenderer implements Renderer { public function render(Formatter $formatter, array $schema, string $role): ?string { - if (!\defined(SchemaInterface::class . '::MACROS')) { + if (! \defined(SchemaInterface::class . '::MACROS')) { return null; } $macrosList = (array)($schema[SchemaInterface::MACROS] ?? []); @@ -57,7 +57,7 @@ public function render(Formatter $formatter, array $schema, string $role): ?stri } /** - * @param mixed $value + * @param mixed $value */ private function printValue(Formatter $formatter, $value): string { diff --git a/src/ConsoleRenderer/Renderer/PropertyRenderer.php b/src/ConsoleRenderer/Renderer/PropertyRenderer.php index daddc80..e79fe66 100644 --- a/src/ConsoleRenderer/Renderer/PropertyRenderer.php +++ b/src/ConsoleRenderer/Renderer/PropertyRenderer.php @@ -24,7 +24,7 @@ public function render(Formatter $formatter, array $schema, string $role): ?stri { $row = sprintf('%s: ', $formatter->title($this->title)); - if (!isset($schema[$this->property])) { + if (! isset($schema[$this->property])) { return $this->required ? $row . $formatter->error('not defined') : null; } diff --git a/src/ConsoleRenderer/Renderer/RelationsRenderer.php b/src/ConsoleRenderer/Renderer/RelationsRenderer.php index bdad453..a3734ca 100644 --- a/src/ConsoleRenderer/Renderer/RelationsRenderer.php +++ b/src/ConsoleRenderer/Renderer/RelationsRenderer.php @@ -130,7 +130,7 @@ public function render(Formatter $formatter, array $schema, string $role): ?stri } /** - * @param array|string $keys + * @param array|string $keys */ private function renderKeys(Formatter $formatter, $keys): string { @@ -140,6 +140,7 @@ private function renderKeys(Formatter $formatter, $keys): string static fn (string $key) => $formatter->property($key), $keys ); + return sprintf( '%s%s%s', $braces ? '[' : '', diff --git a/src/ConsoleRenderer/Renderer/TitleRenderer.php b/src/ConsoleRenderer/Renderer/TitleRenderer.php index 8f302cb..373f656 100644 --- a/src/ConsoleRenderer/Renderer/TitleRenderer.php +++ b/src/ConsoleRenderer/Renderer/TitleRenderer.php @@ -15,16 +15,11 @@ public function render(Formatter $formatter, array $schema, string $role): ?stri $database = $schema[SchemaInterface::DATABASE] ?? ''; $table = $schema[SchemaInterface::TABLE] ?? ''; - $row = $formatter->entity("[{$role}]"); - - if ($database !== null) { - $row .= sprintf( - ' :: %s.%s', - $formatter->column($database), - $formatter->column($table) - ); - } - - return $row; + return sprintf( + '%s :: %s.%s', + $formatter->entity("[{$role}]"), + $formatter->column($database), + $formatter->column($table) + ); } } diff --git a/tests/Schema/Renderer/ConsoleRenderer/Renderer/ColumnsRendererTest.php b/tests/Schema/Renderer/ConsoleRenderer/Renderer/ColumnsRendererTest.php new file mode 100644 index 0000000..92e81ee --- /dev/null +++ b/tests/Schema/Renderer/ConsoleRenderer/Renderer/ColumnsRendererTest.php @@ -0,0 +1,102 @@ +formatter = new PlainFormatter(); + } + + public function testRenderNullValue() + { + $renderer = new ColumnsRenderer(); + + $result = $renderer->render($this->formatter, [SchemaInterface::COLUMNS => null], 'bar'); + + $this->assertSame(' Fields: not defined', $result); + } + + public function testRenderStringValue() + { + $renderer = new ColumnsRenderer(); + + $result = $renderer->render($this->formatter, [SchemaInterface::COLUMNS => 'foo'], 'bar'); + + $this->assertSame(' Fields: not defined', $result); + } + + public function testRenderArrayWithoutTypecastValue() + { + $renderer = new ColumnsRenderer(); + + $result = $renderer->render($this->formatter, [ + SchemaInterface::COLUMNS => [ + 'id' => 'integer', + 'title' => 'string(36)', + 'description' => 'string', + ], + ], 'bar'); + + $this->assertSame( + <<<'OUT' + Fields: + (property -> db.field -> typecast) + id -> integer + title -> string(36) + description -> string +OUT + , + $result + ); + } + + public function testRenderArrayWithTypecastValue() + { + $renderer = new ColumnsRenderer(); + + $result = $renderer->render($this->formatter, [ + SchemaInterface::COLUMNS => [ + 'id' => 'integer', + 'title' => 'string', + 'slug' => 'string', + 'json' => 'json', + 'description' => 'text', + ], + SchemaInterface::TYPECAST => [ + 'id' => 'int', + 'title' => null, + 'slug' => '', + 'json' => ['Json', 'cast'], + 'description' => [], + ], + ], 'bar'); + + $this->assertSame( + <<<'OUT' + Fields: + (property -> db.field -> typecast) + id -> integer -> int + title -> string + slug -> string + json -> json -> Json::cast + description -> text +OUT + , + $result + ); + } +} diff --git a/tests/Schema/Renderer/ConsoleRenderer/Renderer/KeysRendererTest.php b/tests/Schema/Renderer/ConsoleRenderer/Renderer/KeysRendererTest.php new file mode 100644 index 0000000..16a57e2 --- /dev/null +++ b/tests/Schema/Renderer/ConsoleRenderer/Renderer/KeysRendererTest.php @@ -0,0 +1,85 @@ +formatter = new PlainFormatter(); + } + + public function testRenderNullNotRequiredValue() + { + $renderer = new KeysRenderer(1, 'Foo', false); + + $result = $renderer->render($this->formatter, [1 => null], 'bar'); + + $this->assertNull($result); + } + + public function testRenderNullRequiredValue() + { + $renderer = new KeysRenderer(1, 'Foo', true); + + $result = $renderer->render($this->formatter, [1 => null], 'bar'); + + $this->assertSame(' Foo: not defined', $result); + } + + public function testRenderStringValue() + { + $renderer = new KeysRenderer(1, 'Foo'); + + $result = $renderer->render($this->formatter, [1 => 'foo'], 'bar'); + + $this->assertSame(' Foo: foo', $result); + } + + public function testRenderEmptyStringValue() + { + $renderer = new KeysRenderer(1, 'Foo'); + + $result = $renderer->render($this->formatter, [1 => ''], 'bar'); + + $this->assertSame(' Foo: not defined', $result); + } + + public function testRenderEmptyArrayValue() + { + $renderer = new KeysRenderer(1, 'Foo'); + + $result = $renderer->render($this->formatter, [1 => []], 'bar'); + + $this->assertSame(' Foo: not defined', $result); + } + + public function testRenderSingleItemArrayValue() + { + $renderer = new KeysRenderer(1, 'Foo'); + + $result = $renderer->render($this->formatter, [1 => ['hello']], 'bar'); + + $this->assertSame(' Foo: hello', $result); + } + + public function testRenderArrayValue() + { + $renderer = new KeysRenderer(1, 'Foo'); + + $result = $renderer->render($this->formatter, [1 => ['hello', 'world']], 'bar'); + + $this->assertSame(' Foo: hello, world', $result); + } +} diff --git a/tests/Schema/Renderer/ConsoleRenderer/Renderer/PropertyRendererTest.php b/tests/Schema/Renderer/ConsoleRenderer/Renderer/PropertyRendererTest.php new file mode 100644 index 0000000..88e2706 --- /dev/null +++ b/tests/Schema/Renderer/ConsoleRenderer/Renderer/PropertyRendererTest.php @@ -0,0 +1,114 @@ +formatter = new PlainFormatter(); + } + + public function testRenderNotExistsProperty() + { + $renderer = new PropertyRenderer(1, 'Foo'); + + $result = $renderer->render($this->formatter, [], 'baz'); + + $this->assertNull($result); + } + + public function testRenderNotExistsRequiredProperty() + { + $renderer = new PropertyRenderer(1, 'Foo', true); + + $result = $renderer->render($this->formatter, [], 'baz'); + + $this->assertSame(' Foo: not defined', $result); + } + + public function testRenderNullNotRequiredProperty() + { + $renderer = new PropertyRenderer(1, 'Foo'); + + $result = $renderer->render($this->formatter, [ + 1 => null, + ], 'baz'); + + $this->assertNull($result); + } + + public function testRenderNullRequiredProperty() + { + $renderer = new PropertyRenderer(1, 'Foo', true); + + $result = $renderer->render($this->formatter, [ + 1 => null, + ], 'baz'); + + $this->assertSame(' Foo: not defined', $result); + } + + public function testRenderStringProperty() + { + $renderer = new PropertyRenderer(1, 'Foo'); + + $result = $renderer->render($this->formatter, [ + 1 => 'bar', + ], 'baz'); + + $this->assertSame(' Foo: bar', $result); + } + + public function testRenderSingleItemArrayProperty() + { + $renderer = new PropertyRenderer(1, 'Foo'); + + $result = $renderer->render($this->formatter, [ + 1 => ['hello'], + ], 'baz'); + + $this->assertSame(' Foo: hello', $result); + } + + public function testRenderEmptyArrayProperty() + { + $renderer = new PropertyRenderer(1, 'Foo'); + + $result = $renderer->render($this->formatter, [ + 1 => [], + ], 'baz'); + + $this->assertSame(' Foo: []', $result); + } + + public function testRenderArrayProperty() + { + $renderer = new PropertyRenderer(1, 'Foo'); + + $result = $renderer->render($this->formatter, [ + 1 => ['hello', 'world', 'baz'], + ], 'baz'); + + $this->assertSame( + <<<'OUT' + Foo: hello + world + baz +OUT + , + $result + ); + } +} diff --git a/tests/Schema/Renderer/ConsoleRenderer/Renderer/TitleRendererTest.php b/tests/Schema/Renderer/ConsoleRenderer/Renderer/TitleRendererTest.php new file mode 100644 index 0000000..c91d293 --- /dev/null +++ b/tests/Schema/Renderer/ConsoleRenderer/Renderer/TitleRendererTest.php @@ -0,0 +1,91 @@ +formatter = new PlainFormatter(); + } + + public function testRenderWithDefinedProperties() + { + $renderer = new TitleRenderer(); + + $result = $renderer->render($this->formatter, [ + SchemaInterface::DATABASE => 'foo', + SchemaInterface::TABLE => 'bar', + ], 'foo'); + + $this->assertSame('[foo] :: foo.bar', $result); + } + + public function testRenderWithNullDatabaseProperties() + { + $renderer = new TitleRenderer(); + + $result = $renderer->render($this->formatter, [ + SchemaInterface::DATABASE => null, + SchemaInterface::TABLE => 'bar', + ], 'foo'); + + $this->assertSame('[foo] :: .bar', $result); + } + + public function testRenderWithNulTableProperties() + { + $renderer = new TitleRenderer(); + + $result = $renderer->render($this->formatter, [ + SchemaInterface::DATABASE => 'foo', + SchemaInterface::TABLE => null, + ], 'foo'); + + $this->assertSame('[foo] :: foo.', $result); + } + + public function testRenderWithoutDatabaseProperties() + { + $renderer = new TitleRenderer(); + + $result = $renderer->render($this->formatter, [ + SchemaInterface::TABLE => 'bar', + ], 'foo'); + + $this->assertSame('[foo] :: .bar', $result); + } + + public function testRenderWithoutTableProperties() + { + $renderer = new TitleRenderer(); + + $result = $renderer->render($this->formatter, [ + SchemaInterface::DATABASE => 'foo', + ], 'foo'); + + $this->assertSame('[foo] :: foo.', $result); + } + + public function testRenderWithoutProperties() + { + $renderer = new TitleRenderer(); + + $result = $renderer->render($this->formatter, [ + ], 'foo'); + + $this->assertSame('[foo] :: .', $result); + } +} diff --git a/tests/Schema/Renderer/Fixture/console_output.stub.txt b/tests/Schema/Renderer/Fixture/console_output.stub.txt index 8476e6d..bc49c2a 100644 --- a/tests/Schema/Renderer/Fixture/console_output.stub.txt +++ b/tests/Schema/Renderer/Fixture/console_output.stub.txt @@ -3,10 +3,10 @@ Mapper: Cycle\ORM\Mapper\Mapper Primary key: id Fields: - (property -> db.field -> typecast) - 0 -> id -> int - 1 -> email - 2 -> balance -> float + (property -> db.field -> typecast) + 0 -> id -> int + 1 -> email + 2 -> balance -> float Relations: Cycle\Schema\Renderer\Tests\Fixture\User->tags many to many Cycle\Schema\Renderer\Tests\Fixture\Tag, default loading, cascaded n/a Cycle\Schema\Renderer\Tests\Fixture\User.id <= tag_context.user_id | tag_context.tag_id => Cycle\Schema\Renderer\Tests\Fixture\Tag.id @@ -19,9 +19,9 @@ App\FooMapper Primary key: id, name Fields: - (property -> db.field -> typecast) - 0 -> id -> int - 1 -> name + (property -> db.field -> typecast) + 0 -> id -> int + 1 -> name Relations: Cycle\Schema\Renderer\Tests\Fixture\Tag->user belongs to Cycle\Schema\Renderer\Tests\Fixture\User, default loading, cascaded n/a Cycle\Schema\Renderer\Tests\Fixture\Tag.user_id <==> Cycle\Schema\Renderer\Tests\Fixture\User.id diff --git a/tests/Schema/Renderer/Fixture/console_output_plain.stub.txt b/tests/Schema/Renderer/Fixture/console_output_plain.stub.txt index 76f3283..257ac69 100644 --- a/tests/Schema/Renderer/Fixture/console_output_plain.stub.txt +++ b/tests/Schema/Renderer/Fixture/console_output_plain.stub.txt @@ -3,10 +3,10 @@ Mapper: Cycle\ORM\Mapper\Mapper Primary key: id Fields: - (property -> db.field -> typecast) - 0 -> id -> int - 1 -> email - 2 -> balance -> float + (property -> db.field -> typecast) + 0 -> id -> int + 1 -> email + 2 -> balance -> float Relations: user->tags many to many tag, default loading, cascaded n/a user.id <= tag_context.user_id | tag_context.tag_id => tag.id @@ -19,9 +19,9 @@ App\FooMapper Primary key: id, name Fields: - (property -> db.field -> typecast) - 0 -> id -> int - 1 -> name + (property -> db.field -> typecast) + 0 -> id -> int + 1 -> name Relations: tag->user belongs to user, default loading, cascaded n/a tag.user_id <==> user.id diff --git a/tests/Schema/Renderer/Fixture/console_output_with_custom_properties.stub.txt b/tests/Schema/Renderer/Fixture/console_output_with_custom_properties.stub.txt index 9db7b97..51bb88f 100644 --- a/tests/Schema/Renderer/Fixture/console_output_with_custom_properties.stub.txt +++ b/tests/Schema/Renderer/Fixture/console_output_with_custom_properties.stub.txt @@ -3,10 +3,10 @@ Mapper: Cycle\ORM\Mapper\Mapper Primary key: id Fields: - (property -> db.field -> typecast) - 0 -> id -> int - 1 -> email - 2 -> balance -> float + (property -> db.field -> typecast) + 0 -> id -> int + 1 -> email + 2 -> balance -> float Relations: Cycle\Schema\Renderer\Tests\Fixture\User->tags many to many Cycle\Schema\Renderer\Tests\Fixture\Tag, default loading, cascaded n/a Cycle\Schema\Renderer\Tests\Fixture\User.id <= tag_context.user_id | tag_context.tag_id => Cycle\Schema\Renderer\Tests\Fixture\Tag.id @@ -20,9 +20,9 @@ App\FooMapper Primary key: id, name Fields: - (property -> db.field -> typecast) - 0 -> id -> int - 1 -> name + (property -> db.field -> typecast) + 0 -> id -> int + 1 -> name Relations: Cycle\Schema\Renderer\Tests\Fixture\Tag->user belongs to Cycle\Schema\Renderer\Tests\Fixture\User, default loading, cascaded n/a Cycle\Schema\Renderer\Tests\Fixture\Tag.user_id <==> Cycle\Schema\Renderer\Tests\Fixture\User.id diff --git a/tests/Schema/Renderer/OutputSchemaRendererTest.php b/tests/Schema/Renderer/OutputSchemaRendererTest.php index 8f07f23..0800721 100644 --- a/tests/Schema/Renderer/OutputSchemaRendererTest.php +++ b/tests/Schema/Renderer/OutputSchemaRendererTest.php @@ -104,6 +104,8 @@ public function testSchemaShouldBeRendered(): void { $renderer = new OutputSchemaRenderer(OutputSchemaRenderer::FORMAT_CONSOLE_COLOR); + echo $renderer->render($this->schemaArray); + $expected = file_get_contents(__DIR__ . '/Fixture/console_output.stub.txt'); $this->assertSame(