hspec-core 2.7.5 → 2.7.6
raw patch · 9 files changed
+101/−26 lines, 9 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Test.Hspec.Core.Hooks: beforeAllWith :: (b -> IO a) -> SpecWith a -> SpecWith b
+ Test.Hspec.Core.Spec: bimapForest :: (a -> b) -> (c -> d) -> [Tree a c] -> [Tree b d]
+ Test.Hspec.Core.Spec: filterForest :: (a -> Bool) -> [Tree c a] -> [Tree c a]
+ Test.Hspec.Core.Spec: filterTree :: (a -> Bool) -> Tree c a -> Maybe (Tree c a)
Files
- hspec-core.cabal +1/−1
- src/Test/Hspec/Core/Hooks.hs +7/−0
- src/Test/Hspec/Core/Runner.hs +14/−21
- src/Test/Hspec/Core/Spec.hs +1/−1
- src/Test/Hspec/Core/Tree.hs +15/−0
- test/Helper.hs +1/−1
- test/Test/Hspec/Core/HooksSpec.hs +60/−0
- test/Test/Hspec/Core/UtilSpec.hs +1/−1
- version.yaml +1/−1
hspec-core.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: hspec-core-version: 2.7.5+version: 2.7.6 license: MIT license-file: LICENSE copyright: (c) 2011-2021 Simon Hengel,
src/Test/Hspec/Core/Hooks.hs view
@@ -5,6 +5,7 @@ , beforeWith , beforeAll , beforeAll_+, beforeAllWith , after , after_ , afterAll@@ -44,6 +45,12 @@ beforeAll_ action spec = do mvar <- runIO (newMVar Empty) before_ (memoize mvar action) spec++-- | Run a custom action with an argument before the first spec item.+beforeAllWith :: (b -> IO a) -> SpecWith a -> SpecWith b+beforeAllWith action spec = do+ mvar <- runIO (newMVar Empty)+ beforeWith (memoize mvar . action) spec data Memoized a = Empty
src/Test/Hspec/Core/Runner.hs view
@@ -57,9 +57,6 @@ import Test.Hspec.Core.Runner.Eval --- | Filter specs by given predicate.------ The predicate takes a list of "describe" labels and a "requirement". filterSpecs :: Config -> [EvalTree] -> [EvalTree] filterSpecs c = go [] where@@ -81,19 +78,16 @@ Node group specs -> goSpecs (groups ++ [group]) specs (Node group) NodeWithCleanup action specs -> goSpecs groups specs (NodeWithCleanup action) -applyDryRun :: Config -> [SpecTree ()] -> [SpecTree ()]+applyDryRun :: Config -> [EvalTree] -> [EvalTree] applyDryRun c- | configDryRun c = map (removeCleanup . fmap markSuccess)+ | configDryRun c = bimapForest removeCleanup markSuccess | otherwise = id where- markSuccess :: Item () -> Item ()- markSuccess item = item {itemExample = safeEvaluateExample (Result "" Success)}+ removeCleanup :: IO () -> IO ()+ removeCleanup _ = return () - removeCleanup :: SpecTree () -> SpecTree ()- removeCleanup spec = case spec of- Node x xs -> Node x (map removeCleanup xs)- NodeWithCleanup _ xs -> NodeWithCleanup (\() -> return ()) (map removeCleanup xs)- leaf@(Leaf _) -> leaf+ markSuccess :: EvalItem -> EvalItem+ markSuccess item = item {evalItemAction = \ _ -> return $ Result "" Success} -- | Run a given spec and write a report to `stdout`. -- Exit with `exitFailure` if at least one spec item fails.@@ -227,7 +221,7 @@ | configRandomize config = randomizeForest seed | otherwise = id - filteredSpec <- randomize . filterSpecs config . mapMaybe (toEvalTree params) . applyDryRun config <$> runSpecM focusedSpec+ filteredSpec <- randomize . filterSpecs config . applyDryRun config . toEvalForest params <$> runSpecM focusedSpec (total, failures) <- withHiddenCursor useColor h $ do let@@ -249,15 +243,14 @@ dumpFailureReport config seed qcArgs failures return (Summary total (length failures)) -toEvalTree :: Params -> SpecTree () -> Maybe EvalTree-toEvalTree params = go+toEvalForest :: Params -> [SpecTree ()] -> [EvalTree]+toEvalForest params = bimapForest withUnit toEvalItem . filterForest itemIsFocused where- go :: Tree (() -> c) (Item ()) -> Maybe (Tree c EvalItem)- go t = case t of- Node s xs -> Just $ Node s (mapMaybe go xs)- NodeWithCleanup c xs -> Just $ NodeWithCleanup (c ()) (mapMaybe go xs)- Leaf (Item requirement loc isParallelizable isFocused e) ->- guard isFocused >> return (Leaf (EvalItem requirement loc (fromMaybe False isParallelizable) (e params $ ($ ()))))+ toEvalItem :: Item () -> EvalItem+ toEvalItem (Item requirement loc isParallelizable _isFocused e) = EvalItem requirement loc (fromMaybe False isParallelizable) (e params withUnit)++ withUnit :: ActionWith () -> IO ()+ withUnit action = action () dumpFailureReport :: Config -> Integer -> QC.Args -> [Path] -> IO () dumpFailureReport config seed qcArgs xs = do
src/Test/Hspec/Core/Spec.hs view
@@ -108,7 +108,7 @@ let ys | any (any itemIsFocused) xs = xs- | otherwise = map (bimapTree id (\ item -> item {itemIsFocused = True})) xs+ | otherwise = bimapForest id (\ item -> item {itemIsFocused = True}) xs fromSpecList ys -- | @fit@ is an alias for @fmap focus . it@
src/Test/Hspec/Core/Tree.hs view
@@ -13,6 +13,9 @@ , specGroup , specItem , bimapTree+, bimapForest+, filterTree+, filterForest , location ) where @@ -35,6 +38,9 @@ -- over the type of cleanup actions and the type of the actual spec items. type SpecTree a = Tree (ActionWith a) (Item a) +bimapForest :: (a -> b) -> (c -> d) -> [Tree a c] -> [Tree b d]+bimapForest g f = map (bimapTree g f)+ bimapTree :: (a -> b) -> (c -> d) -> Tree a c -> Tree b d bimapTree g f = go where@@ -42,6 +48,15 @@ Node d xs -> Node d (map go xs) NodeWithCleanup cleanup xs -> NodeWithCleanup (g cleanup) (map go xs) Leaf item -> Leaf (f item)++filterForest :: (a -> Bool) -> [Tree c a] -> [Tree c a]+filterForest = mapMaybe . filterTree++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 -- | -- @Item@ is used to represent spec items internally. A spec item consists of:
test/Helper.hs view
@@ -68,7 +68,7 @@ (==) = exceptionEq throwException :: IO ()-throwException = E.throwIO (E.ErrorCall "foobar")+throwException = E.throwIO DivideByZero ignoreExitCode :: IO () -> IO () ignoreExitCode action = action `E.catch` \e -> let _ = e :: ExitCode in return ()
test/Test/Hspec/Core/HooksSpec.hs view
@@ -155,6 +155,66 @@ , "bar" ] + describe "beforeAllWith" $ do+ it "transforms the spec argument" $ do+ (rec, retrieve) <- mkAppend+ let action :: Int -> IO String+ action = return . show+ runSilent $ H.beforeAll (return 23) $ H.beforeAllWith action $ do+ H.it "foo" $ \value -> rec value+ retrieve `shouldReturn` ["23"]++ it "can be used multiple times" $ do+ let action1 :: Int -> IO Int+ action1 = return . succ++ action2 :: Int -> IO String+ action2 = return . show++ action3 :: String -> IO String+ action3 = return . ("foo " ++)++ (rec, retrieve) <- mkAppend++ runSilent $ H.beforeAll (return 23) $+ H.beforeAllWith action1 $ H.beforeAllWith action2 $ H.beforeAllWith action3 $ do+ H.it "foo" $ \value -> rec value++ retrieve `shouldReturn` ["foo 24"]++ it "runs an action before the first spec item" $ do+ (rec, retrieve) <- mkAppend+ runSilent $ H.beforeAll (return (23 :: Int)) $+ H.beforeAllWith (\value -> rec "beforeAllWith" >> return (show value)) $ do+ H.it "foo" $ \value -> do+ rec $ "foo " ++ value+ H.it "bar" $ \value -> do+ rec $ "bar " ++ value+ retrieve `shouldReturn` [+ "beforeAllWith"+ , "foo 23"+ , "bar 23"+ ]++ 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+ 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}++ 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)) $+ H.beforeAllWith (\_ -> rec "beforeAllWith" >> return "value") $ do+ return ()+ retrieve `shouldReturn` []+ describe "after" $ do it "runs an action after every spec item" $ do (rec, retrieve) <- mkAppend
test/Test/Hspec/Core/UtilSpec.hs view
@@ -49,7 +49,7 @@ it "returns Left on exception" $ do Left e <- safeTry throwException- show e `shouldBe` "foobar"+ E.fromException e `shouldBe` Just E.DivideByZero it "evaluates result to weak head normal form" $ do Left e <- safeTry (return $ E.throw $ E.ErrorCall "foo")
version.yaml view
@@ -1,1 +1,1 @@-&version 2.7.5+&version 2.7.6