Skip to content

Commit

Permalink
Merge branch 'master' into issue/2987-docs [ci skip]
Browse files Browse the repository at this point in the history
* master:
  refactor "forbid pending" tests for DRY
  add diff tool artifacts to .gitignore [ci skip]
  fix inaccurate diff output due to post-assertion object mutation  (#3075)
  remove unused code in ms module

# Conflicts:
#	.gitignore
  • Loading branch information
boneskull committed Dec 9, 2017
2 parents e09573f + 2f8173a commit 74ac83f
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 131 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Expand Up @@ -15,4 +15,9 @@ coverage/
yarn.lock
package-lock.json
mocha.js
# artifacts from various diff tools
*_BACKUP_*
*_BASE_*
*_LOCAL_*
*_REMOTE_*
docs/_site
48 changes: 4 additions & 44 deletions lib/ms.js
Expand Up @@ -13,22 +13,15 @@ var y = d * 365.25;
/**
* Parse or format the given `val`.
*
* Options:
*
* - `long` verbose formatting [false]
*
* @api public
* @param {string|number} val
* @param {Object} options
* @return {string|number}
*/
module.exports = function (val, options) {
options = options || {};
module.exports = function (val) {
if (typeof val === 'string') {
return parse(val);
}
// https://github.com/mochajs/mocha/pull/1035
return options['long'] ? longFormat(val) : shortFormat(val);
return format(val);
};

/**
Expand Down Expand Up @@ -74,13 +67,13 @@ function parse (str) {
}

/**
* Short format for `ms`.
* Format for `ms`.
*
* @api private
* @param {number} ms
* @return {string}
*/
function shortFormat (ms) {
function format (ms) {
if (ms >= d) {
return Math.round(ms / d) + 'd';
}
Expand All @@ -95,36 +88,3 @@ function shortFormat (ms) {
}
return ms + 'ms';
}

/**
* Long format for `ms`.
*
* @api private
* @param {number} ms
* @return {string}
*/
function longFormat (ms) {
return plural(ms, d, 'day') ||
plural(ms, h, 'hour') ||
plural(ms, m, 'minute') ||
plural(ms, s, 'second') ||
ms + ' ms';
}

/**
* Pluralization helper.
*
* @api private
* @param {number} ms
* @param {number} n
* @param {string} name
*/
function plural (ms, n, name) {
if (ms < n) {
return;
}
if (ms < n * 1.5) {
return Math.floor(ms / n) + ' ' + name;
}
return Math.ceil(ms / n) + ' ' + name + 's';
}
24 changes: 16 additions & 8 deletions lib/reporters/base.js
Expand Up @@ -155,6 +155,17 @@ exports.cursor = {
}
};

function showDiff (err) {
return err && err.showDiff !== false && sameType(err.actual, err.expected) && err.expected !== undefined;
}

function stringifyDiffObjs (err) {
if (!utils.isString(err.actual) || !utils.isString(err.expected)) {
err.actual = utils.stringify(err.actual);
err.expected = utils.stringify(err.expected);
}
}

/**
* Output the given `failures` as a list.
*
Expand Down Expand Up @@ -183,8 +194,6 @@ exports.list = function (failures) {
}
var stack = err.stack || message;
var index = message ? stack.indexOf(message) : -1;
var actual = err.actual;
var expected = err.expected;

if (index === -1) {
msg = message;
Expand All @@ -200,12 +209,8 @@ exports.list = function (failures) {
msg = 'Uncaught ' + msg;
}
// explicitly show diff
if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) {
if (!(utils.isString(actual) && utils.isString(expected))) {
err.actual = actual = utils.stringify(actual);
err.expected = expected = utils.stringify(expected);
}

if (showDiff(err)) {
stringifyDiffObjs(err);
fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n');
var match = message.match(/^([^:]+): expected/);
msg = '\n ' + color('error message', match ? match[1] : msg);
Expand Down Expand Up @@ -290,6 +295,9 @@ function Base (runner) {
runner.on('fail', function (test, err) {
stats.failures = stats.failures || 0;
stats.failures++;
if (showDiff(err)) {
stringifyDiffObjs(err);
}
test.err = err;
failures.push(test);
});
Expand Down
84 changes: 26 additions & 58 deletions test/integration/options.spec.js
Expand Up @@ -274,63 +274,28 @@ describe('options', function () {
});
});

it('fails if there are tests marked skip', function (done) {
run('options/forbid-pending/skip.js', args, function (err, res) {
if (err) {
done(err);
return;
}
assert.equal(res.code, 1);
assert.equal(res.failures[0].err.message, pendingErrorMessage);
done();
});
});

it('fails if there are pending tests', function (done) {
run('options/forbid-pending/pending.js', args, function (err, res) {
if (err) {
done(err);
return;
}
assert.equal(res.code, 1);
assert.equal(res.failures[0].err.message, pendingErrorMessage);
done();
});
});

it('fails if tests call `skip()`', function (done) {
run('options/forbid-pending/this.skip.js', args, function (err, res) {
assert(!err);
assert.equal(res.code, 1);
assert.equal(res.failures[0].err.message, pendingErrorMessage);
done();
});
});

it('fails if beforeEach calls `skip()`', function (done) {
run('options/forbid-pending/beforeEach-this.skip.js', args, function (err, res) {
assert(!err);
assert.equal(res.code, 1);
assert.equal(res.failures[0].err.message, pendingErrorMessage);
done();
});
});

it('fails if before calls `skip()`', function (done) {
run('options/forbid-pending/before-this.skip.js', args, function (err, res) {
assert(!err);
assert.equal(res.code, 1);
assert.equal(res.failures[0].err.message, pendingErrorMessage);
done();
});
});
var forbidPendingFailureTests = {
'fails if there are tests marked skip': 'skip.js',
'fails if there are pending tests': 'pending.js',
'fails if tests call `skip()`': 'this.skip.js',
'fails if beforeEach calls `skip()`': 'beforeEach-this.skip.js',
'fails if before calls `skip()`': 'before-this.skip.js',
'fails if there are tests in suites marked skip': 'skip-suite.js'
};

it('fails if there are tests in suites marked skip', function (done) {
run('options/forbid-pending/skip-suite.js', args, function (err, res) {
assert(!err);
assert.equal(res.code, 1);
assert.equal(res.failures[0].err.message, pendingErrorMessage);
done();
Object.keys(forbidPendingFailureTests).forEach(function (title) {
it(title, function (done) {
run(path.join('options', 'forbid-pending', forbidPendingFailureTests[title]),
args,
function (err, res) {
if (err) {
done(err);
return;
}
assert.equal(res.code, 1);
assert.equal(res.failures[0].err.message, pendingErrorMessage);
done();
});
});
});
});
Expand All @@ -344,7 +309,8 @@ describe('options', function () {
/**
* Returns a test that executes Mocha in a subprocess with either
* `--exit`, `--no-exit`, or default behavior.
* @param {boolean} shouldExit - Expected result; `true` if Mocha should have force-killed the process.
* @param {boolean} shouldExit - Expected result; `true` if Mocha should
* have force-killed the process.
* @param {string} [behavior] - 'enabled' or 'disabled'
* @returns {Function}
*/
Expand Down Expand Up @@ -392,7 +358,9 @@ describe('options', function () {
describe('--help', function () {
it('works despite the presence of mocha.opts', function (done) {
directInvoke(['-h'], function (error, result) {
if (error) { return done(error); }
if (error) {
return done(error);
}
expect(result.output).to.contain('Usage:');
done();
}, path.join(__dirname, 'fixtures', 'options', 'help'));
Expand Down
22 changes: 22 additions & 0 deletions test/reporters/list.spec.js
Expand Up @@ -192,6 +192,28 @@ describe('List reporter', function () {

Base.cursor = cachedCursor;
});
it('should immediately construct fail strings', function () {
var actual = { a: 'actual' };
var expected = { a: 'expected' };
var test = {};
var checked = false;
var err;
runner.on = function (event, callback) {
if (!checked && event === 'fail') {
err = new Error('fake failure object with actual/expected');
err.actual = actual;
err.expected = expected;
err.showDiff = true;
callback(test, err);
checked = true;
}
};
List.call({epilogue: function () {}}, runner);

process.stdout.write = stdoutWrite;
expect(typeof err.actual).to.equal('string');
expect(typeof err.expected).to.equal('string');
});
});

describe('on end', function () {
Expand Down
21 changes: 0 additions & 21 deletions test/unit/ms.spec.js
Expand Up @@ -21,45 +21,24 @@ describe('.ms()', function () {
it('should return short format', function () {
expect(ms(2000)).to.equal('2s');
});

it('should return long format', function () {
expect(ms(2000, { long: true })).to.equal('2 seconds');
expect(ms(1000, { long: true })).to.equal('1 second');
expect(ms(1010, { long: true })).to.equal('1 second');
});
});

describe('minutes representation', function () {
it('should return short format', function () {
expect(ms(time.minutes(1))).to.equal('1m');
});

it('should return long format', function () {
expect(ms(time.minutes(1), { long: true })).to.equal('1 minute');
expect(ms(time.minutes(3), { long: true })).to.equal('3 minutes');
});
});

describe('hours representation', function () {
it('should return short format', function () {
expect(ms(time.hours(1))).to.equal('1h');
});

it('should return long format', function () {
expect(ms(time.hours(1), { long: true })).to.equal('1 hour');
expect(ms(time.hours(3), { long: true })).to.equal('3 hours');
});
});

describe('days representation', function () {
it('should return short format', function () {
expect(ms(time.days(1))).to.equal('1d');
});

it('should return long format', function () {
expect(ms(time.days(1), { long: true })).to.equal('1 day');
expect(ms(time.days(3), { long: true })).to.equal('3 days');
});
});

describe('Getting string value', function () {
Expand Down

0 comments on commit 74ac83f

Please sign in to comment.