summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/gtest/gtest-typed-test.h10
-rw-r--r--include/gtest/internal/gtest-port.h38
-rw-r--r--include/gtest/internal/gtest-tuple.h3
-rw-r--r--include/gtest/internal/gtest-tuple.h.pump3
-rw-r--r--src/gtest-filepath.cc3
-rw-r--r--src/gtest-port.cc17
-rw-r--r--src/gtest-typed-test.cc12
-rw-r--r--test/gtest-filepath_test.cc51
-rw-r--r--test/gtest_unittest.cc39
9 files changed, 115 insertions, 61 deletions
diff --git a/include/gtest/gtest-typed-test.h b/include/gtest/gtest-typed-test.h
index 519edfe..1ec8eb8 100644
--- a/include/gtest/gtest-typed-test.h
+++ b/include/gtest/gtest-typed-test.h
@@ -159,8 +159,11 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
// given test case.
#define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
#define TYPED_TEST_CASE(CaseName, Types) \
- typedef ::testing::internal::TypeList<Types>::type \
+ typedef ::testing::internal::TypeList< Types >::type \
GTEST_TYPE_PARAMS_(CaseName)
#define TYPED_TEST(CaseName, TestName) \
@@ -241,11 +244,14 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
__FILE__, __LINE__, #__VA_ARGS__)
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
bool gtest_##Prefix##_##CaseName = \
::testing::internal::TypeParameterizedTestCase<CaseName, \
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
- ::testing::internal::TypeList<Types>::type>::Register(\
+ ::testing::internal::TypeList< Types >::type>::Register(\
#Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
#endif // GTEST_HAS_TYPED_TEST_P
diff --git a/include/gtest/internal/gtest-port.h b/include/gtest/internal/gtest-port.h
index d5e2e6b..c049a00 100644
--- a/include/gtest/internal/gtest-port.h
+++ b/include/gtest/internal/gtest-port.h
@@ -42,6 +42,8 @@
//
// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2)
// is/isn't available.
+// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions
+// are enabled.
// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string
// is/isn't available (some systems define
// ::string, which is different to std::string).
@@ -242,9 +244,9 @@
#endif // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC ||
// GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS
-// Defines GTEST_HAS_EXCEPTIONS to 1 if exceptions are enabled, or 0
-// otherwise.
-
+#ifndef GTEST_HAS_EXCEPTIONS
+// The user didn't tell us whether exceptions are enabled, so we need
+// to figure it out.
#if defined(_MSC_VER) || defined(__BORLANDC__)
// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS
// macro to enable exceptions, so we'll do the same.
@@ -253,16 +255,20 @@
#define _HAS_EXCEPTIONS 1
#endif // _HAS_EXCEPTIONS
#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
-#else // The compiler is not MSVC or C++Builder.
-// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. For
-// other compilers, we assume exceptions are disabled to be
-// conservative.
-#if defined(__GNUC__) && __EXCEPTIONS
+#elif defined(__GNUC__) && __EXCEPTIONS
+// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled.
+#define GTEST_HAS_EXCEPTIONS 1
+#elif defined(__SUNPRO_CC)
+// Sun Pro CC supports exceptions. However, there is no compile-time way of
+// detecting whether they are enabled or not. Therefore, we assume that
+// they are enabled unless the user tells us otherwise.
#define GTEST_HAS_EXCEPTIONS 1
#else
+// For other compilers, we assume exceptions are disabled to be
+// conservative.
#define GTEST_HAS_EXCEPTIONS 0
-#endif // defined(__GNUC__) && __EXCEPTIONS
#endif // defined(_MSC_VER) || defined(__BORLANDC__)
+#endif // GTEST_HAS_EXCEPTIONS
#if !defined(GTEST_HAS_STD_STRING)
// Even though we don't use this macro any longer, we keep it in case
@@ -340,7 +346,7 @@
// Determines whether <pthread.h> is available.
#ifndef GTEST_HAS_PTHREAD
// The user didn't tell us, so we need to figure it out.
-#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC)
+#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_SOLARIS)
#endif // GTEST_HAS_PTHREAD
// Determines whether Google Test can use tr1/tuple. You can define
@@ -446,7 +452,7 @@
// Google Test does not support death tests for VC 7.1 and earlier as
// abort() in a VC 7.1 application compiled as GUI in debug config
// pops up a dialog window that cannot be suppressed programmatically.
-#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || \
+#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
(GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || GTEST_OS_WINDOWS_MINGW)
#define GTEST_HAS_DEATH_TEST 1
#include <vector> // NOLINT
@@ -462,12 +468,12 @@
// 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)
+// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0, and
+// Sun Pro CC support.
+#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC)
#define GTEST_HAS_TYPED_TEST 1
#define GTEST_HAS_TYPED_TEST_P 1
-#endif // defined(__GNUC__) || (_MSC_VER >= 1400)
+#endif
// Determines whether to support Combine(). This only makes sense when
// value-parameterized tests are enabled.
@@ -923,7 +929,7 @@ inline const char* GetEnv(const char* name) {
#if GTEST_OS_WINDOWS_MOBILE
// We are on Windows CE, which has no environment variables.
return NULL;
-#elif defined(__BORLANDC__)
+#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
// Environment variables which we programmatically clear will be set to the
// empty string rather than unset (NULL). Handle that case.
const char* const env = getenv(name);
diff --git a/include/gtest/internal/gtest-tuple.h b/include/gtest/internal/gtest-tuple.h
index c201f5c..16178fc 100644
--- a/include/gtest/internal/gtest-tuple.h
+++ b/include/gtest/internal/gtest-tuple.h
@@ -42,7 +42,8 @@
// tuple template as a friend (it complains that tuple is redefined). This
// hack bypasses the bug by declaring the members that should otherwise be
// private as public.
-#if defined(__SYMBIAN32__)
+// Sun Studio versions < 12 also have the above bug.
+#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
#else
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
diff --git a/include/gtest/internal/gtest-tuple.h.pump b/include/gtest/internal/gtest-tuple.h.pump
index 9e42423..85ebc80 100644
--- a/include/gtest/internal/gtest-tuple.h.pump
+++ b/include/gtest/internal/gtest-tuple.h.pump
@@ -43,7 +43,8 @@ $$ This meta comment fixes auto-indentation in Emacs. }}
// tuple template as a friend (it complains that tuple is redefined). This
// hack bypasses the bug by declaring the members that should otherwise be
// private as public.
-#if defined(__SYMBIAN32__)
+// Sun Studio versions < 12 also have the above bug.
+#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
#else
#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
diff --git a/src/gtest-filepath.cc b/src/gtest-filepath.cc
index 27a3342..c1ef918 100644
--- a/src/gtest-filepath.cc
+++ b/src/gtest-filepath.cc
@@ -342,9 +342,10 @@ FilePath FilePath::RemoveTrailingPathSeparator() const {
: *this;
}
-// Normalize removes any redundant separators that might be in the pathname.
+// Removes any redundant separators that might be in the pathname.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..".
+// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
void FilePath::Normalize() {
if (pathname_.c_str() == NULL) {
pathname_ = "";
diff --git a/src/gtest-port.cc b/src/gtest-port.cc
index 957595a..7d89e26 100644
--- a/src/gtest-port.cc
+++ b/src/gtest-port.cc
@@ -111,8 +111,14 @@ size_t GetThreadCount() {
// Implements RE. Currently only needed for death tests.
RE::~RE() {
- regfree(&partial_regex_);
- regfree(&full_regex_);
+ if (is_valid_) {
+ // regfree'ing an invalid regex might crash because the content
+ // of the regex is undefined. Since the regex's are essentially
+ // the same, one cannot be valid (or invalid) without the other
+ // being so too.
+ regfree(&partial_regex_);
+ regfree(&full_regex_);
+ }
free(const_cast<char*>(pattern_));
}
@@ -152,9 +158,10 @@ void RE::Init(const char* regex) {
// Some implementation of POSIX regex (e.g. on at least some
// versions of Cygwin) doesn't accept the empty string as a valid
// regex. We change it to an equivalent form "()" to be safe.
- const char* const partial_regex = (*regex == '\0') ? "()" : regex;
- is_valid_ = (regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0)
- && is_valid_;
+ if (is_valid_) {
+ const char* const partial_regex = (*regex == '\0') ? "()" : regex;
+ is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
+ }
EXPECT_TRUE(is_valid_)
<< "Regular expression \"" << regex
<< "\" is not a valid POSIX Extended regular expression.";
diff --git a/src/gtest-typed-test.cc b/src/gtest-typed-test.cc
index 4a0f657..3cc4b5d 100644
--- a/src/gtest-typed-test.cc
+++ b/src/gtest-typed-test.cc
@@ -37,6 +37,14 @@ namespace internal {
#if GTEST_HAS_TYPED_TEST_P
+// Skips to the first non-space char in str. Returns an empty string if str
+// contains only whitespace characters.
+static const char* SkipSpaces(const char* str) {
+ while (isspace(*str))
+ str++;
+ return str;
+}
+
// Verifies that registered_tests match the test names in
// defined_test_names_; returns registered_tests if successful, or
// aborts the program otherwise.
@@ -45,6 +53,10 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames(
typedef ::std::set<const char*>::const_iterator DefinedTestIter;
registered_ = true;
+ // Skip initial whitespace in registered_tests since some
+ // preprocessors prefix stringizied literals with whitespace.
+ registered_tests = SkipSpaces(registered_tests);
+
Message errors;
::std::set<String> tests;
for (const char* names = registered_tests; names != NULL;
diff --git a/test/gtest-filepath_test.cc b/test/gtest-filepath_test.cc
index 5706c8e..c5f58f4 100644
--- a/test/gtest-filepath_test.cc
+++ b/test/gtest-filepath_test.cc
@@ -153,31 +153,31 @@ TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) {
#if GTEST_HAS_ALT_PATH_SEP_
-// Test RemoveDirectory* functions with "/".
+// Tests that RemoveDirectoryName() works with the alternate separator
+// on Windows.
-// RemoveDirectoryName "/afile" -> "afile"
+// RemoveDirectoryName("/afile") -> "afile"
TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) {
EXPECT_STREQ("afile",
- FilePath("/afile").RemoveDirectoryName().c_str());
+ FilePath("/afile").RemoveDirectoryName().c_str());
}
-// RemoveDirectoryName "adir/" -> ""
+// RemoveDirectoryName("adir/") -> ""
TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) {
EXPECT_STREQ("",
- FilePath("adir/").RemoveDirectoryName().c_str());
+ FilePath("adir/").RemoveDirectoryName().c_str());
}
-// RemoveDirectoryName "adir/afile" -> "afile"
+// RemoveDirectoryName("adir/afile") -> "afile"
TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) {
EXPECT_STREQ("afile",
- FilePath("adir/afile").RemoveDirectoryName().c_str());
+ FilePath("adir/afile").RemoveDirectoryName().c_str());
}
-// RemoveDirectoryName "adir/subdir/afile" -> "afile"
+// RemoveDirectoryName("adir/subdir/afile") -> "afile"
TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) {
EXPECT_STREQ("afile",
- FilePath("adir/subdir/afile")
- .RemoveDirectoryName().c_str());
+ FilePath("adir/subdir/afile").RemoveDirectoryName().c_str());
}
#endif
@@ -222,32 +222,31 @@ TEST(RemoveFileNameTest, GivesRootDir) {
#if GTEST_HAS_ALT_PATH_SEP_
-// Test RemoveFile* functions with "/".
+// Tests that RemoveFileName() works with the alternate separator on
+// Windows.
-// RemoveFileName "adir/" -> "adir/"
+// RemoveFileName("adir/") -> "adir/"
TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) {
EXPECT_STREQ("adir" GTEST_PATH_SEP_,
- FilePath("adir/").RemoveFileName().c_str());
+ FilePath("adir/").RemoveFileName().c_str());
}
-// RemoveFileName "adir/afile" -> "adir/"
+// RemoveFileName("adir/afile") -> "adir/"
TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) {
EXPECT_STREQ("adir" GTEST_PATH_SEP_,
- FilePath("adir/afile")
- .RemoveFileName().c_str());
+ FilePath("adir/afile").RemoveFileName().c_str());
}
-// RemoveFileName "adir/subdir/afile" -> "adir/subdir/"
+// RemoveFileName("adir/subdir/afile") -> "adir/subdir/"
TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) {
EXPECT_STREQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_,
- FilePath("adir/subdir/afile")
- .RemoveFileName().c_str());
+ FilePath("adir/subdir/afile").RemoveFileName().c_str());
}
-// RemoveFileName "/afile" -> "\"
+// RemoveFileName("/afile") -> "\"
TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) {
EXPECT_STREQ(GTEST_PATH_SEP_,
- FilePath("/afile").RemoveFileName().c_str());
+ FilePath("/afile").RemoveFileName().c_str());
}
#endif
@@ -357,9 +356,8 @@ TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) {
"foo",
FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().c_str());
#if GTEST_HAS_ALT_PATH_SEP_
- EXPECT_STREQ(
- "foo",
- FilePath("foo/").RemoveTrailingPathSeparator().c_str());
+ EXPECT_STREQ("foo",
+ FilePath("foo/").RemoveTrailingPathSeparator().c_str());
#endif
}
@@ -465,7 +463,9 @@ TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) {
#if GTEST_HAS_ALT_PATH_SEP_
-// "foo\" =="foo/\" == "foo\\/"
+// Tests that separators at the end of the string are normalized
+// regardless of their combination (e.g. "foo\" =="foo/\" ==
+// "foo\\/").
TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) {
EXPECT_STREQ("foo" GTEST_PATH_SEP_,
FilePath("foo/").c_str());
@@ -678,6 +678,7 @@ TEST(FilePathTest, IsRootDirectory) {
EXPECT_FALSE(FilePath("c|/").IsRootDirectory());
#else
EXPECT_TRUE(FilePath("/").IsRootDirectory());
+ EXPECT_TRUE(FilePath("//").IsRootDirectory());
EXPECT_FALSE(FilePath("").IsRootDirectory());
EXPECT_FALSE(FilePath("\\").IsRootDirectory());
EXPECT_FALSE(FilePath("/x").IsRootDirectory());
diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc
index a593494..55313e3 100644
--- a/test/gtest_unittest.cc
+++ b/test/gtest_unittest.cc
@@ -74,9 +74,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
#include <pthread.h>
#endif // GTEST_HAS_PTHREAD
-#ifdef __BORLANDC__
#include <map>
-#endif
namespace testing {
namespace internal {
@@ -1388,12 +1386,16 @@ TEST(StringTest, CanBeAssignedSelf) {
EXPECT_STREQ("hello", dest.c_str());
}
+// Sun Studio < 12 incorrectly rejects this code due to an overloading
+// ambiguity.
+#if !(defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
// Tests streaming a String.
TEST(StringTest, Streams) {
EXPECT_EQ(StreamableToString(String()), "(null)");
EXPECT_EQ(StreamableToString(String("")), "");
EXPECT_EQ(StreamableToString(String("a\0b", 3)), "a\\0b");
}
+#endif
// Tests that String::Format() works.
TEST(StringTest, FormatWorks) {
@@ -2050,7 +2052,7 @@ static void SetEnv(const char* name, const char* value) {
#if GTEST_OS_WINDOWS_MOBILE
// Environment variables are not supported on Windows CE.
return;
-#elif defined(__BORLANDC__)
+#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
// C++Builder's putenv only stores a pointer to its parameter; we have to
// ensure that the string remains valid as long as it might be needed.
// We use an std::map to do so.
@@ -2063,7 +2065,11 @@ static void SetEnv(const char* name, const char* value) {
prev_env = added_env[name];
}
added_env[name] = new String((Message() << name << "=" << value).GetString());
- putenv(added_env[name]->c_str());
+
+ // The standard signature of putenv accepts a 'char*' argument. Other
+ // implementations, like C++Builder's, accept a 'const char*'.
+ // We cast away the 'const' since that would work for both variants.
+ putenv(const_cast<char*>(added_env[name]->c_str()));
delete prev_env;
#elif GTEST_OS_WINDOWS // If we are on Windows proper.
_putenv((Message() << name << "=" << value).GetString().c_str());
@@ -3013,7 +3019,10 @@ TEST_F(FloatTest, AlmostZeros) {
// In C++Builder, names within local classes (such as used by
// EXPECT_FATAL_FAILURE) cannot be resolved against static members of the
// scoping class. Use a static local alias as a workaround.
- static const FloatTest::TestValues& v(this->values_);
+ // We use the assignment syntax since some compilers, like Sun Studio,
+ // don't allow initializing references using construction syntax
+ // (parentheses).
+ static const FloatTest::TestValues& v = this->values_;
EXPECT_FLOAT_EQ(0.0, v.close_to_positive_zero);
EXPECT_FLOAT_EQ(-0.0, v.close_to_negative_zero);
@@ -3065,7 +3074,10 @@ TEST_F(FloatTest, NaN) {
// In C++Builder, names within local classes (such as used by
// EXPECT_FATAL_FAILURE) cannot be resolved against static members of the
// scoping class. Use a static local alias as a workaround.
- static const FloatTest::TestValues& v(this->values_);
+ // We use the assignment syntax since some compilers, like Sun Studio,
+ // don't allow initializing references using construction syntax
+ // (parentheses).
+ static const FloatTest::TestValues& v = this->values_;
EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan1),
"v.nan1");
@@ -3180,7 +3192,10 @@ TEST_F(DoubleTest, AlmostZeros) {
// In C++Builder, names within local classes (such as used by
// EXPECT_FATAL_FAILURE) cannot be resolved against static members of the
// scoping class. Use a static local alias as a workaround.
- static const DoubleTest::TestValues& v(this->values_);
+ // We use the assignment syntax since some compilers, like Sun Studio,
+ // don't allow initializing references using construction syntax
+ // (parentheses).
+ static const DoubleTest::TestValues& v = this->values_;
EXPECT_DOUBLE_EQ(0.0, v.close_to_positive_zero);
EXPECT_DOUBLE_EQ(-0.0, v.close_to_negative_zero);
@@ -3230,7 +3245,10 @@ TEST_F(DoubleTest, NaN) {
// In C++Builder, names within local classes (such as used by
// EXPECT_FATAL_FAILURE) cannot be resolved against static members of the
// scoping class. Use a static local alias as a workaround.
- static const DoubleTest::TestValues& v(this->values_);
+ // We use the assignment syntax since some compilers, like Sun Studio,
+ // don't allow initializing references using construction syntax
+ // (parentheses).
+ static const DoubleTest::TestValues& v = this->values_;
// Nokia's STLport crashes if we try to output infinity or NaN.
EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan1),
@@ -4015,7 +4033,8 @@ TEST(AssertionTest, ExpectWorksWithUncopyableObject) {
// The version of gcc used in XCode 2.2 has a bug and doesn't allow
// anonymous enums in assertions. Therefore the following test is not
// done on Mac.
-#if !GTEST_OS_MAC
+// Sun Studio also rejects this code.
+#if !GTEST_OS_MAC && !defined(__SUNPRO_CC)
// Tests using assertions with anonymous enums.
enum {
@@ -4060,7 +4079,7 @@ TEST(AssertionTest, AnonymousEnum) {
"Value of: CASE_B");
}
-#endif // !GTEST_OS_MAC
+#endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC)
#if GTEST_OS_WINDOWS