Skip to content

Commit

Permalink
Improve test coverage (#378)
Browse files Browse the repository at this point in the history
* Improve test coverage

* Add expectIsValid utility

* Cover all validators

* Fix typing on Validation spec

* 100%

* Work on linting and typing

* Fix sort

* Revert dist
  • Loading branch information
rkuykendall authored Feb 15, 2020
1 parent 8b5a0db commit b8881d0
Show file tree
Hide file tree
Showing 34 changed files with 807 additions and 844 deletions.
12 changes: 11 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{
"ignorePatterns": [
"dist/",
"node_modules/",
"coverage/"
],
"extends": [
"airbnb",
"eslint:recommended",
Expand All @@ -17,9 +22,14 @@
"@typescript-eslint/explicit-function-return-type": 0,
"@typescript-eslint/no-explicit-any": 0,
"import/extensions": 0,
"import/no-extraneous-dependencies": ["error", {"devDependencies": ["setupTests.ts", "**/*spec.tsx"]}],
"import/no-extraneous-dependencies": [
"error", {
"devDependencies": ["rollup.config.js", "setupTests.ts", "__tests__/*", "__test_utils__/*"]
}
],
"prettier/prettier": ["error", { "singleQuote": true }],
"react/forbid-prop-types": 0,
"react/jsx-filename-extension": 0,
"react/static-property-placement": 0
},
"settings": {
Expand Down
2 changes: 1 addition & 1 deletion API.md
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ Returns true if the value is not undefined or null
<MyInput name="foo" validations="isUndefined" />
```

Returns true if the value is the undefined
Returns true if the value is undefined

**isEmptyString**

Expand Down
2 changes: 1 addition & 1 deletion __test_utils__/TestInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class TestInput extends React.Component<Props> {
};

render() {
return <input type={this.props.type || 'text'} value={this.props.value} onChange={this.updateValue} />;
return <input type={this.props.type || 'text'} value={this.props.value || ''} onChange={this.updateValue} />;
}
}

Expand Down
30 changes: 30 additions & 0 deletions __test_utils__/expectIsValid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { mount } from 'enzyme';

import Formsy from '../src';
import { InputFactory } from './TestInput';
import { getInputInstance } from './getInput';

const TestInput = InputFactory({
render() {
return <input value={this.props.value || ''} readOnly />;
},
});

function ValidationForm(props: { validations: string; value?: any }) {
const { validations, value } = props;

return (
<Formsy>
<TestInput name="foo" validations={validations} value={value} />
</Formsy>
);
}

export function expectIsValid(testForm: React.ComponentElement<any, any>) {
const form = mount(testForm);
const inputComponent = form.find(TestInput);
return expect(getInputInstance(inputComponent).isValid());
}

export default ValidationForm;
10 changes: 10 additions & 0 deletions __test_utils__/getInput.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { WrapperInstanceMethods } from '../src/Wrapper';
import Formsy from '../src';

export function getInputInstance(inputComponent) {
return inputComponent.instance() as WrapperInstanceMethods;
}

export function getFormInstance(formComponent) {
return formComponent.instance() as Formsy;
}
62 changes: 40 additions & 22 deletions __tests__/Element-spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ describe('Element', () => {
updateValue = event => {
this.props.setValue(event.target.value, false);
};

render() {
return <input type="text" value={this.props.value} onChange={this.updateValue} />;
return <input type="text" value={this.props.value || ''} onChange={this.updateValue} />;
}
},
);
const form = mount(
<Formsy>
<Input name="foo" value="foo" innerRef="comp" />
<Input name="foo" value="foo" />
</Formsy>,
);
const inputComponent = form.find(Input);
Expand Down Expand Up @@ -302,7 +303,7 @@ describe('Element', () => {
).toEqual(false);
});

it('should not override error messages with error messages passed by form if passed eror messages is an empty object', () => {
it('should not override error messages with error messages passed by form if passed error messages is an empty object', () => {
class TestForm extends React.Component {
render() {
return (
Expand All @@ -326,6 +327,40 @@ describe('Element', () => {
expect(inputComponent.instance().getErrorMessage()).toEqual('bar3');
});

it('should handle multiple validation error messages passed from validators', () => {
function customValidationA() {
return 'error message one';
}

function customValidationB() {
return 'error message two';
}

function TestForm() {
return (
<Formsy>
<TestInput
name="A"
validations={{
customValidationA,
customValidationB,
}}
value="foo"
/>
</Formsy>
);
}

const form = mount(<TestForm />);
const inputComponent = form.find(TestInput);

const formEl = form.find('form');
formEl.simulate('submit');

expect(inputComponent.instance().getErrorMessage()).toEqual('error message one');
expect(inputComponent.instance().getErrorMessages()).toEqual(['error message one', 'error message two']);
});

it('should override all error messages with error messages passed by form', () => {
class TestForm extends React.Component {
render() {
Expand Down Expand Up @@ -511,6 +546,7 @@ describe('Element', () => {
}
const form = mount(<TestForm />);

// TODO: Beef up this smoke test
expect(true).toBe(true);

const formEl = form.find('form');
Expand All @@ -533,6 +569,7 @@ describe('Element', () => {
}
const form = mount(<TestForm />);

// TODO: Beef up this smoke test
expect(true).toBe(true);

const formEl = form.find('form');
Expand Down Expand Up @@ -589,25 +626,6 @@ describe('Element', () => {
expect(renderSpy.calledTwice).toEqual(true);
});

it('binds all necessary methods', () => {
const onInputRef = input => {
['isValidValue', 'resetValue', 'setValidations', 'setValue'].forEach(fnName => {
const fn = input[fnName];
try {
fn();
} catch (e) {
throw new Error(`Method '${fnName}' isn't bound.`);
}
});
};

mount(
<Formsy>
<TestInput ref={onInputRef} name="name" value="foo" />
</Formsy>,
);
});

it('unregisters on unmount', () => {
const TestComponent = ({ hasInput }) => <Formsy>{hasInput ? <TestInput name="foo" value="foo" /> : null}</Formsy>;

Expand Down
Loading

0 comments on commit b8881d0

Please sign in to comment.