packages feed

purview-0.2.0.0: test/DiffingSpec.hs

module DiffingSpec where

import Prelude hiding (div)
import Test.Hspec

import PrepareTree
import Purview
import Component
import Diffing

type DefaultAction = DirectedEvent String String

spec :: SpecWith ()
spec = parallel $ do

  describe "diff" $ do

    it "creates an update for differing text" $ do
      let
        oldTree = div [ text "night" ]
        newTree = div [ text "morning" ]

      diff Nothing [] oldTree newTree `shouldBe` [Update [0] (text "morning")]

    it "can do a nested update" $ do
      let
        oldTree = div [ div [ text "night" ] ]
        newTree = div [ div [ text "morning" ] ]

      diff Nothing [] oldTree newTree `shouldBe` [Update [0, 0] (text "morning")]

    it "says to update the whole underlying tree on added div" $ do
      let
        oldTree = div [ text "night" ]
        newTree = div [ div [ text "morning" ] ]

      diff Nothing [] oldTree newTree `shouldBe` [Update [0] (div [ text "morning" ])]

    describe "message handlers" $ do

      it "diffs handler children if the state is different" $ do
        let
          handler1 :: (String -> Purview String IO) -> Purview String IO
          handler1 = handler [] "initial state" (\action state -> (const $ state <> action, [] :: [DefaultAction]))
          handler2 = handler [] "different state" (\action state -> (const $ state <> action, [] :: [DefaultAction]))
          oldTree = div [ handler1 (const (text "the original")) ]
          newTree = div [ handler2 (const (text "this is different")) ]

        diff Nothing [] oldTree newTree `shouldBe`
          [ Update [0] (handler2 (const (text "this is different"))) ]

    describe "effect handlers" $ do

      it "diffs handler children if the state is different" $ do
        let
          handler1 :: (String -> Purview String IO) -> Purview String IO
          handler1 = effectHandler [] "initial state" (\action state -> pure $ (const $ state <> action, ([] :: [DirectedEvent String String])))
          handler2 = effectHandler [] "different state" (\action state -> pure $ (const $ state <> action, ([] :: [DirectedEvent String String])))
          oldTree = div [ handler1 (const (text "the original")) ]
          newTree = div [ handler2 (const (text "this is different")) ]

        diff Nothing [] oldTree newTree `shouldBe`
          [ Update [0] (handler2 (const (text "this is different")))
          , Update [0, 0] (text "this is different")
          ]

      it "continues going down the tree even if the state is the same at the top" $ do
        let
          handler1 :: (String -> Purview String IO) -> Purview String IO
          handler1 = effectHandler [] "initial state" (\action state -> pure $ (const $ state <> action, ([] :: [DirectedEvent String String])))
          handler2 = effectHandler [] "different state" (\action state -> pure $ (const $ state <> action, ([] :: [DirectedEvent String String])))
          oldTree = prepareTree $ div [ handler1 . const $ handler1 (const (text "the original")) ]
          newTree = prepareTree $ div [ handler1 . const $ handler2 (const (text "this is different")) ]

        diff (Just [0, 0]) [] oldTree newTree `shouldBe`
          [ Update [0, 0] (EffectHandler
                            (Just [0])
                            (Just [0, 0])
                            []
                            "different state"
                            (\action state -> pure $ (const $ state <> action, ([] :: [DirectedEvent String String])))
                            (const (text "this is different")))
          ]


main :: IO ()
main = hspec spec