From 2cf65089acbff50c1486fc2f287a1d2d65c5c105 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Dec 2025 12:10:44 +0000 Subject: [PATCH 01/10] Initial plan From 84e4fa36d3947ba5c11078cafdddfe11b8c4e8fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Dec 2025 12:16:43 +0000 Subject: [PATCH 02/10] Make Headers and Rows public properties with cache clearing, add AddRows method, and add unit tests Co-authored-by: BrunoVT1992 <8803153+BrunoVT1992@users.noreply.github.com> --- ConsoleTable.Text/Table.cs | 42 +++- Tests/ConsoleTable.Text.Tests/TableTests.cs | 214 ++++++++++++++++++++ 2 files changed, 254 insertions(+), 2 deletions(-) diff --git a/ConsoleTable.Text/Table.cs b/ConsoleTable.Text/Table.cs index b52b19b..6d1440d 100644 --- a/ConsoleTable.Text/Table.cs +++ b/ConsoleTable.Text/Table.cs @@ -8,7 +8,33 @@ namespace ConsoleTable.Text public class Table { private string[] _headers; + /// + /// Gets or sets the headers of the table + /// + public string[] Headers + { + get => _headers; + set + { + _headers = value; + ClearCache(); + } + } + private List _rows = new List(); + /// + /// Gets or sets the rows of the table + /// + public List Rows + { + get => _rows; + set + { + _rows = value ?? new List(); + ClearCache(); + } + } + private string _tableCache = null; private int _padding = 1; @@ -63,8 +89,7 @@ public bool RowTextAlignmentRight /// public Table SetHeaders(params string[] headers) { - _headers = headers; - ClearCache(); + Headers = headers; return this; } @@ -78,6 +103,19 @@ public Table AddRow(params string[] row) return this; } + /// + /// Adds multiple rows to the table + /// + public Table AddRows(params string[][] rows) + { + if (rows != null) + { + _rows.AddRange(rows); + ClearCache(); + } + return this; + } + /// /// Clears all the rows from the table /// diff --git a/Tests/ConsoleTable.Text.Tests/TableTests.cs b/Tests/ConsoleTable.Text.Tests/TableTests.cs index d2794df..4db3f80 100644 --- a/Tests/ConsoleTable.Text.Tests/TableTests.cs +++ b/Tests/ConsoleTable.Text.Tests/TableTests.cs @@ -391,4 +391,218 @@ public void RowTextAlignRight_True_AlignsToDifferentPosition() Assert.Contains("V", resultRight); Assert.NotEqual(resultLeft, resultRight); } + + [Fact] + public void Headers_SetProperty_SetsHeadersAndClearsCache() + { + var table = new Table(); + table.Headers = new[] { "Name", "Age" }; + + var result = table.ToString(); + + Assert.Contains("Name", result); + Assert.Contains("Age", result); + } + + [Fact] + public void Headers_GetProperty_ReturnsHeaders() + { + var table = new Table(); + table.SetHeaders("Name", "Age"); + + var headers = table.Headers; + + Assert.Equal(new[] { "Name", "Age" }, headers); + } + + [Fact] + public void Headers_SetProperty_OverwritesPreviousHeaders() + { + var table = new Table(); + table.Headers = new[] { "Old1", "Old2" }; + table.Headers = new[] { "New1", "New2" }; + + var result = table.ToString(); + + Assert.DoesNotContain("Old1", result); + Assert.DoesNotContain("Old2", result); + Assert.Contains("New1", result); + Assert.Contains("New2", result); + } + + [Fact] + public void Headers_SetProperty_ClearsCache() + { + var table = new Table(); + table.Headers = new[] { "Header1" }; + var firstResult = table.ToString(); + + table.Headers = new[] { "Header2" }; + var secondResult = table.ToString(); + + Assert.Contains("Header1", firstResult); + Assert.DoesNotContain("Header1", secondResult); + Assert.Contains("Header2", secondResult); + } + + [Fact] + public void Rows_SetProperty_SetsRowsAndClearsCache() + { + var table = new Table(); + table.Rows = new List + { + new[] { "John", "30" }, + new[] { "Jane", "25" } + }; + + var result = table.ToString(); + + Assert.Contains("John", result); + Assert.Contains("Jane", result); + Assert.Contains("30", result); + Assert.Contains("25", result); + } + + [Fact] + public void Rows_GetProperty_ReturnsRows() + { + var table = new Table(); + table.AddRow("John", "30"); + table.AddRow("Jane", "25"); + + var rows = table.Rows; + + Assert.Equal(2, rows.Count); + Assert.Equal(new[] { "John", "30" }, rows[0]); + Assert.Equal(new[] { "Jane", "25" }, rows[1]); + } + + [Fact] + public void Rows_SetProperty_OverwritesPreviousRows() + { + var table = new Table(); + table.Rows = new List { new[] { "OldRow" } }; + table.Rows = new List { new[] { "NewRow" } }; + + var result = table.ToString(); + + Assert.DoesNotContain("OldRow", result); + Assert.Contains("NewRow", result); + } + + [Fact] + public void Rows_SetProperty_ClearsCache() + { + var table = new Table(); + table.Rows = new List { new[] { "Row1" } }; + var firstResult = table.ToString(); + + table.Rows = new List { new[] { "Row2" } }; + var secondResult = table.ToString(); + + Assert.Contains("Row1", firstResult); + Assert.DoesNotContain("Row1", secondResult); + Assert.Contains("Row2", secondResult); + } + + [Fact] + public void Rows_SetNull_CreatesEmptyList() + { + var table = new Table(); + table.AddRow("InitialRow"); + table.Rows = null; + + var result = table.ToString(); + + Assert.Empty(result); + Assert.NotNull(table.Rows); + Assert.Empty(table.Rows); + } + + [Fact] + public void AddRows_AddsMultipleRows() + { + var table = new Table(); + table.AddRows( + new[] { "Row1Col1", "Row1Col2" }, + new[] { "Row2Col1", "Row2Col2" }, + new[] { "Row3Col1", "Row3Col2" } + ); + + var result = table.ToString(); + + Assert.Contains("Row1Col1", result); + Assert.Contains("Row2Col1", result); + Assert.Contains("Row3Col1", result); + } + + [Fact] + public void AddRows_AppendsToExistingRows() + { + var table = new Table(); + table.AddRow("ExistingRow"); + table.AddRows( + new[] { "NewRow1" }, + new[] { "NewRow2" } + ); + + var result = table.ToString(); + + Assert.Contains("ExistingRow", result); + Assert.Contains("NewRow1", result); + Assert.Contains("NewRow2", result); + } + + [Fact] + public void AddRows_ReturnsTableInstance() + { + var table = new Table(); + + var result = table.AddRows(new[] { "Row1" }, new[] { "Row2" }); + + Assert.Same(table, result); + } + + [Fact] + public void AddRows_WithNull_DoesNotThrow() + { + var table = new Table(); + table.AddRow("ExistingRow"); + + var exception = Record.Exception(() => table.AddRows(null)); + + Assert.Null(exception); + var result = table.ToString(); + Assert.Contains("ExistingRow", result); + } + + [Fact] + public void AddRows_ClearsCache() + { + var table = new Table(); + table.AddRow("InitialRow"); + var firstResult = table.ToString(); + + table.AddRows(new[] { "NewRow" }); + var secondResult = table.ToString(); + + Assert.DoesNotContain("NewRow", firstResult); + Assert.Contains("NewRow", secondResult); + } + + [Fact] + public void AddRows_ChainedWithOtherMethods() + { + var table = new Table() + .SetHeaders("Col1", "Col2") + .AddRows(new[] { "R1C1", "R1C2" }, new[] { "R2C1", "R2C2" }) + .AddRow("R3C1", "R3C2"); + + var result = table.ToString(); + + Assert.Contains("Col1", result); + Assert.Contains("R1C1", result); + Assert.Contains("R2C1", result); + Assert.Contains("R3C1", result); + } } From 74246ec82e9445b5ab8e76c1ae780774357bd2b5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Dec 2025 12:24:33 +0000 Subject: [PATCH 03/10] Address PR feedback: update Headers summary, use ?.Any() in AddRows, use ToTable() in tests Co-authored-by: BrunoVT1992 <8803153+BrunoVT1992@users.noreply.github.com> --- ConsoleTable.Text/Table.cs | 6 +- Tests/ConsoleTable.Text.Tests/TableTests.cs | 78 ++++++++++----------- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/ConsoleTable.Text/Table.cs b/ConsoleTable.Text/Table.cs index 6d1440d..5a87130 100644 --- a/ConsoleTable.Text/Table.cs +++ b/ConsoleTable.Text/Table.cs @@ -9,7 +9,7 @@ public class Table { private string[] _headers; /// - /// Gets or sets the headers of the table + /// Gets or sets the headers of the table. This is a single optional top row. /// public string[] Headers { @@ -108,8 +108,10 @@ public Table AddRow(params string[] row) /// public Table AddRows(params string[][] rows) { - if (rows != null) + if (rows?.Any() == true) { + if (_rows == null) + _rows = new List(); _rows.AddRange(rows); ClearCache(); } diff --git a/Tests/ConsoleTable.Text.Tests/TableTests.cs b/Tests/ConsoleTable.Text.Tests/TableTests.cs index 4db3f80..c66909b 100644 --- a/Tests/ConsoleTable.Text.Tests/TableTests.cs +++ b/Tests/ConsoleTable.Text.Tests/TableTests.cs @@ -9,7 +9,7 @@ public void ToString_EmptyTable_ReturnsEmptyString() { var table = new Table(); - var result = table.ToString(); + var result = table.ToTable(); Assert.Equal(string.Empty, result); } @@ -20,7 +20,7 @@ public void ToString_WithHeadersOnly_ReturnsFormattedTable() var table = new Table(); table.SetHeaders("Name", "Age"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("Age", result); @@ -33,7 +33,7 @@ public void ToString_WithRowsOnly_ReturnsFormattedTable() table.AddRow("John", "30"); table.AddRow("Jane", "25"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("John", result); Assert.Contains("Jane", result); @@ -49,7 +49,7 @@ public void ToString_WithHeadersAndRows_ReturnsFormattedTable() table.AddRow("John", "30"); table.AddRow("Jane", "25"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("Age", result); @@ -67,7 +67,7 @@ public void ClearRows_RemovesAllRows() table.ClearRows(); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("Age", result); @@ -85,7 +85,7 @@ public void Clear_IsEmpty() table.Clear(); - var result = table.ToString(); + var result = table.ToTable(); Assert.Empty(result); } @@ -99,7 +99,7 @@ public void ClearRows_ThenAddNewRows_Works() table.ClearRows(); table.AddRow("Jane"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.DoesNotContain("John", result); @@ -143,8 +143,8 @@ public void Padding_AffectsTableWidth() table2.SetHeaders("Name"); table2.AddRow("Test"); - var result1 = table1.ToString(); - var result2 = table2.ToString(); + var result1 = table1.ToTable(); + var result2 = table2.ToTable(); // Table with more padding should have longer lines var lines1 = result1.Split('\n', StringSplitOptions.RemoveEmptyEntries); @@ -160,7 +160,7 @@ public void Padding_ZeroPadding_Works() table.SetHeaders("Name"); table.AddRow("Test"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("Test", result); @@ -204,7 +204,7 @@ public void ToString_WithSingleColumn_ReturnsProperCorners() var table = new Table(); table.SetHeaders("Single"); - var result = table.ToString(); + var result = table.ToTable(); // Should have proper corners for single column Assert.Contains("┌", result); @@ -222,7 +222,7 @@ public void ToString_MoreHeadersThanRowColumns_HandlesCorrectly() table.AddRow("name 2", "date 2"); table.AddRow("name 3"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("Date", result); @@ -241,7 +241,7 @@ public void ToString_LessHeadersThanRowColumns_HandlesCorrectly() table.AddRow("name 1", "date 1"); table.AddRow("name 2", "date 2", "1"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("name 1", result); @@ -259,7 +259,7 @@ public void ToString_VaryingRowWidths_HandlesCorrectly() table.AddRow("much longer text here"); table.AddRow("mid length"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("short", result); Assert.Contains("much longer text here", result); @@ -273,7 +273,7 @@ public void SetHeaders_OverwritesPreviousHeaders() table.SetHeaders("Old1", "Old2"); table.SetHeaders("New1", "New2"); - var result = table.ToString(); + var result = table.ToTable(); Assert.DoesNotContain("Old1", result); Assert.DoesNotContain("Old2", result); @@ -289,7 +289,7 @@ public void AddRow_MultipleTimes_AddsAllRows() table.AddRow("Row2"); table.AddRow("Row3"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Row1", result); Assert.Contains("Row2", result); @@ -303,7 +303,7 @@ public void ToString_ContainsTableBorderCharacters() table.SetHeaders("Header"); table.AddRow("Value"); - var result = table.ToString(); + var result = table.ToTable(); // Check for various border characters Assert.Contains("│", result); // Vertical line @@ -319,7 +319,7 @@ public void ToString_MultipleColumns_ContainsMiddleJoint() table.SetHeaders("Col1", "Col2"); table.AddRow("Val1", "Val2"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("┼", result); // Middle joint } @@ -330,7 +330,7 @@ public void ToString_SingleRowSingleColumn_ReturnsValidTable() var table = new Table(); table.AddRow("X"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("X", result); Assert.Contains("┌", result); @@ -346,7 +346,7 @@ public void ToString_EmptyStringValues_HandlesCorrectly() table.SetHeaders("Name", "Value"); table.AddRow("", ""); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("Value", result); @@ -363,8 +363,8 @@ public void HeaderTextAlignRight_True_AlignsToDifferentPosition() tableRight.SetHeaders("H"); tableRight.AddRow("VeryLongValue"); - var resultLeft = tableLeft.ToString(); - var resultRight = tableRight.ToString(); + var resultLeft = tableLeft.ToTable(); + var resultRight = tableRight.ToTable(); // Both should contain the header, but in different positions Assert.Contains("H", resultLeft); @@ -383,8 +383,8 @@ public void RowTextAlignRight_True_AlignsToDifferentPosition() tableRight.SetHeaders("HeaderHeader"); tableRight.AddRow("V"); - var resultLeft = tableLeft.ToString(); - var resultRight = tableRight.ToString(); + var resultLeft = tableLeft.ToTable(); + var resultRight = tableRight.ToTable(); // Both should contain the value, but in different positions Assert.Contains("V", resultLeft); @@ -398,7 +398,7 @@ public void Headers_SetProperty_SetsHeadersAndClearsCache() var table = new Table(); table.Headers = new[] { "Name", "Age" }; - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Name", result); Assert.Contains("Age", result); @@ -422,7 +422,7 @@ public void Headers_SetProperty_OverwritesPreviousHeaders() table.Headers = new[] { "Old1", "Old2" }; table.Headers = new[] { "New1", "New2" }; - var result = table.ToString(); + var result = table.ToTable(); Assert.DoesNotContain("Old1", result); Assert.DoesNotContain("Old2", result); @@ -435,10 +435,10 @@ public void Headers_SetProperty_ClearsCache() { var table = new Table(); table.Headers = new[] { "Header1" }; - var firstResult = table.ToString(); + var firstResult = table.ToTable(); table.Headers = new[] { "Header2" }; - var secondResult = table.ToString(); + var secondResult = table.ToTable(); Assert.Contains("Header1", firstResult); Assert.DoesNotContain("Header1", secondResult); @@ -455,7 +455,7 @@ public void Rows_SetProperty_SetsRowsAndClearsCache() new[] { "Jane", "25" } }; - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("John", result); Assert.Contains("Jane", result); @@ -484,7 +484,7 @@ public void Rows_SetProperty_OverwritesPreviousRows() table.Rows = new List { new[] { "OldRow" } }; table.Rows = new List { new[] { "NewRow" } }; - var result = table.ToString(); + var result = table.ToTable(); Assert.DoesNotContain("OldRow", result); Assert.Contains("NewRow", result); @@ -495,10 +495,10 @@ public void Rows_SetProperty_ClearsCache() { var table = new Table(); table.Rows = new List { new[] { "Row1" } }; - var firstResult = table.ToString(); + var firstResult = table.ToTable(); table.Rows = new List { new[] { "Row2" } }; - var secondResult = table.ToString(); + var secondResult = table.ToTable(); Assert.Contains("Row1", firstResult); Assert.DoesNotContain("Row1", secondResult); @@ -512,7 +512,7 @@ public void Rows_SetNull_CreatesEmptyList() table.AddRow("InitialRow"); table.Rows = null; - var result = table.ToString(); + var result = table.ToTable(); Assert.Empty(result); Assert.NotNull(table.Rows); @@ -529,7 +529,7 @@ public void AddRows_AddsMultipleRows() new[] { "Row3Col1", "Row3Col2" } ); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Row1Col1", result); Assert.Contains("Row2Col1", result); @@ -546,7 +546,7 @@ public void AddRows_AppendsToExistingRows() new[] { "NewRow2" } ); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("ExistingRow", result); Assert.Contains("NewRow1", result); @@ -572,7 +572,7 @@ public void AddRows_WithNull_DoesNotThrow() var exception = Record.Exception(() => table.AddRows(null)); Assert.Null(exception); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("ExistingRow", result); } @@ -581,10 +581,10 @@ public void AddRows_ClearsCache() { var table = new Table(); table.AddRow("InitialRow"); - var firstResult = table.ToString(); + var firstResult = table.ToTable(); table.AddRows(new[] { "NewRow" }); - var secondResult = table.ToString(); + var secondResult = table.ToTable(); Assert.DoesNotContain("NewRow", firstResult); Assert.Contains("NewRow", secondResult); @@ -598,7 +598,7 @@ public void AddRows_ChainedWithOtherMethods() .AddRows(new[] { "R1C1", "R1C2" }, new[] { "R2C1", "R2C2" }) .AddRow("R3C1", "R3C2"); - var result = table.ToString(); + var result = table.ToTable(); Assert.Contains("Col1", result); Assert.Contains("R1C1", result); From f5cae2df5a852be3acbbfa99d6cbf9af1d8ba0d8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Dec 2025 12:28:11 +0000 Subject: [PATCH 04/10] Allow empty rows in AddRows method - remove ?.Any() check Co-authored-by: BrunoVT1992 <8803153+BrunoVT1992@users.noreply.github.com> --- ConsoleTable.Text/Table.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ConsoleTable.Text/Table.cs b/ConsoleTable.Text/Table.cs index 5a87130..91cf972 100644 --- a/ConsoleTable.Text/Table.cs +++ b/ConsoleTable.Text/Table.cs @@ -108,7 +108,7 @@ public Table AddRow(params string[] row) /// public Table AddRows(params string[][] rows) { - if (rows?.Any() == true) + if (rows != null) { if (_rows == null) _rows = new List(); From 5286a5d34527850029e8e523c2e4aa8bda6e49b2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Dec 2025 12:32:19 +0000 Subject: [PATCH 05/10] Add null check in AddRow method and add simple ToString unit test Co-authored-by: BrunoVT1992 <8803153+BrunoVT1992@users.noreply.github.com> --- ConsoleTable.Text/Table.cs | 2 ++ Tests/ConsoleTable.Text.Tests/TableTests.cs | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/ConsoleTable.Text/Table.cs b/ConsoleTable.Text/Table.cs index 91cf972..ecdf8a9 100644 --- a/ConsoleTable.Text/Table.cs +++ b/ConsoleTable.Text/Table.cs @@ -98,6 +98,8 @@ public Table SetHeaders(params string[] headers) /// public Table AddRow(params string[] row) { + if (_rows == null) + _rows = new List(); _rows.Add(row); ClearCache(); return this; diff --git a/Tests/ConsoleTable.Text.Tests/TableTests.cs b/Tests/ConsoleTable.Text.Tests/TableTests.cs index c66909b..a7ddd08 100644 --- a/Tests/ConsoleTable.Text.Tests/TableTests.cs +++ b/Tests/ConsoleTable.Text.Tests/TableTests.cs @@ -605,4 +605,19 @@ public void AddRows_ChainedWithOtherMethods() Assert.Contains("R2C1", result); Assert.Contains("R3C1", result); } + + [Fact] + public void ToString_ReturnsFormattedTable() + { + var table = new Table(); + table.SetHeaders("Name", "Age"); + table.AddRow("John", "30"); + + var result = table.ToString(); + + Assert.Contains("Name", result); + Assert.Contains("Age", result); + Assert.Contains("John", result); + Assert.Contains("30", result); + } } From 3a888dde39b8a554795a0a2df581af604b2ac491 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Dec 2025 16:46:46 +0000 Subject: [PATCH 06/10] Rename unit tests to match the functions being tested (ToString_ -> ToTable_) Co-authored-by: BrunoVT1992 <8803153+BrunoVT1992@users.noreply.github.com> --- Tests/ConsoleTable.Text.Tests/TableTests.cs | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Tests/ConsoleTable.Text.Tests/TableTests.cs b/Tests/ConsoleTable.Text.Tests/TableTests.cs index a7ddd08..d33588d 100644 --- a/Tests/ConsoleTable.Text.Tests/TableTests.cs +++ b/Tests/ConsoleTable.Text.Tests/TableTests.cs @@ -5,7 +5,7 @@ namespace ConsoleTable.Text.Tests; public class TableTests { [Fact] - public void ToString_EmptyTable_ReturnsEmptyString() + public void ToTable_EmptyTable_ReturnsEmptyString() { var table = new Table(); @@ -15,7 +15,7 @@ public void ToString_EmptyTable_ReturnsEmptyString() } [Fact] - public void ToString_WithHeadersOnly_ReturnsFormattedTable() + public void ToTable_WithHeadersOnly_ReturnsFormattedTable() { var table = new Table(); table.SetHeaders("Name", "Age"); @@ -27,7 +27,7 @@ public void ToString_WithHeadersOnly_ReturnsFormattedTable() } [Fact] - public void ToString_WithRowsOnly_ReturnsFormattedTable() + public void ToTable_WithRowsOnly_ReturnsFormattedTable() { var table = new Table(); table.AddRow("John", "30"); @@ -42,7 +42,7 @@ public void ToString_WithRowsOnly_ReturnsFormattedTable() } [Fact] - public void ToString_WithHeadersAndRows_ReturnsFormattedTable() + public void ToTable_WithHeadersAndRows_ReturnsFormattedTable() { var table = new Table(); table.SetHeaders("Name", "Age"); @@ -199,7 +199,7 @@ public void RowTextAlignRight_CanBeSet() } [Fact] - public void ToString_WithSingleColumn_ReturnsProperCorners() + public void ToTable_WithSingleColumn_ReturnsProperCorners() { var table = new Table(); table.SetHeaders("Single"); @@ -214,7 +214,7 @@ public void ToString_WithSingleColumn_ReturnsProperCorners() } [Fact] - public void ToString_MoreHeadersThanRowColumns_HandlesCorrectly() + public void ToTable_MoreHeadersThanRowColumns_HandlesCorrectly() { var table = new Table(); table.SetHeaders("Name", "Date", "Number", "Id"); @@ -234,7 +234,7 @@ public void ToString_MoreHeadersThanRowColumns_HandlesCorrectly() } [Fact] - public void ToString_LessHeadersThanRowColumns_HandlesCorrectly() + public void ToTable_LessHeadersThanRowColumns_HandlesCorrectly() { var table = new Table(); table.SetHeaders("Name"); @@ -252,7 +252,7 @@ public void ToString_LessHeadersThanRowColumns_HandlesCorrectly() } [Fact] - public void ToString_VaryingRowWidths_HandlesCorrectly() + public void ToTable_VaryingRowWidths_HandlesCorrectly() { var table = new Table(); table.AddRow("short"); @@ -297,7 +297,7 @@ public void AddRow_MultipleTimes_AddsAllRows() } [Fact] - public void ToString_ContainsTableBorderCharacters() + public void ToTable_ContainsTableBorderCharacters() { var table = new Table(); table.SetHeaders("Header"); @@ -313,7 +313,7 @@ public void ToString_ContainsTableBorderCharacters() } [Fact] - public void ToString_MultipleColumns_ContainsMiddleJoint() + public void ToTable_MultipleColumns_ContainsMiddleJoint() { var table = new Table(); table.SetHeaders("Col1", "Col2"); @@ -325,7 +325,7 @@ public void ToString_MultipleColumns_ContainsMiddleJoint() } [Fact] - public void ToString_SingleRowSingleColumn_ReturnsValidTable() + public void ToTable_SingleRowSingleColumn_ReturnsValidTable() { var table = new Table(); table.AddRow("X"); @@ -340,7 +340,7 @@ public void ToString_SingleRowSingleColumn_ReturnsValidTable() } [Fact] - public void ToString_EmptyStringValues_HandlesCorrectly() + public void ToTable_EmptyStringValues_HandlesCorrectly() { var table = new Table(); table.SetHeaders("Name", "Value"); From c8ad6583c1e2da351f586336c403961a65d25064 Mon Sep 17 00:00:00 2001 From: Bruno Van Thournout <> Date: Sun, 7 Dec 2025 19:59:34 +0100 Subject: [PATCH 07/10] Fix code structure --- ConsoleTable.Text.Examples/Program.cs | 38 ++++++++++++++++-- ConsoleTable.Text/ConsoleTable.Text.csproj | 2 +- ConsoleTable.Text/Table.cs | 45 ++++++++++++++-------- README.md | 30 +++++++++++---- 4 files changed, 85 insertions(+), 30 deletions(-) diff --git a/ConsoleTable.Text.Examples/Program.cs b/ConsoleTable.Text.Examples/Program.cs index 92da2fa..9fb74f1 100644 --- a/ConsoleTable.Text.Examples/Program.cs +++ b/ConsoleTable.Text.Examples/Program.cs @@ -6,6 +6,8 @@ static void Main(string[] args) { WriteDefaultTable(); + WriteDefaultTableWithProperties(); + WriteTableWithStyling(true, true, 10); WriteTableWithStyling(false, true, 10); @@ -35,8 +37,34 @@ private static void WriteDefaultTable() var table = new Table(); table.SetHeaders("Name", "Age", "City"); table.AddRow("Alice Cooper", "30", "New York"); - table.AddRow("Bob", "25", "Los Angeles"); - table.AddRow("Charlie Brown", "47", "Chicago"); + + var extraRows = new string[][] + { + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } + }; + + table.AddRows(extraRows); + + Console.WriteLine(table.ToTable()); + Console.WriteLine(); + } + + private static void WriteDefaultTableWithProperties() + { + Console.WriteLine(); + Console.WriteLine("Default table with properties instead of methods:"); + + var table = new Table + { + Headers = new string[] { "Name", "Age", "City" }, + Rows = new List + { + new string[] { "Alice Cooper", "30", "New York" }, + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } + } + }; Console.WriteLine(table.ToTable()); Console.WriteLine(); @@ -154,8 +182,10 @@ private static void WriteTableFluent() var tableString = new Table() .SetHeaders("Name", "Age", "City") .AddRow("Alice Cooper", "30", "New York") - .AddRow("Bob", "25", "Los Angeles") - .AddRow("Charlie Brown", "47", "Chicago") + .AddRows( + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } + ) .ToTable(); Console.WriteLine(tableString); diff --git a/ConsoleTable.Text/ConsoleTable.Text.csproj b/ConsoleTable.Text/ConsoleTable.Text.csproj index 952c862..640f4f7 100644 --- a/ConsoleTable.Text/ConsoleTable.Text.csproj +++ b/ConsoleTable.Text/ConsoleTable.Text.csproj @@ -5,7 +5,7 @@ ConsoleTable.Text - 1.0.1 + 1.0.2 Bruno Van Thournout A library for creating a formatted string tables with customizable headers, rows, and alignment options. https://github.com/BrunoVT1992/ConsoleTable diff --git a/ConsoleTable.Text/Table.cs b/ConsoleTable.Text/Table.cs index ecdf8a9..4db99d4 100644 --- a/ConsoleTable.Text/Table.cs +++ b/ConsoleTable.Text/Table.cs @@ -7,7 +7,9 @@ namespace ConsoleTable.Text { public class Table { - private string[] _headers; + private string _tableCache = null; + + private string[] _headers = Array.Empty(); /// /// Gets or sets the headers of the table. This is a single optional top row. /// @@ -16,7 +18,7 @@ public string[] Headers get => _headers; set { - _headers = value; + _headers = value ?? Array.Empty(); ClearCache(); } } @@ -35,8 +37,6 @@ public List Rows } } - private string _tableCache = null; - private int _padding = 1; /// /// Gets or sets the amount of padding in spaces left and right of the rows cell content. Default is 1 @@ -98,9 +98,10 @@ public Table SetHeaders(params string[] headers) /// public Table AddRow(params string[] row) { - if (_rows == null) - _rows = new List(); - _rows.Add(row); + if (Rows == null) + Rows = new List(); + + Rows.Add(row); ClearCache(); return this; } @@ -112,11 +113,13 @@ public Table AddRows(params string[][] rows) { if (rows != null) { - if (_rows == null) - _rows = new List(); - _rows.AddRange(rows); + if (Rows == null) + Rows = new List(); + + Rows.AddRange(rows); ClearCache(); } + return this; } @@ -125,8 +128,16 @@ public Table AddRows(params string[][] rows) /// public Table ClearRows() { - _rows.Clear(); - ClearCache(); + if (Rows == null) + { + Rows = new List(); + } + else + { + Rows.Clear(); + ClearCache(); + } + return this; } @@ -298,18 +309,18 @@ public string ToTable() var table = new List(); var firstRowIsHeader = false; - if (_headers?.Any() == true) + if (Headers?.Any() == true) { - table.Add(_headers); + table.Add(Headers); firstRowIsHeader = true; } - if (_rows?.Any() == true) + if (Rows?.Any() == true) { - foreach (var row in _rows) + foreach (var row in Rows) { //Weird behaviour with empty rows - if ((row == null || row.Length <= 0) && _headers?.Length > 0) + if ((row == null || row.Length <= 0) && Headers?.Length > 0) table.AddRange(new string[][] { new string[] { " " } }); else table.Add(row); diff --git a/README.md b/README.md index a50b8e6..41225dc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ConsoleTable +# ConsoleTable.Text A lightweight .NET library for creating beautifully formatted console tables with customizable headers, rows, padding, and text alignment. @@ -45,12 +45,18 @@ var table = new Table(); table.SetHeaders("Name", "Age", "City"); // Add rows -table.AddRow("Alice", "30", "New York"); -table.AddRow("Bob", "25", "Los Angeles"); -table.AddRow("Charlie", "35", "Chicago"); +table.AddRow("Alice Cooper", "30", "New York"); + +var extraRows = new string[][] +{ + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } +}; + +table.AddRows(extraRows); // Display the table -Console.WriteLine(table.ToString()); +Console.WriteLine(table.ToTable()); ``` Output: @@ -72,6 +78,8 @@ Output: | Property | Type | Default | Description | |----------|------|---------|-------------| +| `Headers` | `string[]` | `Array.Empty()` | The table headers. Headers are not required. | +| `Rows` | `List` | `new List()` | All the data rows for the table. Rows are not required. | | `Padding` | `int` | `1` | The number of spaces on each side of cell content | | `HeaderTextAlignmentRight` | `bool` | `false` | When `true`, header text is right-aligned otherwise left aligned | | `RowTextAlignmentRight` | `bool` | `false` | When `true`, row text is right-aligned otherwise left aligned | @@ -82,6 +90,7 @@ Output: |--------|-------------| | `SetHeaders(params string[] headers)` | Sets the table headers. Calling this again will overwrite previous headers. Headers are not required. | | `AddRow(params string[] row)` | Adds a data row to the table. Rows are not required. | +| `AddRows(params string[][] rows)` | Adds multiple data rows to the table. Rows are not required. | | `ClearRows()` | Removes all data rows from the table (headers are preserved). | | `Clear()` | Clear all the headers and rows from the table. | | `ToTable() / ToString()` | Returns the formatted table as a string. | @@ -146,6 +155,7 @@ Output: └───────────────┴─────┴─────────────┘ ``` + ### Table with inconsistent columns across rows ```csharp @@ -169,7 +179,7 @@ table.AddRow("Nathalie", "29", "Paris", "France", "Europe", "Earth", "Solar Syst table.AddRow("Mathias", "37", "Oslo", "Norway", "Europe", "Earth", "Solar System"); table.AddRow("Kenny", "55", "Tokyo"); -Console.WriteLine(table.ToString()); +Console.WriteLine(table.ToTable()); ``` Output: @@ -205,6 +215,7 @@ Output: └──────────┴─────┴──────────┘ ``` + ### Write a Table Fluent ```csharp @@ -213,8 +224,10 @@ using ConsoleTable.Text; var tableString = new Table() .SetHeaders("Name", "Age", "City") .AddRow("Alice Cooper", "30", "New York") - .AddRow("Bob", "25", "Los Angeles") - .AddRow("Charlie Brown", "47", "Chicago") + .AddRows( + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } + ) .ToTable(); Console.WriteLine(tableString); @@ -233,6 +246,7 @@ Output: └───────────────┴─────┴─────────────┘ ``` + ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. \ No newline at end of file From 7e212d1f6434de4efabb9f9e38e34bd1926fe049 Mon Sep 17 00:00:00 2001 From: Bruno Van Thournout <> Date: Sun, 7 Dec 2025 20:04:32 +0100 Subject: [PATCH 08/10] Add version text --- ChangeLogs/1.0.2-ChangeLog.md | 14 ++++++++++++++ ConsoleTable.slnx | 1 + 2 files changed, 15 insertions(+) create mode 100644 ChangeLogs/1.0.2-ChangeLog.md diff --git a/ChangeLogs/1.0.2-ChangeLog.md b/ChangeLogs/1.0.2-ChangeLog.md new file mode 100644 index 0000000..d68c370 --- /dev/null +++ b/ChangeLogs/1.0.2-ChangeLog.md @@ -0,0 +1,14 @@ +# V1.0.2 + +## New Properties + +| Property | Type | Default | Description | +|----------|------|---------|-------------| +| `Headers` | `string[]` | `Array.Empty()` | The table headers. Headers are not required. | +| `Rows` | `List` | `new List()` | All the data rows for the table. Rows are not required. | + +## New Method + +| Method | Description | +|--------|-------------| +| `AddRows(params string[][] rows)` | Adds multiple data rows to the table. Rows are not required. | diff --git a/ConsoleTable.slnx b/ConsoleTable.slnx index 5a0d0db..1328dc0 100644 --- a/ConsoleTable.slnx +++ b/ConsoleTable.slnx @@ -6,6 +6,7 @@ + From 095082096aa57e5fc1c7f04782f3c9b6b37b8e4f Mon Sep 17 00:00:00 2001 From: Bruno Van Thournout <> Date: Sun, 7 Dec 2025 20:11:14 +0100 Subject: [PATCH 09/10] Fix examples --- ConsoleTable.Text.Examples/Program.cs | 23 ++++++++++++----------- README.md | 22 ++++++++++++---------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/ConsoleTable.Text.Examples/Program.cs b/ConsoleTable.Text.Examples/Program.cs index 9fb74f1..d0771ce 100644 --- a/ConsoleTable.Text.Examples/Program.cs +++ b/ConsoleTable.Text.Examples/Program.cs @@ -37,14 +37,11 @@ private static void WriteDefaultTable() var table = new Table(); table.SetHeaders("Name", "Age", "City"); table.AddRow("Alice Cooper", "30", "New York"); - - var extraRows = new string[][] + table.AddRows(new string[][] { new string[] { "Bob", "25", "Los Angeles" }, new string[] { "Charlie Brown", "47", "Chicago" } - }; - - table.AddRows(extraRows); + }); Console.WriteLine(table.ToTable()); Console.WriteLine(); @@ -93,9 +90,11 @@ private static void WriteTableMoreHeaders() table.SetHeaders("Name", "Age", "City", "Country"); - table.AddRow("Alice Cooper", "30"); - table.AddRow("Bob", "25"); - table.AddRow("Charlie Brown", "47"); + table.AddRows( + new string[] { "Alice Cooper", "30" }, + new string[] { "Bob", "25" }, + new string[] { "Charlie Brown", "47" } + ); Console.WriteLine(table.ToString()); Console.WriteLine(); @@ -110,9 +109,11 @@ private static void WriteTableLessHeaders() table.SetHeaders("Name"); - table.AddRow("Alice Cooper", "30", "New York"); - table.AddRow("Bob", "25", "Los Angeles"); - table.AddRow("Charlie Brown", "47", "Chicago"); + table.AddRows( + new string[] { "Alice Cooper", "30", "New York" }, + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } + ); Console.WriteLine(table.ToString()); Console.WriteLine(); diff --git a/README.md b/README.md index 41225dc..58442af 100644 --- a/README.md +++ b/README.md @@ -47,13 +47,11 @@ table.SetHeaders("Name", "Age", "City"); // Add rows table.AddRow("Alice Cooper", "30", "New York"); -var extraRows = new string[][] +table.AddRows(new string[][] { new string[] { "Bob", "25", "Los Angeles" }, new string[] { "Charlie Brown", "47", "Chicago" } -}; - -table.AddRows(extraRows); +}); // Display the table Console.WriteLine(table.ToTable()); @@ -106,9 +104,11 @@ var table = new Table { Padding = 10 }; table.SetHeaders("Name", "Age", "City"); -table.AddRow("Alice", "30", "New York"); -table.AddRow("Bob", "25", "Los Angeles"); -table.AddRow("Charlie", "47", "Chicago"); +table.AddRows( + new string[] { "Alice", "30", "New York" }, + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie", "47", "Chicago" } +); Console.WriteLine(table.ToTable()); ``` @@ -135,9 +135,11 @@ var table = new Table { HeaderTextAlignmentRight = true, RowTextAlignmentRight = table.SetHeaders("Name", "Age", "City"); -table.AddRow("Alice Cooper", "30", "New York"); -table.AddRow("Bob", "25", "Los Angeles"); -table.AddRow("Charlie Brown", "47", "Chicago"); +table.AddRows( + new string[] { "Alice Cooper", "30", "New York" }, + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } +); Console.WriteLine(table.ToTable()); ``` From 1af1de40c74eaf607dadc1584e2b0e0b97e78cc5 Mon Sep 17 00:00:00 2001 From: Bruno Van Thournout <> Date: Sun, 7 Dec 2025 20:15:43 +0100 Subject: [PATCH 10/10] Fix unit tests --- Tests/ConsoleTable.Text.Tests/TableTests.cs | 61 ++------------------- 1 file changed, 5 insertions(+), 56 deletions(-) diff --git a/Tests/ConsoleTable.Text.Tests/TableTests.cs b/Tests/ConsoleTable.Text.Tests/TableTests.cs index d33588d..e9880ea 100644 --- a/Tests/ConsoleTable.Text.Tests/TableTests.cs +++ b/Tests/ConsoleTable.Text.Tests/TableTests.cs @@ -393,7 +393,7 @@ public void RowTextAlignRight_True_AlignsToDifferentPosition() } [Fact] - public void Headers_SetProperty_SetsHeadersAndClearsCache() + public void Headers_SetHeadersProperty() { var table = new Table(); table.Headers = new[] { "Name", "Age" }; @@ -404,17 +404,6 @@ public void Headers_SetProperty_SetsHeadersAndClearsCache() Assert.Contains("Age", result); } - [Fact] - public void Headers_GetProperty_ReturnsHeaders() - { - var table = new Table(); - table.SetHeaders("Name", "Age"); - - var headers = table.Headers; - - Assert.Equal(new[] { "Name", "Age" }, headers); - } - [Fact] public void Headers_SetProperty_OverwritesPreviousHeaders() { @@ -431,7 +420,7 @@ public void Headers_SetProperty_OverwritesPreviousHeaders() } [Fact] - public void Headers_SetProperty_ClearsCache() + public void Headers_SetHeadersProperty_ClearsCache() { var table = new Table(); table.Headers = new[] { "Header1" }; @@ -446,7 +435,7 @@ public void Headers_SetProperty_ClearsCache() } [Fact] - public void Rows_SetProperty_SetsRowsAndClearsCache() + public void Rows_SetRowsProperty() { var table = new Table(); table.Rows = new List @@ -464,21 +453,7 @@ public void Rows_SetProperty_SetsRowsAndClearsCache() } [Fact] - public void Rows_GetProperty_ReturnsRows() - { - var table = new Table(); - table.AddRow("John", "30"); - table.AddRow("Jane", "25"); - - var rows = table.Rows; - - Assert.Equal(2, rows.Count); - Assert.Equal(new[] { "John", "30" }, rows[0]); - Assert.Equal(new[] { "Jane", "25" }, rows[1]); - } - - [Fact] - public void Rows_SetProperty_OverwritesPreviousRows() + public void Rows_SetRowsProperty_OverwritesPreviousRows() { var table = new Table(); table.Rows = new List { new[] { "OldRow" } }; @@ -491,7 +466,7 @@ public void Rows_SetProperty_OverwritesPreviousRows() } [Fact] - public void Rows_SetProperty_ClearsCache() + public void Rows_SetRowsProperty_ClearsCache() { var table = new Table(); table.Rows = new List { new[] { "Row1" } }; @@ -553,16 +528,6 @@ public void AddRows_AppendsToExistingRows() Assert.Contains("NewRow2", result); } - [Fact] - public void AddRows_ReturnsTableInstance() - { - var table = new Table(); - - var result = table.AddRows(new[] { "Row1" }, new[] { "Row2" }); - - Assert.Same(table, result); - } - [Fact] public void AddRows_WithNull_DoesNotThrow() { @@ -590,22 +555,6 @@ public void AddRows_ClearsCache() Assert.Contains("NewRow", secondResult); } - [Fact] - public void AddRows_ChainedWithOtherMethods() - { - var table = new Table() - .SetHeaders("Col1", "Col2") - .AddRows(new[] { "R1C1", "R1C2" }, new[] { "R2C1", "R2C2" }) - .AddRow("R3C1", "R3C2"); - - var result = table.ToTable(); - - Assert.Contains("Col1", result); - Assert.Contains("R1C1", result); - Assert.Contains("R2C1", result); - Assert.Contains("R3C1", result); - } - [Fact] public void ToString_ReturnsFormattedTable() {