2024-08-13 04:47:28 +00:00
|
|
|
using System.Text.Json;
|
|
|
|
|
2024-08-15 04:12:58 +00:00
|
|
|
using MultiversalDiplomacy.Adjudicate.Decision;
|
2024-08-13 04:47:28 +00:00
|
|
|
using MultiversalDiplomacy.Model;
|
|
|
|
|
|
|
|
using NUnit.Framework;
|
|
|
|
|
2024-08-28 21:27:35 +00:00
|
|
|
using static MultiversalDiplomacyTests.Adjudicator;
|
|
|
|
|
2024-08-13 04:47:28 +00:00
|
|
|
namespace MultiversalDiplomacyTests;
|
|
|
|
|
|
|
|
public class SerializationTest
|
|
|
|
{
|
2024-08-14 16:16:53 +00:00
|
|
|
private JsonSerializerOptions Options = new(World.JsonOptions) {
|
2024-08-14 05:14:55 +00:00
|
|
|
WriteIndented = true,
|
|
|
|
};
|
|
|
|
|
2024-08-15 23:40:23 +00:00
|
|
|
[Test]
|
|
|
|
public void SerializeRoundTrip_Timelines()
|
|
|
|
{
|
|
|
|
Timelines one = Timelines.Create();
|
|
|
|
|
|
|
|
string serial1 = JsonSerializer.Serialize(one, Options);
|
|
|
|
Timelines two = JsonSerializer.Deserialize<Timelines>(serial1, Options)
|
|
|
|
?? throw new AssertionException("Failed to deserialize");
|
|
|
|
|
|
|
|
Assert.That(two.Next, Is.EqualTo(one.Next), "Failed to reserialize next timeline");
|
|
|
|
Assert.That(two.Pasts, Is.EquivalentTo(one.Pasts), "Failed to reserialize pasts");
|
|
|
|
|
|
|
|
Timelines three = two
|
|
|
|
.WithNewSeason(Season.First, out var a1)
|
|
|
|
.WithNewSeason(a1, out var a2)
|
|
|
|
.WithNewSeason(a1, out var b2);
|
|
|
|
|
|
|
|
string serial2 = JsonSerializer.Serialize(three, Options);
|
|
|
|
Timelines four = JsonSerializer.Deserialize<Timelines>(serial2, Options)
|
|
|
|
?? throw new AssertionException("Failed to deserialize");
|
|
|
|
|
|
|
|
Assert.That(four.Next, Is.EqualTo(three.Next), "Failed to reserialize next timeline");
|
|
|
|
Assert.That(four.Pasts, Is.EquivalentTo(three.Pasts), "Failed to reserialize pasts");
|
|
|
|
}
|
|
|
|
|
2024-08-13 15:17:34 +00:00
|
|
|
[Test]
|
|
|
|
public void SerializeRoundTrip_NewGame()
|
|
|
|
{
|
|
|
|
World world = World.WithStandardMap();
|
2024-08-14 05:14:55 +00:00
|
|
|
|
|
|
|
JsonElement document = JsonSerializer.SerializeToDocument(world, Options).RootElement;
|
|
|
|
Assert.That(
|
|
|
|
document.EnumerateObject().Select(prop => prop.Name),
|
|
|
|
Is.EquivalentTo(new List<string> {
|
|
|
|
"mapType",
|
|
|
|
"units",
|
|
|
|
"retreatingUnits",
|
|
|
|
"orderHistory",
|
|
|
|
"options",
|
|
|
|
"timelines",
|
|
|
|
}));
|
2024-08-15 20:51:41 +00:00
|
|
|
|
|
|
|
string serialized = JsonSerializer.Serialize(world, Options);
|
|
|
|
World? deserialized = JsonSerializer.Deserialize<World>(serialized, Options);
|
|
|
|
|
|
|
|
Assert.That(deserialized, Is.Not.Null, "Failed to deserialize");
|
|
|
|
Assert.That(deserialized!.Map, Is.Not.Null, "Failed to deserialize map");
|
|
|
|
Assert.That(deserialized!.Units, Is.Not.Null, "Failed to deserialize units");
|
|
|
|
Assert.That(deserialized!.RetreatingUnits, Is.Not.Null, "Failed to deserialize retreats");
|
|
|
|
Assert.That(deserialized!.OrderHistory, Is.Not.Null, "Failed to deserialize history");
|
|
|
|
Assert.That(deserialized!.Timelines, Is.Not.Null, "Failed to deserialize timelines");
|
|
|
|
Assert.That(deserialized!.Timelines.Pasts, Is.Not.Null, "Failed to deserialize timeline pasts");
|
|
|
|
Assert.That(deserialized!.Timelines.Next, Is.EqualTo(world.Timelines.Next));
|
|
|
|
Assert.That(deserialized!.Options, Is.Not.Null, "Failed to deserialize options");
|
2024-08-13 15:17:34 +00:00
|
|
|
}
|
|
|
|
|
2024-08-13 04:47:28 +00:00
|
|
|
[Test]
|
|
|
|
public void SerializeRoundTrip_MDATC_3_A_2()
|
|
|
|
{
|
|
|
|
// Set up MDATC 3.A.2
|
2024-08-28 21:27:35 +00:00
|
|
|
TestCaseBuilder setup = new(World.WithStandardMap(), MovementPhase);
|
2024-08-13 04:47:28 +00:00
|
|
|
setup[("a", 0)]
|
|
|
|
.GetReference(out Season s0)
|
|
|
|
["Germany"]
|
|
|
|
.Army("Mun").MovesTo("Tyr").GetReference(out var mun0)
|
|
|
|
["Austria"]
|
|
|
|
.Army("Tyr").Holds().GetReference(out var tyr0);
|
|
|
|
|
|
|
|
setup.ValidateOrders();
|
|
|
|
Assert.That(mun0, Is.Valid);
|
|
|
|
Assert.That(tyr0, Is.Valid);
|
|
|
|
setup.AdjudicateOrders();
|
|
|
|
Assert.That(mun0, Is.Repelled);
|
|
|
|
Assert.That(tyr0, Is.NotDislodged);
|
|
|
|
setup.UpdateWorld();
|
|
|
|
|
2024-08-15 23:36:50 +00:00
|
|
|
Assert.That(setup.World.OrderHistory[s0.Key].Orders.Count, Is.GreaterThan(0), "Missing orders");
|
|
|
|
Assert.That(setup.World.OrderHistory[s0.Key].DoesMoveOutcomes.Count, Is.GreaterThan(0), "Missing moves");
|
|
|
|
Assert.That(setup.World.OrderHistory[s0.Key].IsDislodgedOutcomes.Count, Is.GreaterThan(0), "Missing dislodges");
|
2024-08-15 01:45:35 +00:00
|
|
|
|
2024-08-14 16:51:18 +00:00
|
|
|
// Serialize and deserialize the world
|
2024-08-14 05:14:55 +00:00
|
|
|
string serialized = JsonSerializer.Serialize(setup.World, Options);
|
|
|
|
World reserialized = JsonSerializer.Deserialize<World>(serialized, Options)
|
2024-08-13 04:47:28 +00:00
|
|
|
?? throw new AssertionException("Failed to reserialize world");
|
|
|
|
|
2024-08-15 04:12:58 +00:00
|
|
|
Assert.Multiple(() => {
|
2024-08-15 23:36:50 +00:00
|
|
|
Assert.That(reserialized.OrderHistory[s0.Key].Orders.Count, Is.GreaterThan(0), "Missing orders");
|
|
|
|
Assert.That(reserialized.OrderHistory[s0.Key].DoesMoveOutcomes.Count, Is.GreaterThan(0), "Missing moves");
|
|
|
|
Assert.That(reserialized.OrderHistory[s0.Key].IsDislodgedOutcomes.Count, Is.GreaterThan(0), "Missing dislodges");
|
2024-08-16 05:20:03 +00:00
|
|
|
Assert.That(reserialized.Timelines.Pasts, Is.Not.Empty, "Missing timeline history");
|
2024-08-15 04:12:58 +00:00
|
|
|
});
|
2024-08-15 01:45:35 +00:00
|
|
|
|
2024-08-13 04:47:28 +00:00
|
|
|
// Resume the test case
|
2024-08-28 21:27:35 +00:00
|
|
|
setup = new(reserialized, MovementPhase);
|
2024-08-13 04:47:28 +00:00
|
|
|
setup[("a", 1)]
|
|
|
|
["Germany"]
|
2024-08-15 23:36:50 +00:00
|
|
|
.Army("Mun").Supports.Army("Mun", season: s0).MoveTo("Tyr").GetReference(out var mun1)
|
2024-08-13 04:47:28 +00:00
|
|
|
["Austria"]
|
|
|
|
.Army("Tyr").Holds();
|
|
|
|
|
|
|
|
setup.ValidateOrders();
|
|
|
|
Assert.That(mun1, Is.Valid);
|
2024-08-15 04:12:58 +00:00
|
|
|
var adjudications = setup.AdjudicateOrders();
|
2024-08-13 04:47:28 +00:00
|
|
|
Assert.That(mun1, Is.NotCut);
|
2024-08-16 20:13:15 +00:00
|
|
|
|
|
|
|
AttackStrength mun0attack = adjudications.OfType<AttackStrength>().Single();
|
|
|
|
Assert.That(mun0attack.Supports, Is.Not.Empty, "Support not tracked");
|
|
|
|
|
2024-08-15 13:52:08 +00:00
|
|
|
DoesMove mun0move = adjudications.OfType<DoesMove>().Single(move => move.Order.Unit.Key == mun0.Order.Unit.Key);
|
2024-08-15 04:12:58 +00:00
|
|
|
Assert.That(mun0move.Outcome, Is.True);
|
2024-08-16 20:13:15 +00:00
|
|
|
|
2024-08-15 13:52:08 +00:00
|
|
|
IsDislodged tyr0dislodge = adjudications.OfType<IsDislodged>().Single(dis => dis.Order.Unit.Key == tyr0.Order.Unit.Key);
|
2024-08-16 20:13:15 +00:00
|
|
|
Assert.That(tyr0dislodge.Outcome, Is.True);
|
2024-08-13 04:47:28 +00:00
|
|
|
|
|
|
|
// Confirm that an alternate future is created.
|
|
|
|
World world = setup.UpdateWorld();
|
2024-08-15 20:51:41 +00:00
|
|
|
Season fork = new("b1");
|
2024-08-13 23:24:43 +00:00
|
|
|
Unit tyr1 = world.GetUnitAt("Tyr", fork);
|
2024-08-13 04:47:28 +00:00
|
|
|
Assert.That(
|
|
|
|
tyr1.Past,
|
2024-08-15 13:52:08 +00:00
|
|
|
Is.EqualTo(mun0.Order.Unit.Key),
|
2024-08-13 04:47:28 +00:00
|
|
|
"Expected A Mun a0 to advance to Tyr b1");
|
|
|
|
Assert.That(
|
|
|
|
world.RetreatingUnits.Count,
|
|
|
|
Is.EqualTo(1),
|
|
|
|
"Expected A Tyr a0 to be in retreat");
|
2024-08-16 20:13:15 +00:00
|
|
|
Assert.That(world.RetreatingUnits.First().Unit.Key, Is.EqualTo(tyr0.Order.Unit.Key));
|
2024-08-13 04:47:28 +00:00
|
|
|
}
|
|
|
|
}
|