UNPKG

mocha-badge-generator

Version:

Mocha reporter which outputs badge with the number of tests passed and failed.

159 lines (147 loc) 5.4 kB
'use strict'; const fs = require('fs'); const {resolve: pathResolve} = require('path'); const badge = require('@rpl/badge-up').v2; const es6Template = require('es6-template-strings'); const fastGlob = require('fast-glob'); async function makeBadge ({ passes, failures, duration, speeds, options }) { const { badge_subject, badge_ok_color, badge_ko_color, badge_format, badge_output, badge_template, badge_threshold, badge_slow_threshold, badge_duration_threshold } = options || {}; const subject = badge_subject || process.env.MOCHA_BADGE_GEN_SUBJECT || 'Tests'; const okColor = badge_ok_color || process.env.MOCHA_BADGE_GEN_OK_COLOR || '44cc11'; // Bright green const koColor = badge_ko_color || process.env.MOCHA_BADGE_GEN_KO_COLOR || 'e05d44'; // Red const foutput = badge_output || process.env.MOCHA_BADGE_GEN_OUTPUT || './test/badge.svg'; const format = badge_format || process.env.MOCHA_BADGE_GEN_FORMAT || 'svg'; const textTemplate = badge_template || process.env.MOCHA_BADGE_GEN_TEMPLATE || '${passes}/${total}'; const failureThreshold = badge_threshold || process.env.MOCHA_BADGE_GEN_THRESHOLD || 0; const slowThreshold = badge_slow_threshold || process.env.MOCHA_BADGE_GEN_SLOW_THRESHOLD; const durationThreshold = badge_duration_threshold || process.env.MOCHA_BADGE_GEN_DURATION_THRESHOLD; const color = failures > failureThreshold || (durationThreshold && duration > durationThreshold) || (slowThreshold && speeds.slow > slowThreshold) ? koColor : okColor; const total = passes + failures; // Could use `badge.v2.sectionsToData` for more control; see `test` // in `@rpl/badge-up` const sections = [ subject, [es6Template(textTemplate, { passes, failures, total, duration, speeds }), ...color.split(',')] ]; let output = await badge(sections); if (format === 'png') { output = require('svg2png').sync(output); } return new Promise((resolve, reject) => { fs.writeFile(foutput, output, writeErr => { if (writeErr) { return reject(writeErr); } resolve({ output: foutput }); }); }); } exports.makeBadgeFromJSONFile = (options) => { if ( (!options.fileGlob || !options.fileGlob.length) && (!options.file || !options.file.length) ) { throw new TypeError('You must supply a `file` (or `fileGlob`) to `makeBadgeFromJSONFile`'); } const { // Use default from Mocha `Runnable` slow = 75 } = options; // Adapting algorithm from `mocha/lib/reporters/base.js`; would seem // inefficient to run a test with reporter to get at this info, // especially with a simple algorithm. function baseReporterPassSpeedCalculation (obj, duration, tests) { tests.forEach(({speed, duration, err}) => { // Mocha 8.2.0+ (should take into account `this.slow()` and // any changed `slow` value) if (speed !== undefined) { obj.speeds[speed]++; return; } // istanbul ignore else -- Test. env is Mocha >= 8.2.0 if (Object.keys(err).length) { return; } /* c8 ignore next 9 */ // Mocha < 8.2.0 // -- Test. env is Mocha >= 8.2.0 if (duration > slow) { obj.speeds.slow++; } else if (duration > slow / 2) { obj.speeds.medium++; } else { obj.speeds.fast++; } }); } // Throw early above return (async () => { if (options.fileGlob && options.fileGlob.length) { options.file = options.file || []; options.file.push(...await fastGlob(options.fileGlob)); } const { passes, failures, duration, speeds } = options.file.reduce((obj, file) => { const data = require(pathResolve(process.cwd(), file)); const { stats: {passes, failures, duration}, tests, results: mochawesomeTestResults } = data; obj.passes += passes; obj.failures += failures; obj.duration += duration; let testResults = tests || []; if (!tests && mochawesomeTestResults) { testResults = []; const flattenResults = (results) => { results.forEach((result) => { result.tests.forEach((test) => { testResults.push(test); }); flattenResults(result.suites); }); }; flattenResults(mochawesomeTestResults); } baseReporterPassSpeedCalculation(obj, duration, testResults); return obj; }, {passes: 0, failures: 0, duration: 0, speeds: { fast: 0, slow: 0, medium: 0 }}); return makeBadge({passes, failures, options, duration, speeds}); })(); }; exports.makeBadge = makeBadge;