Lumiera  0.pre.03
»edit your freedom«
iter-source-test.cpp
Go to the documentation of this file.
1 /*
2  IterSource(Test) - how to build an opaque iterator-based data source
3 
4  Copyright (C)
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
20 #include "lib/test/run.hpp"
21 #include "lib/test/test-helper.hpp"
22 #include "lib/format-cout.hpp"
23 #include "lib/nocopy.hpp"
24 #include "lib/util.hpp"
25 
26 #include "lib/iter-source.hpp"
27 
28 #include <boost/lexical_cast.hpp>
29 #include <unordered_map>
30 #include <string>
31 #include <list>
32 #include <map>
33 
34 
35 
36 namespace lib {
37 namespace test{
38 
39  using ::Test;
40  using util::isnil;
41  using boost::lexical_cast;
42  using lib::time::TimeVar;
43  using lib::test::randStr;
44  using lib::test::randTime;
45  using std::make_pair;
46  using std::string;
47  using std::list;
48 
49  using LERR_(ITER_EXHAUST);
50 
51  using iter_source::eachEntry;
52  using iter_source::transform;
53  using iter_source::singleVal;
54  using iter_source::eachMapKey;
55  using iter_source::eachMapVal;
56  using iter_source::eachValForKey;
57  using iter_source::eachDistinctKey;
58 
59 
60 
61  namespace { // Subject of test
62 
67  class TestSource
68  : public IterSource<CStr>
70  {
71 
72  string buffer_;
73  CStr current_;
74 
75  virtual Pos
76  firstResult () override
77  {
78  current_ = buffer_.c_str();
79  ENSURE (current_);
80  return &current_;
81  }
82 
83  virtual void
84  nextResult (Pos& pos) override
85  {
86  if (pos && *pos && **pos)
87  ++(*pos);
88 
89  if (!(pos && *pos && **pos))
90  pos = 0;
91  }
92 
93 
94 
95  public:
96  TestSource (uint num)
97  : buffer_(randStr (num))
98  , current_(0)
99  {
100  INFO (test, "created TestSource(\"%s\")", cStr(buffer_));
101  }
102  };
103 
104 
105 
109  struct WrappedList
110  {
111  list<int> data_;
112 
113  WrappedList(uint num)
114  {
115  while (num)
116  data_.push_back(num--);
117  }
118 
119  typedef list<int>::iterator sourceIter;
121 
122  iterator begin() { return iterator(data_.begin(),data_.end()); }
123  iterator end() { return iterator(); }
124 
125  };
126 
127 
129  template<class IT>
130  inline void
131  pullOut (IT& iter)
132  {
133  for ( ; iter; ++iter )
134  cout << "::" << *iter;
135  cout << endl;
136  }
137  } // (END) impl test dummy containers
138 
139 
140 
141 
142 
143 
144 
145  /**************************************************************/
155  class IterSource_test : public Test
156  {
157 
159  typedef IterSource<CStr>::iterator StrIter;
162 
163  typedef std::map<string,TimeVar> TreeMap;
164  typedef std::unordered_map<string,TimeVar> HashMap;
165 
166  typedef std::multimap<int,int> TreeMultimap;
167  typedef std::unordered_multimap<int,int>HashMultimap;
168 
169 
170  uint NUM_ELMS{0};
171 
172  virtual void
173  run (Arg arg)
174  {
175  seedRand();
176  NUM_ELMS = firstVal (arg, 10);
177 
178  verify_simpleIters();
179  verify_transformIter();
180 
181  verify_MapWrappers<TreeMap>();
182  verify_MapWrappers<HashMap>();
183 
184  verify_MultimapIters<TreeMultimap>();
185  verify_MultimapIters<HashMultimap>();
186  }
187 
188 
189  void
190  verify_simpleIters()
191  {
192  // build the test data sources
193  WrappedList customList(NUM_ELMS);
194  TestSource dedicatedSource(NUM_ELMS);
195  list<int>& rawList(customList.data_);
196 
197  IntIter iii (eachEntry (customList));
198  IntIter isi (eachEntry (rawList.begin(), rawList.end()));
199  StrIter cii (IterSource<CStr>::build(dedicatedSource));
200 
201  CHECK (!isnil (iii));
202  CHECK (!isnil (isi));
203  CHECK (!isnil (cii));
204 
205  pullOut (iii);
206  pullOut (isi);
207  pullOut (cii);
208 
209  CHECK (!iii);
210  CHECK (!isi);
211  CHECK (!cii);
212  }
213 
214 
223  void
225  {
226  WrappedList customList(NUM_ELMS);
227  WrappedList::iterator sourceValues = customList.begin();
228 
229  // transformation function
230  auto makeTime = [](int input_sec) -> TimeVar
231  {
232  return time::Time (time::FSecs (input_sec, 4));
233  };
234 
235  TimeIter tIt (transform (sourceValues, makeTime));
236  CHECK (!isnil (tIt));
237  pullOut (tIt);
238  CHECK (!tIt);
239  }
240 
241 
243  void
245  {
246  int i{-9};
247 
248  IntIter ii = singleVal(12);
249  CHECK (not isnil(ii));
250  CHECK (12 == *ii);
251 
252  ++ii;
253  CHECK (isnil (ii));
254  VERIFY_ERROR (ITER_EXHAUST, *ii );
255 
256  // IterSource is an abstracting interface,
257  // thus we're able to reassign an embedded iterator
258  // with a different value type (int& instead of int)
259  ii = singleVal(i);
260 
261  CHECK (not isnil(ii));
262  CHECK (-9 == *ii);
263 
264  // NOTE: since we passed a reference, a reference got wrapped
265  i = 23;
266  CHECK (23 == *ii);
267  ++ii;
268  CHECK (isnil (ii));
269  }
270 
271 
272 
273 
274  template<class MAP>
275  void
276  verify_MapWrappers()
277  {
278  MAP testMap;
279  for (uint i=0; i<NUM_ELMS; ++i)
280  testMap['X'+randStr(11)] = randTime();
281 
282  StringIter sIter = eachMapKey (testMap);
283  TimeIter tIter = eachMapVal (testMap);
284 
285  CHECK (sIter && tIter);
286  pullOut (sIter);
287  pullOut (tIter);
288 
289  CHECK (!sIter && !tIter);
290 
291 
292  // The each-value-for-given-key-Iterator can be used for a map or multimap.
293  // In case of a map, it should yield exactly one result for existing values
294  // and zero results for non-existing mappings
295  StringIter justSomeKey = eachMapKey (testMap);
296  TimeIter correspondingVal = eachMapVal (testMap);
297  ++justSomeKey;
298  ++correspondingVal;
299  CHECK (justSomeKey);
300 
301  TimeIter value4key = eachValForKey (testMap, "nonexistent key");
302  CHECK (!value4key);
303 
304  value4key = eachValForKey (testMap, *justSomeKey);
305  CHECK (value4key);
306  CHECK (*value4key == *correspondingVal);
307  ++value4key;
308  CHECK (!value4key);
309  }
310 
311 
312  template<class MAP>
313  void
314  verify_MultimapIters()
315  {
316  MAP testMap;
317  for (uint i=0; i<NUM_ELMS; ++i)
318  {
319  uint n = 1 + rani(100);
320  do testMap.insert (make_pair (i,n));
321  while (--n);
322  }
323  CHECK (NUM_ELMS < testMap.size(), "no repetition in test data??");
324 
325  IntIter keys = eachDistinctKey (testMap);
326 
327  cout << "distinct_keys";
328  CHECK (keys);
329  pullOut (keys);
330  CHECK (!keys);
331 
332  cout << "values_4_key";
333  IntIter vals = eachValForKey (testMap, NUM_ELMS); // non-existent key
334  CHECK (!vals);
335 
336  vals = eachValForKey (testMap, 0);
337  CHECK (vals);
338  pullOut (vals); // should produce anything between 1 and 100 entries
339  CHECK (!vals);
340  }
341  };
342 
343 
344  LAUNCHER (IterSource_test, "unit common");
345 
346 
347 }} // namespace lib::test
348 
a mutable time value, behaving like a plain number, allowing copy and re-accessing ...
Definition: timevalue.hpp:232
virtual void nextResult(Pos &pos) override
iteration step: switch on to the next element.
Automatically use custom string conversion in C++ stream output.
CStr cStr(std::string const &rendered)
convenience shortcut: forced conversion to c-String via string.
Definition: symbol.hpp:59
Definition: run.hpp:40
Any copy and copy construction prohibited.
Definition: nocopy.hpp:37
int rani(uint bound=_iBOUND())
Definition: random.hpp:135
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
Implementation namespace for support and library code.
string randStr(size_t len)
create garbage string of given length
Definition: test-helper.cpp:61
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:299
Explicit implementation of the IterSource interface (test dummy) Creates a random string and chops of...
virtual Pos firstResult() override
iteration start: prepare the first element.
Iteration source interface to abstract a data source, which then can be accessed through IterAdapter ...
Definition: iter-source.hpp:79
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Simplistic test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
boost::rational< int64_t > FSecs
rational representation of fractional seconds
Definition: timevalue.hpp:220
A collection of frequently used helper functions to support unit testing.
lib::time::Time randTime()
create a random but not insane Time value between 1s ...
Accessing a STL element range through a Lumiera forward iterator, An instance of this iterator adapte...
test dummy: simply wrapping an STL container and exposing a range as Lumiera Forward Iterator ...
Extension module to build an opaque data source, accessible as Lumiera Forward Iterator.