using NUnit.Framework; using MultiversalDiplomacy.Model; namespace MultiversalDiplomacyTests; public class RegexTest { private static TestCaseData Test(string order, params string[] expected) => new TestCaseData(order, expected).SetName($"{{m}}(\"{order}\")"); static IEnumerable HoldRegexMatchesTestCases() { // Full specification yield return Test( "Army a-Munich/l@0 holds", "Army", "a", "Munich", "l", "0", "holds"); // Case insensitivity yield return Test( "fleet B-lon/C@0 H", "fleet", "B", "lon", "C", "0", "H"); // All optionals missing yield return Test( "ROM h", "", "", "ROM", "", "", "h"); // No confusion of unit type and timeline yield return Test( "A F-STP hold", "A", "F", "STP", "", "", "hold"); // Province with space in name yield return Test( "Fleet North Sea Hold", "Fleet", "", "North Sea", "", "", "Hold"); // Parenthesis location yield return Test( "F Spain(nc) holds", "F", "", "Spain", "nc", "", "holds"); } [TestCaseSource(nameof(HoldRegexMatchesTestCases))] public void HoldRegexMatches(string order, string[] expected) { OrderRegex re = new(World.WithStandardMap()); var match = re.Hold.Match(order); Assert.True(match.Success, "Match failed"); var (type, timeline, province, location, turn, holdVerb) = OrderRegex.ParseHold(match); string[] actual = [type, timeline, province, location, turn, holdVerb]; // Use EquivalentTo for more detailed error message Assert.That(actual, Is.EquivalentTo(expected), "Unexpected parse results"); Assert.That(actual, Is.EqualTo(expected), "Unexpected parse results"); } static IEnumerable MoveRegexMatchesTestCases() { static TestCaseData Test(string order, params string[] expected) => new TestCaseData(order, expected).SetName($"{{m}}(\"{order}\")"); // Full specification yield return Test( "Army a-Munich/l@0 - a-Tyrolia/l@0", "Army", "a", "Munich", "l", "0", "-", "a", "Tyrolia", "l", "0", ""); // Case insensitivity yield return Test( "fleet B-lon/C@0 - B-enc/W@0", "fleet", "B", "lon", "C", "0", "-", "B", "enc", "W", "0", ""); // All optionals missing yield return Test( "ROM - VIE", "", "", "ROM", "", "", "-", "", "VIE", "", "", ""); // No confusion of unit type and timeline yield return Test( "A F-STP - MOS", "A", "F", "STP", "", "", "-", "", "MOS", "", "", ""); // Elements with spaces yield return Test( "Fleet Western Mediterranean Sea moves to Gulf of Lyons via convoy", "Fleet", "", "Western Mediterranean Sea", "", "", "moves to", "", "Gulf of Lyons", "", "", "via convoy"); // Parenthesis location yield return Test( "F Spain(nc) - Spain(sc)", "F", "", "Spain", "nc", "", "-", "", "Spain", "sc", "", ""); // Timeline designation spells out a province yield return Test( "A tyr-MUN(vie) - mun-TYR/vie", "A", "tyr", "MUN", "vie", "", "-", "mun", "TYR", "vie", "", ""); } [TestCaseSource(nameof(MoveRegexMatchesTestCases))] public void MoveRegexMatches(string order, string[] expected) { OrderRegex re = new(World.WithStandardMap()); var match = re.Move.Match(order); Assert.True(match.Success, "Match failed"); var (type, timeline, province, location, turn, moveVerb, destTimeline, destProvince, destLocation, destTurn, viaConvoy) = OrderRegex.ParseMove(match); string[] actual = [type, timeline, province, location, turn, moveVerb, destTimeline, destProvince, destLocation, destTurn, viaConvoy]; // Use EquivalentTo for more detailed error message Assert.That(actual, Is.EquivalentTo(expected), "Unexpected parse results"); Assert.That(actual, Is.EqualTo(expected), "Unexpected parse results"); } }