- fastVue.base.js: __onInput 粘贴分支原把显示值当模型值传入 setValue 导致 percent 字段 ×100; 改为按 __change 同款口径先解析为模型值再回显,键盘输入路径不变 - 新增 numberInput.paste.test.js 覆盖 percent:true/append:%/append:‱/普通数字 4 类字段的 Ctrl+V 粘贴 - fe-tests package.json 增加 jest-environment-jsdom、jquery 依赖
106 lines
3.8 KiB
JavaScript
106 lines
3.8 KiB
JavaScript
/**
|
||
* numberInput.paste.test.js — FastVue.numberInput 粘贴路径回归守卫
|
||
* ============================================================================
|
||
* 目的:防止 #EQD-5914 后新增的 `percent:true`+空 append 格式在粘贴时 ×100。
|
||
* 覆盖字段类型:percent、append:'%'、append:'‱'、普通数字。
|
||
*
|
||
* 运行:cd YLErpWeb/fe-tests && npm test -- numberInput.paste
|
||
*/
|
||
|
||
const { JSDOM } = require('jsdom');
|
||
const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>');
|
||
global.window = dom.window;
|
||
global.document = dom.window.document;
|
||
global.navigator = dom.window.navigator;
|
||
|
||
// fastVue.base.js 内部多个 IIFE 通过全局 FastVue 共享;
|
||
// 浏览器里 window.FastVue 与全局 FastVue 等价,Node 里需要桥接一下。
|
||
Object.defineProperty(global, 'FastVue', {
|
||
get() { return global.window.FastVue; },
|
||
set(value) { global.window.FastVue = value; },
|
||
configurable: true
|
||
});
|
||
|
||
const $ = require('jquery');
|
||
global.$ = $;
|
||
global.jQuery = $;
|
||
|
||
// fastVue.base.js 依赖全局 main.formatNumber
|
||
global.main = {
|
||
formatNumber: function (number, precision, options) {
|
||
const n = Number(number);
|
||
if (Number.isNaN(n)) return '0';
|
||
const useGrouping = options && options.grouping;
|
||
if (useGrouping) {
|
||
return n.toLocaleString('en-US', { minimumFractionDigits: precision, maximumFractionDigits: precision });
|
||
}
|
||
return n.toFixed(precision);
|
||
}
|
||
};
|
||
|
||
require('../wwwroot/Scripts/fast/fastVue.base.js');
|
||
|
||
function createInput() {
|
||
return document.createElement('input');
|
||
}
|
||
|
||
function simulatePaste(el, pastedText) {
|
||
el.value = pastedText;
|
||
// 先触发 keydown 让 _ctrlV=true(Ctrl+V 的 keyCode=86,ctrlKey=true)
|
||
const keydown = new window.KeyboardEvent('keydown', { keyCode: 86, ctrlKey: true, bubbles: true });
|
||
el.dispatchEvent(keydown);
|
||
// 再触发 input 事件
|
||
const input = new window.Event('input', { bubbles: true });
|
||
el.dispatchEvent(input);
|
||
// 最后触发 change 事件(浏览器在失焦或回车时触发;这里手动触发验证 onchange)
|
||
const change = new window.Event('change', { bubbles: true });
|
||
el.dispatchEvent(change);
|
||
}
|
||
|
||
describe('FastVue.numberInput 粘贴路径', () => {
|
||
test('percent:true + 空 append:粘贴 99.07 不应 ×100(债券净价 bug 场景)', () => {
|
||
const el = createInput();
|
||
const changes = [];
|
||
FastVue.numberInput(el, { precision: 4, percent: true, append: '', onchange: (v) => changes.push(v) });
|
||
|
||
simulatePaste(el, '99.0756');
|
||
|
||
expect(el.value).toBe('99.0756');
|
||
expect(changes.length).toBeGreaterThan(0);
|
||
expect(changes[changes.length - 1]).toBeCloseTo(0.990756, 8);
|
||
});
|
||
|
||
test('append:"%":粘贴 99.07% 应解析为 0.9907', () => {
|
||
const el = createInput();
|
||
const changes = [];
|
||
FastVue.numberInput(el, { precision: 2, append: '%', onchange: (v) => changes.push(v) });
|
||
|
||
simulatePaste(el, '99.07%');
|
||
|
||
expect(el.value).toBe('99.07%');
|
||
expect(changes[changes.length - 1]).toBeCloseTo(0.9907, 8);
|
||
});
|
||
|
||
test('append:"‱":粘贴 990.7‱ 应解析为 0.09907', () => {
|
||
const el = createInput();
|
||
const changes = [];
|
||
FastVue.numberInput(el, { precision: 4, append: '‱', onchange: (v) => changes.push(v) });
|
||
|
||
simulatePaste(el, '990.7‱');
|
||
|
||
expect(el.value).toBe('990.7‱');
|
||
expect(changes[changes.length - 1]).toBeCloseTo(0.09907, 8);
|
||
});
|
||
|
||
test('普通数字字段:粘贴 99.07 保持原值', () => {
|
||
const el = createInput();
|
||
const changes = [];
|
||
FastVue.numberInput(el, { precision: 2, onchange: (v) => changes.push(v) });
|
||
|
||
simulatePaste(el, '99.07');
|
||
|
||
expect(el.value).toBe('99.07');
|
||
expect(changes[changes.length - 1]).toBeCloseTo(99.07, 8);
|
||
});
|
||
});
|