c435df9fcd
ci / restore build format test pack (push) Failing after 22s
- migrate remaining text and component smoke assertions into TinyTUI.Tests - remove legacy TextChecks and ComponentChecks projects from solution - update README test guidance to use the unified xUnit suite
120 lines
4.3 KiB
C#
120 lines
4.3 KiB
C#
using TinyTUI.Rendering;
|
|
using TinyTUI.Terminal.Images;
|
|
using TinyTUI.Tests.TestInfrastructure;
|
|
using TinyTUI.Text;
|
|
|
|
namespace TinyTUI.Tests.Rendering;
|
|
|
|
public sealed class DifferentialRendererTests
|
|
{
|
|
private static readonly RenderPipelineOptions TestOptions = new()
|
|
{
|
|
ThrowOnWidthOverflow = true,
|
|
UseSynchronizedOutput = false,
|
|
};
|
|
|
|
[Fact]
|
|
public void FirstRenderCapturesVisibleViewportAndLineResets()
|
|
{
|
|
var output = new VirtualTerminalOutput(20, 3);
|
|
var renderer = CreateRenderer(output);
|
|
|
|
renderer.Render(["Line 0", "Line 1", "Line 2", "Line 3"], output.Size);
|
|
|
|
Assert.Equal(1, renderer.FullRedrawCount);
|
|
Assert.Equal(new RenderViewportState(1, 3, 4, 4), renderer.ViewportState);
|
|
Assert.Contains("Line 1\e[0m\e]8;;\a", output.Buffer.ToString(), StringComparison.Ordinal);
|
|
Assert.DoesNotContain("Line 0", output.Buffer.ToString(), StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void DiffRenderOnlyMovesAndClearsChangedRows()
|
|
{
|
|
var output = new VirtualTerminalOutput(20, 4);
|
|
var renderer = CreateRenderer(output);
|
|
renderer.Render(["Header", "Working...", "Footer"], output.Size);
|
|
output.ClearWrites();
|
|
|
|
renderer.Render(["Header", "Working /", "Footer"], output.Size);
|
|
|
|
Assert.Equal(1, renderer.DifferentialRedrawCount);
|
|
Assert.Contains("\e[2;1H\e[2KWorking /", output.Buffer.ToString(), StringComparison.Ordinal);
|
|
Assert.DoesNotContain("\e[1;1H\e[2KHeader", output.Buffer.ToString(), StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void ResizeAndShrinkForceFullRedrawsToClearStaleRows()
|
|
{
|
|
var output = new VirtualTerminalOutput(20, 5);
|
|
var renderer = CreateRenderer(output);
|
|
renderer.Render(["Line 0", "Line 1", "Line 2", "Line 3"], output.Size);
|
|
|
|
output.Resize(20, 6);
|
|
output.ClearWrites();
|
|
renderer.Render(["Line 0", "Line 1", "Line 2", "Line 3"], output.Size);
|
|
Assert.Equal(2, renderer.FullRedrawCount);
|
|
Assert.True(output.Contains("\e[2J\e[H"));
|
|
|
|
output.ClearWrites();
|
|
renderer.Render(["Line 0"], output.Size);
|
|
Assert.Equal(3, renderer.FullRedrawCount);
|
|
Assert.True(output.Contains("\e[2J\e[H"));
|
|
}
|
|
|
|
[Fact]
|
|
public void CursorMarkerMovesHardwareCursorAndCanShowCursor()
|
|
{
|
|
var output = new VirtualTerminalOutput(20, 4);
|
|
var renderer = new DifferentialRenderer(
|
|
output,
|
|
new TerminalTextMeasurer(),
|
|
new RenderPipelineOptions
|
|
{
|
|
ThrowOnWidthOverflow = true,
|
|
UseSynchronizedOutput = false,
|
|
ShowHardwareCursor = true,
|
|
});
|
|
|
|
renderer.Render([$"ab{CursorMarker.Marker}cd"], output.Size);
|
|
|
|
Assert.True(output.Contains("\e[1;3H"));
|
|
Assert.True(output.Contains("\e[?25h"));
|
|
}
|
|
|
|
[Fact]
|
|
public void ChangedKittyImageIsDeletedBeforeReplacementLine()
|
|
{
|
|
var output = new VirtualTerminalOutput(20, 4);
|
|
var renderer = CreateRenderer(output);
|
|
var kittyLine = "\e_Ga=T,f=100,q=2,C=1,c=1,r=1,i=42;AAAA\e\\";
|
|
|
|
renderer.Render([kittyLine], output.Size);
|
|
output.ClearWrites();
|
|
renderer.Render(["changed"], output.Size);
|
|
|
|
var writes = output.Buffer.ToString();
|
|
var deleteIndex = writes.IndexOf(TerminalImageService.DeleteKittyImage(42), StringComparison.Ordinal);
|
|
var changedIndex = writes.IndexOf("changed", StringComparison.Ordinal);
|
|
Assert.True(deleteIndex >= 0);
|
|
Assert.True(changedIndex >= 0);
|
|
Assert.True(deleteIndex < changedIndex);
|
|
}
|
|
|
|
[Fact]
|
|
public void LongITerm2ImageLineBypassesTextWidthOverflow()
|
|
{
|
|
var output = new VirtualTerminalOutput(20, 5);
|
|
var renderer = CreateRenderer(output);
|
|
var imageLine = $"Read image file \e]1337;File=inline=1:{new string('A', 200)}\a";
|
|
|
|
// 图像协议本身可能很长 但渲染器应按图像行处理而不是按可见文本宽度报错
|
|
renderer.Render([imageLine], output.Size);
|
|
renderer.Render(["plain"], output.Size);
|
|
|
|
Assert.Contains("plain", output.Buffer.ToString(), StringComparison.Ordinal);
|
|
}
|
|
|
|
private static DifferentialRenderer CreateRenderer(VirtualTerminalOutput output)
|
|
=> new(output, new TerminalTextMeasurer(), TestOptions);
|
|
}
|