refactor(swap-eod): 利息腿分派可读性收口——观察日命名统一+命名参数+查找助手+分派规格纯函数(零行为变更)

- insterval/autoInterval → observationInterval,SwapIntervalList→FindObservationInterval→形参 interval 全链同名
- :512/:525 调用点命名参数 autoSwap: true/false,签名未动
- 抽取 FindObservationInterval 消除两处重复观察日谓词(表达式逐字保留,null 语义不变)
- 新增 InterestEodScenario 枚举 + ResolveInterestScenario 影子纯函数 + 8 组合表驱动 InterestEodScenarioDispatchTest(分派结构未接线,生产执行路径不变)
- 编译 0 错误;表驱动 8/8 通过
This commit is contained in:
hjhan
2026-08-17 16:25:08 +08:00
parent b94cce68ee
commit ec9c493420
3 changed files with 88 additions and 13 deletions
@@ -447,7 +447,7 @@ namespace YLErp.Modules.SwapModule
/// <summary>
/// [DI_BRANCH_001] 普通日(无互换无平仓无观察日)→ 走 copy 分支
/// ---------------------------------------------------------------
/// flowEvents 为空,insterval=nullhasSwap=falsehasClose=false
/// flowEvents 为空,observationInterval=nullhasSwap=falsehasClose=false
/// → 应走 SaveEodInterestPositionCopycs:338
/// ---------------------------------------------------------------
/// <summary>
@@ -0,0 +1,33 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace YLErp.Modules.SwapModule
{
/// <summary>
/// DealInterests 分派优先级(TEST-MATRIX §6 空洞补盖)。
/// 纯函数 ResolveInterestScenario 的 8 组合表驱动单测,不连库、无 DB。
/// 守卫:手工互换压制观察日自动结息;观察日±平仓区分 autoSwap 真/假;纯平仓与普通日分流。
/// 测试类直接继承 TestableSwapEodPositionService 以访问 protected 的枚举与方法。
/// </summary>
[TestClass]
public class InterestEodScenarioDispatchTest : TestableSwapEodPositionService
{
public InterestEodScenarioDispatchTest() : base(nameof(InterestEodScenarioDispatchTest)) { }
[DataTestMethod]
[DataRow(false, false, false, InterestEodScenario.RollForward)] // 普通日
[DataRow(false, false, true, InterestEodScenario.CloseOnly)] // 纯平仓(非观察日)
[DataRow(false, true, false, InterestEodScenario.ManualSwap)] // 手工互换(非观察日)
[DataRow(false, true, true, InterestEodScenario.ManualSwap)] // 手工互换+平仓 → 手工优先
[DataRow(true, false, false, InterestEodScenario.AutoSettle)] // 观察日, 无平仓
[DataRow(true, false, true, InterestEodScenario.AutoSettleWithClose)] // 观察日+平仓 (autoSwap=true)
[DataRow(true, true, false, InterestEodScenario.ManualSwap)] // 观察日+手工互换 → 手工优先
[DataRow(true, true, true, InterestEodScenario.ManualSwap)] // 观察日+手工互换+平仓 → 手工优先
public void ResolveInterestScenario_CoversAllEightCombinations(
bool hasInterval, bool hasSwap, bool hasClose, InterestEodScenario expected)
{
var actual = ResolveInterestScenario(hasInterval, hasSwap, hasClose);
Assert.AreEqual(expected, actual,
$"hasInterval={hasInterval}, hasSwap={hasSwap}, hasClose={hasClose}");
}
}
}