hspec-core 2.5.2 → 2.5.3
raw patch · 8 files changed
+127/−32 lines, 8 files
Files
- hspec-core.cabal +2/−2
- src/Test/Hspec/Core/Formatters/Diff.hs +59/−2
- src/Test/Hspec/Core/Spec/Monad.hs +3/−3
- src/Test/Hspec/Core/Util.hs +1/−1
- test/Helper.hs +1/−1
- test/Test/Hspec/Core/Formatters/DiffSpec.hs +27/−2
- test/Test/Hspec/Core/RunnerSpec.hs +29/−21
- test/Test/Hspec/Core/UtilSpec.hs +5/−0
hspec-core.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: a6145f4a8f01c6344cd3a210ae77832823ae24ae25509d889b47e91d85661e2c+-- hash: c6552ddea76009fa34e130109e1d7e036f4790640cc908c42633598692cc0c24 name: hspec-core-version: 2.5.2+version: 2.5.3 license: MIT license-file: LICENSE copyright: (c) 2011-2018 Simon Hengel,
src/Test/Hspec/Core/Formatters/Diff.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE ViewPatterns #-} module Test.Hspec.Core.Formatters.Diff ( Diff (..) , diff@@ -8,17 +9,21 @@ #endif ) where +import Prelude ()+import Test.Hspec.Core.Compat+ import Data.Char+import Data.List (stripPrefix) import Data.Algorithm.Diff diff :: String -> String -> [Diff String] diff expected actual = map (fmap concat) $ getGroupedDiff (partition expected) (partition actual) partition :: String -> [String]-partition = mergeBackslashes . breakList isAlphaNum+partition = filter (not . null) . mergeBackslashes . breakList isAlphaNum where mergeBackslashes xs = case xs of- ['\\'] : (y : ys) : zs -> ['\\', y] : ys : mergeBackslashes zs+ ['\\'] : (splitEscape -> Just (escape, ys)) : zs -> ("\\" ++ escape) : ys : mergeBackslashes zs z : zs -> z : mergeBackslashes zs [] -> [] @@ -31,3 +36,55 @@ cons x | null x = id | otherwise = (x :)++splitEscape :: String -> Maybe (String, String)+splitEscape xs = splitNumericEscape xs <|> (msum $ map split escapes)+ where+ split :: String -> Maybe (String, String)+ split escape = (,) escape <$> stripPrefix escape xs++splitNumericEscape :: String -> Maybe (String, String)+splitNumericEscape xs = case span isDigit xs of+ ("", _) -> Nothing+ r -> Just r++escapes :: [String]+escapes = [+ "ACK"+ , "CAN"+ , "DC1"+ , "DC2"+ , "DC3"+ , "DC4"+ , "DEL"+ , "DLE"+ , "ENQ"+ , "EOT"+ , "ESC"+ , "ETB"+ , "ETX"+ , "NAK"+ , "NUL"+ , "SOH"+ , "STX"+ , "SUB"+ , "SYN"+ , "EM"+ , "FS"+ , "GS"+ , "RS"+ , "SI"+ , "SO"+ , "US"+ , "a"+ , "b"+ , "f"+ , "n"+ , "r"+ , "t"+ , "v"+ , "&"+ , "'"+ , "\""+ , "\\"+ ]
src/Test/Hspec/Core/Spec/Monad.hs view
@@ -7,7 +7,6 @@ , fromSpecList , runIO -, mapSpecTree , mapSpecItem , mapSpecItem_ , modifyParams@@ -16,6 +15,7 @@ import Prelude () import Test.Hspec.Core.Compat +import Control.Arrow import Control.Monad.Trans.Writer import Control.Monad.IO.Class (liftIO) @@ -49,8 +49,8 @@ runIO :: IO r -> SpecM a r runIO = SpecM . liftIO -mapSpecTree :: (SpecTree a -> SpecTree b) -> SpecWith a -> SpecWith b-mapSpecTree f spec = runIO (runSpecM spec) >>= fromSpecList . map f+mapSpecTree :: (SpecTree a -> SpecTree b) -> SpecM a r -> SpecM b r+mapSpecTree f (SpecM specs) = SpecM (mapWriterT (fmap (second (map f))) specs) mapSpecItem :: (ActionWith a -> ActionWith b) -> (Item a -> Item b) -> SpecWith a -> SpecWith b mapSpecItem g f = mapSpecTree go
src/Test/Hspec/Core/Util.hs view
@@ -87,7 +87,7 @@ pattern `isInfixOf` plain || pattern `isInfixOf` formatted where- plain = intercalate "/" (groups ++ [requirement])+ plain = "/" ++ intercalate "/" (groups ++ [requirement]) ++ "/" formatted = formatRequirement path -- | The function `formatException` converts an exception to a string.
test/Helper.hs view
@@ -41,7 +41,7 @@ import System.Directory import System.IO.Temp -import Test.Hspec.Meta+import Test.Hspec.Meta hiding (hspec, hspecResult) import Test.QuickCheck hiding (Result(..)) import qualified Test.Hspec.Core.Spec as H
test/Test/Hspec/Core/Formatters/DiffSpec.hs view
@@ -1,15 +1,40 @@+{-# LANGUAGE ScopedTypeVariables #-} module Test.Hspec.Core.Formatters.DiffSpec (spec) where +import Prelude ()+import Test.Hspec.Core.Compat+ import Helper import Data.Char import Test.Hspec.Core.Formatters.Diff +dropQuotes :: String -> String+dropQuotes = init . tail+ spec :: Spec spec = do describe "partition" $ do- it "puts backslash-escaped characters into a separate chunks" $ do- partition (show "foo\nbar") `shouldBe` ["\"", "foo", "\\n", "bar", "\""]+ context "with a single shown Char" $ do+ it "never partitions a character escape" $ do+ property $ \ (c :: Char) -> partition (show c) `shouldBe` ["'", dropQuotes (show c), "'"]++ context "with a shown String" $ do+ it "puts backslash-escaped characters into separate chunks" $ do+ partition (show "foo\nbar") `shouldBe` ["\"", "foo", "\\n", "bar", "\""]++ it "puts *arbitrary* backslash-escaped characters into separate chunks" $ do+ property $ \ xs c ys ->+ let+ char = dropQuotes (show [c])+ isEscaped = length char > 1+ escape = tail char+ sep = case ys of+ x : _ | all isDigit escape && isDigit x || escape == "SO" && x == 'H' -> ["\\&"]+ _ -> []+ actual = partition (show (xs ++ c : ys))+ expected = partition (init $ show xs) ++ [char] ++ sep ++ partition (tail $ show ys)+ in isEscaped ==> actual `shouldBe` expected describe "breakList" $ do context "with a list where the predicate matches at the beginning and the end" $ do
test/Test/Hspec/Core/RunnerSpec.hs view
@@ -44,9 +44,14 @@ spec :: Spec spec = do describe "hspec" $ do++ let+ hspec args = withArgs ("--format=silent" : args) . H.hspec+ hspec_ = hspec []+ it "evaluates examples Unmasked" $ do mvar <- newEmptyMVar- withArgs ["--format", "silent"] . H.hspec $ do+ hspec_ $ do H.it "foo" $ do E.getMaskingState >>= putMVar mvar takeMVar mvar `shouldReturn` E.Unmasked@@ -54,7 +59,7 @@ it "runs finalizers" $ do mvar <- newEmptyMVar ref <- newIORef "did not run finalizer"- a <- async $ withArgs ["--format", "silent"] . H.hspec $ do+ a <- async $ hspec_ $ do H.it "foo" $ do (putMVar mvar () >> threadDelay 10000000) `E.finally` writeIORef ref "ran finalizer"@@ -63,12 +68,12 @@ readIORef ref `shouldReturn` "ran finalizer" it "runs a spec" $ do- silence . H.hspec $ do+ hspec_ $ do H.it "foobar" True `shouldReturn` () it "exits with exitFailure if not all examples pass" $ do- silence . H.hspec $ do+ hspec_ $ do H.it "foobar" False `shouldThrow` (== ExitFailure 1) @@ -87,7 +92,7 @@ ] it "stores a failure report in the environment" $ do- silence . ignoreExitCode . withArgs ["--seed", "23"] . H.hspec $ do+ ignoreExitCode . hspec ["--seed", "23"] $ do H.describe "foo" $ do H.describe "bar" $ do H.it "example 1" True@@ -166,11 +171,10 @@ it "does not leak command-line options to examples" $ do- silence . withArgs ["--verbose"] $ do- H.hspec $ do- H.it "foobar" $ do- getArgs `shouldReturn` []- `shouldReturn` ()+ hspec ["--diff"] $ do+ H.it "foobar" $ do+ getArgs `shouldReturn` []+ `shouldReturn` () context "when interrupted with ctrl-c" $ do it "prints summary immediately" $ do@@ -211,7 +215,7 @@ mvar <- newEmptyMVar sync <- newEmptyMVar threadId <- forkIO $ do- silence . H.hspec $ do+ hspec_ $ do H.it "foo" $ do putMVar sync () threadDelay 1000000@@ -283,7 +287,7 @@ child2 <- newQSem 0 parent <- newQSem 0 ref <- newIORef ""- ignoreExitCode . withArgs ["--fail-fast", "--format=silent", "-j", "2"] . H.hspec $ do+ ignoreExitCode . hspec ["--fail-fast", "-j", "2"] $ do H.parallel $ do H.it "foo" $ do waitQSem child1@@ -329,7 +333,7 @@ e1 <- newMock e2 <- newMock e3 <- newMock- silence . withArgs ["-m", "/bar/example"] . H.hspec $ do+ hspec ["-m", "/bar/example"] $ do H.describe "foo" $ do H.describe "bar" $ do H.it "example 1" $ mockAction e1@@ -343,7 +347,7 @@ e2 <- newMock e3 <- newMock e4 <- newMock- silence . withArgs ["-m", "/bar/example", "--skip", "example 3"] . H.hspec $ do+ hspec ["-m", "/bar/example", "--skip", "example 3"] $ do H.describe "foo" $ do H.describe "bar" $ do H.it "example 1" $ mockAction e1@@ -358,7 +362,7 @@ e1 <- newMock e2 <- newMock e3 <- newMock- silence . withArgs ["-m", "foo", "-m", "baz"] . H.hspec $ do+ hspec ["-m", "foo", "-m", "baz"] $ do H.describe "foo" $ do H.it "example 1" $ mockAction e1 H.describe "bar" $ do@@ -405,7 +409,7 @@ context "with --qc-max-success" $ do it "tries QuickCheck properties specified number of times" $ do m <- newMock- silence . withArgs ["--qc-max-success", "23"] . H.hspec $ do+ hspec ["--qc-max-success", "23"] $ do H.it "foo" $ property $ \(_ :: Int) -> do mockAction m mockCounter m `shouldReturn` 23@@ -471,8 +475,12 @@ r `shouldContain` "<span class=\"hspec-failure\">foo" describe "hspecResult" $ do+ let+ hspecResult args = withArgs ("--format=silent" : args) . H.hspecResult+ hspecResult_ = hspecResult []+ it "returns a summary of the test run" $ do- silence . H.hspecResult $ do+ hspecResult_ $ do H.it "foo" True H.it "foo" False H.it "foo" False@@ -481,7 +489,7 @@ `shouldReturn` H.Summary 5 2 it "treats uncaught exceptions as failure" $ do- silence . H.hspecResult $ do+ hspecResult_ $ do H.it "foobar" throwException `shouldReturn` H.Summary 1 1 @@ -498,7 +506,7 @@ r `shouldBe` "" it "does not let escape error thunks from failure messages" $ do- r <- silence . H.hspecResult $ do+ r <- hspecResult_ $ do H.it "some example" (H.Result "" $ H.Failure Nothing . H.Reason $ "foobar" ++ undefined) r `shouldBe` H.Summary 1 1 @@ -506,7 +514,7 @@ let n = 100 t = 0.01 dt = t * (fromIntegral n / 2)- r <- timeout dt . silence . withArgs ["-j", show n] . H.hspecResult . H.parallel $ do+ r <- timeout dt . hspecResult ["-j", show n] . H.parallel $ do replicateM_ n (H.it "foo" $ sleep t) r `shouldBe` Just (H.Summary n 0) @@ -521,7 +529,7 @@ current <- atomicModifyIORef currentRef $ \x -> let y = succ x in (y, y) atomicModifyIORef highRef $ \x -> (max x current, ()) stop = atomicModifyIORef currentRef $ \x -> (pred x, ())- r <- withArgs ["-j", show j] . H.hspecResult . H.parallel $ do+ r <- hspecResult ["-j", show j] . H.parallel $ do replicateM_ n $ H.it "foo" $ E.bracket_ start stop $ sleep t r `shouldBe` H.Summary n 0 high <- readIORef highRef
test/Test/Hspec/Core/UtilSpec.hs view
@@ -84,6 +84,11 @@ let p = filterPredicate "ModuleA.ModuleB.foo does something" p (["ModuleA", "ModuleB", "foo"], "does something") `shouldBe` True + context "with an absolute path that begins or ends with a slash" $ do+ it "succeeds" $ do+ let p = filterPredicate "/foo/bar/baz/example 1/"+ p (["foo", "bar", "baz"], "example 1") `shouldBe` True+ describe "formatRequirement" $ do it "creates a sentence from a subject and a requirement" $ do formatRequirement (["reverse"], "reverses a list") `shouldBe` "reverse reverses a list"