File indexing completed on 2026-05-10 08:44:37
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_TESTING_ADT_STRINGMAPENTRY_H_
0010 #define LLVM_TESTING_ADT_STRINGMAPENTRY_H_
0011
0012 #include "llvm/ADT/StringMapEntry.h"
0013 #include "gmock/gmock.h"
0014 #include <ostream>
0015 #include <type_traits>
0016
0017 namespace llvm {
0018 namespace detail {
0019
0020 template <typename T, typename = std::void_t<>>
0021 struct CanOutputToOStream : std::false_type {};
0022
0023 template <typename T>
0024 struct CanOutputToOStream<T, std::void_t<decltype(std::declval<std::ostream &>()
0025 << std::declval<T>())>>
0026 : std::true_type {};
0027
0028 }
0029
0030
0031
0032 template <typename T>
0033 std::ostream &operator<<(std::ostream &OS, const StringMapEntry<T> &E) {
0034 OS << "{\"" << E.getKey().data() << "\": ";
0035 if constexpr (detail::CanOutputToOStream<decltype(E.getValue())>::value) {
0036 OS << E.getValue();
0037 } else {
0038 OS << "non-printable value";
0039 }
0040 return OS << "}";
0041 }
0042
0043 namespace detail {
0044
0045 template <typename StringMapEntryT>
0046 class StringMapEntryMatcherImpl
0047 : public testing::MatcherInterface<StringMapEntryT> {
0048 public:
0049 using ValueT = typename std::remove_reference_t<StringMapEntryT>::ValueType;
0050
0051 template <typename KeyMatcherT, typename ValueMatcherT>
0052 StringMapEntryMatcherImpl(KeyMatcherT KeyMatcherArg,
0053 ValueMatcherT ValueMatcherArg)
0054 : KeyMatcher(
0055 testing::SafeMatcherCast<const std::string &>(KeyMatcherArg)),
0056 ValueMatcher(
0057 testing::SafeMatcherCast<const ValueT &>(ValueMatcherArg)) {}
0058
0059 void DescribeTo(std::ostream *OS) const override {
0060 *OS << "has a string key that ";
0061 KeyMatcher.DescribeTo(OS);
0062 *OS << ", and has a value that ";
0063 ValueMatcher.DescribeTo(OS);
0064 }
0065
0066 void DescribeNegationTo(std::ostream *OS) const override {
0067 *OS << "has a string key that ";
0068 KeyMatcher.DescribeNegationTo(OS);
0069 *OS << ", or has a value that ";
0070 ValueMatcher.DescribeNegationTo(OS);
0071 }
0072
0073 bool
0074 MatchAndExplain(StringMapEntryT Entry,
0075 testing::MatchResultListener *ResultListener) const override {
0076 testing::StringMatchResultListener KeyListener;
0077 if (!KeyMatcher.MatchAndExplain(Entry.getKey().data(), &KeyListener)) {
0078 *ResultListener << ("which has a string key " +
0079 (KeyListener.str().empty() ? "that doesn't match"
0080 : KeyListener.str()));
0081 return false;
0082 }
0083 testing::StringMatchResultListener ValueListener;
0084 if (!ValueMatcher.MatchAndExplain(Entry.getValue(), &ValueListener)) {
0085 *ResultListener << ("which has a value " + (ValueListener.str().empty()
0086 ? "that doesn't match"
0087 : ValueListener.str()));
0088 return false;
0089 }
0090 *ResultListener << "which is a match";
0091 return true;
0092 }
0093
0094 private:
0095 const testing::Matcher<const std::string &> KeyMatcher;
0096 const testing::Matcher<const ValueT &> ValueMatcher;
0097 };
0098
0099 template <typename KeyMatcherT, typename ValueMatcherT>
0100 class StringMapEntryMatcher {
0101 public:
0102 StringMapEntryMatcher(KeyMatcherT KMArg, ValueMatcherT VMArg)
0103 : KM(std::move(KMArg)), VM(std::move(VMArg)) {}
0104
0105 template <typename StringMapEntryT>
0106 operator testing::Matcher<StringMapEntryT>() const {
0107 return testing::Matcher<StringMapEntryT>(
0108 new StringMapEntryMatcherImpl<const StringMapEntryT &>(KM, VM));
0109 }
0110
0111 private:
0112 const KeyMatcherT KM;
0113 const ValueMatcherT VM;
0114 };
0115
0116 }
0117
0118
0119
0120 template <typename KeyMatcherT, typename ValueMatcherT>
0121 detail::StringMapEntryMatcher<KeyMatcherT, ValueMatcherT>
0122 IsStringMapEntry(KeyMatcherT KM, ValueMatcherT VM) {
0123 return detail::StringMapEntryMatcher<KeyMatcherT, ValueMatcherT>(
0124 std::move(KM), std::move(VM));
0125 }
0126
0127 }
0128
0129 #endif