@@ -3,6 +3,7 @@ module Data.JsonPointer.AesonSpec (spec) where
33import Data.Aeson (Result (.. ), Value (.. ), fromJSON , object , toJSON , (.=) )
44import Data.JsonPointer
55import Data.JsonPointer.Gen
6+ import Data.Map.Strict qualified as Map
67import Test.Hspec
78import Test.Hspec.QuickCheck
89
@@ -11,7 +12,7 @@ document =
1112 object
1213 [ " foo" .= object [" bar" .= (1 :: Int ), " 0" .= (" keyed" :: String ), " -1" .= (" negative" :: String )]
1314 , " list" .= [object [" x" .= True ], Null ]
14- , " empty " .= object [ " " .= (" blank" :: String )]
15+ , " " .= (" blank" :: String )
1516 ]
1617
1718spec :: Spec
@@ -27,7 +28,7 @@ spec = do
2728 pointTo (atKey " list" <> atIndex 0 <> atKey " x" ) document `shouldBe` Just (Bool True )
2829
2930 it " looks up an empty key" $
30- pointTo (atKey " empty " <> atKey " " ) document `shouldBe` Just (String " blank" )
31+ pointTo (atKey " " ) document `shouldBe` Just (String " blank" )
3132
3233 it " returns a null stored in the document" $
3334 pointTo (atKey " list" <> atIndex 1 ) document `shouldBe` Just Null
@@ -80,6 +81,19 @@ spec = do
8081 it " escapes the reference tokens" $
8182 toJSON (atKey " a/b" ) `shouldBe` String " /a~1b"
8283
84+ describe " ToJSONKey" $ do
85+ it " renders the plain form as an object key" $
86+ toJSON (Map. singleton (atKey " foo" <> atIndex 0 ) (1 :: Int ))
87+ `shouldBe` object [" /foo/0" .= (1 :: Int )]
88+
89+ it " renders the empty pointer as the empty key" $
90+ toJSON (Map. singleton (mempty @ JsonPointer ) (1 :: Int ))
91+ `shouldBe` object [" " .= (1 :: Int )]
92+
93+ it " escapes the reference tokens" $
94+ toJSON (Map. singleton (atKey " a/b" ) (1 :: Int ))
95+ `shouldBe` object [" /a~1b" .= (1 :: Int )]
96+
8397 describe " FromJSON" $ do
8498 it " parses the plain form" $
8599 fromJSON (String " /foo/0" ) `shouldBe` Success (atKey " foo" <> atIndex 0 )
@@ -99,6 +113,27 @@ spec = do
99113 prop " round-trips a pointer through ToJSON" $ \ (Pointer pointer) ->
100114 fromJSON (toJSON pointer) `shouldBe` Success pointer
101115
116+ describe " FromJSONKey" $ do
117+ it " parses the plain form from an object key" $
118+ fromJSON (object [" /foo/0" .= (1 :: Int )])
119+ `shouldBe` Success (Map. singleton (atKey " foo" <> atIndex 0 ) (1 :: Int ))
120+
121+ it " parses the relative URI form from an object key" $
122+ fromJSON (object [" #/foo/0" .= (1 :: Int )])
123+ `shouldBe` Success (Map. singleton (atKey " foo" <> atIndex 0 ) (1 :: Int ))
124+
125+ it " parses the empty key as the empty pointer" $
126+ fromJSON (object [" " .= (1 :: Int )])
127+ `shouldBe` Success (Map. singleton (mempty @ JsonPointer ) (1 :: Int ))
128+
129+ it " fails on an illegal escape sequence" $
130+ fromJSON @ (Map. Map JsonPointer Int ) (object [" /a~2b" .= (1 :: Int )])
131+ `shouldSatisfy` isError
132+
133+ prop " round-trips a pointer through ToJSONKey" $ \ (Pointer pointer) ->
134+ fromJSON (toJSON (Map. singleton pointer (1 :: Int )))
135+ `shouldBe` Success (Map. singleton pointer (1 :: Int ))
136+
102137isError :: Result a -> Bool
103138isError = \ case
104139 Error _ -> True
0 commit comments