From 293ce957a5b0100adfdfa8b75070a27484f26b59 Mon Sep 17 00:00:00 2001 From: Charlie Rudolph Date: Thu, 28 Sep 2017 19:47:04 -0700 Subject: [PATCH] indent test contexts (#2814) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an optional extended description… --- lib/reporters/base.js | 14 +++++++++++++- lib/runnable.js | 12 +++++++++++- lib/suite.js | 22 +++++++++++++++++----- test/integration/hook-err.spec.js | 20 +++++++++++++++----- test/reporters/base.spec.js | 4 ++-- test/unit/runnable.spec.js | 9 +++++++++ test/unit/suite.spec.js | 30 ++++++++++++++++++++++++++++++ 7 files changed, 97 insertions(+), 14 deletions(-) diff --git a/lib/reporters/base.js b/lib/reporters/base.js index 2ccfd1f34f..9243ec42e6 100644 --- a/lib/reporters/base.js +++ b/lib/reporters/base.js @@ -222,7 +222,19 @@ exports.list = function (failures) { // indent stack trace stack = stack.replace(/^/gm, ' '); - console.log(fmt, (i + 1), test.fullTitle(), msg, stack); + // indented test title + var testTitle = ''; + test.titlePath().forEach(function (str, index) { + if (index !== 0) { + testTitle += '\n '; + } + for (var i = 0; i < index; i++) { + testTitle += ' '; + } + testTitle += str; + }); + + console.log(fmt, (i + 1), testTitle, msg, stack); }); }; diff --git a/lib/runnable.js b/lib/runnable.js index ee8c4a3467..8194d32251 100644 --- a/lib/runnable.js +++ b/lib/runnable.js @@ -179,7 +179,17 @@ Runnable.prototype.currentRetry = function (n) { * @return {string} */ Runnable.prototype.fullTitle = function () { - return this.parent.fullTitle() + ' ' + this.title; + return this.titlePath().join(' '); +}; + +/** + * Return the title path generated by concatenating the parent's title path with the title. + * + * @api public + * @return {string} + */ +Runnable.prototype.titlePath = function () { + return this.parent.titlePath().concat([this.title]); }; /** diff --git a/lib/suite.js b/lib/suite.js index 13617ab91d..c592e46bc1 100644 --- a/lib/suite.js +++ b/lib/suite.js @@ -355,13 +355,25 @@ Suite.prototype.addTest = function (test) { * @return {string} */ Suite.prototype.fullTitle = function () { + return this.titlePath().join(' '); +}; + +/** + * Return the title path generated by recursively concatenating the parent's + * title path. + * + * @api public + * @return {string} + */ +Suite.prototype.titlePath = function () { + var result = []; if (this.parent) { - var full = this.parent.fullTitle(); - if (full) { - return full + ' ' + this.title; - } + result = result.concat(this.parent.titlePath()); + } + if (!this.root) { + result.push(this.title); } - return this.title; + return result; }; /** diff --git a/test/integration/hook-err.spec.js b/test/integration/hook-err.spec.js index 8e0896f0d3..10d0e97c4a 100644 --- a/test/integration/hook-err.spec.js +++ b/test/integration/hook-err.spec.js @@ -19,11 +19,11 @@ describe('hook error handling', function () { }); describe('before hook error tip', function () { - before(run('hooks/before-hook-error-tip.fixture.js', onlyErrorTitle)); + before(run('hooks/before-hook-error-tip.fixture.js', onlyErrorTitle())); it('should verify results', function () { assert.deepEqual( lines, - ['1) spec 2 "before all" hook:'] + ['1) spec 2', '"before all" hook:'] ); }); }); @@ -107,11 +107,11 @@ describe('hook error handling', function () { }); describe('async - before hook error tip', function () { - before(run('hooks/before-hook-async-error-tip.fixture.js', onlyErrorTitle)); + before(run('hooks/before-hook-async-error-tip.fixture.js', onlyErrorTitle())); it('should verify results', function () { assert.deepEqual( lines, - ['1) spec 2 "before all" hook:'] + ['1) spec 2', '"before all" hook:'] ); }); }); @@ -213,5 +213,15 @@ function onlyConsoleOutput () { } function onlyErrorTitle (line) { - return !!(/^1\)/).exec(line); + var foundErrorTitle = false; + var foundError = false; + return function (line) { + if (!foundErrorTitle) { + foundErrorTitle = !!(/^1\)/).exec(line); + } + if (!foundError) { + foundError = (/Error:/).exec(line); + } + return foundErrorTitle && !foundError; + }; } diff --git a/test/reporters/base.spec.js b/test/reporters/base.spec.js index 6c0cc587b0..69c2583585 100644 --- a/test/reporters/base.spec.js +++ b/test/reporters/base.spec.js @@ -8,8 +8,8 @@ var Assert = require('assert').AssertionError; function makeTest (err) { return { err: err, - fullTitle: function () { - return 'test title'; + titlePath: function () { + return ['test title']; } }; } diff --git a/test/unit/runnable.spec.js b/test/unit/runnable.spec.js index 8c084281d2..5ee3629722 100644 --- a/test/unit/runnable.spec.js +++ b/test/unit/runnable.spec.js @@ -3,6 +3,7 @@ var mocha = require('../../lib/mocha'); var utils = mocha.utils; var Runnable = mocha.Runnable; +var Suite = mocha.Suite; describe('Runnable(title, fn)', function () { // For every test we poison the global time-related methods. @@ -87,6 +88,14 @@ describe('Runnable(title, fn)', function () { }); }); + describe('.titlePath()', function () { + it('returns the concatenation of the parent\'s title path and runnable\'s title', function () { + var runnable = new Runnable('bar'); + runnable.parent = new Suite('foo'); + runnable.titlePath().should.deepEqual(['foo', 'bar']); + }); + }); + describe('when arity >= 1', function () { it('should be .async', function () { var run = new Runnable('foo', function (done) {}); diff --git a/test/unit/suite.spec.js b/test/unit/suite.spec.js index a4530e3c05..0e94422915 100644 --- a/test/unit/suite.spec.js +++ b/test/unit/suite.spec.js @@ -395,6 +395,36 @@ describe('Suite', function () { }); }); + describe('.titlePath()', function () { + beforeEach(function () { + this.suite = new Suite('A Suite'); + }); + + describe('when there is no parent', function () { + it('returns the suite title', function () { + this.suite.titlePath().should.deepEqual(['A Suite']); + }); + }); + + describe('when there is a parent', function () { + describe('the parent is the root suite', function () { + it('returns the suite title', function () { + var parentSuite = new Suite(''); + parentSuite.addSuite(this.suite); + this.suite.titlePath().should.deepEqual(['A Suite']); + }); + }); + + describe('the parent is not the root suite', function () { + it('returns the concatenation of parent\'s and suite\'s title', function () { + var parentSuite = new Suite('I am a parent'); + parentSuite.addSuite(this.suite); + this.suite.titlePath().should.deepEqual(['I am a parent', 'A Suite']); + }); + }); + }); + }); + describe('.total()', function () { beforeEach(function () { this.suite = new Suite('A Suite');