@@ -0,0 +1,58 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { strToU8, zipSync } from "fflate";
|
||||
import { analyzePackage } from "../../src/package/analyze";
|
||||
import { compareSemanticEntry } from "../../src/package/content-compare";
|
||||
import { verifyPackageContents } from "../../src/package/content-compare";
|
||||
|
||||
const bytes = (value: string) => new TextEncoder().encode(value);
|
||||
|
||||
describe("bounded semantic package comparison", () => {
|
||||
it("hashes verified decompressed bytes instead of ZIP representation", async () => {
|
||||
const contents = { "same.txt": strToU8("same decompressed value") };
|
||||
const left = await analyzePackage(
|
||||
new File([zipSync(contents, { level: 0 })], "left.zip"),
|
||||
);
|
||||
const right = await analyzePackage(
|
||||
new File([zipSync(contents, { level: 9 })], "right.zip"),
|
||||
);
|
||||
const evidence = await verifyPackageContents(left, right);
|
||||
expect(evidence["same.txt"]?.leftSha256).toMatch(/^[0-9a-f]{64}$/u);
|
||||
expect(evidence["same.txt"]?.leftSha256).toBe(
|
||||
evidence["same.txt"]?.rightSha256,
|
||||
);
|
||||
});
|
||||
|
||||
it("recognizes equivalent JSON serialization and reports value paths", () => {
|
||||
expect(
|
||||
compareSemanticEntry(
|
||||
"manifest.json",
|
||||
bytes('{"name":"demo","items":[1,2]}'),
|
||||
bytes('{\n "items": [1, 2], "name": "demo"\n}'),
|
||||
),
|
||||
).toMatchObject({ kind: "json", equivalent: true });
|
||||
expect(
|
||||
compareSemanticEntry(
|
||||
"manifest.json",
|
||||
bytes('{"name":"before"}'),
|
||||
bytes('{"name":"after"}'),
|
||||
)?.differences,
|
||||
).toContain("$.name: value changed");
|
||||
});
|
||||
|
||||
it("normalizes safe XML attributes but rejects active declarations", () => {
|
||||
expect(
|
||||
compareSemanticEntry(
|
||||
"content.xml",
|
||||
bytes('<root a="1" b="2"><item>value</item></root>'),
|
||||
bytes('<root b="2" a="1">\n<item>value</item>\n</root>'),
|
||||
),
|
||||
).toMatchObject({ kind: "xml", equivalent: true });
|
||||
expect(
|
||||
compareSemanticEntry(
|
||||
"content.xml",
|
||||
bytes("<!DOCTYPE root><root/>"),
|
||||
bytes("<root/>"),
|
||||
)?.summary,
|
||||
).toMatch(/could not/u);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user