aboutsummaryrefslogtreecommitdiffziptar.gz
path: root/src/Godosa.Core.Tests/Runs/Scripts/RunReportTests.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Godosa.Core.Tests/Runs/Scripts/RunReportTests.cs')
-rw-r--r--src/Godosa.Core.Tests/Runs/Scripts/RunReportTests.cs83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/Godosa.Core.Tests/Runs/Scripts/RunReportTests.cs b/src/Godosa.Core.Tests/Runs/Scripts/RunReportTests.cs
new file mode 100644
index 0000000..00ee4b0
--- /dev/null
+++ b/src/Godosa.Core.Tests/Runs/Scripts/RunReportTests.cs
@@ -0,0 +1,83 @@
+using System.Text.Json;
+using Godosa.Core.Runs;
+using Godosa.Core.Runs.Scripts;
+using Xunit;
+
+namespace Godosa.Core.Tests.Runs.Scripts;
+
+public sealed class RunReportTests : IDisposable
+{
+ private readonly string _dir = Path.Combine(AppContext.BaseDirectory, "rs-tmp", Guid.NewGuid().ToString("N"));
+
+ public void Dispose()
+ {
+ if (Directory.Exists(_dir))
+ Directory.Delete(_dir, recursive: true);
+ }
+
+ private static (ScriptRunner Runner, RunResult Result, List<string> Output) Run(string main, FakeGame g, ScriptRunOptions o, Dictionary<string, string>? files = null)
+ {
+ var all = new Dictionary<string, string>(files ?? []) { ["main.steps"] = main };
+ var output = new List<string>();
+ var runner = new ScriptRunner(ScriptLoader.Load("main.steps", new MemoryScriptSource(all), new Dictionary<string, string>()), g, o, output.Add);
+ return (runner, runner.Run(10_000), output);
+ }
+
+ [Fact]
+ public void Failure_ReportHoldsChainStepReasonRecentDumpVars()
+ {
+ var g = new FakeGame { State = 7 };
+ g.ProbeFns["quest"] = _ => RunValue.Of(1);
+ var (runner, _, _) = Run("format 1\nmode player\nset who = Gilbert\nkey A\ninclude act2.steps", g, new ScriptRunOptions { ReportDir = _dir },
+ new() { ["act2.steps"] = "format 1\nstep talk-gilbert:\n key B\n expect quest(5) >= accepted" });
+ var f = runner.Report!.Failure!;
+ Assert.Equal("act2.steps:4", f.At);
+ Assert.Equal(["main.steps:5"], f.Chain);
+ Assert.Equal(("expect quest(5) >= accepted", "talk-gilbert"), (f.Step, f.Label));
+ Assert.Equal("expect failed: quest(5) >= accepted (quest(5)=1)", f.Reason);
+ Assert.Equal(["main.steps:4 key A f=2", "act2.steps:3 key B f=4"], f.Recent);
+ Assert.Equal("state=7 frame=4", f.Dump);
+ Assert.Equal("Gilbert", f.Vars["who"]);
+ Assert.True(File.Exists(Path.Combine(_dir, "report.txt")));
+ Assert.True(File.Exists(Path.Combine(_dir, "fail.snap")));
+ var json = JsonDocument.Parse(File.ReadAllText(Path.Combine(_dir, "report.json")));
+ Assert.Equal("Failed", json.RootElement.GetProperty("Outcome").GetString());
+ var text = File.ReadAllText(Path.Combine(_dir, "report.txt"));
+ Assert.Contains("main.steps:5 → act2.steps:4", text);
+ Assert.Contains("state=7 frame=4", text);
+ }
+
+ [Fact]
+ public void Recent_KeepsLast20()
+ {
+ var g = new FakeGame();
+ g.ProbeFns["no"] = _ => RunValue.Of(false);
+ var steps = string.Join("\n", Enumerable.Range(1, 25).Select(n => $"key K{n}"));
+ var (runner, _, _) = Run($"format 1\nmode player\n{steps}\nexpect no", g, new ScriptRunOptions());
+ var recent = runner.Report!.Failure!.Recent;
+ Assert.Equal(20, recent.Count);
+ Assert.StartsWith("main.steps:8 key K6", recent[0]);
+ }
+
+ [Fact]
+ public void Summary_StepsFramesCheckpointsDigests()
+ {
+ var g = new FakeGame { State = 3 };
+ var (runner, r, output) = Run("format 1\nmode player\nkey A\ncheckpoint one\nstep s:\n key B", g, new ScriptRunOptions { Seed = 9 });
+ var rep = runner.Report!;
+ Assert.Equal((RunOutcome.Passed, 4L, 2, 9UL), (rep.Outcome, rep.Frames, rep.Steps, rep.Seed));
+ // Digest = State * 1_000_003 + Frame (FakeGame), at frame 2: 3 * 1000003 + 2 = 3000011.
+ Assert.Equal([new CheckpointRecord("one", 2, 3000011UL.ToString("x16"), "replayed")], rep.Checkpoints);
+ Assert.Contains(DigestLine.Format(2, 2 / 60.0, 3000011UL), output);
+ Assert.Contains(DigestLine.Format(4, 4 / 60.0, 3000013UL), output); // after the labelled step
+ }
+
+ [Fact]
+ public void NonDeterministic_NoDigestLines_FlagInReport()
+ {
+ var (runner, _, output) = Run("format 1\nmode player\ncheckpoint one", new FakeGame(), new ScriptRunOptions { Deterministic = false });
+ Assert.DoesNotContain(output, l => l.StartsWith("digest "));
+ Assert.False(runner.Report!.Deterministic);
+ Assert.Contains("deterministic: no", ReportWriter.Text(runner.Report));
+ }
+}