Initial commit: Theriapolis baseline at port/godot branch point
Captures the pre-Godot-port state of the codebase. This is the rollback anchor for the Godot port (M0 of theriapolis-rpg-implementation-plan-godot-port.md). All Phase 0 through Phase 6.5 work is included; Phase 7 is in flight. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
using Theriapolis.Core;
|
||||
using Theriapolis.Core.Persistence;
|
||||
using Theriapolis.Core.Persistence.SaveMigrations;
|
||||
using Xunit;
|
||||
|
||||
namespace Theriapolis.Tests.Persistence;
|
||||
|
||||
/// <summary>
|
||||
/// Phase 6 M2 — additive V5→V6 migration. Unlike V4→V5 (rejection), v5
|
||||
/// saves are accepted and migrated up by zero-filling the new typed
|
||||
/// reputation containers.
|
||||
/// </summary>
|
||||
public sealed class V5ToV6MigrationTests
|
||||
{
|
||||
[Fact]
|
||||
public void V5Header_IsAcceptedByMigration()
|
||||
{
|
||||
var header = new SaveHeader { Version = 5 };
|
||||
Assert.True(SaveCodec.IsCompatible(header),
|
||||
"v5 must remain readable post-Phase-6 (MIN_VERSION = 5).");
|
||||
|
||||
var body = new SaveBody();
|
||||
bool ok = Migrations.MigrateUp(header, body);
|
||||
Assert.True(ok);
|
||||
Assert.Equal(C.SAVE_SCHEMA_VERSION, header.Version);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void V6_NewBody_HasEmptyReputationState()
|
||||
{
|
||||
var body = new SaveBody();
|
||||
Assert.NotNull(body.ReputationState);
|
||||
Assert.Empty(body.ReputationState.FactionStandings);
|
||||
Assert.Empty(body.ReputationState.Personal);
|
||||
Assert.Empty(body.ReputationState.Ledger);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void V5SaveBody_AfterMigration_HasEmptyReputation()
|
||||
{
|
||||
// Construct what a Phase-5-saved body might look like — v5 fields
|
||||
// (Player, Clock, ModifiedChunks, ModifiedWorldTiles, Flags,
|
||||
// PlayerCharacter, NpcRoster, ActiveEncounter), no v6 fields.
|
||||
var header = new SaveHeader { Version = 5 };
|
||||
var body = new SaveBody
|
||||
{
|
||||
Player = new() { Name = "Old Hand", PositionX = 50, PositionY = 50 },
|
||||
};
|
||||
body.Flags["debug-flag"] = 1;
|
||||
|
||||
bool ok = Migrations.MigrateUp(header, body);
|
||||
Assert.True(ok);
|
||||
// Migration chains all the way up to the current schema version.
|
||||
Assert.Equal(C.SAVE_SCHEMA_VERSION, header.Version);
|
||||
|
||||
// V5 fields must survive untouched.
|
||||
Assert.Equal("Old Hand", body.Player.Name);
|
||||
Assert.Equal(1, body.Flags["debug-flag"]);
|
||||
|
||||
// V6 fields must be empty (the migration does not synthesise data).
|
||||
Assert.NotNull(body.ReputationState);
|
||||
Assert.Empty(body.ReputationState.FactionStandings);
|
||||
Assert.Empty(body.ReputationState.Personal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NewSaveHeader_DefaultsToCurrentSchemaVersion()
|
||||
{
|
||||
// Schema version increments per phase (Phase 6 = v6, Phase 6.5 = v7);
|
||||
// SaveHeader picks up the constant.
|
||||
var header = new SaveHeader();
|
||||
Assert.Equal(C.SAVE_SCHEMA_VERSION, header.Version);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user