feat: integrate room framework and isolated subgame bundles
Complete room UI and protocol integration, move game definitions and resources behind bundle entries, publish authoritative version XML, and document single-game builds. Include all current resource changes and experiment artifacts.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import {DeferredNumericToolsPort} from '../../YouleNexus/assets/framework/presentation/deferred-numeric-tools.ts';
|
||||
import type {NumericToolsPort} from '../../YouleNexus/assets/framework/platform/game-host-adapter.ts';
|
||||
|
||||
function target(events:string[]):NumericToolsPort{return {
|
||||
openNumberInput:request=>{events.push('input:'+request.message);},closeNumberInput:()=>{events.push('closeInput');},
|
||||
showMultiplier:request=>{events.push('multiplier:'+request.values.join(','));},hideMultiplier:()=>{events.push('hideMultiplier');},
|
||||
close:()=>{events.push('close');},
|
||||
};}
|
||||
const input=(message:string)=>({message,onConfirm:()=>{}});
|
||||
const multiplier=(value:number)=>({values:[value],onConfirm:()=>{}});
|
||||
|
||||
test('early attach requests flush after binding in latest per-tool call order',()=>{
|
||||
const port=new DeferredNumericToolsPort(),events:string[]=[];
|
||||
port.openNumberInput(input('old'));port.showMultiplier(multiplier(2));port.openNumberInput(input('new'));
|
||||
assert.deepEqual(events,[]);port.bind(target(events));
|
||||
assert.deepEqual(events,['multiplier:2','input:new']);
|
||||
port.showMultiplier(multiplier(3));assert.equal(events[events.length-1],'multiplier:3');
|
||||
});
|
||||
test('close and hide cancel pending requests independently',()=>{
|
||||
const port=new DeferredNumericToolsPort(),events:string[]=[];
|
||||
port.openNumberInput(input('cancelled'));port.showMultiplier(multiplier(2));port.closeNumberInput();
|
||||
port.bind(target(events));assert.deepEqual(events,['multiplier:2']);
|
||||
port.unbind();port.showMultiplier(multiplier(3));port.hideMultiplier();port.bind(target(events));
|
||||
assert.deepEqual(events,['multiplier:2']);
|
||||
});
|
||||
test('lease close clears pending callbacks and unbinds the previous room',()=>{
|
||||
const port=new DeferredNumericToolsPort(),events:string[]=[];
|
||||
port.openNumberInput(input('old'));port.close();port.bind(target(events));assert.deepEqual(events,[]);
|
||||
port.close();assert.deepEqual(events,['close']);port.openNumberInput(input('new'));
|
||||
assert.deepEqual(events,['close']);port.bind(target(events));assert.deepEqual(events,['close','input:new']);
|
||||
});
|
||||
test('scene unbind retains pending requests while dropping only the current target',()=>{
|
||||
const port=new DeferredNumericToolsPort(),events:string[]=[];
|
||||
port.openNumberInput(input('pending'));port.unbind();port.bind(target(events));
|
||||
port.unbind();port.showMultiplier(multiplier(4));assert.deepEqual(events,['input:pending']);
|
||||
port.bind(target(events));assert.deepEqual(events,['input:pending','multiplier:4']);
|
||||
});
|
||||
test('bound dismissals forward directly and flushed requests are consumed exactly once',()=>{
|
||||
const port=new DeferredNumericToolsPort(),events:string[]=[];
|
||||
port.openNumberInput(input('once'));port.bind(target(events));port.closeNumberInput();port.hideMultiplier();
|
||||
port.unbind();port.bind(target(events));assert.deepEqual(events,['input:once','closeInput','hideMultiplier']);
|
||||
});
|
||||
test('lease close unbinds even when target cleanup throws',()=>{
|
||||
const port=new DeferredNumericToolsPort(),events:string[]=[];
|
||||
port.bind({...target(events),close(){throw Error('cleanup failed');}});
|
||||
assert.throws(()=>port.close(),/cleanup failed/);port.openNumberInput(input('next'));
|
||||
assert.deepEqual(events,[]);port.bind(target(events));assert.deepEqual(events,['input:next']);
|
||||
});
|
||||
|
||||
test('pending numeric requests receive cancellation on replacement and lease close',()=>{
|
||||
const port=new DeferredNumericToolsPort();const cancelled:string[]=[];
|
||||
port.openNumberInput({message:'first',onConfirm(){},onCancel(){cancelled.push('first');}});
|
||||
port.openNumberInput({message:'second',onConfirm(){},onCancel(){cancelled.push('second');}});
|
||||
port.showMultiplier({values:[1],onConfirm(){},onCancel(){cancelled.push('multiplier');throw Error('cancel failure');}});
|
||||
assert.deepEqual(cancelled,['first']);assert.throws(()=>port.close(),/cancel failure/);assert.deepEqual(cancelled,['first','second','multiplier']);
|
||||
assert.doesNotThrow(()=>port.close());
|
||||
});
|
||||
Reference in New Issue
Block a user