Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/emmet/src/test/abbreviationAction.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 'mocha';
7
import * as assert from 'assert';
8
import { Selection, workspace, CancellationTokenSource, CompletionTriggerKind, ConfigurationTarget, CompletionContext } from 'vscode';
9
import { withRandomFileEditor, closeAllEditors } from './testUtils';
10
import { expandEmmetAbbreviation } from '../abbreviationActions';
11
import { DefaultCompletionItemProvider } from '../defaultCompletionProvider';
12
13
const completionProvider = new DefaultCompletionItemProvider();
14
15
const htmlContents = `
16
<body class="header">
17
<ul class="nav main">
18
<li class="item1">img</li>
19
<li class="item2">hithere</li>
20
ul>li
21
ul>li*2
22
ul>li.item$*2
23
ul>li.item$@44*2
24
<div i
25
</ul>
26
<style>
27
.boo {
28
display: dn; m10
29
}
30
</style>
31
<span></span>
32
(ul>li.item$)*2
33
(ul>li.item$)*2+span
34
(div>dl>(dt+dd)*2)
35
<script type="text/html">
36
span.hello
37
</script>
38
<script type="text/javascript">
39
span.bye
40
</script>
41
</body>
42
`;
43
44
const invokeCompletionContext: CompletionContext = {
45
triggerKind: CompletionTriggerKind.Invoke,
46
triggerCharacter: undefined,
47
};
48
49
suite('Tests for Expand Abbreviations (HTML)', () => {
50
teardown(closeAllEditors);
51
52
test('Expand snippets (HTML)', () => {
53
return testExpandAbbreviation('html', new Selection(3, 23, 3, 23), 'img', '<img src=\"\" alt=\"\">');
54
});
55
56
test('Expand snippets in completion list (HTML)', () => {
57
return testHtmlCompletionProvider(new Selection(3, 23, 3, 23), 'img', '<img src=\"\" alt=\"\">');
58
});
59
60
test('Expand snippets when no parent node (HTML)', () => {
61
return withRandomFileEditor('img', 'html', async (editor, _doc) => {
62
editor.selection = new Selection(0, 3, 0, 3);
63
await expandEmmetAbbreviation(null);
64
assert.strictEqual(editor.document.getText(), '<img src=\"\" alt=\"\">');
65
return Promise.resolve();
66
});
67
});
68
69
test('Expand snippets when no parent node in completion list (HTML)', () => {
70
return withRandomFileEditor('img', 'html', async (editor, _doc) => {
71
editor.selection = new Selection(0, 3, 0, 3);
72
const cancelSrc = new CancellationTokenSource();
73
const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);
74
if (!completionPromise) {
75
assert.strictEqual(!completionPromise, false, `Got unexpected undefined instead of a completion promise`);
76
return Promise.resolve();
77
}
78
const completionList = await completionPromise;
79
assert.strictEqual(completionList && completionList.items && completionList.items.length > 0, true);
80
if (completionList) {
81
assert.strictEqual(completionList.items[0].label, 'img');
82
assert.strictEqual(((<string>completionList.items[0].documentation) || '').replace(/\|/g, ''), '<img src=\"\" alt=\"\">');
83
}
84
return Promise.resolve();
85
});
86
});
87
88
test('Expand abbreviation (HTML)', () => {
89
return testExpandAbbreviation('html', new Selection(5, 25, 5, 25), 'ul>li', '<ul>\n\t\t\t<li></li>\n\t\t</ul>');
90
});
91
92
test('Expand abbreviation in completion list (HTML)', () => {
93
return testHtmlCompletionProvider(new Selection(5, 25, 5, 25), 'ul>li', '<ul>\n\t<li></li>\n</ul>');
94
});
95
96
test('Expand text that is neither an abbreviation nor a snippet to tags (HTML)', () => {
97
return testExpandAbbreviation('html', new Selection(4, 20, 4, 27), 'hithere', '<hithere></hithere>');
98
});
99
100
test('Do not Expand text that is neither an abbreviation nor a snippet to tags in completion list (HTML)', () => {
101
return testHtmlCompletionProvider(new Selection(4, 20, 4, 27), 'hithere', '<hithere></hithere>', true);
102
});
103
104
test('Expand abbreviation with repeaters (HTML)', () => {
105
return testExpandAbbreviation('html', new Selection(6, 27, 6, 27), 'ul>li*2', '<ul>\n\t\t\t<li></li>\n\t\t\t<li></li>\n\t\t</ul>');
106
});
107
108
test('Expand abbreviation with repeaters in completion list (HTML)', () => {
109
return testHtmlCompletionProvider(new Selection(6, 27, 6, 27), 'ul>li*2', '<ul>\n\t<li></li>\n\t<li></li>\n</ul>');
110
});
111
112
test('Expand abbreviation with numbered repeaters (HTML)', () => {
113
return testExpandAbbreviation('html', new Selection(7, 33, 7, 33), 'ul>li.item$*2', '<ul>\n\t\t\t<li class="item1"></li>\n\t\t\t<li class="item2"></li>\n\t\t</ul>');
114
});
115
116
test('Expand abbreviation with numbered repeaters in completion list (HTML)', () => {
117
return testHtmlCompletionProvider(new Selection(7, 33, 7, 33), 'ul>li.item$*2', '<ul>\n\t<li class="item1"></li>\n\t<li class="item2"></li>\n</ul>');
118
});
119
120
test('Expand abbreviation with numbered repeaters with offset (HTML)', () => {
121
return testExpandAbbreviation('html', new Selection(8, 36, 8, 36), 'ul>li.item$@44*2', '<ul>\n\t\t\t<li class="item44"></li>\n\t\t\t<li class="item45"></li>\n\t\t</ul>');
122
});
123
124
test('Expand abbreviation with numbered repeaters with offset in completion list (HTML)', () => {
125
return testHtmlCompletionProvider(new Selection(8, 36, 8, 36), 'ul>li.item$@44*2', '<ul>\n\t<li class="item44"></li>\n\t<li class="item45"></li>\n</ul>');
126
});
127
128
test('Expand abbreviation with numbered repeaters in groups (HTML)', () => {
129
return testExpandAbbreviation('html', new Selection(17, 16, 17, 16), '(ul>li.item$)*2', '<ul>\n\t\t<li class="item1"></li>\n\t</ul>\n\t<ul>\n\t\t<li class="item2"></li>\n\t</ul>');
130
});
131
132
test('Expand abbreviation with numbered repeaters in groups in completion list (HTML)', () => {
133
return testHtmlCompletionProvider(new Selection(17, 16, 17, 16), '(ul>li.item$)*2', '<ul>\n\t<li class="item1"></li>\n</ul>\n<ul>\n\t<li class="item2"></li>\n</ul>');
134
});
135
136
test('Expand abbreviation with numbered repeaters in groups with sibling in the end (HTML)', () => {
137
return testExpandAbbreviation('html', new Selection(18, 21, 18, 21), '(ul>li.item$)*2+span', '<ul>\n\t\t<li class="item1"></li>\n\t</ul>\n\t<ul>\n\t\t<li class="item2"></li>\n\t</ul>\n\t<span></span>');
138
});
139
140
test('Expand abbreviation with numbered repeaters in groups with sibling in the end in completion list (HTML)', () => {
141
return testHtmlCompletionProvider(new Selection(18, 21, 18, 21), '(ul>li.item$)*2+span', '<ul>\n\t<li class="item1"></li>\n</ul>\n<ul>\n\t<li class="item2"></li>\n</ul>\n<span></span>');
142
});
143
144
test('Expand abbreviation with nested groups (HTML)', () => {
145
return testExpandAbbreviation('html', new Selection(19, 19, 19, 19), '(div>dl>(dt+dd)*2)', '<div>\n\t\t<dl>\n\t\t\t<dt></dt>\n\t\t\t<dd></dd>\n\t\t\t<dt></dt>\n\t\t\t<dd></dd>\n\t\t</dl>\n\t</div>');
146
});
147
148
test('Expand abbreviation with nested groups in completion list (HTML)', () => {
149
return testHtmlCompletionProvider(new Selection(19, 19, 19, 19), '(div>dl>(dt+dd)*2)', '<div>\n\t<dl>\n\t\t<dt></dt>\n\t\t<dd></dd>\n\t\t<dt></dt>\n\t\t<dd></dd>\n\t</dl>\n</div>');
150
});
151
152
test('Expand tag that is opened, but not closed (HTML)', () => {
153
return testExpandAbbreviation('html', new Selection(9, 6, 9, 6), '<div', '<div></div>');
154
});
155
156
test('Do not Expand tag that is opened, but not closed in completion list (HTML)', () => {
157
return testHtmlCompletionProvider(new Selection(9, 6, 9, 6), '<div', '<div></div>', true);
158
});
159
160
test('No expanding text inside open tag (HTML)', () => {
161
return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {
162
editor.selection = new Selection(2, 4, 2, 4);
163
await expandEmmetAbbreviation(null);
164
assert.strictEqual(editor.document.getText(), htmlContents);
165
return Promise.resolve();
166
});
167
});
168
169
test('No expanding text inside open tag in completion list (HTML)', () => {
170
return withRandomFileEditor(htmlContents, 'html', (editor, _doc) => {
171
editor.selection = new Selection(2, 4, 2, 4);
172
const cancelSrc = new CancellationTokenSource();
173
const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);
174
assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`);
175
return Promise.resolve();
176
});
177
});
178
179
test('No expanding text inside open tag when there is no closing tag (HTML)', () => {
180
return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {
181
editor.selection = new Selection(9, 8, 9, 8);
182
await expandEmmetAbbreviation(null);
183
assert.strictEqual(editor.document.getText(), htmlContents);
184
return Promise.resolve();
185
});
186
});
187
188
test('No expanding text inside open tag when there is no closing tag in completion list (HTML)', () => {
189
return withRandomFileEditor(htmlContents, 'html', (editor, _doc) => {
190
editor.selection = new Selection(9, 8, 9, 8);
191
const cancelSrc = new CancellationTokenSource();
192
const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);
193
assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`);
194
return Promise.resolve();
195
});
196
});
197
198
test('No expanding text inside open tag when there is no closing tag when there is no parent node (HTML)', () => {
199
const fileContents = '<img s';
200
return withRandomFileEditor(fileContents, 'html', async (editor, _doc) => {
201
editor.selection = new Selection(0, 6, 0, 6);
202
await expandEmmetAbbreviation(null);
203
assert.strictEqual(editor.document.getText(), fileContents);
204
return Promise.resolve();
205
});
206
});
207
208
test('No expanding text in completion list inside open tag when there is no closing tag when there is no parent node (HTML)', () => {
209
const fileContents = '<img s';
210
return withRandomFileEditor(fileContents, 'html', (editor, _doc) => {
211
editor.selection = new Selection(0, 6, 0, 6);
212
const cancelSrc = new CancellationTokenSource();
213
const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);
214
assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`);
215
return Promise.resolve();
216
});
217
});
218
219
test('Expand css when inside style tag (HTML)', () => {
220
return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {
221
editor.selection = new Selection(13, 16, 13, 19);
222
const expandPromise = expandEmmetAbbreviation({ language: 'css' });
223
if (!expandPromise) {
224
return Promise.resolve();
225
}
226
await expandPromise;
227
assert.strictEqual(editor.document.getText(), htmlContents.replace('m10', 'margin: 10px;'));
228
return Promise.resolve();
229
});
230
});
231
232
test('Expand css when inside style tag in completion list (HTML)', () => {
233
const abbreviation = 'm10';
234
const expandedText = 'margin: 10px;';
235
236
return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {
237
editor.selection = new Selection(13, 16, 13, 19);
238
const cancelSrc = new CancellationTokenSource();
239
const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);
240
if (!completionPromise) {
241
assert.strictEqual(1, 2, `Problem with expanding m10`);
242
return Promise.resolve();
243
}
244
245
const completionList = await completionPromise;
246
if (!completionList || !completionList.items || !completionList.items.length) {
247
assert.strictEqual(1, 2, `Problem with expanding m10`);
248
return Promise.resolve();
249
}
250
const emmetCompletionItem = completionList.items[0];
251
assert.strictEqual(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`);
252
assert.strictEqual(((<string>emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);
253
assert.strictEqual(emmetCompletionItem.filterText, abbreviation, `FilterText of completion item doesnt match.`);
254
return Promise.resolve();
255
});
256
});
257
258
test('No expanding text inside style tag if position is not for property name (HTML)', () => {
259
return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {
260
editor.selection = new Selection(13, 14, 13, 14);
261
await expandEmmetAbbreviation(null);
262
assert.strictEqual(editor.document.getText(), htmlContents);
263
return Promise.resolve();
264
});
265
});
266
267
test('Expand css when inside style attribute (HTML)', () => {
268
const styleAttributeContent = '<div style="m10" class="hello"></div>';
269
return withRandomFileEditor(styleAttributeContent, 'html', async (editor, _doc) => {
270
editor.selection = new Selection(0, 15, 0, 15);
271
const expandPromise = expandEmmetAbbreviation(null);
272
if (!expandPromise) {
273
return Promise.resolve();
274
}
275
await expandPromise;
276
assert.strictEqual(editor.document.getText(), styleAttributeContent.replace('m10', 'margin: 10px;'));
277
return Promise.resolve();
278
});
279
});
280
281
test('Expand css when inside style attribute in completion list (HTML)', () => {
282
const abbreviation = 'm10';
283
const expandedText = 'margin: 10px;';
284
285
return withRandomFileEditor('<div style="m10" class="hello"></div>', 'html', async (editor, _doc) => {
286
editor.selection = new Selection(0, 15, 0, 15);
287
const cancelSrc = new CancellationTokenSource();
288
const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);
289
if (!completionPromise) {
290
assert.strictEqual(1, 2, `Problem with expanding m10`);
291
return Promise.resolve();
292
}
293
294
const completionList = await completionPromise;
295
if (!completionList || !completionList.items || !completionList.items.length) {
296
assert.strictEqual(1, 2, `Problem with expanding m10`);
297
return Promise.resolve();
298
}
299
const emmetCompletionItem = completionList.items[0];
300
assert.strictEqual(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`);
301
assert.strictEqual(((<string>emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);
302
assert.strictEqual(emmetCompletionItem.filterText, abbreviation, `FilterText of completion item doesnt match.`);
303
return Promise.resolve();
304
});
305
});
306
307
test('Expand html when inside script tag with html type (HTML)', () => {
308
return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {
309
editor.selection = new Selection(21, 12, 21, 12);
310
const expandPromise = expandEmmetAbbreviation(null);
311
if (!expandPromise) {
312
return Promise.resolve();
313
}
314
await expandPromise;
315
assert.strictEqual(editor.document.getText(), htmlContents.replace('span.hello', '<span class="hello"></span>'));
316
return Promise.resolve();
317
});
318
});
319
320
test('Expand html in completion list when inside script tag with html type (HTML)', () => {
321
const abbreviation = 'span.hello';
322
const expandedText = '<span class="hello"></span>';
323
324
return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {
325
editor.selection = new Selection(21, 12, 21, 12);
326
const cancelSrc = new CancellationTokenSource();
327
const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);
328
if (!completionPromise) {
329
assert.strictEqual(1, 2, `Problem with expanding span.hello`);
330
return Promise.resolve();
331
}
332
333
const completionList = await completionPromise;
334
if (!completionList || !completionList.items || !completionList.items.length) {
335
assert.strictEqual(1, 2, `Problem with expanding span.hello`);
336
return Promise.resolve();
337
}
338
const emmetCompletionItem = completionList.items[0];
339
assert.strictEqual(emmetCompletionItem.label, abbreviation, `Label of completion item doesnt match.`);
340
assert.strictEqual(((<string>emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);
341
return Promise.resolve();
342
});
343
});
344
345
test('No expanding text inside script tag with javascript type (HTML)', () => {
346
return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {
347
editor.selection = new Selection(24, 12, 24, 12);
348
await expandEmmetAbbreviation(null);
349
assert.strictEqual(editor.document.getText(), htmlContents);
350
return Promise.resolve();
351
});
352
});
353
354
test('No expanding text in completion list inside script tag with javascript type (HTML)', () => {
355
return withRandomFileEditor(htmlContents, 'html', (editor, _doc) => {
356
editor.selection = new Selection(24, 12, 24, 12);
357
const cancelSrc = new CancellationTokenSource();
358
const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);
359
assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`);
360
return Promise.resolve();
361
});
362
});
363
364
test('Expand html when inside script tag with javascript type if js is mapped to html (HTML)', async () => {
365
const oldConfig = workspace.getConfiguration('emmet').inspect('includeLanguages')?.globalValue;
366
await workspace.getConfiguration('emmet').update('includeLanguages', { 'javascript': 'html' }, ConfigurationTarget.Global);
367
await withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {
368
editor.selection = new Selection(24, 10, 24, 10);
369
const expandPromise = expandEmmetAbbreviation(null);
370
if (!expandPromise) {
371
return Promise.resolve();
372
}
373
await expandPromise;
374
assert.strictEqual(editor.document.getText(), htmlContents.replace('span.bye', '<span class="bye"></span>'));
375
});
376
await workspace.getConfiguration('emmet').update('includeLanguages', oldConfig, ConfigurationTarget.Global);
377
});
378
379
test('Expand html in completion list when inside script tag with javascript type if js is mapped to html (HTML)', async () => {
380
const abbreviation = 'span.bye';
381
const expandedText = '<span class="bye"></span>';
382
const oldConfig = workspace.getConfiguration('emmet').inspect('includeLanguages')?.globalValue;
383
await workspace.getConfiguration('emmet').update('includeLanguages', { 'javascript': 'html' }, ConfigurationTarget.Global);
384
await withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {
385
editor.selection = new Selection(24, 10, 24, 10);
386
const cancelSrc = new CancellationTokenSource();
387
const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);
388
if (!completionPromise) {
389
assert.strictEqual(1, 2, `Problem with expanding span.bye`);
390
return Promise.resolve();
391
}
392
const completionList = await completionPromise;
393
if (!completionList || !completionList.items || !completionList.items.length) {
394
assert.strictEqual(1, 2, `Problem with expanding span.bye`);
395
return Promise.resolve();
396
}
397
const emmetCompletionItem = completionList.items[0];
398
assert.strictEqual(emmetCompletionItem.label, abbreviation, `Label of completion item (${emmetCompletionItem.label}) doesnt match.`);
399
assert.strictEqual(((<string>emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);
400
return Promise.resolve();
401
});
402
await workspace.getConfiguration('emmet').update('includeLanguages', oldConfig, ConfigurationTarget.Global);
403
});
404
405
// test('No expanding when html is excluded in the settings', () => {
406
// return workspace.getConfiguration('emmet').update('excludeLanguages', ['html'], ConfigurationTarget.Global).then(() => {
407
// return testExpandAbbreviation('html', new Selection(9, 6, 9, 6), '', '', true).then(() => {
408
// return workspace.getConfiguration('emmet').update('excludeLanguages', oldValueForExcludeLanguages ? oldValueForExcludeLanguages.globalValue : undefined, ConfigurationTarget.Global);
409
// });
410
// });
411
// });
412
413
test('No expanding when html is excluded in the settings in completion list', async () => {
414
const oldConfig = workspace.getConfiguration('emmet').inspect('excludeLanguages')?.globalValue;
415
await workspace.getConfiguration('emmet').update('excludeLanguages', ['html'], ConfigurationTarget.Global);
416
await testHtmlCompletionProvider(new Selection(9, 6, 9, 6), '', '', true);
417
await workspace.getConfiguration('emmet').update('excludeLanguages', oldConfig, ConfigurationTarget.Global);
418
});
419
420
// test('No expanding when php (mapped syntax) is excluded in the settings', () => {
421
// return workspace.getConfiguration('emmet').update('excludeLanguages', ['php'], ConfigurationTarget.Global).then(() => {
422
// return testExpandAbbreviation('php', new Selection(9, 6, 9, 6), '', '', true).then(() => {
423
// return workspace.getConfiguration('emmet').update('excludeLanguages', oldValueForExcludeLanguages ? oldValueForExcludeLanguages.globalValue : undefined, ConfigurationTarget.Global);
424
// });
425
// });
426
// });
427
428
429
});
430
431
suite('Tests for jsx, xml and xsl', () => {
432
const oldValueForSyntaxProfiles = workspace.getConfiguration('emmet').inspect('syntaxProfiles');
433
teardown(closeAllEditors);
434
435
test('Expand abbreviation with className instead of class in jsx', () => {
436
return withRandomFileEditor('ul.nav', 'javascriptreact', async (editor, _doc) => {
437
editor.selection = new Selection(0, 6, 0, 6);
438
await expandEmmetAbbreviation({ language: 'javascriptreact' });
439
assert.strictEqual(editor.document.getText(), '<ul className="nav"></ul>');
440
return Promise.resolve();
441
});
442
});
443
444
test('Expand abbreviation with self closing tags for jsx', () => {
445
return withRandomFileEditor('img', 'javascriptreact', async (editor, _doc) => {
446
editor.selection = new Selection(0, 6, 0, 6);
447
await expandEmmetAbbreviation({ language: 'javascriptreact' });
448
assert.strictEqual(editor.document.getText(), '<img src="" alt="" />');
449
return Promise.resolve();
450
});
451
});
452
453
test('Expand abbreviation with single quotes for jsx', async () => {
454
await workspace.getConfiguration('emmet').update('syntaxProfiles', { jsx: { 'attr_quotes': 'single' } }, ConfigurationTarget.Global);
455
return withRandomFileEditor('img', 'javascriptreact', async (editor, _doc) => {
456
editor.selection = new Selection(0, 6, 0, 6);
457
await expandEmmetAbbreviation({ language: 'javascriptreact' });
458
assert.strictEqual(editor.document.getText(), '<img src=\'\' alt=\'\' />');
459
return workspace.getConfiguration('emmet').update('syntaxProfiles', oldValueForSyntaxProfiles ? oldValueForSyntaxProfiles.globalValue : undefined, ConfigurationTarget.Global);
460
});
461
});
462
463
test('Expand abbreviation with self closing tags for xml', () => {
464
return withRandomFileEditor('img', 'xml', async (editor, _doc) => {
465
editor.selection = new Selection(0, 6, 0, 6);
466
await expandEmmetAbbreviation({ language: 'xml' });
467
assert.strictEqual(editor.document.getText(), '<img src="" alt=""/>');
468
return Promise.resolve();
469
});
470
});
471
472
test('Expand abbreviation with no self closing tags for html', () => {
473
return withRandomFileEditor('img', 'html', async (editor, _doc) => {
474
editor.selection = new Selection(0, 6, 0, 6);
475
await expandEmmetAbbreviation({ language: 'html' });
476
assert.strictEqual(editor.document.getText(), '<img src="" alt="">');
477
return Promise.resolve();
478
});
479
});
480
481
test('Expand abbreviation with condition containing less than sign for jsx', () => {
482
return withRandomFileEditor('if (foo < 10) { span.bar', 'javascriptreact', async (editor, _doc) => {
483
editor.selection = new Selection(0, 27, 0, 27);
484
await expandEmmetAbbreviation({ language: 'javascriptreact' });
485
assert.strictEqual(editor.document.getText(), 'if (foo < 10) { <span className="bar"></span>');
486
return Promise.resolve();
487
});
488
});
489
490
test('No expanding text inside open tag in completion list (jsx)', () => {
491
return testNoCompletion('jsx', htmlContents, new Selection(2, 4, 2, 4));
492
});
493
494
test('No expanding tag that is opened, but not closed in completion list (jsx)', () => {
495
return testNoCompletion('jsx', htmlContents, new Selection(9, 6, 9, 6));
496
});
497
498
test('No expanding text inside open tag when there is no closing tag in completion list (jsx)', () => {
499
return testNoCompletion('jsx', htmlContents, new Selection(9, 8, 9, 8));
500
});
501
502
test('No expanding text in completion list inside open tag when there is no closing tag when there is no parent node (jsx)', () => {
503
return testNoCompletion('jsx', '<img s', new Selection(0, 6, 0, 6));
504
});
505
506
});
507
508
function testExpandAbbreviation(syntax: string, selection: Selection, abbreviation: string, expandedText: string, shouldFail?: boolean): Thenable<any> {
509
return withRandomFileEditor(htmlContents, syntax, async (editor, _doc) => {
510
editor.selection = selection;
511
const expandPromise = expandEmmetAbbreviation(null);
512
if (!expandPromise) {
513
if (!shouldFail) {
514
assert.strictEqual(1, 2, `Problem with expanding ${abbreviation} to ${expandedText}`);
515
}
516
return Promise.resolve();
517
}
518
await expandPromise;
519
assert.strictEqual(editor.document.getText(), htmlContents.replace(abbreviation, expandedText));
520
return Promise.resolve();
521
});
522
}
523
524
function testHtmlCompletionProvider(selection: Selection, abbreviation: string, expandedText: string, shouldFail?: boolean): Thenable<any> {
525
return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {
526
editor.selection = selection;
527
const cancelSrc = new CancellationTokenSource();
528
const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);
529
if (!completionPromise) {
530
if (!shouldFail) {
531
assert.strictEqual(1, 2, `Problem with expanding ${abbreviation} to ${expandedText}`);
532
}
533
return Promise.resolve();
534
}
535
536
const completionList = await completionPromise;
537
if (!completionList || !completionList.items || !completionList.items.length) {
538
if (!shouldFail) {
539
assert.strictEqual(1, 2, `Problem with expanding ${abbreviation} to ${expandedText}`);
540
}
541
return Promise.resolve();
542
}
543
const emmetCompletionItem = completionList.items[0];
544
assert.strictEqual(emmetCompletionItem.label, abbreviation, `Label of completion item doesnt match.`);
545
assert.strictEqual(((<string>emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);
546
return Promise.resolve();
547
});
548
}
549
550
function testNoCompletion(syntax: string, fileContents: string, selection: Selection): Thenable<any> {
551
return withRandomFileEditor(fileContents, syntax, (editor, _doc) => {
552
editor.selection = selection;
553
const cancelSrc = new CancellationTokenSource();
554
const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);
555
assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`);
556
return Promise.resolve();
557
});
558
}
559
560