Viewing file: StringMapEntry.h (4.31 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
//===- llvm/Testing/ADT/StringMapEntry.h ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===//
#ifndef LLVM_TESTING_ADT_STRINGMAPENTRY_H_ #define LLVM_TESTING_ADT_STRINGMAPENTRY_H_
#include "llvm/ADT/StringMapEntry.h" #include "gmock/gmock.h" #include <ostream> #include <type_traits>
namespace llvm { namespace detail {
template <typename T, typename = std::void_t<>> struct CanOutputToOStream : std::false_type {};
template <typename T> struct CanOutputToOStream<T, std::void_t<decltype(std::declval<std::ostream &>() << std::declval<T>())>> : std::true_type {};
} // namespace detail
/// Support for printing to std::ostream, for use with e.g. producing more /// useful error messages with Google Test. template <typename T> std::ostream &operator<<(std::ostream &OS, const StringMapEntry<T> &E) { OS << "{\"" << E.getKey().data() << "\": "; if constexpr (detail::CanOutputToOStream<decltype(E.getValue())>::value) { OS << E.getValue(); } else { OS << "non-printable value"; } return OS << "}"; }
namespace detail {
template <typename StringMapEntryT> class StringMapEntryMatcherImpl : public testing::MatcherInterface<StringMapEntryT> { public: using ValueT = typename std::remove_reference_t<StringMapEntryT>::ValueType;
template <typename KeyMatcherT, typename ValueMatcherT> StringMapEntryMatcherImpl(KeyMatcherT KeyMatcherArg, ValueMatcherT ValueMatcherArg) : KeyMatcher( testing::SafeMatcherCast<const std::string &>(KeyMatcherArg)), ValueMatcher( testing::SafeMatcherCast<const ValueT &>(ValueMatcherArg)) {}
void DescribeTo(std::ostream *OS) const override { *OS << "has a string key that "; KeyMatcher.DescribeTo(OS); *OS << ", and has a value that "; ValueMatcher.DescribeTo(OS); }
void DescribeNegationTo(std::ostream *OS) const override { *OS << "has a string key that "; KeyMatcher.DescribeNegationTo(OS); *OS << ", or has a value that "; ValueMatcher.DescribeNegationTo(OS); }
bool MatchAndExplain(StringMapEntryT Entry, testing::MatchResultListener *ResultListener) const override { testing::StringMatchResultListener KeyListener; if (!KeyMatcher.MatchAndExplain(Entry.getKey().data(), &KeyListener)) { *ResultListener << ("which has a string key " + (KeyListener.str().empty() ? "that doesn't match" : KeyListener.str())); return false; } testing::StringMatchResultListener ValueListener; if (!ValueMatcher.MatchAndExplain(Entry.getValue(), &ValueListener)) { *ResultListener << ("which has a value " + (ValueListener.str().empty() ? "that doesn't match" : ValueListener.str())); return false; } *ResultListener << "which is a match"; return true; }
private: const testing::Matcher<const std::string &> KeyMatcher; const testing::Matcher<const ValueT &> ValueMatcher; };
template <typename KeyMatcherT, typename ValueMatcherT> class StringMapEntryMatcher { public: StringMapEntryMatcher(KeyMatcherT KMArg, ValueMatcherT VMArg) : KM(std::move(KMArg)), VM(std::move(VMArg)) {}
template <typename StringMapEntryT> operator testing::Matcher<StringMapEntryT>() const { // NOLINT return testing::Matcher<StringMapEntryT>( new StringMapEntryMatcherImpl<const StringMapEntryT &>(KM, VM)); }
private: const KeyMatcherT KM; const ValueMatcherT VM; };
} // namespace detail
/// Returns a gMock matcher that matches a `StringMapEntry` whose string key /// matches `KeyMatcher`, and whose value matches `ValueMatcher`. template <typename KeyMatcherT, typename ValueMatcherT> detail::StringMapEntryMatcher<KeyMatcherT, ValueMatcherT> IsStringMapEntry(KeyMatcherT KM, ValueMatcherT VM) { return detail::StringMapEntryMatcher<KeyMatcherT, ValueMatcherT>( std::move(KM), std::move(VM)); }
} // namespace llvm
#endif
|