monomer-1.0.0.0: test/unit/Monomer/Widgets/Containers/SplitSpec.hs
{-|
Module : Monomer.Widgets.Containers.SplitSpec
Copyright : (c) 2018 Francisco Vallarino
License : BSD-3-Clause (see the LICENSE file)
Maintainer : fjvallarino@gmail.com
Stability : experimental
Portability : non-portable
Unit tests for Split widget.
-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
module Monomer.Widgets.Containers.SplitSpec (spec) where
import Control.Lens ((&), (^.), (.~))
import Control.Lens.TH (abbreviatedFields, makeLensesWith)
import Data.Default
import Data.Sequence (Seq(..))
import Data.Text (Text)
import Test.Hspec
import qualified Data.Sequence as Seq
import Monomer.Core
import Monomer.Core.Combinators
import Monomer.Event
import Monomer.TestUtil
import Monomer.TestEventUtil
import Monomer.Widgets.Containers.Split
import Monomer.Widgets.Singles.Button
import qualified Monomer.Lens as L
data TestEvt
= SliderChanged Double
| Button1
| Button2
deriving (Eq, Show)
newtype TestModel = TestModel {
_tmSliderPos :: Double
} deriving (Eq, Show)
makeLensesWith abbreviatedFields ''TestModel
spec :: Spec
spec = describe "Split" $ do
handleEventMouseDragH
handleEventMouseDragV
getSizeReq
handleEventMouseDragH :: Spec
handleEventMouseDragH = describe "handleEventMouseDragH" $ do
it "should drag left 100 pixels, moving the slider" $ do
let selStart = Point 320 240
let selEnd = Point 220 100
let steps = evtDrag selStart selEnd
model steps ^. sliderPos `shouldBe` (220 / 640)
areas steps `shouldBe` Seq.fromList [Rect 0 0 218 480, Rect 223 0 417 480]
it "should drag left 200 pixels, but move the slider only 120" $ do
let selStart = Point 320 240
let selEnd = Point 120 100
let steps = evtDrag selStart selEnd
model steps ^. sliderPos `shouldBe` (200 / 640)
areas steps `shouldBe` Seq.fromList [Rect 0 0 198 480, Rect 203 0 437 480]
it "should drag right 100 pixels, but move the slider only 80" $ do
let selStart = Point 320 240
let selEnd = Point 420 100
let steps = evtDrag selStart selEnd
model steps ^. sliderPos `shouldBe` (400 / 640)
areas steps `shouldBe` Seq.fromList [Rect 0 0 397 480, Rect 402 0 238 480]
it "should drag up 100 pixels, keeping the slider intact" $ do
let selStart = Point 320 240
let selEnd = Point 320 140
let steps = evtDrag selStart selEnd
model steps ^. sliderPos `shouldBe` 0.5
areas steps `shouldBe` Seq.fromList [Rect 0 0 318 480, Rect 322 0 318 480]
it "should drag down 100 pixels, keeping the slider intact" $ do
let selStart = Point 320 240
let selEnd = Point 320 340
let steps = evtDrag selStart selEnd
model steps ^. sliderPos `shouldBe` 0.5
areas steps `shouldBe` Seq.fromList [Rect 0 0 318 480, Rect 322 0 318 480]
where
wenv = mockWenv (TestModel 0.5)
btn1 = button "Text" Button1 `styleBasic` [rangeWidth 200 400]
btn2 = button "Longer" Button2 `styleBasic` [expandWidth 60]
splitNode = hsplit_ [splitHandlePos sliderPos] (btn1, btn2)
model es = nodeHandleEventModel wenv es splitNode
areas es = vp where
root = nodeHandleEventRoot wenv es splitNode
vp = fmap (roundRectUnits . _wniViewport . _wnInfo) (root ^. L.children)
handleEventMouseDragV :: Spec
handleEventMouseDragV = describe "handleEventMouseDragV" $ do
it "should drag up 100 pixels, moving the slider" $ do
let selStart = Point 320 240
let selEnd = Point 320 140
let steps = evtDrag selStart selEnd
evts steps `shouldBe` Seq.fromList [SliderChanged 0.5, SliderChanged (140 / 480)]
areas steps `shouldBe` Seq.fromList [Rect 0 0 640 139, Rect 0 144 640 336]
it "should drag up 200 pixels, but move the slider only 100" $ do
let selStart = Point 320 240
let selEnd = Point 320 40
let steps = evtDrag selStart selEnd
evts steps `shouldBe` Seq.fromList [SliderChanged 0.5, SliderChanged (80 / 480)]
areas steps `shouldBe` Seq.fromList [Rect 0 0 640 79, Rect 0 84 640 396]
it "should drag down 100 pixels, but move the slider only 40" $ do
let selStart = Point 320 240
let selEnd = Point 320 340
let steps = evtDrag selStart selEnd
evts steps `shouldBe` Seq.fromList [SliderChanged 0.5, SliderChanged (280 / 480)]
areas steps `shouldBe` Seq.fromList [Rect 0 0 640 277, Rect 0 282 640 198]
it "should drag left 100 pixels, keeping the slider intact" $ do
let selStart = Point 320 240
let selEnd = Point 220 240
let steps = evtDrag selStart selEnd
evts steps `shouldBe` Seq.fromList [SliderChanged 0.5]
areas steps `shouldBe` Seq.fromList [Rect 0 0 640 238, Rect 0 242 640 238]
it "should drag right 100 pixels, keeping the slider intact" $ do
let selStart = Point 320 240
let selEnd = Point 420 240
let steps = evtDrag selStart selEnd
evts steps `shouldBe` Seq.fromList [SliderChanged 0.5]
areas steps `shouldBe` Seq.fromList [Rect 0 0 640 238, Rect 0 242 640 238]
where
wenv = mockWenv (TestModel 0.5)
-- Uses flexHeight otherwise buttons are fixed size and split will not move
btn1 = button "Text" Button1 `styleBasic` [flexHeight 20]
btn2 = button "Longer" Button2 `styleBasic` [rangeHeight 200 400]
splitNode = vsplit_ [splitHandlePosV 0.5, onChange SliderChanged] (btn1, btn2)
evts es = nodeHandleEventEvts wenv es splitNode
areas es = vp where
root = nodeHandleEventRoot wenv es splitNode
vp = fmap (roundRectUnits . _wniViewport . _wnInfo) (root ^. L.children)
getSizeReq :: Spec
getSizeReq = describe "getSizeReq" $ do
it "should return width = Range 5 125 0.01" $
hsizeReqW `shouldBe` SizeReq 5 120 120 1
it "should return height = Fixed 20" $
hsizeReqH `shouldBe` fixedSize 20
it "should return width = Expand 60 1" $
vsizeReqW `shouldBe` expandSize 60 1
it "should return height = Fixed 45" $
vsizeReqH `shouldBe` fixedSize 45
where
wenv = mockWenv (TestModel 0)
btn1 = button "Button" Button1 `styleBasic` [expandWidth 60]
btn2 = button "Button" Button2 `styleBasic` [expandWidth 60]
(hsizeReqW, hsizeReqH) = nodeGetSizeReq wenv (hsplit (btn1, btn2))
(vsizeReqW, vsizeReqH) = nodeGetSizeReq wenv (vsplit (btn1, btn2))