QuickCheck: testing every item in the final set

I'm looking for a way to test a function on a deterministic set of values ​​always (not a randomly selected value from a list). For example, I would like to check that

f :: (Num a) => a -> Bool
f x = (x - 2) == (x-3+1)

      

runs for exactly Int

1, 3 and 5, without explicit writing

testGroup "f tests" $ map (testProperty . property) [f (1::Int), f (3::Int), f (5::Int)]

      

Instead, I want to have some type of wrapper around Int

so that when f

this type is called , it tests f

with values ​​1,3 and 5 each time.

The motivation for this is this answer for testing polymorphic functions.

I came up with a solution using my own instance for Arbitrary [Some c]

:

data Some c where
  Some :: (Show a, Arbitrary a, c a) => a -> Some c

instance Arbitrary [Dict c] => Arbitrary [Some c] where
  arbitrary = do
    dicts  :: [Dict c] <- arbitrary
    sequence $ map (\(Dict (Proxy::Proxy a)) -> liftM Some (arbitrary :: Gen a)) dicts


data Dict c where
  Dict :: (Show a, Arbitrary a, c a)
        => Proxy a -> Dict c

class ClassToTest a
  -- where ...    

instance Arbitrary [Dict ClassToTest] where
  arbitrary = return $ [Dict (Proxy::Proxy TYPE1),
                        Dict (Proxy::Proxy TYPE2)]

testAll :: forall a . (Arbitrary [a]) => (a -> Bool) -> Gen Bool
testAll f = do
  xs' <- arbitrary :: Gen [a]
  return $ and $ map f xs'

      

Then I could write a function

myTest :: (ClassToTest a) => a -> Bool
myTest x = error ""

theTest :: Test
theTest = testProperty "mytest" $ testAll myTest

      

which generates a random value TYPE1

and runs myTest

, then generates a random value for TYPE2

and runs again myTest

. The idea is that the TYPE * list is very large, so I would rather not rely on random selection to check that everything in the list is checked. The problem with my approach is that QuickCheck already has a shared instance for (Arbitrary a) => Arbitrary [a]

, so this code requires -XOverlappingInstances

. Is there a better way?

+3


source to share





All Articles