72 lines
3.1 KiB
JavaScript
72 lines
3.1 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { pathToFileURL } from "node:url";
|
|
import test from "node:test";
|
|
import ts from "typescript";
|
|
|
|
const repoRoot = path.resolve(import.meta.dirname, "../../..");
|
|
const temporary = fs.mkdtempSync(path.join(os.tmpdir(), "texture-paint-asset-unit-"));
|
|
|
|
function transpile(sourceName, outputName, replacements = []) {
|
|
const sourcePath = path.join(repoRoot, "web/protocol", sourceName);
|
|
const transpiled = ts.transpileModule(fs.readFileSync(sourcePath, "utf8"), {
|
|
compilerOptions: { module: ts.ModuleKind.ES2022, target: ts.ScriptTarget.ES2022 },
|
|
fileName: sourcePath,
|
|
reportDiagnostics: true,
|
|
});
|
|
assert.deepEqual(transpiled.diagnostics, []);
|
|
const output = replacements.reduce((source, [from, to]) => source.replace(from, to), transpiled.outputText);
|
|
fs.writeFileSync(path.join(temporary, outputName), output);
|
|
}
|
|
|
|
transpile("paint.ts", "paint.mjs");
|
|
transpile("texture-paint-asset.ts", "texture-paint-asset.mjs", [['from "./paint"', 'from "./paint.mjs"']]);
|
|
const protocol = await import(pathToFileURL(path.join(temporary, "texture-paint-asset.mjs")));
|
|
const hash = "1".repeat(64);
|
|
const target = {
|
|
schemaVersion: 1,
|
|
projectId: "texture-project",
|
|
imageId: "image:Paint",
|
|
textureAssetId: "image:Paint:tile:1001",
|
|
kind: "PACKED",
|
|
tile: 1001,
|
|
revision: 4,
|
|
width: 2,
|
|
height: 2,
|
|
mimeType: "image/png",
|
|
colorSpace: "SRGB",
|
|
sourcePath: "textures/paint.png",
|
|
baseAssetSha256: hash,
|
|
};
|
|
const patch = {
|
|
schemaVersion: 1,
|
|
textureAssetId: target.textureAssetId,
|
|
tile: 1001,
|
|
revision: 4,
|
|
width: 2,
|
|
height: 2,
|
|
format: "RGBA8",
|
|
colorSpace: "SRGB",
|
|
baseSha256: "2".repeat(64),
|
|
resultSha256: "3".repeat(64),
|
|
byteOffset: 0,
|
|
bytes: new Uint8Array([1, 2, 3, 255]),
|
|
};
|
|
|
|
test("M9-11 binds a dirty range to one packed or UDIM tile identity", () => {
|
|
const parsed = protocol.validateTexturePaintTileCommit({ schemaVersion: 1, target, patch });
|
|
assert.equal(parsed.target.kind, "PACKED");
|
|
assert.equal(parsed.patch.textureAssetId, target.textureAssetId);
|
|
assert.equal(protocol.texturePaintTileBindingKey({ schemaVersion: 1, projectId: target.projectId, textureAssetId: target.textureAssetId, tile: 1001 }), "texture-paint:v1:texture-project:image%3APaint%3Atile%3A1001:1001");
|
|
});
|
|
|
|
test("M9-11 rejects target, tile, revision and path drift before storage", () => {
|
|
assert.throws(() => protocol.validateTexturePaintTileCommit({ schemaVersion: 1, target, patch: { ...patch, tile: 1002 } }), /PAINT_SCHEMA_INVALID/);
|
|
assert.throws(() => protocol.validateTexturePaintTileCommit({ schemaVersion: 1, target, patch: { ...patch, revision: 5 } }), /PAINT_SCHEMA_INVALID/);
|
|
assert.throws(() => protocol.validateTexturePaintTileCommit({ schemaVersion: 1, target: { ...target, sourcePath: "../escape.png" }, patch }), /PAINT_SCHEMA_INVALID/);
|
|
assert.throws(() => protocol.validateTexturePaintTileCommit({ schemaVersion: 1, target: { ...target, baseAssetSha256: "bad" }, patch }), /PAINT_SCHEMA_INVALID/);
|
|
assert.throws(() => protocol.validateTexturePaintTileCommit({ schemaVersion: 1, target, patch, extra: true }), /PAINT_SCHEMA_INVALID/);
|
|
});
|