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 + ); + }); });