UNPKG

6.6 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', {
4 value: true
5});
6exports.default = void 0;
7
8var _assert = require('assert');
9
10var _ExpectationFailed = _interopRequireDefault(
11 require('../ExpectationFailed')
12);
13
14var _assertionErrorMessage = _interopRequireDefault(
15 require('../assertionErrorMessage')
16);
17
18var _expectationResultFactory = _interopRequireDefault(
19 require('../expectationResultFactory')
20);
21
22function _interopRequireDefault(obj) {
23 return obj && obj.__esModule ? obj : {default: obj};
24}
25
26function _defineProperty(obj, key, value) {
27 if (key in obj) {
28 Object.defineProperty(obj, key, {
29 value: value,
30 enumerable: true,
31 configurable: true,
32 writable: true
33 });
34 } else {
35 obj[key] = value;
36 }
37 return obj;
38}
39
40class Spec {
41 static isPendingSpecException(e) {
42 return !!(
43 e &&
44 e.toString &&
45 e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1
46 );
47 }
48
49 constructor(attrs) {
50 _defineProperty(this, 'id', void 0);
51
52 _defineProperty(this, 'description', void 0);
53
54 _defineProperty(this, 'resultCallback', void 0);
55
56 _defineProperty(this, 'queueableFn', void 0);
57
58 _defineProperty(this, 'beforeAndAfterFns', void 0);
59
60 _defineProperty(this, 'userContext', void 0);
61
62 _defineProperty(this, 'onStart', void 0);
63
64 _defineProperty(this, 'getSpecName', void 0);
65
66 _defineProperty(this, 'queueRunnerFactory', void 0);
67
68 _defineProperty(this, 'throwOnExpectationFailure', void 0);
69
70 _defineProperty(this, 'initError', void 0);
71
72 _defineProperty(this, 'result', void 0);
73
74 _defineProperty(this, 'disabled', void 0);
75
76 _defineProperty(this, 'currentRun', void 0);
77
78 _defineProperty(this, 'markedTodo', void 0);
79
80 _defineProperty(this, 'markedPending', void 0);
81
82 _defineProperty(this, 'expand', void 0);
83
84 this.resultCallback = attrs.resultCallback || function () {};
85
86 this.id = attrs.id;
87 this.description = attrs.description || '';
88 this.queueableFn = attrs.queueableFn;
89
90 this.beforeAndAfterFns =
91 attrs.beforeAndAfterFns ||
92 function () {
93 return {
94 befores: [],
95 afters: []
96 };
97 };
98
99 this.userContext =
100 attrs.userContext ||
101 function () {
102 return {};
103 };
104
105 this.onStart = attrs.onStart || function () {};
106
107 this.getSpecName =
108 attrs.getSpecName ||
109 function () {
110 return '';
111 };
112
113 this.queueRunnerFactory = attrs.queueRunnerFactory || function () {};
114
115 this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
116 this.initError = new Error();
117 this.initError.name = ''; // Without this line v8 stores references to all closures
118 // in the stack in the Error object. This line stringifies the stack
119 // property to allow garbage-collecting objects on the stack
120 // https://crbug.com/v8/7142
121
122 this.initError.stack = this.initError.stack;
123 this.queueableFn.initError = this.initError; // @ts-expect-error
124
125 this.result = {
126 id: this.id,
127 description: this.description,
128 fullName: this.getFullName(),
129 failedExpectations: [],
130 passedExpectations: [],
131 pendingReason: '',
132 testPath: attrs.getTestPath()
133 };
134 }
135
136 addExpectationResult(passed, data, isError) {
137 const expectationResult = (0, _expectationResultFactory.default)(
138 data,
139 this.initError
140 );
141
142 if (passed) {
143 this.result.passedExpectations.push(expectationResult);
144 } else {
145 this.result.failedExpectations.push(expectationResult);
146
147 if (this.throwOnExpectationFailure && !isError) {
148 throw new _ExpectationFailed.default();
149 }
150 }
151 }
152
153 execute(onComplete, enabled) {
154 const self = this;
155 this.onStart(this);
156
157 if (
158 !this.isExecutable() ||
159 this.markedPending ||
160 this.markedTodo ||
161 enabled === false
162 ) {
163 complete(enabled);
164 return;
165 }
166
167 const fns = this.beforeAndAfterFns();
168 const allFns = fns.befores.concat(this.queueableFn).concat(fns.afters);
169 this.currentRun = this.queueRunnerFactory({
170 queueableFns: allFns,
171
172 onException() {
173 // @ts-expect-error
174 self.onException.apply(self, arguments);
175 },
176
177 userContext: this.userContext(),
178 setTimeout,
179 clearTimeout,
180 fail: () => {}
181 });
182 this.currentRun.then(() => complete(true));
183
184 function complete(enabledAgain) {
185 self.result.status = self.status(enabledAgain);
186 self.resultCallback(self.result);
187
188 if (onComplete) {
189 onComplete();
190 }
191 }
192 }
193
194 cancel() {
195 if (this.currentRun) {
196 this.currentRun.cancel();
197 }
198 }
199
200 onException(error) {
201 if (Spec.isPendingSpecException(error)) {
202 this.pend(extractCustomPendingMessage(error));
203 return;
204 }
205
206 if (error instanceof _ExpectationFailed.default) {
207 return;
208 }
209
210 this.addExpectationResult(
211 false,
212 {
213 matcherName: '',
214 passed: false,
215 expected: '',
216 actual: '',
217 error: this.isAssertionError(error)
218 ? (0, _assertionErrorMessage.default)(error, {
219 expand: this.expand
220 })
221 : error
222 },
223 true
224 );
225 }
226
227 disable() {
228 this.disabled = true;
229 }
230
231 pend(message) {
232 this.markedPending = true;
233
234 if (message) {
235 this.result.pendingReason = message;
236 }
237 }
238
239 todo() {
240 this.markedTodo = true;
241 }
242
243 getResult() {
244 this.result.status = this.status();
245 return this.result;
246 }
247
248 status(enabled) {
249 if (this.disabled || enabled === false) {
250 return 'disabled';
251 }
252
253 if (this.markedTodo) {
254 return 'todo';
255 }
256
257 if (this.markedPending) {
258 return 'pending';
259 }
260
261 if (this.result.failedExpectations.length > 0) {
262 return 'failed';
263 } else {
264 return 'passed';
265 }
266 }
267
268 isExecutable() {
269 return !this.disabled;
270 }
271
272 getFullName() {
273 return this.getSpecName(this);
274 }
275
276 isAssertionError(error) {
277 return (
278 error instanceof _assert.AssertionError ||
279 (error && error.name === _assert.AssertionError.name)
280 );
281 }
282}
283
284exports.default = Spec;
285
286_defineProperty(Spec, 'pendingSpecExceptionMessage', void 0);
287
288Spec.pendingSpecExceptionMessage = '=> marked Pending';
289
290const extractCustomPendingMessage = function (e) {
291 const fullMessage = e.toString();
292 const boilerplateStart = fullMessage.indexOf(
293 Spec.pendingSpecExceptionMessage
294 );
295 const boilerplateEnd =
296 boilerplateStart + Spec.pendingSpecExceptionMessage.length;
297 return fullMessage.substr(boilerplateEnd);
298};