import { describe, expect, it } from "vitest";
import { parseSvgSource } from "../../src/document/source-parser";
import { applyToPoint } from "../../src/domain/affine";
import { resolveTransformChain } from "../../src/domain/transform-chain";
function semantic(source: string) {
const result = parseSvgSource(source, 1);
expect(result.semantic).not.toBeNull();
return result.semantic!;
}
describe("ancestor transform chains", () => {
it("composes root, ancestor and local transforms in SVG order", () => {
const document = semantic(
'',
);
const child = [...document.nodes.values()].find(
(node) => node.id === "child",
)!;
const chain = resolveTransformChain(document, child.key);
expect(chain.entries).toHaveLength(3);
expect(applyToPoint(chain.matrix, { x: 1, y: 1 })).toMatchObject({
x: -1,
y: 5,
});
const restored = applyToPoint(
chain.inverse!,
applyToPoint(chain.matrix, { x: 7, y: -4 }),
);
expect(restored.x).toBeCloseTo(7);
expect(restored.y).toBeCloseTo(-4);
});
it("refuses deterministic coordinate editing through singular or CSS transforms", () => {
const document = semantic(
'',
);
const path = [...document.nodes.values()].find((node) => node.id === "p")!;
const chain = resolveTransformChain(document, path.key);
expect(chain.inverse).toBeNull();
expect(chain.diagnostics).toContainEqual(
expect.stringContaining("CSS transforms"),
);
});
});