bend_puzzle/test/expansion-repair-smoke-test.js
2026-08-01 16:06:14 +09:00

39 lines
1.8 KiB
JavaScript

'use strict';
const {vm,assert,functionSource}=require('./helpers/app-source');
const state={solved:true,expanded:false,expansionRetryRound:0,rev:0};
const meta={id:'B0',puzzle:null,x:0,y:0};
const chosen=[],attemptBases=[];
let revision=0,missing=true,hydrations=0;
const context={
metaState:()=>state,
canExpandSharedBoard:()=>true,
hydrateMeta:async target=>{hydrations++;target.puzzle={}},
hydrateAdjacentMetas:async()=>{},
rebuildOccupancy:()=>{},
repairFacingGateConnections:()=>{},
unresolvedExpansionCandidates:()=>[{name:'north'},{name:'east'}],
placeChildAtFrontierAttempt:async(_meta,frontier,attemptBase)=>{
chosen.push(frontier.name);attemptBases.push(attemptBase);return null;
},
missingGateConnections:()=>missing?[1]:[],
nextRevision:()=>++revision,
markStateDirty:()=>{}
};
vm.createContext(context);
vm.runInContext(`${functionSource('repairMetaFrontierNow')}\nthis.repairMetaFrontierNow=repairMetaFrontierNow;`,context);
(async()=>{
await context.repairMetaFrontierNow(meta);
await context.repairMetaFrontierNow(meta);
await context.repairMetaFrontierNow(meta);
assert(chosen.join(',')==='north,east,north','Expansion repair stayed on one linear frontier instead of rotating fairly');
assert(hydrations===1,'Expansion repair skipped or repeatedly hydrated an off-screen compact board');
assert(new Set(attemptBases).size===3,'Expansion repair repeated a deterministic generation seed');
assert(state.expansionRetryRound===3&&!state.expanded,'Incomplete expansion repair did not persist its retry round');
missing=false;
await context.repairMetaFrontierNow(meta);
assert(state.expanded&&state.expansionRetryRound===0,'Completed expansion repair did not clear its retry state');
console.log('Fair expansion-frontier retry test passed');
})().catch(error=>{console.error(error);process.exitCode=1});