diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 8be445a0..27035c5a 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -1641,6 +1641,11 @@ getJasmineRequireObj().Env = function(j$) { reportSpecDone }); + this.parallelReset = function() { + // TODO: ensure that autoCleanClosures was false + suiteBuilder.parallelReset(); + }; + /** * Executes the specs. * @@ -8365,6 +8370,7 @@ getJasmineRequireObj().Runner = function(j$) { class Runner { constructor(options) { this.topSuite_ = options.topSuite; + // TODO use names that read like getters this.totalSpecsDefined_ = options.totalSpecsDefined; this.focusedRunables_ = options.focusedRunables; this.runableResources_ = options.runableResources; @@ -9623,6 +9629,10 @@ getJasmineRequireObj().Suite = function(j$) { this.reportedDone = false; }; + Suite.prototype.removeChildren = function() { + this.children = []; + }; + Suite.prototype.addChild = function(child) { this.children.push(child); }; @@ -9838,6 +9848,12 @@ getJasmineRequireObj().SuiteBuilder = function(j$) { this.focusedRunables = []; } + parallelReset() { + this.topSuite.removeChildren(); + this.totalSpecsDefined = 0; + this.focusedRunables = []; + } + describe(description, definitionFn) { ensureIsFunction(definitionFn, 'describe'); const suite = this.suiteFactory_(description); @@ -10424,5 +10440,5 @@ getJasmineRequireObj().UserContext = function(j$) { }; getJasmineRequireObj().version = function() { - return '4.2.0'; + return '5.0.0-dev'; }; diff --git a/package.json b/package.json index fdfb6c5b..4a0653c4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jasmine-core", "license": "MIT", - "version": "4.2.0", + "version": "5.0.0-dev", "repository": { "type": "git", "url": "https://github.com/jasmine/jasmine.git" diff --git a/spec/core/SuiteBuilderSpec.js b/spec/core/SuiteBuilderSpec.js index a24fca1e..d482e81e 100644 --- a/spec/core/SuiteBuilderSpec.js +++ b/spec/core/SuiteBuilderSpec.js @@ -175,4 +175,69 @@ describe('SuiteBuilder', function() { } }; } + + describe('#parallelReset', function() { + it('removes children of the top suite', function() { + const env = { configuration: () => ({}) }; + const suiteBuilder = new jasmineUnderTest.SuiteBuilder({ env }); + suiteBuilder.describe('a suite', function() { + suiteBuilder.it('a nested spec'); + }); + suiteBuilder.it('a spec'); + + suiteBuilder.parallelReset(); + + expect(suiteBuilder.topSuite.children).toEqual([]); + }); + + it('preserves top suite befores and afters', function() { + const env = { configuration: () => ({}) }; + const suiteBuilder = new jasmineUnderTest.SuiteBuilder({ env }); + + function beforeAll() {} + function beforeEach() {} + function afterEach() {} + function afterAll() {} + + suiteBuilder.beforeAll(beforeAll); + suiteBuilder.beforeEach(beforeEach); + suiteBuilder.afterEach(afterEach); + suiteBuilder.afterAll(afterAll); + + suiteBuilder.parallelReset(); + + expect(suiteBuilder.topSuite.beforeAllFns).toEqual([ + jasmine.objectContaining({ fn: beforeAll }) + ]); + expect(suiteBuilder.topSuite.beforeFns).toEqual([ + jasmine.objectContaining({ fn: beforeEach }) + ]); + expect(suiteBuilder.topSuite.afterFns).toEqual([ + jasmine.objectContaining({ fn: afterEach }) + ]); + expect(suiteBuilder.topSuite.afterAllFns).toEqual([ + jasmine.objectContaining({ fn: afterAll }) + ]); + }); + + it('resets totalSpecsDefined', function() { + const env = { configuration: () => ({}) }; + const suiteBuilder = new jasmineUnderTest.SuiteBuilder({ env }); + suiteBuilder.it('a spec'); + + suiteBuilder.parallelReset(); + + expect(suiteBuilder.totalSpecsDefined).toEqual(0); + }); + + it('resets focusedRunables', function() { + const env = { configuration: () => ({}) }; + const suiteBuilder = new jasmineUnderTest.SuiteBuilder({ env }); + suiteBuilder.fit('a spec', function() {}); + + suiteBuilder.parallelReset(); + + expect(suiteBuilder.focusedRunables).toEqual([]); + }); + }); }); diff --git a/spec/core/integration/ParallelSpec.js b/spec/core/integration/ParallelSpec.js new file mode 100644 index 00000000..3992184b --- /dev/null +++ b/spec/core/integration/ParallelSpec.js @@ -0,0 +1,104 @@ +describe('Support for parallel execution', function() { + let env; + + beforeEach(function() { + env = new jasmineUnderTest.Env(); + }); + + afterEach(function() { + env.cleanup_(); + }); + + it('removes specs and suites from previous batches', async function() { + env.describe('a suite', function() { + env.it('a spec', function() {}); + }); + env.it('a spec', function() {}); + + await env.execute(); + env.parallelReset(); + + env.describe('a suite in a new batch', function() { + env.it('a spec in a new batch', function() {}); + }); + const reporter = jasmine.createSpyObj('reporter', [ + 'suiteDone', + 'specDone' + ]); + env.addReporter(reporter); + + await env.execute(); + + expect(reporter.suiteDone).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + fullName: 'a suite in a new batch' + }) + ); + expect(reporter.specDone).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + fullName: 'a suite in a new batch a spec in a new batch' + }) + ); + }); + + it('preserves top-level before and after fns from previous batches', async function() { + const beforeAll = jasmine.createSpy('beforeAll'); + const beforeEach = jasmine.createSpy('beforeEach'); + const afterEach = jasmine.createSpy('afterEach'); + const afterAll = jasmine.createSpy('afterAll'); + env.beforeAll(beforeAll); + env.beforeEach(beforeEach); + env.afterEach(afterEach); + env.afterAll(afterAll); + + env.parallelReset(); + env.it('a spec', function() {}); + await env.execute(); + + expect(beforeAll).toHaveBeenCalled(); + expect(beforeEach).toHaveBeenCalled(); + expect(afterEach).toHaveBeenCalled(); + expect(afterAll).toHaveBeenCalled(); + }); + + it('does not remember focused runables from previous batches', async function() { + env.fit('a focused spec', function() {}); + env.parallelReset(); + env.it('a spec', function() {}); + const reporter = jasmine.createSpyObj('reporter', [ + 'specDone', + 'jasmineDone' + ]); + env.addReporter(reporter); + await env.execute(); + + expect(reporter.specDone).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + fullName: 'a spec', + status: 'passed' + }) + ); + expect(reporter.jasmineDone).toHaveBeenCalledWith( + jasmine.objectContaining({ overallStatus: 'passed' }) + ); + }); + + it('does not remember failures from previous batches', async function() { + env.it('a failing spec', function() { + env.expect(true).toBe(false); + }); + await env.execute(); + env.parallelReset(); + env.it('a spec', function() {}); + const reporter = jasmine.createSpyObj('reporter', [ + 'specDone', + 'jasmineDone' + ]); + env.addReporter(reporter); + await env.execute(); + + expect(reporter.jasmineDone).toHaveBeenCalledWith( + jasmine.objectContaining({ overallStatus: 'passed' }) + ); + }); +}); diff --git a/src/core/Env.js b/src/core/Env.js index b6fabb6d..ede3baa6 100644 --- a/src/core/Env.js +++ b/src/core/Env.js @@ -499,6 +499,11 @@ getJasmineRequireObj().Env = function(j$) { reportSpecDone }); + this.parallelReset = function() { + // TODO: ensure that autoCleanClosures was false + suiteBuilder.parallelReset(); + }; + /** * Executes the specs. * diff --git a/src/core/Runner.js b/src/core/Runner.js index c9e1c70f..7b9e0227 100644 --- a/src/core/Runner.js +++ b/src/core/Runner.js @@ -2,6 +2,7 @@ getJasmineRequireObj().Runner = function(j$) { class Runner { constructor(options) { this.topSuite_ = options.topSuite; + // TODO use names that read like getters this.totalSpecsDefined_ = options.totalSpecsDefined; this.focusedRunables_ = options.focusedRunables; this.runableResources_ = options.runableResources; diff --git a/src/core/Suite.js b/src/core/Suite.js index 2a0c928c..4cae0b0c 100644 --- a/src/core/Suite.js +++ b/src/core/Suite.js @@ -132,6 +132,10 @@ getJasmineRequireObj().Suite = function(j$) { this.reportedDone = false; }; + Suite.prototype.removeChildren = function() { + this.children = []; + }; + Suite.prototype.addChild = function(child) { this.children.push(child); }; diff --git a/src/core/SuiteBuilder.js b/src/core/SuiteBuilder.js index 0fe85925..1115e7a8 100644 --- a/src/core/SuiteBuilder.js +++ b/src/core/SuiteBuilder.js @@ -22,6 +22,12 @@ getJasmineRequireObj().SuiteBuilder = function(j$) { this.focusedRunables = []; } + parallelReset() { + this.topSuite.removeChildren(); + this.totalSpecsDefined = 0; + this.focusedRunables = []; + } + describe(description, definitionFn) { ensureIsFunction(definitionFn, 'describe'); const suite = this.suiteFactory_(description);