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.
Files changed (182) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +2 -57
  3. package/dist/cjs/classnames.development.js +18 -16
  4. package/dist/cjs/classnames.production.js +1 -1
  5. package/dist/cjs/enforce/compose.development.js +5 -54
  6. package/dist/cjs/enforce/compose.production.js +1 -1
  7. package/dist/cjs/enforce/compounds.development.js +20 -83
  8. package/dist/cjs/enforce/compounds.production.js +1 -1
  9. package/dist/cjs/enforce/schema.development.js +19 -82
  10. package/dist/cjs/enforce/schema.production.js +1 -1
  11. package/dist/cjs/parser.development.js +12 -9
  12. package/dist/cjs/parser.production.js +1 -1
  13. package/dist/cjs/promisify.development.js +4 -8
  14. package/dist/cjs/promisify.production.js +1 -1
  15. package/dist/cjs/vest.development.js +1287 -1153
  16. package/dist/cjs/vest.production.js +1 -1
  17. package/dist/es/classnames.development.js +20 -18
  18. package/dist/es/classnames.production.js +1 -1
  19. package/dist/es/enforce/compose.development.js +1 -58
  20. package/dist/es/enforce/compose.production.js +1 -1
  21. package/dist/es/enforce/compounds.development.js +2 -90
  22. package/dist/es/enforce/compounds.production.js +1 -1
  23. package/dist/es/enforce/schema.development.js +2 -88
  24. package/dist/es/enforce/schema.production.js +1 -1
  25. package/dist/es/parser.development.js +12 -9
  26. package/dist/es/parser.production.js +1 -1
  27. package/dist/es/promisify.development.js +5 -9
  28. package/dist/es/promisify.production.js +1 -1
  29. package/dist/es/vest.development.js +1286 -1148
  30. package/dist/es/vest.production.js +1 -1
  31. package/dist/umd/classnames.development.js +21 -19
  32. package/dist/umd/classnames.production.js +1 -1
  33. package/dist/umd/enforce/compose.development.js +9 -57
  34. package/dist/umd/enforce/compose.production.js +1 -1
  35. package/dist/umd/enforce/compounds.development.js +32 -94
  36. package/dist/umd/enforce/compounds.production.js +1 -1
  37. package/dist/umd/enforce/schema.development.js +32 -94
  38. package/dist/umd/enforce/schema.production.js +1 -1
  39. package/dist/umd/parser.development.js +16 -13
  40. package/dist/umd/parser.production.js +1 -1
  41. package/dist/umd/promisify.development.js +7 -11
  42. package/dist/umd/promisify.production.js +1 -1
  43. package/dist/umd/vest.development.js +1289 -1155
  44. package/dist/umd/vest.production.js +1 -1
  45. package/package.json +12 -16
  46. package/src/__tests__/__snapshots__/integration.async-tests.test.ts.snap +71 -0
  47. package/src/__tests__/__snapshots__/integration.base.test.ts.snap +71 -0
  48. package/src/__tests__/__snapshots__/integration.stateful-async.test.ts.snap +243 -0
  49. package/src/__tests__/__snapshots__/integration.stateful-tests.test.ts.snap +376 -0
  50. package/src/__tests__/integration.async-tests.test.ts +90 -0
  51. package/src/__tests__/integration.base.test.ts +45 -0
  52. package/src/__tests__/integration.exclusive.test.ts +88 -0
  53. package/src/__tests__/integration.stateful-async.test.ts +137 -0
  54. package/src/__tests__/integration.stateful-tests.test.ts +155 -0
  55. package/src/__tests__/isolate.test.ts +288 -0
  56. package/src/__tests__/state_refill.test.ts +41 -0
  57. package/src/core/SuiteWalker/SuiteWalker.ts +64 -0
  58. package/src/core/SuiteWalker/__tests__/hasRemainingTests.test.ts +130 -0
  59. package/src/core/VestBus/VestBus.ts +78 -0
  60. package/src/core/context/PersistedContext.ts +243 -0
  61. package/src/core/context/SuiteContext.ts +74 -0
  62. package/src/core/isolate/IsolateTest/IsolateTest.ts +213 -0
  63. package/src/core/isolate/IsolateTest/IsolateTestReconciler.ts +156 -0
  64. package/src/core/isolate/IsolateTest/IsolateTestStateMachine.ts +69 -0
  65. package/src/core/isolate/IsolateTest/SimpleStateMachine.ts +43 -0
  66. package/src/core/isolate/IsolateTest/TestWalker.ts +77 -0
  67. package/src/core/isolate/IsolateTypes.ts +10 -0
  68. package/src/core/isolate/isIsolate.ts +6 -0
  69. package/src/core/isolate/isolate.ts +110 -0
  70. package/src/core/isolate/reconciler/Reconciler/Reconciler.ts +123 -0
  71. package/src/core/isolate/reconciler/cancelOverriddenPendingTest.ts +15 -0
  72. package/src/core/isolate/reconciler/isSameProfileTest.ts +12 -0
  73. package/src/core/isolate/walker.ts +127 -0
  74. package/src/core/test/TestTypes.ts +3 -0
  75. package/src/core/test/__tests__/IsolateTest.test.ts +152 -0
  76. package/src/core/test/__tests__/__snapshots__/IsolateTest.test.ts.snap +39 -0
  77. package/src/core/test/__tests__/__snapshots__/memo.test.ts.snap +101 -0
  78. package/src/core/test/__tests__/__snapshots__/test.test.ts.snap +231 -0
  79. package/src/core/test/__tests__/key.test.ts +195 -0
  80. package/src/core/test/__tests__/memo.test.ts +218 -0
  81. package/src/core/test/__tests__/merging_of_previous_test_runs.test.ts +341 -0
  82. package/src/core/test/__tests__/runAsyncTest.test.ts +175 -0
  83. package/src/core/test/__tests__/test.test.ts +226 -0
  84. package/src/core/test/helpers/__tests__/nonMatchingSeverityProfile.test.ts +52 -0
  85. package/src/core/test/helpers/asVestTest.ts +9 -0
  86. package/src/core/test/helpers/matchingFieldName.ts +16 -0
  87. package/src/core/test/helpers/matchingGroupName.ts +12 -0
  88. package/src/core/test/helpers/nonMatchingSeverityProfile.ts +14 -0
  89. package/src/core/test/helpers/shouldUseErrorMessage.ts +9 -0
  90. package/src/core/test/test.memo.ts +81 -0
  91. package/src/core/test/test.ts +64 -0
  92. package/src/core/test/testLevelFlowControl/runTest.ts +86 -0
  93. package/src/core/test/testLevelFlowControl/verifyTestRun.ts +32 -0
  94. package/src/core/test/testObjectIsolate.ts +11 -0
  95. package/src/errors/ErrorStrings.ts +4 -0
  96. package/src/exports/__tests__/classnames.test.ts +92 -0
  97. package/src/exports/__tests__/parser.test.ts +441 -0
  98. package/src/exports/__tests__/promisify.test.ts +77 -0
  99. package/src/exports/classnames.ts +35 -0
  100. package/src/exports/enforce@compose.ts +1 -0
  101. package/src/exports/enforce@compounds.ts +1 -0
  102. package/src/exports/enforce@schema.ts +1 -0
  103. package/src/exports/parser.ts +63 -0
  104. package/src/exports/promisify.ts +18 -0
  105. package/src/hooks/__tests__/__snapshots__/include.test.ts.snap +794 -0
  106. package/src/hooks/__tests__/eager.test.ts +130 -0
  107. package/src/hooks/__tests__/exclusive.test.ts +578 -0
  108. package/src/hooks/__tests__/include.test.ts +431 -0
  109. package/src/hooks/__tests__/optional.test.ts +83 -0
  110. package/src/hooks/__tests__/warn.test.ts +42 -0
  111. package/src/hooks/exclusive.ts +179 -0
  112. package/src/hooks/include.ts +54 -0
  113. package/src/hooks/mode.ts +47 -0
  114. package/src/hooks/optional/OptionalTypes.ts +31 -0
  115. package/src/hooks/optional/optional.ts +69 -0
  116. package/src/hooks/warn.ts +19 -0
  117. package/src/isolates/__tests__/__snapshots__/each.test.ts.snap +3 -0
  118. package/src/isolates/__tests__/__snapshots__/group.test.ts.snap +114 -0
  119. package/src/isolates/__tests__/__snapshots__/omitWhen.test.ts.snap +443 -0
  120. package/src/isolates/__tests__/__snapshots__/skipWhen.test.ts.snap +99 -0
  121. package/src/isolates/__tests__/each.test.ts +35 -0
  122. package/src/isolates/__tests__/group.test.ts +362 -0
  123. package/src/isolates/__tests__/omitWhen.test.ts +246 -0
  124. package/src/isolates/__tests__/skipWhen.test.ts +163 -0
  125. package/src/isolates/each.ts +30 -0
  126. package/src/isolates/group.ts +9 -0
  127. package/src/isolates/omitWhen.ts +41 -0
  128. package/src/isolates/skipWhen.ts +42 -0
  129. package/src/suite/__tests__/__snapshots__/create.test.ts.snap +67 -0
  130. package/src/suite/__tests__/create.test.ts +109 -0
  131. package/src/suite/__tests__/remove.test.ts +50 -0
  132. package/src/suite/__tests__/resetField.test.ts +74 -0
  133. package/src/suite/createSuite.ts +94 -0
  134. package/src/suite/runCallbacks.ts +28 -0
  135. package/src/suiteResult/Severity.ts +15 -0
  136. package/src/suiteResult/SuiteResultTypes.ts +42 -0
  137. package/src/suiteResult/__tests__/done.test.ts +334 -0
  138. package/src/suiteResult/__tests__/produce.test.ts +163 -0
  139. package/src/suiteResult/done/deferDoneCallback.ts +28 -0
  140. package/src/suiteResult/done/shouldSkipDoneRegistration.ts +20 -0
  141. package/src/suiteResult/selectors/__tests__/__snapshots__/collectFailureMessages.test.ts.snap +89 -0
  142. package/src/suiteResult/selectors/__tests__/collectFailureMessages.test.ts +124 -0
  143. package/src/suiteResult/selectors/__tests__/getFailures.test.ts +158 -0
  144. package/src/suiteResult/selectors/__tests__/getFailuresByGroup.test.ts +199 -0
  145. package/src/suiteResult/selectors/__tests__/hasFailures.test.ts +141 -0
  146. package/src/suiteResult/selectors/__tests__/hasFailuresByGroup.test.ts +185 -0
  147. package/src/suiteResult/selectors/__tests__/hasFailuresByTestObject.test.ts +88 -0
  148. package/src/suiteResult/selectors/__tests__/isValid.test.ts +359 -0
  149. package/src/suiteResult/selectors/__tests__/isValidByGroup.test.ts +480 -0
  150. package/src/suiteResult/selectors/collectFailures.ts +43 -0
  151. package/src/suiteResult/selectors/hasFailuresByTestObjects.ts +62 -0
  152. package/src/suiteResult/selectors/produceSuiteSummary.ts +135 -0
  153. package/src/suiteResult/selectors/shouldAddValidProperty.ts +148 -0
  154. package/src/suiteResult/selectors/suiteSelectors.ts +199 -0
  155. package/src/suiteResult/suiteResult.ts +15 -0
  156. package/src/suiteResult/suiteRunResult.ts +43 -0
  157. package/src/vest.ts +36 -0
  158. package/testUtils/TVestMock.ts +5 -0
  159. package/testUtils/__tests__/partition.test.ts +4 -4
  160. package/testUtils/mockThrowError.ts +4 -2
  161. package/testUtils/suiteDummy.ts +2 -1
  162. package/testUtils/testDummy.ts +12 -10
  163. package/testUtils/testPromise.ts +3 -0
  164. package/tsconfig.json +84 -2
  165. package/types/classnames.d.ts +39 -4
  166. package/types/classnames.d.ts.map +1 -0
  167. package/types/enforce/compose.d.ts +2 -126
  168. package/types/enforce/compose.d.ts.map +1 -0
  169. package/types/enforce/compounds.d.ts +2 -136
  170. package/types/enforce/compounds.d.ts.map +1 -0
  171. package/types/enforce/schema.d.ts +2 -144
  172. package/types/enforce/schema.d.ts.map +1 -0
  173. package/types/parser.d.ts +45 -10
  174. package/types/parser.d.ts.map +1 -0
  175. package/types/promisify.d.ts +36 -34
  176. package/types/promisify.d.ts.map +1 -0
  177. package/types/vest.d.ts +169 -224
  178. package/types/vest.d.ts.map +1 -0
  179. package/CHANGELOG.md +0 -87
  180. package/testUtils/expandStateRef.ts +0 -8
  181. package/testUtils/runCreateRef.ts +0 -10
  182. package/testUtils/testObjects.ts +0 -6
