hspec 2.4.8 → 2.5.0
raw patch · 7 files changed
+33/−222 lines, 7 filesdep ~HUnitdep ~QuickCheckdep ~hspec-corePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: HUnit, QuickCheck, hspec-core, hspec-discover
API changes (from Hackage documentation)
- Test.Hspec.HUnit: fromHUnitTest :: Test -> Spec
- Test.Hspec: pending :: Expectation
+ Test.Hspec: pending :: HasCallStack -> Expectation
- Test.Hspec: pendingWith :: String -> Expectation
+ Test.Hspec: pendingWith :: HasCallStack -> String -> Expectation
Files
- CHANGES.markdown +20/−6
- hspec.cabal +12/−16
- src/Test/Hspec/Discover.hs +1/−65
- src/Test/Hspec/HUnit.hs +0/−24
- test/Helper.hs +0/−19
- test/HelperSpec.hs +0/−18
- test/Test/Hspec/DiscoverSpec.hs +0/−74
CHANGES.markdown view
@@ -1,9 +1,23 @@-## Changes in 2.4.8- - compatibility with GHC 8.4.1-alpha3--## Changes in 2.4.7- - compatibility with `QuickCheck-2.11.3` and up (note that `QuickCheck`- versions `2.11` to `2.11.2` are not fully supported)+## Changes in 2.5.0+ - Add support for `--diff` when `shouldBe` is uesd with+ `QuickCheck`-properties+ - Add source locations when `shouldBe` is uesd with `QuickCheck`-properties+ - Add `sequential` (see #311)+ - Colorize whitespaces with background color instead of foreground color with+ `--diff`+ - Deprecate `--out`+ - Removed deprecated module `Test.Hspec.HUnit`, use+ `Test.Hspec.Contrib.HUnit` instead+ - Run `Test.Hspec.Core.Formatters.exampleProgress` in `FormatM` instead of+ `IO`+ - Print QuickCheck labels on success (see #297)+ - Include column when formatting source locations+ - Extract source location from error / undefined (close #316)+ - Remove BestEffort source locations+ - Include duration for each spec item in new formatter API (see #315)+ - Add location information to `pending`+ - Make sure that progress output is always cleared (fixes #301)+ - Parse source locations from pattern match failures ## Changes in 2.4.6 - compatibility with the upcoming version `4.11.0.0` of `base`
hspec.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 4e6d8536db1ab37d1c42006f33479988a740fc613f7d80c8ac3d2bbc005d2108+-- hash: 5973a094a7e1665acc54acbbf4e2edfaf3caf3f63f400d39fbbd281fa1479892 name: hspec-version: 2.4.8+version: 2.5.0 license: MIT license-file: LICENSE copyright: (c) 2011-2017 Simon Hengel,@@ -45,12 +45,12 @@ hs-source-dirs: src build-depends:- HUnit >=1.2.5- , QuickCheck >=2.5.1+ HUnit >=1.5.0.0+ , QuickCheck >=2.10 , base ==4.* , call-stack- , hspec-core ==2.4.8- , hspec-discover ==2.4.8+ , hspec-core ==2.5.0+ , hspec-discover ==2.5.0 , hspec-expectations ==0.8.2.* , transformers >=0.2.2.0 exposed-modules:@@ -58,7 +58,6 @@ Test.Hspec.Core Test.Hspec.Discover Test.Hspec.Formatters- Test.Hspec.HUnit Test.Hspec.QuickCheck Test.Hspec.Runner other-modules:@@ -71,22 +70,19 @@ hs-source-dirs: test main-is: Spec.hs- other-modules:- Helper- HelperSpec- Test.Hspec.DiscoverSpec- Paths_hspec build-depends:- HUnit >=1.2.5- , QuickCheck >=2.5.1+ HUnit >=1.5.0.0+ , QuickCheck >=2.10 , base ==4.* , call-stack , directory , hspec- , hspec-core ==2.4.8- , hspec-discover ==2.4.8+ , hspec-core ==2.5.0+ , hspec-discover ==2.5.0 , hspec-expectations ==0.8.2.* , hspec-meta >=2.3.2 , stringbuilder , transformers >=0.2.2.0+ other-modules:+ Paths_hspec default-language: Haskell2010
src/Test/Hspec/Discover.hs view
@@ -12,16 +12,10 @@ ) where import Prelude hiding (mapM)-import Control.Applicative-import Data.Maybe-import Data.List-import Data.Traversable-import Control.Monad.Trans.State import Test.Hspec.Core.Spec import Test.Hspec.Core.Runner import Test.Hspec.Formatters-import Test.Hspec.Core.Util (safeTry) class IsFormatter a where toFormatter :: a -> IO Formatter@@ -38,62 +32,4 @@ hspecWith defaultConfig {configFormatter = Just f} spec postProcessSpec :: FilePath -> Spec -> Spec-postProcessSpec = locationHeuristicFromFile--locationHeuristicFromFile :: FilePath -> Spec -> Spec-locationHeuristicFromFile file spec = do- mInput <- either (const Nothing) Just <$> (runIO . safeTry . readFile) file- let lookupLoc = maybe (\_ _ _ -> Nothing) (lookupLocation file) mInput- runIO (runSpecM spec) >>= fromSpecList . addLoctions lookupLoc--addLoctions :: (Int -> Int -> String -> Maybe Location) -> [SpecTree a] -> [SpecTree a]-addLoctions lookupLoc = map (fmap f) . enumerate- where- f :: ((Int, Int), Item a) -> Item a- f ((n, total), item) = item {itemLocation = itemLocation item <|> lookupLoc n total (itemRequirement item)}--type EnumerateM = State [(String, Int)]--enumerate :: [SpecTree a] -> [Tree (ActionWith a) ((Int, Int), (Item a))]-enumerate tree = (mapM (traverse addPosition) tree >>= mapM (traverse addTotal)) `evalState` []- where- addPosition :: Item a -> EnumerateM (Int, Item a)- addPosition item = (,) <$> getOccurrence (itemRequirement item) <*> pure item-- addTotal :: (Int, Item a) -> EnumerateM ((Int, Int), Item a)- addTotal (n, item) = do- total <- getTotal (itemRequirement item)- return ((n, total), item)-- getTotal :: String -> EnumerateM Int- getTotal requirement = do- gets $ fromMaybe err . lookup requirement- where- err = error ("Test.Hspec.Discover.getTotal: No entry for requirement " ++ show requirement ++ "!")-- getOccurrence :: String -> EnumerateM Int- getOccurrence requirement = do- xs <- get- let n = maybe 1 succ (lookup requirement xs)- put ((requirement, n) : filter ((/= requirement) . fst) xs)- return n--lookupLocation :: FilePath -> String -> Int -> Int -> String -> Maybe Location-lookupLocation file input n total requirement = loc- where- loc :: Maybe Location- loc = Location file <$> line <*> pure 0 <*> pure BestEffort-- line :: Maybe Int- line = case occurrences of- xs | length xs == total -> Just (xs !! pred n)- _ -> Nothing-- occurrences :: [Int]- occurrences = map fst (filter p inputLines)- where- p :: (Int, String) -> Bool- p = isInfixOf (show requirement) . snd-- inputLines :: [(Int, String)]- inputLines = zip [1..] (lines input)+postProcessSpec _ = id
− src/Test/Hspec/HUnit.hs
@@ -1,24 +0,0 @@-module Test.Hspec.HUnit {-# DEPRECATED "use \"Test.Hspec.Contrib.HUnit\" from package @hspec-contrib@ instead" #-}-(--- * Interoperability with HUnit- fromHUnitTest-) where--import Test.Hspec.Core.Spec-import Test.HUnit (Test (..))---- |--- Convert a HUnit test suite to a spec. This can be used to run existing--- HUnit tests with Hspec.-fromHUnitTest :: Test -> Spec-fromHUnitTest t = case t of- TestList xs -> mapM_ go xs- x -> go x- where- go :: Test -> Spec- go t_ = case t_ of- TestLabel s (TestCase e) -> it s e- TestLabel s (TestList xs) -> describe s (mapM_ go xs)- TestLabel s x -> describe s (go x)- TestList xs -> describe "<unlabeled>" (mapM_ go xs)- TestCase e -> it "<unlabeled>" e
− test/Helper.hs
@@ -1,19 +0,0 @@-module Helper (- module Test.Hspec.Meta-, withFileContent-) where--import Control.Exception (finally)-import System.Directory-import System.IO-import Test.Hspec.Meta--import Test.Hspec.QuickCheck ()--withFileContent :: String -> (FilePath -> IO a) -> IO a-withFileContent input action = do- dir <- getTemporaryDirectory- (file, h) <- openTempFile dir "temp"- hPutStr h input- hClose h- action file `finally` removeFile file
− test/HelperSpec.hs
@@ -1,18 +0,0 @@-module HelperSpec (main, spec) where--import Helper-import System.IO.Error (isDoesNotExistError)--main :: IO ()-main = hspec spec--spec :: Spec-spec = do- describe "withFileContent" $ do- it "creates a file with specified content and runs specified action" $ do- withFileContent "foo" $ \file -> do- readFile file `shouldReturn` "foo"-- it "removes file after action has been run" $ do- file <- withFileContent "foo" return- readFile file `shouldThrow` isDoesNotExistError
− test/Test/Hspec/DiscoverSpec.hs
@@ -1,74 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# OPTIONS_GHC -fno-warn-deprecations #-}-module Test.Hspec.DiscoverSpec (main, spec) where--import Helper-import Data.String-import Data.String.Builder--import qualified Test.Hspec.Core.Spec as H-import Test.Hspec.Core (Tree(..), Item(..), Location(..), LocationAccuracy(..), runSpecM)-import qualified Test.Hspec.Discover as H--infix 1 `shouldHaveLocation`--shouldHaveLocation :: Item a -> (String, Int) -> Expectation-item `shouldHaveLocation` (src, line) = itemLocation item `shouldBe` Just (Location src line 0 BestEffort)--removeLocations :: H.SpecWith a -> H.SpecWith a-removeLocations = H.mapSpecItem_ (\item -> item{H.itemLocation = Nothing})--main :: IO ()-main = hspec spec--spec :: Spec-spec = do- describe "postProcessSpec" $ do- it "adds heuristic source locations" $ do- let c = build $ do- ""- strlit "foo"- ""- strlit "bar"- ""- strlit "baz"- withFileContent c $ \src -> do- [Leaf item1, Leaf item2, Leaf item3] <- runSpecM . H.postProcessSpec src . removeLocations $ do- H.it "foo" True- H.it "bar" True- H.it "baz" True- item1 `shouldHaveLocation` (src, 2)- item2 `shouldHaveLocation` (src, 4)- item3 `shouldHaveLocation` (src, 6)-- context "when same requirement is used multiple times" $ do- it "assigns locations sequentially" $ do- let c = build $ do- strlit "foo"- strlit "foo"- strlit "foo"- withFileContent c $ \src -> do- [Leaf item1, Leaf item2, Leaf item3] <- runSpecM . H.postProcessSpec src . removeLocations $ do- H.it "foo" True- H.it "foo" True- H.it "foo" True- item1 `shouldHaveLocation` (src, 1)- item2 `shouldHaveLocation` (src, 2)- item3 `shouldHaveLocation` (src, 3)-- context "when a requirement occurs more often in the spec tree than in the source file" $ do- it "assigns Nothing" $ do- let c = build $ do- strlit "foo"- strlit "foo"- withFileContent c $ \src -> do- [Leaf item1, Leaf item2, Leaf item3] <- runSpecM . H.postProcessSpec src . removeLocations $ do- H.it "foo" True- H.it "foo" True- H.it "foo" True- itemLocation item1 `shouldBe` Nothing- itemLocation item2 `shouldBe` Nothing- itemLocation item3 `shouldBe` Nothing- where- strlit :: String -> Builder- strlit = fromString . show