修复测试程序集编译兼容性
This commit is contained in:
@@ -45,35 +45,35 @@ namespace FlowScope.Tests.EditMode.Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void LoadAllAsync_DuplicateId_ThrowsWithId()
|
public async Task LoadAllAsync_DuplicateId_ThrowsWithId()
|
||||||
{
|
{
|
||||||
var provider = new JsonConfigProvider(new[]
|
var provider = new JsonConfigProvider(new[]
|
||||||
{
|
{
|
||||||
JsonConfigProvider.Mapping<WeaponConfig>("weapons.json", _ => Task.FromResult("[{\"id\":101,\"name\":\"Axe\"},{\"id\":101,\"name\":\"Sword\"}]"))
|
JsonConfigProvider.Mapping<WeaponConfig>("weapons.json", _ => Task.FromResult("[{\"id\":101,\"name\":\"Axe\"},{\"id\":101,\"name\":\"Sword\"}]"))
|
||||||
});
|
});
|
||||||
|
|
||||||
var exception = Assert.ThrowsAsync<InvalidOperationException>(
|
var exception = await ThrowsAsync<InvalidOperationException>(
|
||||||
async () => await provider.LoadAllAsync(CancellationToken.None));
|
async () => await provider.LoadAllAsync(CancellationToken.None));
|
||||||
|
|
||||||
Assert.That(exception.Message, Does.Contain("101"));
|
Assert.That(exception.Message, Does.Contain("101"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void LoadAllAsync_MalformedJson_ThrowsWithFileName()
|
public async Task LoadAllAsync_MalformedJson_ThrowsWithFileName()
|
||||||
{
|
{
|
||||||
var provider = new JsonConfigProvider(new[]
|
var provider = new JsonConfigProvider(new[]
|
||||||
{
|
{
|
||||||
JsonConfigProvider.Mapping<WeaponConfig>("weapons.json", _ => Task.FromResult("[{\"id\":101"))
|
JsonConfigProvider.Mapping<WeaponConfig>("weapons.json", _ => Task.FromResult("[{\"id\":101"))
|
||||||
});
|
});
|
||||||
|
|
||||||
var exception = Assert.ThrowsAsync<InvalidOperationException>(
|
var exception = await ThrowsAsync<InvalidOperationException>(
|
||||||
async () => await provider.LoadAllAsync(CancellationToken.None));
|
async () => await provider.LoadAllAsync(CancellationToken.None));
|
||||||
|
|
||||||
Assert.That(exception.Message, Does.Contain("weapons.json"));
|
Assert.That(exception.Message, Does.Contain("weapons.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void LoadAllAsync_CanceledToken_ThrowsOperationCanceledException()
|
public async Task LoadAllAsync_CanceledToken_ThrowsOperationCanceledException()
|
||||||
{
|
{
|
||||||
using var cts = new CancellationTokenSource();
|
using var cts = new CancellationTokenSource();
|
||||||
cts.Cancel();
|
cts.Cancel();
|
||||||
@@ -82,10 +82,26 @@ namespace FlowScope.Tests.EditMode.Config
|
|||||||
JsonConfigProvider.Mapping<WeaponConfig>("weapons.json", _ => Task.FromResult("[]"))
|
JsonConfigProvider.Mapping<WeaponConfig>("weapons.json", _ => Task.FromResult("[]"))
|
||||||
});
|
});
|
||||||
|
|
||||||
Assert.ThrowsAsync<OperationCanceledException>(
|
await ThrowsAsync<OperationCanceledException>(
|
||||||
async () => await provider.LoadAllAsync(cts.Token));
|
async () => await provider.LoadAllAsync(cts.Token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<TException> ThrowsAsync<TException>(Func<Task> action)
|
||||||
|
where TException : Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await action();
|
||||||
|
}
|
||||||
|
catch (TException exception)
|
||||||
|
{
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.Fail($"Expected {typeof(TException).Name}.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private sealed class WeaponConfig : IConfigRow
|
private sealed class WeaponConfig : IConfigRow
|
||||||
{
|
{
|
||||||
public int id;
|
public int id;
|
||||||
|
|||||||
@@ -59,13 +59,13 @@ namespace FlowScope.Tests.EditMode.Flow
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void StartupAsync_WhenFeatureLoadFails_CleansCreatedFeatureAndReturnsIdle()
|
public async Task StartupAsync_WhenFeatureLoadFails_CleansCreatedFeatureAndReturnsIdle()
|
||||||
{
|
{
|
||||||
var services = new TestServices();
|
var services = new TestServices();
|
||||||
var root = services.CreateRoot();
|
var root = services.CreateRoot();
|
||||||
var flow = new GameFlow();
|
var flow = new GameFlow();
|
||||||
|
|
||||||
Assert.ThrowsAsync<InvalidOperationException>(
|
await ThrowsAsync<InvalidOperationException>(
|
||||||
async () => await flow.StartupAsync<FailingLoadFeature>(root, CancellationToken.None));
|
async () => await flow.StartupAsync<FailingLoadFeature>(root, CancellationToken.None));
|
||||||
|
|
||||||
Assert.That(flow.State, Is.EqualTo(GameFlowState.Idle));
|
Assert.That(flow.State, Is.EqualTo(GameFlowState.Idle));
|
||||||
@@ -81,7 +81,7 @@ namespace FlowScope.Tests.EditMode.Flow
|
|||||||
var flow = new GameFlow();
|
var flow = new GameFlow();
|
||||||
await flow.StartupAsync<FirstFeature>(root, CancellationToken.None);
|
await flow.StartupAsync<FirstFeature>(root, CancellationToken.None);
|
||||||
|
|
||||||
Assert.ThrowsAsync<InvalidOperationException>(
|
await ThrowsAsync<InvalidOperationException>(
|
||||||
async () => await flow.SwitchToAsync<FailingEnterFeature>(CancellationToken.None));
|
async () => await flow.SwitchToAsync<FailingEnterFeature>(CancellationToken.None));
|
||||||
|
|
||||||
Assert.That(flow.State, Is.EqualTo(GameFlowState.NoActiveFeature));
|
Assert.That(flow.State, Is.EqualTo(GameFlowState.NoActiveFeature));
|
||||||
@@ -91,11 +91,11 @@ namespace FlowScope.Tests.EditMode.Flow
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void SwitchToAsync_WhenIdle_ThrowsWithOperationAndCurrentState()
|
public async Task SwitchToAsync_WhenIdle_ThrowsWithOperationAndCurrentState()
|
||||||
{
|
{
|
||||||
var flow = new GameFlow();
|
var flow = new GameFlow();
|
||||||
|
|
||||||
var exception = Assert.ThrowsAsync<InvalidOperationException>(
|
var exception = await ThrowsAsync<InvalidOperationException>(
|
||||||
async () => await flow.SwitchToAsync<FirstFeature>(CancellationToken.None));
|
async () => await flow.SwitchToAsync<FirstFeature>(CancellationToken.None));
|
||||||
|
|
||||||
Assert.That(exception.Message, Does.Contain(nameof(GameFlow.SwitchToAsync)));
|
Assert.That(exception.Message, Does.Contain(nameof(GameFlow.SwitchToAsync)));
|
||||||
@@ -126,7 +126,7 @@ namespace FlowScope.Tests.EditMode.Flow
|
|||||||
using var cts = new CancellationTokenSource();
|
using var cts = new CancellationTokenSource();
|
||||||
cts.Cancel();
|
cts.Cancel();
|
||||||
|
|
||||||
Assert.ThrowsAsync<OperationCanceledException>(
|
await ThrowsAsync<OperationCanceledException>(
|
||||||
async () => await flow.ShutdownAsync(cts.Token));
|
async () => await flow.ShutdownAsync(cts.Token));
|
||||||
|
|
||||||
Assert.That(flow.State, Is.EqualTo(GameFlowState.Disposed));
|
Assert.That(flow.State, Is.EqualTo(GameFlowState.Disposed));
|
||||||
@@ -134,6 +134,22 @@ namespace FlowScope.Tests.EditMode.Flow
|
|||||||
Assert.That(services.Resource.Groups[0].IsDisposed, Is.True);
|
Assert.That(services.Resource.Groups[0].IsDisposed, Is.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<TException> ThrowsAsync<TException>(Func<Task> action)
|
||||||
|
where TException : Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await action();
|
||||||
|
}
|
||||||
|
catch (TException exception)
|
||||||
|
{
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.Fail($"Expected {typeof(TException).Name}.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private sealed class TestServices
|
private sealed class TestServices
|
||||||
{
|
{
|
||||||
public TestConfigProvider Config { get; } = new();
|
public TestConfigProvider Config { get; } = new();
|
||||||
|
|||||||
@@ -10,8 +10,11 @@
|
|||||||
],
|
],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
"allowUnsafeCode": false,
|
"allowUnsafeCode": false,
|
||||||
"overrideReferences": false,
|
"overrideReferences": true,
|
||||||
"precompiledReferences": [],
|
"precompiledReferences": [
|
||||||
|
"R3.dll",
|
||||||
|
"nunit.framework.dll"
|
||||||
|
],
|
||||||
"autoReferenced": false,
|
"autoReferenced": false,
|
||||||
"defineConstraints": [],
|
"defineConstraints": [],
|
||||||
"versionDefines": [],
|
"versionDefines": [],
|
||||||
|
|||||||
@@ -61,27 +61,43 @@ namespace FlowScope.Tests.EditMode.Save
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void SaveAsync_WriteFailure_ThrowsWithKey()
|
public async Task SaveAsync_WriteFailure_ThrowsWithKey()
|
||||||
{
|
{
|
||||||
var service = new SaveService(new FailingWriteStorage(), new JsonSaveSerializer());
|
var service = new SaveService(new FailingWriteStorage(), new JsonSaveSerializer());
|
||||||
|
|
||||||
var exception = Assert.ThrowsAsync<InvalidOperationException>(
|
var exception = await ThrowsAsync<InvalidOperationException>(
|
||||||
async () => await service.SaveAsync("player", new PlayerData(), CancellationToken.None));
|
async () => await service.SaveAsync("player", new PlayerData(), CancellationToken.None));
|
||||||
|
|
||||||
Assert.That(exception.Message, Does.Contain("player"));
|
Assert.That(exception.Message, Does.Contain("player"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void SaveAsync_CanceledToken_ThrowsOperationCanceledException()
|
public async Task SaveAsync_CanceledToken_ThrowsOperationCanceledException()
|
||||||
{
|
{
|
||||||
using var cts = new CancellationTokenSource();
|
using var cts = new CancellationTokenSource();
|
||||||
cts.Cancel();
|
cts.Cancel();
|
||||||
var service = new SaveService(new MemorySaveStorage(), new JsonSaveSerializer());
|
var service = new SaveService(new MemorySaveStorage(), new JsonSaveSerializer());
|
||||||
|
|
||||||
Assert.ThrowsAsync<OperationCanceledException>(
|
await ThrowsAsync<OperationCanceledException>(
|
||||||
async () => await service.SaveAsync("player", new PlayerData(), cts.Token));
|
async () => await service.SaveAsync("player", new PlayerData(), cts.Token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<TException> ThrowsAsync<TException>(Func<Task> action)
|
||||||
|
where TException : Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await action();
|
||||||
|
}
|
||||||
|
catch (TException exception)
|
||||||
|
{
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.Fail($"Expected {typeof(TException).Name}.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private sealed class PlayerData
|
private sealed class PlayerData
|
||||||
{
|
{
|
||||||
public ReactiveProperty<int> Gold { get; } = new(0);
|
public ReactiveProperty<int> Gold { get; } = new(0);
|
||||||
|
|||||||
@@ -9,8 +9,11 @@
|
|||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
"allowUnsafeCode": false,
|
"allowUnsafeCode": false,
|
||||||
"overrideReferences": false,
|
"overrideReferences": true,
|
||||||
"precompiledReferences": [],
|
"precompiledReferences": [
|
||||||
|
"R3.dll",
|
||||||
|
"nunit.framework.dll"
|
||||||
|
],
|
||||||
"autoReferenced": false,
|
"autoReferenced": false,
|
||||||
"defineConstraints": [],
|
"defineConstraints": [],
|
||||||
"versionDefines": [],
|
"versionDefines": [],
|
||||||
|
|||||||
@@ -39,19 +39,35 @@ namespace FlowScope.Tests.PlayMode.Resources
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void LoadAsync_WhenBackendFails_IncludesKeyAndBackend()
|
public async Task LoadAsync_WhenBackendFails_IncludesKeyAndBackend()
|
||||||
{
|
{
|
||||||
var service = new AddressablesResourceService(
|
var service = new AddressablesResourceService(
|
||||||
(_, _, _) => throw new InvalidOperationException("missing"),
|
(_, _, _) => throw new InvalidOperationException("missing"),
|
||||||
(_, _) => { });
|
(_, _) => { });
|
||||||
|
|
||||||
var exception = Assert.ThrowsAsync<InvalidOperationException>(
|
var exception = await ThrowsAsync<InvalidOperationException>(
|
||||||
() => service.LoadAsync<TestAsset>("missing-key", CancellationToken.None));
|
() => service.LoadAsync<TestAsset>("missing-key", CancellationToken.None));
|
||||||
|
|
||||||
StringAssert.Contains("missing-key", exception.Message);
|
StringAssert.Contains("missing-key", exception.Message);
|
||||||
StringAssert.Contains("Addressables", exception.Message);
|
StringAssert.Contains("Addressables", exception.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<TException> ThrowsAsync<TException>(Func<Task> action)
|
||||||
|
where TException : Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await action();
|
||||||
|
}
|
||||||
|
catch (TException exception)
|
||||||
|
{
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.Fail($"Expected {typeof(TException).Name}.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private sealed class TestAsset
|
private sealed class TestAsset
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ namespace FlowScope.Tests.PlayMode.UI
|
|||||||
var manager = new UIManager(resources);
|
var manager = new UIManager(resources);
|
||||||
manager.RegisterLayer("popup", canvas, 0);
|
manager.RegisterLayer("popup", canvas, 0);
|
||||||
|
|
||||||
Assert.ThrowsAsync<InvalidOperationException>(
|
await ThrowsAsync<InvalidOperationException>(
|
||||||
() => manager.OpenAsync<ThrowingBindPanel, TestViewModel>(new TestViewModel("boom"), CancellationToken.None));
|
() => manager.OpenAsync<ThrowingBindPanel, TestViewModel>(new TestViewModel("boom"), CancellationToken.None));
|
||||||
|
|
||||||
Assert.That(resources.Handles[0].IsDisposed, Is.True);
|
Assert.That(resources.Handles[0].IsDisposed, Is.True);
|
||||||
@@ -169,6 +169,22 @@ namespace FlowScope.Tests.PlayMode.UI
|
|||||||
return gameObject.AddComponent<Canvas>();
|
return gameObject.AddComponent<Canvas>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<TException> ThrowsAsync<TException>(Func<Task> action)
|
||||||
|
where TException : Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await action();
|
||||||
|
}
|
||||||
|
catch (TException exception)
|
||||||
|
{
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.Fail($"Expected {typeof(TException).Name}.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private GameObject CreatePrefab<TPanel>(string name)
|
private GameObject CreatePrefab<TPanel>(string name)
|
||||||
where TPanel : Component
|
where TPanel : Component
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user