新增: - IConfigService / ConfigService:读写 defaults.json / planner_config.json - SavePlannerConfig / SaveDefaults / Reload,无需重启 Unity - PlannerConfigReloaded 事件 → ScenarioManager 自动重建 planner - SimulationEngine.UpdatePlanner / ScenarioService.UpdatePlanner - SimulationRunner.ReloadPlanner 桥接 - DefenseRecommendation / RecommendOption 返回类型 - IScenarioService.GetDefenseRecommendation(配置阶段生成最佳抛撒参数) - ConfigServiceTests 5 个测试 + DefenseRecommendationTests 3 个测试 修复: - 云团间距半径基准不一致(间距用 R30、穿越用 R27 → 统一用 effectiveRadius) - 消除硬编码 30f(DefensePlanner + GaussianPuffDispersion 读 Phase2Duration) - TryGenerateFireEvents 复用 ComputeEffectiveRadius,消除重复计算 - 概率计算间距加重叠系数 - DatabaseManager 不再 DROP SimulationReport(保留历史报告) - 清理迁移代码(MetaEntry / 旧表 DROP / 版本检查) 文档: - 对接文档 V2.1:加 IConfigService API + 配置重载用法 + 修正 DLL 更新说明 - 实施跟踪 V1.8:8.2.1 更新 + 新增 8.2.3/8.2.4 + M14 里程碑 - 270 测试通过,Unity 编译通过
119 lines
4.1 KiB
C#
119 lines
4.1 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text.Json;
|
|
using CounterDrone.Core;
|
|
using CounterDrone.Core.Algorithms;
|
|
using CounterDrone.Core.Services;
|
|
using Xunit;
|
|
|
|
namespace CounterDrone.Core.Tests
|
|
{
|
|
public class ConfigServiceTests : IDisposable
|
|
{
|
|
private readonly string _testDir;
|
|
private readonly IPathProvider _paths;
|
|
private readonly ConfigService _config;
|
|
private readonly SQLite.SQLiteConnection _db;
|
|
|
|
public ConfigServiceTests()
|
|
{
|
|
_testDir = Path.Combine(Path.GetTempPath(), $"cd_cfg_{Guid.NewGuid():N}");
|
|
_paths = new TestPathProvider(_testDir);
|
|
var dbm = new DatabaseManager(_paths);
|
|
_db = dbm.OpenMainDb();
|
|
_config = new ConfigService(_paths, _db);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_db?.Close();
|
|
if (Directory.Exists(_testDir)) Directory.Delete(_testDir, true);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetPlannerConfigJson_ReturnsValidJson()
|
|
{
|
|
var json = _config.GetPlannerConfigJson();
|
|
var cfg = JsonSerializer.Deserialize<PlannerConfig>(json, new JsonSerializerOptions
|
|
{
|
|
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() },
|
|
PropertyNameCaseInsensitive = true,
|
|
});
|
|
Assert.NotNull(cfg);
|
|
Assert.True(cfg.CloudOverlapRatio >= 0);
|
|
}
|
|
|
|
[Fact]
|
|
public void SavePlannerConfig_PersistsAndReloads()
|
|
{
|
|
var original = _config.GetPlannerConfigJson();
|
|
var cfg = JsonSerializer.Deserialize<PlannerConfig>(original, new JsonSerializerOptions
|
|
{
|
|
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() },
|
|
PropertyNameCaseInsensitive = true,
|
|
})!;
|
|
cfg.CloudOverlapRatio = 0.3f;
|
|
var modifiedJson = JsonSerializer.Serialize(cfg, new JsonSerializerOptions
|
|
{
|
|
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() },
|
|
});
|
|
|
|
_config.SavePlannerConfig(modifiedJson);
|
|
|
|
var reloaded = _config.GetPlannerConfigJson();
|
|
var reloadedCfg = JsonSerializer.Deserialize<PlannerConfig>(reloaded, new JsonSerializerOptions
|
|
{
|
|
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() },
|
|
PropertyNameCaseInsensitive = true,
|
|
})!;
|
|
Assert.Equal(0.3f, reloadedCfg.CloudOverlapRatio);
|
|
}
|
|
|
|
[Fact]
|
|
public void PlannerConfigReloaded_EventFires()
|
|
{
|
|
PlannerConfig? received = null;
|
|
_config.PlannerConfigReloaded += cfg => received = cfg;
|
|
|
|
var json = _config.GetPlannerConfigJson();
|
|
_config.SavePlannerConfig(json);
|
|
|
|
Assert.NotNull(received);
|
|
Assert.True(received.CloudOverlapRatio >= 0);
|
|
}
|
|
|
|
[Fact]
|
|
public void Reload_FromDiskRefreshesConfig()
|
|
{
|
|
// 直接改文件
|
|
var path = Path.Combine(_testDir, "planner_config.json");
|
|
var json = File.ReadAllText(path);
|
|
var cfg = JsonSerializer.Deserialize<PlannerConfig>(json, new JsonSerializerOptions
|
|
{
|
|
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() },
|
|
PropertyNameCaseInsensitive = true,
|
|
})!;
|
|
cfg.ExpansionFactor = 0.8f;
|
|
File.WriteAllText(path, JsonSerializer.Serialize(cfg, new JsonSerializerOptions
|
|
{
|
|
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() },
|
|
}));
|
|
|
|
PlannerConfig? received = null;
|
|
_config.PlannerConfigReloaded += cfg => received = cfg;
|
|
|
|
_config.Reload();
|
|
|
|
Assert.NotNull(received);
|
|
Assert.Equal(0.8f, received.ExpansionFactor);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetDefaultsJson_ReturnsValidJson()
|
|
{
|
|
var json = _config.GetDefaultsJson();
|
|
Assert.Contains("ammunition", json.ToLower());
|
|
}
|
|
}
|
|
}
|