Breaking change: support for -npm reporter handling in parallel mode

* The `boot` function exported by the core module returns the same object
  every time it's called.
* Removed node_boot.js. Use the exported `boot` function instead
* JasmineStartedInfo does not have totalSpecsDefined or order in parallel mode
* JasmineDoneInfo does not have order in parallel mode
* Added incompleteCode and numWorkers to JasmineDoneInfo
This commit is contained in:
Steve Gravrock
2022-08-06 10:37:40 -07:00
parent 3a43871901
commit 588283cfe5
11 changed files with 109 additions and 94 deletions

View File

@@ -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: {

View File

@@ -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')

View File

@@ -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();

View File

@@ -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;
};

View File

@@ -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();
});
});
});

View File

@@ -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() {

View File

@@ -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;
};

View File

@@ -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() {}

View File

@@ -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 || [];

View File

@@ -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

View File

@@ -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();