1 /***************************************************************************
2  *                                                                         *
3  *   Copyright : (C) 2012 Peter Kümmel                                     *
4  *   email     : syntheticpp@gmx.net                                       *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  ***************************************************************************/
12 
13 #define KST_SMALL_PRREALLOC
14 
15 #include "asciifilebuffer.h"
16 
17 #include <QtTest>
18 
19 namespace QTest
20 {
21     template<>
qCompare(qint64 const & t1,qint32 const & t2,const char * actual,const char * expected,const char * file,int line)22     bool qCompare<qint64, qint32>(qint64 const &t1, qint32 const &t2, const char *actual, const char *expected, const char *file, int line)
23     {
24         return qCompare<qint64>(t1, qint64(t2), actual, expected, file, line);
25     }
26 }
27 
28 
29 class AsciiSourceTest: public QObject
30 {
31     Q_OBJECT
32 
33 public:
34 
AsciiSourceTest()35     AsciiSourceTest()
36     {
37     }
38 
39 private slots:
40 
initTestcase()41     void initTestcase()
42     {
43       buf.setFile(&file);
44     }
45 
46 
47     // int findRowOfPosition(const AsciiFileBuffer::RowIndex& rowIndex, int searchStart, int pos) const
48 
find_wrong_parameters()49     void find_wrong_parameters()
50     {
51       int rows = 3;
52       int rowLength = 100;
53       initRowIndex(rows, rowLength);
54       QCOMPARE(buf.findRowOfPosition(idx, 0, -1), -1);
55       QCOMPARE(buf.findRowOfPosition(AsciiFileBuffer::RowIndex(), 0, 1), -1);
56       QCOMPARE(buf.findRowOfPosition(idx, 5,  1), -1);
57       QCOMPARE(buf.findRowOfPosition(idx, 1, 99), -1);
58     }
59 
60 
find_small()61     void find_small()
62     {
63       int rows = 1;
64       int rowLength = 1;
65       initRowIndex(rows, rowLength);
66       QCOMPARE(buf.findRowOfPosition(idx, 0,  0), 0);
67       QCOMPARE(buf.findRowOfPosition(idx, 0,  1), -1);
68       QCOMPARE(buf.findRowOfPosition(idx, 0,  2), -1);
69 
70       rows = 2;
71       rowLength = 1;
72       initRowIndex(rows, rowLength);
73       QCOMPARE(buf.findRowOfPosition(idx, 0,  0), 0);
74       QCOMPARE(buf.findRowOfPosition(idx, 0,  1), 1);
75       QCOMPARE(buf.findRowOfPosition(idx, 0,  2), -1);
76 
77       rows = 3;
78       rowLength = 1;
79       initRowIndex(rows, rowLength);
80       QCOMPARE(buf.findRowOfPosition(idx, 0,  0), 0);
81       QCOMPARE(buf.findRowOfPosition(idx, 0,  1), 1);
82       QCOMPARE(buf.findRowOfPosition(idx, 0,  2), 2);
83       QCOMPARE(buf.findRowOfPosition(idx, 0,  3), -1);
84 
85       rows = 1;
86       rowLength = 2;
87       initRowIndex(rows, rowLength);
88       QCOMPARE(buf.findRowOfPosition(idx, 0,  0), 0);
89       QCOMPARE(buf.findRowOfPosition(idx, 0,  1), 0);
90       QCOMPARE(buf.findRowOfPosition(idx, 0,  2), -1);
91       QCOMPARE(buf.findRowOfPosition(idx, 0,  3), -1);
92     }
93 
94 
find_start_0()95     void find_start_0()
96     {
97       int rows = 1;
98       int rowLength = 100;
99       initRowIndex(rows, rowLength);
100 
101       QCOMPARE(buf.findRowOfPosition(idx, 0,   0), 0);
102       QCOMPARE(buf.findRowOfPosition(idx, 0,   1), 0);
103       QCOMPARE(buf.findRowOfPosition(idx, 0,  99), 0);
104       QCOMPARE(buf.findRowOfPosition(idx, 0, 100), -1);
105       QCOMPARE(buf.findRowOfPosition(idx, 0, 101), -1);
106       QCOMPARE(buf.findRowOfPosition(idx, 0, 199), -1);
107 
108       rows = 2;
109       rowLength = 100;
110       initRowIndex(rows, rowLength);
111 
112       QCOMPARE(buf.findRowOfPosition(idx, 0,   0), 0);
113       QCOMPARE(buf.findRowOfPosition(idx, 0,   1), 0);
114       QCOMPARE(buf.findRowOfPosition(idx, 0,  99), 0);
115       QCOMPARE(buf.findRowOfPosition(idx, 0, 100), 1);
116       QCOMPARE(buf.findRowOfPosition(idx, 0, 101), 1);
117       QCOMPARE(buf.findRowOfPosition(idx, 0, 199), 1);
118       QCOMPARE(buf.findRowOfPosition(idx, 0, 200), -1);
119       QCOMPARE(buf.findRowOfPosition(idx, 0, 201), -1);
120       QCOMPARE(buf.findRowOfPosition(idx, 0, 299), -1);
121 
122       rows = 3;
123       rowLength = 100;
124       initRowIndex(rows, rowLength);
125 
126       QCOMPARE(buf.findRowOfPosition(idx, 0,   0), 0);
127       QCOMPARE(buf.findRowOfPosition(idx, 0,   1), 0);
128       QCOMPARE(buf.findRowOfPosition(idx, 0,  99), 0);
129       QCOMPARE(buf.findRowOfPosition(idx, 0, 100), 1);
130       QCOMPARE(buf.findRowOfPosition(idx, 0, 101), 1);
131       QCOMPARE(buf.findRowOfPosition(idx, 0, 199), 1);
132       QCOMPARE(buf.findRowOfPosition(idx, 0, 200), 2);
133       QCOMPARE(buf.findRowOfPosition(idx, 0, 201), 2);
134       QCOMPARE(buf.findRowOfPosition(idx, 0, 299), 2);
135       QCOMPARE(buf.findRowOfPosition(idx, 0, 300), -1);
136       QCOMPARE(buf.findRowOfPosition(idx, 0, 301), -1);
137       QCOMPARE(buf.findRowOfPosition(idx, 0, 399), -1);
138     }
139 
140 
find_start_n()141     void find_start_n()
142     {
143       int rows = 3;
144       int rowLength = 100;
145       initRowIndex(rows, rowLength);
146 
147       QCOMPARE(buf.findRowOfPosition(idx, 0, 100), 1);
148       QCOMPARE(buf.findRowOfPosition(idx, 1, 100), 1);
149 
150       QCOMPARE(buf.findRowOfPosition(idx, 0, 101), 1);
151       QCOMPARE(buf.findRowOfPosition(idx, 1, 101), 1);
152 
153     }
154 
155 
156     // const QVector<AsciiFileData> splitFile(int chunkSize, const RowIndex& rowIndex, int start, int bytesToRead) const;
157 
split_wrong_parameters()158     void split_wrong_parameters()
159     {
160       int rows = 1;
161       int rowLength = 1;
162       initRowIndex(rows, rowLength);
163       QCOMPARE(buf.splitFile(1, AsciiFileBuffer::RowIndex(), 0, 1).size(), 0);
164       QCOMPARE(buf.splitFile(-1, idx, 0, 1).size(), 0);
165       QCOMPARE(buf.splitFile(1, idx, -1, 1).size(), 0);
166       QCOMPARE(buf.splitFile(1, idx, -1, 1).size(), 0);
167       QCOMPARE(buf.splitFile(1, idx, 10, 1).size(), 0);
168       QCOMPARE(buf.splitFile(1, idx,  0, 2).size(), 0);
169     }
170 
171 
split_small()172     void split_small()
173     {
174       int rows = 1;
175       int rowLength = 1;
176       initRowIndex(rows, rowLength);
177       QVector<AsciiFileData> c = buf.splitFile(1, idx, 0, 1);
178       QCOMPARE(c.size(), 1);
179       QCOMPARE(c[0].begin(), 0);
180       QCOMPARE(c[0].bytesRead(), 1);
181       QCOMPARE(c[0].rowBegin(), 0);
182       QCOMPARE(c[0].rowsRead(), 1);
183 
184       rows = 2;
185       rowLength = 1;
186       initRowIndex(rows, rowLength);
187       c = buf.splitFile(1, idx, 0, 2);
188       QCOMPARE(c.size(), 2);
189       QCOMPARE(c[0].begin(), 0);
190       QCOMPARE(c[0].bytesRead(), 1);
191       QCOMPARE(c[0].rowBegin(), 0);
192       QCOMPARE(c[0].rowsRead(), 1);
193       QCOMPARE(c[1].begin(), 1);
194       QCOMPARE(c[1].bytesRead(), 1);
195       QCOMPARE(c[1].rowBegin(), 1);
196       QCOMPARE(c[1].rowsRead(), 1);
197 
198       rows = 3;
199       rowLength = 1;
200       initRowIndex(rows, rowLength);
201       c = buf.splitFile(1, idx, 0, 3);
202       QCOMPARE(c.size(), 3);
203       QCOMPARE(c[2].begin(), 2);
204       QCOMPARE(c[2].bytesRead(), 1);
205       QCOMPARE(c[2].rowBegin(), 2);
206       QCOMPARE(c[2].rowsRead(), 1);
207 
208 
209       rows = 1;
210       rowLength = 2;
211       initRowIndex(rows, rowLength);
212       c = buf.splitFile(2, idx, 0, 2);
213       QCOMPARE(c.size(), 1);
214       QCOMPARE(c[0].begin(), 0);
215       QCOMPARE(c[0].bytesRead(), 2);
216       QCOMPARE(c[0].rowBegin(), 0);
217       QCOMPARE(c[0].rowsRead(), 1);
218 
219       rows = 2;
220       rowLength = 2;
221       initRowIndex(rows, rowLength);
222       c = buf.splitFile(2, idx, 0, 4);
223       QCOMPARE(c.size(), 2);
224       QCOMPARE(c[0].begin(), 0);
225       QCOMPARE(c[0].bytesRead(), 2);
226       QCOMPARE(c[0].rowBegin(), 0);
227       QCOMPARE(c[0].rowsRead(), 1);
228       QCOMPARE(c[1].begin(), 2);
229       QCOMPARE(c[1].bytesRead(), 2);
230       QCOMPARE(c[1].rowBegin(), 1);
231       QCOMPARE(c[1].rowsRead(), 1);
232 
233       // chunk ends in the middle of a row
234       rows = 2;
235       rowLength = 3;
236       initRowIndex(rows, rowLength);
237       c = buf.splitFile(5, idx, 0, 6);
238       QCOMPARE(c.size(), 2);
239       QCOMPARE(c[0].begin(), 0);
240       QCOMPARE(c[0].bytesRead(), 3);
241       QCOMPARE(c[0].rowBegin(), 0);
242       QCOMPARE(c[0].rowsRead(), 1);
243       QCOMPARE(c[1].begin(), 3);
244       QCOMPARE(c[1].bytesRead(), 3);
245       QCOMPARE(c[1].rowBegin(), 1);
246       QCOMPARE(c[1].rowsRead(), 1);
247 
248       rows = 1;
249       rowLength = 2;
250       initRowIndex(rows, rowLength);
251       c = buf.splitFile(1, idx, 0, 2);
252       QCOMPARE(c.size(), 0); // chunk size to small for one row
253     }
254 
255 
split_into_1()256     void split_into_1()
257     {
258       int rows = 3;
259       int rowLength = 100;
260       int bytes = rows * rowLength;
261       initRowIndex(rows, rowLength);
262       QVector<AsciiFileData> c = buf.splitFile(rows * rowLength, idx, 0, bytes);
263       QCOMPARE(c[0].begin(), 0);
264       QCOMPARE(c[0].bytesRead(), bytes);
265 
266       idx[0] = 10;
267       bytes -= 10;
268       c = buf.splitFile(rows * rowLength, idx, 10, bytes);
269       QCOMPARE(c[0].begin(), 10);
270       QCOMPARE(c[0].bytesRead(), bytes);
271     }
272 
273 
split_into_3()274     void split_into_3()
275     {
276       int rows = 3;
277       int rowLength = 100;
278       int bytes = rows * rowLength;
279       initRowIndex(rows, rowLength);
280       QVector<AsciiFileData> c = buf.splitFile(rowLength, idx, 0, bytes);
281       QCOMPARE(c.size(), 3);
282       QCOMPARE(c[0].begin(), idx[0]);
283       QCOMPARE(c[1].begin(), idx[1]);
284       QCOMPARE(c[2].begin(), idx[2]);
285     }
286 
287 
split()288     void split()
289     {
290       int rows = 999;
291       int rowLength = 100;
292       int bytes = rows * rowLength;
293       initRowIndex(rows, rowLength);
294       QVector<AsciiFileData> c = buf.splitFile(rowLength * 100, idx, 0, bytes);
295       QCOMPARE(c.size(), 10);
296       QCOMPARE(c[0].begin(), idx[0]);
297       QCOMPARE(c[1].rowsRead(), 100);
298       QCOMPARE(c[1].begin(), idx[100]);
299       QCOMPARE(c[1].rowsRead(), 100);
300       QCOMPARE(c[9].begin(), idx[900]);
301       QCOMPARE(c[9].rowsRead(), 99);
302 
303       int rowsRead = 0;
304       for (int i=0; i < 10; i++) {
305         rowsRead += c[i].rowsRead();
306       }
307       QCOMPARE(rowsRead, rows);
308     }
309 
310 
split_equal_chunkSize_is_bytesToRead()311     void split_equal_chunkSize_is_bytesToRead()
312     {
313       int rows = 20;
314       int rowLength = 10;
315       int offset = 5;
316       int bytesToRead = (rows - offset) * rowLength;
317       initRowIndex(rows, rowLength);
318       int start = offset * rowLength;
319       QVector<AsciiFileData> c = buf.splitFile(bytesToRead, idx, start, bytesToRead);
320       QCOMPARE(c.size(), 1);
321       QCOMPARE(c[0].bytesRead(), bytesToRead);
322       QCOMPARE(c[0].begin(), idx[offset]);
323       QCOMPARE(c[0].rowsRead(), rows - offset);
324     }
325 
326     //void useOneWindowWithChunks(const RowIndex& rowIndex, int start, int bytesToRead, int numChunks);
327 
useOneWindowWithChunks_small()328     void useOneWindowWithChunks_small()
329     {
330       int rows = 1;
331       int rowLength = 1;
332       initRowIndex(rows, rowLength);
333       buf.useOneWindowWithChunks(idx, 0, 1, 1);
334       QVector<QVector<AsciiFileData> > d = buf.fileData();
335       QCOMPARE(d.size(), 1);
336       QCOMPARE(d[0].size(), 1);
337 
338       rows = 2;
339       rowLength = 1;
340       initRowIndex(rows, rowLength);
341       buf.useOneWindowWithChunks(idx, 0, 2, 1);
342       d = buf.fileData();
343       QCOMPARE(d.size(), 1);
344       QCOMPARE(d[0].size(), 1); // only data for one chunk
345 
346       rows = 2;
347       rowLength = 1;
348       initRowIndex(rows, rowLength);
349       buf.useOneWindowWithChunks(idx, 0, 2, 2);
350       d = buf.fileData();
351       QCOMPARE(d.size(), 1);
352       QCOMPARE(d[0].size(), 2);
353 
354       rows = 3;
355       rowLength = 1;
356       initRowIndex(rows, rowLength);
357       buf.useOneWindowWithChunks(idx, 0, 3, 2);
358       d = buf.fileData();
359       QCOMPARE(d.size(), 1);
360       QCOMPARE(d[0].size(), 3); // more than 2 chunks needed
361     }
362 
useOneWindowWithChunks()363     void useOneWindowWithChunks()
364     {
365       int rows = 1000;
366       int rowLength = 100;
367       int bytes = rows * rowLength;
368       initRowIndex(rows, rowLength);
369       buf.useOneWindowWithChunks(idx, 0, bytes, 1);
370       QVector<QVector<AsciiFileData> > d = buf.fileData();
371       QCOMPARE(d.size(), 1);
372       QCOMPARE(d[0].size(), 1);
373 
374       buf.useOneWindowWithChunks(idx, 0, bytes, 10);
375       d = buf.fileData();
376       QCOMPARE(d.size(), 1);
377       QCOMPARE(d[0].size(), 10);
378 
379       buf.useOneWindowWithChunks(idx, 0, bytes, 1000);
380       d = buf.fileData();
381       QCOMPARE(d.size(), 1);
382       QCOMPARE(d[0].size(), 1000);
383 
384       buf.useOneWindowWithChunks(idx, 0, bytes, 1001); // row too long for implizit chunk size
385       d = buf.fileData();
386       QCOMPARE(d.size(), 0);
387     }
388 
389 
390     // void useSlidingWindow(const RowIndex& rowIndex, int start, int bytesToRead, int windowSize);
391 
useSlidingWindow_small()392     void useSlidingWindow_small()
393     {
394       int rows = 1;
395       int rowLength = 1;
396       initRowIndex(rows, rowLength);
397       int windowSize = 1;
398       buf.useSlidingWindow(idx, 0, 1, windowSize);
399       QVector<QVector<AsciiFileData> > d = buf.fileData();
400       QCOMPARE(d.size(), 1);
401       QCOMPARE(d[0].size(), 1);
402 
403       rows = 2;
404       rowLength = 1;
405       initRowIndex(rows, rowLength);
406       windowSize = 1;
407       buf.useSlidingWindow(idx, 0, 2, windowSize);
408       d = buf.fileData();
409       QCOMPARE(d.size(), 2);
410       QCOMPARE(d[0].size(), 1);
411       QCOMPARE(d[1].size(), 1);
412     }
413 
414 
useSlidingWindow()415     void useSlidingWindow()
416     {
417       int rows = 1000;
418       int rowLength = 100;
419       int bytes = rows * rowLength;
420       initRowIndex(rows, rowLength);
421       int windowSize = rowLength;
422       buf.useSlidingWindow(idx, 0, bytes, windowSize);
423       QVector<QVector<AsciiFileData> > d = buf.fileData();
424       QCOMPARE(d.size(), 1000);
425       QCOMPARE(d[0].size(), 1);
426 
427       rows = 999;
428       rowLength = 100;
429       bytes = rows * rowLength;
430       windowSize = rowLength * 100;
431       buf.useSlidingWindow(idx, 0, bytes, windowSize);
432       d = buf.fileData();
433       QCOMPARE(d.size(), 10);
434       QCOMPARE(d[0].size(), 1);
435       QCOMPARE(d[0][0].begin(), 0);
436       QCOMPARE(d[0][0].bytesRead(), rowLength * 100);
437       QCOMPARE(d[0][0].rowBegin(), 0);
438       QCOMPARE(d[1].size(), 1);
439       QCOMPARE(d[1][0].rowBegin(), 100);
440 
441       int rowsRead = 0;
442       for (int i=0; i < 10; i++) {
443         rowsRead += d[i][0].rowsRead();
444       }
445       QCOMPARE(rowsRead, rows);
446     }
447 
448 
449     // void useSlidingWindowWithChunks(const RowIndex& rowIndex, int start, int bytesToRead, int windowSize, int numWindowChunks)
450 
useSlidingWindowWithChunks_small()451     void useSlidingWindowWithChunks_small()
452     {
453       int rows = 1;
454       int rowLength = 1;
455       int bytes = rows * rowLength;
456       initRowIndex(rows, rowLength);
457       int windowSize = 1;
458       buf.useSlidingWindowWithChunks(idx, 0, bytes, windowSize, 1);
459       QVector<QVector<AsciiFileData> > d = buf.fileData();
460       QCOMPARE(d.size(), 1);
461       QCOMPARE(d[0].size(), 1);
462 
463       rows = 3;
464       rowLength = 1;
465       bytes = rows * rowLength;
466       initRowIndex(rows, rowLength);
467       windowSize = 3;
468       buf.useSlidingWindowWithChunks(idx, 0, bytes, windowSize, 3);
469       d = buf.fileData();
470       QCOMPARE(d.size(), 1);
471       QCOMPARE(d[0].size(), 3);
472 
473       rows = 3;
474       rowLength = 1;
475       bytes = rows * rowLength;
476       initRowIndex(rows, rowLength);
477       windowSize = 1;
478       buf.useSlidingWindowWithChunks(idx, 0, bytes, windowSize, 3); // int chunkSize = windowSize / numWindowChunks, == 0
479       d = buf.fileData();
480       QCOMPARE(d.size(), 0);
481 
482       rows = 12;
483       rowLength = 1;
484       bytes = rows * rowLength;
485       initRowIndex(rows, rowLength);
486       windowSize = 4;
487       buf.useSlidingWindowWithChunks(idx, 0, bytes, windowSize, 1);
488       d = buf.fileData();
489       QCOMPARE(d.size(), 3);
490       QCOMPARE(d[0].size(), 1);
491       QCOMPARE(d[2].size(), 1);
492 
493       buf.useSlidingWindowWithChunks(idx, 0, bytes, windowSize, 2);
494       d = buf.fileData();
495       QCOMPARE(d.size(), 3);
496       QCOMPARE(d[0].size(), 2);
497       QCOMPARE(d[2].size(), 2);
498 
499       buf.useSlidingWindowWithChunks(idx, 0, bytes, windowSize, 3);
500       d = buf.fileData();
501       QCOMPARE(d.size(), 4);  // could not split 4 rows into 3 chunks
502       QCOMPARE(d[0].size(), 3);
503       QCOMPARE(d[1].size(), 3);
504       QCOMPARE(d[2].size(), 3);
505       QCOMPARE(d[3].size(), 3);
506     }
507 
508 
useSlidingWindowWithChunks()509     void useSlidingWindowWithChunks()
510     {
511       int rows = 1000;
512       int rowLength = 100;
513       int bytes = rows * rowLength;
514       initRowIndex(rows, rowLength);
515       int windowSize = rowLength * 100;
516       buf.useSlidingWindowWithChunks(idx, 0, bytes, windowSize, 5);
517       QVector<QVector<AsciiFileData> > d = buf.fileData();
518       QCOMPARE(d.size(), 10);
519       QCOMPARE(d[0].size(), 5);
520       QCOMPARE(d[9].size(), 5);
521     }
522 
523 
524 private:
525     AsciiFileBuffer::RowIndex idx;
526     AsciiFileBuffer buf;
527     QFile file;
528 
initRowIndex(int rows,int rowLength)529     void initRowIndex(int rows, int rowLength)
530     {
531       idx.clear();
532       idx.resize(rows + 1);
533       for (int i = 0; i < rows; i++) {
534         idx[i] = i * rowLength;
535       }
536       idx[rows] = rows * rowLength;
537     }
538 };
539 
540 
541 
542 QTEST_MAIN(AsciiSourceTest)
543 
544 
545 
546 #include "moc_asciifilebuffertest.cpp"
547