mirror of https://github.com/lukechilds/node.git
Browse Source
Check in a gypified gtest and add a simple unit test to show that the basic infrastructure is in place. PR-URL: https://github.com/iojs/io.js/pull/1199 Refs: https://github.com/iojs/io.js/issues/1193 Reviewed-By: Fedor Indutny <fedor@indutny.com> Reviewed-By: Johan Bergström <bugs@bergstroem.nu>v1.8.0-commit
Ben Noordhuis
10 years ago
35 changed files with 31194 additions and 3 deletions
@ -0,0 +1,28 @@ |
|||||
|
Copyright 2008, 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. |
@ -0,0 +1,24 @@ |
|||||
|
{ |
||||
|
'targets': [ |
||||
|
{ |
||||
|
'target_name': 'gtest', |
||||
|
'type': 'static_library', |
||||
|
'cflags': ['-Wno-missing-field-initializers'], |
||||
|
'direct_dependent_settings': { |
||||
|
'include_dirs': ['include'], |
||||
|
}, |
||||
|
'include_dirs': ['.', 'include'], |
||||
|
'sources': [ |
||||
|
'src/gtest-death-test.cc', |
||||
|
'src/gtest-filepath.cc', |
||||
|
'src/gtest-internal-inl.h', |
||||
|
'src/gtest-port.cc', |
||||
|
'src/gtest-printers.cc', |
||||
|
'src/gtest-test-part.cc', |
||||
|
'src/gtest-typed-test.cc', |
||||
|
'src/gtest.cc', |
||||
|
'src/gtest_main.cc', |
||||
|
], |
||||
|
} |
||||
|
], |
||||
|
} |
@ -0,0 +1,294 @@ |
|||||
|
// Copyright 2005, 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)
|
||||
|
//
|
||||
|
// The Google C++ Testing Framework (Google Test)
|
||||
|
//
|
||||
|
// This header file defines the public API for death tests. It is
|
||||
|
// #included by gtest.h so a user doesn't need to include this
|
||||
|
// directly.
|
||||
|
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ |
||||
|
#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ |
||||
|
|
||||
|
#include "gtest/internal/gtest-death-test-internal.h" |
||||
|
|
||||
|
namespace testing { |
||||
|
|
||||
|
// This flag controls the style of death tests. Valid values are "threadsafe",
|
||||
|
// meaning that the death test child process will re-execute the test binary
|
||||
|
// from the start, running only a single death test, or "fast",
|
||||
|
// meaning that the child process will execute the test logic immediately
|
||||
|
// after forking.
|
||||
|
GTEST_DECLARE_string_(death_test_style); |
||||
|
|
||||
|
#if GTEST_HAS_DEATH_TEST |
||||
|
|
||||
|
namespace internal { |
||||
|
|
||||
|
// Returns a Boolean value indicating whether the caller is currently
|
||||
|
// executing in the context of the death test child process. Tools such as
|
||||
|
// Valgrind heap checkers may need this to modify their behavior in death
|
||||
|
// tests. IMPORTANT: This is an internal utility. Using it may break the
|
||||
|
// implementation of death tests. User code MUST NOT use it.
|
||||
|
GTEST_API_ bool InDeathTestChild(); |
||||
|
|
||||
|
} // namespace internal
|
||||
|
|
||||
|
// The following macros are useful for writing death tests.
|
||||
|
|
||||
|
// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
|
||||
|
// executed:
|
||||
|
//
|
||||
|
// 1. It generates a warning if there is more than one active
|
||||
|
// thread. This is because it's safe to fork() or clone() only
|
||||
|
// when there is a single thread.
|
||||
|
//
|
||||
|
// 2. The parent process clone()s a sub-process and runs the death
|
||||
|
// test in it; the sub-process exits with code 0 at the end of the
|
||||
|
// death test, if it hasn't exited already.
|
||||
|
//
|
||||
|
// 3. The parent process waits for the sub-process to terminate.
|
||||
|
//
|
||||
|
// 4. The parent process checks the exit code and error message of
|
||||
|
// the sub-process.
|
||||
|
//
|
||||
|
// Examples:
|
||||
|
//
|
||||
|
// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
|
||||
|
// for (int i = 0; i < 5; i++) {
|
||||
|
// EXPECT_DEATH(server.ProcessRequest(i),
|
||||
|
// "Invalid request .* in ProcessRequest()")
|
||||
|
// << "Failed to die on request " << i;
|
||||
|
// }
|
||||
|
//
|
||||
|
// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
|
||||
|
//
|
||||
|
// bool KilledBySIGHUP(int exit_code) {
|
||||
|
// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
|
||||
|
// }
|
||||
|
//
|
||||
|
// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
|
||||
|
//
|
||||
|
// On the regular expressions used in death tests:
|
||||
|
//
|
||||
|
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
||||
|
// which uses the POSIX extended regex syntax.
|
||||
|
//
|
||||
|
// On other platforms (e.g. Windows), we only support a simple regex
|
||||
|
// syntax implemented as part of Google Test. This limited
|
||||
|
// implementation should be enough most of the time when writing
|
||||
|
// death tests; though it lacks many features you can find in PCRE
|
||||
|
// or POSIX extended regex syntax. For example, we don't support
|
||||
|
// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
|
||||
|
// repetition count ("x{5,7}"), among others.
|
||||
|
//
|
||||
|
// Below is the syntax that we do support. We chose it to be a
|
||||
|
// subset of both PCRE and POSIX extended regex, so it's easy to
|
||||
|
// learn wherever you come from. In the following: 'A' denotes a
|
||||
|
// literal character, period (.), or a single \\ escape sequence;
|
||||
|
// 'x' and 'y' denote regular expressions; 'm' and 'n' are for
|
||||
|
// natural numbers.
|
||||
|
//
|
||||
|
// c matches any literal character c
|
||||
|
// \\d matches any decimal digit
|
||||
|
// \\D matches any character that's not a decimal digit
|
||||
|
// \\f matches \f
|
||||
|
// \\n matches \n
|
||||
|
// \\r matches \r
|
||||
|
// \\s matches any ASCII whitespace, including \n
|
||||
|
// \\S matches any character that's not a whitespace
|
||||
|
// \\t matches \t
|
||||
|
// \\v matches \v
|
||||
|
// \\w matches any letter, _, or decimal digit
|
||||
|
// \\W matches any character that \\w doesn't match
|
||||
|
// \\c matches any literal character c, which must be a punctuation
|
||||
|
// . matches any single character except \n
|
||||
|
// A? matches 0 or 1 occurrences of A
|
||||
|
// A* matches 0 or many occurrences of A
|
||||
|
// A+ matches 1 or many occurrences of A
|
||||
|
// ^ matches the beginning of a string (not that of each line)
|
||||
|
// $ matches the end of a string (not that of each line)
|
||||
|
// xy matches x followed by y
|
||||
|
//
|
||||
|
// If you accidentally use PCRE or POSIX extended regex features
|
||||
|
// not implemented by us, you will get a run-time failure. In that
|
||||
|
// case, please try to rewrite your regular expression within the
|
||||
|
// above syntax.
|
||||
|
//
|
||||
|
// This implementation is *not* meant to be as highly tuned or robust
|
||||
|
// as a compiled regex library, but should perform well enough for a
|
||||
|
// death test, which already incurs significant overhead by launching
|
||||
|
// a child process.
|
||||
|
//
|
||||
|
// Known caveats:
|
||||
|
//
|
||||
|
// A "threadsafe" style death test obtains the path to the test
|
||||
|
// program from argv[0] and re-executes it in the sub-process. For
|
||||
|
// simplicity, the current implementation doesn't search the PATH
|
||||
|
// when launching the sub-process. This means that the user must
|
||||
|
// invoke the test program via a path that contains at least one
|
||||
|
// path separator (e.g. path/to/foo_test and
|
||||
|
// /absolute/path/to/bar_test are fine, but foo_test is not). This
|
||||
|
// is rarely a problem as people usually don't put the test binary
|
||||
|
// directory in PATH.
|
||||
|
//
|
||||
|
// TODO(wan@google.com): make thread-safe death tests search the PATH.
|
||||
|
|
||||
|
// Asserts that a given statement causes the program to exit, with an
|
||||
|
// integer exit status that satisfies predicate, and emitting error output
|
||||
|
// that matches regex.
|
||||
|
# define ASSERT_EXIT(statement, predicate, regex) \ |
||||
|
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) |
||||
|
|
||||
|
// Like ASSERT_EXIT, but continues on to successive tests in the
|
||||
|
// test case, if any:
|
||||
|
# define EXPECT_EXIT(statement, predicate, regex) \ |
||||
|
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) |
||||
|
|
||||
|
// Asserts that a given statement causes the program to exit, either by
|
||||
|
// explicitly exiting with a nonzero exit code or being killed by a
|
||||
|
// signal, and emitting error output that matches regex.
|
||||
|
# define ASSERT_DEATH(statement, regex) \ |
||||
|
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) |
||||
|
|
||||
|
// Like ASSERT_DEATH, but continues on to successive tests in the
|
||||
|
// test case, if any:
|
||||
|
# define EXPECT_DEATH(statement, regex) \ |
||||
|
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) |
||||
|
|
||||
|
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
|
||||
|
|
||||
|
// Tests that an exit code describes a normal exit with a given exit code.
|
||||
|
class GTEST_API_ ExitedWithCode { |
||||
|
public: |
||||
|
explicit ExitedWithCode(int exit_code); |
||||
|
bool operator()(int exit_status) const; |
||||
|
private: |
||||
|
// No implementation - assignment is unsupported.
|
||||
|
void operator=(const ExitedWithCode& other); |
||||
|
|
||||
|
const int exit_code_; |
||||
|
}; |
||||
|
|
||||
|
# if !GTEST_OS_WINDOWS |
||||
|
// Tests that an exit code describes an exit due to termination by a
|
||||
|
// given signal.
|
||||
|
class GTEST_API_ KilledBySignal { |
||||
|
public: |
||||
|
explicit KilledBySignal(int signum); |
||||
|
bool operator()(int exit_status) const; |
||||
|
private: |
||||
|
const int signum_; |
||||
|
}; |
||||
|
# endif // !GTEST_OS_WINDOWS
|
||||
|
|
||||
|
// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
|
||||
|
// The death testing framework causes this to have interesting semantics,
|
||||
|
// since the sideeffects of the call are only visible in opt mode, and not
|
||||
|
// in debug mode.
|
||||
|
//
|
||||
|
// In practice, this can be used to test functions that utilize the
|
||||
|
// LOG(DFATAL) macro using the following style:
|
||||
|
//
|
||||
|
// int DieInDebugOr12(int* sideeffect) {
|
||||
|
// if (sideeffect) {
|
||||
|
// *sideeffect = 12;
|
||||
|
// }
|
||||
|
// LOG(DFATAL) << "death";
|
||||
|
// return 12;
|
||||
|
// }
|
||||
|
//
|
||||
|
// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
|
||||
|
// int sideeffect = 0;
|
||||
|
// // Only asserts in dbg.
|
||||
|
// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
|
||||
|
//
|
||||
|
// #ifdef NDEBUG
|
||||
|
// // opt-mode has sideeffect visible.
|
||||
|
// EXPECT_EQ(12, sideeffect);
|
||||
|
// #else
|
||||
|
// // dbg-mode no visible sideeffect.
|
||||
|
// EXPECT_EQ(0, sideeffect);
|
||||
|
// #endif
|
||||
|
// }
|
||||
|
//
|
||||
|
// This will assert that DieInDebugReturn12InOpt() crashes in debug
|
||||
|
// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
|
||||
|
// appropriate fallback value (12 in this case) in opt mode. If you
|
||||
|
// need to test that a function has appropriate side-effects in opt
|
||||
|
// mode, include assertions against the side-effects. A general
|
||||
|
// pattern for this is:
|
||||
|
//
|
||||
|
// EXPECT_DEBUG_DEATH({
|
||||
|
// // Side-effects here will have an effect after this statement in
|
||||
|
// // opt mode, but none in debug mode.
|
||||
|
// EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
|
||||
|
// }, "death");
|
||||
|
//
|
||||
|
# ifdef NDEBUG |
||||
|
|
||||
|
# define EXPECT_DEBUG_DEATH(statement, regex) \ |
||||
|
GTEST_EXECUTE_STATEMENT_(statement, regex) |
||||
|
|
||||
|
# define ASSERT_DEBUG_DEATH(statement, regex) \ |
||||
|
GTEST_EXECUTE_STATEMENT_(statement, regex) |
||||
|
|
||||
|
# else |
||||
|
|
||||
|
# define EXPECT_DEBUG_DEATH(statement, regex) \ |
||||
|
EXPECT_DEATH(statement, regex) |
||||
|
|
||||
|
# define ASSERT_DEBUG_DEATH(statement, regex) \ |
||||
|
ASSERT_DEATH(statement, regex) |
||||
|
|
||||
|
# endif // NDEBUG for EXPECT_DEBUG_DEATH
|
||||
|
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
|
||||
|
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
|
||||
|
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
|
||||
|
// death tests are supported; otherwise they just issue a warning. This is
|
||||
|
// useful when you are combining death test assertions with normal test
|
||||
|
// assertions in one test.
|
||||
|
#if GTEST_HAS_DEATH_TEST |
||||
|
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ |
||||
|
EXPECT_DEATH(statement, regex) |
||||
|
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ |
||||
|
ASSERT_DEATH(statement, regex) |
||||
|
#else |
||||
|
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ |
||||
|
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) |
||||
|
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ |
||||
|
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) |
||||
|
#endif |
||||
|
|
||||
|
} // namespace testing
|
||||
|
|
||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
@ -0,0 +1,250 @@ |
|||||
|
// Copyright 2005, 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)
|
||||
|
//
|
||||
|
// The Google C++ Testing Framework (Google Test)
|
||||
|
//
|
||||
|
// This header file defines the Message class.
|
||||
|
//
|
||||
|
// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
|
||||
|
// leave some internal implementation details in this header file.
|
||||
|
// They are clearly marked by comments like this:
|
||||
|
//
|
||||
|
// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
|
//
|
||||
|
// Such code is NOT meant to be used by a user directly, and is subject
|
||||
|
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
|
||||
|
// program!
|
||||
|
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ |
||||
|
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ |
||||
|
|
||||
|
#include <limits> |
||||
|
|
||||
|
#include "gtest/internal/gtest-port.h" |
||||
|
|
||||
|
// Ensures that there is at least one operator<< in the global namespace.
|
||||
|
// See Message& operator<<(...) below for why.
|
||||
|
void operator<<(const testing::internal::Secret&, int); |
||||
|
|
||||
|
namespace testing { |
||||
|
|
||||
|
// The Message class works like an ostream repeater.
|
||||
|
//
|
||||
|
// Typical usage:
|
||||
|
//
|
||||
|
// 1. You stream a bunch of values to a Message object.
|
||||
|
// It will remember the text in a stringstream.
|
||||
|
// 2. Then you stream the Message object to an ostream.
|
||||
|
// This causes the text in the Message to be streamed
|
||||
|
// to the ostream.
|
||||
|
//
|
||||
|
// For example;
|
||||
|
//
|
||||
|
// testing::Message foo;
|
||||
|
// foo << 1 << " != " << 2;
|
||||
|
// std::cout << foo;
|
||||
|
//
|
||||
|
// will print "1 != 2".
|
||||
|
//
|
||||
|
// Message is not intended to be inherited from. In particular, its
|
||||
|
// destructor is not virtual.
|
||||
|
//
|
||||
|
// Note that stringstream behaves differently in gcc and in MSVC. You
|
||||
|
// can stream a NULL char pointer to it in the former, but not in the
|
||||
|
// latter (it causes an access violation if you do). The Message
|
||||
|
// class hides this difference by treating a NULL char pointer as
|
||||
|
// "(null)".
|
||||
|
class GTEST_API_ Message { |
||||
|
private: |
||||
|
// The type of basic IO manipulators (endl, ends, and flush) for
|
||||
|
// narrow streams.
|
||||
|
typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); |
||||
|
|
||||
|
public: |
||||
|
// Constructs an empty Message.
|
||||
|
Message(); |
||||
|
|
||||
|
// Copy constructor.
|
||||
|
Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT
|
||||
|
*ss_ << msg.GetString(); |
||||
|
} |
||||
|
|
||||
|
// Constructs a Message from a C-string.
|
||||
|
explicit Message(const char* str) : ss_(new ::std::stringstream) { |
||||
|
*ss_ << str; |
||||
|
} |
||||
|
|
||||
|
#if GTEST_OS_SYMBIAN |
||||
|
// Streams a value (either a pointer or not) to this object.
|
||||
|
template <typename T> |
||||
|
inline Message& operator <<(const T& value) { |
||||
|
StreamHelper(typename internal::is_pointer<T>::type(), value); |
||||
|
return *this; |
||||
|
} |
||||
|
#else |
||||
|
// Streams a non-pointer value to this object.
|
||||
|
template <typename T> |
||||
|
inline Message& operator <<(const T& val) { |
||||
|
// Some libraries overload << for STL containers. These
|
||||
|
// overloads are defined in the global namespace instead of ::std.
|
||||
|
//
|
||||
|
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
|
||||
|
// overloads are visible in either the std namespace or the global
|
||||
|
// namespace, but not other namespaces, including the testing
|
||||
|
// namespace which Google Test's Message class is in.
|
||||
|
//
|
||||
|
// To allow STL containers (and other types that has a << operator
|
||||
|
// defined in the global namespace) to be used in Google Test
|
||||
|
// assertions, testing::Message must access the custom << operator
|
||||
|
// from the global namespace. With this using declaration,
|
||||
|
// overloads of << defined in the global namespace and those
|
||||
|
// visible via Koenig lookup are both exposed in this function.
|
||||
|
using ::operator <<; |
||||
|
*ss_ << val; |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
// Streams a pointer value to this object.
|
||||
|
//
|
||||
|
// This function is an overload of the previous one. When you
|
||||
|
// stream a pointer to a Message, this definition will be used as it
|
||||
|
// is more specialized. (The C++ Standard, section
|
||||
|
// [temp.func.order].) If you stream a non-pointer, then the
|
||||
|
// previous definition will be used.
|
||||
|
//
|
||||
|
// The reason for this overload is that streaming a NULL pointer to
|
||||
|
// ostream is undefined behavior. Depending on the compiler, you
|
||||
|
// may get "0", "(nil)", "(null)", or an access violation. To
|
||||
|
// ensure consistent result across compilers, we always treat NULL
|
||||
|
// as "(null)".
|
||||
|
template <typename T> |
||||
|
inline Message& operator <<(T* const& pointer) { // NOLINT
|
||||
|
if (pointer == NULL) { |
||||
|
*ss_ << "(null)"; |
||||
|
} else { |
||||
|
*ss_ << pointer; |
||||
|
} |
||||
|
return *this; |
||||
|
} |
||||
|
#endif // GTEST_OS_SYMBIAN
|
||||
|
|
||||
|
// Since the basic IO manipulators are overloaded for both narrow
|
||||
|
// and wide streams, we have to provide this specialized definition
|
||||
|
// of operator <<, even though its body is the same as the
|
||||
|
// templatized version above. Without this definition, streaming
|
||||
|
// endl or other basic IO manipulators to Message will confuse the
|
||||
|
// compiler.
|
||||
|
Message& operator <<(BasicNarrowIoManip val) { |
||||
|
*ss_ << val; |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
// Instead of 1/0, we want to see true/false for bool values.
|
||||
|
Message& operator <<(bool b) { |
||||
|
return *this << (b ? "true" : "false"); |
||||
|
} |
||||
|
|
||||
|
// These two overloads allow streaming a wide C string to a Message
|
||||
|
// using the UTF-8 encoding.
|
||||
|
Message& operator <<(const wchar_t* wide_c_str); |
||||
|
Message& operator <<(wchar_t* wide_c_str); |
||||
|
|
||||
|
#if GTEST_HAS_STD_WSTRING |
||||
|
// Converts the given wide string to a narrow string using the UTF-8
|
||||
|
// encoding, and streams the result to this Message object.
|
||||
|
Message& operator <<(const ::std::wstring& wstr); |
||||
|
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
|
||||
|
#if GTEST_HAS_GLOBAL_WSTRING |
||||
|
// Converts the given wide string to a narrow string using the UTF-8
|
||||
|
// encoding, and streams the result to this Message object.
|
||||
|
Message& operator <<(const ::wstring& wstr); |
||||
|
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
|
||||
|
// Gets the text streamed to this object so far as an std::string.
|
||||
|
// Each '\0' character in the buffer is replaced with "\\0".
|
||||
|
//
|
||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
|
std::string GetString() const; |
||||
|
|
||||
|
private: |
||||
|
|
||||
|
#if GTEST_OS_SYMBIAN |
||||
|
// These are needed as the Nokia Symbian Compiler cannot decide between
|
||||
|
// const T& and const T* in a function template. The Nokia compiler _can_
|
||||
|
// decide between class template specializations for T and T*, so a
|
||||
|
// tr1::type_traits-like is_pointer works, and we can overload on that.
|
||||
|
template <typename T> |
||||
|
inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) { |
||||
|
if (pointer == NULL) { |
||||
|
*ss_ << "(null)"; |
||||
|
} else { |
||||
|
*ss_ << pointer; |
||||
|
} |
||||
|
} |
||||
|
template <typename T> |
||||
|
inline void StreamHelper(internal::false_type /*is_pointer*/, |
||||
|
const T& value) { |
||||
|
// See the comments in Message& operator <<(const T&) above for why
|
||||
|
// we need this using statement.
|
||||
|
using ::operator <<; |
||||
|
*ss_ << value; |
||||
|
} |
||||
|
#endif // GTEST_OS_SYMBIAN
|
||||
|
|
||||
|
// We'll hold the text streamed to this object here.
|
||||
|
const internal::scoped_ptr< ::std::stringstream> ss_; |
||||
|
|
||||
|
// We declare (but don't implement) this to prevent the compiler
|
||||
|
// from implementing the assignment operator.
|
||||
|
void operator=(const Message&); |
||||
|
}; |
||||
|
|
||||
|
// Streams a Message to an ostream.
|
||||
|
inline std::ostream& operator <<(std::ostream& os, const Message& sb) { |
||||
|
return os << sb.GetString(); |
||||
|
} |
||||
|
|
||||
|
namespace internal { |
||||
|
|
||||
|
// Converts a streamable value to an std::string. A NULL pointer is
|
||||
|
// converted to "(null)". When the input value is a ::string,
|
||||
|
// ::std::string, ::wstring, or ::std::wstring object, each NUL
|
||||
|
// character in it is replaced with "\\0".
|
||||
|
template <typename T> |
||||
|
std::string StreamableToString(const T& streamable) { |
||||
|
return (Message() << streamable).GetString(); |
||||
|
} |
||||
|
|
||||
|
} // namespace internal
|
||||
|
} // namespace testing
|
||||
|
|
||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
File diff suppressed because it is too large
@ -0,0 +1,891 @@ |
|||||
|
// Copyright 2007, 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)
|
||||
|
|
||||
|
// Google Test - The Google C++ Testing Framework
|
||||
|
//
|
||||
|
// This file implements a universal value printer that can print a
|
||||
|
// value of any type T:
|
||||
|
//
|
||||
|
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
|
||||
|
//
|
||||
|
// A user can teach this function how to print a class type T by
|
||||
|
// defining either operator<<() or PrintTo() in the namespace that
|
||||
|
// defines T. More specifically, the FIRST defined function in the
|
||||
|
// following list will be used (assuming T is defined in namespace
|
||||
|
// foo):
|
||||
|
//
|
||||
|
// 1. foo::PrintTo(const T&, ostream*)
|
||||
|
// 2. operator<<(ostream&, const T&) defined in either foo or the
|
||||
|
// global namespace.
|
||||
|
//
|
||||
|
// If none of the above is defined, it will print the debug string of
|
||||
|
// the value if it is a protocol buffer, or print the raw bytes in the
|
||||
|
// value otherwise.
|
||||
|
//
|
||||
|
// To aid debugging: when T is a reference type, the address of the
|
||||
|
// value is also printed; when T is a (const) char pointer, both the
|
||||
|
// pointer value and the NUL-terminated string it points to are
|
||||
|
// printed.
|
||||
|
//
|
||||
|
// We also provide some convenient wrappers:
|
||||
|
//
|
||||
|
// // Prints a value to a string. For a (const or not) char
|
||||
|
// // pointer, the NUL-terminated string (but not the pointer) is
|
||||
|
// // printed.
|
||||
|
// std::string ::testing::PrintToString(const T& value);
|
||||
|
//
|
||||
|
// // Prints a value tersely: for a reference type, the referenced
|
||||
|
// // value (but not the address) is printed; for a (const or not) char
|
||||
|
// // pointer, the NUL-terminated string (but not the pointer) is
|
||||
|
// // printed.
|
||||
|
// void ::testing::internal::UniversalTersePrint(const T& value, ostream*);
|
||||
|
//
|
||||
|
// // Prints value using the type inferred by the compiler. The difference
|
||||
|
// // from UniversalTersePrint() is that this function prints both the
|
||||
|
// // pointer and the NUL-terminated string for a (const or not) char pointer.
|
||||
|
// void ::testing::internal::UniversalPrint(const T& value, ostream*);
|
||||
|
//
|
||||
|
// // Prints the fields of a tuple tersely to a string vector, one
|
||||
|
// // element for each field. Tuple support must be enabled in
|
||||
|
// // gtest-port.h.
|
||||
|
// std::vector<string> UniversalTersePrintTupleFieldsToStrings(
|
||||
|
// const Tuple& value);
|
||||
|
//
|
||||
|
// Known limitation:
|
||||
|
//
|
||||
|
// The print primitives print the elements of an STL-style container
|
||||
|
// using the compiler-inferred type of *iter where iter is a
|
||||
|
// const_iterator of the container. When const_iterator is an input
|
||||
|
// iterator but not a forward iterator, this inferred type may not
|
||||
|
// match value_type, and the print output may be incorrect. In
|
||||
|
// practice, this is rarely a problem as for most containers
|
||||
|
// const_iterator is a forward iterator. We'll fix this if there's an
|
||||
|
// actual need for it. Note that this fix cannot rely on value_type
|
||||
|
// being defined as many user-defined container types don't have
|
||||
|
// value_type.
|
||||
|
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ |
||||
|
#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ |
||||
|
|
||||
|
#include <ostream> // NOLINT |
||||
|
#include <sstream> |
||||
|
#include <string> |
||||
|
#include <utility> |
||||
|
#include <vector> |
||||
|
#include "gtest/internal/gtest-port.h" |
||||
|
#include "gtest/internal/gtest-internal.h" |
||||
|
|
||||
|
#if GTEST_HAS_STD_TUPLE_ |
||||
|
# include <tuple> |
||||
|
#endif |
||||
|
|
||||
|
namespace testing { |
||||
|
|
||||
|
// Definitions in the 'internal' and 'internal2' name spaces are
|
||||
|
// subject to change without notice. DO NOT USE THEM IN USER CODE!
|
||||
|
namespace internal2 { |
||||
|
|
||||
|
// Prints the given number of bytes in the given object to the given
|
||||
|
// ostream.
|
||||
|
GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, |
||||
|
size_t count, |
||||
|
::std::ostream* os); |
||||
|
|
||||
|
// For selecting which printer to use when a given type has neither <<
|
||||
|
// nor PrintTo().
|
||||
|
enum TypeKind { |
||||
|
kProtobuf, // a protobuf type
|
||||
|
kConvertibleToInteger, // a type implicitly convertible to BiggestInt
|
||||
|
// (e.g. a named or unnamed enum type)
|
||||
|
kOtherType // anything else
|
||||
|
}; |
||||
|
|
||||
|
// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
|
||||
|
// by the universal printer to print a value of type T when neither
|
||||
|
// operator<< nor PrintTo() is defined for T, where kTypeKind is the
|
||||
|
// "kind" of T as defined by enum TypeKind.
|
||||
|
template <typename T, TypeKind kTypeKind> |
||||
|
class TypeWithoutFormatter { |
||||
|
public: |
||||
|
// This default version is called when kTypeKind is kOtherType.
|
||||
|
static void PrintValue(const T& value, ::std::ostream* os) { |
||||
|
PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value), |
||||
|
sizeof(value), os); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// We print a protobuf using its ShortDebugString() when the string
|
||||
|
// doesn't exceed this many characters; otherwise we print it using
|
||||
|
// DebugString() for better readability.
|
||||
|
const size_t kProtobufOneLinerMaxLength = 50; |
||||
|
|
||||
|
template <typename T> |
||||
|
class TypeWithoutFormatter<T, kProtobuf> { |
||||
|
public: |
||||
|
static void PrintValue(const T& value, ::std::ostream* os) { |
||||
|
const ::testing::internal::string short_str = value.ShortDebugString(); |
||||
|
const ::testing::internal::string pretty_str = |
||||
|
short_str.length() <= kProtobufOneLinerMaxLength ? |
||||
|
short_str : ("\n" + value.DebugString()); |
||||
|
*os << ("<" + pretty_str + ">"); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
template <typename T> |
||||
|
class TypeWithoutFormatter<T, kConvertibleToInteger> { |
||||
|
public: |
||||
|
// Since T has no << operator or PrintTo() but can be implicitly
|
||||
|
// converted to BiggestInt, we print it as a BiggestInt.
|
||||
|
//
|
||||
|
// Most likely T is an enum type (either named or unnamed), in which
|
||||
|
// case printing it as an integer is the desired behavior. In case
|
||||
|
// T is not an enum, printing it as an integer is the best we can do
|
||||
|
// given that it has no user-defined printer.
|
||||
|
static void PrintValue(const T& value, ::std::ostream* os) { |
||||
|
const internal::BiggestInt kBigInt = value; |
||||
|
*os << kBigInt; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// Prints the given value to the given ostream. If the value is a
|
||||
|
// protocol message, its debug string is printed; if it's an enum or
|
||||
|
// of a type implicitly convertible to BiggestInt, it's printed as an
|
||||
|
// integer; otherwise the bytes in the value are printed. This is
|
||||
|
// what UniversalPrinter<T>::Print() does when it knows nothing about
|
||||
|
// type T and T has neither << operator nor PrintTo().
|
||||
|
//
|
||||
|
// A user can override this behavior for a class type Foo by defining
|
||||
|
// a << operator in the namespace where Foo is defined.
|
||||
|
//
|
||||
|
// We put this operator in namespace 'internal2' instead of 'internal'
|
||||
|
// to simplify the implementation, as much code in 'internal' needs to
|
||||
|
// use << in STL, which would conflict with our own << were it defined
|
||||
|
// in 'internal'.
|
||||
|
//
|
||||
|
// Note that this operator<< takes a generic std::basic_ostream<Char,
|
||||
|
// CharTraits> type instead of the more restricted std::ostream. If
|
||||
|
// we define it to take an std::ostream instead, we'll get an
|
||||
|
// "ambiguous overloads" compiler error when trying to print a type
|
||||
|
// Foo that supports streaming to std::basic_ostream<Char,
|
||||
|
// CharTraits>, as the compiler cannot tell whether
|
||||
|
// operator<<(std::ostream&, const T&) or
|
||||
|
// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more
|
||||
|
// specific.
|
||||
|
template <typename Char, typename CharTraits, typename T> |
||||
|
::std::basic_ostream<Char, CharTraits>& operator<<( |
||||
|
::std::basic_ostream<Char, CharTraits>& os, const T& x) { |
||||
|
TypeWithoutFormatter<T, |
||||
|
(internal::IsAProtocolMessage<T>::value ? kProtobuf : |
||||
|
internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ? |
||||
|
kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); |
||||
|
return os; |
||||
|
} |
||||
|
|
||||
|
} // namespace internal2
|
||||
|
} // namespace testing
|
||||
|
|
||||
|
// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up
|
||||
|
// magic needed for implementing UniversalPrinter won't work.
|
||||
|
namespace testing_internal { |
||||
|
|
||||
|
// Used to print a value that is not an STL-style container when the
|
||||
|
// user doesn't define PrintTo() for it.
|
||||
|
template <typename T> |
||||
|
void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { |
||||
|
// With the following statement, during unqualified name lookup,
|
||||
|
// testing::internal2::operator<< appears as if it was declared in
|
||||
|
// the nearest enclosing namespace that contains both
|
||||
|
// ::testing_internal and ::testing::internal2, i.e. the global
|
||||
|
// namespace. For more details, refer to the C++ Standard section
|
||||
|
// 7.3.4-1 [namespace.udir]. This allows us to fall back onto
|
||||
|
// testing::internal2::operator<< in case T doesn't come with a <<
|
||||
|
// operator.
|
||||
|
//
|
||||
|
// We cannot write 'using ::testing::internal2::operator<<;', which
|
||||
|
// gcc 3.3 fails to compile due to a compiler bug.
|
||||
|
using namespace ::testing::internal2; // NOLINT
|
||||
|
|
||||
|
// Assuming T is defined in namespace foo, in the next statement,
|
||||
|
// the compiler will consider all of:
|
||||
|
//
|
||||
|
// 1. foo::operator<< (thanks to Koenig look-up),
|
||||
|
// 2. ::operator<< (as the current namespace is enclosed in ::),
|
||||
|
// 3. testing::internal2::operator<< (thanks to the using statement above).
|
||||
|
//
|
||||
|
// The operator<< whose type matches T best will be picked.
|
||||
|
//
|
||||
|
// We deliberately allow #2 to be a candidate, as sometimes it's
|
||||
|
// impossible to define #1 (e.g. when foo is ::std, defining
|
||||
|
// anything in it is undefined behavior unless you are a compiler
|
||||
|
// vendor.).
|
||||
|
*os << value; |
||||
|
} |
||||
|
|
||||
|
} // namespace testing_internal
|
||||
|
|
||||
|
namespace testing { |
||||
|
namespace internal { |
||||
|
|
||||
|
// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
|
||||
|
// value to the given ostream. The caller must ensure that
|
||||
|
// 'ostream_ptr' is not NULL, or the behavior is undefined.
|
||||
|
//
|
||||
|
// We define UniversalPrinter as a class template (as opposed to a
|
||||
|
// function template), as we need to partially specialize it for
|
||||
|
// reference types, which cannot be done with function templates.
|
||||
|
template <typename T> |
||||
|
class UniversalPrinter; |
||||
|
|
||||
|
template <typename T> |
||||
|
void UniversalPrint(const T& value, ::std::ostream* os); |
||||
|
|
||||
|
// Used to print an STL-style container when the user doesn't define
|
||||
|
// a PrintTo() for it.
|
||||
|
template <typename C> |
||||
|
void DefaultPrintTo(IsContainer /* dummy */, |
||||
|
false_type /* is not a pointer */, |
||||
|
const C& container, ::std::ostream* os) { |
||||
|
const size_t kMaxCount = 32; // The maximum number of elements to print.
|
||||
|
*os << '{'; |
||||
|
size_t count = 0; |
||||
|
for (typename C::const_iterator it = container.begin(); |
||||
|
it != container.end(); ++it, ++count) { |
||||
|
if (count > 0) { |
||||
|
*os << ','; |
||||
|
if (count == kMaxCount) { // Enough has been printed.
|
||||
|
*os << " ..."; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
*os << ' '; |
||||
|
// We cannot call PrintTo(*it, os) here as PrintTo() doesn't
|
||||
|
// handle *it being a native array.
|
||||
|
internal::UniversalPrint(*it, os); |
||||
|
} |
||||
|
|
||||
|
if (count > 0) { |
||||
|
*os << ' '; |
||||
|
} |
||||
|
*os << '}'; |
||||
|
} |
||||
|
|
||||
|
// Used to print a pointer that is neither a char pointer nor a member
|
||||
|
// pointer, when the user doesn't define PrintTo() for it. (A member
|
||||
|
// variable pointer or member function pointer doesn't really point to
|
||||
|
// a location in the address space. Their representation is
|
||||
|
// implementation-defined. Therefore they will be printed as raw
|
||||
|
// bytes.)
|
||||
|
template <typename T> |
||||
|
void DefaultPrintTo(IsNotContainer /* dummy */, |
||||
|
true_type /* is a pointer */, |
||||
|
T* p, ::std::ostream* os) { |
||||
|
if (p == NULL) { |
||||
|
*os << "NULL"; |
||||
|
} else { |
||||
|
// C++ doesn't allow casting from a function pointer to any object
|
||||
|
// pointer.
|
||||
|
//
|
||||
|
// IsTrue() silences warnings: "Condition is always true",
|
||||
|
// "unreachable code".
|
||||
|
if (IsTrue(ImplicitlyConvertible<T*, const void*>::value)) { |
||||
|
// T is not a function type. We just call << to print p,
|
||||
|
// relying on ADL to pick up user-defined << for their pointer
|
||||
|
// types, if any.
|
||||
|
*os << p; |
||||
|
} else { |
||||
|
// T is a function type, so '*os << p' doesn't do what we want
|
||||
|
// (it just prints p as bool). We want to print p as a const
|
||||
|
// void*. However, we cannot cast it to const void* directly,
|
||||
|
// even using reinterpret_cast, as earlier versions of gcc
|
||||
|
// (e.g. 3.4.5) cannot compile the cast when p is a function
|
||||
|
// pointer. Casting to UInt64 first solves the problem.
|
||||
|
*os << reinterpret_cast<const void*>( |
||||
|
reinterpret_cast<internal::UInt64>(p)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Used to print a non-container, non-pointer value when the user
|
||||
|
// doesn't define PrintTo() for it.
|
||||
|
template <typename T> |
||||
|
void DefaultPrintTo(IsNotContainer /* dummy */, |
||||
|
false_type /* is not a pointer */, |
||||
|
const T& value, ::std::ostream* os) { |
||||
|
::testing_internal::DefaultPrintNonContainerTo(value, os); |
||||
|
} |
||||
|
|
||||
|
// Prints the given value using the << operator if it has one;
|
||||
|
// otherwise prints the bytes in it. This is what
|
||||
|
// UniversalPrinter<T>::Print() does when PrintTo() is not specialized
|
||||
|
// or overloaded for type T.
|
||||
|
//
|
||||
|
// A user can override this behavior for a class type Foo by defining
|
||||
|
// an overload of PrintTo() in the namespace where Foo is defined. We
|
||||
|
// give the user this option as sometimes defining a << operator for
|
||||
|
// Foo is not desirable (e.g. the coding style may prevent doing it,
|
||||
|
// or there is already a << operator but it doesn't do what the user
|
||||
|
// wants).
|
||||
|
template <typename T> |
||||
|
void PrintTo(const T& value, ::std::ostream* os) { |
||||
|
// DefaultPrintTo() is overloaded. The type of its first two
|
||||
|
// arguments determine which version will be picked. If T is an
|
||||
|
// STL-style container, the version for container will be called; if
|
||||
|
// T is a pointer, the pointer version will be called; otherwise the
|
||||
|
// generic version will be called.
|
||||
|
//
|
||||
|
// Note that we check for container types here, prior to we check
|
||||
|
// for protocol message types in our operator<<. The rationale is:
|
||||
|
//
|
||||
|
// For protocol messages, we want to give people a chance to
|
||||
|
// override Google Mock's format by defining a PrintTo() or
|
||||
|
// operator<<. For STL containers, other formats can be
|
||||
|
// incompatible with Google Mock's format for the container
|
||||
|
// elements; therefore we check for container types here to ensure
|
||||
|
// that our format is used.
|
||||
|
//
|
||||
|
// The second argument of DefaultPrintTo() is needed to bypass a bug
|
||||
|
// in Symbian's C++ compiler that prevents it from picking the right
|
||||
|
// overload between:
|
||||
|
//
|
||||
|
// PrintTo(const T& x, ...);
|
||||
|
// PrintTo(T* x, ...);
|
||||
|
DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), value, os); |
||||
|
} |
||||
|
|
||||
|
// The following list of PrintTo() overloads tells
|
||||
|
// UniversalPrinter<T>::Print() how to print standard types (built-in
|
||||
|
// types, strings, plain arrays, and pointers).
|
||||
|
|
||||
|
// Overloads for various char types.
|
||||
|
GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); |
||||
|
GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); |
||||
|
inline void PrintTo(char c, ::std::ostream* os) { |
||||
|
// When printing a plain char, we always treat it as unsigned. This
|
||||
|
// way, the output won't be affected by whether the compiler thinks
|
||||
|
// char is signed or not.
|
||||
|
PrintTo(static_cast<unsigned char>(c), os); |
||||
|
} |
||||
|
|
||||
|
// Overloads for other simple built-in types.
|
||||
|
inline void PrintTo(bool x, ::std::ostream* os) { |
||||
|
*os << (x ? "true" : "false"); |
||||
|
} |
||||
|
|
||||
|
// Overload for wchar_t type.
|
||||
|
// Prints a wchar_t as a symbol if it is printable or as its internal
|
||||
|
// code otherwise and also as its decimal code (except for L'\0').
|
||||
|
// The L'\0' char is printed as "L'\\0'". The decimal code is printed
|
||||
|
// as signed integer when wchar_t is implemented by the compiler
|
||||
|
// as a signed type and is printed as an unsigned integer when wchar_t
|
||||
|
// is implemented as an unsigned type.
|
||||
|
GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); |
||||
|
|
||||
|
// Overloads for C strings.
|
||||
|
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); |
||||
|
inline void PrintTo(char* s, ::std::ostream* os) { |
||||
|
PrintTo(ImplicitCast_<const char*>(s), os); |
||||
|
} |
||||
|
|
||||
|
// signed/unsigned char is often used for representing binary data, so
|
||||
|
// we print pointers to it as void* to be safe.
|
||||
|
inline void PrintTo(const signed char* s, ::std::ostream* os) { |
||||
|
PrintTo(ImplicitCast_<const void*>(s), os); |
||||
|
} |
||||
|
inline void PrintTo(signed char* s, ::std::ostream* os) { |
||||
|
PrintTo(ImplicitCast_<const void*>(s), os); |
||||
|
} |
||||
|
inline void PrintTo(const unsigned char* s, ::std::ostream* os) { |
||||
|
PrintTo(ImplicitCast_<const void*>(s), os); |
||||
|
} |
||||
|
inline void PrintTo(unsigned char* s, ::std::ostream* os) { |
||||
|
PrintTo(ImplicitCast_<const void*>(s), os); |
||||
|
} |
||||
|
|
||||
|
// MSVC can be configured to define wchar_t as a typedef of unsigned
|
||||
|
// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
|
||||
|
// type. When wchar_t is a typedef, defining an overload for const
|
||||
|
// wchar_t* would cause unsigned short* be printed as a wide string,
|
||||
|
// possibly causing invalid memory accesses.
|
||||
|
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) |
||||
|
// Overloads for wide C strings
|
||||
|
GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); |
||||
|
inline void PrintTo(wchar_t* s, ::std::ostream* os) { |
||||
|
PrintTo(ImplicitCast_<const wchar_t*>(s), os); |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
// Overload for C arrays. Multi-dimensional arrays are printed
|
||||
|
// properly.
|
||||
|
|
||||
|
// Prints the given number of elements in an array, without printing
|
||||
|
// the curly braces.
|
||||
|
template <typename T> |
||||
|
void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { |
||||
|
UniversalPrint(a[0], os); |
||||
|
for (size_t i = 1; i != count; i++) { |
||||
|
*os << ", "; |
||||
|
UniversalPrint(a[i], os); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Overloads for ::string and ::std::string.
|
||||
|
#if GTEST_HAS_GLOBAL_STRING |
||||
|
GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os); |
||||
|
inline void PrintTo(const ::string& s, ::std::ostream* os) { |
||||
|
PrintStringTo(s, os); |
||||
|
} |
||||
|
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
|
||||
|
GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); |
||||
|
inline void PrintTo(const ::std::string& s, ::std::ostream* os) { |
||||
|
PrintStringTo(s, os); |
||||
|
} |
||||
|
|
||||
|
// Overloads for ::wstring and ::std::wstring.
|
||||
|
#if GTEST_HAS_GLOBAL_WSTRING |
||||
|
GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os); |
||||
|
inline void PrintTo(const ::wstring& s, ::std::ostream* os) { |
||||
|
PrintWideStringTo(s, os); |
||||
|
} |
||||
|
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
|
||||
|
#if GTEST_HAS_STD_WSTRING |
||||
|
GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); |
||||
|
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { |
||||
|
PrintWideStringTo(s, os); |
||||
|
} |
||||
|
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
|
||||
|
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ |
||||
|
// Helper function for printing a tuple. T must be instantiated with
|
||||
|
// a tuple type.
|
||||
|
template <typename T> |
||||
|
void PrintTupleTo(const T& t, ::std::ostream* os); |
||||
|
#endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
||||
|
|
||||
|
#if GTEST_HAS_TR1_TUPLE |
||||
|
// Overload for ::std::tr1::tuple. Needed for printing function arguments,
|
||||
|
// which are packed as tuples.
|
||||
|
|
||||
|
// Overloaded PrintTo() for tuples of various arities. We support
|
||||
|
// tuples of up-to 10 fields. The following implementation works
|
||||
|
// regardless of whether tr1::tuple is implemented using the
|
||||
|
// non-standard variadic template feature or not.
|
||||
|
|
||||
|
inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) { |
||||
|
PrintTupleTo(t, os); |
||||
|
} |
||||
|
|
||||
|
template <typename T1> |
||||
|
void PrintTo(const ::std::tr1::tuple<T1>& t, ::std::ostream* os) { |
||||
|
PrintTupleTo(t, os); |
||||
|
} |
||||
|
|
||||
|
template <typename T1, typename T2> |
||||
|
void PrintTo(const ::std::tr1::tuple<T1, T2>& t, ::std::ostream* os) { |
||||
|
PrintTupleTo(t, os); |
||||
|
} |
||||
|
|
||||
|
template <typename T1, typename T2, typename T3> |
||||
|
void PrintTo(const ::std::tr1::tuple<T1, T2, T3>& t, ::std::ostream* os) { |
||||
|
PrintTupleTo(t, os); |
||||
|
} |
||||
|
|
||||
|
template <typename T1, typename T2, typename T3, typename T4> |
||||
|
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4>& t, ::std::ostream* os) { |
||||
|
PrintTupleTo(t, os); |
||||
|
} |
||||
|
|
||||
|
template <typename T1, typename T2, typename T3, typename T4, typename T5> |
||||
|
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5>& t, |
||||
|
::std::ostream* os) { |
||||
|
PrintTupleTo(t, os); |
||||
|
} |
||||
|
|
||||
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, |
||||
|
typename T6> |
||||
|
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6>& t, |
||||
|
::std::ostream* os) { |
||||
|
PrintTupleTo(t, os); |
||||
|
} |
||||
|
|
||||
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, |
||||
|
typename T6, typename T7> |
||||
|
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7>& t, |
||||
|
::std::ostream* os) { |
||||
|
PrintTupleTo(t, os); |
||||
|
} |
||||
|
|
||||
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, |
||||
|
typename T6, typename T7, typename T8> |
||||
|
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8>& t, |
||||
|
::std::ostream* os) { |
||||
|
PrintTupleTo(t, os); |
||||
|
} |
||||
|
|
||||
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, |
||||
|
typename T6, typename T7, typename T8, typename T9> |
||||
|
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t, |
||||
|
::std::ostream* os) { |
||||
|
PrintTupleTo(t, os); |
||||
|
} |
||||
|
|
||||
|
template <typename T1, typename T2, typename T3, typename T4, typename T5, |
||||
|
typename T6, typename T7, typename T8, typename T9, typename T10> |
||||
|
void PrintTo( |
||||
|
const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t, |
||||
|
::std::ostream* os) { |
||||
|
PrintTupleTo(t, os); |
||||
|
} |
||||
|
#endif // GTEST_HAS_TR1_TUPLE
|
||||
|
|
||||
|
#if GTEST_HAS_STD_TUPLE_ |
||||
|
template <typename... Types> |
||||
|
void PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) { |
||||
|
PrintTupleTo(t, os); |
||||
|
} |
||||
|
#endif // GTEST_HAS_STD_TUPLE_
|
||||
|
|
||||
|
// Overload for std::pair.
|
||||
|
template <typename T1, typename T2> |
||||
|
void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) { |
||||
|
*os << '('; |
||||
|
// We cannot use UniversalPrint(value.first, os) here, as T1 may be
|
||||
|
// a reference type. The same for printing value.second.
|
||||
|
UniversalPrinter<T1>::Print(value.first, os); |
||||
|
*os << ", "; |
||||
|
UniversalPrinter<T2>::Print(value.second, os); |
||||
|
*os << ')'; |
||||
|
} |
||||
|
|
||||
|
// Implements printing a non-reference type T by letting the compiler
|
||||
|
// pick the right overload of PrintTo() for T.
|
||||
|
template <typename T> |
||||
|
class UniversalPrinter { |
||||
|
public: |
||||
|
// MSVC warns about adding const to a function type, so we want to
|
||||
|
// disable the warning.
|
||||
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) |
||||
|
|
||||
|
// Note: we deliberately don't call this PrintTo(), as that name
|
||||
|
// conflicts with ::testing::internal::PrintTo in the body of the
|
||||
|
// function.
|
||||
|
static void Print(const T& value, ::std::ostream* os) { |
||||
|
// By default, ::testing::internal::PrintTo() is used for printing
|
||||
|
// the value.
|
||||
|
//
|
||||
|
// Thanks to Koenig look-up, if T is a class and has its own
|
||||
|
// PrintTo() function defined in its namespace, that function will
|
||||
|
// be visible here. Since it is more specific than the generic ones
|
||||
|
// in ::testing::internal, it will be picked by the compiler in the
|
||||
|
// following statement - exactly what we want.
|
||||
|
PrintTo(value, os); |
||||
|
} |
||||
|
|
||||
|
GTEST_DISABLE_MSC_WARNINGS_POP_() |
||||
|
}; |
||||
|
|
||||
|
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
||||
|
// elements, starting at address 'begin'.
|
||||
|
template <typename T> |
||||
|
void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { |
||||
|
if (len == 0) { |
||||
|
*os << "{}"; |
||||
|
} else { |
||||
|
*os << "{ "; |
||||
|
const size_t kThreshold = 18; |
||||
|
const size_t kChunkSize = 8; |
||||
|
// If the array has more than kThreshold elements, we'll have to
|
||||
|
// omit some details by printing only the first and the last
|
||||
|
// kChunkSize elements.
|
||||
|
// TODO(wan@google.com): let the user control the threshold using a flag.
|
||||
|
if (len <= kThreshold) { |
||||
|
PrintRawArrayTo(begin, len, os); |
||||
|
} else { |
||||
|
PrintRawArrayTo(begin, kChunkSize, os); |
||||
|
*os << ", ..., "; |
||||
|
PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); |
||||
|
} |
||||
|
*os << " }"; |
||||
|
} |
||||
|
} |
||||
|
// This overload prints a (const) char array compactly.
|
||||
|
GTEST_API_ void UniversalPrintArray( |
||||
|
const char* begin, size_t len, ::std::ostream* os); |
||||
|
|
||||
|
// This overload prints a (const) wchar_t array compactly.
|
||||
|
GTEST_API_ void UniversalPrintArray( |
||||
|
const wchar_t* begin, size_t len, ::std::ostream* os); |
||||
|
|
||||
|
// Implements printing an array type T[N].
|
||||
|
template <typename T, size_t N> |
||||
|
class UniversalPrinter<T[N]> { |
||||
|
public: |
||||
|
// Prints the given array, omitting some elements when there are too
|
||||
|
// many.
|
||||
|
static void Print(const T (&a)[N], ::std::ostream* os) { |
||||
|
UniversalPrintArray(a, N, os); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// Implements printing a reference type T&.
|
||||
|
template <typename T> |
||||
|
class UniversalPrinter<T&> { |
||||
|
public: |
||||
|
// MSVC warns about adding const to a function type, so we want to
|
||||
|
// disable the warning.
|
||||
|
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) |
||||
|
|
||||
|
static void Print(const T& value, ::std::ostream* os) { |
||||
|
// Prints the address of the value. We use reinterpret_cast here
|
||||
|
// as static_cast doesn't compile when T is a function type.
|
||||
|
*os << "@" << reinterpret_cast<const void*>(&value) << " "; |
||||
|
|
||||
|
// Then prints the value itself.
|
||||
|
UniversalPrint(value, os); |
||||
|
} |
||||
|
|
||||
|
GTEST_DISABLE_MSC_WARNINGS_POP_() |
||||
|
}; |
||||
|
|
||||
|
// Prints a value tersely: for a reference type, the referenced value
|
||||
|
// (but not the address) is printed; for a (const) char pointer, the
|
||||
|
// NUL-terminated string (but not the pointer) is printed.
|
||||
|
|
||||
|
template <typename T> |
||||
|
class UniversalTersePrinter { |
||||
|
public: |
||||
|
static void Print(const T& value, ::std::ostream* os) { |
||||
|
UniversalPrint(value, os); |
||||
|
} |
||||
|
}; |
||||
|
template <typename T> |
||||
|
class UniversalTersePrinter<T&> { |
||||
|
public: |
||||
|
static void Print(const T& value, ::std::ostream* os) { |
||||
|
UniversalPrint(value, os); |
||||
|
} |
||||
|
}; |
||||
|
template <typename T, size_t N> |
||||
|
class UniversalTersePrinter<T[N]> { |
||||
|
public: |
||||
|
static void Print(const T (&value)[N], ::std::ostream* os) { |
||||
|
UniversalPrinter<T[N]>::Print(value, os); |
||||
|
} |
||||
|
}; |
||||
|
template <> |
||||
|
class UniversalTersePrinter<const char*> { |
||||
|
public: |
||||
|
static void Print(const char* str, ::std::ostream* os) { |
||||
|
if (str == NULL) { |
||||
|
*os << "NULL"; |
||||
|
} else { |
||||
|
UniversalPrint(string(str), os); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
template <> |
||||
|
class UniversalTersePrinter<char*> { |
||||
|
public: |
||||
|
static void Print(char* str, ::std::ostream* os) { |
||||
|
UniversalTersePrinter<const char*>::Print(str, os); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
#if GTEST_HAS_STD_WSTRING |
||||
|
template <> |
||||
|
class UniversalTersePrinter<const wchar_t*> { |
||||
|
public: |
||||
|
static void Print(const wchar_t* str, ::std::ostream* os) { |
||||
|
if (str == NULL) { |
||||
|
*os << "NULL"; |
||||
|
} else { |
||||
|
UniversalPrint(::std::wstring(str), os); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
#endif |
||||
|
|
||||
|
template <> |
||||
|
class UniversalTersePrinter<wchar_t*> { |
||||
|
public: |
||||
|
static void Print(wchar_t* str, ::std::ostream* os) { |
||||
|
UniversalTersePrinter<const wchar_t*>::Print(str, os); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
template <typename T> |
||||
|
void UniversalTersePrint(const T& value, ::std::ostream* os) { |
||||
|
UniversalTersePrinter<T>::Print(value, os); |
||||
|
} |
||||
|
|
||||
|
// Prints a value using the type inferred by the compiler. The
|
||||
|
// difference between this and UniversalTersePrint() is that for a
|
||||
|
// (const) char pointer, this prints both the pointer and the
|
||||
|
// NUL-terminated string.
|
||||
|
template <typename T> |
||||
|
void UniversalPrint(const T& value, ::std::ostream* os) { |
||||
|
// A workarond for the bug in VC++ 7.1 that prevents us from instantiating
|
||||
|
// UniversalPrinter with T directly.
|
||||
|
typedef T T1; |
||||
|
UniversalPrinter<T1>::Print(value, os); |
||||
|
} |
||||
|
|
||||
|
typedef ::std::vector<string> Strings; |
||||
|
|
||||
|
// TuplePolicy<TupleT> must provide:
|
||||
|
// - tuple_size
|
||||
|
// size of tuple TupleT.
|
||||
|
// - get<size_t I>(const TupleT& t)
|
||||
|
// static function extracting element I of tuple TupleT.
|
||||
|
// - tuple_element<size_t I>::type
|
||||
|
// type of element I of tuple TupleT.
|
||||
|
template <typename TupleT> |
||||
|
struct TuplePolicy; |
||||
|
|
||||
|
#if GTEST_HAS_TR1_TUPLE |
||||
|
template <typename TupleT> |
||||
|
struct TuplePolicy { |
||||
|
typedef TupleT Tuple; |
||||
|
static const size_t tuple_size = ::std::tr1::tuple_size<Tuple>::value; |
||||
|
|
||||
|
template <size_t I> |
||||
|
struct tuple_element : ::std::tr1::tuple_element<I, Tuple> {}; |
||||
|
|
||||
|
template <size_t I> |
||||
|
static typename AddReference< |
||||
|
const typename ::std::tr1::tuple_element<I, Tuple>::type>::type get( |
||||
|
const Tuple& tuple) { |
||||
|
return ::std::tr1::get<I>(tuple); |
||||
|
} |
||||
|
}; |
||||
|
template <typename TupleT> |
||||
|
const size_t TuplePolicy<TupleT>::tuple_size; |
||||
|
#endif // GTEST_HAS_TR1_TUPLE
|
||||
|
|
||||
|
#if GTEST_HAS_STD_TUPLE_ |
||||
|
template <typename... Types> |
||||
|
struct TuplePolicy< ::std::tuple<Types...> > { |
||||
|
typedef ::std::tuple<Types...> Tuple; |
||||
|
static const size_t tuple_size = ::std::tuple_size<Tuple>::value; |
||||
|
|
||||
|
template <size_t I> |
||||
|
struct tuple_element : ::std::tuple_element<I, Tuple> {}; |
||||
|
|
||||
|
template <size_t I> |
||||
|
static const typename ::std::tuple_element<I, Tuple>::type& get( |
||||
|
const Tuple& tuple) { |
||||
|
return ::std::get<I>(tuple); |
||||
|
} |
||||
|
}; |
||||
|
template <typename... Types> |
||||
|
const size_t TuplePolicy< ::std::tuple<Types...> >::tuple_size; |
||||
|
#endif // GTEST_HAS_STD_TUPLE_
|
||||
|
|
||||
|
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ |
||||
|
// This helper template allows PrintTo() for tuples and
|
||||
|
// UniversalTersePrintTupleFieldsToStrings() to be defined by
|
||||
|
// induction on the number of tuple fields. The idea is that
|
||||
|
// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
|
||||
|
// fields in tuple t, and can be defined in terms of
|
||||
|
// TuplePrefixPrinter<N - 1>.
|
||||
|
//
|
||||
|
// The inductive case.
|
||||
|
template <size_t N> |
||||
|
struct TuplePrefixPrinter { |
||||
|
// Prints the first N fields of a tuple.
|
||||
|
template <typename Tuple> |
||||
|
static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { |
||||
|
TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os); |
||||
|
GTEST_INTENTIONAL_CONST_COND_PUSH_() |
||||
|
if (N > 1) { |
||||
|
GTEST_INTENTIONAL_CONST_COND_POP_() |
||||
|
*os << ", "; |
||||
|
} |
||||
|
UniversalPrinter< |
||||
|
typename TuplePolicy<Tuple>::template tuple_element<N - 1>::type> |
||||
|
::Print(TuplePolicy<Tuple>::template get<N - 1>(t), os); |
||||
|
} |
||||
|
|
||||
|
// Tersely prints the first N fields of a tuple to a string vector,
|
||||
|
// one element for each field.
|
||||
|
template <typename Tuple> |
||||
|
static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { |
||||
|
TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings); |
||||
|
::std::stringstream ss; |
||||
|
UniversalTersePrint(TuplePolicy<Tuple>::template get<N - 1>(t), &ss); |
||||
|
strings->push_back(ss.str()); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// Base case.
|
||||
|
template <> |
||||
|
struct TuplePrefixPrinter<0> { |
||||
|
template <typename Tuple> |
||||
|
static void PrintPrefixTo(const Tuple&, ::std::ostream*) {} |
||||
|
|
||||
|
template <typename Tuple> |
||||
|
static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} |
||||
|
}; |
||||
|
|
||||
|
// Helper function for printing a tuple.
|
||||
|
// Tuple must be either std::tr1::tuple or std::tuple type.
|
||||
|
template <typename Tuple> |
||||
|
void PrintTupleTo(const Tuple& t, ::std::ostream* os) { |
||||
|
*os << "("; |
||||
|
TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>::PrintPrefixTo(t, os); |
||||
|
*os << ")"; |
||||
|
} |
||||
|
|
||||
|
// Prints the fields of a tuple tersely to a string vector, one
|
||||
|
// element for each field. See the comment before
|
||||
|
// UniversalTersePrint() for how we define "tersely".
|
||||
|
template <typename Tuple> |
||||
|
Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { |
||||
|
Strings result; |
||||
|
TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>:: |
||||
|
TersePrintPrefixToStrings(value, &result); |
||||
|
return result; |
||||
|
} |
||||
|
#endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
||||
|
|
||||
|
} // namespace internal
|
||||
|
|
||||
|
template <typename T> |
||||
|
::std::string PrintToString(const T& value) { |
||||
|
::std::stringstream ss; |
||||
|
internal::UniversalTersePrinter<T>::Print(value, &ss); |
||||
|
return ss.str(); |
||||
|
} |
||||
|
|
||||
|
} // namespace testing
|
||||
|
|
||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
@ -0,0 +1,232 @@ |
|||||
|
// Copyright 2007, 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)
|
||||
|
//
|
||||
|
// Utilities for testing Google Test itself and code that uses Google Test
|
||||
|
// (e.g. frameworks built on top of Google Test).
|
||||
|
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ |
||||
|
#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ |
||||
|
|
||||
|
#include "gtest/gtest.h" |
||||
|
|
||||
|
namespace testing { |
||||
|
|
||||
|
// This helper class can be used to mock out Google Test failure reporting
|
||||
|
// so that we can test Google Test or code that builds on Google Test.
|
||||
|
//
|
||||
|
// An object of this class appends a TestPartResult object to the
|
||||
|
// TestPartResultArray object given in the constructor whenever a Google Test
|
||||
|
// failure is reported. It can either intercept only failures that are
|
||||
|
// generated in the same thread that created this object or it can intercept
|
||||
|
// all generated failures. The scope of this mock object can be controlled with
|
||||
|
// the second argument to the two arguments constructor.
|
||||
|
class GTEST_API_ ScopedFakeTestPartResultReporter |
||||
|
: public TestPartResultReporterInterface { |
||||
|
public: |
||||
|
// The two possible mocking modes of this object.
|
||||
|
enum InterceptMode { |
||||
|
INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures.
|
||||
|
INTERCEPT_ALL_THREADS // Intercepts all failures.
|
||||
|
}; |
||||
|
|
||||
|
// The c'tor sets this object as the test part result reporter used
|
||||
|
// by Google Test. The 'result' parameter specifies where to report the
|
||||
|
// results. This reporter will only catch failures generated in the current
|
||||
|
// thread. DEPRECATED
|
||||
|
explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); |
||||
|
|
||||
|
// Same as above, but you can choose the interception scope of this object.
|
||||
|
ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, |
||||
|
TestPartResultArray* result); |
||||
|
|
||||
|
// The d'tor restores the previous test part result reporter.
|
||||
|
virtual ~ScopedFakeTestPartResultReporter(); |
||||
|
|
||||
|
// Appends the TestPartResult object to the TestPartResultArray
|
||||
|
// received in the constructor.
|
||||
|
//
|
||||
|
// This method is from the TestPartResultReporterInterface
|
||||
|
// interface.
|
||||
|
virtual void ReportTestPartResult(const TestPartResult& result); |
||||
|
private: |
||||
|
void Init(); |
||||
|
|
||||
|
const InterceptMode intercept_mode_; |
||||
|
TestPartResultReporterInterface* old_reporter_; |
||||
|
TestPartResultArray* const result_; |
||||
|
|
||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); |
||||
|
}; |
||||
|
|
||||
|
namespace internal { |
||||
|
|
||||
|
// A helper class for implementing EXPECT_FATAL_FAILURE() and
|
||||
|
// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given
|
||||
|
// TestPartResultArray contains exactly one failure that has the given
|
||||
|
// type and contains the given substring. If that's not the case, a
|
||||
|
// non-fatal failure will be generated.
|
||||
|
class GTEST_API_ SingleFailureChecker { |
||||
|
public: |
||||
|
// The constructor remembers the arguments.
|
||||
|
SingleFailureChecker(const TestPartResultArray* results, |
||||
|
TestPartResult::Type type, |
||||
|
const string& substr); |
||||
|
~SingleFailureChecker(); |
||||
|
private: |
||||
|
const TestPartResultArray* const results_; |
||||
|
const TestPartResult::Type type_; |
||||
|
const string substr_; |
||||
|
|
||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); |
||||
|
}; |
||||
|
|
||||
|
} // namespace internal
|
||||
|
|
||||
|
} // namespace testing
|
||||
|
|
||||
|
// A set of macros for testing Google Test assertions or code that's expected
|
||||
|
// to generate Google Test fatal failures. It verifies that the given
|
||||
|
// statement will cause exactly one fatal Google Test failure with 'substr'
|
||||
|
// being part of the failure message.
|
||||
|
//
|
||||
|
// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
|
||||
|
// affects and considers failures generated in the current thread and
|
||||
|
// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
||||
|
//
|
||||
|
// The verification of the assertion is done correctly even when the statement
|
||||
|
// throws an exception or aborts the current function.
|
||||
|
//
|
||||
|
// Known restrictions:
|
||||
|
// - 'statement' cannot reference local non-static variables or
|
||||
|
// non-static members of the current object.
|
||||
|
// - 'statement' cannot return a value.
|
||||
|
// - You cannot stream a failure message to this macro.
|
||||
|
//
|
||||
|
// Note that even though the implementations of the following two
|
||||
|
// macros are much alike, we cannot refactor them to use a common
|
||||
|
// helper macro, due to some peculiarity in how the preprocessor
|
||||
|
// works. The AcceptsMacroThatExpandsToUnprotectedComma test in
|
||||
|
// gtest_unittest.cc will fail to compile if we do that.
|
||||
|
#define EXPECT_FATAL_FAILURE(statement, substr) \ |
||||
|
do { \ |
||||
|
class GTestExpectFatalFailureHelper {\ |
||||
|
public:\ |
||||
|
static void Execute() { statement; }\ |
||||
|
};\ |
||||
|
::testing::TestPartResultArray gtest_failures;\ |
||||
|
::testing::internal::SingleFailureChecker gtest_checker(\ |
||||
|
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ |
||||
|
{\ |
||||
|
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ |
||||
|
::testing::ScopedFakeTestPartResultReporter:: \ |
||||
|
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ |
||||
|
GTestExpectFatalFailureHelper::Execute();\ |
||||
|
}\ |
||||
|
} while (::testing::internal::AlwaysFalse()) |
||||
|
|
||||
|
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ |
||||
|
do { \ |
||||
|
class GTestExpectFatalFailureHelper {\ |
||||
|
public:\ |
||||
|
static void Execute() { statement; }\ |
||||
|
};\ |
||||
|
::testing::TestPartResultArray gtest_failures;\ |
||||
|
::testing::internal::SingleFailureChecker gtest_checker(\ |
||||
|
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ |
||||
|
{\ |
||||
|
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ |
||||
|
::testing::ScopedFakeTestPartResultReporter:: \ |
||||
|
INTERCEPT_ALL_THREADS, >est_failures);\ |
||||
|
GTestExpectFatalFailureHelper::Execute();\ |
||||
|
}\ |
||||
|
} while (::testing::internal::AlwaysFalse()) |
||||
|
|
||||
|
// A macro for testing Google Test assertions or code that's expected to
|
||||
|
// generate Google Test non-fatal failures. It asserts that the given
|
||||
|
// statement will cause exactly one non-fatal Google Test failure with 'substr'
|
||||
|
// being part of the failure message.
|
||||
|
//
|
||||
|
// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
|
||||
|
// affects and considers failures generated in the current thread and
|
||||
|
// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
||||
|
//
|
||||
|
// 'statement' is allowed to reference local variables and members of
|
||||
|
// the current object.
|
||||
|
//
|
||||
|
// The verification of the assertion is done correctly even when the statement
|
||||
|
// throws an exception or aborts the current function.
|
||||
|
//
|
||||
|
// Known restrictions:
|
||||
|
// - You cannot stream a failure message to this macro.
|
||||
|
//
|
||||
|
// Note that even though the implementations of the following two
|
||||
|
// macros are much alike, we cannot refactor them to use a common
|
||||
|
// helper macro, due to some peculiarity in how the preprocessor
|
||||
|
// works. If we do that, the code won't compile when the user gives
|
||||
|
// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
|
||||
|
// expands to code containing an unprotected comma. The
|
||||
|
// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
|
||||
|
// catches that.
|
||||
|
//
|
||||
|
// For the same reason, we have to write
|
||||
|
// if (::testing::internal::AlwaysTrue()) { statement; }
|
||||
|
// instead of
|
||||
|
// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
|
||||
|
// to avoid an MSVC warning on unreachable code.
|
||||
|
#define EXPECT_NONFATAL_FAILURE(statement, substr) \ |
||||
|
do {\ |
||||
|
::testing::TestPartResultArray gtest_failures;\ |
||||
|
::testing::internal::SingleFailureChecker gtest_checker(\ |
||||
|
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \ |
||||
|
(substr));\ |
||||
|
{\ |
||||
|
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ |
||||
|
::testing::ScopedFakeTestPartResultReporter:: \ |
||||
|
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ |
||||
|
if (::testing::internal::AlwaysTrue()) { statement; }\ |
||||
|
}\ |
||||
|
} while (::testing::internal::AlwaysFalse()) |
||||
|
|
||||
|
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ |
||||
|
do {\ |
||||
|
::testing::TestPartResultArray gtest_failures;\ |
||||
|
::testing::internal::SingleFailureChecker gtest_checker(\ |
||||
|
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \ |
||||
|
(substr));\ |
||||
|
{\ |
||||
|
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ |
||||
|
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ |
||||
|
>est_failures);\ |
||||
|
if (::testing::internal::AlwaysTrue()) { statement; }\ |
||||
|
}\ |
||||
|
} while (::testing::internal::AlwaysFalse()) |
||||
|
|
||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
@ -0,0 +1,179 @@ |
|||||
|
// Copyright 2008, 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: mheule@google.com (Markus Heule)
|
||||
|
//
|
||||
|
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ |
||||
|
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ |
||||
|
|
||||
|
#include <iosfwd> |
||||
|
#include <vector> |
||||
|
#include "gtest/internal/gtest-internal.h" |
||||
|
#include "gtest/internal/gtest-string.h" |
||||
|
|
||||
|
namespace testing { |
||||
|
|
||||
|
// A copyable object representing the result of a test part (i.e. an
|
||||
|
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
|
||||
|
//
|
||||
|
// Don't inherit from TestPartResult as its destructor is not virtual.
|
||||
|
class GTEST_API_ TestPartResult { |
||||
|
public: |
||||
|
// The possible outcomes of a test part (i.e. an assertion or an
|
||||
|
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
|
||||
|
enum Type { |
||||
|
kSuccess, // Succeeded.
|
||||
|
kNonFatalFailure, // Failed but the test can continue.
|
||||
|
kFatalFailure // Failed and the test should be terminated.
|
||||
|
}; |
||||
|
|
||||
|
// C'tor. TestPartResult does NOT have a default constructor.
|
||||
|
// Always use this constructor (with parameters) to create a
|
||||
|
// TestPartResult object.
|
||||
|
TestPartResult(Type a_type, |
||||
|
const char* a_file_name, |
||||
|
int a_line_number, |
||||
|
const char* a_message) |
||||
|
: type_(a_type), |
||||
|
file_name_(a_file_name == NULL ? "" : a_file_name), |
||||
|
line_number_(a_line_number), |
||||
|
summary_(ExtractSummary(a_message)), |
||||
|
message_(a_message) { |
||||
|
} |
||||
|
|
||||
|
// Gets the outcome of the test part.
|
||||
|
Type type() const { return type_; } |
||||
|
|
||||
|
// Gets the name of the source file where the test part took place, or
|
||||
|
// NULL if it's unknown.
|
||||
|
const char* file_name() const { |
||||
|
return file_name_.empty() ? NULL : file_name_.c_str(); |
||||
|
} |
||||
|
|
||||
|
// Gets the line in the source file where the test part took place,
|
||||
|
// or -1 if it's unknown.
|
||||
|
int line_number() const { return line_number_; } |
||||
|
|
||||
|
// Gets the summary of the failure message.
|
||||
|
const char* summary() const { return summary_.c_str(); } |
||||
|
|
||||
|
// Gets the message associated with the test part.
|
||||
|
const char* message() const { return message_.c_str(); } |
||||
|
|
||||
|
// Returns true iff the test part passed.
|
||||
|
bool passed() const { return type_ == kSuccess; } |
||||
|
|
||||
|
// Returns true iff the test part failed.
|
||||
|
bool failed() const { return type_ != kSuccess; } |
||||
|
|
||||
|
// Returns true iff the test part non-fatally failed.
|
||||
|
bool nonfatally_failed() const { return type_ == kNonFatalFailure; } |
||||
|
|
||||
|
// Returns true iff the test part fatally failed.
|
||||
|
bool fatally_failed() const { return type_ == kFatalFailure; } |
||||
|
|
||||
|
private: |
||||
|
Type type_; |
||||
|
|
||||
|
// Gets the summary of the failure message by omitting the stack
|
||||
|
// trace in it.
|
||||
|
static std::string ExtractSummary(const char* message); |
||||
|
|
||||
|
// The name of the source file where the test part took place, or
|
||||
|
// "" if the source file is unknown.
|
||||
|
std::string file_name_; |
||||
|
// The line in the source file where the test part took place, or -1
|
||||
|
// if the line number is unknown.
|
||||
|
int line_number_; |
||||
|
std::string summary_; // The test failure summary.
|
||||
|
std::string message_; // The test failure message.
|
||||
|
}; |
||||
|
|
||||
|
// Prints a TestPartResult object.
|
||||
|
std::ostream& operator<<(std::ostream& os, const TestPartResult& result); |
||||
|
|
||||
|
// An array of TestPartResult objects.
|
||||
|
//
|
||||
|
// Don't inherit from TestPartResultArray as its destructor is not
|
||||
|
// virtual.
|
||||
|
class GTEST_API_ TestPartResultArray { |
||||
|
public: |
||||
|
TestPartResultArray() {} |
||||
|
|
||||
|
// Appends the given TestPartResult to the array.
|
||||
|
void Append(const TestPartResult& result); |
||||
|
|
||||
|
// Returns the TestPartResult at the given index (0-based).
|
||||
|
const TestPartResult& GetTestPartResult(int index) const; |
||||
|
|
||||
|
// Returns the number of TestPartResult objects in the array.
|
||||
|
int size() const; |
||||
|
|
||||
|
private: |
||||
|
std::vector<TestPartResult> array_; |
||||
|
|
||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); |
||||
|
}; |
||||
|
|
||||
|
// This interface knows how to report a test part result.
|
||||
|
class TestPartResultReporterInterface { |
||||
|
public: |
||||
|
virtual ~TestPartResultReporterInterface() {} |
||||
|
|
||||
|
virtual void ReportTestPartResult(const TestPartResult& result) = 0; |
||||
|
}; |
||||
|
|
||||
|
namespace internal { |
||||
|
|
||||
|
// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
|
||||
|
// statement generates new fatal failures. To do so it registers itself as the
|
||||
|
// current test part result reporter. Besides checking if fatal failures were
|
||||
|
// reported, it only delegates the reporting to the former result reporter.
|
||||
|
// The original result reporter is restored in the destructor.
|
||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
|
class GTEST_API_ HasNewFatalFailureHelper |
||||
|
: public TestPartResultReporterInterface { |
||||
|
public: |
||||
|
HasNewFatalFailureHelper(); |
||||
|
virtual ~HasNewFatalFailureHelper(); |
||||
|
virtual void ReportTestPartResult(const TestPartResult& result); |
||||
|
bool has_new_fatal_failure() const { return has_new_fatal_failure_; } |
||||
|
private: |
||||
|
bool has_new_fatal_failure_; |
||||
|
TestPartResultReporterInterface* original_reporter_; |
||||
|
|
||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); |
||||
|
}; |
||||
|
|
||||
|
} // namespace internal
|
||||
|
|
||||
|
} // namespace testing
|
||||
|
|
||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
@ -0,0 +1,259 @@ |
|||||
|
// Copyright 2008 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)
|
||||
|
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ |
||||
|
#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ |
||||
|
|
||||
|
// This header implements typed tests and type-parameterized tests.
|
||||
|
|
||||
|
// Typed (aka type-driven) tests repeat the same test for types in a
|
||||
|
// list. You must know which types you want to test with when writing
|
||||
|
// typed tests. Here's how you do it:
|
||||
|
|
||||
|
#if 0 |
||||
|
|
||||
|
// First, define a fixture class template. It should be parameterized
|
||||
|
// by a type. Remember to derive it from testing::Test.
|
||||
|
template <typename T> |
||||
|
class FooTest : public testing::Test { |
||||
|
public: |
||||
|
... |
||||
|
typedef std::list<T> List; |
||||
|
static T shared_; |
||||
|
T value_; |
||||
|
}; |
||||
|
|
||||
|
// Next, associate a list of types with the test case, which will be
|
||||
|
// repeated for each type in the list. The typedef is necessary for
|
||||
|
// the macro to parse correctly.
|
||||
|
typedef testing::Types<char, int, unsigned int> MyTypes; |
||||
|
TYPED_TEST_CASE(FooTest, MyTypes); |
||||
|
|
||||
|
// If the type list contains only one type, you can write that type
|
||||
|
// directly without Types<...>:
|
||||
|
// TYPED_TEST_CASE(FooTest, int);
|
||||
|
|
||||
|
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
|
||||
|
// tests for this test case as you want.
|
||||
|
TYPED_TEST(FooTest, DoesBlah) { |
||||
|
// Inside a test, refer to TypeParam to get the type parameter.
|
||||
|
// Since we are inside a derived class template, C++ requires use to
|
||||
|
// visit the members of FooTest via 'this'.
|
||||
|
TypeParam n = this->value_; |
||||
|
|
||||
|
// To visit static members of the fixture, add the TestFixture::
|
||||
|
// prefix.
|
||||
|
n += TestFixture::shared_; |
||||
|
|
||||
|
// To refer to typedefs in the fixture, add the "typename
|
||||
|
// TestFixture::" prefix.
|
||||
|
typename TestFixture::List values; |
||||
|
values.push_back(n); |
||||
|
... |
||||
|
} |
||||
|
|
||||
|
TYPED_TEST(FooTest, HasPropertyA) { ... } |
||||
|
|
||||
|
#endif // 0
|
||||
|
|
||||
|
// Type-parameterized tests are abstract test patterns parameterized
|
||||
|
// by a type. Compared with typed tests, type-parameterized tests
|
||||
|
// allow you to define the test pattern without knowing what the type
|
||||
|
// parameters are. The defined pattern can be instantiated with
|
||||
|
// different types any number of times, in any number of translation
|
||||
|
// units.
|
||||
|
//
|
||||
|
// If you are designing an interface or concept, you can define a
|
||||
|
// suite of type-parameterized tests to verify properties that any
|
||||
|
// valid implementation of the interface/concept should have. Then,
|
||||
|
// each implementation can easily instantiate the test suite to verify
|
||||
|
// that it conforms to the requirements, without having to write
|
||||
|
// similar tests repeatedly. Here's an example:
|
||||
|
|
||||
|
#if 0 |
||||
|
|
||||
|
// First, define a fixture class template. It should be parameterized
|
||||
|
// by a type. Remember to derive it from testing::Test.
|
||||
|
template <typename T> |
||||
|
class FooTest : public testing::Test { |
||||
|
... |
||||
|
}; |
||||
|
|
||||
|
// Next, declare that you will define a type-parameterized test case
|
||||
|
// (the _P suffix is for "parameterized" or "pattern", whichever you
|
||||
|
// prefer):
|
||||
|
TYPED_TEST_CASE_P(FooTest); |
||||
|
|
||||
|
// Then, use TYPED_TEST_P() to define as many type-parameterized tests
|
||||
|
// for this type-parameterized test case as you want.
|
||||
|
TYPED_TEST_P(FooTest, DoesBlah) { |
||||
|
// Inside a test, refer to TypeParam to get the type parameter.
|
||||
|
TypeParam n = 0; |
||||
|
... |
||||
|
} |
||||
|
|
||||
|
TYPED_TEST_P(FooTest, HasPropertyA) { ... } |
||||
|
|
||||
|
// Now the tricky part: you need to register all test patterns before
|
||||
|
// you can instantiate them. The first argument of the macro is the
|
||||
|
// test case name; the rest are the names of the tests in this test
|
||||
|
// case.
|
||||
|
REGISTER_TYPED_TEST_CASE_P(FooTest, |
||||
|
DoesBlah, HasPropertyA); |
||||
|
|
||||
|
// Finally, you are free to instantiate the pattern with the types you
|
||||
|
// want. If you put the above code in a header file, you can #include
|
||||
|
// it in multiple C++ source files and instantiate it multiple times.
|
||||
|
//
|
||||
|
// To distinguish different instances of the pattern, the first
|
||||
|
// argument to the INSTANTIATE_* macro is a prefix that will be added
|
||||
|
// to the actual test case name. Remember to pick unique prefixes for
|
||||
|
// different instances.
|
||||
|
typedef testing::Types<char, int, unsigned int> MyTypes; |
||||
|
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); |
||||
|
|
||||
|
// If the type list contains only one type, you can write that type
|
||||
|
// directly without Types<...>:
|
||||
|
// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
|
||||
|
|
||||
|
#endif // 0
|
||||
|
|
||||
|
#include "gtest/internal/gtest-port.h" |
||||
|
#include "gtest/internal/gtest-type-util.h" |
||||
|
|
||||
|
// Implements typed tests.
|
||||
|
|
||||
|
#if GTEST_HAS_TYPED_TEST |
||||
|
|
||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
|
//
|
||||
|
// Expands to the name of the typedef for the type parameters of the
|
||||
|
// given test case.
|
||||
|
# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ |
||||
|
|
||||
|
// The 'Types' template argument below must have spaces around it
|
||||
|
// since some compilers may choke on '>>' when passing a template
|
||||
|
// instance (e.g. Types<int>)
|
||||
|
# define TYPED_TEST_CASE(CaseName, Types) \ |
||||
|
typedef ::testing::internal::TypeList< Types >::type \ |
||||
|
GTEST_TYPE_PARAMS_(CaseName) |
||||
|
|
||||
|
# define TYPED_TEST(CaseName, TestName) \ |
||||
|
template <typename gtest_TypeParam_> \ |
||||
|
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ |
||||
|
: public CaseName<gtest_TypeParam_> { \ |
||||
|
private: \ |
||||
|
typedef CaseName<gtest_TypeParam_> TestFixture; \ |
||||
|
typedef gtest_TypeParam_ TypeParam; \ |
||||
|
virtual void TestBody(); \ |
||||
|
}; \ |
||||
|
bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ |
||||
|
::testing::internal::TypeParameterizedTest< \ |
||||
|
CaseName, \ |
||||
|
::testing::internal::TemplateSel< \ |
||||
|
GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ |
||||
|
GTEST_TYPE_PARAMS_(CaseName)>::Register(\ |
||||
|
"", #CaseName, #TestName, 0); \ |
||||
|
template <typename gtest_TypeParam_> \ |
||||
|
void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody() |
||||
|
|
||||
|
#endif // GTEST_HAS_TYPED_TEST
|
||||
|
|
||||
|
// Implements type-parameterized tests.
|
||||
|
|
||||
|
#if GTEST_HAS_TYPED_TEST_P |
||||
|
|
||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
|
//
|
||||
|
// Expands to the namespace name that the type-parameterized tests for
|
||||
|
// the given type-parameterized test case are defined in. The exact
|
||||
|
// name of the namespace is subject to change without notice.
|
||||
|
# define GTEST_CASE_NAMESPACE_(TestCaseName) \ |
||||
|
gtest_case_##TestCaseName##_ |
||||
|
|
||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
|
//
|
||||
|
// Expands to the name of the variable used to remember the names of
|
||||
|
// the defined tests in the given test case.
|
||||
|
# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ |
||||
|
gtest_typed_test_case_p_state_##TestCaseName##_ |
||||
|
|
||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
|
||||
|
//
|
||||
|
// Expands to the name of the variable used to remember the names of
|
||||
|
// the registered tests in the given test case.
|
||||
|
# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ |
||||
|
gtest_registered_test_names_##TestCaseName##_ |
||||
|
|
||||
|
// The variables defined in the type-parameterized test macros are
|
||||
|
// static as typically these macros are used in a .h file that can be
|
||||
|
// #included in multiple translation units linked together.
|
||||
|
# define TYPED_TEST_CASE_P(CaseName) \ |
||||
|
static ::testing::internal::TypedTestCasePState \ |
||||
|
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) |
||||
|
|
||||
|
# define TYPED_TEST_P(CaseName, TestName) \ |
||||
|
namespace GTEST_CASE_NAMESPACE_(CaseName) { \ |
||||
|
template <typename gtest_TypeParam_> \ |
||||
|
class TestName : public CaseName<gtest_TypeParam_> { \ |
||||
|
private: \ |
||||
|
typedef CaseName<gtest_TypeParam_> TestFixture; \ |
||||
|
typedef gtest_TypeParam_ TypeParam; \ |
||||
|
virtual void TestBody(); \ |
||||
|
}; \ |
||||
|
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ |
||||
|
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ |
||||
|
__FILE__, __LINE__, #CaseName, #TestName); \ |
||||
|
} \ |
||||
|
template <typename gtest_TypeParam_> \ |
||||
|
void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody() |
||||
|
|
||||
|
# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ |
||||
|
namespace GTEST_CASE_NAMESPACE_(CaseName) { \ |
||||
|
typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ |
||||
|
} \ |
||||
|
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ |
||||
|
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ |
||||
|
__FILE__, __LINE__, #__VA_ARGS__) |
||||
|
|
||||
|
// The 'Types' template argument below must have spaces around it
|
||||
|
// since some compilers may choke on '>>' when passing a template
|
||||
|
// instance (e.g. Types<int>)
|
||||
|
# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ |
||||
|
bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ |
||||
|
::testing::internal::TypeParameterizedTestCase<CaseName, \ |
||||
|
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \ |
||||
|
::testing::internal::TypeList< Types >::type>::Register(\ |
||||
|
#Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) |
||||
|
|
||||
|
#endif // GTEST_HAS_TYPED_TEST_P
|
||||
|
|
||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
File diff suppressed because it is too large
@ -0,0 +1,358 @@ |
|||||
|
// Copyright 2006, 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.
|
||||
|
|
||||
|
// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command
|
||||
|
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
|
||||
|
//
|
||||
|
// Implements a family of generic predicate assertion macros.
|
||||
|
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ |
||||
|
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ |
||||
|
|
||||
|
// Makes sure this header is not included before gtest.h.
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ |
||||
|
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. |
||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
|
||||
|
|
||||
|
// This header implements a family of generic predicate assertion
|
||||
|
// macros:
|
||||
|
//
|
||||
|
// ASSERT_PRED_FORMAT1(pred_format, v1)
|
||||
|
// ASSERT_PRED_FORMAT2(pred_format, v1, v2)
|
||||
|
// ...
|
||||
|
//
|
||||
|
// where pred_format is a function or functor that takes n (in the
|
||||
|
// case of ASSERT_PRED_FORMATn) values and their source expression
|
||||
|
// text, and returns a testing::AssertionResult. See the definition
|
||||
|
// of ASSERT_EQ in gtest.h for an example.
|
||||
|
//
|
||||
|
// If you don't care about formatting, you can use the more
|
||||
|
// restrictive version:
|
||||
|
//
|
||||
|
// ASSERT_PRED1(pred, v1)
|
||||
|
// ASSERT_PRED2(pred, v1, v2)
|
||||
|
// ...
|
||||
|
//
|
||||
|
// where pred is an n-ary function or functor that returns bool,
|
||||
|
// and the values v1, v2, ..., must support the << operator for
|
||||
|
// streaming to std::ostream.
|
||||
|
//
|
||||
|
// We also define the EXPECT_* variations.
|
||||
|
//
|
||||
|
// For now we only support predicates whose arity is at most 5.
|
||||
|
// Please email googletestframework@googlegroups.com if you need
|
||||
|
// support for higher arities.
|
||||
|
|
||||
|
// GTEST_ASSERT_ is the basic statement to which all of the assertions
|
||||
|
// in this file reduce. Don't use this in your code.
|
||||
|
|
||||
|
#define GTEST_ASSERT_(expression, on_failure) \ |
||||
|
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ |
||||
|
if (const ::testing::AssertionResult gtest_ar = (expression)) \ |
||||
|
; \ |
||||
|
else \ |
||||
|
on_failure(gtest_ar.failure_message()) |
||||
|
|
||||
|
|
||||
|
// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
||||
|
// this in your code.
|
||||
|
template <typename Pred, |
||||
|
typename T1> |
||||
|
AssertionResult AssertPred1Helper(const char* pred_text, |
||||
|
const char* e1, |
||||
|
Pred pred, |
||||
|
const T1& v1) { |
||||
|
if (pred(v1)) return AssertionSuccess(); |
||||
|
|
||||
|
return AssertionFailure() << pred_text << "(" |
||||
|
<< e1 << ") evaluates to false, where" |
||||
|
<< "\n" << e1 << " evaluates to " << v1; |
||||
|
} |
||||
|
|
||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
|
||||
|
// Don't use this in your code.
|
||||
|
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ |
||||
|
GTEST_ASSERT_(pred_format(#v1, v1), \ |
||||
|
on_failure) |
||||
|
|
||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
||||
|
// this in your code.
|
||||
|
#define GTEST_PRED1_(pred, v1, on_failure)\ |
||||
|
GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ |
||||
|
#v1, \ |
||||
|
pred, \ |
||||
|
v1), on_failure) |
||||
|
|
||||
|
// Unary predicate assertion macros.
|
||||
|
#define EXPECT_PRED_FORMAT1(pred_format, v1) \ |
||||
|
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) |
||||
|
#define EXPECT_PRED1(pred, v1) \ |
||||
|
GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) |
||||
|
#define ASSERT_PRED_FORMAT1(pred_format, v1) \ |
||||
|
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) |
||||
|
#define ASSERT_PRED1(pred, v1) \ |
||||
|
GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) |
||||
|
|
||||
|
|
||||
|
|
||||
|
// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
||||
|
// this in your code.
|
||||
|
template <typename Pred, |
||||
|
typename T1, |
||||
|
typename T2> |
||||
|
AssertionResult AssertPred2Helper(const char* pred_text, |
||||
|
const char* e1, |
||||
|
const char* e2, |
||||
|
Pred pred, |
||||
|
const T1& v1, |
||||
|
const T2& v2) { |
||||
|
if (pred(v1, v2)) return AssertionSuccess(); |
||||
|
|
||||
|
return AssertionFailure() << pred_text << "(" |
||||
|
<< e1 << ", " |
||||
|
<< e2 << ") evaluates to false, where" |
||||
|
<< "\n" << e1 << " evaluates to " << v1 |
||||
|
<< "\n" << e2 << " evaluates to " << v2; |
||||
|
} |
||||
|
|
||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
|
||||
|
// Don't use this in your code.
|
||||
|
#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ |
||||
|
GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ |
||||
|
on_failure) |
||||
|
|
||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
||||
|
// this in your code.
|
||||
|
#define GTEST_PRED2_(pred, v1, v2, on_failure)\ |
||||
|
GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ |
||||
|
#v1, \ |
||||
|
#v2, \ |
||||
|
pred, \ |
||||
|
v1, \ |
||||
|
v2), on_failure) |
||||
|
|
||||
|
// Binary predicate assertion macros.
|
||||
|
#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ |
||||
|
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) |
||||
|
#define EXPECT_PRED2(pred, v1, v2) \ |
||||
|
GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) |
||||
|
#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ |
||||
|
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) |
||||
|
#define ASSERT_PRED2(pred, v1, v2) \ |
||||
|
GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) |
||||
|
|
||||
|
|
||||
|
|
||||
|
// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
||||
|
// this in your code.
|
||||
|
template <typename Pred, |
||||
|
typename T1, |
||||
|
typename T2, |
||||
|
typename T3> |
||||
|
AssertionResult AssertPred3Helper(const char* pred_text, |
||||
|
const char* e1, |
||||
|
const char* e2, |
||||
|
const char* e3, |
||||
|
Pred pred, |
||||
|
const T1& v1, |
||||
|
const T2& v2, |
||||
|
const T3& v3) { |
||||
|
if (pred(v1, v2, v3)) return AssertionSuccess(); |
||||
|
|
||||
|
return AssertionFailure() << pred_text << "(" |
||||
|
<< e1 << ", " |
||||
|
<< e2 << ", " |
||||
|
<< e3 << ") evaluates to false, where" |
||||
|
<< "\n" << e1 << " evaluates to " << v1 |
||||
|
<< "\n" << e2 << " evaluates to " << v2 |
||||
|
<< "\n" << e3 << " evaluates to " << v3; |
||||
|
} |
||||
|
|
||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
|
||||
|
// Don't use this in your code.
|
||||
|
#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ |
||||
|
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ |
||||
|
on_failure) |
||||
|
|
||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
||||
|
// this in your code.
|
||||
|
#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ |
||||
|
GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ |
||||
|
#v1, \ |
||||
|
#v2, \ |
||||
|
#v3, \ |
||||
|
pred, \ |
||||
|
v1, \ |
||||
|
v2, \ |
||||
|
v3), on_failure) |
||||
|
|
||||
|
// Ternary predicate assertion macros.
|
||||
|
#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ |
||||
|
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) |
||||
|
#define EXPECT_PRED3(pred, v1, v2, v3) \ |
||||
|
GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) |
||||
|
#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ |
||||
|
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) |
||||
|
#define ASSERT_PRED3(pred, v1, v2, v3) \ |
||||
|
GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) |
||||
|
|
||||
|
|
||||
|
|
||||
|
// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
||||
|
// this in your code.
|
||||
|
template <typename Pred, |
||||
|
typename T1, |
||||
|
typename T2, |
||||
|
typename T3, |
||||
|
typename T4> |
||||
|
AssertionResult AssertPred4Helper(const char* pred_text, |
||||
|
const char* e1, |
||||
|
const char* e2, |
||||
|
const char* e3, |
||||
|
const char* e4, |
||||
|
Pred pred, |
||||
|
const T1& v1, |
||||
|
const T2& v2, |
||||
|
const T3& v3, |
||||
|
const T4& v4) { |
||||
|
if (pred(v1, v2, v3, v4)) return AssertionSuccess(); |
||||
|
|
||||
|
return AssertionFailure() << pred_text << "(" |
||||
|
<< e1 << ", " |
||||
|
<< e2 << ", " |
||||
|
<< e3 << ", " |
||||
|
<< e4 << ") evaluates to false, where" |
||||
|
<< "\n" << e1 << " evaluates to " << v1 |
||||
|
<< "\n" << e2 << " evaluates to " << v2 |
||||
|
<< "\n" << e3 << " evaluates to " << v3 |
||||
|
<< "\n" << e4 << " evaluates to " << v4; |
||||
|
} |
||||
|
|
||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
|
||||
|
// Don't use this in your code.
|
||||
|
#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ |
||||
|
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ |
||||
|
on_failure) |
||||
|
|
||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
||||
|
// this in your code.
|
||||
|
#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ |
||||
|
GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ |
||||
|
#v1, \ |
||||
|
#v2, \ |
||||
|
#v3, \ |
||||
|
#v4, \ |
||||
|
pred, \ |
||||
|
v1, \ |
||||
|
v2, \ |
||||
|
v3, \ |
||||
|
v4), on_failure) |
||||
|
|
||||
|
// 4-ary predicate assertion macros.
|
||||
|
#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ |
||||
|
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) |
||||
|
#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ |
||||
|
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) |
||||
|
#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ |
||||
|
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) |
||||
|
#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ |
||||
|
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) |
||||
|
|
||||
|
|
||||
|
|
||||
|
// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
||||
|
// this in your code.
|
||||
|
template <typename Pred, |
||||
|
typename T1, |
||||
|
typename T2, |
||||
|
typename T3, |
||||
|
typename T4, |
||||
|
typename T5> |
||||
|
AssertionResult AssertPred5Helper(const char* pred_text, |
||||
|
const char* e1, |
||||
|
const char* e2, |
||||
|
const char* e3, |
||||
|
const char* e4, |
||||
|
const char* e5, |
||||
|
Pred pred, |
||||
|
const T1& v1, |
||||
|
const T2& v2, |
||||
|
const T3& v3, |
||||
|
const T4& v4, |
||||
|
const T5& v5) { |
||||
|
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); |
||||
|
|
||||
|
return AssertionFailure() << pred_text << "(" |
||||
|
<< e1 << ", " |
||||
|
<< e2 << ", " |
||||
|
<< e3 << ", " |
||||
|
<< e4 << ", " |
||||
|
<< e5 << ") evaluates to false, where" |
||||
|
<< "\n" << e1 << " evaluates to " << v1 |
||||
|
<< "\n" << e2 << " evaluates to " << v2 |
||||
|
<< "\n" << e3 << " evaluates to " << v3 |
||||
|
<< "\n" << e4 << " evaluates to " << v4 |
||||
|
<< "\n" << e5 << " evaluates to " << v5; |
||||
|
} |
||||
|
|
||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
|
||||
|
// Don't use this in your code.
|
||||
|
#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ |
||||
|
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ |
||||
|
on_failure) |
||||
|
|
||||
|
// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
||||
|
// this in your code.
|
||||
|
#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ |
||||
|
GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ |
||||
|
#v1, \ |
||||
|
#v2, \ |
||||
|
#v3, \ |
||||
|
#v4, \ |
||||
|
#v5, \ |
||||
|
pred, \ |
||||
|
v1, \ |
||||
|
v2, \ |
||||
|
v3, \ |
||||
|
v4, \ |
||||
|
v5), on_failure) |
||||
|
|
||||
|
// 5-ary predicate assertion macros.
|
||||
|
#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ |
||||
|
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) |
||||
|
#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ |
||||
|
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) |
||||
|
#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ |
||||
|
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) |
||||
|
#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ |
||||
|
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) |
||||
|
|
||||
|
|
||||
|
|
||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
@ -0,0 +1,58 @@ |
|||||
|
// Copyright 2006, 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)
|
||||
|
//
|
||||
|
// Google C++ Testing Framework definitions useful in production code.
|
||||
|
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ |
||||
|
#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ |
||||
|
|
||||
|
// When you need to test the private or protected members of a class,
|
||||
|
// use the FRIEND_TEST macro to declare your tests as friends of the
|
||||
|
// class. For example:
|
||||
|
//
|
||||
|
// class MyClass {
|
||||
|
// private:
|
||||
|
// void MyMethod();
|
||||
|
// FRIEND_TEST(MyClassTest, MyMethod);
|
||||
|
// };
|
||||
|
//
|
||||
|
// class MyClassTest : public testing::Test {
|
||||
|
// // ...
|
||||
|
// };
|
||||
|
//
|
||||
|
// TEST_F(MyClassTest, MyMethod) {
|
||||
|
// // Can call MyClass::MyMethod() here.
|
||||
|
// }
|
||||
|
|
||||
|
#define FRIEND_TEST(test_case_name, test_name)\ |
||||
|
friend class test_case_name##_##test_name##_Test |
||||
|
|
||||
|
#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_
|
@ -0,0 +1,319 @@ |
|||||
|
// Copyright 2005, 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.
|
||||
|
//
|
||||
|
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
|
||||
|
//
|
||||
|
// The Google C++ Testing Framework (Google Test)
|
||||
|
//
|
||||
|
// This header file defines internal utilities needed for implementing
|
||||
|
// death tests. They are subject to change without notice.
|
||||
|
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ |
||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ |
||||
|
|
||||
|
#include "gtest/internal/gtest-internal.h" |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
|
||||
|
namespace testing { |
||||
|
namespace internal { |
||||
|
|
||||
|
GTEST_DECLARE_string_(internal_run_death_test); |
||||
|
|
||||
|
// Names of the flags (needed for parsing Google Test flags).
|
||||
|
const char kDeathTestStyleFlag[] = "death_test_style"; |
||||
|
const char kDeathTestUseFork[] = "death_test_use_fork"; |
||||
|
const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; |
||||
|
|
||||
|
#if GTEST_HAS_DEATH_TEST |
||||
|
|
||||
|
// DeathTest is a class that hides much of the complexity of the
|
||||
|
// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method
|
||||
|
// returns a concrete class that depends on the prevailing death test
|
||||
|
// style, as defined by the --gtest_death_test_style and/or
|
||||
|
// --gtest_internal_run_death_test flags.
|
||||
|
|
||||
|
// In describing the results of death tests, these terms are used with
|
||||
|
// the corresponding definitions:
|
||||
|
//
|
||||
|
// exit status: The integer exit information in the format specified
|
||||
|
// by wait(2)
|
||||
|
// exit code: The integer code passed to exit(3), _exit(2), or
|
||||
|
// returned from main()
|
||||
|
class GTEST_API_ DeathTest { |
||||
|
public: |
||||
|
// Create returns false if there was an error determining the
|
||||
|
// appropriate action to take for the current death test; for example,
|
||||
|
// if the gtest_death_test_style flag is set to an invalid value.
|
||||
|
// The LastMessage method will return a more detailed message in that
|
||||
|
// case. Otherwise, the DeathTest pointer pointed to by the "test"
|
||||
|
// argument is set. If the death test should be skipped, the pointer
|
||||
|
// is set to NULL; otherwise, it is set to the address of a new concrete
|
||||
|
// DeathTest object that controls the execution of the current test.
|
||||
|
static bool Create(const char* statement, const RE* regex, |
||||
|
const char* file, int line, DeathTest** test); |
||||
|
DeathTest(); |
||||
|
virtual ~DeathTest() { } |
||||
|
|
||||
|
// A helper class that aborts a death test when it's deleted.
|
||||
|
class ReturnSentinel { |
||||
|
public: |
||||
|
explicit ReturnSentinel(DeathTest* test) : test_(test) { } |
||||
|
~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } |
||||
|
private: |
||||
|
DeathTest* const test_; |
||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); |
||||
|
} GTEST_ATTRIBUTE_UNUSED_; |
||||
|
|
||||
|
// An enumeration of possible roles that may be taken when a death
|
||||
|
// test is encountered. EXECUTE means that the death test logic should
|
||||
|
// be executed immediately. OVERSEE means that the program should prepare
|
||||
|
// the appropriate environment for a child process to execute the death
|
||||
|
// test, then wait for it to complete.
|
||||
|
enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; |
||||
|
|
||||
|
// An enumeration of the three reasons that a test might be aborted.
|
||||
|
enum AbortReason { |
||||
|
TEST_ENCOUNTERED_RETURN_STATEMENT, |
||||
|
TEST_THREW_EXCEPTION, |
||||
|
TEST_DID_NOT_DIE |
||||
|
}; |
||||
|
|
||||
|
// Assumes one of the above roles.
|
||||
|
virtual TestRole AssumeRole() = 0; |
||||
|
|
||||
|
// Waits for the death test to finish and returns its status.
|
||||
|
virtual int Wait() = 0; |
||||
|
|
||||
|
// Returns true if the death test passed; that is, the test process
|
||||
|
// exited during the test, its exit status matches a user-supplied
|
||||
|
// predicate, and its stderr output matches a user-supplied regular
|
||||
|
// expression.
|
||||
|
// The user-supplied predicate may be a macro expression rather
|
||||
|
// than a function pointer or functor, or else Wait and Passed could
|
||||
|
// be combined.
|
||||
|
virtual bool Passed(bool exit_status_ok) = 0; |
||||
|
|
||||
|
// Signals that the death test did not die as expected.
|
||||
|
virtual void Abort(AbortReason reason) = 0; |
||||
|
|
||||
|
// Returns a human-readable outcome message regarding the outcome of
|
||||
|
// the last death test.
|
||||
|
static const char* LastMessage(); |
||||
|
|
||||
|
static void set_last_death_test_message(const std::string& message); |
||||
|
|
||||
|
private: |
||||
|
// A string containing a description of the outcome of the last death test.
|
||||
|
static std::string last_death_test_message_; |
||||
|
|
||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); |
||||
|
}; |
||||
|
|
||||
|
// Factory interface for death tests. May be mocked out for testing.
|
||||
|
class DeathTestFactory { |
||||
|
public: |
||||
|
virtual ~DeathTestFactory() { } |
||||
|
virtual bool Create(const char* statement, const RE* regex, |
||||
|
const char* file, int line, DeathTest** test) = 0; |
||||
|
}; |
||||
|
|
||||
|
// A concrete DeathTestFactory implementation for normal use.
|
||||
|
class DefaultDeathTestFactory : public DeathTestFactory { |
||||
|
public: |
||||
|
virtual bool Create(const char* statement, const RE* regex, |
||||
|
const char* file, int line, DeathTest** test); |
||||
|
}; |
||||
|
|
||||
|
// Returns true if exit_status describes a process that was terminated
|
||||
|
// by a signal, or exited normally with a nonzero exit code.
|
||||
|
GTEST_API_ bool ExitedUnsuccessfully(int exit_status); |
||||
|
|
||||
|
// Traps C++ exceptions escaping statement and reports them as test
|
||||
|
// failures. Note that trapping SEH exceptions is not implemented here.
|
||||
|
# if GTEST_HAS_EXCEPTIONS |
||||
|
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ |
||||
|
try { \ |
||||
|
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ |
||||
|
} catch (const ::std::exception& gtest_exception) { \ |
||||
|
fprintf(\ |
||||
|
stderr, \ |
||||
|
"\n%s: Caught std::exception-derived exception escaping the " \ |
||||
|
"death test statement. Exception message: %s\n", \ |
||||
|
::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ |
||||
|
gtest_exception.what()); \ |
||||
|
fflush(stderr); \ |
||||
|
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ |
||||
|
} catch (...) { \ |
||||
|
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ |
||||
|
} |
||||
|
|
||||
|
# else |
||||
|
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ |
||||
|
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) |
||||
|
|
||||
|
# endif |
||||
|
|
||||
|
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
|
||||
|
// ASSERT_EXIT*, and EXPECT_EXIT*.
|
||||
|
# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ |
||||
|
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ |
||||
|
if (::testing::internal::AlwaysTrue()) { \ |
||||
|
const ::testing::internal::RE& gtest_regex = (regex); \ |
||||
|
::testing::internal::DeathTest* gtest_dt; \ |
||||
|
if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ |
||||
|
__FILE__, __LINE__, >est_dt)) { \ |
||||
|
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ |
||||
|
} \ |
||||
|
if (gtest_dt != NULL) { \ |
||||
|
::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ |
||||
|
gtest_dt_ptr(gtest_dt); \ |
||||
|
switch (gtest_dt->AssumeRole()) { \ |
||||
|
case ::testing::internal::DeathTest::OVERSEE_TEST: \ |
||||
|
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ |
||||
|
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ |
||||
|
} \ |
||||
|
break; \ |
||||
|
case ::testing::internal::DeathTest::EXECUTE_TEST: { \ |
||||
|
::testing::internal::DeathTest::ReturnSentinel \ |
||||
|
gtest_sentinel(gtest_dt); \ |
||||
|
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ |
||||
|
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ |
||||
|
break; \ |
||||
|
} \ |
||||
|
default: \ |
||||
|
break; \ |
||||
|
} \ |
||||
|
} \ |
||||
|
} else \ |
||||
|
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ |
||||
|
fail(::testing::internal::DeathTest::LastMessage()) |
||||
|
// The symbol "fail" here expands to something into which a message
|
||||
|
// can be streamed.
|
||||
|
|
||||
|
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
|
||||
|
// NDEBUG mode. In this case we need the statements to be executed, the regex is
|
||||
|
// ignored, and the macro must accept a streamed message even though the message
|
||||
|
// is never printed.
|
||||
|
# define GTEST_EXECUTE_STATEMENT_(statement, regex) \ |
||||
|
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ |
||||
|
if (::testing::internal::AlwaysTrue()) { \ |
||||
|
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ |
||||
|
} else \ |
||||
|
::testing::Message() |
||||
|
|
||||
|
// A class representing the parsed contents of the
|
||||
|
// --gtest_internal_run_death_test flag, as it existed when
|
||||
|
// RUN_ALL_TESTS was called.
|
||||
|
class InternalRunDeathTestFlag { |
||||
|
public: |
||||
|
InternalRunDeathTestFlag(const std::string& a_file, |
||||
|
int a_line, |
||||
|
int an_index, |
||||
|
int a_write_fd) |
||||
|
: file_(a_file), line_(a_line), index_(an_index), |
||||
|
write_fd_(a_write_fd) {} |
||||
|
|
||||
|
~InternalRunDeathTestFlag() { |
||||
|
if (write_fd_ >= 0) |
||||
|
posix::Close(write_fd_); |
||||
|
} |
||||
|
|
||||
|
const std::string& file() const { return file_; } |
||||
|
int line() const { return line_; } |
||||
|
int index() const { return index_; } |
||||
|
int write_fd() const { return write_fd_; } |
||||
|
|
||||
|
private: |
||||
|
std::string file_; |
||||
|
int line_; |
||||
|
int index_; |
||||
|
int write_fd_; |
||||
|
|
||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); |
||||
|
}; |
||||
|
|
||||
|
// Returns a newly created InternalRunDeathTestFlag object with fields
|
||||
|
// initialized from the GTEST_FLAG(internal_run_death_test) flag if
|
||||
|
// the flag is specified; otherwise returns NULL.
|
||||
|
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); |
||||
|
|
||||
|
#else // GTEST_HAS_DEATH_TEST
|
||||
|
|
||||
|
// This macro is used for implementing macros such as
|
||||
|
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
|
||||
|
// death tests are not supported. Those macros must compile on such systems
|
||||
|
// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
|
||||
|
// systems that support death tests. This allows one to write such a macro
|
||||
|
// on a system that does not support death tests and be sure that it will
|
||||
|
// compile on a death-test supporting system.
|
||||
|
//
|
||||
|
// Parameters:
|
||||
|
// statement - A statement that a macro such as EXPECT_DEATH would test
|
||||
|
// for program termination. This macro has to make sure this
|
||||
|
// statement is compiled but not executed, to ensure that
|
||||
|
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
|
||||
|
// parameter iff EXPECT_DEATH compiles with it.
|
||||
|
// regex - A regex that a macro such as EXPECT_DEATH would use to test
|
||||
|
// the output of statement. This parameter has to be
|
||||
|
// compiled but not evaluated by this macro, to ensure that
|
||||
|
// this macro only accepts expressions that a macro such as
|
||||
|
// EXPECT_DEATH would accept.
|
||||
|
// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
|
||||
|
// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
|
||||
|
// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
|
||||
|
// compile inside functions where ASSERT_DEATH doesn't
|
||||
|
// compile.
|
||||
|
//
|
||||
|
// The branch that has an always false condition is used to ensure that
|
||||
|
// statement and regex are compiled (and thus syntactically correct) but
|
||||
|
// never executed. The unreachable code macro protects the terminator
|
||||
|
// statement from generating an 'unreachable code' warning in case
|
||||
|
// statement unconditionally returns or throws. The Message constructor at
|
||||
|
// the end allows the syntax of streaming additional messages into the
|
||||
|
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
|
||||
|
# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ |
||||
|
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ |
||||
|
if (::testing::internal::AlwaysTrue()) { \ |
||||
|
GTEST_LOG_(WARNING) \ |
||||
|
<< "Death tests are not supported on this platform.\n" \ |
||||
|
<< "Statement '" #statement "' cannot be verified."; \ |
||||
|
} else if (::testing::internal::AlwaysFalse()) { \ |
||||
|
::testing::internal::RE::PartialMatch(".*", (regex)); \ |
||||
|
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ |
||||
|
terminator; \ |
||||
|
} else \ |
||||
|
::testing::Message() |
||||
|
|
||||
|
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
|
||||
|
} // namespace internal
|
||||
|
} // namespace testing
|
||||
|
|
||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
|
@ -0,0 +1,206 @@ |
|||||
|
// Copyright 2008, 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: keith.ray@gmail.com (Keith Ray)
|
||||
|
//
|
||||
|
// Google Test filepath utilities
|
||||
|
//
|
||||
|
// This header file declares classes and functions used internally by
|
||||
|
// Google Test. They are subject to change without notice.
|
||||
|
//
|
||||
|
// This file is #included in <gtest/internal/gtest-internal.h>.
|
||||
|
// Do not include this header file separately!
|
||||
|
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ |
||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ |
||||
|
|
||||
|
#include "gtest/internal/gtest-string.h" |
||||
|
|
||||
|
namespace testing { |
||||
|
namespace internal { |
||||
|
|
||||
|
// FilePath - a class for file and directory pathname manipulation which
|
||||
|
// handles platform-specific conventions (like the pathname separator).
|
||||
|
// Used for helper functions for naming files in a directory for xml output.
|
||||
|
// Except for Set methods, all methods are const or static, which provides an
|
||||
|
// "immutable value object" -- useful for peace of mind.
|
||||
|
// A FilePath with a value ending in a path separator ("like/this/") represents
|
||||
|
// a directory, otherwise it is assumed to represent a file. In either case,
|
||||
|
// it may or may not represent an actual file or directory in the file system.
|
||||
|
// Names are NOT checked for syntax correctness -- no checking for illegal
|
||||
|
// characters, malformed paths, etc.
|
||||
|
|
||||
|
class GTEST_API_ FilePath { |
||||
|
public: |
||||
|
FilePath() : pathname_("") { } |
||||
|
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } |
||||
|
|
||||
|
explicit FilePath(const std::string& pathname) : pathname_(pathname) { |
||||
|
Normalize(); |
||||
|
} |
||||
|
|
||||
|
FilePath& operator=(const FilePath& rhs) { |
||||
|
Set(rhs); |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
void Set(const FilePath& rhs) { |
||||
|
pathname_ = rhs.pathname_; |
||||
|
} |
||||
|
|
||||
|
const std::string& string() const { return pathname_; } |
||||
|
const char* c_str() const { return pathname_.c_str(); } |
||||
|
|
||||
|
// Returns the current working directory, or "" if unsuccessful.
|
||||
|
static FilePath GetCurrentDir(); |
||||
|
|
||||
|
// Given directory = "dir", base_name = "test", number = 0,
|
||||
|
// extension = "xml", returns "dir/test.xml". If number is greater
|
||||
|
// than zero (e.g., 12), returns "dir/test_12.xml".
|
||||
|
// On Windows platform, uses \ as the separator rather than /.
|
||||
|
static FilePath MakeFileName(const FilePath& directory, |
||||
|
const FilePath& base_name, |
||||
|
int number, |
||||
|
const char* extension); |
||||
|
|
||||
|
// Given directory = "dir", relative_path = "test.xml",
|
||||
|
// returns "dir/test.xml".
|
||||
|
// On Windows, uses \ as the separator rather than /.
|
||||
|
static FilePath ConcatPaths(const FilePath& directory, |
||||
|
const FilePath& relative_path); |
||||
|
|
||||
|
// Returns a pathname for a file that does not currently exist. The pathname
|
||||
|
// will be directory/base_name.extension or
|
||||
|
// directory/base_name_<number>.extension if directory/base_name.extension
|
||||
|
// already exists. The number will be incremented until a pathname is found
|
||||
|
// that does not already exist.
|
||||
|
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
|
||||
|
// There could be a race condition if two or more processes are calling this
|
||||
|
// function at the same time -- they could both pick the same filename.
|
||||
|
static FilePath GenerateUniqueFileName(const FilePath& directory, |
||||
|
const FilePath& base_name, |
||||
|
const char* extension); |
||||
|
|
||||
|
// Returns true iff the path is "".
|
||||
|
bool IsEmpty() const { return pathname_.empty(); } |
||||
|
|
||||
|
// If input name has a trailing separator character, removes it and returns
|
||||
|
// the name, otherwise return the name string unmodified.
|
||||
|
// On Windows platform, uses \ as the separator, other platforms use /.
|
||||
|
FilePath RemoveTrailingPathSeparator() const; |
||||
|
|
||||
|
// Returns a copy of the FilePath with the directory part removed.
|
||||
|
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
|
||||
|
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
|
||||
|
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
|
||||
|
// returns an empty FilePath ("").
|
||||
|
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
|
FilePath RemoveDirectoryName() const; |
||||
|
|
||||
|
// RemoveFileName returns the directory path with the filename removed.
|
||||
|
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
|
||||
|
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
|
||||
|
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
|
||||
|
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
|
||||
|
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
|
FilePath RemoveFileName() const; |
||||
|
|
||||
|
// Returns a copy of the FilePath with the case-insensitive extension removed.
|
||||
|
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
|
||||
|
// FilePath("dir/file"). If a case-insensitive extension is not
|
||||
|
// found, returns a copy of the original FilePath.
|
||||
|
FilePath RemoveExtension(const char* extension) const; |
||||
|
|
||||
|
// Creates directories so that path exists. Returns true if successful or if
|
||||
|
// the directories already exist; returns false if unable to create
|
||||
|
// directories for any reason. Will also return false if the FilePath does
|
||||
|
// not represent a directory (that is, it doesn't end with a path separator).
|
||||
|
bool CreateDirectoriesRecursively() const; |
||||
|
|
||||
|
// Create the directory so that path exists. Returns true if successful or
|
||||
|
// if the directory already exists; returns false if unable to create the
|
||||
|
// directory for any reason, including if the parent directory does not
|
||||
|
// exist. Not named "CreateDirectory" because that's a macro on Windows.
|
||||
|
bool CreateFolder() const; |
||||
|
|
||||
|
// Returns true if FilePath describes something in the file-system,
|
||||
|
// either a file, directory, or whatever, and that something exists.
|
||||
|
bool FileOrDirectoryExists() const; |
||||
|
|
||||
|
// Returns true if pathname describes a directory in the file-system
|
||||
|
// that exists.
|
||||
|
bool DirectoryExists() const; |
||||
|
|
||||
|
// Returns true if FilePath ends with a path separator, which indicates that
|
||||
|
// it is intended to represent a directory. Returns false otherwise.
|
||||
|
// This does NOT check that a directory (or file) actually exists.
|
||||
|
bool IsDirectory() const; |
||||
|
|
||||
|
// Returns true if pathname describes a root directory. (Windows has one
|
||||
|
// root directory per disk drive.)
|
||||
|
bool IsRootDirectory() const; |
||||
|
|
||||
|
// Returns true if pathname describes an absolute path.
|
||||
|
bool IsAbsolutePath() const; |
||||
|
|
||||
|
private: |
||||
|
// Replaces multiple consecutive separators with a single separator.
|
||||
|
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
|
||||
|
// redundancies that might be in a pathname involving "." or "..".
|
||||
|
//
|
||||
|
// A pathname with multiple consecutive separators may occur either through
|
||||
|
// user error or as a result of some scripts or APIs that generate a pathname
|
||||
|
// with a trailing separator. On other platforms the same API or script
|
||||
|
// may NOT generate a pathname with a trailing "/". Then elsewhere that
|
||||
|
// pathname may have another "/" and pathname components added to it,
|
||||
|
// without checking for the separator already being there.
|
||||
|
// The script language and operating system may allow paths like "foo//bar"
|
||||
|
// but some of the functions in FilePath will not handle that correctly. In
|
||||
|
// particular, RemoveTrailingPathSeparator() only removes one separator, and
|
||||
|
// it is called in CreateDirectoriesRecursively() assuming that it will change
|
||||
|
// a pathname from directory syntax (trailing separator) to filename syntax.
|
||||
|
//
|
||||
|
// On Windows this method also replaces the alternate path separator '/' with
|
||||
|
// the primary path separator '\\', so that for example "bar\\/\\foo" becomes
|
||||
|
// "bar\\foo".
|
||||
|
|
||||
|
void Normalize(); |
||||
|
|
||||
|
// Returns a pointer to the last occurence of a valid path separator in
|
||||
|
// the FilePath. On Windows, for example, both '/' and '\' are valid path
|
||||
|
// separators. Returns NULL if no path separator was found.
|
||||
|
const char* FindLastPathSeparator() const; |
||||
|
|
||||
|
std::string pathname_; |
||||
|
}; // class FilePath
|
||||
|
|
||||
|
} // namespace internal
|
||||
|
} // namespace testing
|
||||
|
|
||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
|
File diff suppressed because it is too large
@ -0,0 +1,243 @@ |
|||||
|
// Copyright 2003 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.
|
||||
|
//
|
||||
|
// Authors: Dan Egnor (egnor@google.com)
|
||||
|
//
|
||||
|
// A "smart" pointer type with reference tracking. Every pointer to a
|
||||
|
// particular object is kept on a circular linked list. When the last pointer
|
||||
|
// to an object is destroyed or reassigned, the object is deleted.
|
||||
|
//
|
||||
|
// Used properly, this deletes the object when the last reference goes away.
|
||||
|
// There are several caveats:
|
||||
|
// - Like all reference counting schemes, cycles lead to leaks.
|
||||
|
// - Each smart pointer is actually two pointers (8 bytes instead of 4).
|
||||
|
// - Every time a pointer is assigned, the entire list of pointers to that
|
||||
|
// object is traversed. This class is therefore NOT SUITABLE when there
|
||||
|
// will often be more than two or three pointers to a particular object.
|
||||
|
// - References are only tracked as long as linked_ptr<> objects are copied.
|
||||
|
// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
|
||||
|
// will happen (double deletion).
|
||||
|
//
|
||||
|
// A good use of this class is storing object references in STL containers.
|
||||
|
// You can safely put linked_ptr<> in a vector<>.
|
||||
|
// Other uses may not be as good.
|
||||
|
//
|
||||
|
// Note: If you use an incomplete type with linked_ptr<>, the class
|
||||
|
// *containing* linked_ptr<> must have a constructor and destructor (even
|
||||
|
// if they do nothing!).
|
||||
|
//
|
||||
|
// Bill Gibbons suggested we use something like this.
|
||||
|
//
|
||||
|
// Thread Safety:
|
||||
|
// Unlike other linked_ptr implementations, in this implementation
|
||||
|
// a linked_ptr object is thread-safe in the sense that:
|
||||
|
// - it's safe to copy linked_ptr objects concurrently,
|
||||
|
// - it's safe to copy *from* a linked_ptr and read its underlying
|
||||
|
// raw pointer (e.g. via get()) concurrently, and
|
||||
|
// - it's safe to write to two linked_ptrs that point to the same
|
||||
|
// shared object concurrently.
|
||||
|
// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
|
||||
|
// confusion with normal linked_ptr.
|
||||
|
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ |
||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ |
||||
|
|
||||
|
#include <stdlib.h> |
||||
|
#include <assert.h> |
||||
|
|
||||
|
#include "gtest/internal/gtest-port.h" |
||||
|
|
||||
|
namespace testing { |
||||
|
namespace internal { |
||||
|
|
||||
|
// Protects copying of all linked_ptr objects.
|
||||
|
GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); |
||||
|
|
||||
|
// This is used internally by all instances of linked_ptr<>. It needs to be
|
||||
|
// a non-template class because different types of linked_ptr<> can refer to
|
||||
|
// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
|
||||
|
// So, it needs to be possible for different types of linked_ptr to participate
|
||||
|
// in the same circular linked list, so we need a single class type here.
|
||||
|
//
|
||||
|
// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
|
||||
|
class linked_ptr_internal { |
||||
|
public: |
||||
|
// Create a new circle that includes only this instance.
|
||||
|
void join_new() { |
||||
|
next_ = this; |
||||
|
} |
||||
|
|
||||
|
// Many linked_ptr operations may change p.link_ for some linked_ptr
|
||||
|
// variable p in the same circle as this object. Therefore we need
|
||||
|
// to prevent two such operations from occurring concurrently.
|
||||
|
//
|
||||
|
// Note that different types of linked_ptr objects can coexist in a
|
||||
|
// circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
|
||||
|
// linked_ptr<Derived2>). Therefore we must use a single mutex to
|
||||
|
// protect all linked_ptr objects. This can create serious
|
||||
|
// contention in production code, but is acceptable in a testing
|
||||
|
// framework.
|
||||
|
|
||||
|
// Join an existing circle.
|
||||
|
void join(linked_ptr_internal const* ptr) |
||||
|
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { |
||||
|
MutexLock lock(&g_linked_ptr_mutex); |
||||
|
|
||||
|
linked_ptr_internal const* p = ptr; |
||||
|
while (p->next_ != ptr) { |
||||
|
assert(p->next_ != this && |
||||
|
"Trying to join() a linked ring we are already in. " |
||||
|
"Is GMock thread safety enabled?"); |
||||
|
p = p->next_; |
||||
|
} |
||||
|
p->next_ = this; |
||||
|
next_ = ptr; |
||||
|
} |
||||
|
|
||||
|
// Leave whatever circle we're part of. Returns true if we were the
|
||||
|
// last member of the circle. Once this is done, you can join() another.
|
||||
|
bool depart() |
||||
|
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { |
||||
|
MutexLock lock(&g_linked_ptr_mutex); |
||||
|
|
||||
|
if (next_ == this) return true; |
||||
|
linked_ptr_internal const* p = next_; |
||||
|
while (p->next_ != this) { |
||||
|
assert(p->next_ != next_ && |
||||
|
"Trying to depart() a linked ring we are not in. " |
||||
|
"Is GMock thread safety enabled?"); |
||||
|
p = p->next_; |
||||
|
} |
||||
|
p->next_ = next_; |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
mutable linked_ptr_internal const* next_; |
||||
|
}; |
||||
|
|
||||
|
template <typename T> |
||||
|
class linked_ptr { |
||||
|
public: |
||||
|
typedef T element_type; |
||||
|
|
||||
|
// Take over ownership of a raw pointer. This should happen as soon as
|
||||
|
// possible after the object is created.
|
||||
|
explicit linked_ptr(T* ptr = NULL) { capture(ptr); } |
||||
|
~linked_ptr() { depart(); } |
||||
|
|
||||
|
// Copy an existing linked_ptr<>, adding ourselves to the list of references.
|
||||
|
template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); } |
||||
|
linked_ptr(linked_ptr const& ptr) { // NOLINT
|
||||
|
assert(&ptr != this); |
||||
|
copy(&ptr); |
||||
|
} |
||||
|
|
||||
|
// Assignment releases the old value and acquires the new.
|
||||
|
template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) { |
||||
|
depart(); |
||||
|
copy(&ptr); |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
linked_ptr& operator=(linked_ptr const& ptr) { |
||||
|
if (&ptr != this) { |
||||
|
depart(); |
||||
|
copy(&ptr); |
||||
|
} |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
// Smart pointer members.
|
||||
|
void reset(T* ptr = NULL) { |
||||
|
depart(); |
||||
|
capture(ptr); |
||||
|
} |
||||
|
T* get() const { return value_; } |
||||
|
T* operator->() const { return value_; } |
||||
|
T& operator*() const { return *value_; } |
||||
|
|
||||
|
bool operator==(T* p) const { return value_ == p; } |
||||
|
bool operator!=(T* p) const { return value_ != p; } |
||||
|
template <typename U> |
||||
|
bool operator==(linked_ptr<U> const& ptr) const { |
||||
|
return value_ == ptr.get(); |
||||
|
} |
||||
|
template <typename U> |
||||
|
bool operator!=(linked_ptr<U> const& ptr) const { |
||||
|
return value_ != ptr.get(); |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
template <typename U> |
||||
|
friend class linked_ptr; |
||||
|
|
||||
|
T* value_; |
||||
|
linked_ptr_internal link_; |
||||
|
|
||||
|
void depart() { |
||||
|
if (link_.depart()) delete value_; |
||||
|
} |
||||
|
|
||||
|
void capture(T* ptr) { |
||||
|
value_ = ptr; |
||||
|
link_.join_new(); |
||||
|
} |
||||
|
|
||||
|
template <typename U> void copy(linked_ptr<U> const* ptr) { |
||||
|
value_ = ptr->get(); |
||||
|
if (value_) |
||||
|
link_.join(&ptr->link_); |
||||
|
else |
||||
|
link_.join_new(); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
template<typename T> inline |
||||
|
bool operator==(T* ptr, const linked_ptr<T>& x) { |
||||
|
return ptr == x.get(); |
||||
|
} |
||||
|
|
||||
|
template<typename T> inline |
||||
|
bool operator!=(T* ptr, const linked_ptr<T>& x) { |
||||
|
return ptr != x.get(); |
||||
|
} |
||||
|
|
||||
|
// A function to convert T* into linked_ptr<T>
|
||||
|
// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
|
||||
|
// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
|
||||
|
template <typename T> |
||||
|
linked_ptr<T> make_linked_ptr(T* ptr) { |
||||
|
return linked_ptr<T>(ptr); |
||||
|
} |
||||
|
|
||||
|
} // namespace internal
|
||||
|
} // namespace testing
|
||||
|
|
||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
|
File diff suppressed because it is too large
@ -0,0 +1,619 @@ |
|||||
|
// Copyright 2008 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: vladl@google.com (Vlad Losev)
|
||||
|
|
||||
|
// Type and function utilities for implementing parameterized tests.
|
||||
|
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ |
||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ |
||||
|
|
||||
|
#include <iterator> |
||||
|
#include <utility> |
||||
|
#include <vector> |
||||
|
|
||||
|
// scripts/fuse_gtest.py depends on gtest's own header being #included
|
||||
|
// *unconditionally*. Therefore these #includes cannot be moved
|
||||
|
// inside #if GTEST_HAS_PARAM_TEST.
|
||||
|
#include "gtest/internal/gtest-internal.h" |
||||
|
#include "gtest/internal/gtest-linked_ptr.h" |
||||
|
#include "gtest/internal/gtest-port.h" |
||||
|
#include "gtest/gtest-printers.h" |
||||
|
|
||||
|
#if GTEST_HAS_PARAM_TEST |
||||
|
|
||||
|
namespace testing { |
||||
|
namespace internal { |
||||
|
|
||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
|
//
|
||||
|
// Outputs a message explaining invalid registration of different
|
||||
|
// fixture class for the same test case. This may happen when
|
||||
|
// TEST_P macro is used to define two tests with the same name
|
||||
|
// but in different namespaces.
|
||||
|
GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, |
||||
|
const char* file, int line); |
||||
|
|
||||
|
template <typename> class ParamGeneratorInterface; |
||||
|
template <typename> class ParamGenerator; |
||||
|
|
||||
|
// Interface for iterating over elements provided by an implementation
|
||||
|
// of ParamGeneratorInterface<T>.
|
||||
|
template <typename T> |
||||
|
class ParamIteratorInterface { |
||||
|
public: |
||||
|
virtual ~ParamIteratorInterface() {} |
||||
|
// A pointer to the base generator instance.
|
||||
|
// Used only for the purposes of iterator comparison
|
||||
|
// to make sure that two iterators belong to the same generator.
|
||||
|
virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0; |
||||
|
// Advances iterator to point to the next element
|
||||
|
// provided by the generator. The caller is responsible
|
||||
|
// for not calling Advance() on an iterator equal to
|
||||
|
// BaseGenerator()->End().
|
||||
|
virtual void Advance() = 0; |
||||
|
// Clones the iterator object. Used for implementing copy semantics
|
||||
|
// of ParamIterator<T>.
|
||||
|
virtual ParamIteratorInterface* Clone() const = 0; |
||||
|
// Dereferences the current iterator and provides (read-only) access
|
||||
|
// to the pointed value. It is the caller's responsibility not to call
|
||||
|
// Current() on an iterator equal to BaseGenerator()->End().
|
||||
|
// Used for implementing ParamGenerator<T>::operator*().
|
||||
|
virtual const T* Current() const = 0; |
||||
|
// Determines whether the given iterator and other point to the same
|
||||
|
// element in the sequence generated by the generator.
|
||||
|
// Used for implementing ParamGenerator<T>::operator==().
|
||||
|
virtual bool Equals(const ParamIteratorInterface& other) const = 0; |
||||
|
}; |
||||
|
|
||||
|
// Class iterating over elements provided by an implementation of
|
||||
|
// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
|
||||
|
// and implements the const forward iterator concept.
|
||||
|
template <typename T> |
||||
|
class ParamIterator { |
||||
|
public: |
||||
|
typedef T value_type; |
||||
|
typedef const T& reference; |
||||
|
typedef ptrdiff_t difference_type; |
||||
|
|
||||
|
// ParamIterator assumes ownership of the impl_ pointer.
|
||||
|
ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} |
||||
|
ParamIterator& operator=(const ParamIterator& other) { |
||||
|
if (this != &other) |
||||
|
impl_.reset(other.impl_->Clone()); |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
const T& operator*() const { return *impl_->Current(); } |
||||
|
const T* operator->() const { return impl_->Current(); } |
||||
|
// Prefix version of operator++.
|
||||
|
ParamIterator& operator++() { |
||||
|
impl_->Advance(); |
||||
|
return *this; |
||||
|
} |
||||
|
// Postfix version of operator++.
|
||||
|
ParamIterator operator++(int /*unused*/) { |
||||
|
ParamIteratorInterface<T>* clone = impl_->Clone(); |
||||
|
impl_->Advance(); |
||||
|
return ParamIterator(clone); |
||||
|
} |
||||
|
bool operator==(const ParamIterator& other) const { |
||||
|
return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); |
||||
|
} |
||||
|
bool operator!=(const ParamIterator& other) const { |
||||
|
return !(*this == other); |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
friend class ParamGenerator<T>; |
||||
|
explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {} |
||||
|
scoped_ptr<ParamIteratorInterface<T> > impl_; |
||||
|
}; |
||||
|
|
||||
|
// ParamGeneratorInterface<T> is the binary interface to access generators
|
||||
|
// defined in other translation units.
|
||||
|
template <typename T> |
||||
|
class ParamGeneratorInterface { |
||||
|
public: |
||||
|
typedef T ParamType; |
||||
|
|
||||
|
virtual ~ParamGeneratorInterface() {} |
||||
|
|
||||
|
// Generator interface definition
|
||||
|
virtual ParamIteratorInterface<T>* Begin() const = 0; |
||||
|
virtual ParamIteratorInterface<T>* End() const = 0; |
||||
|
}; |
||||
|
|
||||
|
// Wraps ParamGeneratorInterface<T> and provides general generator syntax
|
||||
|
// compatible with the STL Container concept.
|
||||
|
// This class implements copy initialization semantics and the contained
|
||||
|
// ParamGeneratorInterface<T> instance is shared among all copies
|
||||
|
// of the original object. This is possible because that instance is immutable.
|
||||
|
template<typename T> |
||||
|
class ParamGenerator { |
||||
|
public: |
||||
|
typedef ParamIterator<T> iterator; |
||||
|
|
||||
|
explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {} |
||||
|
ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} |
||||
|
|
||||
|
ParamGenerator& operator=(const ParamGenerator& other) { |
||||
|
impl_ = other.impl_; |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
iterator begin() const { return iterator(impl_->Begin()); } |
||||
|
iterator end() const { return iterator(impl_->End()); } |
||||
|
|
||||
|
private: |
||||
|
linked_ptr<const ParamGeneratorInterface<T> > impl_; |
||||
|
}; |
||||
|
|
||||
|
// Generates values from a range of two comparable values. Can be used to
|
||||
|
// generate sequences of user-defined types that implement operator+() and
|
||||
|
// operator<().
|
||||
|
// This class is used in the Range() function.
|
||||
|
template <typename T, typename IncrementT> |
||||
|
class RangeGenerator : public ParamGeneratorInterface<T> { |
||||
|
public: |
||||
|
RangeGenerator(T begin, T end, IncrementT step) |
||||
|
: begin_(begin), end_(end), |
||||
|
step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} |
||||
|
virtual ~RangeGenerator() {} |
||||
|
|
||||
|
virtual ParamIteratorInterface<T>* Begin() const { |
||||
|
return new Iterator(this, begin_, 0, step_); |
||||
|
} |
||||
|
virtual ParamIteratorInterface<T>* End() const { |
||||
|
return new Iterator(this, end_, end_index_, step_); |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
class Iterator : public ParamIteratorInterface<T> { |
||||
|
public: |
||||
|
Iterator(const ParamGeneratorInterface<T>* base, T value, int index, |
||||
|
IncrementT step) |
||||
|
: base_(base), value_(value), index_(index), step_(step) {} |
||||
|
virtual ~Iterator() {} |
||||
|
|
||||
|
virtual const ParamGeneratorInterface<T>* BaseGenerator() const { |
||||
|
return base_; |
||||
|
} |
||||
|
virtual void Advance() { |
||||
|
value_ = value_ + step_; |
||||
|
index_++; |
||||
|
} |
||||
|
virtual ParamIteratorInterface<T>* Clone() const { |
||||
|
return new Iterator(*this); |
||||
|
} |
||||
|
virtual const T* Current() const { return &value_; } |
||||
|
virtual bool Equals(const ParamIteratorInterface<T>& other) const { |
||||
|
// Having the same base generator guarantees that the other
|
||||
|
// iterator is of the same type and we can downcast.
|
||||
|
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) |
||||
|
<< "The program attempted to compare iterators " |
||||
|
<< "from different generators." << std::endl; |
||||
|
const int other_index = |
||||
|
CheckedDowncastToActualType<const Iterator>(&other)->index_; |
||||
|
return index_ == other_index; |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
Iterator(const Iterator& other) |
||||
|
: ParamIteratorInterface<T>(), |
||||
|
base_(other.base_), value_(other.value_), index_(other.index_), |
||||
|
step_(other.step_) {} |
||||
|
|
||||
|
// No implementation - assignment is unsupported.
|
||||
|
void operator=(const Iterator& other); |
||||
|
|
||||
|
const ParamGeneratorInterface<T>* const base_; |
||||
|
T value_; |
||||
|
int index_; |
||||
|
const IncrementT step_; |
||||
|
}; // class RangeGenerator::Iterator
|
||||
|
|
||||
|
static int CalculateEndIndex(const T& begin, |
||||
|
const T& end, |
||||
|
const IncrementT& step) { |
||||
|
int end_index = 0; |
||||
|
for (T i = begin; i < end; i = i + step) |
||||
|
end_index++; |
||||
|
return end_index; |
||||
|
} |
||||
|
|
||||
|
// No implementation - assignment is unsupported.
|
||||
|
void operator=(const RangeGenerator& other); |
||||
|
|
||||
|
const T begin_; |
||||
|
const T end_; |
||||
|
const IncrementT step_; |
||||
|
// The index for the end() iterator. All the elements in the generated
|
||||
|
// sequence are indexed (0-based) to aid iterator comparison.
|
||||
|
const int end_index_; |
||||
|
}; // class RangeGenerator
|
||||
|
|
||||
|
|
||||
|
// Generates values from a pair of STL-style iterators. Used in the
|
||||
|
// ValuesIn() function. The elements are copied from the source range
|
||||
|
// since the source can be located on the stack, and the generator
|
||||
|
// is likely to persist beyond that stack frame.
|
||||
|
template <typename T> |
||||
|
class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> { |
||||
|
public: |
||||
|
template <typename ForwardIterator> |
||||
|
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) |
||||
|
: container_(begin, end) {} |
||||
|
virtual ~ValuesInIteratorRangeGenerator() {} |
||||
|
|
||||
|
virtual ParamIteratorInterface<T>* Begin() const { |
||||
|
return new Iterator(this, container_.begin()); |
||||
|
} |
||||
|
virtual ParamIteratorInterface<T>* End() const { |
||||
|
return new Iterator(this, container_.end()); |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
typedef typename ::std::vector<T> ContainerType; |
||||
|
|
||||
|
class Iterator : public ParamIteratorInterface<T> { |
||||
|
public: |
||||
|
Iterator(const ParamGeneratorInterface<T>* base, |
||||
|
typename ContainerType::const_iterator iterator) |
||||
|
: base_(base), iterator_(iterator) {} |
||||
|
virtual ~Iterator() {} |
||||
|
|
||||
|
virtual const ParamGeneratorInterface<T>* BaseGenerator() const { |
||||
|
return base_; |
||||
|
} |
||||
|
virtual void Advance() { |
||||
|
++iterator_; |
||||
|
value_.reset(); |
||||
|
} |
||||
|
virtual ParamIteratorInterface<T>* Clone() const { |
||||
|
return new Iterator(*this); |
||||
|
} |
||||
|
// We need to use cached value referenced by iterator_ because *iterator_
|
||||
|
// can return a temporary object (and of type other then T), so just
|
||||
|
// having "return &*iterator_;" doesn't work.
|
||||
|
// value_ is updated here and not in Advance() because Advance()
|
||||
|
// can advance iterator_ beyond the end of the range, and we cannot
|
||||
|
// detect that fact. The client code, on the other hand, is
|
||||
|
// responsible for not calling Current() on an out-of-range iterator.
|
||||
|
virtual const T* Current() const { |
||||
|
if (value_.get() == NULL) |
||||
|
value_.reset(new T(*iterator_)); |
||||
|
return value_.get(); |
||||
|
} |
||||
|
virtual bool Equals(const ParamIteratorInterface<T>& other) const { |
||||
|
// Having the same base generator guarantees that the other
|
||||
|
// iterator is of the same type and we can downcast.
|
||||
|
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) |
||||
|
<< "The program attempted to compare iterators " |
||||
|
<< "from different generators." << std::endl; |
||||
|
return iterator_ == |
||||
|
CheckedDowncastToActualType<const Iterator>(&other)->iterator_; |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
Iterator(const Iterator& other) |
||||
|
// The explicit constructor call suppresses a false warning
|
||||
|
// emitted by gcc when supplied with the -Wextra option.
|
||||
|
: ParamIteratorInterface<T>(), |
||||
|
base_(other.base_), |
||||
|
iterator_(other.iterator_) {} |
||||
|
|
||||
|
const ParamGeneratorInterface<T>* const base_; |
||||
|
typename ContainerType::const_iterator iterator_; |
||||
|
// A cached value of *iterator_. We keep it here to allow access by
|
||||
|
// pointer in the wrapping iterator's operator->().
|
||||
|
// value_ needs to be mutable to be accessed in Current().
|
||||
|
// Use of scoped_ptr helps manage cached value's lifetime,
|
||||
|
// which is bound by the lifespan of the iterator itself.
|
||||
|
mutable scoped_ptr<const T> value_; |
||||
|
}; // class ValuesInIteratorRangeGenerator::Iterator
|
||||
|
|
||||
|
// No implementation - assignment is unsupported.
|
||||
|
void operator=(const ValuesInIteratorRangeGenerator& other); |
||||
|
|
||||
|
const ContainerType container_; |
||||
|
}; // class ValuesInIteratorRangeGenerator
|
||||
|
|
||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
|
//
|
||||
|
// Stores a parameter value and later creates tests parameterized with that
|
||||
|
// value.
|
||||
|
template <class TestClass> |
||||
|
class ParameterizedTestFactory : public TestFactoryBase { |
||||
|
public: |
||||
|
typedef typename TestClass::ParamType ParamType; |
||||
|
explicit ParameterizedTestFactory(ParamType parameter) : |
||||
|
parameter_(parameter) {} |
||||
|
virtual Test* CreateTest() { |
||||
|
TestClass::SetParam(¶meter_); |
||||
|
return new TestClass(); |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
const ParamType parameter_; |
||||
|
|
||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); |
||||
|
}; |
||||
|
|
||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
|
//
|
||||
|
// TestMetaFactoryBase is a base class for meta-factories that create
|
||||
|
// test factories for passing into MakeAndRegisterTestInfo function.
|
||||
|
template <class ParamType> |
||||
|
class TestMetaFactoryBase { |
||||
|
public: |
||||
|
virtual ~TestMetaFactoryBase() {} |
||||
|
|
||||
|
virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; |
||||
|
}; |
||||
|
|
||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
|
//
|
||||
|
// TestMetaFactory creates test factories for passing into
|
||||
|
// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
|
||||
|
// ownership of test factory pointer, same factory object cannot be passed
|
||||
|
// into that method twice. But ParameterizedTestCaseInfo is going to call
|
||||
|
// it for each Test/Parameter value combination. Thus it needs meta factory
|
||||
|
// creator class.
|
||||
|
template <class TestCase> |
||||
|
class TestMetaFactory |
||||
|
: public TestMetaFactoryBase<typename TestCase::ParamType> { |
||||
|
public: |
||||
|
typedef typename TestCase::ParamType ParamType; |
||||
|
|
||||
|
TestMetaFactory() {} |
||||
|
|
||||
|
virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { |
||||
|
return new ParameterizedTestFactory<TestCase>(parameter); |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); |
||||
|
}; |
||||
|
|
||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
|
//
|
||||
|
// ParameterizedTestCaseInfoBase is a generic interface
|
||||
|
// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
|
||||
|
// accumulates test information provided by TEST_P macro invocations
|
||||
|
// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
|
||||
|
// and uses that information to register all resulting test instances
|
||||
|
// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
|
||||
|
// a collection of pointers to the ParameterizedTestCaseInfo objects
|
||||
|
// and calls RegisterTests() on each of them when asked.
|
||||
|
class ParameterizedTestCaseInfoBase { |
||||
|
public: |
||||
|
virtual ~ParameterizedTestCaseInfoBase() {} |
||||
|
|
||||
|
// Base part of test case name for display purposes.
|
||||
|
virtual const string& GetTestCaseName() const = 0; |
||||
|
// Test case id to verify identity.
|
||||
|
virtual TypeId GetTestCaseTypeId() const = 0; |
||||
|
// UnitTest class invokes this method to register tests in this
|
||||
|
// test case right before running them in RUN_ALL_TESTS macro.
|
||||
|
// This method should not be called more then once on any single
|
||||
|
// instance of a ParameterizedTestCaseInfoBase derived class.
|
||||
|
virtual void RegisterTests() = 0; |
||||
|
|
||||
|
protected: |
||||
|
ParameterizedTestCaseInfoBase() {} |
||||
|
|
||||
|
private: |
||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); |
||||
|
}; |
||||
|
|
||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
|
//
|
||||
|
// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
|
||||
|
// macro invocations for a particular test case and generators
|
||||
|
// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
|
||||
|
// test case. It registers tests with all values generated by all
|
||||
|
// generators when asked.
|
||||
|
template <class TestCase> |
||||
|
class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { |
||||
|
public: |
||||
|
// ParamType and GeneratorCreationFunc are private types but are required
|
||||
|
// for declarations of public methods AddTestPattern() and
|
||||
|
// AddTestCaseInstantiation().
|
||||
|
typedef typename TestCase::ParamType ParamType; |
||||
|
// A function that returns an instance of appropriate generator type.
|
||||
|
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)(); |
||||
|
|
||||
|
explicit ParameterizedTestCaseInfo(const char* name) |
||||
|
: test_case_name_(name) {} |
||||
|
|
||||
|
// Test case base name for display purposes.
|
||||
|
virtual const string& GetTestCaseName() const { return test_case_name_; } |
||||
|
// Test case id to verify identity.
|
||||
|
virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); } |
||||
|
// TEST_P macro uses AddTestPattern() to record information
|
||||
|
// about a single test in a LocalTestInfo structure.
|
||||
|
// test_case_name is the base name of the test case (without invocation
|
||||
|
// prefix). test_base_name is the name of an individual test without
|
||||
|
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
|
||||
|
// test case base name and DoBar is test base name.
|
||||
|
void AddTestPattern(const char* test_case_name, |
||||
|
const char* test_base_name, |
||||
|
TestMetaFactoryBase<ParamType>* meta_factory) { |
||||
|
tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name, |
||||
|
test_base_name, |
||||
|
meta_factory))); |
||||
|
} |
||||
|
// INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
|
||||
|
// about a generator.
|
||||
|
int AddTestCaseInstantiation(const string& instantiation_name, |
||||
|
GeneratorCreationFunc* func, |
||||
|
const char* /* file */, |
||||
|
int /* line */) { |
||||
|
instantiations_.push_back(::std::make_pair(instantiation_name, func)); |
||||
|
return 0; // Return value used only to run this method in namespace scope.
|
||||
|
} |
||||
|
// UnitTest class invokes this method to register tests in this test case
|
||||
|
// test cases right before running tests in RUN_ALL_TESTS macro.
|
||||
|
// This method should not be called more then once on any single
|
||||
|
// instance of a ParameterizedTestCaseInfoBase derived class.
|
||||
|
// UnitTest has a guard to prevent from calling this method more then once.
|
||||
|
virtual void RegisterTests() { |
||||
|
for (typename TestInfoContainer::iterator test_it = tests_.begin(); |
||||
|
test_it != tests_.end(); ++test_it) { |
||||
|
linked_ptr<TestInfo> test_info = *test_it; |
||||
|
for (typename InstantiationContainer::iterator gen_it = |
||||
|
instantiations_.begin(); gen_it != instantiations_.end(); |
||||
|
++gen_it) { |
||||
|
const string& instantiation_name = gen_it->first; |
||||
|
ParamGenerator<ParamType> generator((*gen_it->second)()); |
||||
|
|
||||
|
string test_case_name; |
||||
|
if ( !instantiation_name.empty() ) |
||||
|
test_case_name = instantiation_name + "/"; |
||||
|
test_case_name += test_info->test_case_base_name; |
||||
|
|
||||
|
int i = 0; |
||||
|
for (typename ParamGenerator<ParamType>::iterator param_it = |
||||
|
generator.begin(); |
||||
|
param_it != generator.end(); ++param_it, ++i) { |
||||
|
Message test_name_stream; |
||||
|
test_name_stream << test_info->test_base_name << "/" << i; |
||||
|
MakeAndRegisterTestInfo( |
||||
|
test_case_name.c_str(), |
||||
|
test_name_stream.GetString().c_str(), |
||||
|
NULL, // No type parameter.
|
||||
|
PrintToString(*param_it).c_str(), |
||||
|
GetTestCaseTypeId(), |
||||
|
TestCase::SetUpTestCase, |
||||
|
TestCase::TearDownTestCase, |
||||
|
test_info->test_meta_factory->CreateTestFactory(*param_it)); |
||||
|
} // for param_it
|
||||
|
} // for gen_it
|
||||
|
} // for test_it
|
||||
|
} // RegisterTests
|
||||
|
|
||||
|
private: |
||||
|
// LocalTestInfo structure keeps information about a single test registered
|
||||
|
// with TEST_P macro.
|
||||
|
struct TestInfo { |
||||
|
TestInfo(const char* a_test_case_base_name, |
||||
|
const char* a_test_base_name, |
||||
|
TestMetaFactoryBase<ParamType>* a_test_meta_factory) : |
||||
|
test_case_base_name(a_test_case_base_name), |
||||
|
test_base_name(a_test_base_name), |
||||
|
test_meta_factory(a_test_meta_factory) {} |
||||
|
|
||||
|
const string test_case_base_name; |
||||
|
const string test_base_name; |
||||
|
const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory; |
||||
|
}; |
||||
|
typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer; |
||||
|
// Keeps pairs of <Instantiation name, Sequence generator creation function>
|
||||
|
// received from INSTANTIATE_TEST_CASE_P macros.
|
||||
|
typedef ::std::vector<std::pair<string, GeneratorCreationFunc*> > |
||||
|
InstantiationContainer; |
||||
|
|
||||
|
const string test_case_name_; |
||||
|
TestInfoContainer tests_; |
||||
|
InstantiationContainer instantiations_; |
||||
|
|
||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); |
||||
|
}; // class ParameterizedTestCaseInfo
|
||||
|
|
||||
|
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
|
//
|
||||
|
// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
|
||||
|
// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
|
||||
|
// macros use it to locate their corresponding ParameterizedTestCaseInfo
|
||||
|
// descriptors.
|
||||
|
class ParameterizedTestCaseRegistry { |
||||
|
public: |
||||
|
ParameterizedTestCaseRegistry() {} |
||||
|
~ParameterizedTestCaseRegistry() { |
||||
|
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); |
||||
|
it != test_case_infos_.end(); ++it) { |
||||
|
delete *it; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Looks up or creates and returns a structure containing information about
|
||||
|
// tests and instantiations of a particular test case.
|
||||
|
template <class TestCase> |
||||
|
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder( |
||||
|
const char* test_case_name, |
||||
|
const char* file, |
||||
|
int line) { |
||||
|
ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL; |
||||
|
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); |
||||
|
it != test_case_infos_.end(); ++it) { |
||||
|
if ((*it)->GetTestCaseName() == test_case_name) { |
||||
|
if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) { |
||||
|
// Complain about incorrect usage of Google Test facilities
|
||||
|
// and terminate the program since we cannot guaranty correct
|
||||
|
// test case setup and tear-down in this case.
|
||||
|
ReportInvalidTestCaseType(test_case_name, file, line); |
||||
|
posix::Abort(); |
||||
|
} else { |
||||
|
// At this point we are sure that the object we found is of the same
|
||||
|
// type we are looking for, so we downcast it to that type
|
||||
|
// without further checks.
|
||||
|
typed_test_info = CheckedDowncastToActualType< |
||||
|
ParameterizedTestCaseInfo<TestCase> >(*it); |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
if (typed_test_info == NULL) { |
||||
|
typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name); |
||||
|
test_case_infos_.push_back(typed_test_info); |
||||
|
} |
||||
|
return typed_test_info; |
||||
|
} |
||||
|
void RegisterTests() { |
||||
|
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); |
||||
|
it != test_case_infos_.end(); ++it) { |
||||
|
(*it)->RegisterTests(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer; |
||||
|
|
||||
|
TestCaseInfoContainer test_case_infos_; |
||||
|
|
||||
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); |
||||
|
}; |
||||
|
|
||||
|
} // namespace internal
|
||||
|
} // namespace testing
|
||||
|
|
||||
|
#endif // GTEST_HAS_PARAM_TEST
|
||||
|
|
||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
|
File diff suppressed because it is too large
@ -0,0 +1,167 @@ |
|||||
|
// Copyright 2005, 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.
|
||||
|
//
|
||||
|
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
|
||||
|
//
|
||||
|
// The Google C++ Testing Framework (Google Test)
|
||||
|
//
|
||||
|
// This header file declares the String class and functions used internally by
|
||||
|
// Google Test. They are subject to change without notice. They should not used
|
||||
|
// by code external to Google Test.
|
||||
|
//
|
||||
|
// This header file is #included by <gtest/internal/gtest-internal.h>.
|
||||
|
// It should not be #included by other files.
|
||||
|
|
||||
|
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ |
||||
|
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ |
||||
|
|
||||
|
#ifdef __BORLANDC__ |
||||
|
// string.h is not guaranteed to provide strcpy on C++ Builder.
|
||||
|
# include <mem.h> |
||||
|
#endif |
||||
|
|
||||
|
#include <string.h> |
||||
|
#include <string> |
||||
|
|
||||
|
#include "gtest/internal/gtest-port.h" |
||||
|
|
||||
|
namespace testing { |
||||
|
namespace internal { |
||||
|
|
||||
|
// String - an abstract class holding static string utilities.
|
||||
|
class GTEST_API_ String { |
||||
|
public: |
||||
|
// Static utility methods
|
||||
|
|
||||
|
// Clones a 0-terminated C string, allocating memory using new. The
|
||||
|
// caller is responsible for deleting the return value using
|
||||
|
// delete[]. Returns the cloned string, or NULL if the input is
|
||||
|
// NULL.
|
||||
|
//
|
||||
|
// This is different from strdup() in string.h, which allocates
|
||||
|
// memory using malloc().
|
||||
|
static const char* CloneCString(const char* c_str); |
||||
|
|
||||
|
#if GTEST_OS_WINDOWS_MOBILE |
||||
|
// Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
|
||||
|
// able to pass strings to Win32 APIs on CE we need to convert them
|
||||
|
// to 'Unicode', UTF-16.
|
||||
|
|
||||
|
// Creates a UTF-16 wide string from the given ANSI string, allocating
|
||||
|
// memory using new. The caller is responsible for deleting the return
|
||||
|
// value using delete[]. Returns the wide string, or NULL if the
|
||||
|
// input is NULL.
|
||||
|
//
|
||||
|
// The wide string is created using the ANSI codepage (CP_ACP) to
|
||||
|
// match the behaviour of the ANSI versions of Win32 calls and the
|
||||
|
// C runtime.
|
||||
|
static LPCWSTR AnsiToUtf16(const char* c_str); |
||||
|
|
||||
|
// Creates an ANSI string from the given wide string, allocating
|
||||
|
// memory using new. The caller is responsible for deleting the return
|
||||
|
// value using delete[]. Returns the ANSI string, or NULL if the
|
||||
|
// input is NULL.
|
||||
|
//
|
||||
|
// The returned string is created using the ANSI codepage (CP_ACP) to
|
||||
|
// match the behaviour of the ANSI versions of Win32 calls and the
|
||||
|
// C runtime.
|
||||
|
static const char* Utf16ToAnsi(LPCWSTR utf16_str); |
||||
|
#endif |
||||
|
|
||||
|
// Compares two C strings. Returns true iff they have the same content.
|
||||
|
//
|
||||
|
// Unlike strcmp(), this function can handle NULL argument(s). A
|
||||
|
// NULL C string is considered different to any non-NULL C string,
|
||||
|
// including the empty string.
|
||||
|
static bool CStringEquals(const char* lhs, const char* rhs); |
||||
|
|
||||
|
// Converts a wide C string to a String using the UTF-8 encoding.
|
||||
|
// NULL will be converted to "(null)". If an error occurred during
|
||||
|
// the conversion, "(failed to convert from wide string)" is
|
||||
|
// returned.
|
||||
|
static std::string ShowWideCString(const wchar_t* wide_c_str); |
||||
|
|
||||
|
// Compares two wide C strings. Returns true iff they have the same
|
||||
|
// content.
|
||||
|
//
|
||||
|
// Unlike wcscmp(), this function can handle NULL argument(s). A
|
||||
|
// NULL C string is considered different to any non-NULL C string,
|
||||
|
// including the empty string.
|
||||
|
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); |
||||
|
|
||||
|
// Compares two C strings, ignoring case. Returns true iff they
|
||||
|
// have the same content.
|
||||
|
//
|
||||
|
// Unlike strcasecmp(), this function can handle NULL argument(s).
|
||||
|
// A NULL C string is considered different to any non-NULL C string,
|
||||
|
// including the empty string.
|
||||
|
static bool CaseInsensitiveCStringEquals(const char* lhs, |
||||
|
const char* rhs); |
||||
|
|
||||
|
// Compares two wide C strings, ignoring case. Returns true iff they
|
||||
|
// have the same content.
|
||||
|
//
|
||||
|
// Unlike wcscasecmp(), this function can handle NULL argument(s).
|
||||
|
// A NULL C string is considered different to any non-NULL wide C string,
|
||||
|
// including the empty string.
|
||||
|
// NB: The implementations on different platforms slightly differ.
|
||||
|
// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
|
||||
|
// environment variable. On GNU platform this method uses wcscasecmp
|
||||
|
// which compares according to LC_CTYPE category of the current locale.
|
||||
|
// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
|
||||
|
// current locale.
|
||||
|
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, |
||||
|
const wchar_t* rhs); |
||||
|
|
||||
|
// Returns true iff the given string ends with the given suffix, ignoring
|
||||
|
// case. Any string is considered to end with an empty suffix.
|
||||
|
static bool EndsWithCaseInsensitive( |
||||
|
const std::string& str, const std::string& suffix); |
||||
|
|
||||
|
// Formats an int value as "%02d".
|
||||
|
static std::string FormatIntWidth2(int value); // "%02d" for width == 2
|
||||
|
|
||||
|
// Formats an int value as "%X".
|
||||
|
static std::string FormatHexInt(int value); |
||||
|
|
||||
|
// Formats a byte as "%02X".
|
||||
|
static std::string FormatByte(unsigned char value); |
||||
|
|
||||
|
private: |
||||
|
String(); // Not meant to be instantiated.
|
||||
|
}; // class String
|
||||
|
|
||||
|
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
|
||||
|
// character in the buffer is replaced with "\\0".
|
||||
|
GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); |
||||
|
|
||||
|
} // namespace internal
|
||||
|
} // namespace testing
|
||||
|
|
||||
|
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
|
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,387 @@ |
|||||
|
// Copyright 2008, 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.
|
||||
|
//
|
||||
|
// Authors: keith.ray@gmail.com (Keith Ray)
|
||||
|
|
||||
|
#include "gtest/gtest-message.h" |
||||
|
#include "gtest/internal/gtest-filepath.h" |
||||
|
#include "gtest/internal/gtest-port.h" |
||||
|
|
||||
|
#include <stdlib.h> |
||||
|
|
||||
|
#if GTEST_OS_WINDOWS_MOBILE |
||||
|
# include <windows.h> |
||||
|
#elif GTEST_OS_WINDOWS |
||||
|
# include <direct.h> |
||||
|
# include <io.h> |
||||
|
#elif GTEST_OS_SYMBIAN |
||||
|
// Symbian OpenC has PATH_MAX in sys/syslimits.h
|
||||
|
# include <sys/syslimits.h> |
||||
|
#else |
||||
|
# include <limits.h> |
||||
|
# include <climits> // Some Linux distributions define PATH_MAX here.
|
||||
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
|
||||
|
#if GTEST_OS_WINDOWS |
||||
|
# define GTEST_PATH_MAX_ _MAX_PATH |
||||
|
#elif defined(PATH_MAX) |
||||
|
# define GTEST_PATH_MAX_ PATH_MAX |
||||
|
#elif defined(_XOPEN_PATH_MAX) |
||||
|
# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX |
||||
|
#else |
||||
|
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX |
||||
|
#endif // GTEST_OS_WINDOWS
|
||||
|
|
||||
|
#include "gtest/internal/gtest-string.h" |
||||
|
|
||||
|
namespace testing { |
||||
|
namespace internal { |
||||
|
|
||||
|
#if GTEST_OS_WINDOWS |
||||
|
// On Windows, '\\' is the standard path separator, but many tools and the
|
||||
|
// Windows API also accept '/' as an alternate path separator. Unless otherwise
|
||||
|
// noted, a file path can contain either kind of path separators, or a mixture
|
||||
|
// of them.
|
||||
|
const char kPathSeparator = '\\'; |
||||
|
const char kAlternatePathSeparator = '/'; |
||||
|
const char kAlternatePathSeparatorString[] = "/"; |
||||
|
# if GTEST_OS_WINDOWS_MOBILE |
||||
|
// Windows CE doesn't have a current directory. You should not use
|
||||
|
// the current directory in tests on Windows CE, but this at least
|
||||
|
// provides a reasonable fallback.
|
||||
|
const char kCurrentDirectoryString[] = "\\"; |
||||
|
// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
|
||||
|
const DWORD kInvalidFileAttributes = 0xffffffff; |
||||
|
# else |
||||
|
const char kCurrentDirectoryString[] = ".\\"; |
||||
|
# endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
#else |
||||
|
const char kPathSeparator = '/'; |
||||
|
const char kCurrentDirectoryString[] = "./"; |
||||
|
#endif // GTEST_OS_WINDOWS
|
||||
|
|
||||
|
// Returns whether the given character is a valid path separator.
|
||||
|
static bool IsPathSeparator(char c) { |
||||
|
#if GTEST_HAS_ALT_PATH_SEP_ |
||||
|
return (c == kPathSeparator) || (c == kAlternatePathSeparator); |
||||
|
#else |
||||
|
return c == kPathSeparator; |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
// Returns the current working directory, or "" if unsuccessful.
|
||||
|
FilePath FilePath::GetCurrentDir() { |
||||
|
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT |
||||
|
// Windows CE doesn't have a current directory, so we just return
|
||||
|
// something reasonable.
|
||||
|
return FilePath(kCurrentDirectoryString); |
||||
|
#elif GTEST_OS_WINDOWS |
||||
|
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; |
||||
|
return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); |
||||
|
#else |
||||
|
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; |
||||
|
char* result = getcwd(cwd, sizeof(cwd)); |
||||
|
# if GTEST_OS_NACL |
||||
|
// getcwd will likely fail in NaCl due to the sandbox, so return something
|
||||
|
// reasonable. The user may have provided a shim implementation for getcwd,
|
||||
|
// however, so fallback only when failure is detected.
|
||||
|
return FilePath(result == NULL ? kCurrentDirectoryString : cwd); |
||||
|
# endif // GTEST_OS_NACL
|
||||
|
return FilePath(result == NULL ? "" : cwd); |
||||
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
} |
||||
|
|
||||
|
// Returns a copy of the FilePath with the case-insensitive extension removed.
|
||||
|
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
|
||||
|
// FilePath("dir/file"). If a case-insensitive extension is not
|
||||
|
// found, returns a copy of the original FilePath.
|
||||
|
FilePath FilePath::RemoveExtension(const char* extension) const { |
||||
|
const std::string dot_extension = std::string(".") + extension; |
||||
|
if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { |
||||
|
return FilePath(pathname_.substr( |
||||
|
0, pathname_.length() - dot_extension.length())); |
||||
|
} |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
// Returns a pointer to the last occurence of a valid path separator in
|
||||
|
// the FilePath. On Windows, for example, both '/' and '\' are valid path
|
||||
|
// separators. Returns NULL if no path separator was found.
|
||||
|
const char* FilePath::FindLastPathSeparator() const { |
||||
|
const char* const last_sep = strrchr(c_str(), kPathSeparator); |
||||
|
#if GTEST_HAS_ALT_PATH_SEP_ |
||||
|
const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); |
||||
|
// Comparing two pointers of which only one is NULL is undefined.
|
||||
|
if (last_alt_sep != NULL && |
||||
|
(last_sep == NULL || last_alt_sep > last_sep)) { |
||||
|
return last_alt_sep; |
||||
|
} |
||||
|
#endif |
||||
|
return last_sep; |
||||
|
} |
||||
|
|
||||
|
// Returns a copy of the FilePath with the directory part removed.
|
||||
|
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
|
||||
|
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
|
||||
|
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
|
||||
|
// returns an empty FilePath ("").
|
||||
|
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
|
FilePath FilePath::RemoveDirectoryName() const { |
||||
|
const char* const last_sep = FindLastPathSeparator(); |
||||
|
return last_sep ? FilePath(last_sep + 1) : *this; |
||||
|
} |
||||
|
|
||||
|
// RemoveFileName returns the directory path with the filename removed.
|
||||
|
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
|
||||
|
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
|
||||
|
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
|
||||
|
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
|
||||
|
// On Windows platform, '\' is the path separator, otherwise it is '/'.
|
||||
|
FilePath FilePath::RemoveFileName() const { |
||||
|
const char* const last_sep = FindLastPathSeparator(); |
||||
|
std::string dir; |
||||
|
if (last_sep) { |
||||
|
dir = std::string(c_str(), last_sep + 1 - c_str()); |
||||
|
} else { |
||||
|
dir = kCurrentDirectoryString; |
||||
|
} |
||||
|
return FilePath(dir); |
||||
|
} |
||||
|
|
||||
|
// Helper functions for naming files in a directory for xml output.
|
||||
|
|
||||
|
// Given directory = "dir", base_name = "test", number = 0,
|
||||
|
// extension = "xml", returns "dir/test.xml". If number is greater
|
||||
|
// than zero (e.g., 12), returns "dir/test_12.xml".
|
||||
|
// On Windows platform, uses \ as the separator rather than /.
|
||||
|
FilePath FilePath::MakeFileName(const FilePath& directory, |
||||
|
const FilePath& base_name, |
||||
|
int number, |
||||
|
const char* extension) { |
||||
|
std::string file; |
||||
|
if (number == 0) { |
||||
|
file = base_name.string() + "." + extension; |
||||
|
} else { |
||||
|
file = base_name.string() + "_" + StreamableToString(number) |
||||
|
+ "." + extension; |
||||
|
} |
||||
|
return ConcatPaths(directory, FilePath(file)); |
||||
|
} |
||||
|
|
||||
|
// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
|
||||
|
// On Windows, uses \ as the separator rather than /.
|
||||
|
FilePath FilePath::ConcatPaths(const FilePath& directory, |
||||
|
const FilePath& relative_path) { |
||||
|
if (directory.IsEmpty()) |
||||
|
return relative_path; |
||||
|
const FilePath dir(directory.RemoveTrailingPathSeparator()); |
||||
|
return FilePath(dir.string() + kPathSeparator + relative_path.string()); |
||||
|
} |
||||
|
|
||||
|
// Returns true if pathname describes something findable in the file-system,
|
||||
|
// either a file, directory, or whatever.
|
||||
|
bool FilePath::FileOrDirectoryExists() const { |
||||
|
#if GTEST_OS_WINDOWS_MOBILE |
||||
|
LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); |
||||
|
const DWORD attributes = GetFileAttributes(unicode); |
||||
|
delete [] unicode; |
||||
|
return attributes != kInvalidFileAttributes; |
||||
|
#else |
||||
|
posix::StatStruct file_stat; |
||||
|
return posix::Stat(pathname_.c_str(), &file_stat) == 0; |
||||
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
} |
||||
|
|
||||
|
// Returns true if pathname describes a directory in the file-system
|
||||
|
// that exists.
|
||||
|
bool FilePath::DirectoryExists() const { |
||||
|
bool result = false; |
||||
|
#if GTEST_OS_WINDOWS |
||||
|
// Don't strip off trailing separator if path is a root directory on
|
||||
|
// Windows (like "C:\\").
|
||||
|
const FilePath& path(IsRootDirectory() ? *this : |
||||
|
RemoveTrailingPathSeparator()); |
||||
|
#else |
||||
|
const FilePath& path(*this); |
||||
|
#endif |
||||
|
|
||||
|
#if GTEST_OS_WINDOWS_MOBILE |
||||
|
LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); |
||||
|
const DWORD attributes = GetFileAttributes(unicode); |
||||
|
delete [] unicode; |
||||
|
if ((attributes != kInvalidFileAttributes) && |
||||
|
(attributes & FILE_ATTRIBUTE_DIRECTORY)) { |
||||
|
result = true; |
||||
|
} |
||||
|
#else |
||||
|
posix::StatStruct file_stat; |
||||
|
result = posix::Stat(path.c_str(), &file_stat) == 0 && |
||||
|
posix::IsDir(file_stat); |
||||
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
// Returns true if pathname describes a root directory. (Windows has one
|
||||
|
// root directory per disk drive.)
|
||||
|
bool FilePath::IsRootDirectory() const { |
||||
|
#if GTEST_OS_WINDOWS |
||||
|
// TODO(wan@google.com): on Windows a network share like
|
||||
|
// \\server\share can be a root directory, although it cannot be the
|
||||
|
// current directory. Handle this properly.
|
||||
|
return pathname_.length() == 3 && IsAbsolutePath(); |
||||
|
#else |
||||
|
return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
// Returns true if pathname describes an absolute path.
|
||||
|
bool FilePath::IsAbsolutePath() const { |
||||
|
const char* const name = pathname_.c_str(); |
||||
|
#if GTEST_OS_WINDOWS |
||||
|
return pathname_.length() >= 3 && |
||||
|
((name[0] >= 'a' && name[0] <= 'z') || |
||||
|
(name[0] >= 'A' && name[0] <= 'Z')) && |
||||
|
name[1] == ':' && |
||||
|
IsPathSeparator(name[2]); |
||||
|
#else |
||||
|
return IsPathSeparator(name[0]); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
// Returns a pathname for a file that does not currently exist. The pathname
|
||||
|
// will be directory/base_name.extension or
|
||||
|
// directory/base_name_<number>.extension if directory/base_name.extension
|
||||
|
// already exists. The number will be incremented until a pathname is found
|
||||
|
// that does not already exist.
|
||||
|
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
|
||||
|
// There could be a race condition if two or more processes are calling this
|
||||
|
// function at the same time -- they could both pick the same filename.
|
||||
|
FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, |
||||
|
const FilePath& base_name, |
||||
|
const char* extension) { |
||||
|
FilePath full_pathname; |
||||
|
int number = 0; |
||||
|
do { |
||||
|
full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); |
||||
|
} while (full_pathname.FileOrDirectoryExists()); |
||||
|
return full_pathname; |
||||
|
} |
||||
|
|
||||
|
// Returns true if FilePath ends with a path separator, which indicates that
|
||||
|
// it is intended to represent a directory. Returns false otherwise.
|
||||
|
// This does NOT check that a directory (or file) actually exists.
|
||||
|
bool FilePath::IsDirectory() const { |
||||
|
return !pathname_.empty() && |
||||
|
IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); |
||||
|
} |
||||
|
|
||||
|
// Create directories so that path exists. Returns true if successful or if
|
||||
|
// the directories already exist; returns false if unable to create directories
|
||||
|
// for any reason.
|
||||
|
bool FilePath::CreateDirectoriesRecursively() const { |
||||
|
if (!this->IsDirectory()) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (pathname_.length() == 0 || this->DirectoryExists()) { |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); |
||||
|
return parent.CreateDirectoriesRecursively() && this->CreateFolder(); |
||||
|
} |
||||
|
|
||||
|
// Create the directory so that path exists. Returns true if successful or
|
||||
|
// if the directory already exists; returns false if unable to create the
|
||||
|
// directory for any reason, including if the parent directory does not
|
||||
|
// exist. Not named "CreateDirectory" because that's a macro on Windows.
|
||||
|
bool FilePath::CreateFolder() const { |
||||
|
#if GTEST_OS_WINDOWS_MOBILE |
||||
|
FilePath removed_sep(this->RemoveTrailingPathSeparator()); |
||||
|
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); |
||||
|
int result = CreateDirectory(unicode, NULL) ? 0 : -1; |
||||
|
delete [] unicode; |
||||
|
#elif GTEST_OS_WINDOWS |
||||
|
int result = _mkdir(pathname_.c_str()); |
||||
|
#else |
||||
|
int result = mkdir(pathname_.c_str(), 0777); |
||||
|
#endif // GTEST_OS_WINDOWS_MOBILE
|
||||
|
|
||||
|
if (result == -1) { |
||||
|
return this->DirectoryExists(); // An error is OK if the directory exists.
|
||||
|
} |
||||
|
return true; // No error.
|
||||
|
} |
||||
|
|
||||
|
// If input name has a trailing separator character, remove it and return the
|
||||
|
// name, otherwise return the name string unmodified.
|
||||
|
// On Windows platform, uses \ as the separator, other platforms use /.
|
||||
|
FilePath FilePath::RemoveTrailingPathSeparator() const { |
||||
|
return IsDirectory() |
||||
|
? FilePath(pathname_.substr(0, pathname_.length() - 1)) |
||||
|
: *this; |
||||
|
} |
||||
|
|
||||
|
// Removes any redundant separators that might be in the pathname.
|
||||
|
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
|
||||
|
// redundancies that might be in a pathname involving "." or "..".
|
||||
|
// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
|
||||
|
void FilePath::Normalize() { |
||||
|
if (pathname_.c_str() == NULL) { |
||||
|
pathname_ = ""; |
||||
|
return; |
||||
|
} |
||||
|
const char* src = pathname_.c_str(); |
||||
|
char* const dest = new char[pathname_.length() + 1]; |
||||
|
char* dest_ptr = dest; |
||||
|
memset(dest_ptr, 0, pathname_.length() + 1); |
||||
|
|
||||
|
while (*src != '\0') { |
||||
|
*dest_ptr = *src; |
||||
|
if (!IsPathSeparator(*src)) { |
||||
|
src++; |
||||
|
} else { |
||||
|
#if GTEST_HAS_ALT_PATH_SEP_ |
||||
|
if (*dest_ptr == kAlternatePathSeparator) { |
||||
|
*dest_ptr = kPathSeparator; |
||||
|
} |
||||
|
#endif |
||||
|
while (IsPathSeparator(*src)) |
||||
|
src++; |
||||
|
} |
||||
|
dest_ptr++; |
||||
|
} |
||||
|
*dest_ptr = '\0'; |
||||
|
pathname_ = dest; |
||||
|
delete[] dest; |
||||
|
} |
||||
|
|
||||
|
} // namespace internal
|
||||
|
} // namespace testing
|
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,373 @@ |
|||||
|
// Copyright 2007, 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)
|
||||
|
|
||||
|
// Google Test - The Google C++ Testing Framework
|
||||
|
//
|
||||
|
// This file implements a universal value printer that can print a
|
||||
|
// value of any type T:
|
||||
|
//
|
||||
|
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
|
||||
|
//
|
||||
|
// It uses the << operator when possible, and prints the bytes in the
|
||||
|
// object otherwise. A user can override its behavior for a class
|
||||
|
// type Foo by defining either operator<<(::std::ostream&, const Foo&)
|
||||
|
// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that
|
||||
|
// defines Foo.
|
||||
|
|
||||
|
#include "gtest/gtest-printers.h" |
||||
|
#include <ctype.h> |
||||
|
#include <stdio.h> |
||||
|
#include <cwchar> |
||||
|
#include <ostream> // NOLINT |
||||
|
#include <string> |
||||
|
#include "gtest/internal/gtest-port.h" |
||||
|
|
||||
|
namespace testing { |
||||
|
|
||||
|
namespace { |
||||
|
|
||||
|
using ::std::ostream; |
||||
|
|
||||
|
// Prints a segment of bytes in the given object.
|
||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ |
||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ |
||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ |
||||
|
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, |
||||
|
size_t count, ostream* os) { |
||||
|
char text[5] = ""; |
||||
|
for (size_t i = 0; i != count; i++) { |
||||
|
const size_t j = start + i; |
||||
|
if (i != 0) { |
||||
|
// Organizes the bytes into groups of 2 for easy parsing by
|
||||
|
// human.
|
||||
|
if ((j % 2) == 0) |
||||
|
*os << ' '; |
||||
|
else |
||||
|
*os << '-'; |
||||
|
} |
||||
|
GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); |
||||
|
*os << text; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Prints the bytes in the given value to the given ostream.
|
||||
|
void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, |
||||
|
ostream* os) { |
||||
|
// Tells the user how big the object is.
|
||||
|
*os << count << "-byte object <"; |
||||
|
|
||||
|
const size_t kThreshold = 132; |
||||
|
const size_t kChunkSize = 64; |
||||
|
// If the object size is bigger than kThreshold, we'll have to omit
|
||||
|
// some details by printing only the first and the last kChunkSize
|
||||
|
// bytes.
|
||||
|
// TODO(wan): let the user control the threshold using a flag.
|
||||
|
if (count < kThreshold) { |
||||
|
PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); |
||||
|
} else { |
||||
|
PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); |
||||
|
*os << " ... "; |
||||
|
// Rounds up to 2-byte boundary.
|
||||
|
const size_t resume_pos = (count - kChunkSize + 1)/2*2; |
||||
|
PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); |
||||
|
} |
||||
|
*os << ">"; |
||||
|
} |
||||
|
|
||||
|
} // namespace
|
||||
|
|
||||
|
namespace internal2 { |
||||
|
|
||||
|
// Delegates to PrintBytesInObjectToImpl() to print the bytes in the
|
||||
|
// given object. The delegation simplifies the implementation, which
|
||||
|
// uses the << operator and thus is easier done outside of the
|
||||
|
// ::testing::internal namespace, which contains a << operator that
|
||||
|
// sometimes conflicts with the one in STL.
|
||||
|
void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, |
||||
|
ostream* os) { |
||||
|
PrintBytesInObjectToImpl(obj_bytes, count, os); |
||||
|
} |
||||
|
|
||||
|
} // namespace internal2
|
||||
|
|
||||
|
namespace internal { |
||||
|
|
||||
|
// Depending on the value of a char (or wchar_t), we print it in one
|
||||
|
// of three formats:
|
||||
|
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
|
||||
|
// - as a hexidecimal escape sequence (e.g. '\x7F'), or
|
||||
|
// - as a special escape sequence (e.g. '\r', '\n').
|
||||
|
enum CharFormat { |
||||
|
kAsIs, |
||||
|
kHexEscape, |
||||
|
kSpecialEscape |
||||
|
}; |
||||
|
|
||||
|
// Returns true if c is a printable ASCII character. We test the
|
||||
|
// value of c directly instead of calling isprint(), which is buggy on
|
||||
|
// Windows Mobile.
|
||||
|
inline bool IsPrintableAscii(wchar_t c) { |
||||
|
return 0x20 <= c && c <= 0x7E; |
||||
|
} |
||||
|
|
||||
|
// Prints a wide or narrow char c as a character literal without the
|
||||
|
// quotes, escaping it when necessary; returns how c was formatted.
|
||||
|
// The template argument UnsignedChar is the unsigned version of Char,
|
||||
|
// which is the type of c.
|
||||
|
template <typename UnsignedChar, typename Char> |
||||
|
static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { |
||||
|
switch (static_cast<wchar_t>(c)) { |
||||
|
case L'\0': |
||||
|
*os << "\\0"; |
||||
|
break; |
||||
|
case L'\'': |
||||
|
*os << "\\'"; |
||||
|
break; |
||||
|
case L'\\': |
||||
|
*os << "\\\\"; |
||||
|
break; |
||||
|
case L'\a': |
||||
|
*os << "\\a"; |
||||
|
break; |
||||
|
case L'\b': |
||||
|
*os << "\\b"; |
||||
|
break; |
||||
|
case L'\f': |
||||
|
*os << "\\f"; |
||||
|
break; |
||||
|
case L'\n': |
||||
|
*os << "\\n"; |
||||
|
break; |
||||
|
case L'\r': |
||||
|
*os << "\\r"; |
||||
|
break; |
||||
|
case L'\t': |
||||
|
*os << "\\t"; |
||||
|
break; |
||||
|
case L'\v': |
||||
|
*os << "\\v"; |
||||
|
break; |
||||
|
default: |
||||
|
if (IsPrintableAscii(c)) { |
||||
|
*os << static_cast<char>(c); |
||||
|
return kAsIs; |
||||
|
} else { |
||||
|
*os << "\\x" + String::FormatHexInt(static_cast<UnsignedChar>(c)); |
||||
|
return kHexEscape; |
||||
|
} |
||||
|
} |
||||
|
return kSpecialEscape; |
||||
|
} |
||||
|
|
||||
|
// Prints a wchar_t c as if it's part of a string literal, escaping it when
|
||||
|
// necessary; returns how c was formatted.
|
||||
|
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { |
||||
|
switch (c) { |
||||
|
case L'\'': |
||||
|
*os << "'"; |
||||
|
return kAsIs; |
||||
|
case L'"': |
||||
|
*os << "\\\""; |
||||
|
return kSpecialEscape; |
||||
|
default: |
||||
|
return PrintAsCharLiteralTo<wchar_t>(c, os); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Prints a char c as if it's part of a string literal, escaping it when
|
||||
|
// necessary; returns how c was formatted.
|
||||
|
static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { |
||||
|
return PrintAsStringLiteralTo( |
||||
|
static_cast<wchar_t>(static_cast<unsigned char>(c)), os); |
||||
|
} |
||||
|
|
||||
|
// Prints a wide or narrow character c and its code. '\0' is printed
|
||||
|
// as "'\\0'", other unprintable characters are also properly escaped
|
||||
|
// using the standard C++ escape sequence. The template argument
|
||||
|
// UnsignedChar is the unsigned version of Char, which is the type of c.
|
||||
|
template <typename UnsignedChar, typename Char> |
||||
|
void PrintCharAndCodeTo(Char c, ostream* os) { |
||||
|
// First, print c as a literal in the most readable form we can find.
|
||||
|
*os << ((sizeof(c) > 1) ? "L'" : "'"); |
||||
|
const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os); |
||||
|
*os << "'"; |
||||
|
|
||||
|
// To aid user debugging, we also print c's code in decimal, unless
|
||||
|
// it's 0 (in which case c was printed as '\\0', making the code
|
||||
|
// obvious).
|
||||
|
if (c == 0) |
||||
|
return; |
||||
|
*os << " (" << static_cast<int>(c); |
||||
|
|
||||
|
// For more convenience, we print c's code again in hexidecimal,
|
||||
|
// unless c was already printed in the form '\x##' or the code is in
|
||||
|
// [1, 9].
|
||||
|
if (format == kHexEscape || (1 <= c && c <= 9)) { |
||||
|
// Do nothing.
|
||||
|
} else { |
||||
|
*os << ", 0x" << String::FormatHexInt(static_cast<UnsignedChar>(c)); |
||||
|
} |
||||
|
*os << ")"; |
||||
|
} |
||||
|
|
||||
|
void PrintTo(unsigned char c, ::std::ostream* os) { |
||||
|
PrintCharAndCodeTo<unsigned char>(c, os); |
||||
|
} |
||||
|
void PrintTo(signed char c, ::std::ostream* os) { |
||||
|
PrintCharAndCodeTo<unsigned char>(c, os); |
||||
|
} |
||||
|
|
||||
|
// Prints a wchar_t as a symbol if it is printable or as its internal
|
||||
|
// code otherwise and also as its code. L'\0' is printed as "L'\\0'".
|
||||
|
void PrintTo(wchar_t wc, ostream* os) { |
||||
|
PrintCharAndCodeTo<wchar_t>(wc, os); |
||||
|
} |
||||
|
|
||||
|
// Prints the given array of characters to the ostream. CharType must be either
|
||||
|
// char or wchar_t.
|
||||
|
// The array starts at begin, the length is len, it may include '\0' characters
|
||||
|
// and may not be NUL-terminated.
|
||||
|
template <typename CharType> |
||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ |
||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ |
||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ |
||||
|
static void PrintCharsAsStringTo( |
||||
|
const CharType* begin, size_t len, ostream* os) { |
||||
|
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; |
||||
|
*os << kQuoteBegin; |
||||
|
bool is_previous_hex = false; |
||||
|
for (size_t index = 0; index < len; ++index) { |
||||
|
const CharType cur = begin[index]; |
||||
|
if (is_previous_hex && IsXDigit(cur)) { |
||||
|
// Previous character is of '\x..' form and this character can be
|
||||
|
// interpreted as another hexadecimal digit in its number. Break string to
|
||||
|
// disambiguate.
|
||||
|
*os << "\" " << kQuoteBegin; |
||||
|
} |
||||
|
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; |
||||
|
} |
||||
|
*os << "\""; |
||||
|
} |
||||
|
|
||||
|
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
|
||||
|
// 'begin'. CharType must be either char or wchar_t.
|
||||
|
template <typename CharType> |
||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ |
||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ |
||||
|
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ |
||||
|
static void UniversalPrintCharArray( |
||||
|
const CharType* begin, size_t len, ostream* os) { |
||||
|
// The code
|
||||
|
// const char kFoo[] = "foo";
|
||||
|
// generates an array of 4, not 3, elements, with the last one being '\0'.
|
||||
|
//
|
||||
|
// Therefore when printing a char array, we don't print the last element if
|
||||
|
// it's '\0', such that the output matches the string literal as it's
|
||||
|
// written in the source code.
|
||||
|
if (len > 0 && begin[len - 1] == '\0') { |
||||
|
PrintCharsAsStringTo(begin, len - 1, os); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// If, however, the last element in the array is not '\0', e.g.
|
||||
|
// const char kFoo[] = { 'f', 'o', 'o' };
|
||||
|
// we must print the entire array. We also print a message to indicate
|
||||
|
// that the array is not NUL-terminated.
|
||||
|
PrintCharsAsStringTo(begin, len, os); |
||||
|
*os << " (no terminating NUL)"; |
||||
|
} |
||||
|
|
||||
|
// Prints a (const) char array of 'len' elements, starting at address 'begin'.
|
||||
|
void UniversalPrintArray(const char* begin, size_t len, ostream* os) { |
||||
|
UniversalPrintCharArray(begin, len, os); |
||||
|
} |
||||
|
|
||||
|
// Prints a (const) wchar_t array of 'len' elements, starting at address
|
||||
|
// 'begin'.
|
||||
|
void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { |
||||
|
UniversalPrintCharArray(begin, len, os); |
||||
|
} |
||||
|
|
||||
|
// Prints the given C string to the ostream.
|
||||
|
void PrintTo(const char* s, ostream* os) { |
||||
|
if (s == NULL) { |
||||
|
*os << "NULL"; |
||||
|
} else { |
||||
|
*os << ImplicitCast_<const void*>(s) << " pointing to "; |
||||
|
PrintCharsAsStringTo(s, strlen(s), os); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// MSVC compiler can be configured to define whar_t as a typedef
|
||||
|
// of unsigned short. Defining an overload for const wchar_t* in that case
|
||||
|
// would cause pointers to unsigned shorts be printed as wide strings,
|
||||
|
// possibly accessing more memory than intended and causing invalid
|
||||
|
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
|
||||
|
// wchar_t is implemented as a native type.
|
||||
|
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) |
||||
|
// Prints the given wide C string to the ostream.
|
||||
|
void PrintTo(const wchar_t* s, ostream* os) { |
||||
|
if (s == NULL) { |
||||
|
*os << "NULL"; |
||||
|
} else { |
||||
|
*os << ImplicitCast_<const void*>(s) << " pointing to "; |
||||
|
PrintCharsAsStringTo(s, std::wcslen(s), os); |
||||
|
} |
||||
|
} |
||||
|
#endif // wchar_t is native
|
||||
|
|
||||
|
// Prints a ::string object.
|
||||
|
#if GTEST_HAS_GLOBAL_STRING |
||||
|
void PrintStringTo(const ::string& s, ostream* os) { |
||||
|
PrintCharsAsStringTo(s.data(), s.size(), os); |
||||
|
} |
||||
|
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
|
||||
|
void PrintStringTo(const ::std::string& s, ostream* os) { |
||||
|
PrintCharsAsStringTo(s.data(), s.size(), os); |
||||
|
} |
||||
|
|
||||
|
// Prints a ::wstring object.
|
||||
|
#if GTEST_HAS_GLOBAL_WSTRING |
||||
|
void PrintWideStringTo(const ::wstring& s, ostream* os) { |
||||
|
PrintCharsAsStringTo(s.data(), s.size(), os); |
||||
|
} |
||||
|
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
|
||||
|
#if GTEST_HAS_STD_WSTRING |
||||
|
void PrintWideStringTo(const ::std::wstring& s, ostream* os) { |
||||
|
PrintCharsAsStringTo(s.data(), s.size(), os); |
||||
|
} |
||||
|
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
|
||||
|
} // namespace internal
|
||||
|
|
||||
|
} // namespace testing
|
@ -0,0 +1,110 @@ |
|||||
|
// Copyright 2008, 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: mheule@google.com (Markus Heule)
|
||||
|
//
|
||||
|
// The Google C++ Testing Framework (Google Test)
|
||||
|
|
||||
|
#include "gtest/gtest-test-part.h" |
||||
|
|
||||
|
// Indicates that this translation unit is part of Google Test's
|
||||
|
// implementation. It must come before gtest-internal-inl.h is
|
||||
|
// included, or there will be a compiler error. This trick exists to
|
||||
|
// prevent the accidental inclusion of gtest-internal-inl.h in the
|
||||
|
// user's code.
|
||||
|
#define GTEST_IMPLEMENTATION_ 1 |
||||
|
#include "src/gtest-internal-inl.h" |
||||
|
#undef GTEST_IMPLEMENTATION_ |
||||
|
|
||||
|
namespace testing { |
||||
|
|
||||
|
using internal::GetUnitTestImpl; |
||||
|
|
||||
|
// Gets the summary of the failure message by omitting the stack trace
|
||||
|
// in it.
|
||||
|
std::string TestPartResult::ExtractSummary(const char* message) { |
||||
|
const char* const stack_trace = strstr(message, internal::kStackTraceMarker); |
||||
|
return stack_trace == NULL ? message : |
||||
|
std::string(message, stack_trace); |
||||
|
} |
||||
|
|
||||
|
// Prints a TestPartResult object.
|
||||
|
std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { |
||||
|
return os |
||||
|
<< result.file_name() << ":" << result.line_number() << ": " |
||||
|
<< (result.type() == TestPartResult::kSuccess ? "Success" : |
||||
|
result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : |
||||
|
"Non-fatal failure") << ":\n" |
||||
|
<< result.message() << std::endl; |
||||
|
} |
||||
|
|
||||
|
// Appends a TestPartResult to the array.
|
||||
|
void TestPartResultArray::Append(const TestPartResult& result) { |
||||
|
array_.push_back(result); |
||||
|
} |
||||
|
|
||||
|
// Returns the TestPartResult at the given index (0-based).
|
||||
|
const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { |
||||
|
if (index < 0 || index >= size()) { |
||||
|
printf("\nInvalid index (%d) into TestPartResultArray.\n", index); |
||||
|
internal::posix::Abort(); |
||||
|
} |
||||
|
|
||||
|
return array_[index]; |
||||
|
} |
||||
|
|
||||
|
// Returns the number of TestPartResult objects in the array.
|
||||
|
int TestPartResultArray::size() const { |
||||
|
return static_cast<int>(array_.size()); |
||||
|
} |
||||
|
|
||||
|
namespace internal { |
||||
|
|
||||
|
HasNewFatalFailureHelper::HasNewFatalFailureHelper() |
||||
|
: has_new_fatal_failure_(false), |
||||
|
original_reporter_(GetUnitTestImpl()-> |
||||
|
GetTestPartResultReporterForCurrentThread()) { |
||||
|
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); |
||||
|
} |
||||
|
|
||||
|
HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { |
||||
|
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( |
||||
|
original_reporter_); |
||||
|
} |
||||
|
|
||||
|
void HasNewFatalFailureHelper::ReportTestPartResult( |
||||
|
const TestPartResult& result) { |
||||
|
if (result.fatally_failed()) |
||||
|
has_new_fatal_failure_ = true; |
||||
|
original_reporter_->ReportTestPartResult(result); |
||||
|
} |
||||
|
|
||||
|
} // namespace internal
|
||||
|
|
||||
|
} // namespace testing
|
@ -0,0 +1,118 @@ |
|||||
|
// Copyright 2008 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)
|
||||
|
|
||||
|
#include "gtest/gtest-typed-test.h" |
||||
|
#include "gtest/gtest.h" |
||||
|
|
||||
|
namespace testing { |
||||
|
namespace internal { |
||||
|
|
||||
|
#if GTEST_HAS_TYPED_TEST_P |
||||
|
|
||||
|
// Skips to the first non-space char in str. Returns an empty string if str
|
||||
|
// contains only whitespace characters.
|
||||
|
static const char* SkipSpaces(const char* str) { |
||||
|
while (IsSpace(*str)) |
||||
|
str++; |
||||
|
return str; |
||||
|
} |
||||
|
|
||||
|
static std::vector<std::string> SplitIntoTestNames(const char* src) { |
||||
|
std::vector<std::string> name_vec; |
||||
|
src = SkipSpaces(src); |
||||
|
for (; src != NULL; src = SkipComma(src)) { |
||||
|
name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); |
||||
|
} |
||||
|
return name_vec; |
||||
|
} |
||||
|
|
||||
|
// Verifies that registered_tests match the test names in
|
||||
|
// defined_test_names_; returns registered_tests if successful, or
|
||||
|
// aborts the program otherwise.
|
||||
|
const char* TypedTestCasePState::VerifyRegisteredTestNames( |
||||
|
const char* file, int line, const char* registered_tests) { |
||||
|
typedef ::std::set<const char*>::const_iterator DefinedTestIter; |
||||
|
registered_ = true; |
||||
|
|
||||
|
std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests); |
||||
|
|
||||
|
Message errors; |
||||
|
|
||||
|
std::set<std::string> tests; |
||||
|
for (std::vector<std::string>::const_iterator name_it = name_vec.begin(); |
||||
|
name_it != name_vec.end(); ++name_it) { |
||||
|
const std::string& name = *name_it; |
||||
|
if (tests.count(name) != 0) { |
||||
|
errors << "Test " << name << " is listed more than once.\n"; |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
bool found = false; |
||||
|
for (DefinedTestIter it = defined_test_names_.begin(); |
||||
|
it != defined_test_names_.end(); |
||||
|
++it) { |
||||
|
if (name == *it) { |
||||
|
found = true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (found) { |
||||
|
tests.insert(name); |
||||
|
} else { |
||||
|
errors << "No test named " << name |
||||
|
<< " can be found in this test case.\n"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for (DefinedTestIter it = defined_test_names_.begin(); |
||||
|
it != defined_test_names_.end(); |
||||
|
++it) { |
||||
|
if (tests.count(*it) == 0) { |
||||
|
errors << "You forgot to list test " << *it << ".\n"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const std::string& errors_str = errors.GetString(); |
||||
|
if (errors_str != "") { |
||||
|
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), |
||||
|
errors_str.c_str()); |
||||
|
fflush(stderr); |
||||
|
posix::Abort(); |
||||
|
} |
||||
|
|
||||
|
return registered_tests; |
||||
|
} |
||||
|
|
||||
|
#endif // GTEST_HAS_TYPED_TEST_P
|
||||
|
|
||||
|
} // namespace internal
|
||||
|
} // namespace testing
|
File diff suppressed because it is too large
@ -0,0 +1,38 @@ |
|||||
|
// Copyright 2006, 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.
|
||||
|
|
||||
|
#include <stdio.h> |
||||
|
|
||||
|
#include "gtest/gtest.h" |
||||
|
|
||||
|
GTEST_API_ int main(int argc, char **argv) { |
||||
|
printf("Running main() from gtest_main.cc\n"); |
||||
|
testing::InitGoogleTest(&argc, argv); |
||||
|
return RUN_ALL_TESTS(); |
||||
|
} |
@ -0,0 +1,58 @@ |
|||||
|
#include "util.h" |
||||
|
#include "util-inl.h" |
||||
|
|
||||
|
#include "gtest/gtest.h" |
||||
|
|
||||
|
TEST(UtilTest, ListHead) { |
||||
|
struct Item { node::ListNode<Item> node_; }; |
||||
|
typedef node::ListHead<Item, &Item::node_> List; |
||||
|
|
||||
|
List list; |
||||
|
EXPECT_TRUE(list.IsEmpty()); |
||||
|
|
||||
|
Item one; |
||||
|
EXPECT_TRUE(one.node_.IsEmpty()); |
||||
|
|
||||
|
list.PushBack(&one); |
||||
|
EXPECT_FALSE(list.IsEmpty()); |
||||
|
EXPECT_FALSE(one.node_.IsEmpty()); |
||||
|
|
||||
|
{ |
||||
|
List::Iterator it = list.begin(); |
||||
|
EXPECT_NE(list.end(), it); |
||||
|
EXPECT_EQ(&one, *it); |
||||
|
++it; |
||||
|
EXPECT_FALSE(it != list.end()); // Iterator only implements != operator.
|
||||
|
} |
||||
|
|
||||
|
Item two; |
||||
|
list.PushBack(&two); |
||||
|
|
||||
|
{ |
||||
|
List::Iterator it = list.begin(); |
||||
|
EXPECT_NE(list.end(), it); |
||||
|
EXPECT_EQ(&one, *it); |
||||
|
++it; |
||||
|
EXPECT_NE(list.end(), it); |
||||
|
EXPECT_EQ(&two, *it); |
||||
|
++it; |
||||
|
EXPECT_FALSE(it != list.end()); // Iterator only implements != operator.
|
||||
|
} |
||||
|
|
||||
|
EXPECT_EQ(&one, list.PopFront()); |
||||
|
EXPECT_TRUE(one.node_.IsEmpty()); |
||||
|
EXPECT_FALSE(list.IsEmpty()); |
||||
|
|
||||
|
{ |
||||
|
List::Iterator it = list.begin(); |
||||
|
EXPECT_NE(list.end(), it); |
||||
|
EXPECT_EQ(&two, *it); |
||||
|
++it; |
||||
|
EXPECT_FALSE(it != list.end()); // Iterator only implements != operator.
|
||||
|
} |
||||
|
|
||||
|
EXPECT_EQ(&two, list.PopFront()); |
||||
|
EXPECT_TRUE(two.node_.IsEmpty()); |
||||
|
EXPECT_TRUE(list.IsEmpty()); |
||||
|
EXPECT_FALSE(list.begin() != list.end()); |
||||
|
} |
Loading…
Reference in new issue