nlib
testing/param_value/param_value.cpp
Sample test that uses parameterized values. Describes how to use the TEST_P macro and INSTANCE_TEST_CASE_P( ) macro.
The tests use the Miller-Rabin primality test code and a prime number data array. Prime number data is not explicitly written in the test code. Known prime numbers are written in the sample as array data.
Data is made into parameters to make the test code more compact and to make it easier to add test data.
/*--------------------------------------------------------------------------------*
Project: CrossRoad
Copyright (C)Nintendo All rights reserved.
These coded instructions, statements, and computer programs contain proprietary
information of Nintendo and/or its licensed developers and are protected by
national and international copyright laws. They may not be disclosed to third
parties or copied or duplicated in any form, in whole or in part, without the
prior written consent of Nintendo.
The content herein is highly confidential and should be handled accordingly.
*--------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// define NLIB_USE_GTEST to use googletest
// #define NLIB_USE_GTEST
static uint64_t MyPow(uint64_t base, int power, int mod) {
int result = 1;
while (power > 0) {
if ((power & 1) == 1) result = static_cast<int>((result * base) % mod);
base = (base * base) % mod;
power >>= 1;
}
return result;
}
static bool MillerRabinIsPrime(int n) {
// Miller-Rabin primality test
if (n < 0) n = -n;
if (n == 2) return true;
if (n == 1 || (n & 1) == 0) return false;
int d = n - 1;
while ((d & 1) == 0) d >>= 1;
for (int i = 0; i < 20; ++i) {
double tmp = rand(); // NOLINT
tmp = tmp * (n - 2) / (RAND_MAX);
int a = static_cast<int>(tmp) + 1;
int t = d;
uint64_t y = MyPow(a, t, n);
while (t != n - 1 && y != 1U && y != static_cast<uint64_t>(n - 1)) {
y = (y * y) % n;
t <<= 1;
}
if (y != static_cast<uint64_t>(n - 1) && (t & 1) == 0) return false;
}
return true;
}
class IsPrimeTest : public ::testing::TestWithParam<int> {};
TEST_P(IsPrimeTest, MillerRabinTrue) {
int v = GetParam();
EXPECT_TRUE(MillerRabinIsPrime(v)) << v;
}
TEST_P(IsPrimeTest, MillerRabinFalse) {
int v = GetParam();
if (v < 10000000) {
v = v * 11;
} else {
// too big values will result in overflow....
return;
}
// MillerRabinIsPrime(v) may return true if v is not prime
// because Miller-Rabin primality test is probabilistic algorithm.
EXPECT_FALSE(MillerRabinIsPrime(v)) << v;
}
INSTANTIATE_TEST_CASE_P(Inst, IsPrimeTest,
::testing::Values(11, 13, 661, 1193, 118633, 999961, 24036583));
int lucky_primes[] = {3, 7, 13, 31, 37, 43, 67, 73, 79, 127, 151, 163, 193, 211, 223,
241, 283, 307, 331, 349, 367, 409, 421, 433, 463, 487, 541, 577, 601, 613,
619, 631, 643, 673, 727, 739, 769, 787, 823, 883, 937, 991, 997};
INSTANTIATE_TEST_CASE_P(LuckyPrimes, IsPrimeTest, ::testing::ValuesIn(lucky_primes));
int markov_primes[] = {2, 5, 13, 29, 89, 233,
433, 1597, 2897, 5741, 7561, 28657,
33461, 43261, 96557, 426389, 514229, 1686049,
2922509, 3276509, 94418953, 321534781, 433494437, 780291637};
INSTANTIATE_TEST_CASE_P(MarkovPrimes, IsPrimeTest, ::testing::ValuesIn(markov_primes));
int mersenne_prime_exponents[] = {2, 3, 5, 7, 13, 17, 19,
31, 61, 89, 107, 127, 521, 607,
1279, 2203, 2281, 3217, 4253, 4423, 9689,
9941, 11213, 19937, 21701, 23209, 44497, 86243,
110503, 132049, 216091, 756839, 859433, 1257787, 1398269,
2976221, 3021377, 6972593, 13466917, 20996011, 24036583};
INSTANTIATE_TEST_CASE_P(MersennePrimeExponents, IsPrimeTest,
::testing::ValuesIn(mersenne_prime_exponents));
NLIB_PATHMAPPER_FORSAMPLE
bool SampleMain(int argc, char** argv) {
srand(0);
InitPathMapperForSample();
char path[512];
char buf[512];
size_t count;
g_pathmapper.ResolvePath(&count, path, "nlibpath:///readwrite/param_value.xml");
nlib_snprintf(&count, buf, "xml:%s", path);
::testing::GTEST_FLAG(output) = buf;
// RUN_ALL_TESTS returns 0 if all the tests are successful.
// You can use the return value of main() function.
return RUN_ALL_TESTS() == 0;
}
NLIB_MAINFUNC