Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work done to allow user to update table cell. #546

Merged
merged 2 commits into from Sep 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/Spectre.Console/Extensions/TableExtensions.cs
Expand Up @@ -189,6 +189,56 @@ public static Table InsertRow(this Table table, int index, IEnumerable<IRenderab
return table;
}

/// <summary>
/// Updates a tables cell.
/// </summary>
/// <param name="table">The table to update.</param>
/// <param name="rowIndex">The index of row to update.</param>
/// <param name="columnIndex">The index of column to update.</param>
/// <param name="cellData">New cell data.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static Table UpdateCell(this Table table, int rowIndex, int columnIndex, IRenderable cellData)
{
if (table is null)
{
throw new ArgumentNullException(nameof(table));
}

if (cellData is null)
{
throw new ArgumentNullException(nameof(cellData));
}

table.Rows.Update(rowIndex, columnIndex, cellData);

return table;
}

/// <summary>
/// Updates a tables cell.
/// </summary>
/// <param name="table">The table to update.</param>
/// <param name="rowIndex">The index of row to update.</param>
/// <param name="columnIndex">The index of column to update.</param>
/// <param name="cellData">New cell data.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static Table UpdateCell(this Table table, int rowIndex, int columnIndex, string cellData)
{
if (table is null)
{
throw new ArgumentNullException(nameof(table));
}

if (cellData is null)
{
throw new ArgumentNullException(nameof(cellData));
}

table.Rows.Update(rowIndex, columnIndex, new Markup(cellData));

return table;
}

/// <summary>
/// Inserts a row in the table at the specified index.
/// </summary>
Expand Down
49 changes: 49 additions & 0 deletions src/Spectre.Console/Widgets/Table/TableRowCollection.cs
Expand Up @@ -89,6 +89,55 @@ public int Insert(int index, IEnumerable<IRenderable> columns)
}
}

/// <summary>
/// Update a table cell at the specified index.
/// </summary>
/// <param name="row">Index of cell row.</param>
/// <param name="column">index of cell column.</param>
/// <param name="cellData">The new cells details.</param>
public void Update(int row, int column, IRenderable cellData)
{
if (cellData is null)
{
throw new ArgumentNullException(nameof(cellData));
}

lock (_lock)
{
if (row < 0)
{
throw new IndexOutOfRangeException("Table row index cannot be negative.");
}
else if (row >= _list.Count)
{
throw new IndexOutOfRangeException("Table row index cannot exceed the number of rows in the table.");
}

var tableRow = _list.ElementAtOrDefault(row);

var currentRenderables = tableRow.ToList();

if (column < 0)
{
throw new IndexOutOfRangeException("Table column index cannot be negative.");
}
else if (column >= currentRenderables.Count)
{
throw new IndexOutOfRangeException("Table column index cannot exceed the number of rows in the table.");
}

currentRenderables.RemoveAt(column);

currentRenderables.Insert(column, cellData);

var newTableRow = new TableRow(currentRenderables);

_list.RemoveAt(row);

_list.Insert(row, newTableRow);
}
}

/// <summary>
/// Removes a row at the specified index.
/// </summary>
Expand Down
@@ -0,0 +1,7 @@
┌───────────┬───────────┬───────────┐
│ Column #1 │ Column #2 │ Column #3 │
├───────────┼───────────┼───────────┤
│ 1 │ │ │
│ 2 │ │ │
│ 3 │ 4 │ 5 │
└───────────┴───────────┴───────────┘
@@ -0,0 +1,7 @@
┌───────────┬───────────┬───────────┐
│ Column #1 │ Column #2 │ Column #3 │
├───────────┼───────────┼───────────┤
│ 1 │ │ │
│ 2 │ │ │
│ 3 │ 4 │ 5 │
└───────────┴───────────┴───────────┘
@@ -0,0 +1,7 @@
┌───────────┬───────────┬───────────┐
│ Column #1 │ Column #2 │ Column #3 │
├───────────┼───────────┼───────────┤
│ 1 │ │ │
│ 2 │ │ │
│ 3 │ 4 │ 5 │
└───────────┴───────────┴───────────┘
Expand Up @@ -222,5 +222,145 @@ public void Should_Remove_All_Rows()
result.ShouldBe(0);
}
}

