diff --git a/grunt/config/concat.js b/grunt/config/concat.js index 23997b48..a9c6eedf 100644 --- a/grunt/config/concat.js +++ b/grunt/config/concat.js @@ -45,10 +45,6 @@ module.exports = { src: ['src/boot/boot1.js'], dest: 'lib/jasmine-core/boot1.js' }, - nodeBoot: { - src: ['src/boot/node_boot.js'], - dest: 'lib/jasmine-core/node_boot.js' - }, options: { banner: license(), process: { diff --git a/lib/jasmine-core.js b/lib/jasmine-core.js index 718adcd5..873d446d 100644 --- a/lib/jasmine-core.js +++ b/lib/jasmine-core.js @@ -6,36 +6,48 @@ const jasmineRequire = require('./jasmine-core/jasmine.js'); module.exports = jasmineRequire; +const bootOnce = (function() { + let jasmine, jasmineInterface; + + return function bootWithoutGlobals() { + if (!jasmineInterface) { + jasmine = jasmineRequire.core(jasmineRequire); + const env = jasmine.getEnv({ suppressLoadErrors: true }); + jasmineInterface = jasmineRequire.interface(jasmine, env); + } + + return {jasmine, jasmineInterface}; + }; +}()); + /** * Boots a copy of Jasmine and returns an object as described in {@link jasmine}. + * If boot is called multiple times, the same object is returned every time. * @type {function} * @return {jasmine} */ -module.exports.boot = require('./jasmine-core/node_boot.js'); +module.exports.boot = function() { + const {jasmine, jasmineInterface} = bootOnce(); + + for (const k in jasmineInterface) { + global[k] = jasmineInterface[k]; + } + + return jasmine; +}; /** * Boots a copy of Jasmine and returns an object containing the properties * that would normally be added to the global object. If noGlobals is called * multiple times, the same object is returned every time. * - * Do not call boot() if you also call noGlobals(). - * * @example * const {describe, beforeEach, it, expect, jasmine} = require('jasmine-core').noGlobals(); */ -module.exports.noGlobals = (function() { - let jasmineInterface; - - return function bootWithoutGlobals() { - if (!jasmineInterface) { - const jasmine = jasmineRequire.core(jasmineRequire); - const env = jasmine.getEnv({ suppressLoadErrors: true }); - jasmineInterface = jasmineRequire.interface(jasmine, env); - } - - return jasmineInterface; - }; -}()); +module.exports.noGlobals = function() { + const {jasmineInterface} = bootOnce(); + return jasmineInterface; +}; const path = require('path'), fs = require('fs'); @@ -43,10 +55,9 @@ const path = require('path'), const rootPath = path.join(__dirname, 'jasmine-core'), bootFiles = ['boot0.js', 'boot1.js'], legacyBootFiles = ['boot.js'], - nodeBootFiles = ['node_boot.js'], cssFiles = [], jsFiles = [], - jsFilesToSkip = ['jasmine.js'].concat(bootFiles, legacyBootFiles, nodeBootFiles); + jsFilesToSkip = ['jasmine.js'].concat(bootFiles, legacyBootFiles); fs.readdirSync(rootPath).forEach(function(file) { if(fs.statSync(path.join(rootPath, file)).isFile()) { @@ -56,8 +67,8 @@ fs.readdirSync(rootPath).forEach(function(file) { break; case '.js': if (jsFilesToSkip.indexOf(file) < 0) { - jsFiles.push(file); - } + jsFiles.push(file); + } break; } } @@ -67,7 +78,6 @@ module.exports.files = { path: rootPath, bootDir: rootPath, bootFiles: bootFiles, - nodeBootFiles: nodeBootFiles, cssFiles: cssFiles, jsFiles: ['jasmine.js'].concat(jsFiles), imagesDir: path.join(__dirname, '../images') diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 27035c5a..592743df 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -7409,6 +7409,15 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) { }; getJasmineRequireObj().QueueRunner = function(j$) { + /* + QueueRunner isn't part of the public interface, but it is used by + jasmine-npm. -core and -npm version in lockstep at the major and minor + levels but version independently at the patch level. Any changes that + would break -npm should be done in a major or minor release, never a + patch release, and accompanied by a change to -npm that's released in + the same version. + */ + let nextid = 1; function StopExecutionError() {} @@ -7699,6 +7708,15 @@ getJasmineRequireObj().QueueRunner = function(j$) { }; getJasmineRequireObj().ReportDispatcher = function(j$) { + /* + ReportDispatcher isn't part of the public interface, but it is used by + jasmine-npm. -core and -npm version in lockstep at the major and minor + levels but version independently at the patch level. Any changes that + would break -npm should be done in a major or minor release, never a + patch release, and accompanied by a change to -npm that's released in + the same version. + */ + function ReportDispatcher(methods, queueRunnerFactory, onLateError) { const dispatchedMethods = methods || []; @@ -8495,8 +8513,8 @@ getJasmineRequireObj().Runner = function(j$) { /** * 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. + * @property {Int} totalSpecsDefined - The total number of specs defined in this suite. Note that this property is not present when Jasmine is run in parallel mode. + * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. Note that this property is not present when Jasmine is run in parallel mode. * @since 2.0.0 */ await this.reporter_.jasmineStarted({ @@ -8515,7 +8533,7 @@ getJasmineRequireObj().Runner = function(j$) { this.runableResources_.clearForRunable(this.topSuite_.id); this.currentlyExecutingSuites_.pop(); - let overallStatus, incompleteReason; + let overallStatus, incompleteReason, incompleteCode; if ( this.hasFailures || @@ -8525,9 +8543,11 @@ getJasmineRequireObj().Runner = function(j$) { } else if (this.focusedRunables_().length > 0) { overallStatus = 'incomplete'; incompleteReason = 'fit() or fdescribe() was found'; + incompleteCode = 'focused'; } else if (totalSpecsDefined === 0) { overallStatus = 'incomplete'; incompleteReason = 'No specs found'; + incompleteCode = 'noSpecsFound'; } else { overallStatus = 'passed'; } @@ -8537,8 +8557,10 @@ getJasmineRequireObj().Runner = function(j$) { * @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 {String} incompleteReason - Human-readable explanation of why the suite was incomplete. + * @property {String} incompleteCode - Machine-readable explanation of why the suite was incomplete: 'focused', 'noSpecsFound', or undefined. + * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. Note that this property is not present when Jasmine is run in parallel mode. + * @property {Int} numWorkers - Number of parallel workers. Note that this property is only present when Jasmine is run in parallel mode. * @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 @@ -8547,6 +8569,7 @@ getJasmineRequireObj().Runner = function(j$) { overallStatus: overallStatus, totalTime: jasmineTimer.elapsed(), incompleteReason: incompleteReason, + incompleteCode: incompleteCode, order: order, failedExpectations: this.topSuite_.result.failedExpectations, deprecationWarnings: this.topSuite_.result.deprecationWarnings @@ -10134,6 +10157,15 @@ getJasmineRequireObj().SuiteBuilder = function(j$) { }; getJasmineRequireObj().Timer = function() { + /* + Timer isn't part of the public interface, but it is used by + jasmine-npm. -core and -npm version in lockstep at the major and minor + levels but version independently at the patch level. Any changes that + would break -npm should be done in a major or minor release, never a + patch release, and accompanied by a change to -npm that's released in + the same version. + */ + const defaultNow = (function(Date) { return function() { return new Date().getTime(); diff --git a/lib/jasmine-core/node_boot.js b/lib/jasmine-core/node_boot.js deleted file mode 100644 index c10ca360..00000000 --- a/lib/jasmine-core/node_boot.js +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (c) 2008-2022 Pivotal Labs - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -module.exports = function(jasmineRequire) { - const jasmine = jasmineRequire.core(jasmineRequire); - - const env = jasmine.getEnv({ suppressLoadErrors: true }); - - const jasmineInterface = jasmineRequire.interface(jasmine, env); - - extend(global, jasmineInterface); - - function extend(destination, source) { - for (const property in source) destination[property] = source[property]; - return destination; - } - - return jasmine; -}; diff --git a/spec/core/integration/EnvSpec.js b/spec/core/integration/EnvSpec.js index 01533038..ef5005f4 100644 --- a/spec/core/integration/EnvSpec.js +++ b/spec/core/integration/EnvSpec.js @@ -2908,6 +2908,7 @@ describe('Env integration', function() { const e = reporter.jasmineDone.calls.argsFor(0)[0]; expect(e.overallStatus).toEqual('incomplete'); expect(e.incompleteReason).toEqual('No specs found'); + expect(e.incompleteCode).toEqual('noSpecsFound'); }); }); @@ -2926,6 +2927,7 @@ describe('Env integration', function() { const e = reporter.jasmineDone.calls.argsFor(0)[0]; expect(e.overallStatus).toEqual('incomplete'); expect(e.incompleteReason).toEqual('fit() or fdescribe() was found'); + expect(e.incompleteCode).toEqual('focused'); }); }); @@ -2946,6 +2948,7 @@ describe('Env integration', function() { const e = reporter.jasmineDone.calls.argsFor(0)[0]; expect(e.overallStatus).toEqual('incomplete'); expect(e.incompleteReason).toEqual('fit() or fdescribe() was found'); + expect(e.incompleteCode).toEqual('focused'); }); }); @@ -2966,6 +2969,7 @@ describe('Env integration', function() { const e = reporter.jasmineDone.calls.argsFor(0)[0]; expect(e.overallStatus).toEqual('failed'); expect(e.incompleteReason).toBeUndefined(); + expect(e.incompleteCode).toBeUndefined(); }); }); }); diff --git a/spec/npmPackage/npmPackageSpec.js b/spec/npmPackage/npmPackageSpec.js index a47067a0..ef9dcc9c 100644 --- a/spec/npmPackage/npmPackageSpec.js +++ b/spec/npmPackage/npmPackageSpec.js @@ -78,15 +78,10 @@ describe('npm package', function() { it('has bootFiles', function() { expect(this.packagedCore.files.bootFiles).toEqual(['boot0.js', 'boot1.js']); - expect(this.packagedCore.files.nodeBootFiles).toEqual(['node_boot.js']); for (const fileName of this.packagedCore.files.bootFiles) { expect(fileName).toExistInPath(this.packagedCore.files.bootDir); } - - for (const fileName of this.packagedCore.files.nodeBootFiles) { - expect(fileName).toExistInPath(this.packagedCore.files.bootDir); - } }); it('has an imagesDir', function() { diff --git a/src/boot/node_boot.js b/src/boot/node_boot.js deleted file mode 100644 index 53e86559..00000000 --- a/src/boot/node_boot.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = function(jasmineRequire) { - const jasmine = jasmineRequire.core(jasmineRequire); - - const env = jasmine.getEnv({ suppressLoadErrors: true }); - - const jasmineInterface = jasmineRequire.interface(jasmine, env); - - extend(global, jasmineInterface); - - function extend(destination, source) { - for (const property in source) destination[property] = source[property]; - return destination; - } - - return jasmine; -}; diff --git a/src/core/QueueRunner.js b/src/core/QueueRunner.js index 0d7001c7..04c78917 100644 --- a/src/core/QueueRunner.js +++ b/src/core/QueueRunner.js @@ -1,4 +1,13 @@ getJasmineRequireObj().QueueRunner = function(j$) { + /* + QueueRunner isn't part of the public interface, but it is used by + jasmine-npm. -core and -npm version in lockstep at the major and minor + levels but version independently at the patch level. Any changes that + would break -npm should be done in a major or minor release, never a + patch release, and accompanied by a change to -npm that's released in + the same version. + */ + let nextid = 1; function StopExecutionError() {} diff --git a/src/core/ReportDispatcher.js b/src/core/ReportDispatcher.js index 55759d03..adb09170 100644 --- a/src/core/ReportDispatcher.js +++ b/src/core/ReportDispatcher.js @@ -1,4 +1,13 @@ getJasmineRequireObj().ReportDispatcher = function(j$) { + /* + ReportDispatcher isn't part of the public interface, but it is used by + jasmine-npm. -core and -npm version in lockstep at the major and minor + levels but version independently at the patch level. Any changes that + would break -npm should be done in a major or minor release, never a + patch release, and accompanied by a change to -npm that's released in + the same version. + */ + function ReportDispatcher(methods, queueRunnerFactory, onLateError) { const dispatchedMethods = methods || []; diff --git a/src/core/Runner.js b/src/core/Runner.js index 7b9e0227..55ad10cf 100644 --- a/src/core/Runner.js +++ b/src/core/Runner.js @@ -127,8 +127,8 @@ getJasmineRequireObj().Runner = function(j$) { /** * 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. + * @property {Int} totalSpecsDefined - The total number of specs defined in this suite. Note that this property is not present when Jasmine is run in parallel mode. + * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. Note that this property is not present when Jasmine is run in parallel mode. * @since 2.0.0 */ await this.reporter_.jasmineStarted({ @@ -147,7 +147,7 @@ getJasmineRequireObj().Runner = function(j$) { this.runableResources_.clearForRunable(this.topSuite_.id); this.currentlyExecutingSuites_.pop(); - let overallStatus, incompleteReason; + let overallStatus, incompleteReason, incompleteCode; if ( this.hasFailures || @@ -157,9 +157,11 @@ getJasmineRequireObj().Runner = function(j$) { } else if (this.focusedRunables_().length > 0) { overallStatus = 'incomplete'; incompleteReason = 'fit() or fdescribe() was found'; + incompleteCode = 'focused'; } else if (totalSpecsDefined === 0) { overallStatus = 'incomplete'; incompleteReason = 'No specs found'; + incompleteCode = 'noSpecsFound'; } else { overallStatus = 'passed'; } @@ -169,8 +171,10 @@ getJasmineRequireObj().Runner = function(j$) { * @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 {String} incompleteReason - Human-readable explanation of why the suite was incomplete. + * @property {String} incompleteCode - Machine-readable explanation of why the suite was incomplete: 'focused', 'noSpecsFound', or undefined. + * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. Note that this property is not present when Jasmine is run in parallel mode. + * @property {Int} numWorkers - Number of parallel workers. Note that this property is only present when Jasmine is run in parallel mode. * @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 @@ -179,6 +183,7 @@ getJasmineRequireObj().Runner = function(j$) { overallStatus: overallStatus, totalTime: jasmineTimer.elapsed(), incompleteReason: incompleteReason, + incompleteCode: incompleteCode, order: order, failedExpectations: this.topSuite_.result.failedExpectations, deprecationWarnings: this.topSuite_.result.deprecationWarnings diff --git a/src/core/Timer.js b/src/core/Timer.js index 8a7bf7ea..26266313 100644 --- a/src/core/Timer.js +++ b/src/core/Timer.js @@ -1,4 +1,13 @@ getJasmineRequireObj().Timer = function() { + /* + Timer isn't part of the public interface, but it is used by + jasmine-npm. -core and -npm version in lockstep at the major and minor + levels but version independently at the patch level. Any changes that + would break -npm should be done in a major or minor release, never a + patch release, and accompanied by a change to -npm that's released in + the same version. + */ + const defaultNow = (function(Date) { return function() { return new Date().getTime();