Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
ui-coord-test.cpp
Go to the documentation of this file.
1/*
2 UICoord(Test) - properties of topological UI coordinate specifications
3
4 Copyright (C)
5 2017, 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"
22#include "lib/format-util.hpp"
23#include "lib/util.hpp"
24
25#include <string>
26
27
28using std::string;
29using lib::Symbol;
30using util::isnil;
31using util::join;
32
33
34
35namespace stage {
36namespace interact {
37namespace test {
38
39 using LERR_(INDEX_BOUNDS);
40 using LERR_(LOGIC);
41
42
43
44
45 /******************************************************************************/
61 class UICoord_test : public Test
62 {
63
64 virtual void
73
74
75 void
77 {
78 UICoord undef;
79 CHECK (isnil (undef));
80
81 UICoord uic{"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω"};
82 CHECK (not isnil (uic));
83 CHECK (8 == uic.size());
84 // coordinate sequence is iterable
85 CHECK ("Γ-Δ-Θ-Ξ-Σ-Ψ-Φ-Ω" == join(uic,"-"));
86
87 // indexed access
88 CHECK ("Γ" == uic[UIC_WINDOW]); // window spec to anchor the path
89 CHECK ("Δ" == uic[UIC_PERSP]); // the perspective used within that window
90 CHECK ("Θ" == uic[UIC_PANEL]); // the docking panel within the window
91 CHECK ("Ξ" == uic[UIC_VIEW]); // the view residing in the docking panel
92 CHECK ("Σ" == uic[UIC_TAB]); // the tab or element group within the view
93 CHECK ("Ψ" == uic[UIC_PATH]); // a path sequence...
94 CHECK ("Φ" == uic[UIC_PATH+1]); // ...descending through local widgets
95 CHECK ("Ω" == uic[UIC_PATH+2]);
96
97 // sequential access to the path part
98 CHECK ("Ψ-Φ-Ω" == join(uic.pathSeq(),"-"));
99 CHECK ("Ψ/Φ/Ω" == uic.getPath());
100
101 // iteration of complete coordinates matches index order
102 uint i=0;
103 for (UICoord::iterator ii = uic.begin(); ii; ++ii, ++i)
104 CHECK (uic[i] == *ii);
105 CHECK (8 == i);
106
107 VERIFY_ERROR (INDEX_BOUNDS, uic[8]);
108
109 // string representation
110 CHECK ("UI:Γ[Δ]-Θ.Ξ.Σ/Ψ/Φ/Ω" == string(uic));
111 CHECK ( "Γ[Δ]-Θ.Ξ.Σ" == uic.getComp());
112 CHECK ( "Ψ/Φ/Ω" == uic.getPath());
113
114 // new value can be assigned, but not altered in place
115 uic = UICoord{nullptr,nullptr,"Θ",nullptr,"Σ",nullptr,"Φ"};
116 CHECK (7 == uic.size());
117
118 // representation is trimmed and filled
119 CHECK ("UI:?-Θ.*.Σ/*/Φ" == string(uic));
120 CHECK (Symbol::EMPTY == uic[UIC_WINDOW]);
121 CHECK (Symbol::EMPTY == uic[UIC_PERSP]);
122 CHECK ("Θ" == uic[UIC_PANEL]);
123 CHECK ("*" == uic[UIC_VIEW]);
124 CHECK ("Σ" == uic[UIC_TAB]);
125 CHECK ("*" == uic[UIC_PATH]);
126 CHECK ("Φ" == uic[UIC_PATH+1]);
127 VERIFY_ERROR (INDEX_BOUNDS, uic[UIC_PATH+2]);
128 }
129
130
131 void
133 {
134 UICoord uic1 = UICoord::window("window");
135 UICoord uic2 = uic1.view("view"); // Note: does not alter uic1
136 CHECK ("UI:window" == string(uic1));
137 CHECK ("UI:window[*]-*.view" == string(uic2));
138 CHECK (1 == uic1.size());
139 CHECK (4 == uic2.size());
140
141 // fault-tolerant accessors for the generic part
142 CHECK ("window" == uic1.getWindow());
143 CHECK ("window" == uic2.getWindow());
144 CHECK ("" == uic1.getPersp());
145 CHECK ("*" == uic2.getPersp());
146 CHECK ("" == uic1.getPanel());
147 CHECK ("*" == uic2.getPanel());
148 CHECK ("" == uic1.getView());
149 CHECK ("view" == uic2.getView());
150 CHECK ("" == uic1.getTab());
151 CHECK ("" == uic2.getTab());
152 CHECK ("" == uic1.getPath());
153 CHECK ("" == uic2.getPath());
154 CHECK ("window" == uic1.getComp());
155 CHECK ("window[*]-*.view" == uic2.getComp());
156
157 VERIFY_ERROR (INDEX_BOUNDS, uic1[UIC_PERSP]);
158 VERIFY_ERROR (INDEX_BOUNDS, uic2[UIC_TAB]);
159
160 // partial (incomplete) coordinate spec
161 UICoord uic3 = UICoord().view("view");
162 CHECK (4 == uic3.size());
163 CHECK ("UI:?.view" == string(uic3));
164 CHECK ("" == uic3.getWindow());
165 CHECK ("" == uic3.getPersp());
166 CHECK ("" == uic3.getPanel());
167 CHECK ("view" == uic3.getView());
168
169 UICoord uic4 = uic3.persp("perspective");
170 CHECK (4 == uic4.size());
171 CHECK ("UI:?[perspective]-*.view" == string(uic4));
172
173 uic4 = uic3.append("tab");
174 CHECK (5 == uic4.size());
175 CHECK ("UI:?.view.tab" == string(uic4));
176 uic4 = uic3.prepend("panel");
177 CHECK (4 == uic4.size());
178 CHECK ("UI:?-panel.view" == string(uic4));
179 uic4 = uic4.tab(555);
180 CHECK (5 == uic4.size());
181 CHECK ("UI:?-panel.view.#555" == string(uic4));
182 VERIFY_ERROR(LOGIC, uic1.prepend("root"));
183
184 // the builder may shorten/truncate the path
185 uic4 = uic4.append("α/β/γ/δ/ε/λ").truncateTo(9);
186 CHECK (9 == uic4.size());
187 CHECK ("UI:?-panel.view.#555/α/β/γ/δ" == string(uic4));
188 uic4 = uic4.path("ε/ε/ε/ε/ε").truncateTo(3);
189 CHECK (3 == uic4.size());
190 CHECK ("UI:?-panel" == string(uic4));
191 uic4 = uic4.append("something").truncateTo(2);
192 CHECK (0 == uic4.size()); // NOTE: normalisation detected absence of any remaining content
193 CHECK ("UI:?" == string(uic4));
194 }
195
196
197 void
199 {
200 UICoord uic;
201 CHECK ("UI:?" == string(uic));
202 CHECK ("" == uic.getComp());
203 CHECK ("" == uic.getPath());
204
205 uic = uic.path("ἁρχή");
206 CHECK ("UI:?/ἁρχή" == string(uic));
207 CHECK ("" == uic.getComp());
208 CHECK ("ἁρχή" == uic.getPath());
209
210 uic = uic.path("α/β/γ");
211 CHECK ("UI:?/α/β/γ" == string(uic));
212 CHECK ("" == uic.getComp());
213 CHECK ("α/β/γ" == uic.getPath());
214
215 uic = uic.append("δ");
216 CHECK ("UI:?/α/β/γ/δ" == string(uic));
217 CHECK ("" == uic.getComp());
218 CHECK ("α/β/γ/δ" == uic.getPath());
219
220 uic = uic.append("");
221 CHECK ("UI:?/α/β/γ/δ" == string(uic));
222 CHECK ("" == uic.getComp());
223 CHECK ("α/β/γ/δ" == uic.getPath());
224
225 uic = uic.append("ε/λ/ον");
226 CHECK ("UI:?/α/β/γ/δ/ε/λ/ον" == string(uic));
227 CHECK ("" == uic.getComp());
228 CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath());
229
230 // note: we built a partially empty path array...
231 CHECK (12 == uic.size());
232 CHECK (Symbol::EMPTY == uic.getView());
233 CHECK (Symbol::EMPTY == uic.getTab());
234 CHECK (Symbol::EMPTY == uic[UIC_WINDOW]);
235 CHECK (Symbol::EMPTY == uic[UIC_PERSP]);
236 CHECK (Symbol::EMPTY == uic[UIC_PANEL]);
237 CHECK (Symbol::EMPTY == uic[UIC_VIEW]);
238 CHECK (Symbol::EMPTY == uic[UIC_TAB]);
239 CHECK ("α" == uic[UIC_PATH]);
240 CHECK ("β" == uic[UIC_PATH+1]);
241 CHECK ("γ" == uic[UIC_PATH+2]);
242 CHECK ("δ" == uic[UIC_PATH+3]);
243 CHECK ("ε" == uic[UIC_PATH+4]);
244 CHECK ("λ" == uic[UIC_PATH+5]);
245 CHECK ("ον" == uic[UIC_PATH+6]);
246
247 uic = uic.prepend("ειδος");
248 CHECK ("UI:?.ειδος/α/β/γ/δ/ε/λ/ον" == string(uic));
249 CHECK ("?.ειδος" == uic.getComp());
250 CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath());
251 CHECK (12 == uic.size());
252
253 uic = uic.tab("");
254 CHECK ("UI:?/α/β/γ/δ/ε/λ/ον" == string(uic));
255 CHECK ("" == uic.getComp());
256 CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath());
257
258 uic = uic.view("ειδος");
259 CHECK ("UI:?.ειδος.*/α/β/γ/δ/ε/λ/ον" == string(uic));
260 CHECK ("?.ειδος.*" == uic.getComp());
261 CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath());
262
263 uic = uic.prepend("panel");
264 CHECK ("UI:?-panel.ειδος.*/α/β/γ/δ/ε/λ/ον" == string(uic));
265 CHECK ("?-panel.ειδος.*" == uic.getComp());
266 CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath());
267
268 uic = uic.view(nullptr);
269 CHECK ("UI:?-panel.*.*/α/β/γ/δ/ε/λ/ον" == string(uic));
270 CHECK ("?-panel.*.*" == uic.getComp());
271 CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath());
272
273 uic = uic.tab(8);
274 CHECK ("UI:?-panel.*.#8/α/β/γ/δ/ε/λ/ον" == string(uic));
275 CHECK ("?-panel.*.#8" == uic.getComp());
276 CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath());
277
278 uic = uic.noTab();
279 CHECK ("UI:?-panel.*/α/β/γ/δ/ε/λ/ον" == string(uic));
280 CHECK ("?-panel.*" == uic.getComp());
281 CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath());
282
283 uic = uic.tab(" ");
284 CHECK ("UI:?-panel.*. /α/β/γ/δ/ε/λ/ον" == string(uic));
285 CHECK ("?-panel.*. " == uic.getComp());
286 CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath());
287
288 uic = uic.prepend("perspective");
289 CHECK ("UI:?[perspective]-panel.*. /α/β/γ/δ/ε/λ/ον" == string(uic));
290 CHECK ("?[perspective]-panel.*. " == uic.getComp());
291 CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath());
292
293 uic = uic.prepend("win");
294 CHECK ("UI:win[perspective]-panel.*. /α/β/γ/δ/ε/λ/ον" == string(uic));
295 CHECK ("win[perspective]-panel.*. " == uic.getComp());
296 CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath());
297
298 uic = uic.persp("");
299 CHECK ("UI:win[*]-panel.*. /α/β/γ/δ/ε/λ/ον" == string(uic));
300 CHECK ("win[*]-panel.*. " == uic.getComp());
301 CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath());
302 CHECK (12 == uic.size());
303
304 uic = uic.path(" ");
305 CHECK ("UI:win[*]-panel.*. / " == string(uic));
306 CHECK ("win[*]-panel.*. " == uic.getComp());
307 CHECK (" " == uic.getPath());
308 CHECK (6 == uic.size());
309 CHECK (" " == uic[UIC_PATH]);
310 VERIFY_ERROR (INDEX_BOUNDS, uic[UIC_PATH+1]);
311
312 uic = uic.path(nullptr);
313 CHECK ("UI:win[*]-panel.*. " == string(uic));
314 CHECK ("win[*]-panel.*. " == uic.getComp());
315 CHECK ("" == uic.getPath());
316 CHECK (5 == uic.size());
317 VERIFY_ERROR (INDEX_BOUNDS, uic[UIC_PATH]);
318
319 uic = uic.append(nullptr);
320 CHECK ("UI:win[*]-panel.*. " == string(uic));
321 CHECK ("win[*]-panel.*. " == uic.getComp());
322 CHECK ("" == uic.getPath());
323 CHECK (5 == uic.size());
324
325 uic = uic.append("*");
326 CHECK ("UI:win[*]-panel.*. " == string(uic));
327 CHECK ("win[*]-panel.*. " == uic.getComp());
328 CHECK ("" == uic.getPath());
329 CHECK (5 == uic.size());
330
331 uic = uic.append("**");
332 CHECK ("UI:win[*]-panel.*. /**" == string(uic));
333 CHECK ("win[*]-panel.*. " == uic.getComp());
334 CHECK ("**" == uic.getPath());
335 CHECK ("**" == uic[UIC_PATH]);
336 CHECK (6 == uic.size());
337
338 uic = uic.tab("");
339 CHECK ("UI:win[*]-panel.*.*/**" == string(uic));
340 CHECK ("win[*]-panel.*.*" == uic.getComp());
341 CHECK ("**" == uic.getPath());
342 CHECK (6 == uic.size());
343
344 uic = uic.path("");
345 CHECK ("UI:win[*]-panel" == string(uic));
346 CHECK ("win[*]-panel" == uic.getComp());
347 CHECK ("" == uic.getPath());
348 CHECK (3 == uic.size());
349 }
350
351
352 void
354 {
355 UICoord u1 {"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ" };
356 UICoord u11{"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω"};
357 UICoord u2 {"Γ","Δ","Θ","Σ","Ξ","Ψ","Φ","Ω"};
358
359 UICoord u1c{u1};
360
361 CHECK (u1 == u1 );
362 CHECK (u1 != u11);
363 CHECK (u2 != u1 );
364 CHECK (u2 != u11);
365
366 CHECK (u1 == u1c);
367 CHECK (u1 == UICoord("Γ","Δ","Θ","Ξ","Σ","Ψ","Φ" ));
368 CHECK (u1 == UICoord("Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","" ));
369 CHECK (UICoord("Γ","Δ","Θ","Ξ","Σ","Ψ","Φ",nullptr) == UICoord("Γ","Δ","Θ","Ξ","Σ","Ψ","Φ"));
370
371 CHECK (u11 == u1.path("Ψ/Φ/Ω//"));
372 CHECK (u11 != u1.path("//Ψ/Φ/Ω"));
373
374 CHECK (u1 > u11);
375 CHECK (u11 < u1 );
376 CHECK (u1 >= u1 );
377 CHECK (u1 >= u11);
378 CHECK (not (u1 < u11));
379 CHECK (not (u1 < u1 ));
380 CHECK (not (u1 < u2 ));
381 CHECK (not (u11 < u2 ));
382
383 // expansion of jokers from parent path is tolerated
384 CHECK (u11 < u1.view("*").window(NULL));
385 }
386
387
388 void
390 {
391 UICoord nil;
392 UICoord u1 { "", "", "","Ξ","Σ"};
393 UICoord u2 {"Γ","*","Θ","Ξ","Σ"};
394 UICoord u3 {"Γ","Δ","Θ","Ξ","Σ"};
395
396 CHECK (not u1.isComplete());
397 CHECK (not u1.isExplicit());
398
399 CHECK ( u2.isComplete());
400 CHECK (not u2.isExplicit());
401
402 CHECK ( u3.isComplete());
403 CHECK ( u3.isExplicit());
404
405 CHECK (u1.isIncomplete());
406 CHECK (not nil.isExplicit());
407 CHECK (not nil.isComplete());
408 CHECK (not nil.isIncomplete()); // note fine point
409
410 CHECK (not u1.isPresent(UIC_WINDOW));
411 CHECK (not u1.isPresent(UIC_PERSP));
412 CHECK (not u1.isPresent(UIC_PANEL));
413 CHECK ( u1.isPresent(UIC_VIEW));
414 CHECK ( u1.isPresent(UIC_TAB));
415 CHECK (not u1.isPresent(UIC_PATH));
416 CHECK (not u1.isPresent(UIC_PATH+1));
417
418 CHECK ( u2.isPresent(UIC_WINDOW));
419 CHECK (not u2.isPresent(UIC_PERSP));
420 CHECK ( u2.isPresent(UIC_PANEL));
421 CHECK ( u2.isPresent(UIC_VIEW));
422 CHECK ( u2.isPresent(UIC_TAB));
423 CHECK (not u2.isPresent(UIC_PATH));
424 CHECK (not u2.isPresent(UIC_PATH+1));
425
426 CHECK ( u3.isPresent(UIC_WINDOW));
427 CHECK ( u3.isPresent(UIC_PERSP));
428 CHECK ( u3.isPresent(UIC_PANEL));
429 CHECK ( u3.isPresent(UIC_VIEW));
430 CHECK ( u3.isPresent(UIC_TAB));
431 CHECK (not u3.isPresent(UIC_PATH));
432 CHECK (not u3.isPresent(UIC_PATH+1));
433
434 CHECK (not u2.isWildcard(UIC_WINDOW));
435 CHECK ( u2.isWildcard(UIC_PERSP));
436 CHECK (not u2.isWildcard(UIC_PANEL));
437 CHECK (not u2.isWildcard(UIC_VIEW));
438 CHECK (not u2.isWildcard(UIC_TAB));
439 CHECK (not u2.isWildcard(UIC_PATH));
440 CHECK (not u2.isWildcard(UIC_PATH+1));
441 }
442 };
443
444
446 LAUNCHER (UICoord_test, "unit stage");
447
448
449}}} // namespace stage::interact::test
Adapter for building an implementation of the »Lumiera Forward Iterator« concept.
size_t size() const
Token or Atom with distinct identity.
Definition symbol.hpp:120
static Symbol EMPTY
Definition symbol.hpp:123
Builder && truncateTo(size_t depth)
possibly shorten this path specification to a limited depth
Definition ui-coord.hpp:625
Describe a location within the UI through structural/topological coordinates.
Definition ui-coord.hpp:131
string getComp() const
Definition ui-coord.hpp:304
Literal getView() const
Definition ui-coord.hpp:193
Literal getPanel() const
Definition ui-coord.hpp:192
Literal getTab() const
Definition ui-coord.hpp:194
Builder noTab() const
Definition ui-coord.hpp:726
static Builder window(Literal windowID)
Builder: start definition of UI-Coordinates rooted in given window.
Definition ui-coord.hpp:683
Builder tab(Literal tabID) const
Definition ui-coord.hpp:714
Builder path(Literal pathDefinition) const
convenience builder function so set a full path definition
Definition ui-coord.hpp:737
Builder persp(Literal perspectiveID) const
Definition ui-coord.hpp:696
Literal getWindow() const
Definition ui-coord.hpp:190
string getPath() const
Definition ui-coord.hpp:345
bool isIncomplete() const
Definition ui-coord.hpp:206
Literal getPersp() const
Definition ui-coord.hpp:191
Builder append(Literal elmID) const
Definition ui-coord.hpp:743
Builder prepend(Literal elmID) const
Definition ui-coord.hpp:749
Builder view(Literal viewID) const
Definition ui-coord.hpp:708
#define LERR_(_NAME_)
Definition error.hpp:45
Collection of small helpers and convenience shortcuts for diagnostics & formatting.
unsigned int uint
Definition integral.hpp:29
return NULL
Definition llist.h:586
Lumiera GTK UI implementation root.
Definition guifacade.cpp:37
Test runner and basic definitions for tests.
string join(COLL &&coll, string const &delim=", ")
enumerate a collection's contents, separated by delimiter.
bool isnil(lib::time::Duration const &dur)
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 topological addressing scheme to designate structural locations within the UI.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...