mocha 7.2.0 → 8.1.1

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 (46) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/bin/mocha +17 -2
  3. package/browser-entry.js +26 -9
  4. package/lib/browser/growl.js +2 -1
  5. package/lib/browser/highlight-tags.js +39 -0
  6. package/lib/browser/parse-query.js +24 -0
  7. package/lib/browser/progress.js +4 -0
  8. package/lib/browser/template.html +7 -5
  9. package/lib/cli/cli.js +2 -2
  10. package/lib/cli/collect-files.js +15 -9
  11. package/lib/cli/config.js +0 -1
  12. package/lib/cli/init.js +1 -2
  13. package/lib/cli/lookup-files.js +145 -0
  14. package/lib/cli/node-flags.js +2 -2
  15. package/lib/cli/options.js +11 -87
  16. package/lib/cli/run-helpers.js +54 -16
  17. package/lib/cli/run-option-metadata.js +4 -2
  18. package/lib/cli/run.js +61 -14
  19. package/lib/cli/watch-run.js +211 -51
  20. package/lib/context.js +0 -15
  21. package/lib/errors.js +26 -3
  22. package/lib/esm-utils.js +11 -6
  23. package/lib/hook.js +24 -0
  24. package/lib/interfaces/common.js +19 -11
  25. package/lib/mocha.js +137 -121
  26. package/lib/mocharc.json +0 -1
  27. package/lib/nodejs/buffered-worker-pool.js +174 -0
  28. package/lib/{growl.js → nodejs/growl.js} +3 -2
  29. package/lib/nodejs/parallel-buffered-runner.js +295 -0
  30. package/lib/nodejs/reporters/parallel-buffered.js +133 -0
  31. package/lib/nodejs/serializer.js +404 -0
  32. package/lib/nodejs/worker.js +154 -0
  33. package/lib/pending.js +4 -0
  34. package/lib/reporters/base.js +25 -12
  35. package/lib/reporters/landing.js +3 -3
  36. package/lib/reporters/tap.js +1 -2
  37. package/lib/reporters/xunit.js +3 -2
  38. package/lib/runnable.js +18 -30
  39. package/lib/runner.js +58 -64
  40. package/lib/suite.js +32 -24
  41. package/lib/test.js +28 -1
  42. package/lib/utils.js +19 -206
  43. package/mocha.js +25522 -18248
  44. package/mocha.js.map +1 -0
  45. package/package.json +52 -42
  46. package/lib/browser/tty.js +0 -13
@@ -9,7 +9,6 @@
9
9
  var Base = require('./base');
10
10
  var utils = require('../utils');
11
11
  var fs = require('fs');
12
- var mkdirp = require('mkdirp');
13
12
  var path = require('path');
14
13
  var errors = require('../errors');
15
14
  var createUnsupportedError = errors.createUnsupportedError;
@@ -62,7 +61,9 @@ function XUnit(runner, options) {
62
61
  throw createUnsupportedError('file output not supported in browser');
63
62
  }
64
63
 
65
- mkdirp.sync(path.dirname(options.reporterOptions.output));
64
+ fs.mkdirSync(path.dirname(options.reporterOptions.output), {
65
+ recursive: true
66
+ });
66
67
  self.fileStream = fs.createWriteStream(options.reporterOptions.output);
67
68
  }
68
69
 
package/lib/runnable.js CHANGED
@@ -11,6 +11,7 @@ var createMultipleDoneError = errors.createMultipleDoneError;
11
11
 
12
12
  /**
13
13
  * Save timer references to avoid Sinon interfering (see GH-237).
14
+ * @private
14
15
  */
15
16
  var Date = global.Date;
16
17
  var setTimeout = global.setTimeout;
@@ -36,7 +37,6 @@ function Runnable(title, fn) {
36
37
  this.sync = !this.async;
37
38
  this._timeout = 2000;
38
39
  this._slow = 75;
39
- this._enableTimeouts = true;
40
40
  this._retries = -1;
41
41
  this.reset();
42
42
  }
