Comparing version 5.1.0 to 5.2.0
@@ -5,2 +5,3 @@ #!/usr/bin/env node | ||
const os = require('os'); | ||
const process = require('process'); | ||
const Command = require('../lib/command'); | ||
@@ -15,5 +16,10 @@ const Jasmine = require('../lib/jasmine'); | ||
print: console.log, | ||
terminalColumns: process.stdout.columns, | ||
platform: os.platform, | ||
}); | ||
command.run(process.argv.slice(2)); | ||
command.run(process.argv.slice(2)) | ||
.catch(e => { | ||
console.error(e); | ||
process.exit(1); | ||
}); |
@@ -30,3 +30,3 @@ const path = require('path'); | ||
function Command(projectBaseDir, examplesDir, deps) { | ||
const {print, platform, Jasmine, ParallelRunner} = deps; | ||
const {print, platform, terminalColumns, Jasmine, ParallelRunner} = deps; | ||
const isWindows = platform() === 'win32'; | ||
@@ -58,3 +58,4 @@ | ||
examplesDir: examplesDir, | ||
print, | ||
terminalColumns | ||
}); | ||
@@ -71,3 +72,3 @@ } else { | ||
print(''); | ||
help({print: print}); | ||
help({print, terminalColumns}); | ||
} else { | ||
@@ -85,15 +86,16 @@ await runJasmine(Jasmine, ParallelRunner, projectBaseDir, options); | ||
function parseOptions(argv, isWindows) { | ||
let files = [], | ||
helpers = [], | ||
requires = [], | ||
unknownOptions = [], | ||
usageErrors = [], | ||
color = process.stdout.isTTY || false, | ||
reporter, | ||
configPath, | ||
filter, | ||
failFast, | ||
random, | ||
seed, | ||
numWorkers = 1; | ||
let files = []; | ||
let helpers = []; | ||
let requires = []; | ||
let unknownOptions = []; | ||
let usageErrors = []; | ||
let color = process.stdout.isTTY || false; | ||
let reporter; | ||
let configPath; | ||
let filter; | ||
let failFast; | ||
let random; | ||
let seed; | ||
let numWorkers = 1; | ||
let verbose = false; | ||
@@ -132,2 +134,4 @@ for (const arg of argv) { | ||
} | ||
} else if (arg === '--verbose') { | ||
verbose = true; | ||
} else if (arg === '--') { | ||
@@ -158,2 +162,3 @@ break; | ||
numWorkers, | ||
verbose, | ||
usageErrors | ||
@@ -177,2 +182,3 @@ }; | ||
runner.verbose(options.verbose); | ||
await runner.loadConfigFile(options.configPath || process.env.JASMINE_CONFIG_PATH); | ||
@@ -289,5 +295,7 @@ | ||
function help(options) { | ||
const print = options.print; | ||
print('Usage: jasmine [command] [options] [files] [--]'); | ||
function help(deps) { | ||
const print = deps.print; | ||
let terminalColumns = deps.terminalColumns || 80; | ||
print(wrap(terminalColumns, 'Usage: jasmine [command] [options] [files] [--]')); | ||
print(''); | ||
@@ -300,6 +308,6 @@ print('Commands:'); | ||
} | ||
print('%s\t%s', lPad(commandNameText, 10), subCommands[cmd].description); | ||
print(wrapWithIndent(terminalColumns, lPad(commandNameText, 10) + ' ', subCommands[cmd].description)); | ||
}); | ||
print(''); | ||
print('If no command is given, jasmine specs will be run'); | ||
print(wrap(terminalColumns, 'If no command is given, Jasmine specs will be run.')); | ||
print(''); | ||
@@ -309,18 +317,68 @@ print(''); | ||
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)); | ||
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\tstop 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)); | ||
const options = [ | ||
{ syntax: '--parallel=N', help: 'Run in parallel with N workers' }, | ||
{ syntax: '--parallel=auto', help: 'Run in parallel with an automatically chosen number of workers' }, | ||
{ syntax: '--no-color', help: 'turn off color in spec output' }, | ||
{ syntax: '--color', help: 'force turn on color in spec output' }, | ||
{ syntax: '--filter=', help: 'filter specs to run only those that match the given string' }, | ||
{ syntax: '--helper=', help: 'load helper files that match the given string' }, | ||
{ syntax: '--require=', help: 'load module that matches the given string' }, | ||
{ syntax: '--fail-fast', help: 'stop Jasmine execution on spec failure' }, | ||
{ syntax: '--config=', help: 'path to the Jasmine configuration file' }, | ||
{ syntax: '--reporter=', help: 'path to reporter to use instead of the default Jasmine reporter' }, | ||
{ syntax: '--verbose', help: 'print information that may be useful for debugging configuration' }, | ||
{ syntax: '--', help: 'marker to signal the end of options meant for Jasmine' }, | ||
]; | ||
for (const o of options) { | ||
print(wrapWithIndent(terminalColumns, lPad(o.syntax, 18) + ' ', o.help)); | ||
} | ||
print(''); | ||
print('The given arguments take precedence over options in your jasmine.json'); | ||
print('The path to your optional jasmine.json can also be configured by setting the JASMINE_CONFIG_PATH environment variable'); | ||
print(wrap(terminalColumns, | ||
'The given arguments take precedence over options in your jasmine.json.')); | ||
print(wrap(terminalColumns, | ||
'The path to your optional jasmine.json can also be configured by setting the JASMINE_CONFIG_PATH environment variable.')); | ||
} | ||
function wrapWithIndent(cols, prefix, suffix) { | ||
const lines = wrap2(cols - prefix.length, suffix); | ||
const indent = lPad('', prefix.length); | ||
return prefix + lines.join('\n' + indent); | ||
} | ||
function wrap(cols, input) { | ||
return wrap2(cols, input).join('\n'); | ||
} | ||
function wrap2(cols, input) { | ||
let lines = []; | ||
let start = 0; | ||
while (start < input.length) { | ||
const splitAt = indexOfLastSpaceInRange(start, start + cols, input); | ||
if (splitAt === -1 || input.length - start <= cols) { | ||
lines.push(input.substring(start)); | ||
break; | ||
} else { | ||
lines.push(input.substring(start, splitAt)); | ||
start = splitAt + 1; | ||
} | ||
} | ||
return lines; | ||
} | ||
function indexOfLastSpaceInRange(start, end, s) { | ||
for (let i = end; i >= start; i--) { | ||
if (s[i] === ' ') { | ||
return i; | ||
} | ||
} | ||
return -1; | ||
} | ||
function version(options) { | ||
@@ -327,0 +385,0 @@ const print = options.print; |
@@ -208,2 +208,6 @@ const ExitHandler = require('./exit_handler'); | ||
if (files && files.length > 0) { | ||
if (this.isVerbose_) { | ||
console.log('Overriding previous specDir and specFiles because a list of spec files was provided on the command line or as an argument to Jasmine#execute'); | ||
} | ||
this.specDir = ''; | ||
@@ -210,0 +214,0 @@ this.specFiles = []; |
@@ -123,2 +123,5 @@ const path = require('path'); | ||
async execute(files, filterString) { | ||
if (this.isVerbose_) { | ||
console.log(`Running in parallel with ${this.numWorkers_} workers`); | ||
} | ||
if (this.startedExecuting_) { | ||
@@ -152,2 +155,6 @@ throw new Error('Parallel runner instance can only be executed once'); | ||
if (files && files.length > 0) { | ||
if (this.isVerbose_) { | ||
console.log('Overriding previous specDir and specFiles because a list of spec files was provided on the command line or as an argument to ParallelRunner#execute'); | ||
} | ||
this.specDir = ''; | ||
@@ -326,2 +333,8 @@ this.specFiles = []; | ||
case 'specFileLoadError': | ||
this.addTopLevelError_('load', | ||
`Error loading ${msg.filePath}`, msg.error); | ||
runNextSpecFile(); | ||
break; | ||
case 'uncaughtException': | ||
@@ -437,3 +450,3 @@ this.addTopLevelError_('lateError', | ||
addTopLevelError_(type, msgPrefix, serializedError) { | ||
addTopLevelError_(globalErrorType, msgPrefix, serializedError) { | ||
// Match how jasmine-core reports these in non-parallel situations | ||
@@ -443,3 +456,3 @@ this.executionState_.failedExpectations.push({ | ||
expected: '', | ||
globalErrorType: 'lateError', | ||
globalErrorType, | ||
matcherName: '', | ||
@@ -446,0 +459,0 @@ message: `${msgPrefix}: ${serializedError.message}`, |
@@ -29,12 +29,10 @@ const ConsoleSpecFilter = require("./filters/console_spec_filter"); | ||
options.process.on(errorType, error => { | ||
if (this.clusterWorker_.isConnected()) { | ||
this.clusterWorker_.send({ | ||
type: errorType, | ||
error: serializeError(error) | ||
}); | ||
} else { | ||
// Don't try to report errors after disconnect. If we do, it'll cause | ||
// another unhandled exception. The resulting error-and-reporting loop | ||
// can keep the runner from finishing. | ||
console.error(`${errorType} in Jasmine worker process after disconnect:`, error); | ||
const sent = sendIfConnected(this.clusterWorker_, { | ||
type: errorType, | ||
error: serializeError(error) | ||
}); | ||
if (!sent) { | ||
console.error(`${errorType} in Jasmine worker process after disconnect:`, | ||
error); | ||
console.error('This error cannot be reported properly because it ' + | ||
@@ -116,3 +114,4 @@ 'happened after the worker process was disconnected.' | ||
this.clusterWorker_.send({ | ||
type: 'fatalError', | ||
type: 'specFileLoadError', | ||
filePath: specFilePath, | ||
error: serializeError(error) | ||
@@ -126,5 +125,2 @@ }); | ||
if (!this.clusterWorker_.isConnected()) { | ||
console.error( | ||
'Jasmine worker not sending specFileDone message after disconnect' | ||
); | ||
return; | ||
@@ -158,11 +154,3 @@ } | ||
reporter[eventName] = function (payload) { | ||
if (!clusterWorker.isConnected()) { | ||
console.error( | ||
`Jasmine worker not sending ${eventName} reporter event ` + | ||
'after disconnect' | ||
); | ||
return; | ||
} | ||
clusterWorker.send({ | ||
sendIfConnected(clusterWorker, { | ||
type: 'reporterEvent', | ||
@@ -183,2 +171,20 @@ eventName, | ||
function sendIfConnected(clusterWorker, msg) { | ||
if (clusterWorker.isConnected()) { | ||
try { | ||
clusterWorker.send(msg); | ||
return true; | ||
} catch (e) { | ||
// EPIPE may be thrown if the worker receives a disconnect between | ||
// the calls to isConnected() and send() above. | ||
if (e.code !== 'EPIPE') { | ||
throw e; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
module.exports = ParallelWorker; |
@@ -58,2 +58,13 @@ const path = require('path'); | ||
/** | ||
* Sets whether to run in verbose mode, which prints information that may | ||
* be useful for debugging configuration problems. | ||
* @function | ||
* @name Runner#verbose | ||
* @param {boolean} value Whether to run in verbose mode | ||
*/ | ||
verbose(isVerbose) { | ||
this.isVerbose_ = isVerbose; | ||
} | ||
/** | ||
* Sets whether the console reporter should list pending specs even when there | ||
@@ -71,4 +82,8 @@ * are failures. | ||
* 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 | ||
* any JS file that's loadable as a module and provides a Jasmine config | ||
* as its default export. | ||
* | ||
* The config file will be loaded via dynamic import() unless this Jasmine | ||
* instance has already been configured with {jsLoader: 'require'}. Dynamic | ||
* import() supports ES modules as well as nearly all CommonJS modules. | ||
* @name Runner#loadConfigFile | ||
@@ -80,3 +95,10 @@ * @function | ||
async loadConfigFile(configFilePath) { | ||
if (this.isVerbose_) { | ||
console.log(`Project base dir: ${this.projectBaseDir}`); | ||
} | ||
if (configFilePath) { | ||
if (this.isVerbose_) { | ||
console.log(`Loading config file ${configFilePath} because it was explicitly specified`); | ||
} | ||
await this.loadSpecificConfigFile_(configFilePath); | ||
@@ -87,4 +109,6 @@ } else { | ||
for (const ext of ['json', 'js']) { | ||
const candidate = `spec/support/jasmine.${ext}`; | ||
try { | ||
await this.loadSpecificConfigFile_(`spec/support/jasmine.${ext}`); | ||
await this.loadSpecificConfigFile_(candidate); | ||
numFound++; | ||
@@ -97,2 +121,6 @@ } catch (e) { | ||
} | ||
if (this.isVerbose_) { | ||
console.log(`Tried to load config file ${candidate} but it does not exist (${e.code})`); | ||
} | ||
} | ||
@@ -108,2 +136,4 @@ } | ||
); | ||
} else if (numFound === 0 && this.isVerbose_) { | ||
console.log('Did not find any config files.'); | ||
} | ||
@@ -116,2 +146,5 @@ } | ||
const config = await this.loader.load(absolutePath); | ||
if (this.isVerbose_) { | ||
console.log(`Loaded config file ${absolutePath}`); | ||
} | ||
this.loadConfig(config); | ||
@@ -516,2 +549,7 @@ } | ||
}); | ||
if (this.isVerbose_) { | ||
console.log(`File glob for ${kind}: ${files}`); | ||
console.log(`Resulting ${kind}: [${fileArr}]`); | ||
} | ||
}; | ||
@@ -518,0 +556,0 @@ } |
@@ -13,3 +13,3 @@ { | ||
"license": "MIT", | ||
"version": "5.1.0", | ||
"version": "5.2.0", | ||
"repository": { | ||
@@ -30,3 +30,3 @@ "type": "git", | ||
"lib", | ||
"MIT.LICENSE", | ||
"LICENSE", | ||
"package.json", | ||
@@ -37,3 +37,3 @@ "README.md" | ||
"glob": "^10.2.2", | ||
"jasmine-core": "~5.1.0" | ||
"jasmine-core": "~5.2.0" | ||
}, | ||
@@ -46,29 +46,3 @@ "bin": "./bin/jasmine.js", | ||
"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,7 +0,4 @@ | ||
[![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 Package | ||
# The Jasmine Module | ||
The `jasmine` module is a command line interface and supporting code for running | ||
The `jasmine` package is a command line interface and supporting code for running | ||
[Jasmine](https://github.com/jasmine/jasmine) specs under Node. | ||
@@ -13,3 +10,3 @@ | ||
This module allows you to run Jasmine specs for your Node.js code. The output will be displayed in your terminal by default. | ||
This package allows you to run Jasmine specs for your Node.js code. The output will be displayed in your terminal by default. | ||
@@ -54,3 +51,3 @@ ## Documentation | ||
Jasmine supports Node 18 and 20. | ||
Jasmine supports Node 18, 20, and 22. | ||
@@ -60,11 +57,10 @@ ## Support | ||
Documentation: [jasmine.github.io](https://jasmine.github.io) | ||
Jasmine Mailing list: [jasmine-js@googlegroups.com](mailto:jasmine-js@googlegroups.com) | ||
Twitter: [@jasminebdd](http://twitter.com/jasminebdd) | ||
Please file issues here at GitHub. | ||
Please file issues here at Github | ||
Copyright (c) 2014-2019 Pivotal Labs | ||
Copyright (c) 2014-2023 The Jasmine developers | ||
This software is licensed under the MIT License. | ||
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) |
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
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
78927
2206
64
+ Addedjasmine-core@5.2.0(transitive)
- Removedjasmine-core@5.1.2(transitive)
Updatedjasmine-core@~5.2.0