hledger-flow-0.12.3.0: test/CSVImport/Integration.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE OverloadedLists #-}
module CSVImport.Integration (tests) where
import Test.HUnit
import Turtle
import Prelude hiding (FilePath)
import qualified Data.Map.Strict as Map
import qualified Data.List as List (sort)
import TestHelpers
import Hledger.Flow.Common
import Control.Concurrent.STM
testExtraIncludesForFile :: Test
testExtraIncludesForFile = TestCase (
sh (
do
tmpdir <- using (mktempdir "." "hlflow")
let importedJournals = map (tmpdir </>) journalFiles :: [FilePath]
let accountDir = "import/john/bogartbank/savings"
let opening = tmpdir </> accountDir </> "2017-opening.journal"
let closing = tmpdir </> accountDir </> "2017-closing.journal"
let hidden = map (tmpdir </>) hiddenFiles :: [FilePath]
touchAll $ importedJournals ++ hidden
let accountInclude = tmpdir </> accountDir </> "2017-include.journal"
let expectedEmpty = [(accountInclude, [])]
ch <- liftIO newTChanIO
extraOpening1 <- extraIncludesForFile (defaultOpts tmpdir) ch accountInclude ["opening.journal"] []
liftIO $ assertEqual "The opening journal should not be included when it is not on disk" expectedEmpty extraOpening1
extraClosing1 <- extraIncludesForFile (defaultOpts tmpdir) ch accountInclude ["closing.journal"] []
liftIO $ assertEqual "The closing journal should not be included when it is not on disk" expectedEmpty extraClosing1
touchAll [opening, closing]
extraOpening2 <- extraIncludesForFile (defaultOpts tmpdir) ch accountInclude ["opening.journal"] []
liftIO $ assertEqual "The opening journal should be included when it is on disk" [(accountInclude, [opening])] extraOpening2
extraClosing2 <- extraIncludesForFile (defaultOpts tmpdir) ch accountInclude ["closing.journal"] []
liftIO $ assertEqual "The closing journal should be included when it is on disk" [(accountInclude, [closing])] extraClosing2
))
testIncludesPrePost :: Test
testIncludesPrePost = TestCase (
sh (
do
tmpdir <- using (mktempdir "." "hlflow")
let ownerDir = tmpdir </> "import/john"
let includeFile = ownerDir </> "2019-include.journal"
let pre = ownerDir </> "_manual_" </> "2019" </> "pre-import.journal"
let post = ownerDir </> "_manual_" </> "2019" </> "post-import.journal"
touchAll [pre, post]
let includeMap = Map.singleton includeFile [ownerDir </> "bank1" </> "2019-include.journal",
ownerDir </> "bank2" </> "2019-include.journal"]
ch <- liftIO newTChanIO
fileMap <- toIncludeFiles (defaultOpts tmpdir) ch includeMap
let expectedText = includePreamble <> "\n"
<> "!include _manual_/2019/pre-import.journal\n"
<> "!include bank1/2019-include.journal\n"
<> "!include bank2/2019-include.journal\n"
<> "!include _manual_/2019/post-import.journal\n"
let expectedMap = Map.singleton includeFile expectedText
liftIO $ assertEqual "All pre/post files on disk should be included" expectedMap fileMap
))
testIncludesOpeningClosing :: Test
testIncludesOpeningClosing = TestCase (
sh (
do
tmpdir <- using (mktempdir "." "hlflow")
let ownerDir = tmpdir </> "import/john"
let accountDir = ownerDir </> "bank1" </> "savings"
let includeFile = accountDir </> "2019-include.journal"
let opening = accountDir </> "2019-opening.journal"
let closing = accountDir </> "2019-closing.journal"
touchAll [opening, closing]
let includeMap = Map.singleton includeFile [accountDir </> "3-journal" </> "2019" </> "2019-01-30.journal"]
ch <- liftIO newTChanIO
fileMap <- toIncludeFiles (defaultOpts tmpdir) ch includeMap
let expectedText = includePreamble <> "\n"
<> "!include 2019-opening.journal\n"
<> "!include 3-journal/2019/2019-01-30.journal\n"
<> "!include 2019-closing.journal\n"
let expectedMap = Map.singleton includeFile expectedText
liftIO $ assertEqual "All pre/post files on disk should be included" expectedMap fileMap
))
testWriteIncludeFiles :: Test
testWriteIncludeFiles = TestCase (
sh (
do
tmpdir <- using (mktempdir "." "hlflow")
let importedJournals = map (tmpdir </>) journalFiles :: [FilePath]
let extras = map (tmpdir </>) extraFiles :: [FilePath]
let hidden = map (tmpdir </>) hiddenFiles :: [FilePath]
touchAll $ importedJournals ++ extras ++ hidden
let jane1 = tmpdir </> "import/jane/bogartbank/checking/2018-include.journal"
let jane2 = tmpdir </> "import/jane/bogartbank/checking/2019-include.journal"
let jane3 = tmpdir </> "import/jane/bogartbank/savings/2017-include.journal"
let jane4 = tmpdir </> "import/jane/bogartbank/savings/2018-include.journal"
let jane5 = tmpdir </> "import/jane/otherbank/creditcard/2017-include.journal"
let jane6 = tmpdir </> "import/jane/otherbank/creditcard/2018-include.journal"
let jane7 = tmpdir </> "import/jane/otherbank/investments/2018-include.journal"
let jane8 = tmpdir </> "import/jane/otherbank/investments/2019-include.journal"
let john1 = tmpdir </> "import/john/bogartbank/checking/2018-include.journal"
let john2 = tmpdir </> "import/john/bogartbank/checking/2019-include.journal"
let john3 = tmpdir </> "import/john/bogartbank/savings/2017-include.journal"
let john4 = tmpdir </> "import/john/bogartbank/savings/2018-include.journal"
let john5 = tmpdir </> "import/john/otherbank/creditcard/2017-include.journal"
let john6 = tmpdir </> "import/john/otherbank/creditcard/2018-include.journal"
let john7 = tmpdir </> "import/john/otherbank/investments/2018-include.journal"
let john8 = tmpdir </> "import/john/otherbank/investments/2019-include.journal"
let expectedIncludes = [jane1, jane2, jane3, jane4, jane5, jane6, jane7, jane8,
john1, john2, john3, john4, john5, john6, john7, john8]
ch <- liftIO newTChanIO
reportedAsWritten <- single $ groupAndWriteIncludeFiles (defaultOpts tmpdir) ch importedJournals
liftIO $ assertEqual "groupAndWriteIncludeFiles should return which files it wrote" expectedIncludes reportedAsWritten
let allYears = [tmpdir </> "import/jane/bogartbank/checking/all-years.journal",
tmpdir </> "import/jane/bogartbank/savings/all-years.journal",
tmpdir </> "import/jane/otherbank/creditcard/all-years.journal",
tmpdir </> "import/jane/otherbank/investments/all-years.journal",
tmpdir </> "import/john/bogartbank/checking/all-years.journal",
tmpdir </> "import/john/bogartbank/savings/all-years.journal",
tmpdir </> "import/john/otherbank/creditcard/all-years.journal",
tmpdir </> "import/john/otherbank/investments/all-years.journal"]
let expectedOnDisk = List.sort $ reportedAsWritten ++ extras ++ importedJournals ++ allYears
allFilesOnDisk <- single $ sort $ onlyFiles $ lstree tmpdir
liftIO $ assertEqual "The actual files on disk should match what groupAndWriteIncludeFiles reported" expectedOnDisk allFilesOnDisk
let expectedJohn1Contents = includePreamble <> "\n"
<> "!include 3-journal/2018/2018-10-30.journal\n"
<> "!include 3-journal/2018/2018-11-30.journal\n"
<> "!include 3-journal/2018/2018-12-30.journal\n"
actualJohn1Contents <- liftIO $ readTextFile john1
liftIO $ assertEqual "John1: The include file contents should be the journal files" expectedJohn1Contents actualJohn1Contents
let expectedJohn2Contents = includePreamble <> "\n"
<> "!include 3-journal/2019/2019-01-30.journal\n"
<> "!include 3-journal/2019/2019-02-30.journal\n"
actualJohn2Contents <- liftIO $ readTextFile john2
liftIO $ assertEqual "John2: The include file contents should be the journal files" expectedJohn2Contents actualJohn2Contents
let expectedJohn3Contents = includePreamble <> "\n"
<> "!include 2017-opening.journal\n"
<> "!include 3-journal/2017/2017-11-30.journal\n"
<> "!include 3-journal/2017/2017-12-30.journal\n"
actualJohn3Contents <- liftIO $ readTextFile john3
liftIO $ assertEqual "John3: The include file contents should be the journal files" expectedJohn3Contents actualJohn3Contents
let expectedJohn4Contents = includePreamble <> "\n"
<> "!include 3-journal/2018/2018-01-30.journal\n"
<> "!include 3-journal/2018/2018-02-30.journal\n"
actualJohn4Contents <- liftIO $ readTextFile john4
liftIO $ assertEqual "John4: The include file contents should be the journal files" expectedJohn4Contents actualJohn4Contents
let expectedJane7Contents = includePreamble <> "\n"
<> "!include 3-journal/2018/2018-12-30.journal\n"
actualJane7Contents <- liftIO $ readTextFile jane7
liftIO $ assertEqual "Jane7: The include file contents should be the journal files" expectedJane7Contents actualJane7Contents
)
)
tests :: Test
tests = TestList [testExtraIncludesForFile, testIncludesPrePost, testIncludesOpeningClosing, testWriteIncludeFiles]