aboutsummaryrefslogtreecommitdiff
path: root/tests/src/tester.cpp
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2026-06-21 17:20:13 +0200
committerThomas Schmucker <ts@its1.de>2026-06-21 17:20:13 +0200
commit08a5f3441675c446482b473777cbba53d5191f20 (patch)
treebb462b2439317d8c3be3e542501aa3211357045c /tests/src/tester.cpp
parent7d956c533e9fd7d3bbb9a4a8b7f89f0fe54d4bc3 (diff)
downloadlibcsv-08a5f3441675c446482b473777cbba53d5191f20.tar.gz
libcsv-08a5f3441675c446482b473777cbba53d5191f20.tar.bz2
libcsv-08a5f3441675c446482b473777cbba53d5191f20.zip
rework: add testing frameworkrework
Diffstat (limited to 'tests/src/tester.cpp')
-rw-r--r--tests/src/tester.cpp476
1 files changed, 476 insertions, 0 deletions
diff --git a/tests/src/tester.cpp b/tests/src/tester.cpp
new file mode 100644
index 0000000..75f1366
--- /dev/null
+++ b/tests/src/tester.cpp
@@ -0,0 +1,476 @@
1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
3#include <stdexcept>
4
5#include "csv.h"
6
7using namespace std;
8using namespace testing;
9
10TEST(TestEmptyObject, StandardInitialization)
11{
12 csv_t csv{};
13 ASSERT_THAT(csv_nfields(&csv), Eq(0));
14}
15
16TEST(TestEmptyObject, ExplicitInitialization)
17{
18 csv_t csv;
19 csv_init(&csv);
20
21 ASSERT_THAT(csv_nfields(&csv), Eq(0));
22}
23
24class TestLineEndingsBase : public Test {
25 using file_ptr = unique_ptr<FILE, decltype(&fclose)>;
26
27public:
28 explicit TestLineEndingsBase(string_view data)
29 : data_{ data }
30 , file_{ fmemopen(data_.data(), data_.size(), "r"), &fclose }
31 {
32 csv_init(&csv_);
33 }
34
35 TestLineEndingsBase(string_view data, csv_options_t &csv_options)
36 : data_{ data }
37 , file_{ fmemopen(data_.data(), data_.size(), "r"), &fclose }
38 {
39 csv_init_opt(&csv_, &csv_options);
40 }
41
42 ~TestLineEndingsBase() override
43 {
44 csv_cleanup(&csv_);
45 }
46
47 TestLineEndingsBase(const TestLineEndingsBase &) = delete;
48 TestLineEndingsBase(TestLineEndingsBase &&) = delete;
49 void operator=(const TestLineEndingsBase &) = delete;
50 void operator=(TestLineEndingsBase &&) = delete;
51
52 csv_t csv_{};
53 string data_;
54 file_ptr file_;
55};
56
57class TestLineEndings : public TestLineEndingsBase {
58protected:
59 TestLineEndings()
60 : TestLineEndingsBase("A,B,C\r\nD,E,F\n")
61 {
62 }
63};
64
65TEST_F(TestLineEndings, Part1)
66{
67 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
68 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
69 EXPECT_STREQ(csv_field(&csv_, 0), "A");
70 EXPECT_STREQ(csv_field(&csv_, 1), "B");
71 EXPECT_STREQ(csv_field(&csv_, 2), "C");
72
73 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
74 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
75 EXPECT_STREQ(csv_field(&csv_, 0), "D");
76 EXPECT_STREQ(csv_field(&csv_, 1), "E");
77 EXPECT_STREQ(csv_field(&csv_, 2), "F");
78
79 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(0));
80}
81
82class TestEmptyLinesWithDifferentLineEndings : public TestLineEndingsBase {
83protected:
84 TestEmptyLinesWithDifferentLineEndings()
85 : TestLineEndingsBase("\r\n\n")
86 {
87 }
88};
89
90TEST_F(TestEmptyLinesWithDifferentLineEndings, Part1)
91{
92 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
93 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
94 EXPECT_STREQ(csv_field(&csv_, 0), "");
95
96 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
97 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
98 EXPECT_STREQ(csv_field(&csv_, 0), "");
99
100 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(0));
101}
102
103class TestEmptyFieldsWithDifferentLineEndings : public TestLineEndingsBase {
104 // NOLINTBEGIN
105 constexpr static const char *data = "\n" // L1
106 "\r" // L2
107 "\r\n" // L3
108 "\"\"\n" // L4
109 "\"\"\r" // L5
110 "\"\"\r\n" // L6
111 ",\n" // L7
112 ",\r" // L8
113 ",\r\n" // L9
114 "\"\",\"\"\n" // L10
115 "\"\",\"\"\r" // L11
116 "\"\",\"\"\r\n" // L12
117 ",,\n" // L13
118 ",,\r" // L14
119 ",,\r\n" // L15
120 "\"\",\"\",\n" // L16
121 "\"\",\"\",\r" // L17
122 "\"\",\"\",\r\n" // L18
123 ",,"; // L19
124
125 // NOLINTEND
126protected:
127 TestEmptyFieldsWithDifferentLineEndings()
128 : TestLineEndingsBase(data)
129 {
130 }
131};
132
133TEST_F(TestEmptyFieldsWithDifferentLineEndings, Part1)
134{
135 // Line 1
136 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
137 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
138 EXPECT_STREQ(csv_field(&csv_, 0), "");
139
140 // Line 2
141 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
142 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
143 EXPECT_STREQ(csv_field(&csv_, 0), "");
144
145 // Line 3
146 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
147 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
148 EXPECT_STREQ(csv_field(&csv_, 0), "");
149
150 // Line 4
151 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
152 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
153 EXPECT_STREQ(csv_field(&csv_, 0), "");
154
155 // Line 5
156 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
157 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
158 EXPECT_STREQ(csv_field(&csv_, 0), "");
159
160 // Line 6
161 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
162 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
163 EXPECT_STREQ(csv_field(&csv_, 0), "");
164
165 // Line 7
166 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(2));
167 EXPECT_THAT(csv_nfields(&csv_), Eq(2));
168 EXPECT_STREQ(csv_field(&csv_, 0), "");
169 EXPECT_STREQ(csv_field(&csv_, 1), "");
170
171 // Line 8
172 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(2));
173 EXPECT_THAT(csv_nfields(&csv_), Eq(2));
174 EXPECT_STREQ(csv_field(&csv_, 0), "");
175 EXPECT_STREQ(csv_field(&csv_, 1), "");
176
177 // Line 9
178 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(2));
179 EXPECT_THAT(csv_nfields(&csv_), Eq(2));
180 EXPECT_STREQ(csv_field(&csv_, 0), "");
181 EXPECT_STREQ(csv_field(&csv_, 1), "");
182
183 // Line 10
184 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(2));
185 EXPECT_THAT(csv_nfields(&csv_), Eq(2));
186 EXPECT_STREQ(csv_field(&csv_, 0), "");
187 EXPECT_STREQ(csv_field(&csv_, 1), "");
188
189 // Line 11
190 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(2));
191 EXPECT_THAT(csv_nfields(&csv_), Eq(2));
192 EXPECT_STREQ(csv_field(&csv_, 0), "");
193 EXPECT_STREQ(csv_field(&csv_, 1), "");
194
195 // Line 12
196 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(2));
197 EXPECT_THAT(csv_nfields(&csv_), Eq(2));
198 EXPECT_STREQ(csv_field(&csv_, 0), "");
199 EXPECT_STREQ(csv_field(&csv_, 1), "");
200
201 // Line 13
202 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
203 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
204 EXPECT_STREQ(csv_field(&csv_, 0), "");
205 EXPECT_STREQ(csv_field(&csv_, 1), "");
206 EXPECT_STREQ(csv_field(&csv_, 2), "");
207
208 // Line 14
209 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
210 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
211 EXPECT_STREQ(csv_field(&csv_, 0), "");
212 EXPECT_STREQ(csv_field(&csv_, 1), "");
213 EXPECT_STREQ(csv_field(&csv_, 2), "");
214
215 // Line 15
216 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
217 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
218 EXPECT_STREQ(csv_field(&csv_, 0), "");
219 EXPECT_STREQ(csv_field(&csv_, 1), "");
220 EXPECT_STREQ(csv_field(&csv_, 2), "");
221
222 // Line 16
223 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
224 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
225 EXPECT_STREQ(csv_field(&csv_, 0), "");
226 EXPECT_STREQ(csv_field(&csv_, 1), "");
227 EXPECT_STREQ(csv_field(&csv_, 2), "");
228
229 // Line 17
230 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
231 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
232 EXPECT_STREQ(csv_field(&csv_, 0), "");
233 EXPECT_STREQ(csv_field(&csv_, 1), "");
234 EXPECT_STREQ(csv_field(&csv_, 2), "");
235
236 // Line 18
237 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
238 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
239 EXPECT_STREQ(csv_field(&csv_, 0), "");
240 EXPECT_STREQ(csv_field(&csv_, 1), "");
241 EXPECT_STREQ(csv_field(&csv_, 2), "");
242
243 // Line 19
244 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
245 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
246 EXPECT_STREQ(csv_field(&csv_, 0), "");
247 EXPECT_STREQ(csv_field(&csv_, 1), "");
248 EXPECT_STREQ(csv_field(&csv_, 2), "");
249
250 // EOF
251 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(0));
252 EXPECT_THAT(csv_nfields(&csv_), Eq(0));
253}
254
255class TestFieldsWithDifferentLineEndings : public TestLineEndingsBase {
256 // NOLINTBEGIN
257 static constexpr const char *data = "A\n" // L1
258 "A\r" // L2
259 "A\r\n" // L3
260 "\"A\"\n" // L4
261 "\"A\"\r" // L5
262 "\"A\"\r\n" // L6
263 "A,B\n" // L7
264 "A,B\r" // L8
265 "A,B\r\n" // L9
266 "\"A\",\"B\"\n" // L10
267 "\"A\",\"B\"\r" // L11
268 "\"A\",\"B\"\r\n" // L12
269 "A,B,C\n" // L13
270 "A,B,C\r" // L14
271 "A,B,C\r\n" // L15
272 "\"A\",\"B\",C\n" // L16
273 "\"A\",\"B\",C\r" // L17
274 "\"A\",\"B\",C\r\n" // L18
275 "A,B,C"; // L19
276
277 // NOLINTEND
278protected:
279 TestFieldsWithDifferentLineEndings()
280 : TestLineEndingsBase(data)
281 {
282 }
283};
284
285TEST_F(TestFieldsWithDifferentLineEndings, Part1)
286{
287 // Line 1
288 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
289 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
290 EXPECT_STREQ(csv_field(&csv_, 0), "A");
291
292 // Line 2
293 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
294 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
295 EXPECT_STREQ(csv_field(&csv_, 0), "A");
296
297 // Line 3
298 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
299 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
300 EXPECT_STREQ(csv_field(&csv_, 0), "A");
301
302 // Line 4
303 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
304 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
305 EXPECT_STREQ(csv_field(&csv_, 0), "A");
306
307 // Line 5
308 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
309 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
310 EXPECT_STREQ(csv_field(&csv_, 0), "A");
311
312 // Line 6
313 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
314 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
315 EXPECT_STREQ(csv_field(&csv_, 0), "A");
316
317 // Line 7
318 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(2));
319 EXPECT_THAT(csv_nfields(&csv_), Eq(2));
320 EXPECT_STREQ(csv_field(&csv_, 0), "A");
321 EXPECT_STREQ(csv_field(&csv_, 1), "B");
322
323 // Line 8
324 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(2));
325 EXPECT_THAT(csv_nfields(&csv_), Eq(2));
326 EXPECT_STREQ(csv_field(&csv_, 0), "A");
327 EXPECT_STREQ(csv_field(&csv_, 1), "B");
328
329 // Line 9
330 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(2));
331 EXPECT_THAT(csv_nfields(&csv_), Eq(2));
332 EXPECT_STREQ(csv_field(&csv_, 0), "A");
333 EXPECT_STREQ(csv_field(&csv_, 1), "B");
334
335 // Line 10
336 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(2));
337 EXPECT_THAT(csv_nfields(&csv_), Eq(2));
338 EXPECT_STREQ(csv_field(&csv_, 0), "A");
339 EXPECT_STREQ(csv_field(&csv_, 1), "B");
340
341 // Line 11
342 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(2));
343 EXPECT_THAT(csv_nfields(&csv_), Eq(2));
344 EXPECT_STREQ(csv_field(&csv_, 0), "A");
345 EXPECT_STREQ(csv_field(&csv_, 1), "B");
346
347 // Line 12
348 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(2));
349 EXPECT_THAT(csv_nfields(&csv_), Eq(2));
350 EXPECT_STREQ(csv_field(&csv_, 0), "A");
351 EXPECT_STREQ(csv_field(&csv_, 1), "B");
352
353 // Line 13
354 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
355 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
356 EXPECT_STREQ(csv_field(&csv_, 0), "A");
357 EXPECT_STREQ(csv_field(&csv_, 1), "B");
358 EXPECT_STREQ(csv_field(&csv_, 2), "C");
359
360 // Line 14
361 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
362 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
363 EXPECT_STREQ(csv_field(&csv_, 0), "A");
364 EXPECT_STREQ(csv_field(&csv_, 1), "B");
365 EXPECT_STREQ(csv_field(&csv_, 2), "C");
366
367 // Line 15
368 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
369 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
370 EXPECT_STREQ(csv_field(&csv_, 0), "A");
371 EXPECT_STREQ(csv_field(&csv_, 1), "B");
372 EXPECT_STREQ(csv_field(&csv_, 2), "C");
373
374 // Line 16
375 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
376 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
377 EXPECT_STREQ(csv_field(&csv_, 0), "A");
378 EXPECT_STREQ(csv_field(&csv_, 1), "B");
379 EXPECT_STREQ(csv_field(&csv_, 2), "C");
380
381 // Line 17
382 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
383 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
384 EXPECT_STREQ(csv_field(&csv_, 0), "A");
385 EXPECT_STREQ(csv_field(&csv_, 1), "B");
386 EXPECT_STREQ(csv_field(&csv_, 2), "C");
387
388 // Line 18
389 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
390 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
391 EXPECT_STREQ(csv_field(&csv_, 0), "A");
392 EXPECT_STREQ(csv_field(&csv_, 1), "B");
393 EXPECT_STREQ(csv_field(&csv_, 2), "C");
394
395 // Line 19
396 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(3));
397 EXPECT_THAT(csv_nfields(&csv_), Eq(3));
398 EXPECT_STREQ(csv_field(&csv_, 0), "A");
399 EXPECT_STREQ(csv_field(&csv_, 1), "B");
400 EXPECT_STREQ(csv_field(&csv_, 2), "C");
401
402 // EOF
403 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(0));
404 EXPECT_THAT(csv_nfields(&csv_), Eq(0));
405}
406
407class TestQuotedFields : public TestLineEndingsBase {
408 // NOLINTBEGIN
409 static constexpr const char *data = "foo \"baz\" bar,foo \"\"baz\"\" bar,\"foo \"\"baz\"\" bar\",\"foo \"baz\" bar\",\"foo \"\"baz\"\", bar\"";
410 // NOLINTEND
411
412protected:
413 TestQuotedFields()
414 : TestLineEndingsBase(data)
415 {
416 }
417};
418
419TEST_F(TestQuotedFields, Part1)
420{
421 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(5));
422 EXPECT_THAT(csv_nfields(&csv_), Eq(5));
423
424 EXPECT_STREQ(csv_field(&csv_, 0), "foo \"baz\" bar");
425 EXPECT_STREQ(csv_field(&csv_, 1), "foo \"\"baz\"\" bar");
426 EXPECT_STREQ(csv_field(&csv_, 2), "foo \"baz\" bar");
427 EXPECT_STREQ(csv_field(&csv_, 3), "foo \"baz\" bar");
428 EXPECT_STREQ(csv_field(&csv_, 4), "foo \"baz\", bar");
429
430 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(0));
431 EXPECT_THAT(csv_nfields(&csv_), Eq(0));
432}
433
434class TestWrongQuotedFields : public TestLineEndingsBase {
435protected:
436 TestWrongQuotedFields()
437 : TestLineEndingsBase("\"foo")
438 {
439 }
440};
441
442TEST_F(TestWrongQuotedFields, Part1)
443{
444 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(1));
445 EXPECT_THAT(csv_nfields(&csv_), Eq(1));
446
447 EXPECT_STREQ(csv_field(&csv_, 0), "foo");
448
449 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(0));
450 EXPECT_THAT(csv_nfields(&csv_), Eq(0));
451}
452
453class TestOutOfRangeError : public TestLineEndingsBase {
454protected:
455 TestOutOfRangeError()
456 : TestLineEndingsBase(",")
457 {
458 csv_options.cb_error = &cb_error;
459 csv_init_opt(&csv_, &csv_options);
460 }
461
462 static void cb_error(csv_err_t /*unused*/, void * /*unused*/)
463 {
464 throw out_of_range("out of range");
465 }
466
467 csv_options_t csv_options{ csv_default_options };
468};
469
470TEST_F(TestOutOfRangeError, Part1)
471{
472 EXPECT_THAT(csv_read(&csv_, file_.get()), Eq(2));
473 EXPECT_THAT(csv_nfields(&csv_), Eq(2));
474
475 EXPECT_THROW({ csv_field(&csv_, 2); }, out_of_range);
476}