packages feed

aeson-generic-default-0.1.0.0: test/Main.hs

module Main (main) where

import Test.Tasty
import Test.Tasty.HUnit
import qualified Data.Aeson as AE
import Data.Aeson.DefaultField
import GHC.Generics (Generic)
import Data.Default (Default(..))
import qualified Data.Text as T
import Data.Aeson (FromJSON(..))
import Data.Either (isLeft)

data Color = Red | Green | Blue
  deriving (Show, Eq, Generic, FromJSON)
instance Default Color where
  def = Red

newtype BlueDefault = BlueDefault Color deriving Generic
instance DefaultConstant BlueDefault where
  defValue _ = Blue

data ConfigFileT d = ConfigFile {
  defaultEnabled :: DefaultField d (DefBool True)
, defaultDisabled :: DefaultField d (DefBool False)
, defaultText :: DefaultField d (DefText "default text")
, defaultInt :: DefaultField d (DefInt 42)
, defaultNegativeInt :: DefaultField d (DefNegativeInt 42)
, defaultRed :: DefaultField d (DefDefault Color)
, defaultBlue :: DefaultField d (DefDefaultConstant BlueDefault)
, normalField :: T.Text
, normalOptional :: Maybe Int
} deriving (Generic)

type ConfigFile = ConfigFileT Final
deriving instance Show ConfigFile
deriving instance Eq ConfigFile
instance FromJSON ConfigFile where
  parseJSON = parseWithDefaults AE.defaultOptions


main :: IO ()
main = defaultMain $ testGroup "Tests" [
    testCase "Basic empty input" $ do
      let decoded = AE.eitherDecode "{\"normalField\":\"input\"}"
          expectedResult1 :: ConfigFile
          expectedResult1 = ConfigFile {
            defaultEnabled = True
          , defaultDisabled = False
          , defaultText = "default text"
          , defaultInt = 42
          , defaultNegativeInt = -42
          , defaultRed = Red
          , defaultBlue = Blue
          , normalField = "input"
          , normalOptional = Nothing
          }
      decoded @?= Right expectedResult1
  , testCase "Basic partial input" $ do
      let decoded = AE.eitherDecode "{\"normalField\":\"input\", \"defaultEnabled\":false,\"defaultRed\":\"Green\", \"defaultNegativeInt\":2}"
          expectedResult1 :: ConfigFile
          expectedResult1 = ConfigFile {
            defaultEnabled = False
          , defaultDisabled = False
          , defaultText = "default text"
          , defaultInt = 42
          , defaultNegativeInt = 2
          , defaultRed = Green
          , defaultBlue = Blue
          , normalField = "input"
          , normalOptional = Nothing
          }
      decoded @?= Right expectedResult1
  , testCase "Basic null input" $ do
      let decoded = AE.eitherDecode "{\"normalField\":\"input\", \"defaultEnabled\":null}" :: Either String ConfigFile
      assertBool "Should fail on null value in default field" (isLeft decoded)
  ]