packages feed

filecache-0.3.0: tests/simpletest.hs

module Main where

import System.IO.Temp
import Data.FileCache.Internal
import Control.Monad
import Control.Exception
import System.Directory
import Control.Concurrent
import qualified Data.Map.Strict as M
import qualified Data.Set as S
import Control.Concurrent.STM hiding (check)
import System.FilePath (addTrailingPathSeparator)
import Test.Hspec

computation :: String -> IO (Either String Int)
computation f = do
    c <- readFile f
    return $ if length c `mod` 2 == 0
        then Right (length c)
        else Left "odd length"

main :: IO ()
main = withSystemTempDirectory "filecacheXXX.tmp" $ \tempdir -> do
    cache@(FileCache tcache tdirs _ _ _) <- newFileCache :: IO (FileCache Int)
    let indexes = [1,10,100,1000]
        tofilename :: Int -> String
        tofilename i = tempdir ++ "/temp" ++ show i
    forM_ indexes $ \l -> writeFile (tofilename l) (show l)
    let q l = lazyQuery cache (tofilename l) (computation (tofilename l))
        qf l = lazyQuery cache (tofilename l) (throwIO (AssertionFailed "fail"))
    hspec $ describe "Spec" $ do
      it "Should run the actions" $ do
        mapM q indexes `shouldReturn` [Left "odd length",Right 2,Left "odd length",Right 4]
      it "Should have cached the results" $ do
        mapM qf indexes `shouldReturn` [Left "odd length",Right 2,Left "odd length",Right 4]
      it "Should stop watching dropped files" $ do
        removeFile (tofilename 10)
        doesFileExist (tofilename 10) `shouldReturn` False
        threadDelay (1*10^(5 :: Int))
        cacheInfo <- readTVarIO tcache
        M.size cacheInfo `shouldBe` 3
      it "Should update the list of watched files per directory" $ do
        dirs <- fmap fst <$> readTVarIO tdirs
        M.toList dirs `shouldBe` [(addTrailingPathSeparator tempdir, foldMap (S.singleton . tofilename) [1,100,1000])]
      it "Should stop watching directory without watched files" $ do
        forM_ [1,100,1000] $ \i -> do
          removeFile (tofilename i)
          doesFileExist (tofilename i) `shouldReturn` False
        threadDelay (1*10^(5 :: Int))
        dirs <- fmap fst <$> readTVarIO tdirs
        dirs `shouldBe` M.empty
      it "Should stop the watch" $ do
        killFileCache cache
        q 1 `shouldReturn` Left "Closed cache"