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;