UNPKG

@rawmodel/schema

Version:
211 lines (198 loc) 4.35 kB
import { Model } from '@rawmodel/core'; import { Spec } from '@hayspec/spec'; import { stringParser } from '@rawmodel/parsers'; import { stringLengthValidator } from '@rawmodel/validators'; import { createModelClass } from '../../..'; const spec = new Spec(); spec.test('generates empty model class', (ctx) => { const Klass = createModelClass({}); ctx.true(new Klass() instanceof Model); }); spec.test('generates model with properties', (ctx) => { const Klass = createModelClass({ props: [ { name: 'firstName' }, { name: 'lastName' }, ], }); const data = { firstName: 'John', lastName: 'Smith', }; const model = new Klass(data); ctx.deepEqual(model.serialize(), data); }); spec.test('supports property custom getter', (ctx) => { const Klass = createModelClass({ getters: { foo () { return () => 'foo'; }, }, props: [ { name: 'firstName', getter: 'foo', }, ], }); const model = new Klass(); ctx.deepEqual(model.serialize(), { firstName: 'foo', }); }); spec.test('supports property custom setter', (ctx) => { const Klass = createModelClass({ setters: { foo () { return () => 'foo'; }, }, props: [ { name: 'firstName', setter: 'foo', }, ], }); const model = new Klass({ firstName: 'bar', }); ctx.deepEqual(model.serialize(), { firstName: 'foo', }); }); spec.test('supports property default value', (ctx) => { const Klass = createModelClass({ defaultValues: { smithName() { return 'Smith'; }, }, props: [ { name: 'firstName', defaultValue: 'John', }, { name: 'lastName', defaultValue: 'smithName', }, ], }); const model = new Klass(); ctx.deepEqual(model.serialize(), { firstName: 'John', lastName: 'Smith', }); }); spec.test('supports property fake value', (ctx) => { const Klass = createModelClass({ fakeValues: { smithName() { return 'Smith'; }, }, props: [ { name: 'firstName', fakeValue: 'John', }, { name: 'lastName', fakeValue: 'smithName', }, ], }); const model = new Klass().fake(); ctx.deepEqual(model.serialize(), { firstName: 'John', lastName: 'Smith', }); }); spec.test('supports property empty value', (ctx) => { const Klass = createModelClass({ emptyValues: { emptyString() { return ''; }, }, props: [ { name: 'firstName', emptyValue: 'none', }, { name: 'lastName', emptyValue: 'emptyString', }, ], }); const model = new Klass(); ctx.deepEqual(model.serialize(), { firstName: 'none', lastName: '', }); }); spec.test('supports property parsers', (ctx) => { const Klass = createModelClass({ parsers: { string: stringParser, }, props: [ { name: 'firstName', parser: { array: true, resolver: 'string', }, }, ], }); const model = new Klass({ firstName: 100, }); ctx.deepEqual(model.serialize(), { firstName: ['100'], }); }); spec.test('supports property validators', async (ctx) => { const Klass = createModelClass({ validators: { stringLength: stringLengthValidator, }, props: [ { name: 'firstName', validators: [ { resolver: 'stringLength', code: 400, options: { min: 5 }, }, ], }, ], }); const model = new Klass({ firstName: '123', }); await ctx.throws(() => model.validate()); ctx.deepEqual(model.collectErrors(), [ { path: ['firstName'], code: 400 }, ]); }); spec.test('supports property handlers', async (ctx) => { const Klass = createModelClass({ handlers: { generalError() { return (e: any) => true; }, }, props: [ { name: 'firstName', handlers: [ { resolver: 'generalError', code: 400, }, ], }, ], }); const model = new Klass(); await ctx.throws(() => model.handle(new Error(), { quiet: false })); ctx.deepEqual(model.collectErrors(), [ { path: ['firstName'], code: 400 }, ]); }); export default spec;