@@ -9,6 +9,7 @@ import Data.Time
9import qualified Data.Text as T
9import qualified Data.Text as T
10import qualified Data.Text.Lazy as L
10import qualified Data.Text.Lazy as L
11import qualified Data.ByteString as BS
11import qualified Data.ByteString as BS
12+import Data.ByteString.Builder (toLazyByteString)
12import Data.Version
13import Data.Version
13import qualified Data.UUID as UUID
14import qualified Data.UUID as UUID
@@ -29,6 +30,10 @@ import Web.Internal.TestInstances
29(<=>) :: Eq a => (a -> b) -> (b -> Either T.Text a) -> a -> Bool
30(<=>) :: Eq a => (a -> b) -> (b -> Either T.Text a) -> a -> Bool
30(f <=> g) x = g (f x) == Right x
31(f <=> g) x = g (f x) == Right x
33+encodedUrlPieceProp :: ToHttpApiData a => a -> Bool
34+encodedUrlPieceProp x = toLazyByteString (toEncodedUrlPiece (toUrlPiece x)) == toLazyByteString (toEncodedUrlPiece x)
32checkUrlPiece :: forall a. (Eq a, ToHttpApiData a, FromHttpApiData a, Show a, Arbitrary a) => Proxy a -> String -> Spec
37checkUrlPiece :: forall a. (Eq a, ToHttpApiData a, FromHttpApiData a, Show a, Arbitrary a) => Proxy a -> String -> Spec
33checkUrlPiece _ name = prop name (toUrlPiece <=> parseUrlPiece :: a -> Bool)
38checkUrlPiece _ name = prop name (toUrlPiece <=> parseUrlPiece :: a -> Bool)
@@ -40,6 +45,15 @@ checkUrlPiece' gen name = prop name $ forAll gen (toUrlPiece <=> parseUrlPiece)
40checkUrlPieceI :: forall a. (Eq a, ToHttpApiData a, FromHttpApiData a, Arbitrary a) => Proxy a -> String -> Spec
45checkUrlPieceI :: forall a. (Eq a, ToHttpApiData a, FromHttpApiData a, Arbitrary a) => Proxy a -> String -> Spec
41checkUrlPieceI _ = checkUrlPiece (Proxy :: Proxy (RandomCase a))
46checkUrlPieceI _ = checkUrlPiece (Proxy :: Proxy (RandomCase a))
48+-- | Check that 'toEncodedUrlPiece' is equivallent to default implementation.
49+checkEncodedUrlPiece :: forall a. (Show a, ToHttpApiData a, Arbitrary a) => Proxy a -> String -> Spec
50+checkEncodedUrlPiece _ = checkEncodedUrlPiece' (arbitrary :: Gen a)
52+-- | Check that 'toEncodedUrlPiece' is equivallent to default implementation.
53+-- Use a given generator.
54+checkEncodedUrlPiece' :: forall a. (Show a, ToHttpApiData a) => Gen a -> String -> Spec
55+checkEncodedUrlPiece' gen name = prop name $ forAll gen encodedUrlPieceProp
43spec :: Spec
57spec :: Spec
45 describe "toUrlPiece <=> parseUrlPiece" $ do
59 describe "toUrlPiece <=> parseUrlPiece" $ do
@@ -78,6 +92,42 @@ spec = do
78 checkUrlPiece (Proxy :: Proxy Natural) "Natural"
92 checkUrlPiece (Proxy :: Proxy Natural) "Natural"
95+ describe "toEncodedUrlPiece encodes correctly" $ do
96+ checkEncodedUrlPiece (Proxy :: Proxy ()) "()"
97+ checkEncodedUrlPiece (Proxy :: Proxy Char) "Char"
98+ checkEncodedUrlPiece (Proxy :: Proxy Bool) "Bool"
99+ checkEncodedUrlPiece (Proxy :: Proxy Ordering) "Ordering"
100+ checkEncodedUrlPiece (Proxy :: Proxy Int) "Int"
101+ checkEncodedUrlPiece (Proxy :: Proxy Int8) "Int8"
102+ checkEncodedUrlPiece (Proxy :: Proxy Int16) "Int16"
103+ checkEncodedUrlPiece (Proxy :: Proxy Int32) "Int32"
104+ checkEncodedUrlPiece (Proxy :: Proxy Int64) "Int64"
105+ checkEncodedUrlPiece (Proxy :: Proxy Integer) "Integer"
106+ checkEncodedUrlPiece (Proxy :: Proxy Word) "Word"
107+ checkEncodedUrlPiece (Proxy :: Proxy Word8) "Word8"
108+ checkEncodedUrlPiece (Proxy :: Proxy Word16) "Word16"
109+ checkEncodedUrlPiece (Proxy :: Proxy Word32) "Word32"
110+ checkEncodedUrlPiece (Proxy :: Proxy Word64) "Word64"
111+ checkEncodedUrlPiece (Proxy :: Proxy String) "String"
112+ checkEncodedUrlPiece (Proxy :: Proxy T.Text) "Text.Strict"
113+ checkEncodedUrlPiece (Proxy :: Proxy L.Text) "Text.Lazy"
114+ checkEncodedUrlPiece (Proxy :: Proxy Day) "Day"
115+ checkEncodedUrlPiece' localTimeGen "LocalTime"
116+ checkEncodedUrlPiece' zonedTimeGen "ZonedTime"
117+ checkEncodedUrlPiece' utcTimeGen "UTCTime"
118+ checkEncodedUrlPiece' nominalDiffTimeGen "NominalDiffTime"
119+ checkEncodedUrlPiece (Proxy :: Proxy Version) "Version"
120+ checkEncodedUrlPiece' uuidGen "UUID"
122+ checkEncodedUrlPiece (Proxy :: Proxy (Maybe String)) "Maybe String"
123+ checkEncodedUrlPiece (Proxy :: Proxy (Maybe Integer)) "Maybe Integer"
124+ checkEncodedUrlPiece (Proxy :: Proxy (Either Integer T.Text)) "Either Integer Text"
125+ checkEncodedUrlPiece (Proxy :: Proxy (Either Version Day)) "Either Version Day"
127+#if MIN_VERSION_base(4,8,0)
128+ checkEncodedUrlPiece (Proxy :: Proxy Natural) "Natural"
81 it "bad integers are rejected" $ do
131 it "bad integers are rejected" $ do
82 parseUrlPieceMaybe (T.pack "123hello") `shouldBe` (Nothing :: Maybe Int)
132 parseUrlPieceMaybe (T.pack "123hello") `shouldBe` (Nothing :: Maybe Int)
@@ -88,6 +138,7 @@ spec = do
88 it "invalid utf8 is handled" $ do
138 it "invalid utf8 is handled" $ do
89 parseHeaderMaybe (BS.pack [128]) `shouldBe` (Nothing :: Maybe T.Text)
139 parseHeaderMaybe (BS.pack [128]) `shouldBe` (Nothing :: Maybe T.Text)
91uuidGen :: Gen UUID.UUID
142uuidGen :: Gen UUID.UUID
92uuidGen = UUID.fromWords <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
143uuidGen = UUID.fromWords <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary