Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/emmet/src/test/completion.test.ts
4774 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as assert from 'assert';
7
import 'mocha';
8
import { CancellationTokenSource, CompletionTriggerKind, Selection } from 'vscode';
9
import { DefaultCompletionItemProvider } from '../defaultCompletionProvider';
10
import { closeAllEditors, withRandomFileEditor } from './testUtils';
11
12
const completionProvider = new DefaultCompletionItemProvider();
13
14
suite('Tests for completion in CSS embedded in HTML', () => {
15
teardown(closeAllEditors);
16
17
test('style attribute & attribute value in html', async () => {
18
await testCompletionProvider('html', '<div style="|"', [{ label: 'padding: ;' }]);
19
await testCompletionProvider('html', `<div style='|'`, [{ label: 'padding: ;' }]);
20
await testCompletionProvider('html', `<div style='p|'`, [{ label: 'padding: ;' }]);
21
await testCompletionProvider('html', `<div style='color: #0|'`, [{ label: '#000000' }]);
22
});
23
24
// https://github.com/microsoft/vscode/issues/79766
25
test('microsoft/vscode#79766, correct region determination', async () => {
26
await testCompletionProvider('html', `<div style="color: #000">di|</div>`, [
27
{ label: 'div', documentation: `<div>|</div>` }
28
]);
29
});
30
31
// https://github.com/microsoft/vscode/issues/86941
32
test('microsoft/vscode#86941, widows should be completed after width', async () => {
33
await testCompletionProvider('css', `.foo { wi| }`, [
34
{ label: 'width: ;', documentation: `width: |;` }
35
]);
36
await testCompletionProvider('css', `.foo { wid| }`, [
37
{ label: 'width: ;', documentation: `width: |;` }
38
]);
39
try {
40
await testCompletionProvider('css', `.foo { wi| }`, [
41
{ label: 'widows: ;', documentation: `widows: |;` }
42
]);
43
} catch (e) {
44
assert.strictEqual(e.message, `Didn't find completion item with label widows: ;`);
45
}
46
try {
47
await testCompletionProvider('css', `.foo { wid| }`, [
48
{ label: 'widows: ;', documentation: `widows: |;` }
49
]);
50
} catch (e) {
51
assert.strictEqual(e.message, `Didn't find completion item with label widows: ;`);
52
}
53
await testCompletionProvider('css', `.foo { wido| }`, [
54
{ label: 'widows: ;', documentation: `widows: |;` }
55
]);
56
});
57
58
// https://github.com/microsoft/vscode/issues/117020
59
test('microsoft/vscode#117020, ! at end of abbreviation should have completion', async () => {
60
await testCompletionProvider('css', `.foo { bdbn!| }`, [
61
{ label: 'border-bottom: none !important;', documentation: `border-bottom: none !important;` }
62
]);
63
});
64
65
// https://github.com/microsoft/vscode/issues/138461
66
test('microsoft/vscode#138461, JSX array noise', async () => {
67
await testCompletionProvider('jsx', 'a[i]', undefined);
68
await testCompletionProvider('jsx', 'Component[a b]', undefined);
69
await testCompletionProvider('jsx', '[a, b]', undefined);
70
await testCompletionProvider('jsx', '[a=b]', [
71
{ label: '<div a="b"></div>', documentation: '<div a="b">|</div>' }
72
]);
73
});
74
75
// https://github.com/microsoft/vscode-emmet-helper/pull/90
76
test('microsoft/vscode-emmet-helper#90', async () => {
77
await testCompletionProvider('html', 'dialog', [
78
{ label: '<dialog></dialog>', documentation: '<dialog>|</dialog>' }
79
]);
80
});
81
});
82
83
interface TestCompletionItem {
84
label: string;
85
86
documentation?: string;
87
}
88
89
function testCompletionProvider(fileExtension: string, contents: string, expectedItems: TestCompletionItem[] | undefined): Thenable<boolean> {
90
const cursorPos = contents.indexOf('|');
91
const slicedContents = contents.slice(0, cursorPos) + contents.slice(cursorPos + 1);
92
93
return withRandomFileEditor(slicedContents, fileExtension, async (editor, _doc) => {
94
const selection = new Selection(editor.document.positionAt(cursorPos), editor.document.positionAt(cursorPos));
95
editor.selection = selection;
96
const cancelSrc = new CancellationTokenSource();
97
const completionPromise = completionProvider.provideCompletionItems(
98
editor.document,
99
editor.selection.active,
100
cancelSrc.token,
101
{ triggerKind: CompletionTriggerKind.Invoke, triggerCharacter: undefined }
102
);
103
if (!completionPromise) {
104
return Promise.resolve();
105
}
106
107
const completionList = await completionPromise;
108
if (!completionList || !completionList.items || !completionList.items.length) {
109
if (completionList === undefined) {
110
assert.strictEqual(expectedItems, completionList);
111
}
112
return Promise.resolve();
113
}
114
115
assert.strictEqual(expectedItems === undefined, false);
116
expectedItems!.forEach(eItem => {
117
const matches = completionList.items.filter(i => i.label === eItem.label);
118
const match = matches && matches.length > 0 ? matches[0] : undefined;
119
assert.ok(match, `Didn't find completion item with label ${eItem.label}`);
120
121
if (match) {
122
assert.strictEqual(match.detail, 'Emmet Abbreviation', `Match needs to come from Emmet`);
123
124
if (eItem.documentation) {
125
assert.strictEqual(match.documentation, eItem.documentation, `Emmet completion Documentation doesn't match`);
126
}
127
}
128
});
129
130
return Promise.resolve();
131
});
132
}
133
134