GithubHelp home page GithubHelp logo

hspec-wai's Introduction

Documentation

Read the User's Manual!

Development

Update API dumps

$ (cd util/api-dump && cabal install)
$ util/dump-api

Prepare a release

$ util/release

or

$ util/release major

This will bump the version and update CHANGES.markdown.

Releases happen automatically when a new version ends up on main.

Whenever .github/workflows/publish.yml detects a new version without a corresponding tag it:

  • creates a tag
  • publishes to Hackage

hspec-wai's People

Contributors

begriffs avatar bodigrim avatar fujimura avatar gregwebs avatar jonplussed avatar maxdaten avatar philonous avatar ryanglscott avatar soenkehahn avatar sol avatar zohl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

hspec-wai's Issues

Test suite failure on GHC 7.6.3

Discovered via Stackage:

Unpacking to hspec-wai-0.3.0.1/
Resolving dependencies...
Configuring hspec-wai-0.3.0.1...
Building hspec-wai-0.3.0.1...
Preprocessing library hspec-wai-0.3.0.1...
[1 of 5] Compiling Test.Hspec.Wai.Util ( src/Test/Hspec/Wai/Util.hs, dist/build/Test/Hspec/Wai/Util.o )
[2 of 5] Compiling Test.Hspec.Wai.Matcher ( src/Test/Hspec/Wai/Matcher.hs, dist/build/Test/Hspec/Wai/Matcher.o )
[3 of 5] Compiling Test.Hspec.Wai.Internal ( src/Test/Hspec/Wai/Internal.hs, dist/build/Test/Hspec/Wai/Internal.o )
[4 of 5] Compiling Test.Hspec.Wai   ( src/Test/Hspec/Wai.hs, dist/build/Test/Hspec/Wai.o )
[5 of 5] Compiling Test.Hspec.Wai.JSON ( src/Test/Hspec/Wai/JSON.hs, dist/build/Test/Hspec/Wai/JSON.o )
In-place registering hspec-wai-0.3.0.1...
Preprocessing test suite 'spec' for hspec-wai-0.3.0.1...
[1 of 1] Compiling Main             ( test/Spec.hs, dist/build/spec/spec-tmp/Main.o )
Linking dist/build/spec/spec ...
Preprocessing test suite 'doctests' for hspec-wai-0.3.0.1...
[1 of 1] Compiling Main             ( test/doctests.hs, dist/build/doctests/doctests-tmp/Main.o )
Linking dist/build/doctests/doctests ...
Preprocessing test suite 'README' for hspec-wai-0.3.0.1...
[1 of 1] Compiling Main             ( README.lhs, dist/build/README/README-tmp/Main.o )
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package array-0.4.0.1 ... linking ... done.
Loading package deepseq-1.3.0.1 ... linking ... done.
Loading package bytestring-0.10.0.2 ... linking ... done.
Loading package containers-0.5.0.0 ... linking ... done.
Loading package text-1.1.1.3 ... linking ... done.
Loading package hashable-1.2.2.0 ... linking ... done.
Loading package scientific-0.3.3.0 ... linking ... done.
Loading package attoparsec-0.12.1.1 ... linking ... done.
Loading package dlist-0.7.1 ... linking ... done.
Loading package transformers-0.3.0.0 ... linking ... done.
Loading package mtl-2.1.3.1 ... linking ... done.
Loading package old-locale-1.0.0.5 ... linking ... done.
Loading package syb-0.4.2 ... linking ... done.
Loading package pretty-1.1.1.0 ... linking ... done.
Loading package template-haskell ... linking ... done.
Loading package time-1.4.0.1 ... linking ... done.
Loading package unordered-containers-0.2.5.0 ... linking ... done.
Loading package primitive-0.5.3.0 ... linking ... done.
Loading package vector-0.10.11.0 ... linking ... done.
Loading package aeson-0.7.0.6 ... linking ... done.
Loading package filepath-1.3.0.1 ... linking ... done.
Loading package unix-2.6.0.1 ... linking ... done.
Loading package directory-1.2.0.1 ... linking ... done.
Loading package old-time-1.1.0.1 ... linking ... done.
Loading package polyparse-1.9 ... linking ... done.
Loading package cpphs-1.18.5 ... linking ... done.
Loading package haskell-src-exts-1.15.0.1 ... linking ... done.
Loading package th-lift-0.6.1 ... linking ... done.
Loading package th-orphans-0.8.1 ... linking ... done.
Loading package haskell-src-meta-0.6.0.7 ... linking ... done.
Loading package parsec-3.1.5 ... linking ... done.
Loading package aeson-qq-0.7.2 ... linking ... done.
Loading package case-insensitive-1.2.0.0 ... linking ... done.
Loading package HUnit-1.2.5.2 ... linking ... done.
Loading package random-1.0.1.3 ... linking ... done.
Loading package tf-random-0.5 ... linking ... done.
Loading package QuickCheck-2.7.6 ... linking ... done.
Loading package ansi-terminal-0.6.1.1 ... linking ... done.
Loading package stm-2.4.3 ... linking ... done.
Loading package async-2.0.1.5 ... linking ... done.
Loading package hspec-expectations-0.6.1 ... linking ... done.
Loading package quickcheck-io-0.1.1 ... linking ... done.
Loading package setenv-0.1.1.1 ... linking ... done.
Loading package hspec2-0.4.1 ... linking ... done.
Loading package blaze-builder-0.3.3.2 ... linking ... done.
Loading package http-types-0.8.5 ... linking ... done.
Loading package network-2.5.0.0 ... linking ... done.
Loading package vault-0.3.0.3 ... linking ... done.
Loading package wai-3.0.1.1 ... linking ... done.
Loading package base64-bytestring-1.0.0.1 ... linking ... done.
Loading package data-default-class-0.0.1 ... linking ... done.
Loading package auto-update-0.1.1.2 ... linking ... done.
Loading package fast-logger-2.2.0 ... linking ... done.
Loading package base-unicode-symbols-0.2.2.4 ... linking ... done.
Loading package transformers-base-0.4.3 ... linking ... done.
Loading package monad-control-0.3.3.0 ... linking ... done.
Loading package lifted-base-0.2.2.1 ... linking ... done.
Loading package exceptions-0.6.1 ... linking ... done.
Loading package mmorph-1.0.4 ... linking ... done.
Loading package resourcet-1.1.2.3 ... linking ... done.
Loading package process-1.1.0.2 ... linking ... done.
Loading package zlib-0.5.4.1 ... linking ... done.
Loading package streaming-commons-0.1.4.2 ... linking ... done.
Loading package stringsearch-0.3.6.5 ... linking ... done.
Loading package nats-0.2 ... linking ... done.
Loading package semigroups-0.15.2 ... linking ... done.
Loading package void-0.6.1 ... linking ... done.
Loading package byteorder-1.0.4 ... linking ... done.
Loading package easy-file-0.2.0 ... linking ... done.
Loading package binary-0.5.1.1 ... linking ... done.
Loading package unix-time-0.3.3 ... linking ... done.
Loading package wai-logger-2.2.3 ... linking ... done.
Loading package word8-0.1.1 ... linking ... done.
Loading package wai-extra-3.0.2.1 ... linking ... done.
Loading package hspec-wai-0.3.0.1 ... linking ... done.
Loading package data-default-instances-base-0.0.1 ... linking ... done.
Loading package data-default-instances-containers-0.0.1 ... linking ... done.
Loading package data-default-instances-dlist-0.0.1 ... linking ... done.
Loading package data-default-instances-old-locale-0.0.1 ... linking ... done.
Loading package data-default-0.5.3 ... linking ... done.
Loading package regex-base-0.93.2 ... linking ... done.
Loading package regex-posix-0.95.2 ... linking ... done.
Loading package regex-compat-0.95.1 ... linking ... done.
Loading package http-date-0.0.4 ... linking ... done.
Loading package simple-sendfile-0.2.17 ... linking ... done.
Loading package unix-compat-0.4.1.3 ... linking ... done.
Loading package warp-3.0.1.1 ... linking ... done.
Loading package scotty-0.9.0 ... linking ... done.
Loading package markdown-unlit-0.2.0.1 ... linking ... done.
Linking dist/build/README/README ...
Building hspec-wai-0.3.0.1...
Preprocessing library hspec-wai-0.3.0.1...
In-place registering hspec-wai-0.3.0.1...
Preprocessing test suite 'spec' for hspec-wai-0.3.0.1...
Preprocessing test suite 'doctests' for hspec-wai-0.3.0.1...
Preprocessing test suite 'README' for hspec-wai-0.3.0.1...
Running 3 test suites...
Test suite spec: RUNNING...


