Skip to content

Commit

Permalink
Consolidate annotations on the same line
Browse files Browse the repository at this point in the history
  • Loading branch information
jgillick committed Nov 30, 2022
1 parent e469d4d commit 85171b7
Show file tree
Hide file tree
Showing 7 changed files with 278 additions and 130 deletions.
115 changes: 73 additions & 42 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9505,6 +9505,71 @@ function wrappy (fn, cb) {
}


/***/ }),

/***/ 9029:
/***/ ((__unused_webpack_module, exports) => {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.FileAnnotations = void 0;
/**
* Collect annotations for a single file
*/
class FileAnnotations {
constructor(filepath, filePrefix) {
this.annotations = {};
// Strip path prefix off filepath for annotation
if (filePrefix.length) {
if (filepath.startsWith(filePrefix)) {
filepath = filepath.substring(filePrefix.length);
}
else {
console.warn(`The coverage working directory '${filePrefix}' does not exist on coverage file entry: ${filepath}.`);
}
}
this.filepath = filepath;
}
/**
* Get existing partial annotation for a line
*/
getAnnotation(line) {
let annotation = this.annotations[line];
if (!annotation) {
annotation = {
line,
message: [],
};
this.annotations[line] = annotation;
}
return annotation;
}
/**
* Define an annotation type for a line
*/
addAnnotation(type, line, column) {
const annotation = this.getAnnotation(line);
annotation.message.push(`${type} starting at column ${column}`);
}
/**
* Get all full annotations
*/
getAnnotations() {
return Object.values(this.annotations).map(({ line, message }) => ({
title: "Line missing test coverage",
start_line: line,
end_line: line,
start_column: 0,
path: this.filepath,
annotation_level: "warning",
message: message.join("\n").trim(),
}));
}
}
exports.FileAnnotations = FileAnnotations;


/***/ }),

/***/ 6144:
Expand Down Expand Up @@ -9677,36 +9742,18 @@ main();
/***/ }),

