Skip to content

Commit e13b558

Browse files
committed
patch: use invariant utility
1 parent 6a4ed2c commit e13b558

File tree

24 files changed

+118
-183
lines changed

24 files changed

+118
-183
lines changed

packages/context/src/context.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import assign from 'assign';
22
import defaultTo from 'defaultTo';
3+
import invariant from 'invariant';
34
import optionalFunctionValue from 'optionalFunctionValue';
4-
import throwError from 'throwError';
55

66
// eslint-disable-next-line max-lines-per-function
77
export function createContext<T extends Record<string, unknown>>(
@@ -22,12 +22,11 @@ export function createContext<T extends Record<string, unknown>>(
2222
};
2323

2424
function useX(errorMessage?: string): T {
25-
return (
26-
(storage.ctx as T) ??
27-
throwError(
28-
defaultTo(errorMessage, 'Context was used after it was closed')
29-
)
25+
invariant(
26+
storage.ctx,
27+
defaultTo(errorMessage, 'Context was used after it was closed')
3028
);
29+
return storage.ctx as T;
3130
}
3231

3332
function run<R>(ctxRef: Partial<T>, fn: (context: T) => R): R {

packages/n4s/src/exports/compose.ts

+3-11
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1+
import invariant from 'invariant';
12
import mapFirst from 'mapFirst';
2-
import throwError from 'throwError';
3+
import { ctx } from 'n4s';
34

45
import type { TComposeResult, TLazyRuleRunners } from 'genEnforceLazy';
5-
import { isEmpty } from 'isEmpty';
6-
import { ctx } from 'n4s';
76
import { defaultToPassing, TRuleDetailedResult } from 'ruleReturn';
87
import runLazyRule from 'runLazyRule';
98

@@ -16,14 +15,7 @@ export default function compose(
1615
(value: any) => {
1716
const res = run(value);
1817

19-
if (!res.pass) {
20-
if (isEmpty(res.message)) {
21-
throwError();
22-
} else {
23-
// Explicitly throw a string so that vest.test can pick it up as the validation error message
24-
throw res.message;
25-
}
26-
}
18+
invariant(res.pass, new String(res.message));
2719
},
2820
{
2921
run,

packages/n4s/src/lib/transformResult.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import invariant from 'invariant';
12
import { isBoolean } from 'isBooleanValue';
23
import optionalFunctionValue from 'optionalFunctionValue';
3-
import throwError from 'throwError';
44

55
import ruleReturn, { TRuleReturn, TRuleDetailedResult } from 'ruleReturn';
66
import type { TRuleValue, TArgs } from 'runtimeRules';
@@ -29,9 +29,8 @@ export function transformResult(
2929

3030
function validateResult(result: TRuleReturn): void {
3131
// if result is boolean, or if result.pass is boolean
32-
if (isBoolean(result) || (result && isBoolean(result.pass))) {
33-
return;
34-
}
35-
36-
throwError('Incorrect return value for rule: ' + JSON.stringify(result));
32+
invariant(
33+
isBoolean(result) || (result && isBoolean(result.pass)),
34+
'Incorrect return value for rule: ' + JSON.stringify(result)
35+
);
3736
}

packages/n4s/src/runtime/enforceEager.ts

+8-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import throwError from 'throwError';
1+
import invariant from 'invariant';
22

33
import eachEnforceRule from 'eachEnforceRule';
44
import { ctx } from 'enforceContext';
@@ -45,16 +45,13 @@ export default function enforceEager(value: TRuleValue): IRules {
4545
...args
4646
);
4747

48-
if (!transformedResult.pass) {
49-
if (isEmpty(transformedResult.message)) {
50-
throwError(
51-
`enforce/${ruleName} failed with ${JSON.stringify(value)}`
52-
);
53-
} else {
54-
// Explicitly throw a string so that vest.test can pick it up as the validation error message
55-
throw transformedResult.message;
56-
}
57-
}
48+
invariant(
49+
transformedResult.pass,
50+
isEmpty(transformedResult.message)
51+
? `enforce/${ruleName} failed with ${JSON.stringify(value)}`
52+
: new String(transformedResult.message)
53+
);
54+
5855
return target;
5956
};
6057
}

packages/shared/src/__tests__/throwError.test.ts

-41
This file was deleted.

packages/shared/src/invariant.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import optionalFunctionValue from 'optionalFunctionValue';
2+
import { TStringable } from 'utilityTypes';
3+
4+
export default function invariant(
5+
condition: any,
6+
// eslint-disable-next-line @typescript-eslint/ban-types
7+
message?: String | TStringable
8+
): asserts condition {
9+
if (condition) {
10+
return;
11+
}
12+
13+
// If message is a string object (rather than string literal)
14+
// Throw the value directly as a string
15+
// Alternatively, throw an error with the message
16+
throw message instanceof String
17+
? message.valueOf()
18+
: new Error(message ? optionalFunctionValue(message) : message);
19+
}

packages/shared/src/throwError.ts

+2-19
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,5 @@
1-
import defaultTo from 'defaultTo';
2-
3-
/**
4-
* Throws a timed out error.
5-
*/
6-
export default function throwError(
7-
devMessage?: string,
8-
productionMessage?: string
9-
): never {
10-
throw new Error(
11-
__DEV__ ? devMessage : defaultTo(productionMessage, devMessage)
12-
);
13-
}
14-
15-
export function throwErrorDeferred(
16-
devMessage?: string,
17-
productionMessage?: string
18-
): void {
1+
export function deferThrow(message?: string): void {
192
setTimeout(() => {
20-
throwError(devMessage, productionMessage);
3+
throw new Error(message);
214
}, 0);
225
}

packages/vest/src/__tests__/isolate.test.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import { IsolateTypes } from 'IsolateTypes';
55
describe('isolate', () => {
66
let firstRun = true;
77
let vest, isolate, skipWhen, dummyTest;
8-
let throwErrorDeferred;
8+
let deferThrow;
99

1010
beforeEach(() => {
1111
firstRun = true;
1212
const mock = mockThrowError();
13-
throwErrorDeferred = mock.throwErrorDeferred;
13+
deferThrow = mock.deferThrow;
1414
vest = mock.vest;
1515
skipWhen = vest.skipWhen;
1616
isolate = require('isolate').isolate;
@@ -240,10 +240,10 @@ describe('isolate', () => {
240240
});
241241

242242
suite();
243-
expect(throwErrorDeferred).toHaveBeenCalledTimes(0);
243+
expect(deferThrow).toHaveBeenCalledTimes(0);
244244
suite();
245-
expect(throwErrorDeferred).toHaveBeenCalledTimes(1);
246-
expect(throwErrorDeferred).toHaveBeenCalledWith(
245+
expect(deferThrow).toHaveBeenCalledTimes(1);
246+
expect(deferThrow).toHaveBeenCalledWith(
247247
expect.stringContaining(
248248
'Vest Critical Error: Tests called in different order than previous run'
249249
)
@@ -258,9 +258,9 @@ describe('isolate', () => {
258258
});
259259

260260
suite();
261-
expect(throwErrorDeferred).toHaveBeenCalledTimes(0);
261+
expect(deferThrow).toHaveBeenCalledTimes(0);
262262
suite();
263-
expect(throwErrorDeferred).toHaveBeenCalledTimes(0);
263+
expect(deferThrow).toHaveBeenCalledTimes(0);
264264
});
265265
});
266266
});

packages/vest/src/core/isolate/isolates/each.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import invariant from 'invariant';
12
import isFunction from 'isFunction';
2-
import throwError from 'throwError';
33

44
import { IsolateTypes } from 'IsolateTypes';
55
import { isolate } from 'isolate';
@@ -21,9 +21,7 @@ export default function each<T>(
2121
list: T[],
2222
callback: (arg: T, index: number) => void
2323
): void {
24-
if (!isFunction(callback)) {
25-
throwError('each callback must be a function');
26-
}
24+
invariant(isFunction(callback), 'each callback must be a function');
2725

2826
isolate({ type: IsolateTypes.EACH }, () => {
2927
list.forEach((arg, index) => {
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import invariant from 'invariant';
12
import isFunction from 'isFunction';
23
import { isStringValue } from 'isStringValue';
3-
import throwError from 'throwError';
44

55
import { IsolateTypes } from 'IsolateTypes';
66
import context from 'ctx';
@@ -16,20 +16,16 @@ import { isolate } from 'isolate';
1616
* });
1717
*/
1818
export default function group(groupName: string, tests: () => void): void {
19-
if (!isStringValue(groupName)) {
20-
throwGroupError('name must be a string');
21-
}
19+
invariant(isStringValue(groupName), groupErrorMsg('name must be a string'));
2220

23-
if (!isFunction(tests)) {
24-
throwGroupError('callback must be a function');
25-
}
21+
invariant(isFunction(tests), groupErrorMsg('callback must be a function'));
2622

2723
// Running with the context applied
2824
isolate({ type: IsolateTypes.GROUP }, () => {
2925
context.run({ groupName }, tests);
3026
});
3127
}
3228

33-
function throwGroupError(error: string) {
34-
throwError(`Wrong arguments passed to group. Group ${error}.`);
29+
function groupErrorMsg(error: string) {
30+
return `Wrong arguments passed to group. Group ${error}.`;
3531
}

packages/vest/src/core/suite/create.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import assign from 'assign';
22
import genId from 'genId';
3+
import invariant from 'invariant';
34
import isFunction from 'isFunction';
4-
import throwError from 'throwError';
55
import { createState } from 'vast';
66

77
import { IsolateTypes } from 'IsolateTypes';
@@ -47,9 +47,10 @@ function create<T extends CB>(
4747
): SuiteReturnType<T> {
4848
const [suiteCallback, suiteName] = args.reverse() as [T, string];
4949

50-
if (!isFunction(suiteCallback)) {
51-
throwError('vest.create: Expected callback to be a function.');
52-
}
50+
invariant(
51+
isFunction(suiteCallback),
52+
'vest.create: Expected callback to be a function.'
53+
);
5354

5455
// Event bus initialization
5556
const bus = initBus();

packages/vest/src/core/suite/produce/getFailures/getFailuresByGroup.ts

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import throwError from 'throwError';
1+
import invariant from 'invariant';
22

33
import { Severity } from 'Severity';
44
import collectFailureMessages from 'collectFailureMessages';
@@ -41,13 +41,12 @@ function getByGroup(
4141
group: string,
4242
fieldName?: string
4343
): Record<string, string[]> {
44-
if (!group) {
45-
throwError(
46-
`get${severityKey[0].toUpperCase()}${severityKey.slice(
47-
1
48-
)}ByGroup requires a group name. Received \`${group}\` instead.`
49-
);
50-
}
44+
invariant(
45+
group,
46+
`get${severityKey[0].toUpperCase()}${severityKey.slice(
47+
1
48+
)}ByGroup requires a group name. Received \`${group}\` instead.`
49+
);
5150
const testObjects = useTestsFlat();
5251
return collectFailureMessages(severityKey, testObjects, {
5352
group,

packages/vest/src/core/test/__tests__/key.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ describe('key', () => {
147147
});
148148

149149
describe('When the same key is encountered twice', () => {
150-
let throwErrorDeferred, vest;
150+
let deferThrow, vest;
151151
beforeEach(() => {
152152
const mock = mockThrowError();
153153

154-
throwErrorDeferred = mock.throwErrorDeferred;
154+
deferThrow = mock.deferThrow;
155155
vest = mock.vest;
156156
});
157157

@@ -166,7 +166,7 @@ describe('key', () => {
166166
vest.test('field2', () => false, 'key_1');
167167
});
168168
suite();
169-
expect(throwErrorDeferred).toHaveBeenCalledWith(
169+
expect(deferThrow).toHaveBeenCalledWith(
170170
`Encountered the same test key "key_1" twice. This may lead to tests overriding each other's results, or to tests being unexpectedly omitted.`
171171
);
172172
});

0 commit comments

Comments
 (0)