UNPKG

@lucaspaganini/value-objects

Version:

TypeScript first validation and class creation library

156 lines (133 loc) 4.97 kB
import { expectTypeOf } from 'expect-type' import { VOString, VOStringOptions } from '../..' import { constructorFn } from './utils' describe('VOString', () => { it('Should return a class that can be extended', () => { class Test extends VOString() { test() { return 'test' } } const instance = new Test('') expect(instance.test()).toBe('test') }) it('Should throw on base class creation if one of the options is invalid', () => { const tests: Array<VOStringOptions> = [ { minLength: -1 }, { minLength: 1.5 }, { minLength: '123' as any }, { maxLength: -1 }, { maxLength: 1.5 }, { maxLength: '123' as any }, { minLength: 10, maxLength: 5 }, { trim: 'true' as any }, { trim: 1 as any }, { trim: 0 as any }, { pattern: 'abc' as any }, ] for (const test of tests) { const fn = () => VOString(test) expect(fn).toThrow() } }) it('Should be able to trim', () => { const Test = VOString({ trim: true }) const tests = [ { raw: ' abc ', expected: 'abc' }, { raw: ' a b c ', expected: 'a b c' }, { raw: ' ', expected: '' }, { raw: '\t\tabc\t\t', expected: 'abc' }, { raw: '\n\nabc\n\n', expected: 'abc' }, { raw: '\t abc \t', expected: 'abc' }, { raw: '\n\tabc\t\n', expected: 'abc' }, ] for (const test of tests) { const instance = new Test(test.raw) expect(instance.valueOf()).toBe(test.expected) } }) it('Should be able to not trim', () => { const Test = VOString({ trim: false }) const tests = [ { raw: ' abc ' }, { raw: ' a b c ' }, { raw: ' ' }, { raw: '\t\tabc\t\t' }, { raw: '\n\nabc\n\n' }, { raw: '\t abc \t' }, { raw: '\n\tabc\t\n' }, ] for (const test of tests) { const instance = new Test(test.raw) expect(instance.valueOf()).toBe(test.raw) } }) it("Should be able to set a min length and throw if it's smaller than that", () => { for (const test of lengthTests) { const Test = VOString({ minLength: test.length }) const raw = ''.padEnd(test.length + test.range, test.pattern) const fn = () => new Test(raw) if (test.range >= 0) expect(fn).not.toThrow() else expect(fn).toThrow() } }) it('Should be able to set a min length with trim and throw if the trimed value is smaller than that', () => { for (const test of lengthTests) { const Test = VOString({ minLength: test.length, trim: true }) const raw = ''.padEnd(test.length + test.range, test.pattern) const trimedLength = raw.trim().length const fn = () => new Test(raw) if (trimedLength >= test.length) expect(fn).not.toThrow() else expect(fn).toThrow() } }) it("Should be able to set a max length and throw if it's longer than that", () => { for (const test of lengthTests) { const Test = VOString({ maxLength: test.length, }) const raw = ''.padEnd(test.length + test.range, test.pattern) const fn = () => new Test(raw) if (test.range <= 0) expect(fn).not.toThrow() else expect(fn).toThrow() } }) it('Should be able to set a max length with trim and throw if the trimed value is longer than that', () => { for (const test of lengthTests) { const Test = VOString({ maxLength: test.length, trim: true }) const raw = ''.padEnd(test.length + test.range, test.pattern) const trimedLength = raw.trim().length const fn = () => new Test(raw) if (trimedLength <= test.length) expect(fn).not.toThrow() else expect(fn).toThrow() } }) it("Should be able to set a pattern and throw if it doesn't match it", () => { const tests = [{ pattern: /abc/, successes: ['abc', ' abc ', 'xabc', 'abcx'], failures: ['a b c', 'axbc', 'abxc'] }] for (const test of tests) { const Test = VOString({ pattern: test.pattern }) const makeFn = (raw: string) => () => new Test(raw) for (const raw of test.successes) expect(makeFn(raw)).not.toThrow() for (const raw of test.failures) expect(makeFn(raw)).toThrow() } }) it('Should have the correct types', () => { class Test extends VOString() {} expectTypeOf(constructorFn(Test)).toEqualTypeOf<(r: string) => Test>() expectTypeOf(new Test('').valueOf()).toEqualTypeOf<string>() }) }) const lengthTests = (() => { const ranges = [-10, -5, 0, 5, 10] const testsBase = [ { pattern: 'abc', length: 10 }, { pattern: ' abc ', length: 99 }, { pattern: ' a b c ', length: 287 }, { pattern: ' ', length: 573 }, { pattern: '\t\tabc\t\t', length: 904 }, { pattern: '\n\nabc\n\n', length: 2187 }, { pattern: '\t abc \t', length: 6700 }, { pattern: '\n\tabc\t\n', length: 68000 }, ] return testsBase.map(test => ranges.map(range => ({ ...test, range }))).reduce((acc, curr) => acc.concat(curr), []) })()