66 lines
2.5 KiB
TypeScript
66 lines
2.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { parseSvgSource } from "../../src/document/source-parser";
|
|
import {
|
|
createSelectedSvgSource,
|
|
createSymbolSpriteSource,
|
|
} from "../../src/export/derived-svg-export";
|
|
|
|
function semantic(source: string) {
|
|
const parsed = parseSvgSource(source, 1);
|
|
if (!parsed.semantic) throw new Error("Fixture did not parse");
|
|
return parsed.semantic;
|
|
}
|
|
|
|
describe("derived SVG exports", () => {
|
|
it("retains selected ancestry and definitions while using a safe projection", () => {
|
|
const document = semantic(`
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
|
<defs><linearGradient id="paint"><stop offset="1"/></linearGradient></defs>
|
|
<g transform="translate(2 3)"><path id="keep" d="M0 0L1 1" fill="url(#paint)"/></g>
|
|
<circle id="remove" r="4"/>
|
|
<script>alert(1)</script>
|
|
</svg>`);
|
|
const selected = document.order.find(
|
|
(key) => document.nodes.get(key)?.id === "keep",
|
|
)!;
|
|
const result = createSelectedSvgSource(document, [selected]);
|
|
|
|
expect(result.source).toContain("translate(2 3)");
|
|
expect(result.source).toContain("linearGradient");
|
|
expect(result.source).toContain('id="keep"');
|
|
expect(result.source).not.toContain('id="remove"');
|
|
expect(result.source).not.toContain("script");
|
|
expect(result.source).not.toContain("data-svg-tools-node");
|
|
});
|
|
|
|
it("exports existing symbols and shared definitions as a sprite", () => {
|
|
const document = semantic(`
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
|
<defs>
|
|
<linearGradient id="paint"><stop offset="1"/></linearGradient>
|
|
<symbol id="mark" viewBox="0 0 4 4"><path d="M0 0L4 4"/></symbol>
|
|
</defs>
|
|
</svg>`);
|
|
const result = createSymbolSpriteSource(document, []);
|
|
|
|
expect(result.source).toContain('<symbol id="mark"');
|
|
expect(result.source).toContain("linearGradient");
|
|
expect(result.source.match(/<symbol/gu)).toHaveLength(1);
|
|
expect(result.source).not.toContain("data-svg-tools-node");
|
|
});
|
|
|
|
it("wraps a selection in a symbol when the source has no symbols", () => {
|
|
const document = semantic(`
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10">
|
|
<path id="arrow" d="M0 5L10 5"/>
|
|
</svg>`);
|
|
const selected = document.order.find(
|
|
(key) => document.nodes.get(key)?.id === "arrow",
|
|
)!;
|
|
const result = createSymbolSpriteSource(document, [selected]);
|
|
|
|
expect(result.source).toContain('id="symbol-arrow"');
|
|
expect(result.source).toContain('id="arrow"');
|
|
});
|
|
});
|