Skip to content

Commit cde874a

Browse files
committed
Fix a couple issues with dependent keywords
- Check that min/maxContains is coming from the right schema - Add exclusiveMinimum/Maximum to draft-04 minimum/maximum schemaLocations
1 parent 001d130 commit cde874a

5 files changed

Lines changed: 34 additions & 18 deletions

File tree

src/error-handlers/contains.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,24 @@ const containsErrorHandler = async (normalizedErrors, instance, localization) =>
2828

2929
/** @type ContainsRange */
3030
const range = {};
31+
const parentLocation = pointerPop(schemaLocation);
3132

3233
for (const minContainsLocation in normalizedErrors["https://json-schema.org/keyword/minContains"]) {
33-
const minContainsNode = await getSchema(minContainsLocation);
34-
const minContains = /** @type number */ (Schema.value(minContainsNode));
35-
range.minContains = Math.max(range.minContains ?? -1, minContains);
36-
schemaLocations.push(minContainsLocation);
34+
if (pointerPop(minContainsLocation) === parentLocation) {
35+
const minContainsNode = await getSchema(minContainsLocation);
36+
range.minContains = /** @type number */ (Schema.value(minContainsNode));
37+
schemaLocations.push(minContainsLocation);
38+
break;
39+
}
3740
}
3841

3942
for (const maxContainsLocation in normalizedErrors["https://json-schema.org/keyword/maxContains"]) {
40-
const maxContainsNode = await getSchema(maxContainsLocation);
41-
const maxContains = /** @type number */ (Schema.value(maxContainsNode));
42-
range.maxContains = Math.min(range.maxContains ?? Number.MAX_VALUE, maxContains);
43-
schemaLocations.push(maxContainsLocation);
43+
if (pointerPop(maxContainsLocation) === parentLocation) {
44+
const maxContainsNode = await getSchema(maxContainsLocation);
45+
range.maxContains = /** @type number */ (Schema.value(maxContainsNode));
46+
schemaLocations.push(maxContainsLocation);
47+
break;
48+
}
4449
}
4550

4651
errors.push({
@@ -54,4 +59,7 @@ const containsErrorHandler = async (normalizedErrors, instance, localization) =>
5459
return errors;
5560
};
5661

62+
/** @type (pointer: string) => string */
63+
const pointerPop = (pointer) => pointer.replace(/\/[^/]+$/, "");
64+
5765
export default containsErrorHandler;

src/error-handlers/draft-04/maximum.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ const maximumErrorHandler = async (normalizedErrors, instance, localization) =>
1616
continue;
1717
}
1818

19+
const schemaLocations = [schemaLocation];
1920
const parentLocation = pointerPop(schemaLocation);
2021

2122
let exclusive = false;
2223
for (const exclusiveLocation in normalizedErrors["https://json-schema.org/keyword/draft-04/exclusiveMaximum"]) {
23-
const exclusiveParentLocation = pointerPop(exclusiveLocation);
24-
if (exclusiveParentLocation === parentLocation) {
24+
if (pointerPop(exclusiveLocation) === parentLocation) {
25+
schemaLocations.push(exclusiveLocation);
2526
const exclusiveNode = await getSchema(exclusiveLocation);
2627
exclusive = /** @type boolean */ (Schema.value(exclusiveNode));
2728
break;
@@ -35,13 +36,13 @@ const maximumErrorHandler = async (normalizedErrors, instance, localization) =>
3536
errors.push({
3637
message: localization.getExclusiveMaximumErrorMessage(maximum),
3738
instanceLocation: Instance.uri(instance),
38-
schemaLocations: [schemaLocation]
39+
schemaLocations: schemaLocations
3940
});
4041
} else {
4142
errors.push({
4243
message: localization.getMaximumErrorMessage(maximum),
4344
instanceLocation: Instance.uri(instance),
44-
schemaLocations: [schemaLocation]
45+
schemaLocations: schemaLocations
4546
});
4647
}
4748
}

src/error-handlers/draft-04/minimum.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ const minimumErrorHandler = async (normalizedErrors, instance, localization) =>
1616
continue;
1717
}
1818

19+
const schemaLocations = [schemaLocation];
1920
const parentLocation = pointerPop(schemaLocation);
2021

2122
let exclusive = false;
2223
for (const exclusiveLocation in normalizedErrors["https://json-schema.org/keyword/draft-04/exclusiveMinimum"]) {
23-
const exclusiveParentLocation = pointerPop(exclusiveLocation);
24-
if (exclusiveParentLocation === parentLocation) {
24+
if (pointerPop(exclusiveLocation) === parentLocation) {
25+
schemaLocations.push(exclusiveLocation);
2526
const exclusiveNode = await getSchema(exclusiveLocation);
2627
exclusive = /** @type boolean */ (Schema.value(exclusiveNode));
2728
break;
@@ -35,13 +36,13 @@ const minimumErrorHandler = async (normalizedErrors, instance, localization) =>
3536
errors.push({
3637
message: localization.getExclusiveMinimumErrorMessage(minimum),
3738
instanceLocation: Instance.uri(instance),
38-
schemaLocations: [schemaLocation]
39+
schemaLocations: schemaLocations
3940
});
4041
} else {
4142
errors.push({
4243
message: localization.getMinimumErrorMessage(minimum),
4344
instanceLocation: Instance.uri(instance),
44-
schemaLocations: [schemaLocation]
45+
schemaLocations: schemaLocations
4546
});
4647
}
4748
}

src/test-suite/tests/maximum.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@
7070
"exclusiveMaximum": "3"
7171
},
7272
"instanceLocation": "#",
73-
"schemaLocations": ["#/maximum"]
73+
"schemaLocations": [
74+
"#/maximum",
75+
"#/exclusiveMaximum"
76+
]
7477
}
7578
]
7679
},

src/test-suite/tests/minimum.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@
7070
"exclusiveMinimum": "3"
7171
},
7272
"instanceLocation": "#",
73-
"schemaLocations": ["#/minimum"]
73+
"schemaLocations": [
74+
"#/minimum",
75+
"#/exclusiveMinimum"
76+
]
7477
}
7578
]
7679
},

0 commit comments

Comments
 (0)