/***/ 5541:
/***/ ((__unused_webpack_module, exports) => {
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseCoverage = void 0;
const FileAnnotation_1 = __nccwpck_require__(9029);
/**
* Read the test coverage JSON and stream positions that are missing coverage.
*/
function parseCoverage(coverage, files, filePrefix = "") {
const annotations = [];
const addAnnotation = (annotation) => {
// Remove null value
if (annotation.end_column === null) {
delete annotation.end_column;
}
if (annotation.start_column === null) {
delete annotation.start_column;
}
// Remove column values if start/end lines are not the same
if (annotation.start_line !== annotation.end_line) {
if (typeof annotation.end_column !== "undefined") {
delete annotation.end_column;
}
if (typeof annotation.start_column !== "undefined") {
delete annotation.start_column;
}
}
annotations.push(annotation);
};
let annotations = [];
for (let filepath of files) {
// Get coverage for file
if (typeof coverage[filepath] === "undefined") {
Expand All @@ -9715,35 +9762,19 @@ function parseCoverage(coverage, files, filePrefix = "") {
}
const fileCoverage = coverage[filepath];
console.warn(`Checking coverage for ${filepath}`);
// Strip path prefix off filepath for annotation
let annotationPath = filepath;
if (filePrefix.length) {
if (annotationPath.startsWith(filePrefix)) {
annotationPath = annotationPath.substring(filePrefix.length);
}
else {
console.warn(`The coverage working directory '${filePrefix}' does not exist on coverage file entry: ${annotationPath}.`);
}
}
// Base annotation object
const base = {
path: annotationPath,
annotation_level: "warning",
};
const fileAnnotations = new FileAnnotation_1.FileAnnotations(filepath, filePrefix);
// Statements
for (const [id, count] of Object.entries(fileCoverage.s)) {
if (count === 0) {
const statement = fileCoverage.statementMap[id];
const message = "This statement lacks test coverage";
addAnnotation(Object.assign(Object.assign({}, base), { message, start_line: statement.start.line, start_column: statement.start.column, end_line: statement.end.line, end_column: statement.end.column }));
fileAnnotations.addAnnotation("statement", statement.start.line, statement.start.column);
}
}
// Functions
for (const [id, count] of Object.entries(fileCoverage.f)) {
if (count === 0) {
const func = fileCoverage.fnMap[id];
const message = "This function lacks test coverage";
addAnnotation(Object.assign(Object.assign({}, base), { message, start_line: func.decl.start.line, start_column: func.decl.start.column, end_line: func.loc.end.line, end_column: func.loc.end.column || 0 }));
fileAnnotations.addAnnotation("function", func.decl.start.line, func.decl.start.column);
}
}
// Branches
Expand All @@ -9752,11 +9783,11 @@ function parseCoverage(coverage, files, filePrefix = "") {
const count = counts[i];
if (count === 0) {
const branch = fileCoverage.branchMap[id];
const message = "This branch lacks test coverage";
addAnnotation(Object.assign(Object.assign({}, base), { message, start_line: branch.locations[i].start.line, start_column: branch.locations[i].start.column, end_line: branch.locations[i].end.line, end_column: branch.locations[i].end.column || 0 }));
fileAnnotations.addAnnotation("branch", branch.locations[i].start.line, branch.locations[i].start.column);
}
}
}
annotations = [...annotations, ...fileAnnotations.getAnnotations()];
}
return annotations;
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "test-coverage-annotations",
"version": "0.0.1",
"version": "1.0.2",
"description": "A github action that add file annotations to areas of code lacking test coverage",
"main": "dist/index.ts",
"scripts": {
Expand Down
72 changes: 72 additions & 0 deletions src/FileAnnotation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import type { Annotation } from "./types";

type AnnotationType = "statement" | "function" | "branch";

type PartialAnnotation = {
line: number;
message: string[];
};

/**
* Collect annotations for a single file
*/
export class FileAnnotations {
filepath: string;
annotations: Record<number, PartialAnnotation>;

constructor(filepath: string, filePrefix: string) {
this.annotations = {};

// Strip path prefix off filepath for annotation
if (filePrefix.length) {
if (filepath.startsWith(filePrefix)) {
filepath = filepath.substring(filePrefix.length);
} else {
console.warn(
`The coverage working directory '${filePrefix}' does not exist on coverage file entry: ${filepath}.`
);
}
}
this.filepath = filepath;
}

/**
* Get existing partial annotation for a line
*/
getAnnotation(line: number): PartialAnnotation {
let annotation = this.annotations[line];
if (!annotation) {
annotation = {
line,
message: [],
};
this.annotations[line] = annotation;
}
return annotation;
}

/**
* Define an annotation type for a line
*/
addAnnotation(type: AnnotationType, line: number, column: number) {
const annotation = this.getAnnotation(line);
annotation.message.push(`${type} starting at column ${column}`);
}

/**
* Get all full annotations
*/
getAnnotations() {
return Object.values(this.annotations).map(
({ line, message }: PartialAnnotation): Annotation => ({
title: "Line missing test coverage",
start_line: line,
end_line: line,
start_column: 0,
path: this.filepath,
annotation_level: "warning",
message: message.join("\n").trim(),
})
);
}
}
52 changes: 35 additions & 17 deletions src/parseCoverage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,52 +18,70 @@ describe("parseCoverage", () => {
{
path: "/test/src/file1.ts",
annotation_level: "warning",
message: "This statement lacks test coverage",
message: "statement starting at column 0",
start_line: 2,
start_column: 0,
end_line: 2,
end_column: 30,
start_column: 0,
title: "Line missing test coverage",
},
{
path: "/test/src/file1.ts",
annotation_level: "warning",
message: "This function lacks test coverage",
message: "function starting at column 0",
start_line: 3,
end_line: 3,
start_column: 0,
end_line: 4,
title: "Line missing test coverage",
},
{
path: "/test/src/file1.ts",
annotation_level: "warning",
message: "This branch lacks test coverage",
message: "branch starting at column 10",
start_line: 6,
start_column: 10,
end_line: 6,
end_column: 20,
start_column: 0,
title: "Line missing test coverage",
},
{
path: "/test/src/file2.ts",
path: "/test/src/file1.ts",
annotation_level: "warning",
message: "This statement lacks test coverage",
message: [
"statement starting at column 0",
"function starting at column 2",
"branch starting at column 10",
"branch starting at column 30",
].join("\n"),
start_line: 8,
end_line: 8,
start_column: 0,
title: "Line missing test coverage",
},
{
title: "Line missing test coverage",
start_line: 1,
end_line: 1,
start_column: 0,
end_line: 2,
path: "/test/src/file2.ts",
annotation_level: "warning",
message: "statement starting at column 0",
},
{
path: "/test/src/file2.ts",
annotation_level: "warning",
message: "This function lacks test coverage",
message: "function starting at column 2",
start_line: 4,
start_column: 2,
end_line: 5,
end_line: 4,
start_column: 0,
title: "Line missing test coverage",
},
{
path: "/test/src/file2.ts",
annotation_level: "warning",
message: "This branch lacks test coverage",
message: "branch starting at column 30",
start_line: 5,
start_column: 30,
end_line: 6,
end_line: 5,
start_column: 0,
title: "Line missing test coverage",
},
]);
});
Expand Down
Loading

0 comments on commit 85171b7

Please sign in to comment.