UNPKG

n4s

Version:

typed schema validation version of enforce

127 lines (107 loc) 4.14 kB
/** * Type tests for custom rule extensions via n4s namespace. * This file uses TypeScript's type system to ensure proper type safety. */ import { describe, it, expect, beforeEach } from 'vitest'; import { enforce } from '../n4s'; // Declare custom rules in the n4s namespace declare global { namespace n4s { interface EnforceMatchers { isPositive: (value: number) => boolean; isMockEmail: ( value: string, ) => boolean | { pass: boolean; message?: string }; isBetween: (value: number, min: number, max: number) => boolean; hasLength: (value: string, length: number) => boolean; } } } describe('enforce.extend with n4s namespace typing', () => { beforeEach(() => { enforce.extend({ isPositive: (value: number) => value > 0, isEmail: (value: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) || { pass: false, message: 'Invalid email format', }, isBetween: (value: number, min: number, max: number) => value >= min && value <= max, hasLength: (value: string, length: number) => value.length === length, }); }); describe('Eager mode with custom rules', () => { it('Should work with isPositive (passing)', () => { expect(() => enforce(5).isPositive()).not.toThrow(); }); it('Should work with isPositive (failing)', () => { expect(() => enforce(-1).isPositive()).toThrow(); }); it('Should work with isEmail (passing)', () => { expect(() => enforce('user@example.com').isEmail()).not.toThrow(); }); it('Should work with isEmail (failing)', () => { expect(() => enforce('invalid-email').isEmail()).toThrow(); }); it('Should work with isBetween (passing)', () => { expect(() => enforce(5).isBetween(1, 10)).not.toThrow(); }); it('Should work with isBetween (failing)', () => { expect(() => enforce(15).isBetween(1, 10)).toThrow(); }); it('Should work with hasLength (passing)', () => { expect(() => enforce('hello').hasLength(5)).not.toThrow(); }); it('Should work with hasLength (failing)', () => { expect(() => enforce('hello').hasLength(3)).toThrow(); }); it('Should work with custom message', () => { expect(() => enforce(-1).message('Value must be positive').isPositive(), ).toThrow('Value must be positive'); }); }); describe('Lazy mode with custom rules', () => { it('Should work with isPositive', () => { const rule = enforce.isPositive(); expect(rule.run(5)).toEqual({ pass: true, type: 5 }); expect(rule.run(-1)).toEqual({ pass: false, type: -1 }); }); it('Should work with isEmail', () => { const rule = enforce.isEmail(); expect(rule.run('user@example.com')).toEqual({ pass: true, type: 'user@example.com', }); expect(rule.run('invalid')).toEqual({ pass: false, type: 'invalid', message: 'Invalid email format', }); }); it('Should work with isBetween', () => { const rule = enforce.isBetween(1, 10); expect(rule.run(5)).toEqual({ pass: true, type: 5 }); expect(rule.run(15)).toEqual({ pass: false, type: 15 }); }); it('Should work with hasLength', () => { const rule = enforce.hasLength(5); expect(rule.run('hello')).toEqual({ pass: true, type: 'hello' }); expect(rule.run('hi')).toEqual({ pass: false, type: 'hi' }); }); }); describe('Chaining with built-in rules', () => { it('Should chain custom rules with built-in rules', () => { const rule = enforce.isNumber().isPositive().isBetween(1, 100); expect(rule.run(50)).toEqual({ pass: true, type: 50 }); expect(rule.run(-5)).toEqual({ pass: false, type: -5 }); expect(rule.run(150)).toEqual({ pass: false, type: 150 }); }); it('Should chain built-in rules with custom rules', () => { const rule = enforce.isString().hasLength(5); expect(rule.run('hello')).toEqual({ pass: true, type: 'hello' }); expect(rule.run('hi')).toEqual({ pass: false, type: 'hi' }); }); }); });