Skip to content

Commit

Permalink
only populate documentIndex for multi-doc files
Browse files Browse the repository at this point in the history
  • Loading branch information
chris48s committed Aug 25, 2024
1 parent 841a388 commit 3896d37
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 15 deletions.
13 changes: 7 additions & 6 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getCatalogs, getMatchForFilename } from "./catalogs.js";
import { getFiles } from "./glob.js";
import { getFromUrlOrFile } from "./io.js";
import logger from "./logger.js";
import { getDocumentLocation } from "./output-formatters.js";
import { parseFile } from "./parser.js";

const EXIT = {
Expand Down Expand Up @@ -61,10 +62,11 @@ async function validateDocument(
);
result.valid = valid;
result.errors = errors;
const documentLocation = getDocumentLocation(result);
if (valid) {
logger.success(`${fileLocation} is valid\n`);
logger.success(`${documentLocation} is valid\n`);
} else {
logger.error(`${fileLocation} is invalid\n`);
logger.error(`${documentLocation} is invalid\n`);
}

result.code = valid ? EXIT.VALID : EXIT.INVALID;
Expand Down Expand Up @@ -120,12 +122,11 @@ async function validateFile(filename, config, plugins, cache) {

let results = [];
for (let i = 0; i < documents.length; i++) {
const fileLocation =
documents.length === 1 ? filename : `${filename}[${i}]`;
const documentIndex = documents.length === 1 ? null : i;
results.push(
await validateDocument(
fileLocation,
i,
filename,
documentIndex,
documents[i],
schemaLocation,
schema,
Expand Down
68 changes: 65 additions & 3 deletions src/cli.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,7 @@ describe("CLI", function () {
tearDown();
});

it("should log errors in text format when format is text", async function () {
it("should log errors in text format when format is text (single doc)", async function () {
return cli({
patterns: [
"{./testfiles/files/valid.json,./testfiles/files/invalid.json,./testfiles/files/not-supported.txt}",
Expand All @@ -1032,7 +1032,21 @@ describe("CLI", function () {
});
});

it("should output json report when format is json", async function () {
it("should log errors in text format when format is text (multi doc)", async function () {
return cli({
patterns: ["./testfiles/files/multi-doc.yaml"],
schema: "./testfiles/schemas/schema.json",
format: "text",
}).then(() => {
assert(
logger.stdout.includes(
"./testfiles/files/multi-doc.yaml[2]#/num must be number\n",
),
);
});
});

it("should output json report when format is json (single doc)", async function () {
return cli({
patterns: [
"{./testfiles/files/valid.json,./testfiles/files/invalid.json,./testfiles/files/not-supported.txt}",
Expand All @@ -1056,7 +1070,7 @@ describe("CLI", function () {
},
],
fileLocation: "./testfiles/files/invalid.json",
documentIndex: 0,
documentIndex: null,
schemaLocation: "./testfiles/schemas/schema.json",
valid: false,
},
Expand All @@ -1072,10 +1086,58 @@ describe("CLI", function () {
code: 0,
errors: [],
fileLocation: "./testfiles/files/valid.json",
documentIndex: null,
schemaLocation: "./testfiles/schemas/schema.json",
valid: true,
},
],
};
assert.deepStrictEqual(JSON.parse(logger.stdout[0]), expected);
});
});

it("should output json report when format is json (multi doc)", async function () {
return cli({
patterns: ["./testfiles/files/multi-doc.yaml"],
schema: "./testfiles/schemas/schema.json",
format: "json",
}).then(() => {
const expected = {
results: [
{
code: 0,
errors: [],
fileLocation: "./testfiles/files/multi-doc.yaml",
documentIndex: 0,
schemaLocation: "./testfiles/schemas/schema.json",
valid: true,
},
{
code: 0,
errors: [],
fileLocation: "./testfiles/files/multi-doc.yaml",
documentIndex: 1,
schemaLocation: "./testfiles/schemas/schema.json",
valid: true,
},
{
code: 99,
errors: [
{
instancePath: "/num",
keyword: "type",
message: "must be number",
params: {
type: "number",
},
schemaPath: "#/properties/num/type",
},
],
fileLocation: "./testfiles/files/multi-doc.yaml",
documentIndex: 2,
schemaLocation: "./testfiles/schemas/schema.json",
valid: false,
},
],
};
assert.deepStrictEqual(JSON.parse(logger.stdout[0]), expected);
Expand Down
13 changes: 10 additions & 3 deletions src/output-formatters.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import Ajv from "ajv";

function formatErrors(filename, errors) {
function getDocumentLocation(result) {
if (result.documentIndex == null) {
return result.fileLocation;
}
return `${result.fileLocation}[${result.documentIndex}]`;
}

function formatErrors(location, errors) {
const ajv = new Ajv();
return (
ajv.errorsText(errors, {
separator: "\n",
dataVar: filename + "#",
dataVar: location + "#",
}) + "\n"
);
}

export { formatErrors };
export { formatErrors, getDocumentLocation };
4 changes: 3 additions & 1 deletion src/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ async function loadAllPlugins(userPlugins) {
* @property {number | null} documentIndex - Some file formats allow multiple
* documents to be embedded in one file (e.g:
* [yaml](https://www.yaml.info/learn/document.html)). In these cases,
* `documentIndex` identifies the sub document within the file.
* `documentIndex` identifies is used to identify the sub document within the
* file. `documentIndex` will be `null` when there is a one-to-one
* relationship between file and document.
* @property {string | null} schemaLocation - Location of the schema used to
* validate this file if one could be found. `null` if no schema was found.
* @property {boolean | null} valid - Result of the validation (true/false) if a
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/output-text.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BasePlugin } from "../plugins.js";
import { formatErrors } from "../output-formatters.js";
import { formatErrors, getDocumentLocation } from "../output-formatters.js";

class TextOutput extends BasePlugin {
static name = "v8r-plugin-text-output";
Expand All @@ -10,7 +10,7 @@ class TextOutput extends BasePlugin {

getSingleResultLogMessage(result, fileLocation, format) {
if (result.valid === false && format === "text") {
return formatErrors(fileLocation, result.errors);
return formatErrors(getDocumentLocation(result), result.errors);
}
}
}
Expand Down

0 comments on commit 3896d37

Please sign in to comment.