const path = require('node:path');
const createReport = require('./createReport.js');
const include = require('./include.js');
const RunState = require('./RunState.js');
const callbackReporter = require('./reporters/callback.js');
/**
* @module pete/lib/runner
*/
/**
* Parse options from command line arguments and assign them to `options`.
* Parse `args` into `fn`, `options` and `name` - each of them optional.
*
* @param {string} id see {@link module:pete/lib/createId}
* @param {module:pete/lib/RunOptions} options target options object that will be changed
* @param {any[]} args arguments passed caller function
* @return {Function|undefined} if any was passed through the `args`
*/
module.exports.setOptions = function setOptions (id, options, args) {
var name;
var fn;
var cb;
var opts;
for (let i = 0, max = args.length; i < max; i++) {
if (typeof args[i] === 'function') {
if (fn) {
cb = args[i];
}
else {
fn = args[i];
}
}
else if (typeof args[i] === 'object') {
opts = args[i];
}
else if (typeof args[i] === 'string') {
name = args[i];
}
}
options.setFromOptions(opts);
options.setFromArgv();
options.id = id;
if (name && !fn) {
fn = name;
name = null;
}
if (!name && typeof fn === 'function') {
name = fn.name || id;
}
options.name = options.name || name;
if (cb) {
options.reporters.push(callbackReporter({out: cb}));
}
return fn;
};
/**
* Run and report.
*
* @typedef {Function} run
* @param {module:pete/lib/getReporters~report} report
*/
/**
* Create run function that will call `fn`, depending on passed options.
* `state` will be updated by the run function with benchmark scores.
*
* @param {Function|string} fn either a Function or a path to script
* @param {object} options
* @param {object} [state]
* @return {module:pete/lib/runner~startRun}
*/
module.exports.createRun = function createRun (fn, options, state) {
const maxHDRValue = Number(options.limitRealTime > options.limitCPUTime ? options.limitRealTime : options.limitCPUTime);
if (!state) {
state = new RunState(maxHDRValue);
}
const factory = include(`./runs/${path.basename(options.runType || 'auto')}`) || include(options.runType);
const run = factory(fn, options, state);
const runType = state.runType;
const error = state.error || (!options.limitCPUTime && !options.limitRealTime && new Error('At least one limit has to be set for Runner to start'));
/**
* Resets state, reports error if any.
* Starts running test function if there were no errors.
* Reports results after run is finished.
*
* @typedef {Function} startRun
* @param {string} mode
* @param {module:pete/lib/getReporters~report} report
*/
return function startRun (mode, report) {
state.reset();
state.mode = mode;
state.runType = state.runType || runType;
if (error) {
state.error = error;
report(error, createReport(options, state));
report();
return;
}
run(report);
};
};