Lumiera  0.pre.03
»edityourfreedom«
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
dependency-factory-test.cpp
Go to the documentation of this file.
1 /*
2  DependencyFactory(Test) - verify modes of creating singletons and dependencies
3 
4  Copyright (C) Lumiera.org
5  2013, 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 
32 #include "lib/test/run.hpp"
33 #include "lib/format-obj.hpp"
34 #include "lib/util.hpp"
35 
36 #include "lib/depend.hpp"
37 #include "lib/depend-inject.hpp"
38 #include "test-target-obj.hpp"
39 
40 #include <cstdlib>
41 
42 
43 
44 namespace lib {
45 namespace test{
46 
47  using ::Test;
48  using util::isSameObject;
49 
50  namespace {
51 
52  const uint MAX_ID = 1000;
53 
54  struct Sub
55  : TestTargetObj
56  {
57  static uint created;
58  uint instanceID_;
59 
60  Sub()
61  : TestTargetObj(created++)
62  ,instanceID_(rand() % MAX_ID)
63  { }
64 
65  virtual operator string() const
66  {
67  return util::typeStr(this)
68  + TestTargetObj::operator string();
69  }
70  };
71  uint Sub::created = 0;
72 
73 
74  struct SubSub
75  : Sub
76  { };
77 
78  struct SubSubSub
79  : SubSub
80  { };
81 
82  struct SubSubDub
83  : SubSub
84  { };
85  }
86 
87 
88 
89 
90 
91  /***************************************************************************/
102  class DependencyFactory_test : public Test
103  {
104 
105 
106  virtual void
108  {
114  }
115 
116 
117  void
119  {
120  Depend<Sub> accessor1;
121  Depend<Sub> accessor2;
122 
123  Sub & o1 = accessor1();
124  Sub & o2 = accessor2();
125  CHECK (isSameObject (o1, o2));
126  }
127 
128 
129  void
131  {
132  Depend<SubSub> specialAccessor;
133  Depend<Sub> genericAccessor;
134 
135  // configure singleton subclass (prior to first use)
137 
138  SubSub& oSub = specialAccessor();
139  Sub& o = genericAccessor();
140 
141  CHECK (!isSameObject (oSub, o));
142  CHECK ( INSTANCEOF (SubSubSub, &oSub));
143  CHECK (!INSTANCEOF (SubSubSub, &o));
144  }
145 
146 
147  void
149  {
150  Depend<SubSub> otherSpecialAccessor;
151 
152  SubSub& oSub = otherSpecialAccessor();
153  CHECK ( INSTANCEOF (SubSubSub, &oSub));
154 
155  Depend<SubSubSub> yetAnotherSpecialAccessor;
156 
157  SubSub& yetAnotherInstance = yetAnotherSpecialAccessor();
158  CHECK ( INSTANCEOF (SubSubSub, &yetAnotherInstance));
159 
160  // both refer to the same configuration and thus access the singleton
161  CHECK (isSameObject (oSub, yetAnotherInstance));
162  }
163 
164 
165  void
167  {
169 
170  Depend<SubSubDub> customised;
171 
172  CHECK ( INSTANCEOF (SubSubDub, &customised()));
173  CHECK (MAX_ID + 10 == customised().instanceID_);
174  }
175 
176  static SubSubDub*
178  {
179  SubSubDub* specialInstance = new SubSubDub;
180  specialInstance->instanceID_ = MAX_ID + 10;
181  return specialInstance;
182  }
183 
184 
185 
186  void
188  {
189  Depend<Sub> genericAccessor;
190  Sub& original = genericAccessor();
191  uint oID = original.instanceID_;
192 
193  {
194  DependInject<Sub>::Local<SubSubSub> mockObject;
195 
196  Sub& replacement = genericAccessor();
197  CHECK ( isSameObject (replacement, *mockObject));
198  CHECK (!isSameObject (original, replacement));
199 
200  Depend<SubSub> special;
201  Depend<SubSubSub> custom;
202 
203  CHECK(!isSameObject (replacement, special() ));
204  CHECK(!isSameObject (replacement, custom() ));
205  }
206 
207  Sub& nextFetch = genericAccessor();
208  CHECK (isSameObject (original, nextFetch));
209  CHECK (oID == nextFetch.instanceID_);
210 
211  {
212  DependInject<Sub>::Local<SubSub> otherMock;
213 
214  Sub& replacement = genericAccessor();
215  uint repID = replacement.instanceID_;
216 
217  CHECK (!INSTANCEOF (SubSub, &original));
218  CHECK ( INSTANCEOF (SubSub, &replacement));
219  CHECK (!INSTANCEOF (SubSubSub, &replacement));
220  CHECK (!isSameObject (original, replacement));
221 
222  Depend<Sub> anotherAccessor;
223  Sub& otherAccess = anotherAccessor();
224  CHECK (isSameObject (replacement, otherAccess));
225  CHECK (repID == otherAccess.instanceID_);
226  CHECK (repID == replacement.instanceID_);
227  CHECK ( oID == original.instanceID_);
228 
229  // verify the instrumentation indeed targeted the generic accessor,
230  // and *not* an accessor of the sub type, i.e Depend<SubSub>
231  Depend<SubSub> genericSubTypeAccessor;
232  SubSub& subTypeAccess = genericSubTypeAccessor();
233  CHECK ( INSTANCEOF (SubSub, &subTypeAccess));
234  CHECK (!isSameObject (replacement, subTypeAccess));
235  CHECK (!isSameObject (original, subTypeAccess));
236  CHECK (repID != subTypeAccess.instanceID_);
237  CHECK ( oID != subTypeAccess.instanceID_);
238  }
239 
240  CHECK (isSameObject (original, genericAccessor()));
241  CHECK (oID == genericAccessor().instanceID_);
242  }
243  };
244 
245 
246 
247  LAUNCHER (DependencyFactory_test, "unit common");
248 
249 
250 }} // namespace lib::test
Dummy target object to be created by factory for unit tests Used to verify sane memory management and...
Definition: run.hpp:49
#define INSTANCEOF(CLASS, EXPR)
shortcut for subclass test, intended for assertions only.
Definition: util.hpp:404
Per type specific configuration of instances created as service dependencies.
static void useSingleton()
configure dependency-injection for type SRV to build a subclass singleton.
static SubSubDub * customFactoryFunction(void)
Access point to singletons and other kinds of dependencies designated by type.
Definition: depend.hpp:275
std::string typeStr(TY const *obj=nullptr) noexcept
failsafe human readable type display
Definition: meta/util.hpp:272
Implementation namespace for support and library code.
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.
Definition: util.hpp:337
This framework allows to (re)configure the lib::Depend front-end for dependency-injection.
std::vector< string > & Arg
Definition: run.hpp:54
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
LAUNCHER(SyncClasslock_test,"unit common")
Register this test class...
Singleton services and Dependency Injection.
Simple functions to represent objects, for debugging and diagnostics.
Configuration handle for temporarily shadowing a dependency by a test mock instance.