forked from qt-creator/qt-creator
UnitTests: Add PropertyMatcher
Extend the matcher for Properties with arguments. It is only used if arguments are provided. The matcher argument must be always a matcher. struct Foo { int foo(int) const { return 1; } }; TEST(X, X) { Property("Foo::foo", &Foo::foo, Eq(10), 8); } Change-Id: If20d958dd65652f8268fc5e744220ed2ff26a0f5 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Burak Hancerli
parent
f3eaf3877b
commit
f2342f2563
86
tests/unit/tests/matchers/property-matcher.h
Normal file
86
tests/unit/tests/matchers/property-matcher.h
Normal file
@@ -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 <gmock/gmock-matchers.h>
|
||||||
|
#include <gmock/gmock-more-matchers.h>
|
||||||
|
|
||||||
|
#include <concepts>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template<typename Property, typename Matcher, typename... Arguments>
|
||||||
|
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<typename T>
|
||||||
|
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<Arguments...> m_arguments;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename PropertyMatcher>
|
||||||
|
concept matcher = std::derived_from<PropertyMatcher, testing::MatcherDescriberInterface>
|
||||||
|
|| requires { typename PropertyMatcher::is_gtest_matcher; };
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template<typename PropertyType, internal::matcher PropertyMatcher, typename... Arguments>
|
||||||
|
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<PropertyType, PropertyMatcher, Arguments...>(
|
||||||
|
"whose property `"s + propertyName + "` "s,
|
||||||
|
property,
|
||||||
|
matchingType,
|
||||||
|
std::forward<Arguments>(arguments)...));
|
||||||
|
}
|
@@ -4,6 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gmock/gmock.h>
|
#include <gmock/gmock.h>
|
||||||
|
#include <matchers/property-matcher.h>
|
||||||
|
|
||||||
using testing::_;
|
using testing::_;
|
||||||
using testing::A;
|
using testing::A;
|
||||||
|
Reference in New Issue
Block a user