module TestUtil ( module X , Proxy.Proxy(..) , propWithSize , propNumTests , roundTripJSONSpec , safeJSONDeserializeSpec ) where import Test.Hspec as X import Test.Hspec.QuickCheck as X import Test.QuickCheck as X hiding (Result, generate, labels, reason, theException) import Test.QuickCheck.Property as X import Control.DeepSeq import qualified Data.Aeson as Aeson import qualified Data.ByteString as BS import qualified Data.Data as Data import Data.Monoid ((<>)) import qualified Data.Proxy as Proxy import ArbitraryInstances as X import TestData as X propWithSize :: Testable prop => Int -> String -> prop -> Spec propWithSize n tag = modifyMaxSize (const n) . prop tag propNumTests :: Testable prop => Int -> String -> prop -> Spec propNumTests n tag = modifyMaxSuccess (const n) . prop tag -- Serialization Utils roundTripJSONSpec :: (Arbitrary a, Aeson.FromJSON a, Aeson.ToJSON a, Data.Typeable a, Show a, Eq a) => Proxy.Proxy a -> Spec roundTripJSONSpec proxy = prop ("should round-trip json serialize " <> tag) $ testRoundTripJSON proxy where tag = show (Data.typeRep proxy) testRoundTripJSON :: (Aeson.FromJSON a, Aeson.ToJSON a, Show a, Eq a) => Proxy.Proxy a -> a -> Property testRoundTripJSON _ x = Aeson.decode (Aeson.encode x) === Just x safeJSONDeserializeSpec :: (Aeson.FromJSON a, Show a, Data.Typeable a) => Proxy.Proxy a -> Spec safeJSONDeserializeSpec proxy = prop ("should be safe when deserializing " <> tag) $ testSafeJSONDeserialize proxy where tag = show (Data.typeRep proxy) testSafeJSONDeserialize :: forall a. (Aeson.FromJSON a, Show a) => Proxy.Proxy a -> BS.ByteString -> Bool testSafeJSONDeserialize _ bs = canEval $ show (Aeson.decodeStrict' json :: Maybe [a]) where json = mconcat [ "[\"", bs, "\"]" ] canEval :: NFData a => a -> Bool canEval x = deepseq x True