130 lines
4.4 KiB
TypeScript
130 lines
4.4 KiB
TypeScript
import { describe, expect, it } from "@suaveplan/testing/runner";
|
|
import { findExtraFields } from "./find-extra-fields.js";
|
|
|
|
describe("findExtraFields", () => {
|
|
it("returns empty for null schema", () => {
|
|
expect(findExtraFields(null, { a: 1 })).toEqual([]);
|
|
});
|
|
|
|
it("returns empty for null data", () => {
|
|
expect(findExtraFields({ a: 1 }, null)).toEqual([]);
|
|
});
|
|
|
|
it("returns empty for undefined data", () => {
|
|
expect(findExtraFields({ a: 1 }, undefined)).toEqual([]);
|
|
});
|
|
|
|
it("handles optional wrapper with undefined data", () => {
|
|
const schema = { _bp: { schema: 255 } };
|
|
expect(
|
|
findExtraFields(
|
|
schema as unknown as import("@suaveplan/types").BitPackerSchema,
|
|
undefined
|
|
)
|
|
).toEqual([]);
|
|
});
|
|
|
|
it("unwraps optional schema", () => {
|
|
const schema = { _bp: { schema: { a: 255 } } };
|
|
const data = { a: 1, b: 2 };
|
|
const extras = findExtraFields(
|
|
schema as unknown as import("@suaveplan/types").BitPackerSchema,
|
|
data
|
|
);
|
|
expect(extras.length).toBe(1);
|
|
expect(extras[0]).toMatchObject({ path: "b", value: 2 });
|
|
});
|
|
|
|
it("returns empty for primitive schemas", () => {
|
|
expect(findExtraFields(true, false)).toEqual([]);
|
|
expect(findExtraFields(255, 100)).toEqual([]);
|
|
expect(findExtraFields("-8", "hello")).toEqual([]);
|
|
});
|
|
|
|
it("finds extra elements in arrays", () => {
|
|
const schema = [255, 255];
|
|
const data = [1, 2, 3, 4];
|
|
const extras = findExtraFields(schema, data);
|
|
expect(extras.length).toBe(2);
|
|
expect(extras[0]).toMatchObject({ path: "[2]", value: 3 });
|
|
expect(extras[1]).toMatchObject({ path: "[3]", value: 4 });
|
|
});
|
|
|
|
it("recursively checks array elements", () => {
|
|
const schema = [{ a: 255 }];
|
|
const data = [{ a: 1, b: 2 }];
|
|
const extras = findExtraFields(schema, data);
|
|
expect(extras.length).toBe(1);
|
|
expect(extras[0]).toMatchObject({ path: "[0].b", value: 2 });
|
|
});
|
|
|
|
it("finds extra fields in objects", () => {
|
|
const schema = { a: 255 };
|
|
const data = { a: 1, b: 2 };
|
|
const extras = findExtraFields(schema, data);
|
|
expect(extras.length).toBe(1);
|
|
expect(extras[0]).toMatchObject({ path: "b", value: 2 });
|
|
});
|
|
|
|
it("recursively checks nested objects", () => {
|
|
const schema = { outer: { a: 255 } };
|
|
const data = { outer: { a: 1, b: 2 } };
|
|
const extras = findExtraFields(schema, data);
|
|
expect(extras.length).toBe(1);
|
|
expect(extras[0]).toMatchObject({ path: "outer.b", value: 2 });
|
|
});
|
|
|
|
it("returns empty when no extra fields", () => {
|
|
const schema = { a: 255, b: "-8" };
|
|
const data = { a: 1, b: "hello" };
|
|
expect(findExtraFields(schema, data)).toEqual([]);
|
|
});
|
|
|
|
it("handles path prefix", () => {
|
|
const schema = { a: 255 };
|
|
const data = { a: 1, b: 2 };
|
|
const extras = findExtraFields(schema, data, "root");
|
|
expect(extras[0].path).toBe("root.b");
|
|
});
|
|
|
|
it("handles array path prefix", () => {
|
|
const schema = [255];
|
|
const data = [1, 2];
|
|
const extras = findExtraFields(schema, data, "items");
|
|
expect(extras[0].path).toBe("items[1]");
|
|
});
|
|
|
|
it("skips undefined schema properties", () => {
|
|
const schema = { a: 255 };
|
|
const data = { a: 1 };
|
|
expect(findExtraFields(schema, data)).toEqual([]);
|
|
});
|
|
|
|
it("returns empty for array schema with non-array data", () => {
|
|
expect(findExtraFields([255], "not array")).toEqual([]);
|
|
});
|
|
|
|
it("returns empty for object schema with non-object data", () => {
|
|
expect(findExtraFields({ a: 255 }, "not object")).toEqual([]);
|
|
});
|
|
|
|
it("skips inherited properties in data", () => {
|
|
const schema = { a: 255 };
|
|
const data = Object.create({ inherited: 1 });
|
|
data.a = 1;
|
|
expect(findExtraFields(schema, data)).toEqual([]);
|
|
});
|
|
|
|
it("skips undefined schema property values", () => {
|
|
const schema: Record<string, unknown> = { a: 255 };
|
|
schema.b = undefined;
|
|
const data = { a: 1, b: 2 };
|
|
const extras = findExtraFields(
|
|
schema as import("@suaveplan/types").BitPackerSchema,
|
|
data
|
|
);
|
|
// undefined schema properties are skipped, not treated as extra fields
|
|
expect(extras).toEqual([]);
|
|
});
|
|
});
|