lsm-tree-1.0.0.0: test/Test/Util/Arbitrary.hs
module Test.Util.Arbitrary (
prop_arbitraryAndShrinkPreserveInvariant
, prop_forAllArbitraryAndShrinkPreserveInvariant
, deepseqInvariant
, noInvariant
, noTags
) where
import Control.DeepSeq (NFData, deepseq)
import Database.LSMTree.Extras (showPowersOf10)
import Test.QuickCheck
import Test.Tasty (TestTree)
import Test.Tasty.QuickCheck (testProperty)
prop_arbitraryAndShrinkPreserveInvariant ::
forall a prop. (Arbitrary a, Show a, Testable prop)
=> (a -> Property -> Property) -> (a -> prop) -> [TestTree]
prop_arbitraryAndShrinkPreserveInvariant tag =
prop_forAllArbitraryAndShrinkPreserveInvariant tag arbitrary shrink
prop_forAllArbitraryAndShrinkPreserveInvariant ::
forall a prop. (Show a, Testable prop)
=> (a -> Property -> Property) -> Gen a -> (a -> [a]) -> (a -> prop) -> [TestTree]
prop_forAllArbitraryAndShrinkPreserveInvariant tag gen shr inv =
[ testProperty "Arbitrary satisfies invariant" $
forAllShrink gen shr $ \x ->
tag x $ property $ inv x
, testProperty "Shrinking satisfies invariant" $
-- We don't use forallShrink here. If this property fails, it means that
-- the shrinker is broken, so we don't want to rely on it.
forAll gen $ \x ->
case shr x of
[] -> label "no shrinks" $ property True
xs -> tabulate "number of shrinks" [showPowersOf10 (length xs)] $
forAll (elements xs) inv -- TODO: check more than one?
]
-- | Trivial invariant, but checks that the value is finite
deepseqInvariant :: NFData a => a -> Bool
deepseqInvariant x = x `deepseq` True
noInvariant :: a -> Bool
noInvariant _ = True
noTags :: a -> Property -> Property
noTags _ = id