import test from 'node:test'; import assert from 'node:assert/strict'; import {NumericInputModel} from '../../YouleNexus/assets/framework/presentation/numeric-input-model.ts'; import {MultiplierModel} from '../../YouleNexus/assets/framework/presentation/multiplier-model.ts'; test('numeric input preserves string leading zeros and caller owns closing',()=>{ const results:(string|number)[]=[]; const model=new NumericInputModel({message:'请输入',begin0:true,onConfirm:value=>results.push(value)}); assert.equal(model.text,'');model.inputDigit(0);model.inputDigit(7); assert.equal(model.confirm(),'07');assert.deepEqual(results,['07']);assert.equal(model.text,'07'); model.backspace();model.backspace();model.backspace();assert.equal(model.text,''); }); test('numeric input number mode replaces zero and confirms number',()=>{ const model=new NumericInputModel({message:'金额',begin0:false,onConfirm:()=>{}}); assert.equal(model.text,'0');model.inputDigit(0);model.inputDigit(8);assert.equal(model.confirm(),8); model.backspace();assert.equal(model.text,'0'); }); test('numeric input filters paste and enforces 18 digits without losing prior value',()=>{ const model=new NumericInputModel({message:'ID',begin0:true,onConfirm:()=>{}}); assert.equal(model.paste('id: 0001-23456789012345'),null);assert.equal(model.text,'000123456789012345'); assert.equal(model.inputDigit(9),'输入超出范围');assert.equal(model.paste('1'.repeat(19)),'输入超出范围'); assert.equal(model.text,'000123456789012345');model.paste('abc');assert.equal(model.text,''); assert.throws(()=>model.inputDigit(12)); }); function storage(initial:string|null=null){ const values=new Map();if(initial!==null)values.set('tsgame_multiple_161007',initial); return {values,getItem:(key:string)=>values.get(key)??null,setItem:(key:string,value:string)=>{values.set(key,value);}}; } test('calculator defaults its persisted preference at the source and resets invalid preference',()=>{ for(const initial of [null,'0','nonsense','1b2','-1']){ const saved=storage(initial);const model=new MultiplierModel({originalValues:[2],onConfirm:()=>{},storage:saved,gameid:16,agentid:1007}); assert.equal(model.text,'1');assert.equal(saved.values.get('tsgame_multiple_161007'),'1'); } }); test('calculator uses b marker, rejects duplicate decimal and 9th character',()=>{ const model=new MultiplierModel({originalValues:[],onConfirm:()=>{},storage:storage('1.2'),gameid:16,agentid:1007}); assert.equal(model.text,'1b2');assert.equal(model.inputDecimal(),'输入不正确!'); for(const digit of [3,4,5,6,7])assert.equal(model.inputDigit(digit),null); assert.equal(model.inputDigit(8),'输入长度超过限制!');assert.equal(model.text,'1b234567'); assert.throws(()=>model.inputDigit(-1)); }); test('calculator multiplies supplied originals with decimal precision and persists before callback',()=>{ const saved=storage('0.2');const originals=[0.1,-1.25,0];let result:number[]=[]; const model=new MultiplierModel({originalValues:originals,onConfirm:values=>{result=values;assert.equal(saved.getItem('tsgame_multiple_161007'),'0.2');},storage:saved,gameid:16,agentid:1007}); originals[0]=999;assert.deepEqual(model.confirm(),[0.02,-0.25,0]);assert.deepEqual(result,[0.02,-0.25,0]); }); test('calculator zero confirms as one and normalizes display',()=>{ const model=new MultiplierModel({originalValues:[3],onConfirm:()=>{},storage:storage(),gameid:16,agentid:1007}); model.backspace();assert.equal(model.text,'0');model.inputDecimal();assert.equal(model.text,'0b'); assert.deepEqual(model.confirm(),[3]);assert.equal(model.text,'1');assert.equal(model.multiplier,1); }); test('calculator refuses non-finite original values instead of fabricating results',()=>{ assert.throws(()=>new MultiplierModel({originalValues:[NaN],onConfirm:()=>{},storage:storage(),gameid:16,agentid:1007})); }); test('calculator decimal multiplication supports finite scientific notation',()=>{ const model=new MultiplierModel({originalValues:[1e30,1e-7],onConfirm:()=>{},storage:storage('0.2'),gameid:16,agentid:1007}); assert.deepEqual(model.confirm(),[2e29,2e-8]); });