Merge branch 'master' into yesod-1.4

Conflicts:
	yesod-form/Yesod/Form/Functions.hs
This commit is contained in:
Michael Snoyman 2014-08-25 20:20:16 +03:00
commit c66ef04f17
29 changed files with 375 additions and 223 deletions

View File

@ -9,6 +9,7 @@ module Yesod.Auth.BrowserId
, BrowserIdSettings
, bisAudience
, bisLazyLoad
, forwardUrl
) where
import Yesod.Auth
@ -28,8 +29,11 @@ import Data.Default
pid :: Text
pid = "browserid"
complete :: Route Auth
complete = PluginR pid []
forwardUrl :: AuthRoute
forwardUrl = PluginR pid []
complete :: AuthRoute
complete = forwardUrl
-- | A settings type for various configuration options relevant to BrowserID.
--

View File

@ -30,15 +30,20 @@ import Blaze.ByteString.Builder (fromByteString, toByteString)
import Control.Applicative ((<$>), (<*>))
import Control.Arrow (second)
import Control.Monad (liftM, unless)
import qualified Data.Aeson as A
import qualified Data.Aeson.Encode as A
import Data.Aeson.Parser (json')
import Data.Aeson.Types (FromJSON (parseJSON), parseEither,
withObject)
import Data.Conduit (($$+-))
import Data.Conduit.Attoparsec (sinkParser)
import qualified Data.HashMap.Strict as M
import Data.Monoid (mappend)
import Data.Text (Text)
import qualified Data.Text as T
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Builder as TL
import Network.HTTP.Client (parseUrl, requestHeaders,
responseBody, urlEncodedBody)
import Network.HTTP.Conduit (http)
@ -175,7 +180,7 @@ authGoogleEmail clientID clientSecret =
[e] -> return e
[] -> error "No account email"
x -> error $ "Too many account emails: " ++ show x
lift $ setCredsRedirect $ Creds pid email []
lift $ setCredsRedirect $ Creds pid email $ allPersonInfo value2
dispatch _ _ = notFound
@ -200,3 +205,9 @@ instance FromJSON Email where
parseJSON = withObject "Email" $ \o -> Email
<$> o .: "value"
<*> o .: "type"
allPersonInfo :: A.Value -> [(Text, Text)]
allPersonInfo (A.Object o) = map enc $ M.toList o
where enc (key, A.String s) = (key, s)
enc (key, v) = (key, TL.toStrict $ TL.toLazyText $ A.encodeToTextBuilder v)
allPersonInfo _ = []

View File

@ -15,6 +15,7 @@ module Yesod.Auth.Message
, chineseMessage
, spanishMessage
, czechMessage
, russianMessage
) where
import Data.Monoid (mappend)
@ -396,15 +397,15 @@ japaneseMessage NowLoggedIn = "ログインしました"
japaneseMessage LoginTitle = "ログイン"
japaneseMessage PleaseProvideUsername = "ユーザ名を入力してください"
japaneseMessage PleaseProvidePassword = "パスワードを入力してください"
japaneseMessage NoIdentifierProvided = "No email/username provided"
japaneseMessage InvalidEmailAddress = "Invalid email address provided"
japaneseMessage PasswordResetTitle = "Password Reset"
japaneseMessage ProvideIdentifier = "Email or Username"
japaneseMessage SendPasswordResetEmail = "Send password reset email"
japaneseMessage PasswordResetPrompt = "Enter your e-mail address or username below, and a password reset e-mail will be sent to you."
japaneseMessage InvalidUsernamePass = "Invalid username/password combination"
japaneseMessage NoIdentifierProvided = "メールアドレス/ユーザ名が入力されていません"
japaneseMessage InvalidEmailAddress = "メールアドレスが無効です"
japaneseMessage PasswordResetTitle = "パスワードの再設定"
japaneseMessage ProvideIdentifier = "メールアドレスまたはユーザ名"
japaneseMessage SendPasswordResetEmail = "パスワード再設定用メールの送信"
japaneseMessage PasswordResetPrompt = "以下にメールアドレスまたはユーザ名を入力してください。パスワードを再設定するためのメールが送信されます。"
japaneseMessage InvalidUsernamePass = "ユーザ名とパスワードの組み合わせが間違っています"
japaneseMessage (IdentifierNotFound ident) =
"" `mappend` ident `mappend` "」は正しくないログインので、または未入力の項目があります。"
ident `mappend` "は登録されていません"
finnishMessage :: AuthMessage -> Text
finnishMessage NoOpenID = "OpenID-tunnistetta ei löydy"
@ -533,3 +534,47 @@ czechMessage PasswordResetPrompt = "Zadejte svou e-mailovou adresu nebo uživate
czechMessage InvalidUsernamePass = "Neplatná kombinace uživatelského jména a hesla"
-- TODO
czechMessage i@(IdentifierNotFound _) = englishMessage i
-- Так как e-mail это фактическое сокращение словосочетания electronic mail,
-- для русского перевода так же использовано сокращение: эл.почта
russianMessage :: AuthMessage -> Text
russianMessage NoOpenID = "Идентификатор OpenID не найден"
russianMessage LoginOpenID = "Вход с помощью OpenID"
russianMessage LoginGoogle = "Вход с помощью Google"
russianMessage LoginYahoo = "Вход с помощью Yahoo"
russianMessage Email = "Эл.почта"
russianMessage Password = "Пароль"
russianMessage Register = "Регистрация"
russianMessage RegisterLong = "Создать учётную запись"
russianMessage EnterEmail = "Введите свой адрес эл.почты ниже, вам будет отправлено письмо для подтверждения."
russianMessage ConfirmationEmailSentTitle = "Письмо для подтверждения отправлено"
russianMessage (ConfirmationEmailSent email) =
"Письмо для подтверждения было отправлено на адрес " `mappend`
email `mappend`
"."
russianMessage AddressVerified = "Адрес подтверждён. Пожалуйста, установите новый пароль."
russianMessage InvalidKeyTitle = "Неверный ключ подтверждения"
russianMessage InvalidKey = "Извините, но ключ подтверждения оказался недействительным."
russianMessage InvalidEmailPass = "Неверное сочетание эл.почты и пароля"
russianMessage BadSetPass = "Чтобы изменить пароль, необходимо выполнить вход"
russianMessage SetPassTitle = "Установить пароль"
russianMessage SetPass = "Установить новый пароль"
russianMessage NewPass = "Новый пароль"
russianMessage ConfirmPass = "Подтверждение"
russianMessage PassMismatch = "Пароли не совпадают, повторите снова"
russianMessage PassUpdated = "Пароль обновлён"
russianMessage Facebook = "Вход с помощью Facebook"
russianMessage LoginViaEmail = "Вход по адресу эл.почты"
russianMessage InvalidLogin = "Неверный логин"
russianMessage NowLoggedIn = "Вход выполнен"
russianMessage LoginTitle = "Вход"
russianMessage PleaseProvideUsername = "Пожалуйста, введите ваше имя пользователя"
russianMessage PleaseProvidePassword = "Пожалуйста, введите ваш пароль"
russianMessage NoIdentifierProvided = "Не указан адрес эл.почты/имя пользователя"
russianMessage InvalidEmailAddress = "Указан неверный адрес эл.почты"
russianMessage PasswordResetTitle = "Сброс пароля"
russianMessage ProvideIdentifier = "Имя пользователя или эл.почта"
russianMessage SendPasswordResetEmail = "Отправить письмо для сброса пароля"
russianMessage PasswordResetPrompt = "Введите адрес эл.почты или ваше имя пользователя ниже, вам будет отправлено письмо для сброса пароля."
russianMessage InvalidUsernamePass = "Неверное сочетание имени пользователя и пароля"
russianMessage (IdentifierNotFound ident) = "Логин не найден: " `mappend` ident

