Skip to content

Commit

Permalink
Fix some special cases
Browse files Browse the repository at this point in the history
  • Loading branch information
matz3 committed Mar 17, 2020
1 parent 65068b8 commit b82c110
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 50 deletions.
22 changes: 15 additions & 7 deletions lib/schema/ValidationError.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const chalk = require("chalk");
const escapeStringRegExp = require("escape-string-regexp");

class ValidationError extends Error {
constructor({errors, project, yaml}) {
Expand Down Expand Up @@ -72,20 +73,22 @@ class ValidationError extends Error {
}

let currentIndex = 0;
let currentSubstring = yaml.source;
for (let i = 0; i < objectPath.length; i++) {
const property = objectPath[i];
let newIndex;

if (isNaN(property)) {
newIndex = yaml.source.indexOf(property, currentIndex);
if (newIndex === -1) {
const propertyRegExp = new RegExp(`^[^#]*?${escapeStringRegExp(property)}`, "m");
const propertyMatch = propertyRegExp.exec(currentSubstring);
if (!propertyMatch) {
throw new Error(`Unable to find "${property}" within yaml:\n${yaml.source.substr(currentIndex)}`);
}
newIndex = propertyMatch.index + propertyMatch[0].length;
} else {
const arrayIndex = parseInt(property);
const matchArrayElement = /(^|\n)([ ]*-[^\n]*)/g;
const yamlSubstring = yaml.source.substr(currentIndex);
const arrayIndicators = yamlSubstring.matchAll(matchArrayElement);
const arrayIndicators = currentSubstring.matchAll(matchArrayElement);
let a = 0;
let firstIndentation = -1;
for (const match of arrayIndicators) {
Expand All @@ -101,7 +104,7 @@ class ValidationError extends Error {
}
if (a === arrayIndex) {
// match[1] might be a line-break
newIndex = currentIndex + match.index + match[1].length + currentIndentation;
newIndex = match.index + match[1].length + currentIndentation;
break;
}
a++;
Expand All @@ -110,12 +113,17 @@ class ValidationError extends Error {
throw new Error("Could not find array element!");
}
}
currentIndex = newIndex;
currentIndex += newIndex;
currentSubstring = yaml.source.substring(currentIndex);
}

const linesUntilMatch = yaml.source.substring(0, currentIndex).split("\n");
const line = linesUntilMatch.length;
const column = linesUntilMatch[line - 1].length + 1;
let column = linesUntilMatch[line - 1].length + 1;
const lastPathSegment = objectPath[objectPath.length - 1];
if (isNaN(lastPathSegment)) {
column -= lastPathSegment.length;
}

return {
line,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
"ajv": "^6.12.0",
"ajv-errors": "^1.0.1",
"chalk": "^3.0.0",
"escape-string-regexp": "^2.0.0",
"graceful-fs": "^4.2.3",
"js-yaml": "^3.13.1",
"libnpmconfig": "^1.2.1",
Expand Down
122 changes: 79 additions & 43 deletions test/lib/schema/ValidationError.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const test = require("ava");
const sinon = require("sinon");
const {safeDump: dumpYaml} = require("js-yaml");
const chalk = require("chalk");

const ValidationError = require("../../../lib/schema/ValidationError");
Expand Down Expand Up @@ -203,13 +202,13 @@ This is just an example for an error message with multiple lines.`
project: {id: "my-project"},
yaml: {
path: "/my-project/ui5.yaml",
source: dumpYaml({
property1: "value1",
property2: "value2",
property3: "value3",
property4: "value4",
property5: "value5",
}),
source:
`property1: value1
property2: value2
property3: value3
property4: value4
property5: value5
`,
documentIndex: 0
}
};
Expand Down Expand Up @@ -269,13 +268,13 @@ test.serial("ValidationError.getYamlExtract", (t) => {
const error = {};
const yaml = {
path: "/my-project/ui5.yaml",
source: dumpYaml({
property1: "value1",
property2: "value2",
property3: "value3",
property4: "value4",
property5: "value5",
}),
source:
`property1: value1
property2: value2
property3: value3
property4: value4
property5: value5
`,
documentIndex: 0
};

Expand All @@ -296,10 +295,10 @@ test.serial("ValidationError.getYamlExtract", (t) => {
});

test.serial("ValidationError.getSourceExtract", (t) => {
const yamlSource = dumpYaml({
property1: "value1",
property2: "value2"
});
const yamlSource =
`property1: value1
property2: value2
`;
const line = 2;
const column = 1;

Expand All @@ -317,13 +316,13 @@ test.serial("ValidationError.analyzeYamlError: Property", (t) => {
const error = {dataPath: "/property3"};
const yaml = {
path: "/my-project/ui5.yaml",
source: dumpYaml({
property1: "value1",
property2: "value2",
property3: "value3",
property4: "value4",
property5: "value5",
}),
source:
`property1: value1
property2: value2
property3: value3
property4: value4
property5: value5
`,
documentIndex: 0
};

Expand All @@ -337,13 +336,12 @@ test.serial("ValidationError.analyzeYamlError: Nested property", (t) => {
const error = {dataPath: "/property2/property3"};
const yaml = {
path: "/my-project/ui5.yaml",
source: dumpYaml({
property1: "value1",
property2: {
property3: "value3",
},
property3: "value3",
}),
source:
`property1: value1
property2:
property3: value3
property3: value3
`,
documentIndex: 0
};

Expand All @@ -357,15 +355,13 @@ test.serial("ValidationError.analyzeYamlError: Array", (t) => {
const error = {dataPath: "/property/list/2/name"};
const yaml = {
path: "/my-project/ui5.yaml",
source: dumpYaml({
property: {
list: [
{name: " - - - - -"},
{name: "other - name- with- hyphens"},
{name: "name3"}
]
},
}),
source:
`property:
list:
- name: ' - - - - -'
- name: other - name- with- hyphens
- name: name3
`,
documentIndex: 0
};

Expand All @@ -376,7 +372,7 @@ test.serial("ValidationError.analyzeYamlError: Array", (t) => {
});


test.serial.only("ValidationError.analyzeYamlError: Nested array", (t) => {
test.serial("ValidationError.analyzeYamlError: Nested array", (t) => {
const error = {dataPath: "/items/2/subItems/1"};
const yaml = {
path: "/my-project/ui5.yaml",
Expand All @@ -400,3 +396,43 @@ test.serial.only("ValidationError.analyzeYamlError: Nested array", (t) => {
t.deepEqual(info, {line: 10, column: 7},
"analyzeYamlError should return expected results");
});

test.serial("ValidationError.analyzeYamlError: Nested property with comments", (t) => {
const error = {dataPath: "/property1/property2/property3/property4"};
const yaml = {
path: "/my-project/ui5.yaml",
source:
`property1:
property2:
property3:
# property4: value4444
property4: value4
`,
documentIndex: 0
};

const info = ValidationError.analyzeYamlError({error, yaml});

t.deepEqual(info, {line: 5, column: 7},
"analyzeYamlError should return expected results");
});

test.serial("ValidationError.analyzeYamlError: Nested properties with same name", (t) => {
const error = {dataPath: "/property/property/property/property"};
const yaml = {
path: "/my-project/ui5.yaml",
source:
`property:
property:
property:
# property: foo
property: bar
`,
documentIndex: 0
};

const info = ValidationError.analyzeYamlError({error, yaml});

t.deepEqual(info, {line: 5, column: 7},
"analyzeYamlError should return expected results");
});

0 comments on commit b82c110

Please sign in to comment.