Skip to content

Commit

Permalink
Merge branch 'master' into non-string-error-messages
Browse files Browse the repository at this point in the history
  • Loading branch information
jkimbo committed Feb 17, 2016
2 parents 2e95f10 + 0543798 commit e1e6885
Show file tree
Hide file tree
Showing 14 changed files with 100 additions and 23 deletions.
2 changes: 1 addition & 1 deletion lib/interfaces/bdd.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ module.exports = function(suite) {

var it = context.it = context.specify = function(title, fn) {
var suite = suites[0];
if (suite.pending) {
if (suite.isPending()) {
fn = null;
}
var test = new Test(title, fn);
Expand Down
2 changes: 1 addition & 1 deletion lib/interfaces/tdd.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ module.exports = function(suite) {
*/
context.test = function(title, fn) {
var suite = suites[0];
if (suite.pending) {
if (suite.isPending()) {
fn = null;
}
var test = new Test(title, fn);
Expand Down
4 changes: 2 additions & 2 deletions lib/reporters/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ function HTML(runner) {
if (test.state === 'passed') {
var url = self.testURL(test);
el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span> <a href="%s" class="replay">‣</a></h2></li>', test.speed, test.title, test.duration, url);
} else if (test.pending) {
} else if (test.isPending()) {
el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
} else {
el = fragment('<li class="test fail"><h2>%e <a href="%e" class="replay">‣</a></h2></li>', test.title, self.testURL(test));
Expand Down Expand Up @@ -193,7 +193,7 @@ function HTML(runner) {

// toggle code
// TODO: defer
if (!test.pending) {
if (!test.isPending()) {
var h2 = el.getElementsByTagName('h2')[0];

on(h2, 'click', function() {
Expand Down
2 changes: 1 addition & 1 deletion lib/reporters/xunit.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ XUnit.prototype.test = function(test) {
if (test.state === 'failed') {
var err = test.err;
this.write(tag('testcase', attrs, false, tag('failure', {}, false, cdata(escape(err.message) + '\n' + err.stack))));
} else if (test.pending) {
} else if (test.isPending()) {
this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));
} else {
this.write(tag('testcase', attrs, true));
Expand Down
15 changes: 13 additions & 2 deletions lib/runnable.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ module.exports = Runnable;
function Runnable(title, fn) {
this.title = title;
this.fn = fn;
this.body = (fn || '').toString();
this.async = fn && fn.length;
this.sync = !this.async;
this._timeout = 2000;
Expand All @@ -54,6 +55,7 @@ function Runnable(title, fn) {
this._trace = new Error('done() called multiple times');
this._retries = -1;
this._currentRetry = 0;
this.pending = false;
}

/**
Expand Down Expand Up @@ -124,12 +126,21 @@ Runnable.prototype.enableTimeouts = function(enabled) {
/**
* Halt and mark as pending.
*
* @api private
* @api public
*/
Runnable.prototype.skip = function() {
throw new Pending();
};

/**
* Check if this runnable or its parent suite is marked as pending.
*
* @api private
*/
Runnable.prototype.isPending = function() {
return this.pending || (this.parent && this.parent.isPending());
};

/**
* Set number of retries.
*
Expand Down Expand Up @@ -302,7 +313,7 @@ Runnable.prototype.run = function(fn) {

// sync or promise-returning
try {
if (this.pending) {
if (this.isPending()) {
done();
} else {
callFn(this.fn);
Expand Down
9 changes: 2 additions & 7 deletions lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -507,12 +507,7 @@ Runner.prototype.runTests = function(suite, fn) {
return;
}

function parentPending(suite) {
return suite.pending || (suite.parent && parentPending(suite.parent));
}

// pending
if (test.pending || parentPending(test.parent)) {
if (test.isPending()) {
self.emit('pending', test);
self.emit('test end', test);
return next();
Expand All @@ -521,7 +516,7 @@ Runner.prototype.runTests = function(suite, fn) {
// execute test and hook(s)
self.emit('test', self.test = test);
self.hookDown('beforeEach', function(err, errSuite) {
if (suite.pending) {
if (suite.isPending()) {
self.emit('pending', test);
self.emit('test end', test);
return next();
Expand Down
20 changes: 13 additions & 7 deletions lib/suite.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ exports = module.exports = Suite;
exports.create = function(parent, title) {
var suite = new Suite(title, parent.ctx);
suite.parent = parent;
if (parent.pending) {
suite.pending = true;
}
title = suite.fullTitle();
parent.addSuite(suite);
return suite;
Expand Down Expand Up @@ -176,6 +173,15 @@ Suite.prototype.bail = function(bail) {
return this;
};

/**
* Check if this suite or its parent suite is marked as pending.
*
* @api private
*/
Suite.prototype.isPending = function() {
return this.pending || (this.parent && this.parent.isPending());
};

/**
* Run `fn(test[, done])` before running tests.
*
Expand All @@ -185,7 +191,7 @@ Suite.prototype.bail = function(bail) {
* @return {Suite} for chaining
*/
Suite.prototype.beforeAll = function(title, fn) {
if (this.pending) {
if (this.isPending()) {
return this;
}
if (typeof title === 'function') {
Expand Down Expand Up @@ -215,7 +221,7 @@ Suite.prototype.beforeAll = function(title, fn) {
* @return {Suite} for chaining
*/
Suite.prototype.afterAll = function(title, fn) {
if (this.pending) {
if (this.isPending()) {
return this;
}
if (typeof title === 'function') {
Expand Down Expand Up @@ -245,7 +251,7 @@ Suite.prototype.afterAll = function(title, fn) {
* @return {Suite} for chaining
*/
Suite.prototype.beforeEach = function(title, fn) {
if (this.pending) {
if (this.isPending()) {
return this;
}
if (typeof title === 'function') {
Expand Down Expand Up @@ -275,7 +281,7 @@ Suite.prototype.beforeEach = function(title, fn) {
* @return {Suite} for chaining
*/
Suite.prototype.afterEach = function(title, fn) {
if (this.pending) {
if (this.isPending()) {
return this;
}
if (typeof title === 'function') {
Expand Down
1 change: 0 additions & 1 deletion lib/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ function Test(title, fn) {
Runnable.call(this, title, fn);
this.pending = !fn;
this.type = 'test';
this.body = (fn || '').toString();
}

/**
Expand Down
4 changes: 3 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ function jsonStringify(object, spaces, depth) {
break;
case 'boolean':
case 'regexp':
case 'symbol':
case 'number':
val = val === 0 && (1 / val) === -Infinity // `-0`
? '-0'
Expand All @@ -498,7 +499,7 @@ function jsonStringify(object, spaces, depth) {
}

for (var i in object) {
if (!object.hasOwnProperty(i)) {
if (!Object.prototype.hasOwnProperty.call(object, i)) {
continue; // not my business
}
--length;
Expand Down Expand Up @@ -597,6 +598,7 @@ exports.canonicalize = function(value, stack) {
case 'number':
case 'regexp':
case 'boolean':
case 'symbol':
canonicalizedObj = value;
break;
default:
Expand Down
9 changes: 9 additions & 0 deletions mocha.css
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,15 @@ body {
#mocha-stats .progress {
float: right;
padding-top: 0;

/**
* Set safe initial values, so mochas .progress does not inherit these
* properties from Bootstrap .progress (which causes .progress height to
* equal line height set in Bootstrap).
*/
height: auto;
box-shadow: none;
background-color: initial;
}

#mocha-stats em {
Expand Down
9 changes: 9 additions & 0 deletions test/acceptance/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,15 @@ describe('lib/utils', function () {

stringify(a).should.equal('{\n "foo": 1\n}');
});

// In old version node.js, Symbol is not available by default.
if (typeof global.Symbol === 'function') {
it('should handle Symbol', function () {
var symbol = Symbol('value');
stringify(symbol).should.equal('Symbol(value)');
stringify({symbol: symbol}).should.equal('{\n "symbol": Symbol(value)\n}')
});
}
});

describe('type', function () {
Expand Down
20 changes: 20 additions & 0 deletions test/reporters/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,26 @@ describe('Base reporter', function () {
}
});

it('should stringify Object.create(null)', function () {
var err = new Error('test'),
errOut;

err.actual = Object.create(null);
err.actual.hasOwnProperty = 1;
err.expected = Object.create(null);
err.expected.hasOwnProperty = 2;
err.showDiff = true;
var test = makeTest(err);

Base.list([test]);

errOut = stdout.join('\n');
errOut.should.match(/"hasOwnProperty"/);
errOut.should.match(/test/);
errOut.should.match(/\- actual/);
errOut.should.match(/\+ expected/);
});

it('should remove message from stack', function () {
var err = {
message: 'Error',
Expand Down
5 changes: 5 additions & 0 deletions test/suite.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,11 @@ describe('Suite', function(){
this.first.suites.should.have.length(1);
this.first.suites[0].should.equal(this.second);
});

it('treats suite as pending if its parent is pending', function(){
this.first.pending = true
this.second.isPending.should.be.true
});
});

// describe('.addTest()', function(){
Expand Down
21 changes: 21 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var mocha = require('../')
, should = require('should')
, Context = mocha.Context
, Test = mocha.Test;

Expand Down Expand Up @@ -52,4 +53,24 @@ describe('Test', function(){
this._test.clone().file.should.equal('bar');
});
});

describe('.isPending()', function(){
beforeEach(function(){
this._test = new Test('Is it skipped', function () {});
});

it('should not be pending by default', function(){
should(this._test.isPending()).not.be.ok();
});

it('should be pending when marked as such', function(){
this._test.pending = true;
should(this._test.isPending()).be.ok();
});

it('should be pending when its parent is pending', function(){
this._test.parent = { isPending: function(){ return true } };
should(this._test.isPending()).be.ok();
});
});
});

0 comments on commit e1e6885

Please sign in to comment.