import assert from "node:assert/strict"; import fs from "node:fs"; import factory from "../../web/app/src/vendor/blender/web_engine.js"; const root = new URL("../../", import.meta.url); const wasmBinary = fs.readFileSync(new URL("web/app/src/vendor/blender/web_engine.wasm", root)); const fixture = fs.readFileSync(new URL("tests/files/web/basic_scene.blend", root)); function open(engine, handle, bytes) { const pointer = engine._malloc(bytes.byteLength); try { engine.HEAPU8.set(bytes, pointer); assert.equal(engine._web_engine_open_blend(handle, pointer, bytes.byteLength), 0, engine.UTF8ToString(engine._web_engine_last_error_message())); } finally { engine._free(pointer); } } function snapshot(engine, handle) { const dataOut = engine._malloc(4), lengthOut = engine._malloc(4); try { assert.equal(engine._web_engine_get_scene_snapshot(handle, dataOut, lengthOut), 0, engine.UTF8ToString(engine._web_engine_last_error_message())); const pointer = engine.HEAPU32[dataOut >>> 2], length = engine.HEAPU32[lengthOut >>> 2]; return JSON.parse(new TextDecoder().decode(engine.HEAPU8.slice(pointer, pointer + length))); } finally { engine._free(dataOut); engine._free(lengthOut); } } const supportedEditors = new Set([ "VIEW_3D", "OUTLINER", "PROPERTIES", "UV_IMAGE", "NODE", "GRAPH", "DOPE_SHEET", "NLA", "SPREADSHEET", "SEQUENCER", "CLIP", ]); const regionKinds = new Set(["HEADER", "MAIN", "TOOLBAR", "SIDEBAR", "FOOTER"]); const engine = await factory({ wasmBinary: wasmBinary.slice() }); const handle = engine._web_engine_create(); open(engine, handle, fixture); const scene = snapshot(engine, handle); assert.equal(scene.editorWorkflowStatus, "AVAILABLE"); const workflow = scene.editorWorkflow; assert.equal(workflow.schemaVersion, 1); assert.ok(workflow.workspaces.length > 0 && workflow.workspaces.length <= 64); let areaCount = 0, regionCount = 0; for (const workspace of workflow.workspaces) { assert.ok(workspace.areas.some((area) => area.id === workspace.activeAreaId)); assert.equal(workspace.revision, scene.revision); areaCount += workspace.areas.length; for (const area of workspace.areas) { assert.ok(supportedEditors.has(area.editor), `unsupported editor ${area.editor}`); assert.ok(area.rect.x >= 0 && area.rect.y >= 0 && area.rect.width > 0 && area.rect.height > 0); assert.ok(area.rect.x + area.rect.width <= 1 && area.rect.y + area.rect.height <= 1); assert.ok(area.regions.some((region) => region.kind === "MAIN")); regionCount += area.regions.length; for (const region of area.regions) assert.ok(regionKinds.has(region.kind)); } } assert.ok(areaCount <= 1024 && regionCount <= 4096); const activeWorkspace = workflow.workspaces.find((workspace) => workspace.id === workflow.context.workspaceId); const activeArea = activeWorkspace?.areas.find((area) => area.id === workflow.context.activeAreaId); assert.equal(activeArea?.editor, workflow.context.activeEditor); assert.equal(workflow.context.revision, scene.revision); assert.equal(workflow.context.activeObjectId, scene.activeObjectId); assert.deepEqual(workflow.context.selection, scene.activeObjectId === null ? [] : [scene.activeObjectId]); assert.deepEqual(workflow.keymaps, []); engine._web_engine_destroy(handle); process.stdout.write(`editor-main-reader-ok workspaces=${workflow.workspaces.length} areas=${areaCount} regions=${regionCount}\n`);