Commit 5c7c365d authored by Tanzinul Islam's avatar Tanzinul Islam
Browse files

Merge branch 'master' into fix_death_test_child_mingw_wer_issue1116

parents 6d089311 7888184f
...@@ -1081,22 +1081,36 @@ std::string ReadEntireFile(FILE* file) { ...@@ -1081,22 +1081,36 @@ std::string ReadEntireFile(FILE* file) {
} }
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
static const std::vector<std::string>* g_injected_test_argvs = NULL; // Owned.
static const ::std::vector<testing::internal::string>* g_injected_test_argvs = std::vector<std::string> GetInjectableArgvs() {
NULL; // Owned.
void SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {
if (g_injected_test_argvs != argvs)
delete g_injected_test_argvs;
g_injected_test_argvs = argvs;
}
const ::std::vector<testing::internal::string>& GetInjectableArgvs() {
if (g_injected_test_argvs != NULL) { if (g_injected_test_argvs != NULL) {
return *g_injected_test_argvs; return *g_injected_test_argvs;
} }
return GetArgvs(); return GetArgvs();
} }
void SetInjectableArgvs(const std::vector<std::string>* new_argvs) {
if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs;
g_injected_test_argvs = new_argvs;
}
void SetInjectableArgvs(const std::vector<std::string>& new_argvs) {
SetInjectableArgvs(
new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
}
#if GTEST_HAS_GLOBAL_STRING
void SetInjectableArgvs(const std::vector< ::string>& new_argvs) {
SetInjectableArgvs(
new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
}
#endif // GTEST_HAS_GLOBAL_STRING
void ClearInjectableArgvs() {
delete g_injected_test_argvs;
g_injected_test_argvs = NULL;
}
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
...@@ -1171,11 +1185,12 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) { ...@@ -1171,11 +1185,12 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
bool BoolFromGTestEnv(const char* flag, bool default_value) { bool BoolFromGTestEnv(const char* flag, bool default_value) {
#if defined(GTEST_GET_BOOL_FROM_ENV_) #if defined(GTEST_GET_BOOL_FROM_ENV_)
return GTEST_GET_BOOL_FROM_ENV_(flag, default_value); return GTEST_GET_BOOL_FROM_ENV_(flag, default_value);
#endif // defined(GTEST_GET_BOOL_FROM_ENV_) #else
const std::string env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = posix::GetEnv(env_var.c_str()); const char* const string_value = posix::GetEnv(env_var.c_str());
return string_value == NULL ? return string_value == NULL ?
default_value : strcmp(string_value, "0") != 0; default_value : strcmp(string_value, "0") != 0;
#endif // defined(GTEST_GET_BOOL_FROM_ENV_)
} }
// Reads and returns a 32-bit integer stored in the environment // Reads and returns a 32-bit integer stored in the environment
...@@ -1184,7 +1199,7 @@ bool BoolFromGTestEnv(const char* flag, bool default_value) { ...@@ -1184,7 +1199,7 @@ bool BoolFromGTestEnv(const char* flag, bool default_value) {
Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
#if defined(GTEST_GET_INT32_FROM_ENV_) #if defined(GTEST_GET_INT32_FROM_ENV_)
return GTEST_GET_INT32_FROM_ENV_(flag, default_value); return GTEST_GET_INT32_FROM_ENV_(flag, default_value);
#endif // defined(GTEST_GET_INT32_FROM_ENV_) #else
const std::string env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = posix::GetEnv(env_var.c_str()); const char* const string_value = posix::GetEnv(env_var.c_str());
if (string_value == NULL) { if (string_value == NULL) {
...@@ -1202,37 +1217,36 @@ Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { ...@@ -1202,37 +1217,36 @@ Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
} }
return result; return result;
#endif // defined(GTEST_GET_INT32_FROM_ENV_)
}
// As a special case for the 'output' flag, if GTEST_OUTPUT is not
// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build
// system. The value of XML_OUTPUT_FILE is a filename without the
// "xml:" prefix of GTEST_OUTPUT.
// Note that this is meant to be called at the call site so it does
// not check that the flag is 'output'
// In essence this checks an env variable called XML_OUTPUT_FILE
// and if it is set we prepend "xml:" to its value, if it not set we return ""
std::string OutputFlagAlsoCheckEnvVar(){
std::string default_value_for_output_flag = "";
const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE");
if (NULL != xml_output_file_env) {
default_value_for_output_flag = std::string("xml:") + xml_output_file_env;
}
return default_value_for_output_flag;
} }
// Reads and returns the string environment variable corresponding to // Reads and returns the string environment variable corresponding to
// the given flag; if it's not set, returns default_value. // the given flag; if it's not set, returns default_value.
std::string StringFromGTestEnv(const char* flag, const char* default_value) { const char* StringFromGTestEnv(const char* flag, const char* default_value) {
#if defined(GTEST_GET_STRING_FROM_ENV_) #if defined(GTEST_GET_STRING_FROM_ENV_)
return GTEST_GET_STRING_FROM_ENV_(flag, default_value); return GTEST_GET_STRING_FROM_ENV_(flag, default_value);
#endif // defined(GTEST_GET_STRING_FROM_ENV_) #else
const std::string env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* value = posix::GetEnv(env_var.c_str()); const char* const value = posix::GetEnv(env_var.c_str());
if (value != NULL) { return value == NULL ? default_value : value;
return value; #endif // defined(GTEST_GET_STRING_FROM_ENV_)
}
// As a special case for the 'output' flag, if GTEST_OUTPUT is not
// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build
// system. The value of XML_OUTPUT_FILE is a filename without the
// "xml:" prefix of GTEST_OUTPUT.
//
// The net priority order after flag processing is thus:
// --gtest_output command line flag
// GTEST_OUTPUT environment variable
// XML_OUTPUT_FILE environment variable
// 'default_value'
if (strcmp(flag, "output") == 0) {
value = posix::GetEnv("XML_OUTPUT_FILE");
if (value != NULL) {
return std::string("xml:") + value;
}
}
return default_value;
} }
} // namespace internal } // namespace internal
......
...@@ -230,9 +230,15 @@ GTEST_DEFINE_string_( ...@@ -230,9 +230,15 @@ GTEST_DEFINE_string_(
GTEST_DEFINE_bool_(list_tests, false, GTEST_DEFINE_bool_(list_tests, false,
"List all tests without running them."); "List all tests without running them.");
// The net priority order after flag processing is thus:
// --gtest_output command line flag
// GTEST_OUTPUT environment variable
// XML_OUTPUT_FILE environment variable
// ''
GTEST_DEFINE_string_( GTEST_DEFINE_string_(
output, output,
internal::StringFromGTestEnv("output", ""), internal::StringFromGTestEnv("output",
internal::OutputFlagAlsoCheckEnvVar().c_str()),
"A format (defaults to \"xml\" but can be specified to be \"json\"), " "A format (defaults to \"xml\" but can be specified to be \"json\"), "
"optionally followed by a colon and an output file name or directory. " "optionally followed by a colon and an output file name or directory. "
"A directory is indicated by a trailing pathname separator. " "A directory is indicated by a trailing pathname separator. "
...@@ -386,12 +392,15 @@ void AssertHelper::operator=(const Message& message) const { ...@@ -386,12 +392,15 @@ void AssertHelper::operator=(const Message& message) const {
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
// A copy of all command line arguments. Set by InitGoogleTest(). // A copy of all command line arguments. Set by InitGoogleTest().
::std::vector<testing::internal::string> g_argvs; ::std::vector<std::string> g_argvs;
const ::std::vector<testing::internal::string>& GetArgvs() { ::std::vector<std::string> GetArgvs() {
#if defined(GTEST_CUSTOM_GET_ARGVS_) #if defined(GTEST_CUSTOM_GET_ARGVS_)
return GTEST_CUSTOM_GET_ARGVS_(); // GTEST_CUSTOM_GET_ARGVS_() may return a container of std::string or
#else // defined(GTEST_CUSTOM_GET_ARGVS_) // ::string. This code converts it to the appropriate type.
const auto& custom = GTEST_CUSTOM_GET_ARGVS_();
return ::std::vector<std::string>(custom.begin(), custom.end());
#else // defined(GTEST_CUSTOM_GET_ARGVS_)
return g_argvs; return g_argvs;
#endif // defined(GTEST_CUSTOM_GET_ARGVS_) #endif // defined(GTEST_CUSTOM_GET_ARGVS_)
} }
...@@ -2912,16 +2921,20 @@ static int GetBitOffset(WORD color_mask) { ...@@ -2912,16 +2921,20 @@ static int GetBitOffset(WORD color_mask) {
static WORD GetNewColor(GTestColor color, WORD old_color_attrs) { static WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
// Let's reuse the BG // Let's reuse the BG
static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY; static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN |
static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; BACKGROUND_RED | BACKGROUND_INTENSITY;
static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN |
FOREGROUND_RED | FOREGROUND_INTENSITY;
const WORD existing_bg = old_color_attrs & background_mask; const WORD existing_bg = old_color_attrs & background_mask;
WORD new_color = GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY; WORD new_color =
GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY;
static const int bg_bitOffset = GetBitOffset(background_mask); static const int bg_bitOffset = GetBitOffset(background_mask);
static const int fg_bitOffset = GetBitOffset(foreground_mask); static const int fg_bitOffset = GetBitOffset(foreground_mask);
if (((new_color & background_mask) >> bg_bitOffset) == ((new_color & foreground_mask) >> fg_bitOffset)) { if (((new_color & background_mask) >> bg_bitOffset) ==
new_color ^= FOREGROUND_INTENSITY; //invert intensity ((new_color & foreground_mask) >> fg_bitOffset)) {
new_color ^= FOREGROUND_INTENSITY; // invert intensity
} }
return new_color; return new_color;
} }
...@@ -2982,7 +2995,6 @@ bool ShouldUseColor(bool stdout_is_tty) { ...@@ -2982,7 +2995,6 @@ bool ShouldUseColor(bool stdout_is_tty) {
// cannot simply emit special characters and have the terminal change colors. // cannot simply emit special characters and have the terminal change colors.
// This routine must actually emit the characters rather than return a string // This routine must actually emit the characters rather than return a string
// that would be colored when printed, as can be done on Linux. // that would be colored when printed, as can be done on Linux.
GTEST_ATTRIBUTE_PRINTF_(2, 3)
static void ColoredPrintf(GTestColor color, const char* fmt, ...) { static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
...@@ -3032,7 +3044,7 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) { ...@@ -3032,7 +3044,7 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
va_end(args); va_end(args);
} }
// Text printed in Google Test's text output and --gunit_list_tests // Text printed in Google Test's text output and --gtest_list_tests
// output to label the type parameter and value parameter for a test. // output to label the type parameter and value parameter for a test.
static const char kTypeParamLabel[] = "TypeParam"; static const char kTypeParamLabel[] = "TypeParam";
static const char kValueParamLabel[] = "GetParam()"; static const char kValueParamLabel[] = "GetParam()";
...@@ -3442,6 +3454,11 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener { ...@@ -3442,6 +3454,11 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
// to delimit this attribute from prior attributes. // to delimit this attribute from prior attributes.
static std::string TestPropertiesAsXmlAttributes(const TestResult& result); static std::string TestPropertiesAsXmlAttributes(const TestResult& result);
// Streams an XML representation of the test properties of a TestResult
// object.
static void OutputXmlTestProperties(std::ostream* stream,
const TestResult& result);
// The output file. // The output file.
const std::string output_file_; const std::string output_file_;
...@@ -3653,6 +3670,10 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, ...@@ -3653,6 +3670,10 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
const TestResult& result = *test_info.result(); const TestResult& result = *test_info.result();
const std::string kTestcase = "testcase"; const std::string kTestcase = "testcase";
if (test_info.is_in_another_shard()) {
return;
}
*stream << " <testcase"; *stream << " <testcase";
OutputXmlAttribute(stream, kTestcase, "name", test_info.name()); OutputXmlAttribute(stream, kTestcase, "name", test_info.name());
...@@ -3669,7 +3690,6 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, ...@@ -3669,7 +3690,6 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
OutputXmlAttribute(stream, kTestcase, "time", OutputXmlAttribute(stream, kTestcase, "time",
FormatTimeInMillisAsSeconds(result.elapsed_time())); FormatTimeInMillisAsSeconds(result.elapsed_time()));
OutputXmlAttribute(stream, kTestcase, "classname", test_case_name); OutputXmlAttribute(stream, kTestcase, "classname", test_case_name);
*stream << TestPropertiesAsXmlAttributes(result);
int failures = 0; int failures = 0;
for (int i = 0; i < result.total_part_count(); ++i) { for (int i = 0; i < result.total_part_count(); ++i) {
...@@ -3691,10 +3711,15 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, ...@@ -3691,10 +3711,15 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
} }
} }
if (failures == 0) if (failures == 0 && result.test_property_count() == 0) {
*stream << " />\n"; *stream << " />\n";
else } else {
if (failures == 0) {
*stream << ">\n";
}
OutputXmlTestProperties(stream, result);
*stream << " </testcase>\n"; *stream << " </testcase>\n";
}
} }
// Prints an XML representation of a TestCase object // Prints an XML representation of a TestCase object
...@@ -3749,7 +3774,6 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, ...@@ -3749,7 +3774,6 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,
OutputXmlAttribute(stream, kTestsuites, "random_seed", OutputXmlAttribute(stream, kTestsuites, "random_seed",
StreamableToString(unit_test.random_seed())); StreamableToString(unit_test.random_seed()));
} }
*stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result());
OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); OutputXmlAttribute(stream, kTestsuites, "name", "AllTests");
...@@ -3775,6 +3799,26 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( ...@@ -3775,6 +3799,26 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
return attributes.GetString(); return attributes.GetString();
} }
void XmlUnitTestResultPrinter::OutputXmlTestProperties(
std::ostream* stream, const TestResult& result) {
const std::string kProperties = "properties";
const std::string kProperty = "property";
if (result.test_property_count() <= 0) {
return;
}
*stream << "<" << kProperties << ">\n";
for (int i = 0; i < result.test_property_count(); ++i) {
const TestProperty& property = result.GetTestProperty(i);
*stream << "<" << kProperty;
*stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\"";
*stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\"";
*stream << "/>\n";
}
*stream << "</" << kProperties << ">\n";
}
// End XmlUnitTestResultPrinter // End XmlUnitTestResultPrinter
...@@ -4210,9 +4254,10 @@ void OsStackTraceGetter::UponLeavingGTest() {} ...@@ -4210,9 +4254,10 @@ void OsStackTraceGetter::UponLeavingGTest() {}
class ScopedPrematureExitFile { class ScopedPrematureExitFile {
public: public:
explicit ScopedPrematureExitFile(const char* premature_exit_filepath) explicit ScopedPrematureExitFile(const char* premature_exit_filepath)
: premature_exit_filepath_(premature_exit_filepath) { : premature_exit_filepath_(premature_exit_filepath ?
premature_exit_filepath : "") {
// If a path to the premature-exit file is specified... // If a path to the premature-exit file is specified...
if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') { if (!premature_exit_filepath_.empty()) {
// create the file with a single "0" character in it. I/O // create the file with a single "0" character in it. I/O
// errors are ignored as there's nothing better we can do and we // errors are ignored as there's nothing better we can do and we
// don't want to fail the test because of this. // don't want to fail the test because of this.
...@@ -4223,13 +4268,18 @@ class ScopedPrematureExitFile { ...@@ -4223,13 +4268,18 @@ class ScopedPrematureExitFile {
} }
~ScopedPrematureExitFile() { ~ScopedPrematureExitFile() {
if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') { if (!premature_exit_filepath_.empty()) {
remove(premature_exit_filepath_); int retval = remove(premature_exit_filepath_.c_str());
if (retval) {
GTEST_LOG_(ERROR) << "Failed to remove premature exit filepath \""
<< premature_exit_filepath_ << "\" with error "
<< retval;
}
} }
} }
private: private:
const char* const premature_exit_filepath_; const std::string premature_exit_filepath_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile);
}; };
...@@ -4897,13 +4947,8 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); } ...@@ -4897,13 +4947,8 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); }
// All other functions called from RunAllTests() may safely assume that // All other functions called from RunAllTests() may safely assume that
// parameterized tests are ready to be counted and run. // parameterized tests are ready to be counted and run.
bool UnitTestImpl::RunAllTests() { bool UnitTestImpl::RunAllTests() {
// Makes sure InitGoogleTest() was called. // True iff Google Test is initialized before RUN_ALL_TESTS() is called.
if (!GTestIsInitialized()) { const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized();
GTEST_LOG_(ERROR) <<
"\nThis test program did NOT call ::testing::InitGoogleTest "
"before calling RUN_ALL_TESTS(). Please fix it.";
return false;
}
// Do not run any test if the --help flag was specified. // Do not run any test if the --help flag was specified.
if (g_help_flag) if (g_help_flag)
...@@ -5031,6 +5076,20 @@ bool UnitTestImpl::RunAllTests() { ...@@ -5031,6 +5076,20 @@ bool UnitTestImpl::RunAllTests() {
repeater->OnTestProgramEnd(*parent_); repeater->OnTestProgramEnd(*parent_);
if (!gtest_is_initialized_before_run_all_tests) {
ColoredPrintf(
COLOR_RED,
"\nIMPORTANT NOTICE - DO NOT IGNORE:\n"
"This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_
"() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_
" will start to enforce the valid usage. "
"Please fix it ASAP, or IT WILL START TO FAIL.\n"); // NOLINT
#if GTEST_FOR_GOOGLE_
ColoredPrintf(COLOR_RED,
"For more details, see http://wiki/Main/ValidGUnitMain.\n");
#endif // GTEST_FOR_GOOGLE_
}
return !failed; return !failed;
} }
...@@ -5077,7 +5136,7 @@ bool ShouldShard(const char* total_shards_env, ...@@ -5077,7 +5136,7 @@ bool ShouldShard(const char* total_shards_env,
<< "Invalid environment variables: you have " << "Invalid environment variables: you have "
<< kTestShardIndex << " = " << shard_index << kTestShardIndex << " = " << shard_index
<< ", but have left " << kTestTotalShards << " unset.\n"; << ", but have left " << kTestTotalShards << " unset.\n";
ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); ColoredPrintf(COLOR_RED, msg.GetString().c_str());
fflush(stdout); fflush(stdout);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} else if (total_shards != -1 && shard_index == -1) { } else if (total_shards != -1 && shard_index == -1) {
...@@ -5085,7 +5144,7 @@ bool ShouldShard(const char* total_shards_env, ...@@ -5085,7 +5144,7 @@ bool ShouldShard(const char* total_shards_env,
<< "Invalid environment variables: you have " << "Invalid environment variables: you have "
<< kTestTotalShards << " = " << total_shards << kTestTotalShards << " = " << total_shards
<< ", but have left " << kTestShardIndex << " unset.\n"; << ", but have left " << kTestShardIndex << " unset.\n";
ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); ColoredPrintf(COLOR_RED, msg.GetString().c_str());
fflush(stdout); fflush(stdout);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} else if (shard_index < 0 || shard_index >= total_shards) { } else if (shard_index < 0 || shard_index >= total_shards) {
...@@ -5094,7 +5153,7 @@ bool ShouldShard(const char* total_shards_env, ...@@ -5094,7 +5153,7 @@ bool ShouldShard(const char* total_shards_env,
<< kTestShardIndex << " < " << kTestTotalShards << kTestShardIndex << " < " << kTestTotalShards
<< ", but you have " << kTestShardIndex << "=" << shard_index << ", but you have " << kTestShardIndex << "=" << shard_index
<< ", " << kTestTotalShards << "=" << total_shards << ".\n"; << ", " << kTestTotalShards << "=" << total_shards << ".\n";
ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); ColoredPrintf(COLOR_RED, msg.GetString().c_str());
fflush(stdout); fflush(stdout);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
...@@ -5132,8 +5191,8 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { ...@@ -5132,8 +5191,8 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
// each TestCase and TestInfo object. // each TestCase and TestInfo object.
// If shard_tests == true, further filters tests based on sharding // If shard_tests == true, further filters tests based on sharding
// variables in the environment - see // variables in the environment - see
// https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md . // https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md
// Returns the number of tests that should run. // . Returns the number of tests that should run.
int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ?
Int32FromEnvOrDie(kTestTotalShards, -1) : -1; Int32FromEnvOrDie(kTestTotalShards, -1) : -1;
...@@ -5361,8 +5420,7 @@ bool SkipPrefix(const char* prefix, const char** pstr) { ...@@ -5361,8 +5420,7 @@ bool SkipPrefix(const char* prefix, const char** pstr) {
// part can be omitted. // part can be omitted.
// //
// Returns the value of the flag, or NULL if the parsing failed. // Returns the value of the flag, or NULL if the parsing failed.
static const char* ParseFlagValue(const char* str, static const char* ParseFlagValue(const char* str, const char* flag,
const char* flag,
bool def_optional) { bool def_optional) {
// str and flag must not be NULL. // str and flag must not be NULL.
if (str == NULL || flag == NULL) return NULL; if (str == NULL || flag == NULL) return NULL;
...@@ -5433,9 +5491,8 @@ bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { ...@@ -5433,9 +5491,8 @@ bool ParseInt32Flag(const char* str, const char* flag, Int32* value) {
// //
// On success, stores the value of the flag in *value, and returns // On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value. // true. On failure, returns false without changing *value.
static bool ParseStringFlag(const char* str, template <typename String>
const char* flag, static bool ParseStringFlag(const char* str, const char* flag, String* value) {
std::string* value) {
// Gets the value of the flag as a string. // Gets the value of the flag as a string.
const char* const value_str = ParseFlagValue(str, flag, false); const char* const value_str = ParseFlagValue(str, flag, false);
...@@ -5535,22 +5592,22 @@ static const char kColorEncodedHelpMessage[] = ...@@ -5535,22 +5592,22 @@ static const char kColorEncodedHelpMessage[] =
"Test Output:\n" "Test Output:\n"
" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" " @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n"
" Enable/disable colored output. The default is @Gauto@D.\n" " Enable/disable colored output. The default is @Gauto@D.\n"
" @G--" GTEST_FLAG_PREFIX_ "print_time=0@D\n" " -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
" Don't print the elapsed time of each test.\n" " Don't print the elapsed time of each test.\n"
" @G--" GTEST_FLAG_PREFIX_ "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G" " @G--" GTEST_FLAG_PREFIX_ "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G"
GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
" Generate a JSON or XML report in the given directory or with the given\n" " Generate a JSON or XML report in the given directory or with the given\n"
" file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" " file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n"
#if GTEST_CAN_STREAM_RESULTS_ # if GTEST_CAN_STREAM_RESULTS_
" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" " @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n"
" Stream test results to the given server.\n" " Stream test results to the given server.\n"
#endif // GTEST_CAN_STREAM_RESULTS_ # endif // GTEST_CAN_STREAM_RESULTS_
"\n" "\n"
"Assertion Behavior:\n" "Assertion Behavior:\n"
#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS # if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" " @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
" Set the default death test style.\n" " Set the default death test style.\n"
#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS # endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" " @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n"
" Turn assertion failures into debugger break-points.\n" " Turn assertion failures into debugger break-points.\n"
" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" " @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n"
......
...@@ -848,6 +848,34 @@ TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) { ...@@ -848,6 +848,34 @@ TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) {
INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5));
// Tests that macros in test names are expanded correctly.
class MacroNamingTest : public TestWithParam<int> {};
#define PREFIX_WITH_FOO(test_name) Foo##test_name
#define PREFIX_WITH_MACRO(test_name) Macro##test_name
TEST_P(PREFIX_WITH_MACRO(NamingTest), PREFIX_WITH_FOO(SomeTestName)) {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
EXPECT_STREQ("FortyTwo/MacroNamingTest", test_info->test_case_name());
EXPECT_STREQ("FooSomeTestName", test_info->name());
}
INSTANTIATE_TEST_CASE_P(FortyTwo, MacroNamingTest, Values(42));
// Tests the same thing for non-parametrized tests.
class MacroNamingTestNonParametrized : public ::testing::Test {};
TEST_F(PREFIX_WITH_MACRO(NamingTestNonParametrized),
PREFIX_WITH_FOO(SomeTestName)) {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
EXPECT_STREQ("MacroNamingTestNonParametrized", test_info->test_case_name());
EXPECT_STREQ("FooSomeTestName", test_info->name());
}
// Tests that user supplied custom parameter names are working correctly. // Tests that user supplied custom parameter names are working correctly.
// Runs the test with a builtin helper method which uses PrintToString, // Runs the test with a builtin helper method which uses PrintToString,
// as well as a custom function and custom functor to ensure all possible // as well as a custom function and custom functor to ensure all possible
......
...@@ -50,18 +50,13 @@ ...@@ -50,18 +50,13 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
// hash_map and hash_set are available under Visual C++, or on Linux.
#if GTEST_HAS_UNORDERED_MAP_ #if GTEST_HAS_UNORDERED_MAP_
# include <unordered_map> // NOLINT # include <unordered_map> // NOLINT
#elif GTEST_HAS_HASH_MAP_ #endif // GTEST_HAS_UNORDERED_MAP_
# include <hash_map> // NOLINT
#endif // GTEST_HAS_HASH_MAP_
#if GTEST_HAS_UNORDERED_SET_ #if GTEST_HAS_UNORDERED_SET_
# include <unordered_set> // NOLINT # include <unordered_set> // NOLINT
#elif GTEST_HAS_HASH_SET_ #endif // GTEST_HAS_UNORDERED_SET_
# include <hash_set> // NOLINT
#endif // GTEST_HAS_HASH_SET_
#if GTEST_HAS_STD_FORWARD_LIST_ #if GTEST_HAS_STD_FORWARD_LIST_
# include <forward_list> // NOLINT # include <forward_list> // NOLINT
...@@ -200,7 +195,6 @@ class PathLike { ...@@ -200,7 +195,6 @@ class PathLike {
struct iterator { struct iterator {
typedef PathLike value_type; typedef PathLike value_type;
}; };
typedef iterator const_iterator;
PathLike() {} PathLike() {}
...@@ -238,50 +232,6 @@ using ::testing::internal::UniversalPrinter; ...@@ -238,50 +232,6 @@ using ::testing::internal::UniversalPrinter;
using ::testing::internal::UniversalTersePrint; using ::testing::internal::UniversalTersePrint;
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ #if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; using ::testing::internal::UniversalTersePrintTupleFieldsToStrings;
#endif
using ::testing::internal::string;
// The hash_* classes are not part of the C++ standard. STLport
// defines them in namespace std. MSVC defines them in ::stdext. GCC
// defines them in ::.
#if GTEST_HAS_UNORDERED_MAP_
#define GTEST_HAS_HASH_MAP_ 1
template <class Key, class T>
using hash_map = ::std::unordered_map<Key, T>;
template <class Key, class T>
using hash_multimap = ::std::unordered_multimap<Key, T>;
#elif GTEST_HAS_HASH_MAP_
#ifdef _STLP_HASH_MAP // We got <hash_map> from STLport.
using ::std::hash_map;
using ::std::hash_multimap;
#elif _MSC_VER
using ::stdext::hash_map;
using ::stdext::hash_multimap;
#endif
#endif
#if GTEST_HAS_UNORDERED_SET_
#define GTEST_HAS_HASH_SET_ 1
template <class Key>
using hash_set = ::std::unordered_set<Key>;
template <class Key>
using hash_multiset = ::std::unordered_multiset<Key>;
#elif GTEST_HAS_HASH_SET_
#ifdef _STLP_HASH_MAP // We got <hash_map> from STLport.
using ::std::hash_map;
using ::std::hash_multimap;
#elif _MSC_VER
using ::stdext::hash_map;
using ::stdext::hash_multimap;
#endif
#endif #endif
// Prints a value to a string using the universal value printer. This // Prints a value to a string using the universal value printer. This
...@@ -868,16 +818,16 @@ TEST(PrintStlContainerTest, NonEmptyDeque) { ...@@ -868,16 +818,16 @@ TEST(PrintStlContainerTest, NonEmptyDeque) {
EXPECT_EQ("{ 1, 3 }", Print(non_empty)); EXPECT_EQ("{ 1, 3 }", Print(non_empty));
} }
#if GTEST_HAS_HASH_MAP_ #if GTEST_HAS_UNORDERED_MAP_
TEST(PrintStlContainerTest, OneElementHashMap) { TEST(PrintStlContainerTest, OneElementHashMap) {
hash_map<int, char> map1; ::std::unordered_map<int, char> map1;
map1[1] = 'a'; map1[1] = 'a';
EXPECT_EQ("{ (1, 'a' (97, 0x61)) }", Print(map1)); EXPECT_EQ("{ (1, 'a' (97, 0x61)) }", Print(map1));
} }
TEST(PrintStlContainerTest, HashMultiMap) { TEST(PrintStlContainerTest, HashMultiMap) {
hash_multimap<int, bool> map1; ::std::unordered_multimap<int, bool> map1;
map1.insert(make_pair(5, true)); map1.insert(make_pair(5, true));
map1.insert(make_pair(5, false)); map1.insert(make_pair(5, false));
...@@ -888,12 +838,12 @@ TEST(PrintStlContainerTest, HashMultiMap) { ...@@ -888,12 +838,12 @@ TEST(PrintStlContainerTest, HashMultiMap) {
<< " where Print(map1) returns \"" << result << "\"."; << " where Print(map1) returns \"" << result << "\".";
} }
#endif // GTEST_HAS_HASH_MAP_ #endif // GTEST_HAS_UNORDERED_MAP_
#if GTEST_HAS_HASH_SET_ #if GTEST_HAS_UNORDERED_SET_
TEST(PrintStlContainerTest, HashSet) { TEST(PrintStlContainerTest, HashSet) {
hash_set<int> set1; ::std::unordered_set<int> set1;
set1.insert(1); set1.insert(1);
EXPECT_EQ("{ 1 }", Print(set1)); EXPECT_EQ("{ 1 }", Print(set1));
} }
...@@ -901,7 +851,7 @@ TEST(PrintStlContainerTest, HashSet) { ...@@ -901,7 +851,7 @@ TEST(PrintStlContainerTest, HashSet) {
TEST(PrintStlContainerTest, HashMultiSet) { TEST(PrintStlContainerTest, HashMultiSet) {
const int kSize = 5; const int kSize = 5;
int a[kSize] = { 1, 1, 2, 5, 1 }; int a[kSize] = { 1, 1, 2, 5, 1 };
hash_multiset<int> set1(a, a + kSize); ::std::unordered_multiset<int> set1(a, a + kSize);
// Elements of hash_multiset can be printed in any order. // Elements of hash_multiset can be printed in any order.
const std::string result = Print(set1); const std::string result = Print(set1);
...@@ -927,7 +877,7 @@ TEST(PrintStlContainerTest, HashMultiSet) { ...@@ -927,7 +877,7 @@ TEST(PrintStlContainerTest, HashMultiSet) {
EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin())); EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin()));
} }
#endif // GTEST_HAS_HASH_SET_ #endif // GTEST_HAS_UNORDERED_SET_
TEST(PrintStlContainerTest, List) { TEST(PrintStlContainerTest, List) {
const std::string a[] = {"hello", "world"}; const std::string a[] = {"hello", "world"};
......
...@@ -81,13 +81,14 @@ def TestFlag(flag, test_val, default_val): ...@@ -81,13 +81,14 @@ def TestFlag(flag, test_val, default_val):
class GTestEnvVarTest(gtest_test_utils.TestCase): class GTestEnvVarTest(gtest_test_utils.TestCase):
def testEnvVarAffectsFlag(self): def testEnvVarAffectsFlag(self):
"""Tests that environment variable should affect the corresponding flag.""" """Tests that environment variable should affect the corresponding flag."""
TestFlag('break_on_failure', '1', '0') TestFlag('break_on_failure', '1', '0')
TestFlag('color', 'yes', 'auto') TestFlag('color', 'yes', 'auto')
TestFlag('filter', 'FooTest.Bar', '*') TestFlag('filter', 'FooTest.Bar', '*')
SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test
TestFlag('output', 'xml:tmp/foo.xml', '') TestFlag('output', 'xml:tmp/foo.xml', '')
TestFlag('print_time', '0', '1') TestFlag('print_time', '0', '1')
TestFlag('repeat', '999', '1') TestFlag('repeat', '999', '1')
...@@ -99,6 +100,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase): ...@@ -99,6 +100,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase):
TestFlag('death_test_use_fork', '1', '0') TestFlag('death_test_use_fork', '1', '0')
TestFlag('stack_trace_depth', '0', '100') TestFlag('stack_trace_depth', '0', '100')
def testXmlOutputFile(self): def testXmlOutputFile(self):
"""Tests that $XML_OUTPUT_FILE affects the output flag.""" """Tests that $XML_OUTPUT_FILE affects the output flag."""
...@@ -107,7 +109,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase): ...@@ -107,7 +109,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase):
AssertEq('xml:tmp/bar.xml', GetFlag('output')) AssertEq('xml:tmp/bar.xml', GetFlag('output'))
def testXmlOutputFileOverride(self): def testXmlOutputFileOverride(self):
"""Tests that $XML_OUTPUT_FILE is overridden by $GTEST_OUTPUT""" """Tests that $XML_OUTPUT_FILE is overridden by $GTEST_OUTPUT."""
SetEnvVar('GTEST_OUTPUT', 'xml:tmp/foo.xml') SetEnvVar('GTEST_OUTPUT', 'xml:tmp/foo.xml')
SetEnvVar('XML_OUTPUT_FILE', 'tmp/bar.xml') SetEnvVar('XML_OUTPUT_FILE', 'tmp/bar.xml')
......
...@@ -32,9 +32,8 @@ ...@@ -32,9 +32,8 @@
import json import json
import os import os
import gtest_test_utils
import gtest_json_test_utils import gtest_json_test_utils
import gtest_test_utils
GTEST_OUTPUT_SUBDIR = 'json_outfiles' GTEST_OUTPUT_SUBDIR = 'json_outfiles'
GTEST_OUTPUT_1_TEST = 'gtest_xml_outfile1_test_' GTEST_OUTPUT_1_TEST = 'gtest_xml_outfile1_test_'
......
...@@ -37,9 +37,8 @@ import os ...@@ -37,9 +37,8 @@ import os
import re import re
import sys import sys
import gtest_test_utils
import gtest_json_test_utils import gtest_json_test_utils
import gtest_test_utils
GTEST_FILTER_FLAG = '--gtest_filter' GTEST_FILTER_FLAG = '--gtest_filter'
GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' GTEST_LIST_TESTS_FLAG = '--gtest_list_tests'
......
...@@ -44,7 +44,7 @@ def normalize(obj): ...@@ -44,7 +44,7 @@ def normalize(obj):
""" """
def _normalize(key, value): def _normalize(key, value):
if key == 'time': if key == 'time':
return re.sub(r'^\d+(\.\d+)?s$', u'*', value) return re.sub(r'^\d+(\.\d+)?s$', '*', value)
elif key == 'timestamp': elif key == 'timestamp':
return re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ$', '*', value) return re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ$', '*', value)
elif key == 'failure': elif key == 'failure':
......
...@@ -227,7 +227,7 @@ class Subprocess: ...@@ -227,7 +227,7 @@ class Subprocess:
combined in a string. combined in a string.
""" """
# The subprocess module is the preferable way of running programs # The subprocess module is the preferrable way of running programs
# since it is available and behaves consistently on all platforms, # since it is available and behaves consistently on all platforms,
# including Windows. But it is only available starting in python 2.4. # including Windows. But it is only available starting in python 2.4.
# In earlier python versions, we revert to the popen2 module, which is # In earlier python versions, we revert to the popen2 module, which is
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
__author__ = 'wan@google.com (Zhanyong Wan)' __author__ = 'wan@google.com (Zhanyong Wan)'
import os
import gtest_test_utils import gtest_test_utils
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_') COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_')
......
...@@ -64,6 +64,9 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { ...@@ -64,6 +64,9 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
#include <map> #include <map>
#include <vector> #include <vector>
#include <ostream> #include <ostream>
#if GTEST_LANG_CXX11
#include <unordered_set>
#endif // GTEST_LANG_CXX11
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
...@@ -258,6 +261,8 @@ using testing::internal::IsContainer; ...@@ -258,6 +261,8 @@ using testing::internal::IsContainer;
using testing::internal::IsContainerTest; using testing::internal::IsContainerTest;
using testing::internal::IsNotContainer; using testing::internal::IsNotContainer;
using testing::internal::NativeArray; using testing::internal::NativeArray;
using testing::internal::OsStackTraceGetter;
using testing::internal::OsStackTraceGetterInterface;
using testing::internal::ParseInt32Flag; using testing::internal::ParseInt32Flag;
using testing::internal::RelationToSourceCopy; using testing::internal::RelationToSourceCopy;
using testing::internal::RelationToSourceReference; using testing::internal::RelationToSourceReference;
...@@ -274,6 +279,7 @@ using testing::internal::String; ...@@ -274,6 +279,7 @@ using testing::internal::String;
using testing::internal::TestEventListenersAccessor; using testing::internal::TestEventListenersAccessor;
using testing::internal::TestResultAccessor; using testing::internal::TestResultAccessor;
using testing::internal::UInt32; using testing::internal::UInt32;
using testing::internal::UnitTestImpl;
using testing::internal::WideStringToUtf8; using testing::internal::WideStringToUtf8;
using testing::internal::edit_distance::CalculateOptimalEdits; using testing::internal::edit_distance::CalculateOptimalEdits;
using testing::internal::edit_distance::CreateUnifiedDiff; using testing::internal::edit_distance::CreateUnifiedDiff;
...@@ -7526,6 +7532,50 @@ TEST(IsContainerTestTest, WorksForContainer) { ...@@ -7526,6 +7532,50 @@ TEST(IsContainerTestTest, WorksForContainer) {
sizeof(IsContainerTest<std::map<int, double> >(0))); sizeof(IsContainerTest<std::map<int, double> >(0)));
} }
#if GTEST_LANG_CXX11
struct ConstOnlyContainerWithPointerIterator {
using const_iterator = int*;
const_iterator begin() const;
const_iterator end() const;
};
struct ConstOnlyContainerWithClassIterator {
struct const_iterator {
const int& operator*() const;
const_iterator& operator++(/* pre-increment */);
};
const_iterator begin() const;
const_iterator end() const;
};
TEST(IsContainerTestTest, ConstOnlyContainer) {
EXPECT_EQ(sizeof(IsContainer),
sizeof(IsContainerTest<ConstOnlyContainerWithPointerIterator>(0)));
EXPECT_EQ(sizeof(IsContainer),
sizeof(IsContainerTest<ConstOnlyContainerWithClassIterator>(0)));
}
#endif // GTEST_LANG_CXX11
// Tests IsHashTable.
struct AHashTable {
typedef void hasher;
};
struct NotReallyAHashTable {
typedef void hasher;
typedef void reverse_iterator;
};
TEST(IsHashTable, Basic) {
EXPECT_TRUE(testing::internal::IsHashTable<AHashTable>::value);
EXPECT_FALSE(testing::internal::IsHashTable<NotReallyAHashTable>::value);
#if GTEST_LANG_CXX11
EXPECT_FALSE(testing::internal::IsHashTable<std::vector<int>>::value);
EXPECT_TRUE(testing::internal::IsHashTable<std::unordered_set<int>>::value);
#endif // GTEST_LANG_CXX11
#if GTEST_HAS_HASH_SET_
EXPECT_TRUE(testing::internal::IsHashTable<hash_set<int>>::value);
#endif // GTEST_HAS_HASH_SET_
}
// Tests ArrayEq(). // Tests ArrayEq().
TEST(ArrayEqTest, WorksForDegeneratedArrays) { TEST(ArrayEqTest, WorksForDegeneratedArrays) {
......
...@@ -43,7 +43,13 @@ GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_" ...@@ -43,7 +43,13 @@ GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_"
EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?> EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests"> <testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests">
<testsuite name="PropertyOne" tests="1" failures="0" disabled="0" errors="0" time="*"> <testsuite name="PropertyOne" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="TestSomeProperties" status="run" time="*" classname="PropertyOne" SetUpProp="1" TestSomeProperty="1" TearDownProp="1" /> <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyOne">
<properties>
<property name="SetUpProp" value="1"/>
<property name="TestSomeProperty" value="1"/>
<property name="TearDownProp" value="1"/>
</properties>
</testcase>
</testsuite> </testsuite>
</testsuites> </testsuites>
""" """
...@@ -51,7 +57,13 @@ EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?> ...@@ -51,7 +57,13 @@ EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?>
EXPECTED_XML_2 = """<?xml version="1.0" encoding="UTF-8"?> EXPECTED_XML_2 = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests"> <testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests">
<testsuite name="PropertyTwo" tests="1" failures="0" disabled="0" errors="0" time="*"> <testsuite name="PropertyTwo" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="TestSomeProperties" status="run" time="*" classname="PropertyTwo" SetUpProp="2" TestSomeProperty="2" TearDownProp="2" /> <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyTwo">
<properties>
<property name="SetUpProp" value="2"/>
<property name="TestSomeProperty" value="2"/>
<property name="TearDownProp" value="2"/>
</properties>
</testcase>
</testsuite> </testsuite>
</testsuites> </testsuites>
""" """
......
...@@ -104,15 +104,45 @@ Invalid characters in brackets []%(stack)s]]></failure> ...@@ -104,15 +104,45 @@ Invalid characters in brackets []%(stack)s]]></failure>
<testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/> <testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/>
</testsuite> </testsuite>
<testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" SetUpTestCase="yes" TearDownTestCase="aye"> <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" SetUpTestCase="yes" TearDownTestCase="aye">
<testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest" key_1="1"/> <testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest">
<testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest" key_int="1"/> <properties>
<testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest" key_1="1" key_2="2" key_3="3"/> <property name="key_1" value="1"/>
<testcase name="TwoValuesForOneKeyUsesLastValue" status="run" time="*" classname="PropertyRecordingTest" key_1="2"/> </properties>
</testcase>
<testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest">
<properties>
<property name="key_int" value="1"/>
</properties>
</testcase>
<testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest">
<properties>
<property name="key_1" value="1"/>
<property name="key_2" value="2"/>
<property name="key_3" value="3"/>
</properties>
</testcase>
<testcase name="TwoValuesForOneKeyUsesLastValue" status="run" time="*" classname="PropertyRecordingTest">
<properties>
<property name="key_1" value="2"/>
</properties>
</testcase>
</testsuite> </testsuite>
<testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*"> <testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*">
<testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest" key="1"/> <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest">
<testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_int="1"/> <properties>
<testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_string="1"/> <property name="key" value="1"/>
</properties>
</testcase>
<testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest">
<properties>
<property name="key_for_utility_int" value="1"/>
</properties>
</testcase>
<testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest">
<properties>
<property name="key_for_utility_string" value="1"/>
</properties>
</testcase>
</testsuite> </testsuite>
<testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*"> <testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*">
<testcase name="HasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" /> <testcase name="HasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
...@@ -149,7 +179,11 @@ EXPECTED_SHARDED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?> ...@@ -149,7 +179,11 @@ EXPECTED_SHARDED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/> <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
</testsuite> </testsuite>
<testsuite name="NoFixtureTest" tests="1" failures="0" disabled="0" errors="0" time="*"> <testsuite name="NoFixtureTest" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest" key="1"/> <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest">
<properties>
<property name="key" value="1"/>
</properties>
</testcase>
</testsuite> </testsuite>
<testsuite name="Single/ValueParamTest" tests="1" failures="0" disabled="0" errors="0" time="*"> <testsuite name="Single/ValueParamTest" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" /> <testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />
......
...@@ -101,19 +101,22 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): ...@@ -101,19 +101,22 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
self.AssertEquivalentNodes(child, actual_children[child_id]) self.AssertEquivalentNodes(child, actual_children[child_id])
identifying_attribute = { identifying_attribute = {
'testsuites': 'name', 'testsuites': 'name',
'testsuite': 'name', 'testsuite': 'name',
'testcase': 'name', 'testcase': 'name',
'failure': 'message', 'failure': 'message',
} 'property': 'name',
}
def _GetChildren(self, element): def _GetChildren(self, element):
""" """
Fetches all of the child nodes of element, a DOM Element object. Fetches all of the child nodes of element, a DOM Element object.
Returns them as the values of a dictionary keyed by the IDs of the Returns them as the values of a dictionary keyed by the IDs of the
children. For <testsuites>, <testsuite> and <testcase> elements, the ID children. For <testsuites>, <testsuite>, <testcase>, and <property>
is the value of their "name" attribute; for <failure> elements, it is elements, the ID is the value of their "name" attribute; for <failure>
the value of the "message" attribute; CDATA sections and non-whitespace elements, it is the value of the "message" attribute; for <properties>
elements, it is the value of their parent's "name" attribute plus the
literal string "properties"; CDATA sections and non-whitespace
text nodes are concatenated into a single CDATA section with ID text nodes are concatenated into a single CDATA section with ID
"detail". An exception is raised if any element other than the above "detail". An exception is raised if any element other than the above
four is encountered, if two child elements with the same identifying four is encountered, if two child elements with the same identifying
...@@ -123,11 +126,17 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): ...@@ -123,11 +126,17 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
children = {} children = {}
for child in element.childNodes: for child in element.childNodes:
if child.nodeType == Node.ELEMENT_NODE: if child.nodeType == Node.ELEMENT_NODE:
self.assert_(child.tagName in self.identifying_attribute, if child.tagName == 'properties':
'Encountered unknown element <%s>' % child.tagName) self.assert_(child.parentNode is not None,
childID = child.getAttribute(self.identifying_attribute[child.tagName]) 'Encountered <properties> element without a parent')
self.assert_(childID not in children) child_id = child.parentNode.getAttribute('name') + '-properties'
children[childID] = child else:
self.assert_(child.tagName in self.identifying_attribute,
'Encountered unknown element <%s>' % child.tagName)
child_id = child.getAttribute(
self.identifying_attribute[child.tagName])
self.assert_(child_id not in children)
children[child_id] = child
elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]:
if 'detail' not in children: if 'detail' not in children:
if (child.nodeType == Node.CDATA_SECTION_NODE or if (child.nodeType == Node.CDATA_SECTION_NODE or
......
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