File indexing completed on 2024-04-28 15:11:57
0001 /* 0002 SPDX-FileCopyrightText: 2012 Rishab Arora <ra.rishab@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 /* 0008 * Justification for not testing CombineQuoteParts separately: 0009 * Changing the structure of KSParser would solve this (by removing the 0010 * segments to be tested into separate classes) but would unnecessarily 0011 * complicate things resulting in a large number of small classes. 0012 * This is good from an OOD perspective, but would make the code unmanageable 0013 */ 0014 0015 #include "testcsvparser.h" 0016 0017 #include <QDir> 0018 #include <QTemporaryFile> 0019 0020 TestCSVParser::TestCSVParser() : QObject() 0021 { 0022 } 0023 0024 void TestCSVParser::initTestCase() 0025 { 0026 /* 0027 * Justification for doing this instead of simply creating a file: 0028 * To add/change tests, we'll need to modify 2 places. The file and this class. 0029 * So we write the file from the class. 0030 */ 0031 test_cases_.append("\n"); 0032 test_cases_.append(QString("," 0033 "isn't," 0034 "it," 0035 "\"amusing\"," 0036 "how," 0037 "3," 0038 "\"isn't, pi\"," 0039 "and," 0040 "\"\"," 0041 "-3.141," 0042 "isn't," 0043 "either\n")); 0044 test_cases_.append(QString("," 0045 "isn't," 0046 "it," 0047 "\"amusing\"," 0048 "how," 0049 "3," 0050 "\"isn't\"(, )\"pi\"," 0051 "and," 0052 "\"\"," 0053 "-3.141," 0054 "isn't," 0055 "either\n")); 0056 test_cases_.append(QString("," 0057 "isn't," 0058 "it," 0059 "\"amusing\"," 0060 "how," 0061 "3," 0062 "\"isn't, pi\"," 0063 "and," 0064 "\"\",")); // less than required fields 0065 test_cases_.append(QString("," 0066 "isn't," 0067 "it," 0068 "\"amusing\"," 0069 "how," 0070 "3," 0071 "\"isn't, pi\"," 0072 "and," 0073 "\"," // no matching " 0074 "-3.141," 0075 "isn't," 0076 "either\n")); 0077 test_cases_.append(",,,,,,,,,,,\n"); 0078 test_cases_.append("\n"); 0079 QTemporaryFile temp_file; 0080 //temp_file.setPrefix(QDir::tempPath() + QDir::separator()); 0081 //temp_file.setSuffix(".txt"); 0082 temp_file.setAutoRemove(false); 0083 QVERIFY(temp_file.open()); 0084 test_file_name_ = temp_file.fileName(); 0085 QTextStream out_stream(&temp_file); 0086 foreach (const QString &test_case, test_cases_) 0087 out_stream << test_case; 0088 temp_file.close(); 0089 0090 //Building the sequence to be used. Includes all available types. 0091 sequence_.clear(); 0092 sequence_.append(qMakePair(QString("field1"), KSParser::D_QSTRING)); 0093 sequence_.append(qMakePair(QString("field2"), KSParser::D_QSTRING)); 0094 sequence_.append(qMakePair(QString("field3"), KSParser::D_QSTRING)); 0095 sequence_.append(qMakePair(QString("field4"), KSParser::D_QSTRING)); 0096 sequence_.append(qMakePair(QString("field5"), KSParser::D_QSTRING)); 0097 sequence_.append(qMakePair(QString("field6"), KSParser::D_INT)); 0098 sequence_.append(qMakePair(QString("field7"), KSParser::D_QSTRING)); 0099 sequence_.append(qMakePair(QString("field8"), KSParser::D_QSTRING)); 0100 sequence_.append(qMakePair(QString("field9"), KSParser::D_QSTRING)); 0101 sequence_.append(qMakePair(QString("field10"), KSParser::D_FLOAT)); 0102 sequence_.append(qMakePair(QString("field11"), KSParser::D_QSTRING)); 0103 sequence_.append(qMakePair(QString("field12"), KSParser::D_QSTRING)); 0104 0105 test_parser_ = new KSParser(test_file_name_, '#', sequence_); 0106 } 0107 0108 void TestCSVParser::cleanupTestCase() 0109 { 0110 delete test_parser_; 0111 } 0112 0113 /* 0114 * The following tests checks for the following cases for CSV files 0115 * 1. Mixed inputs (See test case for description) 0116 * 1b. Quoteception 0117 * 2. Empty Row 0118 * 3. No row (only a newline character) 0119 * 4. Truncated row 0120 * 5. Row with no matching quote 0121 * 6. Attempt to read missing file 0122 * 0123 */ 0124 0125 void TestCSVParser::CSVMixedInputs() 0126 { 0127 /* 0128 * Test 1. Includes input of the form: 0129 * 0130 * It starts with a newline char which should be skipped by virtue 0131 * of the design of the parser 0132 * 0133 * Then a row with the following types of inputs: 0134 * 1. empty column 0135 * 2. simple single word 0136 * 3. single word in quotes 0137 * 4. multiple words with , in quotes 0138 * 5. integer 0139 * 6. float 0140 */ 0141 QHash<QString, QVariant> row_content = test_parser_->ReadNextRow(); 0142 qDebug() << row_content["field1"]; 0143 QCOMPARE(row_content["field1"].toString(), QString("")); 0144 QCOMPARE(row_content["field2"].toString(), QString("isn't")); 0145 QCOMPARE(row_content["field3"].toString(), QString("it")); 0146 QCOMPARE(row_content["field4"].toString(), QString("amusing")); 0147 QCOMPARE(row_content["field5"].toString(), QString("how")); 0148 QCOMPARE(row_content["field6"].toInt(), 3); 0149 QCOMPARE(row_content["field7"].toString(), QString("isn't, pi")); 0150 QCOMPARE(row_content["field8"].toString(), QString("and")); 0151 QCOMPARE(row_content["field9"].toString(), QString("")); 0152 QVERIFY(row_content["field10"].toFloat() + 3.141 < 0.1); 0153 QCOMPARE(row_content["field11"].toString(), QString("isn't")); 0154 QCOMPARE(row_content["field12"].toString(), QString("either")); 0155 } 0156 0157 void TestCSVParser::CSVQuotesInQuotes() 0158 { 0159 /* 0160 * Test 1b. Identical to 1 except quotes in quotes 0161 * in Field 7 0162 * 0163 */ 0164 QHash<QString, QVariant> row_content = test_parser_->ReadNextRow(); 0165 qDebug() << row_content["field7"]; 0166 QCOMPARE(row_content["field1"].toString(), QString("")); 0167 QCOMPARE(row_content["field2"].toString(), QString("isn't")); 0168 QCOMPARE(row_content["field3"].toString(), QString("it")); 0169 QCOMPARE(row_content["field4"].toString(), QString("amusing")); 0170 QCOMPARE(row_content["field5"].toString(), QString("how")); 0171 QCOMPARE(row_content["field6"].toInt(), 3); 0172 QCOMPARE(row_content["field7"].toString(), QString("isn't\"(, )\"pi")); 0173 QCOMPARE(row_content["field8"].toString(), QString("and")); 0174 QCOMPARE(row_content["field9"].toString(), QString("")); 0175 QVERIFY(row_content["field10"].toFloat() + 3.141 < 0.1); 0176 QCOMPARE(row_content["field11"].toString(), QString("isn't")); 0177 QCOMPARE(row_content["field12"].toString(), QString("either")); 0178 } 0179 0180 void TestCSVParser::CSVEmptyRow() 0181 { 0182 /* Test 2. Row with less rows than required (to be skipped) 0183 * Test 3. Row with truncated \" i.e. no matching " 0184 * (should be skipped) 0185 */ 0186 /* 0187 * Test 4. Attempt to read an empty but valid row 0188 * 0189 * Also includes test for: 0190 * 1. missing integer 0191 * 2. missing float 0192 * 3. missing string 0193 */ 0194 QHash<QString, QVariant> row_content = test_parser_->ReadNextRow(); 0195 qDebug() << row_content["field1"]; 0196 QCOMPARE(row_content["field1"].toString(), QString("")); 0197 QCOMPARE(row_content["field2"].toString(), QString("")); 0198 QCOMPARE(row_content["field3"].toString(), QString("")); 0199 QCOMPARE(row_content["field4"].toString(), QString("")); 0200 QCOMPARE(row_content["field5"].toString(), QString("")); 0201 QCOMPARE(row_content["field6"].toInt(), 0); 0202 QCOMPARE(row_content["field7"].toString(), QString("")); 0203 QCOMPARE(row_content["field8"].toString(), QString("")); 0204 QCOMPARE(row_content["field9"].toString(), QString("")); 0205 QCOMPARE(row_content["field10"].toFloat(), float(0.0)); 0206 QCOMPARE(row_content["field11"].toString(), QString("")); 0207 QCOMPARE(row_content["field12"].toString(), QString("")); 0208 } 0209 0210 void TestCSVParser::CSVNoRow() 0211 { 0212 /* 0213 * Test 3. Attempt to read a newline char instead of a row 0214 * The parser is designed to skip an empty row so we can 0215 * test this for a boundary case. i.e. newline at the end. 0216 */ 0217 QHash<QString, QVariant> row_content = test_parser_->ReadNextRow(); 0218 qDebug() << row_content["field1"]; 0219 QCOMPARE(row_content["field1"].toString(), QString("Null")); 0220 QCOMPARE(row_content["field2"].toString(), QString("Null")); 0221 QCOMPARE(row_content["field3"].toString(), QString("Null")); 0222 QCOMPARE(row_content["field4"].toString(), QString("Null")); 0223 QCOMPARE(row_content["field5"].toString(), QString("Null")); 0224 QCOMPARE(row_content["field6"].toInt(), 0); 0225 QCOMPARE(row_content["field7"].toString(), QString("Null")); 0226 QCOMPARE(row_content["field8"].toString(), QString("Null")); 0227 QCOMPARE(row_content["field9"].toString(), QString("Null")); 0228 QCOMPARE(row_content["field10"].toFloat(), float(0.0)); 0229 QCOMPARE(row_content["field11"].toString(), QString("Null")); 0230 QCOMPARE(row_content["field12"].toString(), QString("Null")); 0231 } 0232 0233 void TestCSVParser::CSVIgnoreHasNextRow() 0234 { 0235 QHash<QString, QVariant> row_content; 0236 for (int times = 0; times < 20; times++) 0237 { 0238 row_content = test_parser_->ReadNextRow(); 0239 QCOMPARE(row_content["field1"].toString(), QString("Null")); 0240 QCOMPARE(row_content["field2"].toString(), QString("Null")); 0241 QCOMPARE(row_content["field3"].toString(), QString("Null")); 0242 QCOMPARE(row_content["field4"].toString(), QString("Null")); 0243 QCOMPARE(row_content["field5"].toString(), QString("Null")); 0244 QCOMPARE(row_content["field6"].toInt(), 0); 0245 QCOMPARE(row_content["field7"].toString(), QString("Null")); 0246 QCOMPARE(row_content["field8"].toString(), QString("Null")); 0247 QCOMPARE(row_content["field9"].toString(), QString("Null")); 0248 QCOMPARE(row_content["field10"].toFloat(), float(0.0)); 0249 QCOMPARE(row_content["field11"].toString(), QString("Null")); 0250 QCOMPARE(row_content["field12"].toString(), QString("Null")); 0251 } 0252 } 0253 0254 void TestCSVParser::CSVReadMissingFile() 0255 { 0256 /* 0257 * Test 6. Attempt to read a missing file repeatedly 0258 */ 0259 QFile::remove(test_file_name_); 0260 0261 KSParser missing_parser(test_file_name_, '#', sequence_); 0262 QHash<QString, QVariant> row_content = missing_parser.ReadNextRow(); 0263 0264 for (int times = 0; times < 20; times++) 0265 { 0266 row_content = missing_parser.ReadNextRow(); 0267 QCOMPARE(row_content["field1"].toString(), QString("Null")); 0268 QCOMPARE(row_content["field2"].toString(), QString("Null")); 0269 QCOMPARE(row_content["field3"].toString(), QString("Null")); 0270 QCOMPARE(row_content["field4"].toString(), QString("Null")); 0271 QCOMPARE(row_content["field5"].toString(), QString("Null")); 0272 QCOMPARE(row_content["field6"].toInt(), 0); 0273 QCOMPARE(row_content["field7"].toString(), QString("Null")); 0274 QCOMPARE(row_content["field8"].toString(), QString("Null")); 0275 QCOMPARE(row_content["field9"].toString(), QString("Null")); 0276 QCOMPARE(row_content["field10"].toFloat(), float(0.0)); 0277 QCOMPARE(row_content["field11"].toString(), QString("Null")); 0278 QCOMPARE(row_content["field12"].toString(), QString("Null")); 0279 } 0280 } 0281 0282 QTEST_GUILESS_MAIN(TestCSVParser)