import {test} from 'node:test'; import assert from 'node:assert/strict'; import {cloneAndFreezeRoomtype} from '../../YouleNexus/assets/framework/platform/stores/platform-store.ts'; import {parseCreateRoomResponse,parseRoomEntryFields} from '../../YouleNexus/assets/framework/protocol/contracts/room-contracts.ts'; import {ErqiwangRoomRules} from '../../YouleNexus/assets/games/erqiwang/erqiwang-room-rules.ts'; import {createRequire} from 'node:module'; const require=createRequire(import.meta.url); const server=require('../../../server/games/erqiwang/class.config.js'); test('all 32 UI combinations match actual server config, round-trip and fees',()=>{ for(let mask=0;mask<32;mask++){ const r=new ErqiwangRoomRules();r.open(null); for(let group=0;group<5;group++)r.select(group,(mask>>group)&1); const code=r.build();assert.match(code,/^[01]{5}0{6}$/); const cfg=server.parse(code); assert.deepEqual([cfg.aset12,cfg.deductAA,cfg.nocheck,cfg.bangwang,cfg.climb],r.selection.map(Boolean)); const copy=new ErqiwangRoomRules();copy.open(code);assert.deepEqual(copy.selection,r.selection); assert.equal(r.roomCards,(cfg.aset12?2:1)*(cfg.deductAA?1:2)); assert.equal(r.seatCount(code),3); } }); test('required groups have defaults and malformed saved configuration is rejected',()=>{ const r=new ErqiwangRoomRules();r.open(null);assert.equal(r.build(),'00000000000'); for(const invalid of ['', '0000','2'.repeat(11),[],{},123])assert.throws(()=>r.open(invalid)); assert.throws(()=>r.select(5,0));assert.throws(()=>r.select(0,2)); }); test('legacy and extended room configuration reads match server while new requests stay 11 bits',()=>{ for(const code of ['11011','110110','11011000001','11011future-extension']){ const r=new ErqiwangRoomRules();r.open(code); const cfg=server.parse(code); assert.deepEqual(r.selection.map(Boolean),[cfg.aset12,cfg.deductAA,cfg.nocheck,cfg.bangwang,cfg.climb]); assert.equal(r.seatCount(code),3); assert.equal(r.build(),'11011000000'); } }); test('invalid room configuration reports actual wire type and value',()=>{ const r=new ErqiwangRoomRules(); assert.throws(()=>r.seatCount([0,1,0]),/received array: \[0,1,0\]/); assert.throws(()=>r.seatCount('001'),/received string: "001"/); }); test('platform preserves erqiwang string through canonical state and entry responses',()=>{ const code='10100000000'; assert.equal(cloneAndFreezeRoomtype(code as never),code); assert.equal(parseCreateRoomResponse({state:0,roomcode:'123456',seat:0,roomtype:code}).room?.roomtype,code); assert.equal(parseRoomEntryFields({roomcode:'123456',seat:0,roomtype:code,players:[{},null,null]}).roomtype,code); const array=[1,[2]];const copied=cloneAndFreezeRoomtype(array); assert.deepEqual(copied,array);assert.notEqual(copied,array); assert.ok(Object.isFrozen(copied)); });