{-# LANGUAGE DerivingVia #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- | -- Copyright: © 2022–2023 Jonathan Knowles -- License: Apache-2.0 -- module ClassSpec where import Data.Bifunctor ( bimap ) import Data.Monoid ( Product (..), Sum (..) ) import Data.Ratio ( denominator, numerator, (%) ) import Test.Hspec ( Spec ) import Test.Hspec.Laws ( testLawsMany ) import Test.QuickCheck ( Arbitrary (..), NonZero (..), Property, choose, oneof ) import Test.QuickCheck.Classes ( Laws (..) ) import Test.QuickCheck.Classes.Group ( abelianLaws, groupLaws ) import Test.QuickCheck.Property ( Result (..), mapTotalResult ) spec :: Spec spec = do testLawsMany @() $ disableCoverageCheck [ abelianLaws , groupLaws ] testLawsMany @(Sum TestInteger) [ abelianLaws , groupLaws ] testLawsMany @(Product TestRational) [ abelianLaws , groupLaws ] testLawsMany @(Sum TestRational) [ abelianLaws , groupLaws ] -------------------------------------------------------------------------------- -- Test types -------------------------------------------------------------------------------- newtype TestInteger = TestInteger Integer deriving stock (Eq, Show) deriving newtype Num instance Arbitrary TestInteger where arbitrary = TestInteger <$> choose (-4, 4) shrink (TestInteger i) = TestInteger <$> shrink i newtype TestRational = TestRational Rational deriving stock (Eq, Show) deriving newtype (Num, Fractional) instance Arbitrary TestRational where arbitrary = fmap TestRational $ (%) <$> genSmall <*> genSmall where genSmall = oneof [choose (-4, -1), choose (1, 4)] shrink (TestRational r) = TestRational . uncurry (%) . bimap getNonZero getNonZero <$> shrink (NonZero (numerator r), NonZero (denominator r)) -------------------------------------------------------------------------------- -- Coverage checks -------------------------------------------------------------------------------- class HasCoverageCheck p where disableCoverageCheck :: p -> p instance HasCoverageCheck Laws where disableCoverageCheck (Laws title laws) = Laws title $ fmap disableCoverageCheck <$> laws instance HasCoverageCheck Property where disableCoverageCheck = mapTotalResult (\r -> r {maybeCheckCoverage = Nothing}) instance (Functor f, HasCoverageCheck p) => HasCoverageCheck (f p) where disableCoverageCheck = fmap disableCoverageCheck