From 8cce85c5f431a3d20591f22fbbbba4948553bd7b Mon Sep 17 00:00:00 2001 From: Offroaders123 <65947371+Offroaders123@users.noreply.github.com> Date: Sun, 5 Oct 2025 21:38:08 -0700 Subject: [PATCH 1/4] ES6 Class Declarations (Part One) Related to #5025 This is the (nearly) complete migration to the ES6 class syntax, from the original constructor function implementation. This was originally intended to include changes for two more files, but they both were having challenges with passing tests. Those were `lib/mocha.js`, and `lib/reporters/base.js`. As they seemingly will require more formatting than simple syntax changes, I am leaving them for a separate commit. --- lib/context.js | 28 ++++++----- lib/hook.js | 27 ++++++----- lib/pending.js | 11 +++-- lib/reporters/doc.js | 20 ++++---- lib/reporters/dot.js | 20 ++++---- lib/reporters/html.js | 70 +++++++++++++++------------- lib/reporters/json-stream.js | 20 ++++---- lib/reporters/json.js | 20 ++++---- lib/reporters/landing.js | 20 ++++---- lib/reporters/list.js | 20 ++++---- lib/reporters/markdown.js | 20 ++++---- lib/reporters/min.js | 20 ++++---- lib/reporters/nyan.js | 46 +++++++++--------- lib/reporters/progress.js | 20 ++++---- lib/reporters/spec.js | 20 ++++---- lib/reporters/tap.js | 55 ++++++++++------------ lib/reporters/xunit.js | 32 ++++++------- lib/runnable.js | 80 ++++++++++++++++---------------- lib/runner.js | 66 +++++++++++++------------- lib/suite.js | 90 ++++++++++++++++++------------------ lib/test.js | 29 ++++++------ 21 files changed, 369 insertions(+), 365 deletions(-) diff --git a/lib/context.js b/lib/context.js index 247a1c17aa..2883331b1e 100644 --- a/lib/context.js +++ b/lib/context.js @@ -7,18 +7,15 @@ /** * @module Context */ -/** - * Expose `Context`. - */ - -module.exports = Context; /** * Initialize a new `Context`. - * + */ +class Context { +/** * @private */ -function Context() {} +constructor() {} /** * Set or get the context `Runnable` to `runnable`. @@ -27,7 +24,7 @@ function Context() {} * @param {Runnable} runnable * @return {Context} context */ -Context.prototype.runnable = function (runnable) { +runnable(runnable) { if (!arguments.length) { return this._runnable; } @@ -42,7 +39,7 @@ Context.prototype.runnable = function (runnable) { * @param {number} ms * @return {Context} self */ -Context.prototype.timeout = function (ms) { +timeout(ms) { if (!arguments.length) { return this.runnable().timeout(); } @@ -57,7 +54,7 @@ Context.prototype.timeout = function (ms) { * @param {number} ms * @return {Context} self */ -Context.prototype.slow = function (ms) { +slow(ms) { if (!arguments.length) { return this.runnable().slow(); } @@ -71,7 +68,7 @@ Context.prototype.slow = function (ms) { * @private * @throws Pending */ -Context.prototype.skip = function () { +skip() { this.runnable().skip(); }; @@ -82,10 +79,17 @@ Context.prototype.skip = function () { * @param {number} n * @return {Context} self */ -Context.prototype.retries = function (n) { +retries(n) { if (!arguments.length) { return this.runnable().retries(); } this.runnable().retries(n); return this; }; +} + +/** + * Expose `Context`. + */ + +module.exports = Context; diff --git a/lib/hook.js b/lib/hook.js index 862271e735..9c3c0f0c95 100644 --- a/lib/hook.js +++ b/lib/hook.js @@ -1,38 +1,34 @@ 'use strict'; var Runnable = require('./runnable'); -const {inherits, constants} = require('./utils'); +const {constants} = require('./utils'); const {MOCHA_ID_PROP_NAME} = constants; /** * Expose `Hook`. */ -module.exports = Hook; - /** * Initialize a new `Hook` with the given `title` and callback `fn` * * @class * @extends Runnable + */ +class Hook extends Runnable { +/** * @param {String} title * @param {Function} fn */ -function Hook(title, fn) { - Runnable.call(this, title, fn); +constructor(title, fn) { + super(title, fn); this.type = 'hook'; } -/** - * Inherit from `Runnable.prototype`. - */ -inherits(Hook, Runnable); - /** * Resets the state for a next run. */ -Hook.prototype.reset = function () { - Runnable.prototype.reset.call(this); +reset() { + super.reset(); delete this._error; }; @@ -44,7 +40,7 @@ Hook.prototype.reset = function () { * @param {Error} err * @return {Error} */ -Hook.prototype.error = function (err) { +error(err) { if (!arguments.length) { err = this._error; this._error = null; @@ -60,7 +56,7 @@ Hook.prototype.error = function (err) { * @private * @returns {Object} */ -Hook.prototype.serialize = function serialize() { +serialize() { return { $$currentRetry: this.currentRetry(), $$fullTitle: this.fullTitle(), @@ -87,3 +83,6 @@ Hook.prototype.serialize = function serialize() { [MOCHA_ID_PROP_NAME]: this.id }; }; +} + +module.exports = Hook; diff --git a/lib/pending.js b/lib/pending.js index cf9cc84a0e..6db90a7178 100644 --- a/lib/pending.js +++ b/lib/pending.js @@ -4,13 +4,16 @@ @module Pending */ -module.exports = Pending; - /** * Initialize a new `Pending` error with the given message. - * +*/ +class Pending { +/** * @param {string} message */ -function Pending(message) { +constructor(message) { this.message = message; } +} + +module.exports = Pending; diff --git a/lib/reporters/doc.js b/lib/reporters/doc.js index f018525eee..d4a7d7fd91 100644 --- a/lib/reporters/doc.js +++ b/lib/reporters/doc.js @@ -19,12 +19,6 @@ var EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL; var EVENT_SUITE_BEGIN = constants.EVENT_SUITE_BEGIN; var EVENT_SUITE_END = constants.EVENT_SUITE_END; -/** - * Expose `Doc`. - */ - -exports = module.exports = Doc; - /** * Constructs a new `Doc` reporter instance. * @@ -32,11 +26,14 @@ exports = module.exports = Doc; * @class * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class Doc extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function Doc(runner, options) { - Base.call(this, runner, options); +constructor(runner, options) { + super(runner, options); var indents = 2; @@ -96,5 +93,12 @@ function Doc(runner, options) { ); }); } +} + +/** + * Expose `Doc`. + */ + +exports = module.exports = Doc; Doc.description = 'HTML documentation'; diff --git a/lib/reporters/dot.js b/lib/reporters/dot.js index 46e8b811b0..c0a27eacfc 100644 --- a/lib/reporters/dot.js +++ b/lib/reporters/dot.js @@ -12,7 +12,6 @@ */ var Base = require('./base'); -var inherits = require('../utils').inherits; var constants = require('../runner').constants; var EVENT_TEST_PASS = constants.EVENT_TEST_PASS; var EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL; @@ -20,12 +19,6 @@ var EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN; var EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING; var EVENT_RUN_END = constants.EVENT_RUN_END; -/** - * Expose `Dot`. - */ - -exports = module.exports = Dot; - /** * Constructs a new `Dot` reporter instance. * @@ -33,11 +26,14 @@ exports = module.exports = Dot; * @class * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class Dot extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function Dot(runner, options) { - Base.call(this, runner, options); +constructor(runner, options) { + super(runner, options); var self = this; var width = (Base.window.width * 0.75) | 0; @@ -77,10 +73,12 @@ function Dot(runner, options) { self.epilogue(); }); } +} /** - * Inherit from `Base.prototype`. + * Expose `Dot`. */ -inherits(Dot, Base); + +exports = module.exports = Dot; Dot.description = 'dot matrix representation'; diff --git a/lib/reporters/html.js b/lib/reporters/html.js index 77e0abd35a..f6608a8350 100644 --- a/lib/reporters/html.js +++ b/lib/reporters/html.js @@ -29,12 +29,6 @@ var escape = utils.escape; var Date = global.Date; -/** - * Expose `HTML`. - */ - -exports = module.exports = HTML; - /** * Stats template: Result, progress, passes, failures, and duration. */ @@ -57,11 +51,14 @@ var playIcon = '‣'; * @class * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class HTML extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function HTML(runner, options) { - Base.call(this, runner, options); +constructor(runner, options) { + super(runner, options); var self = this; var stats = this.stats; @@ -279,34 +276,12 @@ function HTML(runner, options) { } } -/** - * Makes a URL, preserving querystring ("search") parameters. - * - * @param {string} s - * @return {string} A new URL. - */ -function makeUrl(s) { - var search = window.location.search; - - // Remove previous {grep, fgrep, invert} query parameters if present - if (search) { - search = search.replace(/[?&](?:f?grep|invert)=[^&\s]*/g, '').replace(/^&/, '?'); - } - - return ( - window.location.pathname + - (search ? search + '&' : '?') + - 'grep=' + - encodeURIComponent(s) - ); -} - /** * Provide suite URL. * * @param {Object} [suite] */ -HTML.prototype.suiteURL = function (suite) { +suiteURL(suite) { return makeUrl('^' + escapeRe(suite.fullTitle()) + ' '); }; @@ -315,7 +290,7 @@ HTML.prototype.suiteURL = function (suite) { * * @param {Object} [test] */ -HTML.prototype.testURL = function (test) { +testURL(test) { return makeUrl('^' + escapeRe(test.fullTitle()) + '$'); }; @@ -325,7 +300,7 @@ HTML.prototype.testURL = function (test) { * @param {HTMLLIElement} el * @param {string} contents */ -HTML.prototype.addCodeToggle = function (el, contents) { +addCodeToggle(el, contents) { var h2 = el.getElementsByTagName('h2')[0]; on(h2, 'click', function () { @@ -336,6 +311,29 @@ HTML.prototype.addCodeToggle = function (el, contents) { el.appendChild(pre); pre.style.display = 'none'; }; +} + +/** + * Makes a URL, preserving querystring ("search") parameters. + * + * @param {string} s + * @return {string} A new URL. + */ +function makeUrl(s) { + var search = window.location.search; + + // Remove previous {grep, fgrep, invert} query parameters if present + if (search) { + search = search.replace(/[?&](?:f?grep|invert)=[^&\s]*/g, '').replace(/^&/, '?'); + } + + return ( + window.location.pathname + + (search ? search + '&' : '?') + + 'grep=' + + encodeURIComponent(s) + ); +} /** * Display error `msg`. @@ -420,4 +418,10 @@ function on(el, event, fn) { } } +/** + * Expose `HTML`. + */ + +exports = module.exports = HTML; + HTML.browserOnly = true; diff --git a/lib/reporters/json-stream.js b/lib/reporters/json-stream.js index a57e4a35dc..4525fcc0ad 100644 --- a/lib/reporters/json-stream.js +++ b/lib/reporters/json-stream.js @@ -19,12 +19,6 @@ var EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL; var EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN; var EVENT_RUN_END = constants.EVENT_RUN_END; -/** - * Expose `JSONStream`. - */ - -exports = module.exports = JSONStream; - /** * Constructs a new `JSONStream` reporter instance. * @@ -32,11 +26,14 @@ exports = module.exports = JSONStream; * @class * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class JSONStream extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function JSONStream(runner, options) { - Base.call(this, runner, options); +constructor(runner, options) { + super(runner, options); var self = this; var total = runner.total; @@ -60,6 +57,7 @@ function JSONStream(runner, options) { writeEvent(['end', self.stats]); }); } +} /** * Writes Mocha event to reporter output stream. @@ -90,4 +88,10 @@ function clean(test) { }; } +/** + * Expose `JSONStream`. + */ + +exports = module.exports = JSONStream; + JSONStream.description = 'newline delimited JSON events'; diff --git a/lib/reporters/json.js b/lib/reporters/json.js index f4e1a9d93e..dd596fa599 100644 --- a/lib/reporters/json.js +++ b/lib/reporters/json.js @@ -23,12 +23,6 @@ var EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL; var EVENT_TEST_END = constants.EVENT_TEST_END; var EVENT_RUN_END = constants.EVENT_RUN_END; -/** - * Expose `JSON`. - */ - -exports = module.exports = JSONReporter; - /** * Constructs a new `JSON` reporter instance. * @@ -36,11 +30,14 @@ exports = module.exports = JSONReporter; * @class JSON * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class JSONReporter extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function JSONReporter(runner, options = {}) { - Base.call(this, runner, options); +constructor(runner, options = {}) { + super(runner, options); var self = this; var tests = []; @@ -99,6 +96,7 @@ function JSONReporter(runner, options = {}) { } }); } +} /** * Return a plain-object representation of `test` @@ -164,4 +162,10 @@ function errorJSON(err) { return res; } +/** + * Expose `JSON`. + */ + +exports = module.exports = JSONReporter; + JSONReporter.description = 'single JSON object'; diff --git a/lib/reporters/landing.js b/lib/reporters/landing.js index e30e497a58..cb7caa1737 100644 --- a/lib/reporters/landing.js +++ b/lib/reporters/landing.js @@ -12,7 +12,6 @@ */ var Base = require('./base'); -var inherits = require('../utils').inherits; var constants = require('../runner').constants; var EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN; var EVENT_RUN_END = constants.EVENT_RUN_END; @@ -22,12 +21,6 @@ var STATE_FAILED = require('../runnable').constants.STATE_FAILED; var cursor = Base.cursor; var color = Base.color; -/** - * Expose `Landing`. - */ - -exports = module.exports = Landing; - /** * Airplane color. */ @@ -53,11 +46,14 @@ Base.colors.runway = 90; * @class * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class Landing extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function Landing(runner, options) { - Base.call(this, runner, options); +constructor(runner, options) { + super(runner, options); var self = this; var width = (Base.window.width * 0.75) | 0; @@ -112,10 +108,12 @@ function Landing(runner, options) { }); }); } +} /** - * Inherit from `Base.prototype`. + * Expose `Landing`. */ -inherits(Landing, Base); + +exports = module.exports = Landing; Landing.description = 'Unicode landing strip'; diff --git a/lib/reporters/list.js b/lib/reporters/list.js index 66dd997dd7..716d9721d8 100644 --- a/lib/reporters/list.js +++ b/lib/reporters/list.js @@ -12,7 +12,6 @@ */ var Base = require('./base'); -var inherits = require('../utils').inherits; var constants = require('../runner').constants; var EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN; var EVENT_RUN_END = constants.EVENT_RUN_END; @@ -23,12 +22,6 @@ var EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING; var color = Base.color; var cursor = Base.cursor; -/** - * Expose `List`. - */ - -exports = module.exports = List; - /** * Constructs a new `List` reporter instance. * @@ -36,11 +29,14 @@ exports = module.exports = List; * @class * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class List extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function List(runner, options) { - Base.call(this, runner, options); +constructor(runner, options) { + super(runner, options); var self = this; var n = 0; @@ -74,10 +70,12 @@ function List(runner, options) { runner.once(EVENT_RUN_END, self.epilogue.bind(self)); } +} /** - * Inherit from `Base.prototype`. + * Expose `List`. */ -inherits(List, Base); + +exports = module.exports = List; List.description = 'like "spec" reporter but flat'; diff --git a/lib/reporters/markdown.js b/lib/reporters/markdown.js index 2e196d6ba4..5a83fd1f5f 100644 --- a/lib/reporters/markdown.js +++ b/lib/reporters/markdown.js @@ -25,12 +25,6 @@ var EVENT_TEST_PASS = constants.EVENT_TEST_PASS; var SUITE_PREFIX = '$'; -/** - * Expose `Markdown`. - */ - -exports = module.exports = Markdown; - /** * Constructs a new `Markdown` reporter instance. * @@ -38,11 +32,14 @@ exports = module.exports = Markdown; * @class * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class Markdown extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function Markdown(runner, options) { - Base.call(this, runner, options); +constructor(runner, options) { + super(runner, options); var level = 0; var buf = ''; @@ -113,5 +110,12 @@ function Markdown(runner, options) { process.stdout.write(buf); }); } +} + +/** + * Expose `Markdown`. + */ + +exports = module.exports = Markdown; Markdown.description = 'GitHub Flavored Markdown'; diff --git a/lib/reporters/min.js b/lib/reporters/min.js index 6571ec6fea..1fae96294e 100644 --- a/lib/reporters/min.js +++ b/lib/reporters/min.js @@ -12,17 +12,10 @@ */ var Base = require('./base'); -var inherits = require('../utils').inherits; var constants = require('../runner').constants; var EVENT_RUN_END = constants.EVENT_RUN_END; var EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN; -/** - * Expose `Min`. - */ - -exports = module.exports = Min; - /** * Constructs a new `Min` reporter instance. * @@ -33,11 +26,14 @@ exports = module.exports = Min; * @class * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class Min extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function Min(runner, options) { - Base.call(this, runner, options); +constructor(runner, options) { + super(runner, options); runner.on(EVENT_RUN_BEGIN, function () { // clear screen @@ -48,10 +44,12 @@ function Min(runner, options) { runner.once(EVENT_RUN_END, this.epilogue.bind(this)); } +} /** - * Inherit from `Base.prototype`. + * Expose `Min`. */ -inherits(Min, Base); + +exports = module.exports = Min; Min.description = 'essentially just a summary'; diff --git a/lib/reporters/nyan.js b/lib/reporters/nyan.js index aaeaf42309..3503db5f78 100644 --- a/lib/reporters/nyan.js +++ b/lib/reporters/nyan.js @@ -13,19 +13,12 @@ var Base = require('./base'); var constants = require('../runner').constants; -var inherits = require('../utils').inherits; var EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN; var EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING; var EVENT_TEST_PASS = constants.EVENT_TEST_PASS; var EVENT_RUN_END = constants.EVENT_RUN_END; var EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL; -/** - * Expose `Dot`. - */ - -exports = module.exports = NyanCat; - /** * Constructs a new `Nyan` reporter instance. * @@ -33,11 +26,14 @@ exports = module.exports = NyanCat; * @class Nyan * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class NyanCat extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function NyanCat(runner, options) { - Base.call(this, runner, options); +constructor(runner, options) { + super(runner, options); var self = this; var width = (Base.window.width * 0.75) | 0; @@ -77,18 +73,13 @@ function NyanCat(runner, options) { }); } -/** - * Inherit from `Base.prototype`. - */ -inherits(NyanCat, Base); - /** * Draw the nyan cat * * @private */ -NyanCat.prototype.draw = function () { +draw() { this.appendRainbow(); this.drawScoreboard(); this.drawRainbow(); @@ -103,7 +94,7 @@ NyanCat.prototype.draw = function () { * @private */ -NyanCat.prototype.drawScoreboard = function () { +drawScoreboard() { var stats = this.stats; function draw(type, n) { @@ -126,7 +117,7 @@ NyanCat.prototype.drawScoreboard = function () { * @private */ -NyanCat.prototype.appendRainbow = function () { +appendRainbow() { var segment = this.tick ? '_' : '-'; var rainbowified = this.rainbowify(segment); @@ -145,7 +136,7 @@ NyanCat.prototype.appendRainbow = function () { * @private */ -NyanCat.prototype.drawRainbow = function () { +drawRainbow() { var self = this; this.trajectories.forEach(function (line) { @@ -162,7 +153,7 @@ NyanCat.prototype.drawRainbow = function () { * * @private */ -NyanCat.prototype.drawNyanCat = function () { +drawNyanCat() { var self = this; var startWidth = this.scoreboardWidth + this.trajectories[0].length; var dist = '\u001b[' + startWidth + 'C'; @@ -198,7 +189,7 @@ NyanCat.prototype.drawNyanCat = function () { * @return {string} */ -NyanCat.prototype.face = function () { +face() { var stats = this.stats; if (stats.failures) { return '( x .x)'; @@ -217,7 +208,7 @@ NyanCat.prototype.face = function () { * @param {number} n */ -NyanCat.prototype.cursorUp = function (n) { +cursorUp(n) { process.stdout.write('\u001b[' + n + 'A'); }; @@ -228,7 +219,7 @@ NyanCat.prototype.cursorUp = function (n) { * @param {number} n */ -NyanCat.prototype.cursorDown = function (n) { +cursorDown(n) { process.stdout.write('\u001b[' + n + 'B'); }; @@ -238,7 +229,7 @@ NyanCat.prototype.cursorDown = function (n) { * @private * @return {Array} */ -NyanCat.prototype.generateColors = function () { +generateColors() { var colors = []; for (var i = 0; i < 6 * 7; i++) { @@ -260,7 +251,7 @@ NyanCat.prototype.generateColors = function () { * @param {string} str * @return {string} */ -NyanCat.prototype.rainbowify = function (str) { +rainbowify(str) { if (!Base.useColors) { return str; } @@ -268,5 +259,12 @@ NyanCat.prototype.rainbowify = function (str) { this.colorIndex += 1; return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m'; }; +} + +/** + * Expose `Dot`. + */ + +exports = module.exports = NyanCat; NyanCat.description = '"nyan cat"'; diff --git a/lib/reporters/progress.js b/lib/reporters/progress.js index e25f4f9121..b8a91a24ab 100644 --- a/lib/reporters/progress.js +++ b/lib/reporters/progress.js @@ -16,16 +16,9 @@ var constants = require('../runner').constants; var EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN; var EVENT_TEST_END = constants.EVENT_TEST_END; var EVENT_RUN_END = constants.EVENT_RUN_END; -var inherits = require('../utils').inherits; var color = Base.color; var cursor = Base.cursor; -/** - * Expose `Progress`. - */ - -exports = module.exports = Progress; - /** * General progress bar color. */ @@ -39,11 +32,14 @@ Base.colors.progress = 90; * @class * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class Progress extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function Progress(runner, options) { - Base.call(this, runner, options); +constructor(runner, options) { + super(runner, options); var self = this; var width = (Base.window.width * 0.5) | 0; @@ -100,10 +96,12 @@ function Progress(runner, options) { self.epilogue(); }); } +} /** - * Inherit from `Base.prototype`. + * Expose `Progress`. */ -inherits(Progress, Base); + +exports = module.exports = Progress; Progress.description = 'a progress bar'; diff --git a/lib/reporters/spec.js b/lib/reporters/spec.js index 3d4dd1af4f..0c694f6052 100644 --- a/lib/reporters/spec.js +++ b/lib/reporters/spec.js @@ -21,15 +21,8 @@ var EVENT_SUITE_END = constants.EVENT_SUITE_END; var EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL; var EVENT_TEST_PASS = constants.EVENT_TEST_PASS; var EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING; -var inherits = require('../utils').inherits; var color = Base.color; -/** - * Expose `Spec`. - */ - -exports = module.exports = Spec; - /** * Constructs a new `Spec` reporter instance. * @@ -37,11 +30,14 @@ exports = module.exports = Spec; * @class * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class Spec extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function Spec(runner, options) { - Base.call(this, runner, options); +constructor(runner, options) { + super(runner, options); var self = this; var indents = 0; @@ -96,10 +92,12 @@ function Spec(runner, options) { runner.once(EVENT_RUN_END, self.epilogue.bind(self)); } +} /** - * Inherit from `Base.prototype`. + * Expose `Spec`. */ -inherits(Spec, Base); + +exports = module.exports = Spec; Spec.description = 'hierarchical & verbose [default]'; diff --git a/lib/reporters/tap.js b/lib/reporters/tap.js index 43e53b8270..788b41dd6a 100644 --- a/lib/reporters/tap.js +++ b/lib/reporters/tap.js @@ -21,15 +21,8 @@ var EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN; var EVENT_RUN_END = constants.EVENT_RUN_END; var EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING; var EVENT_TEST_END = constants.EVENT_TEST_END; -var inherits = require('../utils').inherits; var sprintf = util.format; -/** - * Expose `TAP`. - */ - -exports = module.exports = TAP; - /** * Constructs a new `TAP` reporter instance. * @@ -37,11 +30,14 @@ exports = module.exports = TAP; * @class * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class TAP extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function TAP(runner, options) { - Base.call(this, runner, options); +constructor(runner, options) { + super(runner, options); var self = this; var n = 1; @@ -79,11 +75,13 @@ function TAP(runner, options) { self._producer.writeEpilogue(runner.stats); }); } +} /** - * Inherit from `Base.prototype`. + * Expose `TAP`. */ -inherits(TAP, Base); + +exports = module.exports = TAP; /** * Returns a TAP-safe title of `test`. @@ -143,14 +141,14 @@ function createProducer(tapVersion) { * @private * @constructor */ -function TAPProducer() {} +class TAPProducer { /** * Writes the TAP version to reporter output stream. * * @abstract */ -TAPProducer.prototype.writeVersion = function () {}; +writeVersion() {}; /** * Writes the plan to reporter output stream. @@ -158,7 +156,7 @@ TAPProducer.prototype.writeVersion = function () {}; * @abstract * @param {number} ntests - Number of tests that are planned to run. */ -TAPProducer.prototype.writePlan = function (ntests) { +writePlan(ntests) { println('%d..%d', 1, ntests); }; @@ -169,7 +167,7 @@ TAPProducer.prototype.writePlan = function (ntests) { * @param {number} n - Index of test that passed. * @param {Test} test - Instance containing test information. */ -TAPProducer.prototype.writePass = function (n, test) { +writePass(n, test) { println('ok %d %s', n, title(test)); }; @@ -180,7 +178,7 @@ TAPProducer.prototype.writePass = function (n, test) { * @param {number} n - Index of test that was skipped. * @param {Test} test - Instance containing test information. */ -TAPProducer.prototype.writePending = function (n, test) { +writePending(n, test) { println('ok %d %s # SKIP -', n, title(test)); }; @@ -191,7 +189,7 @@ TAPProducer.prototype.writePending = function (n, test) { * @param {number} n - Index of test that failed. * @param {Test} test - Instance containing test information. */ -TAPProducer.prototype.writeFail = function (n, test) { +writeFail(n, test) { println('not ok %d %s', n, title(test)); }; @@ -201,7 +199,7 @@ TAPProducer.prototype.writeFail = function (n, test) { * @abstract * @param {Object} stats - Object containing run statistics. */ -TAPProducer.prototype.writeEpilogue = function (stats) { +writeEpilogue(stats) { // :TBD: Why is this not counting pending tests? println('# tests ' + (stats.passes + stats.failures)); println('# pass ' + stats.passes); @@ -209,6 +207,7 @@ TAPProducer.prototype.writeEpilogue = function (stats) { println('# fail ' + stats.failures); this.writePlan(stats.passes + stats.failures + stats.pending); }; +} /** * @summary @@ -222,7 +221,9 @@ TAPProducer.prototype.writeEpilogue = function (stats) { * @extends TAPProducer * @see {@link https://testanything.org/tap-specification.html|Specification} */ -function TAP12Producer() { +class TAP12Producer extends TAPProducer { +constructor() { + super(); /** * Writes that test failed to reporter output stream, with error formatting. * @override @@ -237,11 +238,7 @@ function TAP12Producer() { } }; } - -/** - * Inherit from `TAPProducer.prototype`. - */ -inherits(TAP12Producer, TAPProducer); +} /** * @summary @@ -255,7 +252,9 @@ inherits(TAP12Producer, TAPProducer); * @extends TAPProducer * @see {@link https://testanything.org/tap-version-13-specification.html|Specification} */ -function TAP13Producer() { +class TAP13Producer extends TAPProducer { +constructor() { + super(); /** * Writes the TAP version to reporter output stream. * @override @@ -289,10 +288,6 @@ function TAP13Producer() { return Array(level + 1).join(' '); } } - -/** - * Inherit from `TAPProducer.prototype`. - */ -inherits(TAP13Producer, TAPProducer); +} TAP.description = 'TAP-compatible output'; diff --git a/lib/reporters/xunit.js b/lib/reporters/xunit.js index 77b71366f1..7d94574c7f 100644 --- a/lib/reporters/xunit.js +++ b/lib/reporters/xunit.js @@ -24,7 +24,6 @@ var EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL; var EVENT_RUN_END = constants.EVENT_RUN_END; var EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING; var STATE_FAILED = require('../runnable').constants.STATE_FAILED; -var inherits = utils.inherits; var escape = utils.escape; /** @@ -32,12 +31,6 @@ var escape = utils.escape; */ var Date = global.Date; -/** - * Expose `XUnit`. - */ - -exports = module.exports = XUnit; - /** * Constructs a new `XUnit` reporter instance. * @@ -45,11 +38,14 @@ exports = module.exports = XUnit; * @class * @memberof Mocha.reporters * @extends Mocha.reporters.Base + */ +class XUnit extends Base { +/** * @param {Runner} runner - Instance triggers reporter actions. * @param {Object} [options] - runner options */ -function XUnit(runner, options) { - Base.call(this, runner, options); +constructor(runner, options) { + super(runner, options); var stats = this.stats; var tests = []; @@ -117,18 +113,13 @@ function XUnit(runner, options) { }); } -/** - * Inherit from `Base.prototype`. - */ -inherits(XUnit, Base); - /** * Override done to close the stream (if it's a file). * * @param failures * @param {Function} fn */ -XUnit.prototype.done = function (failures, fn) { +done(failures, fn) { if (this.fileStream) { this.fileStream.end(function () { fn(failures); @@ -143,7 +134,7 @@ XUnit.prototype.done = function (failures, fn) { * * @param {string} line */ -XUnit.prototype.write = function (line) { +write(line) { if (this.fileStream) { this.fileStream.write(line + '\n'); } else if (typeof process === 'object' && process.stdout) { @@ -158,7 +149,7 @@ XUnit.prototype.write = function (line) { * * @param {Test} test */ -XUnit.prototype.test = function (test, options) { +test(test, options) { Base.useColors = false; var attrs = { @@ -193,6 +184,7 @@ XUnit.prototype.test = function (test, options) { this.write(tag('testcase', attrs, true)); } }; +} /** * HTML tag helper. @@ -229,4 +221,10 @@ function testFilePath(filepath, options) { return filepath; } +/** + * Expose `XUnit`. + */ + +exports = module.exports = XUnit; + XUnit.description = 'XUnit-compatible XML output'; diff --git a/lib/runnable.js b/lib/runnable.js index d1d9e5f6cf..1621c7aa5d 100644 --- a/lib/runnable.js +++ b/lib/runnable.js @@ -22,8 +22,6 @@ var toString = Object.prototype.toString; var MAX_TIMEOUT = Math.pow(2, 31) - 1; -module.exports = Runnable; - // "Additional properties" doc comment added for hosted docs (mochajs.org/api) /** * Initialize a new `Runnable` with the given `title` and callback `fn`. @@ -32,10 +30,14 @@ module.exports = Runnable; * @class * @extends external:EventEmitter * @public + */ +class Runnable extends EventEmitter { +/** * @param {String} title * @param {Function} fn */ -function Runnable(title, fn) { +constructor(title, fn) { + super(); this.title = title; this.fn = fn; this.body = (fn || '').toString(); @@ -53,15 +55,10 @@ function Runnable(title, fn) { this.reset(); } -/** - * Inherit from `EventEmitter.prototype`. - */ -utils.inherits(Runnable, EventEmitter); - /** * Resets the state initially or for a next run. */ -Runnable.prototype.reset = function () { +reset() { this.timedOut = false; this._currentRetry = 0; this.pending = false; @@ -90,7 +87,7 @@ Runnable.prototype.reset = function () { * @returns {Runnable} this * @chainable */ -Runnable.prototype.timeout = function (ms) { +timeout(ms) { if (!arguments.length) { return this._timeout; } @@ -123,7 +120,7 @@ Runnable.prototype.timeout = function (ms) { * @param {number|string} ms * @return {Runnable|number} ms or Runnable instance. */ -Runnable.prototype.slow = function (ms) { +slow(ms) { if (!arguments.length || typeof ms === 'undefined') { return this._slow; } @@ -141,7 +138,7 @@ Runnable.prototype.slow = function (ms) { * @memberof Mocha.Runnable * @public */ -Runnable.prototype.skip = function () { +skip() { this.pending = true; throw new Pending('sync skip; aborting execution'); }; @@ -151,7 +148,7 @@ Runnable.prototype.skip = function () { * * @private */ -Runnable.prototype.isPending = function () { +isPending() { return this.pending || (this.parent && this.parent.isPending()); }; @@ -160,7 +157,7 @@ Runnable.prototype.isPending = function () { * @return {boolean} * @private */ -Runnable.prototype.isFailed = function () { +isFailed() { return !this.isPending() && this.state === constants.STATE_FAILED; }; @@ -169,7 +166,7 @@ Runnable.prototype.isFailed = function () { * @return {boolean} * @private */ -Runnable.prototype.isPassed = function () { +isPassed() { return !this.isPending() && this.state === constants.STATE_PASSED; }; @@ -178,7 +175,7 @@ Runnable.prototype.isPassed = function () { * * @private */ -Runnable.prototype.retries = function (n) { +retries(n) { if (!arguments.length) { return this._retries; } @@ -190,7 +187,7 @@ Runnable.prototype.retries = function (n) { * * @private */ -Runnable.prototype.currentRetry = function (n) { +currentRetry(n) { if (!arguments.length) { return this._currentRetry; } @@ -205,7 +202,7 @@ Runnable.prototype.currentRetry = function (n) { * @public * @return {string} */ -Runnable.prototype.fullTitle = function () { +fullTitle() { return this.titlePath().join(' '); }; @@ -216,7 +213,7 @@ Runnable.prototype.fullTitle = function () { * @public * @return {string[]} */ -Runnable.prototype.titlePath = function () { +titlePath() { return this.parent.titlePath().concat([this.title]); }; @@ -225,7 +222,7 @@ Runnable.prototype.titlePath = function () { * * @private */ -Runnable.prototype.clearTimeout = function () { +clearTimeout() { clearTimeout(this.timer); }; @@ -234,7 +231,7 @@ Runnable.prototype.clearTimeout = function () { * * @private */ -Runnable.prototype.resetTimeout = function () { +resetTimeout() { var self = this; var ms = this.timeout() || MAX_TIMEOUT; @@ -254,7 +251,7 @@ Runnable.prototype.resetTimeout = function () { * @private * @param {string[]} globals */ -Runnable.prototype.globals = function (globals) { +globals(globals) { if (!arguments.length) { return this._allowedGlobals; } @@ -267,7 +264,7 @@ Runnable.prototype.globals = function (globals) { * @param {Function} fn * @private */ -Runnable.prototype.run = function (fn) { +run(fn) { var self = this; var start = new Date(); var ctx = this.ctx; @@ -423,7 +420,7 @@ Runnable.prototype.run = function (fn) { * @returns {Error} a "timeout" error * @private */ -Runnable.prototype._timeoutError = function (ms) { +_timeoutError(ms) { let msg = `Timeout of ${ms}ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.`; if (this.file) { msg += ' (' + this.file + ')'; @@ -431,6 +428,23 @@ Runnable.prototype._timeoutError = function (ms) { return createTimeoutError(msg, ms, this.file); }; +/** + * Given `value`, return identity if truthy, otherwise create an "invalid exception" error and return that. + * @param {*} [value] - Value to return, if present + * @returns {*|Error} `value`, otherwise an `Error` + * @private + */ +static toValueOrError(value) { + return ( + value || + createInvalidExceptionError( + 'Runnable failed with falsy or undefined exception. Please throw an Error instead.', + value + ) + ); +}; +} + var constants = utils.defineConstants( /** * {@link Runnable}-related constants. @@ -457,20 +471,6 @@ var constants = utils.defineConstants( } ); -/** - * Given `value`, return identity if truthy, otherwise create an "invalid exception" error and return that. - * @param {*} [value] - Value to return, if present - * @returns {*|Error} `value`, otherwise an `Error` - * @private - */ -Runnable.toValueOrError = function (value) { - return ( - value || - createInvalidExceptionError( - 'Runnable failed with falsy or undefined exception. Please throw an Error instead.', - value - ) - ); -}; - Runnable.constants = constants; + +module.exports = Runnable; diff --git a/lib/runner.js b/lib/runner.js index 555e919bf6..f5ab21d031 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -238,15 +238,6 @@ class Runner extends EventEmitter { } }; } -} - -/** - * Wrapper for setImmediate, process.nextTick, or browser polyfill. - * - * @param {Function} fn - * @private - */ -Runner.immediately = global.setImmediate || process.nextTick; /** * Replacement for `target.on(eventName, listener)` that does bookkeeping to remove them when this runner instance is disposed. @@ -255,7 +246,7 @@ Runner.immediately = global.setImmediate || process.nextTick; * @param {string} fn - Listener function * @private */ -Runner.prototype._addEventListener = function (target, eventName, listener) { +_addEventListener(target, eventName, listener) { debug( '_addEventListener(): adding for event %s; %d current listeners', eventName, @@ -292,7 +283,7 @@ Runner.prototype._addEventListener = function (target, eventName, listener) { * @param {function} listener - Listener function * @private */ -Runner.prototype._removeEventListener = function (target, eventName, listener) { +_removeEventListener(target, eventName, listener) { target.removeListener(eventName, listener); if (this._eventListeners.has(target)) { @@ -316,7 +307,7 @@ Runner.prototype._removeEventListener = function (target, eventName, listener) { * Removes all event handlers set during a run on this instance. * Remark: this does _not_ clean/dispose the tests or suites themselves. */ -Runner.prototype.dispose = function () { +dispose() { this.removeAllListeners(); this._eventListeners.forEach((targetListeners, target) => { targetListeners.forEach((targetEventListeners, eventName) => { @@ -338,7 +329,7 @@ Runner.prototype.dispose = function () { * @param {boolean} invert * @return {Runner} Runner instance. */ -Runner.prototype.grep = function (re, invert) { +grep(re, invert) { debug('grep(): setting to %s', re); this._grep = re; this._invert = invert; @@ -355,7 +346,7 @@ Runner.prototype.grep = function (re, invert) { * @param {Suite} suite * @return {number} */ -Runner.prototype.grepTotal = function (suite) { +grepTotal(suite) { var self = this; var total = 0; @@ -378,7 +369,7 @@ Runner.prototype.grepTotal = function (suite) { * @return {Array} * @private */ -Runner.prototype.globalProps = function () { +globalProps() { var props = Object.keys(global); // non-enumerables @@ -400,7 +391,7 @@ Runner.prototype.globalProps = function () { * @param {Array} arr * @return {Runner} Runner instance. */ -Runner.prototype.globals = function (arr) { +globals(arr) { if (!arguments.length) { return this._globals; } @@ -414,7 +405,7 @@ Runner.prototype.globals = function (arr) { * * @private */ -Runner.prototype.checkGlobals = function (test) { +checkGlobals(test) { if (!this.checkLeaks) { return; } @@ -462,7 +453,7 @@ Runner.prototype.checkGlobals = function (test) { * @param {Error} err * @param {boolean} [force=false] - Whether to fail a pending test. */ -Runner.prototype.fail = function (test, err, force) { +fail(test, err, force) { force = force === true; if (test.isPending() && !force) { return; @@ -514,7 +505,7 @@ Runner.prototype.fail = function (test, err, force) { * @param {Function} fn */ -Runner.prototype.hook = function (name, fn) { +hook(name, fn) { if (this._opts.dryRun) return fn(); var suite = this.suite; @@ -622,7 +613,7 @@ Runner.prototype.hook = function (name, fn) { * @param {Array} suites * @param {Function} fn */ -Runner.prototype.hooks = function (name, suites, fn) { +hooks(name, suites, fn) { var self = this; var orig = this.suite; @@ -655,7 +646,7 @@ Runner.prototype.hooks = function (name, suites, fn) { * @param {Function} fn * @private */ -Runner.prototype.hookUp = function (name, fn) { +hookUp(name, fn) { var suites = [this.suite].concat(this.parents()).reverse(); this.hooks(name, suites, fn); }; @@ -667,7 +658,7 @@ Runner.prototype.hookUp = function (name, fn) { * @param {Function} fn * @private */ -Runner.prototype.hookDown = function (name, fn) { +hookDown(name, fn) { var suites = [this.suite].concat(this.parents()); this.hooks(name, suites, fn); }; @@ -679,7 +670,7 @@ Runner.prototype.hookDown = function (name, fn) { * @return {Array} * @private */ -Runner.prototype.parents = function () { +parents() { var suite = this.suite; var suites = []; while (suite.parent) { @@ -695,7 +686,7 @@ Runner.prototype.parents = function () { * @param {Function} fn * @private */ -Runner.prototype.runTest = function (fn) { +runTest(fn) { if (this._opts.dryRun) return Runner.immediately(fn); var self = this; @@ -729,7 +720,7 @@ Runner.prototype.runTest = function (fn) { * @param {Suite} suite * @param {Function} fn */ -Runner.prototype.runTests = function (suite, fn) { +runTests(suite, fn) { var self = this; var tests = suite.tests.slice(); var test; @@ -890,7 +881,7 @@ Runner.prototype.runTests = function (suite, fn) { * @param {Suite} suite * @param {Function} fn */ -Runner.prototype.runSuite = function (suite, fn) { +runSuite(suite, fn) { var i = 0; var self = this; var total = this.grepTotal(suite); @@ -977,7 +968,7 @@ Runner.prototype.runSuite = function (suite, fn) { * @param {Error} err - Some uncaught error * @private */ -Runner.prototype._uncaught = function (err) { +_uncaught(err) { // this is defensive to prevent future developers from mis-calling this function. // it's more likely that it'd be called with the incorrect context--say, the global // `process` object--than it would to be called with a context that is not a "subclass" @@ -1075,7 +1066,7 @@ Runner.prototype._uncaught = function (err) { * @param {RunnerOptions} [opts] - For subclasses * @returns {Runner} Runner instance. */ -Runner.prototype.run = function (fn, opts = {}) { +run(fn, opts = {}) { var rootSuite = this.suite; var options = opts.options || {}; @@ -1168,7 +1159,7 @@ Runner.prototype.run = function (fn, opts = {}) { * } * } */ -Runner.prototype.linkPartialObjects = function () { +linkPartialObjects() { return this; }; @@ -1180,7 +1171,7 @@ Runner.prototype.linkPartialObjects = function () { * @param {Object} [opts] - Options for {@link Runner#run} * @returns {Promise} Failure count */ -Runner.prototype.runAsync = async function runAsync(opts = {}) { +async runAsync(opts = {}) { return new Promise(resolve => { this.run(resolve, opts); }); @@ -1193,7 +1184,7 @@ Runner.prototype.runAsync = async function runAsync(opts = {}) { * @public * @return {Runner} Runner instance. */ -Runner.prototype.abort = function () { +abort() { debug('abort(): aborting'); this._abort = true; @@ -1207,7 +1198,7 @@ Runner.prototype.abort = function () { * @public * @returns {false} */ -Runner.prototype.isParallelMode = function isParallelMode() { +isParallelMode() { return false; }; @@ -1221,9 +1212,18 @@ Runner.prototype.isParallelMode = function isParallelMode() { * @chainable * @abstract */ -Runner.prototype.workerReporter = function () { +workerReporter() { throw createUnsupportedError('workerReporter() not supported in serial mode'); }; +} + +/** + * Wrapper for setImmediate, process.nextTick, or browser polyfill. + * + * @param {Function} fn + * @private + */ +Runner.immediately = global.setImmediate || process.nextTick; /** * Filter leaks with the given globals flagged as `ok`. diff --git a/lib/suite.js b/lib/suite.js index b321349f27..3af06a7b61 100644 --- a/lib/suite.js +++ b/lib/suite.js @@ -16,7 +16,6 @@ var { constants: utilsConstants, defineConstants, getMochaID, - inherits, isString } = require('./utils'); const debug = require('debug')('mocha:suite'); @@ -26,10 +25,14 @@ const errors = require('./errors'); const {MOCHA_ID_PROP_NAME} = utilsConstants; /** - * Expose `Suite`. + * Constructs a new `Suite` instance with the given `title`, `ctx`, and `isRoot`. + * + * @public + * @class + * @extends EventEmitter + * @see {@link https://nodejs.org/api/events.html#events_class_eventemitter|EventEmitter} */ - -exports = module.exports = Suite; +class Suite extends EventEmitter { /** * Create a new `Suite` with the given `title` and parent `Suite`. @@ -39,7 +42,7 @@ exports = module.exports = Suite; * @param {string} title - Title * @return {Suite} */ -Suite.create = function (parent, title) { +static create(parent, title) { var suite = new Suite(title, parent.ctx); suite.parent = parent; title = suite.fullTitle(); @@ -48,17 +51,12 @@ Suite.create = function (parent, title) { }; /** - * Constructs a new `Suite` instance with the given `title`, `ctx`, and `isRoot`. - * - * @public - * @class - * @extends EventEmitter - * @see {@link https://nodejs.org/api/events.html#events_class_eventemitter|EventEmitter} * @param {string} title - Suite title. * @param {Context} parentContext - Parent context instance. * @param {boolean} [isRoot=false] - Whether this is the root suite. */ -function Suite(title, parentContext, isRoot) { +constructor(title, parentContext, isRoot) { + super(); if (!isString(title)) { throw errors.createInvalidArgumentTypeError( 'Suite argument "title" must be a string. Received type "' + @@ -97,15 +95,10 @@ function Suite(title, parentContext, isRoot) { this.reset(); } -/** - * Inherit from `EventEmitter.prototype`. - */ -inherits(Suite, EventEmitter); - /** * Resets the state initially or for a next run. */ -Suite.prototype.reset = function () { +reset() { this.delayed = false; function doReset(thingToReset) { thingToReset.reset(); @@ -124,7 +117,7 @@ Suite.prototype.reset = function () { * @private * @return {Suite} */ -Suite.prototype.clone = function () { +clone() { var suite = new Suite(this.title); debug('clone'); suite.ctx = this.ctx; @@ -144,7 +137,7 @@ Suite.prototype.clone = function () { * @param {number|string} ms * @return {Suite|number} for chaining */ -Suite.prototype.timeout = function (ms) { +timeout(ms) { if (!arguments.length) { return this._timeout; } @@ -169,7 +162,7 @@ Suite.prototype.timeout = function (ms) { * @param {number|string} n * @return {Suite|number} for chaining */ -Suite.prototype.retries = function (n) { +retries(n) { if (!arguments.length) { return this._retries; } @@ -185,7 +178,7 @@ Suite.prototype.retries = function (n) { * @param {number|string} ms * @return {Suite|number} for chaining */ -Suite.prototype.slow = function (ms) { +slow(ms) { if (!arguments.length) { return this._slow; } @@ -204,7 +197,7 @@ Suite.prototype.slow = function (ms) { * @param {boolean} bail * @return {Suite|number} for chaining */ -Suite.prototype.bail = function (bail) { +bail(bail) { if (!arguments.length) { return this._bail; } @@ -218,7 +211,7 @@ Suite.prototype.bail = function (bail) { * * @private */ -Suite.prototype.isPending = function () { +isPending() { return this.pending || (this.parent && this.parent.isPending()); }; @@ -229,7 +222,7 @@ Suite.prototype.isPending = function () { * @param {Function} fn - Hook callback * @returns {Hook} A new hook */ -Suite.prototype._createHook = function (title, fn) { +_createHook(title, fn) { var hook = new Hook(title, fn); hook.parent = this; hook.timeout(this.timeout()); @@ -248,7 +241,7 @@ Suite.prototype._createHook = function (title, fn) { * @param {Function} fn * @return {Suite} for chaining */ -Suite.prototype.beforeAll = function (title, fn) { +beforeAll(title, fn) { if (this.isPending()) { return this; } @@ -272,7 +265,7 @@ Suite.prototype.beforeAll = function (title, fn) { * @param {Function} fn * @return {Suite} for chaining */ -Suite.prototype.afterAll = function (title, fn) { +afterAll(title, fn) { if (this.isPending()) { return this; } @@ -296,7 +289,7 @@ Suite.prototype.afterAll = function (title, fn) { * @param {Function} fn * @return {Suite} for chaining */ -Suite.prototype.beforeEach = function (title, fn) { +beforeEach(title, fn) { if (this.isPending()) { return this; } @@ -320,7 +313,7 @@ Suite.prototype.beforeEach = function (title, fn) { * @param {Function} fn * @return {Suite} for chaining */ -Suite.prototype.afterEach = function (title, fn) { +afterEach(title, fn) { if (this.isPending()) { return this; } @@ -343,7 +336,7 @@ Suite.prototype.afterEach = function (title, fn) { * @param {Suite} suite * @return {Suite} for chaining */ -Suite.prototype.addSuite = function (suite) { +addSuite(suite) { suite.parent = this; suite.root = false; suite.timeout(this.timeout()); @@ -362,7 +355,7 @@ Suite.prototype.addSuite = function (suite) { * @param {Test} test * @return {Suite} for chaining */ -Suite.prototype.addTest = function (test) { +addTest(test) { test.parent = this; test.timeout(this.timeout()); test.retries(this.retries()); @@ -381,7 +374,7 @@ Suite.prototype.addTest = function (test) { * @public * @return {string} */ -Suite.prototype.fullTitle = function () { +fullTitle() { return this.titlePath().join(' '); }; @@ -393,7 +386,7 @@ Suite.prototype.fullTitle = function () { * @public * @return {string[]} */ -Suite.prototype.titlePath = function () { +titlePath() { var result = []; if (this.parent) { result = result.concat(this.parent.titlePath()); @@ -411,7 +404,7 @@ Suite.prototype.titlePath = function () { * @public * @return {number} */ -Suite.prototype.total = function () { +total() { return ( this.suites.reduce(function (sum, suite) { return sum + suite.total(); @@ -427,7 +420,7 @@ Suite.prototype.total = function () { * @param {Function} fn * @return {Suite} */ -Suite.prototype.eachTest = function (fn) { +eachTest(fn) { this.tests.forEach(fn); this.suites.forEach(function (suite) { suite.eachTest(fn); @@ -439,7 +432,7 @@ Suite.prototype.eachTest = function (fn) { * This will run the root suite if we happen to be running in delayed mode. * @private */ -Suite.prototype.run = function run() { +run() { if (this.root) { this.emit(constants.EVENT_ROOT_SUITE_RUN); } @@ -451,7 +444,7 @@ Suite.prototype.run = function run() { * @private * @returns {Boolean} */ -Suite.prototype.hasOnly = function hasOnly() { +hasOnly() { return ( this._onlyTests.length > 0 || this._onlySuites.length > 0 || @@ -467,7 +460,7 @@ Suite.prototype.hasOnly = function hasOnly() { * @private * @returns {Boolean} */ -Suite.prototype.filterOnly = function filterOnly() { +filterOnly() { if (this._onlyTests.length) { // If the suite contains `only` tests, run those and ignore any nested suites. this.tests = this._onlyTests; @@ -498,7 +491,7 @@ Suite.prototype.filterOnly = function filterOnly() { * @private * @param {Suite} suite */ -Suite.prototype.appendOnlySuite = function (suite) { +appendOnlySuite(suite) { this._onlySuites.push(suite); }; @@ -507,7 +500,7 @@ Suite.prototype.appendOnlySuite = function (suite) { * * @private */ -Suite.prototype.markOnly = function () { +markOnly() { this.parent && this.parent.appendOnlySuite(this); }; @@ -517,7 +510,7 @@ Suite.prototype.markOnly = function () { * @private * @param {Test} test */ -Suite.prototype.appendOnlyTest = function (test) { +appendOnlyTest(test) { this._onlyTests.push(test); }; @@ -525,14 +518,14 @@ Suite.prototype.appendOnlyTest = function (test) { * Returns the array of hooks by hook name; see `HOOK_TYPE_*` constants. * @private */ -Suite.prototype.getHooks = function getHooks(name) { +getHooks(name) { return this['_' + name]; }; /** * cleans all references from this suite and all child suites. */ -Suite.prototype.dispose = function () { +dispose() { this.suites.forEach(function (suite) { suite.dispose(); }); @@ -549,7 +542,7 @@ Suite.prototype.dispose = function () { * * @private */ -Suite.prototype.cleanReferences = function cleanReferences() { +cleanReferences() { function cleanArrReferences(arr) { for (var i = 0; i < arr.length; i++) { delete arr[i].fn; @@ -583,7 +576,7 @@ Suite.prototype.cleanReferences = function cleanReferences() { * @private * @returns {Object} */ -Suite.prototype.serialize = function serialize() { +serialize() { return { _bail: this._bail, $$fullTitle: this.fullTitle(), @@ -594,6 +587,7 @@ Suite.prototype.serialize = function serialize() { parent: this.parent ? {[MOCHA_ID_PROP_NAME]: this.parent.id} : null }; }; +} var constants = defineConstants( /** @@ -668,3 +662,9 @@ var constants = defineConstants( ); Suite.constants = constants; + +/** + * Expose `Suite`. + */ + +exports = module.exports = Suite; diff --git a/lib/test.js b/lib/test.js index 0b8fe18be7..051b93c185 100644 --- a/lib/test.js +++ b/lib/test.js @@ -7,18 +7,19 @@ var isString = utils.isString; const {MOCHA_ID_PROP_NAME} = utils.constants; -module.exports = Test; - /** * Initialize a new `Test` with the given `title` and callback `fn`. * * @public * @class * @extends Runnable + */ +class Test extends Runnable { +/** * @param {String} title - Test title (required) * @param {Function} [fn] - Test callback. If omitted, the Test is considered "pending" */ -function Test(title, fn) { +constructor(title, fn) { if (!isString(title)) { throw createInvalidArgumentTypeError( 'Test argument "title" should be a string. Received type "' + @@ -28,21 +29,16 @@ function Test(title, fn) { 'string' ); } + super(title, fn); this.type = 'test'; - Runnable.call(this, title, fn); this.reset(); } -/** - * Inherit from `Runnable.prototype`. - */ -utils.inherits(Test, Runnable); - /** * Resets the state initially or for a next run. */ -Test.prototype.reset = function () { - Runnable.prototype.reset.call(this); +reset() { + super.reset(); this.pending = !this.fn; delete this.state; }; @@ -52,7 +48,7 @@ Test.prototype.reset = function () { * * @private */ -Test.prototype.retriedTest = function (n) { +retriedTest(n) { if (!arguments.length) { return this._retriedTest; } @@ -64,11 +60,11 @@ Test.prototype.retriedTest = function (n) { * * @private */ -Test.prototype.markOnly = function () { +markOnly() { this.parent.appendOnlyTest(this); }; -Test.prototype.clone = function () { +clone() { var test = new Test(this.title, this.fn); test.timeout(this.timeout()); test.slow(this.slow()); @@ -88,7 +84,7 @@ Test.prototype.clone = function () { * @private * @returns {Object} */ -Test.prototype.serialize = function serialize() { +serialize() { return { $$currentRetry: this._currentRetry, $$fullTitle: this.fullTitle(), @@ -111,3 +107,6 @@ Test.prototype.serialize = function serialize() { [MOCHA_ID_PROP_NAME]: this.id }; }; +} + +module.exports = Test; From 80344aa0cfcd923c60ac16aa3edab94acb4726f0 Mon Sep 17 00:00:00 2001 From: Brandon Bennett <65947371+Offroaders123@users.noreply.github.com> Date: Wed, 8 Oct 2025 00:08:59 -0700 Subject: [PATCH 2/4] Tap Abstract Fix Co-authored-by: Mark Wiemer <7833360+mark-wiemer@users.noreply.github.com> --- lib/reporters/tap.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/reporters/tap.js b/lib/reporters/tap.js index 788b41dd6a..243ada8a34 100644 --- a/lib/reporters/tap.js +++ b/lib/reporters/tap.js @@ -153,7 +153,6 @@ writeVersion() {}; /** * Writes the plan to reporter output stream. * - * @abstract * @param {number} ntests - Number of tests that are planned to run. */ writePlan(ntests) { From ecd310aa2cdc9f6872ee59f706e21863359c7af6 Mon Sep 17 00:00:00 2001 From: Brandon Bennett <65947371+Offroaders123@users.noreply.github.com> Date: Wed, 8 Oct 2025 00:18:03 -0700 Subject: [PATCH 3/4] Code Review Updates This is a second commit to the first part, which was committed just before this. I am not completely familiar with code review yet, so I may need some more practice with things overall. Co-authored-by: Mark Wiemer <7833360+mark-wiemer@users.noreply.github.com> --- lib/reporters/tap.js | 1 - lib/runnable.js | 2 +- lib/runner.js | 1 - lib/suite.js | 4 ---- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/reporters/tap.js b/lib/reporters/tap.js index 243ada8a34..71849643f1 100644 --- a/lib/reporters/tap.js +++ b/lib/reporters/tap.js @@ -195,7 +195,6 @@ writeFail(n, test) { /** * Writes the summary epilogue to reporter output stream. * - * @abstract * @param {Object} stats - Object containing run statistics. */ writeEpilogue(stats) { diff --git a/lib/runnable.js b/lib/runnable.js index 1621c7aa5d..826275118c 100644 --- a/lib/runnable.js +++ b/lib/runnable.js @@ -251,7 +251,7 @@ resetTimeout() { * @private * @param {string[]} globals */ -globals(globals) { +globals(globalArgs) { if (!arguments.length) { return this._allowedGlobals; } diff --git a/lib/runner.js b/lib/runner.js index f5ab21d031..9eacd6892d 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -1220,7 +1220,6 @@ workerReporter() { /** * Wrapper for setImmediate, process.nextTick, or browser polyfill. * - * @param {Function} fn * @private */ Runner.immediately = global.setImmediate || process.nextTick; diff --git a/lib/suite.js b/lib/suite.js index 3af06a7b61..0d34804000 100644 --- a/lib/suite.js +++ b/lib/suite.js @@ -663,8 +663,4 @@ var constants = defineConstants( Suite.constants = constants; -/** - * Expose `Suite`. - */ - exports = module.exports = Suite; From 49e1aea6db38c2cd67fa6b250948b9f0bbc2e483 Mon Sep 17 00:00:00 2001 From: Mark Wiemer <7833360+mark-wiemer@users.noreply.github.com> Date: Sun, 12 Oct 2025 11:17:07 -0700 Subject: [PATCH 4/4] Update lib/runnable.js --- lib/runnable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/runnable.js b/lib/runnable.js index 826275118c..8decd6a6d9 100644 --- a/lib/runnable.js +++ b/lib/runnable.js @@ -249,7 +249,7 @@ resetTimeout() { * Set or get a list of whitelisted globals for this test run. * * @private - * @param {string[]} globals + * @param {string[]} globalArgs */ globals(globalArgs) { if (!arguments.length) {