hackage-security-0.5.2.0: tests/TestSuite/JSON.hs
{-# OPTIONS_GHC -fno-warn-orphans #-}
module TestSuite.JSON (
prop_roundtrip_canonical,
prop_roundtrip_pretty,
prop_canonical_pretty,
) where
-- stdlib
import Data.Int
import Data.List (sortBy, nubBy)
import Data.Function (on)
import Control.Applicative
import qualified Data.ByteString.Lazy.Char8 as BS
import Test.QuickCheck
-- hackage-security
import Text.JSON.Canonical
prop_roundtrip_canonical, prop_roundtrip_pretty, prop_canonical_pretty
:: JSValue -> Bool
prop_roundtrip_canonical jsval =
parseCanonicalJSON (renderCanonicalJSON jsval) == Right (canonicalise jsval)
prop_roundtrip_pretty jsval =
parseCanonicalJSON (BS.pack (prettyCanonicalJSON jsval)) == Right jsval
prop_canonical_pretty jsval =
parseCanonicalJSON (renderCanonicalJSON jsval) ==
fmap canonicalise (parseCanonicalJSON (BS.pack (prettyCanonicalJSON jsval)))
canonicalise :: JSValue -> JSValue
canonicalise v@JSNull = v
canonicalise v@(JSBool _) = v
canonicalise v@(JSNum _) = v
canonicalise v@(JSString _) = v
canonicalise (JSArray vs) = JSArray [ canonicalise v | v <- vs]
canonicalise (JSObject vs) = JSObject [ (k, canonicalise v)
| (k,v) <- sortBy (compare `on` fst) vs ]
instance Arbitrary JSValue where
arbitrary =
sized $ \sz ->
frequency
[ (1, pure JSNull)
, (1, JSBool <$> arbitrary)
, (2, JSNum <$> arbitrary)
, (2, JSString <$> arbitrary)
, (3, JSArray <$> resize (sz `div` 2) arbitrary)
, (3, JSObject . noDupFields <$> resize (sz `div` 2) arbitrary)
]
where
noDupFields = nubBy (\(x,_) (y,_) -> x==y)
shrink JSNull = []
shrink (JSBool _) = []
shrink (JSNum n) = [ JSNum n' | n' <- shrink n ]
shrink (JSString s) = [ JSString s' | s' <- shrink s ]
shrink (JSArray vs) = [ JSArray vs' | vs' <- shrink vs ]
shrink (JSObject vs) = [ JSObject vs' | vs' <- shrinkList shrinkSnd vs ]
where
shrinkSnd (a,b) = [ (a,b') | b' <- shrink b ]
instance Arbitrary Int54 where
arbitrary = fromIntegral <$>
frequency [ (1, pure lowerbound)
, (1, pure upperbound)
, (8, choose (lowerbound, upperbound))
]
where
upperbound, lowerbound :: Int64
upperbound = 999999999999999 -- 15 decimal digits
lowerbound = (-999999999999999)
shrink = shrinkIntegral