Unverified Commit fc437ef4 authored by Bernhard Bauer's avatar Bernhard Bauer Committed by GitHub
Browse files

Merge branch 'master' into upstream_188748737

parents 7b70413e abc6e943
...@@ -128,7 +128,7 @@ FilePath FilePath::RemoveExtension(const char* extension) const { ...@@ -128,7 +128,7 @@ FilePath FilePath::RemoveExtension(const char* extension) const {
return *this; return *this;
} }
// Returns a pointer to the last occurence of a valid path separator in // Returns a pointer to the last occurrence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path // the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found. // separators. Returns NULL if no path separator was found.
const char* FilePath::FindLastPathSeparator() const { const char* FilePath::FindLastPathSeparator() const {
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
# include <windows.h> // NOLINT # include <windows.h> // NOLINT
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
#include "gtest/gtest.h" // NOLINT #include "gtest/gtest.h"
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
namespace testing { namespace testing {
...@@ -86,6 +86,7 @@ const char kFilterFlag[] = "filter"; ...@@ -86,6 +86,7 @@ const char kFilterFlag[] = "filter";
const char kListTestsFlag[] = "list_tests"; const char kListTestsFlag[] = "list_tests";
const char kOutputFlag[] = "output"; const char kOutputFlag[] = "output";
const char kPrintTimeFlag[] = "print_time"; const char kPrintTimeFlag[] = "print_time";
const char kPrintUTF8Flag[] = "print_utf8";
const char kRandomSeedFlag[] = "random_seed"; const char kRandomSeedFlag[] = "random_seed";
const char kRepeatFlag[] = "repeat"; const char kRepeatFlag[] = "repeat";
const char kShuffleFlag[] = "shuffle"; const char kShuffleFlag[] = "shuffle";
...@@ -166,6 +167,7 @@ class GTestFlagSaver { ...@@ -166,6 +167,7 @@ class GTestFlagSaver {
list_tests_ = GTEST_FLAG(list_tests); list_tests_ = GTEST_FLAG(list_tests);
output_ = GTEST_FLAG(output); output_ = GTEST_FLAG(output);
print_time_ = GTEST_FLAG(print_time); print_time_ = GTEST_FLAG(print_time);
print_utf8_ = GTEST_FLAG(print_utf8);
random_seed_ = GTEST_FLAG(random_seed); random_seed_ = GTEST_FLAG(random_seed);
repeat_ = GTEST_FLAG(repeat); repeat_ = GTEST_FLAG(repeat);
shuffle_ = GTEST_FLAG(shuffle); shuffle_ = GTEST_FLAG(shuffle);
...@@ -187,6 +189,7 @@ class GTestFlagSaver { ...@@ -187,6 +189,7 @@ class GTestFlagSaver {
GTEST_FLAG(list_tests) = list_tests_; GTEST_FLAG(list_tests) = list_tests_;
GTEST_FLAG(output) = output_; GTEST_FLAG(output) = output_;
GTEST_FLAG(print_time) = print_time_; GTEST_FLAG(print_time) = print_time_;
GTEST_FLAG(print_utf8) = print_utf8_;
GTEST_FLAG(random_seed) = random_seed_; GTEST_FLAG(random_seed) = random_seed_;
GTEST_FLAG(repeat) = repeat_; GTEST_FLAG(repeat) = repeat_;
GTEST_FLAG(shuffle) = shuffle_; GTEST_FLAG(shuffle) = shuffle_;
...@@ -208,6 +211,7 @@ class GTestFlagSaver { ...@@ -208,6 +211,7 @@ class GTestFlagSaver {
bool list_tests_; bool list_tests_;
std::string output_; std::string output_;
bool print_time_; bool print_time_;
bool print_utf8_;
internal::Int32 random_seed_; internal::Int32 random_seed_;
internal::Int32 repeat_; internal::Int32 repeat_;
bool shuffle_; bool shuffle_;
...@@ -1020,7 +1024,7 @@ class TestResultAccessor { ...@@ -1020,7 +1024,7 @@ class TestResultAccessor {
#if GTEST_CAN_STREAM_RESULTS_ #if GTEST_CAN_STREAM_RESULTS_
// Streams test results to the given port on the given host machine. // Streams test results to the given port on the given host machine.
class GTEST_API_ StreamingListener : public EmptyTestEventListener { class StreamingListener : public EmptyTestEventListener {
public: public:
// Abstract base class for writing strings to a socket. // Abstract base class for writing strings to a socket.
class AbstractSocketWriter { class AbstractSocketWriter {
......
...@@ -915,6 +915,7 @@ GTestLog::~GTestLog() { ...@@ -915,6 +915,7 @@ GTestLog::~GTestLog() {
posix::Abort(); posix::Abort();
} }
} }
// Disable Microsoft deprecation warnings for POSIX functions called from // Disable Microsoft deprecation warnings for POSIX functions called from
// this class (creat, dup, dup2, and close) // this class (creat, dup, dup2, and close)
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
...@@ -1007,8 +1008,7 @@ static CapturedStream* g_captured_stderr = NULL; ...@@ -1007,8 +1008,7 @@ static CapturedStream* g_captured_stderr = NULL;
static CapturedStream* g_captured_stdout = NULL; static CapturedStream* g_captured_stdout = NULL;
// Starts capturing an output stream (stdout/stderr). // Starts capturing an output stream (stdout/stderr).
static void CaptureStream(int fd, static void CaptureStream(int fd, const char* stream_name,
const char* stream_name,
CapturedStream** stream) { CapturedStream** stream) {
if (*stream != NULL) { if (*stream != NULL) {
GTEST_LOG_(FATAL) << "Only one " << stream_name GTEST_LOG_(FATAL) << "Only one " << stream_name
...@@ -1049,6 +1049,10 @@ std::string GetCapturedStderr() { ...@@ -1049,6 +1049,10 @@ std::string GetCapturedStderr() {
#endif // GTEST_HAS_STREAM_REDIRECTION #endif // GTEST_HAS_STREAM_REDIRECTION
size_t GetFileSize(FILE* file) { size_t GetFileSize(FILE* file) {
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
return static_cast<size_t>(ftell(file)); return static_cast<size_t>(ftell(file));
...@@ -1077,22 +1081,36 @@ std::string ReadEntireFile(FILE* file) { ...@@ -1077,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
......
...@@ -43,12 +43,13 @@ ...@@ -43,12 +43,13 @@
// defines Foo. // defines Foo.
#include "gtest/gtest-printers.h" #include "gtest/gtest-printers.h"
#include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <cctype>
#include <cwchar> #include <cwchar>
#include <ostream> // NOLINT #include <ostream> // NOLINT
#include <string> #include <string>
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#include "src/gtest-internal-inl.h"
namespace testing { namespace testing {
...@@ -123,7 +124,7 @@ namespace internal { ...@@ -123,7 +124,7 @@ namespace internal {
// Depending on the value of a char (or wchar_t), we print it in one // Depending on the value of a char (or wchar_t), we print it in one
// of three formats: // of three formats:
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), // - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
// - as a hexidecimal escape sequence (e.g. '\x7F'), or // - as a hexadecimal escape sequence (e.g. '\x7F'), or
// - as a special escape sequence (e.g. '\r', '\n'). // - as a special escape sequence (e.g. '\r', '\n').
enum CharFormat { enum CharFormat {
kAsIs, kAsIs,
...@@ -230,7 +231,7 @@ void PrintCharAndCodeTo(Char c, ostream* os) { ...@@ -230,7 +231,7 @@ void PrintCharAndCodeTo(Char c, ostream* os) {
return; return;
*os << " (" << static_cast<int>(c); *os << " (" << static_cast<int>(c);
// For more convenience, we print c's code again in hexidecimal, // For more convenience, we print c's code again in hexadecimal,
// unless c was already printed in the form '\x##' or the code is in // unless c was already printed in the form '\x##' or the code is in
// [1, 9]. // [1, 9].
if (format == kHexEscape || (1 <= c && c <= 9)) { if (format == kHexEscape || (1 <= c && c <= 9)) {
...@@ -262,11 +263,12 @@ template <typename CharType> ...@@ -262,11 +263,12 @@ template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
static void PrintCharsAsStringTo( static CharFormat PrintCharsAsStringTo(
const CharType* begin, size_t len, ostream* os) { const CharType* begin, size_t len, ostream* os) {
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
*os << kQuoteBegin; *os << kQuoteBegin;
bool is_previous_hex = false; bool is_previous_hex = false;
CharFormat print_format = kAsIs;
for (size_t index = 0; index < len; ++index) { for (size_t index = 0; index < len; ++index) {
const CharType cur = begin[index]; const CharType cur = begin[index];
if (is_previous_hex && IsXDigit(cur)) { if (is_previous_hex && IsXDigit(cur)) {
...@@ -276,8 +278,13 @@ static void PrintCharsAsStringTo( ...@@ -276,8 +278,13 @@ static void PrintCharsAsStringTo(
*os << "\" " << kQuoteBegin; *os << "\" " << kQuoteBegin;
} }
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
// Remember if any characters required hex escaping.
if (is_previous_hex) {
print_format = kHexEscape;
}
} }
*os << "\""; *os << "\"";
return print_format;
} }
// Prints a (const) char/wchar_t array of 'len' elements, starting at address // Prints a (const) char/wchar_t array of 'len' elements, starting at address
...@@ -347,15 +354,90 @@ void PrintTo(const wchar_t* s, ostream* os) { ...@@ -347,15 +354,90 @@ void PrintTo(const wchar_t* s, ostream* os) {
} }
#endif // wchar_t is native #endif // wchar_t is native
namespace {
bool ContainsUnprintableControlCodes(const char* str, size_t length) {
const unsigned char *s = reinterpret_cast<const unsigned char *>(str);
for (size_t i = 0; i < length; i++) {
unsigned char ch = *s++;
if (std::iscntrl(ch)) {
switch (ch) {
case '\t':
case '\n':
case '\r':
break;
default:
return true;
}
}
}
return false;
}
bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t<= 0xbf; }
bool IsValidUTF8(const char* str, size_t length) {
const unsigned char *s = reinterpret_cast<const unsigned char *>(str);
for (size_t i = 0; i < length;) {
unsigned char lead = s[i++];
if (lead <= 0x7f) {
continue; // single-byte character (ASCII) 0..7F
}
if (lead < 0xc2) {
return false; // trail byte or non-shortest form
} else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) {
++i; // 2-byte character
} else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length &&
IsUTF8TrailByte(s[i]) &&
IsUTF8TrailByte(s[i + 1]) &&
// check for non-shortest form and surrogate
(lead != 0xe0 || s[i] >= 0xa0) &&
(lead != 0xed || s[i] < 0xa0)) {
i += 2; // 3-byte character
} else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length &&
IsUTF8TrailByte(s[i]) &&
IsUTF8TrailByte(s[i + 1]) &&
IsUTF8TrailByte(s[i + 2]) &&
// check for non-shortest form
(lead != 0xf0 || s[i] >= 0x90) &&
(lead != 0xf4 || s[i] < 0x90)) {
i += 3; // 4-byte character
} else {
return false;
}
}
return true;
}
void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
if (!ContainsUnprintableControlCodes(str, length) &&
IsValidUTF8(str, length)) {
*os << "\n As Text: \"" << str << "\"";
}
}
} // anonymous namespace
// Prints a ::string object. // Prints a ::string object.
#if GTEST_HAS_GLOBAL_STRING #if GTEST_HAS_GLOBAL_STRING
void PrintStringTo(const ::string& s, ostream* os) { void PrintStringTo(const ::string& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os); if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
if (GTEST_FLAG(print_utf8)) {
ConditionalPrintAsText(s.data(), s.size(), os);
}
}
} }
#endif // GTEST_HAS_GLOBAL_STRING #endif // GTEST_HAS_GLOBAL_STRING
void PrintStringTo(const ::std::string& s, ostream* os) { void PrintStringTo(const ::std::string& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os); if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
if (GTEST_FLAG(print_utf8)) {
ConditionalPrintAsText(s.data(), s.size(), os);
}
}
} }
// Prints a ::wstring object. // Prints a ::wstring object.
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
// Author: wan@google.com (Zhanyong Wan) // Author: wan@google.com (Zhanyong Wan)
#include "gtest/gtest-typed-test.h" #include "gtest/gtest-typed-test.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace testing { namespace testing {
......
...@@ -160,8 +160,10 @@ static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; ...@@ -160,8 +160,10 @@ static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
// A test filter that matches everything. // A test filter that matches everything.
static const char kUniversalFilter[] = "*"; static const char kUniversalFilter[] = "*";
// The default output file for XML output. // The default output format.
static const char kDefaultOutputFile[] = "test_detail.xml"; static const char kDefaultOutputFormat[] = "xml";
// The default output file.
static const char kDefaultOutputFile[] = "test_detail";
// The environment variable name for the test shard index. // The environment variable name for the test shard index.
static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
...@@ -231,9 +233,9 @@ GTEST_DEFINE_bool_(list_tests, false, ...@@ -231,9 +233,9 @@ GTEST_DEFINE_bool_(list_tests, false,
GTEST_DEFINE_string_( GTEST_DEFINE_string_(
output, output,
internal::StringFromGTestEnv("output", ""), internal::StringFromGTestEnv("output", ""),
"A format (currently must be \"xml\"), optionally followed " "A format (defaults to \"xml\" but can be specified to be \"json\"), "
"by a colon and an output file name or directory. A directory " "optionally followed by a colon and an output file name or directory. "
"is indicated by a trailing pathname separator. " "A directory is indicated by a trailing pathname separator. "
"Examples: \"xml:filename.xml\", \"xml::directoryname/\". " "Examples: \"xml:filename.xml\", \"xml::directoryname/\". "
"If a directory is specified, output files will be created " "If a directory is specified, output files will be created "
"within that directory, with file-names based on the test " "within that directory, with file-names based on the test "
...@@ -246,6 +248,12 @@ GTEST_DEFINE_bool_( ...@@ -246,6 +248,12 @@ GTEST_DEFINE_bool_(
"True iff " GTEST_NAME_ "True iff " GTEST_NAME_
" should display elapsed time in text output."); " should display elapsed time in text output.");
GTEST_DEFINE_bool_(
print_utf8,
internal::BoolFromGTestEnv("print_utf8", true),
"True iff " GTEST_NAME_
" prints UTF8 characters as text.");
GTEST_DEFINE_int32_( GTEST_DEFINE_int32_(
random_seed, random_seed,
internal::Int32FromGTestEnv("random_seed", 0), internal::Int32FromGTestEnv("random_seed", 0),
...@@ -287,7 +295,7 @@ GTEST_DEFINE_bool_( ...@@ -287,7 +295,7 @@ GTEST_DEFINE_bool_(
internal::BoolFromGTestEnv("throw_on_failure", false), internal::BoolFromGTestEnv("throw_on_failure", false),
"When this flag is specified, a failed assertion will throw an exception " "When this flag is specified, a failed assertion will throw an exception "
"if exceptions are enabled or exit the program with a non-zero code " "if exceptions are enabled or exit the program with a non-zero code "
"otherwise."); "otherwise. For use with an external test framework.");
#if GTEST_USE_OWN_FLAGFILE_FLAG_ #if GTEST_USE_OWN_FLAGFILE_FLAG_
GTEST_DEFINE_string_( GTEST_DEFINE_string_(
...@@ -378,12 +386,15 @@ void AssertHelper::operator=(const Message& message) const { ...@@ -378,12 +386,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_)
} }
...@@ -422,12 +433,17 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() { ...@@ -422,12 +433,17 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
if (gtest_output_flag == NULL) if (gtest_output_flag == NULL)
return ""; return "";
std::string format = GetOutputFormat();
if (format.empty())
format = std::string(kDefaultOutputFormat);
const char* const colon = strchr(gtest_output_flag, ':'); const char* const colon = strchr(gtest_output_flag, ':');
if (colon == NULL) if (colon == NULL)
return internal::FilePath::ConcatPaths( return internal::FilePath::MakeFileName(
internal::FilePath( internal::FilePath(
UnitTest::GetInstance()->original_working_dir()), UnitTest::GetInstance()->original_working_dir()),
internal::FilePath(kDefaultOutputFile)).string(); internal::FilePath(kDefaultOutputFile), 0,
format.c_str()).string();
internal::FilePath output_name(colon + 1); internal::FilePath output_name(colon + 1);
if (!output_name.IsAbsolutePath()) if (!output_name.IsAbsolutePath())
...@@ -1712,7 +1728,7 @@ AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT ...@@ -1712,7 +1728,7 @@ AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT
// Utility functions for encoding Unicode text (wide strings) in // Utility functions for encoding Unicode text (wide strings) in
// UTF-8. // UTF-8.
// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 // A Unicode code-point can have up to 21 bits, and is encoded in UTF-8
// like this: // like this:
// //
// Code-point length Encoding // Code-point length Encoding
...@@ -2429,6 +2445,8 @@ Result HandleExceptionsInMethodIfSupported( ...@@ -2429,6 +2445,8 @@ Result HandleExceptionsInMethodIfSupported(
#if GTEST_HAS_EXCEPTIONS #if GTEST_HAS_EXCEPTIONS
try { try {
return HandleSehExceptionsInMethodIfSupported(object, method, location); return HandleSehExceptionsInMethodIfSupported(object, method, location);
} catch (const AssertionException&) { // NOLINT
// This failure was reported already.
} catch (const internal::GoogleTestFailureException&) { // NOLINT } catch (const internal::GoogleTestFailureException&) { // NOLINT
// This exception type can only be thrown by a failed Google // This exception type can only be thrown by a failed Google
// Test assertion with the intention of letting another testing // Test assertion with the intention of letting another testing
...@@ -2563,12 +2581,10 @@ void ReportInvalidTestCaseType(const char* test_case_name, ...@@ -2563,12 +2581,10 @@ void ReportInvalidTestCaseType(const char* test_case_name,
<< "probably rename one of the classes to put the tests into different\n" << "probably rename one of the classes to put the tests into different\n"
<< "test cases."; << "test cases.";
GTEST_LOG_(ERROR) GTEST_LOG_(ERROR) << FormatFileLocation(code_location.file.c_str(),
<< FormatFileLocation(code_location.file.c_str(), code_location.line)
code_location.line) << " " << errors.GetString();
<< " " << errors.GetString();
} }
} // namespace internal } // namespace internal
namespace { namespace {
...@@ -2890,7 +2906,7 @@ static int GetBitOffset(WORD color_mask) { ...@@ -2890,7 +2906,7 @@ static int GetBitOffset(WORD color_mask) {
if (color_mask == 0) return 0; if (color_mask == 0) return 0;
int bitOffset = 0; int bitOffset = 0;
while((color_mask & 1) == 0) { while ((color_mask & 1) == 0) {
color_mask >>= 1; color_mask >>= 1;
++bitOffset; ++bitOffset;
} }
...@@ -2899,16 +2915,20 @@ static int GetBitOffset(WORD color_mask) { ...@@ -2899,16 +2915,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;
} }
...@@ -2969,7 +2989,6 @@ bool ShouldUseColor(bool stdout_is_tty) { ...@@ -2969,7 +2989,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);
...@@ -3019,7 +3038,7 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) { ...@@ -3019,7 +3038,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()";
...@@ -3098,7 +3117,6 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart( ...@@ -3098,7 +3117,6 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart(
"Note: Randomizing tests' orders with a seed of %d .\n", "Note: Randomizing tests' orders with a seed of %d .\n",
unit_test.random_seed()); unit_test.random_seed());
} }
ColoredPrintf(COLOR_GREEN, "[==========] "); ColoredPrintf(COLOR_GREEN, "[==========] ");
printf("Running %s from %s.\n", printf("Running %s from %s.\n",
FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestCount(unit_test.test_to_run_count()).c_str(),
...@@ -3430,6 +3448,11 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener { ...@@ -3430,6 +3448,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_;
...@@ -3465,8 +3488,8 @@ void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, ...@@ -3465,8 +3488,8 @@ void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
// 3. To interpret the meaning of errno in a thread-safe way, // 3. To interpret the meaning of errno in a thread-safe way,
// we need the strerror_r() function, which is not available on // we need the strerror_r() function, which is not available on
// Windows. // Windows.
GTEST_LOG_(FATAL) << "Unable to open file \""
<< output_file_ << "\""; GTEST_LOG_(FATAL) << "Unable to open file \"" << output_file_ << "\"";
} }
std::stringstream stream; std::stringstream stream;
PrintXmlUnitTest(&stream, unit_test); PrintXmlUnitTest(&stream, unit_test);
...@@ -3641,6 +3664,10 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, ...@@ -3641,6 +3664,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());
...@@ -3657,7 +3684,6 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, ...@@ -3657,7 +3684,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) {
...@@ -3679,10 +3705,15 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, ...@@ -3679,10 +3705,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
...@@ -3737,7 +3768,6 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, ...@@ -3737,7 +3768,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");
...@@ -3763,8 +3793,374 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( ...@@ -3763,8 +3793,374 @@ 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
// This class generates an JSON output file.
class JsonUnitTestResultPrinter : public EmptyTestEventListener {
public:
explicit JsonUnitTestResultPrinter(const char* output_file);
virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
private:
// Returns an JSON-escaped copy of the input string str.
static std::string EscapeJson(const std::string& str);
//// Verifies that the given attribute belongs to the given element and
//// streams the attribute as JSON.
static void OutputJsonKey(std::ostream* stream,
const std::string& element_name,
const std::string& name,
const std::string& value,
const std::string& indent,
bool comma = true);
static void OutputJsonKey(std::ostream* stream,
const std::string& element_name,
const std::string& name,
int value,
const std::string& indent,
bool comma = true);
// Streams a JSON representation of a TestInfo object.
static void OutputJsonTestInfo(::std::ostream* stream,
const char* test_case_name,
const TestInfo& test_info);
// Prints a JSON representation of a TestCase object
static void PrintJsonTestCase(::std::ostream* stream,
const TestCase& test_case);
// Prints a JSON summary of unit_test to output stream out.
static void PrintJsonUnitTest(::std::ostream* stream,
const UnitTest& unit_test);
// Produces a string representing the test properties in a result as
// a JSON dictionary.
static std::string TestPropertiesAsJson(const TestResult& result,
const std::string& indent);
// The output file.
const std::string output_file_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(JsonUnitTestResultPrinter);
};
// Creates a new JsonUnitTestResultPrinter.
JsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file)
: output_file_(output_file) {
if (output_file_.empty()) {
GTEST_LOG_(FATAL) << "JSON output file may not be null";
}
}
void JsonUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
int /*iteration*/) {
FILE* jsonout = NULL;
FilePath output_file(output_file_);
FilePath output_dir(output_file.RemoveFileName());
if (output_dir.CreateDirectoriesRecursively()) {
jsonout = posix::FOpen(output_file_.c_str(), "w");
}
if (jsonout == NULL) {
// TODO(phosek): report the reason of the failure.
//
// We don't do it for now as:
//
// 1. There is no urgent need for it.
// 2. It's a bit involved to make the errno variable thread-safe on
// all three operating systems (Linux, Windows, and Mac OS).
// 3. To interpret the meaning of errno in a thread-safe way,
// we need the strerror_r() function, which is not available on
// Windows.
GTEST_LOG_(FATAL) << "Unable to open file \""
<< output_file_ << "\"";
}
std::stringstream stream;
PrintJsonUnitTest(&stream, unit_test);
fprintf(jsonout, "%s", StringStreamToString(&stream).c_str());
fclose(jsonout);
}
// Returns an JSON-escaped copy of the input string str.
std::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) {
Message m;
for (size_t i = 0; i < str.size(); ++i) {
const char ch = str[i];
switch (ch) {
case '\\':
case '"':
case '/':
m << '\\' << ch;
break;
case '\b':
m << "\\b";
break;
case '\t':
m << "\\t";
break;
case '\n':
m << "\\n";
break;
case '\f':
m << "\\f";
break;
case '\r':
m << "\\r";
break;
default:
if (ch < ' ') {
m << "\\u00" << String::FormatByte(static_cast<unsigned char>(ch));
} else {
m << ch;
}
break;
}
}
return m.GetString();
}
// The following routines generate an JSON representation of a UnitTest
// object.
// Formats the given time in milliseconds as seconds.
static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) {
::std::stringstream ss;
ss << (static_cast<double>(ms) * 1e-3) << "s";
return ss.str();
}
// Converts the given epoch time in milliseconds to a date string in the
// RFC3339 format, without the timezone information.
static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) {
struct tm time_struct;
if (!PortableLocaltime(static_cast<time_t>(ms / 1000), &time_struct))
return "";
// YYYY-MM-DDThh:mm:ss
return StreamableToString(time_struct.tm_year + 1900) + "-" +
String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" +
String::FormatIntWidth2(time_struct.tm_mday) + "T" +
String::FormatIntWidth2(time_struct.tm_hour) + ":" +
String::FormatIntWidth2(time_struct.tm_min) + ":" +
String::FormatIntWidth2(time_struct.tm_sec) + "Z";
}
static inline std::string Indent(int width) {
return std::string(width, ' ');
}
void JsonUnitTestResultPrinter::OutputJsonKey(
std::ostream* stream,
const std::string& element_name,
const std::string& name,
const std::string& value,
const std::string& indent,
bool comma) {
const std::vector<std::string>& allowed_names =
GetReservedAttributesForElement(element_name);
GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=
allowed_names.end())
<< "Key \"" << name << "\" is not allowed for value \"" << element_name
<< "\".";
*stream << indent << "\"" << name << "\": \"" << EscapeJson(value) << "\"";
if (comma)
*stream << ",\n";
}
void JsonUnitTestResultPrinter::OutputJsonKey(
std::ostream* stream,
const std::string& element_name,
const std::string& name,
int value,
const std::string& indent,
bool comma) {
const std::vector<std::string>& allowed_names =
GetReservedAttributesForElement(element_name);
GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=
allowed_names.end())
<< "Key \"" << name << "\" is not allowed for value \"" << element_name
<< "\".";
*stream << indent << "\"" << name << "\": " << StreamableToString(value);
if (comma)
*stream << ",\n";
}
// Prints a JSON representation of a TestInfo object.
void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream,
const char* test_case_name,
const TestInfo& test_info) {
const TestResult& result = *test_info.result();
const std::string kTestcase = "testcase";
const std::string kIndent = Indent(10);
*stream << Indent(8) << "{\n";
OutputJsonKey(stream, kTestcase, "name", test_info.name(), kIndent);
if (test_info.value_param() != NULL) {
OutputJsonKey(stream, kTestcase, "value_param",
test_info.value_param(), kIndent);
}
if (test_info.type_param() != NULL) {
OutputJsonKey(stream, kTestcase, "type_param", test_info.type_param(),
kIndent);
}
OutputJsonKey(stream, kTestcase, "status",
test_info.should_run() ? "RUN" : "NOTRUN", kIndent);
OutputJsonKey(stream, kTestcase, "time",
FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent);
OutputJsonKey(stream, kTestcase, "classname", test_case_name, kIndent, false);
*stream << TestPropertiesAsJson(result, kIndent);
int failures = 0;
for (int i = 0; i < result.total_part_count(); ++i) {
const TestPartResult& part = result.GetTestPartResult(i);
if (part.failed()) {
*stream << ",\n";
if (++failures == 1) {
*stream << kIndent << "\"" << "failures" << "\": [\n";
}
const std::string location =
internal::FormatCompilerIndependentFileLocation(part.file_name(),
part.line_number());
const std::string message = EscapeJson(location + "\n" + part.message());
*stream << kIndent << " {\n"
<< kIndent << " \"failure\": \"" << message << "\",\n"
<< kIndent << " \"type\": \"\"\n"
<< kIndent << " }";
}
}
if (failures > 0)
*stream << "\n" << kIndent << "]";
*stream << "\n" << Indent(8) << "}";
}
// Prints an JSON representation of a TestCase object
void JsonUnitTestResultPrinter::PrintJsonTestCase(std::ostream* stream,
const TestCase& test_case) {
const std::string kTestsuite = "testsuite";
const std::string kIndent = Indent(6);
*stream << Indent(4) << "{\n";
OutputJsonKey(stream, kTestsuite, "name", test_case.name(), kIndent);
OutputJsonKey(stream, kTestsuite, "tests", test_case.reportable_test_count(),
kIndent);
OutputJsonKey(stream, kTestsuite, "failures", test_case.failed_test_count(),
kIndent);
OutputJsonKey(stream, kTestsuite, "disabled",
test_case.reportable_disabled_test_count(), kIndent);
OutputJsonKey(stream, kTestsuite, "errors", 0, kIndent);
OutputJsonKey(stream, kTestsuite, "time",
FormatTimeInMillisAsDuration(test_case.elapsed_time()), kIndent,
false);
*stream << TestPropertiesAsJson(test_case.ad_hoc_test_result(), kIndent)
<< ",\n";
*stream << kIndent << "\"" << kTestsuite << "\": [\n";
bool comma = false;
for (int i = 0; i < test_case.total_test_count(); ++i) {
if (test_case.GetTestInfo(i)->is_reportable()) {
if (comma) {
*stream << ",\n";
} else {
comma = true;
}
OutputJsonTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i));
}
}
*stream << "\n" << kIndent << "]\n" << Indent(4) << "}";
}
// Prints a JSON summary of unit_test to output stream out.
void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,
const UnitTest& unit_test) {
const std::string kTestsuites = "testsuites";
const std::string kIndent = Indent(2);
*stream << "{\n";
OutputJsonKey(stream, kTestsuites, "tests", unit_test.reportable_test_count(),
kIndent);
OutputJsonKey(stream, kTestsuites, "failures", unit_test.failed_test_count(),
kIndent);
OutputJsonKey(stream, kTestsuites, "disabled",
unit_test.reportable_disabled_test_count(), kIndent);
OutputJsonKey(stream, kTestsuites, "errors", 0, kIndent);
if (GTEST_FLAG(shuffle)) {
OutputJsonKey(stream, kTestsuites, "random_seed", unit_test.random_seed(),
kIndent);
}
OutputJsonKey(stream, kTestsuites, "timestamp",
FormatEpochTimeInMillisAsRFC3339(unit_test.start_timestamp()),
kIndent);
OutputJsonKey(stream, kTestsuites, "time",
FormatTimeInMillisAsDuration(unit_test.elapsed_time()), kIndent,
false);
*stream << TestPropertiesAsJson(unit_test.ad_hoc_test_result(), kIndent)
<< ",\n";
OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent);
*stream << kIndent << "\"" << kTestsuites << "\": [\n";
bool comma = false;
for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
if (unit_test.GetTestCase(i)->reportable_test_count() > 0) {
if (comma) {
*stream << ",\n";
} else {
comma = true;
}
PrintJsonTestCase(stream, *unit_test.GetTestCase(i));
}
}
*stream << "\n" << kIndent << "]\n" << "}\n";
}
// Produces a string representing the test properties in a result as
// a JSON dictionary.
std::string JsonUnitTestResultPrinter::TestPropertiesAsJson(
const TestResult& result, const std::string& indent) {
Message attributes;
for (int i = 0; i < result.test_property_count(); ++i) {
const TestProperty& property = result.GetTestProperty(i);
attributes << ",\n" << indent << "\"" << property.key() << "\": "
<< "\"" << EscapeJson(property.value()) << "\"";
}
return attributes.GetString();
}
// End JsonUnitTestResultPrinter
#if GTEST_CAN_STREAM_RESULTS_ #if GTEST_CAN_STREAM_RESULTS_
// Checks if str contains '=', '&', '%' or '\n' characters. If yes, // Checks if str contains '=', '&', '%' or '\n' characters. If yes,
...@@ -3852,9 +4248,10 @@ void OsStackTraceGetter::UponLeavingGTest() {} ...@@ -3852,9 +4248,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.
...@@ -3865,13 +4262,18 @@ class ScopedPrematureExitFile { ...@@ -3865,13 +4262,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);
}; };
...@@ -4391,10 +4793,12 @@ void UnitTestImpl::ConfigureXmlOutput() { ...@@ -4391,10 +4793,12 @@ void UnitTestImpl::ConfigureXmlOutput() {
if (output_format == "xml") { if (output_format == "xml") {
listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
} else if (output_format == "json") {
listeners()->SetDefaultXmlGenerator(new JsonUnitTestResultPrinter(
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
} else if (output_format != "") { } else if (output_format != "") {
GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \"" GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \""
<< output_format << output_format << "\" ignored.";
<< "\" ignored.";
} }
} }
...@@ -4409,8 +4813,7 @@ void UnitTestImpl::ConfigureStreamingOutput() { ...@@ -4409,8 +4813,7 @@ void UnitTestImpl::ConfigureStreamingOutput() {
listeners()->Append(new StreamingListener(target.substr(0, pos), listeners()->Append(new StreamingListener(target.substr(0, pos),
target.substr(pos+1))); target.substr(pos+1)));
} else { } else {
GTEST_LOG_(WARNING) << "unrecognized streaming target \"" GTEST_LOG_(WARNING) << "unrecognized streaming target \"" << target
<< target
<< "\" ignored."; << "\" ignored.";
} }
} }
...@@ -4538,13 +4941,8 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); } ...@@ -4538,13 +4941,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)
...@@ -4672,6 +5070,20 @@ bool UnitTestImpl::RunAllTests() { ...@@ -4672,6 +5070,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;
} }
...@@ -4718,7 +5130,7 @@ bool ShouldShard(const char* total_shards_env, ...@@ -4718,7 +5130,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) {
...@@ -4726,7 +5138,7 @@ bool ShouldShard(const char* total_shards_env, ...@@ -4726,7 +5138,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) {
...@@ -4735,7 +5147,7 @@ bool ShouldShard(const char* total_shards_env, ...@@ -4735,7 +5147,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);
} }
...@@ -5002,8 +5414,7 @@ bool SkipPrefix(const char* prefix, const char** pstr) { ...@@ -5002,8 +5414,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;
...@@ -5074,9 +5485,8 @@ bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { ...@@ -5074,9 +5485,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);
...@@ -5176,26 +5586,27 @@ static const char kColorEncodedHelpMessage[] = ...@@ -5176,26 +5586,27 @@ 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=xml@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 an XML report in the given directory or with the given file\n" " Generate a JSON or XML report in the given directory or with the given\n"
" name. @YFILE_PATH@D defaults to @Gtest_detail.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"
" Turn assertion failures into C++ exceptions.\n" " Turn assertion failures into C++ exceptions for use by an external\n"
" test framework.\n"
" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" " @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n"
" Do not report exceptions as test failures. Instead, allow them\n" " Do not report exceptions as test failures. Instead, allow them\n"
" to crash the program or throw a pop-up (on Windows).\n" " to crash the program or throw a pop-up (on Windows).\n"
...@@ -5230,6 +5641,7 @@ static bool ParseGoogleTestFlag(const char* const arg) { ...@@ -5230,6 +5641,7 @@ static bool ParseGoogleTestFlag(const char* const arg) {
ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) || ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) ||
ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) || ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) ||
ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) || ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) ||
ParseBoolFlag(arg, kPrintUTF8Flag, &GTEST_FLAG(print_utf8)) ||
ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) || ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) ||
ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) || ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||
ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) || ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||
...@@ -5245,8 +5657,7 @@ static bool ParseGoogleTestFlag(const char* const arg) { ...@@ -5245,8 +5657,7 @@ static bool ParseGoogleTestFlag(const char* const arg) {
static void LoadFlagsFromFile(const std::string& path) { static void LoadFlagsFromFile(const std::string& path) {
FILE* flagfile = posix::FOpen(path.c_str(), "r"); FILE* flagfile = posix::FOpen(path.c_str(), "r");
if (!flagfile) { if (!flagfile) {
GTEST_LOG_(FATAL) << "Unable to open file \"" GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG(flagfile)
<< GTEST_FLAG(flagfile)
<< "\""; << "\"";
} }
std::string contents(ReadEntireFile(flagfile)); std::string contents(ReadEntireFile(flagfile));
...@@ -5377,8 +5788,9 @@ void InitGoogleTest(int* argc, wchar_t** argv) { ...@@ -5377,8 +5788,9 @@ void InitGoogleTest(int* argc, wchar_t** argv) {
std::string TempDir() { std::string TempDir() {
#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) #if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
return GTEST_CUSTOM_TEMPDIR_FUNCTION_(); return GTEST_CUSTOM_TEMPDIR_FUNCTION_();
#endif #endif
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
return "\\temp\\"; return "\\temp\\";
#elif GTEST_OS_WINDOWS #elif GTEST_OS_WINDOWS
......
...@@ -119,6 +119,16 @@ cc_test( ...@@ -119,6 +119,16 @@ cc_test(
"//:gtest", "//:gtest",
], ],
) )
cc_test(
name = "gtest_unittest",
size = "small",
srcs = ["gtest_unittest.cc"],
args = ["--heap_check=strict"],
shard_count = 2,
deps = ["//:gtest_main"],
)
# Py tests # Py tests
py_library( py_library(
...@@ -219,6 +229,13 @@ py_test( ...@@ -219,6 +229,13 @@ py_test(
deps = [":gtest_test_utils"], deps = [":gtest_test_utils"],
) )
cc_test(
name = "gtest_assert_by_exception_test",
size = "small",
srcs = ["gtest_assert_by_exception_test.cc"],
deps = ["//:gtest"],
)
cc_binary( cc_binary(
name = "gtest_throw_on_failure_test_", name = "gtest_throw_on_failure_test_",
testonly = 1, testonly = 1,
......
...@@ -617,7 +617,11 @@ TEST_F(TestForDeathTest, ReturnIsFailure) { ...@@ -617,7 +617,11 @@ TEST_F(TestForDeathTest, ReturnIsFailure) {
TEST_F(TestForDeathTest, TestExpectDebugDeath) { TEST_F(TestForDeathTest, TestExpectDebugDeath) {
int sideeffect = 0; int sideeffect = 0;
EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") // Put the regex in a local variable to make sure we don't get an "unused"
// warning in opt mode.
const char* regex = "death.*DieInDebugElse12";
EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), regex)
<< "Must accept a streamed message"; << "Must accept a streamed message";
# ifdef NDEBUG # ifdef NDEBUG
......
...@@ -41,8 +41,8 @@ ...@@ -41,8 +41,8 @@
# include <sstream> # include <sstream>
# include <string> # include <string>
# include <vector> # include <vector>
# include "src/gtest-internal-inl.h" // for UnitTestOptions
# include "src/gtest-internal-inl.h" // for UnitTestOptions
# include "test/gtest-param-test_test.h" # include "test/gtest-param-test_test.h"
using ::std::vector; using ::std::vector;
...@@ -536,6 +536,51 @@ TEST(CombineTest, CombineWithMaxNumberOfParameters) { ...@@ -536,6 +536,51 @@ TEST(CombineTest, CombineWithMaxNumberOfParameters) {
VerifyGenerator(gen, expected_values); VerifyGenerator(gen, expected_values);
} }
#if GTEST_LANG_CXX11
class NonDefaultConstructAssignString {
public:
NonDefaultConstructAssignString(const std::string& s) : str_(s) {}
const std::string& str() const { return str_; }
private:
std::string str_;
// Not default constructible
NonDefaultConstructAssignString();
// Not assignable
void operator=(const NonDefaultConstructAssignString&);
};
TEST(CombineTest, NonDefaultConstructAssign) {
const ParamGenerator<tuple<int, NonDefaultConstructAssignString> > gen =
Combine(Values(0, 1), Values(NonDefaultConstructAssignString("A"),
NonDefaultConstructAssignString("B")));
ParamGenerator<tuple<int, NonDefaultConstructAssignString> >::iterator it =
gen.begin();
EXPECT_EQ(0, std::get<0>(*it));
EXPECT_EQ("A", std::get<1>(*it).str());
++it;
EXPECT_EQ(0, std::get<0>(*it));
EXPECT_EQ("B", std::get<1>(*it).str());
++it;
EXPECT_EQ(1, std::get<0>(*it));
EXPECT_EQ("A", std::get<1>(*it).str());
++it;
EXPECT_EQ(1, std::get<0>(*it));
EXPECT_EQ("B", std::get<1>(*it).str());
++it;
EXPECT_TRUE(it == gen.end());
}
#endif // GTEST_LANG_CXX11
# endif // GTEST_HAS_COMBINE # endif // GTEST_HAS_COMBINE
// Tests that an generator produces correct sequence after being // Tests that an generator produces correct sequence after being
...@@ -839,8 +884,8 @@ class CustomFunctorNamingTest : public TestWithParam<std::string> {}; ...@@ -839,8 +884,8 @@ class CustomFunctorNamingTest : public TestWithParam<std::string> {};
TEST_P(CustomFunctorNamingTest, CustomTestNames) {} TEST_P(CustomFunctorNamingTest, CustomTestNames) {}
struct CustomParamNameFunctor { struct CustomParamNameFunctor {
std::string operator()(const ::testing::TestParamInfo<std::string>& info) { std::string operator()(const ::testing::TestParamInfo<std::string>& inf) {
return info.param; return inf.param;
} }
}; };
...@@ -857,8 +902,8 @@ INSTANTIATE_TEST_CASE_P(AllAllowedCharacters, ...@@ -857,8 +902,8 @@ INSTANTIATE_TEST_CASE_P(AllAllowedCharacters,
CustomParamNameFunctor()); CustomParamNameFunctor());
inline std::string CustomParamNameFunction( inline std::string CustomParamNameFunction(
const ::testing::TestParamInfo<std::string>& info) { const ::testing::TestParamInfo<std::string>& inf) {
return info.param; return inf.param;
} }
class CustomFunctionNamingTest : public TestWithParam<std::string> {}; class CustomFunctionNamingTest : public TestWithParam<std::string> {};
...@@ -876,11 +921,10 @@ INSTANTIATE_TEST_CASE_P(CustomParamNameFunction, ...@@ -876,11 +921,10 @@ INSTANTIATE_TEST_CASE_P(CustomParamNameFunction,
class CustomLambdaNamingTest : public TestWithParam<std::string> {}; class CustomLambdaNamingTest : public TestWithParam<std::string> {};
TEST_P(CustomLambdaNamingTest, CustomTestNames) {} TEST_P(CustomLambdaNamingTest, CustomTestNames) {}
INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, INSTANTIATE_TEST_CASE_P(CustomParamNameLambda, CustomLambdaNamingTest,
CustomLambdaNamingTest,
Values(std::string("LambdaName")), Values(std::string("LambdaName")),
[](const ::testing::TestParamInfo<std::string>& tpinfo) { [](const ::testing::TestParamInfo<std::string>& inf) {
return tpinfo.param; return inf.param;
}); });
#endif // GTEST_LANG_CXX11 #endif // GTEST_LANG_CXX11
...@@ -1047,6 +1091,7 @@ TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) { ...@@ -1047,6 +1091,7 @@ TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) {
INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5)); INSTANTIATE_TEST_CASE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5));
int main(int argc, char **argv) { int main(int argc, char **argv) {
// Used in TestGenerationTest test case. // Used in TestGenerationTest test case.
AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance()); AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance());
......
...@@ -239,7 +239,7 @@ using ::testing::internal::UniversalTersePrint; ...@@ -239,7 +239,7 @@ 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 #endif
using ::testing::internal::string;
// The hash_* classes are not part of the C++ standard. STLport // 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 namespace std. MSVC defines them in ::stdext. GCC
...@@ -837,22 +837,22 @@ TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { ...@@ -837,22 +837,22 @@ TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) {
EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a));
} }
#if GTEST_HAS_STRING_PIECE_ #if GTEST_HAS_ABSL
// Tests printing StringPiece. // Tests printing ::absl::string_view.
TEST(PrintStringPieceTest, SimpleStringPiece) { TEST(PrintStringViewTest, SimpleStringView) {
const StringPiece sp = "Hello"; const ::absl::string_view sp = "Hello";
EXPECT_EQ("\"Hello\"", Print(sp)); EXPECT_EQ("\"Hello\"", Print(sp));
} }
TEST(PrintStringPieceTest, UnprintableCharacters) { TEST(PrintStringViewTest, UnprintableCharacters) {
const char str[] = "NUL (\0) and \r\t"; const char str[] = "NUL (\0) and \r\t";
const StringPiece sp(str, sizeof(str) - 1); const ::absl::string_view sp(str, sizeof(str) - 1);
EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp)); EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp));
} }
#endif // GTEST_HAS_STRING_PIECE_ #endif // GTEST_HAS_ABSL
// Tests printing STL containers. // Tests printing STL containers.
...@@ -1327,7 +1327,7 @@ TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) { ...@@ -1327,7 +1327,7 @@ TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) {
} }
// Tests formatting a char pointer when it's compared with another pointer. // Tests formatting a char pointer when it's compared with another pointer.
// In this case we want to print it as a raw pointer, as the comparision is by // In this case we want to print it as a raw pointer, as the comparison is by
// pointer. // pointer.
// char pointer vs pointer // char pointer vs pointer
...@@ -1552,6 +1552,78 @@ TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) { ...@@ -1552,6 +1552,78 @@ TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) {
EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\""); EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\"");
} }
TEST(PrintToStringTest, ContainsNonLatin) {
// Sanity test with valid UTF-8. Prints both in hex and as text.
std::string non_ascii_str = ::std::string("오전 4:30");
EXPECT_PRINT_TO_STRING_(non_ascii_str,
"\"\\xEC\\x98\\xA4\\xEC\\xA0\\x84 4:30\"\n"
" As Text: \"오전 4:30\"");
non_ascii_str = ::std::string("From ä — ẑ");
EXPECT_PRINT_TO_STRING_(non_ascii_str,
"\"From \\xC3\\xA4 \\xE2\\x80\\x94 \\xE1\\xBA\\x91\""
"\n As Text: \"From ä — ẑ\"");
}
TEST(IsValidUTF8Test, IllFormedUTF8) {
// The following test strings are ill-formed UTF-8 and are printed
// as hex only (or ASCII, in case of ASCII bytes) because IsValidUTF8() is
// expected to fail, thus output does not contain "As Text:".
static const char *const kTestdata[][2] = {
// 2-byte lead byte followed by a single-byte character.
{"\xC3\x74", "\"\\xC3t\""},
// Valid 2-byte character followed by an orphan trail byte.
{"\xC3\x84\xA4", "\"\\xC3\\x84\\xA4\""},
// Lead byte without trail byte.
{"abc\xC3", "\"abc\\xC3\""},
// 3-byte lead byte, single-byte character, orphan trail byte.
{"x\xE2\x70\x94", "\"x\\xE2p\\x94\""},
// Truncated 3-byte character.
{"\xE2\x80", "\"\\xE2\\x80\""},
// Truncated 3-byte character followed by valid 2-byte char.
{"\xE2\x80\xC3\x84", "\"\\xE2\\x80\\xC3\\x84\""},
// Truncated 3-byte character followed by a single-byte character.
{"\xE2\x80\x7A", "\"\\xE2\\x80z\""},
// 3-byte lead byte followed by valid 3-byte character.
{"\xE2\xE2\x80\x94", "\"\\xE2\\xE2\\x80\\x94\""},
// 4-byte lead byte followed by valid 3-byte character.
{"\xF0\xE2\x80\x94", "\"\\xF0\\xE2\\x80\\x94\""},
// Truncated 4-byte character.
{"\xF0\xE2\x80", "\"\\xF0\\xE2\\x80\""},
// Invalid UTF-8 byte sequences embedded in other chars.
{"abc\xE2\x80\x94\xC3\x74xyc", "\"abc\\xE2\\x80\\x94\\xC3txyc\""},
{"abc\xC3\x84\xE2\x80\xC3\x84xyz",
"\"abc\\xC3\\x84\\xE2\\x80\\xC3\\x84xyz\""},
// Non-shortest UTF-8 byte sequences are also ill-formed.
// The classics: xC0, xC1 lead byte.
{"\xC0\x80", "\"\\xC0\\x80\""},
{"\xC1\x81", "\"\\xC1\\x81\""},
// Non-shortest sequences.
{"\xE0\x80\x80", "\"\\xE0\\x80\\x80\""},
{"\xf0\x80\x80\x80", "\"\\xF0\\x80\\x80\\x80\""},
// Last valid code point before surrogate range, should be printed as text,
// too.
{"\xED\x9F\xBF", "\"\\xED\\x9F\\xBF\"\n As Text: \"\""},
// Start of surrogate lead. Surrogates are not printed as text.
{"\xED\xA0\x80", "\"\\xED\\xA0\\x80\""},
// Last non-private surrogate lead.
{"\xED\xAD\xBF", "\"\\xED\\xAD\\xBF\""},
// First private-use surrogate lead.
{"\xED\xAE\x80", "\"\\xED\\xAE\\x80\""},
// Last private-use surrogate lead.
{"\xED\xAF\xBF", "\"\\xED\\xAF\\xBF\""},
// Mid-point of surrogate trail.
{"\xED\xB3\xBF", "\"\\xED\\xB3\\xBF\""},
// First valid code point after surrogate range, should be printed as text,
// too.
{"\xEE\x80\x80", "\"\\xEE\\x80\\x80\"\n As Text: \"\""}
};
for (int i = 0; i < int(sizeof(kTestdata)/sizeof(kTestdata[0])); ++i) {
EXPECT_PRINT_TO_STRING_(kTestdata[i][0], kTestdata[i][1]);
}
}
#undef EXPECT_PRINT_TO_STRING_ #undef EXPECT_PRINT_TO_STRING_
TEST(UniversalTersePrintTest, WorksForNonReference) { TEST(UniversalTersePrintTest, WorksForNonReference) {
...@@ -1693,5 +1765,17 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) { ...@@ -1693,5 +1765,17 @@ TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) {
#endif // GTEST_HAS_STD_TUPLE_ #endif // GTEST_HAS_STD_TUPLE_
#if GTEST_HAS_ABSL
TEST(PrintOptionalTest, Basic) {
absl::optional<int> value;
EXPECT_EQ("(nullopt)", PrintToString(value));
value = {7};
EXPECT_EQ("(7)", PrintToString(value));
EXPECT_EQ("(1.1)", PrintToString(absl::optional<double>{1.1}));
EXPECT_EQ("(\"A\")", PrintToString(absl::optional<std::string>{"A"}));
}
#endif // GTEST_HAS_ABSL
} // namespace gtest_printers_test } // namespace gtest_printers_test
} // namespace testing } // namespace testing
...@@ -33,15 +33,15 @@ ...@@ -33,15 +33,15 @@
// //
// Sometimes it's desirable to build most of Google Test's own tests // Sometimes it's desirable to build most of Google Test's own tests
// by compiling a single file. This file serves this purpose. // by compiling a single file. This file serves this purpose.
#include "test/gtest-filepath_test.cc" #include "gtest-filepath_test.cc"
#include "test/gtest-linked_ptr_test.cc" #include "gtest-linked_ptr_test.cc"
#include "test/gtest-message_test.cc" #include "gtest-message_test.cc"
#include "test/gtest-options_test.cc" #include "gtest-options_test.cc"
#include "test/gtest-port_test.cc" #include "gtest-port_test.cc"
#include "test/gtest_pred_impl_unittest.cc" #include "gtest_pred_impl_unittest.cc"
#include "test/gtest_prod_test.cc" #include "gtest_prod_test.cc"
#include "test/gtest-test-part_test.cc" #include "gtest-test-part_test.cc"
#include "test/gtest-typed-test_test.cc" #include "gtest-typed-test_test.cc"
#include "test/gtest-typed-test2_test.cc" #include "gtest-typed-test2_test.cc"
#include "test/gtest_unittest.cc" #include "gtest_unittest.cc"
#include "test/production.cc" #include "production.cc"
// Copyright 2009, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Tests Google Test's assert-by-exception mode with exceptions enabled.
#include "gtest/gtest.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdexcept>
class ThrowListener : public testing::EmptyTestEventListener {
void OnTestPartResult(const testing::TestPartResult& result) override {
if (result.type() == testing::TestPartResult::kFatalFailure) {
throw testing::AssertionException(result);
}
}
};
// Prints the given failure message and exits the program with
// non-zero. We use this instead of a Google Test assertion to
// indicate a failure, as the latter is been tested and cannot be
// relied on.
void Fail(const char* msg) {
printf("FAILURE: %s\n", msg);
fflush(stdout);
exit(1);
}
static void AssertFalse() {
ASSERT_EQ(2, 3) << "Expected failure";
}
// Tests that an assertion failure throws a subclass of
// std::runtime_error.
TEST(Test, Test) {
// A successful assertion shouldn't throw.
try {
EXPECT_EQ(3, 3);
} catch(...) {
Fail("A successful assertion wrongfully threw.");
}
// A successful assertion shouldn't throw.
try {
EXPECT_EQ(3, 4);
} catch(...) {
Fail("A failed non-fatal assertion wrongfully threw.");
}
// A failed assertion should throw.
try {
AssertFalse();
} catch(const testing::AssertionException& e) {
if (strstr(e.what(), "Expected failure") != NULL)
throw;
printf("%s",
"A failed assertion did throw an exception of the right type, "
"but the message is incorrect. Instead of containing \"Expected "
"failure\", it is:\n");
Fail(e.what());
} catch(...) {
Fail("A failed assertion threw the wrong type of exception.");
}
Fail("A failed assertion should've thrown but didn't.");
}
int kTestForContinuingTest = 0;
TEST(Test, Test2) {
// FIXME(sokolov): how to force Test2 to be after Test?
kTestForContinuingTest = 1;
}
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
testing::UnitTest::GetInstance()->listeners().Append(new ThrowListener);
int result = RUN_ALL_TESTS();
if (result == 0) {
printf("RUN_ALL_TESTS returned %d\n", result);
Fail("Expected failure instead.");
}
if (kTestForContinuingTest == 0) {
Fail("Should have continued with other tests, but did not.");
}
return 0;
}
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include <iostream> #include <iostream>
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
using ::std::cout; using ::std::cout;
......
#!/usr/bin/env python
# Copyright 2018, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Unit test for the gtest_json_output module."""
import json
import os
import gtest_json_test_utils
import gtest_test_utils
GTEST_OUTPUT_SUBDIR = 'json_outfiles'
GTEST_OUTPUT_1_TEST = 'gtest_xml_outfile1_test_'
GTEST_OUTPUT_2_TEST = 'gtest_xml_outfile2_test_'
EXPECTED_1 = {
u'tests': 1,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'timestamp': u'*',
u'name': u'AllTests',
u'testsuites': [{
u'name': u'PropertyOne',
u'tests': 1,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'testsuite': [{
u'name': u'TestSomeProperties',
u'status': u'RUN',
u'time': u'*',
u'classname': u'PropertyOne',
u'SetUpProp': u'1',
u'TestSomeProperty': u'1',
u'TearDownProp': u'1',
}],
}],
}
EXPECTED_2 = {
u'tests': 1,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'timestamp': u'*',
u'name': u'AllTests',
u'testsuites': [{
u'name': u'PropertyTwo',
u'tests': 1,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'testsuite': [{
u'name': u'TestSomeProperties',
u'status': u'RUN',
u'time': u'*',
u'classname': u'PropertyTwo',
u'SetUpProp': u'2',
u'TestSomeProperty': u'2',
u'TearDownProp': u'2',
}],
}],
}
class GTestJsonOutFilesTest(gtest_test_utils.TestCase):
"""Unit test for Google Test's JSON output functionality."""
def setUp(self):
# We want the trailing '/' that the last "" provides in os.path.join, for
# telling Google Test to create an output directory instead of a single file
# for xml output.
self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(),
GTEST_OUTPUT_SUBDIR, '')
self.DeleteFilesAndDir()
def tearDown(self):
self.DeleteFilesAndDir()
def DeleteFilesAndDir(self):
try:
os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_1_TEST + '.json'))
except os.error:
pass
try:
os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_2_TEST + '.json'))
except os.error:
pass
try:
os.rmdir(self.output_dir_)
except os.error:
pass
def testOutfile1(self):
self._TestOutFile(GTEST_OUTPUT_1_TEST, EXPECTED_1)
def testOutfile2(self):
self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_2)
def _TestOutFile(self, test_name, expected):
gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name)
command = [gtest_prog_path, '--gtest_output=json:%s' % self.output_dir_]
p = gtest_test_utils.Subprocess(command,
working_dir=gtest_test_utils.GetTempDir())
self.assert_(p.exited)
self.assertEquals(0, p.exit_code)
# TODO(wan@google.com): libtool causes the built test binary to be
# named lt-gtest_xml_outfiles_test_ instead of
# gtest_xml_outfiles_test_. To account for this possibility, we
# allow both names in the following code. We should remove this
# hack when Chandler Carruth's libtool replacement tool is ready.
output_file_name1 = test_name + '.json'
output_file1 = os.path.join(self.output_dir_, output_file_name1)
output_file_name2 = 'lt-' + output_file_name1
output_file2 = os.path.join(self.output_dir_, output_file_name2)
self.assert_(os.path.isfile(output_file1) or os.path.isfile(output_file2),
output_file1)
if os.path.isfile(output_file1):
with open(output_file1) as f:
actual = json.load(f)
else:
with open(output_file2) as f:
actual = json.load(f)
self.assertEqual(expected, gtest_json_test_utils.normalize(actual))
if __name__ == '__main__':
os.environ['GTEST_STACK_TRACE_DEPTH'] = '0'
gtest_test_utils.Main()
#!/usr/bin/env python
# Copyright 2018, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Unit test for the gtest_json_output module."""
import datetime
import errno
import json
import os
import re
import sys
import gtest_json_test_utils
import gtest_test_utils
GTEST_FILTER_FLAG = '--gtest_filter'
GTEST_LIST_TESTS_FLAG = '--gtest_list_tests'
GTEST_OUTPUT_FLAG = '--gtest_output'
GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.json'
GTEST_PROGRAM_NAME = 'gtest_xml_output_unittest_'
SUPPORTS_STACK_TRACES = False
if SUPPORTS_STACK_TRACES:
STACK_TRACE_TEMPLATE = '\nStack trace:\n*'
else:
STACK_TRACE_TEMPLATE = ''
EXPECTED_NON_EMPTY = {
u'tests': 23,
u'failures': 4,
u'disabled': 2,
u'errors': 0,
u'timestamp': u'*',
u'time': u'*',
u'ad_hoc_property': u'42',
u'name': u'AllTests',
u'testsuites': [
{
u'name': u'SuccessfulTest',
u'tests': 1,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'testsuite': [
{
u'name': u'Succeeds',
u'status': u'RUN',
u'time': u'*',
u'classname': u'SuccessfulTest'
}
]
},
{
u'name': u'FailedTest',
u'tests': 1,
u'failures': 1,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'testsuite': [
{
u'name': u'Fails',
u'status': u'RUN',
u'time': u'*',
u'classname': u'FailedTest',
u'failures': [
{
u'failure':
u'gtest_xml_output_unittest_.cc:*\n'
u'Expected equality of these values:\n'
u' 1\n 2' + STACK_TRACE_TEMPLATE,
u'type': u''
}
]
}
]
},
{
u'name': u'DisabledTest',
u'tests': 1,
u'failures': 0,
u'disabled': 1,
u'errors': 0,
u'time': u'*',
u'testsuite': [
{
u'name': u'DISABLED_test_not_run',
u'status': u'NOTRUN',
u'time': u'*',
u'classname': u'DisabledTest'
}
]
},
{
u'name': u'MixedResultTest',
u'tests': 3,
u'failures': 1,
u'disabled': 1,
u'errors': 0,
u'time': u'*',
u'testsuite': [
{
u'name': u'Succeeds',
u'status': u'RUN',
u'time': u'*',
u'classname': u'MixedResultTest'
},
{
u'name': u'Fails',
u'status': u'RUN',
u'time': u'*',
u'classname': u'MixedResultTest',
u'failures': [
{
u'failure':
u'gtest_xml_output_unittest_.cc:*\n'
u'Expected equality of these values:\n'
u' 1\n 2' + STACK_TRACE_TEMPLATE,
u'type': u''
},
{
u'failure':
u'gtest_xml_output_unittest_.cc:*\n'
u'Expected equality of these values:\n'
u' 2\n 3' + STACK_TRACE_TEMPLATE,
u'type': u''
}
]
},
{
u'name': u'DISABLED_test',
u'status': u'NOTRUN',
u'time': u'*',
u'classname': u'MixedResultTest'
}
]
},
{
u'name': u'XmlQuotingTest',
u'tests': 1,
u'failures': 1,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'testsuite': [
{
u'name': u'OutputsCData',
u'status': u'RUN',
u'time': u'*',
u'classname': u'XmlQuotingTest',
u'failures': [
{
u'failure':
u'gtest_xml_output_unittest_.cc:*\n'
u'Failed\nXML output: <?xml encoding="utf-8">'
u'<top><![CDATA[cdata text]]></top>' +
STACK_TRACE_TEMPLATE,
u'type': u''
}
]
}
]
},
{
u'name': u'InvalidCharactersTest',
u'tests': 1,
u'failures': 1,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'testsuite': [
{
u'name': u'InvalidCharactersInMessage',
u'status': u'RUN',
u'time': u'*',
u'classname': u'InvalidCharactersTest',
u'failures': [
{
u'failure':
u'gtest_xml_output_unittest_.cc:*\n'
u'Failed\nInvalid characters in brackets'
u' [\x01\x02]' + STACK_TRACE_TEMPLATE,
u'type': u''
}
]
}
]
},
{
u'name': u'PropertyRecordingTest',
u'tests': 4,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'SetUpTestCase': u'yes',
u'TearDownTestCase': u'aye',
u'testsuite': [
{
u'name': u'OneProperty',
u'status': u'RUN',
u'time': u'*',
u'classname': u'PropertyRecordingTest',
u'key_1': u'1'
},
{
u'name': u'IntValuedProperty',
u'status': u'RUN',
u'time': u'*',
u'classname': u'PropertyRecordingTest',
u'key_int': u'1'
},
{
u'name': u'ThreeProperties',
u'status': u'RUN',
u'time': u'*',
u'classname': u'PropertyRecordingTest',
u'key_1': u'1',
u'key_2': u'2',
u'key_3': u'3'
},
{
u'name': u'TwoValuesForOneKeyUsesLastValue',
u'status': u'RUN',
u'time': u'*',
u'classname': u'PropertyRecordingTest',
u'key_1': u'2'
}
]
},
{
u'name': u'NoFixtureTest',
u'tests': 3,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'testsuite': [
{
u'name': u'RecordProperty',
u'status': u'RUN',
u'time': u'*',
u'classname': u'NoFixtureTest',
u'key': u'1'
},
{
u'name': u'ExternalUtilityThatCallsRecordIntValuedProperty',
u'status': u'RUN',
u'time': u'*',
u'classname': u'NoFixtureTest',
u'key_for_utility_int': u'1'
},
{
u'name':
u'ExternalUtilityThatCallsRecordStringValuedProperty',
u'status': u'RUN',
u'time': u'*',
u'classname': u'NoFixtureTest',
u'key_for_utility_string': u'1'
}
]
},
{
u'name': u'TypedTest/0',
u'tests': 1,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'testsuite': [
{
u'name': u'HasTypeParamAttribute',
u'type_param': u'int',
u'status': u'RUN',
u'time': u'*',
u'classname': u'TypedTest/0'
}
]
},
{
u'name': u'TypedTest/1',
u'tests': 1,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'testsuite': [
{
u'name': u'HasTypeParamAttribute',
u'type_param': u'long',
u'status': u'RUN',
u'time': u'*',
u'classname': u'TypedTest/1'
}
]
},
{
u'name': u'Single/TypeParameterizedTestCase/0',
u'tests': 1,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'testsuite': [
{
u'name': u'HasTypeParamAttribute',
u'type_param': u'int',
u'status': u'RUN',
u'time': u'*',
u'classname': u'Single/TypeParameterizedTestCase/0'
}
]
},
{
u'name': u'Single/TypeParameterizedTestCase/1',
u'tests': 1,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'testsuite': [
{
u'name': u'HasTypeParamAttribute',
u'type_param': u'long',
u'status': u'RUN',
u'time': u'*',
u'classname': u'Single/TypeParameterizedTestCase/1'
}
]
},
{
u'name': u'Single/ValueParamTest',
u'tests': 4,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'testsuite': [
{
u'name': u'HasValueParamAttribute/0',
u'value_param': u'33',
u'status': u'RUN',
u'time': u'*',
u'classname': u'Single/ValueParamTest'
},
{
u'name': u'HasValueParamAttribute/1',
u'value_param': u'42',
u'status': u'RUN',
u'time': u'*',
u'classname': u'Single/ValueParamTest'
},
{
u'name': u'AnotherTestThatHasValueParamAttribute/0',
u'value_param': u'33',
u'status': u'RUN',
u'time': u'*',
u'classname': u'Single/ValueParamTest'
},
{
u'name': u'AnotherTestThatHasValueParamAttribute/1',
u'value_param': u'42',
u'status': u'RUN',
u'time': u'*',
u'classname': u'Single/ValueParamTest'
}
]
}
]
}
EXPECTED_FILTERED = {
u'tests': 1,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'timestamp': u'*',
u'name': u'AllTests',
u'ad_hoc_property': u'42',
u'testsuites': [{
u'name': u'SuccessfulTest',
u'tests': 1,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'testsuite': [{
u'name': u'Succeeds',
u'status': u'RUN',
u'time': u'*',
u'classname': u'SuccessfulTest',
}]
}],
}
EXPECTED_EMPTY = {
u'tests': 0,
u'failures': 0,
u'disabled': 0,
u'errors': 0,
u'time': u'*',
u'timestamp': u'*',
u'name': u'AllTests',
u'testsuites': [],
}
GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
SUPPORTS_TYPED_TESTS = 'TypedTest' in gtest_test_utils.Subprocess(
[GTEST_PROGRAM_PATH, GTEST_LIST_TESTS_FLAG], capture_stderr=False).output
class GTestJsonOutputUnitTest(gtest_test_utils.TestCase):
"""Unit test for Google Test's JSON output functionality.
"""
# This test currently breaks on platforms that do not support typed and
# type-parameterized tests, so we don't run it under them.
if SUPPORTS_TYPED_TESTS:
def testNonEmptyJsonOutput(self):
"""Verifies JSON output for a Google Test binary with non-empty output.
Runs a test program that generates a non-empty JSON output, and
tests that the JSON output is expected.
"""
self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY, 1)
def testEmptyJsonOutput(self):
"""Verifies JSON output for a Google Test binary without actual tests.
Runs a test program that generates an empty JSON output, and
tests that the JSON output is expected.
"""
self._TestJsonOutput('gtest_no_test_unittest', EXPECTED_EMPTY, 0)
def testTimestampValue(self):
"""Checks whether the timestamp attribute in the JSON output is valid.
Runs a test program that generates an empty JSON output, and checks if
the timestamp attribute in the testsuites tag is valid.
"""
actual = self._GetJsonOutput('gtest_no_test_unittest', [], 0)
date_time_str = actual['timestamp']
# datetime.strptime() is only available in Python 2.5+ so we have to
# parse the expected datetime manually.
match = re.match(r'(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)', date_time_str)
self.assertTrue(
re.match,
'JSON datettime string %s has incorrect format' % date_time_str)
date_time_from_json = datetime.datetime(
year=int(match.group(1)), month=int(match.group(2)),
day=int(match.group(3)), hour=int(match.group(4)),
minute=int(match.group(5)), second=int(match.group(6)))
time_delta = abs(datetime.datetime.now() - date_time_from_json)
# timestamp value should be near the current local time
self.assertTrue(time_delta < datetime.timedelta(seconds=600),
'time_delta is %s' % time_delta)
def testDefaultOutputFile(self):
"""Verifies the default output file name.
Confirms that Google Test produces an JSON output file with the expected
default name if no name is explicitly specified.
"""
output_file = os.path.join(gtest_test_utils.GetTempDir(),
GTEST_DEFAULT_OUTPUT_FILE)
gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
'gtest_no_test_unittest')
try:
os.remove(output_file)
except OSError:
e = sys.exc_info()[1]
if e.errno != errno.ENOENT:
raise
p = gtest_test_utils.Subprocess(
[gtest_prog_path, '%s=json' % GTEST_OUTPUT_FLAG],
working_dir=gtest_test_utils.GetTempDir())
self.assert_(p.exited)
self.assertEquals(0, p.exit_code)
self.assert_(os.path.isfile(output_file))
def testSuppressedJsonOutput(self):
"""Verifies that no JSON output is generated.
Tests that no JSON file is generated if the default JSON listener is
shut down before RUN_ALL_TESTS is invoked.
"""
json_path = os.path.join(gtest_test_utils.GetTempDir(),
GTEST_PROGRAM_NAME + 'out.json')
if os.path.isfile(json_path):
os.remove(json_path)
command = [GTEST_PROGRAM_PATH,
'%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path),
'--shut_down_xml']
p = gtest_test_utils.Subprocess(command)
if p.terminated_by_signal:
# p.signal is available only if p.terminated_by_signal is True.
self.assertFalse(
p.terminated_by_signal,
'%s was killed by signal %d' % (GTEST_PROGRAM_NAME, p.signal))
else:
self.assert_(p.exited)
self.assertEquals(1, p.exit_code,
"'%s' exited with code %s, which doesn't match "
'the expected exit code %s.'
% (command, p.exit_code, 1))
self.assert_(not os.path.isfile(json_path))
def testFilteredTestJsonOutput(self):
"""Verifies JSON output when a filter is applied.
Runs a test program that executes only some tests and verifies that
non-selected tests do not show up in the JSON output.
"""
self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_FILTERED, 0,
extra_args=['%s=SuccessfulTest.*' % GTEST_FILTER_FLAG])
def _GetJsonOutput(self, gtest_prog_name, extra_args, expected_exit_code):
"""Returns the JSON output generated by running the program gtest_prog_name.
Furthermore, the program's exit code must be expected_exit_code.
Args:
gtest_prog_name: Google Test binary name.
extra_args: extra arguments to binary invocation.
expected_exit_code: program's exit code.
"""
json_path = os.path.join(gtest_test_utils.GetTempDir(),
gtest_prog_name + 'out.json')
gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
command = (
[gtest_prog_path, '%s=json:%s' % (GTEST_OUTPUT_FLAG, json_path)] +
extra_args
)
p = gtest_test_utils.Subprocess(command)
if p.terminated_by_signal:
self.assert_(False,
'%s was killed by signal %d' % (gtest_prog_name, p.signal))
else:
self.assert_(p.exited)
self.assertEquals(expected_exit_code, p.exit_code,
"'%s' exited with code %s, which doesn't match "
'the expected exit code %s.'
% (command, p.exit_code, expected_exit_code))
with open(json_path) as f:
actual = json.load(f)
return actual
def _TestJsonOutput(self, gtest_prog_name, expected,
expected_exit_code, extra_args=None):
"""Checks the JSON output generated by the Google Test binary.
Asserts that the JSON document generated by running the program
gtest_prog_name matches expected_json, a string containing another
JSON document. Furthermore, the program's exit code must be
expected_exit_code.
Args:
gtest_prog_name: Google Test binary name.
expected: expected output.
expected_exit_code: program's exit code.
extra_args: extra arguments to binary invocation.
"""
actual = self._GetJsonOutput(gtest_prog_name, extra_args or [],
expected_exit_code)
self.assertEqual(expected, gtest_json_test_utils.normalize(actual))
if __name__ == '__main__':
os.environ['GTEST_STACK_TRACE_DEPTH'] = '1'
gtest_test_utils.Main()
# Copyright 2018, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Unit test utilities for gtest_json_output."""
import re
def normalize(obj):
"""Normalize output object.
Args:
obj: Google Test's JSON output object to normalize.
Returns:
Normalized output without any references to transient information that may
change from run to run.
"""
def _normalize(key, value):
if key == 'time':
return re.sub(r'^\d+(\.\d+)?s$', '*', value)
elif key == 'timestamp':
return re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ$', '*', value)
elif key == 'failure':
value = re.sub(r'^.*[/\\](.*:)\d+\n', '\\1*\n', value)
return re.sub(r'Stack trace:\n(.|\n)*', 'Stack trace:\n*', value)
else:
return normalize(value)
if isinstance(obj, dict):
return {k: _normalize(k, v) for k, v in obj.items()}
if isinstance(obj, list):
return [normalize(x) for x in obj]
else:
return obj
...@@ -41,5 +41,5 @@ TEST(GTestMainTest, ShouldSucceed) { ...@@ -41,5 +41,5 @@ TEST(GTestMainTest, ShouldSucceed) {
} // namespace } // namespace
// We are using the main() function defined in src/gtest_main.cc, so // We are using the main() function defined in gtest_main.cc, so we
// we don't define it here. // don't define it here.
...@@ -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_')
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
TEST(DummyTest, Dummy) { TEST(DummyTest, Dummy) {
// This test doesn't verify anything. We just need it to create a // This test doesn't verify anything. We just need it to create a
// realistic stage for testing the behavior of Google Test when // realistic stage for testing the behavior of Google Test when
// RUN_ALL_TESTS() is called without // RUN_ALL_TESTS() is called without
// testing::InitGoogleTest() being called first. // testing::InitGoogleTest() being called first.
} }
......
...@@ -538,7 +538,7 @@ TEST(CodePointToUtf8Test, CanEncode8To11Bits) { ...@@ -538,7 +538,7 @@ TEST(CodePointToUtf8Test, CanEncode8To11Bits) {
// 101 0111 0110 => 110-10101 10-110110 // 101 0111 0110 => 110-10101 10-110110
// Some compilers (e.g., GCC on MinGW) cannot handle non-ASCII codepoints // Some compilers (e.g., GCC on MinGW) cannot handle non-ASCII codepoints
// in wide strings and wide chars. In order to accomodate them, we have to // in wide strings and wide chars. In order to accommodate them, we have to
// introduce such character constants as integers. // introduce such character constants as integers.
EXPECT_EQ("\xD5\xB6", EXPECT_EQ("\xD5\xB6",
CodePointToUtf8(static_cast<wchar_t>(0x576))); CodePointToUtf8(static_cast<wchar_t>(0x576)));
...@@ -1779,7 +1779,7 @@ TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) { ...@@ -1779,7 +1779,7 @@ TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) {
} }
// Tests that Int32FromEnvOrDie() aborts with an error message // Tests that Int32FromEnvOrDie() aborts with an error message
// if the variable cannot be represnted by an Int32. // if the variable cannot be represented by an Int32.
TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) { TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) {
SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234"); SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234");
EXPECT_DEATH_IF_SUPPORTED( EXPECT_DEATH_IF_SUPPORTED(
...@@ -2088,7 +2088,7 @@ class UnitTestRecordPropertyTestEnvironment : public Environment { ...@@ -2088,7 +2088,7 @@ class UnitTestRecordPropertyTestEnvironment : public Environment {
}; };
// This will test property recording outside of any test or test case. // This will test property recording outside of any test or test case.
Environment* record_property_env GTEST_ATTRIBUTE_UNUSED_ = static Environment* record_property_env =
AddGlobalTestEnvironment(new UnitTestRecordPropertyTestEnvironment); AddGlobalTestEnvironment(new UnitTestRecordPropertyTestEnvironment);
// This group of tests is for predicate assertions (ASSERT_PRED*, etc) // This group of tests is for predicate assertions (ASSERT_PRED*, etc)
...@@ -2421,9 +2421,8 @@ TEST(StringAssertionTest, ASSERT_STREQ) { ...@@ -2421,9 +2421,8 @@ TEST(StringAssertionTest, ASSERT_STREQ) {
const char p2[] = "good"; const char p2[] = "good";
ASSERT_STREQ(p1, p2); ASSERT_STREQ(p1, p2);
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(ASSERT_STREQ("bad", "good"),
ASSERT_STREQ("bad", "good"), " \"bad\"\n \"good\"");
"Expected equality of these values:\n \"bad\"\n \"good\"");
} }
// Tests ASSERT_STREQ with NULL arguments. // Tests ASSERT_STREQ with NULL arguments.
...@@ -3361,7 +3360,7 @@ class NoFatalFailureTest : public Test { ...@@ -3361,7 +3360,7 @@ class NoFatalFailureTest : public Test {
void DoAssertNoFatalFailureOnFails() { void DoAssertNoFatalFailureOnFails() {
ASSERT_NO_FATAL_FAILURE(Fails()); ASSERT_NO_FATAL_FAILURE(Fails());
ADD_FAILURE() << "shold not reach here."; ADD_FAILURE() << "should not reach here.";
} }
void DoExpectNoFatalFailureOnFails() { void DoExpectNoFatalFailureOnFails() {
...@@ -3658,7 +3657,7 @@ TEST(AssertionTest, AssertFalseWithAssertionResult) { ...@@ -3658,7 +3657,7 @@ TEST(AssertionTest, AssertFalseWithAssertionResult) {
} }
#ifdef __BORLANDC__ #ifdef __BORLANDC__
// Restores warnings after previous "#pragma option push" supressed them // Restores warnings after previous "#pragma option push" suppressed them
# pragma option pop # pragma option pop
#endif #endif
...@@ -3813,7 +3812,7 @@ void TestEq1(int x) { ...@@ -3813,7 +3812,7 @@ void TestEq1(int x) {
// Tests calling a test subroutine that's not part of a fixture. // Tests calling a test subroutine that's not part of a fixture.
TEST(AssertionTest, NonFixtureSubroutine) { TEST(AssertionTest, NonFixtureSubroutine) {
EXPECT_FATAL_FAILURE(TestEq1(2), EXPECT_FATAL_FAILURE(TestEq1(2),
"Which is: 2"); " x\n Which is: 2");
} }
// An uncopyable class. // An uncopyable class.
...@@ -3952,13 +3951,13 @@ TEST(AssertionTest, AnonymousEnum) { ...@@ -3952,13 +3951,13 @@ TEST(AssertionTest, AnonymousEnum) {
// ICE's in C++Builder. // ICE's in C++Builder.
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB), EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB),
"kCaseB"); " kCaseB\n Which is: ");
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC),
"Which is: 42"); "\n Which is: 42");
# endif # endif
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC),
"Which is: -1"); "\n Which is: -1");
} }
#endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC) #endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC)
...@@ -4384,7 +4383,7 @@ TEST(ExpectTest, ExpectFalseWithAssertionResult) { ...@@ -4384,7 +4383,7 @@ TEST(ExpectTest, ExpectFalseWithAssertionResult) {
} }
#ifdef __BORLANDC__ #ifdef __BORLANDC__
// Restores warnings after previous "#pragma option push" supressed them // Restores warnings after previous "#pragma option push" suppressed them
# pragma option pop # pragma option pop
#endif #endif
...@@ -4426,7 +4425,7 @@ TEST(ExpectTest, EXPECT_EQ_NULL) { ...@@ -4426,7 +4425,7 @@ TEST(ExpectTest, EXPECT_EQ_NULL) {
// A failure. // A failure.
int n = 0; int n = 0;
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n), EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n),
"&n\n"); " &n\n Which is:");
} }
#endif // GTEST_CAN_COMPARE_NULL #endif // GTEST_CAN_COMPARE_NULL
...@@ -4442,7 +4441,7 @@ TEST(ExpectTest, EXPECT_EQ_0) { ...@@ -4442,7 +4441,7 @@ TEST(ExpectTest, EXPECT_EQ_0) {
// A failure. // A failure.
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(0, 5.6), EXPECT_NONFATAL_FAILURE(EXPECT_EQ(0, 5.6),
"Expected equality of these values:\n 0\n 5.6"); " 0\n 5.6");
} }
// Tests EXPECT_NE. // Tests EXPECT_NE.
...@@ -4542,7 +4541,7 @@ TEST(ExpectTest, EXPECT_ANY_THROW) { ...@@ -4542,7 +4541,7 @@ TEST(ExpectTest, EXPECT_ANY_THROW) {
TEST(ExpectTest, ExpectPrecedence) { TEST(ExpectTest, ExpectPrecedence) {
EXPECT_EQ(1 < 2, true); EXPECT_EQ(1 < 2, true);
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(true, true && false), EXPECT_NONFATAL_FAILURE(EXPECT_EQ(true, true && false),
"true && false"); " true && false\n Which is: false");
} }
...@@ -4689,14 +4688,14 @@ TEST(EqAssertionTest, Bool) { ...@@ -4689,14 +4688,14 @@ TEST(EqAssertionTest, Bool) {
EXPECT_FATAL_FAILURE({ EXPECT_FATAL_FAILURE({
bool false_value = false; bool false_value = false;
ASSERT_EQ(false_value, true); ASSERT_EQ(false_value, true);
}, "Which is: false"); }, " false_value\n Which is: false\n true");
} }
// Tests using int values in {EXPECT|ASSERT}_EQ. // Tests using int values in {EXPECT|ASSERT}_EQ.
TEST(EqAssertionTest, Int) { TEST(EqAssertionTest, Int) {
ASSERT_EQ(32, 32); ASSERT_EQ(32, 32);
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(32, 33), EXPECT_NONFATAL_FAILURE(EXPECT_EQ(32, 33),
"33"); " 32\n 33");
} }
// Tests using time_t values in {EXPECT|ASSERT}_EQ. // Tests using time_t values in {EXPECT|ASSERT}_EQ.
...@@ -4713,9 +4712,9 @@ TEST(EqAssertionTest, Char) { ...@@ -4713,9 +4712,9 @@ TEST(EqAssertionTest, Char) {
ASSERT_EQ('z', 'z'); ASSERT_EQ('z', 'z');
const char ch = 'b'; const char ch = 'b';
EXPECT_NONFATAL_FAILURE(EXPECT_EQ('\0', ch), EXPECT_NONFATAL_FAILURE(EXPECT_EQ('\0', ch),
"ch"); " ch\n Which is: 'b'");
EXPECT_NONFATAL_FAILURE(EXPECT_EQ('a', ch), EXPECT_NONFATAL_FAILURE(EXPECT_EQ('a', ch),
"ch"); " ch\n Which is: 'b'");
} }
// Tests using wchar_t values in {EXPECT|ASSERT}_EQ. // Tests using wchar_t values in {EXPECT|ASSERT}_EQ.
...@@ -4735,7 +4734,7 @@ TEST(EqAssertionTest, WideChar) { ...@@ -4735,7 +4734,7 @@ TEST(EqAssertionTest, WideChar) {
"wchar"); "wchar");
wchar = 0x8119; wchar = 0x8119;
EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast<wchar_t>(0x8120), wchar), EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast<wchar_t>(0x8120), wchar),
"wchar"); " wchar\n Which is: L'");
} }
// Tests using ::std::string values in {EXPECT|ASSERT}_EQ. // Tests using ::std::string values in {EXPECT|ASSERT}_EQ.
...@@ -4764,8 +4763,7 @@ TEST(EqAssertionTest, StdString) { ...@@ -4764,8 +4763,7 @@ TEST(EqAssertionTest, StdString) {
static ::std::string str3(str1); static ::std::string str3(str1);
str3.at(2) = '\0'; str3.at(2) = '\0';
EXPECT_FATAL_FAILURE(ASSERT_EQ(str1, str3), EXPECT_FATAL_FAILURE(ASSERT_EQ(str1, str3),
" str3\n" " str3\n Which is: \"A \\0 in the middle\"");
" Which is: \"A \\0 in the middle\"");
} }
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
...@@ -4885,9 +4883,9 @@ TEST(EqAssertionTest, CharPointer) { ...@@ -4885,9 +4883,9 @@ TEST(EqAssertionTest, CharPointer) {
ASSERT_EQ(p1, p1); ASSERT_EQ(p1, p1);
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2),
"p2"); " p2\n Which is:");
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2),
"p2"); " p2\n Which is:");
EXPECT_FATAL_FAILURE(ASSERT_EQ(reinterpret_cast<char*>(0x1234), EXPECT_FATAL_FAILURE(ASSERT_EQ(reinterpret_cast<char*>(0x1234),
reinterpret_cast<char*>(0xABC0)), reinterpret_cast<char*>(0xABC0)),
"ABC0"); "ABC0");
...@@ -4907,9 +4905,9 @@ TEST(EqAssertionTest, WideCharPointer) { ...@@ -4907,9 +4905,9 @@ TEST(EqAssertionTest, WideCharPointer) {
EXPECT_EQ(p0, p0); EXPECT_EQ(p0, p0);
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2), EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2),
"p2"); " p2\n Which is:");
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2), EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2),
"p2"); " p2\n Which is:");
void* pv3 = (void*)0x1234; // NOLINT void* pv3 = (void*)0x1234; // NOLINT
void* pv4 = (void*)0xABC0; // NOLINT void* pv4 = (void*)0xABC0; // NOLINT
const wchar_t* p3 = reinterpret_cast<const wchar_t*>(pv3); const wchar_t* p3 = reinterpret_cast<const wchar_t*>(pv3);
...@@ -5454,7 +5452,8 @@ TEST_F(SetUpTestCaseTest, Test2) { ...@@ -5454,7 +5452,8 @@ TEST_F(SetUpTestCaseTest, Test2) {
EXPECT_STREQ("123", shared_resource_); EXPECT_STREQ("123", shared_resource_);
} }
// The InitGoogleTestTest test case tests testing::InitGoogleTest().
// The ParseFlagsTest test case tests ParseGoogleTestFlagsOnly.
// The Flags struct stores a copy of all Google Test flags. // The Flags struct stores a copy of all Google Test flags.
struct Flags { struct Flags {
...@@ -5540,8 +5539,8 @@ struct Flags { ...@@ -5540,8 +5539,8 @@ struct Flags {
return flags; return flags;
} }
// Creates a Flags struct where the gtest_random_seed flag has // Creates a Flags struct where the gtest_random_seed flag has the given
// the given value. // value.
static Flags RandomSeed(Int32 random_seed) { static Flags RandomSeed(Int32 random_seed) {
Flags flags; Flags flags;
flags.random_seed = random_seed; flags.random_seed = random_seed;
...@@ -5556,8 +5555,8 @@ struct Flags { ...@@ -5556,8 +5555,8 @@ struct Flags {
return flags; return flags;
} }
// Creates a Flags struct where the gtest_shuffle flag has // Creates a Flags struct where the gtest_shuffle flag has the given
// the given value. // value.
static Flags Shuffle(bool shuffle) { static Flags Shuffle(bool shuffle) {
Flags flags; Flags flags;
flags.shuffle = shuffle; flags.shuffle = shuffle;
...@@ -5605,8 +5604,8 @@ struct Flags { ...@@ -5605,8 +5604,8 @@ struct Flags {
bool throw_on_failure; bool throw_on_failure;
}; };
// Fixture for testing InitGoogleTest(). // Fixture for testing ParseGoogleTestFlagsOnly().
class InitGoogleTestTest : public Test { class ParseFlagsTest : public Test {
protected: protected:
// Clears the flags before each test. // Clears the flags before each test.
virtual void SetUp() { virtual void SetUp() {
...@@ -5667,16 +5666,16 @@ class InitGoogleTestTest : public Test { ...@@ -5667,16 +5666,16 @@ class InitGoogleTestTest : public Test {
const bool saved_help_flag = ::testing::internal::g_help_flag; const bool saved_help_flag = ::testing::internal::g_help_flag;
::testing::internal::g_help_flag = false; ::testing::internal::g_help_flag = false;
#if GTEST_HAS_STREAM_REDIRECTION # if GTEST_HAS_STREAM_REDIRECTION
CaptureStdout(); CaptureStdout();
#endif # endif
// Parses the command line. // Parses the command line.
internal::ParseGoogleTestFlagsOnly(&argc1, const_cast<CharType**>(argv1)); internal::ParseGoogleTestFlagsOnly(&argc1, const_cast<CharType**>(argv1));
#if GTEST_HAS_STREAM_REDIRECTION # if GTEST_HAS_STREAM_REDIRECTION
const std::string captured_stdout = GetCapturedStdout(); const std::string captured_stdout = GetCapturedStdout();
#endif # endif
// Verifies the flag values. // Verifies the flag values.
CheckFlags(expected); CheckFlags(expected);
...@@ -5689,7 +5688,7 @@ class InitGoogleTestTest : public Test { ...@@ -5689,7 +5688,7 @@ class InitGoogleTestTest : public Test {
// help message for the flags it recognizes. // help message for the flags it recognizes.
EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag); EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag);
#if GTEST_HAS_STREAM_REDIRECTION # if GTEST_HAS_STREAM_REDIRECTION
const char* const expected_help_fragment = const char* const expected_help_fragment =
"This program contains tests written using"; "This program contains tests written using";
if (should_print_help) { if (should_print_help) {
...@@ -5698,7 +5697,7 @@ class InitGoogleTestTest : public Test { ...@@ -5698,7 +5697,7 @@ class InitGoogleTestTest : public Test {
EXPECT_PRED_FORMAT2(IsNotSubstring, EXPECT_PRED_FORMAT2(IsNotSubstring,
expected_help_fragment, captured_stdout); expected_help_fragment, captured_stdout);
} }
#endif // GTEST_HAS_STREAM_REDIRECTION # endif // GTEST_HAS_STREAM_REDIRECTION
::testing::internal::g_help_flag = saved_help_flag; ::testing::internal::g_help_flag = saved_help_flag;
} }
...@@ -5706,14 +5705,14 @@ class InitGoogleTestTest : public Test { ...@@ -5706,14 +5705,14 @@ class InitGoogleTestTest : public Test {
// This macro wraps TestParsingFlags s.t. the user doesn't need // This macro wraps TestParsingFlags s.t. the user doesn't need
// to specify the array sizes. // to specify the array sizes.
#define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \ # define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \
TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \ TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \
sizeof(argv2)/sizeof(*argv2) - 1, argv2, \ sizeof(argv2)/sizeof(*argv2) - 1, argv2, \
expected, should_print_help) expected, should_print_help)
}; };
// Tests parsing an empty command line. // Tests parsing an empty command line.
TEST_F(InitGoogleTestTest, Empty) { TEST_F(ParseFlagsTest, Empty) {
const char* argv[] = { const char* argv[] = {
NULL NULL
}; };
...@@ -5726,7 +5725,7 @@ TEST_F(InitGoogleTestTest, Empty) { ...@@ -5726,7 +5725,7 @@ TEST_F(InitGoogleTestTest, Empty) {
} }
// Tests parsing a command line that has no flag. // Tests parsing a command line that has no flag.
TEST_F(InitGoogleTestTest, NoFlag) { TEST_F(ParseFlagsTest, NoFlag) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
NULL NULL
...@@ -5741,7 +5740,7 @@ TEST_F(InitGoogleTestTest, NoFlag) { ...@@ -5741,7 +5740,7 @@ TEST_F(InitGoogleTestTest, NoFlag) {
} }
// Tests parsing a bad --gtest_filter flag. // Tests parsing a bad --gtest_filter flag.
TEST_F(InitGoogleTestTest, FilterBad) { TEST_F(ParseFlagsTest, FilterBad) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_filter", "--gtest_filter",
...@@ -5758,7 +5757,7 @@ TEST_F(InitGoogleTestTest, FilterBad) { ...@@ -5758,7 +5757,7 @@ TEST_F(InitGoogleTestTest, FilterBad) {
} }
// Tests parsing an empty --gtest_filter flag. // Tests parsing an empty --gtest_filter flag.
TEST_F(InitGoogleTestTest, FilterEmpty) { TEST_F(ParseFlagsTest, FilterEmpty) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_filter=", "--gtest_filter=",
...@@ -5774,7 +5773,7 @@ TEST_F(InitGoogleTestTest, FilterEmpty) { ...@@ -5774,7 +5773,7 @@ TEST_F(InitGoogleTestTest, FilterEmpty) {
} }
// Tests parsing a non-empty --gtest_filter flag. // Tests parsing a non-empty --gtest_filter flag.
TEST_F(InitGoogleTestTest, FilterNonEmpty) { TEST_F(ParseFlagsTest, FilterNonEmpty) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_filter=abc", "--gtest_filter=abc",
...@@ -5790,7 +5789,7 @@ TEST_F(InitGoogleTestTest, FilterNonEmpty) { ...@@ -5790,7 +5789,7 @@ TEST_F(InitGoogleTestTest, FilterNonEmpty) {
} }
// Tests parsing --gtest_break_on_failure. // Tests parsing --gtest_break_on_failure.
TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) { TEST_F(ParseFlagsTest, BreakOnFailureWithoutValue) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_break_on_failure", "--gtest_break_on_failure",
...@@ -5806,7 +5805,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) { ...@@ -5806,7 +5805,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) {
} }
// Tests parsing --gtest_break_on_failure=0. // Tests parsing --gtest_break_on_failure=0.
TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) { TEST_F(ParseFlagsTest, BreakOnFailureFalse_0) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_break_on_failure=0", "--gtest_break_on_failure=0",
...@@ -5822,7 +5821,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) { ...@@ -5822,7 +5821,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) {
} }
// Tests parsing --gtest_break_on_failure=f. // Tests parsing --gtest_break_on_failure=f.
TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) { TEST_F(ParseFlagsTest, BreakOnFailureFalse_f) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_break_on_failure=f", "--gtest_break_on_failure=f",
...@@ -5838,7 +5837,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) { ...@@ -5838,7 +5837,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) {
} }
// Tests parsing --gtest_break_on_failure=F. // Tests parsing --gtest_break_on_failure=F.
TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) { TEST_F(ParseFlagsTest, BreakOnFailureFalse_F) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_break_on_failure=F", "--gtest_break_on_failure=F",
...@@ -5855,7 +5854,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) { ...@@ -5855,7 +5854,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) {
// Tests parsing a --gtest_break_on_failure flag that has a "true" // Tests parsing a --gtest_break_on_failure flag that has a "true"
// definition. // definition.
TEST_F(InitGoogleTestTest, BreakOnFailureTrue) { TEST_F(ParseFlagsTest, BreakOnFailureTrue) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_break_on_failure=1", "--gtest_break_on_failure=1",
...@@ -5871,7 +5870,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureTrue) { ...@@ -5871,7 +5870,7 @@ TEST_F(InitGoogleTestTest, BreakOnFailureTrue) {
} }
// Tests parsing --gtest_catch_exceptions. // Tests parsing --gtest_catch_exceptions.
TEST_F(InitGoogleTestTest, CatchExceptions) { TEST_F(ParseFlagsTest, CatchExceptions) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_catch_exceptions", "--gtest_catch_exceptions",
...@@ -5887,7 +5886,7 @@ TEST_F(InitGoogleTestTest, CatchExceptions) { ...@@ -5887,7 +5886,7 @@ TEST_F(InitGoogleTestTest, CatchExceptions) {
} }
// Tests parsing --gtest_death_test_use_fork. // Tests parsing --gtest_death_test_use_fork.
TEST_F(InitGoogleTestTest, DeathTestUseFork) { TEST_F(ParseFlagsTest, DeathTestUseFork) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_death_test_use_fork", "--gtest_death_test_use_fork",
...@@ -5904,7 +5903,7 @@ TEST_F(InitGoogleTestTest, DeathTestUseFork) { ...@@ -5904,7 +5903,7 @@ TEST_F(InitGoogleTestTest, DeathTestUseFork) {
// Tests having the same flag twice with different values. The // Tests having the same flag twice with different values. The
// expected behavior is that the one coming last takes precedence. // expected behavior is that the one coming last takes precedence.
TEST_F(InitGoogleTestTest, DuplicatedFlags) { TEST_F(ParseFlagsTest, DuplicatedFlags) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_filter=a", "--gtest_filter=a",
...@@ -5921,7 +5920,7 @@ TEST_F(InitGoogleTestTest, DuplicatedFlags) { ...@@ -5921,7 +5920,7 @@ TEST_F(InitGoogleTestTest, DuplicatedFlags) {
} }
// Tests having an unrecognized flag on the command line. // Tests having an unrecognized flag on the command line.
TEST_F(InitGoogleTestTest, UnrecognizedFlag) { TEST_F(ParseFlagsTest, UnrecognizedFlag) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_break_on_failure", "--gtest_break_on_failure",
...@@ -5943,7 +5942,7 @@ TEST_F(InitGoogleTestTest, UnrecognizedFlag) { ...@@ -5943,7 +5942,7 @@ TEST_F(InitGoogleTestTest, UnrecognizedFlag) {
} }
// Tests having a --gtest_list_tests flag // Tests having a --gtest_list_tests flag
TEST_F(InitGoogleTestTest, ListTestsFlag) { TEST_F(ParseFlagsTest, ListTestsFlag) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_list_tests", "--gtest_list_tests",
...@@ -5959,7 +5958,7 @@ TEST_F(InitGoogleTestTest, ListTestsFlag) { ...@@ -5959,7 +5958,7 @@ TEST_F(InitGoogleTestTest, ListTestsFlag) {
} }
// Tests having a --gtest_list_tests flag with a "true" value // Tests having a --gtest_list_tests flag with a "true" value
TEST_F(InitGoogleTestTest, ListTestsTrue) { TEST_F(ParseFlagsTest, ListTestsTrue) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_list_tests=1", "--gtest_list_tests=1",
...@@ -5975,7 +5974,7 @@ TEST_F(InitGoogleTestTest, ListTestsTrue) { ...@@ -5975,7 +5974,7 @@ TEST_F(InitGoogleTestTest, ListTestsTrue) {
} }
// Tests having a --gtest_list_tests flag with a "false" value // Tests having a --gtest_list_tests flag with a "false" value
TEST_F(InitGoogleTestTest, ListTestsFalse) { TEST_F(ParseFlagsTest, ListTestsFalse) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_list_tests=0", "--gtest_list_tests=0",
...@@ -5991,7 +5990,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse) { ...@@ -5991,7 +5990,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse) {
} }
// Tests parsing --gtest_list_tests=f. // Tests parsing --gtest_list_tests=f.
TEST_F(InitGoogleTestTest, ListTestsFalse_f) { TEST_F(ParseFlagsTest, ListTestsFalse_f) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_list_tests=f", "--gtest_list_tests=f",
...@@ -6007,7 +6006,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_f) { ...@@ -6007,7 +6006,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_f) {
} }
// Tests parsing --gtest_list_tests=F. // Tests parsing --gtest_list_tests=F.
TEST_F(InitGoogleTestTest, ListTestsFalse_F) { TEST_F(ParseFlagsTest, ListTestsFalse_F) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_list_tests=F", "--gtest_list_tests=F",
...@@ -6023,7 +6022,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_F) { ...@@ -6023,7 +6022,7 @@ TEST_F(InitGoogleTestTest, ListTestsFalse_F) {
} }
// Tests parsing --gtest_output (invalid). // Tests parsing --gtest_output (invalid).
TEST_F(InitGoogleTestTest, OutputEmpty) { TEST_F(ParseFlagsTest, OutputEmpty) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_output", "--gtest_output",
...@@ -6040,7 +6039,7 @@ TEST_F(InitGoogleTestTest, OutputEmpty) { ...@@ -6040,7 +6039,7 @@ TEST_F(InitGoogleTestTest, OutputEmpty) {
} }
// Tests parsing --gtest_output=xml // Tests parsing --gtest_output=xml
TEST_F(InitGoogleTestTest, OutputXml) { TEST_F(ParseFlagsTest, OutputXml) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_output=xml", "--gtest_output=xml",
...@@ -6056,7 +6055,7 @@ TEST_F(InitGoogleTestTest, OutputXml) { ...@@ -6056,7 +6055,7 @@ TEST_F(InitGoogleTestTest, OutputXml) {
} }
// Tests parsing --gtest_output=xml:file // Tests parsing --gtest_output=xml:file
TEST_F(InitGoogleTestTest, OutputXmlFile) { TEST_F(ParseFlagsTest, OutputXmlFile) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_output=xml:file", "--gtest_output=xml:file",
...@@ -6072,7 +6071,7 @@ TEST_F(InitGoogleTestTest, OutputXmlFile) { ...@@ -6072,7 +6071,7 @@ TEST_F(InitGoogleTestTest, OutputXmlFile) {
} }
// Tests parsing --gtest_output=xml:directory/path/ // Tests parsing --gtest_output=xml:directory/path/
TEST_F(InitGoogleTestTest, OutputXmlDirectory) { TEST_F(ParseFlagsTest, OutputXmlDirectory) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_output=xml:directory/path/", "--gtest_output=xml:directory/path/",
...@@ -6089,7 +6088,7 @@ TEST_F(InitGoogleTestTest, OutputXmlDirectory) { ...@@ -6089,7 +6088,7 @@ TEST_F(InitGoogleTestTest, OutputXmlDirectory) {
} }
// Tests having a --gtest_print_time flag // Tests having a --gtest_print_time flag
TEST_F(InitGoogleTestTest, PrintTimeFlag) { TEST_F(ParseFlagsTest, PrintTimeFlag) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_print_time", "--gtest_print_time",
...@@ -6105,7 +6104,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFlag) { ...@@ -6105,7 +6104,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFlag) {
} }
// Tests having a --gtest_print_time flag with a "true" value // Tests having a --gtest_print_time flag with a "true" value
TEST_F(InitGoogleTestTest, PrintTimeTrue) { TEST_F(ParseFlagsTest, PrintTimeTrue) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_print_time=1", "--gtest_print_time=1",
...@@ -6121,7 +6120,7 @@ TEST_F(InitGoogleTestTest, PrintTimeTrue) { ...@@ -6121,7 +6120,7 @@ TEST_F(InitGoogleTestTest, PrintTimeTrue) {
} }
// Tests having a --gtest_print_time flag with a "false" value // Tests having a --gtest_print_time flag with a "false" value
TEST_F(InitGoogleTestTest, PrintTimeFalse) { TEST_F(ParseFlagsTest, PrintTimeFalse) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_print_time=0", "--gtest_print_time=0",
...@@ -6137,7 +6136,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse) { ...@@ -6137,7 +6136,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse) {
} }
// Tests parsing --gtest_print_time=f. // Tests parsing --gtest_print_time=f.
TEST_F(InitGoogleTestTest, PrintTimeFalse_f) { TEST_F(ParseFlagsTest, PrintTimeFalse_f) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_print_time=f", "--gtest_print_time=f",
...@@ -6153,7 +6152,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_f) { ...@@ -6153,7 +6152,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_f) {
} }
// Tests parsing --gtest_print_time=F. // Tests parsing --gtest_print_time=F.
TEST_F(InitGoogleTestTest, PrintTimeFalse_F) { TEST_F(ParseFlagsTest, PrintTimeFalse_F) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_print_time=F", "--gtest_print_time=F",
...@@ -6169,7 +6168,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_F) { ...@@ -6169,7 +6168,7 @@ TEST_F(InitGoogleTestTest, PrintTimeFalse_F) {
} }
// Tests parsing --gtest_random_seed=number // Tests parsing --gtest_random_seed=number
TEST_F(InitGoogleTestTest, RandomSeed) { TEST_F(ParseFlagsTest, RandomSeed) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_random_seed=1000", "--gtest_random_seed=1000",
...@@ -6185,7 +6184,7 @@ TEST_F(InitGoogleTestTest, RandomSeed) { ...@@ -6185,7 +6184,7 @@ TEST_F(InitGoogleTestTest, RandomSeed) {
} }
// Tests parsing --gtest_repeat=number // Tests parsing --gtest_repeat=number
TEST_F(InitGoogleTestTest, Repeat) { TEST_F(ParseFlagsTest, Repeat) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_repeat=1000", "--gtest_repeat=1000",
...@@ -6201,7 +6200,7 @@ TEST_F(InitGoogleTestTest, Repeat) { ...@@ -6201,7 +6200,7 @@ TEST_F(InitGoogleTestTest, Repeat) {
} }
// Tests having a --gtest_also_run_disabled_tests flag // Tests having a --gtest_also_run_disabled_tests flag
TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) { TEST_F(ParseFlagsTest, AlsoRunDisabledTestsFlag) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_also_run_disabled_tests", "--gtest_also_run_disabled_tests",
...@@ -6218,7 +6217,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) { ...@@ -6218,7 +6217,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) {
} }
// Tests having a --gtest_also_run_disabled_tests flag with a "true" value // Tests having a --gtest_also_run_disabled_tests flag with a "true" value
TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) { TEST_F(ParseFlagsTest, AlsoRunDisabledTestsTrue) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_also_run_disabled_tests=1", "--gtest_also_run_disabled_tests=1",
...@@ -6235,7 +6234,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) { ...@@ -6235,7 +6234,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) {
} }
// Tests having a --gtest_also_run_disabled_tests flag with a "false" value // Tests having a --gtest_also_run_disabled_tests flag with a "false" value
TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) { TEST_F(ParseFlagsTest, AlsoRunDisabledTestsFalse) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_also_run_disabled_tests=0", "--gtest_also_run_disabled_tests=0",
...@@ -6252,7 +6251,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) { ...@@ -6252,7 +6251,7 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) {
} }
// Tests parsing --gtest_shuffle. // Tests parsing --gtest_shuffle.
TEST_F(InitGoogleTestTest, ShuffleWithoutValue) { TEST_F(ParseFlagsTest, ShuffleWithoutValue) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_shuffle", "--gtest_shuffle",
...@@ -6268,7 +6267,7 @@ TEST_F(InitGoogleTestTest, ShuffleWithoutValue) { ...@@ -6268,7 +6267,7 @@ TEST_F(InitGoogleTestTest, ShuffleWithoutValue) {
} }
// Tests parsing --gtest_shuffle=0. // Tests parsing --gtest_shuffle=0.
TEST_F(InitGoogleTestTest, ShuffleFalse_0) { TEST_F(ParseFlagsTest, ShuffleFalse_0) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_shuffle=0", "--gtest_shuffle=0",
...@@ -6283,9 +6282,8 @@ TEST_F(InitGoogleTestTest, ShuffleFalse_0) { ...@@ -6283,9 +6282,8 @@ TEST_F(InitGoogleTestTest, ShuffleFalse_0) {
GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false), false); GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false), false);
} }
// Tests parsing a --gtest_shuffle flag that has a "true" // Tests parsing a --gtest_shuffle flag that has a "true" definition.
// definition. TEST_F(ParseFlagsTest, ShuffleTrue) {
TEST_F(InitGoogleTestTest, ShuffleTrue) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_shuffle=1", "--gtest_shuffle=1",
...@@ -6301,7 +6299,7 @@ TEST_F(InitGoogleTestTest, ShuffleTrue) { ...@@ -6301,7 +6299,7 @@ TEST_F(InitGoogleTestTest, ShuffleTrue) {
} }
// Tests parsing --gtest_stack_trace_depth=number. // Tests parsing --gtest_stack_trace_depth=number.
TEST_F(InitGoogleTestTest, StackTraceDepth) { TEST_F(ParseFlagsTest, StackTraceDepth) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_stack_trace_depth=5", "--gtest_stack_trace_depth=5",
...@@ -6316,7 +6314,7 @@ TEST_F(InitGoogleTestTest, StackTraceDepth) { ...@@ -6316,7 +6314,7 @@ TEST_F(InitGoogleTestTest, StackTraceDepth) {
GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::StackTraceDepth(5), false); GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::StackTraceDepth(5), false);
} }
TEST_F(InitGoogleTestTest, StreamResultTo) { TEST_F(ParseFlagsTest, StreamResultTo) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_stream_result_to=localhost:1234", "--gtest_stream_result_to=localhost:1234",
...@@ -6333,7 +6331,7 @@ TEST_F(InitGoogleTestTest, StreamResultTo) { ...@@ -6333,7 +6331,7 @@ TEST_F(InitGoogleTestTest, StreamResultTo) {
} }
// Tests parsing --gtest_throw_on_failure. // Tests parsing --gtest_throw_on_failure.
TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) { TEST_F(ParseFlagsTest, ThrowOnFailureWithoutValue) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_throw_on_failure", "--gtest_throw_on_failure",
...@@ -6349,7 +6347,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) { ...@@ -6349,7 +6347,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) {
} }
// Tests parsing --gtest_throw_on_failure=0. // Tests parsing --gtest_throw_on_failure=0.
TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) { TEST_F(ParseFlagsTest, ThrowOnFailureFalse_0) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_throw_on_failure=0", "--gtest_throw_on_failure=0",
...@@ -6366,7 +6364,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) { ...@@ -6366,7 +6364,7 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) {
// Tests parsing a --gtest_throw_on_failure flag that has a "true" // Tests parsing a --gtest_throw_on_failure flag that has a "true"
// definition. // definition.
TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) { TEST_F(ParseFlagsTest, ThrowOnFailureTrue) {
const char* argv[] = { const char* argv[] = {
"foo.exe", "foo.exe",
"--gtest_throw_on_failure=1", "--gtest_throw_on_failure=1",
...@@ -6381,9 +6379,9 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) { ...@@ -6381,9 +6379,9 @@ TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) {
GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false); GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false);
} }
#if GTEST_OS_WINDOWS # if GTEST_OS_WINDOWS
// Tests parsing wide strings. // Tests parsing wide strings.
TEST_F(InitGoogleTestTest, WideStrings) { TEST_F(ParseFlagsTest, WideStrings) {
const wchar_t* argv[] = { const wchar_t* argv[] = {
L"foo.exe", L"foo.exe",
L"--gtest_filter=Foo*", L"--gtest_filter=Foo*",
...@@ -6409,10 +6407,10 @@ TEST_F(InitGoogleTestTest, WideStrings) { ...@@ -6409,10 +6407,10 @@ TEST_F(InitGoogleTestTest, WideStrings) {
# endif // GTEST_OS_WINDOWS # endif // GTEST_OS_WINDOWS
#if GTEST_USE_OWN_FLAGFILE_FLAG_ #if GTEST_USE_OWN_FLAGFILE_FLAG_
class FlagfileTest : public InitGoogleTestTest { class FlagfileTest : public ParseFlagsTest {
public: public:
virtual void SetUp() { virtual void SetUp() {
InitGoogleTestTest::SetUp(); ParseFlagsTest::SetUp();
testdata_path_.Set(internal::FilePath( testdata_path_.Set(internal::FilePath(
testing::TempDir() + internal::GetCurrentExecutableName().string() + testing::TempDir() + internal::GetCurrentExecutableName().string() +
...@@ -6423,7 +6421,7 @@ class FlagfileTest : public InitGoogleTestTest { ...@@ -6423,7 +6421,7 @@ class FlagfileTest : public InitGoogleTestTest {
virtual void TearDown() { virtual void TearDown() {
testing::internal::posix::RmDir(testdata_path_.c_str()); testing::internal::posix::RmDir(testdata_path_.c_str());
InitGoogleTestTest::TearDown(); ParseFlagsTest::TearDown();
} }
internal::FilePath CreateFlagfile(const char* contents) { internal::FilePath CreateFlagfile(const char* contents) {
...@@ -6562,6 +6560,7 @@ TEST_F(CurrentTestInfoTest, WorksForSecondTestInATestCase) { ...@@ -6562,6 +6560,7 @@ TEST_F(CurrentTestInfoTest, WorksForSecondTestInATestCase) {
} // namespace testing } // namespace testing
// These two lines test that we can define tests in a namespace that // These two lines test that we can define tests in a namespace that
// has the name "testing" and is nested in another namespace. // has the name "testing" and is nested in another namespace.
namespace my_namespace { namespace my_namespace {
...@@ -6642,7 +6641,7 @@ TEST(StreamingAssertionsTest, Truth2) { ...@@ -6642,7 +6641,7 @@ TEST(StreamingAssertionsTest, Truth2) {
} }
#ifdef __BORLANDC__ #ifdef __BORLANDC__
// Restores warnings after previous "#pragma option push" supressed them // Restores warnings after previous "#pragma option push" suppressed them
# pragma option pop # pragma option pop
#endif #endif
...@@ -6892,14 +6891,6 @@ TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) { ...@@ -6892,14 +6891,6 @@ TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) {
StaticAssertTypeEq<int*, IntAlias*>(); StaticAssertTypeEq<int*, IntAlias*>();
} }
TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) {
testing::UnitTest* const unit_test = testing::UnitTest::GetInstance();
// We don't have a stack walker in Google Test yet.
EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 0).c_str());
EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 1).c_str());
}
TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsNoFailure) { TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsNoFailure) {
EXPECT_FALSE(HasNonfatalFailure()); EXPECT_FALSE(HasNonfatalFailure());
} }
...@@ -7659,7 +7650,7 @@ TEST(NativeArrayTest, MethodsWork) { ...@@ -7659,7 +7650,7 @@ TEST(NativeArrayTest, MethodsWork) {
EXPECT_EQ(0, *it); EXPECT_EQ(0, *it);
++it; ++it;
EXPECT_EQ(1, *it); EXPECT_EQ(1, *it);
++it; it++;
EXPECT_EQ(2, *it); EXPECT_EQ(2, *it);
++it; ++it;
EXPECT_EQ(na.end(), it); EXPECT_EQ(na.end(), it);
......
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