hledger-flow-0.17.0: test/ImportHelpers/Integration.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
module ImportHelpers.Integration (tests) where
import qualified Data.List as List
import Data.Either (isLeft)
import qualified Data.Text.IO as T
import Hledger.Flow.Import.ImportHelpers (findInputFiles, findJournalFiles, withStagedOutput)
import Hledger.Flow.PathHelpers (AbsFile)
import Path
import Path.IO
import System.IO.Error (tryIOError)
import Test.HUnit
touchFile :: AbsFile -> IO ()
touchFile f = do
createDirIfMissing True (parent f)
T.writeFile (toFilePath f) "x"
testFindInputFiles :: Test
testFindInputFiles =
TestCase
( do
cwd <- getCurrentDir
let tmpbase = cwd </> [reldir|test|] </> [reldir|tmp|]
createDirIfMissing True tmpbase
withTempDir tmpbase "hlflowtest" $ \tmpdir -> do
let file2018 = tmpdir </> [relfile|import/john/mybank/checking/1-in/2018/2018-01-01.csv|]
let file2019 = tmpdir </> [relfile|import/john/mybank/checking/1-in/2019/2019-01-01.csv|]
let file2020 = tmpdir </> [relfile|import/john/mybank/checking/1-in/2020/2020-01-01.csv|]
let hidden = tmpdir </> [relfile|import/john/mybank/checking/1-in/2019/.hidden.csv|]
let wrongYear = tmpdir </> [relfile|import/john/mybank/checking/1-in/20a0/20a0-01-01.csv|]
let nested = tmpdir </> [relfile|import/john/mybank/checking/1-in/2019/subdir/2019-02-01.csv|]
let preprocessed = tmpdir </> [relfile|import/john/mybank/checking/2-preprocessed/2019/pre.csv|]
let manual = tmpdir </> [relfile|import/john/_manual_/2019/manual.journal|]
let journal = tmpdir </> [relfile|import/john/mybank/checking/3-journal/2019/2019-01-01.journal|]
mapM_ touchFile [file2018, file2019, file2020, hidden, wrongYear, nested, preprocessed, manual, journal]
actual <- findInputFiles 2019 tmpdir
let expected = List.sort [file2019, file2020]
assertEqual "findInputFiles should return only year directories >= startYear, excluding hidden and excluded dirs" expected (List.sort actual)
)
testFindJournalFiles :: Test
testFindJournalFiles =
TestCase
( do
cwd <- getCurrentDir
let tmpbase = cwd </> [reldir|test|] </> [reldir|tmp|]
createDirIfMissing True tmpbase
withTempDir tmpbase "hlflowtest" $ \tmpdir -> do
let journal2018 = tmpdir </> [relfile|import/john/mybank/checking/3-journal/2018/2018-01-01.journal|]
let journal2019 = tmpdir </> [relfile|import/john/mybank/checking/3-journal/2019/2019-01-01.journal|]
let hidden = tmpdir </> [relfile|import/john/mybank/checking/3-journal/2019/.hidden.journal|]
let wrongYear = tmpdir </> [relfile|import/john/mybank/checking/3-journal/20a0/20a0-01-01.journal|]
let nested = tmpdir </> [relfile|import/john/mybank/checking/3-journal/2019/subdir/2019-02-01.journal|]
let input = tmpdir </> [relfile|import/john/mybank/checking/1-in/2019/2019-01-01.csv|]
let preprocessed = tmpdir </> [relfile|import/john/mybank/checking/2-preprocessed/2019/pre.csv|]
mapM_ touchFile [journal2018, journal2019, hidden, wrongYear, nested, input, preprocessed]
actual <- findJournalFiles tmpdir
let expected = List.sort [journal2018, journal2019]
assertEqual "findJournalFiles should return only journal directory files, excluding hidden and excluded dirs" expected (List.sort actual)
)
testStagedOutput :: Test
testStagedOutput = TestCase $ withSystemTempDir "hlflow-output" $ \dir -> do
let target = dir </> [relfile|march.bank.csv|]
failAfterWriting staged = do
assertEqual "hook output keeps its filename" (filename target) (filename staged)
assertBool "hook output has a temporary parent" (parent staged /= dir)
T.writeFile (toFilePath staged) "partial"
ioError (userError "failed hook")
checkFailure = do
result <- tryIOError (withStagedOutput target failAfterWriting)
assertBool "propagate hook failure" (isLeft result)
(dirs, _) <- listDir dir
assertEqual "clean up staging directories" [] dirs
checkFailure
doesFileExist target >>= assertEqual "failed first run publishes no file" False
T.writeFile (toFilePath target) "previous"
checkFailure
T.readFile (toFilePath target) >>= assertEqual "preserve previous output" "previous"
withStagedOutput target $ \staged -> T.writeFile (toFilePath staged) "complete"
T.readFile (toFilePath target) >>= assertEqual "publish successful retry" "complete"
tests :: Test
tests = TestList [testFindInputFiles, testFindJournalFiles, testStagedOutput]