445 lines
14 KiB
Haskell
445 lines
14 KiB
Haskell
{-|
|
|
|
|
Hledger.Cli re-exports the options, utilities and commands provided by
|
|
the hledger command-line program. This module also aggregates the
|
|
built-in unit tests defined throughout hledger and hledger-lib, and
|
|
adds some more which are easier to define here.
|
|
|
|
-}
|
|
|
|
module Hledger.Cli (
|
|
module Hledger.Cli.Accounts,
|
|
module Hledger.Cli.Add,
|
|
module Hledger.Cli.Balance,
|
|
module Hledger.Cli.Balancesheet,
|
|
module Hledger.Cli.Cashflow,
|
|
module Hledger.Cli.Histogram,
|
|
module Hledger.Cli.Incomestatement,
|
|
module Hledger.Cli.Print,
|
|
module Hledger.Cli.Register,
|
|
module Hledger.Cli.Stats,
|
|
module Hledger.Cli.Options,
|
|
module Hledger.Cli.Utils,
|
|
module Hledger.Cli.Version,
|
|
tests_Hledger_Cli,
|
|
module Hledger,
|
|
module System.Console.CmdArgs.Explicit
|
|
)
|
|
where
|
|
import Data.Time.Calendar
|
|
import System.Console.CmdArgs.Explicit
|
|
import Test.HUnit
|
|
|
|
import Hledger
|
|
import Hledger.Cli.Accounts
|
|
import Hledger.Cli.Add
|
|
import Hledger.Cli.Balance
|
|
import Hledger.Cli.Balancesheet
|
|
import Hledger.Cli.Cashflow
|
|
import Hledger.Cli.Histogram
|
|
import Hledger.Cli.Incomestatement
|
|
import Hledger.Cli.Print
|
|
import Hledger.Cli.Register
|
|
import Hledger.Cli.Stats
|
|
import Hledger.Cli.Options
|
|
import Hledger.Cli.Utils
|
|
import Hledger.Cli.Version
|
|
|
|
|
|
tests_Hledger_Cli :: Test
|
|
tests_Hledger_Cli = TestList
|
|
[
|
|
tests_Hledger
|
|
-- ,tests_Hledger_Cli_Add
|
|
,tests_Hledger_Cli_Balance
|
|
,tests_Hledger_Cli_Balancesheet
|
|
,tests_Hledger_Cli_Cashflow
|
|
-- ,tests_Hledger_Cli_Histogram
|
|
,tests_Hledger_Cli_Incomestatement
|
|
,tests_Hledger_Cli_Options
|
|
-- ,tests_Hledger_Cli_Print
|
|
,tests_Hledger_Cli_Register
|
|
-- ,tests_Hledger_Cli_Stats
|
|
|
|
|
|
,"account directive" ~:
|
|
let ignoresourcepos j = j{jtxns=map (\t -> t{tsourcepos=nullsourcepos}) (jtxns j)} in
|
|
let sameParse str1 str2 = do j1 <- readJournal Nothing Nothing True Nothing str1 >>= either error' (return . ignoresourcepos)
|
|
j2 <- readJournal Nothing Nothing True Nothing str2 >>= either error' (return . ignoresourcepos)
|
|
j1 `is` j2{filereadtime=filereadtime j1, files=files j1, jContext=jContext j1}
|
|
in TestList
|
|
[
|
|
"account directive 1" ~: sameParse
|
|
"2008/12/07 One\n test:from $-1\n test:to $1\n"
|
|
"!account test\n2008/12/07 One\n from $-1\n to $1\n"
|
|
|
|
,"account directive 2" ~: sameParse
|
|
"2008/12/07 One\n test:foo:from $-1\n test:foo:to $1\n"
|
|
"!account test\n!account foo\n2008/12/07 One\n from $-1\n to $1\n"
|
|
|
|
,"account directive 3" ~: sameParse
|
|
"2008/12/07 One\n test:from $-1\n test:to $1\n"
|
|
"!account test\n!account foo\n!end\n2008/12/07 One\n from $-1\n to $1\n"
|
|
|
|
,"account directive 4" ~: sameParse
|
|
("2008/12/07 One\n alpha $-1\n beta $1\n" ++
|
|
"!account outer\n2008/12/07 Two\n aigh $-2\n bee $2\n" ++
|
|
"!account inner\n2008/12/07 Three\n gamma $-3\n delta $3\n" ++
|
|
"!end\n2008/12/07 Four\n why $-4\n zed $4\n" ++
|
|
"!end\n2008/12/07 Five\n foo $-5\n bar $5\n"
|
|
)
|
|
("2008/12/07 One\n alpha $-1\n beta $1\n" ++
|
|
"2008/12/07 Two\n outer:aigh $-2\n outer:bee $2\n" ++
|
|
"2008/12/07 Three\n outer:inner:gamma $-3\n outer:inner:delta $3\n" ++
|
|
"2008/12/07 Four\n outer:why $-4\n outer:zed $4\n" ++
|
|
"2008/12/07 Five\n foo $-5\n bar $5\n"
|
|
)
|
|
|
|
,"account directive should preserve \"virtual\" posting type" ~: do
|
|
j <- readJournal Nothing Nothing True Nothing "!account test\n2008/12/07 One\n (from) $-1\n (to) $1\n" >>= either error' return
|
|
let p = head $ tpostings $ head $ jtxns j
|
|
assertBool "" $ paccount p == "test:from"
|
|
assertBool "" $ ptype p == VirtualPosting
|
|
|
|
]
|
|
|
|
,"account aliases" ~: do
|
|
j <- readJournal Nothing Nothing True Nothing "!alias expenses = equity:draw:personal\n1/1\n (expenses:food) 1\n" >>= either error' return
|
|
let p = head $ tpostings $ head $ jtxns j
|
|
assertBool "" $ paccount p == "equity:draw:personal:food"
|
|
|
|
,"ledgerAccountNames" ~:
|
|
ledgerAccountNames ledger7 `is`
|
|
["assets","assets:cash","assets:checking","assets:saving","equity","equity:opening balances",
|
|
"expenses","expenses:food","expenses:food:dining","expenses:phone","expenses:vacation",
|
|
"liabilities","liabilities:credit cards","liabilities:credit cards:discover"]
|
|
|
|
-- ,"journalCanonicaliseAmounts" ~:
|
|
-- "use the greatest precision" ~:
|
|
-- (map asprecision $ journalAmountAndPriceCommodities $ journalCanonicaliseAmounts $ journalWithAmounts ["1","2.00"]) `is` [2,2]
|
|
|
|
-- don't know what this should do
|
|
-- ,"elideAccountName" ~: do
|
|
-- (elideAccountName 50 "aaaaaaaaaaaaaaaaaaaa:aaaaaaaaaaaaaaaaaaaa:aaaaaaaaaaaaaaaaaaaa"
|
|
-- `is` "aa:aaaaaaaaaaaaaaaaaaaa:aaaaaaaaaaaaaaaaaaaa")
|
|
-- (elideAccountName 20 "aaaaaaaaaaaaaaaaaaaa:aaaaaaaaaaaaaaaaaaaa:aaaaaaaaaaaaaaaaaaaa"
|
|
-- `is` "aa:aa:aaaaaaaaaaaaaa")
|
|
|
|
,"default year" ~: do
|
|
j <- readJournal Nothing Nothing True Nothing defaultyear_journal_str >>= either error' return
|
|
tdate (head $ jtxns j) `is` fromGregorian 2009 1 1
|
|
return ()
|
|
|
|
,"show dollars" ~: showAmount (usd 1) ~?= "$1.00"
|
|
|
|
,"show hours" ~: showAmount (hrs 1) ~?= "1.00h"
|
|
|
|
]
|
|
|
|
|
|
-- fixtures/test data
|
|
|
|
-- date1 = parsedate "2008/11/26"
|
|
-- t1 = LocalTime date1 midday
|
|
|
|
{-
|
|
samplejournal = readJournal' sample_journal_str
|
|
|
|
sample_journal_str = unlines
|
|
["; A sample journal file."
|
|
,";"
|
|
,"; Sets up this account tree:"
|
|
,"; assets"
|
|
,"; bank"
|
|
,"; checking"
|
|
,"; saving"
|
|
,"; cash"
|
|
,"; expenses"
|
|
,"; food"
|
|
,"; supplies"
|
|
,"; income"
|
|
,"; gifts"
|
|
,"; salary"
|
|
,"; liabilities"
|
|
,"; debts"
|
|
,""
|
|
,"2008/01/01 income"
|
|
," assets:bank:checking $1"
|
|
," income:salary"
|
|
,""
|
|
,"2008/06/01 gift"
|
|
," assets:bank:checking $1"
|
|
," income:gifts"
|
|
,""
|
|
,"2008/06/02 save"
|
|
," assets:bank:saving $1"
|
|
," assets:bank:checking"
|
|
,""
|
|
,"2008/06/03 * eat & shop"
|
|
," expenses:food $1"
|
|
," expenses:supplies $1"
|
|
," assets:cash"
|
|
,""
|
|
,"2008/12/31 * pay off"
|
|
," liabilities:debts $1"
|
|
," assets:bank:checking"
|
|
,""
|
|
,""
|
|
,";final comment"
|
|
]
|
|
-}
|
|
|
|
defaultyear_journal_str :: String
|
|
defaultyear_journal_str = unlines
|
|
["Y2009"
|
|
,""
|
|
,"01/01 A"
|
|
," a $1"
|
|
," b"
|
|
]
|
|
|
|
-- write_sample_journal = writeFile "sample.journal" sample_journal_str
|
|
|
|
-- entry2_str = unlines
|
|
-- ["2007/01/27 * joes diner"
|
|
-- ," expenses:food:dining $10.00"
|
|
-- ," expenses:gifts $10.00"
|
|
-- ," assets:checking $-20.00"
|
|
-- ,""
|
|
-- ]
|
|
|
|
-- entry3_str = unlines
|
|
-- ["2007/01/01 * opening balance"
|
|
-- ," assets:cash $4.82"
|
|
-- ," equity:opening balances"
|
|
-- ,""
|
|
-- ,"2007/01/01 * opening balance"
|
|
-- ," assets:cash $4.82"
|
|
-- ," equity:opening balances"
|
|
-- ,""
|
|
-- ,"2007/01/28 coopportunity"
|
|
-- ," expenses:food:groceries $47.18"
|
|
-- ," assets:checking"
|
|
-- ,""
|
|
-- ]
|
|
|
|
-- periodic_entry1_str = unlines
|
|
-- ["~ monthly from 2007/2/2"
|
|
-- ," assets:saving $200.00"
|
|
-- ," assets:checking"
|
|
-- ,""
|
|
-- ]
|
|
|
|
-- periodic_entry2_str = unlines
|
|
-- ["~ monthly from 2007/2/2"
|
|
-- ," assets:saving $200.00 ;auto savings"
|
|
-- ," assets:checking"
|
|
-- ,""
|
|
-- ]
|
|
|
|
-- periodic_entry3_str = unlines
|
|
-- ["~ monthly from 2007/01/01"
|
|
-- ," assets:cash $4.82"
|
|
-- ," equity:opening balances"
|
|
-- ,""
|
|
-- ,"~ monthly from 2007/01/01"
|
|
-- ," assets:cash $4.82"
|
|
-- ," equity:opening balances"
|
|
-- ,""
|
|
-- ]
|
|
|
|
-- journal1_str = unlines
|
|
-- [""
|
|
-- ,"2007/01/27 * joes diner"
|
|
-- ," expenses:food:dining $10.00"
|
|
-- ," expenses:gifts $10.00"
|
|
-- ," assets:checking $-20.00"
|
|
-- ,""
|
|
-- ,""
|
|
-- ,"2007/01/28 coopportunity"
|
|
-- ," expenses:food:groceries $47.18"
|
|
-- ," assets:checking $-47.18"
|
|
-- ,""
|
|
-- ,""
|
|
-- ]
|
|
|
|
-- journal2_str = unlines
|
|
-- [";comment"
|
|
-- ,"2007/01/27 * joes diner"
|
|
-- ," expenses:food:dining $10.00"
|
|
-- ," assets:checking $-47.18"
|
|
-- ,""
|
|
-- ]
|
|
|
|
-- journal3_str = unlines
|
|
-- ["2007/01/27 * joes diner"
|
|
-- ," expenses:food:dining $10.00"
|
|
-- ,";intra-entry comment"
|
|
-- ," assets:checking $-47.18"
|
|
-- ,""
|
|
-- ]
|
|
|
|
-- journal4_str = unlines
|
|
-- ["!include \"somefile\""
|
|
-- ,"2007/01/27 * joes diner"
|
|
-- ," expenses:food:dining $10.00"
|
|
-- ," assets:checking $-47.18"
|
|
-- ,""
|
|
-- ]
|
|
|
|
-- journal5_str = ""
|
|
|
|
-- journal6_str = unlines
|
|
-- ["~ monthly from 2007/1/21"
|
|
-- ," expenses:entertainment $16.23 ;netflix"
|
|
-- ," assets:checking"
|
|
-- ,""
|
|
-- ,"; 2007/01/01 * opening balance"
|
|
-- ,"; assets:saving $200.04"
|
|
-- ,"; equity:opening balances "
|
|
-- ,""
|
|
-- ]
|
|
|
|
-- journal7_str = unlines
|
|
-- ["2007/01/01 * opening balance"
|
|
-- ," assets:cash $4.82"
|
|
-- ," equity:opening balances "
|
|
-- ,""
|
|
-- ,"2007/01/01 * opening balance"
|
|
-- ," income:interest $-4.82"
|
|
-- ," equity:opening balances "
|
|
-- ,""
|
|
-- ,"2007/01/02 * ayres suites"
|
|
-- ," expenses:vacation $179.92"
|
|
-- ," assets:checking "
|
|
-- ,""
|
|
-- ,"2007/01/02 * auto transfer to savings"
|
|
-- ," assets:saving $200.00"
|
|
-- ," assets:checking "
|
|
-- ,""
|
|
-- ,"2007/01/03 * poquito mas"
|
|
-- ," expenses:food:dining $4.82"
|
|
-- ," assets:cash "
|
|
-- ,""
|
|
-- ,"2007/01/03 * verizon"
|
|
-- ," expenses:phone $95.11"
|
|
-- ," assets:checking "
|
|
-- ,""
|
|
-- ,"2007/01/03 * discover"
|
|
-- ," liabilities:credit cards:discover $80.00"
|
|
-- ," assets:checking "
|
|
-- ,""
|
|
-- ,"2007/01/04 * blue cross"
|
|
-- ," expenses:health:insurance $90.00"
|
|
-- ," assets:checking "
|
|
-- ,""
|
|
-- ,"2007/01/05 * village market liquor"
|
|
-- ," expenses:food:dining $6.48"
|
|
-- ," assets:checking "
|
|
-- ,""
|
|
-- ]
|
|
|
|
journal7 :: Journal
|
|
journal7 = nulljournal {jtxns =
|
|
[
|
|
txnTieKnot Transaction {
|
|
tsourcepos=nullsourcepos,
|
|
tdate=parsedate "2007/01/01",
|
|
tdate2=Nothing,
|
|
tstatus=Uncleared,
|
|
tcode="*",
|
|
tdescription="opening balance",
|
|
tcomment="",
|
|
ttags=[],
|
|
tpostings=
|
|
["assets:cash" `post` usd 4.82
|
|
,"equity:opening balances" `post` usd (-4.82)
|
|
],
|
|
tpreceding_comment_lines=""
|
|
}
|
|
,
|
|
txnTieKnot Transaction {
|
|
tsourcepos=nullsourcepos,
|
|
tdate=parsedate "2007/02/01",
|
|
tdate2=Nothing,
|
|
tstatus=Uncleared,
|
|
tcode="*",
|
|
tdescription="ayres suites",
|
|
tcomment="",
|
|
ttags=[],
|
|
tpostings=
|
|
["expenses:vacation" `post` usd 179.92
|
|
,"assets:checking" `post` usd (-179.92)
|
|
],
|
|
tpreceding_comment_lines=""
|
|
}
|
|
,
|
|
txnTieKnot Transaction {
|
|
tsourcepos=nullsourcepos,
|
|
tdate=parsedate "2007/01/02",
|
|
tdate2=Nothing,
|
|
tstatus=Uncleared,
|
|
tcode="*",
|
|
tdescription="auto transfer to savings",
|
|
tcomment="",
|
|
ttags=[],
|
|
tpostings=
|
|
["assets:saving" `post` usd 200
|
|
,"assets:checking" `post` usd (-200)
|
|
],
|
|
tpreceding_comment_lines=""
|
|
}
|
|
,
|
|
txnTieKnot Transaction {
|
|
tsourcepos=nullsourcepos,
|
|
tdate=parsedate "2007/01/03",
|
|
tdate2=Nothing,
|
|
tstatus=Uncleared,
|
|
tcode="*",
|
|
tdescription="poquito mas",
|
|
tcomment="",
|
|
ttags=[],
|
|
tpostings=
|
|
["expenses:food:dining" `post` usd 4.82
|
|
,"assets:cash" `post` usd (-4.82)
|
|
],
|
|
tpreceding_comment_lines=""
|
|
}
|
|
,
|
|
txnTieKnot Transaction {
|
|
tsourcepos=nullsourcepos,
|
|
tdate=parsedate "2007/01/03",
|
|
tdate2=Nothing,
|
|
tstatus=Uncleared,
|
|
tcode="*",
|
|
tdescription="verizon",
|
|
tcomment="",
|
|
ttags=[],
|
|
tpostings=
|
|
["expenses:phone" `post` usd 95.11
|
|
,"assets:checking" `post` usd (-95.11)
|
|
],
|
|
tpreceding_comment_lines=""
|
|
}
|
|
,
|
|
txnTieKnot Transaction {
|
|
tsourcepos=nullsourcepos,
|
|
tdate=parsedate "2007/01/03",
|
|
tdate2=Nothing,
|
|
tstatus=Uncleared,
|
|
tcode="*",
|
|
tdescription="discover",
|
|
tcomment="",
|
|
ttags=[],
|
|
tpostings=
|
|
["liabilities:credit cards:discover" `post` usd 80
|
|
,"assets:checking" `post` usd (-80)
|
|
],
|
|
tpreceding_comment_lines=""
|
|
}
|
|
]
|
|
}
|
|
|
|
ledger7 :: Ledger
|
|
ledger7 = ledgerFromJournal Any journal7
|