Finished in 0.0002 seconds
0 examples, 0 failures
Test suite spec: PASS
Test suite logged to: dist/test/hspec-wai-0.3.0.1-spec.log
Test suite doctests: RUNNING...

src/Test/Hspec/Wai/Internal.hs:28:42:
    No instance for (MonadIO
                       (transformers-0.3.0.0:Control.Monad.Trans.Reader.ReaderT
                          Application
                          (transformers-0.3.0.0:Control.Monad.Trans.State.Lazy.StateT
                             Network.Wai.Test.ClientState IO)))
      arising from the 'deriving' clause of a data type declaration
    Possible fix:
      add an instance declaration for
      (MonadIO
         (transformers-0.3.0.0:Control.Monad.Trans.Reader.ReaderT
            Application
            (transformers-0.3.0.0:Control.Monad.Trans.State.Lazy.StateT
               Network.Wai.Test.ClientState IO)))
      or use a standalone 'deriving instance' declaration,
           so you can specify the instance context yourself
    When deriving the instance for (MonadIO WaiSession)
Test suite doctests: FAIL
Test suite logged to: dist/test/hspec-wai-0.3.0.1-doctests.log
Test suite README: RUNNING...

GET /
  - responds with 200
  - responds with 'hello'
  - responds with 200 / 'hello'
  - has Content-Type: text/plain

