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