xref: /freebsd-src/contrib/googletest/googletest/samples/sample6_unittest.cc (revision 28f6c2f292806bf31230a959bc4b19d7081669a7)
1b89a7cc2SEnji Cooper // Copyright 2008 Google Inc.
2b89a7cc2SEnji Cooper // All Rights Reserved.
3b89a7cc2SEnji Cooper //
4b89a7cc2SEnji Cooper // Redistribution and use in source and binary forms, with or without
5b89a7cc2SEnji Cooper // modification, are permitted provided that the following conditions are
6b89a7cc2SEnji Cooper // met:
7b89a7cc2SEnji Cooper //
8b89a7cc2SEnji Cooper //     * Redistributions of source code must retain the above copyright
9b89a7cc2SEnji Cooper // notice, this list of conditions and the following disclaimer.
10b89a7cc2SEnji Cooper //     * Redistributions in binary form must reproduce the above
11b89a7cc2SEnji Cooper // copyright notice, this list of conditions and the following disclaimer
12b89a7cc2SEnji Cooper // in the documentation and/or other materials provided with the
13b89a7cc2SEnji Cooper // distribution.
14b89a7cc2SEnji Cooper //     * Neither the name of Google Inc. nor the names of its
15b89a7cc2SEnji Cooper // contributors may be used to endorse or promote products derived from
16b89a7cc2SEnji Cooper // this software without specific prior written permission.
17b89a7cc2SEnji Cooper //
18b89a7cc2SEnji Cooper // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19b89a7cc2SEnji Cooper // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20b89a7cc2SEnji Cooper // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21b89a7cc2SEnji Cooper // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22b89a7cc2SEnji Cooper // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23b89a7cc2SEnji Cooper // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24b89a7cc2SEnji Cooper // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25b89a7cc2SEnji Cooper // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26b89a7cc2SEnji Cooper // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27b89a7cc2SEnji Cooper // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28b89a7cc2SEnji Cooper // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29b89a7cc2SEnji Cooper 
30b89a7cc2SEnji Cooper // This sample shows how to test common properties of multiple
31b89a7cc2SEnji Cooper // implementations of the same interface (aka interface tests).
32b89a7cc2SEnji Cooper 
33b89a7cc2SEnji Cooper // The interface and its implementations are in this header.
34b89a7cc2SEnji Cooper #include "prime_tables.h"
35b89a7cc2SEnji Cooper #include "gtest/gtest.h"
36b89a7cc2SEnji Cooper namespace {
37b89a7cc2SEnji Cooper // First, we define some factory functions for creating instances of
38b89a7cc2SEnji Cooper // the implementations.  You may be able to skip this step if all your
39b89a7cc2SEnji Cooper // implementations can be constructed the same way.
40b89a7cc2SEnji Cooper 
41b89a7cc2SEnji Cooper template <class T>
42b89a7cc2SEnji Cooper PrimeTable* CreatePrimeTable();
43b89a7cc2SEnji Cooper 
44b89a7cc2SEnji Cooper template <>
CreatePrimeTable()45b89a7cc2SEnji Cooper PrimeTable* CreatePrimeTable<OnTheFlyPrimeTable>() {
46b89a7cc2SEnji Cooper   return new OnTheFlyPrimeTable;
47b89a7cc2SEnji Cooper }
48b89a7cc2SEnji Cooper 
49b89a7cc2SEnji Cooper template <>
CreatePrimeTable()50b89a7cc2SEnji Cooper PrimeTable* CreatePrimeTable<PreCalculatedPrimeTable>() {
51b89a7cc2SEnji Cooper   return new PreCalculatedPrimeTable(10000);
52b89a7cc2SEnji Cooper }
53b89a7cc2SEnji Cooper 
54b89a7cc2SEnji Cooper // Then we define a test fixture class template.
55b89a7cc2SEnji Cooper template <class T>
56b89a7cc2SEnji Cooper class PrimeTableTest : public testing::Test {
57b89a7cc2SEnji Cooper  protected:
58b89a7cc2SEnji Cooper   // The ctor calls the factory function to create a prime table
59b89a7cc2SEnji Cooper   // implemented by T.
PrimeTableTest()60b89a7cc2SEnji Cooper   PrimeTableTest() : table_(CreatePrimeTable<T>()) {}
61b89a7cc2SEnji Cooper 
~PrimeTableTest()62*28f6c2f2SEnji Cooper   ~PrimeTableTest() override { delete table_; }
63b89a7cc2SEnji Cooper 
64b89a7cc2SEnji Cooper   // Note that we test an implementation via the base interface
65b89a7cc2SEnji Cooper   // instead of the actual implementation class.  This is important
66b89a7cc2SEnji Cooper   // for keeping the tests close to the real world scenario, where the
67b89a7cc2SEnji Cooper   // implementation is invoked via the base interface.  It avoids
68b89a7cc2SEnji Cooper   // got-yas where the implementation class has a method that shadows
69b89a7cc2SEnji Cooper   // a method with the same name (but slightly different argument
70b89a7cc2SEnji Cooper   // types) in the base interface, for example.
71b89a7cc2SEnji Cooper   PrimeTable* const table_;
72b89a7cc2SEnji Cooper };
73b89a7cc2SEnji Cooper 
74b89a7cc2SEnji Cooper using testing::Types;
75b89a7cc2SEnji Cooper 
76b89a7cc2SEnji Cooper // Google Test offers two ways for reusing tests for different types.
77b89a7cc2SEnji Cooper // The first is called "typed tests".  You should use it if you
78b89a7cc2SEnji Cooper // already know *all* the types you are gonna exercise when you write
79b89a7cc2SEnji Cooper // the tests.
80b89a7cc2SEnji Cooper 
81b89a7cc2SEnji Cooper // To write a typed test case, first use
82b89a7cc2SEnji Cooper //
83*28f6c2f2SEnji Cooper //   TYPED_TEST_SUITE(TestCaseName, TypeList);
84b89a7cc2SEnji Cooper //
85b89a7cc2SEnji Cooper // to declare it and specify the type parameters.  As with TEST_F,
86b89a7cc2SEnji Cooper // TestCaseName must match the test fixture name.
87b89a7cc2SEnji Cooper 
88b89a7cc2SEnji Cooper // The list of types we want to test.
89b89a7cc2SEnji Cooper typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable> Implementations;
90b89a7cc2SEnji Cooper 
91*28f6c2f2SEnji Cooper TYPED_TEST_SUITE(PrimeTableTest, Implementations);
92b89a7cc2SEnji Cooper 
93b89a7cc2SEnji Cooper // Then use TYPED_TEST(TestCaseName, TestName) to define a typed test,
94b89a7cc2SEnji Cooper // similar to TEST_F.
TYPED_TEST(PrimeTableTest,ReturnsFalseForNonPrimes)95b89a7cc2SEnji Cooper TYPED_TEST(PrimeTableTest, ReturnsFalseForNonPrimes) {
96b89a7cc2SEnji Cooper   // Inside the test body, you can refer to the type parameter by
97b89a7cc2SEnji Cooper   // TypeParam, and refer to the fixture class by TestFixture.  We
98b89a7cc2SEnji Cooper   // don't need them in this example.
99b89a7cc2SEnji Cooper 
100b89a7cc2SEnji Cooper   // Since we are in the template world, C++ requires explicitly
101b89a7cc2SEnji Cooper   // writing 'this->' when referring to members of the fixture class.
102b89a7cc2SEnji Cooper   // This is something you have to learn to live with.
103b89a7cc2SEnji Cooper   EXPECT_FALSE(this->table_->IsPrime(-5));
104b89a7cc2SEnji Cooper   EXPECT_FALSE(this->table_->IsPrime(0));
105b89a7cc2SEnji Cooper   EXPECT_FALSE(this->table_->IsPrime(1));
106b89a7cc2SEnji Cooper   EXPECT_FALSE(this->table_->IsPrime(4));
107b89a7cc2SEnji Cooper   EXPECT_FALSE(this->table_->IsPrime(6));
108b89a7cc2SEnji Cooper   EXPECT_FALSE(this->table_->IsPrime(100));
109b89a7cc2SEnji Cooper }
110b89a7cc2SEnji Cooper 
TYPED_TEST(PrimeTableTest,ReturnsTrueForPrimes)111b89a7cc2SEnji Cooper TYPED_TEST(PrimeTableTest, ReturnsTrueForPrimes) {
112b89a7cc2SEnji Cooper   EXPECT_TRUE(this->table_->IsPrime(2));
113b89a7cc2SEnji Cooper   EXPECT_TRUE(this->table_->IsPrime(3));
114b89a7cc2SEnji Cooper   EXPECT_TRUE(this->table_->IsPrime(5));
115b89a7cc2SEnji Cooper   EXPECT_TRUE(this->table_->IsPrime(7));
116b89a7cc2SEnji Cooper   EXPECT_TRUE(this->table_->IsPrime(11));
117b89a7cc2SEnji Cooper   EXPECT_TRUE(this->table_->IsPrime(131));
118b89a7cc2SEnji Cooper }
119b89a7cc2SEnji Cooper 
TYPED_TEST(PrimeTableTest,CanGetNextPrime)120b89a7cc2SEnji Cooper TYPED_TEST(PrimeTableTest, CanGetNextPrime) {
121b89a7cc2SEnji Cooper   EXPECT_EQ(2, this->table_->GetNextPrime(0));
122b89a7cc2SEnji Cooper   EXPECT_EQ(3, this->table_->GetNextPrime(2));
123b89a7cc2SEnji Cooper   EXPECT_EQ(5, this->table_->GetNextPrime(3));
124b89a7cc2SEnji Cooper   EXPECT_EQ(7, this->table_->GetNextPrime(5));
125b89a7cc2SEnji Cooper   EXPECT_EQ(11, this->table_->GetNextPrime(7));
126b89a7cc2SEnji Cooper   EXPECT_EQ(131, this->table_->GetNextPrime(128));
127b89a7cc2SEnji Cooper }
128b89a7cc2SEnji Cooper 
129b89a7cc2SEnji Cooper // That's it!  Google Test will repeat each TYPED_TEST for each type
130*28f6c2f2SEnji Cooper // in the type list specified in TYPED_TEST_SUITE.  Sit back and be
131b89a7cc2SEnji Cooper // happy that you don't have to define them multiple times.
132b89a7cc2SEnji Cooper 
133b89a7cc2SEnji Cooper using testing::Types;
134b89a7cc2SEnji Cooper 
135b89a7cc2SEnji Cooper // Sometimes, however, you don't yet know all the types that you want
136b89a7cc2SEnji Cooper // to test when you write the tests.  For example, if you are the
137b89a7cc2SEnji Cooper // author of an interface and expect other people to implement it, you
138b89a7cc2SEnji Cooper // might want to write a set of tests to make sure each implementation
139b89a7cc2SEnji Cooper // conforms to some basic requirements, but you don't know what
140b89a7cc2SEnji Cooper // implementations will be written in the future.
141b89a7cc2SEnji Cooper //
142b89a7cc2SEnji Cooper // How can you write the tests without committing to the type
143b89a7cc2SEnji Cooper // parameters?  That's what "type-parameterized tests" can do for you.
144b89a7cc2SEnji Cooper // It is a bit more involved than typed tests, but in return you get a
145b89a7cc2SEnji Cooper // test pattern that can be reused in many contexts, which is a big
146b89a7cc2SEnji Cooper // win.  Here's how you do it:
147b89a7cc2SEnji Cooper 
148b89a7cc2SEnji Cooper // First, define a test fixture class template.  Here we just reuse
149b89a7cc2SEnji Cooper // the PrimeTableTest fixture defined earlier:
150b89a7cc2SEnji Cooper 
151b89a7cc2SEnji Cooper template <class T>
152*28f6c2f2SEnji Cooper class PrimeTableTest2 : public PrimeTableTest<T> {};
153b89a7cc2SEnji Cooper 
154b89a7cc2SEnji Cooper // Then, declare the test case.  The argument is the name of the test
155b89a7cc2SEnji Cooper // fixture, and also the name of the test case (as usual).  The _P
156b89a7cc2SEnji Cooper // suffix is for "parameterized" or "pattern".
157*28f6c2f2SEnji Cooper TYPED_TEST_SUITE_P(PrimeTableTest2);
158b89a7cc2SEnji Cooper 
159b89a7cc2SEnji Cooper // Next, use TYPED_TEST_P(TestCaseName, TestName) to define a test,
160b89a7cc2SEnji Cooper // similar to what you do with TEST_F.
TYPED_TEST_P(PrimeTableTest2,ReturnsFalseForNonPrimes)161b89a7cc2SEnji Cooper TYPED_TEST_P(PrimeTableTest2, ReturnsFalseForNonPrimes) {
162b89a7cc2SEnji Cooper   EXPECT_FALSE(this->table_->IsPrime(-5));
163b89a7cc2SEnji Cooper   EXPECT_FALSE(this->table_->IsPrime(0));
164b89a7cc2SEnji Cooper   EXPECT_FALSE(this->table_->IsPrime(1));
165b89a7cc2SEnji Cooper   EXPECT_FALSE(this->table_->IsPrime(4));
166b89a7cc2SEnji Cooper   EXPECT_FALSE(this->table_->IsPrime(6));
167b89a7cc2SEnji Cooper   EXPECT_FALSE(this->table_->IsPrime(100));
168b89a7cc2SEnji Cooper }
169b89a7cc2SEnji Cooper 
TYPED_TEST_P(PrimeTableTest2,ReturnsTrueForPrimes)170b89a7cc2SEnji Cooper TYPED_TEST_P(PrimeTableTest2, ReturnsTrueForPrimes) {
171b89a7cc2SEnji Cooper   EXPECT_TRUE(this->table_->IsPrime(2));
172b89a7cc2SEnji Cooper   EXPECT_TRUE(this->table_->IsPrime(3));
173b89a7cc2SEnji Cooper   EXPECT_TRUE(this->table_->IsPrime(5));
174b89a7cc2SEnji Cooper   EXPECT_TRUE(this->table_->IsPrime(7));
175b89a7cc2SEnji Cooper   EXPECT_TRUE(this->table_->IsPrime(11));
176b89a7cc2SEnji Cooper   EXPECT_TRUE(this->table_->IsPrime(131));
177b89a7cc2SEnji Cooper }
178b89a7cc2SEnji Cooper 
TYPED_TEST_P(PrimeTableTest2,CanGetNextPrime)179b89a7cc2SEnji Cooper TYPED_TEST_P(PrimeTableTest2, CanGetNextPrime) {
180b89a7cc2SEnji Cooper   EXPECT_EQ(2, this->table_->GetNextPrime(0));
181b89a7cc2SEnji Cooper   EXPECT_EQ(3, this->table_->GetNextPrime(2));
182b89a7cc2SEnji Cooper   EXPECT_EQ(5, this->table_->GetNextPrime(3));
183b89a7cc2SEnji Cooper   EXPECT_EQ(7, this->table_->GetNextPrime(5));
184b89a7cc2SEnji Cooper   EXPECT_EQ(11, this->table_->GetNextPrime(7));
185b89a7cc2SEnji Cooper   EXPECT_EQ(131, this->table_->GetNextPrime(128));
186b89a7cc2SEnji Cooper }
187b89a7cc2SEnji Cooper 
188b89a7cc2SEnji Cooper // Type-parameterized tests involve one extra step: you have to
189b89a7cc2SEnji Cooper // enumerate the tests you defined:
190*28f6c2f2SEnji Cooper REGISTER_TYPED_TEST_SUITE_P(
191b89a7cc2SEnji Cooper     PrimeTableTest2,  // The first argument is the test case name.
192b89a7cc2SEnji Cooper     // The rest of the arguments are the test names.
193b89a7cc2SEnji Cooper     ReturnsFalseForNonPrimes, ReturnsTrueForPrimes, CanGetNextPrime);
194b89a7cc2SEnji Cooper 
195b89a7cc2SEnji Cooper // At this point the test pattern is done.  However, you don't have
196b89a7cc2SEnji Cooper // any real test yet as you haven't said which types you want to run
197b89a7cc2SEnji Cooper // the tests with.
198b89a7cc2SEnji Cooper 
199b89a7cc2SEnji Cooper // To turn the abstract test pattern into real tests, you instantiate
200b89a7cc2SEnji Cooper // it with a list of types.  Usually the test pattern will be defined
201b89a7cc2SEnji Cooper // in a .h file, and anyone can #include and instantiate it.  You can
202b89a7cc2SEnji Cooper // even instantiate it more than once in the same program.  To tell
203b89a7cc2SEnji Cooper // different instances apart, you give each of them a name, which will
204b89a7cc2SEnji Cooper // become part of the test case name and can be used in test filters.
205b89a7cc2SEnji Cooper 
206b89a7cc2SEnji Cooper // The list of types we want to test.  Note that it doesn't have to be
207b89a7cc2SEnji Cooper // defined at the time we write the TYPED_TEST_P()s.
208b89a7cc2SEnji Cooper typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable>
209b89a7cc2SEnji Cooper     PrimeTableImplementations;
210*28f6c2f2SEnji Cooper INSTANTIATE_TYPED_TEST_SUITE_P(OnTheFlyAndPreCalculated,    // Instance name
211b89a7cc2SEnji Cooper                                PrimeTableTest2,             // Test case name
212b89a7cc2SEnji Cooper                                PrimeTableImplementations);  // Type list
213b89a7cc2SEnji Cooper 
214b89a7cc2SEnji Cooper }  // namespace
215