156 lines · c
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8/// \file9/// This file contains the definition of the ValueMatcher class which is a used10/// to match lldb_private::Value in gtest assert/expect macros. It also contains11/// several helper functions to create matchers for common Value types.12///13/// The ValueMatcher class was created using the gtest guide found here:14// https://google.github.io/googletest/gmock_cook_book.html#writing-new-monomorphic-matchers15//===----------------------------------------------------------------------===//16 17#ifndef LLDB_UNITTESTS_EXPRESSION_VALUEMATCHER_H18#define LLDB_UNITTESTS_EXPRESSION_VALUEMATCHER_H19 20#include "lldb/Core/Value.h"21#include "lldb/Utility/Scalar.h"22#include "llvm/Support/raw_ostream.h"23#include "llvm/Testing/Support/Error.h"24#include "gtest/gtest.h"25#include <cstdint>26#include <vector>27 28namespace lldb_private {29 30/// Custom printer for Value objects to make test failures more readable.31void PrintTo(const Value &val, std::ostream *os);32 33/// Custom matcher for Value.34///35/// It matches against an expected value_type, and context_type.36/// For HostAddress value types it will match the expected contents of37/// the host buffer. For other value types it matches against an expected38/// scalar value.39class ValueMatcher {40public:41 ValueMatcher(Value::ValueType value_type, const Scalar &expected_scalar,42 Value::ContextType context_type)43 : m_value_type(value_type), m_context_type(context_type),44 m_expected_scalar(expected_scalar) {45 assert(value_type == Value::ValueType::Scalar ||46 value_type == Value::ValueType::FileAddress ||47 value_type == Value::ValueType::LoadAddress);48 }49 50 ValueMatcher(Value::ValueType value_type,51 const std::vector<uint8_t> &expected_bytes,52 Value::ContextType context_type)53 : m_value_type(value_type), m_context_type(context_type),54 m_expected_bytes(expected_bytes) {55 assert(value_type == Value::ValueType::HostAddress);56 }57 58 // Typedef to hook into the gtest matcher machinery.59 using is_gtest_matcher = void;60 61 bool MatchAndExplain(const Value &val, std::ostream *os) const;62 63 void DescribeTo(std::ostream *os) const;64 65 void DescribeNegationTo(std::ostream *os) const;66 67private:68 Value::ValueType m_value_type = Value::ValueType::Invalid;69 Value::ContextType m_context_type = Value::ContextType::Invalid;70 Scalar m_expected_scalar;71 std::vector<uint8_t> m_expected_bytes;72 73 bool MatchAndExplainImpl(const Value &val, llvm::raw_ostream &os) const;74};75 76/// Matcher for Value with Scalar, FileAddress, or LoadAddress types.77/// Use with llvm::HasValue() to match Expected<Value>:78/// EXPECT_THAT_EXPECTED(result, llvm::HasValue(MatchScalarValue(...)));79testing::Matcher<Value> MatchScalarValue(Value::ValueType value_type,80 const Scalar &expected_scalar,81 Value::ContextType context_type);82 83/// Matcher for Value with HostAddress type.84/// Use with llvm::HasValue() to match Expected<Value>:85/// EXPECT_THAT_EXPECTED(result, llvm::HasValue(MatchHostValue(...)));86testing::Matcher<Value>87MatchHostValue(Value::ValueType value_type,88 const std::vector<uint8_t> &expected_bytes,89 Value::ContextType context_type);90 91/// Helper to match a Scalar value and context type.92/// Use with llvm::HasValue() to match Expected<Value>:93/// EXPECT_THAT_EXPECTED(result, llvm::HasValue(IsScalar(42)));94testing::Matcher<Value> IsScalar(const Scalar &expected_scalar,95 Value::ContextType context_type);96 97/// Helper to match a LoadAddress value and context type.98/// Use with llvm::HasValue() to match Expected<Value>:99/// EXPECT_THAT_EXPECTED(result, llvm::HasValue(IsLoadAddress(0x1000)));100testing::Matcher<Value> IsLoadAddress(const Scalar &expected_address,101 Value::ContextType context_type);102 103/// Helper to match a FileAddress value and context type.104/// Use with llvm::HasValue() to match Expected<Value>:105/// EXPECT_THAT_EXPECTED(result, llvm::HasValue(IsFileAddress(Scalar(0x1000))));106testing::Matcher<Value> IsFileAddress(const Scalar &expected_address,107 Value::ContextType context_type);108 109/// Helper to match a HostAddress value and context type.110/// Use with llvm::HasValue() to match Expected<Value>:111/// EXPECT_THAT_EXPECTED(result, llvm::HasValue(IsHostValue({0x11, 0x22})));112testing::Matcher<Value> IsHostValue(const std::vector<uint8_t> &expected_bytes,113 Value::ContextType context_type);114 115/// Helper to create a scalar because Scalar's operator==() is really picky.116Scalar GetScalar(unsigned bits, uint64_t value, bool sign);117 118/// Helper that combines IsScalar with llvm::HasValue for Expected<Value>.119/// Use it on an Expected<Value> like this:120/// EXPECT_THAT_EXPECTED(result, ExpectScalar(42));121llvm::detail::ValueMatchesPoly<testing::Matcher<Value>>122ExpectScalar(const Scalar &expected_scalar,123 Value::ContextType context_type = Value::ContextType::Invalid);124 125/// Helper that combines GetScalar with ExpectScalar to get a precise scalar.126/// Use it on an Expected<Value> like this:127/// EXPECT_THAT_EXPECTED(result, ExpectScalar(8, 42, true));128llvm::detail::ValueMatchesPoly<testing::Matcher<Value>>129ExpectScalar(unsigned bits, uint64_t value, bool sign,130 Value::ContextType context_type = Value::ContextType::Invalid);131 132/// Helper that combines IsLoadAddress with llvm::HasValue for Expected<Value>.133/// Use it on an Expected<Value> like this:134/// EXPECT_THAT_EXPECTED(result, ExpectLoadAddress(0x1000));135llvm::detail::ValueMatchesPoly<testing::Matcher<Value>> ExpectLoadAddress(136 const Scalar &expected_address,137 Value::ContextType context_type = Value::ContextType::Invalid);138 139/// Helper that combines IsFileAddress with llvm::HasValue for Expected<Value>.140/// Use it on an Expected<Value> like this:141/// EXPECT_THAT_EXPECTED(result, ExpectFileAddress(Scalar(0x2000)));142llvm::detail::ValueMatchesPoly<testing::Matcher<Value>> ExpectFileAddress(143 const Scalar &expected_address,144 Value::ContextType context_type = Value::ContextType::Invalid);145 146/// Helper that combines IsHostValue with llvm::HasValue for Expected<Value>.147/// Use it on an Expected<Value> like this:148/// EXPECT_THAT_EXPECTED(result, ExpectHostAddress({0x11, 0x22}));149llvm::detail::ValueMatchesPoly<testing::Matcher<Value>> ExpectHostAddress(150 const std::vector<uint8_t> &expected_bytes,151 Value::ContextType context_type = Value::ContextType::Invalid);152 153} // namespace lldb_private154 155#endif // LLDB_UNITTESTS_EXPRESSION_VALUEMATCHER_H156