债券互换三字段互算:估值日(开始日)缺失报错 + 补提漏交回归用例
- 估值日严格取互换起始日 StartDate,去掉"悄悄回退交易日(TradeDate)":
真的为空时返回错误提示("请先填写开始日…或手动填写三项数值")并 return,
不调用计算器、不覆盖手工输入,与需求(按开始日估值)完全一致。
- 抽纯函数 getBondStartDateMissingMsg(StartDate 空→文案/null) + 导出;
复用 D3 的 shouldShowBondErr 去重,避免空开始日时价格格逐键连刷。
- BondCalcHepler.cs 仅补 XML 注释说明前端已强制 StartDate 必填;
targetDate 空→代理默认 T+1 行为不变(兜底 RealtimePnlCalc 旧链路)。
- 补提此前漏提交的回归用例:bondCalc.test.js(×100/÷100 端到端 + 逐字段手动锁定)、
swapCalc.test.js(D1/D2/D3 + 本次估值日缺失守卫)。
- jest bondCalc+swapCalc 全绿(68 passed)。
This commit is contained in:
@@ -45,6 +45,30 @@ describe('逐字段手动锁定:手填过的字段永不回写', () => {
|
||||
expect(state.cleanPrice).toBe(99);
|
||||
expect(state.dirtyPrice).toBe(100);
|
||||
});
|
||||
|
||||
test('仅手填全价(DP):全价保持,净价/收益率被反算覆盖(最常用场景)', () => {
|
||||
const state = { cleanPrice: null, dirtyPrice: 100.5, ytm: null }; // 用户手填全价 100.5
|
||||
SwapCalc.applyBondCalcResult(state, CALC, { CP: false, DP: true, YD: false });
|
||||
expect(state.dirtyPrice).toBe(100.5); // 手填:绝不回写
|
||||
expect(state.cleanPrice).toBe(99); // 未手填:被反算覆盖
|
||||
expect(state.ytm).toBe(2.5);
|
||||
});
|
||||
|
||||
test('手填净价+收益率(CP&YD):两者保持,仅全价被覆盖', () => {
|
||||
const state = { cleanPrice: 98.5, dirtyPrice: null, ytm: 3.2 };
|
||||
SwapCalc.applyBondCalcResult(state, CALC, { CP: true, DP: false, YD: true });
|
||||
expect(state.cleanPrice).toBe(98.5); // 手填:保持
|
||||
expect(state.ytm).toBe(3.2); // 手填:保持
|
||||
expect(state.dirtyPrice).toBe(100); // 未手填:被反算覆盖
|
||||
});
|
||||
|
||||
test('手填全价+收益率(DP&YD):两者保持,仅净价被覆盖', () => {
|
||||
const state = { cleanPrice: null, dirtyPrice: 101, ytm: 2.8 };
|
||||
SwapCalc.applyBondCalcResult(state, CALC, { CP: false, DP: true, YD: true });
|
||||
expect(state.dirtyPrice).toBe(101); // 手填:保持
|
||||
expect(state.ytm).toBe(2.8); // 手填:保持
|
||||
expect(state.cleanPrice).toBe(99); // 未手填:被反算覆盖
|
||||
});
|
||||
});
|
||||
|
||||
describe('边界:计算器未返回的值不覆盖、无变化不写', () => {
|
||||
|
||||
@@ -395,3 +395,36 @@ describe('D3 债券计算器失败提示去重', () => {
|
||||
expect(SwapCalc.shouldShowBondErr(s, '债券不存在')).toBe(true); // 新一次错误 → 重新提示
|
||||
});
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// 估值日(开始日)缺失守卫:需求——债券净价/全价/收益率以【互换起始日 StartDate】估值;
|
||||
// 开始日现已默认即有,故不再"悄悄回退到交易日(TradeDate)",而是真的为空时返回错误文案,
|
||||
// 由 calcBondForItem 报错提示并 return(不调用计算器、不覆盖手工输入)。
|
||||
// getBondStartDateMissingMsg 为纯函数,jest 直接覆盖。
|
||||
// ============================================================================
|
||||
describe('估值日(开始日)缺失 → 报错提示、不悄悄回退交易日', () => {
|
||||
test('开始日有值 → 返回 null(不报错、继续计算)', () => {
|
||||
expect(SwapCalc.getBondStartDateMissingMsg('2026-07-23')).toBeNull();
|
||||
expect(SwapCalc.getBondStartDateMissingMsg('2026-01-01')).toBeNull();
|
||||
expect(SwapCalc.getBondStartDateMissingMsg('2026/07/23')).toBeNull();
|
||||
});
|
||||
|
||||
test('开始日为空/undefined/null → 返回错误文案(须提示用户)', () => {
|
||||
expect(typeof SwapCalc.getBondStartDateMissingMsg('')).toBe('string');
|
||||
expect(typeof SwapCalc.getBondStartDateMissingMsg(null)).toBe('string');
|
||||
expect(typeof SwapCalc.getBondStartDateMissingMsg(undefined)).toBe('string');
|
||||
// 文案需同时引导"先填开始日"和"可手动填三数"(对应需求2)
|
||||
const m = SwapCalc.getBondStartDateMissingMsg('');
|
||||
expect(m).toMatch(/开始日/);
|
||||
expect(m).toMatch(/手动填写/);
|
||||
});
|
||||
|
||||
test('与 D3 去重配合:开始日缺失时同一文案只弹一次', () => {
|
||||
const item = {};
|
||||
const msg = SwapCalc.getBondStartDateMissingMsg('');
|
||||
// calcBondForItem 中:if (SwapCalc.shouldShowBondErr(item, msg)) main.message(msg); return;
|
||||
expect(SwapCalc.shouldShowBondErr(item, msg)).toBe(true); // 首次 → 提示
|
||||
expect(SwapCalc.shouldShowBondErr(item, msg)).toBe(false); // 价格格逐键输入连刷 → 抑制
|
||||
expect(SwapCalc.shouldShowBondErr(item, null)).toBe(false); // 估值日补填后成功 → 清标记
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user