Skip to content

Commit

Permalink
feature: add junit compatibility of cpplint
Browse files Browse the repository at this point in the history
  • Loading branch information
MeilCli committed May 10, 2021
1 parent 9ff48ca commit 41b736b
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 8 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Current supporting lint file format:
- markdownlint
- checkstyle
- junit
- compatibility: eslint, textlint
- compatibility: eslint, textlint, cpplint

### Feature request
Now, this action is WIP. Features are not enough and should improve about transformer and operator. If you have nice idea, please send as issue:heart:
Expand Down
38 changes: 38 additions & 0 deletions __test__/transformer/junit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,41 @@ test("transformTextlint", async () => {
level: "warning",
} as LintResult);
});

test("transformCpplint", async () => {
const text = fs.readFileSync("data/junit_cpplint.xml", "utf-8");
const transformer = new JunitTransformer();
const result = transformer.parse(text);

expect(result.length).toBe(3);
expect(result[0]).toMatchObject({
path: "data/cpplint/test.cpp",
rule: "legal/copyright",
message: `No copyright message found. You should have a line: "Copyright [year] <Copyright Owner>"`,
startLine: 1,
endLine: undefined,
startColumn: undefined,
endColumn: undefined,
level: "failure",
} as LintResult);
expect(result[1]).toMatchObject({
path: "data/cpplint/test.cpp",
rule: "whitespace/braces",
message: `Missing space before {`,
startLine: 1,
endLine: undefined,
startColumn: undefined,
endColumn: undefined,
level: "failure",
} as LintResult);
expect(result[2]).toMatchObject({
path: "data/cpplint/test.cpp",
rule: "whitespace/ending_newline",
message: `Could not find a newline character at the end of the file.`,
startLine: 3,
endLine: undefined,
startColumn: undefined,
endColumn: undefined,
level: "failure",
} as LintResult);
});
3 changes: 3 additions & 0 deletions data/cpplint/command.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1. `pip install cpplint`
1. `cpplint --output junit data/cpplint/test.cpp`
1. write stdout to `data/junit_cpplint.xml`
3 changes: 3 additions & 0 deletions data/cpplint/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
void method(){
println("test");
}
4 changes: 4 additions & 0 deletions data/junit_cpplint.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?>
<testsuite errors="0" failures="3" name="cpplint" tests="3"><testcase name="data/cpplint/test.cpp"><failure>0: No copyright message found. You should have a line: "Copyright [year] &lt;Copyright Owner&gt;" [legal/copyright] [5]
1: Missing space before { [whitespace/braces] [5]
3: Could not find a newline character at the end of the file. [whitespace/ending_newline] [5]</failure></testcase></testsuite>
1 change: 1 addition & 0 deletions documents/transformer/junit.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ The compatibility is not needed because this action has standard resolver. But,
Now compatibility:
- eslint
- textlint
- cpplint
## Option
### Input
Expand Down
23 changes: 17 additions & 6 deletions src/transformer/junit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { JunitTestSuite, JunitTestCase, JunitTestMessage } from "./junit/entity"
import { convertJunitToLintResult } from "./junit/convert";

interface JunitResult {
testsuites: TestSuites[];
testsuites: TestSuites[] | undefined;
}

interface TestSuites {
Expand All @@ -25,8 +25,8 @@ interface TestSuite {
interface TestCase {
name: string;
classname: string;
error: TestMessage[] | undefined;
failure: TestMessage[] | undefined;
error: TestMessage[] | string | undefined;
failure: TestMessage[] | string | undefined;
}

interface TestMessage {
Expand All @@ -44,8 +44,16 @@ export class JunitTransformer extends Transformer {
attrValueProcessor: (value, _) => he.decode(value),
}) as JunitResult;
const junitTestSuites: JunitTestSuite[] = [];
for (const testSuites of junitResult.testsuites) {
junitTestSuites.push(...this.parseTestSuites(testSuites.testsuite));
if (junitResult.testsuites != undefined) {
for (const testSuites of junitResult.testsuites) {
junitTestSuites.push(...this.parseTestSuites(testSuites.testsuite));
}
} else {
// for cpplint
const testSuites = (junitResult as unknown) as TestSuites;
if (testSuites.testsuite != undefined) {
junitTestSuites.push(...this.parseTestSuites(testSuites.testsuite));
}
}
return convertJunitToLintResult(junitTestSuites);
}
Expand Down Expand Up @@ -82,10 +90,13 @@ export class JunitTransformer extends Transformer {
return result;
}

private parseTestMessages(testMessages: TestMessage[] | undefined): JunitTestMessage[] {
private parseTestMessages(testMessages: TestMessage[] | string | undefined): JunitTestMessage[] {
if (testMessages == undefined) {
return [];
}
if (typeof testMessages == "string") {
return [{ message: testMessages, body: testMessages }];
}
const result: JunitTestMessage[] = [];
for (const testMessage of testMessages) {
result.push({
Expand Down
3 changes: 2 additions & 1 deletion src/transformer/junit/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { JunitTestSuite } from "./entity";
import { JunitHandler } from "./junit-handler";
import { DefaultJunitHandler } from "./junit-handler-default";
import { EslintJunitHandler } from "./junit-handler-eslint";
import { CpplintJunitHandler } from "./junit-handler-cpplint";

const handlers: JunitHandler[] = [new EslintJunitHandler(), new DefaultJunitHandler()];
const handlers: JunitHandler[] = [new EslintJunitHandler(), new CpplintJunitHandler(), new DefaultJunitHandler()];

export function convertJunitToLintResult(testSuites: JunitTestSuite[]): LintResult[] {
for (const handler of handlers) {
Expand Down
99 changes: 99 additions & 0 deletions src/transformer/junit/junit-handler-cpplint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { JunitTestSuite, JunitTestCase } from "./entity";
import { LintResult } from "../../lint-result";
import { JunitHandler } from "./junit-handler";
import * as he from "he";

export class CpplintJunitHandler implements JunitHandler {
match(testSuites: JunitTestSuite[]): boolean {
if (testSuites.length == 0) {
return false;
}
return testSuites[0].name == "cpplint";
}

handle(testSuites: JunitTestSuite[]): LintResult[] {
const result: LintResult[] = [];
this.handleTestSuites(result, testSuites);
return result;
}

private handleTestSuites(result: LintResult[], testSuites: JunitTestSuite[]) {
for (const testSuite of testSuites) {
this.handleTestSuite(result, testSuite);
}
}

private handleTestSuite(result: LintResult[], testSuite: JunitTestSuite) {
this.handleTestCases(result, testSuite.testCases);
this.handleTestSuites(result, testSuite.testSuites);
}

private handleTestCases(result: LintResult[], testCases: JunitTestCase[]) {
for (const testCase of testCases) {
this.handleTestCase(result, testCase);
}
}

private handleTestCase(result: LintResult[], testCase: JunitTestCase) {
for (const failure of testCase.failures) {
for (const message of this.parseBody(failure.body)) {
result.push({
path: testCase.name,
message: message[1],
level: message[3] == 5 ? "failure" : 3 <= message[3] ? "warning" : "notice",
rule: message[2],
startLine: message[0],
startColumn: undefined,
endLine: undefined,
endColumn: undefined,
});
}
}
for (const error of testCase.errors) {
for (const message of this.parseBody(error.body)) {
result.push({
path: testCase.name,
message: message[1],
level: message[3] == 5 ? "failure" : 3 <= message[3] ? "warning" : "notice",
rule: message[2],
startLine: message[0],
startColumn: undefined,
endLine: undefined,
endColumn: undefined,
});
}
}
}

private parseBody(body: string): [number, string, string, number][] {
const result: [number, string, string, number][] = [];
for (const line of body.split(/(\r\n)|\n|\r/g)) {
if (line == undefined || line.length == 0) {
continue;
}

const rawStartLine = line.replace(/^(\d+):\s(.+)\s\[(.+?)\]\s\[(\d)\]$/, "$1");
const rawMessage = line.replace(/^(\d+):\s(.+)\s\[(.+?)\]\s\[(\d)\]$/, "$2");
const rawRule = line.replace(/^(\d+):\s(.+)\s\[(.+?)\]\s\[(\d)\]$/, "$3");
const rawConfidence = line.replace(/^(\d+):\s(.+)\s\[(.+?)\]\s\[(\d)\]$/, "$4");
if (
rawStartLine.length == 0 ||
rawMessage.length == 0 ||
rawRule.length == 0 ||
rawConfidence.length == 0
) {
continue;
}
const startLine = parseInt(rawStartLine);
const message = he.decode(rawMessage);
const rule = he.decode(rawRule);
const confidence = parseInt(rawConfidence);
if (Number.isInteger(startLine) == false || Number.isInteger(confidence) == false) {
continue;
}

result.push([startLine == 0 ? 1 : startLine, message, rule, confidence]);
}
return result;
}
}

0 comments on commit 41b736b

Please sign in to comment.