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) Lumiera.org
5  2017, 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 
23 
24 
25 #include "lib/test/run.hpp"
26 #include "lib/test/test-helper.hpp"
27 #include "lib/util.hpp"
28 #include "lib/time/timevalue.hpp"
29 
30 #include "lib/replaceable-item.hpp"
31 
32 
33 
34 
35 namespace lib {
36 namespace wrapper {
37 namespace test{
38 
39  using ::Test;
40  using lib::test::randStr;
41  using lib::test::randTime;
42  using util::isSameObject;
43 
44  using time::Time;
45  using time::Duration;
46  using std::string;
47  using std::rand;
48  using std::swap;
49 
50 
51 
52  namespace { // Test helper: yet another ctor/dtor counting class
53 
54  long cntTracker = 0;
55 
56  struct Tracker
57  {
58  uint i_;
59 
60  Tracker() : i_(rand() % 500) { ++cntTracker; }
61  Tracker(Tracker const& ot) : i_(ot.i_) { ++cntTracker; }
62  Tracker(uint i) : i_(i) { ++cntTracker; }
63  ~Tracker() { --cntTracker; }
64  };
65 
66  struct NonAssign
67  : Tracker
68  {
69  using Tracker::Tracker;
70  NonAssign& operator= (NonAssign const&) =delete;
71  };
72 
73 
74  bool operator== (Tracker const& t1, Tracker const& t2) { return t1.i_ == t2.i_; }
75  bool operator!= (Tracker const& t1, Tracker const& t2) { return t1.i_ != t2.i_; }
76 
77  } // (END) Test helpers
78 
79 
80 
81 
82 
83 
84 
85  /***************************************************************************/
97  class ReplaceableItem_test : public Test
98  {
99 
100 
101  virtual void
102  run (Arg)
103  {
104  ulong l1 (1 + rand() % 1000);
105  ulong l2 (1 + rand() % 1000);
106  string s1 (randStr(50));
107  string s2 (randStr(50));
108  const char* cp (s1.c_str());
109 
110  Time t1{randTime()}, t2{randTime()};
111  Duration d1{randTime()}, d2{randTime()};
112 
113  verifyUsage<ulong> (l1, l2);
114  verifyUsage<ulong*> (&l1, &l2);
115 
116  verifyUsage<string> (s1, s2);
117  verifyUsage<string*> (&s1, &s2);
118 
119  verifyUsage<string> (s2, cp);
120  verifyUsage<string> (cp, "Lumiera");
121  verifyUsage<const char*> (cp, "Lumiera");
122 
123  // non-assignable types...
124  verifyUsage<Time> (t1, t2);
125  verifyUsage<Time> (t1, d1);
126  verifyUsage<Duration> (d1, t2);
127  verifyUsage<Duration> (d1, d2);
128 
129  verifyNonComparableElements();
130  verifyOnlyMoveConstructible();
131  verifySaneInstanceHandling();
132  verifyWrappedPtr ();
133  }
134 
135 
136  template<typename X, typename Y>
137  void
138  verifyUsage (X she, Y he)
139  {
140  using It = ReplaceableItem<X>;
141 
142  It one{she}, two{he};
143  REQUIRE (one != two);
144  CHECK (two == he);
145  CHECK (one == she);
146  CHECK (sizeof(one) == sizeof(X));
147  CHECK (sizeof(two) == sizeof(X));
148 
149  It copy1{she};
150  It copy2;
151 
152  CHECK (one == copy1);
153  CHECK (one != copy2);
154  CHECK (two != copy1);
155  CHECK (two != copy2);
156 
157  CHECK (copy2 == NullValue<X>::get());
158 
159  copy2 = he; // assign from value
160  CHECK (one == copy1);
161  CHECK (one != copy2);
162  CHECK (two != copy1);
163  CHECK (two == copy2);
164 
165  std::swap (copy1, copy2); // possibly move construction / move assignment
166  CHECK (one != copy1);
167  CHECK (one == copy2);
168  CHECK (two == copy1);
169  CHECK (two != copy2);
170 
171  copy1 = copy1; // self assignment (is skipped)
172  copy2 = one; // assignment of an identical value
173 
174  CHECK (copy1 == he);
175  CHECK (copy2 == she);
176  CHECK (one == she);
177  CHECK (two == he);
178 
179  copy1 = It{}; // copy assignment from anonymous holder
180  CHECK (copy1 == NullValue<X>::get());
181  CHECK (copy1 != he);
182  };
183 
184 
190  void
192  {
193  cntTracker = 0;
194  {
195  Tracker t1;
196  Tracker t2;
197 
198  verifyUsage<Tracker> (t1, t2);
199  verifyUsage<Tracker*> (&t1, &t2);
200  verifyUsage<Tracker> (t1, t2.i_);
201  verifyUsage<Tracker, Tracker&> (t1, t2);
202 
203  NonAssign u1;
204  NonAssign u2;
205  verifyUsage<NonAssign> (u1, u2);
206  verifyUsage<NonAssign*> (&u1, &u2);
207  verifyUsage<NonAssign> (u1, u2.i_);
208  verifyUsage<NonAssign, NonAssign&> (u1, u2);
209  verifyUsage<Tracker> (u1, u2);
210  }
211  CHECK (2 == cntTracker); // surviving singleton instances
212  } // NullValue<Tracker> and NullValue<NonAssign>
213 
214 
216  void
218  {
219  int x = 5;
220  ReplaceableItem<int*> ptrWrap;
221  CHECK (ptrWrap.get() == NULL);
222 
223  ptrWrap = &x;
224  CHECK (5 == *ptrWrap.get());
225  CHECK (&x == ptrWrap.get());
226 
227  *ptrWrap.get() += 5;
228  CHECK (x == 10);
229 
230  CHECK ( isSameObject (*ptrWrap.get(), x));
231  CHECK (!isSameObject ( ptrWrap.get(), x));
232  }
233 
234 
235 
237  void
239  {
240  struct Wrap
241  {
242  int i = -10 + rand() % 21;
243  };
244 
245  ReplaceableItem<Wrap> w1 =Wrap{},
246  w2 =Wrap{};
247 
248  int i = w1.get().i,
249  j = w2.get().i;
250 
251  swap (w1,w2);
252 
253  CHECK (i == w2.get().i);
254  CHECK (j == w1.get().i);
255 
256  // w1 == w2; // does not compile since comparison of Wraps is undefined
257  }
258 
259 
260 
266  void
268  {
269  struct Cagey
270  {
271  int i = -10 + rand() % 21;
272 
273  Cagey(Cagey && privy)
274  : i(55)
275  {
276  swap (i, privy.i);
277  }
278 // Cagey(Cagey const&) =delete; //////////////////////////////////////////TICKET #1059 : should be deleted for this test to make any sense
279  Cagey(Cagey const&) =default;
280  Cagey() =default;
281  };
282 
283  ReplaceableItem<Cagey> uc1 {std::move (Cagey{})},
284  uc2 {std::move (Cagey{})};
285 
286  int i = uc1.get().i,
287  j = uc2.get().i;
288 
289  swap (uc1,uc2);
290 
291  CHECK (i == uc2.get().i);
292  CHECK (j == uc1.get().i);
293 
294  ReplaceableItem<Cagey> occult {std::move (uc1)};
295  CHECK (j == occult.get().i);
296 // CHECK (55 == uc1.get().i); //////////////////////////////////////////TICKET #1059
297  }
298  };
299 
300  LAUNCHER (ReplaceableItem_test, "unit common");
301 
302 
303 }}} // namespace lib::wrapper::test
304 
Definition: run.hpp:49
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:71
Implementation namespace for support and library code.
string randStr(size_t len)
create garbage string of given length
Definition: test-helper.cpp:69
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:305
Simple 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:474
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, bypassing any custom comparison operators.
Definition: util.hpp:347