cabal-doctest
A Setup.hs helper for doctests running
https://github.com/phadej/cabal-doctest
| Version on this page: | 1.0.8@rev:1 |
| LTS Haskell 24.17: | 1.0.11 |
| Stackage Nightly 2025-10-30: | 1.0.11 |
| Latest on Hackage: | 1.0.11 |
cabal-doctest-1.0.8@sha256:34dff6369d417df2699af4e15f06bc181d495eca9c51efde173deae2053c197c,1491Module documentation for 1.0.8
- Distribution
- Distribution.Extra
cabal-doctest
A Setup.hs helper for running doctests.
Simple example
For most use cases—a .cabal file with a single library containing
doctests—adapting the simple example located
here
will be sufficient. (Note that this example requires Cabal-1.24 or later, but
you can relax this bound safely, although running doctests won’t be supported
on versions of Cabal older than 1.24.)
To use this library in your Setup.hs, you should specify a custom-setup
section in your .cabal file. For example:
custom-setup
setup-depends:
base >= 4 && <5,
Cabal,
cabal-doctest >= 1 && <1.1
/Note:/ Cabal dependency is needed because of
Cabal/GH-4288 bug.
You’ll also need to specify build-type: Custom at the top of the .cabal
file. Now put this into your Setup.hs file:
module Main where
import Distribution.Extra.Doctest (defaultMainWithDoctests)
main :: IO ()
main = defaultMainWithDoctests "doctests"
When you build your project, this Setup will generate a Build_doctests
module. To use it in a testsuite, simply do this:
module Main where
import Build_doctests (flags, pkgs, module_sources)
import Data.Foldable (traverse_)
import System.Environment.Compat (unsetEnv)
import Test.DocTest (doctest)
main :: IO ()
main = do
traverse_ putStrLn args -- optionally print arguments
unsetEnv "GHC_ENVIRONMENT" -- see 'Notes'; you may not need this
doctest args
where
args = flags ++ pkgs ++ module_sources
(The System.Environment.Compat module is from the base-compat
package. That’s already in the transitive closure of doctest‘s
dependencies. System.Environment.unsetEnv was added with GHC 7.8 so,
if you don’t need to support versions of GHC older than 7.8, you can
use System.Environment from base instead.)
Example with multiple .cabal components
cabal-doctest also supports more exotic use cases where a .cabal file
contains more components with doctests than just the main library, including:
- Doctests in executables
- Doctests in Internal libraries (if using
Cabal-2.0or later)
Unlike the simple example shown above, these examples involve named
components. You don’t need to change the Setup.hs script to support
this use case. However, in this scenario Build_doctests will generate extra
copies of the flags, pkgs, and module_sources values for each additional
named component.
Simplest approach is to use x-doctest-components field, for example
x-doctest-components: lib lib:internal exe:example
In that case, the testdrive is general:
module Main where
import Build_doctests (Component (..), components)
import Data.Foldable (for_)
import System.Environment.Compat (unsetEnv)
import Test.DocTest (doctest)
main :: IO ()
main = for_ components $ \(Component name flags pkgs sources) -> do
print name
putStrLn "----------------------------------------"
let args = flags ++ pkgs ++ sources
for_ args putStrLn
unsetEnv "GHC_ENVIRONMENT"
doctest args
There’s also a more explicit approach: if you have an executable named foo,
then separate values named flags_exe_foo, pkgs_exe_foo, and module_sources_exe_foo will
be generated in Build_doctests. If the name has hyphens in it
(e.g., my-exe), then cabal-doctest will convert those hyphens to
underscores (e.g., you’d get flags_my_exe, pkgs_my_exe, and
module_sources_my_exe).
Internal library bar values will have a _lib_bar suffix.
An example testsuite driver for this use case might look like this:
module Main where
import Build_doctests
(flags, pkgs, module_sources,
flags_exe_my_exe, pkgs_exe_my_exe, module_sources_exe_my_exe)
import Data.Foldable (traverse_)
import System.Environment.Compat (unsetEnv)
import Test.DocTest
main :: IO ()
main = do
unsetEnv "GHC_ENVRIONMENT"
-- doctests for library
traverse_ putStrLn libArgs
doctest libArgs
-- doctests for executable
traverse_ putStrLn exeArgs
doctest exeArgs
where
libArgs = flags ++ pkgs ++ module_sources
exeArgs = flags_exe_my_exe ++ pkgs_exe_my_exe ++ module_sources_exe_my_exe
See this example for more details.
Additional configuration
The cabal-doctest based Setup.hs supports few extensions fields
in pkg.cabal files to customise the doctest runner behaviour, without
customising the default doctest.hs.
test-suite doctests:
if impl(ghc >= 8.0)
x-doctest-options: -fdiagnostics-color=never
x-doctest-source-dirs: test
x-doctest-modules: Servant.Utils.LinksSpec
...
x-doctest-optionsAdditional arguments passed intodoctestcommand.x-doctest-modulesAdditional modules todoctest. May be useful if you havedoctestin test or executables (i.e not default library complonent).x-doctest-src-dirsAdditional source directories to look for the modules.
Notes
-
Recent versions of
Cabal(for instance, 2.0) can choose to build a package’sdoctesttest suite before the library. However, in order forcabal-doctestto work correctly, the library must be built first, asdoctestrelies on the presence of generated files that are only created when the library is built. See #19.A hacky workaround for this problem is to depend on the library itself in a
docteststest suite. See the simple example’s .cabal file for a demonstration. (This assumes that the test suite has the ability to read build artifacts from the library, a separate build component. In practice, this assumption holds, which is why this library works at all.) -
custom-setupsection is supported starting fromcabal-install-1.24. For oldercabal-install'syou have to install custom setup dependencies manually. -
stackrespectscustom-setupstarting from version 1.3.3. Before that you have to useexplicit-setup-depssetting in yourstack.yaml. (stack/GH-2094) -
There is an issue in the Cabal issue tracker about adding
cabal doctestcommand. After that command is implemented, this library will be deprecated. -
You can use
x-doctest-optionsfield intest-suite docteststo pass additional flags to thedoctest. -
For
build-type: Configurepackages, you can usedefaultMainAutoconfWithDoctestsfunction to make customSetup.hsscript. -
If you use the default
.inhs-source-dirs, then runningdoctestsmight fail with weird errors (ambiguous module errors). Workaround is to move sources undersrc/or some non-top-level directory. -
extensions:field isn’t supported. Upgrade your.cabalfile to use at leastcabal-version: >= 1.10and usedefault-extensionsorother-extensions. -
If you use QuickCheck properties (
prop>) in your doctests, thetest-suite doctestshould depend onQuickCheckandtemplate-haskell. This is a little HACK: These dependencies aren’t needed to build thedocteststest-suite executable. However, as we letCabalresolve dependencies, we can pass the resolved (and installed!) package identifiers to to thedoctestcommand. This way,QuickCheckandtemplate-haskellare available todoctest, otherwise you’ll get errors like:
Variable not in scope:
mkName
:: [Char]
-> template-haskell-2.11.1.0:Language.Haskell.TH.Syntax.Name
or
Variable not in scope:
polyQuickCheck
:: Language.Haskell.TH.Syntax.Name -> Language.Haskell.TH.Lib.ExpQ
-
From version 2, Stack sets the
GHC_ENVRIONMENTvariable, and GHC (as invoked bydoctest) will pick that up. This is undesirable:cabal-doctestpasses all the necessary information on the command line already, and can lead to ambiguous module errors as GHC will load the environment in addition to whatcabal-doctestinstructs it to.Hence,
cabal-doctesttells GHC to ignore package environments altogether on the command line. However, this is only possible since GHC 8.2. If you are usingcabal-doctestwith Stack 2 and GHC 8.0 or earlier and seeing ambiguous module errors or other mysterious failures, try manually unsettingGHC_ENVIRONMENTbefore invokingdoctest.
Copyright
Copyright 2017 Oleg Grenrus.
Available under the BSD 3-clause license.
Changes
1.0.8 – 2019-10-02
- Pass
-package-env=-when compiler supports it - Amend examples to
unsetEnv "GHC_ENVIRONMENT"
1.0.7 – 2019-08-26
- Make
Distribution.Extra.Doctest-Wall-clean - Support GHC-8.8, base-4.13, and Cabal-3.0
1.0.6 – 2018-01-28
- Hook
haddockbuild too. Fixes issue whenhaddockfails, asBuild_doctestsisn’t generated.
1.0.5 – 2018-01-26
- Add a hack so
Build_doctestsmodule is automatically added to toother-modulesandautogen-moduleswhen compiled with Cabal-2.0. Thanks to that, we don’t get warnings because of-Wmissing-home-modules.
1.0.4 – 2017-12-05
- Add support for doctests in executables and (with
Cabal-2.0or later) internal libraries. Refer to theREADMEfor more details.
1.0.3 – 2017-11-02
- Add an explicit
Preludeimport toBuild_doctests
1.0.2 – 2017-05-16
-
Add
defaultMainAutoconfWithDoctestsandaddDoctestsUserHook. -
Add support for
.hscand other preprocessed files (#8) -
Add support for
x-doctest-source-dirsandx-doctest-modules.
1.0.1 – 2017-05-05
-
Add support for
x-doctest-optionscabal-file field -
Proper support for GHC-8.2.1 & Cabal-2.0.0.0
-
Add support to
default-extensionsin library.
1 – 2017-01-31
- First version. Released on an unsuspecting world.