# hspec/hspec

1 parent 570671b commit 5c0630c4ba25db255667b5c81b887c6d351b338f sol committed Nov 28, 2013
Showing with 35 additions and 6 deletions.
1. +18 −6 example/Spec.hs
2. +10 −0 src/Test/Hspec.hs
3. +2 −0 src/Test/Hspec/Core.hs
4. +1 −0 src/Test/Hspec/Core/Type.hs
5. +4 −0 src/Test/Hspec/Runner/Eval.hs
 @@ -6,11 +6,23 @@ import Test.QuickCheck main :: IO () main = hspec spec + +action :: IO String +action = do + putStrLn "This is only run once!" + readFile "example/Spec.hs" + spec :: Spec -spec = do - describe "reverse" $do - it "reverses a list"$ do - reverse [1 :: Int, 2, 3] shouldBe [3, 2, 1] +spec = beforeAll action $do + describe "example/Spec.hs"$ do + it "gives the original list, if applied twice" $\input -> do + input shouldContain "foo" + + it "gives the original list, if applied twice"$ \input -> do + input shouldContain "bar" - it "gives the original list, if applied twice" $property$ - \xs -> (reverse . reverse) xs == (xs :: [Int]) + it "gives the original list, if applied twice" $\input -> + property$ \xs -> do + -- also works for QC properties, also it's not awfully useful for this + -- particular example... + (reverse . reverse) xs shouldBe (xs :: [Int])
 @@ -23,6 +23,7 @@ module Test.Hspec ( , pending , pendingWith , before +, beforeAll , after_ , around , around_ @@ -38,6 +39,7 @@ import Test.Hspec.HUnit () import Test.Hspec.Expectations import Test.Hspec.Core (mapSpecItem) import qualified Test.Hspec.Core as Core +import System.IO.Memoize -- | Combine a list of specs into a larger spec. describe :: String -> SpecWith a -> SpecWith a @@ -84,6 +86,14 @@ parallel = mapSpecItem $\item -> item {itemIsParallelizable = True} before :: IO a -> SpecWith a -> Spec before action = around (action >>=) +-- | Run a custom action before every spec item. +beforeAll :: IO a -> SpecWith a -> SpecWith () +beforeAll action = fromSpecList . return . BuildSpecs . foo . runSpecM + where + foo xs = do + action_ <- ioMemo action + return . runSpecM$ before action_ (fromSpecList xs) + -- | Run a custom action after every spec item. after :: (a -> IO ()) -> SpecWith a -> SpecWith a after a2 = mapSpecItem $\item -> item {itemExample = \params a1 -> itemExample item params (\f -> a1 (\a -> f a >> a2 a))}  @@ -26,12 +26,14 @@ module Test.Hspec.Core ( ) where import Test.Hspec.Core.Type +import Control.Applicative mapSpecItem :: (Item a -> Item b) -> SpecWith a -> SpecWith b mapSpecItem f = fromSpecList . map go . runSpecM where go spec = case spec of SpecItem item -> SpecItem (f item) + BuildSpecs es -> BuildSpecs (map go <$> es) SpecGroup d es -> SpecGroup d (map go es) modifyParams :: (Params -> Params) -> Spec -> Spec
 @@ -78,6 +78,7 @@ data Params = Params { -- | Internal representation of a spec. data SpecTree a = SpecGroup String [SpecTree a] + | BuildSpecs (IO [SpecTree a]) | SpecItem (Item a) data Item a = Item {
 @@ -40,6 +40,10 @@ run chan useColor h c formatter specs = do defer (exampleGroupStarted formatter n (reverse rGroups) group) forM_ (zip [0..] xs) (queueSpec (group : rGroups)) defer (exampleGroupDone formatter) + queueSpec rGroups (n, BuildSpecs xs) = do + ys <- xs + -- FIXME: n is screwed at this point.. + forM_ (zip [n..] ys) (queueSpec rGroups) queueSpec rGroups (_, SpecItem (Item isParallelizable requirement e)) = queueExample isParallelizable (reverse rGroups, requirement) (e (\$ ()))