Adds support for type-parameterized tests (by Zhanyong Wan); also adds case-insensitive wide string comparison to the String class (by Vlad Losev).

This commit is contained in:
shiqian 2008-09-08 17:55:52 +00:00
parent 0c5a66245b
commit a2b1a8556e
17 changed files with 930 additions and 137 deletions

View File

@ -1,9 +1,12 @@
# Automake file
# TODO(chandlerc@google.com): automate the generation of *.h from *.h.pump.
# Nonstandard package files for distribution
EXTRA_DIST = \
CHANGES \
CONTRIBUTORS \
include/gtest/internal/gtest-type-util.h.pump \
scripts/gen_gtest_pred_impl.py
# MSVC project files
@ -19,6 +22,24 @@ EXTRA_DIST += \
msvc/gtest_uninitialized_test_.vcproj \
msvc/gtest_unittest.vcproj
# xcode project files
EXTRA_DIST += \
xcode/Config/DebugProject.xcconfig \
xcode/Config/FrameworkTarget.xcconfig \
xcode/Config/General.xcconfig \
xcode/Config/ReleaseProject.xcconfig \
xcode/Resources/Info.plist \
xcode/Scripts/versiongenerate.py \
xcode/gtest.xcodeproj/project.pbxproj
# xcode sample files
EXTRA_DIST += \
xcode/Samples/FrameworkSample/Info.plist \
xcode/Samples/FrameworkSample/widget_test.cc \
xcode/Samples/FrameworkSample/widget.cc \
xcode/Samples/FrameworkSample/widget.h \
xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj
# TODO(wan@google.com): integrate scripts/gen_gtest_pred_impl.py into
# the build system such that a user can specify the maximum predicate
# arity here and have the script automatically generate the
@ -44,14 +65,16 @@ lib_libgtest_la_SOURCES = src/gtest.cc \
src/gtest-death-test.cc \
src/gtest-filepath.cc \
src/gtest-internal-inl.h \
src/gtest-port.cc
src/gtest-port.cc \
src/gtest-typed-test.cc
pkginclude_HEADERS = include/gtest/gtest.h \
include/gtest/gtest-death-test.h \
include/gtest/gtest-message.h \
include/gtest/gtest-spi.h \
include/gtest/gtest_pred_impl.h \
include/gtest/gtest_prod.h
include/gtest/gtest_prod.h \
include/gtest/gtest-typed-test.h
pkginclude_internaldir = $(pkgincludedir)/internal
pkginclude_internal_HEADERS = \
@ -59,7 +82,8 @@ pkginclude_internal_HEADERS = \
include/gtest/internal/gtest-filepath.h \
include/gtest/internal/gtest-internal.h \
include/gtest/internal/gtest-port.h \
include/gtest/internal/gtest-string.h
include/gtest/internal/gtest-string.h \
include/gtest/internal/gtest-type-util.h
lib_libgtest_main_la_SOURCES = src/gtest_main.cc
lib_libgtest_main_la_LIBADD = lib/libgtest.la
@ -116,6 +140,12 @@ samples_sample5_unittest_SOURCES = samples/sample5_unittest.cc
samples_sample5_unittest_LDADD = lib/libgtest_main.la \
samples/libsamples.la
TESTS += samples/sample6_unittest
check_PROGRAMS += samples/sample6_unittest
samples_sample6_unittest_SOURCES = samples/sample6_unittest.cc
samples_sample6_unittest_LDADD = lib/libgtest_main.la \
samples/libsamples.la
TESTS += test/gtest_unittest
check_PROGRAMS += test/gtest_unittest
test_gtest_unittest_SOURCES = test/gtest_unittest.cc
@ -179,6 +209,13 @@ check_PROGRAMS += test/gtest_stress_test
test_gtest_stress_test_SOURCES = test/gtest_stress_test.cc
test_gtest_stress_test_LDADD = lib/libgtest.la
TESTS += test/gtest-typed-test_test
check_PROGRAMS += test/gtest-typed-test_test
test_gtest_typed_test_test_SOURCES = test/gtest-typed-test_test.cc \
test/gtest-typed-test2_test.cc \
test/gtest-typed-test_test.h
test_gtest_typed_test_test_LDADD = lib/libgtest_main.la
# The following tests depend on the presence of a Python installation and are
# keyed off of it. TODO(chandlerc@google.com): While we currently only attempt
# to build and execute these tests if Autoconf has found Python v2.4 on the

19
README
View File

@ -104,7 +104,6 @@ which contains all of the source code. Here are some examples in Linux:
Building the Source
-------------------
### Linux, Mac OS X (without Xcode), and Cygwin ###
There are two primary options for building the source at this point: build it
inside the source code tree, or in a separate directory. We recommend building
@ -173,4 +172,22 @@ in the "Variables to be set in the environment:" list, where you replace
when you run your executable, it will load the framework and your test will
run as expected.
Regenerating Source Files
-------------------------
Some of Google Test's source files are generated from templates (not
in the C++ sense) using a script. A template file is named FOO.pump,
where FOO is the name of the file it will generate. For example, the
file include/gtest/internal/gtest-type-util.h.pump is used to generate
gtest-type-util.h in the same directory.
Normally you don't need to worry about regenerating the source files,
unless you need to modify them (e.g. if you are working on a patch for
Google Test). In that case, you should modify the corresponding .pump
files instead and run the 'pump' script (for Pump is Useful for Meta
Programming) to regenerate them. We are still working on releasing
the script and its documentation. If you need it now, please email
googletestframework@googlegroups.com such that we know to make it
happen sooner.
Happy testing!

View File

