/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import 'mocha'; import * as assert from 'assert'; import { Selection, workspace, ConfigurationTarget } from 'vscode'; import { withRandomFileEditor, closeAllEditors } from './testUtils'; import { wrapWithAbbreviation } from '../abbreviationActions'; const htmlContentsForBlockWrapTests = ` `; const htmlContentsForInlineWrapTests = ` `; const wrapBlockElementExpected = ` `; const wrapInlineElementExpected = ` `; const wrapSnippetExpected = ` `; const wrapMultiLineAbbrExpected = ` `; // technically a bug, but also a feature (requested behaviour) // https://github.com/microsoft/vscode/issues/78015 const wrapInlineElementExpectedFormatFalse = ` `; suite('Tests for Wrap with Abbreviations', () => { teardown(closeAllEditors); const multiCursors = [new Selection(2, 6, 2, 6), new Selection(3, 6, 3, 6), new Selection(4, 6, 4, 6)]; const multiCursorsWithSelection = [new Selection(2, 2, 2, 28), new Selection(3, 2, 3, 33), new Selection(4, 6, 4, 36)]; const multiCursorsWithFullLineSelection = [new Selection(2, 0, 2, 28), new Selection(3, 0, 3, 33), new Selection(4, 0, 4, 36)]; const oldValueForSyntaxProfiles = workspace.getConfiguration('emmet').inspect('syntaxProfile'); test('Wrap with block element using multi cursor', () => { return testWrapWithAbbreviation(multiCursors, 'div', wrapBlockElementExpected, htmlContentsForBlockWrapTests); }); test('Wrap with inline element using multi cursor', () => { return testWrapWithAbbreviation(multiCursors, 'span', wrapInlineElementExpected, htmlContentsForInlineWrapTests); }); test('Wrap with snippet using multi cursor', () => { return testWrapWithAbbreviation(multiCursors, 'a', wrapSnippetExpected, htmlContentsForBlockWrapTests); }); test('Wrap with multi line abbreviation using multi cursor', () => { return testWrapWithAbbreviation(multiCursors, 'ul>li', wrapMultiLineAbbrExpected, htmlContentsForBlockWrapTests); }); test('Wrap with block element using multi cursor selection', () => { return testWrapWithAbbreviation(multiCursorsWithSelection, 'div', wrapBlockElementExpected, htmlContentsForBlockWrapTests); }); test('Wrap with inline element using multi cursor selection', () => { return testWrapWithAbbreviation(multiCursorsWithSelection, 'span', wrapInlineElementExpected, htmlContentsForInlineWrapTests); }); test('Wrap with snippet using multi cursor selection', () => { return testWrapWithAbbreviation(multiCursorsWithSelection, 'a', wrapSnippetExpected, htmlContentsForBlockWrapTests); }); test('Wrap with multi line abbreviation using multi cursor selection', () => { return testWrapWithAbbreviation(multiCursorsWithSelection, 'ul>li', wrapMultiLineAbbrExpected, htmlContentsForBlockWrapTests); }); test('Wrap with block element using multi cursor full line selection', () => { return testWrapWithAbbreviation(multiCursorsWithFullLineSelection, 'div', wrapBlockElementExpected, htmlContentsForBlockWrapTests); }); test('Wrap with inline element using multi cursor full line selection', () => { return testWrapWithAbbreviation(multiCursorsWithFullLineSelection, 'span', wrapInlineElementExpected, htmlContentsForInlineWrapTests); }); test('Wrap with snippet using multi cursor full line selection', () => { return testWrapWithAbbreviation(multiCursorsWithFullLineSelection, 'a', wrapSnippetExpected, htmlContentsForBlockWrapTests); }); test('Wrap with multi line abbreviation using multi cursor full line selection', () => { return testWrapWithAbbreviation(multiCursorsWithFullLineSelection, 'ul>li', wrapMultiLineAbbrExpected, htmlContentsForBlockWrapTests); }); test('Wrap with abbreviation and comment filter', () => { const contents = ` `; const expectedContents = ` `; return testWrapWithAbbreviation([new Selection(2, 0, 2, 0)], 'li.hello|c', expectedContents, contents); }); test('Wrap with abbreviation link', () => { const contents = ` `; const expectedContents = `
`; return testWrapWithAbbreviation([new Selection(1, 2, 1, 2)], 'a[href="https://example.com"]>div', expectedContents, contents); }); test('Wrap with abbreviation entire node when cursor is on opening tag', () => { const contents = ` `; const expectedContents = `
`; return testWrapWithAbbreviation([new Selection(1, 2, 1, 2)], 'div', expectedContents, contents); }); test('Wrap with abbreviation entire node when cursor is on closing tag', () => { const contents = ` `; const expectedContents = `
`; return testWrapWithAbbreviation([new Selection(3, 2, 3, 2)], 'div', expectedContents, contents); }); test('Wrap with abbreviation inner node in cdata', () => { const contents = `

Test 2

]]> hello `; const expectedContents = `

