Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
71cc864c
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
71cc864c
编写于
1月 12, 2018
作者:
S
Sandeep Somavarapu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
#40018 Revert to use label as id. Do not use index instead have a counter for duplicate labels
上级
f2c8145d
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
193 addition
and
136 deletion
+193
-136
src/vs/workbench/api/node/extHostTreeViews.ts
src/vs/workbench/api/node/extHostTreeViews.ts
+118
-105
src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts
...kbench/test/electron-browser/api/extHostTreeViews.test.ts
+75
-31
未找到文件。
src/vs/workbench/api/node/extHostTreeViews.ts
浏览文件 @
71cc864c
...
@@ -77,7 +77,9 @@ interface TreeNode {
...
@@ -77,7 +77,9 @@ interface TreeNode {
class
ExtHostTreeView
<
T
>
extends
Disposable
{
class
ExtHostTreeView
<
T
>
extends
Disposable
{
private
static
ROOT_HANDLE
=
'
0
'
;
private
static
LABEL_HANDLE_PREFIX
=
'
0
'
;
private
rootHandles
:
TreeItemHandle
[]
=
[];
private
elements
:
Map
<
TreeItemHandle
,
T
>
=
new
Map
<
TreeItemHandle
,
T
>
();
private
elements
:
Map
<
TreeItemHandle
,
T
>
=
new
Map
<
TreeItemHandle
,
T
>
();
private
nodes
:
Map
<
T
,
TreeNode
>
=
new
Map
<
T
,
TreeNode
>
();
private
nodes
:
Map
<
T
,
TreeNode
>
=
new
Map
<
T
,
TreeNode
>
();
...
@@ -85,49 +87,36 @@ class ExtHostTreeView<T> extends Disposable {
...
@@ -85,49 +87,36 @@ class ExtHostTreeView<T> extends Disposable {
super
();
super
();
this
.
proxy
.
$registerView
(
viewId
);
this
.
proxy
.
$registerView
(
viewId
);
if
(
dataProvider
.
onDidChangeTreeData
)
{
if
(
dataProvider
.
onDidChangeTreeData
)
{
this
.
_register
(
debounceEvent
<
T
,
T
[]
>
(
dataProvider
.
onDidChangeTreeData
,
(
last
,
current
)
=>
last
?
[...
last
,
current
]
:
[
current
],
200
)(
elements
=>
this
.
_
refresh
(
elements
)));
this
.
_register
(
debounceEvent
<
T
,
T
[]
>
(
dataProvider
.
onDidChangeTreeData
,
(
last
,
current
)
=>
last
?
[...
last
,
current
]
:
[
current
],
200
)(
elements
=>
this
.
refresh
(
elements
)));
}
}
}
}
getChildren
(
parentHandle
?:
TreeItemHandle
):
TPromise
<
ITreeItem
[]
>
{
getChildren
(
parentHandle
?:
TreeItemHandle
):
TPromise
<
ITreeItem
[]
>
{
let
parentElement
;
const
parentElement
=
parentHandle
?
this
.
getExtensionElement
(
parentHandle
)
:
void
0
;
if
(
parentHandle
)
{
if
(
parentHandle
&&
!
parentElement
)
{
parentElement
=
this
.
getExtensionElement
(
parentHandle
);
console
.
error
(
`No tree item with id \'
${
parentHandle
}
\' found.`
);
if
(
!
parentElement
)
{
return
TPromise
.
as
([]);
return
TPromise
.
wrapError
<
ITreeItem
[]
>
(
new
Error
(
localize
(
'
treeItem.notFound
'
,
'
No tree item with id
\'
{0}
\'
found.
'
,
parentHandle
)));
}
}
}
this
.
clearChildren
(
parentElement
);
return
asWinJsPromise
(()
=>
this
.
dataProvider
.
getChildren
(
parentElement
))
return
asWinJsPromise
(()
=>
this
.
dataProvider
.
getChildren
(
parentElement
))
.
then
(
elements
=>
{
.
then
(
elements
=>
TPromise
.
join
(
elements
=
coalesce
(
elements
||
[]);
coalesce
(
elements
||
[]).
map
(
element
=>
return
TPromise
.
join
(
elements
.
map
((
element
,
index
)
=>
{
asWinJsPromise
(()
=>
this
.
dataProvider
.
getTreeItem
(
element
))
const
node
=
this
.
nodes
.
get
(
element
);
.
then
(
extTreeItem
=>
{
const
currentHandle
=
node
&&
node
.
parentHandle
===
parentHandle
?
node
.
handle
:
void
0
;
if
(
extTreeItem
)
{
return
this
.
resolveElement
(
element
,
currentHandle
?
currentHandle
:
index
,
parentHandle
)
return
{
element
,
extTreeItem
};
.
then
(
treeItem
=>
{
if
(
treeItem
)
{
if
(
!
currentHandle
)
{
// update the caches if current handle is not used
this
.
nodes
.
set
(
element
,
{
handle
:
treeItem
.
handle
,
parentHandle
,
childrenHandles
:
void
0
});
this
.
elements
.
set
(
treeItem
.
handle
,
element
);
}
}
}
return
treeItem
;
return
null
;
});
})
})).
then
(
treeItems
=>
this
.
updateChildren
(
coalesce
(
treeItems
),
parentElement
));
))).
then
(
extTreeItems
=>
extTreeItems
.
map
((({
element
,
extTreeItem
})
=>
this
.
createTreeItem
(
element
,
extTreeItem
,
parentHandle
))));
});
}
}
getExtensionElement
(
treeItemHandle
:
TreeItemHandle
):
T
{
getExtensionElement
(
treeItemHandle
:
TreeItemHandle
):
T
{
return
this
.
elements
.
get
(
treeItemHandle
);
return
this
.
elements
.
get
(
treeItemHandle
);
}
}
private
_
refresh
(
elements
:
T
[]):
void
{
private
refresh
(
elements
:
T
[]):
void
{
const
hasRoot
=
elements
.
some
(
element
=>
!
element
);
const
hasRoot
=
elements
.
some
(
element
=>
!
element
);
if
(
hasRoot
)
{
if
(
hasRoot
)
{
this
.
proxy
.
$refresh
(
this
.
viewId
);
this
.
proxy
.
$refresh
(
this
.
viewId
);
...
@@ -139,26 +128,63 @@ class ExtHostTreeView<T> extends Disposable {
...
@@ -139,26 +128,63 @@ class ExtHostTreeView<T> extends Disposable {
}
}
}
}
private
resolveElement
(
element
:
T
,
handleOrIndex
:
TreeItemHandle
|
number
,
parentHandle
:
TreeItemHandle
):
TPromise
<
ITreeItem
>
{
private
getHandlesToRefresh
(
elements
:
T
[]):
TreeItemHandle
[]
{
return
asWinJsPromise
(()
=>
this
.
dataProvider
.
getTreeItem
(
element
))
const
elementsToUpdate
=
new
Set
<
TreeItemHandle
>
();
.
then
(
extTreeItem
=>
this
.
massageTreeItem
(
element
,
extTreeItem
,
handleOrIndex
,
parentHandle
));
for
(
const
element
of
elements
)
{
let
elementNode
=
this
.
nodes
.
get
(
element
);
if
(
elementNode
&&
!
elementsToUpdate
.
has
(
elementNode
.
handle
))
{
// check if an ancestor of extElement is already in the elements to update list
let
currentNode
=
elementNode
;
while
(
currentNode
&&
currentNode
.
parentHandle
&&
!
elementsToUpdate
.
has
(
currentNode
.
parentHandle
))
{
const
parentElement
=
this
.
elements
.
get
(
currentNode
.
parentHandle
);
currentNode
=
this
.
nodes
.
get
(
parentElement
);
}
if
(
!
currentNode
.
parentHandle
)
{
elementsToUpdate
.
add
(
elementNode
.
handle
);
}
}
}
}
private
massageTreeItem
(
element
:
T
,
extensionTreeItem
:
vscode
.
TreeItem
,
handleOrIndex
:
TreeItemHandle
|
number
,
parentHandle
:
TreeItemHandle
):
ITreeItem
{
const
handlesToUpdate
:
TreeItemHandle
[]
=
[];
if
(
!
extensionTreeItem
)
{
// Take only top level elements
return
null
;
elementsToUpdate
.
forEach
((
handle
)
=>
{
const
element
=
this
.
elements
.
get
(
handle
);
let
node
=
this
.
nodes
.
get
(
element
);
if
(
node
&&
!
elementsToUpdate
.
has
(
node
.
parentHandle
))
{
handlesToUpdate
.
push
(
handle
);
}
});
return
handlesToUpdate
;
}
}
private
refreshHandles
(
itemHandles
:
TreeItemHandle
[]):
TPromise
<
void
>
{
const
itemsToRefresh
:
{
[
handle
:
string
]:
ITreeItem
}
=
{};
const
promises
:
TPromise
<
void
>
[]
=
[];
itemHandles
.
forEach
(
treeItemHandle
=>
{
const
extElement
=
this
.
getExtensionElement
(
treeItemHandle
);
const
node
=
this
.
nodes
.
get
(
extElement
);
promises
.
push
(
asWinJsPromise
(()
=>
this
.
dataProvider
.
getTreeItem
(
extElement
))
.
then
(
extTreeItem
=>
{
if
(
extTreeItem
)
{
itemsToRefresh
[
treeItemHandle
]
=
this
.
createTreeItem
(
extElement
,
extTreeItem
,
node
.
parentHandle
);
}
}));
});
return
TPromise
.
join
(
promises
)
.
then
(
treeItems
=>
this
.
proxy
.
$refresh
(
this
.
viewId
,
itemsToRefresh
));
}
private
createTreeItem
(
element
:
T
,
extensionTreeItem
:
vscode
.
TreeItem
,
parentHandle
:
TreeItemHandle
):
ITreeItem
{
const
handle
=
this
.
createHandle
(
element
,
extensionTreeItem
,
parentHandle
);
const
icon
=
this
.
getLightIconPath
(
extensionTreeItem
);
const
icon
=
this
.
getLightIconPath
(
extensionTreeItem
);
const
label
=
extensionTreeItem
.
label
;
this
.
update
(
element
,
handle
,
parentHandle
);
const
handle
=
typeof
handleOrIndex
===
'
number
'
?
this
.
generateHandle
(
label
,
handleOrIndex
,
parentHandle
)
// create the handle
:
handleOrIndex
;
// reuse the passed handle
return
{
return
{
handle
,
handle
,
parentHandle
,
parentHandle
,
label
,
label
:
extensionTreeItem
.
label
,
command
:
extensionTreeItem
.
command
?
this
.
commands
.
toInternal
(
extensionTreeItem
.
command
)
:
void
0
,
command
:
extensionTreeItem
.
command
?
this
.
commands
.
toInternal
(
extensionTreeItem
.
command
)
:
void
0
,
contextValue
:
extensionTreeItem
.
contextValue
,
contextValue
:
extensionTreeItem
.
contextValue
,
icon
,
icon
,
...
@@ -167,10 +193,19 @@ class ExtHostTreeView<T> extends Disposable {
...
@@ -167,10 +193,19 @@ class ExtHostTreeView<T> extends Disposable {
};
};
}
}
private
generateHandle
(
label
:
string
,
index
:
number
,
parentHandle
:
TreeItemHandle
):
TreeItemHandle
{
private
createHandle
(
element
:
T
,
{
label
}:
vscode
.
TreeItem
,
parentHandle
?
:
TreeItemHandle
):
TreeItemHandle
{
parentHandle
=
parentHandle
?
parentHandle
:
ExtHostTreeView
.
ROOT_HANDLE
;
const
prefix
=
parentHandle
?
parentHandle
:
ExtHostTreeView
.
LABEL_HANDLE_PREFIX
;
label
=
label
.
indexOf
(
'
/
'
)
!==
-
1
?
label
.
replace
(
'
/
'
,
'
//
'
)
:
label
;
label
=
label
.
indexOf
(
'
/
'
)
!==
-
1
?
label
.
replace
(
'
/
'
,
'
//
'
)
:
label
;
return
`
${
parentHandle
}
/
${
index
}
:
${
label
}
`
;
const
existingHandle
=
this
.
nodes
.
has
(
element
)
?
this
.
nodes
.
get
(
element
).
handle
:
void
0
;
for
(
let
labelCount
=
0
;
labelCount
<=
this
.
getChildrenHandles
(
parentHandle
).
length
;
labelCount
++
)
{
const
handle
=
`
${
prefix
}
/
${
labelCount
}
:
${
label
}
`
;
if
(
!
this
.
elements
.
has
(
handle
)
||
existingHandle
===
handle
)
{
return
handle
;
}
}
throw
new
Error
(
'
This should not be reached
'
);
}
}
private
getLightIconPath
(
extensionTreeItem
:
vscode
.
TreeItem
):
string
{
private
getLightIconPath
(
extensionTreeItem
:
vscode
.
TreeItem
):
string
{
...
@@ -197,75 +232,48 @@ class ExtHostTreeView<T> extends Disposable {
...
@@ -197,75 +232,48 @@ class ExtHostTreeView<T> extends Disposable {
return
URI
.
file
(
iconPath
).
toString
();
return
URI
.
file
(
iconPath
).
toString
();
}
}
private
getHandlesToRefresh
(
elements
:
T
[]):
TreeItemHandle
[]
{
private
getChildrenHandles
(
parentHandle
?:
TreeItemHandle
):
TreeItemHandle
[]
{
const
elementsToUpdate
=
new
Set
<
TreeItemHandle
>
();
return
parentHandle
?
this
.
nodes
.
get
(
this
.
getExtensionElement
(
parentHandle
)).
childrenHandles
:
this
.
rootHandles
;
for
(
const
element
of
elements
)
{
let
elementNode
=
this
.
nodes
.
get
(
element
);
if
(
elementNode
&&
!
elementsToUpdate
.
has
(
elementNode
.
handle
))
{
// check if an ancestor of extElement is already in the elements to update list
let
currentNode
=
elementNode
;
while
(
currentNode
&&
currentNode
.
parentHandle
&&
!
elementsToUpdate
.
has
(
currentNode
.
parentHandle
))
{
const
parentElement
=
this
.
elements
.
get
(
currentNode
.
parentHandle
);
currentNode
=
this
.
nodes
.
get
(
parentElement
);
}
if
(
!
currentNode
.
parentHandle
)
{
elementsToUpdate
.
add
(
elementNode
.
handle
);
}
}
}
}
const
handlesToUpdate
:
TreeItemHandle
[]
=
[];
private
update
(
element
:
T
,
handle
:
TreeItemHandle
,
parentHandle
:
TreeItemHandle
):
void
{
// Take only top level elements
const
node
=
this
.
nodes
.
get
(
element
);
elementsToUpdate
.
forEach
((
handle
)
=>
{
const
childrenHandles
=
this
.
getChildrenHandles
(
parentHandle
);
const
element
=
this
.
elements
.
get
(
handle
);
let
node
=
this
.
nodes
.
get
(
element
);
if
(
node
&&
!
elementsToUpdate
.
has
(
node
.
parentHandle
))
{
handlesToUpdate
.
push
(
handle
);
}
});
return
handlesToUpdate
;
// Update parent node
if
(
node
)
{
if
(
node
.
handle
!==
handle
)
{
childrenHandles
[
childrenHandles
.
indexOf
(
node
.
handle
)]
=
handle
;
this
.
clearChildren
(
element
);
}
}
else
{
childrenHandles
.
push
(
handle
);
}
}
private
refreshHandles
(
itemHandles
:
TreeItemHandle
[]):
TPromise
<
void
>
{
// Update element maps
const
itemsToRefresh
:
{
[
handle
:
string
]:
ITreeItem
}
=
{};
this
.
elements
.
set
(
handle
,
element
);
const
promises
:
TPromise
<
void
>
[]
=
[];
this
.
nodes
.
set
(
element
,
{
itemHandles
.
forEach
(
treeItemHandle
=>
{
handle
,
const
extElement
=
this
.
getExtensionElement
(
treeItemHandle
);
parentHandle
,
const
node
=
this
.
nodes
.
get
(
extElement
);
childrenHandles
:
node
?
node
.
childrenHandles
:
[]
promises
.
push
(
this
.
resolveElement
(
extElement
,
treeItemHandle
,
node
.
parentHandle
)
.
then
(
treeItem
=>
{
itemsToRefresh
[
treeItemHandle
]
=
treeItem
;
}));
});
return
TPromise
.
join
(
promises
)
.
then
(
treeItems
=>
{
this
.
proxy
.
$refresh
(
this
.
viewId
,
itemsToRefresh
);
});
});
}
}
private
updateChildren
(
newChildren
:
ITreeItem
[],
parentElement
?:
T
):
ITreeItem
[]
{
private
clearChildren
(
parentElement
?:
T
):
void
{
let
existingChildrenHandles
:
TreeItemHandle
[]
=
[];
if
(
parentElement
)
{
if
(
parentElement
)
{
const
parentNode
=
this
.
nodes
.
get
(
parentElement
);
let
node
=
this
.
nodes
.
get
(
parentElement
);
existingChildrenHandles
=
parentNode
.
childrenHandles
||
[];
if
(
node
.
childrenHandles
)
{
parentNode
.
childrenHandles
=
newChildren
.
map
(
c
=>
c
.
handle
);
for
(
const
childHandle
of
node
.
childrenHandles
)
{
}
else
{
const
childEleement
=
this
.
elements
.
get
(
childHandle
);
this
.
nodes
.
forEach
(
node
=>
{
if
(
childEleement
)
{
if
(
!
node
.
parentHandle
)
{
this
.
clear
(
childEleement
);
existingChildrenHandles
.
push
(
node
.
handle
);
}
}
});
}
}
for
(
const
existingChildHandle
of
existingChildrenHandles
)
{
const
existingChildElement
=
this
.
elements
.
get
(
existingChildHandle
);
if
(
existingChildElement
&&
newChildren
.
every
(
c
=>
c
.
handle
!==
existingChildHandle
))
{
this
.
clear
(
existingChildElement
);
}
}
node
.
childrenHandles
=
[];
}
else
{
this
.
clearAll
();
}
}
return
newChildren
;
}
}
private
clear
(
element
:
T
):
void
{
private
clear
(
element
:
T
):
void
{
...
@@ -282,8 +290,13 @@ class ExtHostTreeView<T> extends Disposable {
...
@@ -282,8 +290,13 @@ class ExtHostTreeView<T> extends Disposable {
this
.
elements
.
delete
(
node
.
handle
);
this
.
elements
.
delete
(
node
.
handle
);
}
}
dispose
()
{
private
clearAll
():
void
{
this
.
rootHandles
=
[];
this
.
elements
.
clear
();
this
.
elements
.
clear
();
this
.
nodes
.
clear
();
this
.
nodes
.
clear
();
}
}
dispose
()
{
this
.
clearAll
();
}
}
}
\ No newline at end of file
src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts
浏览文件 @
71cc864c
...
@@ -83,24 +83,24 @@ suite('ExtHostTreeView', function () {
...
@@ -83,24 +83,24 @@ suite('ExtHostTreeView', function () {
return
testObject
.
$getElements
(
'
testNodeTreeProvider
'
)
return
testObject
.
$getElements
(
'
testNodeTreeProvider
'
)
.
then
(
elements
=>
{
.
then
(
elements
=>
{
const
actuals
=
elements
.
map
(
e
=>
e
.
handle
);
const
actuals
=
elements
.
map
(
e
=>
e
.
handle
);
assert
.
deepEqual
(
actuals
,
[
'
0/0:a
'
,
'
0/
1
:b
'
]);
assert
.
deepEqual
(
actuals
,
[
'
0/0:a
'
,
'
0/
0
:b
'
]);
return
TPromise
.
join
([
return
TPromise
.
join
([
testObject
.
$getChildren
(
'
testNodeTreeProvider
'
,
'
0/0:a
'
)
testObject
.
$getChildren
(
'
testNodeTreeProvider
'
,
'
0/0:a
'
)
.
then
(
children
=>
{
.
then
(
children
=>
{
const
actuals
=
children
.
map
(
e
=>
e
.
handle
);
const
actuals
=
children
.
map
(
e
=>
e
.
handle
);
assert
.
deepEqual
(
actuals
,
[
'
0/0:a/0:aa
'
,
'
0/0:a/
1
:ab
'
]);
assert
.
deepEqual
(
actuals
,
[
'
0/0:a/0:aa
'
,
'
0/0:a/
0
:ab
'
]);
return
TPromise
.
join
([
return
TPromise
.
join
([
testObject
.
$getChildren
(
'
testNodeTreeProvider
'
,
'
0/0:a/0:aa
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
)),
testObject
.
$getChildren
(
'
testNodeTreeProvider
'
,
'
0/0:a/0:aa
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
)),
testObject
.
$getChildren
(
'
testNodeTreeProvider
'
,
'
0/0:a/
1
:ab
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
))
testObject
.
$getChildren
(
'
testNodeTreeProvider
'
,
'
0/0:a/
0
:ab
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
))
]);
]);
}),
}),
testObject
.
$getChildren
(
'
testNodeTreeProvider
'
,
'
0/
1
:b
'
)
testObject
.
$getChildren
(
'
testNodeTreeProvider
'
,
'
0/
0
:b
'
)
.
then
(
children
=>
{
.
then
(
children
=>
{
const
actuals
=
children
.
map
(
e
=>
e
.
handle
);
const
actuals
=
children
.
map
(
e
=>
e
.
handle
);
assert
.
deepEqual
(
actuals
,
[
'
0/
1:b/0:ba
'
,
'
0/1:b/1
:bb
'
]);
assert
.
deepEqual
(
actuals
,
[
'
0/
0:b/0:ba
'
,
'
0/0:b/0
:bb
'
]);
return
TPromise
.
join
([
return
TPromise
.
join
([
testObject
.
$getChildren
(
'
testNodeTreeProvider
'
,
'
0/
1
:b/0:ba
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
)),
testObject
.
$getChildren
(
'
testNodeTreeProvider
'
,
'
0/
0
:b/0:ba
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
)),
testObject
.
$getChildren
(
'
testNodeTreeProvider
'
,
'
0/
1:b/1
:bb
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
))
testObject
.
$getChildren
(
'
testNodeTreeProvider
'
,
'
0/
0:b/0
:bb
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
))
]);
]);
})
})
]);
]);
...
@@ -111,24 +111,24 @@ suite('ExtHostTreeView', function () {
...
@@ -111,24 +111,24 @@ suite('ExtHostTreeView', function () {
return
testObject
.
$getElements
(
'
testStringTreeProvider
'
)
return
testObject
.
$getElements
(
'
testStringTreeProvider
'
)
.
then
(
elements
=>
{
.
then
(
elements
=>
{
const
actuals
=
elements
.
map
(
e
=>
e
.
handle
);
const
actuals
=
elements
.
map
(
e
=>
e
.
handle
);
assert
.
deepEqual
(
actuals
,
[
'
0/0:a
'
,
'
0/
1
:b
'
]);
assert
.
deepEqual
(
actuals
,
[
'
0/0:a
'
,
'
0/
0
:b
'
]);
return
TPromise
.
join
([
return
TPromise
.
join
([
testObject
.
$getChildren
(
'
testStringTreeProvider
'
,
'
0/0:a
'
)
testObject
.
$getChildren
(
'
testStringTreeProvider
'
,
'
0/0:a
'
)
.
then
(
children
=>
{
.
then
(
children
=>
{
const
actuals
=
children
.
map
(
e
=>
e
.
handle
);
const
actuals
=
children
.
map
(
e
=>
e
.
handle
);
assert
.
deepEqual
(
actuals
,
[
'
0/0:a/0:aa
'
,
'
0/0:a/
1
:ab
'
]);
assert
.
deepEqual
(
actuals
,
[
'
0/0:a/0:aa
'
,
'
0/0:a/
0
:ab
'
]);
return
TPromise
.
join
([
return
TPromise
.
join
([
testObject
.
$getChildren
(
'
testStringTreeProvider
'
,
'
0/0:a/0:aa
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
)),
testObject
.
$getChildren
(
'
testStringTreeProvider
'
,
'
0/0:a/0:aa
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
)),
testObject
.
$getChildren
(
'
testStringTreeProvider
'
,
'
0/0:a/
1
:ab
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
))
testObject
.
$getChildren
(
'
testStringTreeProvider
'
,
'
0/0:a/
0
:ab
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
))
]);
]);
}),
}),
testObject
.
$getChildren
(
'
testStringTreeProvider
'
,
'
0/
1
:b
'
)
testObject
.
$getChildren
(
'
testStringTreeProvider
'
,
'
0/
0
:b
'
)
.
then
(
children
=>
{
.
then
(
children
=>
{
const
actuals
=
children
.
map
(
e
=>
e
.
handle
);
const
actuals
=
children
.
map
(
e
=>
e
.
handle
);
assert
.
deepEqual
(
actuals
,
[
'
0/
1:b/0:ba
'
,
'
0/1:b/1
:bb
'
]);
assert
.
deepEqual
(
actuals
,
[
'
0/
0:b/0:ba
'
,
'
0/0:b/0
:bb
'
]);
return
TPromise
.
join
([
return
TPromise
.
join
([
testObject
.
$getChildren
(
'
testStringTreeProvider
'
,
'
0/
1
:b/0:ba
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
)),
testObject
.
$getChildren
(
'
testStringTreeProvider
'
,
'
0/
0
:b/0:ba
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
)),
testObject
.
$getChildren
(
'
testStringTreeProvider
'
,
'
0/
1:b/1
:bb
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
))
testObject
.
$getChildren
(
'
testStringTreeProvider
'
,
'
0/
0:b/0
:bb
'
).
then
(
children
=>
assert
.
equal
(
children
.
length
,
0
))
]);
]);
})
})
]);
]);
...
@@ -146,9 +146,9 @@ suite('ExtHostTreeView', function () {
...
@@ -146,9 +146,9 @@ suite('ExtHostTreeView', function () {
test
(
'
refresh a parent node
'
,
()
=>
{
test
(
'
refresh a parent node
'
,
()
=>
{
return
new
TPromise
((
c
,
e
)
=>
{
return
new
TPromise
((
c
,
e
)
=>
{
target
.
onRefresh
.
event
(
actuals
=>
{
target
.
onRefresh
.
event
(
actuals
=>
{
assert
.
deepEqual
([
'
0/
1
:b
'
],
Object
.
keys
(
actuals
));
assert
.
deepEqual
([
'
0/
0
:b
'
],
Object
.
keys
(
actuals
));
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/
1
:b
'
]),
{
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/
0
:b
'
]),
{
handle
:
'
0/
1
:b
'
,
handle
:
'
0/
0
:b
'
,
label
:
'
b
'
,
label
:
'
b
'
,
});
});
c
(
null
);
c
(
null
);
...
@@ -159,10 +159,10 @@ suite('ExtHostTreeView', function () {
...
@@ -159,10 +159,10 @@ suite('ExtHostTreeView', function () {
test
(
'
refresh a leaf node
'
,
function
(
done
)
{
test
(
'
refresh a leaf node
'
,
function
(
done
)
{
target
.
onRefresh
.
event
(
actuals
=>
{
target
.
onRefresh
.
event
(
actuals
=>
{
assert
.
deepEqual
([
'
0/
1:b/1
:bb
'
],
Object
.
keys
(
actuals
));
assert
.
deepEqual
([
'
0/
0:b/0
:bb
'
],
Object
.
keys
(
actuals
));
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/
1:b/1
:bb
'
]),
{
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/
0:b/0
:bb
'
]),
{
handle
:
'
0/
1:b/1
:bb
'
,
handle
:
'
0/
0:b/0
:bb
'
,
parentHandle
:
'
0/
1
:b
'
,
parentHandle
:
'
0/
0
:b
'
,
label
:
'
bb
'
label
:
'
bb
'
});
});
done
();
done
();
...
@@ -172,9 +172,9 @@ suite('ExtHostTreeView', function () {
...
@@ -172,9 +172,9 @@ suite('ExtHostTreeView', function () {
test
(
'
refresh parent and child node trigger refresh only on parent - scenario 1
'
,
function
(
done
)
{
test
(
'
refresh parent and child node trigger refresh only on parent - scenario 1
'
,
function
(
done
)
{
target
.
onRefresh
.
event
(
actuals
=>
{
target
.
onRefresh
.
event
(
actuals
=>
{
assert
.
deepEqual
([
'
0/
1
:b
'
,
'
0/0:a/0:aa
'
],
Object
.
keys
(
actuals
));
assert
.
deepEqual
([
'
0/
0
:b
'
,
'
0/0:a/0:aa
'
],
Object
.
keys
(
actuals
));
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/
1
:b
'
]),
{
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/
0
:b
'
]),
{
handle
:
'
0/
1
:b
'
,
handle
:
'
0/
0
:b
'
,
label
:
'
b
'
,
label
:
'
b
'
,
});
});
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/0:a/0:aa
'
]),
{
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/0:a/0:aa
'
]),
{
...
@@ -191,9 +191,9 @@ suite('ExtHostTreeView', function () {
...
@@ -191,9 +191,9 @@ suite('ExtHostTreeView', function () {
test
(
'
refresh parent and child node trigger refresh only on parent - scenario 2
'
,
function
(
done
)
{
test
(
'
refresh parent and child node trigger refresh only on parent - scenario 2
'
,
function
(
done
)
{
target
.
onRefresh
.
event
(
actuals
=>
{
target
.
onRefresh
.
event
(
actuals
=>
{
assert
.
deepEqual
([
'
0/0:a/0:aa
'
,
'
0/
1
:b
'
],
Object
.
keys
(
actuals
));
assert
.
deepEqual
([
'
0/0:a/0:aa
'
,
'
0/
0
:b
'
],
Object
.
keys
(
actuals
));
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/
1
:b
'
]),
{
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/
0
:b
'
]),
{
handle
:
'
0/
1
:b
'
,
handle
:
'
0/
0
:b
'
,
label
:
'
b
'
,
label
:
'
b
'
,
});
});
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/0:a/0:aa
'
]),
{
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/0:a/0:aa
'
]),
{
...
@@ -213,7 +213,7 @@ suite('ExtHostTreeView', function () {
...
@@ -213,7 +213,7 @@ suite('ExtHostTreeView', function () {
target
.
onRefresh
.
event
(
actuals
=>
{
target
.
onRefresh
.
event
(
actuals
=>
{
assert
.
deepEqual
([
'
0/0:a
'
],
Object
.
keys
(
actuals
));
assert
.
deepEqual
([
'
0/0:a
'
],
Object
.
keys
(
actuals
));
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/0:a
'
]),
{
assert
.
deepEqual
(
removeUnsetKeys
(
actuals
[
'
0/0:a
'
]),
{
handle
:
'
0/0:a
'
,
handle
:
'
0/0:a
a
'
,
label
:
'
aa
'
,
label
:
'
aa
'
,
});
});
done
();
done
();
...
@@ -234,7 +234,7 @@ suite('ExtHostTreeView', function () {
...
@@ -234,7 +234,7 @@ suite('ExtHostTreeView', function () {
test
(
'
refresh calls are throttled on elements
'
,
function
(
done
)
{
test
(
'
refresh calls are throttled on elements
'
,
function
(
done
)
{
target
.
onRefresh
.
event
(
actuals
=>
{
target
.
onRefresh
.
event
(
actuals
=>
{
assert
.
deepEqual
([
'
0/0:a
'
,
'
0/
1
:b
'
],
Object
.
keys
(
actuals
));
assert
.
deepEqual
([
'
0/0:a
'
,
'
0/
0
:b
'
],
Object
.
keys
(
actuals
));
done
();
done
();
});
});
...
@@ -246,7 +246,7 @@ suite('ExtHostTreeView', function () {
...
@@ -246,7 +246,7 @@ suite('ExtHostTreeView', function () {
test
(
'
refresh calls are throttled on unknown elements
'
,
function
(
done
)
{
test
(
'
refresh calls are throttled on unknown elements
'
,
function
(
done
)
{
target
.
onRefresh
.
event
(
actuals
=>
{
target
.
onRefresh
.
event
(
actuals
=>
{
assert
.
deepEqual
([
'
0/0:a
'
,
'
0/
1
:b
'
],
Object
.
keys
(
actuals
));
assert
.
deepEqual
([
'
0/0:a
'
,
'
0/
0
:b
'
],
Object
.
keys
(
actuals
));
done
();
done
();
});
});
...
@@ -293,6 +293,50 @@ suite('ExtHostTreeView', function () {
...
@@ -293,6 +293,50 @@ suite('ExtHostTreeView', function () {
});
});
});
});
test
(
'
tree with duplicate labels
'
,
()
=>
{
const
dupItems
=
{
'
adup1
'
:
'
c
'
,
'
adup2
'
:
'
g
'
,
'
bdup1
'
:
'
e
'
,
'
hdup1
'
:
'
i
'
,
'
hdup2
'
:
'
l
'
,
'
jdup1
'
:
'
k
'
};
labels
[
'
c
'
]
=
'
a
'
;
labels
[
'
e
'
]
=
'
b
'
;
labels
[
'
g
'
]
=
'
a
'
;
labels
[
'
i
'
]
=
'
h
'
;
labels
[
'
l
'
]
=
'
h
'
;
labels
[
'
k
'
]
=
'
j
'
;
tree
[
dupItems
[
'
adup1
'
]]
=
{};
tree
[
'
d
'
]
=
{};
const
bdup1Tree
=
{};
bdup1Tree
[
'
h
'
]
=
{};
bdup1Tree
[
dupItems
[
'
hdup1
'
]]
=
{};
bdup1Tree
[
'
j
'
]
=
{};
bdup1Tree
[
dupItems
[
'
jdup1
'
]]
=
{};
bdup1Tree
[
dupItems
[
'
hdup2
'
]]
=
{};
tree
[
dupItems
[
'
bdup1
'
]]
=
bdup1Tree
;
tree
[
'
f
'
]
=
{};
tree
[
dupItems
[
'
adup2
'
]]
=
{};
return
testObject
.
$getElements
(
'
testNodeTreeProvider
'
)
.
then
(
elements
=>
{
const
actuals
=
elements
.
map
(
e
=>
e
.
handle
);
assert
.
deepEqual
(
actuals
,
[
'
0/0:a
'
,
'
0/0:b
'
,
'
0/1:a
'
,
'
0/0:d
'
,
'
0/1:b
'
,
'
0/0:f
'
,
'
0/2:a
'
]);
return
testObject
.
$getChildren
(
'
testNodeTreeProvider
'
,
'
0/1:b
'
)
.
then
(
elements
=>
{
const
actuals
=
elements
.
map
(
e
=>
e
.
handle
);
assert
.
deepEqual
(
actuals
,
[
'
0/1:b/0:h
'
,
'
0/1:b/1:h
'
,
'
0/1:b/0:j
'
,
'
0/1:b/1:j
'
,
'
0/1:b/2:h
'
]);
});
});
});
function
removeUnsetKeys
(
obj
:
any
):
any
{
function
removeUnsetKeys
(
obj
:
any
):
any
{
const
result
=
{};
const
result
=
{};
for
(
const
key
of
Object
.
keys
(
obj
))
{
for
(
const
key
of
Object
.
keys
(
obj
))
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录