doctest 0.17 → 0.18
raw patch · 14 files changed
+60/−242 lines, 14 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGES +4/−0
- README.markdown +1/−1
- doctest.cabal +5/−8
- ghci-wrapper/src/Language/Haskell/GhciWrapper.hs +7/−7
- src/PackageDBs.hs +6/−23
- src/Sandbox.hs +0/−87
- test/MainSpec.hs +9/−0
- test/PackageDBsSpec.hs +6/−38
- test/RunSpec.hs +1/−34
- test/SandboxSpec.hs +0/−18
- test/integration/local-stderr-binding/A.hs +11/−0
- test/integration/system-io-imported/A.hs +10/−0
- test/sandbox/bad.config +0/−1
- test/sandbox/cabal.sandbox.config +0/−25
CHANGES view
@@ -1,3 +1,7 @@+Changes in 0.18+ - Don't use unqualified references to `stderr` or `stdout` which may collide with definitions in user code. (#201)+ - Remove support for cabal-install sandboxes. They have been obsoleted in practice by Nix-style builds in cabal-install (i.e., the `v2-*` commands) and stack.+ Changes in 0.17 - #266: - doctest now annotates its internal marker string as a `String`, to prevent misbehaviour in `OverloadedStrings` environments. This has a theoretical chance of breakage; if you're affected, please open an issue.
README.markdown view
@@ -67,7 +67,7 @@ haddock -h Fib.hs -o doc/ `doctest` will fail on comments that `haddock` also doesn't like.-Sometimes (e.g., (https://github.com/sol/doctest/issues/251)[#251]), this means that `doctest` will fail on input that GHC accepts.+Sometimes (e.g., [#251](https://github.com/sol/doctest/issues/251)), this means that `doctest` will fail on input that GHC accepts. `doctest` likes UTF-8. If you are running it with, e.g., `LC_ALL=C`, you may need to invoke `doctest` with `LC_ALL=C.UTF-8`.
doctest.cabal view
@@ -4,13 +4,13 @@ -- -- see: https://github.com/sol/hpack ----- hash: 6671c3bec33afff6873246f7b4a0f0b525135af9e29d05ba1a45d528979511ac+-- hash: a5f986d148ee2304fff5f9d670fcb819b4c821e8f1c9f43497020870a53475ef name: doctest-version: 0.17+version: 0.18 synopsis: Test interactive Haskell examples description: The doctest program checks examples in source code comments. It is modeled- after doctest for Python (<http://docs.python.org/library/doctest.html>).+ after doctest for Python (<https://docs.python.org/3/library/doctest.html>). . Documentation is at <https://github.com/sol/doctest#readme>. category: Testing@@ -71,6 +71,7 @@ test/integration/failing/Foo.hs test/integration/it/Foo.hs test/integration/it/Setup.hs+ test/integration/local-stderr-binding/A.hs test/integration/multiline/Multiline.hs test/integration/parse-error/Foo.hs test/integration/property-bool-with-type-signature/Foo.hs@@ -81,6 +82,7 @@ test/integration/property-setup/Foo.hs test/integration/setup-skip-on-failure/Foo.hs test/integration/setup/Foo.hs+ test/integration/system-io-imported/A.hs test/integration/template-haskell-bugfix/Main.hs test/integration/template-haskell-bugfix/Printf.hs test/integration/template-haskell/Foo.hs@@ -98,8 +100,6 @@ test/integration/trailing-whitespace/Foo.hs test/integration/with-cbits/Bar.hs test/integration/with-cbits/foo.c- test/sandbox/bad.config- test/sandbox/cabal.sandbox.config CHANGES README.markdown @@ -126,7 +126,6 @@ Run Runner Runner.Example- Sandbox Util Language.Haskell.GhciWrapper Paths_doctest@@ -202,7 +201,6 @@ Runner.ExampleSpec RunnerSpec RunSpec- SandboxSpec UtilSpec Extract GhcUtil@@ -215,7 +213,6 @@ Run Runner Runner.Example- Sandbox Test.DocTest Util Language.Haskell.GhciWrapper
ghci-wrapper/src/Language/Haskell/GhciWrapper.hs view
@@ -54,20 +54,20 @@ setMode stdin_ setMode stdout_ let interpreter = Interpreter {hIn = stdin_, hOut = stdout_, process = processHandle}- _ <- eval interpreter "import System.IO"- _ <- eval interpreter "import GHC.IO.Handle"+ _ <- eval interpreter "import qualified System.IO"+ _ <- eval interpreter "import qualified GHC.IO.Handle" -- The buffering of stdout and stderr is NoBuffering- _ <- eval interpreter "hDuplicateTo stdout stderr"+ _ <- eval interpreter "GHC.IO.Handle.hDuplicateTo System.IO.stdout System.IO.stderr" -- Now the buffering of stderr is BlockBuffering Nothing -- In this situation, GHC 7.7 does not flush the buffer even when -- error happens.- _ <- eval interpreter "hSetBuffering stdout LineBuffering"- _ <- eval interpreter "hSetBuffering stderr LineBuffering"+ _ <- eval interpreter "GHC.IO.Handle.hSetBuffering System.IO.stdout GHC.IO.Handle.LineBuffering"+ _ <- eval interpreter "GHC.IO.Handle.hSetBuffering System.IO.stderr GHC.IO.Handle.LineBuffering" -- this is required on systems that don't use utf8 as default encoding (e.g. -- Windows)- _ <- eval interpreter "hSetEncoding stdout utf8"- _ <- eval interpreter "hSetEncoding stderr utf8"+ _ <- eval interpreter "GHC.IO.Handle.hSetEncoding System.IO.stdout GHC.IO.Handle.utf8"+ _ <- eval interpreter "GHC.IO.Handle.hSetEncoding System.IO.stderr GHC.IO.Handle.utf8" _ <- eval interpreter ":m - System.IO" _ <- eval interpreter ":m - GHC.IO.Handle"
src/PackageDBs.hs view
@@ -12,9 +12,6 @@ import System.Environment (getEnvironment) import System.FilePath (splitSearchPath, searchPathSeparator)-import qualified Sandbox-import Control.Exception (try, SomeException)-import System.Directory (getCurrentDirectory) -- | Full stack of GHC package databases data PackageDBs = PackageDBs@@ -55,30 +52,16 @@ buildArgStyle = Pre76 #endif --- | Determine the PackageDBs based on the environment and cabal sandbox--- information+-- | Determine the PackageDBs based on the environment. getPackageDBsFromEnv :: IO PackageDBs getPackageDBsFromEnv = do env <- getEnvironment- case () of+ return $ case () of ()- | Just sandboxes <- lookup "HASKELL_PACKAGE_SANDBOXES" env- -> return $ fromEnvMulti sandboxes- | Just extra <- lookup "HASKELL_PACKAGE_SANDBOX" env- -> return PackageDBs- { includeUser = True- , includeGlobal = True- , extraDBs = [extra]- }- | Just sandboxes <- lookup "GHC_PACKAGE_PATH" env- -> return $ fromEnvMulti sandboxes- | otherwise -> do- eres <- try $ getCurrentDirectory- >>= Sandbox.getSandboxConfigFile- >>= Sandbox.getPackageDbDir- return $ case eres :: Either SomeException FilePath of- Left _ -> PackageDBs True True []- Right db -> PackageDBs False True [db]+ | Just packageDBs <- lookup "GHC_PACKAGE_PATH" env+ -> fromEnvMulti packageDBs+ | otherwise+ -> PackageDBs True True [] where fromEnvMulti s = PackageDBs { includeUser = False
− src/Sandbox.hs
@@ -1,87 +0,0 @@-{-# LANGUAGE CPP, BangPatterns #-}--module Sandbox- ( getSandboxArguments- , getPackageDbDir- , getSandboxConfigFile- ) where--#if __GLASGOW_HASKELL__ < 710-import Data.Functor ((<$>))-#endif-import Control.Exception as E (catch, SomeException, throwIO)-import Data.Char (isSpace)-import Data.List (isPrefixOf, tails)-import System.Directory (getCurrentDirectory, doesFileExist)-import System.FilePath ((</>), takeDirectory, takeFileName)--configFile :: String-configFile = "cabal.sandbox.config"--pkgDbKey :: String-pkgDbKey = "package-db:"--pkgDbKeyLen :: Int-pkgDbKeyLen = length pkgDbKey--getSandboxArguments :: IO [String]-getSandboxArguments = (sandboxArguments <$> getPkgDb) `E.catch` handler- where- getPkgDb = getCurrentDirectory >>= getSandboxConfigFile >>= getPackageDbDir- handler :: SomeException -> IO [String]- handler _ = return []---- | Find a sandbox config file by tracing ancestor directories.--- Exception is thrown if not found-getSandboxConfigFile :: FilePath -> IO FilePath-getSandboxConfigFile dir = do- let cfile = dir </> configFile- exist <- doesFileExist cfile- if exist then- return cfile- else do- let dir' = takeDirectory dir- if dir == dir' then- throwIO $ userError "sandbox config file not found"- else- getSandboxConfigFile dir'---- | Extract a package db directory from the sandbox config file.--- Exception is thrown if the sandbox config file is broken.-getPackageDbDir :: FilePath -> IO FilePath-getPackageDbDir sconf = do- -- Be strict to ensure that an error can be caught.- !path <- extractValue . parse <$> readFile sconf- return path- where- parse = head . filter ("package-db:" `isPrefixOf`) . lines- extractValue = fst . break isSpace . dropWhile isSpace . drop pkgDbKeyLen---- | Adding necessary GHC options to the package db.--- Exception is thrown if the string argument is incorrect.------ >>> sandboxArguments "/foo/bar/i386-osx-ghc-7.6.3-packages.conf.d"--- ["-no-user-package-db","-package-db","/foo/bar/i386-osx-ghc-7.6.3-packages.conf.d"]--- >>> sandboxArguments "/foo/bar/i386-osx-ghc-7.4.1-packages.conf.d"--- ["-no-user-package-conf","-package-conf","/foo/bar/i386-osx-ghc-7.4.1-packages.conf.d"]-sandboxArguments :: FilePath -> [String]-sandboxArguments pkgDb = [noUserPkgDbOpt, pkgDbOpt, pkgDb]- where- ver = extractGhcVer pkgDb- (pkgDbOpt,noUserPkgDbOpt)- | ver < 706 = ("-package-conf","-no-user-package-conf")- | otherwise = ("-package-db", "-no-user-package-db")---- | Extracting GHC version from the path of package db.--- Exception is thrown if the string argument is incorrect.------ >>> extractGhcVer "/foo/bar/i386-osx-ghc-7.6.3-packages.conf.d"--- 706-extractGhcVer :: String -> Int-extractGhcVer dir = ver- where- file = takeFileName dir- findVer = drop 4 . head . filter ("ghc-" `isPrefixOf`) . tails- (verStr1,_:left) = break (== '.') $ findVer file- (verStr2,_) = break (== '.') left- ver = read verStr1 * 100 + read verStr2
test/MainSpec.hs view
@@ -167,3 +167,12 @@ it "template-haskell-bugfix" $ do doctest "template-haskell-bugfix" ["Main.hs"] (cases 2)++ it "doesn't clash with user bindings of stdout/stderr" $ do+ doctest "local-stderr-binding" ["A.hs"]+ (cases 1)++ it "doesn't get confused by doctests using System.IO imports" $ do+ doctest "system-io-imported" ["A.hs"]+ (cases 1)+
test/PackageDBsSpec.hs view
@@ -6,7 +6,6 @@ import qualified Control.Exception as E import Data.List (intercalate) import PackageDBs-import System.Directory (getCurrentDirectory, setCurrentDirectory) import System.Environment.Compat import System.FilePath (searchPathSeparator) import Test.Hspec@@ -16,12 +15,6 @@ main :: IO () main = hspec spec -withCurrentDirectory :: FilePath -> IO a -> IO a-withCurrentDirectory workingDir action = do- E.bracket getCurrentDirectory setCurrentDirectory $ \_ -> do- setCurrentDirectory workingDir- action- withEnv :: String -> String -> IO a -> IO a withEnv k v action = E.bracket save restore $ \_ -> do setEnv k v >> action@@ -32,8 +25,6 @@ clearEnv :: IO a -> IO a clearEnv = withEnv "GHC_PACKAGE_PATH" ""- . withEnv "HASKELL_PACKAGE_SANDBOX" ""- . withEnv "HASKELL_PACKAGE_SANDBOXES" "" combineDirs :: [FilePath] -> String combineDirs = intercalate [searchPathSeparator]@@ -41,33 +32,10 @@ spec :: Spec spec = around_ clearEnv $ do describe "getPackageDBsFromEnv" $ do- context "without a cabal sandbox present" $ do- around_ (inTempDirectory) $ do- it "uses global and user when no env or sandboxing used" $ do- getPackageDBsFromEnv `shouldReturn` PackageDBs True True []-- it "respects GHC_PACKAGE_PATH" $- withEnv "GHC_PACKAGE_PATH" (combineDirs ["foo", "bar", ""]) $ do- getPackageDBsFromEnv `shouldReturn` PackageDBs False True ["foo", "bar"]-- it "HASKELL_PACKAGE_SANDBOXES trumps GHC_PACKAGE_PATH" $- withEnv "GHC_PACKAGE_PATH" (combineDirs ["foo1", "bar1", ""]) $ do- withEnv "HASKELL_PACKAGE_SANDBOXES" (combineDirs ["foo2", "bar2", ""]) $ do- getPackageDBsFromEnv `shouldReturn` PackageDBs False True ["foo2", "bar2"]-- it "HASKELL_PACKAGE_SANDBOX trumps GHC_PACKAGE_PATH" $- withEnv "GHC_PACKAGE_PATH" (combineDirs ["foo1", "bar1", ""]) $ do- withEnv "HASKELL_PACKAGE_SANDBOX" (combineDirs ["foo2"]) $ do-- getPackageDBsFromEnv `shouldReturn` PackageDBs True True ["foo2"]-- context "with a cabal sandbox present" $ do- around_ (withCurrentDirectory "test/sandbox") $ do- it "respects cabal sandboxes" $ do- getPackageDBsFromEnv `shouldReturn`- PackageDBs False True ["/home/me/doctest-haskell/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d"]+ around_ (inTempDirectory) $ do+ it "uses global and user when no env used" $ do+ getPackageDBsFromEnv `shouldReturn` PackageDBs True True [] - it "GHC_PACKAGE_PATH takes precedence" $- withEnv "GHC_PACKAGE_PATH" (combineDirs ["foo", "bar"]) $ do- getPackageDBsFromEnv `shouldReturn`- PackageDBs False False ["foo", "bar"]+ it "respects GHC_PACKAGE_PATH" $+ withEnv "GHC_PACKAGE_PATH" (combineDirs ["foo", "bar", ""]) $ do+ getPackageDBsFromEnv `shouldReturn` PackageDBs False True ["foo", "bar"]
test/RunSpec.hs view
@@ -8,16 +8,9 @@ import System.Exit import qualified Control.Exception as E-#if __GLASGOW_HASKELL__ < 707-import System.Cmd-#else-import System.Process-#endif-import System.Directory (getCurrentDirectory, setCurrentDirectory, removeDirectoryRecursive)+import System.Directory (getCurrentDirectory, setCurrentDirectory) import Data.List.Compat -import System.Environment.Compat- import System.IO.Silently import System.IO (stderr) import qualified Options@@ -33,16 +26,6 @@ setCurrentDirectory workingDir action -rmDir :: FilePath -> IO ()-rmDir dir = removeDirectoryRecursive dir `E.catch` (const $ return () :: E.IOException -> IO ())--withEnv :: String -> String -> IO a -> IO a-withEnv k v action = E.bracket save restore $ \_ -> do- setEnv k v >> action- where- save = lookup k <$> getEnvironment- restore = maybe (unsetEnv k) (setEnv k)- main :: IO () main = hspec spec @@ -80,22 +63,6 @@ "doctest: unrecognized option `--foo'" , "Try `doctest --help' for more information." ]-- it "respects HASKELL_PACKAGE_SANDBOX" $ do- withCurrentDirectory "test/integration/custom-package-conf/foo" $ do- ExitSuccess <- rawSystem "ghc-pkg" ["init", "../packages"]- ExitSuccess <- rawSystem "cabal" ["v1-configure", "--disable-optimization", "--disable-library-profiling", "--package-db=../packages"]- ExitSuccess <- rawSystem "cabal" ["v1-build"]- ExitSuccess <- rawSystem "cabal" ["v1-register", "--inplace"]- return ()-- withEnv "HASKELL_PACKAGE_SANDBOX" "test/integration/custom-package-conf/packages" $ do- hCapture_ [stderr] (doctest ["test/integration/custom-package-conf/Bar.hs"])- `shouldReturn` "Examples: 2 Tried: 2 Errors: 0 Failures: 0\n"-- `E.finally` do- rmDir "test/integration/custom-package-conf/packages/"- rmDir "test/integration/custom-package-conf/foo/dist/" it "prints verbose description of a specification" $ do (r, ()) <- hCapture [stderr] $ doctest ["--verbose", "test/integration/testSimple/Fib.hs"]
− test/SandboxSpec.hs
@@ -1,18 +0,0 @@-module SandboxSpec where--import Test.Hspec--import Sandbox--main :: IO ()-main = hspec spec--spec :: Spec-spec = do- describe "getPackageDbDir" $ do- it "parses a config file and extracts package db" $ do- pkgDb <- getPackageDbDir "test/sandbox/cabal.sandbox.config"- pkgDb `shouldBe` "/home/me/doctest-haskell/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d"-- it "throws an error if a config file is broken" $ do- getPackageDbDir "test/sandbox/bad.config" `shouldThrow` anyException
+ test/integration/local-stderr-binding/A.hs view
@@ -0,0 +1,11 @@+module A where++stderr :: Bool+stderr = True++stdout :: String+stdout = "hello"++-- |+-- >>> 3 + 3+-- 6
+ test/integration/system-io-imported/A.hs view
@@ -0,0 +1,10 @@+module A where++import System.IO++-- ghci-wrapper needs to poke around with System.IO itself, and unloads the module once it's done. Test to make sure legitimate uses of System.IO don't get lost in the wash.++-- |+-- >>> ReadMode+-- ReadMode+
− test/sandbox/bad.config
@@ -1,1 +0,0 @@-broken
− test/sandbox/cabal.sandbox.config
@@ -1,25 +0,0 @@--- This is a Cabal package environment file.--- THIS FILE IS AUTO-GENERATED. DO NOT EDIT DIRECTLY.--- Please create a 'cabal.config' file in the same directory--- if you want to change the default settings for this sandbox.---local-repo: /home/me/doctest-haskell/.cabal-sandbox/packages-logs-dir: /home/me/doctest-haskell/.cabal-sandbox/logs-world-file: /home/me/doctest-haskell/.cabal-sandbox/world-user-install: False-package-db: /home/me/doctest-haskell/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d-build-summary: /home/me/doctest-haskell/.cabal-sandbox/logs/build.log--install-dirs - prefix: /home/me/doctest-haskell/.cabal-sandbox- bindir: $prefix/bin- libdir: $prefix/lib- libsubdir: $arch-$os-$compiler/$pkgid- libexecdir: $prefix/libexec- datadir: $prefix/share- datasubdir: $arch-$os-$compiler/$pkgid- docdir: $datadir/doc/$arch-$os-$compiler/$pkgid- htmldir: $docdir/html- haddockdir: $htmldir- sysconfdir: $prefix/etc