Files
ttui/test/TinyTUI.Tests/Components/ComponentRegressionTests.cs
T
chuan b26104fe95 feat: add tui test infrastructure
- add xunit regression project with virtual terminal output

- cover text input overlay rendering and component checks
2026-06-04 02:35:52 +08:00

84 lines
3.4 KiB
C#

using TinyTUI.Autocomplete;
using TinyTUI.Components;
using TinyTUI.Input;
using TinyTUI.Rendering;
using TinyTUI.Terminal.Images;
using TinyTUI.Text;
namespace TinyTUI.Tests.Components;
public sealed class ComponentRegressionTests
{
private readonly TerminalTextMeasurer _measurer = new();
[Fact]
public void FocusableComponentsOnlyRenderCursorMarkerWhenFocused()
{
var input = new TinyTUI.Components.Input(_measurer) { Prompt = "> " };
Assert.DoesNotContain(CursorMarker.Marker, input.Render(20)[0], StringComparison.Ordinal);
input.Focused = true;
Assert.Contains(CursorMarker.Marker, input.Render(20)[0], StringComparison.Ordinal);
var editor = new Editor(_measurer) { Placeholder = "type here" };
Assert.DoesNotContain(CursorMarker.Marker, editor.Render(20)[0], StringComparison.Ordinal);
editor.Focused = true;
Assert.Contains(CursorMarker.Marker, editor.Render(20)[0], StringComparison.Ordinal);
}
[Fact]
public void SlashCommandAutocompleteCanRenderConfirmAndCancel()
{
var editor = new Editor(_measurer)
{
AutocompleteProvider = new SlashCommandAutocompleteProvider(
[
new SlashCommand("help", "show help"),
new SlashCommand("history", "show history"),
]),
};
editor.HandleInput(new TuiInputEvent(TuiInputEventKind.Text, "/h"));
Assert.True(editor.IsAutocompleteActive);
Assert.Contains(editor.RenderAutocomplete(40), line => line.Contains("help", StringComparison.Ordinal));
editor.HandleInput(new TuiInputEvent(TuiInputEventKind.Key, KeyNames.Down));
editor.HandleInput(new TuiInputEvent(TuiInputEventKind.Key, KeyNames.Tab));
Assert.Equal("/history ", editor.Value);
Assert.False(editor.IsAutocompleteActive);
editor.Value = "/h";
editor.HandleInput(new TuiInputEvent(TuiInputEventKind.Key, KeyNames.Tab));
editor.HandleInput(new TuiInputEvent(TuiInputEventKind.Key, KeyNames.Escape));
Assert.False(editor.IsAutocompleteActive);
Assert.Equal("/h", editor.Value);
}
[Fact]
public void ImageComponentRendersKittySequenceAndFallback()
{
var imageService = new TerminalImageService();
imageService.SetCapabilities(new TerminalCapabilities(ImageProtocol.Kitty, true, true));
imageService.SetCellDimensions(new CellDimensions(10, 10));
Assert.Equal(new ImageCellSize(2, 2), imageService.CalculateCellSize(new ImageDimensions(20, 20), 2));
var image = new Image([1, 2, 3, 4], "image/png", imageService: imageService, dimensions: new ImageDimensions(20, 20))
{
MaxWidthCells = 2,
};
var imageLines = image.Render(4);
Assert.Equal(2, imageLines.Count);
Assert.True(image.ImageId is > 0);
Assert.StartsWith("\e_G", imageLines[0], StringComparison.Ordinal);
Assert.Contains(",C=1,", imageLines[0], StringComparison.Ordinal);
Assert.True(TerminalImageService.IsImageLine($"prefix {imageLines[0]} suffix"));
imageService.SetCapabilities(TerminalCapabilities.Conservative);
var fallback = new Image([1, 2, 3], "image/jpeg", imageService: imageService, dimensions: new ImageDimensions(8, 9))
{
FileName = "photo.jpg",
}.Render(80)[0];
Assert.Contains("[Image: photo.jpg [image/jpeg] 8x9]", fallback, StringComparison.Ordinal);
}
}