hspec-core 2.10.4 → 2.10.5
raw patch · 17 files changed
+214/−42 lines, 17 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Test.Hspec.Core.Runner: [configFailOnEmpty] :: Config -> Bool
+ Test.Hspec.Core.Runner: registerDefaultFormatter :: (String, FormatConfig -> IO Format) -> Config -> Config
+ Test.Hspec.Core.Runner: registerFormatter :: (String, FormatConfig -> IO Format) -> Config -> Config
- Test.Hspec.Core.Runner: Config :: Bool -> Bool -> Bool -> Bool -> Bool -> Maybe Int -> Bool -> Bool -> Bool -> Maybe FilePath -> Bool -> Bool -> Maybe (Path -> Bool) -> Maybe (Path -> Bool) -> Maybe Integer -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> ColorMode -> UnicodeMode -> Bool -> Bool -> (Bool -> String -> String -> (String, String)) -> Bool -> [(String, FormatConfig -> IO Format)] -> Maybe (FormatConfig -> IO Format) -> Maybe Formatter -> Bool -> Maybe Int -> Config
+ Test.Hspec.Core.Runner: Config :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe Int -> Bool -> Bool -> Bool -> Maybe FilePath -> Bool -> Bool -> Maybe (Path -> Bool) -> Maybe (Path -> Bool) -> Maybe Integer -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> ColorMode -> UnicodeMode -> Bool -> Bool -> (Bool -> String -> String -> (String, String)) -> Bool -> [(String, FormatConfig -> IO Format)] -> Maybe (FormatConfig -> IO Format) -> Maybe Formatter -> Bool -> Maybe Int -> Config
Files
- help.txt +4/−3
- hspec-core.cabal +2/−1
- src/Test/Hspec/Core/Compat.hs +1/−0
- src/Test/Hspec/Core/Config/Definition.hs +66/−7
- src/Test/Hspec/Core/Formatters.hs +3/−1
- src/Test/Hspec/Core/Formatters/Pretty.hs +0/−1
- src/Test/Hspec/Core/Runner.hs +17/−5
- src/Test/Hspec/Core/Runner/Result.hs +3/−3
- src/Test/Hspec/Core/Spec/Monad.hs +0/−1
- src/Test/Hspec/Core/Util.hs +5/−3
- test/Test/Hspec/Core/Config/DefinitionSpec.hs +13/−3
- test/Test/Hspec/Core/Config/OptionsSpec.hs +35/−6
- test/Test/Hspec/Core/HooksSpec.hs +0/−1
- test/Test/Hspec/Core/Runner/ResultSpec.hs +36/−0
- test/Test/Hspec/Core/RunnerSpec.hs +20/−6
- test/Test/Hspec/Core/UtilSpec.hs +8/−0
- version.yaml +1/−1
help.txt view
@@ -11,9 +11,10 @@ anything --[no-]focused-only do not run anything, unless there are focused spec items- --[no-]fail-on-focused fail on focused spec items- --[no-]fail-on-pending fail on pending spec items- --[no-]strict enable --fail-on-focused and --fail-on-pending+ --[no-]fail-on=ITEMS empty: fail if no spec items have been run+ focused: fail on focused spec items+ pending: fail on pending spec items+ --[no-]strict same as --fail-on=empty,focused,pending --[no-]fail-fast abort on first failure --[no-]randomize randomize execution order -r --rerun rerun all examples that failed in the previous
hspec-core.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: hspec-core-version: 2.10.4+version: 2.10.5 license: MIT license-file: LICENSE copyright: (c) 2011-2022 Simon Hengel,@@ -208,6 +208,7 @@ Test.Hspec.Core.QuickCheckUtilSpec Test.Hspec.Core.Runner.EvalSpec Test.Hspec.Core.Runner.PrintSlowSpecItemsSpec+ Test.Hspec.Core.Runner.ResultSpec Test.Hspec.Core.RunnerSpec Test.Hspec.Core.ShuffleSpec Test.Hspec.Core.SpecSpec
src/Test/Hspec/Core/Compat.hs view
@@ -4,6 +4,7 @@ , module Test.Hspec.Core.Compat ) where +import Control.Arrow as Imports ((>>>), (&&&), first, second) import Control.Applicative as Imports import Control.Monad as Imports hiding ( mapM
src/Test/Hspec/Core/Config/Definition.hs view
@@ -13,7 +13,7 @@ , runnerOptions #ifdef TEST-, formatOrList+, splitOn #endif ) where @@ -40,6 +40,7 @@ configIgnoreConfigFile :: Bool , configDryRun :: Bool , configFocusedOnly :: Bool+, configFailOnEmpty :: Bool , configFailOnFocused :: Bool , configFailOnPending :: Bool , configPrintSlowItems :: Maybe Int@@ -79,6 +80,7 @@ configIgnoreConfigFile = False , configDryRun = False , configFocusedOnly = False+, configFailOnEmpty = False , configFailOnFocused = False , configFailOnPending = False , configPrintSlowItems = Nothing@@ -229,15 +231,46 @@ setSeed :: Integer -> Config -> Config setSeed n c = c {configQuickCheckSeed = Just n} +data FailOn =+ FailOnEmpty+ | FailOnFocused+ | FailOnPending+ deriving (Bounded, Enum)++allFailOnItems :: [FailOn]+allFailOnItems = [minBound .. maxBound]++showFailOn :: FailOn -> String+showFailOn item = case item of+ FailOnEmpty -> "empty"+ FailOnFocused -> "focused"+ FailOnPending -> "pending"++readFailOn :: String -> Maybe FailOn+readFailOn = (`lookup` items)+ where+ items = map (showFailOn &&& id) allFailOnItems++splitOn :: Char -> String -> [String]+splitOn sep = go+ where+ go xs = case break (== sep) xs of+ ("", "") -> []+ (y, "") -> [y]+ (y, _ : ys) -> y : go ys+ runnerOptions :: [Option Config] runnerOptions = [ mkFlag "dry-run" setDryRun "pretend that everything passed; don't verify anything" , mkFlag "focused-only" setFocusedOnly "do not run anything, unless there are focused spec items" - , mkFlag "fail-on-focused" setFailOnFocused "fail on focused spec items"- , mkFlag "fail-on-pending" setFailOnPending "fail on pending spec items"- , mkFlag "strict" setStrict "enable --fail-on-focused and --fail-on-pending"+ , undocumented $ mkFlag "fail-on-focused" setFailOnFocused "fail on focused spec items"+ , undocumented $ mkFlag "fail-on-pending" setFailOnPending "fail on pending spec items" + , mkOption "fail-on" Nothing (argument "ITEMS" readFailOnItems (setFailOnItems True )) helpForFailOn+ , mkOption "no-fail-on" Nothing (argument "ITEMS" readFailOnItems (setFailOnItems False)) helpForFailOn+ , mkFlag "strict" setStrict $ "same as --fail-on=" <> showFailOnItems strict+ , mkFlag "fail-fast" setFailFast "abort on first failure" , mkFlag "randomize" setRandomize "randomize execution order" , mkOptionNoArg "rerun" (Just 'r') setRerun "rerun all examples that failed in the previous test run (only works in combination with --failure-report or in GHCi)"@@ -246,6 +279,31 @@ , mkOption "jobs" (Just 'j') (argument "N" readMaxJobs setMaxJobs) "run at most N parallelizable tests simultaneously (default: number of available processors)" ] where+ strict = allFailOnItems++ readFailOnItems :: String -> Maybe [FailOn]+ readFailOnItems = mapM readFailOn . splitOn ','++ showFailOnItems :: [FailOn] -> String+ showFailOnItems = intercalate "," . map showFailOn++ helpForFailOn :: String+ helpForFailOn = unlines . flip map allFailOnItems $ \ item ->+ showFailOn item <> ": " <> help item+ where+ help item = case item of+ FailOnEmpty -> "fail if no spec items have been run"+ FailOnFocused -> "fail on focused spec items"+ FailOnPending -> "fail on pending spec items"++ setFailOnItems :: Bool -> [FailOn] -> Config -> Config+ setFailOnItems value = flip $ foldr (`setItem` value)+ where+ setItem item = case item of+ FailOnEmpty -> setFailOnEmpty+ FailOnFocused -> setFailOnFocused+ FailOnPending -> setFailOnPending+ readMaxJobs :: String -> Maybe Int readMaxJobs s = do n <- readMaybe s@@ -264,6 +322,9 @@ setFocusedOnly :: Bool -> Config -> Config setFocusedOnly value config = config {configFocusedOnly = value} + setFailOnEmpty :: Bool -> Config -> Config+ setFailOnEmpty value config = config {configFailOnEmpty = value}+ setFailOnFocused :: Bool -> Config -> Config setFailOnFocused value config = config {configFailOnFocused = value} @@ -271,9 +332,7 @@ setFailOnPending value config = config {configFailOnPending = value} setStrict :: Bool -> Config -> Config- setStrict value =- setFailOnFocused value- . setFailOnPending value+ setStrict = (`setFailOnItems` strict) setFailFast :: Bool -> Config -> Config setFailFast value config = config {configFailFast = value}
src/Test/Hspec/Core/Formatters.hs view
@@ -1,4 +1,6 @@+-- |+-- Deprecated\: Use "Test.Hspec.Core.Formatters.V1" instead. module Test.Hspec.Core.Formatters-{-# DEPRECATED "Use \"Test.Hspec.Core.Formatters.V1\" instead." #-}+-- {-# DEPRECATED "Use \"Test.Hspec.Core.Formatters.V1\" instead." #-} (module V1) where import Test.Hspec.Core.Formatters.V1 as V1
src/Test/Hspec/Core/Formatters/Pretty.hs view
@@ -11,7 +11,6 @@ import Prelude () import Test.Hspec.Core.Compat hiding (shows, intercalate) -import Control.Arrow import Data.Char import Data.String import Data.List (intersperse)
src/Test/Hspec/Core/Runner.hs view
@@ -40,6 +40,8 @@ , UnicodeMode(..) , Path , defaultConfig+, registerFormatter+, registerDefaultFormatter , configAddFilter , readConfig @@ -88,7 +90,6 @@ import System.IO import System.Environment (getArgs, withArgs) import System.Exit-import Control.Arrow import qualified Control.Exception as E import System.Random import Control.Monad.ST@@ -100,7 +101,7 @@ import Test.Hspec.Core.Util (Path) import Test.Hspec.Core.Spec hiding (pruneTree, pruneForest) import Test.Hspec.Core.Config-import Test.Hspec.Core.Format (FormatConfig(..))+import Test.Hspec.Core.Format (Format, FormatConfig(..)) import qualified Test.Hspec.Core.Formatters.V1 as V1 import qualified Test.Hspec.Core.Formatters.V2 as V2 import Test.Hspec.Core.FailureReport@@ -112,6 +113,16 @@ import qualified Test.Hspec.Core.Runner.Eval as Eval import Test.Hspec.Core.Runner.Result +-- |+-- Make a formatter available for use with @--format@.+registerFormatter :: (String, FormatConfig -> IO Format) -> Config -> Config+registerFormatter formatter config = config { configAvailableFormatters = formatter : configAvailableFormatters config }++-- |+-- Make a formatter available for use with @--format@ and use it by default.+registerDefaultFormatter :: (String, FormatConfig -> IO Format) -> Config -> Config+registerDefaultFormatter formatter@(_, format) config = (registerFormatter formatter config) { configFormat = Just format }+ applyFilterPredicates :: Config -> [Tree c EvalItem] -> [Tree c EvalItem] applyFilterPredicates c = filterForestWithLabels p where@@ -268,7 +279,7 @@ failFocused :: Item a -> Item a failFocused item = item {itemExample = example} where- failure = Failure Nothing (Reason "item is focused; failing due to --fail-on-focused")+ failure = Failure Nothing (Reason "item is focused; failing due to --fail-on=focused") example | itemIsFocused item = \ params hook p -> do Result info status <- itemExample item params hook p@@ -289,7 +300,7 @@ example params hook p = do Result info status <- itemExample item params hook p return $ Result info $ case status of- Pending loc _ -> Failure loc (Reason "item is pending; failing due to --fail-on-pending")+ Pending loc _ -> Failure loc (Reason "item is pending; failing due to --fail-on=pending") _ -> status focusSpec :: Config -> [SpecTree a] -> [SpecTree a]@@ -300,6 +311,7 @@ runEvalTree :: Config -> [EvalTree] -> IO SpecResult runEvalTree config spec = do let+ failOnEmpty = configFailOnEmpty config seed = (fromJust . configQuickCheckSeed) config qcArgs = configQuickCheckArgs config !numberOfItems = countSpecItems spec@@ -311,7 +323,7 @@ (reportProgress, useColor) <- colorOutputSupported (configColorMode config) (hSupportsANSI stdout) outputUnicode <- unicodeOutputSupported (configUnicodeMode config) stdout - results <- fmap toSpecResult . withHiddenCursor reportProgress stdout $ do+ results <- fmap (toSpecResult failOnEmpty) . withHiddenCursor reportProgress stdout $ do let formatConfig = FormatConfig { formatConfigUseColor = useColor
src/Test/Hspec/Core/Runner/Result.hs view
@@ -43,11 +43,11 @@ | ResultItemFailure deriving (Eq, Show) -toSpecResult :: [(Path, Format.Item)] -> SpecResult-toSpecResult results = SpecResult items success+toSpecResult :: Bool -> [(Path, Format.Item)] -> SpecResult+toSpecResult failOnEmpty results = SpecResult items success where items = map toResultItem results- success = all (not . resultItemIsFailure) items+ success = not (failOnEmpty && null results) && all (not . resultItemIsFailure) items toResultItem :: (Path, Format.Item) -> ResultItem toResultItem (path, item) = ResultItem path status
src/Test/Hspec/Core/Spec/Monad.hs view
@@ -23,7 +23,6 @@ import Prelude () import Test.Hspec.Core.Compat -import Control.Arrow import Control.Monad.IO.Class (liftIO) import Control.Monad.Trans.Reader import Control.Monad.Trans.Writer
src/Test/Hspec/Core/Util.hs view
@@ -50,10 +50,12 @@ -- ensure that lines are not longer than given `n`, insert line breaks at word -- boundaries lineBreaksAt :: Int -> String -> [String]-lineBreaksAt n input = case words input of- [] -> []- x:xs -> go (x, xs)+lineBreaksAt n = concatMap f . lines where+ f input = case words input of+ [] -> []+ x:xs -> go (x, xs)+ go :: (String, [String]) -> [String] go c = case c of (s, []) -> [s]
test/Test/Hspec/Core/Config/DefinitionSpec.hs view
@@ -7,6 +7,16 @@ spec :: Spec spec = do- describe "formatOrList" $ do- it "formats a list of or-options" $ do- formatOrList ["foo", "bar", "baz"] `shouldBe` "foo, bar or baz"+ describe "splitOn" $ do+ it "splits a string" $ do+ splitOn ',' "foo,bar,baz" `shouldBe` ["foo", "bar", "baz"]++ it "splits *arbitrary* strings" $ property $ do+ let+ string :: Gen String+ string = arbitrary `suchThat` p++ p :: String -> Bool+ p = (&&) <$> not . null <*> all (/= ',')++ forAll (listOf string) $ \ xs -> splitOn ',' (intercalate "," xs) `shouldBe` xs
test/Test/Hspec/Core/Config/OptionsSpec.hs view
@@ -43,6 +43,37 @@ expected <- readFile "help.txt" help `shouldBe` expected + describe "RUNNER OPTIONS" $ do+ let parseOptions_ args = snd <$> Options.parseOptions defaultConfig "my-spec" [] Nothing [] args++ context "with --fail-on-focused" $ do+ it "sets configFailOnFocused to True" $ do+ configFailOnFocused <$> parseOptions_ ["--fail-on-focused"] `shouldBe` Right True++ context "with --fail-on-pending" $ do+ it "sets configFailOnPending to True" $ do+ configFailOnPending <$> parseOptions_ ["--fail-on-pending"] `shouldBe` Right True++ context "with --fail-on" $ do+ it "accepts a list of values" $ do+ let config = parseOptions_ ["--fail-on=focused,pending"]+ configFailOnFocused <$> config `shouldBe` Right True+ configFailOnPending <$> config `shouldBe` Right True++ context "with focused" $ do+ it "sets configFailOnFocused to True" $ do+ configFailOnFocused <$> parseOptions_ ["--fail-on=focused"] `shouldBe` Right True++ context "with pending" $ do+ it "sets configFailOnPending to True" $ do+ configFailOnPending <$> parseOptions_ ["--fail-on=pending"] `shouldBe` Right True++ context "with --no-fail-on" $ do+ it "inverts --fail-on" $ do+ let config = parseOptions_ ["--fail-on=focused,pending", "--no-fail-on=focused,pending"]+ configFailOnFocused <$> config `shouldBe` Right False+ configFailOnPending <$> config `shouldBe` Right False+ context "with --color" $ do it "sets configColorMode to ColorAlways" $ do configColorMode <$> parseOptions [] Nothing [] ["--color"] `shouldBe` Right ColorAlways@@ -112,13 +143,11 @@ fromLeft (parseOptions [("~/.hspec", ["--invalid"])] Nothing [] []) `shouldBe` (ExitFailure 1, "my-spec: unrecognized option `--invalid' in config file ~/.hspec\n") it "rejects ambiguous options" $ do- fromLeft (parseOptions [("~/.hspec", ["--fail"])] Nothing [] []) `shouldBe` (ExitFailure 1,+ fromLeft (parseOptions [("~/.hspec", ["--print"])] Nothing [] []) `shouldBe` (ExitFailure 1, unlines [- "my-spec: option `--fail' is ambiguous; could be one of:"- , " --fail-on-focused fail on focused spec items"- , " --fail-on-pending fail on pending spec items"- , " --fail-fast abort on first failure"- , " --failure-report=FILE read/write a failure report for use with --rerun"+ "my-spec: option `--print' is ambiguous; could be one of:"+ , " --print-cpu-time include used CPU time in summary"+ , " -p[N] --print-slow-items[=N] print the N slowest spec items (default: 10)" , "in config file ~/.hspec" ] )
test/Test/Hspec/Core/HooksSpec.hs view
@@ -7,7 +7,6 @@ import Mock import Control.Exception-import Control.Arrow import qualified Test.Hspec.Core.Runner as H import qualified Test.Hspec.Core.Spec as H
+ test/Test/Hspec/Core/Runner/ResultSpec.hs view
@@ -0,0 +1,36 @@+module Test.Hspec.Core.Runner.ResultSpec (spec) where++import Prelude ()+import Helper++import Test.Hspec.Core.Format++import Test.Hspec.Core.Runner.Result++spec :: Spec+spec = do+ describe "specResultSuccess" $ do+ let+ failure = Failure Nothing NoReason+ item result = (([], ""), Item Nothing 0 "" result)++ context "when all spec items passed" $ do+ it "returns True" $ do+ specResultSuccess (toSpecResult False [item Success]) `shouldBe` True++ context "with a failed spec item" $ do+ it "returns False" $ do+ specResultSuccess (toSpecResult False [item Success, item failure]) `shouldBe` False++ context "with an empty result list" $ do+ it "returns True" $ do+ specResultSuccess (toSpecResult False []) `shouldBe` True++ context "when configFailOnEmpty is True" $ do+ context "when all spec items passed" $ do+ it "returns True" $ do+ specResultSuccess (toSpecResult True [item Success]) `shouldBe` True++ context "with an empty result list" $ do+ it "returns False" $ do+ specResultSuccess (toSpecResult True []) `shouldBe` False
test/Test/Hspec/Core/RunnerSpec.hs view
@@ -269,8 +269,22 @@ , "0 examples, 0 failures" ] - context "with --fail-on-focused" $ do- let run = captureLines . ignoreExitCode . withArgs ["--fail-on-focused", "--seed", "23"] . H.hspec . removeLocations+ context "with --fail-on=empty" $ do+ it "fails if no spec items have been run" $ do+ (out, r) <- capture . E.try . withArgs ["--skip=", "--fail-on=empty"] . H.hspec $ do+ H.it "foo" True+ H.it "bar" True+ H.it "baz" True+ unlines (normalizeSummary (lines out)) `shouldBe` unlines [+ ""+ , ""+ , "Finished in 0.0000 seconds"+ , "0 examples, 0 failures"+ ]+ r `shouldBe` Left (ExitFailure 1)++ context "with --fail-on=focused" $ do+ let run = captureLines . ignoreExitCode . withArgs ["--fail-on=focused", "--seed", "23"] . H.hspec . removeLocations it "fails on focused spec items" $ do r <- run $ do H.it "foo" True@@ -282,7 +296,7 @@ , "Failures:" , "" , " 1) bar"- , " item is focused; failing due to --fail-on-focused"+ , " item is focused; failing due to --fail-on=focused" , "" , " To rerun use: --match \"/bar/\"" , ""@@ -292,8 +306,8 @@ , "1 example, 1 failure" ] - context "with --fail-on-pending" $ do- let run = captureLines . ignoreExitCode . withArgs ["--fail-on-pending", "--seed", "23"] . H.hspec . removeLocations+ context "with --fail-on=pending" $ do+ let run = captureLines . ignoreExitCode . withArgs ["--fail-on=pending", "--seed", "23"] . H.hspec . removeLocations it "fails on pending spec items" $ do r <- run $ do H.it "foo" True@@ -308,7 +322,7 @@ , "Failures:" , "" , " 1) bar"- , " item is pending; failing due to --fail-on-pending"+ , " item is pending; failing due to --fail-on=pending" , "" , " To rerun use: --match \"/bar/\"" , ""
test/Test/Hspec/Core/UtilSpec.hs view
@@ -44,6 +44,14 @@ , "sed do eiusmod" ] + it "preserves existing line breaks" $ do+ lineBreaksAt 10 "foo bar baz\none two three" `shouldBe` [+ "foo bar"+ , "baz"+ , "one two"+ , "three"+ ]+ describe "safeTry" $ do it "returns Right on success" $ do Right e <- safeTry (return 23 :: IO Int)
version.yaml view
@@ -1,1 +1,1 @@-&version 2.10.4+&version 2.10.5