diff options
Diffstat (limited to 'src/Godosa.Core.Tests/Runs/Scripts/ScriptValidatorTests.cs')
| -rw-r--r-- | src/Godosa.Core.Tests/Runs/Scripts/ScriptValidatorTests.cs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/Godosa.Core.Tests/Runs/Scripts/ScriptValidatorTests.cs b/src/Godosa.Core.Tests/Runs/Scripts/ScriptValidatorTests.cs new file mode 100644 index 0000000..98dcc73 --- /dev/null +++ b/src/Godosa.Core.Tests/Runs/Scripts/ScriptValidatorTests.cs @@ -0,0 +1,63 @@ +using Godosa.Core.Runs.Scripts; +using Xunit; + +namespace Godosa.Core.Tests.Runs.Scripts; + +public class ScriptValidatorTests +{ + private static FakeGame Game() + { + var g = new FakeGame(); + g.ProbeFns["quest"] = _ => RunValue.Of(0); + g.ProbeFns["dialog-open"] = _ => RunValue.Of(false); + g.ActionTable["talk"] = new FakeAction(VerbKind.Player, _ => new ActionStart(), min: 1, max: 1); + g.ActionTable["cheat"] = new FakeAction(VerbKind.Debug, _ => new ActionStart(Status: StepStatus.Done), min: 1, max: 20); + return g; + } + + private static string Validate(string main, bool deterministic = true, FakeGame? game = null) => + string.Join(" | ", ScriptValidator.Validate( + ScriptLoader.Load("main.steps", new MemoryScriptSource(new Dictionary<string, string> { ["main.steps"] = main }), new Dictionary<string, string>()), + game ?? Game(), deterministic).Select(e => e.ToString())); + + [Fact] + public void ValidPlayerScript_NoErrors() => + Assert.Equal("", Validate("format 1\nmode player\nsetup:\n cheat gold 5\ntalk @obj(Virgil)\nwait dialog-open 2s\nexpect quest(1) >= accepted\nclick 1,2\nkey R\nlog \"hi\"")); + + [Theory] + [InlineData("format 1\nmode player\ndance", "main.steps:3: unknown verb dance")] + [InlineData("format 1\nmode player\nwalk-to 3,4", "main.steps:3: verb walk-to not supported by game fake")] + [InlineData("format 1\nmode player\nclick", "main.steps:3: verb click takes 1..1 arguments, got 0")] + [InlineData("format 1\nmode player\ncheat gold 5", "main.steps:3: debug verb cheat outside setup in player mode")] + [InlineData("format 1\nmode player\nwait nope 10", "main.steps:3: unknown probe or constant nope")] + [InlineData("format 1\nmode player\nexpect quest(1) >=", "main.steps:3: condition ends early")] + [InlineData("format 1\nmode player\ntalk @npc(Virgil)", "main.steps:3: unknown locator @npc")] + [InlineData("format 1\nmode player\ntry:\n key R", "main.steps:3: try needs a non-deterministic run")] + [InlineData("format 1\nmode player\noutput loud", "main.steps:3: output level must be quiet|checkpoints|labels|steps|trace")] + public void Errors(string main, string error) => Assert.Contains(error, Validate(main)); + + [Fact] + public void DebugMode_DebugVerbAnywhere() => Assert.Equal("", Validate("format 1\nmode debug\ncheat gold 5\nkey R")); + + [Fact] + public void Try_AllowedNonDeterministic() => Assert.Equal("", Validate("format 1\nmode player\ntry:\n key R", deterministic: false)); + + [Fact] + public void Rng_NeedsTheGameHook() + { + var g = Game(); + g.RngImpl = null; + Assert.Contains("main.steps:3: verb rng not supported by game fake", Validate("format 1\nmode player\nrng seed 4", game: g)); + } + + [Fact] + public void GameVerb_ShadowingALibVerbWithAnotherKind_Rejected() + { + var g = Game(); + g.ActionTable["click"] = new FakeAction(VerbKind.Debug, _ => new ActionStart()); + Assert.Contains("game verb click shadows a lib verb", Validate("format 1\nmode debug\nkey R", game: g)); + } + + [Fact] + public void LoaderErrorsComeThrough() => Assert.Contains("main.steps:3: unknown def x", Validate("format 1\nmode debug\ncall x()")); +} |
