yaml-language-server
Version:
YAML language server
1,050 lines (1,049 loc) • 132 kB
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 });
/* eslint-disable @typescript-eslint/no-var-requires */
const testHelper_1 = require("./utils/testHelper");
const assert = require("assert");
const path = require("path");
const verifyError_1 = require("./utils/verifyError");
const serviceSetup_1 = require("./utils/serviceSetup");
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
const chai_1 = require("chai");
const yamlSettings_1 = require("../src/yamlSettings");
describe('Auto Completion Tests', () => {
let languageSettingsSetup;
let languageService;
let languageHandler;
let yamlSettings;
let schemaProvider;
before(() => {
languageSettingsSetup = new serviceSetup_1.ServiceSetup().withCompletion().withSchemaFileMatch({
uri: 'http://google.com',
fileMatch: ['bad-schema.yaml'],
});
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 position The position of the caret in the document.
* Alternatively, `position` can be omitted if 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 parseSetup(content, position) {
if (typeof position === 'undefined') {
({ content, position } = (0, testHelper_1.caretPosition)(content));
}
const testTextDocument = (0, testHelper_1.setupSchemaIDTextDocument)(content);
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);
});
describe('YAML Completion Tests', function () {
describe('JSON Schema Tests', function () {
it('Autocomplete on root without word', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
name: {
type: 'string',
},
},
});
const content = '';
const completion = parseSetup(content, 0);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('name', 'name: ', 0, 0, 0, 0, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Autocomplete on root with partial word', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
name: {
type: 'string',
},
},
});
const content = 'na'; // len: 2
const completion = parseSetup(content, 2);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('name', 'name: ', 0, 0, 0, 2, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Autocomplete on default value (without :)', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
name: {
type: 'string',
default: 'yaml',
},
},
});
const content = 'name'; // len: 4
const completion = parseSetup(content, 10);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('name', 'name: ${1:yaml}', 0, 0, 0, 4, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Autocomplete on default value (without value content)', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
name: {
type: 'string',
default: 'yaml',
},
},
});
const content = 'name: '; // len: 6
const completion = parseSetup(content, 12);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('yaml', 'yaml', 0, 6, 0, 6, 12, 2, {
detail: 'Default value',
}));
})
.then(done, done);
});
it('Autocomplete on default value with \\"', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
name: {
type: 'string',
default: '"yaml"',
},
},
});
const content = 'name: '; // len: 6
const completion = await parseSetup(content, 6);
assert.strictEqual(completion.items.length, 1);
assert.deepStrictEqual(completion.items[0], (0, verifyError_1.createExpectedCompletion)('"yaml"', '"yaml"', 0, 6, 0, 6, 12, 2, {
detail: 'Default value',
}));
});
it('Autocomplete name and value with \\"', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
name: {
type: 'string',
default: '"yaml"',
},
},
});
const content = 'nam|e|'; // len: 4, pos: 3
const completion = await parseSetup(content);
assert.strictEqual(completion.items.length, 1);
assert.deepStrictEqual(completion.items[0], (0, verifyError_1.createExpectedCompletion)('name', 'name: ${1:"yaml"}', 0, 0, 0, 4, 10, 2, {
documentation: '',
}));
});
it('Autocomplete on default value (with value content)', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
name: {
type: 'string',
default: 'yaml',
},
},
});
const content = 'name: ya'; // len: 8
const completion = parseSetup(content, 15);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('yaml', 'yaml', 0, 6, 0, 8, 12, 2, {
detail: 'Default value',
}));
})
.then(done, done);
});
it('Autocomplete on default value (with value content contains dash)', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
name: {
type: 'string',
default: 'yaml-language',
},
},
});
const content = 'name: yaml-';
const completion = parseSetup(content, content.length);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('yaml-language', 'yaml-language', 0, 6, 0, 11, 12, 2, {
detail: 'Default value',
}));
})
.then(done, done);
});
it('Autocomplete on boolean value (without value content)', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
yaml: {
type: 'boolean',
},
},
});
const content = 'yaml: '; // len: 6
const completion = parseSetup(content, 11);
completion
.then(function (result) {
assert.equal(result.items.length, 2);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('true', 'true', 0, 6, 0, 6, 12, 2, {
documentation: '',
}));
assert.deepEqual(result.items[1], (0, verifyError_1.createExpectedCompletion)('false', 'false', 0, 6, 0, 6, 12, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Autocomplete on boolean value with key of `null`', () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
validation: {
type: 'object',
additionalProperties: false,
properties: {
null: {
type: 'boolean',
default: false,
},
},
},
},
});
const content = ''; // len: 0
const completion = parseSetup(content, 0);
completion.then(function (result) {
(0, chai_1.expect)(result.items.length).equal(1);
(0, chai_1.expect)(result.items[0].insertText).equal('validation:\n \\"null\\": ${1:false}');
});
});
it('Autocomplete on boolean value (with value content)', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
yaml: {
type: 'boolean',
},
},
});
const content = 'yaml: fal'; // len: 9
const completion = parseSetup(content, 11);
completion
.then(function (result) {
assert.equal(result.items.length, 2);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('true', 'true', 0, 6, 0, 9, 12, 2, {
documentation: '',
}));
assert.deepEqual(result.items[1], (0, verifyError_1.createExpectedCompletion)('false', 'false', 0, 6, 0, 9, 12, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Autocomplete on number value (without value content)', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
timeout: {
type: 'number',
default: 60000,
},
},
});
const content = 'timeout: '; // len: 9
const completion = parseSetup(content, 9);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('60000', '60000', 0, 9, 0, 9, 12, 2, {
detail: 'Default value',
}));
})
.then(done, done);
});
it('Autocomplete on number value (with value content)', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
timeout: {
type: 'number',
default: 60000,
},
},
});
const content = 'timeout: 6'; // len: 10
const completion = parseSetup(content, 10);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('60000', '60000', 0, 9, 0, 10, 12, 2, {
detail: 'Default value',
}));
})
.then(done, done);
});
it('Autocomplete key in middle of file', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
scripts: {
type: 'object',
properties: {
sample: {
type: 'string',
enum: ['test'],
},
},
},
},
});
const content = 'scripts:\n |s|ample'; // len: 17, pos: 11
const completion = parseSetup(content);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('sample', 'sample: ${1:test}', 1, 2, 1, 8, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Autocomplete key with default value in middle of file', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
scripts: {
type: 'object',
properties: {
sample: {
type: 'string',
default: 'test',
},
},
},
},
});
const content = 'scripts:\n |s|am'; // len: 14, pos: 11
const completion = parseSetup(content);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('sample', 'sample: ${1:test}', 1, 2, 1, 5, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Autocomplete without default value - not required', async () => {
const languageSettingsSetup = new serviceSetup_1.ServiceSetup().withCompletion();
languageSettingsSetup.languageSettings.disableDefaultProperties = true;
languageService.configure(languageSettingsSetup.languageSettings);
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
scripts: {
type: 'object',
properties: {
sample: {
type: 'string',
default: 'test',
},
objectSample: {
type: 'object',
},
},
},
},
});
const content = '';
const result = await parseSetup(content, 0);
(0, chai_1.expect)(result.items.length).to.be.equal(1);
(0, chai_1.expect)(result.items[0]).to.deep.equal((0, verifyError_1.createExpectedCompletion)('scripts', 'scripts:\n ', 0, 0, 0, 0, 10, 2, {
documentation: '',
}));
});
it('Autocomplete without default value - required', async () => {
const languageSettingsSetup = new serviceSetup_1.ServiceSetup().withCompletion();
languageSettingsSetup.languageSettings.disableDefaultProperties = true;
languageService.configure(languageSettingsSetup.languageSettings);
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
scripts: {
type: 'object',
properties: {
sample: {
type: 'string',
default: 'test',
},
objectSample: {
type: 'object',
},
},
required: ['sample', 'objectSample'],
},
},
});
const content = '';
const result = await parseSetup(content, 0);
(0, chai_1.expect)(result.items.length).to.be.equal(1);
(0, chai_1.expect)(result.items[0]).to.deep.equal((0, verifyError_1.createExpectedCompletion)('scripts', 'scripts:\n sample: ${1:test}\n objectSample:\n $2', 0, 0, 0, 0, 10, 2, {
documentation: '',
}));
});
it('Autocomplete second key in middle of file', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
scripts: {
type: 'object',
properties: {
sample: {
type: 'string',
enum: ['test'],
},
myOtherSample: {
type: 'string',
enum: ['test'],
},
},
},
},
});
const content = 'scripts:\n sample: test\n myOth|e|r'; // len: 33, pos: 31
const completion = parseSetup(content);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('myOtherSample', 'myOtherSample: ${1:test}', 2, 2, 2, 9, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Autocomplete does not happen right after key object', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
timeout: {
type: 'number',
default: 60000,
},
},
});
const content = 'timeout:'; // len: 8
const completion = parseSetup(content, 9);
completion
.then(function (result) {
assert.equal(result.items.length, 0);
})
.then(done, done);
});
it('Autocomplete does not happen right after : under an object', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
scripts: {
type: 'object',
properties: {
sample: {
type: 'string',
enum: ['test'],
},
myOtherSample: {
type: 'string',
enum: ['test'],
},
},
},
},
});
const content = 'scripts:\n sample:'; // len: 18
const completion = parseSetup(content, 21);
completion
.then(function (result) {
assert.equal(result.items.length, 0);
})
.then(done, done);
});
it('Autocomplete with defaultSnippet markdown', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
scripts: {
type: 'object',
properties: {},
defaultSnippets: [
{
label: 'myOtherSample snippet',
body: { myOtherSample: {} },
markdownDescription: 'snippet\n```yaml\nmyOtherSample:\n```\n',
},
],
},
},
});
const content = 'scripts: ';
const completion = parseSetup(content, content.length);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.equal(result.items[0].insertText, '\n myOtherSample:');
assert.equal(result.items[0].documentation.value, 'snippet\n```yaml\nmyOtherSample:\n```\n');
})
.then(done, done);
});
it('Autocomplete on multi yaml documents in a single file on root', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
timeout: {
type: 'number',
default: 60000,
},
},
});
const content = '---\ntimeout: 10\n...\n---\n...'; // len: 27
const completion = parseSetup(content, 28);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('timeout', 'timeout: ${1:60000}', 4, 0, 4, 3, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Autocomplete on multi yaml documents in a single file on scalar', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
timeout: {
type: 'number',
default: 60000,
},
},
});
const content = '---\ntimeout: 10\n...\n---\nti|m|e \n...'; // len: 33, pos: 26
const completion = parseSetup(content);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('timeout', 'timeout: ${1:60000}', 4, 0, 4, 4, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Autocompletion has no results on value when they are not available', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
time: {
type: 'string',
},
},
});
const content = 'time: '; // len: 6
const completion = parseSetup(content, 6);
completion
.then(function (result) {
assert.equal(result.items.length, 0);
})
.then(done, done);
});
it('Test that properties that have multiple types get auto completed properly', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
scripts: {
type: ['string', 'boolean'],
enum: ['test', false, true],
},
},
});
const content = 'scripts: '; // len: 9
const completion = parseSetup(content, 9);
completion
.then(function (result) {
assert.equal(result.items.length, 3);
assert.equal(result.items[0].label, 'test');
assert.equal(result.items[1].label, 'false');
assert.equal(result.items[2].label, 'true');
})
.then(done, done);
});
it('Test that properties that have multiple enums get auto completed properly', (done) => {
const schema = {
definitions: {
ImageBuild: {
type: 'object',
properties: {
kind: {
type: 'string',
enum: ['ImageBuild', 'ImageBuilder'],
},
},
},
ImageStream: {
type: 'object',
properties: {
kind: {
type: 'string',
enum: ['ImageStream', 'ImageStreamBuilder'],
},
},
},
},
oneOf: [
{
$ref: '#/definitions/ImageBuild',
},
{
$ref: '#/definitions/ImageStream',
},
],
};
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'kind: '; // len: 6
const validator = parseSetup(content, 6);
validator
.then(function (result) {
assert.equal(result.items.length, 4);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('ImageBuild', 'ImageBuild', 0, 6, 0, 6, 12, 2, {
documentation: undefined,
}));
assert.deepEqual(result.items[1], (0, verifyError_1.createExpectedCompletion)('ImageBuilder', 'ImageBuilder', 0, 6, 0, 6, 12, 2, {
documentation: undefined,
}));
assert.deepEqual(result.items[2], (0, verifyError_1.createExpectedCompletion)('ImageStream', 'ImageStream', 0, 6, 0, 6, 12, 2, {
documentation: undefined,
}));
assert.deepEqual(result.items[3], (0, verifyError_1.createExpectedCompletion)('ImageStreamBuilder', 'ImageStreamBuilder', 0, 6, 0, 6, 12, 2, {
documentation: undefined,
}));
})
.then(done, done);
});
it('Insert required attributes at correct level', (done) => {
const schema = require(path.join(__dirname, './fixtures/testRequiredProperties.json'));
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = '- top:\n prop1: demo\n- ';
const completion = parseSetup(content, content.length);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('top', 'top:\n prop1: ', 2, 2, 2, 2, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Insert required attributes at correct level even on first element', (done) => {
const schema = require(path.join(__dirname, './fixtures/testRequiredProperties.json'));
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = '- ';
const completion = parseSetup(content, content.length);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('top', 'top:\n prop1: ', 0, 2, 0, 2, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Provide the 3 types when none provided', (done) => {
const schema = require(path.join(__dirname, './fixtures/testArrayMaxProperties.json'));
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = '- ';
const completion = parseSetup(content, content.length);
completion
.then(function (result) {
assert.equal(result.items.length, 3);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('prop1', 'prop1: ', 0, 2, 0, 2, 10, 2, {
documentation: '',
}));
assert.deepEqual(result.items[1], (0, verifyError_1.createExpectedCompletion)('prop2', 'prop2: ', 0, 2, 0, 2, 10, 2, {
documentation: '',
}));
assert.deepEqual(result.items[2], (0, verifyError_1.createExpectedCompletion)('prop3', 'prop3: ', 0, 2, 0, 2, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Provide the 2 types when one is provided', (done) => {
const schema = require(path.join(__dirname, './fixtures/testArrayMaxProperties.json'));
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = '- prop1:\n ';
const completion = parseSetup(content, content.length);
completion
.then(function (result) {
assert.equal(result.items.length, 2);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('prop2', 'prop2: ', 1, 2, 1, 2, 10, 2, {
documentation: '',
}));
assert.deepEqual(result.items[1], (0, verifyError_1.createExpectedCompletion)('prop3', 'prop3: ', 1, 2, 1, 2, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Provide the 2 types when one is provided and the second is typed', (done) => {
const schema = require(path.join(__dirname, './fixtures/testArrayMaxProperties.json'));
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = '- prop1:\n p';
const completion = parseSetup(content, content.length);
completion
.then(function (result) {
assert.equal(result.items.length, 2);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('prop2', 'prop2: ', 1, 2, 1, 3, 10, 2, {
documentation: '',
}));
assert.deepEqual(result.items[1], (0, verifyError_1.createExpectedCompletion)('prop3', 'prop3: ', 1, 2, 1, 3, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Provide no completion when maxProperties reached', (done) => {
const schema = require(path.join(__dirname, './fixtures/testArrayMaxProperties.json'));
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = '- prop1:\n prop2:\n ';
const completion = parseSetup(content, content.length);
completion
.then(function (result) {
assert.equal(result.items.length, 0);
})
.then(done, done);
});
it('Autocompletion should escape @', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
'@type': {
type: 'string',
enum: ['foo'],
},
},
});
const content = '';
const completion = await parseSetup(content, 0);
(0, chai_1.expect)(completion.items.length).to.be.equal(1);
(0, chai_1.expect)(completion.items[0]).to.deep.equal((0, verifyError_1.createExpectedCompletion)('@type', '"@type": ${1:foo}', 0, 0, 0, 0, 10, 2, {
documentation: '',
}));
});
it('Autocompletion should escape colon when indicating map', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
'test: colon': {
type: 'object',
properties: {
none: {
type: 'boolean',
enum: [true],
},
},
},
},
});
const content = '';
const completion = await parseSetup(content, 0);
(0, chai_1.expect)(completion.items.length).to.be.equal(1);
(0, chai_1.expect)(completion.items[0]).to.deep.equal((0, verifyError_1.createExpectedCompletion)('test: colon', '"test: colon":\n ', 0, 0, 0, 0, 10, 2, {
documentation: '',
}));
});
it('Autocompletion should not escape colon when no white-space following', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
'test:colon': {
type: 'object',
properties: {
none: {
type: 'boolean',
enum: [true],
},
},
},
},
});
const content = '';
const completion = await parseSetup(content, 0);
(0, chai_1.expect)(completion.items.length).to.be.equal(1);
(0, chai_1.expect)(completion.items[0]).to.deep.equal((0, verifyError_1.createExpectedCompletion)('test:colon', 'test:colon:\n ', 0, 0, 0, 0, 10, 2, {
documentation: '',
}));
});
it('Autocompletion should not escape colon when no key part present', async () => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
':colon': {
type: 'object',
properties: {
none: {
type: 'boolean',
enum: [true],
},
},
},
},
});
const content = '';
const completion = await parseSetup(content, 0);
(0, chai_1.expect)(completion.items.length).to.be.equal(1);
(0, chai_1.expect)(completion.items[0]).to.deep.equal((0, verifyError_1.createExpectedCompletion)(':colon', ':colon:\n ', 0, 0, 0, 0, 10, 2, {
documentation: '',
}));
});
describe('Conditional Schema', () => {
const schema = {
type: 'object',
title: 'basket',
properties: {
name: { type: 'string' },
},
if: {
filePatternAssociation: testHelper_1.SCHEMA_ID,
},
then: {
properties: {
pineapple: { type: 'string' },
},
required: ['pineapple'],
},
else: {
properties: {
tomato: { type: 'string' },
},
required: ['tomato'],
},
};
it('should suggest "then" block if "if" match filePatternAssociation', async () => {
schema.if.filePatternAssociation = testHelper_1.SCHEMA_ID;
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'name: aName\n ';
const completion = await parseSetup(content, content.length);
(0, chai_1.expect)(completion.items.map((i) => i.label)).to.deep.equal(['pineapple', 'basket']);
});
});
});
describe('Array Specific Tests', function () {
it('Should insert empty array item', (done) => {
const schema = require(path.join(__dirname, './fixtures/testStringArray.json'));
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema);
const content = 'fooBa'; // len: 5
const completion = parseSetup(content, content.lastIndexOf('Ba') + 2); // pos: 3+2
completion
.then(function (result) {
assert.strictEqual('fooBar:\n - ${1}', result.items[0].insertText);
})
.then(done, done);
});
it('Array autocomplete without word and extra space', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
authors: {
type: 'array',
items: {
type: 'object',
properties: {
name: {
type: 'string',
},
},
},
},
},
});
const content = 'authors:\n - '; // len: 13
const completion = parseSetup(content, 14);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('name', 'name: ', 1, 4, 1, 4, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Array autocomplete without word and autocompletion beside -', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
authors: {
type: 'array',
items: {
type: 'object',
properties: {
name: {
type: 'string',
},
},
},
},
},
});
const content = 'authors:\n -'; // len: 12
const completion = parseSetup(content, 13);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('name', ' name: ', 1, 3, 1, 3, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Array autocomplete without word on space before array symbol', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
authors: {
type: 'array',
items: {
type: 'object',
properties: {
name: {
type: 'string',
},
email: {
type: 'string',
},
},
},
},
},
});
const content = 'authors:\n - name: test\n '; // len: 26
const completion = parseSetup(content, 26);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('- (array item) object', '- ', 2, 2, 2, 2, 9, 2, {
documentation: { kind: 'markdown', value: 'Create an item of an array type `object`\n ```\n- \n```' },
}));
})
.then(done, done);
});
it('Array autocomplete on empty node with array from schema', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
authors: {
type: 'array',
items: {
type: 'object',
properties: {
name: {
type: 'string',
},
email: {
type: 'string',
},
},
},
},
},
});
const content = 'authors:\n'; // len: 9
const completion = parseSetup(content, 9);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('- (array item) object', '- ', 1, 0, 1, 0, 9, 2, {
documentation: { kind: 'markdown', value: 'Create an item of an array type `object`\n ```\n- \n```' },
}));
})
.then(done, done);
});
it('Array autocomplete with letter', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
authors: {
type: 'array',
items: {
type: 'object',
properties: {
name: {
type: 'string',
},
},
},
},
},
});
const content = 'authors:\n - n'; // len: 14
const completion = parseSetup(content, 14);
completion
.then(function (result) {
assert.equal(result.items.length, 1);
assert.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('name', 'name: ', 1, 4, 1, 5, 10, 2, {
documentation: '',
}));
})
.then(done, done);
});
it('Array autocomplete without word (second item)', (done) => {
schemaProvider.addSchema(testHelper_1.SCHEMA_ID, {
type: 'object',
properties: {
authors: {
type: 'array',
items: {
type: 'object',
properties: {
name: {
type: 'string',
},
email: {