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