aboutsummaryrefslogtreecommitdiffstats
path: root/gtest/src/gtest-internal-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'gtest/src/gtest-internal-inl.h')
-rw-r--r--gtest/src/gtest-internal-inl.h176
1 files changed, 137 insertions, 39 deletions
diff --git a/gtest/src/gtest-internal-inl.h b/gtest/src/gtest-internal-inl.h
index 189852e..47aec22 100644
--- a/gtest/src/gtest-internal-inl.h
+++ b/gtest/src/gtest-internal-inl.h
@@ -277,7 +277,7 @@ class Vector {
// is created using the copy constructor, and then stored in the
// Vector. Changes made to the element in the Vector doesn't affect
// the source object, and vice versa.
- void PushBack(const E & element) { Insert(element, size_); }
+ void PushBack(const E& element) { Insert(element, size_); }
// Adds an element to the beginning of this Vector.
void PushFront(const E& element) { Insert(element, 0); }
@@ -369,7 +369,7 @@ class Vector {
return NULL;
}
- // Returns the i-th element of the list, or aborts the program if i
+ // Returns the i-th element of the Vector, or aborts the program if i
// is not in range [0, size()).
const E& GetElement(int i) const {
GTEST_CHECK_(0 <= i && i < size_)
@@ -379,13 +379,84 @@ class Vector {
return *(elements_[i]);
}
- // Returns the i-th element of the list, or default_value if i is not
+ // Returns a mutable reference to the i-th element of the Vector, or
+ // aborts the program if i is not in range [0, size()).
+ E& GetMutableElement(int i) {
+ GTEST_CHECK_(0 <= i && i < size_)
+ << "Invalid Vector index " << i << ": must be in range [0, "
+ << (size_ - 1) << "].";
+
+ return *(elements_[i]);
+ }
+
+ // Returns the i-th element of the Vector, or default_value if i is not
// in range [0, size()).
E GetElementOr(int i, E default_value) const {
return (i < 0 || i >= size_) ? default_value : *(elements_[i]);
}
+ // Swaps the i-th and j-th elements of the Vector. Crashes if i or
+ // j is invalid.
+ void Swap(int i, int j) {
+ GTEST_CHECK_(0 <= i && i < size_)
+ << "Invalid first swap element " << i << ": must be in range [0, "
+ << (size_ - 1) << "].";
+ GTEST_CHECK_(0 <= j && j < size_)
+ << "Invalid second swap element " << j << ": must be in range [0, "
+ << (size_ - 1) << "].";
+
+ E* const temp = elements_[i];
+ elements_[i] = elements_[j];
+ elements_[j] = temp;
+ }
+
+ // Performs an in-place shuffle of a range of this Vector's nodes.
+ // 'begin' and 'end' are element indices as an STL-style range;
+ // i.e. [begin, end) are shuffled, where 'end' == size() means to
+ // shuffle to the end of the Vector.
+ void ShuffleRange(internal::Random* random, int begin, int end) {
+ GTEST_CHECK_(0 <= begin && begin <= size_)
+ << "Invalid shuffle range start " << begin << ": must be in range [0, "
+ << size_ << "].";
+ GTEST_CHECK_(begin <= end && end <= size_)
+ << "Invalid shuffle range finish " << end << ": must be in range ["
+ << begin << ", " << size_ << "].";
+
+ // Fisher-Yates shuffle, from
+ // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
+ for (int range_width = end - begin; range_width >= 2; range_width--) {
+ const int last_in_range = begin + range_width - 1;
+ const int selected = begin + random->Generate(range_width);
+ Swap(selected, last_in_range);
+ }
+ }
+
+ // Performs an in-place shuffle of this Vector's nodes.
+ void Shuffle(internal::Random* random) {
+ ShuffleRange(random, 0, size());
+ }
+
+ // Returns a copy of this Vector.
+ Vector* Clone() const {
+ Vector* const clone = new Vector;
+ clone->Reserve(size_);
+ for (int i = 0; i < size_; i++) {
+ clone->PushBack(GetElement(i));
+ }
+ return clone;
+ }
+
private:
+ // Makes sure this Vector's capacity is at least the given value.
+ void Reserve(int new_capacity) {
+ if (new_capacity <= capacity_)
+ return;
+
+ capacity_ = new_capacity;
+ elements_ = static_cast<E**>(
+ realloc(elements_, capacity_*sizeof(elements_[0])));
+ }
+
// Grows the buffer if it is not big enough to hold one more element.
void GrowIfNeeded() {
if (size_ < capacity_)
@@ -397,9 +468,7 @@ class Vector {
const int new_capacity = 3*(capacity_/2 + 1);
GTEST_CHECK_(new_capacity > capacity_) // Does the new capacity overflow?
<< "Cannot grow a Vector with " << capacity_ << " elements already.";
- capacity_ = new_capacity;
- elements_ = static_cast<E**>(
- realloc(elements_, capacity_*sizeof(elements_[0])));
+ Reserve(new_capacity);
}
// Moves the give consecutive elements to a new index in the Vector.
@@ -491,11 +560,6 @@ class TestInfoImpl {
// deletes it.
void Run();
- // Calls the given TestInfo object's Run() method.
- static void RunTest(TestInfo * test_info) {
- test_info->impl()->Run();
- }
-
// Clears the test result.
void ClearResult() { result_.Clear(); }
@@ -606,7 +670,7 @@ class OsStackTraceGetterInterface {
// A working implementation of the OsStackTraceGetterInterface interface.
class OsStackTraceGetter : public OsStackTraceGetterInterface {
public:
- OsStackTraceGetter() {}
+ OsStackTraceGetter() : caller_frame_(NULL) {}
virtual String CurrentStackTrace(int max_depth, int skip_count);
virtual void UponLeavingGTest();
@@ -738,9 +802,20 @@ class UnitTestImpl {
// Gets the i-th test case among all the test cases. i can range from 0 to
// total_test_case_count() - 1. If i is not in that range, returns NULL.
const TestCase* GetTestCase(int i) const {
- return test_cases_.GetElementOr(i, NULL);
+ const int index = test_case_indices_.GetElementOr(i, -1);
+ return index < 0 ? NULL : test_cases_.GetElement(i);
+ }
+
+ // Gets the i-th test case among all the test cases. i can range from 0 to
+ // total_test_case_count() - 1. If i is not in that range, returns NULL.
+ TestCase* GetMutableTestCase(int i) {
+ const int index = test_case_indices_.GetElementOr(i, -1);
+ return index < 0 ? NULL : test_cases_.GetElement(index);
}
+ // Provides access to the event listener list.
+ TestEventListeners* listeners() { return &listeners_; }
+
// Returns the TestResult for the test that's currently running, or
// the TestResult for the ad hoc test if no test is running.
TestResult* current_test_result();
@@ -748,18 +823,6 @@ class UnitTestImpl {
// Returns the TestResult for the ad hoc test.
const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }
- // Sets the unit test result printer.
- //
- // Does nothing if the input and the current printer object are the
- // same; otherwise, deletes the old printer object and makes the
- // input the current printer.
- void set_result_printer(UnitTestEventListenerInterface* result_printer);
-
- // Returns the current unit test result printer if it is not NULL;
- // otherwise, creates an appropriate result printer, makes it the
- // current printer, and returns it.
- UnitTestEventListenerInterface* result_printer();
-
// Sets the OS stack trace getter.
//
// Does nothing if the input and the current OS stack trace getter
@@ -895,9 +958,6 @@ class UnitTestImpl {
return &environments_in_reverse_order_;
}
- internal::Vector<TestCase*>* test_cases() { return &test_cases_; }
- const internal::Vector<TestCase*>* test_cases() const { return &test_cases_; }
-
// Getters for the per-thread Google Test trace stack.
internal::Vector<TraceInfo>* gtest_trace_stack() {
return gtest_trace_stack_.pointer();
@@ -907,9 +967,13 @@ class UnitTestImpl {
}
#if GTEST_HAS_DEATH_TEST
+ void InitDeathTestSubprocessControlInfo() {
+ internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
+ }
// Returns a pointer to the parsed --gtest_internal_run_death_test
// flag, or NULL if that flag was not specified.
// This information is useful only in a death test child process.
+ // Must not be called before a call to InitGoogleTest.
const InternalRunDeathTestFlag* internal_run_death_test_flag() const {
return internal_run_death_test_flag_.get();
}
@@ -919,12 +983,35 @@ class UnitTestImpl {
return death_test_factory_.get();
}
+ void SuppressTestEventsIfInSubprocess();
+
friend class ReplaceDeathTestFactory;
#endif // GTEST_HAS_DEATH_TEST
- // Gets the random seed used at the start of the current test run.
+ // Initializes the event listener performing XML output as specified by
+ // UnitTestOptions. Must not be called before InitGoogleTest.
+ void ConfigureXmlOutput();
+
+ // Performs initialization dependent upon flag values obtained in
+ // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to
+ // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest
+ // this function is also called from RunAllTests. Since this function can be
+ // called more than once, it has to be idempotent.
+ void PostFlagParsingInit();
+
+ // Gets the random seed used at the start of the current test iteration.
int random_seed() const { return random_seed_; }
+ // Gets the random number generator.
+ internal::Random* random() { return &random_; }
+
+ // Shuffles all test cases, and the tests within each test case,
+ // making sure that death tests are still run first.
+ void ShuffleTests();
+
+ // Restores the test cases and tests to their order before the first shuffle.
+ void UnshuffleTests();
+
private:
friend class ::testing::UnitTest;
@@ -956,7 +1043,15 @@ class UnitTestImpl {
internal::Vector<Environment*> environments_;
internal::Vector<Environment*> environments_in_reverse_order_;
- internal::Vector<TestCase*> test_cases_; // The vector of TestCases.
+ // The vector of TestCases in their original order. It owns the
+ // elements in the vector.
+ internal::Vector<TestCase*> test_cases_;
+
+ // Provides a level of indirection for the test case list to allow
+ // easy shuffling and restoring the test case order. The i-th
+ // element of this vector is the index of the i-th test case in the
+ // shuffled order.
+ internal::Vector<int> test_case_indices_;
#if GTEST_HAS_PARAM_TEST
// ParameterizedTestRegistry object used to register value-parameterized
@@ -992,11 +1087,9 @@ class UnitTestImpl {
// test, and records the result in ad_hoc_test_result_.
TestResult ad_hoc_test_result_;
- // The unit test result printer. Will be deleted when the UnitTest
- // object is destructed. By default, a plain text printer is used,
- // but the user can set this field to use a custom printer if that
- // is desired.
- UnitTestEventListenerInterface* result_printer_;
+ // The list of event listeners that can be used to track events inside
+ // Google Test.
+ TestEventListeners listeners_;
// The OS stack trace getter. Will be deleted when the UnitTest
// object is destructed. By default, an OsStackTraceGetter is used,
@@ -1004,9 +1097,15 @@ class UnitTestImpl {
// desired.
OsStackTraceGetterInterface* os_stack_trace_getter_;
+ // True iff PostFlagParsingInit() has been called.
+ bool post_flag_parse_init_performed_;
+
// The random number seed used at the beginning of the test run.
int random_seed_;
+ // Our random number generator.
+ internal::Random random_;
+
// How long the test took to run, in milliseconds.
TimeInMillis elapsed_time_;
@@ -1099,13 +1198,14 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
char* end;
// BiggestConvertible is the largest integer type that system-provided
// string-to-number conversion routines can return.
-#if GTEST_OS_WINDOWS
+#if GTEST_OS_WINDOWS && !defined(__GNUC__)
+ // MSVC and C++ Builder define __int64 instead of the standard long long.
typedef unsigned __int64 BiggestConvertible;
const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10);
#else
typedef unsigned long long BiggestConvertible; // NOLINT
const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10);
-#endif // GTEST_OS_WINDOWS
+#endif // GTEST_OS_WINDOWS && !defined(__GNUC__)
const bool parse_success = *end == '\0' && errno == 0;
// TODO(vladl@google.com): Convert this to compile time assertion when it is
@@ -1131,8 +1231,6 @@ class TestResultAccessor {
test_result->RecordProperty(property);
}
- static bool Passed(const TestResult& result) { return result.Passed(); }
-
static void ClearTestPartResults(TestResult* test_result) {
test_result->ClearTestPartResults();
}