{-# LANGUAGE CPP #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Servant.Common.BaseUrlSpec where #if !MIN_VERSION_base(4,8,0) import Control.Applicative #endif import Control.DeepSeq import Test.Hspec import Test.QuickCheck import Servant.Common.BaseUrl spec :: Spec spec = do describe "showBaseUrl" $ do it "shows a BaseUrl" $ do showBaseUrl (BaseUrl Http "foo.com" 80) `shouldBe` "http://foo.com" it "shows a https BaseUrl" $ do showBaseUrl (BaseUrl Https "foo.com" 443) `shouldBe` "https://foo.com" describe "httpBaseUrl" $ do it "allows to construct default http BaseUrls" $ do BaseUrl Http "bar" 80 `shouldBe` BaseUrl Http "bar" 80 describe "parseBaseUrl" $ do it "is total" $ do property $ \ string -> deepseq (fmap show (parseBaseUrl string)) True it "is the inverse of showBaseUrl" $ do property $ \ baseUrl -> counterexample (showBaseUrl baseUrl) $ parseBaseUrl (showBaseUrl baseUrl) === Right baseUrl it "allows trailing slashes" $ do parseBaseUrl "foo.com/" `shouldBe` Right (BaseUrl Http "foo.com" 80) context "urls without scheme" $ do it "assumes http" $ do parseBaseUrl "foo.com" `shouldBe` Right (BaseUrl Http "foo.com" 80) it "allows port numbers" $ do parseBaseUrl "foo.com:8080" `shouldBe` Right (BaseUrl Http "foo.com" 8080) it "rejects ftp urls" $ do parseBaseUrl "ftp://foo.com" `shouldSatisfy` isLeft instance Arbitrary BaseUrl where arbitrary = BaseUrl <$> elements [Http, Https] <*> hostNameGen <*> portGen where -- this does not perfectly mirror the url standard, but I hope it's good -- enough. hostNameGen = do let letters = ['a' .. 'z'] ++ ['A' .. 'Z'] first <- elements letters middle <- listOf1 $ elements (letters ++ ['0' .. '9'] ++ ['.', '-']) last <- elements letters return (first : middle ++ [last]) portGen = frequency $ (1, return 80) : (1, return 443) : (1, choose (1, 20000)) : [] isLeft :: Either a b -> Bool isLeft = either (const True) (const False)