All files / src/cli-validator/utils printResults.js

96.67% Statements 58/60
85.71% Branches 30/35
100% Functions 6/6
96.67% Lines 58/60

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 17212x 12x 12x     12x       12x                 31x     31x               31x                             31x   31x 121x 121x 49x       121x   121x 164x 45x     164x     420x 420x       420x   420x 274x     420x     420x 146x               420x       420x 420x 75x   420x 420x 420x 27x 27x       27x     27x   420x           31x             1x   1x     1x     1x         1x         1x   1x   4x 2x     4x 14x   10x 10x 10x         10x   10x   10x         4x 2x          
const each = require('lodash/each');
const pad = require('pad');
const getPathAsArray = require('./getPathAsArray');
 
// get line-number-producing, 'magic' code from Swagger Editor
const getLineNumberForPath = require(__dirname + '/../../plugins/ast/ast')
  .getLineNumberForPath;
 
// this function prints all of the output
module.exports = function print(
  results,
  chalk,
  printValidators,
  verbose,
  reportingStats,
  originalFile,
  errorsOnly
) {
  const types = errorsOnly
    ? ['errors']
    : ['errors', 'warnings', 'infos', 'hints'];
  const colors = {
    errors: 'bgRed',
    warnings: 'bgYellow',
    infos: 'bgGrey',
    hints: 'bgGreen'
  };
 
  // define an object template in the case that statistics reporting is turned on
  const stats = {
    errors: {
      total: 0
    },
    warnings: {
      total: 0
    },
    infos: {
      total: 0
    },
    hints: {
      total: 0
    }
  };
 
  console.log();
 
  types.forEach(type => {
    let color = colors[type];
    if (Object.keys(results[type]).length) {
      console.log(chalk[color].bold(`${type}\n`));
    }
 
    // convert 'color' from a background color to foreground color
    color = color.slice(2).toLowerCase(); // i.e. 'bgRed' -> 'red'
 
    each(results[type], (problems, validator) => {
      if (printValidators) {
        console.log(`Validator: ${validator}`);
      }
 
      problems.forEach(problem => {
        // To allow messages with fillins to be grouped properly in the statistics,
        // truncate the message at the first ':'
        const message = problem.message.split(':')[0];
        let path = problem.path;
 
        // collect info for stats reporting, if applicable
 
        stats[type].total += 1;
 
        if (!stats[type][message]) {
          stats[type][message] = 0;
        }
 
        stats[type][message] += 1;
 
        // path needs to be an array to get the line number
        if (!Array.isArray(path)) {
          path = path.split('.');
        }
 
        // get line number from the path of strings to the problem
        // as they say in src/plugins/validation/semantic-validators/hook.js,
        //
        //                  "it's magic!"
        //
        const lineNumber = getLineNumberForPath(originalFile, path);
 
        // print the path array as a dot-separated string
 
        console.log(chalk[color](`  Message :   ${problem.message}`));
        if (verbose && problem.rule) {
          console.log(chalk[color](`  Rule    :   ${problem.rule}`));
        }
        console.log(chalk[color](`  Path    :   ${path.join('.')}`));
        console.log(chalk[color](`  Line    :   ${lineNumber}`));
        if (verbose && problem.componentPath) {
          const componentPath = getPathAsArray(problem.componentPath);
          const componentLine = getLineNumberForPath(
            originalFile,
            componentPath
          );
          console.log(
            chalk[color](`  Component Path    :   ${componentPath.join('.')}`)
          );
          console.log(chalk[color](`  Component Line    :   ${componentLine}`));
        }
        console.log();
      });
    });
  });
 
  // print the stats here, if applicable
  if (
    reportingStats &&
    (stats.errors.total ||
      stats.warnings.total ||
      stats.infos.total ||
      stats.hints.total)
  ) {
    console.log(chalk.bgCyan('statistics\n'));
 
    console.log(
      chalk.cyan(`  Total number of errors   : ${stats.errors.total}`)
    );
    console.log(
      chalk.cyan(`  Total number of warnings : ${stats.warnings.total}`)
    );
    Iif (stats.infos.total > 0) {
      console.log(
        chalk.cyan(`  Total number of infos    : ${stats.infos.total}`)
      );
    }
    Iif (stats.hints.total > 0) {
      console.log(
        chalk.cyan(`  Total number of hints    : ${stats.hints.total}`)
      );
    }
    console.log('');
 
    types.forEach(type => {
      // print the type, either error or warning
      if (stats[type].total) {
        console.log('  ' + chalk.underline.cyan(type));
      }
 
      Object.keys(stats[type]).forEach(message => {
        if (message !== 'total') {
          // calculate percentage
          const number = stats[type][message];
          const total = stats[type].total;
          const percentage = Math.round((number / total) * 100).toString();
 
          // pad(<number>, <string>) right-aligns <string> to the <number>th column, padding with spaces.
          // use 4, two for the appended spaces of every line and two for the number
          //   (assuming errors/warnings won't go to triple digits)
          const numberString = pad(4, number.toString());
          // use 6 for largest case of '(100%)'
          const frequencyString = pad(6, `(${percentage}%)`);
 
          console.log(
            chalk.cyan(`${numberString} ${frequencyString} : ${message}`)
          );
        }
      });
      if (stats[type].total) {
        console.log();
      }
    });
  }
};