test: add component behavior coverage

- add lightweight component test runner

- cover markdown loader select list and editor behavior
This commit is contained in:
chuan
2026-06-04 00:14:38 +08:00
Unverified
parent a9297ba5cd
commit 7ffda66f7d
3 changed files with 136 additions and 0 deletions
+121
View File
@@ -0,0 +1,121 @@
using TinyTUI.Components;
using TinyTUI.Input;
var tests = new (string Name, Action Test)[]
{
("Markdown renders supported block markers", MarkdownRendersSupportedBlockMarkers),
("Loader cycles frames", LoaderCyclesFrames),
("SelectList handles navigation and submit", SelectListHandlesNavigationAndSubmit),
("Editor handles unicode text and backspace", EditorHandlesUnicodeTextAndBackspace),
("Editor handles multiline editing", EditorHandlesMultilineEditing),
};
var failed = 0;
foreach (var (name, test) in tests)
{
try
{
test();
Console.WriteLine($"PASS {name}");
}
catch (Exception ex)
{
failed++;
Console.WriteLine($"FAIL {name}");
Console.WriteLine(ex.Message);
}
}
if (failed > 0)
return failed;
Console.WriteLine($"PASS {tests.Length} tests");
return 0;
static void MarkdownRendersSupportedBlockMarkers()
{
var markdown = new Markdown(
"# title\n" +
"## subtitle\n" +
"- item\n" +
"> quote\n" +
"plain **bold** and `code`");
var lines = markdown.Render(80);
AssertEqual("TITLE", lines[0]);
AssertEqual("SUBTITLE", lines[1]);
AssertEqual("* item", lines[2]);
AssertEqual("| quote", lines[3]);
AssertEqual("plain bold and code", lines[4]);
}
static void LoaderCyclesFrames()
{
var loader = new Loader { Message = "work", Frames = ["a", "b"] };
AssertEqual("a work", loader.Render(80)[0]);
loader.Tick();
AssertEqual("b work", loader.Render(80)[0]);
loader.Tick();
AssertEqual("a work", loader.Render(80)[0]);
}
static void SelectListHandlesNavigationAndSubmit()
{
var submitted = string.Empty;
var submittedIndex = -1;
var select = new SelectList { Height = 2 };
select.SetItems(["one", "two", "three"]);
select.OnSubmitted = (item, index) =>
{
submitted = item;
submittedIndex = index;
};
select.HandleInput(Key(KeyNames.Down));
select.HandleInput(Key(KeyNames.Down));
select.HandleInput(Key(KeyNames.Down));
select.HandleInput(Key(KeyNames.Enter));
AssertEqual(2, select.SelectedIndex);
AssertEqual("three", submitted);
AssertEqual(2, submittedIndex);
AssertEqual("> three", select.Render(80)[1]);
}
static void EditorHandlesUnicodeTextAndBackspace()
{
var editor = new Editor();
editor.HandleInput(Text("a😀"));
editor.HandleInput(Key(KeyNames.Backspace));
AssertEqual("a", editor.Value);
}
static void EditorHandlesMultilineEditing()
{
var editor = new Editor();
editor.HandleInput(Text("abc"));
editor.HandleInput(Key(KeyNames.Left));
editor.HandleInput(Key(KeyNames.Enter));
editor.HandleInput(Text("x"));
AssertEqual("ab\nxc", editor.Value);
}
static TuiInputEvent Text(string value) => new(TuiInputEventKind.Text, value);
static TuiInputEvent Key(string value) => new(TuiInputEventKind.Key, value);
static void AssertEqual<T>(T expected, T actual)
{
if (!EqualityComparer<T>.Default.Equals(expected, actual))
throw new InvalidOperationException($"Expected: {expected}{Environment.NewLine}Actual: {actual}");
}
+14
View File
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\TinyTUI\TinyTUI.csproj" />
</ItemGroup>
</Project>
+1
View File
@@ -9,4 +9,5 @@
</Folder>
<Project Path="src/Example/Example.csproj" Id="6656c1ec-b220-4e7a-8875-5a97a85afbc1" />
<Project Path="src/TinyTUI/TinyTUI.csproj" Id="f39199aa-6947-4951-b952-a1588045505e" />
<Project Path="test/TinyTUI.Tests/TinyTUI.Tests.csproj" />
</Solution>