1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_TESTING_GMOCK_SUPPORT_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_TESTING_GMOCK_SUPPORT_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <cmath>
9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <cstring>
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <string>
11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "testing/gmock/include/gmock/gmock.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace testing {
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename T>
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Capture {
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Capture() : value_(), has_value_(false) {}
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const T& value() const { return value_; }
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool has_value() const { return has_value_; }
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetValue(const T& value) {
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!has_value());
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ = value;
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_value_ = true;
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  T value_;
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool has_value_;
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename T>
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CaptureEqMatcher : public MatcherInterface<T> {
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit CaptureEqMatcher(Capture<T>* capture) : capture_(capture) {}
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void DescribeTo(std::ostream* os) const {
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *os << "captured by " << static_cast<const void*>(capture_);
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (capture_->has_value()) *os << " which has value " << capture_->value();
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual bool MatchAndExplain(T value, MatchResultListener* listener) const {
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!capture_->has_value()) {
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      capture_->SetValue(value);
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return true;
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (value != capture_->value()) {
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *listener << "which is not equal to " << capture_->value();
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return false;
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return true;
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Capture<T>* capture_;
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Creates a polymorphic matcher that matches anything whose bit representation
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// is equal to that of {x}.
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMATCHER_P(BitEq, x, std::string(negation ? "isn't" : "is") +
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        " bitwise equal to " + PrintToString(x)) {
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static_assert(sizeof(x) == sizeof(arg), "Size mismatch");
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return std::memcmp(&arg, &x, sizeof(x)) == 0;
73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CaptureEq(capture) captures the value passed in during matching as long as it
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// is unset, and once set, compares the value for equality with the argument.
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename T>
79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierinline Matcher<T> CaptureEq(Capture<T>* capture) {
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return MakeMatcher(new internal::CaptureEqMatcher<T>(capture));
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Creates a polymorphic matcher that matches any floating point NaN value.
85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMATCHER(IsNaN, std::string(negation ? "isn't" : "is") + " not a number") {
86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return std::isnan(arg);
87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace testing
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_TESTING_GMOCK_SUPPORT_H_
92