Add script-based test framework

This commit is contained in:
Tim Van Baak 2024-08-17 21:24:59 -07:00
parent b2461b3736
commit f9f8ea2b5a
13 changed files with 202 additions and 4 deletions

View File

@ -0,0 +1,43 @@
using MultiversalDiplomacy.Model;
namespace MultiversalDiplomacy.Script;
public class GameScriptHandler(World world, bool strict = false) : IScriptHandler
{
public string Prompt => "game> ";
public World World { get; private set; } = world;
/// <summary>
/// Whether unsuccessful commands should terminate the script.
/// </summary>
public bool Strict { get; } = strict;
private string? CurrentPower = null;
public IScriptHandler? HandleInput(string input)
{
if (input == "") {
CurrentPower = null;
return this;
}
// --- submits the orders for validation to allow for assertions about it
if (input == "---") {
// TODO submit orders
// TODO return a new handler that handles asserts
}
// A block of orders for a single power beginning with "{name}:"
if (World.Powers.FirstOrDefault(p => input.EqualsAnyCase($"{p}:"), null) is string power) {
CurrentPower = power;
return this;
}
// TODO parse order, including "{power} {order}" for one-offs
Console.WriteLine($"{CurrentPower}: {input}");
return this;
}
}

View File

@ -32,7 +32,7 @@ public class SetupScriptHandler(World world, bool strict = false) : IScriptHandl
case "help": case "help":
case "?": case "?":
Console.WriteLine("commands:"); Console.WriteLine("commands:");
Console.WriteLine(" begin: complete setup and start the game"); Console.WriteLine(" begin: complete setup and start the game (alias: ---)");
Console.WriteLine(" list <type>: list things in a game category"); Console.WriteLine(" list <type>: list things in a game category");
Console.WriteLine(" option <name> <value>: set a game option"); Console.WriteLine(" option <name> <value>: set a game option");
Console.WriteLine(" unit <power> <type> <province> [location]: add a unit to the game"); Console.WriteLine(" unit <power> <type> <province> [location]: add a unit to the game");
@ -40,7 +40,8 @@ public class SetupScriptHandler(World world, bool strict = false) : IScriptHandl
break; break;
case "begin": case "begin":
return null; // TODO case "---":
return new GameScriptHandler(World, Strict);
case "list" when args.Length == 1: case "list" when args.Length == 1:
Console.WriteLine("usage:"); Console.WriteLine("usage:");

View File

@ -1,8 +1,6 @@
using MultiversalDiplomacy.Adjudicate; using MultiversalDiplomacy.Adjudicate;
using MultiversalDiplomacy.Adjudicate.Decision;
using MultiversalDiplomacy.Model; using MultiversalDiplomacy.Model;
using MultiversalDiplomacy.Orders; using MultiversalDiplomacy.Orders;
using NUnit.Framework; using NUnit.Framework;
namespace MultiversalDiplomacyTests; namespace MultiversalDiplomacyTests;

View File

@ -18,4 +18,10 @@
<PackageReference Include="coverlet.collector" Version="3.1.0" /> <PackageReference Include="coverlet.collector" Version="3.1.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="Scripts/**/*.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,28 @@
using NUnit.Framework;
using MultiversalDiplomacy.Model;
using MultiversalDiplomacy.Script;
namespace MultiversalDiplomacyTests;
public class ScriptTests
{
static IEnumerable<TestCaseData> DatcTestCases()
{
foreach (var path in Directory.EnumerateFiles("Scripts/DATC"))
{
yield return new TestCaseData(path)
.SetName($"{{m}}({Path.GetFileNameWithoutExtension(path)})");
}
}
[TestCaseSource(nameof(DatcTestCases))]
public void Test_DATC(string testScriptPath)
{
IScriptHandler? handler = new SetupScriptHandler(World.WithStandardMap(), strict: true);
foreach (string input in File.ReadAllLines(testScriptPath)) {
handler = handler?.HandleInput(input);
Assert.That(handler, Is.Not.Null, $"Script quit unexpectedly at \"{input}\"");
}
}
}

View File

@ -0,0 +1,14 @@
# 6.A.1. TEST CASE, MOVING TO AN AREA THAT IS NOT A NEIGHBOUR
# Check if an illegal move (without convoy) will fail.
unit England F North Sea
---
England:
F North Sea - Picardy
---
# Order should fail.
assert North Sea holds

View File

@ -0,0 +1,14 @@
# 6.A.2. TEST CASE, MOVE ARMY TO SEA
# Check if an army could not be moved to open sea.
unit England A Liverpool
---
England:
A Liverpool - Irish Sea
---
# Order should fail.
assert Liverpool holds

View File

@ -0,0 +1,14 @@
# 6.A.3. TEST CASE, MOVE FLEET TO LAND
# Check whether a fleet cannot move to land.
unit Germany Army Kiel
---
Germany:
F Kiel - Munich
---
# Order should fail.
assert Kiel holds

View File

@ -0,0 +1,14 @@
# 6.A.4. TEST CASE, MOVE TO OWN SECTOR
# Moving to the same sector is an illegal move (2023 rulebook, page 7, "An Army can be ordered to move into an adjacent inland or coastal province.").
unit Germany Army Kiel
---
Germany:
F Kiel - Kiel
---
# Program should not crash.
assert Kiel holds

View File

@ -0,0 +1,31 @@
# 6.A.5. TEST CASE, MOVE TO OWN SECTOR WITH CONVOY
# Moving to the same sector is still illegal with convoy (2023 rulebook, page 7, "Note: An Army can move across water provinces from one coastal province to another...").
unit England F North Sea
unit England A Yorkshire
unit England A Liverpool
unit Germany F London
unit Germany A Wales
---
England:
F North Sea Convoys A Yorkshire - Yorkshire
A Yorkshire - Yorkshire
A Liverpool Supports A Yorkshire - Yorkshire
Germany:
F London - Yorkshire
A Wales Supports F London - Yorkshire
---
# The move of the army in Yorkshire is illegal.
assert Yorkshire holds
# This makes the support of Liverpool also illegal and without the support, the Germans have a stronger force.
assert North Sea holds
assert Liverpool holds
assert London moves
# The army in London dislodges the army in Yorkshire.
assert Wales supports
assert Yorkshire dislodged

View File

@ -0,0 +1,16 @@
# 6.A.6. TEST CASE, ORDERING A UNIT OF ANOTHER COUNTRY
# Check whether someone cannot order a unit that is not his own unit.
unit England F London
# A German unit is included here so Germany isn't considered dead
unit Germany A Munich
---
Germany:
F London - North Sea
---
# Order should fail.
assert London holds

View File

@ -0,0 +1,16 @@
# 6.A.7. TEST CASE, ONLY ARMIES CAN BE CONVOYED
# A fleet cannot be convoyed.
unit England F London
unit England North Sea
---
England:
F London - Belgium
F North Sea Convoys A London - Belgium
---
# Move from London to Belgium should fail.
assert London holds

View File

@ -0,0 +1,3 @@
# DATC test scripts
These test scripts are copied from DATC v3.1.