@@ -0,0 +1,480 @@
1
+ import wait from 'wait';
2
+
3
+ import { TestPromise } from '../../../../testUtils/testPromise';
4
+
5
+ import { TTestSuite } from 'testUtils/TVestMock';
6
+ import {
7
+ test,
8
+ optional,
9
+ create,
10
+ skipWhen,
11
+ warn,
12
+ skip,
13
+ only,
14
+ group,
15
+ } from 'vest';
16
+
17
+ const GROUP_NAME = 'group_1';
18
+
19
+ describe('isValidByGroup', () => {
20
+ describe('Before any test ran', () => {
21
+ it('Should return false', () => {
22
+ const suite = create(() => {
23
+ group(GROUP_NAME, () => {
24
+ test('field_1', () => {});
25
+ });
26
+ });
27
+
28
+ expect(suite.get().isValidByGroup(GROUP_NAME)).toBe(false);
29
+ });
30
+ });
31
+
32
+ describe('When there are errors in the group', () => {
33
+ let suite: TTestSuite;
34
+
35
+ beforeEach(() => {
36
+ suite = create((fieldToSkip: string) => {
37
+ skip(fieldToSkip);
38
+ optional('field_1');
39
+
40
+ group(GROUP_NAME, () => {
41
+ test('field_1', () => false);
42
+ test('field_2', () => false);
43
+ test('sanity', () => true);
44
+ });
45
+ });
46
+ });
47
+
48
+ it('Should return false when an optional test has errors', () => {
49
+ expect(suite('field_2').isValidByGroup(GROUP_NAME)).toBe(false);
50
+ expect(suite('field_2').isValidByGroup(GROUP_NAME, 'field_1')).toBe(
51
+ false
52
+ );
53
+ });
54
+ it('Should return false when a required test has errors', () => {
55
+ expect(suite('field_1').isValidByGroup(GROUP_NAME)).toBe(false);
56
+ expect(suite('field_1').isValidByGroup(GROUP_NAME, 'field_2')).toBe(
57
+ false
58
+ );
59
+ });
60
+
61
+ it('Should return false when the queried field is not optional and has errors', () => {
62
+ expect(suite('field_2').isValidByGroup(GROUP_NAME, 'field_2')).toBe(
63
+ false
64
+ );
65
+ });
66
+
67
+ it('Should return true when the queried field is optional and has errors', () => {
68
+ expect(suite('field_1').isValidByGroup(GROUP_NAME, 'field_1')).toBe(true);
69
+ });
70
+ });
71
+
72
+ describe('When there are warnings in the group', () => {
73
+ let suite: TTestSuite;
74
+
75
+ beforeEach(() => {
76
+ suite = create(() => {
77
+ group(GROUP_NAME, () => {
78
+ test('field_1', () => {
79
+ warn();
80
+ return false;
81
+ });
82
+ });
83
+ });
84
+ });
85
+ it('Should return true when a required test has warnings', () => {
86
+ expect(suite().isValidByGroup(GROUP_NAME)).toBe(true);
87
+ expect(suite().isValidByGroup(GROUP_NAME, 'field_1')).toBe(true);
88
+ });
89
+
90
+ describe('When some of the tests for the required field are warnings', () => {
91
+ beforeEach(() => {
92
+ suite = create(() => {
93
+ test('field_1', () => {
94
+ warn();
95
+ return false;
96
+ });
97
+ test('field_1', () => true);
98
+ });
99
+ });
100
+ it('Should return true when a required test has warnings', () => {
101
+ expect(suite().isValid()).toBe(true);
102
+ });
103
+ });
104
+
105
+ describe('when a warning test in a required field is skipped', () => {
106
+ beforeEach(() => {
107
+ suite = create(() => {
108
+ test('field_1', () => true);
109
+
110
+ skipWhen(true, () => {
111
+ test('field_1', () => {
112
+ warn();
113
+ return false;
114
+ });
115
+ });
116
+ });
117
+ });
118
+ it('Should return false even when the skipped field is warning', () => {
119
+ expect(suite().isValid()).toBe(false);
120
+ });
121
+ });
122
+ });
123
+
124
+ describe('When a non optional field is skipped', () => {
125
+ let suite: TTestSuite;
126
+
127
+ beforeEach(() => {
128
+ suite = create(fieldToSkip => {
129
+ skip(fieldToSkip);
130
+ group(GROUP_NAME, () => {
131
+ test('field_1', () => {
132
+ return false;
133
+ });
134
+ test('field_2', () => {
135
+ return true;
136
+ });
137
+ test('field_3', () => {
138
+ return true;
139
+ });
140
+ });
141
+ });
142
+ });
143
+ it('Should return false', () => {
144
+ expect(suite('field_1').isValidByGroup(GROUP_NAME)).toBe(false);
145
+ });
146
+ it('Should return false', () => {
147
+ expect(suite(['field_2', 'field_3']).isValidByGroup(GROUP_NAME)).toBe(
148
+ false
149
+ );
150
+ });
151
+ });
152
+
153
+ describe('When the suite has an async optional test', () => {
154
+ let suite: TTestSuite;
155
+
156
+ beforeEach(() => {
157
+ suite = create(() => {
158
+ optional('field_1');
159
+
160
+ group(GROUP_NAME, () => {
161
+ test('field_1', async () => {
162
+ await wait(300);
163
+ });
164
+ });
165
+ });
166
+ });
167
+
168
+ describe('When test is pending', () => {
169
+ it('Should return true', () => {
170
+ suite();
171
+ expect(suite.get().isValidByGroup(GROUP_NAME)).toBe(true);
172
+ expect(suite.get().isValidByGroup(GROUP_NAME, 'field_1')).toBe(true);
173
+ });
174
+ });
175
+ describe('When test is passing', () => {
176
+ it('Should return true', async () => {
177
+ suite();
178
+ await wait(300);
179
+ expect(suite.get().isValidByGroup(GROUP_NAME)).toBe(true);
180
+ expect(suite.get().isValidByGroup(GROUP_NAME, 'field_1')).toBe(true);
181
+ });
182
+ });
183
+ });
184
+
185
+ describe('When the suite has warning async tests', () => {
186
+ let suite: TTestSuite;
187
+
188
+ beforeEach(() => {
189
+ suite = create(() => {
190
+ group(GROUP_NAME, () => {
191
+ test('field_1', async () => {
192
+ warn();
193
+ await wait(300);
194
+ });
195
+
196
+ test('field_1', () => {
197
+ return true;
198
+ });
199
+ });
200
+ });
201
+ });
202
+
203
+ it('Should return false as long as the test is pending', async () => {
204
+ suite();
205
+ expect(suite.get().isValidByGroup(GROUP_NAME)).toBe(false);
206
+ await wait(300);
207
+ expect(suite.get().isValidByGroup(GROUP_NAME)).toBe(true);
208
+ });
209
+
210
+ it('Should return false as long as the test is pending when querying a specific field', async () => {
211
+ suite();
212
+ expect(suite.get().isValidByGroup(GROUP_NAME, 'field_1')).toBe(false);
213
+ await wait(300);
214
+ expect(suite.get().isValidByGroup(GROUP_NAME, 'field_1')).toBe(true);
215
+ });
216
+ });
217
+
218
+ describe('When the suite has async non-optional tests', () => {
219
+ let suite: TTestSuite;
220
+
221
+ beforeEach(() => {
222
+ suite = create(currentField => {
223
+ only(currentField);
224
+ optional('field_2');
225
+ group(GROUP_NAME, () => {
226
+ test('field_1', async () => {
227
+ await wait(300);
228
+ });
229
+ test('field_2', () => {
230
+ return true;
231
+ });
232
+ });
233
+ });
234
+ });
235
+
236
+ describe('When test is pending', () => {
237
+ it('Should return `false` for a required field', () => {
238
+ const result = suite();
239
+
240
+ expect(result.isValidByGroup(GROUP_NAME)).toBe(false);
241
+ expect(result.isValidByGroup(GROUP_NAME, 'field_1')).toBe(false);
242
+ });
243
+ });
244
+
245
+ describe('When async test is passing', () => {
246
+ it('Should return `true`', () => {
247
+ return TestPromise(done => {
248
+ suite().done(result => {
249
+ expect(result.isValidByGroup(GROUP_NAME)).toBe(true);
250
+ expect(result.isValidByGroup(GROUP_NAME, 'field_1')).toBe(true);
251
+ expect(result.isValidByGroup(GROUP_NAME, 'field_2')).toBe(true);
252
+ done();
253
+ });
254
+ });
255
+ });
256
+ });
257
+
258
+ describe('When test is lagging', () => {
259
+ it('Should return `false`', () => {
260
+ suite();
261
+ const result = suite('field_2');
262
+
263
+ expect(result.isValidByGroup(GROUP_NAME)).toBe(false);
264
+ });
265
+ });
266
+ });
267
+
268
+ describe('When a all required fields are passing', () => {
269
+ let suite: TTestSuite;
270
+
271
+ beforeEach(() => {
272
+ suite = create(() => {
273
+ group(GROUP_NAME, () => {
274
+ test('field_1', () => {
275
+ return true;
276
+ });
277
+ test('field_1', () => {
278
+ return true;
279
+ });
280
+ test('field_2', () => {
281
+ return true;
282
+ });
283
+ test('field_3', () => {
284
+ return true;
285
+ });
286
+ });
287
+ });
288
+ });
289
+ it('Should return true', () => {
290
+ expect(suite().isValidByGroup(GROUP_NAME)).toBe(true);
291
+ expect(suite().isValidByGroup(GROUP_NAME, 'field_1')).toBe(true);
292
+ expect(suite().isValidByGroup(GROUP_NAME, 'field_2')).toBe(true);
293
+ expect(suite().isValidByGroup(GROUP_NAME, 'field_3')).toBe(true);
294
+ });
295
+ });
296
+
297
+ describe('When a required field has some passing tests', () => {
298
+ it('Should return false', () => {
299
+ expect(
300
+ create(() => {
301
+ group(GROUP_NAME, () => {
302
+ test('field_1', () => true);
303
+ skipWhen(true, () => {
304
+ test('field_1', () => {
305
+ return true;
306
+ });
307
+ });
308
+ });
309
+ })().isValidByGroup(GROUP_NAME)
310
+ ).toBe(false);
311
+ });
312
+ });
313
+
314
+ describe('When field name is specified', () => {
315
+ it('Should return false when field did not run yet', () => {
316
+ expect(
317
+ create(() => {
318
+ skip('field_1');
319
+ group(GROUP_NAME, () => {
320
+ test('field_1', () => true);
321
+ });
322
+ })().isValidByGroup(GROUP_NAME, 'field_1')
323
+ ).toBe(false);
324
+ });
325
+
326
+ it('Should return false when testing for a field that does not exist', () => {
327
+ expect(
328
+ create(() => {
329
+ group(GROUP_NAME, () => {
330
+ test('field_1', () => {});
331
+ });
332
+ })().isValidByGroup(GROUP_NAME, 'field 2')
333
+ ).toBe(false);
334
+ });
335
+
336
+ it("Should return false when some of the field's tests ran", () => {
337
+ expect(
338
+ create(() => {
339
+ group(GROUP_NAME, () => {
340
+ test('field_1', () => {
341
+ return true;
342
+ });
343
+ skipWhen(true, () => {
344
+ test('field_1', () => {
345
+ return true;
346
+ });
347
+ });
348
+ });
349
+ })().isValidByGroup(GROUP_NAME, 'field_1')
350
+ ).toBe(false);
351
+ });
352
+
353
+ it('Should return false when the field has errors', () => {
354
+ expect(
355
+ create(() => {
356
+ group(GROUP_NAME, () => {
357
+ test('field_1', () => false);
358
+ });
359
+ })().isValidByGroup(GROUP_NAME, 'field_1')
360
+ ).toBe(false);
361
+ });
362
+
363
+ it('Should return true when all the tests are passing', () => {
364
+ expect(
365
+ create(() => {
366
+ group(GROUP_NAME, () => {
367
+ test('field_1', () => {});
368
+ });
369
+ })().isValidByGroup(GROUP_NAME, 'field_1')
370
+ ).toBe(true);
371
+ });
372
+
373
+ it('Should return true when the field only has warnings', () => {
374
+ expect(
375
+ create(() => {
376
+ group(GROUP_NAME, () => {
377
+ test('field_1', () => {
378
+ warn();
379
+ return false;
380
+ });
381
+ });
382
+ })().isValidByGroup(GROUP_NAME, 'field_1')
383
+ ).toBe(true);
384
+ });
385
+
386
+ it('Should return true if field is optional and did not run', () => {
387
+ expect(
388
+ create(() => {
389
+ optional('field_1');
390
+ skipWhen(true, () => {
391
+ group(GROUP_NAME, () => {
392
+ test('field_1', () => false);
393
+ });
394
+ });
395
+ })().isValidByGroup(GROUP_NAME, 'field_1')
396
+ ).toBe(true);
397
+ });
398
+ });
399
+
400
+ describe('When querying a non existing field', () => {
401
+ it('Should return false', () => {
402
+ expect(
403
+ create(() => {
404
+ group(GROUP_NAME, () => {
405
+ test('field_1', () => true);
406
+ });
407
+ })().isValidByGroup(GROUP_NAME, 'field_2')
408
+ ).toBe(false);
409
+ });
410
+ });
411
+
412
+ describe('When querying a non existing group', () => {
413
+ const suite = create(() => {
414
+ group(GROUP_NAME, () => {
415
+ test('field_1', () => true);
416
+ });
417
+ });
418
+ it('Should return false', () => {
419
+ expect(suite().isValidByGroup('does-not-exist')).toBe(false);
420
+ expect(suite().isValidByGroup('does-not-exist', 'field_1')).toBe(false);
421
+ });
422
+ });
423
+
424
+ describe('When queried field is omitted', () => {
425
+ it('Should return true', () => {
426
+ expect(
427
+ create(() => {
428
+ optional({
429
+ field_1: () => true,
430
+ });
431
+ group(GROUP_NAME, () => {
432
+ test('field_1', () => false);
433
+ });
434
+ })().isValidByGroup(GROUP_NAME)
435
+ ).toBe(true);
436
+ });
437
+ });
438
+
439
+ describe('When querying a field that is in a different group', () => {
440
+ const suite = create(() => {
441
+ group('group_1', () => {
442
+ test('field_1', () => {});
443
+ });
444
+ group('group_2', () => {
445
+ test('field_2', () => {});
446
+ });
447
+ });
448
+
449
+ it('Should return false', () => {
450
+ expect(suite().isValidByGroup('group_1', 'field_2')).toBe(false);
451
+ expect(suite().isValidByGroup('group_2', 'field_1')).toBe(false);
452
+ });
453
+ });
454
+
455
+ describe('When querying a field that is outside of a group', () => {
456
+ const suite = create(() => {
457
+ test('field_1', () => {});
458
+ group('group_1', () => {
459
+ test('field_2', () => {});
460
+ });
461
+ });
462
+
463
+ it('Should return false', () => {
464
+ expect(suite().isValidByGroup('group_1', 'field_1')).toBe(false);
465
+ });
466
+ });
467
+
468
+ describe('When the field exists both inside and outside of the group', () => {
469
+ const suite = create(() => {
470
+ test('field_1', () => false);
471
+ group('group_1', () => {
472
+ test('field_1', () => {});
473
+ });
474
+ });
475
+
476
+ it('Should return the result of what is inside the group', () => {
477
+ expect(suite().isValidByGroup('group_1', 'field_1')).toBe(true);
478
+ });
479
+ });
480
+ });
@@ -0,0 +1,43 @@
1
+ import { isPositive } from 'vest-utils';
2
+
3
+ import { countKeyBySeverity, Severity } from 'Severity';
4
+ import { FailureMessages, TestsContainer, TFieldName } from 'SuiteResultTypes';
5
+
6
+ // calls collectAll or getByFieldName depending on whether fieldName is provided
7
+
8
+ export function gatherFailures(
9
+ testGroup: TestsContainer<TFieldName>,
10
+ severityKey: Severity,
11
+ fieldName?: TFieldName
12
+ ): string[] | FailureMessages {
13
+ return fieldName
14
+ ? getByFieldName(testGroup, severityKey, fieldName)
15
+ : collectAll(testGroup, severityKey);
16
+ }
17
+
18
+ function getByFieldName(
19
+ testGroup: TestsContainer<TFieldName>,
20
+ severityKey: Severity,
21
+ fieldName: TFieldName
22
+ ): string[] {
23
+ return testGroup?.[fieldName]?.[severityKey] || [];
24
+ }
25
+
26
+ function collectAll(
27
+ testGroup: TestsContainer<TFieldName>,
28
+ severityKey: Severity
29
+ ): FailureMessages {
30
+ const output: FailureMessages = {};
31
+
32
+ const countKey = countKeyBySeverity(severityKey);
33
+
34
+ for (const field in testGroup) {
35
+ if (isPositive(testGroup[field][countKey])) {
36
+ // We will probably never get to the fallback array
37
+ // leaving it just in case the implementation changes
38
+ output[field] = testGroup[field][severityKey] || [];
39
+ }
40
+ }
41
+
42
+ return output;
43
+ }
@@ -0,0 +1,62 @@
1
+ import { IsolateTest } from 'IsolateTest';
2
+ import { Severity } from 'Severity';
3
+ import { TFieldName } from 'SuiteResultTypes';
4
+ import { TestWalker } from 'TestWalker';
5
+ import { nonMatchingFieldName } from 'matchingFieldName';
6
+ import { nonMatchingGroupName } from 'matchingGroupName';
7
+ import { nonMatchingSeverityProfile } from 'nonMatchingSeverityProfile';
8
+
9
+ /**
10
+ * The difference between this file and hasFailures is that hasFailures uses the static
11
+ * summary object, while this one uses the actual validation state
12
+ */
13
+
14
+ export function hasErrorsByTestObjects(fieldName?: TFieldName): boolean {
15
+ return hasFailuresByTestObjects(Severity.ERRORS, fieldName);
16
+ }
17
+
18
+ export function hasFailuresByTestObjects(
19
+ severityKey: Severity,
20
+ fieldName?: TFieldName
21
+ ): boolean {
22
+ return TestWalker.someTests(testObject => {
23
+ return hasFailuresByTestObject(testObject, severityKey, fieldName);
24
+ });
25
+ }
26
+
27
+ export function hasGroupFailuresByTestObjects(
28
+ severityKey: Severity,
29
+ groupName: string,
30
+ fieldName?: TFieldName
31
+ ): boolean {
32
+ return TestWalker.someTests(testObject => {
33
+ if (nonMatchingGroupName(testObject, groupName)) {
34
+ return false;
35
+ }
36
+
37
+ return hasFailuresByTestObject(testObject, severityKey, fieldName);
38
+ });
39
+ }
40
+
41
+ /**
42
+ * Determines whether a certain test profile has failures.
43
+ */
44
+ export function hasFailuresByTestObject(
45
+ testObject: IsolateTest,
46
+ severityKey: Severity,
47
+ fieldName?: TFieldName
48
+ ): boolean {
49
+ if (!testObject.hasFailures()) {
50
+ return false;
51
+ }
52
+
53
+ if (nonMatchingFieldName(testObject, fieldName)) {
54
+ return false;
55
+ }
56
+
57
+ if (nonMatchingSeverityProfile(severityKey, testObject)) {
58
+ return false;
59
+ }
60
+
61
+ return true;
62
+ }
@@ -0,0 +1,135 @@
1
+ import { assign } from 'vest-utils';
2
+
3
+ import { IsolateTest } from 'IsolateTest';
4
+ import { countKeyBySeverity, Severity } from 'Severity';
5
+ import {
6
+ Group,
7
+ Groups,
8
+ SingleTestSummary,
9
+ SuiteSummary,
10
+ TFieldName,
11
+ Tests,
12
+ TestsContainer,
13
+ } from 'SuiteResultTypes';
14
+ import { TestWalker } from 'TestWalker';
15
+ import {
16
+ shouldAddValidProperty,
17
+ shouldAddValidPropertyInGroup,
18
+ } from 'shouldAddValidProperty';
19
+
20
+ export function produceSuiteSummary<F extends TFieldName>(): SuiteSummary<F> {
21
+ const summary: SuiteSummary<F> = assign(baseStats(), {
22
+ groups: {},
23
+ tests: {},
24
+ valid: false,
25
+ }) as SuiteSummary<F>;
26
+
27
+ TestWalker.walkTests(testObject => {
28
+ appendToTest(summary.tests, testObject);
29
+ appendToGroup(summary.groups, testObject);
30
+ });
31
+
32
+ summary.valid = shouldAddValidProperty();
33
+
34
+ return countFailures(summary);
35
+ }
36
+
37
+ function appendToTest(tests: Tests<TFieldName>, testObject: IsolateTest) {
38
+ tests[testObject.fieldName] = appendTestObject(tests, testObject);
39
+ // If `valid` is false to begin with, keep it that way. Otherwise, assess.
40
+ tests[testObject.fieldName].valid =
41
+ tests[testObject.fieldName].valid === false
42
+ ? false
43
+ : shouldAddValidProperty(testObject.fieldName);
44
+ }
45
+
46
+ /**
47
+ * Appends to a group object if within a group
48
+ */
49
+ function appendToGroup(groups: Groups, testObject: IsolateTest) {
50
+ const { groupName } = testObject;
51
+
52
+ if (!groupName) {
53
+ return;
54
+ }
55
+
56
+ groups[groupName] = groups[groupName] || {};
57
+ groups[groupName][testObject.fieldName] = appendTestObject(
58
+ groups[groupName],
59
+ testObject
60
+ );
61
+
62
+ groups[groupName][testObject.fieldName].valid =
63
+ groups[groupName][testObject.fieldName].valid === false
64
+ ? false
65
+ : shouldAddValidPropertyInGroup(groupName, testObject.fieldName);
66
+ }
67
+
68
+ /**
69
+ * Counts the failed tests and adds global counters
70
+ */
71
+ function countFailures(
72
+ summary: SuiteSummary<TFieldName>
73
+ ): SuiteSummary<TFieldName> {
74
+ for (const test in summary.tests) {
75
+ summary.errorCount += summary.tests[test].errorCount;
76
+ summary.warnCount += summary.tests[test].warnCount;
77
+ summary.testCount += summary.tests[test].testCount;
78
+ }
79
+ return summary;
80
+ }
81
+
82
+ /**
83
+ * Appends the test to a results object.
84
+ * Overload is only needed to satisfy typescript. No use in breaking it down to multiple
85
+ * functions as it is really the same, with the difference of "valid" missing in groups
86
+ */
87
+ function appendTestObject(
88
+ summaryKey: Tests<TFieldName> | Group,
89
+ testObject: IsolateTest
90
+ ): SingleTestSummary;
91
+ function appendTestObject(
92
+ summaryKey: Group | Tests<TFieldName>,
93
+ testObject: IsolateTest
94
+ ): TestsContainer<TFieldName>[keyof TestsContainer<TFieldName>] {
95
+ const { fieldName, message } = testObject;
96
+
97
+ summaryKey[fieldName] = summaryKey[fieldName] || baseTestStats();
98
+
99
+ const testKey = summaryKey[fieldName];
100
+
101
+ if (testObject.isNonActionable()) return testKey;
102
+
103
+ summaryKey[fieldName].testCount++;
104
+
105
+ if (testObject.isFailing()) {
106
+ incrementFailures(Severity.ERRORS);
107
+ } else if (testObject.isWarning()) {
108
+ incrementFailures(Severity.WARNINGS);
109
+ }
110
+
111
+ return testKey;
112
+
113
+ function incrementFailures(severity: Severity) {
114
+ const countKey = countKeyBySeverity(severity);
115
+ testKey[countKey]++;
116
+ if (message) {
117
+ testKey[severity] = (testKey[severity] || []).concat(message);
118
+ }
119
+ }
120
+ }
121
+
122
+ function baseStats() {
123
+ return {
124
+ errorCount: 0,
125
+ warnCount: 0,
126
+ testCount: 0,
127
+ };
128
+ }
129
+
130
+ function baseTestStats() {
131
+ return assign(baseStats(), {
132
+ errors: [],
133
+ warnings: [],
134
+ });
135
+ }