Merge pull request #1341 from yesodweb/pedantic
Compile with -Wall -Werror
This commit is contained in:
commit
52f67fb04b
@ -178,9 +178,9 @@ script:
|
|||||||
if [ `uname` = "Darwin" ]
|
if [ `uname` = "Darwin" ]
|
||||||
then
|
then
|
||||||
# Use slightly less intensive options on OS X due to Travis timeouts
|
# Use slightly less intensive options on OS X due to Travis timeouts
|
||||||
stack --no-terminal $ARGS test --fast
|
stack --no-terminal $ARGS test --fast --pedantic
|
||||||
else
|
else
|
||||||
stack --no-terminal $ARGS test --bench --no-run-benchmarks --haddock --no-haddock-deps
|
stack --no-terminal $ARGS test --bench --no-run-benchmarks --haddock --no-haddock-deps --pedantic
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
cabal)
|
cabal)
|
||||||
|
|||||||
@ -10,7 +10,7 @@ module Yesod.Auth.OAuth
|
|||||||
, tumblrUrl
|
, tumblrUrl
|
||||||
, module Web.Authenticate.OAuth
|
, module Web.Authenticate.OAuth
|
||||||
) where
|
) where
|
||||||
import Control.Applicative ((<$>), (<*>))
|
import Control.Applicative as A ((<$>), (<*>))
|
||||||
import Control.Arrow ((***))
|
import Control.Arrow ((***))
|
||||||
import Control.Exception.Lifted
|
import Control.Exception.Lifted
|
||||||
import Control.Monad.IO.Class
|
import Control.Monad.IO.Class
|
||||||
@ -66,8 +66,8 @@ authOAuth oauth mkCreds = AuthPlugin name dispatch login
|
|||||||
]
|
]
|
||||||
else do
|
else do
|
||||||
(verifier, oaTok) <-
|
(verifier, oaTok) <-
|
||||||
runInputGet $ (,) <$> ireq textField "oauth_verifier"
|
runInputGet $ (,) A.<$> ireq textField "oauth_verifier"
|
||||||
<*> ireq textField "oauth_token"
|
A.<*> ireq textField "oauth_token"
|
||||||
return $ Credential [ ("oauth_verifier", encodeUtf8 verifier)
|
return $ Credential [ ("oauth_verifier", encodeUtf8 verifier)
|
||||||
, ("oauth_token", encodeUtf8 oaTok)
|
, ("oauth_token", encodeUtf8 oaTok)
|
||||||
, ("oauth_token_secret", encodeUtf8 tokSec)
|
, ("oauth_token_secret", encodeUtf8 tokSec)
|
||||||
@ -83,7 +83,7 @@ authOAuth oauth mkCreds = AuthPlugin name dispatch login
|
|||||||
let oaUrl = render $ tm $ oauthUrl name
|
let oaUrl = render $ tm $ oauthUrl name
|
||||||
[whamlet| <a href=#{oaUrl}>Login via #{name} |]
|
[whamlet| <a href=#{oaUrl}>Login via #{name} |]
|
||||||
|
|
||||||
mkExtractCreds :: YesodAuth m => Text -> String -> Credential -> IO (Creds m)
|
mkExtractCreds :: Text -> String -> Credential -> IO (Creds m)
|
||||||
mkExtractCreds name idName (Credential dic) = do
|
mkExtractCreds name idName (Credential dic) = do
|
||||||
let mcrId = decodeUtf8With lenientDecode <$> lookup (encodeUtf8 $ T.pack idName) dic
|
let mcrId = decodeUtf8With lenientDecode <$> lookup (encodeUtf8 $ T.pack idName) dic
|
||||||
case mcrId of
|
case mcrId of
|
||||||
|
|||||||
@ -167,7 +167,7 @@ class (Yesod master, PathPiece (AuthId master), RenderMessage master FormMessage
|
|||||||
-- > lift $ redirect HomeR -- or any other Handler code you want
|
-- > lift $ redirect HomeR -- or any other Handler code you want
|
||||||
-- > defaultLoginHandler
|
-- > defaultLoginHandler
|
||||||
--
|
--
|
||||||
loginHandler :: AuthHandler master Html
|
loginHandler :: HandlerT Auth (HandlerT master IO) Html
|
||||||
loginHandler = defaultLoginHandler
|
loginHandler = defaultLoginHandler
|
||||||
|
|
||||||
-- | Used for i18n of messages provided by this package.
|
-- | Used for i18n of messages provided by this package.
|
||||||
@ -227,7 +227,7 @@ class (Yesod master, PathPiece (AuthId master), RenderMessage master FormMessage
|
|||||||
-- This is an experimental API that is not broadly used throughout the yesod-auth code base
|
-- This is an experimental API that is not broadly used throughout the yesod-auth code base
|
||||||
runHttpRequest :: Request -> (Response BodyReader -> HandlerT master IO a) -> HandlerT master IO a
|
runHttpRequest :: Request -> (Response BodyReader -> HandlerT master IO a) -> HandlerT master IO a
|
||||||
runHttpRequest req inner = do
|
runHttpRequest req inner = do
|
||||||
man <- authHttpManager <$> getYesod
|
man <- authHttpManager Control.Applicative.<$> getYesod
|
||||||
HandlerT $ \t -> withResponse req man $ \res -> unHandlerT (inner res) t
|
HandlerT $ \t -> withResponse req man $ \res -> unHandlerT (inner res) t
|
||||||
|
|
||||||
{-# MINIMAL loginDest, logoutDest, (authenticate | getAuthId), authPlugins, authHttpManager #-}
|
{-# MINIMAL loginDest, logoutDest, (authenticate | getAuthId), authPlugins, authHttpManager #-}
|
||||||
|
|||||||
@ -131,8 +131,7 @@ import Data.Time (addUTCTime, getCurrentTime)
|
|||||||
import Safe (readMay)
|
import Safe (readMay)
|
||||||
import System.IO.Unsafe (unsafePerformIO)
|
import System.IO.Unsafe (unsafePerformIO)
|
||||||
import qualified Text.Email.Validate
|
import qualified Text.Email.Validate
|
||||||
import Network.HTTP.Types.Status (status400)
|
import Data.Aeson.Types (Parser, Result(..), parseMaybe, withObject, (.:?))
|
||||||
import Data.Aeson.Types (Parser(..), Result(..), parseMaybe, withObject, (.:?))
|
|
||||||
import Data.Maybe (isJust, isNothing, fromJust)
|
import Data.Maybe (isJust, isNothing, fromJust)
|
||||||
|
|
||||||
loginR, registerR, forgotPasswordR, setpassR :: AuthRoute
|
loginR, registerR, forgotPasswordR, setpassR :: AuthRoute
|
||||||
@ -170,10 +169,10 @@ data EmailCreds site = EmailCreds
|
|||||||
, emailCredsEmail :: Email
|
, emailCredsEmail :: Email
|
||||||
}
|
}
|
||||||
|
|
||||||
data ForgotPasswordForm = ForgotPasswordForm { forgotEmail :: Text }
|
data ForgotPasswordForm = ForgotPasswordForm { _forgotEmail :: Text }
|
||||||
data PasswordForm = PasswordForm { passwordCurrent :: Text, passwordNew :: Text, passwordConfirm :: Text }
|
data PasswordForm = PasswordForm { _passwordCurrent :: Text, _passwordNew :: Text, _passwordConfirm :: Text }
|
||||||
data UserForm = UserForm { email :: Text }
|
data UserForm = UserForm { _userFormEmail :: Text }
|
||||||
data UserLoginForm = UserLoginForm { loginEmail :: Text, loginPassword :: Text }
|
data UserLoginForm = UserLoginForm { _loginEmail :: Text, _loginPassword :: Text }
|
||||||
|
|
||||||
class ( YesodAuth site
|
class ( YesodAuth site
|
||||||
, PathPiece (AuthEmailId site)
|
, PathPiece (AuthEmailId site)
|
||||||
@ -298,7 +297,7 @@ class ( YesodAuth site
|
|||||||
-- Default: 'defaultRegisterHandler'.
|
-- Default: 'defaultRegisterHandler'.
|
||||||
--
|
--
|
||||||
-- @since: 1.2.6
|
-- @since: 1.2.6
|
||||||
registerHandler :: AuthHandler site Html
|
registerHandler :: HandlerT Auth (HandlerT site IO) Html
|
||||||
registerHandler = defaultRegisterHandler
|
registerHandler = defaultRegisterHandler
|
||||||
|
|
||||||
-- | Handler called to render the \"forgot password\" page.
|
-- | Handler called to render the \"forgot password\" page.
|
||||||
@ -308,7 +307,7 @@ class ( YesodAuth site
|
|||||||
-- Default: 'defaultForgotPasswordHandler'.
|
-- Default: 'defaultForgotPasswordHandler'.
|
||||||
--
|
--
|
||||||
-- @since: 1.2.6
|
-- @since: 1.2.6
|
||||||
forgotPasswordHandler :: AuthHandler site Html
|
forgotPasswordHandler :: HandlerT Auth (HandlerT site IO) Html
|
||||||
forgotPasswordHandler = defaultForgotPasswordHandler
|
forgotPasswordHandler = defaultForgotPasswordHandler
|
||||||
|
|
||||||
-- | Handler called to render the \"set password\" page. The
|
-- | Handler called to render the \"set password\" page. The
|
||||||
@ -324,7 +323,7 @@ class ( YesodAuth site
|
|||||||
-- field for the old password should be presented.
|
-- field for the old password should be presented.
|
||||||
-- Otherwise, just two fields for the new password are
|
-- Otherwise, just two fields for the new password are
|
||||||
-- needed.
|
-- needed.
|
||||||
-> AuthHandler site TypedContent
|
-> HandlerT Auth (HandlerT site IO) TypedContent
|
||||||
setPasswordHandler = defaultSetPasswordHandler
|
setPasswordHandler = defaultSetPasswordHandler
|
||||||
|
|
||||||
authEmail :: (YesodAuthEmail m) => AuthPlugin m
|
authEmail :: (YesodAuthEmail m) => AuthPlugin m
|
||||||
@ -352,7 +351,7 @@ emailLoginHandler toParent = do
|
|||||||
(widget, enctype) <- liftWidgetT $ generateFormPost loginForm
|
(widget, enctype) <- liftWidgetT $ generateFormPost loginForm
|
||||||
|
|
||||||
[whamlet|
|
[whamlet|
|
||||||
<form method="post" action="@{toParent loginR}">
|
<form method="post" action="@{toParent loginR}", enctype=#{enctype}>
|
||||||
<div id="emailLoginForm">
|
<div id="emailLoginForm">
|
||||||
^{widget}
|
^{widget}
|
||||||
<div>
|
<div>
|
||||||
@ -371,7 +370,8 @@ emailLoginHandler toParent = do
|
|||||||
passwordMsg <- renderMessage' Msg.Password
|
passwordMsg <- renderMessage' Msg.Password
|
||||||
(passwordRes, passwordView) <- mreq passwordField (passwordSettings passwordMsg) Nothing
|
(passwordRes, passwordView) <- mreq passwordField (passwordSettings passwordMsg) Nothing
|
||||||
|
|
||||||
let userRes = UserLoginForm <$> emailRes <*> passwordRes
|
let userRes = UserLoginForm Control.Applicative.<$> emailRes
|
||||||
|
Control.Applicative.<*> passwordRes
|
||||||
let widget = do
|
let widget = do
|
||||||
[whamlet|
|
[whamlet|
|
||||||
#{extra}
|
#{extra}
|
||||||
@ -405,7 +405,7 @@ emailLoginHandler toParent = do
|
|||||||
-- | Default implementation of 'registerHandler'.
|
-- | Default implementation of 'registerHandler'.
|
||||||
--
|
--
|
||||||
-- @since 1.2.6
|
-- @since 1.2.6
|
||||||
defaultRegisterHandler :: YesodAuthEmail master => AuthHandler master Html
|
defaultRegisterHandler :: YesodAuthEmail master => HandlerT Auth (HandlerT master IO) Html
|
||||||
defaultRegisterHandler = do
|
defaultRegisterHandler = do
|
||||||
(widget, enctype) <- lift $ generateFormPost registrationForm
|
(widget, enctype) <- lift $ generateFormPost registrationForm
|
||||||
toParentRoute <- getRouteToParent
|
toParentRoute <- getRouteToParent
|
||||||
@ -502,7 +502,7 @@ getForgotPasswordR = forgotPasswordHandler
|
|||||||
-- | Default implementation of 'forgotPasswordHandler'.
|
-- | Default implementation of 'forgotPasswordHandler'.
|
||||||
--
|
--
|
||||||
-- @since 1.2.6
|
-- @since 1.2.6
|
||||||
defaultForgotPasswordHandler :: YesodAuthEmail master => AuthHandler master Html
|
defaultForgotPasswordHandler :: YesodAuthEmail master => HandlerT Auth (HandlerT master IO) Html
|
||||||
defaultForgotPasswordHandler = do
|
defaultForgotPasswordHandler = do
|
||||||
(widget, enctype) <- lift $ generateFormPost forgotPasswordForm
|
(widget, enctype) <- lift $ generateFormPost forgotPasswordForm
|
||||||
toParent <- getRouteToParent
|
toParent <- getRouteToParent
|
||||||
@ -603,21 +603,21 @@ postLoginR = do
|
|||||||
, emailCredsEmail <$> mecreds
|
, emailCredsEmail <$> mecreds
|
||||||
, emailCredsStatus <$> mecreds
|
, emailCredsStatus <$> mecreds
|
||||||
) of
|
) of
|
||||||
(Just aid, Just email, Just True) -> do
|
(Just aid, Just email', Just True) -> do
|
||||||
mrealpass <- lift $ getPassword aid
|
mrealpass <- lift $ getPassword aid
|
||||||
case mrealpass of
|
case mrealpass of
|
||||||
Nothing -> return Nothing
|
Nothing -> return Nothing
|
||||||
Just realpass -> return $ if isValidPass pass realpass
|
Just realpass -> return $ if isValidPass pass realpass
|
||||||
then Just email
|
then Just email'
|
||||||
else Nothing
|
else Nothing
|
||||||
_ -> return Nothing
|
_ -> return Nothing
|
||||||
let isEmail = Text.Email.Validate.isValid $ encodeUtf8 identifier
|
let isEmail = Text.Email.Validate.isValid $ encodeUtf8 identifier
|
||||||
case maid of
|
case maid of
|
||||||
Just email ->
|
Just email' ->
|
||||||
lift $ setCredsRedirect $ Creds
|
lift $ setCredsRedirect $ Creds
|
||||||
(if isEmail then "email" else "username")
|
(if isEmail then "email" else "username")
|
||||||
email
|
email'
|
||||||
[("verifiedEmail", email)]
|
[("verifiedEmail", email')]
|
||||||
Nothing ->
|
Nothing ->
|
||||||
loginErrorMessageI LoginR $
|
loginErrorMessageI LoginR $
|
||||||
if isEmail
|
if isEmail
|
||||||
@ -636,22 +636,22 @@ getPasswordR = do
|
|||||||
-- | Default implementation of 'setPasswordHandler'.
|
-- | Default implementation of 'setPasswordHandler'.
|
||||||
--
|
--
|
||||||
-- @since 1.2.6
|
-- @since 1.2.6
|
||||||
defaultSetPasswordHandler :: YesodAuthEmail master => Bool -> AuthHandler master TypedContent
|
defaultSetPasswordHandler :: YesodAuthEmail master => Bool -> HandlerT Auth (HandlerT master IO) TypedContent
|
||||||
defaultSetPasswordHandler needOld = do
|
defaultSetPasswordHandler needOld = do
|
||||||
messageRender <- lift getMessageRender
|
messageRender <- lift getMessageRender
|
||||||
toParent <- getRouteToParent
|
toParent <- getRouteToParent
|
||||||
selectRep $ do
|
selectRep $ do
|
||||||
provideJsonMessage $ messageRender Msg.SetPass
|
provideJsonMessage $ messageRender Msg.SetPass
|
||||||
provideRep $ lift $ authLayout $ do
|
provideRep $ lift $ authLayout $ do
|
||||||
(widget, enctype) <- liftWidgetT $ generateFormPost $ setPasswordForm needOld
|
(widget, enctype) <- liftWidgetT $ generateFormPost setPasswordForm
|
||||||
setTitleI Msg.SetPassTitle
|
setTitleI Msg.SetPassTitle
|
||||||
[whamlet|
|
[whamlet|
|
||||||
<h3>_{Msg.SetPass}
|
<h3>_{Msg.SetPass}
|
||||||
<form method="post" action="@{toParent setpassR}">
|
<form method="post" action="@{toParent setpassR}" enctype=#{enctype}>
|
||||||
^{widget}
|
^{widget}
|
||||||
|]
|
|]
|
||||||
where
|
where
|
||||||
setPasswordForm needOld extra = do
|
setPasswordForm extra = do
|
||||||
(currentPasswordRes, currentPasswordView) <- mreq passwordField currentPasswordSettings Nothing
|
(currentPasswordRes, currentPasswordView) <- mreq passwordField currentPasswordSettings Nothing
|
||||||
(newPasswordRes, newPasswordView) <- mreq passwordField newPasswordSettings Nothing
|
(newPasswordRes, newPasswordView) <- mreq passwordField newPasswordSettings Nothing
|
||||||
(confirmPasswordRes, confirmPasswordView) <- mreq passwordField confirmPasswordSettings Nothing
|
(confirmPasswordRes, confirmPasswordView) <- mreq passwordField confirmPasswordSettings Nothing
|
||||||
@ -823,7 +823,10 @@ loginLinkKey = "_AUTH_EMAIL_LOGIN_LINK"
|
|||||||
-- | Set 'loginLinkKey' to the current time.
|
-- | Set 'loginLinkKey' to the current time.
|
||||||
--
|
--
|
||||||
-- @since 1.2.1
|
-- @since 1.2.1
|
||||||
setLoginLinkKey :: (YesodAuthEmail site, MonadHandler m, HandlerSite m ~ site) => AuthId site -> m ()
|
--setLoginLinkKey :: (MonadHandler m) => AuthId site -> m ()
|
||||||
|
setLoginLinkKey :: (MonadHandler m, YesodAuthEmail (HandlerSite m))
|
||||||
|
=> AuthId (HandlerSite m)
|
||||||
|
-> m ()
|
||||||
setLoginLinkKey aid = do
|
setLoginLinkKey aid = do
|
||||||
now <- liftIO getCurrentTime
|
now <- liftIO getCurrentTime
|
||||||
setSession loginLinkKey $ TS.pack $ show (toPathPiece aid, now)
|
setSession loginLinkKey $ TS.pack $ show (toPathPiece aid, now)
|
||||||
|
|||||||
@ -71,7 +71,7 @@ authGoogleEmail =
|
|||||||
completeHelper posts
|
completeHelper posts
|
||||||
dispatch _ _ = notFound
|
dispatch _ _ = notFound
|
||||||
|
|
||||||
completeHelper :: YesodAuth master => [(Text, Text)] -> AuthHandler master TypedContent
|
completeHelper :: [(Text, Text)] -> AuthHandler master TypedContent
|
||||||
completeHelper gets' = do
|
completeHelper gets' = do
|
||||||
master <- lift getYesod
|
master <- lift getYesod
|
||||||
eres <- lift $ try $ OpenId.authenticateClaimed gets' (authHttpManager master)
|
eres <- lift $ try $ OpenId.authenticateClaimed gets' (authHttpManager master)
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
{-# LANGUAGE CPP #-}
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
@ -59,7 +60,7 @@ import Yesod.Core (HandlerSite, HandlerT, MonadHandler,
|
|||||||
lift, liftIO, lookupGetParam,
|
lift, liftIO, lookupGetParam,
|
||||||
lookupSession, notFound, redirect,
|
lookupSession, notFound, redirect,
|
||||||
setSession, whamlet, (.:),
|
setSession, whamlet, (.:),
|
||||||
addMessage, getYesod, authRoute,
|
addMessage, getYesod,
|
||||||
toHtml)
|
toHtml)
|
||||||
|
|
||||||
|
|
||||||
@ -85,8 +86,9 @@ import qualified Data.Text as T
|
|||||||
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
|
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
|
||||||
import qualified Data.Text.Lazy as TL
|
import qualified Data.Text.Lazy as TL
|
||||||
import qualified Data.Text.Lazy.Builder as TL
|
import qualified Data.Text.Lazy.Builder as TL
|
||||||
import Network.HTTP.Client (Manager, parseUrl, requestHeaders,
|
import Network.HTTP.Client (Manager, requestHeaders,
|
||||||
responseBody, urlEncodedBody)
|
responseBody, urlEncodedBody)
|
||||||
|
import qualified Network.HTTP.Client as HTTP
|
||||||
import Network.HTTP.Client.Conduit (Request, bodyReaderSource)
|
import Network.HTTP.Client.Conduit (Request, bodyReaderSource)
|
||||||
import Network.HTTP.Conduit (http)
|
import Network.HTTP.Conduit (http)
|
||||||
import Network.HTTP.Types (renderQueryText)
|
import Network.HTTP.Types (renderQueryText)
|
||||||
@ -167,7 +169,7 @@ authPlugin storeToken clientID clientSecret =
|
|||||||
return $ decodeUtf8
|
return $ decodeUtf8
|
||||||
$ toByteString
|
$ toByteString
|
||||||
$ fromByteString "https://accounts.google.com/o/oauth2/auth"
|
$ fromByteString "https://accounts.google.com/o/oauth2/auth"
|
||||||
`mappend` renderQueryText True qs
|
`Data.Monoid.mappend` renderQueryText True qs
|
||||||
|
|
||||||
login tm = do
|
login tm = do
|
||||||
[whamlet|<a href=@{tm forwardUrl}>_{Msg.LoginGoogle}|]
|
[whamlet|<a href=@{tm forwardUrl}>_{Msg.LoginGoogle}|]
|
||||||
@ -206,7 +208,13 @@ authPlugin storeToken clientID clientSecret =
|
|||||||
|
|
||||||
render <- getUrlRender
|
render <- getUrlRender
|
||||||
|
|
||||||
req' <- liftIO $ parseUrl "https://accounts.google.com/o/oauth2/token" -- FIXME don't hardcode, use: https://accounts.google.com/.well-known/openid-configuration
|
req' <- liftIO $
|
||||||
|
#if MIN_VERSION_http_client(0,4,30)
|
||||||
|
HTTP.parseUrlThrow
|
||||||
|
#else
|
||||||
|
HTTP.parseUrl
|
||||||
|
#endif
|
||||||
|
"https://accounts.google.com/o/oauth2/token" -- FIXME don't hardcode, use: https://accounts.google.com/.well-known/openid-configuration
|
||||||
let req =
|
let req =
|
||||||
urlEncodedBody
|
urlEncodedBody
|
||||||
[ ("code", encodeUtf8 code)
|
[ ("code", encodeUtf8 code)
|
||||||
@ -264,7 +272,13 @@ getPerson manager token = parseMaybe parseJSON <$> (do
|
|||||||
|
|
||||||
personValueRequest :: MonadIO m => Token -> m Request
|
personValueRequest :: MonadIO m => Token -> m Request
|
||||||
personValueRequest token = do
|
personValueRequest token = do
|
||||||
req2' <- liftIO $ parseUrl "https://www.googleapis.com/plus/v1/people/me"
|
req2' <- liftIO $
|
||||||
|
#if MIN_VERSION_http_client(0,4,30)
|
||||||
|
HTTP.parseUrlThrow
|
||||||
|
#else
|
||||||
|
HTTP.parseUrl
|
||||||
|
#endif
|
||||||
|
"https://www.googleapis.com/plus/v1/people/me"
|
||||||
return req2'
|
return req2'
|
||||||
{ requestHeaders =
|
{ requestHeaders =
|
||||||
[ ("Authorization", encodeUtf8 $ "Bearer " `mappend` accessToken token)
|
[ ("Authorization", encodeUtf8 $ "Bearer " `mappend` accessToken token)
|
||||||
@ -284,8 +298,8 @@ data Token = Token { accessToken :: Text
|
|||||||
|
|
||||||
instance FromJSON Token where
|
instance FromJSON Token where
|
||||||
parseJSON = withObject "Tokens" $ \o -> Token
|
parseJSON = withObject "Tokens" $ \o -> Token
|
||||||
<$> o .: "access_token"
|
Control.Applicative.<$> o .: "access_token"
|
||||||
<*> o .: "token_type"
|
Control.Applicative.<*> o .: "token_type"
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- | Gender of the person
|
-- | Gender of the person
|
||||||
|
|||||||
@ -186,8 +186,8 @@ postLoginR :: (YesodAuthHardcoded master)
|
|||||||
=> HandlerT Auth (HandlerT master IO) TypedContent
|
=> HandlerT Auth (HandlerT master IO) TypedContent
|
||||||
postLoginR =
|
postLoginR =
|
||||||
do (username, password) <- lift (runInputPost
|
do (username, password) <- lift (runInputPost
|
||||||
((,) <$> ireq textField "username"
|
((,) Control.Applicative.<$> ireq textField "username"
|
||||||
<*> ireq textField "password"))
|
Control.Applicative.<*> ireq textField "password"))
|
||||||
isValid <- lift (validatePassword username password)
|
isValid <- lift (validatePassword username password)
|
||||||
if isValid
|
if isValid
|
||||||
then lift (setCredsRedirect (Creds "hardcoded" username []))
|
then lift (setCredsRedirect (Creds "hardcoded" username []))
|
||||||
|
|||||||
@ -87,7 +87,7 @@ englishMessage RegisterLong = "Register a new account"
|
|||||||
englishMessage EnterEmail = "Enter your e-mail address below, and a confirmation e-mail will be sent to you."
|
englishMessage EnterEmail = "Enter your e-mail address below, and a confirmation e-mail will be sent to you."
|
||||||
englishMessage ConfirmationEmailSentTitle = "Confirmation e-mail sent"
|
englishMessage ConfirmationEmailSentTitle = "Confirmation e-mail sent"
|
||||||
englishMessage (ConfirmationEmailSent email) =
|
englishMessage (ConfirmationEmailSent email) =
|
||||||
"A confirmation e-mail has been sent to " `mappend`
|
"A confirmation e-mail has been sent to " `Data.Monoid.mappend`
|
||||||
email `mappend`
|
email `mappend`
|
||||||
"."
|
"."
|
||||||
englishMessage AddressVerified = "Address verified, please set a new password"
|
englishMessage AddressVerified = "Address verified, please set a new password"
|
||||||
@ -464,7 +464,7 @@ finnishMessage LoginYahoo = "Kirjaudu Yahoo-tilillä"
|
|||||||
finnishMessage Email = "Sähköposti"
|
finnishMessage Email = "Sähköposti"
|
||||||
finnishMessage UserName = "Käyttäjätunnus" -- FIXME by Google Translate "user name"
|
finnishMessage UserName = "Käyttäjätunnus" -- FIXME by Google Translate "user name"
|
||||||
finnishMessage Password = "Salasana"
|
finnishMessage Password = "Salasana"
|
||||||
finnishMessage Password = "Current password"
|
finnishMessage CurrentPassword = "Current password"
|
||||||
finnishMessage Register = "Luo uusi"
|
finnishMessage Register = "Luo uusi"
|
||||||
finnishMessage RegisterLong = "Luo uusi tili"
|
finnishMessage RegisterLong = "Luo uusi tili"
|
||||||
finnishMessage EnterEmail = "Kirjoita alle sähköpostiosoitteesi, johon vahvistussähköposti lähetetään."
|
finnishMessage EnterEmail = "Kirjoita alle sähköpostiosoitteesi, johon vahvistussähköposti lähetetään."
|
||||||
|
|||||||
@ -163,7 +163,7 @@ pbkdf2 password (SaltBS salt) c =
|
|||||||
let hLen = 32
|
let hLen = 32
|
||||||
dkLen = hLen in go hLen dkLen
|
dkLen = hLen in go hLen dkLen
|
||||||
where
|
where
|
||||||
go hLen dkLen | dkLen > (2^32 - 1) * hLen = error "Derived key too long."
|
go hLen dkLen | dkLen > (2^(32 :: Int) - 1) * hLen = error "Derived key too long."
|
||||||
| otherwise =
|
| otherwise =
|
||||||
let !l = ceiling ((fromIntegral dkLen / fromIntegral hLen) :: Double)
|
let !l = ceiling ((fromIntegral dkLen / fromIntegral hLen) :: Double)
|
||||||
!r = dkLen - (l - 1) * hLen
|
!r = dkLen - (l - 1) * hLen
|
||||||
@ -413,17 +413,3 @@ modifySTRef' ref f = do
|
|||||||
let x' = f x
|
let x' = f x
|
||||||
x' `seq` writeSTRef ref x'
|
x' `seq` writeSTRef ref x'
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MIN_VERSION_bytestring(0, 10, 0)
|
|
||||||
toStrict :: BL.ByteString -> BS.ByteString
|
|
||||||
toStrict = BL.toStrict
|
|
||||||
|
|
||||||
fromStrict :: BS.ByteString -> BL.ByteString
|
|
||||||
fromStrict = BL.fromStrict
|
|
||||||
#else
|
|
||||||
toStrict :: BL.ByteString -> BS.ByteString
|
|
||||||
toStrict = BS.concat . BL.toChunks
|
|
||||||
|
|
||||||
fromStrict :: BS.ByteString -> BL.ByteString
|
|
||||||
fromStrict = BL.fromChunks . return
|
|
||||||
#endif
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ module Build
|
|||||||
, safeReadFile
|
, safeReadFile
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Applicative ((<|>), many, (<$>))
|
import Control.Applicative as App ((<|>), many, (<$>))
|
||||||
import qualified Data.Attoparsec.Text as A
|
import qualified Data.Attoparsec.Text as A
|
||||||
import Data.Char (isSpace, isUpper)
|
import Data.Char (isSpace, isUpper)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
@ -28,7 +28,7 @@ import Control.Monad.Trans.Writer (WriterT, tell, execWriterT)
|
|||||||
import Control.Monad.IO.Class (MonadIO, liftIO)
|
import Control.Monad.IO.Class (MonadIO, liftIO)
|
||||||
import Control.Monad.Trans.Class (lift)
|
import Control.Monad.Trans.Class (lift)
|
||||||
|
|
||||||
import Data.Monoid (Monoid (mappend, mempty))
|
import Data.Monoid (Monoid (..))
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ getDeps hsSourceDirs = do
|
|||||||
return $ (hss, fixDeps $ zip hss deps')
|
return $ (hss, fixDeps $ zip hss deps')
|
||||||
|
|
||||||
data AnyFilesTouched = NoFilesTouched | SomeFilesTouched
|
data AnyFilesTouched = NoFilesTouched | SomeFilesTouched
|
||||||
instance Monoid AnyFilesTouched where
|
instance Data.Monoid.Monoid AnyFilesTouched where
|
||||||
mempty = NoFilesTouched
|
mempty = NoFilesTouched
|
||||||
mappend NoFilesTouched NoFilesTouched = mempty
|
mappend NoFilesTouched NoFilesTouched = mempty
|
||||||
mappend _ _ = SomeFilesTouched
|
mappend _ _ = SomeFilesTouched
|
||||||
@ -201,7 +201,7 @@ determineDeps x = do
|
|||||||
Left _ -> return []
|
Left _ -> return []
|
||||||
Right r -> mapM go r >>= filterM (doesFileExist . snd) . concat
|
Right r -> mapM go r >>= filterM (doesFileExist . snd) . concat
|
||||||
where
|
where
|
||||||
go (Just (StaticFiles fp, _)) = map ((,) AlwaysOutdated) <$> getFolderContents fp
|
go (Just (StaticFiles fp, _)) = map ((,) AlwaysOutdated) App.<$> getFolderContents fp
|
||||||
go (Just (Hamlet, f)) = return [(AlwaysOutdated, f)]
|
go (Just (Hamlet, f)) = return [(AlwaysOutdated, f)]
|
||||||
go (Just (Widget, f)) = return
|
go (Just (Widget, f)) = return
|
||||||
[ (AlwaysOutdated, "templates/" ++ f ++ ".hamlet")
|
[ (AlwaysOutdated, "templates/" ++ f ++ ".hamlet")
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE UndecidableInstances #-}
|
{-# LANGUAGE UndecidableInstances #-}
|
||||||
|
{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-} -- Because of ErrorT
|
||||||
module Yesod.Core.Class.Handler
|
module Yesod.Core.Class.Handler
|
||||||
( MonadHandler (..)
|
( MonadHandler (..)
|
||||||
, MonadWidget (..)
|
, MonadWidget (..)
|
||||||
|
|||||||
@ -442,10 +442,9 @@ sameSiteSession s = (fmap . fmap) secureSessionCookies
|
|||||||
-- headers are ignored over HTTP.
|
-- headers are ignored over HTTP.
|
||||||
--
|
--
|
||||||
-- Since 1.4.7
|
-- Since 1.4.7
|
||||||
sslOnlyMiddleware :: Yesod site
|
sslOnlyMiddleware :: Int -- ^ minutes
|
||||||
=> Int -- ^ minutes
|
-> HandlerT site IO res
|
||||||
-> HandlerT site IO res
|
-> HandlerT site IO res
|
||||||
-> HandlerT site IO res
|
|
||||||
sslOnlyMiddleware timeout handler = do
|
sslOnlyMiddleware timeout handler = do
|
||||||
addHeader "Strict-Transport-Security"
|
addHeader "Strict-Transport-Security"
|
||||||
$ T.pack $ concat [ "max-age="
|
$ T.pack $ concat [ "max-age="
|
||||||
@ -496,8 +495,7 @@ defaultCsrfCheckMiddleware handler =
|
|||||||
-- For details, see the "AJAX CSRF protection" section of "Yesod.Core.Handler".
|
-- For details, see the "AJAX CSRF protection" section of "Yesod.Core.Handler".
|
||||||
--
|
--
|
||||||
-- Since 1.4.14
|
-- Since 1.4.14
|
||||||
csrfCheckMiddleware :: Yesod site
|
csrfCheckMiddleware :: HandlerT site IO res
|
||||||
=> HandlerT site IO res
|
|
||||||
-> HandlerT site IO Bool -- ^ Whether or not to perform the CSRF check.
|
-> HandlerT site IO Bool -- ^ Whether or not to perform the CSRF check.
|
||||||
-> CI S8.ByteString -- ^ The header name to lookup the CSRF token from.
|
-> CI S8.ByteString -- ^ The header name to lookup the CSRF token from.
|
||||||
-> Text -- ^ The POST parameter name to lookup the CSRF token from.
|
-> Text -- ^ The POST parameter name to lookup the CSRF token from.
|
||||||
@ -512,7 +510,7 @@ csrfCheckMiddleware handler shouldCheckFn headerName paramName = do
|
|||||||
-- The cookie's path is set to @/@, making it valid for your whole website.
|
-- The cookie's path is set to @/@, making it valid for your whole website.
|
||||||
--
|
--
|
||||||
-- Since 1.4.14
|
-- Since 1.4.14
|
||||||
defaultCsrfSetCookieMiddleware :: Yesod site => HandlerT site IO res -> HandlerT site IO res
|
defaultCsrfSetCookieMiddleware :: HandlerT site IO res -> HandlerT site IO res
|
||||||
defaultCsrfSetCookieMiddleware handler = setCsrfCookie >> handler
|
defaultCsrfSetCookieMiddleware handler = setCsrfCookie >> handler
|
||||||
|
|
||||||
-- | Takes a 'SetCookie' and overrides its value with a CSRF token, then sets the cookie. See 'setCsrfCookieWithCookie'.
|
-- | Takes a 'SetCookie' and overrides its value with a CSRF token, then sets the cookie. See 'setCsrfCookieWithCookie'.
|
||||||
@ -522,7 +520,7 @@ defaultCsrfSetCookieMiddleware handler = setCsrfCookie >> handler
|
|||||||
-- Make sure to set the 'setCookiePath' to the root path of your application, otherwise you'll generate a new CSRF token for every path of your app. If your app is run from from e.g. www.example.com\/app1, use @app1@. The vast majority of sites will just use @/@.
|
-- Make sure to set the 'setCookiePath' to the root path of your application, otherwise you'll generate a new CSRF token for every path of your app. If your app is run from from e.g. www.example.com\/app1, use @app1@. The vast majority of sites will just use @/@.
|
||||||
--
|
--
|
||||||
-- Since 1.4.14
|
-- Since 1.4.14
|
||||||
csrfSetCookieMiddleware :: Yesod site => HandlerT site IO res -> SetCookie -> HandlerT site IO res
|
csrfSetCookieMiddleware :: HandlerT site IO res -> SetCookie -> HandlerT site IO res
|
||||||
csrfSetCookieMiddleware handler cookie = setCsrfCookieWithCookie cookie >> handler
|
csrfSetCookieMiddleware handler cookie = setCsrfCookieWithCookie cookie >> handler
|
||||||
|
|
||||||
-- | Calls 'defaultCsrfSetCookieMiddleware' and 'defaultCsrfCheckMiddleware'.
|
-- | Calls 'defaultCsrfSetCookieMiddleware' and 'defaultCsrfCheckMiddleware'.
|
||||||
@ -546,7 +544,7 @@ defaultCsrfMiddleware :: Yesod site => HandlerT site IO res -> HandlerT site IO
|
|||||||
defaultCsrfMiddleware = defaultCsrfSetCookieMiddleware . defaultCsrfCheckMiddleware
|
defaultCsrfMiddleware = defaultCsrfSetCookieMiddleware . defaultCsrfCheckMiddleware
|
||||||
|
|
||||||
-- | Convert a widget to a 'PageContent'.
|
-- | Convert a widget to a 'PageContent'.
|
||||||
widgetToPageContent :: (Eq (Route site), Yesod site)
|
widgetToPageContent :: Yesod site
|
||||||
=> WidgetT site IO ()
|
=> WidgetT site IO ()
|
||||||
-> HandlerT site IO (PageContent (Route site))
|
-> HandlerT site IO (PageContent (Route site))
|
||||||
widgetToPageContent w = do
|
widgetToPageContent w = do
|
||||||
|
|||||||
@ -1119,13 +1119,13 @@ lookupPostParam :: (MonadResource m, MonadHandler m)
|
|||||||
lookupPostParam = fmap listToMaybe . lookupPostParams
|
lookupPostParam = fmap listToMaybe . lookupPostParams
|
||||||
|
|
||||||
-- | Lookup for POSTed files.
|
-- | Lookup for POSTed files.
|
||||||
lookupFile :: (MonadHandler m, MonadResource m)
|
lookupFile :: MonadHandler m
|
||||||
=> Text
|
=> Text
|
||||||
-> m (Maybe FileInfo)
|
-> m (Maybe FileInfo)
|
||||||
lookupFile = fmap listToMaybe . lookupFiles
|
lookupFile = fmap listToMaybe . lookupFiles
|
||||||
|
|
||||||
-- | Lookup for POSTed files.
|
-- | Lookup for POSTed files.
|
||||||
lookupFiles :: (MonadHandler m, MonadResource m)
|
lookupFiles :: MonadHandler m
|
||||||
=> Text
|
=> Text
|
||||||
-> m [FileInfo]
|
-> m [FileInfo]
|
||||||
lookupFiles pn = do
|
lookupFiles pn = do
|
||||||
|
|||||||
@ -189,7 +189,7 @@ jsonEncodingOrRedirect :: (MonadHandler m, J.ToJSON a)
|
|||||||
jsonEncodingOrRedirect = jsonOrRedirect' J.toEncoding
|
jsonEncodingOrRedirect = jsonOrRedirect' J.toEncoding
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
jsonOrRedirect' :: (MonadHandler m, J.ToJSON a)
|
jsonOrRedirect' :: MonadHandler m
|
||||||
=> (a -> b)
|
=> (a -> b)
|
||||||
-> Route (HandlerSite m) -- ^ Redirect target
|
-> Route (HandlerSite m) -- ^ Redirect target
|
||||||
-> a -- ^ Data to send via JSON
|
-> a -- ^ Data to send via JSON
|
||||||
|
|||||||
@ -462,7 +462,12 @@ instance MonadMask m => MonadMask (WidgetT site m) where
|
|||||||
WidgetT $ \e -> uninterruptibleMask $ \u -> unWidgetT (a $ q u) e
|
WidgetT $ \e -> uninterruptibleMask $ \u -> unWidgetT (a $ q u) e
|
||||||
where q u (WidgetT b) = WidgetT (u . b)
|
where q u (WidgetT b) = WidgetT (u . b)
|
||||||
|
|
||||||
|
-- CPP to avoid a redundant constraints warning
|
||||||
|
#if MIN_VERSION_base(4,9,0)
|
||||||
|
instance (MonadIO m, MonadBase IO m, MonadThrow m) => MonadResource (WidgetT site m) where
|
||||||
|
#else
|
||||||
instance (Applicative m, MonadIO m, MonadBase IO m, MonadThrow m) => MonadResource (WidgetT site m) where
|
instance (Applicative m, MonadIO m, MonadBase IO m, MonadThrow m) => MonadResource (WidgetT site m) where
|
||||||
|
#endif
|
||||||
liftResourceT f = WidgetT $ \hd -> liftIO $ (, mempty) <$> runInternalState f (handlerResource hd)
|
liftResourceT f = WidgetT $ \hd -> liftIO $ (, mempty) <$> runInternalState f (handlerResource hd)
|
||||||
|
|
||||||
instance MonadIO m => MonadLogger (WidgetT site m) where
|
instance MonadIO m => MonadLogger (WidgetT site m) where
|
||||||
|
|||||||
@ -7,20 +7,16 @@ module Main where
|
|||||||
|
|
||||||
import Criterion.Main
|
import Criterion.Main
|
||||||
import Text.Hamlet
|
import Text.Hamlet
|
||||||
import Numeric (showInt)
|
|
||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
import qualified Text.Blaze.Html.Renderer.Utf8 as Utf8
|
import qualified Text.Blaze.Html.Renderer.Utf8 as Utf8
|
||||||
import Data.Monoid (mconcat)
|
import Data.Monoid (mconcat)
|
||||||
import Text.Blaze.Html5 (table, tr, td)
|
import Text.Blaze.Html5 (table, tr, td)
|
||||||
import Text.Blaze.Html (toHtml)
|
import Text.Blaze.Html (toHtml)
|
||||||
import Yesod.Core.Widget
|
import Yesod.Core.Widget
|
||||||
import Control.Monad.Trans.Writer
|
|
||||||
import Control.Monad.Trans.RWS
|
|
||||||
import Data.Functor.Identity
|
|
||||||
import Yesod.Core.Types
|
import Yesod.Core.Types
|
||||||
import Data.Monoid
|
import Data.Int
|
||||||
import Data.IORef
|
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
main = defaultMain
|
main = defaultMain
|
||||||
[ bench "bigTable html" $ nf bigTableHtml bigTableData
|
[ bench "bigTable html" $ nf bigTableHtml bigTableData
|
||||||
, bench "bigTable hamlet" $ nf bigTableHamlet bigTableData
|
, bench "bigTable hamlet" $ nf bigTableHamlet bigTableData
|
||||||
@ -35,6 +31,7 @@ main = defaultMain
|
|||||||
bigTableData = replicate rows [1..10]
|
bigTableData = replicate rows [1..10]
|
||||||
{-# NOINLINE bigTableData #-}
|
{-# NOINLINE bigTableData #-}
|
||||||
|
|
||||||
|
bigTableHtml :: Show a => [[a]] -> Int64
|
||||||
bigTableHtml rows = L.length $ Utf8.renderHtml $ ($ id) [hamlet|
|
bigTableHtml rows = L.length $ Utf8.renderHtml $ ($ id) [hamlet|
|
||||||
<table>
|
<table>
|
||||||
$forall row <- rows
|
$forall row <- rows
|
||||||
@ -43,6 +40,7 @@ bigTableHtml rows = L.length $ Utf8.renderHtml $ ($ id) [hamlet|
|
|||||||
<td>#{show cell}
|
<td>#{show cell}
|
||||||
|]
|
|]
|
||||||
|
|
||||||
|
bigTableHamlet :: Show a => [[a]] -> Int64
|
||||||
bigTableHamlet rows = L.length $ Utf8.renderHtml $ ($ id) [hamlet|
|
bigTableHamlet rows = L.length $ Utf8.renderHtml $ ($ id) [hamlet|
|
||||||
<table>
|
<table>
|
||||||
$forall row <- rows
|
$forall row <- rows
|
||||||
@ -51,6 +49,7 @@ bigTableHamlet rows = L.length $ Utf8.renderHtml $ ($ id) [hamlet|
|
|||||||
<td>#{show cell}
|
<td>#{show cell}
|
||||||
|]
|
|]
|
||||||
|
|
||||||
|
bigTableWidget :: Show a => [[a]] -> IO Int64
|
||||||
bigTableWidget rows = fmap (L.length . Utf8.renderHtml . ($ render)) (run [whamlet|
|
bigTableWidget rows = fmap (L.length . Utf8.renderHtml . ($ render)) (run [whamlet|
|
||||||
<table>
|
<table>
|
||||||
$forall row <- rows
|
$forall row <- rows
|
||||||
@ -64,6 +63,7 @@ bigTableWidget rows = fmap (L.length . Utf8.renderHtml . ($ render)) (run [whaml
|
|||||||
(_, GWData { gwdBody = Body x }) <- w undefined
|
(_, GWData { gwdBody = Body x }) <- w undefined
|
||||||
return x
|
return x
|
||||||
|
|
||||||
bigTableBlaze t = L.length $ Utf8.renderHtml $ table $ mconcat $ map row t
|
bigTableBlaze :: Show a => [[a]] -> Int64
|
||||||
|
bigTableBlaze t = L.length $ Utf8.renderHtml $ table $ Data.Monoid.mconcat $ map row t
|
||||||
where
|
where
|
||||||
row r = tr $ mconcat $ map (td . toHtml . show) r
|
row r = tr $ mconcat $ map (td . toHtml . show) r
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
import Test.Hspec
|
|
||||||
import qualified YesodCoreTest
|
|
||||||
|
|
||||||
main :: IO ()
|
|
||||||
main = hspec YesodCoreTest.specs
|
|
||||||
@ -17,6 +17,9 @@ module Hierarchy
|
|||||||
, toText
|
, toText
|
||||||
, Env (..)
|
, Env (..)
|
||||||
, subDispatch
|
, subDispatch
|
||||||
|
-- to avoid warnings
|
||||||
|
, deleteDelete2
|
||||||
|
, deleteDelete3
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|||||||
@ -118,7 +118,7 @@ instance Dispatcher MySub master where
|
|||||||
route = MySubRoute (pieces, [])
|
route = MySubRoute (pieces, [])
|
||||||
|
|
||||||
instance Dispatcher MySubParam master where
|
instance Dispatcher MySubParam master where
|
||||||
dispatcher env (pieces, method) =
|
dispatcher env (pieces, _method) =
|
||||||
case map unpack pieces of
|
case map unpack pieces of
|
||||||
[[c]] ->
|
[[c]] ->
|
||||||
let route = ParamRoute c
|
let route = ParamRoute c
|
||||||
@ -234,56 +234,65 @@ main = hspec $ do
|
|||||||
|
|
||||||
describe "overlap checking" $ do
|
describe "overlap checking" $ do
|
||||||
it "catches overlapping statics" $ do
|
it "catches overlapping statics" $ do
|
||||||
let routes = [parseRoutesNoCheck|
|
let routes :: [ResourceTree String]
|
||||||
|
routes = [parseRoutesNoCheck|
|
||||||
/foo Foo1
|
/foo Foo1
|
||||||
/foo Foo2
|
/foo Foo2
|
||||||
|]
|
|]
|
||||||
findOverlapNames routes @?= [("Foo1", "Foo2")]
|
findOverlapNames routes @?= [("Foo1", "Foo2")]
|
||||||
it "catches overlapping dynamics" $ do
|
it "catches overlapping dynamics" $ do
|
||||||
let routes = [parseRoutesNoCheck|
|
let routes :: [ResourceTree String]
|
||||||
|
routes = [parseRoutesNoCheck|
|
||||||
/#Int Foo1
|
/#Int Foo1
|
||||||
/#String Foo2
|
/#String Foo2
|
||||||
|]
|
|]
|
||||||
findOverlapNames routes @?= [("Foo1", "Foo2")]
|
findOverlapNames routes @?= [("Foo1", "Foo2")]
|
||||||
it "catches overlapping statics and dynamics" $ do
|
it "catches overlapping statics and dynamics" $ do
|
||||||
let routes = [parseRoutesNoCheck|
|
let routes :: [ResourceTree String]
|
||||||
|
routes = [parseRoutesNoCheck|
|
||||||
/foo Foo1
|
/foo Foo1
|
||||||
/#String Foo2
|
/#String Foo2
|
||||||
|]
|
|]
|
||||||
findOverlapNames routes @?= [("Foo1", "Foo2")]
|
findOverlapNames routes @?= [("Foo1", "Foo2")]
|
||||||
it "catches overlapping multi" $ do
|
it "catches overlapping multi" $ do
|
||||||
let routes = [parseRoutesNoCheck|
|
let routes :: [ResourceTree String]
|
||||||
|
routes = [parseRoutesNoCheck|
|
||||||
/foo Foo1
|
/foo Foo1
|
||||||
/##*Strings Foo2
|
/##*Strings Foo2
|
||||||
|]
|
|]
|
||||||
findOverlapNames routes @?= [("Foo1", "Foo2")]
|
findOverlapNames routes @?= [("Foo1", "Foo2")]
|
||||||
it "catches overlapping subsite" $ do
|
it "catches overlapping subsite" $ do
|
||||||
let routes = [parseRoutesNoCheck|
|
let routes :: [ResourceTree String]
|
||||||
|
routes = [parseRoutesNoCheck|
|
||||||
/foo Foo1
|
/foo Foo1
|
||||||
/foo Foo2 Subsite getSubsite
|
/foo Foo2 Subsite getSubsite
|
||||||
|]
|
|]
|
||||||
findOverlapNames routes @?= [("Foo1", "Foo2")]
|
findOverlapNames routes @?= [("Foo1", "Foo2")]
|
||||||
it "no false positives" $ do
|
it "no false positives" $ do
|
||||||
let routes = [parseRoutesNoCheck|
|
let routes :: [ResourceTree String]
|
||||||
|
routes = [parseRoutesNoCheck|
|
||||||
/foo Foo1
|
/foo Foo1
|
||||||
/bar/#String Foo2
|
/bar/#String Foo2
|
||||||
|]
|
|]
|
||||||
findOverlapNames routes @?= []
|
findOverlapNames routes @?= []
|
||||||
it "obeys ignore rules" $ do
|
it "obeys ignore rules" $ do
|
||||||
let routes = [parseRoutesNoCheck|
|
let routes :: [ResourceTree String]
|
||||||
|
routes = [parseRoutesNoCheck|
|
||||||
/foo Foo1
|
/foo Foo1
|
||||||
/#!String Foo2
|
/#!String Foo2
|
||||||
/!foo Foo3
|
/!foo Foo3
|
||||||
|]
|
|]
|
||||||
findOverlapNames routes @?= []
|
findOverlapNames routes @?= []
|
||||||
it "obeys multipiece ignore rules #779" $ do
|
it "obeys multipiece ignore rules #779" $ do
|
||||||
let routes = [parseRoutesNoCheck|
|
let routes :: [ResourceTree String]
|
||||||
|
routes = [parseRoutesNoCheck|
|
||||||
/foo Foo1
|
/foo Foo1
|
||||||
/+![String] Foo2
|
/+![String] Foo2
|
||||||
|]
|
|]
|
||||||
findOverlapNames routes @?= []
|
findOverlapNames routes @?= []
|
||||||
it "ignore rules for entire route #779" $ do
|
it "ignore rules for entire route #779" $ do
|
||||||
let routes = [parseRoutesNoCheck|
|
let routes :: [ResourceTree String]
|
||||||
|
routes = [parseRoutesNoCheck|
|
||||||
/foo Foo1
|
/foo Foo1
|
||||||
!/+[String] Foo2
|
!/+[String] Foo2
|
||||||
!/#String Foo3
|
!/#String Foo3
|
||||||
@ -291,7 +300,8 @@ main = hspec $ do
|
|||||||
|]
|
|]
|
||||||
findOverlapNames routes @?= []
|
findOverlapNames routes @?= []
|
||||||
it "ignore rules for hierarchy" $ do
|
it "ignore rules for hierarchy" $ do
|
||||||
let routes = [parseRoutesNoCheck|
|
let routes :: [ResourceTree String]
|
||||||
|
routes = [parseRoutesNoCheck|
|
||||||
/+[String] Foo1
|
/+[String] Foo1
|
||||||
!/foo Foo2:
|
!/foo Foo2:
|
||||||
/foo Foo3
|
/foo Foo3
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
{-# LANGUAGE OverloadedStrings, TemplateHaskell, QuasiQuotes, TypeFamilies, MultiParamTypeClasses #-}
|
{-# LANGUAGE OverloadedStrings, TemplateHaskell, QuasiQuotes, TypeFamilies, MultiParamTypeClasses #-}
|
||||||
module YesodCoreTest.Auth (specs, Widget) where
|
module YesodCoreTest.Auth
|
||||||
|
( specs
|
||||||
|
, Widget
|
||||||
|
, resourcesApp
|
||||||
|
) where
|
||||||
|
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|||||||
@ -3,7 +3,11 @@
|
|||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
{-# LANGUAGE DeriveDataTypeable #-}
|
{-# LANGUAGE DeriveDataTypeable #-}
|
||||||
{-# LANGUAGE Rank2Types #-}
|
{-# LANGUAGE Rank2Types #-}
|
||||||
module YesodCoreTest.Cache (cacheTest, Widget) where
|
module YesodCoreTest.Cache
|
||||||
|
( cacheTest
|
||||||
|
, Widget
|
||||||
|
, resourcesC
|
||||||
|
) where
|
||||||
|
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,11 @@
|
|||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE FlexibleInstances, ViewPatterns #-}
|
{-# LANGUAGE FlexibleInstances, ViewPatterns #-}
|
||||||
{-# LANGUAGE CPP #-}
|
{-# LANGUAGE CPP #-}
|
||||||
module YesodCoreTest.CleanPath (cleanPathTest, Widget) where
|
module YesodCoreTest.CleanPath
|
||||||
|
( cleanPathTest
|
||||||
|
, Widget
|
||||||
|
, resourcesY
|
||||||
|
) where
|
||||||
|
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|
||||||
@ -60,7 +64,7 @@ instance Yesod Y where
|
|||||||
corrected = filter (not . TS.null) s
|
corrected = filter (not . TS.null) s
|
||||||
|
|
||||||
joinPath Y ar pieces' qs' =
|
joinPath Y ar pieces' qs' =
|
||||||
fromText ar `mappend` encodePath pieces qs
|
fromText ar `Data.Monoid.mappend` encodePath pieces qs
|
||||||
where
|
where
|
||||||
pieces = if null pieces' then [""] else pieces'
|
pieces = if null pieces' then [""] else pieces'
|
||||||
qs = map (TE.encodeUtf8 *** go) qs'
|
qs = map (TE.encodeUtf8 *** go) qs'
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
module YesodCoreTest.ErrorHandling
|
module YesodCoreTest.ErrorHandling
|
||||||
( errorHandlingTest
|
( errorHandlingTest
|
||||||
, Widget
|
, Widget
|
||||||
|
, resourcesApp
|
||||||
) where
|
) where
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
@ -98,7 +99,7 @@ getFileBadNameR :: Handler TypedContent
|
|||||||
getFileBadNameR = return $ TypedContent "ignored" $ ContentFile (error "filebadname") Nothing
|
getFileBadNameR = return $ TypedContent "ignored" $ ContentFile (error "filebadname") Nothing
|
||||||
|
|
||||||
goodBuilderContent :: Builder
|
goodBuilderContent :: Builder
|
||||||
goodBuilderContent = mconcat $ replicate 100 $ fromByteString "This is a test\n"
|
goodBuilderContent = Data.Monoid.mconcat $ replicate 100 $ fromByteString "This is a test\n"
|
||||||
|
|
||||||
getGoodBuilderR :: Handler TypedContent
|
getGoodBuilderR :: Handler TypedContent
|
||||||
getGoodBuilderR = return $ TypedContent "text/plain" $ toContent goodBuilderContent
|
getGoodBuilderR = return $ TypedContent "text/plain" $ toContent goodBuilderContent
|
||||||
@ -114,6 +115,7 @@ getErrorR 7 = setLanguage undefined
|
|||||||
getErrorR 8 = cacheSeconds undefined
|
getErrorR 8 = cacheSeconds undefined
|
||||||
getErrorR 9 = setUltDest (undefined :: Text)
|
getErrorR 9 = setUltDest (undefined :: Text)
|
||||||
getErrorR 10 = setMessage undefined
|
getErrorR 10 = setMessage undefined
|
||||||
|
getErrorR x = error $ "getErrorR: " ++ show x
|
||||||
|
|
||||||
errorHandlingTest :: Spec
|
errorHandlingTest :: Spec
|
||||||
errorHandlingTest = describe "Test.ErrorHandling" $ do
|
errorHandlingTest = describe "Test.ErrorHandling" $ do
|
||||||
|
|||||||
@ -1,7 +1,11 @@
|
|||||||
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
module YesodCoreTest.Exceptions (exceptionsTest, Widget) where
|
module YesodCoreTest.Exceptions
|
||||||
|
( exceptionsTest
|
||||||
|
, Widget
|
||||||
|
, resourcesY
|
||||||
|
) where
|
||||||
|
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|
||||||
|
|||||||
@ -21,8 +21,8 @@ randomStringSpecs = describe "Yesod.Internal.Request.randomString" $ do
|
|||||||
|
|
||||||
-- NOTE: this testcase may break on other systems/architectures if
|
-- NOTE: this testcase may break on other systems/architectures if
|
||||||
-- mkStdGen is not identical everywhere (is it?).
|
-- mkStdGen is not identical everywhere (is it?).
|
||||||
looksRandom :: Bool
|
_looksRandom :: Bool
|
||||||
looksRandom = runST $ do
|
_looksRandom = runST $ do
|
||||||
gen <- MWC.create
|
gen <- MWC.create
|
||||||
s <- randomString 20 gen
|
s <- randomString 20 gen
|
||||||
return $ s == "VH9SkhtptqPs6GqtofVg"
|
return $ s == "VH9SkhtptqPs6GqtofVg"
|
||||||
@ -57,7 +57,7 @@ tokenSpecs = describe "Yesod.Internal.Request.parseWaiRequest (reqToken)" $ do
|
|||||||
|
|
||||||
noDisabledToken :: Bool
|
noDisabledToken :: Bool
|
||||||
noDisabledToken = reqToken r == Nothing where
|
noDisabledToken = reqToken r == Nothing where
|
||||||
r = parseWaiRequest' defaultRequest mempty False 1000
|
r = parseWaiRequest' defaultRequest Data.Monoid.mempty False 1000
|
||||||
|
|
||||||
ignoreDisabledToken :: Bool
|
ignoreDisabledToken :: Bool
|
||||||
ignoreDisabledToken = reqToken r == Nothing where
|
ignoreDisabledToken = reqToken r == Nothing where
|
||||||
|
|||||||
@ -1,7 +1,11 @@
|
|||||||
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
module YesodCoreTest.JsLoader (specs, Widget) where
|
module YesodCoreTest.JsLoader
|
||||||
|
( specs
|
||||||
|
, Widget
|
||||||
|
, resourcesH
|
||||||
|
) where
|
||||||
|
|
||||||
import YesodCoreTest.JsLoaderSites.Bottom (B(..))
|
import YesodCoreTest.JsLoaderSites.Bottom (B(..))
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,11 @@
|
|||||||
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
module YesodCoreTest.JsLoaderSites.Bottom (B(..), Widget) where
|
module YesodCoreTest.JsLoaderSites.Bottom
|
||||||
|
( B(..)
|
||||||
|
, Widget
|
||||||
|
, resourcesB -- avoid warning
|
||||||
|
) where
|
||||||
|
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
{-# LANGUAGE OverloadedStrings, TemplateHaskell, QuasiQuotes, TypeFamilies, MultiParamTypeClasses, ViewPatterns #-}
|
{-# LANGUAGE OverloadedStrings, TemplateHaskell, QuasiQuotes, TypeFamilies, MultiParamTypeClasses, ViewPatterns #-}
|
||||||
module YesodCoreTest.Json (specs, Widget) where
|
module YesodCoreTest.Json
|
||||||
|
( specs
|
||||||
|
, Widget
|
||||||
|
, resourcesApp
|
||||||
|
) where
|
||||||
|
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|||||||
@ -1,7 +1,11 @@
|
|||||||
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE FlexibleInstances, ViewPatterns #-}
|
{-# LANGUAGE FlexibleInstances, ViewPatterns #-}
|
||||||
module YesodCoreTest.Links (linksTest, Widget) where
|
module YesodCoreTest.Links
|
||||||
|
( linksTest
|
||||||
|
, Widget
|
||||||
|
, resourcesY
|
||||||
|
) where
|
||||||
|
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|
||||||
@ -26,12 +30,16 @@ mkYesod "Y" [parseRoutes|
|
|||||||
data Vector a = Vector
|
data Vector a = Vector
|
||||||
deriving (Show, Read, Eq)
|
deriving (Show, Read, Eq)
|
||||||
|
|
||||||
instance PathMultiPiece (Vector a)
|
instance PathMultiPiece (Vector a) where
|
||||||
|
toPathMultiPiece = error "toPathMultiPiece"
|
||||||
|
fromPathMultiPiece = error "fromPathMultiPiece"
|
||||||
|
|
||||||
data Foo x y = Foo
|
data Foo x y = Foo
|
||||||
deriving (Show, Read, Eq)
|
deriving (Show, Read, Eq)
|
||||||
|
|
||||||
instance PathPiece (Foo x y)
|
instance PathPiece (Foo x y) where
|
||||||
|
toPathPiece = error "toPathPiece"
|
||||||
|
fromPathPiece = error "fromPathPiece"
|
||||||
|
|
||||||
instance Yesod Y
|
instance Yesod Y
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,11 @@
|
|||||||
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE FlexibleInstances, ViewPatterns #-}
|
{-# LANGUAGE FlexibleInstances, ViewPatterns #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-} -- the module name is a lie!!!
|
{-# LANGUAGE OverloadedStrings #-} -- the module name is a lie!!!
|
||||||
module YesodCoreTest.NoOverloadedStrings (noOverloadedTest, Widget) where
|
module YesodCoreTest.NoOverloadedStrings
|
||||||
|
( noOverloadedTest
|
||||||
|
, Widget
|
||||||
|
, resourcesY
|
||||||
|
) where
|
||||||
|
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
import YesodCoreTest.NoOverloadedStringsSub
|
import YesodCoreTest.NoOverloadedStringsSub
|
||||||
@ -60,7 +64,7 @@ runner f = toWaiApp Y >>= runSession f
|
|||||||
case_sanity :: IO ()
|
case_sanity :: IO ()
|
||||||
case_sanity = runner $ do
|
case_sanity = runner $ do
|
||||||
res <- request defaultRequest
|
res <- request defaultRequest
|
||||||
assertBody mempty res
|
assertBody Data.Monoid.mempty res
|
||||||
|
|
||||||
case_subsite :: IO ()
|
case_subsite :: IO ()
|
||||||
case_subsite = runner $ do
|
case_subsite = runner $ do
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
{-# LANGUAGE OverloadedStrings, TemplateHaskell, QuasiQuotes, TypeFamilies, MultiParamTypeClasses, ScopedTypeVariables #-}
|
{-# LANGUAGE OverloadedStrings, TemplateHaskell, QuasiQuotes, TypeFamilies, MultiParamTypeClasses, ScopedTypeVariables #-}
|
||||||
module YesodCoreTest.RawResponse (specs, Widget) where
|
module YesodCoreTest.RawResponse
|
||||||
|
( specs
|
||||||
|
, Widget
|
||||||
|
, resourcesApp
|
||||||
|
) where
|
||||||
|
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
import qualified Data.Map as Map
|
|
||||||
import Network.Wai.Test
|
|
||||||
import Network.Wai (responseStream)
|
import Network.Wai (responseStream)
|
||||||
import Data.Text (Text)
|
|
||||||
import Data.ByteString.Lazy (ByteString)
|
|
||||||
import qualified Data.Conduit.List as CL
|
import qualified Data.Conduit.List as CL
|
||||||
import qualified Data.ByteString.Char8 as S8
|
import qualified Data.ByteString.Char8 as S8
|
||||||
import Data.Conduit
|
import Data.Conduit
|
||||||
@ -15,7 +15,7 @@ import qualified Data.Conduit.Binary as CB
|
|||||||
import Data.Char (toUpper)
|
import Data.Char (toUpper)
|
||||||
import Control.Exception (try, IOException)
|
import Control.Exception (try, IOException)
|
||||||
import Data.Conduit.Network
|
import Data.Conduit.Network
|
||||||
import Network.Socket (sClose)
|
import Network.Socket (close)
|
||||||
import Control.Concurrent (threadDelay)
|
import Control.Concurrent (threadDelay)
|
||||||
import Control.Concurrent.Async (withAsync)
|
import Control.Concurrent.Async (withAsync)
|
||||||
import Control.Monad.Trans.Resource (register)
|
import Control.Monad.Trans.Resource (register)
|
||||||
@ -36,7 +36,7 @@ instance Yesod App
|
|||||||
|
|
||||||
getHomeR :: Handler ()
|
getHomeR :: Handler ()
|
||||||
getHomeR = do
|
getHomeR = do
|
||||||
ref <- liftIO $ newIORef 0
|
ref <- liftIO $ newIORef (0 :: Int)
|
||||||
_ <- register $ writeIORef ref 1
|
_ <- register $ writeIORef ref 1
|
||||||
sendRawResponse $ \src sink -> liftIO $ do
|
sendRawResponse $ \src sink -> liftIO $ do
|
||||||
val <- readIORef ref
|
val <- readIORef ref
|
||||||
@ -66,7 +66,7 @@ getFreePort = do
|
|||||||
case esocket of
|
case esocket of
|
||||||
Left (_ :: IOException) -> loop (succ port)
|
Left (_ :: IOException) -> loop (succ port)
|
||||||
Right socket -> do
|
Right socket -> do
|
||||||
sClose socket
|
close socket
|
||||||
return port
|
return port
|
||||||
|
|
||||||
specs :: Spec
|
specs :: Spec
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
{-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies, MultiParamTypeClasses, OverloadedStrings #-}
|
{-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies, MultiParamTypeClasses, OverloadedStrings #-}
|
||||||
module YesodCoreTest.Redirect (specs, Widget) where
|
module YesodCoreTest.Redirect
|
||||||
|
( specs
|
||||||
|
, Widget
|
||||||
|
, resourcesY
|
||||||
|
) where
|
||||||
|
|
||||||
import YesodCoreTest.YesodTest
|
import YesodCoreTest.YesodTest
|
||||||
import Yesod.Core.Handler (redirectWith, setEtag)
|
import Yesod.Core.Handler (redirectWith, setEtag)
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
{-# LANGUAGE OverloadedStrings, TemplateHaskell, QuasiQuotes, TypeFamilies, MultiParamTypeClasses, ViewPatterns #-}
|
{-# LANGUAGE OverloadedStrings, TemplateHaskell, QuasiQuotes, TypeFamilies, MultiParamTypeClasses, ViewPatterns #-}
|
||||||
module YesodCoreTest.Reps (specs, Widget) where
|
module YesodCoreTest.Reps
|
||||||
|
( specs
|
||||||
|
, Widget
|
||||||
|
, resourcesApp
|
||||||
|
) where
|
||||||
|
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|||||||
@ -1,7 +1,11 @@
|
|||||||
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
module YesodCoreTest.RequestBodySize (specs, Widget) where
|
module YesodCoreTest.RequestBodySize
|
||||||
|
( specs
|
||||||
|
, Widget
|
||||||
|
, resourcesY
|
||||||
|
) where
|
||||||
|
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-}
|
{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-}
|
||||||
module YesodCoreTest.StubLaxSameSite ( App ( App ) ) where
|
module YesodCoreTest.StubLaxSameSite
|
||||||
|
( App ( App )
|
||||||
|
, Widget
|
||||||
|
, resourcesApp
|
||||||
|
) where
|
||||||
|
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import qualified Web.ClientSession as CS
|
import qualified Web.ClientSession as CS
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-}
|
{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-}
|
||||||
module YesodCoreTest.StubSslOnly ( App ( App ) ) where
|
module YesodCoreTest.StubSslOnly
|
||||||
|
( App ( App )
|
||||||
|
, Widget
|
||||||
|
, resourcesApp
|
||||||
|
) where
|
||||||
|
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import qualified Web.ClientSession as CS
|
import qualified Web.ClientSession as CS
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-}
|
{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-}
|
||||||
module YesodCoreTest.StubStrictSameSite ( App ( App ) ) where
|
module YesodCoreTest.StubStrictSameSite
|
||||||
|
( App ( App )
|
||||||
|
, Widget
|
||||||
|
, resourcesApp
|
||||||
|
) where
|
||||||
|
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import qualified Web.ClientSession as CS
|
import qualified Web.ClientSession as CS
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-}
|
{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-}
|
||||||
module YesodCoreTest.StubUnsecured ( App ( App ) ) where
|
module YesodCoreTest.StubUnsecured
|
||||||
|
( App ( App )
|
||||||
|
, Widget
|
||||||
|
, resourcesApp
|
||||||
|
) where
|
||||||
|
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
{-# LANGUAGE CPP, QuasiQuotes, TemplateHaskell, TypeFamilies, MultiParamTypeClasses, OverloadedStrings, ViewPatterns #-}
|
{-# LANGUAGE CPP, QuasiQuotes, TemplateHaskell, TypeFamilies, MultiParamTypeClasses, OverloadedStrings, ViewPatterns #-}
|
||||||
module YesodCoreTest.WaiSubsite (specs, Widget) where
|
module YesodCoreTest.WaiSubsite
|
||||||
|
( specs
|
||||||
|
, Widget
|
||||||
|
, resourcesY
|
||||||
|
) where
|
||||||
|
|
||||||
import YesodCoreTest.YesodTest
|
import YesodCoreTest.YesodTest
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE FlexibleInstances, ViewPatterns #-}
|
{-# LANGUAGE FlexibleInstances, ViewPatterns #-}
|
||||||
module YesodCoreTest.Widget (widgetTest) where
|
module YesodCoreTest.Widget
|
||||||
|
( widgetTest
|
||||||
|
, resourcesY
|
||||||
|
) where
|
||||||
|
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
../test.hs
|
|
||||||
5
yesod-core/test/test.hs
Normal file
5
yesod-core/test/test.hs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import Test.Hspec
|
||||||
|
import qualified YesodCoreTest
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = hspec YesodCoreTest.specs
|
||||||
@ -12,7 +12,6 @@ cabal-version: >= 1.8
|
|||||||
build-type: Simple
|
build-type: Simple
|
||||||
homepage: http://www.yesodweb.com/
|
homepage: http://www.yesodweb.com/
|
||||||
extra-source-files:
|
extra-source-files:
|
||||||
test.hs
|
|
||||||
test/YesodCoreTest.hs
|
test/YesodCoreTest.hs
|
||||||
test/YesodCoreTest/*.hs
|
test/YesodCoreTest/*.hs
|
||||||
test/YesodCoreTest/JsLoaderSites/Bottom.hs
|
test/YesodCoreTest/JsLoaderSites/Bottom.hs
|
||||||
@ -119,6 +118,15 @@ test-suite test-routes
|
|||||||
hs-source-dirs: test, .
|
hs-source-dirs: test, .
|
||||||
|
|
||||||
other-modules: Hierarchy
|
other-modules: Hierarchy
|
||||||
|
Yesod.Routes.Class
|
||||||
|
Yesod.Routes.Overlap
|
||||||
|
Yesod.Routes.Parse
|
||||||
|
Yesod.Routes.TH
|
||||||
|
Yesod.Routes.TH.Dispatch
|
||||||
|
Yesod.Routes.TH.ParseRoute
|
||||||
|
Yesod.Routes.TH.RenderRoute
|
||||||
|
Yesod.Routes.TH.RouteAttrs
|
||||||
|
Yesod.Routes.TH.Types
|
||||||
|
|
||||||
-- Workaround for: http://ghc.haskell.org/trac/ghc/ticket/8443
|
-- Workaround for: http://ghc.haskell.org/trac/ghc/ticket/8443
|
||||||
extensions: TemplateHaskell
|
extensions: TemplateHaskell
|
||||||
@ -138,6 +146,37 @@ test-suite tests
|
|||||||
main-is: test.hs
|
main-is: test.hs
|
||||||
hs-source-dirs: test
|
hs-source-dirs: test
|
||||||
|
|
||||||
|
other-modules: YesodCoreTest
|
||||||
|
YesodCoreTest.Auth
|
||||||
|
YesodCoreTest.Cache
|
||||||
|
YesodCoreTest.CleanPath
|
||||||
|
YesodCoreTest.Csrf
|
||||||
|
YesodCoreTest.ErrorHandling
|
||||||
|
YesodCoreTest.Exceptions
|
||||||
|
YesodCoreTest.InternalRequest
|
||||||
|
YesodCoreTest.JsLoader
|
||||||
|
YesodCoreTest.JsLoaderSites.Bottom
|
||||||
|
YesodCoreTest.Json
|
||||||
|
YesodCoreTest.Links
|
||||||
|
YesodCoreTest.LiteApp
|
||||||
|
YesodCoreTest.Media
|
||||||
|
YesodCoreTest.MediaData
|
||||||
|
YesodCoreTest.NoOverloadedStrings
|
||||||
|
YesodCoreTest.NoOverloadedStringsSub
|
||||||
|
YesodCoreTest.RawResponse
|
||||||
|
YesodCoreTest.Redirect
|
||||||
|
YesodCoreTest.Reps
|
||||||
|
YesodCoreTest.RequestBodySize
|
||||||
|
YesodCoreTest.Ssl
|
||||||
|
YesodCoreTest.Streaming
|
||||||
|
YesodCoreTest.StubLaxSameSite
|
||||||
|
YesodCoreTest.StubSslOnly
|
||||||
|
YesodCoreTest.StubStrictSameSite
|
||||||
|
YesodCoreTest.StubUnsecured
|
||||||
|
YesodCoreTest.WaiSubsite
|
||||||
|
YesodCoreTest.Widget
|
||||||
|
YesodCoreTest.YesodTest
|
||||||
|
|
||||||
cpp-options: -DTEST
|
cpp-options: -DTEST
|
||||||
build-depends: base
|
build-depends: base
|
||||||
,hspec >= 1.3
|
,hspec >= 1.3
|
||||||
|
|||||||
@ -11,7 +11,7 @@ module Yesod.EventSource
|
|||||||
import Blaze.ByteString.Builder (Builder)
|
import Blaze.ByteString.Builder (Builder)
|
||||||
import Control.Monad (when)
|
import Control.Monad (when)
|
||||||
import Data.Functor ((<$>))
|
import Data.Functor ((<$>))
|
||||||
import Data.Monoid (mappend, mempty)
|
import Data.Monoid (Monoid (..))
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import qualified Data.Conduit as C
|
import qualified Data.Conduit as C
|
||||||
import qualified Network.Wai as W
|
import qualified Network.Wai as W
|
||||||
@ -24,7 +24,7 @@ import qualified Network.Wai.EventSource.EventStream as ES
|
|||||||
-- set any necessary headers.
|
-- set any necessary headers.
|
||||||
prepareForEventSource :: MonadHandler m => m EventSourcePolyfill
|
prepareForEventSource :: MonadHandler m => m EventSourcePolyfill
|
||||||
prepareForEventSource = do
|
prepareForEventSource = do
|
||||||
reqWith <- lookup "X-Requested-With" . W.requestHeaders <$> waiRequest
|
reqWith <- lookup "X-Requested-With" . W.requestHeaders Data.Functor.<$> waiRequest
|
||||||
let polyfill | reqWith == Just "XMLHttpRequest" = Remy'sESPolyfill
|
let polyfill | reqWith == Just "XMLHttpRequest" = Remy'sESPolyfill
|
||||||
| otherwise = NoESPolyfill
|
| otherwise = NoESPolyfill
|
||||||
addHeader "Cache-Control" "no-cache" -- extremely important!
|
addHeader "Cache-Control" "no-cache" -- extremely important!
|
||||||
@ -87,7 +87,7 @@ pollingEventSource initial act = do
|
|||||||
-- when we the connection should be closed.
|
-- when we the connection should be closed.
|
||||||
joinEvents (ev:evs) acc =
|
joinEvents (ev:evs) acc =
|
||||||
case ES.eventToBuilder ev of
|
case ES.eventToBuilder ev of
|
||||||
Just b -> joinEvents evs (acc `mappend` b)
|
Just b -> joinEvents evs (acc `Data.Monoid.mappend` b)
|
||||||
Nothing -> (fst $ joinEvents [] acc, False)
|
Nothing -> (fst $ joinEvents [] acc, False)
|
||||||
joinEvents [] acc = (acc, True)
|
joinEvents [] acc = (acc, True)
|
||||||
|
|
||||||
|
|||||||
@ -63,12 +63,10 @@ import Yesod.Form.Types
|
|||||||
import Yesod.Form.I18n.English
|
import Yesod.Form.I18n.English
|
||||||
import Yesod.Form.Functions (parseHelper)
|
import Yesod.Form.Functions (parseHelper)
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import Text.Hamlet
|
|
||||||
import Text.Blaze (ToMarkup (toMarkup), unsafeByteString)
|
import Text.Blaze (ToMarkup (toMarkup), unsafeByteString)
|
||||||
#define ToHtml ToMarkup
|
#define ToHtml ToMarkup
|
||||||
#define toHtml toMarkup
|
#define toHtml toMarkup
|
||||||
#define preEscapedText preEscapedToMarkup
|
#define preEscapedText preEscapedToMarkup
|
||||||
import Text.Cassius
|
|
||||||
import Data.Time (Day, TimeOfDay(..))
|
import Data.Time (Day, TimeOfDay(..))
|
||||||
import qualified Text.Email.Validate as Email
|
import qualified Text.Email.Validate as Email
|
||||||
import Data.Text.Encoding (encodeUtf8, decodeUtf8With)
|
import Data.Text.Encoding (encodeUtf8, decodeUtf8With)
|
||||||
@ -88,7 +86,6 @@ import Data.Maybe (listToMaybe, fromMaybe)
|
|||||||
import qualified Blaze.ByteString.Builder.Html.Utf8 as B
|
import qualified Blaze.ByteString.Builder.Html.Utf8 as B
|
||||||
import Blaze.ByteString.Builder (writeByteString, toLazyByteString)
|
import Blaze.ByteString.Builder (writeByteString, toLazyByteString)
|
||||||
import Blaze.ByteString.Builder.Internal.Write (fromWriteList)
|
import Blaze.ByteString.Builder.Internal.Write (fromWriteList)
|
||||||
import Database.Persist (PersistEntityBackend)
|
|
||||||
|
|
||||||
import Text.Blaze.Html.Renderer.String (renderHtml)
|
import Text.Blaze.Html.Renderer.String (renderHtml)
|
||||||
import qualified Data.ByteString as S
|
import qualified Data.ByteString as S
|
||||||
@ -96,11 +93,11 @@ import qualified Data.ByteString.Lazy as L
|
|||||||
import Data.Text as T ( Text, append, concat, cons, head
|
import Data.Text as T ( Text, append, concat, cons, head
|
||||||
, intercalate, isPrefixOf, null, unpack, pack, splitOn
|
, intercalate, isPrefixOf, null, unpack, pack, splitOn
|
||||||
)
|
)
|
||||||
import qualified Data.Text as T (drop, dropWhile)
|
import qualified Data.Text as T (drop, dropWhile)
|
||||||
import qualified Data.Text.Read
|
import qualified Data.Text.Read
|
||||||
|
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Yesod.Persist (selectList, runDB, Filter, SelectOpt, Key, YesodPersist, PersistEntity, PersistQuery)
|
import Yesod.Persist (selectList, Filter, SelectOpt, Key)
|
||||||
import Control.Arrow ((&&&))
|
import Control.Arrow ((&&&))
|
||||||
|
|
||||||
import Control.Applicative ((<$>), (<|>))
|
import Control.Applicative ((<$>), (<|>))
|
||||||
@ -323,7 +320,7 @@ timeParser = do
|
|||||||
where
|
where
|
||||||
hour = do
|
hour = do
|
||||||
x <- digit
|
x <- digit
|
||||||
y <- (return <$> digit) <|> return []
|
y <- (return Control.Applicative.<$> digit) <|> return []
|
||||||
let xy = x : y
|
let xy = x : y
|
||||||
let i = read xy
|
let i = read xy
|
||||||
if i < 0 || i >= 24
|
if i < 0 || i >= 24
|
||||||
@ -442,13 +439,13 @@ $newline never
|
|||||||
|]) -- inside
|
|]) -- inside
|
||||||
|
|
||||||
-- | Creates a @\<select>@ tag for selecting multiple options.
|
-- | Creates a @\<select>@ tag for selecting multiple options.
|
||||||
multiSelectFieldList :: (Eq a, RenderMessage site FormMessage, RenderMessage site msg)
|
multiSelectFieldList :: (Eq a, RenderMessage site msg)
|
||||||
=> [(msg, a)]
|
=> [(msg, a)]
|
||||||
-> Field (HandlerT site IO) [a]
|
-> Field (HandlerT site IO) [a]
|
||||||
multiSelectFieldList = multiSelectField . optionsPairs
|
multiSelectFieldList = multiSelectField . optionsPairs
|
||||||
|
|
||||||
-- | Creates a @\<select>@ tag for selecting multiple options.
|
-- | Creates a @\<select>@ tag for selecting multiple options.
|
||||||
multiSelectField :: (Eq a, RenderMessage site FormMessage)
|
multiSelectField :: Eq a
|
||||||
=> HandlerT site IO (OptionList a)
|
=> HandlerT site IO (OptionList a)
|
||||||
-> Field (HandlerT site IO) [a]
|
-> Field (HandlerT site IO) [a]
|
||||||
multiSelectField ioptlist =
|
multiSelectField ioptlist =
|
||||||
@ -480,17 +477,17 @@ radioFieldList :: (Eq a, RenderMessage site FormMessage, RenderMessage site msg)
|
|||||||
radioFieldList = radioField . optionsPairs
|
radioFieldList = radioField . optionsPairs
|
||||||
|
|
||||||
-- | Creates an input with @type="checkbox"@ for selecting multiple options.
|
-- | Creates an input with @type="checkbox"@ for selecting multiple options.
|
||||||
checkboxesFieldList :: (Eq a, RenderMessage site FormMessage, RenderMessage site msg) => [(msg, a)]
|
checkboxesFieldList :: (Eq a, RenderMessage site msg) => [(msg, a)]
|
||||||
-> Field (HandlerT site IO) [a]
|
-> Field (HandlerT site IO) [a]
|
||||||
checkboxesFieldList = checkboxesField . optionsPairs
|
checkboxesFieldList = checkboxesField . optionsPairs
|
||||||
|
|
||||||
-- | Creates an input with @type="checkbox"@ for selecting multiple options.
|
-- | Creates an input with @type="checkbox"@ for selecting multiple options.
|
||||||
checkboxesField :: (Eq a, RenderMessage site FormMessage)
|
checkboxesField :: Eq a
|
||||||
=> HandlerT site IO (OptionList a)
|
=> HandlerT site IO (OptionList a)
|
||||||
-> Field (HandlerT site IO) [a]
|
-> Field (HandlerT site IO) [a]
|
||||||
checkboxesField ioptlist = (multiSelectField ioptlist)
|
checkboxesField ioptlist = (multiSelectField ioptlist)
|
||||||
{ fieldView =
|
{ fieldView =
|
||||||
\theId name attrs val isReq -> do
|
\theId name attrs val _isReq -> do
|
||||||
opts <- fmap olOptions $ handlerToWidget ioptlist
|
opts <- fmap olOptions $ handlerToWidget ioptlist
|
||||||
let optselected (Left _) _ = False
|
let optselected (Left _) _ = False
|
||||||
optselected (Right vals) opt = (optionInternalValue opt) `elem` vals
|
optselected (Right vals) opt = (optionInternalValue opt) `elem` vals
|
||||||
@ -572,7 +569,7 @@ $newline never
|
|||||||
--
|
--
|
||||||
-- Note that this makes the field always optional.
|
-- Note that this makes the field always optional.
|
||||||
--
|
--
|
||||||
checkBoxField :: Monad m => RenderMessage (HandlerSite m) FormMessage => Field m Bool
|
checkBoxField :: Monad m => Field m Bool
|
||||||
checkBoxField = Field
|
checkBoxField = Field
|
||||||
{ fieldParse = \e _ -> return $ checkBoxParser e
|
{ fieldParse = \e _ -> return $ checkBoxParser e
|
||||||
, fieldView = \theId name attrs val _ -> [whamlet|
|
, fieldView = \theId name attrs val _ -> [whamlet|
|
||||||
@ -760,7 +757,7 @@ selectFieldHelper outside onOpt inside opts' = Field
|
|||||||
Just y -> Right $ Just y
|
Just y -> Right $ Just y
|
||||||
|
|
||||||
-- | Creates an input with @type="file"@.
|
-- | Creates an input with @type="file"@.
|
||||||
fileField :: (Monad m, RenderMessage (HandlerSite m) FormMessage)
|
fileField :: Monad m
|
||||||
=> Field m FileInfo
|
=> Field m FileInfo
|
||||||
fileField = Field
|
fileField = Field
|
||||||
{ fieldParse = \_ files -> return $
|
{ fieldParse = \_ files -> return $
|
||||||
@ -806,7 +803,6 @@ $newline never
|
|||||||
return (res, (fv :), ints', Multipart)
|
return (res, (fv :), ints', Multipart)
|
||||||
|
|
||||||
fileAFormOpt :: MonadHandler m
|
fileAFormOpt :: MonadHandler m
|
||||||
=> RenderMessage (HandlerSite m) FormMessage
|
|
||||||
=> FieldSettings (HandlerSite m)
|
=> FieldSettings (HandlerSite m)
|
||||||
-> AForm m (Maybe FileInfo)
|
-> AForm m (Maybe FileInfo)
|
||||||
fileAFormOpt fs = AForm $ \(master, langs) menvs ints -> do
|
fileAFormOpt fs = AForm $ \(master, langs) menvs ints -> do
|
||||||
|
|||||||
@ -59,9 +59,7 @@ import Text.Blaze (Markup, toMarkup)
|
|||||||
#define Html Markup
|
#define Html Markup
|
||||||
#define toHtml toMarkup
|
#define toHtml toMarkup
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import Yesod.Core.Handler (defaultCsrfParamName)
|
|
||||||
import Network.Wai (requestMethod)
|
import Network.Wai (requestMethod)
|
||||||
import Text.Hamlet (shamlet)
|
|
||||||
import Data.Monoid (mempty, (<>))
|
import Data.Monoid (mempty, (<>))
|
||||||
import Data.Maybe (listToMaybe, fromMaybe)
|
import Data.Maybe (listToMaybe, fromMaybe)
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
@ -217,7 +215,7 @@ postHelper form env = do
|
|||||||
let tokenKey = defaultCsrfParamName
|
let tokenKey = defaultCsrfParamName
|
||||||
let token =
|
let token =
|
||||||
case reqToken req of
|
case reqToken req of
|
||||||
Nothing -> mempty
|
Nothing -> Data.Monoid.mempty
|
||||||
Just n -> [shamlet|<input type=hidden name=#{tokenKey} value=#{n}>|]
|
Just n -> [shamlet|<input type=hidden name=#{tokenKey} value=#{n}>|]
|
||||||
m <- getYesod
|
m <- getYesod
|
||||||
langs <- languages
|
langs <- languages
|
||||||
@ -245,8 +243,7 @@ generateFormPost
|
|||||||
-> m (xml, Enctype)
|
-> m (xml, Enctype)
|
||||||
generateFormPost form = first snd `liftM` postHelper form Nothing
|
generateFormPost form = first snd `liftM` postHelper form Nothing
|
||||||
|
|
||||||
postEnv :: (MonadHandler m, MonadResource m)
|
postEnv :: MonadHandler m => m (Maybe (Env, FileEnv))
|
||||||
=> m (Maybe (Env, FileEnv))
|
|
||||||
postEnv = do
|
postEnv = do
|
||||||
req <- getRequest
|
req <- getRequest
|
||||||
if requestMethod (reqWaiRequest req) == "GET"
|
if requestMethod (reqWaiRequest req) == "GET"
|
||||||
@ -281,7 +278,7 @@ runFormGet form = do
|
|||||||
--
|
--
|
||||||
-- Since 1.3.11
|
-- Since 1.3.11
|
||||||
generateFormGet'
|
generateFormGet'
|
||||||
:: (RenderMessage (HandlerSite m) FormMessage, MonadHandler m)
|
:: MonadHandler m
|
||||||
=> (Html -> MForm m (FormResult a, xml))
|
=> (Html -> MForm m (FormResult a, xml))
|
||||||
-> m (xml, Enctype)
|
-> m (xml, Enctype)
|
||||||
generateFormGet' form = first snd `liftM` getHelper form Nothing
|
generateFormGet' form = first snd `liftM` getHelper form Nothing
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import Data.Monoid (mappend)
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
|
||||||
czechFormMessage :: FormMessage -> Text
|
czechFormMessage :: FormMessage -> Text
|
||||||
czechFormMessage (MsgInvalidInteger t) = "Neplatné celé číslo: " `mappend` t
|
czechFormMessage (MsgInvalidInteger t) = "Neplatné celé číslo: " `Data.Monoid.mappend` t
|
||||||
czechFormMessage (MsgInvalidNumber t) = "Neplatné číslo: " `mappend` t
|
czechFormMessage (MsgInvalidNumber t) = "Neplatné číslo: " `mappend` t
|
||||||
czechFormMessage (MsgInvalidEntry t) = "Neplatná položka: " `mappend` t
|
czechFormMessage (MsgInvalidEntry t) = "Neplatná položka: " `mappend` t
|
||||||
czechFormMessage MsgInvalidTimeFormat = "Neplatný čas, musí být ve formátu HH:MM[:SS]"
|
czechFormMessage MsgInvalidTimeFormat = "Neplatný čas, musí být ve formátu HH:MM[:SS]"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import Data.Monoid (mappend)
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
|
||||||
dutchFormMessage :: FormMessage -> Text
|
dutchFormMessage :: FormMessage -> Text
|
||||||
dutchFormMessage (MsgInvalidInteger t) = "Ongeldig aantal: " `mappend` t
|
dutchFormMessage (MsgInvalidInteger t) = "Ongeldig aantal: " `Data.Monoid.mappend` t
|
||||||
dutchFormMessage (MsgInvalidNumber t) = "Ongeldig getal: " `mappend` t
|
dutchFormMessage (MsgInvalidNumber t) = "Ongeldig getal: " `mappend` t
|
||||||
dutchFormMessage (MsgInvalidEntry t) = "Ongeldige invoer: " `mappend` t
|
dutchFormMessage (MsgInvalidEntry t) = "Ongeldige invoer: " `mappend` t
|
||||||
dutchFormMessage MsgInvalidTimeFormat = "Ongeldige tijd, het juiste formaat is (UU:MM[:SS])"
|
dutchFormMessage MsgInvalidTimeFormat = "Ongeldige tijd, het juiste formaat is (UU:MM[:SS])"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import Data.Monoid (mappend)
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
|
||||||
englishFormMessage :: FormMessage -> Text
|
englishFormMessage :: FormMessage -> Text
|
||||||
englishFormMessage (MsgInvalidInteger t) = "Invalid integer: " `mappend` t
|
englishFormMessage (MsgInvalidInteger t) = "Invalid integer: " `Data.Monoid.mappend` t
|
||||||
englishFormMessage (MsgInvalidNumber t) = "Invalid number: " `mappend` t
|
englishFormMessage (MsgInvalidNumber t) = "Invalid number: " `mappend` t
|
||||||
englishFormMessage (MsgInvalidEntry t) = "Invalid entry: " `mappend` t
|
englishFormMessage (MsgInvalidEntry t) = "Invalid entry: " `mappend` t
|
||||||
englishFormMessage MsgInvalidTimeFormat = "Invalid time, must be in HH:MM[:SS] format"
|
englishFormMessage MsgInvalidTimeFormat = "Invalid time, must be in HH:MM[:SS] format"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import Data.Monoid (mappend)
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
|
||||||
frenchFormMessage :: FormMessage -> Text
|
frenchFormMessage :: FormMessage -> Text
|
||||||
frenchFormMessage (MsgInvalidInteger t) = "Entier invalide : " `mappend` t
|
frenchFormMessage (MsgInvalidInteger t) = "Entier invalide : " `Data.Monoid.mappend` t
|
||||||
frenchFormMessage (MsgInvalidNumber t) = "Nombre invalide : " `mappend` t
|
frenchFormMessage (MsgInvalidNumber t) = "Nombre invalide : " `mappend` t
|
||||||
frenchFormMessage (MsgInvalidEntry t) = "Entrée invalide : " `mappend` t
|
frenchFormMessage (MsgInvalidEntry t) = "Entrée invalide : " `mappend` t
|
||||||
frenchFormMessage MsgInvalidTimeFormat = "Heure invalide (elle doit être au format HH:MM ou HH:MM:SS"
|
frenchFormMessage MsgInvalidTimeFormat = "Heure invalide (elle doit être au format HH:MM ou HH:MM:SS"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import Data.Monoid (mappend)
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
|
||||||
germanFormMessage :: FormMessage -> Text
|
germanFormMessage :: FormMessage -> Text
|
||||||
germanFormMessage (MsgInvalidInteger t) = "Ungültige Ganzzahl: " `mappend` t
|
germanFormMessage (MsgInvalidInteger t) = "Ungültige Ganzzahl: " `Data.Monoid.mappend` t
|
||||||
germanFormMessage (MsgInvalidNumber t) = "Ungültige Zahl: " `mappend` t
|
germanFormMessage (MsgInvalidNumber t) = "Ungültige Zahl: " `mappend` t
|
||||||
germanFormMessage (MsgInvalidEntry t) = "Ungültiger Eintrag: " `mappend` t
|
germanFormMessage (MsgInvalidEntry t) = "Ungültiger Eintrag: " `mappend` t
|
||||||
germanFormMessage MsgInvalidTimeFormat = "Ungültiges Zeitformat, HH:MM[:SS] Format erwartet"
|
germanFormMessage MsgInvalidTimeFormat = "Ungültiges Zeitformat, HH:MM[:SS] Format erwartet"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import Data.Monoid (mappend)
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
|
||||||
japaneseFormMessage :: FormMessage -> Text
|
japaneseFormMessage :: FormMessage -> Text
|
||||||
japaneseFormMessage (MsgInvalidInteger t) = "無効な整数です: " `mappend` t
|
japaneseFormMessage (MsgInvalidInteger t) = "無効な整数です: " `Data.Monoid.mappend` t
|
||||||
japaneseFormMessage (MsgInvalidNumber t) = "無効な数値です: " `mappend` t
|
japaneseFormMessage (MsgInvalidNumber t) = "無効な数値です: " `mappend` t
|
||||||
japaneseFormMessage (MsgInvalidEntry t) = "無効な入力です: " `mappend` t
|
japaneseFormMessage (MsgInvalidEntry t) = "無効な入力です: " `mappend` t
|
||||||
japaneseFormMessage MsgInvalidTimeFormat = "無効な時刻です。HH:MM[:SS]フォーマットで入力してください"
|
japaneseFormMessage MsgInvalidTimeFormat = "無効な時刻です。HH:MM[:SS]フォーマットで入力してください"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import Data.Monoid (mappend)
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
|
||||||
norwegianBokmålFormMessage :: FormMessage -> Text
|
norwegianBokmålFormMessage :: FormMessage -> Text
|
||||||
norwegianBokmålFormMessage (MsgInvalidInteger t) = "Ugyldig antall: " `mappend` t
|
norwegianBokmålFormMessage (MsgInvalidInteger t) = "Ugyldig antall: " `Data.Monoid.mappend` t
|
||||||
norwegianBokmålFormMessage (MsgInvalidNumber t) = "Ugyldig nummer: " `mappend` t
|
norwegianBokmålFormMessage (MsgInvalidNumber t) = "Ugyldig nummer: " `mappend` t
|
||||||
norwegianBokmålFormMessage (MsgInvalidEntry t) = "Ugyldig oppføring: " `mappend` t
|
norwegianBokmålFormMessage (MsgInvalidEntry t) = "Ugyldig oppføring: " `mappend` t
|
||||||
norwegianBokmålFormMessage MsgInvalidTimeFormat = "Ugyldig klokkeslett, må være i formatet HH:MM[:SS]"
|
norwegianBokmålFormMessage MsgInvalidTimeFormat = "Ugyldig klokkeslett, må være i formatet HH:MM[:SS]"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import Data.Monoid (mappend)
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
|
||||||
portugueseFormMessage :: FormMessage -> Text
|
portugueseFormMessage :: FormMessage -> Text
|
||||||
portugueseFormMessage (MsgInvalidInteger t) = "Número inteiro inválido: " `mappend` t
|
portugueseFormMessage (MsgInvalidInteger t) = "Número inteiro inválido: " `Data.Monoid.mappend` t
|
||||||
portugueseFormMessage (MsgInvalidNumber t) = "Número inválido: " `mappend` t
|
portugueseFormMessage (MsgInvalidNumber t) = "Número inválido: " `mappend` t
|
||||||
portugueseFormMessage (MsgInvalidEntry t) = "Entrada inválida: " `mappend` t
|
portugueseFormMessage (MsgInvalidEntry t) = "Entrada inválida: " `mappend` t
|
||||||
portugueseFormMessage MsgInvalidTimeFormat = "Hora inválida, deve estar no formato HH:MM[:SS]"
|
portugueseFormMessage MsgInvalidTimeFormat = "Hora inválida, deve estar no formato HH:MM[:SS]"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import Data.Monoid (mappend)
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
|
||||||
russianFormMessage :: FormMessage -> Text
|
russianFormMessage :: FormMessage -> Text
|
||||||
russianFormMessage (MsgInvalidInteger t) = "Неверно записано целое число: " `mappend` t
|
russianFormMessage (MsgInvalidInteger t) = "Неверно записано целое число: " `Data.Monoid.mappend` t
|
||||||
russianFormMessage (MsgInvalidNumber t) = "Неверный формат числа: " `mappend` t
|
russianFormMessage (MsgInvalidNumber t) = "Неверный формат числа: " `mappend` t
|
||||||
russianFormMessage (MsgInvalidEntry t) = "Неверный выбор: " `mappend` t
|
russianFormMessage (MsgInvalidEntry t) = "Неверный выбор: " `mappend` t
|
||||||
russianFormMessage MsgInvalidTimeFormat = "Неверно указано время, используйте формат ЧЧ:ММ[:СС]"
|
russianFormMessage MsgInvalidTimeFormat = "Неверно указано время, используйте формат ЧЧ:ММ[:СС]"
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import Data.Monoid (mappend)
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
|
||||||
spanishFormMessage :: FormMessage -> Text
|
spanishFormMessage :: FormMessage -> Text
|
||||||
spanishFormMessage (MsgInvalidInteger t) = "Número entero inválido: " `mappend` t
|
spanishFormMessage (MsgInvalidInteger t) = "Número entero inválido: " `Data.Monoid.mappend` t
|
||||||
spanishFormMessage (MsgInvalidNumber t) = "Número inválido: " `mappend` t
|
spanishFormMessage (MsgInvalidNumber t) = "Número inválido: " `mappend` t
|
||||||
spanishFormMessage (MsgInvalidEntry t) = "Entrada inválida: " `mappend` t
|
spanishFormMessage (MsgInvalidEntry t) = "Entrada inválida: " `mappend` t
|
||||||
spanishFormMessage MsgInvalidTimeFormat = "Hora inválida, debe tener el formato HH:MM[:SS]"
|
spanishFormMessage MsgInvalidTimeFormat = "Hora inválida, debe tener el formato HH:MM[:SS]"
|
||||||
@ -24,4 +24,4 @@ spanishFormMessage MsgSelectNone = "<Ninguno>"
|
|||||||
spanishFormMessage (MsgInvalidBool t) = "Booleano inválido: " `mappend` t
|
spanishFormMessage (MsgInvalidBool t) = "Booleano inválido: " `mappend` t
|
||||||
spanishFormMessage MsgBoolYes = "Sí"
|
spanishFormMessage MsgBoolYes = "Sí"
|
||||||
spanishFormMessage MsgBoolNo = "No"
|
spanishFormMessage MsgBoolNo = "No"
|
||||||
spanishFormMessage MsgDelete = "¿Eliminar?"
|
spanishFormMessage MsgDelete = "¿Eliminar?"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import Data.Monoid (mappend)
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
|
||||||
swedishFormMessage :: FormMessage -> Text
|
swedishFormMessage :: FormMessage -> Text
|
||||||
swedishFormMessage (MsgInvalidInteger t) = "Ogiltigt antal: " `mappend` t
|
swedishFormMessage (MsgInvalidInteger t) = "Ogiltigt antal: " `Data.Monoid.mappend` t
|
||||||
swedishFormMessage (MsgInvalidNumber t) = "Ogiltigt nummer: " `mappend` t
|
swedishFormMessage (MsgInvalidNumber t) = "Ogiltigt nummer: " `mappend` t
|
||||||
swedishFormMessage (MsgInvalidEntry t) = "Invalid entry: " `mappend` t
|
swedishFormMessage (MsgInvalidEntry t) = "Invalid entry: " `mappend` t
|
||||||
swedishFormMessage MsgInvalidTimeFormat = "Ogiltigt klockslag, måste vara på formatet HH:MM[:SS]"
|
swedishFormMessage MsgInvalidTimeFormat = "Ogiltigt klockslag, måste vara på formatet HH:MM[:SS]"
|
||||||
|
|||||||
@ -29,7 +29,7 @@ type DText = [Text] -> [Text]
|
|||||||
newtype FormInput m a = FormInput { unFormInput :: HandlerSite m -> [Text] -> Env -> FileEnv -> m (Either DText a) }
|
newtype FormInput m a = FormInput { unFormInput :: HandlerSite m -> [Text] -> Env -> FileEnv -> m (Either DText a) }
|
||||||
instance Monad m => Functor (FormInput m) where
|
instance Monad m => Functor (FormInput m) where
|
||||||
fmap a (FormInput f) = FormInput $ \c d e e' -> liftM (either Left (Right . a)) $ f c d e e'
|
fmap a (FormInput f) = FormInput $ \c d e e' -> liftM (either Left (Right . a)) $ f c d e e'
|
||||||
instance Monad m => Applicative (FormInput m) where
|
instance Monad m => Control.Applicative.Applicative (FormInput m) where
|
||||||
pure = FormInput . const . const . const . const . return . Right
|
pure = FormInput . const . const . const . const . return . Right
|
||||||
(FormInput f) <*> (FormInput x) = FormInput $ \c d e e' -> do
|
(FormInput f) <*> (FormInput x) = FormInput $ \c d e e' -> do
|
||||||
res1 <- f c d e e'
|
res1 <- f c d e e'
|
||||||
|
|||||||
@ -18,14 +18,13 @@ import Yesod.Core
|
|||||||
import Yesod.Form
|
import Yesod.Form
|
||||||
import Data.Time (Day)
|
import Data.Time (Day)
|
||||||
import Data.Default
|
import Data.Default
|
||||||
import Text.Hamlet (shamlet)
|
import Text.Julius (rawJS)
|
||||||
import Text.Julius (julius, rawJS)
|
|
||||||
import Data.Text (Text, pack, unpack)
|
import Data.Text (Text, pack, unpack)
|
||||||
import Data.Monoid (mconcat)
|
import Data.Monoid (mconcat)
|
||||||
|
|
||||||
-- | Gets the Google hosted jQuery UI 1.8 CSS file with the given theme.
|
-- | Gets the Google hosted jQuery UI 1.8 CSS file with the given theme.
|
||||||
googleHostedJqueryUiCss :: Text -> Text
|
googleHostedJqueryUiCss :: Text -> Text
|
||||||
googleHostedJqueryUiCss theme = mconcat
|
googleHostedJqueryUiCss theme = Data.Monoid.mconcat
|
||||||
[ "//ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/"
|
[ "//ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/"
|
||||||
, theme
|
, theme
|
||||||
, "/jquery-ui.css"
|
, "/jquery-ui.css"
|
||||||
|
|||||||
@ -44,7 +44,7 @@ up i = do
|
|||||||
|
|
||||||
-- | Generate a form that accepts 0 or more values from the user, allowing the
|
-- | Generate a form that accepts 0 or more values from the user, allowing the
|
||||||
-- user to specify that a new row is necessary.
|
-- user to specify that a new row is necessary.
|
||||||
inputList :: (m ~ HandlerT site IO, xml ~ WidgetT site IO (), RenderMessage site FormMessage)
|
inputList :: (xml ~ WidgetT site IO (), RenderMessage site FormMessage)
|
||||||
=> Html
|
=> Html
|
||||||
-- ^ label for the form
|
-- ^ label for the form
|
||||||
-> ([[FieldView site]] -> xml)
|
-> ([[FieldView site]] -> xml)
|
||||||
@ -119,14 +119,13 @@ $newline never
|
|||||||
up 1
|
up 1
|
||||||
return res
|
return res
|
||||||
|
|
||||||
fixme :: (xml ~ WidgetT site IO ())
|
fixme :: [Either xml (FormResult a, [FieldView site])]
|
||||||
=> [Either xml (FormResult a, [FieldView site])]
|
|
||||||
-> (FormResult [a], [xml], [[FieldView site]])
|
-> (FormResult [a], [xml], [[FieldView site]])
|
||||||
fixme eithers =
|
fixme eithers =
|
||||||
(res, xmls, map snd rest)
|
(res, xmls, map snd rest)
|
||||||
where
|
where
|
||||||
(xmls, rest) = partitionEithers eithers
|
(xmls, rest) = partitionEithers eithers
|
||||||
res = sequenceA $ map fst rest
|
res = Data.Traversable.sequenceA $ map fst rest
|
||||||
|
|
||||||
massDivs, massTable
|
massDivs, massTable
|
||||||
:: [[FieldView site]]
|
:: [[FieldView site]]
|
||||||
|
|||||||
@ -19,8 +19,7 @@ module Yesod.Form.Nic
|
|||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import Yesod.Form
|
import Yesod.Form
|
||||||
import Text.HTML.SanitizeXSS (sanitizeBalance)
|
import Text.HTML.SanitizeXSS (sanitizeBalance)
|
||||||
import Text.Hamlet (shamlet)
|
import Text.Julius (rawJS)
|
||||||
import Text.Julius (julius, rawJS)
|
|
||||||
import Text.Blaze.Html.Renderer.String (renderHtml)
|
import Text.Blaze.Html.Renderer.String (renderHtml)
|
||||||
import Data.Text (Text, pack)
|
import Data.Text (Text, pack)
|
||||||
import Data.Maybe (listToMaybe)
|
import Data.Maybe (listToMaybe)
|
||||||
|
|||||||
@ -51,28 +51,28 @@ instance Functor FormResult where
|
|||||||
fmap _ FormMissing = FormMissing
|
fmap _ FormMissing = FormMissing
|
||||||
fmap _ (FormFailure errs) = FormFailure errs
|
fmap _ (FormFailure errs) = FormFailure errs
|
||||||
fmap f (FormSuccess a) = FormSuccess $ f a
|
fmap f (FormSuccess a) = FormSuccess $ f a
|
||||||
instance Applicative FormResult where
|
instance Control.Applicative.Applicative FormResult where
|
||||||
pure = FormSuccess
|
pure = FormSuccess
|
||||||
(FormSuccess f) <*> (FormSuccess g) = FormSuccess $ f g
|
(FormSuccess f) <*> (FormSuccess g) = FormSuccess $ f g
|
||||||
(FormFailure x) <*> (FormFailure y) = FormFailure $ x ++ y
|
(FormFailure x) <*> (FormFailure y) = FormFailure $ x ++ y
|
||||||
(FormFailure x) <*> _ = FormFailure x
|
(FormFailure x) <*> _ = FormFailure x
|
||||||
_ <*> (FormFailure y) = FormFailure y
|
_ <*> (FormFailure y) = FormFailure y
|
||||||
_ <*> _ = FormMissing
|
_ <*> _ = FormMissing
|
||||||
instance Monoid m => Monoid (FormResult m) where
|
instance Data.Monoid.Monoid m => Monoid (FormResult m) where
|
||||||
mempty = pure mempty
|
mempty = pure mempty
|
||||||
mappend x y = mappend <$> x <*> y
|
mappend x y = mappend <$> x <*> y
|
||||||
instance Semigroup m => Semigroup (FormResult m) where
|
instance Semigroup m => Semigroup (FormResult m) where
|
||||||
x <> y = (<>) <$> x <*> y
|
x <> y = (<>) Control.Applicative.<$> x <*> y
|
||||||
|
|
||||||
-- | @since 1.4.5
|
-- | @since 1.4.5
|
||||||
instance Foldable FormResult where
|
instance Data.Foldable.Foldable FormResult where
|
||||||
foldMap f r = case r of
|
foldMap f r = case r of
|
||||||
FormSuccess a -> f a
|
FormSuccess a -> f a
|
||||||
FormFailure errs -> mempty
|
FormFailure _errs -> mempty
|
||||||
FormMissing -> mempty
|
FormMissing -> mempty
|
||||||
|
|
||||||
-- | @since 1.4.5
|
-- | @since 1.4.5
|
||||||
instance Traversable FormResult where
|
instance Data.Traversable.Traversable FormResult where
|
||||||
traverse f r = case r of
|
traverse f r = case r of
|
||||||
FormSuccess a -> fmap FormSuccess (f a)
|
FormSuccess a -> fmap FormSuccess (f a)
|
||||||
FormFailure errs -> pure (FormFailure errs)
|
FormFailure errs -> pure (FormFailure errs)
|
||||||
|
|||||||
@ -23,7 +23,7 @@ module Yesod.Persist.Core
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import Database.Persist
|
import Database.Persist
|
||||||
import Control.Monad.Trans.Reader (ReaderT, runReaderT, withReaderT)
|
import Control.Monad.Trans.Reader (ReaderT, runReaderT)
|
||||||
|
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import Data.Conduit
|
import Data.Conduit
|
||||||
|
|||||||
@ -49,7 +49,7 @@ module Yesod.EmbeddedStatic (
|
|||||||
, module Yesod.EmbeddedStatic.Generators
|
, module Yesod.EmbeddedStatic.Generators
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Applicative ((<$>))
|
import Control.Applicative as A ((<$>))
|
||||||
import Data.IORef
|
import Data.IORef
|
||||||
import Data.Maybe (catMaybes)
|
import Data.Maybe (catMaybes)
|
||||||
import Language.Haskell.TH
|
import Language.Haskell.TH
|
||||||
@ -59,7 +59,6 @@ import Network.Wai.Application.Static (staticApp)
|
|||||||
import System.IO.Unsafe (unsafePerformIO)
|
import System.IO.Unsafe (unsafePerformIO)
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
( HandlerT
|
( HandlerT
|
||||||
, Yesod(..)
|
|
||||||
, YesodSubDispatch(..)
|
, YesodSubDispatch(..)
|
||||||
)
|
)
|
||||||
import Yesod.Core.Types
|
import Yesod.Core.Types
|
||||||
@ -82,7 +81,7 @@ import Yesod.EmbeddedStatic.Generators
|
|||||||
embeddedResourceR :: [T.Text] -> [(T.Text, T.Text)] -> Route EmbeddedStatic
|
embeddedResourceR :: [T.Text] -> [(T.Text, T.Text)] -> Route EmbeddedStatic
|
||||||
embeddedResourceR = EmbeddedResourceR
|
embeddedResourceR = EmbeddedResourceR
|
||||||
|
|
||||||
instance Yesod master => YesodSubDispatch EmbeddedStatic (HandlerT master IO) where
|
instance YesodSubDispatch EmbeddedStatic (HandlerT master IO) where
|
||||||
yesodSubDispatch YesodSubRunnerEnv {..} req = resp
|
yesodSubDispatch YesodSubRunnerEnv {..} req = resp
|
||||||
where
|
where
|
||||||
master = yreSite ysreParentEnv
|
master = yreSite ysreParentEnv
|
||||||
@ -136,7 +135,7 @@ mkEmbeddedStatic :: Bool -- ^ development?
|
|||||||
-> [Generator] -- ^ the generators (see "Yesod.EmbeddedStatic.Generators")
|
-> [Generator] -- ^ the generators (see "Yesod.EmbeddedStatic.Generators")
|
||||||
-> Q [Dec]
|
-> Q [Dec]
|
||||||
mkEmbeddedStatic dev esName gen = do
|
mkEmbeddedStatic dev esName gen = do
|
||||||
entries <- concat <$> sequence gen
|
entries <- concat A.<$> sequence gen
|
||||||
computed <- runIO $ mapM (if dev then devEmbed else prodEmbed) entries
|
computed <- runIO $ mapM (if dev then devEmbed else prodEmbed) entries
|
||||||
|
|
||||||
let settings = Static.mkSettings $ return $ map cStEntry computed
|
let settings = Static.mkSettings $ return $ map cStEntry computed
|
||||||
@ -176,8 +175,7 @@ mkEmbeddedStatic dev esName gen = do
|
|||||||
-- > addStaticContent = embedStaticContent getStatic StaticR mini
|
-- > addStaticContent = embedStaticContent getStatic StaticR mini
|
||||||
-- > where mini = if development then Right else minifym
|
-- > where mini = if development then Right else minifym
|
||||||
-- > ...
|
-- > ...
|
||||||
embedStaticContent :: Yesod site
|
embedStaticContent :: (site -> EmbeddedStatic) -- ^ How to retrieve the embedded static subsite from your site
|
||||||
=> (site -> EmbeddedStatic) -- ^ How to retrieve the embedded static subsite from your site
|
|
||||||
-> (Route EmbeddedStatic -> Route site) -- ^ how to convert an embedded static route
|
-> (Route EmbeddedStatic -> Route site) -- ^ how to convert an embedded static route
|
||||||
-> (BL.ByteString -> Either a BL.ByteString) -- ^ javascript minifier
|
-> (BL.ByteString -> Either a BL.ByteString) -- ^ javascript minifier
|
||||||
-> AddStaticContent site
|
-> AddStaticContent site
|
||||||
|
|||||||
@ -30,10 +30,9 @@ module Yesod.EmbeddedStatic.Generators (
|
|||||||
-- $example
|
-- $example
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Applicative ((<$>), (<*>))
|
import Control.Applicative as A ((<$>), (<*>))
|
||||||
import Control.Exception (try, SomeException)
|
import Control.Exception (try, SomeException)
|
||||||
import Control.Monad (forM, when)
|
import Control.Monad (forM, when)
|
||||||
import Control.Monad.Trans.Resource (runResourceT)
|
|
||||||
import Data.Char (isDigit, isLower)
|
import Data.Char (isDigit, isLower)
|
||||||
import Data.Conduit (($$))
|
import Data.Conduit (($$))
|
||||||
import Data.Default (def)
|
import Data.Default (def)
|
||||||
@ -209,9 +208,9 @@ compressTool f opts ct = do
|
|||||||
}
|
}
|
||||||
(Just hin, Just hout, _, ph) <- Proc.createProcess p
|
(Just hin, Just hout, _, ph) <- Proc.createProcess p
|
||||||
(compressed, (), code) <- runConcurrently $ (,,)
|
(compressed, (), code) <- runConcurrently $ (,,)
|
||||||
<$> Concurrently (sourceHandle hout $$ C.consume)
|
A.<$> Concurrently (sourceHandle hout $$ C.consume)
|
||||||
<*> Concurrently (BL.hPut hin ct >> hClose hin)
|
A.<*> Concurrently (BL.hPut hin ct >> hClose hin)
|
||||||
<*> Concurrently (Proc.waitForProcess ph)
|
A.<*> Concurrently (Proc.waitForProcess ph)
|
||||||
if code == ExitSuccess
|
if code == ExitSuccess
|
||||||
then do
|
then do
|
||||||
putStrLn $ "Compressed successfully with " ++ f
|
putStrLn $ "Compressed successfully with " ++ f
|
||||||
|
|||||||
@ -16,7 +16,7 @@ module Yesod.EmbeddedStatic.Internal (
|
|||||||
, widgetSettings
|
, widgetSettings
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Applicative ((<$>))
|
import Control.Applicative as A ((<$>))
|
||||||
import Data.IORef
|
import Data.IORef
|
||||||
import Language.Haskell.TH
|
import Language.Haskell.TH
|
||||||
import Network.HTTP.Types (Status(..), status404, status200, status304)
|
import Network.HTTP.Types (Status(..), status404, status200, status304)
|
||||||
@ -28,7 +28,6 @@ import Yesod.Core
|
|||||||
( HandlerT
|
( HandlerT
|
||||||
, ParseRoute(..)
|
, ParseRoute(..)
|
||||||
, RenderRoute(..)
|
, RenderRoute(..)
|
||||||
, Yesod(..)
|
|
||||||
, getYesod
|
, getYesod
|
||||||
, liftIO
|
, liftIO
|
||||||
)
|
)
|
||||||
@ -140,13 +139,12 @@ type AddStaticContent site = T.Text -> T.Text -> BL.ByteString
|
|||||||
-> HandlerT site IO (Maybe (Either T.Text (Route site, [(T.Text, T.Text)])))
|
-> HandlerT site IO (Maybe (Either T.Text (Route site, [(T.Text, T.Text)])))
|
||||||
|
|
||||||
-- | Helper for embedStaticContent and embedLicensedStaticContent.
|
-- | Helper for embedStaticContent and embedLicensedStaticContent.
|
||||||
staticContentHelper :: Yesod site
|
staticContentHelper :: (site -> EmbeddedStatic)
|
||||||
=> (site -> EmbeddedStatic)
|
|
||||||
-> (Route EmbeddedStatic -> Route site)
|
-> (Route EmbeddedStatic -> Route site)
|
||||||
-> (BL.ByteString -> Either a BL.ByteString)
|
-> (BL.ByteString -> Either a BL.ByteString)
|
||||||
-> AddStaticContent site
|
-> AddStaticContent site
|
||||||
staticContentHelper getStatic staticR minify ext _ ct = do
|
staticContentHelper getStatic staticR minify ext _ ct = do
|
||||||
wIORef <- widgetFiles . getStatic <$> getYesod
|
wIORef <- widgetFiles . getStatic A.<$> getYesod
|
||||||
let hash = T.pack $ base64md5 ct
|
let hash = T.pack $ base64md5 ct
|
||||||
hash' = Just $ T.encodeUtf8 hash
|
hash' = Just $ T.encodeUtf8 hash
|
||||||
filename = T.concat [hash, ".", ext]
|
filename = T.concat [hash, ".", ext]
|
||||||
|
|||||||
@ -96,9 +96,8 @@ import Data.Conduit.List (sourceList, consume)
|
|||||||
import Data.Conduit.Binary (sourceFile)
|
import Data.Conduit.Binary (sourceFile)
|
||||||
import qualified Data.Conduit.Text as CT
|
import qualified Data.Conduit.Text as CT
|
||||||
import Data.Functor.Identity (runIdentity)
|
import Data.Functor.Identity (runIdentity)
|
||||||
import System.FilePath ((</>), (<.>), FilePath, takeDirectory)
|
import System.FilePath ((</>), (<.>), takeDirectory)
|
||||||
import qualified System.FilePath as F
|
import qualified System.FilePath as F
|
||||||
import System.Directory (createDirectoryIfMissing)
|
|
||||||
import qualified Data.Text.Lazy as TL
|
import qualified Data.Text.Lazy as TL
|
||||||
import qualified Data.Text.Lazy.Encoding as TLE
|
import qualified Data.Text.Lazy.Encoding as TLE
|
||||||
import Data.Default
|
import Data.Default
|
||||||
@ -349,7 +348,6 @@ mkStaticFilesList fp fs makeHash = do
|
|||||||
| isLower (head name') -> name'
|
| isLower (head name') -> name'
|
||||||
| otherwise -> '_' : name'
|
| otherwise -> '_' : name'
|
||||||
f' <- [|map pack $(TH.lift f)|]
|
f' <- [|map pack $(TH.lift f)|]
|
||||||
pack' <- [|pack|]
|
|
||||||
qs <- if makeHash
|
qs <- if makeHash
|
||||||
then do hash <- qRunIO $ base64md5File $ pathFromRawPieces fp f
|
then do hash <- qRunIO $ base64md5File $ pathFromRawPieces fp f
|
||||||
[|[(pack "etag", pack $(TH.lift hash))]|]
|
[|[(pack "etag", pack $(TH.lift hash))]|]
|
||||||
@ -505,9 +503,6 @@ instance Default CombineSettings where
|
|||||||
, csCombinedFolder = "combined"
|
, csCombinedFolder = "combined"
|
||||||
}
|
}
|
||||||
|
|
||||||
errorIntro :: [FilePath] -> [Char] -> [Char]
|
|
||||||
errorIntro fps s = "Error minifying " ++ show fps ++ ": " ++ s
|
|
||||||
|
|
||||||
liftRoutes :: [Route Static] -> Q Exp
|
liftRoutes :: [Route Static] -> Q Exp
|
||||||
liftRoutes =
|
liftRoutes =
|
||||||
fmap ListE . mapM go
|
fmap ListE . mapM go
|
||||||
|
|||||||
@ -5,8 +5,8 @@ import Control.Applicative
|
|||||||
import Control.Monad (when)
|
import Control.Monad (when)
|
||||||
import Data.List (sortBy)
|
import Data.List (sortBy)
|
||||||
import Language.Haskell.TH
|
import Language.Haskell.TH
|
||||||
import Test.HUnit hiding (Location)
|
import Test.HUnit
|
||||||
import Yesod.EmbeddedStatic.Types
|
import Yesod.EmbeddedStatic.Types as Y
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
|
|
||||||
-- We test the generators by executing them at compile time
|
-- We test the generators by executing them at compile time
|
||||||
@ -20,8 +20,8 @@ data GenTestResult = GenError String
|
|||||||
| GenSuccessWithDevel (IO BL.ByteString)
|
| GenSuccessWithDevel (IO BL.ByteString)
|
||||||
|
|
||||||
-- | Creates a GenTestResult at compile time by testing the entry.
|
-- | Creates a GenTestResult at compile time by testing the entry.
|
||||||
testEntry :: Maybe String -> Location -> IO BL.ByteString -> Entry -> ExpQ
|
testEntry :: Maybe String -> Y.Location -> IO BL.ByteString -> Entry -> ExpQ
|
||||||
testEntry name _ _ e | ebHaskellName e /= (mkName <$> name) =
|
testEntry name _ _ e | ebHaskellName e /= (mkName Control.Applicative.<$> name) =
|
||||||
[| GenError ("haskell name " ++ $(litE $ stringL $ show $ ebHaskellName e)
|
[| GenError ("haskell name " ++ $(litE $ stringL $ show $ ebHaskellName e)
|
||||||
++ " /= "
|
++ " /= "
|
||||||
++ $(litE $ stringL $ show name)) |]
|
++ $(litE $ stringL $ show name)) |]
|
||||||
@ -34,12 +34,12 @@ testEntry _ _ act e = do
|
|||||||
then [| GenSuccessWithDevel $(ebDevelReload e) |]
|
then [| GenSuccessWithDevel $(ebDevelReload e) |]
|
||||||
else [| GenError "production content" |]
|
else [| GenError "production content" |]
|
||||||
|
|
||||||
testOneEntry :: Maybe String -> Location -> IO BL.ByteString -> [Entry] -> ExpQ
|
testOneEntry :: Maybe String -> Y.Location -> IO BL.ByteString -> [Entry] -> ExpQ
|
||||||
testOneEntry name loc ct [e] = testEntry name loc ct e
|
testOneEntry name loc ct [e] = testEntry name loc ct e
|
||||||
testOneEntry _ _ _ _ = [| GenError "not exactly one entry" |]
|
testOneEntry _ _ _ _ = [| GenError "not exactly one entry" |]
|
||||||
|
|
||||||
-- | Tests a list of entries
|
-- | Tests a list of entries
|
||||||
testEntries :: [(Maybe String, Location, IO BL.ByteString)] -> [Entry] -> ExpQ
|
testEntries :: [(Maybe String, Y.Location, IO BL.ByteString)] -> [Entry] -> ExpQ
|
||||||
testEntries a b | length a /= length b = [| [GenError "lengths differ"] |]
|
testEntries a b | length a /= length b = [| [GenError "lengths differ"] |]
|
||||||
testEntries a b = listE $ zipWith f a' b'
|
testEntries a b = listE $ zipWith f a' b'
|
||||||
where
|
where
|
||||||
|
|||||||
@ -78,6 +78,17 @@ test-suite tests
|
|||||||
main-is: tests.hs
|
main-is: tests.hs
|
||||||
type: exitcode-stdio-1.0
|
type: exitcode-stdio-1.0
|
||||||
cpp-options: -DTEST_EXPORT
|
cpp-options: -DTEST_EXPORT
|
||||||
|
other-modules: EmbedDevelTest
|
||||||
|
EmbedProductionTest
|
||||||
|
EmbedTestGenerator
|
||||||
|
FileGeneratorTests
|
||||||
|
GeneratorTestUtil
|
||||||
|
Yesod.EmbeddedStatic
|
||||||
|
Yesod.EmbeddedStatic.Generators
|
||||||
|
Yesod.EmbeddedStatic.Internal
|
||||||
|
Yesod.EmbeddedStatic.Types
|
||||||
|
Yesod.Static
|
||||||
|
YesodStaticTest
|
||||||
build-depends: base
|
build-depends: base
|
||||||
, hspec >= 1.3
|
, hspec >= 1.3
|
||||||
, yesod-test >= 1.4
|
, yesod-test >= 1.4
|
||||||
|
|||||||
@ -132,6 +132,7 @@ import Network.Wai.Test hiding (assertHeader, assertNoHeader, request)
|
|||||||
import qualified Control.Monad.Trans.State as ST
|
import qualified Control.Monad.Trans.State as ST
|
||||||
import Control.Monad.IO.Class
|
import Control.Monad.IO.Class
|
||||||
import System.IO
|
import System.IO
|
||||||
|
import Yesod.Core.Unsafe (runFakeHandler)
|
||||||
import Yesod.Test.TransversingCSS
|
import Yesod.Test.TransversingCSS
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import qualified Data.Text.Lazy as TL
|
import qualified Data.Text.Lazy as TL
|
||||||
@ -678,7 +679,7 @@ addTokenFromCookieNamedToHeaderNamed cookieName headerName = do
|
|||||||
getRequestCookies :: RequestBuilder site Cookies
|
getRequestCookies :: RequestBuilder site Cookies
|
||||||
getRequestCookies = do
|
getRequestCookies = do
|
||||||
requestBuilderData <- ST.get
|
requestBuilderData <- ST.get
|
||||||
headers <- case simpleHeaders <$> rbdResponse requestBuilderData of
|
headers <- case simpleHeaders Control.Applicative.<$> rbdResponse requestBuilderData of
|
||||||
Just h -> return h
|
Just h -> return h
|
||||||
Nothing -> failure "getRequestCookies: No request has been made yet; the cookies can't be looked up."
|
Nothing -> failure "getRequestCookies: No request has been made yet; the cookies can't be looked up."
|
||||||
|
|
||||||
@ -759,8 +760,7 @@ followRedirect = do
|
|||||||
-- > (Right (ResourceR resourceId)) <- getLocation
|
-- > (Right (ResourceR resourceId)) <- getLocation
|
||||||
--
|
--
|
||||||
-- @since 1.5.4
|
-- @since 1.5.4
|
||||||
getLocation :: (Yesod site, ParseRoute site)
|
getLocation :: ParseRoute site => YesodExample site (Either T.Text (Route site))
|
||||||
=> YesodExample site (Either T.Text (Route site))
|
|
||||||
getLocation = do
|
getLocation = do
|
||||||
mr <- getResponse
|
mr <- getResponse
|
||||||
case mr of
|
case mr of
|
||||||
@ -802,7 +802,7 @@ setUrl :: (Yesod site, RedirectUrl site url)
|
|||||||
-> RequestBuilder site ()
|
-> RequestBuilder site ()
|
||||||
setUrl url' = do
|
setUrl url' = do
|
||||||
site <- fmap rbdSite ST.get
|
site <- fmap rbdSite ST.get
|
||||||
eurl <- runFakeHandler
|
eurl <- Yesod.Core.Unsafe.runFakeHandler
|
||||||
M.empty
|
M.empty
|
||||||
(const $ error "Yesod.Test: No logger available")
|
(const $ error "Yesod.Test: No logger available")
|
||||||
site
|
site
|
||||||
@ -828,9 +828,7 @@ setUrl url' = do
|
|||||||
-- > import Data.Aeson
|
-- > import Data.Aeson
|
||||||
-- > request $ do
|
-- > request $ do
|
||||||
-- > setRequestBody $ encode $ object ["age" .= (1 :: Integer)]
|
-- > setRequestBody $ encode $ object ["age" .= (1 :: Integer)]
|
||||||
setRequestBody :: (Yesod site)
|
setRequestBody :: BSL8.ByteString -> RequestBuilder site ()
|
||||||
=> BSL8.ByteString
|
|
||||||
-> RequestBuilder site ()
|
|
||||||
setRequestBody body = ST.modify $ \rbd -> rbd { rbdPostData = BinaryPostData body }
|
setRequestBody body = ST.modify $ \rbd -> rbd { rbdPostData = BinaryPostData body }
|
||||||
|
|
||||||
-- | Adds the given header to the request; see "Network.HTTP.Types.Header" for creating 'Header's.
|
-- | Adds the given header to the request; see "Network.HTTP.Types.Header" for creating 'Header's.
|
||||||
@ -858,8 +856,7 @@ addRequestHeader header = ST.modify $ \rbd -> rbd
|
|||||||
-- > byLabel "First Name" "Felipe"
|
-- > byLabel "First Name" "Felipe"
|
||||||
-- > setMethod "PUT"
|
-- > setMethod "PUT"
|
||||||
-- > setUrl NameR
|
-- > setUrl NameR
|
||||||
request :: Yesod site
|
request :: RequestBuilder site ()
|
||||||
=> RequestBuilder site ()
|
|
||||||
-> YesodExample site ()
|
-> YesodExample site ()
|
||||||
request reqBuilder = do
|
request reqBuilder = do
|
||||||
YesodExampleData app site oldCookies mRes <- ST.get
|
YesodExampleData app site oldCookies mRes <- ST.get
|
||||||
|
|||||||
@ -59,8 +59,8 @@ type HtmlLBS = L.ByteString
|
|||||||
-- * Right: List of matching Html fragments.
|
-- * Right: List of matching Html fragments.
|
||||||
findBySelector :: HtmlLBS -> Query -> Either String [String]
|
findBySelector :: HtmlLBS -> Query -> Either String [String]
|
||||||
findBySelector html query = (\x -> map (renderHtml . toHtml . node) . runQuery x)
|
findBySelector html query = (\x -> map (renderHtml . toHtml . node) . runQuery x)
|
||||||
<$> (Right $ fromDocument $ HD.parseLBS html)
|
Control.Applicative.<$> (Right $ fromDocument $ HD.parseLBS html)
|
||||||
<*> parseQuery query
|
Control.Applicative.<*> parseQuery query
|
||||||
|
|
||||||
-- Run a compiled query on Html, returning a list of matching Html fragments.
|
-- Run a compiled query on Html, returning a list of matching Html fragments.
|
||||||
runQuery :: Cursor -> [[SelectorGroup]] -> [Cursor]
|
runQuery :: Cursor -> [[SelectorGroup]] -> [Cursor]
|
||||||
|
|||||||
@ -6,6 +6,13 @@
|
|||||||
{-# LANGUAGE QuasiQuotes #-}
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
{-# LANGUAGE TypeFamilies #-}
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
{-# LANGUAGE ViewPatterns #-}
|
{-# LANGUAGE ViewPatterns #-}
|
||||||
|
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
||||||
|
module Main
|
||||||
|
( main
|
||||||
|
-- avoid warnings
|
||||||
|
, resourcesRoutedApp
|
||||||
|
, Widget
|
||||||
|
) where
|
||||||
|
|
||||||
import Test.HUnit hiding (Test)
|
import Test.HUnit hiding (Test)
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
@ -22,16 +29,17 @@ import Control.Applicative
|
|||||||
import Network.Wai (pathInfo, requestHeaders)
|
import Network.Wai (pathInfo, requestHeaders)
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe)
|
||||||
import Data.Either (isLeft, isRight)
|
import Data.Either (isLeft, isRight)
|
||||||
import Control.Exception.Lifted(try, SomeException)
|
|
||||||
|
|
||||||
import Data.ByteString.Lazy.Char8 ()
|
import Data.ByteString.Lazy.Char8 ()
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import qualified Text.HTML.DOM as HD
|
import qualified Text.HTML.DOM as HD
|
||||||
import Network.HTTP.Types.Status (status301, status303, unsupportedMediaType415)
|
import Network.HTTP.Types.Status (status301, status303, unsupportedMediaType415)
|
||||||
|
|
||||||
|
parseQuery_ :: Text -> [[SelectorGroup]]
|
||||||
parseQuery_ = either error id . parseQuery
|
parseQuery_ = either error id . parseQuery
|
||||||
|
|
||||||
|
findBySelector_ :: HtmlLBS -> Query -> [String]
|
||||||
findBySelector_ x = either error id . findBySelector x
|
findBySelector_ x = either error id . findBySelector x
|
||||||
parseHtml_ = HD.parseLBS
|
|
||||||
|
|
||||||
data RoutedApp = RoutedApp
|
data RoutedApp = RoutedApp
|
||||||
|
|
||||||
@ -86,7 +94,7 @@ main = hspec $ do
|
|||||||
[NodeContent "Hello World"]
|
[NodeContent "Hello World"]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
in parseHtml_ html @?= doc
|
in HD.parseLBS html @?= doc
|
||||||
it "HTML" $
|
it "HTML" $
|
||||||
let html = "<html><head><title>foo</title></head><body><br><p>Hello World</p></body></html>"
|
let html = "<html><head><title>foo</title></head><body><br><p>Hello World</p></body></html>"
|
||||||
doc = Document (Prologue [] Nothing []) root []
|
doc = Document (Prologue [] Nothing []) root []
|
||||||
@ -101,7 +109,7 @@ main = hspec $ do
|
|||||||
[NodeContent "Hello World"]
|
[NodeContent "Hello World"]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
in parseHtml_ html @?= doc
|
in HD.parseLBS html @?= doc
|
||||||
describe "basic usage" $ yesodSpec app $ do
|
describe "basic usage" $ yesodSpec app $ do
|
||||||
ydescribe "tests1" $ do
|
ydescribe "tests1" $ do
|
||||||
yit "tests1a" $ do
|
yit "tests1a" $ do
|
||||||
@ -310,7 +318,7 @@ app = liteApp $ do
|
|||||||
((mfoo, widget), _) <- runFormPost
|
((mfoo, widget), _) <- runFormPost
|
||||||
$ renderDivs
|
$ renderDivs
|
||||||
$ (,)
|
$ (,)
|
||||||
<$> areq textField "Some Label" Nothing
|
Control.Applicative.<$> areq textField "Some Label" Nothing
|
||||||
<*> areq fileField "Some File" Nothing
|
<*> areq fileField "Some File" Nothing
|
||||||
case mfoo of
|
case mfoo of
|
||||||
FormSuccess (foo, _) -> return $ toHtml foo
|
FormSuccess (foo, _) -> return $ toHtml foo
|
||||||
@ -337,7 +345,7 @@ cookieApp = liteApp $ do
|
|||||||
onStatic "cookie" $ do
|
onStatic "cookie" $ do
|
||||||
onStatic "foo" $ dispatchTo $ do
|
onStatic "foo" $ dispatchTo $ do
|
||||||
setMessage "Foo"
|
setMessage "Foo"
|
||||||
redirect ("/cookie/home" :: Text)
|
() <- redirect ("/cookie/home" :: Text)
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
instance Yesod RoutedApp where
|
instance Yesod RoutedApp where
|
||||||
|
|||||||
@ -130,10 +130,10 @@ webSocketsOptionsWith wsConnOpts buildAr inner = do
|
|||||||
sink
|
sink
|
||||||
|
|
||||||
-- | Wrapper for capturing exceptions
|
-- | Wrapper for capturing exceptions
|
||||||
wrapWSE :: (MonadIO m, WS.WebSocketsData a) => (WS.Connection -> a -> IO ())-> a -> WebSocketsT m (Either SomeException ())
|
wrapWSE :: MonadIO m => (WS.Connection -> a -> IO ())-> a -> WebSocketsT m (Either SomeException ())
|
||||||
wrapWSE ws x = ReaderT $ liftIO . tryAny . flip ws x
|
wrapWSE ws x = ReaderT $ liftIO . tryAny . flip ws x
|
||||||
|
|
||||||
wrapWS :: (MonadIO m, WS.WebSocketsData a) => (WS.Connection -> a -> IO ()) -> a -> WebSocketsT m ()
|
wrapWS :: MonadIO m => (WS.Connection -> a -> IO ()) -> a -> WebSocketsT m ()
|
||||||
wrapWS ws x = ReaderT $ liftIO . flip ws x
|
wrapWS ws x = ReaderT $ liftIO . flip ws x
|
||||||
|
|
||||||
-- | Receive a piece of data from the client.
|
-- | Receive a piece of data from the client.
|
||||||
|
|||||||
@ -28,10 +28,6 @@ module Yesod.Default.Config2
|
|||||||
|
|
||||||
import Data.Yaml.Config
|
import Data.Yaml.Config
|
||||||
|
|
||||||
#if __GLASGOW_HASKELL__ < 710
|
|
||||||
import Control.Applicative ((<$>))
|
|
||||||
import Data.Monoid
|
|
||||||
#endif
|
|
||||||
import Data.Semigroup
|
import Data.Semigroup
|
||||||
import Data.Aeson
|
import Data.Aeson
|
||||||
import qualified Data.HashMap.Strict as H
|
import qualified Data.HashMap.Strict as H
|
||||||
|
|||||||
@ -41,8 +41,7 @@ import Control.Concurrent.MVar (newEmptyMVar, putMVar, takeMVar)
|
|||||||
-- > main :: IO ()
|
-- > main :: IO ()
|
||||||
-- > main = defaultMain (fromArgs parseExtra) makeApplication
|
-- > main = defaultMain (fromArgs parseExtra) makeApplication
|
||||||
--
|
--
|
||||||
defaultMain :: (Show env, Read env)
|
defaultMain :: IO (AppConfig env extra)
|
||||||
=> IO (AppConfig env extra)
|
|
||||||
-> (AppConfig env extra -> IO Application)
|
-> (AppConfig env extra -> IO Application)
|
||||||
-> IO ()
|
-> IO ()
|
||||||
defaultMain load getApp = do
|
defaultMain load getApp = do
|
||||||
@ -60,8 +59,7 @@ type LogFunc = Loc -> LogSource -> LogLevel -> LogStr -> IO ()
|
|||||||
-- @Application@ to install Warp exception handlers.
|
-- @Application@ to install Warp exception handlers.
|
||||||
--
|
--
|
||||||
-- Since 1.2.5
|
-- Since 1.2.5
|
||||||
defaultMainLog :: (Show env, Read env)
|
defaultMainLog :: IO (AppConfig env extra)
|
||||||
=> IO (AppConfig env extra)
|
|
||||||
-> (AppConfig env extra -> IO (Application, LogFunc))
|
-> (AppConfig env extra -> IO (Application, LogFunc))
|
||||||
-> IO ()
|
-> IO ()
|
||||||
defaultMainLog load getApp = do
|
defaultMainLog load getApp = do
|
||||||
@ -113,8 +111,7 @@ defaultRunner f app = do
|
|||||||
-- | Run your development app using a custom environment type and loader
|
-- | Run your development app using a custom environment type and loader
|
||||||
-- function
|
-- function
|
||||||
defaultDevelApp
|
defaultDevelApp
|
||||||
:: (Show env, Read env)
|
:: IO (AppConfig env extra) -- ^ A means to load your development @'AppConfig'@
|
||||||
=> IO (AppConfig env extra) -- ^ A means to load your development @'AppConfig'@
|
|
||||||
-> (AppConfig env extra -> IO Application) -- ^ Get your @Application@
|
-> (AppConfig env extra -> IO Application) -- ^ Get your @Application@
|
||||||
-> IO (Int, Application)
|
-> IO (Int, Application)
|
||||||
defaultDevelApp load getApp = do
|
defaultDevelApp load getApp = do
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user