From 6ada55ff774acf636af3dec933f6515f58d378ca Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Sun, 18 Sep 2022 12:10:34 -0700 Subject: [PATCH] Parallel: Fixed reporting of exceptions thrown by a describe --- lib/jasmine-core/jasmine.js | 6 +++ spec/core/EnvSpec.js | 8 ++++ spec/core/SuiteBuilderSpec.js | 20 +++++++++ spec/core/integration/ParallelSpec.js | 58 +++++++++++++++++++++++++++ src/core/Env.js | 1 + src/core/Runner.js | 4 ++ src/core/SuiteBuilder.js | 1 + 7 files changed, 98 insertions(+) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 47c39ecf..f8316bc8 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -1637,6 +1637,7 @@ getJasmineRequireObj().Env = function(j$) { this.parallelReset = function() { // TODO: ensure that autoCleanClosures was false suiteBuilder.parallelReset(); + runner.parallelReset(); }; /** @@ -8422,6 +8423,10 @@ getJasmineRequireObj().Runner = function(j$) { ]; } + parallelReset() { + this.executedBefore_ = false; + } + async execute(runablesToRun) { if (this.executedBefore_) { this.topSuite_.reset(); @@ -9878,6 +9883,7 @@ getJasmineRequireObj().SuiteBuilder = function(j$) { parallelReset() { this.topSuite.removeChildren(); + this.topSuite.reset(); this.totalSpecsDefined = 0; this.focusedRunables = []; } diff --git a/spec/core/EnvSpec.js b/spec/core/EnvSpec.js index eccc972f..85ab4d6d 100644 --- a/spec/core/EnvSpec.js +++ b/spec/core/EnvSpec.js @@ -592,6 +592,14 @@ describe('Env', function() { expect(id).toEqual(env.topSuite().id); }); }); + + it('should not reset the topSuite if parallelReset was called since the last run', async function() { + await env.execute(); + env.parallelReset(); + spyOn(jasmineUnderTest.Suite.prototype, 'reset'); + await env.execute(); + expect(jasmineUnderTest.Suite.prototype.reset).not.toHaveBeenCalled(); + }); }); describe('#spyOnGlobalErrorsAsync', function() { diff --git a/spec/core/SuiteBuilderSpec.js b/spec/core/SuiteBuilderSpec.js index d482e81e..e664a1da 100644 --- a/spec/core/SuiteBuilderSpec.js +++ b/spec/core/SuiteBuilderSpec.js @@ -177,6 +177,26 @@ describe('SuiteBuilder', function() { } describe('#parallelReset', function() { + it('resets the top suite result', function() { + jasmineUnderTest.Suite.prototype.handleException.and.callThrough(); + + const env = { configuration: () => ({}) }; + const suiteBuilder = new jasmineUnderTest.SuiteBuilder({ env }); + + suiteBuilder.topSuite.handleException(new Error('nope')); + suiteBuilder.parallelReset(); + + expect(suiteBuilder.topSuite.result).toEqual({ + id: suiteBuilder.topSuite.id, + description: 'Jasmine__TopLevel__Suite', + fullName: '', + failedExpectations: [], + deprecationWarnings: [], + duration: null, + properties: null + }); + }); + it('removes children of the top suite', function() { const env = { configuration: () => ({}) }; const suiteBuilder = new jasmineUnderTest.SuiteBuilder({ env }); diff --git a/spec/core/integration/ParallelSpec.js b/spec/core/integration/ParallelSpec.js index 3992184b..4381c225 100644 --- a/spec/core/integration/ParallelSpec.js +++ b/spec/core/integration/ParallelSpec.js @@ -101,4 +101,62 @@ describe('Support for parallel execution', function() { jasmine.objectContaining({ overallStatus: 'passed' }) ); }); + + it('reports errors thrown from describe', async function() { + const reporter = jasmine.createSpyObj('reporter', ['suiteDone']); + env.addReporter(reporter); + + env.describe('borken', function() { + throw new Error('nope'); + }); + await env.execute(); + + expect(reporter.suiteDone).toHaveBeenCalledWith( + jasmine.objectContaining({ + description: 'borken', + status: 'failed', + failedExpectations: [ + jasmine.objectContaining({ + message: jasmine.stringContaining('Error: nope') + }) + ] + }) + ); + + // Errors in subsequent suites should also be reported + reporter.suiteDone.calls.reset(); + env.parallelReset(); + env.describe('zarro boogs', function() { + throw new Error('nor that either'); + }); + await env.execute(); + + expect(reporter.suiteDone).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + description: 'zarro boogs', + status: 'failed', + failedExpectations: [ + jasmine.objectContaining({ + message: jasmine.stringContaining('Error: nor that either') + }) + ] + }) + ); + + // Failure state should not persist across resets + reporter.suiteDone.calls.reset(); + env.parallelReset(); + env.describe('actually works', function() { + env.it('a spec', function() {}); + }); + await env.execute(); + + expect(reporter.suiteDone).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + description: 'actually works', + status: 'passed', + failedExpectations: [] + }) + ); + }); }); diff --git a/src/core/Env.js b/src/core/Env.js index 264853d3..3886aa29 100644 --- a/src/core/Env.js +++ b/src/core/Env.js @@ -495,6 +495,7 @@ getJasmineRequireObj().Env = function(j$) { this.parallelReset = function() { // TODO: ensure that autoCleanClosures was false suiteBuilder.parallelReset(); + runner.parallelReset(); }; /** diff --git a/src/core/Runner.js b/src/core/Runner.js index 6d784d92..9929fca5 100644 --- a/src/core/Runner.js +++ b/src/core/Runner.js @@ -27,6 +27,10 @@ getJasmineRequireObj().Runner = function(j$) { ]; } + parallelReset() { + this.executedBefore_ = false; + } + async execute(runablesToRun) { if (this.executedBefore_) { this.topSuite_.reset(); diff --git a/src/core/SuiteBuilder.js b/src/core/SuiteBuilder.js index 50ed5c7d..d17e2451 100644 --- a/src/core/SuiteBuilder.js +++ b/src/core/SuiteBuilder.js @@ -24,6 +24,7 @@ getJasmineRequireObj().SuiteBuilder = function(j$) { parallelReset() { this.topSuite.removeChildren(); + this.topSuite.reset(); this.totalSpecsDefined = 0; this.focusedRunables = []; }