* feat(workspace): group saved negative variants in native library (#208) * fix(library): preserve full name order and batch previews (#208)
24 lines
1.7 KiB
JavaScript
24 lines
1.7 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {createScope} from '../../web/js/shared/toolkit/core.js';
|
|
import {mountImages} from '../../web/js/workspace/images.mjs';
|
|
|
|
test('Images mounted after its parent is aborted creates no DOM, requests or observers',()=>{
|
|
const parent=createScope();parent.dispose();
|
|
const originals=new Map(['document','window','ResizeObserver','IntersectionObserver'].map(key=>[key,Object.getOwnPropertyDescriptor(globalThis,key)]));
|
|
const touches=[];
|
|
const forbidden=name=>new Proxy({}, {get(target,key){touches.push(`${name}.${String(key)}`);throw Error(`Disposed mount accessed ${name}.${String(key)}`);}});
|
|
Object.defineProperty(globalThis,'document',{configurable:true,value:forbidden('document')});
|
|
Object.defineProperty(globalThis,'window',{configurable:true,value:forbidden('window')});
|
|
for(const key of ['ResizeObserver','IntersectionObserver']) Object.defineProperty(globalThis,key,{configurable:true,value:class {constructor(){touches.push(key);throw Error('Observer created after parent disposal');}}});
|
|
const api={get(){touches.push('request');assert.fail('Request started after parent disposal');}};
|
|
try {
|
|
let mounted;
|
|
assert.doesNotThrow(()=>{mounted=mountImages(forbidden('container'),api,parent,{embedded:true,fetchPage(){touches.push('page');assert.fail('Page requested after parent disposal');}});});
|
|
assert.equal(typeof mounted.dispose,'function');mounted.dispose();mounted.dispose();
|
|
assert.deepEqual(touches,[]);
|
|
} finally {
|
|
for(const [key,descriptor] of originals) {if(descriptor) Object.defineProperty(globalThis,key,descriptor);else delete globalThis[key];}
|
|
}
|
|
});
|