hspec-expectations-lens

Hspec expectations for the lens stuff http://supki.github.io/hspec-expectations-lens/

Latest on Hackage:0.4.0

This package is not currently in any snapshots. If you're interested in using it, we recommend adding it to Stackage Nightly. Doing so will make builds more reliable, and allow stackage.org to host generated Haddocks.

BSD2 licensed by Matvey Aksenov
hspec-expectations-lens
=======================

hspec-expectations-lens is a set of expectations for [Hspec][hspec]
with a [lens][lens]-compatible interface

This README is a literate haskell file which contains a Hspec spec.
You can run it with `runhaskell`; result is something akin to:


```shell
% runhaskell README.lhs

shouldHave
- checks targets exist
- looks as deep into structure as you want
- replaces 'shouldBe'
- checks a bigger part of the structure for equality
- checks the whole structure for equality

shouldNotHave
- is the opposite of 'shouldHave'

shouldView
- gets a single target verbatim
- combines multiple targets using Monoid instance

shouldList
- combines multiple targets into list

shouldPreview
- gets the first target

shouldPerform
- performs an action and gets the first target

shouldThrow
- looks into the 'error' call
- looks into the division by zero
```

Expectations
------------

We start with pragmas, module declaration, and imports we use later.

> {-# LANGUAGE ExtendedDefaultRules #-} -- this is only neccessary because we don't like annotations
>
> module Main (main) where
>
> import Control.Lens
> import Control.Exception (evaluate)
> import Control.Exception.Lens (_ErrorCall, _DivideByZero)
> import Test.Hspec.Lens
>
> main :: IO ()
> main = hspec $ do

hspec-expectations-lens expectations form several groups. First one contains `shouldHave`
and `shouldNotHave` combinators—they check whether a `Fold` you give them has (or doesn't have)
any targets in the structure.

> describe "shouldHave" $ do
> it "checks targets exist" $
> Right (Just (Left 'a')) `shouldHave` _Right

We can look arbitrarily deep into the structure; for instance, `_Right._Just._Left`
would also work here:

> it "looks as deep into structure as you want" $
> Right (Just (Left 'a')) `shouldHave` _Right._Just

Finally, `shouldHave` can happily be used as a replacement for a vanilla `shouldBe`.

> it "replaces 'shouldBe'" $
> Right (Just (Left 'a')) `shouldHave` _Right._Just._Left.only 'a'
>
> it "checks a bigger part of the structure for equality" $
> Right (Just (Left 'a')) `shouldHave` _Right._Just.only (Left 'a')
>
> it "checks the whole structure for equality" $
> Right (Just (Left 'a')) `shouldHave` only (Right (Just (Left 'a')))

`shouldNotHave` is the opposite of `shouldHave` as its name implies, it checks
whether a `Fold` does not have any targets in the structure.

> describe "shouldNotHave" $
> it "is the opposite of 'shouldHave'" $
> Right (Just (Left 'a')) `shouldNotHave` _Left

Next group of expectations is those of them that actually care about the result
of looking into the structure. It consists of `shouldView`, `shouldPreview`,
`shouldList`, and `shouldPerform`. They derive names from `view`, `preview`, `toListOf`,
and `perform` `combinators from the lens package.

`shouldView` works similarly to `view`, no big surprises here. If a `Fold` is actually
a `Getter`, you just get its target:

> describe "shouldView" $ do
> it "gets a single target verbatim" $
> (1, (((1, 7), 8), 2, (3, 4), 5, 7)) `shouldView` 7 `through` _2._1._1._2

(`through` is just a fancy name for `id`; it helps to avoid parentheses)

Otherwise, if `Fold` has multiple targets, they are combined using `Monoid` instance
for the target type (and it better have one):

> it "combines multiple targets using Monoid instance" $
> [("foo", 1), ("bar", 2), ("baz", 3)] `shouldView` "foobarbaz" `through` folded._1

`shouldList` is like `toListOf`, that is, it combines its targets into the list:

> describe "shouldList" $
> it "combines multiple targets into list" $
> [("foo", 1), ("bar", 2), ("baz", 3)] `shouldList` [1, 2, 3] `through` folded._2

`shouldPreview` is like `preview` in that it only cares about the first target:

> describe "shouldPreview" $
> it "gets the first target" $
> [1..10] `shouldPreview` 10 `through` reversed.folded

The last combinator, which does not really belong to any of the previous groups,
is `shouldThrow`. It uses composable selectors to determine which
exception was thrown:

> describe "shouldThrow" $ do
> it "looks into the 'error' call" $
> error "foo" `shouldThrow` _ErrorCall.only "foo"
>
> it "looks into the division by zero" $
> evaluate (1 `div` 0) `shouldThrow` _DivideByZero

[hspec]: http://hspec.github.io/
[lens]: https://github.com/ekmett/lens/

Changes

0.4.0

  • Reflect API changes in lens-4.7

0.3.0.0

  • Update to lens-4.0

0.2.1.1

  • Maintenance: Upper bound on lens

0.2.1.0

  • Add a shouldPerform expectation
  • Improve expectations' error messages

0.2.0.0

  • Add a shouldThrow expectation, a lensy variant of shouldThrow

  • Add a Test.Hspec.Lens module, re-exporting Test.Hspec with Test.Hspec.Expectations.Lens expectations

  • More documentation with fake type signatures

0.1.0.0

  • shouldHave, shouldNotHave, shouldView, shouldPreview, and shouldList
Used by 1 package:
comments powered byDisqus