Blame test-suite/Math/NumberTheory/TestUtils.hs

Packit 785658
-- |
Packit 785658
-- Module:      Math.NumberTheory.TestUtils
Packit 785658
-- Copyright:   (c) 2016 Andrew Lelechenko
Packit 785658
-- Licence:     MIT
Packit 785658
-- Maintainer:  Andrew Lelechenko <andrew.lelechenko@gmail.com>
Packit 785658
-- Stability:   Provisional
Packit 785658
-- Portability: Non-portable (GHC extensions)
Packit 785658
--
Packit 785658
Packit 785658
{-# LANGUAGE FlexibleContexts           #-}
Packit 785658
{-# LANGUAGE FlexibleInstances          #-}
Packit 785658
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
Packit 785658
{-# LANGUAGE MultiParamTypeClasses      #-}
Packit 785658
{-# LANGUAGE StandaloneDeriving         #-}
Packit 785658
Packit 785658
{-# OPTIONS_GHC -fno-warn-orphans #-}
Packit 785658
Packit 785658
module Math.NumberTheory.TestUtils
Packit 785658
  ( module Test.SmallCheck.Series
Packit 785658
  , Power (..)
Packit 785658
  , Huge (..)
Packit 785658
  , testSmallAndQuick
Packit 785658
  ) where
Packit 785658
Packit 785658
import Test.SmallCheck.Series (cons2)
Packit 785658
import Test.Tasty
Packit 785658
import Test.Tasty.SmallCheck as SC
Packit 785658
import Test.Tasty.QuickCheck as QC hiding (Positive, NonNegative, generate, getNonNegative)
Packit 785658
import Test.SmallCheck.Series (Positive(..), NonNegative(..), Serial(..), Series, generate)
Packit 785658
Packit 785658
import Control.Applicative
Packit 785658
import Data.Word
Packit 785658
import Numeric.Natural
Packit 785658
Packit 785658
testSmallAndQuick
Packit 785658
  :: SC.Testable IO a
Packit 785658
  => QC.Testable a
Packit 785658
  => String -> a -> TestTree
Packit 785658
testSmallAndQuick name f = testGroup name
Packit 785658
  [ SC.testProperty "smallcheck" f
Packit 785658
  , QC.testProperty "quickcheck" f
Packit 785658
  ]
Packit 785658
Packit 785658
-------------------------------------------------------------------------------
Packit 785658
-- Serial monadic actions
Packit 785658
Packit 785658
instance Monad m => Serial m Word where
Packit 785658
  series =
Packit 785658
    generate (\d -> if d >= 0 then pure 0 else empty) <|> nats
Packit 785658
    where
Packit 785658
      nats = generate $ \d -> if d > 0 then [1 .. fromInteger (toInteger d)] else empty
Packit 785658
Packit 785658
instance Monad m => Serial m Natural where
Packit 785658
  series =
Packit 785658
    generate (\d -> if d >= 0 then pure 0 else empty) <|> nats
Packit 785658
    where
Packit 785658
      nats = generate $ \d -> if d > 0 then [1 .. fromInteger (toInteger d)] else empty
Packit 785658
Packit 785658
-------------------------------------------------------------------------------
Packit 785658
-- Power
Packit 785658
Packit 785658
newtype Power a = Power { getPower :: a }
Packit 785658
  deriving (Eq, Ord, Read, Show, Num, Enum, Bounded, Integral, Real)
Packit 785658
Packit 785658
instance (Monad m, Num a, Ord a, Serial m a) => Serial m (Power a) where
Packit 785658
  series = Power <$> series `suchThatSerial` (> 0)
Packit 785658
Packit 785658
instance (Num a, Ord a, Integral a, Arbitrary a) => Arbitrary (Power a) where
Packit 785658
  arbitrary = Power <$> (getSmall <$> arbitrary) `suchThat` (> 0)
Packit 785658
  shrink (Power x) = Power <$> filter (> 0) (shrink x)
Packit 785658
Packit 785658
suchThatSerial :: Series m a -> (a -> Bool) -> Series m a
Packit 785658
suchThatSerial s p = s >>= \x -> if p x then pure x else empty
Packit 785658
Packit 785658
-------------------------------------------------------------------------------
Packit 785658
-- Huge
Packit 785658
Packit 785658
newtype Huge a = Huge { getHuge :: a }
Packit 785658
  deriving (Eq, Ord, Read, Show, Num, Enum, Bounded, Integral, Real)
Packit 785658
Packit 785658
instance (Num a, Arbitrary a) => Arbitrary (Huge a) where
Packit 785658
  arbitrary = do
Packit 785658
    Positive l <- arbitrary
Packit 785658
    ds <- vector (l :: Int)
Packit 785658
    return $ Huge $ foldl1 (\acc n -> acc * 2^(63 :: Int) + n) ds
Packit 785658
Packit 785658
-- | maps 'Huge' constructor over series
Packit 785658
instance Serial m a => Serial m (Huge a) where
Packit 785658
  series = fmap Huge series
Packit 785658
Packit 785658
-------------------------------------------------------------------------------
Packit 785658
-- Positive from smallcheck
Packit 785658
Packit 785658
instance (Num a, Ord a, Arbitrary a) => Arbitrary (Positive a) where
Packit 785658
  arbitrary = Positive <$> (arbitrary `suchThat` (> 0))
Packit 785658
  shrink (Positive x) = Positive <$> filter (> 0) (shrink x)