diff --git a/YLErpWeb/fe-tests/bondCalc.integration.test.js b/YLErpWeb/fe-tests/bondCalc.integration.test.js
index b1a88e9f..1a39b62a 100644
--- a/YLErpWeb/fe-tests/bondCalc.integration.test.js
+++ b/YLErpWeb/fe-tests/bondCalc.integration.test.js
@@ -47,6 +47,68 @@ global.main = {
const SwapCalc = require('../wwwroot/Scripts/app/swaptrade/swapCalc.js');
+describe('TradeEdit bond price input bindings', () => {
+ const view = fs.readFileSync(path.join(__dirname, '..', 'Views', 'SwapTrade2', 'TradeEdit.cshtml'), 'utf8');
+ const methods = fs.readFileSync(path.join(__dirname, '..', 'wwwroot', 'Scripts', 'app', 'swaptrade', 'swapTradeEdit.js'), 'utf8');
+ const precisionHelper = fs.readFileSync(path.join(__dirname, '..', 'wwwroot', 'Scripts', 'app', 'swaptrade', 'swapPricePrecisionHelper.js'), 'utf8');
+
+ test('binds the three bond price fields to current Vue methods', () => {
+ expect(view).toMatch(/v-model="item\.PosiGrossPrice"[^>]*v-on:input="onDpPriceInput\(item\)"/);
+ expect(view).toMatch(/v-model="item\.PosiNetNoFeePrice"[^>]*v-on:input="onBondPriceEdit\(item,'CP'\)"/);
+ expect(view).toMatch(/v-model="item\.InitYtm"[^>]*v-on:input="onBondPriceEdit\(item,'YD'\)"/);
+ expect(view).not.toContain('v-on:input="onBondPriceInput(');
+ expect(methods).toMatch(/^\s*onBondPriceEdit\s*\(/m);
+ });
+
+ test('precision input preserves the keydown, input, enter event contract', () => {
+ const helper = new Function('window', precisionHelper + '\nreturn swapPricePrecision;')({});
+ const component = helper.createVueInputComponent();
+ expect(component.template).toContain('@blur="onChange"');
+ expect(component.template).not.toContain('@change="onChange"');
+ const emitted = [];
+ const vm = {
+ text: '99.5',
+ enterPressed: false,
+ format: { precision: 4, percent: true },
+ $emit: (event, value) => emitted.push({ event, value })
+ };
+ Object.keys(component.methods).forEach(name => {
+ vm[name] = component.methods[name].bind(vm);
+ });
+ const target = {
+ value: vm.text,
+ blur: () => vm.onChange({ target })
+ };
+
+ vm.onKeydown({ keyCode: 13, target });
+
+ expect(emitted.map(x => x.event)).toEqual(['keydown', 'input', 'enter']);
+ expect(emitted[1].value).toBe('0.995');
+ expect(emitted[2].value).toBe('0.995');
+ });
+
+ test('equal format refresh does not overwrite uncommitted input', () => {
+ const helper = new Function('window', precisionHelper + '\nreturn swapPricePrecision;')({});
+ const component = helper.createVueInputComponent();
+ const format = { precision: 4, percent: true };
+ const vm = {
+ value: '0.995',
+ text: '99.5',
+ format,
+ formatSnapshot: JSON.stringify(format),
+ $emit: () => {}
+ };
+ Object.keys(component.methods).forEach(name => {
+ vm[name] = component.methods[name].bind(vm);
+ });
+
+ vm.onInput({ target: { value: '99.51' } });
+ component.watch.format.handler.call(vm);
+
+ expect(vm.text).toBe('99.51');
+ });
+});
+
// ============================================================================
// 根因 1:vue-number-input keydown 事件 emit 链路
// ============================================================================
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js
index be9e3ed6..2150a5de 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/swapPricePrecisionHelper.js
@@ -242,7 +242,7 @@ var swapPricePrecision = (function (global) {
}
}
},
- template: ''
+ template: ''
};
}