hspec-meta 2.11.9 → 2.11.10
raw patch · 18 files changed
+428/−47 lines, 18 filesdep +containersPVP ok
version bump matches the API change (PVP)
Dependencies added: containers
API changes (from Hackage documentation)
Files
- hspec-core/src/Test/Hspec/Core/Annotations.hs +29/−0
- hspec-core/src/Test/Hspec/Core/Compat.hs +2/−1
- hspec-core/src/Test/Hspec/Core/Config.hs +1/−1
- hspec-core/src/Test/Hspec/Core/Config/Definition.hs +43/−7
- hspec-core/src/Test/Hspec/Core/Config/Options.hs +12/−15
- hspec-core/src/Test/Hspec/Core/Extension.hs +112/−0
- hspec-core/src/Test/Hspec/Core/Extension/Config.hs +19/−0
- hspec-core/src/Test/Hspec/Core/Extension/Config/Type.hs +43/−0
- hspec-core/src/Test/Hspec/Core/Extension/Item.hs +46/−0
- hspec-core/src/Test/Hspec/Core/Extension/Option.hs +27/−0
- hspec-core/src/Test/Hspec/Core/Extension/Spec.hs +10/−0
- hspec-core/src/Test/Hspec/Core/Extension/Tree.hs +19/−0
- hspec-core/src/Test/Hspec/Core/Formatters/Internal.hs +18/−6
- hspec-core/src/Test/Hspec/Core/Formatters/V2.hs +10/−9
- hspec-core/src/Test/Hspec/Core/Runner.hs +6/−4
- hspec-core/src/Test/Hspec/Core/Tree.hs +17/−0
- hspec-discover/src/Test/Hspec/Discover/Run.hs +2/−2
- hspec-meta.cabal +12/−2
+ hspec-core/src/Test/Hspec/Core/Annotations.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Test.Hspec.Core.Annotations (+ Annotations+, setValue+, getValue+) where++import Prelude ()+import Test.Hspec.Core.Compat++import Data.Typeable+import Data.Dynamic+import Data.Map (Map)+import qualified Data.Map as Map++newtype Annotations = Annotations (Map TypeRep Dynamic)+ deriving (+#if MIN_VERSION_base(4,11,0)+ Semigroup,+#endif+ Monoid)++setValue :: Typeable value => value -> Annotations -> Annotations+setValue value (Annotations values) = Annotations $ Map.insert (typeOf value) (toDyn value) values++getValue :: forall value. Typeable value => Annotations -> Maybe value+getValue (Annotations values) = Map.lookup (typeOf (undefined :: value)) values >>= fromDynamic
hspec-core/src/Test/Hspec/Core/Compat.hs view
@@ -19,6 +19,7 @@ import Data.Maybe as Imports import Data.Foldable as Imports import GHC.Stack as Imports (HasCallStack, withFrozenCallStack)+import Data.Typeable as Imports (Typeable) import System.IO import System.Exit@@ -65,7 +66,7 @@ , sum ) -import Data.Typeable (Typeable, typeOf, typeRepTyCon, tyConModule, tyConName)+import Data.Typeable (typeOf, typeRepTyCon, tyConModule, tyConName) import Data.IORef as Imports #if MIN_VERSION_base(4,12,0)
hspec-core/src/Test/Hspec/Core/Config.hs view
@@ -61,7 +61,7 @@ } where - mSeed = configSeed config <|> deprecatedQuickCheckSeed config <|> (failureReportSeed <$> mFailureReport)+ mSeed = getSeed config <|> (failureReportSeed <$> mFailureReport) mMaxSuccess = configQuickCheckMaxSuccess config <|> (failureReportMaxSuccess <$> mFailureReport) mMaxSize = configQuickCheckMaxSize config <|> (failureReportMaxSize <$> mFailureReport) mMaxDiscardRatio = configQuickCheckMaxDiscardRatio config <|> (failureReportMaxDiscardRatio <$> mFailureReport)
hspec-core/src/Test/Hspec/Core/Config/Definition.hs view
@@ -3,16 +3,27 @@ Config(..) , ColorMode(..) , UnicodeMode(..)-, filterOr , mkDefaultConfig +, filterOr++, setConfigAnnotation+, getConfigAnnotation++, addExtensionOptions+, getExtensionOptions++, getSeed+, getFormatter+ , commandLineOnlyOptions , formatterOptions , smallCheckOptions , quickCheckOptions , runnerOptions -, deprecatedQuickCheckSeed+, flag+, option #ifdef TEST , splitOn@@ -26,14 +37,40 @@ import System.IO (openTempFile, hClose) import System.Process (system) +import Test.Hspec.Core.Annotations (Annotations)+import qualified Test.Hspec.Core.Annotations as Annotations+ import Test.Hspec.Core.Format (Format, FormatConfig) import Test.Hspec.Core.Formatters.Pretty (pretty2) import qualified Test.Hspec.Core.Formatters.V1.Monad as V1+import qualified Test.Hspec.Core.Formatters.V1.Internal as V1 (formatterToFormat) import Test.Hspec.Core.Util import GetOpt.Declarative +setConfigAnnotation :: Typeable value => value -> Config -> Config+setConfigAnnotation value config = config { configAnnotations = Annotations.setValue value $ configAnnotations config } +getConfigAnnotation :: Typeable value => Config -> Maybe value+getConfigAnnotation = Annotations.getValue . configAnnotations++newtype ExtensionOptions = ExtensionOptions { unExtensionOptions :: [(String, [Option Config])] }++addExtensionOptions :: String -> [Option Config] -> Config -> Config+addExtensionOptions section opts config = setExtensionOptions ((section, opts) : getExtensionOptions config) config++setExtensionOptions :: [(String, [Option Config])] -> Config -> Config+setExtensionOptions = setConfigAnnotation . ExtensionOptions++getExtensionOptions :: Config -> [(String, [Option Config])]+getExtensionOptions = maybe [] unExtensionOptions . getConfigAnnotation++getFormatter :: Config -> Maybe (FormatConfig -> IO Format)+getFormatter config = configFormat config <|> V1.formatterToFormat <$> configFormatter config++getSeed :: Config -> Maybe Integer+getSeed config = configSeed config <|> configQuickCheckSeed config+ data ColorMode = ColorAuto | ColorNever | ColorAlways deriving (Eq, Show) @@ -91,13 +128,11 @@ , configFormatter :: Maybe V1.Formatter , configHtmlOutput :: Bool , configConcurrentJobs :: Maybe Int+, configAnnotations :: Annotations } {-# DEPRECATED configFormatter "Use [@useFormatter@](https://hackage.haskell.org/package/hspec-api/docs/Test-Hspec-Api-Formatters-V1.html#v:useFormatter) instead." #-} {-# DEPRECATED configQuickCheckSeed "Use `configSeed` instead." #-} -deprecatedQuickCheckSeed :: Config -> Maybe Integer-deprecatedQuickCheckSeed = configQuickCheckSeed- mkDefaultConfig :: [(String, FormatConfig -> IO Format)] -> Config mkDefaultConfig formatters = Config { configIgnoreConfigFile = False@@ -138,6 +173,7 @@ , configFormatter = Nothing , configHtmlOutput = False , configConcurrentJobs = Nothing+, configAnnotations = mempty } defaultDiffContext :: Int@@ -160,7 +196,7 @@ option :: String -> OptionSetter config -> String -> Option config option name arg help = Option name Nothing arg help True -flag :: String -> (Bool -> Config -> Config) -> String -> Option Config+flag :: String -> (Bool -> config -> config) -> String -> Option config flag name setter = option name (Flag setter) mkOptionNoArg :: String -> Maybe Char -> (Config -> Config) -> String -> Option Config@@ -172,7 +208,7 @@ undocumented :: Option config -> Option config undocumented opt = opt {optionDocumented = False} -argument :: String -> (String -> Maybe a) -> (a -> Config -> Config) -> OptionSetter Config+argument :: String -> (String -> Maybe a) -> (a -> config -> config) -> OptionSetter config argument name parser setter = Arg name $ \ input c -> flip setter c <$> parser input formatterOptions :: [(String, FormatConfig -> IO Format)] -> [Option Config]
hspec-core/src/Test/Hspec/Core/Config/Options.hs view
@@ -11,7 +11,6 @@ import System.Exit -import Test.Hspec.Core.Format (Format, FormatConfig) import Test.Hspec.Core.Config.Definition import qualified GetOpt.Declarative as Declarative import GetOpt.Declarative.Interpret (parse, interpretOptions, ParseResult(..))@@ -22,18 +21,21 @@ envVarName :: String envVarName = "HSPEC_OPTIONS" -commandLineOptions :: [(String, FormatConfig -> IO Format)] -> [(String, [Declarative.Option Config])]-commandLineOptions formatters =+commandLineOptions :: Config -> [(String, [Declarative.Option Config])]+commandLineOptions config = ("OPTIONS", commandLineOnlyOptions)- : otherOptions formatters+ : otherOptions config -otherOptions :: [(String, FormatConfig -> IO Format)] -> [(String, [Declarative.Option Config])]-otherOptions formatters = [+otherOptions :: Config -> [(String, [Declarative.Option Config])]+otherOptions config = [ ("RUNNER OPTIONS", runnerOptions) , ("FORMATTER OPTIONS", formatterOptions formatters) , ("OPTIONS FOR QUICKCHECK", quickCheckOptions) , ("OPTIONS FOR SMALLCHECK", smallCheckOptions)- ]+ ] ++ extensionOptions+ where+ formatters = configAvailableFormatters config+ extensionOptions = getExtensionOptions config ignoreConfigFile :: Config -> [String] -> IO Bool ignoreConfigFile config args = do@@ -52,18 +54,15 @@ >>= traverse (parseCommandLineOptions prog args) parseCommandLineOptions :: String -> [String] -> Config -> Either (ExitCode, String) Config-parseCommandLineOptions prog args config = case Declarative.parseCommandLineOptions (commandLineOptions formatters) prog args config of+parseCommandLineOptions prog args config = case Declarative.parseCommandLineOptions (commandLineOptions config) prog args config of Success c -> Right c Help message -> Left (ExitSuccess, message) Failure message -> Left (ExitFailure 1, message)- where- formatters = configAvailableFormatters config parseEnvironmentOptions :: [(String, String)] -> Config -> Either (ExitCode, String) ([String], Config)-parseEnvironmentOptions env config = case Declarative.parseEnvironmentOptions "HSPEC" env config (concatMap snd $ commandLineOptions formatters) of+parseEnvironmentOptions env config = case Declarative.parseEnvironmentOptions "HSPEC" env config (concatMap snd $ commandLineOptions config) of (warnings, c) -> Right (map formatWarning warnings, c) where- formatters = configAvailableFormatters config formatWarning (Declarative.InvalidValue name value) = "invalid value `" ++ value ++ "' for environment variable " ++ name parseFileOptions :: String -> Config -> ConfigFile -> Either (ExitCode, String) Config@@ -80,9 +79,7 @@ Left err -> failure err where options :: [Declarative.Option Config]- options = filter Declarative.optionDocumented $ concatMap snd (otherOptions formatters)-- formatters = configAvailableFormatters config+ options = filter Declarative.optionDocumented $ concatMap snd (otherOptions config) failure err = Left (ExitFailure 1, prog ++ ": " ++ message) where
+ hspec-core/src/Test/Hspec/Core/Extension.hs view
@@ -0,0 +1,112 @@+{-# OPTIONS_GHC -fno-warn-deprecations #-}+-- | Stability: unstable+module Test.Hspec.Core.Extension {-# WARNING "This API is experimental." #-} (+-- * Lifecycle of a test run+{- |+A test run goes through four distinct phases:++1. A tree of spec items and a default `Config` are constructed in `SpecM`.+2. Command-line options are parsed. This transforms the default `Config` that was constructed in phase 1.+3. The tree of spec items is transformed in various ways, depending on specific `Config` values.+4. Each spec item is executed and its result is reported to the user.++An extension can directly influence phase 1, and indirectly influence phases 2-4.++When writing extensions the following imports are recommended:++@+import "Test.Hspec.Core.Extension"+import "Test.Hspec.Core.Extension.Config" qualified as Config+import "Test.Hspec.Core.Extension.Option" qualified as Option+import "Test.Hspec.Core.Extension.Item" qualified as Item+import "Test.Hspec.Core.Extension.Spec" qualified as Spec+import "Test.Hspec.Core.Extension.Tree" qualified as Tree+@+-}++-- ** Phase 1: Constructing a spec tree+{- |+- An extension can use @Spec.`Test.Hspec.Core.Extension.Spec.mapItems`@ to transform spec items in phase 1.++ * @Item.`setAnnotation`@ can be used to add custom metadata to a spec `Item`.++- An extension can use `modifyConfig` to modify the default config.++ * @Config.`Test.Hspec.Core.Extension.Config.setAnnotation`@ can be used to add custom metadata to the default `Config`.+-}+ runIO+, modifyConfig++-- ** Phase 2: Parsing command-line options+{- |+An extension can use `registerOptions` during phase 1 to register custom command-line options, and as a consequence indirectly influence this phase.++* Options can use @Config.`Test.Hspec.Core.Extension.Config.setAnnotation`@ to add custom metadata to the `Config`.+-}+, Option+, registerOptions++-- ** Phase 3: Transforming the spec tree+{- |+An extension can use `registerTransformation` during phase 1 to indirectly influence this phase.+-}+, registerTransformation++-- ** Phase 4: Reporting results+{- |+An extension can register a [custom formatter](https://hspec.github.io/extending-hspec-formatter.html) in phase 1 to indirectly influence this phase.+-}++-- * Types+{- |+Operations on these types are provided by the following modules respectively:++* "Test.Hspec.Core.Extension.Config"+* "Test.Hspec.Core.Extension.Item"+* "Test.Hspec.Core.Extension.Spec"+* "Test.Hspec.Core.Extension.Tree"+-}+, Config+, Item+, SpecM+, SpecWith+, SpecTree+) where++import Prelude ()+import Test.Hspec.Core.Compat++import qualified Data.CallStack as CallStack++import qualified GetOpt.Declarative as Declarative+import Test.Hspec.Core.Spec (SpecM, SpecWith, runIO, modifyConfig)+import qualified Test.Hspec.Core.Spec as Core+import qualified Test.Hspec.Core.Config.Definition as Core++import Test.Hspec.Core.Extension.Config (Config)+import qualified Test.Hspec.Core.Extension.Config.Type as Config+import Test.Hspec.Core.Extension.Option+import Test.Hspec.Core.Extension.Item+import Test.Hspec.Core.Extension.Tree++registerOptions :: HasCallStack => [Option] -> SpecWith a+registerOptions = Core.modifyConfig . Core.addExtensionOptions section . map liftOption+ where+ section = "OPTIONS FOR " <> package+ package = maybe "main" (CallStack.srcLocPackage . snd) CallStack.callSite++ liftOption :: Option -> Declarative.Option Core.Config+ liftOption = Config.unOption++{- |+Register a transformation that transforms the spec tree in phase 3.++The registered transformation can use:++- @Tree.`mapItems`@ to modify spec items+- @Tree.`filterItems`@ to discard spec items+- @Config.`Test.Hspec.Core.Extension.Config.getAnnotation`@ to access custom config metadata+- @Item.`getAnnotation`@ to access custom item metadata+-}+registerTransformation :: (Config -> [SpecTree] -> [SpecTree]) -> SpecWith a+registerTransformation = modifyConfig . Config.addSpecTransformation
+ hspec-core/src/Test/Hspec/Core/Extension/Config.hs view
@@ -0,0 +1,19 @@+{-# OPTIONS_GHC -fno-warn-deprecations #-}+module Test.Hspec.Core.Extension.Config {-# WARNING "This API is experimental." #-} (+-- * Types+ Config(..)+, Path+, ColorMode(..)+, UnicodeMode(..)++-- * Operations+, setAnnotation+, getAnnotation+) where++import Prelude ()++import Test.Hspec.Core.Format+import Test.Hspec.Core.Config.Definition (ColorMode(..), UnicodeMode(..))++import Test.Hspec.Core.Extension.Config.Type
+ hspec-core/src/Test/Hspec/Core/Extension/Config/Type.hs view
@@ -0,0 +1,43 @@+{-# OPTIONS_GHC -fno-warn-deprecations #-}+module Test.Hspec.Core.Extension.Config.Type (+ Option(..)+, Config(..)++, setAnnotation+, getAnnotation++, addSpecTransformation+, applySpecTransformation+) where++import Prelude ()+import Test.Hspec.Core.Compat++import qualified GetOpt.Declarative as Declarative++import Test.Hspec.Core.Config.Definition (Config(..))+import qualified Test.Hspec.Core.Config.Definition as Core++import Test.Hspec.Core.Extension.Tree (SpecTree)++newtype Option = Option { unOption :: Declarative.Option Config }++setAnnotation :: Typeable value => value -> Config -> Config+setAnnotation = Core.setConfigAnnotation++getAnnotation :: Typeable value => Config -> Maybe value+getAnnotation = Core.getConfigAnnotation++newtype SpecTransformation = SpecTransformation { unSpecTransformation :: Config -> [SpecTree] -> [SpecTree] }++setSpecTransformation :: (Config -> [SpecTree] -> [SpecTree]) -> Config -> Config+setSpecTransformation = setAnnotation . SpecTransformation++getSpecTransformation :: Config -> Config -> [SpecTree] -> [SpecTree]+getSpecTransformation = maybe (\ _ -> id) unSpecTransformation . getAnnotation++addSpecTransformation :: (Config -> [SpecTree] -> [SpecTree]) -> Config -> Config+addSpecTransformation f config = setSpecTransformation (\ c -> f c . getSpecTransformation config c) config++applySpecTransformation :: Core.Config -> [SpecTree] -> [SpecTree]+applySpecTransformation config = getSpecTransformation config config
+ hspec-core/src/Test/Hspec/Core/Extension/Item.hs view
@@ -0,0 +1,46 @@+module Test.Hspec.Core.Extension.Item {-# WARNING "This API is experimental." #-} (+-- * Types+ Item(..)+, Location(..)+, Params(..)+, ActionWith+, Progress+, ProgressCallback+, Result(..)+, ResultStatus(..)+, FailureReason(..)++-- * Operations+, isFocused+, pending+, pendingWith+, setAnnotation+, getAnnotation+) where++import Prelude ()+import Test.Hspec.Core.Compat++import Test.Hspec.Core.Spec hiding (pending, pendingWith)+import Test.Hspec.Core.Tree++isFocused :: Item a -> Bool+isFocused = itemIsFocused++pending :: Item a -> Item a+pending item = item { itemExample = \ _params _hook _progress -> result }+ where+ result :: IO Result+ result = return $ Result "" (Pending Nothing Nothing)++pendingWith :: String -> Item a -> Item a+pendingWith reason item = item { itemExample = \ _params _hook _progress -> result }+ where+ result :: IO Result+ result = return $ Result "" (Pending Nothing (Just reason))++setAnnotation :: Typeable value => value -> Item a -> Item a+setAnnotation = setItemAnnotation++getAnnotation :: Typeable value => Item a -> Maybe value+getAnnotation = getItemAnnotation
+ hspec-core/src/Test/Hspec/Core/Extension/Option.hs view
@@ -0,0 +1,27 @@+module Test.Hspec.Core.Extension.Option {-# WARNING "This API is experimental." #-} (+ Option+, flag+, argument+, noArgument+, optionalArgument+) where++import Prelude ()+import Test.Hspec.Core.Compat++import qualified GetOpt.Declarative as Declarative+import qualified Test.Hspec.Core.Config.Definition as Core++import Test.Hspec.Core.Extension.Config.Type (Option(..), Config)++flag :: String -> (Bool -> Config -> Config) -> String -> Option+flag name setter = Option . Core.flag name setter++argument :: String -> String -> (String -> Config -> Maybe Config) -> String -> Option+argument name argumentName setter = Option . Core.option name (Declarative.Arg argumentName setter)++optionalArgument :: String -> String -> (Maybe String -> Config -> Maybe Config) -> String -> Option+optionalArgument name argumentName setter = Option . Core.option name (Declarative.OptArg argumentName setter)++noArgument :: String -> (Config -> Config) -> String -> Option+noArgument name setter help = Option $ Declarative.Option name Nothing (Declarative.NoArg setter) help False
+ hspec-core/src/Test/Hspec/Core/Extension/Spec.hs view
@@ -0,0 +1,10 @@+module Test.Hspec.Core.Extension.Spec {-# WARNING "This API is experimental." #-} (+ mapItems+) where++import Prelude ()++import Test.Hspec.Core.Spec++mapItems :: (Item a -> Item b) -> SpecWith a -> SpecWith b+mapItems = mapSpecItem_
+ hspec-core/src/Test/Hspec/Core/Extension/Tree.hs view
@@ -0,0 +1,19 @@+module Test.Hspec.Core.Extension.Tree {-# WARNING "This API is experimental." #-} (+ SpecTree+, mapItems+, filterItems+) where++import Prelude ()+import Test.Hspec.Core.Compat++import Test.Hspec.Core.Spec hiding (SpecTree)+import qualified Test.Hspec.Core.Spec as Core++type SpecTree = Core.SpecTree ()++mapItems :: (Item () -> Item ()) -> [SpecTree] -> [SpecTree]+mapItems = map . fmap++filterItems :: (Item () -> Bool) -> [SpecTree] -> [SpecTree]+filterItems = filterForest
hspec-core/src/Test/Hspec/Core/Formatters/Internal.hs view
@@ -60,7 +60,7 @@ import qualified System.IO as IO import System.IO (stdout)-import System.Console.ANSI+import System.Console.ANSI hiding (clearLine) import Control.Monad.Trans.Reader (ReaderT(..), ask) import Control.Monad.IO.Class import Data.Char (isSpace)@@ -271,11 +271,20 @@ writeTransient :: String -> FormatM () writeTransient new = do reportProgress <- getConfigValue formatConfigReportProgress- when reportProgress $ do- write new- liftIO $ IO.hFlush stdout- write $ "\r" ++ replicate (length new) ' ' ++ "\r"+ when reportProgress . liftIO $ do+ bracket_ disableLineWrapping enableLineWrapping $ writePlain new+ IO.hFlush stdout+ clearLine+ where+ disableLineWrapping :: IO ()+ disableLineWrapping = writePlain "\ESC[?7l" + enableLineWrapping :: IO ()+ enableLineWrapping = writePlain "\ESC[?7h"++ clearLine :: IO ()+ clearLine = writePlain "\r\ESC[K"+ -- | Append some output to the report. write :: String -> FormatM () write = mapM_ writeChunk . splitLines@@ -288,13 +297,16 @@ writeChunk :: String -> FormatM () writeChunk str = do let- plainOutput = IO.hPutStr stdout str+ plainOutput = writePlain str colorOutput color = bracket_ (hSetSGR stdout [color]) (hSetSGR stdout [Reset]) plainOutput mColor <- gets stateColor liftIO $ case mColor of Just (SetColor Foreground _ _) | all isSpace str -> plainOutput Just color -> colorOutput color Nothing -> plainOutput++writePlain :: String -> IO ()+writePlain = IO.hPutStr stdout -- | Set output color to red, run given action, and finally restore the default -- color.
hspec-core/src/Test/Hspec/Core/Formatters/V2.hs view
@@ -188,7 +188,7 @@ Success {} -> pass Failure {} -> pass Pending _ reason -> withPendingColor $ do- writeLine $ indentationFor ("" : nesting) ++ "# PENDING: " ++ fromMaybe "No reason given" reason+ indentBy (indentationFor ("" : nesting)) $ "# PENDING: " ++ fromMaybe "No reason given" reason } where indentationFor nesting = replicate (length nesting * 2) ' ' @@ -198,8 +198,7 @@ write $ indentationFor nesting ++ requirement ++ " [" withColor $ write symbol writeLine $ "]" ++ if shouldPrintTimes then times else ""- forM_ (lines info) $ \ s ->- writeLine $ indentationFor ("" : nesting) ++ s+ indentBy (indentationFor ("" : nesting)) info where dt :: Int dt = toMilliseconds duration@@ -233,7 +232,7 @@ writeResult nesting requirement duration info Pending _ reason -> withPendingColor $ do writeResult nesting requirement duration info- writeLine $ indentationFor ("" : nesting) ++ "# PENDING: " ++ fromMaybe "No reason given" reason+ indentBy (indentationFor ("" : nesting)) $ "# PENDING: " ++ fromMaybe "No reason given" reason Failure {} -> withFailColor $ do n <- getFailCount writeResult nesting (requirement ++ " FAILED [" ++ show n ++ "]") duration info@@ -245,8 +244,7 @@ writeResult nesting requirement (Seconds duration) info = do shouldPrintTimes <- printTimes writeLine $ indentationFor nesting ++ requirement ++ if shouldPrintTimes then times else ""- forM_ (lines info) $ \ s ->- writeLine $ indentationFor ("" : nesting) ++ s+ indentBy (indentationFor ("" : nesting)) info where dt :: Int dt = floor (duration * 1000)@@ -362,9 +360,12 @@ writeLine (" To rerun use: --match " ++ path_ <> " --seed " <> show seed) where indentation = " "- indent message = do- forM_ (lines message) $ \line -> do- writeLine (indentation ++ line)+ indent = indentBy indentation++indentBy :: String -> String -> FormatM ()+indentBy indentation message = do+ forM_ (lines message) $ \ line -> do+ writeLine (indentation ++ line) data Chunk = Original String | Modified String | OmittedLines Int deriving (Eq, Show)
hspec-core/src/Test/Hspec/Core/Runner.hs view
@@ -117,8 +117,9 @@ import Test.Hspec.Core.Spec hiding (pruneTree, pruneForest) import Test.Hspec.Core.Tree (formatDefaultDescription) import Test.Hspec.Core.Config+import Test.Hspec.Core.Config.Definition as Config (getSeed, getFormatter)+import Test.Hspec.Core.Extension.Config.Type as Extension (applySpecTransformation) 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 import Test.Hspec.Core.QuickCheck.Util@@ -197,7 +198,7 @@ -- for all properties. This helps with --seed and --rerun. ensureSeed :: Config -> IO (Config, Integer) ensureSeed config = do- seed <- case configSeed config <|> configQuickCheckSeed config of+ seed <- case Config.getSeed config of Nothing -> toInteger <$> newSeed Just seed -> return seed return (config { configSeed = Just seed }, seed)@@ -391,7 +392,7 @@ , formatConfigExpertMode = configExpertMode config } - formatter = fromMaybe (V2.formatterToFormat V2.checks) (configFormat config <|> V1.formatterToFormat <$> configFormatter config)+ formatter = fromMaybe (V2.formatterToFormat V2.checks) (Config.getFormatter config) format <- maybe id printSlowSpecItems (configPrintSlowItems config) <$> formatter formatConfig @@ -418,6 +419,7 @@ >>> addDefaultDescriptions >>> failFocusedItems config >>> failPendingItems config+ >>> Extension.applySpecTransformation config >>> focusSpec config >>> toEvalItemForest params >>> applyDryRun config@@ -450,7 +452,7 @@ toEvalItemForest params = bimapForest id toEvalItem . filterForest itemIsFocused where toEvalItem :: Item () -> EvalItem- toEvalItem (Item requirement loc isParallelizable _isFocused e) = EvalItem {+ toEvalItem (Item requirement loc isParallelizable _isFocused _annotations e) = EvalItem { evalItemDescription = requirement , evalItemLocation = loc , evalItemConcurrency = if isParallelizable == Just True then Concurrent else Sequential
hspec-core/src/Test/Hspec/Core/Tree.hs view
@@ -24,6 +24,9 @@ , callSite , formatDefaultDescription , toModuleName++, setItemAnnotation+, getItemAnnotation ) where import Prelude ()@@ -34,6 +37,8 @@ import qualified Data.CallStack as CallStack import Test.Hspec.Core.Example+import Test.Hspec.Core.Annotations (Annotations)+import qualified Test.Hspec.Core.Annotations as Annotations -- | Internal tree data structure data Tree c a =@@ -114,10 +119,21 @@ -- | A flag that indicates whether this spec item is focused , itemIsFocused :: Bool + -- | Arbitrary additional data that can be used by third-party extensions.+ --+ -- @since 2.12.0+, itemAnnotations :: Annotations+ -- | Example for behavior , itemExample :: Params -> (ActionWith a -> IO ()) -> ProgressCallback -> IO Result } +setItemAnnotation :: Typeable value => value -> Item a -> Item a+setItemAnnotation value config = config { itemAnnotations = Annotations.setValue value $ itemAnnotations config }++getItemAnnotation :: Typeable value => Item a -> Maybe value+getItemAnnotation = Annotations.getValue . itemAnnotations+ -- | The @specGroup@ function combines a list of specs into a larger spec. specGroup :: HasCallStack => String -> [SpecTree a] -> SpecTree a specGroup s = Node msg@@ -134,6 +150,7 @@ , itemLocation = location , itemIsParallelizable = Nothing , itemIsFocused = False+ , itemAnnotations = mempty , itemExample = safeEvaluateExample e }
hspec-discover/src/Test/Hspec/Discover/Run.hs view
@@ -62,7 +62,7 @@ ( "{-# LINE 1 " . shows src . " #-}\n" . showString "{-# LANGUAGE NoImplicitPrelude #-}\n" . showString "{-# OPTIONS_GHC -w -Wall -fno-warn-warnings-deprecations #-}\n"- . showString ("module " ++ moduleName src conf ++" where\n")+ . showString ("module " ++ moduleName src conf ++ " where\n") . importList nodes . showString "import Test.Hspec.Discover\n" . maybe driver driverWithFormatter (configFormatter conf)@@ -86,7 +86,7 @@ pathToModule f = toUpper m:ms where fileName = last $ splitDirectories f- m:ms = takeWhile (/='.') fileName+ m:ms = takeWhile (/= '.') fileName driverWithFormatter :: String -> ShowS driverWithFormatter f =
hspec-meta.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.36.0.+-- This file has been generated from package.yaml by hpack version 0.37.0. -- -- see: https://github.com/sol/hpack name: hspec-meta-version: 2.11.9+version: 2.11.10 synopsis: A version of Hspec which is used to test Hspec itself description: A stable version of Hspec which is used to test the in-development version of Hspec.@@ -44,6 +44,7 @@ GetOpt.Declarative.Types GetOpt.Declarative.Util NonEmpty+ Test.Hspec.Core.Annotations Test.Hspec.Core.Clock Test.Hspec.Core.Compat Test.Hspec.Core.Config@@ -51,6 +52,13 @@ Test.Hspec.Core.Config.Options Test.Hspec.Core.Example Test.Hspec.Core.Example.Location+ Test.Hspec.Core.Extension+ Test.Hspec.Core.Extension.Config+ Test.Hspec.Core.Extension.Config.Type+ Test.Hspec.Core.Extension.Item+ Test.Hspec.Core.Extension.Option+ Test.Hspec.Core.Extension.Spec+ Test.Hspec.Core.Extension.Tree Test.Hspec.Core.FailureReport Test.Hspec.Core.Format Test.Hspec.Core.Formatters@@ -93,6 +101,7 @@ , array , base >=4.9.0.0 && <5 , call-stack >=0.2.0+ , containers , deepseq , directory , filepath@@ -132,6 +141,7 @@ , array , base >=4.9.0.0 && <5 , call-stack >=0.2.0+ , containers , deepseq , directory , filepath