Initial Commit
This commit is contained in:
140
packages/devtools/docs/compress-svg/tests/property.test.ts
Normal file
140
packages/devtools/docs/compress-svg/tests/property.test.ts
Normal file
@@ -0,0 +1,140 @@
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import * as fc from "fast-check";
|
||||
import { compressSvg } from "../src/core/compress-svg/compress-svg.js";
|
||||
import { parseSvg, serializeSvg } from "../src/parser/svg/svg.js";
|
||||
import { PRESET_DEFAULT } from "../src/presets/index.js";
|
||||
|
||||
const SIMPLE_SVGS = [
|
||||
'<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40"/></svg>',
|
||||
'<svg><rect width="100" height="100"/></svg>',
|
||||
'<svg><g><path d="M 10 20 L 30 40"/></g></svg>',
|
||||
'<svg><text x="10" y="20">hello</text></svg>',
|
||||
"<svg><g><g><rect/></g></g></svg>",
|
||||
];
|
||||
|
||||
describe("property-based: compression idempotency", () => {
|
||||
it("compress(compress(svg)) === compress(svg) for all sample SVGs", {
|
||||
timeout: 30000,
|
||||
}, () => {
|
||||
fc.assert(
|
||||
fc.property(fc.constantFrom(...SIMPLE_SVGS), (svg) => {
|
||||
const first = compressSvg(svg, { plugins: PRESET_DEFAULT });
|
||||
const second = compressSvg(first.data, {
|
||||
plugins: PRESET_DEFAULT,
|
||||
});
|
||||
expect(second.data).toBe(first.data);
|
||||
return true;
|
||||
}),
|
||||
{ numRuns: 10 }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("property-based: parse ↔ serialize round-trip", () => {
|
||||
it("serializeSvg(parseSvg(svg)) is re-parseable for sample SVGs", {
|
||||
timeout: 30000,
|
||||
}, () => {
|
||||
fc.assert(
|
||||
fc.property(fc.constantFrom(...SIMPLE_SVGS), (svg) => {
|
||||
const node = parseSvg(svg);
|
||||
const serialized = serializeSvg(node);
|
||||
const reparsed = parseSvg(serialized);
|
||||
expect(reparsed.type).toBe("element");
|
||||
return true;
|
||||
}),
|
||||
{ numRuns: 10 }
|
||||
);
|
||||
});
|
||||
|
||||
it("parse → serialize preserves element names", { timeout: 30000 }, () => {
|
||||
fc.assert(
|
||||
fc.property(fc.constantFrom(...SIMPLE_SVGS), (svg) => {
|
||||
const node = parseSvg(svg);
|
||||
const serialized = serializeSvg(node);
|
||||
const reparsed = parseSvg(serialized);
|
||||
expect(reparsed.name).toBe(node.name);
|
||||
return true;
|
||||
}),
|
||||
{ numRuns: 10 }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("property-based: ratio invariants", () => {
|
||||
it("ratio is always > 0 for valid SVG", { timeout: 30000 }, () => {
|
||||
fc.assert(
|
||||
fc.property(fc.constantFrom(...SIMPLE_SVGS), (svg) => {
|
||||
const result = compressSvg(svg);
|
||||
expect(result.ratio).toBeGreaterThan(0);
|
||||
return true;
|
||||
}),
|
||||
{ numRuns: 10 }
|
||||
);
|
||||
});
|
||||
|
||||
it("originalSize matches byte length of input", { timeout: 30000 }, () => {
|
||||
fc.assert(
|
||||
fc.property(fc.constantFrom(...SIMPLE_SVGS), (svg) => {
|
||||
const result = compressSvg(svg);
|
||||
const expected = new TextEncoder().encode(svg).byteLength;
|
||||
expect(result.originalSize).toBe(expected);
|
||||
return true;
|
||||
}),
|
||||
{ numRuns: 10 }
|
||||
);
|
||||
});
|
||||
|
||||
it("compressedSize matches byte length of output", {
|
||||
timeout: 30000,
|
||||
}, () => {
|
||||
fc.assert(
|
||||
fc.property(fc.constantFrom(...SIMPLE_SVGS), (svg) => {
|
||||
const result = compressSvg(svg);
|
||||
const expected = new TextEncoder().encode(
|
||||
result.data
|
||||
).byteLength;
|
||||
expect(result.compressedSize).toBe(expected);
|
||||
return true;
|
||||
}),
|
||||
{ numRuns: 10 }
|
||||
);
|
||||
});
|
||||
|
||||
it("ratio equals compressedSize / originalSize", { timeout: 30000 }, () => {
|
||||
fc.assert(
|
||||
fc.property(fc.constantFrom(...SIMPLE_SVGS), (svg) => {
|
||||
const result = compressSvg(svg);
|
||||
expect(result.ratio).toBeCloseTo(
|
||||
result.compressedSize / result.originalSize,
|
||||
5
|
||||
);
|
||||
return true;
|
||||
}),
|
||||
{ numRuns: 10 }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("property-based: passCount invariants", () => {
|
||||
it("passCount >= 1 for all valid SVGs", { timeout: 30000 }, () => {
|
||||
fc.assert(
|
||||
fc.property(fc.constantFrom(...SIMPLE_SVGS), (svg) => {
|
||||
const result = compressSvg(svg);
|
||||
expect(result.passCount).toBeGreaterThanOrEqual(1);
|
||||
return true;
|
||||
}),
|
||||
{ numRuns: 10 }
|
||||
);
|
||||
});
|
||||
|
||||
it("passCount === 1 when multipass: false", { timeout: 30000 }, () => {
|
||||
fc.assert(
|
||||
fc.property(fc.constantFrom(...SIMPLE_SVGS), (svg) => {
|
||||
const result = compressSvg(svg, { multipass: false });
|
||||
expect(result.passCount).toBe(1);
|
||||
return true;
|
||||
}),
|
||||
{ numRuns: 10 }
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user