packages feed

aeson-commit-1.4: test/tasty/Main.hs

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}

module Main (main) where

import Control.Applicative
import Data.Aeson.Commit
import Data.Aeson.QQ
import Data.Aeson.Types
import Data.Text (Text)
import Test.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 = hspec tests