Lumiera  0.pre.03
»edit your freedom«
query-focus-test.cpp
Go to the documentation of this file.
1 /*
2  QueryFocus(Test) - verify proper management of current scope
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 "lib/format-cout.hpp"
25 
26 
27 
28 namespace steam {
29 namespace mobject {
30 namespace session {
31 namespace test {
32 
33  namespace {
37  inline size_t
38  refs (QueryFocus const& focus)
39  {
40  return focus.currentPath().ref_count();
41  }
42  }
43 
44 
45 
46 
47  /*******************************************************************************/
59  : public Test
60  {
61 
62  virtual void
63  run (Arg)
64  {
65  // Prepare a (test)Session with
66  // some nested dummy placements
67  PPIdx index = build_testScopes();
68  PMO& root = index->getRoot();
69 
70  QueryFocus theFocus;
71  theFocus.reset();
72  CHECK (Scope(root) == Scope(theFocus));
73 
74  checkNavigation (theFocus);
75 
76  Scope scopePosition = Scope(theFocus);
78 
79  QueryFocus currentFocus;
80  CHECK (scopePosition == Scope(currentFocus));
81  CHECK (currentFocus == theFocus);
82  CHECK (2 == refs(currentFocus));
83  CHECK (2 == refs(theFocus));
84  }
85 
86 
87 
90  void
92  {
93  focus.reset();
94  CHECK (Scope(focus).isRoot());
95 
96  PMO& someObj = *focus.query<TestSubMO1>();
97  // by construction of the test fixture,
98  // we know this object is root -> ps2 -> ps3
99 
100  CHECK (Scope(focus).isRoot());
101  focus.shift (someObj);
102  CHECK (!Scope(focus).isRoot());
103  ScopePath path = focus.currentPath();
104  CHECK (someObj == path.getLeaf());
105  CHECK (Scope(focus).getParent().getParent().isRoot());
106 
107  focus.shift (path.getLeaf().getParent());
108  CHECK (Scope(focus) == path.getLeaf().getParent());
109  CHECK (someObj != Scope(focus));
110  CHECK (path.contains (focus.currentPath()));
111  CHECK (focus.currentPath().getLeaf().getParent().isRoot());
112 
113  // as the focus now has been moved up one level,
114  // we'll re-discover the original starting point as immediate child
115  CHECK (someObj == *focus.explore<TestSubMO1>());
116  }
117 
118 
119 
122  void
124  {
125  QueryFocus original; // automatically attaches to current stack top
126  uint num_refs = refs (original);
127  CHECK (num_refs > 1); // because the run() function also holds a ref
128 
129  QueryFocus subF = QueryFocus::push();
130  cout << subF << endl;
131  CHECK (subF == original);
132 
133  CHECK ( 1 == refs(subF) );
134  CHECK (num_refs == refs(original));
135 
136  { // temporarily creating an independent focus attached differently
137  QueryFocus subF2 = QueryFocus::push(Scope(subF).getParent());
138  CHECK (subF2 != subF);
139  CHECK (subF == original);
140  cout << subF2 << endl;
141 
143  while (ii) // drill down depth first
144  {
145  subF2.shift(*ii);
146  cout << subF2 << endl;
147  ii = subF2.explore<TestSubMO21>();
148  }
149  cout << subF2 << "<<<--discovery exhausted" << endl;
150 
151  subF2.pop(); // releasing this focus and re-attaching to what's on stack top
152  cout << subF2 << "<<<--after pop()" << endl;
153  CHECK (subF2 == subF);
154  CHECK (2 == refs(subF2)); // both are now attached to the same path
155  CHECK (2 == refs(subF));
156  }
157  // subF2 went out of scope, but no auto-pop happens (because subF is still there)
158  cout << subF << endl;
159 
160  CHECK ( 1 == refs(subF));
161  CHECK (num_refs == refs(original));
162  // when subF goes out of scope now, auto-pop will happen...
163  }
164 
165  };
166 
167 
168 
170  LAUNCHER (QueryFocus_test, "unit session");
171 
172 
173 }}}} // namespace steam::mobject::session::test
Representation of the current scope when navigating the session model.
Automatically use custom string conversion in C++ stream output.
Subclass-1 is not defined "processible", thus will always be handled as DummyMO...
Scope getParent() const
retrieve the parent scope which encloses this scope.
Definition: scope.cpp:209
Definition: run.hpp:40
PPIdx build_testScopes()
helper for tests: create a pseudo-session (actually just a PlacementIndex), which contains some neste...
Definition: test-scopes.cpp:38
Steam-Layer implementation namespace root.
QueryFocus & shift(Scope const &)
shift this QueryFocus to a container-like scope, causing it to navigate, changing the current ScopePa...
Namespace of Session and user visible high-level objects.
Definition: sequence.hpp:65
Sequence of nested scopes within the high-level model.
Definition: scope-path.hpp:126
QueryFocus & pop()
cease to use this specific reference to the current frame.
A Placement scope within the high-level-model.
Definition: scope.hpp:69
Unit test helper to generate a system of nested test scopes.
Core of the session implementation datastructure.
Simplistic test class runner.
ScopeQuery< MO >::iterator explore() const
discover any matching object contained as immediate Child within current focus.
size_t refs(QueryFocus const &focus)
Helper: extract the refcount of the current path referred by the given focus.
QueryFocus & reset()
discard any state and navigate current focus path to model root
Definition: query-focus.cpp:68
ScopePath const & currentPath() const
ScopeQuery< MO >::iterator query() const
discover depth-first any matching object within current focus.
Current focus location to use as point-of reference for contents and location discovery queries...
Adapter for building an implementation of the »Lumiera Forward Iterator« concept. ...
static QueryFocus push()
push the "current QueryFocus" aside and open a new focus frame, which starts out at the same location...