|
|
|
@ -1,5 +1,6 @@
|
|
|
|
import { describe, expect, expectTypeOf, it, vi } from 'vitest';
|
|
|
|
import { describe, expect, expectTypeOf, it, vi } from 'vitest';
|
|
|
|
import { array, discriminated, object, union } from '../core/combinators';
|
|
|
|
import { array, discriminated, object, union } from '../core/combinators';
|
|
|
|
|
|
|
|
import { optional } from '../core/modifiers';
|
|
|
|
import { pipe, refine } from '../core/pipe';
|
|
|
|
import { pipe, refine } from '../core/pipe';
|
|
|
|
import { literal, number, string } from '../core/primitives';
|
|
|
|
import { literal, number, string } from '../core/primitives';
|
|
|
|
import { createSchema } from '../core/schema';
|
|
|
|
import { createSchema } from '../core/schema';
|
|
|
|
@ -297,6 +298,19 @@ describe('object()', () => {
|
|
|
|
|
|
|
|
|
|
|
|
expect(() => schema.decodeSync({ a: 'x', b: 1 })).toThrow(SiumAsyncSchemaError);
|
|
|
|
expect(() => schema.decodeSync({ a: 'x', b: 1 })).toThrow(SiumAsyncSchemaError);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('short-circuits async optional fields in sync object paths', () => {
|
|
|
|
|
|
|
|
const asyncField = createSchema({
|
|
|
|
|
|
|
|
kind: 'string',
|
|
|
|
|
|
|
|
async: true,
|
|
|
|
|
|
|
|
decodeImpl: async (input: string) => input,
|
|
|
|
|
|
|
|
encode: (value: string) => value
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
const schema = object({ a: optional(asyncField), b: number() });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
expect(schema.decodeSync({ a: undefined, b: 1 })).toEqual({ a: undefined, b: 1 });
|
|
|
|
|
|
|
|
expect(() => schema.decodeSync({ a: 'x', b: 1 })).toThrow(SiumAsyncSchemaError);
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
describe('array()', () => {
|
|
|
|
describe('array()', () => {
|
|
|
|
@ -429,6 +443,19 @@ describe('array()', () => {
|
|
|
|
|
|
|
|
|
|
|
|
expect(() => schema.decodeSync(['a'])).toThrow(SiumAsyncSchemaError);
|
|
|
|
expect(() => schema.decodeSync(['a'])).toThrow(SiumAsyncSchemaError);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('short-circuits sync array paths that do not need async item work', () => {
|
|
|
|
|
|
|
|
const asyncItem = createSchema({
|
|
|
|
|
|
|
|
kind: 'string',
|
|
|
|
|
|
|
|
async: true,
|
|
|
|
|
|
|
|
decodeImpl: async (input: string) => input,
|
|
|
|
|
|
|
|
encode: (value: string) => value
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
expect(array(asyncItem).decodeSync([])).toEqual([]);
|
|
|
|
|
|
|
|
expect(array(optional(asyncItem)).decodeSync([undefined])).toEqual([undefined]);
|
|
|
|
|
|
|
|
expect(() => array(asyncItem).decodeSync(['a'])).toThrow(SiumAsyncSchemaError);
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
describe('union()', () => {
|
|
|
|
describe('union()', () => {
|
|
|
|
@ -496,6 +523,18 @@ describe('union()', () => {
|
|
|
|
|
|
|
|
|
|
|
|
expect(() => schema.decodeSync('x')).toThrow(SiumAsyncSchemaError);
|
|
|
|
expect(() => schema.decodeSync('x')).toThrow(SiumAsyncSchemaError);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('can decode sync union members before an async member is needed', () => {
|
|
|
|
|
|
|
|
const asyncMember = createSchema({
|
|
|
|
|
|
|
|
kind: 'string',
|
|
|
|
|
|
|
|
async: true,
|
|
|
|
|
|
|
|
decodeImpl: async (input: string) => input,
|
|
|
|
|
|
|
|
encode: (value: string) => value
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
expect(union(number(), asyncMember).decodeSync(1)).toBe(1);
|
|
|
|
|
|
|
|
expect(() => union(asyncMember, number()).decodeSync(1 as never)).toThrow(SiumAsyncSchemaError);
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
describe('discriminated()', () => {
|
|
|
|
describe('discriminated()', () => {
|
|
|
|
@ -640,4 +679,24 @@ describe('discriminated()', () => {
|
|
|
|
|
|
|
|
|
|
|
|
expect(() => schema.decodeSync({ kind: 'a', val: 'x' })).toThrow(SiumAsyncSchemaError);
|
|
|
|
expect(() => schema.decodeSync({ kind: 'a', val: 'x' })).toThrow(SiumAsyncSchemaError);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('short-circuits selected discriminated member paths when async work is not needed', () => {
|
|
|
|
|
|
|
|
const asyncValue = createSchema({
|
|
|
|
|
|
|
|
kind: 'string',
|
|
|
|
|
|
|
|
async: true,
|
|
|
|
|
|
|
|
decodeImpl: async (input: string) => input,
|
|
|
|
|
|
|
|
encode: (value: string) => value
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
const schema = discriminated('kind', [
|
|
|
|
|
|
|
|
object({ kind: literal('a'), val: optional(asyncValue) }),
|
|
|
|
|
|
|
|
object({ kind: literal('b'), val: number() })
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
expect(schema.decodeSync({ kind: 'a', val: undefined })).toEqual({
|
|
|
|
|
|
|
|
kind: 'a',
|
|
|
|
|
|
|
|
val: undefined
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(schema.decodeSync({ kind: 'b', val: 1 })).toEqual({ kind: 'b', val: 1 });
|
|
|
|
|
|
|
|
expect(() => schema.decodeSync({ kind: 'a', val: 'x' })).toThrow(SiumAsyncSchemaError);
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|