@@ -93,10 +93,12 @@ Runnable.prototype.timeout = function(ms) {
93
93
 
94
94
  // see #1652 for reasoning
95
95
  if (ms === range[0] || ms === range[1]) {
96
- this._enableTimeouts = false;
96
+ this._timeout = 0;
97
+ } else {
98
+ this._timeout = ms;
97
99
  }
98
- debug('timeout %d', ms);
99
- this._timeout = ms;
100
+ debug('timeout %d', this._timeout);
101
+
100
102
  if (this.timer) {
101
103
  this.resetTimeout();
102
104
  }
@@ -122,22 +124,6 @@ Runnable.prototype.slow = function(ms) {
122
124
  return this;
123
125
  };
124
126
 
125
- /**
126
- * Set and get whether timeout is `enabled`.
127
- *
128
- * @private
129
- * @param {boolean} enabled
130
- * @return {Runnable|boolean} enabled or Runnable instance.
131
- */
132
- Runnable.prototype.enableTimeouts = function(enabled) {
133
- if (!arguments.length) {
134
- return this._enableTimeouts;
135
- }
136
- debug('enableTimeouts %s', enabled);
137
- this._enableTimeouts = enabled;
138
- return this;
139
- };
140
-
141
127
  /**
142
128
  * Halt and mark as pending.
143
129
  *
@@ -239,14 +225,14 @@ Runnable.prototype.clearTimeout = function() {
239
225
  */
240
226
  Runnable.prototype.resetTimeout = function() {
241
227
  var self = this;
242
- var ms = this.timeout() || 1e9;
228
+ var ms = this.timeout();
243
229
 
244
- if (!this._enableTimeouts) {
230
+ if (ms === 0) {
245
231
  return;
246
232
  }
247
233
  this.clearTimeout();
248
234
  this.timer = setTimeout(function() {
249
- if (!self._enableTimeouts) {
235
+ if (self.timeout() === 0) {
250
236
  return;
251
237
  }
252
238
  self.callback(self._timeoutError(ms));
@@ -280,6 +266,8 @@ Runnable.prototype.run = function(fn) {
280
266
  var finished;
281
267
  var errorWasHandled = false;
282
268
 
269
+ if (this.isPending()) return fn();
270
+
283
271
  // Sometimes the ctx exists, but it is not runnable
284
272
  if (ctx && ctx.runnable) {
285
273
  ctx.runnable(this);
@@ -308,7 +296,7 @@ Runnable.prototype.run = function(fn) {
308
296
  self.clearTimeout();
309
297
  self.duration = new Date() - start;
310
298
  finished = true;
311
- if (!err && self.duration > ms && self._enableTimeouts) {
299
+ if (!err && self.duration > ms && ms > 0) {
312
300
  err = self._timeoutError(ms);
313
301
  }
314
302
  fn(err);
@@ -355,11 +343,7 @@ Runnable.prototype.run = function(fn) {
355
343
 
356
344
  // sync or promise-returning
357
345
  try {
358
- if (this.isPending()) {
359
- done();
360
- } else {
361
- callFn(this.fn);
362
- }
346
+ callFn(this.fn);
363
347
  } catch (err) {
364
348
  errorWasHandled = true;
365
349
  if (err instanceof Pending) {
@@ -460,7 +444,11 @@ var constants = utils.defineConstants(
460
444
  /**
461
445
  * Value of `state` prop when a `Runnable` has passed
462
446
  */
463
- STATE_PASSED: 'passed'
447
+ STATE_PASSED: 'passed',
448
+ /**
449
+ * Value of `state` prop when a `Runnable` has been skipped by user
450
+ */
451
+ STATE_PENDING: 'pending'
464
452
  }
465
453
  );
466
454
 
package/lib/runner.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  /**
4
4
  * Module dependencies.
5
+ * @private
5
6
  */
6
7
  var util = require('util');
7
8
  var EventEmitter = require('events').EventEmitter;
@@ -18,6 +19,7 @@ var HOOK_TYPE_BEFORE_ALL = Suite.constants.HOOK_TYPE_BEFORE_ALL;
18
19
  var EVENT_ROOT_SUITE_RUN = Suite.constants.EVENT_ROOT_SUITE_RUN;
19
20
  var STATE_FAILED = Runnable.constants.STATE_FAILED;
20
21
  var STATE_PASSED = Runnable.constants.STATE_PASSED;
22
+ var STATE_PENDING = Runnable.constants.STATE_PENDING;
21
23
  var dQuote = utils.dQuote;
22
24
  var sQuote = utils.sQuote;
23
25
  var stackFilter = utils.stackTraceFilter();
@@ -30,6 +32,7 @@ var createFatalError = errors.createFatalError;
30
32
 
31
33
  /**
32
34
  * Non-enumerable globals.
35
+ * @private
33
36
  * @readonly
34
37
  */
35
38
  var globals = [
@@ -193,6 +196,7 @@ inherits(Runner, EventEmitter);
193
196
  * @param {EventEmitter} target - The `EventEmitter`
194
197
  * @param {string} eventName - The event name
195
198
  * @param {string} fn - Listener function
199
+ * @private
196
200
  */
197
201
  Runner.prototype._addEventListener = function(target, eventName, listener) {
198
202
  target.on(eventName, listener);
@@ -204,6 +208,7 @@ Runner.prototype._addEventListener = function(target, eventName, listener) {
204
208
  * @param {EventEmitter} target - The `EventEmitter`
205
209
  * @param {string} eventName - The event anme
206
210
  * @param {function} listener - Listener function
211
+ * @private
207
212
  */
208
213
  Runner.prototype._removeEventListener = function(target, eventName, listener) {
209
214
  var eventListenerIndex = -1;
@@ -355,12 +360,27 @@ Runner.prototype.checkGlobals = function(test) {
355
360
  /**
356
361
  * Fail the given `test`.
357
362
  *
363
+ * If `test` is a hook, failures work in the following pattern:
364
+ * - If bail, run corresponding `after each` and `after` hooks,
365
+ * then exit
366
+ * - Failed `before` hook skips all tests in a suite and subsuites,
367
+ * but jumps to corresponding `after` hook
368
+ * - Failed `before each` hook skips remaining tests in a
369
+ * suite and jumps to corresponding `after each` hook,
370
+ * which is run only once
371
+ * - Failed `after` hook does not alter execution order
372
+ * - Failed `after each` hook skips remaining tests in a
373
+ * suite and subsuites, but executes other `after each`
374
+ * hooks
375
+ *
358
376
  * @private
359
- * @param {Test} test
377
+ * @param {Runnable} test
360
378
  * @param {Error} err
379
+ * @param {boolean} [force=false] - Whether to fail a pending test.
361
380
  */
362
- Runner.prototype.fail = function(test, err) {
363
- if (test.isPending()) {
381
+ Runner.prototype.fail = function(test, err, force) {
382
+ force = force === true;
383
+ if (test.isPending() && !force) {
364
384
  return;
365
385
  }
366
386
  if (this.state === constants.STATE_STOPPED) {
@@ -391,44 +411,6 @@ Runner.prototype.fail = function(test, err) {
391
411
  this.emit(constants.EVENT_TEST_FAIL, test, err);
392
412
  };
393
413
 
394
- /**
395
- * Fail the given `hook` with `err`.
396
- *
397
- * Hook failures work in the following pattern:
398
- * - If bail, run corresponding `after each` and `after` hooks,
399
- * then exit
400
- * - Failed `before` hook skips all tests in a suite and subsuites,
401
- * but jumps to corresponding `after` hook
402
- * - Failed `before each` hook skips remaining tests in a
403
- * suite and jumps to corresponding `after each` hook,
404
- * which is run only once
405
- * - Failed `after` hook does not alter execution order
406
- * - Failed `after each` hook skips remaining tests in a
407
- * suite and subsuites, but executes other `after each`
408
- * hooks
409
- *
410
- * @private
411
- * @param {Hook} hook
412
- * @param {Error} err
413
- */
414
- Runner.prototype.failHook = function(hook, err) {
415
- hook.originalTitle = hook.originalTitle || hook.title;
416
- if (hook.ctx && hook.ctx.currentTest) {
417
- hook.title =
418
- hook.originalTitle + ' for ' + dQuote(hook.ctx.currentTest.title);
419
- } else {
420
- var parentTitle;
421
- if (hook.parent.title) {
422
- parentTitle = hook.parent.title;
423
- } else {
424
- parentTitle = hook.parent.root ? '{root}' : '';
425
- }
426
- hook.title = hook.originalTitle + ' in ' + dQuote(parentTitle);
427
- }
428
-
429
- this.fail(hook, err);
430
- };
431
-
432
414
  /**
433
415
  * Run hook `name` callbacks and then invoke `fn()`.
434
416
  *
@@ -457,17 +439,19 @@ Runner.prototype.hook = function(name, fn) {
457
439
  hook.ctx.currentTest = self.test;
458
440
  }
459
441
 
442
+ setHookTitle(hook);
443
+
460
444
  hook.allowUncaught = self.allowUncaught;
461
445
 
462
446
  self.emit(constants.EVENT_HOOK_BEGIN, hook);
463
447
 
464
448
  if (!hook.listeners('error').length) {
465
449
  self._addEventListener(hook, 'error', function(err) {
466
- self.failHook(hook, err);
450
+ self.fail(hook, err);
467
451
  });
468
452
  }
469
453
 
470
- hook.run(function(err) {
454
+ hook.run(function cbHookRun(err) {
471
455
  var testError = hook.error();
472
456
  if (testError) {
473
457
  self.fail(self.test, testError);
@@ -493,21 +477,39 @@ Runner.prototype.hook = function(name, fn) {
493
477
  suite.suites.forEach(function(suite) {
494
478
  suite.pending = true;
495
479
  });
480
+ hooks = [];
496
481
  } else {
497
482
  hook.pending = false;
498
483
  var errForbid = createUnsupportedError('`this.skip` forbidden');
499
- self.failHook(hook, errForbid);
484
+ self.fail(hook, errForbid);
500
485
  return fn(errForbid);
501
486
  }
502
487
  } else if (err) {
503
- self.failHook(hook, err);
488
+ self.fail(hook, err);
504
489
  // stop executing hooks, notify callee of hook err
505
490
  return fn(err);
506
491
  }
507
492
  self.emit(constants.EVENT_HOOK_END, hook);
508
493
  delete hook.ctx.currentTest;
494
+ setHookTitle(hook);
509
495
  next(++i);
510
496
  });
497
+
498
+ function setHookTitle(hook) {
499
+ hook.originalTitle = hook.originalTitle || hook.title;
500
+ if (hook.ctx && hook.ctx.currentTest) {
501
+ hook.title =
502
+ hook.originalTitle + ' for ' + dQuote(hook.ctx.currentTest.title);
503
+ } else {
504
+ var parentTitle;
505
+ if (hook.parent.title) {
506
+ parentTitle = hook.parent.title;
507
+ } else {
508
+ parentTitle = hook.parent.root ? '{root}' : '';
509
+ }
510
+ hook.title = hook.originalTitle + ' in ' + dQuote(parentTitle);
511
+ }
512
+ }
511
513
  }
512
514
 
513
515
  Runner.immediately(function() {
@@ -707,10 +709,9 @@ Runner.prototype.runTests = function(suite, fn) {
707
709
  // static skip, no hooks are executed
708
710
  if (test.isPending()) {
709
711
  if (self.forbidPending) {
710
- test.isPending = alwaysFalse;
711
- self.fail(test, new Error('Pending test forbidden'));
712
- delete test.isPending;
712
+ self.fail(test, new Error('Pending test forbidden'), true);
713
713
  } else {
714
+ test.state = STATE_PENDING;
714
715
  self.emit(constants.EVENT_TEST_PENDING, test);
715
716
  }
716
717
  self.emit(constants.EVENT_TEST_END, test);
@@ -723,10 +724,9 @@ Runner.prototype.runTests = function(suite, fn) {
723
724
  // conditional skip within beforeEach
724
725
  if (test.isPending()) {
725
726
  if (self.forbidPending) {
726
- test.isPending = alwaysFalse;
727
- self.fail(test, new Error('Pending test forbidden'));
728
- delete test.isPending;
727
+ self.fail(test, new Error('Pending test forbidden'), true);
729
728
  } else {
729
+ test.state = STATE_PENDING;
730
730
  self.emit(constants.EVENT_TEST_PENDING, test);
731
731
  }
732
732
  self.emit(constants.EVENT_TEST_END, test);
@@ -747,10 +747,9 @@ Runner.prototype.runTests = function(suite, fn) {
747
747
  // conditional skip within it
748
748
  if (test.pending) {
749
749
  if (self.forbidPending) {
750
- test.isPending = alwaysFalse;
751
- self.fail(test, new Error('Pending test forbidden'));
752
- delete test.isPending;
750
+ self.fail(test, new Error('Pending test forbidden'), true);
753
751
  } else {
752
+ test.state = STATE_PENDING;
754
753
  self.emit(constants.EVENT_TEST_PENDING, test);
755
754
  }
756
755
  self.emit(constants.EVENT_TEST_END, test);
@@ -787,10 +786,6 @@ Runner.prototype.runTests = function(suite, fn) {
787
786
  next();
788
787
  };
789
788
 
790
- function alwaysFalse() {
791
- return false;
792
- }
793
-
794
789
  /**
795
790
  * Run the given `suite` and invoke the callback `fn()` when complete.
796
791
  *
@@ -901,7 +896,7 @@ Runner.prototype._uncaught = function(err) {
901
896
  return;
902
897
  }
903
898
  // browser does not exit script when throwing in global.onerror()
904
- if (this.allowUncaught && !process.browser) {
899
+ if (this.allowUncaught && !utils.isBrowser()) {
905
900
  debug('uncaught(): bubbling exception due to --allow-uncaught');
906
901
  throw err;
907
902
  }
@@ -957,9 +952,7 @@ Runner.prototype._uncaught = function(err) {
957
952
  } else if (runnable.isPending()) {
958
953
  debug('uncaught(): pending Runnable wound up failing!');
959
954
  // report 'pending test' retrospectively as failed
960
- runnable.isPending = alwaysFalse;
961
- this.fail(runnable, err);
962
- delete runnable.isPending;
955
+ this.fail(runnable, err, true);
963
956
  return;
964
957
  }
965
958
 
@@ -981,10 +974,11 @@ Runner.prototype._uncaught = function(err) {
981
974
  *
982
975
  * @public
983
976
  * @memberof Runner
984
- * @param {Function} fn
977
+ * @param {Function} fn - Callback when finished
978
+ * @param {{files: string[], options: Options}} [opts] - For subclasses
985
979
  * @return {Runner} Runner instance.
986
980
  */
987
- Runner.prototype.run = function(fn) {
981
+ Runner.prototype.run = function(fn, opts) {
988
982
  var self = this;
989
983
  var rootSuite = this.suite;
990
984
 
package/lib/suite.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  /**
4
4
  * Module dependencies.
5
+ * @private
5
6
  */
6
7
  var EventEmitter = require('events').EventEmitter;
7
8
  var Hook = require('./hook');
@@ -69,7 +70,6 @@ function Suite(title, parentContext, isRoot) {
69
70
  this._afterEach = [];
70
71
  this._afterAll = [];
71
72
  this._timeout = 2000;
72
- this._enableTimeouts = true;
73
73
  this._slow = 75;
74
74
  this._bail = false;
75
75
  this._onlyTests = [];
@@ -121,7 +121,6 @@ Suite.prototype.clone = function() {
121
121
  suite.root = this.root;
122
122
  suite.timeout(this.timeout());
123
123
  suite.retries(this.retries());
124
- suite.enableTimeouts(this.enableTimeouts());
125
124
  suite.slow(this.slow());
126
125
  suite.bail(this.bail());
127
126
  return suite;
@@ -139,12 +138,15 @@ Suite.prototype.timeout = function(ms) {
139
138
  if (!arguments.length) {
140
139
  return this._timeout;
141
140
  }
142
- if (ms.toString() === '0') {
143
- this._enableTimeouts = false;
144
- }
145
141
  if (typeof ms === 'string') {
146
142
  ms = milliseconds(ms);
147
143
  }
144
+
145
+ // Clamp to range
146
+ var INT_MAX = Math.pow(2, 31) - 1;
147
+ var range = [0, INT_MAX];
148
+ ms = utils.clamp(ms, range);
149
+
148
150
  debug('timeout %d', ms);
149
151
  this._timeout = parseInt(ms, 10);
150
152
  return this;
@@ -166,22 +168,6 @@ Suite.prototype.retries = function(n) {
166
168
  return this;
167
169
  };
168
170
 
169
- /**
170
- * Set or get timeout to `enabled`.
171
- *
172
- * @private
173
- * @param {boolean} enabled
174
- * @return {Suite|boolean} self or enabled
175
- */
176
- Suite.prototype.enableTimeouts = function(enabled) {
177
- if (!arguments.length) {
178
- return this._enableTimeouts;
179
- }
180
- debug('enableTimeouts %s', enabled);
181
- this._enableTimeouts = enabled;
182
- return this;
183
- };
184
-
185
171
  /**
186
172
  * Set or get slow `ms` or short-hand such as "2s".
187
173
  *
@@ -238,7 +224,6 @@ Suite.prototype._createHook = function(title, fn) {
238
224
  hook.parent = this;
239
225
  hook.timeout(this.timeout());
240
226
  hook.retries(this.retries());
241
- hook.enableTimeouts(this.enableTimeouts());
242
227
  hook.slow(this.slow());
243
228
  hook.ctx = this.ctx;
244
229
  hook.file = this.file;
@@ -353,7 +338,6 @@ Suite.prototype.addSuite = function(suite) {
353
338
  suite.root = false;
354
339
  suite.timeout(this.timeout());
355
340
  suite.retries(this.retries());
356
- suite.enableTimeouts(this.enableTimeouts());
357
341
  suite.slow(this.slow());
358
342
  suite.bail(this.bail());
359
343
  this.suites.push(suite);
@@ -372,7 +356,6 @@ Suite.prototype.addTest = function(test) {
372
356
  test.parent = this;
373
357
  test.timeout(this.timeout());
374
358
  test.retries(this.retries());
375
- test.enableTimeouts(this.enableTimeouts());
376
359
  test.slow(this.slow());
377
360
  test.ctx = this.ctx;
378
361
  this.tests.push(test);
@@ -509,6 +492,15 @@ Suite.prototype.appendOnlySuite = function(suite) {
509
492
  this._onlySuites.push(suite);
510
493
  };
511
494
 
495
+ /**
496
+ * Marks a suite to be `only`.
497
+ *
498
+ * @private
499
+ */
500
+ Suite.prototype.markOnly = function() {
501
+ this.parent && this.parent.appendOnlySuite(this);
502
+ };
503
+
512
504
  /**
513
505
  * Adds a test to the list of tests marked `only`.
514
506
  *
@@ -575,6 +567,22 @@ Suite.prototype.cleanReferences = function cleanReferences() {
575
567
  }
576
568
  };
577
569
 
570
+ /**
571
+ * Returns an object suitable for IPC.
572
+ * Functions are represented by keys beginning with `$$`.
573
+ * @private
574
+ * @returns {Object}
575
+ */
576
+ Suite.prototype.serialize = function serialize() {
577
+ return {
578
+ _bail: this._bail,
579
+ $$fullTitle: this.fullTitle(),
580
+ $$isPending: this.isPending(),
581
+ root: this.root,
582
+ title: this.title
583
+ };
584
+ };
585
+
578
586
  var constants = utils.defineConstants(
579
587
  /**
580
588
  * {@link Suite}-related constants.
package/lib/test.js CHANGED
@@ -70,7 +70,6 @@ Test.prototype.clone = function() {
70
70
  var test = new Test(this.title, this.fn);
71
71
  test.timeout(this.timeout());
72
72
  test.slow(this.slow());
73
- test.enableTimeouts(this.enableTimeouts());
74
73
  test.retries(this.retries());
75
74
  test.currentRetry(this.currentRetry());
76
75
  test.retriedTest(this.retriedTest() || this);
@@ -80,3 +79,31 @@ Test.prototype.clone = function() {
80
79
  test.ctx = this.ctx;
81
80
  return test;
82
81
  };
82
+
83
+ /**
84
+ * Returns an minimal object suitable for transmission over IPC.
85
+ * Functions are represented by keys beginning with `$$`.
86
+ * @private
87
+ * @returns {Object}
88
+ */
89
+ Test.prototype.serialize = function serialize() {
90
+ return {
91
+ $$currentRetry: this._currentRetry,
92
+ $$fullTitle: this.fullTitle(),
93
+ $$isPending: this.pending,
94
+ $$retriedTest: this._retriedTest || null,
95
+ $$slow: this._slow,
96
+ $$titlePath: this.titlePath(),
97
+ body: this.body,
98
+ duration: this.duration,
99
+ err: this.err,
100
+ parent: {
101
+ $$fullTitle: this.parent.fullTitle()
102
+ },
103
+ speed: this.speed,
104
+ state: this.state,
105
+ title: this.title,
106
+ type: this.type,
107
+ file: this.file
108
+ };
109
+ };