git.iko.soy/typeable/http-api-data
on 8cc39ea help sign in
109 lines 4.3 kB history raw
1{-# LANGUAGE CPP #-}
2{-# LANGUAGE ScopedTypeVariables #-}
3module Web.Internal.HttpApiDataSpec (spec) where
5import Control.Applicative
6import Data.Int
7import Data.Word
8import Data.Time
9import qualified Data.Text as T
10import qualified Data.Text.Lazy as L
11import qualified Data.ByteString as BS
12import Data.Version
13import qualified Data.UUID as UUID
15import Data.Proxy
17#if MIN_VERSION_base(4,8,0)
18import Numeric.Natural
19#endif
21import Test.Hspec
22import Test.Hspec.QuickCheck(prop)
23import Test.QuickCheck
25import Web.Internal.HttpApiData
27import Web.Internal.TestInstances
29(<=>) :: Eq a => (a -> b) -> (b -> Either T.Text a) -> a -> Bool
30(f <=> g) x = g (f x) == Right x
32checkUrlPiece :: forall a. (Eq a, ToHttpApiData a, FromHttpApiData a, Show a, Arbitrary a) => Proxy a -> String -> Spec
33checkUrlPiece _ name = prop name (toUrlPiece <=> parseUrlPiece :: a -> Bool)
35-- | Check with given generator
36checkUrlPiece' :: forall a. (Eq a, ToHttpApiData a, FromHttpApiData a, Show a) => Gen a -> String -> Spec
37checkUrlPiece' gen name = prop name $ forAll gen (toUrlPiece <=> parseUrlPiece)
39-- | Check case insensitivity for @parseUrlPiece@.
40checkUrlPieceI :: forall a. (Eq a, ToHttpApiData a, FromHttpApiData a, Arbitrary a) => Proxy a -> String -> Spec
41checkUrlPieceI _ = checkUrlPiece (Proxy :: Proxy (RandomCase a))
43spec :: Spec
44spec = do
45 describe "toUrlPiece <=> parseUrlPiece" $ do
46 checkUrlPiece (Proxy :: Proxy ()) "()"
47 checkUrlPiece (Proxy :: Proxy Char) "Char"
48 checkUrlPieceI (Proxy :: Proxy Bool) "Bool"
49 checkUrlPieceI (Proxy :: Proxy Ordering) "Ordering"
50 checkUrlPiece (Proxy :: Proxy Int) "Int"
51 checkUrlPiece (Proxy :: Proxy Int8) "Int8"
52 checkUrlPiece (Proxy :: Proxy Int16) "Int16"
53 checkUrlPiece (Proxy :: Proxy Int32) "Int32"
54 checkUrlPiece (Proxy :: Proxy Int64) "Int64"
55 checkUrlPiece (Proxy :: Proxy Integer) "Integer"
56 checkUrlPiece (Proxy :: Proxy Word) "Word"
57 checkUrlPiece (Proxy :: Proxy Word8) "Word8"
58 checkUrlPiece (Proxy :: Proxy Word16) "Word16"
59 checkUrlPiece (Proxy :: Proxy Word32) "Word32"
60 checkUrlPiece (Proxy :: Proxy Word64) "Word64"
61 checkUrlPiece (Proxy :: Proxy String) "String"
62 checkUrlPiece (Proxy :: Proxy T.Text) "Text.Strict"
63 checkUrlPiece (Proxy :: Proxy L.Text) "Text.Lazy"
64 checkUrlPiece (Proxy :: Proxy Day) "Day"
65 checkUrlPiece' localTimeGen "LocalTime"
66 checkUrlPiece' zonedTimeGen "ZonedTime"
67 checkUrlPiece' utcTimeGen "UTCTime"
68 checkUrlPiece' nominalDiffTimeGen "NominalDiffTime"
69 checkUrlPiece (Proxy :: Proxy Version) "Version"
70 checkUrlPiece' uuidGen "UUID"
72 checkUrlPiece (Proxy :: Proxy (Maybe String)) "Maybe String"
73 checkUrlPieceI (Proxy :: Proxy (Maybe Integer)) "Maybe Integer"
74 checkUrlPiece (Proxy :: Proxy (Either Integer T.Text)) "Either Integer Text"
75 checkUrlPieceI (Proxy :: Proxy (Either Version Day)) "Either Version Day"
77#if MIN_VERSION_base(4,8,0)
78 checkUrlPiece (Proxy :: Proxy Natural) "Natural"
79#endif
81 it "bad integers are rejected" $ do
82 parseUrlPieceMaybe (T.pack "123hello") `shouldBe` (Nothing :: Maybe Int)
84 it "bounds checking works" $ do
85 parseUrlPieceMaybe (T.pack "256") `shouldBe` (Nothing :: Maybe Int8)
86 parseUrlPieceMaybe (T.pack "-10") `shouldBe` (Nothing :: Maybe Word)
88 it "invalid utf8 is handled" $ do
89 parseHeaderMaybe (BS.pack [128]) `shouldBe` (Nothing :: Maybe T.Text)
91uuidGen :: Gen UUID.UUID
92uuidGen = UUID.fromWords <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
94-- TODO: this generators don't generate full range items
95localTimeGen :: Gen LocalTime
96localTimeGen = LocalTime
97 <$> arbitrary
98 <*> liftA3 TimeOfDay (choose (0, 23)) (choose (0, 59)) (fromInteger <$> choose (0, 60))
100zonedTimeGen :: Gen ZonedTime
101zonedTimeGen = ZonedTime
102 <$> localTimeGen -- Note: not arbitrary!
103 <*> liftA3 TimeZone arbitrary arbitrary (vectorOf 3 (elements ['A'..'Z']))
105utcTimeGen :: Gen UTCTime
106utcTimeGen = UTCTime <$> arbitrary <*> fmap fromInteger (choose (0, 86400))
108nominalDiffTimeGen :: Gen NominalDiffTime
109nominalDiffTimeGen = fromInteger <$> arbitrary