diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..b3604bc --- /dev/null +++ b/.eslintrc @@ -0,0 +1,27 @@ +{ + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint/eslint-plugin"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:react/recommended" + ], + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module", + "project": "./tsconfig.json" + }, + "env": { + "node": true, + "es6": true + }, + "rules": { + "comma-dangle": "off", + "class-methods-use-this": "off", + "import/prefer-default-export": "off", + "import/no-dynamic-require": "off", + "global-require": "off", + "quotes": ["error", "single", { "allowTemplateLiterals": true }], + "@typescript-eslint/indent": ["error", 4] + } +} diff --git a/.gitignore b/.gitignore index 4d29575..800f3a8 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ # production /build +/dist # misc .DS_Store diff --git a/__tests__/Area.test.tsx b/__tests__/Area.test.tsx new file mode 100644 index 0000000..085891c --- /dev/null +++ b/__tests__/Area.test.tsx @@ -0,0 +1,129 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import { ValidatorArea, Validator } from '../src'; +import { ValidatorAreaProps } from '../src/ValidatorArea'; +import required from '../src/rules/required'; + +describe('test Provider', () => { + it('should render input', () => { + const area = mount( + + + + ); + + expect(area.find('input')).toBeDefined(); + }); + + it('should render inputs with callback as child', () => { + const area = mount( + + {() => ( + + )} + + ); + + expect(area.find('input')).toBeDefined(); + }) + + it('should throw an exception when no name provided', () => { + const area = () => { + mount( + + {() => ( + <> + + + + )} + + ); + } + expect(() => area()).toThrow(); + }); + + it('should index (nested) inputs', () => { + const area = mount( + + {() => ( + <> + <> +
+ + + <> +
+ + )} +
+ ); + + expect(area.instance().getInputRefs().length).toBe(4); + }); + + it('should apply rules on blur', () => { + const area = mount( + + + + ); + + area.find('input').at(0).simulate('blur'); + expect(area.state().errors[0]).toBe('This field is required'); + }); + + it('should render error when area dirty', async () => { + const area = mount( + + {({ errors }) => ( + <> + + {errors.length &&
{errors[0]}
} + + )} +
+ ); + + area.find('input').simulate('blur'); + expect(area.find('div').text()).toBe('This field is required'); + }) + + it('should validate element with rule string', () => { + Validator.extend('testrule', { + passed(): boolean { + return false; + }, + message(): string { + return 'string rule passed'; + } + }); + + const area = mount( + + {({ errors }) => ( + <> + + {errors.length &&
{errors[0]}
} + + )} +
+ ); + + area.find('input').simulate('blur'); + expect(area.find('div').text()).toBe('string rule passed'); + }) + + it('should call element\'s provided blur along validator blur', () => { + const mockFn = jest.fn(); + + const area = mount( + + + + ); + + area.find('input').simulate('blur'); + expect(mockFn).toBeCalled(); + }); +}) diff --git a/__tests__/Provider.test.tsx b/__tests__/Provider.test.tsx new file mode 100644 index 0000000..c1e30b2 --- /dev/null +++ b/__tests__/Provider.test.tsx @@ -0,0 +1,131 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import { ValidatorArea, ValidatorProvider } from '../src'; +import required from '../src/rules/required'; +import { ValidatorProviderProps } from '../src/Provider'; + + +const tick = () => { + return new Promise(resolve => { + setTimeout(resolve, 0); + }) +} + +describe('test Provider', () => { + it('should render Provider', () => { + const provider = mount( + + ); + + expect(provider.instance().props.rules).toBeDefined(); + }); + + it('should throw error when area with existing name is addeded', () => { + const provider = () => { + mount( + + +
+ + +
+ + + ); + } + + expect(() => provider()).toThrow('Validation area names should be unique'); + }) + + it('should render with function as child', () => { + const provider = mount( + + {() =>
test
} +
+ ); + + expect(provider.find('div').text()).toBe('test'); + }) + + it('should add an area when provided as child', () => { + const provider = mount( + + +
+ + + ); + + const areas = provider.state().areas; + + expect(areas.test).toBeDefined(); + expect(areas.test).toBeInstanceOf(ValidatorArea); + }) + + it('should not call callback when areas dirty', async () => { + const mockFn = jest.fn(); + + const provider = mount( + + {({ validate }) => ( + <> + + + + + + +