GET /some-json
  - responds with some JSON

Finished in 0.0016 seconds
5 examples, 0 failures
Test suite README: PASS
Test suite logged to: dist/test/hspec-wai-0.3.0.1-README.log
2 of 3 test suites (2 of 3 test cases) passed.

For JSON response matcher, spaces in Content-Type header don't matter

According to RFC 2045, spaces aren't required in Content-Type: application/json; charset=utf-8 - there can be any number of them after the semicolon, including zero. This should be taken into account for the JSON response matcher, as the following headers are valid:

Content-Type: application/json;charset=utf-8 (note that http-media produces this)

Content-Type: application/json; charset=utf-8

Release the new MatchBody?

Hi, I love the changes that have been merged here d84f589

Is there anything I can do to help this get released soon?

If it's just that you're busy I totally understand, and please don't take this as a "hurry up" πŸ˜„

Two test failures

Just encountered these via Stackage:

1) GET / has Content-Type: text/plain
missing header:
  Content-Type: text/plain
the actual headers were:
  Content-Type: text/plain; charset=utf-8


2) GET /some-json responds with some JSON
missing header:
  Content-Type: application/json
the actual headers were:
  Content-Type: application/json; charset=utf-8

POST request helper improvements

It seems the post function helper could be improved. Currently, it's an alias to request methodPost with empty headersβ€” meaning that the parameters POST body not is parsed by WAI.

Since the usual use-case for a POST is with parameters in the body, I think a better helper might have a type like post :: ByteString -> Query -> WaiSession SResponse, where the application/x-www-form-urlencoded content-type header is already provided. A separate helper such as post' could have a type like post :: ByteString -> SimpleQuery -> WaiSession SResponse. Deviations from the usual POST usage would still be free to use the generic request function.

Happy to send a pull request if you believe this is worthwhile!

Testing with session

Hi @sol, When I try to test an API actually needs the session, it will fail since the mock server can not reach the in-memory session. For instance, when testing with this test case, it will produce the error message:

image

Which is defined here, and it proves that the mock app can not reach out to the session when testing it, but it works fine when I start the server and test the API by hand.

Any ideas to fix this? Thanks in advance!

How to use HSpec.Wai with hspec-discover?

I'm trying to use hspec-discover with HSpec.Wai. The top-level spec items in my FooSpec.hs files are of type spec :: SpecWith (st, Application). I want to use my own Main module and driver, so I generate the test suite like this:

