From d4025999b7bc9e60456e3f5b21865c3fdaeec6f8 Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Sat, 17 Sep 2022 13:23:36 -0700 Subject: [PATCH] Report exceptions thrown by a describe before any it calls Previously, these were masked by the "describe with no children" error. Now they're reported as suite level errors on an empty suite. --- lib/jasmine-core/jasmine.js | 13 ++++++----- spec/core/integration/EnvSpec.js | 38 ++++++++++++++++++++++++++++++++ src/core/SuiteBuilder.js | 13 ++++++----- 3 files changed, 54 insertions(+), 10 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 6b60117c..c2741948 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -9872,11 +9872,6 @@ getJasmineRequireObj().SuiteBuilder = function(j$) { suite.exclude(); } this.addSpecsToSuite_(suite, definitionFn); - if (suite.parentSuite && !suite.children.length) { - throw new Error( - `describe with no children (describe() or it()): ${suite.getFullName()}` - ); - } return suite; } @@ -10023,11 +10018,19 @@ getJasmineRequireObj().SuiteBuilder = function(j$) { const parentSuite = this.currentDeclarationSuite_; parentSuite.addChild(suite); this.currentDeclarationSuite_ = suite; + let threw = false; try { definitionFn(); } catch (e) { suite.handleException(e); + threw = true; + } + + if (suite.parentSuite && !suite.children.length && !threw) { + throw new Error( + `describe with no children (describe() or it()): ${suite.getFullName()}` + ); } this.currentDeclarationSuite_ = parentSuite; diff --git a/spec/core/integration/EnvSpec.js b/spec/core/integration/EnvSpec.js index f2433403..8f2990ad 100644 --- a/spec/core/integration/EnvSpec.js +++ b/spec/core/integration/EnvSpec.js @@ -3966,6 +3966,44 @@ describe('Env integration', function() { }); }); + it('reports a suite level error when a describe fn throws', async function() { + const reporter = jasmine.createSpyObj('reporter', ['suiteDone']); + env.addReporter(reporter); + + env.describe('throws before defining specs', function() { + throw new Error('nope'); + }); + + env.describe('throws after defining specs', function() { + env.it('is a spec'); + throw new Error('nope'); + }); + + await env.execute(); + + expect(reporter.suiteDone).toHaveBeenCalledWith( + jasmine.objectContaining({ + fullName: 'throws after defining specs', + failedExpectations: [ + jasmine.objectContaining({ + message: jasmine.stringContaining('Error: nope') + }) + ] + }) + ); + + expect(reporter.suiteDone).toHaveBeenCalledWith( + jasmine.objectContaining({ + fullName: 'throws after defining specs', + failedExpectations: [ + jasmine.objectContaining({ + message: jasmine.stringContaining('Error: nope') + }) + ] + }) + ); + }); + function browserEventMethods() { return { addEventListener() {}, diff --git a/src/core/SuiteBuilder.js b/src/core/SuiteBuilder.js index 0fe85925..c29b2f40 100644 --- a/src/core/SuiteBuilder.js +++ b/src/core/SuiteBuilder.js @@ -32,11 +32,6 @@ getJasmineRequireObj().SuiteBuilder = function(j$) { suite.exclude(); } this.addSpecsToSuite_(suite, definitionFn); - if (suite.parentSuite && !suite.children.length) { - throw new Error( - `describe with no children (describe() or it()): ${suite.getFullName()}` - ); - } return suite; } @@ -183,11 +178,19 @@ getJasmineRequireObj().SuiteBuilder = function(j$) { const parentSuite = this.currentDeclarationSuite_; parentSuite.addChild(suite); this.currentDeclarationSuite_ = suite; + let threw = false; try { definitionFn(); } catch (e) { suite.handleException(e); + threw = true; + } + + if (suite.parentSuite && !suite.children.length && !threw) { + throw new Error( + `describe with no children (describe() or it()): ${suite.getFullName()}` + ); } this.currentDeclarationSuite_ = parentSuite;