Skip to content

Commit

Permalink
minor(vest): account for async tests in isValid function
Browse files Browse the repository at this point in the history
  • Loading branch information
ealush committed May 11, 2021
1 parent 339fe45 commit e3b42c6
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 2 deletions.
9 changes: 7 additions & 2 deletions packages/vest/docs/result.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,20 @@ Along with these values, the result object exposes the following methods:

`isValid` returns whether the validation suite as a whole is valid or not.

A suite is considered valid if both conditions are met:
A suite is considered valid if the following conditions are met:

- There are no errors (`hasErrors() === false`) in the suite - warnings are not counted as errors.
- All non optional fields have passing tests.
- There are no pending async tests.

```js
resultObject.isValid();
result.isValid();

suite.get().isValid();
```

?> **Note** when `isValid` equals `false`, it does not necessarily mean that the form is inValid, but that it might not be valid _yet_. For example, if not all the fields are filled, the form is simply not valid, even though it may not be strictly invalid.

## `hasErrors` and `hasWarnings` functions

If you only need to know if a certain field has validation errors or warnings but don't really care which they are, you can use `hasErrors` or `hasWarnings` functions.
Expand Down
98 changes: 98 additions & 0 deletions packages/vest/src/core/produce/__tests__/isValid.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import wait from 'wait';

import vest, { test, optional } from 'vest';

describe('isValid', () => {
Expand Down Expand Up @@ -74,6 +76,102 @@ describe('isValid', () => {
});
});

describe('When the suite has an async optional test', () => {
let suite;

beforeEach(() => {
suite = vest.create(() => {
optional('field_1');
test('field_1', async () => {
await wait(300);
return true;
});
});
});

describe('When test is pending', () => {
it('Should return false', () => {
suite();
expect(suite.get().isValid()).toBe(false);
});
});
describe('When test is passing', () => {
it('Should return true', async () => {
suite();
await wait(300);
expect(suite.get().isValid()).toBe(true);
});
});
});

describe('When the suite has warning async tests', () => {
let suite;

beforeEach(() => {
suite = vest.create(() => {
test('field_1', async () => {
vest.warn();
await wait(300);
return true;
});

test('field_1', () => {
return true;
});
});
});

it('Should return true', () => {
expect(suite().isValid()).toBe(true);
});
});

describe('When the suite has async non-optional tests', () => {
let suite;

beforeEach(() => {
suite = vest.create(only => {
vest.only(only);
optional('field_2');
test('field_1', async () => {
await wait(300);
return true;
});
test('field_2', () => {
return true;
});
});
});

describe('When test is pending', () => {
it('Should return `false`', () => {
const result = suite();

expect(result.isValid()).toBe(false);
});
});

describe('When async test is passing', () => {
it('Should return `true`', () => {
return new Promise(done => {
const result = suite().done(() => {
expect(result.isValid()).toBe(true);
done();
});
});
});
});

describe('When test is lagging', () => {
it('Should return `false`', () => {
suite();
const result = suite('field_2');

expect(result.isValid()).toBe(false);
});
});
});

describe('When a all required fields are passing', () => {
let suite;

Expand Down
12 changes: 12 additions & 0 deletions packages/vest/src/core/produce/produce.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import getFailuresByGroup from 'getFailuresByGroup';
import hasFailures from 'hasFailures';
import hasFailuresByGroup from 'hasFailuresByGroup';
import hasRemainingTests from 'hasRemainingTests';
import { isNotEmpty } from 'isEmpty';
import isFunction from 'isFunction';
import { SEVERITY_GROUP_ERROR, SEVERITY_GROUP_WARN } from 'resultKeys';
import { HAS_WARNINGS, HAS_ERRORS } from 'sharedKeys';
import {
useTestCallbacks,
useTestObjects,
useOptionalFields,
usePending,
} from 'stateHooks';
import withArgs from 'withArgs';

Expand Down Expand Up @@ -119,6 +121,16 @@ function isValid() {

const [optionalFields] = useOptionalFields();

const [{ pending, lagging }] = usePending();

if (
isNotEmpty(
pending.concat(lagging).filter(testObject => !testObject.isWarning)
)
) {
return false;
}

for (const test in result.tests) {
if (!optionalFields[test] && result.tests[test].testCount === 0) {
return false;
Expand Down

0 comments on commit e3b42c6

Please sign in to comment.