From 209ac33b3fc8becd2ac9b4e8122dec8b6facc721 Mon Sep 17 00:00:00 2001 From: Shiva Gupta Date: Fri, 30 Jan 2026 16:11:52 +0530 Subject: [PATCH 1/3] Combine `const` and `enum` errors into a single message --- src/error-handlers/const.js | 32 --------- src/error-handlers/constAndEnum.js | 98 ++++++++++++++++++++++++++ src/error-handlers/enum.js | 32 --------- src/index.js | 6 +- src/test-suite/tests/const.json | 19 +++++ src/test-suite/tests/constAndEnum.json | 74 +++++++++++++++++++ src/test-suite/tests/enum.json | 40 +++++++++++ 7 files changed, 233 insertions(+), 68 deletions(-) delete mode 100644 src/error-handlers/const.js create mode 100644 src/error-handlers/constAndEnum.js delete mode 100644 src/error-handlers/enum.js create mode 100644 src/test-suite/tests/constAndEnum.json diff --git a/src/error-handlers/const.js b/src/error-handlers/const.js deleted file mode 100644 index 64c23c3..0000000 --- a/src/error-handlers/const.js +++ /dev/null @@ -1,32 +0,0 @@ -import { getSchema } from "@hyperjump/json-schema/experimental"; -import * as Schema from "@hyperjump/browser"; -import * as Instance from "@hyperjump/json-schema/instance/experimental"; - -/** - * @import { ErrorHandler, ErrorObject, Json } from "../index.d.ts" - */ - -/** @type ErrorHandler */ -const constErrorHandler = async (normalizedErrors, instance, localization) => { - /** @type ErrorObject[] */ - const errors = []; - - for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/const"]) { - if (normalizedErrors["https://json-schema.org/keyword/const"][schemaLocation]) { - continue; - } - - const keyword = await getSchema(schemaLocation); - const expected = /** @type Json */ (Schema.value(keyword)); - - errors.push({ - message: localization.getConstErrorMessage(expected), - instanceLocation: Instance.uri(instance), - schemaLocations: [schemaLocation] - }); - } - - return errors; -}; - -export default constErrorHandler; diff --git a/src/error-handlers/constAndEnum.js b/src/error-handlers/constAndEnum.js new file mode 100644 index 0000000..509d828 --- /dev/null +++ b/src/error-handlers/constAndEnum.js @@ -0,0 +1,98 @@ +import { getSchema } from "@hyperjump/json-schema/experimental"; +import * as Schema from "@hyperjump/browser"; +import * as Instance from "@hyperjump/json-schema/instance/experimental"; +import jsonStringify from "json-stringify-deterministic"; + +/** + * @import { ErrorHandler, ErrorObject, Json } from "../index.d.ts" + */ + +/** + * @typedef {{ + * allowedValues: Json[]; + * schemaLocation: string; + * }} Constraint + */ + +/** @type {ErrorHandler} */ +const constAndEnumErrorHandler = async (normalizedErrors, instance, localization) => { + /** @type {ErrorObject[]} */ + const errors = []; + + /** @type {Constraint[]} */ + const constraints = []; + let hasFailure = false; + + for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/const"]) { + const passed = normalizedErrors["https://json-schema.org/keyword/const"][schemaLocation] === true; + if (!passed) { + hasFailure = true; + } + const keyword = await getSchema(schemaLocation); + constraints.push({ + allowedValues: [Schema.value(keyword)], + schemaLocation + }); + } + + for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/enum"]) { + const passed = normalizedErrors["https://json-schema.org/keyword/enum"][schemaLocation] === true; + if (!passed) { + hasFailure = true; + } + const keyword = await getSchema(schemaLocation); + constraints.push({ + allowedValues: Schema.value(keyword), + schemaLocation + }); + } + + if (!hasFailure || constraints.length === 0) { + return errors; + } + + let intersectionKeys = new Set(constraints[0].allowedValues.map(toKey)); + for (let i = 1; i < constraints.length; i++) { + intersectionKeys = intersectionKeys.intersection(new Set(constraints[i].allowedValues.map(toKey))); + } + + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + const intersection = /** @type {Json[]} */ ([...intersectionKeys].map((k) => JSON.parse(k))); + + const instanceLocation = Instance.uri(instance); + const intersectionKeysArray = [...intersectionKeys]; + const exactMatch = constraints.find((c) => { + if (c.allowedValues.length !== intersection.length) return false; + const constraintKeys = new Set(c.allowedValues.map(toKey)); + return intersectionKeysArray.every((k) => constraintKeys.has(k)); + }); + + if (intersection.length === 0) { + errors.push({ + message: localization.getBooleanSchemaErrorMessage(), + instanceLocation, + schemaLocations: constraints.map((c) => c.schemaLocation) + }); + } else if (intersection.length === 1) { + errors.push({ + message: localization.getConstErrorMessage(intersection[0]), + instanceLocation, + schemaLocations: exactMatch ? [exactMatch.schemaLocation] : constraints.map((c) => c.schemaLocation) + }); + } else { + errors.push({ + message: localization.getEnumErrorMessage(intersection), + instanceLocation, + schemaLocations: exactMatch ? [exactMatch.schemaLocation] : constraints.map((c) => c.schemaLocation) + }); + } + return errors; +}; + +/** + * @param {Json} val + * @returns {string} + */ +const toKey = (val) => jsonStringify(val); + +export default constAndEnumErrorHandler; diff --git a/src/error-handlers/enum.js b/src/error-handlers/enum.js deleted file mode 100644 index 2d1c1d0..0000000 --- a/src/error-handlers/enum.js +++ /dev/null @@ -1,32 +0,0 @@ -import { getSchema } from "@hyperjump/json-schema/experimental"; -import * as Schema from "@hyperjump/browser"; -import * as Instance from "@hyperjump/json-schema/instance/experimental"; - -/** - * @import { ErrorHandler, ErrorObject, Json } from "../index.d.ts" - */ - -/** @type ErrorHandler */ -const enumErrorHandler = async (normalizedErrors, instance, localization) => { - /** @type ErrorObject[] */ - const errors = []; - - for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/enum"]) { - if (normalizedErrors["https://json-schema.org/keyword/enum"][schemaLocation]) { - continue; - } - - const keyword = await getSchema(schemaLocation); - const expected = /** @type Json[] */ (Schema.value(keyword)); - - errors.push({ - message: localization.getEnumErrorMessage(expected), - instanceLocation: Instance.uri(instance), - schemaLocations: [schemaLocation] - }); - } - - return errors; -}; - -export default enumErrorHandler; diff --git a/src/index.js b/src/index.js index ce48b7f..5031cff 100644 --- a/src/index.js +++ b/src/index.js @@ -55,10 +55,9 @@ import unknownNormalizationHandler from "./normalization-handlers/unknown.js"; // Error Handlers import anyOfErrorHandler from "./error-handlers/anyOf.js"; import booleanSchemaErrorHandler from "./error-handlers/boolean-schema.js"; -import constErrorHandler from "./error-handlers/const.js"; +import constAndEnumErrorHandler from "./error-handlers/constAndEnum.js"; import containsErrorHandler from "./error-handlers/contains.js"; import dependenciesErrorHandler from "./error-handlers/draft-04/dependencies.js"; -import enumErrorHandler from "./error-handlers/enum.js"; import exclusiveMaximumErrorHandler from "./error-handlers/exclusiveMaximum.js"; import exclusiveMinimumErrorHandler from "./error-handlers/exclusiveMinimum.js"; import formatErrorHandler from "./error-handlers/format.js"; @@ -140,10 +139,9 @@ setNormalizationHandler("https://json-schema.org/keyword/unknown", unknownNormal addErrorHandler(anyOfErrorHandler); addErrorHandler(booleanSchemaErrorHandler); -addErrorHandler(constErrorHandler); +addErrorHandler(constAndEnumErrorHandler); addErrorHandler(containsErrorHandler); addErrorHandler(dependenciesErrorHandler); -addErrorHandler(enumErrorHandler); addErrorHandler(exclusiveMaximumErrorHandler); addErrorHandler(exclusiveMinimumErrorHandler); addErrorHandler(formatErrorHandler); diff --git a/src/test-suite/tests/const.json b/src/test-suite/tests/const.json index c59ac52..4044877 100644 --- a/src/test-suite/tests/const.json +++ b/src/test-suite/tests/const.json @@ -29,6 +29,25 @@ }, "instance": 42, "errors": [] + }, + { + "description": "contradictory const - empty intersection", + "compatibility": "6", + "schema": { + "allOf": [ + { "const": "a" }, + { "const": "b" } + ] + }, + "instance": "a", + "errors": [ + { + "messageId": "boolean-schema-message", + "messageParams": {}, + "instanceLocation": "#", + "schemaLocations": ["#/allOf/0/const", "#/allOf/1/const"] + } + ] } ] } diff --git a/src/test-suite/tests/constAndEnum.json b/src/test-suite/tests/constAndEnum.json new file mode 100644 index 0000000..d2706b0 --- /dev/null +++ b/src/test-suite/tests/constAndEnum.json @@ -0,0 +1,74 @@ +{ + "$schema": "../test-suite.schema.json", + + "description": "Combined const and enum constraints", + "tests": [ + { + "description": "const with enum constraints (combined)", + "compatibility": "6", + "schema": { + "allOf": [ + { "enum": ["a", "b", "c"] }, + { "enum": ["a", "b"] }, + { "const": "a" } + ] + }, + "instance": "x", + "errors": [ + { + "messageId": "const-message", + "messageParams": { "expected": "\"a\"" }, + "instanceLocation": "#", + "schemaLocations": ["#/allOf/2/const"] + } + ] + }, + { + "description": "enum with const - deterministic key order", + "compatibility": "6", + "schema": { + "allOf": [ + { "enum": [{"a": 1, "b": 2}, {"c": 3}] }, + { "const": {"b": 2, "a": 1} } + ] + }, + "instance": "x", + "errors": [ + { + "messageId": "const-message", + "messageParams": { + "expected": "{\n \"a\": 1,\n \"b\": 2\n}" + }, + "instanceLocation": "#", + "schemaLocations": ["#/allOf/1/const"] + } + ] + }, + { + "description": "multiple enums with no exact match", + "compatibility": "6", + "schema": { + "allOf": [ + { "enum": ["a", "b", "c"] }, + { "enum": ["a", "b", "d"] }, + { "enum": ["a", "b", "e"] } + ] + }, + "instance": "c", + "errors": [ + { + "messageId": "enum-message", + "messageParams": { + "expected": { "or": ["\"a\"", "\"b\""] } + }, + "instanceLocation": "#", + "schemaLocations": [ + "#/allOf/0/enum", + "#/allOf/1/enum", + "#/allOf/2/enum" + ] + } + ] + } + ] +} diff --git a/src/test-suite/tests/enum.json b/src/test-suite/tests/enum.json index 613e004..03f6c2d 100644 --- a/src/test-suite/tests/enum.json +++ b/src/test-suite/tests/enum.json @@ -21,6 +21,27 @@ } ] }, + { + "description": "multiple enum constraints (combined)", + "schema": { + "allOf": [ + { "enum": ["a", "b", "c"] }, + { "enum": ["a", "b"] } + ] + }, + "instance": "x", + "errors": [ + { + "messageId": "enum-message", + "messageParams": { + "expected": { "or": ["\"a\"", "\"b\""] }, + "count": 2 + }, + "instanceLocation": "#", + "schemaLocations": ["#/allOf/1/enum"] + } + ] + }, { "description": "enum pass", "schema": { @@ -28,6 +49,25 @@ }, "instance": "foo", "errors": [] + }, + { + "description": "contradictory enum - empty intersection", + "compatibility": "6", + "schema": { + "allOf": [ + { "enum": ["a", "b", "c"] }, + { "enum": ["d", "e", "f"] } + ] + }, + "instance": "a", + "errors": [ + { + "messageId": "boolean-schema-message", + "messageParams": {}, + "instanceLocation": "#", + "schemaLocations": ["#/allOf/0/enum", "#/allOf/1/enum"] + } + ] } ] } From 42e7cca113f6ada595ce93a3cc2f2d76533dbe4b Mon Sep 17 00:00:00 2001 From: Jason Desrosiers Date: Mon, 9 Feb 2026 10:34:38 -0800 Subject: [PATCH 2/3] Simplify const/enum --- src/error-handlers/constAndEnum.js | 100 ++++++++++--------------- src/localization.js | 21 +++--- src/test-suite/tests/const.json | 5 +- src/test-suite/tests/constAndEnum.json | 5 +- src/test-suite/tests/enum.json | 10 ++- 5 files changed, 64 insertions(+), 77 deletions(-) diff --git a/src/error-handlers/constAndEnum.js b/src/error-handlers/constAndEnum.js index 509d828..e9b8ece 100644 --- a/src/error-handlers/constAndEnum.js +++ b/src/error-handlers/constAndEnum.js @@ -4,7 +4,7 @@ import * as Instance from "@hyperjump/json-schema/instance/experimental"; import jsonStringify from "json-stringify-deterministic"; /** - * @import { ErrorHandler, ErrorObject, Json } from "../index.d.ts" + * @import { ErrorHandler, Json } from "../index.d.ts" */ /** @@ -16,83 +16,63 @@ import jsonStringify from "json-stringify-deterministic"; /** @type {ErrorHandler} */ const constAndEnumErrorHandler = async (normalizedErrors, instance, localization) => { - /** @type {ErrorObject[]} */ - const errors = []; + /** @type Set | undefined */ + let allowedJson; - /** @type {Constraint[]} */ - const constraints = []; - let hasFailure = false; + /** @type string[]> */ + const constSchemaLocations = []; + + /** @type string[]> */ + const enumSchemaLocations = []; + + /** @type string[]> */ + const allSchemaLocations = []; for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/const"]) { - const passed = normalizedErrors["https://json-schema.org/keyword/const"][schemaLocation] === true; - if (!passed) { - hasFailure = true; + if (!normalizedErrors["https://json-schema.org/keyword/const"][schemaLocation]) { + constSchemaLocations.push(schemaLocation); } + allSchemaLocations.push(schemaLocation); + const keyword = await getSchema(schemaLocation); - constraints.push({ - allowedValues: [Schema.value(keyword)], - schemaLocation - }); + const keywordJson = new Set([jsonStringify(/** @type Json */ (Schema.value(keyword)))]); + + allowedJson = allowedJson?.intersection(keywordJson) ?? keywordJson; } for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/enum"]) { - const passed = normalizedErrors["https://json-schema.org/keyword/enum"][schemaLocation] === true; - if (!passed) { - hasFailure = true; + if (!normalizedErrors["https://json-schema.org/keyword/enum"][schemaLocation]) { + enumSchemaLocations.push(schemaLocation); } + allSchemaLocations.push(schemaLocation); + const keyword = await getSchema(schemaLocation); - constraints.push({ - allowedValues: Schema.value(keyword), - schemaLocation - }); - } + const keywordJson = new Set(/** @type Json[] */ (Schema.value(keyword)).map((value) => jsonStringify(value))); - if (!hasFailure || constraints.length === 0) { - return errors; + allowedJson = allowedJson?.intersection(keywordJson) ?? keywordJson; } - let intersectionKeys = new Set(constraints[0].allowedValues.map(toKey)); - for (let i = 1; i < constraints.length; i++) { - intersectionKeys = intersectionKeys.intersection(new Set(constraints[i].allowedValues.map(toKey))); + if (constSchemaLocations.length === 0 && enumSchemaLocations.length === 0) { + return []; } - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - const intersection = /** @type {Json[]} */ ([...intersectionKeys].map((k) => JSON.parse(k))); - - const instanceLocation = Instance.uri(instance); - const intersectionKeysArray = [...intersectionKeys]; - const exactMatch = constraints.find((c) => { - if (c.allowedValues.length !== intersection.length) return false; - const constraintKeys = new Set(c.allowedValues.map(toKey)); - return intersectionKeysArray.every((k) => constraintKeys.has(k)); - }); - - if (intersection.length === 0) { - errors.push({ + if (allowedJson?.size === 0) { + return [{ message: localization.getBooleanSchemaErrorMessage(), - instanceLocation, - schemaLocations: constraints.map((c) => c.schemaLocation) - }); - } else if (intersection.length === 1) { - errors.push({ - message: localization.getConstErrorMessage(intersection[0]), - instanceLocation, - schemaLocations: exactMatch ? [exactMatch.schemaLocation] : constraints.map((c) => c.schemaLocation) - }); + instanceLocation: Instance.uri(instance), + schemaLocations: allSchemaLocations + }]; } else { - errors.push({ - message: localization.getEnumErrorMessage(intersection), - instanceLocation, - schemaLocations: exactMatch ? [exactMatch.schemaLocation] : constraints.map((c) => c.schemaLocation) - }); + /** @type Json[] */ + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + const allowedValues = [...allowedJson ?? []].map((json) => JSON.parse(json)); + + return [{ + message: localization.getEnumErrorMessage(allowedValues), + instanceLocation: Instance.uri(instance), + schemaLocations: constSchemaLocations.length ? constSchemaLocations : enumSchemaLocations + }]; } - return errors; }; -/** - * @param {Json} val - * @returns {string} - */ -const toKey = (val) => jsonStringify(val); - export default constAndEnumErrorHandler; diff --git a/src/localization.js b/src/localization.js index 17ccef4..ddd16d5 100644 --- a/src/localization.js +++ b/src/localization.js @@ -59,19 +59,18 @@ export class Localization { }); } - /** @type (expected: Json) => string */ - getConstErrorMessage(expected) { - return this.#formatMessage("const-message", { - expected: JSON.stringify(expected, null, " ") - }); - } - /** @type (expected: Json[]) => string */ getEnumErrorMessage(expected) { - const expectedJson = expected.map((value) => JSON.stringify(value)); - return this.#formatMessage("enum-message", { - expected: this.disjunction.format(expectedJson) - }); + if (expected.length === 1) { + return this.#formatMessage("const-message", { + expected: JSON.stringify(expected[0], null, " ") + }); + } else { + const expectedJson = expected.map((value) => JSON.stringify(value)); + return this.#formatMessage("enum-message", { + expected: this.disjunction.format(expectedJson) + }); + } } /** @type (format: string) => string */ diff --git a/src/test-suite/tests/const.json b/src/test-suite/tests/const.json index 4044877..378da7f 100644 --- a/src/test-suite/tests/const.json +++ b/src/test-suite/tests/const.json @@ -45,7 +45,10 @@ "messageId": "boolean-schema-message", "messageParams": {}, "instanceLocation": "#", - "schemaLocations": ["#/allOf/0/const", "#/allOf/1/const"] + "schemaLocations": [ + "#/allOf/0/const", + "#/allOf/1/const" + ] } ] } diff --git a/src/test-suite/tests/constAndEnum.json b/src/test-suite/tests/constAndEnum.json index d2706b0..b18dae9 100644 --- a/src/test-suite/tests/constAndEnum.json +++ b/src/test-suite/tests/constAndEnum.json @@ -28,8 +28,8 @@ "compatibility": "6", "schema": { "allOf": [ - { "enum": [{"a": 1, "b": 2}, {"c": 3}] }, - { "const": {"b": 2, "a": 1} } + { "enum": [{ "a": 1, "b": 2 }, { "c": 3 }] }, + { "const": { "b": 2, "a": 1 } } ] }, "instance": "x", @@ -63,7 +63,6 @@ }, "instanceLocation": "#", "schemaLocations": [ - "#/allOf/0/enum", "#/allOf/1/enum", "#/allOf/2/enum" ] diff --git a/src/test-suite/tests/enum.json b/src/test-suite/tests/enum.json index 03f6c2d..4592ae6 100644 --- a/src/test-suite/tests/enum.json +++ b/src/test-suite/tests/enum.json @@ -38,7 +38,10 @@ "count": 2 }, "instanceLocation": "#", - "schemaLocations": ["#/allOf/1/enum"] + "schemaLocations": [ + "#/allOf/0/enum", + "#/allOf/1/enum" + ] } ] }, @@ -65,7 +68,10 @@ "messageId": "boolean-schema-message", "messageParams": {}, "instanceLocation": "#", - "schemaLocations": ["#/allOf/0/enum", "#/allOf/1/enum"] + "schemaLocations": [ + "#/allOf/0/enum", + "#/allOf/1/enum" + ] } ] } From 9b1bd1928c05a6fe71f53685041d1e18ae271fbf Mon Sep 17 00:00:00 2001 From: Jason Desrosiers Date: Sat, 14 Feb 2026 19:28:59 -0800 Subject: [PATCH 3/3] A little cleanup --- .../{constAndEnum.js => constEnum.js} | 4 +- src/index.js | 4 +- src/test-suite/tests/const.json | 43 ++++++++++- src/test-suite/tests/constAndEnum.json | 73 ------------------- src/test-suite/tests/enum.json | 37 ++++++++-- 5 files changed, 77 insertions(+), 84 deletions(-) rename src/error-handlers/{constAndEnum.js => constEnum.js} (94%) delete mode 100644 src/test-suite/tests/constAndEnum.json diff --git a/src/error-handlers/constAndEnum.js b/src/error-handlers/constEnum.js similarity index 94% rename from src/error-handlers/constAndEnum.js rename to src/error-handlers/constEnum.js index e9b8ece..ab0a311 100644 --- a/src/error-handlers/constAndEnum.js +++ b/src/error-handlers/constEnum.js @@ -15,7 +15,7 @@ import jsonStringify from "json-stringify-deterministic"; */ /** @type {ErrorHandler} */ -const constAndEnumErrorHandler = async (normalizedErrors, instance, localization) => { +const constEnumErrorHandler = async (normalizedErrors, instance, localization) => { /** @type Set | undefined */ let allowedJson; @@ -75,4 +75,4 @@ const constAndEnumErrorHandler = async (normalizedErrors, instance, localization } }; -export default constAndEnumErrorHandler; +export default constEnumErrorHandler; diff --git a/src/index.js b/src/index.js index 5031cff..c617f46 100644 --- a/src/index.js +++ b/src/index.js @@ -55,7 +55,7 @@ import unknownNormalizationHandler from "./normalization-handlers/unknown.js"; // Error Handlers import anyOfErrorHandler from "./error-handlers/anyOf.js"; import booleanSchemaErrorHandler from "./error-handlers/boolean-schema.js"; -import constAndEnumErrorHandler from "./error-handlers/constAndEnum.js"; +import constEnumErrorHandler from "./error-handlers/constEnum.js"; import containsErrorHandler from "./error-handlers/contains.js"; import dependenciesErrorHandler from "./error-handlers/draft-04/dependencies.js"; import exclusiveMaximumErrorHandler from "./error-handlers/exclusiveMaximum.js"; @@ -139,7 +139,7 @@ setNormalizationHandler("https://json-schema.org/keyword/unknown", unknownNormal addErrorHandler(anyOfErrorHandler); addErrorHandler(booleanSchemaErrorHandler); -addErrorHandler(constAndEnumErrorHandler); +addErrorHandler(constEnumErrorHandler); addErrorHandler(containsErrorHandler); addErrorHandler(dependenciesErrorHandler); addErrorHandler(exclusiveMaximumErrorHandler); diff --git a/src/test-suite/tests/const.json b/src/test-suite/tests/const.json index 378da7f..559ca3a 100644 --- a/src/test-suite/tests/const.json +++ b/src/test-suite/tests/const.json @@ -31,7 +31,48 @@ "errors": [] }, { - "description": "contradictory const - empty intersection", + "description": "const with enum", + "compatibility": "6", + "schema": { + "allOf": [ + { "enum": ["a", "b", "c"] }, + { "enum": ["a", "b"] }, + { "const": "a" } + ] + }, + "instance": "x", + "errors": [ + { + "messageId": "const-message", + "messageParams": { "expected": "\"a\"" }, + "instanceLocation": "#", + "schemaLocations": ["#/allOf/2/const"] + } + ] + }, + { + "description": "const with enum - deterministic key order", + "compatibility": "6", + "schema": { + "allOf": [ + { "enum": [{ "a": 1, "b": 2 }, { "c": 3 }] }, + { "const": { "b": 2, "a": 1 } } + ] + }, + "instance": "x", + "errors": [ + { + "messageId": "const-message", + "messageParams": { + "expected": "{\n \"a\": 1,\n \"b\": 2\n}" + }, + "instanceLocation": "#", + "schemaLocations": ["#/allOf/1/const"] + } + ] + }, + { + "description": "contradictory const", "compatibility": "6", "schema": { "allOf": [ diff --git a/src/test-suite/tests/constAndEnum.json b/src/test-suite/tests/constAndEnum.json deleted file mode 100644 index b18dae9..0000000 --- a/src/test-suite/tests/constAndEnum.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "$schema": "../test-suite.schema.json", - - "description": "Combined const and enum constraints", - "tests": [ - { - "description": "const with enum constraints (combined)", - "compatibility": "6", - "schema": { - "allOf": [ - { "enum": ["a", "b", "c"] }, - { "enum": ["a", "b"] }, - { "const": "a" } - ] - }, - "instance": "x", - "errors": [ - { - "messageId": "const-message", - "messageParams": { "expected": "\"a\"" }, - "instanceLocation": "#", - "schemaLocations": ["#/allOf/2/const"] - } - ] - }, - { - "description": "enum with const - deterministic key order", - "compatibility": "6", - "schema": { - "allOf": [ - { "enum": [{ "a": 1, "b": 2 }, { "c": 3 }] }, - { "const": { "b": 2, "a": 1 } } - ] - }, - "instance": "x", - "errors": [ - { - "messageId": "const-message", - "messageParams": { - "expected": "{\n \"a\": 1,\n \"b\": 2\n}" - }, - "instanceLocation": "#", - "schemaLocations": ["#/allOf/1/const"] - } - ] - }, - { - "description": "multiple enums with no exact match", - "compatibility": "6", - "schema": { - "allOf": [ - { "enum": ["a", "b", "c"] }, - { "enum": ["a", "b", "d"] }, - { "enum": ["a", "b", "e"] } - ] - }, - "instance": "c", - "errors": [ - { - "messageId": "enum-message", - "messageParams": { - "expected": { "or": ["\"a\"", "\"b\""] } - }, - "instanceLocation": "#", - "schemaLocations": [ - "#/allOf/1/enum", - "#/allOf/2/enum" - ] - } - ] - } - ] -} diff --git a/src/test-suite/tests/enum.json b/src/test-suite/tests/enum.json index 4592ae6..86be502 100644 --- a/src/test-suite/tests/enum.json +++ b/src/test-suite/tests/enum.json @@ -22,7 +22,15 @@ ] }, { - "description": "multiple enum constraints (combined)", + "description": "enum pass", + "schema": { + "enum": ["foo", "bar"] + }, + "instance": "foo", + "errors": [] + }, + { + "description": "multiple enums with matches", "schema": { "allOf": [ { "enum": ["a", "b", "c"] }, @@ -46,15 +54,32 @@ ] }, { - "description": "enum pass", + "description": "multiple enums with a match", + "compatibility": "6", "schema": { - "enum": ["foo", "bar"] + "allOf": [ + { "enum": ["a", "b", "c"] }, + { "enum": ["a", "b", "d"] }, + { "enum": ["a", "b", "e"] } + ] }, - "instance": "foo", - "errors": [] + "instance": "c", + "errors": [ + { + "messageId": "enum-message", + "messageParams": { + "expected": { "or": ["\"a\"", "\"b\""] } + }, + "instanceLocation": "#", + "schemaLocations": [ + "#/allOf/1/enum", + "#/allOf/2/enum" + ] + } + ] }, { - "description": "contradictory enum - empty intersection", + "description": "contradictory enum", "compatibility": "6", "schema": { "allOf": [