"xcode/Config/InternalPythonTestTarget.xcconfig" did not exist on "980926a9ed432f490191b109f6aac257de737e51"
Commit bad778ca authored by vladlosev's avatar vladlosev
Browse files

Implements support for AssertionResult in Boolean assertions such as...

Implements support for AssertionResult in Boolean assertions such as EXPECT_TRUE; Fixes Google Tests's tuple implementation to default-initialize its fields in the default constructor (by Zhanyong Wan); Populates gtest_stress_test.cc with actual tests.
parent 060804de
...@@ -276,7 +276,9 @@ test_gtest_sole_header_test_LDADD = lib/libgtest_main.la ...@@ -276,7 +276,9 @@ test_gtest_sole_header_test_LDADD = lib/libgtest_main.la
TESTS += test/gtest_stress_test TESTS += test/gtest_stress_test
check_PROGRAMS += test/gtest_stress_test check_PROGRAMS += test/gtest_stress_test
test_gtest_stress_test_SOURCES = test/gtest_stress_test.cc test_gtest_stress_test_SOURCES = test/gtest_stress_test.cc
test_gtest_stress_test_LDADD = lib/libgtest.la test_gtest_stress_test_CXXFLAGS = $(AM_CXXFLAGS) $(PTHREAD_CFLAGS)
test_gtest_stress_test_LDADD = $(PTHREAD_LIBS) $(PTHREAD_CFLAGS) \
lib/libgtest.la
TESTS += test/gtest-test-part_test TESTS += test/gtest-test-part_test
check_PROGRAMS += test/gtest-test-part_test check_PROGRAMS += test/gtest-test-part_test
......
...@@ -177,63 +177,145 @@ String StreamableToString(const T& streamable) { ...@@ -177,63 +177,145 @@ String StreamableToString(const T& streamable) {
// A class for indicating whether an assertion was successful. When // A class for indicating whether an assertion was successful. When
// the assertion wasn't successful, the AssertionResult object // the assertion wasn't successful, the AssertionResult object
// remembers a non-empty message that described how it failed. // remembers a non-empty message that describes how it failed.
// //
// This class is useful for defining predicate-format functions to be // To create an instance of this class, use one of the factory functions
// used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
//
// The constructor of AssertionResult is private. To create an
// instance of this class, use one of the factory functions
// (AssertionSuccess() and AssertionFailure()). // (AssertionSuccess() and AssertionFailure()).
// //
// For example, in order to be able to write: // This class is useful for two purposes:
// 1. Defining predicate functions to be used with Boolean test assertions
// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts
// 2. Defining predicate-format functions to be
// used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
//
// For example, if you define IsEven predicate:
//
// testing::AssertionResult IsEven(int n) {
// if ((n % 2) == 0)
// return testing::AssertionSuccess();
// else
// return testing::AssertionFailure() << n << " is odd";
// }
//
// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))
// will print the message
//
// Value of: IsEven(Fib(5))
// Actual: false (5 is odd)
// Expected: true
//
// instead of a more opaque
//
// Value of: IsEven(Fib(5))
// Actual: false
// Expected: true
//
// in case IsEven is a simple Boolean predicate.
//
// If you expect your predicate to be reused and want to support informative
// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up
// about half as often as positive ones in our tests), supply messages for
// both success and failure cases:
//
// testing::AssertionResult IsEven(int n) {
// if ((n % 2) == 0)
// return testing::AssertionSuccess() << n << " is even";
// else
// return testing::AssertionFailure() << n << " is odd";
// }
//
// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print
//
// Value of: IsEven(Fib(6))
// Actual: true (8 is even)
// Expected: false
//
// NB: Predicates that support negative Boolean assertions have reduced
// performance in positive ones so be careful not to use them in tests
// that have lots (tens of thousands) of positive Boolean assertions.
//
// To use this class with EXPECT_PRED_FORMAT assertions such as:
// //
// // Verifies that Foo() returns an even number. // // Verifies that Foo() returns an even number.
// EXPECT_PRED_FORMAT1(IsEven, Foo()); // EXPECT_PRED_FORMAT1(IsEven, Foo());
// //
// you just need to define: // you need to define:
// //
// testing::AssertionResult IsEven(const char* expr, int n) { // testing::AssertionResult IsEven(const char* expr, int n) {
// if ((n % 2) == 0) return testing::AssertionSuccess(); // if ((n % 2) == 0)
// // return testing::AssertionSuccess();
// Message msg; // else
// msg << "Expected: " << expr << " is even\n" // return testing::AssertionFailure()
// << " Actual: it's " << n; // << "Expected: " << expr << " is even\n Actual: it's " << n;
// return testing::AssertionFailure(msg);
// } // }
// //
// If Foo() returns 5, you will see the following message: // If Foo() returns 5, you will see the following message:
// //
// Expected: Foo() is even // Expected: Foo() is even
// Actual: it's 5 // Actual: it's 5
//
class AssertionResult { class AssertionResult {
public: public:
// Declares factory functions for making successful and failed // Copy constructor.
// assertion results as friends. // Used in EXPECT_TRUE/FALSE(assertion_result).
friend AssertionResult AssertionSuccess(); AssertionResult(const AssertionResult& other);
friend AssertionResult AssertionFailure(const Message&); // Used in the EXPECT_TRUE/FALSE(bool_expression).
explicit AssertionResult(bool success) : success_(success) {}
// Returns true iff the assertion succeeded. // Returns true iff the assertion succeeded.
operator bool() const { return failure_message_.c_str() == NULL; } // NOLINT operator bool() const { return success_; } // NOLINT
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
AssertionResult operator!() const;
// Returns the text streamed into this AssertionResult. Test assertions
// use it when they fail (i.e., the predicate's outcome doesn't match the
// assertion's expectation). When nothing has been streamed into the
// object, returns an empty string.
const char* message() const {
return message_.get() != NULL && message_->c_str() != NULL ?
message_->c_str() : "";
}
// TODO(vladl@google.com): Remove this after making sure no clients use it.
// Deprecated; please use message() instead.
const char* failure_message() const { return message(); }
// Returns the assertion's failure message. // Streams a custom failure message into this object.
const char* failure_message() const { return failure_message_.c_str(); } template <typename T> AssertionResult& operator<<(const T& value);
private: private:
// The default constructor. It is used when the assertion succeeded. // No implementation - we want AssertionResult to be
AssertionResult() {} // copy-constructible but not assignable.
void operator=(const AssertionResult& other);
// The constructor used when the assertion failed.
explicit AssertionResult(const internal::String& failure_message); // Stores result of the assertion predicate.
bool success_;
// Stores the assertion's failure message. // Stores the message describing the condition in case the expectation
internal::String failure_message_; // construct is not satisfied with the predicate's outcome.
}; // Referenced via a pointer to avoid taking too much stack frame space
// with test assertions.
internal::scoped_ptr<internal::String> message_;
}; // class AssertionResult
// Streams a custom failure message into this object.
template <typename T>
AssertionResult& AssertionResult::operator<<(const T& value) {
Message msg;
if (message_.get() != NULL)
msg << *message_;
msg << value;
message_.reset(new internal::String(msg.GetString()));
return *this;
}
// Makes a successful assertion result. // Makes a successful assertion result.
AssertionResult AssertionSuccess(); AssertionResult AssertionSuccess();
// Makes a failed assertion result.
AssertionResult AssertionFailure();
// Makes a failed assertion result with the given failure message. // Makes a failed assertion result with the given failure message.
// Deprecated; use AssertionFailure() << msg.
AssertionResult AssertionFailure(const Message& msg); AssertionResult AssertionFailure(const Message& msg);
// The abstract class that all tests inherit from. // The abstract class that all tests inherit from.
...@@ -1603,7 +1685,9 @@ const T* TestWithParam<T>::parameter_ = NULL; ...@@ -1603,7 +1685,9 @@ const T* TestWithParam<T>::parameter_ = NULL;
#define ASSERT_ANY_THROW(statement) \ #define ASSERT_ANY_THROW(statement) \
GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)
// Boolean assertions. // Boolean assertions. Condition can be either a Boolean expression or an
// AssertionResult. For more information on how to use AssertionResult with
// these macros see comments on that class.
#define EXPECT_TRUE(condition) \ #define EXPECT_TRUE(condition) \
GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
GTEST_NONFATAL_FAILURE_) GTEST_NONFATAL_FAILURE_)
......
...@@ -299,6 +299,11 @@ AssertionResult EqFailure(const char* expected_expression, ...@@ -299,6 +299,11 @@ AssertionResult EqFailure(const char* expected_expression,
const String& actual_value, const String& actual_value,
bool ignoring_case); bool ignoring_case);
// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result,
const char* expression_text,
const char* actual_predicate_value,
const char* expected_predicate_value);
// This template class represents an IEEE floating-point number // This template class represents an IEEE floating-point number
// (either single-precision or double-precision, depending on the // (either single-precision or double-precision, depending on the
...@@ -858,12 +863,17 @@ class Random { ...@@ -858,12 +863,17 @@ class Random {
fail(gtest_msg) fail(gtest_msg)
#define GTEST_TEST_BOOLEAN_(boolexpr, booltext, actual, expected, fail) \ // Implements Boolean test assertions such as EXPECT_TRUE. expression can be
// either a boolean expression or an AssertionResult. text is a textual
// represenation of expression as it was passed into the EXPECT_TRUE.
#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::IsTrue(boolexpr)) \ if (const ::testing::AssertionResult gtest_ar_ = \
::testing::AssertionResult(expression)) \
; \ ; \
else \ else \
fail("Value of: " booltext "\n Actual: " #actual "\nExpected: " #expected) fail(::testing::internal::GetBoolAssertionFailureMessage(\
gtest_ar_, text, #actual, #expected).c_str())
#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ #define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
......
...@@ -183,7 +183,7 @@ class GTEST_1_TUPLE_(T) { ...@@ -183,7 +183,7 @@ class GTEST_1_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
tuple() {} tuple() : f0_() {}
explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}
...@@ -215,7 +215,7 @@ class GTEST_2_TUPLE_(T) { ...@@ -215,7 +215,7 @@ class GTEST_2_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
tuple() {} tuple() : f0_(), f1_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),
f1_(f1) {} f1_(f1) {}
...@@ -258,7 +258,7 @@ class GTEST_3_TUPLE_(T) { ...@@ -258,7 +258,7 @@ class GTEST_3_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
tuple() {} tuple() : f0_(), f1_(), f2_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}
...@@ -295,7 +295,7 @@ class GTEST_4_TUPLE_(T) { ...@@ -295,7 +295,7 @@ class GTEST_4_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
tuple() {} tuple() : f0_(), f1_(), f2_(), f3_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),
...@@ -336,7 +336,7 @@ class GTEST_5_TUPLE_(T) { ...@@ -336,7 +336,7 @@ class GTEST_5_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
tuple() {} tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,
...@@ -380,7 +380,7 @@ class GTEST_6_TUPLE_(T) { ...@@ -380,7 +380,7 @@ class GTEST_6_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
tuple() {} tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
...@@ -427,7 +427,7 @@ class GTEST_7_TUPLE_(T) { ...@@ -427,7 +427,7 @@ class GTEST_7_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
tuple() {} tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
...@@ -476,7 +476,7 @@ class GTEST_8_TUPLE_(T) { ...@@ -476,7 +476,7 @@ class GTEST_8_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
tuple() {} tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
...@@ -528,7 +528,7 @@ class GTEST_9_TUPLE_(T) { ...@@ -528,7 +528,7 @@ class GTEST_9_TUPLE_(T) {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
tuple() {} tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
...@@ -582,7 +582,8 @@ class tuple { ...@@ -582,7 +582,8 @@ class tuple {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
tuple() {} tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(),
f9_() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
......
...@@ -39,11 +39,11 @@ $$ This meta comment fixes auto-indentation in Emacs. }} ...@@ -39,11 +39,11 @@ $$ This meta comment fixes auto-indentation in Emacs. }}
#include <utility> // For ::std::pair. #include <utility> // For ::std::pair.
// The compiler used in Symbian 5th Edition (__S60_50__) has a bug // The compiler used in Symbian has a bug that prevents us from declaring the
// that prevents us from declaring the tuple template as a friend (it // tuple template as a friend (it complains that tuple is redefined). This
// complains that tuple is redefined). This hack bypasses the bug by // hack bypasses the bug by declaring the members that should otherwise be
// declaring the members that should otherwise be private as public. // private as public.
#if defined(__SYMBIAN32__) && __S60_50__ #if defined(__SYMBIAN32__)
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: #define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
#else #else
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ #define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
...@@ -140,7 +140,7 @@ class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] { ...@@ -140,7 +140,7 @@ class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
public: public:
template <int k> friend class gtest_internal::Get; template <int k> friend class gtest_internal::Get;
tuple() {} tuple() : $for m, [[f$(m)_()]] {}
explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]] explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
$for m, [[f$(m)_(f$m)]] {} $for m, [[f$(m)_(f$m)]] {}
......
...@@ -279,6 +279,7 @@ if BUILD_TESTS: ...@@ -279,6 +279,7 @@ if BUILD_TESTS:
GtestTest(env_with_exceptions, 'gtest_output_test_', gtest_ex) GtestTest(env_with_exceptions, 'gtest_output_test_', gtest_ex)
GtestTest(env_with_exceptions, 'gtest_throw_on_failure_ex_test', gtest_ex) GtestTest(env_with_exceptions, 'gtest_throw_on_failure_ex_test', gtest_ex)
GtestTest(env_with_threads, 'gtest-death-test_test', gtest_main) GtestTest(env_with_threads, 'gtest-death-test_test', gtest_main)
GtestTest(env_with_threads, 'gtest_stress_test', gtest)
GtestTest(env_less_optimized, 'gtest_env_var_test_', gtest) GtestTest(env_less_optimized, 'gtest_env_var_test_', gtest)
GtestTest(env_less_optimized, 'gtest_uninitialized_test_', gtest) GtestTest(env_less_optimized, 'gtest_uninitialized_test_', gtest)
GtestTest(env_use_own_tuple, 'gtest-tuple_test', gtest_use_own_tuple_main) GtestTest(env_use_own_tuple, 'gtest-tuple_test', gtest_use_own_tuple_main)
......
...@@ -952,21 +952,37 @@ String FormatForFailureMessage(wchar_t wchar) { ...@@ -952,21 +952,37 @@ String FormatForFailureMessage(wchar_t wchar) {
} // namespace internal } // namespace internal
// AssertionResult constructor. // AssertionResult constructors.
AssertionResult::AssertionResult(const internal::String& failure_message) // Used in EXPECT_TRUE/FALSE(assertion_result).
: failure_message_(failure_message) { AssertionResult::AssertionResult(const AssertionResult& other)
: success_(other.success_),
message_(other.message_.get() != NULL ?
new internal::String(*other.message_) :
static_cast<internal::String*>(NULL)) {
} }
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
AssertionResult AssertionResult::operator!() const {
AssertionResult negation(!success_);
if (message_.get() != NULL)
negation << *message_;
return negation;
}
// Makes a successful assertion result. // Makes a successful assertion result.
AssertionResult AssertionSuccess() { AssertionResult AssertionSuccess() {
return AssertionResult(); return AssertionResult(true);
} }
// Makes a failed assertion result.
AssertionResult AssertionFailure() {
return AssertionResult(false);
}
// Makes a failed assertion result with the given failure message. // Makes a failed assertion result with the given failure message.
// Deprecated; use AssertionFailure() << message.
AssertionResult AssertionFailure(const Message& message) { AssertionResult AssertionFailure(const Message& message) {
return AssertionResult(message.GetString()); return AssertionFailure() << message;
} }
namespace internal { namespace internal {
...@@ -1008,6 +1024,20 @@ AssertionResult EqFailure(const char* expected_expression, ...@@ -1008,6 +1024,20 @@ AssertionResult EqFailure(const char* expected_expression,
return AssertionFailure(msg); return AssertionFailure(msg);
} }
// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result,
const char* expression_text,
const char* actual_predicate_value,
const char* expected_predicate_value) {
const char* actual_message = assertion_result.message();
Message msg;
msg << "Value of: " << expression_text
<< "\n Actual: " << actual_predicate_value;
if (actual_message[0] != '\0')
msg << " (" << actual_message << ")";
msg << "\nExpected: " << expected_predicate_value;
return msg.GetString();
}
// Helper function for implementing ASSERT_NEAR. // Helper function for implementing ASSERT_NEAR.
AssertionResult DoubleNearPredFormat(const char* expr1, AssertionResult DoubleNearPredFormat(const char* expr1,
......
...@@ -135,12 +135,44 @@ TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) { ...@@ -135,12 +135,44 @@ TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) {
<< "Changing a reference field should update the underlying variable."; << "Changing a reference field should update the underlying variable.";
} }
// Tests tuple's default constructor. // Tests that tuple's default constructor default initializes each field.
TEST(TupleConstructorTest, DefaultConstructor) { // This test needs to compile without generating warnings.
// We are just testing that the following compiles. TEST(TupleConstructorTest, DefaultConstructorDefaultInitializesEachField) {
// The TR1 report requires that tuple's default constructor default
// initializes each field, even if it's a primitive type. If the
// implementation forgets to do this, this test will catch it by
// generating warnings about using uninitialized variables (assuming
// a decent compiler).
tuple<> empty; tuple<> empty;
tuple<int> one_field;
tuple<double, char, bool*> three_fields; tuple<int> a1, b1;
b1 = a1;
EXPECT_EQ(0, get<0>(b1));
tuple<int, double> a2, b2;
b2 = a2;
EXPECT_EQ(0, get<0>(b2));
EXPECT_EQ(0.0, get<1>(b2));
tuple<double, char, bool*> a3, b3;
b3 = a3;
EXPECT_EQ(0.0, get<0>(b3));
EXPECT_EQ('\0', get<1>(b3));
EXPECT_EQ(NULL, get<2>(b3));
tuple<int, int, int, int, int, int, int, int, int, int> a10, b10;
b10 = a10;
EXPECT_EQ(0, get<0>(b10));
EXPECT_EQ(0, get<1>(b10));
EXPECT_EQ(0, get<2>(b10));
EXPECT_EQ(0, get<3>(b10));
EXPECT_EQ(0, get<4>(b10));
EXPECT_EQ(0, get<5>(b10));
EXPECT_EQ(0, get<6>(b10));
EXPECT_EQ(0, get<7>(b10));
EXPECT_EQ(0, get<8>(b10));
EXPECT_EQ(0, get<9>(b10));
} }
// Tests constructing a tuple from its fields. // Tests constructing a tuple from its fields.
......
...@@ -32,9 +32,10 @@ ...@@ -32,9 +32,10 @@
// Tests that SCOPED_TRACE() and various Google Test assertions can be // Tests that SCOPED_TRACE() and various Google Test assertions can be
// used in a large number of threads concurrently. // used in a large number of threads concurrently.
#include <iostream>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <iostream>
// We must define this macro in order to #include // We must define this macro in order to #include
// gtest-internal-inl.h. This is how Google Test prevents a user from // gtest-internal-inl.h. This is how Google Test prevents a user from
// accidentally depending on its internal implementation. // accidentally depending on its internal implementation.
...@@ -42,6 +43,8 @@ ...@@ -42,6 +43,8 @@
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_ #undef GTEST_IMPLEMENTATION_
#if GTEST_IS_THREADSAFE
namespace testing { namespace testing {
namespace { namespace {
...@@ -49,6 +52,20 @@ using internal::String; ...@@ -49,6 +52,20 @@ using internal::String;
using internal::TestPropertyKeyIs; using internal::TestPropertyKeyIs;
using internal::Vector; using internal::Vector;
// In order to run tests in this file, for platforms where Google Test is
// thread safe, implement ThreadWithParam with the following interface:
//
// template <typename T> class ThreadWithParam {
// public:
// // Creates the thread. The thread should execute thread_func(param) when
// // started by a call to Start().
// ThreadWithParam(void (*thread_func)(T), T param);
// // Starts the thread.
// void Start();
// // Waits for the thread to finish.
// void Join();
// };
// How many threads to create? // How many threads to create?
const int kThreadCount = 50; const int kThreadCount = 50;
...@@ -77,7 +94,7 @@ void ExpectKeyAndValueWereRecordedForId(const Vector<TestProperty>& properties, ...@@ -77,7 +94,7 @@ void ExpectKeyAndValueWereRecordedForId(const Vector<TestProperty>& properties,
// Calls a large number of Google Test assertions, where exactly one of them // Calls a large number of Google Test assertions, where exactly one of them
// will fail. // will fail.
void ManyAsserts(int id) { void ManyAsserts(int id) {
::std::cout << "Thread #" << id << " running...\n"; GTEST_LOG_(INFO) << "Thread #" << id << " running...";
SCOPED_TRACE(Message() << "Thread #" << id); SCOPED_TRACE(Message() << "Thread #" << id);
...@@ -104,41 +121,125 @@ void ManyAsserts(int id) { ...@@ -104,41 +121,125 @@ void ManyAsserts(int id) {
} }
} }
void CheckTestFailureCount(int expected_failures) {
const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
const TestResult* const result = info->result();
GTEST_CHECK_(expected_failures == result->total_part_count())
<< "Logged " << result->total_part_count() << " failures "
<< " vs. " << expected_failures << " expected";
}
// Tests using SCOPED_TRACE() and Google Test assertions in many threads // Tests using SCOPED_TRACE() and Google Test assertions in many threads
// concurrently. // concurrently.
TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) { TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) {
// TODO(wan): when Google Test is made thread-safe, run ThreadWithParam<int>* threads[kThreadCount] = {};
// ManyAsserts() in many threads here. for (int i = 0; i != kThreadCount; i++) {
// Creates a thread to run the ManyAsserts() function.
threads[i] = new ThreadWithParam<int>(&ManyAsserts, i);
// Starts the thread.
threads[i]->Start();
}
// At this point, we have many threads running.
for (int i = 0; i != kThreadCount; i++) {
// We block until the thread is done.
threads[i]->Join();
delete threads[i];
threads[i] = NULL;
}
// Ensures that kThreadCount*kThreadCount failures have been reported.
const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
const TestResult* const result = info->result();
Vector<TestProperty> properties;
// We have no access to the TestResult's list of properties but we can
// copy them one by one.
for (int i = 0; i < result->test_property_count(); ++i)
properties.PushBack(result->GetTestProperty(i));
EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count())
<< "String and int values recorded on each thread, "
<< "as well as one shared_key";
for (int i = 0; i < kThreadCount; ++i) {
ExpectKeyAndValueWereRecordedForId(properties, i, "string");
ExpectKeyAndValueWereRecordedForId(properties, i, "int");
}
CheckTestFailureCount(kThreadCount*kThreadCount);
}
void FailingThread(bool is_fatal) {
if (is_fatal)
FAIL() << "Fatal failure in some other thread. "
<< "(This failure is expected.)";
else
ADD_FAILURE() << "Non-fatal failure in some other thread. "
<< "(This failure is expected.)";
}
void GenerateFatalFailureInAnotherThread(bool is_fatal) {
ThreadWithParam<bool> thread(&FailingThread, is_fatal);
thread.Start();
thread.Join();
} }
TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) { TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) {
// TODO(mheule@google.com): Test this works correctly when Google EXPECT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
// Test is made thread-safe. // We should only have one failure (the one from
// GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE
// should succeed.
CheckTestFailureCount(1);
} }
void AssertNoFatalFailureIgnoresFailuresInOtherThreads() {
ASSERT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
}
TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) { TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) {
// TODO(mheule@google.com): Test this works correctly when Google // Using a subroutine, to make sure, that the test continues.
// Test is made thread-safe. AssertNoFatalFailureIgnoresFailuresInOtherThreads();
// We should only have one failure (the one from
// GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE
// should succeed.
CheckTestFailureCount(1);
} }
TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) { TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) {
// TODO(mheule@google.com): Test this works correctly when Google // This statement should fail, since the current thread doesn't generate a
// Test is made thread-safe. // fatal failure, only another one does.
EXPECT_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true), "expected");
CheckTestFailureCount(2);
} }
TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) { TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) {
// TODO(wan@google.com): Test this works correctly when Google Test // This statement should succeed, because failures in all threads are
// is made thread-safe. // considered.
EXPECT_FATAL_FAILURE_ON_ALL_THREADS(
GenerateFatalFailureInAnotherThread(true), "expected");
CheckTestFailureCount(0);
// We need to add a failure, because main() checks that there are failures.
// But when only this test is run, we shouldn't have any failures.
ADD_FAILURE() << "This is an expected non-fatal failure.";
} }
TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) { TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) {
// TODO(mheule@google.com): Test this works correctly when Google // This statement should fail, since the current thread doesn't generate a
// Test is made thread-safe. // fatal failure, only another one does.
EXPECT_NONFATAL_FAILURE(GenerateFatalFailureInAnotherThread(false),
"expected");
CheckTestFailureCount(2);
} }
TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) { TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) {
// TODO(wan@google.com): Test this works correctly when Google Test // This statement should succeed, because failures in all threads are
// is made thread-safe. // considered.
EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(
GenerateFatalFailureInAnotherThread(false), "expected");
CheckTestFailureCount(0);
// We need to add a failure, because main() checks that there are failures,
// But when only this test is run, we shouldn't have any failures.
ADD_FAILURE() << "This is an expected non-fatal failure.";
} }
} // namespace } // namespace
...@@ -147,5 +248,20 @@ TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) { ...@@ -147,5 +248,20 @@ TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
const int result = RUN_ALL_TESTS(); // Expected to fail.
GTEST_CHECK_(result == 1) << "RUN_ALL_TESTS() did not fail as expected";
printf("\nPASS\n");
return 0;
}
#else
TEST(StressTest,
DISABLED_ThreadSafetyTestsAreSkippedWhenGoogleTestIsNotThreadSafe) {
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }
#endif // GTEST_IS_THREADSAFE
...@@ -2418,6 +2418,25 @@ AssertionResult AssertIsEven(const char* expr, int n) { ...@@ -2418,6 +2418,25 @@ AssertionResult AssertIsEven(const char* expr, int n) {
return AssertionFailure(msg); return AssertionFailure(msg);
} }
// A predicate function that returns AssertionResult for use in
// EXPECT/ASSERT_TRUE/FALSE.
AssertionResult ResultIsEven(int n) {
if (IsEven(n))
return AssertionSuccess() << n << " is even";
else
return AssertionFailure() << n << " is odd";
}
// A predicate function that returns AssertionResult but gives no
// explanation why it succeeds. Needed for testing that
// EXPECT/ASSERT_FALSE handles such functions correctly.
AssertionResult ResultIsEvenNoExplanation(int n) {
if (IsEven(n))
return AssertionSuccess();
else
return AssertionFailure() << n << " is odd";
}
// A predicate-formatter functor that asserts the argument is an even // A predicate-formatter functor that asserts the argument is an even
// number. // number.
struct AssertIsEvenFunctor { struct AssertIsEvenFunctor {
...@@ -3786,6 +3805,20 @@ TEST(AssertionTest, ASSERT_TRUE) { ...@@ -3786,6 +3805,20 @@ TEST(AssertionTest, ASSERT_TRUE) {
"2 < 1"); "2 < 1");
} }
// Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult.
TEST(AssertionTest, AssertTrueWithAssertionResult) {
ASSERT_TRUE(ResultIsEven(2));
EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)),
"Value of: ResultIsEven(3)\n"
" Actual: false (3 is odd)\n"
"Expected: true");
ASSERT_TRUE(ResultIsEvenNoExplanation(2));
EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)),
"Value of: ResultIsEvenNoExplanation(3)\n"
" Actual: false (3 is odd)\n"
"Expected: true");
}
// Tests ASSERT_FALSE. // Tests ASSERT_FALSE.
TEST(AssertionTest, ASSERT_FALSE) { TEST(AssertionTest, ASSERT_FALSE) {
ASSERT_FALSE(2 < 1); // NOLINT ASSERT_FALSE(2 < 1); // NOLINT
...@@ -3795,6 +3828,20 @@ TEST(AssertionTest, ASSERT_FALSE) { ...@@ -3795,6 +3828,20 @@ TEST(AssertionTest, ASSERT_FALSE) {
"Expected: false"); "Expected: false");
} }
// Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult.
TEST(AssertionTest, AssertFalseWithAssertionResult) {
ASSERT_FALSE(ResultIsEven(3));
EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)),
"Value of: ResultIsEven(2)\n"
" Actual: true (2 is even)\n"
"Expected: false");
ASSERT_FALSE(ResultIsEvenNoExplanation(3));
EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)),
"Value of: ResultIsEvenNoExplanation(2)\n"
" Actual: true\n"
"Expected: false");
}
#ifdef __BORLANDC__ #ifdef __BORLANDC__
// Restores warnings after previous "#pragma option push" supressed them // Restores warnings after previous "#pragma option push" supressed them
#pragma option pop #pragma option pop
...@@ -4336,6 +4383,20 @@ TEST(ExpectTest, EXPECT_TRUE) { ...@@ -4336,6 +4383,20 @@ TEST(ExpectTest, EXPECT_TRUE) {
"2 > 3"); "2 > 3");
} }
// Tests EXPECT_TRUE(predicate) for predicates returning AssertionResult.
TEST(ExpectTest, ExpectTrueWithAssertionResult) {
EXPECT_TRUE(ResultIsEven(2));
EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEven(3)),
"Value of: ResultIsEven(3)\n"
" Actual: false (3 is odd)\n"
"Expected: true");
EXPECT_TRUE(ResultIsEvenNoExplanation(2));
EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEvenNoExplanation(3)),
"Value of: ResultIsEvenNoExplanation(3)\n"
" Actual: false (3 is odd)\n"
"Expected: true");
}
// Tests EXPECT_FALSE. // Tests EXPECT_FALSE.
TEST(ExpectTest, EXPECT_FALSE) { TEST(ExpectTest, EXPECT_FALSE) {
EXPECT_FALSE(2 < 1); // NOLINT EXPECT_FALSE(2 < 1); // NOLINT
...@@ -4347,6 +4408,20 @@ TEST(ExpectTest, EXPECT_FALSE) { ...@@ -4347,6 +4408,20 @@ TEST(ExpectTest, EXPECT_FALSE) {
"2 < 3"); "2 < 3");
} }
// Tests EXPECT_FALSE(predicate) for predicates returning AssertionResult.
TEST(ExpectTest, ExpectFalseWithAssertionResult) {
EXPECT_FALSE(ResultIsEven(3));
EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEven(2)),
"Value of: ResultIsEven(2)\n"
" Actual: true (2 is even)\n"
"Expected: false");
EXPECT_FALSE(ResultIsEvenNoExplanation(3));
EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEvenNoExplanation(2)),
"Value of: ResultIsEvenNoExplanation(2)\n"
" Actual: true\n"
"Expected: false");
}
#ifdef __BORLANDC__ #ifdef __BORLANDC__
// Restores warnings after previous "#pragma option push" supressed them // Restores warnings after previous "#pragma option push" supressed them
#pragma option pop #pragma option pop
...@@ -4952,6 +5027,63 @@ TEST_F(TestLifeCycleTest, Test2) { ...@@ -4952,6 +5027,63 @@ TEST_F(TestLifeCycleTest, Test2) {
} // namespace } // namespace
// Tests that the copy constructor works when it is NOT optimized away by
// the compiler.
TEST(AssertionResultTest, CopyConstructorWorksWhenNotOptimied) {
// Checks that the copy constructor doesn't try to dereference NULL pointers
// in the source object.
AssertionResult r1 = AssertionSuccess();
AssertionResult r2 = r1;
// The following line is added to prevent the compiler from optimizing
// away the constructor call.
r1 << "abc";
AssertionResult r3 = r1;
EXPECT_EQ(static_cast<bool>(r3), static_cast<bool>(r1));
EXPECT_STREQ("abc", r1.message());
}
// Tests that AssertionSuccess and AssertionFailure construct
// AssertionResult objects as expected.
TEST(AssertionResultTest, ConstructionWorks) {
AssertionResult r1 = AssertionSuccess();
EXPECT_TRUE(r1);
EXPECT_STREQ("", r1.message());
AssertionResult r2 = AssertionSuccess() << "abc";
EXPECT_TRUE(r2);
EXPECT_STREQ("abc", r2.message());
AssertionResult r3 = AssertionFailure();
EXPECT_FALSE(r3);
EXPECT_STREQ("", r3.message());
AssertionResult r4 = AssertionFailure() << "def";
EXPECT_FALSE(r4);
EXPECT_STREQ("def", r4.message());
AssertionResult r5 = AssertionFailure(Message() << "ghi");
EXPECT_FALSE(r5);
EXPECT_STREQ("ghi", r5.message());
}
// Tests that the negation fips the predicate result but keeps the message.
TEST(AssertionResultTest, NegationWorks) {
AssertionResult r1 = AssertionSuccess() << "abc";
EXPECT_FALSE(!r1);
EXPECT_STREQ("abc", (!r1).message());
AssertionResult r2 = AssertionFailure() << "def";
EXPECT_TRUE(!r2);
EXPECT_STREQ("def", (!r2).message());
}
TEST(AssertionResultTest, StreamingWorks) {
AssertionResult r = AssertionSuccess();
r << "abc" << 'd' << 0 << true;
EXPECT_STREQ("abcd0true", r.message());
}
// Tests streaming a user type whose definition and operator << are // Tests streaming a user type whose definition and operator << are
// both in the global namespace. // both in the global namespace.
class Base { class Base {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment