Clean up Widgets

* Move /Widgets/Live/* to /Live/*
* Move /Widgets/Prompt/* to /Prompts/*
* Move tests and expectations to match the new locations
This commit is contained in:
Patrik Svensson
2021-07-12 09:39:20 +02:00
committed by Phil Scott
parent d532e1011f
commit fa5a1e88ec
114 changed files with 5 additions and 5 deletions

View File

@ -0,0 +1,51 @@
using System.Threading.Tasks;
using Spectre.Console.Testing;
using Spectre.Verify.Extensions;
using VerifyXunit;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
[UsesVerify]
[ExpectationPath("Widgets/BarChart")]
public sealed class BarChartTests
{
[Fact]
[Expectation("Render")]
public async Task Should_Render_Correctly()
{
// Given
var console = new TestConsole();
// When
console.Write(new BarChart()
.Width(60)
.Label("Number of fruits")
.AddItem("Apple", 12)
.AddItem("Orange", 54)
.AddItem("Banana", 33));
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Zero_Value")]
public async Task Should_Render_Correctly_2()
{
// Given
var console = new TestConsole();
// When
console.Write(new BarChart()
.Width(60)
.Label("Number of fruits")
.AddItem("Apple", 0)
.AddItem("Orange", 54)
.AddItem("Banana", 33));
// Then
await Verifier.Verify(console.Output);
}
}
}

View File

@ -0,0 +1,150 @@
using System.Threading.Tasks;
using Spectre.Console.Testing;
using Spectre.Verify.Extensions;
using VerifyXunit;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
[UsesVerify]
[ExpectationPath("Widgets/BreakdownChart")]
public sealed class BreakdownChartTests
{
[Fact]
[Expectation("Default")]
public async Task Should_Render_Correctly()
{
// Given
var console = new TestConsole();
var chart = Fixture.GetChart();
// When
console.Write(chart);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Width")]
public async Task Should_Render_With_Specific_Width()
{
// Given
var console = new TestConsole();
var chart = Fixture.GetChart().Width(60);
// When
console.Write(chart);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("TagFormat")]
public async Task Should_Render_Correctly_With_Specific_Value_Formatter()
{
// Given
var console = new TestConsole();
var chart = Fixture.GetChart()
.Width(60)
.Culture("sv-SE")
.UseValueFormatter((v, c) => string.Format(c, "{0}%", v));
// When
console.Write(chart);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("HideTags")]
public async Task Should_Render_Correctly_Without_Tags()
{
// Given
var console = new TestConsole();
var chart = Fixture.GetChart().Width(60).HideTags();
// When
console.Write(chart);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("HideTagValues")]
public async Task Should_Render_Correctly_Without_Tag_Values()
{
// Given
var console = new TestConsole();
var chart = Fixture.GetChart().Width(60).HideTagValues();
// When
console.Write(chart);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Culture")]
public async Task Should_Render_Correctly_With_Specific_Culture()
{
// Given
var console = new TestConsole();
var chart = Fixture.GetChart().Width(60).Culture("sv-SE");
// When
console.Write(chart);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("FullSize")]
public async Task Should_Render_FullSize_Mode_Correctly()
{
// Given
var console = new TestConsole();
var chart = Fixture.GetChart().Width(60).FullSize();
// When
console.Write(chart);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Ansi")]
public async Task Should_Render_Correct_Ansi()
{
// Given
var console = new TestConsole().EmitAnsiSequences();
var chart = Fixture.GetChart().Width(60).FullSize();
// When
console.Write(chart);
// Then
await Verifier.Verify(console.Output);
}
public static class Fixture
{
public static BreakdownChart GetChart()
{
return new BreakdownChart()
.AddItem("SCSS", 37, Color.Red)
.AddItem("HTML", 28.3, Color.Blue)
.AddItem("C#", 22.6, Color.Green)
.AddItem("JavaScript", 6, Color.Yellow)
.AddItem("Ruby", 6, Color.LightGreen)
.AddItem("Shell", 0.1, Color.Aqua);
}
}
}
}

View File

@ -0,0 +1,108 @@
using System;
using System.Threading.Tasks;
using Spectre.Console.Testing;
using Spectre.Verify.Extensions;
using VerifyXunit;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
[UsesVerify]
[ExpectationPath("Widgets/Calendar")]
public sealed class CalendarTests
{
[Fact]
[Expectation("Render")]
public Task Should_Render_Calendar_Correctly()
{
// Given
var console = new TestConsole();
var calendar = new Calendar(2020, 10)
.AddCalendarEvent(new DateTime(2020, 9, 1))
.AddCalendarEvent(new DateTime(2020, 10, 3))
.AddCalendarEvent(new DateTime(2020, 10, 12));
// When
console.Write(calendar);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Centered")]
public Task Should_Center_Calendar_Correctly()
{
// Given
var console = new TestConsole();
var calendar = new Calendar(2020, 10)
.Centered()
.AddCalendarEvent(new DateTime(2020, 9, 1))
.AddCalendarEvent(new DateTime(2020, 10, 3))
.AddCalendarEvent(new DateTime(2020, 10, 12));
// When
console.Write(calendar);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("LeftAligned")]
public Task Should_Left_Align_Calendar_Correctly()
{
// Given
var console = new TestConsole();
var calendar = new Calendar(2020, 10)
.LeftAligned()
.AddCalendarEvent(new DateTime(2020, 9, 1))
.AddCalendarEvent(new DateTime(2020, 10, 3))
.AddCalendarEvent(new DateTime(2020, 10, 12));
// When
console.Write(calendar);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("RightAligned")]
public Task Should_Right_Align_Calendar_Correctly()
{
// Given
var console = new TestConsole();
var calendar = new Calendar(2020, 10)
.RightAligned()
.AddCalendarEvent(new DateTime(2020, 9, 1))
.AddCalendarEvent(new DateTime(2020, 10, 3))
.AddCalendarEvent(new DateTime(2020, 10, 12));
// When
console.Write(calendar);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Culture")]
public Task Should_Render_Calendar_Correctly_For_Specific_Culture()
{
// Given
var console = new TestConsole();
var calendar = new Calendar(2020, 10, 15)
.Culture("de-DE")
.AddCalendarEvent(new DateTime(2020, 9, 1))
.AddCalendarEvent(new DateTime(2020, 10, 3))
.AddCalendarEvent(new DateTime(2020, 10, 12));
// When
console.Write(calendar);
// Then
return Verifier.Verify(console.Output);
}
}
}

View File

@ -0,0 +1,143 @@
using System;
using System.Threading.Tasks;
using Shouldly;
using Spectre.Console.Testing;
using Spectre.Verify.Extensions;
using VerifyXunit;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
[UsesVerify]
[ExpectationPath("Widgets/Canvas")]
public class CanvasTests
{
public sealed class TheConstructor
{
[Fact]
public void Should_Throw_If_Width_Is_Less_Than_Zero()
{
// Given, When
var result = Record.Exception(() => new Canvas(0, 1));
// Then
result.ShouldBeOfType<ArgumentException>()
.And(ex => ex.ParamName.ShouldBe("width"));
}
[Fact]
public void Should_Throw_If_Height_Is_Less_Than_Zero()
{
// Given, When
var result = Record.Exception(() => new Canvas(1, 0));
// Then
result.ShouldBeOfType<ArgumentException>()
.And(ex => ex.ParamName.ShouldBe("height"));
}
}
[Fact]
[Expectation("Render")]
public async Task Should_Render_Canvas_Correctly()
{
// Given
var console = new TestConsole()
.Colors(ColorSystem.Standard)
.EmitAnsiSequences();
var canvas = new Canvas(width: 5, height: 5);
canvas.SetPixel(0, 0, Color.Red);
canvas.SetPixel(4, 0, Color.Green);
canvas.SetPixel(0, 4, Color.Blue);
canvas.SetPixel(4, 4, Color.Yellow);
// When
console.Write(canvas);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Nested")]
public async Task Simple_Measure()
{
// Given
var console = new TestConsole()
.Colors(ColorSystem.Standard)
.EmitAnsiSequences();
var panel = new Panel(new Canvas(width: 2, height: 2)
.SetPixel(0, 0, Color.Aqua)
.SetPixel(1, 1, Color.Grey));
// When
console.Write(panel);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_NarrowTerminal")]
public async Task Should_Scale_Down_Canvas_Is_Bigger_Than_Terminal()
{
// Given
var console = new TestConsole()
.Width(10)
.Colors(ColorSystem.Standard)
.EmitAnsiSequences();
var canvas = new Canvas(width: 20, height: 10);
canvas.SetPixel(0, 0, Color.Aqua);
canvas.SetPixel(19, 9, Color.Grey);
// When
console.Write(canvas);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_MaxWidth")]
public async Task Should_Scale_Down_Canvas_If_MaxWidth_Is_Set()
{
// Given
var console = new TestConsole()
.Colors(ColorSystem.Standard)
.EmitAnsiSequences();
var canvas = new Canvas(width: 20, height: 10) { MaxWidth = 10 };
canvas.SetPixel(0, 0, Color.Aqua);
canvas.SetPixel(19, 9, Color.Aqua);
// When
console.Write(canvas);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
public void Should_Not_Render_Canvas_If_Canvas_Cannot_Be_Scaled_Down()
{
// Given
var console = new TestConsole()
.Width(10)
.Colors(ColorSystem.Standard)
.EmitAnsiSequences();
var canvas = new Canvas(width: 20, height: 2);
canvas.SetPixel(0, 0, Color.Aqua);
canvas.SetPixel(19, 1, Color.Grey);
// When
console.Write(canvas);
// Then
console.Output.ShouldBeEmpty();
}
}
}

View File

@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Spectre.Console.Testing;
using Spectre.Verify.Extensions;
using VerifyXunit;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
[UsesVerify]
[ExpectationPath("Widgets/Columns")]
public sealed class ColumnsTests
{
private sealed class User
{
public string Name { get; set; }
public string Country { get; set; }
}
[Fact]
[Expectation("Render")]
public Task Should_Render_Columns_Correctly()
{
// Given
var console = new TestConsole().Width(61);
var users = new[]
{
new User { Name = "Savannah Thompson", Country = "Australia" },
new User { Name = "Sophie Ramos", Country = "United States" },
new User { Name = "Katrin Goldberg", Country = "Germany" },
};
var cards = new List<Panel>();
foreach (var user in users)
{
cards.Add(
new Panel($"[b]{user.Name}[/]\n[yellow]{user.Country}[/]")
.RoundedBorder().Expand());
}
// When
console.Write(new Columns(cards));
// Then
return Verifier.Verify(console.Output);
}
}
}

View File

@ -0,0 +1,107 @@
using System.Threading.Tasks;
using Spectre.Console.Testing;
using Spectre.Verify.Extensions;
using VerifyXunit;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
[UsesVerify]
[ExpectationPath("Widgets/Figlet")]
public sealed class FigletTests
{
[Fact]
[Expectation("Load_Stream")]
public async Task Should_Load_Font_From_Stream()
{
// Given
var console = new TestConsole().Width(180);
var font = FigletFont.Load(EmbeddedResourceReader.LoadResourceStream("Spectre.Console.Tests/Data/starwars.flf"));
var text = new FigletText(font, "Patrik was here");
// When
console.Write(text);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render")]
public async Task Should_Render_Text_Correctly()
{
// Given
var console = new TestConsole().Width(70);
var text = new FigletText(FigletFont.Default, "Patrik was here");
// When
console.Write(text);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Wrapped")]
public async Task Should_Render_Wrapped_Text_Correctly()
{
// Given
var console = new TestConsole().Width(70);
var text = new FigletText(FigletFont.Default, "Spectre.Console");
// When
console.Write(text);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_LeftAligned")]
public async Task Should_Render_Left_Aligned_Text_Correctly()
{
// Given
var console = new TestConsole().Width(120);
var text = new FigletText(FigletFont.Default, "Spectre.Console")
.Alignment(Justify.Left);
// When
console.Write(text);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Centered")]
public async Task Should_Render_Centered_Text_Correctly()
{
// Given
var console = new TestConsole().Width(120);
var text = new FigletText(FigletFont.Default, "Spectre.Console")
.Alignment(Justify.Center);
// When
console.Write(text);
// Then
await Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_RightAligned")]
public async Task Should_Render_Right_Aligned_Text_Correctly()
{
// Given
var console = new TestConsole().Width(120);
var text = new FigletText(FigletFont.Default, "Spectre.Console")
.Alignment(Justify.Right);
// When
console.Write(text);
// Then
await Verifier.Verify(console.Output);
}
}
}

View File

@ -0,0 +1,206 @@
using System;
using System.Threading.Tasks;
using Shouldly;
using Spectre.Console.Testing;
using Spectre.Verify.Extensions;
using VerifyXunit;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
[UsesVerify]
[ExpectationPath("Widgets/Grid")]
public sealed class GridTests
{
public sealed class TheAddColumnMethod
{
[Fact]
public void Should_Throw_If_Rows_Are_Not_Empty()
{
// Given
var grid = new Grid();
grid.AddColumn();
grid.AddRow("Hello World!");
// When
var result = Record.Exception(() => grid.AddColumn());
// Then
result.ShouldBeOfType<InvalidOperationException>()
.Message.ShouldBe("Cannot add new columns to grid with existing rows.");
}
}
public sealed class TheAddRowMethod
{
[Fact]
public void Should_Throw_If_Rows_Are_Null()
{
// Given
var grid = new Grid();
// When
var result = Record.Exception(() => grid.AddRow(null));
// Then
result.ShouldBeOfType<ArgumentNullException>()
.ParamName.ShouldBe("columns");
}
[Fact]
public void Should_Add_Empty_Items_If_User_Provides_Less_Row_Items_Than_Columns()
{
// Given
var grid = new Grid();
grid.AddColumn();
grid.AddColumn();
// When
grid.AddRow("Foo");
// Then
grid.Rows.Count.ShouldBe(1);
}
[Fact]
public void Should_Throw_If_Row_Columns_Are_Greater_Than_Number_Of_Columns()
{
// Given
var grid = new Grid();
grid.AddColumn();
// When
var result = Record.Exception(() => grid.AddRow("Foo", "Bar"));
// Then
result.ShouldBeOfType<InvalidOperationException>();
result.Message.ShouldBe("The number of row columns are greater than the number of grid columns.");
}
}
[UsesVerify]
[ExpectationPath("AddEmptyRow")]
public sealed class TheAddEmptyRowMethod
{
[Fact]
[Expectation("Render")]
public Task Should_Add_Empty_Row()
{
// Given
var console = new TestConsole();
var grid = new Grid();
grid.AddColumns(2);
grid.AddRow("Foo", "Bar");
grid.AddEmptyRow();
grid.AddRow("Qux", "Corgi");
grid.AddEmptyRow();
// When
console.Write(grid);
// Then
return Verifier.Verify(console.Output);
}
}
[Fact]
[Expectation("Render")]
public Task Should_Render_Grid_Correctly()
{
// Given
var console = new TestConsole();
var grid = new Grid();
grid.AddColumn();
grid.AddColumn();
grid.AddColumn();
grid.AddRow("Qux", "Corgi", "Waldo");
grid.AddRow("Grault", "Garply", "Fred");
// When
console.Write(grid);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_2")]
public Task Should_Render_Grid_Correctly_2()
{
var console = new TestConsole();
var grid = new Grid();
grid.AddColumn(new GridColumn { NoWrap = true });
grid.AddColumn(new GridColumn { Padding = new Padding(2, 0, 0, 0) });
grid.AddRow("[bold]Options[/]", string.Empty);
grid.AddRow(" [blue]-h[/], [blue]--help[/]", "Show command line help.");
grid.AddRow(" [blue]-c[/], [blue]--configuration[/]", "The configuration to run for.\nThe default for most projects is [green]Debug[/].");
// When
console.Write(grid);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Alignment")]
public Task Should_Render_Grid_Column_Alignment_Correctly()
{
// Given
var console = new TestConsole();
var grid = new Grid();
grid.AddColumn(new GridColumn { Alignment = Justify.Right });
grid.AddColumn(new GridColumn { Alignment = Justify.Center });
grid.AddColumn(new GridColumn { Alignment = Justify.Left });
grid.AddRow("Foo", "Bar", "Baz");
grid.AddRow("Qux", "Corgi", "Waldo");
grid.AddRow("Grault", "Garply", "Fred");
// When
console.Write(grid);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Padding")]
public Task Should_Use_Default_Padding()
{
// Given
var console = new TestConsole();
var grid = new Grid();
grid.AddColumns(3);
grid.AddRow("Foo", "Bar", "Baz");
grid.AddRow("Qux", "Corgi", "Waldo");
grid.AddRow("Grault", "Garply", "Fred");
// When
console.Write(grid);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_ExplicitPadding")]
public Task Should_Render_Explicit_Grid_Column_Padding_Correctly()
{
// Given
var console = new TestConsole();
var grid = new Grid();
grid.AddColumn(new GridColumn { Padding = new Padding(3, 0, 0, 0) });
grid.AddColumn(new GridColumn { Padding = new Padding(0, 0, 0, 0) });
grid.AddColumn(new GridColumn { Padding = new Padding(0, 0, 3, 0) });
grid.AddRow("Foo", "Bar", "Baz");
grid.AddRow("Qux", "Corgi", "Waldo");
grid.AddRow("Grault", "Garply", "Fred");
// When
console.Write(grid);
// Then
return Verifier.Verify(console.Output);
}
}
}

View File

@ -0,0 +1,143 @@
using System;
using Shouldly;
using Spectre.Console.Testing;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
public sealed class MarkupTests
{
public sealed class TheLengthProperty
{
[Theory]
[InlineData("Hello", 5)]
[InlineData("Hello\nWorld", 11)]
[InlineData("[yellow]Hello[/]", 5)]
public void Should_Return_The_Number_Of_Characters(string input, int expected)
{
// Given
var markup = new Markup(input);
// When
var result = markup.Length;
// Then
result.ShouldBe(expected);
}
}
public sealed class TheLinesProperty
{
[Theory]
[InlineData("Hello", 1)]
[InlineData("Hello\nWorld", 2)]
[InlineData("[yellow]Hello[/]\nWorld", 2)]
public void Should_Return_The_Number_Of_Lines(string input, int expected)
{
// Given
var markup = new Markup(input);
// When
var result = markup.Lines;
// Then
result.ShouldBe(expected);
}
}
public sealed class TheEscapeMethod
{
[Theory]
[InlineData("Hello World", "Hello World")]
[InlineData("Hello World [", "Hello World [[")]
[InlineData("Hello World ]", "Hello World ]]")]
[InlineData("Hello [World]", "Hello [[World]]")]
[InlineData("Hello [[World]]", "Hello [[[[World]]]]")]
public void Should_Escape_Markup_As_Expected(string input, string expected)
{
// Given, When
var result = Markup.Escape(input);
// Then
result.ShouldBe(expected);
}
}
public sealed class TheRemoveMethod
{
[Theory]
[InlineData("Hello World", "Hello World")]
[InlineData("Hello [blue]World", "Hello World")]
[InlineData("Hello [blue]World[/]", "Hello World")]
public void Should_Remove_Markup_From_Text(string input, string expected)
{
// Given, When
var result = Markup.Remove(input);
// Then
result.ShouldBe(expected);
}
}
[Theory]
[InlineData("Hello [[ World ]")]
[InlineData("Hello [[ World ] !")]
public void Should_Throw_If_Closing_Tag_Is_Not_Properly_Escaped(string input)
{
// Given
var console = new TestConsole();
// When
var result = Record.Exception(() => new Markup(input));
// Then
result.ShouldNotBeNull();
result.ShouldBeOfType<InvalidOperationException>();
result.Message.ShouldBe("Encountered unescaped ']' token at position 16");
}
[Fact]
public void Should_Escape_Markup_Blocks_As_Expected()
{
// Given
var console = new TestConsole();
var markup = new Markup("Hello [[ World ]] !");
// When
console.Write(markup);
// Then
console.Output.ShouldBe("Hello [ World ] !");
}
[Theory]
[InlineData("Hello [link=http://example.com]example.com[/]", "Hello example.com")]
[InlineData("Hello [link=http://example.com]http://example.com[/]", "Hello http://example.com")]
public void Should_Render_Links_As_Expected(string input, string output)
{
// Given
var console = new TestConsole();
var markup = new Markup(input);
// When
console.Write(markup);
// Then
console.Output.ShouldBe(output);
}
[Fact]
public void Should_Not_Fail_With_Brackets_On_Calls_Without_Args()
{
// Given
var console = new TestConsole();
// When
console.MarkupLine("{");
// Then
console.Output.NormalizeLineEndings()
.ShouldBe("{\n");
}
}
}

View File

@ -0,0 +1,75 @@
using System.Threading.Tasks;
using Spectre.Console.Testing;
using Spectre.Verify.Extensions;
using VerifyXunit;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
[UsesVerify]
[ExpectationPath("Widgets/Padder")]
public sealed class PadderTests
{
[Fact]
[Expectation("Render")]
public Task Should_Render_Padded_Object_Correctly()
{
// Given
var console = new TestConsole().Width(60);
var table = new Table();
table.AddColumn("Foo");
table.AddColumn("Bar");
table.AddRow("Baz", "Qux");
table.AddRow("Corgi", "Waldo");
// When
console.Write(new Padder(table).Padding(1, 2, 3, 4));
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Expanded")]
public Task Should_Render_Expanded_Padded_Object_Correctly()
{
// Given
var console = new TestConsole().Width(60);
var table = new Table();
table.AddColumn("Foo");
table.AddColumn("Bar");
table.AddRow("Baz", "Qux");
table.AddRow("Corgi", "Waldo");
// When
console.Write(new Padder(table)
.Padding(1, 2, 3, 4)
.Expand());
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Nested")]
public Task Should_Render_Padded_Object_Correctly_When_Nested_Within_Other_Object()
{
// Given
var console = new TestConsole().Width(60);
var table = new Table();
table.AddColumn("Foo");
table.AddColumn("Bar", c => c.PadLeft(0).PadRight(0));
table.AddRow("Baz", "Qux");
table.AddRow(new Text("Corgi"), new Padder(new Panel("Waldo"))
.Padding(2, 1));
// When
console.Write(new Padder(table)
.Padding(1, 2, 3, 4)
.Expand());
// Then
return Verifier.Verify(console.Output);
}
}
}

View File

@ -0,0 +1,309 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Spectre.Console.Rendering;
using Spectre.Console.Testing;
using Spectre.Verify.Extensions;
using VerifyXunit;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
[UsesVerify]
[ExpectationPath("Widgets/Panel")]
public sealed class PanelTests
{
[Fact]
[Expectation("Render")]
public Task Should_Render_Panel()
{
// Given
var console = new TestConsole();
// When
console.Write(new Panel(new Text("Hello World")));
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_ZeroPadding")]
public Task Should_Render_Panel_With_Padding_Set_To_Zero()
{
// Given
var console = new TestConsole();
// When
console.Write(new Panel(new Text("Hello World"))
{
Padding = new Padding(0, 0, 0, 0),
});
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Padding")]
public Task Should_Render_Panel_With_Padding()
{
// Given
var console = new TestConsole();
// When
console.Write(new Panel(new Text("Hello World"))
{
Padding = new Padding(3, 1, 5, 2),
});
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Header")]
public Task Should_Render_Panel_With_Header()
{
// Given
var console = new TestConsole();
// When
console.Write(new Panel("Hello World")
{
Header = new PanelHeader("Greeting"),
Expand = true,
Padding = new Padding(2, 0, 2, 0),
});
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Header_LeftAligned")]
public Task Should_Render_Panel_With_Left_Aligned_Header()
{
// Given
var console = new TestConsole();
// When
console.Write(new Panel("Hello World")
{
Header = new PanelHeader("Greeting").LeftAligned(),
Expand = true,
});
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Header_Centered")]
public Task Should_Render_Panel_With_Centered_Header()
{
// Given
var console = new TestConsole();
// When
console.Write(new Panel("Hello World")
{
Header = new PanelHeader("Greeting").Centered(),
Expand = true,
});
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Header_RightAligned")]
public Task Should_Render_Panel_With_Right_Aligned_Header()
{
// Given
var console = new TestConsole();
// When
console.Write(new Panel("Hello World")
{
Header = new PanelHeader("Greeting").RightAligned(),
Expand = true,
});
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Header_Collapse")]
public Task Should_Collapse_Header_If_It_Will_Not_Fit()
{
// Given
var console = new TestConsole().Width(10);
// When
console.Write(new Panel("Hello World")
{
Header = new PanelHeader("Greeting"),
Expand = true,
});
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Unicode")]
public Task Should_Render_Panel_With_Unicode_Correctly()
{
// Given
var console = new TestConsole();
// When
console.Write(new Panel(new Text(" \n💩\n ")));
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Multiline")]
public Task Should_Render_Panel_With_Multiple_Lines()
{
// Given
var console = new TestConsole();
// When
console.Write(new Panel(new Text("Hello World\nFoo Bar")));
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_LineEndings")]
public Task Should_Preserve_Explicit_Line_Ending()
{
// Given
var console = new TestConsole();
var text = new Panel(
new Markup("I heard [underline on blue]you[/] like 📦\n\n\n\nSo I put a 📦 in a 📦"));
// When
console.Write(text);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Expand")]
public Task Should_Expand_Panel_If_Enabled()
{
// Given
var console = new TestConsole();
// When
console.Write(new Panel(new Text("Hello World"))
{
Expand = true,
});
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Child_RightAligned")]
public Task Should_Justify_Child_To_Right_Correctly()
{
// Given
var console = new TestConsole().Width(25);
// When
console.Write(
new Panel(new Text("Hello World").RightAligned())
{
Expand = true,
});
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Child_Centered")]
public Task Should_Center_Child_Correctly()
{
// Given
var console = new TestConsole().Width(25);
// When
console.Write(
new Panel(new Text("Hello World").Centered())
{
Expand = true,
});
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Child_Panel")]
public Task Should_Render_Panel_Inside_Panel_Correctly()
{
// Given
var console = new TestConsole();
// When
console.Write(new Panel(new Panel(new Text("Hello World"))));
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Wrap")]
public Task Should_Wrap_Content_Correctly()
{
// Given
var console = new TestConsole().Width(84);
var rows = new List<IRenderable>();
var grid = new Grid();
grid.AddColumn(new GridColumn().PadLeft(2).PadRight(0));
grid.AddColumn(new GridColumn().PadLeft(1).PadRight(0));
grid.AddRow("at", "[grey]System.Runtime.CompilerServices.TaskAwaiter.[/][yellow]HandleNonSuccessAndDebuggerNotification[/]([blue]Task[/] task)");
rows.Add(grid);
var panel = new Panel(grid)
.Expand().RoundedBorder()
.BorderStyle(new Style().Foreground(Color.Grey))
.Header("[grey]Short paths[/]");
// When
console.Write(panel);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_CJK")]
public Task Should_Wrap_Table_With_CJK_Tables_In_Panel_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn("测试");
table.AddRow("测试");
var panel = new Panel(table);
// When
console.Write(panel);
// Then
return Verifier.Verify(console.Output);
}
}
}

View File

@ -0,0 +1,83 @@
using System.Threading.Tasks;
using Spectre.Console.Rendering;
using Spectre.Console.Testing;
using Spectre.Verify.Extensions;
using VerifyXunit;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
[UsesVerify]
[ExpectationPath("Widgets/Rows")]
public sealed class RowsTests
{
[Fact]
[Expectation("Render")]
public Task Should_Render_Rows()
{
// Given
var console = new TestConsole().Width(60);
var rows = new Rows(
new IRenderable[]
{
new Markup("Hello"),
new Table()
.AddColumns("Foo", "Bar")
.AddRow("Baz", "Qux"),
new Markup("World"),
});
// When
console.Write(rows);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Nested")]
public Task Should_Render_Rows_Correctly_Inside_Other_Widget()
{
// Given
var console = new TestConsole().Width(60);
var table = new Table()
.AddColumns("Foo", "Bar")
.AddRow("HELLO WORLD")
.AddRow(
new Rows(new IRenderable[]
{
new Markup("Hello"),
new Markup("World"),
}), new Text("Qux"));
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Expanded_And_Nested")]
public Task Should_Render_Rows_Correctly_Inside_Other_Widget_When_Expanded()
{
// Given
var console = new TestConsole().Width(60);
var table = new Table()
.AddColumns("Foo", "Bar")
.AddRow("HELLO WORLD")
.AddRow(
new Rows(new IRenderable[]
{
new Markup("Hello"),
new Markup("World"),
}).Expand(), new Text("Qux"));
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
}
}

View File

@ -0,0 +1,158 @@
using System.Threading.Tasks;
using Shouldly;
using Spectre.Console.Testing;
using Spectre.Verify.Extensions;
using VerifyXunit;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
[UsesVerify]
[ExpectationPath("Widgets/Rule")]
public sealed class RuleTests
{
[Fact]
[Expectation("Render")]
public Task Should_Render_Default_Rule_Without_Title()
{
// Given
var console = new TestConsole().Width(40);
// When
console.Write(new Rule());
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Border_NoHeader")]
public Task Should_Render_Default_Rule_With_Specified_Border()
{
// Given
var console = new TestConsole().Width(40);
// When
console.Write(new Rule().DoubleBorder());
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Border_Header")]
public Task Should_Render_With_Specified_Box()
{
// Given
var console = new TestConsole().Width(40);
// When
console.Write(new Rule("Hello World").DoubleBorder());
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Header_DefaultAlignment")]
public Task Should_Render_Default_Rule_With_Title_Centered_By_Default()
{
// Given
var console = new TestConsole().Width(40);
// When
console.Write(new Rule("Hello World"));
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Header_LeftAligned")]
public Task Should_Render_Default_Rule_With_Title_Left_Aligned()
{
// Given
var console = new TestConsole().Width(40);
// When
console.Write(new Rule("Hello World")
{
Alignment = Justify.Left,
});
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Header_RightAligned")]
public Task Should_Render_Default_Rule_With_Title_Right_Aligned()
{
// Given
var console = new TestConsole().Width(40);
// When
console.Write(new Rule("Hello World")
{
Alignment = Justify.Right,
});
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Linebreaks")]
public Task Should_Convert_Line_Breaks_In_Title_To_Spaces()
{
// Given
var console = new TestConsole().Width(40);
// When
console.Write(new Rule("Hello\nWorld\r\n!"));
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Truncate")]
public Task Should_Truncate_Title()
{
// Given
var console = new TestConsole().Width(40);
// When
console.Write(new Rule(" Hello World "));
// Then
return Verifier.Verify(console.Output);
}
[Theory]
[InlineData(1, "Hello World Hello World Hello World Hello World Hello World", "─")]
[InlineData(2, "Hello World Hello World Hello World Hello World Hello World", "──")]
[InlineData(3, "Hello World Hello World Hello World Hello World Hello World", "───")]
[InlineData(4, "Hello World Hello World Hello World Hello World Hello World", "────")]
[InlineData(5, "Hello World Hello World Hello World Hello World Hello World", "─────")]
[InlineData(6, "Hello World Hello World Hello World Hello World Hello World", "──────")]
[InlineData(7, "Hello World Hello World Hello World Hello World Hello World", "───────")]
[InlineData(8, "Hello World Hello World Hello World Hello World Hello World", "── H… ──")]
[InlineData(8, "A", "── A ───")]
[InlineData(8, "AB", "── AB ──")]
[InlineData(8, "ABC", "── A… ──")]
[InlineData(40, "Hello World Hello World Hello World Hello World Hello World", "──── Hello World Hello World Hello… ────")]
public void Should_Truncate_Too_Long_Title(int width, string input, string expected)
{
// Given
var console = new TestConsole().Width(width);
// When
console.Write(new Rule(input));
// Then
console.Lines.Count.ShouldBe(1);
console.Lines[0].ShouldBe(expected);
}
}
}

View File

@ -0,0 +1,501 @@
using System;
using System.Threading.Tasks;
using Shouldly;
using Spectre.Console.Testing;
using Spectre.Verify.Extensions;
using VerifyXunit;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
[UsesVerify]
[ExpectationPath("Widgets/Table")]
public sealed class TableTests
{
public sealed class TheAddColumnMethod
{
[Fact]
public void Should_Throw_If_Column_Is_Null()
{
// Given
var table = new Table();
// When
var result = Record.Exception(() => table.AddColumn((string)null));
// Then
result.ShouldBeOfType<ArgumentNullException>()
.ParamName.ShouldBe("column");
}
[Fact]
public void Should_Throw_If_Rows_Are_Not_Empty()
{
// Given
var grid = new Table();
grid.AddColumn("Foo");
grid.AddRow("Hello World");
// When
var result = Record.Exception(() => grid.AddColumn("Bar"));
// Then
result.ShouldBeOfType<InvalidOperationException>()
.Message.ShouldBe("Cannot add new columns to table with existing rows.");
}
}
public sealed class TheAddColumnsMethod
{
[Fact]
public void Should_Throw_If_Columns_Are_Null()
{
// Given
var table = new Table();
// When
var result = Record.Exception(() => table.AddColumns((string[])null));
// Then
result.ShouldBeOfType<ArgumentNullException>()
.ParamName.ShouldBe("columns");
}
}
public sealed class TheAddRowMethod
{
[Fact]
public void Should_Throw_If_String_Rows_Are_Null()
{
// Given
var table = new Table();
// When
var result = Record.Exception(() => table.AddRow((string[])null));
// Then
result.ShouldBeOfType<ArgumentNullException>()
.ParamName.ShouldBe("columns");
}
[Fact]
public void Should_Throw_If_Renderable_Rows_Are_Null()
{
// Given
var table = new Table();
// When
var result = Record.Exception(() => table.AddRow(null));
// Then
result.ShouldBeOfType<ArgumentNullException>()
.ParamName.ShouldBe("columns");
}
[Fact]
public void Should_Add_Empty_Items_If_User_Provides_Less_Row_Items_Than_Columns()
{
// Given
var table = new Table();
table.AddColumn("Hello");
table.AddColumn("World");
// When
table.AddRow("Foo");
// Then
table.Rows.Count.ShouldBe(1);
}
[Fact]
public void Should_Throw_If_Row_Columns_Are_Greater_Than_Number_Of_Columns()
{
// Given
var table = new Table();
table.AddColumn("Hello");
// When
var result = Record.Exception(() => table.AddRow("Foo", "Bar"));
// Then
result.ShouldBeOfType<InvalidOperationException>();
result.Message.ShouldBe("The number of row columns are greater than the number of table columns.");
}
}
[UsesVerify]
public sealed class TheAddEmptyRowMethod
{
[Fact]
[Expectation("AddEmptyRow")]
public Task Should_Render_Table_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux", "Corgi", "Waldo");
table.AddEmptyRow();
table.AddRow("Grault", "Garply", "Fred");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
}
[Fact]
[Expectation("Render")]
public Task Should_Render_Table_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Footers")]
public Task Should_Render_Table_With_Footers_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn(new TableColumn("Foo").Footer("Oof").RightAligned());
table.AddColumn("Bar");
table.AddColumns(new TableColumn("Baz").Footer("Zab"));
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_LeftAligned")]
public Task Should_Left_Align_Table_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table();
table.Alignment = Justify.Left;
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Centered")]
public Task Should_Center_Table_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table();
table.Alignment = Justify.Center;
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_RightAligned")]
public Task Should_Right_Align_Table_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table();
table.Alignment = Justify.Right;
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Nested")]
public Task Should_Render_Table_Nested_In_Panels_Correctly()
{
// A simple table
var console = new TestConsole();
var table = new Table() { Border = TableBorder.Rounded };
table.AddColumn("Foo");
table.AddColumn("Bar");
table.AddColumn(new TableColumn("Baz") { Alignment = Justify.Right });
table.AddRow("Qux\nQuuuuuux", "[blue]Corgi[/]", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
// Render a table in some panels.
console.Write(new Panel(new Panel(table)
{
Border = BoxBorder.Ascii,
}));
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_ColumnJustification")]
public Task Should_Render_Table_With_Column_Justification_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumn(new TableColumn("Foo") { Alignment = Justify.Left });
table.AddColumn(new TableColumn("Bar") { Alignment = Justify.Right });
table.AddColumn(new TableColumn("Baz") { Alignment = Justify.Center });
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Lorem ipsum dolor sit amet");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Expand")]
public Task Should_Expand_Table_To_Available_Space_If_Specified()
{
// Given
var console = new TestConsole();
var table = new Table() { Expand = true };
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Multiline")]
public Task Should_Render_Table_With_Multiple_Rows_In_Cell_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux\nQuuux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_CellPadding")]
public Task Should_Render_Table_With_Cell_Padding_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumns("Foo", "Bar");
table.AddColumn(new TableColumn("Baz") { Padding = new Padding(3, 0, 2, 0) });
table.AddRow("Qux\nQuuux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_NoRows")]
public Task Should_Render_Table_Without_Rows()
{
// Given
var console = new TestConsole();
var table = new Table();
table.AddColumns("Foo", "Bar");
table.AddColumn(new TableColumn("Baz") { Padding = new Padding(3, 0, 2, 0) });
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Impossible")]
public Task Should_Not_Draw_Tables_That_Are_Impossible_To_Draw()
{
// Given
var console = new TestConsole().Width(25);
var first = new Table().Border(TableBorder.Rounded).BorderColor(Color.Red);
first.AddColumn(new TableColumn("[u]PS1[/]").Centered());
first.AddColumn(new TableColumn("[u]PS2[/]"));
first.AddColumn(new TableColumn("[u]PS3[/]"));
first.AddRow("Hello", "[red]World[/]", string.Empty);
first.AddRow("[blue]Bonjour[/]", "[white]le[/]", "[red]monde![/]");
first.AddRow("[blue]Hej[/]", "[yellow]Världen[/]", string.Empty);
var second = new Table().Border(TableBorder.Square).BorderColor(Color.Green);
second.AddColumn(new TableColumn("[u]Foo[/]"));
second.AddColumn(new TableColumn("[u]Bar[/]"));
second.AddColumn(new TableColumn("[u]Baz[/]"));
second.AddRow("Hello", "[red]World[/]", string.Empty);
second.AddRow(first, new Text("Whaaat"), new Text("Lolz"));
second.AddRow("[blue]Hej[/]", "[yellow]Världen[/]", string.Empty);
var table = new Table().Border(TableBorder.Rounded);
table.AddColumn(new TableColumn(new Panel("[u]ABC[/]").BorderColor(Color.Red)));
table.AddColumn(new TableColumn(new Panel("[u]DEF[/]").BorderColor(Color.Green)));
table.AddColumn(new TableColumn(new Panel("[u]GHI[/]").BorderColor(Color.Blue)));
table.AddRow(new Text("Hello").Centered(), new Markup("[red]World[/]"), Text.Empty);
table.AddRow(second, new Text("Whaat"), new Text("Lol").RightAligned());
table.AddRow(new Markup("[blue]Hej[/]"), new Markup("[yellow]Världen[/]"), Text.Empty);
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Title_Caption")]
public Task Should_Render_Table_With_Title_And_Caption_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table { Border = TableBorder.Rounded };
table.Title = new TableTitle("Hello World");
table.Caption = new TableTitle("Goodbye World");
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Title_Caption_LeftAligned")]
public Task Should_Left_Align_Table_With_Title_And_Caption_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table { Border = TableBorder.Rounded };
table.LeftAligned();
table.Title = new TableTitle("Hello World");
table.Caption = new TableTitle("Goodbye World");
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Title_Caption_Centered")]
public Task Should_Center_Table_With_Title_And_Caption_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table { Border = TableBorder.Rounded };
table.Centered();
table.Title = new TableTitle("Hello World");
table.Caption = new TableTitle("Goodbye World");
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Title_Caption_RightAligned")]
public Task Should_Right_Align_Table_With_Title_And_Caption_Correctly()
{
// Given
var console = new TestConsole();
var table = new Table { Border = TableBorder.Rounded };
table.RightAligned();
table.Title = new TableTitle("Hello World");
table.Caption = new TableTitle("Goodbye World");
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred");
// When
console.Write(table);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_Fold")]
public Task Should_Render_With_Folded_Text_Table_Correctly()
{
// Given
var console = new TestConsole().Width(30);
var table = new Table();
table.AddColumns("Foo", "Bar", "Baz");
table.AddRow("Qux With A Long Description", "Corgi", "Waldo");
table.AddRow("Grault", "Garply", "Fred On A Long Long Walk");
var panel = new Panel(table);
panel.Border = BoxBorder.Double;
// When
console.Write(panel);
// Then
return Verifier.Verify(console.Output);
}
}
}

View File

@ -0,0 +1,158 @@
using Shouldly;
using Spectre.Console.Rendering;
using Spectre.Console.Testing;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
public sealed class TextTests
{
public sealed class TheLengthProperty
{
[Theory]
[InlineData("Hello", 5)]
[InlineData("Hello\nWorld", 11)]
public void Should_Return_The_Number_Of_Characters(string input, int expected)
{
// Given
var markup = new Text(input);
// When
var result = markup.Length;
// Then
result.ShouldBe(expected);
}
}
public sealed class TheLinesProperty
{
[Theory]
[InlineData("Hello", 1)]
[InlineData("Hello\nWorld", 2)]
public void Should_Return_The_Number_Of_Lines(string input, int expected)
{
// Given
var markup = new Text(input);
// When
var result = markup.Lines;
// Then
result.ShouldBe(expected);
}
}
[Fact]
public void Should_Consider_The_Longest_Word_As_Minimum_Width()
{
// Given
var caps = new TestCapabilities { Unicode = true };
var text = new Text("Foo Bar Baz\nQux\nLol mobile");
// When
var result = ((IRenderable)text).Measure(caps.CreateRenderContext(), 80);
// Then
result.Min.ShouldBe(6);
}
[Fact]
public void Should_Consider_The_Longest_Line_As_Maximum_Width()
{
// Given
var caps = new TestCapabilities { Unicode = true };
var text = new Text("Foo Bar Baz\nQux\nLol mobile");
// When
var result = ((IRenderable)text).Measure(caps.CreateRenderContext(), 80);
// Then
result.Max.ShouldBe(11);
}
[Fact]
public void Should_Render_Unstyled_Text_As_Expected()
{
// Given
var console = new TestConsole();
var text = new Text("Hello World");
// When
console.Write(text);
// Then
console.Output.ShouldBe("Hello World");
}
[Theory]
[InlineData("Hello\n\nWorld\n\n")]
[InlineData("Hello\r\n\r\nWorld\r\n\r\n")]
public void Should_Write_Line_Breaks(string input)
{
// Given
var console = new TestConsole();
var text = new Text(input);
// When
console.Write(text);
// Then
console.Output.ShouldBe("Hello\n\nWorld\n\n");
}
[Fact]
public void Should_Render_Panel_2()
{
// Given
var console = new TestConsole();
// When
console.Write(new Markup("[b]Hello World[/]\n[yellow]Hello World[/]"));
// Then
console.Lines.Count.ShouldBe(2);
console.Lines[0].ShouldBe("Hello World");
console.Lines[1].ShouldBe("Hello World");
}
[Theory]
[InlineData(5, "Hello World", "Hello\nWorld")]
[InlineData(10, "Hello Sweet Nice World", "Hello \nSweet Nice\nWorld")]
public void Should_Split_Unstyled_Text_To_New_Lines_If_Width_Exceeds_Console_Width(
int width, string input, string expected)
{
// Given
var console = new TestConsole().Width(width);
var text = new Text(input);
// When
console.Write(text);
// Then
console.Output
.NormalizeLineEndings()
.ShouldBe(expected);
}
[Theory]
[InlineData(Overflow.Fold, "foo \npneumonoultram\nicroscopicsili\ncovolcanoconio\nsis bar qux")]
[InlineData(Overflow.Crop, "foo \npneumonoultram\nbar qux")]
[InlineData(Overflow.Ellipsis, "foo \npneumonoultra…\nbar qux")]
public void Should_Overflow_Text_Correctly(Overflow overflow, string expected)
{
// Given
var console = new TestConsole().Width(14);
var text = new Text("foo pneumonoultramicroscopicsilicovolcanoconiosis bar qux")
.Overflow(overflow);
// When
console.Write(text);
// Then
console.Output
.NormalizeLineEndings()
.ShouldBe(expected);
}
}
}

View File

@ -0,0 +1,85 @@
using System.Linq;
using System.Threading.Tasks;
using Shouldly;
using Spectre.Console.Testing;
using Spectre.Verify.Extensions;
using VerifyXunit;
using Xunit;
namespace Spectre.Console.Tests.Unit
{
[UsesVerify]
[ExpectationPath("Widgets/Tree")]
public class TreeTests
{
[Fact]
[Expectation("Render")]
public Task Should_Render_Tree_Correctly()
{
// Given
var console = new TestConsole();
var tree = new Tree(new Text("Root node")).Guide(TreeGuide.DoubleLine);
var nestedChildren = Enumerable.Range(0, 10).Select(x => new Text($"multiple\nline {x}"));
var child2 = new TreeNode(new Text("child2"));
var child2Child = new TreeNode(new Text("child2-1"));
child2.AddNode(child2Child);
child2Child.AddNode(new TreeNode(new Text("Child2-1-1\nchild")));
var child3 = new TreeNode(new Text("child3"));
var child3Child = new TreeNode(new Text("single leaf\nmultiline"));
child3Child.AddNode(new TreeNode(new Calendar(2021, 01)));
child3.AddNode(child3Child);
tree.AddNode("child1").AddNodes(nestedChildren);
tree.AddNode(child2);
tree.AddNode(child3);
tree.AddNode("child4");
// When
console.Write(tree);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
[Expectation("Render_NoChildren")]
public Task Should_Render_Tree_With_No_Child_Nodes_Correctly()
{
// Given
var console = new TestConsole();
var tree = new Tree(new Text("Root node"));
// When
console.Write(tree);
// Then
return Verifier.Verify(console.Output);
}
[Fact]
public void Should_Throw_If_Tree_Contains_Cycles()
{
// Given
var console = new TestConsole();
var child2 = new TreeNode(new Text("child 2"));
var child3 = new TreeNode(new Text("child 3"));
var child1 = new TreeNode(new Text("child 1"));
child1.AddNodes(child2, child3);
var root = new TreeNode(new Text("Branch Node"));
root.AddNodes(child1);
child2.AddNode(root);
var tree = new Tree("root node");
tree.AddNodes(root);
// When
var result = Record.Exception(() => console.Write(tree));
// Then
result.ShouldBeOfType<CircularTreeException>();
}
}
}