Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/emmet/src/test/partialParsingStylesheet.test.ts
4774 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import 'mocha';
7
import * as assert from 'assert';
8
import { closeAllEditors, withRandomFileEditor } from './testUtils';
9
import * as vscode from 'vscode';
10
import { parsePartialStylesheet, getFlatNode } from '../util';
11
import { isValidLocationForEmmetAbbreviation } from '../abbreviationActions';
12
13
suite('Tests for partial parse of Stylesheets', () => {
14
teardown(closeAllEditors);
15
16
function isValid(doc: vscode.TextDocument, range: vscode.Range, syntax: string): boolean {
17
const rootNode = parsePartialStylesheet(doc, range.end);
18
const endOffset = doc.offsetAt(range.end);
19
const currentNode = getFlatNode(rootNode, endOffset, true);
20
return isValidLocationForEmmetAbbreviation(doc, rootNode, currentNode, syntax, endOffset, range);
21
}
22
23
test('Ignore block comment inside rule', function (): any {
24
const cssContents = `
25
p {
26
margin: p ;
27
/*dn: none; p */ p
28
p
29
p.
30
} p
31
`;
32
return withRandomFileEditor(cssContents, '.css', (_, doc) => {
33
const rangesForEmmet = [
34
new vscode.Range(3, 18, 3, 19), // Same line after block comment
35
new vscode.Range(4, 1, 4, 2), // p after block comment
36
new vscode.Range(5, 1, 5, 3) // p. after block comment
37
];
38
const rangesNotEmmet = [
39
new vscode.Range(1, 0, 1, 1), // Selector
40
new vscode.Range(2, 9, 2, 10), // Property value
41
new vscode.Range(3, 3, 3, 5), // dn inside block comment
42
new vscode.Range(3, 13, 3, 14), // p just before ending of block comment
43
new vscode.Range(6, 2, 6, 3) // p after ending of block
44
45
];
46
rangesForEmmet.forEach(range => {
47
assert.strictEqual(isValid(doc, range, 'css'), true);
48
});
49
rangesNotEmmet.forEach(range => {
50
assert.strictEqual(isValid(doc, range, 'css'), false);
51
});
52
53
return Promise.resolve();
54
});
55
});
56
57
test('Ignore commented braces', function (): any {
58
const sassContents = `
59
.foo
60
// .foo { brs
61
/* .foo { op.3
62
dn {
63
*/
64
bgc
65
} bg
66
`;
67
return withRandomFileEditor(sassContents, '.scss', (_, doc) => {
68
const rangesNotEmmet = [
69
new vscode.Range(1, 0, 1, 4), // Selector
70
new vscode.Range(2, 3, 2, 7), // Line commented selector
71
new vscode.Range(3, 3, 3, 7), // Block commented selector
72
new vscode.Range(4, 0, 4, 2), // dn inside block comment
73
new vscode.Range(6, 1, 6, 2), // bgc inside a rule whose opening brace is commented
74
new vscode.Range(7, 2, 7, 4) // bg after ending of badly constructed block
75
];
76
rangesNotEmmet.forEach(range => {
77
assert.strictEqual(isValid(doc, range, 'scss'), false);
78
});
79
return Promise.resolve();
80
});
81
});
82
83
test('Block comment between selector and open brace', function (): any {
84
const cssContents = `
85
p
86
/* First line
87
of a multiline
88
comment */
89
{
90
margin: p ;
91
/*dn: none; p */ p
92
p
93
p.
94
} p
95
`;
96
return withRandomFileEditor(cssContents, '.css', (_, doc) => {
97
const rangesForEmmet = [
98
new vscode.Range(7, 18, 7, 19), // Same line after block comment
99
new vscode.Range(8, 1, 8, 2), // p after block comment
100
new vscode.Range(9, 1, 9, 3) // p. after block comment
101
];
102
const rangesNotEmmet = [
103
new vscode.Range(1, 2, 1, 3), // Selector
104
new vscode.Range(3, 3, 3, 4), // Inside multiline comment
105
new vscode.Range(5, 0, 5, 1), // Opening Brace
106
new vscode.Range(6, 9, 6, 10), // Property value
107
new vscode.Range(7, 3, 7, 5), // dn inside block comment
108
new vscode.Range(7, 13, 7, 14), // p just before ending of block comment
109
new vscode.Range(10, 2, 10, 3) // p after ending of block
110
];
111
rangesForEmmet.forEach(range => {
112
assert.strictEqual(isValid(doc, range, 'css'), true);
113
});
114
rangesNotEmmet.forEach(range => {
115
assert.strictEqual(isValid(doc, range, 'css'), false);
116
});
117
return Promise.resolve();
118
});
119
});
120
121
test('Nested and consecutive rulesets with errors', function (): any {
122
const sassContents = `
123
.foo{
124
a
125
a
126
}}{ p
127
}
128
.bar{
129
@
130
.rudi {
131
@
132
}
133
}}}
134
`;
135
return withRandomFileEditor(sassContents, '.scss', (_, doc) => {
136
const rangesForEmmet = [
137
new vscode.Range(2, 1, 2, 2), // Inside a ruleset before errors
138
new vscode.Range(3, 1, 3, 2), // Inside a ruleset after no serious error
139
new vscode.Range(7, 1, 7, 2), // @ inside a so far well structured ruleset
140
new vscode.Range(9, 2, 9, 3), // @ inside a so far well structured nested ruleset
141
];
142
const rangesNotEmmet = [
143
new vscode.Range(4, 4, 4, 5), // p inside ruleset without proper selector
144
new vscode.Range(6, 3, 6, 4) // In selector
145
];
146
rangesForEmmet.forEach(range => {
147
assert.strictEqual(isValid(doc, range, 'scss'), true);
148
});
149
rangesNotEmmet.forEach(range => {
150
assert.strictEqual(isValid(doc, range, 'scss'), false);
151
});
152
return Promise.resolve();
153
});
154
});
155
156
test('One liner sass', function (): any {
157
const sassContents = `
158
.foo{dn}.bar{.boo{dn}dn}.comd{/*{dn*/p{div{dn}} }.foo{.other{dn}} dn
159
`;
160
return withRandomFileEditor(sassContents, '.scss', (_, doc) => {
161
const rangesForEmmet = [
162
new vscode.Range(1, 5, 1, 7), // Inside a ruleset
163
new vscode.Range(1, 18, 1, 20), // Inside a nested ruleset
164
new vscode.Range(1, 21, 1, 23), // Inside ruleset after nested one.
165
new vscode.Range(1, 43, 1, 45), // Inside nested ruleset after comment
166
new vscode.Range(1, 61, 1, 63) // Inside nested ruleset
167
];
168
const rangesNotEmmet = [
169
new vscode.Range(1, 3, 1, 4), // In foo selector
170
new vscode.Range(1, 10, 1, 11), // In bar selector
171
new vscode.Range(1, 15, 1, 16), // In boo selector
172
new vscode.Range(1, 28, 1, 29), // In comd selector
173
new vscode.Range(1, 33, 1, 34), // In commented dn
174
new vscode.Range(1, 37, 1, 38), // In p selector
175
new vscode.Range(1, 39, 1, 42), // In div selector
176
new vscode.Range(1, 66, 1, 68) // Outside any ruleset
177
];
178
rangesForEmmet.forEach(range => {
179
assert.strictEqual(isValid(doc, range, 'scss'), true);
180
});
181
rangesNotEmmet.forEach(range => {
182
assert.strictEqual(isValid(doc, range, 'scss'), false);
183
});
184
return Promise.resolve();
185
});
186
});
187
188
test('Variables and interpolation', function (): any {
189
const sassContents = `
190
p.#{dn} {
191
p.3
192
#{$attr}-color: blue;
193
dn
194
} op
195
.foo{nes{ted}} {
196
dn
197
}
198
`;
199
return withRandomFileEditor(sassContents, '.scss', (_, doc) => {
200
const rangesForEmmet = [
201
new vscode.Range(2, 1, 2, 4), // p.3 inside a ruleset whose selector uses interpolation
202
new vscode.Range(4, 1, 4, 3) // dn inside ruleset after property with variable
203
];
204
const rangesNotEmmet = [
205
new vscode.Range(1, 0, 1, 1), // In p in selector
206
new vscode.Range(1, 2, 1, 3), // In # in selector
207
new vscode.Range(1, 4, 1, 6), // In dn inside variable in selector
208
new vscode.Range(3, 7, 3, 8), // r of attr inside variable
209
new vscode.Range(5, 2, 5, 4), // op after ruleset
210
new vscode.Range(7, 1, 7, 3), // dn inside ruleset whose selector uses nested interpolation
211
new vscode.Range(3, 1, 3, 2), // # inside ruleset
212
];
213
rangesForEmmet.forEach(range => {
214
assert.strictEqual(isValid(doc, range, 'scss'), true);
215
});
216
rangesNotEmmet.forEach(range => {
217
assert.strictEqual(isValid(doc, range, 'scss'), false);
218
});
219
return Promise.resolve();
220
});
221
});
222
223
test('Comments in sass', function (): any {
224
const sassContents = `
225
.foo{
226
/* p // p */ brs6-2p
227
dn
228
}
229
p
230
/* c
231
om
232
ment */{
233
m10
234
}
235
.boo{
236
op.3
237
}
238
`;
239
return withRandomFileEditor(sassContents, '.scss', (_, doc) => {
240
const rangesForEmmet = [
241
new vscode.Range(2, 14, 2, 21), // brs6-2p with a block commented line comment ('/* */' overrides '//')
242
new vscode.Range(3, 1, 3, 3), // dn after a line with combined comments inside a ruleset
243
new vscode.Range(9, 1, 9, 4), // m10 inside ruleset whose selector is before a comment
244
new vscode.Range(12, 1, 12, 5) // op3 inside a ruleset with commented extra braces
245
];
246
const rangesNotEmmet = [
247
new vscode.Range(2, 4, 2, 5), // In p inside block comment
248
new vscode.Range(2, 9, 2, 10), // In p inside block comment and after line comment
249
new vscode.Range(6, 3, 6, 4) // In c inside block comment
250
];
251
rangesForEmmet.forEach(range => {
252
assert.strictEqual(isValid(doc, range, 'scss'), true);
253
});
254
rangesNotEmmet.forEach(range => {
255
assert.strictEqual(isValid(doc, range, 'scss'), false);
256
});
257
return Promise.resolve();
258
});
259
});
260
261
262
});
263
264