const NanoTime = require('./NanoTime.js');
/**
* @module pete/lib/createReport
*/
module.exports = createReport;
/**
* Pseudo hdr that returns `Infinity` for every percentile.
*
* @private
*/
const HDR2INFINITY = {percentile: () => Infinity};
/**
* Information about test run.
*
* `percentiles.p1` to `percentiles.p100` are optional, depending on `options.percentiles` passed to test function.
*
* @typedef {object} Report
* @alias module:pete/lib/createReport~Report
* @property {string} id Unique identifier of place from which test function was called
* @property {string} name Name of the test
* @property {string} mode For example: "skip", "todo", "warmup" or "regular"
* @property {string} type Type of runner used to call target function
* @property {NanoTime} limitCPUTime Maximum time target function can run
* @property {NanoTime} limitRealTime Maximum total real time test can run
* @property {number} limitSamples Maximum number of times target function should be run
* @property {string[]} args Arguments passed to target function
* @property {boolean} exitOnError Should test be cancelled after error
* @property {NanoTime} started
* @property {NanoTime} finished
* @property {NanoTime} totalCPUTime Sum of time it took to run target function
* @property {NanoTime} totalRealTime Time it took to run whole test
* @property {number} samples Number of times target function was run
* @property {number} min see {@link external:Histogram}
* @property {number} max see {@link external:Histogram}
* @property {number} mean see {@link external:Histogram}
* @property {number} stddev see {@link external:Histogram}
* @property {object} percentiles
* @property {number} [percentiles.p1] If test options contained percentile 1, p1 will contain its value
* @property {number} [percentiles.p100] If test options contained percentile 100, p100 will contain its value
* @property {Error} [error] If there was any, while running the test
*/
/**
* Creates report object from runner's options and state.
*
* @alias module:pete/lib/createReport
* @param {module:pete/lib/RunOptions} options
* @param {module:pete/lib/RunState} state
* @return {module:pete/lib/createReport~Report}
*/
function createReport (options, state) {
var result = {
id : options.id,
name : options.name,
mode : state.mode,
type : state.runType,
limitCPUTime : new NanoTime(options.limitCPUTime),
limitRealTime: new NanoTime(options.limitRealTime),
limitSamples : options.limitSamples,
args : options.args,
exitOnError : options.exitOnError,
started : new NanoTime(state.started),
finished : new NanoTime(state.finished),
totalCPUTime : new NanoTime(state.totalCPUTime),
totalRealTime: new NanoTime(state.finished - state.started),
samples : state.samplesCount,
min : nanToInfinity(state.hdr.min),
max : nanToInfinity(state.hdr.max),
mean : nanToInfinity(state.hdr.mean),
stddev : nanToInfinity(state.hdr.stddev),
percentiles : {},
error : state.error && state.error.toString()
};
if (result.max < result.min) {
result.max = Infinity;
}
var p = 0;
var value = 0;
var hdr = state.hdr || HDR2INFINITY;
for (var i = 0, max = options.percentiles.length; i < max; i++) {
p = options.percentiles[i];
value = hdr.percentile(p);
result.percentiles[`p${p}`] = value >= result.min ? value : Infinity;
}
return result;
}
/**
* Helper function to convert NaN to Infinity.
*
* @private
* @param {any} value
* @return {number}
*/
function nanToInfinity (value) {
return isNaN(value) ? Infinity : value;
}