{-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE RankNTypes #-} module Json where import Data.Aeson ( decode, encode, FromJSON, ToJSON ) import Data.EnumSet ( EnumSet) import Data.EnumMap ( EnumMap) import qualified Data.EnumSet as ES import qualified Data.EnumMap as EM import Test.HUnit ( Assertion, (@?=) ) import GHC.Generics (Generic) import Test.QuickCheck ( Property, (===)) data Creature = Cat | Dog | Fish | Wolf deriving stock (Eq, Show, Enum, Ord, Generic) deriving anyclass (ToJSON, FromJSON) creature :: [Creature] creature = [Cat, Dog, Fish, Dog] creature2 :: [Creature] creature2 = [Cat, Wolf] creatureM :: [(Creature,String)] creatureM = [(Cat,"C"), (Dog,"D")] creatureMRev :: [(Creature,String)] creatureMRev = [(Dog,"D"), (Cat,"C")] creatureMDup :: [(Creature, String)] creatureMDup = [(Cat,"C"), (Dog,"D"),(Dog,"DD")] test_encode_set :: Assertion test_encode_set = do encode (ES.fromList creature) @?= "[0,1,2]" encode (ES.fromList creature2) @?= "[0,3]" test_decode_set :: Assertion test_decode_set = do decode "[0,1,2]" @?= (Just (ES.fromList creature) :: Maybe (EnumSet Creature)) decode "[0,3]" @?= (Just (ES.fromList creature2) :: Maybe (EnumSet Creature)) test_encode_map :: Assertion test_encode_map = do encode (EM.fromSet id $ ES.fromList creature) @?= "[[0,\"Cat\"],[1,\"Dog\"],[2,\"Fish\"]]" encode (EM.fromSet id $ ES.fromList creature2) @?= "[[0,\"Cat\"],[3,\"Wolf\"]]" encode (EM.fromList creatureM) @?= "[[0,\"C\"],[1,\"D\"]]" encode (EM.fromList creatureMRev) @?= "[[0,\"C\"],[1,\"D\"]]" encode (EM.fromList creatureMDup) @?= "[[0,\"C\"],[1,\"DD\"]]" test_decode_map :: Assertion test_decode_map = do decode "[[0,\"Cat\"],[1,\"Dog\"],[2,\"Fish\"]]" @?= ((Just $ EM.fromSet id $ ES.fromList creature) :: Maybe (EnumMap Creature Creature)) (EM.keys <$> decode @(EnumMap Creature Creature) "[[0,\"Cat\"],[1,\"Dog\"],[2,\"Fish\"]]") @?= Just [Cat,Dog,Fish] EM.toList <$> decode "[[0,\"C\"],[1,\"D\"]]" @?= (Just creatureM :: Maybe [(Creature, String)]) prop_json_trip_set :: [Int] -> Property prop_json_trip_set is = let setNums = ES.fromList is in decode (encode setNums) === Just setNums prop_json_trip_map :: [Int] -> Property prop_json_trip_map is = let mapNums = EM.fromSet show $ ES.fromList is in decode (encode mapNums) === Just mapNums prop_json_trip_map2 :: [(Int,String)] -> Property prop_json_trip_map2 is = let mapNums = EM.fromList is in decode (encode mapNums) === Just mapNums