diff --git a/googletest/include/gtest/gtest-param-test.h b/googletest/include/gtest/gtest-param-test.h index 9989765d..f61e3c5d 100644 --- a/googletest/include/gtest/gtest-param-test.h +++ b/googletest/include/gtest/gtest-param-test.h @@ -1,513 +1,514 @@ // 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. // // Macros and functions for implementing parameterized tests // in Google C++ Testing and Mocking Framework (Google Test) // // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // // GOOGLETEST_CM0001 DO NOT DELETE #ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ // Value-parameterized tests allow you to test your code with different // parameters without writing multiple copies of the same test. // // Here is how you use value-parameterized tests: #if 0 // To write value-parameterized tests, first you should define a fixture // class. It is usually derived from testing::TestWithParam (see below for // another inheritance scheme that's sometimes useful in more complicated // class hierarchies), where the type of your parameter values. // TestWithParam is itself derived from testing::Test. T can be any // copyable type. If it's a raw pointer, you are responsible for managing the // lifespan of the pointed values. class FooTest : public ::testing::TestWithParam { // You can implement all the usual class fixture members here. }; // Then, use the TEST_P macro to define as many parameterized tests // for this fixture as you want. The _P suffix is for "parameterized" // or "pattern", whichever you prefer to think. The arguments to the // TEST_P macro are the test_suite_name and test_case (both which must be // non-empty) that will form the test name. TEST_P(FooTest, DoesBlah) { // Inside a test, access the test parameter with the GetParam() method // of the TestWithParam class: EXPECT_TRUE(foo.Blah(GetParam())); ... } TEST_P(FooTest, HasBlahBlah) { ... } // Finally, you can use INSTANTIATE_TEST_SUITE_P to instantiate the test // case with any set of parameters you want. Google Test defines a number // of functions for generating test parameters. They return what we call // (surprise!) parameter generators. Here is a summary of them, which // are all in the testing namespace: // // // Range(begin, end [, step]) - Yields values {begin, begin+step, // begin+step+step, ...}. The values do not // include end. step defaults to 1. // Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. // ValuesIn(container) - Yields values from a C-style array, an STL // ValuesIn(begin,end) container, or an iterator range [begin, end). // Bool() - Yields sequence {false, true}. // Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product // for the math savvy) of the values generated // by the N generators. // // For more details, see comments at the definitions of these functions below // in this file. // // The following statement will instantiate tests from the FooTest test suite // each with parameter values "meeny", "miny", and "moe". INSTANTIATE_TEST_SUITE_P(InstantiationName, FooTest, Values("meeny", "miny", "moe")); // To distinguish different instances of the pattern, (yes, you // can instantiate it more than once) the first argument to the // INSTANTIATE_TEST_SUITE_P macro is a prefix (which must be non-empty) that // will be added to the actual test suite name. Remember to pick unique prefixes // for different instantiations. The tests from the instantiation above will // have these names: // // * InstantiationName/FooTest.DoesBlah/0 for "meeny" // * InstantiationName/FooTest.DoesBlah/1 for "miny" // * InstantiationName/FooTest.DoesBlah/2 for "moe" // * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" // * InstantiationName/FooTest.HasBlahBlah/1 for "miny" // * InstantiationName/FooTest.HasBlahBlah/2 for "moe" // // You can use these names in --gtest_filter. // // This statement will instantiate all tests from FooTest again, each // with parameter values "cat" and "dog": const char* pets[] = {"cat", "dog"}; INSTANTIATE_TEST_SUITE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); // The tests from the instantiation above will have these names: // // * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" // * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" // * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" // * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" // // Please note that INSTANTIATE_TEST_SUITE_P will instantiate all tests // in the given test suite, whether their definitions come before or // AFTER the INSTANTIATE_TEST_SUITE_P statement. // // Please also note that generator expressions (including parameters to the // generators) are evaluated in InitGoogleTest(), after main() has started. // This allows the user on one hand, to adjust generator parameters in order // to dynamically determine a set of tests to run and on the other hand, // give the user a chance to inspect the generated tests with Google Test // reflection API before RUN_ALL_TESTS() is executed. // // You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc // for more examples. // // In the future, we plan to publish the API for defining new parameter // generators. But for now this interface remains part of the internal // implementation and is subject to change. // // // A parameterized test fixture must be derived from testing::Test and from // testing::WithParamInterface, where T is the type of the parameter // values. Inheriting from TestWithParam satisfies that requirement because // TestWithParam inherits from both Test and WithParamInterface. In more // complicated hierarchies, however, it is occasionally useful to inherit // separately from Test and WithParamInterface. For example: class BaseTest : public ::testing::Test { // You can inherit all the usual members for a non-parameterized test // fixture here. }; class DerivedTest : public BaseTest, public ::testing::WithParamInterface { // The usual test fixture members go here too. }; TEST_F(BaseTest, HasFoo) { // This is an ordinary non-parameterized test. } TEST_P(DerivedTest, DoesBlah) { // GetParam works just the same here as if you inherit from TestWithParam. EXPECT_TRUE(foo.Blah(GetParam())); } #endif // 0 #include #include #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-param-util.h" #include "gtest/internal/gtest-port.h" namespace testing { // Functions producing parameter generators. // // Google Test uses these generators to produce parameters for value- // parameterized tests. When a parameterized test suite is instantiated // with a particular generator, Google Test creates and runs tests // for each element in the sequence produced by the generator. // // In the following sample, tests from test suite FooTest are instantiated // each three times with parameter values 3, 5, and 8: // // class FooTest : public TestWithParam { ... }; // // TEST_P(FooTest, TestThis) { // } // TEST_P(FooTest, TestThat) { // } // INSTANTIATE_TEST_SUITE_P(TestSequence, FooTest, Values(3, 5, 8)); // // Range() returns generators providing sequences of values in a range. // // Synopsis: // Range(start, end) // - returns a generator producing a sequence of values {start, start+1, // start+2, ..., }. // Range(start, end, step) // - returns a generator producing a sequence of values {start, start+step, // start+step+step, ..., }. // Notes: // * The generated sequences never include end. For example, Range(1, 5) // returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) // returns a generator producing {1, 3, 5, 7}. // * start and end must have the same type. That type may be any integral or // floating-point type or a user defined type satisfying these conditions: // * It must be assignable (have operator=() defined). // * It must have operator+() (operator+(int-compatible type) for // two-operand version). // * It must have operator<() defined. // Elements in the resulting sequences will also have that type. // * Condition start < end must be satisfied in order for resulting sequences // to contain any elements. // template internal::ParamGenerator Range(T start, T end, IncrementT step) { return internal::ParamGenerator( new internal::RangeGenerator(start, end, step)); } template internal::ParamGenerator Range(T start, T end) { return Range(start, end, 1); } // ValuesIn() function allows generation of tests with parameters coming from // a container. // // Synopsis: // ValuesIn(const T (&array)[N]) // - returns a generator producing sequences with elements from // a C-style array. // ValuesIn(const Container& container) // - returns a generator producing sequences with elements from // an STL-style container. // ValuesIn(Iterator begin, Iterator end) // - returns a generator producing sequences with elements from // a range [begin, end) defined by a pair of STL-style iterators. These // iterators can also be plain C pointers. // // Please note that ValuesIn copies the values from the containers // passed in and keeps them to generate tests in RUN_ALL_TESTS(). // // Examples: // // This instantiates tests from test suite StringTest // each with C-string values of "foo", "bar", and "baz": // // const char* strings[] = {"foo", "bar", "baz"}; // INSTANTIATE_TEST_SUITE_P(StringSequence, StringTest, ValuesIn(strings)); // // This instantiates tests from test suite StlStringTest // each with STL strings with values "a" and "b": // // ::std::vector< ::std::string> GetParameterStrings() { // ::std::vector< ::std::string> v; // v.push_back("a"); // v.push_back("b"); // return v; // } // // INSTANTIATE_TEST_SUITE_P(CharSequence, // StlStringTest, // ValuesIn(GetParameterStrings())); // // // This will also instantiate tests from CharTest // each with parameter values 'a' and 'b': // // ::std::list GetParameterChars() { // ::std::list list; // list.push_back('a'); // list.push_back('b'); // return list; // } // ::std::list l = GetParameterChars(); // INSTANTIATE_TEST_SUITE_P(CharSequence2, // CharTest, // ValuesIn(l.begin(), l.end())); // template internal::ParamGenerator< typename std::iterator_traits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end) { typedef typename std::iterator_traits::value_type ParamType; return internal::ParamGenerator( new internal::ValuesInIteratorRangeGenerator(begin, end)); } template internal::ParamGenerator ValuesIn(const T (&array)[N]) { return ValuesIn(array, array + N); } template internal::ParamGenerator ValuesIn( const Container& container) { return ValuesIn(container.begin(), container.end()); } // Values() allows generating tests from explicitly specified list of // parameters. // // Synopsis: // Values(T v1, T v2, ..., T vN) // - returns a generator producing sequences with elements v1, v2, ..., vN. // // For example, this instantiates tests from test suite BarTest each // with values "one", "two", and "three": // // INSTANTIATE_TEST_SUITE_P(NumSequence, // BarTest, // Values("one", "two", "three")); // // This instantiates tests from test suite BazTest each with values 1, 2, 3.5. // The exact type of values will depend on the type of parameter in BazTest. // // INSTANTIATE_TEST_SUITE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); // // template internal::ValueArray Values(T... v) { return internal::ValueArray(std::move(v)...); } // Bool() allows generating tests with parameters in a set of (false, true). // // Synopsis: // Bool() // - returns a generator producing sequences with elements {false, true}. // // It is useful when testing code that depends on Boolean flags. Combinations // of multiple flags can be tested when several Bool()'s are combined using // Combine() function. // // In the following example all tests in the test suite FlagDependentTest // will be instantiated twice with parameters false and true. // // class FlagDependentTest : public testing::TestWithParam { // virtual void SetUp() { // external_flag = GetParam(); // } // } // INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool()); // inline internal::ParamGenerator Bool() { return Values(false, true); } // Combine() allows the user to combine two or more sequences to produce // values of a Cartesian product of those sequences' elements. // // Synopsis: // Combine(gen1, gen2, ..., genN) // - returns a generator producing sequences with elements coming from // the Cartesian product of elements from the sequences generated by // gen1, gen2, ..., genN. The sequence elements will have a type of // std::tuple where T1, T2, ..., TN are the types // of elements from sequences produces by gen1, gen2, ..., genN. // // Combine can have up to 10 arguments. // // Example: // // This will instantiate tests in test suite AnimalTest each one with // the parameter values tuple("cat", BLACK), tuple("cat", WHITE), // tuple("dog", BLACK), and tuple("dog", WHITE): // // enum Color { BLACK, GRAY, WHITE }; // class AnimalTest // : public testing::TestWithParam > {...}; // // TEST_P(AnimalTest, AnimalLooksNice) {...} // // INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest, // Combine(Values("cat", "dog"), // Values(BLACK, WHITE))); // // This will instantiate tests in FlagDependentTest with all variations of two // Boolean flags: // // class FlagDependentTest // : public testing::TestWithParam > { // virtual void SetUp() { // // Assigns external_flag_1 and external_flag_2 values from the tuple. // std::tie(external_flag_1, external_flag_2) = GetParam(); // } // }; // // TEST_P(FlagDependentTest, TestFeature1) { // // Test your code using external_flag_1 and external_flag_2 here. // } // INSTANTIATE_TEST_SUITE_P(TwoBoolSequence, FlagDependentTest, // Combine(Bool(), Bool())); // template internal::CartesianProductHolder Combine(const Generator&... g) { return internal::CartesianProductHolder(g...); } #define TEST_P(test_suite_name, test_name) \ static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \ "test_suite_name must not be empty"); \ static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1, \ "test_name must not be empty"); \ class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ : public test_suite_name { \ public: \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \ void TestBody() override; \ \ private: \ static int AddToRegistry() { \ ::testing::UnitTest::GetInstance() \ ->parameterized_test_registry() \ .GetTestSuitePatternHolder( \ - #test_suite_name, \ + GTEST_STRINGIFY_(test_suite_name), \ ::testing::internal::CodeLocation(__FILE__, __LINE__)) \ ->AddTestPattern( \ GTEST_STRINGIFY_(test_suite_name), GTEST_STRINGIFY_(test_name), \ new ::testing::internal::TestMetaFactory()); \ return 0; \ } \ static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ test_name)); \ }; \ int GTEST_TEST_CLASS_NAME_(test_suite_name, \ test_name)::gtest_registering_dummy_ = \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::AddToRegistry(); \ void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody() // The last argument to INSTANTIATE_TEST_SUITE_P allows the user to specify // generator and an optional function or functor that generates custom test name // suffixes based on the test parameters. Such a function or functor should // accept one argument of type testing::TestParamInfo, and // return std::string. // // testing::PrintToStringParamName is a builtin test suffix generator that // returns the value of testing::PrintToString(GetParam()). // // Note: test names must be non-empty, unique, and may only contain ASCII // alphanumeric characters or underscore. Because PrintToString adds quotes // to std::string and C strings, it won't work for these types. #define GTEST_EXPAND_(arg) arg #define GTEST_GET_FIRST_(first, ...) first #define GTEST_GET_SECOND_(first, second, ...) second #define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \ static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \ "test_suite_name must not be empty"); \ static_assert(sizeof(GTEST_STRINGIFY_(prefix)) > 1, \ "prefix must not be empty"); \ static ::testing::internal::ParamGenerator \ gtest_##prefix##test_suite_name##_EvalGenerator_() { \ return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \ } \ static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \ const ::testing::TestParamInfo& info) { \ if (::testing::internal::AlwaysFalse()) { \ ::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \ __VA_ARGS__, \ ::testing::internal::DefaultParamName, \ DUMMY_PARAM_))); \ auto t = std::make_tuple(__VA_ARGS__); \ static_assert(std::tuple_size::value <= 2, \ "Too Many Args!"); \ } \ return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \ __VA_ARGS__, \ ::testing::internal::DefaultParamName, \ DUMMY_PARAM_))))(info); \ } \ static int gtest_##prefix##test_suite_name##_dummy_ \ GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::UnitTest::GetInstance() \ ->parameterized_test_registry() \ .GetTestSuitePatternHolder( \ - #test_suite_name, \ + GTEST_STRINGIFY_(test_suite_name), \ ::testing::internal::CodeLocation(__FILE__, __LINE__)) \ ->AddTestSuiteInstantiation( \ - #prefix, >est_##prefix##test_suite_name##_EvalGenerator_, \ + GTEST_STRINGIFY_(prefix), \ + >est_##prefix##test_suite_name##_EvalGenerator_, \ >est_##prefix##test_suite_name##_EvalGenerateName_, \ __FILE__, __LINE__) // Legacy API is deprecated but still available #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ #define INSTANTIATE_TEST_CASE_P \ static_assert(::testing::internal::InstantiateTestCase_P_IsDeprecated(), \ ""); \ INSTANTIATE_TEST_SUITE_P #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ diff --git a/googletest/test/googletest-param-test-test.cc b/googletest/test/googletest-param-test-test.cc index 6c187dff..2740aaab 100644 --- a/googletest/test/googletest-param-test-test.cc +++ b/googletest/test/googletest-param-test-test.cc @@ -1,1055 +1,1086 @@ // 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. // // Tests for Google Test itself. This file verifies that the parameter // generators objects produce correct parameter sequences and that // Google Test runtime instantiates correct tests from those sequences. #include "gtest/gtest.h" # include # include # include +# include # include # include # include # include "src/gtest-internal-inl.h" // for UnitTestOptions # include "test/googletest-param-test-test.h" using ::std::vector; using ::std::sort; using ::testing::AddGlobalTestEnvironment; using ::testing::Bool; using ::testing::Combine; using ::testing::Message; using ::testing::Range; using ::testing::TestWithParam; using ::testing::Values; using ::testing::ValuesIn; using ::testing::internal::ParamGenerator; using ::testing::internal::UnitTestOptions; // Prints a value to a string. // // FIXME: remove PrintValue() when we move matchers and // EXPECT_THAT() from Google Mock to Google Test. At that time, we // can write EXPECT_THAT(x, Eq(y)) to compare two tuples x and y, as // EXPECT_THAT() and the matchers know how to print tuples. template ::std::string PrintValue(const T& value) { return testing::PrintToString(value); } // Verifies that a sequence generated by the generator and accessed // via the iterator object matches the expected one using Google Test // assertions. template void VerifyGenerator(const ParamGenerator& generator, const T (&expected_values)[N]) { typename ParamGenerator::iterator it = generator.begin(); for (size_t i = 0; i < N; ++i) { ASSERT_FALSE(it == generator.end()) << "At element " << i << " when accessing via an iterator " << "created with the copy constructor.\n"; // We cannot use EXPECT_EQ() here as the values may be tuples, // which don't support <<. EXPECT_TRUE(expected_values[i] == *it) << "where i is " << i << ", expected_values[i] is " << PrintValue(expected_values[i]) << ", *it is " << PrintValue(*it) << ", and 'it' is an iterator created with the copy constructor.\n"; ++it; } EXPECT_TRUE(it == generator.end()) << "At the presumed end of sequence when accessing via an iterator " << "created with the copy constructor.\n"; // Test the iterator assignment. The following lines verify that // the sequence accessed via an iterator initialized via the // assignment operator (as opposed to a copy constructor) matches // just the same. it = generator.begin(); for (size_t i = 0; i < N; ++i) { ASSERT_FALSE(it == generator.end()) << "At element " << i << " when accessing via an iterator " << "created with the assignment operator.\n"; EXPECT_TRUE(expected_values[i] == *it) << "where i is " << i << ", expected_values[i] is " << PrintValue(expected_values[i]) << ", *it is " << PrintValue(*it) << ", and 'it' is an iterator created with the copy constructor.\n"; ++it; } EXPECT_TRUE(it == generator.end()) << "At the presumed end of sequence when accessing via an iterator " << "created with the assignment operator.\n"; } template void VerifyGeneratorIsEmpty(const ParamGenerator& generator) { typename ParamGenerator::iterator it = generator.begin(); EXPECT_TRUE(it == generator.end()); it = generator.begin(); EXPECT_TRUE(it == generator.end()); } // Generator tests. They test that each of the provided generator functions // generates an expected sequence of values. The general test pattern // instantiates a generator using one of the generator functions, // checks the sequence produced by the generator using its iterator API, // and then resets the iterator back to the beginning of the sequence // and checks the sequence again. // Tests that iterators produced by generator functions conform to the // ForwardIterator concept. TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) { const ParamGenerator gen = Range(0, 10); ParamGenerator::iterator it = gen.begin(); // Verifies that iterator initialization works as expected. ParamGenerator::iterator it2 = it; EXPECT_TRUE(*it == *it2) << "Initialized iterators must point to the " << "element same as its source points to"; // Verifies that iterator assignment works as expected. ++it; EXPECT_FALSE(*it == *it2); it2 = it; EXPECT_TRUE(*it == *it2) << "Assigned iterators must point to the " << "element same as its source points to"; // Verifies that prefix operator++() returns *this. EXPECT_EQ(&it, &(++it)) << "Result of the prefix operator++ must be " << "refer to the original object"; // Verifies that the result of the postfix operator++ points to the value // pointed to by the original iterator. int original_value = *it; // Have to compute it outside of macro call to be // unaffected by the parameter evaluation order. EXPECT_EQ(original_value, *(it++)); // Verifies that prefix and postfix operator++() advance an iterator // all the same. it2 = it; ++it; ++it2; EXPECT_TRUE(*it == *it2); } // Tests that Range() generates the expected sequence. TEST(RangeTest, IntRangeWithDefaultStep) { const ParamGenerator gen = Range(0, 3); const int expected_values[] = {0, 1, 2}; VerifyGenerator(gen, expected_values); } // Edge case. Tests that Range() generates the single element sequence // as expected when provided with range limits that are equal. TEST(RangeTest, IntRangeSingleValue) { const ParamGenerator gen = Range(0, 1); const int expected_values[] = {0}; VerifyGenerator(gen, expected_values); } // Edge case. Tests that Range() with generates empty sequence when // supplied with an empty range. TEST(RangeTest, IntRangeEmpty) { const ParamGenerator gen = Range(0, 0); VerifyGeneratorIsEmpty(gen); } // Tests that Range() with custom step (greater then one) generates // the expected sequence. TEST(RangeTest, IntRangeWithCustomStep) { const ParamGenerator gen = Range(0, 9, 3); const int expected_values[] = {0, 3, 6}; VerifyGenerator(gen, expected_values); } // Tests that Range() with custom step (greater then one) generates // the expected sequence when the last element does not fall on the // upper range limit. Sequences generated by Range() must not have // elements beyond the range limits. TEST(RangeTest, IntRangeWithCustomStepOverUpperBound) { const ParamGenerator gen = Range(0, 4, 3); const int expected_values[] = {0, 3}; VerifyGenerator(gen, expected_values); } // Verifies that Range works with user-defined types that define // copy constructor, operator=(), operator+(), and operator<(). class DogAdder { public: explicit DogAdder(const char* a_value) : value_(a_value) {} DogAdder(const DogAdder& other) : value_(other.value_.c_str()) {} DogAdder operator=(const DogAdder& other) { if (this != &other) value_ = other.value_; return *this; } DogAdder operator+(const DogAdder& other) const { Message msg; msg << value_.c_str() << other.value_.c_str(); return DogAdder(msg.GetString().c_str()); } bool operator<(const DogAdder& other) const { return value_ < other.value_; } const std::string& value() const { return value_; } private: std::string value_; }; TEST(RangeTest, WorksWithACustomType) { const ParamGenerator gen = Range(DogAdder("cat"), DogAdder("catdogdog"), DogAdder("dog")); ParamGenerator::iterator it = gen.begin(); ASSERT_FALSE(it == gen.end()); EXPECT_STREQ("cat", it->value().c_str()); ASSERT_FALSE(++it == gen.end()); EXPECT_STREQ("catdog", it->value().c_str()); EXPECT_TRUE(++it == gen.end()); } class IntWrapper { public: explicit IntWrapper(int a_value) : value_(a_value) {} IntWrapper(const IntWrapper& other) : value_(other.value_) {} IntWrapper operator=(const IntWrapper& other) { value_ = other.value_; return *this; } // operator+() adds a different type. IntWrapper operator+(int other) const { return IntWrapper(value_ + other); } bool operator<(const IntWrapper& other) const { return value_ < other.value_; } int value() const { return value_; } private: int value_; }; TEST(RangeTest, WorksWithACustomTypeWithDifferentIncrementType) { const ParamGenerator gen = Range(IntWrapper(0), IntWrapper(2)); ParamGenerator::iterator it = gen.begin(); ASSERT_FALSE(it == gen.end()); EXPECT_EQ(0, it->value()); ASSERT_FALSE(++it == gen.end()); EXPECT_EQ(1, it->value()); EXPECT_TRUE(++it == gen.end()); } // Tests that ValuesIn() with an array parameter generates // the expected sequence. TEST(ValuesInTest, ValuesInArray) { int array[] = {3, 5, 8}; const ParamGenerator gen = ValuesIn(array); VerifyGenerator(gen, array); } // Tests that ValuesIn() with a const array parameter generates // the expected sequence. TEST(ValuesInTest, ValuesInConstArray) { const int array[] = {3, 5, 8}; const ParamGenerator gen = ValuesIn(array); VerifyGenerator(gen, array); } // Edge case. Tests that ValuesIn() with an array parameter containing a // single element generates the single element sequence. TEST(ValuesInTest, ValuesInSingleElementArray) { int array[] = {42}; const ParamGenerator gen = ValuesIn(array); VerifyGenerator(gen, array); } // Tests that ValuesIn() generates the expected sequence for an STL // container (vector). TEST(ValuesInTest, ValuesInVector) { typedef ::std::vector ContainerType; ContainerType values; values.push_back(3); values.push_back(5); values.push_back(8); const ParamGenerator gen = ValuesIn(values); const int expected_values[] = {3, 5, 8}; VerifyGenerator(gen, expected_values); } // Tests that ValuesIn() generates the expected sequence. TEST(ValuesInTest, ValuesInIteratorRange) { typedef ::std::vector ContainerType; ContainerType values; values.push_back(3); values.push_back(5); values.push_back(8); const ParamGenerator gen = ValuesIn(values.begin(), values.end()); const int expected_values[] = {3, 5, 8}; VerifyGenerator(gen, expected_values); } // Edge case. Tests that ValuesIn() provided with an iterator range specifying a // single value generates a single-element sequence. TEST(ValuesInTest, ValuesInSingleElementIteratorRange) { typedef ::std::vector ContainerType; ContainerType values; values.push_back(42); const ParamGenerator gen = ValuesIn(values.begin(), values.end()); const int expected_values[] = {42}; VerifyGenerator(gen, expected_values); } // Edge case. Tests that ValuesIn() provided with an empty iterator range // generates an empty sequence. TEST(ValuesInTest, ValuesInEmptyIteratorRange) { typedef ::std::vector ContainerType; ContainerType values; const ParamGenerator gen = ValuesIn(values.begin(), values.end()); VerifyGeneratorIsEmpty(gen); } // Tests that the Values() generates the expected sequence. TEST(ValuesTest, ValuesWorks) { const ParamGenerator gen = Values(3, 5, 8); const int expected_values[] = {3, 5, 8}; VerifyGenerator(gen, expected_values); } // Tests that Values() generates the expected sequences from elements of // different types convertible to ParamGenerator's parameter type. TEST(ValuesTest, ValuesWorksForValuesOfCompatibleTypes) { const ParamGenerator gen = Values(3, 5.0f, 8.0); const double expected_values[] = {3.0, 5.0, 8.0}; VerifyGenerator(gen, expected_values); } TEST(ValuesTest, ValuesWorksForMaxLengthList) { const ParamGenerator gen = Values( 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500); const int expected_values[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500}; VerifyGenerator(gen, expected_values); } // Edge case test. Tests that single-parameter Values() generates the sequence // with the single value. TEST(ValuesTest, ValuesWithSingleParameter) { const ParamGenerator gen = Values(42); const int expected_values[] = {42}; VerifyGenerator(gen, expected_values); } // Tests that Bool() generates sequence (false, true). TEST(BoolTest, BoolWorks) { const ParamGenerator gen = Bool(); const bool expected_values[] = {false, true}; VerifyGenerator(gen, expected_values); } // Tests that Combine() with two parameters generates the expected sequence. TEST(CombineTest, CombineWithTwoParameters) { const char* foo = "foo"; const char* bar = "bar"; const ParamGenerator > gen = Combine(Values(foo, bar), Values(3, 4)); std::tuple expected_values[] = { std::make_tuple(foo, 3), std::make_tuple(foo, 4), std::make_tuple(bar, 3), std::make_tuple(bar, 4)}; VerifyGenerator(gen, expected_values); } // Tests that Combine() with three parameters generates the expected sequence. TEST(CombineTest, CombineWithThreeParameters) { const ParamGenerator > gen = Combine(Values(0, 1), Values(3, 4), Values(5, 6)); std::tuple expected_values[] = { std::make_tuple(0, 3, 5), std::make_tuple(0, 3, 6), std::make_tuple(0, 4, 5), std::make_tuple(0, 4, 6), std::make_tuple(1, 3, 5), std::make_tuple(1, 3, 6), std::make_tuple(1, 4, 5), std::make_tuple(1, 4, 6)}; VerifyGenerator(gen, expected_values); } // Tests that the Combine() with the first parameter generating a single value // sequence generates a sequence with the number of elements equal to the // number of elements in the sequence generated by the second parameter. TEST(CombineTest, CombineWithFirstParameterSingleValue) { const ParamGenerator > gen = Combine(Values(42), Values(0, 1)); std::tuple expected_values[] = {std::make_tuple(42, 0), std::make_tuple(42, 1)}; VerifyGenerator(gen, expected_values); } // Tests that the Combine() with the second parameter generating a single value // sequence generates a sequence with the number of elements equal to the // number of elements in the sequence generated by the first parameter. TEST(CombineTest, CombineWithSecondParameterSingleValue) { const ParamGenerator > gen = Combine(Values(0, 1), Values(42)); std::tuple expected_values[] = {std::make_tuple(0, 42), std::make_tuple(1, 42)}; VerifyGenerator(gen, expected_values); } // Tests that when the first parameter produces an empty sequence, // Combine() produces an empty sequence, too. TEST(CombineTest, CombineWithFirstParameterEmptyRange) { const ParamGenerator > gen = Combine(Range(0, 0), Values(0, 1)); VerifyGeneratorIsEmpty(gen); } // Tests that when the second parameter produces an empty sequence, // Combine() produces an empty sequence, too. TEST(CombineTest, CombineWithSecondParameterEmptyRange) { const ParamGenerator > gen = Combine(Values(0, 1), Range(1, 1)); VerifyGeneratorIsEmpty(gen); } // Edge case. Tests that combine works with the maximum number // of parameters supported by Google Test (currently 10). TEST(CombineTest, CombineWithMaxNumberOfParameters) { const char* foo = "foo"; const char* bar = "bar"; const ParamGenerator< std::tuple > gen = Combine(Values(foo, bar), Values(1), Values(2), Values(3), Values(4), Values(5), Values(6), Values(7), Values(8), Values(9)); std::tuple expected_values[] = {std::make_tuple(foo, 1, 2, 3, 4, 5, 6, 7, 8, 9), std::make_tuple(bar, 1, 2, 3, 4, 5, 6, 7, 8, 9)}; VerifyGenerator(gen, expected_values); } class NonDefaultConstructAssignString { public: NonDefaultConstructAssignString(const std::string& s) : str_(s) {} const std::string& str() const { return str_; } private: std::string str_; // Not default constructible NonDefaultConstructAssignString(); // Not assignable void operator=(const NonDefaultConstructAssignString&); }; TEST(CombineTest, NonDefaultConstructAssign) { const ParamGenerator > gen = Combine(Values(0, 1), Values(NonDefaultConstructAssignString("A"), NonDefaultConstructAssignString("B"))); ParamGenerator >::iterator it = gen.begin(); EXPECT_EQ(0, std::get<0>(*it)); EXPECT_EQ("A", std::get<1>(*it).str()); ++it; EXPECT_EQ(0, std::get<0>(*it)); EXPECT_EQ("B", std::get<1>(*it).str()); ++it; EXPECT_EQ(1, std::get<0>(*it)); EXPECT_EQ("A", std::get<1>(*it).str()); ++it; EXPECT_EQ(1, std::get<0>(*it)); EXPECT_EQ("B", std::get<1>(*it).str()); ++it; EXPECT_TRUE(it == gen.end()); } // Tests that an generator produces correct sequence after being // assigned from another generator. TEST(ParamGeneratorTest, AssignmentWorks) { ParamGenerator gen = Values(1, 2); const ParamGenerator gen2 = Values(3, 4); gen = gen2; const int expected_values[] = {3, 4}; VerifyGenerator(gen, expected_values); } // This test verifies that the tests are expanded and run as specified: // one test per element from the sequence produced by the generator // specified in INSTANTIATE_TEST_SUITE_P. It also verifies that the test's // fixture constructor, SetUp(), and TearDown() have run and have been // supplied with the correct parameters. // The use of environment object allows detection of the case where no test // case functionality is run at all. In this case TearDownTestSuite will not // be able to detect missing tests, naturally. template class TestGenerationEnvironment : public ::testing::Environment { public: static TestGenerationEnvironment* Instance() { static TestGenerationEnvironment* instance = new TestGenerationEnvironment; return instance; } void FixtureConstructorExecuted() { fixture_constructor_count_++; } void SetUpExecuted() { set_up_count_++; } void TearDownExecuted() { tear_down_count_++; } void TestBodyExecuted() { test_body_count_++; } void TearDown() override { // If all MultipleTestGenerationTest tests have been de-selected // by the filter flag, the following checks make no sense. bool perform_check = false; for (int i = 0; i < kExpectedCalls; ++i) { Message msg; msg << "TestsExpandedAndRun/" << i; if (UnitTestOptions::FilterMatchesTest( "TestExpansionModule/MultipleTestGenerationTest", msg.GetString().c_str())) { perform_check = true; } } if (perform_check) { EXPECT_EQ(kExpectedCalls, fixture_constructor_count_) << "Fixture constructor of ParamTestGenerationTest test case " << "has not been run as expected."; EXPECT_EQ(kExpectedCalls, set_up_count_) << "Fixture SetUp method of ParamTestGenerationTest test case " << "has not been run as expected."; EXPECT_EQ(kExpectedCalls, tear_down_count_) << "Fixture TearDown method of ParamTestGenerationTest test case " << "has not been run as expected."; EXPECT_EQ(kExpectedCalls, test_body_count_) << "Test in ParamTestGenerationTest test case " << "has not been run as expected."; } } private: TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0), tear_down_count_(0), test_body_count_(0) {} int fixture_constructor_count_; int set_up_count_; int tear_down_count_; int test_body_count_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationEnvironment); }; const int test_generation_params[] = {36, 42, 72}; class TestGenerationTest : public TestWithParam { public: enum { PARAMETER_COUNT = sizeof(test_generation_params)/sizeof(test_generation_params[0]) }; typedef TestGenerationEnvironment Environment; TestGenerationTest() { Environment::Instance()->FixtureConstructorExecuted(); current_parameter_ = GetParam(); } void SetUp() override { Environment::Instance()->SetUpExecuted(); EXPECT_EQ(current_parameter_, GetParam()); } void TearDown() override { Environment::Instance()->TearDownExecuted(); EXPECT_EQ(current_parameter_, GetParam()); } static void SetUpTestSuite() { bool all_tests_in_test_case_selected = true; for (int i = 0; i < PARAMETER_COUNT; ++i) { Message test_name; test_name << "TestsExpandedAndRun/" << i; if ( !UnitTestOptions::FilterMatchesTest( "TestExpansionModule/MultipleTestGenerationTest", test_name.GetString())) { all_tests_in_test_case_selected = false; } } EXPECT_TRUE(all_tests_in_test_case_selected) << "When running the TestGenerationTest test case all of its tests\n" << "must be selected by the filter flag for the test case to pass.\n" << "If not all of them are enabled, we can't reliably conclude\n" << "that the correct number of tests have been generated."; collected_parameters_.clear(); } static void TearDownTestSuite() { vector expected_values(test_generation_params, test_generation_params + PARAMETER_COUNT); // Test execution order is not guaranteed by Google Test, // so the order of values in collected_parameters_ can be // different and we have to sort to compare. sort(expected_values.begin(), expected_values.end()); sort(collected_parameters_.begin(), collected_parameters_.end()); EXPECT_TRUE(collected_parameters_ == expected_values); } protected: int current_parameter_; static vector collected_parameters_; private: GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationTest); }; vector TestGenerationTest::collected_parameters_; TEST_P(TestGenerationTest, TestsExpandedAndRun) { Environment::Instance()->TestBodyExecuted(); EXPECT_EQ(current_parameter_, GetParam()); collected_parameters_.push_back(GetParam()); } INSTANTIATE_TEST_SUITE_P(TestExpansionModule, TestGenerationTest, ValuesIn(test_generation_params)); // This test verifies that the element sequence (third parameter of // INSTANTIATE_TEST_SUITE_P) is evaluated in InitGoogleTest() and neither at // the call site of INSTANTIATE_TEST_SUITE_P nor in RUN_ALL_TESTS(). For // that, we declare param_value_ to be a static member of // GeneratorEvaluationTest and initialize it to 0. We set it to 1 in // main(), just before invocation of InitGoogleTest(). After calling // InitGoogleTest(), we set the value to 2. If the sequence is evaluated // before or after InitGoogleTest, INSTANTIATE_TEST_SUITE_P will create a // test with parameter other than 1, and the test body will fail the // assertion. class GeneratorEvaluationTest : public TestWithParam { public: static int param_value() { return param_value_; } static void set_param_value(int param_value) { param_value_ = param_value; } private: static int param_value_; }; int GeneratorEvaluationTest::param_value_ = 0; TEST_P(GeneratorEvaluationTest, GeneratorsEvaluatedInMain) { EXPECT_EQ(1, GetParam()); } INSTANTIATE_TEST_SUITE_P(GenEvalModule, GeneratorEvaluationTest, Values(GeneratorEvaluationTest::param_value())); // Tests that generators defined in a different translation unit are // functional. Generator extern_gen is defined in gtest-param-test_test2.cc. extern ParamGenerator extern_gen; class ExternalGeneratorTest : public TestWithParam {}; TEST_P(ExternalGeneratorTest, ExternalGenerator) { // Sequence produced by extern_gen contains only a single value // which we verify here. EXPECT_EQ(GetParam(), 33); } INSTANTIATE_TEST_SUITE_P(ExternalGeneratorModule, ExternalGeneratorTest, extern_gen); // Tests that a parameterized test case can be defined in one translation // unit and instantiated in another. This test will be instantiated in // gtest-param-test_test2.cc. ExternalInstantiationTest fixture class is // defined in gtest-param-test_test.h. TEST_P(ExternalInstantiationTest, IsMultipleOf33) { EXPECT_EQ(0, GetParam() % 33); } // Tests that a parameterized test case can be instantiated with multiple // generators. class MultipleInstantiationTest : public TestWithParam {}; TEST_P(MultipleInstantiationTest, AllowsMultipleInstances) { } INSTANTIATE_TEST_SUITE_P(Sequence1, MultipleInstantiationTest, Values(1, 2)); INSTANTIATE_TEST_SUITE_P(Sequence2, MultipleInstantiationTest, Range(3, 5)); // Tests that a parameterized test case can be instantiated // in multiple translation units. This test will be instantiated // here and in gtest-param-test_test2.cc. // InstantiationInMultipleTranslationUnitsTest fixture class // is defined in gtest-param-test_test.h. TEST_P(InstantiationInMultipleTranslationUnitsTest, IsMultipleOf42) { EXPECT_EQ(0, GetParam() % 42); } INSTANTIATE_TEST_SUITE_P(Sequence1, InstantiationInMultipleTranslationUnitsTest, Values(42, 42 * 2)); // Tests that each iteration of parameterized test runs in a separate test // object. class SeparateInstanceTest : public TestWithParam { public: SeparateInstanceTest() : count_(0) {} static void TearDownTestSuite() { EXPECT_GE(global_count_, 2) << "If some (but not all) SeparateInstanceTest tests have been " << "filtered out this test will fail. Make sure that all " << "GeneratorEvaluationTest are selected or de-selected together " << "by the test filter."; } protected: int count_; static int global_count_; }; int SeparateInstanceTest::global_count_ = 0; TEST_P(SeparateInstanceTest, TestsRunInSeparateInstances) { EXPECT_EQ(0, count_++); global_count_++; } INSTANTIATE_TEST_SUITE_P(FourElemSequence, SeparateInstanceTest, Range(1, 4)); // Tests that all instantiations of a test have named appropriately. Test // defined with TEST_P(TestSuiteName, TestName) and instantiated with // INSTANTIATE_TEST_SUITE_P(SequenceName, TestSuiteName, generator) must be // named SequenceName/TestSuiteName.TestName/i, where i is the 0-based index of // the sequence element used to instantiate the test. class NamingTest : public TestWithParam {}; TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_suite_name()); Message index_stream; index_stream << "TestsReportCorrectNamesAndParameters/" << GetParam(); EXPECT_STREQ(index_stream.GetString().c_str(), test_info->name()); EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); } INSTANTIATE_TEST_SUITE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); // Tests that macros in test names are expanded correctly. class MacroNamingTest : public TestWithParam {}; #define PREFIX_WITH_FOO(test_name) Foo##test_name #define PREFIX_WITH_MACRO(test_name) Macro##test_name TEST_P(PREFIX_WITH_MACRO(NamingTest), PREFIX_WITH_FOO(SomeTestName)) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); EXPECT_STREQ("FortyTwo/MacroNamingTest", test_info->test_suite_name()); - EXPECT_STREQ("FooSomeTestName", test_info->name()); + EXPECT_STREQ("FooSomeTestName/0", test_info->name()); } INSTANTIATE_TEST_SUITE_P(FortyTwo, MacroNamingTest, Values(42)); // Tests the same thing for non-parametrized tests. class MacroNamingTestNonParametrized : public ::testing::Test {}; TEST_F(PREFIX_WITH_MACRO(NamingTestNonParametrized), PREFIX_WITH_FOO(SomeTestName)) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); EXPECT_STREQ("MacroNamingTestNonParametrized", test_info->test_suite_name()); EXPECT_STREQ("FooSomeTestName", test_info->name()); } +TEST(MacroNameing, LookupNames) { + std::set know_suite_names, know_test_names; + + auto ins = testing::UnitTest::GetInstance(); + int ts = 0; + while (const testing::TestSuite* suite = ins->GetTestSuite(ts++)) { + know_suite_names.insert(suite->name()); + + int ti = 0; + while (const testing::TestInfo* info = suite->GetTestInfo(ti++)) { + know_test_names.insert(std::string(suite->name()) + "." + info->name()); + } + } + + // Check that the expected form of the test suit name actualy exists. + EXPECT_NE( // + know_suite_names.find("FortyTwo/MacroNamingTest"), + know_suite_names.end()); + EXPECT_NE( + know_suite_names.find("MacroNamingTestNonParametrized"), + know_suite_names.end()); + // Check that the expected form of the test name actualy exists. + EXPECT_NE( // + know_test_names.find("FortyTwo/MacroNamingTest.FooSomeTestName/0"), + know_test_names.end()); + EXPECT_NE( + know_test_names.find("MacroNamingTestNonParametrized.FooSomeTestName"), + know_test_names.end()); +} + // Tests that user supplied custom parameter names are working correctly. // Runs the test with a builtin helper method which uses PrintToString, // as well as a custom function and custom functor to ensure all possible // uses work correctly. class CustomFunctorNamingTest : public TestWithParam {}; TEST_P(CustomFunctorNamingTest, CustomTestNames) {} struct CustomParamNameFunctor { std::string operator()(const ::testing::TestParamInfo& inf) { return inf.param; } }; INSTANTIATE_TEST_SUITE_P(CustomParamNameFunctor, CustomFunctorNamingTest, Values(std::string("FunctorName")), CustomParamNameFunctor()); INSTANTIATE_TEST_SUITE_P(AllAllowedCharacters, CustomFunctorNamingTest, Values("abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "01234567890_"), CustomParamNameFunctor()); inline std::string CustomParamNameFunction( const ::testing::TestParamInfo& inf) { return inf.param; } class CustomFunctionNamingTest : public TestWithParam {}; TEST_P(CustomFunctionNamingTest, CustomTestNames) {} INSTANTIATE_TEST_SUITE_P(CustomParamNameFunction, CustomFunctionNamingTest, Values(std::string("FunctionName")), CustomParamNameFunction); INSTANTIATE_TEST_SUITE_P(CustomParamNameFunctionP, CustomFunctionNamingTest, Values(std::string("FunctionNameP")), &CustomParamNameFunction); // Test custom naming with a lambda class CustomLambdaNamingTest : public TestWithParam {}; TEST_P(CustomLambdaNamingTest, CustomTestNames) {} INSTANTIATE_TEST_SUITE_P(CustomParamNameLambda, CustomLambdaNamingTest, Values(std::string("LambdaName")), [](const ::testing::TestParamInfo& inf) { return inf.param; }); TEST(CustomNamingTest, CheckNameRegistry) { ::testing::UnitTest* unit_test = ::testing::UnitTest::GetInstance(); std::set test_names; for (int suite_num = 0; suite_num < unit_test->total_test_suite_count(); ++suite_num) { const ::testing::TestSuite* test_suite = unit_test->GetTestSuite(suite_num); for (int test_num = 0; test_num < test_suite->total_test_count(); ++test_num) { const ::testing::TestInfo* test_info = test_suite->GetTestInfo(test_num); test_names.insert(std::string(test_info->name())); } } EXPECT_EQ(1u, test_names.count("CustomTestNames/FunctorName")); EXPECT_EQ(1u, test_names.count("CustomTestNames/FunctionName")); EXPECT_EQ(1u, test_names.count("CustomTestNames/FunctionNameP")); EXPECT_EQ(1u, test_names.count("CustomTestNames/LambdaName")); } // Test a numeric name to ensure PrintToStringParamName works correctly. class CustomIntegerNamingTest : public TestWithParam {}; TEST_P(CustomIntegerNamingTest, TestsReportCorrectNames) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); Message test_name_stream; test_name_stream << "TestsReportCorrectNames/" << GetParam(); EXPECT_STREQ(test_name_stream.GetString().c_str(), test_info->name()); } INSTANTIATE_TEST_SUITE_P(PrintToString, CustomIntegerNamingTest, Range(0, 5), ::testing::PrintToStringParamName()); // Test a custom struct with PrintToString. struct CustomStruct { explicit CustomStruct(int value) : x(value) {} int x; }; std::ostream& operator<<(std::ostream& stream, const CustomStruct& val) { stream << val.x; return stream; } class CustomStructNamingTest : public TestWithParam {}; TEST_P(CustomStructNamingTest, TestsReportCorrectNames) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); Message test_name_stream; test_name_stream << "TestsReportCorrectNames/" << GetParam(); EXPECT_STREQ(test_name_stream.GetString().c_str(), test_info->name()); } INSTANTIATE_TEST_SUITE_P(PrintToString, CustomStructNamingTest, Values(CustomStruct(0), CustomStruct(1)), ::testing::PrintToStringParamName()); // Test that using a stateful parameter naming function works as expected. struct StatefulNamingFunctor { StatefulNamingFunctor() : sum(0) {} std::string operator()(const ::testing::TestParamInfo& info) { int value = info.param + sum; sum += info.param; return ::testing::PrintToString(value); } int sum; }; class StatefulNamingTest : public ::testing::TestWithParam { protected: StatefulNamingTest() : sum_(0) {} int sum_; }; TEST_P(StatefulNamingTest, TestsReportCorrectNames) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); sum_ += GetParam(); Message test_name_stream; test_name_stream << "TestsReportCorrectNames/" << sum_; EXPECT_STREQ(test_name_stream.GetString().c_str(), test_info->name()); } INSTANTIATE_TEST_SUITE_P(StatefulNamingFunctor, StatefulNamingTest, Range(0, 5), StatefulNamingFunctor()); // Class that cannot be streamed into an ostream. It needs to be copyable // (and, in case of MSVC, also assignable) in order to be a test parameter // type. Its default copy constructor and assignment operator do exactly // what we need. class Unstreamable { public: explicit Unstreamable(int value) : value_(value) {} // -Wunused-private-field: dummy accessor for `value_`. const int& dummy_value() const { return value_; } private: int value_; }; class CommentTest : public TestWithParam {}; TEST_P(CommentTest, TestsCorrectlyReportUnstreamableParams) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); EXPECT_EQ(::testing::PrintToString(GetParam()), test_info->value_param()); } INSTANTIATE_TEST_SUITE_P(InstantiationWithComments, CommentTest, Values(Unstreamable(1))); // Verify that we can create a hierarchy of test fixtures, where the base // class fixture is not parameterized and the derived class is. In this case // ParameterizedDerivedTest inherits from NonParameterizedBaseTest. We // perform simple tests on both. class NonParameterizedBaseTest : public ::testing::Test { public: NonParameterizedBaseTest() : n_(17) { } protected: int n_; }; class ParameterizedDerivedTest : public NonParameterizedBaseTest, public ::testing::WithParamInterface { protected: ParameterizedDerivedTest() : count_(0) { } int count_; static int global_count_; }; int ParameterizedDerivedTest::global_count_ = 0; TEST_F(NonParameterizedBaseTest, FixtureIsInitialized) { EXPECT_EQ(17, n_); } TEST_P(ParameterizedDerivedTest, SeesSequence) { EXPECT_EQ(17, n_); EXPECT_EQ(0, count_++); EXPECT_EQ(GetParam(), global_count_++); } class ParameterizedDeathTest : public ::testing::TestWithParam { }; TEST_F(ParameterizedDeathTest, GetParamDiesFromTestF) { EXPECT_DEATH_IF_SUPPORTED(GetParam(), ".* value-parameterized test .*"); } INSTANTIATE_TEST_SUITE_P(RangeZeroToFive, ParameterizedDerivedTest, Range(0, 5)); // Tests param generator working with Enums enum MyEnums { ENUM1 = 1, ENUM2 = 3, ENUM3 = 8, }; class MyEnumTest : public testing::TestWithParam {}; TEST_P(MyEnumTest, ChecksParamMoreThanZero) { EXPECT_GE(10, GetParam()); } INSTANTIATE_TEST_SUITE_P(MyEnumTests, MyEnumTest, ::testing::Values(ENUM1, ENUM2, 0)); int main(int argc, char **argv) { // Used in TestGenerationTest test suite. AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance()); // Used in GeneratorEvaluationTest test suite. Tests that the updated value // will be picked up for instantiating tests in GeneratorEvaluationTest. GeneratorEvaluationTest::set_param_value(1); ::testing::InitGoogleTest(&argc, argv); // Used in GeneratorEvaluationTest test suite. Tests that value updated // here will NOT be used for instantiating tests in // GeneratorEvaluationTest. GeneratorEvaluationTest::set_param_value(2); return RUN_ALL_TESTS(); }