sensei 0.2.0 → 0.3.0
raw patch · 5 files changed
+88/−19 lines, 5 files
Files
- sensei.cabal +2/−2
- src/Trigger.hs +17/−2
- test/Helper.hs +25/−0
- test/SessionSpec.hs +1/−1
- test/TriggerSpec.hs +43/−14
sensei.cabal view
@@ -1,9 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.15.0.+-- This file has been generated from package.yaml by hpack version 0.18.0. -- -- see: https://github.com/sol/hpack name: sensei-version: 0.2.0+version: 0.3.0 synopsis: Automatically run Hspec tests on file modifications category: Development homepage: https://github.com/hspec/sensei#readme
src/Trigger.hs view
@@ -1,11 +1,16 @@+{-# LANGUAGE CPP #-} module Trigger ( trigger , triggerAll+#ifdef TEST+, reloadedSuccessfully+#endif ) where import Prelude () import Prelude.Compat-import Data.List+import Data.List.Compat+import Data.Char import Session (Session, isFailure, isSuccess, hspecPreviousSummary, resetSummary) import qualified Session@@ -15,10 +20,20 @@ resetSummary session trigger session +reloadedSuccessfully :: String -> Bool+reloadedSuccessfully = any success . lines+ where+ success :: String -> Bool+ success x = case stripPrefix "Ok, " x of+ Just "1 module loaded." -> True+ Just xs | " modules loaded." <- dropWhile isNumber xs -> True+ Just xs -> "modules loaded: " `isPrefixOf` xs+ Nothing -> False+ trigger :: Session -> IO (Bool, String) trigger session = do xs <- Session.reload session- fmap (xs ++) <$> if "Ok, modules loaded:" `isInfixOf` xs+ fmap (xs ++) <$> if reloadedSuccessfully xs then hspec else return (False, "") where
test/Helper.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE QuasiQuotes #-} module Helper ( module Test.Hspec@@ -9,11 +10,16 @@ , passingSpec , passingMetaSpec , failingSpec+, Status(..)+, modulesLoaded ) where import Control.Applicative import Control.Exception import Data.String.Interpolate+#if __GLASGOW_HASKELL__ < 802+import Data.List.Compat+#endif import System.IO.Silently import Test.Hspec import Test.Mockery.Directory@@ -63,3 +69,22 @@ it "foo" True it "bar" False |]++data Status = Ok | Failed+ deriving (Eq, Show)++modulesLoaded :: Status -> [String] -> String+#if __GLASGOW_HASKELL__ < 802+modulesLoaded status xs = show status ++ ", modules loaded: " ++ mods ++ "."+ where+ mods = case xs of+ [] -> "none"+ _ -> intercalate ", " xs+#else+modulesLoaded status xs = show status ++ ", " ++ show n ++ " " ++ mods ++ " loaded."+ where+ n = length xs+ mods+ | n == 1 = "module"+ | otherwise = "modules"+#endif
test/SessionSpec.hs view
@@ -21,7 +21,7 @@ describe "reload" $ do it "reloads" $ do withSession [] $ \session -> do- silence (Session.reload session) `shouldReturn` "Ok, modules loaded: none.\n"+ silence (Session.reload session) `shouldReturn` (modulesLoaded Ok [] ++ "\n") describe "hasSpec" $ around_ withSomeSpec $ do context "when module contains spec" $ do
test/TriggerSpec.hs view
@@ -1,16 +1,14 @@ module TriggerSpec (spec) where import Helper-import Data.List+import Data.List.Compat+import Data.Char import Trigger normalize :: String -> [String]-normalize = normalizeErrors . normalizeTiming . normalizeSeed . lines+normalize = normalizeErrors . normalizeTiming . normalizeSeed . lines . stripAnsiColors where- normalizeErrors :: [String] -> [String]- normalizeErrors = mkNormalize "Spec.hs:"- normalizeTiming :: [String] -> [String] normalizeTiming = mkNormalize "Finished in " @@ -24,15 +22,46 @@ | message `isPrefixOf` line = message ++ "..." | otherwise = line + normalizeErrors :: [String] -> [String]+ normalizeErrors xs = case xs of+ y : ys | "Spec.hs:" `isPrefixOf` y -> "Spec.hs:..." : normalizeErrors (removeErrorDetails ys)+ y : ys -> y : normalizeErrors ys+ [] -> []++ removeErrorDetails :: [String] -> [String]+ removeErrorDetails xs = case xs of+ (_ : _ : ' ' : '|' : _) : ys -> removeErrorDetails ys+ _ -> xs++ stripAnsiColors xs = case xs of+ '\ESC' : '[' : ';' : ys | 'm' : zs <- dropWhile isNumber ys -> stripAnsiColors zs+ '\ESC' : '[' : ys | 'm' : zs <- dropWhile isNumber ys -> stripAnsiColors zs+ y : ys -> y : stripAnsiColors ys+ [] -> []+ spec :: Spec spec = do+ describe "reloadedSuccessfully" $ do+ context "with GHC < 8.2.1" $ do+ it "detects success" $ do+ reloadedSuccessfully "Ok, modules loaded: Spec." `shouldBe` True++ context "with GHC >= 8.2.1" $ do+ context "with a single module" $ do+ it "detects success" $ do+ reloadedSuccessfully "Ok, 1 module loaded." `shouldBe` True++ context "with multiple modules" $ do+ it "detects success" $ do+ reloadedSuccessfully "Ok, 5 modules loaded." `shouldBe` True+ describe "triggerAll" $ around_ withSomeSpec $ do it "runs all specs" $ do withSession ["Spec.hs", "--no-color"] $ \session -> do writeFile "Spec.hs" failingSpec (False, xs) <- silence (trigger session >> triggerAll session) normalize xs `shouldBe` [- "Ok, modules loaded: Spec."+ modulesLoaded Ok ["Spec"] , "" , "foo" , "bar FAILED [1]"@@ -54,7 +83,7 @@ withSession ["Spec.hs", "--no-color"] $ \session -> do result <- silence (trigger session >> trigger session) fmap normalize result `shouldBe` (True, [- "Ok, modules loaded: Spec."+ modulesLoaded Ok ["Spec"] , "" , "foo" , "bar"@@ -73,7 +102,7 @@ "[1 of 1] Compiling Spec ( Spec.hs, interpreted )" , "" , "Spec.hs:..."- , "Failed, modules loaded: none."+ , modulesLoaded Failed [] ] context "with a failing spec" $ do@@ -81,7 +110,7 @@ withSession ["Spec.hs"] $ \session -> do writeFile "Spec.hs" failingSpec (False, xs) <- silence (trigger session)- xs `shouldContain` "Ok, modules loaded:"+ xs `shouldContain` modulesLoaded Ok ["Spec"] xs `shouldContain` "2 examples, 1 failure" it "only reruns failing specs" $ do@@ -89,7 +118,7 @@ writeFile "Spec.hs" failingSpec (False, xs) <- silence (trigger session >> trigger session) normalize xs `shouldBe` [- "Ok, modules loaded: Spec."+ modulesLoaded Ok ["Spec"] , "" , "bar FAILED [1]" , ""@@ -114,7 +143,7 @@ (True, xs) <- silence (trigger session) normalize xs `shouldBe` [ "[1 of 1] Compiling Spec ( Spec.hs, interpreted )"- , "Ok, modules loaded: Spec."+ , modulesLoaded Ok ["Spec"] , "" , "bar" , ""@@ -133,8 +162,8 @@ context "with a module that does not expose a spec" $ do it "only reloads" $ do withSession ["Spec.hs"] $ \session -> do- writeFile "Spec.hs" "module Main where"- silence (trigger session >> trigger session) `shouldReturn` (True, "Ok, modules loaded: Main.\n")+ writeFile "Spec.hs" "module Foo where"+ silence (trigger session >> trigger session) `shouldReturn` (True, modulesLoaded Ok ["Foo"] ++ "\n") context "with an hspec-meta spec" $ do it "reloads and runs spec" $ do@@ -142,7 +171,7 @@ writeFile "Spec.hs" passingMetaSpec result <- silence (trigger session >> trigger session) fmap normalize result `shouldBe` (True, [- "Ok, modules loaded: Spec."+ modulesLoaded Ok ["Spec"] , "" , "foo" , "bar"