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