shelly 1.6.2.1 → 1.6.2.2
raw patch · 16 files changed
+568/−2 lines, 16 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- shelly.cabal +4/−2
- test/src/CopySpec.hs +85/−0
- test/src/EnvSpec.hs +36/−0
- test/src/FailureSpec.hs +29/−0
- test/src/FindSpec.hs +69/−0
- test/src/Help.hs +24/−0
- test/src/LiftedSpec.hs +23/−0
- test/src/LogWithSpec.hs +19/−0
- test/src/MoveSpec.hs +76/−0
- test/src/ReadFileSpec.hs +23/−0
- test/src/RmSpec.hs +82/−0
- test/src/RunSpec.hs +26/−0
- test/src/TestInit.hs +10/−0
- test/src/WhichSpec.hs +17/−0
- test/src/WriteSpec.hs +36/−0
- test/src/sleep.hs +9/−0
shelly.cabal view
@@ -1,6 +1,6 @@ Name: shelly -Version: 1.6.2.1+Version: 1.6.2.2 Synopsis: shell-like (systems) programming in Haskell Description: Shelly provides convenient systems programming in Haskell,@@ -31,6 +31,8 @@ Build-type: Simple Cabal-version: >=1.8 +-- for the sdist of the test suite+extra-source-files: test/src/*.hs Library Exposed-modules: Shelly, Shelly.Lifted, Shelly.Pipe@@ -68,7 +70,6 @@ extensions: CPP - source-repository head type: git location: https://github.com/yesodweb/Shelly.hs@@ -83,6 +84,7 @@ main-is: TestMain.hs ghc-options: -O2 -Wall -fhpc -fwarn-tabs -funbox-strict-fields -threaded -fno-warn-unused-do-bind -fno-warn-type-defaults+ extensions: OverloadedStrings, ExtendedDefaultRules
+ test/src/CopySpec.hs view
@@ -0,0 +1,85 @@+{-# Language CPP #-}+module CopySpec ( copySpec ) where++import TestInit++#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 706+import Prelude hiding ( FilePath, catch)+#else+import Prelude hiding ( FilePath)+#endif+import Control.Monad (forM_)+import System.IO.Error+import Help++copySpec :: Spec+copySpec = do+ let b = "b" + let c = "c"+ describe "cp file" $ do+ it "cp to same dir" $+ forM_ [cp, cp_r] $ \copier -> do+ res <- shelly $+ within_dir "test/a" $ do+ writefile b "testing"+ copier b c+ readfile c+ res @?= "testing"++ it "cp to other dir" $+ forM_ [cp, cp_r] $ \copier -> do+ res <- shelly $+ within_dir "test/a" $ do+ writefile b "testing"+ mkdir c+ copier b c+ readfile "c/b"+ res @?= "testing"++ describe "cp dir" $ do+ it "to dir does not exist: create the to dir" $ do+ res <- shelly $+ within_dir "test/a" $ do+ mkdir b+ writefile "b/d" ""+ cp_r b c+ cIsDir <- test_d c+ liftIO $ assert $ cIsDir+ test_f "c/d"+ assert res++ it "to dir exists: creates a nested directory, full to path given" $ do+ res <- shelly $+ within_dir "test/a" $ do+ mkdir b+ mkdir c+ writefile "b/d" ""+ cp_r b $ c</>b+ cIsDir <- test_d c+ liftIO $ assert $ cIsDir+ bIsDir <- test_d $ c</>b+ liftIO $ assert $ bIsDir+ test_f "c/b/d"+ assert res++ it "to dir exists: creates a nested directory, partial to path given" $ do+ res <- shelly $+ within_dir "test/a" $ do+ mkdir b+ mkdir c+ writefile "b/d" ""+ cp_r b $ c+ cIsDir <- test_d c+ liftIO $ assert $ cIsDir+ bIsDir <- test_d $ c</>b+ liftIO $ assert $ bIsDir+ test_f "c/b/d"+ assert res++ it "copies the same dir" $ do+ shelly $+ within_dir "test/a" $ do+ mkdir b+ writefile "b/d" ""+ cp_r b b `catch_sh` (\e -> liftIO $ assert $ isUserError e)+ assert True
+ test/src/EnvSpec.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE CPP #-}+module EnvSpec ( envSpec ) where++import TestInit+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 706+import Prelude hiding ( FilePath, catch)+#else+import Prelude hiding ( FilePath)+#endif+import Data.Maybe++envSpec :: Spec+envSpec = do+ describe "getting unset env variables" $ do+ it "get_env" $ do+ res <- shelly $ get_env "FOOBARSHELLY"+ assert $ isNothing res++ it "get_env_text" $ do+ res <- shelly $ get_env_text "FOOBARSHELLY"+ assert $ res == ""++ describe "with SHELLY var set" $ do+ it "get_env" $ do+ res <- shelly $ do+ setenv "SHELLY" "test"+ get_env "SHELLY"+ assert $ res == Just "test"++ it "get_env_text" $ do+ res <- shelly $ do+ setenv "SHELLY" "test"+ get_env_text "SHELLY"+ assert $ res == "test"+ +
+ test/src/FailureSpec.hs view
@@ -0,0 +1,29 @@+module FailureSpec ( failureSpec ) where++import TestInit++failureSpec :: Spec+failureSpec = do+ let discardException action = shellyFailDir $ catchany_sh action (\_ -> return ())++ describe "failure set to stderr" $+ it "writes a failure message to stderr" $ do+ shellyFailDir $ discardException $+ liftIO $ shelly $ do+ test_d ".shelly" >>= liftIO . assert . not+ echo "testing"+ error "bam!"+ assert . not =<< shellyFailDir (test_d ".shelly")++ describe "failure set to directory" $+ it "writes a failure message to a .shelly directory" $ do+ shellyFailDir $ discardException $+ shellyFailDir $ do+ test_d ".shelly" >>= liftIO . assert . not+ echo "testing"+ error "bam!"+ assert =<< shellyFailDir ( do+ exists <- test_d ".shelly"+ rm_rf ".shelly"+ return exists+ )
+ test/src/FindSpec.hs view
@@ -0,0 +1,69 @@+module FindSpec ( findSpec ) where++import TestInit+import Data.List (sort)++findSpec :: Spec+findSpec = do+ describe "relativeTo" $ do+ it "relative to non-existent dir" $ do+ res <- shelly $ relativeTo "rel/" "rel/foo"+ res @?= "foo"+ res2 <- shelly $ relativeTo "rel" "rel/foo"+ res2 @?= "foo"++ it "relative to existing dir" $ do+ res <- shelly $ relativeTo "test/" "test/drain.hs"+ res @?= "drain.hs"+ res2 <- shelly $ relativeTo "test" "test/drain.hs"+ res2 @?= "drain.hs"++ it "abs path relative to existing dir" $ do+ res <- shelly $ do+ d <- pwd+ relativeTo "test/" $ d </> "test/drain.hs"+ res @?= "drain.hs"++ describe "relative listing" $ do+ it "lists relative files" $ do+ res <- shelly $ cd "test/src" >> ls "."+ sort res @?= ["./CopySpec.hs", "./EnvSpec.hs", "./FailureSpec.hs",+ "./FindSpec.hs", "./Help.hs", "./LiftedSpec.hs", "./LogWithSpec.hs", "./MoveSpec.hs",+ "./ReadFileSpec.hs", "./RmSpec.hs", "./RunSpec.hs",+ "./TestInit.hs", "./TestMain.hs",+ "./WhichSpec.hs", "./WriteSpec.hs", "./sleep.hs"]++ it "finds relative files" $ do+ res <- shelly $ cd "test/src" >> find "."+ sort res @?= ["./CopySpec.hs", "./EnvSpec.hs", "./FailureSpec.hs",+ "./FindSpec.hs", "./Help.hs", "./LiftedSpec.hs", "./LogWithSpec.hs", "./MoveSpec.hs",+ "./ReadFileSpec.hs", "./RmSpec.hs", "./RunSpec.hs",+ "./TestInit.hs", "./TestMain.hs",+ "./WhichSpec.hs", "./WriteSpec.hs", "./sleep.hs"]++ describe "find" $ do+ it "empty list for empty dir" $ do+ let d = "deleteme"+ res <- shelly $ do+ mkdir_p d+ res <- find d+ rm_rf d+ return res+ res @?= []++ it "lists relative files" $ do+ res <- shelly $ find "test/src"+ sort res @?= ["test/src/CopySpec.hs", "test/src/EnvSpec.hs", "test/src/FailureSpec.hs",+ "test/src/FindSpec.hs", "test/src/Help.hs", "test/src/LiftedSpec.hs",+ "test/src/LogWithSpec.hs", "test/src/MoveSpec.hs", "test/src/ReadFileSpec.hs",+ "test/src/RmSpec.hs", "test/src/RunSpec.hs",+ "test/src/TestInit.hs", "test/src/TestMain.hs", "test/src/WhichSpec.hs", "test/src/WriteSpec.hs",+ "test/src/sleep.hs"]++ it "lists absolute files" $ do+ res <- shelly $ relPath "test/src" >>= find >>= mapM (relativeTo "test/src")+ sort res @?= ["CopySpec.hs", "EnvSpec.hs", "FailureSpec.hs", "FindSpec.hs",+ "Help.hs", "LiftedSpec.hs", "LogWithSpec.hs", "MoveSpec.hs",+ "ReadFileSpec.hs", "RmSpec.hs", "RunSpec.hs",+ "TestInit.hs", "TestMain.hs",+ "WhichSpec.hs", "WriteSpec.hs", "sleep.hs"]
+ test/src/Help.hs view
@@ -0,0 +1,24 @@+module Help (+ with_dir, within_dir,+ (@==)+) where++import Shelly+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 706+import Prelude hiding ( catch, FilePath )+#else+import Prelude hiding ( FilePath )+#endif+import Test.HUnit+import Control.Monad.Trans ( MonadIO )++(@==) :: (Eq a, Show a, MonadIO m) => a -> a -> m ()+(@==) a b = liftIO (a @?= b)++with_dir :: FilePath -> Sh a -> Sh a+with_dir d action =+ mkdir_p d >> (action `finally_sh` rm_rf d)++within_dir :: FilePath -> Sh a -> Sh a+within_dir d action =+ with_dir d $ chdir d action
+ test/src/LiftedSpec.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE OverloadedStrings #-}++module LiftedSpec ( liftedSpec ) where++import Test.HUnit hiding (path)+import Test.Hspec+import Shelly.Lifted+import Control.Concurrent.Async.Lifted+import Control.Monad.Trans.Maybe+import Test.Hspec.HUnit ()++liftedSpec :: Spec+liftedSpec =+ describe "basic actions" $+ it "lifted sub" $ do+ xs <- shelly $+ runMaybeT $ do+ echo "Hello!"+ sub $ withTmpDir $ \p -> wait =<< (async $ do+ writefile (p </> "test.txt") "hello"+ readfile (p </> "test.txt")+ )+ xs @?= Just "hello"
+ test/src/LogWithSpec.hs view
@@ -0,0 +1,19 @@+{-# LANGUAGE OverloadedStrings #-}+module LogWithSpec ( logWithSpec ) where++import TestInit+import Prelude hiding (FilePath)++import Control.Concurrent (newEmptyMVar, takeMVar, putMVar)+import Data.Text (Text)+default (Text)++logWithSpec :: Spec+logWithSpec =+ describe "withOutputWriter" $+ it "calls writer function with handler and stdout output" $ do+ outputVar <- newEmptyMVar+ shelly $ log_stdout_with (putMVar outputVar)+ $ run_ "echo" ["single line output"]+ result <- takeMVar outputVar+ assertEqual "expecting output" "single line output" result
+ test/src/MoveSpec.hs view
@@ -0,0 +1,76 @@+module MoveSpec (moveSpec) where++import TestInit+import Help++moveSpec :: Spec+moveSpec = do+ let b = "b" + let c = "c"+ describe "mv file" $ do+ it "to same dir" $ do+ res <- shelly $+ within_dir "test/a" $ do+ writefile b "testing"+ mv b c+ readfile c+ res @?= "testing"+ + it "to other dir" $ do+ res <- shelly $+ within_dir "test/a" $ do+ writefile b "testing"+ mkdir c+ mv b c+ readfile "c/b"+ res @?= "testing"+ + describe "mv dir" $ do+ it "to dir does not exist: create the to dir" $ do+ res <- shelly $+ within_dir "test/a" $ do+ mkdir b+ writefile "b/d" ""+ mv b c+ cIsDir <- test_d c+ liftIO $ assert cIsDir+ test_f "c/d"+ assert res+ + it "to dir exists: creates a nested directory, full to path given" $ do+ res <- shelly $+ within_dir "test/a" $ do+ mkdir b+ mkdir c+ writefile "b/d" ""+ mv b $ c</>b+ cIsDir <- test_d c+ liftIO $ assert cIsDir+ bIsDir <- test_d $ c</>b+ liftIO $ assert bIsDir+ test_f "c/b/d"+ assert res+ + it "to dir exists: creates a nested directory, partial to path given" $ do+ res <- shelly $+ within_dir "test/a" $ do+ mkdir b+ mkdir c+ writefile "b/d" ""+ mv b $ c+ cIsDir <- test_d c+ liftIO $ assert cIsDir+ bIsDir <- test_d $ c</>b+ liftIO $ assert bIsDir+ test_f "c/b/d"+ assert res+ + {-+ it "mv the same dir" $ do+ shelly $ do+ within_dir "test/a" $ do+ mkdir b+ writefile "b/d" ""+ mv b b `catch_sh` (\e -> liftIO $ assert $ isUserError e)+ assert True+ -}
+ test/src/ReadFileSpec.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE CPP #-}++module ReadFileSpec (readFileSpec) where++import TestInit+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 706+import Prelude hiding ( FilePath, catch)+#else+import Prelude hiding ( FilePath)+#endif+import qualified Data.ByteString as BS+import qualified Data.Text as T++readFileSpec :: Spec+readFileSpec = describe "file with invalid encoding" $ do+ it "readBinary" $ do+ res <- shelly $ readBinary "test/data/zshrc"+ assert (BS.length res > 0)+ + it "readfile" $ do+ res <- shelly $ readfile "test/data/zshrc"+ assert (T.length res > 0)+
+ test/src/RmSpec.hs view
@@ -0,0 +1,82 @@+module RmSpec (rmSpec) where++import TestInit+import Help++rmSpec :: Spec+rmSpec = do+ let b = "b"+ let d = "dir"+ describe "rm file" $ do+ it "rm" $ do+ res <- shelly $ do+ writefile b "testing"+ (True @==) =<< test_f b+ rm b+ test_f b+ assert (not res)++ it "rm_r" $ do+ res <- shelly $ do+ writefile b "testing"+ (True @==) =<< test_f b+ rm b+ test_f b+ assert $ not res++ it "rm_f" $ do+ res <- shelly $ do+ (False @==) =<< test_f b+ rm_f b+ test_f b+ assert $ not res++ describe "rm_rf dir" $ do+ it "empty dir" $ do+ res <- shelly $ do+ mkdir d+ rm_rf d+ test_d d+ assert $ not res++ it "dir with file" $ do+ res <- shelly $ do+ mkdir d+ rm d `catchany_sh` (\_ -> return ())+ (True @==) =<< test_d d+ writefile (d </> b) "testing"+ rm d `catchany_sh` (\_ -> return ())+ (True @==) =<< test_d d+ rm_rf d+ test_d d+ assert $ not res++ describe "rm symlink" $ do+ let l = "l"+ it "rm" $ do+ res <- shelly $ do+ writefile b "b"+ cmd "ln" "-s" b l+ rm l+ test_f b+ assert res+ shelly $ rm b++ it "rm_f" $ do+ res <- shelly $ do+ writefile b "b"+ cmd "ln" "-s" b l+ rm_f l+ test_f b+ assert res+ shelly $ rm_f b++ it "rm_rf" $ do+ res <- shelly $ do+ mkdir d+ writefile (d</>b) "b"+ cmd "ln" "-s" (d</>b) l+ rm_rf l+ test_f (d</>b)+ assert res+ shelly $ rm_rf d
+ test/src/RunSpec.hs view
@@ -0,0 +1,26 @@+module RunSpec ( runSpec ) where++import TestInit++import qualified Data.Text as T+import System.IO++runSpec :: Spec+runSpec = do+ describe "run" $ do+ it "simple command" $ do+ res <- shelly $ run "echo" [ "wibble" ]+ res @?= "wibble\n"++ it "with escaping" $ do+ res <- shelly $ run "echo" [ "*" ]+ res @?= "*\n"++ it "without escaping" $ do+ res <- shelly $ escaping False $ run "echo" [ "*" ]+ assert $ "README.md" `elem` T.words res++ it "with binary handle mode" $ do+ res <- shelly $ onCommandHandles (initOutputHandles (flip hSetBinaryMode True))+ $ run "cat" [ "test/data/nonascii.txt" ]+ res @?= "Selbstverst\228ndlich \252berraschend\n"
+ test/src/TestInit.hs view
@@ -0,0 +1,10 @@+module TestInit (module Export) where++import Test.HUnit as Export hiding (path) +import Test.Hspec as Export+#ifdef LIFTED+import Shelly.Lifted as Export+#else+import Shelly as Export+#endif+import Test.Hspec.HUnit ()
+ test/src/WhichSpec.hs view
@@ -0,0 +1,17 @@+module WhichSpec (whichSpec) where++import TestInit++whichSpec :: Spec+whichSpec = describe "which" $ do+ it "gives full path to cabal" $ do+ Just _ <- shelly $ which "cabal"+ assert True++ it "recognizes cabal as a path executable" $ do+ res <- shelly $ test_px "cabal"+ True @?= res+ + it "cannot find missing exe" $ do+ Nothing <- shelly $ which "alskjdf;ashlva;ousnva;nj"+ assert True
+ test/src/WriteSpec.hs view
@@ -0,0 +1,36 @@+module WriteSpec ( writeSpec ) where++import TestInit+import Prelude hiding (FilePath)++import Data.Text (Text)+default (Text)++createsFile :: FilePath -> (FilePath -> IO ()) -> IO ()+createsFile f action = do+ exists <- shelly $ test_e f+ when exists $ error "cleanup after yourself!"+ action f+ shelly $ rm f+ return ()+++writeSpec :: Spec+writeSpec = do+ describe "writefile" $+ it "creates and overwites a file" $ createsFile "foo" $ \f -> do+ assert . (== "a") =<< (shelly $ writefile f "a" >> readfile f)+ assert . (== "b") =<< (shelly $ writefile f "b" >> readfile f)++ describe "appendfile" $+ it "creates and appends a file" $ createsFile "foo" $ \f -> do+ assert . (== "a") =<< (shelly $ appendfile f "a" >> readfile f)+ assert . (== "ab") =<< (shelly $ appendfile f "b" >> readfile f)++ describe "touchfile" $+ it "creates and updates a file" $ createsFile "foo" $ \f -> do+ assert . (== "") =<< (shelly $ touchfile f >> readfile f)+ assert . (== "") =<< (shelly $ touchfile f >> readfile f)++ assert . (== "a") =<< (shelly $+ writefile f "a" >> touchfile f >> readfile f)
+ test/src/sleep.hs view
@@ -0,0 +1,9 @@+{-# Language OverloadedStrings #-}+import Shelly++main :: IO ()+main =+ shelly $ do+ echo "sleeping"+ run "sleep" ["5"]+ echo "all done"