From ce643a9b89c84d3d457637840481bb2da74c101c Mon Sep 17 00:00:00 2001 From: Petr Spacek Date: Wed, 15 May 2024 11:50:07 +0200 Subject: [PATCH] fix: array default value --- .../services/yamlCompletion.ts | 15 +++- test/autoCompletion.test.ts | 84 +++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/src/languageservice/services/yamlCompletion.ts b/src/languageservice/services/yamlCompletion.ts index 513a23d6..6025f67f 100644 --- a/src/languageservice/services/yamlCompletion.ts +++ b/src/languageservice/services/yamlCompletion.ts @@ -1277,7 +1277,12 @@ export class YamlCompletion { if (Array.isArray(value)) { let insertText = '\n'; for (const arrValue of value) { - insertText += `${indent}- \${${navOrder.index++}:${arrValue}}\n`; + if (typeof arrValue === 'object') { + const objectText = this.getInsertTemplateForValue(arrValue, indent, { ...navOrder }, separatorAfter); + insertText += convertObjectToArrayItem(objectText, indent); + } else { + insertText += `${indent}- \${${navOrder.index++}:${arrValue}}\n`; + } } return insertText; } else if (typeof value === 'object') { @@ -1729,3 +1734,11 @@ function evaluateTab1Symbol(value: string): string { function isParentCompletionItem(item: CompletionItemBase): item is CompletionItem { return 'parent' in item; } + +export function convertObjectToArrayItem(objectText: string, indent: string): string { + const objectItem = objectText.replace(/^(\s+)/gm, (match, _, index) => { + // first line can contains newLine, so use indent from input parameter + return index === 0 ? `${indent}- ` : `${match} `; + }); + return objectItem; +} diff --git a/test/autoCompletion.test.ts b/test/autoCompletion.test.ts index eba8fa6d..37c8c76e 100644 --- a/test/autoCompletion.test.ts +++ b/test/autoCompletion.test.ts @@ -21,6 +21,7 @@ import { expect } from 'chai'; import { SettingsState, TextDocumentTestManager } from '../src/yamlSettings'; import { LanguageService } from '../src'; import { LanguageHandlers } from '../src/languageserver/handlers/languageHandlers'; +import { convertObjectToArrayItem } from '../src/languageservice/services/yamlCompletion'; describe('Auto Completion Tests', () => { let languageSettingsSetup: ServiceSetup; @@ -931,6 +932,89 @@ describe('Auto Completion Tests', () => { ); }); + it('Autocompletion with default value as an object', async () => { + schemaProvider.addSchema(SCHEMA_ID, { + type: 'object', + properties: { + car: { + type: 'object', + default: { + engine: { + fuel: 'gasoline', + }, + wheel: 4, + }, + }, + }, + }); + const content = 'car: |\n|'; + const completion = await parseSetup(content); + expect(completion.items.map((i) => i.insertText)).to.deep.equal([ + '\n ${1:engine}:\n ${2:fuel}: ${3:gasoline}\n ${4:wheel}: ${5:4}\n', + ]); + }); + + it('Autocompletion with default value as an array', async () => { + schemaProvider.addSchema(SCHEMA_ID, { + type: 'object', + properties: { + garage: { + type: 'array', + items: { + type: 'object', + }, + default: [ + { + car: { + engine: { fuel: 'gasoline' }, + wheel: [1, 2], + }, + }, + { + car: { + engine: { fuel: 'diesel' }, + }, + }, + ], + }, + }, + }); + const content = 'garage: |\n|'; + const completion = await parseSetup(content); + const expected = ` + - \${1:car}: + \${2:engine}: + \${3:fuel}: \${4:gasoline} + \${5:wheel}: + - \${6:1} + - \${7:2} + - \${1:car}: + \${2:engine}: + \${3:fuel}: \${4:diesel} +`; + expect(completion.items.map((i) => i.insertText)).to.deep.equal([expected]); + }); + + it('should convert object to array item', () => { + const objectText = ` + car: + engine: + fuel: gasoline + wheel: + - 1 + - 2 +`; + const expectedArrayItem = ` - car: + engine: + fuel: gasoline + wheel: + - 1 + - 2 +`; + const arrayItem = convertObjectToArrayItem(objectText, ' '); + expect(arrayItem).to.equal(expectedArrayItem); + }); + it('Autocompletion should escape colon when indicating map', async () => { schemaProvider.addSchema(SCHEMA_ID, { type: 'object',