Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/gmock/src')
-rw-r--r--extern/gmock/src/gmock-all.cc3
-rw-r--r--extern/gmock/src/gmock-cardinalities.cc15
-rw-r--r--extern/gmock/src/gmock-internal-utils.cc56
-rw-r--r--extern/gmock/src/gmock-matchers.cc290
-rw-r--r--extern/gmock/src/gmock-spec-builders.cc249
-rw-r--r--extern/gmock/src/gmock.cc56
-rw-r--r--extern/gmock/src/gmock_main.cc17
7 files changed, 390 insertions, 296 deletions
diff --git a/extern/gmock/src/gmock-all.cc b/extern/gmock/src/gmock-all.cc
index 7aebce7afef..e43c9b7b4c1 100644
--- a/extern/gmock/src/gmock-all.cc
+++ b/extern/gmock/src/gmock-all.cc
@@ -26,8 +26,7 @@
// 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 C++ Mocking Framework (Google Mock)
//
diff --git a/extern/gmock/src/gmock-cardinalities.cc b/extern/gmock/src/gmock-cardinalities.cc
index 50ec7286eeb..7463f438323 100644
--- a/extern/gmock/src/gmock-cardinalities.cc
+++ b/extern/gmock/src/gmock-cardinalities.cc
@@ -26,8 +26,7 @@
// 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.
//
@@ -71,18 +70,18 @@ class BetweenCardinalityImpl : public CardinalityInterface {
// Conservative estimate on the lower/upper bound of the number of
// calls allowed.
- virtual int ConservativeLowerBound() const { return min_; }
- virtual int ConservativeUpperBound() const { return max_; }
+ int ConservativeLowerBound() const override { return min_; }
+ int ConservativeUpperBound() const override { return max_; }
- virtual bool IsSatisfiedByCallCount(int call_count) const {
+ bool IsSatisfiedByCallCount(int call_count) const override {
return min_ <= call_count && call_count <= max_;
}
- virtual bool IsSaturatedByCallCount(int call_count) const {
+ bool IsSaturatedByCallCount(int call_count) const override {
return call_count >= max_;
}
- virtual void DescribeTo(::std::ostream* os) const;
+ void DescribeTo(::std::ostream* os) const override;
private:
const int min_;
@@ -92,7 +91,7 @@ class BetweenCardinalityImpl : public CardinalityInterface {
};
// Formats "n times" in a human-friendly way.
-inline internal::string FormatTimes(int n) {
+inline std::string FormatTimes(int n) {
if (n == 1) {
return "once";
} else if (n == 2) {
diff --git a/extern/gmock/src/gmock-internal-utils.cc b/extern/gmock/src/gmock-internal-utils.cc
index fb5308018a7..e5b547981d1 100644
--- a/extern/gmock/src/gmock-internal-utils.cc
+++ b/extern/gmock/src/gmock-internal-utils.cc
@@ -26,8 +26,7 @@
// 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.
//
@@ -47,12 +46,31 @@
namespace testing {
namespace internal {
+// Joins a vector of strings as if they are fields of a tuple; returns
+// the joined string.
+GTEST_API_ std::string JoinAsTuple(const Strings& fields) {
+ switch (fields.size()) {
+ case 0:
+ return "";
+ case 1:
+ return fields[0];
+ default:
+ std::string result = "(" + fields[0];
+ for (size_t i = 1; i < fields.size(); i++) {
+ result += ", ";
+ result += fields[i];
+ }
+ result += ")";
+ return result;
+ }
+}
+
// 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;
+GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) {
+ std::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
@@ -71,12 +89,12 @@ GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) {
}
// This class reports Google Mock failures as Google Test failures. A
-// user can define another class in a similar fashion if he intends to
+// user can define another class in a similar fashion if they intend 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) {
+ void ReportFailure(FailureType type, const char* file, int line,
+ const std::string& message) override {
AssertHelper(type == kFatal ?
TestPartResult::kFatalFailure :
TestPartResult::kNonFatalFailure,
@@ -105,8 +123,8 @@ GTEST_API_ FailureReporterInterface* GetFailureReporter() {
// 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.
+// Returns true if and only if 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.
@@ -121,15 +139,14 @@ GTEST_API_ bool LogIsVisible(LogSeverity severity) {
}
}
-// Prints the given message to stdout iff 'severity' >= the level
+// Prints the given message to stdout if and only if '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,
+GTEST_API_ void Log(LogSeverity severity, const std::string& message,
int stack_frames_to_skip) {
if (!LogIsVisible(severity))
return;
@@ -137,9 +154,6 @@ GTEST_API_ void Log(LogSeverity severity,
// 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:";
@@ -170,5 +184,17 @@ GTEST_API_ void Log(LogSeverity severity,
std::cout << ::std::flush;
}
+GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); }
+
+GTEST_API_ void IllegalDoDefault(const char* file, int line) {
+ internal::Assert(
+ false, file, line,
+ "You are using DoDefault() inside a composite action like "
+ "DoAll() or WithArgs(). This is not supported for technical "
+ "reasons. Please instead spell out the default action, or "
+ "assign the default action to an Action variable and use "
+ "the variable in various places.");
+}
+
} // namespace internal
} // namespace testing
diff --git a/extern/gmock/src/gmock-matchers.cc b/extern/gmock/src/gmock-matchers.cc
index e7424510fca..4a3f7af2351 100644
--- a/extern/gmock/src/gmock-matchers.cc
+++ b/extern/gmock/src/gmock-matchers.cc
@@ -26,8 +26,7 @@
// 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.
//
@@ -38,98 +37,23 @@
#include "gmock/gmock-generated-matchers.h"
#include <string.h>
+#include <iostream>
#include <sstream>
#include <string>
namespace testing {
-
-// Constructs a matcher that matches a const string& whose value is
-// equal to s.
-Matcher<const internal::string&>::Matcher(const internal::string& s) {
- *this = Eq(s);
-}
-
-// Constructs a matcher that matches a const string& whose value is
-// equal to s.
-Matcher<const internal::string&>::Matcher(const char* s) {
- *this = Eq(internal::string(s));
-}
-
-// Constructs a matcher that matches a string whose value is equal to s.
-Matcher<internal::string>::Matcher(const internal::string& s) { *this = Eq(s); }
-
-// Constructs a matcher that matches a string whose value is equal to s.
-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.
-GTEST_API_ string JoinAsTuple(const Strings& fields) {
- switch (fields.size()) {
- case 0:
- return "";
- case 1:
- return fields[0];
- default:
- string result = "(" + fields[0];
- for (size_t i = 1; i < fields.size(); i++) {
- result += ", ";
- result += fields[i];
- }
- result += ")";
- return result;
- }
-}
-
// Returns the description for a matcher defined using the MATCHER*()
// macro where the user-supplied description string is "", if
// '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.
-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);
+GTEST_API_ std::string FormatMatcherDescription(bool negation,
+ const char* matcher_name,
+ const Strings& param_values) {
+ std::string result = ConvertIdentifierNameToWords(matcher_name);
+ if (param_values.size() >= 1) result += " " + JoinAsTuple(param_values);
return negation ? "not (" + result + ")" : result;
}
@@ -200,8 +124,7 @@ class MaxBipartiteMatchState {
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
: graph_(&graph),
left_(graph_->LhsSize(), kUnused),
- right_(graph_->RhsSize(), kUnused) {
- }
+ right_(graph_->RhsSize(), kUnused) {}
// Returns the edges of a maximal match, each in the form {left, right}.
ElementMatcherPairs Compute() {
@@ -258,10 +181,8 @@ class MaxBipartiteMatchState {
//
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;
+ 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
@@ -288,7 +209,7 @@ class MaxBipartiteMatchState {
// 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
+ // outflow from that node to a node on 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
@@ -304,8 +225,7 @@ class MaxBipartiteMatchState {
const size_t MaxBipartiteMatchState::kUnused;
-GTEST_API_ ElementMatcherPairs
-FindMaxBipartiteMatching(const MatchMatrix& g) {
+GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) {
return MaxBipartiteMatchState(g).Compute();
}
@@ -314,7 +234,7 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
typedef ElementMatcherPairs::const_iterator Iter;
::std::ostream& os = *stream;
os << "{";
- const char *sep = "";
+ const char* sep = "";
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
os << sep << "\n ("
<< "element #" << it->first << ", "
@@ -324,38 +244,6 @@ static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs,
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) {
@@ -379,9 +267,9 @@ void MatchMatrix::Randomize() {
}
}
-string MatchMatrix::DebugString() const {
+std::string MatchMatrix::DebugString() const {
::std::stringstream ss;
- const char *sep = "";
+ const char* sep = "";
for (size_t i = 0; i < LhsSize(); ++i) {
ss << sep;
for (size_t j = 0; j < RhsSize(); ++j) {
@@ -394,44 +282,83 @@ string MatchMatrix::DebugString() const {
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;
+ switch (match_flags()) {
+ case UnorderedMatcherRequire::ExactMatch:
+ 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";
+ break;
+ case UnorderedMatcherRequire::Superset:
+ *os << "a surjection from elements to requirements exists such that:\n";
+ break;
+ case UnorderedMatcherRequire::Subset:
+ *os << "an injection from elements to requirements exists such that:\n";
+ break;
}
- *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 << " ";
+ *os << sep;
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ *os << " - element #" << i << " ";
+ } else {
+ *os << " - an element ";
+ }
matcher_describers_[i]->DescribeTo(os);
- sep = ", and\n";
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ sep = ", and\n";
+ } else {
+ sep = "\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;
+ switch (match_flags()) {
+ case UnorderedMatcherRequire::ExactMatch:
+ 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";
+ break;
+ case UnorderedMatcherRequire::Superset:
+ *os << "no surjection from elements to requirements exists such that:\n";
+ break;
+ case UnorderedMatcherRequire::Subset:
+ *os << "no injection from elements to requirements exists such that:\n";
+ break;
}
- *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 << " ";
+ *os << sep;
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ *os << " - element #" << i << " ";
+ } else {
+ *os << " - an element ";
+ }
matcher_describers_[i]->DescribeTo(os);
- sep = ", and\n";
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ sep = ", and\n";
+ } else {
+ sep = "\n";
+ }
}
}
@@ -440,11 +367,9 @@ void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
// 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 UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
+ const ::std::vector<std::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);
@@ -457,12 +382,11 @@ VerifyAllElementsAndMatchersAreMatched(
}
}
- {
+ if (match_flags() & UnorderedMatcherRequire::Superset) {
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;
+ if (matcher_matched[mi]) continue;
result = false;
if (listener->IsInterested()) {
*listener << sep << "matcher #" << mi << ": ";
@@ -472,7 +396,7 @@ VerifyAllElementsAndMatchersAreMatched(
}
}
- {
+ if (match_flags() & UnorderedMatcherRequire::Subset) {
const char* sep =
"where the following elements don't match any matchers:\n";
const char* outer_sep = "";
@@ -480,8 +404,7 @@ VerifyAllElementsAndMatchersAreMatched(
outer_sep = "\nand ";
}
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
- if (element_matched[ei])
- continue;
+ if (element_matched[ei]) continue;
result = false;
if (listener->IsInterested()) {
*listener << outer_sep << sep << "element #" << ei << ": "
@@ -494,5 +417,46 @@ VerifyAllElementsAndMatchersAreMatched(
return result;
}
+bool UnorderedElementsAreMatcherImplBase::FindPairing(
+ const MatchMatrix& matrix, MatchResultListener* listener) const {
+ ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
+
+ size_t max_flow = matches.size();
+ if ((match_flags() & UnorderedMatcherRequire::Superset) &&
+ max_flow < matrix.RhsSize()) {
+ 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 ((match_flags() & UnorderedMatcherRequire::Subset) &&
+ max_flow < matrix.LhsSize()) {
+ if (listener->IsInterested()) {
+ *listener
+ << "where not all elements can be matched, 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;
+}
+
} // namespace internal
} // namespace testing
diff --git a/extern/gmock/src/gmock-spec-builders.cc b/extern/gmock/src/gmock-spec-builders.cc
index 95513420707..f9d3434560b 100644
--- a/extern/gmock/src/gmock-spec-builders.cc
+++ b/extern/gmock/src/gmock-spec-builders.cc
@@ -26,8 +26,7 @@
// 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.
//
@@ -39,8 +38,10 @@
#include <stdlib.h>
#include <iostream> // NOLINT
#include <map>
+#include <memory>
#include <set>
#include <string>
+#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -48,6 +49,15 @@
# include <unistd.h> // NOLINT
#endif
+// Silence C4800 (C4800: 'int *const ': forcing value
+// to bool 'true' or 'false') for MSVC 15
+#ifdef _MSC_VER
+#if _MSC_VER == 1900
+# pragma warning(push)
+# pragma warning(disable:4800)
+#endif
+#endif
+
namespace testing {
namespace internal {
@@ -58,16 +68,15 @@ GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex);
// Logs a message including file and line number information.
GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
const char* file, int line,
- const string& message) {
+ const std::string& message) {
::std::ostringstream s;
s << file << ":" << line << ": " << message << ::std::endl;
Log(severity, s.str(), 0);
}
// Constructs an ExpectationBase object.
-ExpectationBase::ExpectationBase(const char* a_file,
- int a_line,
- const string& a_source_text)
+ExpectationBase::ExpectationBase(const char* a_file, int a_line,
+ const std::string& a_source_text)
: file_(a_file),
line_(a_line),
source_text_(a_source_text),
@@ -100,26 +109,40 @@ void ExpectationBase::RetireAllPreRequisites()
return;
}
- for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
- it != immediate_prerequisites_.end(); ++it) {
- ExpectationBase* const prerequisite = it->expectation_base().get();
- if (!prerequisite->is_retired()) {
- prerequisite->RetireAllPreRequisites();
- prerequisite->Retire();
+ ::std::vector<ExpectationBase*> expectations(1, this);
+ while (!expectations.empty()) {
+ ExpectationBase* exp = expectations.back();
+ expectations.pop_back();
+
+ for (ExpectationSet::const_iterator it =
+ exp->immediate_prerequisites_.begin();
+ it != exp->immediate_prerequisites_.end(); ++it) {
+ ExpectationBase* next = it->expectation_base().get();
+ if (!next->is_retired()) {
+ next->Retire();
+ expectations.push_back(next);
+ }
}
}
}
-// Returns true iff all pre-requisites of this expectation have been
-// satisfied.
+// Returns true if and only if all pre-requisites of this expectation
+// have been satisfied.
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) {
- if (!(it->expectation_base()->IsSatisfied()) ||
- !(it->expectation_base()->AllPrerequisitesAreSatisfied()))
- return false;
+ ::std::vector<const ExpectationBase*> expectations(1, this);
+ while (!expectations.empty()) {
+ const ExpectationBase* exp = expectations.back();
+ expectations.pop_back();
+
+ for (ExpectationSet::const_iterator it =
+ exp->immediate_prerequisites_.begin();
+ it != exp->immediate_prerequisites_.end(); ++it) {
+ const ExpectationBase* next = it->expectation_base().get();
+ if (!next->IsSatisfied()) return false;
+ expectations.push_back(next);
+ }
}
return true;
}
@@ -128,19 +151,28 @@ bool ExpectationBase::AllPrerequisitesAreSatisfied() 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) {
- if (it->expectation_base()->IsSatisfied()) {
- // If *it is satisfied and has a call count of 0, some of its
- // pre-requisites may not be satisfied yet.
- if (it->expectation_base()->call_count_ == 0) {
- it->expectation_base()->FindUnsatisfiedPrerequisites(result);
+ ::std::vector<const ExpectationBase*> expectations(1, this);
+ while (!expectations.empty()) {
+ const ExpectationBase* exp = expectations.back();
+ expectations.pop_back();
+
+ for (ExpectationSet::const_iterator it =
+ exp->immediate_prerequisites_.begin();
+ it != exp->immediate_prerequisites_.end(); ++it) {
+ const ExpectationBase* next = it->expectation_base().get();
+
+ if (next->IsSatisfied()) {
+ // If *it is satisfied and has a call count of 0, some of its
+ // pre-requisites may not be satisfied yet.
+ if (next->call_count_ == 0) {
+ expectations.push_back(next);
+ }
+ } else {
+ // Now that we know next is unsatisfied, we are not so interested
+ // in whether its pre-requisites are satisfied. Therefore we
+ // don't iterate into it here.
+ *result += *it;
}
- } else {
- // Now that we know *it is unsatisfied, we are not so interested
- // in whether its pre-requisites are satisfied. Therefore we
- // don't recursively call FindUnsatisfiedPrerequisites() here.
- *result += *it;
}
}
}
@@ -244,7 +276,7 @@ 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) {
+void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
// Include a stack trace only if --gmock_verbose=info is specified.
const int stack_frames_to_skip =
GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1;
@@ -255,20 +287,22 @@ void ReportUninterestingCall(CallReaction reaction, const string& msg) {
case kWarn:
Log(kWarning,
msg +
- "\nNOTE: You can safely ignore the above warning unless this "
- "call should not happen. Do not suppress it by blindly adding "
- "an EXPECT_CALL() if you don't mean to enforce the call. "
- "See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#"
- "knowing-when-to-expect for details.\n",
+ "\nNOTE: You can safely ignore the above warning unless this "
+ "call should not happen. Do not suppress it by blindly adding "
+ "an EXPECT_CALL() if you don't mean to enforce the call. "
+ "See "
+ "https://github.com/google/googletest/blob/master/googlemock/"
+ "docs/cook_book.md#"
+ "knowing-when-to-expect for details.\n",
stack_frames_to_skip);
break;
default: // FAIL
- Expect(false, NULL, -1, msg);
+ Expect(false, nullptr, -1, msg);
}
}
UntypedFunctionMockerBase::UntypedFunctionMockerBase()
- : mock_obj_(NULL), name_("") {}
+ : mock_obj_(nullptr), name_("") {}
UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
@@ -307,7 +341,7 @@ const void* UntypedFunctionMockerBase::MockObject() const
// We protect mock_obj_ under g_gmock_mutex in case this mock
// function is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
- Assert(mock_obj_ != NULL, __FILE__, __LINE__,
+ Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
"MockObject() must not be called before RegisterOwner() or "
"SetOwnerAndName() has been called.");
mock_obj = mock_obj_;
@@ -324,7 +358,7 @@ const char* UntypedFunctionMockerBase::Name() const
// We protect name_ under g_gmock_mutex in case this mock
// function is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
- Assert(name_ != NULL, __FILE__, __LINE__,
+ Assert(name_ != nullptr, __FILE__, __LINE__,
"Name() must not be called before SetOwnerAndName() has "
"been called.");
name = name_;
@@ -335,9 +369,10 @@ 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.
-UntypedActionResultHolderBase*
-UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith(
+ void* const untyped_args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+ // See the definition of untyped_expectations_ for why access to it
+ // is unprotected here.
if (untyped_expectations_.size() == 0) {
// No expectation is set on this mock method - we have an
// uninteresting call.
@@ -349,23 +384,26 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
const CallReaction reaction =
Mock::GetReactionOnUninterestingCalls(MockObject());
- // True iff we need to print this call's arguments and return
+ // True if and only if we need to print this call's arguments and return
// value. This definition must be kept in sync with
// the behavior of ReportUninterestingCall().
const bool need_to_report_uninteresting_call =
// If the user allows this uninteresting call, we print it
- // only when he wants informational messages.
+ // only when they want informational messages.
reaction == kAllow ? LogIsVisible(kInfo) :
- // If the user wants this to be a warning, we print it only
- // when he wants to see warnings.
- reaction == kWarn ? LogIsVisible(kWarning) :
- // Otherwise, the user wants this to be an error, and we
- // should always print detailed information in the error.
- true;
+ // If the user wants this to be a warning, we print
+ // it only when they want to see warnings.
+ reaction == kWarn
+ ? LogIsVisible(kWarning)
+ :
+ // Otherwise, the user wants this to be an error, and we
+ // should always print detailed information in the error.
+ true;
if (!need_to_report_uninteresting_call) {
// Perform the action without printing the call information.
- return this->UntypedPerformDefaultAction(untyped_args, "");
+ return this->UntypedPerformDefaultAction(
+ untyped_args, "Function call: " + std::string(Name()));
}
// Warns about the uninteresting call.
@@ -377,8 +415,7 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
this->UntypedPerformDefaultAction(untyped_args, ss.str());
// Prints the function result.
- if (result != NULL)
- result->PrintAsActionResult(&ss);
+ if (result != nullptr) result->PrintAsActionResult(&ss);
ReportUninterestingCall(reaction, ss.str());
return result;
@@ -388,7 +425,7 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
::std::stringstream ss;
::std::stringstream why;
::std::stringstream loc;
- const void* untyped_action = NULL;
+ const void* untyped_action = nullptr;
// The UntypedFindMatchingExpectation() function acquires and
// releases g_gmock_mutex.
@@ -396,19 +433,19 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
this->UntypedFindMatchingExpectation(
untyped_args, &untyped_action, &is_excessive,
&ss, &why);
- const bool found = untyped_expectation != NULL;
+ const bool found = untyped_expectation != nullptr;
- // True iff we need to print the call's arguments and return value.
+ // True if and only if 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(kInfo);
if (!need_to_report_call) {
// Perform the action without printing the call information.
- return
- untyped_action == NULL ?
- this->UntypedPerformDefaultAction(untyped_args, "") :
- this->UntypedPerformAction(untyped_action, untyped_args);
+ return untyped_action == nullptr
+ ? this->UntypedPerformDefaultAction(untyped_args, "")
+ : this->UntypedPerformAction(untyped_action, untyped_args);
}
ss << " Function call: " << Name();
@@ -421,16 +458,15 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
}
UntypedActionResultHolderBase* const result =
- untyped_action == NULL ?
- this->UntypedPerformDefaultAction(untyped_args, ss.str()) :
- this->UntypedPerformAction(untyped_action, untyped_args);
- if (result != NULL)
- result->PrintAsActionResult(&ss);
+ untyped_action == nullptr
+ ? this->UntypedPerformDefaultAction(untyped_args, ss.str())
+ : this->UntypedPerformAction(untyped_action, untyped_args);
+ if (result != nullptr) result->PrintAsActionResult(&ss);
ss << "\n" << why.str();
if (!found) {
// No expectation matches this call - reports a failure.
- Expect(false, NULL, -1, ss.str());
+ Expect(false, nullptr, -1, ss.str());
} else if (is_excessive) {
// We had an upper-bound violation and the failure message is in ss.
Expect(false, untyped_expectation->file(),
@@ -447,6 +483,8 @@ UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
// Returns an Expectation object that references and co-owns exp,
// which must be an expectation on this mock function.
Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
+ // See the definition of untyped_expectations_ for why access to it
+ // is unprotected here.
for (UntypedExpectations::const_iterator it =
untyped_expectations_.begin();
it != untyped_expectations_.end(); ++it) {
@@ -509,6 +547,13 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
return expectations_met;
}
+CallReaction intToCallReaction(int mock_behavior) {
+ if (mock_behavior >= kAllow && mock_behavior <= kFail) {
+ return static_cast<internal::CallReaction>(mock_behavior);
+ }
+ return kWarn;
+}
+
} // namespace internal
// Class Mock.
@@ -522,15 +567,15 @@ typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
// expectations.
struct MockObjectState {
MockObjectState()
- : first_used_file(NULL), first_used_line(-1), leakable(false) {}
+ : first_used_file(nullptr), first_used_line(-1), leakable(false) {}
// Where in the source file an ON_CALL or EXPECT_CALL is first
// invoked on this mock object.
const char* first_used_file;
int first_used_line;
- ::std::string first_used_test_case;
+ ::std::string first_used_test_suite;
::std::string first_used_test;
- bool leakable; // true iff it's OK to leak the object.
+ bool leakable; // true if and only if it's OK to leak the object.
FunctionMockers function_mockers; // All registered methods of the object.
};
@@ -548,9 +593,6 @@ class MockObjectRegistry {
// object alive. Therefore we report any living object as test
// failure, unless the user explicitly asked us to ignore it.
~MockObjectRegistry() {
- // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is
- // a macro.
-
if (!GMOCK_FLAG(catch_leaked_mocks))
return;
@@ -560,7 +602,7 @@ class MockObjectRegistry {
if (it->second.leakable) // The user said it's fine to leak this object.
continue;
- // TODO(wan@google.com): Print the type of the leaked object.
+ // FIXME: Print the type of the leaked object.
// This can help the user identify the leaked object.
std::cout << "\n";
const MockObjectState& state = it->second;
@@ -568,17 +610,23 @@ class MockObjectRegistry {
state.first_used_line);
std::cout << " ERROR: this mock object";
if (state.first_used_test != "") {
- std::cout << " (used in test " << state.first_used_test_case << "."
- << state.first_used_test << ")";
+ std::cout << " (used in test " << state.first_used_test_suite << "."
+ << state.first_used_test << ")";
}
std::cout << " should be deleted but never is. Its address is @"
<< it->first << ".";
leaked_count++;
}
if (leaked_count > 0) {
- std::cout << "\nERROR: " << leaked_count
- << " leaked mock " << (leaked_count == 1 ? "object" : "objects")
- << " found at program exit.\n";
+ std::cout << "\nERROR: " << leaked_count << " leaked mock "
+ << (leaked_count == 1 ? "object" : "objects")
+ << " found at program exit. Expectations on a mock object is "
+ "verified when the object is destructed. Leaking a mock "
+ "means that its expectations aren't verified, which is "
+ "usually a test bug. If you really intend to leak a mock, "
+ "you can suppress this error using "
+ "testing::Mock::AllowLeak(mock_object), or you may use a "
+ "fake or stub instead of a mock.\n";
std::cout.flush();
::std::cerr.flush();
// RUN_ALL_TESTS() has already returned when this destructor is
@@ -649,7 +697,8 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
- internal::kDefault : g_uninteresting_call_reaction[mock_obj];
+ internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) :
+ g_uninteresting_call_reaction[mock_obj];
}
// Tells Google Mock to ignore mock_obj when checking for leaked mock
@@ -670,7 +719,7 @@ 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
+// default actions and expectations. Returns true if and only if the
// verification was successful.
bool Mock::VerifyAndClear(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
@@ -707,6 +756,19 @@ bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj)
return expectations_met;
}
+bool Mock::IsNaggy(void* mock_obj)
+ GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
+ return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kWarn;
+}
+bool Mock::IsNice(void* mock_obj)
+ GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
+ return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kAllow;
+}
+bool Mock::IsStrict(void* mock_obj)
+ GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
+ return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kFail;
+}
+
// Registers a mock object and a mock method it owns.
void Mock::Register(const void* mock_obj,
internal::UntypedFunctionMockerBase* mocker)
@@ -723,16 +785,13 @@ void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj,
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) {
+ if (state.first_used_file == nullptr) {
state.first_used_file = file;
state.first_used_line = line;
const TestInfo* const test_info =
UnitTest::GetInstance()->current_test_info();
- if (test_info != NULL) {
- // TODO(wan@google.com): record the test case name when the
- // ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or
- // TearDownTestCase().
- state.first_used_test_case = test_info->test_case_name();
+ if (test_info != nullptr) {
+ state.first_used_test_suite = test_info->test_suite_name();
state.first_used_test = test_info->name();
}
}
@@ -785,7 +844,7 @@ void Mock::ClearDefaultActionsLocked(void* mock_obj)
Expectation::Expectation() {}
Expectation::Expectation(
- const internal::linked_ptr<internal::ExpectationBase>& an_expectation_base)
+ const std::shared_ptr<internal::ExpectationBase>& an_expectation_base)
: expectation_base_(an_expectation_base) {}
Expectation::~Expectation() {}
@@ -793,7 +852,7 @@ Expectation::~Expectation() {}
// Adds an expectation to a sequence.
void Sequence::AddExpectation(const Expectation& expectation) const {
if (*last_expectation_ != expectation) {
- if (last_expectation_->expectation_base() != NULL) {
+ if (last_expectation_->expectation_base() != nullptr) {
expectation.expectation_base()->immediate_prerequisites_
+= *last_expectation_;
}
@@ -803,7 +862,7 @@ void Sequence::AddExpectation(const Expectation& expectation) const {
// Creates the implicit sequence if there isn't one.
InSequence::InSequence() {
- if (internal::g_gmock_implicit_sequence.get() == NULL) {
+ if (internal::g_gmock_implicit_sequence.get() == nullptr) {
internal::g_gmock_implicit_sequence.set(new Sequence);
sequence_created_ = true;
} else {
@@ -816,8 +875,14 @@ InSequence::InSequence() {
InSequence::~InSequence() {
if (sequence_created_) {
delete internal::g_gmock_implicit_sequence.get();
- internal::g_gmock_implicit_sequence.set(NULL);
+ internal::g_gmock_implicit_sequence.set(nullptr);
}
}
} // namespace testing
+
+#ifdef _MSC_VER
+#if _MSC_VER == 1900
+# pragma warning(pop)
+#endif
+#endif
diff --git a/extern/gmock/src/gmock.cc b/extern/gmock/src/gmock.cc
index eac3d842ba0..32b2a7394fd 100644
--- a/extern/gmock/src/gmock.cc
+++ b/extern/gmock/src/gmock.cc
@@ -26,20 +26,16 @@
// 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)
+
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
-// TODO(wan@google.com): support using environment variables to
-// control the flag values, like what Google Test does.
-
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
- "true iff Google Mock should report leaked mock objects "
- "as failures.");
+ "true if and only if Google Mock should report leaked "
+ "mock objects as failures.");
GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
"Controls how verbose Google Mock's output is."
@@ -48,6 +44,13 @@ GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
" warning - prints warnings and errors.\n"
" error - prints errors only.");
+GMOCK_DEFINE_int32_(default_mock_behavior, 1,
+ "Controls the default behavior of mocks."
+ " Valid values:\n"
+ " 0 - by default, mocks act as NiceMocks.\n"
+ " 1 - by default, mocks act as NaggyMocks.\n"
+ " 2 - by default, mocks act as StrictMocks.");
+
namespace internal {
// Parses a string as a command line flag. The string should have the
@@ -59,12 +62,12 @@ static const char* ParseGoogleMockFlagValue(const char* str,
const char* flag,
bool def_optional) {
// str and flag must not be NULL.
- if (str == NULL || flag == NULL) return NULL;
+ if (str == nullptr || flag == nullptr) return nullptr;
// The flag must start with "--gmock_".
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;
+ if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
// Skips the flag name.
const char* flag_end = str + flag_len;
@@ -77,7 +80,7 @@ static const char* ParseGoogleMockFlagValue(const char* str,
// If def_optional is true and there are more characters after the
// flag name, or if def_optional is false, there must be a '=' after
// the flag name.
- if (flag_end[0] != '=') return NULL;
+ if (flag_end[0] != '=') return nullptr;
// Returns the string after "=".
return flag_end + 1;
@@ -94,7 +97,7 @@ static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
// Aborts if the parsing failed.
- if (value_str == NULL) return false;
+ if (value_str == nullptr) return false;
// Converts the string value to a bool.
*value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
@@ -113,13 +116,26 @@ static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
// Aborts if the parsing failed.
- if (value_str == NULL) return false;
+ if (value_str == nullptr) return false;
// Sets *value to the value of the flag.
*value = value_str;
return true;
}
+static bool ParseGoogleMockIntFlag(const char* str, const char* flag,
+ int* value) {
+ // Gets the value of the flag as a string.
+ const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
+
+ // Aborts if the parsing failed.
+ if (value_str == nullptr) return false;
+
+ // Sets *value to the value of the flag.
+ return ParseInt32(Message() << "The value of flag --" << flag,
+ value_str, value);
+}
+
// The internal implementation of InitGoogleMock().
//
// The type parameter CharType can be instantiated to either char or
@@ -138,7 +154,9 @@ void InitGoogleMockImpl(int* argc, CharType** argv) {
// Do we see a Google Mock flag?
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
&GMOCK_FLAG(catch_leaked_mocks)) ||
- ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
+ ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose)) ||
+ ParseGoogleMockIntFlag(arg, "default_mock_behavior",
+ &GMOCK_FLAG(default_mock_behavior))) {
// Yes. Shift the remainder of the argv list left by one. Note
// that argv has (*argc + 1) elements, the last one always being
// NULL. The following loop moves the trailing NULL element as
@@ -180,4 +198,16 @@ GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) {
internal::InitGoogleMockImpl(argc, argv);
}
+// This overloaded version can be used on Arduino/embedded platforms where
+// there is no argc/argv.
+GTEST_API_ void InitGoogleMock() {
+ // Since Arduino doesn't have a command line, fake out the argc/argv arguments
+ int argc = 1;
+ const auto arg0 = "dummy";
+ char* argv0 = const_cast<char*>(arg0);
+ char** argv = &argv0;
+
+ internal::InitGoogleMockImpl(&argc, argv);
+}
+
} // namespace testing
diff --git a/extern/gmock/src/gmock_main.cc b/extern/gmock/src/gmock_main.cc
index bd5be03be22..98611b93535 100644
--- a/extern/gmock/src/gmock_main.cc
+++ b/extern/gmock/src/gmock_main.cc
@@ -26,18 +26,28 @@
// 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)
+
#include <iostream>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#ifdef ARDUINO
+void setup() {
+ // Since Google Mock depends on Google Test, InitGoogleMock() is
+ // also responsible for initializing Google Test. Therefore there's
+ // no need for calling testing::InitGoogleTest() separately.
+ testing::InitGoogleMock();
+}
+void loop() { RUN_ALL_TESTS(); }
+#else
+
// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which
// causes a link error when _tmain is defined in a static library and UNICODE
// is enabled. For this reason instead of _tmain, main function is used on
// Windows. See the following link to track the current status of this bug:
-// http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=394464 // NOLINT
+// https://web.archive.org/web/20170912203238/connect.microsoft.com/VisualStudio/feedback/details/394464/wmain-link-error-in-the-static-library
+// // NOLINT
#if GTEST_OS_WINDOWS_MOBILE
# include <tchar.h> // NOLINT
@@ -52,3 +62,4 @@ GTEST_API_ int main(int argc, char** argv) {
testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
+#endif