wai-app-static 1.3.2 → 1.3.2.1
raw patch · 4 files changed
+145/−3 lines, 4 filesdep ~template-haskell
Dependency ranges changed: template-haskell
Files
- WaiAppStatic/Storage/Embedded/TH.hs +19/−0
- test/EmbeddedTestEntries.hs +45/−0
- test/WaiAppEmbeddedTest.hs +78/−0
- wai-app-static.cabal +3/−3
WaiAppStatic/Storage/Embedded/TH.hs view
@@ -18,6 +18,10 @@ import WaiAppStatic.Storage.Filesystem (defaultWebAppSettings) import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as BL+#if !MIN_VERSION_template_haskell(2, 8, 0)+import qualified Data.ByteString.Char8 as B8+import qualified Data.ByteString.Lazy.Char8 as BL8+#endif import qualified Data.HashMap.Strict as M import qualified Data.Text as T import qualified Data.Text.Encoding as T@@ -71,15 +75,30 @@ -- the IORef will always be holding (NoFinalizers, []). Therefore -- unsafeDupablePerformIO is safe. bytestringE :: B.ByteString -> ExpQ+#if MIN_VERSION_template_haskell(2, 8, 0) bytestringE b = [| unsafeDupablePerformIO (unsafePackAddressLen (I# $lenE) $ctE) |] where lenE = litE $ intPrimL $ toInteger $ B.length b ctE = litE $ stringPrimL $ B.unpack b+#else+bytestringE b =+ [| B8.pack $s |]+ where+ s = litE $ stringL $ B8.unpack b+#endif+ bytestringLazyE :: BL.ByteString -> ExpQ+#if MIN_VERSION_template_haskell(2, 8, 0) bytestringLazyE b = [| unsafeDupablePerformIO (unsafePackAddressLen (I# $lenE) $ctE) |] where lenE = litE $ intPrimL $ toInteger $ BL.length b ctE = litE $ stringPrimL $ BL.unpack b+#else+bytestringLazyE b =+ [| B8.pack $s |]+ where+ s = litE $ stringL $ BL8.unpack b+#endif -- | A template haskell expression which creates either an EmbeddedEntry or ReloadEntry. mkEntry :: EmbeddableEntry -> ExpQ
+ test/EmbeddedTestEntries.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE TemplateHaskell, QuasiQuotes, OverloadedStrings #-}++module EmbeddedTestEntries where++import WaiAppStatic.Storage.Embedded+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.Encoding as TL+import qualified Data.ByteString.Lazy as BL++body :: Int -> Char -> BL.ByteString+body i c = TL.encodeUtf8 $ TL.pack $ take i $ repeat c++mkEntries :: IO [EmbeddableEntry]+mkEntries = return+ -- An entry that should be compressed+ [ EmbeddableEntry "e1.txt" + "text/plain" + (Left ("Etag 1", body 1000 'A'))++ -- An entry so short that the compressed text is longer+ , EmbeddableEntry "e2.txt"+ "text/plain"+ (Left ("Etag 2", "ABC"))++ -- An entry that is not compressed because of the mime+ , EmbeddableEntry "somedir/e3.txt"+ "xxx"+ (Left ("Etag 3", body 1000 'A'))++ -- A reloadable entry+ , EmbeddableEntry "e4.css"+ "text/css"+ (Right [| return ("Etag 4" :: T.Text, body 2000 'Q') |])++ -- An entry without etag+ , EmbeddableEntry "e5.txt"+ "text/plain"+ (Left ("", body 1000 'Z'))++ -- A reloadable entry without etag+ , EmbeddableEntry "e6.txt"+ "text/plain"+ (Right [| return ("" :: T.Text, body 1000 'W') |] )+ ]
+ test/WaiAppEmbeddedTest.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE TemplateHaskell, OverloadedStrings #-}+module WaiAppEmbeddedTest (embSpec) where++import Codec.Compression.GZip (compress)+import EmbeddedTestEntries+import Network.Wai+import Network.Wai.Application.Static (staticApp)+import Network.Wai.Test+import Test.Hspec+import WaiAppStatic.Storage.Embedded++embApp :: Application+embApp = staticApp $(mkSettings mkEntries)++defRequest :: Request+defRequest = defaultRequest++embSpec :: Spec+embSpec = do+ let embed = flip runSession embApp+ describe "embedded, compressed entry" $ do+ it "served correctly" $ embed $ do+ req <- request (setRawPathInfo defRequest "e1.txt")+ assertStatus 200 req+ assertHeader "Content-Type" "text/plain" req+ assertHeader "Content-Encoding" "gzip" req+ assertHeader "ETag" "Etag 1" req+ assertNoHeader "Last-Modified req" req+ assertBody (compress $ body 1000 'A') req++ it "304 when valid if-none-match sent" $ embed $ do+ req <- request (setRawPathInfo defRequest "e1.txt")+ { requestHeaders = [("If-None-Match", "Etag 1")] }+ assertStatus 304 req++ describe "embedded, uncompressed entry" $ do+ it "too short" $ embed $ do+ req <- request (setRawPathInfo defRequest "e2.txt")+ assertStatus 200 req+ assertHeader "Content-Type" "text/plain" req+ assertNoHeader "Content-Encoding" req+ assertHeader "ETag" "Etag 2" req+ assertBody "ABC" req++ it "wrong mime" $ embed $ do+ req <- request (setRawPathInfo defRequest "somedir/e3.txt")+ assertStatus 200 req+ assertHeader "Content-Type" "xxx" req+ assertNoHeader "Content-Encoding" req+ assertHeader "ETag" "Etag 3" req+ assertBody (body 1000 'A') req++ describe "reloadable entry" $+ it "served correctly" $ embed $ do+ req <- request (setRawPathInfo defRequest "e4.css")+ assertStatus 200 req+ assertHeader "Content-Type" "text/css" req+ assertNoHeader "Content-Encoding" req+ assertHeader "ETag" "Etag 4" req+ assertBody (body 2000 'Q') req++ describe "entries without etags" $ do+ it "embedded entry" $ embed $ do+ req <- request (setRawPathInfo defRequest "e5.txt")+ assertStatus 200 req+ assertHeader "Content-Type" "text/plain" req+ assertHeader "Content-Encoding" "gzip" req+ assertNoHeader "ETag" req+ assertBody (compress $ body 1000 'Z') req++ it "reload entry" $ embed $ do+ req <- request (setRawPathInfo defRequest "e6.txt")+ assertStatus 200 req+ assertHeader "Content-Type" "text/plain" req+ assertNoHeader "Content-Encoding" req+ assertNoHeader "ETag" req+ assertBody (body 1000 'W') req+
wai-app-static.cabal view
@@ -1,5 +1,5 @@ name: wai-app-static-version: 1.3.2+version: 1.3.2.1 license: MIT license-file: LICENSE author: Michael Snoyman <michael@snoyman.com>@@ -14,7 +14,7 @@ Extra-source-files: images/folder.png images/haskell.png- test/WaiAppStaticTest.hs+ test/*.hs test/a/b tests.hs @@ -48,7 +48,7 @@ , cereal >= 0.3.5 , mime-types >= 0.1 && < 0.2 , unordered-containers >= 0.2- , template-haskell >= 2.8+ , template-haskell >= 2.7 , zlib >= 0.5 exposed-modules: Network.Wai.Application.Static