{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE OverloadedStrings #-}
module Main (main) where
import Data.Aeson.QQ
import Data.Aeson.Types
import Data.Aeson.Commit
import Control.Applicative
import Data.Text (Text)
import Test.Tasty
import Test.Tasty.Hspec
tests :: Spec
tests = testParserWithCases pNested
[ ( "fails"
, [aesonQQ| {} |]
, Left $ unlines
[ "Error in $: No match,"
, "- key \"value\" not found"
, "- key \"nested\" not found"
]
)
, ( "succeeds unnested"
, [aesonQQ| { value: "top" } |]
, Right "top"
)
, ( "succeeds and prefers nested"
, [aesonQQ| { value: "top" , nested: { value: "nest" } } |]
, Right "nest"
)
, ( "fails on malformed nested"
, [aesonQQ| { value: "top", nested: { foo: 9 } } |]
, Left "Error in $.nested: key \"value\" not found"
)
, ( "fails on nested type mismatch"
, [aesonQQ| { value: "top", nested: 9 } |]
, Left "Error in $.nested: parsing nestedObj failed, expected Object, but encountered Number"
)
]
where
pNested :: Value -> Parser Text
pNested = withObject "topLevel" $ \o ->
runCommit
$ (o .:> "nested") (withObject "nestedObj" (.: "value"))
<|> tryParser (o .: "value")
testParserWithCases
:: (Eq a, Show a)
=> (v -> Parser a)
-> [(String, v, Either String a)]
-> Spec
testParserWithCases p =
mapM_ ( \(name, v, result) -> it name (parseEither p v `shouldBe` result))
main :: IO ()
main = testSpecs tests >>= defaultMain . testGroup "aeson-commit"