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