File indexing completed on 2024-05-05 04:35:28

0001 /*
0002  * This file is part of KDevelop Krazy2 Plugin.
0003  *
0004  * Copyright 2012 Daniel Calviño Sánchez <danxuliu@gmail.com>
0005  *
0006  * This program is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU General Public License
0008  * as published by the Free Software Foundation; either version 2
0009  * of the License, or (at your option) any later version.
0010  *
0011  * This program is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014  * GNU General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU General Public License
0017  * along with this program. If not, see <http://www.gnu.org/licenses/>.
0018  */
0019 
0020 #include <QTest>
0021 
0022 #include "../analysisresultsparser.h"
0023 #include "../analysisresults.h"
0024 #include "../checker.h"
0025 #include "../issue.h"
0026 
0027 #include <time.h>
0028 
0029 class AnalysisResultsParserTest: public QObject {
0030 Q_OBJECT
0031 private slots:
0032 
0033     void init();
0034     void cleanup();
0035 
0036     void testParseNoChecker();
0037     void testParseSingleCheckerNoIssues();
0038     void testParseSingleCheckerSingleFileSingleIssue();
0039     void testParseSingleCheckerSingleFileSingleIssueNoMessage();
0040     void testParseSingleCheckerSingleFileSingleIssueWithDetails();
0041     void testParseSingleCheckerSingleFileSingleIssueWithMessageAndDetails();
0042     void testParseSingleCheckerSingleFileSingleIssueNonAsciiFilename();
0043     void testParseSingleCheckerSingleFileSeveralIssues();
0044     void testParseSingleCheckerSingleFileSeveralIssuesNoMessage();
0045     void testParseSingleCheckerSingleFileSeveralIssuesWithDetails();
0046     void testParseSingleCheckerSeveralFiles();
0047     void testParseSeveralCheckers();
0048     void testParseSeveralFileTypes();
0049 
0050     void testParseSingleCheckerSingleFileSeveralIssuesIssueWithoutMessageAfterIssueWithDetails();
0051     void testParseSingleCheckerSeveralFilesSingleIssueWithoutMessageAfterSingleIssueWithMessage();
0052 
0053     void testParseSingleCheckerExplanationEndingWithNewLine();
0054 
0055     void testParseSingleCheckerNoDescription();
0056     void testParseSingleCheckerNoExplanation();
0057 
0058     void testParseWithDataInSeveralChunks();
0059 
0060     void testParseWhenAnalysisResultsHasPreviousContents();
0061 
0062 private:
0063 
0064     void assertChecker(int index, const QString& name, const QString& description,
0065                        const QString& explanation, const QString& fileType) const;
0066     void assertIssue(int index, const QString& message, const QString& fileName,
0067                      int line) const;
0068 
0069     AnalysisResultsParser* m_analysisResultsParser;
0070     AnalysisResults* m_analysisResults;
0071 
0072 };
0073 
0074 #define KRAZY2_HEADER_XML \
0075     "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"\
0076     "<tool-result tool=\"krazy2\">\n"\
0077         "<global>\n"\
0078             "<date value=\"September 22 2004 04:16:42 UTC\"/>\n"\
0079             "<processed-files value=\"ignored\"/>\n"\
0080         "</global>\n"\
0081         "<file-types>\n"
0082 
0083 #define KRAZY2_FOOTER_XML \
0084         "</file-types>\n"\
0085     "</tool-result>\n"
0086 
0087 #define KRAZY2_FILETYPE_SINGLE_CHECKER_START_XML \
0088     "<file-type value=\"fileType\">\n"\
0089         "<check desc=\"Checker description [checkerName]...\">\n"
0090 
0091 #define KRAZY2_FILETYPE_SINGLE_CHECKER_END_XML \
0092             "<explanation>Checker explanation</explanation>\n"\
0093         "</check>\n"\
0094     "</file-type>\n"
0095 
0096 #define KRAZY2_FILE_SINGLE_ISSUE_XML \
0097     "<file name=\"singleIssueFile.cpp\">\n"\
0098         "<message>single issue message</message>\n"\
0099         "<issues>\n"\
0100             "<line>-1</line>\n"\
0101         "</issues>\n"\
0102     "</file>\n"
0103 
0104 #define KRAZY2_FILE_SINGLE_ISSUE_NO_MESSAGE_XML \
0105     "<file name=\"singleIssueNoMessageFile.cpp\">\n"\
0106         "<issues>\n"\
0107             "<line>423</line>\n"\
0108         "</issues>\n"\
0109     "</file>\n"
0110 
0111 #define KRAZY2_FILE_SINGLE_ISSUE_WITH_DETAILS_XML \
0112     "<file name=\"singleIssueWithDetailsFile.cpp\">\n"\
0113         "<issues>\n"\
0114             "<line issue=\"[details]\">4</line>\n"\
0115         "</issues>\n"\
0116     "</file>\n"
0117 
0118 #define KRAZY2_FILE_SINGLE_ISSUE_WITH_MESSAGE_AND_DETAILS_XML \
0119     "<file name=\"singleIssueWithMessageAndDetailsFile.cpp\">\n"\
0120         "<message>single issue message</message>\n"\
0121         "<issues>\n"\
0122             "<line issue=\"[details]\">4</line>\n"\
0123         "</issues>\n"\
0124     "</file>\n"
0125 
0126 #define KRAZY2_FILE_SINGLE_ISSUE_NON_ASCII_FILE_NAME_XML \
0127     "<file name=\"singleIssueFileNonAsciiFileNameḶḷambión.cpp\">\n"\
0128         "<message>single issue message</message>\n"\
0129         "<issues>\n"\
0130             "<line>-1</line>\n"\
0131         "</issues>\n"\
0132     "</file>\n"
0133 
0134 #define KRAZY2_FILE_SEVERAL_ISSUES_XML \
0135     "<file name=\"severalIssuesFile.cpp\">\n"\
0136         "<message>several issues message</message>\n"\
0137         "<issues>\n"\
0138             "<line>8</line>\n"\
0139             "<line>15</line>\n"\
0140             "<line>16</line>\n"\
0141         "</issues>\n"\
0142     "</file>\n"
0143 
0144 #define KRAZY2_FILE_SEVERAL_ISSUES_NO_MESSAGE_XML \
0145     "<file name=\"severalIssuesNoMessageFile.cpp\">\n"\
0146         "<issues>\n"\
0147             "<line>815</line>\n"\
0148             "<line>1516</line>\n"\
0149             "<line>1623</line>\n"\
0150         "</issues>\n"\
0151     "</file>\n"
0152 
0153 #define KRAZY2_FILE_SEVERAL_ISSUES_WITH_DETAILS_XML \
0154     "<file name=\"severalIssuesWithDetailsFile.cpp\">\n"\
0155         "<issues>\n"\
0156             "<line issue=\"details1\">23</line>\n"\
0157             "<line issue=\"details2\">42</line>\n"\
0158             "<line issue=\"details3\">108</line>\n"\
0159         "</issues>\n"\
0160     "</file>\n"
0161 
0162 void AnalysisResultsParserTest::init() {
0163     m_analysisResultsParser = new AnalysisResultsParser();
0164     m_analysisResults = new AnalysisResults();
0165     m_analysisResultsParser->setAnalysisResults(m_analysisResults);
0166 }
0167 
0168 void AnalysisResultsParserTest::cleanup() {
0169     delete m_analysisResults;
0170     delete m_analysisResultsParser;
0171 }
0172 
0173 void AnalysisResultsParserTest::testParseNoChecker() {
0174     QByteArray data =
0175         KRAZY2_HEADER_XML
0176         KRAZY2_FOOTER_XML;
0177 
0178     m_analysisResultsParser->parse(data);
0179 
0180     QCOMPARE(m_analysisResults->issues().size(), 0);
0181 }
0182 
0183 void AnalysisResultsParserTest::testParseSingleCheckerNoIssues() {
0184     QByteArray data =
0185         KRAZY2_HEADER_XML
0186         "<file-type value=\"fileType\">\n"
0187             "<check desc=\"Checker description [checkerName]...\">\n"
0188             "</check>\n"
0189         "</file-type>\n"
0190         KRAZY2_FOOTER_XML;
0191 
0192     m_analysisResultsParser->parse(data);
0193 
0194     QCOMPARE(m_analysisResults->issues().size(), 0);
0195 }
0196 
0197 void AnalysisResultsParserTest::testParseSingleCheckerSingleFileSingleIssue() {
0198     QByteArray data =
0199         KRAZY2_HEADER_XML
0200             KRAZY2_FILETYPE_SINGLE_CHECKER_START_XML
0201                 KRAZY2_FILE_SINGLE_ISSUE_XML
0202             KRAZY2_FILETYPE_SINGLE_CHECKER_END_XML
0203         KRAZY2_FOOTER_XML;
0204 
0205     m_analysisResultsParser->parse(data);
0206 
0207     QCOMPARE(m_analysisResults->issues().size(), 1);
0208     assertIssue(0, "single issue message", "singleIssueFile.cpp", -1);
0209     assertChecker(0, "checkerName", "Checker description", "Checker explanation", "fileType");
0210 }
0211 
0212 void AnalysisResultsParserTest::testParseSingleCheckerSingleFileSingleIssueNoMessage() {
0213     QByteArray data =
0214         KRAZY2_HEADER_XML
0215             KRAZY2_FILETYPE_SINGLE_CHECKER_START_XML
0216                 KRAZY2_FILE_SINGLE_ISSUE_NO_MESSAGE_XML
0217             KRAZY2_FILETYPE_SINGLE_CHECKER_END_XML
0218         KRAZY2_FOOTER_XML;
0219 
0220     m_analysisResultsParser->parse(data);
0221 
0222     QCOMPARE(m_analysisResults->issues().size(), 1);
0223     assertIssue(0, "", "singleIssueNoMessageFile.cpp", 423);
0224     assertChecker(0, "checkerName", "Checker description", "Checker explanation", "fileType");
0225 }
0226 
0227 void AnalysisResultsParserTest::testParseSingleCheckerSingleFileSingleIssueWithDetails() {
0228     QByteArray data =
0229         KRAZY2_HEADER_XML
0230             KRAZY2_FILETYPE_SINGLE_CHECKER_START_XML
0231                 KRAZY2_FILE_SINGLE_ISSUE_WITH_DETAILS_XML
0232             KRAZY2_FILETYPE_SINGLE_CHECKER_END_XML
0233         KRAZY2_FOOTER_XML;
0234 
0235     m_analysisResultsParser->parse(data);
0236 
0237     QCOMPARE(m_analysisResults->issues().size(), 1);
0238     assertIssue(0, "details", "singleIssueWithDetailsFile.cpp", 4);
0239     assertChecker(0, "checkerName", "Checker description", "Checker explanation", "fileType");
0240 }
0241 
0242 void AnalysisResultsParserTest::testParseSingleCheckerSingleFileSingleIssueWithMessageAndDetails() {
0243     QByteArray data =
0244         KRAZY2_HEADER_XML
0245             KRAZY2_FILETYPE_SINGLE_CHECKER_START_XML
0246                 KRAZY2_FILE_SINGLE_ISSUE_WITH_MESSAGE_AND_DETAILS_XML
0247             KRAZY2_FILETYPE_SINGLE_CHECKER_END_XML
0248         KRAZY2_FOOTER_XML;
0249 
0250     m_analysisResultsParser->parse(data);
0251 
0252     QCOMPARE(m_analysisResults->issues().size(), 1);
0253     assertIssue(0, "details", "singleIssueWithMessageAndDetailsFile.cpp", 4);
0254     assertChecker(0, "checkerName", "Checker description", "Checker explanation", "fileType");
0255 }
0256 
0257 void AnalysisResultsParserTest::testParseSingleCheckerSingleFileSingleIssueNonAsciiFilename() {
0258     //This source file is UTF-8 encoded, just like krazy2 XML output
0259     QByteArray data =
0260         KRAZY2_HEADER_XML
0261             KRAZY2_FILETYPE_SINGLE_CHECKER_START_XML
0262                 KRAZY2_FILE_SINGLE_ISSUE_NON_ASCII_FILE_NAME_XML
0263             KRAZY2_FILETYPE_SINGLE_CHECKER_END_XML
0264         KRAZY2_FOOTER_XML;
0265 
0266     m_analysisResultsParser->parse(data);
0267 
0268     QCOMPARE(m_analysisResults->issues().size(), 1);
0269     assertIssue(0, "single issue message", QString::fromUtf8("singleIssueFileNonAsciiFileNameḶḷambión.cpp"), -1);
0270     assertChecker(0, "checkerName", "Checker description", "Checker explanation", "fileType");
0271 }
0272 
0273 void AnalysisResultsParserTest::testParseSingleCheckerSingleFileSeveralIssues() {
0274     QByteArray data =
0275         KRAZY2_HEADER_XML
0276             KRAZY2_FILETYPE_SINGLE_CHECKER_START_XML
0277                 KRAZY2_FILE_SEVERAL_ISSUES_XML
0278             KRAZY2_FILETYPE_SINGLE_CHECKER_END_XML
0279         KRAZY2_FOOTER_XML;
0280 
0281     m_analysisResultsParser->parse(data);
0282 
0283     QCOMPARE(m_analysisResults->issues().size(), 3);
0284     assertIssue(0, "several issues message", "severalIssuesFile.cpp", 8);
0285     assertIssue(1, "several issues message", "severalIssuesFile.cpp", 15);
0286     assertIssue(2, "several issues message", "severalIssuesFile.cpp", 16);
0287     assertChecker(0, "checkerName", "Checker description", "Checker explanation", "fileType");
0288     QCOMPARE(m_analysisResults->issues()[1]->checker(), m_analysisResults->issues()[0]->checker());
0289     QCOMPARE(m_analysisResults->issues()[2]->checker(), m_analysisResults->issues()[0]->checker());
0290 }
0291 
0292 void AnalysisResultsParserTest::testParseSingleCheckerSingleFileSeveralIssuesNoMessage() {
0293     QByteArray data =
0294         KRAZY2_HEADER_XML
0295             KRAZY2_FILETYPE_SINGLE_CHECKER_START_XML
0296                 KRAZY2_FILE_SEVERAL_ISSUES_NO_MESSAGE_XML
0297             KRAZY2_FILETYPE_SINGLE_CHECKER_END_XML
0298         KRAZY2_FOOTER_XML;
0299 
0300     m_analysisResultsParser->parse(data);
0301 
0302     QCOMPARE(m_analysisResults->issues().size(), 3);
0303     assertIssue(0, "", "severalIssuesNoMessageFile.cpp", 815);
0304     assertIssue(1, "", "severalIssuesNoMessageFile.cpp", 1516);
0305     assertIssue(2, "", "severalIssuesNoMessageFile.cpp", 1623);
0306     assertChecker(0, "checkerName", "Checker description", "Checker explanation", "fileType");
0307     QCOMPARE(m_analysisResults->issues()[1]->checker(), m_analysisResults->issues()[0]->checker());
0308     QCOMPARE(m_analysisResults->issues()[2]->checker(), m_analysisResults->issues()[0]->checker());
0309 }
0310 
0311 void AnalysisResultsParserTest::testParseSingleCheckerSingleFileSeveralIssuesWithDetails() {
0312     QByteArray data =
0313         KRAZY2_HEADER_XML
0314             KRAZY2_FILETYPE_SINGLE_CHECKER_START_XML
0315                 KRAZY2_FILE_SEVERAL_ISSUES_WITH_DETAILS_XML
0316             KRAZY2_FILETYPE_SINGLE_CHECKER_END_XML
0317         KRAZY2_FOOTER_XML;
0318 
0319     m_analysisResultsParser->parse(data);
0320 
0321     QCOMPARE(m_analysisResults->issues().size(), 3);
0322     assertIssue(0, "details1", "severalIssuesWithDetailsFile.cpp", 23);
0323     assertIssue(1, "details2", "severalIssuesWithDetailsFile.cpp", 42);
0324     assertIssue(2, "details3", "severalIssuesWithDetailsFile.cpp", 108);
0325     assertChecker(0, "checkerName", "Checker description", "Checker explanation", "fileType");
0326     QCOMPARE(m_analysisResults->issues()[1]->checker(), m_analysisResults->issues()[0]->checker());
0327     QCOMPARE(m_analysisResults->issues()[2]->checker(), m_analysisResults->issues()[0]->checker());
0328 }
0329 
0330 void AnalysisResultsParserTest::testParseSingleCheckerSeveralFiles() {
0331     QByteArray data =
0332         KRAZY2_HEADER_XML
0333             KRAZY2_FILETYPE_SINGLE_CHECKER_START_XML
0334                 KRAZY2_FILE_SINGLE_ISSUE_XML
0335                 KRAZY2_FILE_SEVERAL_ISSUES_XML
0336             KRAZY2_FILETYPE_SINGLE_CHECKER_END_XML
0337         KRAZY2_FOOTER_XML;
0338 
0339     m_analysisResultsParser->parse(data);
0340 
0341     QCOMPARE(m_analysisResults->issues().size(), 4);
0342     assertIssue(0, "single issue message", "singleIssueFile.cpp", -1);
0343     assertIssue(1, "several issues message", "severalIssuesFile.cpp", 8);
0344     assertIssue(2, "several issues message", "severalIssuesFile.cpp", 15);
0345     assertIssue(3, "several issues message", "severalIssuesFile.cpp", 16);
0346     assertChecker(0, "checkerName", "Checker description", "Checker explanation", "fileType");
0347     QCOMPARE(m_analysisResults->issues()[1]->checker(), m_analysisResults->issues()[0]->checker());
0348     QCOMPARE(m_analysisResults->issues()[2]->checker(), m_analysisResults->issues()[0]->checker());
0349     QCOMPARE(m_analysisResults->issues()[3]->checker(), m_analysisResults->issues()[0]->checker());
0350 }
0351 
0352 void AnalysisResultsParserTest::testParseSeveralCheckers() {
0353     QByteArray data =
0354         KRAZY2_HEADER_XML
0355         "<file-type value=\"fileType\">\n"
0356             "<check desc=\"Checker1 description [checker1Name]...\">\n"
0357                 KRAZY2_FILE_SINGLE_ISSUE_XML
0358                 KRAZY2_FILE_SEVERAL_ISSUES_XML
0359                 "<explanation>Checker1 explanation</explanation>\n"
0360             "</check>\n"
0361             "<check desc=\"Checker2 description [checker2Name]...\">\n"
0362                 KRAZY2_FILE_SINGLE_ISSUE_WITH_DETAILS_XML
0363                 "<explanation>Checker2 explanation</explanation>\n"
0364             "</check>\n"
0365         "</file-type>\n"
0366         KRAZY2_FOOTER_XML;
0367 
0368     m_analysisResultsParser->parse(data);
0369 
0370     QCOMPARE(m_analysisResults->issues().size(), 5);
0371     assertIssue(0, "single issue message", "singleIssueFile.cpp", -1);
0372     assertIssue(1, "several issues message", "severalIssuesFile.cpp", 8);
0373     assertIssue(2, "several issues message", "severalIssuesFile.cpp", 15);
0374     assertIssue(3, "several issues message", "severalIssuesFile.cpp", 16);
0375     assertIssue(4, "details", "singleIssueWithDetailsFile.cpp", 4);
0376     assertChecker(0, "checker1Name", "Checker1 description", "Checker1 explanation", "fileType");
0377     QCOMPARE(m_analysisResults->issues()[1]->checker(), m_analysisResults->issues()[0]->checker());
0378     QCOMPARE(m_analysisResults->issues()[2]->checker(), m_analysisResults->issues()[0]->checker());
0379     QCOMPARE(m_analysisResults->issues()[3]->checker(), m_analysisResults->issues()[0]->checker());
0380     assertChecker(4, "checker2Name", "Checker2 description", "Checker2 explanation", "fileType");
0381 }
0382 
0383 void AnalysisResultsParserTest::testParseSeveralFileTypes() {
0384     QByteArray data =
0385         KRAZY2_HEADER_XML
0386         "<file-type value=\"fileType1\">\n"
0387             "<check desc=\"Checker1 description [checker1Name]...\">\n"
0388                 KRAZY2_FILE_SINGLE_ISSUE_XML
0389                 KRAZY2_FILE_SEVERAL_ISSUES_XML
0390                 "<explanation>Checker1 explanation</explanation>\n"
0391             "</check>\n"
0392             "<check desc=\"Checker2 description [checker2Name]...\">\n"
0393                 KRAZY2_FILE_SINGLE_ISSUE_WITH_DETAILS_XML
0394                 "<explanation>Checker2 explanation</explanation>\n"
0395             "</check>\n"
0396         "</file-type>\n"
0397         "<file-type value=\"fileType2\">\n"
0398             "<check desc=\"Checker1 description [checker1Name]...\">\n"
0399                 KRAZY2_FILE_SEVERAL_ISSUES_WITH_DETAILS_XML
0400                 "<explanation>Checker1 explanation</explanation>\n"
0401             "</check>\n"
0402         "</file-type>\n"
0403         KRAZY2_FOOTER_XML;
0404 
0405     m_analysisResultsParser->parse(data);
0406 
0407     QCOMPARE(m_analysisResults->issues().size(), 8);
0408     assertIssue(0, "single issue message", "singleIssueFile.cpp", -1);
0409     assertIssue(1, "several issues message", "severalIssuesFile.cpp", 8);
0410     assertIssue(2, "several issues message", "severalIssuesFile.cpp", 15);
0411     assertIssue(3, "several issues message", "severalIssuesFile.cpp", 16);
0412     assertIssue(4, "details", "singleIssueWithDetailsFile.cpp", 4);
0413     assertIssue(5, "details1", "severalIssuesWithDetailsFile.cpp", 23);
0414     assertIssue(6, "details2", "severalIssuesWithDetailsFile.cpp", 42);
0415     assertIssue(7, "details3", "severalIssuesWithDetailsFile.cpp", 108);
0416     assertChecker(0, "checker1Name", "Checker1 description", "Checker1 explanation", "fileType1");
0417     QCOMPARE(m_analysisResults->issues()[1]->checker(), m_analysisResults->issues()[0]->checker());
0418     QCOMPARE(m_analysisResults->issues()[2]->checker(), m_analysisResults->issues()[0]->checker());
0419     QCOMPARE(m_analysisResults->issues()[3]->checker(), m_analysisResults->issues()[0]->checker());
0420     assertChecker(4, "checker2Name", "Checker2 description", "Checker2 explanation", "fileType1");
0421     assertChecker(5, "checker1Name", "Checker1 description", "Checker1 explanation", "fileType2");
0422     QCOMPARE(m_analysisResults->issues()[6]->checker(), m_analysisResults->issues()[5]->checker());
0423     QCOMPARE(m_analysisResults->issues()[7]->checker(), m_analysisResults->issues()[5]->checker());
0424 }
0425 
0426 void AnalysisResultsParserTest::testParseSingleCheckerSingleFileSeveralIssuesIssueWithoutMessageAfterIssueWithDetails() {
0427     QByteArray data =
0428         KRAZY2_HEADER_XML
0429             KRAZY2_FILETYPE_SINGLE_CHECKER_START_XML
0430                 "<file name=\"severalIssuesWithAndWithoutDetailsFile.cpp\">\n"
0431                     "<issues>\n"
0432                         "<line issue=\"details\">42</line>\n"
0433                         "<line>108</line>\n"
0434                     "</issues>\n"
0435                 "</file>\n"
0436             KRAZY2_FILETYPE_SINGLE_CHECKER_END_XML
0437         KRAZY2_FOOTER_XML;
0438 
0439     m_analysisResultsParser->parse(data);
0440 
0441     QCOMPARE(m_analysisResults->issues().size(), 2);
0442     assertIssue(0, "details", "severalIssuesWithAndWithoutDetailsFile.cpp", 42);
0443     assertIssue(1, "", "severalIssuesWithAndWithoutDetailsFile.cpp", 108);
0444     assertChecker(0, "checkerName", "Checker description", "Checker explanation", "fileType");
0445 }
0446 
0447 void AnalysisResultsParserTest::testParseSingleCheckerSeveralFilesSingleIssueWithoutMessageAfterSingleIssueWithMessage() {
0448     QByteArray data =
0449         KRAZY2_HEADER_XML
0450             KRAZY2_FILETYPE_SINGLE_CHECKER_START_XML
0451                 KRAZY2_FILE_SINGLE_ISSUE_XML
0452                 KRAZY2_FILE_SINGLE_ISSUE_NO_MESSAGE_XML
0453             KRAZY2_FILETYPE_SINGLE_CHECKER_END_XML
0454         KRAZY2_FOOTER_XML;
0455 
0456     m_analysisResultsParser->parse(data);
0457 
0458     QCOMPARE(m_analysisResults->issues().size(), 2);
0459     assertIssue(0, "single issue message", "singleIssueFile.cpp", -1);
0460     assertIssue(1, "", "singleIssueNoMessageFile.cpp", 423);
0461     assertChecker(0, "checkerName", "Checker description", "Checker explanation", "fileType");
0462 }
0463 
0464 void AnalysisResultsParserTest::testParseSingleCheckerExplanationEndingWithNewLine() {
0465     QByteArray data =
0466         KRAZY2_HEADER_XML
0467         "<file-type value=\"fileType\">\n"
0468             "<check desc=\"Checker description [checkerName]...\">\n"
0469                 KRAZY2_FILE_SINGLE_ISSUE_XML
0470                 "<explanation>Checker explanation\n</explanation>\n"
0471             "</check>\n"
0472         "</file-type>\n"
0473         KRAZY2_FOOTER_XML;
0474 
0475     m_analysisResultsParser->parse(data);
0476 
0477     QCOMPARE(m_analysisResults->issues().size(), 1);
0478     assertChecker(0, "checkerName", "Checker description", "Checker explanation", "fileType");
0479 }
0480 
0481 void AnalysisResultsParserTest::testParseSingleCheckerNoDescription() {
0482     QByteArray data =
0483         KRAZY2_HEADER_XML
0484         "<file-type value=\"fileType\">\n"
0485             "<check desc=\"no description available [checkerName]...\">\n"
0486                 KRAZY2_FILE_SINGLE_ISSUE_XML
0487                 "<explanation>Checker explanation</explanation>\n"
0488             "</check>\n"
0489         "</file-type>\n"
0490         KRAZY2_FOOTER_XML;
0491 
0492     m_analysisResultsParser->parse(data);
0493 
0494     QCOMPARE(m_analysisResults->issues().size(), 1);
0495     assertChecker(0, "checkerName", "", "Checker explanation", "fileType");
0496 }
0497 
0498 void AnalysisResultsParserTest::testParseSingleCheckerNoExplanation() {
0499     QByteArray data =
0500         KRAZY2_HEADER_XML
0501         "<file-type value=\"fileType\">\n"
0502             "<check desc=\"Checker description [checkerName]...\">\n"
0503                 KRAZY2_FILE_SINGLE_ISSUE_XML
0504                 "<explanation>(no explanation available)\n</explanation>\n"
0505             "</check>\n"
0506         "</file-type>\n"
0507         KRAZY2_FOOTER_XML;
0508 
0509     m_analysisResultsParser->parse(data);
0510 
0511     QCOMPARE(m_analysisResults->issues().size(), 1);
0512     assertChecker(0, "checkerName", "Checker description", "", "fileType");
0513 }
0514 
0515 void AnalysisResultsParserTest::testParseWithDataInSeveralChunks() {
0516     QByteArray data =
0517         KRAZY2_HEADER_XML
0518         "<file-type value=\"fileType1\">\n"
0519             "<check desc=\"Checker1 description [checker1Name]...\">\n"
0520                 KRAZY2_FILE_SINGLE_ISSUE_XML
0521                 KRAZY2_FILE_SEVERAL_ISSUES_XML
0522                 "<explanation>Checker1 explanation</explanation>\n"
0523             "</check>\n"
0524             "<check desc=\"Checker2 description [checker2Name]...\">\n"
0525                 KRAZY2_FILE_SINGLE_ISSUE_WITH_DETAILS_XML
0526                 "<explanation>Checker2 explanation</explanation>\n"
0527             "</check>\n"
0528         "</file-type>\n"
0529         "<file-type value=\"fileType2\">\n"
0530             "<check desc=\"Checker1 description [checker1Name]...\">\n"
0531                 KRAZY2_FILE_SEVERAL_ISSUES_WITH_DETAILS_XML
0532                 "<explanation>Checker1 explanation</explanation>\n"
0533             "</check>\n"
0534         "</file-type>\n"
0535         KRAZY2_FOOTER_XML;
0536 
0537     srand(time(nullptr));
0538 
0539     for (int i=0; i<1000; i++) {
0540         delete m_analysisResults;
0541         delete m_analysisResultsParser;
0542 
0543         m_analysisResultsParser = new AnalysisResultsParser();
0544         m_analysisResults = new AnalysisResults();
0545         m_analysisResultsParser->setAnalysisResults(m_analysisResults);
0546 
0547         QByteArray remainingData = data;
0548         while (remainingData.size() > 0) {
0549             const float randomValue = rand()/float(RAND_MAX);
0550             int numberOfCharacters = randomValue * remainingData.size();
0551 
0552             // A little help to random number generator to speed up the test, as
0553             // chances of getting a RAND_MAX are scarce
0554             if (remainingData.size() == 1) {
0555                 numberOfCharacters = 1;
0556             }
0557 
0558             m_analysisResultsParser->parse(remainingData.left(numberOfCharacters));
0559             remainingData.remove(0, numberOfCharacters);
0560         }
0561 
0562         QCOMPARE(m_analysisResults->issues().size(), 8);
0563         assertIssue(0, "single issue message", "singleIssueFile.cpp", -1);
0564         assertIssue(1, "several issues message", "severalIssuesFile.cpp", 8);
0565         assertIssue(2, "several issues message", "severalIssuesFile.cpp", 15);
0566         assertIssue(3, "several issues message", "severalIssuesFile.cpp", 16);
0567         assertIssue(4, "details", "singleIssueWithDetailsFile.cpp", 4);
0568         assertIssue(5, "details1", "severalIssuesWithDetailsFile.cpp", 23);
0569         assertIssue(6, "details2", "severalIssuesWithDetailsFile.cpp", 42);
0570         assertIssue(7, "details3", "severalIssuesWithDetailsFile.cpp", 108);
0571         assertChecker(0, "checker1Name", "Checker1 description", "Checker1 explanation", "fileType1");
0572         QCOMPARE(m_analysisResults->issues()[1]->checker(), m_analysisResults->issues()[0]->checker());
0573         QCOMPARE(m_analysisResults->issues()[2]->checker(), m_analysisResults->issues()[0]->checker());
0574         QCOMPARE(m_analysisResults->issues()[3]->checker(), m_analysisResults->issues()[0]->checker());
0575         assertChecker(4, "checker2Name", "Checker2 description", "Checker2 explanation", "fileType1");
0576         assertChecker(5, "checker1Name", "Checker1 description", "Checker1 explanation", "fileType2");
0577         QCOMPARE(m_analysisResults->issues()[6]->checker(), m_analysisResults->issues()[5]->checker());
0578         QCOMPARE(m_analysisResults->issues()[7]->checker(), m_analysisResults->issues()[5]->checker());
0579     }
0580 }
0581 
0582 void AnalysisResultsParserTest::testParseWhenAnalysisResultsHasPreviousContents() {
0583     QByteArray data =
0584         KRAZY2_HEADER_XML
0585         "<file-type value=\"fileType\">\n"
0586             "<check desc=\"Checker1 description [checker1Name]...\">\n"
0587                 KRAZY2_FILE_SINGLE_ISSUE_XML
0588                 KRAZY2_FILE_SEVERAL_ISSUES_XML
0589                 "<explanation>Checker1 explanation</explanation>\n"
0590             "</check>\n"
0591             "<check desc=\"Checker2 description [checker2Name]...\">\n"
0592                 KRAZY2_FILE_SINGLE_ISSUE_WITH_DETAILS_XML
0593                 "<explanation>Checker2 explanation</explanation>\n"
0594             "</check>\n"
0595         "</file-type>\n"
0596         KRAZY2_FOOTER_XML;
0597 
0598     auto  checker = new Checker();
0599     checker->setDescription("Checker1 old description");
0600     checker->setExplanation("Checker1 old explanation");
0601     checker->setFileType("fileType");
0602     checker->setName("checker1Name");
0603     m_analysisResults->addChecker(checker);
0604 
0605     auto  issue = new Issue();
0606     issue->setChecker(checker);
0607     issue->setFileName("someFile.cpp");
0608     issue->setLine(316);
0609     issue->setMessage("some message");
0610     m_analysisResults->addIssue(issue);
0611 
0612     m_analysisResultsParser->parse(data);
0613 
0614     QCOMPARE(m_analysisResults->issues().size(), 6);
0615     assertIssue(0, "some message", "someFile.cpp", 316);
0616     assertIssue(1, "single issue message", "singleIssueFile.cpp", -1);
0617     assertIssue(2, "several issues message", "severalIssuesFile.cpp", 8);
0618     assertIssue(3, "several issues message", "severalIssuesFile.cpp", 15);
0619     assertIssue(4, "several issues message", "severalIssuesFile.cpp", 16);
0620     assertIssue(5, "details", "singleIssueWithDetailsFile.cpp", 4);
0621     assertChecker(0, "checker1Name", "Checker1 old description", "Checker1 old explanation", "fileType");
0622     QCOMPARE(m_analysisResults->issues()[1]->checker(), m_analysisResults->issues()[0]->checker());
0623     QCOMPARE(m_analysisResults->issues()[2]->checker(), m_analysisResults->issues()[0]->checker());
0624     QCOMPARE(m_analysisResults->issues()[3]->checker(), m_analysisResults->issues()[0]->checker());
0625     QCOMPARE(m_analysisResults->issues()[4]->checker(), m_analysisResults->issues()[0]->checker());
0626     assertChecker(5, "checker2Name", "Checker2 description", "Checker2 explanation", "fileType");
0627 }
0628 
0629 ////////////////////////////////// Helpers /////////////////////////////////////
0630 
0631 void AnalysisResultsParserTest::assertChecker(int index, const QString& name, const QString& description,
0632                                               const QString& explanation, const QString& fileType) const {
0633     const Checker* checker = m_analysisResults->issues()[index]->checker();
0634     QVERIFY(checker);
0635     QCOMPARE(checker->name(), name);
0636     QCOMPARE(checker->description(), description);
0637     QCOMPARE(checker->explanation(), explanation);
0638     QCOMPARE(checker->fileType(), fileType);
0639 }
0640 
0641 void AnalysisResultsParserTest::assertIssue(int index, const QString& message,
0642                                             const QString& fileName, int line) const {
0643     const Issue* issue = m_analysisResults->issues()[index];
0644     QVERIFY(issue);
0645     QCOMPARE(issue->message(), message);
0646     QCOMPARE(issue->fileName(), fileName);
0647     QCOMPARE(issue->line(), line);
0648 }
0649 
0650 QTEST_GUILESS_MAIN(AnalysisResultsParserTest)
0651 
0652 #include "analysisresultsparsertest.moc"