@@ -32,6 +32,9 @@ import Data.Proxy (Proxy(..))
3232import Data.Scientific (Scientific)
3333import Data.Tagged (Tagged(..))
3434import Data.Time (fromGregorian)
35+import Data.Time.Calendar.Compat (CalendarDiffDays (..), DayOfWeek (..))
36+import Data.Time.LocalTime.Compat (CalendarDiffTime (..))
37+import Data.Time.Clock.System.Compat (SystemTime (..))
3538import Data.Word (Word8)
3639import GHC.Generics (Generic)
3740import Instances ()
@@ -68,6 +71,9 @@ jsonExamples =
6871 example "Either Left" "{\"Left\":1}" (Left 1 :: Either Int Int)
6972 , example "Either Right" "{\"Right\":1}" (Right 1 :: Either Int Int)
7073 , example "Nothing" "null" (Nothing :: Maybe Int)
74+ -- Maybe serialising is lossy
75+ -- https://github.com/bos/aeson/issues/376
76+ , Example "Just Nothing" ["null"] (Just Nothing :: Maybe (Maybe Int)) Nothing
7177 , example "Just" "1" (Just 1 :: Maybe Int)
7278 , example "Proxy Int" "null" (Proxy :: Proxy Int)
7379 , example "Tagged Char Int" "1" (Tagged 1 :: Tagged Char Int)
@@ -82,22 +88,22 @@ jsonExamples =
8288 , example "DList" "[1,2,3]" (DList.fromList [1, 2, 3] :: DList.DList Int)
8389 , example "()" "[]" ()
8490
85− , Example "HashMap Int Int"
91+ , ndExample "HashMap Int Int"
8692 [ "{\"0\":1,\"2\":3}", "{\"2\":3,\"0\":1}"]
8793 (HM.fromList [(0,1),(2,3)] :: HM.HashMap Int Int)
88− , Example "Map Int Int"
94+ , ndExample "Map Int Int"
8995 [ "{\"0\":1,\"2\":3}", "{\"2\":3,\"0\":1}"]
9096 (M.fromList [(0,1),(2,3)] :: M.Map Int Int)
91− , Example "Map (Tagged Int Int) Int"
97+ , ndExample "Map (Tagged Int Int) Int"
9298 [ "{\"0\":1,\"2\":3}", "{\"2\":3,\"0\":1}"]
9399 (M.fromList [(Tagged 0,1),(Tagged 2,3)] :: M.Map (Tagged Int Int) Int)
94100 , example "Map [Int] Int"
95101 "[[[0],1],[[2],3]]"
96102 (M.fromList [([0],1),([2],3)] :: M.Map [Int] Int)
97− , Example "Map [Char] Int"
103+ , ndExample "Map [Char] Int"
98104 [ "{\"ab\":1,\"cd\":3}", "{\"cd\":3,\"ab\":1}" ]
99105 (M.fromList [("ab",1),("cd",3)] :: M.Map String Int)
100− , Example "Map [I Char] Int"
106+ , ndExample "Map [I Char] Int"
101107 [ "{\"ab\":1,\"cd\":3}", "{\"cd\":3,\"ab\":1}" ]
102108 (M.fromList [(map pure "ab",1),(map pure "cd",3)] :: M.Map [I Char] Int)
103109
@@ -193,16 +199,27 @@ jsonExamples =
193199 , example "Semigroup.WrappedMonoid Int" "2" (Semigroup.WrapMonoid 2 :: Semigroup.WrappedMonoid Int)
194200 , example "Semigroup.Option Just" "2" (pure 2 :: Semigroup.Option Int)
195201 , example "Semigroup.Option Nothing" "null" (Semigroup.Option (Nothing :: Maybe Bool))
202+
203+ -- time 1.9
204+ , example "SystemTime" "123.123456789" (MkSystemTime 123 123456789)
205+ , Example "SystemTime" ["124.23456789"]
206+ (MkSystemTime 123 1234567890)
207+ (MkSystemTime 124 234567890)
208+ , ndExample "CalendarDiffTime"
209+ [ "{\"months\":12,\"time\":456.789}", "{\"time\":456.789,\"months\":12}" ]
210+ (CalendarDiffTime 12 456.789)
211+ , ndExample "CalendarDiffDays"
212+ [ "{\"months\":12,\"days\":20}", "{\"days\":20,\"months\":12}" ]
213+ (CalendarDiffDays 12 20)
214+ , example "DayOfWeek" "\"monday\"" Monday
196215 ]
197216
198217jsonEncodingExamples :: [Example]
199218jsonEncodingExamples =
200219 [
201− -- Maybe serialising is lossy
202− -- https://github.com/bos/aeson/issues/376
203− example "Just Nothing" "null" (Just Nothing :: Maybe (Maybe Int))
204220 -- infinities cannot be recovered, null is decoded as NaN
205− , example "inf :: Double" "null" (Approx $ 1/0 :: Approx Double)
221+ example "inf :: Double" "null" (Approx $ 1/0 :: Approx Double)
222+ , example "-inf :: Double" "null" (Approx $ -1/0 :: Approx Double)
206223 ]
207224
208225jsonDecodingExamples :: [Example]
@@ -224,16 +241,27 @@ jsonDecodingExamples = [
224241 ]
225242
226243data Example where
227− Example
228− :: (Eq a, Show a, ToJSON a, FromJSON a)
229− => String -> [L.ByteString] -> a -> Example -- empty bytestring will fail, any p [] == False
230− MaybeExample
231− :: (Eq a, Show a, FromJSON a)
232− => String -> L.ByteString -> Maybe a -> Example
244+ Example
245+ :: (Eq a, Show a, ToJSON a, FromJSON a)
246+ => String -- name
247+ -> [L.ByteString] -- encoded variants
248+ -> a -- input
249+ -> a -- decoded
250+ -> Example -- empty bytestring will fail, any p [] == False
251+
252+ MaybeExample
253+ :: (Eq a, Show a, FromJSON a)
254+ => String -> L.ByteString -> Maybe a -> Example
233255
234256example :: (Eq a, Show a, ToJSON a, FromJSON a)
235257 => String -> L.ByteString -> a -> Example
236−example n bs x = Example n [bs] x
258+example n bs x = Example n [bs] x x
259+
260+-- | Non-deterministic example, input encodes to some of bytestrings.
261+ndExample :: (Eq a, Show a, ToJSON a, FromJSON a)
262+ => String -> [L.ByteString] -> a -> Example
263+ndExample n bss x = Example n bss x x
264+
237265
238266data MyEither a b = MyLeft a | MyRight b
239267 deriving (Generic, Show, Eq)
@@ -246,16 +274,16 @@ instance (FromJSON a, FromJSON b) => FromJSON (MyEither a b) where
246274 parseJSON = genericParseJSON defaultOptions { sumEncoding = UntaggedValue }
247275
248276assertJsonExample :: Example -> TestTree
249−assertJsonExample (Example name bss val) = testCase name $ do
277+assertJsonExample (Example name bss val val') = testCase name $ do
250278 assertSomeEqual "encode" bss (encode val)
251279 assertSomeEqual "encode/via value" bss (encode $ toJSON val)
252280 for_ bss $ \bs ->
253− assertEqual "decode" (Just val) (decode bs)
281+ assertEqual "decode" (Just val') (decode bs)
254282assertJsonExample (MaybeExample name bs mval) = testCase name $
255283 assertEqual "decode" mval (decode bs)
256284
257285assertJsonEncodingExample :: Example -> TestTree
258−assertJsonEncodingExample (Example name bss val) = testCase name $ do
286+assertJsonEncodingExample (Example name bss val _) = testCase name $ do
259287 assertSomeEqual "encode" bss (encode val)
260288 assertSomeEqual "encode/via value" bss (encode $ toJSON val)
261289assertJsonEncodingExample (MaybeExample name _ _) = testCase name $