Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ghc-hspec-core for openSUSE:Factory 
checked in at 2021-01-27 18:57:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-hspec-core (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-hspec-core.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-hspec-core"

Wed Jan 27 18:57:46 2021 rev:17 rq:866949 version:2.7.8

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-hspec-core/ghc-hspec-core.changes    
2021-01-20 18:25:48.951425962 +0100
+++ /work/SRC/openSUSE:Factory/.ghc-hspec-core.new.28504/ghc-hspec-core.changes 
2021-01-27 18:57:47.456392176 +0100
@@ -1,0 +2,12 @@
+Mon Jan 18 13:22:00 UTC 2021 - [email protected]
+
+- Update hspec-core to version 2.7.8.
+  Upstream does not provide a change log file.
+
+-------------------------------------------------------------------
+Mon Jan 18 09:07:53 UTC 2021 - [email protected]
+
+- Update hspec-core to version 2.7.7.
+  Upstream does not provide a change log file.
+
+-------------------------------------------------------------------

Old:
----
  hspec-core-2.7.6.tar.gz

New:
----
  hspec-core-2.7.8.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-hspec-core.spec ++++++
--- /var/tmp/diff_new_pack.6zno8s/_old  2021-01-27 18:57:48.364393581 +0100
+++ /var/tmp/diff_new_pack.6zno8s/_new  2021-01-27 18:57:48.368393587 +0100
@@ -19,7 +19,7 @@
 %global pkg_name hspec-core
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        2.7.6
+Version:        2.7.8
 Release:        0
 Summary:        A Testing Framework for Haskell
 License:        MIT

++++++ hspec-core-2.7.6.tar.gz -> hspec-core-2.7.8.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/hspec-core.cabal 
new/hspec-core-2.7.8/hspec-core.cabal
--- old/hspec-core-2.7.6/hspec-core.cabal       2001-09-09 03:46:40.000000000 
+0200
+++ new/hspec-core-2.7.8/hspec-core.cabal       2001-09-09 03:46:40.000000000 
+0200
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:             hspec-core
-version:          2.7.6
+version:          2.7.8
 license:          MIT
 license-file:     LICENSE
 copyright:        (c) 2011-2021 Simon Hengel,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/src/Test/Hspec/Core/Compat.hs 
new/hspec-core-2.7.8/src/Test/Hspec/Core/Compat.hs
--- old/hspec-core-2.7.6/src/Test/Hspec/Core/Compat.hs  2001-09-09 
03:46:40.000000000 +0200
+++ new/hspec-core-2.7.8/src/Test/Hspec/Core/Compat.hs  2001-09-09 
03:46:40.000000000 +0200
@@ -20,6 +20,8 @@
 , atomicWriteIORef
 #endif
 , interruptible
+
+, guarded
 ) where
 
 import           Control.Applicative
@@ -58,6 +60,9 @@
   , sequence
   , sequence_
   , sum
+#if !MIN_VERSION_base(4,6,0)
+  , catch
+#endif
   )
 
 import           Data.Typeable (Typeable, typeOf, typeRepTyCon)
@@ -139,3 +144,6 @@
     MaskedInterruptible   -> unsafeUnmask act
     MaskedUninterruptible -> act
 #endif
+
+guarded :: Alternative m => (a -> Bool) -> a -> m a
+guarded p a = if p a then pure a else empty
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/src/Test/Hspec/Core/Example.hs 
new/hspec-core-2.7.8/src/Test/Hspec/Core/Example.hs
--- old/hspec-core-2.7.6/src/Test/Hspec/Core/Example.hs 2001-09-09 
03:46:40.000000000 +0200
+++ new/hspec-core-2.7.8/src/Test/Hspec/Core/Example.hs 2001-09-09 
03:46:40.000000000 +0200
@@ -4,6 +4,8 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE TypeSynonymInstances #-}
+
+-- NOTE: re-exported from Test.Hspec.Core.Spec
 module Test.Hspec.Core.Example (
   Example (..)
 , Params (..)
@@ -15,6 +17,7 @@
 , ResultStatus (..)
 , Location (..)
 , FailureReason (..)
+, safeEvaluate
 , safeEvaluateExample
 ) where
 
@@ -88,13 +91,7 @@
 instance Exception ResultStatus
 
 safeEvaluateExample :: Example e => e -> Params -> (ActionWith (Arg e) -> IO 
()) -> ProgressCallback -> IO Result
-safeEvaluateExample example params around progress = do
-  r <- safeTry $ forceResult <$> evaluateExample example params around progress
-  return $ case r of
-    Left e | Just result <- fromException e -> Result "" result
-    Left e | Just hunit <- fromException e -> Result "" $ hunitFailureToResult 
Nothing hunit
-    Left e -> Result "" $ Failure Nothing $ Error Nothing e
-    Right result -> result
+safeEvaluateExample example params around progress = safeEvaluate $ 
forceResult <$> evaluateExample example params around progress
   where
     forceResult :: Result -> Result
     forceResult r@(Result info status) = info `deepseq` (forceResultStatus 
status) `seq` r
@@ -105,6 +102,15 @@
       Pending _ m -> m `deepseq` r
       Failure _ m -> m `deepseq` r
 
+safeEvaluate :: IO Result -> IO Result
+safeEvaluate action = do
+  r <- safeTry $ action
+  return $ case r of
+    Left e | Just result <- fromException e -> Result "" result
+    Left e | Just hunit <- fromException e -> Result "" $ hunitFailureToResult 
Nothing hunit
+    Left e -> Result "" $ Failure Nothing $ Error Nothing e
+    Right result -> result
+
 instance Example Result where
   type Arg Result = ()
   evaluateExample e = evaluateExample (\() -> e)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/src/Test/Hspec/Core/Format.hs 
new/hspec-core-2.7.8/src/Test/Hspec/Core/Format.hs
--- old/hspec-core-2.7.6/src/Test/Hspec/Core/Format.hs  2001-09-09 
03:46:40.000000000 +0200
+++ new/hspec-core-2.7.8/src/Test/Hspec/Core/Format.hs  2001-09-09 
03:46:40.000000000 +0200
@@ -20,12 +20,13 @@
 , itemDuration :: Seconds
 , itemInfo :: String
 , itemResult :: Result
-}
+} deriving Show
 
 data Result =
     Success
   | Pending (Maybe String)
   | Failure FailureReason
