67 lines
1.9 KiB
TypeScript
67 lines
1.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { inferJsonShape } from "../src/domain/jsonShape.js";
|
|
|
|
describe("inferJsonShape", () => {
|
|
it("retains paths and types without retaining JSON values", () => {
|
|
const shape = inferJsonShape(
|
|
JSON.stringify({
|
|
token: "super-secret",
|
|
users: [
|
|
{ id: 1, active: true },
|
|
{ id: "second-secret", active: false },
|
|
],
|
|
optional: null,
|
|
}),
|
|
{ maximumBytes: 4_096, maximumNodes: 100, maximumDepth: 10 },
|
|
);
|
|
|
|
expect(shape).toMatchObject({
|
|
root_type: "object",
|
|
truncated: false,
|
|
properties: expect.arrayContaining([
|
|
{ path: "/token", types: ["string"], observations: 1 },
|
|
{
|
|
path: "/users/*/id",
|
|
types: ["number", "string"],
|
|
observations: 2,
|
|
},
|
|
{
|
|
path: "/users/*/active",
|
|
types: ["boolean"],
|
|
observations: 2,
|
|
},
|
|
]),
|
|
});
|
|
expect(JSON.stringify(shape)).not.toContain("super-secret");
|
|
expect(JSON.stringify(shape)).not.toContain("second-secret");
|
|
});
|
|
|
|
it("rejects malformed and oversized JSON without returning a prefix", () => {
|
|
const limits = {
|
|
maximumBytes: 8,
|
|
maximumNodes: 100,
|
|
maximumDepth: 10,
|
|
};
|
|
expect(inferJsonShape("not-json", limits)).toBeNull();
|
|
expect(inferJsonShape('{"secret":"value"}', limits)).toBeNull();
|
|
});
|
|
|
|
it("reports node and depth truncation deterministically", () => {
|
|
expect(
|
|
inferJsonShape('{"a":{"b":{"c":1}}}', {
|
|
maximumBytes: 1_024,
|
|
maximumNodes: 100,
|
|
maximumDepth: 1,
|
|
}),
|
|
).toMatchObject({ truncated: true, max_depth_observed: 1 });
|
|
expect(
|
|
inferJsonShape("[1,2,3,4]", {
|
|
maximumBytes: 1_024,
|
|
maximumNodes: 2,
|
|
maximumDepth: 10,
|
|
}),
|
|
).toMatchObject({ truncated: true, node_count: 2 });
|
|
});
|
|
});
|