diff --git a/test/TinyTUI.Tests/Program.cs b/test/TinyTUI.Tests/Program.cs new file mode 100644 index 0000000..0e196c3 --- /dev/null +++ b/test/TinyTUI.Tests/Program.cs @@ -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 expected, T actual) +{ + if (!EqualityComparer.Default.Equals(expected, actual)) + throw new InvalidOperationException($"Expected: {expected}{Environment.NewLine}Actual: {actual}"); +} diff --git a/test/TinyTUI.Tests/TinyTUI.Tests.csproj b/test/TinyTUI.Tests/TinyTUI.Tests.csproj new file mode 100644 index 0000000..68e6e1e --- /dev/null +++ b/test/TinyTUI.Tests/TinyTUI.Tests.csproj @@ -0,0 +1,14 @@ + + + + Exe + net10.0 + enable + enable + + + + + + + diff --git a/ttui.slnx b/ttui.slnx index 358266e..de56e78 100644 --- a/ttui.slnx +++ b/ttui.slnx @@ -9,4 +9,5 @@ +