Path: blob/main/extensions/emmet/src/test/partialParsingStylesheet.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 { closeAllEditors, withRandomFileEditor } from './testUtils';8import * as vscode from 'vscode';9import { parsePartialStylesheet, getFlatNode } from '../util';10import { isValidLocationForEmmetAbbreviation } from '../abbreviationActions';1112suite('Tests for partial parse of Stylesheets', () => {13teardown(closeAllEditors);1415function isValid(doc: vscode.TextDocument, range: vscode.Range, syntax: string): boolean {16const rootNode = parsePartialStylesheet(doc, range.end);17const endOffset = doc.offsetAt(range.end);18const currentNode = getFlatNode(rootNode, endOffset, true);19return isValidLocationForEmmetAbbreviation(doc, rootNode, currentNode, syntax, endOffset, range);20}2122test('Ignore block comment inside rule', function (): any {23const cssContents = `24p {25margin: p ;26/*dn: none; p */ p27p28p.29} p30`;31return withRandomFileEditor(cssContents, '.css', (_, doc) => {32const rangesForEmmet = [33new vscode.Range(3, 18, 3, 19), // Same line after block comment34new vscode.Range(4, 1, 4, 2), // p after block comment35new vscode.Range(5, 1, 5, 3) // p. after block comment36];37const rangesNotEmmet = [38new vscode.Range(1, 0, 1, 1), // Selector39new vscode.Range(2, 9, 2, 10), // Property value40new vscode.Range(3, 3, 3, 5), // dn inside block comment41new vscode.Range(3, 13, 3, 14), // p just before ending of block comment42new vscode.Range(6, 2, 6, 3) // p after ending of block4344];45rangesForEmmet.forEach(range => {46assert.strictEqual(isValid(doc, range, 'css'), true);47});48rangesNotEmmet.forEach(range => {49assert.strictEqual(isValid(doc, range, 'css'), false);50});5152return Promise.resolve();53});54});5556test('Ignore commented braces', function (): any {57const sassContents = `58.foo59// .foo { brs60/* .foo { op.361dn {62*/63bgc64} bg65`;66return withRandomFileEditor(sassContents, '.scss', (_, doc) => {67const rangesNotEmmet = [68new vscode.Range(1, 0, 1, 4), // Selector69new vscode.Range(2, 3, 2, 7), // Line commented selector70new vscode.Range(3, 3, 3, 7), // Block commented selector71new vscode.Range(4, 0, 4, 2), // dn inside block comment72new vscode.Range(6, 1, 6, 2), // bgc inside a rule whose opening brace is commented73new vscode.Range(7, 2, 7, 4) // bg after ending of badly constructed block74];75rangesNotEmmet.forEach(range => {76assert.strictEqual(isValid(doc, range, 'scss'), false);77});78return Promise.resolve();79});80});8182test('Block comment between selector and open brace', function (): any {83const cssContents = `84p85/* First line86of a multiline87comment */88{89margin: p ;90/*dn: none; p */ p91p92p.93} p94`;95return withRandomFileEditor(cssContents, '.css', (_, doc) => {96const rangesForEmmet = [97new vscode.Range(7, 18, 7, 19), // Same line after block comment98new vscode.Range(8, 1, 8, 2), // p after block comment99new vscode.Range(9, 1, 9, 3) // p. after block comment100];101const rangesNotEmmet = [102new vscode.Range(1, 2, 1, 3), // Selector103new vscode.Range(3, 3, 3, 4), // Inside multiline comment104new vscode.Range(5, 0, 5, 1), // Opening Brace105new vscode.Range(6, 9, 6, 10), // Property value106new vscode.Range(7, 3, 7, 5), // dn inside block comment107new vscode.Range(7, 13, 7, 14), // p just before ending of block comment108new vscode.Range(10, 2, 10, 3) // p after ending of block109];110rangesForEmmet.forEach(range => {111assert.strictEqual(isValid(doc, range, 'css'), true);112});113rangesNotEmmet.forEach(range => {114assert.strictEqual(isValid(doc, range, 'css'), false);115});116return Promise.resolve();117});118});119120test('Nested and consecutive rulesets with errors', function (): any {121const sassContents = `122.foo{123a124a125}}{ p126}127.bar{128@129.rudi {130@131}132}}}133`;134return withRandomFileEditor(sassContents, '.scss', (_, doc) => {135const rangesForEmmet = [136new vscode.Range(2, 1, 2, 2), // Inside a ruleset before errors137new vscode.Range(3, 1, 3, 2), // Inside a ruleset after no serious error138new vscode.Range(7, 1, 7, 2), // @ inside a so far well structured ruleset139new vscode.Range(9, 2, 9, 3), // @ inside a so far well structured nested ruleset140];141const rangesNotEmmet = [142new vscode.Range(4, 4, 4, 5), // p inside ruleset without proper selector143new vscode.Range(6, 3, 6, 4) // In selector144];145rangesForEmmet.forEach(range => {146assert.strictEqual(isValid(doc, range, 'scss'), true);147});148rangesNotEmmet.forEach(range => {149assert.strictEqual(isValid(doc, range, 'scss'), false);150});151return Promise.resolve();152});153});154155test('One liner sass', function (): any {156const sassContents = `157.foo{dn}.bar{.boo{dn}dn}.comd{/*{dn*/p{div{dn}} }.foo{.other{dn}} dn158`;159return withRandomFileEditor(sassContents, '.scss', (_, doc) => {160const rangesForEmmet = [161new vscode.Range(1, 5, 1, 7), // Inside a ruleset162new vscode.Range(1, 18, 1, 20), // Inside a nested ruleset163new vscode.Range(1, 21, 1, 23), // Inside ruleset after nested one.164new vscode.Range(1, 43, 1, 45), // Inside nested ruleset after comment165new vscode.Range(1, 61, 1, 63) // Inside nested ruleset166];167const rangesNotEmmet = [168new vscode.Range(1, 3, 1, 4), // In foo selector169new vscode.Range(1, 10, 1, 11), // In bar selector170new vscode.Range(1, 15, 1, 16), // In boo selector171new vscode.Range(1, 28, 1, 29), // In comd selector172new vscode.Range(1, 33, 1, 34), // In commented dn173new vscode.Range(1, 37, 1, 38), // In p selector174new vscode.Range(1, 39, 1, 42), // In div selector175new vscode.Range(1, 66, 1, 68) // Outside any ruleset176];177rangesForEmmet.forEach(range => {178assert.strictEqual(isValid(doc, range, 'scss'), true);179});180rangesNotEmmet.forEach(range => {181assert.strictEqual(isValid(doc, range, 'scss'), false);182});183return Promise.resolve();184});185});186187test('Variables and interpolation', function (): any {188const sassContents = `189p.#{dn} {190p.3191#{$attr}-color: blue;192dn193} op194.foo{nes{ted}} {195dn196}197`;198return withRandomFileEditor(sassContents, '.scss', (_, doc) => {199const rangesForEmmet = [200new vscode.Range(2, 1, 2, 4), // p.3 inside a ruleset whose selector uses interpolation201new vscode.Range(4, 1, 4, 3) // dn inside ruleset after property with variable202];203const rangesNotEmmet = [204new vscode.Range(1, 0, 1, 1), // In p in selector205new vscode.Range(1, 2, 1, 3), // In # in selector206new vscode.Range(1, 4, 1, 6), // In dn inside variable in selector207new vscode.Range(3, 7, 3, 8), // r of attr inside variable208new vscode.Range(5, 2, 5, 4), // op after ruleset209new vscode.Range(7, 1, 7, 3), // dn inside ruleset whose selector uses nested interpolation210new vscode.Range(3, 1, 3, 2), // # inside ruleset211];212rangesForEmmet.forEach(range => {213assert.strictEqual(isValid(doc, range, 'scss'), true);214});215rangesNotEmmet.forEach(range => {216assert.strictEqual(isValid(doc, range, 'scss'), false);217});218return Promise.resolve();219});220});221222test('Comments in sass', function (): any {223const sassContents = `224.foo{225/* p // p */ brs6-2p226dn227}228p229/* c230om231ment */{232m10233}234.boo{235op.3236}237`;238return withRandomFileEditor(sassContents, '.scss', (_, doc) => {239const rangesForEmmet = [240new vscode.Range(2, 14, 2, 21), // brs6-2p with a block commented line comment ('/* */' overrides '//')241new vscode.Range(3, 1, 3, 3), // dn after a line with combined comments inside a ruleset242new vscode.Range(9, 1, 9, 4), // m10 inside ruleset whose selector is before a comment243new vscode.Range(12, 1, 12, 5) // op3 inside a ruleset with commented extra braces244];245const rangesNotEmmet = [246new vscode.Range(2, 4, 2, 5), // In p inside block comment247new vscode.Range(2, 9, 2, 10), // In p inside block comment and after line comment248new vscode.Range(6, 3, 6, 4) // In c inside block comment249];250rangesForEmmet.forEach(range => {251assert.strictEqual(isValid(doc, range, 'scss'), true);252});253rangesNotEmmet.forEach(range => {254assert.strictEqual(isValid(doc, range, 'scss'), false);255});256return Promise.resolve();257});258});259260261});262263264