andrewthad / quickcheck-classes

Quickcheck Properties for common typeclasses
34 stars 9 forks source link

add examples of use with test frameworks like tasty, hspec, etc. #23

Open chessai opened 6 years ago

chessai commented 6 years ago

These examples shouldn't need to be large but will be useful in showing people what something like 'lawsToTest' (found in the test suite for primitive) looks like

andrewthad commented 6 years ago

Agreed. It would be good to provide example of how to use this with test frameworks.

chessai commented 5 years ago

i haven't used this with hspec, but i typically use the following with tasty:

{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeApplications #-}

import Data.Monoid (Sum)
import Data.Map (Map)
import Test.QuickCheck.Classes (Laws(Laws))
import Test.QuickCheck (Property)
import qualified Test.Tasty.QuickCheck as TQC
import Test.Tasty (TestName, TestTree, defaultMain, testGroup)

import qualified Test.QuickCheck.Classes as QCC

main = do
  let pInt = Proxy @Int
  let pSumInt = Proxy @(Sum Int)
  let pMapInt = Proxy @(Map Int)
  let pMapIntInt = Proxy @(Map Int Int)
  defaultMain $ testGroup "properties"
    [ lawsToTest "Int" (mkLaws pInt [QCC.eqLaws, QCC.ordLaws])
    , lawsToTest "Sum Int" (mkLaws pSumInt [QCC.monoidLaws])
    , lawsToTest "Map Int" (mkLaws pMapInt [QCC.functorLaws])
    , lawsToTest "Map Int Int" (mkLaws pMapIntInt [QCC.monoidLaws, QCC.isListLaws])
    ]

mkLaws :: Proxy (a :: k) -> [Proxy a -> Laws] -> [Laws]
mkLaws p fs = map ($ p) fs

pairsToTestTree :: [(String, Property)] -> [TestTree]
pairsToTestTree pairs = map (uncurry TQC.testProperty) pairs

lawsToTest :: TestName -> [Laws] -> TestTree
lawsToTest testName laws = testGroup testName (map lawToTest laws)

lawToTest :: Laws -> TestTree
lawToTest (Laws name pairs) = testGroup name (pairsToTestTree pairs)