Lumiera  0.pre.03
»edit your freedom«
replaceable-item-test.cpp
1 /*
2  ReplaceableItem(Test) - adapter to take snapshot from non-assignable values
3 
4  Copyright (C)
5  2017, 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 
14 
15 
16 #include "lib/test/run.hpp"
17 #include "lib/test/test-helper.hpp"
18 #include "lib/util.hpp"
19 #include "lib/time/timevalue.hpp"
20 
21 #include "lib/replaceable-item.hpp"
22 
23 
24 
25 
26 namespace lib {
27 namespace wrapper {
28 namespace test{
29 
30  using ::Test;
31  using lib::test::randStr;
32  using lib::test::randTime;
33  using util::isSameObject;
34 
35  using time::Time;
36  using time::Duration;
37  using std::string;
38  using std::swap;
39 
40 
41 
42  namespace { // Test helper: yet another ctor/dtor counting class
43 
44  long cntTracker = 0;
45 
46  struct Tracker
47  {
48  uint i_;
49 
50  Tracker() : i_(rani(500)) { ++cntTracker; }
51  Tracker(Tracker const& ot) : i_(ot.i_) { ++cntTracker; }
52  Tracker(uint i) : i_(i) { ++cntTracker; }
53  ~Tracker() { --cntTracker; }
54  };
55 
56  struct NonAssign
57  : Tracker
58  {
59  using Tracker::Tracker;
60  NonAssign& operator= (NonAssign const&) =delete;
61  };
62 
63 
64  bool operator== (Tracker const& t1, Tracker const& t2) { return t1.i_ == t2.i_; }
65  bool operator!= (Tracker const& t1, Tracker const& t2) { return t1.i_ != t2.i_; }
66 
67  } // (END) Test helpers
68 
69 
70 
71 
72 
73 
74 
75  /***************************************************************************/
87  class ReplaceableItem_test : public Test
88  {
89 
90 
91  virtual void
92  run (Arg)
93  {
94  seedRand();
95  ulong l1 (1 + rani(1000));
96  ulong l2 (1 + rani(1000));
97  string s1 (randStr(50));
98  string s2 (randStr(50));
99  const char* cp (s1.c_str());
100 
101  Time t1{randTime()}, t2{randTime()};
102  Duration d1{randTime()}, d2{randTime()};
103 
104  verifyUsage<ulong> (l1, l2);
105  verifyUsage<ulong*> (&l1, &l2);
106 
107  verifyUsage<string> (s1, s2);
108  verifyUsage<string*> (&s1, &s2);
109 
110  verifyUsage<string> (s2, cp);
111  verifyUsage<string> (cp, "Lumiera");
112  verifyUsage<const char*> (cp, "Lumiera");
113 
114  // non-assignable types...
115  verifyUsage<Time> (t1, t2);
116  verifyUsage<Time> (t1, d1);
117  verifyUsage<Duration> (d1, t2);
118  verifyUsage<Duration> (d1, d2);
119 
120  verifyNonComparableElements();
121  verifyOnlyMoveConstructible();
122  verifySaneInstanceHandling();
123  verifyWrappedPtr ();
124  }
125 
126 
127  template<typename X, typename Y>
128  void
129  verifyUsage (X she, Y he)
130  {
131  using It = ReplaceableItem<X>;
132 
133  It one{she}, two{he};
134  REQUIRE (one != two);
135  CHECK (two == he);
136  CHECK (one == she);
137  CHECK (sizeof(one) == sizeof(X));
138  CHECK (sizeof(two) == sizeof(X));
139 
140  It copy1{she};
141  It copy2;
142 
143  CHECK (one == copy1);
144  CHECK (one != copy2);
145  CHECK (two != copy1);
146  CHECK (two != copy2);
147 
148  CHECK (copy2 == NullValue<X>::get());
149 
150  copy2 = he; // assign from value
151  CHECK (one == copy1);
152  CHECK (one != copy2);
153  CHECK (two != copy1);
154  CHECK (two == copy2);
155 
156  std::swap (copy1, copy2); // possibly move construction / move assignment
157  CHECK (one != copy1);
158  CHECK (one == copy2);
159  CHECK (two == copy1);
160  CHECK (two != copy2);
161 
162  copy1 = copy1; // self assignment (is skipped)
163  copy2 = one; // assignment of an identical value
164 
165  CHECK (copy1 == he);
166  CHECK (copy2 == she);
167  CHECK (one == she);
168  CHECK (two == he);
169 
170  copy1 = It{}; // copy assignment from anonymous holder
171  CHECK (copy1 == NullValue<X>::get());
172  CHECK (copy1 != he);
173  };
174 
175 
181  void
183  {
184  cntTracker = 0;
185  {
186  Tracker t1;
187  Tracker t2;
188 
189  verifyUsage<Tracker> (t1, t2);
190  verifyUsage<Tracker*> (&t1, &t2);
191  verifyUsage<Tracker> (t1, t2.i_);
192  verifyUsage<Tracker, Tracker&> (t1, t2);
193 
194  NonAssign u1;
195  NonAssign u2;
196  verifyUsage<NonAssign> (u1, u2);
197  verifyUsage<NonAssign*> (&u1, &u2);
198  verifyUsage<NonAssign> (u1, u2.i_);
199  verifyUsage<NonAssign, NonAssign&> (u1, u2);
200  verifyUsage<Tracker> (u1, u2);
201  }
202  CHECK (2 == cntTracker); // surviving singleton instances
203  } // NullValue<Tracker> and NullValue<NonAssign>
204 
205 
207  void
209  {
210  int x = 5;
211  ReplaceableItem<int*> ptrWrap;
212  CHECK (ptrWrap.get() == NULL);
213 
214  ptrWrap = &x;
215  CHECK (5 == *ptrWrap.get());
216  CHECK (&x == ptrWrap.get());
217 
218  *ptrWrap.get() += 5;
219  CHECK (x == 10);
220 
221  CHECK ( isSameObject (*ptrWrap.get(), x));
222  CHECK (!isSameObject ( ptrWrap.get(), x));
223  }
224 
225 
226 
228  void
230  {
231  struct Wrap
232  {
233  int i = -10 + rani(21);
234  };
235 
236  ReplaceableItem<Wrap> w1 =Wrap{},
237  w2 =Wrap{};
238 
239  int i = w1.get().i,
240  j = w2.get().i;
241 
242  swap (w1,w2);
243 
244  CHECK (i == w2.get().i);
245  CHECK (j == w1.get().i);
246 
247  // w1 == w2; // does not compile since comparison of Wraps is undefined
248  }
249 
250 
251 
257  void
259  {
260  struct Cagey
261  {
262  int i = -10 + rani(21);
263 
264  Cagey(Cagey && privy)
265  : i(55)
266  {
267  swap (i, privy.i);
268  }
269 // Cagey(Cagey const&) =delete; //////////////////////////////////////////TICKET #1059 : should be deleted for this test to make any sense
270  Cagey(Cagey const&) =default;
271  Cagey() =default;
272  };
273 
274  ReplaceableItem<Cagey> uc1 {std::move (Cagey{})},
275  uc2 {std::move (Cagey{})};
276 
277  int i = uc1.get().i,
278  j = uc2.get().i;
279 
280  swap (uc1,uc2);
281 
282  CHECK (i == uc2.get().i);
283  CHECK (j == uc1.get().i);
284 
285  ReplaceableItem<Cagey> occult {std::move (uc1)};
286  CHECK (j == occult.get().i);
287 // CHECK (55 == uc1.get().i); //////////////////////////////////////////TICKET #1059
288  }
289  };
290 
291  LAUNCHER (ReplaceableItem_test, "unit common");
292 
293 
294 }}} // namespace lib::wrapper::test
295 
Definition: run.hpp:40
int rani(uint bound=_iBOUND())
Definition: random.hpp:135
bool operator==(PtrDerefIter< I1 > const &il, PtrDerefIter< I2 > const &ir)
Supporting equality comparisons...
Singleton holder for NIL or default value objects.
Definition: null-value.hpp:62
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
Simplistic test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A collection of frequently used helper functions to support unit testing.
ExampleStrategy::Qualifier two(string additionalArg)
definition of another qualifier two(arg), accepting an additional argument
Adapter container to take snapshots from non-assignable values.
Duration is the internal Lumiera time metric.
Definition: timevalue.hpp:468
lib::time::Time randTime()
create a random but not insane Time value between 1s ...
ExampleStrategy::Qualifier one()
definition of a qualifier one()
a family of time value like entities and their relationships.
Adapter wrapper to treat non-assignable values as if they were assignable.
bool isSameObject(A const &a, B const &b)
compare plain object identity, based directly on the referee&#39;s memory identities. ...
Definition: util.hpp:421