packages feed

req 3.10.0 → 3.11.0

raw patch · 5 files changed

+107/−30 lines, 5 files

Files

CHANGELOG.md view
@@ -1,3 +1,10 @@+## Req 3.11.0++* Add the `queryParamToList` method to the `QueryParam` type class.+* Add the `formToQuery` function. [Issue 126](https://github.com/mrkkrp/req/issues/126).+* Add `FromForm` instances (in the `Web.FormUrlEncoded` module) to the+  `Option` and `FormUrlEncodedParam` types.+ ## Req 3.10.0  * Add `MonadHttp` instances for `transformers` types.
Network/HTTP/Req.hs view
@@ -155,6 +155,7 @@     -- $query-parameters     (=:),     queryFlag,+    formToQuery,     QueryParam (..),      -- *** Headers@@ -251,7 +252,7 @@ import qualified Data.List.NonEmpty as NE import Data.Maybe (fromMaybe) import Data.Proxy-import Data.Semigroup hiding (Option, option)+import Data.Semigroup (Endo (..)) import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.Encoding as T@@ -272,6 +273,8 @@ import qualified Text.URI as URI import qualified Text.URI.QQ as QQ import qualified Web.Authenticate.OAuth as OAuth+import Web.FormUrlEncoded (FromForm (..), ToForm (..))+import qualified Web.FormUrlEncoded as Form import Web.HttpApiData (ToHttpApiData (..))  ----------------------------------------------------------------------------@@ -1303,7 +1306,14 @@ instance QueryParam FormUrlEncodedParam where   queryParam name mvalue =     FormUrlEncodedParam [(name, toQueryParam <$> mvalue)]+  queryParamToList (FormUrlEncodedParam p) = p +-- | Use 'formToQuery'.+--+-- @since 3.11.0+instance FromForm FormUrlEncodedParam where+  fromForm = Right . formToQuery+ -- | Multipart form data. Please consult the -- "Network.HTTP.Client.MultipartFormData" module for how to construct -- parts, then use 'reqBodyMultipart' to create actual request body from the@@ -1428,6 +1438,12 @@   mempty = Option mempty Nothing   mappend = (<>) +-- | Use 'formToQuery'.+--+-- @since 3.11.0+instance FromForm (Option scheme) where+  fromForm = Right . formToQuery+ -- | A helper to create an 'Option' that modifies only collection of query -- parameters. This helper is not a part of the public API. withQueryParams :: (Y.QueryText -> Y.QueryText) -> Option scheme@@ -1482,6 +1498,24 @@ queryFlag :: QueryParam param => Text -> param queryFlag name = queryParam name (Nothing :: Maybe ()) +-- | Construct query parameters from a 'ToForm' instance. This function+-- produces the same query params as 'Form.urlEncodeAsFormStable'.+--+-- Note that 'Form.Form' doesn't have the concept of parameters with the+-- empty value (i.e. what you can get by @key =: ""@). If the value is+-- empty, it will be encoded as a valueless parameter (i.e. what you can get+-- by @queryFlag key@).+--+-- @since 3.11.0+formToQuery :: (QueryParam param, Monoid param, ToForm f) => f -> param+formToQuery f = mconcat . fmap toParam . Form.toListStable $ toForm f+  where+    toParam (key, val) =+      queryParam key $+        if val == ""+          then Nothing+          else Just val+ -- | A type class for query-parameter-like things. The reason to have an -- overloaded 'queryParam' is to be able to use it as an 'Option' and as a -- 'FormUrlEncodedParam' when constructing form URL encoded request bodies.@@ -1493,9 +1527,15 @@   -- method, because they are easier to read.   queryParam :: ToHttpApiData a => Text -> Maybe a -> param +  -- | Get the query parameter names and values set by 'queryParam'.+  --+  -- @since 3.11.0+  queryParamToList :: param -> [(Text, Maybe Text)]+ instance QueryParam (Option scheme) where   queryParam name mvalue =     withQueryParams ((:) (name, toQueryParam <$> mvalue))+  queryParamToList (Option f _) = fst $ appEndo f ([], L.defaultRequest)  ---------------------------------------------------------------------------- -- Request—Optional parameters—Headers
httpbin-tests/Network/HTTP/ReqSpec.hs view
@@ -16,6 +16,7 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as BL import Data.Functor.Identity (runIdentity)+import Data.Maybe (fromJust) import Data.Proxy import Data.Text (Text) import qualified Data.Text as T@@ -135,7 +136,7 @@             LM.partBS "bar" "bar data!"           ]       r <- req POST (httpbin /: "post") body jsonResponse mempty-      let Just contentType = getRequestContentType body+      let contentType = fromJust (getRequestContentType body)       (stripFunnyHeaders . stripOrigin) (responseBody r)         `shouldBe` object           [ "args" .= emptyObject,@@ -260,21 +261,17 @@   -- TODO /response-headers   -- TODO /redirect -  -- FIXME Redirects test is temporarily disabled due to-  ---  -- https://github.com/postmanlabs/httpbin/issues/617--  -- describe "redirects" $-  --   it "follows redirects" $ do-  --     r <--  --       req-  --         GET-  --         (httpbin /: "redirect-to")-  --         NoReqBody-  --         ignoreResponse-  --         ("url" =: ("https://httpbin.org" :: Text))-  --     responseStatusCode r `shouldBe` 200-  --     responseStatusMessage r `shouldBe` "OK"+  describe "redirects" $+    it "follows redirects" $ do+      r <-+        req+          GET+          (httpbin /: "redirect-to")+          NoReqBody+          ignoreResponse+          ("url" =: ("https://httpbin.org" :: Text))+      responseStatusCode r `shouldBe` 200+      responseStatusMessage r `shouldBe` "OK"    -- TODO /relative-redicet   -- TODO /absolute-redirect
pure-tests/Network/HTTP/ReqSpec.hs view
@@ -33,6 +33,7 @@ import qualified Data.Text.Encoding as T import Data.Time import Data.Typeable (Typeable, eqT)+import GHC.Exts (IsList (..)) import GHC.Generics import qualified Language.Haskell.TH as TH import qualified Language.Haskell.TH.Quote as TH@@ -46,6 +47,7 @@ import Text.URI (URI) import qualified Text.URI as URI import qualified Text.URI.QQ as QQ+import qualified Web.FormUrlEncoded as F  spec :: Spec spec = do@@ -159,11 +161,13 @@           let uriHttp = uri' {URI.uriScheme = Just [QQ.scheme|http|]}               uriHttps = uri' {URI.uriScheme = Just [QQ.scheme|https|]}           requestHttp <--            let Left (url', options) = fromJust (useURI uriHttp)-             in req_ GET url' NoReqBody options+            case fromJust (useURI uriHttp) of+              Left (url', options) -> req_ GET url' NoReqBody options+              _ -> error "(useURI uriHttp) should have returned Left"           requestHttps <--            let Right (url', options) = fromJust (useURI uriHttps)-             in req_ GET url' NoReqBody options+            case fromJust (useURI uriHttps) of+              Right (url', options) -> req_ GET url' NoReqBody options+              _ -> error "(useURI uriHttps) should have returned Right"           L.host requestHttp `shouldBe` uriHost uriHttp           L.host requestHttps `shouldBe` uriHost uriHttps           L.port requestHttp `shouldBe` uriPort 80 uriHttp@@ -233,6 +237,19 @@             L.RequestBodyLBS x -> x `shouldBe` renderQuery params             _ -> expectationFailure "Wrong request body constructor." +  describe "query params" $ do+    describe "FormUrlEncodedParam" $ do+      describe "formToQuery" $ do+        it "should produce the same parameters as F.urlEncodeFormStable" $+          property $ \form -> do+            request <- req_ POST url (ReqBodyUrlEnc $ formToQuery form) mempty+            case L.requestBody request of+              L.RequestBodyLBS x -> x `shouldBe` F.urlEncodeFormStable form+              _ -> expectationFailure "Wrong request body constructor"+      specParamToList (Proxy :: Proxy FormUrlEncodedParam)+    describe "Option" $ do+      specParamToList (Proxy :: Proxy (Option 'Http))+   describe "optional parameters" $ do     describe "header" $ do       it "sets specified header value" $@@ -486,6 +503,9 @@ instance Arbitrary DiffTime where   arbitrary = secondsToDiffTime <$> arbitrary +instance Arbitrary F.Form where+  arbitrary = (F.Form . fromList) <$> arbitrary+ ---------------------------------------------------------------------------- -- Helper types @@ -598,3 +618,15 @@ basicProxyAuthHeader username password =   fromJust . lookup Y.hProxyAuthorization . L.requestHeaders $     L.applyBasicProxyAuth username password L.defaultRequest++-- | Spec about 'paramToList' for the type @p@.+specParamToList :: (QueryParam p, Monoid p) => Proxy p -> Spec+specParamToList typeProxy = do+  describe "paramToList" $ do+    it "should reproduce the parameters given by queryParam" $+      property $ \(QueryParams params) -> do+        let queryParam0 =+              (mconcat $ fmap (uncurry queryParam) params)+                `asProxyTypeOf` typeProxy+            got = queryParamToList queryParam0+        got `shouldBe` params
req.cabal view
@@ -1,11 +1,11 @@-cabal-version:   1.18+cabal-version:   2.4 name:            req-version:         3.10.0-license:         BSD3+version:         3.11.0+license:         BSD-3-Clause license-file:    LICENSE.md maintainer:      Mark Karpov <markkarpov92@gmail.com> author:          Mark Karpov <markkarpov92@gmail.com>-tested-with:     ghc ==8.8.4 ghc ==8.10.5 ghc ==9.0.1+tested-with:     ghc ==8.10.7 ghc ==9.0.2 ghc ==9.2.1 homepage:        https://github.com/mrkkrp/req bug-reports:     https://github.com/mrkkrp/req/issues synopsis:        HTTP client library@@ -49,8 +49,8 @@         monad-control >=1.0 && <1.1,         mtl >=2.0 && <3.0,         retry >=0.8 && <0.10,-        template-haskell >=2.14 && <2.18,-        text >=0.2 && <1.3,+        template-haskell >=2.14 && <2.19,+        text >=0.2 && <2.1,         time >=1.2 && <1.13,         transformers >=0.5.3.0 && <0.6,         transformers-base,@@ -83,14 +83,15 @@         case-insensitive >=0.2 && <1.3,         hspec >=2.0 && <3.0,         hspec-core >=2.0 && <3.0,+        http-api-data >=0.2 && <0.5,         http-client >=0.7 && <0.8,         http-types >=0.8 && <10.0,         modern-uri >=0.3 && <0.4,         mtl >=2.0 && <3.0,         req,         retry >=0.8 && <0.10,-        template-haskell >=2.14 && <2.18,-        text >=0.2 && <1.3,+        template-haskell >=2.14 && <2.19,+        text >=0.2 && <2.1,         time >=1.2 && <1.13      if flag(dev)@@ -117,7 +118,7 @@         monad-control >=1.0 && <1.1,         mtl >=2.0 && <3.0,         req,-        text >=0.2 && <1.3+        text >=0.2 && <2.1      if flag(dev)         ghc-options: -O0 -Wall -Werror