Skip to content

Commit

Permalink
Merge pull request #390 from p-spacek/fix/completion-array
Browse files Browse the repository at this point in the history
fix: Completion array anyOf
  • Loading branch information
JPinkney authored Jan 15, 2021
2 parents a18a018 + 252c1e8 commit 80a34d4
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 1 deletion.
34 changes: 33 additions & 1 deletion src/languageservice/services/yamlCompletion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { stringifyObject, StringifySettings } from '../utils/json';
import { guessIndentation } from '../utils/indentationGuesser';
import { TextBuffer } from '../utils/textBuffer';
import { setKubernetesParserOption } from '../parser/isKubernetes';
import { ClientCapabilities } from 'vscode-languageserver';
import { ClientCapabilities, MarkupContent } from 'vscode-languageserver';
const localize = nls.loadMessageBundle();

export class YAMLCompletion extends JSONCompletion {
Expand Down Expand Up @@ -393,6 +393,25 @@ export class YAMLCompletion extends JSONCompletion {
insertTextFormat: InsertTextFormat.Snippet,
});
this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types);
} else if (typeof s.schema.items === 'object' && s.schema.items.anyOf) {
s.schema.items.anyOf
.filter((i) => typeof i === 'object')
.forEach((i: JSONSchema, index) => {
const insertText = `- ${this.getInsertTextForObject(i, separatorAfter).insertText.trimLeft()}`;
//append insertText to documentation
const documentation = this.getDocumentationWithMarkdownText(
`Create an item of an array${s.schema.description === undefined ? '' : '(' + s.schema.description + ')'}`,
insertText
);
collector.add({
kind: super.getSuggestionKind(i.type),
label: '- (array item) ' + (index + 1),
documentation: documentation,
insertText: insertText,
insertTextFormat: InsertTextFormat.Snippet,
});
});
this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types);
} else {
this.addSchemaValueCompletions(s.schema.items, separatorAfter, collector, types);
}
Expand Down Expand Up @@ -1004,6 +1023,19 @@ export class YAMLCompletion extends JSONCompletion {
private is_EOL(c: number): boolean {
return c === 0x0a /* LF */ || c === 0x0d /* CR */;
}

private getDocumentationWithMarkdownText(documentation: string, insertText: string): string | MarkupContent {
let res: string | MarkupContent = documentation;
if (super.doesSupportMarkdown()) {
insertText = insertText
.replace(/\${[0-9]+[:|](.*)}/g, (s, arg) => {
return arg;
})
.replace(/\$([0-9]+)/g, '');
res = super.fromMarkup(`${documentation}\n \`\`\`\n${insertText}\n\`\`\``) as MarkupContent;
}
return res;
}
}

const isNumberExp = /^\d+$/;
Expand Down
78 changes: 78 additions & 0 deletions test/autoCompletion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1730,5 +1730,83 @@ suite('Auto Completion Tests', () => {
);
});
});
describe('Array completion', () => {
it('Simple array object completion with "-" without any item', async () => {
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
languageService.addSchema(SCHEMA_ID, schema);
const content = 'test_simpleArrayObject:\n -';
const completion = parseSetup(content, content.length);
completion.then(function (result) {
assert.equal(result.items.length, 1);
assert.equal(result.items[0].label, '- (array item)');
});
});

it('Simple array object completion without "-" after array item', async () => {
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
languageService.addSchema(SCHEMA_ID, schema);
const content = 'test_simpleArrayObject:\n - obj1:\n name: 1\n ';
const completion = parseSetup(content, content.length);
completion.then(function (result) {
assert.equal(result.items.length, 1);
assert.equal(result.items[0].label, '- (array item)');
});
});

it('Simple array object completion with "-" after array item', async () => {
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
languageService.addSchema(SCHEMA_ID, schema);
const content = 'test_simpleArrayObject:\n - obj1:\n name: 1\n -';
const completion = parseSetup(content, content.length);
completion.then(function (result) {
assert.equal(result.items.length, 1);
assert.equal(result.items[0].label, '- (array item)');
});
});

it('Array anyOf two objects completion with "- " without any item', async () => {
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
languageService.addSchema(SCHEMA_ID, schema);
const content = 'test_array_anyOf_2objects:\n - ';
const completion = parseSetup(content, content.length);
completion.then(function (result) {
assert.equal(result.items.length, 2);
assert.equal(result.items[0].label, 'obj1');
});
});

it('Array anyOf two objects completion with "-" without any item', async () => {
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
languageService.addSchema(SCHEMA_ID, schema);
const content = 'test_array_anyOf_2objects:\n -';
const completion = parseSetup(content, content.length);
completion.then(function (result) {
assert.equal(result.items.length, 2);
assert.equal(result.items[0].label, '- (array item) 1');
});
});

it('Array anyOf two objects completion without "-" after array item', async () => {
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
languageService.addSchema(SCHEMA_ID, schema);
const content = 'test_array_anyOf_2objects:\n - obj1:\n name: 1\n ';
const completion = parseSetup(content, content.length);
completion.then(function (result) {
assert.equal(result.items.length, 2);
assert.equal(result.items[0].label, '- (array item) 1');
});
});

it('Array anyOf two objects completion with "-" after array item', async () => {
const schema = require(path.join(__dirname, './fixtures/testArrayCompletionSchema.json'));
languageService.addSchema(SCHEMA_ID, schema);
const content = 'test_array_anyOf_2objects:\n - obj1:\n name: 1\n -';
const completion = parseSetup(content, content.length);
completion.then(function (result) {
assert.equal(result.items.length, 2);
assert.equal(result.items[0].label, '- (array item) 1');
});
});
});
});
});
85 changes: 85 additions & 0 deletions test/fixtures/testArrayCompletionSchema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"obj1": {
"properties": {
"obj1": {
"type": "object"
}
},
"required": [
"obj1"
],
"type": "object"
},
"obj2": {
"properties": {
"obj2": {
"type": "object"
}
},
"required": [
"obj2"
],
"type": "object"
}
},
"properties": {
"test_simpleArrayObject": {
"items": {
"$ref": "#/definitions/obj1"
},
"type": "array"
},
"test_array_anyOf_2objects": {
"items": {
"anyOf": [
{
"$ref": "#/definitions/obj1"
},
{
"$ref": "#/definitions/obj2"
}
]
},
"type": "array"
},
"test_array_anyOf_strAndObj": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/obj1"
}
]
},
"type": "array"
},
"test_anyOfObjectAndNull": {
"anyOf": [
{
"$ref": "#/definitions/obj1"
},
{
"type": "null"
}
]
},
"test_anyOfArrAndNull": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
]
}
},
"type": "object"
}

0 comments on commit 80a34d4

Please sign in to comment.