Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

karma

Package Overview
Dependencies
Maintainers
5
Versions
213
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

karma - npm Package Compare versions

Comparing version 6.2.0 to 6.3.0

64

lib/cli.js

@@ -10,2 +10,3 @@ 'use strict'

const constant = require('./constants')
const cfg = require('./config')

@@ -281,23 +282,46 @@ function processArgs (argv, options, fs, path) {

exports.run = () => {
const config = exports.process()
exports.run = async () => {
const cliOptions = exports.process()
const cmd = cliOptions.cmd // prevent config from changing the command
const cmdNeedsConfig = cmd === 'start' || cmd === 'run' || cmd === 'stop'
if (cmdNeedsConfig) {
let config
try {
config = await cfg.parseConfig(
cliOptions.configFile,
cliOptions,
{
promiseConfig: true,
throwErrors: true
}
)
} catch (karmaConfigException) {
// The reject reason/exception isn't used to log a message since
// parseConfig already calls a configured logger method with an almost
// identical message.
switch (config.cmd) {
case 'start':
new Server(config).start()
break
case 'run':
require('./runner')
.run(config)
.on('progress', printRunnerProgress)
break
case 'stop':
require('./stopper').stop(config)
break
case 'init':
require('./init').init(config)
break
case 'completion':
require('./completion').completion(config)
break
// The `run` function is a private application, not a public API. We don't
// need to worry about process.exit vs throw vs promise rejection here.
process.exit(1)
}
switch (cmd) {
case 'start': {
const server = new Server(config)
await server.start()
return server
}
case 'run':
return require('./runner')
.run(config)
.on('progress', printRunnerProgress)
case 'stop':
return require('./stopper').stop(config)
}
} else {
switch (cmd) {
case 'init':
return require('./init').init(cliOptions)
case 'completion':
return require('./completion').completion(cliOptions)
}
}

@@ -304,0 +328,0 @@ }

@@ -271,2 +271,5 @@ 'use strict'

/**
* @class
*/
class Config {

@@ -355,8 +358,57 @@ constructor () {

/**
* Retrieve a parsed and finalized Karma `Config` instance. This `karmaConfig`
* object may be used to configure public API methods such a `Server`,
* `runner.run`, and `stopper.stop`.
*
* @param {?string} [configFilePath=null]
* A string representing a file system path pointing to the config file
* whose default export is a function that will be used to set Karma
* configuration options. This function will be passed an instance of the
* `Config` class as its first argument. If this option is not provided,
* then only the options provided by the `cliOptions` argument will be
* set.
* @param {Object} cliOptions
* An object whose values will take priority over options set in the
* config file. The config object passed to function exported by the
* config file will already have these options applied. Any changes the
* config file makes to these options will effectively be ignored in the
* final configuration.
*
* `cliOptions` all the same options as the config file and is applied
* using the same `config.set()` method.
* @param {Object} parseOptions
* @param {boolean} [parseOptions.promiseConfig=false]
* When `true`, a promise that resolves to a `Config` object will be
* returned. This also allows the function exported by config files (if
* provided) to be asynchronous by returning a promise. Resolving this
* promise indicates that all async activity has completed. The resolution
* value itself is ignored, all configuration must be done with
* `config.set`.
* @param {boolean} [parseOptions.throwErrors=false]
* When `true`, process exiting on critical failures will be disabled. In
* The error will be thrown as an exception. If
* `parseOptions.promiseConfig` is also `true`, then the error will
* instead be used as the promise's reject reason.
* @returns {Config|Promise<Config>}
*/
function parseConfig (configFilePath, cliOptions, parseOptions) {
const promiseConfig = parseOptions && parseOptions.promiseConfig === true
const throwErrors = parseOptions && parseOptions.throwErrors === true
const shouldSetupLoggerEarly = promiseConfig
if (shouldSetupLoggerEarly) {
// `setupFromConfig` provides defaults for `colors` and `logLevel`.
// `setup` provides defaults for `appenders`
// The first argument MUST BE an object
logger.setupFromConfig({})
}
function fail () {
log.error(...arguments)
if (parseOptions && parseOptions.throwErrors === true) {
if (throwErrors) {
const errorMessage = Array.from(arguments).join(' ')
throw new Error(errorMessage)
const err = new Error(errorMessage)
if (promiseConfig) {
return Promise.reject(err)
}
throw err
} else {

@@ -416,30 +468,72 @@ const warningMessage =

let configModuleReturn
try {
configModule(config)
configModuleReturn = configModule(config)
} catch (e) {
return fail('Error in config file!\n', e)
}
function finalizeConfig (config) {
// merge the config from config file and cliOptions (precedence)
config.set(cliOptions)
// merge the config from config file and cliOptions (precedence)
config.set(cliOptions)
// if the user changed listenAddress, but didn't set a hostname, warn them
if (config.hostname === null && config.listenAddress !== null) {
log.warn(`ListenAddress was set to ${config.listenAddress} but hostname was left as the default: ` +
// if the user changed listenAddress, but didn't set a hostname, warn them
if (config.hostname === null && config.listenAddress !== null) {
log.warn(`ListenAddress was set to ${config.listenAddress} but hostname was left as the default: ` +
`${defaultHostname}. If your browsers fail to connect, consider changing the hostname option.`)
}
// restore values that weren't overwritten by the user
if (config.hostname === null) {
config.hostname = defaultHostname
}
if (config.listenAddress === null) {
config.listenAddress = defaultListenAddress
}
}
// restore values that weren't overwritten by the user
if (config.hostname === null) {
config.hostname = defaultHostname
}
if (config.listenAddress === null) {
config.listenAddress = defaultListenAddress
}
// configure the logger as soon as we can
logger.setup(config.logLevel, config.colors, config.loggers)
// configure the logger as soon as we can
logger.setup(config.logLevel, config.colors, config.loggers)
log.debug(configFilePath ? `Loading config ${configFilePath}` : 'No config file specified.')
log.debug(configFilePath ? `Loading config ${configFilePath}` : 'No config file specified.')
return normalizeConfig(config, configFilePath)
return normalizeConfig(config, configFilePath)
}
/**
* Return value is a function or (non-null) object that has a `then` method.
*
* @type {boolean}
* @see {@link https://promisesaplus.com/}
*/
const returnIsThenable = (
(
(configModuleReturn != null && typeof configModuleReturn === 'object') ||
typeof configModuleReturn === 'function'
) && typeof configModuleReturn.then === 'function'
)
if (returnIsThenable) {
if (promiseConfig !== true) {
const errorMessage =
'The `parseOptions.promiseConfig` option must be set to `true` to ' +
'enable promise return values from configuration files. ' +
'Example: `parseConfig(path, cliOptions, { promiseConfig: true })`'
return fail(errorMessage)
}
return configModuleReturn.then(
function onKarmaConfigModuleFulfilled (/* ignoredResolutionValue */) {
return finalizeConfig(config)
},
function onKarmaConfigModuleRejected (reason) {
return fail('Error in config file!\n', reason)
}
)
} else {
if (promiseConfig) {
try {
return Promise.resolve(finalizeConfig(config))
} catch (exception) {
return Promise.reject(exception)
}
} else {
return finalizeConfig(config)
}
}
}

@@ -446,0 +540,0 @@

@@ -35,10 +35,35 @@ 'use strict'

// TODO(vojta): read config file (port, host, urlRoot)
function run (config, done) {
config = config || {}
logger.setupFromConfig(config)
function run (cliOptionsOrConfig, done) {
cliOptionsOrConfig = cliOptionsOrConfig || {}
done = helper.isFunction(done) ? done : process.exit
config = cfg.parseConfig(config.configFile, config)
let config
if (cliOptionsOrConfig instanceof cfg.Config) {
config = cliOptionsOrConfig
} else {
logger.setupFromConfig({
colors: cliOptionsOrConfig.colors,
logLevel: cliOptionsOrConfig.logLevel
})
const deprecatedCliOptionsMessage =
'Passing raw CLI options to `runner(config, done)` is deprecated. Use ' +
'`parseConfig(configFilePath, cliOptions, {promiseConfig: true, throwErrors: true})` ' +
'to prepare a processed `Config` instance and pass that as the ' +
'`config` argument instead.'
log.warn(deprecatedCliOptionsMessage)
try {
config = cfg.parseConfig(
cliOptionsOrConfig.configFile,
cliOptionsOrConfig,
{
promiseConfig: false,
throwErrors: true
}
)
} catch (parseConfigError) {
// TODO: change how `done` falls back to exit in next major version
// SEE: https://github.com/karma-runner/karma/pull/3635#discussion_r565399378
done(1)
}
}
let exitCode = 1

@@ -45,0 +70,0 @@ const emitter = new EventEmitter()

@@ -58,18 +58,39 @@ 'use strict'

class Server extends KarmaEventEmitter {
constructor (cliOptions, done) {
constructor (cliOptionsOrConfig, done) {
super()
logger.setupFromConfig(cliOptions)
cliOptionsOrConfig = cliOptionsOrConfig || {}
this.log = logger.create('karma-server')
done = helper.isFunction(done) ? done : process.exit
this.loadErrors = []
let config
try {
config = cfg.parseConfig(cliOptions.configFile, cliOptions, { throwErrors: true })
} catch (parseConfigError) {
// TODO: change how `done` falls back to exit in next major version
// SEE: https://github.com/karma-runner/karma/pull/3635#discussion_r565399378
(done || process.exit)(1)
return
if (cliOptionsOrConfig instanceof cfg.Config) {
config = cliOptionsOrConfig
} else {
logger.setupFromConfig({
colors: cliOptionsOrConfig.colors,
logLevel: cliOptionsOrConfig.logLevel
})
const deprecatedCliOptionsMessage =
'Passing raw CLI options to `new Server(config, done)` is ' +
'deprecated. Use ' +
'`parseConfig(configFilePath, cliOptions, {promiseConfig: true, throwErrors: true})` ' +
'to prepare a processed `Config` instance and pass that as the ' +
'`config` argument instead.'
this.log.warn(deprecatedCliOptionsMessage)
try {
config = cfg.parseConfig(
cliOptionsOrConfig.configFile,
cliOptionsOrConfig,
{
promiseConfig: false,
throwErrors: true
}
)
} catch (parseConfigError) {
// TODO: change how `done` falls back to exit in next major version
// SEE: https://github.com/karma-runner/karma/pull/3635#discussion_r565399378
done(1)
return
}
}

@@ -76,0 +97,0 @@

@@ -6,9 +6,37 @@ const http = require('http')

exports.stop = function (config, done) {
config = config || {}
logger.setupFromConfig(config)
exports.stop = function (cliOptionsOrConfig, done) {
cliOptionsOrConfig = cliOptionsOrConfig || {}
const log = logger.create('stopper')
done = helper.isFunction(done) ? done : process.exit
config = cfg.parseConfig(config.configFile, config)
let config
if (cliOptionsOrConfig instanceof cfg.Config) {
config = cliOptionsOrConfig
} else {
logger.setupFromConfig({
colors: cliOptionsOrConfig.colors,
logLevel: cliOptionsOrConfig.logLevel
})
const deprecatedCliOptionsMessage =
'Passing raw CLI options to `stopper(config, done)` is deprecated. Use ' +
'`parseConfig(configFilePath, cliOptions, {promiseConfig: true, throwErrors: true})` ' +
'to prepare a processed `Config` instance and pass that as the ' +
'`config` argument instead.'
log.warn(deprecatedCliOptionsMessage)
try {
config = cfg.parseConfig(
cliOptionsOrConfig.configFile,
cliOptionsOrConfig,
{
promiseConfig: false,
throwErrors: true
}
)
} catch (parseConfigError) {
// TODO: change how `done` falls back to exit in next major version
// SEE: https://github.com/karma-runner/karma/pull/3635#discussion_r565399378
done(1)
}
}
const request = http.request({

@@ -15,0 +43,0 @@ hostname: config.hostname,

@@ -297,2 +297,3 @@ {

"Nick Payne <nick@kurai.co.uk>",
"Nick Petruzzelli <code.npetruzzelli@gmail.com>",
"Nick Petruzzelli <npetruzzelli@users.noreply.github.com>",

@@ -493,3 +494,3 @@ "Nick Williams <mr.nicksta@gmail.com>",

},
"version": "6.2.0",
"version": "6.3.0",
"license": "MIT",

@@ -496,0 +497,0 @@ "husky": {

Sorry, the diff of this file is too big to display

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