From 75384bb5bcbb959c2566fad354f6a5d0272b3d85 Mon Sep 17 00:00:00 2001 From: Yannik Tausch Date: Tue, 7 Jan 2025 15:30:53 +0100 Subject: [PATCH 1/3] add test for #952 --- test/hover.test.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/hover.test.ts b/test/hover.test.ts index 404ed676..5dbc6d55 100644 --- a/test/hover.test.ts +++ b/test/hover.test.ts @@ -764,6 +764,32 @@ Source: [${SCHEMA_ID}](file:///${SCHEMA_ID})` ); expect(telemetry.messages).to.be.empty; }); + it('should show the parent description in anyOf (no child descriptions)', async () => { + schemaProvider.addSchema(SCHEMA_ID, { + title: 'The Root', + description: 'Root Object', + type: 'object', + properties: { + optionalZipFile: { + title: 'ZIP file', + anyOf: [{ type: "string", pattern: "\\.zip$" }, { type: "null" }], + default: null, + description: "Optional ZIP file path." + }, + }, + required: ['optionalZipFile'], + additionalProperties: false, + }); + let content = 'optionalZipF|i|le:'; + let result = await parseSetup(content); + + assert.strictEqual(MarkupContent.is(result.contents), true); + assert.strictEqual( + (result.contents as MarkupContent).value, + `#### ZIP file || ZIP file\n\nOptional ZIP file path.\n\nSource: [${SCHEMA_ID}](file:///${SCHEMA_ID})` + ); + expect(telemetry.messages).to.be.empty; + }); }); describe('Bug fixes', () => { From 6be8db3c38152540dce04826328646aca2f71f9a Mon Sep 17 00:00:00 2001 From: Yannik Tausch Date: Tue, 7 Jan 2025 15:55:46 +0100 Subject: [PATCH 2/3] display parent description for anyOf --- src/languageservice/services/yamlHover.ts | 4 +- test/hover.test.ts | 72 ++++++++++++++++++++++- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/src/languageservice/services/yamlHover.ts b/src/languageservice/services/yamlHover.ts index f02c29d1..f30eab3a 100644 --- a/src/languageservice/services/yamlHover.ts +++ b/src/languageservice/services/yamlHover.ts @@ -103,7 +103,7 @@ export class YAMLHover { }; const removePipe = (value: string): string => { - return value.replace(/\|\|\s*$/, ''); + return value.replace(/\s\|\|\s*$/, ''); }; return this.schemaService.getSchemaForResource(document.uri, doc).then((schema) => { @@ -141,7 +141,7 @@ export class YAMLHover { if (s.schema.anyOf && isAllSchemasMatched(node, matchingSchemas, s.schema)) { //if append title and description of all matched schemas on hover title = ''; - markdownDescription = ''; + markdownDescription = s.schema.description ? (s.schema.description + '\n') : ''; s.schema.anyOf.forEach((childSchema: JSONSchema, index: number) => { title += childSchema.title || s.schema.closestTitle || ''; markdownDescription += childSchema.markdownDescription || this.toMarkdown(childSchema.description) || ''; diff --git a/test/hover.test.ts b/test/hover.test.ts index 5dbc6d55..e7017d57 100644 --- a/test/hover.test.ts +++ b/test/hover.test.ts @@ -774,7 +774,7 @@ Source: [${SCHEMA_ID}](file:///${SCHEMA_ID})` title: 'ZIP file', anyOf: [{ type: "string", pattern: "\\.zip$" }, { type: "null" }], default: null, - description: "Optional ZIP file path." + description: "Optional ZIP file path.", }, }, required: ['optionalZipFile'], @@ -790,6 +790,76 @@ Source: [${SCHEMA_ID}](file:///${SCHEMA_ID})` ); expect(telemetry.messages).to.be.empty; }); + it('should concat parent and child descriptions in anyOf', async () => { + schemaProvider.addSchema(SCHEMA_ID, { + title: 'The Root', + description: 'Root Object', + type: 'object', + properties: { + child: { + title: 'Child', + anyOf: [ + { + $ref: '#/definitions/FirstChoice', + }, + { + $ref: '#/definitions/SecondChoice', + }, + ], + description: "The parent description." + }, + }, + required: ['child'], + additionalProperties: false, + definitions: { + FirstChoice: { + title: 'FirstChoice', + description: 'The first choice', + type: 'object', + properties: { + choice: { + title: 'Choice', + default: 'first', + enum: ['first'], + type: 'string', + }, + property_a: { + title: 'Property A', + type: 'string', + }, + }, + required: ['property_a'], + }, + SecondChoice: { + title: 'SecondChoice', + description: 'The second choice', + type: 'object', + properties: { + choice: { + title: 'Choice', + default: 'second', + enum: ['second'], + type: 'string', + }, + property_b: { + title: 'Property B', + type: 'string', + }, + }, + required: ['property_b'], + }, + }, + }); + + let content = 'ch|i|ld:'; + let result = await parseSetup(content); + assert.strictEqual(MarkupContent.is(result.contents), true); + assert.strictEqual( + (result.contents as MarkupContent).value, + `#### FirstChoice || SecondChoice\n\nThe parent description.\nThe first choice || The second choice\n\nSource: [${SCHEMA_ID}](file:///${SCHEMA_ID})` + ); + expect(telemetry.messages).to.be.empty; + }) }); describe('Bug fixes', () => { From 49f1ab443bb4c2c316e963f0d2d7d40eb219a3c6 Mon Sep 17 00:00:00 2001 From: Yannik Tausch Date: Tue, 21 Jan 2025 17:35:13 +0100 Subject: [PATCH 3/3] fix linter issues --- src/languageservice/services/yamlHover.ts | 2 +- test/hover.test.ts | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/languageservice/services/yamlHover.ts b/src/languageservice/services/yamlHover.ts index f30eab3a..39dbac91 100644 --- a/src/languageservice/services/yamlHover.ts +++ b/src/languageservice/services/yamlHover.ts @@ -141,7 +141,7 @@ export class YAMLHover { if (s.schema.anyOf && isAllSchemasMatched(node, matchingSchemas, s.schema)) { //if append title and description of all matched schemas on hover title = ''; - markdownDescription = s.schema.description ? (s.schema.description + '\n') : ''; + markdownDescription = s.schema.description ? s.schema.description + '\n' : ''; s.schema.anyOf.forEach((childSchema: JSONSchema, index: number) => { title += childSchema.title || s.schema.closestTitle || ''; markdownDescription += childSchema.markdownDescription || this.toMarkdown(childSchema.description) || ''; diff --git a/test/hover.test.ts b/test/hover.test.ts index e7017d57..9fd6041e 100644 --- a/test/hover.test.ts +++ b/test/hover.test.ts @@ -772,16 +772,16 @@ Source: [${SCHEMA_ID}](file:///${SCHEMA_ID})` properties: { optionalZipFile: { title: 'ZIP file', - anyOf: [{ type: "string", pattern: "\\.zip$" }, { type: "null" }], + anyOf: [{ type: 'string', pattern: '\\.zip$' }, { type: 'null' }], default: null, - description: "Optional ZIP file path.", + description: 'Optional ZIP file path.', }, }, required: ['optionalZipFile'], additionalProperties: false, }); - let content = 'optionalZipF|i|le:'; - let result = await parseSetup(content); + const content = 'optionalZipF|i|le:'; + const result = await parseSetup(content); assert.strictEqual(MarkupContent.is(result.contents), true); assert.strictEqual( @@ -806,7 +806,7 @@ Source: [${SCHEMA_ID}](file:///${SCHEMA_ID})` $ref: '#/definitions/SecondChoice', }, ], - description: "The parent description." + description: 'The parent description.', }, }, required: ['child'], @@ -851,15 +851,15 @@ Source: [${SCHEMA_ID}](file:///${SCHEMA_ID})` }, }); - let content = 'ch|i|ld:'; - let result = await parseSetup(content); + const content = 'ch|i|ld:'; + const result = await parseSetup(content); assert.strictEqual(MarkupContent.is(result.contents), true); assert.strictEqual( (result.contents as MarkupContent).value, `#### FirstChoice || SecondChoice\n\nThe parent description.\nThe first choice || The second choice\n\nSource: [${SCHEMA_ID}](file:///${SCHEMA_ID})` ); expect(telemetry.messages).to.be.empty; - }) + }); }); describe('Bug fixes', () => {