summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Kernel.Tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/LivingVillage.Kernel.Tests')
-rw-r--r--src/LivingVillage.Kernel.Tests/OccupationStoryTests.fs53
1 files changed, 52 insertions, 1 deletions
diff --git a/src/LivingVillage.Kernel.Tests/OccupationStoryTests.fs b/src/LivingVillage.Kernel.Tests/OccupationStoryTests.fs
index 80bc9a4..d204ca6 100644
--- a/src/LivingVillage.Kernel.Tests/OccupationStoryTests.fs
+++ b/src/LivingVillage.Kernel.Tests/OccupationStoryTests.fs
@@ -8,6 +8,14 @@ module private StoryHarness =
let seed = 42UL
+ let withTempSave (action: string -> unit) =
+ let id = System.Guid.NewGuid().ToString("N")
+ let path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), $"living-village-p31-{id}.save")
+ try
+ action path
+ finally
+ if System.IO.File.Exists path then System.IO.File.Delete path
+
let worldAtTick (tick: int64) : World =
{ Sim.initialWorldN 4UL 4 with Tick = tick; Time = float tick * Sim.dtSeconds }
@@ -94,7 +102,7 @@ type OccupationStoryTests () =
summaries <- summary :: summaries
Assert.AreEqual<int>(3, state.StoryStage)
Assert.AreEqual<int>(3, summaries.Length)
- Assert.AreEqual<string option>(Some "走访了几户人家,改日再问。", summaries |> List.rev |> List.item 1)
+ Assert.AreEqual<string option>(Some "走访了几户人家,改日再问", summaries |> List.rev |> List.item 1)
Assert.IsTrue(
summaries
|> List.choose id
@@ -228,3 +236,46 @@ type OccupationStoryTests () =
let secondState, secondSummary = Occupation.Story.onDialogue StoryHarness.seed state world
Assert.AreEqual<Occupation.State>(firstState, secondState)
Assert.AreEqual<string option>(firstSummary, secondSummary)
+
+ // ---- §3 身份条目 + 存档持久化 ----
+
+ [<TestMethod>]
+ member _.IdentitySummariesUsePlainChronicleStyle () =
+ Assert.AreEqual<string>("以耕田为生", Occupation.Story.identitySummaryOf Occupation.Farmer)
+ Assert.AreEqual<string>("以打渔为生", Occupation.Story.identitySummaryOf Occupation.Fisher)
+ Assert.AreEqual<string>("以贩货为生", Occupation.Story.identitySummaryOf Occupation.Peddler)
+ Assert.AreEqual<string>("以读书为生", Occupation.Story.identitySummaryOf Occupation.Scholar)
+
+ [<TestMethod>]
+ member _.StoryAnnalRoundTripsThroughTheV3Save () =
+ let kind = Occupation.Fisher
+ let startDay = Occupation.Story.startDayOf StoryHarness.seed kind
+ let world = StoryHarness.worldAtTick (StoryHarness.dayTick (startDay + 2L))
+ let _, summary = Occupation.Story.onDialogue StoryHarness.seed (StoryHarness.stateOf kind 2) world
+ let entry = { Tick = world.Tick; Kind = StoryAnnal; Summary = summary.Value }
+ let worldWithAnnal = Sim.appendAnnal entry world
+ let text = WorldSave.saveWith (Some (StoryHarness.stateOf kind 3)) worldWithAnnal
+ match WorldSave.load text with
+ | Ok loaded ->
+ Assert.AreEqual(worldWithAnnal.Annals, loaded.Annals)
+ // 存 → 读 → 存 逐字节一致
+ Assert.AreEqual<string>(text, WorldSave.saveWith (Some (StoryHarness.stateOf kind 3)) loaded)
+ | Error message -> Assert.Fail(message)
+
+ [<TestMethod>]
+ member _.StoryStageRestoresFromTheV3OccupationSegment () =
+ StoryHarness.withTempSave (fun path ->
+ let state = StoryHarness.stateOf Occupation.Peddler 2
+ WorldSave.saveToFileWith (Some state) path (StoryHarness.worldAtTick 0L)
+ match WorldSave.loadFromFileWith path with
+ | Ok (_, Some loaded) -> Assert.AreEqual<int>(2, loaded.StoryStage)
+ | Ok (_, None) -> Assert.Fail("v3 occupation state expected")
+ | Error message -> Assert.Fail(message))
+
+ [<TestMethod>]
+ member _.NoOccupationSaveStaysFreeOfStoryTokens () =
+ // 无职业 v2 存档永不产生 story token,v1/v2 字节口径不变
+ let world = StoryHarness.worldAtTick 0L
+ let text = WorldSave.save world
+ Assert.IsFalse(text.Contains("story"))
+ Assert.IsTrue(text.StartsWith("LV_WORLD_SAVE_V2|"))