{-| 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))