From e252da38617bdacc9612873528d6477b64232d50 Mon Sep 17 00:00:00 2001 From: Gus Hurovich Date: Thu, 29 Mar 2018 17:48:32 -0700 Subject: [PATCH] Adding tests for stylesheets partial parsing (#46977) --- .../src/test/partialParsingStylesheet.test.ts | 255 ++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 extensions/emmet/src/test/partialParsingStylesheet.test.ts diff --git a/extensions/emmet/src/test/partialParsingStylesheet.test.ts b/extensions/emmet/src/test/partialParsingStylesheet.test.ts new file mode 100644 index 0000000000000..6c3b995960fa9 --- /dev/null +++ b/extensions/emmet/src/test/partialParsingStylesheet.test.ts @@ -0,0 +1,255 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { withRandomFileEditor } from './testUtils'; +import * as vscode from 'vscode'; +import { parsePartialStylesheet } from '../util'; +import { isValidLocationForEmmetAbbreviation } from '../abbreviationActions'; + + + +suite('Tests for partial parse of Stylesheets', () => { + test('Ignore block comment inside rule', function (): any { + const cssContents = ` +p { + margin: p ; + /*dn: none; p */ p + p + p. +} p +`; + return withRandomFileEditor(cssContents, '.css', (editor, doc) => { + let rangesForEmmet = [ + new vscode.Range(3, 18, 3, 19), // Same line after block comment + new vscode.Range(4, 1, 4, 2), // p after block comment + new vscode.Range(5, 1, 5, 3) // p. after block comment + ]; + let rangesNotEmmet = [ + new vscode.Range(1, 0, 1, 1), // Selector + new vscode.Range(2, 9, 2, 10), // Property value + new vscode.Range(3, 3, 3, 5), // dn inside block comment + new vscode.Range(3, 13, 3, 14), // p just before ending of block comment + new vscode.Range(6, 2, 6, 3) // p after ending of block + + ] + rangesForEmmet.forEach(range => { + assert.equal(isValidLocationForEmmetAbbreviation(doc, parsePartialStylesheet(doc, range.end), 'css', range.end, range), true); + }); + rangesNotEmmet.forEach(range => { + assert.equal(isValidLocationForEmmetAbbreviation(doc, parsePartialStylesheet(doc, range.end), 'css', range.end, range), false); + }); + + return Promise.resolve(); + }); + }); + + test('Ignore commented braces', function (): any { + const sassContents = ` +.foo +// .foo { brs +/* .foo { op.3 +dn { +*/ + @ +} bg +`; + return withRandomFileEditor(sassContents, '.scss', (editor, doc) => { + let rangesNotEmmet = [ + new vscode.Range(1, 0, 1, 4), // Selector + new vscode.Range(2, 3, 2, 7), // Line commented selector + new vscode.Range(3, 3, 3, 7), // Block commented selector + new vscode.Range(4, 0, 4, 2), // dn inside block comment + new vscode.Range(6, 1, 6, 2), // @ inside a rule whose opening brace is commented + new vscode.Range(7, 2, 7, 4) // bg after ending of badly constructed block + ]; + rangesNotEmmet.forEach(range => { + assert.equal(isValidLocationForEmmetAbbreviation(doc, parsePartialStylesheet(doc, range.end), 'scss', range.end, range), false); + }); + return Promise.resolve(); + }); + }); + + test('Block comment between selector and open brace', function (): any { + const cssContents = ` +p +/* First line +of a multiline +comment */ +{ + margin: p ; + /*dn: none; p */ p + p + p. +} p +`; + return withRandomFileEditor(cssContents, '.css', (editor, doc) => { + let rangesForEmmet = [ + new vscode.Range(7, 18, 7, 19), // Same line after block comment + new vscode.Range(8, 1, 8, 2), // p after block comment + new vscode.Range(9, 1, 9, 3) // p. after block comment + ]; + let rangesNotEmmet = [ + new vscode.Range(1, 2, 1, 3), // Selector + new vscode.Range(3, 3, 3, 4), // Inside multiline comment + new vscode.Range(5, 0, 5, 1), // Opening Brace + new vscode.Range(6, 9, 6, 10), // Property value + new vscode.Range(7, 3, 7, 5), // dn inside block comment + new vscode.Range(7, 13, 7, 14), // p just before ending of block comment + new vscode.Range(10, 2, 10, 3) // p after ending of block + ]; + rangesForEmmet.forEach(range => { + assert.equal(isValidLocationForEmmetAbbreviation(doc, parsePartialStylesheet(doc, range.end), 'css', range.end, range), true); + }); + rangesNotEmmet.forEach(range => { + assert.equal(isValidLocationForEmmetAbbreviation(doc, parsePartialStylesheet(doc, range.end), 'css', range.end, range), false); + }); + return Promise.resolve(); + }); + }); + + test('Nested and consecutive rulesets with errors', function (): any { + const sassContents = ` +.foo{ + a + a +}}{ p +} +.bar{ + @ + .rudi { + @ + } +}}} +`; + return withRandomFileEditor(sassContents, '.scss', (editor, doc) => { + let rangesForEmmet = [ + new vscode.Range(2, 1, 2, 2), // Inside a ruleset before errors + new vscode.Range(3, 1, 3, 2), // Inside a ruleset after no serious error + new vscode.Range(7, 1, 7, 2), // @ inside a so far well structured ruleset + new vscode.Range(9, 2, 9, 3), // @ inside a so far well structured nested ruleset + ]; + let rangesNotEmmet = [ + new vscode.Range(4, 4, 4, 5), // p inside ruleset without proper selector + new vscode.Range(6, 3, 6, 4) // In selector + ]; + rangesForEmmet.forEach(range => { + assert.equal(isValidLocationForEmmetAbbreviation(doc, parsePartialStylesheet(doc, range.end), 'scss', range.end, range), true); + }); + rangesNotEmmet.forEach(range => { + assert.equal(isValidLocationForEmmetAbbreviation(doc, parsePartialStylesheet(doc, range.end), 'scss', range.end, range), false); + }); + return Promise.resolve(); + }); + }); + + test('One liner sass', function (): any { + const sassContents = ` +.foo{dn}.bar{.boo{dn}dn}.comd{/*{dn*/p{div{dn}} }.foo{.other{dn}} dn +`; + return withRandomFileEditor(sassContents, '.scss', (editor, doc) => { + let rangesForEmmet = [ + new vscode.Range(1, 5, 1, 7), // Inside a ruleset + new vscode.Range(1, 18, 1, 20), // Inside a nested ruleset + new vscode.Range(1, 21, 1, 23), // Inside ruleset after nested one. + new vscode.Range(1, 43, 1, 45), // Inside nested ruleset after comment + new vscode.Range(1, 61, 1, 63) // Inside nested ruleset + ]; + let rangesNotEmmet = [ + new vscode.Range(1, 3, 1, 4), // In foo selector + new vscode.Range(1, 10, 1, 11), // In bar selector + new vscode.Range(1, 15, 1, 16), // In boo selector + new vscode.Range(1, 28, 1, 29), // In comd selector + new vscode.Range(1, 33, 1, 34), // In commented dn + new vscode.Range(1, 37, 1, 38), // In p selector + new vscode.Range(1, 39, 1, 42), // In div selector + new vscode.Range(1, 66, 1, 68) // Outside any ruleset + ]; + rangesForEmmet.forEach(range => { + assert.equal(isValidLocationForEmmetAbbreviation(doc, parsePartialStylesheet(doc, range.end), 'scss', range.end, range), true); + }); + rangesNotEmmet.forEach(range => { + assert.equal(isValidLocationForEmmetAbbreviation(doc, parsePartialStylesheet(doc, range.end), 'scss', range.end, range), false); + }); + return Promise.resolve(); + }); + }); + + test('Variables and interpolation', function (): any { + const sassContents = ` +p.#{dn} { + p.3 + #{$attr}-color: blue; + dn +} op +.foo{nes{ted}} { + dn +} +`; + return withRandomFileEditor(sassContents, '.scss', (editor, doc) => { + let rangesForEmmet = [ + new vscode.Range(2, 1, 2, 4), // p.3 inside a ruleset whose selector uses interpolation + new vscode.Range(3, 1, 3, 2), // # inside ruleset + new vscode.Range(4, 1, 4, 3) // dn inside ruleset after property with variable + ]; + let rangesNotEmmet = [ + new vscode.Range(1, 0, 1, 1), // In p in selector + new vscode.Range(1, 2, 1, 3), // In # in selector + new vscode.Range(1, 4, 1, 6), // In dn inside variable in selector + new vscode.Range(3, 7, 3, 8), // r of attr inside variable + new vscode.Range(5, 2, 5, 4), // op after ruleset + new vscode.Range(7, 1, 7, 3) // dn inside ruleset whose selector uses nested interpolation + ]; + rangesForEmmet.forEach(range => { + assert.equal(isValidLocationForEmmetAbbreviation(doc, parsePartialStylesheet(doc, range.end), 'scss', range.end, range), true); + }); + rangesNotEmmet.forEach(range => { + assert.equal(isValidLocationForEmmetAbbreviation(doc, parsePartialStylesheet(doc, range.end), 'scss', range.end, range), false); + }); + return Promise.resolve(); + }); + }); + + test('Comments in sass', function (): any { + const sassContents = ` +.foo{ + /* p // p */ brs6-2p + dn +} +p +/* c +om +ment */{ + m10 +} +.boo{ + op.3 +} +`; + return withRandomFileEditor(sassContents, '.scss', (editor, doc) => { + let rangesForEmmet = [ + new vscode.Range(2, 14, 2, 21), // brs6-2p with a block commented line comment ('/* */' overrides '//') + new vscode.Range(3, 1, 3, 3), // dn after a line with combined comments inside a ruleset + new vscode.Range(9, 1, 9, 4), // m10 inside ruleset whose selector is before a comment + new vscode.Range(12, 1, 12, 5) // op3 inside a ruleset with commented extra braces + ]; + let rangesNotEmmet = [ + new vscode.Range(2, 4, 2, 5), // In p inside block comment + new vscode.Range(2, 9, 2, 10), // In p inside block comment and after line comment + new vscode.Range(6, 3, 6, 4) // In c inside block comment + ]; + rangesForEmmet.forEach(range => { + assert.equal(isValidLocationForEmmetAbbreviation(doc, parsePartialStylesheet(doc, range.end), 'scss', range.end, range), true); + }); + rangesNotEmmet.forEach(range => { + assert.equal(isValidLocationForEmmetAbbreviation(doc, parsePartialStylesheet(doc, range.end), 'scss', range.end, range), false); + }); + return Promise.resolve(); + }); + }); + + +}); \ No newline at end of file