Skip to content

Commit 2a41e0b

Browse files
authored
Full reload before running (#27)
* Reload tests before running * On test loading error, create error under test suite to show failed executable * Update tests
1 parent 96c64f0 commit 2a41e0b

9 files changed

Lines changed: 128 additions & 119 deletions

src/Domain/CppUTest.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { TestInfo } from "vscode-test-adapter-api";
2-
import uuid from "./uuid";
32

43
export class CppUTest implements TestInfo {
54
type: "test" = "test";
@@ -12,11 +11,21 @@ export class CppUTest implements TestInfo {
1211
line?: number | undefined;
1312
skipped?: boolean | undefined;
1413

15-
constructor(testString: string, group: string, file?: string | undefined, line?: number | undefined) {
16-
this.id = uuid();
14+
constructor(testString: string, group: string, id: string, file?: string | undefined, line?: number | undefined) {
15+
this.id = id;
1716
this.file = file;
1817
this.line = line;
1918
this.label = testString;
2019
this.group = group;
2120
}
21+
22+
public AddDebugInformation(testDebugString: string): void {
23+
const symbolInformationLines = testDebugString.split("\n");
24+
const filePath = symbolInformationLines.filter(si => si.startsWith("/"))[0];
25+
const debugSymbols: string[] = filePath.split(":");
26+
const file = debugSymbols[0];
27+
const line = parseInt(debugSymbols[1], 10);
28+
this.file = file;
29+
this.line = line;
30+
}
2231
}

src/Domain/CppUTestContainer.ts

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { VscodeAdapter } from "../Infrastructure/VscodeAdapter";
1111

1212
export default class CppUTestContainer {
1313
private runners: ExecutableRunner[];
14-
private suites: Map<string, CppUTestGroup>;
14+
private suites: Map<string, CppUTestSuite>;
1515
private settingsProvider: SettingsProvider;
1616
private vscodeAdapter: VscodeAdapter;
1717
private resultParser: ResultParser;
@@ -30,25 +30,24 @@ export default class CppUTestContainer {
3030
this.runners = runners;
3131
this.vscodeAdapter = vscodeAdapter;
3232
this.resultParser = resultParser;
33-
this.suites = new Map<string, CppUTestGroup>();
33+
this.suites = new Map<string, CppUTestSuite>();
3434
}
3535

36-
public LoadTests(): Promise<CppUTestGroup[]> {
36+
public LoadTests(): Promise<CppUTestSuite[]> {
3737
return Promise.all(this.runners
3838
.map(runner => runner.GetTestList()
39-
.then(testString => this.EmbedInRunnerGroup(runner, testString))
40-
.catch(error => new CppUTestGroup("ERROR ON LOADING TESTS"))
39+
.then(testString => this.UpdateTestSuite(runner, testString))
40+
.catch(error => this.CreateTestSuiteError(runner.Name))
4141
));
4242
}
4343

4444
public ClearTests() {
45-
this.suites = new Map<string, CppUTestGroup>();
45+
this.suites = new Map<string, CppUTestSuite>();
4646
}
4747

4848
public async RunAllTests(): Promise<TestResult[]> {
49-
const testList = await this.LoadTests();
5049
const testResults: TestResult[] = new Array<TestResult>();
51-
for (const executableGroup of testList) {
50+
for (const executableGroup of this.suites.values()) {
5251
for (const testGroup of executableGroup.children) {
5352
for (const test of (testGroup as CppUTestGroup).children) {
5453
const runner = this.runners.filter(r => r.Name === executableGroup.label)[0];
@@ -64,10 +63,9 @@ export default class CppUTestContainer {
6463
}
6564

6665
public async RunTest(...testId: string[]): Promise<TestResult[]> {
67-
const testList = await this.LoadTests();
6866
const testResults: TestResult[] = new Array<TestResult>();
6967
const testsToRun: CppUTest[] = new Array<CppUTest>();
70-
for (const executableGroup of testList) {
68+
for (const executableGroup of this.suites.values()) {
7169
testsToRun.splice(0, testsToRun.length);
7270
if (testId.includes(executableGroup.id)) {
7371
testsToRun.push(...executableGroup.Tests);
@@ -106,8 +104,7 @@ export default class CppUTestContainer {
106104
if (!workspaceFolders) {
107105
throw new Error("No workspaceFolders found. Not able to debug!");
108106
}
109-
const testList = await this.LoadTests();
110-
for (const executableGroup of testList) {
107+
for (const executableGroup of this.suites.values()) {
111108
const testOrGroup = this.GetGroupOrTest(testId, executableGroup);
112109
const runner = this.runners.filter(r => r.Name === executableGroup.label)[0];
113110
if (testOrGroup && runner) {
@@ -147,21 +144,33 @@ export default class CppUTestContainer {
147144
return Array<CppUTest>().concat(...tests);
148145
}
149146

150-
private async EmbedInRunnerGroup(runner: ExecutableRunner, testString: string): Promise<CppUTestGroup> {
151-
if (this.suites.has(runner.Name)) {
152-
return (this.suites.get(runner.Name) as CppUTestGroup);
153-
}
154-
const testFactory = new CppUTestSuite(runner.Name);
155-
const testGroup = testFactory.CreateTestGroupsFromTestListString(testString);
156-
for(const test of testGroup.Tests) {
147+
private async UpdateTestSuite(runner: ExecutableRunner, testString: string): Promise<CppUTestSuite> {
148+
const testSuite = this.GetTestSuite(runner.Name);
149+
testSuite.UpdateFromTestListString(testString);
150+
for(const test of testSuite.Tests) {
157151
try {
158152
const debugString = await runner.GetDebugSymbols(test.group, test.label);
159-
testFactory.AddDebugInformationToTest(test, debugString);
153+
test.AddDebugInformation(debugString);
160154
} catch (error) {
161155
console.error(error);
162156
}
163157
}
164-
this.suites.set(runner.Name, testGroup);
165-
return testGroup;
158+
return testSuite;
159+
}
160+
161+
private async CreateTestSuiteError(runnerName: string): Promise<CppUTestSuite> {
162+
const testSuite = this.GetTestSuite(runnerName);
163+
testSuite.AddTestGroup("ERROR LOADING TESTS");
164+
return testSuite;
165+
}
166+
167+
private GetTestSuite(runnerName: string): CppUTestSuite {
168+
if (this.suites.has(runnerName)) {
169+
return (this.suites.get(runnerName) as CppUTestSuite);
170+
} else {
171+
const testSuite = new CppUTestSuite(runnerName);
172+
this.suites.set(runnerName, testSuite);
173+
return testSuite;
174+
}
166175
}
167176
}

src/Domain/CppUTestGroup.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import { TestSuiteInfo, TestInfo } from 'vscode-test-adapter-api';
1+
import { TestSuiteInfo } from 'vscode-test-adapter-api';
22
import { CppUTest } from "./CppUTest";
3-
import uuid from './uuid';
4-
53

64
export class CppUTestGroup implements TestSuiteInfo {
75
type: "suite";
@@ -11,22 +9,26 @@ export class CppUTestGroup implements TestSuiteInfo {
119
tooltip?: string | undefined;
1210
file?: string | undefined;
1311
line?: number | undefined;
14-
children: (TestSuiteInfo | TestInfo)[];
15-
executable: string | undefined;
12+
children: (CppUTest | CppUTestGroup)[];
1613

17-
constructor(inputString: string, executable: string | undefined = undefined) {
14+
constructor(label: string, id: string) {
1815
this.type = "suite";
19-
this.id = uuid();
20-
this.label = inputString;
16+
this.id = id;
17+
this.label = label;
2118
this.children = new Array<CppUTest | CppUTestGroup>();
22-
this.executable = executable;
2319
}
2420

2521
AddTest(testName: string, file?: string, line?: number) {
26-
const test: CppUTest = new CppUTest(testName, this.label, file, line);
22+
const test: CppUTest = new CppUTest(testName, this.label, this.id + "/" + testName, file, line);
2723
this.children.unshift(test);
2824
}
2925

26+
AddTestGroup(groupName: string): CppUTestGroup {
27+
const testGroup = new CppUTestGroup(groupName, this.id + "/" + groupName);
28+
this.children.push(testGroup);
29+
return testGroup;
30+
}
31+
3032
FindTest(id: string): CppUTest[] {
3133
if(this.id === id) {
3234
return this.Tests;

src/Domain/CppUTestSuite.ts

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,24 @@
1-
import { TestSuiteInfo } from 'vscode-test-adapter-api';
2-
import { CppUTest } from './CppUTest';
31
import { CppUTestGroup } from './CppUTestGroup';
42

5-
export default class CppUTestSuite {
6-
private readonly groupLabel: string;
3+
export default class CppUTestSuite extends CppUTestGroup {
74

8-
constructor(groupLabel: string) {
9-
this.groupLabel = groupLabel;
5+
constructor(label: string) {
6+
super(label, label);
107
}
118

12-
public CreateTestGroupsFromTestListString(testListString: string) {
13-
const groupStrings: string[] = testListString.split(" ");
14-
const subSuite: CppUTestGroup = new CppUTestGroup(this.groupLabel);
15-
groupStrings
9+
public UpdateFromTestListString(testListString: string): void {
10+
const groupAndGroupStrings: string[] = testListString.split(" ");
11+
this.children.splice(0, this.children.length);
12+
groupAndGroupStrings
1613
.map(gs => gs.split("."))
17-
.forEach(split => this.CreateGroupAndTests(subSuite, split[0], split[1]));
18-
19-
return subSuite;
14+
.map(split => this.UpdateGroupAndTest(split[0], split[1]));
2015
}
2116

22-
private CreateGroupAndTests(suite: CppUTestGroup, groupName: string, testName: string): CppUTestGroup {
23-
let testGroup = suite.children.find(c => c.label === groupName);
17+
private UpdateGroupAndTest(groupName: string, testName: string): void {
18+
let testGroup = this.children.find(c => c.label === groupName) as CppUTestGroup;
2419
if (!testGroup) {
25-
testGroup = new CppUTestGroup(groupName);
26-
suite.children.push(testGroup);
20+
testGroup = this.AddTestGroup(groupName);
2721
}
28-
const test = new CppUTest(testName, groupName);
29-
(testGroup as TestSuiteInfo).children.unshift(test);
30-
return (testGroup as CppUTestGroup);
31-
}
32-
33-
public AddDebugInformationToTest(test: CppUTest, testDebugString: string): void {
34-
const symbolInformationLines = testDebugString.split("\n");
35-
const filePath = symbolInformationLines.filter(si => si.startsWith("/"))[0];
36-
const debugSymbols: string[] = filePath.split(":");
37-
const file = debugSymbols[0];
38-
const line = parseInt(debugSymbols[1], 10);
39-
test.file = file;
40-
test.line = line;
22+
testGroup.AddTest(testName);
4123
}
4224
}
43-
44-

src/adapter.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export class CppUTestAdapter implements TestAdapter {
4747
this.root.OnTestFinish = this.handleTestFinished.bind(this);
4848
this.root.OnTestStart = this.handleTestStarted.bind(this);
4949

50-
this.mainSuite = new CppUTestGroup("Main Suite");
50+
this.mainSuite = new CppUTestGroup("Main Suite", "");
5151
// runners.forEach(runner => fs.watchFile(<fs.PathLike>runner, (cur: fs.Stats, prev: fs.Stats) => {
5252
// if (cur.mtimeMs !== prev.mtimeMs) {
5353
// this.log.info("Executable changed, updating test cases");
@@ -73,6 +73,7 @@ export class CppUTestAdapter implements TestAdapter {
7373
public async run(tests: string[]): Promise<void> {
7474
this.testStatesEmitter.fire(<TestRunStartedEvent>{ type: 'started', tests });
7575
this.log.info('Running tests');
76+
await this.updateTests();
7677
if (tests.length == 1 && tests[0] == this.mainSuite.id) {
7778
await this.root.RunAllTests();
7879
} else {
@@ -83,6 +84,7 @@ export class CppUTestAdapter implements TestAdapter {
8384
}
8485

8586
public async debug(tests: string[]): Promise<void> {
87+
await this.updateTests();
8688
return this.root.DebugTest(...tests);
8789
}
8890

@@ -99,6 +101,13 @@ export class CppUTestAdapter implements TestAdapter {
99101
this.disposables = [];
100102
}
101103

104+
private async updateTests(): Promise<void> {
105+
this.root.ClearTests();
106+
const loadedTests = await this.root.LoadTests();
107+
this.mainSuite.children = loadedTests;
108+
this.testsEmitter.fire(<TestLoadFinishedEvent>{ type: 'finished', suite: this.mainSuite });
109+
}
110+
102111
private handleTestStarted(test: CppUTest): void {
103112
const event = this.mapTestResultToTestEvent(test);
104113
this.testStatesEmitter.fire(event)

tests/CppUTest.spec.ts

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,55 @@
11
import { expect } from "chai";
22
import { CppUTest } from "../src/Domain/CppUTest";
33

4+
const symbolStrings = [
5+
{
6+
test: new CppUTest("test1", "group1", "id1"),
7+
value:
8+
"_ZN31TEST_Group1_Test1_TestShellC4Ev():\n" +
9+
"/tmp/myPath/basicTests.cpp:56\n" +
10+
"randomly placed line that confuses the analyzer\n" +
11+
"TEST(Group1, Test1)\n" +
12+
"random information that is not correlated at all"
13+
},
14+
{
15+
test: new CppUTest("test2", "group1", "id2"),
16+
value:
17+
"_ZN31TEST_Group1_Test1_TestShellC4Ev():\n" +
18+
"randomly placed line that confuses the analyzer\n" +
19+
"/tmp/myPath/basicTests.cpp:56\n" +
20+
"TEST(Group1, Test1)\n" +
21+
"random information that is not correlated at all"
22+
},
23+
{
24+
test: new CppUTest("test3", "group1", "id3"),
25+
value:
26+
"/tmp/myPath/basicTests.cpp:56"
27+
}
28+
];
29+
430
describe("CppUTest should", () => {
531
it("be creatable with all information", () => {
6-
const test = new CppUTest("TestName", "GroupName", "file.cpp", 53);
32+
const test = new CppUTest("TestName", "GroupName", "TestName/GroupName", "file.cpp", 53);
733
expect(test.label).to.be.equal("TestName");
8-
expect(test.id).to.contain("-");
34+
expect(test.id).to.be.equal("TestName/GroupName");
935
expect(test.file).to.be.equal("file.cpp");
1036
expect(test.line).to.be.equal(53);
1137
})
1238

1339
it("be creatable with basic information", () => {
14-
const test = new CppUTest("TestName", "GroupName");
40+
const test = new CppUTest("TestName", "GroupName", "TestName/GroupName");
1541
expect(test.label).to.be.equal("TestName");
1642
expect(test.group).to.be.equal("GroupName");
17-
expect(test.id).to.contain("-");
43+
expect(test.id).to.contain("TestName/GroupName");
1844
expect(test.file).to.be.equal(undefined);
1945
expect(test.line).to.be.equal(undefined);
2046
})
47+
48+
symbolStrings.forEach(symbolString =>
49+
it(`create debug information from symbol definition string for ${symbolString.test.label}`, () => {
50+
symbolString.test.AddDebugInformation(symbolString.value);
51+
expect(symbolString.test.file).to.be.equal("/tmp/myPath/basicTests.cpp");
52+
expect(symbolString.test.line).to.be.equal(56);
53+
})
54+
)
2155
});

tests/CppUTestContainer.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ describe("CppUTestContainer should", () => {
5050
const testList1 = await container.LoadTests();
5151
container.ClearTests()
5252
const testList2 = await container.LoadTests();
53-
expect(JSON.stringify(testList1)).to.be.not.eq(JSON.stringify(testList2));
53+
expect(JSON.stringify(testList1)).to.be.eq(JSON.stringify(testList2));
5454
})
5555

5656
it("get the same id on consecutive loads", async () => {

tests/CppUTestGroup.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import { CppUTestGroup } from "../src/Domain/CppUTestGroup";
55
describe("CppUTestGroup should", () => {
66
let testGroup: CppUTestGroup;
77
beforeEach(() => {
8-
testGroup = new CppUTestGroup("TestName");
8+
testGroup = new CppUTestGroup("TestGroup", "TestGroupId");
99
})
1010

1111
it("be creatable with all information", () => {
12-
expect(testGroup.label).to.be.equal("TestName");
13-
expect(testGroup.id).to.contain("-");
12+
expect(testGroup.label).to.be.equal("TestGroup");
13+
expect(testGroup.id).to.be.equal("TestGroupId");
1414
})
1515
it("be able to add tests", () => {
1616
expect(testGroup.children.length).to.be.eq(0);
@@ -19,7 +19,7 @@ describe("CppUTestGroup should", () => {
1919
})
2020

2121
it("find test by id", () => {
22-
const test = new CppUTest("myTest", "myGroup");
22+
const test = new CppUTest("myTest", "myGroup", "myId");
2323
const id = test.id;
2424
testGroup.children.push(test);
2525
testGroup.AddTest("randomTest1");
@@ -45,8 +45,8 @@ describe("CppUTestGroup should", () => {
4545
})
4646

4747
it("find all tests in nested groups", () => {
48-
const subTestGroup1 = new CppUTestGroup("subTestGroup1");
49-
const subTestGroup2 = new CppUTestGroup("subTestGroup2");
48+
const subTestGroup1 = new CppUTestGroup("subTestGroup1", "subTestGroupId1");
49+
const subTestGroup2 = new CppUTestGroup("subTestGroup2", "subTestGroupId2");
5050
testGroup.children.push(subTestGroup1);
5151
testGroup.children.push(subTestGroup2);
5252
subTestGroup1.AddTest("test1");

0 commit comments

Comments
 (0)