44 lines
6.1 KiB
JavaScript
44 lines
6.1 KiB
JavaScript
'use strict';
|
|
const vm=require('vm');
|
|
const {assert,functionSource,app,css,html,read,buildMeta}=require('./helpers/app-source');
|
|
const server=read('server.js');
|
|
const packageVersion=JSON.parse(read('package.json')).version;
|
|
assert(packageVersion===buildMeta.PACKAGE_VERSION&&buildMeta.APP_VERSION==='48.0','v47.84 canonical version marker is missing');
|
|
|
|
assert(html.includes('<div class="minimap-head"><b>マップ</b></div>')&&!html.includes('minimapStatus')&&!html.includes('周辺マップ'),'Map title or count removal is incomplete');
|
|
assert(html.includes('<span class="shop">ショップ</span>')&&functionSource('makeBoard').includes('<small>ショップ</small>'),'Shop labels were not localized');
|
|
assert(!functionSource('drawMinimap').includes('nearbyPlayers')&&!functionSource('drawMinimap').includes('visibleMetas.length')&&!functionSource('drawMinimap').includes('storeCount||0'),'Map still exposes player, board, or shop counts');
|
|
assert(!css.includes('.active-board-boundary-dash'),'Retired active-board orbit dots remain');
|
|
|
|
const renderDrag=functionSource('renderDragFrame'),overlay=functionSource('updatePickupHandleOverlay');
|
|
assert(functionSource('activeDrawingLineColorIndex').includes('startColorIndex')&&overlay.includes('activeDrawingLineColorIndex(path)'),'Pickup overlay color is not derived from the actively drawn line');
|
|
assert(renderDrag.includes('color=startColor')&&renderDrag.includes('colorChanged=drawing.lastRenderedColor!==color')&&renderDrag.includes('drawing.lastRenderedColor=color'),'Repeated grabs can retain a stale knob color');
|
|
|
|
const maybeStore=functionSource('maybeOpenStore'),normalizeStore=functionSource('normalizeStore'),renderBoard=functionSource('renderBoardNow');
|
|
assert(app.includes('STORE_CHANCE=1/10')&&server.includes('const STORE_CHANCE=1/10'),'Client/server shop appearance probability is not three times the former 1/30 rate');
|
|
assert(functionSource('storeObstacleCell').includes('puzzleOf(meta).obstacles')&&maybeStore.includes('cell=storeObstacleCell(meta)')&&maybeStore.includes('pathIndex:-1'),'Shop generation is not anchored to a former obstacle cell');
|
|
assert(normalizeStore.includes('directCell')&&functionSource('storeCellForMeta').includes('store?.cell')&&functionSource('summarizeBoardV2').includes('store?.cell'),'Obstacle-site shop coordinates are not durable');
|
|
assert(server.includes('meta?.puzzle?.obstacles||[]')&&server.includes('pathIndex:-1,cellIndex:-1,cell')&&functionSource('sanitizeStateForPuzzle').includes('st.store.cell=obstacleCell')&&functionSource('makeBoard').includes('obstacleNodes.set')&&renderBoard.includes("key===ckey(...storeCell)?'none':''"),'The replaced obstacle remains visible under the shop');
|
|
|
|
assert(functionSource('personalEconomyMode').includes('cloudProfile'),'Personal economy mode is not stable across transient connectivity changes');
|
|
for(const name of['inventoryEntries','spentScoreTotal','pruneAndCount'])assert(functionSource(name).includes('personalEconomyMode()'),`${name} can fall back to shared-board purchases during an outage`);
|
|
assert(functionSource('purchaseStoreItem').includes("personalEconomyMode()&&!onlinePlayerEconomy()")&&functionSource('purchaseStoreItem').includes('共有の所持数を確認できないため購入できません。'),'Offline personal purchases are not blocked safely');
|
|
assert(functionSource('applyPlayerEconomyEnvelope').includes('data.playerEarnedScore=Number.isSafeInteger(player.earnedScore)')&&!functionSource('applyPlayerEconomyEnvelope').includes('playerEarnedScore=Math.max'),'Personal gem balance is not server-authoritative');
|
|
assert(functionSource('rememberStateSignatures').includes('!personalEconomyMode()'),'World-store purchase deltas can still reduce personal gems');
|
|
|
|
assert(functionSource('finalizeAtGate').includes('commitConnectedLineVisuals(b,pi)')&&functionSource('joinTips').includes('commitConnectedLineVisuals'),'Connected-line visuals are not scheduled after connection');
|
|
assert(functionSource('commitConnectedLineVisuals').includes('invalidateLineGraphCaches')&&functionSource('commitConnectedLineVisuals').includes('renderBoard(b)')&&functionSource('commitConnectedLineVisuals').includes('queueLineWidthRefresh'),'Line thickness inheritance can remain stale or synchronously block pointer input after connection');
|
|
|
|
const preserveSource=functionSource('preserveSolvedBoardState');
|
|
assert(preserveSource.includes('solvedSource?._summaryOnly?baseState:solvedSource')&&preserveSource.includes('preserved.solved=true')&&preserveSource.includes('delete preserved._summaryOnly'),'Solved summary recovery can still erase full route data');
|
|
assert(!app.includes('applyWorldSignal')&&!app.includes('BroadcastChannel'),'Retired cross-tab board reconciliation remains');
|
|
assert(functionSource('hydrateMeta').includes('currentState?.solved&&!loadedState.solved')&&functionSource('hydrateMeta').includes('preserveSolvedBoardState(currentState,loadedState)'),'Rehydration can still restore an older unsolved state');
|
|
assert(functionSource('evictHydratedBoardDetails').includes('summarizeBoardV2(target,currentState'),'Eviction can still cache a stale pre-clear summary');
|
|
|
|
const context={SCORE_VERSION:6,deepClone:value=>JSON.parse(JSON.stringify(value)),mergeSpecialProgress:(a,b)=>({crossings:[...(a?.crossings||[]),...(b?.crossings||[])]}),mergePurchases:(a=[],b=[])=>[...a,...b],normalizeState:()=>({paths:[],specialProgress:{crossings:[]}})};
|
|
vm.createContext(context);vm.runInContext(`${preserveSource}\nthis.preserveSolvedBoardState=preserveSolvedBoardState;`,context);
|
|
const summary={_summaryOnly:true,solved:true,expanded:true,solvedBy:'A',scoreAwarded:500,specialProgress:{crossings:[[1,1]]}},incoming={solved:false,expanded:false,paths:[{cells:[[0,0],[0,1]]}],specialProgress:{crossings:[]},scoreAwarded:0};
|
|
const preserved=context.preserveSolvedBoardState(summary,incoming);
|
|
assert(preserved.solved===true&&preserved.paths.length===1&&preserved.paths[0].cells.length===2&&!('_summaryOnly' in preserved),'Solved-summary repair did not retain incoming full route data');
|
|
|
|
console.log('v47.84 map, store, economy, line inheritance, and clear persistence regression test passed');
|