[UsesVerify]
public sealed class TheUpdateMethod
{
[Fact]
public Task Should_Update_Row_With_String()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn("Column #1");
table.AddColumn("Column #2");
table.AddColumn("Column #3");
table.Rows.Add(new[] { new Text("1") });
table.Rows.Add(new[] { new Text("2") });
table.Rows.Add(new[] { new Text("3"), new Text("4"), new Text("8") });

table.UpdateCell(2, 2, "5");

// When
console.Write(table);

// Then
return Verifier.Verify(console.Output);
}

[Fact]
public Task Should_Update_Row_With_Renderable()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn("Column #1");
table.AddColumn("Column #2");
table.AddColumn("Column #3");
table.Rows.Add(new[] { new Text("1") });
table.Rows.Add(new[] { new Text("2") });
table.Rows.Add(new[] { new Text("3"), new Text("4"), new Text("8") });

table.UpdateCell(2, 2, new Markup("5"));

// When
console.Write(table);

// Then
return Verifier.Verify(console.Output);
}

[Fact]
public void Should_Throw_If_Index_Is_Larger_Than_Number_Of_Rows()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn("Column #1");
table.AddColumn("Column #2");
table.AddColumn("Column #3");
table.Rows.Add(new[] { new Text("1") });
table.Rows.Add(new[] { new Text("2") });
table.Rows.Add(new[] { new Text("3"), new Text("4"), new Text("8") });
table.UpdateCell(2, 2, "5");


// When
var result = Record.Exception(() => table.UpdateCell(5, 2, "5"));

// Then
result.ShouldBeOfType<IndexOutOfRangeException>()
.Message.ShouldBe("Table row index cannot exceed the number of rows in the table.");
}

[Fact]
public void Should_Throw_If_Index_Is_Larger_Than_Number_Of_Columns()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn("Column #1");
table.AddColumn("Column #2");
table.AddColumn("Column #3");
table.Rows.Add(new[] { new Text("1") });
table.Rows.Add(new[] { new Text("2") });
table.Rows.Add(new[] { new Text("3"), new Text("4"), new Text("8") });
table.UpdateCell(2, 2, "5");


// When
var result = Record.Exception(() => table.UpdateCell(2, 5, "5"));

// Then
result.ShouldBeOfType<IndexOutOfRangeException>()
.Message.ShouldBe("Table column index cannot exceed the number of rows in the table.");
}

[Fact]
public void Should_Throw_If_Index_Row_Is_Negative()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn("Column #1");
table.AddColumn("Column #2");
table.AddColumn("Column #3");
table.Rows.Add(new[] { new Text("1") });
table.Rows.Add(new[] { new Text("2") });
table.Rows.Add(new[] { new Text("3"), new Text("4"), new Text("8") });
table.UpdateCell(2, 2, "5");


// When
var result = Record.Exception(() => table.UpdateCell(-1, 2, "5"));

// Then
result.ShouldBeOfType<IndexOutOfRangeException>()
.Message.ShouldBe("Table row index cannot be negative.");
}

[Fact]
public void Should_Throw_If_Index_Column_Is_Negative()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn("Column #1");
table.AddColumn("Column #2");
table.AddColumn("Column #3");
table.Rows.Add(new[] { new Text("1") });
table.Rows.Add(new[] { new Text("2") });
table.Rows.Add(new[] { new Text("3"), new Text("4"), new Text("8") });
table.UpdateCell(2, 2, "5");


// When
var result = Record.Exception(() => table.UpdateCell(2, -1, "5"));

// Then
result.ShouldBeOfType<IndexOutOfRangeException>()
.Message.ShouldBe("Table column index cannot be negative.");
}
}
}
}