1 #include <cppunit/CompilerOutputter.h>
2 #include <cppunit/TestCaller.h>
3 #include <cppunit/TestFixture.h>
4 #include <cppunit/extensions/TestFactoryRegistry.h>
5 #include <cppunit/ui/text/TestRunner.h>
6
7 #include "csvline.hh"
8
9 class CSVLineTest : public CppUnit::TestFixture {
10 public:
suite()11 static CppUnit::TestSuite *suite() {
12 CppUnit::TestSuite *suiteOfTests = new CppUnit::TestSuite("CSV Line");
13
14 suiteOfTests->addTest(new CppUnit::TestCaller<CSVLineTest>(
15 "should produce correct line on empty fields",
16 &CSVLineTest::getEmptyLine));
17
18 suiteOfTests->addTest(new CppUnit::TestCaller<CSVLineTest>(
19 "should return fields unescaped",
20 &CSVLineTest::getFieldsUnescaped));
21
22 suiteOfTests->addTest(new CppUnit::TestCaller<CSVLineTest>(
23 "should produce correct line", &CSVLineTest::getLine));
24
25 suiteOfTests->addTest(new CppUnit::TestCaller<CSVLineTest>(
26 "should throw on adding to much fields",
27 &CSVLineTest::throwTooMuchFields));
28
29 suiteOfTests->addTest(new CppUnit::TestCaller<CSVLineTest>(
30 "should throw on getting invalid index",
31 &CSVLineTest::throwInvalidIndex));
32
33 suiteOfTests->addTest(new CppUnit::TestCaller<CSVLineTest>(
34 "should parse line correctly", &CSVLineTest::parseLine));
35
36 suiteOfTests->addTest(new CppUnit::TestCaller<CSVLineTest>(
37 "should parse corner case lines correctly",
38 &CSVLineTest::parseCornerCases));
39
40 suiteOfTests->addTest(new CppUnit::TestCaller<CSVLineTest>(
41 "should parse empty CSV line correctly",
42 &CSVLineTest::parseEmptyCsvLine));
43
44 suiteOfTests->addTest(new CppUnit::TestCaller<CSVLineTest>(
45 "should throw on empty line", &CSVLineTest::throwEmptyLine));
46
47 suiteOfTests->addTest(new CppUnit::TestCaller<CSVLineTest>(
48 "should throw on malformed line",
49 &CSVLineTest::throwMalformedLine));
50
51 suiteOfTests->addTest(new CppUnit::TestCaller<CSVLineTest>(
52 "should use different separator", &CSVLineTest::separator));
53
54 return suiteOfTests;
55 }
56
getEmptyLine()57 void getEmptyLine() {
58 yapet::CSVLine csvLine{3};
59
60 std::string actual{csvLine.getLine()};
61 std::string expected{",,"};
62 CPPUNIT_ASSERT_EQUAL(expected, actual);
63 }
64
getFieldsUnescaped()65 void getFieldsUnescaped() {
66 yapet::CSVLine csvLine{1};
67
68 csvLine.addField(0, "\",\"");
69
70 std::string actual{csvLine[0]};
71 std::string expected{","};
72 CPPUNIT_ASSERT_EQUAL(expected, actual);
73 }
74
getLine()75 void getLine() {
76 yapet::CSVLine csvLine{3};
77
78 csvLine.addField(0, "Field 1");
79 csvLine.addField(1, "Field,2");
80 csvLine.addField(2, "Field\",3");
81
82 std::string actual{csvLine.getLine()};
83 std::string expected{"Field 1,\"Field,2\",\"Field\"\",3\""};
84 CPPUNIT_ASSERT_EQUAL(expected, actual);
85 }
86
throwTooMuchFields()87 void throwTooMuchFields() {
88 yapet::CSVLine csvLine{2};
89
90 CPPUNIT_ASSERT_THROW(csvLine.addField(3, ""), std::out_of_range);
91 CPPUNIT_ASSERT_THROW(csvLine[3], std::out_of_range);
92 }
93
throwInvalidIndex()94 void throwInvalidIndex() {
95 yapet::CSVLine csvLine{2};
96 CPPUNIT_ASSERT_THROW(csvLine[3], std::out_of_range);
97 }
98
parseLine()99 void parseLine() {
100 yapet::CSVLine csvLine1{3};
101 csvLine1.parseLine("a,b,c");
102 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine1[0]);
103 CPPUNIT_ASSERT_EQUAL(std::string{"b"}, csvLine1[1]);
104 CPPUNIT_ASSERT_EQUAL(std::string{"c"}, csvLine1[2]);
105
106 yapet::CSVLine csvLine2{1};
107 csvLine2.parseLine("a");
108 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine2[0]);
109
110 yapet::CSVLine csvLine3{2};
111 CPPUNIT_ASSERT_THROW(csvLine3.parseLine("a,b,c"),
112 std::invalid_argument);
113
114 yapet::CSVLine csvLine4{2};
115 CPPUNIT_ASSERT_THROW(csvLine4.parseLine("a"), std::invalid_argument);
116 }
117
parseCornerCases()118 void parseCornerCases() {
119 yapet::CSVLine csvLine2{2};
120 csvLine2.parseLine("\"a,\",b\"");
121 CPPUNIT_ASSERT_EQUAL(std::string{"a,"}, csvLine2[0]);
122 CPPUNIT_ASSERT_EQUAL(std::string{"b\""}, csvLine2[1]);
123
124 yapet::CSVLine csvLine3{3};
125 csvLine3.parseLine("a,b\",");
126 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[0]);
127 CPPUNIT_ASSERT_EQUAL(std::string{"b\""}, csvLine3[1]);
128 CPPUNIT_ASSERT_EQUAL(std::string{}, csvLine3[2]);
129
130 csvLine3.parseLine("a,\"b,\"\"\",");
131 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[0]);
132 CPPUNIT_ASSERT_EQUAL(std::string{"b,\""}, csvLine3[1]);
133 CPPUNIT_ASSERT_EQUAL(std::string{}, csvLine3[2]);
134
135 // Start of line
136 csvLine3.parseLine("\"\"\"\",a,");
137 CPPUNIT_ASSERT_EQUAL(std::string{"\""}, csvLine3[0]);
138 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[1]);
139 CPPUNIT_ASSERT_EQUAL(std::string{}, csvLine3[2]);
140
141 csvLine3.parseLine("\",\"\"\",a,");
142 CPPUNIT_ASSERT_EQUAL(std::string{",\""}, csvLine3[0]);
143 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[1]);
144 CPPUNIT_ASSERT_EQUAL(std::string{}, csvLine3[2]);
145
146 csvLine3.parseLine("\"\"\",\",a,");
147 CPPUNIT_ASSERT_EQUAL(std::string{"\","}, csvLine3[0]);
148 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[1]);
149 CPPUNIT_ASSERT_EQUAL(std::string{}, csvLine3[2]);
150
151 // In middle of line
152 csvLine3.parseLine("a,\"\"\"\",");
153 CPPUNIT_ASSERT_EQUAL(std::string{"\""}, csvLine3[1]);
154 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[0]);
155 CPPUNIT_ASSERT_EQUAL(std::string{}, csvLine3[2]);
156
157 csvLine3.parseLine("a,\",\"\"\",");
158 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[0]);
159 CPPUNIT_ASSERT_EQUAL(std::string{",\""}, csvLine3[1]);
160 CPPUNIT_ASSERT_EQUAL(std::string{}, csvLine3[2]);
161
162 csvLine3.parseLine("a,\"\"\",\",");
163 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[0]);
164 CPPUNIT_ASSERT_EQUAL(std::string{"\","}, csvLine3[1]);
165 CPPUNIT_ASSERT_EQUAL(std::string{}, csvLine3[2]);
166
167 // at end of line
168 csvLine3.parseLine("a,b,\"\"\"\"");
169 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[0]);
170 CPPUNIT_ASSERT_EQUAL(std::string{"b"}, csvLine3[1]);
171 CPPUNIT_ASSERT_EQUAL(std::string{"\""}, csvLine3[2]);
172
173 csvLine3.parseLine("a,b,\",\"\"\"");
174 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[0]);
175 CPPUNIT_ASSERT_EQUAL(std::string{"b"}, csvLine3[1]);
176 CPPUNIT_ASSERT_EQUAL(std::string{",\""}, csvLine3[2]);
177
178 csvLine3.parseLine("a,,\"\"\",\"");
179 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[0]);
180 CPPUNIT_ASSERT_EQUAL(std::string{""}, csvLine3[1]);
181 CPPUNIT_ASSERT_EQUAL(std::string{"\","}, csvLine3[2]);
182
183 csvLine3.parseLine("a,\"b\",\"c\"");
184 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[0]);
185 CPPUNIT_ASSERT_EQUAL(std::string{"b"}, csvLine3[1]);
186 CPPUNIT_ASSERT_EQUAL(std::string{"c"}, csvLine3[2]);
187
188 csvLine2.parseLine("a\",b");
189 CPPUNIT_ASSERT_EQUAL(std::string{"a\""}, csvLine2[0]);
190 CPPUNIT_ASSERT_EQUAL(std::string{"b"}, csvLine2[1]);
191
192 csvLine2.parseLine("a,\"b\"\",c\"");
193 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine2[0]);
194 CPPUNIT_ASSERT_EQUAL(std::string{"b\",c"}, csvLine2[1]);
195
196 csvLine2.parseLine("a,\"\"");
197 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine2[0]);
198 CPPUNIT_ASSERT_EQUAL(std::string{""}, csvLine2[1]);
199
200 csvLine3.parseLine("a,\"\",\",\"");
201 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[0]);
202 CPPUNIT_ASSERT_EQUAL(std::string{""}, csvLine3[1]);
203 CPPUNIT_ASSERT_EQUAL(std::string{","}, csvLine3[2]);
204
205 csvLine3.parseLine("a,\"\"\"\",\",\"");
206 CPPUNIT_ASSERT_EQUAL(std::string{"a"}, csvLine3[0]);
207 CPPUNIT_ASSERT_EQUAL(std::string{"\""}, csvLine3[1]);
208 CPPUNIT_ASSERT_EQUAL(std::string{","}, csvLine3[2]);
209 }
210
parseEmptyCsvLine()211 void parseEmptyCsvLine() {
212 yapet::CSVLine csvLine{3};
213 csvLine.parseLine(",,");
214
215 CPPUNIT_ASSERT_EQUAL(std::string{}, csvLine[0]);
216 CPPUNIT_ASSERT_EQUAL(std::string{}, csvLine[1]);
217 CPPUNIT_ASSERT_EQUAL(std::string{}, csvLine[2]);
218 }
219
throwEmptyLine()220 void throwEmptyLine() {
221 yapet::CSVLine csvLine{3};
222 CPPUNIT_ASSERT_THROW(csvLine.parseLine(""), std::invalid_argument);
223 }
224
throwMalformedLine()225 void throwMalformedLine() {
226 yapet::CSVLine csvLine1{3};
227 CPPUNIT_ASSERT_THROW(csvLine1.parseLine("a,\"b,c"),
228 std::invalid_argument);
229 }
230
separator()231 void separator() {
232 yapet::CSVLine csvLine1{4, ';'};
233 csvLine1.parseLine("\"a;\";b\"\";\"c;\"\"\";\"d\"");
234 CPPUNIT_ASSERT_EQUAL(std::string{"a;"}, csvLine1[0]);
235 CPPUNIT_ASSERT_EQUAL(std::string{"b\"\""}, csvLine1[1]);
236 CPPUNIT_ASSERT_EQUAL(std::string{"c;\""}, csvLine1[2]);
237 CPPUNIT_ASSERT_EQUAL(std::string{"d"}, csvLine1[3]);
238
239 yapet::CSVLine csvLine2{3, ';'};
240 csvLine2.addField(0, "Field 1");
241 csvLine2.addField(1, "Field;2");
242 csvLine2.addField(2, "Field\";3");
243
244 std::string actual{csvLine2.getLine()};
245 std::string expected{"Field 1;\"Field;2\";\"Field\"\";3\""};
246 CPPUNIT_ASSERT_EQUAL(expected, actual);
247 }
248 };
249
main()250 int main() {
251 CppUnit::TextUi::TestRunner runner;
252 runner.addTest(CSVLineTest::suite());
253 return runner.run() ? 0 : 1;
254 }