reorganize tests
This commit is contained in:
parent
e03ada3bd3
commit
dd9e78a67a
@ -37,16 +37,16 @@ import Hledger.Data.Utils
|
|||||||
|
|
||||||
tests_Hledger_Data = TestList
|
tests_Hledger_Data = TestList
|
||||||
[
|
[
|
||||||
-- Hledger.Data.Account.tests_Account
|
tests_Hledger_Data_Account
|
||||||
-- ,Hledger.Data.AccountName.tests_AccountName
|
,tests_Hledger_Data_AccountName
|
||||||
Hledger.Data.Amount.tests_Amount
|
,tests_Hledger_Data_Amount
|
||||||
-- ,Hledger.Data.Commodity.tests_Commodity
|
,tests_Hledger_Data_Commodity
|
||||||
,Hledger.Data.Dates.tests_Dates
|
,tests_Hledger_Data_Dates
|
||||||
,Hledger.Data.Transaction.tests_Transaction
|
,tests_Hledger_Data_Journal
|
||||||
-- ,Hledger.Data.Hledger.Data.tests_Hledger.Data
|
,tests_Hledger_Data_Ledger
|
||||||
-- ,Hledger.Data.Journal.tests_Journal
|
,tests_Hledger_Data_Posting
|
||||||
-- ,Hledger.Data.Posting.tests_Posting
|
,tests_Hledger_Data_TimeLog
|
||||||
,Hledger.Data.TimeLog.tests_TimeLog
|
,tests_Hledger_Data_Transaction
|
||||||
-- ,Hledger.Data.Types.tests_Types
|
-- ,tests_Hledger_Data_Types
|
||||||
-- ,Hledger.Data.Utils.tests_Utils
|
-- ,tests_Hledger_Data_Utils
|
||||||
]
|
]
|
||||||
|
|||||||
@ -25,3 +25,6 @@ instance Eq Account where
|
|||||||
|
|
||||||
nullacct = Account "" [] nullmixedamt
|
nullacct = Account "" [] nullmixedamt
|
||||||
|
|
||||||
|
tests_Hledger_Data_Account = TestList [
|
||||||
|
]
|
||||||
|
|
||||||
|
|||||||
@ -173,3 +173,29 @@ elideAccountName width s =
|
|||||||
clipAccountName :: Int -> AccountName -> AccountName
|
clipAccountName :: Int -> AccountName -> AccountName
|
||||||
clipAccountName n = accountNameFromComponents . take n . accountNameComponents
|
clipAccountName n = accountNameFromComponents . take n . accountNameComponents
|
||||||
|
|
||||||
|
tests_Hledger_Data_AccountName = TestList
|
||||||
|
[
|
||||||
|
"accountNameTreeFrom" ~: do
|
||||||
|
accountNameTreeFrom ["a"] `is` Node "top" [Node "a" []]
|
||||||
|
accountNameTreeFrom ["a","b"] `is` Node "top" [Node "a" [], Node "b" []]
|
||||||
|
accountNameTreeFrom ["a","a:b"] `is` Node "top" [Node "a" [Node "a:b" []]]
|
||||||
|
accountNameTreeFrom ["a:b:c"] `is` Node "top" [Node "a" [Node "a:b" [Node "a:b:c" []]]]
|
||||||
|
|
||||||
|
,"expandAccountNames" ~:
|
||||||
|
expandAccountNames ["assets:cash","assets:checking","expenses:vacation"] `is`
|
||||||
|
["assets","assets:cash","assets:checking","expenses","expenses:vacation"]
|
||||||
|
|
||||||
|
,"isAccountNamePrefixOf" ~: do
|
||||||
|
"assets" `isAccountNamePrefixOf` "assets" `is` False
|
||||||
|
"assets" `isAccountNamePrefixOf` "assets:bank" `is` True
|
||||||
|
"assets" `isAccountNamePrefixOf` "assets:bank:checking" `is` True
|
||||||
|
"my assets" `isAccountNamePrefixOf` "assets:bank" `is` False
|
||||||
|
|
||||||
|
,"isSubAccountNameOf" ~: do
|
||||||
|
"assets" `isSubAccountNameOf` "assets" `is` False
|
||||||
|
"assets:bank" `isSubAccountNameOf` "assets" `is` True
|
||||||
|
"assets:bank:checking" `isSubAccountNameOf` "assets" `is` False
|
||||||
|
"assets:bank" `isSubAccountNameOf` "my assets" `is` False
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|||||||
@ -38,7 +38,32 @@ price-discarding arithmetic which ignores and discards prices.
|
|||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
module Hledger.Data.Amount
|
module Hledger.Data.Amount (
|
||||||
|
amounts,
|
||||||
|
canonicaliseAmount,
|
||||||
|
canonicaliseMixedAmount,
|
||||||
|
convertMixedAmountTo,
|
||||||
|
costOfAmount,
|
||||||
|
costOfMixedAmount,
|
||||||
|
isNegativeMixedAmount,
|
||||||
|
isReallyZeroMixedAmountCost,
|
||||||
|
isZeroMixedAmount,
|
||||||
|
maxprecision,
|
||||||
|
missingamt,
|
||||||
|
normaliseMixedAmount,
|
||||||
|
nullamt,
|
||||||
|
nullmixedamt,
|
||||||
|
punctuatethousands,
|
||||||
|
showMixedAmount,
|
||||||
|
showMixedAmountDebug,
|
||||||
|
showMixedAmountOrZero,
|
||||||
|
showMixedAmountOrZeroWithoutPrice,
|
||||||
|
showMixedAmountWithoutPrice,
|
||||||
|
showMixedAmountWithPrecision,
|
||||||
|
sumMixedAmountsPreservingHighestPrecision,
|
||||||
|
tests_Hledger_Data_Amount
|
||||||
|
-- Hledger.Data.Amount.tests_Hledger_Data_Amount
|
||||||
|
)
|
||||||
where
|
where
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Data.Map (findWithDefault)
|
import Data.Map (findWithDefault)
|
||||||
@ -216,14 +241,14 @@ isNegativeMixedAmount m = case as of [a] -> Just $ isNegativeAmount a
|
|||||||
isReallyZeroMixedAmountCost :: MixedAmount -> Bool
|
isReallyZeroMixedAmountCost :: MixedAmount -> Bool
|
||||||
isReallyZeroMixedAmountCost = isReallyZeroMixedAmount . costOfMixedAmount
|
isReallyZeroMixedAmountCost = isReallyZeroMixedAmount . costOfMixedAmount
|
||||||
|
|
||||||
-- | MixedAmount derives Eq in Types.hs, but that doesn't know that we
|
-- -- | MixedAmount derives Eq in Types.hs, but that doesn't know that we
|
||||||
-- want $0 = EUR0 = 0. Yet we don't want to drag all this code in there.
|
-- -- want $0 = EUR0 = 0. Yet we don't want to drag all this code in there.
|
||||||
-- When zero equality is important, use this, for now; should be used
|
-- -- When zero equality is important, use this, for now; should be used
|
||||||
-- everywhere.
|
-- -- everywhere.
|
||||||
mixedAmountEquals :: MixedAmount -> MixedAmount -> Bool
|
-- mixedAmountEquals :: MixedAmount -> MixedAmount -> Bool
|
||||||
mixedAmountEquals a b = amounts a' == amounts b' || (isZeroMixedAmount a' && isZeroMixedAmount b')
|
-- mixedAmountEquals a b = amounts a' == amounts b' || (isZeroMixedAmount a' && isZeroMixedAmount b')
|
||||||
where a' = normaliseMixedAmount a
|
-- where a' = normaliseMixedAmount a
|
||||||
b' = normaliseMixedAmount b
|
-- b' = normaliseMixedAmount b
|
||||||
|
|
||||||
-- | Get the string representation of a mixed amount, showing each of
|
-- | Get the string representation of a mixed amount, showing each of
|
||||||
-- its component amounts. NB a mixed amount can have an empty amounts
|
-- its component amounts. NB a mixed amount can have an empty amounts
|
||||||
@ -231,8 +256,8 @@ mixedAmountEquals a b = amounts a' == amounts b' || (isZeroMixedAmount a' && isZ
|
|||||||
showMixedAmount :: MixedAmount -> String
|
showMixedAmount :: MixedAmount -> String
|
||||||
showMixedAmount m = vConcatRightAligned $ map show $ amounts $ normaliseMixedAmount m
|
showMixedAmount m = vConcatRightAligned $ map show $ amounts $ normaliseMixedAmount m
|
||||||
|
|
||||||
setMixedAmountPrecision :: Int -> MixedAmount -> MixedAmount
|
-- setMixedAmountPrecision :: Int -> MixedAmount -> MixedAmount
|
||||||
setMixedAmountPrecision p (Mixed as) = Mixed $ map (setAmountPrecision p) as
|
-- setMixedAmountPrecision p (Mixed as) = Mixed $ map (setAmountPrecision p) as
|
||||||
|
|
||||||
-- | Get the string representation of a mixed amount, showing each of its
|
-- | Get the string representation of a mixed amount, showing each of its
|
||||||
-- component amounts with the specified precision, ignoring their
|
-- component amounts with the specified precision, ignoring their
|
||||||
@ -382,7 +407,7 @@ missingamt :: MixedAmount
|
|||||||
missingamt = Mixed [Amount Commodity {symbol="AUTO",side=L,spaced=False,comma=False,precision=0} 0 Nothing]
|
missingamt = Mixed [Amount Commodity {symbol="AUTO",side=L,spaced=False,comma=False,precision=0} 0 Nothing]
|
||||||
|
|
||||||
|
|
||||||
tests_Amount = TestList [
|
tests_Hledger_Data_Amount = TestList [
|
||||||
|
|
||||||
"showMixedAmount" ~: do
|
"showMixedAmount" ~: do
|
||||||
showMixedAmount (Mixed [Amount dollar 0 Nothing]) `is` "$0.00"
|
showMixedAmount (Mixed [Amount dollar 0 Nothing]) `is` "$0.00"
|
||||||
@ -417,5 +442,13 @@ tests_Amount = TestList [
|
|||||||
Amount dollar (-0.25) Nothing])
|
Amount dollar (-0.25) Nothing])
|
||||||
`is` Mixed [Amount dollar 0 Nothing]
|
`is` Mixed [Amount dollar 0 Nothing]
|
||||||
|
|
||||||
|
,"normaliseMixedAmount" ~: do
|
||||||
|
normaliseMixedAmount (Mixed []) ~?= Mixed [nullamt]
|
||||||
|
|
||||||
|
,"punctuatethousands 1" ~: punctuatethousands "" `is` ""
|
||||||
|
|
||||||
|
,"punctuatethousands 2" ~: punctuatethousands "1234567.8901" `is` "1,234,567.8901"
|
||||||
|
|
||||||
|
,"punctuatethousands 3" ~: punctuatethousands "-100" `is` "-100"
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
@ -57,3 +57,7 @@ canonicaliseCommodities cs =
|
|||||||
commoditymap = Map.fromList [(s, commoditieswithsymbol s) | s <- symbols]
|
commoditymap = Map.fromList [(s, commoditieswithsymbol s) | s <- symbols]
|
||||||
commoditieswithsymbol s = filter ((s==) . symbol) cs
|
commoditieswithsymbol s = filter ((s==) . symbol) cs
|
||||||
symbols = nub $ map symbol cs
|
symbols = nub $ map symbol cs
|
||||||
|
|
||||||
|
tests_Hledger_Data_Commodity = TestList [
|
||||||
|
]
|
||||||
|
|
||||||
|
|||||||
@ -470,7 +470,8 @@ nulldatespan = DateSpan Nothing Nothing
|
|||||||
|
|
||||||
nulldate = parsedate "1900/01/01"
|
nulldate = parsedate "1900/01/01"
|
||||||
|
|
||||||
tests_Dates = TestList [
|
tests_Hledger_Data_Dates = TestList
|
||||||
|
[
|
||||||
|
|
||||||
"splitSpan" ~: do
|
"splitSpan" ~: do
|
||||||
let gives (interval, span) = (splitSpan interval span `is`)
|
let gives (interval, span) = (splitSpan interval span `is`)
|
||||||
@ -489,4 +490,53 @@ tests_Dates = TestList [
|
|||||||
(Quarterly,mkdatespan "2008/01/01" "2008/01/01") `gives`
|
(Quarterly,mkdatespan "2008/01/01" "2008/01/01") `gives`
|
||||||
[mkdatespan "2008/01/01" "2008/01/01"]
|
[mkdatespan "2008/01/01" "2008/01/01"]
|
||||||
|
|
||||||
]
|
,"parsedate" ~: do
|
||||||
|
let date1 = parsedate "2008/11/26"
|
||||||
|
parsedate "2008/02/03" `is` parsetimewith "%Y/%m/%d" "2008/02/03" date1
|
||||||
|
parsedate "2008-02-03" `is` parsetimewith "%Y/%m/%d" "2008/02/03" date1
|
||||||
|
|
||||||
|
,"period expressions" ~: do
|
||||||
|
let todaysdate = parsedate "2008/11/26"
|
||||||
|
let str `gives` result = show (parsewith (periodexpr todaysdate) str) `is` ("Right " ++ result)
|
||||||
|
"from aug to oct" `gives` "(NoInterval,DateSpan (Just 2008-08-01) (Just 2008-10-01))"
|
||||||
|
"aug to oct" `gives` "(NoInterval,DateSpan (Just 2008-08-01) (Just 2008-10-01))"
|
||||||
|
"every day from aug to oct" `gives` "(Daily,DateSpan (Just 2008-08-01) (Just 2008-10-01))"
|
||||||
|
"daily from aug" `gives` "(Daily,DateSpan (Just 2008-08-01) Nothing)"
|
||||||
|
"every week to 2009" `gives` "(Weekly,DateSpan Nothing (Just 2009-01-01))"
|
||||||
|
|
||||||
|
,"fixSmartDateStr" ~: do
|
||||||
|
let gives = is . fixSmartDateStr (parsedate "2008/11/26")
|
||||||
|
"1999-12-02" `gives` "1999/12/02"
|
||||||
|
"1999.12.02" `gives` "1999/12/02"
|
||||||
|
"1999/3/2" `gives` "1999/03/02"
|
||||||
|
"19990302" `gives` "1999/03/02"
|
||||||
|
"2008/2" `gives` "2008/02/01"
|
||||||
|
"0020/2" `gives` "0020/02/01"
|
||||||
|
"1000" `gives` "1000/01/01"
|
||||||
|
"4/2" `gives` "2008/04/02"
|
||||||
|
"2" `gives` "2008/11/02"
|
||||||
|
"January" `gives` "2008/01/01"
|
||||||
|
"feb" `gives` "2008/02/01"
|
||||||
|
"today" `gives` "2008/11/26"
|
||||||
|
"yesterday" `gives` "2008/11/25"
|
||||||
|
"tomorrow" `gives` "2008/11/27"
|
||||||
|
"this day" `gives` "2008/11/26"
|
||||||
|
"last day" `gives` "2008/11/25"
|
||||||
|
"next day" `gives` "2008/11/27"
|
||||||
|
"this week" `gives` "2008/11/24" -- last monday
|
||||||
|
"last week" `gives` "2008/11/17" -- previous monday
|
||||||
|
"next week" `gives` "2008/12/01" -- next monday
|
||||||
|
"this month" `gives` "2008/11/01"
|
||||||
|
"last month" `gives` "2008/10/01"
|
||||||
|
"next month" `gives` "2008/12/01"
|
||||||
|
"this quarter" `gives` "2008/10/01"
|
||||||
|
"last quarter" `gives` "2008/07/01"
|
||||||
|
"next quarter" `gives` "2009/01/01"
|
||||||
|
"this year" `gives` "2008/01/01"
|
||||||
|
"last year" `gives` "2007/01/01"
|
||||||
|
"next year" `gives` "2009/01/01"
|
||||||
|
-- "last wed" `gives` "2008/11/19"
|
||||||
|
-- "next friday" `gives` "2008/11/28"
|
||||||
|
-- "next january" `gives` "2009/01/01"
|
||||||
|
|
||||||
|
]
|
||||||
|
|||||||
@ -389,3 +389,7 @@ postingsByAccount ps = m'
|
|||||||
sortedps = sortBy (comparing paccount) ps
|
sortedps = sortBy (comparing paccount) ps
|
||||||
groupedps = groupBy (\p1 p2 -> paccount p1 == paccount p2) sortedps
|
groupedps = groupBy (\p1 p2 -> paccount p1 == paccount p2) sortedps
|
||||||
m' = Map.fromList [(paccount $ head g, g) | g <- groupedps]
|
m' = Map.fromList [(paccount $ head g, g) | g <- groupedps]
|
||||||
|
|
||||||
|
tests_Hledger_Data_Journal = TestList [
|
||||||
|
]
|
||||||
|
|
||||||
|
|||||||
@ -122,3 +122,8 @@ rawdatespan = journalDateSpan . journal
|
|||||||
|
|
||||||
ledgeramounts :: Ledger -> [MixedAmount]
|
ledgeramounts :: Ledger -> [MixedAmount]
|
||||||
ledgeramounts = journalAmounts . journal
|
ledgeramounts = journalAmounts . journal
|
||||||
|
|
||||||
|
tests_Hledger_Data_Ledger = TestList
|
||||||
|
[
|
||||||
|
]
|
||||||
|
|
||||||
|
|||||||
@ -91,3 +91,6 @@ postingsDateSpan [] = DateSpan Nothing Nothing
|
|||||||
postingsDateSpan ps = DateSpan (Just $ postingDate $ head ps') (Just $ addDays 1 $ postingDate $ last ps')
|
postingsDateSpan ps = DateSpan (Just $ postingDate $ head ps') (Just $ addDays 1 $ postingDate $ last ps')
|
||||||
where ps' = sortBy (comparing postingDate) ps
|
where ps' = sortBy (comparing postingDate) ps
|
||||||
|
|
||||||
|
tests_Hledger_Data_Posting = TestList [
|
||||||
|
]
|
||||||
|
|
||||||
|
|||||||
@ -90,7 +90,7 @@ entryFromTimeLogInOut i o
|
|||||||
ps = [Posting{pstatus=False,paccount=acctname,pamount=amount,
|
ps = [Posting{pstatus=False,paccount=acctname,pamount=amount,
|
||||||
pcomment="",ptype=VirtualPosting,pmetadata=[],ptransaction=Just t}]
|
pcomment="",ptype=VirtualPosting,pmetadata=[],ptransaction=Just t}]
|
||||||
|
|
||||||
tests_TimeLog = TestList [
|
tests_Hledger_Data_TimeLog = TestList [
|
||||||
|
|
||||||
"timeLogEntriesToTransactions" ~: do
|
"timeLogEntriesToTransactions" ~: do
|
||||||
today <- getCurrentDay
|
today <- getCurrentDay
|
||||||
|
|||||||
@ -182,7 +182,7 @@ txnTieKnot t@Transaction{tpostings=ps} = t{tpostings=map (settxn t) ps}
|
|||||||
settxn :: Transaction -> Posting -> Posting
|
settxn :: Transaction -> Posting -> Posting
|
||||||
settxn t p = p{ptransaction=Just t}
|
settxn t p = p{ptransaction=Just t}
|
||||||
|
|
||||||
tests_Transaction = TestList [
|
tests_Hledger_Data_Transaction = TestList [
|
||||||
"showTransaction" ~: do
|
"showTransaction" ~: do
|
||||||
assertEqual "show a balanced transaction, eliding last amount"
|
assertEqual "show a balanced transaction, eliding last amount"
|
||||||
(unlines
|
(unlines
|
||||||
@ -264,4 +264,67 @@ tests_Transaction = TestList [
|
|||||||
,Posting False "b" missingamt "" RegularPosting [] Nothing
|
,Posting False "b" missingamt "" RegularPosting [] Nothing
|
||||||
] ""))
|
] ""))
|
||||||
|
|
||||||
|
,"balanceTransaction" ~: do
|
||||||
|
assertBool "detect unbalanced entry, sign error"
|
||||||
|
(isLeft $ balanceTransaction Nothing
|
||||||
|
(Transaction (parsedate "2007/01/28") Nothing False "" "test" "" []
|
||||||
|
[Posting False "a" (Mixed [dollars 1]) "" RegularPosting [] Nothing,
|
||||||
|
Posting False "b" (Mixed [dollars 1]) "" RegularPosting [] Nothing
|
||||||
|
] ""))
|
||||||
|
assertBool "detect unbalanced entry, multiple missing amounts"
|
||||||
|
(isLeft $ balanceTransaction Nothing
|
||||||
|
(Transaction (parsedate "2007/01/28") Nothing False "" "test" "" []
|
||||||
|
[Posting False "a" missingamt "" RegularPosting [] Nothing,
|
||||||
|
Posting False "b" missingamt "" RegularPosting [] Nothing
|
||||||
|
] ""))
|
||||||
|
let e = balanceTransaction Nothing (Transaction (parsedate "2007/01/28") Nothing False "" "test" "" []
|
||||||
|
[Posting False "a" (Mixed [dollars 1]) "" RegularPosting [] Nothing,
|
||||||
|
Posting False "b" missingamt "" RegularPosting [] Nothing
|
||||||
|
] "")
|
||||||
|
assertBool "one missing amount should be ok" (isRight e)
|
||||||
|
assertEqual "balancing amount is added"
|
||||||
|
(Mixed [dollars (-1)])
|
||||||
|
(case e of
|
||||||
|
Right e' -> (pamount $ last $ tpostings e')
|
||||||
|
Left _ -> error' "should not happen")
|
||||||
|
|
||||||
|
,"isTransactionBalanced" ~: do
|
||||||
|
let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" "" []
|
||||||
|
[Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting [] (Just t)
|
||||||
|
,Posting False "c" (Mixed [dollars (-1.00)]) "" RegularPosting [] (Just t)
|
||||||
|
] ""
|
||||||
|
assertBool "detect balanced" (isTransactionBalanced Nothing t)
|
||||||
|
let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" "" []
|
||||||
|
[Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting [] (Just t)
|
||||||
|
,Posting False "c" (Mixed [dollars (-1.01)]) "" RegularPosting [] (Just t)
|
||||||
|
] ""
|
||||||
|
assertBool "detect unbalanced" (not $ isTransactionBalanced Nothing t)
|
||||||
|
let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" "" []
|
||||||
|
[Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting [] (Just t)
|
||||||
|
] ""
|
||||||
|
assertBool "detect unbalanced, one posting" (not $ isTransactionBalanced Nothing t)
|
||||||
|
let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" "" []
|
||||||
|
[Posting False "b" (Mixed [dollars 0]) "" RegularPosting [] (Just t)
|
||||||
|
] ""
|
||||||
|
assertBool "one zero posting is considered balanced for now" (isTransactionBalanced Nothing t)
|
||||||
|
let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" "" []
|
||||||
|
[Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting [] (Just t)
|
||||||
|
,Posting False "c" (Mixed [dollars (-1.00)]) "" RegularPosting [] (Just t)
|
||||||
|
,Posting False "d" (Mixed [dollars 100]) "" VirtualPosting [] (Just t)
|
||||||
|
] ""
|
||||||
|
assertBool "virtual postings don't need to balance" (isTransactionBalanced Nothing t)
|
||||||
|
let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" "" []
|
||||||
|
[Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting [] (Just t)
|
||||||
|
,Posting False "c" (Mixed [dollars (-1.00)]) "" RegularPosting [] (Just t)
|
||||||
|
,Posting False "d" (Mixed [dollars 100]) "" BalancedVirtualPosting [] (Just t)
|
||||||
|
] ""
|
||||||
|
assertBool "balanced virtual postings need to balance among themselves" (not $ isTransactionBalanced Nothing t)
|
||||||
|
let t = Transaction (parsedate "2009/01/01") Nothing False "" "a" "" []
|
||||||
|
[Posting False "b" (Mixed [dollars 1.00]) "" RegularPosting [] (Just t)
|
||||||
|
,Posting False "c" (Mixed [dollars (-1.00)]) "" RegularPosting [] (Just t)
|
||||||
|
,Posting False "d" (Mixed [dollars 100]) "" BalancedVirtualPosting [] (Just t)
|
||||||
|
,Posting False "e" (Mixed [dollars (-100)]) "" BalancedVirtualPosting [] (Just t)
|
||||||
|
] ""
|
||||||
|
assertBool "balanced virtual postings need to balance among themselves (2)" (isTransactionBalanced Nothing t)
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
@ -137,12 +137,12 @@ myTimelog = myTimelogPath >>= readJournalFile Nothing >>= either error' return
|
|||||||
|
|
||||||
tests_Hledger_Read = TestList
|
tests_Hledger_Read = TestList
|
||||||
[
|
[
|
||||||
|
tests_Hledger_Read_JournalReader,
|
||||||
|
tests_Hledger_Read_TimelogReader,
|
||||||
|
|
||||||
"journalFile" ~: do
|
"journalFile" ~: do
|
||||||
assertBool "journalFile should parse an empty file" (isRight $ parseWithCtx nullctx JournalReader.journalFile "")
|
assertBool "journalFile should parse an empty file" (isRight $ parseWithCtx nullctx JournalReader.journalFile "")
|
||||||
jE <- readJournal Nothing "" -- don't know how to get it from journalFile
|
jE <- readJournal Nothing "" -- don't know how to get it from journalFile
|
||||||
either error' (assertBool "journalFile parsing an empty file should give an empty journal" . null . jtxns) jE
|
either error' (assertBool "journalFile parsing an empty file should give an empty journal" . null . jtxns) jE
|
||||||
|
|
||||||
,JournalReader.tests_JournalReader
|
|
||||||
,TimelogReader.tests_TimelogReader
|
|
||||||
]
|
]
|
||||||
|
|||||||
@ -104,17 +104,17 @@ i, o, b, h
|
|||||||
-}
|
-}
|
||||||
|
|
||||||
module Hledger.Read.JournalReader (
|
module Hledger.Read.JournalReader (
|
||||||
tests_JournalReader,
|
emptyLine,
|
||||||
reader,
|
|
||||||
journalFile,
|
|
||||||
journalAddFile,
|
journalAddFile,
|
||||||
someamount,
|
journalFile,
|
||||||
ledgeraccountname,
|
ledgeraccountname,
|
||||||
|
ledgerdatetime,
|
||||||
|
ledgerDefaultYear,
|
||||||
ledgerExclamationDirective,
|
ledgerExclamationDirective,
|
||||||
ledgerHistoricalPrice,
|
ledgerHistoricalPrice,
|
||||||
ledgerDefaultYear,
|
reader,
|
||||||
emptyLine,
|
someamount,
|
||||||
ledgerdatetime,
|
tests_Hledger_Read_JournalReader
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
import Control.Monad.Error (ErrorT(..), throwError, catchError)
|
import Control.Monad.Error (ErrorT(..), throwError, catchError)
|
||||||
@ -590,7 +590,7 @@ numberpartsstartingwithpoint = do
|
|||||||
return ("",frac)
|
return ("",frac)
|
||||||
|
|
||||||
|
|
||||||
tests_JournalReader = TestList [
|
tests_Hledger_Read_JournalReader = TestList [
|
||||||
|
|
||||||
"ledgerTransaction" ~: do
|
"ledgerTransaction" ~: do
|
||||||
assertParseEqual (parseWithCtx nullctx ledgerTransaction entry1_str) entry1
|
assertParseEqual (parseWithCtx nullctx ledgerTransaction entry1_str) entry1
|
||||||
|
|||||||
@ -43,8 +43,8 @@ o 2007/03/10 17:26:02
|
|||||||
-}
|
-}
|
||||||
|
|
||||||
module Hledger.Read.TimelogReader (
|
module Hledger.Read.TimelogReader (
|
||||||
tests_TimelogReader,
|
|
||||||
reader,
|
reader,
|
||||||
|
tests_Hledger_Read_TimelogReader
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
import Control.Monad.Error (ErrorT(..))
|
import Control.Monad.Error (ErrorT(..))
|
||||||
@ -96,6 +96,6 @@ timelogentry = do
|
|||||||
comment <- optionMaybe (many1 spacenonewline >> liftM2 (++) getParentAccount restofline)
|
comment <- optionMaybe (many1 spacenonewline >> liftM2 (++) getParentAccount restofline)
|
||||||
return $ TimeLogEntry (read [code]) datetime (maybe "" rstrip comment)
|
return $ TimeLogEntry (read [code]) datetime (maybe "" rstrip comment)
|
||||||
|
|
||||||
tests_TimelogReader = TestList [
|
tests_Hledger_Read_TimelogReader = TestList [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
909
hledger/Hledger/Cli.hs
Normal file
909
hledger/Hledger/Cli.hs
Normal file
@ -0,0 +1,909 @@
|
|||||||
|
{-|
|
||||||
|
Hledger.Cli re-exports the options, utilities and commands provided by the
|
||||||
|
hledger command-line program.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Hledger.Cli (
|
||||||
|
module Hledger.Cli.Add,
|
||||||
|
module Hledger.Cli.Balance,
|
||||||
|
module Hledger.Cli.Convert,
|
||||||
|
module Hledger.Cli.Histogram,
|
||||||
|
module Hledger.Cli.Print,
|
||||||
|
module Hledger.Cli.Register,
|
||||||
|
module Hledger.Cli.Stats,
|
||||||
|
module Hledger.Cli.Options,
|
||||||
|
module Hledger.Cli.Utils,
|
||||||
|
tests_Hledger_Cli
|
||||||
|
)
|
||||||
|
where
|
||||||
|
import Hledger.Cli.Add
|
||||||
|
import Hledger.Cli.Balance
|
||||||
|
import Hledger.Cli.Convert
|
||||||
|
import Hledger.Cli.Histogram
|
||||||
|
import Hledger.Cli.Print
|
||||||
|
import Hledger.Cli.Register
|
||||||
|
import Hledger.Cli.Stats
|
||||||
|
import Hledger.Cli.Options
|
||||||
|
import Hledger.Cli.Utils
|
||||||
|
|
||||||
|
|
||||||
|
import qualified Data.Map as Map
|
||||||
|
import System.Time (ClockTime(TOD))
|
||||||
|
|
||||||
|
import Hledger.Data -- including testing utils in Hledger.Data.Utils
|
||||||
|
import Hledger.Read
|
||||||
|
import Hledger.Read.JournalReader (someamount)
|
||||||
|
|
||||||
|
|
||||||
|
-- | hledger and hledger-lib's unit tests aggregated from all modules
|
||||||
|
-- plus some more which are easier to define here for now.
|
||||||
|
-- tests_Hledger_Cli1 :: Test
|
||||||
|
tests_Hledger_Cli = TestList
|
||||||
|
[
|
||||||
|
tests_Hledger_Data
|
||||||
|
,tests_Hledger_Read
|
||||||
|
-- ,tests_Hledger_Cli_Add
|
||||||
|
-- ,tests_Hledger_Cli_Balance
|
||||||
|
,tests_Hledger_Cli_Convert
|
||||||
|
-- ,tests_Hledger_Cli_Histogram
|
||||||
|
,tests_Hledger_Cli_Options
|
||||||
|
-- ,tests_Hledger_Cli_Print
|
||||||
|
,tests_Hledger_Cli_Register
|
||||||
|
-- ,tests_Hledger_Cli_Stats
|
||||||
|
|
||||||
|
|
||||||
|
,"account directive" ~:
|
||||||
|
let sameParse str1 str2 = do j1 <- readJournal Nothing str1 >>= either error' return
|
||||||
|
j2 <- readJournal Nothing str2 >>= either error' return
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
,"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"]
|
||||||
|
|
||||||
|
,"balance report tests" ~:
|
||||||
|
let (opts,args) `gives` es = do
|
||||||
|
l <- samplejournalwithopts opts args
|
||||||
|
t <- getCurrentLocalTime
|
||||||
|
balanceReportAsText opts (balanceReport opts (optsToFilterSpec opts args t) l) `is` unlines es
|
||||||
|
in TestList
|
||||||
|
[
|
||||||
|
|
||||||
|
"balance report with no args" ~:
|
||||||
|
([], []) `gives`
|
||||||
|
[" $-1 assets"
|
||||||
|
," $1 bank:saving"
|
||||||
|
," $-2 cash"
|
||||||
|
," $2 expenses"
|
||||||
|
," $1 food"
|
||||||
|
," $1 supplies"
|
||||||
|
," $-2 income"
|
||||||
|
," $-1 gifts"
|
||||||
|
," $-1 salary"
|
||||||
|
," $1 liabilities:debts"
|
||||||
|
,"--------------------"
|
||||||
|
," $0"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"balance report can be limited with --depth" ~:
|
||||||
|
([Depth "1"], []) `gives`
|
||||||
|
[" $-1 assets"
|
||||||
|
," $2 expenses"
|
||||||
|
," $-2 income"
|
||||||
|
," $1 liabilities"
|
||||||
|
,"--------------------"
|
||||||
|
," $0"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"balance report with account pattern o" ~:
|
||||||
|
([SubTotal], ["o"]) `gives`
|
||||||
|
[" $1 expenses:food"
|
||||||
|
," $-2 income"
|
||||||
|
," $-1 gifts"
|
||||||
|
," $-1 salary"
|
||||||
|
,"--------------------"
|
||||||
|
," $-1"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"balance report with account pattern o and --depth 1" ~:
|
||||||
|
([Depth "1"], ["o"]) `gives`
|
||||||
|
[" $1 expenses"
|
||||||
|
," $-2 income"
|
||||||
|
,"--------------------"
|
||||||
|
," $-1"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"balance report with account pattern a" ~:
|
||||||
|
([], ["a"]) `gives`
|
||||||
|
[" $-1 assets"
|
||||||
|
," $1 bank:saving"
|
||||||
|
," $-2 cash"
|
||||||
|
," $-1 income:salary"
|
||||||
|
," $1 liabilities:debts"
|
||||||
|
,"--------------------"
|
||||||
|
," $-1"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"balance report with account pattern e" ~:
|
||||||
|
([], ["e"]) `gives`
|
||||||
|
[" $-1 assets"
|
||||||
|
," $1 bank:saving"
|
||||||
|
," $-2 cash"
|
||||||
|
," $2 expenses"
|
||||||
|
," $1 food"
|
||||||
|
," $1 supplies"
|
||||||
|
," $-2 income"
|
||||||
|
," $-1 gifts"
|
||||||
|
," $-1 salary"
|
||||||
|
," $1 liabilities:debts"
|
||||||
|
,"--------------------"
|
||||||
|
," $0"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"balance report with unmatched parent of two matched subaccounts" ~:
|
||||||
|
([], ["cash","saving"]) `gives`
|
||||||
|
[" $-1 assets"
|
||||||
|
," $1 bank:saving"
|
||||||
|
," $-2 cash"
|
||||||
|
,"--------------------"
|
||||||
|
," $-1"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"balance report with multi-part account name" ~:
|
||||||
|
([], ["expenses:food"]) `gives`
|
||||||
|
[" $1 expenses:food"
|
||||||
|
,"--------------------"
|
||||||
|
," $1"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"balance report with negative account pattern" ~:
|
||||||
|
([], ["not:assets"]) `gives`
|
||||||
|
[" $2 expenses"
|
||||||
|
," $1 food"
|
||||||
|
," $1 supplies"
|
||||||
|
," $-2 income"
|
||||||
|
," $-1 gifts"
|
||||||
|
," $-1 salary"
|
||||||
|
," $1 liabilities:debts"
|
||||||
|
,"--------------------"
|
||||||
|
," $1"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"balance report negative account pattern always matches full name" ~:
|
||||||
|
([], ["not:e"]) `gives`
|
||||||
|
["--------------------"
|
||||||
|
," 0"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"balance report negative patterns affect totals" ~:
|
||||||
|
([], ["expenses","not:food"]) `gives`
|
||||||
|
[" $1 expenses:supplies"
|
||||||
|
,"--------------------"
|
||||||
|
," $1"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"balance report with -E shows zero-balance accounts" ~:
|
||||||
|
([SubTotal,Empty], ["assets"]) `gives`
|
||||||
|
[" $-1 assets"
|
||||||
|
," $1 bank"
|
||||||
|
," $0 checking"
|
||||||
|
," $1 saving"
|
||||||
|
," $-2 cash"
|
||||||
|
,"--------------------"
|
||||||
|
," $-1"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"balance report with cost basis" ~: do
|
||||||
|
j <- (readJournal Nothing $ unlines
|
||||||
|
[""
|
||||||
|
,"2008/1/1 test "
|
||||||
|
," a:b 10h @ $50"
|
||||||
|
," c:d "
|
||||||
|
]) >>= either error' return
|
||||||
|
let j' = journalCanonicaliseAmounts $ journalConvertAmountsToCost j -- enable cost basis adjustment
|
||||||
|
balanceReportAsText [] (balanceReport [] nullfilterspec j') `is`
|
||||||
|
unlines
|
||||||
|
[" $500 a:b"
|
||||||
|
," $-500 c:d"
|
||||||
|
,"--------------------"
|
||||||
|
," $0"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"balance report elides zero-balance root account(s)" ~: do
|
||||||
|
l <- readJournalWithOpts []
|
||||||
|
(unlines
|
||||||
|
["2008/1/1 one"
|
||||||
|
," test:a 1"
|
||||||
|
," test:b"
|
||||||
|
])
|
||||||
|
balanceReportAsText [] (balanceReport [] nullfilterspec l) `is`
|
||||||
|
unlines
|
||||||
|
[" 1 test:a"
|
||||||
|
," -1 test:b"
|
||||||
|
,"--------------------"
|
||||||
|
," 0"
|
||||||
|
]
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
,"journalCanonicaliseAmounts" ~:
|
||||||
|
"use the greatest precision" ~:
|
||||||
|
(map precision $ journalAmountAndPriceCommodities $ journalCanonicaliseAmounts $ journalWithAmounts ["1","2.00"]) `is` [2,2]
|
||||||
|
|
||||||
|
,"commodities" ~:
|
||||||
|
Map.elems (commodities ledger7) `is` [Commodity {symbol="$", side=L, spaced=False, comma=False, precision=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
|
||||||
|
rl <- readJournal Nothing defaultyear_journal_str >>= either error' return
|
||||||
|
tdate (head $ jtxns rl) `is` fromGregorian 2009 1 1
|
||||||
|
return ()
|
||||||
|
|
||||||
|
,"print report tests" ~: TestList
|
||||||
|
[
|
||||||
|
|
||||||
|
"print expenses" ~:
|
||||||
|
do
|
||||||
|
let args = ["expenses"]
|
||||||
|
l <- samplejournalwithopts [] args
|
||||||
|
t <- getCurrentLocalTime
|
||||||
|
showTransactions (optsToFilterSpec [] args t) l `is` unlines
|
||||||
|
["2008/06/03 * eat & shop"
|
||||||
|
," expenses:food $1"
|
||||||
|
," expenses:supplies $1"
|
||||||
|
," assets:cash $-2"
|
||||||
|
,""
|
||||||
|
]
|
||||||
|
|
||||||
|
, "print report with depth arg" ~:
|
||||||
|
do
|
||||||
|
l <- samplejournal
|
||||||
|
t <- getCurrentLocalTime
|
||||||
|
showTransactions (optsToFilterSpec [Depth "2"] [] t) l `is` unlines
|
||||||
|
["2008/01/01 income"
|
||||||
|
," income:salary $-1"
|
||||||
|
,""
|
||||||
|
,"2008/06/01 gift"
|
||||||
|
," income:gifts $-1"
|
||||||
|
,""
|
||||||
|
,"2008/06/03 * eat & shop"
|
||||||
|
," expenses:food $1"
|
||||||
|
," expenses:supplies $1"
|
||||||
|
," assets:cash $-2"
|
||||||
|
,""
|
||||||
|
,"2008/12/31 * pay off"
|
||||||
|
," liabilities:debts $1"
|
||||||
|
,""
|
||||||
|
]
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
,"register report tests" ~:
|
||||||
|
let registerdates = filter (not . null) . map (strip . take 10) . lines
|
||||||
|
in
|
||||||
|
TestList
|
||||||
|
[
|
||||||
|
|
||||||
|
"register report with no args" ~:
|
||||||
|
do
|
||||||
|
l <- samplejournal
|
||||||
|
(registerReportAsText [] $ registerReport [] (optsToFilterSpec [] [] t1) l) `is` unlines
|
||||||
|
["2008/01/01 income assets:bank:checking $1 $1"
|
||||||
|
," income:salary $-1 0"
|
||||||
|
,"2008/06/01 gift assets:bank:checking $1 $1"
|
||||||
|
," income:gifts $-1 0"
|
||||||
|
,"2008/06/02 save assets:bank:saving $1 $1"
|
||||||
|
," assets:bank:checking $-1 0"
|
||||||
|
,"2008/06/03 eat & shop expenses:food $1 $1"
|
||||||
|
," expenses:supplies $1 $2"
|
||||||
|
," assets:cash $-2 0"
|
||||||
|
,"2008/12/31 pay off liabilities:debts $1 $1"
|
||||||
|
," assets:bank:checking $-1 0"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"register report with cleared option" ~:
|
||||||
|
do
|
||||||
|
let opts = [Cleared]
|
||||||
|
l <- readJournalWithOpts opts sample_journal_str
|
||||||
|
(registerReportAsText opts $ registerReport opts (optsToFilterSpec opts [] t1) l) `is` unlines
|
||||||
|
["2008/06/03 eat & shop expenses:food $1 $1"
|
||||||
|
," expenses:supplies $1 $2"
|
||||||
|
," assets:cash $-2 0"
|
||||||
|
,"2008/12/31 pay off liabilities:debts $1 $1"
|
||||||
|
," assets:bank:checking $-1 0"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"register report with uncleared option" ~:
|
||||||
|
do
|
||||||
|
let opts = [UnCleared]
|
||||||
|
l <- readJournalWithOpts opts sample_journal_str
|
||||||
|
(registerReportAsText opts $ registerReport opts (optsToFilterSpec opts [] t1) l) `is` unlines
|
||||||
|
["2008/01/01 income assets:bank:checking $1 $1"
|
||||||
|
," income:salary $-1 0"
|
||||||
|
,"2008/06/01 gift assets:bank:checking $1 $1"
|
||||||
|
," income:gifts $-1 0"
|
||||||
|
,"2008/06/02 save assets:bank:saving $1 $1"
|
||||||
|
," assets:bank:checking $-1 0"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"register report sorts by date" ~:
|
||||||
|
do
|
||||||
|
l <- readJournalWithOpts [] $ unlines
|
||||||
|
["2008/02/02 a"
|
||||||
|
," b 1"
|
||||||
|
," c"
|
||||||
|
,""
|
||||||
|
,"2008/01/01 d"
|
||||||
|
," e 1"
|
||||||
|
," f"
|
||||||
|
]
|
||||||
|
registerdates (registerReportAsText [] $ registerReport [] (optsToFilterSpec [] [] t1) l) `is` ["2008/01/01","2008/02/02"]
|
||||||
|
|
||||||
|
,"register report with account pattern" ~:
|
||||||
|
do
|
||||||
|
l <- samplejournal
|
||||||
|
(registerReportAsText [] $ registerReport [] (optsToFilterSpec [] ["cash"] t1) l) `is` unlines
|
||||||
|
["2008/06/03 eat & shop assets:cash $-2 $-2"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"register report with account pattern, case insensitive" ~:
|
||||||
|
do
|
||||||
|
l <- samplejournal
|
||||||
|
(registerReportAsText [] $ registerReport [] (optsToFilterSpec [] ["cAsH"] t1) l) `is` unlines
|
||||||
|
["2008/06/03 eat & shop assets:cash $-2 $-2"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"register report with display expression" ~:
|
||||||
|
do
|
||||||
|
l <- samplejournal
|
||||||
|
let gives displayexpr =
|
||||||
|
(registerdates (registerReportAsText opts $ registerReport opts (optsToFilterSpec opts [] t1) l) `is`)
|
||||||
|
where opts = [Display displayexpr]
|
||||||
|
"d<[2008/6/2]" `gives` ["2008/01/01","2008/06/01"]
|
||||||
|
"d<=[2008/6/2]" `gives` ["2008/01/01","2008/06/01","2008/06/02"]
|
||||||
|
"d=[2008/6/2]" `gives` ["2008/06/02"]
|
||||||
|
"d>=[2008/6/2]" `gives` ["2008/06/02","2008/06/03","2008/12/31"]
|
||||||
|
"d>[2008/6/2]" `gives` ["2008/06/03","2008/12/31"]
|
||||||
|
|
||||||
|
,"register report with period expression" ~:
|
||||||
|
do
|
||||||
|
l <- samplejournal
|
||||||
|
let periodexpr `gives` dates = do
|
||||||
|
l' <- samplejournalwithopts opts []
|
||||||
|
registerdates (registerReportAsText opts $ registerReport opts (optsToFilterSpec opts [] t1) l') `is` dates
|
||||||
|
where opts = [Period periodexpr]
|
||||||
|
"" `gives` ["2008/01/01","2008/06/01","2008/06/02","2008/06/03","2008/12/31"]
|
||||||
|
"2008" `gives` ["2008/01/01","2008/06/01","2008/06/02","2008/06/03","2008/12/31"]
|
||||||
|
"2007" `gives` []
|
||||||
|
"june" `gives` ["2008/06/01","2008/06/02","2008/06/03"]
|
||||||
|
"monthly" `gives` ["2008/01/01","2008/06/01","2008/12/01"]
|
||||||
|
"quarterly" `gives` ["2008/01/01","2008/04/01","2008/10/01"]
|
||||||
|
let opts = [Period "yearly"]
|
||||||
|
(registerReportAsText opts $ registerReport opts (optsToFilterSpec opts [] t1) l) `is` unlines
|
||||||
|
["2008/01/01 - 2008/12/31 assets:bank:saving $1 $1"
|
||||||
|
," assets:cash $-2 $-1"
|
||||||
|
," expenses:food $1 0"
|
||||||
|
," expenses:supplies $1 $1"
|
||||||
|
," income:gifts $-1 0"
|
||||||
|
," income:salary $-1 $-1"
|
||||||
|
," liabilities:debts $1 0"
|
||||||
|
]
|
||||||
|
let opts = [Period "quarterly"]
|
||||||
|
registerdates (registerReportAsText opts $ registerReport opts (optsToFilterSpec opts [] t1) l) `is` ["2008/01/01","2008/04/01","2008/10/01"]
|
||||||
|
let opts = [Period "quarterly",Empty]
|
||||||
|
registerdates (registerReportAsText opts $ registerReport opts (optsToFilterSpec opts [] t1) l) `is` ["2008/01/01","2008/04/01","2008/07/01","2008/10/01"]
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
, "register report with depth arg" ~:
|
||||||
|
do
|
||||||
|
l <- samplejournal
|
||||||
|
let opts = [Depth "2"]
|
||||||
|
(registerReportAsText opts $ registerReport opts (optsToFilterSpec opts [] t1) l) `is` unlines
|
||||||
|
["2008/01/01 income assets:bank $1 $1"
|
||||||
|
," income:salary $-1 0"
|
||||||
|
,"2008/06/01 gift assets:bank $1 $1"
|
||||||
|
," income:gifts $-1 0"
|
||||||
|
,"2008/06/02 save assets:bank $1 $1"
|
||||||
|
," assets:bank $-1 0"
|
||||||
|
,"2008/06/03 eat & shop expenses:food $1 $1"
|
||||||
|
," expenses:supplies $1 $2"
|
||||||
|
," assets:cash $-2 0"
|
||||||
|
,"2008/12/31 pay off liabilities:debts $1 $1"
|
||||||
|
," assets:bank $-1 0"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"show dollars" ~: show (dollars 1) ~?= "$1.00"
|
||||||
|
|
||||||
|
,"show hours" ~: show (hours 1) ~?= "1.0h"
|
||||||
|
|
||||||
|
,"unicode in balance layout" ~: do
|
||||||
|
l <- readJournalWithOpts []
|
||||||
|
"2009/01/01 * медвежья шкура\n расходы:покупки 100\n актив:наличные\n"
|
||||||
|
balanceReportAsText [] (balanceReport [] (optsToFilterSpec [] [] t1) l) `is` unlines
|
||||||
|
[" -100 актив:наличные"
|
||||||
|
," 100 расходы:покупки"
|
||||||
|
,"--------------------"
|
||||||
|
," 0"
|
||||||
|
]
|
||||||
|
|
||||||
|
,"unicode in register layout" ~: do
|
||||||
|
l <- readJournalWithOpts []
|
||||||
|
"2009/01/01 * медвежья шкура\n расходы:покупки 100\n актив:наличные\n"
|
||||||
|
(registerReportAsText [] $ registerReport [] (optsToFilterSpec [] [] t1) l) `is` unlines
|
||||||
|
["2009/01/01 медвежья шкура расходы:покупки 100 100"
|
||||||
|
," актив:наличные -100 0"]
|
||||||
|
|
||||||
|
,"subAccounts" ~: do
|
||||||
|
l <- liftM (journalToLedger nullfilterspec) samplejournal
|
||||||
|
let a = ledgerAccount l "assets"
|
||||||
|
map aname (ledgerSubAccounts l a) `is` ["assets:bank","assets:cash"]
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
-- fixtures/test data
|
||||||
|
|
||||||
|
t1 = LocalTime date1 midday where date1 = parsedate "2008/11/26"
|
||||||
|
|
||||||
|
samplejournal = readJournalWithOpts [] sample_journal_str
|
||||||
|
samplejournalwithopts opts _ = readJournalWithOpts opts 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 = 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
|
||||||
|
[]
|
||||||
|
[]
|
||||||
|
[
|
||||||
|
txnTieKnot $ Transaction {
|
||||||
|
tdate=parsedate "2007/01/01",
|
||||||
|
teffectivedate=Nothing,
|
||||||
|
tstatus=False,
|
||||||
|
tcode="*",
|
||||||
|
tdescription="opening balance",
|
||||||
|
tcomment="",
|
||||||
|
tmetadata=[],
|
||||||
|
tpostings=[
|
||||||
|
Posting {
|
||||||
|
pstatus=False,
|
||||||
|
paccount="assets:cash",
|
||||||
|
pamount=(Mixed [dollars 4.82]),
|
||||||
|
pcomment="",
|
||||||
|
ptype=RegularPosting,
|
||||||
|
pmetadata=[],
|
||||||
|
ptransaction=Nothing
|
||||||
|
},
|
||||||
|
Posting {
|
||||||
|
pstatus=False,
|
||||||
|
paccount="equity:opening balances",
|
||||||
|
pamount=(Mixed [dollars (-4.82)]),
|
||||||
|
pcomment="",
|
||||||
|
ptype=RegularPosting,
|
||||||
|
pmetadata=[],
|
||||||
|
ptransaction=Nothing
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tpreceding_comment_lines=""
|
||||||
|
}
|
||||||
|
,
|
||||||
|
txnTieKnot $ Transaction {
|
||||||
|
tdate=parsedate "2007/02/01",
|
||||||
|
teffectivedate=Nothing,
|
||||||
|
tstatus=False,
|
||||||
|
tcode="*",
|
||||||
|
tdescription="ayres suites",
|
||||||
|
tcomment="",
|
||||||
|
tmetadata=[],
|
||||||
|
tpostings=[
|
||||||
|
Posting {
|
||||||
|
pstatus=False,
|
||||||
|
paccount="expenses:vacation",
|
||||||
|
pamount=(Mixed [dollars 179.92]),
|
||||||
|
pcomment="",
|
||||||
|
ptype=RegularPosting,
|
||||||
|
pmetadata=[],
|
||||||
|
ptransaction=Nothing
|
||||||
|
},
|
||||||
|
Posting {
|
||||||
|
pstatus=False,
|
||||||
|
paccount="assets:checking",
|
||||||
|
pamount=(Mixed [dollars (-179.92)]),
|
||||||
|
pcomment="",
|
||||||
|
ptype=RegularPosting,
|
||||||
|
pmetadata=[],
|
||||||
|
ptransaction=Nothing
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tpreceding_comment_lines=""
|
||||||
|
}
|
||||||
|
,
|
||||||
|
txnTieKnot $ Transaction {
|
||||||
|
tdate=parsedate "2007/01/02",
|
||||||
|
teffectivedate=Nothing,
|
||||||
|
tstatus=False,
|
||||||
|
tcode="*",
|
||||||
|
tdescription="auto transfer to savings",
|
||||||
|
tcomment="",
|
||||||
|
tmetadata=[],
|
||||||
|
tpostings=[
|
||||||
|
Posting {
|
||||||
|
pstatus=False,
|
||||||
|
paccount="assets:saving",
|
||||||
|
pamount=(Mixed [dollars 200]),
|
||||||
|
pcomment="",
|
||||||
|
ptype=RegularPosting,
|
||||||
|
pmetadata=[],
|
||||||
|
ptransaction=Nothing
|
||||||
|
},
|
||||||
|
Posting {
|
||||||
|
pstatus=False,
|
||||||
|
paccount="assets:checking",
|
||||||
|
pamount=(Mixed [dollars (-200)]),
|
||||||
|
pcomment="",
|
||||||
|
ptype=RegularPosting,
|
||||||
|
pmetadata=[],
|
||||||
|
ptransaction=Nothing
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tpreceding_comment_lines=""
|
||||||
|
}
|
||||||
|
,
|
||||||
|
txnTieKnot $ Transaction {
|
||||||
|
tdate=parsedate "2007/01/03",
|
||||||
|
teffectivedate=Nothing,
|
||||||
|
tstatus=False,
|
||||||
|
tcode="*",
|
||||||
|
tdescription="poquito mas",
|
||||||
|
tcomment="",
|
||||||
|
tmetadata=[],
|
||||||
|
tpostings=[
|
||||||
|
Posting {
|
||||||
|
pstatus=False,
|
||||||
|
paccount="expenses:food:dining",
|
||||||
|
pamount=(Mixed [dollars 4.82]),
|
||||||
|
pcomment="",
|
||||||
|
ptype=RegularPosting,
|
||||||
|
pmetadata=[],
|
||||||
|
ptransaction=Nothing
|
||||||
|
},
|
||||||
|
Posting {
|
||||||
|
pstatus=False,
|
||||||
|
paccount="assets:cash",
|
||||||
|
pamount=(Mixed [dollars (-4.82)]),
|
||||||
|
pcomment="",
|
||||||
|
ptype=RegularPosting,
|
||||||
|
pmetadata=[],
|
||||||
|
ptransaction=Nothing
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tpreceding_comment_lines=""
|
||||||
|
}
|
||||||
|
,
|
||||||
|
txnTieKnot $ Transaction {
|
||||||
|
tdate=parsedate "2007/01/03",
|
||||||
|
teffectivedate=Nothing,
|
||||||
|
tstatus=False,
|
||||||
|
tcode="*",
|
||||||
|
tdescription="verizon",
|
||||||
|
tcomment="",
|
||||||
|
tmetadata=[],
|
||||||
|
tpostings=[
|
||||||
|
Posting {
|
||||||
|
pstatus=False,
|
||||||
|
paccount="expenses:phone",
|
||||||
|
pamount=(Mixed [dollars 95.11]),
|
||||||
|
pcomment="",
|
||||||
|
ptype=RegularPosting,
|
||||||
|
pmetadata=[],
|
||||||
|
ptransaction=Nothing
|
||||||
|
},
|
||||||
|
Posting {
|
||||||
|
pstatus=False,
|
||||||
|
paccount="assets:checking",
|
||||||
|
pamount=(Mixed [dollars (-95.11)]),
|
||||||
|
pcomment="",
|
||||||
|
ptype=RegularPosting,
|
||||||
|
pmetadata=[],
|
||||||
|
ptransaction=Nothing
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tpreceding_comment_lines=""
|
||||||
|
}
|
||||||
|
,
|
||||||
|
txnTieKnot $ Transaction {
|
||||||
|
tdate=parsedate "2007/01/03",
|
||||||
|
teffectivedate=Nothing,
|
||||||
|
tstatus=False,
|
||||||
|
tcode="*",
|
||||||
|
tdescription="discover",
|
||||||
|
tcomment="",
|
||||||
|
tmetadata=[],
|
||||||
|
tpostings=[
|
||||||
|
Posting {
|
||||||
|
pstatus=False,
|
||||||
|
paccount="liabilities:credit cards:discover",
|
||||||
|
pamount=(Mixed [dollars 80]),
|
||||||
|
pcomment="",
|
||||||
|
ptype=RegularPosting,
|
||||||
|
pmetadata=[],
|
||||||
|
ptransaction=Nothing
|
||||||
|
},
|
||||||
|
Posting {
|
||||||
|
pstatus=False,
|
||||||
|
paccount="assets:checking",
|
||||||
|
pamount=(Mixed [dollars (-80)]),
|
||||||
|
pcomment="",
|
||||||
|
ptype=RegularPosting,
|
||||||
|
pmetadata=[],
|
||||||
|
ptransaction=Nothing
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tpreceding_comment_lines=""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
[]
|
||||||
|
""
|
||||||
|
nullctx
|
||||||
|
[]
|
||||||
|
(TOD 0 0)
|
||||||
|
|
||||||
|
ledger7 = journalToLedger nullfilterspec journal7
|
||||||
|
|
||||||
|
-- journal8_str = unlines
|
||||||
|
-- ["2008/1/1 test "
|
||||||
|
-- ," a:b 10h @ $40"
|
||||||
|
-- ," c:d "
|
||||||
|
-- ,""
|
||||||
|
-- ]
|
||||||
|
|
||||||
|
-- timelogentry1_str = "i 2007/03/11 16:19:00 hledger\n"
|
||||||
|
-- timelogentry1 = TimeLogEntry In (parsedatetime "2007/03/11 16:19:00") "hledger"
|
||||||
|
|
||||||
|
-- timelogentry2_str = "o 2007/03/11 16:30:00\n"
|
||||||
|
-- timelogentry2 = TimeLogEntry Out (parsedatetime "2007/03/11 16:30:00") ""
|
||||||
|
|
||||||
|
-- a1 = Mixed [(hours 1){price=Just $ Mixed [Amount (comm "$") 10 Nothing]}]
|
||||||
|
-- a2 = Mixed [(hours 2){price=Just $ Mixed [Amount (comm "EUR") 10 Nothing]}]
|
||||||
|
-- a3 = Mixed $ amounts a1 ++ amounts a2
|
||||||
|
|
||||||
|
journalWithAmounts :: [String] -> Journal
|
||||||
|
journalWithAmounts as =
|
||||||
|
Journal
|
||||||
|
[]
|
||||||
|
[]
|
||||||
|
[t | a <- as, let t = nulltransaction{tdescription=a,tpostings=[nullposting{pamount=parse a,ptransaction=Just t}]}]
|
||||||
|
[]
|
||||||
|
[]
|
||||||
|
""
|
||||||
|
nullctx
|
||||||
|
[]
|
||||||
|
(TOD 0 0)
|
||||||
|
where parse = fromparse . parseWithCtx nullctx someamount
|
||||||
|
|
||||||
@ -101,6 +101,7 @@ module Hledger.Cli.Balance (
|
|||||||
,balance
|
,balance
|
||||||
,balanceReport
|
,balanceReport
|
||||||
,balanceReportAsText
|
,balanceReportAsText
|
||||||
|
,tests_Hledger_Cli_Balance
|
||||||
-- ,tests_Balance
|
-- ,tests_Balance
|
||||||
) where
|
) where
|
||||||
import Hledger.Data.Utils
|
import Hledger.Data.Utils
|
||||||
@ -211,3 +212,6 @@ isInterestingIndented opts l a
|
|||||||
isInterestingTree = treeany (isInteresting opts l . aname)
|
isInterestingTree = treeany (isInteresting opts l . aname)
|
||||||
subtrees = map (fromJust . ledgerAccountTreeAt l) $ ledgerSubAccounts l $ ledgerAccount l a
|
subtrees = map (fromJust . ledgerAccountTreeAt l) $ ledgerSubAccounts l $ ledgerAccount l a
|
||||||
|
|
||||||
|
tests_Hledger_Cli_Balance = TestList
|
||||||
|
[
|
||||||
|
]
|
||||||
|
|||||||
@ -1,40 +0,0 @@
|
|||||||
{-# LANGUAGE CPP #-}
|
|
||||||
{-|
|
|
||||||
|
|
||||||
The Commands package defines all the commands offered by the hledger
|
|
||||||
application, like \"register\" and \"balance\". This module exports all
|
|
||||||
the commands; you can also import individual modules if you prefer.
|
|
||||||
|
|
||||||
-}
|
|
||||||
|
|
||||||
module Hledger.Cli.Commands (
|
|
||||||
module Hledger.Cli.Add,
|
|
||||||
module Hledger.Cli.Balance,
|
|
||||||
module Hledger.Cli.Convert,
|
|
||||||
module Hledger.Cli.Histogram,
|
|
||||||
module Hledger.Cli.Print,
|
|
||||||
module Hledger.Cli.Register,
|
|
||||||
module Hledger.Cli.Stats,
|
|
||||||
tests_Hledger_Commands
|
|
||||||
)
|
|
||||||
where
|
|
||||||
import Hledger.Cli.Add
|
|
||||||
import Hledger.Cli.Balance
|
|
||||||
import Hledger.Cli.Convert
|
|
||||||
import Hledger.Cli.Histogram
|
|
||||||
import Hledger.Cli.Print
|
|
||||||
import Hledger.Cli.Register
|
|
||||||
import Hledger.Cli.Stats
|
|
||||||
import Test.HUnit (Test(TestList))
|
|
||||||
|
|
||||||
|
|
||||||
tests_Hledger_Commands = TestList
|
|
||||||
[
|
|
||||||
-- Hledger.Cli.Add.tests_Add
|
|
||||||
-- ,Hledger.Cli.Balance.tests_Balance
|
|
||||||
Hledger.Cli.Convert.tests_Convert
|
|
||||||
-- ,Hledger.Cli.Histogram.tests_Histogram
|
|
||||||
-- ,Hledger.Cli.Print.tests_Print
|
|
||||||
,Hledger.Cli.Register.tests_Register
|
|
||||||
-- ,Hledger.Cli.Stats.tests_Stats
|
|
||||||
]
|
|
||||||
@ -350,7 +350,7 @@ identify rules defacct desc | null matchingrules = (defacct,desc)
|
|||||||
|
|
||||||
caseinsensitive = ("(?i)"++)
|
caseinsensitive = ("(?i)"++)
|
||||||
|
|
||||||
tests_Convert = TestList [
|
tests_Hledger_Cli_Convert = TestList [
|
||||||
|
|
||||||
"convert rules parsing: empty file" ~: do
|
"convert rules parsing: empty file" ~: do
|
||||||
-- let assertMixedAmountParse parseresult mixedamount =
|
-- let assertMixedAmountParse parseresult mixedamount =
|
||||||
|
|||||||
@ -295,3 +295,28 @@ optsToFilterSpec opts args t = FilterSpec {
|
|||||||
-- where
|
-- where
|
||||||
-- listtomaybe [] = Nothing
|
-- listtomaybe [] = Nothing
|
||||||
-- listtomaybe vs = Just $ last vs
|
-- listtomaybe vs = Just $ last vs
|
||||||
|
|
||||||
|
tests_Hledger_Cli_Options = TestList
|
||||||
|
[
|
||||||
|
"dateSpanFromOpts" ~: do
|
||||||
|
let todaysdate = parsedate "2008/11/26"
|
||||||
|
let gives = is . show . dateSpanFromOpts todaysdate
|
||||||
|
[] `gives` "DateSpan Nothing Nothing"
|
||||||
|
[Begin "2008", End "2009"] `gives` "DateSpan (Just 2008-01-01) (Just 2009-01-01)"
|
||||||
|
[Period "in 2008"] `gives` "DateSpan (Just 2008-01-01) (Just 2009-01-01)"
|
||||||
|
[Begin "2005", End "2007",Period "in 2008"] `gives` "DateSpan (Just 2008-01-01) (Just 2009-01-01)"
|
||||||
|
|
||||||
|
,"intervalFromOpts" ~: do
|
||||||
|
let gives = is . intervalFromOpts
|
||||||
|
[] `gives` NoInterval
|
||||||
|
[DailyOpt] `gives` Daily
|
||||||
|
[WeeklyOpt] `gives` Weekly
|
||||||
|
[MonthlyOpt] `gives` Monthly
|
||||||
|
[QuarterlyOpt] `gives` Quarterly
|
||||||
|
[YearlyOpt] `gives` Yearly
|
||||||
|
[Period "weekly"] `gives` Weekly
|
||||||
|
[Period "monthly"] `gives` Monthly
|
||||||
|
[Period "quarterly"] `gives` Quarterly
|
||||||
|
[WeeklyOpt, Period "yearly"] `gives` Yearly
|
||||||
|
|
||||||
|
]
|
||||||
@ -12,7 +12,7 @@ module Hledger.Cli.Register (
|
|||||||
,registerReport
|
,registerReport
|
||||||
,registerReportAsText
|
,registerReportAsText
|
||||||
,showPostingWithBalanceForVty
|
,showPostingWithBalanceForVty
|
||||||
,tests_Register
|
,tests_Hledger_Cli_Register
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Safe (headMay, lastMay)
|
import Safe (headMay, lastMay)
|
||||||
@ -198,10 +198,46 @@ depthClipPosting Nothing p = p
|
|||||||
depthClipPosting (Just d) p@Posting{paccount=a} = p{paccount=clipAccountName d a}
|
depthClipPosting (Just d) p@Posting{paccount=a} = p{paccount=clipAccountName d a}
|
||||||
|
|
||||||
|
|
||||||
tests_Register :: Test
|
tests_Hledger_Cli_Register :: Test
|
||||||
tests_Register = TestList [
|
tests_Hledger_Cli_Register = TestList
|
||||||
|
[
|
||||||
|
|
||||||
"summarisePostingsByInterval" ~: do
|
"summarisePostingsByInterval" ~: do
|
||||||
summarisePostingsByInterval Quarterly Nothing False (DateSpan Nothing Nothing) [] ~?= []
|
summarisePostingsByInterval Quarterly Nothing False (DateSpan Nothing Nothing) [] ~?= []
|
||||||
|
|
||||||
]
|
-- ,"summarisePostingsInDateSpan" ~: do
|
||||||
|
-- let gives (b,e,depth,showempty,ps) =
|
||||||
|
-- (summarisePostingsInDateSpan (mkdatespan b e) depth showempty ps `is`)
|
||||||
|
-- let ps =
|
||||||
|
-- [
|
||||||
|
-- nullposting{lpdescription="desc",lpaccount="expenses:food:groceries",lpamount=Mixed [dollars 1]}
|
||||||
|
-- ,nullposting{lpdescription="desc",lpaccount="expenses:food:dining", lpamount=Mixed [dollars 2]}
|
||||||
|
-- ,nullposting{lpdescription="desc",lpaccount="expenses:food", lpamount=Mixed [dollars 4]}
|
||||||
|
-- ,nullposting{lpdescription="desc",lpaccount="expenses:food:dining", lpamount=Mixed [dollars 8]}
|
||||||
|
-- ]
|
||||||
|
-- ("2008/01/01","2009/01/01",0,9999,False,[]) `gives`
|
||||||
|
-- []
|
||||||
|
-- ("2008/01/01","2009/01/01",0,9999,True,[]) `gives`
|
||||||
|
-- [
|
||||||
|
-- nullposting{lpdate=parsedate "2008/01/01",lpdescription="- 2008/12/31"}
|
||||||
|
-- ]
|
||||||
|
-- ("2008/01/01","2009/01/01",0,9999,False,ts) `gives`
|
||||||
|
-- [
|
||||||
|
-- nullposting{lpdate=parsedate "2008/01/01",lpdescription="- 2008/12/31",lpaccount="expenses:food", lpamount=Mixed [dollars 4]}
|
||||||
|
-- ,nullposting{lpdate=parsedate "2008/01/01",lpdescription="- 2008/12/31",lpaccount="expenses:food:dining", lpamount=Mixed [dollars 10]}
|
||||||
|
-- ,nullposting{lpdate=parsedate "2008/01/01",lpdescription="- 2008/12/31",lpaccount="expenses:food:groceries",lpamount=Mixed [dollars 1]}
|
||||||
|
-- ]
|
||||||
|
-- ("2008/01/01","2009/01/01",0,2,False,ts) `gives`
|
||||||
|
-- [
|
||||||
|
-- nullposting{lpdate=parsedate "2008/01/01",lpdescription="- 2008/12/31",lpaccount="expenses:food",lpamount=Mixed [dollars 15]}
|
||||||
|
-- ]
|
||||||
|
-- ("2008/01/01","2009/01/01",0,1,False,ts) `gives`
|
||||||
|
-- [
|
||||||
|
-- nullposting{lpdate=parsedate "2008/01/01",lpdescription="- 2008/12/31",lpaccount="expenses",lpamount=Mixed [dollars 15]}
|
||||||
|
-- ]
|
||||||
|
-- ("2008/01/01","2009/01/01",0,0,False,ts) `gives`
|
||||||
|
-- [
|
||||||
|
-- nullposting{lpdate=parsedate "2008/01/01",lpdescription="- 2008/12/31",lpaccount="",lpamount=Mixed [dollars 15]}
|
||||||
|
-- ]
|
||||||
|
|
||||||
|
]
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,7 @@ module Hledger.Cli.Utils
|
|||||||
writeFileWithBackup,
|
writeFileWithBackup,
|
||||||
writeFileWithBackupIfChanged,
|
writeFileWithBackupIfChanged,
|
||||||
readFileStrictly,
|
readFileStrictly,
|
||||||
|
Test(TestList),
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
import Hledger.Data
|
import Hledger.Data
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user