1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
import Data.Text (Text)
import Debug.Trace
import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.QuickCheck
import Test.Hspec.HUnit
import Test.QuickCheck (Arbitrary (..))
import Test.HUnit
import qualified Blaze.ByteString.Builder as Blaze
import qualified Data.ByteString as S
import qualified Data.ByteString.Char8 as S8
import qualified Data.Text as T
--main :: IO ()
main = hspecX
[ describe "encode/decode path"
[ it "is identity to encode and then decode"
$ property propEncodeDecodePath
, it "does not escape period and dash" $
Blaze.toByteString (encodePath ["foo-bar.baz"] []) @?= "/foo-bar.baz"
]
, describe "encode/decode query"
[ it "is identity to encode and then decode"
$ property propEncodeDecodeQuery
, it "add ? in front of Query if and only if necessary"
$ property propQueryQuestionMark
]
, describe "encode/decode path segments"
[ it "is identity to encode and then decode"
$ property propEncodeDecodePathSegments
]
, describe "encode ByteRanges"
[ it "first 500 bytes" $ renderByteRanges [ByteRangeFromTo 0 499] @?= "bytes=0-499"
, it "second 500 bytes" $ renderByteRanges [ByteRangeFromTo 500 999] @?= "bytes=500-999"
, it "final 500 bytes" $ renderByteRanges [ByteRangeSuffix 500] @?= "bytes=-500"
, it "final 500 bytes (of 1000, absolute)" $ renderByteRanges [ByteRangeFrom 9500] @?= "bytes=9500-"
, it "first and last bytes only" $ renderByteRanges [ByteRangeFromTo 0 0, ByteRangeSuffix 1] @?= "bytes=0-0,-1"
, it "non-canonical second 500 bytes (1)" $ renderByteRanges [ByteRangeFromTo 500 600, ByteRangeFromTo 601 999] @?= "bytes=500-600,601-999"
, it "non-canonical second 500 bytes (2)" $ renderByteRanges [ByteRangeFromTo 500 700, ByteRangeFromTo 601 999] @?= "bytes=500-700,601-999"
]
]
propEncodeDecodePath :: ([Text], Query) -> Bool
propEncodeDecodePath (p', q') =
let x = Blaze.toByteString $ encodePath a b
y = decodePath x
z = y == (a, b)
in if z then z else traceShow (a, b, x, y) z
where
a = if p' == [""] then [] else p'
b = filter (\(x, _) -> not (S.null x)) q'
propEncodeDecodeQuery :: Query -> Bool
propEncodeDecodeQuery q' =
q == parseQuery (renderQuery True q)
where
q = filter (\(x, _) -> not (S.null x)) q'
propQueryQuestionMark :: (Bool, Query) -> Bool
propQueryQuestionMark (useQuestionMark, query) = actual == expected
where
actual = case S8.uncons $ renderQuery useQuestionMark query of
Nothing -> False
Just ('?', _) -> True
_ -> False
expected = case (useQuestionMark, null query) of
(False, _) -> False
(True, True) -> False
(True, False) -> True
propEncodeDecodePathSegments :: [Text] -> Bool
propEncodeDecodePathSegments p' =
p == decodePathSegments (Blaze.toByteString $ encodePathSegments p)
where
p = if p' == [""] then [] else p'
instance Arbitrary Text where
arbitrary = fmap T.pack arbitrary
instance Arbitrary S.ByteString where
arbitrary = fmap S.pack arbitrary
|