Comparing version 0.4.0-alpha26 to 0.4.0-alpha27
@@ -53,3 +53,3 @@ "use strict"; | ||
preserveOutput: process.env.CI ? 'failures-only' : 'always', | ||
reporter: [defaultReporter], | ||
reporter: [[defaultReporter]], | ||
timeout: defaultTimeout, | ||
@@ -152,5 +152,3 @@ updateSnapshots: process.env.CI ? 'none' : 'missing', | ||
retries: options.retries ? parseInt(options.retries, 10) : undefined, | ||
reporter: (options.reporter && options.reporter.length) ? options.reporter.split(',').map(r => { | ||
return builtinReporters.includes(r) ? r : { require: r }; | ||
}) : undefined, | ||
reporter: (options.reporter && options.reporter.length) ? options.reporter.split(',').map(r => [r]) : undefined, | ||
shard: shardPair ? { current: shardPair[0] - 1, total: shardPair[1] } : undefined, | ||
@@ -157,0 +155,0 @@ timeout: isDebuggerAttached ? 0 : (options.timeout ? parseInt(options.timeout, 10) : undefined), |
@@ -132,2 +132,3 @@ "use strict"; | ||
worker.once('done', (params) => { | ||
var _a, _b; | ||
// We won't file remaining if: | ||
@@ -151,3 +152,3 @@ // - there are no remaining | ||
const { test, result } = this._testById.get(testId); | ||
this._reporter.onTestBegin(test); | ||
(_b = (_a = this._reporter).onTestBegin) === null || _b === void 0 ? void 0 : _b.call(_a, test); | ||
result.error = params.fatalError; | ||
@@ -154,0 +155,0 @@ this._reportTestEnd(test, result, 'failed'); |
@@ -20,2 +20,3 @@ /** | ||
import { ProjectImpl } from './project'; | ||
import { Reporter } from './reporter'; | ||
export declare class Loader { | ||
@@ -36,2 +37,3 @@ private _defaultConfig; | ||
loadGlobalHook(file: string, name: string): (config: FullConfig) => any; | ||
loadReporter(file: string): new (arg?: any) => Reporter; | ||
fullConfig(): FullConfig; | ||
@@ -38,0 +40,0 @@ projects(): ProjectImpl[]; |
@@ -149,2 +149,20 @@ "use strict"; | ||
} | ||
loadReporter(file) { | ||
const revertBabelRequire = transform_1.installTransform(); | ||
try { | ||
let func = require(path.resolve(this._fullConfig.rootDir, file)); | ||
if (func && typeof func === 'object' && ('default' in func)) | ||
func = func['default']; | ||
if (typeof func !== 'function') | ||
throw util_1.errorWithCallLocation(`Reporter file "${file}" must export a single class.`); | ||
return func; | ||
} | ||
catch (e) { | ||
util_1.prependErrorMessage(e, `Error while reading ${file}:\n`); | ||
throw e; | ||
} | ||
finally { | ||
revertBabelRequire(); | ||
} | ||
} | ||
fullConfig() { | ||
@@ -196,5 +214,5 @@ return this._fullConfig; | ||
return; | ||
if (Array.isArray(reporters)) | ||
return reporters; | ||
return [reporters]; | ||
if (typeof reporters === 'string') | ||
return [[reporters]]; | ||
return reporters; | ||
} | ||
@@ -254,7 +272,10 @@ function validateConfig(config) { | ||
config.reporter.forEach((item, index) => { | ||
validateReporter(item, `config.reporter[${index}]`); | ||
if (!Array.isArray(item) || item.length <= 0 || item.length > 2 || typeof item[0] !== 'string') | ||
throw new Error(`config.reporter[${index}] must be a tuple [name, optionalArgument]`); | ||
}); | ||
} | ||
else { | ||
validateReporter(config.reporter, `config.reporter`); | ||
const builtinReporters = ['dot', 'line', 'list', 'junit', 'json', 'null']; | ||
if (typeof config.reporter !== 'string' || !builtinReporters.includes(config.reporter)) | ||
throw new Error(`config.reporter must be one of ${builtinReporters.map(name => `"${name}"`).join(', ')}`); | ||
} | ||
@@ -341,20 +362,2 @@ } | ||
} | ||
function validateReporter(reporter, title) { | ||
const builtinReporters = ['dot', 'line', 'list', 'junit', 'json', 'null']; | ||
if (typeof reporter === 'string') { | ||
if (!builtinReporters.includes(reporter)) | ||
throw new Error(`${title} must be one of ${builtinReporters.map(name => `"${name}"`).join(', ')}`); | ||
} | ||
else if (!reporter || typeof reporter !== 'object') { | ||
throw new Error(`${title} must be a string or an object`); | ||
} | ||
else if ('require' in reporter) { | ||
if (typeof reporter.require !== 'string') | ||
throw new Error(`${title}.require must be a string`); | ||
} | ||
else { | ||
if (!('name' in reporter) || typeof reporter.name !== 'string' || !builtinReporters.includes(reporter.name)) | ||
throw new Error(`${title}.name must be one of ${builtinReporters.map(name => `"${name}"`).join(', ')}`); | ||
} | ||
} | ||
const baseFullConfig = { | ||
@@ -369,3 +372,3 @@ forbidOnly: false, | ||
projects: [], | ||
reporter: ['list'], | ||
reporter: [['list']], | ||
rootDir: path.resolve(process.cwd()), | ||
@@ -372,0 +375,0 @@ quiet: false, |
@@ -77,14 +77,9 @@ "use strict"; | ||
for (const r of this._loader.fullConfig().reporter) { | ||
if (typeof r === 'string' && r in defaultReporters) { | ||
reporters.push(new defaultReporters[r]()); | ||
const [name, arg] = r; | ||
if (name in defaultReporters) { | ||
reporters.push(new defaultReporters[name](arg)); | ||
} | ||
else if (typeof r === 'object' && 'name' in r && r.name in defaultReporters) { | ||
reporters.push(new defaultReporters[r.name](r)); | ||
} | ||
else if (typeof r === 'object' && 'require' in r) { | ||
const p = path.resolve(process.cwd(), r.require); | ||
reporters.push(new (require(p).default)(r)); | ||
} | ||
else { | ||
throw new Error(`Unsupported reporter "${r}"`); | ||
const reporterConstructor = this._loader.loadReporter(name); | ||
reporters.push(new reporterConstructor(arg)); | ||
} | ||
@@ -201,3 +196,7 @@ } | ||
const sigintHandler = () => { | ||
process.off('SIGINT', sigintHandler); | ||
// We remove handler so that double Ctrl+C immediately kills the runner, | ||
// for the case where our shutdown takes a lot of time or is buggy. | ||
// Removing the handler synchronously sometimes triggers the default handler | ||
// that exits the process, so we remove asynchronously. | ||
setTimeout(() => process.off('SIGINT', sigintHandler), 0); | ||
sigint = true; | ||
@@ -204,0 +203,0 @@ sigintCallback(); |
@@ -18,20 +18,22 @@ /** | ||
import type { Expect } from './expectType'; | ||
export declare type ReporterDescription = 'dot' | { | ||
name: 'dot'; | ||
} | 'line' | { | ||
name: 'line'; | ||
} | 'list' | { | ||
name: 'list'; | ||
} | 'junit' | { | ||
name: 'junit'; | ||
export declare type ReporterDescription = [ | ||
'dot' | ||
] | [ | ||
'line' | ||
] | [ | ||
'list' | ||
] | [ | ||
'junit' | ||
] | ['junit', { | ||
outputFile?: string; | ||
stripANSIControlSequences?: boolean; | ||
} | 'json' | { | ||
name: 'json'; | ||
}] | [ | ||
'json' | ||
] | ['json', { | ||
outputFile?: string; | ||
} | 'null' | { | ||
name: 'null'; | ||
} | { | ||
require: string; | ||
}; | ||
}] | [ | ||
'null' | ||
] | [ | ||
string | ||
] | [string, any]; | ||
export declare type Shard = { | ||
@@ -156,3 +158,3 @@ total: number; | ||
*/ | ||
reporter?: ReporterDescription | ReporterDescription[]; | ||
reporter?: 'dot' | 'line' | 'list' | 'junit' | 'json' | 'null' | ReporterDescription[]; | ||
/** | ||
@@ -159,0 +161,0 @@ * Whether to suppress stdio output from the tests. |
{ | ||
"name": "folio", | ||
"version": "0.4.0-alpha26", | ||
"version": "0.4.0-alpha27", | ||
"bin": { | ||
@@ -5,0 +5,0 @@ "folio": "./cli.js" |
@@ -473,3 +473,6 @@ # Folio ![npm](https://img.shields.io/npm/v/folio) | ||
// Use very concise "dot" reporter plus a comprehensive json report. | ||
: ['dot', { name: 'json', outputFile: 'test-results.json' }], | ||
: [ | ||
['dot'], | ||
[ 'json', { outputFile: 'test-results.json' }] | ||
], | ||
}; | ||
@@ -571,3 +574,3 @@ | ||
const config = { | ||
reporter: { name: 'json', outputFile: 'results.json' }, | ||
reporter: [ ['json', { outputFile: 'results.json' }] ], | ||
}; | ||
@@ -590,3 +593,3 @@ export default config; | ||
const config = { | ||
reporter: { name: 'junit', outputFile: 'results.xml' }, | ||
reporter: [ ['junit', { outputFile: 'results.xml' }] ], | ||
}; | ||
@@ -593,0 +596,0 @@ export default config; |
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
355417
7892
965