Merge pull request #1764 from parsonsmatt/matt/yesod-test-expose-sio

Expose SIO type
This commit is contained in:
Michael Snoyman 2022-04-18 09:09:09 +03:00 committed by GitHub
commit 4f962c9073
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 99 additions and 38 deletions

View File

@ -1,5 +1,9 @@
# ChangeLog for yesod-test # ChangeLog for yesod-test
## 1.6.13
* Add `Yesod.Test.Internal.SIO` module to expose the `SIO` type.
## 1.6.12 ## 1.6.12
* Fix import in cookie example [#1713](https://github.com/yesodweb/yesod/pull/1713) * Fix import in cookie example [#1713](https://github.com/yesodweb/yesod/pull/1713)

View File

@ -243,10 +243,7 @@ import Data.CaseInsensitive (CI)
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import Network.Wai import Network.Wai
import Network.Wai.Test hiding (assertHeader, assertNoHeader, request) import Network.Wai.Test hiding (assertHeader, assertNoHeader, request)
import Control.Monad.Trans.Reader (ReaderT (..))
import Conduit (MonadThrow)
import Control.Monad.IO.Class import Control.Monad.IO.Class
import qualified Control.Monad.State.Class as MS
import System.IO import System.IO
import Yesod.Core.Unsafe (runFakeHandler) import Yesod.Core.Unsafe (runFakeHandler)
import Yesod.Test.TransversingCSS import Yesod.Test.TransversingCSS
@ -257,7 +254,6 @@ import Text.XML.Cursor hiding (element)
import qualified Text.XML.Cursor as C import qualified Text.XML.Cursor as C
import qualified Text.HTML.DOM as HD import qualified Text.HTML.DOM as HD
import Control.Monad.Trans.Writer import Control.Monad.Trans.Writer
import Data.IORef
import qualified Data.Map as M import qualified Data.Map as M
import qualified Web.Cookie as Cookie import qualified Web.Cookie as Cookie
import qualified Blaze.ByteString.Builder as Builder import qualified Blaze.ByteString.Builder as Builder
@ -281,6 +277,7 @@ import Data.Aeson (FromJSON, eitherDecode')
import Control.Monad (unless) import Control.Monad (unless)
import Yesod.Test.Internal (getBodyTextPreview, contentTypeHeaderIsUtf8) import Yesod.Test.Internal (getBodyTextPreview, contentTypeHeaderIsUtf8)
import Yesod.Test.Internal.SIO
{-# DEPRECATED byLabel "This function seems to have multiple bugs (ref: https://github.com/yesodweb/yesod/pull/1459). Use byLabelExact, byLabelContain, byLabelPrefix or byLabelSuffix instead" #-} {-# DEPRECATED byLabel "This function seems to have multiple bugs (ref: https://github.com/yesodweb/yesod/pull/1459). Use byLabelExact, byLabelContain, byLabelPrefix or byLabelSuffix instead" #-}
{-# DEPRECATED fileByLabel "This function seems to have multiple bugs (ref: https://github.com/yesodweb/yesod/pull/1459). Use fileByLabelExact, fileByLabelContain, fileByLabelPrefix or fileByLabelSuffix instead" #-} {-# DEPRECATED fileByLabel "This function seems to have multiple bugs (ref: https://github.com/yesodweb/yesod/pull/1459). Use fileByLabelExact, fileByLabelContain, fileByLabelPrefix or fileByLabelSuffix instead" #-}
@ -1596,32 +1593,3 @@ instance YesodDispatch site => Hspec.Example (SIO (YesodExampleData site) a) whe
return ()) return ())
params params
($ ()) ($ ())
-- | State + IO
--
-- @since 1.6.0
newtype SIO s a = SIO (ReaderT (IORef s) IO a)
deriving (Functor, Applicative, Monad, MonadIO, MonadThrow, MonadUnliftIO)
instance MS.MonadState s (SIO s)
where
get = getSIO
put = putSIO
getSIO :: SIO s s
getSIO = SIO $ ReaderT readIORef
putSIO :: s -> SIO s ()
putSIO s = SIO $ ReaderT $ \ref -> writeIORef ref $! s
modifySIO :: (s -> s) -> SIO s ()
modifySIO f = SIO $ ReaderT $ \ref -> modifyIORef' ref f
evalSIO :: SIO s a -> s -> IO a
evalSIO (SIO (ReaderT f)) s = newIORef s >>= f
execSIO :: SIO s () -> s -> IO s
execSIO (SIO (ReaderT f)) s = do
ref <- newIORef s
f ref
readIORef ref

View File

@ -0,0 +1,88 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ImplicitParams #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
-- | The 'SIO' type is used by "Yesod.Test" to provide exception-safe
-- environment between requests and assertions.
--
-- This module is internal. Breaking changes to this module will not be
-- reflected in the major version of this package.
--
-- @since 1.6.13
module Yesod.Test.Internal.SIO where
import Control.Monad.Trans.Reader (ReaderT (..))
import Conduit (MonadThrow)
import qualified Control.Monad.State.Class as MS
import Yesod.Core
import Data.IORef
-- | State + IO
--
-- @since 1.6.0
newtype SIO s a = SIO (ReaderT (IORef s) IO a)
deriving (Functor, Applicative, Monad, MonadIO, MonadThrow, MonadUnliftIO)
instance MS.MonadState s (SIO s)
where
get = getSIO
put = putSIO
-- | Retrieve the current state in the 'SIO' type.
--
-- Equivalent to 'MS.get'
--
-- @since 1.6.13
getSIO :: SIO s s
getSIO = SIO $ ReaderT readIORef
-- | Put the given @s@ into the 'SIO' state for later retrieval.
--
-- Equivalent to 'MS.put', but the value is evaluated to weak head normal
-- form.
--
-- @since 1.6.13
putSIO :: s -> SIO s ()
putSIO s = SIO $ ReaderT $ \ref -> writeIORef ref $! s
-- | Modify the underlying @s@ state.
--
-- This is strict in the function used, and is equivalent to 'MS.modify''.
--
-- @since 1.6.13
modifySIO :: (s -> s) -> SIO s ()
modifySIO f = SIO $ ReaderT $ \ref -> modifyIORef' ref f
-- | Run an 'SIO' action with the intial state @s@ provided, returning the
-- result, and discard the final state.
--
-- @since 1.6.13
evalSIO :: SIO s a -> s -> IO a
evalSIO action =
fmap snd . runSIO action
-- | Run an 'SIO' action with the initial state @s@ provided, returning the
-- final state, and discarding the result.
--
-- @since 1.6.13
execSIO :: SIO s () -> s -> IO s
execSIO action =
fmap fst . runSIO action
-- | Run an 'SIO' action with the initial state provided, returning both
-- the result of the computation as well as the final state.
--
-- @since 1.6.13
runSIO :: SIO s a -> s -> IO (s, a)
runSIO (SIO (ReaderT f)) s = do
ref <- newIORef s
a <- f ref
s' <- readIORef ref
pure (s', a)

View File

@ -1,5 +1,5 @@
name: yesod-test name: yesod-test
version: 1.6.12 version: 1.6.13
license: MIT license: MIT
license-file: LICENSE license-file: LICENSE
author: Nubis <nubis@woobiz.com.ar> author: Nubis <nubis@woobiz.com.ar>
@ -46,6 +46,7 @@ library
Yesod.Test.CssQuery Yesod.Test.CssQuery
Yesod.Test.TransversingCSS Yesod.Test.TransversingCSS
Yesod.Test.Internal Yesod.Test.Internal
Yesod.Test.Internal.SIO
ghc-options: -Wall ghc-options: -Wall
test-suite test test-suite test