diff --git a/src/error-handlers/anyOf.js b/src/error-handlers/anyOf.js index 7550250..8f87471 100644 --- a/src/error-handlers/anyOf.js +++ b/src/error-handlers/anyOf.js @@ -151,9 +151,38 @@ const anyOfErrorHandler = async (normalizedErrors, instance, localization) => { } // Discriminator identified, but none of the alternatives match if (discriminatedAlternatives.length === 0) { - // TODO: For now, it will use the schema description strategy - } + let discriminatorErrorFound = false; + for (const discriminatorLocation of discriminator) { + /** @type Set */ + const messageSet = new Set(); + let matchesAny = false; + for (const alternative of allAlternatives) { + if (discriminatorLocation in alternative) { + const errorObjects = await getErrors({ [discriminatorLocation]: alternative[discriminatorLocation] }, instance, localization); + if (errorObjects.length === 0) { + matchesAny = true; + break; + } + for (const errorObject of errorObjects) { + messageSet.add(errorObject.message); + } + } + } + if (!matchesAny) { + discriminatorErrorFound = true; + errors.push({ + message: localization.getAnyOfBulletsErrorMessage([...messageSet]), + instanceLocation: discriminatorLocation, + schemaLocation + }); + } + } + + if (discriminatorErrorFound) { + continue; + } + } // Last resort, select the alternative with the most properties matching the instance const instanceProperties = new Set(Instance.values(instance).map((node) => Instance.uri(node))); let maxMatches = -1; diff --git a/src/keyword-error-message.test.js b/src/keyword-error-message.test.js index 79d56ea..c45357b 100644 --- a/src/keyword-error-message.test.js +++ b/src/keyword-error-message.test.js @@ -976,7 +976,7 @@ describe("Error messages", async () => { ]); }); - test.skip("anyOf - discriminator with no matches", async () => { + test("anyOf - discriminator with no matches", async () => { registerSchema({ $schema: "https://json-schema.org/draft/2020-12/schema", anyOf: [ @@ -1019,6 +1019,10 @@ describe("Error messages", async () => { absoluteKeywordLocation: `https://example.com/main#/anyOf/1/properties/type/const`, instanceLocation: "#/type" }, + { + absoluteKeywordLocation: `https://example.com/main#/anyOf/1/properties/box/type`, + instanceLocation: "#/box" + }, { absoluteKeywordLocation: `https://example.com/main#/anyOf`, instanceLocation: "#" @@ -1032,7 +1036,10 @@ describe("Error messages", async () => { { schemaLocation: `https://example.com/main#/anyOf`, instanceLocation: "#/type", - message: `Invalid value. Expected "a", "b". Found "d".` + message: localization.getAnyOfBulletsErrorMessage([ + localization.getConstErrorMessage("a"), + localization.getConstErrorMessage("b") + ]) } ]); });