Updated gMock to 1.7.0
This change updates gMock to the new release, 1.7.0. This is necessary for Android, as Android Master has updated their gTest to 1.7.0, and we must always use the matching version of gMock. This should not break any existing tests, as 1.7.0 is backwards-compatible with 1.6.0 code in nearly all cases. There are a few bugfixes around being too generous with type coercion in EXPECT_THAT() and ASSERT_THAT() that could break code that was accepted by the compiler before but was never technically safe. For a full list of changes, including all the awesome new matchers you can now use in your tests, see CHANGES, which is included from gMock unchanged. For a full list of modifications made to allow this to work on Android Master, see the updated README.android. No changes to the GYP files were necessary as part of this upgrade. Change-Id: Ib1445044e78c9fe0cf16031d544577d65ebbf6df
This commit is contained in:
@@ -1,70 +1,37 @@
|
||||
# Copyright 2013 Google Inc. All Rights Reserved.
|
||||
# Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
# gMock builds 2 libraries: libgmock and libgmock_main. libgmock
|
||||
# contains most of the code and libgmock_main just
|
||||
# provide a common main to run the test. (i.e. If you link against
|
||||
# libgmock_main you shouldn't provide a main() entry point.)
|
||||
# gMock builds 2 libraries: libgmock and libgmock_main. libgmock contains most
|
||||
# of the code and libgmock_main just provides a common main to run the test.
|
||||
# (i.e. If you link against libgmock_main you shouldn't provide a main() entry
|
||||
# point. If you link against libgmock_main, do not also link against
|
||||
# libgtest_main, as libgmock_main is a superset of libgtest_main, and they will
|
||||
# conflict in subtle ways.)
|
||||
#
|
||||
# We build these 2 libraries for the target device and for the host if
|
||||
# it is running linux and using ASTL.
|
||||
# We build these 2 libraries for the target device only.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
libgmock_target_includes := \
|
||||
$(LOCAL_PATH)/.. \
|
||||
$(LOCAL_PATH)/../include \
|
||||
external/gtest/include \
|
||||
$(TOP)/external/gtest/include \
|
||||
|
||||
libgmock_host_includes := \
|
||||
$(LOCAL_PATH)/.. \
|
||||
$(LOCAL_PATH)/../include \
|
||||
external/gtest/include \
|
||||
$(TOP)/external/gtest/include \
|
||||
|
||||
#######################################################################
|
||||
# gmock lib host
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_CPP_EXTENSION := .cc
|
||||
|
||||
LOCAL_SRC_FILES := gmock-all.cc
|
||||
|
||||
LOCAL_C_INCLUDES := $(libgmock_host_includes)
|
||||
|
||||
LOCAL_CFLAGS += -O0
|
||||
|
||||
LOCAL_MODULE := libgmock_host
|
||||
|
||||
include $(BUILD_HOST_STATIC_LIBRARY)
|
||||
|
||||
#######################################################################
|
||||
# gmock_main lib host
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_CPP_EXTENSION := .cc
|
||||
|
||||
LOCAL_SRC_FILES := gmock_main.cc
|
||||
|
||||
LOCAL_C_INCLUDES := $(libgmock_host_includes)
|
||||
|
||||
LOCAL_CFLAGS += -O0
|
||||
|
||||
LOCAL_MODULE := libgmock_main_host
|
||||
|
||||
include $(BUILD_HOST_STATIC_LIBRARY)
|
||||
libgmock_cflags := \
|
||||
-DGTEST_HAS_TR1_TUPLE \
|
||||
-DGTEST_USE_OWN_TR1_TUPLE \
|
||||
-Wno-missing-field-initializers \
|
||||
|
||||
#######################################################################
|
||||
# gmock lib target
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
ifeq ($(TARGET_ARCH), arm)
|
||||
LOCAL_SDK_VERSION := 8
|
||||
else
|
||||
# NDK support of other archs (ie. x86 and mips) are only available after android-9
|
||||
LOCAL_SDK_VERSION := 9
|
||||
endif
|
||||
LOCAL_SDK_VERSION := 9
|
||||
|
||||
LOCAL_NDK_STL_VARIANT := stlport_static
|
||||
|
||||
@@ -74,6 +41,8 @@ LOCAL_SRC_FILES := gmock-all.cc
|
||||
|
||||
LOCAL_C_INCLUDES := $(libgmock_target_includes)
|
||||
|
||||
LOCAL_CFLAGS += $(libgmock_cflags)
|
||||
|
||||
LOCAL_MODULE := libgmock
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
@@ -83,12 +52,7 @@ include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
ifeq ($(TARGET_ARCH), arm)
|
||||
LOCAL_SDK_VERSION := 8
|
||||
else
|
||||
# NDK support of other archs (ie. x86 and mips) are only available after android-9
|
||||
LOCAL_SDK_VERSION := 9
|
||||
endif
|
||||
LOCAL_SDK_VERSION := 9
|
||||
|
||||
LOCAL_NDK_STL_VARIANT := stlport_static
|
||||
|
||||
@@ -98,6 +62,8 @@ LOCAL_SRC_FILES := gmock_main.cc
|
||||
|
||||
LOCAL_C_INCLUDES := $(libgmock_target_includes)
|
||||
|
||||
LOCAL_CFLAGS += $(libgmock_cflags)
|
||||
|
||||
LOCAL_MODULE := libgmock_main
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
@@ -75,7 +75,7 @@ class BetweenCardinalityImpl : public CardinalityInterface {
|
||||
virtual int ConservativeUpperBound() const { return max_; }
|
||||
|
||||
virtual bool IsSatisfiedByCallCount(int call_count) const {
|
||||
return min_ <= call_count && call_count <= max_ ;
|
||||
return min_ <= call_count && call_count <= max_;
|
||||
}
|
||||
|
||||
virtual bool IsSaturatedByCallCount(int call_count) const {
|
||||
@@ -83,6 +83,7 @@ class BetweenCardinalityImpl : public CardinalityInterface {
|
||||
}
|
||||
|
||||
virtual void DescribeTo(::std::ostream* os) const;
|
||||
|
||||
private:
|
||||
const int min_;
|
||||
const int max_;
|
||||
@@ -136,20 +137,20 @@ void Cardinality::DescribeActualCallCountTo(int actual_call_count,
|
||||
}
|
||||
|
||||
// Creates a cardinality that allows at least n calls.
|
||||
Cardinality AtLeast(int n) { return Between(n, INT_MAX); }
|
||||
GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); }
|
||||
|
||||
// Creates a cardinality that allows at most n calls.
|
||||
Cardinality AtMost(int n) { return Between(0, n); }
|
||||
GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); }
|
||||
|
||||
// Creates a cardinality that allows any number of calls.
|
||||
Cardinality AnyNumber() { return AtLeast(0); }
|
||||
GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); }
|
||||
|
||||
// Creates a cardinality that allows between min and max calls.
|
||||
Cardinality Between(int min, int max) {
|
||||
GTEST_API_ Cardinality Between(int min, int max) {
|
||||
return Cardinality(new BetweenCardinalityImpl(min, max));
|
||||
}
|
||||
|
||||
// Creates a cardinality that allows exactly n calls.
|
||||
Cardinality Exactly(int n) { return Between(n, n); }
|
||||
GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); }
|
||||
|
||||
} // namespace testing
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace internal {
|
||||
// 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".
|
||||
string ConvertIdentifierNameToWords(const char* id_name) {
|
||||
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++)) {
|
||||
@@ -77,13 +77,13 @@ class GoogleTestFailureReporter : public FailureReporterInterface {
|
||||
public:
|
||||
virtual void ReportFailure(FailureType type, const char* file, int line,
|
||||
const string& message) {
|
||||
AssertHelper(type == FATAL ?
|
||||
AssertHelper(type == kFatal ?
|
||||
TestPartResult::kFatalFailure :
|
||||
TestPartResult::kNonFatalFailure,
|
||||
file,
|
||||
line,
|
||||
message.c_str()) = Message();
|
||||
if (type == FATAL) {
|
||||
if (type == kFatal) {
|
||||
posix::Abort();
|
||||
}
|
||||
}
|
||||
@@ -91,7 +91,7 @@ class GoogleTestFailureReporter : public FailureReporterInterface {
|
||||
|
||||
// Returns the global failure reporter. Will create a
|
||||
// GoogleTestFailureReporter and return it the first time called.
|
||||
FailureReporterInterface* GetFailureReporter() {
|
||||
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
|
||||
@@ -107,7 +107,7 @@ 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.
|
||||
bool LogIsVisible(LogSeverity severity) {
|
||||
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
|
||||
if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
|
||||
// Always show the log if --gmock_verbose=info.
|
||||
return true;
|
||||
@@ -117,7 +117,7 @@ bool LogIsVisible(LogSeverity severity) {
|
||||
} else {
|
||||
// If --gmock_verbose is neither "info" nor "error", we treat it
|
||||
// as "warning" (its default value).
|
||||
return severity == WARNING;
|
||||
return severity == kWarning;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,8 +128,9 @@ bool LogIsVisible(LogSeverity severity) {
|
||||
// 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.
|
||||
void Log(LogSeverity severity, const string& message,
|
||||
int stack_frames_to_skip) {
|
||||
GTEST_API_ void Log(LogSeverity severity,
|
||||
const string& message,
|
||||
int stack_frames_to_skip) {
|
||||
if (!LogIsVisible(severity))
|
||||
return;
|
||||
|
||||
@@ -139,7 +140,7 @@ void Log(LogSeverity severity, const string& message,
|
||||
// "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a
|
||||
// macro.
|
||||
|
||||
if (severity == WARNING) {
|
||||
if (severity == kWarning) {
|
||||
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
|
||||
std::cout << "\nGMOCK WARNING:";
|
||||
}
|
||||
|
||||
@@ -63,11 +63,46 @@ Matcher<internal::string>::Matcher(const char* s) {
|
||||
*this = Eq(internal::string(s));
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STRING_PIECE_
|
||||
// Constructs a matcher that matches a const StringPiece& whose value is
|
||||
// equal to s.
|
||||
Matcher<const StringPiece&>::Matcher(const internal::string& s) {
|
||||
*this = Eq(s);
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a const StringPiece& whose value is
|
||||
// equal to s.
|
||||
Matcher<const StringPiece&>::Matcher(const char* s) {
|
||||
*this = Eq(internal::string(s));
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a const StringPiece& whose value is
|
||||
// equal to s.
|
||||
Matcher<const StringPiece&>::Matcher(StringPiece s) {
|
||||
*this = Eq(s.ToString());
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a StringPiece whose value is equal to s.
|
||||
Matcher<StringPiece>::Matcher(const internal::string& s) {
|
||||
*this = Eq(s);
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a StringPiece whose value is equal to s.
|
||||
Matcher<StringPiece>::Matcher(const char* s) {
|
||||
*this = Eq(internal::string(s));
|
||||
}
|
||||
|
||||
// Constructs a matcher that matches a StringPiece whose value is equal to s.
|
||||
Matcher<StringPiece>::Matcher(StringPiece s) {
|
||||
*this = Eq(s.ToString());
|
||||
}
|
||||
#endif // GTEST_HAS_STRING_PIECE_
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Joins a vector of strings as if they are fields of a tuple; returns
|
||||
// the joined string.
|
||||
string JoinAsTuple(const Strings& fields) {
|
||||
GTEST_API_ string JoinAsTuple(const Strings& fields) {
|
||||
switch (fields.size()) {
|
||||
case 0:
|
||||
return "";
|
||||
@@ -89,13 +124,375 @@ string JoinAsTuple(const Strings& fields) {
|
||||
// 'negation' is false; otherwise returns the description of the
|
||||
// negation of the matcher. 'param_values' contains a list of strings
|
||||
// that are the print-out of the matcher's parameters.
|
||||
string FormatMatcherDescription(bool negation, const char* matcher_name,
|
||||
const Strings& param_values) {
|
||||
GTEST_API_ string FormatMatcherDescription(bool negation,
|
||||
const char* matcher_name,
|
||||
const Strings& param_values) {
|
||||
string result = ConvertIdentifierNameToWords(matcher_name);
|
||||
if (param_values.size() >= 1)
|
||||
result += " " + JoinAsTuple(param_values);
|
||||
return negation ? "not (" + result + ")" : result;
|
||||
}
|
||||
|
||||
// FindMaxBipartiteMatching and its helper class.
|
||||
//
|
||||
// Uses the well-known Ford-Fulkerson max flow method to find a maximum
|
||||
// bipartite matching. Flow is considered to be from left to right.
|
||||
// There is an implicit source node that is connected to all of the left
|
||||
// nodes, and an implicit sink node that is connected to all of the
|
||||
// right nodes. All edges have unit capacity.
|
||||
//
|
||||
// Neither the flow graph nor the residual flow graph are represented
|
||||
// explicitly. Instead, they are implied by the information in 'graph' and
|
||||
// a vector<int> called 'left_' whose elements are initialized to the
|
||||
// value kUnused. This represents the initial state of the algorithm,
|
||||
// where the flow graph is empty, and the residual flow graph has the
|
||||
// following edges:
|
||||
// - An edge from source to each left_ node
|
||||
// - An edge from each right_ node to sink
|
||||
// - An edge from each left_ node to each right_ node, if the
|
||||
// corresponding edge exists in 'graph'.
|
||||
//
|
||||
// When the TryAugment() method adds a flow, it sets left_[l] = r for some
|
||||
// nodes l and r. This induces the following changes:
|
||||
// - The edges (source, l), (l, r), and (r, sink) are added to the
|
||||
// flow graph.
|
||||
// - The same three edges are removed from the residual flow graph.
|
||||
// - The reverse edges (l, source), (r, l), and (sink, r) are added
|
||||
// to the residual flow graph, which is a directional graph
|
||||
// representing unused flow capacity.
|
||||
//
|
||||
// When the method augments a flow (moving left_[l] from some r1 to some
|
||||
// other r2), this can be thought of as "undoing" the above steps with
|
||||
// respect to r1 and "redoing" them with respect to r2.
|
||||
//
|
||||
// It bears repeating that the flow graph and residual flow graph are
|
||||
// never represented explicitly, but can be derived by looking at the
|
||||
// information in 'graph' and in left_.
|
||||
//
|
||||
// As an optimization, there is a second vector<int> called right_ which
|
||||
// does not provide any new information. Instead, it enables more
|
||||
// efficient queries about edges entering or leaving the right-side nodes
|
||||
// of the flow or residual flow graphs. The following invariants are
|
||||
// maintained:
|
||||
//
|
||||
// left[l] == kUnused or right[left[l]] == l
|
||||
// right[r] == kUnused or left[right[r]] == r
|
||||
//
|
||||
// . [ source ] .
|
||||
// . ||| .
|
||||
// . ||| .
|
||||
// . ||\--> left[0]=1 ---\ right[0]=-1 ----\ .
|
||||
// . || | | .
|
||||
// . |\---> left[1]=-1 \--> right[1]=0 ---\| .
|
||||
// . | || .
|
||||
// . \----> left[2]=2 ------> right[2]=2 --\|| .
|
||||
// . ||| .
|
||||
// . elements matchers vvv .
|
||||
// . [ sink ] .
|
||||
//
|
||||
// See Also:
|
||||
// [1] Cormen, et al (2001). "Section 26.2: The Ford–Fulkerson method".
|
||||
// "Introduction to Algorithms (Second ed.)", pp. 651–664.
|
||||
// [2] "Ford–Fulkerson algorithm", Wikipedia,
|
||||
// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm'
|
||||
class MaxBipartiteMatchState {
|
||||
public:
|
||||
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
|
||||
: graph_(&graph),
|
||||
left_(graph_->LhsSize(), kUnused),
|
||||
right_(graph_->RhsSize(), kUnused) {
|
||||
}
|
||||
|
||||
// Returns the edges of a maximal match, each in the form {left, right}.
|
||||
ElementMatcherPairs Compute() {
|
||||
// 'seen' is used for path finding { 0: unseen, 1: seen }.
|
||||
::std::vector<char> seen;
|
||||
// Searches the residual flow graph for a path from each left node to
|
||||
// the sink in the residual flow graph, and if one is found, add flow
|
||||
// to the graph. It's okay to search through the left nodes once. The
|
||||
// edge from the implicit source node to each previously-visited left
|
||||
// node will have flow if that left node has any path to the sink
|
||||
// whatsoever. Subsequent augmentations can only add flow to the
|
||||
// network, and cannot take away that previous flow unit from the source.
|
||||
// Since the source-to-left edge can only carry one flow unit (or,
|
||||
// each element can be matched to only one matcher), there is no need
|
||||
// to visit the left nodes more than once looking for augmented paths.
|
||||
// The flow is known to be possible or impossible by looking at the
|
||||
// node once.
|
||||
for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) {
|
||||
// Reset the path-marking vector and try to find a path from
|
||||
// source to sink starting at the left_[ilhs] node.
|
||||
GTEST_CHECK_(left_[ilhs] == kUnused)
|
||||
<< "ilhs: " << ilhs << ", left_[ilhs]: " << left_[ilhs];
|
||||
// 'seen' initialized to 'graph_->RhsSize()' copies of 0.
|
||||
seen.assign(graph_->RhsSize(), 0);
|
||||
TryAugment(ilhs, &seen);
|
||||
}
|
||||
ElementMatcherPairs result;
|
||||
for (size_t ilhs = 0; ilhs < left_.size(); ++ilhs) {
|
||||
size_t irhs = left_[ilhs];
|
||||
if (irhs == kUnused) continue;
|
||||
result.push_back(ElementMatcherPair(ilhs, irhs));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
static const size_t kUnused = static_cast<size_t>(-1);
|
||||
|
||||
// Perform a depth-first search from left node ilhs to the sink. If a
|
||||
// path is found, flow is added to the network by linking the left and
|
||||
// right vector elements corresponding each segment of the path.
|
||||
// Returns true if a path to sink was found, which means that a unit of
|
||||
// flow was added to the network. The 'seen' vector elements correspond
|
||||
// to right nodes and are marked to eliminate cycles from the search.
|
||||
//
|
||||
// Left nodes will only be explored at most once because they
|
||||
// are accessible from at most one right node in the residual flow
|
||||
// graph.
|
||||
//
|
||||
// Note that left_[ilhs] is the only element of left_ that TryAugment will
|
||||
// potentially transition from kUnused to another value. Any other
|
||||
// left_ element holding kUnused before TryAugment will be holding it
|
||||
// when TryAugment returns.
|
||||
//
|
||||
bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {
|
||||
for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {
|
||||
if ((*seen)[irhs])
|
||||
continue;
|
||||
if (!graph_->HasEdge(ilhs, irhs))
|
||||
continue;
|
||||
// There's an available edge from ilhs to irhs.
|
||||
(*seen)[irhs] = 1;
|
||||
// Next a search is performed to determine whether
|
||||
// this edge is a dead end or leads to the sink.
|
||||
//
|
||||
// right_[irhs] == kUnused means that there is residual flow from
|
||||
// right node irhs to the sink, so we can use that to finish this
|
||||
// flow path and return success.
|
||||
//
|
||||
// Otherwise there is residual flow to some ilhs. We push flow
|
||||
// along that path and call ourselves recursively to see if this
|
||||
// ultimately leads to sink.
|
||||
if (right_[irhs] == kUnused || TryAugment(right_[irhs], seen)) {
|
||||
// Add flow from left_[ilhs] to right_[irhs].
|
||||
left_[ilhs] = irhs;
|
||||
right_[irhs] = ilhs;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const MatchMatrix* graph_; // not owned
|
||||
// Each element of the left_ vector represents a left hand side node
|
||||
// (i.e. an element) and each element of right_ is a right hand side
|
||||
// node (i.e. a matcher). The values in the left_ vector indicate
|
||||
// outflow from that node to a node on the the right_ side. The values
|
||||
// in the right_ indicate inflow, and specify which left_ node is
|
||||
// feeding that right_ node, if any. For example, left_[3] == 1 means
|
||||
// there's a flow from element #3 to matcher #1. Such a flow would also
|
||||
// be redundantly represented in the right_ vector as right_[1] == 3.
|
||||
// Elements of left_ and right_ are either kUnused or mutually
|
||||
// referent. Mutually referent means that left_[right_[i]] = i and
|
||||
// right_[left_[i]] = i.
|
||||
::std::vector<size_t> left_;
|
||||
::std::vector<size_t> right_;
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(MaxBipartiteMatchState);
|
||||
};
|
||||
|
||||
const size_t MaxBipartiteMatchState::kUnused;
|
||||
|
||||
GTEST_API_ ElementMatcherPairs
|
||||
FindMaxBipartiteMatching(const MatchMatrix& g) {
|
||||
return MaxBipartiteMatchState(g).Compute();
|
||||
}
|
||||
|
||||
static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
|
||||
::std::ostream* stream) {
|
||||
typedef ElementMatcherPairs::const_iterator Iter;
|
||||
::std::ostream& os = *stream;
|
||||
os << "{";
|
||||
const char *sep = "";
|
||||
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
|
||||
os << sep << "\n ("
|
||||
<< "element #" << it->first << ", "
|
||||
<< "matcher #" << it->second << ")";
|
||||
sep = ",";
|
||||
}
|
||||
os << "\n}";
|
||||
}
|
||||
|
||||
// Tries to find a pairing, and explains the result.
|
||||
GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
|
||||
MatchResultListener* listener) {
|
||||
ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
|
||||
|
||||
size_t max_flow = matches.size();
|
||||
bool result = (max_flow == matrix.RhsSize());
|
||||
|
||||
if (!result) {
|
||||
if (listener->IsInterested()) {
|
||||
*listener << "where no permutation of the elements can "
|
||||
"satisfy all matchers, and the closest match is "
|
||||
<< max_flow << " of " << matrix.RhsSize()
|
||||
<< " matchers with the pairings:\n";
|
||||
LogElementMatcherPairVec(matches, listener->stream());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (matches.size() > 1) {
|
||||
if (listener->IsInterested()) {
|
||||
const char *sep = "where:\n";
|
||||
for (size_t mi = 0; mi < matches.size(); ++mi) {
|
||||
*listener << sep << " - element #" << matches[mi].first
|
||||
<< " is matched by matcher #" << matches[mi].second;
|
||||
sep = ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MatchMatrix::NextGraph() {
|
||||
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
|
||||
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
|
||||
char& b = matched_[SpaceIndex(ilhs, irhs)];
|
||||
if (!b) {
|
||||
b = 1;
|
||||
return true;
|
||||
}
|
||||
b = 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MatchMatrix::Randomize() {
|
||||
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
|
||||
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
|
||||
char& b = matched_[SpaceIndex(ilhs, irhs)];
|
||||
b = static_cast<char>(rand() & 1); // NOLINT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string MatchMatrix::DebugString() const {
|
||||
::std::stringstream ss;
|
||||
const char *sep = "";
|
||||
for (size_t i = 0; i < LhsSize(); ++i) {
|
||||
ss << sep;
|
||||
for (size_t j = 0; j < RhsSize(); ++j) {
|
||||
ss << HasEdge(i, j);
|
||||
}
|
||||
sep = ";";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
|
||||
::std::ostream* os) const {
|
||||
if (matcher_describers_.empty()) {
|
||||
*os << "is empty";
|
||||
return;
|
||||
}
|
||||
if (matcher_describers_.size() == 1) {
|
||||
*os << "has " << Elements(1) << " and that element ";
|
||||
matcher_describers_[0]->DescribeTo(os);
|
||||
return;
|
||||
}
|
||||
*os << "has " << Elements(matcher_describers_.size())
|
||||
<< " and there exists some permutation of elements such that:\n";
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
||||
*os << sep << " - element #" << i << " ";
|
||||
matcher_describers_[i]->DescribeTo(os);
|
||||
sep = ", and\n";
|
||||
}
|
||||
}
|
||||
|
||||
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
|
||||
::std::ostream* os) const {
|
||||
if (matcher_describers_.empty()) {
|
||||
*os << "isn't empty";
|
||||
return;
|
||||
}
|
||||
if (matcher_describers_.size() == 1) {
|
||||
*os << "doesn't have " << Elements(1)
|
||||
<< ", or has " << Elements(1) << " that ";
|
||||
matcher_describers_[0]->DescribeNegationTo(os);
|
||||
return;
|
||||
}
|
||||
*os << "doesn't have " << Elements(matcher_describers_.size())
|
||||
<< ", or there exists no permutation of elements such that:\n";
|
||||
const char* sep = "";
|
||||
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
|
||||
*os << sep << " - element #" << i << " ";
|
||||
matcher_describers_[i]->DescribeTo(os);
|
||||
sep = ", and\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Checks that all matchers match at least one element, and that all
|
||||
// elements match at least one matcher. This enables faster matching
|
||||
// and better error reporting.
|
||||
// Returns false, writing an explanation to 'listener', if and only
|
||||
// if the success criteria are not met.
|
||||
bool UnorderedElementsAreMatcherImplBase::
|
||||
VerifyAllElementsAndMatchersAreMatched(
|
||||
const ::std::vector<string>& element_printouts,
|
||||
const MatchMatrix& matrix,
|
||||
MatchResultListener* listener) const {
|
||||
bool result = true;
|
||||
::std::vector<char> element_matched(matrix.LhsSize(), 0);
|
||||
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
|
||||
|
||||
for (size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) {
|
||||
for (size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) {
|
||||
char matched = matrix.HasEdge(ilhs, irhs);
|
||||
element_matched[ilhs] |= matched;
|
||||
matcher_matched[irhs] |= matched;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const char* sep =
|
||||
"where the following matchers don't match any elements:\n";
|
||||
for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {
|
||||
if (matcher_matched[mi])
|
||||
continue;
|
||||
result = false;
|
||||
if (listener->IsInterested()) {
|
||||
*listener << sep << "matcher #" << mi << ": ";
|
||||
matcher_describers_[mi]->DescribeTo(listener->stream());
|
||||
sep = ",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const char* sep =
|
||||
"where the following elements don't match any matchers:\n";
|
||||
const char* outer_sep = "";
|
||||
if (!result) {
|
||||
outer_sep = "\nand ";
|
||||
}
|
||||
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
|
||||
if (element_matched[ei])
|
||||
continue;
|
||||
result = false;
|
||||
if (listener->IsInterested()) {
|
||||
*listener << outer_sep << sep << "element #" << ei << ": "
|
||||
<< element_printouts[ei];
|
||||
sep = ",\n";
|
||||
outer_sep = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
@@ -53,12 +53,12 @@ namespace internal {
|
||||
|
||||
// Protects the mock object registry (in class Mock), all function
|
||||
// mockers, and all expectations.
|
||||
GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);
|
||||
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);
|
||||
|
||||
// Logs a message including file and line number information.
|
||||
void LogWithLocation(testing::internal::LogSeverity severity,
|
||||
const char* file, int line,
|
||||
const string& message) {
|
||||
GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
|
||||
const char* file, int line,
|
||||
const string& message) {
|
||||
::std::ostringstream s;
|
||||
s << file << ":" << line << ": " << message << ::std::endl;
|
||||
Log(severity, s.str(), 0);
|
||||
@@ -92,7 +92,8 @@ void ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) {
|
||||
}
|
||||
|
||||
// Retires all pre-requisites of this expectation.
|
||||
void ExpectationBase::RetireAllPreRequisites() {
|
||||
void ExpectationBase::RetireAllPreRequisites()
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
if (is_retired()) {
|
||||
// We can take this short-cut as we never retire an expectation
|
||||
// until we have retired all its pre-requisites.
|
||||
@@ -111,8 +112,8 @@ void ExpectationBase::RetireAllPreRequisites() {
|
||||
|
||||
// Returns true iff all pre-requisites of this expectation have been
|
||||
// satisfied.
|
||||
// L >= g_gmock_mutex
|
||||
bool ExpectationBase::AllPrerequisitesAreSatisfied() const {
|
||||
bool ExpectationBase::AllPrerequisitesAreSatisfied() const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end(); ++it) {
|
||||
@@ -124,9 +125,8 @@ bool ExpectationBase::AllPrerequisitesAreSatisfied() const {
|
||||
}
|
||||
|
||||
// Adds unsatisfied pre-requisites of this expectation to 'result'.
|
||||
// L >= g_gmock_mutex
|
||||
void ExpectationBase::FindUnsatisfiedPrerequisites(
|
||||
ExpectationSet* result) const {
|
||||
void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
|
||||
it != immediate_prerequisites_.end(); ++it) {
|
||||
@@ -147,8 +147,8 @@ void ExpectationBase::FindUnsatisfiedPrerequisites(
|
||||
|
||||
// Describes how many times a function call matching this
|
||||
// expectation has occurred.
|
||||
// L >= g_gmock_mutex
|
||||
void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const {
|
||||
void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
|
||||
// Describes how many times the function is expected to be called.
|
||||
@@ -170,8 +170,8 @@ void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const {
|
||||
// WillRepeatedly() clauses) against the cardinality if this hasn't
|
||||
// been done before. Prints a warning if there are too many or too
|
||||
// few actions.
|
||||
// L < mutex_
|
||||
void ExpectationBase::CheckActionCountIfNotDone() const {
|
||||
void ExpectationBase::CheckActionCountIfNotDone() const
|
||||
GTEST_LOCK_EXCLUDED_(mutex_) {
|
||||
bool should_check = false;
|
||||
{
|
||||
MutexLock l(&mutex_);
|
||||
@@ -217,7 +217,7 @@ void ExpectationBase::CheckActionCountIfNotDone() const {
|
||||
ss << " and a WillRepeatedly()";
|
||||
}
|
||||
ss << ".";
|
||||
Log(WARNING, ss.str(), -1); // -1 means "don't print stack trace".
|
||||
Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace".
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,17 +240,17 @@ void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) {
|
||||
|
||||
// Points to the implicit sequence introduced by a living InSequence
|
||||
// object (if any) in the current thread or NULL.
|
||||
ThreadLocal<Sequence*> g_gmock_implicit_sequence;
|
||||
GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence;
|
||||
|
||||
// Reports an uninteresting call (whose description is in msg) in the
|
||||
// manner specified by 'reaction'.
|
||||
void ReportUninterestingCall(CallReaction reaction, const string& msg) {
|
||||
switch (reaction) {
|
||||
case ALLOW:
|
||||
Log(INFO, msg, 3);
|
||||
case kAllow:
|
||||
Log(kInfo, msg, 3);
|
||||
break;
|
||||
case WARN:
|
||||
Log(WARNING, msg, 3);
|
||||
case kWarn:
|
||||
Log(kWarning, msg, 3);
|
||||
break;
|
||||
default: // FAIL
|
||||
Expect(false, NULL, -1, msg);
|
||||
@@ -266,8 +266,8 @@ UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
|
||||
// this information in the global mock registry. Will be called
|
||||
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
|
||||
// method.
|
||||
// L < g_gmock_mutex
|
||||
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj) {
|
||||
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
{
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
mock_obj_ = mock_obj;
|
||||
@@ -278,9 +278,9 @@ void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj) {
|
||||
// Sets the mock object this mock method belongs to, and sets the name
|
||||
// of the mock function. Will be called upon each invocation of this
|
||||
// mock function.
|
||||
// L < g_gmock_mutex
|
||||
void UntypedFunctionMockerBase::SetOwnerAndName(
|
||||
const void* mock_obj, const char* name) {
|
||||
void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj,
|
||||
const char* name)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
// We protect name_ under g_gmock_mutex in case this mock function
|
||||
// is called from two threads concurrently.
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
@@ -290,8 +290,8 @@ void UntypedFunctionMockerBase::SetOwnerAndName(
|
||||
|
||||
// Returns the name of the function being mocked. Must be called
|
||||
// after RegisterOwner() or SetOwnerAndName() has been called.
|
||||
// L < g_gmock_mutex
|
||||
const void* UntypedFunctionMockerBase::MockObject() const {
|
||||
const void* UntypedFunctionMockerBase::MockObject() const
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
const void* mock_obj;
|
||||
{
|
||||
// We protect mock_obj_ under g_gmock_mutex in case this mock
|
||||
@@ -307,8 +307,8 @@ const void* UntypedFunctionMockerBase::MockObject() const {
|
||||
|
||||
// Returns the name of this mock method. Must be called after
|
||||
// SetOwnerAndName() has been called.
|
||||
// L < g_gmock_mutex
|
||||
const char* UntypedFunctionMockerBase::Name() const {
|
||||
const char* UntypedFunctionMockerBase::Name() const
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
const char* name;
|
||||
{
|
||||
// We protect name_ under g_gmock_mutex in case this mock
|
||||
@@ -325,9 +325,9 @@ const char* UntypedFunctionMockerBase::Name() const {
|
||||
// Calculates the result of invoking this mock function with the given
|
||||
// arguments, prints it, and returns it. The caller is responsible
|
||||
// for deleting the result.
|
||||
// L < g_gmock_mutex
|
||||
const UntypedActionResultHolderBase*
|
||||
UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) {
|
||||
UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
if (untyped_expectations_.size() == 0) {
|
||||
// No expectation is set on this mock method - we have an
|
||||
// uninteresting call.
|
||||
@@ -345,10 +345,10 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) {
|
||||
const bool need_to_report_uninteresting_call =
|
||||
// If the user allows this uninteresting call, we print it
|
||||
// only when he wants informational messages.
|
||||
reaction == ALLOW ? LogIsVisible(INFO) :
|
||||
reaction == kAllow ? LogIsVisible(kInfo) :
|
||||
// If the user wants this to be a warning, we print it only
|
||||
// when he wants to see warnings.
|
||||
reaction == WARN ? LogIsVisible(WARNING) :
|
||||
reaction == kWarn ? LogIsVisible(kWarning) :
|
||||
// Otherwise, the user wants this to be an error, and we
|
||||
// should always print detailed information in the error.
|
||||
true;
|
||||
@@ -391,7 +391,8 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) {
|
||||
// True iff we need to print the call's arguments and return value.
|
||||
// This definition must be kept in sync with the uses of Expect()
|
||||
// and Log() in this function.
|
||||
const bool need_to_report_call = !found || is_excessive || LogIsVisible(INFO);
|
||||
const bool need_to_report_call =
|
||||
!found || is_excessive || LogIsVisible(kInfo);
|
||||
if (!need_to_report_call) {
|
||||
// Perform the action without printing the call information.
|
||||
return
|
||||
@@ -427,7 +428,7 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) {
|
||||
} else {
|
||||
// We had an expected call and the matching expectation is
|
||||
// described in ss.
|
||||
Log(INFO, loc.str() + ss.str(), 2);
|
||||
Log(kInfo, loc.str() + ss.str(), 2);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -453,8 +454,8 @@ Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
|
||||
// Verifies that all expectations on this mock function have been
|
||||
// satisfied. Reports one or more Google Test non-fatal failures
|
||||
// and returns false if not.
|
||||
// L >= g_gmock_mutex
|
||||
bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() {
|
||||
bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
bool expectations_met = true;
|
||||
for (UntypedExpectations::const_iterator it =
|
||||
@@ -480,7 +481,21 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() {
|
||||
untyped_expectation->line(), ss.str());
|
||||
}
|
||||
}
|
||||
untyped_expectations_.clear();
|
||||
|
||||
// Deleting our expectations may trigger other mock objects to be deleted, for
|
||||
// example if an action contains a reference counted smart pointer to that
|
||||
// mock object, and that is the last reference. So if we delete our
|
||||
// expectations within the context of the global mutex we may deadlock when
|
||||
// this method is called again. Instead, make a copy of the set of
|
||||
// expectations to delete, clear our set within the mutex, and then clear the
|
||||
// copied set outside of it.
|
||||
UntypedExpectations expectations_to_delete;
|
||||
untyped_expectations_.swap(expectations_to_delete);
|
||||
|
||||
g_gmock_mutex.Unlock();
|
||||
expectations_to_delete.clear();
|
||||
g_gmock_mutex.Lock();
|
||||
|
||||
return expectations_met;
|
||||
}
|
||||
|
||||
@@ -565,6 +580,7 @@ class MockObjectRegistry {
|
||||
}
|
||||
|
||||
StateMap& states() { return states_; }
|
||||
|
||||
private:
|
||||
StateMap states_;
|
||||
};
|
||||
@@ -578,9 +594,9 @@ std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction;
|
||||
|
||||
// Sets the reaction Google Mock should have when an uninteresting
|
||||
// method of the given mock object is called.
|
||||
// L < g_gmock_mutex
|
||||
void SetReactionOnUninterestingCalls(const void* mock_obj,
|
||||
internal::CallReaction reaction) {
|
||||
internal::CallReaction reaction)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_uninteresting_call_reaction[mock_obj] = reaction;
|
||||
}
|
||||
@@ -589,47 +605,47 @@ void SetReactionOnUninterestingCalls(const void* mock_obj,
|
||||
|
||||
// Tells Google Mock to allow uninteresting calls on the given mock
|
||||
// object.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::AllowUninterestingCalls(const void* mock_obj) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::ALLOW);
|
||||
void Mock::AllowUninterestingCalls(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::kAllow);
|
||||
}
|
||||
|
||||
// Tells Google Mock to warn the user about uninteresting calls on the
|
||||
// given mock object.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::WarnUninterestingCalls(const void* mock_obj) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::WARN);
|
||||
void Mock::WarnUninterestingCalls(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::kWarn);
|
||||
}
|
||||
|
||||
// Tells Google Mock to fail uninteresting calls on the given mock
|
||||
// object.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::FailUninterestingCalls(const void* mock_obj) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::FAIL);
|
||||
void Mock::FailUninterestingCalls(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
SetReactionOnUninterestingCalls(mock_obj, internal::kFail);
|
||||
}
|
||||
|
||||
// Tells Google Mock the given mock object is being destroyed and its
|
||||
// entry in the call-reaction table should be removed.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::UnregisterCallReaction(const void* mock_obj) {
|
||||
void Mock::UnregisterCallReaction(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_uninteresting_call_reaction.erase(mock_obj);
|
||||
}
|
||||
|
||||
// Returns the reaction Google Mock will have on uninteresting calls
|
||||
// made on the given mock object.
|
||||
// L < g_gmock_mutex
|
||||
internal::CallReaction Mock::GetReactionOnUninterestingCalls(
|
||||
const void* mock_obj) {
|
||||
const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
|
||||
internal::WARN : g_uninteresting_call_reaction[mock_obj];
|
||||
internal::kDefault : g_uninteresting_call_reaction[mock_obj];
|
||||
}
|
||||
|
||||
// Tells Google Mock to ignore mock_obj when checking for leaked mock
|
||||
// objects.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::AllowLeak(const void* mock_obj) {
|
||||
void Mock::AllowLeak(const void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].leakable = true;
|
||||
}
|
||||
@@ -637,8 +653,8 @@ void Mock::AllowLeak(const void* mock_obj) {
|
||||
// Verifies and clears all expectations on the given mock object. If
|
||||
// the expectations aren't satisfied, generates one or more Google
|
||||
// Test non-fatal failures and returns false.
|
||||
// L < g_gmock_mutex
|
||||
bool Mock::VerifyAndClearExpectations(void* mock_obj) {
|
||||
bool Mock::VerifyAndClearExpectations(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
}
|
||||
@@ -646,8 +662,8 @@ bool Mock::VerifyAndClearExpectations(void* mock_obj) {
|
||||
// Verifies all expectations on the given mock object and clears its
|
||||
// default actions and expectations. Returns true iff the
|
||||
// verification was successful.
|
||||
// L < g_gmock_mutex
|
||||
bool Mock::VerifyAndClear(void* mock_obj) {
|
||||
bool Mock::VerifyAndClear(void* mock_obj)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
ClearDefaultActionsLocked(mock_obj);
|
||||
return VerifyAndClearExpectationsLocked(mock_obj);
|
||||
@@ -656,8 +672,8 @@ bool Mock::VerifyAndClear(void* mock_obj) {
|
||||
// Verifies and clears all expectations on the given mock object. If
|
||||
// the expectations aren't satisfied, generates one or more Google
|
||||
// Test non-fatal failures and returns false.
|
||||
// L >= g_gmock_mutex
|
||||
bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) {
|
||||
bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
if (g_mock_object_registry.states().count(mock_obj) == 0) {
|
||||
// No EXPECT_CALL() was set on the given mock object.
|
||||
@@ -682,9 +698,9 @@ bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) {
|
||||
}
|
||||
|
||||
// Registers a mock object and a mock method it owns.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::Register(const void* mock_obj,
|
||||
internal::UntypedFunctionMockerBase* mocker) {
|
||||
internal::UntypedFunctionMockerBase* mocker)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
|
||||
}
|
||||
@@ -692,9 +708,9 @@ void Mock::Register(const void* mock_obj,
|
||||
// Tells Google Mock where in the source code mock_obj is used in an
|
||||
// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this
|
||||
// information helps the user identify which object it is.
|
||||
// L < g_gmock_mutex
|
||||
void Mock::RegisterUseByOnCallOrExpectCall(
|
||||
const void* mock_obj, const char* file, int line) {
|
||||
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
|
||||
const char* file, int line)
|
||||
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
|
||||
internal::MutexLock l(&internal::g_gmock_mutex);
|
||||
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
|
||||
if (state.first_used_file == NULL) {
|
||||
@@ -716,8 +732,8 @@ void Mock::RegisterUseByOnCallOrExpectCall(
|
||||
// registry when the last mock method associated with it has been
|
||||
// unregistered. This is called only in the destructor of
|
||||
// FunctionMockerBase.
|
||||
// L >= g_gmock_mutex
|
||||
void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) {
|
||||
void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
for (MockObjectRegistry::StateMap::iterator it =
|
||||
g_mock_object_registry.states().begin();
|
||||
@@ -734,8 +750,8 @@ void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) {
|
||||
}
|
||||
|
||||
// Clears all ON_CALL()s set on the given mock object.
|
||||
// L >= g_gmock_mutex
|
||||
void Mock::ClearDefaultActionsLocked(void* mock_obj) {
|
||||
void Mock::ClearDefaultActionsLocked(void* mock_obj)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) {
|
||||
internal::g_gmock_mutex.AssertHeld();
|
||||
|
||||
if (g_mock_object_registry.states().count(mock_obj) == 0) {
|
||||
|
||||
@@ -62,7 +62,7 @@ static const char* ParseGoogleMockFlagValue(const char* str,
|
||||
if (str == NULL || flag == NULL) return NULL;
|
||||
|
||||
// The flag must start with "--gmock_".
|
||||
const String flag_str = String::Format("--gmock_%s", flag);
|
||||
const std::string flag_str = std::string("--gmock_") + flag;
|
||||
const size_t flag_len = flag_str.length();
|
||||
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
|
||||
|
||||
@@ -107,7 +107,7 @@ static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
|
||||
// On success, stores the value of the flag in *value, and returns
|
||||
// true. On failure, returns false without changing *value.
|
||||
static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
|
||||
String* value) {
|
||||
std::string* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
|
||||
|
||||
@@ -131,7 +131,7 @@ void InitGoogleMockImpl(int* argc, CharType** argv) {
|
||||
if (*argc <= 0) return;
|
||||
|
||||
for (int i = 1; i != *argc; i++) {
|
||||
const String arg_string = StreamableToString(argv[i]);
|
||||
const std::string arg_string = StreamableToString(argv[i]);
|
||||
const char* const arg = arg_string.c_str();
|
||||
|
||||
// Do we see a Google Mock flag?
|
||||
@@ -169,13 +169,13 @@ void InitGoogleMockImpl(int* argc, CharType** argv) {
|
||||
// Since Google Test is needed for Google Mock to work, this function
|
||||
// also initializes Google Test and parses its flags, if that hasn't
|
||||
// been done.
|
||||
void InitGoogleMock(int* argc, char** argv) {
|
||||
GTEST_API_ void InitGoogleMock(int* argc, char** argv) {
|
||||
internal::InitGoogleMockImpl(argc, argv);
|
||||
}
|
||||
|
||||
// This overloaded version can be used in Windows programs compiled in
|
||||
// UNICODE mode.
|
||||
void InitGoogleMock(int* argc, wchar_t** argv) {
|
||||
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) {
|
||||
internal::InitGoogleMockImpl(argc, argv);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
#if GTEST_OS_WINDOWS_MOBILE
|
||||
# include <tchar.h> // NOLINT
|
||||
|
||||
int _tmain(int argc, TCHAR** argv) {
|
||||
GTEST_API_ int _tmain(int argc, TCHAR** argv) {
|
||||
#else
|
||||
int main(int argc, char** argv) {
|
||||
GTEST_API_ int main(int argc, char** argv) {
|
||||
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
std::cout << "Running main() from gmock_main.cc\n";
|
||||
// Since Google Mock depends on Google Test, InitGoogleMock() is
|
||||
|
||||
Reference in New Issue
Block a user