From c2c297943bc4b471f8f5401af95fb81e2914f24c Mon Sep 17 00:00:00 2001
From: Petr Spacek
Date: Mon, 10 Jul 2023 07:47:29 +0200
Subject: [PATCH] fix: nested anyof const (#888)
* fix: nested anyof const
* fix: test and const partial match when callFromAutoComplete
---
src/languageservice/parser/jsonParser07.ts | 9 +++-
src/languageservice/utils/objects.ts | 2 +-
test/schemaValidation.test.ts | 50 ++++++++++++++++++++++
3 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/src/languageservice/parser/jsonParser07.ts b/src/languageservice/parser/jsonParser07.ts
index ce5715ff6..a9bb2d48d 100644
--- a/src/languageservice/parser/jsonParser07.ts
+++ b/src/languageservice/parser/jsonParser07.ts
@@ -786,6 +786,10 @@ function validate(
validationResult.merge(bestMatch.validationResult);
validationResult.propertiesMatches += bestMatch.validationResult.propertiesMatches;
validationResult.propertiesValueMatches += bestMatch.validationResult.propertiesValueMatches;
+ validationResult.enumValueMatch = validationResult.enumValueMatch || bestMatch.validationResult.enumValueMatch;
+ if (bestMatch.validationResult.enumValues?.length) {
+ validationResult.enumValues = (validationResult.enumValues || []).concat(bestMatch.validationResult.enumValues);
+ }
matchingSchemas.merge(bestMatch.matchingSchemas);
}
return matches.length;
@@ -890,7 +894,10 @@ function validate(
if (isDefined(schema.const)) {
const val = getNodeValue(node);
- if (!equals(val, schema.const)) {
+ if (
+ !equals(val, schema.const) &&
+ !(callFromAutoComplete && isString(val) && isString(schema.const) && schema.const.startsWith(val))
+ ) {
validationResult.problems.push({
location: { offset: node.offset, length: node.length },
severity: DiagnosticSeverity.Warning,
diff --git a/src/languageservice/utils/objects.ts b/src/languageservice/utils/objects.ts
index 19d011e13..7337cf948 100644
--- a/src/languageservice/utils/objects.ts
+++ b/src/languageservice/utils/objects.ts
@@ -62,7 +62,7 @@ export function isNumber(val: unknown): val is number {
}
// eslint-disable-next-line @typescript-eslint/ban-types
-export function isDefined(val: unknown): val is object {
+export function isDefined(val: unknown): val is object | string | number | boolean {
return typeof val !== 'undefined';
}
diff --git a/test/schemaValidation.test.ts b/test/schemaValidation.test.ts
index 42d6cd5af..71268db7b 100644
--- a/test/schemaValidation.test.ts
+++ b/test/schemaValidation.test.ts
@@ -1974,4 +1974,54 @@ obj:
expect(telemetry.messages).to.be.empty;
});
});
+ it('Nested AnyOf const should correctly evaluate and merge problems', async () => {
+ // note that 'missing form property' is necessary to trigger the bug (there has to be some problem in both subSchemas)
+ // order of the object in `anyOf` is also important
+ const schema: JSONSchema = {
+ type: 'object',
+ properties: {
+ options: {
+ anyOf: [
+ {
+ type: 'object',
+ properties: {
+ form: {
+ type: 'string',
+ },
+ provider: {
+ type: 'string',
+ const: 'test1',
+ },
+ },
+ required: ['form', 'provider'],
+ },
+ {
+ type: 'object',
+ properties: {
+ form: {
+ type: 'string',
+ },
+ provider: {
+ anyOf: [
+ {
+ type: 'string',
+ const: 'testX',
+ },
+ ],
+ },
+ },
+ required: ['form', 'provider'],
+ },
+ ],
+ },
+ },
+ };
+ schemaProvider.addSchema(SCHEMA_ID, schema);
+ const content = `options:\n provider: testX`;
+ const result = await parseSetup(content);
+ assert.deepEqual(
+ result.map((e) => e.message),
+ ['Missing property "form".'] // not inclide provider error
+ );
+ });
});