import json import subprocess from pathlib import Path ROOT = Path(__file__).resolve().parents[2] def test_large_edit_history_is_compressed_and_restores_independent_snapshots(): script = r""" const fs=require('node:fs'),vm=require('node:vm'); const context=vm.createContext({Response,Blob,CompressionStream,DecompressionStream, document:{addEventListener(){}},console}); vm.runInContext(fs.readFileSync(process.argv[1],'utf8')+';globalThis.app=EstApp',context); (async()=>{ const {app}=context; app.state.project={name:'before',binary:'x'.repeat(11*1024*1024)}; app.remember(); app.state.project.name='after'; const entry=await app.state.history[0],restored=await app.restore(entry); if(!(entry instanceof Blob)||entry.size>=100000)throw Error('History is not compressed'); if(restored.name!=='before'||restored.binary.length!==11*1024*1024) throw Error('Snapshot was changed or truncated'); restored.name='independent'; if((await app.restore(entry)).name!=='before')throw Error('Snapshot shares mutable data'); app.state.project={name:'small'}; app.state.future=['discard']; for(let i=0;i<10;i++){app.state.project.name=String(i);app.remember();} if(app.state.history.length!==8||app.state.future.length)throw Error('History limits'); if((await app.restore(app.state.history[0])).name!=='2')throw Error('History ordering'); context.CompressionStream=undefined; app.state.project={binary:'y'.repeat(11*1024*1024)}; const fallback=app.snapshot(); if(typeof fallback!=='string')throw Error('Missing platform fallback'); if((await app.restore(fallback)).binary.length!==11*1024*1024) throw Error('Fallback truncated'); console.log(JSON.stringify({compressedBytes:entry.size,revision:app.state.revision})); })().catch(error=>{console.error(error);process.exitCode=1}); """ result = json.loads( subprocess.check_output( ["node", "-e", script, str(ROOT / "tools/est-test/native-app.js")], text=True, encoding="utf-8", ) ) assert result["compressedBytes"] < 100_000 assert result["revision"] == 11