Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
query-focus-stack-test.cpp
Go to the documentation of this file.
1/*
2 QueryFocusStack(Test) - verify the stack of focus path frames
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/util.hpp"
25
26
27namespace steam {
28namespace mobject {
29namespace session {
30namespace test {
31
32 using util::isnil;
34 using LERR_(INVALID_SCOPE);
35
36
37 /***********************************************************************/
51 class QueryFocusStack_test : public Test
52 {
53
54 virtual void
55 run (Arg)
56 {
57 // Prepare an (test)Index and
58 // set up dummy session contents
59 PPIdx index = build_testScopes();
60
65 clear();
66 }
67
68
69 void
71 {
72 QueryFocusStack stack;
73
74 CHECK (!isnil (stack));
75 CHECK (!isnil (stack.top()));
76 CHECK (stack.top().isRoot());
77 }
78
79
80 void
82 {
83 QueryFocusStack stack;
84 PMO& startPoint = retrieve_startElm();
85
86 ScopePath& firstFrame = stack.top(); // remember for later
87 intrusive_ptr_add_ref (&firstFrame);
88 stack.top().navigate(startPoint);
89 stack.top().moveUp();
90 CHECK (Scope(startPoint).getParent() == stack.top().getLeaf());
91 CHECK (1 == stack.size());
92
93 // now open a second path frame, pushing aside the initial one
94 ScopePath& secondFrame = stack.push(startPoint);
95 intrusive_ptr_add_ref (&secondFrame);
96 CHECK (2 == stack.size());
97 CHECK (secondFrame == stack.top());
98 CHECK (secondFrame.getLeaf() == startPoint);
99 CHECK (secondFrame.getLeaf() != firstFrame.getLeaf());
100
101 // can still reach and manipulate the ref-count of the first frame
102 intrusive_ptr_add_ref (&firstFrame);
103 CHECK (2 == firstFrame.ref_count());
104 CHECK (1 == secondFrame.ref_count());
105
106 // can use/navigate the stack top frame
107 stack.top().goRoot();
108 CHECK (!stack.top()); // now indeed at root == no path
109 CHECK (secondFrame.getLeaf().isRoot());
110 CHECK (secondFrame == stack.top());
111
112 // now drop back to the first frame:
113 CHECK (1 == secondFrame.ref_count());
114 intrusive_ptr_release (&secondFrame);
115 CHECK (0 == secondFrame.ref_count());
116 stack.pop_unused();
117 CHECK (1 == stack.size());
118 CHECK (firstFrame == stack.top());
119
120 // ...still pointing at the previous location
121 CHECK (Scope(startPoint).getParent() == stack.top().getLeaf());
122 CHECK (2 == firstFrame.ref_count());
123 }
124
125
126 void
128 {
129 QueryFocusStack stack;
130 PMO& startPoint = retrieve_startElm();
131
132 ScopePath& firstFrame = stack.top(); // remember for later
133 stack.top().navigate(startPoint);
134 CHECK (1 == stack.size());
135 intrusive_ptr_add_ref (&firstFrame);
136
137 // now open two new frames, but don't add ref-counts on them
138 ScopePath& secondFrame = stack.push(startPoint);
139 ScopePath& thirdFrame = stack.push(startPoint);
140 CHECK (3 == stack.size());
141 CHECK (1 == firstFrame.ref_count());
142 CHECK (0 == secondFrame.ref_count());
143 CHECK (0 == thirdFrame.ref_count());
144
145 // any ref to top detects the non-referred-to state (by ref count==0)
146 // and will automatically pop and clean up...
147 ScopePath& newTop = stack.top();
148 CHECK (1 == stack.size());
149 CHECK (firstFrame == stack.top());
150 CHECK (isSameObject(newTop, firstFrame));
151 CHECK (stack.top().getLeaf() == startPoint);
152
153 // second exercise: a pop_unused may even completely empty the stack
154 ScopePath& anotherFrame = stack.push(startPoint);
155 CHECK (0 == anotherFrame.ref_count());
156 CHECK (1 == firstFrame.ref_count());
157 intrusive_ptr_release (&firstFrame);
158 CHECK (0 == firstFrame.ref_count());
159 CHECK (firstFrame.getLeaf() == startPoint);
160
161 stack.pop_unused();
162 CHECK (1 == stack.size());
163 // Note: don't use previously taken pointers
164 // or references anymore, after the stack
165 // triggered a cleanup!
166 ScopePath& anotherFrame2 = stack.top();
167 CHECK (0 == anotherFrame2.ref_count());
168 CHECK (anotherFrame2.getLeaf().isRoot());
169 anotherFrame2.navigate(startPoint);
170 CHECK (anotherFrame2.getLeaf() == startPoint);
171
172 stack.top();
173 CHECK (1 == stack.size());
174 CHECK (stack.top().getLeaf().isRoot());
175 }
176
177
178 void
180 {
181 QueryFocusStack stack;
182 PMO& startPoint = retrieve_startElm();
183
184 ScopePath& firstFrame = stack.top(); // remember for later
185 stack.top().navigate(startPoint);
186 CHECK (1 == stack.size());
187 intrusive_ptr_add_ref (&firstFrame);
188
189 ScopePath beforeInvalidNavigation = firstFrame;
190 Scope const& unrelatedScope = fabricate_invalidScope();
191
192 // try to navigate to an invalid place
193 VERIFY_ERROR (INVALID_SCOPE, stack.top().navigate (unrelatedScope) );
194 CHECK (1 == stack.size());
195 CHECK (1 == firstFrame.ref_count());
196 CHECK (stack.top().getLeaf() == startPoint);
197
198 // try to push an invalid place
199 VERIFY_ERROR (INVALID_SCOPE, stack.push (unrelatedScope) );
200 CHECK (1 == stack.size());
201 CHECK (1 == firstFrame.ref_count());
202 CHECK (stack.top().getLeaf() == startPoint);
203 }
204
205
206 void
208 {
209 QueryFocusStack stack;
210 intrusive_ptr_add_ref (&stack.top());
211 stack.top().moveUp();
212 CHECK (stack.top().empty());
213
214 PMO& startPoint = retrieve_startElm();
215 intrusive_ptr_add_ref ( & stack.push(startPoint) );
216 intrusive_ptr_add_ref ( & stack.push(startPoint) );
217 intrusive_ptr_add_ref ( & stack.push(startPoint) );
218 intrusive_ptr_add_ref ( & stack.push(startPoint) );
219 intrusive_ptr_add_ref ( & stack.push(startPoint) );
220 intrusive_ptr_add_ref ( & stack.push(startPoint) );
221 intrusive_ptr_add_ref ( & stack.push(startPoint) );
222 intrusive_ptr_add_ref ( & stack.push(startPoint) );
223 intrusive_ptr_add_ref ( & stack.push(startPoint) );
224 CHECK (10 == stack.size());
225 stack.pop_unused();
226 CHECK (10 == stack.size());
227 CHECK (1 == stack.top().ref_count());
228
229 stack.clear();
230 CHECK (1 == stack.size());
231 CHECK (!stack.top().empty());
232 CHECK (stack.top().getLeaf().isRoot());
233 CHECK (0 == stack.top().ref_count());
234 }
235
236 };
237
238
241
242
243}}}}// namespace steam::mobject::session::test
A custom stack holding ScopePath »frames«.
ScopePath & push(Scope const &)
Open a new path frame, pushing down the current frame.
void pop_unused()
investigate the stack top and discard any path frames which aren't referred anymore (as indicated by ...
Sequence of nested scopes within the high-level model.
bool empty() const
an empty path doesn't even contain a root element.
A Placement scope within the high-level-model.
Definition scope.hpp:70
#define LERR_(_NAME_)
Definition error.hpp:45
PPIdx build_testScopes()
helper for tests: create a pseudo-session (actually just a PlacementIndex), which contains some neste...
std::shared_ptr< PlacementIndex > PPIdx
PlacementMO & retrieve_startElm()
complement to the helper: retrieve one of the dummy placements which is a Placement<> and way down in...
Namespace of Session and user visible high-level objects.
Definition sequence.hpp:65
void intrusive_ptr_add_ref(ScopePath *pathFrame)
management function for boost::intrusive_ptr to be picked up by ADL
void intrusive_ptr_release(ScopePath *pathFrame)
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
bool isnil(lib::time::Duration const &dur)
Implementation facility to work with and navigate nested scopes.
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.
Unit test helper to generate deliberately wrong placement scopes.
Unit test helper to generate a system of nested test scopes.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...