{-# OPTIONS_GHC -F -pgmF hspec-discover -optF --module-name=APISpec -optF --no-main #-}

However, hspec-discover generates spec :: Spec in which it tries to run the (st, Application) specs from the test modules.

Is there a way to make hspec-discover generate a spec :: SpecWith (st, Application)? Or do I have to set up my tests differently?

Move Test.Hspec.Wai.JSON into a separate package

Would it be possible to move Test.Hspec.Wai.JSON to a separate package? I think that testing for a specific JSON is useful in some cases, but there are still a lot of WAI Apps that don't need that. And for those installing the dependency aeson-qq (which installs haskell-src-meta; haskell-src-exts) takes very long and is useless...

Expose bodyEquals

It's a bit of a pain maintaining a string value to match a body when I have a data type that I could create and then use Aeson's encode function to check the body. So I think bodyEquals would be extremely useful to use but it's not exposed 😞

Test.Hspec.Wai should shadow lifted Test.Hspec functions

Rather than requiring conflicting imports from both Test.Hspec and Test.Hspec.Wai, Test.Hspec.Wai could export all of Test.Hspec, replacing the functions that need lifting, such as render or shouldBe, with the lifted versions.

This seems unlikely to cause problems, since anybody using both test suites in the same file should probably have them qualified to avoid conflicts even in the current iteration. Will send a pull if going this route sounds worthwhile to you.

Diffs are not colored

Since the failure message is constructed manually, --diff has no effect on the result of matching against a ResponseMatcher.

`post` always returns `415` status

Sorry that I am pretty new to hspec-wai and couldn't find the answer to this problem. Therefore I posted a question here.
I have a POST test case as follows:

it "post /users sample user responds with success msg" $
  post "/users" postBody `shouldRespondWith` "wai"
where postBody = [json|{"name":"wai"}|]

It returns status_code 415, media-type not supported. I tried other ways such as:
post "/users" "" `shouldRespondWith` "wai" although this will fail, I expect it will return error message like 400, not enough input. But still, it return 415
Alternatively

post "/users" (fromValue $ object [ "name" .= "wai" ]) `shouldRespondWith` "wai"

But still returns 415.
In hspec-wai/Wai.hs, I found the post function is post path = request methodPost path [], the headers is an empty list.
Therefore I changed the test case by using request directly

request methodPost "/users" postHeader postBody `shouldRespondWith` "wai"
where postBody = [json|{"name":"wai"}|]
           postHeader = [("Content-Type", "application/json")]

It works. It seems the post func that passes empty headers doesn't work. I need to specify the content-type in the headers. Did I do something wrong?

Documentation for using wai-hspec with other resources

I'd like to use hspec-wai in the following way:

  • create a database before all my tests
  • use that database to construct my wai application
  • around each test, reset the database
  • inside some tests, access the database directly to do some set up that's not supported by my public REST API

I think this is a pretty standard set of things to want to test. However, it's really hard to figure out how to do this with hspec & hspec-wai. I'm cobbling something together now (will post if I finish it), but it has taken a lot of time to figure it out, with a lot of searching down dead ends.

I would really appreciate concrete examples for doing the above. I think they'd make a good addition to the documentation.

Allow to use `hspec-wai` for individual examples

Add

withApplication = flip runWaiSession

so that it can be used for individual examples, like so:

it "serves requests" $ withApplication app $ do
  get "/" `shouldRespondWith` 200

In addition we may want to deprecated runWaiSession.

hspec-wai-0.10.0 build failures on GHC <7.10

For example, when I build hspec-wai-0.10.0 with GHC 7.8.4:

[6 of 6] Compiling Test.Hspec.Wai   ( src/Test/Hspec/Wai.hs, /home/rgscott/Documents/Hacking/Haskell/hspec-wai/dist-newstyle/build/x86_64-linux/ghc-7.8.4/hspec-wai-0.10.0/build/Test/Hspec/Wai.o )

src/Test/Hspec/Wai.hs:62:30:
    Not in scope: β€˜<$>’
    Perhaps you meant β€˜<:>’ (imported from Test.Hspec.Wai.Matcher)

Missing documentation for Test.Hspec.Wai.QuickCheck

I see no example nor test for Test.Hspec.Wai.QuickCheck module, nor usage example.

I used both Test.Hspec.QuickCheck and Test.Hspec.Wai, but it does not seem easy to construct tests just using this knowledge.

Json matcher doesn't accept correct header

I'm trying to test a REST api written in servant. To that end I have a test like this:

get "/users" `shouldRespondWith` [json|[{"name":"bob"}]|]

That test fails with

  1) GET /users responds with [User]
       missing header:
         Content-Type: application/json
       the actual headers were:
         Content-Type: application/json;charset=utf-8

