ddd
This commit is contained in:
parent
0a343ecbc5
commit
c3a6f5ff37
80 changed files with 2512 additions and 1625 deletions
|
|
@ -2,6 +2,7 @@
|
|||
const assert=require('assert/strict');
|
||||
const vm=require('vm');
|
||||
const {functionSource,loadAppLogic}=require('./helpers/app-source');
|
||||
const {normalizeSpecialMechanics}=require('../shared-contracts');
|
||||
|
||||
const outboxContext={
|
||||
data:{states:{B0:{solved:false},B1:{solved:true}}},cloudApiEnabled:true,
|
||||
|
|
@ -33,18 +34,20 @@ assert.equal(leaseContext.sharedExpansionRepairDelay({solved:true,solvedById:'aa
|
|||
const localMeta={id:'B0',x:99,y:99,seed:1,chunks:[[0,0]],sealedSides:[],rev:9_999};
|
||||
const remoteMeta={id:'B0',x:0,y:0,seed:2,chunks:[[0,0]],sealedSides:[],rev:2_000};
|
||||
const authoritativeContext={
|
||||
cloudApiEnabled:true,
|
||||
data:{
|
||||
metas:{B0:localMeta},states:{B0:{solved:true,solvedBy:'Local',paths:[{cells:[[0,0]]}],rev:9_999}},
|
||||
nextId:99,solved:1,lastSolveAt:123,specialMechanicsSeen:['warp'],quarantine:{local:true},
|
||||
playerName:'Player',score:777,cursorStyle:'flag-jp'
|
||||
},
|
||||
isPlainObject:value=>value&&typeof value==='object'&&!Array.isArray(value),lastRevision:0,normalizedStateObjects:new Set(),
|
||||
cloudJournalMetaIds:new Set(['B0']),cloudJournalStateIds:new Set(['B0']),cloudJournalDeletedIds:new Set(),cloudOutboxDeleteKeys:new Set(),
|
||||
normalizeSpecialMechanics,
|
||||
cloudJournalMetaIds:new Set(['B0']),cloudJournalStateIds:new Set(['B0']),cloudJournalDeletedIds:new Set(),cloudOutboxDeleteKeys:new Set(),cloudJournalChangeSeq:0,
|
||||
sameMetaGeometry:(a,b)=>a.x===b.x&&a.y===b.y&&a.seed===b.seed&&JSON.stringify(a.chunks)===JSON.stringify(b.chunks)&&JSON.stringify(a.sealedSides||[])===JSON.stringify(b.sealedSides||[]),
|
||||
destroyBoard:()=>{},destroyStaticBoard:()=>{},rendered:new Map(),staticRendered:new Map(),deepClone:value=>JSON.parse(JSON.stringify(value)),
|
||||
destroyBoard:()=>{},rendered:new Map(),deepClone:value=>JSON.parse(JSON.stringify(value)),sameDataValue:(a,b)=>JSON.stringify(a)===JSON.stringify(b),
|
||||
compareRevisionVersions:(a,b)=>(a?.rev||0)-(b?.rev||0),
|
||||
mergeBoardStates:(current,incoming)=>{
|
||||
if(current?.solved&&!incoming?.solved)return JSON.parse(JSON.stringify(incoming));
|
||||
if(current?.solved&&!incoming?.solved)return JSON.parse(JSON.stringify(current));
|
||||
if(current&&!current.solved&&!incoming.solved)return{...JSON.parse(JSON.stringify(incoming)),paths:JSON.parse(JSON.stringify(current.paths||[]))};
|
||||
return JSON.parse(JSON.stringify(incoming));
|
||||
},
|
||||
|
|
@ -52,17 +55,26 @@ const authoritativeContext={
|
|||
mergeGlobalFields:()=>{throw new Error('Authoritative shared global unexpectedly used generic merge')},resolveMergedOverlaps:()=>[],statsDirty:false
|
||||
};
|
||||
vm.createContext(authoritativeContext);
|
||||
vm.runInContext(`${functionSource('clearSharedWorldJournalRow')}\n${functionSource('applyAuthoritativeSharedGlobal')}\n${functionSource('mergeSnapshotIntoData')}\nthis.mergeSnapshotIntoData=mergeSnapshotIntoData;`,authoritativeContext);
|
||||
vm.runInContext(`${functionSource('clearSharedWorldJournalRow')}\n${functionSource('noteCloudRow')}\n${functionSource('applyAuthoritativeSharedGlobal')}\n${functionSource('mergeSnapshotIntoData')}\nthis.mergeSnapshotIntoData=mergeSnapshotIntoData;`,authoritativeContext);
|
||||
authoritativeContext.mergeSnapshotIntoData({
|
||||
metas:{B0:remoteMeta},states:{B0:{solved:false,paths:[],rev:2_000}},
|
||||
nextId:2,solved:0,lastSolveAt:0,specialMechanicsSeen:['lock'],quarantine:{shared:true}
|
||||
},{finalize:false,authoritativeWorld:true});
|
||||
assert.equal(authoritativeContext.data.metas.B0.seed,2,'An existing local world row overrode the authoritative shared board');
|
||||
assert.equal(authoritativeContext.data.states.B0.solved,false,'An unconfirmed local clear survived authoritative shared adoption');
|
||||
assert.equal(authoritativeContext.data.states.B0.solved,false,'A clear from a replaced board definition leaked into the authoritative shared board');
|
||||
assert.equal(authoritativeContext.data.nextId,2,'A private local board counter leaked into the shared world');
|
||||
assert.equal(authoritativeContext.data.playerName,'Player');assert.equal(authoritativeContext.data.score,777);assert.equal(authoritativeContext.data.cursorStyle,'flag-jp');
|
||||
assert.equal(authoritativeContext.cloudJournalMetaIds.size,0);assert.equal(authoritativeContext.cloudJournalStateIds.size,0);
|
||||
assert(authoritativeContext.cloudOutboxDeleteKeys.has('meta:B0')&&authoritativeContext.cloudOutboxDeleteKeys.has('state:B0'),'Adopted shared rows did not clear stale local outbox records');
|
||||
assert(authoritativeContext.cloudOutboxDeleteKeys.has('meta:B0')&&authoritativeContext.cloudOutboxDeleteKeys.has('state:B0'),'Replaced shared rows did not clear stale local outbox records');
|
||||
|
||||
// A durable clear for the same board definition survives a stale authoritative snapshot and is queued for upload.
|
||||
authoritativeContext.cloudJournalStateIds.clear();authoritativeContext.cloudOutboxDeleteKeys.clear();
|
||||
authoritativeContext.data.metas.B0=JSON.parse(JSON.stringify(remoteMeta));
|
||||
authoritativeContext.data.states.B0={solved:true,solvedBy:'Local',paths:[{cells:[[0,0]]}],rev:9_999};
|
||||
authoritativeContext.mergeSnapshotIntoData({metas:{B0:{...remoteMeta,rev:4_000}},states:{B0:{solved:false,paths:[],rev:4_000}},nextId:2},{finalize:false,authoritativeWorld:true});
|
||||
assert.equal(authoritativeContext.data.states.B0.solved,true,'A durable clear was downgraded by a stale authoritative snapshot of the same board');
|
||||
assert.deepEqual([...authoritativeContext.cloudJournalStateIds],['B0'],'The retained clear was not queued for shared upload');
|
||||
assert.equal(authoritativeContext.cloudOutboxDeleteKeys.has('state:B0'),false,'The retained clear was incorrectly scheduled for deletion');
|
||||
|
||||
// Matching unsolved boards keep the player's unfinished line locally while the board definition stays shared.
|
||||
authoritativeContext.data.metas.B0=remoteMeta;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue