Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
placement-index-test.cpp
Go to the documentation of this file.
1/*
2 PlacementIndex(Test) - facility keeping track of Placements within the Session
3
4 Copyright (C)
5 2009, 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"
24#include "steam/asset/media.hpp"
25#include "lib/format-string.hpp"
26#include "lib/format-cout.hpp"
27#include "lib/util.hpp"
28
31
32
33using util::_Fmt;
35using std::string;
36
37
38namespace steam {
39namespace mobject {
40namespace session {
41namespace test {
42
43 using session::test::TestClip;
44 using LERR_(BOTTOM_PLACEMENTREF);
45 using LERR_(NONEMPTY_SCOPE);
46 using LERR_(INVALID_SCOPE);
47
49
50
51 /***********************************************************************/
59 class PlacementIndex_test : public Test
60 {
61
62 virtual void
63 run (Arg)
64 {
66 CHECK (index.isValid());
67
69 has_size (0, index);
70
71 PMO::ID elmID = checkSimpleAccess (index);
72 CHECK (index.isValid());
73 has_size (2, index);
74
75 checkTypedAccess (index, elmID);
76 has_size (3, index);
77
78 checkScopeHandling (index);
79 has_size (9, index);
80
82
83 has_size (9, index);
84 CHECK (index.isValid());
85
86 index.clear();
87 has_size (0, index);
88 CHECK (index.isValid());
89 }
90
91 void
92 has_size(uint siz, Idx index)
93 {
94 CHECK (siz == index.size());
95 }
96
97
98 void
100 {
101 PMO clip = TestClip::create();
102 PMO& root = index.getRoot();
103
104 CHECK (0 == index.size());
105
106 PMO::ID elmID = index.insert (clip, root);
107 CHECK (1 == index.size());
108 CHECK ( index.contains (elmID));
109 CHECK (!index.contains (clip)); // index stores copies
110
111 index.remove(clip); // has no effect
112 CHECK (1 == index.size());
113 index.remove(elmID);
114 CHECK (0 == index.size());
115 CHECK (!index.contains (elmID));
116 CHECK ( index.contains (root));
117 }
118
119
120 PMO::ID
122 {
123 PMO testObj = TestClip::create();
124 PMO& root = index.getRoot();
125 PMO::ID elmID = index.insert (testObj, root);
126
127 PMO& elm = index.find(elmID);
128 CHECK (elmID == elm.getID());
129 CHECK (!isSameObject (elm,testObj)); // note: placements are registered as copy
130 CHECK (isSameDef(elm,testObj)); // they are semantically equivalent ////////TICKET #511
131 CHECK (elmID != testObj.getID()); // but have a distinct identity
132
133 PMO::ID elmID2 = index.insert(testObj, root);
134 CHECK (elmID2 != elmID); // ...and each insert creates a new instance
135 CHECK (testObj != index.find (elmID));
136 CHECK (testObj != index.find (elmID2));
137 CHECK (isSameDef(testObj, index.find(elmID)));
138 CHECK (isSameDef(testObj, index.find(elmID2)));
139 CHECK (!isSameObject (testObj, index.find(elmID2)));
140 CHECK (!isSameObject (elm, index.find(elmID2)));
141
142 // can repeatedly retrieve a reference to the same object
143 CHECK ( isSameObject (elm, index.find(elmID )));
144 CHECK ( isSameObject (elm, index.find(elmID )));
145
146 // can also re-access objects by previous ref
147 CHECK ( isSameObject (elm, index.find(elm)));
148 return elmID;
149 }
150
151
152
153 void
154 checkTypedAccess (Idx index, PMO::ID elmID)
155 {
156 PMO& elm = index.find(elmID);
157 CHECK (elmID == elm.getID());
158
159 typedef Placement<Clip> PClip;
160 PClip anotherTestClip = TestClip::create();
161
162 typedef PlacementMO::Id<Clip> IDClip;
163 IDClip clipID = index.insert(anotherTestClip, elmID);
164 // retaining the more specific type info
165
166 // access as MObject...
167 PMO::ID mID = clipID;
168 PMO& asMO = index.find(mID);
169
170 // access as Clip
171 PClip& asClip = index.find(clipID);
172 CHECK (LENGTH_TestClip == asClip->getMedia()->getLength()); // using the Clip API
173
174 CHECK ( isSameObject(asMO,asClip));
175 CHECK (!isSameObject(asClip, anotherTestClip)); // always inserting a copy into the PlacementIndex
176 }
177
178
179 void
181 {
182 RefPlacement invalid;
183 PlacementMO::ID invalidID (invalid);
184 CHECK (!bool(invalidID));
185 CHECK (!bool(invalid));
186
187 VERIFY_ERROR(BOTTOM_PLACEMENTREF, index.find(invalid) );
188 VERIFY_ERROR(BOTTOM_PLACEMENTREF, index.find(invalidID) );
189 VERIFY_ERROR(BOTTOM_PLACEMENTREF, index.getScope(invalidID) );
190
191 CHECK (!index.contains(invalidID));
192
193 PMO testObj = TestClip::create();
194 VERIFY_ERROR(INVALID_SCOPE, index.insert(testObj, invalidID) );
195
196 CHECK (false == index.remove(invalidID));
197 }
198
199
200 void
202 {
203 PMO testObj = TestClip::create();
204 PMO& root = index.getRoot();
205
206 typedef PMO::ID ID;
207 ID e1 = index.insert (testObj, root);
208 ID e11 = index.insert (testObj, e1);
209 ID e12 = index.insert (testObj, e1);
210 ID e13 = index.insert (testObj, e1);
211 ID e131 = index.insert (testObj, e13);
212 ID e132 = index.insert (testObj, e13);
213 ID e133 = index.insert (testObj, e13);
214 ID e1331 = index.insert (testObj, e133);
215
216 CHECK (index.isValid());
217 CHECK (root == index.getScope(e1));
218 CHECK (e1 == index.getScope(e11).getID());
219 CHECK (e1 == index.getScope(e12).getID());
220 CHECK (e1 == index.getScope(e13).getID());
221 CHECK (e13 == index.getScope(e131).getID());
222 CHECK (e13 == index.getScope(e132).getID());
223 CHECK (e13 == index.getScope(e133).getID());
224 CHECK (e133 == index.getScope(e1331).getID());
225 CHECK (e1 != e13);
226 CHECK (e13 != e133);
227
228 CHECK (index.getScope(e11) == index.getScope(index.find(e11)));
229 CHECK (index.getScope(e131) == index.getScope(index.find(e131)));
230
231 VERIFY_ERROR(NONEMPTY_SCOPE, index.remove(e13) ); // can't remove a scope-constituting element
232 VERIFY_ERROR(NONEMPTY_SCOPE, index.remove(e133) );
233
234 CHECK (index.contains(e1331));
235 CHECK (index.remove(e1331));
236 CHECK (!index.contains(e1331));
237 CHECK (!index.remove(e1331));
238
239 CHECK (index.remove(e133)); // but can remove an scope, after emptying it
240 CHECK (!index.contains(e133));
241 CHECK (index.isValid());
242
243 // build a complete new subtree
244 uint siz = index.size();
245 ID e1321 = index.insert (testObj, e132);
246 ID e13211 = index.insert (testObj, e1321);
247 ID e13212 = index.insert (testObj, e1321);
248 ID e13213 = index.insert (testObj, e1321);
249 ID e13214 = index.insert (testObj, e1321);
250 ID e132131 = index.insert (testObj, e13213);
251 ID e132132 = index.insert (testObj, e13213);
252 ID e132133 = index.insert (testObj, e13213);
253 ID e132134 = index.insert (testObj, e13213);
254 ID e132141 = index.insert (testObj, e13214);
255 ID e132142 = index.insert (testObj, e13214);
256 ID e132143 = index.insert (testObj, e13214);
257 ID e132144 = index.insert (testObj, e13214);
258
259 // ...and kill it recursively in one sway
260 index.clear (e1321);
261 CHECK (!index.contains (e1321));
262 CHECK (!index.contains (e13211));
263 CHECK (!index.contains (e13212));
264 CHECK (!index.contains (e13213));
265 CHECK (!index.contains (e132131));
266 CHECK (!index.contains (e132132));
267 CHECK (!index.contains (e132133));
268 CHECK (!index.contains (e132134));
269 CHECK (!index.contains (e132141));
270 CHECK (!index.contains (e132142));
271 CHECK (!index.contains (e132143));
272 CHECK (!index.contains (e132144));
273 CHECK (siz == index.size());
274 CHECK (index.isValid());
275 }
276
277
278
280
292 void
294 {
295 PMO& root = index.getRoot();
296
297 Iter rootContents = index.getReferrers (root.getID());
298 CHECK (rootContents);
299
300 discover (index, rootContents, 0);
301 }
302
303
304 void
305 discover (Idx index, Iter iter, uint level)
306 {
307 uint count (0);
308 for ( ; iter; ++iter )
309 {
310 cout << indent(level) << "::" << *iter << endl;
311
312 ++count;
313 Iter scopeContents = index.getReferrers (iter->getID());
314 if (scopeContents)
315 discover (index, scopeContents, level+1);
316 }
317
318 static _Fmt summary{"...%i elements at Level %i"};
319 cout << indent(level) << summary % count % level << endl;
320
321 CHECK (!iter);
322 CHECK (0 < count);
323 }
324
325 static string
326 indent (uint level)
327 {
328 return string (level, ' ');
329 }
330 };
331
332
334 LAUNCHER (PlacementIndex_test, "unit session");
335
336
337}}}} // namespace steam::mobject::session::test
Iterator tool treating pulled data by a custom transformation (function)
thin wrapper around a size_t hash ID used as primary key for all Asset objects.
Definition asset.hpp:98
Structured compound of Placement instances with lookup capabilities.
bool isValid() const
validity self-check, used for sanity checks and the session self-check.
PlacementMO & getRoot() const
retrieve the logical root scope
bool contains(PlacementMO const &) const
PlacementMO & getScope(PlacementMO const &) const
iterator getReferrers(ID) const
Retrieve all the elements attached to the given entry (scope) Each element (Placement) can act as a s...
ID insert(PlacementMO const &newObj, ID targetScope)
Add a new Placement (Object "instance") into the index.
void clear(ID targetScope)
recursively kill a complete scope, including the given element and all children.
static Placement< Clip > create()
Definition testclip.hpp:70
A front-end for using printf-style formatting.
#define LERR_(_NAME_)
Definition error.hpp:45
Automatically use custom string conversion in C++ stream output.
Front-end for printf-style string template interpolation.
unsigned int uint
Definition integral.hpp:29
Media data represented a specific kind of Asset.
Placement< Label > make_dummyRoot()
Definition testroot.hpp:38
const Duration LENGTH_TestClip(Time(0, 25, 0, 0))
Definition testclip.hpp:77
Namespace of Session and user visible high-level objects.
Definition sequence.hpp:65
bool isSameDef(PlacementMO const &pl1, PlacementMO const &pl2)
compare the properties of placement
Definition placement.cpp:68
Steam-Layer implementation namespace root.
Test runner and basic definitions for tests.
bool isSameObject(A const &a, B const &b)
compare plain object identity, based directly on the referee's memory identities.
Definition util.hpp:421
Core of the session implementation datastructure.
Core abstraction: placement of a media object into session context.
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Definition run.hpp:116
A collection of frequently used helper functions to support unit testing.
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
A stub implementation of the Clip interface for unit testing.
Setup of a faked session root for unit testing.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...