Skip to content

Feature/min max rule #2

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 5 commits into from
Aug 23, 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
4 changes: 2 additions & 2 deletions __tests__/Area.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe('test Provider', () => {
);

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

it('should render error when area dirty', async () => {
Expand All @@ -86,7 +86,7 @@ describe('test Provider', () => {
);

area.find('input').simulate('blur');
expect(area.find('div').text()).toBe('This field is required');
expect(area.find('div').text()).toBe('Test is required');
})

it('should validate element with rule string', () => {
Expand Down
58 changes: 58 additions & 0 deletions __tests__/rules/max.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react';
import { mount } from 'enzyme';
import { ValidatorArea } from '../../src';
import { ValidatorAreaProps } from '../../src/ValidatorArea';
import max from '../../src/rules/max';

describe('test max rule', () => {
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 falsely validate textarea', () => {
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)]}>
<select name="test">
<option value="">Choose...</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);
});
});
58 changes: 58 additions & 0 deletions __tests__/rules/min.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react';
import { mount } from 'enzyme';
import { ValidatorArea } from '../../src';
import { ValidatorAreaProps } from '../../src/ValidatorArea';
import min from '../../src/rules/min';

describe('test min rule', () => {
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');
});

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 falsely validate select', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules={[min(5)]}>
<select name="test">
<option value="">Choose...</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);
});
});
25 changes: 19 additions & 6 deletions __tests__/rules/required.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ValidatorAreaProps } from '../../src/ValidatorArea';
import required from '../../src/rules/required';

describe('test required rule', () => {
it('should validate input', () => {
it('should falsely validate input', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules={[required]}>
<input name="test" />
Expand All @@ -14,10 +14,10 @@ describe('test required rule', () => {

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

it('should validate textarea', () => {
it('should falsely validate textarea', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules={[required]}>
<textarea name="test" />
Expand All @@ -26,10 +26,10 @@ describe('test required rule', () => {

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

it('should validate select', () => {
it('should falsely validate select', () => {
const area = mount<ValidatorArea, ValidatorAreaProps>(
<ValidatorArea rules={[required]}>
<select name="test">
Expand All @@ -40,6 +40,19 @@ describe('test required rule', () => {

area.find('select').simulate('blur');
expect(area.state().errors.length).toBe(1);
expect(area.state().errors[0]).toBe('This field is required');
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>
);

area.find('select').simulate('blur');
expect(area.state().errors.length).toBe(0);
});
});
4 changes: 2 additions & 2 deletions src/Rule.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ValidationElement } from './ValidationElement';

export type Rule = {
passed(element: ValidationElement[]): boolean;
message(element: ValidationElement[]): string;
passed(elements: ValidationElement[]): boolean;
message(name: string): string;
}
2 changes: 1 addition & 1 deletion src/ValidatorArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class ValidatorArea extends React.Component<ValidatorAreaProps, ValidatorAreaSta
}

if (typeof rule !== 'string' && !rule.passed(refs)) {
messages.push(rule.message(refs));
messages.push(rule.message(this.getName()));
this.dirty = true;
}
}
Expand Down
28 changes: 28 additions & 0 deletions src/rules/max.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Rule } from '../Rule';
import { ValidationElement } from '../ValidationElement';
import { capitalize } from '../utils/utils';

export default (value: number): Rule => {
return {
passed(elements: ValidationElement[]): boolean {
let passed = true;

elements.forEach((element) => {
if (element instanceof HTMLInputElement
|| element instanceof HTMLTextAreaElement
) {
passed = parseFloat(element.value.trim()) <= value;
}

if (element instanceof HTMLSelectElement) {
passed = parseFloat(element.options[element.selectedIndex].value) <= value;
}
});

return passed;
},
message(name: string): string {
return `${capitalize(name)} should be not greater than ${value}`
}
}
}
28 changes: 28 additions & 0 deletions src/rules/min.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Rule } from '../Rule';
import { ValidationElement } from '../ValidationElement';
import { capitalize } from '../utils/utils';

export default (value: number): Rule => {
return {
passed(elements: ValidationElement[]): boolean {
let passed = true;

elements.forEach((element) => {
if (element instanceof HTMLInputElement
|| element instanceof HTMLTextAreaElement
) {
passed = parseFloat(element.value.trim()) >= value;
}

if (element instanceof HTMLSelectElement) {
passed = parseFloat(element.options[element.selectedIndex].value) >= value;
}
});

return passed;
},
message(name: string): string {
return `${capitalize(name)} should be at least ${value}`
}
}
}
5 changes: 3 additions & 2 deletions src/rules/required.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ValidationElement } from '../ValidationElement';
import { capitalize } from '../utils/utils';

export default {
passed(elements: ValidationElement[]): boolean {
Expand All @@ -19,7 +20,7 @@ export default {
return passed;
},

message(): string {
return 'This field is required';
message(name: string): string {
return `${capitalize(name)} is required`;
}
};
6 changes: 6 additions & 0 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Return the given string with an uppercase first letter
*/
export const capitalize = (value: string): string => {
return value.substr(0, 1).toUpperCase() + value.substr(1, value.length - 1);
}