Fixes issue with Panel not applying overflow to children

Add tests for widget content overflow scenarios in Panel, Table, and Grid widgets.
This commit is contained in:
Phil Scott
2025-10-31 10:53:57 -04:00
committed by Patrik Svensson
parent 010beffae0
commit 1ec7b8ae8f
21 changed files with 457 additions and 6 deletions

View File

@@ -83,12 +83,13 @@ public sealed class Panel : Renderable, IHasBoxBorder, IHasBorder, IExpandable,
if (Width != null)
{
var width = Width.Value - edgeWidth;
if (width > childWidth.Max)
{
childWidth = new Measurement(
childWidth.Min,
width);
}
// If Width is specified, constrain or expand the measurement
// to exactly the specified width (clamped by maxWidth)
var constrainedWidth = Math.Min(width, maxWidth - edgeWidth);
childWidth = new Measurement(
Math.Min(childWidth.Min, constrainedWidth),
constrainedWidth);
}
return new Measurement(

View File

@@ -0,0 +1,3 @@
foo Short text
pneumonoultramicr…
bar

View File

@@ -0,0 +1,3 @@
foo Short text
pneumonoultrami
bar

View File

@@ -0,0 +1,3 @@
foo Short text
pneumonoultram…
bar

View File

@@ -0,0 +1,5 @@
foo Short text
pneumonoultrami
croscopicsilico
volcanoconiosis
bar

View File

@@ -0,0 +1,3 @@
foo Short text
pneumonoultram…
bar

View File

@@ -0,0 +1,5 @@
┌──────────────────┐
│ foo │
│ pneumonoultrami… │
│ bar qux │
└──────────────────┘

View File

@@ -0,0 +1,7 @@
┌───────────────────────┐
│ ┌─────────────┐ │
│ │ foo │ │
│ │ pneumonoult │ │
│ │ bar qux │ │
│ └─────────────┘ │
└───────────────────────┘

View File

@@ -0,0 +1,5 @@
┌──────────────────┐
│ foo │
│ pneumonoultramic │
│ bar qux │
└──────────────────┘

View File

@@ -0,0 +1,5 @@
┌──────────────────┐
│ foo │
│ pneumonoultrami… │
│ bar qux │
└──────────────────┘

View File

@@ -0,0 +1,7 @@
┌──────────────────┐
│ foo │
│ pneumonoultramic │
│ roscopicsilicovo │
│ lcanoconiosis │
│ bar qux │
└──────────────────┘

View File

@@ -0,0 +1,5 @@
┌───────────────────────┐
│ foo │
│ pneumonoultramicro… │
│ bar qux │
└───────────────────────┘

View File

@@ -0,0 +1,7 @@
┌────────────────────┬─────────────────┐
│ Column1 │ Column2 │
├────────────────────┼─────────────────┤
│ foo │ Short text │
│ pneumonoultramicr… │ │
│ bar │ │
└────────────────────┴─────────────────┘

View File

@@ -0,0 +1,7 @@
┌─────────────────┬─────────────────┐
│ Column1 │ Column2 │
├─────────────────┼─────────────────┤
│ foo │ Short text │
│ pneumonoultrami │ │
│ bar │ │
└─────────────────┴─────────────────┘

View File

@@ -0,0 +1,7 @@
┌─────────────────┬─────────────────┐
│ Column1 │ Column2 │
├─────────────────┼─────────────────┤
│ foo │ Short text │
│ pneumonoultram… │ │
│ bar │ │
└─────────────────┴─────────────────┘

View File

@@ -0,0 +1,9 @@
┌─────────────────┬─────────────────┐
│ Column1 │ Column2 │
├─────────────────┼─────────────────┤
│ foo │ Short text │
│ pneumonoultrami │ │
│ croscopicsilico │ │
│ volcanoconiosis │ │
│ bar │ │
└─────────────────┴─────────────────┘

View File

@@ -0,0 +1,11 @@
┌─────────────────┬─────────────────┐
│ Column1 │ Column2 │
├─────────────────┼─────────────────┤
│ foo │ First row │
│ pneumonoultrami │ │
│ bar │ Second row │
│ supercalifragi… │ │
│ qux │ Third row │
│ antidisestablis │ │
│ hmentarianism │ │
└─────────────────┴─────────────────┘

View File

@@ -0,0 +1,7 @@
┌─────────────────┬─────────────────┐
│ Column1 │ Column2 │
├─────────────────┼─────────────────┤
│ foo │ Short text │
│ pneumonoultram… │ │
│ bar │ │
└─────────────────┴─────────────────┘

View File

@@ -192,4 +192,104 @@ public sealed class GridTests
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Cell_Overflow_Crop")]
public Task Should_Respect_Cell_Content_Overflow_Crop()
{
// Given
var console = new TestConsole().Width(40);
var grid = new Grid();
grid.AddColumn(new GridColumn { Width = 15 });
grid.AddColumn(new GridColumn { Width = 15 });
grid.AddRow(
new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar").Overflow(Overflow.Crop),
new Text("Short text"));
// When
console.Write(grid);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Cell_Overflow_Ellipsis")]
public Task Should_Respect_Cell_Content_Overflow_Ellipsis()
{
// Given
var console = new TestConsole().Width(40);
var grid = new Grid();
grid.AddColumn(new GridColumn { Width = 15 });
grid.AddColumn(new GridColumn { Width = 15 });
grid.AddRow(
new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar").Overflow(Overflow.Ellipsis),
new Text("Short text"));
// When
console.Write(grid);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Cell_Overflow_Fold")]
public Task Should_Respect_Cell_Content_Overflow_Fold()
{
// Given
var console = new TestConsole().Width(40);
var grid = new Grid();
grid.AddColumn(new GridColumn { Width = 15 });
grid.AddColumn(new GridColumn { Width = 15 });
grid.AddRow(
new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar").Overflow(Overflow.Fold),
new Text("Short text"));
// When
console.Write(grid);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Cell_Markup_Overflow")]
public Task Should_Respect_Markup_Content_Overflow_In_Cell()
{
// Given
var console = new TestConsole().Width(40);
var grid = new Grid();
grid.AddColumn(new GridColumn { Width = 18 });
grid.AddColumn(new GridColumn { Width = 15 });
grid.AddRow(
new Markup("[yellow]foo[/] [red]pneumonoultramicroscopicsilicovolcanoconiosis[/] [blue]bar[/]").Overflow(Overflow.Ellipsis),
new Markup("[green]Short text[/]"));
// When
console.Write(grid);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Cell_Overflow_With_NoWrap")]
public Task Should_Respect_Cell_Content_Overflow_With_NoWrap_Column()
{
// Given
var console = new TestConsole().Width(40);
var grid = new Grid();
grid.AddColumn(new GridColumn { Width = 15, NoWrap = true });
grid.AddColumn(new GridColumn { Width = 15 });
grid.AddRow(
new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar").Overflow(Overflow.Ellipsis),
new Text("Short text"));
// When
console.Write(grid);
// Then
return Verifier.Verify(console.Output);
}
}

View File

@@ -366,4 +366,129 @@ public sealed class PanelTests
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Text_Overflow_Crop")]
public Task Should_Respect_Text_Overflow_Crop_In_Panel()
{
// Given
var console = new TestConsole();
var text = new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar qux")
.Overflow(Overflow.Crop);
var panel = new Panel(text)
{
Width = 20,
};
// When
console.Write(panel);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Text_Overflow_Ellipsis")]
public Task Should_Respect_Text_Overflow_Ellipsis_In_Panel()
{
// Given
var console = new TestConsole();
var text = new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar qux")
.Overflow(Overflow.Ellipsis);
var panel = new Panel(text)
{
Width = 20,
};
// When
console.Write(panel);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Text_Overflow_Fold")]
public Task Should_Respect_Text_Overflow_Fold_In_Panel()
{
// Given
var console = new TestConsole();
var text = new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar qux")
.Overflow(Overflow.Fold);
var panel = new Panel(text)
{
Width = 20,
};
// When
console.Write(panel);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Markup_Overflow_Ellipsis")]
public Task Should_Respect_Markup_Overflow_Ellipsis_In_Panel()
{
// Given
var console = new TestConsole();
var markup = new Markup("[yellow]foo[/] [red]pneumonoultramicroscopicsilicovolcanoconiosis[/] [blue]bar qux[/]")
.Overflow(Overflow.Ellipsis);
var panel = new Panel(markup)
{
Width = 20,
};
// When
console.Write(panel);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Text_Overflow_With_Padding")]
public Task Should_Respect_Text_Overflow_In_Panel_With_Padding()
{
// Given
var console = new TestConsole();
var text = new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar qux")
.Overflow(Overflow.Ellipsis);
var panel = new Panel(text)
{
Width = 25,
Padding = new Padding(2, 0, 2, 0),
};
// When
console.Write(panel);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Nested_Panel_With_Overflow")]
public Task Should_Respect_Text_Overflow_In_Nested_Panel()
{
// Given
var console = new TestConsole();
var text = new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar qux")
.Overflow(Overflow.Crop);
var innerPanel = new Panel(text)
{
Width = 15,
};
var outerPanel = new Panel(innerPanel)
{
Width = 25,
};
// When
console.Write(outerPanel);
// Then
return Verifier.Verify(console.Output);
}
}

View File

@@ -631,4 +631,130 @@ public sealed class TableTests
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Cell_Overflow_Crop")]
public Task Should_Respect_Cell_Content_Overflow_Crop()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn(new TableColumn("Column1").Width(15));
table.AddColumn(new TableColumn("Column2").Width(15));
table.AddRow(
new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar").Overflow(Overflow.Crop),
new Text("Short text"));
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Cell_Overflow_Ellipsis")]
public Task Should_Respect_Cell_Content_Overflow_Ellipsis()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn(new TableColumn("Column1").Width(15));
table.AddColumn(new TableColumn("Column2").Width(15));
table.AddRow(
new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar").Overflow(Overflow.Ellipsis),
new Text("Short text"));
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Cell_Overflow_Fold")]
public Task Should_Respect_Cell_Content_Overflow_Fold()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn(new TableColumn("Column1").Width(15));
table.AddColumn(new TableColumn("Column2").Width(15));
table.AddRow(
new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar").Overflow(Overflow.Fold),
new Text("Short text"));
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Cell_Markup_Overflow")]
public Task Should_Respect_Markup_Content_Overflow_In_Cell()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn(new TableColumn("Column1").Width(18));
table.AddColumn(new TableColumn("Column2").Width(15));
table.AddRow(
new Markup("[yellow]foo[/] [red]pneumonoultramicroscopicsilicovolcanoconiosis[/] [blue]bar[/]").Overflow(Overflow.Ellipsis),
new Markup("[green]Short text[/]"));
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Cell_Overflow_Multiple_Rows")]
public Task Should_Respect_Cell_Content_Overflow_In_Multiple_Rows()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn(new TableColumn("Column1").Width(15));
table.AddColumn(new TableColumn("Column2").Width(15));
table.AddRow(
new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis").Overflow(Overflow.Crop),
new Text("First row"));
table.AddRow(
new Text("bar supercalifragilisticexpialidocious").Overflow(Overflow.Ellipsis),
new Text("Second row"));
table.AddRow(
new Text("qux antidisestablishmentarianism").Overflow(Overflow.Fold),
new Text("Third row"));
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Cell_Overflow_With_NoWrap")]
public Task Should_Respect_Cell_Content_Overflow_With_NoWrap_Column()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn(new TableColumn("Column1").Width(15).NoWrap());
table.AddColumn(new TableColumn("Column2").Width(15));
table.AddRow(
new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar").Overflow(Overflow.Ellipsis),
new Text("Short text"));
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
}