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 = [
'',
'',
'',
'',
"",
];
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 }
);
});
});