Lumiera  0.pre.03
»edit your freedom«
UICoordResolver_test Class Reference

Description

Test:
verify query and mutation of UICoord in relation to actual UI topology.

A UI-Coordinate resolver is a special builder, which is initialised by the given coordinate spec, and also attached to a "location query API", which allows to investigate the current actual UI structure. The builder then exposes query and mutation operations, to determine to what extent the coordinate spec is "covered" by the real UI, and to match and expand any wildcards in the coordinate spec (pattern).

See also
UICoordResolver
navigator.hpp
ViewLocator
UICoord_test

Definition at line 72 of file ui-coord-resolver-test.cpp.

Private Member Functions

virtual void run (Arg)
 
void verify_backingQuery ()
 
void verify_mutateAnchor ()
 
void verify_mutateCoverage ()
 
void verify_mutateCoverPartially ()
 
void verify_mutateExtend ()
 
void verify_queryAnchor ()
 
void verify_simpleUsage ()
 

Member Function Documentation

◆ verify_simpleUsage()

void verify_simpleUsage ( )
inlineprivate
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

Definition at line 95 of file ui-coord-resolver-test.cpp.

◆ verify_backingQuery()

void verify_backingQuery ( )
inlineprivate
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 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().
  • there is a special convention for this test setup solely to set the currentWindow to be the last one in list – in a real UI this would of course not be a configurable property of the LocationQuery, but rather just reflect the transient window state and return the currently activated window
See also
IterExplorer_test::verify_IterSource() regarding "child exploration"...

Definition at line 151 of file ui-coord-resolver-test.cpp.

◆ verify_queryAnchor()

void verify_queryAnchor ( )
inlineprivate
Test:
query anchorage of given UI coordinates.
  • an anchored UI coordinate spec explicitly rooted within a top level window.
  • 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.

Definition at line 247 of file ui-coord-resolver-test.cpp.

◆ verify_mutateCoverage()

void verify_mutateCoverage ( )
inlineprivate
Test:
path 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.

  • (1) trivial cases not requiring a tree search ** total coverage ** partial coverage, leaving an uncovered suffix
  • (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 ** trailing wildcards are stripped and ignored ** 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
  • (5) selection between several possible solutions ** the length of the covered trailing suffix decides ** when two solutions are equivalent, pick the fist one ** best solution will be picked, irrespective of discovery order

Definition at line 329 of file ui-coord-resolver-test.cpp.

◆ verify_mutateCoverPartially()

void verify_mutateCoverPartially ( )
inlineprivate
Test:
resolve by matching, but retain an extraneous, uncovered extension.

This is a variation of the UICoordResolver::cover() operation, which likewise resolves any wildcards; but here we tolerate additional elements below the covered part, as long as those are explicit. The typical use case is when we're about to create a new UI element at a specific existing anchor location within the UI. The extraneous uncovered part then describes those extra element yet to be created.

Definition at line 504 of file ui-coord-resolver-test.cpp.

◆ verify_mutateAnchor()

void verify_mutateAnchor ( )
inlineprivate
Test:
mutate given UI coordinates by anchoring them.

This operation changes only the window part of the coordinate spec; it might use the result of a preceding coverage solution search or even trigger such a search, but only to find out about the root window.

Note
some fine points touched here: to anchor a path is something different than to cover it; in fact there are cases where we can determine the possible anchor point, but are unable to cover the path spec beyond that. And, on the other hand, there are cases where you need to compute a coverage in order to decide upon the anchor point.

Definition at line 584 of file ui-coord-resolver-test.cpp.

◆ verify_mutateExtend()

void verify_mutateExtend ( )
inlineprivate
Test:
mutate given UI coordinates by uncovered extension.

Contrary to just appending something to the path (which is a basic path operation available on the generic path builder), a path extension is always rooted at the end of the actually covered part of the UI coordinates. So extending a path implies search for a coverage solution, followed by truncating the path to the covered part. There are two flavours of extending a path:

  • extending with a literal specification, which is just appended behind the coverage
  • extending with an incomplete UI coordinate spec, which allows to place the extension at a specific depth (e.g. as a view). This is typically what we want in practice.

Definition at line 698 of file ui-coord-resolver-test.cpp.

+ Inheritance diagram for UICoordResolver_test:
+ Collaboration diagram for UICoordResolver_test:

The documentation for this class was generated from the following file: