Files
ry.kazcloud.dev/node_modules/yaml-language-server/out/server/test/autoCompletionFix.test.js

1197 lines
52 KiB
JavaScript

"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Red Hat. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
const yamlSettings_1 = require("../src/yamlSettings");
const serviceSetup_1 = require("./utils/serviceSetup");
const testHelper_1 = require("./utils/testHelper");
const chai_1 = require("chai");
const verifyError_1 = require("./utils/verifyError");
const path = require("path");
describe('Auto Completion Fix Tests', () => {
let languageSettingsSetup;
let languageService;
let languageHandler;
let yamlSettings;
let schemaProvider;
before(() => {
languageSettingsSetup = new serviceSetup_1.ServiceSetup().withCompletion().withSchemaFileMatch({
uri: 'https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.22.4-standalone-strict/all.json',
fileMatch: [testHelper_1.SCHEMA_ID],
});
const { languageService: langService, languageHandler: langHandler, yamlSettings: settings, schemaProvider: testSchemaProvider, } = (0, testHelper_1.setupLanguageService)(languageSettingsSetup.languageSettings);
languageService = langService;
languageHandler = langHandler;
yamlSettings = settings;
schemaProvider = testSchemaProvider;
});
/**
* Generates a completion list for the given document and caret (cursor) position.
* @param content The content of the document.
* @param line starts with 0 index
* @param character starts with 1 index
* @returns A list of valid completions.
*/
function parseSetup(content, line, character) {
const testTextDocument = (0, testHelper_1.setupSchemaIDTextDocument)(content);
yamlSettings.documents = new yamlSettings_1.TextDocumentTestManager();
yamlSettings.documents.set(testTextDocument);
return languageHandler.completionHandler({
position: vscode_languageserver_types_1.Position.create(line, character),
textDocument: testTextDocument,
});
}
/**
* Generates a completion list for the given document and caret (cursor) position.
* @param content The content of the document.
* The caret is located in the content using `|` bookends.
* For example, `content = 'ab|c|d'` places the caret over the `'c'`, at `position = 2`
* @returns A list of valid completions.
*/
function parseCaret(content) {
const { position, content: content2 } = (0, testHelper_1.caretPosition)(content);
const testTextDocument = (0, testHelper_1.setupSchemaIDTextDocument)(content2);
yamlSettings.documents = new yamlSettings_1.TextDocumentTestManager();
yamlSettings.documents.set(testTextDocument);
return languageHandler.completionHandler({
position: testTextDocument.positionAt(position),
textDocument: testTextDocument,
});
}
afterEach(() => {
schemaProvider.deleteSchema(testHelper_1.SCHEMA_ID);
languageService.configure(languageSettingsSetup.languageSettings);
});
it('should show completion on map under array', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'array',
items: {
type: 'object',
properties: {
from: {
type: 'object',
properties: {
foo: {
type: 'boolean',
},
},
},
},
},
});
const content = '- from:\n | |'; // len: 12, pos: 11
const completion = await parseCaret(content);
(0, chai_1.expect)(completion.items).lengthOf(1);
(0, chai_1.expect)(completion.items[0]).eql((0, verifyError_1.createExpectedCompletion)('foo', 'foo: ', 1, 3, 1, 4, 10, 2, {
documentation: '',
}));
});
it('completion with array objects', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'array',
items: {
type: 'object',
properties: {
prop1: {
type: 'string',
},
prop2: {
type: 'string',
},
prop3: {
type: 'string',
},
},
},
});
const content = '- prop1: a\n | |'; // len: 12, pos: 11
const completion = await parseCaret(content);
(0, chai_1.expect)(completion.items).lengthOf(2);
(0, chai_1.expect)(completion.items[0]).eql((0, verifyError_1.createExpectedCompletion)('prop2', 'prop2: ', 1, 3, 1, 4, 10, 2, {
documentation: '',
}));
(0, chai_1.expect)(completion.items[1]).eql((0, verifyError_1.createExpectedCompletion)('prop3', 'prop3: ', 1, 3, 1, 4, 10, 2, {
documentation: '',
}));
});
it('should show completion on array empty array item', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'array',
items: {
type: 'object',
properties: {
from: {
type: 'object',
properties: {
foo: {
type: 'boolean',
},
},
},
},
},
});
const content = '- '; // len: 2
const completion = await parseSetup(content, 0, 2);
(0, chai_1.expect)(completion.items).lengthOf(1);
(0, chai_1.expect)(completion.items[0]).eql((0, verifyError_1.createExpectedCompletion)('from', 'from:\n ', 0, 2, 0, 2, 10, 2, {
documentation: '',
}));
});
it('should show completion items in the middle of map in array', async () => {
const content = `apiVersion: v1
kind: Pod
metadata:
name: foo
spec:
containers:
- name: test
image: alpine
`; // len: 90
const completion = await parseSetup(content, 7, 6);
(0, chai_1.expect)(completion.items).length.greaterThan(1);
});
it('should show completion on array item on first line', async () => {
const content = '-d'; // len: 2
const completion = await parseSetup(content, 0, 1);
(0, chai_1.expect)(completion.items).is.empty;
});
it('should complete without error on map inside array', async () => {
const content = '- foo\n- bar:\n so'; // len: 19
const completion = await parseSetup(content, 2, 6);
(0, chai_1.expect)(completion.items).is.empty;
});
it('should complete array', async () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const schema = require(path.join(__dirname, './fixtures/test-nested-object-array.json'));
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = `objA:
- name: nameA1
objB:
size: midle
name: nameB2
`; // len: 67
const completion = await parseSetup(content, 2, 4);
(0, chai_1.expect)(completion.items).is.not.empty;
});
it('should complete array item for "oneOf" schema', async () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const schema = require(path.join(__dirname, './fixtures/test-completion-oneOf.json'));
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = `metadata:
Selector:
query:
-
`; // len: 42
const completion = await parseSetup(content, 3, 8);
(0, chai_1.expect)(completion.items).length(5);
(0, chai_1.expect)(completion.items.map((it) => it.label)).to.have.members(['NOT', 'attribute', 'operation', 'value', 'FUNC_item']);
});
it('Autocomplete with short nextLine - nested object', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
example: {
type: 'object',
properties: {
sample: {
type: 'object',
properties: {
detail: {
type: 'object',
},
},
},
},
},
a: {
type: 'string',
description: 'short prop name because of distance to the cursor',
},
},
});
const content = 'example:\n sample:\n '; // len: 23
const completion = await parseSetup(content + '\na: test', 2, 4);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('detail', 'detail:\n ', 2, 4, 2, 4, 10, 2, {
documentation: '',
}));
});
it('Should suggest valid matches from oneOf', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
oneOf: [
{
type: 'object',
properties: {
spec: {
type: 'object',
},
},
},
{
properties: {
spec: {
type: 'object',
required: ['bar'],
properties: {
bar: {
type: 'string',
},
},
},
},
},
],
});
const content = '|s|'; // len: 1, pos: 1
const completion = await parseCaret(content);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('spec', 'spec:\n bar: ', 0, 0, 0, 1, 10, 2, {
documentation: '',
}));
});
it('Should suggest all the matches from allOf', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
allOf: [
{
type: 'object',
properties: {
spec: {
type: 'object',
},
},
},
{
properties: {
spec: {
type: 'object',
required: ['bar'],
properties: {
bar: {
type: 'string',
},
},
},
},
},
],
});
const content = '|s|'; // len: 1, pos: 1
const completion = await parseCaret(content);
(0, chai_1.expect)(completion.items.length).equal(2);
(0, chai_1.expect)(completion.items[0]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('spec', 'spec:\n ', 0, 0, 0, 1, 10, 2, {
documentation: '',
}));
(0, chai_1.expect)(completion.items[1]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('spec', 'spec:\n bar: ', 0, 0, 0, 1, 10, 2, {
documentation: '',
}));
});
it('Autocomplete with a new line inside the object', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
example: {
type: 'object',
properties: {
sample: {
type: 'object',
properties: {
prop1: {
type: 'string',
},
prop2: {
type: 'string',
},
},
},
},
},
},
});
const content = 'example:\n sample:\n |\n| prop2: value2'; // len: 41, pos: 23
const completion = await parseCaret(content);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('prop1', 'prop1: ', 2, 4, 2, 4, 10, 2, {
documentation: '',
}));
});
it('Autocomplete on the first array item', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
examples: {
type: 'array',
items: {
type: 'object',
properties: {
sample: {
type: 'object',
properties: {
prop1: {
type: 'string',
},
},
},
},
},
},
},
});
const content = 'examples:\n |\n| - sample:\n prop1: value1'; // len: 44, pos: 12
const completion = await parseCaret(content);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('- (array item) object', '- ', 1, 2, 1, 2, 9, 2, {
documentation: {
kind: 'markdown',
value: 'Create an item of an array type `object`\n ```\n- \n```',
},
}));
});
it('Array of enum autocomplete of irregular order', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
apiVersion: {
type: 'string',
},
metadata: {
type: 'object',
properties: {
name: {
type: 'string',
},
},
},
kind: {
type: 'string',
enum: ['Pod', 'PodTemplate'],
},
},
});
const content = 'kind: Po'; // len: 8
const completion = await parseSetup(content, 1, 9);
(0, chai_1.expect)(completion.items.length).equal(2);
(0, chai_1.expect)(completion.items[0].insertText).equal('Pod');
(0, chai_1.expect)(completion.items[1].insertText).equal('PodTemplate');
});
it('Test that properties have enum of string type with number', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
version: {
type: 'array',
items: {
enum: ['12.1', 13, '13.1', '14.0', 'all', 14.4, false, null, ['test']],
type: ['string', 'integer', 'number', 'boolean', 'object', 'array'],
},
},
},
});
const content = 'version:\n - ';
const completion = await parseSetup(content, 2, 0);
(0, chai_1.expect)(completion.items).lengthOf(9);
(0, chai_1.expect)(completion.items[0].insertText).equal('"12.1"');
(0, chai_1.expect)(completion.items[1].insertText).equal('13');
(0, chai_1.expect)(completion.items[4].insertText).equal('all');
(0, chai_1.expect)(completion.items[5].insertText).equal('14.4');
(0, chai_1.expect)(completion.items[6].insertText).equal('false');
(0, chai_1.expect)(completion.items[7].insertText).equal('null');
(0, chai_1.expect)(completion.items[8].insertText).equal('\n - ${1:test}\n');
});
it('Autocomplete indent on array when parent is array', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
examples: {
type: 'array',
items: {
type: 'object',
properties: {
objectWithArray: {
type: 'array',
items: {
type: 'string',
},
},
},
},
},
},
});
const content = 'examples:\n - '; // len: 14
const completion = await parseSetup(content, 1, 4);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('objectWithArray', 'objectWithArray:\n - ${1}', 1, 4, 1, 4, 10, 2, {
documentation: '',
}));
});
it('Autocomplete indent on array object when parent is array', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
examples: {
type: 'array',
items: {
type: 'object',
properties: {
objectWithArray: {
type: 'array',
items: {
type: 'object',
required: ['item', 'item2'],
properties: {
item: { type: 'string' },
item2: { type: 'string' },
},
},
},
},
},
},
},
});
const content = 'examples:\n - '; // len: 14
const completion = await parseSetup(content, 1, 4);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('objectWithArray', 'objectWithArray:\n - item: $1\n item2: $2', 1, 4, 1, 4, 10, 2, {
documentation: '',
}));
});
it('Autocomplete indent on array object when parent is array of an array', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
array1: {
type: 'array',
items: {
type: 'object',
required: ['thing1'],
properties: {
thing1: {
type: 'object',
required: ['array2'],
properties: {
array2: {
type: 'array',
items: {
type: 'object',
required: ['thing2', 'type'],
properties: {
type: {
type: 'string',
},
thing2: {
type: 'object',
required: ['item1', 'item2'],
properties: {
item1: { type: 'string' },
item2: { type: 'string' },
},
},
},
},
},
},
},
},
},
},
},
});
const content = 'array1:\n - ';
const completion = await parseSetup(content, 1, 4);
(0, chai_1.expect)(completion.items[0].insertText).to.be.equal('thing1:\n array2:\n - type: $1\n thing2:\n item1: $2\n item2: $3');
});
describe('array indent on different index position', () => {
const schema = {
type: 'object',
properties: {
objectWithArray: {
type: 'array',
items: {
type: 'object',
required: ['item', 'item2'],
properties: {
item: { type: 'string' },
item2: {
type: 'object',
required: ['prop1', 'prop2'],
properties: {
prop1: { type: 'string' },
prop2: { type: 'string' },
},
},
},
},
},
},
};
it('array indent on the first item', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'objectWithArray:\n - '; // len: 21
const completion = await parseSetup(content, 1, 4);
(0, chai_1.expect)(completion.items.length).equal(3);
(0, chai_1.expect)(completion.items[0]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('item', 'item: ', 1, 4, 1, 4, 10, 2, {
documentation: '',
}));
(0, chai_1.expect)(completion.items[2]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('item2', 'item2:\n prop1: $1\n prop2: $2', 1, 4, 1, 4, 10, 2, {
documentation: '',
}));
});
it('array indent on the second item', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'objectWithArray:\n - item: first line\n '; // len: 42
const completion = await parseSetup(content, 2, 4);
(0, chai_1.expect)(completion.items.length).equal(2);
(0, chai_1.expect)(completion.items[0]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('item2', 'item2:\n prop1: $1\n prop2: $2', 2, 4, 2, 4, 10, 2, {
documentation: '',
}));
});
});
describe('merge properties from anyOf objects', () => {
it('should merge different simple values', async () => {
const schema = {
anyOf: [
{
properties: {
simplePropWithSimpleValue: { type: 'string', const: 'const value' },
},
},
{
properties: {
simplePropWithSimpleValue: { type: 'boolean', default: false },
},
},
{
properties: {
simplePropWithSimpleValue: { type: 'null', default: null },
},
},
{
properties: {
simplePropWithSimpleValue: { type: 'string' },
},
},
],
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = '';
const completion = await parseSetup(content, 0, 1);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0].insertText).to.be.equal('simplePropWithSimpleValue: ${1|const value,false,null|}');
});
it('should autocomplete as single item with same value', async () => {
const schema = {
anyOf: [
{
properties: {
simplePropWithSameValue: { type: 'string', const: 'const value 1' },
obj1: { properties: { prop1: { type: 'string' } } },
},
},
{
properties: {
simplePropWithSameValue: { type: 'string', const: 'const value 1' },
obj1: { properties: { prop1: { type: 'string' } } },
},
},
],
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = '';
const completion = await parseSetup(content, 0, 1);
(0, chai_1.expect)(completion.items.length).equal(2);
(0, chai_1.expect)(completion.items[0].insertText).to.be.equal('simplePropWithSameValue: const value 1');
(0, chai_1.expect)(completion.items[1].insertText).to.be.equal('obj1:\n ');
});
it('should not merge objects', async () => {
const schema = {
anyOf: [
{
properties: {
obj1: { properties: { prop1: { type: 'string' } }, required: ['prop1'] },
},
},
{
properties: {
obj1: { properties: { prop2: { type: 'string', const: 'value' } }, required: ['prop2'] },
},
},
],
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = '';
const completion = await parseSetup(content, 0, 1);
(0, chai_1.expect)(completion.items.length).equal(2);
(0, chai_1.expect)(completion.items[0].label).to.be.equal('obj1');
(0, chai_1.expect)(completion.items[0].insertText).to.be.equal('obj1:\n prop1: ');
(0, chai_1.expect)(completion.items[1].label).to.be.equal('obj1');
(0, chai_1.expect)(completion.items[1].insertText).to.be.equal('obj1:\n prop2: ${1:value}');
});
it('Autocomplete should not suggest items for parent object', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
scripts: {
type: 'object',
properties: {
sample: {
type: 'string',
},
},
},
scripts2: {
type: 'string',
},
},
});
const content = 'scripts: \n sample: | |';
const completion = await parseSetup(content, 0, 9); // before line brake
(0, chai_1.expect)(completion.items.length).equal(0);
});
it('autoCompletion when value is null inside anyOf object', async () => {
const schema = {
anyOf: [
{
properties: {
prop: {
const: 'const value',
},
},
},
{
properties: {
prop: {
type: 'null',
},
},
},
],
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = '';
const completion = await parseSetup(content, 0, 6);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0].label).to.be.equal('prop');
(0, chai_1.expect)(completion.items[0].insertText).to.be.equal('prop: ${1|const value,null|}');
});
});
describe('extra space after cursor', () => {
it('simple const', async () => {
const schema = {
properties: {
prop: {
const: 'const',
},
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'prop: | | '; // len: 8, pos: 6
const completion = await parseCaret(content);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0].label).to.be.equal('const');
(0, chai_1.expect)(completion.items[0].textEdit).to.be.deep.equal({ newText: 'const', range: vscode_languageserver_types_1.Range.create(0, 6, 0, 8) });
});
it('partial key with trailing spaces', async () => {
const schema = {
properties: {
name: {
const: 'my name',
},
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'na ';
const completion = await parseSetup(content, 0, 2);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).eql((0, verifyError_1.createExpectedCompletion)('name', 'name: my name', 0, 0, 0, 4, 10, 2, {
documentation: '',
}));
});
it('partial key with trailing spaces with new line', async () => {
const schema = {
properties: {
name: {
const: 'my name',
},
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'na \n';
const completion = await parseSetup(content, 0, 2);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).eql((0, verifyError_1.createExpectedCompletion)('name', 'name: my name', 0, 0, 0, 5, 10, 2, {
documentation: '',
}));
});
it('partial key with leading and trailing spaces', async () => {
const schema = {
properties: {
name: {
const: 'my name',
},
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = ' na ';
const completion = await parseSetup(content, 0, 2);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).eql((0, verifyError_1.createExpectedCompletion)('name', 'name: my name', 0, 2, 0, 4, 10, 2, {
documentation: '',
}));
});
it('partial key with trailing spaces with special chars inside the array', async () => {
const schema = {
type: 'object',
properties: {
array: {
type: 'array',
items: {
type: 'object',
properties: {
'name / 123': {
const: 'my name',
},
},
},
},
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'array:\n - name / ';
const completion = await parseSetup(content, 1, 9);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).eql((0, verifyError_1.createExpectedCompletion)('name / 123', 'name / 123: my name', 1, 3, 1, 12, 10, 2, {
documentation: '',
}));
});
describe('partial value with trailing spaces', () => {
it('partial value with trailing spaces', async () => {
const schema = {
properties: {
name: {
const: 'my name',
},
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'name: my| | ';
const completion = await parseCaret(content);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).eql((0, verifyError_1.createExpectedCompletion)('my name', 'my name', 0, 6, 0, 12, 12, 2, {
documentation: undefined,
}));
});
it('partial value with trailing spaces with new line', async () => {
const schema = {
properties: {
name: {
const: 'my name',
},
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'name: my| | \n';
const completion = await parseCaret(content);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).eql((0, verifyError_1.createExpectedCompletion)('my name', 'my name', 0, 6, 0, 13, 12, 2, {
documentation: undefined,
}));
});
it('partial value with leading and trailing spaces', async () => {
const schema = {
properties: {
name: {
const: 'my name',
},
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'name: my na| | ';
const completion = await parseCaret(content);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).eql((0, verifyError_1.createExpectedCompletion)('my name', 'my name', 0, 6, 0, 17, 12, 2, {
documentation: undefined,
}));
});
it('partial value with trailing spaces with special chars inside the array', async () => {
const schema = {
type: 'object',
properties: {
array: {
type: 'array',
items: {
type: 'object',
properties: {
name: {
const: 'my name / 123',
},
},
},
},
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'array:\n - name: my name /| | ';
const completion = await parseCaret(content);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).eql((0, verifyError_1.createExpectedCompletion)('my name / 123', 'my name / 123', 1, 9, 1, 21, 12, 2, {
documentation: undefined,
}));
});
});
it('object - 2nd nested property', async () => {
const schema = {
properties: {
parent: {
properties: {
prop1: {
const: 'const1',
},
prop2: {
const: 'const2',
},
},
},
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'parent:\n prop1: const1\n prop2: ';
const completion = await parseSetup(content, 2, 9);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0].label).to.be.equal('const2');
(0, chai_1.expect)(completion.items[0].textEdit).to.be.deep.equal({
newText: 'const2',
range: vscode_languageserver_types_1.Range.create(2, 9, 2, 11),
});
});
it('array - 2nd nested property', async () => {
const schema = {
properties: {
arrayObj: {
type: 'array',
items: {
type: 'object',
properties: {
item1: {
type: 'string',
},
item2: {
const: 'const2',
},
},
required: ['item1', 'item2'],
},
},
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'arrayObj:\n - item1: test\n - item2: ';
const completion = await parseSetup(content, 2, 11);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0].label).to.be.equal('const2');
(0, chai_1.expect)(completion.items[0].textEdit).to.be.deep.equal({
newText: 'const2',
range: vscode_languageserver_types_1.Range.create(2, 11, 2, 13),
});
});
describe('array object item', () => {
const schema = {
properties: {
arrayObj: {
type: 'array',
items: {
type: 'object',
properties: {
item1: {
type: 'string',
},
item2: {
type: 'string',
},
},
required: ['item1', 'item2'],
},
},
},
};
it('1st item', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'arrayObj:\n - ';
const completion = await parseSetup(content, 1, 4);
(0, chai_1.expect)(completion.items.length).equal(3);
(0, chai_1.expect)(completion.items[1].textEdit).to.be.deep.equal({
newText: 'item1: $1\n item2: $2',
range: vscode_languageserver_types_1.Range.create(1, 4, 1, 6), // removes extra spaces after cursor
});
});
it('next item', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'arrayObj:\n - item1: a\n - item2: b\n - ';
const completion = await parseSetup(content, 3, 4);
(0, chai_1.expect)(completion.items.length).equal(3);
(0, chai_1.expect)(completion.items[1].textEdit).to.be.deep.equal({
newText: 'item1: $1\n item2: $2',
range: vscode_languageserver_types_1.Range.create(3, 4, 3, 6), // removes extra spaces after cursor
});
});
});
it('array completion - should suggest correct indent when extra spaces after cursor', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
test: {
type: 'array',
items: {
type: 'object',
properties: {
objA: {
type: 'object',
required: ['itemA'],
properties: {
itemA: {
type: 'string',
},
},
},
},
},
},
},
});
const content = 'test:\n - ';
const result = await parseSetup(content, 1, 4);
(0, chai_1.expect)(result.items.length).to.be.equal(1);
(0, chai_1.expect)(result.items[0].insertText).to.be.equal('objA:\n itemA: ');
});
it('array of arrays completion - should suggest correct indent when extra spaces after cursor', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
array1: {
type: 'array',
items: {
type: 'object',
required: ['array2'],
properties: {
array2: {
type: 'array',
items: {
type: 'object',
required: ['objA'],
properties: {
objA: {
type: 'object',
required: ['itemA'],
properties: {
itemA: {
type: 'string',
},
},
},
},
},
},
},
},
},
},
});
const content = 'array1:\n - ';
const result = await parseSetup(content, 1, 4);
(0, chai_1.expect)(result.items.length).to.be.equal(2);
(0, chai_1.expect)(result.items[0].insertText).to.be.equal('array2:\n - objA:\n itemA: ');
});
it('object of array of arrays completion - should suggest correct indent when extra spaces after cursor', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
array1: {
type: 'array',
items: {
type: 'object',
properties: {
array2: {
type: 'array',
items: {
type: 'object',
properties: {
objA: {
type: 'object',
required: ['itemA'],
properties: {
itemA: {
type: 'string',
},
},
},
},
},
},
},
},
},
},
});
const content = 'array1:\n - array2:\n - ';
const result = await parseSetup(content, 2, 8);
(0, chai_1.expect)(result.items.length).to.be.equal(1);
(0, chai_1.expect)(result.items[0].insertText).to.be.equal('objA:\n itemA: ');
});
}); //'extra space after cursor'
it('should suggest from additionalProperties', async () => {
const schema = {
type: 'object',
additionalProperties: {
anyOf: [
{
type: 'string',
const: 'test1',
},
],
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'value: ';
const completion = await parseSetup(content, 0, content.length);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0].insertText).to.be.equal('test1');
});
it('should suggest defaultSnippets from additionalProperties', async () => {
const schema = {
type: 'object',
properties: {
id: {
type: 'string',
},
},
additionalProperties: {
anyOf: [
{
type: 'string',
defaultSnippets: [{ label: 'snippet', body: 'snippetBody' }],
},
],
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'value: |\n|';
const completion = await parseCaret(content);
(0, chai_1.expect)(completion.items.map((i) => i.insertText)).to.be.deep.equal(['snippetBody']);
});
describe('should suggest prop of the object (based on not completed prop name)', () => {
const schema = {
definitions: {
Obj: {
anyOf: [
{ type: 'string' },
{
type: 'object',
properties: {
prop1: { type: 'string' },
},
required: ['prop1'],
},
],
},
},
properties: {
test1: {
properties: {
nested: { $ref: '#/definitions/Obj' },
},
},
test2: { $ref: '#/definitions/Obj' },
},
};
const content = `
test2:
pr
test1:
nested:
pr
`;
it('nested object', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const completion = await parseSetup(content, 5, 6);
(0, chai_1.expect)(completion.items.length).equal(2);
(0, chai_1.expect)(completion.items[0].label).to.be.equal('prop1');
});
it('root object', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const completion = await parseSetup(content, 2, 4);
(0, chai_1.expect)(completion.items.length).equal(2);
(0, chai_1.expect)(completion.items[0].label).to.be.equal('prop1');
});
});
describe('should suggest property before indented comment', () => {
const schema = {
type: 'object',
properties: {
example: {
type: 'object',
properties: {
prop1: {
type: 'string',
},
prop2: {
type: 'string',
},
prop3: {
type: 'string',
},
},
},
},
};
it('completion should handle indented comment on new line', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'example:\n prop1: "test"\n \n #comment';
const completion = await parseSetup(content, 2, 2);
(0, chai_1.expect)(completion.items.length).equal(2);
(0, chai_1.expect)(completion.items[0]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('prop2', 'prop2: ', 2, 2, 2, 2, vscode_languageserver_types_1.CompletionItemKind.Property, vscode_languageserver_types_1.InsertTextFormat.Snippet, {
documentation: '',
}));
});
it('completion should handle comment at same indent level on new line', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'example:\n prop1: "test"\n \n #comment';
const completion = await parseSetup(content, 2, 2);
(0, chai_1.expect)(completion.items.length).equal(2);
(0, chai_1.expect)(completion.items[0]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('prop2', 'prop2: ', 2, 2, 2, 2, vscode_languageserver_types_1.CompletionItemKind.Property, vscode_languageserver_types_1.InsertTextFormat.Snippet, {
documentation: '',
}));
});
it('completion should handle suggestion without comment on next line', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'example:\n prop1: "test"\n \n prop3: "test"';
const completion = await parseSetup(content, 2, 2);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0]).to.be.deep.equal((0, verifyError_1.createExpectedCompletion)('prop2', 'prop2: ', 2, 2, 2, 2, vscode_languageserver_types_1.CompletionItemKind.Property, vscode_languageserver_types_1.InsertTextFormat.Snippet, {
documentation: '',
}));
});
});
it('should suggest property of unknown object', async () => {
const schema = {
type: 'object',
additionalProperties: true,
propertyNames: {
title: 'property',
description: 'Property Description',
},
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = '';
const completion = await parseSetup(content, 0, content.length);
(0, chai_1.expect)(completion.items.length).equal(1);
(0, chai_1.expect)(completion.items[0].insertText).to.be.equal('${1:property}: ');
(0, chai_1.expect)(completion.items[0].documentation).to.be.equal('Property Description');
});
});
//# sourceMappingURL=autoCompletionFix.test.js.map