@@ -3,15 +3,23 @@ import * as vscode from 'vscode';
33import { Tests , TestsToRun , TestFolder , TestFile , TestFunction , TestSuite , FlattenedTestFunction , TestStatus } from '../common/contracts' ;
44import { getDiscoveredTests } from '../common/testUtils' ;
55import * as constants from '../../common/constants' ;
6+ import * as path from 'path' ;
67
78export class TestDisplay {
89 constructor ( ) {
910 }
10- public displayTestUI ( ) {
11+ public displayStopTestUI ( message : string ) {
12+ window . showQuickPick ( [ message ] ) . then ( item => {
13+ if ( item === message ) {
14+ vscode . commands . executeCommand ( constants . Commands . Tests_Stop ) ;
15+ }
16+ } )
17+ }
18+ public displayTestUI ( rootDirectory : string ) {
1119 const tests = getDiscoveredTests ( ) ;
12- window . showQuickPick ( buildItems ( tests ) , { matchOnDescription : true , matchOnDetail : true } ) . then ( onItemSelected ) ;
20+ window . showQuickPick ( buildItems ( rootDirectory , tests ) , { matchOnDescription : true , matchOnDetail : true } ) . then ( onItemSelected ) ;
1321 }
14- public displayFunctionTestPickerUI ( fileName : string , testFunctions : TestFunction [ ] ) {
22+ public displayFunctionTestPickerUI ( rootDirectory : string , fileName : string , testFunctions : TestFunction [ ] ) {
1523 const tests = getDiscoveredTests ( ) ;
1624 if ( ! tests ) {
1725 return ;
@@ -25,7 +33,7 @@ export class TestDisplay {
2533 testFunctions . some ( testFunc => testFunc . nameToRun === fn . testFunction . nameToRun ) ;
2634 } ) ;
2735
28- window . showQuickPick ( buildItemsForFunctions ( flattenedFunctions ) , { matchOnDescription : true , matchOnDetail : true } ) . then ( onItemSelected ) ;
36+ window . showQuickPick ( buildItemsForFunctions ( rootDirectory , flattenedFunctions ) , { matchOnDescription : true , matchOnDetail : true } ) . then ( onItemSelected ) ;
2937 }
3038}
3139
@@ -37,7 +45,8 @@ enum Type {
3745 RunFile = 4 ,
3846 RunClass = 5 ,
3947 RunMethod = 6 ,
40- ViewTestOutput = 7
48+ ViewTestOutput = 7 ,
49+ Null = 8
4150}
4251const statusIconMapping = new Map < TestStatus , string > ( ) ;
4352statusIconMapping . set ( TestStatus . Pass , constants . Octicons . Test_Pass ) ;
@@ -69,14 +78,20 @@ function getSummary(tests?: Tests) {
6978 }
7079 return statusText . join ( ', ' ) . trim ( ) ;
7180}
72- function buildItems ( tests ?: Tests ) : TestItem [ ] {
81+ function buildItems ( rootDirectory : string , tests ?: Tests ) : TestItem [ ] {
7382 const items : TestItem [ ] = [ ] ;
7483 items . push ( { description : '' , label : 'Run All Tests' , type : Type . RunAll } ) ;
7584 items . push ( { description : '' , label : 'Rediscover Tests' , type : Type . ReDiscover } ) ;
76- const summary = getSummary ( tests ) ;
85+
86+ let summary = getSummary ( tests ) ;
87+ let separatorAdded = false ; ;
7788
7889 // Add an empty space because we'd like a separtor between actions and tests
79- items . push ( { description : '' , label : 'View Test Output' , type : Type . ViewTestOutput , detail : summary . length === 0 && tests ? ' ' : summary } ) ;
90+ if ( summary . length === 0 && tests && tests . summary . failures === 0 ) {
91+ separatorAdded = true ;
92+ summary = ' ' ;
93+ }
94+ items . push ( { description : '' , label : 'View Test Output' , type : Type . ViewTestOutput , detail : summary } ) ;
8095
8196 if ( ! tests ) {
8297 return items ;
@@ -86,28 +101,49 @@ function buildItems(tests?: Tests): TestItem[] {
86101 items . push ( { description : '' , label : 'Run Failed Tests' , type : Type . RunFailed , detail : `${ constants . Octicons . Test_Fail } ${ tests . summary . failures } Failed` } ) ;
87102 }
88103
89- let functionItems = buildItemsForFunctions ( tests . testFunctions ) ;
104+ if ( tests . testFunctions . length > 0 && ! separatorAdded ) {
105+ items . push ( { description : '' , label : '' , type : Type . Null , detail : `` } ) ;
106+ }
107+
108+ let functionItems = buildItemsForFunctions ( rootDirectory , tests . testFunctions , true , true ) ;
90109 items . push ( ...functionItems ) ;
91110 return items ;
92111}
93112
94- function buildItemsForFunctions ( tests : FlattenedTestFunction [ ] ) : TestItem [ ] {
113+ const statusSortPrefix = { } ;
114+ statusSortPrefix [ TestStatus . Error ] = '1' ;
115+ statusSortPrefix [ TestStatus . Fail ] = '2' ;
116+ statusSortPrefix [ TestStatus . Skipped ] = '3' ;
117+ statusSortPrefix [ TestStatus . Pass ] = '4' ;
118+
119+ function buildItemsForFunctions ( rootDirectory : string , tests : FlattenedTestFunction [ ] , sortBasedOnResults : boolean = false , displayStatusIcons : boolean = false ) : TestItem [ ] {
95120 let functionItems : TestItem [ ] = [ ] ;
96121 tests . forEach ( fn => {
97122 const classPrefix = fn . parentTestSuite ? fn . parentTestSuite . name + '.' : '' ;
123+ let icon = '' ;
124+ if ( displayStatusIcons && statusIconMapping . has ( fn . testFunction . status ) ) {
125+ icon = `${ statusIconMapping . get ( fn . testFunction . status ) } ` ;
126+ }
127+
98128 functionItems . push ( {
99129 description : '' ,
100- detail : fn . parentTestFile . name ,
101- label : fn . testFunction . name ,
130+ detail : path . relative ( rootDirectory , fn . parentTestFile . fullPath ) ,
131+ label : icon + fn . testFunction . name ,
102132 type : Type . RunMethod ,
103133 fn : fn
104134 } ) ;
105135 } ) ;
106136 functionItems . sort ( ( a , b ) => {
107- if ( a . detail + a . label < b . detail + b . label ) {
137+ let sortAPrefix = '5-' ;
138+ let sortBPrefix = '5-' ;
139+ if ( sortBasedOnResults ) {
140+ sortAPrefix = statusSortPrefix [ a . fn . testFunction . status ] ? statusSortPrefix [ a . fn . testFunction . status ] : sortAPrefix ;
141+ sortBPrefix = statusSortPrefix [ b . fn . testFunction . status ] ? statusSortPrefix [ b . fn . testFunction . status ] : sortBPrefix ;
142+ }
143+ if ( sortAPrefix + a . detail + a . label < sortBPrefix + b . detail + b . label ) {
108144 return - 1 ;
109145 }
110- if ( a . detail + a . label > b . detail + b . label ) {
146+ if ( sortAPrefix + a . detail + a . label > sortBPrefix + b . detail + b . label ) {
111147 return 1 ;
112148 }
113149 return 0 ;
@@ -121,6 +157,9 @@ function onItemSelected(selection: TestItem) {
121157 let cmd = '' ;
122158 let args = [ ] ;
123159 switch ( selection . type ) {
160+ case Type . Null : {
161+ return ;
162+ }
124163 case Type . RunAll : {
125164 cmd = constants . Commands . Tests_Run ;
126165 break ;
0 commit comments