feat(3d): integrate ZJB scene with project context
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
/** @jest-environment node */
|
||||
|
||||
import { createHash } from "node:crypto";
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
|
||||
const sceneRoot = join(
|
||||
process.cwd(),
|
||||
"public",
|
||||
"three-dimensional",
|
||||
"zjb",
|
||||
"v29",
|
||||
);
|
||||
|
||||
describe("ZJB three-dimensional runtime assets", () => {
|
||||
it("ships every model referenced by the production manifest", () => {
|
||||
const manifest = JSON.parse(
|
||||
readFileSync(join(sceneRoot, "manifest.json"), "utf8"),
|
||||
) as {
|
||||
packageId: string;
|
||||
renderRevision: number;
|
||||
assets: Array<{ file: string; sha256: string }>;
|
||||
networkModel: { file: string; metadata: string; sha256: string };
|
||||
sourceCatalogFile?: string;
|
||||
bindingsFile?: string;
|
||||
};
|
||||
|
||||
expect(manifest.packageId).toBe("zjb-web-v29");
|
||||
expect(manifest.renderRevision).toBe(29);
|
||||
expect(manifest.assets).toHaveLength(24);
|
||||
manifest.assets.forEach((asset) => {
|
||||
const assetPath = join(sceneRoot, asset.file);
|
||||
expect(existsSync(assetPath)).toBe(true);
|
||||
expect(createHash("sha256").update(readFileSync(assetPath)).digest("hex")).toBe(
|
||||
asset.sha256,
|
||||
);
|
||||
});
|
||||
expect(existsSync(join(sceneRoot, manifest.networkModel.file))).toBe(true);
|
||||
expect(existsSync(join(sceneRoot, manifest.networkModel.metadata))).toBe(true);
|
||||
expect(manifest.sourceCatalogFile).toBeUndefined();
|
||||
expect(manifest.bindingsFile).toBeUndefined();
|
||||
|
||||
const networkModel = readFileSync(join(sceneRoot, manifest.networkModel.file));
|
||||
expect(createHash("sha256").update(networkModel).digest("hex")).toBe(
|
||||
manifest.networkModel.sha256,
|
||||
);
|
||||
});
|
||||
|
||||
it("includes the offline runtime modules and third-party licenses", () => {
|
||||
[
|
||||
"preview.html",
|
||||
"preview.mjs",
|
||||
"appearance.mjs",
|
||||
"asset-inspector.mjs",
|
||||
"camera-navigation.mjs",
|
||||
"network-style.mjs",
|
||||
"integration.mjs",
|
||||
"render-effects.mjs",
|
||||
"vendor/meshopt_decoder.module.js",
|
||||
"vendor/meshoptimizer-LICENSE.md",
|
||||
"vendor/three/LICENSE",
|
||||
"vendor/three/three.module.js",
|
||||
"vendor/three/addons/loaders/GLTFLoader.js",
|
||||
].forEach((relativePath) => {
|
||||
expect(existsSync(join(sceneRoot, relativePath))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps the embedded viewer on the versioned same-origin host protocol", () => {
|
||||
const preview = readFileSync(join(sceneRoot, "preview.mjs"), "utf8");
|
||||
const html = readFileSync(join(sceneRoot, "preview.html"), "utf8");
|
||||
const inspector = readFileSync(
|
||||
join(sceneRoot, "asset-inspector.mjs"),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
expect(preview).toContain("tjwater:zjb-scene");
|
||||
expect(preview).toContain("HOST_VERSION=2");
|
||||
expect(preview).toContain("event.origin===window.location.origin");
|
||||
expect(preview).toContain("event.source===window.parent");
|
||||
expect(preview).toContain("postHost('ready'");
|
||||
expect(preview).toContain("data.type==='results'");
|
||||
expect(preview).toContain("data.type==='clear-results'");
|
||||
expect(preview).toContain("data.type!=='command'");
|
||||
expect(preview).toContain("postHost('selection-changed'");
|
||||
expect(preview).not.toContain("window.zjbNetwork");
|
||||
expect(preview).not.toContain("resultsFile");
|
||||
expect(html).not.toContain("绑定运行结果");
|
||||
expect(html).not.toContain("resultsFile");
|
||||
expect(inspector).not.toContain("document.getElementById");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user