doctest 0.22.0 → 0.22.1
raw patch · 30 files changed
+112/−70 lines, 30 filesdep −base-compatPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies removed: base-compat
API changes (from Hackage documentation)
+ Test.DocTest.Internal.Run: [repl] :: Config -> (String, [String])
+ Test.DocTest.Internal.Run: doctestWithRepl :: (String, [String]) -> [String] -> IO ()
- Test.DocTest.Internal.Run: Config :: [String] -> Bool -> Bool -> Bool -> Config
+ Test.DocTest.Internal.Run: Config :: [String] -> Bool -> Bool -> Bool -> (String, [String]) -> Config
Files
- CHANGES.markdown +3/−0
- doctest.cabal +7/−5
- driver/Main.hs +2/−0
- src/GhcUtil.hs +2/−0
- src/Imports.hs +5/−0
- src/Info.hs +3/−1
- src/Interpreter.hs +6/−13
- src/Language/Haskell/GhciWrapper.hs +2/−1
- src/Location.hs +2/−0
- src/Options.hs +6/−5
- src/PackageDBs.hs +2/−0
- src/Parse.hs +2/−0
- src/Property.hs +2/−0
- src/Run.hs +9/−7
- src/Runner/Example.hs +2/−0
- src/Util.hs +3/−0
- test/ExtractSpec.hs +2/−0
- test/InfoSpec.hs +2/−0
- test/InterpreterSpec.hs +8/−8
- test/Language/Haskell/GhciWrapperSpec.hs +2/−0
- test/LocationSpec.hs +2/−0
- test/MainSpec.hs +2/−0
- test/OptionsSpec.hs +3/−3
- test/PackageDBsSpec.hs +2/−3
- test/ParseSpec.hs +2/−0
- test/PropertySpec.hs +22/−19
- test/RunSpec.hs +2/−3
- test/Runner/ExampleSpec.hs +1/−2
- test/RunnerSpec.hs +2/−0
- test/UtilSpec.hs +2/−0
CHANGES.markdown view
@@ -1,3 +1,6 @@+Changes in 0.22.1+ - Add `Test.DocTest.Internal.Run.doctestWithRepl`+ Changes in 0.22.0 - Export more internals
doctest.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.2.+-- This file has been generated from package.yaml by hpack version 0.35.4. -- -- see: https://github.com/sol/hpack name: doctest-version: 0.22.0+version: 0.22.1 synopsis: Test interactive Haskell examples description: `doctest` is a tool that checks [examples](https://www.haskell.org/haddock/doc/html/ch03s08.html#idm140354810775744) and [properties](https://www.haskell.org/haddock/doc/html/ch03s08.html#idm140354810771856)@@ -115,6 +115,7 @@ NamedFieldPuns RecordWildCards DeriveFunctor+ NoImplicitPrelude exposed-modules: Test.DocTest Test.DocTest.Internal.Extract@@ -124,6 +125,7 @@ other-modules: Extract GhcUtil+ Imports Info Interpreter Language.Haskell.GhciWrapper@@ -139,7 +141,6 @@ Paths_doctest build-depends: base >=4.5 && <5- , base-compat >=0.7.0 , code-page >=0.1 , deepseq , directory@@ -163,9 +164,9 @@ NamedFieldPuns RecordWildCards DeriveFunctor+ NoImplicitPrelude build-depends: base >=4.5 && <5- , base-compat >=0.7.0 , code-page >=0.1 , deepseq , directory@@ -198,6 +199,7 @@ UtilSpec Extract GhcUtil+ Imports Info Interpreter Language.Haskell.GhciWrapper@@ -226,6 +228,7 @@ NamedFieldPuns RecordWildCards DeriveFunctor+ NoImplicitPrelude c-sources: test/integration/with-cbits/foo.c build-tool-depends:@@ -234,7 +237,6 @@ HUnit , QuickCheck >=2.13.1 , base >=4.5 && <5- , base-compat >=0.7.0 , code-page >=0.1 , deepseq , directory
driver/Main.hs view
@@ -1,4 +1,6 @@ module Main (main) where++import Prelude import Test.DocTest import System.Environment (getArgs)
src/GhcUtil.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE CPP #-} module GhcUtil (withGhc) where +import Imports+ import GHC.Paths (libdir) import GHC #if __GLASGOW_HASKELL__ < 900
+ src/Imports.hs view
@@ -0,0 +1,5 @@+module Imports (module Imports) where++import Prelude as Imports+import Data.Monoid as Imports+import Control.Monad as Imports
src/Info.hs view
@@ -7,7 +7,9 @@ #endif ) where -import Data.List.Compat+import Imports++import Data.List import System.Process import System.IO.Unsafe
src/Interpreter.hs view
@@ -13,9 +13,10 @@ , filterExpression ) where +import Imports+ import System.Process import System.Directory (getPermissions, executable)-import Control.Monad import Control.Exception hiding (handle) import Data.Char import GHC.Paths (ghc)@@ -38,28 +39,20 @@ maybe False (== "YES") . lookup haveInterpreterKey <$> ghcInfo --- | Run an interpreter session.------ Example:------ >>> withInterpreter [] $ \i -> eval i "23 + 42"--- ...--- "65\n" withInterpreter- :: [String] -- ^ List of flags, passed to GHC+ :: (String, [String]) -> (Interpreter -> IO a) -- ^ Action to run -> IO a -- ^ Result of action-withInterpreter flags action = do+withInterpreter (command, flags) action = do let args = flags ++ [- "--interactive"- , xTemplateHaskell+ xTemplateHaskell #if __GLASGOW_HASKELL__ >= 802 , "-fdiagnostics-color=never" , "-fno-diagnostics-show-caret" #endif ]- bracket (new defaultConfig{configGhci = ghc} args) close action+ bracket (new defaultConfig{configGhci = command} args) close action xTemplateHaskell :: String xTemplateHaskell = "-XTemplateHaskell"
src/Language/Haskell/GhciWrapper.hs view
@@ -9,10 +9,11 @@ , evalEcho ) where +import Imports+ import System.IO hiding (stdin, stdout, stderr) import System.Process import System.Exit-import Control.Monad import Control.Exception import Data.List (isSuffixOf) import Data.Maybe
src/Location.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE CPP #-} module Location where +import Imports+ import Control.DeepSeq (deepseq, NFData(rnf)) #if __GLASGOW_HASKELL__ < 900
src/Options.hs view
@@ -14,16 +14,15 @@ #endif ) where -import Prelude ()-import Prelude.Compat+import Imports import Control.Monad.Trans.RWS (RWS, execRWS) import qualified Control.Monad.Trans.RWS as RWS -import Control.Monad (when)-import Data.List.Compat (stripPrefix)-import Data.Monoid (Endo (Endo))+import Data.List (stripPrefix) +import GHC.Paths (ghc)+ import Info usage :: String@@ -59,6 +58,7 @@ , fastMode :: Bool , preserveIt :: Bool , verbose :: Bool+, repl :: (String, [String]) } deriving (Eq, Show) defaultConfig :: Config@@ -67,6 +67,7 @@ , fastMode = False , preserveIt = False , verbose = False+, repl = (ghc, ["--interactive"]) } nonInteractiveGhcOptions :: [String]
src/PackageDBs.hs view
@@ -8,6 +8,8 @@ #endif ) where +import Imports+ import System.Environment (getEnvironment) import System.FilePath (splitSearchPath, searchPathSeparator)
src/Parse.hs view
@@ -17,6 +17,8 @@ #endif ) where +import Imports+ import Data.Char (isSpace) import Data.List (isPrefixOf, stripPrefix) import Data.Maybe
src/Property.hs view
@@ -8,6 +8,8 @@ #endif ) where +import Imports+ import Data.List import Data.Maybe import Data.Foldable
src/Run.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE CPP #-} module Run ( doctest+, doctestWithRepl , Config(..) , defaultConfig@@ -18,10 +19,8 @@ #endif ) where -import Prelude ()-import Prelude.Compat+import Imports -import Control.Monad import System.Directory (doesFileExist, doesDirectoryExist, getDirectoryContents) import System.Environment (getEnvironment) import System.Exit (exitFailure, exitSuccess)@@ -60,7 +59,10 @@ -- If a directory is given, it is traversed to find all .hs and .lhs files -- inside of it, ignoring hidden entries. doctest :: [String] -> IO ()-doctest args0 = case parseOptions args0 of+doctest = doctestWithRepl (repl defaultConfig)++doctestWithRepl :: (String, [String]) -> [String] -> IO ()+doctestWithRepl repl args0 = case parseOptions args0 of Options.ProxyToGhc args -> rawSystem Interpreter.ghc args >>= E.throwIO Options.Output s -> putStr s Options.Result (Run warnings magicMode config) -> do@@ -79,7 +81,7 @@ packageDBArgs <- getPackageDBArgs addDistArgs <- getAddDistArgs return (addDistArgs $ packageDBArgs ++ expandedArgs)- doctestWith config{ghcOptions = opts}+ doctestWith config{repl, ghcOptions = opts} -- | Expand a reference to a directory to all .hs and .lhs files within it. expandDirs :: String -> IO [String]@@ -155,5 +157,5 @@ runDocTests :: Config -> [Module [Located DocTest]] -> IO Result runDocTests Config{..} modules = do- Interpreter.withInterpreter ghcOptions $ \repl -> withCP65001 $ do- runModules fastMode preserveIt verbose repl modules+ Interpreter.withInterpreter ((<> ghcOptions) <$> repl) $ \ interpreter -> withCP65001 $ do+ runModules fastMode preserveIt verbose interpreter modules
src/Runner/Example.hs view
@@ -3,6 +3,8 @@ , mkResult ) where +import Imports+ import Data.Char import Data.List (isPrefixOf) import Util
src/Util.hs view
@@ -1,4 +1,7 @@ module Util where++import Imports+ import Data.Char convertDosLineEndings :: String -> String
test/ExtractSpec.hs view
@@ -4,6 +4,8 @@ module ExtractSpec (main, spec) where +import Imports+ import Test.Hspec import Test.HUnit
test/InfoSpec.hs view
@@ -1,5 +1,7 @@ module InfoSpec (spec) where +import Imports+ import Test.Hspec import System.Process
test/InterpreterSpec.hs view
@@ -1,14 +1,14 @@-module InterpreterSpec (main, spec) where+module InterpreterSpec (spec) where -import Prelude ()-import Prelude.Compat+import Imports import Test.Hspec -import Interpreter (interpreterSupported, haveInterpreterKey, ghcInfo, withInterpreter, safeEval, filterExpression)+import Interpreter (Interpreter, interpreterSupported, haveInterpreterKey, ghcInfo, ghc, safeEval, filterExpression)+import qualified Interpreter -main :: IO ()-main = hspec spec+withInterpreter :: (Interpreter -> IO a) -> IO a+withInterpreter = Interpreter.withInterpreter (Interpreter.ghc, ["--interactive"]) spec :: Spec spec = do@@ -23,10 +23,10 @@ (||) <$> (== Just "YES") <*> (== Just "NO") describe "safeEval" $ do- it "evaluates an expression" $ withInterpreter [] $ \ghci -> do+ it "evaluates an expression" $ withInterpreter $ \ ghci -> do Interpreter.safeEval ghci "23 + 42" `shouldReturn` Right "65\n" - it "returns Left on unterminated multiline command" $ withInterpreter [] $ \ghci -> do+ it "returns Left on unterminated multiline command" $ withInterpreter $ \ ghci -> do Interpreter.safeEval ghci ":{\n23 + 42" `shouldReturn` Left "unterminated multi-line command" describe "filterExpression" $ do
test/Language/Haskell/GhciWrapperSpec.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE CPP #-} module Language.Haskell.GhciWrapperSpec (main, spec) where +import Imports+ import Test.Hspec import System.IO.Silently
test/LocationSpec.hs view
@@ -2,6 +2,8 @@ module LocationSpec (main, spec) where +import Imports+ import Test.Hspec import Location
test/MainSpec.hs view
@@ -2,6 +2,8 @@ {-# LANGUAGE ConstraintKinds #-} module MainSpec (main, spec) where +import Imports+ import Test.Hspec import Test.HUnit (assertEqual, Assertion)
test/OptionsSpec.hs view
@@ -1,8 +1,8 @@ module OptionsSpec (spec) where -import Prelude ()-import Prelude.Compat-import Data.List.Compat+import Imports++import Data.List import Test.Hspec import Test.QuickCheck hiding (verbose)
test/PackageDBsSpec.hs view
@@ -1,12 +1,11 @@ module PackageDBsSpec (main, spec) where -import Prelude ()-import Prelude.Compat+import Imports import qualified Control.Exception as E import Data.List (intercalate) import PackageDBs-import System.Environment.Compat+import System.Environment import System.FilePath (searchPathSeparator) import Test.Hspec
test/ParseSpec.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE OverloadedStrings #-} module ParseSpec (main, spec) where +import Imports+ import Test.Hspec import Data.String import Data.String.Builder (Builder, build)
test/PropertySpec.hs view
@@ -1,14 +1,17 @@ {-# LANGUAGE OverloadedStrings #-}-module PropertySpec (main, spec) where+module PropertySpec (spec) where +import Imports+ import Test.Hspec import Data.String.Builder import Property-import Interpreter (withInterpreter)+import Interpreter (Interpreter)+import qualified Interpreter -main :: IO ()-main = hspec spec+withInterpreter :: (Interpreter -> IO a) -> IO a+withInterpreter = Interpreter.withInterpreter (Interpreter.ghc, ["--interactive"]) isFailure :: PropertyResult -> Bool isFailure (Failure _) = True@@ -17,54 +20,54 @@ spec :: Spec spec = do describe "runProperty" $ do- it "reports a failing property" $ withInterpreter [] $ \repl -> do+ it "reports a failing property" $ withInterpreter $ \repl -> do runProperty repl "False" `shouldReturn` Failure "*** Failed! Falsified (after 1 test):" - it "runs a Bool property" $ withInterpreter [] $ \repl -> do+ it "runs a Bool property" $ withInterpreter $ \repl -> do runProperty repl "True" `shouldReturn` Success - it "runs a Bool property with an explicit type signature" $ withInterpreter [] $ \repl -> do+ it "runs a Bool property with an explicit type signature" $ withInterpreter $ \repl -> do runProperty repl "True :: Bool" `shouldReturn` Success - it "runs an implicitly quantified property" $ withInterpreter [] $ \repl -> do+ it "runs an implicitly quantified property" $ withInterpreter $ \repl -> do runProperty repl "(reverse . reverse) xs == (xs :: [Int])" `shouldReturn` Success it "runs an implicitly quantified property even with GHC 7.4" $ -- ghc will include a suggestion (did you mean `id` instead of `is`) in -- the error message- withInterpreter [] $ \repl -> do+ withInterpreter $ \repl -> do runProperty repl "foldr (+) 0 is == sum (is :: [Int])" `shouldReturn` Success - it "runs an explicitly quantified property" $ withInterpreter [] $ \repl -> do+ it "runs an explicitly quantified property" $ withInterpreter $ \repl -> do runProperty repl "\\xs -> (reverse . reverse) xs == (xs :: [Int])" `shouldReturn` Success - it "allows to mix implicit and explicit quantification" $ withInterpreter [] $ \repl -> do+ it "allows to mix implicit and explicit quantification" $ withInterpreter $ \repl -> do runProperty repl "\\x -> x + y == y + x" `shouldReturn` Success - it "reports the value for which a property fails" $ withInterpreter [] $ \repl -> do+ it "reports the value for which a property fails" $ withInterpreter $ \repl -> do runProperty repl "x == 23" `shouldReturn` Failure "*** Failed! Falsified (after 1 test):\n0" - it "reports the values for which a property that takes multiple arguments fails" $ withInterpreter [] $ \repl -> do+ it "reports the values for which a property that takes multiple arguments fails" $ withInterpreter $ \repl -> do let vals x = case x of (Failure r) -> tail (lines r); _ -> error "Property did not fail!" vals `fmap` runProperty repl "x == True && y == 10 && z == \"foo\"" `shouldReturn` ["False", "0", show ("" :: String)] - it "defaults ambiguous type variables to Integer" $ withInterpreter [] $ \repl -> do+ it "defaults ambiguous type variables to Integer" $ withInterpreter $ \repl -> do runProperty repl "reverse xs == xs" >>= (`shouldSatisfy` isFailure) describe "freeVariables" $ do- it "finds a free variables in a term" $ withInterpreter [] $ \repl -> do+ it "finds a free variables in a term" $ withInterpreter $ \repl -> do freeVariables repl "x" `shouldReturn` ["x"] - it "ignores duplicates" $ withInterpreter [] $ \repl -> do+ it "ignores duplicates" $ withInterpreter $ \repl -> do freeVariables repl "x == x" `shouldReturn` ["x"] - it "works for terms with multiple names" $ withInterpreter [] $ \repl -> do+ it "works for terms with multiple names" $ withInterpreter $ \repl -> do freeVariables repl "\\z -> x + y + z == foo 23" `shouldReturn` ["x", "y", "foo"] - it "works for names that contain a prime" $ withInterpreter [] $ \repl -> do+ it "works for names that contain a prime" $ withInterpreter $ \repl -> do freeVariables repl "x' == y''" `shouldReturn` ["x'", "y''"] - it "works for names that are similar to other names that are in scope" $ withInterpreter [] $ \repl -> do+ it "works for names that are similar to other names that are in scope" $ withInterpreter $ \repl -> do freeVariables repl "length_" `shouldReturn` ["length_"] describe "parseNotInScope" $ do
test/RunSpec.hs view
@@ -1,8 +1,7 @@ {-# LANGUAGE CPP #-} module RunSpec (main, spec) where -import Prelude ()-import Prelude.Compat+import Imports import Test.Hspec import System.Exit@@ -10,7 +9,7 @@ import qualified Control.Exception as E import System.FilePath import System.Directory (getCurrentDirectory, setCurrentDirectory)-import Data.List.Compat (isPrefixOf, sort)+import Data.List (isPrefixOf, sort) import Data.Char import System.IO.Silently
test/Runner/ExampleSpec.hs view
@@ -1,8 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} module Runner.ExampleSpec (main, spec) where -import Prelude ()-import Prelude.Compat+import Imports import Data.String import Test.Hspec
test/RunnerSpec.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE CPP, OverloadedStrings #-} module RunnerSpec (main, spec) where +import Imports+ import Test.Hspec import System.IO
test/UtilSpec.hs view
@@ -1,5 +1,7 @@ module UtilSpec (main, spec) where +import Imports+ import Test.Hspec import Util