monaco-yaml/test/autoCompletion3.test.ts

151 lines
5 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Red Hat. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { TextDocument } from 'vscode-languageserver';
import { getLanguageService } from '../src/languageservice/yamlLanguageService';
import { schemaRequestService, workspaceContext } from './utils/testHelper';
import { getLineOffsets } from '../src/languageservice/utils/arrUtils';
import assert = require('assert');
const languageService = getLanguageService(
schemaRequestService,
workspaceContext,
[],
null
);
const uri = 'http://json.schemastore.org/asmdef';
const languageSettings = {
schemas: [],
completion: true,
};
const fileMatch = ['*.yml', '*.yaml'];
languageSettings.schemas.push({ uri, fileMatch: fileMatch });
languageService.configure(languageSettings);
describe('Auto Completion Tests', () => {
describe('yamlCompletion with asmdef', function() {
describe('doComplete', function() {
function setup(content: string) {
return TextDocument.create(
'file://~/Desktop/vscode-k8s/test.yaml',
'yaml',
0,
content
);
}
function parseSetup(content: string, position) {
const testTextDocument = setup(content);
return completionHelper(
testTextDocument,
testTextDocument.positionAt(position)
);
}
it('Array of enum autocomplete without word on array symbol', done => {
const content = 'optionalUnityReferences:\n -';
const completion = parseSetup(content, 29);
completion
.then(function(result) {
assert.notEqual(result.items.length, 0);
})
.then(done, done);
});
it('Array of enum autocomplete without word', done => {
const content = 'optionalUnityReferences:\n - ';
const completion = parseSetup(content, 30);
completion
.then(function(result) {
assert.notEqual(result.items.length, 0);
})
.then(done, done);
});
it('Array of enum autocomplete with letter', done => {
const content = 'optionalUnityReferences:\n - T';
const completion = parseSetup(content, 31);
completion
.then(function(result) {
assert.notEqual(result.items.length, 0);
})
.then(done, done);
});
it('Array of enum autocomplete with multiline text', done => {
const content = 'optionalUnityReferences:\n - T\n e\n';
const completion = parseSetup(content, 31);
completion
.then(function(result) {
assert.notEqual(result.items.length, 0);
// textEdit must be single line
assert.equal(result.items[0].textEdit, undefined);
})
.then(done, done);
});
});
});
});
function is_EOL(c) {
return c === 0x0a /* LF */ || c === 0x0d /* CR */;
}
function completionHelper(document: TextDocument, textDocumentPosition) {
//Get the string we are looking at via a substring
const linePos = textDocumentPosition.line;
const position = textDocumentPosition;
const lineOffset = getLineOffsets(document.getText());
const start = lineOffset[linePos]; //Start of where the autocompletion is happening
let end = 0; //End of where the autocompletion is happening
if (lineOffset[linePos + 1]) {
end = lineOffset[linePos + 1];
} else {
end = document.getText().length;
}
while (end - 1 >= 0 && is_EOL(document.getText().charCodeAt(end - 1))) {
end--;
}
const textLine = document.getText().substring(start, end);
//Check if the string we are looking at is a node
if (textLine.indexOf(':') === -1) {
//We need to add the ":" to load the nodes
let newText = '';
//This is for the empty line case
const trimmedText = textLine.trim();
if (
trimmedText.length === 0 ||
(trimmedText.length === 1 && trimmedText[0] === '-')
) {
//Add a temp node that is in the document but we don't use at all.
newText =
document.getText().substring(0, start + textLine.length) +
(trimmedText[0] === '-' && !textLine.endsWith(' ') ? ' ' : '') +
'holder:\r\n' +
document
.getText()
.substr(lineOffset[linePos + 1] || document.getText().length);
//For when missing semi colon case
} else {
//Add a semicolon to the end of the current line so we can validate the node
newText =
document.getText().substring(0, start + textLine.length) +
':\r\n' +
document
.getText()
.substr(lineOffset[linePos + 1] || document.getText().length);
}
return languageService.doComplete(document, position, false);
} else {
//All the nodes are loaded
position.character = position.character - 1;
return languageService.doComplete(document, position, false);
}
}