Socket
Socket
Sign inDemoInstall

jasmine

Package Overview
Dependencies
Maintainers
4
Versions
55
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jasmine - npm Package Compare versions

Comparing version 4.6.0 to 5.0.0

bin/worker.js

15

bin/jasmine.js

@@ -7,15 +7,8 @@ #!/usr/bin/env node

const Jasmine = require('../lib/jasmine');
const ParallelRunner = require("../lib/parallel_runner");
let projectBaseDir = path.resolve();
if (os.platform() === 'win32') {
// Future versions of glob will interpret backslashes as escape sequences on
// all platforms, and Jasmine warns about them. Convert to slashes to avoid
// the warning and future behavior change.
projectBaseDir = projectBaseDir.replace(/\\/g, '/');
}
const jasmine = new Jasmine({ projectBaseDir });
const examplesDir = path.join(path.dirname(require.resolve('jasmine-core')), 'jasmine-core', 'example', 'node_example');
const command = new Command(path.resolve(), examplesDir, {
Jasmine,
ParallelRunner,
print: console.log,

@@ -25,2 +18,2 @@ platform: os.platform,

command.run(jasmine, process.argv.slice(2));
command.run(process.argv.slice(2));
const path = require('path');
const fs = require('fs');
const os = require('os');
const unWindows = require('./unWindows');

@@ -28,3 +30,3 @@ exports = module.exports = Command;

function Command(projectBaseDir, examplesDir, deps) {
const {print, platform} = deps;
const {print, platform, Jasmine, ParallelRunner} = deps;
const isWindows = platform() === 'win32';

@@ -37,4 +39,4 @@

this.run = async function(jasmine, commands) {
setEnvironmentVariables(commands);
this.run = async function(args) {
setEnvironmentVariables(args);

@@ -44,5 +46,5 @@ let commandToRun;

const commandObject = subCommands[cmd];
if (commands.indexOf(cmd) >= 0) {
if (args.indexOf(cmd) >= 0) {
commandToRun = commandObject;
} else if(commandObject.alias && commands.indexOf(commandObject.alias) >= 0) {
} else if (commandObject.alias && args.indexOf(commandObject.alias) >= 0) {
commandToRun = commandObject;

@@ -53,12 +55,22 @@ }

if (commandToRun) {
commandToRun.action({jasmine: jasmine, projectBaseDir: command.projectBaseDir, specDir: command.specDir, examplesDir: examplesDir, print: print});
commandToRun.action({
Jasmine,
projectBaseDir,
specDir: command.specDir,
examplesDir: examplesDir,
print
});
} else {
const env = parseOptions(commands, isWindows);
if (env.unknownOptions.length > 0) {
const options = parseOptions(args, isWindows);
if (options.usageErrors.length > 0) {
process.exitCode = 1;
print('Unknown options: ' + env.unknownOptions.join(', '));
for (const e of options.usageErrors) {
print(e);
}
print('');
help({print: print});
} else {
await runJasmine(jasmine, env);
await runJasmine(Jasmine, ParallelRunner, projectBaseDir, options);
}

@@ -78,2 +90,3 @@ }

unknownOptions = [],
usageErrors = [],
color = process.stdout.isTTY || false,

@@ -85,3 +98,4 @@ reporter,

random,
seed;
seed,
numWorkers = 1;

@@ -109,2 +123,13 @@ for (const arg of argv) {

reporter = arg.match("^--reporter=(.*)")[1];
} else if (arg.match("^--parallel=(.*)")) {
const w = arg.match("^--parallel=(.*)")[1];
if (w === 'auto') {
// A reasonable default in most situations
numWorkers = os.cpus().length -1;
} else {
numWorkers = parseFloat(w);
if (isNaN(numWorkers) || numWorkers < 2 || numWorkers !== Math.floor(numWorkers)) {
usageErrors.push('Argument to --parallel= must be an integer greater than 1');
}
}
} else if (arg === '--') {

@@ -119,2 +144,6 @@ break;

if (unknownOptions.length > 0) {
usageErrors.push('Unknown options: ' + unknownOptions.join(', '));
}
return {

@@ -131,11 +160,25 @@ color,

seed,
unknownOptions
numWorkers,
usageErrors
};
}
async function runJasmine(jasmine, options) {
await jasmine.loadConfigFile(options.configPath || process.env.JASMINE_CONFIG_PATH);
async function runJasmine(Jasmine, ParallelRunner, projectBaseDir, options) {
let runner;
if (options.numWorkers > 1) {
runner = new ParallelRunner({
projectBaseDir,
numWorkers: options.numWorkers
});
} else {
runner = new Jasmine({
projectBaseDir
});
}
await runner.loadConfigFile(options.configPath || process.env.JASMINE_CONFIG_PATH);
if (options.failFast !== undefined) {
jasmine.env.configure({
runner.configureEnv({
stopSpecOnExpectationFailure: options.failFast,

@@ -147,25 +190,25 @@ stopOnSpecFailure: options.failFast

if (options.seed !== undefined) {
jasmine.seed(options.seed);
runner.seed(options.seed);
}
if (options.random !== undefined) {
jasmine.randomizeTests(options.random);
runner.randomizeTests(options.random);
}
if (options.helpers !== undefined && options.helpers.length) {
jasmine.addMatchingHelperFiles(options.helpers);
runner.addMatchingHelperFiles(options.helpers);
}
if (options.requires !== undefined && options.requires.length) {
jasmine.addRequires(options.requires);
runner.addRequires(options.requires);
}
if (options.reporter !== undefined) {
await registerReporter(options.reporter, jasmine);
await registerReporter(options.reporter, runner);
}
jasmine.showColors(options.color);
runner.showColors(options.color);
try {
await jasmine.execute(options.files, options.filter);
await runner.execute(options.files, options.filter);
} catch (error) {

@@ -177,7 +220,7 @@ console.error(error);

async function registerReporter(reporterModuleName, jasmine) {
async function registerReporter(reporterModuleName, runner) {
let Reporter;
try {
Reporter = await jasmine.loader.load(resolveReporter(reporterModuleName));
Reporter = await runner.loader.load(resolveReporter(reporterModuleName));
} catch (e) {

@@ -197,4 +240,4 @@ throw new Error('Failed to load reporter module '+ reporterModuleName +

}
jasmine.clearReporters();
jasmine.addReporter(reporter);
runner.clearReporters();
runner.addReporter(reporter);
}

@@ -269,2 +312,4 @@

print('Options:');
print('%s\tRun in parallel with N workers', lPad('--parallel=N', 18));
print('%s\tRun in parallel with an automatically chosen number of workers', lPad('--parallel=auto', 18));
print('%s\tturn off color in spec output', lPad('--no-color', 18));

@@ -287,3 +332,4 @@ print('%s\tforce turn on color in spec output', lPad('--color', 18));

print('jasmine v' + require('../package.json').version);
print('jasmine-core v' + options.jasmine.coreVersion());
const jasmine = new options.Jasmine();
print('jasmine-core v' + jasmine.coreVersion());
}

@@ -320,10 +366,13 @@

function isEnvironmentVariable(command) {
const envRegExp = /(.*)=(.*)/;
return command.match(envRegExp);
function isEnvironmentVariable(arg) {
if (arg.match(/^--/)) {
return false;
}
return arg.match(/(.*)=(.*)/);
}
function setEnvironmentVariables(commands) {
commands.forEach(function (command) {
const regExpMatch = isEnvironmentVariable(command);
function setEnvironmentVariables(args) {
args.forEach(function (arg) {
const regExpMatch = isEnvironmentVariable(arg);
if(regExpMatch) {

@@ -336,9 +385,1 @@ const key = regExpMatch[1];

}
// Future versions of glob will interpret backslashes as escape sequences on
// all platforms, and Jasmine warns about them. Convert to slashes to avoid
// the warning and future behavior change. Should only be called when running
// on Windows.
function unWindows(projectBaseDir) {
return projectBaseDir.replace(/\\/g, '/');
}

@@ -1,8 +0,4 @@

const os = require('os');
const path = require('path');
const util = require('util');
const glob = require('glob');
const Loader = require('./loader');
const ExitHandler = require('./exit_handler');
const ConsoleSpecFilter = require('./filters/console_spec_filter');
const RunnerBase = require('./runner_base');

@@ -34,6 +30,7 @@ /**

/**
* @classdesc Configures, builds, and executes a Jasmine test suite
* @classdesc Configures, builds, and executes a Jasmine test suite.<br>See also {@link ParallelRunner} which provides equivalent functionality for parallel execution.
* @param {(JasmineOptions | undefined)} options
* @constructor
* @name Jasmine
* @extends Runner
* @example

@@ -43,7 +40,6 @@ * const Jasmine = require('jasmine');

*/
class Jasmine {
class Jasmine extends RunnerBase {
constructor(options) {
options = options || {};
this.loader = options.loader || new Loader();
this.isWindows_ = (options.platform || os.platform)() === 'win32';
super(options);
const jasmineCore = options.jasmineCore || require('jasmine-core');

@@ -57,13 +53,2 @@

if (options.projectBaseDir) {
this.validatePath_(options.projectBaseDir);
this.projectBaseDir = options.projectBaseDir;
} else {
this.projectBaseDir = (options.getcwd || path.resolve)();
}
this.specDir = '';
this.specFiles = [];
this.helperFiles = [];
this.requires = [];
/**

@@ -79,7 +64,3 @@ * The Jasmine environment.

this.exit = process.exit;
this.showingColors = true;
this.alwaysListPendingSpecs_ = true;
this.reporter = new module.exports.ConsoleReporter();
this.addReporter(this.reporter);
this.defaultReporterConfigured = false;
this.addReporter(this.reporter_);

@@ -95,9 +76,3 @@ /**

/**
* Whether to cause the Node process to exit when the suite finishes executing.
*
* @name Jasmine#exitOnCompletion
* @type {boolean}
* @default true
*/
// Public. See RunnerBase.
this.exitOnCompletion = true;

@@ -126,49 +101,3 @@ }

/**
* Sets whether to show colors in the console reporter.
* @function
* @name Jasmine#showColors
* @param {boolean} value Whether to show colors
*/
showColors(value) {
this.showingColors = value;
}
/**
* Sets whether the console reporter should list pending specs even when there
* are failures.
* @name Jasmine#alwaysListPendingSpecs
* @param value {boolean}
*/
alwaysListPendingSpecs(value) {
this.alwaysListPendingSpecs_ = value;
}
/**
* Adds a spec file to the list that will be loaded when the suite is executed.
* @function
* @name Jasmine#addSpecFile
* @param {string} filePath The path to the file to be loaded.
*/
addSpecFile(filePath) {
this.specFiles.push(filePath);
}
/**
* Adds a helper file to the list that will be loaded when the suite is executed.
* @function
* @name Jasmine#addHelperFile
* @param {string} filePath The path to the file to be loaded.
*/
addHelperFile(filePath) {
this.helperFiles.push(filePath);
}
/**
* Add a custom reporter to the Jasmine environment.
* @function
* @name Jasmine#addReporter
* @param {Reporter} reporter The reporter to add
* @see custom_reporter
*/
// Public. See RunnerBase jsdocs.
addReporter(reporter) {

@@ -179,7 +108,3 @@ this.env.addReporter(reporter);

/**
* Clears all registered reporters.
* @function
* @name Jasmine#clearReporters
*/
// Public. See RunnerBase jsdocs.
clearReporters() {

@@ -202,17 +127,2 @@ this.env.clearReporters();

/**
* Configures the default reporter that is installed if no other reporter is
* specified.
* @param {ConsoleReporterOptions} options
*/
configureDefaultReporter(options) {
options.print = options.print || function() {
process.stdout.write(util.format.apply(this, arguments));
};
options.showColors = options.hasOwnProperty('showColors') ? options.showColors : true;
this.reporter.setOptions(options);
this.defaultReporterConfigured = true;
}
/**
* Add custom matchers for the current scope of specs.

@@ -248,186 +158,7 @@ *

/**
* Loads configuration from the specified file. The file can be a JSON file or
* any JS file that's loadable via require and provides a Jasmine config
* as its default export.
* @param {string} [configFilePath=spec/support/jasmine.json]
* @return Promise
*/
async loadConfigFile(configFilePath) {
if (configFilePath) {
await this.loadSpecificConfigFile_(configFilePath);
} else {
for (const ext of ['json', 'js']) {
try {
await this.loadSpecificConfigFile_(`spec/support/jasmine.${ext}`);
} catch (e) {
if (e.code !== 'MODULE_NOT_FOUND' && e.code !== 'ERR_MODULE_NOT_FOUND') {
throw e;
}
}
}
}
configureEnv(envConfig) {
this.env.configure(envConfig);
}
async loadSpecificConfigFile_(relativePath) {
const absolutePath = path.resolve(this.projectBaseDir, relativePath);
const config = await this.loader.load(absolutePath);
this.loadConfig(config);
}
/**
* Loads configuration from the specified object.
* @param {Configuration} config
*/
loadConfig(config) {
/**
* @interface Configuration
*/
const envConfig = {...config.env};
/**
* The directory that spec files are contained in, relative to the project
* base directory.
* @name Configuration#spec_dir
* @type string | undefined
*/
this.specDir = config.spec_dir || this.specDir;
this.validatePath_(this.specDir);
/**
* Whether to fail specs that contain no expectations.
* @name Configuration#failSpecWithNoExpectations
* @type boolean | undefined
* @default false
*/
if (config.failSpecWithNoExpectations !== undefined) {
envConfig.failSpecWithNoExpectations = config.failSpecWithNoExpectations;
}
/**
* Whether to stop each spec on the first expectation failure.
* @name Configuration#stopSpecOnExpectationFailure
* @type boolean | undefined
* @default false
*/
if (config.stopSpecOnExpectationFailure !== undefined) {
envConfig.stopSpecOnExpectationFailure = config.stopSpecOnExpectationFailure;
}
/**
* Whether to stop suite execution on the first spec failure.
* @name Configuration#stopOnSpecFailure
* @type boolean | undefined
* @default false
*/
if (config.stopOnSpecFailure !== undefined) {
envConfig.stopOnSpecFailure = config.stopOnSpecFailure;
}
/**
* Whether the default reporter should list pending specs even if there are
* failures.
* @name Configuration#alwaysListPendingSpecs
* @type boolean | undefined
* @default true
*/
if (config.alwaysListPendingSpecs !== undefined) {
this.alwaysListPendingSpecs(config.alwaysListPendingSpecs);
}
/**
* Whether to run specs in a random order.
* @name Configuration#random
* @type boolean | undefined
* @default true
*/
if (config.random !== undefined) {
envConfig.random = config.random;
}
if (config.verboseDeprecations !== undefined) {
envConfig.verboseDeprecations = config.verboseDeprecations;
}
/**
* Specifies how to load files with names ending in .js. Valid values are
* "require" and "import". "import" should be safe in all cases, and is
* required if your project contains ES modules with filenames ending in .js.
* @name Configuration#jsLoader
* @type string | undefined
* @default "require"
*/
if (config.jsLoader === 'import' || config.jsLoader === undefined) {
this.loader.alwaysImport = true;
} else if (config.jsLoader === 'require') {
this.loader.alwaysImport = false;
} else {
throw new Error(`"${config.jsLoader}" is not a valid value for the ` +
'jsLoader configuration property. Valid values are "import", ' +
'"require", and undefined.');
}
if (Object.keys(envConfig).length > 0) {
this.env.configure(envConfig);
}
/**
* An array of helper file paths or {@link https://github.com/isaacs/node-glob#glob-primer|globs}
* that match helper files. Each path or glob will be evaluated relative to
* the spec directory. Helpers are loaded before specs.
* @name Configuration#helpers
* @type string[] | undefined
*/
if(config.helpers) {
this.addMatchingHelperFiles(config.helpers);
}
/**
* An array of module names to load via require() at the start of execution.
* @name Configuration#requires
* @type string[] | undefined
*/
if(config.requires) {
this.addRequires(config.requires);
}
/**
* An array of spec file paths or {@link https://github.com/isaacs/node-glob#glob-primer|globs}
* that match helper files. Each path or glob will be evaluated relative to
* the spec directory.
* @name Configuration#spec_files
* @type string[] | undefined
*/
if(config.spec_files) {
this.addMatchingSpecFiles(config.spec_files);
}
/**
* An array of reporters. Each object in the array will be passed to
* {@link Jasmine#addReporter|addReporter}.
*
* This provides a middle ground between the --reporter= CLI option and full
* programmatic usage. Note that because reporters are objects with methods,
* this option can only be used in JavaScript config files
* (e.g `spec/support/jasmine.js`), not JSON.
* @name Configuration#reporters
* @type Reporter[] | undefined
* @see custom_reporter
*/
if (config.reporters) {
for (const r of config.reporters) {
this.addReporter(r);
}
}
}
addRequires(requires) {
const jasmineRunner = this;
requires.forEach(function(r) {
jasmineRunner.requires.push(r);
});
}
/**
* Sets whether to cause specs to only have one expectation failure.

@@ -454,15 +185,2 @@ * @function

async flushOutput() {
// Ensure that all data has been written to stdout and stderr,
// then exit with an appropriate status code. Otherwise, we
// might exit before all previous writes have actually been
// written when Jasmine is piped to another process that isn't
// reading quickly enough.
var streams = [process.stdout, process.stderr];
var promises = streams.map(stream => {
return new Promise(resolve => stream.write('', null, resolve));
});
return Promise.all(promises);
}
/**

@@ -505,12 +223,18 @@ * Runs the test suite.

await this.loadSpecs();
const prematureExitHandler = new ExitHandler(() => this.exit(4));
prematureExitHandler.install();
const overallResult = await this.env.execute();
await this.flushOutput();
prematureExitHandler.uninstall();
let overallResult;
try {
await this.withinGlobalSetup_(async () => {
await this.loadSpecs();
overallResult = await this.env.execute();
});
} finally {
await this.flushOutput();
prematureExitHandler.uninstall();
}
if (this.exitOnCompletion) {
this.exit(exitCodeForStatus(overallResult.overallStatus));
this.exit(RunnerBase.exitCodeForStatus(overallResult.overallStatus));
}

@@ -520,90 +244,5 @@

}
validatePath_(path) {
if (this.isWindows_ && path.includes('\\')) {
const fixed = path.replace(/\\/g, '/');
console.warn('Backslashes in ' +
'file paths behave inconsistently between platforms and might not be ' +
'treated as directory separators in a future version. Consider ' +
`changing ${path} to ${fixed}.`);
}
}
}
/**
* Adds files that match the specified patterns to the list of spec files.
* @function
* @name Jasmine#addMatchingSpecFiles
* @param {Array<string>} patterns An array of spec file paths
* or {@link https://github.com/isaacs/node-glob#glob-primer|globs} that match
* spec files. Each path or glob will be evaluated relative to the spec directory.
*/
Jasmine.prototype.addMatchingSpecFiles = addFiles('specFiles');
/**
* Adds files that match the specified patterns to the list of helper files.
* @function
* @name Jasmine#addMatchingHelperFiles
* @param {Array<string>} patterns An array of helper file paths
* or {@link https://github.com/isaacs/node-glob#glob-primer|globs} that match
* helper files. Each path or glob will be evaluated relative to the spec directory.
*/
Jasmine.prototype.addMatchingHelperFiles = addFiles('helperFiles');
function addFiles(kind) {
return function (files) {
for (const f of files) {
this.validatePath_(f);
}
const jasmineRunner = this;
const fileArr = this[kind];
const {includeFiles, excludeFiles} = files.reduce(function(ongoing, file) {
const hasNegation = file.startsWith('!');
if (hasNegation) {
file = file.substring(1);
}
if (!path.isAbsolute(file)) {
file = path.join(jasmineRunner.projectBaseDir, jasmineRunner.specDir, file);
}
return {
includeFiles: ongoing.includeFiles.concat(!hasNegation ? [file] : []),
excludeFiles: ongoing.excludeFiles.concat(hasNegation ? [file] : [])
};
}, { includeFiles: [], excludeFiles: [] });
includeFiles.forEach(function(file) {
const filePaths = glob
.sync(file, { ignore: excludeFiles })
.filter(function(filePath) {
// glob will always output '/' as a segment separator but the fileArr may use \ on windows
// fileArr needs to be checked for both versions
return fileArr.indexOf(filePath) === -1 && fileArr.indexOf(path.normalize(filePath)) === -1;
});
filePaths.forEach(function(filePath) {
fileArr.push(filePath);
});
});
};
}
function exitCodeForStatus(status) {
switch (status) {
case 'passed':
return 0;
case 'incomplete':
return 2;
case 'failed':
return 3;
default:
console.error(`Unrecognized overall status: ${status}`);
return 1;
}
}
module.exports = Jasmine;
module.exports.ConsoleReporter = require('./reporters/console_reporter');

@@ -141,3 +141,6 @@ const path = require('path');

} else {
return new Error(`While loading ${importedPath}: ${e.constructor.name}: ${e.message}`);
return new Error(
`While loading ${importedPath}: ${e.constructor.name}: ${e.message}`,
{cause: e}
);
}

@@ -144,0 +147,0 @@ }

@@ -139,2 +139,8 @@ module.exports = exports = ConsoleReporter;

printNewline();
if (result.numWorkers) {
print('Ran in parallel with ' + result.numWorkers + ' workers');
printNewline();
}
const seconds = result ? result.totalTime / 1000 : 0;

@@ -191,2 +197,4 @@ print('Finished in ' + seconds + ' ' + plural('second', seconds));

this.reporterCapabilities = {parallel: true};
return this;

@@ -193,0 +201,0 @@

@@ -13,3 +13,3 @@ {

"license": "MIT",
"version": "4.6.0",
"version": "5.0.0",
"repository": {

@@ -23,3 +23,6 @@ "type": "git",

},
"exports": "./lib/jasmine.js",
"exports": {
".": "./lib/jasmine.js",
"./parallel": "./lib/parallel_runner.js"
},
"files": [

@@ -33,4 +36,4 @@ "bin",

"dependencies": {
"glob": "^7.1.6",
"jasmine-core": "^4.6.0"
"glob": "^10.2.2",
"jasmine-core": "~5.0.0"
},

@@ -40,5 +43,4 @@ "bin": "./bin/jasmine.js",

"devDependencies": {
"eslint": "^6.8.0",
"eslint": "^8.36.0",
"shelljs": "^0.8.3",
"slash": "^3.0.0",
"temp": "^0.9.4"

@@ -45,0 +47,0 @@ },

@@ -53,3 +53,3 @@ [![Build Status](https://circleci.com/gh/jasmine/jasmine-npm.svg?style=shield)](https://circleci.com/gh/jasmine/jasmine-npm)

Jasmine supports Node 18, 16, 14, and 12.17-12.22.
Jasmine supports Node 18 and 20.

@@ -56,0 +56,0 @@ ## Support

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc