From 110db79e521affe11e9d659ee95786d550db94b3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 10:08:43 +0000 Subject: [PATCH 1/8] Initial plan From dfd6b617166a408734694f388828f95f73954fd8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 10:21:28 +0000 Subject: [PATCH 2/8] Add table column alignment feature - Create Column interface with ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER constants - Update Renderer base class to support alignments and headers - Update Ascii renderer to apply alignment when padding columns - Update Table class to support alignment in constructor and setAlignments() - Add comprehensive tests for all alignment types - Address PR #171 feedback: headers passed explicitly to renderer, validation allows setting alignments before headers Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- lib/cli/Table.php | 37 ++++++++++++++-- lib/cli/table/Ascii.php | 4 +- lib/cli/table/Column.php | 22 +++++++++ lib/cli/table/Renderer.php | 23 +++++++++- tests/Test_Table.php | 91 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 171 insertions(+), 6 deletions(-) create mode 100644 lib/cli/table/Column.php diff --git a/lib/cli/Table.php b/lib/cli/Table.php index 1ed18fc..f8e349f 100644 --- a/lib/cli/Table.php +++ b/lib/cli/Table.php @@ -15,6 +15,7 @@ use cli\Shell; use cli\Streams; use cli\table\Ascii; +use cli\table\Column; use cli\table\Renderer; use cli\table\Tabular; @@ -27,6 +28,7 @@ class Table { protected $_footers = array(); protected $_width = array(); protected $_rows = array(); + protected $_alignments = array(); /** * Initializes the `Table` class. @@ -40,11 +42,12 @@ class Table { * table are used as the header values. * 3. Pass nothing and use `setHeaders()` and `addRow()` or `setRows()`. * - * @param array $headers Headers used in this table. Optional. - * @param array $rows The rows of data for this table. Optional. - * @param array $footers Footers used in this table. Optional. + * @param array $headers Headers used in this table. Optional. + * @param array $rows The rows of data for this table. Optional. + * @param array $footers Footers used in this table. Optional. + * @param array $alignments Column alignments. Optional. */ - public function __construct(array $headers = array(), array $rows = array(), array $footers = array()) { + public function __construct(array $headers = array(), array $rows = array(), array $footers = array(), array $alignments = array()) { if (!empty($headers)) { // If all the rows is given in $headers we use the keys from the // first row for the header values @@ -66,6 +69,10 @@ public function __construct(array $headers = array(), array $rows = array(), arr $this->setFooters($footers); } + if (!empty($alignments)) { + $this->setAlignments($alignments); + } + if (Shell::isPiped()) { $this->setRenderer(new Tabular()); } else { @@ -79,6 +86,7 @@ public function resetTable() $this->_width = array(); $this->_rows = array(); $this->_footers = array(); + $this->_alignments = array(); return $this; } @@ -137,6 +145,8 @@ public function display() { */ public function getDisplayLines() { $this->_renderer->setWidths($this->_width, $fallback = true); + $this->_renderer->setHeaders($this->_headers); + $this->_renderer->setAlignments($this->_alignments); $border = $this->_renderer->border(); $out = array(); @@ -201,6 +211,25 @@ public function setFooters(array $footers) { $this->_footers = $this->checkRow($footers); } + /** + * Set the alignments of the table. + * + * @param array $alignments An array of alignment constants keyed by column name. + */ + public function setAlignments(array $alignments) { + $valid_alignments = array( Column::ALIGN_LEFT, Column::ALIGN_RIGHT, Column::ALIGN_CENTER ); + foreach ( $alignments as $column => $alignment ) { + if ( ! in_array( $alignment, $valid_alignments, true ) ) { + throw new \InvalidArgumentException( "Invalid alignment value '$alignment' for column '$column'." ); + } + // Only validate column names if headers are already set + if ( ! empty( $this->_headers ) && ! in_array( $column, $this->_headers, true ) ) { + throw new \InvalidArgumentException( "Column '$column' does not exist in table headers." ); + } + } + $this->_alignments = $alignments; + } + /** * Add a row to the table. diff --git a/lib/cli/table/Ascii.php b/lib/cli/table/Ascii.php index 113c092..94add5f 100644 --- a/lib/cli/table/Ascii.php +++ b/lib/cli/table/Ascii.php @@ -198,8 +198,10 @@ public function row( array $row ) { } private function padColumn($content, $column) { + $column_name = isset( $this->_headers[$column] ) ? $this->_headers[$column] : ''; + $alignment = ( $column_name !== '' && array_key_exists( $column_name, $this->_alignments ) ) ? $this->_alignments[$column_name] : Column::ALIGN_LEFT; $content = str_replace( "\t", ' ', (string) $content ); - return $this->_characters['padding'] . Colors::pad( $content, $this->_widths[ $column ], $this->isPreColorized( $column ) ) . $this->_characters['padding']; + return $this->_characters['padding'] . Colors::pad( $content, $this->_widths[ $column ], $this->isPreColorized( $column ), false, $alignment ) . $this->_characters['padding']; } /** diff --git a/lib/cli/table/Column.php b/lib/cli/table/Column.php new file mode 100644 index 0000000..5c1f733 --- /dev/null +++ b/lib/cli/table/Column.php @@ -0,0 +1,22 @@ + + * @copyright 2010 James Logsdom (http://girsbrain.org) + * @license http://www.opensource.org/licenses/mit-license.php The MIT License + */ + +namespace cli\table; + +/** + * Column alignment constants for table rendering. + */ +interface Column { + const ALIGN_LEFT = STR_PAD_RIGHT; + const ALIGN_RIGHT = STR_PAD_LEFT; + const ALIGN_CENTER = STR_PAD_BOTH; +} diff --git a/lib/cli/table/Renderer.php b/lib/cli/table/Renderer.php index 3ac7be5..6bf6df7 100644 --- a/lib/cli/table/Renderer.php +++ b/lib/cli/table/Renderer.php @@ -17,9 +17,30 @@ */ abstract class Renderer { protected $_widths = array(); + protected $_alignments = array(); + protected $_headers = array(); - public function __construct(array $widths = array()) { + public function __construct(array $widths = array(), array $alignments = array()) { $this->setWidths($widths); + $this->setAlignments($alignments); + } + + /** + * Set the alignments of each column in the table. + * + * @param array $alignments The alignments of the columns. + */ + public function setAlignments(array $alignments) { + $this->_alignments = $alignments; + } + + /** + * Set the headers of the table. + * + * @param array $headers The headers of the table. + */ + public function setHeaders(array $headers) { + $this->_headers = $headers; } /** diff --git a/tests/Test_Table.php b/tests/Test_Table.php index 26db650..53542a7 100644 --- a/tests/Test_Table.php +++ b/tests/Test_Table.php @@ -289,4 +289,95 @@ public function test_null_values_are_handled() { ]; $this->assertSame( $expected, $out, 'Null values should be safely converted to empty strings in table output.' ); } + + public function test_default_alignment() { + $table = new cli\Table(); + $table->setRenderer( new cli\Table\Ascii() ); + $table->setHeaders( array( 'Header1', 'Header2' ) ); + $table->addRow( array( 'Row1Col1', 'Row1Col2' ) ); + + $out = $table->getDisplayLines(); + + // By default, columns should be left-aligned. + $this->assertStringContainsString( '| Header1 | Header2 |', $out[1] ); + $this->assertStringContainsString( '| Row1Col1 | Row1Col2 |', $out[3] ); + } + + public function test_right_alignment() { + $table = new cli\Table(); + $table->setRenderer( new cli\Table\Ascii() ); + $table->setHeaders( array( 'Name', 'Size' ) ); + $table->setAlignments( array( 'Name' => \cli\table\Column::ALIGN_RIGHT, 'Size' => \cli\table\Column::ALIGN_RIGHT ) ); + $table->addRow( array( 'file.txt', '1024 B' ) ); + + $out = $table->getDisplayLines(); + + // Headers should be right-aligned in their columns + $this->assertStringContainsString( '| Name | Size |', $out[1] ); + // Data should be right-aligned + $this->assertStringContainsString( '| file.txt | 1024 B |', $out[3] ); + } + + public function test_center_alignment() { + $table = new cli\Table(); + $table->setRenderer( new cli\Table\Ascii() ); + $table->setHeaders( array( 'A', 'B' ) ); + $table->setAlignments( array( 'A' => \cli\table\Column::ALIGN_CENTER, 'B' => \cli\table\Column::ALIGN_CENTER ) ); + $table->addRow( array( 'test', 'data' ) ); + + $out = $table->getDisplayLines(); + + // Headers should be center-aligned + $this->assertStringContainsString( '| A | B |', $out[1] ); + // Data should be center-aligned + $this->assertStringContainsString( '| test | data |', $out[3] ); + } + + public function test_mixed_alignments() { + $table = new cli\Table(); + $table->setRenderer( new cli\Table\Ascii() ); + $table->setHeaders( array( 'Name', 'Count', 'Status' ) ); + $table->setAlignments( array( + 'Name' => \cli\table\Column::ALIGN_LEFT, + 'Count' => \cli\table\Column::ALIGN_RIGHT, + 'Status' => \cli\table\Column::ALIGN_CENTER, + ) ); + $table->addRow( array( 'Item', '42', 'OK' ) ); + + $out = $table->getDisplayLines(); + + // Headers line should show all three with proper alignment + $this->assertStringContainsString( '| Name | Count | Status |', $out[1] ); + // Data line: Name left, Count right, Status center + $this->assertStringContainsString( '| Item | 42 | OK |', $out[3] ); + } + + public function test_invalid_alignment_value() { + $this->expectException( \InvalidArgumentException::class ); + $table = new cli\Table(); + $table->setHeaders( array( 'Header1' ) ); + $table->setAlignments( array( 'Header1' => 'invalid-alignment' ) ); + } + + public function test_invalid_alignment_column() { + $this->expectException( \InvalidArgumentException::class ); + $table = new cli\Table(); + $table->setHeaders( array( 'Header1' ) ); + $table->setAlignments( array( 'NonExistent' => \cli\table\Column::ALIGN_LEFT ) ); + } + + public function test_alignment_before_headers() { + // Test that alignments can be set before headers without throwing an error + $table = new cli\Table(); + $table->setRenderer( new cli\Table\Ascii() ); + $table->setAlignments( array( 'Name' => \cli\table\Column::ALIGN_RIGHT ) ); + $table->setHeaders( array( 'Name' ) ); + $table->addRow( array( 'LongName' ) ); + + $out = $table->getDisplayLines(); + + // Should be right-aligned - "Name" is 4 chars, "LongName" is 8 chars, so column width is 8 + $this->assertStringContainsString( '| Name |', $out[1] ); + $this->assertStringContainsString( '| LongName |', $out[3] ); + } } From df01866a7e995bfd16cfe1b02f7a40487869004d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 10:22:37 +0000 Subject: [PATCH 3/8] Add table alignment example demonstrating the feature Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- examples/table-alignment.php | 103 +++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100755 examples/table-alignment.php diff --git a/examples/table-alignment.php b/examples/table-alignment.php new file mode 100755 index 0000000..cc55e63 --- /dev/null +++ b/examples/table-alignment.php @@ -0,0 +1,103 @@ +#!/usr/bin/env php +setHeaders(['Product', 'Price', 'Stock']); +$table->addRow(['Widget', '$19.99', '150']); +$table->addRow(['Gadget', '$29.99', '75']); +$table->addRow(['Tool', '$9.99', '200']); +$table->display(); +cli\line(); + +// Example 2: Right Alignment for Numeric Columns +cli\line('%Y## Example 2: Right Alignment for Numeric Columns%n'); +cli\line('Notice how the numeric values are much easier to compare when right-aligned.'); +cli\line(); +$table = new cli\Table(); +$table->setHeaders(['Product', 'Price', 'Stock']); +$table->setAlignments([ + 'Product' => cli\table\Column::ALIGN_LEFT, + 'Price' => cli\table\Column::ALIGN_RIGHT, + 'Stock' => cli\table\Column::ALIGN_RIGHT, +]); +$table->addRow(['Widget', '$19.99', '150']); +$table->addRow(['Gadget', '$29.99', '75']); +$table->addRow(['Tool', '$9.99', '200']); +$table->display(); +cli\line(); + +// Example 3: Center Alignment +cli\line('%Y## Example 3: Center Alignment%n'); +cli\line(); +$table = new cli\Table(); +$table->setHeaders(['Left', 'Center', 'Right']); +$table->setAlignments([ + 'Left' => cli\table\Column::ALIGN_LEFT, + 'Center' => cli\table\Column::ALIGN_CENTER, + 'Right' => cli\table\Column::ALIGN_RIGHT, +]); +$table->addRow(['Text', 'Centered', 'More']); +$table->addRow(['Data', 'Values', 'Here']); +$table->addRow(['A', 'B', 'C']); +$table->display(); +cli\line(); + +// Example 4: Real-world Database Table Sizes +cli\line('%Y## Example 4: Database Table Sizes (Real-world Use Case)%n'); +cli\line('This example shows how the alignment feature makes database'); +cli\line('statistics much more readable and easier to compare.'); +cli\line(); +$table = new cli\Table(); +$table->setHeaders(['Table Name', 'Rows', 'Data Size', 'Index Size']); +$table->setAlignments([ + 'Table Name' => cli\table\Column::ALIGN_LEFT, + 'Rows' => cli\table\Column::ALIGN_RIGHT, + 'Data Size' => cli\table\Column::ALIGN_RIGHT, + 'Index Size' => cli\table\Column::ALIGN_RIGHT, +]); +$table->addRow(['wp_posts', '1,234', '5.2 MB', '1.1 MB']); +$table->addRow(['wp_postmeta', '45,678', '23.4 MB', '8.7 MB']); +$table->addRow(['wp_comments', '9,012', '2.3 MB', '0.8 MB']); +$table->addRow(['wp_options', '456', '1.5 MB', '0.2 MB']); +$table->addRow(['wp_users', '89', '0.1 MB', '0.05 MB']); +$table->display(); +cli\line(); + +// Example 5: Alignment Constants +cli\line('%Y## Alignment Constants%n'); +cli\line(); +cli\line('You can use the following constants from %Ccli\table\Column%n:'); +cli\line(' %G*%n %CALIGN_LEFT%n - Left align (default)'); +cli\line(' %G*%n %CALIGN_RIGHT%n - Right align (good for numbers)'); +cli\line(' %G*%n %CALIGN_CENTER%n - Center align'); +cli\line(); +cli\line('Example usage:'); +cli\line(' %c$table->setAlignments([%n'); +cli\line(' %c\'Column1\' => cli\table\Column::ALIGN_LEFT,%n'); +cli\line(' %c\'Column2\' => cli\table\Column::ALIGN_RIGHT,%n'); +cli\line(' %c]);%n'); +cli\line(); + +cli\line('%GDone!%n'); +cli\line(); From 69bd29f3c3b6355bed0e9663d3dd2326d31a707b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 10:24:17 +0000 Subject: [PATCH 4/8] Optimize alignment lookup and validation - Extract getColumnAlignment() method for better readability - Use array_flip() for O(1) lookups instead of in_array() O(n) searches - Address code review feedback Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- lib/cli/Table.php | 11 +++++++---- lib/cli/table/Ascii.php | 17 +++++++++++++++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/cli/Table.php b/lib/cli/Table.php index f8e349f..6beb9d4 100644 --- a/lib/cli/Table.php +++ b/lib/cli/Table.php @@ -217,14 +217,17 @@ public function setFooters(array $footers) { * @param array $alignments An array of alignment constants keyed by column name. */ public function setAlignments(array $alignments) { - $valid_alignments = array( Column::ALIGN_LEFT, Column::ALIGN_RIGHT, Column::ALIGN_CENTER ); + $valid_alignments = array_flip( array( Column::ALIGN_LEFT, Column::ALIGN_RIGHT, Column::ALIGN_CENTER ) ); foreach ( $alignments as $column => $alignment ) { - if ( ! in_array( $alignment, $valid_alignments, true ) ) { + if ( ! isset( $valid_alignments[ $alignment ] ) ) { throw new \InvalidArgumentException( "Invalid alignment value '$alignment' for column '$column'." ); } // Only validate column names if headers are already set - if ( ! empty( $this->_headers ) && ! in_array( $column, $this->_headers, true ) ) { - throw new \InvalidArgumentException( "Column '$column' does not exist in table headers." ); + if ( ! empty( $this->_headers ) ) { + $headers_map = array_flip( $this->_headers ); + if ( ! isset( $headers_map[ $column ] ) ) { + throw new \InvalidArgumentException( "Column '$column' does not exist in table headers." ); + } } } $this->_alignments = $alignments; diff --git a/lib/cli/table/Ascii.php b/lib/cli/table/Ascii.php index 94add5f..506ffec 100644 --- a/lib/cli/table/Ascii.php +++ b/lib/cli/table/Ascii.php @@ -197,9 +197,22 @@ public function row( array $row ) { return $ret; } + /** + * Get the alignment for a column. + * + * @param int $column Column index. + * @return int Alignment constant (STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH). + */ + private function getColumnAlignment( $column ) { + $column_name = isset( $this->_headers[ $column ] ) ? $this->_headers[ $column ] : ''; + if ( $column_name !== '' && array_key_exists( $column_name, $this->_alignments ) ) { + return $this->_alignments[ $column_name ]; + } + return Column::ALIGN_LEFT; + } + private function padColumn($content, $column) { - $column_name = isset( $this->_headers[$column] ) ? $this->_headers[$column] : ''; - $alignment = ( $column_name !== '' && array_key_exists( $column_name, $this->_alignments ) ) ? $this->_alignments[$column_name] : Column::ALIGN_LEFT; + $alignment = $this->getColumnAlignment( $column ); $content = str_replace( "\t", ' ', (string) $content ); return $this->_characters['padding'] . Colors::pad( $content, $this->_widths[ $column ], $this->isPreColorized( $column ), false, $alignment ) . $this->_characters['padding']; } From e842497caa3cfb995058a145a204f8d222dab65b Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 20 Jan 2026 11:37:02 +0100 Subject: [PATCH 5/8] Update lib/cli/Table.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- lib/cli/Table.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/cli/Table.php b/lib/cli/Table.php index 6beb9d4..d159adf 100644 --- a/lib/cli/Table.php +++ b/lib/cli/Table.php @@ -218,16 +218,14 @@ public function setFooters(array $footers) { */ public function setAlignments(array $alignments) { $valid_alignments = array_flip( array( Column::ALIGN_LEFT, Column::ALIGN_RIGHT, Column::ALIGN_CENTER ) ); + $headers_map = ! empty( $this->_headers ) ? array_flip( $this->_headers ) : null; foreach ( $alignments as $column => $alignment ) { if ( ! isset( $valid_alignments[ $alignment ] ) ) { throw new \InvalidArgumentException( "Invalid alignment value '$alignment' for column '$column'." ); } // Only validate column names if headers are already set - if ( ! empty( $this->_headers ) ) { - $headers_map = array_flip( $this->_headers ); - if ( ! isset( $headers_map[ $column ] ) ) { - throw new \InvalidArgumentException( "Column '$column' does not exist in table headers." ); - } + if ( $headers_map !== null && ! isset( $headers_map[ $column ] ) ) { + throw new \InvalidArgumentException( "Column '$column' does not exist in table headers." ); } } $this->_alignments = $alignments; From cb48e85459e55eac8342d4065a5c8299ba1ea897 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 10:46:38 +0000 Subject: [PATCH 6/8] Cache valid alignments map to avoid recreating on every call Use a static property to cache the valid alignments map, avoiding the overhead of array creation and array_flip() on every setAlignments() call. Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- lib/cli/Table.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/cli/Table.php b/lib/cli/Table.php index d159adf..9a7df92 100644 --- a/lib/cli/Table.php +++ b/lib/cli/Table.php @@ -30,6 +30,13 @@ class Table { protected $_rows = array(); protected $_alignments = array(); + /** + * Cached map of valid alignment constants. + * + * @var array|null + */ + private static $_valid_alignments_map = null; + /** * Initializes the `Table` class. * @@ -217,10 +224,14 @@ public function setFooters(array $footers) { * @param array $alignments An array of alignment constants keyed by column name. */ public function setAlignments(array $alignments) { - $valid_alignments = array_flip( array( Column::ALIGN_LEFT, Column::ALIGN_RIGHT, Column::ALIGN_CENTER ) ); + // Initialize the cached valid alignments map on first use + if ( null === self::$_valid_alignments_map ) { + self::$_valid_alignments_map = array_flip( array( Column::ALIGN_LEFT, Column::ALIGN_RIGHT, Column::ALIGN_CENTER ) ); + } + $headers_map = ! empty( $this->_headers ) ? array_flip( $this->_headers ) : null; foreach ( $alignments as $column => $alignment ) { - if ( ! isset( $valid_alignments[ $alignment ] ) ) { + if ( ! isset( self::$_valid_alignments_map[ $alignment ] ) ) { throw new \InvalidArgumentException( "Invalid alignment value '$alignment' for column '$column'." ); } // Only validate column names if headers are already set From c3ff813a9c663e7375cfe87ed164fc780c62ecc9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 11:12:28 +0000 Subject: [PATCH 7/8] Remove extra blank line for consistent spacing Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- lib/cli/Table.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/cli/Table.php b/lib/cli/Table.php index 9a7df92..5ea3392 100644 --- a/lib/cli/Table.php +++ b/lib/cli/Table.php @@ -242,7 +242,6 @@ public function setAlignments(array $alignments) { $this->_alignments = $alignments; } - /** * Add a row to the table. * From d34de56b07390d5e9c262c77dad677599b9fd81b Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 20 Jan 2026 21:20:20 +0100 Subject: [PATCH 8/8] Fix merge hiccup --- tests/Test_Table.php | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/tests/Test_Table.php b/tests/Test_Table.php index 8cb5cfc..ca03f71 100644 --- a/tests/Test_Table.php +++ b/tests/Test_Table.php @@ -379,18 +379,20 @@ public function test_alignment_before_headers() { // Should be right-aligned - "Name" is 4 chars, "LongName" is 8 chars, so column width is 8 $this->assertStringContainsString( '| Name |', $out[1] ); $this->assertStringContainsString( '| LongName |', $out[3] ); + } + public function test_resetRows() { $table = new cli\Table(); $table->setHeaders( array( 'Name', 'Age' ) ); $table->addRow( array( 'Alice', '30' ) ); $table->addRow( array( 'Bob', '25' ) ); - + $this->assertEquals( 2, $table->countRows() ); - + $table->resetRows(); - + $this->assertEquals( 0, $table->countRows() ); - + // Headers should still be intact $out = $table->getDisplayLines(); $this->assertGreaterThan( 0, count( $out ) ); @@ -402,21 +404,21 @@ public function test_displayRow_ascii() { try { \cli\Streams::setStream( 'out', $resource ); - + $table = new cli\Table(); $renderer = new cli\Table\Ascii(); $table->setRenderer( $renderer ); $table->setHeaders( array( 'Name', 'Age' ) ); - + // Display a single row $table->displayRow( array( 'Alice', '30' ) ); - + $output = file_get_contents( $mockFile ); - + // Should contain the row data $this->assertStringContainsString( 'Alice', $output ); $this->assertStringContainsString( '30', $output ); - + // Should contain borders $this->assertStringContainsString( '|', $output ); $this->assertStringContainsString( '+', $output ); @@ -433,17 +435,17 @@ public function test_displayRow_tabular() { try { \cli\Streams::setStream( 'out', $resource ); - + $table = new cli\Table(); $renderer = new cli\Table\Tabular(); $table->setRenderer( $renderer ); $table->setHeaders( array( 'Name', 'Age' ) ); - + // Display a single row $table->displayRow( array( 'Alice', '30' ) ); - + $output = file_get_contents( $mockFile ); - + // Should contain the row data with tabs $this->assertStringContainsString( 'Alice', $output ); $this->assertStringContainsString( '30', $output );