packages feed

composite-aeson-0.5.0.0: test/THSpec.hs

module THSpec where

import Composite.Aeson.Base (dimapJsonFormat, fromJsonWithFormat, toJsonWithFormat)
import Composite.Aeson.CoRecord (JsonFormatField)
import Composite.Aeson.Formats.Default (defaultJsonFormat)
import Composite.Aeson.Formats.Generic (SumStyle(SumStyleFieldName))
import Composite.Aeson.Formats.Provided (integralJsonFormat)
import Composite.Aeson.Record (JsonFormatRecord, field)
import Composite.Aeson.TH (makeFieldJsonWrapper, makeFieldJsonWrapperExplicit, makeRecordJsonWrapper, makeRecordJsonWrapperExplicit)
import Composite.Record ((:->), Rec((:&), RNil), pattern (:*:))
import Composite.TH (withOpticsAndProxies)
import Control.Lens (review)
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Types as Aeson
import qualified Data.Aeson.BetterErrors  as ABE
import Data.Aeson.QQ (aesonQQ)
import Data.Void (Void)
import Test.Hspec (Spec, describe, it, shouldBe)

withOpticsAndProxies [d|
  type FFoo = "foo" :-> Int
  |]

type Foo = '[FFoo]

explicitFooJsonFormatRecord :: JsonFormatRecord e Foo
explicitFooJsonFormatRecord
  =  field (dimapJsonFormat (+10) (subtract 10) integralJsonFormat)
  :& RNil

explicitFooJsonFormatField :: JsonFormatField e Foo
explicitFooJsonFormatField
  =  dimapJsonFormat (+10) (subtract 10) integralJsonFormat
  :& RNil

makeRecordJsonWrapper "FooRecordDefaultJson" ''Foo
makeRecordJsonWrapperExplicit "FooRecordExplicitJson" ''Foo [| explicitFooJsonFormatRecord |]
makeFieldJsonWrapper "FooFieldDefaultJson" ''Foo SumStyleFieldName
makeFieldJsonWrapperExplicit "FooFieldExplicitJson" ''Foo SumStyleFieldName [| explicitFooJsonFormatField |]

deriving instance Eq FooRecordDefaultJson
deriving instance Eq FooRecordExplicitJson
deriving instance Eq FooFieldDefaultJson
deriving instance Eq FooFieldExplicitJson

deriving instance Show FooRecordDefaultJson
deriving instance Show FooRecordExplicitJson
deriving instance Show FooFieldDefaultJson
deriving instance Show FooFieldExplicitJson

thSuite :: Spec
thSuite = do
  describe "Composite.Aeson.TH" $ do
    it "decodes via FromJSON using makeRecordJsonWrapper" $ do
      Aeson.parseEither Aeson.parseJSON [aesonQQ| {foo: 123} |] `shouldBe` Right (FooRecordDefaultJson $ 123 :*: RNil)
    it "encodes via ToJSON using makeRecordJsonWrapper" $ do
      Aeson.toJSON (FooRecordDefaultJson $ 123 :*: RNil) `shouldBe` [aesonQQ| {foo: 123} |]
    it "decodes via DefaultJsonFormat using makeRecordJsonWrapper" $ do
      ABE.parseValue @Void (fromJsonWithFormat defaultJsonFormat) [aesonQQ| {foo: 123} |] `shouldBe` Right (FooRecordDefaultJson $ 123 :*: RNil)
    it "encodes via DefaultJsonFormat using makeRecordJsonWrapper" $ do
      toJsonWithFormat defaultJsonFormat (FooRecordDefaultJson $ 123 :*: RNil) `shouldBe` [aesonQQ| {foo: 123} |]

    it "decodes via FromJSON using makeRecordJsonWrapperExplicit" $ do
      Aeson.parseEither Aeson.parseJSON [aesonQQ| {foo: 123} |] `shouldBe` Right (FooRecordExplicitJson $ 113 :*: RNil)
    it "encodes via ToJSON using makeRecordJsonWrapperExplicit" $ do
      Aeson.toJSON (FooRecordExplicitJson $ 113 :*: RNil) `shouldBe` [aesonQQ| {foo: 123} |]
    it "decodes via DefaultJsonFormat using makeRecordJsonWrapperExplicit" $ do
      ABE.parseValue @Void (fromJsonWithFormat defaultJsonFormat) [aesonQQ| {foo: 123} |] `shouldBe` Right (FooRecordExplicitJson $ 113 :*: RNil)
    it "encodes via DefaultJsonFormat using makeRecordJsonWrapperExplicit" $ do
      toJsonWithFormat defaultJsonFormat (FooRecordExplicitJson $ 113 :*: RNil) `shouldBe` [aesonQQ| {foo: 123} |]

    it "decodes via FromJSON using makeFieldJsonWrapper" $ do
      Aeson.parseEither Aeson.parseJSON [aesonQQ| {foo: 123} |] `shouldBe` Right (FooFieldDefaultJson $ review _FFoo 123)
    it "encodes via ToJSON using makeFieldJsonWrapper" $ do
      Aeson.toJSON (FooFieldDefaultJson $ review _FFoo 123) `shouldBe` [aesonQQ| {foo: 123} |]
    it "decodes via DefaultJsonFormat using makeFieldJsonWrapper" $ do
      ABE.parseValue @Void (fromJsonWithFormat defaultJsonFormat) [aesonQQ| {foo: 123} |] `shouldBe` Right (FooFieldDefaultJson $ review _FFoo 123)
    it "encodes via DefaultJsonFormat using makeFieldJsonWrapper" $ do
      toJsonWithFormat defaultJsonFormat (FooFieldDefaultJson $ review _FFoo 123) `shouldBe` [aesonQQ| {foo: 123} |]

    it "decodes via FromJSON using makeFieldJsonWrapperExplicit" $ do
      Aeson.parseEither Aeson.parseJSON [aesonQQ| {foo: 123} |] `shouldBe` Right (FooFieldExplicitJson $ review _FFoo 113)
    it "encodes via ToJSON using makeFieldJsonWrapperExplicit" $ do
      Aeson.toJSON (FooFieldExplicitJson $ review _FFoo 113) `shouldBe` [aesonQQ| {foo: 123} |]
    it "decodes via DefaultJsonFormat using makeFieldJsonWrapperExplicit" $ do
      ABE.parseValue @Void (fromJsonWithFormat defaultJsonFormat) [aesonQQ| {foo: 123} |] `shouldBe` Right (FooFieldExplicitJson $ review _FFoo 113)
    it "encodes via DefaultJsonFormat using makeFieldJsonWrapperExplicit" $ do
      toJsonWithFormat defaultJsonFormat (FooFieldExplicitJson $ review _FFoo 113) `shouldBe` [aesonQQ| {foo: 123} |]