Add hold-order assertion for unparseable orders
This commit is contained in:
parent
4096e4d517
commit
7773c571e3
|
@ -58,6 +58,14 @@ public class AdjudicationQueryScriptHandler(
|
|||
private ScriptResult EvaluateAssertion(string assertion)
|
||||
{
|
||||
var args = assertion.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries);
|
||||
OrderParser re = new(World);
|
||||
Regex prov = new($"^{re.FullLocation}$", RegexOptions.IgnoreCase);
|
||||
Match match;
|
||||
string timeline;
|
||||
IEnumerable<Season> seasonsInTimeline;
|
||||
int turn;
|
||||
Season season;
|
||||
Province province;
|
||||
|
||||
switch (args[0])
|
||||
{
|
||||
|
@ -67,28 +75,56 @@ public class AdjudicationQueryScriptHandler(
|
|||
case "false":
|
||||
return ScriptResult.Fail("assert false", this);
|
||||
|
||||
case "order-valid":
|
||||
case "order-invalid":
|
||||
OrderParser re = new(World);
|
||||
Regex prov = new($"^{re.FullLocation}$", RegexOptions.IgnoreCase);
|
||||
Match match = prov.Match(args[1]);
|
||||
if (!match.Success) return ScriptResult.Fail($"Could not parse province from \"{args[1]}\"", this);
|
||||
case "hold-order":
|
||||
// The hold-order assertion primarily serves to verify that a unit's order was illegal in cases where
|
||||
// a written non-hold order was rejected before order validation and replaced with a hold order.
|
||||
match = prov.Match(args[1]);
|
||||
|
||||
string timeline = match.Groups[1].Length > 0
|
||||
timeline = match.Groups[1].Length > 0
|
||||
? match.Groups[1].Value
|
||||
: Season.First.Timeline;
|
||||
var seasonsInTimeline = World.Timelines.Seasons.Where(season => season.Timeline == timeline);
|
||||
seasonsInTimeline = World.Timelines.Seasons.Where(season => season.Timeline == timeline);
|
||||
if (!seasonsInTimeline.Any()) return ScriptResult.Fail($"No seasons in timeline {timeline}", this);
|
||||
|
||||
int turn = match.Groups[4].Length > 0
|
||||
turn = match.Groups[4].Length > 0
|
||||
? int.Parse(match.Groups[4].Value)
|
||||
// If turn is unspecified, use the second-latest turn in the timeline,
|
||||
// since we want to assert against the subjects of the orders just adjudicated,
|
||||
// and adjudication created a new set of seasons.
|
||||
: seasonsInTimeline.Max(season => season.Turn) - 1;
|
||||
Season season = new(timeline, turn);
|
||||
season = new(timeline, turn);
|
||||
|
||||
Province province = World.Map.Provinces.Single(province => province.Is(match.Groups[2].Value));
|
||||
province = World.Map.Provinces.Single(province => province.Is(match.Groups[2].Value));
|
||||
|
||||
var matchingHolds = Validations.Where(val
|
||||
=> val.Valid
|
||||
&& val.Order is HoldOrder hold
|
||||
&& hold.Unit.Season == season
|
||||
&& World.Map.GetLocation(hold.Unit.Location).ProvinceName == province.Name);
|
||||
if (!matchingHolds.Any()) return ScriptResult.Fail("No matching holds");
|
||||
|
||||
return ScriptResult.Succeed(this);
|
||||
|
||||
case "order-valid":
|
||||
case "order-invalid":
|
||||
match = prov.Match(args[1]);
|
||||
if (!match.Success) return ScriptResult.Fail($"Could not parse province from \"{args[1]}\"", this);
|
||||
|
||||
timeline = match.Groups[1].Length > 0
|
||||
? match.Groups[1].Value
|
||||
: Season.First.Timeline;
|
||||
seasonsInTimeline = World.Timelines.Seasons.Where(season => season.Timeline == timeline);
|
||||
if (!seasonsInTimeline.Any()) return ScriptResult.Fail($"No seasons in timeline {timeline}", this);
|
||||
|
||||
turn = match.Groups[4].Length > 0
|
||||
? int.Parse(match.Groups[4].Value)
|
||||
// If turn is unspecified, use the second-latest turn in the timeline,
|
||||
// since we want to assert against the subjects of the orders just adjudicated,
|
||||
// and adjudication created a new set of seasons.
|
||||
: seasonsInTimeline.Max(season => season.Turn) - 1;
|
||||
season = new(timeline, turn);
|
||||
|
||||
province = World.Map.Provinces.Single(province => province.Is(match.Groups[2].Value));
|
||||
|
||||
var matching = Validations.Where(val
|
||||
=> val.Order is UnitOrder order
|
||||
|
@ -106,20 +142,20 @@ public class AdjudicationQueryScriptHandler(
|
|||
|
||||
case "has-past":
|
||||
Regex hasPast = new($"^([a-z]+[0-9]+)>([a-z]+[0-9]+)$");
|
||||
Match hpMatch = hasPast.Match(args[1]);
|
||||
if (!hpMatch.Success) return ScriptResult.Fail("Expected format s1>s2", this);
|
||||
match = hasPast.Match(args[1]);
|
||||
if (!match.Success) return ScriptResult.Fail("Expected format s1>s2", this);
|
||||
|
||||
Season future = new(hpMatch.Groups[1].Value);
|
||||
Season future = new(match.Groups[1].Value);
|
||||
if (!World.Timelines.Pasts.TryGetValue(future.Key, out Season? actual)) {
|
||||
return ScriptResult.Fail($"No such season \"{future}\"");
|
||||
}
|
||||
|
||||
Season expected = new(hpMatch.Groups[2].Value);
|
||||
Season expected = new(match.Groups[2].Value);
|
||||
if (actual != expected) return ScriptResult.Fail(
|
||||
$"Expected past of {future} to be {expected}, but it was {actual}");
|
||||
return ScriptResult.Succeed(this);
|
||||
|
||||
case "holds":
|
||||
case "not-dislodged":
|
||||
case "dislodged":
|
||||
re = new(World);
|
||||
prov = new($"^{re.FullLocation}$", RegexOptions.IgnoreCase);
|
||||
|
@ -149,7 +185,7 @@ public class AdjudicationQueryScriptHandler(
|
|||
if (!matchingDislodges.Any()) return ScriptResult.Fail("No matching dislodge decisions");
|
||||
var isDislodged = matchingDislodges.Cast<IsDislodged>().First();
|
||||
|
||||
if (args[0] == "holds" && isDislodged.Outcome != false) {
|
||||
if (args[0] == "not-dislodged" && isDislodged.Outcome != false) {
|
||||
return ScriptResult.Fail($"Adjudication {isDislodged} is true");
|
||||
}
|
||||
if (args[0] == "dislodged" && isDislodged.Outcome != true) {
|
||||
|
|
|
@ -133,6 +133,24 @@ public class ReplTest
|
|||
repl.AssertFails("assert has-past a2>a1");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AssertHoldOrder()
|
||||
{
|
||||
var repl = StandardRepl();
|
||||
|
||||
repl.ExecuteAll("""
|
||||
unit Germany A Mun
|
||||
---
|
||||
""");
|
||||
repl.AssertFails("Germany A Mun - The Sun");
|
||||
repl.Execute("---");
|
||||
|
||||
// Order is invalid
|
||||
repl.Execute("assert hold-order Mun");
|
||||
// order-invalid requires the order be parsable, which this isn't
|
||||
repl.AssertFails("assert order-invalid Mun");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AssertMovement()
|
||||
{
|
||||
|
@ -241,7 +259,7 @@ public class ReplTest
|
|||
""");
|
||||
|
||||
// Move repelled
|
||||
repl.Execute("assert holds Tyr");
|
||||
repl.Execute("assert not-dislodged Tyr");
|
||||
repl.AssertFails("assert dislodged Tyr");
|
||||
|
||||
repl.ExecuteAll("""
|
||||
|
@ -253,6 +271,6 @@ public class ReplTest
|
|||
|
||||
// Move succeeds
|
||||
repl.Execute("assert dislodged Tyr");
|
||||
repl.AssertFails("assert holds Tyr");
|
||||
repl.AssertFails("assert not-dislodged Tyr");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue