diff options
Diffstat (limited to 'gtest/src/gtest-internal-inl.h')
-rw-r--r-- | gtest/src/gtest-internal-inl.h | 176 |
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(); } |