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, space, spaces, 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.Date.Read as Date.Read
31 import qualified Hcompta.Model.Filter as Filter
32 import qualified Hcompta.Model.Filter.Read as Filter.Read
33 import qualified Hcompta.Calc.Balance as Calc.Balance
34 import qualified Hcompta.Format.Ledger as Format.Ledger
35 import qualified Hcompta.Format.Ledger.Read as Format.Ledger.Read
36 import qualified Hcompta.Format.Ledger.Write as Format.Ledger.Write
37 import qualified Hcompta.Lib.TreeMap as Lib.TreeMap
38 import qualified Hcompta.Lib.Parsec as P
39 import qualified Hcompta.Lib.Foldable as Lib.Foldable
42 main = defaultMain $ hUnitTestToTests test_Hcompta
44 (~?) :: String -> Bool -> Test
45 (~?) s b = s ~: (b ~?= True)
51 [ "TreeMap" ~: TestList
52 [ "insert" ~: TestList
54 (Lib.TreeMap.insert const ((0::Int):|[]) () Lib.TreeMap.empty)
56 (Lib.TreeMap.TreeMap $
58 [ ((0::Int), Lib.TreeMap.leaf ())
61 (Lib.TreeMap.insert const ((0::Int):|1:[]) () Lib.TreeMap.empty)
63 (Lib.TreeMap.TreeMap $
65 [ ((0::Int), Lib.TreeMap.Node
66 { Lib.TreeMap.node_value = Nothing
67 , Lib.TreeMap.node_size = 1
68 , Lib.TreeMap.node_descendants =
69 Lib.TreeMap.singleton ((1::Int):|[]) ()
76 , "map_by_depth_first" ~: TestList
79 , "flatten" ~: TestList
80 [ "[0, 0/1, 0/1/2]" ~:
81 (Lib.TreeMap.flatten id $
82 Lib.TreeMap.from_List const
83 [ (((0::Integer):|[]), ())
94 , "[1, 1/2, 1/22, 1/2/3, 1/2/33, 11, 11/2, 11/2/3, 11/2/33]" ~:
95 (Lib.TreeMap.flatten id $
96 Lib.TreeMap.from_List const
105 , ((11:|2:33:[]), ())
110 [ (((1::Integer):|[]), ())
118 , ((11:|2:33:[]), ())
122 , "Foldable" ~: TestList
123 [ "accumLeftsAndFoldrRights" ~: TestList
125 (Lib.Foldable.accumLeftsAndFoldrRights (++) [""] $
128 (([(0::Integer)], [(""::String)]))
130 ((take 1 *** take 0) $
131 Lib.Foldable.accumLeftsAndFoldrRights (++) [""] $
132 ( repeat (Left [0]) ))
134 ([(0::Integer)], ([]::[String]))
135 , "Right:Left:Right:Left" ~:
136 (Lib.Foldable.accumLeftsAndFoldrRights (++) ["0"] $
137 ( Right ["2"]:Left [1]:Right ["1"]:Left [0]:[] ))
139 (([1, 0]::[Integer]), (["2", "1", "0"]::[String]))
140 , "Right:Left:Right:repeat Left" ~:
141 ((take 1 *** take 2) $
142 Lib.Foldable.accumLeftsAndFoldrRights (++) ["0"] $
143 ( Right ["2"]:Left [1]:Right ["1"]:repeat (Left [0]) ))
145 (([1]::[Integer]), (["2", "1"]::[String]))
149 , "Model" ~: TestList
150 [ "Account" ~: TestList
151 [ "foldr" ~: TestList
153 (reverse $ Account.foldr ("A":|[]) (:) []) ~?= ["A":|[]]
155 (reverse $ Account.foldr ("A":|["B"]) (:) []) ~?= ["A":|[], "A":|["B"]]
157 (reverse $ Account.foldr ("A":|["B", "C"]) (:) []) ~?= ["A":|[], "A":|["B"], "A":|["B", "C"]]
159 , "ascending" ~: TestList
161 Account.ascending ("A":|[]) ~?= Nothing
163 Account.ascending ("A":|["B"]) ~?= Just ("A":|[])
165 Account.ascending ("A":|["B", "C"]) ~?= Just ("A":|["B"])
168 , "Amount" ~: TestList
173 { Amount.quantity = Decimal 0 1
174 , Amount.style = Amount.Style.nil
175 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
180 { Amount.quantity = Decimal 0 1
181 , Amount.style = Amount.Style.nil
182 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
188 { Amount.quantity = Decimal 0 2
189 , Amount.style = Amount.Style.nil
190 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
195 , "from_List" ~: TestList
196 [ "from_List [$1, 1$] = $2" ~:
199 { Amount.quantity = Decimal 0 1
200 , Amount.style = Amount.Style.nil
201 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
206 { Amount.quantity = Decimal 0 1
207 , Amount.style = Amount.Style.nil
208 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
216 { Amount.quantity = Decimal 0 2
217 , Amount.style = Amount.Style.nil
218 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
225 , "Filter" ~: TestList
227 [ "Test_Account" ~: TestList
230 [ Filter.Test_Account_Section_Text
231 (Filter.Test_Text_Exact "A")
236 [ Filter.Test_Account_Section_Any
241 [ Filter.Test_Account_Section_Many
246 [ Filter.Test_Account_Section_Many
247 , Filter.Test_Account_Section_Text
248 (Filter.Test_Text_Exact "A")
253 [ Filter.Test_Account_Section_Text
254 (Filter.Test_Text_Exact "A")
255 , Filter.Test_Account_Section_Many
260 [ Filter.Test_Account_Section_Text
261 (Filter.Test_Text_Exact "A")
262 , Filter.Test_Account_Section_Many
264 (("A":|"B":[]::Account))
267 [ Filter.Test_Account_Section_Text
268 (Filter.Test_Text_Exact "A")
269 , Filter.Test_Account_Section_Text
270 (Filter.Test_Text_Exact "B")
272 (("A":|"B":[]::Account))
275 [ Filter.Test_Account_Section_Text
276 (Filter.Test_Text_Exact "A")
277 , Filter.Test_Account_Section_Many
278 , Filter.Test_Account_Section_Text
279 (Filter.Test_Text_Exact "B")
281 (("A":|"B":[]::Account))
284 [ Filter.Test_Account_Section_Many
285 , Filter.Test_Account_Section_Text
286 (Filter.Test_Text_Exact "B")
287 , Filter.Test_Account_Section_Many
289 (("A":|"B":"C":[]::Account))
292 [ Filter.Test_Account_Section_Many
293 , Filter.Test_Account_Section_Text
294 (Filter.Test_Text_Exact "C")
296 (("A":|"B":"C":[]::Account))
298 , "Test_Bool" ~: TestList
301 (Filter.Any::Filter.Test_Bool Filter.Test_Account)
306 [ "test_account_section" ~: TestList
308 (Data.Either.rights $
310 (Filter.Read.test_account <* P.eof)
313 [ [Filter.Test_Account_Section_Any]
316 (Data.Either.rights $
318 (Filter.Read.test_account <* P.eof)
321 [ [Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")]
324 (Data.Either.rights $
326 (Filter.Read.test_account <* P.eof)
329 [ [Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "AA")]
332 (Data.Either.rights $
334 (Filter.Read.test_account <* P.eof)
335 () "" ("::A"::Text)])
337 [ [ Filter.Test_Account_Section_Many
338 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
342 (Data.Either.rights $
344 (Filter.Read.test_account <* P.eof)
347 [ [ Filter.Test_Account_Section_Many
348 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
352 (Data.Either.rights $
354 (Filter.Read.test_account <* P.eof)
357 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
358 , Filter.Test_Account_Section_Many
362 (Data.Either.rights $
364 (Filter.Read.test_account <* P.eof)
365 () "" ("A::"::Text)])
367 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
368 , Filter.Test_Account_Section_Many
372 (Data.Either.rights $
374 (Filter.Read.test_account <* P.eof)
375 () "" ("A:B"::Text)])
377 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
378 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B") ]
381 (Data.Either.rights $
383 (Filter.Read.test_account <* P.eof)
384 () "" ("A::B"::Text)])
386 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
387 , Filter.Test_Account_Section_Many
388 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B")
392 (Data.Either.rights $
394 (Filter.Read.test_account <* P.eof)
395 () "" ("A:::B"::Text)])
397 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
398 , Filter.Test_Account_Section_Many
399 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B")
403 (Data.Either.rights $
405 (Filter.Read.test_account <* P.char ' ' <* P.eof)
406 () "" ("A: "::Text)])
408 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
409 , Filter.Test_Account_Section_Many
413 , "test_bool" ~: TestList
415 (Data.Either.rights $
417 (Filter.Read.test_bool
418 [ P.char 'E' >> return (return True) ]
420 () "" ("( E )"::Text)])
422 [ Filter.And (Filter.Bool True) Filter.Any
425 (Data.Either.rights $
427 (Filter.Read.test_bool
428 [ P.char 'E' >> return (return True) ]
430 () "" ("( ( E ) )"::Text)])
432 [ Filter.And (Filter.And (Filter.Bool True) Filter.Any) Filter.Any
435 (Data.Either.rights $
437 (Filter.Read.test_bool
438 [ P.char 'E' >> return (return True) ]
440 () "" ("( E ) & ( E )"::Text)])
443 (Filter.And (Filter.Bool True) Filter.Any)
444 (Filter.And (Filter.Bool True) Filter.Any)
447 (Data.Either.rights $
449 (Filter.Read.test_bool
450 [ P.char 'E' >> return (return True) ]
452 () "" ("( E ) + ( E )"::Text)])
455 (Filter.And (Filter.Bool True) Filter.Any)
456 (Filter.And (Filter.Bool True) Filter.Any)
459 (Data.Either.rights $
461 (Filter.Read.test_bool
462 [ P.char 'E' >> return (return True) ]
464 () "" ("( E ) - ( E )"::Text)])
467 (Filter.And (Filter.Bool True) Filter.Any)
468 (Filter.Not (Filter.And (Filter.Bool True) Filter.Any))
471 (Data.Either.rights $
473 (Filter.Read.test_bool
474 [ P.char 'E' >> return (return True) ]
476 () "" ("(- E )"::Text)])
478 [ Filter.And (Filter.Not (Filter.Bool True)) Filter.Any
485 [ "Balance" ~: TestList
486 [ "balance" ~: TestList
487 [ "[A+$1] = A+$1 & $+1" ~:
488 (Calc.Balance.balance
489 (Format.Ledger.posting ("A":|[]))
490 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
495 { Calc.Balance.balance_by_account =
496 Lib.TreeMap.from_List const $
497 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
498 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
499 , Calc.Balance.balance_by_unit =
501 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
502 [ Calc.Balance.Unit_Sum
503 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
504 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
509 , "[A+$1, A-$1] = {A+$0, $+0}" ~:
511 (flip Calc.Balance.balance)
513 [ (Format.Ledger.posting ("A":|[]))
514 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
516 , (Format.Ledger.posting ("A":|[]))
517 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ]
522 { Calc.Balance.balance_by_account =
523 Lib.TreeMap.from_List const $
525 , Data.Map.fromListWith const $
526 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance s, s))
527 [ Calc.Balance.Amount_Sum
528 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
529 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
530 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
534 , Calc.Balance.balance_by_unit =
536 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
537 [ Calc.Balance.Unit_Sum
538 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
539 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
540 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
541 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
543 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
548 , "[A+$1, A-€1] = {A+$1-€1, $+1 €-1}" ~:
550 (flip Calc.Balance.balance)
552 [ (Format.Ledger.posting ("A":|[]))
553 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
555 , (Format.Ledger.posting ("A":|[]))
556 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1 ]
561 { Calc.Balance.balance_by_account =
562 Lib.TreeMap.from_List const $
563 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
564 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ -1 ]) ]
565 , Calc.Balance.balance_by_unit =
567 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
568 [ Calc.Balance.Unit_Sum
569 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
570 { Calc.Balance.amount_sum_negative = Nothing
571 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
572 , Calc.Balance.amount_sum_balance = Amount.usd $ 1
574 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
577 , Calc.Balance.Unit_Sum
578 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
579 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -1
580 , Calc.Balance.amount_sum_positive = Nothing
581 , Calc.Balance.amount_sum_balance = Amount.eur $ -1
583 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
588 , "[A+$1, B-$1] = {A+$1 B-$1, $+0}" ~:
590 (flip Calc.Balance.balance)
592 [ (Format.Ledger.posting ("A":|[]))
593 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
595 , (Format.Ledger.posting ("B":|[]))
596 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ]
601 { Calc.Balance.balance_by_account =
602 Lib.TreeMap.from_List const $
603 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
604 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
605 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
607 , Calc.Balance.balance_by_unit =
609 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
610 [ Calc.Balance.Unit_Sum
611 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
612 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
613 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
614 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
616 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
623 (flip Calc.Balance.balance)
625 [ (Format.Ledger.posting ("A":|[]))
626 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
628 , (Format.Ledger.posting ("B":|[]))
629 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
634 { Calc.Balance.balance_by_account =
635 Lib.TreeMap.from_List const $
636 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
637 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
638 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ])
640 , Calc.Balance.balance_by_unit =
642 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
643 [ Calc.Balance.Unit_Sum
644 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
645 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
650 , "[A+$1+€2, A-$1-€2] = {A+$0+€0, $+0 €+0}" ~:
652 (flip Calc.Balance.balance)
654 [ (Format.Ledger.posting ("A":|[]))
655 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2 ]
657 , (Format.Ledger.posting ("A":|[]))
658 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2 ]
663 { Calc.Balance.balance_by_account =
664 Lib.TreeMap.from_List const $
666 , Data.Map.fromListWith const $
667 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance s, s))
668 [ Calc.Balance.Amount_Sum
669 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
670 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
671 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
673 , Calc.Balance.Amount_Sum
674 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -2
675 , Calc.Balance.amount_sum_positive = Just $ Amount.eur $ 2
676 , Calc.Balance.amount_sum_balance = Amount.eur $ 0
681 , Calc.Balance.balance_by_unit =
683 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
684 [ Calc.Balance.Unit_Sum
685 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
686 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
687 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
688 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
690 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
693 , Calc.Balance.Unit_Sum
694 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
695 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -2
696 , Calc.Balance.amount_sum_positive = Just $ Amount.eur $ 2
697 , Calc.Balance.amount_sum_balance = Amount.eur $ 0
699 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
704 , "[A+$1+€2+£3, B-$1-2€-£3] = {A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~:
706 (flip Calc.Balance.balance)
708 [ (Format.Ledger.posting ("A":|[]))
709 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ]
711 , (Format.Ledger.posting ("B":|[]))
712 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ]
717 { Calc.Balance.balance_by_account =
718 Lib.TreeMap.from_List const $
719 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
720 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
721 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
723 , Calc.Balance.balance_by_unit =
725 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
726 [ Calc.Balance.Unit_Sum
727 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
728 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
729 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
730 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
732 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
735 , Calc.Balance.Unit_Sum
736 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
737 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -2
738 , Calc.Balance.amount_sum_positive = Just $ Amount.eur $ 2
739 , Calc.Balance.amount_sum_balance = Amount.eur $ 0
741 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
744 , Calc.Balance.Unit_Sum
745 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
746 { Calc.Balance.amount_sum_negative = Just $ Amount.gbp $ -3
747 , Calc.Balance.amount_sum_positive = Just $ Amount.gbp $ 3
748 , Calc.Balance.amount_sum_balance = Amount.gbp $ 0
750 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
756 , "union" ~: TestList
758 Calc.Balance.union Calc.Balance.nil Calc.Balance.nil
760 (Calc.Balance.nil::Calc.Balance.Balance Amount)
761 , "{A+$1, $+1} {A+$1, $+1} = {A+$2, $+2}" ~:
763 (Calc.Balance.Balance
764 { Calc.Balance.balance_by_account =
765 Lib.TreeMap.from_List const $
766 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
767 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
768 , Calc.Balance.balance_by_unit =
770 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
771 [ Calc.Balance.Unit_Sum
772 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
773 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
778 (Calc.Balance.Balance
779 { Calc.Balance.balance_by_account =
780 Lib.TreeMap.from_List const $
781 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
782 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
783 , Calc.Balance.balance_by_unit =
785 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
786 [ Calc.Balance.Unit_Sum
787 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
788 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
795 { Calc.Balance.balance_by_account =
796 Lib.TreeMap.from_List const $
797 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
798 [ ("A":|[], Amount.from_List [ Amount.usd $ 2 ]) ]
799 , Calc.Balance.balance_by_unit =
801 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
802 [ Calc.Balance.Unit_Sum
803 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
804 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
809 , "{A+$1, $+1} {B+$1, $+1} = {A+$1 B+$1, $+2}" ~:
811 (Calc.Balance.Balance
812 { Calc.Balance.balance_by_account =
813 Lib.TreeMap.from_List const $
814 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
815 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
816 , Calc.Balance.balance_by_unit =
818 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
819 [ Calc.Balance.Unit_Sum
820 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
821 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
826 (Calc.Balance.Balance
827 { Calc.Balance.balance_by_account =
828 Lib.TreeMap.from_List const $
829 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
830 [ ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
831 , Calc.Balance.balance_by_unit =
833 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
834 [ Calc.Balance.Unit_Sum
835 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
836 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
843 { Calc.Balance.balance_by_account =
844 Lib.TreeMap.from_List const $
845 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
846 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
847 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
848 , Calc.Balance.balance_by_unit =
850 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
851 [ Calc.Balance.Unit_Sum
852 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
853 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
858 , "{A+$1, $+1} {B+€1, €+1} = {A+$1 B+€1, $+1 €+1}" ~:
860 (Calc.Balance.Balance
861 { Calc.Balance.balance_by_account =
862 Lib.TreeMap.from_List const $
863 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
864 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
865 , Calc.Balance.balance_by_unit =
867 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
868 [ Calc.Balance.Unit_Sum
869 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
870 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
875 (Calc.Balance.Balance
876 { Calc.Balance.balance_by_account =
877 Lib.TreeMap.from_List const $
878 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
879 [ ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
880 , Calc.Balance.balance_by_unit =
882 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
883 [ Calc.Balance.Unit_Sum
884 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
885 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
892 { Calc.Balance.balance_by_account =
893 Lib.TreeMap.from_List const $
894 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
895 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
896 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
897 , Calc.Balance.balance_by_unit =
899 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
900 [ Calc.Balance.Unit_Sum
901 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
902 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
905 , Calc.Balance.Unit_Sum
906 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
907 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
913 , "expanded" ~: TestList
914 [ "nil_By_Account" ~:
915 Calc.Balance.expanded
918 (Lib.TreeMap.empty::Calc.Balance.Expanded Amount)
920 Calc.Balance.expanded
921 (Lib.TreeMap.from_List const $
922 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
923 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ])
925 (Lib.TreeMap.from_List const $
926 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
927 { Calc.Balance.inclusive =
928 Data.Map.map Calc.Balance.amount_sum $
929 Amount.from_List [ Amount.usd $ 1 ]
930 , Calc.Balance.exclusive =
931 Data.Map.map Calc.Balance.amount_sum $
932 Amount.from_List [ Amount.usd $ 1 ]
935 , "A/A+$1 = A+$1 A/A+$1" ~:
936 Calc.Balance.expanded
937 (Lib.TreeMap.from_List const $
938 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
939 [ ("A":|["A"], Amount.from_List [ Amount.usd $ 1 ]) ])
941 (Lib.TreeMap.from_List const
942 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
943 { Calc.Balance.inclusive =
944 Data.Map.map Calc.Balance.amount_sum $
945 Amount.from_List [ Amount.usd $ 1 ]
946 , Calc.Balance.exclusive =
947 Data.Map.map Calc.Balance.amount_sum $
950 , ("A":|["A"], Calc.Balance.Account_Sum_Expanded
951 { Calc.Balance.inclusive =
952 Data.Map.map Calc.Balance.amount_sum $
953 Amount.from_List [ Amount.usd $ 1 ]
954 , Calc.Balance.exclusive =
955 Data.Map.map Calc.Balance.amount_sum $
956 Amount.from_List [ Amount.usd $ 1 ]
959 , "A/B+$1 = A+$1 A/B+$1" ~:
960 Calc.Balance.expanded
961 (Lib.TreeMap.from_List const $
962 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
963 [ ("A":|["B"], 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 $ 1 ]
970 , Calc.Balance.exclusive =
971 Data.Map.map Calc.Balance.amount_sum $
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 $ 1 ]
978 , Calc.Balance.exclusive =
979 Data.Map.map Calc.Balance.amount_sum $
980 Amount.from_List [ Amount.usd $ 1 ]
983 , "A/B/C+$1 = A+$1 A/B+$1 A/B/C+$1" ~:
984 Calc.Balance.expanded
985 (Lib.TreeMap.from_List const $
986 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
987 [ ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ]) ])
989 (Lib.TreeMap.from_List const $
990 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
991 { Calc.Balance.inclusive =
992 Data.Map.map Calc.Balance.amount_sum $
993 Amount.from_List [ Amount.usd $ 1 ]
994 , Calc.Balance.exclusive =
995 Data.Map.map Calc.Balance.amount_sum $
998 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
999 { Calc.Balance.inclusive =
1000 Data.Map.map Calc.Balance.amount_sum $
1001 Amount.from_List [ Amount.usd $ 1 ]
1002 , Calc.Balance.exclusive =
1003 Data.Map.map Calc.Balance.amount_sum $
1006 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
1007 { Calc.Balance.inclusive =
1008 Data.Map.map Calc.Balance.amount_sum $
1009 Amount.from_List [ Amount.usd $ 1 ]
1010 , Calc.Balance.exclusive =
1011 Data.Map.map Calc.Balance.amount_sum $
1012 Amount.from_List [ Amount.usd $ 1 ]
1015 , "A+$1 A/B+$1 = A+$2 A/B+$1" ~:
1016 Calc.Balance.expanded
1017 (Lib.TreeMap.from_List const $
1018 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1019 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1020 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
1023 (Lib.TreeMap.from_List const
1024 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
1025 { Calc.Balance.inclusive =
1026 Data.Map.map Calc.Balance.amount_sum $
1027 Amount.from_List [ Amount.usd $ 2 ]
1028 , Calc.Balance.exclusive =
1029 Data.Map.map Calc.Balance.amount_sum $
1030 Amount.from_List [ Amount.usd $ 1 ]
1032 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
1033 { Calc.Balance.inclusive =
1034 Data.Map.map Calc.Balance.amount_sum $
1035 Amount.from_List [ Amount.usd $ 1 ]
1036 , Calc.Balance.exclusive =
1037 Data.Map.map Calc.Balance.amount_sum $
1038 Amount.from_List [ Amount.usd $ 1 ]
1041 , "A+$1 A/B+$1 A/B/C+$1 = A+$3 A/B+$2 A/B/C+$1" ~:
1042 Calc.Balance.expanded
1043 (Lib.TreeMap.from_List const $
1044 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1045 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1046 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
1047 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
1050 (Lib.TreeMap.from_List const
1051 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
1052 { Calc.Balance.inclusive =
1053 Data.Map.map Calc.Balance.amount_sum $
1054 Amount.from_List [ Amount.usd $ 3 ]
1055 , Calc.Balance.exclusive =
1056 Data.Map.map Calc.Balance.amount_sum $
1057 Amount.from_List [ Amount.usd $ 1 ]
1059 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
1060 { Calc.Balance.inclusive =
1061 Data.Map.map Calc.Balance.amount_sum $
1062 Amount.from_List [ Amount.usd $ 2 ]
1063 , Calc.Balance.exclusive =
1064 Data.Map.map Calc.Balance.amount_sum $
1065 Amount.from_List [ Amount.usd $ 1 ]
1067 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
1068 { Calc.Balance.inclusive =
1069 Data.Map.map Calc.Balance.amount_sum $
1070 Amount.from_List [ Amount.usd $ 1 ]
1071 , Calc.Balance.exclusive =
1072 Data.Map.map Calc.Balance.amount_sum $
1073 Amount.from_List [ Amount.usd $ 1 ]
1076 , "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" ~:
1077 Calc.Balance.expanded
1078 (Lib.TreeMap.from_List const $
1079 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1080 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1081 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
1082 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
1083 , ("A":|["B", "C", "D"], Amount.from_List [ Amount.usd $ 1 ])
1086 (Lib.TreeMap.from_List const
1087 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
1088 { Calc.Balance.inclusive =
1089 Data.Map.map Calc.Balance.amount_sum $
1090 Amount.from_List [ Amount.usd $ 4 ]
1091 , Calc.Balance.exclusive =
1092 Data.Map.map Calc.Balance.amount_sum $
1093 Amount.from_List [ Amount.usd $ 1 ]
1095 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
1096 { Calc.Balance.inclusive =
1097 Data.Map.map Calc.Balance.amount_sum $
1098 Amount.from_List [ Amount.usd $ 3 ]
1099 , Calc.Balance.exclusive =
1100 Data.Map.map Calc.Balance.amount_sum $
1101 Amount.from_List [ Amount.usd $ 1 ]
1103 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
1104 { Calc.Balance.inclusive =
1105 Data.Map.map Calc.Balance.amount_sum $
1106 Amount.from_List [ Amount.usd $ 2 ]
1107 , Calc.Balance.exclusive =
1108 Data.Map.map Calc.Balance.amount_sum $
1109 Amount.from_List [ Amount.usd $ 1 ]
1111 , ("A":|["B", "C", "D"], Calc.Balance.Account_Sum_Expanded
1112 { Calc.Balance.inclusive =
1113 Data.Map.map Calc.Balance.amount_sum $
1114 Amount.from_List [ Amount.usd $ 1 ]
1115 , Calc.Balance.exclusive =
1116 Data.Map.map Calc.Balance.amount_sum $
1117 Amount.from_List [ Amount.usd $ 1 ]
1120 , "A+$1 A/B+$1 A/BB+$1 AA/B+$1 = A+$3 A/B+$1 A/BB+$1 AA+$1 AA/B+$1" ~:
1121 Calc.Balance.expanded
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 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
1126 , ("A":|["BB"], Amount.from_List [ Amount.usd $ 1 ])
1127 , ("AA":|["B"], Amount.from_List [ Amount.usd $ 1 ])
1130 (Lib.TreeMap.from_List const
1131 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
1132 { Calc.Balance.inclusive =
1133 Data.Map.map Calc.Balance.amount_sum $
1134 Amount.from_List [ Amount.usd $ 3 ]
1135 , Calc.Balance.exclusive =
1136 Data.Map.map Calc.Balance.amount_sum $
1137 Amount.from_List [ Amount.usd $ 1 ]
1139 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
1140 { Calc.Balance.inclusive =
1141 Data.Map.map Calc.Balance.amount_sum $
1142 Amount.from_List [ Amount.usd $ 1 ]
1143 , Calc.Balance.exclusive =
1144 Data.Map.map Calc.Balance.amount_sum $
1145 Amount.from_List [ Amount.usd $ 1 ]
1147 , ("A":|["BB"], Calc.Balance.Account_Sum_Expanded
1148 { Calc.Balance.inclusive =
1149 Data.Map.map Calc.Balance.amount_sum $
1150 Amount.from_List [ Amount.usd $ 1 ]
1151 , Calc.Balance.exclusive =
1152 Data.Map.map Calc.Balance.amount_sum $
1153 Amount.from_List [ Amount.usd $ 1 ]
1155 , ("AA":|[], Calc.Balance.Account_Sum_Expanded
1156 { Calc.Balance.inclusive =
1157 Data.Map.map Calc.Balance.amount_sum $
1158 Amount.from_List [ Amount.usd $ 1 ]
1159 , Calc.Balance.exclusive =
1160 Data.Map.map Calc.Balance.amount_sum $
1163 , ("AA":|["B"], Calc.Balance.Account_Sum_Expanded
1164 { Calc.Balance.inclusive =
1165 Data.Map.map Calc.Balance.amount_sum $
1166 Amount.from_List [ Amount.usd $ 1 ]
1167 , Calc.Balance.exclusive =
1168 Data.Map.map Calc.Balance.amount_sum $
1169 Amount.from_List [ Amount.usd $ 1 ]
1173 , "deviation" ~: TestList
1175 (Calc.Balance.deviation $
1176 Calc.Balance.Balance
1177 { Calc.Balance.balance_by_account =
1178 Lib.TreeMap.from_List const $
1179 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1180 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1181 , ("B":|[], Amount.from_List [])
1183 , Calc.Balance.balance_by_unit =
1185 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1186 [ Calc.Balance.Unit_Sum
1187 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1188 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1194 (Calc.Balance.Deviation $
1196 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1197 [ Calc.Balance.Unit_Sum
1198 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1199 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1203 , "{A+$1 B+$1, $2}" ~:
1204 (Calc.Balance.deviation $
1205 Calc.Balance.Balance
1206 { Calc.Balance.balance_by_account =
1207 Lib.TreeMap.from_List const $
1208 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1209 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1210 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ])
1212 , Calc.Balance.balance_by_unit =
1214 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1215 [ Calc.Balance.Unit_Sum
1216 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
1217 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1225 (Calc.Balance.Deviation $
1227 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1228 [ Calc.Balance.Unit_Sum
1229 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
1230 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1236 , "is_equilibrium_inferrable" ~: TestList
1237 [ "nil" ~: TestCase $
1239 Calc.Balance.is_equilibrium_inferrable $
1240 Calc.Balance.deviation $
1241 (Calc.Balance.nil::Calc.Balance.Balance Amount.Amount)
1242 , "{A+$0, $+0}" ~: TestCase $
1244 Calc.Balance.is_equilibrium_inferrable $
1245 Calc.Balance.deviation $
1246 Calc.Balance.Balance
1247 { Calc.Balance.balance_by_account =
1248 Lib.TreeMap.from_List const $
1249 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1250 [ ("A":|[], Amount.from_List [ Amount.usd $ 0 ])
1252 , Calc.Balance.balance_by_unit =
1254 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1255 [ Calc.Balance.Unit_Sum
1256 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1257 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1262 , "{A+$1, $+1}" ~: TestCase $
1264 Calc.Balance.is_equilibrium_inferrable $
1265 Calc.Balance.deviation $
1266 Calc.Balance.Balance
1267 { Calc.Balance.balance_by_account =
1268 Lib.TreeMap.from_List const $
1269 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1270 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1272 , Calc.Balance.balance_by_unit =
1274 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1275 [ Calc.Balance.Unit_Sum
1276 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1277 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1282 , "{A+$0+€0, $0 €+0}" ~: TestCase $
1284 Calc.Balance.is_equilibrium_inferrable $
1285 Calc.Balance.deviation $
1286 Calc.Balance.Balance
1287 { Calc.Balance.balance_by_account =
1288 Lib.TreeMap.from_List const $
1289 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1290 [ ("A":|[], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
1292 , Calc.Balance.balance_by_unit =
1294 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1295 [ Calc.Balance.Unit_Sum
1296 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1297 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1300 , Calc.Balance.Unit_Sum
1301 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 0
1302 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1307 , "{A+$1, B-$1, $+0}" ~: TestCase $
1309 Calc.Balance.is_equilibrium_inferrable $
1310 Calc.Balance.deviation $
1311 Calc.Balance.Balance
1312 { Calc.Balance.balance_by_account =
1313 Lib.TreeMap.from_List const $
1314 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1315 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1316 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
1318 , Calc.Balance.balance_by_unit =
1320 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1321 [ Calc.Balance.Unit_Sum
1322 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1323 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1328 , "{A+$1 B, $+1}" ~: TestCase $
1330 Calc.Balance.is_equilibrium_inferrable $
1331 Calc.Balance.deviation $
1332 Calc.Balance.Balance
1333 { Calc.Balance.balance_by_account =
1334 Lib.TreeMap.from_List const $
1335 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1336 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1337 , ("B":|[], Amount.from_List [])
1339 , Calc.Balance.balance_by_unit =
1341 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1342 [ Calc.Balance.Unit_Sum
1343 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1344 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1349 , "{A+$1 B+€1, $+1 €+1}" ~: TestCase $
1351 Calc.Balance.is_equilibrium_inferrable $
1352 Calc.Balance.deviation $
1353 Calc.Balance.Balance
1354 { Calc.Balance.balance_by_account =
1355 Lib.TreeMap.from_List const $
1356 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1357 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1358 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ])
1360 , Calc.Balance.balance_by_unit =
1362 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1363 [ Calc.Balance.Unit_Sum
1364 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1365 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1368 , Calc.Balance.Unit_Sum
1369 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
1370 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1375 , "{A+$1 B-$1+€1, $+0 €+1}" ~: TestCase $
1377 Calc.Balance.is_equilibrium_inferrable $
1378 Calc.Balance.deviation $
1379 Calc.Balance.Balance
1380 { Calc.Balance.balance_by_account =
1381 Lib.TreeMap.from_List const $
1382 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1383 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1384 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ 1 ])
1386 , Calc.Balance.balance_by_unit =
1388 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1389 [ Calc.Balance.Unit_Sum
1390 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1391 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1394 , Calc.Balance.Unit_Sum
1395 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
1396 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1401 , "{A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~: TestCase $
1403 Calc.Balance.is_equilibrium_inferrable $
1404 Calc.Balance.deviation $
1405 Calc.Balance.Balance
1406 { Calc.Balance.balance_by_account =
1407 Lib.TreeMap.from_List const $
1408 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1409 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
1410 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
1412 , Calc.Balance.balance_by_unit =
1414 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1415 [ Calc.Balance.Unit_Sum
1416 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1417 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1420 , Calc.Balance.Unit_Sum
1421 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 0
1422 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1425 , Calc.Balance.Unit_Sum
1426 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.gbp $ 0
1427 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1433 , "infer_equilibrium" ~: TestList
1435 (snd $ Calc.Balance.infer_equilibrium $
1436 Format.Ledger.posting_by_Account
1437 [ (Format.Ledger.posting ("A":|[]))
1438 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1439 , (Format.Ledger.posting ("B":|[]))
1440 { Format.Ledger.posting_amounts=Amount.from_List [] }
1444 Format.Ledger.posting_by_Account
1445 [ (Format.Ledger.posting ("A":|[]))
1446 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1447 , (Format.Ledger.posting ("B":|[]))
1448 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ] }
1451 (snd $ Calc.Balance.infer_equilibrium $
1452 Format.Ledger.posting_by_Account
1453 [ (Format.Ledger.posting ("A":|[]))
1454 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1455 , (Format.Ledger.posting ("B":|[]))
1456 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1 ] }
1460 Format.Ledger.posting_by_Account
1461 [ (Format.Ledger.posting ("A":|[]))
1462 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 1] }
1463 , (Format.Ledger.posting ("B":|[]))
1464 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1, Amount.usd $ -1 ] }
1467 (snd $ Calc.Balance.infer_equilibrium $
1468 Format.Ledger.posting_by_Account
1469 [ (Format.Ledger.posting ("A":|[]))
1470 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1471 , (Format.Ledger.posting ("B":|[]))
1472 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1476 [ Calc.Balance.Unit_Sum
1477 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
1478 , Calc.Balance.unit_sum_accounts = Data.Map.fromList []}
1480 , "{A+$1 B-$1 B-1€}" ~:
1481 (snd $ Calc.Balance.infer_equilibrium $
1482 Format.Ledger.posting_by_Account
1483 [ (Format.Ledger.posting ("A":|[]))
1484 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1485 , (Format.Ledger.posting ("B":|[]))
1486 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -1 ] }
1490 Format.Ledger.posting_by_Account
1491 [ (Format.Ledger.posting ("A":|[]))
1492 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 1 ] }
1493 , (Format.Ledger.posting ("B":|[]))
1494 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -1 ] }
1499 , "Format" ~: TestList
1500 [ "Ledger" ~: TestList
1501 [ "Read" ~: TestList
1502 [ "account_name" ~: TestList
1504 (Data.Either.rights $
1506 (Format.Ledger.Read.account_name <* P.eof)
1511 (Data.Either.rights $
1513 (Format.Ledger.Read.account_name <* P.eof)
1518 (Data.Either.rights $
1520 (Format.Ledger.Read.account_name <* P.eof)
1521 () "" ("AA"::Text)])
1525 (Data.Either.rights $
1527 (Format.Ledger.Read.account_name <* P.eof)
1532 (Data.Either.rights $
1534 (Format.Ledger.Read.account_name <* P.eof)
1539 (Data.Either.rights $
1541 (Format.Ledger.Read.account_name <* P.eof)
1542 () "" ("A:"::Text)])
1546 (Data.Either.rights $
1548 (Format.Ledger.Read.account_name <* P.eof)
1549 () "" (":A"::Text)])
1553 (Data.Either.rights $
1555 (Format.Ledger.Read.account_name <* P.eof)
1556 () "" ("A "::Text)])
1560 (Data.Either.rights $
1562 (Format.Ledger.Read.account_name)
1563 () "" ("A "::Text)])
1567 (Data.Either.rights $
1569 (Format.Ledger.Read.account_name <* P.eof)
1570 () "" ("A A"::Text)])
1574 (Data.Either.rights $
1576 (Format.Ledger.Read.account_name <* P.eof)
1577 () "" ("A "::Text)])
1581 (Data.Either.rights $
1583 (Format.Ledger.Read.account_name <* P.eof)
1584 () "" ("A \n"::Text)])
1588 (Data.Either.rights $
1590 (Format.Ledger.Read.account_name <* P.eof)
1591 () "" ("(A)A"::Text)])
1595 (Data.Either.rights $
1597 (Format.Ledger.Read.account_name <* P.eof)
1598 () "" ("( )A"::Text)])
1602 (Data.Either.rights $
1604 (Format.Ledger.Read.account_name <* P.eof)
1605 () "" ("(A) A"::Text)])
1609 (Data.Either.rights $
1611 (Format.Ledger.Read.account_name <* P.eof)
1612 () "" ("[ ]A"::Text)])
1616 (Data.Either.rights $
1618 (Format.Ledger.Read.account_name <* P.eof)
1619 () "" ("(A) "::Text)])
1623 (Data.Either.rights $
1625 (Format.Ledger.Read.account_name <* P.eof)
1626 () "" ("(A)"::Text)])
1630 (Data.Either.rights $
1632 (Format.Ledger.Read.account_name <* P.eof)
1633 () "" ("A(A)"::Text)])
1637 (Data.Either.rights $
1639 (Format.Ledger.Read.account_name <* P.eof)
1640 () "" ("[A]A"::Text)])
1644 (Data.Either.rights $
1646 (Format.Ledger.Read.account_name <* P.eof)
1647 () "" ("[A] A"::Text)])
1651 (Data.Either.rights $
1653 (Format.Ledger.Read.account_name <* P.eof)
1654 () "" ("[A] "::Text)])
1658 (Data.Either.rights $
1660 (Format.Ledger.Read.account_name <* P.eof)
1661 () "" ("[A]"::Text)])
1665 , "account" ~: TestList
1667 (Data.Either.rights $
1669 (Format.Ledger.Read.account <* P.eof)
1674 (Data.Either.rights $
1676 (Format.Ledger.Read.account <* P.eof)
1681 (Data.Either.rights $
1683 (Format.Ledger.Read.account <* P.eof)
1684 () "" ("A:"::Text)])
1688 (Data.Either.rights $
1690 (Format.Ledger.Read.account <* P.eof)
1691 () "" (":A"::Text)])
1695 (Data.Either.rights $
1697 (Format.Ledger.Read.account <* P.eof)
1698 () "" ("A "::Text)])
1702 (Data.Either.rights $
1704 (Format.Ledger.Read.account <* P.eof)
1705 () "" (" A"::Text)])
1709 (Data.Either.rights $
1711 (Format.Ledger.Read.account <* P.eof)
1712 () "" ("A:B"::Text)])
1716 (Data.Either.rights $
1718 (Format.Ledger.Read.account <* P.eof)
1719 () "" ("A:B:C"::Text)])
1722 , "\"Aa:Bbb:Cccc\"" ~:
1723 (Data.Either.rights $
1725 (Format.Ledger.Read.account <* P.eof)
1726 () "" ("Aa:Bbb:Cccc"::Text)])
1728 ["Aa":|["Bbb", "Cccc"]]
1729 , "\"A a : B b b : C c c c\"" ~:
1730 (Data.Either.rights $
1732 (Format.Ledger.Read.account <* P.eof)
1733 () "" ("A a : B b b : C c c c"::Text)])
1735 ["A a ":|[" B b b ", " C c c c"]]
1737 (Data.Either.rights $
1739 (Format.Ledger.Read.account <* P.eof)
1740 () "" ("A: :C"::Text)])
1744 (Data.Either.rights $
1746 (Format.Ledger.Read.account <* P.eof)
1747 () "" ("A::C"::Text)])
1751 (Data.Either.rights $
1753 (Format.Ledger.Read.account <* P.eof)
1754 () "" ("A:B:(C)"::Text)])
1758 , "posting_type" ~: TestList
1760 Format.Ledger.Read.posting_type
1763 (Format.Ledger.Posting_Type_Regular, "A":|[])
1765 Format.Ledger.Read.posting_type
1768 (Format.Ledger.Posting_Type_Regular, "(":|[])
1770 Format.Ledger.Read.posting_type
1773 (Format.Ledger.Posting_Type_Regular, ")":|[])
1775 Format.Ledger.Read.posting_type
1778 (Format.Ledger.Posting_Type_Regular, "()":|[])
1780 Format.Ledger.Read.posting_type
1783 (Format.Ledger.Posting_Type_Regular, "( )":|[])
1785 Format.Ledger.Read.posting_type
1788 (Format.Ledger.Posting_Type_Virtual, "A":|[])
1790 Format.Ledger.Read.posting_type
1793 (Format.Ledger.Posting_Type_Virtual, "A":|["B", "C"])
1795 Format.Ledger.Read.posting_type
1798 (Format.Ledger.Posting_Type_Regular, "A":|["B", "C"])
1800 Format.Ledger.Read.posting_type
1803 (Format.Ledger.Posting_Type_Regular, "(A)":|["B", "C"])
1805 Format.Ledger.Read.posting_type
1808 (Format.Ledger.Posting_Type_Regular, "A":|["(B)", "C"])
1810 Format.Ledger.Read.posting_type
1813 (Format.Ledger.Posting_Type_Regular, "A":|["B", "(C)"])
1815 Format.Ledger.Read.posting_type
1818 (Format.Ledger.Posting_Type_Regular, "[":|[])
1820 Format.Ledger.Read.posting_type
1823 (Format.Ledger.Posting_Type_Regular, "]":|[])
1825 Format.Ledger.Read.posting_type
1828 (Format.Ledger.Posting_Type_Regular, "[]":|[])
1830 Format.Ledger.Read.posting_type
1833 (Format.Ledger.Posting_Type_Regular, "[ ]":|[])
1835 Format.Ledger.Read.posting_type
1838 (Format.Ledger.Posting_Type_Virtual_Balanced, "A":|[])
1840 Format.Ledger.Read.posting_type
1843 (Format.Ledger.Posting_Type_Virtual_Balanced, "A":|["B", "C"])
1845 Format.Ledger.Read.posting_type
1848 (Format.Ledger.Posting_Type_Regular, "A":|["B", "C"])
1850 Format.Ledger.Read.posting_type
1853 (Format.Ledger.Posting_Type_Regular, "[A]":|["B", "C"])
1855 Format.Ledger.Read.posting_type
1858 (Format.Ledger.Posting_Type_Regular, "A":|["[B]", "C"])
1860 Format.Ledger.Read.posting_type
1863 (Format.Ledger.Posting_Type_Regular, "A":|["B", "[C]"])
1865 , "amount" ~: TestList
1867 (Data.Either.rights $
1869 (Format.Ledger.Read.amount <* P.eof)
1873 , "\"0\" = Right 0" ~:
1874 (Data.Either.rights $
1876 (Format.Ledger.Read.amount <* P.eof)
1880 { Amount.quantity = Decimal 0 0
1882 , "\"00\" = Right 0" ~:
1883 (Data.Either.rights $
1885 (Format.Ledger.Read.amount <* P.eof)
1886 () "" ("00"::Text)])
1889 { Amount.quantity = Decimal 0 0
1891 , "\"0.\" = Right 0." ~:
1892 (Data.Either.rights $
1894 (Format.Ledger.Read.amount <* P.eof)
1895 () "" ("0."::Text)])
1898 { Amount.quantity = Decimal 0 0
1901 { Amount.Style.fractioning = Just '.'
1904 , "\".0\" = Right 0.0" ~:
1905 (Data.Either.rights $
1907 (Format.Ledger.Read.amount <* P.eof)
1908 () "" (".0"::Text)])
1911 { Amount.quantity = Decimal 0 0
1914 { Amount.Style.fractioning = Just '.'
1915 , Amount.Style.precision = 1
1918 , "\"0,\" = Right 0," ~:
1919 (Data.Either.rights $
1921 (Format.Ledger.Read.amount <* P.eof)
1922 () "" ("0,"::Text)])
1925 { Amount.quantity = Decimal 0 0
1928 { Amount.Style.fractioning = Just ','
1931 , "\",0\" = Right 0,0" ~:
1932 (Data.Either.rights $
1934 (Format.Ledger.Read.amount <* P.eof)
1935 () "" (",0"::Text)])
1938 { Amount.quantity = Decimal 0 0
1941 { Amount.Style.fractioning = Just ','
1942 , Amount.Style.precision = 1
1945 , "\"0_\" = Left" ~:
1946 (Data.Either.rights $
1948 (Format.Ledger.Read.amount <* P.eof)
1949 () "" ("0_"::Text)])
1952 , "\"_0\" = Left" ~:
1953 (Data.Either.rights $
1955 (Format.Ledger.Read.amount <* P.eof)
1956 () "" ("_0"::Text)])
1959 , "\"0.0\" = Right 0.0" ~:
1960 (Data.Either.rights $
1962 (Format.Ledger.Read.amount <* P.eof)
1963 () "" ("0.0"::Text)])
1966 { Amount.quantity = Decimal 0 0
1969 { Amount.Style.fractioning = Just '.'
1970 , Amount.Style.precision = 1
1973 , "\"00.00\" = Right 0.00" ~:
1974 (Data.Either.rights $
1976 (Format.Ledger.Read.amount <* P.eof)
1977 () "" ("00.00"::Text)])
1980 { Amount.quantity = Decimal 0 0
1983 { Amount.Style.fractioning = Just '.'
1984 , Amount.Style.precision = 2
1987 , "\"0,0\" = Right 0,0" ~:
1988 (Data.Either.rights $
1990 (Format.Ledger.Read.amount <* P.eof)
1991 () "" ("0,0"::Text)])
1994 { Amount.quantity = Decimal 0 0
1997 { Amount.Style.fractioning = Just ','
1998 , Amount.Style.precision = 1
2001 , "\"00,00\" = Right 0,00" ~:
2002 (Data.Either.rights $
2004 (Format.Ledger.Read.amount <* P.eof)
2005 () "" ("00,00"::Text)])
2008 { Amount.quantity = Decimal 0 0
2011 { Amount.Style.fractioning = Just ','
2012 , Amount.Style.precision = 2
2015 , "\"0_0\" = Right 0" ~:
2016 (Data.Either.rights $
2018 (Format.Ledger.Read.amount <* P.eof)
2019 () "" ("0_0"::Text)])
2022 { Amount.quantity = Decimal 0 0
2025 { Amount.Style.fractioning = Nothing
2026 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
2027 , Amount.Style.precision = 0
2030 , "\"00_00\" = Right 0" ~:
2031 (Data.Either.rights $
2033 (Format.Ledger.Read.amount <* P.eof)
2034 () "" ("00_00"::Text)])
2037 { Amount.quantity = Decimal 0 0
2040 { Amount.Style.fractioning = Nothing
2041 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
2042 , Amount.Style.precision = 0
2045 , "\"0,000.00\" = Right 0,000.00" ~:
2046 (Data.Either.rights $
2048 (Format.Ledger.Read.amount <* P.eof)
2049 () "" ("0,000.00"::Text)])
2052 { Amount.quantity = Decimal 0 0
2055 { Amount.Style.fractioning = Just '.'
2056 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
2057 , Amount.Style.precision = 2
2060 , "\"0.000,00\" = Right 0.000,00" ~:
2061 (Data.Either.rights $
2063 (Format.Ledger.Read.amount)
2064 () "" ("0.000,00"::Text)])
2067 { Amount.quantity = Decimal 0 0
2070 { Amount.Style.fractioning = Just ','
2071 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
2072 , Amount.Style.precision = 2
2075 , "\"1,000.00\" = Right 1,000.00" ~:
2076 (Data.Either.rights $
2078 (Format.Ledger.Read.amount <* P.eof)
2079 () "" ("1,000.00"::Text)])
2082 { Amount.quantity = Decimal 0 1000
2085 { Amount.Style.fractioning = Just '.'
2086 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
2087 , Amount.Style.precision = 2
2090 , "\"1.000,00\" = Right 1.000,00" ~:
2091 (Data.Either.rights $
2093 (Format.Ledger.Read.amount)
2094 () "" ("1.000,00"::Text)])
2097 { Amount.quantity = Decimal 0 1000
2100 { Amount.Style.fractioning = Just ','
2101 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
2102 , Amount.Style.precision = 2
2105 , "\"1,000.00.\" = Left" ~:
2106 (Data.Either.rights $
2108 (Format.Ledger.Read.amount)
2109 () "" ("1,000.00."::Text)])
2112 , "\"1.000,00,\" = Left" ~:
2113 (Data.Either.rights $
2115 (Format.Ledger.Read.amount)
2116 () "" ("1.000,00,"::Text)])
2119 , "\"1,000.00_\" = Left" ~:
2120 (Data.Either.rights $
2122 (Format.Ledger.Read.amount)
2123 () "" ("1,000.00_"::Text)])
2126 , "\"12\" = Right 12" ~:
2127 (Data.Either.rights $
2129 (Format.Ledger.Read.amount <* P.eof)
2130 () "" ("123"::Text)])
2133 { Amount.quantity = Decimal 0 123
2135 , "\"1.2\" = Right 1.2" ~:
2136 (Data.Either.rights $
2138 (Format.Ledger.Read.amount <* P.eof)
2139 () "" ("1.2"::Text)])
2142 { Amount.quantity = Decimal 1 12
2145 { Amount.Style.fractioning = Just '.'
2146 , Amount.Style.precision = 1
2149 , "\"1,2\" = Right 1,2" ~:
2150 (Data.Either.rights $
2152 (Format.Ledger.Read.amount <* P.eof)
2153 () "" ("1,2"::Text)])
2156 { Amount.quantity = Decimal 1 12
2159 { Amount.Style.fractioning = Just ','
2160 , Amount.Style.precision = 1
2163 , "\"12.23\" = Right 12.23" ~:
2164 (Data.Either.rights $
2166 (Format.Ledger.Read.amount <* P.eof)
2167 () "" ("12.34"::Text)])
2170 { Amount.quantity = Decimal 2 1234
2173 { Amount.Style.fractioning = Just '.'
2174 , Amount.Style.precision = 2
2177 , "\"12,23\" = Right 12,23" ~:
2178 (Data.Either.rights $
2180 (Format.Ledger.Read.amount <* P.eof)
2181 () "" ("12,34"::Text)])
2184 { Amount.quantity = Decimal 2 1234
2187 { Amount.Style.fractioning = Just ','
2188 , Amount.Style.precision = 2
2191 , "\"1_2\" = Right 1_2" ~:
2192 (Data.Either.rights $
2194 (Format.Ledger.Read.amount <* P.eof)
2195 () "" ("1_2"::Text)])
2198 { Amount.quantity = Decimal 0 12
2201 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
2202 , Amount.Style.precision = 0
2205 , "\"1_23\" = Right 1_23" ~:
2206 (Data.Either.rights $
2208 (Format.Ledger.Read.amount <* P.eof)
2209 () "" ("1_23"::Text)])
2212 { Amount.quantity = Decimal 0 123
2215 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
2216 , Amount.Style.precision = 0
2219 , "\"1_23_456\" = Right 1_23_456" ~:
2220 (Data.Either.rights $
2222 (Format.Ledger.Read.amount <* P.eof)
2223 () "" ("1_23_456"::Text)])
2226 { Amount.quantity = Decimal 0 123456
2229 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
2230 , Amount.Style.precision = 0
2233 , "\"1_23_456.7890_12345_678901\" = Right 1_23_456.7890_12345_678901" ~:
2234 (Data.Either.rights $
2236 (Format.Ledger.Read.amount <* P.eof)
2237 () "" ("1_23_456.7890_12345_678901"::Text)])
2240 { Amount.quantity = Decimal 15 123456789012345678901
2243 { Amount.Style.fractioning = Just '.'
2244 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
2245 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [4, 5, 6]
2246 , Amount.Style.precision = 15
2249 , "\"123456_78901_2345.678_90_1\" = Right 123456_78901_2345.678_90_1" ~:
2250 (Data.Either.rights $
2252 (Format.Ledger.Read.amount <* P.eof)
2253 () "" ("123456_78901_2345.678_90_1"::Text)])
2256 { Amount.quantity = Decimal 6 123456789012345678901
2259 { Amount.Style.fractioning = Just '.'
2260 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [4, 5, 6]
2261 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [3, 2]
2262 , Amount.Style.precision = 6
2265 , "\"$1\" = Right $1" ~:
2266 (Data.Either.rights $
2268 (Format.Ledger.Read.amount <* P.eof)
2269 () "" ("$1"::Text)])
2272 { Amount.quantity = Decimal 0 1
2275 { Amount.Style.fractioning = Nothing
2276 , Amount.Style.grouping_integral = Nothing
2277 , Amount.Style.grouping_fractional = Nothing
2278 , Amount.Style.precision = 0
2279 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2280 , Amount.Style.unit_spaced = Just False
2284 , "\"1$\" = Right 1$" ~:
2285 (Data.Either.rights $
2287 (Format.Ledger.Read.amount <* P.eof)
2288 () "" ("1$"::Text)])
2291 { Amount.quantity = Decimal 0 1
2294 { Amount.Style.fractioning = Nothing
2295 , Amount.Style.grouping_integral = Nothing
2296 , Amount.Style.grouping_fractional = Nothing
2297 , Amount.Style.precision = 0
2298 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2299 , Amount.Style.unit_spaced = Just False
2303 , "\"$ 1\" = Right $ 1" ~:
2304 (Data.Either.rights $
2306 (Format.Ledger.Read.amount <* P.eof)
2307 () "" ("$ 1"::Text)])
2310 { Amount.quantity = Decimal 0 1
2313 { Amount.Style.fractioning = Nothing
2314 , Amount.Style.grouping_integral = Nothing
2315 , Amount.Style.grouping_fractional = Nothing
2316 , Amount.Style.precision = 0
2317 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2318 , Amount.Style.unit_spaced = Just True
2322 , "\"1 $\" = Right 1 $" ~:
2323 (Data.Either.rights $
2325 (Format.Ledger.Read.amount <* P.eof)
2326 () "" ("1 $"::Text)])
2329 { Amount.quantity = Decimal 0 1
2332 { Amount.Style.fractioning = Nothing
2333 , Amount.Style.grouping_integral = Nothing
2334 , Amount.Style.grouping_fractional = Nothing
2335 , Amount.Style.precision = 0
2336 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2337 , Amount.Style.unit_spaced = Just True
2341 , "\"-$1\" = Right $-1" ~:
2342 (Data.Either.rights $
2344 (Format.Ledger.Read.amount <* P.eof)
2345 () "" ("-$1"::Text)])
2348 { Amount.quantity = Decimal 0 (-1)
2351 { Amount.Style.fractioning = Nothing
2352 , Amount.Style.grouping_integral = Nothing
2353 , Amount.Style.grouping_fractional = Nothing
2354 , Amount.Style.precision = 0
2355 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2356 , Amount.Style.unit_spaced = Just False
2360 , "\"\\\"4 2\\\"1\" = Right \\\"4 2\\\"1" ~:
2361 (Data.Either.rights $
2363 (Format.Ledger.Read.amount <* P.eof)
2364 () "" ("\"4 2\"1"::Text)])
2367 { Amount.quantity = Decimal 0 1
2370 { Amount.Style.fractioning = Nothing
2371 , Amount.Style.grouping_integral = Nothing
2372 , Amount.Style.grouping_fractional = Nothing
2373 , Amount.Style.precision = 0
2374 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2375 , Amount.Style.unit_spaced = Just False
2377 , Amount.unit = "4 2"
2379 , "\"1\\\"4 2\\\"\" = Right 1\\\"4 2\\\"" ~:
2380 (Data.Either.rights $
2382 (Format.Ledger.Read.amount <* P.eof)
2383 () "" ("1\"4 2\""::Text)])
2386 { Amount.quantity = Decimal 0 1
2389 { Amount.Style.fractioning = Nothing
2390 , Amount.Style.grouping_integral = Nothing
2391 , Amount.Style.grouping_fractional = Nothing
2392 , Amount.Style.precision = 0
2393 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2394 , Amount.Style.unit_spaced = Just False
2396 , Amount.unit = "4 2"
2398 , "\"$1.000,00\" = Right $1.000,00" ~:
2399 (Data.Either.rights $
2401 (Format.Ledger.Read.amount <* P.eof)
2402 () "" ("$1.000,00"::Text)])
2405 { Amount.quantity = Decimal 0 1000
2408 { Amount.Style.fractioning = Just ','
2409 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
2410 , Amount.Style.grouping_fractional = Nothing
2411 , Amount.Style.precision = 2
2412 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2413 , Amount.Style.unit_spaced = Just False
2417 , "\"1.000,00$\" = Right 1.000,00$" ~:
2418 (Data.Either.rights $
2420 (Format.Ledger.Read.amount <* P.eof)
2421 () "" ("1.000,00$"::Text)])
2424 { Amount.quantity = Decimal 0 1000
2427 { Amount.Style.fractioning = Just ','
2428 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
2429 , Amount.Style.grouping_fractional = Nothing
2430 , Amount.Style.precision = 2
2431 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2432 , Amount.Style.unit_spaced = Just False
2437 , "comment" ~: TestList
2438 [ "; some comment = Right \" some comment\"" ~:
2439 (Data.Either.rights $
2441 (Format.Ledger.Read.comment <* P.eof)
2442 () "" ("; some comment"::Text)])
2445 , "; some comment \\n = Right \" some comment \"" ~:
2446 (Data.Either.rights $
2448 (Format.Ledger.Read.comment <* P.newline <* P.eof)
2449 () "" ("; some comment \n"::Text)])
2451 [ " some comment " ]
2452 , "; some comment \\r\\n = Right \" some comment \"" ~:
2453 (Data.Either.rights $
2455 (Format.Ledger.Read.comment <* P.string "\r\n" <* P.eof)
2456 () "" ("; some comment \r\n"::Text)])
2458 [ " some comment " ]
2460 , "comments" ~: TestList
2461 [ "; some comment\\n ; some other comment = Right [\" some comment\", \" some other comment\"]" ~:
2462 (Data.Either.rights $
2464 (Format.Ledger.Read.comments <* P.eof)
2465 () "" ("; some comment\n ; some other comment"::Text)])
2467 [ [" some comment", " some other comment"] ]
2468 , "; some comment \\n = Right \" some comment \"" ~:
2469 (Data.Either.rights $
2471 (Format.Ledger.Read.comments <* P.string "\n" <* P.eof)
2472 () "" ("; some comment \n"::Text)])
2474 [ [" some comment "] ]
2476 , "date" ~: TestList
2478 (Data.Either.rights $
2479 [P.runParser_with_Error
2480 (Date.Read.date id Nothing <* P.eof)
2481 () "" ("2000/01/01"::Text)])
2483 [ Time.zonedTimeToUTC $
2486 (Time.fromGregorian 2000 01 01)
2487 (Time.TimeOfDay 0 0 0))
2489 , "2000/01/01 some text" ~:
2490 (Data.Either.rights $
2491 [P.runParser_with_Error
2492 (Date.Read.date id Nothing)
2493 () "" ("2000/01/01 some text"::Text)])
2495 [ Time.zonedTimeToUTC $
2498 (Time.fromGregorian 2000 01 01)
2499 (Time.TimeOfDay 0 0 0))
2501 , "2000/01/01 12:34" ~:
2502 (Data.Either.rights $
2503 [P.runParser_with_Error
2504 (Date.Read.date id Nothing <* P.eof)
2505 () "" ("2000/01/01 12:34"::Text)])
2507 [ Time.zonedTimeToUTC $
2510 (Time.fromGregorian 2000 01 01)
2511 (Time.TimeOfDay 12 34 0))
2513 , "2000/01/01 12:34:56" ~:
2514 (Data.Either.rights $
2515 [P.runParser_with_Error
2516 (Date.Read.date id Nothing <* P.eof)
2517 () "" ("2000/01/01 12:34:56"::Text)])
2519 [ Time.zonedTimeToUTC $
2522 (Time.fromGregorian 2000 01 01)
2523 (Time.TimeOfDay 12 34 56))
2525 , "2000/01/01 12:34 CET" ~:
2526 (Data.Either.rights $
2527 [P.runParser_with_Error
2528 (Date.Read.date id Nothing <* P.eof)
2529 () "" ("2000/01/01 12:34 CET"::Text)])
2531 [ Time.zonedTimeToUTC $
2534 (Time.fromGregorian 2000 01 01)
2535 (Time.TimeOfDay 12 34 0))
2536 (Time.TimeZone 60 True "CET")]
2537 , "2000/01/01 12:34 +0130" ~:
2538 (Data.Either.rights $
2539 [P.runParser_with_Error
2540 (Date.Read.date id Nothing <* P.eof)
2541 () "" ("2000/01/01 12:34 +0130"::Text)])
2543 [ Time.zonedTimeToUTC $
2546 (Time.fromGregorian 2000 01 01)
2547 (Time.TimeOfDay 12 34 0))
2548 (Time.TimeZone 90 False "+0130")]
2549 , "2000/01/01 12:34:56 CET" ~:
2550 (Data.Either.rights $
2551 [P.runParser_with_Error
2552 (Date.Read.date id Nothing <* P.eof)
2553 () "" ("2000/01/01 12:34:56 CET"::Text)])
2555 [ Time.zonedTimeToUTC $
2558 (Time.fromGregorian 2000 01 01)
2559 (Time.TimeOfDay 12 34 56))
2560 (Time.TimeZone 60 True "CET")]
2562 (Data.Either.rights $
2563 [P.runParser_with_Error
2564 (Date.Read.date id Nothing <* P.eof)
2565 () "" ("2001/02/29"::Text)])
2569 (Data.Either.rights $
2570 [P.runParser_with_Error
2571 (Date.Read.date id (Just 2000) <* P.eof)
2572 () "" ("01/01"::Text)])
2574 [ Time.zonedTimeToUTC $
2577 (Time.fromGregorian 2000 01 01)
2578 (Time.TimeOfDay 0 0 0))
2581 , "tag_value" ~: TestList
2583 (Data.Either.rights $
2585 (Format.Ledger.Read.tag_value <* P.eof)
2590 (Data.Either.rights $
2592 (Format.Ledger.Read.tag_value <* P.char '\n' <* P.eof)
2593 () "" (",\n"::Text)])
2597 (Data.Either.rights $
2599 (Format.Ledger.Read.tag_value <* P.eof)
2600 () "" (",x"::Text)])
2604 (Data.Either.rights $
2606 (Format.Ledger.Read.tag_value <* P.string ",x:" <* P.eof)
2607 () "" (",x:"::Text)])
2611 (Data.Either.rights $
2613 (Format.Ledger.Read.tag_value <* P.string ", n:" <* P.eof)
2614 () "" ("v, v, n:"::Text)])
2620 (Data.Either.rights $
2622 (Format.Ledger.Read.tag <* P.eof)
2623 () "" ("Name:"::Text)])
2627 (Data.Either.rights $
2629 (Format.Ledger.Read.tag <* P.eof)
2630 () "" ("Name:Value"::Text)])
2633 , "Name:Value\\n" ~:
2634 (Data.Either.rights $
2636 (Format.Ledger.Read.tag <* P.string "\n" <* P.eof)
2637 () "" ("Name:Value\n"::Text)])
2641 (Data.Either.rights $
2643 (Format.Ledger.Read.tag <* P.eof)
2644 () "" ("Name:Val ue"::Text)])
2646 [("Name", "Val ue")]
2648 (Data.Either.rights $
2650 (Format.Ledger.Read.tag <* P.eof)
2651 () "" ("Name:,"::Text)])
2655 (Data.Either.rights $
2657 (Format.Ledger.Read.tag <* P.eof)
2658 () "" ("Name:Val,ue"::Text)])
2660 [("Name", "Val,ue")]
2662 (Data.Either.rights $
2664 (Format.Ledger.Read.tag <* P.string ",ue:" <* P.eof)
2665 () "" ("Name:Val,ue:"::Text)])
2669 , "tags" ~: TestList
2671 (Data.Either.rights $
2673 (Format.Ledger.Read.tags <* P.eof)
2674 () "" ("Name:"::Text)])
2681 (Data.Either.rights $
2683 (Format.Ledger.Read.tags <* P.eof)
2684 () "" ("Name:,"::Text)])
2691 (Data.Either.rights $
2693 (Format.Ledger.Read.tags <* P.eof)
2694 () "" ("Name:,Name:"::Text)])
2697 [ ("Name", ["", ""])
2701 (Data.Either.rights $
2703 (Format.Ledger.Read.tags <* P.eof)
2704 () "" ("Name:,Name2:"::Text)])
2711 , "Name: , Name2:" ~:
2712 (Data.Either.rights $
2714 (Format.Ledger.Read.tags <* P.eof)
2715 () "" ("Name: , Name2:"::Text)])
2722 , "Name:,Name2:,Name3:" ~:
2723 (Data.Either.rights $
2725 (Format.Ledger.Read.tags <* P.eof)
2726 () "" ("Name:,Name2:,Name3:"::Text)])
2734 , "Name:Val ue,Name2:V a l u e,Name3:V al ue" ~:
2735 (Data.Either.rights $
2737 (Format.Ledger.Read.tags <* P.eof)
2738 () "" ("Name:Val ue,Name2:V a l u e,Name3:V al ue"::Text)])
2741 [ ("Name", ["Val ue"])
2742 , ("Name2", ["V a l u e"])
2743 , ("Name3", ["V al ue"])
2747 , "posting" ~: TestList
2748 [ " A:B:C = Right A:B:C" ~:
2749 (Data.Either.rights $
2750 [P.runParser_with_Error
2751 (Format.Ledger.Read.posting <* P.eof)
2752 Format.Ledger.Read.nil_Context "" (" A:B:C"::Text)])
2754 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
2755 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2757 , Format.Ledger.Posting_Type_Regular
2760 , " !A:B:C = Right !A:B:C" ~:
2761 (Data.List.map fst $
2762 Data.Either.rights $
2763 [P.runParser_with_Error
2764 (Format.Ledger.Read.posting <* P.eof)
2765 Format.Ledger.Read.nil_Context "" (" !A:B:C"::Text)])
2767 [ (Format.Ledger.posting ("A":|["B", "C"]))
2768 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2769 , Format.Ledger.posting_status = True
2772 , " *A:B:C = Right *A:B:C" ~:
2773 (Data.List.map fst $
2774 Data.Either.rights $
2775 [P.runParser_with_Error
2776 (Format.Ledger.Read.posting <* P.eof)
2777 Format.Ledger.Read.nil_Context "" (" *A:B:C"::Text)])
2779 [ (Format.Ledger.posting ("A":|["B", "C"]))
2780 { Format.Ledger.posting_amounts = Data.Map.fromList []
2781 , Format.Ledger.posting_comments = []
2782 , Format.Ledger.posting_dates = []
2783 , Format.Ledger.posting_status = True
2784 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2785 , Format.Ledger.posting_tags = Data.Map.fromList []
2788 , " A:B:C $1 = Right A:B:C $1" ~:
2789 (Data.List.map fst $
2790 Data.Either.rights $
2791 [P.runParser_with_Error
2792 (Format.Ledger.Read.posting <* P.eof)
2793 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
2795 [ (Format.Ledger.posting ("A":|["B","C $1"]))
2796 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2799 , " A:B:C $1 = Right A:B:C $1" ~:
2800 (Data.List.map fst $
2801 Data.Either.rights $
2802 [P.runParser_with_Error
2803 (Format.Ledger.Read.posting <* P.eof)
2804 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
2806 [ (Format.Ledger.posting ("A":|["B", "C"]))
2807 { Format.Ledger.posting_amounts = Data.Map.fromList
2809 { Amount.quantity = 1
2810 , Amount.style = Amount.Style.nil
2811 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2812 , Amount.Style.unit_spaced = Just False
2817 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2820 , " A:B:C $1 + 1€ = Right A:B:C $1 + 1€" ~:
2821 (Data.List.map fst $
2822 Data.Either.rights $
2823 [P.runParser_with_Error
2824 (Format.Ledger.Read.posting <* P.eof)
2825 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1€"::Text)])
2827 [ (Format.Ledger.posting ("A":|["B", "C"]))
2828 { Format.Ledger.posting_amounts = Data.Map.fromList
2830 { Amount.quantity = 1
2831 , Amount.style = Amount.Style.nil
2832 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2833 , Amount.Style.unit_spaced = Just False
2838 { Amount.quantity = 1
2839 , Amount.style = Amount.Style.nil
2840 { Amount.Style.unit_side = Just Amount.Style.Side_Right
2841 , Amount.Style.unit_spaced = Just False
2846 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2849 , " A:B:C $1 + 1$ = Right A:B:C $2" ~:
2850 (Data.List.map fst $
2851 Data.Either.rights $
2852 [P.runParser_with_Error
2853 (Format.Ledger.Read.posting <* P.eof)
2854 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$"::Text)])
2856 [ (Format.Ledger.posting ("A":|["B", "C"]))
2857 { Format.Ledger.posting_amounts = Data.Map.fromList
2859 { Amount.quantity = 2
2860 , Amount.style = Amount.Style.nil
2861 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2862 , Amount.Style.unit_spaced = Just False
2867 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2870 , " A:B:C $1 + 1$ + 1$ = Right A:B:C $3" ~:
2871 (Data.List.map fst $
2872 Data.Either.rights $
2873 [P.runParser_with_Error
2874 (Format.Ledger.Read.posting <* P.eof)
2875 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$ + 1$"::Text)])
2877 [ (Format.Ledger.posting ("A":|["B", "C"]))
2878 { Format.Ledger.posting_amounts = Data.Map.fromList
2880 { Amount.quantity = 3
2881 , Amount.style = Amount.Style.nil
2882 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2883 , Amount.Style.unit_spaced = Just False
2888 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2891 , " A:B:C ; some comment = Right A:B:C ; some comment" ~:
2892 (Data.List.map fst $
2893 Data.Either.rights $
2894 [P.runParser_with_Error
2895 (Format.Ledger.Read.posting <* P.eof)
2896 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment"::Text)])
2898 [ (Format.Ledger.posting ("A":|["B", "C"]))
2899 { Format.Ledger.posting_amounts = Data.Map.fromList []
2900 , Format.Ledger.posting_comments = [" some comment"]
2901 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2904 , " A:B:C ; some comment\\n ; some other comment = Right A:B:C ; some comment\\n ; some other comment" ~:
2905 (Data.List.map fst $
2906 Data.Either.rights $
2907 [P.runParser_with_Error
2908 (Format.Ledger.Read.posting <* P.eof)
2909 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment\n ; some other comment"::Text)])
2911 [ (Format.Ledger.posting ("A":|["B", "C"]))
2912 { Format.Ledger.posting_amounts = Data.Map.fromList []
2913 , Format.Ledger.posting_comments = [" some comment", " some other comment"]
2914 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2917 , " A:B:C $1 ; some comment = Right A:B:C $1 ; some comment" ~:
2918 (Data.List.map fst $
2919 Data.Either.rights $
2920 [P.runParser_with_Error
2921 (Format.Ledger.Read.posting)
2922 Format.Ledger.Read.nil_Context "" (" A:B:C $1 ; some comment"::Text)])
2924 [ (Format.Ledger.posting ("A":|["B", "C"]))
2925 { Format.Ledger.posting_amounts = Data.Map.fromList
2927 { Amount.quantity = 1
2928 , Amount.style = Amount.Style.nil
2929 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2930 , Amount.Style.unit_spaced = Just False
2935 , Format.Ledger.posting_comments = [" some comment"]
2936 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2939 , " A:B:C ; N:V = Right A:B:C ; N:V" ~:
2940 (Data.List.map fst $
2941 Data.Either.rights $
2942 [P.runParser_with_Error
2943 (Format.Ledger.Read.posting <* P.eof)
2944 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V"::Text)])
2946 [ (Format.Ledger.posting ("A":|["B", "C"]))
2947 { Format.Ledger.posting_comments = [" N:V"]
2948 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2949 , Format.Ledger.posting_tags = Data.Map.fromList
2954 , " A:B:C ; some comment N:V = Right A:B:C ; some comment N:V" ~:
2955 (Data.List.map fst $
2956 Data.Either.rights $
2957 [P.runParser_with_Error
2958 (Format.Ledger.Read.posting <* P.eof)
2959 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V"::Text)])
2961 [ (Format.Ledger.posting ("A":|["B", "C"]))
2962 { Format.Ledger.posting_comments = [" some comment N:V"]
2963 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2964 , Format.Ledger.posting_tags = Data.Map.fromList
2969 , " A:B:C ; some comment N:V v, N2:V2 v2 = Right A:B:C ; some comment N:V v, N2:V2 v2" ~:
2970 (Data.List.map fst $
2971 Data.Either.rights $
2972 [P.runParser_with_Error
2973 (Format.Ledger.Read.posting )
2974 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V v, N2:V2 v2"::Text)])
2976 [ (Format.Ledger.posting ("A":|["B", "C"]))
2977 { Format.Ledger.posting_comments = [" some comment N:V v, N2:V2 v2"]
2978 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2979 , Format.Ledger.posting_tags = Data.Map.fromList
2985 , " A:B:C ; N:V\\n ; N:V2 = Right A:B:C ; N:V\\n ; N:V2" ~:
2986 (Data.List.map fst $
2987 Data.Either.rights $
2988 [P.runParser_with_Error
2989 (Format.Ledger.Read.posting <* P.eof)
2990 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N:V2"::Text)])
2992 [ (Format.Ledger.posting ("A":|["B", "C"]))
2993 { Format.Ledger.posting_comments = [" N:V", " N:V2"]
2994 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2995 , Format.Ledger.posting_tags = Data.Map.fromList
2996 [ ("N", ["V", "V2"])
3000 , " A:B:C ; N:V\\n ; N2:V = Right A:B:C ; N:V\\n ; N2:V" ~:
3001 (Data.List.map fst $
3002 Data.Either.rights $
3003 [P.runParser_with_Error
3004 (Format.Ledger.Read.posting <* P.eof)
3005 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N2:V"::Text)])
3007 [ (Format.Ledger.posting ("A":|["B", "C"]))
3008 { Format.Ledger.posting_comments = [" N:V", " N2:V"]
3009 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3010 , Format.Ledger.posting_tags = Data.Map.fromList
3016 , " A:B:C ; date:2001/01/01 = Right A:B:C ; date:2001/01/01" ~:
3017 (Data.List.map fst $
3018 Data.Either.rights $
3019 [P.runParser_with_Error
3020 (Format.Ledger.Read.posting <* P.eof)
3021 Format.Ledger.Read.nil_Context "" (" A:B:C ; date:2001/01/01"::Text)])
3023 [ (Format.Ledger.posting ("A":|["B", "C"]))
3024 { Format.Ledger.posting_comments = [" date:2001/01/01"]
3025 , Format.Ledger.posting_dates =
3026 [ Time.zonedTimeToUTC $
3029 (Time.fromGregorian 2001 01 01)
3030 (Time.TimeOfDay 0 0 0))
3033 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3034 , Format.Ledger.posting_tags = Data.Map.fromList
3035 [ ("date", ["2001/01/01"])
3039 , " (A:B:C) = Right (A:B:C)" ~:
3040 (Data.Either.rights $
3041 [P.runParser_with_Error
3042 (Format.Ledger.Read.posting <* P.eof)
3043 Format.Ledger.Read.nil_Context "" (" (A:B:C)"::Text)])
3045 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
3046 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3048 , Format.Ledger.Posting_Type_Virtual
3051 , " [A:B:C] = Right [A:B:C]" ~:
3052 (Data.Either.rights $
3053 [P.runParser_with_Error
3054 (Format.Ledger.Read.posting <* P.eof)
3055 Format.Ledger.Read.nil_Context "" (" [A:B:C]"::Text)])
3057 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
3058 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3060 , Format.Ledger.Posting_Type_Virtual_Balanced
3064 , "transaction" ~: TestList
3065 [ "2000/01/01 some description\\n A:B:C $1\\n a:b:c" ~:
3066 (Data.Either.rights $
3067 [P.runParser_with_Error
3068 (Format.Ledger.Read.transaction <* P.eof)
3069 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c"::Text)])
3071 [ Format.Ledger.transaction
3072 { Format.Ledger.transaction_dates=
3073 ( Time.zonedTimeToUTC $
3076 (Time.fromGregorian 2000 01 01)
3077 (Time.TimeOfDay 0 0 0))
3080 , Format.Ledger.transaction_description="some description"
3081 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3082 [ (Format.Ledger.posting ("A":|["B", "C"]))
3083 { Format.Ledger.posting_amounts = Data.Map.fromList
3085 { Amount.quantity = 1
3086 , Amount.style = Amount.Style.nil
3087 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3088 , Amount.Style.unit_spaced = Just False
3093 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3095 , (Format.Ledger.posting ("a":|["b", "c"]))
3096 { Format.Ledger.posting_amounts = Data.Map.fromList
3098 { Amount.quantity = -1
3099 , Amount.style = Amount.Style.nil
3100 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3101 , Amount.Style.unit_spaced = Just False
3106 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3109 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3112 , "2000/01/01 some description\\n A:B:C $1\\n a:b:c\\n" ~:
3113 (Data.Either.rights $
3114 [P.runParser_with_Error
3115 (Format.Ledger.Read.transaction <* P.newline <* P.eof)
3116 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c\n"::Text)])
3118 [ Format.Ledger.transaction
3119 { Format.Ledger.transaction_dates=
3120 ( Time.zonedTimeToUTC $
3123 (Time.fromGregorian 2000 01 01)
3124 (Time.TimeOfDay 0 0 0))
3127 , Format.Ledger.transaction_description="some description"
3128 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3129 [ (Format.Ledger.posting ("A":|["B", "C"]))
3130 { Format.Ledger.posting_amounts = Data.Map.fromList
3132 { Amount.quantity = 1
3133 , Amount.style = Amount.Style.nil
3134 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3135 , Amount.Style.unit_spaced = Just False
3140 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3142 , (Format.Ledger.posting ("a":|["b", "c"]))
3143 { Format.Ledger.posting_amounts = Data.Map.fromList
3145 { Amount.quantity = -1
3146 , Amount.style = Amount.Style.nil
3147 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3148 , Amount.Style.unit_spaced = Just False
3153 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3156 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3159 , "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" ~:
3160 (Data.Either.rights $
3161 [P.runParser_with_Error
3162 (Format.Ledger.Read.transaction <* P.eof)
3163 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)])
3165 [ Format.Ledger.transaction
3166 { Format.Ledger.transaction_comments_after =
3168 , " some other;comment"
3170 , " some last comment"
3172 , Format.Ledger.transaction_dates=
3173 ( Time.zonedTimeToUTC $
3176 (Time.fromGregorian 2000 01 01)
3177 (Time.TimeOfDay 0 0 0))
3180 , Format.Ledger.transaction_description="some 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 ("a":|["b", "c"]))
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_tags = Data.Map.fromList
3212 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3216 , "journal" ~: TestList
3217 [ "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
3219 P.runParserT_with_Error
3220 (Format.Ledger.Read.journal "" {-<* P.eof-})
3221 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)
3223 (\j -> j{Format.Ledger.journal_last_read_time=
3224 Format.Ledger.journal_last_read_time Format.Ledger.journal}) $
3225 Data.Either.rights [jnl])
3227 [ Format.Ledger.journal
3228 { Format.Ledger.journal_transactions =
3229 Format.Ledger.transaction_by_Date
3230 [ Format.Ledger.transaction
3231 { Format.Ledger.transaction_dates=
3232 ( Time.zonedTimeToUTC $
3235 (Time.fromGregorian 2000 01 01)
3236 (Time.TimeOfDay 0 0 0))
3239 , Format.Ledger.transaction_description="1° description"
3240 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3241 [ (Format.Ledger.posting ("A":|["B", "C"]))
3242 { Format.Ledger.posting_amounts = Data.Map.fromList
3244 { Amount.quantity = 1
3245 , Amount.style = Amount.Style.nil
3246 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3247 , Amount.Style.unit_spaced = Just False
3252 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3254 , (Format.Ledger.posting ("a":|["b", "c"]))
3255 { Format.Ledger.posting_amounts = Data.Map.fromList
3257 { Amount.quantity = -1
3258 , Amount.style = Amount.Style.nil
3259 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3260 , Amount.Style.unit_spaced = Just False
3265 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3268 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3270 , Format.Ledger.transaction
3271 { Format.Ledger.transaction_dates=
3272 ( Time.zonedTimeToUTC $
3275 (Time.fromGregorian 2000 01 02)
3276 (Time.TimeOfDay 0 0 0))
3279 , Format.Ledger.transaction_description="2° description"
3280 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3281 [ (Format.Ledger.posting ("A":|["B", "C"]))
3282 { Format.Ledger.posting_amounts = Data.Map.fromList
3284 { Amount.quantity = 1
3285 , Amount.style = Amount.Style.nil
3286 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3287 , Amount.Style.unit_spaced = Just False
3292 , Format.Ledger.posting_sourcepos = P.newPos "" 5 1
3294 , (Format.Ledger.posting ("x":|["y", "z"]))
3295 { Format.Ledger.posting_amounts = Data.Map.fromList
3297 { Amount.quantity = -1
3298 , Amount.style = Amount.Style.nil
3299 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3300 , Amount.Style.unit_spaced = Just False
3305 , Format.Ledger.posting_sourcepos = P.newPos "" 6 1
3308 , Format.Ledger.transaction_sourcepos = P.newPos "" 4 1
3315 , "Write" ~: TestList
3316 [ "account" ~: TestList
3318 ((Format.Ledger.Write.show
3319 Format.Ledger.Write.Style
3320 { Format.Ledger.Write.style_color=False
3321 , Format.Ledger.Write.style_align=True
3323 Format.Ledger.Write.account Format.Ledger.Posting_Type_Regular $
3328 ((Format.Ledger.Write.show
3329 Format.Ledger.Write.Style
3330 { Format.Ledger.Write.style_color=False
3331 , Format.Ledger.Write.style_align=True
3333 Format.Ledger.Write.account Format.Ledger.Posting_Type_Regular $
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.account Format.Ledger.Posting_Type_Virtual $
3348 ((Format.Ledger.Write.show
3349 Format.Ledger.Write.Style
3350 { Format.Ledger.Write.style_color=False
3351 , Format.Ledger.Write.style_align=True
3353 Format.Ledger.Write.account Format.Ledger.Posting_Type_Virtual_Balanced $
3358 , "amount" ~: TestList
3360 ((Format.Ledger.Write.show
3361 Format.Ledger.Write.Style
3362 { Format.Ledger.Write.style_color=False
3363 , Format.Ledger.Write.style_align=True
3365 Format.Ledger.Write.amount
3370 ((Format.Ledger.Write.show
3371 Format.Ledger.Write.Style
3372 { Format.Ledger.Write.style_color=False
3373 , Format.Ledger.Write.style_align=True
3375 Format.Ledger.Write.amount
3377 { Amount.style = Amount.Style.nil
3378 { Amount.Style.precision = 2 }
3383 ((Format.Ledger.Write.show
3384 Format.Ledger.Write.Style
3385 { Format.Ledger.Write.style_color=False
3386 , Format.Ledger.Write.style_align=True
3388 Format.Ledger.Write.amount
3390 { Amount.quantity = Decimal 0 123
3395 ((Format.Ledger.Write.show
3396 Format.Ledger.Write.Style
3397 { Format.Ledger.Write.style_color=False
3398 , Format.Ledger.Write.style_align=True
3400 Format.Ledger.Write.amount
3402 { Amount.quantity = Decimal 0 (- 123)
3406 , "12.3 @ prec=0" ~:
3407 ((Format.Ledger.Write.show
3408 Format.Ledger.Write.Style
3409 { Format.Ledger.Write.style_color=False
3410 , Format.Ledger.Write.style_align=True
3412 Format.Ledger.Write.amount
3414 { Amount.quantity = Decimal 1 123
3415 , Amount.style = Amount.Style.nil
3416 { Amount.Style.fractioning = Just '.'
3421 , "12.5 @ prec=0" ~:
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 1 125
3430 , Amount.style = Amount.Style.nil
3431 { Amount.Style.fractioning = Just '.'
3436 , "12.3 @ prec=1" ~:
3437 ((Format.Ledger.Write.show
3438 Format.Ledger.Write.Style
3439 { Format.Ledger.Write.style_color=False
3440 , Format.Ledger.Write.style_align=True
3442 Format.Ledger.Write.amount
3444 { Amount.quantity = Decimal 1 123
3445 , Amount.style = Amount.Style.nil
3446 { Amount.Style.fractioning = Just '.'
3447 , Amount.Style.precision = 1
3452 , "1,234.56 @ prec=2" ~:
3453 ((Format.Ledger.Write.show
3454 Format.Ledger.Write.Style
3455 { Format.Ledger.Write.style_color=False
3456 , Format.Ledger.Write.style_align=True
3458 Format.Ledger.Write.amount
3460 { Amount.quantity = Decimal 2 123456
3461 , Amount.style = Amount.Style.nil
3462 { Amount.Style.fractioning = Just '.'
3463 , Amount.Style.precision = 2
3464 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
3469 , "123,456,789,01,2.3456789 @ prec=7" ~:
3470 ((Format.Ledger.Write.show
3471 Format.Ledger.Write.Style
3472 { Format.Ledger.Write.style_color=False
3473 , Format.Ledger.Write.style_align=True
3475 Format.Ledger.Write.amount
3477 { Amount.quantity = Decimal 7 1234567890123456789
3478 , Amount.style = Amount.Style.nil
3479 { Amount.Style.fractioning = Just '.'
3480 , Amount.Style.precision = 7
3481 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3485 "123,456,789,01,2.3456789")
3486 , "1234567.8,90,123,456,789 @ prec=12" ~:
3487 ((Format.Ledger.Write.show
3488 Format.Ledger.Write.Style
3489 { Format.Ledger.Write.style_color=False
3490 , Format.Ledger.Write.style_align=True
3492 Format.Ledger.Write.amount
3494 { Amount.quantity = Decimal 12 1234567890123456789
3495 , Amount.style = Amount.Style.nil
3496 { Amount.Style.fractioning = Just '.'
3497 , Amount.Style.precision = 12
3498 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3502 "1234567.8,90,123,456,789")
3503 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
3504 ((Format.Ledger.Write.show
3505 Format.Ledger.Write.Style
3506 { Format.Ledger.Write.style_color=False
3507 , Format.Ledger.Write.style_align=True
3509 Format.Ledger.Write.amount
3511 { Amount.quantity = Decimal 7 1234567890123456789
3512 , Amount.style = Amount.Style.nil
3513 { Amount.Style.fractioning = Just '.'
3514 , Amount.Style.precision = 7
3515 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3519 "1,2,3,4,5,6,7,89,012.3456789")
3520 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
3521 ((Format.Ledger.Write.show
3522 Format.Ledger.Write.Style
3523 { Format.Ledger.Write.style_color=False
3524 , Format.Ledger.Write.style_align=True
3526 Format.Ledger.Write.amount
3528 { Amount.quantity = Decimal 12 1234567890123456789
3529 , Amount.style = Amount.Style.nil
3530 { Amount.Style.fractioning = Just '.'
3531 , Amount.Style.precision = 12
3532 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3536 "1234567.890,12,3,4,5,6,7,8,9")
3538 , "amount_length" ~: TestList
3540 ((Format.Ledger.Write.amount_length
3545 ((Format.Ledger.Write.amount_length
3547 { Amount.style = Amount.Style.nil
3548 { Amount.Style.precision = 2 }
3553 ((Format.Ledger.Write.amount_length
3555 { Amount.quantity = Decimal 0 123
3560 ((Format.Ledger.Write.amount_length
3562 { Amount.quantity = Decimal 0 (- 123)
3566 , "12.3 @ prec=0" ~:
3567 ((Format.Ledger.Write.amount_length
3569 { Amount.quantity = Decimal 1 123
3570 , Amount.style = Amount.Style.nil
3571 { Amount.Style.fractioning = Just '.'
3576 , "12.5 @ prec=0" ~:
3577 ((Format.Ledger.Write.amount_length
3579 { Amount.quantity = Decimal 1 125
3580 , Amount.style = Amount.Style.nil
3581 { Amount.Style.fractioning = Just '.'
3586 , "12.3 @ prec=1" ~:
3587 ((Format.Ledger.Write.amount_length
3589 { Amount.quantity = Decimal 1 123
3590 , Amount.style = Amount.Style.nil
3591 { Amount.Style.fractioning = Just '.'
3592 , Amount.Style.precision = 1
3597 , "1,234.56 @ prec=2" ~:
3598 ((Format.Ledger.Write.amount_length
3600 { Amount.quantity = Decimal 2 123456
3601 , Amount.style = Amount.Style.nil
3602 { Amount.Style.fractioning = Just '.'
3603 , Amount.Style.precision = 2
3604 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
3609 , "123,456,789,01,2.3456789 @ prec=7" ~:
3610 ((Format.Ledger.Write.amount_length
3612 { Amount.quantity = Decimal 7 1234567890123456789
3613 , Amount.style = Amount.Style.nil
3614 { Amount.Style.fractioning = Just '.'
3615 , Amount.Style.precision = 7
3616 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3621 , "1234567.8,90,123,456,789 @ prec=12" ~:
3622 ((Format.Ledger.Write.amount_length
3624 { Amount.quantity = Decimal 12 1234567890123456789
3625 , Amount.style = Amount.Style.nil
3626 { Amount.Style.fractioning = Just '.'
3627 , Amount.Style.precision = 12
3628 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3633 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
3634 ((Format.Ledger.Write.amount_length
3636 { Amount.quantity = Decimal 7 1234567890123456789
3637 , Amount.style = Amount.Style.nil
3638 { Amount.Style.fractioning = Just '.'
3639 , Amount.Style.precision = 7
3640 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3645 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
3646 ((Format.Ledger.Write.amount_length
3648 { Amount.quantity = Decimal 12 1234567890123456789
3649 , Amount.style = Amount.Style.nil
3650 { Amount.Style.fractioning = Just '.'
3651 , Amount.Style.precision = 12
3652 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3657 , "1000000.000,00,0,0,0,0,0,0,0 @ prec=12" ~:
3658 ((Format.Ledger.Write.amount_length
3660 { Amount.quantity = Decimal 12 1000000000000000000
3661 , Amount.style = Amount.Style.nil
3662 { Amount.Style.fractioning = Just '.'
3663 , Amount.Style.precision = 12
3664 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3670 ((Format.Ledger.Write.amount_length $
3672 { Amount.quantity = Decimal 0 999
3673 , Amount.style = Amount.Style.nil
3674 { Amount.Style.precision = 0
3679 , "1000 @ prec=0" ~:
3680 ((Format.Ledger.Write.amount_length $
3682 { Amount.quantity = Decimal 0 1000
3683 , Amount.style = Amount.Style.nil
3684 { Amount.Style.precision = 0
3689 , "10,00€ @ prec=2" ~:
3690 ((Format.Ledger.Write.amount_length $ Amount.eur 10)
3694 , "date" ~: TestList
3696 ((Format.Ledger.Write.show
3697 Format.Ledger.Write.Style
3698 { Format.Ledger.Write.style_color=False
3699 , Format.Ledger.Write.style_align=True
3701 Format.Ledger.Write.date
3705 , "2000/01/01 12:34:51 CET" ~:
3706 (Format.Ledger.Write.show
3707 Format.Ledger.Write.Style
3708 { Format.Ledger.Write.style_color=False
3709 , Format.Ledger.Write.style_align=True
3711 Format.Ledger.Write.date $
3712 Time.zonedTimeToUTC $
3715 (Time.fromGregorian 2000 01 01)
3716 (Time.TimeOfDay 12 34 51))
3717 (Time.TimeZone 60 False "CET"))
3719 "2000/01/01 11:34:51"
3720 , "2000/01/01 12:34:51 +0100" ~:
3721 (Format.Ledger.Write.show
3722 Format.Ledger.Write.Style
3723 { Format.Ledger.Write.style_color=False
3724 , Format.Ledger.Write.style_align=True
3726 Format.Ledger.Write.date $
3727 Time.zonedTimeToUTC $
3730 (Time.fromGregorian 2000 01 01)
3731 (Time.TimeOfDay 12 34 51))
3732 (Time.TimeZone 60 False ""))
3734 "2000/01/01 11:34:51"
3735 , "2000/01/01 01:02:03" ~:
3736 (Format.Ledger.Write.show
3737 Format.Ledger.Write.Style
3738 { Format.Ledger.Write.style_color=False
3739 , Format.Ledger.Write.style_align=True
3741 Format.Ledger.Write.date $
3742 Time.zonedTimeToUTC $
3745 (Time.fromGregorian 2000 01 01)
3746 (Time.TimeOfDay 1 2 3))
3749 "2000/01/01 01:02:03"
3751 (Format.Ledger.Write.show
3752 Format.Ledger.Write.Style
3753 { Format.Ledger.Write.style_color=False
3754 , Format.Ledger.Write.style_align=True
3756 Format.Ledger.Write.date $
3757 Time.zonedTimeToUTC $
3760 (Time.fromGregorian 0 01 01)
3761 (Time.TimeOfDay 1 2 0))
3766 (Format.Ledger.Write.show
3767 Format.Ledger.Write.Style
3768 { Format.Ledger.Write.style_color=False
3769 , Format.Ledger.Write.style_align=True
3771 Format.Ledger.Write.date $
3772 Time.zonedTimeToUTC $
3775 (Time.fromGregorian 0 01 01)
3776 (Time.TimeOfDay 1 0 0))
3781 (Format.Ledger.Write.show
3782 Format.Ledger.Write.Style
3783 { Format.Ledger.Write.style_color=False
3784 , Format.Ledger.Write.style_align=True
3786 Format.Ledger.Write.date $
3787 Time.zonedTimeToUTC $
3790 (Time.fromGregorian 0 01 01)
3791 (Time.TimeOfDay 0 1 0))
3796 (Format.Ledger.Write.show
3797 Format.Ledger.Write.Style
3798 { Format.Ledger.Write.style_color=False
3799 , Format.Ledger.Write.style_align=True
3801 Format.Ledger.Write.date $
3802 Time.zonedTimeToUTC $
3805 (Time.fromGregorian 0 01 01)
3806 (Time.TimeOfDay 0 0 0))
3811 , "transaction" ~: TestList
3813 ((Format.Ledger.Write.show
3814 Format.Ledger.Write.Style
3815 { Format.Ledger.Write.style_color=False
3816 , Format.Ledger.Write.style_align=True
3818 Format.Ledger.Write.transaction
3819 Format.Ledger.transaction)
3822 , "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" ~:
3823 ((Format.Ledger.Write.show
3824 Format.Ledger.Write.Style
3825 { Format.Ledger.Write.style_color=False
3826 , Format.Ledger.Write.style_align=True
3828 Format.Ledger.Write.transaction $
3829 Format.Ledger.transaction
3830 { Format.Ledger.transaction_dates=
3831 ( Time.zonedTimeToUTC $
3834 (Time.fromGregorian 2000 01 01)
3835 (Time.TimeOfDay 0 0 0))
3838 , Format.Ledger.transaction_description="some description"
3839 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3840 [ (Format.Ledger.posting ("A":|["B", "C"]))
3841 { Format.Ledger.posting_amounts = Data.Map.fromList
3843 { Amount.quantity = 1
3844 , Amount.style = Amount.Style.nil
3845 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3846 , Amount.Style.unit_spaced = Just False
3852 , (Format.Ledger.posting ("a":|["b", "c"]))
3853 { Format.Ledger.posting_comments = ["first comment","second comment","third comment"]
3858 "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")
3859 , "2000/01/01 some description\\n\\tA:B:C $1\\n\\tAA:BB:CC $123" ~:
3860 ((Format.Ledger.Write.show
3861 Format.Ledger.Write.Style
3862 { Format.Ledger.Write.style_color=False
3863 , Format.Ledger.Write.style_align=True
3865 Format.Ledger.Write.transaction $
3866 Format.Ledger.transaction
3867 { Format.Ledger.transaction_dates=
3868 ( Time.zonedTimeToUTC $
3871 (Time.fromGregorian 2000 01 01)
3872 (Time.TimeOfDay 0 0 0))
3875 , Format.Ledger.transaction_description="some description"
3876 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3877 [ (Format.Ledger.posting ("A":|["B", "C"]))
3878 { Format.Ledger.posting_amounts = Data.Map.fromList
3880 { Amount.quantity = 1
3881 , Amount.style = Amount.Style.nil
3882 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3883 , Amount.Style.unit_spaced = Just False
3889 , (Format.Ledger.posting ("AA":|["BB", "CC"]))
3890 { Format.Ledger.posting_amounts = Data.Map.fromList
3892 { Amount.quantity = 123
3893 , Amount.style = Amount.Style.nil
3894 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3895 , Amount.Style.unit_spaced = Just False
3904 "2000/01/01 some description\n\tA:B:C $1\n\tAA:BB:CC $123")