hledger-flow-0.19.0: test/Status/Integration.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
module Status.Integration (tests) where
import Data.Maybe (isNothing)
import Data.Time.Clock (addUTCTime)
import Hledger.Flow.Common (findHledger)
import Hledger.Flow.PathHelpers (AbsFile)
import Hledger.Flow.Status
import Hledger.Flow.Status.Gather (classifyDir, gatherStatus)
import Path
import Path.IO
import Control.Monad (unless)
import System.Environment (lookupEnv, setEnv, unsetEnv)
import qualified System.Info as Sys
import System.FilePath (joinPath)
import Test.HUnit hiding (Path)
import TestHelpers (defaultHlInfo, withTestDir)
touch :: AbsFile -> IO ()
touch file = do
createDirIfMissing True (parent file)
writeFile (toFilePath file) "Date,Desc,Amount\n"
testClassify :: Test
testClassify = TestCase $ withTestDir $ \tmp -> do
let ledger = tmp </> [reldir|ledger|]
empty = tmp </> [reldir|empty|]
other = tmp </> [reldir|other|]
mapM_ (createDirIfMissing True) [ledger </> [reldir|import/me|], empty, other]
writeFile (toFilePath (empty </> [relfile|.DS_Store|])) ""
writeFile (toFilePath (other </> [relfile|notes.txt|])) ""
(@?= InLedger ledger) =<< classifyDir (ledger </> [reldir|import/me|])
(@?= EmptyDir) =<< classifyDir empty
(@?= Elsewhere) =<< classifyDir other
testGather :: Test
testGather = TestCase $ withTestDir $ \base -> do
let imp = base </> [reldir|import|]
cardCsv = imp </> [relfile|other/bank/card/1-in/2026/c.csv|]
cardJournal = imp </> [relfile|other/bank/card/3-journal/2026/c.journal|]
mapM_ touch
[ imp </> [relfile|me/mybank/checking/1-in/2025/a.csv|],
imp </> [relfile|me/mybank/checking/1-in/2026/b.csv|],
cardCsv,
imp </> [relfile|bank.rules|],
cardJournal,
imp </> [relfile|me/mybank/jan.csv|],
imp </> [relfile|me/_manual_/2026/pre-import.journal|]
]
now <- getModificationTime cardCsv
setModificationTime cardJournal (addUTCTime (-3600) now)
unsetEnv "LEDGER_FILE"
s <- gatherStatus (Just defaultHlInfo) base
map asAccount (lsAccounts s) @?= ["me/mybank/checking", "other/bank/card"]
case lsAccounts s of
[checking, card] -> do
(asStatements checking, asYears checking, asRulesFile checking, asWithoutRules checking, asJournalsMissing checking)
@?= (2, [2025, 2026], Nothing, 2, 2)
asRulesCandidates checking @?= [joinPath ["import", "me", "mybank", "checking", "mybank-checking.rules"], joinPath ["import", "mybank.rules"]]
(asRulesFile card, asWithoutRules card, asJournalsMissing card, asJournalsOutdated card)
@?= (Just (joinPath ["import", "bank.rules"]), 0, 0, 1)
_ -> assertFailure "expected two accounts"
map mpPath (lsMisplaced s) @?= [joinPath ["import", "me", "mybank", "jan.csv"]]
lsManualJournals s @?= 1
lsLedgerFile s @?= Nothing
setEnv "LEDGER_FILE" (toFilePath (base </> [relfile|missing.journal|]))
s2 <- gatherStatus Nothing base
unsetEnv "LEDGER_FILE"
fmap lfExists (lsLedgerFile s2) @?= Just False
lsAllYearsExists s2 @?= False
testLedgerFileTilde :: Test
testLedgerFileTilde = TestCase $ unless (Sys.os == "mingw32") $ withTestDir $ \base -> do
oldHome <- lookupEnv "HOME"
writeFile (toFilePath (base </> [relfile|x.journal|])) ""
createDirIfMissing True (base </> [reldir|import|])
setEnv "HOME" (toFilePath base)
setEnv "LEDGER_FILE" "~/x.journal"
s <- gatherStatus Nothing base
unsetEnv "LEDGER_FILE"
maybe (unsetEnv "HOME") (setEnv "HOME") oldHome
fmap lfExists (lsLedgerFile s) @?= Just True
testFindHledgerMissing :: Test
testFindHledgerMissing = TestCase $ do
r <- findHledger (Just "/nonexistent/hledger")
assertBool "Nothing for a missing path" (isNothing r)
tests :: Test
tests = TestList [testClassify, testGather, testFindHledgerMissing, testLedgerFileTilde]