From 8e3066db425309ecdabd96b8b61b7fec31a4b94e Mon Sep 17 00:00:00 2001 From: slackersoft Date: Mon, 26 Jan 2015 15:55:31 -0800 Subject: [PATCH] Allow `pending` to take a reason and show it in the HtmlReporter [#78954014] Fix #671 --- lib/jasmine-core/jasmine-html.js | 3 +++ lib/jasmine-core/jasmine.js | 28 ++++++++++++++++++++++------ spec/core/EnvSpec.js | 6 ++++++ spec/core/SpecSpec.js | 25 ++++++++++++++++++++++++- spec/core/integration/EnvSpec.js | 24 ++++++++++++++++++++++++ spec/html/HtmlReporterSpec.js | 15 ++++++++++++--- src/core/Env.js | 8 ++++++-- src/core/Spec.js | 18 +++++++++++++++--- src/core/requireInterface.js | 2 +- src/html/HtmlReporter.js | 3 +++ 10 files changed, 116 insertions(+), 16 deletions(-) diff --git a/lib/jasmine-core/jasmine-html.js b/lib/jasmine-core/jasmine-html.js index 04562808..bee5a04f 100644 --- a/lib/jasmine-core/jasmine-html.js +++ b/lib/jasmine-core/jasmine-html.js @@ -221,6 +221,9 @@ jasmineRequire.HtmlReporter = function(j$) { if(noExpectations(resultNode.result)) { specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription; } + if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') { + specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason; + } specListNode.appendChild( createDom('li', { className: resultNode.result.status, diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index cd0a66fe..767ef93f 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -312,7 +312,8 @@ getJasmineRequireObj().Spec = function(j$) { description: this.description, fullName: this.getFullName(), failedExpectations: [], - passedExpectations: [] + passedExpectations: [], + pendingReason: '' }; } @@ -361,7 +362,7 @@ getJasmineRequireObj().Spec = function(j$) { Spec.prototype.onException = function onException(e) { if (Spec.isPendingSpecException(e)) { - this.pend(); + this.pend(extractCustomPendingMessage(e)); return; } @@ -378,8 +379,11 @@ getJasmineRequireObj().Spec = function(j$) { this.disabled = true; }; - Spec.prototype.pend = function() { + Spec.prototype.pend = function(message) { this.markedPending = true; + if (message) { + this.result.pendingReason = message; + } }; Spec.prototype.status = function() { @@ -406,6 +410,14 @@ getJasmineRequireObj().Spec = function(j$) { return this.getSpecName(this); }; + var extractCustomPendingMessage = function(e) { + var fullMessage = e.toString(), + boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage), + boilerplateEnd = boilerplateStart + Spec.pendingSpecExceptionMessage.length; + + return fullMessage.substr(boilerplateEnd); + }; + Spec.pendingSpecExceptionMessage = '=> marked Pending'; Spec.isPendingSpecException = function(e) { @@ -851,8 +863,12 @@ getJasmineRequireObj().Env = function(j$) { }); }; - this.pending = function() { - throw j$.Spec.pendingSpecExceptionMessage; + this.pending = function(message) { + var fullMessage = j$.Spec.pendingSpecExceptionMessage; + if(message) { + fullMessage += message; + } + throw fullMessage; }; this.fail = function(error) { @@ -2994,7 +3010,7 @@ getJasmineRequireObj().interface = function(jasmine, env) { }, pending: function() { - return env.pending(); + return env.pending.apply(env, arguments); }, fail: function() { diff --git a/spec/core/EnvSpec.js b/spec/core/EnvSpec.js index f8867885..e80c4f51 100644 --- a/spec/core/EnvSpec.js +++ b/spec/core/EnvSpec.js @@ -11,6 +11,12 @@ describe("Env", function() { env.pending(); }).toThrow(j$.Spec.pendingSpecExceptionMessage); }); + + it("throws the Pending Spec exception with a custom message", function() { + expect(function() { + env.pending('custom message'); + }).toThrow(j$.Spec.pendingSpecExceptionMessage + 'custom message'); + }); }); describe("#topSuite", function() { diff --git a/spec/core/SpecSpec.js b/spec/core/SpecSpec.js index a99b7451..3bb0fcb0 100644 --- a/spec/core/SpecSpec.js +++ b/spec/core/SpecSpec.js @@ -14,6 +14,10 @@ describe("Spec", function() { expect(j$.Spec.isPendingSpecException(fakeError)).toBe(true); }); + it("#isPendingSpecException returns true for a pending spec exception with a custom message", function() { + expect(j$.Spec.isPendingSpecException(j$.Spec.pendingSpecExceptionMessage + 'foo')).toBe(true); + }); + it("#isPendingSpecException returns false for not a pending spec exception", function() { var e = new Error("foo"); @@ -174,7 +178,8 @@ describe("Spec", function() { description: 'with a spec', fullName: 'a suite with a spec', failedExpectations: [], - passedExpectations: [] + passedExpectations: [], + pendingReason: '' }); }); @@ -254,6 +259,24 @@ describe("Spec", function() { spec.execute(); expect(spec.status()).toEqual("pending"); + expect(spec.result.pendingReason).toEqual(''); + }); + + it("should set the pendingReason", function() { + var fakeQueueRunner = function(opts) { + opts.onException(new Error(j$.Spec.pendingSpecExceptionMessage + 'custom message')); + }, + spec = new j$.Spec({ + description: 'my test', + id: 'some-id', + queueableFn: { fn: function() { } }, + queueRunnerFactory: fakeQueueRunner + }); + + spec.execute(); + + expect(spec.status()).toEqual("pending"); + expect(spec.result.pendingReason).toEqual('custom message'); }); }); }); diff --git a/spec/core/integration/EnvSpec.js b/spec/core/integration/EnvSpec.js index 0321a197..cb199586 100644 --- a/spec/core/integration/EnvSpec.js +++ b/spec/core/integration/EnvSpec.js @@ -1137,6 +1137,30 @@ describe("Env integration", function() { env.execute(); }); + it('should report pending spec messages', function(done) { + var env = new j$.Env(), + reporter = jasmine.createSpyObj('fakeReporter', [ + 'specDone', + 'jasmineDone' + ]); + + reporter.jasmineDone.and.callFake(function() { + var specStatus = reporter.specDone.calls.argsFor(0)[0]; + + expect(specStatus.pendingReason).toBe('with a message'); + + done(); + }); + + env.addReporter(reporter); + + env.it('will be pending', function() { + env.pending('with a message'); + }); + + env.execute(); + }); + it('should report xdescribes as expected', function(done) { var env = new j$.Env(), reporter = jasmine.createSpyObj('fakeReporter', [ diff --git a/spec/html/HtmlReporterSpec.js b/spec/html/HtmlReporterSpec.js index 0d1054ec..c1eb5628 100644 --- a/spec/html/HtmlReporterSpec.js +++ b/spec/html/HtmlReporterSpec.js @@ -533,14 +533,17 @@ describe("New HtmlReporter", function() { reporter.initialize(); reporter.jasmineStarted({ totalSpecsDefined: 1 }); - reporter.specDone({ + var specStatus = { id: 123, description: "with a spec", fullName: "A Suite with a spec", status: "pending", passedExpectations: [], - failedExpectations: [] - }); + failedExpectations: [], + pendingReason: "my custom pending reason" + }; + reporter.specStarted(specStatus); + reporter.specDone(specStatus); reporter.jasmineDone({}); }); @@ -555,6 +558,12 @@ describe("New HtmlReporter", function() { expect(specFailure.childNodes.length).toEqual(0); }); + + it("displays the custom pending reason", function() { + var pendingDetails = container.querySelector(".summary .pending"); + + expect(pendingDetails.innerHTML).toContain("my custom pending reason"); + }); }); describe("and some tests fail", function() { diff --git a/src/core/Env.js b/src/core/Env.js index 80f1ddae..def82860 100644 --- a/src/core/Env.js +++ b/src/core/Env.js @@ -430,8 +430,12 @@ getJasmineRequireObj().Env = function(j$) { }); }; - this.pending = function() { - throw j$.Spec.pendingSpecExceptionMessage; + this.pending = function(message) { + var fullMessage = j$.Spec.pendingSpecExceptionMessage; + if(message) { + fullMessage += message; + } + throw fullMessage; }; this.fail = function(error) { diff --git a/src/core/Spec.js b/src/core/Spec.js index 056c4703..093c582b 100644 --- a/src/core/Spec.js +++ b/src/core/Spec.js @@ -22,7 +22,8 @@ getJasmineRequireObj().Spec = function(j$) { description: this.description, fullName: this.getFullName(), failedExpectations: [], - passedExpectations: [] + passedExpectations: [], + pendingReason: '' }; } @@ -71,7 +72,7 @@ getJasmineRequireObj().Spec = function(j$) { Spec.prototype.onException = function onException(e) { if (Spec.isPendingSpecException(e)) { - this.pend(); + this.pend(extractCustomPendingMessage(e)); return; } @@ -88,8 +89,11 @@ getJasmineRequireObj().Spec = function(j$) { this.disabled = true; }; - Spec.prototype.pend = function() { + Spec.prototype.pend = function(message) { this.markedPending = true; + if (message) { + this.result.pendingReason = message; + } }; Spec.prototype.status = function() { @@ -116,6 +120,14 @@ getJasmineRequireObj().Spec = function(j$) { return this.getSpecName(this); }; + var extractCustomPendingMessage = function(e) { + var fullMessage = e.toString(), + boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage), + boilerplateEnd = boilerplateStart + Spec.pendingSpecExceptionMessage.length; + + return fullMessage.substr(boilerplateEnd); + }; + Spec.pendingSpecExceptionMessage = '=> marked Pending'; Spec.isPendingSpecException = function(e) { diff --git a/src/core/requireInterface.js b/src/core/requireInterface.js index 306813a0..840eaaed 100644 --- a/src/core/requireInterface.js +++ b/src/core/requireInterface.js @@ -45,7 +45,7 @@ getJasmineRequireObj().interface = function(jasmine, env) { }, pending: function() { - return env.pending(); + return env.pending.apply(env, arguments); }, fail: function() { diff --git a/src/html/HtmlReporter.js b/src/html/HtmlReporter.js index e49f83b4..42b9d924 100644 --- a/src/html/HtmlReporter.js +++ b/src/html/HtmlReporter.js @@ -192,6 +192,9 @@ jasmineRequire.HtmlReporter = function(j$) { if(noExpectations(resultNode.result)) { specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription; } + if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') { + specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason; + } specListNode.appendChild( createDom('li', { className: resultNode.result.status,