diff options
Diffstat (limited to 'src/Godosa.Core.Tests/Runs/Scripts/VarsTests.cs')
| -rw-r--r-- | src/Godosa.Core.Tests/Runs/Scripts/VarsTests.cs | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/Godosa.Core.Tests/Runs/Scripts/VarsTests.cs b/src/Godosa.Core.Tests/Runs/Scripts/VarsTests.cs new file mode 100644 index 0000000..c6d3286 --- /dev/null +++ b/src/Godosa.Core.Tests/Runs/Scripts/VarsTests.cs @@ -0,0 +1,84 @@ +using Godosa.Core.Runs.Scripts; +using Xunit; + +namespace Godosa.Core.Tests.Runs.Scripts; + +public class VarsTests +{ + private static readonly Dictionary<string, string> Values = new() + { + ["res"] = "1920x1080", ["hours"] = "8", ["ui.rest.8"] = "400,300", ["a"] = "b", ["b"] = "deep", + }; + + private static string Expand(string text) => VarExpander.Expand(text, n => Values.GetValueOrDefault(n), + p => p == "global(gold)" ? RunValue.Of(1250) : throw new ScriptFault($"no probe {p}")); + + [Theory] + [InlineData("ui/${res}.vars", "ui/1920x1080.vars")] + [InlineData("click ${ui.rest.${hours}}", "click 400,300")] + [InlineData("${${a}}", "deep")] + [InlineData("gold ${probe:global(gold)}", "gold 1250")] + [InlineData("cost $5 and $", "cost $5 and $")] // review focus 4: lone $ is literal + [InlineData("no vars", "no vars")] + public void Expand_Values(string text, string expected) => Assert.Equal(expected, Expand(text)); + + [Theory] + [InlineData("${missing}", "unresolved variable ${missing}")] + [InlineData("x ${a", "unclosed ${ in 'x ${a'")] + [InlineData("${}", "empty ${}")] + public void Expand_Errors_AreFaults(string text, string message) => + Assert.Equal(message, Assert.Throws<ScriptFault>(() => Expand(text)).Message); + + [Fact] + public void Names_InnermostPlainOnly() => + Assert.Equal(["hours", "res"], VarExpander.Names("${ui.${hours}} ${res} ${probe:quest(1)}").Order()); + + [Fact] + public void VarsFile_ParsesAndReportsBadLines() + { + var (values, errors) = VarsFile.Parse("ui/hd.vars", "# hd\nui.answer1 = 412,520\n\nui.rest.8=400,300\nbroken line\n"); + Assert.Equal("412,520", values["ui.answer1"]); + Assert.Equal("400,300", values["ui.rest.8"]); + Assert.Equal(["ui/hd.vars:5: bad vars line (name = value)"], errors.Select(e => e.ToString())); + } + + [Fact] + public void Scopes_SetGoesToLocalOrRoot() + { + var s = new VarScopes(OutputLevel.Labels); + s.Set("g", "1"); + s.Push(local: false, OutputLevel.Labels, []); // include + s.Set("inc", "2"); // global: root + s.Push(local: true, OutputLevel.Labels, [new("p", "x")]); // def call + s.Set("loc", "3"); + Assert.Equal(("1", "2", "3", "x"), (s.Get("g"), s.Get("inc"), s.Get("loc"), s.Get("p"))); + s.Pop(); + Assert.Null(s.Get("loc")); + Assert.Null(s.Get("p")); + s.Pop(); + Assert.Equal("2", s.Get("inc")); + } + + [Fact] + public void Scopes_OutputLevelRestoredOnPop() + { + var s = new VarScopes(OutputLevel.Labels); + s.Push(local: false, s.Level, []); + s.Level = OutputLevel.Trace; + s.Pop(); + Assert.Equal(OutputLevel.Labels, s.Level); + } + + [Fact] + public void Scopes_SnapshotRestore_RoundTrips() + { + var s = new VarScopes(OutputLevel.Labels); + s.Set("g", "1"); + s.Push(local: true, OutputLevel.Steps, [new("p", "x")]); + var copy = new VarScopes(OutputLevel.Quiet); + copy.Restore(s.Snapshot()); + Assert.Equal(("1", "x", OutputLevel.Steps), (copy.Get("g"), copy.Get("p"), copy.Level)); + s.Set("p", "changed"); + Assert.Equal("x", copy.Get("p")); // deep copy + } +} |
