UNPKG

yaml-language-server

Version:
1,000 lines 142 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Red Hat. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const testHelper_1 = require("./utils/testHelper"); const assert_1 = __importDefault(require("assert")); const path = __importStar(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', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { name: { type: 'string', }, }, }); const content = ''; const result = await parseSetup(content, 0); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('name', 'name: ', 0, 0, 0, 0, 10, 2, { documentation: '', })); }); it('Autocomplete on root with partial word', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { name: { type: 'string', }, }, }); const content = 'na'; // len: 2 const result = await parseSetup(content, 2); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('name', 'name: ', 0, 0, 0, 2, 10, 2, { documentation: '', })); }); it('Autocomplete on default value (without :)', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { name: { type: 'string', default: 'yaml', }, }, }); const content = 'name'; // len: 4 const result = await parseSetup(content, 10); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('name', 'name: ${1:yaml}', 0, 0, 0, 4, 10, 2, { documentation: '', })); }); it('Autocomplete on default value (without value content)', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { name: { type: 'string', default: 'yaml', }, }, }); const content = 'name: '; // len: 6 const result = await parseSetup(content, 12); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('yaml', 'yaml', 0, 6, 0, 6, 12, 2, { detail: 'Default value', })); }); 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_1.default.strictEqual(completion.items.length, 1); assert_1.default.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_1.default.strictEqual(completion.items.length, 1); assert_1.default.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)', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { name: { type: 'string', default: 'yaml', }, }, }); const content = 'name: ya'; // len: 8 const result = await parseSetup(content, 15); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('yaml', 'yaml', 0, 6, 0, 8, 12, 2, { detail: 'Default value', })); }); it('Autocomplete on default value (with value content contains dash)', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { name: { type: 'string', default: 'yaml-language', }, }, }); const content = 'name: yaml-'; const result = await parseSetup(content, content.length); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('yaml-language', 'yaml-language', 0, 6, 0, 11, 12, 2, { detail: 'Default value', })); }); it('Autocomplete on boolean value (without value content)', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { yaml: { type: 'boolean', }, }, }); const content = 'yaml: '; // len: 6 const result = await parseSetup(content, 11); assert_1.default.equal(result.items.length, 2); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('true', 'true', 0, 6, 0, 6, 12, 2, { documentation: '', })); assert_1.default.deepEqual(result.items[1], (0, verifyError_1.createExpectedCompletion)('false', 'false', 0, 6, 0, 6, 12, 2, { documentation: '', })); }); it('Autocomplete on boolean value with key of `null`', async () => { 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 result = await parseSetup(content, 0); (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)', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { yaml: { type: 'boolean', }, }, }); const content = 'yaml: fal'; // len: 9 const result = await parseSetup(content, 11); assert_1.default.equal(result.items.length, 2); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('true', 'true', 0, 6, 0, 9, 12, 2, { documentation: '', })); assert_1.default.deepEqual(result.items[1], (0, verifyError_1.createExpectedCompletion)('false', 'false', 0, 6, 0, 9, 12, 2, { documentation: '', })); }); it('Autocomplete on number value (without value content)', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { timeout: { type: 'number', default: 60000, }, }, }); const content = 'timeout: '; // len: 9 const result = await parseSetup(content, 9); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('60000', '60000', 0, 9, 0, 9, 12, 2, { detail: 'Default value', })); }); it('Autocomplete on number value (with value content)', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { timeout: { type: 'number', default: 60000, }, }, }); const content = 'timeout: 6'; // len: 10 const result = await parseSetup(content, 10); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('60000', '60000', 0, 9, 0, 10, 12, 2, { detail: 'Default value', })); }); it('Autocomplete key in middle of file', async () => { 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 result = await parseSetup(content); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('sample', 'sample: ${1:test}', 1, 2, 1, 8, 10, 2, { documentation: '', })); }); it('Autocomplete key with default value in middle of file', async () => { 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 result = await parseSetup(content); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('sample', 'sample: ${1:test}', 1, 2, 1, 5, 10, 2, { documentation: '', })); }); 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', async () => { 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 result = await parseSetup(content); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('myOtherSample', 'myOtherSample: ${1:test}', 2, 2, 2, 9, 10, 2, { documentation: '', })); }); it('Autocomplete does not happen right after key object', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { timeout: { type: 'number', default: 60000, }, }, }); const content = 'timeout:'; // len: 8 const result = await parseSetup(content, 9); assert_1.default.equal(result.items.length, 0); }); it('Autocomplete does not happen right after : under an object', async () => { 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 result = await parseSetup(content, 21); assert_1.default.equal(result.items.length, 0); }); it('Autocomplete with defaultSnippet markdown', async () => { 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 result = await parseSetup(content, content.length); assert_1.default.equal(result.items.length, 1); assert_1.default.equal(result.items[0].insertText, '\n myOtherSample:'); assert_1.default.equal(result.items[0].documentation.value, 'snippet\n```yaml\nmyOtherSample:\n```\n'); }); it('Autocomplete on multi yaml documents in a single file on root', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { timeout: { type: 'number', default: 60000, }, }, }); const content = '---\ntimeout: 10\n...\n---\n...'; // len: 27 const result = await parseSetup(content, 28); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('timeout', 'timeout: ${1:60000}', 4, 0, 4, 3, 10, 2, { documentation: '', })); }); it('Autocomplete on multi yaml documents in a single file on scalar', async () => { 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 result = await parseSetup(content); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('timeout', 'timeout: ${1:60000}', 4, 0, 4, 4, 10, 2, { documentation: '', })); }); it('Autocompletion has no results on value when they are not available', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { time: { type: 'string', }, }, }); const content = 'time: '; // len: 6 const result = await parseSetup(content, 6); assert_1.default.equal(result.items.length, 0); }); it('Test that properties that have multiple types get auto completed properly', async () => { schemaProvider.addSchema(testHelper_1.SCHEMA_ID, { type: 'object', properties: { scripts: { type: ['string', 'boolean'], enum: ['test', false, true], }, }, }); const content = 'scripts: '; // len: 9 const result = await parseSetup(content, 9); assert_1.default.equal(result.items.length, 3); assert_1.default.equal(result.items[0].label, 'test'); assert_1.default.equal(result.items[1].label, 'false'); assert_1.default.equal(result.items[2].label, 'true'); }); it('Test that properties that have multiple enums get auto completed properly', async () => { 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 result = await parseSetup(content, 6); assert_1.default.equal(result.items.length, 4); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('ImageBuild', 'ImageBuild', 0, 6, 0, 6, 12, 2, { documentation: undefined, })); assert_1.default.deepEqual(result.items[1], (0, verifyError_1.createExpectedCompletion)('ImageBuilder', 'ImageBuilder', 0, 6, 0, 6, 12, 2, { documentation: undefined, })); assert_1.default.deepEqual(result.items[2], (0, verifyError_1.createExpectedCompletion)('ImageStream', 'ImageStream', 0, 6, 0, 6, 12, 2, { documentation: undefined, })); assert_1.default.deepEqual(result.items[3], (0, verifyError_1.createExpectedCompletion)('ImageStreamBuilder', 'ImageStreamBuilder', 0, 6, 0, 6, 12, 2, { documentation: undefined, })); }); it('Insert required attributes at correct level', async () => { // eslint-disable-next-line @typescript-eslint/no-require-imports const schema = require(path.join(__dirname, './fixtures/testRequiredProperties.json')); schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema); const content = '- top:\n prop1: demo\n- '; const result = await parseSetup(content, content.length); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('top', 'top:\n prop1: ', 2, 2, 2, 2, 10, 2, { documentation: '', })); }); it('Insert required attributes at correct level even on first element', async () => { // eslint-disable-next-line @typescript-eslint/no-require-imports const schema = require(path.join(__dirname, './fixtures/testRequiredProperties.json')); schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema); const content = '- '; const result = await parseSetup(content, content.length); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('top', 'top:\n prop1: ', 0, 2, 0, 2, 10, 2, { documentation: '', })); }); it('Provide the 3 types when none provided', async () => { // eslint-disable-next-line @typescript-eslint/no-require-imports const schema = require(path.join(__dirname, './fixtures/testArrayMaxProperties.json')); schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema); const content = '- '; const result = await parseSetup(content, content.length); assert_1.default.equal(result.items.length, 3); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('prop1', 'prop1: ', 0, 2, 0, 2, 10, 2, { documentation: '', })); assert_1.default.deepEqual(result.items[1], (0, verifyError_1.createExpectedCompletion)('prop2', 'prop2: ', 0, 2, 0, 2, 10, 2, { documentation: '', })); assert_1.default.deepEqual(result.items[2], (0, verifyError_1.createExpectedCompletion)('prop3', 'prop3: ', 0, 2, 0, 2, 10, 2, { documentation: '', })); }); it('Provide the 2 types when one is provided', async () => { // eslint-disable-next-line @typescript-eslint/no-require-imports const schema = require(path.join(__dirname, './fixtures/testArrayMaxProperties.json')); schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema); const content = '- prop1:\n '; const result = await parseSetup(content, content.length); assert_1.default.equal(result.items.length, 2); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('prop2', 'prop2: ', 1, 2, 1, 2, 10, 2, { documentation: '', })); assert_1.default.deepEqual(result.items[1], (0, verifyError_1.createExpectedCompletion)('prop3', 'prop3: ', 1, 2, 1, 2, 10, 2, { documentation: '', })); }); it('Provide the 2 types when one is provided and the second is typed', async () => { // eslint-disable-next-line @typescript-eslint/no-require-imports const schema = require(path.join(__dirname, './fixtures/testArrayMaxProperties.json')); schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema); const content = '- prop1:\n p'; const result = await parseSetup(content, content.length); assert_1.default.equal(result.items.length, 2); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('prop2', 'prop2: ', 1, 2, 1, 3, 10, 2, { documentation: '', })); assert_1.default.deepEqual(result.items[1], (0, verifyError_1.createExpectedCompletion)('prop3', 'prop3: ', 1, 2, 1, 3, 10, 2, { documentation: '', })); }); it('Provide no completion when maxProperties reached', async () => { // eslint-disable-next-line @typescript-eslint/no-require-imports const schema = require(path.join(__dirname, './fixtures/testArrayMaxProperties.json')); schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema); const content = '- prop1:\n prop2:\n '; const result = await parseSetup(content, content.length); assert_1.default.equal(result.items.length, 0); }); 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', async () => { // eslint-disable-next-line @typescript-eslint/no-require-imports const schema = require(path.join(__dirname, './fixtures/testStringArray.json')); schemaProvider.addSchema(testHelper_1.SCHEMA_ID, schema); const content = 'fooBa'; // len: 5 const result = await parseSetup(content, content.lastIndexOf('Ba') + 2); // pos: 3+2 assert_1.default.strictEqual('fooBar:\n - ${1}', result.items[0].insertText); }); it('Array autocomplete without word and extra space', async () => { 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 result = await parseSetup(content, 14); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('name', 'name: ', 1, 4, 1, 4, 10, 2, { documentation: '', })); }); it('Array autocomplete without word and autocompletion beside -', async () => { 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 result = await parseSetup(content, 13); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('name', ' name: ', 1, 3, 1, 3, 10, 2, { documentation: '', })); }); it('Array autocomplete without word on space before array symbol', async () => { 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 result = await parseSetup(content, 26); assert_1.default.equal(result.items.length, 1); assert_1.default.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```' }, })); }); it('Array autocomplete on empty node with array from schema', async () => { 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 result = await parseSetup(content, 9); assert_1.default.equal(result.items.length, 1); assert_1.default.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```' }, })); }); it('Array autocomplete with letter', async () => { 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 result = await parseSetup(content, 14); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('name', 'name: ', 1, 4, 1, 5, 10, 2, { documentation: '', })); }); it('Array autocomplete without word (second item)', async () => { 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: 28 const result = await parseSetup(content, 32); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('email', 'email: ', 2, 4, 2, 4, 10, 2, { documentation: '', })); }); it('Array autocomplete with letter (second item)', async () => { 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 | |e'; // len: 29, pos: 27 const result = await parseSetup(content); assert_1.default.equal(result.items.length, 1); assert_1.default.deepEqual(result.items[0], (0, verifyError_1.createExpectedCompletion)('email', 'email: ', 2, 3, 2, 3, 10, 2, { documentation: '', })); }); it('Autocompletion after array', async () => { schemaProvider.addSchema