Comparing version 2.99.0 to 3.99.0
#!/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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
48519
2
1221
115
6
12
+ Addedjasmine-core@3.99.1(transitive)
- Removedexit@^0.1.2
- Removedexit@0.1.2(transitive)
- Removedjasmine-core@2.99.1(transitive)
Updatedglob@^7.1.6
Updatedjasmine-core@~3.99.0