@ -62,11 +62,13 @@
// Windows proper with Visual C++ and MS C library (_MSC_VER && !_WIN32_WCE) and
// Windows Mobile with Visual C++ and no C library (_WIN32_WCE).
#include <limits>
#include <gtest/internal/gtest-internal.h>
#include <gtest/internal/gtest-string.h>
#include <gtest/gtest-death-test.h>
#include <gtest/gtest-message.h>
#include <gtest/gtest_prod.h>
#include <gtest/gtest-typed-test.h>
// Depending on the platform, different string classes are available.
// On Windows, ::std::string compiles only when exceptions are
@ -217,12 +219,28 @@ class Test {
// Defines types for pointers to functions that set up and tear down
// a test case.
typedef void (*SetUpTestCaseFunc)();
typedef void (*TearDownTestCaseFunc)();
typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc;
typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc;
// The d'tor is virtual as we intend to inherit from Test.
virtual ~Test();
// Sets up the stuff shared by all tests in this test case.
//
// Google Test will call Foo::SetUpTestCase() before running the first
// test in test case Foo. Hence a sub-class can define its own
// SetUpTestCase() method to shadow the one defined in the super
// class.
static void SetUpTestCase() {}
// Tears down the stuff shared by all tests in this test case.
//
// Google Test will call Foo::TearDownTestCase() after running the last
// test in test case Foo. Hence a sub-class can define its own
// TearDownTestCase() method to shadow the one defined in the super
// class.
static void TearDownTestCase() {}
// Returns true iff the current test has a fatal failure.
static bool HasFatalFailure();
@ -245,22 +263,6 @@ class Test {
// Creates a Test object.
Test();
// Sets up the stuff shared by all tests in this test case.
//
// Google Test will call Foo::SetUpTestCase() before running the first
// test in test case Foo. Hence a sub-class can define its own
// SetUpTestCase() method to shadow the one defined in the super
// class.
static void SetUpTestCase() {}
// Tears down the stuff shared by all tests in this test case.
//
// Google Test will call Foo::TearDownTestCase() after running the last
// test in test case Foo. Hence a sub-class can define its own
// TearDownTestCase() method to shadow the one defined in the super
// class.
static void TearDownTestCase() {}
// Sets up the test fixture.
virtual void SetUp();
@ -327,36 +329,18 @@ class TestInfo {
// don't inherit from TestInfo.
~TestInfo();
// Creates a TestInfo object and registers it with the UnitTest
// singleton; returns the created object.
//
// Arguments:
//
// test_case_name: name of the test case
// name: name of the test
// fixture_class_id: ID of the test fixture class
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
// factory: Pointer to the factory that creates a test object.
// The newly created TestInfo instance will assume
// ownershi pof the factory object.
//
// This is public only because it's needed by the TEST and TEST_F macros.
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
static TestInfo* MakeAndRegisterInstance(
const char* test_case_name,
const char* name,
internal::TypeId fixture_class_id,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc,
internal::TestFactoryBase* factory);
// Returns the test case name.
const char* test_case_name() const;
// Returns the test name.
const char* name() const;
// Returns the test case comment.
const char* test_case_comment() const;
// Returns the test comment.
const char* comment() const;
// Returns true if this test should run.
//
// Google Test allows the user to filter the tests by their full names.
@ -383,6 +367,13 @@ class TestInfo {
friend class internal::UnitTestImpl;
friend class Test;
friend class TestCase;
friend TestInfo* internal::MakeAndRegisterTestInfo(
const char* test_case_name, const char* name,
const char* test_case_comment, const char* comment,
internal::TypeId fixture_class_id,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc,
internal::TestFactoryBase* factory);
// Increments the number of death tests encountered in this test so
// far.
@ -395,6 +386,7 @@ class TestInfo {
// Constructs a TestInfo object. The newly constructed instance assumes
// ownership of the factory object.
TestInfo(const char* test_case_name, const char* name,
const char* test_case_comment, const char* comment,
internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory);
@ -1118,9 +1110,10 @@ AssertionResult DoubleLE(const char* expr1, const char* expr2,
//
// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr)
//
// When expr unexpectedly fails or succeeds, Google Test prints the expected result
// and the actual result with both a human-readable string representation of
// the error, if available, as well as the hex result code.
// When expr unexpectedly fails or succeeds, Google Test prints the
// expected result and the actual result with both a human-readable
// string representation of the error, if available, as well as the
// hex result code.
#define EXPECT_HRESULT_SUCCEEDED(expr) \
EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))

View File

@ -46,11 +46,15 @@
#include <unistd.h>
#endif // GTEST_OS_LINUX
#include <iomanip> // NOLINT
#include <limits> // NOLINT
#include <ctype.h>
#include <string.h>
#include <iomanip>
#include <limits>
#include <set>
#include <gtest/internal/gtest-string.h>
#include <gtest/internal/gtest-filepath.h>
#include <gtest/internal/gtest-type-util.h>
// Due to C++ preprocessor weirdness, we need double indirection to
// concatenate two tokens when one of them is __LINE__. Writing
@ -521,6 +525,182 @@ AssertionResult IsHRESULTFailure(const char* expr, long hr); // NOLINT
#endif // GTEST_OS_WINDOWS
// Formats a source file path and a line number as they would appear
// in a compiler error message.
inline String FormatFileLocation(const char* file, int line) {
const char* const file_name = file == NULL ? "unknown file" : file;
if (line < 0) {
return String::Format("%s:", file_name);
}
#ifdef _MSC_VER
return String::Format("%s(%d):", file_name, line);
#else
return String::Format("%s:%d:", file_name, line);
#endif // _MSC_VER
}
// Types of SetUpTestCase() and TearDownTestCase() functions.
typedef void (*SetUpTestCaseFunc)();
typedef void (*TearDownTestCaseFunc)();
// Creates a new TestInfo object and registers it with Google Test;
// returns the created object.
//
// Arguments:
//
// test_case_name: name of the test case
// name: name of the test
// test_case_comment: a comment on the test case that will be included in
// the test output
// comment: a comment on the test that will be included in the
// test output
// fixture_class_id: ID of the test fixture class
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
// factory: pointer to the factory that creates a test object.
// The newly created TestInfo instance will assume
// ownership of the factory object.
TestInfo* MakeAndRegisterTestInfo(
const char* test_case_name, const char* name,
const char* test_case_comment, const char* comment,
TypeId fixture_class_id,
SetUpTestCaseFunc set_up_tc,
TearDownTestCaseFunc tear_down_tc,
TestFactoryBase* factory);
#if defined(GTEST_HAS_TYPED_TEST) || defined(GTEST_HAS_TYPED_TEST_P)
// State of the definition of a type-parameterized test case.
class TypedTestCasePState {
public:
TypedTestCasePState() : registered_(false) {}
// Adds the given test name to defined_test_names_ and return true
// if the test case hasn't been registered; otherwise aborts the
// program.
bool AddTestName(const char* file, int line, const char* case_name,
const char* test_name) {
if (registered_) {
fprintf(stderr, "%s Test %s must be defined before "
"REGISTER_TYPED_TEST_CASE_P(%s, ...).\n",
FormatFileLocation(file, line).c_str(), test_name, case_name);
abort();
}
defined_test_names_.insert(test_name);
return true;
}
// Verifies that registered_tests match the test names in
// defined_test_names_; returns registered_tests if successful, or
// aborts the program otherwise.
const char* VerifyRegisteredTestNames(
const char* file, int line, const char* registered_tests);
private:
bool registered_;
::std::set<const char*> defined_test_names_;
};
// Skips to the first non-space char after the first comma in 'str';
// returns NULL if no comma is found in 'str'.
inline const char* SkipComma(const char* str) {
const char* comma = strchr(str, ',');
if (comma == NULL) {
return NULL;
}
while (isspace(*(++comma))) {}
return comma;
}
// Returns the prefix of 'str' before the first comma in it; returns
// the entire string if it contains no comma.
inline String GetPrefixUntilComma(const char* str) {
const char* comma = strchr(str, ',');
return comma == NULL ? String(str) : String(str, comma - str);
}
// TypeParameterizedTest<Fixture, TestSel, Types>::Register()
// registers a list of type-parameterized tests with Google Test. The
// return value is insignificant - we just need to return something
// such that we can call this function in a namespace scope.
//
// Implementation note: The GTEST_TEMPLATE_ macro declares a template
// template parameter. It's defined in gtest-type-util.h.
template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
class TypeParameterizedTest {
public:
// 'index' is the index of the test in the type list 'Types'
// specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
// Types). Valid values for 'index' are [0, N - 1] where N is the
// length of Types.
static bool Register(const char* prefix, const char* case_name,
const char* test_names, int index) {
typedef typename Types::Head Type;
typedef Fixture<Type> FixtureClass;
typedef typename GTEST_BIND_(TestSel, Type) TestClass;
// First, registers the first type-parameterized test in the type
// list.
MakeAndRegisterTestInfo(
String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/",
case_name, index).c_str(),
GetPrefixUntilComma(test_names).c_str(),
String::Format("TypeParam = %s", GetTypeName<Type>().c_str()).c_str(),
"",
GetTypeId<FixtureClass>(),
TestClass::SetUpTestCase,
TestClass::TearDownTestCase,
new TestFactoryImpl<TestClass>);
// Next, recurses (at compile time) with the tail of the type list.
return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>
::Register(prefix, case_name, test_names, index + 1);
}
};
// The base case for the compile time recursion.
template <GTEST_TEMPLATE_ Fixture, class TestSel>
class TypeParameterizedTest<Fixture, TestSel, Types0> {
public:
static bool Register(const char* /*prefix*/, const char* /*case_name*/,
const char* /*test_names*/, int /*index*/) {
return true;
}
};
// TypeParameterizedTestCase<Fixture, Tests, Types>::Register()
// registers *all combinations* of 'Tests' and 'Types' with Google
// Test. The return value is insignificant - we just need to return
// something such that we can call this function in a namespace scope.
template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
class TypeParameterizedTestCase {
public:
static bool Register(const char* prefix, const char* case_name,
const char* test_names) {
typedef typename Tests::Head Head;
// First, register the first test in 'Test' for each type in 'Types'.
TypeParameterizedTest<Fixture, Head, Types>::Register(
prefix, case_name, test_names, 0);
// Next, recurses (at compile time) with the tail of the test list.
return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>
::Register(prefix, case_name, SkipComma(test_names));
}
};
// The base case for the compile time recursion.
template <GTEST_TEMPLATE_ Fixture, typename Types>
class TypeParameterizedTestCase<Fixture, Templates0, Types> {
public:
static bool Register(const char* prefix, const char* case_name,
const char* test_names) {
return true;
}
};
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
} // namespace internal
} // namespace testing
@ -544,27 +724,32 @@ AssertionResult IsHRESULTFailure(const char* expr, long hr); // NOLINT
else \
fail("Value of: " booltext "\n Actual: " #actual "\nExpected: " #expected)
// Expands to the name of the class that implements the given test.
#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
test_case_name##_##test_name##_Test
// Helper macro for defining tests.
#define GTEST_TEST(test_case_name, test_name, parent_class)\
class test_case_name##_##test_name##_Test : public parent_class {\
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
public:\
test_case_name##_##test_name##_Test() {}\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
private:\
virtual void TestBody();\
static ::testing::TestInfo* const test_info_;\
GTEST_DISALLOW_COPY_AND_ASSIGN(test_case_name##_##test_name##_Test);\
GTEST_DISALLOW_COPY_AND_ASSIGN(\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
};\
\
::testing::TestInfo* const test_case_name##_##test_name##_Test::test_info_ =\
::testing::TestInfo::MakeAndRegisterInstance(\
#test_case_name, \
#test_name, \
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
::test_info_ =\
::testing::internal::MakeAndRegisterTestInfo(\
#test_case_name, #test_name, "", "", \
::testing::internal::GetTypeId< parent_class >(), \
parent_class::SetUpTestCase, \
parent_class::TearDownTestCase, \
new ::testing::internal::TestFactoryImpl<\
test_case_name##_##test_name##_Test>);\
void test_case_name##_##test_name##_Test::TestBody()
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_

View File

@ -73,7 +73,10 @@
// Note that it is possible that none of the GTEST_OS_ macros are defined.
//
// Macros indicating available Google Test features:
// GTEST_HAS_DEATH_TEST - defined iff death tests are supported.
// GTEST_HAS_DEATH_TEST - defined iff death tests are supported.
// GTEST_HAS_TYPED_TEST - defined iff typed tests are supported.
// GTEST_HAS_TYPED_TEST_P - defined iff type-parameterized tests are
// supported.
//
// Macros for basic C++ coding:
// GTEST_AMBIGUOUS_ELSE_BLOCKER - for disabling a gcc warning.
@ -225,6 +228,15 @@
#include <sys/mman.h>
#endif // GTEST_HAS_STD_STRING && defined(GTEST_OS_LINUX)
// Determines whether to support type-driven tests.
// Typed tests need <typeinfo> and variadic macros, which gcc and VC
// 8.0+ support.
#if defined(__GNUC__) || (_MSC_VER >= 1400)
#define GTEST_HAS_TYPED_TEST
#define GTEST_HAS_TYPED_TEST_P
#endif // defined(__GNUC__) || (_MSC_VER >= 1400)
// Determines whether the system compiler uses UTF-16 for encoding wide strings.
#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_CYGWIN) || \
defined(__SYMBIAN32__)

View File

@ -167,6 +167,21 @@ class String {
static bool CaseInsensitiveCStringEquals(const char* lhs,
const char* rhs);
// Compares two wide C strings, ignoring case. Returns true iff they
// have the same content.
//
// Unlike wcscasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL wide C string,
// including the empty string.
// NB: The implementations on different platforms slightly differ.
// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
// environment variable. On GNU platform this method uses wcscasecmp
// which compares according to LC_CTYPE category of the current locale.
// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
// current locale.
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
const wchar_t* rhs);
// Formats a list of arguments to a String, using the same format
// spec string as for printf.
//
@ -218,6 +233,10 @@ class String {
return CStringEquals(c_str_, c_str);
}
// Returns true iff this String is less than the given C string. A NULL
// string is considered less than "".
bool operator<(const String& rhs) const { return Compare(rhs) < 0; }
// Returns true iff this String doesn't equal the given C string. A NULL
// string and a non-NULL string are considered not equal.
bool operator!=(const char* c_str) const {

View File

@ -144,6 +144,21 @@
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\gtest-typed-test.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\gtest.cc">
<FileConfiguration

View File

@ -563,7 +563,8 @@ class TestResult {
class TestInfoImpl {
public:
TestInfoImpl(TestInfo* parent, const char* test_case_name,
const char* name, TypeId fixture_class_id,
const char* name, const char* test_case_comment,
const char* comment, TypeId fixture_class_id,
internal::TestFactoryBase* factory);
~TestInfoImpl();
@ -585,6 +586,12 @@ class TestInfoImpl {
// Returns the test name.
const char* name() const { return name_.c_str(); }
// Returns the test case comment.
const char* test_case_comment() const { return test_case_comment_.c_str(); }
// Returns the test comment.
const char* comment() const { return comment_.c_str(); }
// Returns the ID of the test fixture class.
TypeId fixture_class_id() const { return fixture_class_id_; }
@ -611,12 +618,14 @@ class TestInfoImpl {
private:
// These fields are immutable properties of the test.
TestInfo* const parent_; // The owner of this object
const String test_case_name_; // Test case name
const String name_; // Test name
const TypeId fixture_class_id_; // ID of the test fixture class
bool should_run_; // True iff this test should run
bool is_disabled_; // True iff this test is disabled
TestInfo* const parent_; // The owner of this object
const String test_case_name_; // Test case name
const String name_; // Test name
const String test_case_comment_; // Test case comment
const String comment_; // Test comment
const TypeId fixture_class_id_; // ID of the test fixture class
bool should_run_; // True iff this test should run
bool is_disabled_; // True iff this test is disabled
internal::TestFactoryBase* const factory_; // The factory that creates
// the test object
@ -644,7 +653,7 @@ class TestCase {
// name: name of the test case
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
TestCase(const char* name,
TestCase(const char* name, const char* comment,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc);
@ -654,6 +663,9 @@ class TestCase {
// Gets the name of the TestCase.
const char* name() const { return name_.c_str(); }
// Returns the test case comment.
const char* comment() const { return comment_.c_str(); }
// Returns true if any test in this test case should run.
bool should_run() const { return should_run_; }
@ -739,6 +751,8 @@ class TestCase {
private:
// Name of the test case.
internal::String name_;
// Comment on the test case.
internal::String comment_;
// List of TestInfos.
internal::List<TestInfo*>* test_info_list_;
// Pointer to the function that sets up the test case.
@ -799,7 +813,7 @@ class UnitTestOptions {
// This function is useful as an __except condition.
static int GTestShouldProcessSEH(DWORD exception_code);
#endif // GTEST_OS_WINDOWS
private:
// Returns true if "name" matches the ':' separated list of glob-style
// filters in "filter".
static bool MatchesFilter(const String& name, const char* filter);
@ -975,6 +989,7 @@ class UnitTestImpl : public TestPartResultReporterInterface {
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
TestCase* GetTestCase(const char* test_case_name,
const char* comment,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc);
@ -989,6 +1004,7 @@ class UnitTestImpl : public TestPartResultReporterInterface {
Test::TearDownTestCaseFunc tear_down_tc,
TestInfo * test_info) {
GetTestCase(test_info->test_case_name(),
test_info->test_case_comment(),
set_up_tc,
tear_down_tc)->AddTestInfo(test_info);
}

View File

@ -40,6 +40,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <wctype.h>
#ifdef GTEST_OS_LINUX
@ -117,8 +119,14 @@ namespace testing {
// Constants.
// A test that matches this pattern is disabled and not run.
static const char kDisableTestPattern[] = "DISABLED_*";
// A test whose test case name or test name matches this filter is
// disabled and not run.
static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*";
// A test case whose name matches this filter is considered a death
// test case and will be run before test cases whose name doesn't
// match this filter.
static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
// A test filter that matches everything.
static const char kUniversalFilter[] = "*";
@ -1516,6 +1524,39 @@ bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) {
#else // GTEST_OS_WINDOWS
return strcasecmp(lhs, rhs) == 0;
#endif // GTEST_OS_WINDOWS
}
// Compares two wide C strings, ignoring case. Returns true iff they
// have the same content.
//
// Unlike wcscasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL wide C string,
// including the empty string.
// NB: The implementations on different platforms slightly differ.
// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
// environment variable. On GNU platform this method uses wcscasecmp
// which compares according to LC_CTYPE category of the current locale.
// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
// current locale.
bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
const wchar_t* rhs) {
if ( lhs == NULL ) return rhs == NULL;
if ( rhs == NULL ) return false;
#ifdef GTEST_OS_WINDOWS
return _wcsicmp(lhs, rhs) == 0;
#elif defined(GTEST_OS_MAC)
// Mac OS X doesn't define wcscasecmp.
wint_t left, right;
do {
left = towlower(*lhs++);
right = towlower(*rhs++);
} while (left && left == right);
return left == right;
#else
return wcscasecmp(lhs, rhs) == 0;
#endif // OS selector
}
// Constructs a String by copying a given number of chars from a
@ -1716,8 +1757,8 @@ void TestResult::RecordProperty(const TestProperty& test_property) {
property_with_matching_key.SetValue(test_property.value());
}
// Adds a failure if the key is a reserved attribute of Google Test testcase tags.
// Returns true if the property is valid.
// Adds a failure if the key is a reserved attribute of Google Test
// testcase tags. Returns true if the property is valid.
bool TestResult::ValidateTestProperty(const TestProperty& test_property) {
String key(test_property.key());
if (key == "name" || key == "status" || key == "time" || key == "classname") {
@ -1973,9 +2014,12 @@ bool Test::HasFatalFailure() {
// object via impl_.
TestInfo::TestInfo(const char* test_case_name,
const char* name,
const char* test_case_comment,
const char* comment,
internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory) {
impl_ = new internal::TestInfoImpl(this, test_case_name, name,
test_case_comment, comment,
fixture_class_id, factory);
}
@ -1984,30 +2028,41 @@ TestInfo::~TestInfo() {
delete impl_;
}
// Creates a TestInfo object and registers it with the UnitTest
// singleton; returns the created object.
namespace internal {
// Creates a new TestInfo object and registers it with Google Test;
// returns the created object.
//
// Arguments:
//
// test_case_name: name of the test case
// name: name of the test
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
// factory factory object that creates a test object. The new
// TestInfo instance assumes ownership of the factory object.
TestInfo* TestInfo::MakeAndRegisterInstance(
const char* test_case_name,
const char* name,
internal::TypeId fixture_class_id,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc,
internal::TestFactoryBase* factory) {
// test_case_name: name of the test case
// name: name of the test
// test_case_comment: a comment on the test case that will be included in
// the test output
// comment: a comment on the test that will be included in the
// test output
// fixture_class_id: ID of the test fixture class
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
// factory: pointer to the factory that creates a test object.
// The newly created TestInfo instance will assume
// ownership of the factory object.
TestInfo* MakeAndRegisterTestInfo(
const char* test_case_name, const char* name,
const char* test_case_comment, const char* comment,
TypeId fixture_class_id,
SetUpTestCaseFunc set_up_tc,
TearDownTestCaseFunc tear_down_tc,
TestFactoryBase* factory) {
TestInfo* const test_info =
new TestInfo(test_case_name, name, fixture_class_id, factory);
internal::GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
new TestInfo(test_case_name, name, test_case_comment, comment,
fixture_class_id, factory);
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
return test_info;
}
} // namespace internal
// Returns the test case name.
const char* TestInfo::test_case_name() const {
return impl_->test_case_name();
@ -2018,6 +2073,16 @@ const char* TestInfo::name() const {
return impl_->name();
}
// Returns the test case comment.
const char* TestInfo::test_case_comment() const {
return impl_->test_case_comment();
}
// Returns the test comment.
const char* TestInfo::comment() const {
return impl_->comment();
}
// Returns true if this test should run.
bool TestInfo::should_run() const { return impl_->should_run(); }
@ -2170,10 +2235,11 @@ int TestCase::total_test_count() const {
// name: name of the test case
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
TestCase::TestCase(const char* name,
TestCase::TestCase(const char* name, const char* comment,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc)
: name_(name),
comment_(comment),
set_up_tc_(set_up_tc),
tear_down_tc_(tear_down_tc),
should_run_(false),
@ -2283,18 +2349,11 @@ static const char * TestPartResultTypeToString(TestPartResultType type) {
// Prints a TestPartResult.
static void PrintTestPartResult(
const TestPartResult & test_part_result) {
const char * const file_name = test_part_result.file_name();
printf("%s", file_name == NULL ? "unknown file" : file_name);
if (test_part_result.line_number() >= 0) {
#ifdef _MSC_VER
printf("(%d)", test_part_result.line_number());
#else
printf(":%d", test_part_result.line_number());
#endif
}
printf(": %s", TestPartResultTypeToString(test_part_result.type()));
printf("%s\n", test_part_result.message());
printf("%s %s%s\n",
internal::FormatFileLocation(test_part_result.file_name(),
test_part_result.line_number()).c_str(),
TestPartResultTypeToString(test_part_result.type()),
test_part_result.message());
fflush(stdout);
}
@ -2471,7 +2530,12 @@ void PrettyUnitTestResultPrinter::OnTestCaseStart(
const internal::String counts =
FormatCountableNoun(test_case->test_to_run_count(), "test", "tests");
ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("%s from %s\n", counts.c_str(), test_case_name_.c_str());
printf("%s from %s", counts.c_str(), test_case_name_.c_str());
if (test_case->comment()[0] == '\0') {
printf("\n");
} else {
printf(", where %s\n", test_case->comment());
}
fflush(stdout);
}
@ -2492,7 +2556,11 @@ void PrettyUnitTestResultPrinter::OnTestCaseEnd(
void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo * test_info) {
ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
PrintTestName(test_case_name_.c_str(), test_info->name());
printf("\n");
if (test_info->comment()[0] == '\0') {
printf("\n");
} else {
printf(", where %s\n", test_info->comment());
}
fflush(stdout);
}
@ -2553,7 +2621,16 @@ static void PrintFailedTestsPretty(const UnitTestImpl* impl) {
continue;
}
ColoredPrintf(COLOR_RED, "[ FAILED ] ");
printf("%s.%s\n", ti->test_case_name(), ti->name());
printf("%s.%s", ti->test_case_name(), ti->name());
if (ti->test_case_comment()[0] != '\0' ||
ti->comment()[0] != '\0') {
printf(", where %s", ti->test_case_comment());
if (ti->test_case_comment()[0] != '\0' &&
ti->comment()[0] != '\0') {
printf(" and ");
}
}
printf("%s\n", ti->comment());
}
}
}
@ -3244,6 +3321,7 @@ class TestCaseNameIs {
// set_up_tc: pointer to the function that sets up the test case
// tear_down_tc: pointer to the function that tears down the test case
TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
const char* comment,
Test::SetUpTestCaseFunc set_up_tc,
Test::TearDownTestCaseFunc tear_down_tc) {
// Can we find a TestCase with the given name?
@ -3253,10 +3331,11 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
if (node == NULL) {
// No. Let's create one.
TestCase* const test_case =
new TestCase(test_case_name, set_up_tc, tear_down_tc);
new TestCase(test_case_name, comment, set_up_tc, tear_down_tc);
// Is this a death test case?
if (String(test_case_name).EndsWith("DeathTest")) {
if (internal::UnitTestOptions::MatchesFilter(String(test_case_name),
kDeathTestCaseFilter)) {
// Yes. Inserts the test case after the last death test case
// defined so far.
node = test_cases_.InsertAfter(last_death_test_case_, test_case);
@ -3389,12 +3468,12 @@ int UnitTestImpl::FilterTests() {
TestInfo * const test_info = test_info_node->element();
const String test_name(test_info->name());
// A test is disabled if test case name or test name matches
// kDisableTestPattern.
// kDisableTestFilter.
const bool is_disabled =
internal::UnitTestOptions::PatternMatchesString(kDisableTestPattern,
test_case_name.c_str()) ||
internal::UnitTestOptions::PatternMatchesString(kDisableTestPattern,
test_name.c_str());
internal::UnitTestOptions::MatchesFilter(test_case_name,
kDisableTestFilter) ||
internal::UnitTestOptions::MatchesFilter(test_name,
kDisableTestFilter);
test_info->impl()->set_is_disabled(is_disabled);
const bool should_run = !is_disabled &&
@ -3511,11 +3590,15 @@ internal::TestResult* UnitTestImpl::current_test_result() {
TestInfoImpl::TestInfoImpl(TestInfo* parent,
const char* test_case_name,
const char* name,
const char* test_case_comment,
const char* comment,
TypeId fixture_class_id,
internal::TestFactoryBase* factory) :
parent_(parent),
test_case_name_(String(test_case_name)),
name_(String(name)),
test_case_comment_(String(test_case_comment)),
comment_(String(comment)),
fixture_class_id_(fixture_class_id),
should_run_(false),
is_disabled_(false),

View File

@ -103,6 +103,84 @@ class MyEnvironment : public testing::Environment {
}
};
#elif defined(TEST_CATCHES_WRONG_CASE_IN_TYPED_TEST_P)
// Tests that the compiler catches using the wrong test case name in
// TYPED_TEST_P.
#include <gtest/gtest.h>
template <typename T>
class FooTest : public testing::Test {
};
template <typename T>
class BarTest : public testing::Test {
};
TYPED_TEST_CASE_P(FooTest);
TYPED_TEST_P(BarTest, A) {} // Wrong test case name.
REGISTER_TYPED_TEST_CASE_P(FooTest, A);
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types<int>);
#elif defined(TEST_CATCHES_WRONG_CASE_IN_REGISTER_TYPED_TEST_CASE_P)
// Tests that the compiler catches using the wrong test case name in
// REGISTER_TYPED_TEST_CASE_P.
#include <gtest/gtest.h>
template <typename T>
class FooTest : public testing::Test {
};
template <typename T>
class BarTest : public testing::Test {
};
TYPED_TEST_CASE_P(FooTest);
TYPED_TEST_P(FooTest, A) {}
REGISTER_TYPED_TEST_CASE_P(BarTest, A); // Wrong test case name.
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types<int>);
#elif defined(TEST_CATCHES_WRONG_CASE_IN_INSTANTIATE_TYPED_TEST_CASE_P)
// Tests that the compiler catches using the wrong test case name in
// INSTANTIATE_TYPED_TEST_CASE_P.
#include <gtest/gtest.h>
template <typename T>
class FooTest : public testing::Test {
};
template <typename T>
class BarTest : public testing::Test {
};
TYPED_TEST_CASE_P(FooTest);
TYPED_TEST_P(FooTest, A) {}
REGISTER_TYPED_TEST_CASE_P(FooTest, A);
// Wrong test case name.
INSTANTIATE_TYPED_TEST_CASE_P(My, BarTest, testing::Types<int>);
#elif defined(TEST_CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX)
// Tests that the compiler catches instantiating TYPED_TEST_CASE_P
// twice with the same name prefix.
#include <gtest/gtest.h>
template <typename T>
class FooTest : public testing::Test {
};
TYPED_TEST_CASE_P(FooTest);
TYPED_TEST_P(FooTest, A) {}
REGISTER_TYPED_TEST_CASE_P(FooTest, A);
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types<int>);
// Wrong name prefix: "My" has been used.
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types<double>);
#else
// A sanity test. This should compile.

View File

@ -66,6 +66,18 @@ class GTestNCTest(unittest.TestCase):
('CATCHES_CALLING_SETUP_IN_ENVIRONMENT_WITH_TYPO',
[r'Setup_should_be_spelled_SetUp']),
('CATCHES_WRONG_CASE_IN_TYPED_TEST_P',
[r'BarTest.*was not declared']),
('CATCHES_WRONG_CASE_IN_REGISTER_TYPED_TEST_CASE_P',
[r'BarTest.*was not declared']),
('CATCHES_WRONG_CASE_IN_INSTANTIATE_TYPED_TEST_CASE_P',
[r'BarTest.*not declared']),
('CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX',
[r'redefinition of.*My.*FooTest']),
('SANITY',
None)
]

View File

@ -32,6 +32,8 @@
"""Tests the text output of Google C++ Testing Framework.
SYNOPSIS
gtest_output_test.py --gtest_build_dir=BUILD/DIR --gengolden
# where BUILD/DIR contains the built gtest_output_test_ file.
gtest_output_test.py --gengolden
gtest_output_test.py
"""

View File

@ -699,6 +699,97 @@ TEST(ExpectFatalFailureTest, FailsWhenStatementThrows) {
#endif // GTEST_HAS_EXCEPTIONS
// This #ifdef block tests the output of typed tests.
#ifdef GTEST_HAS_TYPED_TEST
template <typename T>
class TypedTest : public testing::Test {
};
TYPED_TEST_CASE(TypedTest, testing::Types<int>);
TYPED_TEST(TypedTest, Success) {
EXPECT_EQ(0, TypeParam());
}
TYPED_TEST(TypedTest, Failure) {
EXPECT_EQ(1, TypeParam()) << "Expected failure";
}
#endif // GTEST_HAS_TYPED_TEST
// This #ifdef block tests the output of type-parameterized tests.
#ifdef GTEST_HAS_TYPED_TEST_P
template <typename T>
class TypedTestP : public testing::Test {
};
TYPED_TEST_CASE_P(TypedTestP);
TYPED_TEST_P(TypedTestP, Success) {
EXPECT_EQ(0, TypeParam());
}
TYPED_TEST_P(TypedTestP, Failure) {
EXPECT_EQ(1, TypeParam()) << "Expected failure";
}
REGISTER_TYPED_TEST_CASE_P(TypedTestP, Success, Failure);
typedef testing::Types<unsigned char, unsigned int> UnsignedTypes;
INSTANTIATE_TYPED_TEST_CASE_P(Unsigned, TypedTestP, UnsignedTypes);
#endif // GTEST_HAS_TYPED_TEST_P
#ifdef GTEST_HAS_DEATH_TEST
// We rely on the golden file to verify that tests whose test case
// name ends with DeathTest are run first.
TEST(ADeathTest, ShouldRunFirst) {
}
#ifdef GTEST_HAS_TYPED_TEST
// We rely on the golden file to verify that typed tests whose test
// case name ends with DeathTest are run first.
template <typename T>
class ATypedDeathTest : public testing::Test {
};
typedef testing::Types<int, double> NumericTypes;
TYPED_TEST_CASE(ATypedDeathTest, NumericTypes);
TYPED_TEST(ATypedDeathTest, ShouldRunFirst) {
}
#endif // GTEST_HAS_TYPED_TEST
#ifdef GTEST_HAS_TYPED_TEST_P
// We rely on the golden file to verify that type-parameterized tests
// whose test case name ends with DeathTest are run first.
template <typename T>
class ATypeParamDeathTest : public testing::Test {
};
TYPED_TEST_CASE_P(ATypeParamDeathTest);
TYPED_TEST_P(ATypeParamDeathTest, ShouldRunFirst) {
}
REGISTER_TYPED_TEST_CASE_P(ATypeParamDeathTest, ShouldRunFirst);
INSTANTIATE_TYPED_TEST_CASE_P(My, ATypeParamDeathTest, NumericTypes);
#endif // GTEST_HAS_TYPED_TEST_P
#endif // GTEST_HAS_DEATH_TEST
// Two test environments for testing testing::AddGlobalTestEnvironment().
class FooEnvironment : public testing::Environment {

View File

@ -7,10 +7,25 @@ Expected: true
gtest_output_test_.cc:#: Failure
Value of: 3
Expected: 2
[==========] Running 37 tests from 13 test cases.
[==========] Running 48 tests from 21 test cases.
[----------] Global test environment set-up.
FooEnvironment::SetUp() called.
BarEnvironment::SetUp() called.
[----------] 1 test from ADeathTest
[ RUN ] ADeathTest.ShouldRunFirst
[ OK ] ADeathTest.ShouldRunFirst
[----------] 1 test from ATypedDeathTest/0, where TypeParam = int
[ RUN ] ATypedDeathTest/0.ShouldRunFirst
[ OK ] ATypedDeathTest/0.ShouldRunFirst
[----------] 1 test from ATypedDeathTest/1, where TypeParam = double
[ RUN ] ATypedDeathTest/1.ShouldRunFirst
[ OK ] ATypedDeathTest/1.ShouldRunFirst
[----------] 1 test from My/ATypeParamDeathTest/0, where TypeParam = int
[ RUN ] My/ATypeParamDeathTest/0.ShouldRunFirst
[ OK ] My/ATypeParamDeathTest/0.ShouldRunFirst
[----------] 1 test from My/ATypeParamDeathTest/1, where TypeParam = double
[ RUN ] My/ATypeParamDeathTest/1.ShouldRunFirst
[ OK ] My/ATypeParamDeathTest/1.ShouldRunFirst
[----------] 3 tests from FatalFailureTest
[ RUN ] FatalFailureTest.FatalFailureInSubroutine
(expecting a failure that x should be 1)
@ -341,6 +356,36 @@ gtest.cc:#: Failure
Expected: 1 fatal failure
Actual: 0 failures
[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns
[----------] 2 tests from TypedTest/0, where TypeParam = int
[ RUN ] TypedTest/0.Success
[ OK ] TypedTest/0.Success
[ RUN ] TypedTest/0.Failure
gtest_output_test_.cc:#: Failure
Value of: TypeParam()
Actual: 0
Expected: 1
Expected failure
[ FAILED ] TypedTest/0.Failure
[----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char
[ RUN ] Unsigned/TypedTestP/0.Success
[ OK ] Unsigned/TypedTestP/0.Success
[ RUN ] Unsigned/TypedTestP/0.Failure
gtest_output_test_.cc:#: Failure
Value of: TypeParam()
Actual: \0
Expected: 1
Expected failure
[ FAILED ] Unsigned/TypedTestP/0.Failure
[----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int
[ RUN ] Unsigned/TypedTestP/1.Success
[ OK ] Unsigned/TypedTestP/1.Success
[ RUN ] Unsigned/TypedTestP/1.Failure
gtest_output_test_.cc:#: Failure
Value of: TypeParam()
Actual: 0
Expected: 1
Expected failure
[ FAILED ] Unsigned/TypedTestP/1.Failure
[----------] Global test environment tear-down
BarEnvironment::TearDown() called.
gtest_output_test_.cc:#: Failure
@ -350,9 +395,9 @@ FooEnvironment::TearDown() called.
gtest_output_test_.cc:#: Failure
Failed
Expected fatal failure.
[==========] 37 tests from 13 test cases ran.
[ PASSED ] 11 tests.
[ FAILED ] 26 tests, listed below:
[==========] 48 tests from 21 test cases ran.
[ PASSED ] 19 tests.
[ FAILED ] 29 tests, listed below:
[ FAILED ] FatalFailureTest.FatalFailureInSubroutine
[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine
[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine
@ -379,8 +424,11 @@ Expected fatal failure.
[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures
[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure
[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns
[ FAILED ] TypedTest/0.Failure, where TypeParam = int
[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char
[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int
26 FAILED TESTS
29 FAILED TESTS
The non-test part of the code is expected to have 2 failures.
gtest_output_test_.cc:#: Failure

View File

@ -5,7 +5,7 @@ gtest_output_test_.cc:#: error: Value of: false
Expected: true
gtest_output_test_.cc:#: error: Value of: 3
Expected: 2
[==========] Running 40 tests from 16 test cases.
[==========] Running 46 tests from 19 test cases.
[----------] Global test environment set-up.
FooEnvironment::SetUp() called.
BarEnvironment::SetUp() called.
@ -317,6 +317,33 @@ Expected non-fatal failure.
gtest.cc:#: error: Expected: 1 fatal failure
Actual: 0 failures
[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns
[----------] 2 tests from TypedTest/0, where TypeParam = int
[ RUN ] TypedTest/0.Success
[ OK ] TypedTest/0.Success
[ RUN ] TypedTest/0.Failure
gtest_output_test_.cc:#: error: Value of: TypeParam()
Actual: 0
Expected: 1
Expected failure
[ FAILED ] TypedTest/0.Failure
[----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char
[ RUN ] Unsigned/TypedTestP/0.Success
[ OK ] Unsigned/TypedTestP/0.Success
[ RUN ] Unsigned/TypedTestP/0.Failure
gtest_output_test_.cc:#: error: Value of: TypeParam()
Actual: \0
Expected: 1
Expected failure
[ FAILED ] Unsigned/TypedTestP/0.Failure
[----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int
[ RUN ] Unsigned/TypedTestP/1.Success
[ OK ] Unsigned/TypedTestP/1.Success
[ RUN ] Unsigned/TypedTestP/1.Failure
gtest_output_test_.cc:#: error: Value of: TypeParam()
Actual: 0
Expected: 1
Expected failure
[ FAILED ] Unsigned/TypedTestP/1.Failure
[----------] Global test environment tear-down
BarEnvironment::TearDown() called.
gtest_output_test_.cc:#: error: Failed
@ -324,9 +351,9 @@ Expected non-fatal failure.
FooEnvironment::TearDown() called.
gtest_output_test_.cc:#: error: Failed
Expected fatal failure.
[==========] 40 tests from 16 test cases ran.
[ PASSED ] 11 tests.
[ FAILED ] 29 tests, listed below:
[==========] 46 tests from 19 test cases ran.
[ PASSED ] 14 tests.
[ FAILED ] 32 tests, listed below:
[ FAILED ] FatalFailureTest.FatalFailureInSubroutine
[ FAILED ] FatalFailureTest.FatalFailureInNestedSubroutine
[ FAILED ] FatalFailureTest.NonfatalFailureInSubroutine
@ -356,8 +383,11 @@ Expected fatal failure.
[ FAILED ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures
[ FAILED ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure
[ FAILED ] ExpectFatalFailureTest.FailsWhenStatementReturns
[ FAILED ] TypedTest/0.Failure, where TypeParam = int
[ FAILED ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char
[ FAILED ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int
29 FAILED TESTS
32 FAILED TESTS
The non-test part of the code is expected to have 2 failures.
gtest_output_test_.cc:#: error: Value of: false

View File

@ -529,6 +529,18 @@ TEST(StringTest, EndsWithCaseInsensitive) {
EXPECT_FALSE(String("").EndsWithCaseInsensitive("foo"));
}
// Tests String::CaseInsensitiveWideCStringEquals
TEST(StringTest, CaseInsensitiveWideCStringEquals) {
EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(NULL, NULL));
EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(NULL, L""));
EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"", NULL));
EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(NULL, L"foobar"));
EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"foobar", NULL));
EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"foobar"));
EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"FOOBAR"));
EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"FOOBAR", L"foobar"));
}
// Tests that NULL can be assigned to a String.
TEST(StringTest, CanBeAssignedNULL) {
const String src(NULL);
@ -2134,6 +2146,68 @@ TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_2) {
FAIL() << "Unexpected failure: Disabled test should not be run.";
}
// Tests that disabled typed tests aren't run.
#ifdef GTEST_HAS_TYPED_TEST
template <typename T>
class TypedTest : public Test {
};
typedef testing::Types<int, double> NumericTypes;
TYPED_TEST_CASE(TypedTest, NumericTypes);
TYPED_TEST(TypedTest, DISABLED_ShouldNotRun) {
FAIL() << "Unexpected failure: Disabled typed test should not run.";
}
template <typename T>
class DISABLED_TypedTest : public Test {
};
TYPED_TEST_CASE(DISABLED_TypedTest, NumericTypes);
TYPED_TEST(DISABLED_TypedTest, ShouldNotRun) {
FAIL() << "Unexpected failure: Disabled typed test should not run.";
}
#endif // GTEST_HAS_TYPED_TEST
// Tests that disabled type-parameterized tests aren't run.
#ifdef GTEST_HAS_TYPED_TEST_P
template <typename T>
class TypedTestP : public Test {
};
TYPED_TEST_CASE_P(TypedTestP);
TYPED_TEST_P(TypedTestP, DISABLED_ShouldNotRun) {
FAIL() << "Unexpected failure: "
<< "Disabled type-parameterized test should not run.";
}
REGISTER_TYPED_TEST_CASE_P(TypedTestP, DISABLED_ShouldNotRun);
INSTANTIATE_TYPED_TEST_CASE_P(My, TypedTestP, NumericTypes);
template <typename T>
class DISABLED_TypedTestP : public Test {
};
TYPED_TEST_CASE_P(DISABLED_TypedTestP);
TYPED_TEST_P(DISABLED_TypedTestP, ShouldNotRun) {
FAIL() << "Unexpected failure: "
<< "Disabled type-parameterized test should not run.";
}
REGISTER_TYPED_TEST_CASE_P(DISABLED_TypedTestP, ShouldNotRun);
INSTANTIATE_TYPED_TEST_CASE_P(My, DISABLED_TypedTestP, NumericTypes);
#endif // GTEST_HAS_TYPED_TEST_P
// Tests that assertion macros evaluate their arguments exactly once.
@ -3491,7 +3565,7 @@ class TestInfoTest : public Test {
protected:
static TestInfo * GetTestInfo(const char* test_name) {
return UnitTest::GetInstance()->impl()->
GetTestCase("TestInfoTest", NULL, NULL)->
GetTestCase("TestInfoTest", "", NULL, NULL)->
GetTestInfo(test_name);
}

View File

@ -22,6 +22,9 @@
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
22A865FD0E70A35700F7AE6E /* gtest-typed-test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 22A865FC0E70A35700F7AE6E /* gtest-typed-test.cc */; };
22A866080E70A39900F7AE6E /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D07F2C80486CC7A007CD1D0 /* gtest.framework */; };
22A866190E70A41000F7AE6E /* sample6_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 22A866180E70A41000F7AE6E /* sample6_unittest.cc */; };
404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DB0E2F799B00CF7658 /* gtest-death-test.h */; settings = {ATTRIBUTES = (Public, ); }; };
404884390E2F799B00CF7658 /* gtest-message.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DC0E2F799B00CF7658 /* gtest-message.h */; settings = {ATTRIBUTES = (Public, ); }; };
4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DD0E2F799B00CF7658 /* gtest-spi.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -59,6 +62,13 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
22A866030E70A39900F7AE6E /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
remoteInfo = gtest;
};
404885A70E2F824900CF7658 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
@ -98,7 +108,7 @@
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 40C44ADC0E3798F4008FCC51 /* Version.h */;
remoteGlobalIDString = 40C44ADC0E3798F4008FCC51;
remoteInfo = Version.h;
};
/* End PBXContainerItemProxy section */
@ -122,6 +132,9 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
22A865FC0E70A35700F7AE6E /* gtest-typed-test.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-typed-test.cc"; sourceTree = "<group>"; };
22A8660C0E70A39900F7AE6E /* sample6 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample6; sourceTree = BUILT_PRODUCTS_DIR; };
22A866180E70A41000F7AE6E /* sample6_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = sample6_unittest.cc; sourceTree = "<group>"; };
403EE37C0E377822004BD1E2 /* versiongenerate.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = versiongenerate.py; sourceTree = "<group>"; };
404883DB0E2F799B00CF7658 /* gtest-death-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-death-test.h"; sourceTree = "<group>"; };
404883DC0E2F799B00CF7658 /* gtest-message.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-message.h"; sourceTree = "<group>"; };
@ -156,8 +169,8 @@
404884A90E2F7CD900CF7658 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CHANGES; path = ../CHANGES; sourceTree = SOURCE_ROOT; };
404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CONTRIBUTORS; path = ../CONTRIBUTORS; sourceTree = SOURCE_ROOT; };
404884AB0E2F7CD900CF7658 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = COPYING; path = ../COPYING; sourceTree = SOURCE_ROOT; };
404885930E2F814C00CF7658 /* sample1 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample1; sourceTree = BUILT_PRODUCTS_DIR; };
404885BB0E2F82BA00CF7658 /* sample3 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample3; sourceTree = BUILT_PRODUCTS_DIR; };
404885930E2F814C00CF7658 /* sample1 */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = sample1; sourceTree = BUILT_PRODUCTS_DIR; };
404885BB0E2F82BA00CF7658 /* sample2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample2; sourceTree = BUILT_PRODUCTS_DIR; };
404885DF0E2F832A00CF7658 /* sample3 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample3; sourceTree = BUILT_PRODUCTS_DIR; };
404885EC0E2F833000CF7658 /* sample4 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample4; sourceTree = BUILT_PRODUCTS_DIR; };
404885F90E2F833400CF7658 /* sample5 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample5; sourceTree = BUILT_PRODUCTS_DIR; };
@ -165,11 +178,19 @@
40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FrameworkTarget.xcconfig; sourceTree = "<group>"; };
40D4CDF30E30E07400294801 /* General.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = "<group>"; };
40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReleaseProject.xcconfig; sourceTree = "<group>"; };
40D4CF510E30F5E200294801 /* Info.plist */ = {isa = PBXFileReference; explicitFileType = text.plist.xml; fileEncoding = 4; path = Info.plist; sourceTree = "<group>"; };
40D4CF510E30F5E200294801 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
8D07F2C80486CC7A007CD1D0 /* gtest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = gtest.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
22A866070E70A39900F7AE6E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
22A866080E70A39900F7AE6E /* gtest.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
404885910E2F814C00CF7658 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -225,10 +246,11 @@
children = (
8D07F2C80486CC7A007CD1D0 /* gtest.framework */,
404885930E2F814C00CF7658 /* sample1 */,
404885BB0E2F82BA00CF7658 /* sample3 */,
404885BB0E2F82BA00CF7658 /* sample2 */,
404885DF0E2F832A00CF7658 /* sample3 */,
404885EC0E2F833000CF7658 /* sample4 */,
404885F90E2F833400CF7658 /* sample5 */,
22A8660C0E70A39900F7AE6E /* sample6 */,
);
name = Products;
sourceTree = "<group>";
@ -317,6 +339,7 @@
404884010E2F799B00CF7658 /* sample4.h */,
404884020E2F799B00CF7658 /* sample4_unittest.cc */,
404884030E2F799B00CF7658 /* sample5_unittest.cc */,
22A866180E70A41000F7AE6E /* sample6_unittest.cc */,
);
name = samples;
path = ../samples;
@ -331,6 +354,7 @@
4048840B0E2F799B00CF7658 /* gtest-port.cc */,
4048840C0E2F799B00CF7658 /* gtest.cc */,
4048840D0E2F799B00CF7658 /* gtest_main.cc */,
22A865FC0E70A35700F7AE6E /* gtest-typed-test.cc */,
);
name = src;
path = ../src;
@ -374,6 +398,23 @@
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
22A866010E70A39900F7AE6E /* sample6 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 22A866090E70A39900F7AE6E /* Build configuration list for PBXNativeTarget "sample6" */;
buildPhases = (
22A866040E70A39900F7AE6E /* Sources */,
22A866070E70A39900F7AE6E /* Frameworks */,
);
buildRules = (
);
dependencies = (
22A866020E70A39900F7AE6E /* PBXTargetDependency */,
);
name = sample6;
productName = sample6;
productReference = 22A8660C0E70A39900F7AE6E /* sample6 */;
productType = "com.apple.product-type.tool";
};
404885920E2F814C00CF7658 /* sample1 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4048859E0E2F818900CF7658 /* Build configuration list for PBXNativeTarget "sample1" */;
@ -404,8 +445,8 @@
404885B10E2F82BA00CF7658 /* PBXTargetDependency */,
);
name = sample2;
productName = sample1;
productReference = 404885BB0E2F82BA00CF7658 /* sample3 */;
productName = sample2;
productReference = 404885BB0E2F82BA00CF7658 /* sample2 */;
productType = "com.apple.product-type.tool";
};
404885D40E2F832A00CF7658 /* sample3 */ = {
@ -421,7 +462,7 @@
404885D50E2F832A00CF7658 /* PBXTargetDependency */,
);
name = sample3;
productName = sample1;
productName = sample3;
productReference = 404885DF0E2F832A00CF7658 /* sample3 */;
productType = "com.apple.product-type.tool";
};
@ -438,7 +479,7 @@
404885E20E2F833000CF7658 /* PBXTargetDependency */,
);
name = sample4;
productName = sample1;
productName = sample4;
productReference = 404885EC0E2F833000CF7658 /* sample4 */;
productType = "com.apple.product-type.tool";
};
@ -455,7 +496,7 @@
404885EF0E2F833400CF7658 /* PBXTargetDependency */,
);
name = sample5;
productName = sample1;
productName = sample5;
productReference = 404885F90E2F833400CF7658 /* sample5 */;
productType = "com.apple.product-type.tool";
};
@ -507,6 +548,7 @@
404885D40E2F832A00CF7658 /* sample3 */,
404885E10E2F833000CF7658 /* sample4 */,
404885EE0E2F833400CF7658 /* sample5 */,
22A866010E70A39900F7AE6E /* sample6 */,
40C44ADC0E3798F4008FCC51 /* Version Info */,
);
};
@ -557,6 +599,14 @@
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
22A866040E70A39900F7AE6E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
22A866190E70A41000F7AE6E /* sample6_unittest.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
404885900E2F814C00CF7658 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -610,12 +660,18 @@
404884620E2F799B00CF7658 /* gtest-port.cc in Sources */,
404884630E2F799B00CF7658 /* gtest.cc in Sources */,
404884640E2F799B00CF7658 /* gtest_main.cc in Sources */,
22A865FD0E70A35700F7AE6E /* gtest-typed-test.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
22A866020E70A39900F7AE6E /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8D07F2BC0486CC7A007CD1D0 /* gtest */;
targetProxy = 22A866030E70A39900F7AE6E /* PBXContainerItemProxy */;
};
404885A80E2F824900CF7658 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8D07F2BC0486CC7A007CD1D0 /* gtest */;
@ -649,6 +705,22 @@
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
22A8660A0E70A39900F7AE6E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = sample6;
};
name = Debug;
};
22A8660B0E70A39900F7AE6E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = sample6;
};
name = Release;
};
404885950E2F814C00CF7658 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -669,7 +741,7 @@
isa = XCBuildConfiguration;
buildSettings = {
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = sample3;
PRODUCT_NAME = sample2;
};
name = Debug;
};
@ -677,7 +749,7 @@
isa = XCBuildConfiguration;
buildSettings = {
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = sample3;
PRODUCT_NAME = sample2;
};
name = Release;
};
@ -798,6 +870,15 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
22A866090E70A39900F7AE6E /* Build configuration list for PBXNativeTarget "sample6" */ = {
isa = XCConfigurationList;
buildConfigurations = (
22A8660A0E70A39900F7AE6E /* Debug */,
22A8660B0E70A39900F7AE6E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4048859E0E2F818900CF7658 /* Build configuration list for PBXNativeTarget "sample1" */ = {
isa = XCConfigurationList;
buildConfigurations = (