Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
da7d92b8
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,发现更多精彩内容 >>
未验证
提交
da7d92b8
编写于
7月 16, 2021
作者:
C
Connor Peet
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
testing: make test ids locally unique, instead of globally unique
上级
42c268a6
变更
21
隐藏空白更改
内联
并排
Showing
21 changed file
with
430 addition
and
390 deletion
+430
-390
src/vs/vscode.proposed.d.ts
src/vs/vscode.proposed.d.ts
+8
-3
src/vs/workbench/api/common/extHostTesting.ts
src/vs/workbench/api/common/extHostTesting.ts
+37
-28
src/vs/workbench/api/common/extHostTestingPrivateApi.ts
src/vs/workbench/api/common/extHostTestingPrivateApi.ts
+13
-1
src/vs/workbench/api/common/extHostTypeConverters.ts
src/vs/workbench/api/common/extHostTypeConverters.ts
+28
-29
src/vs/workbench/contrib/testing/browser/testExplorerActions.ts
.../workbench/contrib/testing/browser/testExplorerActions.ts
+18
-23
src/vs/workbench/contrib/testing/browser/testing.contribution.ts
...workbench/contrib/testing/browser/testing.contribution.ts
+8
-8
src/vs/workbench/contrib/testing/browser/testingDecorations.ts
...s/workbench/contrib/testing/browser/testingDecorations.ts
+2
-14
src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts
...orkbench/contrib/testing/browser/testingExplorerFilter.ts
+3
-8
src/vs/workbench/contrib/testing/browser/testingExplorerView.ts
.../workbench/contrib/testing/browser/testingExplorerView.ts
+9
-7
src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts
...vs/workbench/contrib/testing/browser/testingOutputPeek.ts
+7
-14
src/vs/workbench/contrib/testing/common/ownedTestCollection.ts
...s/workbench/contrib/testing/common/ownedTestCollection.ts
+49
-150
src/vs/workbench/contrib/testing/common/testCollection.ts
src/vs/workbench/contrib/testing/common/testCollection.ts
+0
-6
src/vs/workbench/contrib/testing/common/testId.ts
src/vs/workbench/contrib/testing/common/testId.ts
+159
-0
src/vs/workbench/contrib/testing/common/testResult.ts
src/vs/workbench/contrib/testing/common/testResult.ts
+1
-10
src/vs/workbench/contrib/testing/common/testService.ts
src/vs/workbench/contrib/testing/common/testService.ts
+5
-10
src/vs/workbench/contrib/testing/common/testServiceImpl.ts
src/vs/workbench/contrib/testing/common/testServiceImpl.ts
+3
-1
src/vs/workbench/contrib/testing/test/browser/explorerProjections/hierarchalByLocation.test.ts
.../browser/explorerProjections/hierarchalByLocation.test.ts
+7
-6
src/vs/workbench/contrib/testing/test/browser/explorerProjections/hierarchalByName.test.ts
...test/browser/explorerProjections/hierarchalByName.test.ts
+3
-2
src/vs/workbench/contrib/testing/test/common/testResultService.test.ts
...nch/contrib/testing/test/common/testResultService.test.ts
+26
-33
src/vs/workbench/contrib/testing/test/common/testResultStorage.test.ts
...nch/contrib/testing/test/common/testResultStorage.test.ts
+8
-6
src/vs/workbench/test/browser/api/extHostTesting.test.ts
src/vs/workbench/test/browser/api/extHostTesting.test.ts
+36
-31
未找到文件。
src/vs/vscode.proposed.d.ts
浏览文件 @
da7d92b8
...
...
@@ -2190,11 +2190,11 @@ declare module 'vscode' {
*/
export
interface
TestItem
{
/**
*
Unique i
dentifier for the TestItem. This is used to correlate
*
I
dentifier for the TestItem. This is used to correlate
* test results and tests in the document with those in the workspace
* (test explorer). This must not change for the lifetime of the TestItem.
* (test explorer). This cannot change for the lifetime of the TestItem,
* and must be unique among its parent's direct children.
*/
// todo@API globally vs extension vs controller unique. I would strongly recommend non-global
readonly
id
:
string
;
/**
...
...
@@ -2380,6 +2380,11 @@ declare module 'vscode' {
*/
readonly
id
:
string
;
/**
* Parent of this item.
*/
readonly
parent
?:
TestResultSnapshot
;
/**
* URI this TestItem is associated with. May be a file or file.
*/
...
...
src/vs/workbench/api/common/extHostTesting.ts
浏览文件 @
da7d92b8
...
...
@@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
RunOnceScheduler
}
from
'
vs/base/common/async
'
;
import
{
VSBuffer
}
from
'
vs/base/common/buffer
'
;
import
{
CancellationToken
,
CancellationTokenSource
}
from
'
vs/base/common/cancellation
'
;
import
{
Emitter
,
Event
}
from
'
vs/base/common/event
'
;
...
...
@@ -18,11 +17,12 @@ import { generateUuid } from 'vs/base/common/uuid';
import
{
ExtHostTestingShape
,
MainContext
,
MainThreadTestingShape
}
from
'
vs/workbench/api/common/extHost.protocol
'
;
import
{
ExtHostCommands
}
from
'
vs/workbench/api/common/extHostCommands
'
;
import
{
IExtHostRpcService
}
from
'
vs/workbench/api/common/extHostRpcService
'
;
import
{
TestItemImpl
}
from
'
vs/workbench/api/common/extHostTestingPrivateApi
'
;
import
{
TestItemImpl
,
TestItemRootImpl
}
from
'
vs/workbench/api/common/extHostTestingPrivateApi
'
;
import
*
as
Convert
from
'
vs/workbench/api/common/extHostTypeConverters
'
;
import
{
TestRunProfileGroup
,
TestRunRequest
}
from
'
vs/workbench/api/common/extHostTypes
'
;
import
{
SingleUseTestCollection
,
TestPosition
}
from
'
vs/workbench/contrib/testing/common/ownedTestCollection
'
;
import
{
SingleUseTestCollection
}
from
'
vs/workbench/contrib/testing/common/ownedTestCollection
'
;
import
{
AbstractIncrementalTestCollection
,
CoverageDetails
,
IFileCoverage
,
IncrementalChangeCollector
,
IncrementalTestCollectionItem
,
InternalTestItem
,
ISerializedTestResults
,
ITestIdWithSrc
,
ITestItem
,
RunTestForControllerRequest
,
TestRunProfileBitset
,
TestsDiff
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
TestId
,
TestIdPathParts
,
TestPosition
}
from
'
vs/workbench/contrib/testing/common/testId
'
;
import
type
*
as
vscode
from
'
vscode
'
;
interface
ControllerInfo
{
...
...
@@ -58,7 +58,6 @@ export class ExtHostTesting implements ExtHostTestingShape {
public
createTestController
(
controllerId
:
string
,
label
:
string
):
vscode
.
TestController
{
const
disposable
=
new
DisposableStore
();
const
collection
=
disposable
.
add
(
new
SingleUseTestCollection
(
controllerId
));
const
initialExpand
=
disposable
.
add
(
new
RunOnceScheduler
(()
=>
collection
.
expand
(
collection
.
root
.
id
,
0
),
0
));
const
profiles
=
new
Map
<
number
,
vscode
.
TestRunProfile
>
();
const
proxy
=
this
.
proxy
;
...
...
@@ -92,9 +91,6 @@ export class ExtHostTesting implements ExtHostTestingShape {
},
set
resolveChildrenHandler
(
fn
)
{
collection
.
resolveHandler
=
fn
;
if
(
fn
)
{
initialExpand
.
schedule
();
}
},
get
resolveChildrenHandler
()
{
return
collection
.
resolveHandler
;
...
...
@@ -239,7 +235,7 @@ export class ExtHostTesting implements ExtHostTestingShape {
.
map
(
id
=>
lookup
.
collection
.
tree
.
get
(
id
))
.
filter
(
isDefined
)
.
filter
(
exclude
=>
includeTests
.
some
(
include
=>
collection
.
tree
.
comparePositions
(
include
,
exclude
)
===
TestPosition
.
IsChild
,
include
=>
include
.
fullId
.
compare
(
exclude
.
fullId
)
===
TestPosition
.
IsChild
,
));
if
(
!
includeTests
.
length
)
{
...
...
@@ -247,7 +243,7 @@ export class ExtHostTesting implements ExtHostTestingShape {
}
const
publicReq
=
new
TestRunRequest
(
includeTests
.
map
(
t
=>
t
.
actual
),
includeTests
.
some
(
i
=>
i
.
actual
instanceof
TestItemRootImpl
)
?
undefined
:
includeTests
.
map
(
t
=>
t
.
actual
),
excludeTests
.
map
(
t
=>
t
.
actual
),
profile
,
);
...
...
@@ -437,12 +433,15 @@ const tryGetProfileFromTestRunReq = (request: vscode.TestRunRequest) => {
};
export
class
TestRunDto
{
private
readonly
includePrefix
:
string
[];
private
readonly
excludePrefix
:
string
[];
public
static
fromPublic
(
controllerId
:
string
,
collection
:
SingleUseTestCollection
,
request
:
vscode
.
TestRunRequest
)
{
return
new
TestRunDto
(
controllerId
,
generateUuid
(),
request
.
include
&&
new
Set
(
request
.
include
.
map
(
t
=>
t
.
id
))
,
new
Set
(
request
.
exclude
?.
map
(
t
=>
t
.
id
)
??
Iterable
.
empty
())
,
request
.
include
?.
map
(
t
=>
TestId
.
fromExtHostTestItem
(
t
,
controllerId
).
toString
())
??
[
controllerId
]
,
request
.
exclude
?.
map
(
t
=>
TestId
.
fromExtHostTestItem
(
t
,
controllerId
).
toString
())
??
[]
,
collection
,
);
}
...
...
@@ -451,8 +450,8 @@ export class TestRunDto {
return
new
TestRunDto
(
request
.
controllerId
,
request
.
runId
,
request
.
testIds
.
includes
(
collection
.
root
.
id
)
?
undefined
:
new
Set
(
request
.
testIds
)
,
new
Set
(
request
.
excludeExtIds
)
,
request
.
testIds
,
request
.
excludeExtIds
,
collection
,
);
}
...
...
@@ -460,21 +459,29 @@ export class TestRunDto {
constructor
(
public
readonly
controllerId
:
string
,
public
readonly
id
:
string
,
private
readonly
include
:
ReadonlySet
<
string
>
|
undefined
,
private
readonly
exclude
:
ReadonlySet
<
string
>
,
include
:
string
[]
,
exclude
:
string
[]
,
public
readonly
colllection
:
SingleUseTestCollection
,
)
{
}
)
{
this
.
includePrefix
=
include
.
map
(
id
=>
id
+
TestIdPathParts
.
Delimiter
);
this
.
excludePrefix
=
exclude
.
map
(
id
=>
id
+
TestIdPathParts
.
Delimiter
);
}
public
isIncluded
(
test
:
vscode
.
TestItem
)
{
for
(
let
t
:
vscode
.
TestItem
|
undefined
=
test
;
t
;
t
=
t
.
parent
)
{
if
(
this
.
include
?.
has
(
t
.
id
))
{
return
true
;
}
else
if
(
this
.
exclude
.
has
(
t
.
id
))
{
const
id
=
TestId
.
fromExtHostTestItem
(
test
,
this
.
controllerId
).
toString
()
+
TestIdPathParts
.
Delimiter
;
for
(
const
prefix
of
this
.
excludePrefix
)
{
if
(
id
===
prefix
||
id
.
startsWith
(
prefix
))
{
return
false
;
}
}
return
this
.
include
===
undefined
;
// default to true if running all tests with include=undefined
for
(
const
prefix
of
this
.
includePrefix
)
{
if
(
id
===
prefix
||
id
.
startsWith
(
prefix
))
{
return
true
;
}
}
return
false
;
}
}
...
...
@@ -574,16 +581,18 @@ class TestRunImpl implements vscode.TestRun {
}
setState
(
test
:
vscode
.
TestItem
,
state
:
vscode
.
TestResultState
,
duration
?:
number
):
void
{
if
(
!
this
.
#
ended
&&
this
.
#
req
.
isIncluded
(
test
))
{
const
req
=
this
.
#
req
;
if
(
!
this
.
#
ended
&&
req
.
isIncluded
(
test
))
{
this
.
ensureTestIsKnown
(
test
);
this
.
#
proxy
.
$updateTestStateInRun
(
this
.
#
req
.
id
,
this
.
taskId
,
test
.
id
,
state
,
duration
);
this
.
#
proxy
.
$updateTestStateInRun
(
req
.
id
,
this
.
taskId
,
TestId
.
fromExtHostTestItem
(
test
,
req
.
controllerId
).
toString
()
,
state
,
duration
);
}
}
appendMessage
(
test
:
vscode
.
TestItem
,
message
:
vscode
.
TestMessage
):
void
{
if
(
!
this
.
#
ended
&&
this
.
#
req
.
isIncluded
(
test
))
{
const
req
=
this
.
#
req
;
if
(
!
this
.
#
ended
&&
req
.
isIncluded
(
test
))
{
this
.
ensureTestIsKnown
(
test
);
this
.
#
proxy
.
$appendTestMessageInRun
(
this
.
#
req
.
id
,
this
.
taskId
,
test
.
id
,
Convert
.
TestMessage
.
from
(
message
));
this
.
#
proxy
.
$appendTestMessageInRun
(
req
.
id
,
this
.
taskId
,
TestId
.
fromExtHostTestItem
(
test
,
req
.
controllerId
).
toString
()
,
Convert
.
TestMessage
.
from
(
message
));
}
}
...
...
@@ -608,8 +617,9 @@ class TestRunImpl implements vscode.TestRun {
}
const
chain
:
ITestItem
[]
=
[];
const
root
=
this
.
#
req
.
colllection
.
root
;
while
(
true
)
{
chain
.
unshift
(
Convert
.
TestItem
.
from
(
test
));
chain
.
unshift
(
Convert
.
TestItem
.
from
(
test
,
root
.
id
));
if
(
sent
.
has
(
test
.
id
))
{
break
;
...
...
@@ -623,10 +633,9 @@ class TestRunImpl implements vscode.TestRun {
test
=
test
.
parent
;
}
const
root
=
this
.
#
req
.
colllection
.
root
;
if
(
!
sent
.
has
(
root
.
id
))
{
sent
.
add
(
root
.
id
);
chain
.
unshift
(
Convert
.
TestItem
.
from
(
root
));
chain
.
unshift
(
Convert
.
TestItem
.
from
(
root
,
root
.
id
));
}
this
.
#
proxy
.
$addTestsToRun
(
this
.
#
req
.
controllerId
,
this
.
#
req
.
id
,
chain
);
...
...
src/vs/workbench/api/common/extHostTestingPrivateApi.ts
浏览文件 @
da7d92b8
...
...
@@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
TestIdPathParts
}
from
'
vs/workbench/contrib/testing/common/testId
'
;
import
*
as
vscode
from
'
vscode
'
;
export
const
enum
ExtHostTestItemEventOp
{
...
...
@@ -242,6 +243,9 @@ export class TestItemImpl implements vscode.TestItem {
*/
constructor
(
id
:
string
,
label
:
string
,
uri
:
vscode
.
Uri
|
undefined
)
{
const
api
=
getPrivateApiFor
(
this
);
if
(
id
.
includes
(
TestIdPathParts
.
Delimiter
))
{
throw
new
Error
(
`Test IDs may not include the
${
JSON
.
stringify
(
id
)}
symbol`
);
}
Object
.
defineProperties
(
this
,
{
id
:
{
...
...
@@ -256,7 +260,9 @@ export class TestItemImpl implements vscode.TestItem {
},
parent
:
{
enumerable
:
false
,
get
()
{
return
api
.
parent
;
},
get
()
{
return
api
.
parent
instanceof
TestItemRootImpl
?
undefined
:
api
.
parent
;
},
},
children
:
{
value
:
createTestItemCollection
(
this
),
...
...
@@ -272,3 +278,9 @@ export class TestItemImpl implements vscode.TestItem {
getPrivateApiFor
(
this
).
listener
?.({
op
:
ExtHostTestItemEventOp
.
Invalidated
});
}
}
export
class
TestItemRootImpl
extends
TestItemImpl
{
constructor
(
controllerId
:
string
,
label
:
string
)
{
super
(
controllerId
,
label
,
undefined
);
}
}
src/vs/workbench/api/common/extHostTypeConverters.ts
浏览文件 @
da7d92b8
...
...
@@ -32,6 +32,7 @@ import * as notebooks from 'vs/workbench/contrib/notebook/common/notebookCommon'
import
{
ICellRange
}
from
'
vs/workbench/contrib/notebook/common/notebookRange
'
;
import
*
as
search
from
'
vs/workbench/contrib/search/common/search
'
;
import
{
CoverageDetails
,
DetailType
,
ICoveredCount
,
IFileCoverage
,
ISerializedTestResults
,
ITestItem
,
ITestItemContext
,
ITestMessage
,
SerializedTestResultItem
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
TestId
}
from
'
vs/workbench/contrib/testing/common/testId
'
;
import
{
EditorGroupColumn
}
from
'
vs/workbench/services/editor/common/editorGroupColumn
'
;
import
{
ACTIVE_GROUP
,
SIDE_GROUP
}
from
'
vs/workbench/services/editor/common/editorService
'
;
import
type
*
as
vscode
from
'
vscode
'
;
...
...
@@ -1658,11 +1659,11 @@ export namespace TestMessage {
}
export
namespace
TestItem
{
export
type
Raw
<
T
=
unknown
>
=
vscode
.
TestItem
;
export
type
Raw
=
vscode
.
TestItem
;
export
function
from
(
item
:
vscode
.
TestItem
):
ITestItem
{
export
function
from
(
item
:
vscode
.
TestItem
,
controllerId
:
string
):
ITestItem
{
return
{
extId
:
item
.
id
,
extId
:
TestId
.
fromExtHostTestItem
(
item
,
controllerId
).
toString
()
,
label
:
item
.
label
,
uri
:
item
.
uri
,
range
:
Range
.
from
(
item
.
range
)
||
null
,
...
...
@@ -1671,20 +1672,9 @@ export namespace TestItem {
};
}
export
function
fromResultSnapshot
(
item
:
vscode
.
TestResultSnapshot
):
ITestItem
{
return
{
extId
:
item
.
id
,
label
:
item
.
label
,
uri
:
item
.
uri
,
range
:
Range
.
from
(
item
.
range
)
||
null
,
description
:
item
.
description
||
null
,
error
:
null
,
};
}
export
function
toPlain
(
item
:
ITestItem
):
Omit
<
vscode
.
TestItem
,
'
children
'
|
'
invalidate
'
|
'
discoverChildren
'
>
{
return
{
id
:
item
.
ext
Id
,
id
:
TestId
.
fromString
(
item
.
extId
).
local
Id
,
label
:
item
.
label
,
uri
:
URI
.
revive
(
item
.
uri
),
range
:
Range
.
to
(
item
.
range
||
undefined
),
...
...
@@ -1695,8 +1685,8 @@ export namespace TestItem {
};
}
export
function
to
(
item
:
ITestItem
):
TestItemImpl
{
const
testItem
=
new
TestItemImpl
(
item
.
ext
Id
,
item
.
label
,
URI
.
revive
(
item
.
uri
));
function
to
(
item
:
ITestItem
):
TestItemImpl
{
const
testItem
=
new
TestItemImpl
(
TestId
.
fromString
(
item
.
extId
).
local
Id
,
item
.
label
,
URI
.
revive
(
item
.
uri
));
testItem
.
range
=
Range
.
to
(
item
.
range
||
undefined
);
testItem
.
description
=
item
.
description
||
undefined
;
return
testItem
;
...
...
@@ -1715,18 +1705,27 @@ export namespace TestItem {
}
export
namespace
TestResults
{
const
convertTestResultItem
=
(
item
:
SerializedTestResultItem
,
byInternalId
:
Map
<
string
,
SerializedTestResultItem
>
):
vscode
.
TestResultSnapshot
=>
({
...
TestItem
.
toPlain
(
item
.
item
),
taskStates
:
item
.
tasks
.
map
(
t
=>
({
state
:
t
.
state
,
duration
:
t
.
duration
,
messages
:
t
.
messages
.
map
(
TestMessage
.
to
),
})),
children
:
item
.
children
.
map
(
c
=>
byInternalId
.
get
(
c
))
.
filter
(
isDefined
)
.
map
(
c
=>
convertTestResultItem
(
c
,
byInternalId
)),
});
const
convertTestResultItem
=
(
item
:
SerializedTestResultItem
,
byInternalId
:
Map
<
string
,
SerializedTestResultItem
>
):
vscode
.
TestResultSnapshot
=>
{
const
snapshot
:
vscode
.
TestResultSnapshot
=
({
...
TestItem
.
toPlain
(
item
.
item
),
parent
:
undefined
,
taskStates
:
item
.
tasks
.
map
(
t
=>
({
state
:
t
.
state
,
duration
:
t
.
duration
,
messages
:
t
.
messages
.
map
(
TestMessage
.
to
),
})),
children
:
item
.
children
.
map
(
c
=>
byInternalId
.
get
(
c
))
.
filter
(
isDefined
)
.
map
(
c
=>
convertTestResultItem
(
c
,
byInternalId
))
});
for
(
const
child
of
snapshot
.
children
)
{
(
child
as
any
).
parent
=
snapshot
;
}
return
snapshot
;
};
export
function
to
(
serialized
:
ISerializedTestResults
):
vscode
.
TestRunResult
{
const
roots
:
SerializedTestResultItem
[]
=
[];
...
...
src/vs/workbench/contrib/testing/browser/testExplorerActions.ts
浏览文件 @
da7d92b8
...
...
@@ -29,15 +29,15 @@ import { ITestExplorerFilterState } from 'vs/workbench/contrib/testing/browser/t
import
type
{
TestingExplorerView
,
TestingExplorerViewModel
}
from
'
vs/workbench/contrib/testing/browser/testingExplorerView
'
;
import
{
ITestingOutputTerminalService
}
from
'
vs/workbench/contrib/testing/browser/testingOutputTerminalService
'
;
import
{
TestExplorerViewMode
,
TestExplorerViewSorting
,
Testing
}
from
'
vs/workbench/contrib/testing/common/constants
'
;
import
{
identifyTest
,
InternalTestItem
,
ITestIdWithSrc
,
ITestItem
,
ITestRunProfile
,
Test
IdPath
,
Test
RunProfileBitset
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
identifyTest
,
InternalTestItem
,
ITestIdWithSrc
,
ITestItem
,
ITestRunProfile
,
TestRunProfileBitset
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
ITestProfileService
}
from
'
vs/workbench/contrib/testing/common/testConfigurationService
'
;
import
{
ITestingAutoRun
}
from
'
vs/workbench/contrib/testing/common/testingAutoRun
'
;
import
{
TestingContextKeys
}
from
'
vs/workbench/contrib/testing/common/testingContextKeys
'
;
import
{
ITestingPeekOpener
}
from
'
vs/workbench/contrib/testing/common/testingPeekOpener
'
;
import
{
isFailedState
}
from
'
vs/workbench/contrib/testing/common/testingStates
'
;
import
{
getPathForTestInResult
,
ITestResult
}
from
'
vs/workbench/contrib/testing/common/testResult
'
;
import
{
ITestResult
}
from
'
vs/workbench/contrib/testing/common/testResult
'
;
import
{
ITestResultService
}
from
'
vs/workbench/contrib/testing/common/testResultService
'
;
import
{
getTestByPath
,
IMainThreadTestCollection
,
ITestService
,
testsInFile
}
from
'
vs/workbench/contrib/testing/common/testService
'
;
import
{
expandAndGetTestById
,
IMainThreadTestCollection
,
ITestService
,
testsInFile
}
from
'
vs/workbench/contrib/testing/common/testService
'
;
import
{
IEditorService
}
from
'
vs/workbench/services/editor/common/editorService
'
;
import
{
IViewletService
}
from
'
vs/workbench/services/viewlet/browser/viewlet
'
;
...
...
@@ -660,7 +660,7 @@ export class GoToTest extends Action2 {
const
editorService
=
accessor
.
get
(
IEditorService
);
const
{
range
,
uri
,
extId
}
=
element
.
test
.
item
;
accessor
.
get
(
ITestExplorerFilterState
).
reveal
.
value
=
[
extId
]
;
accessor
.
get
(
ITestExplorerFilterState
).
reveal
.
value
=
extId
;
accessor
.
get
(
ITestingPeekOpener
).
closeAllPeeks
();
let
isFile
=
true
;
...
...
@@ -710,7 +710,7 @@ export class GoToTest extends Action2 {
const
fileService
=
accessor
.
get
(
IFileService
);
const
editorService
=
accessor
.
get
(
IEditorService
);
accessor
.
get
(
ITestExplorerFilterState
).
reveal
.
value
=
[
test
.
extId
]
;
accessor
.
get
(
ITestExplorerFilterState
).
reveal
.
value
=
test
.
extId
;
accessor
.
get
(
ITestingPeekOpener
).
closeAllPeeks
();
let
isFile
=
true
;
...
...
@@ -928,13 +928,13 @@ export class DebugCurrentFile extends ExecuteTestsInCurrentFile {
}
}
export
const
runTestsByPath
=
async
(
export
const
discoverAndRunTests
=
async
(
collection
:
IMainThreadTestCollection
,
progress
:
IProgressService
,
paths
:
ReadonlyArray
<
TestIdPath
>
,
ids
:
ReadonlyArray
<
string
>
,
runTests
:
(
tests
:
ReadonlyArray
<
InternalTestItem
>
)
=>
Promise
<
ITestResult
>
,
):
Promise
<
ITestResult
|
undefined
>
=>
{
const
todo
=
Promise
.
all
(
paths
.
map
(
p
=>
getTestByPath
(
collection
,
p
)));
const
todo
=
Promise
.
all
(
ids
.
map
(
p
=>
expandAndGetTestById
(
collection
,
p
)));
const
tests
=
(
await
showDiscoveringWhile
(
progress
,
todo
)).
filter
(
isDefined
);
return
tests
.
length
?
await
runTests
(
tests
)
:
undefined
;
};
...
...
@@ -945,7 +945,7 @@ abstract class RunOrDebugExtsByPath extends Action2 {
*/
public
async
run
(
accessor
:
ServicesAccessor
,
...
args
:
unknown
[])
{
const
testService
=
accessor
.
get
(
ITestService
);
await
runTestsByPath
(
await
discoverAndRunTests
(
accessor
.
get
(
ITestService
).
collection
,
accessor
.
get
(
IProgressService
),
[...
this
.
getTestExtIdsToRun
(
accessor
,
...
args
)],
...
...
@@ -953,7 +953,7 @@ abstract class RunOrDebugExtsByPath extends Action2 {
);
}
protected
abstract
getTestExtIdsToRun
(
accessor
:
ServicesAccessor
,
...
args
:
unknown
[]):
Iterable
<
TestIdPath
>
;
protected
abstract
getTestExtIdsToRun
(
accessor
:
ServicesAccessor
,
...
args
:
unknown
[]):
Iterable
<
string
>
;
protected
abstract
runTest
(
service
:
ITestService
,
node
:
readonly
InternalTestItem
[]):
Promise
<
ITestResult
>
;
}
...
...
@@ -971,23 +971,21 @@ abstract class RunOrDebugFailedTests extends RunOrDebugExtsByPath {
/**
* @inheritdoc
*/
protected
getTestExtIdsToRun
(
accessor
:
ServicesAccessor
)
:
Iterable
<
TestIdPath
>
{
protected
getTestExtIdsToRun
(
accessor
:
ServicesAccessor
)
{
const
{
results
}
=
accessor
.
get
(
ITestResultService
);
const
paths
=
new
Map
<
string
/* id */
,
string
/* path */
>
();
const
sep
=
'
$$TEST SEP$$
'
;
const
ids
=
new
Set
<
string
>
();
for
(
let
i
=
results
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
resultSet
=
results
[
i
];
for
(
const
test
of
resultSet
.
tests
)
{
const
path
=
getPathForTestInResult
(
test
,
resultSet
).
join
(
sep
);
if
(
isFailedState
(
test
.
ownComputedState
))
{
paths
.
set
(
test
.
item
.
extId
,
path
);
ids
.
add
(
test
.
item
.
extId
);
}
else
{
path
s
.
delete
(
test
.
item
.
extId
);
id
s
.
delete
(
test
.
item
.
extId
);
}
}
}
return
Iterable
.
map
(
paths
.
values
(),
p
=>
p
.
split
(
sep
))
;
return
ids
;
}
}
...
...
@@ -1008,7 +1006,7 @@ abstract class RunOrDebugLastRun extends RunOrDebugExtsByPath {
/**
* @inheritdoc
*/
protected
*
getTestExtIdsToRun
(
accessor
:
ServicesAccessor
,
runId
?:
string
):
Iterable
<
TestIdPath
>
{
protected
*
getTestExtIdsToRun
(
accessor
:
ServicesAccessor
,
runId
?:
string
):
Iterable
<
string
>
{
const
resultService
=
accessor
.
get
(
ITestResultService
);
const
lastResult
=
runId
?
resultService
.
results
.
find
(
r
=>
r
.
id
===
runId
)
:
resultService
.
results
[
0
];
if
(
!
lastResult
)
{
...
...
@@ -1017,10 +1015,7 @@ abstract class RunOrDebugLastRun extends RunOrDebugExtsByPath {
for
(
const
test
of
lastResult
.
request
.
targets
)
{
for
(
const
testId
of
test
.
testIds
)
{
const
test
=
lastResult
.
getStateById
(
testId
);
if
(
test
)
{
yield
getPathForTestInResult
(
test
,
lastResult
);
}
yield
testId
;
}
}
}
...
...
@@ -1086,7 +1081,7 @@ export class ReRunLastRun extends RunOrDebugLastRun {
protected
runTest
(
service
:
ITestService
,
internalTests
:
InternalTestItem
[]):
Promise
<
ITestResult
>
{
return
service
.
runTests
({
group
:
TestRunProfileBitset
.
Debug
,
group
:
TestRunProfileBitset
.
Run
,
tests
:
internalTests
.
map
(
identifyTest
),
});
}
...
...
src/vs/workbench/contrib/testing/browser/testing.contribution.ts
浏览文件 @
da7d92b8
...
...
@@ -26,7 +26,7 @@ import { ITestingProgressUiService, TestingProgressUiService } from 'vs/workbenc
import
{
TestingViewPaneContainer
}
from
'
vs/workbench/contrib/testing/browser/testingViewPaneContainer
'
;
import
{
testingConfiguation
}
from
'
vs/workbench/contrib/testing/common/configuration
'
;
import
{
Testing
}
from
'
vs/workbench/contrib/testing/common/constants
'
;
import
{
identifyTest
,
ITestIdWithSrc
,
Test
IdPath
,
Test
RunProfileBitset
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
identifyTest
,
ITestIdWithSrc
,
TestRunProfileBitset
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
ITestProfileService
,
TestProfileService
}
from
'
vs/workbench/contrib/testing/common/testConfigurationService
'
;
import
{
ITestingAutoRun
,
TestingAutoRun
}
from
'
vs/workbench/contrib/testing/common/testingAutoRun
'
;
import
{
TestingContentProvider
}
from
'
vs/workbench/contrib/testing/common/testingContentProvider
'
;
...
...
@@ -37,7 +37,7 @@ import { ITestResultStorage, TestResultStorage } from 'vs/workbench/contrib/test
import
{
ITestService
}
from
'
vs/workbench/contrib/testing/common/testService
'
;
import
{
TestService
}
from
'
vs/workbench/contrib/testing/common/testServiceImpl
'
;
import
{
LifecyclePhase
}
from
'
vs/workbench/services/lifecycle/common/lifecycle
'
;
import
{
allTestActions
,
runTestsByPath
}
from
'
./testExplorerActions
'
;
import
{
allTestActions
,
discoverAndRunTests
}
from
'
./testExplorerActions
'
;
import
'
./testingConfigurationUi
'
;
registerSingleton
(
ITestService
,
TestService
,
true
);
...
...
@@ -127,8 +127,8 @@ CommandsRegistry.registerCommand({
CommandsRegistry
.
registerCommand
({
id
:
'
vscode.revealTestInExplorer
'
,
handler
:
async
(
accessor
:
ServicesAccessor
,
pathToTest
:
TestIdPath
)
=>
{
accessor
.
get
(
ITestExplorerFilterState
).
reveal
.
value
=
pathToTest
;
handler
:
async
(
accessor
:
ServicesAccessor
,
testId
:
string
)
=>
{
accessor
.
get
(
ITestExplorerFilterState
).
reveal
.
value
=
testId
;
accessor
.
get
(
IViewsService
).
openView
(
Testing
.
ExplorerViewId
);
}
});
...
...
@@ -144,13 +144,13 @@ CommandsRegistry.registerCommand({
});
CommandsRegistry
.
registerCommand
({
id
:
'
vscode.runTestsBy
Path
'
,
handler
:
async
(
accessor
:
ServicesAccessor
,
group
:
TestRunProfileBitset
,
...
pathToTests
:
TestIdPath
[])
=>
{
id
:
'
vscode.runTestsBy
Id
'
,
handler
:
async
(
accessor
:
ServicesAccessor
,
group
:
TestRunProfileBitset
,
...
testIds
:
string
[])
=>
{
const
testService
=
accessor
.
get
(
ITestService
);
await
runTestsByPath
(
await
discoverAndRunTests
(
accessor
.
get
(
ITestService
).
collection
,
accessor
.
get
(
IProgressService
),
pathToTest
s
,
testId
s
,
tests
=>
testService
.
runTests
({
group
,
tests
:
tests
.
map
(
identifyTest
)
}),
);
}
...
...
src/vs/workbench/contrib/testing/browser/testingDecorations.ts
浏览文件 @
da7d92b8
...
...
@@ -437,20 +437,8 @@ abstract class RunTestDecoration extends Disposable {
}));
}
testActions
.
push
(
new
Action
(
'
testing.gutter.reveal
'
,
localize
(
'
reveal test
'
,
'
Reveal in Test Explorer
'
),
undefined
,
undefined
,
async
()
=>
{
const
path
=
[
test
];
while
(
true
)
{
const
parentId
=
path
[
0
].
parent
;
const
parent
=
parentId
&&
collection
.
getNodeById
(
parentId
);
if
(
!
parent
)
{
break
;
}
path
.
unshift
(
parent
);
}
await
this
.
commandService
.
executeCommand
(
'
vscode.revealTestInExplorer
'
,
path
.
map
(
t
=>
t
.
item
.
extId
));
}));
testActions
.
push
(
new
Action
(
'
testing.gutter.reveal
'
,
localize
(
'
reveal test
'
,
'
Reveal in Test Explorer
'
),
undefined
,
undefined
,
()
=>
this
.
commandService
.
executeCommand
(
'
vscode.revealTestInExplorer
'
,
test
.
item
.
extId
)));
return
testActions
;
}
...
...
src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts
浏览文件 @
da7d92b8
...
...
@@ -27,19 +27,14 @@ import { testingFilterIcon } from 'vs/workbench/contrib/testing/browser/icons';
import
{
TestExplorerStateFilter
,
Testing
}
from
'
vs/workbench/contrib/testing/common/constants
'
;
import
{
MutableObservableValue
}
from
'
vs/workbench/contrib/testing/common/observableValue
'
;
import
{
StoredValue
}
from
'
vs/workbench/contrib/testing/common/storedValue
'
;
import
{
TestIdPath
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
TestingContextKeys
}
from
'
vs/workbench/contrib/testing/common/testingContextKeys
'
;
import
{
ITestService
}
from
'
vs/workbench/contrib/testing/common/testService
'
;
export
interface
ITestExplorerFilterState
{
_serviceBrand
:
undefined
;
readonly
text
:
MutableObservableValue
<
string
>
;
/**
* Reveal request: the path to the test to reveal. The last element of the
* array is the test the user wanted to reveal, and the previous
* items are its parents.
*/
readonly
reveal
:
MutableObservableValue
<
TestIdPath
|
undefined
>
;
/** Test ID the user wants to reveal in the explorer */
readonly
reveal
:
MutableObservableValue
<
string
|
undefined
>
;
readonly
stateFilter
:
MutableObservableValue
<
TestExplorerStateFilter
>
;
readonly
currentDocumentOnly
:
MutableObservableValue
<
boolean
>
;
/** Whether excluded test should be shown in the view */
...
...
@@ -67,7 +62,7 @@ export class TestExplorerFilterState implements ITestExplorerFilterState {
},
this
.
storage
),
false
);
public
readonly
showExcludedTests
=
new
MutableObservableValue
(
false
);
public
readonly
reveal
=
new
MutableObservableValue
<
TestIdPath
|
undefined
>
(
undefined
);
public
readonly
reveal
=
new
MutableObservableValue
<
/* test ID */
string
|
undefined
>
(
undefined
);
public
readonly
onDidRequestInputFocus
=
this
.
focusEmitter
.
event
;
...
...
src/vs/workbench/contrib/testing/browser/testingExplorerView.ts
浏览文件 @
da7d92b8
...
...
@@ -55,12 +55,13 @@ import { ITestExplorerFilterState, TestExplorerFilterState, TestingExplorerFilte
import
{
ITestingProgressUiService
}
from
'
vs/workbench/contrib/testing/browser/testingProgressUiService
'
;
import
{
getTestingConfiguration
,
TestingConfigKeys
}
from
'
vs/workbench/contrib/testing/common/configuration
'
;
import
{
labelForTestInState
,
TestExplorerStateFilter
,
TestExplorerViewMode
,
TestExplorerViewSorting
,
Testing
,
testStateNames
}
from
'
vs/workbench/contrib/testing/common/constants
'
;
import
{
identifyTest
,
ITestRunProfile
,
TestI
dPath
,
TestI
temExpandState
,
TestRunProfileBitset
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
identifyTest
,
ITestRunProfile
,
TestItemExpandState
,
TestRunProfileBitset
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
capabilityContextKeys
,
ITestProfileService
}
from
'
vs/workbench/contrib/testing/common/testConfigurationService
'
;
import
{
TestId
}
from
'
vs/workbench/contrib/testing/common/testId
'
;
import
{
TestingContextKeys
}
from
'
vs/workbench/contrib/testing/common/testingContextKeys
'
;
import
{
ITestingPeekOpener
}
from
'
vs/workbench/contrib/testing/common/testingPeekOpener
'
;
import
{
cmpPriority
,
isFailedState
,
isStateWithResult
}
from
'
vs/workbench/contrib/testing/common/testingStates
'
;
import
{
getPathForTestInResult
,
TestResultItemChangeReason
}
from
'
vs/workbench/contrib/testing/common/testResult
'
;
import
{
TestResultItemChangeReason
}
from
'
vs/workbench/contrib/testing/common/testResult
'
;
import
{
ITestResultService
}
from
'
vs/workbench/contrib/testing/common/testResultService
'
;
import
{
ITestService
,
testCollectionIsEmpty
}
from
'
vs/workbench/contrib/testing/common/testService
'
;
import
{
ConfigureTestProfilesAction
,
DebugAllAction
,
GoToTest
,
RunAllAction
,
SelectDefaultTestProfiles
}
from
'
./testExplorerActions
'
;
...
...
@@ -451,7 +452,7 @@ export class TestingExplorerViewModel extends Disposable {
}
}));
this
.
_register
(
filterState
.
reveal
.
onDidChange
(
this
.
revealById
Path
,
this
));
this
.
_register
(
filterState
.
reveal
.
onDidChange
(
this
.
revealById
,
this
));
this
.
_register
(
onDidChangeVisibility
(
visible
=>
{
if
(
visible
)
{
...
...
@@ -495,7 +496,7 @@ export class TestingExplorerViewModel extends Disposable {
return
;
}
this
.
revealById
Path
(
getPathForTestInResult
(
evt
.
item
,
evt
.
result
)
,
false
,
false
);
this
.
revealById
(
evt
.
item
.
item
.
extId
,
false
,
false
);
}));
this
.
_register
(
testResults
.
onResultsChanged
(
evt
=>
{
...
...
@@ -525,8 +526,8 @@ export class TestingExplorerViewModel extends Disposable {
* Tries to reveal by extension ID. Queues the request if the extension
* ID is not currently available.
*/
private
revealById
Path
(
idPath
:
TestIdPath
|
undefined
,
expand
=
true
,
focus
=
true
)
{
if
(
!
id
Path
)
{
private
revealById
(
id
:
string
|
undefined
,
expand
=
true
,
focus
=
true
)
{
if
(
!
id
)
{
this
.
hasPendingReveal
=
false
;
return
;
}
...
...
@@ -538,6 +539,7 @@ export class TestingExplorerViewModel extends Disposable {
// If the item itself is visible in the tree, show it. Otherwise, expand
// its closest parent.
let
expandToLevel
=
0
;
const
idPath
=
[...
TestId
.
fromString
(
id
).
idsFromRoot
()];
for
(
let
i
=
idPath
.
length
-
1
;
i
>=
expandToLevel
;
i
--
)
{
const
element
=
this
.
projection
.
value
.
getElementByTestId
(
idPath
[
i
]);
// Skip all elements that aren't in the tree.
...
...
@@ -687,7 +689,7 @@ export class TestingExplorerViewModel extends Disposable {
this
.
projection
.
value
?.
applyTo
(
this
.
tree
);
if
(
this
.
hasPendingReveal
)
{
this
.
revealById
Path
(
this
.
filterState
.
reveal
.
value
);
this
.
revealById
(
this
.
filterState
.
reveal
.
value
);
}
}
...
...
src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts
浏览文件 @
da7d92b8
...
...
@@ -64,7 +64,7 @@ import { TestingContextKeys } from 'vs/workbench/contrib/testing/common/testingC
import
{
ITestingPeekOpener
}
from
'
vs/workbench/contrib/testing/common/testingPeekOpener
'
;
import
{
isFailedState
}
from
'
vs/workbench/contrib/testing/common/testingStates
'
;
import
{
buildTestUri
,
ParsedTestUri
,
parseTestUri
,
TestUriType
}
from
'
vs/workbench/contrib/testing/common/testingUri
'
;
import
{
getPathForTestInResult
,
ITestResult
,
maxCountPriority
,
resultItemParents
,
TestResultItemChange
,
TestResultItemChangeReason
}
from
'
vs/workbench/contrib/testing/common/testResult
'
;
import
{
ITestResult
,
maxCountPriority
,
resultItemParents
,
TestResultItemChange
,
TestResultItemChangeReason
}
from
'
vs/workbench/contrib/testing/common/testResult
'
;
import
{
ITestResultService
,
ResultChangeEvent
}
from
'
vs/workbench/contrib/testing/common/testResultService
'
;
import
{
ITestService
}
from
'
vs/workbench/contrib/testing/common/testService
'
;
import
{
ACTIVE_GROUP
,
IEditorService
,
SIDE_GROUP
}
from
'
vs/workbench/services/editor/common/editorService
'
;
...
...
@@ -900,10 +900,6 @@ export class TestCaseElement implements ITreeElement {
return
icons
.
testingStatesToIcons
.
get
(
this
.
test
.
computedState
);
}
public
get
path
()
{
return
getPathForTestInResult
(
this
.
test
,
this
.
results
);
}
constructor
(
private
readonly
results
:
ITestResult
,
public
readonly
test
:
TestResultItem
,
...
...
@@ -926,11 +922,7 @@ class TestTaskElement implements ITreeElement {
public
readonly
label
:
string
;
public
readonly
icon
=
undefined
;
public
get
path
()
{
return
getPathForTestInResult
(
this
.
test
,
this
.
results
);
}
constructor
(
private
readonly
results
:
ITestResult
,
public
readonly
test
:
TestResultItem
,
index
:
number
)
{
constructor
(
results
:
ITestResult
,
public
readonly
test
:
TestResultItem
,
index
:
number
)
{
this
.
id
=
`
${
results
.
id
}
/
${
test
.
item
.
extId
}
/
${
index
}
`
;
this
.
task
=
results
.
tasks
[
index
];
this
.
context
=
String
(
index
);
...
...
@@ -1318,12 +1310,13 @@ class TreeActionsProvider {
}
if
(
element
instanceof
TestCaseElement
||
element
instanceof
TestTaskElement
)
{
const
extId
=
element
.
test
.
item
.
extId
;
primary
.
push
(
new
Action
(
'
testing.outputPeek.revealInExplorer
'
,
localize
(
'
testing.revealInExplorer
'
,
"
Reveal in Test Explorer
"
),
Codicon
.
listTree
.
classNames
,
undefined
,
()
=>
this
.
commandService
.
executeCommand
(
'
vscode.revealTestInExplorer
'
,
e
lement
.
path
),
()
=>
this
.
commandService
.
executeCommand
(
'
vscode.revealTestInExplorer
'
,
e
xtId
),
));
if
(
capabilities
&
TestRunProfileBitset
.
Run
)
{
...
...
@@ -1332,17 +1325,17 @@ class TreeActionsProvider {
localize
(
'
run test
'
,
'
Run Test
'
),
ThemeIcon
.
asClassName
(
icons
.
testingRunIcon
),
undefined
,
()
=>
this
.
commandService
.
executeCommand
(
'
vscode.runTestsBy
Path
'
,
false
,
element
.
path
),
()
=>
this
.
commandService
.
executeCommand
(
'
vscode.runTestsBy
Id
'
,
TestRunProfileBitset
.
Run
,
extId
),
));
}
if
(
capabilities
&
TestRunProfileBitset
.
Coverage
)
{
if
(
capabilities
&
TestRunProfileBitset
.
Debug
)
{
primary
.
push
(
new
Action
(
'
testing.outputPeek.debugTest
'
,
localize
(
'
debug test
'
,
'
Debug Test
'
),
ThemeIcon
.
asClassName
(
icons
.
testingDebugIcon
),
undefined
,
()
=>
this
.
commandService
.
executeCommand
(
'
vscode.runTestsBy
Path
'
,
true
,
element
.
path
),
()
=>
this
.
commandService
.
executeCommand
(
'
vscode.runTestsBy
Id
'
,
TestRunProfileBitset
.
Debug
,
extId
),
));
}
}
...
...
src/vs/workbench/contrib/testing/common/ownedTestCollection.ts
浏览文件 @
da7d92b8
...
...
@@ -8,9 +8,10 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
assertNever
}
from
'
vs/base/common/types
'
;
import
{
diffTestItems
,
ExtHostTestItemEvent
,
ExtHostTestItemEventOp
,
getPrivateApiFor
,
TestItemImpl
}
from
'
vs/workbench/api/common/extHostTestingPrivateApi
'
;
import
{
diffTestItems
,
ExtHostTestItemEvent
,
ExtHostTestItemEventOp
,
getPrivateApiFor
,
TestItemImpl
,
TestItemRootImpl
}
from
'
vs/workbench/api/common/extHostTestingPrivateApi
'
;
import
*
as
Convert
from
'
vs/workbench/api/common/extHostTypeConverters
'
;
import
{
applyTestItemUpdate
,
TestDiffOpType
,
TestItemExpandState
,
TestsDiff
,
TestsDiffOp
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
TestId
}
from
'
vs/workbench/contrib/testing/common/testId
'
;
type
TestItemRaw
=
Convert
.
TestItem
.
Raw
;
...
...
@@ -22,9 +23,10 @@ export interface IHierarchyProvider {
* @private
*/
export
interface
OwnedCollectionTestItem
{
expand
:
TestItemExpandState
;
parent
:
string
|
null
;
readonly
fullId
:
TestId
;
readonly
parent
:
TestId
|
null
;
actual
:
TestItemImpl
;
expand
:
TestItemExpandState
;
/**
* Number of levels of items below this one that are expanded. May be infinite.
*/
...
...
@@ -32,118 +34,6 @@ export interface OwnedCollectionTestItem {
resolveBarrier
?:
Barrier
;
}
/**
* Enum for describing relative positions of tests. Similar to
* `node.compareDocumentPosition` in the DOM.
*/
export
const
enum
TestPosition
{
/** Neither a nor b are a child of one another. They may share a common parent, though. */
Disconnected
,
/** b is a child of a */
IsChild
,
/** b is a parent of a */
IsParent
,
/** a === b */
IsSame
,
}
/**
* Test tree is (or will be after debt week 2020-03) the standard collection
* for test trees. Internally it indexes tests by their extension ID in
* a map.
*/
export
class
TestTree
<
T
extends
OwnedCollectionTestItem
>
{
private
readonly
map
=
new
Map
<
string
,
T
>
();
private
readonly
_roots
=
new
Set
<
T
>
();
public
readonly
roots
:
ReadonlySet
<
T
>
=
this
.
_roots
;
/**
* Gets the size of the tree.
*/
public
get
size
()
{
return
this
.
map
.
size
;
}
/**
* Adds a new test to the tree if it doesn't exist.
* @throws if a duplicate item is inserted
*/
public
add
(
test
:
T
)
{
if
(
this
.
map
.
has
(
test
.
actual
.
id
))
{
throw
new
Error
(
`Attempted to insert a duplicate test item ID
${
test
.
actual
.
id
}
`
);
}
this
.
map
.
set
(
test
.
actual
.
id
,
test
);
if
(
!
test
.
parent
)
{
this
.
_roots
.
add
(
test
);
}
}
/**
* Gets whether the test exists in the tree.
*/
public
has
(
testId
:
string
)
{
return
this
.
map
.
has
(
testId
);
}
/**
* Removes a test ID from the tree. This is NOT recursive.
*/
public
delete
(
testId
:
string
)
{
const
existing
=
this
.
map
.
get
(
testId
);
if
(
!
existing
)
{
return
false
;
}
this
.
map
.
delete
(
testId
);
this
.
_roots
.
delete
(
existing
);
return
true
;
}
/**
* Gets a test item by ID from the tree.
*/
public
get
(
testId
:
string
)
{
return
this
.
map
.
get
(
testId
);
}
/**
* Compares the positions of the two items in the test tree.
*/
public
comparePositions
(
aOrId
:
T
|
string
,
bOrId
:
T
|
string
)
{
const
a
=
typeof
aOrId
===
'
string
'
?
this
.
map
.
get
(
aOrId
)
:
aOrId
;
const
b
=
typeof
bOrId
===
'
string
'
?
this
.
map
.
get
(
bOrId
)
:
bOrId
;
if
(
!
a
||
!
b
)
{
return
TestPosition
.
Disconnected
;
}
if
(
a
===
b
)
{
return
TestPosition
.
IsSame
;
}
for
(
let
p
=
this
.
map
.
get
(
b
.
parent
!
);
p
;
p
=
this
.
map
.
get
(
p
.
parent
!
))
{
if
(
p
===
a
)
{
return
TestPosition
.
IsChild
;
}
}
for
(
let
p
=
this
.
map
.
get
(
a
.
parent
!
);
p
;
p
=
this
.
map
.
get
(
p
.
parent
!
))
{
if
(
p
===
b
)
{
return
TestPosition
.
IsParent
;
}
}
return
TestPosition
.
Disconnected
;
}
/**
* Iterates over all test in the tree.
*/
[
Symbol
.
iterator
]()
{
return
this
.
map
.
values
();
}
}
/**
* Maintains tests created and registered for a single set of hierarchies
* for a workspace or document.
...
...
@@ -154,15 +44,13 @@ export class SingleUseTestCollection extends Disposable {
private
readonly
diffOpEmitter
=
this
.
_register
(
new
Emitter
<
TestsDiff
>
());
private
_resolveHandler
?:
(
item
:
TestItemRaw
)
=>
Promise
<
void
>
|
void
;
public
readonly
root
=
new
TestItem
Impl
(
`
${
this
.
controllerId
}
Root`
,
this
.
controllerId
,
undefine
d
);
public
readonly
tree
=
new
TestTree
<
OwnedCollectionTestItem
>
();
public
readonly
root
=
new
TestItem
RootImpl
(
this
.
controllerId
,
this
.
controllerI
d
);
public
readonly
tree
=
new
Map
<
/* full test id */
string
,
OwnedCollectionTestItem
>
();
protected
diff
:
TestsDiff
=
[];
constructor
(
private
readonly
controllerId
:
string
,
)
{
constructor
(
private
readonly
controllerId
:
string
)
{
super
();
this
.
upsertItem
(
this
.
root
,
null
);
this
.
upsertItem
(
this
.
root
,
undefined
);
}
/**
...
...
@@ -170,7 +58,7 @@ export class SingleUseTestCollection extends Disposable {
*/
public
set
resolveHandler
(
handler
:
undefined
|
((
item
:
TestItemRaw
)
=>
void
))
{
this
.
_resolveHandler
=
handler
;
for
(
const
test
of
this
.
tree
)
{
for
(
const
test
of
this
.
tree
.
values
()
)
{
this
.
updateExpandability
(
test
);
}
}
...
...
@@ -244,24 +132,23 @@ export class SingleUseTestCollection extends Disposable {
}
public
override
dispose
()
{
for
(
const
item
of
this
.
tree
)
{
for
(
const
item
of
this
.
tree
.
values
()
)
{
getPrivateApiFor
(
item
.
actual
).
listener
=
undefined
;
}
this
.
tree
.
clear
();
this
.
diff
=
[];
super
.
dispose
();
}
private
onTestItemEvent
(
internal
:
OwnedCollectionTestItem
,
evt
:
ExtHostTestItemEvent
)
{
const
extId
=
internal
?.
actual
.
id
;
switch
(
evt
.
op
)
{
case
ExtHostTestItemEventOp
.
Invalidated
:
this
.
pushDiff
([
TestDiffOpType
.
Retire
,
extId
]);
this
.
pushDiff
([
TestDiffOpType
.
Retire
,
internal
.
fullId
.
toString
()
]);
break
;
case
ExtHostTestItemEventOp
.
RemoveChild
:
this
.
removeItem
(
evt
.
id
);
this
.
removeItem
(
TestId
.
joinToString
(
internal
.
fullId
,
evt
.
id
)
);
break
;
case
ExtHostTestItemEventOp
.
Upsert
:
...
...
@@ -276,6 +163,7 @@ export class SingleUseTestCollection extends Disposable {
case
ExtHostTestItemEventOp
.
SetProp
:
const
{
key
,
value
}
=
evt
;
const
extId
=
internal
.
fullId
.
toString
();
switch
(
key
)
{
case
'
canResolveChildren
'
:
this
.
updateExpandability
(
internal
);
...
...
@@ -296,35 +184,43 @@ export class SingleUseTestCollection extends Disposable {
}
}
private
upsertItem
(
actual
:
TestItemRaw
,
parent
:
OwnedCollectionTestItem
|
null
)
{
private
upsertItem
(
actual
:
TestItemRaw
,
parent
:
OwnedCollectionTestItem
|
undefined
)
{
if
(
!
(
actual
instanceof
TestItemImpl
))
{
throw
new
Error
(
`TestItems provided to the VS Code API must extend
\`
vscode.TestItem
\`
, but
${
actual
.
id
}
did not`
);
}
const
fullId
=
TestId
.
fromExtHostTestItem
(
actual
,
this
.
root
.
id
,
parent
?.
actual
);
// If th
e item already exists under a different parent, remove it.
let
internal
=
this
.
tree
.
get
(
actual
.
id
);
if
(
internal
&&
internal
.
parent
!==
parent
?.
actual
.
id
)
{
(
internal
.
actual
.
parent
??
this
.
root
).
children
.
delete
(
actual
.
id
);
internal
=
undefined
;
// If th
is test item exists elsewhere in the tree already (exists at an
// old ID with an existing parent), remove that old item.
const
privateApi
=
getPrivateApiFor
(
actual
);
if
(
privateApi
.
parent
&&
privateApi
.
parent
!==
parent
?.
actual
)
{
privateApi
.
parent
.
children
.
delete
(
actual
.
id
)
;
}
let
internal
=
this
.
tree
.
get
(
fullId
.
toString
());
// Case 1: a brand new item
if
(
!
internal
)
{
const
parentId
=
parent
?
parent
.
actual
.
id
:
null
;
// always expand root node to know if there are tests (and whether to show the welcome view)
const
pExpandLvls
=
parent
?
parent
.
expandLevels
:
1
;
internal
=
{
fullId
,
actual
,
parent
:
parent
Id
,
parent
:
parent
?
fullId
.
parentId
:
null
,
expandLevels
:
pExpandLvls
/* intentionally undefined or 0 */
?
pExpandLvls
-
1
:
undefined
,
expand
:
TestItemExpandState
.
NotExpandable
,
// updated by `connectItemAndChildren`
};
this
.
tree
.
add
(
internal
);
this
.
tree
.
set
(
internal
.
fullId
.
toString
(),
internal
);
this
.
setItemParent
(
actual
,
parent
);
this
.
pushDiff
([
TestDiffOpType
.
Add
,
{
parent
:
parentId
,
controllerId
:
this
.
controllerId
,
expand
:
internal
.
expand
,
item
:
Convert
.
TestItem
.
from
(
actual
)
},
{
parent
:
internal
.
parent
&&
internal
.
parent
.
toString
(),
controllerId
:
this
.
controllerId
,
expand
:
internal
.
expand
,
item
:
Convert
.
TestItem
.
from
(
actual
,
this
.
root
.
id
),
},
]);
this
.
connectItemAndChildren
(
actual
,
internal
,
parent
);
...
...
@@ -351,24 +247,27 @@ export class SingleUseTestCollection extends Disposable {
this
.
connectItemAndChildren
(
actual
,
internal
,
parent
);
// Remove any children still referencing the old parent that aren't
// included in the new one. Note that children might have moved to a new
// parent, so the parent ID check is done.
// Remove any orphaned children.
for
(
const
child
of
oldChildren
)
{
if
(
!
actual
.
children
.
get
(
child
.
id
)
&&
this
.
tree
.
get
(
child
.
id
)?.
parent
===
actual
.
id
)
{
this
.
removeItem
(
child
.
id
);
if
(
!
actual
.
children
.
get
(
child
.
id
))
{
this
.
removeItem
(
TestId
.
joinToString
(
fullId
,
child
.
id
)
);
}
}
}
private
connectItem
(
actual
:
TestItemImpl
,
internal
:
OwnedCollectionTestItem
,
parent
:
OwnedCollectionTestItem
|
null
)
{
private
setItemParent
(
actual
:
TestItemImpl
,
parent
:
OwnedCollectionTestItem
|
undefined
)
{
getPrivateApiFor
(
actual
).
parent
=
parent
&&
parent
.
actual
!==
this
.
root
?
parent
.
actual
:
undefined
;
}
private
connectItem
(
actual
:
TestItemImpl
,
internal
:
OwnedCollectionTestItem
,
parent
:
OwnedCollectionTestItem
|
undefined
)
{
this
.
setItemParent
(
actual
,
parent
);
const
api
=
getPrivateApiFor
(
actual
);
api
.
parent
=
parent
&&
parent
.
actual
!==
this
.
root
?
parent
.
actual
:
undefined
;
api
.
parent
=
parent
?.
actual
;
api
.
listener
=
evt
=>
this
.
onTestItemEvent
(
internal
,
evt
);
this
.
updateExpandability
(
internal
);
}
private
connectItemAndChildren
(
actual
:
TestItemImpl
,
internal
:
OwnedCollectionTestItem
,
parent
:
OwnedCollectionTestItem
|
null
)
{
private
connectItemAndChildren
(
actual
:
TestItemImpl
,
internal
:
OwnedCollectionTestItem
,
parent
:
OwnedCollectionTestItem
|
undefined
)
{
this
.
connectItem
(
actual
,
internal
,
parent
);
// Discover any existing children that might have already been added
...
...
@@ -401,7 +300,7 @@ export class SingleUseTestCollection extends Disposable {
}
internal
.
expand
=
newState
;
this
.
pushDiff
([
TestDiffOpType
.
Update
,
{
extId
:
internal
.
actual
.
id
,
expand
:
newState
}]);
this
.
pushDiff
([
TestDiffOpType
.
Update
,
{
extId
:
internal
.
fullId
.
toString
()
,
expand
:
newState
}]);
if
(
newState
===
TestItemExpandState
.
Expandable
&&
internal
.
expandLevels
!==
undefined
)
{
this
.
resolveChildren
(
internal
);
...
...
@@ -419,7 +318,7 @@ export class SingleUseTestCollection extends Disposable {
}
const
asyncChildren
=
internal
.
actual
.
children
.
all
.
map
(
c
=>
this
.
expand
(
c
.
id
,
levels
))
.
map
(
c
=>
this
.
expand
(
TestId
.
joinToString
(
internal
.
fullId
,
c
.
id
)
,
levels
))
.
filter
(
isThenable
);
if
(
asyncChildren
.
length
)
{
...
...
@@ -467,7 +366,7 @@ export class SingleUseTestCollection extends Disposable {
}
private
pushExpandStateUpdate
(
internal
:
OwnedCollectionTestItem
)
{
this
.
pushDiff
([
TestDiffOpType
.
Update
,
{
extId
:
internal
.
actual
.
id
,
expand
:
internal
.
expand
}]);
this
.
pushDiff
([
TestDiffOpType
.
Update
,
{
extId
:
internal
.
fullId
.
toString
()
,
expand
:
internal
.
expand
}]);
}
private
removeItem
(
childId
:
string
)
{
...
...
@@ -486,9 +385,9 @@ export class SingleUseTestCollection extends Disposable {
}
getPrivateApiFor
(
item
.
actual
).
listener
=
undefined
;
this
.
tree
.
delete
(
item
.
actual
.
id
);
this
.
tree
.
delete
(
item
.
fullId
.
toString
()
);
for
(
const
child
of
item
.
actual
.
children
.
all
)
{
queue
.
push
(
this
.
tree
.
get
(
child
.
id
));
queue
.
push
(
this
.
tree
.
get
(
TestId
.
joinToString
(
item
.
fullId
,
child
.
id
)
));
}
}
}
...
...
src/vs/workbench/contrib/testing/common/testCollection.ts
浏览文件 @
da7d92b8
...
...
@@ -50,12 +50,6 @@ export interface ITestRunProfile {
hasConfigurationHandler
:
boolean
;
}
/**
* Defines the path to a test, as a list of test IDs. The last element of the
* array is the test ID, and the predecessors are its parents, in order.
*/
export
type
TestIdPath
=
string
[];
/**
* A fully-resolved request to run tests, passsed between the main thread
* and extension host.
...
...
src/vs/workbench/contrib/testing/common/testId.ts
0 → 100644
浏览文件 @
da7d92b8
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export
const
enum
TestIdPathParts
{
/** Delimiter for path parts in test IDs */
Delimiter
=
'
\
0
'
,
}
/**
* Enum for describing relative positions of tests. Similar to
* `node.compareDocumentPosition` in the DOM.
*/
export
const
enum
TestPosition
{
/** a === b */
IsSame
,
/** Neither a nor b are a child of one another. They may share a common parent, though. */
Disconnected
,
/** b is a child of a */
IsChild
,
/** b is a parent of a */
IsParent
,
}
type
TestItemLike
=
{
id
:
string
;
parent
?:
TestItemLike
};
/**
* The test ID is a stringifiable client that
*/
export
class
TestId
{
private
stringifed
?:
string
;
/**
* Creates a test ID from an ext host test item.
*/
public
static
fromExtHostTestItem
(
item
:
TestItemLike
,
rootId
:
string
,
parent
=
item
.
parent
)
{
if
(
item
.
id
===
rootId
)
{
return
new
TestId
([
rootId
]);
}
let
path
=
[
item
.
id
];
for
(
let
i
=
parent
;
i
&&
i
.
id
!==
rootId
;
i
=
i
.
parent
)
{
path
.
push
(
i
.
id
);
}
path
.
push
(
rootId
);
return
new
TestId
(
path
.
reverse
());
}
/**
* Creates a test ID from a serialized TestId instance.
*/
public
static
fromString
(
idString
:
string
)
{
return
new
TestId
(
idString
.
split
(
TestIdPathParts
.
Delimiter
));
}
/**
* Gets the ID resulting from adding b to the base ID.
*/
public
static
join
(
base
:
TestId
,
b
:
string
)
{
return
new
TestId
([...
base
.
path
,
b
]);
}
/**
* Gets the string ID resulting from adding b to the base ID.
*/
public
static
joinToString
(
base
:
string
|
TestId
,
b
:
string
)
{
return
base
.
toString
()
+
TestIdPathParts
.
Delimiter
+
b
;
}
constructor
(
public
readonly
path
:
readonly
string
[],
private
readonly
viewEnd
=
path
.
length
,
)
{
if
(
path
.
length
===
0
||
viewEnd
<
1
)
{
throw
new
Error
(
'
cannot create test with empty path
'
);
}
}
/**
* Gets the ID of the parent test.
*/
public
get
parentId
():
TestId
{
return
this
.
viewEnd
>
1
?
new
TestId
(
this
.
path
,
this
.
viewEnd
-
1
)
:
this
;
}
/**
* Gets the local ID of the current full test ID.
*/
public
get
localId
()
{
return
this
.
path
[
this
.
viewEnd
-
1
];
}
/**
* Gets whether this ID refers to the root.
*/
public
get
isRoot
()
{
return
this
.
viewEnd
===
1
;
}
/**
* Returns an iterable that yields IDs of all parent items down to and
* including the current item.
*/
public
*
idsFromRoot
()
{
let
built
=
this
.
path
[
0
];
yield
built
;
for
(
let
i
=
1
;
i
<
this
.
viewEnd
;
i
++
)
{
built
+=
TestIdPathParts
.
Delimiter
;
built
+=
this
.
path
[
i
];
yield
built
;
}
}
/**
* Compares the other test ID with this one.
*/
public
compare
(
other
:
TestId
)
{
for
(
let
i
=
0
;
i
<
other
.
viewEnd
&&
i
<
this
.
viewEnd
;
i
++
)
{
if
(
other
.
path
[
i
]
!==
this
.
path
[
i
])
{
return
TestPosition
.
Disconnected
;
}
}
if
(
other
.
viewEnd
>
this
.
viewEnd
)
{
return
TestPosition
.
IsChild
;
}
if
(
other
.
viewEnd
<
this
.
viewEnd
)
{
return
TestPosition
.
IsParent
;
}
return
TestPosition
.
IsSame
;
}
/**
* Serializes the ID.
*/
public
toJSON
()
{
return
this
.
toString
();
}
/**
* Serializes the ID to a string.
*/
public
toString
()
{
if
(
!
this
.
stringifed
)
{
this
.
stringifed
=
this
.
path
[
0
];
for
(
let
i
=
1
;
i
<
this
.
viewEnd
;
i
++
)
{
this
.
stringifed
+=
TestIdPathParts
.
Delimiter
;
this
.
stringifed
+=
this
.
path
[
i
];
}
}
return
this
.
stringifed
;
}
}
src/vs/workbench/contrib/testing/common/testResult.ts
浏览文件 @
da7d92b8
...
...
@@ -13,7 +13,7 @@ import { localize } from 'vs/nls';
import
{
TestResultState
}
from
'
vs/workbench/api/common/extHostTypes
'
;
import
{
IComputedStateAccessor
,
refreshComputedState
}
from
'
vs/workbench/contrib/testing/common/getComputedState
'
;
import
{
IObservableValue
,
MutableObservableValue
,
staticObservableValue
}
from
'
vs/workbench/contrib/testing/common/observableValue
'
;
import
{
ISerializedTestResults
,
ITestItem
,
ITestMessage
,
ITestRunTask
,
ITestTaskState
,
ResolvedTestRunRequest
,
Test
IdPath
,
Test
ResultItem
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
ISerializedTestResults
,
ITestItem
,
ITestMessage
,
ITestRunTask
,
ITestTaskState
,
ResolvedTestRunRequest
,
TestResultItem
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
TestCoverage
}
from
'
vs/workbench/contrib/testing/common/testCoverage
'
;
import
{
maxPriority
,
statesInOrder
}
from
'
vs/workbench/contrib/testing/common/testingStates
'
;
...
...
@@ -86,15 +86,6 @@ export const resultItemParents = function* (results: ITestResult, item: TestResu
}
};
export
const
getPathForTestInResult
=
(
test
:
TestResultItem
,
results
:
ITestResult
):
TestIdPath
=>
{
const
path
:
TestIdPath
=
[];
for
(
const
node
of
resultItemParents
(
results
,
test
))
{
path
.
unshift
(
node
.
item
.
extId
);
}
return
path
;
};
/**
* Count of the number of tests in each run state.
*/
...
...
src/vs/workbench/contrib/testing/common/testService.ts
浏览文件 @
da7d92b8
...
...
@@ -11,8 +11,9 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
createDecorator
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IObservableValue
}
from
'
vs/workbench/contrib/testing/common/observableValue
'
;
import
{
AbstractIncrementalTestCollection
,
IncrementalTestCollectionItem
,
InternalTestItem
,
ITestIdWithSrc
,
ResolvedTestRunRequest
,
RunTestForControllerRequest
,
TestI
dPath
,
TestI
temExpandState
,
TestRunProfileBitset
,
TestsDiff
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
AbstractIncrementalTestCollection
,
IncrementalTestCollectionItem
,
InternalTestItem
,
ITestIdWithSrc
,
ResolvedTestRunRequest
,
RunTestForControllerRequest
,
TestItemExpandState
,
TestRunProfileBitset
,
TestsDiff
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
TestExclusions
}
from
'
vs/workbench/contrib/testing/common/testExclusions
'
;
import
{
TestId
}
from
'
vs/workbench/contrib/testing/common/testId
'
;
import
{
ITestResult
}
from
'
vs/workbench/contrib/testing/common/testResult
'
;
export
const
ITestService
=
createDecorator
<
ITestService
>
(
'
testService
'
);
...
...
@@ -82,18 +83,12 @@ export const testCollectionIsEmpty = (collection: IMainThreadTestCollection) =>
!
Iterable
.
some
(
collection
.
rootItems
,
r
=>
r
.
children
.
size
>
0
);
/**
* Ensures the test with the given
path
exists in the collection, if possible.
* Ensures the test with the given
ID
exists in the collection, if possible.
* If cancellation is requested, or the test cannot be found, it will return
* undefined.
*/
export
const
getTestByPath
=
async
(
collection
:
IMainThreadTestCollection
,
idPath
:
TestIdPath
,
ct
=
CancellationToken
.
None
)
=>
{
// Expand all direct children since roots might well have different IDs, but
// children should start matching.
await
expandFirstLevel
(
collection
);
if
(
ct
.
isCancellationRequested
)
{
return
undefined
;
}
export
const
expandAndGetTestById
=
async
(
collection
:
IMainThreadTestCollection
,
id
:
string
,
ct
=
CancellationToken
.
None
)
=>
{
const
idPath
=
[...
TestId
.
fromString
(
id
).
idsFromRoot
()];
let
expandToLevel
=
0
;
for
(
let
i
=
idPath
.
length
-
1
;
!
ct
.
isCancellationRequested
&&
i
>=
expandToLevel
;)
{
...
...
src/vs/workbench/contrib/testing/common/testServiceImpl.ts
浏览文件 @
da7d92b8
...
...
@@ -155,7 +155,9 @@ export class TestService extends Disposable implements ITestService {
group
=>
this
.
testControllers
.
get
(
group
.
controllerId
)?.
runTests
(
{
runId
:
result
.
id
,
excludeExtIds
:
req
.
exclude
!
.
filter
(
t
=>
t
.
controllerId
===
group
.
controllerId
).
map
(
t
=>
t
.
testId
),
excludeExtIds
:
req
.
exclude
!
.
filter
(
t
=>
t
.
controllerId
===
group
.
controllerId
&&
!
group
.
testIds
.
includes
(
t
.
testId
))
.
map
(
t
=>
t
.
testId
),
profileId
:
group
.
profileId
,
controllerId
:
group
.
controllerId
,
testIds
:
group
.
testIds
,
...
...
src/vs/workbench/contrib/testing/test/browser/explorerProjections/hierarchalByLocation.test.ts
浏览文件 @
da7d92b8
...
...
@@ -7,6 +7,7 @@ import * as assert from 'assert';
import
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
HierarchicalByLocationProjection
}
from
'
vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByLocation
'
;
import
{
TestDiffOpType
,
TestItemExpandState
,
TestResultItem
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
TestId
}
from
'
vs/workbench/contrib/testing/common/testId
'
;
import
{
TestResultState
}
from
'
vs/workbench/contrib/testing/common/testingStates
'
;
import
{
TestResultItemChange
,
TestResultItemChangeReason
}
from
'
vs/workbench/contrib/testing/common/testResult
'
;
import
{
Convert
,
TestItemImpl
}
from
'
vs/workbench/contrib/testing/common/testStubs
'
;
...
...
@@ -44,7 +45,7 @@ suite('Workbench - Testing Explorer Hierarchal by Location Projection', () => {
test
(
'
expands children
'
,
async
()
=>
{
harness
.
flush
();
harness
.
tree
.
expand
(
harness
.
projection
.
getElementByTestId
(
'
id-a
'
)
!
);
harness
.
tree
.
expand
(
harness
.
projection
.
getElementByTestId
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
)
!
);
assert
.
deepStrictEqual
(
harness
.
flush
(),
[
{
e
:
'
a
'
,
children
:
[{
e
:
'
aa
'
},
{
e
:
'
ab
'
}]
},
{
e
:
'
b
'
}
]);
...
...
@@ -54,10 +55,10 @@ suite('Workbench - Testing Explorer Hierarchal by Location Projection', () => {
harness
.
flush
();
harness
.
pushDiff
([
TestDiffOpType
.
Add
,
{
controllerId
:
'
ctrl2
'
,
parent
:
null
,
expand
:
TestItemExpandState
.
Expanded
,
item
:
Convert
.
TestItem
.
from
(
new
TestItemImpl
(
'
c
'
,
'
c
'
,
undefined
))
},
{
controllerId
:
'
ctrl2
'
,
parent
:
null
,
expand
:
TestItemExpandState
.
Expanded
,
item
:
Convert
.
TestItem
.
from
(
new
TestItemImpl
(
'
c
'
,
'
c
'
,
undefined
)
,
'
ctrl2
'
)
},
],
[
TestDiffOpType
.
Add
,
{
controllerId
:
'
ctrl2
'
,
parent
:
'
c
'
,
expand
:
TestItemExpandState
.
NotExpandable
,
item
:
Convert
.
TestItem
.
from
(
new
TestItemImpl
(
'
c-a
'
,
'
ca
'
,
undefined
)
)
},
{
controllerId
:
'
ctrl2
'
,
parent
:
new
TestId
([
'
ctrl2
'
,
'
c
'
]).
toString
(),
expand
:
TestItemExpandState
.
NotExpandable
,
item
:
Convert
.
TestItem
.
from
(
new
TestItemImpl
(
'
c-a
'
,
'
ca
'
,
undefined
),
'
ctrl2
'
)
},
]);
assert
.
deepStrictEqual
(
harness
.
flush
(),
[
...
...
@@ -68,7 +69,7 @@ suite('Workbench - Testing Explorer Hierarchal by Location Projection', () => {
test
(
'
updates nodes if they add children
'
,
async
()
=>
{
harness
.
flush
();
harness
.
tree
.
expand
(
harness
.
projection
.
getElementByTestId
(
'
id-a
'
)
!
);
harness
.
tree
.
expand
(
harness
.
projection
.
getElementByTestId
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
)
!
);
assert
.
deepStrictEqual
(
harness
.
flush
(),
[
{
e
:
'
a
'
,
children
:
[{
e
:
'
aa
'
},
{
e
:
'
ab
'
}]
},
...
...
@@ -85,7 +86,7 @@ suite('Workbench - Testing Explorer Hierarchal by Location Projection', () => {
test
(
'
updates nodes if they remove children
'
,
async
()
=>
{
harness
.
flush
();
harness
.
tree
.
expand
(
harness
.
projection
.
getElementByTestId
(
'
id-a
'
)
!
);
harness
.
tree
.
expand
(
harness
.
projection
.
getElementByTestId
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
)
!
);
assert
.
deepStrictEqual
(
harness
.
flush
(),
[
{
e
:
'
a
'
,
children
:
[{
e
:
'
aa
'
},
{
e
:
'
ab
'
}]
},
...
...
@@ -105,7 +106,7 @@ suite('Workbench - Testing Explorer Hierarchal by Location Projection', () => {
resultsService
.
getStateById
=
()
=>
[
undefined
,
resultInState
(
TestResultState
.
Failed
)];
const
resultInState
=
(
state
:
TestResultState
):
TestResultItem
=>
({
item
:
Convert
.
TestItem
.
from
(
harness
.
c
.
tree
.
get
(
'
id-a
'
)
!
.
actual
),
item
:
Convert
.
TestItem
.
from
(
harness
.
c
.
tree
.
get
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
())
!
.
actual
,
'
ctrlId
'
),
parent
:
'
id-root
'
,
tasks
:
[],
retired
:
false
,
...
...
src/vs/workbench/contrib/testing/test/browser/explorerProjections/hierarchalByName.test.ts
浏览文件 @
da7d92b8
...
...
@@ -7,6 +7,7 @@ import * as assert from 'assert';
import
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
HierarchicalByNameProjection
}
from
'
vs/workbench/contrib/testing/browser/explorerProjections/hierarchalByName
'
;
import
{
TestDiffOpType
,
TestItemExpandState
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
TestId
}
from
'
vs/workbench/contrib/testing/common/testId
'
;
import
{
TestResultItemChange
}
from
'
vs/workbench/contrib/testing/common/testResult
'
;
import
{
Convert
,
TestItemImpl
}
from
'
vs/workbench/contrib/testing/common/testStubs
'
;
import
{
TestTreeTestHarness
}
from
'
vs/workbench/contrib/testing/test/browser/testObjectTree
'
;
...
...
@@ -42,10 +43,10 @@ suite('Workbench - Testing Explorer Hierarchal by Name Projection', () => {
harness
.
flush
();
harness
.
pushDiff
([
TestDiffOpType
.
Add
,
{
controllerId
:
'
ctrl2
'
,
parent
:
null
,
expand
:
TestItemExpandState
.
Expanded
,
item
:
Convert
.
TestItem
.
from
(
new
TestItemImpl
(
'
c
'
,
'
root2
'
,
undefined
))
},
{
controllerId
:
'
ctrl2
'
,
parent
:
null
,
expand
:
TestItemExpandState
.
Expanded
,
item
:
Convert
.
TestItem
.
from
(
new
TestItemImpl
(
'
c
'
,
'
root2
'
,
undefined
)
,
'
ctrl2
'
)
},
],
[
TestDiffOpType
.
Add
,
{
controllerId
:
'
ctrl2
'
,
parent
:
'
c
'
,
expand
:
TestItemExpandState
.
NotExpandable
,
item
:
Convert
.
TestItem
.
from
(
new
TestItemImpl
(
'
c-a
'
,
'
c
'
,
undefined
)
)
},
{
controllerId
:
'
ctrl2
'
,
parent
:
new
TestId
([
'
ctrl2
'
,
'
c
'
]).
toString
(),
expand
:
TestItemExpandState
.
NotExpandable
,
item
:
Convert
.
TestItem
.
from
(
new
TestItemImpl
(
'
c-a
'
,
'
c
'
,
undefined
),
'
ctrl2
'
)
},
]);
assert
.
deepStrictEqual
(
harness
.
flush
(),
[
...
...
src/vs/workbench/contrib/testing/test/common/testResultService.test.ts
浏览文件 @
da7d92b8
...
...
@@ -12,8 +12,9 @@ import { NullLogService } from 'vs/platform/log/common/log';
import
{
SingleUseTestCollection
}
from
'
vs/workbench/contrib/testing/common/ownedTestCollection
'
;
import
{
ITestTaskState
,
ResolvedTestRunRequest
,
TestResultItem
,
TestRunProfileBitset
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
TestProfileService
}
from
'
vs/workbench/contrib/testing/common/testConfigurationService
'
;
import
{
TestId
}
from
'
vs/workbench/contrib/testing/common/testId
'
;
import
{
TestResultState
}
from
'
vs/workbench/contrib/testing/common/testingStates
'
;
import
{
getPathForTestInResult
,
HydratedTestResult
,
LiveOutputController
,
LiveTestResult
,
makeEmptyCounts
,
resultItemParents
,
TestResultItemChange
,
TestResultItemChangeReason
}
from
'
vs/workbench/contrib/testing/common/testResult
'
;
import
{
HydratedTestResult
,
LiveOutputController
,
LiveTestResult
,
makeEmptyCounts
,
resultItemParents
,
TestResultItemChange
,
TestResultItemChangeReason
}
from
'
vs/workbench/contrib/testing/common/testResult
'
;
import
{
TestResultService
}
from
'
vs/workbench/contrib/testing/common/testResultService
'
;
import
{
InMemoryResultStorage
,
ITestResultStorage
}
from
'
vs/workbench/contrib/testing/common/testResultStorage
'
;
import
{
Convert
,
getInitializedMainTestCollection
,
testStubs
}
from
'
vs/workbench/contrib/testing/common/testStubs
'
;
...
...
@@ -63,15 +64,15 @@ suite('Workbench - Test Results Service', () => {
tests
=
testStubs
.
nested
();
await
tests
.
expand
(
tests
.
root
.
id
,
Infinity
);
r
.
addTestChainToRun
(
'
ctrl
'
,
[
Convert
.
TestItem
.
from
(
tests
.
root
),
Convert
.
TestItem
.
from
(
tests
.
root
.
children
.
get
(
'
id-a
'
)
!
),
Convert
.
TestItem
.
from
(
tests
.
root
.
children
.
get
(
'
id-a
'
)
!
.
children
.
get
(
'
id-aa
'
)
!
),
r
.
addTestChainToRun
(
'
ctrl
Id
'
,
[
Convert
.
TestItem
.
from
(
tests
.
root
,
'
ctrlId
'
),
Convert
.
TestItem
.
from
(
tests
.
root
.
children
.
get
(
'
id-a
'
)
!
,
'
ctrlId
'
),
Convert
.
TestItem
.
from
(
tests
.
root
.
children
.
get
(
'
id-a
'
)
!
.
children
.
get
(
'
id-aa
'
)
!
,
'
ctrlId
'
),
]);
r
.
addTestChainToRun
(
'
ctrl
'
,
[
Convert
.
TestItem
.
from
(
tests
.
root
.
children
.
get
(
'
id-a
'
)
!
),
Convert
.
TestItem
.
from
(
tests
.
root
.
children
.
get
(
'
id-a
'
)
!
.
children
.
get
(
'
id-ab
'
)
!
),
r
.
addTestChainToRun
(
'
ctrl
Id
'
,
[
Convert
.
TestItem
.
from
(
tests
.
root
.
children
.
get
(
'
id-a
'
)
!
,
'
ctrlId
'
),
Convert
.
TestItem
.
from
(
tests
.
root
.
children
.
get
(
'
id-a
'
)
!
.
children
.
get
(
'
id-ab
'
)
!
,
'
ctrlId
'
),
]);
});
...
...
@@ -122,8 +123,8 @@ suite('Workbench - Test Results Service', () => {
[
TestResultState
.
Failed
]:
3
,
});
assert
.
deepStrictEqual
(
r
.
getStateById
(
'
id-a
'
)?.
ownComputedState
,
TestResultState
.
Failed
);
assert
.
deepStrictEqual
(
r
.
getStateById
(
'
id-a
'
)?.
tasks
[
0
].
state
,
TestResultState
.
Failed
);
assert
.
deepStrictEqual
(
r
.
getStateById
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
)?.
ownComputedState
,
TestResultState
.
Failed
);
assert
.
deepStrictEqual
(
r
.
getStateById
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
)?.
tasks
[
0
].
state
,
TestResultState
.
Failed
);
assert
.
deepStrictEqual
(
getChangeSummary
(),
[
{
label
:
'
a
'
,
reason
:
TestResultItemChangeReason
.
OwnStateChange
},
{
label
:
'
aa
'
,
reason
:
TestResultItemChangeReason
.
OwnStateChange
},
...
...
@@ -134,14 +135,14 @@ suite('Workbench - Test Results Service', () => {
test
(
'
updateState
'
,
()
=>
{
changed
.
clear
();
r
.
updateState
(
'
id-aa
'
,
'
t
'
,
TestResultState
.
Running
);
r
.
updateState
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
,
'
id-aa
'
]).
toString
()
,
'
t
'
,
TestResultState
.
Running
);
assert
.
deepStrictEqual
(
r
.
counts
,
{
...
makeEmptyCounts
(),
[
TestResultState
.
Unset
]:
2
,
[
TestResultState
.
Running
]:
1
,
[
TestResultState
.
Queued
]:
1
,
});
assert
.
deepStrictEqual
(
r
.
getStateById
(
'
id-aa
'
)?.
ownComputedState
,
TestResultState
.
Running
);
assert
.
deepStrictEqual
(
r
.
getStateById
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
,
'
id-aa
'
]).
toString
()
)?.
ownComputedState
,
TestResultState
.
Running
);
// update computed state:
assert
.
deepStrictEqual
(
r
.
getStateById
(
tests
.
root
.
id
)?.
computedState
,
TestResultState
.
Running
);
assert
.
deepStrictEqual
(
getChangeSummary
(),
[
...
...
@@ -153,7 +154,7 @@ suite('Workbench - Test Results Service', () => {
test
(
'
retire
'
,
()
=>
{
changed
.
clear
();
r
.
retire
(
'
id-a
'
);
r
.
retire
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
);
assert
.
deepStrictEqual
(
getChangeSummary
(),
[
{
label
:
'
a
'
,
reason
:
TestResultItemChangeReason
.
Retired
},
{
label
:
'
aa
'
,
reason
:
TestResultItemChangeReason
.
ParentRetired
},
...
...
@@ -161,24 +162,24 @@ suite('Workbench - Test Results Service', () => {
]);
changed
.
clear
();
r
.
retire
(
'
id-a
'
);
r
.
retire
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
);
assert
.
strictEqual
(
changed
.
size
,
0
);
});
test
(
'
ignores outside run
'
,
()
=>
{
changed
.
clear
();
r
.
updateState
(
'
id-b
'
,
'
t
'
,
TestResultState
.
Running
);
r
.
updateState
(
new
TestId
([
'
ctrlId
'
,
'
id-b
'
]).
toString
()
,
'
t
'
,
TestResultState
.
Running
);
assert
.
deepStrictEqual
(
r
.
counts
,
{
...
makeEmptyCounts
(),
[
TestResultState
.
Queued
]:
2
,
[
TestResultState
.
Unset
]:
2
,
});
assert
.
deepStrictEqual
(
r
.
getStateById
(
'
id-b
'
),
undefined
);
assert
.
deepStrictEqual
(
r
.
getStateById
(
new
TestId
([
'
ctrlId
'
,
'
id-b
'
]).
toString
()
),
undefined
);
});
test
(
'
markComplete
'
,
()
=>
{
r
.
setAllToState
(
TestResultState
.
Queued
,
'
t
'
,
()
=>
true
);
r
.
updateState
(
'
id-aa
'
,
'
t
'
,
TestResultState
.
Passed
);
r
.
updateState
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
,
'
id-aa
'
]).
toString
()
,
'
t
'
,
TestResultState
.
Passed
);
changed
.
clear
();
r
.
markComplete
();
...
...
@@ -190,7 +191,7 @@ suite('Workbench - Test Results Service', () => {
});
assert
.
deepStrictEqual
(
r
.
getStateById
(
tests
.
root
.
id
)?.
ownComputedState
,
TestResultState
.
Unset
);
assert
.
deepStrictEqual
(
r
.
getStateById
(
'
id-aa
'
)?.
ownComputedState
,
TestResultState
.
Passed
);
assert
.
deepStrictEqual
(
r
.
getStateById
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
,
'
id-aa
'
]).
toString
()
)?.
ownComputedState
,
TestResultState
.
Passed
);
});
});
...
...
@@ -214,7 +215,7 @@ suite('Workbench - Test Results Service', () => {
test
(
'
serializes and re-hydrates
'
,
async
()
=>
{
results
.
push
(
r
);
r
.
updateState
(
'
id-aa
'
,
'
t
'
,
TestResultState
.
Passed
);
r
.
updateState
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
,
'
id-aa
'
]).
toString
()
,
'
t
'
,
TestResultState
.
Passed
);
r
.
markComplete
();
await
timeout
(
10
);
// allow persistImmediately async to happen
...
...
@@ -235,7 +236,7 @@ suite('Workbench - Test Results Service', () => {
delete
expected
.
item
.
description
;
expected
.
item
.
uri
=
actual
.
item
.
uri
;
assert
.
deepStrictEqual
(
actual
,
{
...
expected
,
src
:
undefined
,
retired
:
true
,
children
:
[
'
id-a
'
]
});
assert
.
deepStrictEqual
(
actual
,
{
...
expected
,
src
:
undefined
,
retired
:
true
,
children
:
[
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
]
});
assert
.
deepStrictEqual
(
rehydrated
.
counts
,
r
.
counts
);
assert
.
strictEqual
(
typeof
rehydrated
.
completedAt
,
'
number
'
);
});
...
...
@@ -278,7 +279,7 @@ suite('Workbench - Test Results Service', () => {
name
:
'
hello world
'
,
request
:
defaultOpts
([]),
items
:
[{
...(
await
getInitializedMainTestCollection
()).
getNodeById
(
'
id-a
'
)
!
,
...(
await
getInitializedMainTestCollection
()).
getNodeById
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
)
!
,
tasks
:
[{
state
,
duration
:
0
,
messages
:
[]
}],
computedState
:
state
,
ownComputedState
:
state
,
...
...
@@ -312,22 +313,14 @@ suite('Workbench - Test Results Service', () => {
});
test
(
'
resultItemParents
'
,
()
=>
{
assert
.
deepStrictEqual
([...
resultItemParents
(
r
,
r
.
getStateById
(
'
id-aa
'
)
!
)],
[
r
.
getStateById
(
'
id-aa
'
),
r
.
getStateById
(
'
id-a
'
),
r
.
getStateById
(
tests
.
root
.
id
),
assert
.
deepStrictEqual
([...
resultItemParents
(
r
,
r
.
getStateById
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
,
'
id-aa
'
]).
toString
()
)
!
)],
[
r
.
getStateById
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
,
'
id-aa
'
]).
toString
()
),
r
.
getStateById
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
),
r
.
getStateById
(
new
TestId
([
'
ctrlId
'
]).
toString
()
),
]);
assert
.
deepStrictEqual
([...
resultItemParents
(
r
,
r
.
getStateById
(
tests
.
root
.
id
)
!
)],
[
r
.
getStateById
(
tests
.
root
.
id
),
]);
});
test
(
'
getPathForTestInResult
'
,
()
=>
{
assert
.
deepStrictEqual
([...
getPathForTestInResult
(
r
.
getStateById
(
'
id-aa
'
)
!
,
r
)],
[
tests
.
root
.
id
,
'
id-a
'
,
'
id-aa
'
,
]);
});
});
src/vs/workbench/contrib/testing/test/common/testResultStorage.test.ts
浏览文件 @
da7d92b8
...
...
@@ -6,6 +6,7 @@
import
*
as
assert
from
'
assert
'
;
import
{
range
}
from
'
vs/base/common/arrays
'
;
import
{
NullLogService
}
from
'
vs/platform/log/common/log
'
;
import
{
TestId
}
from
'
vs/workbench/contrib/testing/common/testId
'
;
import
{
ITestResult
,
LiveTestResult
}
from
'
vs/workbench/contrib/testing/common/testResult
'
;
import
{
InMemoryResultStorage
,
RETAIN_MAX_RESULTS
}
from
'
vs/workbench/contrib/testing/common/testResultStorage
'
;
import
{
Convert
,
testStubs
}
from
'
vs/workbench/contrib/testing/common/testStubs
'
;
...
...
@@ -26,14 +27,14 @@ suite('Workbench - Test Result Storage', () => {
t
.
addTask
({
id
:
'
t
'
,
name
:
undefined
,
running
:
true
});
const
tests
=
testStubs
.
nested
();
tests
.
expand
(
tests
.
root
.
id
,
Infinity
);
t
.
addTestChainToRun
(
'
ctrl
'
,
[
Convert
.
TestItem
.
from
(
tests
.
root
),
Convert
.
TestItem
.
from
(
tests
.
root
.
children
.
get
(
'
id-a
'
)
!
),
Convert
.
TestItem
.
from
(
tests
.
root
.
children
.
get
(
'
id-a
'
)
!
.
children
.
get
(
'
id-aa
'
)
!
),
t
.
addTestChainToRun
(
'
ctrl
Id
'
,
[
Convert
.
TestItem
.
from
(
tests
.
root
,
'
ctrlId
'
),
Convert
.
TestItem
.
from
(
tests
.
root
.
children
.
get
(
'
id-a
'
)
!
,
'
ctrlId
'
),
Convert
.
TestItem
.
from
(
tests
.
root
.
children
.
get
(
'
id-a
'
)
!
.
children
.
get
(
'
id-aa
'
)
!
,
'
ctrlId
'
),
]);
if
(
addMessage
)
{
t
.
appendMessage
(
'
id-a
'
,
'
t
'
,
{
t
.
appendMessage
(
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
,
'
t
'
,
{
message
:
addMessage
,
actualOutput
:
undefined
,
expectedOutput
:
undefined
,
...
...
@@ -75,7 +76,8 @@ suite('Workbench - Test Result Storage', () => {
test
(
'
limits stored result by budget
'
,
async
()
=>
{
const
r
=
range
(
100
).
map
(()
=>
makeResult
(
'
a
'
.
repeat
(
2048
)));
await
storage
.
persist
(
r
);
assert
.
strictEqual
(
true
,
(
await
storage
.
read
()).
length
<
50
);
const
length
=
(
await
storage
.
read
()).
length
;
assert
.
strictEqual
(
true
,
length
<
50
);
});
test
(
'
always stores the min number of results
'
,
async
()
=>
{
...
...
src/vs/workbench/test/browser/api/extHostTesting.test.ts
浏览文件 @
da7d92b8
...
...
@@ -13,6 +13,7 @@ import { TestRunProfileImpl, TestRunCoordinator, TestRunDto } from 'vs/workbench
import
*
as
convert
from
'
vs/workbench/api/common/extHostTypeConverters
'
;
import
{
TestMessage
,
TestResultState
,
TestRunProfileGroup
}
from
'
vs/workbench/api/common/extHostTypes
'
;
import
{
TestDiffOpType
,
TestItemExpandState
}
from
'
vs/workbench/contrib/testing/common/testCollection
'
;
import
{
TestId
}
from
'
vs/workbench/contrib/testing/common/testId
'
;
import
{
TestItemImpl
,
testStubs
}
from
'
vs/workbench/contrib/testing/common/testStubs
'
;
import
{
TestSingleUseCollection
}
from
'
vs/workbench/contrib/testing/test/common/ownedTestCollection
'
;
import
type
{
TestItem
,
TestRunRequest
}
from
'
vscode
'
;
...
...
@@ -73,18 +74,20 @@ suite('ExtHost Testing', () => {
suite
(
'
OwnedTestCollection
'
,
()
=>
{
test
(
'
adds a root recursively
'
,
async
()
=>
{
await
single
.
expand
(
single
.
root
.
id
,
Infinity
);
const
a
=
single
.
root
.
children
.
get
(
'
id-a
'
)
!
;
const
b
=
single
.
root
.
children
.
get
(
'
id-b
'
)
!
;
assert
.
deepStrictEqual
(
single
.
collectDiff
(),
[
[
TestDiffOpType
.
Add
,
{
controllerId
:
'
ctrlId
'
,
parent
:
null
,
expand
:
TestItemExpandState
.
BusyExpanding
,
item
:
{
...
convert
.
TestItem
.
from
(
single
.
root
)
}
}
{
controllerId
:
'
ctrlId
'
,
parent
:
null
,
expand
:
TestItemExpandState
.
BusyExpanding
,
item
:
{
...
convert
.
TestItem
.
from
(
single
.
root
,
'
ctrlId
'
)
}
}
],
[
TestDiffOpType
.
Add
,
{
controllerId
:
'
ctrlId
'
,
parent
:
single
.
root
.
id
,
expand
:
TestItemExpandState
.
Expandable
,
item
:
{
...
convert
.
TestItem
.
from
(
single
.
tree
.
get
(
'
id-a
'
)
!
.
actual
)
}
}
{
controllerId
:
'
ctrlId
'
,
parent
:
single
.
root
.
id
,
expand
:
TestItemExpandState
.
Expandable
,
item
:
{
...
convert
.
TestItem
.
from
(
a
,
'
ctrlId
'
)
}
}
],
[
TestDiffOpType
.
Add
,
{
controllerId
:
'
ctrlId
'
,
parent
:
single
.
root
.
id
,
expand
:
TestItemExpandState
.
NotExpandable
,
item
:
convert
.
TestItem
.
from
(
single
.
tree
.
get
(
'
id-b
'
)
!
.
actual
)
}
{
controllerId
:
'
ctrlId
'
,
parent
:
single
.
root
.
id
,
expand
:
TestItemExpandState
.
NotExpandable
,
item
:
convert
.
TestItem
.
from
(
b
,
'
ctrlId
'
)
}
],
[
TestDiffOpType
.
Update
,
...
...
@@ -92,19 +95,19 @@ suite('ExtHost Testing', () => {
],
[
TestDiffOpType
.
Update
,
{
extId
:
'
id-a
'
,
expand
:
TestItemExpandState
.
BusyExpanding
}
{
extId
:
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
,
expand
:
TestItemExpandState
.
BusyExpanding
}
],
[
TestDiffOpType
.
Add
,
{
controllerId
:
'
ctrlId
'
,
parent
:
'
id-a
'
,
expand
:
TestItemExpandState
.
NotExpandable
,
item
:
convert
.
TestItem
.
from
(
single
.
tree
.
get
(
'
id-aa
'
)
!
.
actual
)
}
{
controllerId
:
'
ctrlId
'
,
parent
:
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
(),
expand
:
TestItemExpandState
.
NotExpandable
,
item
:
convert
.
TestItem
.
from
(
a
.
children
.
get
(
'
id-aa
'
)
!
,
'
ctrlId
'
)
}
],
[
TestDiffOpType
.
Add
,
{
controllerId
:
'
ctrlId
'
,
parent
:
'
id-a
'
,
expand
:
TestItemExpandState
.
NotExpandable
,
item
:
convert
.
TestItem
.
from
(
single
.
tree
.
get
(
'
id-ab
'
)
!
.
actual
)
}
{
controllerId
:
'
ctrlId
'
,
parent
:
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
(),
expand
:
TestItemExpandState
.
NotExpandable
,
item
:
convert
.
TestItem
.
from
(
a
.
children
.
get
(
'
id-ab
'
)
!
,
'
ctrlId
'
)
}
],
[
TestDiffOpType
.
Update
,
{
extId
:
'
id-a
'
,
expand
:
TestItemExpandState
.
Expanded
}
{
extId
:
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
,
expand
:
TestItemExpandState
.
Expanded
}
],
]);
});
...
...
@@ -132,7 +135,7 @@ suite('ExtHost Testing', () => {
assert
.
deepStrictEqual
(
single
.
collectDiff
(),
[
[
TestDiffOpType
.
Update
,
{
extId
:
'
id-a
'
,
item
:
{
description
:
'
Hello world
'
}
}],
{
extId
:
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
,
item
:
{
description
:
'
Hello world
'
}
}],
]);
});
...
...
@@ -142,9 +145,12 @@ suite('ExtHost Testing', () => {
single
.
root
.
children
.
delete
(
'
id-a
'
);
assert
.
deepStrictEqual
(
single
.
collectDiff
(),
[
[
TestDiffOpType
.
Remove
,
'
id-a
'
],
[
TestDiffOpType
.
Remove
,
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
],
]);
assert
.
deepStrictEqual
([...
single
.
tree
].
map
(
n
=>
n
.
actual
.
id
).
sort
(),
[
single
.
root
.
id
,
'
id-b
'
]);
assert
.
deepStrictEqual
(
[...
single
.
tree
.
keys
()].
sort
(),
[
single
.
root
.
id
,
new
TestId
([
'
ctrlId
'
,
'
id-b
'
]).
toString
()],
);
assert
.
strictEqual
(
single
.
tree
.
size
,
2
);
});
...
...
@@ -157,13 +163,13 @@ suite('ExtHost Testing', () => {
assert
.
deepStrictEqual
(
single
.
collectDiff
(),
[
[
TestDiffOpType
.
Add
,
{
controllerId
:
'
ctrlId
'
,
parent
:
'
id-a
'
,
parent
:
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
,
expand
:
TestItemExpandState
.
NotExpandable
,
item
:
convert
.
TestItem
.
from
(
child
),
item
:
convert
.
TestItem
.
from
(
child
,
'
ctrlId
'
),
}],
]);
assert
.
deepStrictEqual
(
[...
single
.
tree
].
map
(
n
=>
n
.
actual
.
id
).
sort
(),
[...
single
.
tree
.
values
()
].
map
(
n
=>
n
.
actual
.
id
).
sort
(),
[
single
.
root
.
id
,
'
id-a
'
,
'
id-aa
'
,
'
id-ab
'
,
'
id-ac
'
,
'
id-b
'
],
);
assert
.
strictEqual
(
single
.
tree
.
size
,
6
);
...
...
@@ -184,7 +190,7 @@ suite('ExtHost Testing', () => {
assert
.
deepStrictEqual
(
single
.
collectDiff
(),
[
[
TestDiffOpType
.
Update
,
{
extId
:
'
id-a
'
,
expand
:
TestItemExpandState
.
Expanded
,
item
:
{
label
:
'
Hello world
'
}
},
{
extId
:
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
,
expand
:
TestItemExpandState
.
Expanded
,
item
:
{
label
:
'
Hello world
'
}
},
],
]);
...
...
@@ -192,7 +198,7 @@ suite('ExtHost Testing', () => {
assert
.
deepStrictEqual
(
single
.
collectDiff
(),
[
[
TestDiffOpType
.
Update
,
{
extId
:
'
id-a
'
,
item
:
{
label
:
'
still connected
'
}
}
{
extId
:
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
,
item
:
{
label
:
'
still connected
'
}
}
],
]);
...
...
@@ -215,11 +221,11 @@ suite('ExtHost Testing', () => {
assert
.
deepStrictEqual
(
single
.
collectDiff
(),
[
[
TestDiffOpType
.
Update
,
{
extId
:
'
id-a
'
,
expand
:
TestItemExpandState
.
Expanded
},
{
extId
:
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
()
,
expand
:
TestItemExpandState
.
Expanded
},
],
[
TestDiffOpType
.
Update
,
{
extId
:
'
id-ab
'
,
item
:
{
label
:
'
Hello world
'
}
},
{
extId
:
TestId
.
fromExtHostTestItem
(
oldAB
,
'
ctrlId
'
).
toString
()
,
item
:
{
label
:
'
Hello world
'
}
},
],
]);
...
...
@@ -229,11 +235,11 @@ suite('ExtHost Testing', () => {
assert
.
deepStrictEqual
(
single
.
collectDiff
(),
[
[
TestDiffOpType
.
Update
,
{
extId
:
'
id-aa
'
,
item
:
{
label
:
'
still connected1
'
}
}
{
extId
:
new
TestId
([
'
ctrlId
'
,
'
id-a
'
,
'
id-aa
'
]).
toString
()
,
item
:
{
label
:
'
still connected1
'
}
}
],
[
TestDiffOpType
.
Update
,
{
extId
:
'
id-ab
'
,
item
:
{
label
:
'
still connected2
'
}
}
{
extId
:
new
TestId
([
'
ctrlId
'
,
'
id-a
'
,
'
id-ab
'
]).
toString
()
,
item
:
{
label
:
'
still connected2
'
}
}
],
]);
...
...
@@ -250,11 +256,11 @@ suite('ExtHost Testing', () => {
assert
.
deepStrictEqual
(
single
.
collectDiff
(),
[
[
TestDiffOpType
.
Remove
,
'
id-b
'
,
new
TestId
([
'
ctrlId
'
,
'
id-b
'
]).
toString
()
,
],
[
TestDiffOpType
.
Add
,
{
controllerId
:
'
ctrlId
'
,
parent
:
'
id-a
'
,
expand
:
TestItemExpandState
.
NotExpandable
,
item
:
convert
.
TestItem
.
from
(
single
.
tree
.
get
(
'
id-b
'
)
!
.
actual
)
}
{
controllerId
:
'
ctrlId
'
,
parent
:
new
TestId
([
'
ctrlId
'
,
'
id-a
'
]).
toString
(),
expand
:
TestItemExpandState
.
NotExpandable
,
item
:
convert
.
TestItem
.
from
(
b
,
'
ctrlId
'
)
}
],
]);
...
...
@@ -262,7 +268,7 @@ suite('ExtHost Testing', () => {
assert
.
deepStrictEqual
(
single
.
collectDiff
(),
[
[
TestDiffOpType
.
Update
,
{
extId
:
'
id-b
'
,
item
:
{
label
:
'
still connected
'
}
}
{
extId
:
new
TestId
([
'
ctrlId
'
,
'
id-a
'
,
'
id-b
'
]).
toString
()
,
item
:
{
label
:
'
still connected
'
}
}
],
]);
...
...
@@ -469,7 +475,7 @@ suite('ExtHost Testing', () => {
assert
.
strictEqual
(
tracker
.
isRunning
,
true
);
assert
.
deepStrictEqual
(
proxy
.
$startedExtensionTestRun
.
args
,
[
[{
config
:
{
group
:
2
,
id
:
42
},
profile
:
{
group
:
2
,
id
:
42
},
controllerId
:
'
ctrl
'
,
id
:
tracker
.
id
,
include
:
[
single
.
root
.
id
],
...
...
@@ -504,9 +510,9 @@ suite('ExtHost Testing', () => {
'
ctrl
'
,
tracker
.
id
,
[
convert
.
TestItem
.
from
(
single
.
root
),
convert
.
TestItem
.
from
(
single
.
root
.
children
.
get
(
'
id-a
'
)
!
),
convert
.
TestItem
.
from
(
single
.
root
.
children
.
get
(
'
id-a
'
)
!
.
children
.
get
(
'
id-aa
'
)
!
),
convert
.
TestItem
.
from
(
single
.
root
,
'
ctrlId
'
),
convert
.
TestItem
.
from
(
single
.
root
.
children
.
get
(
'
id-a
'
)
!
,
'
ctrlId
'
),
convert
.
TestItem
.
from
(
single
.
root
.
children
.
get
(
'
id-a
'
)
!
.
children
.
get
(
'
id-aa
'
)
!
,
'
ctrlId
'
),
]
]);
assert
.
deepStrictEqual
(
proxy
.
$addTestsToRun
.
args
,
expectedArgs
);
...
...
@@ -517,8 +523,8 @@ suite('ExtHost Testing', () => {
'
ctrl
'
,
tracker
.
id
,
[
convert
.
TestItem
.
from
(
single
.
root
.
children
.
get
(
'
id-a
'
)
!
),
convert
.
TestItem
.
from
(
single
.
root
.
children
.
get
(
'
id-a
'
)
!
.
children
.
get
(
'
id-ab
'
)
!
),
convert
.
TestItem
.
from
(
single
.
root
.
children
.
get
(
'
id-a
'
)
!
,
'
ctrlId
'
),
convert
.
TestItem
.
from
(
single
.
root
.
children
.
get
(
'
id-a
'
)
!
.
children
.
get
(
'
id-ab
'
)
!
,
'
ctrlId
'
),
],
]);
assert
.
deepStrictEqual
(
proxy
.
$addTestsToRun
.
args
,
expectedArgs
);
...
...
@@ -543,13 +549,12 @@ suite('ExtHost Testing', () => {
test
(
'
excludes tests outside tree or explicitly excluded
'
,
()
=>
{
single
.
expand
(
single
.
root
.
id
,
Infinity
);
const
task
=
c
.
createTestRun
(
'
ctrl
'
,
single
,
{
const
task
=
c
.
createTestRun
(
'
ctrl
Id
'
,
single
,
{
profile
:
configuration
,
include
:
[
single
.
root
.
children
.
get
(
'
id-a
'
)
!
],
exclude
:
[
single
.
root
.
children
.
get
(
'
id-a
'
)
!
.
children
.
get
(
'
id-aa
'
)
!
],
},
'
hello world
'
,
false
);
task
.
setState
(
single
.
root
.
children
.
get
(
'
b
'
)
!
,
TestResultState
.
Passed
);
task
.
setState
(
single
.
root
.
children
.
get
(
'
id-a
'
)
!
.
children
.
get
(
'
id-aa
'
)
!
,
TestResultState
.
Passed
);
task
.
setState
(
single
.
root
.
children
.
get
(
'
id-a
'
)
!
.
children
.
get
(
'
id-ab
'
)
!
,
TestResultState
.
Passed
);
...
...
@@ -558,7 +563,7 @@ suite('ExtHost Testing', () => {
assert
.
deepStrictEqual
(
proxy
.
$updateTestStateInRun
.
args
,
[[
args
[
0
],
args
[
1
],
'
id-ab
'
,
new
TestId
([
'
ctrlId
'
,
'
id-a
'
,
'
id-ab
'
]).
toString
()
,
TestResultState
.
Passed
,
undefined
,
]]);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录