File indexing completed on 2024-04-28 05:42:13

0001 // clang-format off
0002 /*
0003  * KDiff3 - Text Diff And Merge Tool
0004  *
0005  * SPDX-FileCopyrightText: 2019-2020 Michael Reeves reeves.87@gmail.com
0006  * SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 // clang-format on
0009 
0010 #include <QTest>
0011 
0012 #include "../CommentParser.h"
0013 
0014 class CommentParserTest : public QObject
0015 {
0016     Q_OBJECT
0017   private Q_SLOTS:
0018     void init()
0019     {
0020         DefaultCommentParser parser;
0021 
0022         //Sanity check defaults.
0023         QVERIFY(!parser.isSkipable());
0024         QVERIFY(!parser.isEscaped());
0025         QVERIFY(!parser.inString());
0026         QVERIFY(!parser.inComment());
0027         QVERIFY(!parser.isPureComment());
0028     }
0029 
0030     void singleLineComment()
0031     {
0032         DefaultCommentParser test;
0033 
0034         test.processLine("//ddj ?*8");
0035         QVERIFY(!test.inComment());
0036         QVERIFY(test.isSkipable());
0037         QVERIFY(test.isPureComment());
0038 
0039         //ignore trailing+leading whitespace
0040         test = DefaultCommentParser();
0041         test.processLine("\t  \t  // comment     ");
0042         QVERIFY(!test.inComment());
0043         QVERIFY(test.isSkipable());
0044         QVERIFY(!test.isPureComment());
0045 
0046         test = DefaultCommentParser();
0047         test.processLine("//comment with quotes embedded \"\"");
0048         QVERIFY(!test.inComment());
0049         QVERIFY(test.isSkipable());
0050         QVERIFY(test.isPureComment());
0051 
0052         test = DefaultCommentParser();
0053         test.processLine("anythis//endof line comment");
0054         QVERIFY(!test.inComment());
0055         QVERIFY(!test.isSkipable());
0056         QVERIFY(!test.isPureComment());
0057 
0058         test = DefaultCommentParser();
0059         test.processLine("anythis//ignore embedded multiline sequence  /*");
0060         QVERIFY(!test.inComment());
0061         QVERIFY(!test.isSkipable());
0062         QVERIFY(!test.isPureComment());
0063     }
0064 
0065     void inComment()
0066     {
0067         DefaultCommentParser test;
0068 
0069         test.mCommentType = DefaultCommentParser::multiLine;
0070         QVERIFY(test.inComment());
0071 
0072         test.mCommentType = DefaultCommentParser::singleLine;
0073         QVERIFY(test.inComment());
0074 
0075         test.mCommentType = DefaultCommentParser::none;
0076         QVERIFY(!test.inComment());
0077     }
0078 
0079     void multiLineComment()
0080     {
0081         DefaultCommentParser test;
0082 
0083         //mutiline syntax on one line
0084         test.processLine("/* kjd*/");
0085         QVERIFY(test.isSkipable());
0086         QVERIFY(test.isPureComment());
0087         QVERIFY(!test.inComment());
0088 
0089         //mid line comment start.
0090         test = DefaultCommentParser();
0091         test.processLine("fskk /* kjd */");
0092         QVERIFY(!test.inComment());
0093         QVERIFY(!test.isSkipable());
0094         QVERIFY(!test.isPureComment());
0095 
0096 
0097         //mid line comment start. multiple lines
0098         test = DefaultCommentParser();
0099         test.processLine("fskk /* kjd ");
0100         QVERIFY(test.inComment());
0101         QVERIFY(!test.isSkipable());
0102         QVERIFY(!test.isPureComment());
0103 
0104         test.processLine("  comment line ");
0105         QVERIFY(test.inComment());
0106         QVERIFY(test.isSkipable());
0107         QVERIFY(test.isPureComment());
0108 
0109         test.processLine("  comment */ not comment ");
0110         QVERIFY(!test.inComment());
0111         QVERIFY(!test.isSkipable());
0112         QVERIFY(!test.isPureComment());
0113 
0114         //mid line comment start. multiple lines
0115         test = DefaultCommentParser();
0116         test.processLine("fskk /* kjd ");
0117         QVERIFY(test.inComment());
0118         QVERIFY(!test.isSkipable());
0119         QVERIFY(!test.isPureComment());
0120 
0121         test.processLine("  comment line ");
0122         QVERIFY(test.inComment());
0123         QVERIFY(test.isSkipable());
0124         QVERIFY(test.isPureComment());
0125 
0126         test.processLine("  comment * line /  ");
0127         QVERIFY(test.inComment());
0128         QVERIFY(test.isSkipable());
0129         QVERIFY(test.isPureComment());
0130 
0131         //embedded single line character sequence should not end comment
0132         test.processLine("  comment line //");
0133         QVERIFY(test.inComment());
0134         QVERIFY(test.isSkipable());
0135         QVERIFY(test.isPureComment());
0136 
0137         test.processLine("  comment */");
0138         QVERIFY(!test.inComment());
0139         QVERIFY(test.isSkipable());
0140         QVERIFY(test.isPureComment());
0141 
0142         //Escape squeances not relavate to comments
0143         test = DefaultCommentParser();
0144         test.processLine("/*  comment \\*/");
0145         QVERIFY(!test.inComment());
0146         QVERIFY(test.isSkipable());
0147         QVERIFY(test.isPureComment());
0148 
0149         test = DefaultCommentParser();
0150         test.processLine("  qint32 i = 8 / 8 * 3;/* comment*/");
0151         QVERIFY(!test.inComment());
0152         QVERIFY(!test.isSkipable());
0153         QVERIFY(!test.isPureComment());
0154 
0155         //invalid in C++ should not be flagged as pure comment
0156         test.processLine("/*  comment */ */");
0157         QVERIFY(!test.inComment());
0158         QVERIFY(!test.isSkipable());
0159         QVERIFY(!test.isPureComment());
0160 
0161         //leading whitespace
0162         test = DefaultCommentParser();
0163         test.processLine("\t  \t  /*  comment */");
0164         QVERIFY(!test.inComment());
0165         QVERIFY(test.isSkipable());
0166         QVERIFY(!test.isPureComment());
0167 
0168         //trailing whitespace
0169         test = DefaultCommentParser();
0170         test.processLine("\t  \t  /*  comment */    ");
0171         QVERIFY(!test.inComment());
0172         QVERIFY(test.isSkipable());
0173         QVERIFY(!test.isPureComment());
0174 
0175         test = DefaultCommentParser();
0176         test.processLine("/*  comment */    ");
0177         QVERIFY(!test.inComment());
0178         QVERIFY(test.isSkipable());
0179         QVERIFY(!test.isPureComment());
0180     }
0181 
0182     void stringTest()
0183     {
0184         DefaultCommentParser test;
0185 
0186         test.processLine("\"quoted string // \"");
0187         QVERIFY(!test.inString());
0188         QVERIFY(!test.inComment());
0189         QVERIFY(!test.isSkipable());
0190         QVERIFY(!test.isPureComment());
0191 
0192         test = DefaultCommentParser();
0193         test.processLine("\"quoted string /* \"");
0194         QVERIFY(!test.inString());
0195         QVERIFY(!test.inComment());
0196         QVERIFY(!test.isSkipable());
0197         QVERIFY(!test.isPureComment());
0198 
0199         test = DefaultCommentParser();
0200         test.processLine("\"\"");
0201         QVERIFY(!test.inString());
0202         QVERIFY(!test.inComment());
0203         QVERIFY(!test.isSkipable());
0204 
0205         test = DefaultCommentParser();
0206         test.processChar("\"", '"');
0207         QVERIFY(!test.isEscaped());
0208         QVERIFY(test.inString());
0209 
0210         test.processChar("\"'", '\'');
0211         QVERIFY(test.inString());
0212         test.processChar("\"'\"", '"');
0213         QVERIFY(!test.inString());
0214 
0215         //test only escape sequence we care about
0216         test = DefaultCommentParser();
0217         test.processChar("\"", '"');
0218 
0219         test.processChar("\"", '\\');
0220         QVERIFY(test.isEscaped());
0221         QVERIFY(test.inString());
0222 
0223         test.processChar("\"\\\"", '"');
0224         QVERIFY(!test.isEscaped());
0225         QVERIFY(test.inString());
0226 
0227         test.processChar("\"\\\"\"", '"');
0228         QVERIFY(!test.isEscaped());
0229         QVERIFY(!test.inString());
0230     }
0231 
0232     void quotedCharacter()
0233     {
0234         DefaultCommentParser test;
0235 
0236         test.processLine("'\"'");
0237         QVERIFY(!test.inString());
0238         QVERIFY(!test.inComment());
0239         QVERIFY(!test.isSkipable());
0240         QVERIFY(!test.isPureComment());
0241 
0242         test.processLine("'a'");
0243         QVERIFY(!test.inString());
0244         QVERIFY(!test.inComment());
0245         QVERIFY(!test.isSkipable());
0246         QVERIFY(!test.isPureComment());
0247 
0248         test.processLine("'\\\''");
0249         QVERIFY(!test.inString());
0250         QVERIFY(!test.inComment());
0251         QVERIFY(!test.isSkipable());
0252         QVERIFY(!test.isPureComment());
0253 
0254         test.processLine("'*'");
0255         QVERIFY(!test.inString());
0256         QVERIFY(!test.inComment());
0257         QVERIFY(!test.isSkipable());
0258         QVERIFY(!test.isPureComment());
0259 
0260         test.processLine("'/'");
0261         QVERIFY(!test.inString());
0262         QVERIFY(!test.inComment());
0263         QVERIFY(!test.isSkipable());
0264         QVERIFY(!test.isPureComment());
0265     }
0266 
0267     void nonComment()
0268     {
0269         DefaultCommentParser test;
0270 
0271         test.processLine("  qint32 i = 8 / 8 * 3;");
0272         QVERIFY(!test.inString());
0273         QVERIFY(!test.inComment());
0274         QVERIFY(!test.isSkipable());
0275         QVERIFY(!test.isPureComment());
0276 
0277         test = DefaultCommentParser();
0278         test.processLine("  ");
0279         QVERIFY(!test.inString());
0280         QVERIFY(!test.inComment());
0281         QVERIFY(!test.isSkipable());
0282         QVERIFY(!test.isPureComment());
0283 
0284         test = DefaultCommentParser();
0285         test.processLine("");
0286         QVERIFY(!test.inString());
0287         QVERIFY(!test.inComment());
0288         QVERIFY(!test.isSkipable());
0289         QVERIFY(!test.isPureComment());
0290 
0291         test = DefaultCommentParser();
0292         test.processLine("  / ");
0293         QVERIFY(!test.inString());
0294         QVERIFY(!test.inComment());
0295         QVERIFY(!test.isSkipable());
0296         QVERIFY(!test.isPureComment());
0297 
0298         test = DefaultCommentParser();
0299         test.processLine("  * ");
0300         QVERIFY(!test.inString());
0301         QVERIFY(!test.inComment());
0302         QVERIFY(!test.isSkipable());
0303         QVERIFY(!test.isPureComment());
0304 
0305         //invalid in C++ should not be flagged as non-comment
0306         test.processLine(" */");
0307         QVERIFY(!test.inString());
0308         QVERIFY(!test.inComment());
0309         QVERIFY(!test.isSkipable());
0310         QVERIFY(!test.isPureComment());
0311     }
0312 
0313     void removeComment()
0314     {
0315         DefaultCommentParser test;
0316         QString line=u8"  qint32 i = 8 / 8 * 3;", correct=u8"  qint32 i = 8 / 8 * 3;";
0317 
0318         test.processLine(line);
0319         test.removeComment(line);
0320         QCOMPARE(line, correct);
0321         QCOMPARE(line.length(), correct.length());
0322 
0323         test = DefaultCommentParser();
0324         correct = line = u8"  //qint32 i = 8 / 8 * 3;";
0325 
0326         test.processLine(line);
0327         test.removeComment(line);
0328         QCOMPARE(line, correct);
0329 
0330         test = DefaultCommentParser();
0331         correct = line = u8"//  qint32 i = 8 / 8 * 3;";
0332 
0333         test.processLine(line);
0334         test.removeComment(line);
0335         QCOMPARE(line, correct);
0336         QCOMPARE(line.length(), correct.length());
0337 
0338         test = DefaultCommentParser();
0339         line = u8"  qint32 i = 8 / 8 * 3;// comment";
0340         correct = u8"  qint32 i = 8 / 8 * 3;          ";
0341 
0342         test.processLine(line);
0343         test.removeComment(line);
0344         QCOMPARE(line, correct);
0345         QCOMPARE(line.length(), correct.length());
0346 
0347         test = DefaultCommentParser();
0348         line = u8"  qint32 i = 8 / 8 * 3;/* comment";
0349         correct = u8"  qint32 i = 8 / 8 * 3;          ";
0350 
0351         test.processLine(line);
0352         test.removeComment(line);
0353         QCOMPARE(line, correct);
0354         QCOMPARE(line.length(), correct.length());
0355 
0356         correct = line = u8"  qint32 i = 8 / 8 * 3;/* mot a comment";
0357         test.processLine(line);
0358         test.removeComment(line);
0359         QCOMPARE(line, correct);
0360         QCOMPARE(line.length(), correct.length());
0361 
0362         //end comment mid-line
0363         line = u8"d  */ why";
0364         correct = u8"      why";
0365 
0366         test.processLine(line);
0367         test.removeComment(line);
0368         QCOMPARE(line, correct);
0369         QCOMPARE(line.length(), correct.length());
0370 
0371         test = DefaultCommentParser();
0372         line = u8"  qint32 i = 8 / 8 * 3;/* comment*/";
0373         correct = u8"  qint32 i = 8 / 8 * 3;            ";
0374 
0375         test.processLine(line);
0376         test.removeComment(line);
0377         QCOMPARE(line, correct);
0378         QCOMPARE(line.length(), correct.length());
0379 
0380         test = DefaultCommentParser();
0381         correct = line = u8"  /*qint32 i = 8 / 8 * 3;/* comment*/";
0382 
0383         test.processLine(line);
0384         test.removeComment(line);
0385         QCOMPARE(line, correct);
0386         QCOMPARE(line.length(), correct.length());
0387 
0388         //line with multiple comments weird but legal c/c++
0389         test = DefaultCommentParser();
0390         line = u8"  qint32 /*why?*/ i = 8 / 8 * 3;/* comment*/";
0391         correct = u8"  qint32          i = 8 / 8 * 3;            ";
0392         test.processLine(line);
0393         test.removeComment(line);
0394         QCOMPARE(line, correct);
0395         QCOMPARE(line.length(), correct.length());
0396 
0397         //invalid in C++ should be flagged as non-comment
0398         test = DefaultCommentParser();
0399         line = correct = " */";
0400         test.processLine(" */");
0401         QCOMPARE(line, correct);
0402         QCOMPARE(line.length(), correct.length());
0403     }
0404 };
0405 
0406 QTEST_MAIN(CommentParserTest);
0407 
0408 #include "commentparser.moc"