Lumiera  0.pre.03
»edit your freedom«
entry-id-test.cpp
Go to the documentation of this file.
1 /*
2  EntryID(Test) - proof-of-concept test for a combined hash+symbolic ID
3 
4  Copyright (C)
5  2010, 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/test/test-helper.hpp"
21 
22 #include "lib/idi/entry-id.hpp"
27 #include "lib/util-foreach.hpp"
28 #include "lib/format-cout.hpp"
29 #include "lib/symbol.hpp"
30 
31 #include <unordered_map>
32 #include <string>
33 
34 using lib::test::showSizeof;
35 using lib::test::randStr;
36 using util::isSameObject;
37 using util::contains;
38 using util::and_all;
39 using lib::Literal;
40 using std::string;
41 
42 
43 
44 namespace lib {
45 namespace idi {
46 namespace test{
47 
48  using LERR_(WRONG_TYPE);
49 
50  namespace { // Test definitions...
51 
52  struct Dummy { };
53 
54  }
55 
56  using DummyID = EntryID<Dummy>;
59 
60 
61 
62 
63  /***********************************************************************/
74  class EntryID_test : public Test
75  {
76 
77  virtual void
78  run (Arg)
79  {
80  checkCreation();
81  checkBasicProperties();
82  checkComparisions();
83  checkErasure();
84  buildHashtable();
85  }
86 
87 
88 
89  void
90  checkCreation ()
91  {
92  DummyID dID1;
93  DummyID dID2("strange");
94  DummyID dID3;
95  CHECK (dID1.isValid());
96  CHECK (dID2.isValid());
97  CHECK (dID3.isValid());
98  CHECK (dID1 != dID2); CHECK (dID2 != dID1);
99  CHECK (dID2 != dID3); CHECK (dID3 != dID2);
100  CHECK (dID1 != dID3); CHECK (dID3 != dID1);
101 
102  ForkID tID1;
103  ForkID tID2;
104  ForkID tID3("special");
105  CHECK (tID1.isValid());
106  CHECK (tID2.isValid());
107  CHECK (tID3.isValid());
108  CHECK (tID1 != tID2); CHECK (tID2 != tID1);
109  CHECK (tID2 != tID3); CHECK (tID3 != tID2);
110  CHECK (tID1 != tID3); CHECK (tID3 != tID1);
111 
112  cout << dID1 << endl;
113  cout << dID2 << endl;
114  cout << dID3 << endl;
115 
116  cout << tID1 << endl;
117  cout << tID2 << endl;
118  cout << tID3 << endl;
119 
120  DummyID x (dID2); // copy ctor
121  CHECK (x == dID2);
122  CHECK (!isSameObject (x, dID2));
123  }
124 
125 
126  void
127  checkBasicProperties ()
128  {
129  using steam::asset::Asset;
130  using steam::asset::STRUCT;
132  using steam::asset::idi::getAssetIdent;
133 
134  ForkID tID(" test ⚡ ☠ ☭ ⚡ track ");
135 
136  // Symbol-ID will be "sanitised"
137  CHECK ("test_track" == tID.getSym());
138  CHECK (tID == ForkID("☢ test ☢ track ☢"));
139  CHECK (tID == ForkID(string{"☢ test ☢ track ☢"}));
140 
141  // but: there is a pass-through for internal symbols
142  CHECK (tID != ForkID(Symbol{"☢ test ☢ track ☢"}));
143 
144  CHECK (tID.getHash() == ForkID("☢ test ☢ track ☢").getHash());
145 
146  CHECK (getAssetIdent(tID) == Asset::Ident("test_track", Category(STRUCT,"forks"), "lumi", 0));
147 
148  CHECK (tID.getSym() == getAssetIdent(tID).name);
149  CHECK (getAssetIdent(ForkID()).category == Category (STRUCT,"forks"));
150  CHECK (getAssetIdent(ClipID()).category == Category (STRUCT,"clips"));
151 
152  ClipID cID2,cID3;
153  CHECK (cID2.getSym() < cID3.getSym());
154  CHECK (ClipID("x").getSym() == ClipID(" x ").getSym());
155 
156  for (uint i=0; i<10000; ++i)
157  {
158  ForkID arbitrary(randStr(30));
159  CHECK (0 < arbitrary.getHash());
160  CHECK (tID.getHash() != arbitrary.getHash());
161  tID = arbitrary;
162  CHECK (tID.getHash() == arbitrary.getHash());
163  CHECK (tID.getSym() == arbitrary.getSym());
164  CHECK (getAssetIdent(tID)== getAssetIdent(arbitrary));
165  }
166 
167  cout << showSizeof<ForkID>() << endl;
168  cout << showSizeof<BareEntryID>() << endl;
169  cout << showSizeof<lumiera_uid>() << endl;
170  cout << showSizeof<string>() << endl;
171  cout << showSizeof<void*>() << endl;
172  CHECK (sizeof(ForkID) == sizeof(BareEntryID));
173  CHECK (sizeof(ForkID) == sizeof(lumiera_uid) + sizeof(string));
174  }
175 
176 
177  void
178  checkComparisions ()
179  {
180  ForkID tID1("a1");
181  ForkID tID2("a1");
182  ForkID tID3("a2");
183  ForkID tID4("b");
184  CHECK (tID1 == tID2);
185 
186  CHECK (tID2 < tID3);
187  CHECK (tID2 <= tID3);
188  CHECK (tID3 >= tID2);
189  CHECK (tID3 > tID2);
190 
191  CHECK (tID3 < tID4);
192  CHECK (tID3 <= tID4);
193  CHECK (tID4 >= tID3);
194  CHECK (tID4 > tID3);
195 
196  ForkID trackID1, trackID2;
197  CHECK (trackID1 < trackID2); // auto generated IDs are prefix + running counter
198  }
199 
200 
201 
210  void
212  {
213  ForkID fID("suspicious");
214  ClipID cID("suspicious");
215 
216  CHECK (fID.getHash() != cID.getHash());
217  CHECK (fID.getSym() == cID.getSym());
218 
219  BareEntryID bIDf (fID);
220  BareEntryID bIDc (cID);
221 
222  CHECK (bIDf != bIDc);
223  CHECK (bIDf.getHash() != bIDc.getHash());
224  CHECK (bIDf.getSym() == bIDc.getSym());
225  CHECK ("suspicious" == bIDc.getSym());
226 
229  ForkID tIDnew = bIDf.recast<Fork>();
230  ClipID cIDnew = bIDc.recast<Clip>();
231  CHECK (tIDnew == fID);
232  CHECK (cIDnew == cID);
233 
234  VERIFY_ERROR (WRONG_TYPE, bIDf.recast<Clip>());
235  VERIFY_ERROR (WRONG_TYPE, bIDc.recast<Fork>());
236  VERIFY_ERROR (WRONG_TYPE, bIDc.recast<Dummy>());
237  VERIFY_ERROR (WRONG_TYPE, bIDf.recast<Dummy>());
238 
239  CHECK (fID == ForkID::recast (bIDf)); // equivalent static API on typed subclass
240  VERIFY_ERROR (WRONG_TYPE, ForkID::recast(bIDc));
241  VERIFY_ERROR (WRONG_TYPE, ClipID::recast(bIDf));
242  VERIFY_ERROR (WRONG_TYPE, DummyID::recast(bIDc));
243  VERIFY_ERROR (WRONG_TYPE, DummyID::recast(bIDf));
244 
245  // mixed equality comparisons (based on the hash)
246  BareEntryID bIDt_copy (bIDf);
247  CHECK (bIDf == bIDt_copy);
248  CHECK (!isSameObject (bIDf, bIDt_copy));
249 
250  CHECK (fID != bIDc);
251  CHECK (cID != bIDt_copy);
252  CHECK (fID == bIDt_copy);
253 
254  CHECK (bIDf == ForkID ("suspicious"));
255  CHECK (bIDf != ClipID ("suspicious"));
256  CHECK (bIDc == ClipID ("suspicious"));
257  CHECK (ForkID ("suspicious") != ClipID ("suspicious"));
258  }
259 
260 
261 
262  //---key--+-value-+-hash-function---
263  typedef std::unordered_map<DummyID, string, DummyID::UseEmbeddedHash> Hashtable;
264 
272  void
274  {
275  Hashtable tab;
276 
277  for (uint i=0; i<100000; ++i)
278  {
279  DummyID dummy;
280  tab[dummy] = string(dummy);
281  }
282 
283  CHECK (and_all (tab, verifyEntry));
284  CHECK (100000 == tab.size());
285  }
286 
287 
288  static bool
289  verifyEntry (Hashtable::value_type entry)
290  {
291  return checkForHashCollision(string(entry.first), entry.second);
292  }
293 
294  static bool
295  checkForHashCollision(string const& key, string const& val)
296  {
297  if (key != val) cout << "Hash collision: "<<key<<" != "<<val<< endl;
298  return key == val;
299  }
300 
301  };
302 
303 
304 
306  LAUNCHER (EntryID_test, "unit common");
307 
308 
309 }}} // namespace lib::idi::test
type erased baseclass for building a combined hash and symbolic ID.
Definition: entry-id.hpp:133
string name
element ID, comprehensible but sanitised.
Definition: asset.hpp:155
Automatically use custom string conversion in C++ stream output.
Tree like classification of Assets.
Definition: category.hpp:66
AnyPair entry(Query< TY > const &query, typename WrapReturn< TY >::Wrapper &obj)
helper to simplify creating mock table entries, wrapped correctly
Definition: run.hpp:40
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:76
MObject in the Session to represent a clip on the timeline.
typed symbolic and hash ID for asset-like position accounting.
Definition: entry-id.hpp:126
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
bool and_all(CON const &elements, FUN function, P1 &&bind1, ARGS &&...args)
Accept binding for arbitrary function arguments.
A user visible/editable Clip is a reference to a contiguous sequence of media data loaded as Asset in...
Organisational grouping device within the Session model ("Track" / "Media Bin").
Implementation namespace for support and library code.
string randStr(size_t len)
create garbage string of given length
Definition: test-helper.cpp:61
Token or Atom with distinct identity.
Definition: symbol.hpp:117
EntryID< TAR > const & recast() const
try to upcast this BareEntryID to a fully typed EntryID.
Definition: entry-id.hpp:322
Marker types to indicate a literal string and a Symbol.
Simplistic test class runner.
Superinterface describing especially bookkeeping properties.
Definition: asset.hpp:139
A collection of frequently used helper functions to support unit testing.
Rarely used specialisations of otherwise heavily used generic code.
A Fork serves as grouping device within the Session.
Definition: fork.hpp:94
Bare symbolic and hash ID used for accounting of asset like entries.
unsigned char lumiera_uid[16]
storage for a Lumiera unique ID, based on a 128bit random number
Definition: hash-value.h:40
Perform operations "for each element" of a collection.
Naming and labelling scheme for structural assets.
bool contains(SEQ const &cont, typename SEQ::const_reference val)
shortcut for brute-force containment test in any sequential container
Definition: util.hpp:255
bool isSameObject(A const &a, B const &b)
compare plain object identity, based directly on the referee&#39;s memory identities. ...
Definition: util.hpp:421