doctest icon indicating copy to clipboard operation
doctest copied to clipboard

doctest can't find mkName even after running with stack and adding th/qc to test-suite build-deps

Open unhammer opened this issue 4 years ago • 4 comments

I've started getting this:

src/Foo.hs:603: failure in expression `not . null . parseFoo'

<interactive>:76:19: error:
    • Variable not in scope:
        mkName
          :: [Char]
             -> template-haskell-2.14.0.0:Language.Haskell.TH.Syntax.Name
    • Perhaps you meant one of these:
        ‘gmName’ (imported from FooCalc),
        ‘fName’ (imported from FooEntities)

on running $ stack exec doctest -- src/Foo.hs.

I have added template-haskell and QuickCheck to the test-suite deps as mentioned elsewhere

test-suite foo-doctests
  default-language:   Haskell2010
  type:               exitcode-stdio-1.0
  ghc-options:        -threaded
  hs-source-dirs:     test
  main-is:            Doctest.hs
  build-depends:      base >4 && <5
                    , doctest
                    , semigroups       >=0.18.2
                    , Foolib
                    , QuickCheck
                    , template-haskell >= 2.14

but that made no difference.

When I tried adding import "template-haskell" Language.Haskell.TH (mkName) to $setup, I got

              Ambiguous module name ‘Language.Haskell.TH’:
it was found in multiple packages:
ghc-lib-parser-8.8.0.20190424 template-haskell-2.14.0.0  

I'm not sure why I have ghc-lib-parser in my ghc-pkg list, but shouldn't that package be hidden from doctests anyway? stack dot --include-base --external |grep ghc-lib gives no hits, nor does stack dot --include-base --external --test |grep ghc-lib.

I can workaround by putting >>> :set -XPackageImports and >>> import "template-haskell" Language.Haskell.TH (mkName) in $setup, but it seems like it shouldn't be necessary.

unhammer avatar Feb 14 '20 14:02 unhammer

How are you invoking doctest in your test suite, and are you using cabal-doctest? It looks to me like it's not using the right package database or something similar.

quasicomputational avatar Mar 25 '20 10:03 quasicomputational

I experienced this problem when running with:

cabal exec cabal test package:doctest

The problem exists in a production codebase and I can't get it to reproduce in a small test case.

As a hack, I can work around the problem with:

-- $setup
-- >>> :set -XPackageImports
-- >>> import "template-haskell" Language.Haskell.TH

TomMD avatar Mar 25 '20 15:03 TomMD

How are you invoking doctest in your test suite, and are you using cabal-doctest? It looks to me like it's not using the right package database or something similar.

As I wrote above, this happens with simply stack exec doctest. It also happens when it's run through stack test, where the Doctest.hs just does main = doctest ["Foo.hs"]. I thought stack was supposed to pick the right package database? In any case, the initial error message doesn't seem to have anything to do package databases, but with not even trying to import mkName.

unhammer avatar Mar 25 '20 19:03 unhammer

stack exec doctest just invokes doctest - which knows exactly nothing about .cabal files (or package.yaml). So, just because template-haskell is a dependency of the foo-doctests component, it doesn't meant that invoking the doctest binary like that will be pointed at a package database with template-haskell in it; the actual gory details, and whether it works by accident anyway, depend on just how stack exec works. Similarly, that Doctest.hs doesn't have package database information plumbed in, so it can't expect to be using one that'll work (but might anyway).

On the other hand, you're right: if package database confusion was the problem, I would expect it to be failing at import time, not use time. That's quite mysterious indeed.

Do you have a project where it'll happen reliably and I can poke around and see what's getting passed where?

quasicomputational avatar Mar 27 '20 11:03 quasicomputational