|
Packit |
9a2dfb |
{-# LANGUAGE CPP #-}
|
|
Packit |
9a2dfb |
{-# LANGUAGE DeriveGeneric #-}
|
|
Packit |
9a2dfb |
{-# LANGUAGE GADTs #-}
|
|
Packit |
9a2dfb |
{-# LANGUAGE OverloadedStrings #-}
|
|
Packit |
9a2dfb |
#if __GLASGOW_HASKELL__ >= 708
|
|
Packit |
9a2dfb |
{-# LANGUAGE DataKinds #-}
|
|
Packit |
9a2dfb |
#endif
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
------------------------------------------------------------------------------
|
|
Packit |
9a2dfb |
-- These tests assert that the JSON serialization doesn't change by accident.
|
|
Packit |
9a2dfb |
-----------------------------------------------------------------------------
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
module SerializationFormatSpec
|
|
Packit |
9a2dfb |
(
|
|
Packit |
9a2dfb |
tests
|
|
Packit |
9a2dfb |
) 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 (FromJSON(..), decode, encode, genericParseJSON, genericToEncoding, genericToJSON)
|
|
Packit |
9a2dfb |
import Data.Aeson.Types (Options(..), SumEncoding(..), ToJSON(..), defaultOptions)
|
|
Packit |
9a2dfb |
import Data.Fixed (Pico)
|
|
Packit |
9a2dfb |
import Data.Foldable (for_, toList)
|
|
Packit |
9a2dfb |
import Data.Functor.Compose (Compose(..))
|
|
Packit |
9a2dfb |
import Data.Functor.Identity (Identity(..))
|
|
Packit |
9a2dfb |
import Data.Functor.Product (Product(..))
|
|
Packit |
9a2dfb |
import Data.Functor.Sum (Sum(..))
|
|
Packit |
9a2dfb |
import Data.List.NonEmpty (NonEmpty(..))
|
|
Packit |
9a2dfb |
import Data.Proxy (Proxy(..))
|
|
Packit |
9a2dfb |
import Data.Scientific (Scientific)
|
|
Packit |
9a2dfb |
import Data.Tagged (Tagged(..))
|
|
Packit |
9a2dfb |
import Data.Time (fromGregorian)
|
|
Packit |
9a2dfb |
import Data.Word (Word8)
|
|
Packit |
9a2dfb |
import GHC.Generics (Generic)
|
|
Packit |
9a2dfb |
import Instances ()
|
|
Packit |
9a2dfb |
import Test.Framework (Test, testGroup)
|
|
Packit |
9a2dfb |
import Test.Framework.Providers.HUnit (testCase)
|
|
Packit |
9a2dfb |
import Test.HUnit (assertFailure, assertEqual)
|
|
Packit |
9a2dfb |
import Types (Approx(..), Compose3, Compose3', I)
|
|
Packit |
9a2dfb |
import qualified Data.ByteString.Lazy.Char8 as L
|
|
Packit |
9a2dfb |
import qualified Data.DList as DList
|
|
Packit |
9a2dfb |
import qualified Data.HashMap.Strict as HM
|
|
Packit |
9a2dfb |
import qualified Data.HashSet as HashSet
|
|
Packit |
9a2dfb |
import qualified Data.IntMap as IntMap
|
|
Packit |
9a2dfb |
import qualified Data.IntSet as IntSet
|
|
Packit |
9a2dfb |
import qualified Data.Map as M
|
|
Packit |
9a2dfb |
import qualified Data.Monoid as Monoid
|
|
Packit |
9a2dfb |
import qualified Data.Semigroup as Semigroup
|
|
Packit |
9a2dfb |
import qualified Data.Sequence as Seq
|
|
Packit |
9a2dfb |
import qualified Data.Set as Set
|
|
Packit |
9a2dfb |
import qualified Data.Tree as Tree
|
|
Packit |
9a2dfb |
import qualified Data.UUID.Types as UUID
|
|
Packit |
9a2dfb |
import qualified Data.Vector as Vector
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
tests :: [Test]
|
|
Packit |
9a2dfb |
tests =
|
|
Packit |
9a2dfb |
[
|
|
Packit |
9a2dfb |
testGroup "To JSON representation" $ fmap assertJsonEncodingExample jsonEncodingExamples
|
|
Packit |
9a2dfb |
, testGroup "From JSON representation" $ fmap assertJsonExample jsonDecodingExamples
|
|
Packit |
9a2dfb |
, testGroup "To/From JSON representation" $ fmap assertJsonExample jsonExamples
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
]
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
jsonExamples :: [Example]
|
|
Packit |
9a2dfb |
jsonExamples =
|
|
Packit |
9a2dfb |
[
|
|
Packit |
9a2dfb |
example "Either Left" "{\"Left\":1}" (Left 1 :: Either Int Int)
|
|
Packit |
9a2dfb |
, example "Either Right" "{\"Right\":1}" (Right 1 :: Either Int Int)
|
|
Packit |
9a2dfb |
, example "Nothing" "null" (Nothing :: Maybe Int)
|
|
Packit |
9a2dfb |
, example "Just" "1" (Just 1 :: Maybe Int)
|
|
Packit |
9a2dfb |
, example "Proxy Int" "null" (Proxy :: Proxy Int)
|
|
Packit |
9a2dfb |
, example "Tagged Char Int" "1" (Tagged 1 :: Tagged Char Int)
|
|
Packit |
9a2dfb |
#if __GLASGOW_HASKELL__ >= 708
|
|
Packit |
9a2dfb |
-- Test Tagged instance is polykinded
|
|
Packit |
9a2dfb |
, example "Tagged 123 Int" "1" (Tagged 1 :: Tagged 123 Int)
|
|
Packit |
9a2dfb |
#endif
|
|
Packit |
9a2dfb |
, example "Const Char Int" "\"c\"" (Const 'c' :: Const Char Int)
|
|
Packit |
9a2dfb |
, example "Tuple" "[1,2]" ((1, 2) :: (Int, Int))
|
|
Packit |
9a2dfb |
, example "NonEmpty" "[1,2,3]" (1 :| [2, 3] :: NonEmpty Int)
|
|
Packit |
9a2dfb |
, example "Seq" "[1,2,3]" (Seq.fromList [1, 2, 3] :: Seq.Seq Int)
|
|
Packit |
9a2dfb |
, example "DList" "[1,2,3]" (DList.fromList [1, 2, 3] :: DList.DList Int)
|
|
Packit |
9a2dfb |
, example "()" "[]" ()
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, Example "HashMap Int Int"
|
|
Packit |
9a2dfb |
[ "{\"0\":1,\"2\":3}", "{\"2\":3,\"0\":1}"]
|
|
Packit |
9a2dfb |
(HM.fromList [(0,1),(2,3)] :: HM.HashMap Int Int)
|
|
Packit |
9a2dfb |
, Example "Map Int Int"
|
|
Packit |
9a2dfb |
[ "{\"0\":1,\"2\":3}", "{\"2\":3,\"0\":1}"]
|
|
Packit |
9a2dfb |
(M.fromList [(0,1),(2,3)] :: M.Map Int Int)
|
|
Packit |
9a2dfb |
, Example "Map (Tagged Int Int) Int"
|
|
Packit |
9a2dfb |
[ "{\"0\":1,\"2\":3}", "{\"2\":3,\"0\":1}"]
|
|
Packit |
9a2dfb |
(M.fromList [(Tagged 0,1),(Tagged 2,3)] :: M.Map (Tagged Int Int) Int)
|
|
Packit |
9a2dfb |
, example "Map [Int] Int"
|
|
Packit |
9a2dfb |
"[[[0],1],[[2],3]]"
|
|
Packit |
9a2dfb |
(M.fromList [([0],1),([2],3)] :: M.Map [Int] Int)
|
|
Packit |
9a2dfb |
, Example "Map [Char] Int"
|
|
Packit |
9a2dfb |
[ "{\"ab\":1,\"cd\":3}", "{\"cd\":3,\"ab\":1}" ]
|
|
Packit |
9a2dfb |
(M.fromList [("ab",1),("cd",3)] :: M.Map String Int)
|
|
Packit |
9a2dfb |
, Example "Map [I Char] Int"
|
|
Packit |
9a2dfb |
[ "{\"ab\":1,\"cd\":3}", "{\"cd\":3,\"ab\":1}" ]
|
|
Packit |
9a2dfb |
(M.fromList [(map pure "ab",1),(map pure "cd",3)] :: M.Map [I Char] Int)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "nan :: Double" "null" (Approx $ 0/0 :: Approx Double)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "Ordering LT" "\"LT\"" LT
|
|
Packit |
9a2dfb |
, example "Ordering EQ" "\"EQ\"" EQ
|
|
Packit |
9a2dfb |
, example "Ordering GT" "\"GT\"" GT
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "Float" "3.14" (3.14 :: Float)
|
|
Packit |
9a2dfb |
, example "Pico" "3.14" (3.14 :: Pico)
|
|
Packit |
9a2dfb |
, example "Scientific" "3.14" (3.14 :: Scientific)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "UUID" "\"c2cc10e1-57d6-4b6f-9899-38d972112d8c\"" $ UUID.fromWords
|
|
Packit |
9a2dfb |
0xc2cc10e1 0x57d64b6f 0x989938d9 0x72112d8c
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "Set Int" "[1,2,3]" (Set.fromList [3, 2, 1] :: Set.Set Int)
|
|
Packit |
9a2dfb |
, example "IntSet" "[1,2,3]" (IntSet.fromList [3, 2, 1])
|
|
Packit |
9a2dfb |
, example "IntMap" "[[1,2],[3,4]]" (IntMap.fromList [(3,4), (1,2)] :: IntMap.IntMap Int)
|
|
Packit |
9a2dfb |
, example "Vector" "[1,2,3]" (Vector.fromList [1, 2, 3] :: Vector.Vector Int)
|
|
Packit |
9a2dfb |
, example "HashSet Int" "[1,2,3]" (HashSet.fromList [3, 2, 1] :: HashSet.HashSet Int)
|
|
Packit |
9a2dfb |
, example "Tree Int" "[1,[[2,[[3,[]],[4,[]]]],[5,[]]]]" (let n = Tree.Node in n 1 [n 2 [n 3 [], n 4 []], n 5 []] :: Tree.Tree Int)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
-- Three separate cases, as ordering in HashMap is not defined
|
|
Packit |
9a2dfb |
, example "HashMap Float Int, NaN" "{\"NaN\":1}" (Approx $ HM.singleton (0/0) 1 :: Approx (HM.HashMap Float Int))
|
|
Packit |
9a2dfb |
, example "HashMap Float Int, Infinity" "{\"Infinity\":1}" (HM.singleton (1/0) 1 :: HM.HashMap Float Int)
|
|
Packit |
9a2dfb |
, example "HashMap Float Int, +Infinity" "{\"-Infinity\":1}" (HM.singleton (negate 1/0) 1 :: HM.HashMap Float Int)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
-- Functors
|
|
Packit |
9a2dfb |
, example "Identity Int" "1" (pure 1 :: Identity Int)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "Identity Char" "\"x\"" (pure 'x' :: Identity Char)
|
|
Packit |
9a2dfb |
, example "Identity String" "\"foo\"" (pure "foo" :: Identity String)
|
|
Packit |
9a2dfb |
, example "[Identity Char]" "\"xy\"" ([pure 'x', pure 'y'] :: [Identity Char])
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "Maybe Char" "\"x\"" (pure 'x' :: Maybe Char)
|
|
Packit |
9a2dfb |
, example "Maybe String" "\"foo\"" (pure "foo" :: Maybe String)
|
|
Packit |
9a2dfb |
, example "Maybe [Identity Char]" "\"xy\"" (pure [pure 'x', pure 'y'] :: Maybe [Identity Char])
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "Day; year >= 1000" "\"1999-10-12\"" (fromGregorian 1999 10 12)
|
|
Packit |
9a2dfb |
, example "Day; year > 0 && < 1000" "\"0500-03-04\"" (fromGregorian 500 3 4)
|
|
Packit |
9a2dfb |
, example "Day; year == 0" "\"0000-02-20\"" (fromGregorian 0 2 20)
|
|
Packit |
9a2dfb |
, example "Day; year < 0" "\"-0234-01-01\"" (fromGregorian (-234) 1 1)
|
|
Packit |
9a2dfb |
, example "Day; year < -1000" "\"-1234-01-01\"" (fromGregorian (-1234) 1 1)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "Product I Maybe Int" "[1,2]" (Pair (pure 1) (pure 2) :: Product I Maybe Int)
|
|
Packit |
9a2dfb |
, example "Product I Maybe Int" "[1,null]" (Pair (pure 1) Nothing :: Product I Maybe Int)
|
|
Packit |
9a2dfb |
, example "Product I [] Char" "[\"a\",\"foo\"]" (Pair (pure 'a') "foo" :: Product I [] Char)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "Sum I [] Int: InL" "{\"InL\":1}" (InL (pure 1) :: Sum I [] Int)
|
|
Packit |
9a2dfb |
, example "Sum I [] Int: InR" "{\"InR\":[1,2]}" (InR [1, 2] :: Sum I [] Int)
|
|
Packit |
9a2dfb |
, example "Sum I [] Char: InR" "{\"InR\":\"foo\"}" (InR "foo" :: Sum I [] Char)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "Compose I I Int" "1" (pure 1 :: Compose I I Int)
|
|
Packit |
9a2dfb |
, example "Compose I [] Int" "[1]" (pure 1 :: Compose I [] Int)
|
|
Packit |
9a2dfb |
, example "Compose [] I Int" "[1]" (pure 1 :: Compose [] I Int)
|
|
Packit |
9a2dfb |
, example "Compose [] [] Int" "[[1]]" (pure 1 :: Compose [] [] Int)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "Compose I I Char" "\"x\"" (pure 'x' :: Compose I I Char)
|
|
Packit |
9a2dfb |
, example "Compose I [] Char" "\"x\"" (pure 'x' :: Compose I [] Char)
|
|
Packit |
9a2dfb |
, example "Compose [] I Char" "\"x\"" (pure 'x' :: Compose [] I Char)
|
|
Packit |
9a2dfb |
, example "Compose [] [] Char" "[\"x\"]" (pure 'x' :: Compose [] [] Char)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "Compose3 I I I Char" "\"x\"" (pure 'x' :: Compose3 I I I Char)
|
|
Packit |
9a2dfb |
, example "Compose3 I I [] Char" "\"x\"" (pure 'x' :: Compose3 I I [] Char)
|
|
Packit |
9a2dfb |
, example "Compose3 I [] I Char" "\"x\"" (pure 'x' :: Compose3 I [] I Char)
|
|
Packit |
9a2dfb |
, example "Compose3 I [] [] Char" "[\"x\"]" (pure 'x' :: Compose3 I [] [] Char)
|
|
Packit |
9a2dfb |
, example "Compose3 [] I I Char" "\"x\"" (pure 'x' :: Compose3 [] I I Char)
|
|
Packit |
9a2dfb |
, example "Compose3 [] I [] Char" "[\"x\"]" (pure 'x' :: Compose3 [] I [] Char)
|
|
Packit |
9a2dfb |
, example "Compose3 [] [] I Char" "[\"x\"]" (pure 'x' :: Compose3 [] [] I Char)
|
|
Packit |
9a2dfb |
, example "Compose3 [] [] [] Char" "[[\"x\"]]" (pure 'x' :: Compose3 [] [] [] Char)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "Compose3' I I I Char" "\"x\"" (pure 'x' :: Compose3' I I I Char)
|
|
Packit |
9a2dfb |
, example "Compose3' I I [] Char" "\"x\"" (pure 'x' :: Compose3' I I [] Char)
|
|
Packit |
9a2dfb |
, example "Compose3' I [] I Char" "\"x\"" (pure 'x' :: Compose3' I [] I Char)
|
|
Packit |
9a2dfb |
, example "Compose3' I [] [] Char" "[\"x\"]" (pure 'x' :: Compose3' I [] [] Char)
|
|
Packit |
9a2dfb |
, example "Compose3' [] I I Char" "\"x\"" (pure 'x' :: Compose3' [] I I Char)
|
|
Packit |
9a2dfb |
, example "Compose3' [] I [] Char" "[\"x\"]" (pure 'x' :: Compose3' [] I [] Char)
|
|
Packit |
9a2dfb |
, example "Compose3' [] [] I Char" "[\"x\"]" (pure 'x' :: Compose3' [] [] I Char)
|
|
Packit |
9a2dfb |
, example "Compose3' [] [] [] Char" "[[\"x\"]]" (pure 'x' :: Compose3' [] [] [] Char)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
, example "MyEither Int String: Left" "42" (MyLeft 42 :: MyEither Int String)
|
|
Packit |
9a2dfb |
, example "MyEither Int String: Right" "\"foo\"" (MyRight "foo" :: MyEither Int String)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
-- newtypes from Monoid/Semigroup
|
|
Packit |
9a2dfb |
, example "Monoid.Dual Int" "2" (pure 2 :: Monoid.Dual Int)
|
|
Packit |
9a2dfb |
, example "Monoid.First Int" "2" (pure 2 :: Monoid.First Int)
|
|
Packit |
9a2dfb |
, example "Monoid.Last Int" "2" (pure 2 :: Monoid.Last Int)
|
|
Packit |
9a2dfb |
, example "Semigroup.Min Int" "2" (pure 2 :: Semigroup.Min Int)
|
|
Packit |
9a2dfb |
, example "Semigroup.Max Int" "2" (pure 2 :: Semigroup.Max Int)
|
|
Packit |
9a2dfb |
, example "Semigroup.First Int" "2" (pure 2 :: Semigroup.First Int)
|
|
Packit |
9a2dfb |
, example "Semigroup.Last Int" "2" (pure 2 :: Semigroup.Last Int)
|
|
Packit |
9a2dfb |
, example "Semigroup.WrappedMonoid Int" "2" (Semigroup.WrapMonoid 2 :: Semigroup.WrappedMonoid Int)
|
|
Packit |
9a2dfb |
, example "Semigroup.Option Just" "2" (pure 2 :: Semigroup.Option Int)
|
|
Packit |
9a2dfb |
, example "Semigroup.Option Nothing" "null" (Semigroup.Option (Nothing :: Maybe Bool))
|
|
Packit |
9a2dfb |
]
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
jsonEncodingExamples :: [Example]
|
|
Packit |
9a2dfb |
jsonEncodingExamples =
|
|
Packit |
9a2dfb |
[
|
|
Packit |
9a2dfb |
-- Maybe serialising is lossy
|
|
Packit |
9a2dfb |
-- https://github.com/bos/aeson/issues/376
|
|
Packit |
9a2dfb |
example "Just Nothing" "null" (Just Nothing :: Maybe (Maybe Int))
|
|
Packit |
9a2dfb |
-- infinities cannot be recovered, null is decoded as NaN
|
|
Packit |
9a2dfb |
, example "inf :: Double" "null" (Approx $ 1/0 :: Approx Double)
|
|
Packit |
9a2dfb |
]
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
jsonDecodingExamples :: [Example]
|
|
Packit |
9a2dfb |
jsonDecodingExamples = [
|
|
Packit |
9a2dfb |
-- Maybe serialising is lossy
|
|
Packit |
9a2dfb |
-- https://github.com/bos/aeson/issues/376
|
|
Packit |
9a2dfb |
MaybeExample "Nothing" "null" (Just Nothing :: Maybe (Maybe Int))
|
|
Packit |
9a2dfb |
, MaybeExample "Just" "1" (Just $ Just 1 :: Maybe (Maybe Int))
|
|
Packit |
9a2dfb |
, MaybeExample "Just Nothing" "null" (Just Nothing :: Maybe (Maybe (Maybe Int)))
|
|
Packit |
9a2dfb |
-- Integral values are truncated, and overflowed
|
|
Packit |
9a2dfb |
-- https://github.com/bos/aeson/issues/317
|
|
Packit |
9a2dfb |
, MaybeExample "Word8 3" "3" (Just 3 :: Maybe Word8)
|
|
Packit |
9a2dfb |
, MaybeExample "Word8 3.00" "3.00" (Just 3 :: Maybe Word8)
|
|
Packit |
9a2dfb |
, MaybeExample "Word8 3.14" "3.14" (Nothing :: Maybe Word8)
|
|
Packit |
9a2dfb |
, MaybeExample "Word8 -1" "-1" (Nothing :: Maybe Word8)
|
|
Packit |
9a2dfb |
, MaybeExample "Word8 300" "300" (Nothing :: Maybe Word8)
|
|
Packit |
9a2dfb |
-- Negative zero year, encoding never produces such:
|
|
Packit |
9a2dfb |
, MaybeExample "Day -0000-02-03" "\"-0000-02-03\"" (Just (fromGregorian 0 2 3))
|
|
Packit |
9a2dfb |
]
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
data Example where
|
|
Packit |
9a2dfb |
Example
|
|
Packit |
9a2dfb |
:: (Eq a, Show a, ToJSON a, FromJSON a)
|
|
Packit |
9a2dfb |
=> String -> [L.ByteString] -> a -> Example -- empty bytestring will fail, any p [] == False
|
|
Packit |
9a2dfb |
MaybeExample
|
|
Packit |
9a2dfb |
:: (Eq a, Show a, FromJSON a)
|
|
Packit |
9a2dfb |
=> String -> L.ByteString -> Maybe a -> Example
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
example :: (Eq a, Show a, ToJSON a, FromJSON a)
|
|
Packit |
9a2dfb |
=> String -> L.ByteString -> a -> Example
|
|
Packit |
9a2dfb |
example n bs x = Example n [bs] x
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
data MyEither a b = MyLeft a | MyRight b
|
|
Packit |
9a2dfb |
deriving (Generic, Show, Eq)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
instance (ToJSON a, ToJSON b) => ToJSON (MyEither a b) where
|
|
Packit |
9a2dfb |
toJSON = genericToJSON defaultOptions { sumEncoding = UntaggedValue }
|
|
Packit |
9a2dfb |
toEncoding = genericToEncoding defaultOptions { sumEncoding = UntaggedValue }
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
instance (FromJSON a, FromJSON b) => FromJSON (MyEither a b) where
|
|
Packit |
9a2dfb |
parseJSON = genericParseJSON defaultOptions { sumEncoding = UntaggedValue }
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
assertJsonExample :: Example -> Test
|
|
Packit |
9a2dfb |
assertJsonExample (Example name bss val) = testCase name $ do
|
|
Packit |
9a2dfb |
assertSomeEqual "encode" bss (encode val)
|
|
Packit |
9a2dfb |
assertSomeEqual "encode/via value" bss (encode $ toJSON val)
|
|
Packit |
9a2dfb |
for_ bss $ \bs ->
|
|
Packit |
9a2dfb |
assertEqual "decode" (Just val) (decode bs)
|
|
Packit |
9a2dfb |
assertJsonExample (MaybeExample name bs mval) = testCase name $
|
|
Packit |
9a2dfb |
assertEqual "decode" mval (decode bs)
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
assertJsonEncodingExample :: Example -> Test
|
|
Packit |
9a2dfb |
assertJsonEncodingExample (Example name bss val) = testCase name $ do
|
|
Packit |
9a2dfb |
assertSomeEqual "encode" bss (encode val)
|
|
Packit |
9a2dfb |
assertSomeEqual "encode/via value" bss (encode $ toJSON val)
|
|
Packit |
9a2dfb |
assertJsonEncodingExample (MaybeExample name _ _) = testCase name $
|
|
Packit |
9a2dfb |
assertFailure "cannot encode MaybeExample"
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
assertSomeEqual :: (Eq a, Show a, Foldable f) => String -> f a -> a -> IO ()
|
|
Packit |
9a2dfb |
assertSomeEqual preface expected actual
|
|
Packit |
9a2dfb |
| actual `elem` expected = return ()
|
|
Packit |
9a2dfb |
| otherwise = assertFailure $ preface
|
|
Packit |
9a2dfb |
++ ": expecting one of " ++ show (toList expected)
|
|
Packit |
9a2dfb |
++ ", got " ++ show actual
|
|
Packit |
9a2dfb |
|