michael@0: // Copyright 2007, Google Inc. michael@0: // All rights reserved. michael@0: // michael@0: // Redistribution and use in source and binary forms, with or without michael@0: // modification, are permitted provided that the following conditions are michael@0: // met: michael@0: // michael@0: // * Redistributions of source code must retain the above copyright michael@0: // notice, this list of conditions and the following disclaimer. michael@0: // * Redistributions in binary form must reproduce the above michael@0: // copyright notice, this list of conditions and the following disclaimer michael@0: // in the documentation and/or other materials provided with the michael@0: // distribution. michael@0: // * Neither the name of Google Inc. nor the names of its michael@0: // contributors may be used to endorse or promote products derived from michael@0: // this software without specific prior written permission. michael@0: // michael@0: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR michael@0: // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT michael@0: // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@0: // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@0: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, michael@0: // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY michael@0: // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE michael@0: // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: // michael@0: // Author: wan@google.com (Zhanyong Wan) michael@0: // michael@0: // Tests using global test environments. michael@0: michael@0: #include michael@0: #include michael@0: #include "gtest/gtest.h" michael@0: michael@0: #define GTEST_IMPLEMENTATION_ 1 // Required for the next #include. michael@0: #include "src/gtest-internal-inl.h" michael@0: #undef GTEST_IMPLEMENTATION_ michael@0: michael@0: namespace testing { michael@0: GTEST_DECLARE_string_(filter); michael@0: } michael@0: michael@0: namespace { michael@0: michael@0: enum FailureType { michael@0: NO_FAILURE, NON_FATAL_FAILURE, FATAL_FAILURE michael@0: }; michael@0: michael@0: // For testing using global test environments. michael@0: class MyEnvironment : public testing::Environment { michael@0: public: michael@0: MyEnvironment() { Reset(); } michael@0: michael@0: // Depending on the value of failure_in_set_up_, SetUp() will michael@0: // generate a non-fatal failure, generate a fatal failure, or michael@0: // succeed. michael@0: virtual void SetUp() { michael@0: set_up_was_run_ = true; michael@0: michael@0: switch (failure_in_set_up_) { michael@0: case NON_FATAL_FAILURE: michael@0: ADD_FAILURE() << "Expected non-fatal failure in global set-up."; michael@0: break; michael@0: case FATAL_FAILURE: michael@0: FAIL() << "Expected fatal failure in global set-up."; michael@0: break; michael@0: default: michael@0: break; michael@0: } michael@0: } michael@0: michael@0: // Generates a non-fatal failure. michael@0: virtual void TearDown() { michael@0: tear_down_was_run_ = true; michael@0: ADD_FAILURE() << "Expected non-fatal failure in global tear-down."; michael@0: } michael@0: michael@0: // Resets the state of the environment s.t. it can be reused. michael@0: void Reset() { michael@0: failure_in_set_up_ = NO_FAILURE; michael@0: set_up_was_run_ = false; michael@0: tear_down_was_run_ = false; michael@0: } michael@0: michael@0: // We call this function to set the type of failure SetUp() should michael@0: // generate. michael@0: void set_failure_in_set_up(FailureType type) { michael@0: failure_in_set_up_ = type; michael@0: } michael@0: michael@0: // Was SetUp() run? michael@0: bool set_up_was_run() const { return set_up_was_run_; } michael@0: michael@0: // Was TearDown() run? michael@0: bool tear_down_was_run() const { return tear_down_was_run_; } michael@0: michael@0: private: michael@0: FailureType failure_in_set_up_; michael@0: bool set_up_was_run_; michael@0: bool tear_down_was_run_; michael@0: }; michael@0: michael@0: // Was the TEST run? michael@0: bool test_was_run; michael@0: michael@0: // The sole purpose of this TEST is to enable us to check whether it michael@0: // was run. michael@0: TEST(FooTest, Bar) { michael@0: test_was_run = true; michael@0: } michael@0: michael@0: // Prints the message and aborts the program if condition is false. michael@0: void Check(bool condition, const char* msg) { michael@0: if (!condition) { michael@0: printf("FAILED: %s\n", msg); michael@0: testing::internal::posix::Abort(); michael@0: } michael@0: } michael@0: michael@0: // Runs the tests. Return true iff successful. michael@0: // michael@0: // The 'failure' parameter specifies the type of failure that should michael@0: // be generated by the global set-up. michael@0: int RunAllTests(MyEnvironment* env, FailureType failure) { michael@0: env->Reset(); michael@0: env->set_failure_in_set_up(failure); michael@0: test_was_run = false; michael@0: testing::internal::GetUnitTestImpl()->ClearAdHocTestResult(); michael@0: return RUN_ALL_TESTS(); michael@0: } michael@0: michael@0: } // namespace michael@0: michael@0: int main(int argc, char **argv) { michael@0: testing::InitGoogleTest(&argc, argv); michael@0: michael@0: // Registers a global test environment, and verifies that the michael@0: // registration function returns its argument. michael@0: MyEnvironment* const env = new MyEnvironment; michael@0: Check(testing::AddGlobalTestEnvironment(env) == env, michael@0: "AddGlobalTestEnvironment() should return its argument."); michael@0: michael@0: // Verifies that RUN_ALL_TESTS() runs the tests when the global michael@0: // set-up is successful. michael@0: Check(RunAllTests(env, NO_FAILURE) != 0, michael@0: "RUN_ALL_TESTS() should return non-zero, as the global tear-down " michael@0: "should generate a failure."); michael@0: Check(test_was_run, michael@0: "The tests should run, as the global set-up should generate no " michael@0: "failure"); michael@0: Check(env->tear_down_was_run(), michael@0: "The global tear-down should run, as the global set-up was run."); michael@0: michael@0: // Verifies that RUN_ALL_TESTS() runs the tests when the global michael@0: // set-up generates no fatal failure. michael@0: Check(RunAllTests(env, NON_FATAL_FAILURE) != 0, michael@0: "RUN_ALL_TESTS() should return non-zero, as both the global set-up " michael@0: "and the global tear-down should generate a non-fatal failure."); michael@0: Check(test_was_run, michael@0: "The tests should run, as the global set-up should generate no " michael@0: "fatal failure."); michael@0: Check(env->tear_down_was_run(), michael@0: "The global tear-down should run, as the global set-up was run."); michael@0: michael@0: // Verifies that RUN_ALL_TESTS() runs no test when the global set-up michael@0: // generates a fatal failure. michael@0: Check(RunAllTests(env, FATAL_FAILURE) != 0, michael@0: "RUN_ALL_TESTS() should return non-zero, as the global set-up " michael@0: "should generate a fatal failure."); michael@0: Check(!test_was_run, michael@0: "The tests should not run, as the global set-up should generate " michael@0: "a fatal failure."); michael@0: Check(env->tear_down_was_run(), michael@0: "The global tear-down should run, as the global set-up was run."); michael@0: michael@0: // Verifies that RUN_ALL_TESTS() doesn't do global set-up or michael@0: // tear-down when there is no test to run. michael@0: testing::GTEST_FLAG(filter) = "-*"; michael@0: Check(RunAllTests(env, NO_FAILURE) == 0, michael@0: "RUN_ALL_TESTS() should return zero, as there is no test to run."); michael@0: Check(!env->set_up_was_run(), michael@0: "The global set-up should not run, as there is no test to run."); michael@0: Check(!env->tear_down_was_run(), michael@0: "The global tear-down should not run, " michael@0: "as the global set-up was not run."); michael@0: michael@0: printf("PASS\n"); michael@0: return 0; michael@0: }