fakepull: Monad to pull from fake stream-like objects.

[ apache, library, testing ] [ Propose Tags ]

See https://github.com/igrep/haskell-fakepull#readme.

[Skip to Readme]
Versions [faq],
Change log ChangeLog.md
Dependencies base (>=4.7 && <5), exceptions, mtl [details]
License Apache-2.0
Copyright 2020 Yuji Yamamoto
Author YAMAMOTO Yuji
Maintainer whosekiteneverfly@gmail.com
Category Testing
Home page https://github.com/igrep/haskell-fakepull#readme
Bug tracker https://github.com/igrep/haskell-fakepull/issues
Source repo head: git clone https://github.com/igrep/haskell-fakepull
Uploaded by igrep at 2020-09-05T10:04:23Z
Distributions NixOS:
Downloads 56 total (3 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs available [build log]
Last success reported on 2020-09-05 [all 1 reports]


[Index] [Quick Jump]


Maintainer's Corner

For package maintainers and hackage trustees

Readme for fakepull-

[back to package description]


Monad to pull from fake stream-like objects.


Sometimes you might want to test a function that uses an HTTP client object to get responses from some web server, without actually making the HTTP requests.


import Control.Monad.IO.Class
import Data.IORef
import Data.Maybe
import Test.Hspec
import Test.Pull.Fake.IO

data Request = Request
  { searchTerm :: String
  , pageSize :: Int
  , cursor :: Maybe String
  } deriving (Eq, Show)

data Response = Response
  { searchResult :: [String]
  , nextCursor :: Maybe String
  } deriving (Eq, Show)

-- | The function you test.
--   Call `sendRequest` repeatedly to get all paginated search results using
--   the cursor.
fetchAllPages :: MonadIO m => (Request -> m Response) -> String -> m [String]
fetchAllPages sendRequest term = go [] (Request term 3 Nothing)
  go accum req = do
    res <- sendRequest req
    let newAccum = accum ++ searchResult res
    case nextCursor res of
        Just cur -> do
          let newReq = req { cursor = Just cur }
          go newAccum newReq
        Nothing -> return newAccum

-- | The function to make an HTTP request actually. Will be stubbed.
sendRequestActually :: Request -> IO Response
sendRequestActually = error "This function should be stubbed!"

-- | Simulate the `sendRequest` function that returns a different result every
--   time.
stubbedSendRequest :: FakeStream Response -> Request -> IO Response
stubbedSendRequest stream _request =
  -- NOTE: You may want to validate the request argument for testing.
  --       I've omitted that for simplicity here.
  fromJust <$> pull stream

main :: IO ()
main = hspec $
  describe "fetchAllPages" $
    it "collect all results by sending requests" $ do
      let allResponses =
            [ Response ["result 1-1", "result 1-2", "result 1-3"] $ Just "cursor a"
            , Response ["result 2-2", "result 2-2", "result 2-3"] $ Just "cursor b"
            , Response ["result 3-1"] Nothing

      responsesToReturn <- newFakeStream allResponses
      fetchAllPages (stubbedSendRequest responsesToReturn) "result" 
        `shouldReturn` concatMap searchResult allResponses

-- END

Related package

  • fakefs
    • This package is a variant of fakefs for stream-like objects.