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 2.99.0 to 3.99.0

lib/loadConfig.js

12

bin/jasmine.js
#!/usr/bin/env node
var path = require('path'),
Command = require('../lib/command.js'),
Jasmine = require('../lib/jasmine.js');
const path = require('path');
const Command = require('../lib/command');
const Jasmine = require('../lib/jasmine');
var jasmine = new Jasmine({ projectBaseDir: path.resolve() });
var examplesDir = path.join(path.dirname(require.resolve('jasmine-core')), 'jasmine-core', 'example', 'node_example');
var command = new Command(path.resolve(), examplesDir, console.log);
const jasmine = new Jasmine({ projectBaseDir: path.resolve() });
const examplesDir = path.join(path.dirname(require.resolve('jasmine-core')), 'jasmine-core', 'example', 'node_example');
const command = new Command(path.resolve(), examplesDir, console.log);
command.run(jasmine, process.argv.slice(2));

@@ -1,7 +0,7 @@

var path = require('path'),
fs = require('fs');
const path = require('path');
const fs = require('fs');
exports = module.exports = Command;
var subCommands = {
const subCommands = {
init: {

@@ -31,3 +31,3 @@ description: 'initialize jasmine',

var command = this;
const command = this;

@@ -37,5 +37,5 @@ this.run = function(jasmine, commands) {

var commandToRun;
let commandToRun;
Object.keys(subCommands).forEach(function(cmd) {
var commandObject = subCommands[cmd];
const commandObject = subCommands[cmd];
if (commands.indexOf(cmd) >= 0) {

@@ -51,4 +51,5 @@ commandToRun = commandObject;

} else {
var env = parseOptions(commands);
const env = parseOptions(commands);
if (env.unknownOptions.length > 0) {
process.exitCode = 1;
print('Unknown options: ' + env.unknownOptions.join(', '));

@@ -58,3 +59,3 @@ print('');

} else {
runJasmine(jasmine, env);
runJasmine(jasmine, env, print);
}

@@ -70,15 +71,21 @@ }

function parseOptions(argv) {
var files = [],
let files = [],
helpers = [],
requires = [],
unknownOptions = [],
color = process.stdout.isTTY || false,
reporter,
configPath,
filter,
stopOnFailure,
failFast,
random,
seed;
argv.forEach(function(arg) {
for (let i in argv) {
const arg = argv[i];
if (arg === '--no-color') {
color = false;
} else if (arg === '--color') {
color = true;
} else if (arg.match("^--filter=")) {

@@ -88,4 +95,8 @@ filter = arg.match("^--filter=(.*)")[1];

helpers.push(arg.match("^--helper=(.*)")[1]);
} else if (arg.match("^--require=")) {
requires.push(arg.match("^--require=(.*)")[1]);
} else if (arg.match("^--stop-on-failure=")) {
stopOnFailure = arg.match("^--stop-on-failure=(.*)")[1] === 'true';
} else if (arg.match("^--fail-fast=")) {
failFast = arg.match("^--fail-fast=(.*)")[1] === 'true';
} else if (arg.match("^--random=")) {

@@ -97,2 +108,6 @@ random = arg.match("^--random=(.*)")[1] === 'true';

configPath = arg.match("^--config=(.*)")[1];
} else if (arg.match("^--reporter=")) {
reporter = arg.match("^--reporter=(.*)")[1];
} else if (arg === '--') {
break;
} else if (isFileArg(arg)) {

@@ -103,3 +118,3 @@ files.push(arg);

}
});
}
return {

@@ -110,3 +125,6 @@ color: color,

stopOnFailure: stopOnFailure,
failFast: failFast,
helpers: helpers,
requires: requires,
reporter: reporter,
files: files,

@@ -119,23 +137,15 @@ random: random,

function runJasmine(jasmine, env) {
jasmine.loadConfigFile(env.configPath || process.env.JASMINE_CONFIG_PATH);
if (env.stopOnFailure !== undefined) {
jasmine.stopSpecOnExpectationFailure(env.stopOnFailure);
}
if (env.seed !== undefined) {
jasmine.seed(env.seed);
}
if (env.random !== undefined) {
jasmine.randomizeTests(env.random);
}
if (env.helpers !== undefined && env.helpers.length) {
jasmine.addHelperFiles(env.helpers);
}
jasmine.showColors(env.color);
jasmine.execute(env.files, env.filter);
function runJasmine(jasmine, env, print) {
const loadConfig = require('./loadConfig');
loadConfig(jasmine, env, print);
jasmine.execute(env.files, env.filter)
.catch(function(error) {
console.error(error);
process.exit(1);
});
}
function initJasmine(options) {
var print = options.print;
var specDir = options.specDir;
const print = options.print;
const specDir = options.specDir;
makeDirStructure(path.join(specDir, 'support/'));

@@ -151,5 +161,5 @@ if(!fs.existsSync(path.join(specDir, 'support/jasmine.json'))) {

function installExamples(options) {
var specDir = options.specDir;
var projectBaseDir = options.projectBaseDir;
var examplesDir = options.examplesDir;
const specDir = options.specDir;
const projectBaseDir = options.projectBaseDir;
const examplesDir = options.examplesDir;

@@ -181,8 +191,8 @@ makeDirStructure(path.join(specDir, 'support'));

function help(options) {
var print = options.print;
print('Usage: jasmine [command] [options] [files]');
const print = options.print;
print('Usage: jasmine [command] [options] [files] [--]');
print('');
print('Commands:');
Object.keys(subCommands).forEach(function(cmd) {
var commandNameText = cmd;
let commandNameText = cmd;
if(subCommands[cmd].alias) {

@@ -200,6 +210,11 @@ commandNameText = commandNameText + ',' + subCommands[cmd].alias;

print('%s\tturn off color in spec output', lPad('--no-color', 18));
print('%s\tforce turn on color in spec output', lPad('--color', 18));
print('%s\tfilter specs to run only those that match the given string', lPad('--filter=', 18));
print('%s\tload helper files that match the given string', lPad('--helper=', 18));
print('%s\tload module that match the given string', lPad('--require=', 18));
print('%s\t[true|false] stop spec execution on expectation failure', lPad('--stop-on-failure=', 18));
print('%s\t[true|false] stop Jasmine execution on spec failure', lPad('--fail-fast=', 18));
print('%s\tpath to your optional jasmine.json', lPad('--config=', 18));
print('%s\tpath to reporter to use instead of the default Jasmine reporter', lPad('--reporter=', 18));
print('%s\tmarker to signal the end of options meant for Jasmine', lPad('--', 18));
print('');

@@ -211,3 +226,3 @@ print('The given arguments take precedence over options in your jasmine.json');

function version(options) {
var print = options.print;
const print = options.print;
print('jasmine v' + require('../package.json').version);

@@ -226,3 +241,3 @@ print('jasmine-core v' + options.jasmine.coreVersion());

function copyFiles(srcDir, destDir, pattern) {
var srcDirFiles = fs.readdirSync(srcDir);
const srcDirFiles = fs.readdirSync(srcDir);
srcDirFiles.forEach(function(file) {

@@ -236,6 +251,6 @@ if (file.search(pattern) !== -1) {

function makeDirStructure(absolutePath) {
var splitPath = absolutePath.split(path.sep);
const splitPath = absolutePath.split(path.sep);
splitPath.forEach(function(dir, index) {
if(index > 1) {
var fullPath = path.join(splitPath.slice(0, index).join('/'), dir);
const fullPath = path.join(splitPath.slice(0, index).join('/'), dir);
if (!fs.existsSync(fullPath)) {

@@ -249,3 +264,3 @@ fs.mkdirSync(fullPath);

function isEnvironmentVariable(command) {
var envRegExp = /(.*)=(.*)/;
const envRegExp = /(.*)=(.*)/;
return command.match(envRegExp);

@@ -256,6 +271,6 @@ }

commands.forEach(function (command) {
var regExpMatch = isEnvironmentVariable(command);
const regExpMatch = isEnvironmentVariable(command);
if(regExpMatch) {
var key = regExpMatch[1];
var value = regExpMatch[2];
const key = regExpMatch[1];
const value = regExpMatch[2];
process.env[key] = value;

@@ -262,0 +277,0 @@ }

{
"spec_dir": "spec",
"spec_files": [
"**/*[sS]pec.js"
"**/*[sS]pec.?(m)js"
],
"helpers": [
"helpers/**/*.js"
"helpers/**/*.?(m)js"
],
"stopSpecOnExpectationFailure": false,
"random": false
"random": true
}
module.exports = exports = ConsoleSpecFilter;
function ConsoleSpecFilter(options) {
var filterString = options && options.filterString;
var filterPattern = new RegExp(filterString);
const filterString = options && options.filterString;
const filterPattern = new RegExp(filterString);

@@ -7,0 +7,0 @@ this.matches = function(specName) {

@@ -1,7 +0,7 @@

var path = require('path'),
util = require('util'),
glob = require('glob'),
exit = require('./exit'),
CompletionReporter = require('./reporters/completion_reporter'),
ConsoleSpecFilter = require('./filters/console_spec_filter');
const path = require('path');
const util = require('util');
const glob = require('glob');
const Loader = require('./loader');
const CompletionReporter = require('./reporters/completion_reporter');
const ConsoleSpecFilter = require('./filters/console_spec_filter');

@@ -11,17 +11,47 @@ module.exports = Jasmine;

/**
* Options for the {@link Jasmine} constructor
* @name JasmineOptions
* @interface
*/
/**
* The path to the project's base directory. This can be absolute or relative
* to the current working directory. If it isn't specified, the current working
* directory will be used.
* @name JasmineOptions#projectBaseDir
* @type (string | undefined)
*/
/**
* @classdesc Configures, builds, and executes a Jasmine test suite
* @param {(JasmineOptions | undefined)} options
* @constructor
* @name Jasmine
* @example
* const Jasmine = require('jasmine');
* const jasmine = new Jasmine();
*/
function Jasmine(options) {
options = options || {};
var jasmineCore = options.jasmineCore || require('jasmine-core');
this.loader = options.loader || new Loader();
const jasmineCore = options.jasmineCore || require('jasmine-core');
this.jasmineCorePath = path.join(jasmineCore.files.path, 'jasmine.js');
this.jasmine = jasmineCore.boot(jasmineCore);
this.projectBaseDir = options.projectBaseDir || path.resolve();
this.printDeprecation = options.printDeprecation || require('./printDeprecation');
this.specDir = '';
this.specFiles = [];
this.helperFiles = [];
this.env = this.jasmine.getEnv();
this.requires = [];
/**
* The Jasmine environment.
* @name Jasmine#env
* @readonly
* @see {@link https://jasmine.github.io/api/edge/Env.html|Env}
* @type {Env}
*/
this.env = this.jasmine.getEnv({suppressLoadErrors: true});
this.reportersCount = 0;
this.completionReporter = new CompletionReporter();
this.onCompleteCallbackAdded = false;
this.exit = exit;
this.exit = process.exit;
this.showingColors = true;

@@ -32,3 +62,3 @@ this.reporter = new module.exports.ConsoleReporter();

var jasmineRunner = this;
const jasmineRunner = this;
this.completionReporter.onComplete(function(passed) {

@@ -39,15 +69,49 @@ jasmineRunner.exitCodeCompletion(passed);

/**
* @function
* @name Jasmine#coreVersion
* @return {string} The version of jasmine-core in use
*/
this.coreVersion = function() {
return jasmineCore.version();
};
/**
* Whether to cause the Node process to exit when the suite finishes executing.
*
* _Note_: If {@link Jasmine#onComplete|onComplete} is called, Jasmine will not
* exit when the suite completes even if exitOnCompletion is set to true.
* @name Jasmine#exitOnCompletion
* @type {boolean}
* @default true
*/
this.exitOnCompletion = true;
}
/**
* Sets whether to randomize the order of specs.
* @function
* @name Jasmine#randomizeTests
* @param {boolean} value Whether to randomize
*/
Jasmine.prototype.randomizeTests = function(value) {
this.env.randomizeTests(value);
this.env.configure({random: value});
};
/**
* Sets the random seed.
* @function
* @name Jasmine#seed
* @param {number} seed The random seed
*/
Jasmine.prototype.seed = function(value) {
this.env.seed(value);
this.env.configure({seed: value});
};
/**
* Sets whether to show colors in the console reporter.
* @function
* @name Jasmine#showColors
* @param {boolean} value Whether to show colors
*/
Jasmine.prototype.showColors = function(value) {

@@ -57,2 +121,8 @@ this.showingColors = 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.
*/
Jasmine.prototype.addSpecFile = function(filePath) {

@@ -62,2 +132,19 @@ 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.
*/
Jasmine.prototype.addHelperFile = function(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
*/
Jasmine.prototype.addReporter = function(reporter) {

@@ -68,2 +155,7 @@ this.env.addReporter(reporter);

/**
* Clears all registered reporters.
* @function
* @name Jasmine#clearReporters
*/
Jasmine.prototype.clearReporters = function() {

@@ -74,2 +166,9 @@ this.env.clearReporters();

/**
* Provide a fallback reporter if no other reporters have been specified.
* @function
* @name Jasmine#provideFallbackReporter
* @param reporter The fallback reporter
* @see custom_reporter
*/
Jasmine.prototype.provideFallbackReporter = function(reporter) {

@@ -79,4 +178,8 @@ this.env.provideFallbackReporter(reporter);

/**
* Configures the default reporter that is installed if no other reporter is
* specified.
* @param {ConsoleReporterOptions} options
*/
Jasmine.prototype.configureDefaultReporter = function(options) {
options.timer = options.timer || new this.jasmine.Timer();
options.print = options.print || function() {

@@ -88,5 +191,2 @@ process.stdout.write(util.format.apply(this, arguments));

if(options.onComplete) {
this.printDeprecation('Passing in an onComplete function to configureDefaultReporter is deprecated.');
}
this.reporter.setOptions(options);

@@ -96,2 +196,11 @@ this.defaultReporterConfigured = true;

/**
* Add custom matchers for the current scope of specs.
*
* _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.
* @function
* @name Jasmine#addMatchers
* @param {Object} matchers - Keys from this object will be the new matcher names.
* @see custom_matcher
*/
Jasmine.prototype.addMatchers = function(matchers) {

@@ -101,18 +210,41 @@ this.env.addMatchers(matchers);

Jasmine.prototype.loadSpecs = function() {
this.specFiles.forEach(function(file) {
require(file);
});
Jasmine.prototype.loadSpecs = async function() {
await this._loadFiles(this.specFiles);
};
Jasmine.prototype.loadHelpers = function() {
this.helperFiles.forEach(function(file) {
require(file);
Jasmine.prototype.loadHelpers = async function() {
await this._loadFiles(this.helperFiles);
};
Jasmine.prototype._loadFiles = async function(files) {
for (const file of files) {
await this.loader.load(file, this._alwaysImport || false);
}
};
Jasmine.prototype.loadRequires = function() {
// TODO: In 4.0, switch to calling _loadFiles
// (requires making this function async)
this.requires.forEach(function(r) {
if (r.startsWith('./') || r.startsWith("../")) {
console.warn('DEPRECATION: requires with relative paths (in this case ' +
`${r}) are currently resolved relative to the jasmine/lib/jasmine ` +
'module but will be relative to the current working directory in ' +
'Jasmine 4.0.');
}
require(r);
});
};
/**
* 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]
*/
Jasmine.prototype.loadConfigFile = function(configFilePath) {
try {
var absoluteConfigFilePath = path.resolve(this.projectBaseDir, configFilePath || 'spec/support/jasmine.json');
var config = require(absoluteConfigFilePath);
const absoluteConfigFilePath = path.resolve(this.projectBaseDir, configFilePath || 'spec/support/jasmine.json');
const config = require(absoluteConfigFilePath);
this.loadConfig(config);

@@ -124,33 +256,212 @@ } catch (e) {

/**
* Loads configuration from the specified object.
* @param {Configuration} config
*/
Jasmine.prototype.loadConfig = function(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.env.throwOnExpectationFailure(config.stopSpecOnExpectationFailure);
this.env.randomizeTests(config.random);
/**
* 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 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') {
checkForJsFileImportSupport();
this._alwaysImport = true;
} else if (config.jsLoader === 'require' || config.jsLoader === undefined) {
this._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.addHelperFiles(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.addSpecFiles(config.spec_files);
this.addMatchingSpecFiles(config.spec_files);
}
};
Jasmine.prototype.addHelperFiles = addFiles('helperFiles');
Jasmine.prototype.addSpecFiles = addFiles('specFiles');
/**
* 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');
// Deprecated synonyms for the above. These are confusingly named (addSpecFiles
// doesn't just do N of what addSpecFile does) but they've been around a long
// time and there might be quite a bit of code that uses them.
/**
* Synonym for {@link Jasmine#addMatchingSpecFiles}
* @function
* @name Jasmine#addSpecFiles
* @deprecated Use {@link Jasmine#addMatchingSpecFiles|addMatchingSpecFiles},
* {@link Jasmine#loadConfig|loadConfig}, or {@link Jasmine#loadConfigFile|loadConfigFile}
* instead.
*/
Jasmine.prototype.addSpecFiles = function(globs) {
this.env.deprecated('jasmine#addSpecFiles is deprecated. Use ' +
'jasmine#addMatchingSpecFiles instead.');
this.addMatchingSpecFiles(globs);
};
/**
* Synonym for {@link Jasmine#addMatchingHelperFiles}
* @name Jasmine#addHelperFiles
* @function
* @deprecated Use {@link Jasmine#addMatchingHelperFiles|addMatchingHelperFiles},
* {@link Jasmine#loadConfig|loadConfig}, or {@link Jasmine#loadConfigFile|loadConfigFile}
* instead.
*/
Jasmine.prototype.addHelperFiles = function(globs) {
this.env.deprecated('jasmine#addHelperFiles is deprecated. Use ' +
'jasmine#addMatchingHelperFiles instead.');
this.addMatchingHelperFiles(globs);
};
Jasmine.prototype.addRequires = function(requires) {
const jasmineRunner = this;
requires.forEach(function(r) {
jasmineRunner.requires.push(r);
});
};
function addFiles(kind) {
return function (files) {
var jasmineRunner = this;
var fileArr = this[kind];
const jasmineRunner = this;
const fileArr = this[kind];
files.forEach(function(file) {
if(!(path.isAbsolute && path.isAbsolute(file))) {
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);
}
var filePaths = glob.sync(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) {
if(fileArr.indexOf(filePath) === -1) {
fileArr.push(filePath);
}
fileArr.push(filePath);
});

@@ -161,20 +472,72 @@ });

/**
* Registers a callback that will be called when execution finishes.
*
* _Note_: Only one callback can be registered. The callback will be called
* after the suite has completed and the results have been finalized, but not
* necessarily before all of Jasmine's cleanup has finished. Calling this
* function will also prevent Jasmine from exiting the Node process at the end
* of suite execution.
*
* @deprecated Set {@link Jasmine#exitOnCompletion|exitOnCompletion} to false
* and use the promise returned from {@link Jasmine#execute|execute} instead.
* @param {function} onCompleteCallback
*/
Jasmine.prototype.onComplete = function(onCompleteCallback) {
this.env.deprecated(
'Jasmine#onComplete is deprecated. Instead of calling onComplete, set ' +
"the Jasmine instance's exitOnCompletion property to false and use the " +
'promise returned from the execute method.'
);
this.completionReporter.onComplete(onCompleteCallback);
};
/**
* Sets whether to cause specs to only have one expectation failure.
* @function
* @name Jasmine#stopSpecOnExpectationFailure
* @param {boolean} value Whether to cause specs to only have one expectation
* failure
*/
Jasmine.prototype.stopSpecOnExpectationFailure = function(value) {
this.env.throwOnExpectationFailure(value);
this.env.configure({stopSpecOnExpectationFailure: value});
};
/**
* Sets whether to stop execution of the suite after the first spec failure.
* @function
* @name Jasmine#stopOnSpecFailure
* @param {boolean} value Whether to stop execution of the suite after the
* first spec failure
*/
Jasmine.prototype.stopOnSpecFailure = function(value) {
this.env.configure({stopOnSpecFailure: value});
};
Jasmine.prototype.exitCodeCompletion = function(passed) {
if(passed) {
this.exit(0, process.platform, process.version, process.exit, require('exit'));
// 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.
const jasmineRunner = this;
const streams = [process.stdout, process.stderr];
let writesToWait = streams.length;
streams.forEach(function(stream) {
stream.write('', null, exitIfAllStreamsCompleted);
});
function exitIfAllStreamsCompleted() {
writesToWait--;
if (writesToWait === 0 && jasmineRunner.exitOnCompletion) {
if(passed) {
jasmineRunner.exit(0);
}
else {
jasmineRunner.exit(1);
}
}
}
else {
this.exit(1, process.platform, process.version, process.exit, require('exit'));
}
};
var checkExit = function(jasmineRunner) {
const checkExit = function(jasmineRunner) {
return function() {

@@ -187,6 +550,30 @@ if (!jasmineRunner.completionReporter.isComplete()) {

Jasmine.prototype.execute = function(files, filterString) {
process.on('exit', this.checkExit);
function checkForJsFileImportSupport() {
const v = process.versions.node
.split('.')
.map(el => parseInt(el, 10));
this.loadHelpers();
if (v[0] < 12 || (v[0] === 12 && v[1] < 17)) {
console.warn('Warning: jsLoader: "import" may not work reliably on Node ' +
'versions before 12.17.');
}
}
/**
* Runs the test suite.
*
* _Note_: Set {@link Jasmine#exitOnCompletion|exitOnCompletion} to false if you
* intend to use the returned promise. Otherwise, the Node process will
* ordinarily exit before the promise is settled.
* @param {Array.<string>} [files] Spec files to run instead of the previously
* configured set
* @param {string} [filterString] Regex used to filter specs. If specified, only
* specs with matching full names will be run.
* @return {Promise<JasmineDoneInfo>} Promise that is resolved when the suite completes.
*/
Jasmine.prototype.execute = async function(files, filterString) {
this.completionReporter.exitHandler = this.checkExit;
this.loadRequires();
await this.loadHelpers();
if (!this.defaultReporterConfigured) {

@@ -196,9 +583,9 @@ this.configureDefaultReporter({ showColors: this.showingColors });

if(filterString) {
var specFilter = new ConsoleSpecFilter({
if (filterString) {
const specFilter = new ConsoleSpecFilter({
filterString: filterString
});
this.env.specFilter = function(spec) {
this.env.configure({specFilter: function(spec) {
return specFilter.matches(spec.getFullName());
};
}});
}

@@ -209,9 +596,20 @@

this.specFiles = [];
this.addSpecFiles(files);
this.addMatchingSpecFiles(files);
}
this.loadSpecs();
await this.loadSpecs();
this.addReporter(this.completionReporter);
this.env.execute();
if (!this.completionReporterInstalled_) {
this.addReporter(this.completionReporter);
this.completionReporterInstalled_ = true;
}
let overallResult;
this.addReporter({
jasmineDone: r => overallResult = r
});
await new Promise(resolve => {
this.env.execute(null, resolve);
});
return overallResult;
};
module.exports = function() {
var results = true;
var onCompleteCallback = function() {};
var completed = false;
let onCompleteCallback = function() {};
let completed = false;

@@ -10,8 +9,15 @@ this.onComplete = function(callback) {

this.jasmineStarted = function() {
if (this.exitHandler) {
process.on('exit', this.exitHandler);
}
};
this.jasmineDone = function(result) {
completed = true;
if (result && result.failedExpectations && result.failedExpectations.length > 0) {
results = false;
if (this.exitHandler) {
process.removeListener('exit', this.exitHandler);
}
onCompleteCallback(results);
onCompleteCallback(result.overallStatus === 'passed');
};

@@ -23,13 +29,3 @@

this.specDone = function(result) {
if(result.status === 'failed') {
results = false;
}
};
this.suiteDone = function(result) {
if (result.failedExpectations && result.failedExpectations.length > 0) {
results = false;
}
};
this.exitHandler = null;
};
module.exports = exports = ConsoleReporter;
var noopTimer = {
start: function(){},
elapsed: function(){ return 0; }
};
/**
* @classdesc A reporter that prints spec and suite results to the console.
* A ConsoleReporter is installed by default.
*
* @constructor
* @example
* const {ConsoleReporter} = require('jasmine');
* const reporter = new ConsoleReporter();
*/
function ConsoleReporter() {
var print = function() {},
let print = function() {},
showColors = false,
timer = noopTimer,
jasmineCorePath = null,
printDeprecation = function() {},
specCount,

@@ -26,5 +28,10 @@ executableSpecCount,

failedSuites = [],
stackFilter = defaultStackFilter,
onComplete = function() {};
stackFilter = defaultStackFilter;
/**
* Configures the reporter.
* @function
* @name ConsoleReporter#setOptions
* @param {ConsoleReporterOptions} options
*/
this.setOptions = function(options) {

@@ -34,19 +41,28 @@ if (options.print) {

}
/**
* @interface ConsoleReporterOptions
*/
/**
* Whether to colorize the output
* @name ConsoleReporterOptions#showColors
* @type Boolean|undefined
* @default false
*/
showColors = options.showColors || false;
if (options.timer) {
timer = options.timer;
}
if (options.jasmineCorePath) {
jasmineCorePath = options.jasmineCorePath;
}
if (options.printDeprecation) {
printDeprecation = options.printDeprecation;
}
if (options.stackFilter) {
stackFilter = options.stackFilter;
}
if(options.onComplete) {
printDeprecation('Passing in an onComplete function to the ConsoleReporter is deprecated.');
onComplete = options.onComplete;
/**
* A function that takes a random seed and returns the command to reproduce
* that seed. Use this to customize the output when using ConsoleReporter
* in a different command line tool.
* @name ConsoleReporterOptions#randomSeedReproductionCmd
* @type Function|undefined
*/
if (options.randomSeedReproductionCmd) {
this.randomSeedReproductionCmd = options.randomSeedReproductionCmd;
}

@@ -65,3 +81,2 @@ };

printNewline();
timer.start();
};

@@ -72,9 +87,17 @@

printNewline();
if(failedSpecs.length > 0) {
if (failedSpecs.length > 0) {
print('Failures:');
}
for (var i = 0; i < failedSpecs.length; i++) {
for (let i = 0; i < failedSpecs.length; i++) {
specFailureDetails(failedSpecs[i], i + 1);
}
for(let i = 0; i < failedSuites.length; i++) {
suiteFailureDetails(failedSuites[i]);
}
if (result && result.failedExpectations && result.failedExpectations.length > 0) {
suiteFailureDetails({ fullName: 'top suite', ...result });
}
if (pendingSpecs.length > 0) {

@@ -94,3 +117,3 @@ print("Pending:");

}
var specCounts = executableSpecCount + ' ' + plural('spec', executableSpecCount) + ', ' +
let specCounts = executableSpecCount + ' ' + plural('spec', executableSpecCount) + ', ' +
failureCount + ' ' + plural('failure', failureCount);

@@ -108,20 +131,20 @@

printNewline();
var seconds = timer.elapsed() / 1000;
const seconds = result ? result.totalTime / 1000 : 0;
print('Finished in ' + seconds + ' ' + plural('second', seconds));
printNewline();
for(i = 0; i < failedSuites.length; i++) {
suiteFailureDetails(failedSuites[i]);
if (result && result.overallStatus === 'incomplete') {
print('Incomplete: ' + result.incompleteReason);
printNewline();
}
if (result && result.failedExpectations) {
suiteFailureDetails(result);
}
if (result && result.order && result.order.random) {
print('Randomized with seed ' + result.order.seed);
print(' (' + this.randomSeedReproductionCmd(result.order.seed) + ')');
printNewline();
}
};
onComplete(failureCount === 0);
this.randomSeedReproductionCmd = function(seed) {
return 'jasmine --random=true --seed=' + seed;
};

@@ -175,4 +198,4 @@

function repeat(thing, times) {
var arr = [];
for (var i = 0; i < times; i++) {
const arr = [];
for (let i = 0; i < times; i++) {
arr.push(thing);

@@ -184,5 +207,5 @@ }

function indent(str, spaces) {
var lines = (str || '').split('\n');
var newArr = [];
for (var i = 0; i < lines.length; i++) {
const lines = (str || '').split('\n');
const newArr = [];
for (let i = 0; i < lines.length; i++) {
newArr.push(repeat(' ', spaces).join('') + lines[i]);

@@ -198,3 +221,3 @@ }

var filteredStack = stack.split('\n').filter(function(stackLine) {
const filteredStack = stack.split('\n').filter(function(stackLine) {
return stackLine.indexOf(jasmineCorePath) === -1;

@@ -209,6 +232,26 @@ }).join('\n');

print(result.fullName);
printFailedExpectations(result);
for (var i = 0; i < result.failedExpectations.length; i++) {
var failedExpectation = result.failedExpectations[i];
if (result.trace) {
printNewline();
print(indent('Trace:', 2));
printNewline();
for (const entry of result.trace) {
print(indent(`${entry.timestamp}ms: ${entry.message}`, 4));
printNewline();
}
}
}
function suiteFailureDetails(result) {
printNewline();
print('Suite error: ' + result.fullName);
printFailedExpectations(result);
}
function printFailedExpectations(result) {
for (let i = 0; i < result.failedExpectations.length; i++) {
const failedExpectation = result.failedExpectations[i];
printNewline();
print(indent('Message:', 2));

@@ -223,13 +266,17 @@ printNewline();

printNewline();
}
function suiteFailureDetails(result) {
for (var i = 0; i < result.failedExpectations.length; i++) {
// When failSpecWithNoExpectations = true and a spec fails because of no expectations found,
// jasmine-core reports it as a failure with no message.
//
// Therefore we assume that when there are no failed or passed expectations,
// the failure was because of our failSpecWithNoExpectations setting.
//
// Same logic is used by jasmine.HtmlReporter, see https://github.com/jasmine/jasmine/blob/main/src/html/HtmlReporter.js
if (result.failedExpectations.length === 0 &&
result.passedExpectations.length === 0) {
printNewline();
print(colored('red', 'An error was thrown in an afterAll'));
print(indent('Message:', 2));
printNewline();
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
print(colored('red', indent('Spec has no expectations', 4)));
}
}
printNewline();

@@ -244,3 +291,3 @@ }

printNewline();
var pendingReason = "No reason given";
let pendingReason = "No reason given";
if (result.pendingReason && result.pendingReason !== '') {

@@ -247,0 +294,0 @@ pendingReason = result.pendingReason;

{
"name": "jasmine",
"description": "Command line jasmine",
"description": "CLI for Jasmine, a simple JavaScript testing framework for browsers and Node",
"homepage": "http://jasmine.github.io/",
"keywords": [
"test",
"testing",
"jasmine",

@@ -12,3 +13,3 @@ "tdd",

"license": "MIT",
"version": "2.99.0",
"version": "3.99.0",
"repository": {

@@ -19,8 +20,15 @@ "type": "git",

"scripts": {
"test": "./node_modules/.bin/grunt && ./bin/jasmine.js"
"test": "node ./bin/jasmine.js",
"posttest": "eslint \"bin/**/*.js\" \"lib/**/*.js\" \"spec/**/*.js\""
},
"files": [
"bin",
"lib",
"MIT.LICENSE",
"package.json",
"README.md"
],
"dependencies": {
"exit": "^0.1.2",
"glob": "^7.0.6",
"jasmine-core": "~2.99.0"
"glob": "^7.1.6",
"jasmine-core": "~3.99.0"
},

@@ -30,7 +38,35 @@ "bin": "./bin/jasmine.js",

"devDependencies": {
"grunt": "^0.4.2",
"grunt-cli": "^0.1.13",
"grunt-contrib-jshint": "^0.11.0",
"shelljs": "^0.3.0"
"eslint": "^6.8.0",
"grunt": "^1.0.4",
"grunt-cli": "^1.3.2",
"shelljs": "^0.8.3",
"slash": "^3.0.0",
"temp": "^0.9.4"
},
"eslintConfig": {
"parserOptions": {
"ecmaVersion": 11
},
"rules": {
"no-unused-vars": [
"error",
{
"args": "none"
}
],
"block-spacing": "error",
"func-call-spacing": [
"error",
"never"
],
"key-spacing": "error",
"no-tabs": "error",
"no-whitespace-before-property": "error",
"semi": [
"error",
"always"
],
"space-before-blocks": "error"
}
}
}

@@ -1,6 +0,8 @@

[![Build Status](https://travis-ci.org/jasmine/jasmine-npm.png?branch=master)](https://travis-ci.org/jasmine/jasmine-npm)
[![Build Status](https://circleci.com/gh/jasmine/jasmine-npm.svg?style=shield)](https://circleci.com/gh/jasmine/jasmine-npm)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fjasmine%2Fjasmine-npm.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fjasmine%2Fjasmine-npm?ref=badge_shield)
# The Jasmine Module
The `jasmine` module is a package of helper code for developing Jasmine projects for Node.js.
The `jasmine` module is a command line interface and supporting code for running
[Jasmine](https://github.com/jasmine/jasmine) specs under Node.

@@ -15,3 +17,3 @@ The core of jasmine lives at https://github.com/jasmine/jasmine and is `jasmine-core` in npm.

https://jasmine.github.io/2.8/node.html
https://jasmine.github.io/edge/node.html

@@ -33,2 +35,10 @@ ## Installation

To initialize a project for Jasmine when being installed locally
`node_modules/.bin/jasmine init`
or
`npx jasmine init`
To seed your project with some examples

@@ -48,3 +58,3 @@

You may use dir glob strings.
More information on the format of `jasmine.json` can be found in [the documentation](http://jasmine.github.io/2.4/node.html#section-Configuration)
More information on the format of `jasmine.json` can be found in [the documentation](http://jasmine.github.io/edge/node.html#section-Configuration)

@@ -58,2 +68,39 @@ Alternatively, you may specify the path to your `jasmine.json` by setting an environment variable or an option:

## Using ES modules
If the name of a spec file or helper file ends in `.mjs`, Jasmine will load it
as an [ES module](https://nodejs.org/docs/latest-v13.x/api/esm.html) rather
than a CommonJS module. This allows the spec file or helper to import other
ES modules. No extra configuration is required.
You can also use ES modules with names ending in `.js` by adding
`"jsLoader": "import"` to `jasmine.json`. This should work for CommonJS modules
as well as ES modules. We expect to make it the default in a future release.
Please [log an issue](https://github.com/jasmine/jasmine-npm/issues) if you have
code that doesn't load correctly with `"jsLoader": "import"`.
# Filtering specs
Execute only those specs which filename match given glob:
```shell
jasmine "spec/**/critical/*Spec.js"
```
Or a single file:
```shell
jasmine spec/currentSpec.js
```
Or execute only those specs which name matches a particular regex:
```shell
jasmine --filter "adapter21*"
```
(where the *name* of a spec is the first parameter passed to `describe()`)
## Support

@@ -68,1 +115,5 @@

Copyright (c) 2008-2017 Pivotal Labs. This software is licensed under the MIT License.
## License
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fjasmine%2Fjasmine-npm.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fjasmine%2Fjasmine-npm?ref=badge_large)

Sorry, the diff of this file is not supported yet

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