Skip to content

WIP validation all elements #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions __tests__/Area.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,17 @@ describe('test ValidatorProvider', () => {
expect(area.state().errors[0]).toBe('Not passed');
});

it('should not apply rules on blur when non-blurrable element', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="passes_not" name="test">
<canvas />
</ValidatorArea>
);

area.find('canvas').at(0).simulate('blur');
expect(area.state().errors.length).toBe(0);
});

it('should render error when area dirty', async () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="passes_not">
Expand Down Expand Up @@ -239,4 +250,39 @@ describe('test ValidatorProvider', () => {
area.find('input').simulate('blur');
expect(mockFn).toBeCalled();
});

it('should get refs by type', async () => {
Validator.extend('test_types', (validator: Validator) => ({
passed(): boolean {
return validator.refs(undefined, HTMLInputElement).length === 1
&& validator.refs('test1', HTMLTextAreaElement).length === 1
&& validator.refs('test1').length === 1
&& validator.refs('test1', HTMLProgressElement).length === 0;
},
message(): string {
return 'test';
}
}))
const mockFn = jest.fn();

const provider = mount<ValidatorProvider, ValidatorProviderProps>(
<ValidatorProvider rules="test_types">
{({ validate }: ProviderScope) => (
<>
<ValidatorArea name="test1">
<textarea value="" />
</ValidatorArea>
<ValidatorArea>
<input value="" name="test2" />
</ValidatorArea>
<button onClick={() => validate(mockFn)} />
</>
)}
</ValidatorProvider>
);

provider.find('button').simulate('click');
await tick();
expect(mockFn).toHaveBeenCalled();
});
})
77 changes: 38 additions & 39 deletions __tests__/rules/max.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,54 +9,53 @@ describe('test max rule', () => {
Validator.extend('max', max);
});

it('should falsely validate input', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="max:5">
<input name="test" value="6" />
</ValidatorArea>
);

area.find('input').simulate('blur');
expect(area.state().errors.length).toBe(1);
expect(area.state().errors[0]).toBe('Test should be not greater than 5');
it('should always validate inputs and not validate non-inputs', () => {
const input = document.createElement('input');
input.value = '5';

const throwsArgumentError = () => {
const validator = new Validator([
input
], ['max:foo'],
'validate_throws'
);
validator.validate();
}

const validator_input = new Validator([
input
],
['max:4'],
'validator_input');

const progress = document.createElement('progress');
progress.value = 5;

const validator_progress = new Validator([
progress
],
['max:4'],
'validate_progress');

expect(() => throwsArgumentError()).toThrowError('max rule has incorrect argument foo. Expected a number.')

validator_input.validate();
expect(validator_input.getErrors().length).toBe(1);

validator_progress.validate();
expect(validator_progress.getErrors().length).toBe(0);
});

it('should falsely validate textarea', () => {
it('should validate select', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="max:5">
<textarea name="test" value="6" />
</ValidatorArea>
);

area.find('textarea').simulate('blur');
expect(area.state().errors.length).toBe(1);
expect(area.state().errors[0]).toBe('Test should be not greater than 5');
});

it('should falsely validate select', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="max:5">
<ValidatorArea rules="max:3">
<select name="test">
<option value="">Choose...</option>
<option value="4" selected>Option</option>
</select>
</ValidatorArea>
);

area.find('select').simulate('blur');
expect(area.state().errors.length).toBe(1);
expect(area.state().errors[0]).toBe('Test should be not greater than 5');
});

it('should truly validate select', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="max:5">
<select name="test">
<option value={5}>Choose...</option>
</select>
</ValidatorArea>
);

area.find('select').simulate('blur');
expect(area.state().errors.length).toBe(0);
});
});
82 changes: 42 additions & 40 deletions __tests__/rules/min.test.tsx
Original file line number Diff line number Diff line change
@@ -1,59 +1,61 @@
import React from 'react';
import { mount } from 'enzyme';
import { ValidatorArea, ValidatorAreaProps } from '@/components/ValidatorArea';
import min from '@/rules/min';
import { Validator } from '@/Validator';
import { mount } from 'enzyme';
import { ValidatorArea, ValidatorAreaProps } from '@/components/ValidatorArea';
import React from 'react';

describe('test min rule', () => {
Validator.extend('min', min);
it('should falsely validate input', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="min:5">
<input name="test" />
</ValidatorArea>
);

area.find('input').simulate('blur');
expect(area.state().errors.length).toBe(1);
expect(area.state().errors[0]).toBe('Test should be at least 5');
beforeEach(() => {
Validator.extend('min', min);
});

it('should falsely validate textarea', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="min:5">
<textarea name="test" />
</ValidatorArea>
);

area.find('textarea').simulate('blur');
expect(area.state().errors.length).toBe(1);
expect(area.state().errors[0]).toBe('Test should be at least 5');
it('should always validate inputs and not validate non-inputs', () => {
const input = document.createElement('input');
input.value = '5';

const throwsArgumentError = () => {
const validator = new Validator([
input
], ['min:foo'],
'validate_throws'
);
validator.validate();
}

const validator_input = new Validator([
input
],
['min:6'],
'validator_input');

const progress = document.createElement('progress');
progress.value = 5;

const validator_progress = new Validator([
progress
],
['min:4'],
'validate_progress');

expect(() => throwsArgumentError()).toThrowError('min rule has incorrect argument foo. Expected a number.')

validator_input.validate();
expect(validator_input.getErrors().length).toBe(1);

validator_progress.validate();
expect(validator_progress.getErrors().length).toBe(0);
});

it('should falsely validate select', () => {
it('should validate select', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="min:5">
<select name="test">
<option value="">Choose...</option>
<option value="4" selected>Option</option>
</select>
</ValidatorArea>
);

area.find('select').simulate('blur');
expect(area.state().errors.length).toBe(1);
expect(area.state().errors[0]).toBe('Test should be at least 5');
});

it('should truly validate select', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="min:5">
<select name="test">
<option value={5}>Choose...</option>
</select>
</ValidatorArea>
);

area.find('select').simulate('blur');
expect(area.state().errors.length).toBe(0);
});
});
53 changes: 18 additions & 35 deletions __tests__/rules/required.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,7 @@ describe('test required rule', () => {
Validator.extend('required', required);
});

it('should falsely validate input', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="required">
<input name="test" />
</ValidatorArea>
);

area.find('input').simulate('blur');
expect(area.state().errors.length).toBe(1);
expect(area.state().errors[0]).toBe('Test is required');
});

it('should falsely validate textarea', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="required">
<textarea name="test" />
</ValidatorArea>
);

area.find('textarea').simulate('blur');
expect(area.state().errors.length).toBe(1);
expect(area.state().errors[0]).toBe('Test is required');
});

it('should falsely validate select', () => {
it('should falsely validate select with options', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="required">
<select name="test">
Expand All @@ -47,16 +23,23 @@ describe('test required rule', () => {
expect(area.state().errors[0]).toBe('Test is required');
});

it('should validate select', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules="required">
<select name="test">
<option value="foo">Choose...</option>
</select>
</ValidatorArea>
);
it('should always validate inputs and not validate non-inputs', () => {
const validator_input = new Validator([
document.createElement('input')
],
['required'],
'validator_input');

area.find('select').simulate('blur');
expect(area.state().errors.length).toBe(0);
const validator_progress = new Validator([
document.createElement('progress')
],
['required'],
'validate_progress');

validator_input.validate();
expect(validator_input.getErrors().length).toBe(1);

validator_progress.validate();
expect(validator_progress.getErrors().length).toBe(0);
});
});
37 changes: 37 additions & 0 deletions __tests__/utils/dom.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { getValue, htmlCollectionToArray } from '@/utils/dom';

describe('dom helpers test', () => {
it('should convert HtmlCollection to array', () => {
const select = document.createElement('select');
const option1 = document.createElement('option');
const option2 = document.createElement('option');
select.appendChild(option1);
select.appendChild(option2);

const optionArray = htmlCollectionToArray(select.children);
expect(Array.isArray(optionArray)).toBeTruthy();
})

it('should get value of elements or null', () => {
const select = document.createElement('select');
select.multiple = true;
const option1 = document.createElement('option');
option1.value = 'foo';
option1.selected = true;
const option2 = document.createElement('option');
option2.value = 'bar';
option2.selected = true;
select.appendChild(option1);
select.appendChild(option2);

const input = document.createElement('input');
input.value = 'baz';

const div = document.createElement('div');

expect(getValue(select)).toEqual(expect.arrayContaining(['foo', 'bar']));
expect(getValue(input)).toBe('baz');
expect(getValue(div)).toBeNull();

})
});
3 changes: 1 addition & 2 deletions src/Rule.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Validator } from '@/Validator';
import { ValidationElement } from '@/ValidationElement';

/**
* Function to access validator using the rule
Expand All @@ -13,7 +12,7 @@ export type RuleObject = {
/**
* Returns whether the rule passed with the given element(s)
*/
passed(elements: ValidationElement[], ...args: string[]): boolean;
passed(elements: HTMLElement[], ...args: string[]): boolean;
/**
* Message shown when the rule doesn't pass
*/
Expand Down
4 changes: 0 additions & 4 deletions src/ValidationElement.ts

This file was deleted.

Loading