packages feed

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

{-# 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"