{-| Module: Test.Hspec.Multicheck Description: A testing framework based on hspec. Copyright: (c) Marcellus Siegburg, 2017 License: PublicDomain Maintainer: Marcellus Siegburg Stability: Experimental This module imports and reexports Hspec. However, the functions 'it' and 'specify' are changed. Thus, QuickCheck and smallcheck are executed for every test case that is specified using this library. -} {-# OPTIONS_GHC -fno-warn-orphans #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} module Test.Hspec.Multicheck ( module Test.Hspec, (==>), it, property, specify ) where import qualified Test.QuickCheck as QC import qualified Test.SmallCheck as SC import qualified Test.Hspec.SmallCheck as SC import Test.Hspec hiding (it, specify) import qualified Test.Hspec as Hspec import Prelude hiding (length) {-| Creates a spec item for SmallCheck and QuickCheck by calling Hspecs 'Hspec.it' for each within the spec monad. -} it :: (QC.Testable prop, SC.Testable IO prop) => String -> prop -> Spec it descr p = do Hspec.it (descr ++ " (SC)") $ SC.property p Hspec.it (descr ++ " (QC)") $ QC.property p {-| A synonym for 'it'. -} specify :: (QC.Testable prop, SC.Testable IO prop) => String -> prop -> Spec specify = it infixr 0 ==> {-| Implication for properties: Applied using Smallchecks 'SC.==>' and QuickChecks 'QC.==>' and returned as tuple. -} (==>) :: (SC.Testable m prop, QC.Testable prop) => Bool -> prop -> (SC.Property m, QC.Property) cond ==> p = (cond SC.==> p, cond QC.==> p) {-| Converts the given parameter to a tuple of properties. I.e. a Smallcheck 'SC.Property' and a QuickCheck 'QC.Property'. -} property :: (SC.Testable IO prop, QC.Testable prop) => prop -> (SC.Property IO, QC.Property) property p = (SC.property p, QC.property p) instance QC.Testable (SC.Property m, QC.Property) where property (_, p) = QC.property p instance (Monad m, m ~ n) => SC.Testable n (SC.Property m, QC.Property) where test (p, _) = SC.test p