From 731a7772d801b8e78eb86bc9f6a9791d64d2324d Mon Sep 17 00:00:00 2001 From: Alexander Stephan Date: Sun, 26 Sep 2021 22:14:20 +0200 Subject: [PATCH] Add C language support (#11) --- .../tum/in/ase/parser/strategy/GCCParser.java | 191 ++++++++++++++++++ .../strategy/StaticCodeAnalysisTool.java | 6 +- .../de/tum/in/ase/parser/IntegrationTest.java | 88 +++++--- src/test/java/expected/checkstyle.txt | 1 + src/test/java/expected/gcc.txt | 1 + src/test/java/expected/invalid_filename.txt | 1 + src/test/java/expected/invalid_name.txt | 1 + src/test/java/expected/invalid_xml.txt | 1 + src/test/java/expected/pmd.txt | 1 + src/test/java/expected/pmd_cpd.txt | 1 + src/test/java/expected/spotbugs.txt | 1 + src/test/java/expected/swiftlint.txt | 1 + .../java/{ => reports}/checkstyle-result.xml | 0 src/test/java/{ => reports}/cpd.xml | 0 src/test/java/{ => reports}/cpd_invalid.txt | 0 src/test/java/reports/gcc.xml | 43 ++++ src/test/java/{ => reports}/invalid_name.xml | 0 src/test/java/{ => reports}/invalid_xml.xml | 0 src/test/java/{ => reports}/pmd.xml | 0 src/test/java/{ => reports}/spotbugsXml.xml | 0 .../java/{ => reports}/swiftlint-result.xml | 0 21 files changed, 305 insertions(+), 32 deletions(-) create mode 100644 src/main/java/de/tum/in/ase/parser/strategy/GCCParser.java create mode 100644 src/test/java/expected/checkstyle.txt create mode 100644 src/test/java/expected/gcc.txt create mode 100644 src/test/java/expected/invalid_filename.txt create mode 100644 src/test/java/expected/invalid_name.txt create mode 100644 src/test/java/expected/invalid_xml.txt create mode 100644 src/test/java/expected/pmd.txt create mode 100644 src/test/java/expected/pmd_cpd.txt create mode 100644 src/test/java/expected/spotbugs.txt create mode 100644 src/test/java/expected/swiftlint.txt rename src/test/java/{ => reports}/checkstyle-result.xml (100%) rename src/test/java/{ => reports}/cpd.xml (100%) rename src/test/java/{ => reports}/cpd_invalid.txt (100%) create mode 100644 src/test/java/reports/gcc.xml rename src/test/java/{ => reports}/invalid_name.xml (100%) rename src/test/java/{ => reports}/invalid_xml.xml (100%) rename src/test/java/{ => reports}/pmd.xml (100%) rename src/test/java/{ => reports}/spotbugsXml.xml (100%) rename src/test/java/{ => reports}/swiftlint-result.xml (100%) diff --git a/src/main/java/de/tum/in/ase/parser/strategy/GCCParser.java b/src/main/java/de/tum/in/ase/parser/strategy/GCCParser.java new file mode 100644 index 0000000..4a4276a --- /dev/null +++ b/src/main/java/de/tum/in/ase/parser/strategy/GCCParser.java @@ -0,0 +1,191 @@ +package de.tum.in.ase.parser.strategy; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import de.tum.in.ase.parser.domain.Issue; +import de.tum.in.ase.parser.domain.Report; + +public class GCCParser implements ParserStrategy { + + // The message is split into two segments + private static final int SEGMENTS_COUNT = 2; + + // Segment 0 (Header): Contains info about filename, row, column, type etc. + private static final int HEADER_SEGMENT_POS = 0; + + // Segment 1 (Body): Body contains the trace of the error (possibly rendered with ASCII art) + private static final int BODY_SEGMENT_POS = 1; + + // Locations in regex group + private static final int FILE_POS = 1; + + private static final int ROW_POS = 2; + + private static final int COLUMN_POS = 3; + + private static final int TYPE_POS = 4; + + private static final int DESCRIPTION_POS = 5; + + private static final int ERROR_POS = 6; + + // Map that contains the matching category for each error + private static final Map categories = new HashMap<>(); + + private static final String ANALYZER_PREFIX = "[-Wanalyzer"; + + // Categories + private static final String MEMORY = "Memory"; + + private static final String BAD_PRACTICE = "BadPractice"; + + private static final String SECURITY = "Security"; + + private static final String UNDEFINED_BEHAVIOR = "UndefinedBehavior"; + + // For various other results that are not part of the static analysis + private static final String MISC = "Misc"; + + // Used to parse the first line of an issue which contains all the essential data + // e.g. "ascii_table.c:7:13: warning: variable ‘arr’ set but not used [-Wunused-but-set-variable]". + // A colon ":" is the separator symbol used by GCC. + private static final String HEADER_REGEX = "([^:^\\n]+):(\\d+):(\\d+):\\s(\\w+\\s*\\w*):\\s(.+)(\\[.+])"; + /* ^ ^ ^ ^ ^ ^ + | | | | | | + | | | | | | + | | | | | +- error name eg. "[-Wunused-but-set-variable]" + | | | | +- message text e.g. " warning: variable ‘arr’ set but not used" (note the leading whitespace) + | | | +- type (error|warning|note) + | | +- column e.g. "13" + | +- row e.g. "7" + +- filename e.g. "ascii_table.c" + */ + + // More generic regex similar to HEADER_REGEX, that describes the beginning of a basic GCC message, which is used to divide the output into chunks. + // A look ahead regex (see "?=") is used, since we need to keep the delimiter after the split. + // We need to include new line, so we can guarantee that we actually match to a new message. + private static final String DELIM_REGEX = "(?=(\\n([^:^\\n]+):(\\d)+:(\\d)+:(.)+:(.)+))"; + + @Override + public Report parse(Document doc) { + Report report = new Report(StaticCodeAnalysisTool.GCC); + extractIssues(doc, report); + return report; + } + + /** + * Constructs issues and adds them to the static analysis report. + * + * @param doc Contains the output from GCC SCA. + * @param report The report the issues will be added to. + */ + private void extractIssues(Document doc, Report report) { + Element gccLog = doc.getDocumentElement(); + + String[] logItems = gccLog.getTextContent().split(DELIM_REGEX); + + Pattern pattern = Pattern.compile(HEADER_REGEX); + Matcher matcher = pattern.matcher(""); + + initCategoryMapping(); + + List issues = new ArrayList<>(); + + for (String entry : logItems) { + + // Chops off the leading \n which makes parsing more clear, as we avoid an empty extra segment + String[] segments = entry.substring(1).split("\n", SEGMENTS_COUNT); + + if (segments.length < 2) { + continue; + } + + String header = segments[HEADER_SEGMENT_POS]; + String body = segments[BODY_SEGMENT_POS]; + + matcher.reset(header); + + if (!matcher.find()) { + continue; + } + + // Construct issue details based on regex groups + String filename = matcher.group(FILE_POS).trim(); + Integer row = Integer.parseInt(matcher.group(ROW_POS)); + Integer col = Integer.parseInt(matcher.group(COLUMN_POS)); + String type = matcher.group(TYPE_POS); + String description = matcher.group(DESCRIPTION_POS); + String warningName = matcher.group(ERROR_POS); + + // Only output warnings that have a name associated with it + if (warningName == null) { + continue; + } + + // warningName is included in the description, as it will not be shown be Artemis otherwise + String message = warningName + ": " + description + "\n" + body; + + Issue issue = new Issue(null); + + issue.setMessage(message); + issue.setFilePath(filename); + issue.setStartLine(row); + issue.setEndLine(row); + issue.setStartColumn(col); + issue.setEndColumn(col); + issue.setRule(warningName); + issue.setPriority(type); // Could potentially be used for sorting at some point, not displayed by Artemis + + boolean isAnalyzerIssue = warningName.startsWith(ANALYZER_PREFIX); + + // Set correct category, only real static analysis issues are categorized, see https://gcc.gnu.org/onlinedocs/gcc-11.1.0/gcc/Static-Analyzer-Options.html + if (isAnalyzerIssue) { + String category = categories.get(warningName); + issue.setCategory(category); + } + else { + issue.setCategory(MISC); + } + + issues.add(issue); + } + report.setIssues(issues); + } + + private void initCategoryMapping() { + // Memory warnings + categories.put("[-Wanalyzer-free-of-non-heap]", MEMORY); + categories.put("[-Wanalyzer-malloc-leak]", MEMORY); + categories.put("[-Wanalyzer-file-leak]", MEMORY); + categories.put("[-Wanalyzer-mismatching-deallocation]", MEMORY); + + // Undefined behavior + categories.put("[-Wanalyzer-double-free]", UNDEFINED_BEHAVIOR); + categories.put("[-Wanalyzer-null-argument]", UNDEFINED_BEHAVIOR); + categories.put("[-Wanalyzer-use-after-free]", UNDEFINED_BEHAVIOR); + categories.put("[-Wanalyzer-use-of-uninitialized-value]", UNDEFINED_BEHAVIOR); + categories.put("[-Wanalyzer-write-to-const]", UNDEFINED_BEHAVIOR); + categories.put("[-Wanalyzer-write-to-string-literal]", UNDEFINED_BEHAVIOR); + categories.put("[-Wanalyzer-possible-null-argument]", UNDEFINED_BEHAVIOR); + categories.put("[-Wanalyzer-possible-null-dereference]", UNDEFINED_BEHAVIOR); + + // Bad Practice + categories.put("[-Wanalyzer-double-fclose]", BAD_PRACTICE); + categories.put("[-Wanalyzer-too-complex]", BAD_PRACTICE); + categories.put("[-Wanalyzer-stale-setjmp-buffer]", BAD_PRACTICE); + + // Security + categories.put("[-Wanalyzer-exposure-through-output-file]", SECURITY); + categories.put("[-Wanalyzer-unsafe-call-within-signal-handler]", SECURITY); + categories.put("[-Wanalyzer-use-of-pointer-in-stale-stack-frame]", SECURITY); + categories.put("[-Wanalyzer-tainted-array-index]", SECURITY); + } +} diff --git a/src/main/java/de/tum/in/ase/parser/strategy/StaticCodeAnalysisTool.java b/src/main/java/de/tum/in/ase/parser/strategy/StaticCodeAnalysisTool.java index 42304c3..c97aee3 100644 --- a/src/main/java/de/tum/in/ase/parser/strategy/StaticCodeAnalysisTool.java +++ b/src/main/java/de/tum/in/ase/parser/strategy/StaticCodeAnalysisTool.java @@ -4,14 +4,18 @@ import java.util.Optional; public enum StaticCodeAnalysisTool { + SPOTBUGS("BugCollection", "spotbugsXml.xml", new SpotbugsParser()), CHECKSTYLE("checkstyle", "checkstyle-result.xml", new CheckstyleParser()), SWIFTLINT("checkstyle", "swiftlint-result.xml", new SwiftLintParser()), PMD("pmd", "pmd.xml", new PMDParser()), - PMD_CPD("pmd-cpd", "cpd.xml", new PMDCPDParser()); + PMD_CPD("pmd-cpd", "cpd.xml", new PMDCPDParser()), + GCC("root", "gcc.xml", new GCCParser()); private final String identifierTag; + private final String filename; + private final ParserStrategy strategy; StaticCodeAnalysisTool(String identifyingTag, String filename, ParserStrategy strategy) { diff --git a/src/test/java/de/tum/in/ase/parser/IntegrationTest.java b/src/test/java/de/tum/in/ase/parser/IntegrationTest.java index 4ae2d3c..0e1a777 100644 --- a/src/test/java/de/tum/in/ase/parser/IntegrationTest.java +++ b/src/test/java/de/tum/in/ase/parser/IntegrationTest.java @@ -3,7 +3,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import java.io.BufferedReader; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Collectors; import org.junit.jupiter.api.Test; import org.xml.sax.SAXParseException; @@ -16,69 +22,89 @@ */ public class IntegrationTest { - private static final String EXPECTED_CHECKSTYLE = "{\"tool\":\"CHECKSTYLE\",\"issues\":[{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":6,\"endLine\":6,\"startColumn\":8,\"endColumn\":8,\"rule\":\"UnusedImportsCheck\",\"category\":\"imports\",\"message\":\"Unused import - javax.swing.JFrame.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":7,\"endLine\":7,\"startColumn\":1,\"endColumn\":1,\"rule\":\"RedundantImportCheck\",\"category\":\"imports\",\"message\":\"Redundant import from the java.lang package - java.lang.*.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":65,\"endLine\":65,\"startColumn\":0,\"endColumn\":0,\"rule\":\"RegexpSinglelineCheck\",\"category\":\"regexp\",\"message\":\"Line has trailing spaces.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":68,\"endLine\":68,\"startColumn\":0,\"endColumn\":0,\"rule\":\"RegexpSinglelineCheck\",\"category\":\"regexp\",\"message\":\"Line has trailing spaces.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":70,\"endLine\":70,\"startColumn\":0,\"endColumn\":0,\"rule\":\"RegexpSinglelineCheck\",\"category\":\"regexp\",\"message\":\"Line has trailing spaces.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":70,\"endLine\":70,\"startColumn\":9,\"endColumn\":9,\"rule\":\"NeedBracesCheck\",\"category\":\"blocks\",\"message\":\"'for' construct must use '{}'s.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":73,\"endLine\":73,\"startColumn\":0,\"endColumn\":0,\"rule\":\"RegexpSinglelineCheck\",\"category\":\"regexp\",\"message\":\"Line has trailing spaces.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":76,\"endLine\":76,\"startColumn\":0,\"endColumn\":0,\"rule\":\"RegexpSinglelineCheck\",\"category\":\"regexp\",\"message\":\"Line has trailing spaces.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":78,\"endLine\":78,\"startColumn\":8,\"endColumn\":8,\"rule\":\"JavadocMethodCheck\",\"category\":\"javadoc\",\"message\":\"Unused @param tag for 'x1'.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":80,\"endLine\":80,\"startColumn\":0,\"endColumn\":0,\"rule\":\"JavadocMethodCheck\",\"category\":\"javadoc\",\"message\":\"@return tag should be present and have description.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":80,\"endLine\":80,\"startColumn\":31,\"endColumn\":31,\"rule\":\"MethodNameCheck\",\"category\":\"naming\",\"message\":\"Name 'CreateRandomDatesList' must match pattern '^[a-z][a-zA-Z0-9]*$'.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":93,\"endLine\":93,\"startColumn\":9,\"endColumn\":9,\"rule\":\"EmptyStatementCheck\",\"category\":\"coding\",\"message\":\"Empty statement.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":93,\"endLine\":93,\"startColumn\":10,\"endColumn\":10,\"rule\":\"EmptyStatementCheck\",\"category\":\"coding\",\"message\":\"Empty statement.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":93,\"endLine\":93,\"startColumn\":11,\"endColumn\":11,\"rule\":\"EmptyStatementCheck\",\"category\":\"coding\",\"message\":\"Empty statement.\",\"priority\":\"error\"}]}"; + private final static Path EXPECTED_FOLDER_PATH = Paths.get("src", "test", "java", "expected"); - private static final String EXPECTED_PMD_CPD = "{\"tool\":\"PMD_CPD\",\"issues\":[{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":60,\"endLine\":75,\"startColumn\":52,\"endColumn\":18,\"rule\":\"Copy/Paste Detection\",\"category\":\"Copy/Paste Detection\",\"message\":\"Code duplication of 16 lines in the following files:\\n1. Client.java:60-75\\n2. Client.java:75-97\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":75,\"endLine\":97,\"startColumn\":53,\"endColumn\":18,\"rule\":\"Copy/Paste Detection\",\"category\":\"Copy/Paste Detection\",\"message\":\"Code duplication of 16 lines in the following files:\\n1. Client.java:60-75\\n2. Client.java:75-97\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/BubbleSort.java\",\"startLine\":13,\"endLine\":24,\"startColumn\":9,\"endColumn\":9,\"rule\":\"Copy/Paste Detection\",\"category\":\"Copy/Paste Detection\",\"message\":\"Code duplication of 12 lines in the following files:\\n1. BubbleSort.java:13-24\\n2. BubbleSort.java:25-36\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/BubbleSort.java\",\"startLine\":25,\"endLine\":36,\"startColumn\":9,\"endColumn\":9,\"rule\":\"Copy/Paste Detection\",\"category\":\"Copy/Paste Detection\",\"message\":\"Code duplication of 12 lines in the following files:\\n1. BubbleSort.java:13-24\\n2. BubbleSort.java:25-36\"}]}"; + private final static Path REPORTS_FOLDER_PATH = Paths.get("src", "test", "java", "reports"); - private static final String EXPECTED_PMD = "{\"tool\":\"PMD\",\"issues\":[{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":6,\"endLine\":6,\"startColumn\":1,\"endColumn\":26,\"rule\":\"UnusedImports\",\"category\":\"Best Practices\",\"message\":\"Avoid unused imports such as 'javax.swing.JFrame'\",\"priority\":\"4\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":7,\"endLine\":7,\"startColumn\":1,\"endColumn\":19,\"rule\":\"DontImportJavaLang\",\"category\":\"Code Style\",\"message\":\"Avoid importing anything from the package java.lang\",\"priority\":\"4\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":7,\"endLine\":7,\"startColumn\":1,\"endColumn\":19,\"rule\":\"UnusedImports\",\"category\":\"Best Practices\",\"message\":\"Avoid unused imports such as 'java.lang'\",\"priority\":\"4\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":73,\"endLine\":73,\"startColumn\":18,\"endColumn\":27,\"rule\":\"UnusedLocalVariable\",\"category\":\"Best Practices\",\"message\":\"Avoid unused local variables such as 'randomDate'.\",\"priority\":\"3\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":81,\"endLine\":81,\"startColumn\":31,\"endColumn\":53,\"rule\":\"UnusedPrivateMethod\",\"category\":\"Best Practices\",\"message\":\"Avoid unused private methods such as 'CreateRandomDatesList()'.\",\"priority\":\"3\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":94,\"endLine\":94,\"startColumn\":9,\"endColumn\":9,\"rule\":\"EmptyStatementNotInLoop\",\"category\":\"Error Prone\",\"message\":\"An empty statement (semicolon) not part of a loop\",\"priority\":\"3\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":94,\"endLine\":94,\"startColumn\":10,\"endColumn\":10,\"rule\":\"EmptyStatementNotInLoop\",\"category\":\"Error Prone\",\"message\":\"An empty statement (semicolon) not part of a loop\",\"priority\":\"3\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":94,\"endLine\":94,\"startColumn\":11,\"endColumn\":11,\"rule\":\"EmptyStatementNotInLoop\",\"category\":\"Error Prone\",\"message\":\"An empty statement (semicolon) not part of a loop\",\"priority\":\"3\"}]}"; + /** + * Compares the parsed JSON report with the expected JSON report + * @param toolGeneratedReportFileName The name of the file contains the report as generated by the different tools + * @param expectedJSONReportFileName The name of the file that contains the parsed report + * @throws ParserException If an exception occurs that is not already handled by the parser itself, e.g. caused by the json-parsing + */ + private void testParserWithFile(String toolGeneratedReportFileName, String expectedJSONReportFileName) throws ParserException, IOException { + File toolReport = REPORTS_FOLDER_PATH.resolve(toolGeneratedReportFileName).toFile(); - private static final String EXPECTED_SPOTBUGS = "{\"tool\":\"SPOTBUGS\",\"issues\":[{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":73,\"endLine\":73,\"rule\":\"DLS_DEAD_LOCAL_STORE\",\"category\":\"STYLE\",\"message\":\"Dead store to randomDate in code.Client.createRandomDatesList()\",\"priority\":\"2\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":82,\"endLine\":95,\"rule\":\"NM_METHOD_NAMING_CONVENTION\",\"category\":\"BAD_PRACTICE\",\"message\":\"The method name code.Client.CreateRandomDatesList() doesn't start with a lower case letter\",\"priority\":\"3\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java\",\"startLine\":82,\"endLine\":95,\"rule\":\"UPM_UNCALLED_PRIVATE_METHOD\",\"category\":\"PERFORMANCE\",\"message\":\"Private method code.Client.CreateRandomDatesList() is never called\",\"priority\":\"2\"}]}"; - - private static final String EXPECTED_SWIFTLINT = "{\"tool\":\"SWIFTLINT\",\"issues\":[{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":20,\"endLine\":20,\"startColumn\":21,\"endColumn\":21,\"rule\":\"array_init\",\"category\":\"swiftLint\",\"message\":\"Prefer using `Array(seq)` over `seq.map { $0 }` to convert a sequence into an Array.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":25,\"endLine\":25,\"startColumn\":38,\"endColumn\":38,\"rule\":\"closing_brace\",\"category\":\"swiftLint\",\"message\":\"Closing brace with closing parenthesis should not have any whitespaces in the middle.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":22,\"endLine\":22,\"startColumn\":15,\"endColumn\":15,\"rule\":\"closure_end_indentation\",\"category\":\"swiftLint\",\"message\":\"Closure end should have the same indentation as the line that started it. Expected 8, got 14.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":44,\"endLine\":44,\"startColumn\":21,\"endColumn\":21,\"rule\":\"closure_spacing\",\"category\":\"swiftLint\",\"message\":\"Closure expressions should have a single space inside each brace.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":41,\"endLine\":41,\"startColumn\":23,\"endColumn\":23,\"rule\":\"comma\",\"category\":\"swiftLint\",\"message\":\"There should be no space before and one after any comma.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":41,\"endLine\":41,\"startColumn\":27,\"endColumn\":27,\"rule\":\"comma\",\"category\":\"swiftLint\",\"message\":\"There should be no space before and one after any comma.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":41,\"endLine\":41,\"startColumn\":29,\"endColumn\":29,\"rule\":\"comma\",\"category\":\"swiftLint\",\"message\":\"There should be no space before and one after any comma.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":44,\"endLine\":44,\"startColumn\":9,\"endColumn\":9,\"rule\":\"control_statement\",\"category\":\"swiftLint\",\"message\":\"`if`, `for`, `guard`, `switch`, `while`, and `catch` statements shouldn't unnecessarily wrap their conditionals or arguments in parentheses.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":47,\"endLine\":47,\"startColumn\":22,\"endColumn\":22,\"rule\":\"discouraged_optional_boolean\",\"category\":\"swiftLint\",\"message\":\"Prefer non-optional booleans over optional booleans.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":6,\"endLine\":6,\"startColumn\":1,\"endColumn\":1,\"rule\":\"duplicate_imports\",\"category\":\"swiftLint\",\"message\":\"Imports should be unique.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":55,\"endLine\":55,\"startColumn\":27,\"endColumn\":27,\"rule\":\"empty_collection_literal\",\"category\":\"swiftLint\",\"message\":\"Prefer checking `isEmpty` over comparing collection to an empty array or dictionary literal.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":59,\"endLine\":59,\"startColumn\":28,\"endColumn\":28,\"rule\":\"empty_count\",\"category\":\"swiftLint\",\"message\":\"Prefer checking `isEmpty` over comparing `count` to zero.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":65,\"endLine\":65,\"startColumn\":23,\"endColumn\":23,\"rule\":\"empty_string\",\"category\":\"swiftLint\",\"message\":\"Prefer checking `isEmpty` over comparing `string` to an empty string literal.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":71,\"endLine\":71,\"startColumn\":13,\"endColumn\":13,\"rule\":\"for_where\",\"category\":\"swiftLint\",\"message\":\"`where` clauses are preferred over a single `if` inside a `for`.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":1,\"endLine\":1,\"startColumn\":0,\"endColumn\":0,\"rule\":\"leading_whitespace\",\"category\":\"swiftLint\",\"message\":\"File shouldn't start with whitespace: currently starts with 2 whitespace characters\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":36,\"endLine\":36,\"startColumn\":0,\"endColumn\":0,\"rule\":\"line_length\",\"category\":\"swiftLint\",\"message\":\"Line should be 120 characters or less: currently 229 characters\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":77,\"endLine\":77,\"startColumn\":15,\"endColumn\":15,\"rule\":\"no_space_in_method_call\",\"category\":\"swiftLint\",\"message\":\"Don't add a space between the method name and the parentheses.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":20,\"endLine\":20,\"startColumn\":33,\"endColumn\":33,\"rule\":\"opening_brace\",\"category\":\"swiftLint\",\"message\":\"Opening braces should be preceded by a single space and on the same line as the declaration.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":83,\"endLine\":83,\"startColumn\":26,\"endColumn\":26,\"rule\":\"opening_brace\",\"category\":\"swiftLint\",\"message\":\"Opening braces should be preceded by a single space and on the same line as the declaration.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":33,\"endLine\":33,\"startColumn\":18,\"endColumn\":18,\"rule\":\"operator_usage_whitespace\",\"category\":\"swiftLint\",\"message\":\"Operators should be surrounded by a single whitespace when they are being used.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":93,\"endLine\":93,\"startColumn\":27,\"endColumn\":27,\"rule\":\"operator_usage_whitespace\",\"category\":\"swiftLint\",\"message\":\"Operators should be surrounded by a single whitespace when they are being used.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":93,\"endLine\":93,\"startColumn\":27,\"endColumn\":27,\"rule\":\"redundant_void_return\",\"category\":\"swiftLint\",\"message\":\"Returning Void in a function declaration is redundant.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":93,\"endLine\":93,\"startColumn\":27,\"endColumn\":27,\"rule\":\"return_arrow_whitespace\",\"category\":\"swiftLint\",\"message\":\"Return arrow and return type should be separated by a single space or on a separate line.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":38,\"endLine\":38,\"startColumn\":9,\"endColumn\":9,\"rule\":\"shorthand_operator\",\"category\":\"swiftLint\",\"message\":\"Prefer shorthand operators (+=, -=, *=, /=) over doing the operation and assigning.\",\"priority\":\"error\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":51,\"endLine\":51,\"startColumn\":9,\"endColumn\":9,\"rule\":\"toggle_bool\",\"category\":\"swiftLint\",\"message\":\"Prefer `someBool.toggle()` over `someBool = !someBool`.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":112,\"endLine\":112,\"startColumn\":0,\"endColumn\":0,\"rule\":\"trailing_newline\",\"category\":\"swiftLint\",\"message\":\"Files should have a single trailing newline.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":19,\"endLine\":19,\"startColumn\":29,\"endColumn\":29,\"rule\":\"trailing_semicolon\",\"category\":\"swiftLint\",\"message\":\"Lines should not have trailing semicolons.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":79,\"endLine\":79,\"startColumn\":21,\"endColumn\":21,\"rule\":\"trailing_semicolon\",\"category\":\"swiftLint\",\"message\":\"Lines should not have trailing semicolons.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":19,\"endLine\":19,\"startColumn\":0,\"endColumn\":0,\"rule\":\"trailing_whitespace\",\"category\":\"swiftLint\",\"message\":\"Lines should not have trailing whitespace.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":20,\"endLine\":20,\"startColumn\":0,\"endColumn\":0,\"rule\":\"trailing_whitespace\",\"category\":\"swiftLint\",\"message\":\"Lines should not have trailing whitespace.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":21,\"endLine\":21,\"startColumn\":0,\"endColumn\":0,\"rule\":\"trailing_whitespace\",\"category\":\"swiftLint\",\"message\":\"Lines should not have trailing whitespace.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":22,\"endLine\":22,\"startColumn\":0,\"endColumn\":0,\"rule\":\"trailing_whitespace\",\"category\":\"swiftLint\",\"message\":\"Lines should not have trailing whitespace.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":102,\"endLine\":102,\"startColumn\":10,\"endColumn\":10,\"rule\":\"type_name\",\"category\":\"swiftLint\",\"message\":\"Type name should be between 3 and 40 characters long: 'A'\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":91,\"endLine\":91,\"startColumn\":0,\"endColumn\":0,\"rule\":\"vertical_whitespace\",\"category\":\"swiftLint\",\"message\":\"Limit vertical whitespace to maximum 2 empty lines. Currently 5.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":56,\"endLine\":56,\"startColumn\":1,\"endColumn\":1,\"rule\":\"vertical_whitespace_closing_braces\",\"category\":\"swiftLint\",\"message\":\"Don't include vertical whitespace (empty line) before closing braces.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":60,\"endLine\":60,\"startColumn\":1,\"endColumn\":1,\"rule\":\"vertical_whitespace_closing_braces\",\"category\":\"swiftLint\",\"message\":\"Don't include vertical whitespace (empty line) before closing braces.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":66,\"endLine\":66,\"startColumn\":1,\"endColumn\":1,\"rule\":\"vertical_whitespace_closing_braces\",\"category\":\"swiftLint\",\"message\":\"Don't include vertical whitespace (empty line) before closing braces.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":72,\"endLine\":72,\"startColumn\":1,\"endColumn\":1,\"rule\":\"vertical_whitespace_closing_braces\",\"category\":\"swiftLint\",\"message\":\"Don't include vertical whitespace (empty line) before closing braces.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":84,\"endLine\":84,\"startColumn\":1,\"endColumn\":1,\"rule\":\"vertical_whitespace_closing_braces\",\"category\":\"swiftLint\",\"message\":\"Don't include vertical whitespace (empty line) before closing braces.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":110,\"endLine\":110,\"startColumn\":1,\"endColumn\":1,\"rule\":\"vertical_whitespace_closing_braces\",\"category\":\"swiftLint\",\"message\":\"Don't include vertical whitespace (empty line) before closing braces.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":9,\"endLine\":9,\"startColumn\":1,\"endColumn\":1,\"rule\":\"vertical_whitespace_opening_braces\",\"category\":\"swiftLint\",\"message\":\"Don't include vertical whitespace (empty line) after opening braces.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":56,\"endLine\":56,\"startColumn\":1,\"endColumn\":1,\"rule\":\"vertical_whitespace_opening_braces\",\"category\":\"swiftLint\",\"message\":\"Don't include vertical whitespace (empty line) after opening braces.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":60,\"endLine\":60,\"startColumn\":1,\"endColumn\":1,\"rule\":\"vertical_whitespace_opening_braces\",\"category\":\"swiftLint\",\"message\":\"Don't include vertical whitespace (empty line) after opening braces.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":66,\"endLine\":66,\"startColumn\":1,\"endColumn\":1,\"rule\":\"vertical_whitespace_opening_braces\",\"category\":\"swiftLint\",\"message\":\"Don't include vertical whitespace (empty line) after opening braces.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":72,\"endLine\":72,\"startColumn\":1,\"endColumn\":1,\"rule\":\"vertical_whitespace_opening_braces\",\"category\":\"swiftLint\",\"message\":\"Don't include vertical whitespace (empty line) after opening braces.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift\",\"startLine\":84,\"endLine\":84,\"startColumn\":1,\"endColumn\":1,\"rule\":\"vertical_whitespace_opening_braces\",\"category\":\"swiftLint\",\"message\":\"Don't include vertical whitespace (empty line) after opening braces.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/Client.swift\",\"startLine\":21,\"endLine\":21,\"startColumn\":30,\"endColumn\":30,\"rule\":\"explicit_init\",\"category\":\"swiftLint\",\"message\":\"Explicitly calling .init() should be avoided.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/Client.swift\",\"startLine\":78,\"endLine\":78,\"startColumn\":0,\"endColumn\":0,\"rule\":\"trailing_newline\",\"category\":\"swiftLint\",\"message\":\"Files should have a single trailing newline.\",\"priority\":\"warning\"},{\"filePath\":\"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/Context.swift\",\"startLine\":6,\"endLine\":6,\"startColumn\":0,\"endColumn\":0,\"rule\":\"trailing_newline\",\"category\":\"swiftLint\",\"message\":\"Files should have a single trailing newline.\",\"priority\":\"warning\"}]}"; - - private static final String EXPECTED_INVALID_FILENAME = "{\"tool\":null,\"issues\":[{\"filePath\":\"cpd_invalid.txt\",\"startLine\":1,\"rule\":\"ExceptionDuringParsing\",\"category\":\"miscellaneous\",\"message\":\"An exception occurred during parsing the report for file cpd_invalid.txt. Exception: java.lang.IllegalArgumentException: File must be xml format\"}]}"; + ReportParser parser = new ReportParser(); + String actual = parser.transformToJSONReport(toolReport); - private static final String EXPECTED_INVALID_XML = "{\"tool\":null,\"issues\":[{\"filePath\":\"invalid_xml.xml\",\"startLine\":1,\"rule\":\"ExceptionDuringParsing\",\"category\":\"miscellaneous\",\"message\":\"An exception occurred during parsing the report for file invalid_xml.xml. Exception: %s\"}]}"; + BufferedReader reader = Files.newBufferedReader(EXPECTED_FOLDER_PATH.resolve(expectedJSONReportFileName)); + String expected = reader.lines().collect(Collectors.joining(System.lineSeparator())); + assertEquals(expected, actual); + } - private static final String EXPECTED_INVALID_NAME = "{\"tool\":null,\"issues\":[{\"filePath\":\"invalid_name.xml\",\"startLine\":1,\"rule\":\"ExceptionDuringParsing\",\"category\":\"miscellaneous\",\"message\":\"An exception occurred during parsing the report for file invalid_name.xml. Exception: de.tum.in.ase.parser.exception.UnsupportedToolException: Tool for identifying tag data not found\"}]}"; + /** + * Compares the parsed JSON report with the expected JSON report + * @param fileName The name of the file contains the report as generated by the different tools + * @param expected The expected output + * @throws ParserException If an exception occurs that is not already handled by the parser itself, e.g. caused by the json-parsing + */ + private void testParserWithString(String fileName, String expected) throws ParserException { + File toolReport = REPORTS_FOLDER_PATH.resolve(fileName).toFile(); - private void testParser(String fileName, String expected) throws ParserException { - File file = new File(fileName); ReportParser parser = new ReportParser(); - String actual = parser.transformToJSONReport(file); + String actual = parser.transformToJSONReport(toolReport); + assertEquals(expected, actual); } @Test - public void testCheckstyleParser() throws ParserException { - testParser("src/test/java/checkstyle-result.xml", EXPECTED_CHECKSTYLE); + public void testCheckstyleParser() throws ParserException, IOException { + testParserWithFile("checkstyle-result.xml", "checkstyle.txt"); } @Test - public void testPMDCPDParser() throws ParserException { - testParser("src/test/java/cpd.xml", EXPECTED_PMD_CPD); + public void testPMDCPDParser() throws ParserException, IOException { + testParserWithFile("cpd.xml", "pmd_cpd.txt"); } @Test - public void testPMDParser() throws ParserException { - testParser("src/test/java/pmd.xml", EXPECTED_PMD); + public void testPMDParser() throws ParserException, IOException { + testParserWithFile("pmd.xml", "pmd.txt"); } @Test - public void testSpotbugsParser() throws ParserException { - testParser("src/test/java/spotbugsXml.xml", EXPECTED_SPOTBUGS); + public void testSpotbugsParser() throws ParserException, IOException { + testParserWithFile("spotbugsXml.xml", "spotbugs.txt"); } @Test - public void testSwiftlintParser() throws ParserException { - testParser("src/test/java/swiftlint-result.xml", EXPECTED_SWIFTLINT); + public void testSwiftlintParser() throws ParserException, IOException { + testParserWithFile("swiftlint-result.xml", "swiftlint.txt"); } @Test - public void testParseInvalidFilename() throws ParserException { - testParser("src/test/java/cpd_invalid.txt", EXPECTED_INVALID_FILENAME); + public void testGCCParser() throws ParserException, IOException { + testParserWithFile("gcc.xml", "gcc.txt"); } @Test - public void testParseInvalidXML() throws ParserException { - String filePath = "src/test/java/invalid_xml.xml"; - Exception exception = assertThrows(SAXParseException.class, () -> XmlUtils.createDocumentBuilder().parse(new File(filePath))); + public void testParseInvalidFilename() throws ParserException, IOException { + testParserWithFile("cpd_invalid.txt", "invalid_filename.txt"); + } + + @Test + public void testParseInvalidXML() throws ParserException, IOException { + Exception exception = assertThrows(SAXParseException.class, + () -> XmlUtils.createDocumentBuilder().parse(new File(REPORTS_FOLDER_PATH.resolve("invalid_xml.xml").toString()))); + + String expectedInvalidXML = Files.newBufferedReader(EXPECTED_FOLDER_PATH.resolve("invalid_xml.txt")).readLine(); // JSON transform escapes quotes, so we need to escape them too - testParser(filePath, String.format(EXPECTED_INVALID_XML, exception.toString().replaceAll("\"", "\\\\\""))); + testParserWithString("invalid_xml.xml", String.format(expectedInvalidXML, exception.toString().replaceAll("\"", "\\\\\""))); } @Test - public void testInvalidName() throws ParserException { - testParser("src/test/java/invalid_name.xml", EXPECTED_INVALID_NAME); + public void testInvalidName() throws ParserException, IOException { + testParserWithFile("invalid_name.xml", "invalid_name.txt"); } } diff --git a/src/test/java/expected/checkstyle.txt b/src/test/java/expected/checkstyle.txt new file mode 100644 index 0000000..a9ad067 --- /dev/null +++ b/src/test/java/expected/checkstyle.txt @@ -0,0 +1 @@ +{"tool":"CHECKSTYLE","issues":[{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":6,"endLine":6,"startColumn":8,"endColumn":8,"rule":"UnusedImportsCheck","category":"imports","message":"Unused import - javax.swing.JFrame.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":7,"endLine":7,"startColumn":1,"endColumn":1,"rule":"RedundantImportCheck","category":"imports","message":"Redundant import from the java.lang package - java.lang.*.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":65,"endLine":65,"startColumn":0,"endColumn":0,"rule":"RegexpSinglelineCheck","category":"regexp","message":"Line has trailing spaces.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":68,"endLine":68,"startColumn":0,"endColumn":0,"rule":"RegexpSinglelineCheck","category":"regexp","message":"Line has trailing spaces.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":70,"endLine":70,"startColumn":0,"endColumn":0,"rule":"RegexpSinglelineCheck","category":"regexp","message":"Line has trailing spaces.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":70,"endLine":70,"startColumn":9,"endColumn":9,"rule":"NeedBracesCheck","category":"blocks","message":"'for' construct must use '{}'s.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":73,"endLine":73,"startColumn":0,"endColumn":0,"rule":"RegexpSinglelineCheck","category":"regexp","message":"Line has trailing spaces.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":76,"endLine":76,"startColumn":0,"endColumn":0,"rule":"RegexpSinglelineCheck","category":"regexp","message":"Line has trailing spaces.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":78,"endLine":78,"startColumn":8,"endColumn":8,"rule":"JavadocMethodCheck","category":"javadoc","message":"Unused @param tag for 'x1'.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":80,"endLine":80,"startColumn":0,"endColumn":0,"rule":"JavadocMethodCheck","category":"javadoc","message":"@return tag should be present and have description.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":80,"endLine":80,"startColumn":31,"endColumn":31,"rule":"MethodNameCheck","category":"naming","message":"Name 'CreateRandomDatesList' must match pattern '^[a-z][a-zA-Z0-9]*$'.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":93,"endLine":93,"startColumn":9,"endColumn":9,"rule":"EmptyStatementCheck","category":"coding","message":"Empty statement.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":93,"endLine":93,"startColumn":10,"endColumn":10,"rule":"EmptyStatementCheck","category":"coding","message":"Empty statement.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":93,"endLine":93,"startColumn":11,"endColumn":11,"rule":"EmptyStatementCheck","category":"coding","message":"Empty statement.","priority":"error"}]} diff --git a/src/test/java/expected/gcc.txt b/src/test/java/expected/gcc.txt new file mode 100644 index 0000000..7b0d782 --- /dev/null +++ b/src/test/java/expected/gcc.txt @@ -0,0 +1 @@ +{"tool":"GCC","issues":[{"filePath":"ascii_table.c","startLine":7,"endLine":7,"startColumn":13,"endColumn":13,"rule":"[-Wunused-but-set-variable]","category":"Misc","message":"[-Wunused-but-set-variable]: variable ‘arr’ set but not used \n 7 | int arr[5];\n | ^~~\n ascii_table.c: In function ‘decimal_to_hexadecimal’:","priority":"warning"},{"filePath":"ascii_table.c","startLine":32,"endLine":32,"startColumn":15,"endColumn":15,"rule":"[-Wimplicit-function-declaration]","category":"Misc","message":"[-Wimplicit-function-declaration]: implicit declaration of function ‘malloc’ \n 32 | ptr = malloc(sizeof(int));\n | ^~~~~~","priority":"warning"},{"filePath":"ascii_table.c","startLine":32,"endLine":32,"startColumn":15,"endColumn":15,"rule":"[-Wbuiltin-declaration-mismatch]","category":"Misc","message":"[-Wbuiltin-declaration-mismatch]: incompatible implicit declaration of built-in function ‘malloc’ \n 32 | ptr = malloc(sizeof(int));\n | ^~~~~~","priority":"warning"},{"filePath":"ascii_table.c","startLine":31,"endLine":31,"startColumn":14,"endColumn":14,"rule":"[-Wunused-but-set-variable]","category":"Misc","message":"[-Wunused-but-set-variable]: variable ‘ptr’ set but not used \n 31 | int *ptr;\n | ^~~","priority":"warning"},{"filePath":"ascii_table.c","startLine":40,"endLine":40,"startColumn":16,"endColumn":16,"rule":"[-Wanalyzer-malloc-leak]","category":"Memory","message":"[-Wanalyzer-malloc-leak]: leak of ‘ptr’ [CWE-401] \n 40 | return hex_num;\n | ^~~~~~~\n ‘decimal_to_hexadecimal’: events 1-4\n |\n | 32 | ptr = malloc(sizeof(int));\n | | ^~~~~~~~~~~~~~~~~~~\n | | |\n | | (1) allocated here\n | 33 |\n | 34 | for (int i = 0; dec_num != 0; i++) {\n | | ~~~~~~~~~~~~\n | | |\n | | (2) following ‘false’ branch (when ‘dec_num == 0’)...\n |......\n | 40 | return hex_num;\n | | ~~~~~~~\n | | |\n | | (3) ...to here\n | | (4) ‘ptr’ leaks here; was allocated at (1)\n |\n","priority":"warning"}]} diff --git a/src/test/java/expected/invalid_filename.txt b/src/test/java/expected/invalid_filename.txt new file mode 100644 index 0000000..208c631 --- /dev/null +++ b/src/test/java/expected/invalid_filename.txt @@ -0,0 +1 @@ +{"tool":null,"issues":[{"filePath":"cpd_invalid.txt","startLine":1,"rule":"ExceptionDuringParsing","category":"miscellaneous","message":"An exception occurred during parsing the report for file cpd_invalid.txt. Exception: java.lang.IllegalArgumentException: File must be xml format"}]} diff --git a/src/test/java/expected/invalid_name.txt b/src/test/java/expected/invalid_name.txt new file mode 100644 index 0000000..8415833 --- /dev/null +++ b/src/test/java/expected/invalid_name.txt @@ -0,0 +1 @@ +{"tool":null,"issues":[{"filePath":"invalid_name.xml","startLine":1,"rule":"ExceptionDuringParsing","category":"miscellaneous","message":"An exception occurred during parsing the report for file invalid_name.xml. Exception: de.tum.in.ase.parser.exception.UnsupportedToolException: Tool for identifying tag data not found"}]} diff --git a/src/test/java/expected/invalid_xml.txt b/src/test/java/expected/invalid_xml.txt new file mode 100644 index 0000000..8fdb8d4 --- /dev/null +++ b/src/test/java/expected/invalid_xml.txt @@ -0,0 +1 @@ +{"tool":null,"issues":[{"filePath":"invalid_xml.xml","startLine":1,"rule":"ExceptionDuringParsing","category":"miscellaneous","message":"An exception occurred during parsing the report for file invalid_xml.xml. Exception: %s"}]} diff --git a/src/test/java/expected/pmd.txt b/src/test/java/expected/pmd.txt new file mode 100644 index 0000000..b57cc60 --- /dev/null +++ b/src/test/java/expected/pmd.txt @@ -0,0 +1 @@ +{"tool":"PMD","issues":[{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":6,"endLine":6,"startColumn":1,"endColumn":26,"rule":"UnusedImports","category":"Best Practices","message":"Avoid unused imports such as 'javax.swing.JFrame'","priority":"4"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":7,"endLine":7,"startColumn":1,"endColumn":19,"rule":"DontImportJavaLang","category":"Code Style","message":"Avoid importing anything from the package java.lang","priority":"4"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":7,"endLine":7,"startColumn":1,"endColumn":19,"rule":"UnusedImports","category":"Best Practices","message":"Avoid unused imports such as 'java.lang'","priority":"4"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":73,"endLine":73,"startColumn":18,"endColumn":27,"rule":"UnusedLocalVariable","category":"Best Practices","message":"Avoid unused local variables such as 'randomDate'.","priority":"3"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":81,"endLine":81,"startColumn":31,"endColumn":53,"rule":"UnusedPrivateMethod","category":"Best Practices","message":"Avoid unused private methods such as 'CreateRandomDatesList()'.","priority":"3"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":94,"endLine":94,"startColumn":9,"endColumn":9,"rule":"EmptyStatementNotInLoop","category":"Error Prone","message":"An empty statement (semicolon) not part of a loop","priority":"3"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":94,"endLine":94,"startColumn":10,"endColumn":10,"rule":"EmptyStatementNotInLoop","category":"Error Prone","message":"An empty statement (semicolon) not part of a loop","priority":"3"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":94,"endLine":94,"startColumn":11,"endColumn":11,"rule":"EmptyStatementNotInLoop","category":"Error Prone","message":"An empty statement (semicolon) not part of a loop","priority":"3"}]} diff --git a/src/test/java/expected/pmd_cpd.txt b/src/test/java/expected/pmd_cpd.txt new file mode 100644 index 0000000..6b495bc --- /dev/null +++ b/src/test/java/expected/pmd_cpd.txt @@ -0,0 +1 @@ +{"tool":"PMD_CPD","issues":[{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":60,"endLine":75,"startColumn":52,"endColumn":18,"rule":"Copy/Paste Detection","category":"Copy/Paste Detection","message":"Code duplication of 16 lines in the following files:\n1. Client.java:60-75\n2. Client.java:75-97"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":75,"endLine":97,"startColumn":53,"endColumn":18,"rule":"Copy/Paste Detection","category":"Copy/Paste Detection","message":"Code duplication of 16 lines in the following files:\n1. Client.java:60-75\n2. Client.java:75-97"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/BubbleSort.java","startLine":13,"endLine":24,"startColumn":9,"endColumn":9,"rule":"Copy/Paste Detection","category":"Copy/Paste Detection","message":"Code duplication of 12 lines in the following files:\n1. BubbleSort.java:13-24\n2. BubbleSort.java:25-36"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/BubbleSort.java","startLine":25,"endLine":36,"startColumn":9,"endColumn":9,"rule":"Copy/Paste Detection","category":"Copy/Paste Detection","message":"Code duplication of 12 lines in the following files:\n1. BubbleSort.java:13-24\n2. BubbleSort.java:25-36"}]} diff --git a/src/test/java/expected/spotbugs.txt b/src/test/java/expected/spotbugs.txt new file mode 100644 index 0000000..c10146e --- /dev/null +++ b/src/test/java/expected/spotbugs.txt @@ -0,0 +1 @@ +{"tool":"SPOTBUGS","issues":[{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":73,"endLine":73,"rule":"DLS_DEAD_LOCAL_STORE","category":"STYLE","message":"Dead store to randomDate in code.Client.createRandomDatesList()","priority":"2"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":82,"endLine":95,"rule":"NM_METHOD_NAMING_CONVENTION","category":"BAD_PRACTICE","message":"The method name code.Client.CreateRandomDatesList() doesn't start with a lower case letter","priority":"3"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTCODE-ARTEMISTESTUSER1-JOB1/assignment/src/code/Client.java","startLine":82,"endLine":95,"rule":"UPM_UNCALLED_PRIVATE_METHOD","category":"PERFORMANCE","message":"Private method code.Client.CreateRandomDatesList() is never called","priority":"2"}]} diff --git a/src/test/java/expected/swiftlint.txt b/src/test/java/expected/swiftlint.txt new file mode 100644 index 0000000..4f73232 --- /dev/null +++ b/src/test/java/expected/swiftlint.txt @@ -0,0 +1 @@ +{"tool":"SWIFTLINT","issues":[{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":20,"endLine":20,"startColumn":21,"endColumn":21,"rule":"array_init","category":"swiftLint","message":"Prefer using `Array(seq)` over `seq.map { $0 }` to convert a sequence into an Array.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":25,"endLine":25,"startColumn":38,"endColumn":38,"rule":"closing_brace","category":"swiftLint","message":"Closing brace with closing parenthesis should not have any whitespaces in the middle.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":22,"endLine":22,"startColumn":15,"endColumn":15,"rule":"closure_end_indentation","category":"swiftLint","message":"Closure end should have the same indentation as the line that started it. Expected 8, got 14.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":44,"endLine":44,"startColumn":21,"endColumn":21,"rule":"closure_spacing","category":"swiftLint","message":"Closure expressions should have a single space inside each brace.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":41,"endLine":41,"startColumn":23,"endColumn":23,"rule":"comma","category":"swiftLint","message":"There should be no space before and one after any comma.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":41,"endLine":41,"startColumn":27,"endColumn":27,"rule":"comma","category":"swiftLint","message":"There should be no space before and one after any comma.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":41,"endLine":41,"startColumn":29,"endColumn":29,"rule":"comma","category":"swiftLint","message":"There should be no space before and one after any comma.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":44,"endLine":44,"startColumn":9,"endColumn":9,"rule":"control_statement","category":"swiftLint","message":"`if`, `for`, `guard`, `switch`, `while`, and `catch` statements shouldn't unnecessarily wrap their conditionals or arguments in parentheses.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":47,"endLine":47,"startColumn":22,"endColumn":22,"rule":"discouraged_optional_boolean","category":"swiftLint","message":"Prefer non-optional booleans over optional booleans.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":6,"endLine":6,"startColumn":1,"endColumn":1,"rule":"duplicate_imports","category":"swiftLint","message":"Imports should be unique.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":55,"endLine":55,"startColumn":27,"endColumn":27,"rule":"empty_collection_literal","category":"swiftLint","message":"Prefer checking `isEmpty` over comparing collection to an empty array or dictionary literal.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":59,"endLine":59,"startColumn":28,"endColumn":28,"rule":"empty_count","category":"swiftLint","message":"Prefer checking `isEmpty` over comparing `count` to zero.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":65,"endLine":65,"startColumn":23,"endColumn":23,"rule":"empty_string","category":"swiftLint","message":"Prefer checking `isEmpty` over comparing `string` to an empty string literal.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":71,"endLine":71,"startColumn":13,"endColumn":13,"rule":"for_where","category":"swiftLint","message":"`where` clauses are preferred over a single `if` inside a `for`.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":1,"endLine":1,"startColumn":0,"endColumn":0,"rule":"leading_whitespace","category":"swiftLint","message":"File shouldn't start with whitespace: currently starts with 2 whitespace characters","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":36,"endLine":36,"startColumn":0,"endColumn":0,"rule":"line_length","category":"swiftLint","message":"Line should be 120 characters or less: currently 229 characters","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":77,"endLine":77,"startColumn":15,"endColumn":15,"rule":"no_space_in_method_call","category":"swiftLint","message":"Don't add a space between the method name and the parentheses.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":20,"endLine":20,"startColumn":33,"endColumn":33,"rule":"opening_brace","category":"swiftLint","message":"Opening braces should be preceded by a single space and on the same line as the declaration.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":83,"endLine":83,"startColumn":26,"endColumn":26,"rule":"opening_brace","category":"swiftLint","message":"Opening braces should be preceded by a single space and on the same line as the declaration.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":33,"endLine":33,"startColumn":18,"endColumn":18,"rule":"operator_usage_whitespace","category":"swiftLint","message":"Operators should be surrounded by a single whitespace when they are being used.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":93,"endLine":93,"startColumn":27,"endColumn":27,"rule":"operator_usage_whitespace","category":"swiftLint","message":"Operators should be surrounded by a single whitespace when they are being used.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":93,"endLine":93,"startColumn":27,"endColumn":27,"rule":"redundant_void_return","category":"swiftLint","message":"Returning Void in a function declaration is redundant.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":93,"endLine":93,"startColumn":27,"endColumn":27,"rule":"return_arrow_whitespace","category":"swiftLint","message":"Return arrow and return type should be separated by a single space or on a separate line.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":38,"endLine":38,"startColumn":9,"endColumn":9,"rule":"shorthand_operator","category":"swiftLint","message":"Prefer shorthand operators (+=, -=, *=, /=) over doing the operation and assigning.","priority":"error"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":51,"endLine":51,"startColumn":9,"endColumn":9,"rule":"toggle_bool","category":"swiftLint","message":"Prefer `someBool.toggle()` over `someBool = !someBool`.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":112,"endLine":112,"startColumn":0,"endColumn":0,"rule":"trailing_newline","category":"swiftLint","message":"Files should have a single trailing newline.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":19,"endLine":19,"startColumn":29,"endColumn":29,"rule":"trailing_semicolon","category":"swiftLint","message":"Lines should not have trailing semicolons.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":79,"endLine":79,"startColumn":21,"endColumn":21,"rule":"trailing_semicolon","category":"swiftLint","message":"Lines should not have trailing semicolons.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":19,"endLine":19,"startColumn":0,"endColumn":0,"rule":"trailing_whitespace","category":"swiftLint","message":"Lines should not have trailing whitespace.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":20,"endLine":20,"startColumn":0,"endColumn":0,"rule":"trailing_whitespace","category":"swiftLint","message":"Lines should not have trailing whitespace.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":21,"endLine":21,"startColumn":0,"endColumn":0,"rule":"trailing_whitespace","category":"swiftLint","message":"Lines should not have trailing whitespace.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":22,"endLine":22,"startColumn":0,"endColumn":0,"rule":"trailing_whitespace","category":"swiftLint","message":"Lines should not have trailing whitespace.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":102,"endLine":102,"startColumn":10,"endColumn":10,"rule":"type_name","category":"swiftLint","message":"Type name should be between 3 and 40 characters long: 'A'","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":91,"endLine":91,"startColumn":0,"endColumn":0,"rule":"vertical_whitespace","category":"swiftLint","message":"Limit vertical whitespace to maximum 2 empty lines. Currently 5.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":56,"endLine":56,"startColumn":1,"endColumn":1,"rule":"vertical_whitespace_closing_braces","category":"swiftLint","message":"Don't include vertical whitespace (empty line) before closing braces.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":60,"endLine":60,"startColumn":1,"endColumn":1,"rule":"vertical_whitespace_closing_braces","category":"swiftLint","message":"Don't include vertical whitespace (empty line) before closing braces.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":66,"endLine":66,"startColumn":1,"endColumn":1,"rule":"vertical_whitespace_closing_braces","category":"swiftLint","message":"Don't include vertical whitespace (empty line) before closing braces.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":72,"endLine":72,"startColumn":1,"endColumn":1,"rule":"vertical_whitespace_closing_braces","category":"swiftLint","message":"Don't include vertical whitespace (empty line) before closing braces.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":84,"endLine":84,"startColumn":1,"endColumn":1,"rule":"vertical_whitespace_closing_braces","category":"swiftLint","message":"Don't include vertical whitespace (empty line) before closing braces.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":110,"endLine":110,"startColumn":1,"endColumn":1,"rule":"vertical_whitespace_closing_braces","category":"swiftLint","message":"Don't include vertical whitespace (empty line) before closing braces.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":9,"endLine":9,"startColumn":1,"endColumn":1,"rule":"vertical_whitespace_opening_braces","category":"swiftLint","message":"Don't include vertical whitespace (empty line) after opening braces.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":56,"endLine":56,"startColumn":1,"endColumn":1,"rule":"vertical_whitespace_opening_braces","category":"swiftLint","message":"Don't include vertical whitespace (empty line) after opening braces.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":60,"endLine":60,"startColumn":1,"endColumn":1,"rule":"vertical_whitespace_opening_braces","category":"swiftLint","message":"Don't include vertical whitespace (empty line) after opening braces.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":66,"endLine":66,"startColumn":1,"endColumn":1,"rule":"vertical_whitespace_opening_braces","category":"swiftLint","message":"Don't include vertical whitespace (empty line) after opening braces.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":72,"endLine":72,"startColumn":1,"endColumn":1,"rule":"vertical_whitespace_opening_braces","category":"swiftLint","message":"Don't include vertical whitespace (empty line) after opening braces.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/BubbleSort.swift","startLine":84,"endLine":84,"startColumn":1,"endColumn":1,"rule":"vertical_whitespace_opening_braces","category":"swiftLint","message":"Don't include vertical whitespace (empty line) after opening braces.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/Client.swift","startLine":21,"endLine":21,"startColumn":30,"endColumn":30,"rule":"explicit_init","category":"swiftLint","message":"Explicitly calling .init() should be avoided.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/Client.swift","startLine":78,"endLine":78,"startColumn":0,"endColumn":0,"rule":"trailing_newline","category":"swiftLint","message":"Files should have a single trailing newline.","priority":"warning"},{"filePath":"/opt/bambooagent/bamboo-agent-home/xml-data/build-dir/MDTESTSWIFT-ARTEMISTESTUSER50-JOB1/assignment/Sources/swiftLib/Context.swift","startLine":6,"endLine":6,"startColumn":0,"endColumn":0,"rule":"trailing_newline","category":"swiftLint","message":"Files should have a single trailing newline.","priority":"warning"}]} diff --git a/src/test/java/checkstyle-result.xml b/src/test/java/reports/checkstyle-result.xml similarity index 100% rename from src/test/java/checkstyle-result.xml rename to src/test/java/reports/checkstyle-result.xml diff --git a/src/test/java/cpd.xml b/src/test/java/reports/cpd.xml similarity index 100% rename from src/test/java/cpd.xml rename to src/test/java/reports/cpd.xml diff --git a/src/test/java/cpd_invalid.txt b/src/test/java/reports/cpd_invalid.txt similarity index 100% rename from src/test/java/cpd_invalid.txt rename to src/test/java/reports/cpd_invalid.txt diff --git a/src/test/java/reports/gcc.xml b/src/test/java/reports/gcc.xml new file mode 100644 index 0000000..4c6cce7 --- /dev/null +++ b/src/test/java/reports/gcc.xml @@ -0,0 +1,43 @@ + + + ascii_table.c: In function ‘power’: + ascii_table.c:7:13: warning: variable ‘arr’ set but not used [-Wunused-but-set-variable] + 7 | int arr[5]; + | ^~~ + ascii_table.c: In function ‘decimal_to_hexadecimal’: + ascii_table.c:32:15: warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration] + 32 | ptr = malloc(sizeof(int)); + | ^~~~~~ + ascii_table.c:2:1: note: include ‘<stdlib.h>’ or provide a declaration of ‘malloc’ + 1 | #include <stdio.h> + +++ |+#include <stdlib.h> + 2 | + ascii_table.c:32:15: warning: incompatible implicit declaration of built-in function ‘malloc’ [-Wbuiltin-declaration-mismatch] + 32 | ptr = malloc(sizeof(int)); + | ^~~~~~ + ascii_table.c:32:15: note: include ‘<stdlib.h>’ or provide a declaration of ‘malloc’ + ascii_table.c:31:14: warning: variable ‘ptr’ set but not used [-Wunused-but-set-variable] + 31 | int *ptr; + | ^~~ + ascii_table.c:40:16: warning: leak of ‘ptr’ [CWE-401] [-Wanalyzer-malloc-leak] + 40 | return hex_num; + | ^~~~~~~ + ‘decimal_to_hexadecimal’: events 1-4 + | + | 32 | ptr = malloc(sizeof(int)); + | | ^~~~~~~~~~~~~~~~~~~ + | | | + | | (1) allocated here + | 33 | + | 34 | for (int i = 0; dec_num != 0; i++) { + | | ~~~~~~~~~~~~ + | | | + | | (2) following ‘false’ branch (when ‘dec_num == 0’)... + |...... + | 40 | return hex_num; + | | ~~~~~~~ + | | | + | | (3) ...to here + | | (4) ‘ptr’ leaks here; was allocated at (1) + | + diff --git a/src/test/java/invalid_name.xml b/src/test/java/reports/invalid_name.xml similarity index 100% rename from src/test/java/invalid_name.xml rename to src/test/java/reports/invalid_name.xml diff --git a/src/test/java/invalid_xml.xml b/src/test/java/reports/invalid_xml.xml similarity index 100% rename from src/test/java/invalid_xml.xml rename to src/test/java/reports/invalid_xml.xml diff --git a/src/test/java/pmd.xml b/src/test/java/reports/pmd.xml similarity index 100% rename from src/test/java/pmd.xml rename to src/test/java/reports/pmd.xml diff --git a/src/test/java/spotbugsXml.xml b/src/test/java/reports/spotbugsXml.xml similarity index 100% rename from src/test/java/spotbugsXml.xml rename to src/test/java/reports/spotbugsXml.xml diff --git a/src/test/java/swiftlint-result.xml b/src/test/java/reports/swiftlint-result.xml similarity index 100% rename from src/test/java/swiftlint-result.xml rename to src/test/java/reports/swiftlint-result.xml