mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-21 12:20:29 -04:00
* Merge from vscode 37cb23d3dd4f9433d56d4ba5ea3203580719a0bd * fix issues with merges * bump node version in azpipe * replace license headers * remove duplicate launch task * fix build errors * fix build errors * fix tslint issues * working through package and linux build issues * more work * wip * fix packaged builds * working through linux build errors * wip * wip * wip * fix mac and linux file limits * iterate linux pipeline * disable editor typing * revert series to parallel * remove optimize vscode from linux * fix linting issues * revert testing change * add work round for new node * readd packaging for extensions * fix issue with angular not resolving decorator dependencies
339 lines
12 KiB
TypeScript
339 lines
12 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
import * as assert from 'assert';
|
|
import { IPosition } from 'vs/editor/common/core/position';
|
|
import * as modes from 'vs/editor/common/modes';
|
|
import { CompletionModel } from 'vs/editor/contrib/suggest/completionModel';
|
|
import { CompletionItem, getSuggestionComparator, SnippetSortOrder } from 'vs/editor/contrib/suggest/suggest';
|
|
import { WordDistance } from 'vs/editor/contrib/suggest/wordDistance';
|
|
|
|
export function createSuggestItem(label: string, overwriteBefore: number, kind = modes.CompletionItemKind.Property, incomplete: boolean = false, position: IPosition = { lineNumber: 1, column: 1 }, sortText?: string, filterText?: string): CompletionItem {
|
|
const suggestion: modes.CompletionItem = {
|
|
label,
|
|
sortText,
|
|
filterText,
|
|
range: { startLineNumber: position.lineNumber, startColumn: position.column - overwriteBefore, endLineNumber: position.lineNumber, endColumn: position.column },
|
|
insertText: label,
|
|
kind
|
|
};
|
|
const container: modes.CompletionList = {
|
|
incomplete,
|
|
suggestions: [suggestion]
|
|
};
|
|
const provider: modes.CompletionItemProvider = {
|
|
provideCompletionItems(): any {
|
|
return;
|
|
}
|
|
};
|
|
|
|
return new CompletionItem(position, suggestion, container, provider, undefined!);
|
|
}
|
|
suite('CompletionModel', function () {
|
|
|
|
|
|
let model: CompletionModel;
|
|
|
|
setup(function () {
|
|
|
|
model = new CompletionModel([
|
|
createSuggestItem('foo', 3),
|
|
createSuggestItem('Foo', 3),
|
|
createSuggestItem('foo', 2),
|
|
], 1, {
|
|
leadingLineContent: 'foo',
|
|
characterCountDelta: 0
|
|
}, WordDistance.None);
|
|
});
|
|
|
|
test('filtering - cached', function () {
|
|
|
|
const itemsNow = model.items;
|
|
let itemsThen = model.items;
|
|
assert.ok(itemsNow === itemsThen);
|
|
|
|
// still the same context
|
|
model.lineContext = { leadingLineContent: 'foo', characterCountDelta: 0 };
|
|
itemsThen = model.items;
|
|
assert.ok(itemsNow === itemsThen);
|
|
|
|
// different context, refilter
|
|
model.lineContext = { leadingLineContent: 'foo1', characterCountDelta: 1 };
|
|
itemsThen = model.items;
|
|
assert.ok(itemsNow !== itemsThen);
|
|
});
|
|
|
|
|
|
test('complete/incomplete', () => {
|
|
|
|
assert.equal(model.incomplete.size, 0);
|
|
|
|
let incompleteModel = new CompletionModel([
|
|
createSuggestItem('foo', 3, undefined, true),
|
|
createSuggestItem('foo', 2),
|
|
], 1, {
|
|
leadingLineContent: 'foo',
|
|
characterCountDelta: 0
|
|
}, WordDistance.None);
|
|
assert.equal(incompleteModel.incomplete.size, 1);
|
|
});
|
|
|
|
test('replaceIncomplete', () => {
|
|
|
|
const completeItem = createSuggestItem('foobar', 1, undefined, false, { lineNumber: 1, column: 2 });
|
|
const incompleteItem = createSuggestItem('foofoo', 1, undefined, true, { lineNumber: 1, column: 2 });
|
|
|
|
const model = new CompletionModel([completeItem, incompleteItem], 2, { leadingLineContent: 'f', characterCountDelta: 0 }, WordDistance.None);
|
|
assert.equal(model.incomplete.size, 1);
|
|
assert.equal(model.items.length, 2);
|
|
|
|
const { incomplete } = model;
|
|
const complete = model.adopt(incomplete);
|
|
|
|
assert.equal(incomplete.size, 1);
|
|
assert.ok(incomplete.has(incompleteItem.provider));
|
|
assert.equal(complete.length, 1);
|
|
assert.ok(complete[0] === completeItem);
|
|
});
|
|
|
|
test('Fuzzy matching of snippets stopped working with inline snippet suggestions #49895', function () {
|
|
const completeItem1 = createSuggestItem('foobar1', 1, undefined, false, { lineNumber: 1, column: 2 });
|
|
const completeItem2 = createSuggestItem('foobar2', 1, undefined, false, { lineNumber: 1, column: 2 });
|
|
const completeItem3 = createSuggestItem('foobar3', 1, undefined, false, { lineNumber: 1, column: 2 });
|
|
const completeItem4 = createSuggestItem('foobar4', 1, undefined, false, { lineNumber: 1, column: 2 });
|
|
const completeItem5 = createSuggestItem('foobar5', 1, undefined, false, { lineNumber: 1, column: 2 });
|
|
const incompleteItem1 = createSuggestItem('foofoo1', 1, undefined, true, { lineNumber: 1, column: 2 });
|
|
|
|
const model = new CompletionModel(
|
|
[
|
|
completeItem1,
|
|
completeItem2,
|
|
completeItem3,
|
|
completeItem4,
|
|
completeItem5,
|
|
incompleteItem1,
|
|
], 2, { leadingLineContent: 'f', characterCountDelta: 0 }, WordDistance.None
|
|
);
|
|
assert.equal(model.incomplete.size, 1);
|
|
assert.equal(model.items.length, 6);
|
|
|
|
const { incomplete } = model;
|
|
const complete = model.adopt(incomplete);
|
|
|
|
assert.equal(incomplete.size, 1);
|
|
assert.ok(incomplete.has(incompleteItem1.provider));
|
|
assert.equal(complete.length, 5);
|
|
});
|
|
|
|
test('proper current word when length=0, #16380', function () {
|
|
|
|
model = new CompletionModel([
|
|
createSuggestItem(' </div', 4),
|
|
createSuggestItem('a', 0),
|
|
createSuggestItem('p', 0),
|
|
createSuggestItem(' </tag', 4),
|
|
createSuggestItem(' XYZ', 4),
|
|
], 1, {
|
|
leadingLineContent: ' <',
|
|
characterCountDelta: 0
|
|
}, WordDistance.None);
|
|
|
|
assert.equal(model.items.length, 4);
|
|
|
|
const [a, b, c, d] = model.items;
|
|
assert.equal(a.completion.label, ' </div');
|
|
assert.equal(b.completion.label, ' </tag');
|
|
assert.equal(c.completion.label, 'a');
|
|
assert.equal(d.completion.label, 'p');
|
|
});
|
|
|
|
test('keep snippet sorting with prefix: top, #25495', function () {
|
|
|
|
model = new CompletionModel([
|
|
createSuggestItem('Snippet1', 1, modes.CompletionItemKind.Snippet),
|
|
createSuggestItem('tnippet2', 1, modes.CompletionItemKind.Snippet),
|
|
createSuggestItem('semver', 1, modes.CompletionItemKind.Property),
|
|
], 1, {
|
|
leadingLineContent: 's',
|
|
characterCountDelta: 0
|
|
}, WordDistance.None, {
|
|
snippets: 'top',
|
|
snippetsPreventQuickSuggestions: true,
|
|
filterGraceful: true,
|
|
localityBonus: false,
|
|
shareSuggestSelections: false,
|
|
showIcons: true,
|
|
maxVisibleSuggestions: 12,
|
|
filteredTypes: Object.create(null)
|
|
});
|
|
|
|
assert.equal(model.items.length, 2);
|
|
const [a, b] = model.items;
|
|
assert.equal(a.completion.label, 'Snippet1');
|
|
assert.equal(b.completion.label, 'semver');
|
|
assert.ok(a.score < b.score); // snippet really promoted
|
|
|
|
});
|
|
|
|
test('keep snippet sorting with prefix: bottom, #25495', function () {
|
|
|
|
model = new CompletionModel([
|
|
createSuggestItem('snippet1', 1, modes.CompletionItemKind.Snippet),
|
|
createSuggestItem('tnippet2', 1, modes.CompletionItemKind.Snippet),
|
|
createSuggestItem('Semver', 1, modes.CompletionItemKind.Property),
|
|
], 1, {
|
|
leadingLineContent: 's',
|
|
characterCountDelta: 0
|
|
}, WordDistance.None, {
|
|
snippets: 'bottom',
|
|
snippetsPreventQuickSuggestions: true,
|
|
filterGraceful: true,
|
|
localityBonus: false,
|
|
shareSuggestSelections: false,
|
|
showIcons: true,
|
|
maxVisibleSuggestions: 12,
|
|
filteredTypes: Object.create(null)
|
|
});
|
|
|
|
assert.equal(model.items.length, 2);
|
|
const [a, b] = model.items;
|
|
assert.equal(a.completion.label, 'Semver');
|
|
assert.equal(b.completion.label, 'snippet1');
|
|
assert.ok(a.score < b.score); // snippet really demoted
|
|
});
|
|
|
|
test('keep snippet sorting with prefix: inline, #25495', function () {
|
|
|
|
model = new CompletionModel([
|
|
createSuggestItem('snippet1', 1, modes.CompletionItemKind.Snippet),
|
|
createSuggestItem('tnippet2', 1, modes.CompletionItemKind.Snippet),
|
|
createSuggestItem('Semver', 1),
|
|
], 1, {
|
|
leadingLineContent: 's',
|
|
characterCountDelta: 0
|
|
}, WordDistance.None, {
|
|
snippets: 'inline',
|
|
snippetsPreventQuickSuggestions: true,
|
|
filterGraceful: true,
|
|
localityBonus: false,
|
|
shareSuggestSelections: false,
|
|
showIcons: true,
|
|
maxVisibleSuggestions: 12,
|
|
filteredTypes: Object.create(null)
|
|
});
|
|
|
|
assert.equal(model.items.length, 2);
|
|
const [a, b] = model.items;
|
|
assert.equal(a.completion.label, 'snippet1');
|
|
assert.equal(b.completion.label, 'Semver');
|
|
assert.ok(a.score > b.score); // snippet really demoted
|
|
});
|
|
|
|
test('filterText seems ignored in autocompletion, #26874', function () {
|
|
|
|
const item1 = createSuggestItem('Map - java.util', 1, undefined, undefined, undefined, undefined, 'Map');
|
|
const item2 = createSuggestItem('Map - java.util', 1);
|
|
|
|
model = new CompletionModel([item1, item2], 1, {
|
|
leadingLineContent: 'M',
|
|
characterCountDelta: 0
|
|
}, WordDistance.None);
|
|
|
|
assert.equal(model.items.length, 2);
|
|
|
|
model.lineContext = {
|
|
leadingLineContent: 'Map ',
|
|
characterCountDelta: 3
|
|
};
|
|
assert.equal(model.items.length, 1);
|
|
});
|
|
|
|
test('Vscode 1.12 no longer obeys \'sortText\' in completion items (from language server), #26096', function () {
|
|
|
|
const item1 = createSuggestItem('<- groups', 2, modes.CompletionItemKind.Property, false, { lineNumber: 1, column: 3 }, '00002', ' groups');
|
|
const item2 = createSuggestItem('source', 0, modes.CompletionItemKind.Property, false, { lineNumber: 1, column: 3 }, '00001', 'source');
|
|
const items = [item1, item2].sort(getSuggestionComparator(SnippetSortOrder.Inline));
|
|
|
|
model = new CompletionModel(items, 3, {
|
|
leadingLineContent: ' ',
|
|
characterCountDelta: 0
|
|
}, WordDistance.None);
|
|
|
|
assert.equal(model.items.length, 2);
|
|
|
|
const [first, second] = model.items;
|
|
assert.equal(first.completion.label, 'source');
|
|
assert.equal(second.completion.label, '<- groups');
|
|
});
|
|
|
|
test('Score only filtered items when typing more, score all when typing less', function () {
|
|
model = new CompletionModel([
|
|
createSuggestItem('console', 0),
|
|
createSuggestItem('co_new', 0),
|
|
createSuggestItem('bar', 0),
|
|
createSuggestItem('car', 0),
|
|
createSuggestItem('foo', 0),
|
|
], 1, {
|
|
leadingLineContent: '',
|
|
characterCountDelta: 0
|
|
}, WordDistance.None);
|
|
|
|
assert.equal(model.items.length, 5);
|
|
|
|
// narrow down once
|
|
model.lineContext = { leadingLineContent: 'c', characterCountDelta: 1 };
|
|
assert.equal(model.items.length, 3);
|
|
|
|
// query gets longer, narrow down the narrow-down'ed-set from before
|
|
model.lineContext = { leadingLineContent: 'cn', characterCountDelta: 2 };
|
|
assert.equal(model.items.length, 2);
|
|
|
|
// query gets shorter, refilter everything
|
|
model.lineContext = { leadingLineContent: '', characterCountDelta: 0 };
|
|
assert.equal(model.items.length, 5);
|
|
});
|
|
|
|
test('Have more relaxed suggest matching algorithm #15419', function () {
|
|
model = new CompletionModel([
|
|
createSuggestItem('result', 0),
|
|
createSuggestItem('replyToUser', 0),
|
|
createSuggestItem('randomLolut', 0),
|
|
createSuggestItem('car', 0),
|
|
createSuggestItem('foo', 0),
|
|
], 1, {
|
|
leadingLineContent: '',
|
|
characterCountDelta: 0
|
|
}, WordDistance.None);
|
|
|
|
// query gets longer, narrow down the narrow-down'ed-set from before
|
|
model.lineContext = { leadingLineContent: 'rlut', characterCountDelta: 4 };
|
|
assert.equal(model.items.length, 3);
|
|
|
|
const [first, second, third] = model.items;
|
|
assert.equal(first.completion.label, 'result'); // best with `rult`
|
|
assert.equal(second.completion.label, 'replyToUser'); // best with `rltu`
|
|
assert.equal(third.completion.label, 'randomLolut'); // best with `rlut`
|
|
});
|
|
|
|
test('Emmet suggestion not appearing at the top of the list in jsx files, #39518', function () {
|
|
model = new CompletionModel([
|
|
createSuggestItem('from', 0),
|
|
createSuggestItem('form', 0),
|
|
createSuggestItem('form:get', 0),
|
|
createSuggestItem('testForeignMeasure', 0),
|
|
createSuggestItem('fooRoom', 0),
|
|
], 1, {
|
|
leadingLineContent: '',
|
|
characterCountDelta: 0
|
|
}, WordDistance.None);
|
|
|
|
model.lineContext = { leadingLineContent: 'form', characterCountDelta: 4 };
|
|
assert.equal(model.items.length, 5);
|
|
const [first, second, third] = model.items;
|
|
assert.equal(first.completion.label, 'form'); // best with `form`
|
|
assert.equal(second.completion.label, 'form:get'); // best with `form`
|
|
assert.equal(third.completion.label, 'from'); // best with `from`
|
|
});
|
|
});
|