1 //==============================================================================
2 //
3 // This file is part of GPSTk, the GPS Toolkit.
4 //
5 // The GPSTk is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation; either version 3.0 of the License, or
8 // any later version.
9 //
10 // The GPSTk is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with GPSTk; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 // This software was developed by Applied Research Laboratories at the
20 // University of Texas at Austin.
21 // Copyright 2004-2020, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24
25 //==============================================================================
26 //
27 // This software was developed by Applied Research Laboratories at the
28 // University of Texas at Austin, under contract to an agency or agencies
29 // within the U.S. Department of Defense. The U.S. Government retains all
30 // rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 // Pursuant to DoD Directive 523024
33 //
34 // DISTRIBUTION STATEMENT A: This software has been approved for public
35 // release, distribution is unlimited.
36 //
37 //==============================================================================
38
39 #include "FileFilter.hpp"
40 #include "TestUtil.hpp"
41 #include <algorithm>
42 #include <iostream>
43 #include <list>
44
45 using namespace std;
46 using namespace gpstk;
47
48 class FileFilter_T
49 {
50 public:
51
52 // constructor
FileFilter_T()53 FileFilter_T() { init(); }
54
55 // desructor
~FileFilter_T()56 ~FileFilter_T() { cleanup(); }
57
58 // initialize tests
59 void init();
60
61 // remove file system objectst created during tests
62 void cleanup();
63
64 // test creation of an initialization of FileFilter objects
65 // @return number of failures, i.e., 0=PASS, !0=FAIL
66 int testInitialization();
67
68 // test addData(), getData(), getDataCount(), empty(), and clear()
69 // @return number of failures, i.e., 0=PASS, !0=FAIL
70 int testData();
71
72 int testBeginEnd();
73 int testFrontBack();
74 int testBack();
75 int testFilter();
76 int testSort();
77 int testMerge();
78 int testTouch();
79 int testUnique();
80 int testDiff();
81 int testFindAll();
82
83 private:
84
85 // FileFilter Test Data - dummy data class with which to run tests
86 class FFTData : public FFData
87 {
88 public:
FFTData(int val)89 FFTData(int val) : value(val) {}
~FFTData()90 ~FFTData() {}
91
92 int value;
93
94 private:
95
reallyGetRecord(FFStream & s)96 virtual void reallyGetRecord(FFStream& s)
97 { /* do nothing */ }
98
99 /// Does the actual writing from the stream into this FFData object.
reallyPutRecord(FFStream & s) const100 virtual void reallyPutRecord(FFStream& s) const
101 { /* do nothing */ }
102
103 }; // class Dummy
104
105 typedef list<FFTData> FFTDataList;
106
107 // Unary predicate that returns true for data that has an even value
108 struct IsEven
109 {
110 bool operator() (const FFTData& fftd);
111 };
112
113 // Unary predicate that returns true for data that has a value > 999
114 struct Above999
115 {
116 bool operator() (const FFTData& fftd);
117 };
118
119 // Unary operation that doubles a data element if it is divisible by 5
120 // and returns true. Elements not divisible by 5 are unchanged
121 // and false is returned.
122 struct DoubleFives
123 {
124 bool operator() (FFTData& fftd);
125 };
126
127 // Binary predicate that implements "less-than" for data values
128 struct LessThan
129 {
130 bool operator() (const FFTData& left, const FFTData& right) const;
131 };
132
133 // Binary predicate that implements "equal" for data values
134 struct Equal
135 {
136 bool operator() (const FFTData& left, const FFTData& right) const;
137 };
138
139 // emit a list of objects to standard output
140 // @param list objects to emit
141 void dump(const FFTDataList& list);
142
143 FFTDataList sampleData;
144
145 }; // class FileFilter_T
146
147
148 //---------------------------------------------------------------------------
operator ()(const FFTData & fftd)149 bool FileFilter_T :: IsEven :: operator() (const FFTData& fftd)
150 {
151 return (0 == (fftd.value % 2) );
152 }
153
154
155 //---------------------------------------------------------------------------
operator ()(const FFTData & fftd)156 bool FileFilter_T :: Above999 :: operator() (const FFTData& fftd)
157 {
158 return (fftd.value > 999);
159 }
160
161
162 //---------------------------------------------------------------------------
operator ()(FFTData & fftd)163 bool FileFilter_T :: DoubleFives :: operator() (FFTData& fftd)
164 {
165 if (0 == (fftd.value % 5) )
166 {
167 fftd.value *= 2;
168 return true;
169 }
170 return false;
171 }
172
173
174 //---------------------------------------------------------------------------
operator ()(const FFTData & left,const FFTData & right) const175 bool FileFilter_T :: LessThan :: operator() (const FFTData& left, const FFTData& right) const
176 {
177 return (left.value < right.value);
178 }
179
180
181 //---------------------------------------------------------------------------
operator ()(const FFTData & left,const FFTData & right) const182 bool FileFilter_T :: Equal :: operator() (const FFTData& left, const FFTData& right) const
183 {
184 return (left.value == right.value);
185 }
186
187
188 //---------------------------------------------------------------------------
init()189 void FileFilter_T :: init()
190 {
191 // create 100 test objects
192 for (int i = 0; i < 100; ++i)
193 sampleData.push_back( FFTData(i) );
194 }
195
196
197 //---------------------------------------------------------------------------
cleanup()198 void FileFilter_T :: cleanup()
199 {
200 // empty
201 }
202
203
204 //---------------------------------------------------------------------------
testInitialization()205 int FileFilter_T :: testInitialization()
206 {
207 TestUtil tester( "FileFilter", "initialization/getDataCount/size/empty", __FILE__, __LINE__ );
208
209 try
210 {
211 FileFilter<FFTData> ff;
212 tester.assert( true, "error creating FileFilter", __LINE__ );
213
214 tester.assert( (0 == ff.getDataCount() ), "data count should be 0", __LINE__ );
215
216 tester.assert( (0 == ff.size() ), "data size should be 0", __LINE__ );
217
218 tester.assert( ff.empty(), "data list should be empty", __LINE__ );
219 }
220 catch (...)
221 {
222 tester.assert( false, "error creating FileFilter", __LINE__ );
223 }
224
225 return tester.countFails();
226 }
227
228
229 //---------------------------------------------------------------------------
testData()230 int FileFilter_T :: testData()
231 {
232 TestUtil tester( "FileFilter", "addData/getData/getDataCount/size/empty/clear", __FILE__, __LINE__ );
233
234 try // empty data list
235 {
236 FileFilter<FFTData> ff;
237 FFTDataList list;
238 ff.addData(list);
239 tester.assert( true, "error adding data", __LINE__ );
240
241 tester.assert( (0 == ff.getDataCount() ), "data count should be 0", __LINE__ );
242
243 tester.assert( (0 == ff.size() ), "data size should be 0", __LINE__ );
244
245 tester.assert( ff.empty(), "data list should be empty", __LINE__ );
246
247 FFTDataList got = ff.getData();
248 tester.assert( true, "error getting data", __LINE__ );
249
250 tester.assert( (0 == got.size() ), "got data size should be 0", __LINE__ );
251
252 ff.clear();
253 tester.assert( true, "error clearing data", __LINE__ );
254
255 tester.assert( (0 == ff.getDataCount() ), "cleared data count should be 0", __LINE__ );
256
257 tester.assert( (0 == ff.size() ), "cleared data size should be 0", __LINE__ );
258
259 tester.assert( ff.empty(), "cleared data list should be empty", __LINE__ );
260 }
261 catch (...)
262 {
263 tester.assert( false, "error adding data", __LINE__ );
264 }
265
266 try // single-item data list
267 {
268 FileFilter<FFTData> ff;
269 FFTDataList list;
270 list.push_back( FFTData(1) );
271 ff.addData(list);
272 tester.assert( true, "error adding data", __LINE__ );
273
274 tester.assert( (1 == ff.getDataCount() ), "data count should be 1", __LINE__ );
275
276 tester.assert( (1 == ff.size() ), "data size should be 1", __LINE__ );
277
278 tester.assert( !ff.empty(), "data list should not be empty", __LINE__ );
279
280 FFTDataList got = ff.getData();
281 tester.assert( true, "error getting data", __LINE__ );
282
283 tester.assert( (1 == got.size() ), "got data size should be 1", __LINE__ );
284
285 ff.clear();
286 tester.assert( true, "error clearing data", __LINE__ );
287
288 tester.assert( (0 == ff.getDataCount() ), "cleared data count should be 0", __LINE__ );
289
290 tester.assert( (0 == ff.size() ), "cleared data size should be 0", __LINE__ );
291
292 tester.assert( ff.empty(), "cleared data list should be empty", __LINE__ );
293 }
294 catch (...)
295 {
296 tester.assert( false, "error adding data", __LINE__ );
297 }
298
299 try // many-item data list
300 {
301 FileFilter<FFTData> ff;
302 ff.addData( sampleData );
303 tester.assert( true, "error adding data", __LINE__ );
304
305 ostringstream oss;
306 oss << sampleData.size();
307
308 tester.assert( (sampleData.size() == ff.getDataCount() ),
309 "data count should be " + oss.str() , __LINE__ );
310
311 tester.assert( (sampleData.size() == ff.size() ),
312 "data size should be " + oss.str(), __LINE__ );
313
314 tester.assert( !ff.empty(), "data list should not be empty", __LINE__ );
315
316 FFTDataList got = ff.getData();
317 tester.assert( true, "error getting data", __LINE__ );
318
319 tester.assert( (sampleData.size() == got.size() ),
320 "got data size should be " + oss.str(), __LINE__ );
321
322 ff.clear();
323 tester.assert( true, "error clearing data", __LINE__ );
324
325 tester.assert( (0 == ff.getDataCount() ), "cleared data count should be 0", __LINE__ );
326
327 tester.assert( (0 == ff.size() ), "cleared data size should be 0", __LINE__ );
328
329 tester.assert( ff.empty(), "cleared data list should be empty", __LINE__ );
330 }
331 catch (...)
332 {
333 tester.assert( false, "error adding data", __LINE__ );
334 }
335
336 return tester.countFails();
337 }
338
339
340 //---------------------------------------------------------------------------
testBeginEnd()341 int FileFilter_T :: testBeginEnd()
342 {
343 TestUtil tester( "FileFilter", "begin/end", __FILE__, __LINE__ );
344
345 try // empty data list
346 {
347 FileFilter<FFTData> ff;
348
349 FFTDataList::iterator bIter = ff.begin();
350 tester.assert( true, "iterator error", __LINE__ );
351
352 FFTDataList::iterator eIter = ff.end();
353 tester.assert( true, "iterator error", __LINE__ );
354
355 tester.assert( (bIter == eIter), "iterator", __LINE__ );
356 }
357 catch (...)
358 {
359 tester.assert( false, "iterator error", __LINE__ );
360 }
361
362 try // single-item data list
363 {
364 FileFilter<FFTData> ff;
365 FFTDataList list;
366 list.push_back( FFTData(1) );
367 ff.addData(list);
368
369 FFTDataList::iterator bIter = ff.begin();
370 tester.assert( true, "iterator error", __LINE__ );
371
372 FFTDataList::iterator eIter = ff.end();
373 tester.assert( true, "iterator error", __LINE__ );
374
375 tester.assert( (bIter != eIter), "iterator", __LINE__ );
376
377 bIter++;
378 tester.assert( true, "iterator error", __LINE__ );
379
380 tester.assert( (bIter == eIter), "iterator", __LINE__ );
381 }
382 catch (...)
383 {
384 tester.assert( false, "iterator error", __LINE__ );
385 }
386
387 try // multiple-item data list
388 {
389 FileFilter<FFTData> ff;
390 ff.addData( sampleData );
391
392 FFTDataList::iterator bIter = ff.begin();
393 tester.assert( true, "iterator error", __LINE__ );
394
395 FFTDataList::iterator eIter = ff.end();
396 tester.assert( true, "iterator error", __LINE__ );
397
398 tester.assert( (bIter != eIter), "iterator error", __LINE__ );
399
400 int advances = 0;
401 FFTDataList::const_iterator sampleIter = sampleData.begin();
402 while ( (bIter != eIter) && (sampleIter != sampleData.end() ) )
403 {
404 if ( bIter->value != sampleIter->value )
405 {
406 tester.assert( false, "iterator error - value mismatch", __LINE__ );
407 break;
408 }
409 bIter++;
410 sampleIter++;
411 advances++;
412 }
413 tester.assert( (advances == sampleData.size() ), "iterator error - premature end", __LINE__ );
414
415 tester.assert( (bIter == eIter), "iterator error - end not reached", __LINE__ );
416 }
417 catch (...)
418 {
419 tester.assert( false, "iterator error", __LINE__ );
420 }
421
422 return tester.countFails();
423 }
424
425
426 //---------------------------------------------------------------------------
testFrontBack()427 int FileFilter_T :: testFrontBack()
428 {
429 TestUtil tester( "FileFilter", "front/back", __FILE__, __LINE__ );
430
431 try // empty data list - front()
432 {
433 FileFilter<FFTData> ff;
434
435 FFTData& data = ff.front();
436 tester.assert( false, "expected exception for empty list", __LINE__ );
437 }
438 catch (...)
439 {
440 tester.assert( true, "expected exception for empty list", __LINE__ );
441 }
442
443 try // empty data list - back()
444 {
445 FileFilter<FFTData> ff;
446
447 FFTData& data = ff.back();
448 tester.assert( false, "expected exception for empty list", __LINE__ );
449 }
450 catch (...)
451 {
452 tester.assert( true, "expected exception for empty list", __LINE__ );
453 }
454
455 try // single-item data list
456 {
457 FileFilter<FFTData> ff;
458 FFTDataList list;
459 list.push_back( FFTData(1) );
460 ff.addData(list);
461
462 FFTData& fdata = ff.front();
463 tester.assert( (fdata.value == 1), "error accessing list front", __LINE__ );
464
465 FFTData& bdata = ff.back();
466 tester.assert( (bdata.value == 1), "error accessing list back", __LINE__ );
467 }
468 catch (...)
469 {
470 tester.assert( false, "error accessing list front/back", __LINE__ );
471 }
472
473 try // multiple-item data list
474 {
475 FileFilter<FFTData> ff;
476 ff.addData( sampleData );
477
478 FFTData& fdata = ff.front();
479 tester.assert( (fdata.value == sampleData.front().value),
480 "error accessing list front", __LINE__ );
481
482 FFTData& bdata = ff.back();
483 tester.assert( (bdata.value == sampleData.back().value),
484 "error accessing list back", __LINE__ );
485 }
486 catch (...)
487 {
488 tester.assert( false, "error accessing list front/back", __LINE__ );
489 }
490
491 return tester.countFails();
492 }
493
494
495 //---------------------------------------------------------------------------
testFilter()496 int FileFilter_T :: testFilter()
497 {
498 TestUtil tester( "FileFilter", "filter/getFiltered", __FILE__, __LINE__ );
499
500 try // empty data list
501 {
502 FileFilter<FFTData> ff;
503
504 tester.assert( (0 == ff.getFiltered() ),
505 "no filtering has occurred", __LINE__ );
506
507 tester.assert( (0 == ff.filter(IsEven()).getFiltered() ),
508 "empty list expected after filtering", __LINE__ );
509 }
510 catch (...)
511 {
512 tester.assert( false, "exception filtering empty list", __LINE__ );
513 }
514
515 try // single-item data list filtered to empty
516 {
517 FileFilter<FFTData> ff;
518 FFTDataList list;
519 list.push_back( FFTData(2) );
520 ff.addData(list);
521
522 tester.assert( (0 == ff.getFiltered() ),
523 "no filtering has occurred", __LINE__ );
524
525 tester.assert( (1 == ff.filter(IsEven() ).getFiltered() ),
526 "expected filtering", __LINE__ );
527
528 tester.assert( (0 == ff.getDataCount() ),
529 "empty list expected following filtering", __LINE__ );
530 }
531 catch (...)
532 {
533 tester.assert( false, "exception filtering non-empty list", __LINE__ );
534 }
535
536 try // single-item data list filtered to no effect
537 {
538 FileFilter<FFTData> ff;
539 FFTDataList list;
540 list.push_back( FFTData(3) );
541 ff.addData(list);
542
543 tester.assert( (0 == ff.getFiltered() ),
544 "no filtering has occurred", __LINE__ );
545
546 tester.assert( (0 == ff.filter(IsEven()).getFiltered() ),
547 "expected no filtering", __LINE__ );
548
549 tester.assert( (1 == ff.getDataCount() ),
550 "non-empty list expected following filtering", __LINE__ );
551 }
552 catch (...)
553 {
554 tester.assert( false, "exception filtering non-empty list", __LINE__ );
555 }
556
557 try // multiple-item data list filtering
558 {
559 FileFilter<FFTData> ff;
560 ff.addData( sampleData ); // assumes 100 elements
561
562 tester.assert( (0 == ff.getFiltered() ),
563 "no filtering has occurred", __LINE__ );
564
565 tester.assert( (50 == ff.filter(IsEven()).getFiltered() ),
566 "expected filtering", __LINE__ );
567
568 tester.assert( (50 == ff.getDataCount() ),
569 "non-empty list expected following filtering", __LINE__ );
570 }
571 catch (...)
572 {
573 tester.assert( false, "error accessing list front/back", __LINE__ );
574 }
575
576 return tester.countFails();
577 }
578
579
580 //---------------------------------------------------------------------------
testSort()581 int FileFilter_T :: testSort()
582 {
583 TestUtil tester( "FileFilter", "sort", __FILE__, __LINE__ );
584
585 try // empty data list
586 {
587 FileFilter<FFTData> ff;
588
589 tester.assert( (0 == ff.sort(LessThan() ).getDataCount() ),
590 "empty list expected after sorting", __LINE__ );
591 }
592 catch (...)
593 {
594 tester.assert( false, "exception sorting empty list", __LINE__ );
595 }
596
597 try // single-item data list
598 {
599 FileFilter<FFTData> ff;
600 FFTDataList list;
601 list.push_back( FFTData(2) );
602 ff.addData(list);
603
604 tester.assert( (1 == ff.sort(LessThan() ).getDataCount() ),
605 "one item expected after sorting", __LINE__ );
606
607 tester.assert( (2 == ff.front().value), "unexpected value", __LINE__ );
608 }
609 catch (...)
610 {
611 tester.assert( false, "exception sorting non-empty list", __LINE__ );
612 }
613
614 try // two-item, out-of-order data list
615 {
616 FileFilter<FFTData> ff;
617 FFTDataList list;
618 list.push_back( FFTData(2) );
619 list.push_back( FFTData(1) );
620 ff.addData(list);
621
622 tester.assert( (2 == ff.sort(LessThan() ).getDataCount() ),
623 "two items expected after sorting", __LINE__ );
624
625 tester.assert( (1 == ff.front().value), "unexpected value", __LINE__ );
626 tester.assert( (2 == ff.back().value), "unexpected value", __LINE__ );
627 }
628 catch (...)
629 {
630 tester.assert( false, "exception sorting non-empty list", __LINE__ );
631 }
632
633 try // multiple-item, pre-sorted data list
634 {
635 FileFilter<FFTData> ff;
636 ff.addData( sampleData ); // assumes 100 elements
637
638 tester.assert( (100 == ff.sort(LessThan() ).getDataCount() ),
639 "100 items expected after sorting", __LINE__ );
640
641 bool sorted = true;
642 int previous = 0;
643 FFTDataList::const_iterator ffIter = ff.begin();
644 for ( ; ffIter != ff.end(); ++ffIter)
645 {
646 if ( (ffIter != ff.begin()) && (ffIter->value < previous) )
647 {
648 sorted = false;
649 break;
650 }
651 previous = ffIter->value;
652 }
653 tester.assert( sorted, "data list was not sorted", __LINE__ );
654
655 }
656 catch (...)
657 {
658 tester.assert( false, "error accessing list front/back", __LINE__ );
659 }
660
661 try // multiple-item, un-sorted data list
662 {
663 FileFilter<FFTData> ff;
664 FFTDataList reversedData( sampleData );
665 reverse(reversedData.begin(), reversedData.end() );
666 ff.addData( reversedData ); // assumes 100 elements
667
668 tester.assert( (100 == ff.sort(LessThan() ).getDataCount() ),
669 "100 items expected after sorting", __LINE__ );
670
671 bool sorted = true;
672 int previous = 0;
673 FFTDataList::const_iterator ffIter = ff.begin();
674 for ( ; ffIter != ff.end(); ++ffIter)
675 {
676 if ( (ffIter != ff.begin()) && (ffIter->value < previous) )
677 {
678 sorted = false;
679 break;
680 }
681 previous = ffIter->value;
682 }
683 tester.assert( sorted, "data list was not sorted", __LINE__ );
684
685 }
686 catch (...)
687 {
688 tester.assert( false, "error accessing list front/back", __LINE__ );
689 }
690
691 return tester.countFails();
692 }
693
694
695 //---------------------------------------------------------------------------
testMerge()696 int FileFilter_T :: testMerge()
697 {
698 TestUtil tester( "FileFilter", "merge", __FILE__, __LINE__ );
699
700 try // empty data lists
701 {
702 FileFilter<FFTData> ff;
703 FileFilter<FFTData> ffOther;
704
705 tester.assert( (0 == ff.merge(ffOther).getDataCount() ),
706 "empty list expected", __LINE__ );
707 }
708 catch (...)
709 {
710 tester.assert( false, "exception merging empty lists", __LINE__ );
711 }
712
713 try // empty data lists (sorted)
714 {
715 FileFilter<FFTData> ff;
716 FileFilter<FFTData> ffOther;
717
718 tester.assert( (0 == ff.merge(ffOther, LessThan() ).getDataCount() ),
719 "empty list expected", __LINE__ );
720 }
721 catch (...)
722 {
723 tester.assert( false, "exception merging empty lists", __LINE__ );
724 }
725
726 try // one empty data list (first)
727 {
728 FileFilter<FFTData> ff;
729 FileFilter<FFTData> ffOther;
730 FFTDataList list;
731 list.push_back( FFTData(1) );
732 ffOther.addData(list);
733
734 tester.assert( (1 == ff.merge(ffOther).getDataCount() ),
735 "unexpected element count", __LINE__ );
736
737 tester.assert( ( (1 == ff.getDataCount() ) && (1 == ff.front().value) ),
738 "unexpected value", __LINE__ );
739
740 if ( 1 != ff.getDataCount() )
741 {
742 dump(ff.getData() );
743 }
744 }
745 catch (...)
746 {
747 tester.assert( false, "exception merging lists", __LINE__ );
748 }
749
750 try // one empty data list (second)
751 {
752 FileFilter<FFTData> ff;
753 FileFilter<FFTData> ffOther;
754 FFTDataList list;
755 list.push_back( FFTData(1) );
756 ff.addData(list);
757
758 tester.assert( (1 == ff.merge(ffOther).getDataCount() ),
759 "unexpected element count", __LINE__ );
760
761 tester.assert( ( (1 == ff.getDataCount() ) && (1 == ff.front().value) ),
762 "unexpected value", __LINE__ );
763
764 if ( 1 != ff.getDataCount() )
765 {
766 dump(ff.getData() );
767 }
768 }
769 catch (...)
770 {
771 tester.assert( false, "exception merging lists", __LINE__ );
772 }
773
774 try // two non-empty data lists
775 {
776 FileFilter<FFTData> ff;
777 FileFilter<FFTData> ffOther;
778 FFTDataList list;
779 list.push_back( FFTData(2) );
780 ff.addData(list);
781 list.clear();
782 list.push_back( FFTData(1) );
783 ffOther.addData(list);
784
785 tester.assert( (2 == ff.merge(ffOther).getDataCount() ),
786 "unexpected element count", __LINE__ );
787
788 if ( 2 != ff.getDataCount() )
789 {
790 dump(ff.getData() );
791 }
792 }
793 catch (...)
794 {
795 tester.assert( false, "exception merging lists", __LINE__ );
796 }
797
798 try // two non-empty data lists (sorted)
799 {
800 FileFilter<FFTData> ff;
801 FileFilter<FFTData> ffOther;
802 FFTDataList list;
803 list.push_back( FFTData(3) );
804 list.push_back( FFTData(1) );
805 ff.addData(list);
806 list.clear();
807 list.push_back( FFTData(4) );
808 list.push_back( FFTData(2) );
809 ffOther.addData(list);
810
811 tester.assert( (4 == ff.merge(ffOther, LessThan() ).getDataCount() ),
812 "unexpected element count", __LINE__ );
813
814 if ( 4 == ff.getDataCount() )
815 {
816 tester.assert( (1 == ff.front().value),
817 "unexpected value", __LINE__ );
818
819 tester.assert( (4 == ff.back().value),
820 "unexpected value", __LINE__ );
821 }
822 else
823 {
824 dump(ff.getData() );
825 }
826 }
827 catch (...)
828 {
829 tester.assert( false, "exception merging lists", __LINE__ );
830 }
831
832 return tester.countFails();
833 }
834
835
836 //---------------------------------------------------------------------------
testTouch()837 int FileFilter_T :: testTouch()
838 {
839 TestUtil tester( "FileFilter", "touch", __FILE__, __LINE__ );
840
841 try // empty data list
842 {
843 FileFilter<FFTData> ff;
844
845 tester.assert( (0 == ff.getFiltered() ),
846 "no operation has occurred", __LINE__ );
847
848 tester.assert( (0 == ff.touch(DoubleFives() ).getFiltered() ),
849 "no operations expected", __LINE__ );
850 }
851 catch (...)
852 {
853 tester.assert( false, "exception operating on an empty list", __LINE__ );
854 }
855
856 try // single-item data list filtered to empty
857 {
858 FileFilter<FFTData> ff;
859 FFTDataList list;
860 list.push_back( FFTData(5) );
861 ff.addData(list);
862
863 tester.assert( (0 == ff.getFiltered() ),
864 "no operation has occurred", __LINE__ );
865
866 tester.assert( (1 == ff.touch(DoubleFives() ).getFiltered() ),
867 "expected a single operation", __LINE__ );
868
869 tester.assert( (1 == ff.getDataCount() ),
870 "unexpected change to data count", __LINE__ );
871
872 FFTData& fdata = ff.front();
873 tester.assert( (10 == fdata.value),
874 "operation was not applied", __LINE__ );
875 }
876 catch (...)
877 {
878 tester.assert( false, "exception operating on a non-empty list", __LINE__ );
879 }
880
881 try // single-item data list filtered to no effect
882 {
883 FileFilter<FFTData> ff;
884 FFTDataList list;
885 list.push_back( FFTData(3) );
886 ff.addData(list);
887
888 tester.assert( (0 == ff.getFiltered() ),
889 "no operation has occurred", __LINE__ );
890
891 tester.assert( (0 == ff.touch(DoubleFives() ).getFiltered() ),
892 "no operations expected", __LINE__ );
893
894 tester.assert( (1 == ff.getDataCount() ),
895 "unexpected change to data count", __LINE__ );
896
897 FFTData& fdata = ff.front();
898 tester.assert( (3 == fdata.value),
899 "operation was erroneously applied", __LINE__ );
900 }
901 catch (...)
902 {
903 tester.assert( false, "exception operating on a non-empty list", __LINE__ );
904 }
905
906 try // multiple-item data list filtering
907 {
908 FileFilter<FFTData> ff;
909 ff.addData( sampleData ); // assumes 100 elements
910
911 tester.assert( (0 == ff.getFiltered() ),
912 "no operation has occurred", __LINE__ );
913
914 tester.assert( (20 == ff.touch(DoubleFives() ).getFiltered() ),
915 "expected 50 operations", __LINE__ );
916
917 tester.assert( (100 == ff.getDataCount() ),
918 "unexpected change to data count", __LINE__ );
919
920 // check that the operation was applied to all appropriate elememts,
921 // i.e. make sure every 5th element is divisible by 10
922 bool applied = true;
923 int i = 0;
924 FFTDataList::const_iterator ffIter = ff.begin();
925 for ( ; ffIter != ff.end(); ++i, ++ffIter)
926 {
927 if ( (0 == (i % 5) ) && (0 != (ffIter->value % 10) ) )
928 {
929 applied = false;
930 break;
931 }
932 }
933 tester.assert( applied, "operation was not applied to all approriate elments", __LINE__ );
934 }
935 catch (...)
936 {
937 tester.assert( false, "exception operating on a non-empty list", __LINE__ );
938 }
939
940 return tester.countFails();
941 }
942
943
944 //---------------------------------------------------------------------------
testUnique()945 int FileFilter_T :: testUnique()
946 {
947 TestUtil tester( "FileFilter", "unique", __FILE__, __LINE__ );
948
949 // @note - unique() requires a sorted list as input
950
951 try // empty data list
952 {
953 FileFilter<FFTData> ff;
954
955 tester.assert( (0 == ff.unique(Equal() ).getDataCount() ),
956 "empty list expected", __LINE__ );
957 }
958 catch (...)
959 {
960 tester.assert( false, "exception for empty list", __LINE__ );
961 }
962
963 try // single-item data list
964 {
965 FileFilter<FFTData> ff;
966 FFTDataList list;
967 list.push_back( FFTData(2) );
968 ff.addData(list);
969
970 tester.assert( (1 == ff.unique(Equal() ).getDataCount() ),
971 "one item expected", __LINE__ );
972
973 tester.assert( (2 == ff.front().value), "unexpected value", __LINE__ );
974 }
975 catch (...)
976 {
977 tester.assert( false, "exception for non-empty list", __LINE__ );
978 }
979
980 try // two-item data list
981 {
982 FileFilter<FFTData> ff;
983 FFTDataList list;
984 list.push_back( FFTData(2) );
985 list.push_back( FFTData(2) );
986 ff.addData(list);
987
988 tester.assert( (1 == ff.unique(Equal() ).getDataCount() ),
989 "one item expected", __LINE__ );
990
991 tester.assert( (2 == ff.front().value), "unexpected value", __LINE__ );
992 }
993 catch (...)
994 {
995 tester.assert( false, "exception for non-empty list", __LINE__ );
996 }
997
998 try // multiple-item data list
999 {
1000 FileFilter<FFTData> ff;
1001 FFTDataList list;
1002 list.push_back( FFTData(1) );
1003 list.push_back( FFTData(2) );
1004 list.push_back( FFTData(2) );
1005 list.push_back( FFTData(2) );
1006 list.push_back( FFTData(3) );
1007 ff.addData(list);
1008
1009 tester.assert( (3 == ff.unique(Equal() ).getDataCount() ),
1010 "three items expected", __LINE__ );
1011
1012 tester.assert( (1 == ff.front().value), "unexpected value", __LINE__ );
1013 tester.assert( (3 == ff.back().value), "unexpected value", __LINE__ );
1014 }
1015 catch (...)
1016 {
1017 tester.assert( false, "exception for non-empty list", __LINE__ );
1018 }
1019
1020 return tester.countFails();
1021 }
1022
1023
1024 //---------------------------------------------------------------------------
testDiff()1025 int FileFilter_T :: testDiff()
1026 {
1027 TestUtil tester( "FileFilter", "diff", __FILE__, __LINE__ );
1028
1029 try // empty data lists
1030 {
1031 FileFilter<FFTData> ff;
1032 FileFilter<FFTData> ffOther;
1033
1034 std::pair< FFTDataList, FFTDataList > results = ff.diff(ffOther, LessThan() );
1035
1036 tester.assert( ( (0 == results.first.size() ) && (0 == results.second.size() ) ),
1037 "empty lists expected", __LINE__ );
1038 }
1039 catch (...)
1040 {
1041 tester.assert( false, "exception diffing empty lists", __LINE__ );
1042 }
1043
1044 try // one empty data list (first)
1045 {
1046 FileFilter<FFTData> ff;
1047 FileFilter<FFTData> ffOther;
1048 FFTDataList list;
1049 list.push_back( FFTData(1) );
1050 ffOther.addData(list);
1051
1052 std::pair< FFTDataList, FFTDataList > results = ff.diff(ffOther, LessThan() );
1053
1054 tester.assert( ( (0 == results.first.size() ) && (1 == results.second.size() ) ),
1055 "unexpected element count(s)", __LINE__ );
1056
1057 tester.assert( ( (1 == results.second.size() ) && (1 == results.second.front().value) ),
1058 "unexpected value", __LINE__ );
1059 }
1060 catch (...)
1061 {
1062 tester.assert( false, "exception diffing lists", __LINE__ );
1063 }
1064
1065 try // one empty data list (second)
1066 {
1067 FileFilter<FFTData> ff;
1068 FileFilter<FFTData> ffOther;
1069 FFTDataList list;
1070 list.push_back( FFTData(1) );
1071 ff.addData(list);
1072
1073 std::pair< FFTDataList, FFTDataList > results = ff.diff(ffOther, LessThan() );
1074
1075 tester.assert( ( (1 == results.first.size() ) && (0 == results.second.size() ) ),
1076 "unexpected element count(s)", __LINE__ );
1077
1078 tester.assert( ( (1 == results.first.size() ) && (1 == results.first.front().value) ),
1079 "unexpected value", __LINE__ );
1080 }
1081 catch (...)
1082 {
1083 tester.assert( false, "exception diffing lists", __LINE__ );
1084 }
1085
1086 try // two identical non-empty data lists
1087 {
1088 FileFilter<FFTData> ff;
1089 FileFilter<FFTData> ffOther;
1090 FFTDataList list;
1091 list.push_back( FFTData(1) );
1092 ff.addData(list);
1093 ffOther.addData(list);
1094
1095 std::pair< FFTDataList, FFTDataList > results = ff.diff(ffOther, LessThan() );
1096
1097 tester.assert( ( (0 == results.first.size() ) && (0 == results.second.size() ) ),
1098 "empty lists expected", __LINE__ );
1099
1100 if ( (0 != results.first.size() ) || (0 != results.second.size() ) )
1101 {
1102 dump(results.first);
1103 dump(results.second);
1104 }
1105 }
1106 catch (...)
1107 {
1108 tester.assert( false, "exception diffing lists", __LINE__ );
1109 }
1110
1111 try // two non-identical non-empty data lists
1112 {
1113 FileFilter<FFTData> ff;
1114 FileFilter<FFTData> ffOther;
1115 FFTDataList list;
1116 list.push_back( FFTData(1) );
1117 ff.addData(list);
1118 list.clear();
1119 list.push_back( FFTData(2) );
1120 ffOther.addData(list);
1121
1122 std::pair< FFTDataList, FFTDataList > results = ff.diff(ffOther, LessThan() );
1123
1124 tester.assert( ( (1 == results.first.size() ) && (1 == results.second.size() ) ),
1125 "expected element count(s)", __LINE__ );
1126
1127 tester.assert( ( (1 == results.first.size() ) && (1 == results.first.front().value) ),
1128 "unexpected value", __LINE__ );
1129
1130 tester.assert( ( (1 == results.second.size() ) && (2 == results.second.front().value) ),
1131 "unexpected value", __LINE__ );
1132
1133 if ( (1 != results.first.size() ) || (1 != results.second.size() ) )
1134 {
1135 dump(results.first);
1136 dump(results.second);
1137 }
1138 }
1139 catch (...)
1140 {
1141 tester.assert( false, "exception diffing lists", __LINE__ );
1142 }
1143
1144 return tester.countFails();
1145 }
1146
1147
1148 //---------------------------------------------------------------------------
testFindAll()1149 int FileFilter_T :: testFindAll()
1150 {
1151 TestUtil tester( "FileFilter", "findAll", __FILE__, __LINE__ );
1152
1153 try // empty data list
1154 {
1155 FileFilter<FFTData> ff;
1156
1157 FFTDataList fftdList = ff.findAll(IsEven() );
1158 tester.assert( (0 == fftdList.size() ),
1159 "empty list expected", __LINE__ );
1160 }
1161 catch (...)
1162 {
1163 tester.assert( false, "exception searching empty list", __LINE__ );
1164 }
1165
1166 try // non-empty list, no matches
1167 {
1168 FileFilter<FFTData> ff;
1169 ff.addData( sampleData );
1170
1171 FFTDataList fftdList = ff.findAll(Above999() );
1172 tester.assert( (0 == fftdList.size() ),
1173 "empty list expected", __LINE__ );
1174
1175 }
1176 catch (...)
1177 {
1178 tester.assert( false, "exception searching non-empty list", __LINE__ );
1179 }
1180
1181 try // non-empty list, several matches
1182 {
1183 FileFilter<FFTData> ff;
1184 ff.addData( sampleData );
1185
1186 FFTDataList fftdList = ff.findAll(IsEven() );
1187 tester.assert( (50 == fftdList.size() ),
1188 "50 element list expected", __LINE__ );
1189 }
1190 catch (...)
1191 {
1192 tester.assert( false, "exception searching non-empty list", __LINE__ );
1193 }
1194
1195 return tester.countFails();
1196 }
1197
1198
1199 //---------------------------------------------------------------------------
dump(const FFTDataList & data)1200 void FileFilter_T :: dump(const FFTDataList& data)
1201 {
1202 cout << " DATA DUMP:" << endl;
1203 FFTDataList::const_iterator iter = data.begin();
1204 for ( ; iter != data.end(); ++iter)
1205 cout << " " << iter->value << endl;
1206 }
1207
1208
1209 /** Initialize and run all tests.
1210 *
1211 * @return Total error count for all tests
1212 */
main(int argc,char * argv[])1213 int main(int argc, char *argv[])
1214 {
1215 int errorTotal = 0;
1216
1217 FileFilter_T testClass;
1218
1219 errorTotal += testClass.testInitialization();
1220 errorTotal += testClass.testData();
1221 errorTotal += testClass.testBeginEnd();
1222 errorTotal += testClass.testFrontBack();
1223 errorTotal += testClass.testFilter();
1224 errorTotal += testClass.testSort();
1225 errorTotal += testClass.testMerge();
1226 errorTotal += testClass.testTouch();
1227 errorTotal += testClass.testUnique();
1228 errorTotal += testClass.testDiff();
1229 errorTotal += testClass.testFindAll();
1230
1231 cout << "Total Failures for " << __FILE__ << ": " << errorTotal << endl;
1232
1233 return errorTotal;
1234 }
1235