ava 0.16.0 → 0.18.2
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/api.js +297 -265
- package/cli.js +15 -179
- package/index.js +5 -98
- package/index.js.flow +201 -0
- package/lib/assert.js +87 -53
- package/lib/ava-error.js +4 -8
- package/lib/ava-files.js +282 -0
- package/lib/babel-config.js +35 -73
- package/lib/beautify-stack.js +17 -16
- package/lib/caching-precompiler.js +72 -87
- package/lib/cli.js +181 -0
- package/lib/code-excerpt.js +57 -0
- package/lib/colors.js +6 -2
- package/lib/concurrent.js +62 -75
- package/lib/enhance-assert.js +57 -49
- package/lib/extract-stack.js +10 -0
- package/lib/fork.js +67 -68
- package/lib/format-assert-error.js +72 -0
- package/lib/globals.js +3 -8
- package/lib/hook.js +15 -20
- package/lib/logger.js +59 -82
- package/lib/main.js +90 -0
- package/lib/prefix-title.js +21 -0
- package/lib/process-adapter.js +108 -0
- package/lib/reporters/mini.js +260 -257
- package/lib/reporters/tap.js +80 -85
- package/lib/reporters/verbose.js +142 -115
- package/lib/run-status.js +110 -152
- package/lib/runner.js +125 -137
- package/lib/sequence.js +68 -84
- package/lib/serialize-error.js +68 -4
- package/lib/snapshot-state.js +30 -0
- package/lib/test-collection.js +144 -156
- package/lib/test-worker.js +45 -95
- package/lib/test.js +289 -318
- package/lib/throws-helper.js +9 -9
- package/lib/validate-test.js +48 -0
- package/lib/watcher.js +258 -297
- package/package.json +63 -53
- package/profile.js +68 -55
- package/readme.md +215 -101
- package/types/generated.d.ts +848 -228
- package/types/make.js +54 -23
- package/lib/send.js +0 -16
package/lib/test.js
CHANGED
|
@@ -1,398 +1,369 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (typeof title === 'function') {
|
|
24
|
-
contextRef = fn;
|
|
25
|
-
fn = title;
|
|
26
|
-
title = null;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
assert.is(typeof fn, 'function', 'you must provide a callback');
|
|
30
|
-
|
|
31
|
-
this.title = title || fnName(fn) || '[anonymous]';
|
|
32
|
-
this.fn = isGeneratorFn(fn) ? co.wrap(fn) : fn;
|
|
33
|
-
this.assertions = [];
|
|
34
|
-
this.planCount = null;
|
|
35
|
-
this.duration = null;
|
|
36
|
-
this.assertError = undefined;
|
|
37
|
-
this.sync = true;
|
|
38
|
-
this.contextRef = contextRef;
|
|
39
|
-
this.report = report;
|
|
40
|
-
this.threwSync = false;
|
|
41
|
-
|
|
42
|
-
// TODO(jamestalmage): make this an optional constructor arg instead of having Runner set it after the fact.
|
|
43
|
-
// metadata should just always exist, otherwise it requires a bunch of ugly checks all over the place.
|
|
44
|
-
this.metadata = {};
|
|
45
|
-
|
|
46
|
-
// store the time point before test execution
|
|
47
|
-
// to calculate the total time spent in test
|
|
48
|
-
this._timeStart = null;
|
|
49
|
-
|
|
50
|
-
// workaround for Babel giving anonymous functions a name
|
|
51
|
-
if (this.title === 'callee$0$0') {
|
|
52
|
-
this.title = '[anonymous]';
|
|
2
|
+
const inspect = require('util').inspect;
|
|
3
|
+
const isGeneratorFn = require('is-generator-fn');
|
|
4
|
+
const maxTimeout = require('max-timeout');
|
|
5
|
+
const Promise = require('bluebird');
|
|
6
|
+
const fnName = require('fn-name');
|
|
7
|
+
const co = require('co-with-promise');
|
|
8
|
+
const observableToPromise = require('observable-to-promise');
|
|
9
|
+
const isPromise = require('is-promise');
|
|
10
|
+
const isObservable = require('is-observable');
|
|
11
|
+
const plur = require('plur');
|
|
12
|
+
const assert = require('./assert');
|
|
13
|
+
const enhanceAssert = require('./enhance-assert');
|
|
14
|
+
const globals = require('./globals');
|
|
15
|
+
const throwsHelper = require('./throws-helper');
|
|
16
|
+
|
|
17
|
+
const formatter = enhanceAssert.formatter();
|
|
18
|
+
|
|
19
|
+
class SkipApi {
|
|
20
|
+
constructor(test) {
|
|
21
|
+
this._test = test;
|
|
53
22
|
}
|
|
54
23
|
}
|
|
55
24
|
|
|
56
|
-
|
|
25
|
+
function skipFn() {
|
|
26
|
+
return this._test._assert(null);
|
|
27
|
+
}
|
|
57
28
|
|
|
58
|
-
Object.
|
|
59
|
-
|
|
60
|
-
get: function () {
|
|
61
|
-
return this.assertions.length;
|
|
62
|
-
}
|
|
29
|
+
Object.keys(assert).forEach(el => {
|
|
30
|
+
SkipApi.prototype[el] = skipFn;
|
|
63
31
|
});
|
|
64
32
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
this.
|
|
33
|
+
class PublicApi {
|
|
34
|
+
constructor(test) {
|
|
35
|
+
this._test = test;
|
|
36
|
+
this.skip = new SkipApi(test);
|
|
68
37
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return;
|
|
38
|
+
plan(ct) {
|
|
39
|
+
const limitBefore = Error.stackTraceLimit;
|
|
40
|
+
Error.stackTraceLimit = 1;
|
|
41
|
+
const obj = {};
|
|
42
|
+
Error.captureStackTrace(obj, this.plan);
|
|
43
|
+
Error.stackTraceLimit = limitBefore;
|
|
44
|
+
this._test.plan(ct, obj.stack);
|
|
77
45
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
Test.prototype.plan = function (count, planStack) {
|
|
83
|
-
if (typeof count !== 'number') {
|
|
84
|
-
throw new TypeError('Expected a number');
|
|
46
|
+
get context() {
|
|
47
|
+
const contextRef = this._test.contextRef;
|
|
48
|
+
return contextRef && contextRef.context;
|
|
85
49
|
}
|
|
50
|
+
set context(context) {
|
|
51
|
+
const contextRef = this._test.contextRef;
|
|
86
52
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// we need the stack of this function to throw with a useful stack
|
|
91
|
-
this.planStack = planStack;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
Test.prototype._run = function () {
|
|
95
|
-
var ret;
|
|
96
|
-
|
|
97
|
-
try {
|
|
98
|
-
ret = this.fn(this._publicApi());
|
|
99
|
-
} catch (err) {
|
|
100
|
-
this.threwSync = true;
|
|
101
|
-
if (err instanceof Error) {
|
|
102
|
-
this._setAssertError(err);
|
|
103
|
-
} else {
|
|
104
|
-
this._setAssertError(new assert.AssertionError({
|
|
105
|
-
actual: err,
|
|
106
|
-
message: 'Non-error thrown with value: ' + inspect(err, {depth: null}),
|
|
107
|
-
operator: 'catch'
|
|
108
|
-
}));
|
|
53
|
+
if (!contextRef) {
|
|
54
|
+
this._test._setAssertError(new Error(`t.context is not available in ${this._test.metadata.type} tests`));
|
|
55
|
+
return;
|
|
109
56
|
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return ret;
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
Test.prototype.promise = function () {
|
|
116
|
-
var self = this;
|
|
117
57
|
|
|
118
|
-
|
|
119
|
-
this._promise = {};
|
|
120
|
-
|
|
121
|
-
this._promise.promise = new Promise(function (resolve, reject) { // eslint-disable-line no-use-extend-native/no-use-extend-native
|
|
122
|
-
self._promise.resolve = resolve;
|
|
123
|
-
self._promise.reject = reject;
|
|
124
|
-
}).tap(function (result) {
|
|
125
|
-
if (self.report) {
|
|
126
|
-
self.report(result);
|
|
127
|
-
}
|
|
128
|
-
});
|
|
58
|
+
contextRef.context = context;
|
|
129
59
|
}
|
|
60
|
+
}
|
|
130
61
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
62
|
+
function onAssertionEvent(event) {
|
|
63
|
+
if (event.assertionThrew) {
|
|
64
|
+
if (event.powerAssertContext) {
|
|
65
|
+
event.error.statements = formatter(event.powerAssertContext);
|
|
66
|
+
event.error.message = event.originalMessage || '';
|
|
67
|
+
}
|
|
68
|
+
this._test._setAssertError(event.error);
|
|
69
|
+
this._test._assert(null);
|
|
70
|
+
return null;
|
|
137
71
|
}
|
|
138
72
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
this._timeStart = globals.now();
|
|
142
|
-
|
|
143
|
-
// wait until all assertions are complete
|
|
144
|
-
this._timeout = globals.setTimeout(function () {}, maxTimeout);
|
|
145
|
-
|
|
146
|
-
var ret = this._run();
|
|
147
|
-
|
|
148
|
-
var asyncType = 'promises';
|
|
73
|
+
let ret = event.returnValue;
|
|
149
74
|
|
|
150
75
|
if (isObservable(ret)) {
|
|
151
|
-
asyncType = 'observables';
|
|
152
76
|
ret = observableToPromise(ret);
|
|
153
77
|
}
|
|
154
78
|
|
|
155
79
|
if (isPromise(ret)) {
|
|
156
|
-
|
|
80
|
+
const promise = ret.then(null, err => {
|
|
81
|
+
err.originalMessage = event.originalMessage;
|
|
82
|
+
throw err;
|
|
83
|
+
});
|
|
157
84
|
|
|
158
|
-
|
|
159
|
-
self._setAssertError(new Error('Do not return ' + asyncType + ' from tests declared via `test.cb(...)`, if you want to return a promise simply declare the test via `test(...)`'));
|
|
160
|
-
}
|
|
85
|
+
this._test._assert(promise);
|
|
161
86
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
self.exit();
|
|
165
|
-
},
|
|
166
|
-
function (err) {
|
|
167
|
-
if (!(err instanceof Error)) {
|
|
168
|
-
err = new assert.AssertionError({
|
|
169
|
-
actual: err,
|
|
170
|
-
message: 'Promise rejected with: ' + inspect(err, {depth: null}),
|
|
171
|
-
operator: 'promise'
|
|
172
|
-
});
|
|
173
|
-
}
|
|
87
|
+
return promise;
|
|
88
|
+
}
|
|
174
89
|
|
|
175
|
-
|
|
176
|
-
self.exit();
|
|
177
|
-
});
|
|
90
|
+
this._test._assert(null);
|
|
178
91
|
|
|
179
|
-
|
|
180
|
-
|
|
92
|
+
return ret;
|
|
93
|
+
}
|
|
181
94
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
95
|
+
Object.assign(PublicApi.prototype, enhanceAssert({
|
|
96
|
+
assert,
|
|
97
|
+
onSuccess: onAssertionEvent,
|
|
98
|
+
onError: onAssertionEvent
|
|
99
|
+
}));
|
|
185
100
|
|
|
186
|
-
|
|
187
|
-
|
|
101
|
+
// Getters
|
|
102
|
+
[
|
|
103
|
+
'assertCount',
|
|
104
|
+
'title',
|
|
105
|
+
'end'
|
|
106
|
+
]
|
|
107
|
+
.forEach(name => {
|
|
108
|
+
Object.defineProperty(PublicApi.prototype, name, {
|
|
109
|
+
get() {
|
|
110
|
+
return this._test[name];
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
188
114
|
|
|
189
|
-
|
|
190
|
-
var reason = this.assertError;
|
|
191
|
-
var passed = reason === undefined;
|
|
115
|
+
Object.defineProperty(PublicApi.prototype, 'context', {enumerable: true});
|
|
192
116
|
|
|
193
|
-
|
|
194
|
-
|
|
117
|
+
class Test {
|
|
118
|
+
constructor(title, fn, contextRef, report) {
|
|
119
|
+
if (typeof title === 'function') {
|
|
120
|
+
contextRef = fn;
|
|
121
|
+
fn = title;
|
|
122
|
+
title = null;
|
|
123
|
+
}
|
|
195
124
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
125
|
+
assert.is(typeof fn, 'function', 'You must provide a callback');
|
|
126
|
+
|
|
127
|
+
this.title = title || fnName(fn) || '[anonymous]';
|
|
128
|
+
this.fn = isGeneratorFn(fn) ? co.wrap(fn) : fn;
|
|
129
|
+
this.assertions = [];
|
|
130
|
+
this.planCount = null;
|
|
131
|
+
this.duration = null;
|
|
132
|
+
this.assertError = undefined;
|
|
133
|
+
this.sync = true;
|
|
134
|
+
this.contextRef = contextRef;
|
|
135
|
+
this.report = report;
|
|
136
|
+
this.threwSync = false;
|
|
137
|
+
|
|
138
|
+
// TODO(jamestalmage): Make this an optional constructor arg instead of having Runner set it after the fact.
|
|
139
|
+
// metadata should just always exist, otherwise it requires a bunch of ugly checks all over the place.
|
|
140
|
+
this.metadata = {};
|
|
141
|
+
|
|
142
|
+
// Store the time point before test execution
|
|
143
|
+
// to calculate the total time spent in test
|
|
144
|
+
this._timeStart = null;
|
|
145
|
+
|
|
146
|
+
// Workaround for Babel giving anonymous functions a name
|
|
147
|
+
if (this.title === 'callee$0$0') {
|
|
148
|
+
this.title = '[anonymous]';
|
|
200
149
|
}
|
|
201
150
|
}
|
|
151
|
+
get assertCount() {
|
|
152
|
+
return this.assertions.length;
|
|
153
|
+
}
|
|
154
|
+
_assert(promise) {
|
|
155
|
+
if (isPromise(promise)) {
|
|
156
|
+
this.sync = false;
|
|
157
|
+
}
|
|
202
158
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
};
|
|
208
|
-
};
|
|
159
|
+
this.assertions.push(promise);
|
|
160
|
+
}
|
|
161
|
+
_setAssertError(err) {
|
|
162
|
+
throwsHelper(err);
|
|
209
163
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (this.metadata.callback) {
|
|
213
|
-
return this._end.bind(this);
|
|
164
|
+
if (this.assertError !== undefined) {
|
|
165
|
+
return;
|
|
214
166
|
}
|
|
215
167
|
|
|
216
|
-
|
|
168
|
+
this.assertError = err;
|
|
217
169
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if (err) {
|
|
222
|
-
if (!(err instanceof Error)) {
|
|
223
|
-
err = new assert.AssertionError({
|
|
224
|
-
actual: err,
|
|
225
|
-
message: 'Callback called with an error: ' + inspect(err, {depth: null}),
|
|
226
|
-
operator: 'callback'
|
|
227
|
-
});
|
|
170
|
+
plan(count, planStack) {
|
|
171
|
+
if (typeof count !== 'number') {
|
|
172
|
+
throw new TypeError('Expected a number');
|
|
228
173
|
}
|
|
229
174
|
|
|
230
|
-
this.
|
|
231
|
-
this.exit();
|
|
175
|
+
this.planCount = count;
|
|
232
176
|
|
|
233
|
-
|
|
177
|
+
// In case the `planCount` doesn't match `assertCount,
|
|
178
|
+
// we need the stack of this function to throw with a useful stack
|
|
179
|
+
this.planStack = planStack;
|
|
234
180
|
}
|
|
181
|
+
_run() {
|
|
182
|
+
let ret;
|
|
183
|
+
|
|
184
|
+
try {
|
|
185
|
+
ret = this.fn(this._publicApi());
|
|
186
|
+
} catch (err) {
|
|
187
|
+
this.threwSync = true;
|
|
188
|
+
|
|
189
|
+
if (err instanceof Error) {
|
|
190
|
+
this._setAssertError(err);
|
|
191
|
+
} else {
|
|
192
|
+
this._setAssertError(new assert.AssertionError({
|
|
193
|
+
actual: err,
|
|
194
|
+
message: `Non-error thrown with value: ${inspect(err, {depth: null})}`,
|
|
195
|
+
operator: 'catch'
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
235
199
|
|
|
236
|
-
|
|
237
|
-
this._setAssertError(new Error('.end() called more than once'));
|
|
238
|
-
return;
|
|
200
|
+
return ret;
|
|
239
201
|
}
|
|
202
|
+
promise() {
|
|
203
|
+
if (!this._promise) {
|
|
204
|
+
this._promise = {};
|
|
205
|
+
|
|
206
|
+
this._promise.promise = new Promise((resolve, reject) => {
|
|
207
|
+
this._promise.resolve = resolve;
|
|
208
|
+
this._promise.reject = reject;
|
|
209
|
+
}).tap(result => {
|
|
210
|
+
if (this.report) {
|
|
211
|
+
this.report(result);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
240
215
|
|
|
241
|
-
|
|
242
|
-
this.exit();
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
Test.prototype._checkPlanCount = function () {
|
|
246
|
-
if (this.assertError === undefined && this.planCount !== null && this.planCount !== this.assertions.length) {
|
|
247
|
-
this._setAssertError(new assert.AssertionError({
|
|
248
|
-
actual: this.assertions.length,
|
|
249
|
-
expected: this.planCount,
|
|
250
|
-
message: 'Planned for ' + this.planCount + plur(' assertion', this.planCount) + ', but got ' + this.assertions.length + '.',
|
|
251
|
-
operator: 'plan'
|
|
252
|
-
}));
|
|
253
|
-
|
|
254
|
-
this.assertError.stack = this.planStack;
|
|
216
|
+
return this._promise;
|
|
255
217
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
218
|
+
run() {
|
|
219
|
+
if (this.metadata.callback) {
|
|
220
|
+
this.sync = false;
|
|
221
|
+
}
|
|
260
222
|
|
|
261
|
-
|
|
223
|
+
this._timeStart = globals.now();
|
|
262
224
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
globals.clearTimeout(self._timeout);
|
|
225
|
+
// Wait until all assertions are complete
|
|
226
|
+
this._timeout = globals.setTimeout(() => {}, maxTimeout);
|
|
266
227
|
|
|
267
|
-
|
|
228
|
+
let ret = this._run();
|
|
229
|
+
let asyncType = 'promises';
|
|
268
230
|
|
|
269
|
-
if (
|
|
270
|
-
|
|
231
|
+
if (isObservable(ret)) {
|
|
232
|
+
asyncType = 'observables';
|
|
233
|
+
ret = observableToPromise(ret);
|
|
271
234
|
}
|
|
272
235
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
Promise.all(this.assertions)
|
|
277
|
-
.catch(function (err) {
|
|
278
|
-
self._setAssertError(err);
|
|
279
|
-
})
|
|
280
|
-
.finally(function () {
|
|
281
|
-
// calculate total time spent in test
|
|
282
|
-
self.duration = globals.now() - self._timeStart;
|
|
283
|
-
|
|
284
|
-
// stop infinite timer
|
|
285
|
-
globals.clearTimeout(self._timeout);
|
|
236
|
+
if (isPromise(ret)) {
|
|
237
|
+
this.sync = false;
|
|
286
238
|
|
|
287
|
-
|
|
239
|
+
if (this.metadata.callback) {
|
|
240
|
+
this._setAssertError(new Error(`Do not return ${asyncType} from tests declared via \`test.cb(...)\`, if you want to return a promise simply declare the test via \`test(...)\``));
|
|
241
|
+
}
|
|
288
242
|
|
|
289
|
-
|
|
290
|
-
|
|
243
|
+
// Convert to a Bluebird promise
|
|
244
|
+
return Promise.resolve(ret).then(
|
|
245
|
+
() => this.exit(),
|
|
246
|
+
err => {
|
|
247
|
+
if (!(err instanceof Error)) {
|
|
248
|
+
err = new assert.AssertionError({
|
|
249
|
+
actual: err,
|
|
250
|
+
message: `Promise rejected with: ${inspect(err, {depth: null})}`,
|
|
251
|
+
operator: 'promise'
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
this._setAssertError(err);
|
|
256
|
+
return this.exit();
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
}
|
|
291
260
|
|
|
292
|
-
|
|
293
|
-
|
|
261
|
+
if (this.metadata.callback && !this.threwSync) {
|
|
262
|
+
return this.promise().promise;
|
|
263
|
+
}
|
|
294
264
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
265
|
+
return this.exit();
|
|
266
|
+
}
|
|
267
|
+
_result() {
|
|
268
|
+
let reason = this.assertError;
|
|
269
|
+
let passed = reason === undefined;
|
|
298
270
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
this.skip = new SkipApi(test);
|
|
302
|
-
}
|
|
271
|
+
if (this.metadata.failing) {
|
|
272
|
+
passed = !passed;
|
|
303
273
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
if (event.originalMessage) {
|
|
309
|
-
event.error.message = event.originalMessage + ' ' + event.error.message;
|
|
274
|
+
if (passed) {
|
|
275
|
+
reason = undefined;
|
|
276
|
+
} else {
|
|
277
|
+
reason = new Error('Test was expected to fail, but succeeded, you should stop marking the test as failing');
|
|
310
278
|
}
|
|
311
279
|
}
|
|
312
|
-
this._test._setAssertError(event.error);
|
|
313
|
-
this._test._assert(null);
|
|
314
|
-
return null;
|
|
315
|
-
}
|
|
316
280
|
|
|
317
|
-
|
|
281
|
+
return {
|
|
282
|
+
passed,
|
|
283
|
+
result: this,
|
|
284
|
+
reason
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
get end() {
|
|
288
|
+
if (this.metadata.callback) {
|
|
289
|
+
return this._end.bind(this);
|
|
290
|
+
}
|
|
318
291
|
|
|
319
|
-
|
|
320
|
-
ret = observableToPromise(ret);
|
|
292
|
+
throw new Error('t.end is not supported in this context. To use t.end as a callback, you must use "callback mode" via `test.cb(testName, fn)`');
|
|
321
293
|
}
|
|
294
|
+
_end(err) {
|
|
295
|
+
if (err) {
|
|
296
|
+
if (!(err instanceof Error)) {
|
|
297
|
+
err = new assert.AssertionError({
|
|
298
|
+
actual: err,
|
|
299
|
+
message: 'Callback called with an error: ' + inspect(err, {depth: null}),
|
|
300
|
+
operator: 'callback'
|
|
301
|
+
});
|
|
302
|
+
}
|
|
322
303
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
err.originalMessage = event.originalMessage;
|
|
326
|
-
throw err;
|
|
327
|
-
});
|
|
304
|
+
this._setAssertError(err);
|
|
305
|
+
this.exit();
|
|
328
306
|
|
|
329
|
-
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
330
309
|
|
|
331
|
-
|
|
332
|
-
|
|
310
|
+
if (this.endCalled) {
|
|
311
|
+
this._setAssertError(new Error('.end() called more than once'));
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
333
314
|
|
|
334
|
-
|
|
315
|
+
this.endCalled = true;
|
|
316
|
+
this.exit();
|
|
317
|
+
}
|
|
318
|
+
_checkPlanCount() {
|
|
319
|
+
if (this.assertError === undefined && this.planCount !== null && this.planCount !== this.assertions.length) {
|
|
320
|
+
this._setAssertError(new assert.AssertionError({
|
|
321
|
+
actual: this.assertions.length,
|
|
322
|
+
expected: this.planCount,
|
|
323
|
+
message: `Planned for ${this.planCount} ${plur('assertion', this.planCount)}, but got ${this.assertions.length}.`,
|
|
324
|
+
operator: 'plan'
|
|
325
|
+
}));
|
|
335
326
|
|
|
336
|
-
|
|
337
|
-
}
|
|
327
|
+
this.assertError.stack = this.planStack;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
exit() {
|
|
331
|
+
this._checkPlanCount();
|
|
338
332
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
onError: onAssertionEvent
|
|
343
|
-
});
|
|
333
|
+
if (this.sync || this.threwSync) {
|
|
334
|
+
this.duration = globals.now() - this._timeStart;
|
|
335
|
+
globals.clearTimeout(this._timeout);
|
|
344
336
|
|
|
345
|
-
|
|
346
|
-
var limitBefore = Error.stackTraceLimit;
|
|
347
|
-
Error.stackTraceLimit = 1;
|
|
348
|
-
var obj = {};
|
|
349
|
-
Error.captureStackTrace(obj, plan);
|
|
350
|
-
Error.stackTraceLimit = limitBefore;
|
|
351
|
-
this._test.plan(ct, obj.stack);
|
|
352
|
-
};
|
|
337
|
+
const result = this._result();
|
|
353
338
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
'assertCount',
|
|
357
|
-
'title',
|
|
358
|
-
'end'
|
|
359
|
-
]
|
|
360
|
-
.forEach(function (name) {
|
|
361
|
-
Object.defineProperty(PublicApi.prototype, name, {
|
|
362
|
-
enumerable: false,
|
|
363
|
-
get: function () {
|
|
364
|
-
return this._test[name];
|
|
339
|
+
if (this.report) {
|
|
340
|
+
this.report(result);
|
|
365
341
|
}
|
|
366
|
-
});
|
|
367
|
-
});
|
|
368
342
|
|
|
369
|
-
|
|
370
|
-
Object.defineProperty(PublicApi.prototype, 'context', {
|
|
371
|
-
enumerable: true,
|
|
372
|
-
get: function () {
|
|
373
|
-
var contextRef = this._test.contextRef;
|
|
374
|
-
return contextRef && contextRef.context;
|
|
375
|
-
},
|
|
376
|
-
set: function (context) {
|
|
377
|
-
var contextRef = this._test.contextRef;
|
|
378
|
-
|
|
379
|
-
if (!contextRef) {
|
|
380
|
-
this._test._setAssertError(new Error('t.context is not available in ' + this._test.metadata.type + ' tests'));
|
|
381
|
-
return;
|
|
343
|
+
return result;
|
|
382
344
|
}
|
|
383
345
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
346
|
+
Promise.all(this.assertions)
|
|
347
|
+
.catch(err => {
|
|
348
|
+
this._setAssertError(err);
|
|
349
|
+
})
|
|
350
|
+
.finally(() => {
|
|
351
|
+
// Calculate total time spent in test
|
|
352
|
+
this.duration = globals.now() - this._timeStart;
|
|
387
353
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
354
|
+
// Stop infinite timer
|
|
355
|
+
globals.clearTimeout(this._timeout);
|
|
356
|
+
|
|
357
|
+
this._checkPlanCount();
|
|
391
358
|
|
|
392
|
-
|
|
393
|
-
|
|
359
|
+
this.promise().resolve(this._result());
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
return this.promise().promise;
|
|
363
|
+
}
|
|
364
|
+
_publicApi() {
|
|
365
|
+
return new PublicApi(this);
|
|
366
|
+
}
|
|
394
367
|
}
|
|
395
368
|
|
|
396
|
-
|
|
397
|
-
SkipApi.prototype[el] = skipFn;
|
|
398
|
-
});
|
|
369
|
+
module.exports = Test;
|