Lumiera  0.pre.03
»edit your freedom«
w-link-test.cpp
Go to the documentation of this file.
1 /*
2  WLink(Test) - verify managed link to sigc::trackable widget
3 
4  Copyright (C) Lumiera.org
5  2018, 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 
28 #include "lib/test/run.hpp"
29 #include "lib/test/test-helper.hpp"
30 #include "stage/model/w-link.hpp"
31 #include "lib/util.hpp"
32 
33 #include <utility>
34 #include <memory>
35 
36 
37 using util::isSameObject;
38 using std::make_unique;
39 using std::move;
40 
41 
42 namespace stage {
43 namespace model{
44 namespace test {
45 
46 
47  namespace { // Test fixture...
48 
49  template<typename X>
50  struct DummyWidget
51  : public sigc::trackable
52  {
53  X val = 1 + rand() % 100;
54  };
55  }
56 
57 
58 
59 
60  /******************************************************************************/
64  class WLink_test : public Test
65  {
66 
67  virtual void
68  run (Arg)
69  {
70  verify_standardUsage();
71  verify_reconnect();
72  verify_copy();
73  }
74 
75 
79  void
81  {
82  using Wint = DummyWidget<int>;
83  auto widget = make_unique<Wint>();
84  int r = widget->val;
85 
86  WLink<Wint> link{*widget};
87  CHECK (link);
88  link->val += 23;
89  CHECK (r+23 == widget->val);
90 
91  // kill widget
92  widget.reset();
93  CHECK (not link);
94  VERIFY_ERROR (BOTTOM_VALUE, link->val );
95  }
96 
97 
99  void
101  {
102  using Wint = DummyWidget<int>;
103 
104  auto w1 = make_unique<Wint>();
105  auto w2 = make_unique<Wint>();
106  int r1 = w1->val;
107  int r2 = w2->val;
108 
109  WLink<Wint> l1;
110  WLink<Wint> l2{*w1};
111  CHECK (not l1);
112  CHECK ( l2);
113 
114  l2->val = r1;
115  l1.connect(*l2);
116  ++l1->val;
117  CHECK (w1->val == r1+1);
118  CHECK (isSameObject (*l1, *l2));
119 
120  l2.connect(*w2);
121  CHECK (not isSameObject (*l1, *l2));
122  w2->val = r2;
123  CHECK (r1+1 == l1->val);
124  CHECK (r2 == l2->val);
125 
126  w1.reset(); // kill first widget
127  CHECK (not l1);
128  CHECK ( l2);
129  l2->val *= -10;
130  l2.clear();
131  CHECK (not l1);
132  CHECK (not l2);
133  CHECK (-10*r2 == w2->val);
134  l1.connect(*w2);
135  l2.connect(*l1);
136  CHECK (-10*r2 == l2->val);
137  CHECK (isSameObject (*l1, *l2));
138  CHECK (isSameObject (*l1, *w2));
139 
140  // implicitly kill second widget
141  *w2 = Wint{};
142  CHECK (not l1);
143  CHECK (not l2);
144  }
145 
146 
148  void
150  {
151  using Wint = DummyWidget<int>;
152  auto w1 = make_unique<Wint>();
153  auto w2 = make_unique<Wint>();
154 
155  WLink<Wint> l1;
156  WLink<Wint> l2{l1};
157  CHECK (not l2);
158  l2.connect(*w1);
159 
160  WLink<Wint> l3{l2};
161  CHECK (l3);
162  CHECK (w1->val == l3->val);
163 
164  CHECK (not l1); // they are statefull and independent
165  l1 = move(l2);
166  CHECK (not l2);
167  CHECK (l1);
168  CHECK (isSameObject (*l1, *l3));
169 
170  l2 = WLink<Wint>{WLink<Wint>{*w2}};
171  CHECK (w2->val == l2->val);
172 
173  l1 = l3;
174  CHECK (w1->val == l1->val);
175  WLink<Wint>& ref{l1};
176  l1 = move(ref);
177  CHECK (w1->val == l1->val);
178  CHECK (w1->val == l3->val);
179 
180  std::swap (l2, l3);
181  CHECK (w1->val == l1->val);
182  CHECK (w1->val == l2->val);
183  CHECK (w2->val == l3->val);
184 
185  w1.reset();
186  CHECK (not l1);
187  CHECK (not l2);
188  CHECK (w2->val == l3->val);
189 
190  using Wuint = DummyWidget<uint>;
191  auto uu = make_unique<Wuint>();
192  WLink<Wuint> lu{*uu};
193 
195 // l1 = uu;
196 // l1.connect(*uu);
197 
198  // But it is a compile time check...
199  // At runtime, only the bare pointer is managed
200  l1 = reinterpret_cast<WLink<Wint>&&> (lu);
201  CHECK ((int)uu->val == l1->val);
202  CHECK (not lu); // assignment was actually a move
203 
204  // even the subversively attached link is managed properly
205  uu.reset();
206  CHECK (not l1);
207 
208  // others unaffected...
209  CHECK (not l2);
210  CHECK (l3);
211  }
212  };
213 
214 
216  LAUNCHER (WLink_test, "unit stage");
217 
218 
219 }}} // namespace stage::model::test
Definition: run.hpp:49
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
Simple test class runner.
Lumiera GTK UI implementation root.
Definition: guifacade.cpp:46
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.
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.
Definition: util.hpp:372