Test 2

]]> hello `; return testWrapWithAbbreviation([new Selection(6, 5, 6, 5)], 'div', expectedContents, contents); }); test('Wrap with abbreviation inner node in script in cdata', () => { const contents = ` `; const expectedContents = ` `; return testWrapWithAbbreviation([new Selection(4, 10, 4, 10)], 'div', expectedContents, contents); }); test('Wrap with abbreviation inner node in cdata one-liner', () => { const contents = ` `; // this result occurs because no selection on the open/close p tag was given const expectedContents = ` `; return testWrapWithAbbreviation([new Selection(2, 15, 2, 15)], 'div', expectedContents, contents); }); test('Wrap with multiline abbreviation doesnt add extra spaces', () => { // Issue #29898 const contents = ` hello `; const expectedContents = ` `; return testWrapWithAbbreviation([new Selection(1, 2, 1, 2)], 'ul>li>a', expectedContents, contents); }); test('Wrap individual lines with abbreviation', () => { const contents = ` `; const wrapIndividualLinesExpected = ` `; return testWrapIndividualLinesWithAbbreviation([new Selection(2, 2, 3, 33)], 'ul>li.hello$*', wrapIndividualLinesExpected, contents); }); test('Wrap individual lines with abbreviation with extra space selected', () => { const contents = ` `; const wrapIndividualLinesExpected = ` `; return testWrapIndividualLinesWithAbbreviation([new Selection(2, 1, 4, 0)], 'ul>li.hello$*', wrapIndividualLinesExpected, contents); }); test('Wrap individual lines with abbreviation with comment filter', () => { const contents = ` `; const wrapIndividualLinesExpected = ` `; return testWrapIndividualLinesWithAbbreviation([new Selection(2, 2, 3, 33)], 'ul>li.hello*|c', wrapIndividualLinesExpected, contents); }); test('Wrap individual lines with abbreviation and trim', () => { const contents = ` `; const wrapIndividualLinesExpected = ` `; return testWrapIndividualLinesWithAbbreviation([new Selection(2, 3, 3, 16)], 'ul>li.hello$*|t', wrapIndividualLinesExpected, contents); }); test('Wrap with abbreviation and format set to false', () => { return workspace.getConfiguration('emmet').update('syntaxProfiles', { 'html': { 'format': false } }, ConfigurationTarget.Global).then(() => { return testWrapWithAbbreviation(multiCursors, 'h1', wrapInlineElementExpectedFormatFalse, htmlContentsForBlockWrapTests).then(() => { return workspace.getConfiguration('emmet').update('syntaxProfiles', oldValueForSyntaxProfiles ? oldValueForSyntaxProfiles.globalValue : undefined, ConfigurationTarget.Global); }); }); }); test('Wrap multi line selections with abbreviation', () => { const htmlContentsForWrapMultiLineTests = ` `; const wrapMultiLineExpected = ` `; return testWrapWithAbbreviation([new Selection(2, 4, 3, 9), new Selection(5, 4, 6, 9)], 'div', wrapMultiLineExpected, htmlContentsForWrapMultiLineTests); }); test('Wrap multiline with abbreviation uses className for jsx files', () => { const wrapMultiLineJsxExpected = ` `; return testWrapWithAbbreviation([new Selection(2, 2, 4, 36)], '.hello', wrapMultiLineJsxExpected, htmlContentsForBlockWrapTests, 'jsx'); }); test('Wrap individual line with abbreviation uses className for jsx files', () => { const wrapIndividualLinesJsxExpected = ` `; return testWrapIndividualLinesWithAbbreviation([new Selection(2, 2, 4, 36)], '.hello$*', wrapIndividualLinesJsxExpected, htmlContentsForBlockWrapTests, 'jsx'); }); test('Wrap with abbreviation merge overlapping computed ranges', () => { const contents = ` `; const expectedContents = `
`; return testWrapWithAbbreviation([new Selection(1, 2, 1, 2), new Selection(1, 10, 1, 10)], 'div', expectedContents, contents); }); test('Wrap with abbreviation ignore invalid abbreviation', () => { const contents = ` `; return testWrapWithAbbreviation([new Selection(1, 2, 1, 2)], 'div]', contents, contents); }); }); function testWrapWithAbbreviation(selections: Selection[], abbreviation: string, expectedContents: string, input: string, fileExtension: string = 'html'): Thenable { return withRandomFileEditor(input, fileExtension, (editor, _) => { editor.selections = selections; const promise = wrapWithAbbreviation({ abbreviation }); if (!promise) { assert.strictEqual(1, 2, 'Wrap with Abbreviation returned undefined.'); return Promise.resolve(); } return promise.then(() => { assert.strictEqual(editor.document.getText(), expectedContents); return Promise.resolve(); }); }); } function testWrapIndividualLinesWithAbbreviation(selections: Selection[], abbreviation: string, expectedContents: string, input: string, fileExtension: string = 'html'): Thenable { return withRandomFileEditor(input, fileExtension, (editor, _) => { editor.selections = selections; const promise = wrapWithAbbreviation({ abbreviation }); if (!promise) { assert.strictEqual(1, 2, 'Wrap individual lines with Abbreviation returned undefined.'); return Promise.resolve(); } return promise.then(() => { assert.strictEqual(editor.document.getText(), expectedContents); return Promise.resolve(); }); }); }