packages feed

hspec-wai 0.6.0 → 0.6.1

raw patch · 3 files changed

+81/−7 lines, 3 filesdep +QuickCheckdep ~bytestring

Dependencies added: QuickCheck

Dependency ranges changed: bytestring

Files

hspec-wai.cabal view
@@ -1,5 +1,5 @@ name:             hspec-wai-version:          0.6.0+version:          0.6.1 license:          MIT license-file:     LICENSE copyright:        (c) 2012-2014 Fujimura Daisuke,@@ -9,8 +9,8 @@ build-type:       Simple cabal-version:    >= 1.8 category:         Testing-synopsis:         Experimental Hspec support for testing WAI applications (depends on hspec2!)-description:      Experimental Hspec support for testing WAI applications (depends on hspec2!)+synopsis:         Experimental Hspec support for testing WAI applications+description:      Experimental Hspec support for testing WAI applications  source-repository head   type: git@@ -29,7 +29,7 @@       Test.Hspec.Wai.Matcher   build-depends:       base == 4.*-    , bytestring+    , bytestring >= 0.10     , text     , transformers     , case-insensitive@@ -61,3 +61,4 @@     , hspec-expectations      , hspec+    , QuickCheck
src/Test/Hspec/Wai.hs view
@@ -14,6 +14,9 @@ , delete , request +-- ** Posting HTML forms+, postHtmlForm+ -- * Matching on the response , shouldRespondWith , ResponseMatcher(..)@@ -41,6 +44,7 @@ import           Test.Hspec.Core.Hooks import           Test.Hspec.Expectations (expectationFailure) +import           Test.Hspec.Wai.Util import           Test.Hspec.Wai.Internal import           Test.Hspec.Wai.Matcher @@ -121,3 +125,12 @@ request method path headers body = getApp >>= liftIO . runSession (Wai.srequest $ SRequest req body)   where     req = setPath defaultRequest {requestMethod = method, requestHeaders = headers} path++-- | Perform a @POST@ request to the application under test.+--+-- The specified list of key-value pairs is encoded as+-- @application/x-www-form-urlencoded@ and used as request body.+--+-- In additon the @Content-Type@ is set to @application/x-www-form-urlencoded@.+postHtmlForm :: ByteString -> [(String, String)] -> WaiSession SResponse+postHtmlForm path = request methodPost path [(hContentType, "application/x-www-form-urlencoded")] . formUrlEncodeQuery
src/Test/Hspec/Wai/Util.hs view
@@ -4,17 +4,23 @@ import           Control.Monad import           Data.Monoid import           Data.Maybe-import           Data.Char+import           Data.List+import           Data.Word+import           Data.Char hiding (ord)+import qualified Data.Char as Char import           Data.ByteString (ByteString)-import qualified Data.ByteString.Char8 as B+import qualified Data.ByteString as B+import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Lazy as LB+import           Data.ByteString.Lazy.Builder (Builder)+import qualified Data.ByteString.Lazy.Builder as Builder import qualified Data.Text as T import qualified Data.Text.Encoding as T import qualified Data.CaseInsensitive as CI import           Network.HTTP.Types  formatHeader :: Header -> String-formatHeader header@(name, value) = "  " ++ fromMaybe (show header) (safeToString $ B.concat [CI.original name, ": ", value])+formatHeader header@(name, value) = "  " ++ fromMaybe (show header) (safeToString $ B8.concat [CI.original name, ": ", value])  safeToString :: ByteString -> Maybe String safeToString bs = do@@ -27,3 +33,57 @@ -- for compatibility with older versions of `bytestring` toStrict :: LB.ByteString -> ByteString toStrict = mconcat . LB.toChunks++formUrlEncodeQuery :: [(String, String)] -> LB.ByteString+formUrlEncodeQuery = Builder.toLazyByteString . mconcat . intersperse amp . map encodePair+  where+    equals = Builder.word8 (ord '=')+    amp = Builder.word8 (ord '&')+    percent = Builder.word8 (ord '%')+    plus = Builder.word8 (ord '+')++    encodePair :: (String, String) -> Builder+    encodePair (key, value) = encode key <> equals <> encode value++    encode :: String -> Builder+    encode = escape . T.encodeUtf8 . T.pack . newlineNormalize++    newlineNormalize :: String -> String+    newlineNormalize input = case input of+      [] -> []+      '\n' : xs -> '\r' : '\n': newlineNormalize xs+      x : xs -> x : newlineNormalize xs++    escape :: ByteString -> Builder+    escape = mconcat . map f . B.unpack+      where+        f :: Word8 -> Builder+        f c+          | p c = Builder.word8 c+          | c == ord ' ' = plus+          | otherwise = percentEncode c++        p :: Word8 -> Bool+        p c =+             ord 'a' <= c && c <= ord 'z'+          || c == ord '_'+          || c == ord '*'+          || c == ord '-'+          || c == ord '.'+          || ord '0' <= c && c <= ord '9'+          || ord 'A' <= c && c <= ord 'Z'++    ord :: Char -> Word8+    ord = fromIntegral . Char.ord++    percentEncode :: Word8 -> Builder+    percentEncode n = percent <> hex hi <> hex lo+      where+        (hi, lo) = n `divMod` 16++    hex :: Word8 -> Builder+    hex n = Builder.word8 (offset + n)+      where+        offset+          | n < 10    = 48+          | otherwise = 55