Skip to content

Commit

Permalink
Merge pull request #9167 from webpack/refactor/validation
Browse files Browse the repository at this point in the history
improve validation errors and tests
  • Loading branch information
sokra committed May 22, 2019
2 parents 87fc33e + a4406ff commit d3ef632
Show file tree
Hide file tree
Showing 4 changed files with 415 additions and 364 deletions.
2 changes: 2 additions & 0 deletions declarations/WebpackOptions.d.ts
Expand Up @@ -22,6 +22,8 @@ export type EntryDynamic = () => EntryStatic | Promise<EntryStatic>;
*/
export type EntryStatic = EntryObject | EntryItem;
/**
* A non-empty array of non-empty strings
*
* This interface was referenced by `WebpackOptions`'s JSON-Schema
* via the `definition` "NonEmptyArrayOfUniqueStringValues".
*/
Expand Down
62 changes: 52 additions & 10 deletions lib/WebpackOptionsValidationError.js
Expand Up @@ -50,13 +50,34 @@ const getSchemaPartDescription = schemaPart => {
return "";
};

const SPECIFICITY = {
type: 1,
oneOf: 1,
anyOf: 1,
allOf: 1,
additionalProperties: 2,
enum: 1,
instanceof: 1,
required: 2,
minimum: 2,
uniqueItems: 2,
minLength: 2,
minItems: 2,
minProperties: 2,
absolutePath: 2
};

const filterMax = (array, fn) => {
const max = array.reduce((max, item) => Math.max(max, fn(item)), 0);
return array.filter(item => fn(item) === max);
};

const filterChildren = children => {
return children.filter(
err =>
err.keyword !== "anyOf" &&
err.keyword !== "allOf" &&
err.keyword !== "oneOf"
children = filterMax(children, err =>
err.dataPath ? err.dataPath.length : 0
);
children = filterMax(children, err => SPECIFICITY[err.keyword] || 2);
return children;
};

const indent = (str, prefix, firstLine) => {
Expand Down Expand Up @@ -154,6 +175,10 @@ class WebpackOptionsValidationError extends WebpackError {
return "RegExp";
}

if (schema.enum) {
return schema.enum.map(item => JSON.stringify(item)).join(" | ");
}

if (schema.$ref) {
return formatInnerSchema(getSchemaPart(schema.$ref), true);
}
Expand All @@ -166,9 +191,6 @@ class WebpackOptionsValidationError extends WebpackError {
if (schema.anyOf) {
return schema.anyOf.map(formatInnerSchema).join(" | ");
}
if (schema.enum) {
return schema.enum.map(item => JSON.stringify(item)).join(" | ");
}
return JSON.stringify(schema, null, 2);
}

Expand Down Expand Up @@ -229,11 +251,17 @@ class WebpackOptionsValidationError extends WebpackError {
})
);
}
const children = filterChildren(err.children);
if (children.length === 1) {
return WebpackOptionsValidationError.formatValidationError(
children[0]
);
}
return (
`${dataPath} should be one of these:\n${getSchemaPartText(
err.parentSchema
)}\n` +
`Details:\n${filterChildren(err.children)
`Details:\n${children
.map(
err =>
" * " +
Expand Down Expand Up @@ -312,7 +340,21 @@ class WebpackOptionsValidationError extends WebpackError {
err.keyword === "minProperties"
) {
if (err.params.limit === 1) {
return `${dataPath} should not be empty.${getSchemaPartDescription(
switch (err.keyword) {
case "minLength":
return `${dataPath} should be an non-empty string.${getSchemaPartDescription(
err.parentSchema
)}`;
case "minItems":
return `${dataPath} should be an non-empty array.${getSchemaPartDescription(
err.parentSchema
)}`;
case "minProperties":
return `${dataPath} should be an non-empty object.${getSchemaPartDescription(
err.parentSchema
)}`;
}
return `${dataPath} should be not empty.${getSchemaPartDescription(
err.parentSchema
)}`;
} else {
Expand Down
1 change: 1 addition & 0 deletions schemas/WebpackOptions.json
Expand Up @@ -385,6 +385,7 @@
}
},
"NonEmptyArrayOfUniqueStringValues": {
"description": "A non-empty array of non-empty strings",
"type": "array",
"items": {
"description": "A non-empty string",
Expand Down

0 comments on commit d3ef632

Please sign in to comment.