Path: blob/main/extensions/emmet/src/test/abbreviationAction.test.ts
4774 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import 'mocha';6import * as assert from 'assert';7import { Selection, workspace, CancellationTokenSource, CompletionTriggerKind, ConfigurationTarget, CompletionContext } from 'vscode';8import { withRandomFileEditor, closeAllEditors } from './testUtils';9import { expandEmmetAbbreviation } from '../abbreviationActions';10import { DefaultCompletionItemProvider } from '../defaultCompletionProvider';1112const completionProvider = new DefaultCompletionItemProvider();1314const htmlContents = `15<body class="header">16<ul class="nav main">17<li class="item1">img</li>18<li class="item2">hithere</li>19ul>li20ul>li*221ul>li.item$*222ul>li.item$@44*223<div i24</ul>25<style>26.boo {27display: dn; m1028}29</style>30<span></span>31(ul>li.item$)*232(ul>li.item$)*2+span33(div>dl>(dt+dd)*2)34<script type="text/html">35span.hello36</script>37<script type="text/javascript">38span.bye39</script>40</body>41`;4243const invokeCompletionContext: CompletionContext = {44triggerKind: CompletionTriggerKind.Invoke,45triggerCharacter: undefined,46};4748suite('Tests for Expand Abbreviations (HTML)', () => {49teardown(closeAllEditors);5051test('Expand snippets (HTML)', () => {52return testExpandAbbreviation('html', new Selection(3, 23, 3, 23), 'img', '<img src=\"\" alt=\"\">');53});5455test('Expand snippets in completion list (HTML)', () => {56return testHtmlCompletionProvider(new Selection(3, 23, 3, 23), 'img', '<img src=\"\" alt=\"\">');57});5859test('Expand snippets when no parent node (HTML)', () => {60return withRandomFileEditor('img', 'html', async (editor, _doc) => {61editor.selection = new Selection(0, 3, 0, 3);62await expandEmmetAbbreviation(null);63assert.strictEqual(editor.document.getText(), '<img src=\"\" alt=\"\">');64return Promise.resolve();65});66});6768test('Expand snippets when no parent node in completion list (HTML)', () => {69return withRandomFileEditor('img', 'html', async (editor, _doc) => {70editor.selection = new Selection(0, 3, 0, 3);71const cancelSrc = new CancellationTokenSource();72const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);73if (!completionPromise) {74assert.strictEqual(!completionPromise, false, `Got unexpected undefined instead of a completion promise`);75return Promise.resolve();76}77const completionList = await completionPromise;78assert.strictEqual(completionList && completionList.items && completionList.items.length > 0, true);79if (completionList) {80assert.strictEqual(completionList.items[0].label, 'img');81assert.strictEqual(((<string>completionList.items[0].documentation) || '').replace(/\|/g, ''), '<img src=\"\" alt=\"\">');82}83return Promise.resolve();84});85});8687test('Expand abbreviation (HTML)', () => {88return testExpandAbbreviation('html', new Selection(5, 25, 5, 25), 'ul>li', '<ul>\n\t\t\t<li></li>\n\t\t</ul>');89});9091test('Expand abbreviation in completion list (HTML)', () => {92return testHtmlCompletionProvider(new Selection(5, 25, 5, 25), 'ul>li', '<ul>\n\t<li></li>\n</ul>');93});9495test('Expand text that is neither an abbreviation nor a snippet to tags (HTML)', () => {96return testExpandAbbreviation('html', new Selection(4, 20, 4, 27), 'hithere', '<hithere></hithere>');97});9899test('Do not Expand text that is neither an abbreviation nor a snippet to tags in completion list (HTML)', () => {100return testHtmlCompletionProvider(new Selection(4, 20, 4, 27), 'hithere', '<hithere></hithere>', true);101});102103test('Expand abbreviation with repeaters (HTML)', () => {104return 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>');105});106107test('Expand abbreviation with repeaters in completion list (HTML)', () => {108return testHtmlCompletionProvider(new Selection(6, 27, 6, 27), 'ul>li*2', '<ul>\n\t<li></li>\n\t<li></li>\n</ul>');109});110111test('Expand abbreviation with numbered repeaters (HTML)', () => {112return 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>');113});114115test('Expand abbreviation with numbered repeaters in completion list (HTML)', () => {116return 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>');117});118119test('Expand abbreviation with numbered repeaters with offset (HTML)', () => {120return 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>');121});122123test('Expand abbreviation with numbered repeaters with offset in completion list (HTML)', () => {124return 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>');125});126127test('Expand abbreviation with numbered repeaters in groups (HTML)', () => {128return 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>');129});130131test('Expand abbreviation with numbered repeaters in groups in completion list (HTML)', () => {132return 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>');133});134135test('Expand abbreviation with numbered repeaters in groups with sibling in the end (HTML)', () => {136return 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>');137});138139test('Expand abbreviation with numbered repeaters in groups with sibling in the end in completion list (HTML)', () => {140return 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>');141});142143test('Expand abbreviation with nested groups (HTML)', () => {144return 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>');145});146147test('Expand abbreviation with nested groups in completion list (HTML)', () => {148return 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>');149});150151test('Expand tag that is opened, but not closed (HTML)', () => {152return testExpandAbbreviation('html', new Selection(9, 6, 9, 6), '<div', '<div></div>');153});154155test('Do not Expand tag that is opened, but not closed in completion list (HTML)', () => {156return testHtmlCompletionProvider(new Selection(9, 6, 9, 6), '<div', '<div></div>', true);157});158159test('No expanding text inside open tag (HTML)', () => {160return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {161editor.selection = new Selection(2, 4, 2, 4);162await expandEmmetAbbreviation(null);163assert.strictEqual(editor.document.getText(), htmlContents);164return Promise.resolve();165});166});167168test('No expanding text inside open tag in completion list (HTML)', () => {169return withRandomFileEditor(htmlContents, 'html', (editor, _doc) => {170editor.selection = new Selection(2, 4, 2, 4);171const cancelSrc = new CancellationTokenSource();172const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);173assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`);174return Promise.resolve();175});176});177178test('No expanding text inside open tag when there is no closing tag (HTML)', () => {179return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {180editor.selection = new Selection(9, 8, 9, 8);181await expandEmmetAbbreviation(null);182assert.strictEqual(editor.document.getText(), htmlContents);183return Promise.resolve();184});185});186187test('No expanding text inside open tag when there is no closing tag in completion list (HTML)', () => {188return withRandomFileEditor(htmlContents, 'html', (editor, _doc) => {189editor.selection = new Selection(9, 8, 9, 8);190const cancelSrc = new CancellationTokenSource();191const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);192assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`);193return Promise.resolve();194});195});196197test('No expanding text inside open tag when there is no closing tag when there is no parent node (HTML)', () => {198const fileContents = '<img s';199return withRandomFileEditor(fileContents, 'html', async (editor, _doc) => {200editor.selection = new Selection(0, 6, 0, 6);201await expandEmmetAbbreviation(null);202assert.strictEqual(editor.document.getText(), fileContents);203return Promise.resolve();204});205});206207test('No expanding text in completion list inside open tag when there is no closing tag when there is no parent node (HTML)', () => {208const fileContents = '<img s';209return withRandomFileEditor(fileContents, 'html', (editor, _doc) => {210editor.selection = new Selection(0, 6, 0, 6);211const cancelSrc = new CancellationTokenSource();212const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);213assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`);214return Promise.resolve();215});216});217218test('Expand css when inside style tag (HTML)', () => {219return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {220editor.selection = new Selection(13, 16, 13, 19);221const expandPromise = expandEmmetAbbreviation({ language: 'css' });222if (!expandPromise) {223return Promise.resolve();224}225await expandPromise;226assert.strictEqual(editor.document.getText(), htmlContents.replace('m10', 'margin: 10px;'));227return Promise.resolve();228});229});230231test('Expand css when inside style tag in completion list (HTML)', () => {232const abbreviation = 'm10';233const expandedText = 'margin: 10px;';234235return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {236editor.selection = new Selection(13, 16, 13, 19);237const cancelSrc = new CancellationTokenSource();238const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);239if (!completionPromise) {240assert.strictEqual(1, 2, `Problem with expanding m10`);241return Promise.resolve();242}243244const completionList = await completionPromise;245if (!completionList || !completionList.items || !completionList.items.length) {246assert.strictEqual(1, 2, `Problem with expanding m10`);247return Promise.resolve();248}249const emmetCompletionItem = completionList.items[0];250assert.strictEqual(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`);251assert.strictEqual(((<string>emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);252assert.strictEqual(emmetCompletionItem.filterText, abbreviation, `FilterText of completion item doesnt match.`);253return Promise.resolve();254});255});256257test('No expanding text inside style tag if position is not for property name (HTML)', () => {258return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {259editor.selection = new Selection(13, 14, 13, 14);260await expandEmmetAbbreviation(null);261assert.strictEqual(editor.document.getText(), htmlContents);262return Promise.resolve();263});264});265266test('Expand css when inside style attribute (HTML)', () => {267const styleAttributeContent = '<div style="m10" class="hello"></div>';268return withRandomFileEditor(styleAttributeContent, 'html', async (editor, _doc) => {269editor.selection = new Selection(0, 15, 0, 15);270const expandPromise = expandEmmetAbbreviation(null);271if (!expandPromise) {272return Promise.resolve();273}274await expandPromise;275assert.strictEqual(editor.document.getText(), styleAttributeContent.replace('m10', 'margin: 10px;'));276return Promise.resolve();277});278});279280test('Expand css when inside style attribute in completion list (HTML)', () => {281const abbreviation = 'm10';282const expandedText = 'margin: 10px;';283284return withRandomFileEditor('<div style="m10" class="hello"></div>', 'html', async (editor, _doc) => {285editor.selection = new Selection(0, 15, 0, 15);286const cancelSrc = new CancellationTokenSource();287const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);288if (!completionPromise) {289assert.strictEqual(1, 2, `Problem with expanding m10`);290return Promise.resolve();291}292293const completionList = await completionPromise;294if (!completionList || !completionList.items || !completionList.items.length) {295assert.strictEqual(1, 2, `Problem with expanding m10`);296return Promise.resolve();297}298const emmetCompletionItem = completionList.items[0];299assert.strictEqual(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`);300assert.strictEqual(((<string>emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);301assert.strictEqual(emmetCompletionItem.filterText, abbreviation, `FilterText of completion item doesnt match.`);302return Promise.resolve();303});304});305306test('Expand html when inside script tag with html type (HTML)', () => {307return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {308editor.selection = new Selection(21, 12, 21, 12);309const expandPromise = expandEmmetAbbreviation(null);310if (!expandPromise) {311return Promise.resolve();312}313await expandPromise;314assert.strictEqual(editor.document.getText(), htmlContents.replace('span.hello', '<span class="hello"></span>'));315return Promise.resolve();316});317});318319test('Expand html in completion list when inside script tag with html type (HTML)', () => {320const abbreviation = 'span.hello';321const expandedText = '<span class="hello"></span>';322323return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {324editor.selection = new Selection(21, 12, 21, 12);325const cancelSrc = new CancellationTokenSource();326const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);327if (!completionPromise) {328assert.strictEqual(1, 2, `Problem with expanding span.hello`);329return Promise.resolve();330}331332const completionList = await completionPromise;333if (!completionList || !completionList.items || !completionList.items.length) {334assert.strictEqual(1, 2, `Problem with expanding span.hello`);335return Promise.resolve();336}337const emmetCompletionItem = completionList.items[0];338assert.strictEqual(emmetCompletionItem.label, abbreviation, `Label of completion item doesnt match.`);339assert.strictEqual(((<string>emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);340return Promise.resolve();341});342});343344test('No expanding text inside script tag with javascript type (HTML)', () => {345return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {346editor.selection = new Selection(24, 12, 24, 12);347await expandEmmetAbbreviation(null);348assert.strictEqual(editor.document.getText(), htmlContents);349return Promise.resolve();350});351});352353test('No expanding text in completion list inside script tag with javascript type (HTML)', () => {354return withRandomFileEditor(htmlContents, 'html', (editor, _doc) => {355editor.selection = new Selection(24, 12, 24, 12);356const cancelSrc = new CancellationTokenSource();357const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);358assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`);359return Promise.resolve();360});361});362363test('Expand html when inside script tag with javascript type if js is mapped to html (HTML)', async () => {364const oldConfig = workspace.getConfiguration('emmet').inspect('includeLanguages')?.globalValue;365await workspace.getConfiguration('emmet').update('includeLanguages', { 'javascript': 'html' }, ConfigurationTarget.Global);366await withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {367editor.selection = new Selection(24, 10, 24, 10);368const expandPromise = expandEmmetAbbreviation(null);369if (!expandPromise) {370return Promise.resolve();371}372await expandPromise;373assert.strictEqual(editor.document.getText(), htmlContents.replace('span.bye', '<span class="bye"></span>'));374});375await workspace.getConfiguration('emmet').update('includeLanguages', oldConfig, ConfigurationTarget.Global);376});377378test('Expand html in completion list when inside script tag with javascript type if js is mapped to html (HTML)', async () => {379const abbreviation = 'span.bye';380const expandedText = '<span class="bye"></span>';381const oldConfig = workspace.getConfiguration('emmet').inspect('includeLanguages')?.globalValue;382await workspace.getConfiguration('emmet').update('includeLanguages', { 'javascript': 'html' }, ConfigurationTarget.Global);383await withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {384editor.selection = new Selection(24, 10, 24, 10);385const cancelSrc = new CancellationTokenSource();386const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);387if (!completionPromise) {388assert.strictEqual(1, 2, `Problem with expanding span.bye`);389return Promise.resolve();390}391const completionList = await completionPromise;392if (!completionList || !completionList.items || !completionList.items.length) {393assert.strictEqual(1, 2, `Problem with expanding span.bye`);394return Promise.resolve();395}396const emmetCompletionItem = completionList.items[0];397assert.strictEqual(emmetCompletionItem.label, abbreviation, `Label of completion item (${emmetCompletionItem.label}) doesnt match.`);398assert.strictEqual(((<string>emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);399return Promise.resolve();400});401await workspace.getConfiguration('emmet').update('includeLanguages', oldConfig, ConfigurationTarget.Global);402});403404// test('No expanding when html is excluded in the settings', () => {405// return workspace.getConfiguration('emmet').update('excludeLanguages', ['html'], ConfigurationTarget.Global).then(() => {406// return testExpandAbbreviation('html', new Selection(9, 6, 9, 6), '', '', true).then(() => {407// return workspace.getConfiguration('emmet').update('excludeLanguages', oldValueForExcludeLanguages ? oldValueForExcludeLanguages.globalValue : undefined, ConfigurationTarget.Global);408// });409// });410// });411412test('No expanding when html is excluded in the settings in completion list', async () => {413const oldConfig = workspace.getConfiguration('emmet').inspect('excludeLanguages')?.globalValue;414await workspace.getConfiguration('emmet').update('excludeLanguages', ['html'], ConfigurationTarget.Global);415await testHtmlCompletionProvider(new Selection(9, 6, 9, 6), '', '', true);416await workspace.getConfiguration('emmet').update('excludeLanguages', oldConfig, ConfigurationTarget.Global);417});418419// test('No expanding when php (mapped syntax) is excluded in the settings', () => {420// return workspace.getConfiguration('emmet').update('excludeLanguages', ['php'], ConfigurationTarget.Global).then(() => {421// return testExpandAbbreviation('php', new Selection(9, 6, 9, 6), '', '', true).then(() => {422// return workspace.getConfiguration('emmet').update('excludeLanguages', oldValueForExcludeLanguages ? oldValueForExcludeLanguages.globalValue : undefined, ConfigurationTarget.Global);423// });424// });425// });426427428});429430suite('Tests for jsx, xml and xsl', () => {431const oldValueForSyntaxProfiles = workspace.getConfiguration('emmet').inspect('syntaxProfiles');432teardown(closeAllEditors);433434test('Expand abbreviation with className instead of class in jsx', () => {435return withRandomFileEditor('ul.nav', 'javascriptreact', async (editor, _doc) => {436editor.selection = new Selection(0, 6, 0, 6);437await expandEmmetAbbreviation({ language: 'javascriptreact' });438assert.strictEqual(editor.document.getText(), '<ul className="nav"></ul>');439return Promise.resolve();440});441});442443test('Expand abbreviation with self closing tags for jsx', () => {444return withRandomFileEditor('img', 'javascriptreact', async (editor, _doc) => {445editor.selection = new Selection(0, 6, 0, 6);446await expandEmmetAbbreviation({ language: 'javascriptreact' });447assert.strictEqual(editor.document.getText(), '<img src="" alt="" />');448return Promise.resolve();449});450});451452test('Expand abbreviation with single quotes for jsx', async () => {453await workspace.getConfiguration('emmet').update('syntaxProfiles', { jsx: { 'attr_quotes': 'single' } }, ConfigurationTarget.Global);454return withRandomFileEditor('img', 'javascriptreact', async (editor, _doc) => {455editor.selection = new Selection(0, 6, 0, 6);456await expandEmmetAbbreviation({ language: 'javascriptreact' });457assert.strictEqual(editor.document.getText(), '<img src=\'\' alt=\'\' />');458return workspace.getConfiguration('emmet').update('syntaxProfiles', oldValueForSyntaxProfiles ? oldValueForSyntaxProfiles.globalValue : undefined, ConfigurationTarget.Global);459});460});461462test('Expand abbreviation with self closing tags for xml', () => {463return withRandomFileEditor('img', 'xml', async (editor, _doc) => {464editor.selection = new Selection(0, 6, 0, 6);465await expandEmmetAbbreviation({ language: 'xml' });466assert.strictEqual(editor.document.getText(), '<img src="" alt=""/>');467return Promise.resolve();468});469});470471test('Expand abbreviation with no self closing tags for html', () => {472return withRandomFileEditor('img', 'html', async (editor, _doc) => {473editor.selection = new Selection(0, 6, 0, 6);474await expandEmmetAbbreviation({ language: 'html' });475assert.strictEqual(editor.document.getText(), '<img src="" alt="">');476return Promise.resolve();477});478});479480test('Expand abbreviation with condition containing less than sign for jsx', () => {481return withRandomFileEditor('if (foo < 10) { span.bar', 'javascriptreact', async (editor, _doc) => {482editor.selection = new Selection(0, 27, 0, 27);483await expandEmmetAbbreviation({ language: 'javascriptreact' });484assert.strictEqual(editor.document.getText(), 'if (foo < 10) { <span className="bar"></span>');485return Promise.resolve();486});487});488489test('No expanding text inside open tag in completion list (jsx)', () => {490return testNoCompletion('jsx', htmlContents, new Selection(2, 4, 2, 4));491});492493test('No expanding tag that is opened, but not closed in completion list (jsx)', () => {494return testNoCompletion('jsx', htmlContents, new Selection(9, 6, 9, 6));495});496497test('No expanding text inside open tag when there is no closing tag in completion list (jsx)', () => {498return testNoCompletion('jsx', htmlContents, new Selection(9, 8, 9, 8));499});500501test('No expanding text in completion list inside open tag when there is no closing tag when there is no parent node (jsx)', () => {502return testNoCompletion('jsx', '<img s', new Selection(0, 6, 0, 6));503});504505});506507function testExpandAbbreviation(syntax: string, selection: Selection, abbreviation: string, expandedText: string, shouldFail?: boolean): Thenable<any> {508return withRandomFileEditor(htmlContents, syntax, async (editor, _doc) => {509editor.selection = selection;510const expandPromise = expandEmmetAbbreviation(null);511if (!expandPromise) {512if (!shouldFail) {513assert.strictEqual(1, 2, `Problem with expanding ${abbreviation} to ${expandedText}`);514}515return Promise.resolve();516}517await expandPromise;518assert.strictEqual(editor.document.getText(), htmlContents.replace(abbreviation, expandedText));519return Promise.resolve();520});521}522523function testHtmlCompletionProvider(selection: Selection, abbreviation: string, expandedText: string, shouldFail?: boolean): Thenable<any> {524return withRandomFileEditor(htmlContents, 'html', async (editor, _doc) => {525editor.selection = selection;526const cancelSrc = new CancellationTokenSource();527const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);528if (!completionPromise) {529if (!shouldFail) {530assert.strictEqual(1, 2, `Problem with expanding ${abbreviation} to ${expandedText}`);531}532return Promise.resolve();533}534535const completionList = await completionPromise;536if (!completionList || !completionList.items || !completionList.items.length) {537if (!shouldFail) {538assert.strictEqual(1, 2, `Problem with expanding ${abbreviation} to ${expandedText}`);539}540return Promise.resolve();541}542const emmetCompletionItem = completionList.items[0];543assert.strictEqual(emmetCompletionItem.label, abbreviation, `Label of completion item doesnt match.`);544assert.strictEqual(((<string>emmetCompletionItem.documentation) || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);545return Promise.resolve();546});547}548549function testNoCompletion(syntax: string, fileContents: string, selection: Selection): Thenable<any> {550return withRandomFileEditor(fileContents, syntax, (editor, _doc) => {551editor.selection = selection;552const cancelSrc = new CancellationTokenSource();553const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, invokeCompletionContext);554assert.strictEqual(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`);555return Promise.resolve();556});557}558559560