From e7cd6a473aa9c8eb51ee0a836664d118adc7a3e1 Mon Sep 17 00:00:00 2001 From: Lee Byrd & Christian Williams Date: Tue, 22 Jun 2010 12:23:54 -0700 Subject: [PATCH] jasmine.log() and Spec#log() take multiple arguments which are pretty-printed and concatted together. Log messages are handled correctly in TrivialReporter and JsApiReporter. --- lib/TrivialReporter.js | 5 ++- lib/jasmine-0.10.4.js | 58 +++++++++++++++++------------- spec/runner.html | 1 + spec/suites/BaseSpec.js | 15 ++++++++ spec/suites/JsApiReporterSpec.js | 7 ++-- spec/suites/SpecSpec.js | 16 ++++++++- spec/suites/TrivialReporterSpec.js | 35 ++++++++++++++---- src/JsApiReporter.js | 10 +++--- src/NestedResults.js | 8 ++--- src/Spec.js | 4 +-- src/base.js | 20 ++++++++--- 11 files changed, 124 insertions(+), 55 deletions(-) create mode 100644 spec/suites/BaseSpec.js diff --git a/lib/TrivialReporter.js b/lib/TrivialReporter.js index 0025ede..9abd667 100644 --- a/lib/TrivialReporter.js +++ b/lib/TrivialReporter.js @@ -134,7 +134,10 @@ jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) { var messagesDiv = this.createDom('div', { className: 'messages' }); for (var i = 0; i < resultItems.length; i++) { var result = resultItems[i]; - if (result.passed && !result.passed()) { + + if (result.type == 'MessageResult') { + messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); + } else if (result.type == 'ExpectationResult' && result.passed && !result.passed()) { messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); if (result.trace.stack) { diff --git a/lib/jasmine-0.10.4.js b/lib/jasmine-0.10.4.js index 73885cc..1511619 100644 --- a/lib/jasmine-0.10.4.js +++ b/lib/jasmine-0.10.4.js @@ -51,14 +51,23 @@ jasmine.clearTimeout = jasmine.bindOriginal_(window, 'clearTimeout'); jasmine.setInterval = jasmine.bindOriginal_(window, 'setInterval'); jasmine.clearInterval = jasmine.bindOriginal_(window, 'clearInterval'); -jasmine.MessageResult = function(text) { +jasmine.MessageResult = function(values) { this.type = 'MessageResult'; - this.text = text; + this.values = values; this.trace = new Error(); // todo: test better }; jasmine.MessageResult.prototype.toString = function() { - return this.text; + var text = ""; + for(var i = 0; i < this.values.length; i++) { + if (i > 0) text += " "; + if (jasmine.isString_(this.values[i])) { + text += this.values[i]; + } else { + text += jasmine.pp(this.values[i]); + } + } + return text; }; jasmine.ExpectationResult = function(params) { @@ -395,8 +404,9 @@ jasmine.createSpyObj = function(baseName, methodNames) { return obj; }; -jasmine.log = function(message) { - jasmine.getEnv().currentSpec.log(message); +jasmine.log = function() { + var spec = jasmine.getEnv().currentSpec; + spec.log.apply(spec, arguments); }; /** @@ -1045,11 +1055,11 @@ jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ var summaryMessages = []; - var messagesLength = result.messages.length + var messagesLength = result.messages.length; for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { var resultMessage = result.messages[messageIndex]; summaryMessages.push({ - text: resultMessage.text, + text: resultMessage.type == 'MessageResult' ? resultMessage.toString() : jasmine.undefined, passed: resultMessage.passed ? resultMessage.passed() : true, type: resultMessage.type, message: resultMessage.message, @@ -1057,14 +1067,12 @@ jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined } }); - }; + } - var summaryResult = { + return { result : result.result, messages : summaryMessages }; - - return summaryResult; }; /** @@ -1471,11 +1479,11 @@ jasmine.NestedResults.prototype.rollupCounts = function(result) { }; /** - * Tracks a result's message. - * @param message + * Adds a log message. + * @param values Array of message parts which will be concatenated later. */ -jasmine.NestedResults.prototype.log = function(message) { - this.items_.push(new jasmine.MessageResult(message)); +jasmine.NestedResults.prototype.log = function(values) { + this.items_.push(new jasmine.MessageResult(values)); }; /** @@ -1886,8 +1894,8 @@ jasmine.Spec.prototype.results = function() { return this.results_; }; -jasmine.Spec.prototype.log = function(message) { - return this.results_.log(message); +jasmine.Spec.prototype.log = function() { + return this.results_.log(arguments); }; /** @deprecated */ @@ -2106,15 +2114,15 @@ jasmine.Suite.prototype.results = function() { return this.queue.results(); }; -jasmine.Suite.prototype.add = function(block) { - this.children_.push(block); - if (block instanceof jasmine.Suite) { - this.suites_.push(block); - this.env.currentRunner().addSuite(block); +jasmine.Suite.prototype.add = function(suiteOrSpec) { + this.children_.push(suiteOrSpec); + if (suiteOrSpec instanceof jasmine.Suite) { + this.suites_.push(suiteOrSpec); + this.env.currentRunner().addSuite(suiteOrSpec); } else { - this.specs_.push(block); + this.specs_.push(suiteOrSpec); } - this.queue.add(block); + this.queue.add(suiteOrSpec); }; jasmine.Suite.prototype.specs = function() { @@ -2367,5 +2375,5 @@ jasmine.version_= { "major": 0, "minor": 10, "build": 4, - "revision": 1277227072 + "revision": 1277234552 }; diff --git a/spec/runner.html b/spec/runner.html index c61a74b..416cd51 100644 --- a/spec/runner.html +++ b/spec/runner.html @@ -34,6 +34,7 @@ + diff --git a/spec/suites/BaseSpec.js b/spec/suites/BaseSpec.js new file mode 100644 index 0000000..33256f9 --- /dev/null +++ b/spec/suites/BaseSpec.js @@ -0,0 +1,15 @@ +describe("jasmine.MessageResult", function() { + it("#toString should pretty-print and concatenate each part of the message", function() { + var values = ["log", "message", 123, {key: "value"}, "FTW!"]; + var messageResult = new jasmine.MessageResult(values); + expect(messageResult.toString()).toEqual("log message 123 { key : 'value' } FTW!"); + }); +}); + +describe("jasmine.log", function() { + it("should accept n arguments", function() { + spyOn(jasmine.getEnv().currentSpec, 'log'); + jasmine.log(1, 2, 3); + expect(jasmine.getEnv().currentSpec.log).wasCalledWith(1, 2, 3); + }); +}); \ No newline at end of file diff --git a/spec/suites/JsApiReporterSpec.js b/spec/suites/JsApiReporterSpec.js index aa52258..2437e46 100644 --- a/spec/suites/JsApiReporterSpec.js +++ b/spec/suites/JsApiReporterSpec.js @@ -1,6 +1,4 @@ describe('jasmine.jsApiReporter', function() { - - describe('results', function () { var reporter, spec1, spec2, spec3, expectedSpec1Results, expectedSpec2Results; var env; @@ -82,8 +80,8 @@ describe('jasmine.jsApiReporter', function() { expect(summarizedResult.messages[0].message).toEqual(result.messages[0].message); expect(summarizedResult.messages[0].passed).toBeTruthy(); expect(summarizedResult.messages[0].type).toEqual('ExpectationResult'); - expect(summarizedResult.messages[0].text).toEqual(jasmine.undefined); - expect(summarizedResult.messages[0].trace.stack).toEqual(jasmine.undefined); + expect(summarizedResult.messages[0].text).toBeUndefined(); + expect(summarizedResult.messages[0].trace.stack).toBeUndefined(); }); it("should have a stack trace for failing specs", function() { @@ -97,6 +95,7 @@ describe('jasmine.jsApiReporter', function() { var result = reporter.results()[spec3.id]; var summarizedResult = reporter.summarizeResult_(result); expect(summarizedResult.result).toEqual('passed'); + expect(summarizedResult.messages[0].type).toEqual('MessageResult'); expect(summarizedResult.messages[0].text).toEqual('some debug message'); }); }); diff --git a/spec/suites/SpecSpec.js b/spec/suites/SpecSpec.js index de6640d..7a83258 100644 --- a/spec/suites/SpecSpec.js +++ b/spec/suites/SpecSpec.js @@ -34,7 +34,6 @@ describe('Spec', function () { expect(spec2.id).toEqual(1); expect(spec3.id).toEqual(2); }); - }); it('getFullName returns suite & spec description', function () { @@ -106,5 +105,20 @@ describe('Spec', function () { expect(results.passed()).toEqual(true); }); }); + + it("includes log messages, which may contain arbitary objects", function() { + spec.runs(function() { + this.log("here's some log message", {key: 'value'}, 123); + }); + spec.execute(); + var items = results.getItems(); + expect(items).toEqual([ + jasmine.any(jasmine.ExpectationResult), + jasmine.any(jasmine.ExpectationResult), + jasmine.any(jasmine.MessageResult) + ]); + var logResult = items[2]; + expect(logResult.values).toEqual(["here's some log message", {key: 'value'}, 123]); + }); }); }); \ No newline at end of file diff --git a/spec/suites/TrivialReporterSpec.js b/spec/suites/TrivialReporterSpec.js index a7ab433..23cc314 100644 --- a/spec/suites/TrivialReporterSpec.js +++ b/spec/suites/TrivialReporterSpec.js @@ -1,9 +1,16 @@ describe("TrivialReporter", function() { + var env; var trivialReporter; var body; + var fakeDocument; beforeEach(function() { + env = new jasmine.Env(); + env.updateInterval = 0; + body = document.createElement("body"); + fakeDocument = { body: body, location: { search: "" } }; + trivialReporter = new jasmine.TrivialReporter(fakeDocument); }); function fakeSpec(name) { @@ -17,6 +24,7 @@ describe("TrivialReporter", function() { function findElements(divs, withClass) { var els = []; for (var i = 0; i < divs.length; i++) { + console.log(divs[i], divs[i].className); if (divs[i].className == withClass) els.push(divs[i]); } return els; @@ -29,16 +37,15 @@ describe("TrivialReporter", function() { } it("should run only specs beginning with spec parameter", function() { - var trivialReporter = new jasmine.TrivialReporter({ location: {search: "?spec=run%20this"} }); + fakeDocument.location.search = "?spec=run%20this"; expect(trivialReporter.specFilter(fakeSpec("run this"))).toBeTruthy(); expect(trivialReporter.specFilter(fakeSpec("not the right spec"))).toBeFalsy(); expect(trivialReporter.specFilter(fakeSpec("not run this"))).toBeFalsy(); }); it("should display empty divs for every suite when the runner is starting", function() { - var trivialReporter = new jasmine.TrivialReporter({ body: body }); trivialReporter.reportRunnerStarting({ - env: new jasmine.Env(), + env: env, suites: function() { return [ new jasmine.Suite({}, "suite 1", null, null) ]; } @@ -61,7 +68,6 @@ describe("TrivialReporter", function() { var runner, spec, fakeTimer; beforeEach(function () { - var env = new jasmine.Env(); fakeTimer = new jasmine.FakeTimer(); env.setTimeout = fakeTimer.setTimeout; env.clearTimeout = fakeTimer.clearTimeout; @@ -72,7 +78,7 @@ describe("TrivialReporter", function() { runner.add(suite); spec = new jasmine.Spec(env, suite, 'some spec'); suite.add(spec); - var trivialReporter = new jasmine.TrivialReporter({ body: body, location: {search: "?"} }); + fakeDocument.location.search = "?"; env.addReporter(trivialReporter); }); @@ -117,9 +123,8 @@ describe("TrivialReporter", function() { } }; - trivialReporter = new jasmine.TrivialReporter({ body: body }); trivialReporter.reportRunnerStarting({ - env: new jasmine.Env(), + env: env, suites: function() { return [ new jasmine.Suite({}, "suite 1", null, null) ]; } @@ -155,4 +160,20 @@ describe("TrivialReporter", function() { }); }); + describe("log messages", function() { + it("should appear in the report", function() { + env.describe("suite", function() { + env.it("will have log messages", function() { + this.log("this is a", "multipart log message"); + }); + }); + + env.addReporter(trivialReporter); + env.execute(); + + var divs = body.getElementsByTagName("div"); + var errorDiv = findElement(divs, 'resultMessage log'); + expect(errorDiv.innerHTML).toEqual("this is a multipart log message"); + }); + }); }); diff --git a/src/JsApiReporter.js b/src/JsApiReporter.js index 7f4d8a5..f897839 100644 --- a/src/JsApiReporter.js +++ b/src/JsApiReporter.js @@ -80,11 +80,11 @@ jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ var summaryMessages = []; - var messagesLength = result.messages.length + var messagesLength = result.messages.length; for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { var resultMessage = result.messages[messageIndex]; summaryMessages.push({ - text: resultMessage.text, + text: resultMessage.type == 'MessageResult' ? resultMessage.toString() : jasmine.undefined, passed: resultMessage.passed ? resultMessage.passed() : true, type: resultMessage.type, message: resultMessage.message, @@ -92,13 +92,11 @@ jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined } }); - }; + } - var summaryResult = { + return { result : result.result, messages : summaryMessages }; - - return summaryResult; }; diff --git a/src/NestedResults.js b/src/NestedResults.js index 69de9e0..461c133 100644 --- a/src/NestedResults.js +++ b/src/NestedResults.js @@ -38,11 +38,11 @@ jasmine.NestedResults.prototype.rollupCounts = function(result) { }; /** - * Tracks a result's message. - * @param message + * Adds a log message. + * @param values Array of message parts which will be concatenated later. */ -jasmine.NestedResults.prototype.log = function(message) { - this.items_.push(new jasmine.MessageResult(message)); +jasmine.NestedResults.prototype.log = function(values) { + this.items_.push(new jasmine.MessageResult(values)); }; /** diff --git a/src/Spec.js b/src/Spec.js index e84adfa..8e074b6 100644 --- a/src/Spec.js +++ b/src/Spec.js @@ -37,8 +37,8 @@ jasmine.Spec.prototype.results = function() { return this.results_; }; -jasmine.Spec.prototype.log = function(message) { - return this.results_.log(message); +jasmine.Spec.prototype.log = function() { + return this.results_.log(arguments); }; /** @deprecated */ diff --git a/src/base.js b/src/base.js index 2948888..f373aa5 100755 --- a/src/base.js +++ b/src/base.js @@ -51,14 +51,23 @@ jasmine.clearTimeout = jasmine.bindOriginal_(window, 'clearTimeout'); jasmine.setInterval = jasmine.bindOriginal_(window, 'setInterval'); jasmine.clearInterval = jasmine.bindOriginal_(window, 'clearInterval'); -jasmine.MessageResult = function(text) { +jasmine.MessageResult = function(values) { this.type = 'MessageResult'; - this.text = text; + this.values = values; this.trace = new Error(); // todo: test better }; jasmine.MessageResult.prototype.toString = function() { - return this.text; + var text = ""; + for(var i = 0; i < this.values.length; i++) { + if (i > 0) text += " "; + if (jasmine.isString_(this.values[i])) { + text += this.values[i]; + } else { + text += jasmine.pp(this.values[i]); + } + } + return text; }; jasmine.ExpectationResult = function(params) { @@ -395,8 +404,9 @@ jasmine.createSpyObj = function(baseName, methodNames) { return obj; }; -jasmine.log = function(message) { - jasmine.getEnv().currentSpec.log(message); +jasmine.log = function() { + var spec = jasmine.getEnv().currentSpec; + spec.log.apply(spec, arguments); }; /**