1 {-# LANGUAGE OverloadedStrings #-}
2 {-# LANGUAGE TupleSections #-}
5 import Test.HUnit hiding ((~?))
6 import Test.Framework.Providers.HUnit (hUnitTestToTests)
7 import Test.Framework.Runners.Console (defaultMain)
9 import Control.Applicative ((<*))
10 import Control.Arrow ((***))
11 import Control.Monad.IO.Class (liftIO)
12 import Data.Decimal (DecimalRaw(..))
13 import qualified Data.Either
14 import qualified Data.List
15 import Data.List.NonEmpty (NonEmpty(..))
16 import qualified Data.Map.Strict as Data.Map
17 import Data.Text (Text)
18 import qualified Data.Time.Calendar as Time
19 import qualified Data.Time.LocalTime as Time
20 import qualified Text.Parsec as P hiding (char, string)
21 import qualified Text.Parsec.Pos as P
22 -- import qualified Text.PrettyPrint.Leijen.Text as PP
24 import qualified Hcompta.Model.Account as Account
25 import Hcompta.Model.Account (Account)
26 import qualified Hcompta.Model.Amount as Amount
27 import Hcompta.Model.Amount (Amount)
28 import qualified Hcompta.Model.Amount.Style as Amount.Style
29 import qualified Hcompta.Model.Date as Date
30 import qualified Hcompta.Model.Filter as Filter
31 import qualified Hcompta.Model.Filter.Read as Filter.Read
32 import qualified Hcompta.Calc.Balance as Calc.Balance
33 import qualified Hcompta.Format.Ledger as Format.Ledger
34 import qualified Hcompta.Format.Ledger.Read as Format.Ledger.Read
35 import qualified Hcompta.Format.Ledger.Write as Format.Ledger.Write
36 import qualified Hcompta.Lib.TreeMap as Lib.TreeMap
37 import qualified Hcompta.Lib.Parsec as P
38 import qualified Hcompta.Lib.Foldable as Lib.Foldable
41 main = defaultMain $ hUnitTestToTests test_Hcompta
43 (~?) :: String -> Bool -> Test
44 (~?) s b = s ~: (b ~?= True)
50 [ "TreeMap" ~: TestList
51 [ "insert" ~: TestList
53 (Lib.TreeMap.insert const ((0::Int):|[]) () Lib.TreeMap.empty)
55 (Lib.TreeMap.TreeMap $
57 [ ((0::Int), Lib.TreeMap.leaf ())
60 (Lib.TreeMap.insert const ((0::Int):|1:[]) () Lib.TreeMap.empty)
62 (Lib.TreeMap.TreeMap $
64 [ ((0::Int), Lib.TreeMap.Node
65 { Lib.TreeMap.node_value = Nothing
66 , Lib.TreeMap.node_size = 1
67 , Lib.TreeMap.node_descendants =
68 Lib.TreeMap.singleton ((1::Int):|[]) ()
75 , "map_by_depth_first" ~: TestList
78 , "flatten" ~: TestList
79 [ "[0, 0/1, 0/1/2]" ~:
80 (Lib.TreeMap.flatten id $
81 Lib.TreeMap.from_List const
82 [ (((0::Integer):|[]), ())
93 , "[1, 1/2, 1/22, 1/2/3, 1/2/33, 11, 11/2, 11/2/3, 11/2/33]" ~:
94 (Lib.TreeMap.flatten id $
95 Lib.TreeMap.from_List const
104 , ((11:|2:33:[]), ())
109 [ (((1::Integer):|[]), ())
117 , ((11:|2:33:[]), ())
121 , "Foldable" ~: TestList
122 [ "accumLeftsAndFoldrRights" ~: TestList
124 (Lib.Foldable.accumLeftsAndFoldrRights (++) [""] $
127 (([(0::Integer)], [(""::String)]))
129 ((take 1 *** take 0) $
130 Lib.Foldable.accumLeftsAndFoldrRights (++) [""] $
131 ( repeat (Left [0]) ))
133 ([(0::Integer)], ([]::[String]))
134 , "Right:Left:Right:Left" ~:
135 (Lib.Foldable.accumLeftsAndFoldrRights (++) ["0"] $
136 ( Right ["2"]:Left [1]:Right ["1"]:Left [0]:[] ))
138 (([1, 0]::[Integer]), (["2", "1", "0"]::[String]))
139 , "Right:Left:Right:repeat Left" ~:
140 ((take 1 *** take 2) $
141 Lib.Foldable.accumLeftsAndFoldrRights (++) ["0"] $
142 ( Right ["2"]:Left [1]:Right ["1"]:repeat (Left [0]) ))
144 (([1]::[Integer]), (["2", "1"]::[String]))
148 , "Model" ~: TestList
149 [ "Account" ~: TestList
150 [ "foldr" ~: TestList
152 (reverse $ Account.foldr ("A":|[]) (:) []) ~?= ["A":|[]]
154 (reverse $ Account.foldr ("A":|["B"]) (:) []) ~?= ["A":|[], "A":|["B"]]
156 (reverse $ Account.foldr ("A":|["B", "C"]) (:) []) ~?= ["A":|[], "A":|["B"], "A":|["B", "C"]]
158 , "ascending" ~: TestList
160 Account.ascending ("A":|[]) ~?= Nothing
162 Account.ascending ("A":|["B"]) ~?= Just ("A":|[])
164 Account.ascending ("A":|["B", "C"]) ~?= Just ("A":|["B"])
167 , "Amount" ~: TestList
172 { Amount.quantity = Decimal 0 1
173 , Amount.style = Amount.Style.nil
174 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
179 { Amount.quantity = Decimal 0 1
180 , Amount.style = Amount.Style.nil
181 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
187 { Amount.quantity = Decimal 0 2
188 , Amount.style = Amount.Style.nil
189 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
194 , "from_List" ~: TestList
195 [ "from_List [$1, 1$] = $2" ~:
198 { Amount.quantity = Decimal 0 1
199 , Amount.style = Amount.Style.nil
200 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
205 { Amount.quantity = Decimal 0 1
206 , Amount.style = Amount.Style.nil
207 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
215 { Amount.quantity = Decimal 0 2
216 , Amount.style = Amount.Style.nil
217 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
224 , "Filter" ~: TestList
225 [ "filter" ~: TestList
226 [ "Test_Account" ~: TestList
229 [ Filter.Test_Account_Section_Text
230 (Filter.Test_Text_Exact "A")
235 [ Filter.Test_Account_Section_Any
240 [ Filter.Test_Account_Section_Skip
245 [ Filter.Test_Account_Section_Skip
246 , Filter.Test_Account_Section_Text
247 (Filter.Test_Text_Exact "A")
252 [ Filter.Test_Account_Section_Text
253 (Filter.Test_Text_Exact "A")
254 , Filter.Test_Account_Section_Skip
259 [ Filter.Test_Account_Section_Text
260 (Filter.Test_Text_Exact "A")
261 , Filter.Test_Account_Section_Skip
263 (("A":|"B":[]::Account))
266 [ Filter.Test_Account_Section_Text
267 (Filter.Test_Text_Exact "A")
268 , Filter.Test_Account_Section_Text
269 (Filter.Test_Text_Exact "B")
271 (("A":|"B":[]::Account))
274 [ Filter.Test_Account_Section_Text
275 (Filter.Test_Text_Exact "A")
276 , Filter.Test_Account_Section_Skip
277 , Filter.Test_Account_Section_Text
278 (Filter.Test_Text_Exact "B")
280 (("A":|"B":[]::Account))
283 [ Filter.Test_Account_Section_Skip
284 , Filter.Test_Account_Section_Text
285 (Filter.Test_Text_Exact "B")
286 , Filter.Test_Account_Section_Skip
288 (("A":|"B":"C":[]::Account))
291 [ Filter.Test_Account_Section_Skip
292 , Filter.Test_Account_Section_Text
293 (Filter.Test_Text_Exact "C")
295 (("A":|"B":"C":[]::Account))
299 [ "filter_account_section" ~: TestList
301 (Data.Either.rights $
303 (Filter.Read.test_account <* P.eof)
306 [ [Filter.Test_Account_Section_Any]
309 (Data.Either.rights $
311 (Filter.Read.test_account <* P.eof)
314 [ [Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")]
317 (Data.Either.rights $
319 (Filter.Read.test_account <* P.eof)
322 [ [Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "AA")]
325 (Data.Either.rights $
327 (Filter.Read.test_account <* P.eof)
328 () "" ("::A"::Text)])
330 [ [ Filter.Test_Account_Section_Skip
331 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
335 (Data.Either.rights $
337 (Filter.Read.test_account <* P.eof)
340 [ [ Filter.Test_Account_Section_Skip
341 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
345 (Data.Either.rights $
347 (Filter.Read.test_account <* P.eof)
350 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
351 , Filter.Test_Account_Section_Skip
355 (Data.Either.rights $
357 (Filter.Read.test_account <* P.eof)
358 () "" ("A::"::Text)])
360 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
361 , Filter.Test_Account_Section_Skip
365 (Data.Either.rights $
367 (Filter.Read.test_account <* P.eof)
368 () "" ("A:B"::Text)])
370 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
371 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B") ]
374 (Data.Either.rights $
376 (Filter.Read.test_account <* P.eof)
377 () "" ("A::B"::Text)])
379 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
380 , Filter.Test_Account_Section_Skip
381 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B")
385 (Data.Either.rights $
387 (Filter.Read.test_account <* P.eof)
388 () "" ("A:::B"::Text)])
390 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
391 , Filter.Test_Account_Section_Skip
392 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B")
400 [ "Balance" ~: TestList
401 [ "balance" ~: TestList
402 [ "[A+$1] = A+$1 & $+1" ~:
403 (Calc.Balance.balance
404 (Format.Ledger.posting ("A":|[]))
405 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
410 { Calc.Balance.balance_by_account =
411 Lib.TreeMap.from_List const $
412 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
413 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
414 , Calc.Balance.balance_by_unit =
416 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
417 [ Calc.Balance.Unit_Sum
418 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
419 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
424 , "[A+$1, A-$1] = {A+$0, $+0}" ~:
426 (flip Calc.Balance.balance)
428 [ (Format.Ledger.posting ("A":|[]))
429 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
431 , (Format.Ledger.posting ("A":|[]))
432 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ]
437 { Calc.Balance.balance_by_account =
438 Lib.TreeMap.from_List const $
440 , Data.Map.fromListWith const $
441 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance s, s))
442 [ Calc.Balance.Amount_Sum
443 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
444 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
445 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
449 , Calc.Balance.balance_by_unit =
451 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
452 [ Calc.Balance.Unit_Sum
453 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
454 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
455 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
456 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
458 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
463 , "[A+$1, A-€1] = {A+$1-€1, $+1 €-1}" ~:
465 (flip Calc.Balance.balance)
467 [ (Format.Ledger.posting ("A":|[]))
468 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
470 , (Format.Ledger.posting ("A":|[]))
471 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1 ]
476 { Calc.Balance.balance_by_account =
477 Lib.TreeMap.from_List const $
478 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
479 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ -1 ]) ]
480 , Calc.Balance.balance_by_unit =
482 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
483 [ Calc.Balance.Unit_Sum
484 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
485 { Calc.Balance.amount_sum_negative = Nothing
486 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
487 , Calc.Balance.amount_sum_balance = Amount.usd $ 1
489 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
492 , Calc.Balance.Unit_Sum
493 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
494 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -1
495 , Calc.Balance.amount_sum_positive = Nothing
496 , Calc.Balance.amount_sum_balance = Amount.eur $ -1
498 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
503 , "[A+$1, B-$1] = {A+$1 B-$1, $+0}" ~:
505 (flip Calc.Balance.balance)
507 [ (Format.Ledger.posting ("A":|[]))
508 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
510 , (Format.Ledger.posting ("B":|[]))
511 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ]
516 { Calc.Balance.balance_by_account =
517 Lib.TreeMap.from_List const $
518 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
519 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
520 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
522 , Calc.Balance.balance_by_unit =
524 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
525 [ Calc.Balance.Unit_Sum
526 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
527 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
528 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
529 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
531 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
538 (flip Calc.Balance.balance)
540 [ (Format.Ledger.posting ("A":|[]))
541 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
543 , (Format.Ledger.posting ("B":|[]))
544 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
549 { Calc.Balance.balance_by_account =
550 Lib.TreeMap.from_List const $
551 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
552 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
553 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ])
555 , Calc.Balance.balance_by_unit =
557 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
558 [ Calc.Balance.Unit_Sum
559 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
560 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
565 , "[A+$1+€2, A-$1-€2] = {A+$0+€0, $+0 €+0}" ~:
567 (flip Calc.Balance.balance)
569 [ (Format.Ledger.posting ("A":|[]))
570 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2 ]
572 , (Format.Ledger.posting ("A":|[]))
573 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2 ]
578 { Calc.Balance.balance_by_account =
579 Lib.TreeMap.from_List const $
581 , Data.Map.fromListWith const $
582 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance s, s))
583 [ Calc.Balance.Amount_Sum
584 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
585 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
586 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
588 , Calc.Balance.Amount_Sum
589 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -2
590 , Calc.Balance.amount_sum_positive = Just $ Amount.eur $ 2
591 , Calc.Balance.amount_sum_balance = Amount.eur $ 0
596 , Calc.Balance.balance_by_unit =
598 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
599 [ Calc.Balance.Unit_Sum
600 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
601 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
602 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
603 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
605 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
608 , Calc.Balance.Unit_Sum
609 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
610 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -2
611 , Calc.Balance.amount_sum_positive = Just $ Amount.eur $ 2
612 , Calc.Balance.amount_sum_balance = Amount.eur $ 0
614 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
619 , "[A+$1+€2+£3, B-$1-2€-£3] = {A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~:
621 (flip Calc.Balance.balance)
623 [ (Format.Ledger.posting ("A":|[]))
624 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ]
626 , (Format.Ledger.posting ("B":|[]))
627 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ]
632 { Calc.Balance.balance_by_account =
633 Lib.TreeMap.from_List const $
634 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
635 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
636 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
638 , Calc.Balance.balance_by_unit =
640 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
641 [ Calc.Balance.Unit_Sum
642 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
643 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
644 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
645 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
647 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
650 , Calc.Balance.Unit_Sum
651 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
652 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -2
653 , Calc.Balance.amount_sum_positive = Just $ Amount.eur $ 2
654 , Calc.Balance.amount_sum_balance = Amount.eur $ 0
656 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
659 , Calc.Balance.Unit_Sum
660 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
661 { Calc.Balance.amount_sum_negative = Just $ Amount.gbp $ -3
662 , Calc.Balance.amount_sum_positive = Just $ Amount.gbp $ 3
663 , Calc.Balance.amount_sum_balance = Amount.gbp $ 0
665 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
671 , "union" ~: TestList
673 Calc.Balance.union Calc.Balance.nil Calc.Balance.nil
675 (Calc.Balance.nil::Calc.Balance.Balance Amount)
676 , "{A+$1, $+1} {A+$1, $+1} = {A+$2, $+2}" ~:
678 (Calc.Balance.Balance
679 { Calc.Balance.balance_by_account =
680 Lib.TreeMap.from_List const $
681 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
682 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
683 , Calc.Balance.balance_by_unit =
685 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
686 [ Calc.Balance.Unit_Sum
687 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
688 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
693 (Calc.Balance.Balance
694 { Calc.Balance.balance_by_account =
695 Lib.TreeMap.from_List const $
696 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
697 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
698 , Calc.Balance.balance_by_unit =
700 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
701 [ Calc.Balance.Unit_Sum
702 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
703 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
710 { Calc.Balance.balance_by_account =
711 Lib.TreeMap.from_List const $
712 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
713 [ ("A":|[], Amount.from_List [ Amount.usd $ 2 ]) ]
714 , Calc.Balance.balance_by_unit =
716 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
717 [ Calc.Balance.Unit_Sum
718 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
719 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
724 , "{A+$1, $+1} {B+$1, $+1} = {A+$1 B+$1, $+2}" ~:
726 (Calc.Balance.Balance
727 { Calc.Balance.balance_by_account =
728 Lib.TreeMap.from_List const $
729 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
730 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
731 , Calc.Balance.balance_by_unit =
733 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
734 [ Calc.Balance.Unit_Sum
735 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
736 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
741 (Calc.Balance.Balance
742 { Calc.Balance.balance_by_account =
743 Lib.TreeMap.from_List const $
744 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
745 [ ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
746 , Calc.Balance.balance_by_unit =
748 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
749 [ Calc.Balance.Unit_Sum
750 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
751 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
758 { Calc.Balance.balance_by_account =
759 Lib.TreeMap.from_List const $
760 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
761 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
762 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
763 , Calc.Balance.balance_by_unit =
765 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
766 [ Calc.Balance.Unit_Sum
767 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
768 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
773 , "{A+$1, $+1} {B+€1, €+1} = {A+$1 B+€1, $+1 €+1}" ~:
775 (Calc.Balance.Balance
776 { Calc.Balance.balance_by_account =
777 Lib.TreeMap.from_List const $
778 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
779 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
780 , Calc.Balance.balance_by_unit =
782 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
783 [ Calc.Balance.Unit_Sum
784 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
785 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
790 (Calc.Balance.Balance
791 { Calc.Balance.balance_by_account =
792 Lib.TreeMap.from_List const $
793 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
794 [ ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
795 , Calc.Balance.balance_by_unit =
797 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
798 [ Calc.Balance.Unit_Sum
799 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
800 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
807 { Calc.Balance.balance_by_account =
808 Lib.TreeMap.from_List const $
809 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
810 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
811 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
812 , Calc.Balance.balance_by_unit =
814 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
815 [ Calc.Balance.Unit_Sum
816 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
817 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
820 , Calc.Balance.Unit_Sum
821 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
822 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
828 , "expanded" ~: TestList
829 [ "nil_By_Account" ~:
830 Calc.Balance.expanded
833 (Lib.TreeMap.empty::Calc.Balance.Expanded Amount)
835 Calc.Balance.expanded
836 (Lib.TreeMap.from_List const $
837 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
838 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ])
840 (Lib.TreeMap.from_List const $
841 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
842 { Calc.Balance.inclusive =
843 Data.Map.map Calc.Balance.amount_sum $
844 Amount.from_List [ Amount.usd $ 1 ]
845 , Calc.Balance.exclusive =
846 Data.Map.map Calc.Balance.amount_sum $
847 Amount.from_List [ Amount.usd $ 1 ]
850 , "A/A+$1 = A+$1 A/A+$1" ~:
851 Calc.Balance.expanded
852 (Lib.TreeMap.from_List const $
853 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
854 [ ("A":|["A"], Amount.from_List [ Amount.usd $ 1 ]) ])
856 (Lib.TreeMap.from_List const
857 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
858 { Calc.Balance.inclusive =
859 Data.Map.map Calc.Balance.amount_sum $
860 Amount.from_List [ Amount.usd $ 1 ]
861 , Calc.Balance.exclusive =
862 Data.Map.map Calc.Balance.amount_sum $
865 , ("A":|["A"], Calc.Balance.Account_Sum_Expanded
866 { Calc.Balance.inclusive =
867 Data.Map.map Calc.Balance.amount_sum $
868 Amount.from_List [ Amount.usd $ 1 ]
869 , Calc.Balance.exclusive =
870 Data.Map.map Calc.Balance.amount_sum $
871 Amount.from_List [ Amount.usd $ 1 ]
874 , "A/B+$1 = A+$1 A/B+$1" ~:
875 Calc.Balance.expanded
876 (Lib.TreeMap.from_List const $
877 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
878 [ ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ]) ])
880 (Lib.TreeMap.from_List const
881 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
882 { Calc.Balance.inclusive =
883 Data.Map.map Calc.Balance.amount_sum $
884 Amount.from_List [ Amount.usd $ 1 ]
885 , Calc.Balance.exclusive =
886 Data.Map.map Calc.Balance.amount_sum $
889 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
890 { Calc.Balance.inclusive =
891 Data.Map.map Calc.Balance.amount_sum $
892 Amount.from_List [ Amount.usd $ 1 ]
893 , Calc.Balance.exclusive =
894 Data.Map.map Calc.Balance.amount_sum $
895 Amount.from_List [ Amount.usd $ 1 ]
898 , "A/B/C+$1 = A+$1 A/B+$1 A/B/C+$1" ~:
899 Calc.Balance.expanded
900 (Lib.TreeMap.from_List const $
901 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
902 [ ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ]) ])
904 (Lib.TreeMap.from_List const $
905 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
906 { Calc.Balance.inclusive =
907 Data.Map.map Calc.Balance.amount_sum $
908 Amount.from_List [ Amount.usd $ 1 ]
909 , Calc.Balance.exclusive =
910 Data.Map.map Calc.Balance.amount_sum $
913 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
914 { Calc.Balance.inclusive =
915 Data.Map.map Calc.Balance.amount_sum $
916 Amount.from_List [ Amount.usd $ 1 ]
917 , Calc.Balance.exclusive =
918 Data.Map.map Calc.Balance.amount_sum $
921 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
922 { Calc.Balance.inclusive =
923 Data.Map.map Calc.Balance.amount_sum $
924 Amount.from_List [ Amount.usd $ 1 ]
925 , Calc.Balance.exclusive =
926 Data.Map.map Calc.Balance.amount_sum $
927 Amount.from_List [ Amount.usd $ 1 ]
930 , "A+$1 A/B+$1 = A+$2 A/B+$1" ~:
931 Calc.Balance.expanded
932 (Lib.TreeMap.from_List const $
933 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
934 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
935 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
938 (Lib.TreeMap.from_List const
939 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
940 { Calc.Balance.inclusive =
941 Data.Map.map Calc.Balance.amount_sum $
942 Amount.from_List [ Amount.usd $ 2 ]
943 , Calc.Balance.exclusive =
944 Data.Map.map Calc.Balance.amount_sum $
945 Amount.from_List [ Amount.usd $ 1 ]
947 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
948 { Calc.Balance.inclusive =
949 Data.Map.map Calc.Balance.amount_sum $
950 Amount.from_List [ Amount.usd $ 1 ]
951 , Calc.Balance.exclusive =
952 Data.Map.map Calc.Balance.amount_sum $
953 Amount.from_List [ Amount.usd $ 1 ]
956 , "A+$1 A/B+$1 A/B/C+$1 = A+$3 A/B+$2 A/B/C+$1" ~:
957 Calc.Balance.expanded
958 (Lib.TreeMap.from_List const $
959 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
960 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
961 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
962 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
965 (Lib.TreeMap.from_List const
966 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
967 { Calc.Balance.inclusive =
968 Data.Map.map Calc.Balance.amount_sum $
969 Amount.from_List [ Amount.usd $ 3 ]
970 , Calc.Balance.exclusive =
971 Data.Map.map Calc.Balance.amount_sum $
972 Amount.from_List [ Amount.usd $ 1 ]
974 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
975 { Calc.Balance.inclusive =
976 Data.Map.map Calc.Balance.amount_sum $
977 Amount.from_List [ Amount.usd $ 2 ]
978 , Calc.Balance.exclusive =
979 Data.Map.map Calc.Balance.amount_sum $
980 Amount.from_List [ Amount.usd $ 1 ]
982 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
983 { Calc.Balance.inclusive =
984 Data.Map.map Calc.Balance.amount_sum $
985 Amount.from_List [ Amount.usd $ 1 ]
986 , Calc.Balance.exclusive =
987 Data.Map.map Calc.Balance.amount_sum $
988 Amount.from_List [ Amount.usd $ 1 ]
991 , "A+$1 A/B+$1 A/B/C+$1 A/B/C/D+$1 = A+$4 A/B+$3 A/B/C+$2 A/B/C/D+$1" ~:
992 Calc.Balance.expanded
993 (Lib.TreeMap.from_List const $
994 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
995 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
996 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
997 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
998 , ("A":|["B", "C", "D"], Amount.from_List [ Amount.usd $ 1 ])
1001 (Lib.TreeMap.from_List const
1002 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
1003 { Calc.Balance.inclusive =
1004 Data.Map.map Calc.Balance.amount_sum $
1005 Amount.from_List [ Amount.usd $ 4 ]
1006 , Calc.Balance.exclusive =
1007 Data.Map.map Calc.Balance.amount_sum $
1008 Amount.from_List [ Amount.usd $ 1 ]
1010 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
1011 { Calc.Balance.inclusive =
1012 Data.Map.map Calc.Balance.amount_sum $
1013 Amount.from_List [ Amount.usd $ 3 ]
1014 , Calc.Balance.exclusive =
1015 Data.Map.map Calc.Balance.amount_sum $
1016 Amount.from_List [ Amount.usd $ 1 ]
1018 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
1019 { Calc.Balance.inclusive =
1020 Data.Map.map Calc.Balance.amount_sum $
1021 Amount.from_List [ Amount.usd $ 2 ]
1022 , Calc.Balance.exclusive =
1023 Data.Map.map Calc.Balance.amount_sum $
1024 Amount.from_List [ Amount.usd $ 1 ]
1026 , ("A":|["B", "C", "D"], Calc.Balance.Account_Sum_Expanded
1027 { Calc.Balance.inclusive =
1028 Data.Map.map Calc.Balance.amount_sum $
1029 Amount.from_List [ Amount.usd $ 1 ]
1030 , Calc.Balance.exclusive =
1031 Data.Map.map Calc.Balance.amount_sum $
1032 Amount.from_List [ Amount.usd $ 1 ]
1035 , "A+$1 A/B+$1 A/BB+$1 AA/B+$1 = A+$3 A/B+$1 A/BB+$1 AA+$1 AA/B+$1" ~:
1036 Calc.Balance.expanded
1037 (Lib.TreeMap.from_List const $
1038 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1039 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1040 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
1041 , ("A":|["BB"], Amount.from_List [ Amount.usd $ 1 ])
1042 , ("AA":|["B"], Amount.from_List [ Amount.usd $ 1 ])
1045 (Lib.TreeMap.from_List const
1046 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
1047 { Calc.Balance.inclusive =
1048 Data.Map.map Calc.Balance.amount_sum $
1049 Amount.from_List [ Amount.usd $ 3 ]
1050 , Calc.Balance.exclusive =
1051 Data.Map.map Calc.Balance.amount_sum $
1052 Amount.from_List [ Amount.usd $ 1 ]
1054 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
1055 { Calc.Balance.inclusive =
1056 Data.Map.map Calc.Balance.amount_sum $
1057 Amount.from_List [ Amount.usd $ 1 ]
1058 , Calc.Balance.exclusive =
1059 Data.Map.map Calc.Balance.amount_sum $
1060 Amount.from_List [ Amount.usd $ 1 ]
1062 , ("A":|["BB"], Calc.Balance.Account_Sum_Expanded
1063 { Calc.Balance.inclusive =
1064 Data.Map.map Calc.Balance.amount_sum $
1065 Amount.from_List [ Amount.usd $ 1 ]
1066 , Calc.Balance.exclusive =
1067 Data.Map.map Calc.Balance.amount_sum $
1068 Amount.from_List [ Amount.usd $ 1 ]
1070 , ("AA":|[], Calc.Balance.Account_Sum_Expanded
1071 { Calc.Balance.inclusive =
1072 Data.Map.map Calc.Balance.amount_sum $
1073 Amount.from_List [ Amount.usd $ 1 ]
1074 , Calc.Balance.exclusive =
1075 Data.Map.map Calc.Balance.amount_sum $
1078 , ("AA":|["B"], Calc.Balance.Account_Sum_Expanded
1079 { Calc.Balance.inclusive =
1080 Data.Map.map Calc.Balance.amount_sum $
1081 Amount.from_List [ Amount.usd $ 1 ]
1082 , Calc.Balance.exclusive =
1083 Data.Map.map Calc.Balance.amount_sum $
1084 Amount.from_List [ Amount.usd $ 1 ]
1088 , "deviation" ~: TestList
1090 (Calc.Balance.deviation $
1091 Calc.Balance.Balance
1092 { Calc.Balance.balance_by_account =
1093 Lib.TreeMap.from_List const $
1094 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1095 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1096 , ("B":|[], Amount.from_List [])
1098 , Calc.Balance.balance_by_unit =
1100 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1101 [ Calc.Balance.Unit_Sum
1102 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1103 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1109 (Calc.Balance.Deviation $
1111 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1112 [ Calc.Balance.Unit_Sum
1113 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1114 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1118 , "{A+$1 B+$1, $2}" ~:
1119 (Calc.Balance.deviation $
1120 Calc.Balance.Balance
1121 { Calc.Balance.balance_by_account =
1122 Lib.TreeMap.from_List const $
1123 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1124 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1125 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ])
1127 , Calc.Balance.balance_by_unit =
1129 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1130 [ Calc.Balance.Unit_Sum
1131 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
1132 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1140 (Calc.Balance.Deviation $
1142 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1143 [ Calc.Balance.Unit_Sum
1144 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
1145 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1151 , "is_equilibrium_inferrable" ~: TestList
1152 [ "nil" ~: TestCase $
1154 Calc.Balance.is_equilibrium_inferrable $
1155 Calc.Balance.deviation $
1156 (Calc.Balance.nil::Calc.Balance.Balance Amount.Amount)
1157 , "{A+$0, $+0}" ~: TestCase $
1159 Calc.Balance.is_equilibrium_inferrable $
1160 Calc.Balance.deviation $
1161 Calc.Balance.Balance
1162 { Calc.Balance.balance_by_account =
1163 Lib.TreeMap.from_List const $
1164 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1165 [ ("A":|[], Amount.from_List [ Amount.usd $ 0 ])
1167 , Calc.Balance.balance_by_unit =
1169 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1170 [ Calc.Balance.Unit_Sum
1171 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1172 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1177 , "{A+$1, $+1}" ~: TestCase $
1179 Calc.Balance.is_equilibrium_inferrable $
1180 Calc.Balance.deviation $
1181 Calc.Balance.Balance
1182 { Calc.Balance.balance_by_account =
1183 Lib.TreeMap.from_List const $
1184 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1185 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1187 , Calc.Balance.balance_by_unit =
1189 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1190 [ Calc.Balance.Unit_Sum
1191 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1192 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1197 , "{A+$0+€0, $0 €+0}" ~: TestCase $
1199 Calc.Balance.is_equilibrium_inferrable $
1200 Calc.Balance.deviation $
1201 Calc.Balance.Balance
1202 { Calc.Balance.balance_by_account =
1203 Lib.TreeMap.from_List const $
1204 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1205 [ ("A":|[], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
1207 , Calc.Balance.balance_by_unit =
1209 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1210 [ Calc.Balance.Unit_Sum
1211 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1212 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1215 , Calc.Balance.Unit_Sum
1216 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 0
1217 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1222 , "{A+$1, B-$1, $+0}" ~: TestCase $
1224 Calc.Balance.is_equilibrium_inferrable $
1225 Calc.Balance.deviation $
1226 Calc.Balance.Balance
1227 { Calc.Balance.balance_by_account =
1228 Lib.TreeMap.from_List const $
1229 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1230 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1231 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
1233 , Calc.Balance.balance_by_unit =
1235 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1236 [ Calc.Balance.Unit_Sum
1237 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1238 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1243 , "{A+$1 B, $+1}" ~: TestCase $
1245 Calc.Balance.is_equilibrium_inferrable $
1246 Calc.Balance.deviation $
1247 Calc.Balance.Balance
1248 { Calc.Balance.balance_by_account =
1249 Lib.TreeMap.from_List const $
1250 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1251 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1252 , ("B":|[], Amount.from_List [])
1254 , Calc.Balance.balance_by_unit =
1256 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1257 [ Calc.Balance.Unit_Sum
1258 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1259 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1264 , "{A+$1 B+€1, $+1 €+1}" ~: TestCase $
1266 Calc.Balance.is_equilibrium_inferrable $
1267 Calc.Balance.deviation $
1268 Calc.Balance.Balance
1269 { Calc.Balance.balance_by_account =
1270 Lib.TreeMap.from_List const $
1271 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1272 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1273 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ])
1275 , Calc.Balance.balance_by_unit =
1277 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1278 [ Calc.Balance.Unit_Sum
1279 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1280 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1283 , Calc.Balance.Unit_Sum
1284 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
1285 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1290 , "{A+$1 B-$1+€1, $+0 €+1}" ~: TestCase $
1292 Calc.Balance.is_equilibrium_inferrable $
1293 Calc.Balance.deviation $
1294 Calc.Balance.Balance
1295 { Calc.Balance.balance_by_account =
1296 Lib.TreeMap.from_List const $
1297 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1298 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1299 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ 1 ])
1301 , Calc.Balance.balance_by_unit =
1303 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1304 [ Calc.Balance.Unit_Sum
1305 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1306 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1309 , Calc.Balance.Unit_Sum
1310 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
1311 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1316 , "{A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~: TestCase $
1318 Calc.Balance.is_equilibrium_inferrable $
1319 Calc.Balance.deviation $
1320 Calc.Balance.Balance
1321 { Calc.Balance.balance_by_account =
1322 Lib.TreeMap.from_List const $
1323 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1324 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
1325 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
1327 , Calc.Balance.balance_by_unit =
1329 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1330 [ Calc.Balance.Unit_Sum
1331 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1332 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1335 , Calc.Balance.Unit_Sum
1336 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 0
1337 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1340 , Calc.Balance.Unit_Sum
1341 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.gbp $ 0
1342 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1348 , "infer_equilibrium" ~: TestList
1350 (snd $ Calc.Balance.infer_equilibrium $
1351 Format.Ledger.posting_by_Account
1352 [ (Format.Ledger.posting ("A":|[]))
1353 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1354 , (Format.Ledger.posting ("B":|[]))
1355 { Format.Ledger.posting_amounts=Amount.from_List [] }
1359 Format.Ledger.posting_by_Account
1360 [ (Format.Ledger.posting ("A":|[]))
1361 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1362 , (Format.Ledger.posting ("B":|[]))
1363 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ] }
1366 (snd $ Calc.Balance.infer_equilibrium $
1367 Format.Ledger.posting_by_Account
1368 [ (Format.Ledger.posting ("A":|[]))
1369 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1370 , (Format.Ledger.posting ("B":|[]))
1371 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1 ] }
1375 Format.Ledger.posting_by_Account
1376 [ (Format.Ledger.posting ("A":|[]))
1377 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 1] }
1378 , (Format.Ledger.posting ("B":|[]))
1379 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1, Amount.usd $ -1 ] }
1382 (snd $ Calc.Balance.infer_equilibrium $
1383 Format.Ledger.posting_by_Account
1384 [ (Format.Ledger.posting ("A":|[]))
1385 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1386 , (Format.Ledger.posting ("B":|[]))
1387 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1391 [ Calc.Balance.Unit_Sum
1392 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
1393 , Calc.Balance.unit_sum_accounts = Data.Map.fromList []}
1395 , "{A+$1 B-$1 B-1€}" ~:
1396 (snd $ Calc.Balance.infer_equilibrium $
1397 Format.Ledger.posting_by_Account
1398 [ (Format.Ledger.posting ("A":|[]))
1399 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1400 , (Format.Ledger.posting ("B":|[]))
1401 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -1 ] }
1405 Format.Ledger.posting_by_Account
1406 [ (Format.Ledger.posting ("A":|[]))
1407 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 1 ] }
1408 , (Format.Ledger.posting ("B":|[]))
1409 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -1 ] }
1414 , "Format" ~: TestList
1415 [ "Ledger" ~: TestList
1416 [ "Read" ~: TestList
1417 [ "account_name" ~: TestList
1419 (Data.Either.rights $
1421 (Format.Ledger.Read.account_name <* P.eof)
1426 (Data.Either.rights $
1428 (Format.Ledger.Read.account_name <* P.eof)
1433 (Data.Either.rights $
1435 (Format.Ledger.Read.account_name <* P.eof)
1436 () "" ("AA"::Text)])
1440 (Data.Either.rights $
1442 (Format.Ledger.Read.account_name <* P.eof)
1447 (Data.Either.rights $
1449 (Format.Ledger.Read.account_name <* P.eof)
1454 (Data.Either.rights $
1456 (Format.Ledger.Read.account_name <* P.eof)
1457 () "" ("A:"::Text)])
1461 (Data.Either.rights $
1463 (Format.Ledger.Read.account_name <* P.eof)
1464 () "" (":A"::Text)])
1468 (Data.Either.rights $
1470 (Format.Ledger.Read.account_name <* P.eof)
1471 () "" ("A "::Text)])
1475 (Data.Either.rights $
1477 (Format.Ledger.Read.account_name)
1478 () "" ("A "::Text)])
1482 (Data.Either.rights $
1484 (Format.Ledger.Read.account_name <* P.eof)
1485 () "" ("A A"::Text)])
1489 (Data.Either.rights $
1491 (Format.Ledger.Read.account_name <* P.eof)
1492 () "" ("A "::Text)])
1496 (Data.Either.rights $
1498 (Format.Ledger.Read.account_name <* P.eof)
1499 () "" ("A \n"::Text)])
1503 (Data.Either.rights $
1505 (Format.Ledger.Read.account_name <* P.eof)
1506 () "" ("(A)A"::Text)])
1510 (Data.Either.rights $
1512 (Format.Ledger.Read.account_name <* P.eof)
1513 () "" ("( )A"::Text)])
1517 (Data.Either.rights $
1519 (Format.Ledger.Read.account_name <* P.eof)
1520 () "" ("(A) A"::Text)])
1524 (Data.Either.rights $
1526 (Format.Ledger.Read.account_name <* P.eof)
1527 () "" ("[ ]A"::Text)])
1531 (Data.Either.rights $
1533 (Format.Ledger.Read.account_name <* P.eof)
1534 () "" ("(A) "::Text)])
1538 (Data.Either.rights $
1540 (Format.Ledger.Read.account_name <* P.eof)
1541 () "" ("(A)"::Text)])
1545 (Data.Either.rights $
1547 (Format.Ledger.Read.account_name <* P.eof)
1548 () "" ("A(A)"::Text)])
1552 (Data.Either.rights $
1554 (Format.Ledger.Read.account_name <* P.eof)
1555 () "" ("[A]A"::Text)])
1559 (Data.Either.rights $
1561 (Format.Ledger.Read.account_name <* P.eof)
1562 () "" ("[A] A"::Text)])
1566 (Data.Either.rights $
1568 (Format.Ledger.Read.account_name <* P.eof)
1569 () "" ("[A] "::Text)])
1573 (Data.Either.rights $
1575 (Format.Ledger.Read.account_name <* P.eof)
1576 () "" ("[A]"::Text)])
1580 , "account" ~: TestList
1582 (Data.Either.rights $
1584 (Format.Ledger.Read.account <* P.eof)
1589 (Data.Either.rights $
1591 (Format.Ledger.Read.account <* P.eof)
1596 (Data.Either.rights $
1598 (Format.Ledger.Read.account <* P.eof)
1599 () "" ("A:"::Text)])
1603 (Data.Either.rights $
1605 (Format.Ledger.Read.account <* P.eof)
1606 () "" (":A"::Text)])
1610 (Data.Either.rights $
1612 (Format.Ledger.Read.account <* P.eof)
1613 () "" ("A "::Text)])
1617 (Data.Either.rights $
1619 (Format.Ledger.Read.account <* P.eof)
1620 () "" (" A"::Text)])
1624 (Data.Either.rights $
1626 (Format.Ledger.Read.account <* P.eof)
1627 () "" ("A:B"::Text)])
1631 (Data.Either.rights $
1633 (Format.Ledger.Read.account <* P.eof)
1634 () "" ("A:B:C"::Text)])
1637 , "\"Aa:Bbb:Cccc\"" ~:
1638 (Data.Either.rights $
1640 (Format.Ledger.Read.account <* P.eof)
1641 () "" ("Aa:Bbb:Cccc"::Text)])
1643 ["Aa":|["Bbb", "Cccc"]]
1644 , "\"A a : B b b : C c c c\"" ~:
1645 (Data.Either.rights $
1647 (Format.Ledger.Read.account <* P.eof)
1648 () "" ("A a : B b b : C c c c"::Text)])
1650 ["A a ":|[" B b b ", " C c c c"]]
1652 (Data.Either.rights $
1654 (Format.Ledger.Read.account <* P.eof)
1655 () "" ("A: :C"::Text)])
1659 (Data.Either.rights $
1661 (Format.Ledger.Read.account <* P.eof)
1662 () "" ("A::C"::Text)])
1666 (Data.Either.rights $
1668 (Format.Ledger.Read.account <* P.eof)
1669 () "" ("A:B:(C)"::Text)])
1673 , "posting_type" ~: TestList
1675 Format.Ledger.Read.posting_type
1678 (Format.Ledger.Posting_Type_Regular, "A":|[])
1680 Format.Ledger.Read.posting_type
1683 (Format.Ledger.Posting_Type_Regular, "(":|[])
1685 Format.Ledger.Read.posting_type
1688 (Format.Ledger.Posting_Type_Regular, ")":|[])
1690 Format.Ledger.Read.posting_type
1693 (Format.Ledger.Posting_Type_Regular, "()":|[])
1695 Format.Ledger.Read.posting_type
1698 (Format.Ledger.Posting_Type_Regular, "( )":|[])
1700 Format.Ledger.Read.posting_type
1703 (Format.Ledger.Posting_Type_Virtual, "A":|[])
1705 Format.Ledger.Read.posting_type
1708 (Format.Ledger.Posting_Type_Virtual, "A":|["B", "C"])
1710 Format.Ledger.Read.posting_type
1713 (Format.Ledger.Posting_Type_Regular, "A":|["B", "C"])
1715 Format.Ledger.Read.posting_type
1718 (Format.Ledger.Posting_Type_Regular, "(A)":|["B", "C"])
1720 Format.Ledger.Read.posting_type
1723 (Format.Ledger.Posting_Type_Regular, "A":|["(B)", "C"])
1725 Format.Ledger.Read.posting_type
1728 (Format.Ledger.Posting_Type_Regular, "A":|["B", "(C)"])
1730 Format.Ledger.Read.posting_type
1733 (Format.Ledger.Posting_Type_Regular, "[":|[])
1735 Format.Ledger.Read.posting_type
1738 (Format.Ledger.Posting_Type_Regular, "]":|[])
1740 Format.Ledger.Read.posting_type
1743 (Format.Ledger.Posting_Type_Regular, "[]":|[])
1745 Format.Ledger.Read.posting_type
1748 (Format.Ledger.Posting_Type_Regular, "[ ]":|[])
1750 Format.Ledger.Read.posting_type
1753 (Format.Ledger.Posting_Type_Virtual_Balanced, "A":|[])
1755 Format.Ledger.Read.posting_type
1758 (Format.Ledger.Posting_Type_Virtual_Balanced, "A":|["B", "C"])
1760 Format.Ledger.Read.posting_type
1763 (Format.Ledger.Posting_Type_Regular, "A":|["B", "C"])
1765 Format.Ledger.Read.posting_type
1768 (Format.Ledger.Posting_Type_Regular, "[A]":|["B", "C"])
1770 Format.Ledger.Read.posting_type
1773 (Format.Ledger.Posting_Type_Regular, "A":|["[B]", "C"])
1775 Format.Ledger.Read.posting_type
1778 (Format.Ledger.Posting_Type_Regular, "A":|["B", "[C]"])
1780 , "amount" ~: TestList
1782 (Data.Either.rights $
1784 (Format.Ledger.Read.amount <* P.eof)
1788 , "\"0\" = Right 0" ~:
1789 (Data.Either.rights $
1791 (Format.Ledger.Read.amount <* P.eof)
1795 { Amount.quantity = Decimal 0 0
1797 , "\"00\" = Right 0" ~:
1798 (Data.Either.rights $
1800 (Format.Ledger.Read.amount <* P.eof)
1801 () "" ("00"::Text)])
1804 { Amount.quantity = Decimal 0 0
1806 , "\"0.\" = Right 0." ~:
1807 (Data.Either.rights $
1809 (Format.Ledger.Read.amount <* P.eof)
1810 () "" ("0."::Text)])
1813 { Amount.quantity = Decimal 0 0
1816 { Amount.Style.fractioning = Just '.'
1819 , "\".0\" = Right 0.0" ~:
1820 (Data.Either.rights $
1822 (Format.Ledger.Read.amount <* P.eof)
1823 () "" (".0"::Text)])
1826 { Amount.quantity = Decimal 0 0
1829 { Amount.Style.fractioning = Just '.'
1830 , Amount.Style.precision = 1
1833 , "\"0,\" = Right 0," ~:
1834 (Data.Either.rights $
1836 (Format.Ledger.Read.amount <* P.eof)
1837 () "" ("0,"::Text)])
1840 { Amount.quantity = Decimal 0 0
1843 { Amount.Style.fractioning = Just ','
1846 , "\",0\" = Right 0,0" ~:
1847 (Data.Either.rights $
1849 (Format.Ledger.Read.amount <* P.eof)
1850 () "" (",0"::Text)])
1853 { Amount.quantity = Decimal 0 0
1856 { Amount.Style.fractioning = Just ','
1857 , Amount.Style.precision = 1
1860 , "\"0_\" = Left" ~:
1861 (Data.Either.rights $
1863 (Format.Ledger.Read.amount <* P.eof)
1864 () "" ("0_"::Text)])
1867 , "\"_0\" = Left" ~:
1868 (Data.Either.rights $
1870 (Format.Ledger.Read.amount <* P.eof)
1871 () "" ("_0"::Text)])
1874 , "\"0.0\" = Right 0.0" ~:
1875 (Data.Either.rights $
1877 (Format.Ledger.Read.amount <* P.eof)
1878 () "" ("0.0"::Text)])
1881 { Amount.quantity = Decimal 0 0
1884 { Amount.Style.fractioning = Just '.'
1885 , Amount.Style.precision = 1
1888 , "\"00.00\" = Right 0.00" ~:
1889 (Data.Either.rights $
1891 (Format.Ledger.Read.amount <* P.eof)
1892 () "" ("00.00"::Text)])
1895 { Amount.quantity = Decimal 0 0
1898 { Amount.Style.fractioning = Just '.'
1899 , Amount.Style.precision = 2
1902 , "\"0,0\" = Right 0,0" ~:
1903 (Data.Either.rights $
1905 (Format.Ledger.Read.amount <* P.eof)
1906 () "" ("0,0"::Text)])
1909 { Amount.quantity = Decimal 0 0
1912 { Amount.Style.fractioning = Just ','
1913 , Amount.Style.precision = 1
1916 , "\"00,00\" = Right 0,00" ~:
1917 (Data.Either.rights $
1919 (Format.Ledger.Read.amount <* P.eof)
1920 () "" ("00,00"::Text)])
1923 { Amount.quantity = Decimal 0 0
1926 { Amount.Style.fractioning = Just ','
1927 , Amount.Style.precision = 2
1930 , "\"0_0\" = Right 0" ~:
1931 (Data.Either.rights $
1933 (Format.Ledger.Read.amount <* P.eof)
1934 () "" ("0_0"::Text)])
1937 { Amount.quantity = Decimal 0 0
1940 { Amount.Style.fractioning = Nothing
1941 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
1942 , Amount.Style.precision = 0
1945 , "\"00_00\" = Right 0" ~:
1946 (Data.Either.rights $
1948 (Format.Ledger.Read.amount <* P.eof)
1949 () "" ("00_00"::Text)])
1952 { Amount.quantity = Decimal 0 0
1955 { Amount.Style.fractioning = Nothing
1956 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
1957 , Amount.Style.precision = 0
1960 , "\"0,000.00\" = Right 0,000.00" ~:
1961 (Data.Either.rights $
1963 (Format.Ledger.Read.amount <* P.eof)
1964 () "" ("0,000.00"::Text)])
1967 { Amount.quantity = Decimal 0 0
1970 { Amount.Style.fractioning = Just '.'
1971 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
1972 , Amount.Style.precision = 2
1975 , "\"0.000,00\" = Right 0.000,00" ~:
1976 (Data.Either.rights $
1978 (Format.Ledger.Read.amount)
1979 () "" ("0.000,00"::Text)])
1982 { Amount.quantity = Decimal 0 0
1985 { Amount.Style.fractioning = Just ','
1986 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
1987 , Amount.Style.precision = 2
1990 , "\"1,000.00\" = Right 1,000.00" ~:
1991 (Data.Either.rights $
1993 (Format.Ledger.Read.amount <* P.eof)
1994 () "" ("1,000.00"::Text)])
1997 { Amount.quantity = Decimal 0 1000
2000 { Amount.Style.fractioning = Just '.'
2001 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
2002 , Amount.Style.precision = 2
2005 , "\"1.000,00\" = Right 1.000,00" ~:
2006 (Data.Either.rights $
2008 (Format.Ledger.Read.amount)
2009 () "" ("1.000,00"::Text)])
2012 { Amount.quantity = Decimal 0 1000
2015 { Amount.Style.fractioning = Just ','
2016 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
2017 , Amount.Style.precision = 2
2020 , "\"1,000.00.\" = Left" ~:
2021 (Data.Either.rights $
2023 (Format.Ledger.Read.amount)
2024 () "" ("1,000.00."::Text)])
2027 , "\"1.000,00,\" = Left" ~:
2028 (Data.Either.rights $
2030 (Format.Ledger.Read.amount)
2031 () "" ("1.000,00,"::Text)])
2034 , "\"1,000.00_\" = Left" ~:
2035 (Data.Either.rights $
2037 (Format.Ledger.Read.amount)
2038 () "" ("1,000.00_"::Text)])
2041 , "\"12\" = Right 12" ~:
2042 (Data.Either.rights $
2044 (Format.Ledger.Read.amount <* P.eof)
2045 () "" ("123"::Text)])
2048 { Amount.quantity = Decimal 0 123
2050 , "\"1.2\" = Right 1.2" ~:
2051 (Data.Either.rights $
2053 (Format.Ledger.Read.amount <* P.eof)
2054 () "" ("1.2"::Text)])
2057 { Amount.quantity = Decimal 1 12
2060 { Amount.Style.fractioning = Just '.'
2061 , Amount.Style.precision = 1
2064 , "\"1,2\" = Right 1,2" ~:
2065 (Data.Either.rights $
2067 (Format.Ledger.Read.amount <* P.eof)
2068 () "" ("1,2"::Text)])
2071 { Amount.quantity = Decimal 1 12
2074 { Amount.Style.fractioning = Just ','
2075 , Amount.Style.precision = 1
2078 , "\"12.23\" = Right 12.23" ~:
2079 (Data.Either.rights $
2081 (Format.Ledger.Read.amount <* P.eof)
2082 () "" ("12.34"::Text)])
2085 { Amount.quantity = Decimal 2 1234
2088 { Amount.Style.fractioning = Just '.'
2089 , Amount.Style.precision = 2
2092 , "\"12,23\" = Right 12,23" ~:
2093 (Data.Either.rights $
2095 (Format.Ledger.Read.amount <* P.eof)
2096 () "" ("12,34"::Text)])
2099 { Amount.quantity = Decimal 2 1234
2102 { Amount.Style.fractioning = Just ','
2103 , Amount.Style.precision = 2
2106 , "\"1_2\" = Right 1_2" ~:
2107 (Data.Either.rights $
2109 (Format.Ledger.Read.amount <* P.eof)
2110 () "" ("1_2"::Text)])
2113 { Amount.quantity = Decimal 0 12
2116 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
2117 , Amount.Style.precision = 0
2120 , "\"1_23\" = Right 1_23" ~:
2121 (Data.Either.rights $
2123 (Format.Ledger.Read.amount <* P.eof)
2124 () "" ("1_23"::Text)])
2127 { Amount.quantity = Decimal 0 123
2130 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
2131 , Amount.Style.precision = 0
2134 , "\"1_23_456\" = Right 1_23_456" ~:
2135 (Data.Either.rights $
2137 (Format.Ledger.Read.amount <* P.eof)
2138 () "" ("1_23_456"::Text)])
2141 { Amount.quantity = Decimal 0 123456
2144 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
2145 , Amount.Style.precision = 0
2148 , "\"1_23_456.7890_12345_678901\" = Right 1_23_456.7890_12345_678901" ~:
2149 (Data.Either.rights $
2151 (Format.Ledger.Read.amount <* P.eof)
2152 () "" ("1_23_456.7890_12345_678901"::Text)])
2155 { Amount.quantity = Decimal 15 123456789012345678901
2158 { Amount.Style.fractioning = Just '.'
2159 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
2160 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [4, 5, 6]
2161 , Amount.Style.precision = 15
2164 , "\"123456_78901_2345.678_90_1\" = Right 123456_78901_2345.678_90_1" ~:
2165 (Data.Either.rights $
2167 (Format.Ledger.Read.amount <* P.eof)
2168 () "" ("123456_78901_2345.678_90_1"::Text)])
2171 { Amount.quantity = Decimal 6 123456789012345678901
2174 { Amount.Style.fractioning = Just '.'
2175 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [4, 5, 6]
2176 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [3, 2]
2177 , Amount.Style.precision = 6
2180 , "\"$1\" = Right $1" ~:
2181 (Data.Either.rights $
2183 (Format.Ledger.Read.amount <* P.eof)
2184 () "" ("$1"::Text)])
2187 { Amount.quantity = Decimal 0 1
2190 { Amount.Style.fractioning = Nothing
2191 , Amount.Style.grouping_integral = Nothing
2192 , Amount.Style.grouping_fractional = Nothing
2193 , Amount.Style.precision = 0
2194 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2195 , Amount.Style.unit_spaced = Just False
2199 , "\"1$\" = Right 1$" ~:
2200 (Data.Either.rights $
2202 (Format.Ledger.Read.amount <* P.eof)
2203 () "" ("1$"::Text)])
2206 { Amount.quantity = Decimal 0 1
2209 { Amount.Style.fractioning = Nothing
2210 , Amount.Style.grouping_integral = Nothing
2211 , Amount.Style.grouping_fractional = Nothing
2212 , Amount.Style.precision = 0
2213 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2214 , Amount.Style.unit_spaced = Just False
2218 , "\"$ 1\" = Right $ 1" ~:
2219 (Data.Either.rights $
2221 (Format.Ledger.Read.amount <* P.eof)
2222 () "" ("$ 1"::Text)])
2225 { Amount.quantity = Decimal 0 1
2228 { Amount.Style.fractioning = Nothing
2229 , Amount.Style.grouping_integral = Nothing
2230 , Amount.Style.grouping_fractional = Nothing
2231 , Amount.Style.precision = 0
2232 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2233 , Amount.Style.unit_spaced = Just True
2237 , "\"1 $\" = Right 1 $" ~:
2238 (Data.Either.rights $
2240 (Format.Ledger.Read.amount <* P.eof)
2241 () "" ("1 $"::Text)])
2244 { Amount.quantity = Decimal 0 1
2247 { Amount.Style.fractioning = Nothing
2248 , Amount.Style.grouping_integral = Nothing
2249 , Amount.Style.grouping_fractional = Nothing
2250 , Amount.Style.precision = 0
2251 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2252 , Amount.Style.unit_spaced = Just True
2256 , "\"-$1\" = Right $-1" ~:
2257 (Data.Either.rights $
2259 (Format.Ledger.Read.amount <* P.eof)
2260 () "" ("-$1"::Text)])
2263 { Amount.quantity = Decimal 0 (-1)
2266 { Amount.Style.fractioning = Nothing
2267 , Amount.Style.grouping_integral = Nothing
2268 , Amount.Style.grouping_fractional = Nothing
2269 , Amount.Style.precision = 0
2270 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2271 , Amount.Style.unit_spaced = Just False
2275 , "\"\\\"4 2\\\"1\" = Right \\\"4 2\\\"1" ~:
2276 (Data.Either.rights $
2278 (Format.Ledger.Read.amount <* P.eof)
2279 () "" ("\"4 2\"1"::Text)])
2282 { Amount.quantity = Decimal 0 1
2285 { Amount.Style.fractioning = Nothing
2286 , Amount.Style.grouping_integral = Nothing
2287 , Amount.Style.grouping_fractional = Nothing
2288 , Amount.Style.precision = 0
2289 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2290 , Amount.Style.unit_spaced = Just False
2292 , Amount.unit = "4 2"
2294 , "\"1\\\"4 2\\\"\" = Right 1\\\"4 2\\\"" ~:
2295 (Data.Either.rights $
2297 (Format.Ledger.Read.amount <* P.eof)
2298 () "" ("1\"4 2\""::Text)])
2301 { Amount.quantity = Decimal 0 1
2304 { Amount.Style.fractioning = Nothing
2305 , Amount.Style.grouping_integral = Nothing
2306 , Amount.Style.grouping_fractional = Nothing
2307 , Amount.Style.precision = 0
2308 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2309 , Amount.Style.unit_spaced = Just False
2311 , Amount.unit = "4 2"
2313 , "\"$1.000,00\" = Right $1.000,00" ~:
2314 (Data.Either.rights $
2316 (Format.Ledger.Read.amount <* P.eof)
2317 () "" ("$1.000,00"::Text)])
2320 { Amount.quantity = Decimal 0 1000
2323 { Amount.Style.fractioning = Just ','
2324 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
2325 , Amount.Style.grouping_fractional = Nothing
2326 , Amount.Style.precision = 2
2327 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2328 , Amount.Style.unit_spaced = Just False
2332 , "\"1.000,00$\" = Right 1.000,00$" ~:
2333 (Data.Either.rights $
2335 (Format.Ledger.Read.amount <* P.eof)
2336 () "" ("1.000,00$"::Text)])
2339 { Amount.quantity = Decimal 0 1000
2342 { Amount.Style.fractioning = Just ','
2343 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
2344 , Amount.Style.grouping_fractional = Nothing
2345 , Amount.Style.precision = 2
2346 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2347 , Amount.Style.unit_spaced = Just False
2352 , "comment" ~: TestList
2353 [ "; some comment = Right \" some comment\"" ~:
2354 (Data.Either.rights $
2356 (Format.Ledger.Read.comment <* P.eof)
2357 () "" ("; some comment"::Text)])
2360 , "; some comment \\n = Right \" some comment \"" ~:
2361 (Data.Either.rights $
2363 (Format.Ledger.Read.comment <* P.newline <* P.eof)
2364 () "" ("; some comment \n"::Text)])
2366 [ " some comment " ]
2367 , "; some comment \\r\\n = Right \" some comment \"" ~:
2368 (Data.Either.rights $
2370 (Format.Ledger.Read.comment <* P.string "\r\n" <* P.eof)
2371 () "" ("; some comment \r\n"::Text)])
2373 [ " some comment " ]
2375 , "comments" ~: TestList
2376 [ "; some comment\\n ; some other comment = Right [\" some comment\", \" some other comment\"]" ~:
2377 (Data.Either.rights $
2379 (Format.Ledger.Read.comments <* P.eof)
2380 () "" ("; some comment\n ; some other comment"::Text)])
2382 [ [" some comment", " some other comment"] ]
2383 , "; some comment \\n = Right \" some comment \"" ~:
2384 (Data.Either.rights $
2386 (Format.Ledger.Read.comments <* P.string "\n" <* P.eof)
2387 () "" ("; some comment \n"::Text)])
2389 [ [" some comment "] ]
2391 , "date" ~: TestList
2393 (Data.Either.rights $
2394 [P.runParser_with_Error
2395 (Format.Ledger.Read.date Nothing <* P.eof)
2396 () "" ("2000/01/01"::Text)])
2400 (Time.fromGregorian 2000 01 01)
2401 (Time.TimeOfDay 0 0 0))
2403 , "2000/01/01 some text" ~:
2404 (Data.Either.rights $
2405 [P.runParser_with_Error
2406 (Format.Ledger.Read.date Nothing)
2407 () "" ("2000/01/01 some text"::Text)])
2411 (Time.fromGregorian 2000 01 01)
2412 (Time.TimeOfDay 0 0 0))
2414 , "2000/01/01 12:34" ~:
2415 (Data.Either.rights $
2416 [P.runParser_with_Error
2417 (Format.Ledger.Read.date Nothing <* P.eof)
2418 () "" ("2000/01/01 12:34"::Text)])
2422 (Time.fromGregorian 2000 01 01)
2423 (Time.TimeOfDay 12 34 0))
2425 , "2000/01/01 12:34:56" ~:
2426 (Data.Either.rights $
2427 [P.runParser_with_Error
2428 (Format.Ledger.Read.date Nothing <* P.eof)
2429 () "" ("2000/01/01 12:34:56"::Text)])
2433 (Time.fromGregorian 2000 01 01)
2434 (Time.TimeOfDay 12 34 56))
2436 , "2000/01/01 12:34 CET" ~:
2437 (Data.Either.rights $
2438 [P.runParser_with_Error
2439 (Format.Ledger.Read.date Nothing <* P.eof)
2440 () "" ("2000/01/01 12:34 CET"::Text)])
2444 (Time.fromGregorian 2000 01 01)
2445 (Time.TimeOfDay 12 34 0))
2446 (Time.TimeZone 60 True "CET")]
2447 , "2000/01/01 12:34 +0130" ~:
2448 (Data.Either.rights $
2449 [P.runParser_with_Error
2450 (Format.Ledger.Read.date Nothing <* P.eof)
2451 () "" ("2000/01/01 12:34 +0130"::Text)])
2455 (Time.fromGregorian 2000 01 01)
2456 (Time.TimeOfDay 12 34 0))
2457 (Time.TimeZone 90 False "+0130")]
2458 , "2000/01/01 12:34:56 CET" ~:
2459 (Data.Either.rights $
2460 [P.runParser_with_Error
2461 (Format.Ledger.Read.date Nothing <* P.eof)
2462 () "" ("2000/01/01 12:34:56 CET"::Text)])
2466 (Time.fromGregorian 2000 01 01)
2467 (Time.TimeOfDay 12 34 56))
2468 (Time.TimeZone 60 True "CET")]
2470 (Data.Either.rights $
2471 [P.runParser_with_Error
2472 (Format.Ledger.Read.date Nothing <* P.eof)
2473 () "" ("2001/02/29"::Text)])
2477 (Data.Either.rights $
2478 [P.runParser_with_Error
2479 (Format.Ledger.Read.date (Just 2000) <* P.eof)
2480 () "" ("01/01"::Text)])
2484 (Time.fromGregorian 2000 01 01)
2485 (Time.TimeOfDay 0 0 0))
2488 , "tag_value" ~: TestList
2490 (Data.Either.rights $
2492 (Format.Ledger.Read.tag_value <* P.eof)
2497 (Data.Either.rights $
2499 (Format.Ledger.Read.tag_value <* P.char '\n' <* P.eof)
2500 () "" (",\n"::Text)])
2504 (Data.Either.rights $
2506 (Format.Ledger.Read.tag_value <* P.eof)
2507 () "" (",x"::Text)])
2511 (Data.Either.rights $
2513 (Format.Ledger.Read.tag_value <* P.string ",x:" <* P.eof)
2514 () "" (",x:"::Text)])
2518 (Data.Either.rights $
2520 (Format.Ledger.Read.tag_value <* P.string ", n:" <* P.eof)
2521 () "" ("v, v, n:"::Text)])
2527 (Data.Either.rights $
2529 (Format.Ledger.Read.tag <* P.eof)
2530 () "" ("Name:"::Text)])
2534 (Data.Either.rights $
2536 (Format.Ledger.Read.tag <* P.eof)
2537 () "" ("Name:Value"::Text)])
2540 , "Name:Value\\n" ~:
2541 (Data.Either.rights $
2543 (Format.Ledger.Read.tag <* P.string "\n" <* P.eof)
2544 () "" ("Name:Value\n"::Text)])
2548 (Data.Either.rights $
2550 (Format.Ledger.Read.tag <* P.eof)
2551 () "" ("Name:Val ue"::Text)])
2553 [("Name", "Val ue")]
2555 (Data.Either.rights $
2557 (Format.Ledger.Read.tag <* P.eof)
2558 () "" ("Name:,"::Text)])
2562 (Data.Either.rights $
2564 (Format.Ledger.Read.tag <* P.eof)
2565 () "" ("Name:Val,ue"::Text)])
2567 [("Name", "Val,ue")]
2569 (Data.Either.rights $
2571 (Format.Ledger.Read.tag <* P.string ",ue:" <* P.eof)
2572 () "" ("Name:Val,ue:"::Text)])
2576 , "tags" ~: TestList
2578 (Data.Either.rights $
2580 (Format.Ledger.Read.tags <* P.eof)
2581 () "" ("Name:"::Text)])
2588 (Data.Either.rights $
2590 (Format.Ledger.Read.tags <* P.eof)
2591 () "" ("Name:,"::Text)])
2598 (Data.Either.rights $
2600 (Format.Ledger.Read.tags <* P.eof)
2601 () "" ("Name:,Name:"::Text)])
2604 [ ("Name", ["", ""])
2608 (Data.Either.rights $
2610 (Format.Ledger.Read.tags <* P.eof)
2611 () "" ("Name:,Name2:"::Text)])
2618 , "Name: , Name2:" ~:
2619 (Data.Either.rights $
2621 (Format.Ledger.Read.tags <* P.eof)
2622 () "" ("Name: , Name2:"::Text)])
2629 , "Name:,Name2:,Name3:" ~:
2630 (Data.Either.rights $
2632 (Format.Ledger.Read.tags <* P.eof)
2633 () "" ("Name:,Name2:,Name3:"::Text)])
2641 , "Name:Val ue,Name2:V a l u e,Name3:V al ue" ~:
2642 (Data.Either.rights $
2644 (Format.Ledger.Read.tags <* P.eof)
2645 () "" ("Name:Val ue,Name2:V a l u e,Name3:V al ue"::Text)])
2648 [ ("Name", ["Val ue"])
2649 , ("Name2", ["V a l u e"])
2650 , ("Name3", ["V al ue"])
2654 , "posting" ~: TestList
2655 [ " A:B:C = Right A:B:C" ~:
2656 (Data.Either.rights $
2657 [P.runParser_with_Error
2658 (Format.Ledger.Read.posting <* P.eof)
2659 Format.Ledger.Read.nil_Context "" (" A:B:C"::Text)])
2661 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
2662 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2664 , Format.Ledger.Posting_Type_Regular
2667 , " !A:B:C = Right !A:B:C" ~:
2668 (Data.List.map fst $
2669 Data.Either.rights $
2670 [P.runParser_with_Error
2671 (Format.Ledger.Read.posting <* P.eof)
2672 Format.Ledger.Read.nil_Context "" (" !A:B:C"::Text)])
2674 [ (Format.Ledger.posting ("A":|["B", "C"]))
2675 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2676 , Format.Ledger.posting_status = True
2679 , " *A:B:C = Right *A:B:C" ~:
2680 (Data.List.map fst $
2681 Data.Either.rights $
2682 [P.runParser_with_Error
2683 (Format.Ledger.Read.posting <* P.eof)
2684 Format.Ledger.Read.nil_Context "" (" *A:B:C"::Text)])
2686 [ (Format.Ledger.posting ("A":|["B", "C"]))
2687 { Format.Ledger.posting_amounts = Data.Map.fromList []
2688 , Format.Ledger.posting_comments = []
2689 , Format.Ledger.posting_dates = []
2690 , Format.Ledger.posting_status = True
2691 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2692 , Format.Ledger.posting_tags = Data.Map.fromList []
2695 , " A:B:C $1 = Right A:B:C $1" ~:
2696 (Data.List.map fst $
2697 Data.Either.rights $
2698 [P.runParser_with_Error
2699 (Format.Ledger.Read.posting <* P.eof)
2700 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
2702 [ (Format.Ledger.posting ("A":|["B","C $1"]))
2703 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2706 , " A:B:C $1 = Right A:B:C $1" ~:
2707 (Data.List.map fst $
2708 Data.Either.rights $
2709 [P.runParser_with_Error
2710 (Format.Ledger.Read.posting <* P.eof)
2711 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
2713 [ (Format.Ledger.posting ("A":|["B", "C"]))
2714 { Format.Ledger.posting_amounts = Data.Map.fromList
2716 { Amount.quantity = 1
2717 , Amount.style = Amount.Style.nil
2718 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2719 , Amount.Style.unit_spaced = Just False
2724 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2727 , " A:B:C $1 + 1€ = Right A:B:C $1 + 1€" ~:
2728 (Data.List.map fst $
2729 Data.Either.rights $
2730 [P.runParser_with_Error
2731 (Format.Ledger.Read.posting <* P.eof)
2732 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1€"::Text)])
2734 [ (Format.Ledger.posting ("A":|["B", "C"]))
2735 { Format.Ledger.posting_amounts = Data.Map.fromList
2737 { Amount.quantity = 1
2738 , Amount.style = Amount.Style.nil
2739 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2740 , Amount.Style.unit_spaced = Just False
2745 { Amount.quantity = 1
2746 , Amount.style = Amount.Style.nil
2747 { Amount.Style.unit_side = Just Amount.Style.Side_Right
2748 , Amount.Style.unit_spaced = Just False
2753 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2756 , " A:B:C $1 + 1$ = Right A:B:C $2" ~:
2757 (Data.List.map fst $
2758 Data.Either.rights $
2759 [P.runParser_with_Error
2760 (Format.Ledger.Read.posting <* P.eof)
2761 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$"::Text)])
2763 [ (Format.Ledger.posting ("A":|["B", "C"]))
2764 { Format.Ledger.posting_amounts = Data.Map.fromList
2766 { Amount.quantity = 2
2767 , Amount.style = Amount.Style.nil
2768 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2769 , Amount.Style.unit_spaced = Just False
2774 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2777 , " A:B:C $1 + 1$ + 1$ = Right A:B:C $3" ~:
2778 (Data.List.map fst $
2779 Data.Either.rights $
2780 [P.runParser_with_Error
2781 (Format.Ledger.Read.posting <* P.eof)
2782 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$ + 1$"::Text)])
2784 [ (Format.Ledger.posting ("A":|["B", "C"]))
2785 { Format.Ledger.posting_amounts = Data.Map.fromList
2787 { Amount.quantity = 3
2788 , Amount.style = Amount.Style.nil
2789 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2790 , Amount.Style.unit_spaced = Just False
2795 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2798 , " A:B:C ; some comment = Right A:B:C ; some comment" ~:
2799 (Data.List.map fst $
2800 Data.Either.rights $
2801 [P.runParser_with_Error
2802 (Format.Ledger.Read.posting <* P.eof)
2803 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment"::Text)])
2805 [ (Format.Ledger.posting ("A":|["B", "C"]))
2806 { Format.Ledger.posting_amounts = Data.Map.fromList []
2807 , Format.Ledger.posting_comments = [" some comment"]
2808 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2811 , " A:B:C ; some comment\\n ; some other comment = Right A:B:C ; some comment\\n ; some other comment" ~:
2812 (Data.List.map fst $
2813 Data.Either.rights $
2814 [P.runParser_with_Error
2815 (Format.Ledger.Read.posting <* P.eof)
2816 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment\n ; some other comment"::Text)])
2818 [ (Format.Ledger.posting ("A":|["B", "C"]))
2819 { Format.Ledger.posting_amounts = Data.Map.fromList []
2820 , Format.Ledger.posting_comments = [" some comment", " some other comment"]
2821 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2824 , " A:B:C $1 ; some comment = Right A:B:C $1 ; some comment" ~:
2825 (Data.List.map fst $
2826 Data.Either.rights $
2827 [P.runParser_with_Error
2828 (Format.Ledger.Read.posting)
2829 Format.Ledger.Read.nil_Context "" (" A:B:C $1 ; some comment"::Text)])
2831 [ (Format.Ledger.posting ("A":|["B", "C"]))
2832 { Format.Ledger.posting_amounts = Data.Map.fromList
2834 { Amount.quantity = 1
2835 , Amount.style = Amount.Style.nil
2836 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2837 , Amount.Style.unit_spaced = Just False
2842 , Format.Ledger.posting_comments = [" some comment"]
2843 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2846 , " A:B:C ; N:V = Right A:B:C ; N:V" ~:
2847 (Data.List.map fst $
2848 Data.Either.rights $
2849 [P.runParser_with_Error
2850 (Format.Ledger.Read.posting <* P.eof)
2851 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V"::Text)])
2853 [ (Format.Ledger.posting ("A":|["B", "C"]))
2854 { Format.Ledger.posting_comments = [" N:V"]
2855 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2856 , Format.Ledger.posting_tags = Data.Map.fromList
2861 , " A:B:C ; some comment N:V = Right A:B:C ; some comment N:V" ~:
2862 (Data.List.map fst $
2863 Data.Either.rights $
2864 [P.runParser_with_Error
2865 (Format.Ledger.Read.posting <* P.eof)
2866 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V"::Text)])
2868 [ (Format.Ledger.posting ("A":|["B", "C"]))
2869 { Format.Ledger.posting_comments = [" some comment N:V"]
2870 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2871 , Format.Ledger.posting_tags = Data.Map.fromList
2876 , " A:B:C ; some comment N:V v, N2:V2 v2 = Right A:B:C ; some comment N:V v, N2:V2 v2" ~:
2877 (Data.List.map fst $
2878 Data.Either.rights $
2879 [P.runParser_with_Error
2880 (Format.Ledger.Read.posting )
2881 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V v, N2:V2 v2"::Text)])
2883 [ (Format.Ledger.posting ("A":|["B", "C"]))
2884 { Format.Ledger.posting_comments = [" some comment N:V v, N2:V2 v2"]
2885 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2886 , Format.Ledger.posting_tags = Data.Map.fromList
2892 , " A:B:C ; N:V\\n ; N:V2 = Right A:B:C ; N:V\\n ; N:V2" ~:
2893 (Data.List.map fst $
2894 Data.Either.rights $
2895 [P.runParser_with_Error
2896 (Format.Ledger.Read.posting <* P.eof)
2897 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N:V2"::Text)])
2899 [ (Format.Ledger.posting ("A":|["B", "C"]))
2900 { Format.Ledger.posting_comments = [" N:V", " N:V2"]
2901 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2902 , Format.Ledger.posting_tags = Data.Map.fromList
2903 [ ("N", ["V", "V2"])
2907 , " A:B:C ; N:V\\n ; N2:V = Right A:B:C ; N:V\\n ; N2:V" ~:
2908 (Data.List.map fst $
2909 Data.Either.rights $
2910 [P.runParser_with_Error
2911 (Format.Ledger.Read.posting <* P.eof)
2912 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N2:V"::Text)])
2914 [ (Format.Ledger.posting ("A":|["B", "C"]))
2915 { Format.Ledger.posting_comments = [" N:V", " N2:V"]
2916 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2917 , Format.Ledger.posting_tags = Data.Map.fromList
2923 , " A:B:C ; date:2001/01/01 = Right A:B:C ; date:2001/01/01" ~:
2924 (Data.List.map fst $
2925 Data.Either.rights $
2926 [P.runParser_with_Error
2927 (Format.Ledger.Read.posting <* P.eof)
2928 Format.Ledger.Read.nil_Context "" (" A:B:C ; date:2001/01/01"::Text)])
2930 [ (Format.Ledger.posting ("A":|["B", "C"]))
2931 { Format.Ledger.posting_comments = [" date:2001/01/01"]
2932 , Format.Ledger.posting_dates =
2935 (Time.fromGregorian 2001 01 01)
2936 (Time.TimeOfDay 0 0 0))
2939 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2940 , Format.Ledger.posting_tags = Data.Map.fromList
2941 [ ("date", ["2001/01/01"])
2945 , " (A:B:C) = Right (A:B:C)" ~:
2946 (Data.Either.rights $
2947 [P.runParser_with_Error
2948 (Format.Ledger.Read.posting <* P.eof)
2949 Format.Ledger.Read.nil_Context "" (" (A:B:C)"::Text)])
2951 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
2952 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2954 , Format.Ledger.Posting_Type_Virtual
2957 , " [A:B:C] = Right [A:B:C]" ~:
2958 (Data.Either.rights $
2959 [P.runParser_with_Error
2960 (Format.Ledger.Read.posting <* P.eof)
2961 Format.Ledger.Read.nil_Context "" (" [A:B:C]"::Text)])
2963 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
2964 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2966 , Format.Ledger.Posting_Type_Virtual_Balanced
2970 , "transaction" ~: TestList
2971 [ "2000/01/01 some description\\n A:B:C $1\\n a:b:c" ~:
2972 (Data.Either.rights $
2973 [P.runParser_with_Error
2974 (Format.Ledger.Read.transaction <* P.eof)
2975 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c"::Text)])
2977 [ Format.Ledger.transaction
2978 { Format.Ledger.transaction_dates=
2981 (Time.fromGregorian 2000 01 01)
2982 (Time.TimeOfDay 0 0 0))
2985 , Format.Ledger.transaction_description="some description"
2986 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
2987 [ (Format.Ledger.posting ("A":|["B", "C"]))
2988 { Format.Ledger.posting_amounts = Data.Map.fromList
2990 { Amount.quantity = 1
2991 , Amount.style = Amount.Style.nil
2992 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2993 , Amount.Style.unit_spaced = Just False
2998 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3000 , (Format.Ledger.posting ("a":|["b", "c"]))
3001 { Format.Ledger.posting_amounts = Data.Map.fromList
3003 { Amount.quantity = -1
3004 , Amount.style = Amount.Style.nil
3005 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3006 , Amount.Style.unit_spaced = Just False
3011 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3014 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3017 , "2000/01/01 some description\\n A:B:C $1\\n a:b:c\\n" ~:
3018 (Data.Either.rights $
3019 [P.runParser_with_Error
3020 (Format.Ledger.Read.transaction <* P.newline <* P.eof)
3021 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c\n"::Text)])
3023 [ Format.Ledger.transaction
3024 { Format.Ledger.transaction_dates=
3027 (Time.fromGregorian 2000 01 01)
3028 (Time.TimeOfDay 0 0 0))
3031 , Format.Ledger.transaction_description="some description"
3032 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3033 [ (Format.Ledger.posting ("A":|["B", "C"]))
3034 { Format.Ledger.posting_amounts = Data.Map.fromList
3036 { Amount.quantity = 1
3037 , Amount.style = Amount.Style.nil
3038 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3039 , Amount.Style.unit_spaced = Just False
3044 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3046 , (Format.Ledger.posting ("a":|["b", "c"]))
3047 { Format.Ledger.posting_amounts = Data.Map.fromList
3049 { Amount.quantity = -1
3050 , Amount.style = Amount.Style.nil
3051 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3052 , Amount.Style.unit_spaced = Just False
3057 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3060 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3063 , "2000/01/01 some description ; some comment\\n ; some other;comment\\n ; some Tag:\\n ; some last comment\\n A:B:C $1\\n a:b:c" ~:
3064 (Data.Either.rights $
3065 [P.runParser_with_Error
3066 (Format.Ledger.Read.transaction <* P.eof)
3067 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description ; some comment\n ; some other;comment\n ; some Tag:\n ; some last comment\n A:B:C $1\n a:b:c"::Text)])
3069 [ Format.Ledger.transaction
3070 { Format.Ledger.transaction_comments_after =
3072 , " some other;comment"
3074 , " some last comment"
3076 , Format.Ledger.transaction_dates=
3079 (Time.fromGregorian 2000 01 01)
3080 (Time.TimeOfDay 0 0 0))
3083 , Format.Ledger.transaction_description="some description"
3084 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3085 [ (Format.Ledger.posting ("A":|["B", "C"]))
3086 { Format.Ledger.posting_amounts = Data.Map.fromList
3088 { Amount.quantity = 1
3089 , Amount.style = Amount.Style.nil
3090 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3091 , Amount.Style.unit_spaced = Just False
3096 , Format.Ledger.posting_sourcepos = P.newPos "" 5 1
3098 , (Format.Ledger.posting ("a":|["b", "c"]))
3099 { Format.Ledger.posting_amounts = Data.Map.fromList
3101 { Amount.quantity = -1
3102 , Amount.style = Amount.Style.nil
3103 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3104 , Amount.Style.unit_spaced = Just False
3109 , Format.Ledger.posting_sourcepos = P.newPos "" 6 1
3112 , Format.Ledger.transaction_tags = Data.Map.fromList
3115 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3119 , "journal" ~: TestList
3120 [ "2000/01/01 1° description\\n A:B:C $1\\n a:b:c\\n2000/01/02 2° description\\n A:B:C $1\\n x:y:z" ~: TestCase $ do
3122 P.runParserT_with_Error
3123 (Format.Ledger.Read.journal "" {-<* P.eof-})
3124 Format.Ledger.Read.nil_Context "" ("2000/01/01 1° description\n A:B:C $1\n a:b:c\n2000/01/02 2° description\n A:B:C $1\n x:y:z"::Text)
3126 (\j -> j{Format.Ledger.journal_last_read_time=
3127 Format.Ledger.journal_last_read_time Format.Ledger.journal}) $
3128 Data.Either.rights [jnl])
3130 [ Format.Ledger.journal
3131 { Format.Ledger.journal_transactions =
3132 Format.Ledger.transaction_by_Date
3133 [ Format.Ledger.transaction
3134 { Format.Ledger.transaction_dates=
3137 (Time.fromGregorian 2000 01 01)
3138 (Time.TimeOfDay 0 0 0))
3141 , Format.Ledger.transaction_description="1° description"
3142 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3143 [ (Format.Ledger.posting ("A":|["B", "C"]))
3144 { Format.Ledger.posting_amounts = Data.Map.fromList
3146 { Amount.quantity = 1
3147 , Amount.style = Amount.Style.nil
3148 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3149 , Amount.Style.unit_spaced = Just False
3154 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3156 , (Format.Ledger.posting ("a":|["b", "c"]))
3157 { Format.Ledger.posting_amounts = Data.Map.fromList
3159 { Amount.quantity = -1
3160 , Amount.style = Amount.Style.nil
3161 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3162 , Amount.Style.unit_spaced = Just False
3167 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3170 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3172 , Format.Ledger.transaction
3173 { Format.Ledger.transaction_dates=
3176 (Time.fromGregorian 2000 01 02)
3177 (Time.TimeOfDay 0 0 0))
3180 , Format.Ledger.transaction_description="2° description"
3181 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3182 [ (Format.Ledger.posting ("A":|["B", "C"]))
3183 { Format.Ledger.posting_amounts = Data.Map.fromList
3185 { Amount.quantity = 1
3186 , Amount.style = Amount.Style.nil
3187 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3188 , Amount.Style.unit_spaced = Just False
3193 , Format.Ledger.posting_sourcepos = P.newPos "" 5 1
3195 , (Format.Ledger.posting ("x":|["y", "z"]))
3196 { Format.Ledger.posting_amounts = Data.Map.fromList
3198 { Amount.quantity = -1
3199 , Amount.style = Amount.Style.nil
3200 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3201 , Amount.Style.unit_spaced = Just False
3206 , Format.Ledger.posting_sourcepos = P.newPos "" 6 1
3209 , Format.Ledger.transaction_sourcepos = P.newPos "" 4 1
3216 , "Write" ~: TestList
3217 [ "account" ~: TestList
3219 ((Format.Ledger.Write.show
3220 Format.Ledger.Write.Style
3221 { Format.Ledger.Write.style_color=False
3222 , Format.Ledger.Write.style_align=True
3224 Format.Ledger.Write.account Format.Ledger.Posting_Type_Regular $
3229 ((Format.Ledger.Write.show
3230 Format.Ledger.Write.Style
3231 { Format.Ledger.Write.style_color=False
3232 , Format.Ledger.Write.style_align=True
3234 Format.Ledger.Write.account Format.Ledger.Posting_Type_Regular $
3239 ((Format.Ledger.Write.show
3240 Format.Ledger.Write.Style
3241 { Format.Ledger.Write.style_color=False
3242 , Format.Ledger.Write.style_align=True
3244 Format.Ledger.Write.account Format.Ledger.Posting_Type_Virtual $
3249 ((Format.Ledger.Write.show
3250 Format.Ledger.Write.Style
3251 { Format.Ledger.Write.style_color=False
3252 , Format.Ledger.Write.style_align=True
3254 Format.Ledger.Write.account Format.Ledger.Posting_Type_Virtual_Balanced $
3259 , "amount" ~: TestList
3261 ((Format.Ledger.Write.show
3262 Format.Ledger.Write.Style
3263 { Format.Ledger.Write.style_color=False
3264 , Format.Ledger.Write.style_align=True
3266 Format.Ledger.Write.amount
3271 ((Format.Ledger.Write.show
3272 Format.Ledger.Write.Style
3273 { Format.Ledger.Write.style_color=False
3274 , Format.Ledger.Write.style_align=True
3276 Format.Ledger.Write.amount
3278 { Amount.style = Amount.Style.nil
3279 { Amount.Style.precision = 2 }
3284 ((Format.Ledger.Write.show
3285 Format.Ledger.Write.Style
3286 { Format.Ledger.Write.style_color=False
3287 , Format.Ledger.Write.style_align=True
3289 Format.Ledger.Write.amount
3291 { Amount.quantity = Decimal 0 123
3296 ((Format.Ledger.Write.show
3297 Format.Ledger.Write.Style
3298 { Format.Ledger.Write.style_color=False
3299 , Format.Ledger.Write.style_align=True
3301 Format.Ledger.Write.amount
3303 { Amount.quantity = Decimal 0 (- 123)
3307 , "12.3 @ prec=0" ~:
3308 ((Format.Ledger.Write.show
3309 Format.Ledger.Write.Style
3310 { Format.Ledger.Write.style_color=False
3311 , Format.Ledger.Write.style_align=True
3313 Format.Ledger.Write.amount
3315 { Amount.quantity = Decimal 1 123
3316 , Amount.style = Amount.Style.nil
3317 { Amount.Style.fractioning = Just '.'
3322 , "12.5 @ prec=0" ~:
3323 ((Format.Ledger.Write.show
3324 Format.Ledger.Write.Style
3325 { Format.Ledger.Write.style_color=False
3326 , Format.Ledger.Write.style_align=True
3328 Format.Ledger.Write.amount
3330 { Amount.quantity = Decimal 1 125
3331 , Amount.style = Amount.Style.nil
3332 { Amount.Style.fractioning = Just '.'
3337 , "12.3 @ prec=1" ~:
3338 ((Format.Ledger.Write.show
3339 Format.Ledger.Write.Style
3340 { Format.Ledger.Write.style_color=False
3341 , Format.Ledger.Write.style_align=True
3343 Format.Ledger.Write.amount
3345 { Amount.quantity = Decimal 1 123
3346 , Amount.style = Amount.Style.nil
3347 { Amount.Style.fractioning = Just '.'
3348 , Amount.Style.precision = 1
3353 , "1,234.56 @ prec=2" ~:
3354 ((Format.Ledger.Write.show
3355 Format.Ledger.Write.Style
3356 { Format.Ledger.Write.style_color=False
3357 , Format.Ledger.Write.style_align=True
3359 Format.Ledger.Write.amount
3361 { Amount.quantity = Decimal 2 123456
3362 , Amount.style = Amount.Style.nil
3363 { Amount.Style.fractioning = Just '.'
3364 , Amount.Style.precision = 2
3365 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
3370 , "123,456,789,01,2.3456789 @ prec=7" ~:
3371 ((Format.Ledger.Write.show
3372 Format.Ledger.Write.Style
3373 { Format.Ledger.Write.style_color=False
3374 , Format.Ledger.Write.style_align=True
3376 Format.Ledger.Write.amount
3378 { Amount.quantity = Decimal 7 1234567890123456789
3379 , Amount.style = Amount.Style.nil
3380 { Amount.Style.fractioning = Just '.'
3381 , Amount.Style.precision = 7
3382 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3386 "123,456,789,01,2.3456789")
3387 , "1234567.8,90,123,456,789 @ prec=12" ~:
3388 ((Format.Ledger.Write.show
3389 Format.Ledger.Write.Style
3390 { Format.Ledger.Write.style_color=False
3391 , Format.Ledger.Write.style_align=True
3393 Format.Ledger.Write.amount
3395 { Amount.quantity = Decimal 12 1234567890123456789
3396 , Amount.style = Amount.Style.nil
3397 { Amount.Style.fractioning = Just '.'
3398 , Amount.Style.precision = 12
3399 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3403 "1234567.8,90,123,456,789")
3404 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
3405 ((Format.Ledger.Write.show
3406 Format.Ledger.Write.Style
3407 { Format.Ledger.Write.style_color=False
3408 , Format.Ledger.Write.style_align=True
3410 Format.Ledger.Write.amount
3412 { Amount.quantity = Decimal 7 1234567890123456789
3413 , Amount.style = Amount.Style.nil
3414 { Amount.Style.fractioning = Just '.'
3415 , Amount.Style.precision = 7
3416 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3420 "1,2,3,4,5,6,7,89,012.3456789")
3421 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
3422 ((Format.Ledger.Write.show
3423 Format.Ledger.Write.Style
3424 { Format.Ledger.Write.style_color=False
3425 , Format.Ledger.Write.style_align=True
3427 Format.Ledger.Write.amount
3429 { Amount.quantity = Decimal 12 1234567890123456789
3430 , Amount.style = Amount.Style.nil
3431 { Amount.Style.fractioning = Just '.'
3432 , Amount.Style.precision = 12
3433 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3437 "1234567.890,12,3,4,5,6,7,8,9")
3439 , "amount_length" ~: TestList
3441 ((Format.Ledger.Write.amount_length
3446 ((Format.Ledger.Write.amount_length
3448 { Amount.style = Amount.Style.nil
3449 { Amount.Style.precision = 2 }
3454 ((Format.Ledger.Write.amount_length
3456 { Amount.quantity = Decimal 0 123
3461 ((Format.Ledger.Write.amount_length
3463 { Amount.quantity = Decimal 0 (- 123)
3467 , "12.3 @ prec=0" ~:
3468 ((Format.Ledger.Write.amount_length
3470 { Amount.quantity = Decimal 1 123
3471 , Amount.style = Amount.Style.nil
3472 { Amount.Style.fractioning = Just '.'
3477 , "12.5 @ prec=0" ~:
3478 ((Format.Ledger.Write.amount_length
3480 { Amount.quantity = Decimal 1 125
3481 , Amount.style = Amount.Style.nil
3482 { Amount.Style.fractioning = Just '.'
3487 , "12.3 @ prec=1" ~:
3488 ((Format.Ledger.Write.amount_length
3490 { Amount.quantity = Decimal 1 123
3491 , Amount.style = Amount.Style.nil
3492 { Amount.Style.fractioning = Just '.'
3493 , Amount.Style.precision = 1
3498 , "1,234.56 @ prec=2" ~:
3499 ((Format.Ledger.Write.amount_length
3501 { Amount.quantity = Decimal 2 123456
3502 , Amount.style = Amount.Style.nil
3503 { Amount.Style.fractioning = Just '.'
3504 , Amount.Style.precision = 2
3505 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
3510 , "123,456,789,01,2.3456789 @ prec=7" ~:
3511 ((Format.Ledger.Write.amount_length
3513 { Amount.quantity = Decimal 7 1234567890123456789
3514 , Amount.style = Amount.Style.nil
3515 { Amount.Style.fractioning = Just '.'
3516 , Amount.Style.precision = 7
3517 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3522 , "1234567.8,90,123,456,789 @ prec=12" ~:
3523 ((Format.Ledger.Write.amount_length
3525 { Amount.quantity = Decimal 12 1234567890123456789
3526 , Amount.style = Amount.Style.nil
3527 { Amount.Style.fractioning = Just '.'
3528 , Amount.Style.precision = 12
3529 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3534 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
3535 ((Format.Ledger.Write.amount_length
3537 { Amount.quantity = Decimal 7 1234567890123456789
3538 , Amount.style = Amount.Style.nil
3539 { Amount.Style.fractioning = Just '.'
3540 , Amount.Style.precision = 7
3541 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3546 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
3547 ((Format.Ledger.Write.amount_length
3549 { Amount.quantity = Decimal 12 1234567890123456789
3550 , Amount.style = Amount.Style.nil
3551 { Amount.Style.fractioning = Just '.'
3552 , Amount.Style.precision = 12
3553 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3558 , "1000000.000,00,0,0,0,0,0,0,0 @ prec=12" ~:
3559 ((Format.Ledger.Write.amount_length
3561 { Amount.quantity = Decimal 12 1000000000000000000
3562 , Amount.style = Amount.Style.nil
3563 { Amount.Style.fractioning = Just '.'
3564 , Amount.Style.precision = 12
3565 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3571 ((Format.Ledger.Write.amount_length $
3573 { Amount.quantity = Decimal 0 999
3574 , Amount.style = Amount.Style.nil
3575 { Amount.Style.precision = 0
3580 , "1000 @ prec=0" ~:
3581 ((Format.Ledger.Write.amount_length $
3583 { Amount.quantity = Decimal 0 1000
3584 , Amount.style = Amount.Style.nil
3585 { Amount.Style.precision = 0
3590 , "10,00€ @ prec=2" ~:
3591 ((Format.Ledger.Write.amount_length $ Amount.eur 10)
3595 , "date" ~: TestList
3597 ((Format.Ledger.Write.show
3598 Format.Ledger.Write.Style
3599 { Format.Ledger.Write.style_color=False
3600 , Format.Ledger.Write.style_align=True
3602 Format.Ledger.Write.date
3606 , "2000/01/01 12:34:51 CET" ~:
3607 (Format.Ledger.Write.show
3608 Format.Ledger.Write.Style
3609 { Format.Ledger.Write.style_color=False
3610 , Format.Ledger.Write.style_align=True
3612 Format.Ledger.Write.date $
3615 (Time.fromGregorian 2000 01 01)
3616 (Time.TimeOfDay 12 34 51))
3617 (Time.TimeZone 60 False "CET"))
3619 "2000/01/01 12:34:51 CET"
3620 , "2000/01/01 12:34:51 +0100" ~:
3621 (Format.Ledger.Write.show
3622 Format.Ledger.Write.Style
3623 { Format.Ledger.Write.style_color=False
3624 , Format.Ledger.Write.style_align=True
3626 Format.Ledger.Write.date $
3629 (Time.fromGregorian 2000 01 01)
3630 (Time.TimeOfDay 12 34 51))
3631 (Time.TimeZone 60 False ""))
3633 "2000/01/01 12:34:51 +0100"
3634 , "2000/01/01 01:02:03" ~:
3635 (Format.Ledger.Write.show
3636 Format.Ledger.Write.Style
3637 { Format.Ledger.Write.style_color=False
3638 , Format.Ledger.Write.style_align=True
3640 Format.Ledger.Write.date $
3643 (Time.fromGregorian 2000 01 01)
3644 (Time.TimeOfDay 1 2 3))
3647 "2000/01/01 01:02:03"
3649 (Format.Ledger.Write.show
3650 Format.Ledger.Write.Style
3651 { Format.Ledger.Write.style_color=False
3652 , Format.Ledger.Write.style_align=True
3654 Format.Ledger.Write.date $
3657 (Time.fromGregorian 0 01 01)
3658 (Time.TimeOfDay 1 2 0))
3663 (Format.Ledger.Write.show
3664 Format.Ledger.Write.Style
3665 { Format.Ledger.Write.style_color=False
3666 , Format.Ledger.Write.style_align=True
3668 Format.Ledger.Write.date $
3671 (Time.fromGregorian 0 01 01)
3672 (Time.TimeOfDay 1 0 0))
3677 (Format.Ledger.Write.show
3678 Format.Ledger.Write.Style
3679 { Format.Ledger.Write.style_color=False
3680 , Format.Ledger.Write.style_align=True
3682 Format.Ledger.Write.date $
3685 (Time.fromGregorian 0 01 01)
3686 (Time.TimeOfDay 0 1 0))
3691 (Format.Ledger.Write.show
3692 Format.Ledger.Write.Style
3693 { Format.Ledger.Write.style_color=False
3694 , Format.Ledger.Write.style_align=True
3696 Format.Ledger.Write.date $
3699 (Time.fromGregorian 0 01 01)
3700 (Time.TimeOfDay 0 0 0))
3705 , "transaction" ~: TestList
3707 ((Format.Ledger.Write.show
3708 Format.Ledger.Write.Style
3709 { Format.Ledger.Write.style_color=False
3710 , Format.Ledger.Write.style_align=True
3712 Format.Ledger.Write.transaction
3713 Format.Ledger.transaction)
3716 , "2000/01/01 some description\\n\\ta:b:c\\n\\t ; first comment\\n\\t ; second comment\\n\\t ; third comment\\n\\tA:B:C $1" ~:
3717 ((Format.Ledger.Write.show
3718 Format.Ledger.Write.Style
3719 { Format.Ledger.Write.style_color=False
3720 , Format.Ledger.Write.style_align=True
3722 Format.Ledger.Write.transaction $
3723 Format.Ledger.transaction
3724 { Format.Ledger.transaction_dates=
3727 (Time.fromGregorian 2000 01 01)
3728 (Time.TimeOfDay 0 0 0))
3731 , Format.Ledger.transaction_description="some description"
3732 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3733 [ (Format.Ledger.posting ("A":|["B", "C"]))
3734 { Format.Ledger.posting_amounts = Data.Map.fromList
3736 { Amount.quantity = 1
3737 , Amount.style = Amount.Style.nil
3738 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3739 , Amount.Style.unit_spaced = Just False
3745 , (Format.Ledger.posting ("a":|["b", "c"]))
3746 { Format.Ledger.posting_comments = ["first comment","second comment","third comment"]
3751 "2000/01/01 some description\n\ta:b:c\n\t ; first comment\n\t ; second comment\n\t ; third comment\n\tA:B:C $1")
3752 , "2000/01/01 some description\\n\\tA:B:C $1\\n\\tAA:BB:CC $123" ~:
3753 ((Format.Ledger.Write.show
3754 Format.Ledger.Write.Style
3755 { Format.Ledger.Write.style_color=False
3756 , Format.Ledger.Write.style_align=True
3758 Format.Ledger.Write.transaction $
3759 Format.Ledger.transaction
3760 { Format.Ledger.transaction_dates=
3763 (Time.fromGregorian 2000 01 01)
3764 (Time.TimeOfDay 0 0 0))
3767 , Format.Ledger.transaction_description="some description"
3768 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3769 [ (Format.Ledger.posting ("A":|["B", "C"]))
3770 { Format.Ledger.posting_amounts = Data.Map.fromList
3772 { Amount.quantity = 1
3773 , Amount.style = Amount.Style.nil
3774 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3775 , Amount.Style.unit_spaced = Just False
3781 , (Format.Ledger.posting ("AA":|["BB", "CC"]))
3782 { Format.Ledger.posting_amounts = Data.Map.fromList
3784 { Amount.quantity = 123
3785 , Amount.style = Amount.Style.nil
3786 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3787 , Amount.Style.unit_spaced = Just False
3796 "2000/01/01 some description\n\tA:B:C $1\n\tAA:BB:CC $123")