vest 5.0.0-dev-781e21 → 5.0.2-dev-d315d9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +2 -2
- package/README.md +2 -57
- package/dist/cjs/classnames.development.js +18 -16
- package/dist/cjs/classnames.production.js +1 -1
- package/dist/cjs/enforce/compose.development.js +5 -54
- package/dist/cjs/enforce/compose.production.js +1 -1
- package/dist/cjs/enforce/compounds.development.js +20 -83
- package/dist/cjs/enforce/compounds.production.js +1 -1
- package/dist/cjs/enforce/schema.development.js +19 -82
- package/dist/cjs/enforce/schema.production.js +1 -1
- package/dist/cjs/parser.development.js +12 -9
- package/dist/cjs/parser.production.js +1 -1
- package/dist/cjs/promisify.development.js +4 -8
- package/dist/cjs/promisify.production.js +1 -1
- package/dist/cjs/vest.development.js +1287 -1153
- package/dist/cjs/vest.production.js +1 -1
- package/dist/es/classnames.development.js +20 -18
- package/dist/es/classnames.production.js +1 -1
- package/dist/es/enforce/compose.development.js +1 -58
- package/dist/es/enforce/compose.production.js +1 -1
- package/dist/es/enforce/compounds.development.js +2 -90
- package/dist/es/enforce/compounds.production.js +1 -1
- package/dist/es/enforce/schema.development.js +2 -88
- package/dist/es/enforce/schema.production.js +1 -1
- package/dist/es/parser.development.js +12 -9
- package/dist/es/parser.production.js +1 -1
- package/dist/es/promisify.development.js +5 -9
- package/dist/es/promisify.production.js +1 -1
- package/dist/es/vest.development.js +1286 -1148
- package/dist/es/vest.production.js +1 -1
- package/dist/umd/classnames.development.js +21 -19
- package/dist/umd/classnames.production.js +1 -1
- package/dist/umd/enforce/compose.development.js +9 -57
- package/dist/umd/enforce/compose.production.js +1 -1
- package/dist/umd/enforce/compounds.development.js +32 -94
- package/dist/umd/enforce/compounds.production.js +1 -1
- package/dist/umd/enforce/schema.development.js +32 -94
- package/dist/umd/enforce/schema.production.js +1 -1
- package/dist/umd/parser.development.js +16 -13
- package/dist/umd/parser.production.js +1 -1
- package/dist/umd/promisify.development.js +7 -11
- package/dist/umd/promisify.production.js +1 -1
- package/dist/umd/vest.development.js +1289 -1155
- package/dist/umd/vest.production.js +1 -1
- package/package.json +12 -16
- package/src/__tests__/__snapshots__/integration.async-tests.test.ts.snap +71 -0
- package/src/__tests__/__snapshots__/integration.base.test.ts.snap +71 -0
- package/src/__tests__/__snapshots__/integration.stateful-async.test.ts.snap +243 -0
- package/src/__tests__/__snapshots__/integration.stateful-tests.test.ts.snap +376 -0
- package/src/__tests__/integration.async-tests.test.ts +90 -0
- package/src/__tests__/integration.base.test.ts +45 -0
- package/src/__tests__/integration.exclusive.test.ts +88 -0
- package/src/__tests__/integration.stateful-async.test.ts +137 -0
- package/src/__tests__/integration.stateful-tests.test.ts +155 -0
- package/src/__tests__/isolate.test.ts +288 -0
- package/src/__tests__/state_refill.test.ts +41 -0
- package/src/core/SuiteWalker/SuiteWalker.ts +64 -0
- package/src/core/SuiteWalker/__tests__/hasRemainingTests.test.ts +130 -0
- package/src/core/VestBus/VestBus.ts +78 -0
- package/src/core/context/PersistedContext.ts +243 -0
- package/src/core/context/SuiteContext.ts +74 -0
- package/src/core/isolate/IsolateTest/IsolateTest.ts +213 -0
- package/src/core/isolate/IsolateTest/IsolateTestReconciler.ts +156 -0
- package/src/core/isolate/IsolateTest/IsolateTestStateMachine.ts +69 -0
- package/src/core/isolate/IsolateTest/SimpleStateMachine.ts +43 -0
- package/src/core/isolate/IsolateTest/TestWalker.ts +77 -0
- package/src/core/isolate/IsolateTypes.ts +10 -0
- package/src/core/isolate/isIsolate.ts +6 -0
- package/src/core/isolate/isolate.ts +110 -0
- package/src/core/isolate/reconciler/Reconciler/Reconciler.ts +123 -0
- package/src/core/isolate/reconciler/cancelOverriddenPendingTest.ts +15 -0
- package/src/core/isolate/reconciler/isSameProfileTest.ts +12 -0
- package/src/core/isolate/walker.ts +127 -0
- package/src/core/test/TestTypes.ts +3 -0
- package/src/core/test/__tests__/IsolateTest.test.ts +152 -0
- package/src/core/test/__tests__/__snapshots__/IsolateTest.test.ts.snap +39 -0
- package/src/core/test/__tests__/__snapshots__/memo.test.ts.snap +101 -0
- package/src/core/test/__tests__/__snapshots__/test.test.ts.snap +231 -0
- package/src/core/test/__tests__/key.test.ts +195 -0
- package/src/core/test/__tests__/memo.test.ts +218 -0
- package/src/core/test/__tests__/merging_of_previous_test_runs.test.ts +341 -0
- package/src/core/test/__tests__/runAsyncTest.test.ts +175 -0
- package/src/core/test/__tests__/test.test.ts +226 -0
- package/src/core/test/helpers/__tests__/nonMatchingSeverityProfile.test.ts +52 -0
- package/src/core/test/helpers/asVestTest.ts +9 -0
- package/src/core/test/helpers/matchingFieldName.ts +16 -0
- package/src/core/test/helpers/matchingGroupName.ts +12 -0
- package/src/core/test/helpers/nonMatchingSeverityProfile.ts +14 -0
- package/src/core/test/helpers/shouldUseErrorMessage.ts +9 -0
- package/src/core/test/test.memo.ts +81 -0
- package/src/core/test/test.ts +64 -0
- package/src/core/test/testLevelFlowControl/runTest.ts +86 -0
- package/src/core/test/testLevelFlowControl/verifyTestRun.ts +32 -0
- package/src/core/test/testObjectIsolate.ts +11 -0
- package/src/errors/ErrorStrings.ts +4 -0
- package/src/exports/__tests__/classnames.test.ts +92 -0
- package/src/exports/__tests__/parser.test.ts +441 -0
- package/src/exports/__tests__/promisify.test.ts +77 -0
- package/src/exports/classnames.ts +35 -0
- package/src/exports/enforce@compose.ts +1 -0
- package/src/exports/enforce@compounds.ts +1 -0
- package/src/exports/enforce@schema.ts +1 -0
- package/src/exports/parser.ts +63 -0
- package/src/exports/promisify.ts +18 -0
- package/src/hooks/__tests__/__snapshots__/include.test.ts.snap +794 -0
- package/src/hooks/__tests__/eager.test.ts +130 -0
- package/src/hooks/__tests__/exclusive.test.ts +578 -0
- package/src/hooks/__tests__/include.test.ts +431 -0
- package/src/hooks/__tests__/optional.test.ts +83 -0
- package/src/hooks/__tests__/warn.test.ts +42 -0
- package/src/hooks/exclusive.ts +179 -0
- package/src/hooks/include.ts +54 -0
- package/src/hooks/mode.ts +47 -0
- package/src/hooks/optional/OptionalTypes.ts +31 -0
- package/src/hooks/optional/optional.ts +69 -0
- package/src/hooks/warn.ts +19 -0
- package/src/isolates/__tests__/__snapshots__/each.test.ts.snap +3 -0
- package/src/isolates/__tests__/__snapshots__/group.test.ts.snap +114 -0
- package/src/isolates/__tests__/__snapshots__/omitWhen.test.ts.snap +443 -0
- package/src/isolates/__tests__/__snapshots__/skipWhen.test.ts.snap +99 -0
- package/src/isolates/__tests__/each.test.ts +35 -0
- package/src/isolates/__tests__/group.test.ts +362 -0
- package/src/isolates/__tests__/omitWhen.test.ts +246 -0
- package/src/isolates/__tests__/skipWhen.test.ts +163 -0
- package/src/isolates/each.ts +30 -0
- package/src/isolates/group.ts +9 -0
- package/src/isolates/omitWhen.ts +41 -0
- package/src/isolates/skipWhen.ts +42 -0
- package/src/suite/__tests__/__snapshots__/create.test.ts.snap +67 -0
- package/src/suite/__tests__/create.test.ts +109 -0
- package/src/suite/__tests__/remove.test.ts +50 -0
- package/src/suite/__tests__/resetField.test.ts +74 -0
- package/src/suite/createSuite.ts +94 -0
- package/src/suite/runCallbacks.ts +28 -0
- package/src/suiteResult/Severity.ts +15 -0
- package/src/suiteResult/SuiteResultTypes.ts +42 -0
- package/src/suiteResult/__tests__/done.test.ts +334 -0
- package/src/suiteResult/__tests__/produce.test.ts +163 -0
- package/src/suiteResult/done/deferDoneCallback.ts +28 -0
- package/src/suiteResult/done/shouldSkipDoneRegistration.ts +20 -0
- package/src/suiteResult/selectors/__tests__/__snapshots__/collectFailureMessages.test.ts.snap +89 -0
- package/src/suiteResult/selectors/__tests__/collectFailureMessages.test.ts +124 -0
- package/src/suiteResult/selectors/__tests__/getFailures.test.ts +158 -0
- package/src/suiteResult/selectors/__tests__/getFailuresByGroup.test.ts +199 -0
- package/src/suiteResult/selectors/__tests__/hasFailures.test.ts +141 -0
- package/src/suiteResult/selectors/__tests__/hasFailuresByGroup.test.ts +185 -0
- package/src/suiteResult/selectors/__tests__/hasFailuresByTestObject.test.ts +88 -0
- package/src/suiteResult/selectors/__tests__/isValid.test.ts +359 -0
- package/src/suiteResult/selectors/__tests__/isValidByGroup.test.ts +480 -0
- package/src/suiteResult/selectors/collectFailures.ts +43 -0
- package/src/suiteResult/selectors/hasFailuresByTestObjects.ts +62 -0
- package/src/suiteResult/selectors/produceSuiteSummary.ts +135 -0
- package/src/suiteResult/selectors/shouldAddValidProperty.ts +148 -0
- package/src/suiteResult/selectors/suiteSelectors.ts +199 -0
- package/src/suiteResult/suiteResult.ts +15 -0
- package/src/suiteResult/suiteRunResult.ts +43 -0
- package/src/vest.ts +36 -0
- package/testUtils/TVestMock.ts +5 -0
- package/testUtils/__tests__/partition.test.ts +4 -4
- package/testUtils/mockThrowError.ts +4 -2
- package/testUtils/suiteDummy.ts +2 -1
- package/testUtils/testDummy.ts +12 -10
- package/testUtils/testPromise.ts +3 -0
- package/tsconfig.json +84 -2
- package/types/classnames.d.ts +39 -4
- package/types/classnames.d.ts.map +1 -0
- package/types/enforce/compose.d.ts +2 -126
- package/types/enforce/compose.d.ts.map +1 -0
- package/types/enforce/compounds.d.ts +2 -136
- package/types/enforce/compounds.d.ts.map +1 -0
- package/types/enforce/schema.d.ts +2 -144
- package/types/enforce/schema.d.ts.map +1 -0
- package/types/parser.d.ts +45 -10
- package/types/parser.d.ts.map +1 -0
- package/types/promisify.d.ts +36 -34
- package/types/promisify.d.ts.map +1 -0
- package/types/vest.d.ts +169 -224
- package/types/vest.d.ts.map +1 -0
- package/CHANGELOG.md +0 -87
- package/testUtils/expandStateRef.ts +0 -8
- package/testUtils/runCreateRef.ts +0 -10
- package/testUtils/testObjects.ts +0 -6
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { faker } from '@faker-js/faker';
|
|
2
|
+
|
|
3
|
+
import { TestPromise } from '../../../../testUtils/testPromise';
|
|
4
|
+
|
|
5
|
+
import { create, test, warn, enforce, IsolateTest } from 'vest';
|
|
6
|
+
|
|
7
|
+
let testObject: IsolateTest;
|
|
8
|
+
|
|
9
|
+
describe("Test Vest's `test` function", () => {
|
|
10
|
+
describe('test callbacks', () => {
|
|
11
|
+
describe('Warn hook', () => {
|
|
12
|
+
it('Should be marked as warning when the warn hook gets called', () => {
|
|
13
|
+
create(() => {
|
|
14
|
+
testObject = test(faker.random.word(), faker.lorem.sentence(), () => {
|
|
15
|
+
warn();
|
|
16
|
+
});
|
|
17
|
+
})();
|
|
18
|
+
expect(testObject.warns()).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe('Sync', () => {
|
|
23
|
+
it('Should be marked as failed after a thrown error', () => {
|
|
24
|
+
create(() => {
|
|
25
|
+
testObject = test(faker.random.word(), faker.lorem.sentence(), () => {
|
|
26
|
+
throw new Error();
|
|
27
|
+
});
|
|
28
|
+
})();
|
|
29
|
+
expect(testObject.isFailing()).toBe(true);
|
|
30
|
+
// @ts-ignore - very much intentional
|
|
31
|
+
expect(testObject == false).toBe(true); //eslint-disable-line
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('Should be marked as failed for an explicit false return', () => {
|
|
35
|
+
create(() => {
|
|
36
|
+
test(faker.random.word(), faker.lorem.sentence(), () => false);
|
|
37
|
+
})();
|
|
38
|
+
expect(testObject.isFailing()).toBe(true);
|
|
39
|
+
// @ts-ignore - very much intentional
|
|
40
|
+
expect(testObject == false).toBe(true); //eslint-disable-line
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe('Thrown with a message', () => {
|
|
44
|
+
describe('When field has a message', () => {
|
|
45
|
+
it("Should use field's own message", () => {
|
|
46
|
+
const res = create(() => {
|
|
47
|
+
test('field_with_message', 'some_field_message', () => {
|
|
48
|
+
failWithString();
|
|
49
|
+
});
|
|
50
|
+
test('warning_field_with_message', 'some_field_message', () => {
|
|
51
|
+
warn();
|
|
52
|
+
failWithString();
|
|
53
|
+
});
|
|
54
|
+
})();
|
|
55
|
+
|
|
56
|
+
expect(res.getErrors('field_with_message')).toEqual([
|
|
57
|
+
'some_field_message',
|
|
58
|
+
]);
|
|
59
|
+
expect(res.tests['field_with_message'].errors).toEqual([
|
|
60
|
+
'some_field_message',
|
|
61
|
+
]);
|
|
62
|
+
expect(res.getWarnings('warning_field_with_message')).toEqual([
|
|
63
|
+
'some_field_message',
|
|
64
|
+
]);
|
|
65
|
+
expect(res.tests['warning_field_with_message'].warnings).toEqual([
|
|
66
|
+
'some_field_message',
|
|
67
|
+
]);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
describe('When field does not have a message', () => {
|
|
71
|
+
it('Should use message from enforce().message()', () => {
|
|
72
|
+
const res = create(() => {
|
|
73
|
+
test('field_without_message', () => {
|
|
74
|
+
enforce(100).message('some_field_message').equals(0);
|
|
75
|
+
});
|
|
76
|
+
})();
|
|
77
|
+
|
|
78
|
+
expect(res.getErrors('field_without_message')).toEqual([
|
|
79
|
+
'some_field_message',
|
|
80
|
+
]);
|
|
81
|
+
});
|
|
82
|
+
it('Should use message from thrown error', () => {
|
|
83
|
+
const res = create(() => {
|
|
84
|
+
test('field_without_message', () => {
|
|
85
|
+
failWithString();
|
|
86
|
+
});
|
|
87
|
+
test('warning_field_without_message', () => {
|
|
88
|
+
warn();
|
|
89
|
+
failWithString();
|
|
90
|
+
});
|
|
91
|
+
})();
|
|
92
|
+
|
|
93
|
+
expect(res.getErrors('field_without_message')).toEqual([
|
|
94
|
+
'I fail with a message',
|
|
95
|
+
]);
|
|
96
|
+
expect(res.tests['field_without_message'].errors).toEqual([
|
|
97
|
+
'I fail with a message',
|
|
98
|
+
]);
|
|
99
|
+
expect(res.getWarnings('warning_field_without_message')).toEqual([
|
|
100
|
+
'I fail with a message',
|
|
101
|
+
]);
|
|
102
|
+
expect(res.tests['warning_field_without_message'].warnings).toEqual(
|
|
103
|
+
['I fail with a message']
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
describe('async', () => {
|
|
111
|
+
it('Should be marked as failed when a returned promise rejects', () =>
|
|
112
|
+
TestPromise(done => {
|
|
113
|
+
create(() => {
|
|
114
|
+
testObject = test(
|
|
115
|
+
faker.random.word(),
|
|
116
|
+
faker.lorem.sentence(),
|
|
117
|
+
() =>
|
|
118
|
+
new Promise((_, reject) => {
|
|
119
|
+
expect(testObject.isFailing()).toBe(false);
|
|
120
|
+
setTimeout(reject, 300);
|
|
121
|
+
})
|
|
122
|
+
);
|
|
123
|
+
expect(testObject.isFailing()).toBe(false);
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
expect(testObject.isFailing()).toBe(true);
|
|
126
|
+
done();
|
|
127
|
+
}, 310);
|
|
128
|
+
})();
|
|
129
|
+
}));
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe('test params', () => {
|
|
134
|
+
let testObject: IsolateTest;
|
|
135
|
+
it('creates a test without a message and without a key', () => {
|
|
136
|
+
create(() => {
|
|
137
|
+
testObject = test('field_name', () => undefined);
|
|
138
|
+
})();
|
|
139
|
+
expect(testObject.fieldName).toBe('field_name');
|
|
140
|
+
expect(testObject.key).toBeNull();
|
|
141
|
+
expect(testObject.message).toBeUndefined();
|
|
142
|
+
expect(testObject).toMatchSnapshot();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('creates a test without a key', () => {
|
|
146
|
+
create(() => {
|
|
147
|
+
testObject = test('field_name', 'failure message', () => undefined);
|
|
148
|
+
})();
|
|
149
|
+
expect(testObject.fieldName).toBe('field_name');
|
|
150
|
+
expect(testObject.key).toBeNull();
|
|
151
|
+
expect(testObject.message).toBe('failure message');
|
|
152
|
+
expect(testObject).toMatchSnapshot();
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('creates a test without a message and with a key', () => {
|
|
156
|
+
create(() => {
|
|
157
|
+
testObject = test('field_name', () => undefined, 'keyboardcat');
|
|
158
|
+
})();
|
|
159
|
+
expect(testObject.fieldName).toBe('field_name');
|
|
160
|
+
expect(testObject.key).toBe('keyboardcat');
|
|
161
|
+
expect(testObject.message).toBeUndefined();
|
|
162
|
+
expect(testObject).toMatchSnapshot();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('creates a test with a message and with a key', () => {
|
|
166
|
+
create(() => {
|
|
167
|
+
testObject = test(
|
|
168
|
+
'field_name',
|
|
169
|
+
'failure message',
|
|
170
|
+
() => undefined,
|
|
171
|
+
'keyboardcat'
|
|
172
|
+
);
|
|
173
|
+
})();
|
|
174
|
+
expect(testObject.fieldName).toBe('field_name');
|
|
175
|
+
expect(testObject.key).toBe('keyboardcat');
|
|
176
|
+
expect(testObject.message).toBe('failure message');
|
|
177
|
+
expect(testObject).toMatchSnapshot();
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('throws when field name is not a string', () => {
|
|
181
|
+
const control = jest.fn();
|
|
182
|
+
create(() => {
|
|
183
|
+
// @ts-ignore
|
|
184
|
+
expect(() => test(undefined, () => undefined)).toThrow(
|
|
185
|
+
'Incompatible params passed to test function. Test fieldName must be a string'
|
|
186
|
+
);
|
|
187
|
+
// @ts-expect-error
|
|
188
|
+
expect(() => test(null, 'error message', () => undefined)).toThrow(
|
|
189
|
+
'Incompatible params passed to test function. Test fieldName must be a string'
|
|
190
|
+
);
|
|
191
|
+
expect(() =>
|
|
192
|
+
// @ts-expect-error
|
|
193
|
+
test(null, 'error message', () => undefined, 'key')
|
|
194
|
+
).toThrow(
|
|
195
|
+
'Incompatible params passed to test function. Test fieldName must be a string'
|
|
196
|
+
);
|
|
197
|
+
control();
|
|
198
|
+
})();
|
|
199
|
+
expect(control).toHaveBeenCalled();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('throws when callback is not a function', () => {
|
|
203
|
+
const control = jest.fn();
|
|
204
|
+
create(() => {
|
|
205
|
+
// @ts-expect-error
|
|
206
|
+
expect(() => test('x')).toThrow(
|
|
207
|
+
'Incompatible params passed to test function. Test callback must be a function'
|
|
208
|
+
);
|
|
209
|
+
// @ts-expect-error
|
|
210
|
+
expect(() => test('x', 'msg', undefined)).toThrow(
|
|
211
|
+
'Incompatible params passed to test function. Test callback must be a function'
|
|
212
|
+
);
|
|
213
|
+
// @ts-expect-error
|
|
214
|
+
expect(() => test('x', 'msg', undefined, 'key')).toThrow(
|
|
215
|
+
'Incompatible params passed to test function. Test callback must be a function'
|
|
216
|
+
);
|
|
217
|
+
control();
|
|
218
|
+
})();
|
|
219
|
+
expect(control).toHaveBeenCalled();
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
function failWithString(msg?: string) {
|
|
225
|
+
throw msg ?? 'I fail with a message';
|
|
226
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { IsolateTest } from 'IsolateTest';
|
|
2
|
+
import { IsolateTypes } from 'IsolateTypes';
|
|
3
|
+
import { Severity } from 'Severity';
|
|
4
|
+
import { nonMatchingSeverityProfile } from 'nonMatchingSeverityProfile';
|
|
5
|
+
|
|
6
|
+
describe('nonMatchingSeverityProfile', () => {
|
|
7
|
+
let testObject: IsolateTest;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
testObject = new IsolateTest(IsolateTypes.TEST, {
|
|
11
|
+
fieldName: 'field',
|
|
12
|
+
testFn: jest.fn(),
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
describe('When matching', () => {
|
|
16
|
+
describe('When both are warning', () => {
|
|
17
|
+
it('should return false', () => {
|
|
18
|
+
testObject.warn();
|
|
19
|
+
expect(nonMatchingSeverityProfile(Severity.WARNINGS, testObject)).toBe(
|
|
20
|
+
false
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('When both are not warning', () => {
|
|
26
|
+
it('should return false', () => {
|
|
27
|
+
expect(nonMatchingSeverityProfile(Severity.ERRORS, testObject)).toBe(
|
|
28
|
+
false
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('When non matching', () => {
|
|
35
|
+
describe('When test is warning', () => {
|
|
36
|
+
it('should return true', () => {
|
|
37
|
+
testObject.warn();
|
|
38
|
+
expect(nonMatchingSeverityProfile(Severity.ERRORS, testObject)).toBe(
|
|
39
|
+
true
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe('When severity is warning', () => {
|
|
45
|
+
it('should return true', () => {
|
|
46
|
+
expect(nonMatchingSeverityProfile(Severity.WARNINGS, testObject)).toBe(
|
|
47
|
+
true
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { invariant } from 'vest-utils';
|
|
2
|
+
|
|
3
|
+
import { ErrorStrings } from 'ErrorStrings';
|
|
4
|
+
import { IsolateTest } from 'IsolateTest';
|
|
5
|
+
|
|
6
|
+
export function asVestTest(value: any): IsolateTest {
|
|
7
|
+
invariant(value instanceof IsolateTest, ErrorStrings.EXPECTED_VEST_TEST);
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IsolateTest } from 'IsolateTest';
|
|
2
|
+
import { TFieldName } from 'SuiteResultTypes';
|
|
3
|
+
|
|
4
|
+
export function nonMatchingFieldName(
|
|
5
|
+
testObject: IsolateTest,
|
|
6
|
+
fieldName?: TFieldName | void
|
|
7
|
+
): boolean {
|
|
8
|
+
return !!fieldName && !matchingFieldName(testObject, fieldName);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default function matchingFieldName(
|
|
12
|
+
testObject: IsolateTest,
|
|
13
|
+
fieldName?: TFieldName | void
|
|
14
|
+
): boolean {
|
|
15
|
+
return !!(fieldName && testObject.fieldName === fieldName);
|
|
16
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { bindNot } from 'vest-utils';
|
|
2
|
+
|
|
3
|
+
import { IsolateTest } from 'IsolateTest';
|
|
4
|
+
|
|
5
|
+
export const nonMatchingGroupName = bindNot(matchingGroupName);
|
|
6
|
+
|
|
7
|
+
export function matchingGroupName(
|
|
8
|
+
testObject: IsolateTest,
|
|
9
|
+
groupName: string | void
|
|
10
|
+
): boolean {
|
|
11
|
+
return testObject.groupName === groupName;
|
|
12
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { either } from 'vest-utils';
|
|
2
|
+
|
|
3
|
+
import { IsolateTest } from 'IsolateTest';
|
|
4
|
+
import { Severity } from 'Severity';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Checks that a given test object matches the currently specified severity level
|
|
8
|
+
*/
|
|
9
|
+
export function nonMatchingSeverityProfile(
|
|
10
|
+
severity: Severity,
|
|
11
|
+
testObject: IsolateTest
|
|
12
|
+
): boolean {
|
|
13
|
+
return either(severity === Severity.WARNINGS, testObject.warns());
|
|
14
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { isStringValue, isUndefined } from 'vest-utils';
|
|
2
|
+
|
|
3
|
+
export function shouldUseErrorAsMessage(
|
|
4
|
+
message: string | void,
|
|
5
|
+
error: unknown
|
|
6
|
+
): error is string {
|
|
7
|
+
// kind of cheating with this safe guard, but it does the job
|
|
8
|
+
return isUndefined(message) && isStringValue(error);
|
|
9
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { isNull } from 'vest-utils';
|
|
2
|
+
|
|
3
|
+
import { IsolateTest } from 'IsolateTest';
|
|
4
|
+
import { useCurrentCursor, useSuiteId } from 'PersistedContext';
|
|
5
|
+
import { useTestMemoCache } from 'SuiteContext';
|
|
6
|
+
import { TFieldName } from 'SuiteResultTypes';
|
|
7
|
+
import { TestFn } from 'TestTypes';
|
|
8
|
+
import { VTest } from 'test';
|
|
9
|
+
|
|
10
|
+
export function wrapTestMemo(test: VTest): TestMemo<TFieldName> {
|
|
11
|
+
/**
|
|
12
|
+
* Caches a test result based on the test's dependencies.
|
|
13
|
+
*/
|
|
14
|
+
function memo<F extends TFieldName>(
|
|
15
|
+
fieldName: F,
|
|
16
|
+
...args: ParametersWithoutMessage
|
|
17
|
+
): IsolateTest;
|
|
18
|
+
function memo<F extends TFieldName>(
|
|
19
|
+
fieldName: F,
|
|
20
|
+
...args: ParametersWithMessage
|
|
21
|
+
): IsolateTest;
|
|
22
|
+
function memo<F extends TFieldName>(
|
|
23
|
+
fieldName: F,
|
|
24
|
+
...args: ParamsOverload
|
|
25
|
+
): IsolateTest {
|
|
26
|
+
const [deps, testFn, msg] = args.reverse() as [any[], TestFn, string];
|
|
27
|
+
|
|
28
|
+
// Implicit dependency for better specificity
|
|
29
|
+
const dependencies = [useSuiteId(), fieldName, useCurrentCursor()].concat(
|
|
30
|
+
deps
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
return getTestFromCache(dependencies, cacheAction);
|
|
34
|
+
|
|
35
|
+
function cacheAction() {
|
|
36
|
+
return test(fieldName, msg, testFn);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return memo;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getTestFromCache(
|
|
44
|
+
dependencies: any[],
|
|
45
|
+
cacheAction: () => IsolateTest
|
|
46
|
+
): IsolateTest {
|
|
47
|
+
const cache = useTestMemoCache();
|
|
48
|
+
|
|
49
|
+
const cached = cache.get(dependencies);
|
|
50
|
+
|
|
51
|
+
if (isNull(cached)) {
|
|
52
|
+
// cache miss
|
|
53
|
+
return cache(dependencies, cacheAction);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const [, cachedValue] = cached;
|
|
57
|
+
|
|
58
|
+
if (cachedValue.isCanceled()) {
|
|
59
|
+
// cache hit, but test is canceled
|
|
60
|
+
cache.invalidate(dependencies);
|
|
61
|
+
return cache(dependencies, cacheAction);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
IsolateTest.setNode(cachedValue);
|
|
65
|
+
|
|
66
|
+
return cachedValue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
type TestMemo<F extends TFieldName> = {
|
|
70
|
+
(fieldName: F, ...args: ParametersWithoutMessage): IsolateTest;
|
|
71
|
+
(fieldName: F, ...args: ParametersWithMessage): IsolateTest;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
type ParametersWithoutMessage = [test: TestFn, dependencies: unknown[]];
|
|
75
|
+
type ParametersWithMessage = [
|
|
76
|
+
message: string,
|
|
77
|
+
test: TestFn,
|
|
78
|
+
dependencies: unknown[]
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
type ParamsOverload = ParametersWithoutMessage | ParametersWithMessage;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { assign, invariant, isFunction, isStringValue } from 'vest-utils';
|
|
2
|
+
|
|
3
|
+
import { IsolateTest } from 'IsolateTest';
|
|
4
|
+
import { useEmit } from 'PersistedContext';
|
|
5
|
+
import { useGroupName } from 'SuiteContext';
|
|
6
|
+
import { TFieldName } from 'SuiteResultTypes';
|
|
7
|
+
import { TestFn } from 'TestTypes';
|
|
8
|
+
import { Events } from 'VestBus';
|
|
9
|
+
import { IsolateKey } from 'isolate';
|
|
10
|
+
import { wrapTestMemo } from 'test.memo';
|
|
11
|
+
import { testObjectIsolate } from 'testObjectIsolate';
|
|
12
|
+
|
|
13
|
+
function vestTest<F extends TFieldName>(
|
|
14
|
+
fieldName: F,
|
|
15
|
+
message: string,
|
|
16
|
+
cb: TestFn
|
|
17
|
+
): IsolateTest;
|
|
18
|
+
function vestTest<F extends TFieldName>(fieldName: F, cb: TestFn): IsolateTest;
|
|
19
|
+
function vestTest<F extends TFieldName>(
|
|
20
|
+
fieldName: F,
|
|
21
|
+
message: string,
|
|
22
|
+
cb: TestFn,
|
|
23
|
+
key: IsolateKey
|
|
24
|
+
): IsolateTest;
|
|
25
|
+
function vestTest<F extends TFieldName>(
|
|
26
|
+
fieldName: F,
|
|
27
|
+
cb: TestFn,
|
|
28
|
+
key: IsolateKey
|
|
29
|
+
): IsolateTest;
|
|
30
|
+
function vestTest<F extends TFieldName>(
|
|
31
|
+
fieldName: F,
|
|
32
|
+
...args:
|
|
33
|
+
| [message: string, cb: TestFn]
|
|
34
|
+
| [cb: TestFn]
|
|
35
|
+
| [message: string, cb: TestFn, key: IsolateKey]
|
|
36
|
+
| [cb: TestFn, key: IsolateKey]
|
|
37
|
+
): IsolateTest {
|
|
38
|
+
const [message, testFn, key] = (
|
|
39
|
+
isFunction(args[1]) ? args : [undefined, ...args]
|
|
40
|
+
) as [string | undefined, TestFn, IsolateKey];
|
|
41
|
+
|
|
42
|
+
invariant(isStringValue(fieldName), invalidParamError('fieldName', 'string'));
|
|
43
|
+
invariant(isFunction(testFn), invalidParamError('callback', 'function'));
|
|
44
|
+
|
|
45
|
+
const groupName = useGroupName();
|
|
46
|
+
const emit = useEmit();
|
|
47
|
+
|
|
48
|
+
const testObjectInput = { fieldName, groupName, key, message, testFn };
|
|
49
|
+
|
|
50
|
+
// This invalidates the suite cache.
|
|
51
|
+
emit(Events.TEST_RUN_STARTED);
|
|
52
|
+
|
|
53
|
+
return testObjectIsolate(testObjectInput);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const test = assign(vestTest, {
|
|
57
|
+
memo: wrapTestMemo(vestTest),
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export type VTest = typeof vestTest;
|
|
61
|
+
|
|
62
|
+
function invalidParamError(name: string, expected: string): string {
|
|
63
|
+
return `Incompatible params passed to test function. Test ${name} must be a ${expected}`;
|
|
64
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { isPromise, isStringValue } from 'vest-utils';
|
|
2
|
+
|
|
3
|
+
import { IsolateTest } from 'IsolateTest';
|
|
4
|
+
import { persist, useVestBus } from 'PersistedContext';
|
|
5
|
+
import { SuiteContext } from 'SuiteContext';
|
|
6
|
+
import { TestResult } from 'TestTypes';
|
|
7
|
+
import { Events } from 'VestBus';
|
|
8
|
+
import { verifyTestRun } from 'verifyTestRun';
|
|
9
|
+
|
|
10
|
+
export function attemptRunTestObjectByTier(testObject: IsolateTest) {
|
|
11
|
+
verifyTestRun(testObject);
|
|
12
|
+
|
|
13
|
+
if (testObject.isNonActionable()) {
|
|
14
|
+
// TODO: Need to test that this works as expected
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (testObject.isUntested()) {
|
|
19
|
+
runTest(testObject);
|
|
20
|
+
} else if (testObject.isAsyncTest()) {
|
|
21
|
+
testObject.setPending();
|
|
22
|
+
runAsyncTest(testObject);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function runSyncTest(testObject: IsolateTest): TestResult {
|
|
27
|
+
return SuiteContext.run({ currentTest: testObject }, () => testObject.run());
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* runs test, if async - adds to pending array
|
|
32
|
+
*/
|
|
33
|
+
function runTest(testObject: IsolateTest): void {
|
|
34
|
+
const VestBus = useVestBus();
|
|
35
|
+
|
|
36
|
+
// Run test callback.
|
|
37
|
+
// If a promise is returned, set as async and
|
|
38
|
+
// Move to pending list.
|
|
39
|
+
const result = runSyncTest(testObject);
|
|
40
|
+
try {
|
|
41
|
+
// try catch for safe property access
|
|
42
|
+
// in case object is an enforce chain
|
|
43
|
+
if (isPromise(result)) {
|
|
44
|
+
testObject.asyncTest = result;
|
|
45
|
+
testObject.setPending();
|
|
46
|
+
runAsyncTest(testObject);
|
|
47
|
+
} else {
|
|
48
|
+
VestBus.emit(Events.TEST_COMPLETED, testObject);
|
|
49
|
+
}
|
|
50
|
+
} catch (e) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`Unexpected error encountered during test registration.
|
|
53
|
+
Test Object: ${JSON.stringify(testObject)}.
|
|
54
|
+
Error: ${e}.`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Runs async test.
|
|
61
|
+
*/
|
|
62
|
+
function runAsyncTest(testObject: IsolateTest): void {
|
|
63
|
+
const { asyncTest, message } = testObject;
|
|
64
|
+
|
|
65
|
+
if (!isPromise(asyncTest)) return;
|
|
66
|
+
|
|
67
|
+
const VestBus = useVestBus();
|
|
68
|
+
|
|
69
|
+
const done = persist(() => {
|
|
70
|
+
VestBus.emit(Events.TEST_COMPLETED, testObject);
|
|
71
|
+
});
|
|
72
|
+
const fail = persist((rejectionMessage?: string) => {
|
|
73
|
+
if (testObject.isCanceled()) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
testObject.message = isStringValue(rejectionMessage)
|
|
78
|
+
? rejectionMessage
|
|
79
|
+
: message;
|
|
80
|
+
testObject.fail();
|
|
81
|
+
|
|
82
|
+
done();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
asyncTest.then(done, fail);
|
|
86
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { isOptionalFiedApplied } from 'optional';
|
|
2
|
+
|
|
3
|
+
import { IsolateTest } from 'IsolateTest';
|
|
4
|
+
import { isExcluded } from 'exclusive';
|
|
5
|
+
import { shouldSkipBasedOnMode } from 'mode';
|
|
6
|
+
import { withinActiveOmitWhen } from 'omitWhen';
|
|
7
|
+
import { isExcludedIndividually } from 'skipWhen';
|
|
8
|
+
|
|
9
|
+
export function verifyTestRun(testObject: IsolateTest): IsolateTest {
|
|
10
|
+
if (shouldSkipBasedOnMode(testObject)) {
|
|
11
|
+
testObject.skip();
|
|
12
|
+
|
|
13
|
+
return testObject;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (withinActiveOmitWhen() || isOptionalFiedApplied(testObject.fieldName)) {
|
|
17
|
+
testObject.omit();
|
|
18
|
+
|
|
19
|
+
return testObject;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (isExcluded(testObject)) {
|
|
23
|
+
// We're forcing skipping the pending test
|
|
24
|
+
// if we're directly within a skipWhen block
|
|
25
|
+
// This mostly means that we're probably giving
|
|
26
|
+
// up on this async test intentionally.
|
|
27
|
+
testObject.skip(isExcludedIndividually());
|
|
28
|
+
return testObject;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return testObject;
|
|
32
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IsolateTest, IsolateTestInput } from 'IsolateTest';
|
|
2
|
+
import { attemptRunTestObjectByTier } from 'runTest';
|
|
3
|
+
|
|
4
|
+
export function testObjectIsolate(
|
|
5
|
+
testObjectInput: IsolateTestInput
|
|
6
|
+
): IsolateTest {
|
|
7
|
+
return IsolateTest.factory(
|
|
8
|
+
(testObject: IsolateTest) => attemptRunTestObjectByTier(testObject),
|
|
9
|
+
testObjectInput
|
|
10
|
+
);
|
|
11
|
+
}
|