You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
1.9 KiB
100 lines
1.9 KiB
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
array,
|
|
lazy,
|
|
number,
|
|
object,
|
|
optional,
|
|
pipe,
|
|
serializeSchema,
|
|
string,
|
|
walkSchema
|
|
} from '../core';
|
|
import type { Schema } from '../core';
|
|
|
|
describe('serializeSchema()', () => {
|
|
it('serializes object schemas into a JSON-friendly tree', () => {
|
|
const schema = object({ a: string() });
|
|
|
|
expect(serializeSchema(schema)).toEqual({
|
|
kind: 'object',
|
|
wrappers: [],
|
|
effects: [],
|
|
async: false,
|
|
meta: {},
|
|
shape: {
|
|
kind: 'object',
|
|
unknownKeys: 'strip',
|
|
fields: {
|
|
a: {
|
|
kind: 'string',
|
|
wrappers: [],
|
|
effects: [],
|
|
async: false,
|
|
meta: {}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
it('truncates recursive schemas without overflowing', () => {
|
|
type TreeNode = {
|
|
value: string;
|
|
children?: TreeNode[];
|
|
};
|
|
|
|
const TreeSchema: Schema<TreeNode, TreeNode> = lazy(() =>
|
|
object({
|
|
value: string(),
|
|
children: optional(array(TreeSchema))
|
|
})
|
|
);
|
|
|
|
const serialized = serializeSchema(TreeSchema, 1);
|
|
const children =
|
|
serialized.shape?.kind === 'object' ? serialized.shape.fields.children : undefined;
|
|
|
|
expect(children?.shape).toEqual({
|
|
kind: 'truncated',
|
|
inner: 'optional'
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('countLeafFields()', () => {
|
|
it('counts nested object leaves and treats arrays as one slot', async () => {
|
|
const { countLeafFields } = await import('../core');
|
|
|
|
expect(
|
|
countLeafFields(
|
|
object({
|
|
a: string(),
|
|
b: number(),
|
|
nested: object({
|
|
c: string()
|
|
})
|
|
})
|
|
)
|
|
).toBe(3);
|
|
|
|
expect(countLeafFields(array(string()))).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('walkSchema()', () => {
|
|
it('visits the schema tree in pre-order for object fields', () => {
|
|
const visited: string[] = [];
|
|
const schema = object({
|
|
a: string(),
|
|
b: pipe(number())
|
|
});
|
|
|
|
walkSchema(schema, (_node, path) => {
|
|
visited.push(path.length === 0 ? '(root)' : path.join('.'));
|
|
});
|
|
|
|
expect(visited).toEqual(['(root)', 'a', 'b']);
|
|
});
|
|
});
|