Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
021e95d7
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
021e95d7
编写于
12月 04, 2017
作者:
R
Ramya Achutha Rao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix #39578 Add completion provider tests for emmet
上级
6ac53feb
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
218 addition
and
3 deletion
+218
-3
extensions/emmet/src/abbreviationActions.ts
extensions/emmet/src/abbreviationActions.ts
+5
-1
extensions/emmet/src/test/abbreviationAction.test.ts
extensions/emmet/src/test/abbreviationAction.test.ts
+213
-2
未找到文件。
extensions/emmet/src/abbreviationActions.ts
浏览文件 @
021e95d7
...
...
@@ -272,7 +272,7 @@ export function isValidLocationForEmmetAbbreviation(document: vscode.TextDocumen
start
=
lastChildBeforePosition
.
end
;
lastChildBeforePosition
=
lastChildBeforePosition
.
nextSibling
;
}
let
textToBackTrack
=
document
.
getText
(
new
vscode
.
Range
(
start
,
abbreviationRange
.
start
));
let
textToBackTrack
=
document
.
getText
(
new
vscode
.
Range
(
start
.
line
,
start
.
character
,
abbreviationRange
.
start
.
line
,
abbreviationRange
.
start
.
character
));
// Worse case scenario is when cursor is inside a big chunk of text which needs to backtracked
// Backtrack only 500 offsets to ensure we dont waste time doing this
...
...
@@ -280,6 +280,10 @@ export function isValidLocationForEmmetAbbreviation(document: vscode.TextDocumen
textToBackTrack
=
textToBackTrack
.
substr
(
textToBackTrack
.
length
-
500
);
}
if
(
!
textToBackTrack
.
trim
())
{
return
true
;
}
let
valid
=
true
;
let
foundSpace
=
false
;
// If < is found before finding whitespace, then its valid abbreviation. Eg: <div|
let
i
=
textToBackTrack
.
length
-
1
;
...
...
extensions/emmet/src/test/abbreviationAction.test.ts
浏览文件 @
021e95d7
...
...
@@ -5,10 +5,12 @@
import
'
mocha
'
;
import
*
as
assert
from
'
assert
'
;
import
{
Selection
,
workspace
}
from
'
vscode
'
;
import
{
Selection
,
workspace
,
CompletionList
,
CancellationTokenSource
,
Position
}
from
'
vscode
'
;
import
{
withRandomFileEditor
,
closeAllEditors
}
from
'
./testUtils
'
;
import
{
expandEmmetAbbreviation
,
wrapWithAbbreviation
,
wrapIndividualLinesWithAbbreviation
}
from
'
../abbreviationActions
'
;
import
{
DefaultCompletionItemProvider
}
from
'
../defaultCompletionProvider
'
;
const
completionProvider
=
new
DefaultCompletionItemProvider
();
const
cssContents
=
`
.boo {
margin: 20px 10px;
...
...
@@ -122,50 +124,98 @@ suite('Tests for Expand Abbreviations (HTML)', () => {
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
3
,
23
,
3
,
23
),
'
img
'
,
'
<img src=
\
"
\
" alt=
\
"
\
">
'
);
});
test
(
'
Expand snippets in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
3
,
23
,
3
,
23
),
'
img
'
,
'
<img src=
\
"
\
" alt=
\
"
\
">
'
);
});
test
(
'
Expand abbreviation (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
5
,
25
,
5
,
25
),
'
ul>li
'
,
'
<ul>
\n\t\t\t
<li></li>
\n\t\t
</ul>
'
);
});
test
(
'
Expand abbreviation in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
5
,
25
,
5
,
25
),
'
ul>li
'
,
'
<ul>
\n\t
<li></li>
\n
</ul>
'
);
});
test
(
'
Expand text that is neither an abbreviation nor a snippet to tags (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
4
,
20
,
4
,
27
),
'
hithere
'
,
'
<hithere></hithere>
'
);
});
test
(
'
Do not Expand text that is neither an abbreviation nor a snippet to tags in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
4
,
20
,
4
,
27
),
'
hithere
'
,
'
<hithere></hithere>
'
,
true
);
});
test
(
'
Expand abbreviation with repeaters (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
6
,
27
,
6
,
27
),
'
ul>li*2
'
,
'
<ul>
\n\t\t\t
<li></li>
\n\t\t\t
<li></li>
\n\t\t
</ul>
'
);
});
test
(
'
Expand abbreviation with repeaters in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
6
,
27
,
6
,
27
),
'
ul>li*2
'
,
'
<ul>
\n\t
<li></li>
\n\t
<li></li>
\n
</ul>
'
);
});
test
(
'
Expand abbreviation with numbered repeaters (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
7
,
33
,
7
,
33
),
'
ul>li.item$*2
'
,
'
<ul>
\n\t\t\t
<li class="item1"></li>
\n\t\t\t
<li class="item2"></li>
\n\t\t
</ul>
'
);
});
test
(
'
Expand abbreviation with numbered repeaters in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
7
,
33
,
7
,
33
),
'
ul>li.item$*2
'
,
'
<ul>
\n\t
<li class="item1"></li>
\n\t
<li class="item2"></li>
\n
</ul>
'
);
});
test
(
'
Expand abbreviation with numbered repeaters with offset (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
8
,
36
,
8
,
36
),
'
ul>li.item$@44*2
'
,
'
<ul>
\n\t\t\t
<li class="item44"></li>
\n\t\t\t
<li class="item45"></li>
\n\t\t
</ul>
'
);
});
test
(
'
Expand abbreviation with numbered repeaters with offset in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
8
,
36
,
8
,
36
),
'
ul>li.item$@44*2
'
,
'
<ul>
\n\t
<li class="item44"></li>
\n\t
<li class="item45"></li>
\n
</ul>
'
);
});
test
(
'
Expand abbreviation with numbered repeaters in groups (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
17
,
16
,
17
,
16
),
'
(ul>li.item$)*2
'
,
'
<ul>
\n\t\t
<li class="item1"></li>
\n\t
</ul>
\n\t
<ul>
\n\t\t
<li class="item2"></li>
\n\t
</ul>
'
);
});
test
(
'
Expand abbreviation with numbered repeaters in groups in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
17
,
16
,
17
,
16
),
'
(ul>li.item$)*2
'
,
'
<ul>
\n\t
<li class="item1"></li>
\n
</ul>
\n
<ul>
\n\t
<li class="item2"></li>
\n
</ul>
'
);
});
test
(
'
Expand abbreviation with numbered repeaters in groups with sibling in the end (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
18
,
21
,
18
,
21
),
'
(ul>li.item$)*2+span
'
,
'
<ul>
\n\t\t
<li class="item1"></li>
\n\t
</ul>
\n\t
<ul>
\n\t\t
<li class="item2"></li>
\n\t
</ul>
\n\t
<span></span>
'
);
});
test
(
'
Expand abbreviation with numbered repeaters in groups with sibling in the end in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
18
,
21
,
18
,
21
),
'
(ul>li.item$)*2+span
'
,
'
<ul>
\n\t
<li class="item1"></li>
\n
</ul>
\n
<ul>
\n\t
<li class="item2"></li>
\n
</ul>
\n
<span></span>
'
);
});
test
(
'
Expand abbreviation with nested groups (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
19
,
19
,
19
,
19
),
'
(div>dl>(dt+dd)*2)
'
,
'
<div>
\n\t\t
<dl>
\n\t\t\t
<dt></dt>
\n\t\t\t
<dd></dd>
\n\t\t\t
<dt></dt>
\n\t\t\t
<dd></dd>
\n\t\t
</dl>
\n\t
</div>
'
);
});
test
(
'
Expand abbreviation with nested groups in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
19
,
19
,
19
,
19
),
'
(div>dl>(dt+dd)*2)
'
,
'
<div>
\n\t
<dl>
\n\t\t
<dt></dt>
\n\t\t
<dd></dd>
\n\t\t
<dt></dt>
\n\t\t
<dd></dd>
\n\t
</dl>
\n
</div>
'
);
});
test
(
'
Expand tag that is opened, but not closed (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
9
,
6
,
9
,
6
),
'
<div
'
,
'
<div></div>
'
);
});
test
(
'
Do not Expand tag that is opened, but not closed in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
9
,
6
,
9
,
6
),
'
<div
'
,
'
<div></div>
'
,
true
);
});
test
(
'
No expanding text inside open tag (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
2
,
4
,
2
,
4
),
''
,
''
,
true
);
});
test
(
'
No expanding text inside open tag in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
2
,
4
,
2
,
4
),
''
,
''
,
true
);
});
test
(
'
No expanding text inside open tag when there is no closing tag (HTML)
'
,
()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
9
,
8
,
9
,
8
),
''
,
''
,
true
);
});
test
(
'
No expanding text inside open tag when there is no closing tag in completion list (HTML)
'
,
()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
9
,
8
,
9
,
8
),
''
,
''
,
true
);
});
test
(
'
Expand css when inside style tag (HTML)
'
,
()
=>
{
return
withRandomFileEditor
(
htmlContents
,
'
html
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
13
,
3
,
13
,
6
);
...
...
@@ -180,6 +230,33 @@ suite('Tests for Expand Abbreviations (HTML)', () => {
});
});
test
(
'
Expand css when inside style tag in completion list (HTML)
'
,
()
=>
{
const
abbreviation
=
'
m10
'
;
const
expandedText
=
'
margin: 10px;
'
;
return
withRandomFileEditor
(
htmlContents
,
'
html
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
13
,
3
,
13
,
6
);
const
cancelSrc
=
new
CancellationTokenSource
();
const
completionPromise
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
editor
.
selection
.
active
,
cancelSrc
.
token
);
if
(
!
completionPromise
)
{
assert
.
equal
(
1
,
2
,
`Problem with expanding m10`
);
return
Promise
.
resolve
();
}
return
completionPromise
.
then
((
completionList
:
CompletionList
)
=>
{
if
(
!
completionList
.
items
||
!
completionList
.
items
.
length
)
{
assert
.
equal
(
1
,
2
,
`Problem with expanding m10`
);
return
Promise
.
resolve
();
}
const
emmetCompletionItem
=
completionList
.
items
[
0
];
assert
.
equal
(
emmetCompletionItem
.
label
,
expandedText
,
`Label of completion item doesnt match.`
);
assert
.
equal
((
<
string
>
emmetCompletionItem
.
documentation
||
''
).
replace
(
/
\|
/g
,
''
),
expandedText
,
`Docs of completion item doesnt match.`
);
assert
.
equal
(
emmetCompletionItem
.
filterText
,
abbreviation
,
`FilterText of completion item doesnt match.`
)
return
Promise
.
resolve
();
});
});
});
test
(
'
No expanding when html is excluded in the settings
'
,
()
=>
{
return
workspace
.
getConfiguration
(
'
emmet
'
).
update
(
'
excludeLanguages
'
,
[
'
html
'
]).
then
(()
=>
{
return
testExpandAbbreviation
(
'
html
'
,
new
Selection
(
9
,
6
,
9
,
6
),
''
,
''
,
true
).
then
(()
=>
{
...
...
@@ -188,6 +265,14 @@ suite('Tests for Expand Abbreviations (HTML)', () => {
});
});
test
(
'
No expanding when html is excluded in the settings in completion list
'
,
()
=>
{
return
workspace
.
getConfiguration
(
'
emmet
'
).
update
(
'
excludeLanguages
'
,
[
'
html
'
]).
then
(()
=>
{
return
testHtmlCompletionProvider
(
new
Selection
(
9
,
6
,
9
,
6
),
''
,
''
,
true
).
then
(()
=>
{
return
workspace
.
getConfiguration
(
'
emmet
'
).
update
(
'
excludeLanguages
'
,
[]);
});
});
});
test
(
'
No expanding when php (mapped syntax) is excluded in the settings
'
,
()
=>
{
return
workspace
.
getConfiguration
(
'
emmet
'
).
update
(
'
excludeLanguages
'
,
[
'
php
'
]).
then
(()
=>
{
return
testExpandAbbreviation
(
'
php
'
,
new
Selection
(
9
,
6
,
9
,
6
),
''
,
''
,
true
).
then
(()
=>
{
...
...
@@ -212,6 +297,39 @@ suite('Tests for Expand Abbreviations (CSS)', () => {
});
});
test
(
'
Expand abbreviation in completion list (CSS)
'
,
()
=>
{
const
abbreviation
=
'
m10
'
;
const
expandedText
=
'
margin: 10px;
'
;
return
withRandomFileEditor
(
cssContents
,
'
css
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
3
,
1
,
3
,
4
);
const
cancelSrc
=
new
CancellationTokenSource
();
const
completionPromise1
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
new
Position
(
3
,
4
),
cancelSrc
.
token
);
const
completionPromise2
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
new
Position
(
5
,
4
),
cancelSrc
.
token
);
if
(
!
completionPromise1
||
!
completionPromise2
)
{
assert
.
equal
(
1
,
2
,
`Problem with expanding m10`
);
return
Promise
.
resolve
();
}
const
callBack
=
(
completionList
:
CompletionList
)
=>
{
if
(
!
completionList
.
items
||
!
completionList
.
items
.
length
)
{
assert
.
equal
(
1
,
2
,
`Problem with expanding m10`
);
return
;
}
const
emmetCompletionItem
=
completionList
.
items
[
0
];
assert
.
equal
(
emmetCompletionItem
.
label
,
expandedText
,
`Label of completion item doesnt match.`
);
assert
.
equal
((
<
string
>
emmetCompletionItem
.
documentation
||
''
).
replace
(
/
\|
/g
,
''
),
expandedText
,
`Docs of completion item doesnt match.`
);
assert
.
equal
(
emmetCompletionItem
.
filterText
,
abbreviation
,
`FilterText of completion item doesnt match.`
);
};
return
Promise
.
all
<
CompletionList
>
([
completionPromise1
,
completionPromise2
]).
then
(([
result1
,
result2
])
=>
{
callBack
(
result1
);
callBack
(
result2
);
return
Promise
.
resolve
();
});
});
});
test
(
'
Expand abbreviation (SCSS)
'
,
()
=>
{
return
withRandomFileEditor
(
scssContents
,
'
scss
'
,
(
editor
,
doc
)
=>
{
editor
.
selections
=
[
...
...
@@ -227,7 +345,43 @@ suite('Tests for Expand Abbreviations (CSS)', () => {
});
});
test
(
'
Invalid locations for abbreviations in css
'
,
()
=>
{
test
(
'
Expand abbreviation in completion list (SCSS)
'
,
()
=>
{
return
withRandomFileEditor
(
scssContents
,
'
scss
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
3
,
4
,
3
,
4
);
const
cancelSrc
=
new
CancellationTokenSource
();
const
completionPromise1
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
new
Position
(
3
,
4
),
cancelSrc
.
token
);
const
completionPromise2
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
new
Position
(
5
,
5
),
cancelSrc
.
token
);
const
completionPromise3
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
new
Position
(
11
,
4
),
cancelSrc
.
token
);
const
completionPromise4
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
new
Position
(
14
,
5
),
cancelSrc
.
token
);
if
(
!
completionPromise1
||
!
completionPromise2
||
!
completionPromise3
||
!
completionPromise4
)
{
assert
.
equal
(
1
,
2
,
`Problem with expanding padding abbreviations`
);
return
Promise
.
resolve
();
}
const
callBack
=
(
completionList
:
CompletionList
,
abbreviation
,
expandedText
)
=>
{
if
(
!
completionList
.
items
||
!
completionList
.
items
.
length
)
{
assert
.
equal
(
1
,
2
,
`Problem with expanding m10`
);
return
;
}
const
emmetCompletionItem
=
completionList
.
items
[
0
];
assert
.
equal
(
emmetCompletionItem
.
label
,
expandedText
,
`Label of completion item doesnt match.`
);
assert
.
equal
((
<
string
>
emmetCompletionItem
.
documentation
||
''
).
replace
(
/
\|
/g
,
''
),
expandedText
,
`Docs of completion item doesnt match.`
);
assert
.
equal
(
emmetCompletionItem
.
filterText
,
abbreviation
,
`FilterText of completion item doesnt match.`
);
};
return
Promise
.
all
<
CompletionList
>
([
completionPromise1
,
completionPromise2
,
completionPromise3
,
completionPromise4
]).
then
(([
result1
,
result2
,
result3
,
result4
])
=>
{
callBack
(
result1
,
'
p10
'
,
'
padding: 10px;
'
);
callBack
(
result2
,
'
p20
'
,
'
padding: 20px;
'
);
callBack
(
result3
,
'
p10
'
,
'
padding: 30px;
'
);
callBack
(
result4
,
'
p20
'
,
'
padding: 40px;
'
);
return
Promise
.
resolve
();
});
});
});
test
(
'
Invalid locations for abbreviations in scss
'
,
()
=>
{
const
scssContentsNoExpand
=
`
m10
.boo {
...
...
@@ -249,6 +403,36 @@ m10
});
});
});
test
(
'
Invalid locations for abbreviations in scss in completion list
'
,
()
=>
{
const
scssContentsNoExpand
=
`
m10
.boo {
margin: 10px;
.hoo {
background:
}
}
`
return
withRandomFileEditor
(
scssContentsNoExpand
,
'
scss
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
new
Selection
(
1
,
3
,
1
,
3
);
// outside rule
const
cancelSrc
=
new
CancellationTokenSource
();
let
completionPromise
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
editor
.
selection
.
active
,
cancelSrc
.
token
);
if
(
completionPromise
)
{
assert
.
equal
(
1
,
2
,
`m10 gets expanded in invalid location`
);
}
editor
.
selection
=
new
Selection
(
5
,
15
,
5
,
15
);
// in the value part of property value
completionPromise
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
editor
.
selection
.
active
,
cancelSrc
.
token
);
if
(
completionPromise
)
{
assert
.
equal
(
1
,
2
,
`m10 gets expanded in invalid location`
);
}
return
Promise
.
resolve
();
});
});
});
suite
(
'
Tests for Wrap with Abbreviations
'
,
()
=>
{
...
...
@@ -429,6 +613,33 @@ function testExpandAbbreviation(syntax: string, selection: Selection, abbreviati
});
}
function
testHtmlCompletionProvider
(
selection
:
Selection
,
abbreviation
:
string
,
expandedText
:
string
,
shouldFail
?:
boolean
):
Thenable
<
any
>
{
return
withRandomFileEditor
(
htmlContents
,
'
html
'
,
(
editor
,
doc
)
=>
{
editor
.
selection
=
selection
;
const
cancelSrc
=
new
CancellationTokenSource
();
const
completionPromise
=
completionProvider
.
provideCompletionItems
(
editor
.
document
,
editor
.
selection
.
active
,
cancelSrc
.
token
);
if
(
!
completionPromise
)
{
if
(
!
shouldFail
)
{
assert
.
equal
(
1
,
2
,
`Problem with expanding
${
abbreviation
}
to
${
expandedText
}
`
);
}
return
Promise
.
resolve
();
}
return
completionPromise
.
then
((
completionList
:
CompletionList
)
=>
{
if
(
!
completionList
.
items
||
!
completionList
.
items
.
length
)
{
if
(
!
shouldFail
)
{
assert
.
equal
(
1
,
2
,
`Problem with expanding
${
abbreviation
}
to
${
expandedText
}
`
);
}
return
Promise
.
resolve
();
}
const
emmetCompletionItem
=
completionList
.
items
[
0
];
assert
.
equal
(
emmetCompletionItem
.
label
,
abbreviation
,
`Label of completion item doesnt match.`
);
assert
.
equal
((
<
string
>
emmetCompletionItem
.
documentation
||
''
).
replace
(
/
\|
/g
,
''
),
expandedText
,
`Docs of completion item doesnt match.`
);
return
Promise
.
resolve
();
});
});
}
function
testWrapWithAbbreviation
(
selections
:
Selection
[],
abbreviation
:
string
,
expectedContents
:
string
):
Thenable
<
any
>
{
return
withRandomFileEditor
(
htmlContentsForWrapTests
,
'
html
'
,
(
editor
,
doc
)
=>
{
editor
.
selections
=
selections
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录