Files
mrgameeng/tests/MrGameEng.DevConsole.Tests/DevConsoleTests.cs
T
Leonid Pershin fd6343bd09
CI / build-test (push) Failing after 1m8s
@
Add MrGameEng.AI utility-AI module; format codebase with CSharpier

New MrGameEng.AI module (ResponseCurve, Consideration, UtilityAction,
UtilityAi selector, Blackboard) plus CSharpier formatting applied across
the whole engine. Documents the CSharpier convention in CLAUDE.md.
@
2026-06-12 07:19:10 +03:00

191 lines
5.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Text;
using MrGameEng.Core;
using Xunit;
namespace MrGameEng.DevConsole.Tests;
public class DevConsoleTests
{
private static string Visible(DevConsole console, int lines = 50)
{
var sb = new StringBuilder();
console.BuildVisibleText(sb, lines);
return sb.ToString();
}
[Fact]
public void Execute_RunsRegisteredCommand_WithArguments()
{
using var console = new DevConsole();
string[]? received = null;
console.Register("test", "test command", (_, args) => received = args);
console.Execute("test one two");
Assert.NotNull(received);
Assert.Equal(["one", "two"], received!);
Assert.Contains("> test one two", Visible(console));
}
[Fact]
public void Execute_UnknownCommand_ReportsWithoutThrowing()
{
using var console = new DevConsole();
console.Execute("nosuchcommand");
Assert.Contains("unknown command 'nosuchcommand'", Visible(console));
}
[Fact]
public void Execute_HandlerException_IsCaughtAndLogged()
{
using var console = new DevConsole();
console.Register("boom", "throws", (_, _) => throw new InvalidOperationException("kaboom"));
console.Execute("boom");
Assert.Contains("[err] kaboom", Visible(console));
}
[Fact]
public void RingBuffer_OverflowDropsOldestLines()
{
using var console = new DevConsole(capacity: 4);
for (var i = 0; i < 10; i++)
{
console.WriteLine($"line{i}");
}
var visible = Visible(console);
Assert.DoesNotContain("line5", visible);
Assert.Contains("line6", visible);
Assert.Contains("line9", visible);
}
[Fact]
public void BuildVisibleText_RespectsWindowAndScroll()
{
using var console = new DevConsole();
for (var i = 0; i < 10; i++)
{
console.WriteLine($"line{i}");
}
var sb = new StringBuilder();
console.BuildVisibleText(sb, 3);
Assert.Equal("line7\nline8\nline9", sb.ToString());
console.Scroll(+2);
console.BuildVisibleText(sb, 3);
Assert.StartsWith("line5\nline6\nline7", sb.ToString());
}
[Fact]
public void History_NavigatesUpAndDown()
{
using var console = new DevConsole();
console.Register("a", "", (_, _) => { });
console.Execute("a 1");
console.Execute("a 2");
Assert.Equal("a 2", console.HistoryPrevious());
Assert.Equal("a 1", console.HistoryPrevious());
Assert.Equal("a 1", console.HistoryPrevious()); // упёрлись в начало
Assert.Equal("a 2", console.HistoryNext());
Assert.Equal("", console.HistoryNext()); // за последним — пустая строка
}
[Fact]
public void Complete_SingleMatch_CompletesWithTrailingSpace()
{
using var console = new DevConsole();
Assert.Equal("echo ", console.Complete("ec"));
}
[Fact]
public void Complete_MultipleMatches_ReturnsCommonPrefix_AndListsOptions()
{
using var console = new DevConsole();
console.Register("spawn", "", (_, _) => { });
console.Register("spawnall", "", (_, _) => { });
var completed = console.Complete("sp");
Assert.Equal("spawn", completed);
Assert.Contains("spawn spawnall", Visible(console));
}
[Fact]
public void LogMessages_AreCaptured_WithLevelTags()
{
using var console = new DevConsole();
Log.Info("plain info");
Log.Warning("careful");
var visible = Visible(console);
Assert.Contains("plain info", visible);
Assert.Contains("[warn] careful", visible);
}
[Fact]
public void Execute_QuotedArguments_KeptAsSingleArgument()
{
using var console = new DevConsole();
string[]? received = null;
console.Register("say", "", (_, args) => received = args);
console.Execute("say \"hello world\" plain \"\"");
Assert.Equal(["hello world", "plain", ""], received!);
}
[Fact]
public void Execute_UnterminatedQuote_RunsToEndOfLine()
{
using var console = new DevConsole();
string[]? received = null;
console.Register("say", "", (_, args) => received = args);
console.Execute("say \"one two");
Assert.Equal(["one two"], received!);
}
[Fact]
public void History_IsCapped_OldestEntriesDropped()
{
using var console = new DevConsole();
console.Register("n", "", (_, _) => { });
for (var i = 0; i < 300; i++)
{
console.Execute($"n {i}");
}
string? oldest = null;
for (var i = 0; i < 400; i++)
{
oldest = console.HistoryPrevious(); // упирается в самую старую сохранённую
}
Assert.Equal("n 44", oldest); // 300 256 (лимит) = 44
}
[Fact]
public void Revision_ChangesOnlyOnVisibleChanges()
{
using var console = new DevConsole();
var before = console.Revision;
console.WriteLine("x");
Assert.NotEqual(before, console.Revision);
before = console.Revision;
_ = Visible(console); // чтение не меняет ревизию
Assert.Equal(before, console.Revision);
}
}