import assert from "node:assert/strict"; import crypto from "node:crypto"; 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/script_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 engine = await factory({ wasmBinary: wasmBinary.slice() }); const handle = engine._web_engine_create(); open(engine, handle, fixture); const scene = snapshot(engine, handle); assert.equal(scene.scriptSourceStatus, "AVAILABLE"); assert.equal(scene.scriptSources.schemaVersion, 1); assert.equal(scene.scriptSources.sources.length, 3); assert.equal(scene.nonMeshData.some((data) => data.id.startsWith("text:")), false); const byName = new Map(scene.scriptSources.sources.map((source) => [source.name, source])); for (const source of byName.values()) { assert.equal(source.byteLength, Buffer.byteLength(source.source)); assert.equal(source.lineCount, source.source.split("\n").length); assert.equal(source.sourceSha256, crypto.createHash("sha256").update(source.source).digest("hex")); assert.equal(source.readOnly, true); assert.equal(source.executionStatus, "BLOCKED"); } assert.equal(byName.get("InternalSafe.py").source, "value = 7\nprint(value)\n"); assert.equal(byName.get("InternalSafe.py").internal, true); assert.equal(byName.get("InternalSafe.py").errorCode, "SCRIPT_SANDBOX_UNAVAILABLE"); assert.equal(byName.get("ModuleAutorun.py").moduleAutorunRequested, true); assert.equal(byName.get("ModuleAutorun.py").errorCode, "SCRIPT_POLICY_DENIED"); assert.equal(byName.get("ExternalProject.py").sourcePath, "//scripts/external_project.py"); assert.equal(byName.get("ExternalProject.py").internal, false); engine._web_engine_destroy(handle); process.stdout.write("script-main-reader-ok full-source=passed sha256=passed autorun-default-deny=passed\n");