2020-04-16 09:45:21 +03:00
|
|
|
module Data.Parser.JSONPathSpec (spec) where
|
|
|
|
|
2022-07-06 10:54:57 +03:00
|
|
|
import Data.Aeson (JSONPath)
|
2022-06-08 18:31:28 +03:00
|
|
|
import Data.Aeson.Key qualified as K
|
2022-07-06 10:54:57 +03:00
|
|
|
import Data.Aeson.Types (JSONPathElement (..))
|
2020-04-16 09:45:21 +03:00
|
|
|
import Data.Parser.JSONPath
|
2021-05-11 18:18:31 +03:00
|
|
|
import Data.Text qualified as T
|
2020-04-16 09:45:21 +03:00
|
|
|
import Hasura.Prelude
|
|
|
|
import Test.Hspec
|
|
|
|
import Test.QuickCheck
|
|
|
|
|
|
|
|
spec :: Spec
|
2022-07-05 18:52:40 +03:00
|
|
|
spec = do
|
|
|
|
describe "encoding a JSON path" $ do
|
|
|
|
it "encodes a one-level path" $
|
|
|
|
encodeJSONPath [Key "ABCD"] `shouldBe` "$.ABCD"
|
2020-04-20 11:55:09 +03:00
|
|
|
|
2022-07-05 18:52:40 +03:00
|
|
|
it "encodes a multi-level path" $
|
|
|
|
encodeJSONPath [Key "7seven", Index 0, Key "@!^@*#(!("] `shouldBe` "$[\"7seven\"][0][\"@!^@*#(!(\"]"
|
2020-04-21 11:06:11 +03:00
|
|
|
|
2022-07-05 18:52:40 +03:00
|
|
|
it "escapes control characters and quotes" $
|
|
|
|
encodeJSONPath [Key "/\\ '\" \t\r\n \xfffd"] `shouldBe` "$[\"/\\\\ '\\\" \\t\\r\\n \xfffd\"]"
|
|
|
|
|
|
|
|
describe "parsing a JSON path" $ do
|
|
|
|
it "parses a single '$'" $
|
|
|
|
parseJSONPath "$" `shouldBe` Right []
|
|
|
|
|
|
|
|
it "parses bracketed single quotes" $
|
|
|
|
parseJSONPath "$['foo \\' \" bar']" `shouldBe` Right [Key "foo ' \" bar"]
|
|
|
|
|
|
|
|
it "parses bracketed double quotes" $
|
|
|
|
parseJSONPath "$[\"bar ' \\\" foo\"]" `shouldBe` Right [Key "bar ' \" foo"]
|
|
|
|
|
|
|
|
describe "the round trip" $ do
|
|
|
|
it "encodes and parses random JSON paths" $
|
2020-04-21 11:06:11 +03:00
|
|
|
withMaxSuccess 1000 $
|
|
|
|
forAll (resize 20 generateJSONPath) $ \jsonPath ->
|
|
|
|
let encPath = encodeJSONPath jsonPath
|
2022-07-05 18:52:40 +03:00
|
|
|
parsedJSONPathE = parseJSONPath encPath
|
2020-04-21 11:06:11 +03:00
|
|
|
in case parsedJSONPathE of
|
2022-07-05 18:52:40 +03:00
|
|
|
Left err -> counterexample (T.unpack (err <> ": " <> encPath)) False
|
|
|
|
Right parsedJSONPath -> property $ parsedJSONPath === jsonPath
|
2020-04-20 11:55:09 +03:00
|
|
|
|
2020-04-16 09:45:21 +03:00
|
|
|
generateJSONPath :: Gen JSONPath
|
|
|
|
generateJSONPath = map (either id id) <$> listOf1 genPathElementEither
|
|
|
|
where
|
|
|
|
genPathElementEither = do
|
|
|
|
indexLeft <- Left <$> genIndex
|
|
|
|
keyRight <- Right <$> genKey
|
|
|
|
elements [indexLeft, keyRight]
|
|
|
|
genIndex = Index <$> choose (0, 100)
|
2022-07-05 18:52:40 +03:00
|
|
|
genKey = Key . K.fromText . T.pack <$> listOf1 arbitraryUnicodeChar
|