126 lines
3.8 KiB
C#
126 lines
3.8 KiB
C#
using System;
|
|
using Newtonsoft.Json.Linq;
|
|
using NUnit.Framework;
|
|
using UnityEngine;
|
|
using UnityEngine.TestTools;
|
|
|
|
namespace ShrinkDataSaver.Tests
|
|
{
|
|
[TestFixture]
|
|
public class MigrationChainTests
|
|
{
|
|
[SetUp]
|
|
public void SetUp() => MigrationChain.Clear();
|
|
|
|
[TearDown]
|
|
public void TearDown() => MigrationChain.Clear();
|
|
|
|
[Test]
|
|
public void Register_ValidVersions_Succeeds()
|
|
{
|
|
Assert.DoesNotThrow(() =>
|
|
MigrationChain.Register(1, 2, data => data));
|
|
}
|
|
|
|
[Test]
|
|
public void Register_InvalidRange_Throws()
|
|
{
|
|
Assert.Throws<ArgumentException>(() =>
|
|
MigrationChain.Register(2, 1, data => data));
|
|
|
|
Assert.Throws<ArgumentException>(() =>
|
|
MigrationChain.Register(1, 1, data => data));
|
|
}
|
|
|
|
[Test]
|
|
public void Apply_SingleMigration()
|
|
{
|
|
MigrationChain.Register(1, 2, data =>
|
|
{
|
|
data["newField"] = "added";
|
|
return data;
|
|
});
|
|
|
|
var input = new JObject { ["existing"] = "value" };
|
|
var (result, version) = MigrationChain.Apply(input, 1, 2);
|
|
|
|
Assert.AreEqual(2, version);
|
|
Assert.AreEqual("value", result["existing"].ToString());
|
|
Assert.AreEqual("added", result["newField"].ToString());
|
|
}
|
|
|
|
[Test]
|
|
public void Apply_ChainMigration_1To3()
|
|
{
|
|
MigrationChain.Register(1, 2, data =>
|
|
{
|
|
data["coins"] = data["gold"];
|
|
data.Remove("gold");
|
|
return data;
|
|
});
|
|
|
|
MigrationChain.Register(2, 3, data =>
|
|
{
|
|
data["version3Field"] = 42;
|
|
return data;
|
|
});
|
|
|
|
var input = new JObject { ["gold"] = 100 };
|
|
var (result, version) = MigrationChain.Apply(input, 1, 3);
|
|
|
|
Assert.AreEqual(3, version);
|
|
Assert.AreEqual(100, result["coins"].Value<int>());
|
|
Assert.IsFalse(result.ContainsKey("gold"));
|
|
Assert.AreEqual(42, result["version3Field"].Value<int>());
|
|
}
|
|
|
|
[Test]
|
|
public void Apply_MissingStep_StopsEarly()
|
|
{
|
|
MigrationChain.Register(1, 2, data => data);
|
|
// 缺少 2→3 的迁移
|
|
|
|
var input = new JObject { ["data"] = "test" };
|
|
var (result, version) = MigrationChain.Apply(input, 1, 3);
|
|
|
|
// 应该停在 v2,因为没有 2→3 的迁移
|
|
Assert.AreEqual(2, version);
|
|
}
|
|
|
|
[Test]
|
|
public void Apply_FailedMigration_Rollback()
|
|
{
|
|
MigrationChain.Register(1, 2, data =>
|
|
{
|
|
data["step1"] = "done";
|
|
return data;
|
|
});
|
|
|
|
MigrationChain.Register(2, 3, data =>
|
|
{
|
|
throw new Exception("Migration failed!");
|
|
});
|
|
|
|
var input = new JObject { ["original"] = "data" };
|
|
LogAssert.Expect(LogType.Error, "[ShrinkDataSaver] 迁移 v2 → v3 失败: Migration failed!,已回滚至 v1");
|
|
var (result, version) = MigrationChain.Apply(input, 1, 3);
|
|
|
|
// 应该回滚到 v1 的备份数据
|
|
Assert.AreEqual(1, version);
|
|
Assert.AreEqual("data", result["original"].ToString());
|
|
// 回滚意味着 step1 的修改不会存在
|
|
Assert.IsFalse(result.ContainsKey("step1"));
|
|
}
|
|
|
|
[Test]
|
|
public void Apply_NoMigrationNeeded_ReturnsSameData()
|
|
{
|
|
var input = new JObject { ["data"] = "unchanged" };
|
|
var (result, version) = MigrationChain.Apply(input, 3, 3);
|
|
|
|
Assert.AreEqual(3, version);
|
|
Assert.AreEqual("unchanged", result["data"].ToString());
|
|
}
|
|
}
|
|
}
|