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