diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 1201ec00..22c24bec 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -1843,12 +1843,12 @@ getJasmineRequireObj().Env = function(j$) { function specStarted(spec, suite, next) { runner.currentSpec = spec; runableResources.initForRunable(spec.id, suite.id); - reporter.specStarted(spec.result, next); + reporter.specStarted(spec.result).then(next); } function reportSpecDone(spec, result, next) { spec.reportedDone = true; - reporter.specDone(result, next); + reporter.specDone(result).then(next); } this.it = function(description, fn, timeout) { @@ -7700,7 +7700,7 @@ getJasmineRequireObj().ReportDispatcher = function(j$) { for (const method of dispatchedMethods) { this[method] = (function(m) { return function() { - dispatch(m, arguments); + return dispatch(m, arguments); }; })(method); } @@ -7726,25 +7726,25 @@ getJasmineRequireObj().ReportDispatcher = function(j$) { if (reporters.length === 0 && fallbackReporter !== null) { reporters.push(fallbackReporter); } - const onComplete = args[args.length - 1]; - args = Array.from(args).splice(0, args.length - 1); const fns = []; for (const reporter of reporters) { addFn(fns, reporter, method, args); } - queueRunnerFactory({ - queueableFns: fns, - onComplete: onComplete, - isReporter: true, - onMultipleDone: function() { - onLateError( - new Error( - "An asynchronous reporter callback called its 'done' callback " + - 'more than once.' - ) - ); - } + return new Promise(function(resolve) { + queueRunnerFactory({ + queueableFns: fns, + onComplete: resolve, + isReporter: true, + onMultipleDone: function() { + onLateError( + new Error( + "An asynchronous reporter callback called its 'done' callback " + + 'more than once.' + ) + ); + } + }); }); } @@ -8400,7 +8400,6 @@ getJasmineRequireObj().Runner = function(j$) { this.executedBefore_ = true; this.hasFailures = false; - const totalSpecsDefined = this.totalSpecsDefined_(); const focusedRunables = this.focusedRunables_(); const config = this.getConfig_(); @@ -8439,7 +8438,7 @@ getJasmineRequireObj().Runner = function(j$) { nodeStart: (suite, next) => { this.currentlyExecutingSuites_.push(suite); this.runableResources_.initForRunable(suite.id, suite.parentSuite.id); - this.reporter_.suiteStarted(suite.result, next); + this.reporter_.suiteStarted(suite.result).then(next); suite.startTimer(); }, nodeComplete: (suite, result, next) => { @@ -8477,106 +8476,95 @@ getJasmineRequireObj().Runner = function(j$) { ); } + return this.execute2_(runablesToRun, order, processor); + } + + async execute2_(runablesToRun, order, processor) { + const totalSpecsDefined = this.totalSpecsDefined_(); + this.runableResources_.initForRunable(this.topSuite_.id); const jasmineTimer = new j$.Timer(); jasmineTimer.start(); + await this.reporter_.jasmineStarted({ + totalSpecsDefined, + order: order + }); + + this.currentlyExecutingSuites_.push(this.topSuite_); + return new Promise(resolve => { - /** - * Information passed to the {@link Reporter#jasmineStarted} event. - * @typedef JasmineStartedInfo - * @property {Int} totalSpecsDefined - The total number of specs defined in this suite. - * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. - * @since 2.0.0 - */ - this.reporter_.jasmineStarted( - { - totalSpecsDefined, - order: order - }, - () => { - this.currentlyExecutingSuites_.push(this.topSuite_); + processor.execute(() => { + (async () => { + if (this.topSuite_.hadBeforeAllFailure) { + await this.reportChildrenOfBeforeAllFailure_(this.topSuite_); + } - processor.execute(() => { - (async () => { - if (this.topSuite_.hadBeforeAllFailure) { - await this.reportChildrenOfBeforeAllFailure_(this.topSuite_); - } + this.runableResources_.clearForRunable(this.topSuite_.id); + this.currentlyExecutingSuites_.pop(); + let overallStatus, incompleteReason; - this.runableResources_.clearForRunable(this.topSuite_.id); - this.currentlyExecutingSuites_.pop(); - let overallStatus, incompleteReason; + if ( + this.hasFailures || + this.topSuite_.result.failedExpectations.length > 0 + ) { + overallStatus = 'failed'; + } else if (this.focusedRunables_().length > 0) { + overallStatus = 'incomplete'; + incompleteReason = 'fit() or fdescribe() was found'; + } else if (totalSpecsDefined === 0) { + overallStatus = 'incomplete'; + incompleteReason = 'No specs found'; + } else { + overallStatus = 'passed'; + } - if ( - this.hasFailures || - this.topSuite_.result.failedExpectations.length > 0 - ) { - overallStatus = 'failed'; - } else if (focusedRunables.length > 0) { - overallStatus = 'incomplete'; - incompleteReason = 'fit() or fdescribe() was found'; - } else if (totalSpecsDefined === 0) { - overallStatus = 'incomplete'; - incompleteReason = 'No specs found'; - } else { - overallStatus = 'passed'; - } - - /** - * Information passed to the {@link Reporter#jasmineDone} event. - * @typedef JasmineDoneInfo - * @property {OverallStatus} overallStatus - The overall result of the suite: 'passed', 'failed', or 'incomplete'. - * @property {Int} totalTime - The total time (in ms) that it took to execute the suite - * @property {IncompleteReason} incompleteReason - Explanation of why the suite was incomplete. - * @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. - * @since 2.4.0 - */ - const jasmineDoneInfo = { - overallStatus: overallStatus, - totalTime: jasmineTimer.elapsed(), - incompleteReason: incompleteReason, - order: order, - failedExpectations: this.topSuite_.result.failedExpectations, - deprecationWarnings: this.topSuite_.result.deprecationWarnings - }; - this.topSuite_.reportedDone = true; - this.reporter_.jasmineDone(jasmineDoneInfo, function() { - resolve(jasmineDoneInfo); - }); - })(); - }); - } - ); + /** + * Information passed to the {@link Reporter#jasmineDone} event. + * @typedef JasmineDoneInfo + * @property {OverallStatus} overallStatus - The overall result of the suite: 'passed', 'failed', or 'incomplete'. + * @property {Int} totalTime - The total time (in ms) that it took to execute the suite + * @property {IncompleteReason} incompleteReason - Explanation of why the suite was incomplete. + * @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. + * @since 2.4.0 + */ + const jasmineDoneInfo = { + overallStatus: overallStatus, + totalTime: jasmineTimer.elapsed(), + incompleteReason: incompleteReason, + order: order, + failedExpectations: this.topSuite_.result.failedExpectations, + deprecationWarnings: this.topSuite_.result.deprecationWarnings + }; + this.topSuite_.reportedDone = true; + await this.reporter_.jasmineDone(jasmineDoneInfo); + resolve(jasmineDoneInfo); + })(); + }); }); } reportSuiteDone_(suite, result, next) { suite.reportedDone = true; - this.reporter_.suiteDone(result, next); + this.reporter_.suiteDone(result).then(next); } async reportChildrenOfBeforeAllFailure_(suite) { for (const child of suite.children) { if (child instanceof j$.Suite) { - await new Promise(resolve => { - this.reporter_.suiteStarted(child.result, resolve); - }); + await this.reporter_.suiteStarted(child.result); await this.reportChildrenOfBeforeAllFailure_(child); // Marking the suite passed is consistent with how suites that // contain failed specs but no suite-level failures are reported. child.result.status = 'passed'; - await new Promise(resolve => { - this.reporter_.suiteDone(child.result, resolve); - }); + await this.reporter_.suiteDone(child.result); } else { /* a spec */ - await new Promise(resolve => { - this.reporter_.specStarted(child.result, resolve); - }); + await this.reporter_.specStarted(child.result); child.addExpectationResult( false, diff --git a/spec/core/ReportDispatcherSpec.js b/spec/core/ReportDispatcherSpec.js index d435239e..0bee1d00 100644 --- a/spec/core/ReportDispatcherSpec.js +++ b/spec/core/ReportDispatcherSpec.js @@ -18,13 +18,12 @@ describe('ReportDispatcher', function() { queueRunnerFactory ), reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']), - anotherReporter = jasmine.createSpyObj('reporter', ['foo', 'bar']), - completeCallback = jasmine.createSpy('complete'); + anotherReporter = jasmine.createSpyObj('reporter', ['foo', 'bar']); dispatcher.addReporter(reporter); dispatcher.addReporter(anotherReporter); - dispatcher.foo(123, 456, completeCallback); + dispatcher.foo(123, 456); expect(queueRunnerFactory).toHaveBeenCalledWith( jasmine.objectContaining({ @@ -47,7 +46,7 @@ describe('ReportDispatcher', function() { queueRunnerFactory.calls.reset(); - dispatcher.bar('a', 'b', completeCallback); + dispatcher.bar('a', 'b'); expect(queueRunnerFactory).toHaveBeenCalledWith( jasmine.objectContaining({ @@ -91,11 +90,10 @@ describe('ReportDispatcher', function() { ['foo', 'bar'], queueRunnerFactory ), - reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']), - completeCallback = jasmine.createSpy('complete'); + reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']); dispatcher.provideFallbackReporter(reporter); - dispatcher.foo(123, 456, completeCallback); + dispatcher.foo(123, 456); expect(queueRunnerFactory).toHaveBeenCalledWith( jasmine.objectContaining({ @@ -116,12 +114,11 @@ describe('ReportDispatcher', function() { queueRunnerFactory ), reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']), - fallbackReporter = jasmine.createSpyObj('otherReporter', ['foo', 'bar']), - completeCallback = jasmine.createSpy('complete'); + fallbackReporter = jasmine.createSpyObj('otherReporter', ['foo', 'bar']); dispatcher.provideFallbackReporter(fallbackReporter); dispatcher.addReporter(reporter); - dispatcher.foo(123, 456, completeCallback); + dispatcher.foo(123, 456); expect(queueRunnerFactory).toHaveBeenCalledWith( jasmine.objectContaining({ @@ -143,11 +140,10 @@ describe('ReportDispatcher', function() { queueRunnerFactory ), reporter1 = jasmine.createSpyObj('reporter1', ['foo', 'bar']), - reporter2 = jasmine.createSpyObj('reporter2', ['foo', 'bar']), - completeCallback = jasmine.createSpy('complete'); + reporter2 = jasmine.createSpyObj('reporter2', ['foo', 'bar']); dispatcher.addReporter(reporter1); - dispatcher.foo(123, completeCallback); + dispatcher.foo(123); expect(queueRunnerFactory).toHaveBeenCalledWith( jasmine.objectContaining({ queueableFns: [{ fn: jasmine.any(Function) }], @@ -161,7 +157,7 @@ describe('ReportDispatcher', function() { dispatcher.clearReporters(); dispatcher.addReporter(reporter2); - dispatcher.bar(456, completeCallback); + dispatcher.bar(456); expect(queueRunnerFactory).toHaveBeenCalledWith( jasmine.objectContaining({ diff --git a/src/core/Env.js b/src/core/Env.js index a9905328..b6fabb6d 100644 --- a/src/core/Env.js +++ b/src/core/Env.js @@ -701,12 +701,12 @@ getJasmineRequireObj().Env = function(j$) { function specStarted(spec, suite, next) { runner.currentSpec = spec; runableResources.initForRunable(spec.id, suite.id); - reporter.specStarted(spec.result, next); + reporter.specStarted(spec.result).then(next); } function reportSpecDone(spec, result, next) { spec.reportedDone = true; - reporter.specDone(result, next); + reporter.specDone(result).then(next); } this.it = function(description, fn, timeout) { diff --git a/src/core/ReportDispatcher.js b/src/core/ReportDispatcher.js index 55a7097c..55759d03 100644 --- a/src/core/ReportDispatcher.js +++ b/src/core/ReportDispatcher.js @@ -5,7 +5,7 @@ getJasmineRequireObj().ReportDispatcher = function(j$) { for (const method of dispatchedMethods) { this[method] = (function(m) { return function() { - dispatch(m, arguments); + return dispatch(m, arguments); }; })(method); } @@ -31,25 +31,25 @@ getJasmineRequireObj().ReportDispatcher = function(j$) { if (reporters.length === 0 && fallbackReporter !== null) { reporters.push(fallbackReporter); } - const onComplete = args[args.length - 1]; - args = Array.from(args).splice(0, args.length - 1); const fns = []; for (const reporter of reporters) { addFn(fns, reporter, method, args); } - queueRunnerFactory({ - queueableFns: fns, - onComplete: onComplete, - isReporter: true, - onMultipleDone: function() { - onLateError( - new Error( - "An asynchronous reporter callback called its 'done' callback " + - 'more than once.' - ) - ); - } + return new Promise(function(resolve) { + queueRunnerFactory({ + queueableFns: fns, + onComplete: resolve, + isReporter: true, + onMultipleDone: function() { + onLateError( + new Error( + "An asynchronous reporter callback called its 'done' callback " + + 'more than once.' + ) + ); + } + }); }); } diff --git a/src/core/Runner.js b/src/core/Runner.js index 10df5195..cc1ce3a9 100644 --- a/src/core/Runner.js +++ b/src/core/Runner.js @@ -37,7 +37,6 @@ getJasmineRequireObj().Runner = function(j$) { this.executedBefore_ = true; this.hasFailures = false; - const totalSpecsDefined = this.totalSpecsDefined_(); const focusedRunables = this.focusedRunables_(); const config = this.getConfig_(); @@ -76,7 +75,7 @@ getJasmineRequireObj().Runner = function(j$) { nodeStart: (suite, next) => { this.currentlyExecutingSuites_.push(suite); this.runableResources_.initForRunable(suite.id, suite.parentSuite.id); - this.reporter_.suiteStarted(suite.result, next); + this.reporter_.suiteStarted(suite.result).then(next); suite.startTimer(); }, nodeComplete: (suite, result, next) => { @@ -114,106 +113,95 @@ getJasmineRequireObj().Runner = function(j$) { ); } + return this.execute2_(runablesToRun, order, processor); + } + + async execute2_(runablesToRun, order, processor) { + const totalSpecsDefined = this.totalSpecsDefined_(); + this.runableResources_.initForRunable(this.topSuite_.id); const jasmineTimer = new j$.Timer(); jasmineTimer.start(); + await this.reporter_.jasmineStarted({ + totalSpecsDefined, + order: order + }); + + this.currentlyExecutingSuites_.push(this.topSuite_); + return new Promise(resolve => { - /** - * Information passed to the {@link Reporter#jasmineStarted} event. - * @typedef JasmineStartedInfo - * @property {Int} totalSpecsDefined - The total number of specs defined in this suite. - * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. - * @since 2.0.0 - */ - this.reporter_.jasmineStarted( - { - totalSpecsDefined, - order: order - }, - () => { - this.currentlyExecutingSuites_.push(this.topSuite_); + processor.execute(() => { + (async () => { + if (this.topSuite_.hadBeforeAllFailure) { + await this.reportChildrenOfBeforeAllFailure_(this.topSuite_); + } - processor.execute(() => { - (async () => { - if (this.topSuite_.hadBeforeAllFailure) { - await this.reportChildrenOfBeforeAllFailure_(this.topSuite_); - } + this.runableResources_.clearForRunable(this.topSuite_.id); + this.currentlyExecutingSuites_.pop(); + let overallStatus, incompleteReason; - this.runableResources_.clearForRunable(this.topSuite_.id); - this.currentlyExecutingSuites_.pop(); - let overallStatus, incompleteReason; + if ( + this.hasFailures || + this.topSuite_.result.failedExpectations.length > 0 + ) { + overallStatus = 'failed'; + } else if (this.focusedRunables_().length > 0) { + overallStatus = 'incomplete'; + incompleteReason = 'fit() or fdescribe() was found'; + } else if (totalSpecsDefined === 0) { + overallStatus = 'incomplete'; + incompleteReason = 'No specs found'; + } else { + overallStatus = 'passed'; + } - if ( - this.hasFailures || - this.topSuite_.result.failedExpectations.length > 0 - ) { - overallStatus = 'failed'; - } else if (focusedRunables.length > 0) { - overallStatus = 'incomplete'; - incompleteReason = 'fit() or fdescribe() was found'; - } else if (totalSpecsDefined === 0) { - overallStatus = 'incomplete'; - incompleteReason = 'No specs found'; - } else { - overallStatus = 'passed'; - } - - /** - * Information passed to the {@link Reporter#jasmineDone} event. - * @typedef JasmineDoneInfo - * @property {OverallStatus} overallStatus - The overall result of the suite: 'passed', 'failed', or 'incomplete'. - * @property {Int} totalTime - The total time (in ms) that it took to execute the suite - * @property {IncompleteReason} incompleteReason - Explanation of why the suite was incomplete. - * @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. - * @since 2.4.0 - */ - const jasmineDoneInfo = { - overallStatus: overallStatus, - totalTime: jasmineTimer.elapsed(), - incompleteReason: incompleteReason, - order: order, - failedExpectations: this.topSuite_.result.failedExpectations, - deprecationWarnings: this.topSuite_.result.deprecationWarnings - }; - this.topSuite_.reportedDone = true; - this.reporter_.jasmineDone(jasmineDoneInfo, function() { - resolve(jasmineDoneInfo); - }); - })(); - }); - } - ); + /** + * Information passed to the {@link Reporter#jasmineDone} event. + * @typedef JasmineDoneInfo + * @property {OverallStatus} overallStatus - The overall result of the suite: 'passed', 'failed', or 'incomplete'. + * @property {Int} totalTime - The total time (in ms) that it took to execute the suite + * @property {IncompleteReason} incompleteReason - Explanation of why the suite was incomplete. + * @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. + * @since 2.4.0 + */ + const jasmineDoneInfo = { + overallStatus: overallStatus, + totalTime: jasmineTimer.elapsed(), + incompleteReason: incompleteReason, + order: order, + failedExpectations: this.topSuite_.result.failedExpectations, + deprecationWarnings: this.topSuite_.result.deprecationWarnings + }; + this.topSuite_.reportedDone = true; + await this.reporter_.jasmineDone(jasmineDoneInfo); + resolve(jasmineDoneInfo); + })(); + }); }); } reportSuiteDone_(suite, result, next) { suite.reportedDone = true; - this.reporter_.suiteDone(result, next); + this.reporter_.suiteDone(result).then(next); } async reportChildrenOfBeforeAllFailure_(suite) { for (const child of suite.children) { if (child instanceof j$.Suite) { - await new Promise(resolve => { - this.reporter_.suiteStarted(child.result, resolve); - }); + await this.reporter_.suiteStarted(child.result); await this.reportChildrenOfBeforeAllFailure_(child); // Marking the suite passed is consistent with how suites that // contain failed specs but no suite-level failures are reported. child.result.status = 'passed'; - await new Promise(resolve => { - this.reporter_.suiteDone(child.result, resolve); - }); + await this.reporter_.suiteDone(child.result); } else { /* a spec */ - await new Promise(resolve => { - this.reporter_.specStarted(child.result, resolve); - }); + await this.reporter_.specStarted(child.result); child.addExpectationResult( false,