using System.Text.Json; using Chessistics.Engine.Loading; using Chessistics.Engine.Model; using Xunit; namespace Chessistics.Tests.Loading; public class CampaignLoaderTests { private const string ValidCampaignJson = """ { "name": "La Quête du Roi", "initialWidth": 4, "initialHeight": 4, "missions": [ { "id": 1, "name": "Premier Convoi", "description": "Les pions découvrent une scierie.", "terrainPatch": { "newWidth": 4, "newHeight": 4, "cells": [ { "col": 0, "row": 0, "type": "production", "production": { "name": "Scierie", "cargo": "wood", "amount": 1 } }, { "col": 3, "row": 0, "type": "demand", "demand": { "name": "Dépôt", "cargo": "wood", "amount": 3 } } ] }, "unlockedPieces": ["pawn"], "unlockedLevels": [{ "kind": "pawn", "level": 1 }], "stock": [{ "kind": "pawn", "count": 6 }] }, { "id": 2, "name": "Forger les Tours", "description": "De nouveaux territoires s'ouvrent.", "terrainPatch": { "newWidth": 6, "newHeight": 4, "cells": [ { "col": 4, "row": 0, "type": "empty" }, { "col": 4, "row": 1, "type": "wall" }, { "col": 5, "row": 2, "type": "production", "production": { "name": "Carrière", "cargo": "stone", "amount": 1 } }, { "col": 5, "row": 3, "type": "demand", "demand": { "name": "Chantier", "cargo": "stone", "amount": 5 } } ] }, "unlockedPieces": ["rook"], "unlockedLevels": [{ "kind": "rook", "level": 1 }], "stock": [ { "kind": "pawn", "count": 2 }, { "kind": "rook", "count": 3 } ] } ] } """; [Fact] public void LoadValidCampaign_ParsesCorrectly() { var campaign = CampaignLoader.Load(ValidCampaignJson); Assert.Equal("La Quête du Roi", campaign.Name); Assert.Equal(4, campaign.InitialWidth); Assert.Equal(4, campaign.InitialHeight); Assert.Equal(2, campaign.Missions.Count); } [Fact] public void LoadValidCampaign_Mission1_Correct() { var campaign = CampaignLoader.Load(ValidCampaignJson); var m1 = campaign.Missions[0]; Assert.Equal(1, m1.Id); Assert.Equal("Premier Convoi", m1.Name); Assert.Equal(4, m1.TerrainPatch.NewWidth); Assert.Equal(2, m1.TerrainPatch.Cells.Count); Assert.Single(m1.UnlockedPieces); Assert.Equal(PieceKind.Pawn, m1.UnlockedPieces[0]); Assert.Single(m1.Stock); Assert.Equal(6, m1.Stock[0].Count); } [Fact] public void LoadValidCampaign_Mission2_TerrainExpands() { var campaign = CampaignLoader.Load(ValidCampaignJson); var m2 = campaign.Missions[1]; Assert.Equal(6, m2.TerrainPatch.NewWidth); Assert.Equal(4, m2.TerrainPatch.NewHeight); var wallCell = m2.TerrainPatch.Cells.First(c => c.Type == CellType.Wall); Assert.Equal(4, wallCell.Col); Assert.Equal(1, wallCell.Row); } [Fact] public void LoadCampaign_ShrinkingTerrain_Throws() { var badJson = """ { "name": "Bad", "initialWidth": 6, "initialHeight": 6, "missions": [ { "id": 1, "name": "M1", "terrainPatch": { "newWidth": 4, "newHeight": 4, "cells": [] }, "stock": [] } ] } """; Assert.Throws(() => CampaignLoader.Load(badJson)); } [Fact] public void LoadCampaign_EmptyName_Throws() { var badJson = """ { "name": "", "initialWidth": 4, "initialHeight": 4, "missions": [{ "id": 1, "name": "M", "terrainPatch": { "newWidth": 4, "newHeight": 4, "cells": [] } }] } """; Assert.Throws(() => CampaignLoader.Load(badJson)); } [Fact] public void LoadCampaign_NoMissions_Throws() { var badJson = """ { "name": "Empty", "initialWidth": 4, "initialHeight": 4, "missions": [] } """; Assert.Throws(() => CampaignLoader.Load(badJson)); } [Fact] public void LoadCampaign_TransformerCell_ParsesCorrectly() { var json = """ { "name": "Forge Test", "initialWidth": 5, "initialHeight": 1, "missions": [ { "id": 1, "name": "M1", "terrainPatch": { "newWidth": 5, "newHeight": 1, "cells": [ { "col": 0, "row": 0, "type": "production", "production": { "name": "Scierie", "cargo": "wood", "amount": 4 } }, { "col": 2, "row": 0, "type": "transformer", "transformer": { "name": "Forge", "inputCargo": "wood", "inputRequired": 2, "outputCargo": "tools", "outputAmount": 1 } }, { "col": 4, "row": 0, "type": "demand", "demand": { "name": "Depot", "cargo": "tools", "amount": 3 } } ] }, "stock": [{ "kind": "rook", "count": 3 }], "unlockedPieces": ["rook"], "unlockedLevels": [{ "kind": "rook", "level": 1 }] } ] } """; var campaign = CampaignLoader.Load(json); var cells = campaign.Missions[0].TerrainPatch.Cells; var transformerCell = cells.First(c => c.Type == CellType.Transformer); Assert.NotNull(transformerCell.Transformer); Assert.Equal("Forge", transformerCell.Transformer.Name); Assert.Equal(CargoType.Wood, transformerCell.Transformer.InputCargo); Assert.Equal(2, transformerCell.Transformer.InputRequired); Assert.Equal(CargoType.Tools, transformerCell.Transformer.OutputCargo); Assert.Equal(1, transformerCell.Transformer.OutputAmount); } [Fact] public void LoadCampaign_NewCargoTypes_ParseCorrectly() { var json = """ { "name": "Cargo Test", "initialWidth": 3, "initialHeight": 1, "missions": [ { "id": 1, "name": "M1", "terrainPatch": { "newWidth": 3, "newHeight": 1, "cells": [ { "col": 0, "row": 0, "type": "demand", "demand": { "name": "D1", "cargo": "arms", "amount": 1 } }, { "col": 1, "row": 0, "type": "demand", "demand": { "name": "D2", "cargo": "gold", "amount": 1 } }, { "col": 2, "row": 0, "type": "demand", "demand": { "name": "D3", "cargo": "tools", "amount": 1 } } ] }, "stock": [] } ] } """; var campaign = CampaignLoader.Load(json); var cells = campaign.Missions[0].TerrainPatch.Cells; Assert.Equal(CargoType.Arms, cells[0].Demand!.Cargo); Assert.Equal(CargoType.Gold, cells[1].Demand!.Cargo); Assert.Equal(CargoType.Tools, cells[2].Demand!.Cargo); } }