I'm trying to figure out how to use the smallcheck property-based test library in conjunction with tasty.
I ran into a problem with multi-field record types: How can I make a record type with mor than 4 fields member of the Serial
typeclass?
I assume that this would be the normal way to go:
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
import Test.Tasty
import Test.Tasty.SmallCheck
import Test.SmallCheck.Series
data T1 = T1 { p1 :: Int,
p2 :: Char,
p3 :: [Int]
} deriving (Show, Eq)
instance (Monad m) => Serial m T1 where
series = cons3 T1
main :: IO ()
main = defaultMain tests
tests :: TestTree
tests = testGroup "Tests" [scProps]
scProps = testGroup "(checked by SmallCheck)"
[ testProperty "Test1" prop_test1
]
prop_test1 x y = x == y
where types = (x :: T1, y :: T1)
This works and of course 'Test1' fails. However this approach does not work for record types with more than 4 fields because the consN
function is only defined to take up to 4 parameters. Here's a link to the module Test.SmallCheck.Series
where the function is declared.
For something like:
data T1 = T1 { p1 :: Int,
p2 :: Char,
p3 :: Int,
p4 :: Int,
p5 :: [Int]
} deriving (Show, Eq)
what is the way to add it to Serial
? I tried using generics like this:
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
{-# LANGUAGE DeriveGeneric #-}
import Test.Tasty
import Test.Tasty.SmallCheck
import Test.SmallCheck.Series
import GHC.Generics
data T1 = T1 { p1 :: Int,
p2 :: Char,
p3 :: [Int]
} deriving (Show, Generic)
instance Serial m a => Serial m T1
But ghc refuses to accept the above example with the following message:
Variable occurs more often in a constraint than in the instance head
in the constraint: Serial m a
(Use -XUndecidableInstances to permit this)
In the instance declaration for `Serial m T1'
Many thanks in advance!
jules