Lumiera  0.pre.03
»edit your freedom«
defs-registry-impl-test.cpp
Go to the documentation of this file.
1 /*
2  DefsRegistryImpl(Test) - verifying correct behaviour of the defaults registry
3 
4  Copyright (C) Lumiera.org
5  2008, 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/util.hpp"
30 
31 #include "common/query.hpp"
33 #include "lib/format-string.hpp"
34 #include "lib/p.hpp"
35 
37 
38 #include <memory>
39 #include <map>
40 
41 using util::isnil;
42 using util::_Fmt;
43 using lib::P;
44 
45 using std::unique_ptr;
46 using std::string;
47 using std::rand;
48 using std::map;
49 
50 
51 
52 namespace lumiera {
53 namespace query {
54 namespace test {
55 
56  namespace { // Test helpers...
57 
58  _Fmt instancePatt ("obj_%s_%i");
59 
60 
62  string
63  newID (string prefix)
64  {
65  return instancePatt % prefix % rand();
66  }
67 
68 
70  template<int I>
71  struct Dummy
72  {
73  static string name;
74  string instanceID;
75  operator string () const { return instanceID; }
76  bool operator== (const Dummy& odu) const { return this == &odu; }
77 
78 
79  Dummy () : instanceID (newID (name)) {}
80  };
81 
82  template<int I>
83  string Dummy<I>::name = _Fmt("Dummy<%2i>") % I;
84 
85  template<int I>
86  inline P<Dummy<I>>
87  fabricate()
88  {
89  return P<Dummy<I>>(new Dummy<I>);
90  }
91 
92  }//(End)Test helpers
93 
94  using lib::query::test::garbage_query;
95 
96 
97 
98 
99 
100  /********************************************************************/
107  class DefsRegistryImpl_test : public Test
108  {
109  unique_ptr<DefsRegistry> reg_;
110 
111  typedef P<Dummy<13>> Obj;
112  typedef P<Dummy<23>> Pra;
113 
114  typedef Query<Dummy<13>> Q13;
115  typedef Query<Dummy<23>> Q23;
116 
119 
120 
121  // some test objects...
122  Obj o1, o2, o3;
123  Q13 q1, q2, q3, q4, q5;
124  map<QueryKey, Pra> ps;
125 
126  public:
128  : o1 (fabricate<13>())
129  , o2 (fabricate<13>())
130  , o3 (fabricate<13>())
131  , q1 (garbage_query (1))
132  , q2 (garbage_query (2))
133  , q3 (garbage_query (3))
134  , q4 (garbage_query (4))
135  , q5 (garbage_query (5))
136  { }
137 
138 
139  virtual void
140  run (Arg)
141  {
142  this->reg_.reset (new DefsRegistry);
143 
144  fill_table ();
145  check_query ();
146  check_remove ();
147  }
148 
149 
150 
151 
152  void
153  fill_table ()
154  {
155  // at start the registry is indeed empty
156  // thus a query doesn't yield any results....
157  CHECK ( ! *(reg_->candidates(Q13 ("something"))) );
158 
159  reg_->put (o1, q5);
160  reg_->put (o2, q4);
161  reg_->put (o2, q3);
162  reg_->put (o3, q2);
163  reg_->put (o2, q1);
164  reg_->put (o1, Q13()); // the empty query
165 
166  ps.clear();
167  for (int i=0; i<100; ++i)
168  {
169  Pra px (fabricate<23>());
170  Q23 qx (garbage_query());
171  reg_->put (px, qx);
172 
173  // store for verification....
174  px->instanceID = QueryKey(qx).getQueryString();
175  ps[qx] = px;
176  }
177  }
178 
179 
180  void
181  check_query ()
182  {
183  Iter13 i (reg_->candidates(Q13 ("irrelevant query")));
184  CHECK ( i.hasNext());
185  CHECK ( *i == o1); ++i; // ordered according to the degree of the queries
186  CHECK ( *i == o2); ++i; // degree == 1
187  CHECK ( *i == o3); ++i; // degree == 2
188  CHECK ( *i == o2); ++i; // ...
189  CHECK ( *i == o2); ++i;
190  CHECK ( *i == o1);
191  CHECK (!i.hasNext());
192  CHECK (! *++i ); // null after end
193 
194  i = reg_->candidates(q2);
195  CHECK ( *i == o3); ++i; // found by direct match
196  CHECK ( *i == o1); ++i; // followed by the ordered enumeration
197  CHECK ( *i == o2); ++i;
198  CHECK ( *i == o3); ++i;
199  CHECK ( *i == o2); ++i;
200  CHECK ( *i == o2); ++i;
201  CHECK ( *i == o1); ++i;
202  CHECK (!i.hasNext());
203 
204  i = reg_->candidates(Q13());
205  CHECK ( *i == o1); ++i; // found by direct match to the empty query
206  CHECK ( *i == o1); ++i;
207  CHECK ( *i == o2); ++i;
208  CHECK ( *i == o3); ++i;
209  CHECK ( *i == o2); ++i;
210  CHECK ( *i == o2); ++i;
211  CHECK ( *i == o1); ++i;
212  CHECK (!i.hasNext());
213 
214  uint d=0;
215  uint d_prev=0;
216  Iter23 j = reg_->candidates(Q23 ("some crap"));
217  for ( ; *j ; ++j )
218  {
219  CHECK ( *j );
220  Q23 qx ((*j)->instanceID);
221  CHECK ( ps[qx] == (*j));
222  d = QueryKey(qx).degree();
223  CHECK ( d_prev <= d );
224  d_prev = d;
225  }
226  CHECK (!j.hasNext());
227 
228  // calling with an arbitrary (registered) query
229  // yields the corresponding object at start of the enumeration
230  Q23 someQuery(ps.begin()->first);
231  j = reg_->candidates(someQuery);
232  CHECK ( *j == ps.begin()->second);
233 
234  }
235 
236 
237  void
238  check_remove ()
239  {
240  reg_->forget (o2);
241 
242  Iter13 i (reg_->candidates(q4));
243  CHECK ( i.hasNext());
244  CHECK ( *i == o1); ++i; // ordered according to the degree of the queries
245  // but the o2 entries are missing
246  CHECK ( *i == o3); ++i;
247  // o2 missing
248  // o2 missing
249  CHECK ( *i == o1);
250  CHECK (!i.hasNext());
251 
252  o3.reset(); // killing the only reference....
253  // expires the weak ref in the registry
254 
255  i = reg_->candidates(Q13 ("something"));
256  CHECK ( i.hasNext());
257  CHECK ( *i == o1); ++i; // ordered according to the degree of the queries
258  // but now also the o3 entry is missing...
259  CHECK ( *i == o1);
260  CHECK (!i.hasNext());
261 
262  CHECK ( reg_->put (o1, q5)); // trying to register the same object at the same place
263  // doesn't change anything (but counts as "success")
264  i = reg_->candidates(q5);
265  CHECK ( *i == o1); ++i; // direct match
266  CHECK ( *i == o1); ++i;
267  CHECK ( *i == o1); ++i;
268  CHECK (!i.hasNext());
269 
270  CHECK (!reg_->put (o2, q5)); // trying to (re)register o2 with a existing query
271  // counts as failure (nothing changes)
272  i = reg_->candidates(q5);
273  CHECK ( *i == o1); ++i; // direct match
274  CHECK ( *i == o1); ++i;
275  CHECK ( *i == o1); ++i;
276  CHECK (!i.hasNext());
277 
278  CHECK ( reg_->put (o2, q2)); // trying to (re)register o2 with another query succeeds
279  i = reg_->candidates(q2);
280  CHECK ( *i == o2); ++i; // direct match
281  CHECK ( *i == o1); ++i;
282  CHECK ( *i == o2); ++i; // inserted here in the dataset, since q2 has degree 2
283  CHECK ( *i == o1); ++i;
284  CHECK (!i.hasNext());
285 
286  CHECK ( reg_->forget (o1));
287  CHECK (!reg_->forget (o1)); // failure, because it's already removed
288  CHECK ( reg_->forget (o2));
289 
290  o3 = fabricate<13>(); // another object is another object (it's irrelevant...)
291 
292  i = reg_->candidates(q2);
293  CHECK (! (*i)); // empty
294  }
295 
296  };
297 
298 
300  LAUNCHER (DefsRegistryImpl_test, "function session");
301 
302 
303 
304 }}} // namespace lumiera::query::test
used for enumerating solutions
Basic and generic representation of an internal query.
Definition: run.hpp:49
Front-end for printf-style string template interpolation.
Customised refcounting smart pointer.
A front-end for using printf-style formatting.
A piece of implementation code factored out into a separate header (include).
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
diagnostic helpers to support test related to predicate queries
Wrapper for indexing and ordering.
Definition: query.hpp:397
Lumiera public interface.
Definition: advice.cpp:113
Customised refcounting smart pointer template, built upon std::shared_ptr, but forwarding type relati...
Definition: trait.hpp:80
Generic interface to express a query for specifically typed result elements exposing some capabilitie...
Definition: query.hpp:279
ElementBoxWidget::Config::Qualifier name(string id)
define the name-ID displayed in the caption