packages feed

doctest 0.20.1 → 0.21.0

raw patch · 9 files changed

+94/−76 lines, 9 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

CHANGES.markdown view
@@ -1,3 +1,6 @@+Changes in 0.21.0+  - Accept `--fast`, `--preserve-it` and `--verbose` via `--repl-options`+ Changes in 0.20.1   - GHC 9.4 compatibility. (#382) 
README.md view
@@ -10,7 +10,8 @@ * [Getting started](#getting-started)    * [Installation](#installation)    * [A basic example](#a-basic-example)-   * [Running doctest for a Cabal package](#running-doctest-for-a-cabal-package)+* [Running doctest for a Cabal package](#running-doctest-for-a-cabal-package)+   * [Passing doctest options to cabal repl](#passing-doctest-options-to-cabal-repl) * [Writing examples and properties](#writing-examples-and-properties)    * [Example groups](#example-groups)       * [A note on performance](#a-note-on-performance)@@ -91,7 +92,7 @@ ```  -## Running `doctest` for a Cabal package+# Running `doctest` for a Cabal package  The easiest way to run `doctest` for a Cabal package is via `cabal repl --with-ghc=doctest`. @@ -134,6 +135,7 @@ - `doctest` always uses the version of GHC it was compiled with.  Reinstalling   `doctest` with `cabal install doctest --overwrite-policy=always` before each   invocation ensures that it uses the same version of GHC as is on the `PATH`.+ - Technically, `cabal build` is not necessary. `cabal repl --with-ghc=doctest`   will build any dependencies as needed.  However, it's more robust to run   `cabal build` first (specifically it is not a good idea to build@@ -147,7 +149,29 @@  (This is what you want to use on CI.) +## Passing `doctest` options to `cabal repl` +You can pass `doctest` options like `--fast`, `--preserve-it` and `--verbose` to+`cabal repl` via `--repl-options`.++Example:++```+$ cabal repl --with-ghc=doctest --repl-options=--verbose+### Started execution at src/Fib.hs:7.+### example:+fib 10+### Successful!++### Started execution at src/Fib.hs:10.+### example:+fib 5+### Successful!++# Final summary:+Examples: 2  Tried: 2  Errors: 0  Failures: 0+```+ # Writing examples and properties  ## Example groups@@ -185,7 +209,7 @@ (With the caveat that the order in which groups appear now matters!)  However, note that due to a-[bug on GHC 8.2.1 or later](https://ghc.haskell.org/trac/ghc/ticket/14052),+[bug on GHC 8.2.1 or later](https://gitlab.haskell.org/ghc/ghc/-/issues/14052), the performance of `--fast` suffers significantly when combined with the `--preserve-it` flag (which keeps the value of GHCi's `it` value between examples).
doctest.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.0.+-- This file has been generated from package.yaml by hpack version 0.35.1. -- -- see: https://github.com/sol/hpack  name:           doctest-version:        0.20.1+version:        0.21.0 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)
ghci-wrapper/src/Language/Haskell/GhciWrapper.hs view
@@ -43,14 +43,18 @@ itMarker = "d42472243a0e6fc481e7514cbc9eb08812ed48daa29ca815844d86010b1d113a"  data Interpreter = Interpreter {-    hIn  :: Handle-  , hOut :: Handle-  , process :: ProcessHandle-  }+  hIn  :: Handle+, hOut :: Handle+, process :: ProcessHandle+}  new :: Config -> [String] -> IO Interpreter new Config{..} args_ = do-  (Just stdin_, Just stdout_, Nothing, processHandle ) <- createProcess $ (proc configGhci args) {std_in = CreatePipe, std_out = CreatePipe, std_err = Inherit}+  (Just stdin_, Just stdout_, Nothing, processHandle ) <- createProcess (proc configGhci args) {+    std_in  = CreatePipe+  , std_out = CreatePipe+  , std_err = Inherit+  }   setMode stdin_   setMode stdout_   let interpreter = Interpreter {hIn = stdin_, hOut = stdout_, process = processHandle}@@ -134,7 +138,7 @@     echo :: String -> IO ()     echo       | echoMode = putStr-      | otherwise = (const $ return ())+      | otherwise = \ _ -> return ()  -- | Evaluate an expression eval :: Interpreter -> String -> IO String
src/Options.hs view
@@ -3,12 +3,9 @@ module Options (   Result(..) , Run(..)-, defaultMagic-, defaultFastMode-, defaultPreserveIt-, defaultVerbose , parseOptions #ifdef TEST+, defaultRun , usage , info , versionInfo@@ -72,26 +69,14 @@   , "--abi-hash"   ] -defaultMagic :: Bool-defaultMagic = True--defaultFastMode :: Bool-defaultFastMode = False--defaultPreserveIt :: Bool-defaultPreserveIt = False--defaultVerbose :: Bool-defaultVerbose = False- defaultRun :: Run defaultRun = Run {   runWarnings = [] , runOptions = []-, runMagicMode = defaultMagic-, runFastMode = defaultFastMode-, runPreserveIt = defaultPreserveIt-, runVerbose = defaultVerbose+, runMagicMode = False+, runFastMode = False+, runPreserveIt = False+, runVerbose = False }  modifyWarnings :: ([String] -> [String]) -> Run -> Run@@ -114,51 +99,41 @@  parseOptions :: [String] -> Result Run parseOptions args-  | "--info" `elem` args = Output info-  | "--interactive" `elem` args = Result Run {-        runWarnings = []-      , runOptions = filter (/= "--interactive") args-      , runMagicMode = False-      , runFastMode = False-      , runPreserveIt = False-      , runVerbose = False-      }-  | any (`elem` nonInteractiveGhcOptions) args = RunGhc args-  | "--help" `elem` args = Output usage-  | "--version" `elem` args = Output versionInfo-  | otherwise = case execRWS parse () args of-      (xs, Endo setter) ->-        Result (setOptions xs $ setter defaultRun)-    where-      parse :: RWS () (Endo Run) [String] ()-      parse = do-        stripNoMagic-        stripFast-        stripPreserveIt-        stripVerbose-        stripOptGhc--stripNoMagic :: RWS () (Endo Run) [String] ()-stripNoMagic = stripFlag (setMagicMode False) "--no-magic"+  | on "--info" = Output info+  | on "--interactive" = runRunOptionsParser (discard "--interactive" args) defaultRun $ do+      commonRunOptions+  | on `any` nonInteractiveGhcOptions = RunGhc args+  | on "--help" = Output usage+  | on "--version" = Output versionInfo+  | otherwise = runRunOptionsParser args defaultRun {runMagicMode = True} $ do+      commonRunOptions+      parseFlag "--no-magic" (setMagicMode False)+      parseOptGhc+  where+    on option = option `elem` args -stripFast :: RWS () (Endo Run) [String] ()-stripFast = stripFlag (setFastMode True) "--fast"+type RunOptionsParser = RWS () (Endo Run) [String] () -stripPreserveIt :: RWS () (Endo Run) [String] ()-stripPreserveIt = stripFlag (setPreserveIt True) "--preserve-it"+runRunOptionsParser :: [String] -> Run -> RunOptionsParser -> Result Run+runRunOptionsParser args def parse = case execRWS parse () args of+  (xs, Endo setter) ->+    Result (setOptions xs $ setter def) -stripVerbose :: RWS () (Endo Run) [String] ()-stripVerbose = stripFlag (setVerbose True) "--verbose"+commonRunOptions :: RunOptionsParser+commonRunOptions = do+  parseFlag "--fast" (setFastMode True)+  parseFlag "--preserve-it" (setPreserveIt True)+  parseFlag "--verbose" (setVerbose True) -stripFlag :: (Run -> Run) -> String -> RWS () (Endo Run) [String] ()-stripFlag setter flag = do+parseFlag :: String -> (Run -> Run) -> RunOptionsParser+parseFlag flag setter = do   args <- RWS.get   when (flag `elem` args) $     RWS.tell (Endo setter)-  RWS.put (filter (/= flag) args)+  RWS.put (discard flag args) -stripOptGhc :: RWS () (Endo Run) [String] ()-stripOptGhc = do+parseOptGhc :: RunOptionsParser+parseOptGhc = do   issueWarning <- RWS.state go   when issueWarning $     RWS.tell $ Endo $ modifyWarnings (++ [warning])@@ -169,3 +144,6 @@       opt : rest -> maybe (fmap (opt :)) (\x (_, xs) -> (True, x : xs)) (stripPrefix "--optghc=" opt) (go rest)      warning = "WARNING: --optghc is deprecated, doctest now accepts arbitrary GHC options\ndirectly."++discard :: String -> [String] -> [String]+discard flag = filter (/= flag)
src/Runner.hs view
@@ -129,7 +129,7 @@     reload = do       unless fastMode $         -- NOTE: It is important to do the :reload first! See-        -- https://ghc.haskell.org/trac/ghc/ticket/5904, which results in a+        -- https://gitlab.haskell.org/ghc/ghc/-/issues/5904, which results in a         -- panic on GHC 7.4.1 if you do the :reload second.         void $ Interpreter.safeEval repl ":reload"       void $ Interpreter.safeEval repl $ ":m *" ++ module_
test/MainSpec.hs view
@@ -8,7 +8,6 @@ import           Control.Exception import           System.Directory (getCurrentDirectory, setCurrentDirectory) import           System.FilePath-import           Options import           Runner (Summary(..)) import           Run hiding (doctest) import           System.IO.Silently@@ -22,11 +21,11 @@  -- | Construct a doctest specific 'Assertion'. doctest :: HasCallStack => FilePath -> [String] -> Summary -> Assertion-doctest = doctestWithPreserveIt defaultPreserveIt+doctest = doctestWithPreserveIt False  doctestWithPreserveIt :: HasCallStack => Bool -> FilePath -> [String] -> Summary -> Assertion doctestWithPreserveIt preserveIt workingDir args expected = do-  actual <- withCurrentDirectory ("test/integration" </> workingDir) (hSilence [stderr] $ doctestWithOptions defaultFastMode preserveIt defaultVerbose args)+  actual <- withCurrentDirectory ("test/integration" </> workingDir) (hSilence [stderr] $ doctestWithOptions False preserveIt False args)   assertEqual label expected actual   where     label = workingDir ++ " " ++ show args
test/OptionsSpec.hs view
@@ -18,12 +18,19 @@ spec :: Spec spec = do   describe "parseOptions" $ do-    let warning = ["WARNING: --optghc is deprecated, doctest now accepts arbitrary GHC options\ndirectly."]+    let+      run :: [String] -> Run+      run options = defaultRun {+        runWarnings = ["WARNING: --optghc is deprecated, doctest now accepts arbitrary GHC options\ndirectly."]+      , runOptions = options+      , runMagicMode = True+      }+     it "strips --optghc" $-      parseOptions ["--optghc", "foobar"] `shouldBe` Result (Run warning ["foobar"] defaultMagic defaultFastMode defaultPreserveIt defaultVerbose)+      parseOptions ["--optghc", "foobar"] `shouldBe` Result (run ["foobar"])      it "strips --optghc=" $-      parseOptions ["--optghc=foobar"] `shouldBe` Result (Run warning ["foobar"] defaultMagic defaultFastMode defaultPreserveIt defaultVerbose)+      parseOptions ["--optghc=foobar"] `shouldBe` Result (run ["foobar"])      context "with ghc options that are not valid with --interactive" $ do       it "returns RunGhc" $ do@@ -39,6 +46,9 @@        it "filters out --interactive" $ do         runOptions <$> parseOptions options `shouldBe` Result ["--foo", "--bar"]++      it "accepts --fast" $ do+        runFastMode <$> parseOptions ("--fast" : options) `shouldBe` Result True      describe "--no-magic" $ do       context "without --no-magic" $ do
test/RunSpec.hs view
@@ -20,7 +20,7 @@ import           Run  doctestWithDefaultOptions :: [String] -> IO Summary-doctestWithDefaultOptions = doctestWithOptions Options.defaultFastMode Options.defaultPreserveIt Options.defaultVerbose+doctestWithDefaultOptions = doctestWithOptions False False False  withCurrentDirectory :: FilePath -> IO a -> IO a withCurrentDirectory workingDir action = do