hspec-meta 1.10.0 → 1.11.0
raw patch · 7 files changed
+53/−28 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Test.Hspec.Meta: runIO :: IO a -> SpecM a
Files
- hspec-meta.cabal +3/−2
- src/Test/Hspec.hs +2/−1
- src/Test/Hspec/Core/Type.hs +19/−5
- src/Test/Hspec/Formatters/Internal.hs +1/−1
- src/Test/Hspec/Runner.hs +7/−7
- src/Test/Hspec/Runner/Eval.hs +3/−12
- src/Test/Hspec/Runner/Tree.hs +18/−0
hspec-meta.cabal view
@@ -1,5 +1,5 @@ name: hspec-meta-version: 1.10.0+version: 1.11.0 license: MIT license-file: LICENSE copyright: (c) 2011-2014 Simon Hengel,@@ -46,8 +46,8 @@ , HUnit >= 1.2.5 , QuickCheck >= 2.5.1 , quickcheck-io- , async >= 2 , hspec-expectations+ , async >= 2 exposed-modules: Test.Hspec.Meta other-modules:@@ -65,6 +65,7 @@ Test.Hspec.Options Test.Hspec.FailureReport Test.Hspec.Runner.Eval+ Test.Hspec.Runner.Tree Test.Hspec.Formatters.Internal Test.Hspec.Timer
src/Test/Hspec.hs view
@@ -25,6 +25,7 @@ , after , around , parallel+, runIO -- * Running a spec , hspec@@ -40,7 +41,7 @@ -- | Combine a list of specs into a larger spec. describe :: String -> Spec -> Spec-describe label action = fromSpecList [Core.describe label (runSpecM action)]+describe label action = fromSpecList [Core.describe label [BuildSpecs $ runSpecM action]] -- | An alias for `describe`. context :: String -> Spec -> Spec
src/Test/Hspec/Core/Type.hs view
@@ -17,13 +17,16 @@ , it , forceResult +, runIO+ , pending , pendingWith ) where import qualified Control.Exception as E import Control.Applicative-import Control.Monad.Trans.Writer (Writer, execWriter, tell)+import Control.Monad.Trans.Writer+import Control.Monad.IO.Class (liftIO) import Data.Typeable (Typeable) import Data.List (isPrefixOf) import Data.Maybe (fromMaybe)@@ -43,17 +46,26 @@ type Spec = SpecM () -- | A writer monad for `SpecTree` forests.-newtype SpecM a = SpecM (Writer [SpecTree] a)+newtype SpecM a = SpecM (WriterT [SpecTree] IO a) deriving (Functor, Applicative, Monad) -- | Convert a `Spec` to a forest of `SpecTree`s.-runSpecM :: Spec -> [SpecTree]-runSpecM (SpecM specs) = execWriter specs+runSpecM :: Spec -> IO [SpecTree]+runSpecM (SpecM specs) = execWriterT specs -- | Create a `Spec` from a forest of `SpecTree`s. fromSpecList :: [SpecTree] -> Spec fromSpecList = SpecM . tell +-- | Run an IO action while constructing the spec tree.+--+-- `SpecM` is a monad to construct a spec tree, without executing any spec+-- items. `runIO` allows you to run IO actions during this construction phase.+-- The IO action is always run when the spec tree is constructed (e.g. even+-- when @--dry-run@ is specified).+runIO :: IO a -> SpecM a+runIO = SpecM . liftIO+ -- | The result of running an example. data Result = Success | Pending (Maybe String) | Fail String deriving (Eq, Show, Read, Typeable)@@ -77,6 +89,7 @@ -- | Internal representation of a spec. data SpecTree = SpecGroup String [SpecTree]+ | BuildSpecs (IO [SpecTree]) | SpecItem String Item data Item = Item {@@ -85,11 +98,12 @@ } mapSpecItem :: (Item -> Item) -> Spec -> Spec-mapSpecItem f = fromSpecList . map go . runSpecM+mapSpecItem f = fromSpecList . return . BuildSpecs . fmap (map go) . runSpecM where go :: SpecTree -> SpecTree go spec = case spec of SpecItem r item -> SpecItem r (f item)+ BuildSpecs es -> BuildSpecs (map go <$> es) SpecGroup d es -> SpecGroup d (map go es) -- | The @describe@ function combines a list of specs into a larger spec.
src/Test/Hspec/Formatters/Internal.hs view
@@ -147,7 +147,7 @@ -- | used to notify the progress of the currently evaluated example ----- NOTE: This is only called when interactive/color mode.+-- /Note/: This is only called when interactive/color mode. , exampleProgress :: Handle -> Path -> Progress -> IO () -- | evaluated after each successful example
src/Test/Hspec/Runner.hs view
@@ -41,23 +41,22 @@ import Test.Hspec.Core.QuickCheckUtil import Test.Hspec.Options (Options(..), ColorMode(..), defaultOptions)+import Test.Hspec.Runner.Tree import Test.Hspec.Runner.Eval -- | Filter specs by given predicate. -- -- The predicate takes a list of "describe" labels and a "requirement".-filterSpecs :: (Path -> Bool) -> [SpecTree] -> [SpecTree]+filterSpecs :: (Path -> Bool) -> [Tree a] -> [Tree a] filterSpecs p = goSpecs [] where- goSpecs :: [String] -> [SpecTree] -> [SpecTree] goSpecs groups = mapMaybe (goSpec groups) - goSpec :: [String] -> SpecTree -> Maybe SpecTree goSpec groups spec = case spec of- SpecItem requirement _ -> guard (p (groups, requirement)) >> return spec- SpecGroup group specs -> case goSpecs (groups ++ [group]) specs of+ Leaf requirement _ -> guard (p (groups, requirement)) >> return spec+ Node group specs -> case goSpecs (groups ++ [group]) specs of [] -> Nothing- xs -> Just (SpecGroup group xs)+ xs -> Just (Node group xs) -- | Run given spec and write a report to `stdout`. -- Exit with `exitFailure` if at least one spec item fails.@@ -115,10 +114,11 @@ | otherwise = spec_ useColor <- doesUseColor h c+ filteredSpec <- maybe id filterSpecs (configFilterPredicate c) <$> toTree spec withHiddenCursor useColor h $ runFormatM useColor (configHtmlOutput c) (configPrintCpuTime c) seed h $ do- runFormatter useColor h c formatter (maybe id filterSpecs (configFilterPredicate c) $ runSpecM spec) `finally_` do+ runFormatter useColor h c formatter filteredSpec `finally_` do failedFormatter formatter footerFormatter formatter
src/Test/Hspec/Runner/Eval.hs view
@@ -10,6 +10,7 @@ import Control.Monad.IO.Class (liftIO) import Test.Hspec.Util+import Test.Hspec.Runner.Tree import Test.Hspec.Core.Type import Test.Hspec.Config import Test.Hspec.Formatters@@ -17,20 +18,10 @@ import Test.Hspec.Timer import Data.Time.Clock.POSIX -data Tree a- = Node !String [Tree a]- | Leaf !String a- deriving (Eq, Show, Functor)--toTree :: SpecTree -> Tree Item-toTree spec = case spec of- SpecGroup label specs -> Node label (map toTree specs)- SpecItem r item -> Leaf r item- type EvalTree = Tree (ProgressCallback -> FormatResult -> IO (FormatM ())) -- | Evaluate all examples of a given spec and produce a report.-runFormatter :: Bool -> Handle -> Config -> Formatter -> [SpecTree] -> FormatM ()+runFormatter :: Bool -> Handle -> Config -> Formatter -> [Tree Item] -> FormatM () runFormatter useColor h c formatter specs_ = do headerFormatter formatter chan <- liftIO newChan@@ -42,7 +33,7 @@ | useColor = every 0.05 $ exampleProgress formatter h | otherwise = return $ \_ _ -> return () - specs = map (fmap (parallelize . fmap (applyNoOpAround . applyParams) . unwrapItem) . toTree) specs_+ specs = map (fmap (parallelize . fmap (applyNoOpAround . applyParams) . unwrapItem)) specs_ unwrapItem :: Item -> (Bool, Params -> (IO () -> IO ()) -> ProgressCallback -> IO Result) unwrapItem (Item isParallelizable e) = (isParallelizable, e)
+ src/Test/Hspec/Runner/Tree.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE DeriveFunctor #-}+module Test.Hspec.Runner.Tree where++import Control.Applicative+import Test.Hspec.Core.Type++data Tree a+ = Node !String [Tree a]+ | Leaf !String a+ deriving (Eq, Show, Functor)++toTree :: Spec -> IO [Tree Item]+toTree spec = concat <$> (runSpecM spec >>= mapM go)+ where+ go x = case x of+ SpecGroup label xs -> return . Node label . concat <$> mapM go xs+ BuildSpecs xs -> concat <$> (xs >>= mapM go)+ SpecItem r item -> return [Leaf r item]