aboutsummaryrefslogtreecommitdiffstats
path: root/3rdparty/googletest/googlemock/src/gmock-internal-utils.cc
blob: fb5308018a712d7478b36a405e74e779db2a7250 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)

// Google Mock - a framework for writing C++ mock classes.
//
// This file defines some utilities useful for implementing Google
// Mock.  They are subject to change without notice, so please DO NOT
// USE THEM IN USER CODE.

#include "gmock/internal/gmock-internal-utils.h"

#include <ctype.h>
#include <ostream>  // NOLINT
#include <string>
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"

namespace testing {
namespace internal {

// Converts an identifier name to a space-separated list of lower-case
// words.  Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
// treated as one word.  For example, both "FooBar123" and
// "foo_bar_123" are converted to "foo bar 123".
GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) {
  string result;
  char prev_char = '\0';
  for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) {
    // We don't care about the current locale as the input is
    // guaranteed to be a valid C++ identifier name.
    const bool starts_new_word = IsUpper(*p) ||
        (!IsAlpha(prev_char) && IsLower(*p)) ||
        (!IsDigit(prev_char) && IsDigit(*p));

    if (IsAlNum(*p)) {
      if (starts_new_word && result != "")
        result += ' ';
      result += ToLower(*p);
    }
  }
  return result;
}

// This class reports Google Mock failures as Google Test failures.  A
// user can define another class in a similar fashion if he intends to
// use Google Mock with a testing framework other than Google Test.
class GoogleTestFailureReporter : public FailureReporterInterface {
 public:
  virtual void ReportFailure(FailureType type, const char* file, int line,
                             const string& message) {
    AssertHelper(type == kFatal ?
                 TestPartResult::kFatalFailure :
                 TestPartResult::kNonFatalFailure,
                 file,
                 line,
                 message.c_str()) = Message();
    if (type == kFatal) {
      posix::Abort();
    }
  }
};

// Returns the global failure reporter.  Will create a
// GoogleTestFailureReporter and return it the first time called.
GTEST_API_ FailureReporterInterface* GetFailureReporter() {
  // Points to the global failure reporter used by Google Mock.  gcc
  // guarantees that the following use of failure_reporter is
  // thread-safe.  We may need to add additional synchronization to
  // protect failure_reporter if we port Google Mock to other
  // compilers.
  static FailureReporterInterface* const failure_reporter =
      new GoogleTestFailureReporter();
  return failure_reporter;
}

// Protects global resources (stdout in particular) used by Log().
static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);

// Returns true iff a log with the given severity is visible according
// to the --gmock_verbose flag.
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
  if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
    // Always show the log if --gmock_verbose=info.
    return true;
  } else if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
    // Always hide it if --gmock_verbose=error.
    return false;
  } else {
    // If --gmock_verbose is neither "info" nor "error", we treat it
    // as "warning" (its default value).
    return severity == kWarning;
  }
}

