diff --git a/tests/unit/tests/matchers/property-matcher.h b/tests/unit/tests/matchers/property-matcher.h new file mode 100644 index 00000000000..561a94cb69e --- /dev/null +++ b/tests/unit/tests/matchers/property-matcher.h @@ -0,0 +1,86 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include +#include + +#include +#include + +namespace internal { + +template +class PropertyMatcher +{ +public: + PropertyMatcher(Property property, const Matcher &matcher, Arguments... arguments) + : m_property(property) + , matcher_(matcher) + , m_whose_property() + , m_arguments{arguments...} + {} + + PropertyMatcher(const std::string &whose_property, + Property property, + const Matcher &matcher, + Arguments... arguments) + : m_property(property) + , matcher_(matcher) + , m_whose_property(whose_property) + , m_arguments{arguments...} + {} + + void DescribeTo(::std::ostream *os) const + { + *os << "is an object " << m_whose_property; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream *os) const + { + *os << "is an object " << m_whose_property; + matcher_.DescribeNegationTo(os); + } + + template + bool MatchAndExplain(const T &value, testing::MatchResultListener *listener) const + { + *listener << "which points to an object "; + + auto result = std::apply( + [&](auto &&...arguments) { return std::invoke(m_property, value, arguments...); }, + m_arguments); + return MatchPrintAndExplain(result, matcher_, listener); + } + +private: + Property m_property; + const Matcher matcher_; + const std::string m_whose_property; + const std::tuple m_arguments; +}; + +template +concept matcher = std::derived_from + || requires { typename PropertyMatcher::is_gtest_matcher; }; + +} // namespace internal + +template +inline auto Property(const std::string &propertyName, + PropertyType property, + const PropertyMatcher &matchingType, + Arguments... arguments) +// requires(sizeof...(Arguments) >= 1) +{ + using namespace std::string_literals; + + return testing::MakePolymorphicMatcher( + internal::PropertyMatcher( + "whose property `"s + propertyName + "` "s, + property, + matchingType, + std::forward(arguments)...)); +} diff --git a/tests/unit/tests/utils/google-using-declarations.h b/tests/unit/tests/utils/google-using-declarations.h index 8dd8e790b5c..ea781e59dbc 100644 --- a/tests/unit/tests/utils/google-using-declarations.h +++ b/tests/unit/tests/utils/google-using-declarations.h @@ -4,6 +4,7 @@ #pragma once #include +#include using testing::_; using testing::A;