dhodovsk / source-git / ghc-aeson

Forked from source-git/ghc-aeson 3 years ago
Clone

Blame tests/Properties.hs

Packit 9a2dfb
{-# LANGUAGE CPP #-}
Packit 9a2dfb
{-# LANGUAGE FlexibleContexts #-} -- For arbitrary Compose
Packit 9a2dfb
{-# LANGUAGE OverloadedStrings #-}
Packit 9a2dfb
{-# LANGUAGE RankNTypes #-}
Packit 9a2dfb
{-# LANGUAGE ScopedTypeVariables #-}
Packit 9a2dfb
Packit 9a2dfb
module Properties (module Properties) where
Packit 9a2dfb
Packit 9a2dfb
import Prelude ()
Packit 9a2dfb
import Prelude.Compat
Packit 9a2dfb
Packit 9a2dfb
import Control.Applicative (Const)
Packit 9a2dfb
import Data.Aeson (eitherDecode, encode)
Packit 9a2dfb
import Data.Aeson.Encoding (encodingToLazyByteString)
Packit 9a2dfb
import Data.Aeson.Internal (IResult(..), formatError, ifromJSON, iparse)
Packit 9a2dfb
import qualified Data.Aeson.Internal as I
Packit 9a2dfb
import Data.Aeson.Parser (value)
Packit 9a2dfb
import Data.Aeson.Types
Packit 9a2dfb
import Data.DList (DList)
Packit 9a2dfb
import Data.Functor.Compose (Compose (..))
Packit 9a2dfb
import Data.HashMap.Strict (HashMap)
Packit 9a2dfb
import Data.Hashable (Hashable)
Packit 9a2dfb
import Data.Int (Int8)
Packit 9a2dfb
import Data.List.NonEmpty (NonEmpty)
Packit 9a2dfb
import Data.Map (Map)
Packit 9a2dfb
import Data.Proxy (Proxy)
Packit 9a2dfb
import Data.Ratio (Ratio)
Packit 9a2dfb
import Data.Semigroup (Option(..))
Packit 9a2dfb
import Data.Sequence (Seq)
Packit 9a2dfb
import Data.Tagged (Tagged)
Packit 9a2dfb
import Data.Time (Day, DiffTime, LocalTime, NominalDiffTime, TimeOfDay, UTCTime, ZonedTime)
Packit 9a2dfb
import Data.Version (Version)
Packit 9a2dfb
import Encoders
Packit 9a2dfb
import Instances ()
Packit 9a2dfb
import Numeric.Natural (Natural)
Packit 9a2dfb
import Test.Framework (Test, testGroup)
Packit 9a2dfb
import Test.Framework.Providers.QuickCheck2 (testProperty)
Packit 9a2dfb
import Test.QuickCheck (Arbitrary(..), Property, Testable, (===), (.&&.), counterexample)
Packit 9a2dfb
import Types
Packit 9a2dfb
import qualified Data.Attoparsec.Lazy as L
Packit 9a2dfb
import qualified Data.ByteString.Lazy.Char8 as L
Packit 9a2dfb
import qualified Data.HashMap.Strict as H
Packit 9a2dfb
import qualified Data.Map as Map
Packit 9a2dfb
import qualified Data.Text as T
Packit 9a2dfb
import qualified Data.Text.Lazy as LT
Packit 9a2dfb
import qualified Data.UUID.Types as UUID
Packit 9a2dfb
import qualified Data.Vector as V
Packit 9a2dfb
Packit 9a2dfb
encodeDouble :: Double -> Double -> Property
Packit 9a2dfb
encodeDouble num denom
Packit 9a2dfb
    | isInfinite d || isNaN d = encode d === "null"
Packit 9a2dfb
    | otherwise               = (read . L.unpack . encode) d === d
Packit 9a2dfb
  where d = num / denom
Packit 9a2dfb
Packit 9a2dfb
encodeInteger :: Integer -> Property
Packit 9a2dfb
encodeInteger i = encode i === L.pack (show i)
Packit 9a2dfb
Packit 9a2dfb
toParseJSON :: (Eq a, Show a) =>
Packit 9a2dfb
               (Value -> Parser a) -> (a -> Value) -> a -> Property
Packit 9a2dfb
toParseJSON parsejson tojson x =
Packit 9a2dfb
    case iparse parsejson . tojson $ x of
Packit 9a2dfb
      IError path msg -> failure "parse" (formatError path msg) x
Packit 9a2dfb
      ISuccess x'     -> x === x'
Packit 9a2dfb
Packit 9a2dfb
toParseJSON1
Packit 9a2dfb
    :: (Eq (f Int), Show (f Int))
Packit 9a2dfb
    => (forall a. LiftParseJSON f a)
Packit 9a2dfb
    -> (forall a. LiftToJSON f a)
Packit 9a2dfb
    -> f Int
Packit 9a2dfb
    -> Property
Packit 9a2dfb
toParseJSON1 parsejson1 tojson1 = toParseJSON parsejson tojson
Packit 9a2dfb
  where
Packit 9a2dfb
    parsejson = parsejson1 parseJSON (listParser parseJSON)
Packit 9a2dfb
    tojson    = tojson1 toJSON (listValue toJSON)
Packit 9a2dfb
Packit 9a2dfb
roundTripEnc :: (FromJSON a, ToJSON a, Show a) =>
Packit 9a2dfb
             (a -> a -> Property) -> a -> a -> Property
Packit 9a2dfb
roundTripEnc eq _ i =
Packit 9a2dfb
    case fmap ifromJSON . L.parse value . encode $ i of
Packit 9a2dfb
      L.Done _ (ISuccess v)      -> v `eq` i
Packit 9a2dfb
      L.Done _ (IError path err) -> failure "fromJSON" (formatError path err) i
Packit 9a2dfb
      L.Fail _ _ err             -> failure "parse" err i
Packit 9a2dfb
Packit 9a2dfb
roundTripNoEnc :: (FromJSON a, ToJSON a, Show a) =>
Packit 9a2dfb
             (a -> a -> Property) -> a -> a -> Property
Packit 9a2dfb
roundTripNoEnc eq _ i =
Packit 9a2dfb
    case ifromJSON . toJSON $ i of
Packit 9a2dfb
      (ISuccess v)      -> v `eq` i
Packit 9a2dfb
      (IError path err) -> failure "fromJSON" (formatError path err) i
Packit 9a2dfb
Packit 9a2dfb
roundTripEq :: (Eq a, FromJSON a, ToJSON a, Show a) => a -> a -> Property
Packit 9a2dfb
roundTripEq x y = roundTripEnc (===) x y .&&. roundTripNoEnc (===) x y
Packit 9a2dfb
Packit 9a2dfb
-- We test keys by encoding HashMap and Map with it
Packit 9a2dfb
roundTripKey
Packit 9a2dfb
    :: (Ord a, Hashable a, FromJSONKey a, ToJSONKey a, Show a)
Packit 9a2dfb
    => a -> HashMap a Int -> Map a Int -> Property
Packit 9a2dfb
roundTripKey _ h m = roundTripEq h h .&&. roundTripEq m m
Packit 9a2dfb
Packit 9a2dfb
infix 4 ==~
Packit 9a2dfb
(==~) :: (ApproxEq a, Show a) => a -> a -> Property
Packit 9a2dfb
x ==~ y =
Packit 9a2dfb
  counterexample (show x ++ " /= " ++ show y) (x =~ y)
Packit 9a2dfb
Packit 9a2dfb
toFromJSON :: (Arbitrary a, Eq a, FromJSON a, ToJSON a, Show a) => a -> Property
Packit 9a2dfb
toFromJSON x = case ifromJSON (toJSON x) of
Packit 9a2dfb
                IError path err -> failure "fromJSON" (formatError path err) x
Packit 9a2dfb
                ISuccess x'     -> x === x'
Packit 9a2dfb
Packit 9a2dfb
modifyFailureProp :: String -> String -> Bool
Packit 9a2dfb
modifyFailureProp orig added =
Packit 9a2dfb
    result == Error (added ++ orig)
Packit 9a2dfb
  where
Packit 9a2dfb
    parser = const $ modifyFailure (added ++) $ fail orig
Packit 9a2dfb
    result :: Result ()
Packit 9a2dfb
    result = parse parser ()
Packit 9a2dfb
Packit 9a2dfb
parserThrowErrorProp :: String -> Property
Packit 9a2dfb
parserThrowErrorProp msg =
Packit 9a2dfb
    result === Error msg
Packit 9a2dfb
  where
Packit 9a2dfb
    parser = const $ parserThrowError [] msg
Packit 9a2dfb
    result :: Result ()
Packit 9a2dfb
    result = parse parser ()
Packit 9a2dfb
Packit 9a2dfb
-- | Tests (also) that we catch the JSONPath and it has elements in the right order.
Packit 9a2dfb
parserCatchErrorProp :: [String] -> String -> Property
Packit 9a2dfb
parserCatchErrorProp path msg =
Packit 9a2dfb
    result === Success ([I.Key "outer", I.Key "inner"] ++ jsonPath, msg)
Packit 9a2dfb
  where
Packit 9a2dfb
    parser = parserCatchError outer (curry pure)
Packit 9a2dfb
Packit 9a2dfb
    outer = inner I. I.Key "outer"
Packit 9a2dfb
    inner = parserThrowError jsonPath msg I. I.Key "inner"
Packit 9a2dfb
Packit 9a2dfb
    result :: Result (I.JSONPath, String)
Packit 9a2dfb
    result = parse (const parser) ()
Packit 9a2dfb
Packit 9a2dfb
    jsonPath = map (I.Key . T.pack) path
Packit 9a2dfb
Packit 9a2dfb
-- | Perform a structural comparison of the results of two encoding
Packit 9a2dfb
-- methods. Compares decoded values to account for HashMap-driven
Packit 9a2dfb
-- variation in JSON object key ordering.
Packit 9a2dfb
sameAs :: (a -> Value) -> (a -> Encoding) -> a -> Property
Packit 9a2dfb
sameAs toVal toEnc v =
Packit 9a2dfb
  counterexample (show s) $
Packit 9a2dfb
    eitherDecode s === Right (toVal v)
Packit 9a2dfb
  where
Packit 9a2dfb
    s = encodingToLazyByteString (toEnc v)
Packit 9a2dfb
Packit 9a2dfb
sameAs1
Packit 9a2dfb
    :: (forall a. LiftToJSON f a)
Packit 9a2dfb
    -> (forall a. LiftToEncoding f a)
Packit 9a2dfb
    -> f Int
Packit 9a2dfb
    -> Property
Packit 9a2dfb
sameAs1 toVal1 toEnc1 v = lhs === rhs
Packit 9a2dfb
  where
Packit 9a2dfb
    rhs = Right $ toVal1 toJSON (listValue toJSON) v
Packit 9a2dfb
    lhs = eitherDecode . encodingToLazyByteString $
Packit 9a2dfb
        toEnc1 toEncoding (listEncoding toEncoding) v
Packit 9a2dfb
Packit 9a2dfb
sameAs1Agree
Packit 9a2dfb
    :: ToJSON a
Packit 9a2dfb
    => (f a -> Encoding)
Packit 9a2dfb
    -> (forall b. LiftToEncoding f b)
Packit 9a2dfb
    -> f a
Packit 9a2dfb
    -> Property
Packit 9a2dfb
sameAs1Agree toEnc toEnc1 v = rhs === lhs
Packit 9a2dfb
  where
Packit 9a2dfb
    rhs = encodingToLazyByteString $ toEnc v
Packit 9a2dfb
    lhs = encodingToLazyByteString $ toEnc1 toEncoding (listEncoding toEncoding) v
Packit 9a2dfb
Packit 9a2dfb
type P6 = Product6 Int Bool String (Approx Double) (Int, Approx Double) ()
Packit 9a2dfb
type S4 = Sum4 Int8 ZonedTime T.Text (Map.Map String Int)
Packit 9a2dfb
Packit 9a2dfb
--------------------------------------------------------------------------------
Packit 9a2dfb
-- Value properties
Packit 9a2dfb
--------------------------------------------------------------------------------
Packit 9a2dfb
Packit 9a2dfb
-- | Add the formatted @Value@ to the printed counterexample when the property
Packit 9a2dfb
-- fails.
Packit 9a2dfb
checkValue :: Testable a => (Value -> a) -> Value -> Property
Packit 9a2dfb
checkValue prop v = counterexample (L.unpack (encode v)) (prop v)
Packit 9a2dfb
Packit 9a2dfb
isString :: Value -> Bool
Packit 9a2dfb
isString (String _) = True
Packit 9a2dfb
isString _          = False
Packit 9a2dfb
Packit 9a2dfb
is2ElemArray :: Value -> Bool
Packit 9a2dfb
is2ElemArray (Array v) = V.length v == 2 && isString (V.head v)
Packit 9a2dfb
is2ElemArray _         = False
Packit 9a2dfb
Packit 9a2dfb
isTaggedObjectValue :: Value -> Bool
Packit 9a2dfb
isTaggedObjectValue (Object obj) = "tag"      `H.member` obj &&
Packit 9a2dfb
                                   "contents" `H.member` obj
Packit 9a2dfb
isTaggedObjectValue _            = False
Packit 9a2dfb
Packit 9a2dfb
isNullaryTaggedObject :: Value -> Bool
Packit 9a2dfb
isNullaryTaggedObject obj = isTaggedObject' obj && isObjectWithSingleField obj
Packit 9a2dfb
Packit 9a2dfb
isTaggedObject :: Value -> Property
Packit 9a2dfb
isTaggedObject = checkValue isTaggedObject'
Packit 9a2dfb
Packit 9a2dfb
isTaggedObject' :: Value -> Bool
Packit 9a2dfb
isTaggedObject' (Object obj) = "tag" `H.member` obj
Packit 9a2dfb
isTaggedObject' _            = False
Packit 9a2dfb
Packit 9a2dfb
isObjectWithSingleField :: Value -> Bool
Packit 9a2dfb
isObjectWithSingleField (Object obj) = H.size obj == 1
Packit 9a2dfb
isObjectWithSingleField _            = False
Packit 9a2dfb
Packit 9a2dfb
-- | is untaggedValue of EitherTextInt
Packit 9a2dfb
isUntaggedValueETI :: Value -> Bool
Packit 9a2dfb
isUntaggedValueETI (String s)
Packit 9a2dfb
    | s == "nonenullary"   = True
Packit 9a2dfb
isUntaggedValueETI (Bool _)   = True
Packit 9a2dfb
isUntaggedValueETI (Number _) = True
Packit 9a2dfb
isUntaggedValueETI (Array a)  = length a == 2
Packit 9a2dfb
isUntaggedValueETI _          = False
Packit 9a2dfb
Packit 9a2dfb
isEmptyArray :: Value -> Property
Packit 9a2dfb
isEmptyArray = checkValue isEmptyArray'
Packit 9a2dfb
Packit 9a2dfb
isEmptyArray' :: Value -> Bool
Packit 9a2dfb
isEmptyArray' = (Array mempty ==)
Packit 9a2dfb
Packit 9a2dfb
Packit 9a2dfb
--------------------------------------------------------------------------------
Packit 9a2dfb
Packit 9a2dfb
Packit 9a2dfb
tests :: Test
Packit 9a2dfb
tests = testGroup "properties" [
Packit 9a2dfb
  testGroup "encode" [
Packit 9a2dfb
      testProperty "encodeDouble" encodeDouble
Packit 9a2dfb
    , testProperty "encodeInteger" encodeInteger
Packit 9a2dfb
    ]
Packit 9a2dfb
  , testGroup "roundTrip" [
Packit 9a2dfb
      testProperty "Bool" $ roundTripEq True
Packit 9a2dfb
    , testProperty "Double" $ roundTripEq (1 :: Approx Double)
Packit 9a2dfb
    , testProperty "Int" $ roundTripEq (1 :: Int)
Packit 9a2dfb
    , testProperty "NonEmpty Char" $ roundTripEq (undefined :: NonEmpty Char)
Packit 9a2dfb
    , testProperty "Integer" $ roundTripEq (1 :: Integer)
Packit 9a2dfb
    , testProperty "String" $ roundTripEq ("" :: String)
Packit 9a2dfb
    , testProperty "Text" $ roundTripEq T.empty
Packit 9a2dfb
    , testProperty "Lazy Text" $ roundTripEq LT.empty
Packit 9a2dfb
    , testProperty "Foo" $ roundTripEq (undefined :: Foo)
Packit 9a2dfb
    , testProperty "Day" $ roundTripEq (undefined :: Day)
Packit 9a2dfb
    , testProperty "BCE Day" $ roundTripEq (undefined :: BCEDay)
Packit 9a2dfb
    , testProperty "DotNetTime" $ roundTripEq (undefined :: Approx DotNetTime)
Packit 9a2dfb
    , testProperty "LocalTime" $ roundTripEq (undefined :: LocalTime)
Packit 9a2dfb
    , testProperty "TimeOfDay" $ roundTripEq (undefined :: TimeOfDay)
Packit 9a2dfb
    , testProperty "UTCTime" $ roundTripEq (undefined :: UTCTime)
Packit 9a2dfb
    , testProperty "ZonedTime" $ roundTripEq (undefined :: ZonedTime)
Packit 9a2dfb
    , testProperty "NominalDiffTime" $ roundTripEq (undefined :: NominalDiffTime)
Packit 9a2dfb
    , testProperty "DiffTime" $ roundTripEq (undefined :: DiffTime)
Packit 9a2dfb
    , testProperty "Version" $ roundTripEq (undefined :: Version)
Packit 9a2dfb
    , testProperty "Natural" $ roundTripEq (undefined :: Natural)
Packit 9a2dfb
    , testProperty "Proxy" $ roundTripEq (undefined :: Proxy Int)
Packit 9a2dfb
    , testProperty "Tagged" $ roundTripEq (undefined :: Tagged Int Char)
Packit 9a2dfb
    , testProperty "Const" $ roundTripEq (undefined :: Const Int Char)
Packit 9a2dfb
    , testProperty "DList" $ roundTripEq (undefined :: DList Int)
Packit 9a2dfb
    , testProperty "Seq" $ roundTripEq (undefined :: Seq Int)
Packit 9a2dfb
    , testProperty "Rational" $ roundTripEq (undefined :: Rational)
Packit 9a2dfb
    , testProperty "Ratio Int" $ roundTripEq (undefined :: Ratio Int)
Packit 9a2dfb
    , testProperty "UUID" $ roundTripEq UUID.nil
Packit 9a2dfb
    , testGroup "functors"
Packit 9a2dfb
      [ testProperty "Identity Char" $ roundTripEq (undefined :: I Int)
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "Identity Char" $ roundTripEq (undefined :: I Char)
Packit 9a2dfb
      , testProperty "Identity [Char]" $ roundTripEq (undefined :: I String)
Packit 9a2dfb
      , testProperty "[Identity Char]" $ roundTripEq (undefined :: [I Char])
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "Compose I  I  Int" $ roundTripEq (undefined :: LogScaled (Compose I  I  Int))
Packit 9a2dfb
      , testProperty "Compose [] I  Int" $ roundTripEq (undefined :: LogScaled (Compose [] I  Int))
Packit 9a2dfb
      , testProperty "Compose I  [] Int" $ roundTripEq (undefined :: LogScaled (Compose I  [] Int))
Packit 9a2dfb
      , testProperty "Compose [] [] Int" $ roundTripEq (undefined :: LogScaled (Compose [] [] Int))
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "Compose I  I  Char" $ roundTripEq (undefined :: LogScaled (Compose I  I  Char))
Packit 9a2dfb
      , testProperty "Compose [] I  Char" $ roundTripEq (undefined :: LogScaled (Compose [] I  Char))
Packit 9a2dfb
      , testProperty "Compose I  [] Char" $ roundTripEq (undefined :: LogScaled (Compose I  [] Char))
Packit 9a2dfb
      , testProperty "Compose [] [] Char" $ roundTripEq (undefined :: LogScaled (Compose [] [] Char))
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "Compose3 I  I  I  Char" $ roundTripEq (undefined :: LogScaled (Compose3 I  I  I  Char))
Packit 9a2dfb
      , testProperty "Compose3 I  [] I  Char" $ roundTripEq (undefined :: LogScaled (Compose3 I  [] I  Char))
Packit 9a2dfb
      , testProperty "Compose3 I  I  [] Char" $ roundTripEq (undefined :: LogScaled (Compose3 I  I  [] Char))
Packit 9a2dfb
      , testProperty "Compose3 I  [] [] Char" $ roundTripEq (undefined :: LogScaled (Compose3 I  [] [] Char))
Packit 9a2dfb
      , testProperty "Compose3 [] I  I  Char" $ roundTripEq (undefined :: LogScaled (Compose3 [] I  I  Char))
Packit 9a2dfb
      , testProperty "Compose3 [] [] I  Char" $ roundTripEq (undefined :: LogScaled (Compose3 [] [] I  Char))
Packit 9a2dfb
      , testProperty "Compose3 [] I  [] Char" $ roundTripEq (undefined :: LogScaled (Compose3 [] I  [] Char))
Packit 9a2dfb
      , testProperty "Compose3 [] [] [] Char" $ roundTripEq (undefined :: LogScaled (Compose3 [] [] [] Char))
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "Compose3' I  I  I  Char" $ roundTripEq (undefined :: LogScaled (Compose3' I  I  I  Char))
Packit 9a2dfb
      , testProperty "Compose3' I  [] I  Char" $ roundTripEq (undefined :: LogScaled (Compose3' I  [] I  Char))
Packit 9a2dfb
      , testProperty "Compose3' I  I  [] Char" $ roundTripEq (undefined :: LogScaled (Compose3' I  I  [] Char))
Packit 9a2dfb
      , testProperty "Compose3' I  [] [] Char" $ roundTripEq (undefined :: LogScaled (Compose3' I  [] [] Char))
Packit 9a2dfb
      , testProperty "Compose3' [] I  I  Char" $ roundTripEq (undefined :: LogScaled (Compose3' [] I  I  Char))
Packit 9a2dfb
      , testProperty "Compose3' [] [] I  Char" $ roundTripEq (undefined :: LogScaled (Compose3' [] [] I  Char))
Packit 9a2dfb
      , testProperty "Compose3' [] I  [] Char" $ roundTripEq (undefined :: LogScaled (Compose3' [] I  [] Char))
Packit 9a2dfb
      , testProperty "Compose3' [] [] [] Char" $ roundTripEq (undefined :: LogScaled (Compose3' [] [] [] Char))
Packit 9a2dfb
      ]
Packit 9a2dfb
    , testGroup "ghcGenerics" [
Packit 9a2dfb
        testProperty "OneConstructor" $ roundTripEq OneConstructor
Packit 9a2dfb
      , testProperty "Product2" $ roundTripEq (undefined :: Product2 Int Bool)
Packit 9a2dfb
      , testProperty "Product6" $ roundTripEq (undefined :: P6)
Packit 9a2dfb
      , testProperty "Sum4" $ roundTripEq (undefined :: S4)
Packit 9a2dfb
      ]
Packit 9a2dfb
    ]
Packit 9a2dfb
  , testGroup "roundTrip Key"
Packit 9a2dfb
    [ testProperty "Bool" $ roundTripKey True
Packit 9a2dfb
    , testProperty "Text" $ roundTripKey (undefined :: T.Text)
Packit 9a2dfb
    , testProperty "String" $ roundTripKey (undefined :: String)
Packit 9a2dfb
    , testProperty "Int" $ roundTripKey (undefined :: Int)
Packit 9a2dfb
    , testProperty "[Text]" $ roundTripKey (undefined :: LogScaled [T.Text])
Packit 9a2dfb
    , testProperty "(Int,Char)" $ roundTripKey (undefined :: (Int,Char))
Packit 9a2dfb
    , testProperty "Integer" $ roundTripKey (undefined :: Integer)
Packit 9a2dfb
    , testProperty "Natural" $ roundTripKey (undefined :: Natural)
Packit 9a2dfb
    , testProperty "Float" $ roundTripKey (undefined :: Float)
Packit 9a2dfb
    , testProperty "Double" $ roundTripKey (undefined :: Double)
Packit 9a2dfb
#if MIN_VERSION_base(4,7,0)
Packit 9a2dfb
    , testProperty "Day" $ roundTripKey (undefined :: Day)
Packit 9a2dfb
    , testProperty "LocalTime" $ roundTripKey (undefined :: LocalTime)
Packit 9a2dfb
    , testProperty "TimeOfDay" $ roundTripKey (undefined :: TimeOfDay)
Packit 9a2dfb
    , testProperty "UTCTime" $ roundTripKey (undefined :: UTCTime)
Packit 9a2dfb
#endif
Packit 9a2dfb
    , testProperty "Version" $ roundTripKey (undefined :: Version)
Packit 9a2dfb
    , testProperty "Lazy Text" $ roundTripKey (undefined :: LT.Text)
Packit 9a2dfb
    , testProperty "UUID" $ roundTripKey UUID.nil
Packit 9a2dfb
    ]
Packit 9a2dfb
  , testGroup "toFromJSON" [
Packit 9a2dfb
      testProperty "Integer" (toFromJSON :: Integer -> Property)
Packit 9a2dfb
    , testProperty "Double" (toFromJSON :: Double -> Property)
Packit 9a2dfb
    , testProperty "Maybe Integer" (toFromJSON :: Maybe Integer -> Property)
Packit 9a2dfb
    , testProperty "Either Integer Double" (toFromJSON :: Either Integer Double -> Property)
Packit 9a2dfb
    , testProperty "Either Integer Integer" (toFromJSON :: Either Integer Integer -> Property)
Packit 9a2dfb
    ]
Packit 9a2dfb
  , testGroup "failure messages" [
Packit 9a2dfb
      testProperty "modify failure" modifyFailureProp
Packit 9a2dfb
    , testProperty "parserThrowError" parserThrowErrorProp
Packit 9a2dfb
    , testProperty "parserCatchError" parserCatchErrorProp
Packit 9a2dfb
    ]
Packit 9a2dfb
  , testGroup "generic" [
Packit 9a2dfb
      testGroup "toJSON" [
Packit 9a2dfb
        testGroup "Nullary" [
Packit 9a2dfb
            testProperty "string" (isString . gNullaryToJSONString)
Packit 9a2dfb
          , testProperty "2ElemArray" (is2ElemArray . gNullaryToJSON2ElemArray)
Packit 9a2dfb
          , testProperty "TaggedObject" (isNullaryTaggedObject . gNullaryToJSONTaggedObject)
Packit 9a2dfb
          , testProperty "ObjectWithSingleField" (isObjectWithSingleField . gNullaryToJSONObjectWithSingleField)
Packit 9a2dfb
          , testGroup "roundTrip" [
Packit 9a2dfb
              testProperty "string" (toParseJSON gNullaryParseJSONString gNullaryToJSONString)
Packit 9a2dfb
            , testProperty "2ElemArray" (toParseJSON gNullaryParseJSON2ElemArray gNullaryToJSON2ElemArray)
Packit 9a2dfb
            , testProperty "TaggedObject" (toParseJSON gNullaryParseJSONTaggedObject gNullaryToJSONTaggedObject)
Packit 9a2dfb
            , testProperty "ObjectWithSingleField" (toParseJSON gNullaryParseJSONObjectWithSingleField gNullaryToJSONObjectWithSingleField)
Packit 9a2dfb
            ]
Packit 9a2dfb
        ]
Packit 9a2dfb
      , testGroup "EitherTextInt" [
Packit 9a2dfb
          testProperty "UntaggedValue" (isUntaggedValueETI . gEitherTextIntToJSONUntaggedValue)
Packit 9a2dfb
        , testProperty "roundtrip" (toParseJSON gEitherTextIntParseJSONUntaggedValue gEitherTextIntToJSONUntaggedValue)
Packit 9a2dfb
        ]
Packit 9a2dfb
      , testGroup "SomeType" [
Packit 9a2dfb
          testProperty "2ElemArray" (is2ElemArray . gSomeTypeToJSON2ElemArray)
Packit 9a2dfb
        , testProperty "TaggedObject" (isTaggedObject . gSomeTypeToJSONTaggedObject)
Packit 9a2dfb
        , testProperty "ObjectWithSingleField" (isObjectWithSingleField . gSomeTypeToJSONObjectWithSingleField)
Packit 9a2dfb
        , testGroup "roundTrip" [
Packit 9a2dfb
            testProperty "2ElemArray" (toParseJSON gSomeTypeParseJSON2ElemArray gSomeTypeToJSON2ElemArray)
Packit 9a2dfb
          , testProperty "TaggedObject" (toParseJSON gSomeTypeParseJSONTaggedObject gSomeTypeToJSONTaggedObject)
Packit 9a2dfb
          , testProperty "ObjectWithSingleField" (toParseJSON gSomeTypeParseJSONObjectWithSingleField gSomeTypeToJSONObjectWithSingleField)
Packit 9a2dfb
Packit 9a2dfb
#if __GLASGOW_HASKELL__ >= 706
Packit 9a2dfb
          , testProperty "2ElemArray unary" (toParseJSON1 gSomeTypeLiftParseJSON2ElemArray gSomeTypeLiftToJSON2ElemArray)
Packit 9a2dfb
          , testProperty "TaggedObject unary" (toParseJSON1 gSomeTypeLiftParseJSONTaggedObject gSomeTypeLiftToJSONTaggedObject)
Packit 9a2dfb
          , testProperty "ObjectWithSingleField unary" (toParseJSON1 gSomeTypeLiftParseJSONObjectWithSingleField gSomeTypeLiftToJSONObjectWithSingleField)
Packit 9a2dfb
#endif
Packit 9a2dfb
          ]
Packit 9a2dfb
        ]
Packit 9a2dfb
      , testGroup "OneConstructor" [
Packit 9a2dfb
          testProperty "default" (isEmptyArray . gOneConstructorToJSONDefault)
Packit 9a2dfb
        , testProperty "Tagged"  (isTaggedObject . gOneConstructorToJSONTagged)
Packit 9a2dfb
        , testGroup "roundTrip" [
Packit 9a2dfb
            testProperty "default" (toParseJSON gOneConstructorParseJSONDefault gOneConstructorToJSONDefault)
Packit 9a2dfb
          , testProperty "Tagged"  (toParseJSON gOneConstructorParseJSONTagged  gOneConstructorToJSONTagged)
Packit 9a2dfb
          ]
Packit 9a2dfb
        ]
Packit 9a2dfb
      , testGroup "OptionField" [
Packit 9a2dfb
          testProperty "like Maybe" $
Packit 9a2dfb
          \x -> gOptionFieldToJSON (OptionField (Option x)) === thMaybeFieldToJSON (MaybeField x)
Packit 9a2dfb
        , testProperty "roundTrip" (toParseJSON gOptionFieldParseJSON gOptionFieldToJSON)
Packit 9a2dfb
        ]
Packit 9a2dfb
      ]
Packit 9a2dfb
    , testGroup "toEncoding" [
Packit 9a2dfb
        testProperty "NullaryString" $
Packit 9a2dfb
        gNullaryToJSONString `sameAs` gNullaryToEncodingString
Packit 9a2dfb
      , testProperty "Nullary2ElemArray" $
Packit 9a2dfb
        gNullaryToJSON2ElemArray `sameAs` gNullaryToEncoding2ElemArray
Packit 9a2dfb
      , testProperty "NullaryTaggedObject" $
Packit 9a2dfb
        gNullaryToJSONTaggedObject `sameAs` gNullaryToEncodingTaggedObject
Packit 9a2dfb
      , testProperty "NullaryObjectWithSingleField" $
Packit 9a2dfb
        gNullaryToJSONObjectWithSingleField `sameAs`
Packit 9a2dfb
        gNullaryToEncodingObjectWithSingleField
Packit 9a2dfb
      -- , testProperty "ApproxUnwrap" $
Packit 9a2dfb
      --   gApproxToJSONUnwrap `sameAs` gApproxToEncodingUnwrap
Packit 9a2dfb
      , testProperty "ApproxDefault" $
Packit 9a2dfb
        gApproxToJSONDefault `sameAs` gApproxToEncodingDefault
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "EitherTextInt UntaggedValue" $
Packit 9a2dfb
        gEitherTextIntToJSONUntaggedValue `sameAs` gEitherTextIntToEncodingUntaggedValue
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "SomeType2ElemArray" $
Packit 9a2dfb
        gSomeTypeToJSON2ElemArray `sameAs` gSomeTypeToEncoding2ElemArray
Packit 9a2dfb
#if __GLASGOW_HASKELL__ >= 706
Packit 9a2dfb
      , testProperty "SomeType2ElemArray unary" $
Packit 9a2dfb
        gSomeTypeLiftToJSON2ElemArray `sameAs1` gSomeTypeLiftToEncoding2ElemArray
Packit 9a2dfb
      , testProperty "SomeType2ElemArray unary agree" $
Packit 9a2dfb
        gSomeTypeToEncoding2ElemArray `sameAs1Agree` gSomeTypeLiftToEncoding2ElemArray
Packit 9a2dfb
#endif
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "SomeTypeTaggedObject" $
Packit 9a2dfb
        gSomeTypeToJSONTaggedObject `sameAs` gSomeTypeToEncodingTaggedObject
Packit 9a2dfb
#if __GLASGOW_HASKELL__ >= 706
Packit 9a2dfb
      , testProperty "SomeTypeTaggedObject unary" $
Packit 9a2dfb
        gSomeTypeLiftToJSONTaggedObject `sameAs1` gSomeTypeLiftToEncodingTaggedObject
Packit 9a2dfb
      , testProperty "SomeTypeTaggedObject unary agree" $
Packit 9a2dfb
        gSomeTypeToEncodingTaggedObject `sameAs1Agree` gSomeTypeLiftToEncodingTaggedObject
Packit 9a2dfb
#endif
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "SomeTypeObjectWithSingleField" $
Packit 9a2dfb
        gSomeTypeToJSONObjectWithSingleField `sameAs` gSomeTypeToEncodingObjectWithSingleField
Packit 9a2dfb
#if __GLASGOW_HASKELL__ >= 706
Packit 9a2dfb
      , testProperty "SomeTypeObjectWithSingleField unary" $
Packit 9a2dfb
        gSomeTypeLiftToJSONObjectWithSingleField `sameAs1` gSomeTypeLiftToEncodingObjectWithSingleField
Packit 9a2dfb
      , testProperty "SomeTypeObjectWithSingleField unary agree" $
Packit 9a2dfb
        gSomeTypeToEncodingObjectWithSingleField `sameAs1Agree` gSomeTypeLiftToEncodingObjectWithSingleField
Packit 9a2dfb
#endif
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "SomeTypeOmitNothingFields" $
Packit 9a2dfb
        gSomeTypeToJSONOmitNothingFields `sameAs` gSomeTypeToEncodingOmitNothingFields
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "OneConstructorDefault" $
Packit 9a2dfb
        gOneConstructorToJSONDefault `sameAs` gOneConstructorToEncodingDefault
Packit 9a2dfb
      , testProperty "OneConstructorTagged" $
Packit 9a2dfb
        gOneConstructorToJSONTagged `sameAs` gOneConstructorToEncodingTagged
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "OptionField" $
Packit 9a2dfb
        gOptionFieldToJSON `sameAs` gOptionFieldToEncoding
Packit 9a2dfb
      ]
Packit 9a2dfb
    ]
Packit 9a2dfb
  , testGroup "template-haskell" [
Packit 9a2dfb
      testGroup "toJSON" [
Packit 9a2dfb
        testGroup "Nullary" [
Packit 9a2dfb
            testProperty "string" (isString . thNullaryToJSONString)
Packit 9a2dfb
          , testProperty "2ElemArray" (is2ElemArray . thNullaryToJSON2ElemArray)
Packit 9a2dfb
          , testProperty "TaggedObject" (isNullaryTaggedObject . thNullaryToJSONTaggedObject)
Packit 9a2dfb
          , testProperty "ObjectWithSingleField" (isObjectWithSingleField . thNullaryToJSONObjectWithSingleField)
Packit 9a2dfb
Packit 9a2dfb
          , testGroup "roundTrip" [
Packit 9a2dfb
              testProperty "string" (toParseJSON thNullaryParseJSONString thNullaryToJSONString)
Packit 9a2dfb
            , testProperty "2ElemArray" (toParseJSON thNullaryParseJSON2ElemArray thNullaryToJSON2ElemArray)
Packit 9a2dfb
            , testProperty "TaggedObject" (toParseJSON thNullaryParseJSONTaggedObject thNullaryToJSONTaggedObject)
Packit 9a2dfb
            , testProperty "ObjectWithSingleField" (toParseJSON thNullaryParseJSONObjectWithSingleField thNullaryToJSONObjectWithSingleField)
Packit 9a2dfb
            ]
Packit 9a2dfb
        ]
Packit 9a2dfb
      , testGroup "EitherTextInt" [
Packit 9a2dfb
          testProperty "UntaggedValue" (isUntaggedValueETI . thEitherTextIntToJSONUntaggedValue)
Packit 9a2dfb
        , testProperty "roundtrip" (toParseJSON thEitherTextIntParseJSONUntaggedValue thEitherTextIntToJSONUntaggedValue)
Packit 9a2dfb
        ]
Packit 9a2dfb
      , testGroup "SomeType" [
Packit 9a2dfb
          testProperty "2ElemArray" (is2ElemArray . thSomeTypeToJSON2ElemArray)
Packit 9a2dfb
        , testProperty "TaggedObject" (isTaggedObject . thSomeTypeToJSONTaggedObject)
Packit 9a2dfb
        , testProperty "ObjectWithSingleField" (isObjectWithSingleField . thSomeTypeToJSONObjectWithSingleField)
Packit 9a2dfb
        , testGroup "roundTrip" [
Packit 9a2dfb
            testProperty "2ElemArray" (toParseJSON thSomeTypeParseJSON2ElemArray thSomeTypeToJSON2ElemArray)
Packit 9a2dfb
          , testProperty "TaggedObject" (toParseJSON thSomeTypeParseJSONTaggedObject thSomeTypeToJSONTaggedObject)
Packit 9a2dfb
          , testProperty "ObjectWithSingleField" (toParseJSON thSomeTypeParseJSONObjectWithSingleField thSomeTypeToJSONObjectWithSingleField)
Packit 9a2dfb
Packit 9a2dfb
          , testProperty "2ElemArray unary" (toParseJSON1 thSomeTypeLiftParseJSON2ElemArray thSomeTypeLiftToJSON2ElemArray)
Packit 9a2dfb
          , testProperty "TaggedObject unary" (toParseJSON1 thSomeTypeLiftParseJSONTaggedObject thSomeTypeLiftToJSONTaggedObject)
Packit 9a2dfb
          , testProperty "ObjectWithSingleField unary" (toParseJSON1 thSomeTypeLiftParseJSONObjectWithSingleField thSomeTypeLiftToJSONObjectWithSingleField)
Packit 9a2dfb
Packit 9a2dfb
          ]
Packit 9a2dfb
        ]
Packit 9a2dfb
      , testGroup "Approx" [
Packit 9a2dfb
          testProperty "string"                (isString                . thApproxToJSONUnwrap)
Packit 9a2dfb
        , testProperty "ObjectWithSingleField" (isObjectWithSingleField . thApproxToJSONDefault)
Packit 9a2dfb
        , testGroup "roundTrip" [
Packit 9a2dfb
            testProperty "string"                (toParseJSON thApproxParseJSONUnwrap  thApproxToJSONUnwrap)
Packit 9a2dfb
          , testProperty "ObjectWithSingleField" (toParseJSON thApproxParseJSONDefault thApproxToJSONDefault)
Packit 9a2dfb
          ]
Packit 9a2dfb
        ]
Packit 9a2dfb
      , testGroup "GADT" [
Packit 9a2dfb
          testProperty "string"                (isString                . thGADTToJSONUnwrap)
Packit 9a2dfb
        , testProperty "ObjectWithSingleField" (isObjectWithSingleField . thGADTToJSONDefault)
Packit 9a2dfb
        , testGroup "roundTrip" [
Packit 9a2dfb
            testProperty "string"                (toParseJSON thGADTParseJSONUnwrap  thGADTToJSONUnwrap)
Packit 9a2dfb
          , testProperty "ObjectWithSingleField" (toParseJSON thGADTParseJSONDefault thGADTToJSONDefault)
Packit 9a2dfb
          ]
Packit 9a2dfb
        ]
Packit 9a2dfb
      , testGroup "OneConstructor" [
Packit 9a2dfb
          testProperty "default" (isEmptyArray . thOneConstructorToJSONDefault)
Packit 9a2dfb
        , testProperty "Tagged"  (isTaggedObject . thOneConstructorToJSONTagged)
Packit 9a2dfb
        , testGroup "roundTrip" [
Packit 9a2dfb
            testProperty "default" (toParseJSON thOneConstructorParseJSONDefault thOneConstructorToJSONDefault)
Packit 9a2dfb
          , testProperty "Tagged"  (toParseJSON thOneConstructorParseJSONTagged  thOneConstructorToJSONTagged)
Packit 9a2dfb
          ]
Packit 9a2dfb
        ]
Packit 9a2dfb
      , testGroup "OptionField" [
Packit 9a2dfb
          testProperty "like Maybe" $
Packit 9a2dfb
          \x -> thOptionFieldToJSON (OptionField (Option x)) === thMaybeFieldToJSON (MaybeField x)
Packit 9a2dfb
        , testProperty "roundTrip" (toParseJSON thOptionFieldParseJSON thOptionFieldToJSON)
Packit 9a2dfb
        ]
Packit 9a2dfb
      ]
Packit 9a2dfb
    , testGroup "toEncoding" [
Packit 9a2dfb
        testProperty "NullaryString" $
Packit 9a2dfb
        thNullaryToJSONString `sameAs` thNullaryToEncodingString
Packit 9a2dfb
      , testProperty "Nullary2ElemArray" $
Packit 9a2dfb
        thNullaryToJSON2ElemArray `sameAs` thNullaryToEncoding2ElemArray
Packit 9a2dfb
      , testProperty "NullaryTaggedObject" $
Packit 9a2dfb
        thNullaryToJSONTaggedObject `sameAs` thNullaryToEncodingTaggedObject
Packit 9a2dfb
      , testProperty "NullaryObjectWithSingleField" $
Packit 9a2dfb
        thNullaryToJSONObjectWithSingleField `sameAs`
Packit 9a2dfb
        thNullaryToEncodingObjectWithSingleField
Packit 9a2dfb
      , testProperty "ApproxUnwrap" $
Packit 9a2dfb
        thApproxToJSONUnwrap `sameAs` thApproxToEncodingUnwrap
Packit 9a2dfb
      , testProperty "ApproxDefault" $
Packit 9a2dfb
        thApproxToJSONDefault `sameAs` thApproxToEncodingDefault
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "EitherTextInt UntaggedValue" $
Packit 9a2dfb
        thEitherTextIntToJSONUntaggedValue `sameAs` thEitherTextIntToEncodingUntaggedValue
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "SomeType2ElemArray" $
Packit 9a2dfb
        thSomeTypeToJSON2ElemArray `sameAs` thSomeTypeToEncoding2ElemArray
Packit 9a2dfb
      , testProperty "SomeType2ElemArray unary" $
Packit 9a2dfb
        thSomeTypeLiftToJSON2ElemArray `sameAs1` thSomeTypeLiftToEncoding2ElemArray
Packit 9a2dfb
      , testProperty "SomeType2ElemArray unary agree" $
Packit 9a2dfb
        thSomeTypeToEncoding2ElemArray `sameAs1Agree` thSomeTypeLiftToEncoding2ElemArray
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "SomeTypeTaggedObject" $
Packit 9a2dfb
        thSomeTypeToJSONTaggedObject `sameAs` thSomeTypeToEncodingTaggedObject
Packit 9a2dfb
      , testProperty "SomeTypeTaggedObject unary" $
Packit 9a2dfb
        thSomeTypeLiftToJSONTaggedObject `sameAs1` thSomeTypeLiftToEncodingTaggedObject
Packit 9a2dfb
      , testProperty "SomeTypeTaggedObject unary agree" $
Packit 9a2dfb
        thSomeTypeToEncodingTaggedObject `sameAs1Agree` thSomeTypeLiftToEncodingTaggedObject
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "SomeTypeObjectWithSingleField" $
Packit 9a2dfb
        thSomeTypeToJSONObjectWithSingleField `sameAs` thSomeTypeToEncodingObjectWithSingleField
Packit 9a2dfb
      , testProperty "SomeTypeObjectWithSingleField unary" $
Packit 9a2dfb
        thSomeTypeLiftToJSONObjectWithSingleField `sameAs1` thSomeTypeLiftToEncodingObjectWithSingleField
Packit 9a2dfb
      , testProperty "SomeTypeObjectWithSingleField unary agree" $
Packit 9a2dfb
        thSomeTypeToEncodingObjectWithSingleField `sameAs1Agree` thSomeTypeLiftToEncodingObjectWithSingleField
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "OneConstructorDefault" $
Packit 9a2dfb
        thOneConstructorToJSONDefault `sameAs` thOneConstructorToEncodingDefault
Packit 9a2dfb
      , testProperty "OneConstructorTagged" $
Packit 9a2dfb
        thOneConstructorToJSONTagged `sameAs` thOneConstructorToEncodingTagged
Packit 9a2dfb
Packit 9a2dfb
      , testProperty "OptionField" $
Packit 9a2dfb
        thOptionFieldToJSON `sameAs` thOptionFieldToEncoding
Packit 9a2dfb
      ]
Packit 9a2dfb
    ]
Packit 9a2dfb
  ]