{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE OverloadedStrings #-} module Encoder ( encoderTests , encodeImage , testImageDataType ) where import Control.Lens ((<&>), (?~)) import Test.Tasty (TestName, TestTree, testGroup) import Test.Tasty.HUnit (Assertion, testCase, (@?=)) import Data.Proxy (Proxy (..)) import Waargonaut.Encode (Encoder, Encoder') import qualified Waargonaut.Encode as E import Data.Text.Lazy (Text) import Types.Common (Image (..), Overlayed (..), testFudge, testImageDataType) import Waargonaut.Generic (GWaarg, mkEncoder, proxy) import Waargonaut.Types.Json (oat) testOptionalKeyValue :: Assertion testOptionalKeyValue = do let encoder = E.mapLikeObj $ \(a,b) -> E.atKey' "A" E.text a . E.atOptKey' "B" E.int b hasKey = ("bob", Just 33) withKey = "{\"A\":\"bob\",\"B\":33}" noKey = ("bob", Nothing) withoutKey = "{\"A\":\"bob\"}" E.simplePureEncodeTextNoSpaces encoder hasKey @?= withKey E.simplePureEncodeTextNoSpaces encoder noKey @?= withoutKey testImageEncodedNoSpaces :: Text testImageEncodedNoSpaces = "{\"Width\":800,\"Height\":600,\"Title\":\"View from 15th Floor\",\"Animated\":false,\"IDs\":[116,943,234,38793]}" -- | The recommended way of defining an Encoder is to be explicit. encodeImage :: Applicative f => Encoder f Image encodeImage = E.mapLikeObj $ \img -> E.intAt "Width" (_imageWidth img) . E.intAt "Height" (_imageHeight img) . E.textAt "Title" (_imageTitle img) . E.boolAt "Animated" (_imageAnimated img) . E.listAt E.int "IDs" (_imageIDs img) testFudgeEncodedWithConsName :: Text testFudgeEncodedWithConsName = "{\"fudgey\":\"Chocolate\"}" testOverlayed :: Overlayed testOverlayed = Overlayed "fred" testFudge testOverlayedOut :: Text testOverlayedOut = "{\"id\":\"fred\",\"fudgey\":\"Chocolate\"}" encodeOverlay :: Applicative f => Encoder f Overlayed encodeOverlay = E.encodeA $ \(Overlayed i f) -> E.runEncoder fudgeEnc f <&> oat "id" ?~ E.runPureEncoder E.text i where fudgeEnc = proxy mkEncoder (Proxy :: Proxy GWaarg) tCase :: TestName -> Encoder' a -> a -> Text -> TestTree tCase nm enc a expected = testCase nm $ E.simplePureEncodeTextNoSpaces enc a @?= expected encoderTests :: TestTree encoderTests = testGroup "Encoder" [ tCase "Image" encodeImage testImageDataType testImageEncodedNoSpaces , tCase "Image (Generic)" enc testImageDataType testImageEncodedNoSpaces , tCase "newtype - with constructor name" enc testFudge testFudgeEncodedWithConsName , tCase "Overlayed" encodeOverlay testOverlayed testOverlayedOut , testCase "Optional Key:Value" testOptionalKeyValue ] where enc = proxy mkEncoder (Proxy :: Proxy GWaarg)