import { describe, it, expect } from "vitest"; import { jsonToToon } from "../../extensions/compress/stages/toon.js"; describe("jsonToToon", () => { it("returns unchanged text for non-JSON input", () => { const text = "this is plain text, not JSON"; expect(jsonToToon(text)).toBe(text); }); it("returns unchanged text for short input (< 200 chars)", () => { const json = JSON.stringify({ a: 1 }); expect(jsonToToon(json)).toBe(json); }); it("returns unchanged text when not starting with { or [", () => { const text = 'x' + JSON.stringify({ key: "value" }).repeat(20); expect(jsonToToon(text)).toBe(text); }); it("compresses a large uniform array of objects", () => { const rows = Array.from({ length: 20 }, (_, i) => ({ id: i, name: `User ${i}`, role: i % 2 === 0 ? "admin" : "user", active: true, })); const json = JSON.stringify(rows, null, 2); const result = jsonToToon(json); // Should compress — TOON is much shorter for uniform arrays expect(result.length).toBeLessThan(json.length * 0.9); }); it("returns unchanged text when TOON is not >= 10% shorter", () => { // A simple scalar object with no repetition compresses poorly const json = JSON.stringify({ deeply: { nested: { unique: "values", more: "stuff" } } }); // Pad to > 200 chars so size check passes const padded = json + " ".repeat(210 - json.length); const result = jsonToToon(padded.trim()); // May or may not compress, but should never be longer expect(result.length).toBeLessThanOrEqual(padded.trim().length + 1); }); it("handles invalid JSON gracefully (returns original)", () => { const text = '{"broken": json content without quotes}' + "x".repeat(200); expect(jsonToToon(text)).toBe(text); }); it("handles large JSON object (> 200 chars) starting with {", () => { const obj: Record = {}; for (let i = 0; i < 30; i++) obj[`key_${i}`] = `value_${i}`; const json = JSON.stringify(obj, null, 2); const result = jsonToToon(json); // Result should be a string (either compressed or original) expect(typeof result).toBe("string"); expect(result.length).toBeGreaterThan(0); }); });