Path: blob/main/extensions/emmet/src/test/editPointSelectItemBalance.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 } from 'vscode';8import { withRandomFileEditor, closeAllEditors } from './testUtils';9import { fetchEditPoint } from '../editPoint';10import { fetchSelectItem } from '../selectItem';11import { balanceOut, balanceIn } from '../balance';1213suite('Tests for Next/Previous Select/Edit point and Balance actions', () => {14teardown(closeAllEditors);1516const cssContents = `17.boo {18margin: 20px 10px;19background-image: url('tryme.png');20}2122.boo .hoo {23margin: 10px;24}25`;2627const scssContents = `28.boo {29margin: 20px 10px;30background-image: url('tryme.png');3132.boo .hoo {33margin: 10px;34}35}36`;3738const htmlContents = `39<!DOCTYPE html>40<html lang="en">41<head>42<meta charset="">43<meta name="viewport" content="width=device-width, initial-scale=1.0">44<title></title>45</head>46<body>47<div>48\t\t49</div>50<div class="header">51<ul class="nav main">52<li class="item1">Item 1</li>53<li class="item2">Item 2</li>54</ul>55</div>56</body>57</html>58`;5960test('Emmet Next/Prev Edit point in html file', function (): any {61return withRandomFileEditor(htmlContents, '.html', (editor, _) => {62editor.selections = [new Selection(1, 5, 1, 5)];6364const expectedNextEditPoints: [number, number][] = [[4, 16], [6, 8], [10, 2], [10, 2]];65expectedNextEditPoints.forEach(([line, col]) => {66fetchEditPoint('next');67testSelection(editor.selection, col, line);68});6970const expectedPrevEditPoints = [[6, 8], [4, 16], [4, 16]];71expectedPrevEditPoints.forEach(([line, col]) => {72fetchEditPoint('prev');73testSelection(editor.selection, col, line);74});7576return Promise.resolve();77});78});7980test('Emmet Select Next/Prev Item in html file', function (): any {81return withRandomFileEditor(htmlContents, '.html', (editor, _) => {82editor.selections = [new Selection(2, 2, 2, 2)];8384const expectedNextItemPoints: [number, number, number][] = [85[2, 1, 5], // html86[2, 6, 15], // lang="en"87[2, 12, 14], // en88[3, 1, 5], // head89[4, 2, 6], // meta90[4, 7, 17], // charset=""91[5, 2, 6], // meta92[5, 7, 22], // name="viewport"93[5, 13, 21], // viewport94[5, 23, 70], // content="width=device-width, initial-scale=1.0"95[5, 32, 69], // width=device-width, initial-scale=1.096[5, 32, 51], // width=device-width,97[5, 52, 69], // initial-scale=1.098[6, 2, 7] // title99];100expectedNextItemPoints.forEach(([line, colstart, colend]) => {101fetchSelectItem('next');102testSelection(editor.selection, colstart, line, colend);103});104105editor.selections = [new Selection(6, 15, 6, 15)];106expectedNextItemPoints.reverse().forEach(([line, colstart, colend]) => {107fetchSelectItem('prev');108testSelection(editor.selection, colstart, line, colend);109});110111return Promise.resolve();112});113});114115test('Emmet Select Next/Prev item at boundary', function (): any {116return withRandomFileEditor(htmlContents, '.html', (editor, _) => {117editor.selections = [new Selection(4, 1, 4, 1)];118119fetchSelectItem('next');120testSelection(editor.selection, 2, 4, 6);121122editor.selections = [new Selection(4, 1, 4, 1)];123124fetchSelectItem('prev');125testSelection(editor.selection, 1, 3, 5);126127return Promise.resolve();128});129});130131test('Emmet Next/Prev Item in html template', function (): any {132const templateContents = `133<script type="text/template">134<div class="header">135<ul class="nav main">136</ul>137</div>138</script>139`;140return withRandomFileEditor(templateContents, '.html', (editor, _) => {141editor.selections = [new Selection(2, 2, 2, 2)];142143const expectedNextItemPoints: [number, number, number][] = [144[2, 2, 5], // div145[2, 6, 20], // class="header"146[2, 13, 19], // header147[3, 3, 5], // ul148[3, 6, 22], // class="nav main"149[3, 13, 21], // nav main150[3, 13, 16], // nav151[3, 17, 21], // main152];153expectedNextItemPoints.forEach(([line, colstart, colend]) => {154fetchSelectItem('next');155testSelection(editor.selection, colstart, line, colend);156});157158editor.selections = [new Selection(4, 1, 4, 1)];159expectedNextItemPoints.reverse().forEach(([line, colstart, colend]) => {160fetchSelectItem('prev');161testSelection(editor.selection, colstart, line, colend);162});163164return Promise.resolve();165});166});167168test('Emmet Select Next/Prev Item in css file', function (): any {169return withRandomFileEditor(cssContents, '.css', (editor, _) => {170editor.selections = [new Selection(0, 0, 0, 0)];171172const expectedNextItemPoints: [number, number, number][] = [173[1, 0, 4], // .boo174[2, 1, 19], // margin: 20px 10px;175[2, 9, 18], // 20px 10px176[2, 9, 13], // 20px177[2, 14, 18], // 10px178[3, 1, 36], // background-image: url('tryme.png');179[3, 19, 35], // url('tryme.png')180[6, 0, 9], // .boo .hoo181[7, 1, 14], // margin: 10px;182[7, 9, 13], // 10px183];184expectedNextItemPoints.forEach(([line, colstart, colend]) => {185fetchSelectItem('next');186testSelection(editor.selection, colstart, line, colend);187});188189editor.selections = [new Selection(9, 0, 9, 0)];190expectedNextItemPoints.reverse().forEach(([line, colstart, colend]) => {191fetchSelectItem('prev');192testSelection(editor.selection, colstart, line, colend);193});194195return Promise.resolve();196});197});198199test('Emmet Select Next/Prev Item in scss file with nested rules', function (): any {200return withRandomFileEditor(scssContents, '.scss', (editor, _) => {201editor.selections = [new Selection(0, 0, 0, 0)];202203const expectedNextItemPoints: [number, number, number][] = [204[1, 0, 4], // .boo205[2, 1, 19], // margin: 20px 10px;206[2, 9, 18], // 20px 10px207[2, 9, 13], // 20px208[2, 14, 18], // 10px209[3, 1, 36], // background-image: url('tryme.png');210[3, 19, 35], // url('tryme.png')211[5, 1, 10], // .boo .hoo212[6, 2, 15], // margin: 10px;213[6, 10, 14], // 10px214];215expectedNextItemPoints.forEach(([line, colstart, colend]) => {216fetchSelectItem('next');217testSelection(editor.selection, colstart, line, colend);218});219220editor.selections = [new Selection(8, 0, 8, 0)];221expectedNextItemPoints.reverse().forEach(([line, colstart, colend]) => {222fetchSelectItem('prev');223testSelection(editor.selection, colstart, line, colend);224});225226return Promise.resolve();227});228});229230test('Emmet Balance Out in html file', function (): any {231return withRandomFileEditor(htmlContents, 'html', (editor, _) => {232233editor.selections = [new Selection(14, 6, 14, 10)];234const expectedBalanceOutRanges: [number, number, number, number][] = [235[14, 3, 14, 32], // <li class="item1">Item 1</li>236[13, 23, 16, 2], // inner contents of <ul class="nav main">237[13, 2, 16, 7], // outer contents of <ul class="nav main">238[12, 21, 17, 1], // inner contents of <div class="header">239[12, 1, 17, 7], // outer contents of <div class="header">240[8, 6, 18, 0], // inner contents of <body>241[8, 0, 18, 7], // outer contents of <body>242[2, 16, 19, 0], // inner contents of <html>243[2, 0, 19, 7], // outer contents of <html>244];245expectedBalanceOutRanges.forEach(([linestart, colstart, lineend, colend]) => {246balanceOut();247testSelection(editor.selection, colstart, linestart, colend, lineend);248});249250editor.selections = [new Selection(12, 7, 12, 7)];251const expectedBalanceInRanges: [number, number, number, number][] = [252[12, 21, 17, 1], // inner contents of <div class="header">253[13, 2, 16, 7], // outer contents of <ul class="nav main">254[13, 23, 16, 2], // inner contents of <ul class="nav main">255[14, 3, 14, 32], // <li class="item1">Item 1</li>256[14, 21, 14, 27] // Item 1257];258expectedBalanceInRanges.forEach(([linestart, colstart, lineend, colend]) => {259balanceIn();260testSelection(editor.selection, colstart, linestart, colend, lineend);261});262263return Promise.resolve();264});265});266267test('Emmet Balance In using the same stack as Balance out in html file', function (): any {268return withRandomFileEditor(htmlContents, 'html', (editor, _) => {269270editor.selections = [new Selection(15, 6, 15, 10)];271const expectedBalanceOutRanges: [number, number, number, number][] = [272[15, 3, 15, 32], // <li class="item1">Item 2</li>273[13, 23, 16, 2], // inner contents of <ul class="nav main">274[13, 2, 16, 7], // outer contents of <ul class="nav main">275[12, 21, 17, 1], // inner contents of <div class="header">276[12, 1, 17, 7], // outer contents of <div class="header">277[8, 6, 18, 0], // inner contents of <body>278[8, 0, 18, 7], // outer contents of <body>279[2, 16, 19, 0], // inner contents of <html>280[2, 0, 19, 7], // outer contents of <html>281];282expectedBalanceOutRanges.forEach(([linestart, colstart, lineend, colend]) => {283balanceOut();284testSelection(editor.selection, colstart, linestart, colend, lineend);285});286287expectedBalanceOutRanges.reverse().forEach(([linestart, colstart, lineend, colend]) => {288testSelection(editor.selection, colstart, linestart, colend, lineend);289balanceIn();290});291292return Promise.resolve();293});294});295296test('Emmet Balance In when selection doesnt span entire node or its inner contents', function (): any {297return withRandomFileEditor(htmlContents, 'html', (editor, _) => {298299editor.selection = new Selection(13, 7, 13, 10); // Inside the open tag of <ul class="nav main">300balanceIn();301testSelection(editor.selection, 23, 13, 2, 16); // inner contents of <ul class="nav main">302303editor.selection = new Selection(16, 4, 16, 5); // Inside the open close of <ul class="nav main">304balanceIn();305testSelection(editor.selection, 23, 13, 2, 16); // inner contents of <ul class="nav main">306307editor.selection = new Selection(13, 7, 14, 2); // Inside the open tag of <ul class="nav main"> and the next line308balanceIn();309testSelection(editor.selection, 23, 13, 2, 16); // inner contents of <ul class="nav main">310311return Promise.resolve();312});313});314315test('Emmet Balance In/Out in html template', function (): any {316const htmlTemplate = `317<script type="text/html">318<div class="header">319<ul class="nav main">320<li class="item1">Item 1</li>321<li class="item2">Item 2</li>322</ul>323</div>324</script>`;325326return withRandomFileEditor(htmlTemplate, 'html', (editor, _) => {327328editor.selections = [new Selection(5, 24, 5, 24)];329const expectedBalanceOutRanges: [number, number, number, number][] = [330[5, 20, 5, 26], // <li class="item1">``Item 2''</li>331[5, 2, 5, 31], // ``<li class="item1">Item 2</li>''332[3, 22, 6, 1], // inner contents of ul333[3, 1, 6, 6], // outer contents of ul334[2, 20, 7, 0], // inner contents of div335[2, 0, 7, 6], // outer contents of div336];337expectedBalanceOutRanges.forEach(([linestart, colstart, lineend, colend]) => {338balanceOut();339testSelection(editor.selection, colstart, linestart, colend, lineend);340});341342expectedBalanceOutRanges.pop();343expectedBalanceOutRanges.reverse().forEach(([linestart, colstart, lineend, colend]) => {344balanceIn();345testSelection(editor.selection, colstart, linestart, colend, lineend);346});347348return Promise.resolve();349});350});351});352353function testSelection(selection: Selection, startChar: number, startline: number, endChar?: number, endLine?: number) {354assert.strictEqual(selection.anchor.line, startline);355assert.strictEqual(selection.anchor.character, startChar);356if (!endLine && endLine !== 0) {357assert.strictEqual(selection.isSingleLine, true);358} else {359assert.strictEqual(selection.active.line, endLine);360}361if (!endChar && endChar !== 0) {362assert.strictEqual(selection.isEmpty, true);363} else {364assert.strictEqual(selection.active.character, endChar);365}366}367368369