+  deriving Show
 
 data Format m = Format {
   formatRun :: forall a. m a -> IO a
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/src/Test/Hspec/Core/Hooks.hs 
new/hspec-core-2.7.8/src/Test/Hspec/Core/Hooks.hs
--- old/hspec-core-2.7.6/src/Test/Hspec/Core/Hooks.hs   2001-09-09 
03:46:40.000000000 +0200
+++ new/hspec-core-2.7.8/src/Test/Hspec/Core/Hooks.hs   2001-09-09 
03:46:40.000000000 +0200
@@ -1,3 +1,4 @@
+{-# LANGUAGE ScopedTypeVariables #-}
 -- | Stability: provisional
 module Test.Hspec.Core.Hooks (
   before
@@ -13,10 +14,17 @@
 , around
 , around_
 , aroundWith
+, aroundAll
+, aroundAll_
+, aroundAllWith
 ) where
 
-import           Control.Exception (SomeException, finally, throwIO, try)
+import           Prelude ()
+import           Test.Hspec.Core.Compat
+
+import           Control.Exception (SomeException, finally, throwIO, try, 
catch)
 import           Control.Concurrent.MVar
+import           Control.Concurrent.Async
 
 import           Test.Hspec.Core.Example
 import           Test.Hspec.Core.Tree
@@ -98,3 +106,60 @@
 modifyAroundAction :: (ActionWith a -> ActionWith b) -> Item a -> Item b
 modifyAroundAction action item@Item{itemExample = e} =
   item{ itemExample = \params aroundAction -> e params (aroundAction . action) 
}
+
+-- | Wrap an action around the given spec.
+aroundAll :: (ActionWith a -> IO ()) -> SpecWith a -> Spec
+aroundAll action = aroundAllWith $ \ e () -> action e
+
+-- | Wrap an action around the given spec.
+aroundAll_ :: (IO () -> IO ()) -> SpecWith a -> SpecWith a
+aroundAll_ action spec = do
+  allSpecItemsDone <- runIO newEmptyMVar
+  workerRef <- runIO newEmptyMVar
+  let
+    acquire :: IO ()
+    acquire = do
+      resource <- newEmptyMVar
+      worker <- async $ do
+        action $ do
+          signal resource
+          waitFor allSpecItemsDone
+      putMVar workerRef worker
+      unwrapExceptionsFromLinkedThread $ do
+        link worker
+        waitFor resource
+    release :: IO ()
+    release = signal allSpecItemsDone >> takeMVar workerRef >>= wait
+  beforeAll_ acquire $ afterAll_ release spec
+
+-- | Wrap an action around the given spec. Changes the arg type inside.
+aroundAllWith :: forall a b. (ActionWith a -> ActionWith b) -> SpecWith a -> 
SpecWith b
+aroundAllWith action spec = do
+  allSpecItemsDone <- runIO newEmptyMVar
+  workerRef <- runIO newEmptyMVar
+  let
+    acquire :: b -> IO a
+    acquire b = do
+      resource <- newEmptyMVar
+      worker <- async $ do
+        flip action b $ \ a -> do
+          putMVar resource a
+          waitFor allSpecItemsDone
+      putMVar workerRef worker
+      unwrapExceptionsFromLinkedThread $ do
+        link worker
+        takeMVar resource
+    release :: IO ()
+    release = signal allSpecItemsDone >> takeMVar workerRef >>= wait
+  beforeAllWith acquire $ afterAll_ release spec
+
+unwrapExceptionsFromLinkedThread :: IO a -> IO a
+unwrapExceptionsFromLinkedThread = (`catch` \ (ExceptionInLinkedThread _ e) -> 
throwIO e)
+
+type BinarySemaphore = MVar ()
+
+signal :: BinarySemaphore -> IO ()
+signal = flip putMVar ()
+
+waitFor :: BinarySemaphore -> IO ()
+waitFor = takeMVar
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/src/Test/Hspec/Core/Runner/Eval.hs 
new/hspec-core-2.7.8/src/Test/Hspec/Core/Runner/Eval.hs
--- old/hspec-core-2.7.6/src/Test/Hspec/Core/Runner/Eval.hs     2001-09-09 
03:46:40.000000000 +0200
+++ new/hspec-core-2.7.8/src/Test/Hspec/Core/Runner/Eval.hs     2001-09-09 
03:46:40.000000000 +0200
@@ -14,6 +14,7 @@
 , EvalTree
 , EvalItem(..)
 , runFormatter
+, resultItemIsFailure
 #ifdef TEST
 , runSequentially
 #endif
@@ -40,6 +41,7 @@
 import qualified Test.Hspec.Core.Format as Format
 import           Test.Hspec.Core.Clock
 import           Test.Hspec.Core.Example.Location
+import           Test.Hspec.Core.Example (safeEvaluate)
 
 -- for compatibility with GHC < 7.10.1
 type Monad m = (Functor m, Applicative m, M.Monad m)
@@ -53,31 +55,20 @@
 
 data State m = State {
   stateConfig :: EvalConfig m
-, stateSuccessCount :: Int
-, statePendingCount :: Int
-, stateFailures :: [Path]
+, stateResults :: [(Path, Format.Item)]
 }
 
 type EvalM m = StateT (State m) m
 
-increaseSuccessCount :: Monad m => EvalM m ()
-increaseSuccessCount = modify $ \state -> state {stateSuccessCount = 
stateSuccessCount state + 1}
-
-increasePendingCount :: Monad m => EvalM m ()
-increasePendingCount = modify $ \state -> state {statePendingCount = 
statePendingCount state + 1}
-
-addFailure :: Monad m => Path -> EvalM m ()
-addFailure path = modify $ \state -> state {stateFailures = path : 
stateFailures state}
+addResult :: Monad m => Path -> Format.Item -> EvalM m ()
+addResult path item = modify $ \ state -> state {stateResults = (path, item) : 
stateResults state}
 
 getFormat :: Monad m => (Format m -> a) -> EvalM m a
 getFormat format = gets (format . evalConfigFormat . stateConfig)
 
 reportItem :: Monad m => Path -> Format.Item -> EvalM m ()
 reportItem path item = do
-  case Format.itemResult item of
-    Format.Success {} -> increaseSuccessCount
-    Format.Pending {} -> increasePendingCount
-    Format.Failure {} -> addFailure path
+  addResult path item
   format <- getFormat formatItem
   lift (format path item)
 
@@ -113,10 +104,10 @@
 type EvalTree = Tree (IO ()) EvalItem
 
 runEvalM :: Monad m => EvalConfig m -> EvalM m () -> m (State m)
-runEvalM config action = execStateT action (State config 0 0 [])
+runEvalM config action = execStateT action (State config [])
 
 -- | Evaluate all examples of a given spec and produce a report.
-runFormatter :: forall m. MonadIO m => EvalConfig m -> [EvalTree] -> IO (Int, 
[Path])
+runFormatter :: forall m. MonadIO m => EvalConfig m -> [EvalTree] -> IO 
([(Path, Format.Item)])
 runFormatter config specs = do
   let
     start = parallelizeTree (evalConfigConcurrentJobs config) specs
@@ -126,10 +117,7 @@
       state <- formatRun format $ do
         runEvalM config $
           run $ map (fmap (fmap (. reportProgress timer) . snd)) runningSpecs
-      let
-        failures = stateFailures state
-        total = stateSuccessCount state + statePendingCount state + length 
failures
-      return (total, reverse failures)
+      return (reverse $ stateResults state)
   where
     format = evalConfigFormat config
 
@@ -223,8 +211,10 @@
 
     runCleanup :: [String] -> IO () -> EvalM m ()
     runCleanup groups action = do
-      (dt, r) <- liftIO $ measure $ safeTry action
-      either (\ e -> reportItem path . failureItem (extractLocation e) dt "" . 
Error Nothing $ e) return r
+      r <- liftIO $ measure $ safeEvaluate (action >> return (Result "" 
Success))
+      case r of
+        (_, Result "" Success) -> return ()
+        _ -> reportResult path Nothing r
       where
         path = (groups, "afterAll-hook")
 
@@ -260,9 +250,18 @@
 sequenceActions :: Monad m => Bool -> [EvalM m ()] -> EvalM m ()
 sequenceActions fastFail = go
   where
+    go :: Monad m => [EvalM m ()] -> EvalM m ()
     go [] = return ()
     go (action : actions) = do
-      () <- action
-      hasFailures <- (not . null) <$> gets stateFailures
+      action
+      hasFailures <- any resultItemIsFailure <$> gets stateResults
       let stopNow = fastFail && hasFailures
       unless stopNow (go actions)
+
+resultItemIsFailure :: (Path, Format.Item) -> Bool
+resultItemIsFailure = isFailure . Format.itemResult . snd
+  where
+    isFailure r = case r of
+      Format.Success{} -> False
+      Format.Pending{} -> False
+      Format.Failure{} -> True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/src/Test/Hspec/Core/Runner.hs 
new/hspec-core-2.7.8/src/Test/Hspec/Core/Runner.hs
--- old/hspec-core-2.7.6/src/Test/Hspec/Core/Runner.hs  2001-09-09 
03:46:40.000000000 +0200
+++ new/hspec-core-2.7.8/src/Test/Hspec/Core/Runner.hs  2001-09-09 
03:46:40.000000000 +0200
@@ -28,6 +28,7 @@
 
 #ifdef TEST
 , rerunAll
+, specToEvalForest
 #endif
 ) where
 
@@ -57,26 +58,19 @@
 
 import           Test.Hspec.Core.Runner.Eval
 
-filterSpecs :: Config -> [EvalTree] -> [EvalTree]
-filterSpecs c = go []
+applyFilterPredicates :: Config -> [EvalTree] -> [EvalTree]
+applyFilterPredicates c = filterForestWithLabels p
   where
-    p :: Path -> Bool
-    p path = (fromMaybe (const True) (configFilterPredicate c) path) &&
-               not (fromMaybe (const False) (configSkipPredicate c) path)
-
-    go :: [String] -> [EvalTree] -> [EvalTree]
-    go groups = mapMaybe (goSpec groups)
-
-    goSpecs :: [String] -> [EvalTree] -> ([EvalTree] -> b) -> Maybe b
-    goSpecs groups specs ctor = case go groups specs of
-      [] -> Nothing
-      xs -> Just (ctor xs)
-
-    goSpec :: [String] -> EvalTree -> Maybe (EvalTree)
-    goSpec groups spec = case spec of
-      Leaf item -> guard (p (groups, evalItemDescription item)) >> return spec
-      Node group specs -> goSpecs (groups ++ [group]) specs (Node group)
-      NodeWithCleanup action specs -> goSpecs groups specs (NodeWithCleanup 
action)
+    include :: Path -> Bool
+    include = fromMaybe (const True) (configFilterPredicate c)
+
+    skip :: Path -> Bool
+    skip = fromMaybe (const False) (configSkipPredicate c)
+
+    p :: [String] -> EvalItem -> Bool
+    p groups item = include path && not (skip path)
+      where
+        path = (groups, evalItemDescription item)
 
 applyDryRun :: Config -> [EvalTree] -> [EvalTree]
 applyDryRun c
@@ -203,6 +197,7 @@
 
 runSpec_ :: Config -> Spec -> IO Summary
 runSpec_ config spec = do
+  filteredSpec <- specToEvalForest config spec
   withHandle config $ \h -> do
     let formatter = fromMaybe specdoc (configFormatter config)
         seed = (fromJust . configQuickCheckSeed) config
@@ -214,16 +209,7 @@
 
     useColor <- doesUseColor h config
 
-    let
-      focusedSpec = focusSpec config (failFocusedItems config spec)
-      params = Params (configQuickCheckArgs config) (configSmallCheckDepth 
config)
-      randomize
-        | configRandomize config = randomizeForest seed
-        | otherwise = id
-
-    filteredSpec <- randomize . filterSpecs config . applyDryRun config . 
toEvalForest params <$> runSpecM focusedSpec
-
-    (total, failures) <- withHiddenCursor useColor h $ do
+    results <- withHiddenCursor useColor h $ do
       let
         formatConfig = FormatConfig {
           formatConfigHandle = h
@@ -240,8 +226,25 @@
         }
       runFormatter evalConfig filteredSpec
 
-    dumpFailureReport config seed qcArgs failures
-    return (Summary total (length failures))
+    let failures = filter resultItemIsFailure results
+
+    dumpFailureReport config seed qcArgs (map fst failures)
+
+    return Summary {
+      summaryExamples = length results
+    , summaryFailures = length failures
+    }
+
+specToEvalForest :: Config -> Spec -> IO [EvalTree]
+specToEvalForest config spec = do
+  let
+    seed = (fromJust . configQuickCheckSeed) config
+    focusedSpec = focusSpec config (failFocusedItems config spec)
+    params = Params (configQuickCheckArgs config) (configSmallCheckDepth 
config)
+    randomize
+      | configRandomize config = randomizeForest seed
+      | otherwise = id
+  randomize . pruneForest . applyFilterPredicates config . applyDryRun config 
. toEvalForest params <$> runSpecM focusedSpec
 
 toEvalForest :: Params -> [SpecTree ()] -> [EvalTree]
 toEvalForest params = bimapForest withUnit toEvalItem . filterForest 
itemIsFocused
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/src/Test/Hspec/Core/Spec/Monad.hs 
new/hspec-core-2.7.8/src/Test/Hspec/Core/Spec/Monad.hs
--- old/hspec-core-2.7.6/src/Test/Hspec/Core/Spec/Monad.hs      2001-09-09 
03:46:40.000000000 +0200
+++ new/hspec-core-2.7.8/src/Test/Hspec/Core/Spec/Monad.hs      2001-09-09 
03:46:40.000000000 +0200
@@ -1,4 +1,6 @@
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+-- NOTE: re-exported from Test.Hspec.Core.Spec
 module Test.Hspec.Core.Spec.Monad (
   Spec
 , SpecWith
@@ -49,11 +51,11 @@
 runIO :: IO r -> SpecM a r
 runIO = SpecM . liftIO
 
-mapSpecTree :: (SpecTree a -> SpecTree b) -> SpecM a r -> SpecM b r
-mapSpecTree f (SpecM specs) = SpecM (mapWriterT (fmap (second (map f))) specs)
+mapSpecForest :: ([SpecTree a] -> [SpecTree b]) -> SpecM a r -> SpecM b r
+mapSpecForest f (SpecM specs) = SpecM (mapWriterT (fmap (second f)) specs)
 
 mapSpecItem :: (ActionWith a -> ActionWith b) -> (Item a -> Item b) -> 
SpecWith a -> SpecWith b
-mapSpecItem g f = mapSpecTree (bimapTree g f)
+mapSpecItem g f = mapSpecForest (bimapForest g f)
 
 mapSpecItem_ :: (Item a -> Item a) -> SpecWith a -> SpecWith a
 mapSpecItem_ = mapSpecItem id
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/src/Test/Hspec/Core/Tree.hs 
new/hspec-core-2.7.8/src/Test/Hspec/Core/Tree.hs
--- old/hspec-core-2.7.6/src/Test/Hspec/Core/Tree.hs    2001-09-09 
03:46:40.000000000 +0200
+++ new/hspec-core-2.7.8/src/Test/Hspec/Core/Tree.hs    2001-09-09 
03:46:40.000000000 +0200
@@ -4,8 +4,7 @@
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE ConstraintKinds #-}
 
--- |
--- Stability: unstable
+-- NOTE: re-exported from Test.Hspec.Core.Spec
 module Test.Hspec.Core.Tree (
   SpecTree
 , Tree (..)
@@ -16,6 +15,10 @@
 , bimapForest
 , filterTree
 , filterForest
+, filterTreeWithLabels
+, filterForestWithLabels
+, pruneTree
+, pruneForest
 , location
 ) where
 
@@ -49,14 +52,37 @@
       NodeWithCleanup cleanup xs -> NodeWithCleanup (g cleanup) (map go xs)
       Leaf item -> Leaf (f item)
 
+filterTree :: (a -> Bool) -> Tree c a -> Maybe (Tree c a)
+filterTree = filterTreeWithLabels . const
+
 filterForest :: (a -> Bool) -> [Tree c a] -> [Tree c a]
-filterForest = mapMaybe . filterTree
+filterForest = filterForestWithLabels . const
 
-filterTree :: (a -> Bool) -> Tree c a -> Maybe (Tree c a)
-filterTree p t = case t of
-  Node s xs -> Just $ Node s (filterForest p xs)
-  NodeWithCleanup c xs -> Just $ NodeWithCleanup c (filterForest p xs)
-  leaf@(Leaf a) -> guard (p a) >> return leaf
+filterTreeWithLabels :: ([String] -> a -> Bool) -> Tree c a -> Maybe (Tree c a)
+filterTreeWithLabels = filterTree_ []
+
+filterForestWithLabels :: ([String] -> a -> Bool) -> [Tree c a] -> [Tree c a]
+filterForestWithLabels = filterForest_ []
+
+filterForest_ :: [String] -> ([String] -> a -> Bool) -> [Tree c a] -> [Tree c 
a]
+filterForest_ groups = mapMaybe . filterTree_ groups
+
+filterTree_ :: [String] -> ([String] -> a -> Bool) -> Tree c a -> Maybe (Tree 
c a)
+filterTree_ groups p tree = case tree of
+  Node group xs -> Just $ Node group $ filterForest_ (groups ++ [group]) p xs
+  NodeWithCleanup action xs -> Just $ NodeWithCleanup action $ filterForest_ 
groups p xs
+  Leaf item -> Leaf <$> guarded (p groups) item
+
+pruneForest :: [Tree c a] -> [Tree c a]
+pruneForest = mapMaybe pruneTree
+
+pruneTree :: Tree c a -> Maybe (Tree c a)
+pruneTree node = case node of
+  Node group xs -> Node group <$> prune xs
+  NodeWithCleanup action xs -> NodeWithCleanup action <$> prune xs
+  Leaf{} -> Just node
+  where
+    prune = guarded (not . null) . pruneForest
 
 -- |
 -- @Item@ is used to represent spec items internally.  A spec item consists of:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/test/Helper.hs 
new/hspec-core-2.7.8/test/Helper.hs
--- old/hspec-core-2.7.6/test/Helper.hs 2001-09-09 03:46:40.000000000 +0200
+++ new/hspec-core-2.7.8/test/Helper.hs 2001-09-09 03:46:40.000000000 +0200
@@ -18,6 +18,7 @@
 , ignoreExitCode
 , ignoreUserInterrupt
 , throwException
+, throwException_
 
 , withEnvironment
 , inTempDirectory
@@ -41,14 +42,17 @@
 import           System.Directory
 import           System.IO.Temp
 
-import           Test.Hspec.Meta hiding (hspec, hspecResult)
+import           Test.Hspec.Meta hiding (hspec, hspecResult, pending, 
pendingWith)
 import           Test.QuickCheck hiding (Result(..))
+import qualified Test.HUnit.Lang as HUnit
 
 import qualified Test.Hspec.Core.Spec as H
 import qualified Test.Hspec.Core.Runner as H
 import           Test.Hspec.Core.QuickCheckUtil (mkGen)
 import           Test.Hspec.Core.Clock
-import           Test.Hspec.Core.Example(Result(..), ResultStatus(..), 
FailureReason(..))
+import           Test.Hspec.Core.Example (Result(..), ResultStatus(..), 
FailureReason(..))
+import           Test.Hspec.Core.Util
+import qualified Test.Hspec.Core.Format as Format
 
 #if !MIN_VERSION_base(4,7,0)
 deriving instance Eq ErrorCall
@@ -58,18 +62,24 @@
 exceptionEq a b
   | Just ea <- E.fromException a, Just eb <- E.fromException b = ea == (eb :: 
E.ErrorCall)
   | Just ea <- E.fromException a, Just eb <- E.fromException b = ea == (eb :: 
E.ArithException)
-  | otherwise = undefined
+  | otherwise = throw (HUnit.HUnitFailure Nothing $ HUnit.ExpectedButGot 
Nothing (formatException b) (formatException a))
 
 deriving instance Eq FailureReason
 deriving instance Eq ResultStatus
 deriving instance Eq Result
 
+deriving instance Eq Format.Result
+deriving instance Eq Format.Item
+
 instance Eq SomeException where
   (==) = exceptionEq
 
-throwException :: IO ()
+throwException :: IO a
 throwException = E.throwIO DivideByZero
 
+throwException_ :: IO ()
+throwException_ = throwException
+
 ignoreExitCode :: IO () -> IO ()
 ignoreExitCode action = action `E.catch` \e -> let _ = e :: ExitCode in return 
()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/test/Test/Hspec/Core/HooksSpec.hs 
new/hspec-core-2.7.8/test/Test/Hspec/Core/HooksSpec.hs
--- old/hspec-core-2.7.6/test/Test/Hspec/Core/HooksSpec.hs      2001-09-09 
03:46:40.000000000 +0200
+++ new/hspec-core-2.7.8/test/Test/Hspec/Core/HooksSpec.hs      2001-09-09 
03:46:40.000000000 +0200
@@ -1,17 +1,40 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 module Test.Hspec.Core.HooksSpec (spec) where
 
-import           Control.Exception
-import           Helper
 import           Prelude ()
+import           Helper
+import           Mock
+
+import           Control.Exception
 
 import qualified Test.Hspec.Core.Runner as H
 import qualified Test.Hspec.Core.Spec as H
+import           Test.Hspec.Core.Format
+import           Test.Hspec.Core.Runner.Eval
 
 import qualified Test.Hspec.Core.Hooks as H
 
-runSilent :: H.Spec -> IO ()
-runSilent = silence . H.hspec
+evalSpec_ :: H.Spec -> IO ()
+evalSpec_ = void . evalSpec
+
+evalSpec :: H.Spec -> IO [([String], Item)]
+evalSpec = fmap normalize . (H.specToEvalForest H.defaultConfig >=> 
runFormatter config)
+  where
+    config = EvalConfig {
+      evalConfigFormat = format
+    , evalConfigConcurrentJobs = 1
+    , evalConfigFastFail = False
+    }
+    format = Format {
+      formatRun = id
+    , formatGroupStarted = \ _ -> return ()
+    , formatGroupDone = \ _ -> return ()
+    , formatProgress = \ _ _ -> return ()
+    , formatItem = \ _ _ -> return ()
+    }
+    normalize = map $ \ (path, item) -> (pathToList path, normalizeItem item)
+    normalizeItem item = item {itemLocation = Nothing, itemDuration = 0}
+    pathToList (xs, x) = xs ++ [x]
 
 mkAppend :: IO (String -> IO (), IO [String])
 mkAppend = do
@@ -24,7 +47,7 @@
   describe "before" $ do
     it "runs an action before every spec item" $ do
       (rec, retrieve) <- mkAppend
-      runSilent $ H.before (rec "before" >> return "value") $ do
+      evalSpec_ $ H.before (rec "before" >> return "value") $ do
         H.it "foo" $ \value -> do
           rec (value ++ " foo")
         H.it "bar" $ \value -> do
@@ -34,14 +57,14 @@
     context "when used with a QuickCheck property" $ do
       it "runs action before every check of the property" $ do
         (rec, retrieve) <- mkAppend
-        runSilent $ H.before (rec "before" >> return "value") $ do
+        evalSpec_ $ H.before (rec "before" >> return "value") $ do
           H.it "foo" $ \value -> property $ \(_ :: Int) -> rec value
         retrieve `shouldReturn` (take 200 . cycle) ["before", "value"]
 
   describe "before_" $ do
     it "runs an action before every spec item" $ do
       (rec, retrieve) <- mkAppend
-      runSilent $ H.before_ (rec "before") $ do
+      evalSpec_ $ H.before_ (rec "before") $ do
         H.it "foo" $ do
           rec "foo"
         H.it "bar" $ do
@@ -51,7 +74,7 @@
     context "when used multiple times" $ do
       it "is evaluated outside in" $ do
         (rec, retrieve) <- mkAppend
-        runSilent $ H.before_ (rec "outer") $ H.before_ (rec "inner") $ do
+        evalSpec_ $ H.before_ (rec "outer") $ H.before_ (rec "inner") $ do
           H.it "foo" $ do
             rec "foo"
         retrieve `shouldReturn` ["outer", "inner", "foo"]
@@ -59,14 +82,14 @@
     context "when used with a QuickCheck property" $ do
       it "runs action before every check of the property" $ do
         (rec, retrieve) <- mkAppend
-        runSilent $ H.before_ (rec "before") $ do
+        evalSpec_ $ H.before_ (rec "before") $ do
           H.it "foo" $ property $ \(_ :: Int) -> rec "foo"
         retrieve `shouldReturn` (take 200 . cycle) ["before", "foo"]
 
       context "when used multiple times" $ do
         it "is evaluated outside in" $ do
           (rec, retrieve) <- mkAppend
-          runSilent $ H.before_ (rec "outer") $ H.before_ (rec "inner") $ do
+          evalSpec_ $ H.before_ (rec "outer") $ H.before_ (rec "inner") $ do
             H.it "foo" $ property $ \(_ :: Int) -> rec "foo"
           retrieve `shouldReturn` (take 300 . cycle) ["outer", "inner", "foo"]
 
@@ -75,7 +98,7 @@
       (rec, retrieve) <- mkAppend
       let action :: Int -> IO String
           action = return . show
-      runSilent $ H.before (return 23) $ H.beforeWith action $ do
+      evalSpec_ $ H.before (return 23) $ H.beforeWith action $ do
         H.it "foo" $ \value -> rec value
       retrieve `shouldReturn` ["23"]
 
@@ -91,7 +114,7 @@
 
       (rec, retrieve) <- mkAppend
 
-      runSilent $ H.before (return 23) $ H.beforeWith action1 $ H.beforeWith 
action2 $ H.beforeWith action3 $ do
+      evalSpec_ $ H.before (return 23) $ H.beforeWith action1 $ H.beforeWith 
action2 $ H.beforeWith action3 $ do
         H.it "foo" $ \value -> rec value
 
       retrieve `shouldReturn` ["foo 24"]
@@ -99,7 +122,7 @@
   describe "beforeAll" $ do
     it "runs an action before the first spec item" $ do
       (rec, retrieve) <- mkAppend
-      runSilent $ H.beforeAll (rec "beforeAll" >> return "value") $ do
+      evalSpec_ $ H.beforeAll (rec "beforeAll" >> return "value") $ do
         H.it "foo" $ \value -> do
           rec $ "foo " ++ value
         H.it "bar" $ \value -> do
@@ -112,24 +135,27 @@
 
     context "when specified action throws an exception" $ do
       it "sets subsequent spec items to pending" $ do
-        result <- silence . H.hspecResult $ H.beforeAll (throwIO (ErrorCall 
"foo")) $ do
+        evalSpec $ H.beforeAll throwException $ do
           H.it "foo" $ \n -> do
             n `shouldBe` (23 :: Int)
           H.it "bar" $ \n -> do
             n `shouldBe` 23
-        result `shouldBe` H.Summary {H.summaryExamples = 2, H.summaryFailures 
= 1}
+        `shouldReturn` [
+          item ["foo"] divideByZero
+        , item ["bar"] (Pending (Just "exception in beforeAll-hook (see 
previous failure)"))
+        ]
 
     context "when used with an empty list of examples" $ do
       it "does not run specified action" $ do
         (rec, retrieve) <- mkAppend
-        runSilent $ H.beforeAll (rec "beforeAll" >> return "value") $ do
+        evalSpec_ $ H.beforeAll (rec "beforeAll" >> return "value") $ do
           return ()
         retrieve `shouldReturn` []
 
   describe "beforeAll_" $ do
     it "runs an action before the first spec item" $ do
       (rec, retrieve) <- mkAppend
-      runSilent $ H.beforeAll_ (rec "beforeAll_") $ do
+      evalSpec_ $ H.beforeAll_ (rec "beforeAll_") $ do
         H.it "foo" $ do
           rec "foo"
         H.it "bar" $ do
@@ -143,7 +169,7 @@
     context "when used multiple times" $ do
       it "is evaluated outside in" $ do
         (rec, retrieve) <- mkAppend
-        runSilent $ H.beforeAll_ (rec "outer") $ H.beforeAll_ (rec "inner") $ 
do
+        evalSpec_ $ H.beforeAll_ (rec "outer") $ H.beforeAll_ (rec "inner") $ 
do
           H.it "foo" $ do
             rec "foo"
           H.it "bar" $ do
@@ -160,7 +186,7 @@
       (rec, retrieve) <- mkAppend
       let action :: Int -> IO String
           action = return . show
-      runSilent $ H.beforeAll (return 23) $ H.beforeAllWith action $ do
+      evalSpec_ $ H.beforeAll (return 23) $ H.beforeAllWith action $ do
         H.it "foo" $ \value -> rec value
       retrieve `shouldReturn` ["23"]
 
@@ -176,7 +202,7 @@
 
       (rec, retrieve) <- mkAppend
 
-      runSilent $ H.beforeAll (return 23) $
+      evalSpec_ $ H.beforeAll (return 23) $
         H.beforeAllWith action1 $ H.beforeAllWith action2 $ H.beforeAllWith 
action3 $ do
           H.it "foo" $ \value -> rec value
 
@@ -184,7 +210,7 @@
 
     it "runs an action before the first spec item" $ do
       (rec, retrieve) <- mkAppend
-      runSilent $ H.beforeAll (return (23 :: Int)) $
+      evalSpec_ $ H.beforeAll (return (23 :: Int)) $
         H.beforeAllWith (\value -> rec "beforeAllWith" >> return (show value)) 
$ do
           H.it "foo" $ \value -> do
             rec $ "foo " ++ value
@@ -198,19 +224,22 @@
 
     context "when specified action throws an exception" $ do
       it "sets subsequent spec items to pending" $ do
-        result <- silence . H.hspecResult $
-          H.beforeAll (return (23 :: Int)) $
-            H.beforeAllWith (\_ -> throwIO (ErrorCall "foo")) $ do
+        evalSpec $ do
+          H.beforeAll (return (23 :: Int)) $ do
+            H.beforeAllWith (\ _ -> throwException) $ do
               H.it "foo" $ \n -> do
                 n `shouldBe` (23 :: Int)
               H.it "bar" $ \n -> do
                 n `shouldBe` 23
-        result `shouldBe` H.Summary {H.summaryExamples = 2, H.summaryFailures 
= 1}
+        `shouldReturn` [
+          item ["foo"] divideByZero
+        , item ["bar"] (Pending (Just "exception in beforeAll-hook (see 
previous failure)"))
+        ]
 
     context "when used with an empty list of examples" $ do
       it "does not run specified action" $ do
         (rec, retrieve) <- mkAppend
-        runSilent $ H.beforeAll (return (23 :: Int)) $
+        evalSpec_ $ H.beforeAll (return (23 :: Int)) $
           H.beforeAllWith (\_ -> rec "beforeAllWith" >> return "value") $ do
             return ()
         retrieve `shouldReturn` []
@@ -218,7 +247,7 @@
   describe "after" $ do
     it "runs an action after every spec item" $ do
       (rec, retrieve) <- mkAppend
-      runSilent $ H.before (rec "before" >> return "from before") $ H.after 
rec $ do
+      evalSpec_ $ H.before (rec "before" >> return "from before") $ H.after 
rec $ do
         H.it "foo" $ \_ -> do
           rec "foo"
         H.it "bar" $ \_ -> do
@@ -234,16 +263,16 @@
 
     it "guarantees that action is run" $ do
       (rec, retrieve) <- mkAppend
-      silence . ignoreExitCode . H.hspec $ H.before (rec "before" >> return 
"from before") $ H.after rec $ do
+      evalSpec_ $ H.before (rec "before" >> return "from before") $ H.after 
rec $ do
         H.it "foo" $ \_ -> do
-          ioError $ userError "foo" :: IO ()
+          throwException_
           rec "foo"
       retrieve `shouldReturn` ["before", "from before"]
 
   describe "after_" $ do
     it "runs an action after every spec item" $ do
       (rec, retrieve) <- mkAppend
-      runSilent $ H.after_ (rec "after") $ do
+      evalSpec_ $ H.after_ (rec "after") $ do
         H.it "foo" $ do
           rec "foo"
         H.it "bar" $ do
@@ -257,16 +286,16 @@
 
     it "guarantees that action is run" $ do
       (rec, retrieve) <- mkAppend
-      silence . ignoreExitCode $ H.hspec $ H.after_ (rec "after") $ do
+      evalSpec_ $ H.after_ (rec "after") $ do
         H.it "foo" $ do
-          ioError $ userError "foo" :: IO ()
+          throwException_
           rec "foo"
       retrieve `shouldReturn` ["after"]
 
     context "when used multiple times" $ do
       it "is evaluated inside out" $ do
         (rec, retrieve) <- mkAppend
-        runSilent $ H.after_ (rec "after outer") $ H.after_ (rec "after 
inner") $ do
+        evalSpec_ $ H.after_ (rec "after outer") $ H.after_ (rec "after 
inner") $ do
           H.it "foo" $ do
             rec "foo"
         retrieve `shouldReturn` [
@@ -278,7 +307,7 @@
   describe "afterAll" $ do
     it "runs an action after the last spec item" $ do
       (rec, retrieve) <- mkAppend
-      runSilent $ H.before (rec "before" >> return "from before") $ H.afterAll 
rec $ do
+      evalSpec_ $ H.before (rec "before" >> return "from before") $ H.afterAll 
rec $ do
         H.it "foo" $ \_ -> do
           rec "foo"
         H.it "bar" $ \_ -> do
@@ -294,21 +323,23 @@
 
     context "when used with an empty list of examples" $ do
       it "does not run specified action" $ do
-        (rec, retrieve) <- mkAppend
-        runSilent $ H.before (rec "before" >> return "from before") $ 
H.afterAll rec $ do
+        evalSpec $ H.before undefined $ H.afterAll undefined $ do
           return ()
-        retrieve `shouldReturn` []
+        `shouldReturn` []
 
     context "when action throws an exception" $ do
       it "reports a failure" $ do
-        r <- runSpec $ H.before (return "from before") $ H.afterAll (\_ -> 
throwException) $ do
+        evalSpec $ H.before (return "from before") $ H.afterAll (\_ -> 
throwException) $ do
           H.it "foo" $ \a -> a `shouldBe` "from before"
-        r `shouldSatisfy` any (== "afterAll-hook FAILED [1]")
+        `shouldReturn` [
+          item ["foo"] Success
+        , item ["afterAll-hook"] divideByZero
+        ]
 
   describe "afterAll_" $ do
     it "runs an action after the last spec item" $ do
       (rec, retrieve) <- mkAppend
-      runSilent $ H.before_ (rec "before") $ H.afterAll_ (rec "afterAll_") $ do
+      evalSpec_ $ H.before_ (rec "before") $ H.afterAll_ (rec "afterAll_") $ do
         H.it "foo" $ do
           rec "foo"
         H.it "bar" $ do
@@ -325,7 +356,7 @@
     context "when used multiple times" $ do
       it "is evaluated inside out" $ do
         (rec, retrieve) <- mkAppend
-        runSilent $ H.afterAll_ (rec "after outer") $ H.afterAll_ (rec "after 
inner") $ do
+        evalSpec_ $ H.afterAll_ (rec "after outer") $ H.afterAll_ (rec "after 
inner") $ do
           H.it "foo" $ do
             rec "foo"
         retrieve `shouldReturn` [
@@ -337,22 +368,44 @@
     context "when used with an empty list of examples" $ do
       it "does not run specified action" $ do
         (rec, retrieve) <- mkAppend
-        runSilent $ H.afterAll_ (rec "afterAll_") $ do
+        evalSpec_ $ H.afterAll_ (rec "afterAll_") $ do
           return ()
         retrieve `shouldReturn` []
 
+    context "when action is pending" $ do
+      it "reports pending" $ do
+        evalSpec $ do
+          H.afterAll_ H.pending $ do
+            H.it "foo" True
+        `shouldReturn` [
+          item ["foo"] Success
+        , item ["afterAll-hook"] (Pending Nothing)
+        ]
+
     context "when action throws an exception" $ do
       it "reports a failure" $ do
-        r <- runSpec $ do
+        evalSpec $ do
           H.afterAll_ throwException $ do
             H.it "foo" True
-        r `shouldSatisfy` any (== "afterAll-hook FAILED [1]")
+        `shouldReturn` [
+          item ["foo"] Success
+        , item ["afterAll-hook"] divideByZero
+        ]
+
+    context "when action is successful" $ do
+      it "does not report anythig" $ do
+        evalSpec $ do
+          H.afterAll_ (return ()) $ do
+            H.it "foo" True
+        `shouldReturn` [
+          item ["foo"] Success
+        ]
 
   describe "around" $ do
     it "wraps every spec item with an action" $ do
       (rec, retrieve) <- mkAppend
       let action e = rec "before" >> e "from around" >> rec "after"
-      runSilent $ H.around action $ do
+      evalSpec_ $ H.around action $ do
         H.it "foo" $ rec . ("foo " ++)
         H.it "bar" $ rec . ("bar " ++)
       retrieve `shouldReturn` [
@@ -368,7 +421,7 @@
     it "wraps every spec item with an action" $ do
       (rec, retrieve) <- mkAppend
       let action e = rec "before" >> e >> rec "after"
-      runSilent $ H.around_ action $ do
+      evalSpec_ $ H.around_ action $ do
         H.it "foo" $ do
           rec "foo"
         H.it "bar" $ do
@@ -387,7 +440,7 @@
         (rec, retrieve) <- mkAppend
         let actionOuter e = rec "before outer" >> e >> rec "after outer"
             actionInner e = rec "before inner" >> e >> rec "after inner"
-        runSilent $ H.around_ actionOuter $ H.around_ actionInner $ do
+        evalSpec_ $ H.around_ actionOuter $ H.around_ actionInner $ do
           H.it "foo" $ do
             rec "foo"
         retrieve `shouldReturn` [
@@ -400,12 +453,122 @@
 
   describe "aroundWith" $ do
     it "wraps every spec item with an action" $ do
+      mock <- newMock
       (rec, retrieve) <- mkAppend
-      let action :: H.ActionWith String -> H.ActionWith Int
-          action e = e . show
-      runSilent $ H.before (return 23) $ H.aroundWith action $ do
+      let action = (. show)
+      evalSpec_ $ H.before (mockAction mock >> mockCounter mock) $ 
H.aroundWith action $ do
         H.it "foo" rec
-      retrieve `shouldReturn` ["23"]
+        H.it "bar" rec
+        H.it "baz" rec
+      retrieve `shouldReturn` [
+          "1"
+        , "2"
+        , "3"
+        ]
+      mockCounter mock `shouldReturn` 3
+
+  describe "aroundAll" $ do
+    it "wraps an action around a spec" $ do
+      (rec, retrieve) <- mkAppend
+      let action e = rec "before" *> e "from around" <* rec "after"
+      evalSpec_ $ H.aroundAll action $ do
+        H.it "foo" $ rec . ("foo " ++)
+        H.it "bar" $ rec . ("bar " ++)
+        H.it "baz" $ rec . ("baz " ++)
+      retrieve `shouldReturn` [
+          "before"
+        , "foo from around"
+        , "bar from around"
+        , "baz from around"
+        , "after"
+        ]
+
+  describe "aroundAll_" $ do
+    it "wraps an action around a spec" $ do
+      (rec, retrieve) <- mkAppend
+      let action inner = rec "before" *> inner <* rec "after"
+      evalSpec_ $ H.aroundAll_ action $ do
+        H.it "foo" $ rec "foo"
+        H.it "bar" $ rec "bar"
+      retrieve `shouldReturn` [
+          "before"
+        , "foo"
+        , "bar"
+        , "after"
+        ]
+
+    it "does not memoize subject" $ do
+      mock <- newMock
+      let action :: IO Int
+          action = mockAction mock >> mockCounter mock
+
+      (rec, retrieve) <- mkAppend
+      evalSpec_ $ H.before action $ H.aroundAll_ id $ do
+        H.it "foo" $ rec . show
+        H.it "bar" $ rec . show
+        H.it "baz" $ rec . show
+      retrieve `shouldReturn` [
+          "1"
+        , "2"
+        , "3"
+        ]
+      mockCounter mock `shouldReturn` 4
+
+    it "reports exceptions on acquire" $ do
+      evalSpec $ do
+        H.aroundAll_ (throwException <*) $ do
+          H.it "foo" True
+      `shouldReturn` [
+        item ["foo"] divideByZero
+      , item ["afterAll-hook"] (Pending (Just "exception in beforeAll-hook 
(see previous failure)"))
+      ]
+
+    it "reports exceptions on release" $ do
+      evalSpec $ do
+        H.aroundAll_ (<* throwException) $ do
+          H.it "foo" True
+      `shouldReturn` [
+        item ["foo"] Success
+      , item ["afterAll-hook"] divideByZero
+      ]
+
+  describe "aroundAllWith" $ do
+    it "wraps an action around a spec" $ do
+      mock <- newMock
+      (rec, retrieve) <- mkAppend
+      let action = (. show)
+      evalSpec_ $ H.before (mockAction mock >> mockCounter mock) $ 
H.aroundAllWith action $ do
+        H.it "foo" rec
+        H.it "bar" rec
+        H.it "baz" rec
+      retrieve `shouldReturn` [
+          "1"
+        , "1"
+        , "1"
+        ]
+      mockCounter mock `shouldReturn` 4
+
+    it "reports exceptions on acquire" $ do
+      evalSpec $ do
+        H.aroundAllWith (\ action () -> throwException >>= action) $ do
+          H.it "foo" H.pending
+      `shouldReturn` [
+        item ["foo"] divideByZero
+      , item ["afterAll-hook"] (Pending (Just "exception in beforeAll-hook 
(see previous failure)"))
+      ]
+
+    it "reports exceptions on release" $ do
+      evalSpec $ do
+        H.aroundAllWith (\ action () -> action () <* throwException) $ do
+          H.it "foo" True
+      `shouldReturn` [
+        item ["foo"] Success
+      , item ["afterAll-hook"] divideByZero
+      ]
+
   where
-    runSpec :: H.Spec -> IO [String]
-    runSpec = captureLines . H.hspecResult
+    divideByZero :: Result
+    divideByZero = Failure (Error Nothing $ toException DivideByZero)
+
+    item :: [String] -> Result -> ([String], Item)
+    item path result = (path, Item Nothing 0 "" result)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/test/Test/Hspec/Core/RunnerSpec.hs 
new/hspec-core-2.7.8/test/Test/Hspec/Core/RunnerSpec.hs
--- old/hspec-core-2.7.6/test/Test/Hspec/Core/RunnerSpec.hs     2001-09-09 
03:46:40.000000000 +0200
+++ new/hspec-core-2.7.8/test/Test/Hspec/Core/RunnerSpec.hs     2001-09-09 
03:46:40.000000000 +0200
@@ -540,7 +540,7 @@
 
     it "treats uncaught exceptions as failure" $ do
       hspecResult_  $ do
-        H.it "foobar" throwException
+        H.it "foobar" throwException_
       `shouldReturn` H.Summary 1 1
 
     it "uses the specdoc formatter by default" $ do
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/test/Test/Hspec/Core/SpecSpec.hs 
new/hspec-core-2.7.8/test/Test/Hspec/Core/SpecSpec.hs
--- old/hspec-core-2.7.6/test/Test/Hspec/Core/SpecSpec.hs       2001-09-09 
03:46:40.000000000 +0200
+++ new/hspec-core-2.7.8/test/Test/Hspec/Core/SpecSpec.hs       2001-09-09 
03:46:40.000000000 +0200
@@ -10,8 +10,8 @@
 
 import qualified Test.Hspec.Core.Spec as H
 
-ignoreCleanup :: Tree c a -> Tree () a
-ignoreCleanup = H.bimapTree (const ()) id
+extract :: (Item () -> a) -> H.Spec -> IO [Tree () a]
+extract f = fmap (H.bimapForest (const ()) f) . runSpecM
 
 runSpec :: H.Spec -> IO [String]
 runSpec = captureLines . H.hspecResult
@@ -91,37 +91,35 @@
 
   describe "focus" $ do
     it "focuses spec items" $ do
-      items <- runSpecM $ H.focus $ do
+      items <- extract itemIsFocused $ H.focus $ do
         H.it "is focused and will run" True
         H.it "is also focused and will also run" True
-      map (ignoreCleanup . fmap itemIsFocused) items
-        `shouldBe` [Leaf True, Leaf True]
+      items `shouldBe` [Leaf True, Leaf True]
 
     context "when applied to a spec with focused spec items" $ do
       it "has no effect" $ do
-        items <- runSpecM $ H.focus $ do
+        items <- extract itemIsFocused $ H.focus $ do
           H.focus $ H.it "is focused and will run" True
           H.it "is not focused and will not run" True
-        map (ignoreCleanup . fmap itemIsFocused) items
-          `shouldBe` [Leaf True, Leaf False]
+        items `shouldBe` [Leaf True, Leaf False]
 
   describe "parallel" $ do
     it "marks examples for parallel execution" $ do
-      [Leaf item] <- runSpecM . H.parallel $ H.it "whatever" H.pending
-      itemIsParallelizable item `shouldBe` Just True
+      items <- extract itemIsParallelizable . H.parallel $ H.it "whatever" 
H.pending
+      items `shouldBe` [Leaf $ Just True]
 
     it "is applied recursively" $ do
-      [Node _ [Node _ [Leaf item]]] <- runSpecM . H.parallel $ do
+      items <- extract itemIsParallelizable . H.parallel $ do
         H.describe "foo" $ do
           H.describe "bar" $ do
             H.it "baz" H.pending
-      itemIsParallelizable item `shouldBe` Just True
+      items `shouldBe` [Node "foo" [Node "bar" [Leaf $ Just True]]]
 
   describe "sequential" $ do
     it "marks examples for sequential execution" $ do
-      [Leaf item] <- runSpecM . H.sequential $ H.it "whatever" H.pending
-      itemIsParallelizable item `shouldBe` Just False
+      items <- extract itemIsParallelizable . H.sequential $ H.it "whatever" 
H.pending
+      items `shouldBe` [Leaf $ Just False]
 
     it "takes precedence over a later `parallel`" $ do
-      [Leaf item] <- runSpecM . H.parallel . H.sequential $ H.it "whatever" 
H.pending
-      itemIsParallelizable item `shouldBe` Just False
+      items <- extract itemIsParallelizable . H.parallel . H.sequential $ H.it 
"whatever" H.pending
+      items `shouldBe` [Leaf $ Just False]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hspec-core-2.7.6/version.yaml 
new/hspec-core-2.7.8/version.yaml
--- old/hspec-core-2.7.6/version.yaml   2001-09-09 03:46:40.000000000 +0200
+++ new/hspec-core-2.7.8/version.yaml   2001-09-09 03:46:40.000000000 +0200
@@ -1 +1 @@
-&version 2.7.6
+&version 2.7.8

Reply via email to