2017-10-02 18:11:21 +02:00
/*
UICoordResolver ( Test ) - resolve UI coordinates against actual topology
Copyright ( C ) Lumiera . org
2017 , Hermann Vosseler < Ichthyostega @ web . de >
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation ; either version 2 of
the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/** @file ui-coord-resolver-test.cpp
* * unit test \ ref UICoordResolver_test
*/
# include "lib/test/run.hpp"
# include "lib/test/test-helper.hpp"
# include "gui/interact/ui-coord.hpp"
# include "gui/interact/ui-coord-resolver.hpp"
2017-10-16 02:39:22 +02:00
# include "gui/interact/gen-node-location-query.hpp"
2017-10-16 01:28:49 +02:00
# include "lib/diff/gen-node.hpp"
2017-10-02 18:11:21 +02:00
# include "lib/format-cout.hpp" /////////////////////////TODO RLY?
# include "lib/format-util.hpp"
//#include "lib/idi/entry-id.hpp"
//#include "lib/diff/gen-node.hpp"
# include "lib/util.hpp"
# include <string>
using std : : string ;
//using lib::idi::EntryID;
2017-10-16 01:28:49 +02:00
using lib : : diff : : MakeRec ;
using lib : : diff : : Rec ;
2017-10-02 18:11:21 +02:00
//using util::isSameObject;
using lib : : Symbol ;
using util : : isnil ;
using util : : join ;
namespace gui {
namespace interact {
namespace test {
// using lumiera::error::LUMIERA_ERROR_WRONG_TYPE;
2017-10-22 00:44:30 +02:00
// using lumiera::error::LUMIERA_ERROR_INDEX_BOUNDS;
using lumiera : : error : : LUMIERA_ERROR_STATE ;
// using lumiera::error::LUMIERA_ERROR_LOGIC;
2017-10-02 18:11:21 +02:00
namespace { //Test fixture...
} //(End)Test fixture
/******************************************************************************/ /**
* @ test verify query and mutation of UICoord in relation to actual UI topology .
*
* @ see UICoordResolver
* @ see navigator . hpp
* @ see ViewLocator
* @ see UICoord_test
*/
class UICoordResolver_test : public Test
{
virtual void
run ( Arg )
{
2017-12-26 14:04:21 +01:00
verify_simpleUsage ( ) ;
2017-10-02 18:39:18 +02:00
verify_backingQuery ( ) ;
2017-10-02 18:11:21 +02:00
verify_queryAnchor ( ) ;
2018-01-04 04:52:09 +01:00
verify_mutateCoverage ( ) ;
2017-10-02 18:11:21 +02:00
verify_mutateAnchor ( ) ;
verify_mutateExtend ( ) ;
}
2017-10-16 01:28:49 +02:00
/** @test introduction to UI coordinate resolution
* - use a backing " real " ( dummy ) data structure to resolve against
* - establish a suitable implementation of the LocationQuery interface
* - attach a resolver
* - have fun
*/
2017-10-02 18:11:21 +02:00
void
2017-10-02 18:39:18 +02:00
verify_simpleUsage ( )
2017-10-02 18:11:21 +02:00
{
2017-10-16 02:39:22 +02:00
// a Test dummy placeholder for the real UI structure
2017-10-28 00:06:44 +02:00
Rec dummyUiStructure = MakeRec ( )
. set ( " window-1 "
, MakeRec ( )
. type ( " perspective-A " )
)
. set ( " window-2 "
, MakeRec ( )
. type ( " perspective-B " )
. set ( " panelX " , MakeRec ( ) )
. set ( " panelXX " , MakeRec ( ) )
) ;
2017-10-16 01:28:49 +02:00
2017-10-16 02:39:22 +02:00
// helper to answer "location queries" backed by this structure
GenNodeLocationQuery locationQuery { dummyUiStructure } ;
2017-10-30 01:47:29 +01:00
UICoord uic { " window-2 " , " * " , " panelX " , " someView " } ;
2017-10-16 02:39:22 +02:00
UICoordResolver resolver { uic , locationQuery } ;
CHECK ( not resolver . isCovered ( ) ) ;
2017-10-21 01:53:13 +02:00
CHECK ( resolver . canCover ( ) ) ;
2017-10-16 02:39:22 +02:00
UICoord uic2 = resolver . cover ( )
. extend ( " otherView " ) ;
CHECK ( " UI:window-2[perspective-B]-panelX.otherView " = = string ( uic2 ) ) ;
2017-10-02 18:11:21 +02:00
}
2017-10-22 00:44:30 +02:00
/** @test verify the command-and-query interface backing the resolver.
* This test actually uses a dummy implementation of the interface , which ,
* instead of navigating an actual UI topology , just uses a ` Record < GenNode > `
* ( a " GenNode tree " ) to emulate the hierarchical structure of UI components .
* @ remarks note some twists how the GenNode tree is used here to represent
* an imaginary UI structure :
* - we use the special _type_ attribute to represent the _perspective_
* within each window ; deliberately , we ' ll use this twisted structure
* here to highlight the fact that the backing structure need not be
* homogeneous ; rather , it may require explicit branching
* - we use the _attributes_ within the GenNode " object " representation ,
* since these are named nested elements , and the whole notion of an
* UI coordinate path is based on named child components
* - we use the _object builder_ helper to define the whole structure
2017-10-28 00:06:44 +02:00
* as nested inline tree ; named nested elements ( " attributes " ) are
* added with the ` set ( key , val ) ` builder function , and for each
* nested scope , we start a new nested builder with ` MakeRec ( ) ` .
2017-10-22 00:44:30 +02:00
* - there is a special convention _for this test setup solely_ to
* set the ` currentWindow ` to be the last one in list - - in a real
2017-12-22 19:35:36 +01:00
* UI this would of course not be a configurable property of the
* LocationQuery , but rather just reflect the transient window
2017-10-22 00:44:30 +02:00
* state and return the currently activated window
2017-12-26 14:56:43 +01:00
* @ see IterTreeExplorer_test : : verify_IterSource ( ) regarding " child exploration " . . .
2017-10-22 00:44:30 +02:00
*/
2017-10-02 18:11:21 +02:00
void
2017-10-02 18:39:18 +02:00
verify_backingQuery ( )
2017-10-02 18:11:21 +02:00
{
2017-10-28 00:06:44 +02:00
GenNodeLocationQuery queryAPI { MakeRec ( )
. set ( " window-1 "
, MakeRec ( )
. type ( " perspective-A " )
. set ( " panelX "
, MakeRec ( )
. set ( " firstView " , MakeRec ( ) )
. set ( " secondView " , MakeRec ( ) )
)
)
. set ( " window-2 "
, MakeRec ( )
. type ( " perspective-B " )
. set ( " panelY " , MakeRec ( ) )
)
. set ( " window-3 "
, MakeRec ( )
. type ( " perspective-C " )
. set ( " panelZ "
, MakeRec ( )
. set ( " thirdView " , MakeRec ( ) )
)
. set ( " panelZZ " , MakeRec ( ) )
)
} ;
2017-10-22 00:44:30 +02:00
// the LocationQuery API works by matching a UICoord spec against the "real" structure
UICoord uic1 = UICoord : : window ( " window-2 " ) . persp ( " perspective-B " ) ;
UICoord uic2 = UICoord : : window ( " windows " ) ;
UICoord uic3 = UICoord : : firstWindow ( ) . persp ( " perspective-A " ) . panel ( " panelX " ) . view ( " secondView " ) ;
UICoord uic4 = UICoord : : currentWindow ( ) . persp ( " perspective-B " ) ;
UICoord uic5 = UICoord : : currentWindow ( ) . persp ( " perspective-C " ) . panel ( " panelZ " ) . view ( " someOtherView " ) ;
CHECK ( " window-2 " = = queryAPI . determineAnchor ( uic1 ) ) ;
CHECK ( Symbol : : BOTTOM = = queryAPI . determineAnchor ( uic2 ) ) ;
CHECK ( " window-1 " = = queryAPI . determineAnchor ( uic3 ) ) ;
CHECK ( " window-3 " = = queryAPI . determineAnchor ( uic4 ) ) ;
CHECK ( " window-3 " = = queryAPI . determineAnchor ( uic5 ) ) ;
CHECK ( 2 = = queryAPI . determineCoverage ( uic1 ) ) ;
CHECK ( 0 = = queryAPI . determineCoverage ( uic2 ) ) ;
CHECK ( 4 = = queryAPI . determineCoverage ( uic3 ) ) ;
CHECK ( 1 = = queryAPI . determineCoverage ( uic4 ) ) ;
CHECK ( 3 = = queryAPI . determineCoverage ( uic5 ) ) ;
LocationQuery : : ChildIter cii = queryAPI . getChildren ( uic3 , 3 ) ;
CHECK ( not isnil ( cii ) ) ;
CHECK ( " firstView " = = * cii ) ;
+ + cii ;
CHECK ( " secondView " = = * cii ) ;
CHECK ( not isnil ( cii ) ) ;
+ + cii ;
CHECK ( isnil ( cii ) ) ;
CHECK ( " window-1, window-2, window-3 " = = join ( queryAPI . getChildren ( uic3 , 0 ) ) ) ;
CHECK ( " perspective-A " = = join ( queryAPI . getChildren ( uic3 , 1 ) ) ) ;
CHECK ( " panelX " = = join ( queryAPI . getChildren ( uic3 , 2 ) ) ) ;
CHECK ( " firstView, secondView " = = join ( queryAPI . getChildren ( uic3 , 3 ) ) ) ;
CHECK ( isnil ( queryAPI . getChildren ( uic3 , 4 ) ) ) ; // "firstView" has no children
CHECK ( " window-1, window-2, window-3 " = = join ( queryAPI . getChildren ( uic2 , 0 ) ) ) ;
VERIFY_ERROR ( STATE , queryAPI . getChildren ( uic2 , 1 ) ) ; // "windows" at pos==0 is not covered by real UI
CHECK ( " window-1, window-2, window-3 " = = join ( queryAPI . getChildren ( uic5 , 0 ) ) ) ;
CHECK ( " perspective-C " = = join ( queryAPI . getChildren ( uic5 , 1 ) ) ) ;
CHECK ( " panelZ, panelZZ " = = join ( queryAPI . getChildren ( uic5 , 2 ) ) ) ;
CHECK ( " thirdView " = = join ( queryAPI . getChildren ( uic5 , 3 ) ) ) ;
VERIFY_ERROR ( STATE , queryAPI . getChildren ( uic5 , 4 ) ) ; // "someOtherView" at level 4 does not exist
2017-12-26 05:07:35 +01:00
2017-12-26 14:04:21 +01:00
// verify "child exploration" via iterator interface
cii = queryAPI . getChildren ( uic3 , 0 ) ; // enter at root level...
CHECK ( " window-1 " = = * cii ) ; // first child of root to appear is "window-1"
CHECK ( 0 = = cii . depth ( ) ) ; // (note depth just happens to coincide with absolute tree depth here)
cii . expandChildren ( ) ; // drill down into current element's children
2017-12-26 05:07:35 +01:00
CHECK ( 1 = = cii . depth ( ) ) ;
2017-12-26 14:04:21 +01:00
CHECK ( " perspective-A " = = * cii ) ; // which is just one, the perspective
cii . expandChildren ( ) ; // drill down into the (formal, logical) children of "perspective-A"
2017-12-26 05:07:35 +01:00
CHECK ( 2 = = cii . depth ( ) ) ;
2017-12-26 14:04:21 +01:00
CHECK ( " panelX " = = * cii ) ; // ..and find the "panelX" at level 2
cii . expandChildren ( ) ; // drill down one level further
2017-12-26 05:07:35 +01:00
CHECK ( 3 = = cii . depth ( ) ) ;
2017-12-26 14:04:21 +01:00
CHECK ( " firstView " = = * cii ) ; // and then just continue iteration, which first explores that scope...
2017-12-26 14:56:43 +01:00
CHECK ( " firstView, secondView, window-2, window-3 " = = join ( cii ) ) ; // ...followed by returning to the enclosing scopes, finally top level.
2017-10-02 18:11:21 +02:00
}
2017-10-18 03:40:26 +02:00
/** @test query anchorage of given UI coordinates.
* - an anchored UI coordinate spec explicitly rooted within a top level window .
2018-01-04 04:52:09 +01:00
* - an explicit UI coordinate spec impossible to anchor within current UI tree
* - a UI coordinate spec with dynamic reference to first / current window
* - an incomplete spec , which needs to be solved ( pattern matched ) to determine anchor .
2017-10-18 03:40:26 +02:00
*/
2017-10-02 18:11:21 +02:00
void
verify_queryAnchor ( )
{
2018-01-04 04:52:09 +01:00
GenNodeLocationQuery tree { MakeRec ( )
2017-10-28 00:06:44 +02:00
. set ( " window-1 "
, MakeRec ( )
. type ( " perspective-A " )
)
. set ( " window-2 "
, MakeRec ( )
. type ( " perspective-B " )
. set ( " panelX "
, MakeRec ( )
. set ( " someView " , MakeRec ( ) )
)
)
} ;
2017-10-18 03:40:26 +02:00
UICoord uic1 = UICoord : : window ( " window-1 " ) . persp ( " perspective-A " ) ;
UICoord uic2 = UICoord : : window ( " windows " ) ;
UICoord uic3 = UICoord : : firstWindow ( ) ;
UICoord uic4 = UICoord : : currentWindow ( ) . persp ( " perspective-B " ) ;
UICoord uic5 = UICoord : : currentWindow ( ) . panel ( " panelY " ) ;
2018-01-05 03:57:27 +01:00
UICoord uic6 = UICoord ( ) . view ( " someView " ) ;
2017-10-18 03:40:26 +02:00
2018-01-04 04:52:09 +01:00
UICoordResolver r1 { uic1 , tree } ;
UICoordResolver r2 { uic2 , tree } ;
UICoordResolver r3 { uic3 , tree } ;
UICoordResolver r4 { uic4 , tree } ;
UICoordResolver r5 { uic5 , tree } ;
UICoordResolver r6 { uic6 , tree } ;
2017-10-18 03:40:26 +02:00
CHECK ( r1 . isAnchored ( ) ) ;
CHECK ( not r2 . isAnchored ( ) ) ;
CHECK ( r3 . isAnchored ( ) ) ;
CHECK ( r4 . isAnchored ( ) ) ;
2018-01-03 02:46:12 +01:00
CHECK ( r5 . isAnchored ( ) ) ;
2017-10-18 03:40:26 +02:00
CHECK ( not r6 . isAnchored ( ) ) ;
CHECK ( r1 . canAnchor ( ) ) ;
CHECK ( not r2 . canAnchor ( ) ) ;
CHECK ( r3 . canAnchor ( ) ) ;
CHECK ( r4 . canAnchor ( ) ) ;
2018-01-03 02:46:12 +01:00
CHECK ( r5 . canAnchor ( ) ) ;
2017-10-18 03:40:26 +02:00
CHECK ( r6 . canAnchor ( ) ) ;
2017-10-02 18:11:21 +02:00
}
2018-01-04 04:52:09 +01:00
/** @test patch matching algorithm to resolve UI coordinates with wildcards against the current UI structure tree.
* Since an UI coordinate path with gaps and wildcards could match anywhere , even several times , we need to perform
* an exhaustive search with backtracking over the whole tree . By convention , we use the first maximal solution ,
* which can be just a partial solution , leaving an additional uncovered trailing part of the UI coordinate spec .
* Whenever a coordinate spec is _not explicit , _ has wildcards or a leading gap , we need to perform the full
* matching algorithm , even to just answer the question if coverage _is possible_ . The result , i . e . the computed
* coverage , is cached internally , and can be used to _mutate_ the UI coordinate spec to match that coverage .
*
* This test verifies various corner cases ; especially there is a rule to prevent a partial match based
* on wildcards solely , rather we require at least one explicit match to qualify as partial solution .
2018-01-05 02:14:22 +01:00
* - ( 1 ) trivial cases not requiring a tree search
2018-01-04 04:52:09 +01:00
* * * total coverage
* * * partial coverage , leaving an uncovered suffix
2018-01-05 02:14:22 +01:00
* - ( 2 ) expand dynamic anchor specifiers
* * * with following content
* * * anchor spec alone
* - ( 3 ) wildcard interpolation
* * * interpolate a single gap
* * * interpolate several gaps
* * * interpolate anchor and consecutive wildcards
* * * discriminate by anchor and fill additional gap
* - ( 4 ) failure detection
2018-01-05 03:57:27 +01:00
* * * trailing wildcards are stripped and ignored
2018-01-05 02:14:22 +01:00
* * * reject gap beyond existing real UI tree
* * * reject gap ending at perimeter of real UI tree
* * * reject interpolated gap on immediately following mismatch
* * * reject mismatch immediately behind second gap
* * * mismatch of tree level
* * * contradiction to anchorage
2018-01-04 04:52:09 +01:00
*/
2017-10-02 18:11:21 +02:00
void
2018-01-04 04:52:09 +01:00
verify_mutateCoverage ( )
2017-10-02 18:11:21 +02:00
{
2018-01-04 04:52:09 +01:00
GenNodeLocationQuery tree { MakeRec ( )
. set ( " window-1 "
, MakeRec ( )
2018-01-05 03:57:27 +01:00
. type ( " persp-A " )
2018-01-04 04:52:09 +01:00
. set ( " panelX "
, MakeRec ( )
. set ( " firstView " , MakeRec ( ) )
. set ( " secondView " , MakeRec ( ) )
)
2018-01-05 02:14:22 +01:00
. set ( " panelZ "
, MakeRec ( )
. set ( " thirdView "
, MakeRec ( )
. set ( " #1 " , MakeRec ( ) )
. set ( " #2 " , MakeRec ( ) )
2018-01-05 03:57:27 +01:00
. set ( " tab " , MakeRec ( ) )
2018-01-05 02:14:22 +01:00
)
)
2018-01-04 04:52:09 +01:00
)
. set ( " window-2 "
, MakeRec ( )
2018-01-05 03:57:27 +01:00
. type ( " persp-B " )
2018-01-04 04:52:09 +01:00
. set ( " panelY " , MakeRec ( ) )
)
. set ( " window-3 "
, MakeRec ( )
2018-01-05 03:57:27 +01:00
. type ( " persp-C " )
2018-01-04 04:52:09 +01:00
. set ( " panelZ "
, MakeRec ( )
2018-01-05 02:14:22 +01:00
. set ( " thirdView "
, MakeRec ( )
2018-01-05 03:57:27 +01:00
. set ( " tab "
2018-01-05 02:14:22 +01:00
, MakeRec ( )
. set ( " sub " , MakeRec ( ) )
)
)
2018-01-04 04:52:09 +01:00
)
. set ( " panelZZ " , MakeRec ( ) )
)
} ;
/* === trivial cases === */
UICoordResolver r11 { UICoord : : window ( " window-1 " )
2018-01-05 03:57:27 +01:00
. persp ( " persp-A " )
2018-01-04 04:52:09 +01:00
. panel ( " panelX " ) , tree } ;
CHECK ( r11 . isCovered ( ) ) ;
CHECK ( 3 = = r11 . coverDepth ( ) ) ;
UICoordResolver r12 { UICoord : : window ( " window-1 " )
2018-01-05 03:57:27 +01:00
. persp ( " persp-A " )
2018-01-04 04:52:09 +01:00
. panel ( " panelX " )
. view ( " thirdView " ) , tree } ;
CHECK ( not r12 . isCovered ( ) ) ;
CHECK ( r12 . isCoveredPartially ( ) ) ;
CHECK ( 3 = = r12 . coverDepth ( ) ) ;
2018-01-05 03:57:27 +01:00
CHECK ( " UI:window-1[persp-A]-panelX.thirdView " = = string ( r12 ) ) ;
2018-01-04 04:52:09 +01:00
auto r12_covered = r12 . cover ( ) ;
CHECK ( r12_covered . isCovered ( ) ) ;
CHECK ( r12_covered . isCoveredPartially ( ) ) ;
CHECK ( 3 = = r12_covered . coverDepth ( ) ) ;
2018-01-05 03:57:27 +01:00
CHECK ( " UI:window-1[persp-A]-panelX " = = string ( r12_covered ) ) ;
2018-01-04 04:52:09 +01:00
2018-01-05 02:14:22 +01:00
/* === expand anchor === */
2018-01-05 03:57:27 +01:00
UICoordResolver r21 { UICoord : : firstWindow ( ) . persp ( " persp-A " ) , tree } ;
cout < < r21 . cover ( ) < < endl ; ///////////////////////////////////////////TODO doesn't work, yields UI:firstWindow[persp-A]
2018-01-05 02:14:22 +01:00
/* === expand anchor alone === */
UICoordResolver r22 { UICoord : : currentWindow ( ) , tree } ;
2018-01-05 03:57:27 +01:00
cout < < r22 . cover ( ) < < endl ; ///////////////////////////////////////////TODO doesn't work, yields UI:currentWindow
2018-01-05 02:14:22 +01:00
/* === interpolate a single gap === */
UICoordResolver r31 { UICoord : : window ( " window-1 " ) . view ( " secondView " ) , tree } ;
2018-01-05 03:57:27 +01:00
CHECK ( " UI:window-1[persp-A]-panelX.secondView " = = string ( r31 . cover ( ) ) ) ;
2018-01-05 02:14:22 +01:00
/* === interpolate several gaps === */
UICoordResolver r32 { UICoord ( ) . view ( " thirdView " ) . path ( " sub " ) , tree } ;
2018-01-05 03:57:27 +01:00
CHECK ( " UI:window-3[persp-C]-panelZ.thirdView.tab/sub " = = string ( r32 . cover ( ) ) ) ;
2018-01-05 02:14:22 +01:00
/* === interpolate anchor and consecutive wildcards === */
UICoordResolver r33 { UICoord : : firstWindow ( ) . tab ( 2 ) , tree } ;
2018-01-05 03:57:27 +01:00
CHECK ( " UI:window-1[persp-A]-panelZ.thirdView.#2 " = = string ( r33 . cover ( ) ) ) ;
2018-01-05 02:14:22 +01:00
/* === discriminate by anchor and fill second gap === */
2018-01-05 03:57:27 +01:00
UICoordResolver r34 { UICoord : : currentWindow ( ) . panel ( " panelZ " ) . tab ( " tab " ) , tree } ;
CHECK ( " UI:window-3[persp-C]-panelZ.thirdView.tab " = = string ( r34 . cover ( ) ) ) ; // Note: rest of the path would also match on window-1, but currentWindow == window-3
2018-01-05 02:14:22 +01:00
2018-01-05 03:57:27 +01:00
/* === trailing wildcards stripped automatically === */
2018-01-05 02:14:22 +01:00
UICoordResolver r41 { UICoord : : window ( " window-2 " ) . append ( " */* " ) , tree } ;
2018-01-05 03:57:27 +01:00
CHECK ( " UI:window-2 " = = string ( r41 ) ) ; // Note: trailing wildcards are already discarded by PathArray / UICoord
auto r41_extended = r41 . extend ( " */* " ) ; // if we now attempt to "sneak in" trailing wildcards...
CHECK ( " UI:window-2[*]-* " = = string ( r41_extended ) ) ;
CHECK ( not r41_extended . canCover ( ) ) ; // ...then the algorithm rejects any solution
CHECK ( " UI:window-2 " = = string ( r41_extended . cover ( ) ) ) ; // Note: but cover() will act on the previous coverage and just strip the extraneous suffix
2018-01-05 02:14:22 +01:00
/* === reject gap beyond existing real UI tree === */
UICoordResolver r42 { UICoord : : window ( " window-2 " ) . append ( " */*/*/some/path " ) , tree } ;
2018-01-05 03:57:27 +01:00
CHECK ( not r42 . canCover ( ) ) ;
2018-01-05 02:14:22 +01:00
/* === reject gap ending at real UI tree boundary === */
2018-01-05 03:57:27 +01:00
UICoordResolver r43 { UICoord : : currentWindow ( ) . view ( " firstView " ) . tab ( " nonexisting " ) , tree } ;
2018-01-05 02:14:22 +01:00
CHECK ( not r43 . canCover ( ) ) ;
/* === reject interpolated gap on mismatch right behind === */
2018-01-05 03:57:27 +01:00
UICoordResolver r44 { UICoord ( ) . view ( " otherView " ) , tree } ; // Note: will be checked on all four existing views, but never matches
2018-01-05 02:14:22 +01:00
CHECK ( not r44 . canCover ( ) ) ;
/* === reject mismatch immediately behind second gap === */
2018-01-05 03:57:27 +01:00
UICoordResolver r45 { UICoord ( ) . panel ( " panelZ " ) . tab ( 3 ) , tree } ; // Note: we have two "panelZ", but none has a tab #3
CHECK ( not r45 . canCover ( ) ) ;
2018-01-05 02:14:22 +01:00
/* === mismatch of tree level === */
2018-01-05 03:57:27 +01:00
UICoordResolver r46 { UICoord : : currentWindow ( ) . append ( " */*/panelZ/thirdView " ) , tree } ; // Note: one '*' too much, thus 'panelZ' is matched on view level
2018-01-05 02:14:22 +01:00
CHECK ( not r46 . canCover ( ) ) ;
/* === impossible to anchor === */
UICoordResolver r47 { UICoord : : firstWindow ( ) . tab ( 3 ) , tree } ;
CHECK ( not r47 . canCover ( ) ) ;
2018-01-04 04:52:09 +01:00
UNIMPLEMENTED ( " TODO: further cases of coverage query.... " ) ;
2017-10-02 18:11:21 +02:00
}
void
verify_mutateAnchor ( )
{
UNIMPLEMENTED ( " mutate given UI coordinates by anchoring them " ) ;
}
void
verify_mutateExtend ( )
{
UNIMPLEMENTED ( " mutate given UI coordinates by uncovered extension " ) ;
}
} ;
/** Register this test class... */
LAUNCHER ( UICoordResolver_test , " unit gui " ) ;
} } } // namespace gui::interact::test