packages feed

todoist-sdk-0.1.2.1: test/Web/Todoist/BuilderSpec.hs

{-# LANGUAGE ScopedTypeVariables #-}

module Web.Todoist.BuilderSpec (spec) where

import Test.Hspec (Spec, describe, it, shouldBe, shouldSatisfy)
import Web.Todoist.Domain.Project (ProjectCreate, createProjectBuilder)
import Web.Todoist.Util.Builder
    ( Builder
    , runBuilder
    , withDescription
    , withParentId
    )

import Data.Aeson (encode)
import Data.Bool (Bool (True))
import Data.Function (($))
import Data.Monoid (Monoid (mempty), (<>))
import GHC.Base (const)

spec :: Spec
spec = do
    describe "Builder Monoid instance" $ do
        it "satisfies left identity: mempty <> x = x" $ do
            let x = withDescription "test" <> withParentId "parent123"
            let seed = createProjectBuilder "Project"
            encode (runBuilder seed (mempty <> x)) `shouldBe` encode (runBuilder seed x)

        it "satisfies right identity: x <> mempty = x" $ do
            let x = withDescription "test" <> withParentId "parent123"
            let seed = createProjectBuilder "Project"
            encode (runBuilder seed (x <> mempty)) `shouldBe` encode (runBuilder seed x)

        it "satisfies associativity: (x <> y) <> z = x <> (y <> z)" $ do
            let x = withDescription "desc"
            let y = withParentId "parent1"
            let z = withParentId "parent2"
            let seed = createProjectBuilder "Project"
            encode (runBuilder seed ((x <> y) <> z)) `shouldBe` encode (runBuilder seed (x <> (y <> z)))

        it "mempty is the identity modification" $ do
            let seed = createProjectBuilder "Project"
            encode (runBuilder seed mempty)
                `shouldBe` encode (runBuilder seed (mempty :: Builder ProjectCreate))

    describe "Builder usage patterns" $ do
        it "can use mempty when no modifications needed" $ do
            let seed = createProjectBuilder "Project"
            let result = runBuilder seed mempty
            result `shouldSatisfy` const True -- Just verify it compiles and runs
        it "can compose multiple modifications" $ do
            let seed = createProjectBuilder "Project"
            let mods = withDescription "desc" <> withParentId "parent123"
            let result = runBuilder seed mods
            result `shouldSatisfy` const True