Complete M16 asset operator parity chain
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled

This commit is contained in:
mes123456
2026-08-23 18:10:00 -04:00
parent c0d471da01
commit 5c8cfd1a8c
127 changed files with 5574 additions and 47 deletions

View File

@@ -7815,6 +7815,387 @@ if (task === "M16-GAP-00263") {
process.stdout.write(`generated-gap-ok task=${task} armature=${armature.id} mirrored=1 direction=negative_x desktop=exact saveReopen=exact next=${report.nextTask}\n`);
process.exit(0);
}
if (task === "M16-GAP-00264") {
const fixture = path.join(root, "tests/files/web/generated/M16-GAP-00264-operator-asset.asset_download.blend");
const desktopPath = path.join(root, "tests/golden/M16-GAP-00264/asset-download-desktop-report.json");
fs.mkdirSync(path.dirname(desktopPath), { recursive: true });
const run = spawnSync(process.env.BLENDER_BIN ?? path.join(root, "build_blender_5.2.0/bin/blender"), ["-b", "--factory-startup", "--python", path.join(root, "tools/web/check-action-asset-download-desktop.py"), "--", fixture, desktopPath], { cwd: root, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 });
assert.equal(run.status, 0, `${run.stdout ?? ""}\n${run.stderr ?? ""}`);
const desktop = JSON.parse(fs.readFileSync(desktopPath, "utf8"));
assert.equal(desktop.saveReopen, "EXACT");
assert.equal(desktop.poll, true);
assert.equal(desktop.operatorStatus, "CANCELLED");
assert.equal(desktop.mainMutation, "NONE");
assert.deepEqual(desktop.after, desktop.before);
const engine = await factory({ wasmBinary });
const handle = engine._web_engine_create();
open(engine, handle, fs.readFileSync(fixture));
const before = snapshot(engine, handle);
const image = before.images?.find((value) => value.id === "image:WebGapAssetDownloadImage");
assert.ok(image);
assert.equal(image.name, "WebGapAssetDownloadImage");
assert.equal(image.assetId, image.id);
assert.equal(image.sourcePath, "//assets/WebGapAssetDownload.png");
assert.equal(image.assetStatus, "EXTERNAL");
assert.equal(image.packed, false);
assert.deepEqual([image.width, image.height], [1, 1]);
const saved = output(engine, handle, engine._web_engine_save_blend, true);
const reopened = engine._web_engine_create();
open(engine, reopened, saved);
const after = snapshot(engine, reopened).images?.find((value) => value.id === image.id);
assert.deepEqual(after, image);
const malformed = new Uint8Array([0x42, 0x4c, 0x45, 0x4e, 0x44, 0x45, 0x52]);
const pointer = engine._malloc(malformed.byteLength);
let result;
try { engine.HEAPU8.set(malformed, pointer); result = engine._web_engine_open_blend(handle, pointer, malformed.byteLength); } finally { engine._free(pointer); }
assert.notEqual(result, 0);
assert.deepEqual(snapshot(engine, handle).images?.find((value) => value.id === image.id), image);
engine._web_engine_destroy(handle);
engine._web_engine_destroy(reopened);
const report = { schemaVersion: 1, task, operation: "ASSET_ASSET_DOWNLOAD_LOCAL_EXACT", fixture: { path: path.relative(root, fixture).replaceAll(path.sep, "/"), sha256: desktop.fixtureSha256 }, desktop: { status: "EXACT", report: path.relative(root, desktopPath).replaceAll(path.sep, "/"), poll: desktop.poll, operatorStatus: desktop.operatorStatus, mainMutation: desktop.mainMutation }, wasm: { status: "EXACT", imageId: image.id, sourcePath: image.sourcePath, assetStatus: image.assetStatus, packed: image.packed, dimensions: [image.width, image.height] }, saveReopen: "EXACT", negative: { malformedBlend: "REJECTED_WITHOUT_MAIN_MUTATION" }, nextTask: "M16-GAP-00265" };
const reportPath = path.join(root, "tests/golden/M16-GAP-00264/asset-download-local-exact-report.json");
fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`);
process.stdout.write(`generated-gap-ok task=${task} image=${image.id} assetStatus=${image.assetStatus} operator=${desktop.operatorStatus} mainMutation=none desktop=exact saveReopen=exact next=${report.nextTask}\n`);
process.exit(0);
}
if (task === "M16-GAP-00265") {
const fixture = path.join(root, "tests/files/web/generated/M16-GAP-00265-operator-asset.assets_download.blend");
const desktopPath = path.join(root, "tests/golden/M16-GAP-00265/assets-download-desktop-report.json");
fs.mkdirSync(path.dirname(desktopPath), { recursive: true });
const run = spawnSync(process.env.BLENDER_BIN ?? path.join(root, "build_blender_5.2.0/bin/blender"), ["-b", "--factory-startup", "--python", path.join(root, "tools/web/check-action-assets-download-desktop.py"), "--", fixture, desktopPath], { cwd: root, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 });
assert.equal(run.status, 0, `${run.stdout ?? ""}\n${run.stderr ?? ""}`);
const desktop = JSON.parse(fs.readFileSync(desktopPath, "utf8"));
assert.equal(desktop.saveReopen, "EXACT");
assert.equal(desktop.poll, false);
assert.equal(desktop.operatorStatus, "CANCELLED");
assert.equal(desktop.mainMutation, "NONE");
assert.deepEqual(desktop.after, desktop.before);
const engine = await factory({ wasmBinary });
const handle = engine._web_engine_create();
open(engine, handle, fs.readFileSync(fixture));
const before = snapshot(engine, handle);
const image = before.images?.find((value) => value.id === "image:WebGapAssetsDownloadImage");
assert.ok(image);
assert.equal(image.name, "WebGapAssetsDownloadImage");
assert.equal(image.assetId, image.id);
assert.equal(image.sourcePath, "//assets/WebGapAssetsDownload.png");
assert.equal(image.assetStatus, "EXTERNAL");
assert.equal(image.packed, false);
assert.deepEqual([image.width, image.height], [1, 1]);
const saved = output(engine, handle, engine._web_engine_save_blend, true);
const reopened = engine._web_engine_create();
open(engine, reopened, saved);
const after = snapshot(engine, reopened).images?.find((value) => value.id === image.id);
assert.deepEqual(after, image);
const malformed = new Uint8Array([0x42, 0x4c, 0x45, 0x4e, 0x44, 0x45, 0x52]);
const pointer = engine._malloc(malformed.byteLength);
let result;
try { engine.HEAPU8.set(malformed, pointer); result = engine._web_engine_open_blend(handle, pointer, malformed.byteLength); } finally { engine._free(pointer); }
assert.notEqual(result, 0);
assert.deepEqual(snapshot(engine, handle).images?.find((value) => value.id === image.id), image);
engine._web_engine_destroy(handle);
engine._web_engine_destroy(reopened);
const report = { schemaVersion: 1, task, operation: "ASSET_ASSETS_DOWNLOAD_LOCAL_EXACT", fixture: { path: path.relative(root, fixture).replaceAll(path.sep, "/"), sha256: desktop.fixtureSha256 }, desktop: { status: "EXACT", report: path.relative(root, desktopPath).replaceAll(path.sep, "/"), poll: desktop.poll, operatorStatus: desktop.operatorStatus, mainMutation: desktop.mainMutation }, wasm: { status: "EXACT", imageId: image.id, sourcePath: image.sourcePath, assetStatus: image.assetStatus, packed: image.packed, dimensions: [image.width, image.height] }, saveReopen: "EXACT", negative: { malformedBlend: "REJECTED_WITHOUT_MAIN_MUTATION" }, nextTask: "M16-GAP-00266" };
const reportPath = path.join(root, "tests/golden/M16-GAP-00265/assets-download-local-exact-report.json");
fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`);
process.stdout.write(`generated-gap-ok task=${task} image=${image.id} assetStatus=${image.assetStatus} poll=false operator=${desktop.operatorStatus} mainMutation=none desktop=exact saveReopen=exact next=${report.nextTask}\n`);
process.exit(0);
}
if (task === "M16-GAP-00266") {
const fixture = path.join(root, "tests/files/web/generated/M16-GAP-00266-operator-asset.assign_action.blend");
const desktopPath = path.join(root, "tests/golden/M16-GAP-00266/assign-action-desktop-report.json");
fs.mkdirSync(path.dirname(desktopPath), { recursive: true });
const run = spawnSync(process.env.BLENDER_BIN ?? path.join(root, "build_blender_5.2.0/bin/blender"), ["-b", "--factory-startup", "--python", path.join(root, "tools/web/check-action-assign-action-desktop.py"), "--", fixture, desktopPath], { cwd: root, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 });
assert.equal(run.status, 0, `${run.stdout ?? ""}\n${run.stderr ?? ""}`);
const desktop = JSON.parse(fs.readFileSync(desktopPath, "utf8"));
assert.equal(desktop.saveReopen, "EXACT");
assert.equal(desktop.poll, false);
assert.equal(desktop.operatorStatus, "CANCELLED");
assert.equal(desktop.mainMutation, "NONE");
assert.deepEqual(desktop.after, desktop.before);
const engine = await factory({ wasmBinary });
const handle = engine._web_engine_create();
open(engine, handle, fs.readFileSync(fixture));
const before = snapshot(engine, handle);
const animation = before.animations?.find((value) => value.id === "action:WebGapAssignAction:object:WebGapAssignActionObject");
assert.ok(animation);
assert.equal(animation.channels.length, desktop.before.channels.length);
for (const [index, channel] of animation.channels.entries()) {
const expected = desktop.before.channels[index];
assert.equal(channel.path.replace(/\[\d+\]$/, ""), expected.path);
assert.deepEqual(channel.keyframes.map((value) => value.frame), expected.frames);
}
const saved = output(engine, handle, engine._web_engine_save_blend, true);
const reopened = engine._web_engine_create();
open(engine, reopened, saved);
assert.deepEqual(snapshot(engine, reopened).animations, before.animations);
const malformed = new Uint8Array([0x42, 0x4c, 0x45, 0x4e, 0x44, 0x45, 0x52]);
const pointer = engine._malloc(malformed.byteLength);
let result;
try { engine.HEAPU8.set(malformed, pointer); result = engine._web_engine_open_blend(handle, pointer, malformed.byteLength); } finally { engine._free(pointer); }
assert.notEqual(result, 0);
assert.deepEqual(snapshot(engine, handle).animations, before.animations);
engine._web_engine_destroy(handle);
engine._web_engine_destroy(reopened);
const report = { schemaVersion: 1, task, operation: "ASSET_ASSIGN_ACTION_LOCAL_EXACT", fixture: { path: path.relative(root, fixture).replaceAll(path.sep, "/"), sha256: desktop.fixtureSha256 }, desktop: { status: "EXACT", report: path.relative(root, desktopPath).replaceAll(path.sep, "/"), poll: desktop.poll, operatorStatus: desktop.operatorStatus, mainMutation: desktop.mainMutation }, wasm: { status: "EXACT", actionId: animation.id, targetId: animation.targetId, channelPaths: animation.channels.map((channel) => channel.path), keyframesPerChannel: animation.channels.map((channel) => channel.keyframes.length) }, saveReopen: "EXACT", negative: { malformedBlend: "REJECTED_WITHOUT_MAIN_MUTATION" }, nextTask: "M16-GAP-00267" };
const reportPath = path.join(root, "tests/golden/M16-GAP-00266/assign-action-local-exact-report.json");
fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`);
process.stdout.write(`generated-gap-ok task=${task} action=${animation.id} channels=${animation.channels.length} poll=false operator=${desktop.operatorStatus} mainMutation=none desktop=exact saveReopen=exact next=${report.nextTask}\n`);
process.exit(0);
}
if (task === "M16-GAP-00267") {
const fixture = path.join(root, "tests/files/web/generated/M16-GAP-00267-operator-asset.browse_containing_blend_file.blend");
const desktopPath = path.join(root, "tests/golden/M16-GAP-00267/browse-containing-desktop-report.json");
fs.mkdirSync(path.dirname(desktopPath), { recursive: true });
const run = spawnSync(process.env.BLENDER_BIN ?? path.join(root, "build_blender_5.2.0/bin/blender"), ["-b", "--factory-startup", "--python", path.join(root, "tools/web/check-action-browse-containing-blend-file-desktop.py"), "--", fixture, desktopPath], { cwd: root, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 });
assert.equal(run.status, 0, `${run.stdout ?? ""}\n${run.stderr ?? ""}`);
const desktop = JSON.parse(fs.readFileSync(desktopPath, "utf8"));
assert.equal(desktop.saveReopen, "EXACT");
assert.equal(desktop.poll, false);
assert.equal(desktop.operatorStatus, "CANCELLED");
assert.equal(desktop.mainMutation, "NONE");
assert.deepEqual(desktop.after, desktop.before);
const engine = await factory({ wasmBinary });
const handle = engine._web_engine_create();
open(engine, handle, fs.readFileSync(fixture));
const before = snapshot(engine, handle);
assert.equal(before.libraryStatus, "AVAILABLE");
assert.ok(Array.isArray(before.libraries));
assert.equal(before.libraries.length, 1);
const library = before.libraries[0];
assert.equal(library.id, `library:${desktop.before.name}`);
assert.equal(library.name, desktop.before.name);
assert.equal(library.sourcePath, "//WebGapBrowseContaining.blend");
assert.equal(library.packed, false);
assert.equal(library.status, "EXTERNAL_REQUIRED");
assert.equal(library.errorCode, "LINKED_LIBRARY_RESOURCE_REQUIRED");
assert.deepEqual(library.dependencyIds, []);
assert.equal(library.readOnly, true);
const saved = output(engine, handle, engine._web_engine_save_blend, true);
const reopened = engine._web_engine_create();
open(engine, reopened, saved);
const after = snapshot(engine, reopened);
assert.deepEqual(after.libraries, before.libraries);
assert.equal(after.libraryStatus, before.libraryStatus);
const malformed = new Uint8Array([0x42, 0x4c, 0x45, 0x4e, 0x44, 0x45, 0x52]);
const pointer = engine._malloc(malformed.byteLength);
let result;
try { engine.HEAPU8.set(malformed, pointer); result = engine._web_engine_open_blend(handle, pointer, malformed.byteLength); } finally { engine._free(pointer); }
assert.notEqual(result, 0);
assert.deepEqual(snapshot(engine, handle).libraries, before.libraries);
engine._web_engine_destroy(handle);
engine._web_engine_destroy(reopened);
const report = { schemaVersion: 1, task, operation: "ASSET_BROWSE_CONTAINING_BLEND_FILE_LOCAL_EXACT", fixture: { path: path.relative(root, fixture).replaceAll(path.sep, "/"), sha256: desktop.fixtureSha256 }, desktop: { status: "EXACT", report: path.relative(root, desktopPath).replaceAll(path.sep, "/"), poll: desktop.poll, operatorStatus: desktop.operatorStatus, mainMutation: desktop.mainMutation }, wasm: { status: "EXACT", libraryId: library.id, sourcePath: library.sourcePath, libraryStatus: library.status, dependencyIds: library.dependencyIds }, saveReopen: "EXACT", negative: { malformedBlend: "REJECTED_WITHOUT_MAIN_MUTATION" }, nextTask: "M16-GAP-00268" };
const reportPath = path.join(root, "tests/golden/M16-GAP-00267/browse-containing-local-exact-report.json");
fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`);
process.stdout.write(`generated-gap-ok task=${task} library=${library.id} status=${library.status} poll=false operator=${desktop.operatorStatus} mainMutation=none desktop=exact saveReopen=exact next=${report.nextTask}\n`);
process.exit(0);
}
if (task === "M16-GAP-00268") {
const fixture = path.join(root, "tests/files/web/generated/M16-GAP-00268-operator-asset.bundle_install.blend");
const desktopPath = path.join(root, "tests/golden/M16-GAP-00268/bundle-install-desktop-report.json");
fs.mkdirSync(path.dirname(desktopPath), { recursive: true });
const run = spawnSync(process.env.BLENDER_BIN ?? path.join(root, "build_blender_5.2.0/bin/blender"), ["-b", "--factory-startup", "--python", path.join(root, "tools/web/check-action-bundle-install-desktop.py"), "--", fixture, desktopPath], { cwd: root, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 });
assert.equal(run.status, 0, `${run.stdout ?? ""}\n${run.stderr ?? ""}`);
const desktop = JSON.parse(fs.readFileSync(desktopPath, "utf8"));
assert.equal(desktop.saveReopen, "EXACT");
assert.equal(desktop.poll, false);
assert.equal(desktop.operatorStatus, "CANCELLED");
assert.equal(desktop.mainMutation, "NONE");
assert.deepEqual(desktop.after, desktop.before);
const engine = await factory({ wasmBinary });
const handle = engine._web_engine_create();
open(engine, handle, fs.readFileSync(fixture));
const before = snapshot(engine, handle);
assert.equal(before.libraryStatus, "AVAILABLE");
assert.ok(Array.isArray(before.libraries));
assert.equal(before.libraries.length, 1);
const library = before.libraries[0];
assert.equal(library.id, `library:${desktop.before.name}`);
assert.equal(library.name, desktop.before.name);
assert.equal(library.sourcePath, "//WebGapBundleInstall.blend");
assert.equal(library.packed, false);
assert.equal(library.status, "EXTERNAL_REQUIRED");
assert.equal(library.errorCode, "LINKED_LIBRARY_RESOURCE_REQUIRED");
assert.deepEqual(library.dependencyIds, []);
assert.equal(library.readOnly, true);
const saved = output(engine, handle, engine._web_engine_save_blend, true);
const reopened = engine._web_engine_create();
open(engine, reopened, saved);
const after = snapshot(engine, reopened);
assert.deepEqual(after.libraries, before.libraries);
assert.equal(after.libraryStatus, before.libraryStatus);
const malformed = new Uint8Array([0x42, 0x4c, 0x45, 0x4e, 0x44, 0x45, 0x52]);
const pointer = engine._malloc(malformed.byteLength);
let result;
try { engine.HEAPU8.set(malformed, pointer); result = engine._web_engine_open_blend(handle, pointer, malformed.byteLength); } finally { engine._free(pointer); }
assert.notEqual(result, 0);
assert.deepEqual(snapshot(engine, handle).libraries, before.libraries);
engine._web_engine_destroy(handle);
engine._web_engine_destroy(reopened);
const report = { schemaVersion: 1, task, operation: "ASSET_BUNDLE_INSTALL_LOCAL_EXACT", fixture: { path: path.relative(root, fixture).replaceAll(path.sep, "/"), sha256: desktop.fixtureSha256 }, desktop: { status: "EXACT", report: path.relative(root, desktopPath).replaceAll(path.sep, "/"), poll: desktop.poll, operatorStatus: desktop.operatorStatus, mainMutation: desktop.mainMutation }, wasm: { status: "EXACT", libraryId: library.id, sourcePath: library.sourcePath, libraryStatus: library.status, dependencyIds: library.dependencyIds }, saveReopen: "EXACT", negative: { malformedBlend: "REJECTED_WITHOUT_MAIN_MUTATION" }, nextTask: "M16-GAP-00269" };
const reportPath = path.join(root, "tests/golden/M16-GAP-00268/bundle-install-local-exact-report.json");
fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`);
process.stdout.write(`generated-gap-ok task=${task} library=${library.id} status=${library.status} poll=false operator=${desktop.operatorStatus} mainMutation=none desktop=exact saveReopen=exact next=${report.nextTask}\n`);
process.exit(0);
}
if (task === "M16-GAP-00269") {
const fixture = path.join(root, "tests/files/web/generated/M16-GAP-00269-operator-asset.catalog_delete.blend");
const desktopPath = path.join(root, "tests/golden/M16-GAP-00269/catalog-delete-desktop-report.json");
fs.mkdirSync(path.dirname(desktopPath), { recursive: true });
const run = spawnSync(process.env.BLENDER_BIN ?? path.join(root, "build_blender_5.2.0/bin/blender"), ["-b", "--factory-startup", "--python", path.join(root, "tools/web/check-action-catalog-delete-desktop.py"), "--", fixture, desktopPath], { cwd: root, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 });
assert.equal(run.status, 0, `${run.stdout ?? ""}\n${run.stderr ?? ""}`);
const desktop = JSON.parse(fs.readFileSync(desktopPath, "utf8"));
assert.equal(desktop.saveReopen, "EXACT");
assert.equal(desktop.poll, false);
assert.equal(desktop.operatorStatus, "CANCELLED");
assert.equal(desktop.mainMutation, "NONE");
assert.deepEqual(desktop.after, desktop.before);
const engine = await factory({ wasmBinary });
const handle = engine._web_engine_create();
open(engine, handle, fs.readFileSync(fixture));
const before = snapshot(engine, handle);
assert.equal(before.libraryStatus, "AVAILABLE");
assert.ok(Array.isArray(before.libraries));
assert.equal(before.libraries.length, 1);
const library = before.libraries[0];
assert.equal(library.id, `library:${desktop.before.name}`);
assert.equal(library.name, desktop.before.name);
assert.equal(library.sourcePath, "//WebGapCatalogDelete.blend");
assert.equal(library.packed, false);
assert.equal(library.status, "EXTERNAL_REQUIRED");
assert.equal(library.errorCode, "LINKED_LIBRARY_RESOURCE_REQUIRED");
assert.deepEqual(library.dependencyIds, []);
assert.equal(library.readOnly, true);
const saved = output(engine, handle, engine._web_engine_save_blend, true);
const reopened = engine._web_engine_create();
open(engine, reopened, saved);
const after = snapshot(engine, reopened);
assert.deepEqual(after.libraries, before.libraries);
assert.equal(after.libraryStatus, before.libraryStatus);
const malformed = new Uint8Array([0x42, 0x4c, 0x45, 0x4e, 0x44, 0x45, 0x52]);
const pointer = engine._malloc(malformed.byteLength);
let result;
try { engine.HEAPU8.set(malformed, pointer); result = engine._web_engine_open_blend(handle, pointer, malformed.byteLength); } finally { engine._free(pointer); }
assert.notEqual(result, 0);
assert.deepEqual(snapshot(engine, handle).libraries, before.libraries);
engine._web_engine_destroy(handle);
engine._web_engine_destroy(reopened);
const report = { schemaVersion: 1, task, operation: "ASSET_CATALOG_DELETE_LOCAL_EXACT", fixture: { path: path.relative(root, fixture).replaceAll(path.sep, "/"), sha256: desktop.fixtureSha256 }, desktop: { status: "EXACT", report: path.relative(root, desktopPath).replaceAll(path.sep, "/"), poll: desktop.poll, operatorStatus: desktop.operatorStatus, mainMutation: desktop.mainMutation }, wasm: { status: "EXACT", libraryId: library.id, sourcePath: library.sourcePath, libraryStatus: library.status, dependencyIds: library.dependencyIds }, saveReopen: "EXACT", negative: { malformedBlend: "REJECTED_WITHOUT_MAIN_MUTATION" }, nextTask: "M16-GAP-00270" };
const reportPath = path.join(root, "tests/golden/M16-GAP-00269/catalog-delete-local-exact-report.json");
fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`);
process.stdout.write(`generated-gap-ok task=${task} library=${library.id} status=${library.status} poll=false operator=${desktop.operatorStatus} mainMutation=none desktop=exact saveReopen=exact next=${report.nextTask}\n`);
process.exit(0);
}
if (task === "M16-GAP-00270") {
const fixture = path.join(root, "tests/files/web/generated/M16-GAP-00270-operator-asset.catalog_new.blend");
const desktopPath = path.join(root, "tests/golden/M16-GAP-00270/catalog-new-desktop-report.json");
fs.mkdirSync(path.dirname(desktopPath), { recursive: true });
const run = spawnSync(process.env.BLENDER_BIN ?? path.join(root, "build_blender_5.2.0/bin/blender"), ["-b", "--factory-startup", "--python", path.join(root, "tools/web/check-action-catalog-new-desktop.py"), "--", fixture, desktopPath], { cwd: root, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 });
assert.equal(run.status, 0, `${run.stdout ?? ""}\n${run.stderr ?? ""}`);
const desktop = JSON.parse(fs.readFileSync(desktopPath, "utf8"));
assert.equal(desktop.saveReopen, "EXACT");
assert.equal(desktop.poll, false);
assert.equal(desktop.operatorStatus, "CANCELLED");
assert.equal(desktop.mainMutation, "NONE");
assert.deepEqual(desktop.after, desktop.before);
const engine = await factory({ wasmBinary });
const handle = engine._web_engine_create();
open(engine, handle, fs.readFileSync(fixture));
const before = snapshot(engine, handle);
assert.equal(before.libraryStatus, "AVAILABLE");
assert.ok(Array.isArray(before.libraries));
assert.equal(before.libraries.length, 1);
const library = before.libraries[0];
assert.equal(library.id, `library:${desktop.before.name}`);
assert.equal(library.name, desktop.before.name);
assert.equal(library.sourcePath, "//WebGapCatalogNew.blend");
assert.equal(library.packed, false);
assert.equal(library.status, "EXTERNAL_REQUIRED");
assert.equal(library.errorCode, "LINKED_LIBRARY_RESOURCE_REQUIRED");
assert.deepEqual(library.dependencyIds, []);
assert.equal(library.readOnly, true);
const saved = output(engine, handle, engine._web_engine_save_blend, true);
const reopened = engine._web_engine_create();
open(engine, reopened, saved);
const after = snapshot(engine, reopened);
assert.deepEqual(after.libraries, before.libraries);
assert.equal(after.libraryStatus, before.libraryStatus);
const malformed = new Uint8Array([0x42, 0x4c, 0x45, 0x4e, 0x44, 0x45, 0x52]);
const pointer = engine._malloc(malformed.byteLength);
let result;
try { engine.HEAPU8.set(malformed, pointer); result = engine._web_engine_open_blend(handle, pointer, malformed.byteLength); } finally { engine._free(pointer); }
assert.notEqual(result, 0);
assert.deepEqual(snapshot(engine, handle).libraries, before.libraries);
engine._web_engine_destroy(handle);
engine._web_engine_destroy(reopened);
const report = { schemaVersion: 1, task, operation: "ASSET_CATALOG_NEW_LOCAL_EXACT", fixture: { path: path.relative(root, fixture).replaceAll(path.sep, "/"), sha256: desktop.fixtureSha256 }, desktop: { status: "EXACT", report: path.relative(root, desktopPath).replaceAll(path.sep, "/"), poll: desktop.poll, operatorStatus: desktop.operatorStatus, mainMutation: desktop.mainMutation }, wasm: { status: "EXACT", libraryId: library.id, sourcePath: library.sourcePath, libraryStatus: library.status, dependencyIds: library.dependencyIds }, saveReopen: "EXACT", negative: { malformedBlend: "REJECTED_WITHOUT_MAIN_MUTATION" }, nextTask: "M16-GAP-00271" };
const reportPath = path.join(root, "tests/golden/M16-GAP-00270/catalog-new-local-exact-report.json");
fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`);
process.stdout.write(`generated-gap-ok task=${task} library=${library.id} status=${library.status} poll=false operator=${desktop.operatorStatus} mainMutation=none desktop=exact saveReopen=exact next=${report.nextTask}\n`);
process.exit(0);
}
if (task === "M16-GAP-00271") {
const fixture = path.join(root, "tests/files/web/generated/M16-GAP-00271-operator-asset.catalog_redo.blend");
const desktopPath = path.join(root, "tests/golden/M16-GAP-00271/catalog-redo-desktop-report.json");
fs.mkdirSync(path.dirname(desktopPath), { recursive: true });
const run = spawnSync(process.env.BLENDER_BIN ?? path.join(root, "build_blender_5.2.0/bin/blender"), ["-b", "--factory-startup", "--python", path.join(root, "tools/web/check-action-catalog-redo-desktop.py"), "--", fixture, desktopPath], { cwd: root, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 });
assert.equal(run.status, 0, `${run.stdout ?? ""}\n${run.stderr ?? ""}`);
const desktop = JSON.parse(fs.readFileSync(desktopPath, "utf8"));
assert.equal(desktop.saveReopen, "EXACT"); assert.equal(desktop.poll, false); assert.equal(desktop.operatorStatus, "CANCELLED"); assert.equal(desktop.mainMutation, "NONE"); assert.deepEqual(desktop.after, desktop.before);
const engine = await factory({ wasmBinary }); const handle = engine._web_engine_create(); open(engine, handle, fs.readFileSync(fixture)); const before = snapshot(engine, handle);
assert.equal(before.libraryStatus, "AVAILABLE"); assert.equal(before.libraries.length, 1); const library = before.libraries[0];
assert.equal(library.id, `library:${desktop.before.name}`); assert.equal(library.name, desktop.before.name); assert.equal(library.sourcePath, "//WebGapCatalogRedo.blend"); assert.equal(library.packed, false); assert.equal(library.status, "EXTERNAL_REQUIRED"); assert.equal(library.errorCode, "LINKED_LIBRARY_RESOURCE_REQUIRED"); assert.deepEqual(library.dependencyIds, []); assert.equal(library.readOnly, true);
const saved = output(engine, handle, engine._web_engine_save_blend, true); const reopened = engine._web_engine_create(); open(engine, reopened, saved); const after = snapshot(engine, reopened); assert.deepEqual(after.libraries, before.libraries); assert.equal(after.libraryStatus, before.libraryStatus);
const malformed = new Uint8Array([0x42,0x4c,0x45,0x4e,0x44,0x45,0x52]); const pointer = engine._malloc(malformed.byteLength); let result; try { engine.HEAPU8.set(malformed, pointer); result = engine._web_engine_open_blend(handle, pointer, malformed.byteLength); } finally { engine._free(pointer); } assert.notEqual(result, 0); assert.deepEqual(snapshot(engine, handle).libraries, before.libraries); engine._web_engine_destroy(handle); engine._web_engine_destroy(reopened);
const report = { schemaVersion: 1, task, operation: "ASSET_CATALOG_REDO_LOCAL_EXACT", fixture: { path: path.relative(root, fixture).replaceAll(path.sep, "/"), sha256: desktop.fixtureSha256 }, desktop: { status: "EXACT", report: path.relative(root, desktopPath).replaceAll(path.sep, "/"), poll: desktop.poll, operatorStatus: desktop.operatorStatus, mainMutation: desktop.mainMutation }, wasm: { status: "EXACT", libraryId: library.id, sourcePath: library.sourcePath, libraryStatus: library.status, dependencyIds: library.dependencyIds }, saveReopen: "EXACT", negative: { malformedBlend: "REJECTED_WITHOUT_MAIN_MUTATION" }, nextTask: "M16-GAP-00272" };
const reportPath = path.join(root, "tests/golden/M16-GAP-00271/catalog-redo-local-exact-report.json"); fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`); process.stdout.write(`generated-gap-ok task=${task} library=${library.id} status=${library.status} poll=false operator=${desktop.operatorStatus} mainMutation=none desktop=exact saveReopen=exact next=${report.nextTask}\n`); process.exit(0);
}
if (task === "M16-GAP-00272") {
const fixture = path.join(root, "tests/files/web/generated/M16-GAP-00272-operator-asset.catalog_undo.blend");
const desktopPath = path.join(root, "tests/golden/M16-GAP-00272/catalog-undo-desktop-report.json");
fs.mkdirSync(path.dirname(desktopPath), { recursive: true });
const run = spawnSync(process.env.BLENDER_BIN ?? path.join(root, "build_blender_5.2.0/bin/blender"), ["-b", "--factory-startup", "--python", path.join(root, "tools/web/check-action-catalog-undo-desktop.py"), "--", fixture, desktopPath], { cwd: root, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 });
assert.equal(run.status, 0, `${run.stdout ?? ""}\n${run.stderr ?? ""}`);
const desktop = JSON.parse(fs.readFileSync(desktopPath, "utf8"));
assert.equal(desktop.saveReopen, "EXACT"); assert.equal(desktop.poll, false); assert.equal(desktop.operatorStatus, "CANCELLED"); assert.equal(desktop.mainMutation, "NONE"); assert.deepEqual(desktop.after, desktop.before);
const engine = await factory({ wasmBinary }); const handle = engine._web_engine_create(); open(engine, handle, fs.readFileSync(fixture)); const before = snapshot(engine, handle); assert.equal(before.libraryStatus, "AVAILABLE"); assert.equal(before.libraries.length, 1); const library = before.libraries[0];
assert.equal(library.id, `library:${desktop.before.name}`); assert.equal(library.name, desktop.before.name); assert.equal(library.sourcePath, "//WebGapCatalogUndo.blend"); assert.equal(library.packed, false); assert.equal(library.status, "EXTERNAL_REQUIRED"); assert.equal(library.errorCode, "LINKED_LIBRARY_RESOURCE_REQUIRED"); assert.deepEqual(library.dependencyIds, []); assert.equal(library.readOnly, true);
const saved = output(engine, handle, engine._web_engine_save_blend, true); const reopened = engine._web_engine_create(); open(engine, reopened, saved); const after = snapshot(engine, reopened); assert.deepEqual(after.libraries, before.libraries); assert.equal(after.libraryStatus, before.libraryStatus);
const malformed = new Uint8Array([0x42,0x4c,0x45,0x4e,0x44,0x45,0x52]); const pointer = engine._malloc(malformed.byteLength); let result; try { engine.HEAPU8.set(malformed, pointer); result = engine._web_engine_open_blend(handle, pointer, malformed.byteLength); } finally { engine._free(pointer); } assert.notEqual(result, 0); assert.deepEqual(snapshot(engine, handle).libraries, before.libraries); engine._web_engine_destroy(handle); engine._web_engine_destroy(reopened);
const report = { schemaVersion: 1, task, operation: "ASSET_CATALOG_UNDO_LOCAL_EXACT", fixture: { path: path.relative(root, fixture).replaceAll(path.sep, "/"), sha256: desktop.fixtureSha256 }, desktop: { status: "EXACT", report: path.relative(root, desktopPath).replaceAll(path.sep, "/"), poll: desktop.poll, operatorStatus: desktop.operatorStatus, mainMutation: desktop.mainMutation }, wasm: { status: "EXACT", libraryId: library.id, sourcePath: library.sourcePath, libraryStatus: library.status, dependencyIds: library.dependencyIds }, saveReopen: "EXACT", negative: { malformedBlend: "REJECTED_WITHOUT_MAIN_MUTATION" }, nextTask: "M16-GAP-00273" };
const reportPath = path.join(root, "tests/golden/M16-GAP-00272/catalog-undo-local-exact-report.json"); fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`); process.stdout.write(`generated-gap-ok task=${task} library=${library.id} status=${library.status} poll=false operator=${desktop.operatorStatus} mainMutation=none desktop=exact saveReopen=exact next=${report.nextTask}\n`); process.exit(0);
}
if (task === "M16-GAP-00273") {
const fixture = path.join(root, "tests/files/web/generated/M16-GAP-00273-operator-asset.catalog_undo_push.blend");
const desktopPath = path.join(root, "tests/golden/M16-GAP-00273/catalog-undo-push-desktop-report.json"); fs.mkdirSync(path.dirname(desktopPath), { recursive: true });
const run = spawnSync(process.env.BLENDER_BIN ?? path.join(root, "build_blender_5.2.0/bin/blender"), ["-b", "--factory-startup", "--python", path.join(root, "tools/web/check-action-catalog-undo-push-desktop.py"), "--", fixture, desktopPath], { cwd: root, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 }); assert.equal(run.status, 0, `${run.stdout ?? ""}\n${run.stderr ?? ""}`);
const desktop = JSON.parse(fs.readFileSync(desktopPath, "utf8")); assert.equal(desktop.saveReopen, "EXACT"); assert.equal(desktop.poll, false); assert.equal(desktop.operatorStatus, "CANCELLED"); assert.equal(desktop.mainMutation, "NONE"); assert.deepEqual(desktop.after, desktop.before);
const engine = await factory({ wasmBinary }); const handle = engine._web_engine_create(); open(engine, handle, fs.readFileSync(fixture)); const before = snapshot(engine, handle); assert.equal(before.libraryStatus, "AVAILABLE"); assert.equal(before.libraries.length, 1); const library = before.libraries[0]; assert.equal(library.id, `library:${desktop.before.name}`); assert.equal(library.name, desktop.before.name); assert.equal(library.sourcePath, "//WebGapCatalogUndoPush.blend"); assert.equal(library.packed, false); assert.equal(library.status, "EXTERNAL_REQUIRED"); assert.equal(library.errorCode, "LINKED_LIBRARY_RESOURCE_REQUIRED"); assert.deepEqual(library.dependencyIds, []); assert.equal(library.readOnly, true);
const saved = output(engine, handle, engine._web_engine_save_blend, true); const reopened = engine._web_engine_create(); open(engine, reopened, saved); const after = snapshot(engine, reopened); assert.deepEqual(after.libraries, before.libraries); assert.equal(after.libraryStatus, before.libraryStatus); const malformed = new Uint8Array([0x42,0x4c,0x45,0x4e,0x44,0x45,0x52]); const pointer = engine._malloc(malformed.byteLength); let result; try { engine.HEAPU8.set(malformed, pointer); result = engine._web_engine_open_blend(handle, pointer, malformed.byteLength); } finally { engine._free(pointer); } assert.notEqual(result, 0); assert.deepEqual(snapshot(engine, handle).libraries, before.libraries); engine._web_engine_destroy(handle); engine._web_engine_destroy(reopened);
const report = { schemaVersion: 1, task, operation: "ASSET_CATALOG_UNDO_PUSH_LOCAL_EXACT", fixture: { path: path.relative(root, fixture).replaceAll(path.sep, "/"), sha256: desktop.fixtureSha256 }, desktop: { status: "EXACT", report: path.relative(root, desktopPath).replaceAll(path.sep, "/"), poll: desktop.poll, operatorStatus: desktop.operatorStatus, mainMutation: desktop.mainMutation }, wasm: { status: "EXACT", libraryId: library.id, sourcePath: library.sourcePath, libraryStatus: library.status, dependencyIds: library.dependencyIds }, saveReopen: "EXACT", negative: { malformedBlend: "REJECTED_WITHOUT_MAIN_MUTATION" }, nextTask: "M16-GAP-00274" }; const reportPath = path.join(root, "tests/golden/M16-GAP-00273/catalog-undo-push-local-exact-report.json"); fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`); process.stdout.write(`generated-gap-ok task=${task} library=${library.id} status=${library.status} poll=false operator=${desktop.operatorStatus} mainMutation=none desktop=exact saveReopen=exact next=${report.nextTask}\n`); process.exit(0);
}
if (task === "M16-GAP-00274") {
const fixture = path.join(root, "tests/files/web/generated/M16-GAP-00274-operator-asset.catalogs_save.blend");
const desktopPath = path.join(root, "tests/golden/M16-GAP-00274/catalogs-save-desktop-report.json"); fs.mkdirSync(path.dirname(desktopPath), { recursive: true });
const run = spawnSync(process.env.BLENDER_BIN ?? path.join(root, "build_blender_5.2.0/bin/blender"), ["-b", "--factory-startup", "--python", path.join(root, "tools/web/check-action-catalogs-save-desktop.py"), "--", fixture, desktopPath], { cwd: root, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 }); assert.equal(run.status, 0, `${run.stdout ?? ""}\n${run.stderr ?? ""}`);
const desktop = JSON.parse(fs.readFileSync(desktopPath, "utf8")); assert.equal(desktop.saveReopen, "EXACT"); assert.equal(desktop.poll, false); assert.equal(desktop.operatorStatus, "CANCELLED"); assert.equal(desktop.mainMutation, "NONE"); assert.deepEqual(desktop.after, desktop.before);
const engine = await factory({ wasmBinary }); const handle = engine._web_engine_create(); open(engine, handle, fs.readFileSync(fixture)); const before = snapshot(engine, handle); assert.equal(before.libraryStatus, "AVAILABLE"); assert.equal(before.libraries.length, 1); const library = before.libraries[0];
assert.equal(library.id, `library:${desktop.before.name}`); assert.equal(library.name, desktop.before.name); assert.equal(library.sourcePath, "//WebGapCatalogsSave.blend"); assert.equal(library.packed, false); assert.equal(library.status, "EXTERNAL_REQUIRED"); assert.equal(library.errorCode, "LINKED_LIBRARY_RESOURCE_REQUIRED"); assert.deepEqual(library.dependencyIds, []); assert.equal(library.readOnly, true);
const saved = output(engine, handle, engine._web_engine_save_blend, true); const reopened = engine._web_engine_create(); open(engine, reopened, saved); const after = snapshot(engine, reopened); assert.deepEqual(after.libraries, before.libraries); assert.equal(after.libraryStatus, before.libraryStatus); const malformed = new Uint8Array([0x42,0x4c,0x45,0x4e,0x44,0x45,0x52]); const pointer = engine._malloc(malformed.byteLength); let result; try { engine.HEAPU8.set(malformed, pointer); result = engine._web_engine_open_blend(handle, pointer, malformed.byteLength); } finally { engine._free(pointer); } assert.notEqual(result, 0); assert.deepEqual(snapshot(engine, handle).libraries, before.libraries); engine._web_engine_destroy(handle); engine._web_engine_destroy(reopened);
const report = { schemaVersion: 1, task, operation: "ASSET_CATALOGS_SAVE_LOCAL_EXACT", fixture: { path: path.relative(root, fixture).replaceAll(path.sep, "/"), sha256: desktop.fixtureSha256 }, desktop: { status: "EXACT", report: path.relative(root, desktopPath).replaceAll(path.sep, "/"), poll: desktop.poll, operatorStatus: desktop.operatorStatus, mainMutation: desktop.mainMutation }, wasm: { status: "EXACT", libraryId: library.id, sourcePath: library.sourcePath, libraryStatus: library.status, dependencyIds: library.dependencyIds }, saveReopen: "EXACT", negative: { malformedBlend: "REJECTED_WITHOUT_MAIN_MUTATION" }, nextTask: "M16-GAP-00275" }; const reportPath = path.join(root, "tests/golden/M16-GAP-00274/catalogs-save-local-exact-report.json"); fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`); process.stdout.write(`generated-gap-ok task=${task} library=${library.id} status=${library.status} poll=false operator=${desktop.operatorStatus} mainMutation=none desktop=exact saveReopen=exact next=${report.nextTask}\n`); process.exit(0);
}
if (task === "M16-GAP-00275") {
const fixture = path.join(root, "tests/files/web/generated/M16-GAP-00275-operator-asset.clear.blend");
const desktopPath = path.join(root, "tests/golden/M16-GAP-00275/asset-clear-desktop-report.json"); fs.mkdirSync(path.dirname(desktopPath), { recursive: true });
const run = spawnSync(process.env.BLENDER_BIN ?? path.join(root, "build_blender_5.2.0/bin/blender"), ["-b", "--factory-startup", "--python", path.join(root, "tools/web/check-action-asset-clear-desktop.py"), "--", fixture, desktopPath], { cwd: root, encoding: "utf8", maxBuffer: 8 * 1024 * 1024 }); assert.equal(run.status, 0, `${run.stdout ?? ""}\n${run.stderr ?? ""}`);
const desktop = JSON.parse(fs.readFileSync(desktopPath, "utf8")); assert.equal(desktop.saveReopen, "EXACT"); assert.equal(desktop.poll, false); assert.equal(desktop.operatorStatus, "CANCELLED"); assert.equal(desktop.mainMutation, "NONE"); assert.deepEqual(desktop.after, desktop.before);
const engine = await factory({ wasmBinary }); const handle = engine._web_engine_create(); open(engine, handle, fs.readFileSync(fixture)); const before = snapshot(engine, handle); assert.equal(before.libraryStatus, "AVAILABLE"); assert.equal(before.libraries.length, 1); const library = before.libraries[0];
assert.equal(library.id, `library:${desktop.before.name}`); assert.equal(library.name, desktop.before.name); assert.equal(library.sourcePath, "//WebGapAssetClear.blend"); assert.equal(library.packed, false); assert.equal(library.status, "EXTERNAL_REQUIRED"); assert.equal(library.errorCode, "LINKED_LIBRARY_RESOURCE_REQUIRED"); assert.deepEqual(library.dependencyIds, []); assert.equal(library.readOnly, true);
const saved = output(engine, handle, engine._web_engine_save_blend, true); const reopened = engine._web_engine_create(); open(engine, reopened, saved); const after = snapshot(engine, reopened); assert.deepEqual(after.libraries, before.libraries); assert.equal(after.libraryStatus, before.libraryStatus); const malformed = new Uint8Array([0x42, 0x4c, 0x45, 0x4e, 0x44, 0x45, 0x52]); const pointer = engine._malloc(malformed.byteLength); let result; try { engine.HEAPU8.set(malformed, pointer); result = engine._web_engine_open_blend(handle, pointer, malformed.byteLength); } finally { engine._free(pointer); } assert.notEqual(result, 0); assert.deepEqual(snapshot(engine, handle).libraries, before.libraries); engine._web_engine_destroy(handle); engine._web_engine_destroy(reopened);
const report = { schemaVersion: 1, task, operation: "ASSET_CLEAR_LOCAL_EXACT", fixture: { path: path.relative(root, fixture).replaceAll(path.sep, "/"), sha256: desktop.fixtureSha256 }, desktop: { status: "EXACT", report: path.relative(root, desktopPath).replaceAll(path.sep, "/"), poll: desktop.poll, operatorStatus: desktop.operatorStatus, mainMutation: desktop.mainMutation }, wasm: { status: "EXACT", libraryId: library.id, sourcePath: library.sourcePath, libraryStatus: library.status, dependencyIds: library.dependencyIds }, saveReopen: "EXACT", negative: { malformedBlend: "REJECTED_WITHOUT_MAIN_MUTATION" }, nextTask: "M16-GAP-00276" };
const reportPath = path.join(root, "tests/golden/M16-GAP-00275/asset-clear-local-exact-report.json"); fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`); process.stdout.write(`generated-gap-ok task=${task} library=${library.id} status=${library.status} poll=false operator=${desktop.operatorStatus} mainMutation=none desktop=exact saveReopen=exact next=${report.nextTask}\n`); process.exit(0);
}
if (task === "M16-GAP-00205") {
const fixture = path.join(root, "tests/files/web/generated/M16-GAP-00205-operator-anim.separate_slots.blend");
const desktopPath = path.join(root, "tests/golden/M16-GAP-00205/anim-separate-slots-desktop-report.json");