1dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Copyright 2008 Google Inc.
2dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// All Rights Reserved.
3dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
4dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Redistribution and use in source and binary forms, with or without
5dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// modification, are permitted provided that the following conditions are
6dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// met:
7dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
8dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//     * Redistributions of source code must retain the above copyright
9dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// notice, this list of conditions and the following disclaimer.
10dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//     * Redistributions in binary form must reproduce the above
11dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// copyright notice, this list of conditions and the following disclaimer
12dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// in the documentation and/or other materials provided with the
13dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// distribution.
14dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//     * Neither the name of Google Inc. nor the names of its
15dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// contributors may be used to endorse or promote products derived from
16dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// this software without specific prior written permission.
17dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
18dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
30dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Author: vladl@google.com (Vlad Losev)
31dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
32dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// This sample shows how to test code relying on some global flag variables.
33dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Combine() helps with generating all possible combinations of such flags,
34dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// and each test is given one combination as a parameter.
35dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
36dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Use class definitions to test from this header.
37dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#include "prime_tables.h"
38dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
3946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan#include "gtest/gtest.h"
40dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
41dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#if GTEST_HAS_COMBINE
42dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
43dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Suppose we want to introduce a new, improved implementation of PrimeTable
44dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// which combines speed of PrecalcPrimeTable and versatility of
45dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// OnTheFlyPrimeTable (see prime_tables.h). Inside it instantiates both
46dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// PrecalcPrimeTable and OnTheFlyPrimeTable and uses the one that is more
47dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// appropriate under the circumstances. But in low memory conditions, it can be
48dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// told to instantiate without PrecalcPrimeTable instance at all and use only
49dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// OnTheFlyPrimeTable.
50dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterclass HybridPrimeTable : public PrimeTable {
51dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter public:
52dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  HybridPrimeTable(bool force_on_the_fly, int max_precalculated)
53dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      : on_the_fly_impl_(new OnTheFlyPrimeTable),
54dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter        precalc_impl_(force_on_the_fly ? NULL :
55dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter                          new PreCalculatedPrimeTable(max_precalculated)),
56dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter        max_precalculated_(max_precalculated) {}
57dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  virtual ~HybridPrimeTable() {
58dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    delete on_the_fly_impl_;
59dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    delete precalc_impl_;
60dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
61dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
62dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  virtual bool IsPrime(int n) const {
63dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    if (precalc_impl_ != NULL && n < max_precalculated_)
64dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      return precalc_impl_->IsPrime(n);
65dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    else
66dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      return on_the_fly_impl_->IsPrime(n);
67dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
68dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
69dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  virtual int GetNextPrime(int p) const {
70dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    int next_prime = -1;
71dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    if (precalc_impl_ != NULL && p < max_precalculated_)
72dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter      next_prime = precalc_impl_->GetNextPrime(p);
73dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
74dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p);
75dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
76dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
77dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter private:
78dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  OnTheFlyPrimeTable* on_the_fly_impl_;
79dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  PreCalculatedPrimeTable* precalc_impl_;
80dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  int max_precalculated_;
81dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter};
82dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
83dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterusing ::testing::TestWithParam;
84dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterusing ::testing::Bool;
85dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterusing ::testing::Values;
86dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterusing ::testing::Combine;
87dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
88dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// To test all code paths for HybridPrimeTable we must test it with numbers
89dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// both within and outside PreCalculatedPrimeTable's capacity and also with
90dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// PreCalculatedPrimeTable disabled. We do this by defining fixture which will
91dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// accept different combinations of parameters for instantiating a
92dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// HybridPrimeTable instance.
93dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixterclass PrimeTableTest : public TestWithParam< ::std::tr1::tuple<bool, int> > {
94dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter protected:
95dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  virtual void SetUp() {
96dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    // This can be written as
97dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    //
98dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    // bool force_on_the_fly;
99dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    // int max_precalculated;
100dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    // tie(force_on_the_fly, max_precalculated) = GetParam();
101dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    //
102dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    // once the Google C++ Style Guide allows use of ::std::tr1::tie.
103dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    //
104dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    bool force_on_the_fly = ::std::tr1::get<0>(GetParam());
105dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    int max_precalculated = ::std::tr1::get<1>(GetParam());
106dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated);
107dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
108dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  virtual void TearDown() {
109dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    delete table_;
110dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter    table_ = NULL;
111dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  }
112dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  HybridPrimeTable* table_;
113dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter};
114dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
115dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterTEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) {
116dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Inside the test body, you can refer to the test parameter by GetParam().
117dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // In this case, the test parameter is a PrimeTable interface pointer which
118dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // we can use directly.
119dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // Please note that you can also save it in the fixture's SetUp() method
120dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  // or constructor and use saved copy in the tests.
121dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
122dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_FALSE(table_->IsPrime(-5));
123dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_FALSE(table_->IsPrime(0));
124dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_FALSE(table_->IsPrime(1));
125dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_FALSE(table_->IsPrime(4));
126dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_FALSE(table_->IsPrime(6));
127dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_FALSE(table_->IsPrime(100));
128dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter}
129dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
130dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterTEST_P(PrimeTableTest, ReturnsTrueForPrimes) {
131dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_TRUE(table_->IsPrime(2));
132dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_TRUE(table_->IsPrime(3));
133dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_TRUE(table_->IsPrime(5));
134dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_TRUE(table_->IsPrime(7));
135dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_TRUE(table_->IsPrime(11));
136dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_TRUE(table_->IsPrime(131));
137dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter}
138dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
139dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterTEST_P(PrimeTableTest, CanGetNextPrime) {
140dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_EQ(2, table_->GetNextPrime(0));
141dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_EQ(3, table_->GetNextPrime(2));
142dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_EQ(5, table_->GetNextPrime(3));
143dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_EQ(7, table_->GetNextPrime(5));
144dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_EQ(11, table_->GetNextPrime(7));
145dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter  EXPECT_EQ(131, table_->GetNextPrime(128));
146dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter}
147dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
148dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// In order to run value-parameterized tests, you need to instantiate them,
149dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// or bind them to a list of values which will be used as test parameters.
150dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// You can instantiate them in a different translation module, or even
151dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// instantiate them several times.
152dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter//
153dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// Here, we instantiate our tests with a list of parameters. We must combine
154dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// all variations of the boolean flag suppressing PrecalcPrimeTable and some
155dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// meaningful values for tests. We choose a small value (1), and a value that
156dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// will put some of the tested numbers beyond the capability of the
157dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// PrecalcPrimeTable instance and some inside it (10). Combine will produce all
158dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter// possible combinations.
159dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterINSTANTIATE_TEST_CASE_P(MeaningfulTestParameters,
160dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter                        PrimeTableTest,
161dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter                        Combine(Bool(), Values(1, 10)));
162dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
163dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#else
164dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
16546108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan// Google Test may not support Combine() with some compilers. If we
16646108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan// use conditional compilation to compile out all code referring to
16746108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan// the gtest_main library, MSVC linker will not link that library at
16846108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan// all and consequently complain about missing entry point defined in
16946108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan// that library (fatal error LNK1561: entry point must be
17046108a219a4b812dd8f36fee479a0340ea5963f5Ben Chan// defined). This dummy test keeps gtest_main linked in.
171dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken MixterTEST(DummyTest, CombineIsNotSupportedOnThisPlatform) {}
172dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter
173dd1c93d5709e32713961cfd95fe30489a4ad2d26Ken Mixter#endif  // GTEST_HAS_COMBINE
174