content: -- |
  -- Module:      Math.NumberTheory.Primes.TestingTests
  -- Copyright:   (c) 2017 Andrew Lelechenko
  -- Licence:     MIT
  -- Maintainer:  Andrew Lelechenko <andrew.lelechenko@gmail.com>
  --
  -- Tests for Math.NumberTheory.Primes.Testing
  --
  
  {-# OPTIONS_GHC -fno-warn-type-defaults #-}
  
  module Math.NumberTheory.Primes.TestingTests
    ( testSuite
    ) where
  
  import Test.Tasty
  import Test.Tasty.HUnit
  
  import Math.NumberTheory.Primes.Testing
  import Math.NumberTheory.TestUtils
  
  isPrimeProperty1 :: Assertion
  isPrimeProperty1 = assertEqual "[0..100]" expected actual
    where
      expected = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
      actual   = filter isPrime [0..100]
  
  isPrimeProperty2 :: Integer -> Bool
  isPrimeProperty2 n = isPrime n == isPrime (negate n)
  
  isPrimeProperty3 :: Assertion
  isPrimeProperty3 = assertBool "Carmichael pseudoprimes" $ not $ any isPrime pseudoprimes
    where
      -- OEIS A002997
      pseudoprimes = [561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841, 29341, 41041, 46657, 52633, 62745, 63973, 75361, 101101, 115921, 126217, 162401, 172081, 188461, 252601, 278545, 294409, 314821, 334153, 340561, 399001, 410041, 449065, 488881, 512461]
  
  isPrimeProperty4 :: Assertion
  isPrimeProperty4 = assertBool "strong pseudoprimes to base 2" $ not $ any isPrime pseudoprimes
    where
      -- OEIS A001262
      pseudoprimes = [2047, 3277, 4033, 4681, 8321, 15841, 29341, 42799, 49141, 52633, 65281, 74665, 80581, 85489, 88357, 90751, 104653, 130561, 196093, 220729, 233017, 252601, 253241, 256999, 271951, 280601, 314821, 357761, 390937, 458989, 476971, 486737]
  
  isPrimeProperty5 :: Assertion
  isPrimeProperty5 = assertBool "strong Lucas pseudoprimes" $ not $ any isPrime pseudoprimes
    where
      -- OEIS A217255
      pseudoprimes = [5459, 5777, 10877, 16109, 18971, 22499, 24569, 25199, 40309, 58519, 75077, 97439, 100127, 113573, 115639, 130139, 155819, 158399, 161027, 162133, 176399, 176471, 189419, 192509, 197801, 224369, 230691, 231703, 243629, 253259, 268349, 288919, 313499, 324899]
  
  isStrongFermatPPProperty :: NonNegative Integer -> Integer -> Bool
  isStrongFermatPPProperty (NonNegative n) b = not (isPrime n) || isStrongFermatPP n b
  
  testSuite :: TestTree
  testSuite = testGroup "Testing"
    [ testGroup "isPrime"
      [ testCase          "[0..100]"                   isPrimeProperty1
      , testSmallAndQuick "negate"                     isPrimeProperty2
      , testCase          "Carmichael pseudoprimes"    isPrimeProperty3
      , testCase          "strong pseudoprimes base 2" isPrimeProperty4
      , testCase          "strong Lucas pseudoprimes"  isPrimeProperty5
      ]
    , testGroup "isStrongFermatPP"
      [ testSmallAndQuick "matches isPrime" isStrongFermatPPProperty
      ]
    ]
  