Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
import { describe, expect, it } from "@suaveplan/testing/runner";
import { compressSvg } from "../src/core/compress-svg/compress-svg.js";
import { parseSvg } from "../src/parser/svg/svg.js";
import {
PRESET_AGGRESSIVE,
PRESET_DEFAULT,
PRESET_SAFE,
} from "../src/presets/index.js";
const REAL_SVG_ICON = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- This is an SVG icon -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24" width="24" height="24" fill="black" opacity="1">
<metadata>
<dc:title xmlns:dc="http://purl.org/dc/elements/1.1/">Home Icon</dc:title>
</metadata>
<!-- house shape -->
<g id="layer1">
<g>
<path d="M 10.000000001 20.0000000009 L 14.000000001 20.0000000009 L 14.000000001 15.0000000009 L 10.000000001 15.0000000009 Z" fill="black" opacity="1"/>
</g>
</g>
<path d="M 12 3.0000000009 L 2.0000000001 12 L 4.0000000001 12 L 4.0000000001 21 L 10.000000001 21 L 10.000000001 15 L 14 15 L 14 21 L 20 21 L 20 12 L 22 12 Z" fill-opacity="1" stroke-opacity="1"/>
</svg>`;
const MINIMAL_SVG =
'<svg xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100"/></svg>';
describe("integration: PRESET_DEFAULT", () => {
it("compresses real SVG icon and reduces size", { timeout: 5000 }, () => {
const result = compressSvg(REAL_SVG_ICON, { plugins: PRESET_DEFAULT });
expect(result.ratio).toBeLessThanOrEqual(1);
expect(result.data).not.toContain("<!--");
expect(result.data).not.toContain("DOCTYPE");
expect(result.data).not.toContain("<metadata>");
});
it("removes XML declaration", { timeout: 5000 }, () => {
const result = compressSvg(REAL_SVG_ICON, { plugins: PRESET_DEFAULT });
expect(result.data).not.toContain("<?xml");
});
it("output is parseable after compression", { timeout: 5000 }, () => {
const result = compressSvg(REAL_SVG_ICON, { plugins: PRESET_DEFAULT });
expect(() => parseSvg(result.data)).not.toThrow();
});
it("reduces float precision in path data", { timeout: 5000 }, () => {
const result = compressSvg(REAL_SVG_ICON, {
plugins: PRESET_DEFAULT,
floatPrecision: 1,
});
expect(result.data).not.toMatch(/\d\.\d{4,}/);
});
it("collapses single-child groups", { timeout: 5000 }, () => {
const svg = '<svg><g><rect width="10" height="10"/></g></svg>';
const result = compressSvg(svg, { plugins: PRESET_DEFAULT });
expect(result.data).not.toContain("<g>");
expect(result.data).toContain("<rect");
});
it("reports passCount >= 1", { timeout: 5000 }, () => {
const result = compressSvg(REAL_SVG_ICON, { plugins: PRESET_DEFAULT });
expect(result.passCount).toBeGreaterThanOrEqual(1);
});
});
describe("integration: PRESET_SAFE", () => {
it("compresses without converting transforms", { timeout: 5000 }, () => {
const svg =
'<svg><rect transform="translate(1.123456789 2.987654321)"/></svg>';
const defaultResult = compressSvg(svg, { plugins: PRESET_DEFAULT });
const safeResult = compressSvg(svg, { plugins: PRESET_SAFE });
// PRESET_SAFE does not include convertTransforms
expect(safeResult.data).toContain("1.123456789");
// PRESET_DEFAULT does not include convertTransforms either, so both same
expect(defaultResult.data).toContain("1.123456789");
});
it("still removes comments", { timeout: 5000 }, () => {
const svg = "<svg><!-- note --><rect/></svg>";
const result = compressSvg(svg, { plugins: PRESET_SAFE });
expect(result.data).not.toContain("<!--");
});
});
describe("integration: PRESET_AGGRESSIVE", () => {
it("mangles ids", { timeout: 5000 }, () => {
const svg = '<svg><rect id="veryLongDescriptiveName"/></svg>';
const result = compressSvg(svg, { plugins: PRESET_AGGRESSIVE });
expect(result.data).not.toContain("veryLongDescriptiveName");
expect(result.data).toContain("id=");
});
it("converts transforms", { timeout: 5000 }, () => {
const svg =
'<svg><rect transform="translate(1.123456789 2.987654321)"/></svg>';
const result = compressSvg(svg, {
plugins: PRESET_AGGRESSIVE,
transformPrecision: 2,
});
expect(result.data).toContain("translate(1.12 2.99)");
});
it("has smaller output than PRESET_SAFE for icon", {
timeout: 5000,
}, () => {
const safe = compressSvg(REAL_SVG_ICON, { plugins: PRESET_SAFE });
const aggressive = compressSvg(REAL_SVG_ICON, {
plugins: PRESET_AGGRESSIVE,
});
expect(aggressive.compressedSize).toBeLessThanOrEqual(
safe.compressedSize
);
});
});
describe("integration: minimal SVG", () => {
it("handles minimal SVG without error", { timeout: 5000 }, () => {
const result = compressSvg(MINIMAL_SVG);
expect(result.data).toBeTruthy();
expect(result.originalSize).toBeGreaterThan(0);
});
it("passCount is 1 when multipass=false", { timeout: 5000 }, () => {
const result = compressSvg(MINIMAL_SVG, { multipass: false });
expect(result.passCount).toBe(1);
});
});