The actual header is compatible with the required one, so this shouldn't fail.

Feature request: partial body matcher

It would be nice if there were a way to match part of the body of a response. Sometimes responses contain random bits that you don't care about testing.

Analyse the response body (instead of expecting an exact value)

Is there a way to get the response body and perform tests on it?

Let's say I get a response body like this:

{
    "results": [42, 12, 66, 73, 59]
}

and all I care about is that there are 5 items in results and they are all Int. I don't care about each individual value.

I could not find any obvious way to achieve this by reading the code.

Support matching json body with non-standard content type

My app uses a vendored mime type (application/vnd.foo.bar+json) in certain responses, so `shouldRespondWith` [json| ... |] fails. I'd rather not fall back to string matches though because then the order of the keys in my json objects matter in the tests. Exposing equalsJSON would let me create my own matcher like:

jsonMatch j =
  ResponseMatcher {
    matchBody    = equalsJSON j
  , matchStatus  = 200
  , matchHeaders = [
      "Content-Type" <:>
      "application/vnd.foo.bar+json; charset=utf-8"
    ]
  }

But maybe you know a more elegant way.

documentation: Add "@since 0.10.0" to "withState" haddock docs?

For users of the library – potentially having to integrate it with other packages, of various versions – it would be handy to be able to see in the Haddock docs when the API has changed. (And thus, if they want to use a newly-introduced function, what version of hspec-wai they'll need to depend on.)

I see withState seems to have been introduced in version 0.10.0. In Haddock docs, this is normally indicated using the @since tag – e.g. @since 0.10.0.

I'd suggest adding @since 0.10.0 to the Haddock documentation for withState. Happy to create a pull request if desired.

Doing a parallel load test

A user discovered a problem in my web server that causes it to freeze under certain types of concurrent traffic. I'm trying to model the situation in a test but having trouble with the types.

import Control.Concurrent.Async (mapConcurrently)
-- ...

context "in parallel, contentiously" $ do
  it "does not crash the server" $ do
    liftIO $ mapConcurrently (
        const . void $ get "/foo"
      ) [1..100]
    get "/bar" `shouldRespondWith` 200

My problem is that once I'm inside of the concurrent map I'm in IO and I don't know how to get back into WaiSession in order to make a get request. Is it possible to do this?

Equivalent of withApplication with app wrapped in IO (e.g. for Scotty)

Hello! Haskell newbie here :) I'm learning how to build a web API in Haskell, and I'm stumbling on figuring out the correct way to test my app. What I want to accomplish is basically to

  1. set some initial app state
  2. make an http call
  3. verify stuff about the response
  4. verify stuff about the state after the request returns

For now, I don't mind if the test runner has to run the entire cycle for each verification, so 3. and 4. could be lumped together into "verify something about the response or the app state after the action".

I've looked at the examples posted in #36 (as well as in a bunch of other places) but I'm only almost getting all the pieces in place to start writing real tests. The problem I'm currently facing is that in #36, the mkApplication is of type Connection -> Application, which seems to follow from the OP there using Servant. I'm using Scotty, where my corresponding function type is MyState -> IO Application, and I can't figure out how to make that IO match up with the stuff around it.

Here's my attempt at defining a Spec:

mkState :: IO (TVar MyState)
mkState = liftIO $ newTVarIO (def :: MyState)

mkApp :: TVar MyState -> IO Network.Wai.Application
mkApp s = scottyAppT (runWithState s) myApp
  where
    -- WebM is defined as here: https://github.com/scotty-web/scotty/blob/master/examples/globalstate.hs
    runWithState :: TVar MyState -> WebM a -> IO a
    runWithState s = \m -> runReaderT (runWebM m) s

spec :: Spec
spec = do
  before mkState $ do
    it "get /" $ \s -> do
      withApplication (mkApp s) $ do 
        Test.Hspec.Wai.pending -- e.g. get "/" `shouldRespondWith` 200
                               -- or do s' <- readTVar s
                                        getStuff s `shouldBe` expectedStuff

The above snippet fails to build because mkApp s is expected to return an Application, but returns an IO Application. I bet I'm missing something fairly trivial, but I haven't been able to figure out what.

Grateful for all help!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.