Lumiera  0.pre.03
»edit your freedom«
item-wrapper-test.cpp
Go to the documentation of this file.
1 /*
2  ItemWrapper(Test) - wrapping and holding arbitrary values, pointers and references
3 
4  Copyright (C) Lumiera.org
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
29 #include "lib/test/run.hpp"
30 #include "lib/test/test-helper.hpp"
31 #include "lib/util.hpp"
32 
33 #include "lib/wrapper.hpp"
34 
35 #include <functional>
36 #include <iostream>
37 #include <cstdlib>
38 #include <memory>
39 #include <string>
40 #include <vector>
41 
42 
43 
44 namespace lib {
45 namespace wrapper {
46 namespace test{
47 
48  using ::Test;
49  using lib::test::randStr;
50  using lib::test::showSizeof;
51  using util::isSameObject;
52 
53  using std::placeholders::_1;
54  using std::ref;
55  using std::shared_ptr;
56  using std::vector;
57  using std::string;
58  using std::rand;
59  using std::cout;
60  using std::endl;
61 
62 
63 
64  namespace { // Test helper: yet another ctor/dtor counting class
65 
66  long cntTracker = 0;
67 
68  struct Tracker
69  {
70  uint i_;
71 
72  Tracker() : i_(rand() % 500) { ++cntTracker; }
73  Tracker(Tracker const& ot) : i_(ot.i_) { ++cntTracker; }
74  ~Tracker() { --cntTracker; }
75  };
76 
77  bool operator== (Tracker const& t1, Tracker const& t2) { return t1.i_ == t2.i_; }
78  bool operator!= (Tracker const& t1, Tracker const& t2) { return t1.i_ != t2.i_; }
79 
80 
82  int&
83  pickElement (vector<int>& vec, size_t idx)
84  {
85  return vec[idx];
86  }
87 
88  function<int&(size_t)>
89  pickElement_ofVector (vector<int>& vec)
90  {
91  return std::bind (pickElement, ref(vec), _1 );
92  }
93  } // (END) Test helpers
94 
95 
96 
97 
98 
99 
100 
101  /***************************************************************************/
108  class ItemWrapper_test : public Test
109  {
110 
111 
112  virtual void
113  run (Arg)
114  {
115  ulong l1 (rand() % 1000);
116  ulong l2 (rand() % 1000);
117  string s1 (randStr(50));
118  string s2 (randStr(50));
119  const char* cp (s1.c_str());
120 
121  verifyWrapper<ulong> (l1, l2);
122  verifyWrapper<ulong&> (l1, l2);
123  verifyWrapper<ulong*> (&l1, &l2);
124  verifyWrapper<ulong*> ((0), &l2);
125  verifyWrapper<ulong*> (&l1, (0));
126  verifyWrapper<ulong const&> (l1, l2);
127 
128  verifyWrapper<string> (s1, s2);
129  verifyWrapper<string&> (s1, s2);
130  verifyWrapper<string*> (&s1, &s2);
131 
132  verifyWrapper<const char*> (cp, "Lumiera");
133 
134 
135  verifySaneInstanceHandling();
136  verifySaneMoveHandling();
137  verifyWrappedRef ();
138 
139  verifyFunctionResult ();
140  verifyFunctionRefResult ();
141  }
142 
143 
144  template<typename X>
145  void
146  verifyWrapper (X val, X otherVal)
147  {
148  const ItemWrapper<X> wrap(val);
149  CHECK (wrap);
150 
151  cout << "ItemWrapper: " << showSizeof(wrap) << endl;
152 
153  ItemWrapper<X> copy1 (wrap);
154  ItemWrapper<X> copy2;
155  ItemWrapper<X> empty;
156 
157  CHECK (copy1);
158  CHECK (!copy2);
159  CHECK (false == bool(empty));
160 
161  CHECK (wrap == copy1);
162  CHECK (wrap != copy2);
163  CHECK (wrap != empty);
164 
165  copy2 = copy1;
166  CHECK (copy2);
167  CHECK (wrap == copy2);
168  CHECK (wrap != empty);
169 
170  copy2 = otherVal;
171  CHECK (copy2);
172  CHECK (wrap != copy2);
173  CHECK (wrap != empty);
174 
175  CHECK (val == *wrap);
176  CHECK (val == *copy1);
177  CHECK (val != *copy2);
178  VERIFY_ERROR (BOTTOM_VALUE, *empty );
179 
180  CHECK (otherVal == *copy2);
181  copy1 = copy2;
182  CHECK (otherVal == *copy1);
183  CHECK (otherVal == *copy2);
184  CHECK (wrap != copy1);
185  CHECK (wrap != copy2);
186 
187  copy1 = empty; // assign empty to discard value
188  copy1 = copy1; // self-assign empty value
189  CHECK (!copy1);
190 
191  copy1 = copy2;
192  CHECK (otherVal == *copy1);
193  copy1 = copy1; // self-assign (will be suppressed)
194  CHECK (otherVal == *copy1);
195  copy1 = *copy1; // self-assign also detected in this case
196  CHECK (otherVal == *copy2);
197 
198  CHECK (copy1);
199  copy1.reset();
200  CHECK (!copy1);
201  CHECK (empty == copy1);
202  CHECK (copy2 != copy1);
203  VERIFY_ERROR (BOTTOM_VALUE, *copy1 );
204  };
205 
206 
210  void
212  {
213  cntTracker = 0;
214  {
215  Tracker t1;
216  Tracker t2;
217 
218  verifyWrapper<Tracker> (t1, t2);
219  verifyWrapper<Tracker&> (t1, t2);
220  verifyWrapper<Tracker*> (&t1, &t2);
221 
222  }
223  CHECK (0 == cntTracker);
224  }
225 
226 
228  void
230  {
231  using Data = shared_ptr<int>;
232  using Wrap = ItemWrapper<Data>;
233 
234  Data data{new int(12345)};
235  CHECK (1 == data.use_count());
236 
237  Wrap wrap{data};
238  CHECK (2 == data.use_count());
239  CHECK (12345 == **wrap);
240  CHECK (isSameObject (*data, **wrap));
241  CHECK (!isSameObject (data, *wrap));
242 
243  Wrap wcopy{wrap};
244  CHECK (3 == data.use_count());
245 
246  Wrap wmove{move (wcopy)};
247  CHECK (3 == data.use_count());
248  CHECK (not wcopy);
249  CHECK (wmove);
250 
251  wcopy = move(wmove);
252  CHECK (3 == data.use_count());
253  CHECK (not wmove);
254  CHECK (wcopy);
255 
256  Wrap wmove2{move (data)};
257  CHECK (0 == data.use_count());
258  CHECK (3 == wmove2->use_count());
259  CHECK (not data);
260  CHECK (wmove2);
261  CHECK (wrap);
262 
263  wmove2 = move (wcopy);
264  CHECK (2 == wmove2->use_count());
265  CHECK (not wcopy);
266  CHECK (wmove2);
267  CHECK (wrap);
268 
269  wmove2 = move (wrap);
270  CHECK (1 == wmove2->use_count());
271  CHECK (not wrap);
272  CHECK (wmove2);
273 
274  wmove2 = move (wmove);
275  CHECK (not wcopy);
276  CHECK (not wmove);
277  CHECK (not wmove2);
278  }
279 
280 
284  void
286  {
287  int x = 5;
288  ItemWrapper<int&> refWrap;
289  CHECK (!refWrap);
290 
291  refWrap = x;
292  CHECK (refWrap);
293  CHECK (5 == *refWrap);
294  CHECK (x == *refWrap);
295 
296  *refWrap += 5;
297  CHECK (x == 10);
298 
299  ItemWrapper<int*> ptrWrap (& *refWrap);
300  CHECK ( isSameObject (**ptrWrap, x));
301  CHECK (!isSameObject ( *ptrWrap, &x));
302  **ptrWrap += 13;
303  CHECK (x == 23);
304  }
305 
306 
312  void
314  {
315  FunctionResult<int(void)> randomVal (std::rand);
316 
317  // function was never invoked, thus the remembered result is NIL
318  CHECK (!randomVal);
319  VERIFY_ERROR (BOTTOM_VALUE, *randomVal );
320 
321  int v1 = randomVal();
322  CHECK (v1 == *randomVal);
323  CHECK (v1 == *randomVal);
324  CHECK (v1 == *randomVal);
325  CHECK (randomVal);
326 
327  int v2;
328  do v2 = randomVal();
329  while (v1 == v2);
330  CHECK (v2 == *randomVal);
331  CHECK (v2 == *randomVal);
332  CHECK (v1 != *randomVal);
333  }
334 
335 
344  void
346  {
347  vector<int> testVec;
348  for (uint i=0; i<10; ++i)
349  testVec.push_back(i);
350 
351  FunctionResult<int&(size_t)> funRes (pickElement_ofVector(testVec));
352 
353  // function was never invoked, thus the remembered result is NIL
354  CHECK (!funRes);
355  VERIFY_ERROR (BOTTOM_VALUE, *funRes );
356 
357  int& r5 = funRes (5);
358  CHECK (funRes); // indicates existence of cached result
359 
360  CHECK (5 == r5);
361  CHECK (isSameObject (r5, testVec[5]));
362 
363  int& r5x = *funRes;
364  CHECK (isSameObject (r5, r5x));
365 
366  CHECK ( isSameObject (r5, *funRes));
367  int& r7 = funRes (7);
368  CHECK (!isSameObject (r5, *funRes));
369  CHECK ( isSameObject (r7, *funRes));
370 
371  -- r5x;
372  ++ *funRes;
373  CHECK (5-1 == testVec[5]);
374  CHECK (7+1 == testVec[7]);
375  CHECK (7+1 == r7);
376  }
377  };
378 
379  LAUNCHER (ItemWrapper_test, "unit common");
380 
381 
382 }}} // namespace lib::wrapper::test
383 
Definition: run.hpp:49
bool operator==(PtrDerefIter< I1 > const &il, PtrDerefIter< I2 > const &ir)
Supporting equality comparisons...
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
Universal value/ref wrapper accessible similar to a pointer.
Definition: wrapper.hpp:111
Implementation namespace for support and library code.
string randStr(size_t len)
create garbage string of given length
Definition: test-helper.cpp:69
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Extension of ItemWrapper: a function remembering the result of the last invocation.
Definition: wrapper.hpp:410
int & pickElement(vector< int > &vec, size_t idx)
to be bound as test function....
A collection of frequently used helper functions to support unit testing.
Library implementation: smart-pointer variations, wrappers and managing holders.
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.
Definition: util.hpp:372