Skip to content

Commit 8f7cb40

Browse files
author
Kartik Raj
authored
Generalize test results service (#4813)
* Generalize test results service * News entry * Fix gulp errors * Updated status icons * Added tests
1 parent e0e86a2 commit 8f7cb40

File tree

7 files changed

+254
-120
lines changed

7 files changed

+254
-120
lines changed

news/1 Enhancements/4796.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Generalize Test results service

resources/dark/status-unknown.svg

Lines changed: 1 addition & 1 deletion
Loading

resources/light/status-unknown.svg

Lines changed: 1 addition & 1 deletion
Loading
Lines changed: 46 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { inject, injectable, named } from 'inversify';
22
import { TestDataItem } from '../../types';
3-
import { visitParentsRecursive } from '../testVisitors/visitor';
4-
import { ITestResultsService, ITestVisitor, TestFile, TestFolder, Tests, TestStatus, TestSuite } from './../types';
3+
import { getChildren, getTestType } from '../testUtils';
4+
import { ITestResultsService, ITestVisitor, Tests, TestStatus, TestType } from './../types';
55

66
@injectable()
77
export class TestResultsService implements ITestResultsService {
@@ -13,134 +13,63 @@ export class TestResultsService implements ITestResultsService {
1313
tests.testFiles.forEach(testFile => this.resultResetVisitor.visitTestFile(testFile));
1414
}
1515
public updateResults(tests: Tests): void {
16-
tests.testFiles.forEach(test => this.updateTestFileResults(test));
17-
tests.rootTestFolders.forEach(folder => this.updateTestFolderResults(folder));
18-
// List items should be updated in order
19-
[TestStatus.Pass, TestStatus.Fail].forEach(item => this.updateParentStatus(tests, item));
20-
}
21-
private updateTestSuiteResults(test: TestSuite): void {
22-
this.updateTestSuiteAndFileResults(test);
23-
}
24-
private updateTestFileResults(test: TestFile): void {
25-
this.updateTestSuiteAndFileResults(test);
26-
}
27-
private updateParentStatus(tests: Tests, status: TestStatus): void {
28-
const visitor = (item: TestDataItem) => item.status = status;
29-
tests.testFiles.forEach(item => {
30-
if (typeof item.passed === 'boolean') {
31-
if (status === TestStatus.Pass ? item.passed : !item.passed) {
32-
visitParentsRecursive(tests, item, visitor);
33-
}
34-
}
35-
});
36-
tests.testSuites.forEach(item => {
37-
if (typeof item.testSuite.passed === 'boolean') {
38-
if (status === TestStatus.Pass ? item.testSuite.passed : !item.testSuite.passed) {
39-
visitParentsRecursive(tests, item.testSuite, visitor);
40-
}
41-
}
42-
});
43-
tests.testFunctions.forEach(item => {
44-
if (typeof item.testFunction.passed === 'boolean') {
45-
if (status === TestStatus.Pass ? item.testFunction.passed : !item.testFunction.passed) {
46-
visitParentsRecursive(tests, item.testFunction, visitor);
47-
}
48-
}
49-
});
50-
}
51-
private updateTestFolderResults(testFolder: TestFolder): void {
52-
let totalTime = 0;
53-
let allFilesPassed = true;
54-
let noFilesRan = true;
55-
testFolder.functionsPassed = testFolder.functionsFailed = testFolder.functionsDidNotRun = 0;
16+
// Update Test tree bottom to top
17+
const testQueue: TestDataItem[] = [];
18+
const testStack: TestDataItem[] = [];
19+
tests.rootTestFolders.forEach(folder => testQueue.push(folder));
5620

57-
testFolder.testFiles.forEach(fl => {
58-
totalTime += fl.time;
59-
if (typeof fl.passed === 'boolean') {
60-
noFilesRan = false;
61-
if (!fl.passed) {
62-
allFilesPassed = false;
63-
}
64-
}
65-
66-
testFolder.functionsFailed! += fl.functionsFailed!;
67-
testFolder.functionsPassed! += fl.functionsPassed!;
68-
testFolder.functionsDidNotRun! += fl.functionsDidNotRun!;
69-
});
70-
71-
let allFoldersPassed = true;
72-
let noFoldersRan = true;
73-
74-
testFolder.folders.forEach(folder => {
75-
totalTime += folder.time;
76-
this.updateTestFolderResults(folder);
77-
if (typeof folder.passed === 'boolean') {
78-
noFoldersRan = false;
79-
if (!folder.passed) {
80-
allFoldersPassed = false;
81-
}
82-
}
83-
84-
testFolder.functionsFailed! += folder.functionsFailed!;
85-
testFolder.functionsPassed! += folder.functionsPassed!;
86-
testFolder.functionsDidNotRun! += folder.functionsDidNotRun!;
87-
});
88-
89-
testFolder.time = totalTime;
90-
if (noFilesRan && noFoldersRan) {
91-
testFolder.passed = undefined;
92-
testFolder.status = TestStatus.Unknown;
93-
} else {
94-
testFolder.passed = allFilesPassed && allFoldersPassed;
95-
testFolder.status = testFolder.passed ? TestStatus.Pass : TestStatus.Fail;
21+
while (testQueue.length > 0) {
22+
const item = testQueue.shift();
23+
testStack.push(item);
24+
const children = getChildren(item);
25+
children.forEach(child => testQueue.push(child));
26+
}
27+
while (testStack.length > 0) {
28+
const item = testStack.pop();
29+
this.updateTestItem(item);
9630
}
9731
}
98-
private updateTestSuiteAndFileResults(test: TestSuite | TestFile): void {
99-
let totalTime = 0;
100-
let allFunctionsPassed = true;
101-
let noFunctionsRan = true;
102-
test.functionsPassed = test.functionsFailed = test.functionsDidNotRun = 0;
32+
private updateTestItem(test: TestDataItem): void {
33+
if (getTestType(test) === TestType.testFunction) {
34+
return;
35+
}
36+
let allChildrenPassed = true;
37+
let noChildrenRan = true;
38+
test.time = test.functionsPassed = test.functionsFailed = test.functionsDidNotRun = 0;
10339

104-
test.functions.forEach(fn => {
105-
totalTime += fn.time;
106-
if (typeof fn.passed === 'boolean') {
107-
noFunctionsRan = false;
108-
if (fn.passed) {
109-
test.functionsPassed! += 1;
40+
const children = getChildren(test);
41+
children.forEach(child => {
42+
test.time += child.time;
43+
if (getTestType(child) === TestType.testFunction) {
44+
if (typeof child.passed === 'boolean') {
45+
noChildrenRan = false;
46+
if (child.passed) {
47+
test.functionsPassed! += 1;
48+
} else {
49+
test.functionsFailed! += 1;
50+
allChildrenPassed = false;
51+
}
11052
} else {
111-
test.functionsFailed! += 1;
112-
allFunctionsPassed = false;
53+
test.functionsDidNotRun! += 1;
11354
}
11455
} else {
115-
test.functionsDidNotRun! += 1;
116-
}
117-
});
118-
119-
let allSuitesPassed = true;
120-
let noSuitesRan = true;
121-
122-
test.suites.forEach(suite => {
123-
this.updateTestSuiteResults(suite);
124-
totalTime += suite.time;
125-
if (typeof suite.passed === 'boolean') {
126-
noSuitesRan = false;
127-
if (!suite.passed) {
128-
allSuitesPassed = false;
56+
if (typeof child.passed === 'boolean') {
57+
noChildrenRan = false;
58+
if (!child.passed) {
59+
allChildrenPassed = false;
60+
}
12961
}
62+
test.functionsFailed! += child.functionsFailed!;
63+
test.functionsPassed! += child.functionsPassed!;
64+
test.functionsDidNotRun! += child.functionsDidNotRun!;
13065
}
131-
132-
test.functionsFailed! += suite.functionsFailed!;
133-
test.functionsPassed! += suite.functionsPassed!;
134-
test.functionsDidNotRun! += suite.functionsDidNotRun!;
13566
});
136-
137-
test.time = totalTime;
138-
if (noSuitesRan && noFunctionsRan) {
67+
if (noChildrenRan) {
13968
test.passed = undefined;
14069
test.status = TestStatus.Unknown;
14170
} else {
142-
test.passed = allFunctionsPassed && allSuitesPassed;
143-
test.status = test.passed ? TestStatus.Pass : TestStatus.Error;
71+
test.passed = allChildrenPassed;
72+
test.status = test.passed ? TestStatus.Pass : TestStatus.Fail;
14473
}
14574
}
14675
}

src/client/unittests/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ export class TestWorkspaceFolder {
164164
public functionsPassed?: number;
165165
public functionsFailed?: number;
166166
public functionsDidNotRun?: number;
167+
public passed?: boolean;
167168
constructor(public readonly workspaceFolder: WorkspaceFolder) { }
168169
public get resource(): Uri {
169170
return this.workspaceFolder.uri;

0 commit comments

Comments
 (0)