21class API_AUI_UITESTS UIMatcher {
24 bool mIncludeInvisibleViews =
false;
27 template<
typename Container>
30 template<
typename T,
typename =
int>
31 struct ignores_visibility : std::false_type { };
34 struct ignores_visibility<T, decltype((T::IGNORE_VISIBILITY::value, 0))> : T::IGNORE_VISIBILITY { };
36 template<
class Assertion>
37 void performHintChecks(
const char* msg,
ASet<
_<AView>>& set) {
39 if constexpr (ignores_visibility<Assertion>::value) {
43 if (msg ==
nullptr) std::cout <<
"Assertion message is empty";
44 if constexpr(!std::is_same_v<Assertion, empty>) {
45 if (set.empty()) std::cout <<
"UIMatcher is empty so check is not performed";
49 static UIMatcher*& currentImpl();
52 UIMatcher(
const _<IMatcher>& matcher) : mMatcher(matcher) {}
55 if (current() ==
this) {
56 currentImpl() =
nullptr;
60 static UIMatcher* current() {
70 SCOPED_TRACE(
"no views selected");
76 UIMatcher& includeInvisibleViews() {
77 mIncludeInvisibleViews =
true;
81 template<
class Action>
82 UIMatcher& perform(Action&& action) {
84 if (set.empty()) std::cout <<
"UIMatcher is empty so action is not performed";
114 auto mySet = toSet();
115 auto targets = matcher.toSet();
117 if (targets.size() != 1) {
118 throw AException(
"expected to match one view, matched {}"_format(mySet.size()));
121 throw AException(
"findNearestTo requires at least one element to match");
124 auto nearestToView = (*targets.begin());
125 auto nearestToPoint = glm::vec2(nearestToView->getPositionInWindow() + nearestToView->getSize());
126 auto target = std::min_element(mySet.begin(), mySet.end(), [&](
const _<AView>& lhs,
const _<AView>& rhs) {
127 float dst1 = glm::distance2(nearestToPoint, glm::vec2(lhs->getCenterPointInWindow()));
128 float dst2 = glm::distance2(nearestToPoint, glm::vec2(rhs->getCenterPointInWindow()));
131 EXPECT_TRUE(target != mySet.end());
133 class ToOneMatcher:
public IMatcher {
135 explicit ToOneMatcher(
_<AView> view) : mView(std::move(view)) {}
137 bool matches(
const _<AView>& view)
override {
138 return view == mView;
144 return { _new<ToOneMatcher>(std::move(*target)) };
148 template<
class Assertion>
149 UIMatcher& check(Assertion&& assertion,
const char* msg =
"no msg") {
150 mIncludeInvisibleViews = ignores_visibility<Assertion>::value;
154 performHintChecks<Assertion>(msg, set);
155 for (
auto& s : set) {
162 UIMatcher parent()
const {
164 struct ParentMatcher:
public IMatcher {
166 _<IMatcher> childMatcher;
168 ParentMatcher(
const _<IMatcher>& childMatcher) : childMatcher(childMatcher) {}
170 bool matches(
const _<AView>& view)
override {
171 if (
auto container = _cast<AViewContainer>(view)) {
172 for (
const auto& childView : container) {
173 if (childMatcher->matches(childView))
return true;
179 return { _new<ParentMatcher>(mMatcher) };
183 UIMatcher allChildren()
const {
185 struct ChildMatcher:
public IMatcher {
187 _<IMatcher> childMatcher;
189 ChildMatcher(
const _<IMatcher>& childMatcher) : childMatcher(childMatcher) {}
191 bool matches(
const _<AView>& view)
override {
196 return { _new<ChildMatcher>(mMatcher) };
201 template<
class BinaryOperator>
202 struct BinaryOperatorMatcher:
public IMatcher {
207 BinaryOperatorMatcher(
const _<IMatcher>& lhs,
const _<IMatcher>& rhs) : lhs(lhs), rhs(rhs) {}
209 bool matches(
const _<AView>& view)
override {
210 return BinaryOperator()(lhs->matches(view), rhs->matches(view));
216 UIMatcher operator|(
const UIMatcher& matcher)
const {
218 bool operator()(
bool lhs,
bool rhs)
const {
222 return { _new<BinaryOperatorMatcher<compare_or>>(mMatcher, matcher.mMatcher) };
225 UIMatcher operator&(
const UIMatcher& matcher)
const {
227 bool operator()(
bool lhs,
bool rhs)
const {
231 return { _new<BinaryOperatorMatcher<compare_and>>(mMatcher, matcher.mMatcher) };
static _< T > fake(T *raw)
Creates fake shared pointer to T* raw with empty destructor, which does nothing. It's useful when som...
Definition SharedPtrTypes.h:429