From e03959dca3dc55aa19df1b7d88e36d07e8920b0d Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Thu, 5 Jun 2025 08:35:28 +1000 Subject: [PATCH] Added a smaller header to the installer. --- .../installer/src/Command/InstallCommand.php | 39 ++-- .vortex/installer/src/Utils/Tui.php | 29 +++ .vortex/installer/tests/Unit/TuiTest.php | 169 ++++++++++++++++++ 3 files changed, 222 insertions(+), 15 deletions(-) diff --git a/.vortex/installer/src/Command/InstallCommand.php b/.vortex/installer/src/Command/InstallCommand.php index 9fb14a266..73275971f 100644 --- a/.vortex/installer/src/Command/InstallCommand.php +++ b/.vortex/installer/src/Command/InstallCommand.php @@ -349,26 +349,35 @@ protected function handleDemo(): array|string { } protected function header(): void { - $logo = <<= 80) { - Tui::note($logo); - } + $logo_small = <<= 80 ? $logo_large : $logo_small; + $logo = Tui::center($logo, Tui::terminalWidth(), '─'); + Tui::note($logo); $title = 'Welcome to Vortex interactive installer'; $content = ''; diff --git a/.vortex/installer/src/Utils/Tui.php b/.vortex/installer/src/Utils/Tui.php index 3d761a38e..b76e5bbe1 100644 --- a/.vortex/installer/src/Utils/Tui.php +++ b/.vortex/installer/src/Utils/Tui.php @@ -97,6 +97,35 @@ public static function box(string $content, ?string $title = NULL, int $width = table([], $rows); } + public static function center(string $text, int $width = 80, ?string $border = NULL): string { + $lines = explode(PHP_EOL, $text); + $centered_lines = []; + + // Find the maximum line length. + $max_length = 0; + foreach ($lines as $line) { + $line_length = Strings::strlenPlain($line); + if ($line_length > $max_length) { + $max_length = $line_length; + } + } + + foreach ($lines as $line) { + $padding = empty($line) ? '' : str_repeat(' ', (int) (($width - $max_length) / 2)); + $centered_lines[] = $padding . $line; + } + + if ($border) { + $border = str_repeat($border, $width - 2); + array_unshift($centered_lines, ''); + array_unshift($centered_lines, $border); + $centered_lines[] = ''; + $centered_lines[] = $border; + } + + return implode(PHP_EOL, $centered_lines); + } + public static function ok(string $text = 'OK'): void { $ok = static::green(static::normalizeText("✅ " . $text)); static::note($ok); diff --git a/.vortex/installer/tests/Unit/TuiTest.php b/.vortex/installer/tests/Unit/TuiTest.php index cd7fe16b9..863dfd097 100644 --- a/.vortex/installer/tests/Unit/TuiTest.php +++ b/.vortex/installer/tests/Unit/TuiTest.php @@ -120,4 +120,173 @@ public static function dataProviderAction(): array { ]; } + #[DataProvider('dataProviderCenter')] + public function testCenter( + string $text, + int $width, + ?string $border, + string $expected, + ): void { + $actual = Tui::center($text, $width, $border); + $this->assertSame($expected, $actual); + } + + /** + * Data provider for testCenter. + */ + public static function dataProviderCenter(): array { + return [ + + 'single line text with default width' => [ + 'text' => 'Hello', + 'width' => 80, + 'border' => NULL, + 'expected' => <<<'EXPECTED' + Hello +EXPECTED, + ], + + 'single line text with custom width' => [ + 'text' => 'Test', + 'width' => 20, + 'border' => NULL, + 'expected' => <<<'EXPECTED' + Test +EXPECTED, + ], + + 'multiline text without border' => [ + 'text' => <<<'TEXT' +Line 1 +Line 2 +TEXT, + 'width' => 20, + 'border' => NULL, + 'expected' => <<<'EXPECTED' + Line 1 + Line 2 +EXPECTED, + ], + + 'multiline text with different line lengths' => [ + 'text' => <<<'TEXT' +Short +Longer line +X +TEXT, + 'width' => 30, + 'border' => NULL, + 'expected' => <<<'EXPECTED' + Short + Longer line + X +EXPECTED, + ], + + 'empty line in multiline text' => [ + 'text' => <<<'TEXT' +Line 1 + +Line 3 +TEXT, + 'width' => 20, + 'border' => NULL, + 'expected' => <<<'EXPECTED' + Line 1 + + Line 3 +EXPECTED, + ], + + 'single line text with border' => [ + 'text' => 'Hello', + 'width' => 20, + 'border' => '=', + 'expected' => <<<'EXPECTED' +================== + + Hello + +================== +EXPECTED, + ], + + 'multiline text with border' => [ + 'text' => <<<'TEXT' +Line 1 +Line 2 +TEXT, + 'width' => 25, + 'border' => '-', + 'expected' => <<<'EXPECTED' +----------------------- + + Line 1 + Line 2 + +----------------------- +EXPECTED, + ], + + 'text with exact width match' => [ + 'text' => 'Exact', + 'width' => 5, + 'border' => NULL, + 'expected' => <<<'EXPECTED' +Exact +EXPECTED, + ], + + 'text wider than available width' => [ + 'text' => 'Very long text', + 'width' => 20, + 'border' => NULL, + 'expected' => <<<'EXPECTED' + Very long text +EXPECTED, + ], + + 'single character text' => [ + 'text' => 'X', + 'width' => 10, + 'border' => NULL, + 'expected' => <<<'EXPECTED' + X +EXPECTED, + ], + + 'empty text' => [ + 'text' => '', + 'width' => 10, + 'border' => NULL, + 'expected' => <<<'EXPECTED' + +EXPECTED, + ], + + 'whitespace only text' => [ + 'text' => ' ', + 'width' => 15, + 'border' => NULL, + 'expected' => <<<'EXPECTED' + +EXPECTED, + ], + + 'text with border using different character' => [ + 'text' => 'Bordered', + 'width' => 16, + 'border' => '*', + 'expected' => <<<'EXPECTED' +************** + + Bordered + +************** +EXPECTED, + ], + + ]; + } + }