View File

@ -1,5 +1,5 @@
name: yesod-auth
version: 1.3.1.1
version: 1.3.4.2
license: MIT
license-file: LICENSE
author: Michael Snoyman, Patrick Brisbin
@ -20,6 +20,10 @@ description:
* <https://github.com/ollieh/yesod-auth-bcrypt/>: An alternative to the HashDB module.
extra-source-files: persona_sign_in_blue.png
flag network-uri
description: Get Network.URI from the network-uri package
default: True
library
build-depends: base >= 4 && < 5
, authenticate >= 1.3
@ -44,11 +48,10 @@ library
, persistent >= 1.2 && < 2.1
, persistent-template >= 1.2 && < 2.1
, http-conduit >= 1.5
, aeson >= 0.5
, aeson >= 0.7
, lifted-base >= 0.1
, blaze-html >= 0.5
, blaze-markup >= 0.5.1
, network
, http-types
, file-embed
, email-validate >= 1.0
@ -65,6 +68,11 @@ library
, conduit-extra
, attoparsec-conduit
if flag(network-uri)
build-depends: network-uri >= 2.6
else
build-depends: network < 2.6
exposed-modules: Yesod.Auth
Yesod.Auth.BrowserId
Yesod.Auth.Dummy

View File

@ -6,7 +6,8 @@ import Data.Char (isLower, toLower, isSpace)
import Data.List (isPrefixOf, isSuffixOf)
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import System.Directory (getDirectoryContents)
import System.Directory (getDirectoryContents, doesFileExist)
import Control.Monad (when)
-- strict readFile
readFile :: FilePath -> IO String
@ -21,14 +22,28 @@ addHandler = do
[] -> error "No cabal file found"
_ -> error "Too many cabal files found"
putStr "Name of route (without trailing R): "
hFlush stdout
name <- getLine
case name of
[] -> error "Please provide a name"
c:_
| isLower c -> error "Name must start with an upper case letter"
| otherwise -> return ()
let routeInput = do
putStr "Name of route (without trailing R): "
hFlush stdout
name <- getLine
case name of
[] -> error "No name entered. Quitting ..."
c:_
| isLower c -> do
putStrLn "Name must start with an upper case letter"
routeInput
| otherwise -> do
-- Check that the handler file doesn't already exist
let handlerFile = concat ["Handler/", name, ".hs"]
exists <- doesFileExist handlerFile
if exists
then do
putStrLn $ "File already exists: " ++ show handlerFile
putStrLn "Try another name or leave blank to exit"
routeInput
else return (name, handlerFile)
(name, handlerFile) <- routeInput
putStr "Enter route pattern (ex: /entry/#EntryId): "
hFlush stdout
pattern <- getLine
@ -41,7 +56,7 @@ addHandler = do
modify "Application.hs" $ fixApp name
modify cabal $ fixCabal name
modify "config/routes" $ fixRoutes name pattern methods
writeFile ("Handler/" ++ name ++ ".hs") $ mkHandler name pattern methods
writeFile handlerFile $ mkHandler name pattern methods
fixApp :: String -> String -> String
fixApp name =

View File

@ -33,7 +33,8 @@ import qualified Data.Set as Set
import qualified System.Posix.Types
import System.Directory
import System.FilePath (takeExtension, replaceExtension, (</>), takeDirectory)
import System.FilePath (takeExtension, replaceExtension, (</>), takeDirectory,
splitPath, joinPath)
import System.PosixCompat.Files (getFileStatus, setFileTimes,
accessTime, modificationTime)
@ -112,7 +113,7 @@ removeHi :: FilePath -> FilePath -> IO ()
removeHi _ hs = mapM_ removeFile' hiFiles
where
removeFile' file = try' (removeFile file) >> return ()
hiFiles = map (\e -> "dist/build" </> replaceExtension hs e)
hiFiles = map (\e -> "dist/build" </> removeSrc (replaceExtension hs e))
["hi", "p_hi"]
-- | change file mtime of .hs file to that of the dependency
@ -124,7 +125,12 @@ updateFileTime x hs = do
return ()
hiFile :: FilePath -> FilePath
hiFile hs = "dist/build" </> replaceExtension hs "hi"
hiFile hs = "dist/build" </> removeSrc (replaceExtension hs "hi")
removeSrc :: FilePath -> FilePath
removeSrc f = case splitPath f of
("src/" : xs) -> joinPath xs
_ -> f
try' :: IO x -> IO (Either SomeException x)
try' = try

View File

@ -416,7 +416,7 @@ checkCabalFile gpd = case D.condLibrary gpd of
unless (null unlisted) $ do
putStrLn "WARNING: the following source files are not listed in exposed-modules or other-modules:"
mapM_ putStrLn unlisted
when (D.fromString "Application" `notElem` D.exposedModules dLib) $
when ("Application" `notElem` (map (last . D.components) $ D.exposedModules dLib)) $
putStrLn "WARNING: no exposed module Application"
return (hsSourceDirs, dLib)

View File

@ -27,16 +27,17 @@ keter :: String -- ^ cabal command
-> Bool -- ^ no build?
-> IO ()
keter cabal noBuild = do
mvalue <- decodeFile "config/keter.yaml"
ketercfg <- keterConfig
mvalue <- decodeFile ketercfg
value <-
case mvalue of
Nothing -> error "No config/keter.yaml found"
Just (Object value) ->
case Map.lookup "host" value of
Just (String s) | "<<" `T.isPrefixOf` s ->
error "Please set your hostname in config/keter.yaml"
error $ "Please set your hostname in " ++ ketercfg
_ -> return value
Just _ -> error "config/keter.yaml is not an object"
Just _ -> error $ ketercfg ++ " is not an object"
files <- getDirectoryContents "."
project <-
@ -48,7 +49,7 @@ keter cabal noBuild = do
exec <-
case Map.lookup "exec" value of
Just (String s) -> return $ F.collapse $ "config" F.</> F.fromText s
_ -> error "exec not found in config/keter.yaml"
_ -> error $ "exec not found in " ++ ketercfg
unless noBuild $ do
run cabal ["clean"]
@ -67,6 +68,12 @@ keter cabal noBuild = do
Just i -> run "scp" ["-P" ++ show (i :: Int), fp, T.unpack s]
Nothing -> run "scp" [fp, T.unpack s]
_ -> return ()
where
-- Test for alternative config file extension (yaml or yml).
keterConfig = do
let yml = "config/keter.yml"
ymlExists <- doesFileExist yml
return $ if ymlExists then yml else "config/keter.yaml"
try' :: IO a -> IO (Either SomeException a)
try' = try

