aboutsummaryrefslogtreecommitdiffziptar.gz
path: root/src/Godosa.Core.Tests/Runs/Scripts/ConditionTests.cs
diff options
context:
space:
mode:
authorgodosa <godosa@godosa.eu>2026-10-06 23:39:36 +0200
committergodosa <godosa@godosa.eu>2026-10-06 23:39:36 +0200
commit39066900773e7857faf2d02e7ed51b71d219d97d (patch)
treeffab8e4ddd971626776c3b1f4ce1da2c186c2187 /src/Godosa.Core.Tests/Runs/Scripts/ConditionTests.cs
downloadgodosa-engine-39066900773e7857faf2d02e7ed51b71d219d97d.tar.gz
godosa-engine-39066900773e7857faf2d02e7ed51b71d219d97d.zip
godosa-engine: initial public history
Diffstat (limited to 'src/Godosa.Core.Tests/Runs/Scripts/ConditionTests.cs')
-rw-r--r--src/Godosa.Core.Tests/Runs/Scripts/ConditionTests.cs63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/Godosa.Core.Tests/Runs/Scripts/ConditionTests.cs b/src/Godosa.Core.Tests/Runs/Scripts/ConditionTests.cs
new file mode 100644
index 0000000..d14ea6a
--- /dev/null
+++ b/src/Godosa.Core.Tests/Runs/Scripts/ConditionTests.cs
@@ -0,0 +1,63 @@
+using Godosa.Core.Runs.Scripts;
+using Xunit;
+
+namespace Godosa.Core.Tests.Runs.Scripts;
+
+public class ConditionTests
+{
+ private sealed class Ctx : IConditionContext
+ {
+ public Dictionary<string, RunValue> Values { get; } = new()
+ {
+ ["quest(1)"] = RunValue.Of(2), ["map"] = RunValue.Of("tarant"), ["dialog-open"] = RunValue.Of(true),
+ ["global(gold)"] = RunValue.Of(500), ["alive"] = RunValue.Of(false),
+ };
+
+ public bool HasProbe(string name) => name is "quest" or "map" or "dialog-open" or "global" or "alive";
+
+ public RunValue Probe(string name, IReadOnlyList<string> args) =>
+ Values[args.Count == 0 ? name : $"{name}({string.Join(",", args)})"];
+
+ public long? Constant(string name) => name switch { "accepted" => 2, "completed" => 4, _ => null };
+ }
+
+ private static bool Test(string text) => ConditionParser.Parse(text).Test(new Ctx());
+
+ [Theory]
+ [InlineData("quest(1) >= accepted", true)]
+ [InlineData("quest(1) = completed", false)]
+ [InlineData("map = \"tarant\"", true)]
+ [InlineData("map != \"ashbury\"", true)]
+ [InlineData("dialog-open", true)]
+ [InlineData("alive", false)]
+ [InlineData("not alive", true)]
+ [InlineData("dialog-open and global(gold) > 499", true)]
+ [InlineData("alive or global(gold) < 100", false)]
+ [InlineData("not (alive or dialog-open)", false)]
+ [InlineData("alive or dialog-open and quest(1) = 2", true)] // and binds tighter than or
+ [InlineData("global(gold) <= 500", true)]
+ public void Evaluates(string text, bool expected) => Assert.Equal(expected, Test(text));
+
+ [Fact]
+ public void MismatchedTypes_Fault() =>
+ Assert.Equal("cannot compare tarant with 3", Assert.Throws<ScriptFault>(() => Test("map > 3")).Message);
+
+ [Theory]
+ [InlineData("quest(1) >=")]
+ [InlineData("(alive")]
+ [InlineData("alive alive")]
+ [InlineData("\"open")]
+ public void BadSyntax_Throws(string text) => Assert.Throws<FormatException>(() => ConditionParser.Parse(text));
+
+ [Fact]
+ public void ListsProbesAndBareNames()
+ {
+ var c = ConditionParser.Parse("quest(1) >= accepted and not dialog-open");
+ Assert.Equal(["quest(1)", "accepted", "dialog-open"], c.Probes().Select(p => p.Args.Count == 0 ? p.Name : $"{p.Name}({string.Join(",", p.Args)})"));
+ Assert.Equal(["accepted", "dialog-open"], c.Bare());
+ }
+
+ [Fact]
+ public void Describe_ListsProbeValues() =>
+ Assert.Equal("quest(1)=2 map=tarant", Cond.Describe(ConditionParser.Parse("quest(1) > 3 and map = \"x\""), new Ctx()));
+}