gi-gtk-declarative-0.6.3: test/GI/Gtk/Declarative/PatchTest.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TupleSections #-}
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
module GI.Gtk.Declarative.PatchTest where
import Control.Exception.Safe
import Control.Monad ( foldM )
import Control.Monad.IO.Class
import qualified Data.Text as Text
import Data.Text ( Text )
import qualified GI.Gtk as Gtk
import GI.Gtk.Declarative
import GI.Gtk.Declarative.TestWidget
import GI.Gtk.Declarative.State
import GI.Gtk.Declarative.TestUtils
import Hedgehog
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
prop_history_of_prior_patches_has_no_effect_on_resulting_widget = property $ do
(first : intermediate) <- forAll (Gen.list (Range.linear 1 100) genTestWidget)
last' <- forAll genTestWidget
cover 10 "prior include nested widgets" (any isNested (first : intermediate))
cover 5 "last is nested widget" (isNested last')
-- Directly creating the 'last' widget.
direct <- assertRight =<< patchAllInNewWindow last' []
-- Creating and patching all prior widgets before patching with the 'last' widget.
afterOthers <- assertRight
=<< patchAllInNewWindow first (intermediate <> pure last')
-- They (converted back to TestWidgets) should be the same.
direct === afterOthers
-- And the result should be equal to the TestWidget we started with.
afterOthers === setDefaults last'
assertRight :: MonadTest m => Either Text a -> m a
assertRight (Left err) = annotate (Text.unpack err) >> failure
assertRight (Right a ) = pure a
patchAll :: SomeState -> Widget event -> [Widget event] -> IO SomeState
patchAll s1 w ws =
fst <$> foldM (\(s, w1) w2 -> (, w2) <$> patch' s w1 w2) (s1, w) ws
patchAllInNewWindow
:: MonadIO m => TestWidget -> [TestWidget] -> m (Either Text TestWidget)
patchAllInNewWindow first rest =
runUI . bracket (Gtk.new Gtk.Window []) #destroy $ \window -> do
firstState <- create (toTestWidget first)
#add window =<< someStateWidget firstState
Gtk.widgetShowAll window
lastState <- patchAll firstState
(toTestWidget first)
(map toTestWidget rest)
fromGtkWidget =<< someStateWidget lastState
-- * Test collection
tests :: IO Bool
tests = checkParallel $$(discover)