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',