Skip to content

Commit

Permalink
minor: add vest.skip.group and vest.only.group (#225)
Browse files Browse the repository at this point in the history
  • Loading branch information
ealush authored Jun 28, 2020
1 parent 2d032a7 commit d1ce227
Show file tree
Hide file tree
Showing 25 changed files with 624 additions and 139 deletions.
54 changes: 50 additions & 4 deletions docs/exclusion.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ When performing validations in real world-scenarios, you may need to only run te

`vest.skip()` and `vest.only()` are functions that take a name of the test, or a list of names to either include or exclude fields from being validated. They should be called from the body of suite callback, and in order for them to take effect, they should be called before anything else.

## Important to know before using exclusion hooks:
!> **NOTE** When using `vest.only()` or `vest.skip()` you must place them before any of the tests defined in the suite. Hooks run in order of appearance, which means that if you place your `skip` hook after the filed you're skipping - it won't have any effect.

When using `vest.only()` or `vest.skip()` you must place them before any of the tests defined in the suite. Hooks run in order of appearance, which means that if you place your `skip` hook after the filed you're skipping - it won't have any effect.

### Only running specific tests
### Only running specific tests (including)

When validating upon user interactions, you will usually want to only validate the input the user currently interacts with to prevent errors appearing in unrelated places. For this, you can use `vest.only()` with the name of the test currently being validated.

Expand Down Expand Up @@ -57,6 +55,54 @@ const validate = vest.create('purchase', data => {
const validationResult = validate(formData);
```

## Including and excluding groups of tests

Similar to the way you use `vest.skip` and `vest.only` to include and exclude tests, you can use `vest.skip.group` and `vest.only.group` to exclude and include whole groups.

These two functions are very powerful and give you control of whole portions of your suite at once.

```js
import vest, { test, group, enforce } from 'vest';

vest.create('authentication_form', data => {
vest.skip.group(data.userExists ? 'signUp' : 'signIn');

test('userName', "Can't be empty", () => {
enforce(data.username).isNotEmpty();
});
test('password', "Can't be empty", () => {
enforce(data.password).isNotEmpty();
});

group('signIn', () => {
test(
'userName',
'User not found. Please check if you typed it correctly.',
findUserName(data.username)
);
});

group('signUp', () => {
test('email', 'Email already registered', isEmailRegistered(data.email));

test('age', 'You must be at least 18 years old to join', () => {
enforce(data.age).largerThanOrEquals(18);
});
});
});
```

## Things to know about how these functions work:

**vest.only.group()**:
When using `vest.only.group`, other groups won't be tested - but top level tests that aren't nested in any groups will. The reasoning is that the top level space is a shared are that will always be executed. If you want only your group to run, nest everything else under groups as well.

If you combine `vest.only.group` with `vest.skip`, if you skip a field inside a group that is included, that field will be excluded during this run regardless of its group membership.

**vest.skip.group()**

If you combine `vest.skip.group` with `vest.only` your included field declared within the skipped tests will be ignored.

**Read next about:**

- [Accessing intermediate suite result](./draft).
8 changes: 4 additions & 4 deletions docs/group.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Similar to the `describe` and `context` features provided by unit testing framew
import vest, { test, group, enforce } from 'vest';

vest.create('authentication_form', data => {
vest.skip(data.userExists ? 'signUp' : 'signIn');
vest.skip.group(data.userExists ? 'signUp' : 'signIn');

test('userName', "Can't be empty", () => {
enforce(data.username).isNotEmpty();
Expand Down Expand Up @@ -49,7 +49,7 @@ You may have in your application a multi-screen form, in which you want to valid
import vest, { test, group, enforce } from 'vest';

const validate = vest.create('product-create', (data, currentTab) => {
vest.only(currentScreen);
vest.only.group(currentScreen);

group('overview_tab', () => {
test('productTitle', 'Must be at least 5 chars.', () => {
Expand Down Expand Up @@ -97,11 +97,11 @@ import vest, { test, group, enforce } from 'vest';

const validate = vest.create('checkout_form', data => {
if (!data.usedPromo) {
vest.skip('used_promo');
vest.skip.group('used_promo');
}

if (!data.paysWithBalance) {
vest.skip('balance');
vest.skip.group('balance');
}

test(
Expand Down
5 changes: 5 additions & 0 deletions packages/vest/src/__snapshots__/spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Object {
"hasWarnings": [Function],
"hasWarningsByGroup": [Function],
"name": "molestias-veritatis-deserunt",
"testCount": 2,
"tests": Object {
"doloribus-enim-quisquam": Object {
"errorCount": 0,
Expand All @@ -39,6 +40,7 @@ Object {
"hasWarnings": [Function],
"hasWarningsByGroup": [Function],
"name": "eveniet-maxime-ea",
"testCount": 2,
"tests": Object {
"non-rem-dolorem": Object {
"errorCount": 0,
Expand Down Expand Up @@ -72,6 +74,7 @@ Object {
"hasWarnings": [Function],
"hasWarningsByGroup": [Function],
"name": "inventore-quis-impedit",
"testCount": 1,
"tests": Object {
"doloribus-enim-quisquam": Object {
"errorCount": 0,
Expand All @@ -97,6 +100,7 @@ Object {
"hasWarnings": [Function],
"hasWarningsByGroup": [Function],
"name": "corrupti-alias-autem",
"testCount": 1,
"tests": Object {
"autem": Object {
"errorCount": 0,
Expand Down Expand Up @@ -125,6 +129,7 @@ Object {
"hasWarnings": [Function],
"hasWarningsByGroup": [Function],
"name": "corrupti-alias-autem",
"testCount": 2,
"tests": Object {
"autem": Object {
"errorCount": 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ exports[`Test createSuite module Initial run Should initialize with an empty sta
Array [
Object {
"doneCallbacks": Array [],
"exclusive": Object {},
"exclusion": Object {
"groups": Object {},
"tests": Object {},
},
"fieldCallbacks": Object {},
"groups": Object {},
"lagging": Array [],
Expand Down
3 changes: 2 additions & 1 deletion packages/vest/src/core/createSuite/spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ describe('Test createSuite module', () => {
expect(state[0].testObjects).toHaveLength(0);
expect(state[0].pending).toHaveLength(0);
expect(state[0].lagging).toHaveLength(0);
expect(Object.keys(state[0].exclusive)).toHaveLength(0);
expect(Object.keys(state[0].exclusion.groups)).toHaveLength(0);
expect(Object.keys(state[0].exclusion.tests)).toHaveLength(0);
expect(Object.keys(state[0].tests)).toHaveLength(0);
expect(Object.keys(state[0].groups)).toHaveLength(0);
expect(Object.keys(state[0].doneCallbacks)).toHaveLength(0);
Expand Down
2 changes: 2 additions & 0 deletions packages/vest/src/core/produce/genTestsSummary/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ const genTestObject = (stateKey, testObject) => {
export const countFailures = state => {
state[SEVERITY_COUNT_ERROR] = 0;
state[SEVERITY_COUNT_WARN] = 0;
state[TEST_COUNT] = 0;
for (const test in state.tests) {
state[SEVERITY_COUNT_ERROR] += state.tests[test][SEVERITY_COUNT_ERROR];
state[SEVERITY_COUNT_WARN] += state.tests[test][SEVERITY_COUNT_WARN];
state[TEST_COUNT] += state.tests[test][TEST_COUNT];
}
return state;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
exports[`registerSuite When suite does not exist in state Should create initial suite without prevState 1`] = `
Object {
"doneCallbacks": Array [],
"exclusive": Object {},
"exclusion": Object {
"groups": Object {},
"tests": Object {},
},
"fieldCallbacks": Object {},
"groups": Object {},
"lagging": Array [],
Expand All @@ -19,7 +22,10 @@ exports[`registerSuite When suite exists in state Prev state data handling When
Array [
Object {
"doneCallbacks": Array [],
"exclusive": Object {},
"exclusion": Object {
"groups": Object {},
"tests": Object {},
},
"fieldCallbacks": Object {},
"groups": Object {},
"lagging": Array [
Expand All @@ -38,7 +44,10 @@ Array [
},
Object {
"doneCallbacks": Array [],
"exclusive": Object {},
"exclusion": Object {
"groups": Object {},
"tests": Object {},
},
"fieldCallbacks": Object {},
"groups": Object {},
"lagging": null,
Expand All @@ -55,7 +64,10 @@ exports[`registerSuite When suite exists in state Should match snapshot 1`] = `
Array [
Object {
"doneCallbacks": Array [],
"exclusive": Object {},
"exclusion": Object {
"groups": Object {},
"tests": Object {},
},
"fieldCallbacks": Object {},
"groups": Object {},
"lagging": Array [],
Expand All @@ -67,7 +79,10 @@ Array [
},
Object {
"doneCallbacks": Array [],
"exclusive": Object {},
"exclusion": Object {
"groups": Object {},
"tests": Object {},
},
"fieldCallbacks": Object {},
"groups": Object {},
"lagging": null,
Expand Down
9 changes: 8 additions & 1 deletion packages/vest/src/core/state/registerSuite/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { getSuite, setSuites } from '..';
import {
EXCLUSION_ITEM_TYPE_TESTS,
EXCLUSION_ITEM_TYPE_GROUPS,
} from '../../../hooks/exclusive/constants';
import singleton from '../../../lib/singleton';

/**
Expand All @@ -8,7 +12,10 @@ import singleton from '../../../lib/singleton';
*/
const INITIAL_SUITE_STATE = (suiteId, name) => ({
doneCallbacks: [],
exclusive: {},
exclusion: {
[EXCLUSION_ITEM_TYPE_TESTS]: {},
[EXCLUSION_ITEM_TYPE_GROUPS]: {},
},
fieldCallbacks: {},
groups: {},
lagging: [],
Expand Down
Loading

0 comments on commit d1ce227

Please sign in to comment.