Skip to content

Commit 8beed50

Browse files
committed
Implement uncovered branch highlight
1 parent 922d6e2 commit 8beed50

File tree

8 files changed

+108
-9
lines changed

8 files changed

+108
-9
lines changed

assembly/diytest.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export function mycmp<T>(a: T, b: T): bool {
2+
if (a > b) {
3+
return true;
4+
} else {
5+
return false;
6+
}
7+
}
8+
9+
export function instancecmp<T>(a: T, b: T): bool {
10+
if (isInteger<T>()) {
11+
if (a > b) {
12+
return true;
13+
} else {
14+
return false;
15+
}
16+
} else if (isFloat<T>()) {
17+
if (a > b) {
18+
return true;
19+
} else {
20+
return false;
21+
}
22+
}
23+
return false;
24+
}

src/generator/html-generator/genCode.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,16 @@ function generateLineCoverage(codes: CodeCoverage[]): string {
2323
return str.join("\n");
2424
}
2525

26-
function generateSource(codes: CodeCoverage[]): string {
26+
function generateSource(codes: CodeCoverage[], result: FileCoverageResult): string {
2727
const str: string[] = [];
28-
for (const code of codes) {
29-
str.push(escape(code.source));
28+
for (const [index, code] of codes.entries()) {
29+
if (result.linesToHighlight.has(index + 1)) {
30+
// IMPORTANT! to add "nocode" here to preventing prettify from adding unwanted pln class
31+
str.push('<span class="missing-if-branch nocode" title="Branch not taken">!</span>' + escape(code.source));
32+
}
33+
else {
34+
str.push(escape(code.source));
35+
}
3036
}
3137
return str.join("\n");
3238
}
@@ -36,7 +42,7 @@ export function generateCodeHtml(relativePathofRoot: string, result: FileCoverag
3642

3743
const lineCoutHtml = generateLineCount(codes.length);
3844
const lineCov = generateLineCoverage(codes);
39-
const lineSource = generateSource(codes);
45+
const lineSource = generateSource(codes, result);
4046

4147
return `
4248
<!DOCTYPE html>

src/interface.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,13 @@ export class FileCoverageResult {
8787
functionCoverageRate: Rate = new Rate();
8888
lineCoverageRate: Rate = new Rate();
8989
sourceUsedCount: CodeCoverage[] = [];
90+
linesToHighlight: Set<number> = new Set();
9091
}
9192

9293
export class FunctionCoverageResult {
9394
constructor(public functionName: string) {}
9495
branchCoverageRate: Rate = new Rate();
96+
linesToHighlight: Set<number> = new Set();
9597
lineRange: [number, number] = [Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER];
9698
/**
9799
* first means lineIndex;
@@ -111,6 +113,7 @@ export class FunctionCoverageResult {
111113
];
112114
result.branchCoverageRate = Rate.summarize(infos.map((info) => info.branchCoverageRate));
113115
for (const info of infos) {
116+
info.linesToHighlight.forEach(line => result.linesToHighlight.add(line));
114117
for (const [lineIndex, count] of info.sourceUsedCount.entries()) {
115118
const srcLineUsedCount = result.sourceUsedCount.get(lineIndex);
116119
result.sourceUsedCount.set(lineIndex, srcLineUsedCount === undefined ? count : srcLineUsedCount + count);

src/parser/singleFileAnalysis.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,23 @@ export class SingleFileCoverageAnalysis {
1919
for (let index = startLine - 1; index < endLine; index++) {
2020
const codeCoverage = this.result.sourceUsedCount[index];
2121
if (codeCoverage === undefined) {
22-
throw new Error(`unknowm error: There is no ${index} Line in file ${this.result.filename}`);
22+
throw new Error(`unknown error: There is no ${index} Line in file ${this.result.filename}`);
2323
}
2424
codeCoverage.usedCount = 0;
2525
}
2626
}
2727
}
2828

2929
merge(results: FunctionCoverageResult[]) {
30+
// SingleFileCoverageAnalysis contains FileCoverageResult
3031
if (results.length === 0) return;
3132
for (const functionCovResult of results) {
33+
functionCovResult.linesToHighlight.forEach(line => this.result.linesToHighlight.add(line));
3234
for (const [lineIndex, count] of functionCovResult.sourceUsedCount.entries()) {
3335
const srcLineUsedCount = this.result.sourceUsedCount[lineIndex - 1];
3436
if (srcLineUsedCount === undefined) {
3537
throw new Error(
36-
`unknowm error: There is not Line ${lineIndex} in ${JSON.stringify(this.result.sourceUsedCount)}`
38+
`unknown error: There is not Line ${lineIndex} in ${JSON.stringify(this.result.sourceUsedCount)}`
3739
);
3840
}
3941
if (srcLineUsedCount.usedCount === CodeCoverage.default) {

src/parser/singleFunctionAnalysis.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ type BranchGraph = Map<number, Map<number, boolean>>;
66
export class SingleFunctionCoverageAnalysis {
77
result: FunctionCoverageResult;
88
branchGraph: BranchGraph = new Map();
9+
notFullyCoveredBasicBlock: Set<number> = new Set();
910
constructor(
1011
public covInfo: CovInfo,
1112
name: string
@@ -72,12 +73,28 @@ export class SingleFunctionCoverageAnalysis {
7273
toNodes.set(second, true);
7374
}
7475
}
76+
for (const toNodes of this.branchGraph) {
77+
let [currentBasicBlock, branchesForThatBasicBlock] = toNodes;
78+
for (const isCovered of branchesForThatBasicBlock.values()) {
79+
if (!isCovered) {
80+
this.notFullyCoveredBasicBlock.add(currentBasicBlock);
81+
}
82+
}
83+
}
7584
for (const toNodes of this.branchGraph.values()) {
7685
let used = 0;
7786
for (const toNode of toNodes.values()) {
7887
if (toNode) used++;
7988
}
8089
this.result.branchCoverageRate.used += used;
8190
}
91+
// console.log(this.notFullyCoveredBasicBlock);
92+
for (const block of this.notFullyCoveredBasicBlock) {
93+
const lineInfo = this.covInfo.lineInfo.get(block);
94+
if (lineInfo !== undefined && lineInfo.size > 0) {
95+
this.result.linesToHighlight.add(Math.max(...lineInfo));
96+
}
97+
}
98+
// console.log(this.result.functionName, this.result.lineRange, this.result.linesToHighlight);
8299
}
83100
}

tests-as/diytest.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { describe, endTest, expect, test } from "../assembly";
2+
import { mycmp, instancecmp } from "../assembly/diytest"
3+
4+
describe("cmp test", () => {
5+
// 要考虑到流图可能不同,导致总branch数可能不同,所以计算branch覆盖率只能进行加权平均
6+
test("a>b", () => {
7+
let a: i32 = 1;
8+
let b: i32 = 0;
9+
expect(mycmp(a, b)).equal(true);
10+
});
11+
test("a<b", () => {
12+
let a: f32 = 0;
13+
let b: f32 = 0.5;
14+
expect(mycmp(a, b)).equal(false);
15+
});
16+
});
17+
18+
describe("instance test", () => {
19+
test("a>b", () => {
20+
let a: i32 = 1;
21+
let b: i32 = 0;
22+
expect(instancecmp(a, b)).equal(true);
23+
});
24+
test("a<b", () => {
25+
let a: f32 = 0;
26+
let b: f32 = 0.5;
27+
expect(instancecmp(a, b)).equal(false);
28+
});
29+
});
30+
31+
endTest();

tests-ts/test/parser/__snapshots__/parser.test.ts.snap

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ exports[`Parser generateFileCoverage 1`] = `
1616
"total": 18,
1717
"used": 9,
1818
},
19+
"linesToHighlight": Set {},
1920
"sourceUsedCount": [
2021
CodeCoverage {
2122
"source": "",
@@ -241,6 +242,7 @@ exports[`Parser generateFileCoverage 1`] = `
241242
"total": 1,
242243
"used": 1,
243244
},
245+
"linesToHighlight": Set {},
244246
"sourceUsedCount": [
245247
CodeCoverage {
246248
"source": "",
@@ -466,6 +468,9 @@ exports[`Parser generateFileCoverage 1`] = `
466468
"total": 13,
467469
"used": 9,
468470
},
471+
"linesToHighlight": Set {
472+
25,
473+
},
469474
"sourceUsedCount": [
470475
CodeCoverage {
471476
"source": "",
@@ -691,6 +696,7 @@ exports[`Parser generateFileCoverage 1`] = `
691696
"total": 2,
692697
"used": 2,
693698
},
699+
"linesToHighlight": Set {},
694700
"sourceUsedCount": [
695701
CodeCoverage {
696702
"source": "",
@@ -917,6 +923,7 @@ exports[`Parser generateFunctionCoverage 1`] = `
917923
39,
918924
39,
919925
],
926+
"linesToHighlight": Set {},
920927
"sourceUsedCount": Map {
921928
39 => 3,
922929
},
@@ -931,6 +938,7 @@ exports[`Parser generateFunctionCoverage 1`] = `
931938
16,
932939
24,
933940
],
941+
"linesToHighlight": Set {},
934942
"sourceUsedCount": Map {
935943
16 => 3,
936944
17 => 3,
@@ -952,6 +960,7 @@ exports[`Parser generateFunctionCoverage 1`] = `
952960
45,
953961
45,
954962
],
963+
"linesToHighlight": Set {},
955964
"sourceUsedCount": Map {
956965
45 => 4,
957966
},
@@ -966,6 +975,9 @@ exports[`Parser generateFunctionCoverage 1`] = `
966975
10,
967976
29,
968977
],
978+
"linesToHighlight": Set {
979+
25,
980+
},
969981
"sourceUsedCount": Map {
970982
10 => 2,
971983
11 => 2,
@@ -989,6 +1001,7 @@ exports[`Parser generateFunctionCoverage 1`] = `
9891001
10,
9901002
11,
9911003
],
1004+
"linesToHighlight": Set {},
9921005
"sourceUsedCount": Map {
9931006
10 => 2,
9941007
11 => 2,

tests-ts/test/parser/singleFileAnalysis.test.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ describe("singleFileAnalysis", () => {
3636
functionName: "A",
3737
lineRange: [6, 9],
3838
branchCoverageRate: rate_A,
39+
linesToHighlight: new Set<number>([]),
3940
sourceUsedCount: new Map([
4041
[6, 3],
4142
[7, 0],
@@ -49,6 +50,7 @@ describe("singleFileAnalysis", () => {
4950
functionName: "B",
5051
lineRange: [10, 14],
5152
branchCoverageRate: rate_B,
53+
linesToHighlight: new Set<number>([]),
5254
sourceUsedCount: new Map([
5355
[10, 2],
5456
[11, 0],
@@ -73,8 +75,8 @@ describe("singleFileAnalysis", () => {
7375

7476
test("setUnTestedFunction error", () => {
7577
const analyzer = new SingleFileCoverageAnalysis("main", source);
76-
expect(() => analyzer.setUnTestedFunction([[30, 31]])).toThrowError(
77-
"unknowm error: There is no 29 Line in file main"
78+
expect(() => analyzer.setUnTestedFunction([[30, 31]])).toThrow(
79+
"unknown error: There is no 29 Line in file main"
7880
);
7981
});
8082

@@ -88,12 +90,13 @@ describe("singleFileAnalysis", () => {
8890
functionName: "A",
8991
lineRange: [6, 30],
9092
branchCoverageRate: rate,
93+
linesToHighlight: new Set<number>([]),
9194
sourceUsedCount: new Map([
9295
[6, 3],
9396
[7, 0],
9497
[30, 3],
9598
]),
9699
};
97-
expect(() => analyzer.merge([funcResult])).toThrowError();
100+
expect(() => analyzer.merge([funcResult])).toThrow();
98101
});
99102
});

0 commit comments

Comments
 (0)