From 5afe1222f45b7f8eebd7f9da8f9dce7b12728cf8 Mon Sep 17 00:00:00 2001 From: Gregg Van Hove Date: Mon, 5 Feb 2018 11:19:15 -0800 Subject: [PATCH 1/5] Add ability to report deprecation warnings from within the suite [#154746527] --- lib/jasmine-core/jasmine.js | 26 ++++++++++++++-- spec/core/SpecSpec.js | 1 + spec/core/integration/EnvSpec.js | 52 ++++++++++++++++++++++++++++++++ src/core/Env.js | 12 +++++++- src/core/Spec.js | 6 ++++ src/core/Suite.js | 8 ++++- 6 files changed, 101 insertions(+), 4 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 23d1441d..ea582c8f 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -505,6 +505,7 @@ getJasmineRequireObj().Spec = function(j$) { * @property {String} fullName - The full description including all ancestors of this spec. * @property {Expectation[]} failedExpectations - The list of expectations that failed during execution of this spec. * @property {Expectation[]} passedExpectations - The list of expectations that passed during execution of this spec. + * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec. * @property {String} pendingReason - If the spec is {@link pending}, this will be the reason. * @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec. */ @@ -514,6 +515,7 @@ getJasmineRequireObj().Spec = function(j$) { fullName: this.getFullName(), failedExpectations: [], passedExpectations: [], + deprecationWarnings: [], pendingReason: '' }; } @@ -629,6 +631,10 @@ getJasmineRequireObj().Spec = function(j$) { return this.getSpecName(this); }; + Spec.prototype.addDeprecationWarning = function(msg) { + this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg })); + }; + var extractCustomPendingMessage = function(e) { var fullMessage = e.toString(), boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage), @@ -933,6 +939,14 @@ getJasmineRequireObj().Env = function(j$) { return seed; }; + this.deprecated = function(msg) { + var runnable = currentRunnable() || topSuite; + runnable.addDeprecationWarning(msg); + if(typeof console !== 'undefined' && typeof console.warn !== 'undefined') { + console.error('DEPRECATION: ' + msg); + } + }; + var queueRunnerFactory = function(options) { options.catchException = catchException; options.clearStack = options.clearStack || clearStack; @@ -1025,10 +1039,12 @@ getJasmineRequireObj().Env = function(j$) { * @typedef JasmineDoneInfo * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. * @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level. + * @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level. */ reporter.jasmineDone({ order: order, - failedExpectations: topSuite.result.failedExpectations + failedExpectations: topSuite.result.failedExpectations, + deprecationWarnings: topSuite.result.deprecationWarnings }); }); }; @@ -5147,13 +5163,15 @@ getJasmineRequireObj().Suite = function(j$) { * @property {String} description - The description text passed to the {@link describe} that made this suite. * @property {String} fullName - The full description including all ancestors of this suite. * @property {Expectation[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite. + * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite. * @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite. */ this.result = { id: this.id, description: this.description, fullName: this.getFullName(), - failedExpectations: [] + failedExpectations: [], + deprecationWarnings: [] }; } @@ -5273,6 +5291,10 @@ getJasmineRequireObj().Suite = function(j$) { } }; + Suite.prototype.addDeprecationWarning = function(msg) { + this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg })); + }; + function isAfterAll(children) { return children && children[0].result.status; } diff --git a/spec/core/SpecSpec.js b/spec/core/SpecSpec.js index 8bc538da..6118ffb0 100644 --- a/spec/core/SpecSpec.js +++ b/spec/core/SpecSpec.js @@ -222,6 +222,7 @@ describe("Spec", function() { fullName: 'a suite with a spec', failedExpectations: [], passedExpectations: [], + deprecationWarnings: [], pendingReason: '' }); }); diff --git a/spec/core/integration/EnvSpec.js b/spec/core/integration/EnvSpec.js index 0adbad94..25d6d69c 100644 --- a/spec/core/integration/EnvSpec.js +++ b/spec/core/integration/EnvSpec.js @@ -2004,4 +2004,56 @@ describe("Env integration", function() { env.execute(); }); + + it('should report deprecation warnings on the correct specs and suites', function(done) { + var env = new jasmineUnderTest.Env(), + reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']); + + reporter.jasmineDone.and.callFake(function(result) { + expect(result.deprecationWarnings).toEqual([ + jasmine.objectContaining({ + message: 'top level deprecation', + stack: jasmine.any(String) + }) + ]); + + expect(reporter.suiteDone).toHaveBeenCalledWith(jasmine.objectContaining({ + fullName: 'suite', + deprecationWarnings: [ + jasmine.objectContaining({ + message: 'suite level deprecation', + stack: jasmine.any(String) + }) + ] + })); + + expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({ + fullName: 'suite spec', + deprecationWarnings: [ + jasmine.objectContaining({ + message: 'spec level deprecation', + stack: jasmine.any(String) + }) + ] + })); + + done(); + }); + + env.addReporter(reporter); + + env.deprecated('top level deprecation'); + + env.describe('suite', function() { + env.beforeAll(function() { + env.deprecated('suite level deprecation'); + }); + + env.it('spec', function() { + env.deprecated('spec level deprecation'); + }); + }); + + env.execute(); + }); }); diff --git a/src/core/Env.js b/src/core/Env.js index 9655f15d..af1ad374 100644 --- a/src/core/Env.js +++ b/src/core/Env.js @@ -234,6 +234,14 @@ getJasmineRequireObj().Env = function(j$) { return seed; }; + this.deprecated = function(msg) { + var runnable = currentRunnable() || topSuite; + runnable.addDeprecationWarning(msg); + if(typeof console !== 'undefined' && typeof console.warn !== 'undefined') { + console.error('DEPRECATION: ' + msg); + } + }; + var queueRunnerFactory = function(options) { options.catchException = catchException; options.clearStack = options.clearStack || clearStack; @@ -326,10 +334,12 @@ getJasmineRequireObj().Env = function(j$) { * @typedef JasmineDoneInfo * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. * @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level. + * @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level. */ reporter.jasmineDone({ order: order, - failedExpectations: topSuite.result.failedExpectations + failedExpectations: topSuite.result.failedExpectations, + deprecationWarnings: topSuite.result.deprecationWarnings }); }); }; diff --git a/src/core/Spec.js b/src/core/Spec.js index c2ee8a58..f5e50e0f 100644 --- a/src/core/Spec.js +++ b/src/core/Spec.js @@ -25,6 +25,7 @@ getJasmineRequireObj().Spec = function(j$) { * @property {String} fullName - The full description including all ancestors of this spec. * @property {Expectation[]} failedExpectations - The list of expectations that failed during execution of this spec. * @property {Expectation[]} passedExpectations - The list of expectations that passed during execution of this spec. + * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec. * @property {String} pendingReason - If the spec is {@link pending}, this will be the reason. * @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec. */ @@ -34,6 +35,7 @@ getJasmineRequireObj().Spec = function(j$) { fullName: this.getFullName(), failedExpectations: [], passedExpectations: [], + deprecationWarnings: [], pendingReason: '' }; } @@ -149,6 +151,10 @@ getJasmineRequireObj().Spec = function(j$) { return this.getSpecName(this); }; + Spec.prototype.addDeprecationWarning = function(msg) { + this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg })); + }; + var extractCustomPendingMessage = function(e) { var fullMessage = e.toString(), boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage), diff --git a/src/core/Suite.js b/src/core/Suite.js index e85ab04e..8a3bef2f 100644 --- a/src/core/Suite.js +++ b/src/core/Suite.js @@ -21,13 +21,15 @@ getJasmineRequireObj().Suite = function(j$) { * @property {String} description - The description text passed to the {@link describe} that made this suite. * @property {String} fullName - The full description including all ancestors of this suite. * @property {Expectation[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite. + * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite. * @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite. */ this.result = { id: this.id, description: this.description, fullName: this.getFullName(), - failedExpectations: [] + failedExpectations: [], + deprecationWarnings: [] }; } @@ -147,6 +149,10 @@ getJasmineRequireObj().Suite = function(j$) { } }; + Suite.prototype.addDeprecationWarning = function(msg) { + this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg })); + }; + function isAfterAll(children) { return children && children[0].result.status; } From 24bf3489dccfa6987fcf8d79eb36eec25963ee61 Mon Sep 17 00:00:00 2001 From: Gregg Van Hove Date: Mon, 5 Feb 2018 12:11:36 -0800 Subject: [PATCH 2/5] Display deprecation warnings in HTML reporter - Also no longer check for stack since IE doesn't do that [#154746527] --- lib/jasmine-core/jasmine-html.js | 20 +++++++++++++++- lib/jasmine-core/jasmine.css | 1 + spec/core/integration/EnvSpec.js | 15 +++--------- spec/html/HtmlReporterSpec.js | 41 ++++++++++++++++++++++++++++++++ src/html/HtmlReporter.js | 20 +++++++++++++++- src/html/_HTMLReporter.scss | 4 ++++ 6 files changed, 87 insertions(+), 14 deletions(-) diff --git a/lib/jasmine-core/jasmine-html.js b/lib/jasmine-core/jasmine-html.js index 221a15d5..a5c29417 100644 --- a/lib/jasmine-core/jasmine-html.js +++ b/lib/jasmine-core/jasmine-html.js @@ -88,7 +88,8 @@ jasmineRequire.HtmlReporter = function(j$) { results = [], htmlReporterMain, symbols, - failedSuites = []; + failedSuites = [], + deprecationWarnings = []; this.initialize = function() { clearPrior(); @@ -126,6 +127,7 @@ jasmineRequire.HtmlReporter = function(j$) { } stateBuilder.suiteDone(result); + addDeprecationWarnings(result); }; this.specStarted = function(result) { @@ -169,6 +171,8 @@ jasmineRequire.HtmlReporter = function(j$) { failures.push(failure); } + + addDeprecationWarnings(result); }; this.jasmineDone = function(doneResult) { @@ -278,6 +282,14 @@ jasmineRequire.HtmlReporter = function(j$) { alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failure.message)); } + addDeprecationWarnings(doneResult); + + var warningBarClassName = 'jasmine-bar jasmine-warning'; + for(i = 0; i < deprecationWarnings.length; i++) { + var warning = deprecationWarnings[i]; + alert.appendChild(createDom('span', {className: warningBarClassName}, 'DEPRECATION: ' + warning.message)); + } + var results = find('.jasmine-results'); results.appendChild(summary); @@ -352,6 +364,12 @@ jasmineRequire.HtmlReporter = function(j$) { return this; + function addDeprecationWarnings(result) { + if (result && result.deprecationWarnings && result.deprecationWarnings.length > 0) { + deprecationWarnings = deprecationWarnings.concat(result.deprecationWarnings); + } + } + function find(selector) { return getContainer().querySelector('.jasmine_html-reporter ' + selector); } diff --git a/lib/jasmine-core/jasmine.css b/lib/jasmine-core/jasmine.css index 63199827..3144f266 100644 --- a/lib/jasmine-core/jasmine.css +++ b/lib/jasmine-core/jasmine.css @@ -33,6 +33,7 @@ body { overflow-y: scroll; } .jasmine_html-reporter .jasmine-bar.jasmine-passed { background-color: #007069; } .jasmine_html-reporter .jasmine-bar.jasmine-skipped { background-color: #bababa; } .jasmine_html-reporter .jasmine-bar.jasmine-errored { background-color: #ca3a11; } +.jasmine_html-reporter .jasmine-bar.jasmine-warning { background-color: #ba9d37; } .jasmine_html-reporter .jasmine-bar.jasmine-menu { background-color: #fff; color: #aaa; } .jasmine_html-reporter .jasmine-bar.jasmine-menu a { color: #333; } .jasmine_html-reporter .jasmine-bar a { color: white; } diff --git a/spec/core/integration/EnvSpec.js b/spec/core/integration/EnvSpec.js index 25d6d69c..9e3ab587 100644 --- a/spec/core/integration/EnvSpec.js +++ b/spec/core/integration/EnvSpec.js @@ -2011,29 +2011,20 @@ describe("Env integration", function() { reporter.jasmineDone.and.callFake(function(result) { expect(result.deprecationWarnings).toEqual([ - jasmine.objectContaining({ - message: 'top level deprecation', - stack: jasmine.any(String) - }) + jasmine.objectContaining({ message: 'top level deprecation' }) ]); expect(reporter.suiteDone).toHaveBeenCalledWith(jasmine.objectContaining({ fullName: 'suite', deprecationWarnings: [ - jasmine.objectContaining({ - message: 'suite level deprecation', - stack: jasmine.any(String) - }) + jasmine.objectContaining({ message: 'suite level deprecation' }) ] })); expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({ fullName: 'suite spec', deprecationWarnings: [ - jasmine.objectContaining({ - message: 'spec level deprecation', - stack: jasmine.any(String) - }) + jasmine.objectContaining({ message: 'spec level deprecation' }) ] })); diff --git a/spec/html/HtmlReporterSpec.js b/spec/html/HtmlReporterSpec.js index 59138c8a..c585b79e 100644 --- a/spec/html/HtmlReporterSpec.js +++ b/spec/html/HtmlReporterSpec.js @@ -208,6 +208,47 @@ describe("New HtmlReporter", function() { }); }); + describe('when there are deprecation warnings', function() { + it('displays the messages in their own alert bars', function() { + var env = new jasmineUnderTest.Env(), + container = document.createElement('div'), + getContainer = function() { return container; }, + reporter = new jasmineUnderTest.HtmlReporter({ + env: env, + getContainer: getContainer, + createElement: function() { return document.createElement.apply(document, arguments); }, + createTextNode: function() { return document.createTextNode.apply(document, arguments); } + }); + + reporter.initialize(); + + reporter.jasmineStarted({}); + reporter.specDone({ + status: 'passed', + deprecationWarnings: [{ message: 'spec deprecation' }], + failedExpectations: [], + passedExpectations: [] + }); + reporter.suiteDone({ + status: 'passed', + deprecationWarnings: [{ message: 'suite deprecation' }], + failedExpectations: [] + }); + reporter.jasmineDone({ + deprecationWarnings: [{ message: 'global deprecation' }], + failedExpectations: [] + }); + + var alertBars = container.querySelectorAll(".jasmine-alert .jasmine-bar"); + + expect(alertBars.length).toEqual(4); + expect(alertBars[1].innerHTML).toMatch(/spec deprecation/); + expect(alertBars[1].getAttribute("class")).toEqual('jasmine-bar jasmine-warning'); + expect(alertBars[2].innerHTML).toMatch(/suite deprecation/); + expect(alertBars[3].innerHTML).toMatch(/global deprecation/); + }); + }); + describe("when Jasmine is done", function() { it("adds a warning to the link title of specs that have no expectations", function() { if (!window.console) { diff --git a/src/html/HtmlReporter.js b/src/html/HtmlReporter.js index 6ce6a41b..724050e6 100644 --- a/src/html/HtmlReporter.js +++ b/src/html/HtmlReporter.js @@ -59,7 +59,8 @@ jasmineRequire.HtmlReporter = function(j$) { results = [], htmlReporterMain, symbols, - failedSuites = []; + failedSuites = [], + deprecationWarnings = []; this.initialize = function() { clearPrior(); @@ -97,6 +98,7 @@ jasmineRequire.HtmlReporter = function(j$) { } stateBuilder.suiteDone(result); + addDeprecationWarnings(result); }; this.specStarted = function(result) { @@ -140,6 +142,8 @@ jasmineRequire.HtmlReporter = function(j$) { failures.push(failure); } + + addDeprecationWarnings(result); }; this.jasmineDone = function(doneResult) { @@ -249,6 +253,14 @@ jasmineRequire.HtmlReporter = function(j$) { alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failure.message)); } + addDeprecationWarnings(doneResult); + + var warningBarClassName = 'jasmine-bar jasmine-warning'; + for(i = 0; i < deprecationWarnings.length; i++) { + var warning = deprecationWarnings[i]; + alert.appendChild(createDom('span', {className: warningBarClassName}, 'DEPRECATION: ' + warning.message)); + } + var results = find('.jasmine-results'); results.appendChild(summary); @@ -323,6 +335,12 @@ jasmineRequire.HtmlReporter = function(j$) { return this; + function addDeprecationWarnings(result) { + if (result && result.deprecationWarnings && result.deprecationWarnings.length > 0) { + deprecationWarnings = deprecationWarnings.concat(result.deprecationWarnings); + } + } + function find(selector) { return getContainer().querySelector('.jasmine_html-reporter ' + selector); } diff --git a/src/html/_HTMLReporter.scss b/src/html/_HTMLReporter.scss index 093692b9..de8d0145 100644 --- a/src/html/_HTMLReporter.scss +++ b/src/html/_HTMLReporter.scss @@ -216,6 +216,10 @@ body { background-color: $failing-color; } + &.jasmine-warning { + background-color: $pending-color; + } + &.jasmine-menu { background-color: #fff; color: $faint-text-color; From c142490c6951b86f48fa0cee25f4e2434546b1c9 Mon Sep 17 00:00:00 2001 From: Gregg Van Hove Date: Mon, 5 Feb 2018 14:01:46 -0800 Subject: [PATCH 3/5] Add deprecation messages for things that will change/break in 3.0 [#154746527] --- lib/jasmine-core/jasmine-html.js | 11 ++++++++--- lib/jasmine-core/jasmine.css | 2 +- lib/jasmine-core/jasmine.js | 24 ++++++++++++++++++++++-- src/core/Env.js | 12 ++++++++++++ src/core/QueueRunner.js | 9 +++++++-- src/core/asymmetric_equality/Any.js | 3 +++ src/html/HtmlReporter.js | 11 ++++++++--- src/html/_HTMLReporter.scss | 1 + 8 files changed, 62 insertions(+), 11 deletions(-) diff --git a/lib/jasmine-core/jasmine-html.js b/lib/jasmine-core/jasmine-html.js index a5c29417..09f09847 100644 --- a/lib/jasmine-core/jasmine-html.js +++ b/lib/jasmine-core/jasmine-html.js @@ -287,7 +287,7 @@ jasmineRequire.HtmlReporter = function(j$) { var warningBarClassName = 'jasmine-bar jasmine-warning'; for(i = 0; i < deprecationWarnings.length; i++) { var warning = deprecationWarnings[i]; - alert.appendChild(createDom('span', {className: warningBarClassName}, 'DEPRECATION: ' + warning.message)); + alert.appendChild(createDom('span', {className: warningBarClassName}, 'DEPRECATION: ' + warning)); } var results = find('.jasmine-results'); @@ -365,8 +365,13 @@ jasmineRequire.HtmlReporter = function(j$) { return this; function addDeprecationWarnings(result) { - if (result && result.deprecationWarnings && result.deprecationWarnings.length > 0) { - deprecationWarnings = deprecationWarnings.concat(result.deprecationWarnings); + if (result && result.deprecationWarnings) { + for(var i = 0; i < result.deprecationWarnings.length; i++) { + var warning = result.deprecationWarnings[i].message; + if (deprecationWarnings.indexOf(warning) < 0) { + deprecationWarnings.push(warning); + } + } } } diff --git a/lib/jasmine-core/jasmine.css b/lib/jasmine-core/jasmine.css index 3144f266..5207c5b2 100644 --- a/lib/jasmine-core/jasmine.css +++ b/lib/jasmine-core/jasmine.css @@ -33,7 +33,7 @@ body { overflow-y: scroll; } .jasmine_html-reporter .jasmine-bar.jasmine-passed { background-color: #007069; } .jasmine_html-reporter .jasmine-bar.jasmine-skipped { background-color: #bababa; } .jasmine_html-reporter .jasmine-bar.jasmine-errored { background-color: #ca3a11; } -.jasmine_html-reporter .jasmine-bar.jasmine-warning { background-color: #ba9d37; } +.jasmine_html-reporter .jasmine-bar.jasmine-warning { background-color: #ba9d37; color: #333; } .jasmine_html-reporter .jasmine-bar.jasmine-menu { background-color: #fff; color: #aaa; } .jasmine_html-reporter .jasmine-bar.jasmine-menu a { color: #333; } .jasmine_html-reporter .jasmine-bar a { color: white; } diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index ea582c8f..80fee4a5 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -716,6 +716,8 @@ getJasmineRequireObj().Env = function(j$) { var self = this; var global = options.global || j$.getGlobal(); + var hasExecuted = false; + var totalSpecsDefined = 0; var catchExceptions = true; @@ -901,6 +903,7 @@ getJasmineRequireObj().Env = function(j$) { // TODO: fix this naming, and here's where the value comes in this.catchExceptions = function(value) { + this.deprecated('The catchExceptions option is deprecated and will be replaced with stopOnSpecFailure in Jasmine 3.0'); catchExceptions = !!value; return catchExceptions; }; @@ -954,6 +957,7 @@ getJasmineRequireObj().Env = function(j$) { options.fail = self.fail; options.globalErrors = globalErrors; options.completeOnFirstError = throwOnExpectationFailure && options.isLeaf; + options.deprecated = self.deprecated; new j$.QueueRunner(options).execute(); }; @@ -973,6 +977,12 @@ getJasmineRequireObj().Env = function(j$) { }; this.execute = function(runnablesToRun) { + if (hasExecuted) { + this.deprecated('Executing the same Jasmine multiple times will no longer work in Jasmine 3.0'); + } + + hasExecuted = true; + if(!runnablesToRun) { if (focusedRunnables.length) { runnablesToRun = focusedRunnables; @@ -1146,6 +1156,7 @@ getJasmineRequireObj().Env = function(j$) { var focusedRunnables = []; this.fdescribe = function(description, specDefinitions) { + this.deprecated('fit and fdescribe will cause your suite to report an \'incomplete\' status in Jasmine 3.0'); ensureIsNotNested('fdescribe'); ensureIsFunction(specDefinitions, 'fdescribe'); var suite = suiteFactory(description); @@ -1271,6 +1282,7 @@ getJasmineRequireObj().Env = function(j$) { }; this.fit = function(description, fn, timeout){ + this.deprecated('fit and fdescribe will cause your suite to report an \'incomplete\' status in Jasmine 3.0'); ensureIsNotNested('fit'); ensureIsFunctionOrAsync(fn, 'fit'); var spec = specFactory(description, fn, currentDeclarationSuite, timeout); @@ -1526,6 +1538,9 @@ getJasmineRequireObj().Any = function(j$) { } if (this.expectedObject == Object) { + if (other === null) { + j$.getEnv().deprecated('jasmine.Any(Object) will no longer match null in Jasmine 3.0'); + } return typeof other == 'object'; } @@ -4336,7 +4351,7 @@ getJasmineRequireObj().QueueRunner = function(j$) { return function() { if (!called) { called = true; - fn(); + fn.apply(null, arguments); } return null; }; @@ -4355,6 +4370,7 @@ getJasmineRequireObj().QueueRunner = function(j$) { this.fail = attrs.fail || function() {}; this.globalErrors = attrs.globalErrors || { pushListener: function() {}, popListener: function() {} }; this.completeOnFirstError = !!attrs.completeOnFirstError; + this.deprecated = attrs.deprecated; } QueueRunner.prototype.execute = function() { @@ -4414,9 +4430,13 @@ getJasmineRequireObj().QueueRunner = function(j$) { clearTimeout(timeoutId); self.globalErrors.popListener(handleError); }), - next = once(function () { + next = once(function (err) { cleanup(); + if (err instanceof Error) { + self.deprecated('done callback received an Error object. Jasmine 3.0 will treat this as a failure'); + } + function runNext() { if (self.completeOnFirstError && errored) { self.skipToCleanup(iterativeIndex); diff --git a/src/core/Env.js b/src/core/Env.js index af1ad374..c62b7843 100644 --- a/src/core/Env.js +++ b/src/core/Env.js @@ -11,6 +11,8 @@ getJasmineRequireObj().Env = function(j$) { var self = this; var global = options.global || j$.getGlobal(); + var hasExecuted = false; + var totalSpecsDefined = 0; var catchExceptions = true; @@ -196,6 +198,7 @@ getJasmineRequireObj().Env = function(j$) { // TODO: fix this naming, and here's where the value comes in this.catchExceptions = function(value) { + this.deprecated('The catchExceptions option is deprecated and will be replaced with stopOnSpecFailure in Jasmine 3.0'); catchExceptions = !!value; return catchExceptions; }; @@ -249,6 +252,7 @@ getJasmineRequireObj().Env = function(j$) { options.fail = self.fail; options.globalErrors = globalErrors; options.completeOnFirstError = throwOnExpectationFailure && options.isLeaf; + options.deprecated = self.deprecated; new j$.QueueRunner(options).execute(); }; @@ -268,6 +272,12 @@ getJasmineRequireObj().Env = function(j$) { }; this.execute = function(runnablesToRun) { + if (hasExecuted) { + this.deprecated('Executing the same Jasmine multiple times will no longer work in Jasmine 3.0'); + } + + hasExecuted = true; + if(!runnablesToRun) { if (focusedRunnables.length) { runnablesToRun = focusedRunnables; @@ -441,6 +451,7 @@ getJasmineRequireObj().Env = function(j$) { var focusedRunnables = []; this.fdescribe = function(description, specDefinitions) { + this.deprecated('fit and fdescribe will cause your suite to report an \'incomplete\' status in Jasmine 3.0'); ensureIsNotNested('fdescribe'); ensureIsFunction(specDefinitions, 'fdescribe'); var suite = suiteFactory(description); @@ -566,6 +577,7 @@ getJasmineRequireObj().Env = function(j$) { }; this.fit = function(description, fn, timeout){ + this.deprecated('fit and fdescribe will cause your suite to report an \'incomplete\' status in Jasmine 3.0'); ensureIsNotNested('fit'); ensureIsFunctionOrAsync(fn, 'fit'); var spec = specFactory(description, fn, currentDeclarationSuite, timeout); diff --git a/src/core/QueueRunner.js b/src/core/QueueRunner.js index f422b49d..086f330d 100644 --- a/src/core/QueueRunner.js +++ b/src/core/QueueRunner.js @@ -5,7 +5,7 @@ getJasmineRequireObj().QueueRunner = function(j$) { return function() { if (!called) { called = true; - fn(); + fn.apply(null, arguments); } return null; }; @@ -24,6 +24,7 @@ getJasmineRequireObj().QueueRunner = function(j$) { this.fail = attrs.fail || function() {}; this.globalErrors = attrs.globalErrors || { pushListener: function() {}, popListener: function() {} }; this.completeOnFirstError = !!attrs.completeOnFirstError; + this.deprecated = attrs.deprecated; } QueueRunner.prototype.execute = function() { @@ -83,9 +84,13 @@ getJasmineRequireObj().QueueRunner = function(j$) { clearTimeout(timeoutId); self.globalErrors.popListener(handleError); }), - next = once(function () { + next = once(function (err) { cleanup(); + if (err instanceof Error) { + self.deprecated('done callback received an Error object. Jasmine 3.0 will treat this as a failure'); + } + function runNext() { if (self.completeOnFirstError && errored) { self.skipToCleanup(iterativeIndex); diff --git a/src/core/asymmetric_equality/Any.js b/src/core/asymmetric_equality/Any.js index 3f447529..960dd478 100644 --- a/src/core/asymmetric_equality/Any.js +++ b/src/core/asymmetric_equality/Any.js @@ -24,6 +24,9 @@ getJasmineRequireObj().Any = function(j$) { } if (this.expectedObject == Object) { + if (other === null) { + j$.getEnv().deprecated('jasmine.Any(Object) will no longer match null in Jasmine 3.0'); + } return typeof other == 'object'; } diff --git a/src/html/HtmlReporter.js b/src/html/HtmlReporter.js index 724050e6..85c19b77 100644 --- a/src/html/HtmlReporter.js +++ b/src/html/HtmlReporter.js @@ -258,7 +258,7 @@ jasmineRequire.HtmlReporter = function(j$) { var warningBarClassName = 'jasmine-bar jasmine-warning'; for(i = 0; i < deprecationWarnings.length; i++) { var warning = deprecationWarnings[i]; - alert.appendChild(createDom('span', {className: warningBarClassName}, 'DEPRECATION: ' + warning.message)); + alert.appendChild(createDom('span', {className: warningBarClassName}, 'DEPRECATION: ' + warning)); } var results = find('.jasmine-results'); @@ -336,8 +336,13 @@ jasmineRequire.HtmlReporter = function(j$) { return this; function addDeprecationWarnings(result) { - if (result && result.deprecationWarnings && result.deprecationWarnings.length > 0) { - deprecationWarnings = deprecationWarnings.concat(result.deprecationWarnings); + if (result && result.deprecationWarnings) { + for(var i = 0; i < result.deprecationWarnings.length; i++) { + var warning = result.deprecationWarnings[i].message; + if (deprecationWarnings.indexOf(warning) < 0) { + deprecationWarnings.push(warning); + } + } } } diff --git a/src/html/_HTMLReporter.scss b/src/html/_HTMLReporter.scss index de8d0145..8e8fa61f 100644 --- a/src/html/_HTMLReporter.scss +++ b/src/html/_HTMLReporter.scss @@ -218,6 +218,7 @@ body { &.jasmine-warning { background-color: $pending-color; + color: $text-color; } &.jasmine-menu { From 32f99ef99d3f14208034630dbb42989121addaf6 Mon Sep 17 00:00:00 2001 From: Gregg Van Hove Date: Mon, 5 Feb 2018 14:24:14 -0800 Subject: [PATCH 4/5] Use Jasmine's arrayContains to look for duplicate deprecations [#154746527] --- src/html/HtmlReporter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/html/HtmlReporter.js b/src/html/HtmlReporter.js index 85c19b77..18ea6432 100644 --- a/src/html/HtmlReporter.js +++ b/src/html/HtmlReporter.js @@ -339,7 +339,7 @@ jasmineRequire.HtmlReporter = function(j$) { if (result && result.deprecationWarnings) { for(var i = 0; i < result.deprecationWarnings.length; i++) { var warning = result.deprecationWarnings[i].message; - if (deprecationWarnings.indexOf(warning) < 0) { + if (!j$.util.arrayContains(warning)) { deprecationWarnings.push(warning); } } From 9911d37f06629c2f766598ba04ee56cf9a3289ff Mon Sep 17 00:00:00 2001 From: Gregg Van Hove Date: Mon, 5 Feb 2018 16:57:51 -0800 Subject: [PATCH 5/5] bump version to 2.99 --- lib/jasmine-core/version.rb | 2 +- package.json | 2 +- release_notes/2.99.md | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 release_notes/2.99.md diff --git a/lib/jasmine-core/version.rb b/lib/jasmine-core/version.rb index 26125ac0..f120958d 100644 --- a/lib/jasmine-core/version.rb +++ b/lib/jasmine-core/version.rb @@ -4,6 +4,6 @@ # module Jasmine module Core - VERSION = "2.9.1" + VERSION = "2.99.0" end end diff --git a/package.json b/package.json index d1fb37f3..1050dc8f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jasmine-core", "license": "MIT", - "version": "2.9.1", + "version": "2.99.0", "repository": { "type": "git", "url": "https://github.com/jasmine/jasmine.git" diff --git a/release_notes/2.99.md b/release_notes/2.99.md new file mode 100644 index 00000000..405474fa --- /dev/null +++ b/release_notes/2.99.md @@ -0,0 +1,19 @@ +# Jasmine-Core 2.99 Release Notes + +## Summary + +This release is part of the upgrade path to Jasmine 3.0. It deprecates some functionality that will change. + +## Changes + +* Add ability to report deprecation warnings from within the suite and display them in the HTML reporter +* Add deprecation messages for things that will change/break in 3.0 +* * done for async functionality will now add a failure if it is invoked with an Error +* * Env.catchExceptions and the query param are going away, in favor of a more fully functional fail fast handler +* * jasmine.Any(Object) will no longer match null +* * Unhandled errors during suite load will be caught and reported as failures by Jasmine +* * Calling execute more than once on the same spec will definitely fail in 3.0 + +------ + +_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_