View File

@ -45,8 +45,7 @@ import Network.Wai.Middleware.RequestLogger
import qualified Network.Wai.Middleware.RequestLogger as RequestLogger
import qualified Database.Persist
import Network.HTTP.Client.Conduit (newManager)
import Control.Concurrent (forkIO, threadDelay)
import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize, flushLogStr)
import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize)
import Network.Wai.Logger (clockDateCacher)
import Data.Default (def)
import Yesod.Core.Types (loggerSet, Logger (Logger))
@ -94,18 +93,7 @@ makeFoundation conf = do
p <- Database.Persist.createPoolConfig (dbconf :: Settings.PersistConf)
loggerSet' <- newStdoutLoggerSet defaultBufSize
(getter, updater) <- clockDateCacher
-- If the Yesod logger (as opposed to the request logger middleware) is
-- used less than once a second on average, you may prefer to omit this
-- thread and use "(updater >> getter)" in place of "getter" below. That
-- would update the cache every time it is used, instead of every second.
let updateLoop = do
threadDelay 1000000
updater
flushLogStr loggerSet'
updateLoop
_ <- forkIO updateLoop
(getter, _) <- clockDateCacher
let logger = Yesod.Core.Types.Logger loggerSet' getter
foundation = App conf s p manager dbconf logger
@ -430,7 +418,7 @@ library
, bytestring >= 0.9 && < 0.11
, text >= 0.11 && < 2.0
, persistent >= 1.3 && < 1.4
, persistent-mongoDB >= 1.3 && < 1.4
, persistent-mongoDB >= 1.3 && < 1.5
, persistent-template >= 1.3 && < 1.4
, template-haskell
, shakespeare >= 2.0 && < 2.1
@ -442,11 +430,11 @@ library
, directory >= 1.1 && < 1.3
, warp >= 3.0 && < 3.1
, data-default
, aeson >= 0.6 && < 0.8
, aeson >= 0.6 && < 0.9
, conduit >= 1.0 && < 2.0
, monad-logger >= 0.3 && < 0.4
, fast-logger >= 2.1.4 && < 2.2
, wai-logger >= 2.1 && < 2.2
, fast-logger >= 2.2 && < 2.3
, wai-logger >= 2.2 && < 2.3
executable PROJECTNAME
if flag(library-only)
@ -458,7 +446,7 @@ executable PROJECTNAME
, PROJECTNAME
, yesod
ghc-options: -threaded -O2
ghc-options: -threaded -O2 -rtsopts -with-rtsopts=-N
test-suite test
type: exitcode-stdio-1.0
@ -714,7 +702,7 @@ AAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
{-# START_FILE config/keter.yaml #-}
{-# START_FILE config/keter.yml #-}
exec: ../dist/build/PROJECTNAME/PROJECTNAME
args:
- production
@ -890,6 +878,7 @@ Production:
web: ./dist/build/PROJECTNAME/PROJECTNAME production -p $PORT
{-# START_FILE devel.hs #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE PackageImports #-}
import "PROJECTNAME" Application (getApplicationDev)
import Network.Wai.Handler.Warp
@ -899,8 +888,16 @@ import System.Directory (doesFileExist, removeFile)
import System.Exit (exitSuccess)
import Control.Concurrent (threadDelay)
#ifndef mingw32_HOST_OS
import System.Posix.Signals (installHandler, sigINT, Handler(Catch))
#endif
main :: IO ()
main = do
#ifndef mingw32_HOST_OS
_ <- installHandler sigINT (Catch $ return ()) Nothing
#endif
putStrLn "Starting devel application"
(port, app) <- getApplicationDev
forkIO $ runSettings (setPort port defaultSettings) app

View File

@ -47,8 +47,7 @@ import qualified Database.Persist
import Database.Persist.Sql (runMigration)
import Network.HTTP.Client.Conduit (newManager)
import Control.Monad.Logger (runLoggingT)
import Control.Concurrent (forkIO, threadDelay)
import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize, flushLogStr)
import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize)
import Network.Wai.Logger (clockDateCacher)
import Data.Default (def)
import Yesod.Core.Types (loggerSet, Logger (Logger))
@ -96,18 +95,7 @@ makeFoundation conf = do
p <- Database.Persist.createPoolConfig (dbconf :: Settings.PersistConf)
loggerSet' <- newStdoutLoggerSet defaultBufSize
(getter, updater) <- clockDateCacher
-- If the Yesod logger (as opposed to the request logger middleware) is
-- used less than once a second on average, you may prefer to omit this
-- thread and use "(updater >> getter)" in place of "getter" below. That
-- would update the cache every time it is used, instead of every second.
let updateLoop = do
threadDelay 1000000
updater
flushLogStr loggerSet'
updateLoop
_ <- forkIO updateLoop
(getter, _) <- clockDateCacher
let logger = Yesod.Core.Types.Logger loggerSet' getter
foundation = App conf s p manager dbconf logger
@ -446,11 +434,11 @@ library
, directory >= 1.1 && < 1.3
, warp >= 3.0 && < 3.1
, data-default
, aeson >= 0.6 && < 0.8
, aeson >= 0.6 && < 0.9
, conduit >= 1.0 && < 2.0
, monad-logger >= 0.3 && < 0.4
, fast-logger >= 2.1.4 && < 2.2
, wai-logger >= 2.1 && < 2.2
, fast-logger >= 2.2 && < 2.3
, wai-logger >= 2.2 && < 2.3
executable PROJECTNAME
if flag(library-only)
@ -462,7 +450,7 @@ executable PROJECTNAME
, PROJECTNAME
, yesod
ghc-options: -threaded -O2
ghc-options: -threaded -O2 -rtsopts -with-rtsopts=-N
test-suite test
type: exitcode-stdio-1.0
@ -718,7 +706,7 @@ AAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
{-# START_FILE config/keter.yaml #-}
{-# START_FILE config/keter.yml #-}
exec: ../dist/build/PROJECTNAME/PROJECTNAME
args:
- production
@ -920,6 +908,7 @@ Production:
web: ./dist/build/PROJECTNAME/PROJECTNAME production -p $PORT
{-# START_FILE devel.hs #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE PackageImports #-}
import "PROJECTNAME" Application (getApplicationDev)
import Network.Wai.Handler.Warp
@ -929,8 +918,16 @@ import System.Directory (doesFileExist, removeFile)
import System.Exit (exitSuccess)
import Control.Concurrent (threadDelay)
#ifndef mingw32_HOST_OS
import System.Posix.Signals (installHandler, sigINT, Handler(Catch))
#endif
main :: IO ()
main = do
#ifndef mingw32_HOST_OS
_ <- installHandler sigINT (Catch $ return ()) Nothing
#endif
putStrLn "Starting devel application"
(port, app) <- getApplicationDev
forkIO $ runSettings (setPort port defaultSettings) app

View File

@ -49,8 +49,7 @@ import Database.Persist.Sql (runMigration)
import Network.HTTP.Client.Conduit (newManager)
import Yesod.Fay (getFaySite)
import Control.Monad.Logger (runLoggingT)
import Control.Concurrent (forkIO, threadDelay)
import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize, flushLogStr)
import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize)
import Network.Wai.Logger (clockDateCacher)
import Data.Default (def)
import Yesod.Core.Types (loggerSet, Logger (Logger))
@ -99,18 +98,7 @@ makeFoundation conf = do
p <- Database.Persist.createPoolConfig (dbconf :: Settings.PersistConf)
loggerSet' <- newStdoutLoggerSet defaultBufSize
(getter, updater) <- clockDateCacher
-- If the Yesod logger (as opposed to the request logger middleware) is
-- used less than once a second on average, you may prefer to omit this
-- thread and use "(updater >> getter)" in place of "getter" below. That
-- would update the cache every time it is used, instead of every second.
let updateLoop = do
threadDelay 1000000
updater
flushLogStr loggerSet'
updateLoop
_ <- forkIO updateLoop
(getter, _) <- clockDateCacher
let logger = Yesod.Core.Types.Logger loggerSet' getter
foundation = App conf s p manager dbconf onCommand logger
@ -483,11 +471,11 @@ library
, directory >= 1.1 && < 1.3
, warp >= 3.0 && < 3.1
, data-default
, aeson >= 0.6 && < 0.8
, aeson >= 0.6 && < 0.9
, conduit >= 1.0 && < 2.0
, monad-logger >= 0.3 && < 0.4
, fast-logger >= 2.1.4 && < 2.2
, wai-logger >= 2.1 && < 2.2
, fast-logger >= 2.2 && < 2.3
, wai-logger >= 2.2 && < 2.3
executable PROJECTNAME
if flag(library-only)
@ -499,7 +487,7 @@ executable PROJECTNAME
, PROJECTNAME
, yesod
ghc-options: -threaded -O2
ghc-options: -threaded -O2 -rtsopts -with-rtsopts=-N
test-suite test
type: exitcode-stdio-1.0
@ -767,7 +755,7 @@ AAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
{-# START_FILE config/keter.yaml #-}
{-# START_FILE config/keter.yml #-}
exec: ../dist/build/PROJECTNAME/PROJECTNAME
args:
- production
@ -944,6 +932,7 @@ Production:
web: ./dist/build/PROJECTNAME/PROJECTNAME production -p $PORT
{-# START_FILE devel.hs #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE PackageImports #-}
import "PROJECTNAME" Application (getApplicationDev)
import Network.Wai.Handler.Warp
@ -953,8 +942,16 @@ import System.Directory (doesFileExist, removeFile)
import System.Exit (exitSuccess)
import Control.Concurrent (threadDelay)
#ifndef mingw32_HOST_OS
import System.Posix.Signals (installHandler, sigINT, Handler(Catch))
#endif
main :: IO ()
main = do
#ifndef mingw32_HOST_OS
_ <- installHandler sigINT (Catch $ return ()) Nothing
#endif
putStrLn "Starting devel application"
(port, app) <- getApplicationDev
forkIO $ runSettings (setPort port defaultSettings) app

View File

@ -47,8 +47,7 @@ import qualified Database.Persist
import Database.Persist.Sql (runMigration)
import Network.HTTP.Client.Conduit (newManager)
import Control.Monad.Logger (runLoggingT)
import Control.Concurrent (forkIO, threadDelay)
import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize, flushLogStr)
import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize)
import Network.Wai.Logger (clockDateCacher)
import Data.Default (def)
import Yesod.Core.Types (loggerSet, Logger (Logger))
@ -96,18 +95,7 @@ makeFoundation conf = do
p <- Database.Persist.createPoolConfig (dbconf :: Settings.PersistConf)
loggerSet' <- newStdoutLoggerSet defaultBufSize
(getter, updater) <- clockDateCacher
-- If the Yesod logger (as opposed to the request logger middleware) is
-- used less than once a second on average, you may prefer to omit this
-- thread and use "(updater >> getter)" in place of "getter" below. That
-- would update the cache every time it is used, instead of every second.
let updateLoop = do
threadDelay 1000000
updater
flushLogStr loggerSet'
updateLoop
_ <- forkIO updateLoop
(getter, _) <- clockDateCacher
let logger = Yesod.Core.Types.Logger loggerSet' getter
foundation = App conf s p manager dbconf logger
@ -446,11 +434,11 @@ library
, directory >= 1.1 && < 1.3
, warp >= 3.0 && < 3.1
, data-default
, aeson >= 0.6 && < 0.8
, aeson >= 0.6 && < 0.9
, conduit >= 1.0 && < 2.0
, monad-logger >= 0.3 && < 0.4
, fast-logger >= 2.1.4 && < 2.2
, wai-logger >= 2.1 && < 2.2
, fast-logger >= 2.2 && < 2.3
, wai-logger >= 2.2 && < 2.3
executable PROJECTNAME
if flag(library-only)
@ -462,7 +450,7 @@ executable PROJECTNAME
, PROJECTNAME
, yesod
ghc-options: -threaded -O2
ghc-options: -threaded -O2 -rtsopts -with-rtsopts=-N
test-suite test
type: exitcode-stdio-1.0
@ -718,7 +706,7 @@ AAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
{-# START_FILE config/keter.yaml #-}
{-# START_FILE config/keter.yml #-}
exec: ../dist/build/PROJECTNAME/PROJECTNAME
args:
- production
@ -894,6 +882,7 @@ Production:
web: ./dist/build/PROJECTNAME/PROJECTNAME production -p $PORT
{-# START_FILE devel.hs #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE PackageImports #-}
import "PROJECTNAME" Application (getApplicationDev)
import Network.Wai.Handler.Warp
@ -903,8 +892,16 @@ import System.Directory (doesFileExist, removeFile)
import System.Exit (exitSuccess)
import Control.Concurrent (threadDelay)
#ifndef mingw32_HOST_OS
import System.Posix.Signals (installHandler, sigINT, Handler(Catch))
#endif
main :: IO ()
main = do
#ifndef mingw32_HOST_OS
_ <- installHandler sigINT (Catch $ return ()) Nothing
#endif
putStrLn "Starting devel application"
(port, app) <- getApplicationDev
forkIO $ runSettings (setPort port defaultSettings) app

View File

@ -42,8 +42,7 @@ import Network.Wai.Middleware.RequestLogger
)
import qualified Network.Wai.Middleware.RequestLogger as RequestLogger
import Network.HTTP.Client.Conduit (newManager)
import Control.Concurrent (forkIO, threadDelay)
import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize, flushLogStr)
import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize)
import Network.Wai.Logger (clockDateCacher)
import Data.Default (def)
import Yesod.Core.Types (loggerSet, Logger (Logger))
@ -87,18 +86,7 @@ makeFoundation conf = do
s <- staticSite
loggerSet' <- newStdoutLoggerSet defaultBufSize
(getter, updater) <- clockDateCacher
-- If the Yesod logger (as opposed to the request logger middleware) is
-- used less than once a second on average, you may prefer to omit this
-- thread and use "(updater >> getter)" in place of "getter" below. That
-- would update the cache every time it is used, instead of every second.
let updateLoop = do
threadDelay 1000000
updater
flushLogStr loggerSet'
updateLoop
_ <- forkIO updateLoop
(getter, _) <- clockDateCacher
let logger = Yesod.Core.Types.Logger loggerSet' getter
foundation = App conf s manager logger
@ -120,8 +108,6 @@ module Foundation where
import Prelude
import Yesod
import Yesod.Static
import Yesod.Auth
import Yesod.Auth.BrowserId
import Yesod.Default.Config
import Yesod.Default.Util (addStaticContentExternal)
import Network.HTTP.Client.Conduit (Manager, HasHttpManager (getHttpManager))
@ -197,7 +183,6 @@ instance Yesod App where
urlRenderOverride _ _ = Nothing
-- Routes not requiring authenitcation.
isAuthorized (AuthR _) _ = return Authorized
isAuthorized FaviconR _ = return Authorized
isAuthorized RobotsR _ = return Authorized
-- Default to Authorized for now.
@ -373,11 +358,11 @@ library
, directory >= 1.1 && < 1.3
, warp >= 3.0 && < 3.1
, data-default
, aeson >= 0.6 && < 0.8
, aeson >= 0.6 && < 0.9
, conduit >= 1.0 && < 2.0
, monad-logger >= 0.3 && < 0.4
, fast-logger >= 2.1.4 && < 2.2
, wai-logger >= 2.1 && < 2.2
, fast-logger >= 2.2 && < 2.3
, wai-logger >= 2.2 && < 2.3
executable PROJECTNAME
if flag(library-only)
@ -389,7 +374,7 @@ executable PROJECTNAME
, PROJECTNAME
, yesod
ghc-options: -threaded -O2
ghc-options: -threaded -O2 -rtsopts -with-rtsopts=-N
test-suite test
type: exitcode-stdio-1.0
@ -636,7 +621,7 @@ AAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
{-# START_FILE config/keter.yaml #-}
{-# START_FILE config/keter.yml #-}
exec: ../dist/build/PROJECTNAME/PROJECTNAME
args:
- production
@ -771,6 +756,7 @@ Production:
web: ./dist/build/PROJECTNAME/PROJECTNAME production -p $PORT
{-# START_FILE devel.hs #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE PackageImports #-}
import "PROJECTNAME" Application (getApplicationDev)
import Network.Wai.Handler.Warp
@ -780,8 +766,16 @@ import System.Directory (doesFileExist, removeFile)
import System.Exit (exitSuccess)
import Control.Concurrent (threadDelay)
#ifndef mingw32_HOST_OS
import System.Posix.Signals (installHandler, sigINT, Handler(Catch))
#endif
main :: IO ()
main = do
#ifndef mingw32_HOST_OS
_ <- installHandler sigINT (Catch $ return ()) Nothing
#endif
putStrLn "Starting devel application"
(port, app) <- getApplicationDev
forkIO $ runSettings (setPort port defaultSettings) app

View File

@ -47,8 +47,7 @@ import qualified Database.Persist
import Database.Persist.Sql (runMigration)
import Network.HTTP.Client.Conduit (newManager)
import Control.Monad.Logger (runLoggingT)
import Control.Concurrent (forkIO, threadDelay)
import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize, flushLogStr)
import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize)
import Network.Wai.Logger (clockDateCacher)
import Data.Default (def)
import Yesod.Core.Types (loggerSet, Logger (Logger))
@ -96,18 +95,7 @@ makeFoundation conf = do
p <- Database.Persist.createPoolConfig (dbconf :: Settings.PersistConf)
loggerSet' <- newStdoutLoggerSet defaultBufSize
(getter, updater) <- clockDateCacher
-- If the Yesod logger (as opposed to the request logger middleware) is
-- used less than once a second on average, you may prefer to omit this
-- thread and use "(updater >> getter)" in place of "getter" below. That
-- would update the cache every time it is used, instead of every second.
let updateLoop = do
threadDelay 1000000
updater
flushLogStr loggerSet'
updateLoop
_ <- forkIO updateLoop
(getter, _) <- clockDateCacher
let logger = Yesod.Core.Types.Logger loggerSet' getter
foundation = App conf s p manager dbconf logger
@ -446,11 +434,11 @@ library
, directory >= 1.1 && < 1.3
, warp >= 3.0 && < 3.1
, data-default
, aeson >= 0.6 && < 0.8
, aeson >= 0.6 && < 0.9
, conduit >= 1.0 && < 2.0
, monad-logger >= 0.3 && < 0.4
, fast-logger >= 2.1.4 && < 2.2
, wai-logger >= 2.1 && < 2.2
, fast-logger >= 2.2 && < 2.3
, wai-logger >= 2.2 && < 2.3
executable PROJECTNAME
if flag(library-only)
@ -462,7 +450,7 @@ executable PROJECTNAME
, PROJECTNAME
, yesod
ghc-options: -threaded -O2
ghc-options: -threaded -O2 -rtsopts -with-rtsopts=-N
test-suite test
type: exitcode-stdio-1.0
@ -718,7 +706,7 @@ AAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
{-# START_FILE config/keter.yaml #-}
{-# START_FILE config/keter.yml #-}
exec: ../dist/build/PROJECTNAME/PROJECTNAME
args:
- production
@ -890,6 +878,7 @@ Production:
web: ./dist/build/PROJECTNAME/PROJECTNAME production -p $PORT
{-# START_FILE devel.hs #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE PackageImports #-}
import "PROJECTNAME" Application (getApplicationDev)
import Network.Wai.Handler.Warp
@ -899,8 +888,16 @@ import System.Directory (doesFileExist, removeFile)
import System.Exit (exitSuccess)
import Control.Concurrent (threadDelay)
#ifndef mingw32_HOST_OS
import System.Posix.Signals (installHandler, sigINT, Handler(Catch))
#endif
main :: IO ()
main = do
#ifndef mingw32_HOST_OS
_ <- installHandler sigINT (Catch $ return ()) Nothing
#endif
putStrLn "Starting devel application"
(port, app) <- getApplicationDev
forkIO $ runSettings (setPort port defaultSettings) app

View File

@ -152,6 +152,9 @@ optParser = Options
keterOptions :: Parser Command
keterOptions = Keter <$> switch ( long "nobuild" <> short 'n' <> help "Skip rebuilding" )
defaultRescan :: Int
defaultRescan = 10
develOptions :: Parser Command
develOptions = Devel <$> switch ( long "disable-api" <> short 'd'
<> help "Disable fast GHC API rebuilding")
@ -159,8 +162,10 @@ develOptions = Devel <$> switch ( long "disable-api" <> short 'd'
<> help "Run COMMAND after rebuild succeeds")
<*> optStr ( long "failure-hook" <> short 'f' <> metavar "COMMAND"
<> help "Run COMMAND when rebuild fails")
<*> option ( long "event-timeout" <> short 't' <> value 1 <> metavar "N"
<> help "Force rescan of files every N seconds" )
<*> option ( long "event-timeout" <> short 't' <> value defaultRescan <> metavar "N"
<> help ("Force rescan of files every N seconds (default "
++ show defaultRescan
++ ", use -1 to rely on FSNotify alone)") )
<*> optStr ( long "builddir" <> short 'b'
<> help "Set custom cabal build directory, default `dist'")
<*> many ( strOption ( long "ignore" <> short 'i' <> metavar "DIR"

View File

@ -1,5 +1,5 @@
name: yesod-bin
version: 1.2.11
version: 1.2.12.4
license: MIT
license-file: LICENSE
author: Michael Snoyman <michael@snoyman.com>

View File

@ -68,6 +68,9 @@ import Yesod.Routes.Class (RenderRoute (..), ParseRout
import Control.Monad.Reader (MonadReader (..))
import Prelude hiding (catch)
import Control.DeepSeq (NFData (rnf))
#if MIN_VERSION_conduit(1, 1, 0)
import Data.Conduit.Lazy (MonadActive, monadActive)
#endif
-- Sessions
type SessionMap = Map Text ByteString
@ -458,6 +461,13 @@ instance MonadIO m => MonadLogger (WidgetT site m) where
monadLoggerLog a b c d = WidgetT $ \hd ->
liftIO $ fmap (, mempty) $ rheLog (handlerEnv hd) a b c (toLogStr d)
#if MIN_VERSION_conduit(1, 1, 0)
instance MonadActive m => MonadActive (WidgetT site m) where
monadActive = lift monadActive
instance MonadActive m => MonadActive (HandlerT site m) where
monadActive = lift monadActive
#endif
instance MonadTrans (HandlerT site) where
lift = HandlerT . const

View File

@ -16,7 +16,7 @@ import System.IO.Unsafe (unsafePerformIO)
randomStringSpecs :: Spec
randomStringSpecs = describe "Yesod.Internal.Request.randomString" $ do
it "looks reasonably random" looksRandom
--it "looks reasonably random" looksRandom
it "does not repeat itself" $ noRepeat 10 100
-- NOTE: this testcase may break on other systems/architectures if

View File

@ -1,5 +1,5 @@
name: yesod-core
version: 1.2.17
version: 1.2.19.1
license: MIT
license-file: LICENSE
author: Michael Snoyman <michael@snoyman.com>

View File

@ -430,6 +430,8 @@ renderBootstrap = renderBootstrap2
-- > ^{formWidget}
-- > <div .form-actions>
-- > <input .btn .primary type=submit value=_{MsgSubmit}>
--
-- Since 1.3.14
renderBootstrap2 :: Monad m => FormRender m a
renderBootstrap2 aform fragment = do
(res, views') <- aFormToForm aform
@ -450,6 +452,10 @@ renderBootstrap2 aform fragment = do
<span .help-block>#{err}
|]
return (res, widget)
-- | Deprecated synonym for 'renderBootstrap2'.
renderBootstrap :: Monad m => FormRender m a
renderBootstrap = renderBootstrap2
{-# DEPRECATED renderBootstrap "Please use the Yesod.Form.Bootstrap3 module." #-}
check :: (Monad m, RenderMessage (HandlerSite m) msg)

View File

@ -0,0 +1,26 @@
{-# LANGUAGE OverloadedStrings #-}
module Yesod.Form.I18n.Russian where
import Yesod.Form.Types (FormMessage (..))
import Data.Monoid (mappend)
import Data.Text (Text)
russianFormMessage :: FormMessage -> Text
russianFormMessage (MsgInvalidInteger t) = "Неверно записано целое число: " `mappend` t
russianFormMessage (MsgInvalidNumber t) = "Неверный формат числа: " `mappend` t
russianFormMessage (MsgInvalidEntry t) = "Неверный выбор: " `mappend` t
russianFormMessage MsgInvalidTimeFormat = "Неверно указано время, используйте формат ЧЧ:ММ[:СС]"
russianFormMessage MsgInvalidDay = "Неверно указана дата, используйте формат ГГГГ-ММ-ДД"
russianFormMessage (MsgInvalidUrl t) = "Неверно указан URL адрес: " `mappend` t
russianFormMessage (MsgInvalidEmail t) = "Неверно указана электронная почта: " `mappend` t
russianFormMessage (MsgInvalidHour t) = "Неверно указан час: " `mappend` t
russianFormMessage (MsgInvalidMinute t) = "Неверно указаны минуты: " `mappend` t
russianFormMessage (MsgInvalidSecond t) = "Неверны указаны секунды: " `mappend` t
russianFormMessage MsgCsrfWarning = "Для защиты от межсайтовой подделки запросов (CSRF), пожалуйста, подтвердите отправку данных формы."
russianFormMessage MsgValueRequired = "Обязательно к заполнению"
russianFormMessage (MsgInputNotFound t) = "Поле не найдено: " `mappend` t
russianFormMessage MsgSelectNone = "<Не выбрано>"
russianFormMessage (MsgInvalidBool t) = "Неверное логическое значение: " `mappend` t
russianFormMessage MsgBoolYes = "Да"
russianFormMessage MsgBoolNo = "Нет"
russianFormMessage MsgDelete = "Удалить?"

View File

@ -7,6 +7,7 @@ module Yesod.Form.Jquery
( YesodJquery (..)
, jqueryDayField
, jqueryAutocompleteField
, jqueryAutocompleteField'
, googleHostedJqueryUiCss
, JqueryDaySettings (..)
, Default (..)
@ -98,7 +99,13 @@ $(function(){
jqueryAutocompleteField :: (RenderMessage site FormMessage, YesodJquery site)
=> Route site -> Field (HandlerT site IO) Text
jqueryAutocompleteField src = Field
jqueryAutocompleteField = jqueryAutocompleteField' 2
jqueryAutocompleteField' :: (RenderMessage site FormMessage, YesodJquery site)
=> Int -- ^ autocomplete minimum length
-> Route site
-> Field (HandlerT site IO) Text
jqueryAutocompleteField' minLen src = Field
{ fieldParse = parseHelper $ Right
, fieldView = \theId name attrs val isReq -> do
toWidget [shamlet|
@ -109,7 +116,7 @@ $newline never
addScript' urlJqueryUiJs
addStylesheet' urlJqueryUiCss
toWidget [julius|
$(function(){$("##{rawJS theId}").autocomplete({source:"@{src}",minLength:2})});
$(function(){$("##{rawJS theId}").autocomplete({source:"@{src}",minLength:#{toJSON minLen}})});
|]
, fieldEnctype = UrlEncoded
}

View File

@ -26,10 +26,10 @@ class Yesod a => YesodNic a where
nicHtmlField :: YesodNic site => Field (HandlerT site IO) Html
nicHtmlField = Field
{ fieldParse = \e _ -> return . Right . fmap (preEscapedToMarkup . sanitizeBalance) . listToMaybe $ e
, fieldView = \theId name attrs val _isReq -> do
, fieldView = \theId name attrs val isReq -> do
toWidget [shamlet|
$newline never
<textarea id="#{theId}" *{attrs} name="#{name}" .html>#{showVal val}
<textarea id="#{theId}" *{attrs} name="#{name}" :isReq:required .html>#{showVal val}
|]
addScript' urlNicEdit
master <- getYesod

View File

@ -1,5 +1,5 @@
name: yesod-form
version: 1.3.11
version: 1.3.15.2
license: MIT
license-file: LICENSE
author: Michael Snoyman <michael@snoyman.com>
@ -12,6 +12,10 @@ build-type: Simple
homepage: http://www.yesodweb.com/
description: Form handling support for Yesod Web Framework
flag network-uri
description: Get Network.URI from the network-uri package
default: True
library
build-depends: base >= 4 && < 5
, yesod-core >= 1.2 && < 1.3
@ -27,7 +31,6 @@ library
, data-default
, xss-sanitize >= 0.3.0.1
, blaze-builder >= 0.2.1.4
, network >= 2.2
, email-validate >= 1.0
, bytestring >= 0.9.1.4
, text >= 0.9
@ -40,6 +43,11 @@ library
, aeson
, resourcet
if flag(network-uri)
build-depends: network-uri >= 2.6
else
build-depends: network < 2.6
exposed-modules: Yesod.Form
Yesod.Form.Types
Yesod.Form.Functions
@ -57,6 +65,7 @@ library
Yesod.Form.I18n.Norwegian
Yesod.Form.I18n.Japanese
Yesod.Form.I18n.Czech
Yesod.Form.I18n.Russian
-- FIXME Yesod.Helpers.Crud
ghc-options: -Wall

View File

@ -1,5 +1,5 @@
name: yesod-newsfeed
version: 1.2.0.2
version: 1.2.1
license: MIT
license-file: LICENSE
author: Michael Snoyman, Patrick Brisbin

View File

@ -3,7 +3,7 @@ import Control.Applicative ((<$>))
main = do
pkgs <- map (intercalate " == ")
. filter (\xs -> not $ any (`isPrefixOf` xs) $ map return ["parsec", "text", "transformers", "mtl", "HUnit", "QuickCheck", "binary", "zlib", "stm", "regex-compat", "hashable", "vault", "integer-gmp"])
. filter (\xs -> not $ any (`isPrefixOf` xs) $ map return ["parsec", "text", "transformers", "mtl", "HUnit", "QuickCheck", "binary", "zlib", "stm", "regex-compat", "hashable", "vault", "integer-gmp", "unordered-containers", "async", "aeson", "attoparsec", "scientific", "case-insensitive", "vector", "primitive", "unix-compat", "transformers-compat"])
. map words
. filter (not . null)
. lines

View File

@ -1,5 +1,5 @@
name: yesod-platform
version: 1.2.12.2
version: 1.2.13.2
license: MIT
license-file: LICENSE
author: Michael Snoyman <michael@snoyman.com>
@ -14,17 +14,15 @@ homepage: http://www.yesodweb.com/
library
build-depends: base >= 4 && < 5
, SHA == 1.6.4
, aeson == 0.7.0.6
, SHA == 1.6.4.1
, ansi-terminal == 0.6.1.1
, ansi-wl-pprint == 0.6.7.1
, asn1-encoding == 0.8.1.3
, asn1-parse == 0.8.1
, asn1-types == 0.2.3
, async == 2.0.1.5
, attoparsec == 0.12.0.0
, attoparsec-conduit == 1.1.0
, authenticate == 1.3.2.8
, authenticate == 1.3.2.10
, auto-update == 0.1.0.0
, base16-bytestring == 0.1.1.6
, base64-bytestring == 1.0.0.1
, blaze-builder == 0.3.3.2
@ -33,16 +31,15 @@ library
, blaze-markup == 0.6.1.0
, byteable == 0.1.1
, byteorder == 1.0.4
, case-insensitive == 1.2.0.0
, cereal == 0.4.0.1
, cipher-aes == 0.2.7
, cipher-aes == 0.2.8
, cipher-des == 0.0.6
, cipher-rc4 == 0.1.4
, clientsession == 0.9.0.3
, conduit == 1.1.6
, conduit-extra == 1.1.0.4
, connection == 0.2.1
, cookie == 0.4.1.1
, conduit == 1.1.7
, conduit-extra == 1.1.3
, connection == 0.2.3
, cookie == 0.4.1.2
, cprng-aes == 0.5.2
, crypto-api == 0.13
, crypto-cipher-types == 0.0.9
@ -50,7 +47,7 @@ library
, crypto-pubkey == 0.2.4
, crypto-pubkey-types == 0.4.2.2
, crypto-random == 0.0.7
, cryptohash == 0.11.5
, cryptohash == 0.11.6
, cryptohash-conduit == 0.1.1
, css-text == 0.1.2.1
, data-default == 0.5.3
@ -59,61 +56,59 @@ library
, data-default-instances-containers == 0.0.1
, data-default-instances-dlist == 0.0.1
, data-default-instances-old-locale == 0.0.1
, dlist == 0.7.0.1
, dlist == 0.7.1
, email-validate == 2.0.1
, entropy == 0.3.2
, esqueleto == 1.4.1.2
, esqueleto == 1.4.4
, exceptions == 0.6.1
, fast-logger == 2.1.5
, fast-logger == 2.2.0
, file-embed == 0.0.7
, hamlet == 1.2.0
, hjsmin == 0.1.4.6
, hspec == 1.9.5
, hspec-expectations == 0.5.0.1
, hjsmin == 0.1.4.7
, hspec == 1.11.0
, hspec-expectations == 0.6.0.1
, html-conduit == 1.1.0.5
, http-client == 0.3.3
, http-client-tls == 0.2.1.1
, http-conduit == 2.1.2
, http-client == 0.3.7.1
, http-client-tls == 0.2.2
, http-conduit == 2.1.4
, http-date == 0.0.4
, http-reverse-proxy == 0.3.1.8
, http-reverse-proxy == 0.4.0.1
, http-types == 0.8.5
, language-javascript == 0.5.13
, lifted-base == 0.2.2.2
, lifted-base == 0.2.3.0
, mime-mail == 0.4.5.2
, mime-types == 0.1.0.4
, mmorph == 1.0.3
, monad-control == 0.3.3.0
, monad-logger == 0.3.6.1
, monad-loops == 0.4.2
, monad-logger == 0.3.7.1
, monad-loops == 0.4.2.1
, nats == 0.2
, network-conduit == 1.1.0
, optparse-applicative == 0.8.1
, path-pieces == 0.1.3.1
, optparse-applicative == 0.9.1.1
, path-pieces == 0.1.4
, pem == 0.2.2
, persistent == 1.3.1.1
, persistent-template == 1.3.1.4
, primitive == 0.5.3.0
, persistent == 1.3.3
, persistent-template == 1.3.2.2
, publicsuffixlist == 0.1
, pwstore-fast == 2.4.1
, quickcheck-io == 0.1.1
, resource-pool == 0.2.3.0
, resourcet == 1.1.2.2
, safe == 0.3.4
, scientific == 0.3.2.1
, resourcet == 1.1.2.3
, safe == 0.3.7
, securemem == 0.1.3
, semigroups == 0.15
, semigroups == 0.15.2
, setenv == 0.1.1.1
, shakespeare == 2.0.0.3
, shakespeare == 2.0.1.1
, shakespeare-css == 1.1.0
, shakespeare-i18n == 1.1.0
, shakespeare-js == 1.3.0
, shakespeare-text == 1.1.0
, silently == 1.2.4.1
, simple-sendfile == 0.2.14
, simple-sendfile == 0.2.15
, skein == 1.0.9
, socks == 0.5.4
, stm-chans == 3.0.0.2
, streaming-commons == 0.1.3
, streaming-commons == 0.1.4.1
, stringsearch == 0.3.6.5
, system-fileio == 0.3.14
, system-filepath == 0.4.12
@ -123,37 +118,33 @@ library
, tf-random == 0.5
, tls == 1.2.8
, transformers-base == 0.4.2
-- , transformers-compat == 0.3.3.4
, unix-compat == 0.4.1.1
, unordered-containers == 0.2.4.0
, utf8-string == 0.3.8
, vector == 0.10.11.0
, void == 0.6.1
, wai == 3.0.0
, wai == 3.0.1.1
, wai-app-static == 3.0.0
, wai-extra == 3.0.0
, wai-logger == 2.1.1
, wai-extra == 3.0.1.2
, wai-logger == 2.2.0
, wai-test == 3.0.0
, warp == 3.0.0.2
, warp == 3.0.0.5
, warp-tls == 3.0.0
, word8 == 0.0.4
, word8 == 0.1.1
, x509 == 1.4.11
, x509-store == 1.4.4
, x509-system == 1.4.5
, x509-validation == 1.5.0
, xml-conduit == 1.2.0.2
, xml-conduit == 1.2.1
, xml-types == 0.3.4
, xss-sanitize == 0.3.5.2
, yaml == 0.8.8.3
, yesod == 1.2.6
, yesod-auth == 1.3.1
, xss-sanitize == 0.3.5.3
, yaml == 0.8.8.4
, yesod == 1.2.6.1
, yesod-auth == 1.3.4.1
, yesod-auth-hashdb == 1.3.0.1
, yesod-core == 1.2.16
, yesod-form == 1.3.10
, yesod-core == 1.2.19
, yesod-form == 1.3.15.1
, yesod-persistent == 1.2.3
, yesod-routes == 1.2.0.6
, yesod-routes == 1.2.0.7
, yesod-static == 1.2.4
, yesod-test == 1.2.3
, yesod-test == 1.2.3.2
exposed-modules: Yesod.Platform

View File

@ -28,7 +28,9 @@ module Yesod.Test
yesodSpec
, YesodSpec
, yesodSpecWithSiteGenerator
, yesodSpecApp
, YesodExample
, YesodExampleData(..)
, YesodSpecTree (..)
, ydescribe
, yit
@ -125,7 +127,7 @@ import Data.Time.Clock (getCurrentTime)
-- | The state used in a single test case defined using 'yit'
--
-- Since 1.2.0
-- Since 1.2.4
data YesodExampleData site = YesodExampleData
{ yedApp :: !Application
, yedSite :: !site
@ -187,7 +189,7 @@ data RequestPart
-- | The RequestBuilder state monad constructs an url encoded string of arguments
-- to send with your requests. Some of the functions that run on it use the current
-- response to analize the forms that the server is expecting to receive.
-- response to analyze the forms that the server is expecting to receive.
type RequestBuilder site = ST.StateT (RequestBuilderData site) IO
-- | Start describing a Tests suite keeping cookies and a reference to the tested 'Application'
@ -234,6 +236,27 @@ yesodSpecWithSiteGenerator getSiteAction yspecs =
, yedResponse = Nothing
}
-- | Same as yesodSpec, but instead of taking a site it
-- takes an action which produces the 'Application' for each test.
-- This lets you use your middleware from makeApplication
yesodSpecApp :: YesodDispatch site
=> site
-> IO Application
-> YesodSpec site
-> Hspec.Spec
yesodSpecApp site getApp yspecs =
Core.fromSpecList $ map unYesod $ execWriter yspecs
where
unYesod (YesodSpecGroup x y) = Core.SpecGroup x $ map unYesod y
unYesod (YesodSpecItem x y) = Core.it x $ do
app <- getApp
ST.evalStateT y YesodExampleData
{ yedApp = app
, yedSite = site
, yedCookies = M.empty
, yedResponse = Nothing
}
-- | Describe a single test that keeps cookies, and a reference to the last response.
yit :: String -> YesodExample site () -> YesodSpec site
yit label example = tell [YesodSpecItem label example]

View File

@ -1,9 +1,9 @@
name: yesod-test
version: 1.2.3.1
version: 1.2.5
license: MIT
license-file: LICENSE
author: Nubis <nubis@woobiz.com.ar>
maintainer: Nubis <nubis@woobiz.com.ar>, Michael Snoyman
maintainer: Michael Snoyman, Greg Weber, Nubis <nubis@woobiz.com.ar>
synopsis: integration testing for WAI/Yesod Applications
category: Web, Yesod, Testing
stability: Experimental