Skip to content

Commit

Permalink
feat: Added -j/--json output option to cli-validator
Browse files Browse the repository at this point in the history
This revision adds a new --json option to the cli-validator that prints the internal
result data in json format to stdout.  It does additionally include the line number
as a 'line' field in the JSON (this is not in the internal json data).  Automated
test validates that json is received.

Closes #43
  • Loading branch information
aspear committed May 30, 2019
1 parent 8152d06 commit 759856f
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 6 deletions.
4 changes: 4 additions & 0 deletions src/cli-validator/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ program
'-n, --no_colors',
'turn off output coloring'
)
.option(
'-j, --json',
'output as json'
)
.option(
'-d, --default_mode',
'ignore config file and run in default mode'
Expand Down
18 changes: 12 additions & 6 deletions src/cli-validator/runValidator.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const config = require('./utils/processConfiguration');
const buildSwaggerObject = require('./utils/buildSwaggerObject');
const validator = require('./utils/validator');
const print = require('./utils/printResults');
const printJson = require('./utils/printJsonResults');
const printError = require('./utils/printError');
const preprocessFile = require('./utils/preprocessFile');

Expand All @@ -35,6 +36,7 @@ const processInput = async function(program) {

const turnOffColoring = !!program.no_colors;
const defaultMode = !!program.default_mode;
const jsonOutput = !!program.json;

// turn on coloring by default
const colors = turnOffColoring ? false : true;
Expand Down Expand Up @@ -217,13 +219,17 @@ const processInput = async function(program) {
continue;
}

if (results.error || results.warning) {
print(results, chalk, printValidators, reportingStats, originalFile);
// fail on errors, but not if there are only warnings
if (results.error) exitCode = 1;
if (jsonOutput) {
printJson(results, originalFile);
} else {
console.log(chalk.green(`\n${validFile} passed the validator`));
if (validFile === last(filesToValidate)) console.log();
if (results.error || results.warning) {
print(results, chalk, printValidators, reportingStats, originalFile);
// fail on errors, but not if there are only warnings
if (results.error) exitCode = 1;
} else {
console.log(chalk.green(`\n${validFile} passed the validator`));
if (validFile === last(filesToValidate)) console.log();
}
}
}

Expand Down
38 changes: 38 additions & 0 deletions src/cli-validator/utils/printJsonResults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const each = require('lodash/each');

// get line-number-producing, 'magic' code from Swagger Editor
const getLineNumberForPath = require(__dirname + '/../../plugins/ast/ast')
.getLineNumberForPath;

// function to print the results as json to the console.
module.exports = function printJson(results, originalFile) {
const types = ['errors', 'warnings'];
types.forEach(type => {
each(results[type], problems => {
problems.forEach(problem => {
// TODO figure out how to include the config option that caused the error/warning
// and inject that as additional data.

let path = problem.path;

// 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 line = getLineNumberForPath(originalFile, path);

// add the line number to the result JSON
problem.line = line;
});
});
});
// render the results to json in the console with 2 char spacing
const jsonstr = JSON.stringify(results, null, 2);
console.log(jsonstr);
};
39 changes: 39 additions & 0 deletions test/cli-validator/tests/optionHandling.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,43 @@ describe('cli tool - test option handling', function() {
expect(line.includes('statistics')).toEqual(false);
});
});

it('should print json output when -j option is given', async function() {
const capturedText = [];

const unhookIntercept = intercept(function(txt) {
capturedText.push(stripAnsiFrom(txt));
return '';
});

const program = {};
program.args = ['./test/cli-validator/mockFiles/errAndWarn.yaml'];
program.json = true;
program.default_mode = true;

await commandLineValidator(program);
unhookIntercept();

// capturedText should be JSON object. convert to json and check fields
const outputObject = JSON.parse(capturedText);

//console.print(JSON.stringify(outputObject)); //FIXME

expect(outputObject.warning).toEqual(true);
expect(outputObject.error).toEqual(true);

// {"line": 59, "message": "operationIds must be unique", "path": "paths./pet.put.operationId"
expect(outputObject['errors']['operation-ids'][0]['line']).toEqual(59);
expect(outputObject['errors']['operation-ids'][0]['message']).toEqual(
'operationIds must be unique'
);

// {"operations-shared": [{"line": 36, "message": "Operations must have a non-empty `operationId`.", "path": "paths./pet.post.operationId"},
expect(outputObject['warnings']['operations-shared'][0]['line']).toEqual(
36
);
expect(outputObject['warnings']['operations-shared'][0]['message']).toEqual(
'Operations must have a non-empty `operationId`.'
);
});
});

0 comments on commit 759856f

Please sign in to comment.