// Prints the given message to stdout iff 'severity' >= the level
// specified by the --gmock_verbose flag.  If stack_frames_to_skip >=
// 0, also prints the stack trace excluding the top
// stack_frames_to_skip frames.  In opt mode, any positive
// stack_frames_to_skip is treated as 0, since we don't know which
// function calls will be inlined by the compiler and need to be
// conservative.
GTEST_API_ void Log(LogSeverity severity,
                    const string& message,
                    int stack_frames_to_skip) {
  if (!LogIsVisible(severity))
    return;

  // Ensures that logs from different threads don't interleave.
  MutexLock l(&g_log_mutex);

  // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a
  // macro.

  if (severity == kWarning) {
    // Prints a GMOCK WARNING marker to make the warnings easily searchable.
    std::cout << "\nGMOCK WARNING:";
  }
  // Pre-pends a new-line to message if it doesn't start with one.
  if (message.empty() || message[0] != '\n') {
    std::cout << "\n";
  }
  std::cout << message;
  if (stack_frames_to_skip >= 0) {
#ifdef NDEBUG
    // In opt mode, we have to be conservative and skip no stack frame.
    const int actual_to_skip = 0;
#else
    // In dbg mode, we can do what the caller tell us to do (plus one
    // for skipping this function's stack frame).
    const int actual_to_skip = stack_frames_to_skip + 1;
#endif  // NDEBUG

    // Appends a new-line to message if it doesn't end with one.
    if (!message.empty() && *message.rbegin() != '\n') {
      std::cout << "\n";
    }
    std::cout << "Stack trace:\n"
         << ::testing::internal::GetCurrentOsStackTraceExceptTop(
             ::testing::UnitTest::GetInstance(), actual_to_skip);
  }
  std::cout << ::std::flush;
}

}  // namespace internal
}  // namespace testing
bool Matches(MyType value) const { // Returns true if value matches. return value.GetFoo() > 5; } virtual void ExplainMatchResultTo(MyType value, ::std::ostream* os) const { // Prints some helpful information to os to help // a user understand why value matches (or doesn't match). *os << "the Foo property is " << value.GetFoo(); } ... }; ``` you should move the logic of `ExplainMatchResultTo()` into `MatchAndExplain()`, using the `MatchResultListener` argument where the `::std::ostream` was used: ``` // New matcher definition that works with the latest Google Mock. using ::testing::MatcherInterface; using ::testing::MatchResultListener; ... class MyWonderfulMatcher : public MatcherInterface<MyType> { public: ... virtual bool MatchAndExplain(MyType value, MatchResultListener* listener) const { // Returns true if value matches. *listener << "the Foo property is " << value.GetFoo(); return value.GetFoo() > 5; } ... }; ``` If your matcher is defined using `MakePolymorphicMatcher()`: ``` // Old matcher definition that doesn't work with the latest // Google Mock. using ::testing::MakePolymorphicMatcher; ... class MyGreatMatcher { public: ... bool Matches(MyType value) const { // Returns true if value matches. return value.GetBar() < 42; } ... }; ... MakePolymorphicMatcher(MyGreatMatcher()) ... ``` you should rename the `Matches()` method to `MatchAndExplain()` and add a `MatchResultListener*` argument (the same as what you need to do for matchers defined by implementing `MatcherInterface`): ``` // New matcher definition that works with the latest Google Mock. using ::testing::MakePolymorphicMatcher; using ::testing::MatchResultListener; ... class MyGreatMatcher { public: ... bool MatchAndExplain(MyType value, MatchResultListener* listener) const { // Returns true if value matches. return value.GetBar() < 42; } ... }; ... MakePolymorphicMatcher(MyGreatMatcher()) ... ``` If your polymorphic matcher uses `ExplainMatchResultTo()` for better failure messages: ``` // Old matcher definition that doesn't work with the latest // Google Mock. using ::testing::MakePolymorphicMatcher; ... class MyGreatMatcher { public: ... bool Matches(MyType value) const { // Returns true if value matches. return value.GetBar() < 42; } ... }; void ExplainMatchResultTo(const MyGreatMatcher& matcher, MyType value, ::std::ostream* os) { // Prints some helpful information to os to help // a user understand why value matches (or doesn't match). *os << "the Bar property is " << value.GetBar(); } ... MakePolymorphicMatcher(MyGreatMatcher()) ... ``` you'll need to move the logic inside `ExplainMatchResultTo()` to `MatchAndExplain()`: ``` // New matcher definition that works with the latest Google Mock. using ::testing::MakePolymorphicMatcher; using ::testing::MatchResultListener; ... class MyGreatMatcher { public: ... bool MatchAndExplain(MyType value, MatchResultListener* listener) const { // Returns true if value matches. *listener << "the Bar property is " << value.GetBar(); return value.GetBar() < 42; } ... }; ... MakePolymorphicMatcher(MyGreatMatcher()) ... ``` For more information, you can read these [two](CookBook.md#writing-new-monomorphic-matchers) [recipes](CookBook.md#writing-new-polymorphic-matchers) from the cookbook. As always, you are welcome to post questions on `googlemock@googlegroups.com` if you need any help. ## When using Google Mock, do I have to use Google Test as the testing framework? I have my favorite testing framework and don't want to switch. ## Google Mock works out of the box with Google Test. However, it's easy to configure it to work with any testing framework of your choice. [Here](ForDummies.md#using-google-mock-with-any-testing-framework) is how. ## How am I supposed to make sense of these horrible template errors? ## If you are confused by the compiler errors gcc threw at you, try consulting the _Google Mock Doctor_ tool first. What it does is to scan stdin for gcc error messages, and spit out diagnoses on the problems (we call them diseases) your code has. To "install", run command: ``` alias gmd='<path to googlemock>/scripts/gmock_doctor.py' ``` To use it, do: ``` <your-favorite-build-command> <your-test> 2>&1 | gmd ``` For example: ``` make my_test 2>&1 | gmd ``` Or you can run `gmd` and copy-n-paste gcc's error messages to it. ## Can I mock a variadic function? ## You cannot mock a variadic function (i.e. a function taking ellipsis (`...`) arguments) directly in Google Mock. The problem is that in general, there is _no way_ for a mock object to know how many arguments are passed to the variadic method, and what the arguments' types are. Only the _author of the base class_ knows the protocol, and we cannot look into his head. Therefore, to mock such a function, the _user_ must teach the mock object how to figure out the number of arguments and their types. One way to do it is to provide overloaded versions of the function. Ellipsis arguments are inherited from C and not really a C++ feature. They are unsafe to use and don't work with arguments that have constructors or destructors. Therefore we recommend to avoid them in C++ as much as possible. ## MSVC gives me warning C4301 or C4373 when I define a mock method with a const parameter. Why? ## If you compile this using Microsoft Visual C++ 2005 SP1: ``` class Foo { ... virtual void Bar(const int i) = 0; }; class MockFoo : public Foo { ... MOCK_METHOD1(Bar, void(const int i)); }; ``` You may get the following warning: ``` warning C4301: 'MockFoo::Bar': overriding virtual function only differs from 'Foo::Bar' by const/volatile qualifier ``` This is a MSVC bug. The same code compiles fine with gcc ,for example. If you use Visual C++ 2008 SP1, you would get the warning: ``` warning C4373: 'MockFoo::Bar': virtual function overrides 'Foo::Bar', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers ``` In C++, if you _declare_ a function with a `const` parameter, the `const` modifier is _ignored_. Therefore, the `Foo` base class above is equivalent to: ``` class Foo { ... virtual void Bar(int i) = 0; // int or const int? Makes no difference. }; ``` In fact, you can _declare_ Bar() with an `int` parameter, and _define_ it with a `const int` parameter. The compiler will still match them up. Since making a parameter `const` is meaningless in the method _declaration_, we recommend to remove it in both `Foo` and `MockFoo`. That should workaround the VC bug. Note that we are talking about the _top-level_ `const` modifier here. If the function parameter is passed by pointer or reference, declaring the _pointee_ or _referee_ as `const` is still meaningful. For example, the following two declarations are _not_ equivalent: ``` void Bar(int* p); // Neither p nor *p is const. void Bar(const int* p); // p is not const, but *p is. ``` ## I have a huge mock class, and Microsoft Visual C++ runs out of memory when compiling it. What can I do? ## We've noticed that when the `/clr` compiler flag is used, Visual C++ uses 5~6 times as much memory when compiling a mock class. We suggest to avoid `/clr` when compiling native C++ mocks. ## I can't figure out why Google Mock thinks my expectations are not satisfied. What should I do? ## You might want to run your test with `--gmock_verbose=info`. This flag lets Google Mock print a trace of every mock function call it receives. By studying the trace, you'll gain insights on why the expectations you set are not met. ## How can I assert that a function is NEVER called? ## ``` EXPECT_CALL(foo, Bar(_)) .Times(0); ``` ## I have a failed test where Google Mock tells me TWICE that a particular expectation is not satisfied. Isn't this redundant? ## When Google Mock detects a failure, it prints relevant information (the mock function arguments, the state of relevant expectations, and etc) to help the user debug. If another failure is detected, Google Mock will do the same, including printing the state of relevant expectations. Sometimes an expectation's state didn't change between two failures, and you'll see the same description of the state twice. They are however _not_ redundant, as they refer to _different points in time_. The fact they are the same _is_ interesting information. ## I get a heap check failure when using a mock object, but using a real object is fine. What can be wrong? ## Does the class (hopefully a pure interface) you are mocking have a virtual destructor? Whenever you derive from a base class, make sure its destructor is virtual. Otherwise Bad Things will happen. Consider the following code: ``` class Base { public: // Not virtual, but should be. ~Base() { ... } ... }; class Derived : public Base { public: ... private: std::string value_; }; ... Base* p = new Derived; ... delete p; // Surprise! ~Base() will be called, but ~Derived() will not // - value_ is leaked. ``` By changing `~Base()` to virtual, `~Derived()` will be correctly called when `delete p` is executed, and the heap checker will be happy. ## The "newer expectations override older ones" rule makes writing expectations awkward. Why does Google Mock do that? ## When people complain about this, often they are referring to code like: ``` // foo.Bar() should be called twice, return 1 the first time, and return // 2 the second time. However, I have to write the expectations in the // reverse order. This sucks big time!!! EXPECT_CALL(foo, Bar()) .WillOnce(Return(2)) .RetiresOnSaturation(); EXPECT_CALL(foo, Bar()) .WillOnce(Return(1)) .RetiresOnSaturation(); ``` The problem is that they didn't pick the **best** way to express the test's intent. By default, expectations don't have to be matched in _any_ particular order. If you want them to match in a certain order, you need to be explicit. This is Google Mock's (and jMock's) fundamental philosophy: it's easy to accidentally over-specify your tests, and we want to make it harder to do so. There are two better ways to write the test spec. You could either put the expectations in sequence: ```