Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
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)
5 2009, 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"
22#include "lib/format-cout.hpp"
23#include "lib/random.hpp"
24#include "lib/util.hpp"
25
26#include "lib/item-wrapper.hpp"
28
29#include <functional>
30#include <iostream>
31#include <memory>
32#include <string>
33#include <vector>
34
35
36
37namespace lib {
38namespace wrapper {
39namespace test{
40
41 using ::Test;
42 using lib::test::randStr;
43 using lib::test::showSizeof;
45
46 using std::placeholders::_1;
47 using std::ref;
48 using std::shared_ptr;
49 using std::vector;
50 using std::string;
51
52
53
54 namespace { // Test helper: yet another ctor/dtor counting class
55
56 long cntTracker = 0;
57
58 struct Tracker
59 {
61
62 Tracker() : i_(rani(500)) { ++cntTracker; }
63 Tracker(Tracker const& ot) : i_(ot.i_) { ++cntTracker; }
65 };
66
67 bool operator== (Tracker const& t1, Tracker const& t2) { return t1.i_ == t2.i_; }
68 bool operator!= (Tracker const& t1, Tracker const& t2) { return t1.i_ != t2.i_; }
69
70
72 int&
73 pickElement (vector<int>& vec, size_t idx)
74 {
75 return vec[idx];
76 }
77
78 function<int&(size_t)>
79 pickElement_ofVector (vector<int>& vec)
80 {
81 return std::bind (pickElement, ref(vec), _1 );
82 }
83 } // (END) Test helpers
84
85
86
87
88
89
90
91 /***************************************************************************/
98 class ItemWrapper_test : public Test
99 {
100
101
102 virtual void
103 run (Arg)
104 {
105 seedRand();
106
107 ulong l1 (rani (1000));
108 ulong l2 (rani (1000));
109 string s1 (randStr(50));
110 string s2 (randStr(50));
111 CStr cp (s1.c_str());
112
113 verifyWrapper<ulong> (l1, l2);
114 verifyWrapper<ulong&> (l1, l2);
115 verifyWrapper<ulong*> (&l1, &l2);
116 verifyWrapper<ulong*> ((0), &l2);
117 verifyWrapper<ulong*> (&l1, (0));
118 verifyWrapper<ulong const&> (l1, l2);
119
120 verifyWrapper<string> (s1, s2);
121 verifyWrapper<string&> (s1, s2);
122 verifyWrapper<string*> (&s1, &s2);
123
124 verifyWrapper<CStr> (cp, "Lumiera");
125
126
130
133 }
134
135
136 template<typename X>
137 void
138 verifyWrapper (X val, X otherVal)
139 {
140 const ItemWrapper<X> wrap(val);
141 CHECK (wrap);
142
143 cout << "ItemWrapper: " << showSizeof(wrap) << endl;
144
145 ItemWrapper<X> copy1 (wrap);
146 ItemWrapper<X> copy2;
147 ItemWrapper<X> empty;
148
149 CHECK (copy1);
150 CHECK (!copy2);
151 CHECK (false == bool(empty));
152
153 CHECK (wrap == copy1);
154 CHECK (wrap != copy2);
155 CHECK (wrap != empty);
156
157 copy2 = copy1;
158 CHECK (copy2);
159 CHECK (wrap == copy2);
160 CHECK (wrap != empty);
161
162 copy2 = otherVal;
163 CHECK (copy2);
164 CHECK (wrap != copy2);
165 CHECK (wrap != empty);
166
167 CHECK (val == *wrap);
168 CHECK (val == *copy1);
169 CHECK (val != *copy2);
170 VERIFY_ERROR (BOTTOM_VALUE, *empty );
171
172 CHECK (otherVal == *copy2);
173 copy1 = copy2;
174 CHECK (otherVal == *copy1);
175 CHECK (otherVal == *copy2);
176 CHECK (wrap != copy1);
177 CHECK (wrap != copy2);
178
179 copy1 = empty; // assign empty to discard value
180 copy1 = copy1; // self-assign empty value
181 CHECK (!copy1);
182
183 copy1 = copy2;
184 CHECK (otherVal == *copy1);
185 copy1 = copy1; // self-assign (will be suppressed)
186 CHECK (otherVal == *copy1);
187 copy1 = *copy1; // self-assign also detected in this case
188 CHECK (otherVal == *copy2);
189
190 CHECK (copy1);
191 copy1.reset();
192 CHECK (!copy1);
193 CHECK (empty == copy1);
194 CHECK (copy2 != copy1);
195 VERIFY_ERROR (BOTTOM_VALUE, *copy1 );
196 };
197
198
202 void
204 {
205 cntTracker = 0;
206 {
207 Tracker t1;
208 Tracker t2;
209
210 verifyWrapper<Tracker> (t1, t2);
211 verifyWrapper<Tracker&> (t1, t2);
212 verifyWrapper<Tracker*> (&t1, &t2);
213
214 }
215 CHECK (0 == cntTracker);
216 }
217
218
220 void
222 {
223 using Data = shared_ptr<int>;
224 using Wrap = ItemWrapper<Data>;
225
226 Data data{new int(12345)};
227 CHECK (1 == data.use_count());
228
229 Wrap wrap{data};
230 CHECK (2 == data.use_count());
231 CHECK (12345 == **wrap);
232 CHECK (isSameObject (*data, **wrap));
233 CHECK (!isSameObject (data, *wrap));
234
235 Wrap wcopy{wrap};
236 CHECK (3 == data.use_count());
237
238 Wrap wmove{move (wcopy)};
239 CHECK (3 == data.use_count());
240 CHECK (not wcopy);
241 CHECK (wmove);
242
243 wcopy = move(wmove);
244 CHECK (3 == data.use_count());
245 CHECK (not wmove);
246 CHECK (wcopy);
247
248 Wrap wmove2{move (data)};
249 CHECK (0 == data.use_count());
250 CHECK (3 == wmove2->use_count());
251 CHECK (not data);
252 CHECK (wmove2);
253 CHECK (wrap);
254
255 wmove2 = move (wcopy);
256 CHECK (2 == wmove2->use_count());
257 CHECK (not wcopy);
258 CHECK (wmove2);
259 CHECK (wrap);
260
261 wmove2 = move (wrap);
262 CHECK (1 == wmove2->use_count());
263 CHECK (not wrap);
264 CHECK (wmove2);
265
266 wmove2 = move (wmove);
267 CHECK (not wcopy);
268 CHECK (not wmove);
269 CHECK (not wmove2);
270 }
271
272
276 void
278 {
279 int x = 5;
280 ItemWrapper<int&> refWrap;
281 CHECK (!refWrap);
282
283 refWrap = x;
284 CHECK (refWrap);
285 CHECK (5 == *refWrap);
286 CHECK (x == *refWrap);
287
288 *refWrap += 5;
289 CHECK (x == 10);
290
291 ItemWrapper<int*> ptrWrap (& *refWrap);
292 CHECK ( isSameObject (**ptrWrap, x));
293 CHECK (!isSameObject ( *ptrWrap, &x));
294 **ptrWrap += 13;
295 CHECK (x == 23);
296 }
297
298
299 static auto produceResult() { return rani(); }
300
306 void
308 {
309 FunctionResult<int(void)> randomVal (produceResult);
310
311 // function was never invoked, thus the remembered result is NIL
312 CHECK (!randomVal);
313 VERIFY_ERROR (BOTTOM_VALUE, *randomVal );
314
315 int v1 = randomVal();
316 CHECK (v1 == *randomVal);
317 CHECK (v1 == *randomVal);
318 CHECK (v1 == *randomVal);
319 CHECK (randomVal);
320
321 int v2;
322 do v2 = randomVal();
323 while (v1 == v2);
324 CHECK (v2 == *randomVal);
325 CHECK (v2 == *randomVal);
326 CHECK (v1 != *randomVal);
327 }
328
329
338 void
340 {
341 vector<int> testVec;
342 for (uint i=0; i<10; ++i)
343 testVec.push_back(i);
344
345 FunctionResult<int&(size_t)> funRes (pickElement_ofVector(testVec));
346
347 // function was never invoked, thus the remembered result is NIL
348 CHECK (!funRes);
349 VERIFY_ERROR (BOTTOM_VALUE, *funRes );
350
351 int& r5 = funRes (5);
352 CHECK (funRes); // indicates existence of cached result
353
354 CHECK (5 == r5);
355 CHECK (isSameObject (r5, testVec[5]));
356
357 int& r5x = *funRes;
358 CHECK (isSameObject (r5, r5x));
359
360 CHECK ( isSameObject (r5, *funRes));
361 int& r7 = funRes (7);
362 CHECK (!isSameObject (r5, *funRes));
363 CHECK ( isSameObject (r7, *funRes));
364
365 -- r5x;
366 ++ *funRes;
367 CHECK (5-1 == testVec[5]);
368 CHECK (7+1 == testVec[7]);
369 CHECK (7+1 == r7);
370 }
371 };
372
373 LAUNCHER (ItemWrapper_test, "unit common");
374
375
376}}} // namespace lib::wrapper::test
377
Universal value/ref wrapper accessible similar to a pointer.
const char * CStr
Definition error.hpp:42
Automatically use custom string conversion in C++ stream output.
unsigned int uint
Definition integral.hpp:29
unsigned long int ulong
Definition integral.hpp:31
Adapter to store and hold an element of arbitrary type in local storage.
int & pickElement(vector< int > &vec, size_t idx)
to be bound as test function....
bool operator!=(ItemWrapper< TY > const &w1, ItemWrapper< TY > const &w2)
bool operator==(ItemWrapper< TY > const &w1, ItemWrapper< TY > const &w2)
allow equality comparison if the wrapped types are comparable
Implementation namespace for support and library code.
int rani(uint bound=_iBOUND())
Definition random.hpp:135
Test runner and basic definitions for tests.
bool isSameObject(A const &a, B const &b)
compare plain object identity, based directly on the referee's memory identities.
Definition util.hpp:421
Generating (pseudo) random numbers with controlled seed.
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Definition run.hpp:116
Extension of ItemWrapper: a function remembering the result of the last invocation.
A collection of frequently used helper functions to support unit testing.
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Helper to cache the result of function invocation.