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