Lumiera  0.pre.03
»edit your freedom«
gen-node-test.cpp
Go to the documentation of this file.
1 /*
2  GenNode(Test) - fundamental properties of a generic tree node element
3 
4  Copyright (C) Lumiera.org
5  2015, 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/test/test-helper.hpp"
30 #include "lib/format-cout.hpp"
31 #include "lib/diff/gen-node.hpp"
32 #include "lib/diff/record.hpp"
33 #include "lib/time/timevalue.hpp"
34 #include "lib/util-quant.hpp"
35 #include "lib/util.hpp"
36 
37 #include <string>
38 
39 using util::isnil;
40 using util::contains;
41 using util::isSameObject;
42 using util::almostEqual;
43 using lib::hash::LuidH;
44 using lib::time::FSecs;
45 using lib::time::Time;
48 using std::string;
49 
50 
51 namespace lib {
52 namespace diff{
53 namespace test{
54 
55  using LERR_(WRONG_TYPE);
56  using LERR_(BOTTOM_VALUE);
57 
58  namespace {//Test fixture....
59 
60  const double PI = 3.14159265358979323846264338328;
61 
62  }//(End)Test fixture
63 
64 
65 
66 
67 
68 
69 
70 
71 
72  /*****************************************************************************/
91  class GenNode_test : public Test
92  {
93 
94  virtual void
95  run (Arg)
96  {
97  simpleUsage();
98  equalityMatch();
99  objectShortcut();
100  symbolReference();
101  sequenceIteration();
103  }
104 
105 
106  void
107  simpleUsage()
108  {
109  // can build from the supported value types
110  GenNode n1(42);
111  CHECK (42 == n1.data.get<int>());
112  CHECK (!n1.isNamed());
113  CHECK (contains (n1.idi.getSym(), "_CHILD_"));
114  CHECK (contains (name(n1), "_CHILD_"));
115 
116  // can optionally be named
117  GenNode n2("π", PI);
118  CHECK (almostEqual (PI, n2.data.get<double>()));
119  CHECK (n2.isNamed());
120  CHECK ("π" == n2.idi.getSym());
121  CHECK ("π" == name(n2));
122 
123  // is a copyable value
124  GenNode n11(n1);
125  CHECK (n1 == n11);
126  CHECK (42 == n11.data.get<int>());
127 
128  // is assignable with compatible payload value
129  n11.data = 24;
130  CHECK (n1 != n11);
131  CHECK (24 == n11.data.get<int>());
132  CHECK (42 == n1.data.get<int>());
133 
134  // is assignable within the same kind of value
135  n1 = n11;
136  CHECK (n1 == n11);
137 
138  // but assignment may not alter payload type
139  VERIFY_ERROR (WRONG_TYPE, n1 = n2 );
140 
141  // can build recursive data structures
142  GenNode n3(Rec({GenNode("type", "spam"), GenNode("ham", "eggs")}));
143  CHECK ("spam" == n3.data.get<Rec>().getType());
144  CHECK ("eggs" == n3.data.get<Rec>().get("ham").data.get<string>());
145  CHECK ("ham" == n3.data.get<Rec>().get("ham").idi.getSym());
146  CHECK (n3.data.get<Rec>().get("ham").isNamed());
147  CHECK (!n3.isNamed());
148 
149  cout << n3 <<endl; // diagnostic spam
150 
151  CHECK (renderCompact(n3) == "spam{ham=eggs}"_expect);
152  }
153 
154 
155  void
156  objectShortcut()
157  {
158  auto o0 = MakeRec().genNode();
159  auto o1 = MakeRec().genNode("νόμος");
160  auto o2 = MakeRec().type("spam").genNode();
161  auto o3 = MakeRec().attrib("Ψ", int64_t(42), "π", 3.14159265358979323846264338328).genNode("μάθησις");
162 
163  CHECK (!o0.isNamed());
164  CHECK (isnil(o0.data.get<Rec>()));
165  CHECK ("NIL" == o0.data.get<Rec>().getType());
166 
167  CHECK (o1.isNamed());
168  CHECK ("νόμος" == o1.idi.getSym());
169  CHECK (isnil(o1.data.get<Rec>()));
170 
171  CHECK (!o2.isNamed());
172  CHECK ("spam" == o2.data.get<Rec>().getType());
173  CHECK (isnil(o2.data.get<Rec>()));
174 
175  CHECK (o3.isNamed());
176  CHECK ("μάθησις" == o3.idi.getSym());
177  CHECK ("NIL" == o3.data.get<Rec>().getType());
178  CHECK (GenNode("Ψ", int64_t(42)) == o3.data.get<Rec>().get("Ψ"));
179  CHECK (42L == o3.data.get<Rec>().get("Ψ").data.get<int64_t>());
180  CHECK (almostEqual (PI, o3.data.get<Rec>().get("π").data.get<double>()));
181 
182  LuidH luid;
183  //Demonstration: object builder is based on the mutator mechanism for Records...
184  auto o4 = Rec::Mutator(o2.data.get<Rec>()) // ...use GenNode o2 as starting point
185  .appendChild(GenNode("τ", Time(1,2,3,4))) // a named node with Time value
186  .scope('*' // a char node
187  ,"★" // a string node
188  ,luid // a hash value (LUID)
189  ,TimeSpan(Time::ZERO, FSecs(23,25)) // a time span
190  ,MakeRec().type("ham").scope("eggs").genNode()) // a spam object
191  .genNode("baked beans"); // ---> finish into named node
192 
193  CHECK (o4.isNamed());
194  CHECK ("baked beans" == o4.idi.getSym());
195  CHECK ("spam" == o4.data.get<Rec>().getType()); // this was "inherited" from o2
196 
197  auto scope = o4.data.get<Rec>().scope();
198  CHECK (!isnil(scope));
199  CHECK (GenNode("τ", Time(1,2,3,4)) == *scope);
200  ++scope;
201  CHECK (char('*') == scope->data.get<char>());
202  ++scope;
203  CHECK ("★" == scope->data.get<string>());
204  ++scope;
205  CHECK (luid == scope->data.get<LuidH>());
206  ++scope;
207  CHECK (Time(920,0) == scope->data.get<TimeSpan>().end());
208  ++scope;
209  auto spam = *scope;
210  CHECK (!++scope);
211  CHECK ("ham" == spam.data.get<Rec>().getType());
212  CHECK (spam.contains ("eggs"));
213 
214  // but while o4 was based on o2,
215  // adding all the additional contents didn't mutate o2
216  CHECK (isnil(o2.data.get<Rec>()));
217 
218  // special case: can create an (Attribute) GenNode with specifically crafted ID
219  idi::EntryID<uint8_t> veryspecialID{"quasi niente"};
220  auto o5 = MakeRec().genNode(veryspecialID);
221  CHECK (o5 != MakeRec().genNode());
222  CHECK (o5 != MakeRec().genNode("quasi niente"));
223  CHECK (o5 == MakeRec().genNode(veryspecialID));
224  CHECK (name(o5) == "quasi_niente"); // Note: EntryID sanitised the string
225  CHECK (o5.idi == veryspecialID);
226  }
227 
228 
229 
230  void
231  symbolReference()
232  {
233  GenNode ham = MakeRec().type("spam").attrib("τ", Time(23,42)).genNode("egg bacon sausage and spam");
234 
235  GenNode::ID hamID(ham);
236  CHECK (hamID == ham.idi);
237  CHECK (hamID.getSym() == ham.idi.getSym());
238  CHECK (hamID.getHash() == ham.idi.getHash());
239  CHECK (contains (string(hamID), "spam")); // Lovely spam!
240 
241  Ref ref1("egg bacon sausage and spam"); // empty placeholder
242  Ref ref2(ham);
243 
244  CHECK (ref1.idi == ham.idi);
245  CHECK (ref2.idi == ham.idi);
246 
247  // can stand-in for the original Record...
248  Rec& hamRef = ham.data.get<Rec>();
249  CHECK (isSameObject (hamRef, ref2.data.get<Rec>()));
250  VERIFY_ERROR (BOTTOM_VALUE, ref1.data.get<Rec>());
251 
252  RecRef rr1 = ref1.data.get<RecRef>();
253  RecRef rr2 = ref2.data.get<RecRef>();
254 
255  CHECK ( isnil(rr1));
256  CHECK (!isnil(rr2));
257  Rec& ham_ref = rr2;
258  CHECK (isSameObject(hamRef, ham_ref));
259  CHECK (isSameObject(hamRef, *rr2.get()));
260 
261  // pre-defined special ref-tokens
262  CHECK ("_END_" == name(Ref::END));
263  CHECK ("_THIS_" == name(Ref::THIS));
264  CHECK ("_CHILD_" == name(Ref::CHILD));
265  CHECK ("_ATTRIBS_" == name(Ref::ATTRIBS));
266 
267  CHECK (isnil (Ref::END.data.get<RecRef>()));
268  CHECK (isnil (Ref::THIS.data.get<RecRef>()));
269  CHECK (isnil (Ref::CHILD.data.get<RecRef>()));
270  CHECK (isnil (Ref::ATTRIBS.data.get<RecRef>()));
271  }
272 
273 
274  void
275  sequenceIteration()
276  {
277  GenNode n = MakeRec()
278  .scope('*' // a char node
279  ,"★" // a string node
280  , PI // a double value
281  ,MakeRec().type("ham")
282  .scope("eggs","spam","spam")
283  .genNode("spam") // a spam object
284  ,TimeSpan(Time::ZERO, FSecs(23,25)) // a time span
285  ,int64_t(42)) // long value
286  .attrib("hasSpam", true) // boolean Attribute
287  .genNode("baked beans"); // build Node from named Record
288 
289 
290  cout << "--spam--"<<endl;
291  for (auto & elm : n)
292  cout << elm <<endl;
293 
294  CHECK (renderCompact(n) == "{hasSpam=true|*, ★, 3.1415927, ham{|eggs, spam, spam}, 0:00:00.000≺920ms≻, 42}"_expect);
295 
296 
297  auto iter = n.begin();
298  CHECK (!isnil (iter));
299  CHECK (1 == iter.level());
300  CHECK ("baked beans" == iter->idi.getSym()); // initially the Record itself is exposed
301  CHECK (Rec::TYPE_NIL == iter->data.get<Rec>().getType());
302 
303  ++iter;
304  CHECK (2 == iter.level()); // delve into the contents,
305  CHECK ("hasSpam" == iter->idi.getSym()); // ...starting with the attribute(s)
306  CHECK (true == iter->data.get<bool>());
307  CHECK ("GenNode-ID(\"hasSpam\")-DataCap|«bool»|true" == string(*iter));
308 
309  ++iter;
310  CHECK (!iter->isNamed()); // contents of the object's scope
311  CHECK ('*' == iter->data.get<char>());
312 
313  ++iter;
314  CHECK (!iter->isNamed());
315  CHECK ("★" == iter->data.get<string>());
316 
317  ++iter;
318  CHECK (!iter->isNamed());
319  CHECK (almostEqual (PI, iter->data.get<double>()));
320 
321  ++iter;
322  CHECK ("spam" == iter->idi.getSym()); // the nested object is first exposed as a whole
323  CHECK ("ham" == iter->data.get<Rec>().getType());
324 
325  ++iter;
326  CHECK (3 == iter.level());
327  CHECK ("eggs" == iter->data.get<string>()); // contents of the nested ("spam") object's scope
328 
329  ++iter;
330  CHECK ("spam" == iter->data.get<string>());
331 
332  ++iter;
333  CHECK ("spam" == iter->data.get<string>());
334  CHECK (3 == iter.level());
335 
336  ++iter;
337  CHECK (2 == iter.level()); // decreasing level indicates we left nested scope
338  CHECK (!iter->isNamed()); // next item in the enclosing scope
339  CHECK ("0:00:00.000≺920ms≻" == string(iter->data.get<TimeSpan>()));
340  ++iter;
341  CHECK (!iter->isNamed());
342  CHECK (42 == iter->data.get<int64_t>());
343  CHECK (2 == iter.level());
344 
345  ++iter; // nothing more on top level beyond the initial Record
346  CHECK (0 == iter.level());
347  CHECK (isnil (iter));
348 
349 
350 
351  // another kind of iteration: shallow child data sequence
352  // note: exposing the DataCap of each child
353  auto child = childData(n);
354  CHECK (!isnil (child));
355  CHECK ('*' == child->get<char>());
356 
357  ++child;
358  CHECK ("★" == child->get<string>());
359 
360  ++child;
361  CHECK (almostEqual (PI, child->get<double>()));
362 
363  ++child;
364  CHECK ("ham" == child->get<Rec>().getType());
365  CHECK ("eggs" == child->get<Rec>().child(0).data.get<string>());
366 
367  ++child;
368  CHECK (TimeSpan(Time::ZERO, FSecs(23,25)) == child->get<TimeSpan>());
369 
370  ++child;
371  CHECK (42 == child->get<int64_t>());
372 
373  ++child;
374  CHECK (isnil (child));
375 
376  CHECK (n.hasChildren());
377  CHECK (not GenNode{42}.hasChildren());
378  }
379 
380 
381  void
382  equalityMatch()
383  {
384  int i1 = 64; GenNode ni1(i1);
385  int i2 = 126; GenNode ni2(i2);
386  int64_t l1 = 64; GenNode nl1(l1);
387  int64_t l2 = 126; GenNode nl2(l2);
388  short r1 = 64; GenNode nr1(r1);
389  short r2 = 126; GenNode nr2(r2);
390  double d1 = 64; GenNode nd1(d1);
391  double d2 = 126; GenNode nd2(d2);
392  char c1 = '@'; GenNode nc1(c1);
393  char c2 = '~'; GenNode nc2(c2);
394  bool b1 = true; GenNode nb1(b1);
395  bool b2 = false; GenNode nb2(b2);
396  string s1 = ""; GenNode ns1(s1);
397  string s2 = "↯"; GenNode ns2(s2);
398 
399  time::Time t1 = randTime(); GenNode nt1(t1);
400  time::Time t2(-t1); GenNode nt2(t2);
401  time::Offset to1(t1); GenNode nto1(to1);
402  time::Offset to2(t2); GenNode nto2(to2);
403  time::Duration td1(to2); GenNode ntd1(td1);
404  time::Duration td2(to2*2); GenNode ntd2(td2);
405  time::TimeSpan ts1(t1, td1); GenNode nts1(ts1);
406  time::TimeSpan ts2(t2, td2); GenNode nts2(ts2);
407  hash::LuidH h1; GenNode nh1(h1);
408  hash::LuidH h2; GenNode nh2(h2);
409 
410  Rec spam1({GenNode("ham", "eggs")}); GenNode rec1(spam1);
411  Rec spam2(MakeRec(spam1).type("spam")); GenNode rec2(spam2);
412 
413  RecRef recRef1(spam1); Ref ref1(rec1);
414  RecRef recRef2(spam2); Ref ref2(rec2);
415  // NOTE: same ID as referee
416  CHECK (ni1 == ni1);
417  CHECK (ni2 == ni2);
418  CHECK (nl1 == nl1);
419  CHECK (nl2 == nl2);
420  CHECK (nr1 == nr1);
421  CHECK (nr2 == nr2);
422  CHECK (nd1 == nd1);
423  CHECK (nd2 == nd2);
424  CHECK (nc1 == nc1);
425  CHECK (nc2 == nc2);
426  CHECK (nb1 == nb1);
427  CHECK (nb2 == nb2);
428  CHECK (ns1 == ns1);
429  CHECK (ns2 == ns2);
430  CHECK (nt1 == nt1 );
431  CHECK (nt2 == nt2 );
432  CHECK (nto1 == nto1);
433  CHECK (nto2 == nto2);
434  CHECK (ntd1 == ntd1);
435  CHECK (ntd2 == ntd2);
436  CHECK (nts1 == nts1);
437  CHECK (nts2 == nts2);
438  CHECK (nh1 == nh1 );
439  CHECK (nh2 == nh2 );
440  CHECK (rec1 == rec1);
441  CHECK (rec2 == rec2);
442  CHECK (ref1 == ref1);
443  CHECK (ref2 == ref2);
444 
445  CHECK (ni1 != ni2); CHECK (ni2 != ni1);
446  CHECK (nl1 != nl2); CHECK (nl2 != nl1);
447  CHECK (nr1 != nr2); CHECK (nr2 != nr1);
448  CHECK (nd1 != nd2); CHECK (nd2 != nd1);
449  CHECK (nc1 != nc2); CHECK (nc2 != nc1);
450  CHECK (nb1 != nb2); CHECK (nb2 != nb1);
451  CHECK (ns1 != ns2); CHECK (ns2 != ns1);
452  CHECK (nt1 != nt2 ); CHECK (nt2 != nt1 );
453  CHECK (nto1 != nto2); CHECK (nto2 != nto1);
454  CHECK (ntd1 != ntd2); CHECK (ntd2 != ntd1);
455  CHECK (nts1 != nts2); CHECK (nts2 != nts1);
456  CHECK (nh1 != nh2 ); CHECK (nh2 != nh1 );
457  CHECK (rec1 != rec2); CHECK (rec2 != rec1);
458  CHECK (ref1 != ref2); CHECK (ref2 != ref1);
459 
460  CHECK (ni1 != ni2); CHECK (ni2 != ni1);
461  CHECK (ni1 != nl1); CHECK (nl1 != ni1);
462  CHECK (ni1 != nl2); CHECK (nl2 != ni1);
463  CHECK (ni1 != nr1); CHECK (nr1 != ni1);
464  CHECK (ni1 != nr2); CHECK (nr2 != ni1);
465  CHECK (ni1 != nd1); CHECK (nd1 != ni1);
466  CHECK (ni1 != nd2); CHECK (nd2 != ni1);
467  CHECK (ni1 != nc1); CHECK (nc1 != ni1);
468  CHECK (ni1 != nc2); CHECK (nc2 != ni1);
469  CHECK (ni1 != nb1); CHECK (nb1 != ni1);
470  CHECK (ni1 != nb2); CHECK (nb2 != ni1);
471  CHECK (ni1 != ns1); CHECK (ns1 != ni1);
472  CHECK (ni1 != ns2); CHECK (ns2 != ni1);
473  CHECK (ni1 != nt1 ); CHECK (nt1 != ni1);
474  CHECK (ni1 != nt2 ); CHECK (nt2 != ni1);
475  CHECK (ni1 != nto1); CHECK (nto1 != ni1);
476  CHECK (ni1 != nto2); CHECK (nto2 != ni1);
477  CHECK (ni1 != ntd1); CHECK (ntd1 != ni1);
478  CHECK (ni1 != ntd2); CHECK (ntd2 != ni1);
479  CHECK (ni1 != nts1); CHECK (nts1 != ni1);
480  CHECK (ni1 != nts2); CHECK (nts2 != ni1);
481  CHECK (ni1 != nh1 ); CHECK (nh1 != ni1);
482  CHECK (ni1 != nh2 ); CHECK (nh2 != ni1);
483  CHECK (ni1 != rec1); CHECK (rec1 != ni1);
484  CHECK (ni1 != rec2); CHECK (rec2 != ni1);
485  CHECK (ni1 != ref1); CHECK (ref1 != ni1);
486  CHECK (ni1 != ref2); CHECK (ref2 != ni1);
487 
488  CHECK (ni2 != nl1); CHECK (nl1 != ni2);
489  CHECK (ni2 != nl2); CHECK (nl2 != ni2);
490  CHECK (ni2 != nr1); CHECK (nr1 != ni2);
491  CHECK (ni2 != nr2); CHECK (nr2 != ni2);
492  CHECK (ni2 != nd1); CHECK (nd1 != ni2);
493  CHECK (ni2 != nd2); CHECK (nd2 != ni2);
494  CHECK (ni2 != nc1); CHECK (nc1 != ni2);
495  CHECK (ni2 != nc2); CHECK (nc2 != ni2);
496  CHECK (ni2 != nb1); CHECK (nb1 != ni2);
497  CHECK (ni2 != nb2); CHECK (nb2 != ni2);
498  CHECK (ni2 != ns1); CHECK (ns1 != ni2);
499  CHECK (ni2 != ns2); CHECK (ns2 != ni2);
500  CHECK (ni2 != nt1 ); CHECK (nt1 != ni2);
501  CHECK (ni2 != nt2 ); CHECK (nt2 != ni2);
502  CHECK (ni2 != nto1); CHECK (nto1 != ni2);
503  CHECK (ni2 != nto2); CHECK (nto2 != ni2);
504  CHECK (ni2 != ntd1); CHECK (ntd1 != ni2);
505  CHECK (ni2 != ntd2); CHECK (ntd2 != ni2);
506  CHECK (ni2 != nts1); CHECK (nts1 != ni2);
507  CHECK (ni2 != nts2); CHECK (nts2 != ni2);
508  CHECK (ni2 != nh1 ); CHECK (nh1 != ni2);
509  CHECK (ni2 != nh2 ); CHECK (nh2 != ni2);
510  CHECK (ni2 != rec1); CHECK (rec1 != ni2);
511  CHECK (ni2 != rec2); CHECK (rec2 != ni2);
512  CHECK (ni2 != ref1); CHECK (ref1 != ni2);
513  CHECK (ni2 != ref2); CHECK (ref2 != ni2);
514 
515  CHECK (nl1 != nl2); CHECK (nl2 != nl1);
516  CHECK (nl1 != nr1); CHECK (nr1 != nl1);
517  CHECK (nl1 != nr2); CHECK (nr2 != nl1);
518  CHECK (nl1 != nd1); CHECK (nd1 != nl1);
519  CHECK (nl1 != nd2); CHECK (nd2 != nl1);
520  CHECK (nl1 != nc1); CHECK (nc1 != nl1);
521  CHECK (nl1 != nc2); CHECK (nc2 != nl1);
522  CHECK (nl1 != nb1); CHECK (nb1 != nl1);
523  CHECK (nl1 != nb2); CHECK (nb2 != nl1);
524  CHECK (nl1 != ns1); CHECK (ns1 != nl1);
525  CHECK (nl1 != ns2); CHECK (ns2 != nl1);
526  CHECK (nl1 != nt1 ); CHECK (nt1 != nl1);
527  CHECK (nl1 != nt2 ); CHECK (nt2 != nl1);
528  CHECK (nl1 != nto1); CHECK (nto1 != nl1);
529  CHECK (nl1 != nto2); CHECK (nto2 != nl1);
530  CHECK (nl1 != ntd1); CHECK (ntd1 != nl1);
531  CHECK (nl1 != ntd2); CHECK (ntd2 != nl1);
532  CHECK (nl1 != nts1); CHECK (nts1 != nl1);
533  CHECK (nl1 != nts2); CHECK (nts2 != nl1);
534  CHECK (nl1 != nh1 ); CHECK (nh1 != nl1);
535  CHECK (nl1 != nh2 ); CHECK (nh2 != nl1);
536  CHECK (nl1 != rec1); CHECK (rec1 != nl1);
537  CHECK (nl1 != rec2); CHECK (rec2 != nl1);
538  CHECK (nl1 != ref1); CHECK (ref1 != nl1);
539  CHECK (nl1 != ref2); CHECK (ref2 != nl1);
540 
541  CHECK (nl2 != nr1); CHECK (nr1 != nl2);
542  CHECK (nl2 != nr2); CHECK (nr2 != nl2);
543  CHECK (nl2 != nd1); CHECK (nd1 != nl2);
544  CHECK (nl2 != nd2); CHECK (nd2 != nl2);
545  CHECK (nl2 != nc1); CHECK (nc1 != nl2);
546  CHECK (nl2 != nc2); CHECK (nc2 != nl2);
547  CHECK (nl2 != nb1); CHECK (nb1 != nl2);
548  CHECK (nl2 != nb2); CHECK (nb2 != nl2);
549  CHECK (nl2 != ns1); CHECK (ns1 != nl2);
550  CHECK (nl2 != ns2); CHECK (ns2 != nl2);
551  CHECK (nl2 != nt1 ); CHECK (nt1 != nl2);
552  CHECK (nl2 != nt2 ); CHECK (nt2 != nl2);
553  CHECK (nl2 != nto1); CHECK (nto1 != nl2);
554  CHECK (nl2 != nto2); CHECK (nto2 != nl2);
555  CHECK (nl2 != ntd1); CHECK (ntd1 != nl2);
556  CHECK (nl2 != ntd2); CHECK (ntd2 != nl2);
557  CHECK (nl2 != nts1); CHECK (nts1 != nl2);
558  CHECK (nl2 != nts2); CHECK (nts2 != nl2);
559  CHECK (nl2 != nh1 ); CHECK (nh1 != nl2);
560  CHECK (nl2 != nh2 ); CHECK (nh2 != nl2);
561  CHECK (nl2 != rec1); CHECK (rec1 != nl2);
562  CHECK (nl2 != rec2); CHECK (rec2 != nl2);
563  CHECK (nl2 != ref1); CHECK (ref1 != nl2);
564  CHECK (nl2 != ref2); CHECK (ref2 != nl2);
565 
566  CHECK (nr1 != nr2); CHECK (nr2 != nr1);
567  CHECK (nr1 != nd1); CHECK (nd1 != nr1);
568  CHECK (nr1 != nd2); CHECK (nd2 != nr1);
569  CHECK (nr1 != nc1); CHECK (nc1 != nr1);
570  CHECK (nr1 != nc2); CHECK (nc2 != nr1);
571  CHECK (nr1 != nb1); CHECK (nb1 != nr1);
572  CHECK (nr1 != nb2); CHECK (nb2 != nr1);
573  CHECK (nr1 != ns1); CHECK (ns1 != nr1);
574  CHECK (nr1 != ns2); CHECK (ns2 != nr1);
575  CHECK (nr1 != nt1 ); CHECK (nt1 != nr1);
576  CHECK (nr1 != nt2 ); CHECK (nt2 != nr1);
577  CHECK (nr1 != nto1); CHECK (nto1 != nr1);
578  CHECK (nr1 != nto2); CHECK (nto2 != nr1);
579  CHECK (nr1 != ntd1); CHECK (ntd1 != nr1);
580  CHECK (nr1 != ntd2); CHECK (ntd2 != nr1);
581  CHECK (nr1 != nts1); CHECK (nts1 != nr1);
582  CHECK (nr1 != nts2); CHECK (nts2 != nr1);
583  CHECK (nr1 != nh1 ); CHECK (nh1 != nr1);
584  CHECK (nr1 != nh2 ); CHECK (nh2 != nr1);
585  CHECK (nr1 != rec1); CHECK (rec1 != nr1);
586  CHECK (nr1 != rec2); CHECK (rec2 != nr1);
587  CHECK (nr1 != ref1); CHECK (ref1 != nr1);
588  CHECK (nr1 != ref2); CHECK (ref2 != nr1);
589 
590  CHECK (nr2 != nd1); CHECK (nd1 != nr2);
591  CHECK (nr2 != nd2); CHECK (nd2 != nr2);
592  CHECK (nr2 != nc1); CHECK (nc1 != nr2);
593  CHECK (nr2 != nc2); CHECK (nc2 != nr2);
594  CHECK (nr2 != nb1); CHECK (nb1 != nr2);
595  CHECK (nr2 != nb2); CHECK (nb2 != nr2);
596  CHECK (nr2 != ns1); CHECK (ns1 != nr2);
597  CHECK (nr2 != ns2); CHECK (ns2 != nr2);
598  CHECK (nr2 != nt1 ); CHECK (nt1 != nr2);
599  CHECK (nr2 != nt2 ); CHECK (nt2 != nr2);
600  CHECK (nr2 != nto1); CHECK (nto1 != nr2);
601  CHECK (nr2 != nto2); CHECK (nto2 != nr2);
602  CHECK (nr2 != ntd1); CHECK (ntd1 != nr2);
603  CHECK (nr2 != ntd2); CHECK (ntd2 != nr2);
604  CHECK (nr2 != nts1); CHECK (nts1 != nr2);
605  CHECK (nr2 != nts2); CHECK (nts2 != nr2);
606  CHECK (nr2 != nh1 ); CHECK (nh1 != nr2);
607  CHECK (nr2 != nh2 ); CHECK (nh2 != nr2);
608  CHECK (nr2 != rec1); CHECK (rec1 != nr2);
609  CHECK (nr2 != rec2); CHECK (rec2 != nr2);
610  CHECK (nr2 != ref1); CHECK (ref1 != nr2);
611  CHECK (nr2 != ref2); CHECK (ref2 != nr2);
612 
613  CHECK (nd1 != nd2); CHECK (nd2 != nd1);
614  CHECK (nd1 != nc1); CHECK (nc1 != nd1);
615  CHECK (nd1 != nc2); CHECK (nc2 != nd1);
616  CHECK (nd1 != nb1); CHECK (nb1 != nd1);
617  CHECK (nd1 != nb2); CHECK (nb2 != nd1);
618  CHECK (nd1 != ns1); CHECK (ns1 != nd1);
619  CHECK (nd1 != ns2); CHECK (ns2 != nd1);
620  CHECK (nd1 != nt1 ); CHECK (nt1 != nd1);
621  CHECK (nd1 != nt2 ); CHECK (nt2 != nd1);
622  CHECK (nd1 != nto1); CHECK (nto1 != nd1);
623  CHECK (nd1 != nto2); CHECK (nto2 != nd1);
624  CHECK (nd1 != ntd1); CHECK (ntd1 != nd1);
625  CHECK (nd1 != ntd2); CHECK (ntd2 != nd1);
626  CHECK (nd1 != nts1); CHECK (nts1 != nd1);
627  CHECK (nd1 != nts2); CHECK (nts2 != nd1);
628  CHECK (nd1 != nh1 ); CHECK (nh1 != nd1);
629  CHECK (nd1 != nh2 ); CHECK (nh2 != nd1);
630  CHECK (nd1 != rec1); CHECK (rec1 != nd1);
631  CHECK (nd1 != rec2); CHECK (rec2 != nd1);
632  CHECK (nd1 != ref1); CHECK (ref1 != nd1);
633  CHECK (nd1 != ref2); CHECK (ref2 != nd1);
634 
635  CHECK (nd2 != nc1); CHECK (nc1 != nd2);
636  CHECK (nd2 != nc2); CHECK (nc2 != nd2);
637  CHECK (nd2 != nb1); CHECK (nb1 != nd2);
638  CHECK (nd2 != nb2); CHECK (nb2 != nd2);
639  CHECK (nd2 != ns1); CHECK (ns1 != nd2);
640  CHECK (nd2 != ns2); CHECK (ns2 != nd2);
641  CHECK (nd2 != nt1 ); CHECK (nt1 != nd2);
642  CHECK (nd2 != nt2 ); CHECK (nt2 != nd2);
643  CHECK (nd2 != nto1); CHECK (nto1 != nd2);
644  CHECK (nd2 != nto2); CHECK (nto2 != nd2);
645  CHECK (nd2 != ntd1); CHECK (ntd1 != nd2);
646  CHECK (nd2 != ntd2); CHECK (ntd2 != nd2);
647  CHECK (nd2 != nts1); CHECK (nts1 != nd2);
648  CHECK (nd2 != nts2); CHECK (nts2 != nd2);
649  CHECK (nd2 != nh1 ); CHECK (nh1 != nd2);
650  CHECK (nd2 != nh2 ); CHECK (nh2 != nd2);
651  CHECK (nd2 != rec1); CHECK (rec1 != nd2);
652  CHECK (nd2 != rec2); CHECK (rec2 != nd2);
653  CHECK (nd2 != ref1); CHECK (ref1 != nd2);
654  CHECK (nd2 != ref2); CHECK (ref2 != nd2);
655 
656  CHECK (nc1 != nc2); CHECK (nc2 != nc1);
657  CHECK (nc1 != nb1); CHECK (nb1 != nc1);
658  CHECK (nc1 != nb2); CHECK (nb2 != nc1);
659  CHECK (nc1 != ns1); CHECK (ns1 != nc1);
660  CHECK (nc1 != ns2); CHECK (ns2 != nc1);
661  CHECK (nc1 != nt1 ); CHECK (nt1 != nc1);
662  CHECK (nc1 != nt2 ); CHECK (nt2 != nc1);
663  CHECK (nc1 != nto1); CHECK (nto1 != nc1);
664  CHECK (nc1 != nto2); CHECK (nto2 != nc1);
665  CHECK (nc1 != ntd1); CHECK (ntd1 != nc1);
666  CHECK (nc1 != ntd2); CHECK (ntd2 != nc1);
667  CHECK (nc1 != nts1); CHECK (nts1 != nc1);
668  CHECK (nc1 != nts2); CHECK (nts2 != nc1);
669  CHECK (nc1 != nh1 ); CHECK (nh1 != nc1);
670  CHECK (nc1 != nh2 ); CHECK (nh2 != nc1);
671  CHECK (nc1 != rec1); CHECK (rec1 != nc1);
672  CHECK (nc1 != rec2); CHECK (rec2 != nc1);
673  CHECK (nc1 != ref1); CHECK (ref1 != nc1);
674  CHECK (nc1 != ref2); CHECK (ref2 != nc1);
675 
676  CHECK (nc2 != nb1); CHECK (nb1 != nc2);
677  CHECK (nc2 != nb2); CHECK (nb2 != nc2);
678  CHECK (nc2 != ns1); CHECK (ns1 != nc2);
679  CHECK (nc2 != ns2); CHECK (ns2 != nc2);
680  CHECK (nc2 != nt1 ); CHECK (nt1 != nc2);
681  CHECK (nc2 != nt2 ); CHECK (nt2 != nc2);
682  CHECK (nc2 != nto1); CHECK (nto1 != nc2);
683  CHECK (nc2 != nto2); CHECK (nto2 != nc2);
684  CHECK (nc2 != ntd1); CHECK (ntd1 != nc2);
685  CHECK (nc2 != ntd2); CHECK (ntd2 != nc2);
686  CHECK (nc2 != nts1); CHECK (nts1 != nc2);
687  CHECK (nc2 != nts2); CHECK (nts2 != nc2);
688  CHECK (nc2 != nh1 ); CHECK (nh1 != nc2);
689  CHECK (nc2 != nh2 ); CHECK (nh2 != nc2);
690  CHECK (nc2 != rec1); CHECK (rec1 != nc2);
691  CHECK (nc2 != rec2); CHECK (rec2 != nc2);
692  CHECK (nc2 != ref1); CHECK (ref1 != nc2);
693  CHECK (nc2 != ref2); CHECK (ref2 != nc2);
694 
695  CHECK (nb1 != nb2); CHECK (nb2 != nb1);
696  CHECK (nb1 != ns1); CHECK (ns1 != nb1);
697  CHECK (nb1 != ns2); CHECK (ns2 != nb1);
698  CHECK (nb1 != nt1 ); CHECK (nt1 != nb1);
699  CHECK (nb1 != nt2 ); CHECK (nt2 != nb1);
700  CHECK (nb1 != nto1); CHECK (nto1 != nb1);
701  CHECK (nb1 != nto2); CHECK (nto2 != nb1);
702  CHECK (nb1 != ntd1); CHECK (ntd1 != nb1);
703  CHECK (nb1 != ntd2); CHECK (ntd2 != nb1);
704  CHECK (nb1 != nts1); CHECK (nts1 != nb1);
705  CHECK (nb1 != nts2); CHECK (nts2 != nb1);
706  CHECK (nb1 != nh1 ); CHECK (nh1 != nb1);
707  CHECK (nb1 != nh2 ); CHECK (nh2 != nb1);
708  CHECK (nb1 != rec1); CHECK (rec1 != nb1);
709  CHECK (nb1 != rec2); CHECK (rec2 != nb1);
710  CHECK (nb1 != ref1); CHECK (ref1 != nb1);
711  CHECK (nb1 != ref2); CHECK (ref2 != nb1);
712 
713  CHECK (nb2 != ns1); CHECK (ns1 != nb2);
714  CHECK (nb2 != ns2); CHECK (ns2 != nb2);
715  CHECK (nb2 != nt1 ); CHECK (nt1 != nb2);
716  CHECK (nb2 != nt2 ); CHECK (nt2 != nb2);
717  CHECK (nb2 != nto1); CHECK (nto1 != nb2);
718  CHECK (nb2 != nto2); CHECK (nto2 != nb2);
719  CHECK (nb2 != ntd1); CHECK (ntd1 != nb2);
720  CHECK (nb2 != ntd2); CHECK (ntd2 != nb2);
721  CHECK (nb2 != nts1); CHECK (nts1 != nb2);
722  CHECK (nb2 != nts2); CHECK (nts2 != nb2);
723  CHECK (nb2 != nh1 ); CHECK (nh1 != nb2);
724  CHECK (nb2 != nh2 ); CHECK (nh2 != nb2);
725  CHECK (nb2 != rec1); CHECK (rec1 != nb2);
726  CHECK (nb2 != rec2); CHECK (rec2 != nb2);
727  CHECK (nb2 != ref1); CHECK (ref1 != nb2);
728  CHECK (nb2 != ref2); CHECK (ref2 != nb2);
729 
730  CHECK (ns1 != nt2 ); CHECK (nt2 != ns1);
731  CHECK (ns1 != nto1); CHECK (nto1 != ns1);
732  CHECK (ns1 != nto2); CHECK (nto2 != ns1);
733  CHECK (ns1 != ntd1); CHECK (ntd1 != ns1);
734  CHECK (ns1 != ntd2); CHECK (ntd2 != ns1);
735  CHECK (ns1 != nts1); CHECK (nts1 != ns1);
736  CHECK (ns1 != nts2); CHECK (nts2 != ns1);
737  CHECK (ns1 != nh1 ); CHECK (nh1 != ns1);
738  CHECK (ns1 != nh2 ); CHECK (nh2 != ns1);
739  CHECK (ns1 != rec1); CHECK (rec1 != ns1);
740  CHECK (ns1 != rec2); CHECK (rec2 != ns1);
741  CHECK (ns1 != ref1); CHECK (ref1 != ns1);
742  CHECK (ns1 != ref2); CHECK (ref2 != ns1);
743 
744  CHECK (ns2 != nt1 ); CHECK (nt1 != ns2);
745  CHECK (ns2 != nt2 ); CHECK (nt2 != ns2);
746  CHECK (ns2 != nto1); CHECK (nto1 != ns2);
747  CHECK (ns2 != nto2); CHECK (nto2 != ns2);
748  CHECK (ns2 != ntd1); CHECK (ntd1 != ns2);
749  CHECK (ns2 != ntd2); CHECK (ntd2 != ns2);
750  CHECK (ns2 != nts1); CHECK (nts1 != ns2);
751  CHECK (ns2 != nts2); CHECK (nts2 != ns2);
752  CHECK (ns2 != nh1 ); CHECK (nh1 != ns2);
753  CHECK (ns2 != nh2 ); CHECK (nh2 != ns2);
754  CHECK (ns2 != rec1); CHECK (rec1 != ns2);
755  CHECK (ns2 != rec2); CHECK (rec2 != ns2);
756  CHECK (ns2 != ref1); CHECK (ref1 != ns2);
757  CHECK (ns2 != ref2); CHECK (ref2 != ns2);
758 
759  CHECK (nt1 != nt2 ); CHECK (nt2 != nt1);
760  CHECK (nt1 != nto1); CHECK (nto1 != nt1);
761  CHECK (nt1 != nto2); CHECK (nto2 != nt1);
762  CHECK (nt1 != ntd1); CHECK (ntd1 != nt1);
763  CHECK (nt1 != ntd2); CHECK (ntd2 != nt1);
764  CHECK (nt1 != nts1); CHECK (nts1 != nt1);
765  CHECK (nt1 != nts2); CHECK (nts2 != nt1);
766  CHECK (nt1 != nh1 ); CHECK (nh1 != nt1);
767  CHECK (nt1 != nh2 ); CHECK (nh2 != nt1);
768  CHECK (nt1 != rec1); CHECK (rec1 != nt1);
769  CHECK (nt1 != rec2); CHECK (rec2 != nt1);
770  CHECK (nt1 != ref1); CHECK (ref1 != nt1);
771  CHECK (nt1 != ref2); CHECK (ref2 != nt1);
772 
773  CHECK (nt2 != nto1); CHECK (nto1 != nt2);
774  CHECK (nt2 != nto2); CHECK (nto2 != nt2);
775  CHECK (nt2 != ntd1); CHECK (ntd1 != nt2);
776  CHECK (nt2 != ntd2); CHECK (ntd2 != nt2);
777  CHECK (nt2 != nts1); CHECK (nts1 != nt2);
778  CHECK (nt2 != nts2); CHECK (nts2 != nt2);
779  CHECK (nt2 != nh1 ); CHECK (nh1 != nt2);
780  CHECK (nt2 != nh2 ); CHECK (nh2 != nt2);
781  CHECK (nt2 != rec1); CHECK (rec1 != nt2);
782  CHECK (nt2 != rec2); CHECK (rec2 != nt2);
783  CHECK (nt2 != ref1); CHECK (ref1 != nt2);
784  CHECK (nt2 != ref2); CHECK (ref2 != nt2);
785 
786  CHECK (nto1 != nto2); CHECK (nto2 != nto1);
787  CHECK (nto1 != ntd1); CHECK (ntd1 != nto1);
788  CHECK (nto1 != ntd2); CHECK (ntd2 != nto1);
789  CHECK (nto1 != nts1); CHECK (nts1 != nto1);
790  CHECK (nto1 != nts2); CHECK (nts2 != nto1);
791  CHECK (nto1 != nh1 ); CHECK (nh1 != nto1);
792  CHECK (nto1 != nh2 ); CHECK (nh2 != nto1);
793  CHECK (nto1 != rec1); CHECK (rec1 != nto1);
794  CHECK (nto1 != rec2); CHECK (rec2 != nto1);
795  CHECK (nto1 != ref1); CHECK (ref1 != nto1);
796  CHECK (nto1 != ref2); CHECK (ref2 != nto1);
797 
798  CHECK (nto2 != ntd1); CHECK (ntd1 != nto2);
799  CHECK (nto2 != ntd2); CHECK (ntd2 != nto2);
800  CHECK (nto2 != nts1); CHECK (nts1 != nto2);
801  CHECK (nto2 != nts2); CHECK (nts2 != nto2);
802  CHECK (nto2 != nh1 ); CHECK (nh1 != nto2);
803  CHECK (nto2 != nh2 ); CHECK (nh2 != nto2);
804  CHECK (nto2 != rec1); CHECK (rec1 != nto2);
805  CHECK (nto2 != rec2); CHECK (rec2 != nto2);
806  CHECK (nto2 != ref1); CHECK (ref1 != nto2);
807  CHECK (nto2 != ref2); CHECK (ref2 != nto2);
808 
809  CHECK (ntd1 != ntd2); CHECK (ntd2 != ntd1);
810  CHECK (ntd1 != nts1); CHECK (nts1 != ntd1);
811  CHECK (ntd1 != nts2); CHECK (nts2 != ntd1);
812  CHECK (ntd1 != nh1 ); CHECK (nh1 != ntd1);
813  CHECK (ntd1 != nh2 ); CHECK (nh2 != ntd1);
814  CHECK (ntd1 != rec1); CHECK (rec1 != ntd1);
815  CHECK (ntd1 != rec2); CHECK (rec2 != ntd1);
816  CHECK (ntd1 != ref1); CHECK (ref1 != ntd1);
817  CHECK (ntd1 != ref2); CHECK (ref2 != ntd1);
818 
819  CHECK (ntd2 != nts1); CHECK (nts1 != ntd2);
820  CHECK (ntd2 != nts2); CHECK (nts2 != ntd2);
821  CHECK (ntd2 != nh1 ); CHECK (nh1 != ntd2);
822  CHECK (ntd2 != nh2 ); CHECK (nh2 != ntd2);
823  CHECK (ntd2 != rec1); CHECK (rec1 != ntd2);
824  CHECK (ntd2 != rec2); CHECK (rec2 != ntd2);
825  CHECK (ntd2 != ref1); CHECK (ref1 != ntd2);
826  CHECK (ntd2 != ref2); CHECK (ref2 != ntd2);
827 
828  CHECK (nts1 != nts2); CHECK (nts2 != nts1);
829  CHECK (nts1 != nh1 ); CHECK (nh1 != nts1);
830  CHECK (nts1 != nh2 ); CHECK (nh2 != nts1);
831  CHECK (nts1 != rec1); CHECK (rec1 != nts1);
832  CHECK (nts1 != rec2); CHECK (rec2 != nts1);
833  CHECK (nts1 != ref1); CHECK (ref1 != nts1);
834  CHECK (nts1 != ref2); CHECK (ref2 != nts1);
835 
836  CHECK (nts2 != nh1 ); CHECK (nh1 != nts2);
837  CHECK (nts2 != nh2 ); CHECK (nh2 != nts2);
838  CHECK (nts2 != rec1); CHECK (rec1 != nts2);
839  CHECK (nts2 != rec2); CHECK (rec2 != nts2);
840  CHECK (nts2 != ref1); CHECK (ref1 != nts2);
841  CHECK (nts2 != ref2); CHECK (ref2 != nts2);
842 
843  CHECK (nh1 != nh2 ); CHECK (nh2 != nh1);
844  CHECK (nh1 != rec1); CHECK (rec1 != nh1);
845  CHECK (nh1 != rec2); CHECK (rec2 != nh1);
846  CHECK (nh1 != ref1); CHECK (ref1 != nh1);
847  CHECK (nh1 != ref2); CHECK (ref2 != nh1);
848 
849  CHECK (nh2 != rec1); CHECK (rec1 != nh2);
850  CHECK (nh2 != rec2); CHECK (rec2 != nh2);
851  CHECK (nh2 != ref1); CHECK (ref1 != nh2);
852  CHECK (nh2 != ref2); CHECK (ref2 != nh2);
853 
854  CHECK (rec1 != rec2); CHECK (rec2 != rec1);
855  CHECK (ref1 != ref2); CHECK (ref2 != ref1);
856 
857  // NOTE: special handling for record references…
858  CHECK (rec1 == ref1); CHECK (ref1 == rec1);
859  CHECK (rec1 != ref2); CHECK (ref2 != rec1);
860 
861  CHECK (rec2 != ref1); CHECK (ref1 != rec2);
862  CHECK (rec2 == ref2); CHECK (ref2 == rec2);
863 
864 
865 
866  /* ----- equivalence match ----- */
867 
868  // equivalence as object // equivalence on ID match // contained value equality
869  CHECK (ni1 .matches(ni1 )); CHECK (ni1 .matches(ni1 .idi)); CHECK (ni1 .matches(i1 ));
870  CHECK (ni2 .matches(ni2 )); CHECK (ni2 .matches(ni2 .idi)); CHECK (ni2 .matches(i2 ));
871  CHECK (nl1 .matches(nl1 )); CHECK (nl1 .matches(nl1 .idi)); CHECK (nl1 .matches(l1 ));
872  CHECK (nl2 .matches(nl2 )); CHECK (nl2 .matches(nl2 .idi)); CHECK (nl2 .matches(l2 ));
873  CHECK (nr1 .matches(nr1 )); CHECK (nr1 .matches(nr1 .idi)); CHECK (nr1 .matches(r1 ));
874  CHECK (nr2 .matches(nr2 )); CHECK (nr2 .matches(nr2 .idi)); CHECK (nr2 .matches(r2 ));
875  CHECK (nd1 .matches(nd1 )); CHECK (nd1 .matches(nd1 .idi)); CHECK (nd1 .matches(d1 ));
876  CHECK (nd2 .matches(nd2 )); CHECK (nd2 .matches(nd2 .idi)); CHECK (nd2 .matches(d2 ));
877  CHECK (nc1 .matches(nc1 )); CHECK (nc1 .matches(nc1 .idi)); CHECK (nc1 .matches(c1 ));
878  CHECK (nc2 .matches(nc2 )); CHECK (nc2 .matches(nc2 .idi)); CHECK (nc2 .matches(c2 ));
879  CHECK (nb1 .matches(nb1 )); CHECK (nb1 .matches(nb1 .idi)); CHECK (nb1 .matches(b1 ));
880  CHECK (nb2 .matches(nb2 )); CHECK (nb2 .matches(nb2 .idi)); CHECK (nb2 .matches(b2 ));
881  CHECK (ns1 .matches(ns1 )); CHECK (ns1 .matches(ns1 .idi)); CHECK (ns1 .matches(s1 ));
882  CHECK (ns2 .matches(ns2 )); CHECK (ns2 .matches(ns2 .idi)); CHECK (ns2 .matches(s2 ));
883  CHECK (nt1 .matches(nt1 )); CHECK (nt1 .matches(nt1 .idi)); CHECK (nt1 .matches(t1 ));
884  CHECK (nt2 .matches(nt2 )); CHECK (nt2 .matches(nt2 .idi)); CHECK (nt2 .matches(t2 ));
885  CHECK (nto1.matches(nto1)); CHECK (nto1.matches(nto1.idi)); CHECK (nto1.matches(to1));
886  CHECK (nto2.matches(nto2)); CHECK (nto2.matches(nto2.idi)); CHECK (nto2.matches(to2));
887  CHECK (ntd1.matches(ntd1)); CHECK (ntd1.matches(ntd1.idi)); CHECK (ntd1.matches(td1));
888  CHECK (ntd2.matches(ntd2)); CHECK (ntd2.matches(ntd2.idi)); CHECK (ntd2.matches(td2));
889  CHECK (nts1.matches(nts1)); CHECK (nts1.matches(nts1.idi)); CHECK (nts1.matches(ts1));
890  CHECK (nts2.matches(nts2)); CHECK (nts2.matches(nts2.idi)); CHECK (nts2.matches(ts2));
891  CHECK (nh1 .matches(nh1 )); CHECK (nh1 .matches(nh1 .idi)); CHECK (nh1 .matches(h1 ));
892  CHECK (nh2 .matches(nh2 )); CHECK (nh2 .matches(nh2 .idi)); CHECK (nh2 .matches(h2 ));
893  CHECK (rec1.matches(rec1)); CHECK (rec1.matches(rec1.idi)); CHECK (rec1.matches(spam1));
894  CHECK (rec2.matches(rec2)); CHECK (rec2.matches(rec2.idi)); CHECK (rec2.matches(spam2));
895  CHECK (ref1.matches(ref1)); CHECK (ref1.matches(ref1.idi)); CHECK (ref1.matches(recRef1));
896  CHECK (ref2.matches(ref2)); CHECK (ref2.matches(ref2.idi)); CHECK (ref2.matches(recRef2));
897 
898  // cross-match on equivalent payload data --------
899  CHECK (nl1.matches(i1)); CHECK (nr1.matches(i1)); CHECK (nd1.matches(i1)); CHECK (nc1.matches(i1));
900  CHECK (ni1.matches(l1)); CHECK (nr1.matches(l1)); CHECK (nd1.matches(l1)); CHECK (nc1.matches(l1));
901  CHECK (ni1.matches(r1)); CHECK (nl1.matches(r1)); CHECK (nd1.matches(r1)); CHECK (nc1.matches(r1));
902  CHECK (ni1.matches(d1)); CHECK (nl1.matches(d1)); CHECK (nr1.matches(d1)); CHECK (nc1.matches(d1));
903  CHECK (ni1.matches(c1)); CHECK (nl1.matches(c1)); CHECK (nr1.matches(c1)); CHECK (nd1.matches(c1));
904 
905  CHECK (nl2.matches(i2)); CHECK (nr2.matches(i2)); CHECK (nd2.matches(i2)); CHECK (nc2.matches(i2));
906  CHECK (ni2.matches(l2)); CHECK (nr2.matches(l2)); CHECK (nd2.matches(l2)); CHECK (nc2.matches(l2));
907  CHECK (ni2.matches(r2)); CHECK (nl2.matches(r2)); CHECK (nd2.matches(r2)); CHECK (nc2.matches(r2));
908  CHECK (ni2.matches(d2)); CHECK (nl2.matches(d2)); CHECK (nr2.matches(d2)); CHECK (nc2.matches(d2));
909  CHECK (ni2.matches(c2)); CHECK (nl2.matches(c2)); CHECK (nr2.matches(c2)); CHECK (nd2.matches(c2));
910 
911  CHECK (nto1.matches(t1 )); CHECK (nts1.matches(t1 ));
912  CHECK (nt1.matches(to1)); CHECK (nts1.matches(to1));
913  CHECK (nt1.matches(ts1)); CHECK (nto1.matches(ts1));
914 
915  CHECK (nto2.matches(t2 )); CHECK (nts2.matches(t2 ));
916  CHECK (nt2.matches(to2)); CHECK (nts2.matches(to2));
917  CHECK (nt2.matches(ts2)); CHECK (nto2.matches(ts2));
918 
919  CHECK (ns1.matches(""));
920  CHECK (ns2.matches("↯"));
921  CHECK (nc1.matches("@"));
922  CHECK (nc2.matches("~"));
923 
924  // match due to references sharing the target's ID
925  CHECK (rec1.matches(ref1.idi));
926  CHECK (ref1.matches(rec1.idi));
927  CHECK (rec2.matches(ref2.idi));
928  CHECK (ref2.matches(rec2.idi));
929 
930  // some negative cases...
931  CHECK (!ni1.matches(i2)); CHECK (!ni2.matches(i1));
932  CHECK (!ni1.matches(l2)); CHECK (!ni2.matches(l1));
933  CHECK (!ni1.matches(r2)); CHECK (!ni2.matches(r1));
934  CHECK (!ni1.matches(d2)); CHECK (!ni2.matches(d1));
935  CHECK (!ni1.matches(c2)); CHECK (!ni2.matches(c1));
936 
937  CHECK (!nd1.matches(i2)); CHECK (!nd2.matches(i1));
938  CHECK (!nd1.matches(l2)); CHECK (!nd2.matches(l1));
939  CHECK (!nd1.matches(r2)); CHECK (!nd2.matches(r1));
940  CHECK (!nd1.matches(d2)); CHECK (!nd2.matches(d1));
941  CHECK (!nd1.matches(c2)); CHECK (!nd2.matches(c1));
942 
943  // string match is literal
944  CHECK (!ns1.matches(" "));
945  CHECK (!ns2.matches("↯ "));
946 
947  GenNode copy(ni1);
948  CHECK (copy == ni1);
949 
950  copy.data = 2*i1;
951  CHECK (copy != ni1);
952  CHECK (copy.idi == ni1.idi);
953  CHECK (not copy.data.matchData(ni1.data));
954 
955  // NOTE: "match" operation is shallow on records
956  CHECK (copy.matches(ni1)); CHECK (ni1.matches(copy));
957  }
958 
959 
966  void
968  {
969  GenNode n1(42);
970  GenNode n2 = MakeRec().type("spam").genNode("eggs");
971  GenNode n3 = MakeRec().attrib("Ψ", Time(3,2,1)).genNode();
972 
973  CHECK (not n1.isNamed());
974  CHECK ( n2.isNamed());
975  CHECK (not n3.isNamed());
976 
977  CHECK (not n1.isNested());
978  CHECK ( n2.isNested());
979  CHECK ( n3.isNested());
980 
981  CHECK (n1.data.recordType() == util::BOTTOM_INDICATOR);
982  CHECK (n2.data.recordType() == "spam" );
983  CHECK (n3.data.recordType() == Rec::TYPE_NIL );
984 
985  CHECK (not n1.hasAttribute("baked beans"));
986  CHECK (not n2.hasAttribute("baked beans"));
987  CHECK (not n3.hasAttribute("baked beans"));
988 
989  CHECK (not n1.hasAttribute("Ψ"));
990  CHECK (not n2.hasAttribute("Ψ"));
991  CHECK ( n3.hasAttribute("Ψ"));
992 
993  CHECK (not n1.retrieveAttribute<float>("Ψ"));
994  CHECK (not n2.retrieveAttribute<float>("Ψ"));
995  CHECK (not n3.retrieveAttribute<float>("Ψ"));
996 
997  CHECK (not n1.retrieveAttribute<Time>("Ψ"));
998  CHECK (not n2.retrieveAttribute<Time>("Ψ"));
999  CHECK ( n3.retrieveAttribute<Time>("Ψ"));
1000 
1001  CHECK (Time(3,2,1) == *n3.retrieveAttribute<Time>("Ψ"));
1002  CHECK (std::nullopt == n2.retrieveAttribute<Time>("Ψ"));
1003 
1004  CHECK (not n1.hasChildren()); // a simple value GenNode is not nested and thus can not have children
1005  CHECK (not n2.hasChildren()); // n2 is nested (holds a Rec), but has an empty scope
1006  CHECK (not n3.hasChildren()); // n3 is likewise nested, but holds only attributes, no children
1007  }
1008  };
1009 
1010 
1012  LAUNCHER (GenNode_test, "unit common");
1013 
1014 
1015 
1016 }}} // namespace lib::diff::test
Automatically use custom string conversion in C++ stream output.
Constructor for a specially crafted &#39;ref GenNode&#39;.
Definition: gen-node.hpp:849
Definition: run.hpp:49
typed symbolic and hash ID for asset-like position accounting.
Definition: entry-id.hpp:135
static const Ref CHILD
symbolic ID ref "_CHILD_"
Definition: gen-node.hpp:873
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
string renderCompact(Rec const &rec)
compact textual representation of a Record<GenNode> (»object«).
Definition: gen-node.cpp:299
Implementation namespace for support and library code.
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:308
Special collection to represent object-like data.
static const Ref END
symbolic ID ref "_END_"
Definition: gen-node.hpp:871
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
wrapped record reference.
Definition: record.hpp:620
Utilities for quantisation (grid alignment) and comparisons.
Generic building block for tree shaped (meta)data structures.
boost::rational< int64_t > FSecs
rational representation of fractional seconds
Definition: timevalue.hpp:229
A collection of frequently used helper functions to support unit testing.
std::optional< X > retrieveAttribute(string key) const
mismatch tolerant convenience shortcut to peek into the attributes of a nested Record ...
Definition: gen-node.hpp:809
Hash implementation based on a lumiera unique object id (LUID) When invoking the default ctor...
bool matches(GenNode const &o) const
Definition: gen-node.hpp:360
static const Ref ATTRIBS
symbolic ID ref "_ATTRIBS_"
Definition: gen-node.hpp:874
Offset measures a distance in time.
Definition: timevalue.hpp:367
string recordType() const
peek into the type field of a nested Record<GenNode>
Definition: gen-node.hpp:769
Duration is the internal Lumiera time metric.
Definition: timevalue.hpp:477
lib::time::Time randTime()
create a random but not insane Time value between 1s ...
bool almostEqual(double d1, double d2, unsigned int ulp=2)
epsilon comparison of doubles.
Definition: util-quant.hpp:152
A time interval anchored at a specific point in time.
Definition: timevalue.hpp:582
a family of time value like entities and their relationships.
object-like record of data.
Definition: record.hpp:150
static const Ref THIS
symbolic ID ref "_THIS_"
Definition: gen-node.hpp:872
ElementBoxWidget::Config::Qualifier name(string id)
define the name-ID displayed in the caption
generic data element node within a tree
Definition: gen-node.hpp:231
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, bypassing any custom comparison operators.
Definition: util.hpp:372