guard-haskell
Guard::Haskell
automatically runs your specs
Install
% cabal install hspec
% gem install guard-haskell
Usage
How does it work?
For explanation what guard
is and how to use it, please refer to the guard manual
guard-haskell
uses hspec
to run specs and check results, so it makes
some assumptions about your code organization and style:
hspec
is your testing framework of choice; therefore,hspec-discover
organizes your specs
When you type guard
in the terminal, guard-haskell
fires up a cabal repl
instance
to talk to, running (parts of) examples when files are modified.
Guard::Haskell setup
For guard-haskell
to be ready to work we need a test suite named "spec" (that's
configurable, any test suite name will do) defined in the cabal file and a Guardfile
(which you can get by running guard init haskell
)
Guardfile examples
A typical haskell project:
guard :haskell do
watch(%r{test/.+Spec\.l?hs$})
watch(%r{src/.+\.l?hs$})
watch(%r{\.cabal$})
end
A customized haskell project:
= ["--ghc-options=-ignore-dot-ghci -DTEST"]
guard :haskell, all_on_start: true, repl_options: do
watch(%r{test/.+Spec\.l?hs$})
watch(%r{lib/.+\.l?hs$})
watch(%r{bin/.+\.l?hs$})
watch(%r{\.cabal$})
end
Another customized haskell project:
guard :haskell, all_on_start: true, all_on_pass: true, cabal_target: "not-spec" do
watch(%r{test/.+Spec\.l?hs$})
watch(%r{lib/.+\.l?hs$})
watch(%r{bin/.+\.l?hs$})
watch(%r{\.cabal$})
end
Gemfile
It's also advised to have a trivial Gemfile
in the repository for
bundler exec guard
to be able to pick the correct versions of the dependencies:
source "https://rubygems.org"
gem "guard-haskell", "~>2.0"
Options
Guard::Haskell
has a bunch of options:
all_on_start
Run all examples on start (default: false
).
all_on_pass
Run all examples when a failed spec passes again (default: false
).
focus_on_fail
Rerun only failed examples until they pass (default: true
).
repl_options
Pass custom cabal repl options (default: []
).
cabal_target
The cabal build target to load (default: spec
).
Known problems
App you test uses the GHC API
Unfortunately, testing such applications with guard-haskell
is basically impossible
because ghci
uses GHC API
too. Sooner or later you will see something like:
GHCi runtime linker: fatal error: I found a duplicate definition for symbol
HUnitzm1zi2zi5zi2_TestziHUnitziBase_zdwzdcshowsPrec_slow
whilst processing object file
/home/maksenov/.cabal/lib/HUnit-1.2.5.2/ghc-7.6.2/HSHUnit-1.2.5.2.o
This could be caused by:
* Loading two different object files which export the same symbol
* Specifying the same object file twice on the GHCi command line
* An incorrect `package.conf' entry, causing some object to be
loaded twice.
GHCi cannot safely continue in this situation. Exiting now. Sorry.
Fragile concurrent access is a known limitation of the GHC API
, which hopefully will be eventually fixed.