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, 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
226 [ "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))
300 [ "filter_account_section" ~: TestList
302 (Data.Either.rights $
304 (Filter.Read.test_account <* P.eof)
307 [ [Filter.Test_Account_Section_Any]
310 (Data.Either.rights $
312 (Filter.Read.test_account <* P.eof)
315 [ [Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")]
318 (Data.Either.rights $
320 (Filter.Read.test_account <* P.eof)
323 [ [Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "AA")]
326 (Data.Either.rights $
328 (Filter.Read.test_account <* P.eof)
329 () "" ("::A"::Text)])
331 [ [ Filter.Test_Account_Section_Many
332 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
336 (Data.Either.rights $
338 (Filter.Read.test_account <* P.eof)
341 [ [ Filter.Test_Account_Section_Many
342 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
346 (Data.Either.rights $
348 (Filter.Read.test_account <* P.eof)
351 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
352 , Filter.Test_Account_Section_Many
356 (Data.Either.rights $
358 (Filter.Read.test_account <* P.eof)
359 () "" ("A::"::Text)])
361 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
362 , Filter.Test_Account_Section_Many
366 (Data.Either.rights $
368 (Filter.Read.test_account <* P.eof)
369 () "" ("A:B"::Text)])
371 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
372 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B") ]
375 (Data.Either.rights $
377 (Filter.Read.test_account <* P.eof)
378 () "" ("A::B"::Text)])
380 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
381 , Filter.Test_Account_Section_Many
382 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B")
386 (Data.Either.rights $
388 (Filter.Read.test_account <* P.eof)
389 () "" ("A:::B"::Text)])
391 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
392 , Filter.Test_Account_Section_Many
393 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B")
397 (Data.Either.rights $
399 (Filter.Read.test_account <* P.char ' ' <* P.eof)
400 () "" ("A: "::Text)])
402 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
403 , Filter.Test_Account_Section_Many
411 [ "Balance" ~: TestList
412 [ "balance" ~: TestList
413 [ "[A+$1] = A+$1 & $+1" ~:
414 (Calc.Balance.balance
415 (Format.Ledger.posting ("A":|[]))
416 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
421 { Calc.Balance.balance_by_account =
422 Lib.TreeMap.from_List const $
423 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
424 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
425 , Calc.Balance.balance_by_unit =
427 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
428 [ Calc.Balance.Unit_Sum
429 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
430 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
435 , "[A+$1, A-$1] = {A+$0, $+0}" ~:
437 (flip Calc.Balance.balance)
439 [ (Format.Ledger.posting ("A":|[]))
440 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
442 , (Format.Ledger.posting ("A":|[]))
443 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ]
448 { Calc.Balance.balance_by_account =
449 Lib.TreeMap.from_List const $
451 , Data.Map.fromListWith const $
452 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance s, s))
453 [ Calc.Balance.Amount_Sum
454 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
455 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
456 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
460 , Calc.Balance.balance_by_unit =
462 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
463 [ Calc.Balance.Unit_Sum
464 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
465 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
466 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
467 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
469 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
474 , "[A+$1, A-€1] = {A+$1-€1, $+1 €-1}" ~:
476 (flip Calc.Balance.balance)
478 [ (Format.Ledger.posting ("A":|[]))
479 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
481 , (Format.Ledger.posting ("A":|[]))
482 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1 ]
487 { Calc.Balance.balance_by_account =
488 Lib.TreeMap.from_List const $
489 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
490 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ -1 ]) ]
491 , Calc.Balance.balance_by_unit =
493 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
494 [ Calc.Balance.Unit_Sum
495 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
496 { Calc.Balance.amount_sum_negative = Nothing
497 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
498 , Calc.Balance.amount_sum_balance = Amount.usd $ 1
500 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
503 , Calc.Balance.Unit_Sum
504 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
505 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -1
506 , Calc.Balance.amount_sum_positive = Nothing
507 , Calc.Balance.amount_sum_balance = Amount.eur $ -1
509 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
514 , "[A+$1, B-$1] = {A+$1 B-$1, $+0}" ~:
516 (flip Calc.Balance.balance)
518 [ (Format.Ledger.posting ("A":|[]))
519 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
521 , (Format.Ledger.posting ("B":|[]))
522 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ]
527 { Calc.Balance.balance_by_account =
528 Lib.TreeMap.from_List const $
529 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
530 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
531 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
533 , Calc.Balance.balance_by_unit =
535 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
536 [ Calc.Balance.Unit_Sum
537 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
538 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
539 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
540 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
542 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
549 (flip Calc.Balance.balance)
551 [ (Format.Ledger.posting ("A":|[]))
552 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
554 , (Format.Ledger.posting ("B":|[]))
555 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
560 { Calc.Balance.balance_by_account =
561 Lib.TreeMap.from_List const $
562 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
563 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
564 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ])
566 , Calc.Balance.balance_by_unit =
568 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
569 [ Calc.Balance.Unit_Sum
570 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
571 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
576 , "[A+$1+€2, A-$1-€2] = {A+$0+€0, $+0 €+0}" ~:
578 (flip Calc.Balance.balance)
580 [ (Format.Ledger.posting ("A":|[]))
581 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2 ]
583 , (Format.Ledger.posting ("A":|[]))
584 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2 ]
589 { Calc.Balance.balance_by_account =
590 Lib.TreeMap.from_List const $
592 , Data.Map.fromListWith const $
593 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance s, s))
594 [ Calc.Balance.Amount_Sum
595 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
596 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
597 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
599 , Calc.Balance.Amount_Sum
600 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -2
601 , Calc.Balance.amount_sum_positive = Just $ Amount.eur $ 2
602 , Calc.Balance.amount_sum_balance = Amount.eur $ 0
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 (,())
619 , Calc.Balance.Unit_Sum
620 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
621 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -2
622 , Calc.Balance.amount_sum_positive = Just $ Amount.eur $ 2
623 , Calc.Balance.amount_sum_balance = Amount.eur $ 0
625 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
630 , "[A+$1+€2+£3, B-$1-2€-£3] = {A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~:
632 (flip Calc.Balance.balance)
634 [ (Format.Ledger.posting ("A":|[]))
635 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ]
637 , (Format.Ledger.posting ("B":|[]))
638 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ]
643 { Calc.Balance.balance_by_account =
644 Lib.TreeMap.from_List const $
645 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
646 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
647 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
649 , Calc.Balance.balance_by_unit =
651 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
652 [ Calc.Balance.Unit_Sum
653 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
654 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
655 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
656 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
658 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
661 , Calc.Balance.Unit_Sum
662 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
663 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -2
664 , Calc.Balance.amount_sum_positive = Just $ Amount.eur $ 2
665 , Calc.Balance.amount_sum_balance = Amount.eur $ 0
667 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
670 , Calc.Balance.Unit_Sum
671 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
672 { Calc.Balance.amount_sum_negative = Just $ Amount.gbp $ -3
673 , Calc.Balance.amount_sum_positive = Just $ Amount.gbp $ 3
674 , Calc.Balance.amount_sum_balance = Amount.gbp $ 0
676 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
682 , "union" ~: TestList
684 Calc.Balance.union Calc.Balance.nil Calc.Balance.nil
686 (Calc.Balance.nil::Calc.Balance.Balance Amount)
687 , "{A+$1, $+1} {A+$1, $+1} = {A+$2, $+2}" ~:
689 (Calc.Balance.Balance
690 { Calc.Balance.balance_by_account =
691 Lib.TreeMap.from_List const $
692 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
693 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
694 , Calc.Balance.balance_by_unit =
696 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
697 [ Calc.Balance.Unit_Sum
698 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
699 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
704 (Calc.Balance.Balance
705 { Calc.Balance.balance_by_account =
706 Lib.TreeMap.from_List const $
707 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
708 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
709 , Calc.Balance.balance_by_unit =
711 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
712 [ Calc.Balance.Unit_Sum
713 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
714 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
721 { Calc.Balance.balance_by_account =
722 Lib.TreeMap.from_List const $
723 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
724 [ ("A":|[], Amount.from_List [ Amount.usd $ 2 ]) ]
725 , Calc.Balance.balance_by_unit =
727 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
728 [ Calc.Balance.Unit_Sum
729 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
730 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
735 , "{A+$1, $+1} {B+$1, $+1} = {A+$1 B+$1, $+2}" ~:
737 (Calc.Balance.Balance
738 { Calc.Balance.balance_by_account =
739 Lib.TreeMap.from_List const $
740 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
741 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
742 , Calc.Balance.balance_by_unit =
744 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
745 [ Calc.Balance.Unit_Sum
746 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
747 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
752 (Calc.Balance.Balance
753 { Calc.Balance.balance_by_account =
754 Lib.TreeMap.from_List const $
755 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
756 [ ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
757 , Calc.Balance.balance_by_unit =
759 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
760 [ Calc.Balance.Unit_Sum
761 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
762 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
769 { Calc.Balance.balance_by_account =
770 Lib.TreeMap.from_List const $
771 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
772 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
773 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
774 , Calc.Balance.balance_by_unit =
776 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
777 [ Calc.Balance.Unit_Sum
778 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
779 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
784 , "{A+$1, $+1} {B+€1, €+1} = {A+$1 B+€1, $+1 €+1}" ~:
786 (Calc.Balance.Balance
787 { Calc.Balance.balance_by_account =
788 Lib.TreeMap.from_List const $
789 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
790 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
791 , Calc.Balance.balance_by_unit =
793 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
794 [ Calc.Balance.Unit_Sum
795 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
796 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
801 (Calc.Balance.Balance
802 { Calc.Balance.balance_by_account =
803 Lib.TreeMap.from_List const $
804 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
805 [ ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
806 , Calc.Balance.balance_by_unit =
808 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
809 [ Calc.Balance.Unit_Sum
810 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
811 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
818 { Calc.Balance.balance_by_account =
819 Lib.TreeMap.from_List const $
820 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
821 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
822 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
823 , Calc.Balance.balance_by_unit =
825 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
826 [ Calc.Balance.Unit_Sum
827 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
828 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
831 , Calc.Balance.Unit_Sum
832 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
833 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
839 , "expanded" ~: TestList
840 [ "nil_By_Account" ~:
841 Calc.Balance.expanded
844 (Lib.TreeMap.empty::Calc.Balance.Expanded Amount)
846 Calc.Balance.expanded
847 (Lib.TreeMap.from_List const $
848 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
849 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ])
851 (Lib.TreeMap.from_List const $
852 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
853 { Calc.Balance.inclusive =
854 Data.Map.map Calc.Balance.amount_sum $
855 Amount.from_List [ Amount.usd $ 1 ]
856 , Calc.Balance.exclusive =
857 Data.Map.map Calc.Balance.amount_sum $
858 Amount.from_List [ Amount.usd $ 1 ]
861 , "A/A+$1 = A+$1 A/A+$1" ~:
862 Calc.Balance.expanded
863 (Lib.TreeMap.from_List const $
864 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
865 [ ("A":|["A"], Amount.from_List [ Amount.usd $ 1 ]) ])
867 (Lib.TreeMap.from_List const
868 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
869 { Calc.Balance.inclusive =
870 Data.Map.map Calc.Balance.amount_sum $
871 Amount.from_List [ Amount.usd $ 1 ]
872 , Calc.Balance.exclusive =
873 Data.Map.map Calc.Balance.amount_sum $
876 , ("A":|["A"], Calc.Balance.Account_Sum_Expanded
877 { Calc.Balance.inclusive =
878 Data.Map.map Calc.Balance.amount_sum $
879 Amount.from_List [ Amount.usd $ 1 ]
880 , Calc.Balance.exclusive =
881 Data.Map.map Calc.Balance.amount_sum $
882 Amount.from_List [ Amount.usd $ 1 ]
885 , "A/B+$1 = A+$1 A/B+$1" ~:
886 Calc.Balance.expanded
887 (Lib.TreeMap.from_List const $
888 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
889 [ ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ]) ])
891 (Lib.TreeMap.from_List const
892 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
893 { Calc.Balance.inclusive =
894 Data.Map.map Calc.Balance.amount_sum $
895 Amount.from_List [ Amount.usd $ 1 ]
896 , Calc.Balance.exclusive =
897 Data.Map.map Calc.Balance.amount_sum $
900 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
901 { Calc.Balance.inclusive =
902 Data.Map.map Calc.Balance.amount_sum $
903 Amount.from_List [ Amount.usd $ 1 ]
904 , Calc.Balance.exclusive =
905 Data.Map.map Calc.Balance.amount_sum $
906 Amount.from_List [ Amount.usd $ 1 ]
909 , "A/B/C+$1 = A+$1 A/B+$1 A/B/C+$1" ~:
910 Calc.Balance.expanded
911 (Lib.TreeMap.from_List const $
912 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
913 [ ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ]) ])
915 (Lib.TreeMap.from_List const $
916 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
917 { Calc.Balance.inclusive =
918 Data.Map.map Calc.Balance.amount_sum $
919 Amount.from_List [ Amount.usd $ 1 ]
920 , Calc.Balance.exclusive =
921 Data.Map.map Calc.Balance.amount_sum $
924 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
925 { Calc.Balance.inclusive =
926 Data.Map.map Calc.Balance.amount_sum $
927 Amount.from_List [ Amount.usd $ 1 ]
928 , Calc.Balance.exclusive =
929 Data.Map.map Calc.Balance.amount_sum $
932 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
933 { Calc.Balance.inclusive =
934 Data.Map.map Calc.Balance.amount_sum $
935 Amount.from_List [ Amount.usd $ 1 ]
936 , Calc.Balance.exclusive =
937 Data.Map.map Calc.Balance.amount_sum $
938 Amount.from_List [ Amount.usd $ 1 ]
941 , "A+$1 A/B+$1 = A+$2 A/B+$1" ~:
942 Calc.Balance.expanded
943 (Lib.TreeMap.from_List const $
944 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
945 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
946 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
949 (Lib.TreeMap.from_List const
950 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
951 { Calc.Balance.inclusive =
952 Data.Map.map Calc.Balance.amount_sum $
953 Amount.from_List [ Amount.usd $ 2 ]
954 , Calc.Balance.exclusive =
955 Data.Map.map Calc.Balance.amount_sum $
956 Amount.from_List [ Amount.usd $ 1 ]
958 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
959 { Calc.Balance.inclusive =
960 Data.Map.map Calc.Balance.amount_sum $
961 Amount.from_List [ Amount.usd $ 1 ]
962 , Calc.Balance.exclusive =
963 Data.Map.map Calc.Balance.amount_sum $
964 Amount.from_List [ Amount.usd $ 1 ]
967 , "A+$1 A/B+$1 A/B/C+$1 = A+$3 A/B+$2 A/B/C+$1" ~:
968 Calc.Balance.expanded
969 (Lib.TreeMap.from_List const $
970 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
971 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
972 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
973 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
976 (Lib.TreeMap.from_List const
977 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
978 { Calc.Balance.inclusive =
979 Data.Map.map Calc.Balance.amount_sum $
980 Amount.from_List [ Amount.usd $ 3 ]
981 , Calc.Balance.exclusive =
982 Data.Map.map Calc.Balance.amount_sum $
983 Amount.from_List [ Amount.usd $ 1 ]
985 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
986 { Calc.Balance.inclusive =
987 Data.Map.map Calc.Balance.amount_sum $
988 Amount.from_List [ Amount.usd $ 2 ]
989 , Calc.Balance.exclusive =
990 Data.Map.map Calc.Balance.amount_sum $
991 Amount.from_List [ Amount.usd $ 1 ]
993 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
994 { Calc.Balance.inclusive =
995 Data.Map.map Calc.Balance.amount_sum $
996 Amount.from_List [ Amount.usd $ 1 ]
997 , Calc.Balance.exclusive =
998 Data.Map.map Calc.Balance.amount_sum $
999 Amount.from_List [ Amount.usd $ 1 ]
1002 , "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" ~:
1003 Calc.Balance.expanded
1004 (Lib.TreeMap.from_List const $
1005 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1006 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1007 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
1008 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
1009 , ("A":|["B", "C", "D"], Amount.from_List [ Amount.usd $ 1 ])
1012 (Lib.TreeMap.from_List const
1013 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
1014 { Calc.Balance.inclusive =
1015 Data.Map.map Calc.Balance.amount_sum $
1016 Amount.from_List [ Amount.usd $ 4 ]
1017 , Calc.Balance.exclusive =
1018 Data.Map.map Calc.Balance.amount_sum $
1019 Amount.from_List [ Amount.usd $ 1 ]
1021 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
1022 { Calc.Balance.inclusive =
1023 Data.Map.map Calc.Balance.amount_sum $
1024 Amount.from_List [ Amount.usd $ 3 ]
1025 , Calc.Balance.exclusive =
1026 Data.Map.map Calc.Balance.amount_sum $
1027 Amount.from_List [ Amount.usd $ 1 ]
1029 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
1030 { Calc.Balance.inclusive =
1031 Data.Map.map Calc.Balance.amount_sum $
1032 Amount.from_List [ Amount.usd $ 2 ]
1033 , Calc.Balance.exclusive =
1034 Data.Map.map Calc.Balance.amount_sum $
1035 Amount.from_List [ Amount.usd $ 1 ]
1037 , ("A":|["B", "C", "D"], Calc.Balance.Account_Sum_Expanded
1038 { Calc.Balance.inclusive =
1039 Data.Map.map Calc.Balance.amount_sum $
1040 Amount.from_List [ Amount.usd $ 1 ]
1041 , Calc.Balance.exclusive =
1042 Data.Map.map Calc.Balance.amount_sum $
1043 Amount.from_List [ Amount.usd $ 1 ]
1046 , "A+$1 A/B+$1 A/BB+$1 AA/B+$1 = A+$3 A/B+$1 A/BB+$1 AA+$1 AA/B+$1" ~:
1047 Calc.Balance.expanded
1048 (Lib.TreeMap.from_List const $
1049 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1050 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1051 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
1052 , ("A":|["BB"], Amount.from_List [ Amount.usd $ 1 ])
1053 , ("AA":|["B"], Amount.from_List [ Amount.usd $ 1 ])
1056 (Lib.TreeMap.from_List const
1057 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
1058 { Calc.Balance.inclusive =
1059 Data.Map.map Calc.Balance.amount_sum $
1060 Amount.from_List [ Amount.usd $ 3 ]
1061 , Calc.Balance.exclusive =
1062 Data.Map.map Calc.Balance.amount_sum $
1063 Amount.from_List [ Amount.usd $ 1 ]
1065 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
1066 { Calc.Balance.inclusive =
1067 Data.Map.map Calc.Balance.amount_sum $
1068 Amount.from_List [ Amount.usd $ 1 ]
1069 , Calc.Balance.exclusive =
1070 Data.Map.map Calc.Balance.amount_sum $
1071 Amount.from_List [ Amount.usd $ 1 ]
1073 , ("A":|["BB"], Calc.Balance.Account_Sum_Expanded
1074 { Calc.Balance.inclusive =
1075 Data.Map.map Calc.Balance.amount_sum $
1076 Amount.from_List [ Amount.usd $ 1 ]
1077 , Calc.Balance.exclusive =
1078 Data.Map.map Calc.Balance.amount_sum $
1079 Amount.from_List [ Amount.usd $ 1 ]
1081 , ("AA":|[], Calc.Balance.Account_Sum_Expanded
1082 { Calc.Balance.inclusive =
1083 Data.Map.map Calc.Balance.amount_sum $
1084 Amount.from_List [ Amount.usd $ 1 ]
1085 , Calc.Balance.exclusive =
1086 Data.Map.map Calc.Balance.amount_sum $
1089 , ("AA":|["B"], Calc.Balance.Account_Sum_Expanded
1090 { Calc.Balance.inclusive =
1091 Data.Map.map Calc.Balance.amount_sum $
1092 Amount.from_List [ Amount.usd $ 1 ]
1093 , Calc.Balance.exclusive =
1094 Data.Map.map Calc.Balance.amount_sum $
1095 Amount.from_List [ Amount.usd $ 1 ]
1099 , "deviation" ~: TestList
1101 (Calc.Balance.deviation $
1102 Calc.Balance.Balance
1103 { Calc.Balance.balance_by_account =
1104 Lib.TreeMap.from_List const $
1105 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1106 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1107 , ("B":|[], Amount.from_List [])
1109 , Calc.Balance.balance_by_unit =
1111 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1112 [ Calc.Balance.Unit_Sum
1113 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1114 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1120 (Calc.Balance.Deviation $
1122 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1123 [ Calc.Balance.Unit_Sum
1124 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1125 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1129 , "{A+$1 B+$1, $2}" ~:
1130 (Calc.Balance.deviation $
1131 Calc.Balance.Balance
1132 { Calc.Balance.balance_by_account =
1133 Lib.TreeMap.from_List const $
1134 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1135 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1136 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ])
1138 , Calc.Balance.balance_by_unit =
1140 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1141 [ Calc.Balance.Unit_Sum
1142 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
1143 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1151 (Calc.Balance.Deviation $
1153 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1154 [ Calc.Balance.Unit_Sum
1155 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
1156 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1162 , "is_equilibrium_inferrable" ~: TestList
1163 [ "nil" ~: TestCase $
1165 Calc.Balance.is_equilibrium_inferrable $
1166 Calc.Balance.deviation $
1167 (Calc.Balance.nil::Calc.Balance.Balance Amount.Amount)
1168 , "{A+$0, $+0}" ~: TestCase $
1170 Calc.Balance.is_equilibrium_inferrable $
1171 Calc.Balance.deviation $
1172 Calc.Balance.Balance
1173 { Calc.Balance.balance_by_account =
1174 Lib.TreeMap.from_List const $
1175 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1176 [ ("A":|[], Amount.from_List [ Amount.usd $ 0 ])
1178 , Calc.Balance.balance_by_unit =
1180 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1181 [ Calc.Balance.Unit_Sum
1182 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1183 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1188 , "{A+$1, $+1}" ~: TestCase $
1190 Calc.Balance.is_equilibrium_inferrable $
1191 Calc.Balance.deviation $
1192 Calc.Balance.Balance
1193 { Calc.Balance.balance_by_account =
1194 Lib.TreeMap.from_List const $
1195 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1196 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1198 , Calc.Balance.balance_by_unit =
1200 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1201 [ Calc.Balance.Unit_Sum
1202 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1203 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1208 , "{A+$0+€0, $0 €+0}" ~: TestCase $
1210 Calc.Balance.is_equilibrium_inferrable $
1211 Calc.Balance.deviation $
1212 Calc.Balance.Balance
1213 { Calc.Balance.balance_by_account =
1214 Lib.TreeMap.from_List const $
1215 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1216 [ ("A":|[], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
1218 , Calc.Balance.balance_by_unit =
1220 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1221 [ Calc.Balance.Unit_Sum
1222 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1223 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1226 , Calc.Balance.Unit_Sum
1227 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 0
1228 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1233 , "{A+$1, B-$1, $+0}" ~: TestCase $
1235 Calc.Balance.is_equilibrium_inferrable $
1236 Calc.Balance.deviation $
1237 Calc.Balance.Balance
1238 { Calc.Balance.balance_by_account =
1239 Lib.TreeMap.from_List const $
1240 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1241 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1242 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
1244 , Calc.Balance.balance_by_unit =
1246 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1247 [ Calc.Balance.Unit_Sum
1248 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1249 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1254 , "{A+$1 B, $+1}" ~: TestCase $
1256 Calc.Balance.is_equilibrium_inferrable $
1257 Calc.Balance.deviation $
1258 Calc.Balance.Balance
1259 { Calc.Balance.balance_by_account =
1260 Lib.TreeMap.from_List const $
1261 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1262 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1263 , ("B":|[], Amount.from_List [])
1265 , Calc.Balance.balance_by_unit =
1267 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1268 [ Calc.Balance.Unit_Sum
1269 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1270 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1275 , "{A+$1 B+€1, $+1 €+1}" ~: TestCase $
1277 Calc.Balance.is_equilibrium_inferrable $
1278 Calc.Balance.deviation $
1279 Calc.Balance.Balance
1280 { Calc.Balance.balance_by_account =
1281 Lib.TreeMap.from_List const $
1282 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1283 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1284 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ])
1286 , Calc.Balance.balance_by_unit =
1288 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1289 [ Calc.Balance.Unit_Sum
1290 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1291 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1294 , Calc.Balance.Unit_Sum
1295 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
1296 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1301 , "{A+$1 B-$1+€1, $+0 €+1}" ~: TestCase $
1303 Calc.Balance.is_equilibrium_inferrable $
1304 Calc.Balance.deviation $
1305 Calc.Balance.Balance
1306 { Calc.Balance.balance_by_account =
1307 Lib.TreeMap.from_List const $
1308 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1309 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1310 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ 1 ])
1312 , Calc.Balance.balance_by_unit =
1314 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1315 [ Calc.Balance.Unit_Sum
1316 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1317 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1320 , Calc.Balance.Unit_Sum
1321 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
1322 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1327 , "{A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~: TestCase $
1329 Calc.Balance.is_equilibrium_inferrable $
1330 Calc.Balance.deviation $
1331 Calc.Balance.Balance
1332 { Calc.Balance.balance_by_account =
1333 Lib.TreeMap.from_List const $
1334 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1335 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
1336 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
1338 , Calc.Balance.balance_by_unit =
1340 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1341 [ Calc.Balance.Unit_Sum
1342 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1343 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1346 , Calc.Balance.Unit_Sum
1347 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 0
1348 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1351 , Calc.Balance.Unit_Sum
1352 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.gbp $ 0
1353 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1359 , "infer_equilibrium" ~: TestList
1361 (snd $ Calc.Balance.infer_equilibrium $
1362 Format.Ledger.posting_by_Account
1363 [ (Format.Ledger.posting ("A":|[]))
1364 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1365 , (Format.Ledger.posting ("B":|[]))
1366 { Format.Ledger.posting_amounts=Amount.from_List [] }
1370 Format.Ledger.posting_by_Account
1371 [ (Format.Ledger.posting ("A":|[]))
1372 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1373 , (Format.Ledger.posting ("B":|[]))
1374 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ] }
1377 (snd $ Calc.Balance.infer_equilibrium $
1378 Format.Ledger.posting_by_Account
1379 [ (Format.Ledger.posting ("A":|[]))
1380 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1381 , (Format.Ledger.posting ("B":|[]))
1382 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1 ] }
1386 Format.Ledger.posting_by_Account
1387 [ (Format.Ledger.posting ("A":|[]))
1388 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 1] }
1389 , (Format.Ledger.posting ("B":|[]))
1390 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1, Amount.usd $ -1 ] }
1393 (snd $ Calc.Balance.infer_equilibrium $
1394 Format.Ledger.posting_by_Account
1395 [ (Format.Ledger.posting ("A":|[]))
1396 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1397 , (Format.Ledger.posting ("B":|[]))
1398 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1402 [ Calc.Balance.Unit_Sum
1403 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
1404 , Calc.Balance.unit_sum_accounts = Data.Map.fromList []}
1406 , "{A+$1 B-$1 B-1€}" ~:
1407 (snd $ Calc.Balance.infer_equilibrium $
1408 Format.Ledger.posting_by_Account
1409 [ (Format.Ledger.posting ("A":|[]))
1410 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1411 , (Format.Ledger.posting ("B":|[]))
1412 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -1 ] }
1416 Format.Ledger.posting_by_Account
1417 [ (Format.Ledger.posting ("A":|[]))
1418 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 1 ] }
1419 , (Format.Ledger.posting ("B":|[]))
1420 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -1 ] }
1425 , "Format" ~: TestList
1426 [ "Ledger" ~: TestList
1427 [ "Read" ~: TestList
1428 [ "account_name" ~: TestList
1430 (Data.Either.rights $
1432 (Format.Ledger.Read.account_name <* P.eof)
1437 (Data.Either.rights $
1439 (Format.Ledger.Read.account_name <* P.eof)
1444 (Data.Either.rights $
1446 (Format.Ledger.Read.account_name <* P.eof)
1447 () "" ("AA"::Text)])
1451 (Data.Either.rights $
1453 (Format.Ledger.Read.account_name <* P.eof)
1458 (Data.Either.rights $
1460 (Format.Ledger.Read.account_name <* P.eof)
1465 (Data.Either.rights $
1467 (Format.Ledger.Read.account_name <* P.eof)
1468 () "" ("A:"::Text)])
1472 (Data.Either.rights $
1474 (Format.Ledger.Read.account_name <* P.eof)
1475 () "" (":A"::Text)])
1479 (Data.Either.rights $
1481 (Format.Ledger.Read.account_name <* P.eof)
1482 () "" ("A "::Text)])
1486 (Data.Either.rights $
1488 (Format.Ledger.Read.account_name)
1489 () "" ("A "::Text)])
1493 (Data.Either.rights $
1495 (Format.Ledger.Read.account_name <* P.eof)
1496 () "" ("A A"::Text)])
1500 (Data.Either.rights $
1502 (Format.Ledger.Read.account_name <* P.eof)
1503 () "" ("A "::Text)])
1507 (Data.Either.rights $
1509 (Format.Ledger.Read.account_name <* P.eof)
1510 () "" ("A \n"::Text)])
1514 (Data.Either.rights $
1516 (Format.Ledger.Read.account_name <* P.eof)
1517 () "" ("(A)A"::Text)])
1521 (Data.Either.rights $
1523 (Format.Ledger.Read.account_name <* P.eof)
1524 () "" ("( )A"::Text)])
1528 (Data.Either.rights $
1530 (Format.Ledger.Read.account_name <* P.eof)
1531 () "" ("(A) A"::Text)])
1535 (Data.Either.rights $
1537 (Format.Ledger.Read.account_name <* P.eof)
1538 () "" ("[ ]A"::Text)])
1542 (Data.Either.rights $
1544 (Format.Ledger.Read.account_name <* P.eof)
1545 () "" ("(A) "::Text)])
1549 (Data.Either.rights $
1551 (Format.Ledger.Read.account_name <* P.eof)
1552 () "" ("(A)"::Text)])
1556 (Data.Either.rights $
1558 (Format.Ledger.Read.account_name <* P.eof)
1559 () "" ("A(A)"::Text)])
1563 (Data.Either.rights $
1565 (Format.Ledger.Read.account_name <* P.eof)
1566 () "" ("[A]A"::Text)])
1570 (Data.Either.rights $
1572 (Format.Ledger.Read.account_name <* P.eof)
1573 () "" ("[A] A"::Text)])
1577 (Data.Either.rights $
1579 (Format.Ledger.Read.account_name <* P.eof)
1580 () "" ("[A] "::Text)])
1584 (Data.Either.rights $
1586 (Format.Ledger.Read.account_name <* P.eof)
1587 () "" ("[A]"::Text)])
1591 , "account" ~: TestList
1593 (Data.Either.rights $
1595 (Format.Ledger.Read.account <* P.eof)
1600 (Data.Either.rights $
1602 (Format.Ledger.Read.account <* P.eof)
1607 (Data.Either.rights $
1609 (Format.Ledger.Read.account <* P.eof)
1610 () "" ("A:"::Text)])
1614 (Data.Either.rights $
1616 (Format.Ledger.Read.account <* P.eof)
1617 () "" (":A"::Text)])
1621 (Data.Either.rights $
1623 (Format.Ledger.Read.account <* P.eof)
1624 () "" ("A "::Text)])
1628 (Data.Either.rights $
1630 (Format.Ledger.Read.account <* P.eof)
1631 () "" (" A"::Text)])
1635 (Data.Either.rights $
1637 (Format.Ledger.Read.account <* P.eof)
1638 () "" ("A:B"::Text)])
1642 (Data.Either.rights $
1644 (Format.Ledger.Read.account <* P.eof)
1645 () "" ("A:B:C"::Text)])
1648 , "\"Aa:Bbb:Cccc\"" ~:
1649 (Data.Either.rights $
1651 (Format.Ledger.Read.account <* P.eof)
1652 () "" ("Aa:Bbb:Cccc"::Text)])
1654 ["Aa":|["Bbb", "Cccc"]]
1655 , "\"A a : B b b : C c c c\"" ~:
1656 (Data.Either.rights $
1658 (Format.Ledger.Read.account <* P.eof)
1659 () "" ("A a : B b b : C c c c"::Text)])
1661 ["A a ":|[" B b b ", " C c c c"]]
1663 (Data.Either.rights $
1665 (Format.Ledger.Read.account <* P.eof)
1666 () "" ("A: :C"::Text)])
1670 (Data.Either.rights $
1672 (Format.Ledger.Read.account <* P.eof)
1673 () "" ("A::C"::Text)])
1677 (Data.Either.rights $
1679 (Format.Ledger.Read.account <* P.eof)
1680 () "" ("A:B:(C)"::Text)])
1684 , "posting_type" ~: TestList
1686 Format.Ledger.Read.posting_type
1689 (Format.Ledger.Posting_Type_Regular, "A":|[])
1691 Format.Ledger.Read.posting_type
1694 (Format.Ledger.Posting_Type_Regular, "(":|[])
1696 Format.Ledger.Read.posting_type
1699 (Format.Ledger.Posting_Type_Regular, ")":|[])
1701 Format.Ledger.Read.posting_type
1704 (Format.Ledger.Posting_Type_Regular, "()":|[])
1706 Format.Ledger.Read.posting_type
1709 (Format.Ledger.Posting_Type_Regular, "( )":|[])
1711 Format.Ledger.Read.posting_type
1714 (Format.Ledger.Posting_Type_Virtual, "A":|[])
1716 Format.Ledger.Read.posting_type
1719 (Format.Ledger.Posting_Type_Virtual, "A":|["B", "C"])
1721 Format.Ledger.Read.posting_type
1724 (Format.Ledger.Posting_Type_Regular, "A":|["B", "C"])
1726 Format.Ledger.Read.posting_type
1729 (Format.Ledger.Posting_Type_Regular, "(A)":|["B", "C"])
1731 Format.Ledger.Read.posting_type
1734 (Format.Ledger.Posting_Type_Regular, "A":|["(B)", "C"])
1736 Format.Ledger.Read.posting_type
1739 (Format.Ledger.Posting_Type_Regular, "A":|["B", "(C)"])
1741 Format.Ledger.Read.posting_type
1744 (Format.Ledger.Posting_Type_Regular, "[":|[])
1746 Format.Ledger.Read.posting_type
1749 (Format.Ledger.Posting_Type_Regular, "]":|[])
1751 Format.Ledger.Read.posting_type
1754 (Format.Ledger.Posting_Type_Regular, "[]":|[])
1756 Format.Ledger.Read.posting_type
1759 (Format.Ledger.Posting_Type_Regular, "[ ]":|[])
1761 Format.Ledger.Read.posting_type
1764 (Format.Ledger.Posting_Type_Virtual_Balanced, "A":|[])
1766 Format.Ledger.Read.posting_type
1769 (Format.Ledger.Posting_Type_Virtual_Balanced, "A":|["B", "C"])
1771 Format.Ledger.Read.posting_type
1774 (Format.Ledger.Posting_Type_Regular, "A":|["B", "C"])
1776 Format.Ledger.Read.posting_type
1779 (Format.Ledger.Posting_Type_Regular, "[A]":|["B", "C"])
1781 Format.Ledger.Read.posting_type
1784 (Format.Ledger.Posting_Type_Regular, "A":|["[B]", "C"])
1786 Format.Ledger.Read.posting_type
1789 (Format.Ledger.Posting_Type_Regular, "A":|["B", "[C]"])
1791 , "amount" ~: TestList
1793 (Data.Either.rights $
1795 (Format.Ledger.Read.amount <* P.eof)
1799 , "\"0\" = Right 0" ~:
1800 (Data.Either.rights $
1802 (Format.Ledger.Read.amount <* P.eof)
1806 { Amount.quantity = Decimal 0 0
1808 , "\"00\" = Right 0" ~:
1809 (Data.Either.rights $
1811 (Format.Ledger.Read.amount <* P.eof)
1812 () "" ("00"::Text)])
1815 { Amount.quantity = Decimal 0 0
1817 , "\"0.\" = Right 0." ~:
1818 (Data.Either.rights $
1820 (Format.Ledger.Read.amount <* P.eof)
1821 () "" ("0."::Text)])
1824 { Amount.quantity = Decimal 0 0
1827 { Amount.Style.fractioning = Just '.'
1830 , "\".0\" = Right 0.0" ~:
1831 (Data.Either.rights $
1833 (Format.Ledger.Read.amount <* P.eof)
1834 () "" (".0"::Text)])
1837 { Amount.quantity = Decimal 0 0
1840 { Amount.Style.fractioning = Just '.'
1841 , Amount.Style.precision = 1
1844 , "\"0,\" = Right 0," ~:
1845 (Data.Either.rights $
1847 (Format.Ledger.Read.amount <* P.eof)
1848 () "" ("0,"::Text)])
1851 { Amount.quantity = Decimal 0 0
1854 { Amount.Style.fractioning = Just ','
1857 , "\",0\" = Right 0,0" ~:
1858 (Data.Either.rights $
1860 (Format.Ledger.Read.amount <* P.eof)
1861 () "" (",0"::Text)])
1864 { Amount.quantity = Decimal 0 0
1867 { Amount.Style.fractioning = Just ','
1868 , Amount.Style.precision = 1
1871 , "\"0_\" = Left" ~:
1872 (Data.Either.rights $
1874 (Format.Ledger.Read.amount <* P.eof)
1875 () "" ("0_"::Text)])
1878 , "\"_0\" = Left" ~:
1879 (Data.Either.rights $
1881 (Format.Ledger.Read.amount <* P.eof)
1882 () "" ("_0"::Text)])
1885 , "\"0.0\" = Right 0.0" ~:
1886 (Data.Either.rights $
1888 (Format.Ledger.Read.amount <* P.eof)
1889 () "" ("0.0"::Text)])
1892 { Amount.quantity = Decimal 0 0
1895 { Amount.Style.fractioning = Just '.'
1896 , Amount.Style.precision = 1
1899 , "\"00.00\" = Right 0.00" ~:
1900 (Data.Either.rights $
1902 (Format.Ledger.Read.amount <* P.eof)
1903 () "" ("00.00"::Text)])
1906 { Amount.quantity = Decimal 0 0
1909 { Amount.Style.fractioning = Just '.'
1910 , Amount.Style.precision = 2
1913 , "\"0,0\" = Right 0,0" ~:
1914 (Data.Either.rights $
1916 (Format.Ledger.Read.amount <* P.eof)
1917 () "" ("0,0"::Text)])
1920 { Amount.quantity = Decimal 0 0
1923 { Amount.Style.fractioning = Just ','
1924 , Amount.Style.precision = 1
1927 , "\"00,00\" = Right 0,00" ~:
1928 (Data.Either.rights $
1930 (Format.Ledger.Read.amount <* P.eof)
1931 () "" ("00,00"::Text)])
1934 { Amount.quantity = Decimal 0 0
1937 { Amount.Style.fractioning = Just ','
1938 , Amount.Style.precision = 2
1941 , "\"0_0\" = Right 0" ~:
1942 (Data.Either.rights $
1944 (Format.Ledger.Read.amount <* P.eof)
1945 () "" ("0_0"::Text)])
1948 { Amount.quantity = Decimal 0 0
1951 { Amount.Style.fractioning = Nothing
1952 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
1953 , Amount.Style.precision = 0
1956 , "\"00_00\" = Right 0" ~:
1957 (Data.Either.rights $
1959 (Format.Ledger.Read.amount <* P.eof)
1960 () "" ("00_00"::Text)])
1963 { Amount.quantity = Decimal 0 0
1966 { Amount.Style.fractioning = Nothing
1967 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
1968 , Amount.Style.precision = 0
1971 , "\"0,000.00\" = Right 0,000.00" ~:
1972 (Data.Either.rights $
1974 (Format.Ledger.Read.amount <* P.eof)
1975 () "" ("0,000.00"::Text)])
1978 { Amount.quantity = Decimal 0 0
1981 { Amount.Style.fractioning = Just '.'
1982 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
1983 , Amount.Style.precision = 2
1986 , "\"0.000,00\" = Right 0.000,00" ~:
1987 (Data.Either.rights $
1989 (Format.Ledger.Read.amount)
1990 () "" ("0.000,00"::Text)])
1993 { Amount.quantity = Decimal 0 0
1996 { Amount.Style.fractioning = Just ','
1997 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
1998 , Amount.Style.precision = 2
2001 , "\"1,000.00\" = Right 1,000.00" ~:
2002 (Data.Either.rights $
2004 (Format.Ledger.Read.amount <* P.eof)
2005 () "" ("1,000.00"::Text)])
2008 { Amount.quantity = Decimal 0 1000
2011 { Amount.Style.fractioning = Just '.'
2012 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
2013 , Amount.Style.precision = 2
2016 , "\"1.000,00\" = Right 1.000,00" ~:
2017 (Data.Either.rights $
2019 (Format.Ledger.Read.amount)
2020 () "" ("1.000,00"::Text)])
2023 { Amount.quantity = Decimal 0 1000
2026 { Amount.Style.fractioning = Just ','
2027 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
2028 , Amount.Style.precision = 2
2031 , "\"1,000.00.\" = Left" ~:
2032 (Data.Either.rights $
2034 (Format.Ledger.Read.amount)
2035 () "" ("1,000.00."::Text)])
2038 , "\"1.000,00,\" = Left" ~:
2039 (Data.Either.rights $
2041 (Format.Ledger.Read.amount)
2042 () "" ("1.000,00,"::Text)])
2045 , "\"1,000.00_\" = Left" ~:
2046 (Data.Either.rights $
2048 (Format.Ledger.Read.amount)
2049 () "" ("1,000.00_"::Text)])
2052 , "\"12\" = Right 12" ~:
2053 (Data.Either.rights $
2055 (Format.Ledger.Read.amount <* P.eof)
2056 () "" ("123"::Text)])
2059 { Amount.quantity = Decimal 0 123
2061 , "\"1.2\" = Right 1.2" ~:
2062 (Data.Either.rights $
2064 (Format.Ledger.Read.amount <* P.eof)
2065 () "" ("1.2"::Text)])
2068 { Amount.quantity = Decimal 1 12
2071 { Amount.Style.fractioning = Just '.'
2072 , Amount.Style.precision = 1
2075 , "\"1,2\" = Right 1,2" ~:
2076 (Data.Either.rights $
2078 (Format.Ledger.Read.amount <* P.eof)
2079 () "" ("1,2"::Text)])
2082 { Amount.quantity = Decimal 1 12
2085 { Amount.Style.fractioning = Just ','
2086 , Amount.Style.precision = 1
2089 , "\"12.23\" = Right 12.23" ~:
2090 (Data.Either.rights $
2092 (Format.Ledger.Read.amount <* P.eof)
2093 () "" ("12.34"::Text)])
2096 { Amount.quantity = Decimal 2 1234
2099 { Amount.Style.fractioning = Just '.'
2100 , Amount.Style.precision = 2
2103 , "\"12,23\" = Right 12,23" ~:
2104 (Data.Either.rights $
2106 (Format.Ledger.Read.amount <* P.eof)
2107 () "" ("12,34"::Text)])
2110 { Amount.quantity = Decimal 2 1234
2113 { Amount.Style.fractioning = Just ','
2114 , Amount.Style.precision = 2
2117 , "\"1_2\" = Right 1_2" ~:
2118 (Data.Either.rights $
2120 (Format.Ledger.Read.amount <* P.eof)
2121 () "" ("1_2"::Text)])
2124 { Amount.quantity = Decimal 0 12
2127 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
2128 , Amount.Style.precision = 0
2131 , "\"1_23\" = Right 1_23" ~:
2132 (Data.Either.rights $
2134 (Format.Ledger.Read.amount <* P.eof)
2135 () "" ("1_23"::Text)])
2138 { Amount.quantity = Decimal 0 123
2141 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
2142 , Amount.Style.precision = 0
2145 , "\"1_23_456\" = Right 1_23_456" ~:
2146 (Data.Either.rights $
2148 (Format.Ledger.Read.amount <* P.eof)
2149 () "" ("1_23_456"::Text)])
2152 { Amount.quantity = Decimal 0 123456
2155 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
2156 , Amount.Style.precision = 0
2159 , "\"1_23_456.7890_12345_678901\" = Right 1_23_456.7890_12345_678901" ~:
2160 (Data.Either.rights $
2162 (Format.Ledger.Read.amount <* P.eof)
2163 () "" ("1_23_456.7890_12345_678901"::Text)])
2166 { Amount.quantity = Decimal 15 123456789012345678901
2169 { Amount.Style.fractioning = Just '.'
2170 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
2171 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [4, 5, 6]
2172 , Amount.Style.precision = 15
2175 , "\"123456_78901_2345.678_90_1\" = Right 123456_78901_2345.678_90_1" ~:
2176 (Data.Either.rights $
2178 (Format.Ledger.Read.amount <* P.eof)
2179 () "" ("123456_78901_2345.678_90_1"::Text)])
2182 { Amount.quantity = Decimal 6 123456789012345678901
2185 { Amount.Style.fractioning = Just '.'
2186 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [4, 5, 6]
2187 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [3, 2]
2188 , Amount.Style.precision = 6
2191 , "\"$1\" = Right $1" ~:
2192 (Data.Either.rights $
2194 (Format.Ledger.Read.amount <* P.eof)
2195 () "" ("$1"::Text)])
2198 { Amount.quantity = Decimal 0 1
2201 { Amount.Style.fractioning = Nothing
2202 , Amount.Style.grouping_integral = Nothing
2203 , Amount.Style.grouping_fractional = Nothing
2204 , Amount.Style.precision = 0
2205 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2206 , Amount.Style.unit_spaced = Just False
2210 , "\"1$\" = Right 1$" ~:
2211 (Data.Either.rights $
2213 (Format.Ledger.Read.amount <* P.eof)
2214 () "" ("1$"::Text)])
2217 { Amount.quantity = Decimal 0 1
2220 { Amount.Style.fractioning = Nothing
2221 , Amount.Style.grouping_integral = Nothing
2222 , Amount.Style.grouping_fractional = Nothing
2223 , Amount.Style.precision = 0
2224 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2225 , Amount.Style.unit_spaced = Just False
2229 , "\"$ 1\" = Right $ 1" ~:
2230 (Data.Either.rights $
2232 (Format.Ledger.Read.amount <* P.eof)
2233 () "" ("$ 1"::Text)])
2236 { Amount.quantity = Decimal 0 1
2239 { Amount.Style.fractioning = Nothing
2240 , Amount.Style.grouping_integral = Nothing
2241 , Amount.Style.grouping_fractional = Nothing
2242 , Amount.Style.precision = 0
2243 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2244 , Amount.Style.unit_spaced = Just True
2248 , "\"1 $\" = Right 1 $" ~:
2249 (Data.Either.rights $
2251 (Format.Ledger.Read.amount <* P.eof)
2252 () "" ("1 $"::Text)])
2255 { Amount.quantity = Decimal 0 1
2258 { Amount.Style.fractioning = Nothing
2259 , Amount.Style.grouping_integral = Nothing
2260 , Amount.Style.grouping_fractional = Nothing
2261 , Amount.Style.precision = 0
2262 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2263 , Amount.Style.unit_spaced = Just True
2267 , "\"-$1\" = Right $-1" ~:
2268 (Data.Either.rights $
2270 (Format.Ledger.Read.amount <* P.eof)
2271 () "" ("-$1"::Text)])
2274 { Amount.quantity = Decimal 0 (-1)
2277 { Amount.Style.fractioning = Nothing
2278 , Amount.Style.grouping_integral = Nothing
2279 , Amount.Style.grouping_fractional = Nothing
2280 , Amount.Style.precision = 0
2281 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2282 , Amount.Style.unit_spaced = Just False
2286 , "\"\\\"4 2\\\"1\" = Right \\\"4 2\\\"1" ~:
2287 (Data.Either.rights $
2289 (Format.Ledger.Read.amount <* P.eof)
2290 () "" ("\"4 2\"1"::Text)])
2293 { Amount.quantity = Decimal 0 1
2296 { Amount.Style.fractioning = Nothing
2297 , Amount.Style.grouping_integral = Nothing
2298 , Amount.Style.grouping_fractional = Nothing
2299 , Amount.Style.precision = 0
2300 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2301 , Amount.Style.unit_spaced = Just False
2303 , Amount.unit = "4 2"
2305 , "\"1\\\"4 2\\\"\" = Right 1\\\"4 2\\\"" ~:
2306 (Data.Either.rights $
2308 (Format.Ledger.Read.amount <* P.eof)
2309 () "" ("1\"4 2\""::Text)])
2312 { Amount.quantity = Decimal 0 1
2315 { Amount.Style.fractioning = Nothing
2316 , Amount.Style.grouping_integral = Nothing
2317 , Amount.Style.grouping_fractional = Nothing
2318 , Amount.Style.precision = 0
2319 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2320 , Amount.Style.unit_spaced = Just False
2322 , Amount.unit = "4 2"
2324 , "\"$1.000,00\" = Right $1.000,00" ~:
2325 (Data.Either.rights $
2327 (Format.Ledger.Read.amount <* P.eof)
2328 () "" ("$1.000,00"::Text)])
2331 { Amount.quantity = Decimal 0 1000
2334 { Amount.Style.fractioning = Just ','
2335 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
2336 , Amount.Style.grouping_fractional = Nothing
2337 , Amount.Style.precision = 2
2338 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2339 , Amount.Style.unit_spaced = Just False
2343 , "\"1.000,00$\" = Right 1.000,00$" ~:
2344 (Data.Either.rights $
2346 (Format.Ledger.Read.amount <* P.eof)
2347 () "" ("1.000,00$"::Text)])
2350 { Amount.quantity = Decimal 0 1000
2353 { Amount.Style.fractioning = Just ','
2354 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
2355 , Amount.Style.grouping_fractional = Nothing
2356 , Amount.Style.precision = 2
2357 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2358 , Amount.Style.unit_spaced = Just False
2363 , "comment" ~: TestList
2364 [ "; some comment = Right \" some comment\"" ~:
2365 (Data.Either.rights $
2367 (Format.Ledger.Read.comment <* P.eof)
2368 () "" ("; some comment"::Text)])
2371 , "; some comment \\n = Right \" some comment \"" ~:
2372 (Data.Either.rights $
2374 (Format.Ledger.Read.comment <* P.newline <* P.eof)
2375 () "" ("; some comment \n"::Text)])
2377 [ " some comment " ]
2378 , "; some comment \\r\\n = Right \" some comment \"" ~:
2379 (Data.Either.rights $
2381 (Format.Ledger.Read.comment <* P.string "\r\n" <* P.eof)
2382 () "" ("; some comment \r\n"::Text)])
2384 [ " some comment " ]
2386 , "comments" ~: TestList
2387 [ "; some comment\\n ; some other comment = Right [\" some comment\", \" some other comment\"]" ~:
2388 (Data.Either.rights $
2390 (Format.Ledger.Read.comments <* P.eof)
2391 () "" ("; some comment\n ; some other comment"::Text)])
2393 [ [" some comment", " some other comment"] ]
2394 , "; some comment \\n = Right \" some comment \"" ~:
2395 (Data.Either.rights $
2397 (Format.Ledger.Read.comments <* P.string "\n" <* P.eof)
2398 () "" ("; some comment \n"::Text)])
2400 [ [" some comment "] ]
2402 , "date" ~: TestList
2404 (Data.Either.rights $
2405 [P.runParser_with_Error
2406 (Date.Read.date id Nothing <* P.eof)
2407 () "" ("2000/01/01"::Text)])
2409 [ Time.zonedTimeToUTC $
2412 (Time.fromGregorian 2000 01 01)
2413 (Time.TimeOfDay 0 0 0))
2415 , "2000/01/01 some text" ~:
2416 (Data.Either.rights $
2417 [P.runParser_with_Error
2418 (Date.Read.date id Nothing)
2419 () "" ("2000/01/01 some text"::Text)])
2421 [ Time.zonedTimeToUTC $
2424 (Time.fromGregorian 2000 01 01)
2425 (Time.TimeOfDay 0 0 0))
2427 , "2000/01/01 12:34" ~:
2428 (Data.Either.rights $
2429 [P.runParser_with_Error
2430 (Date.Read.date id Nothing <* P.eof)
2431 () "" ("2000/01/01 12:34"::Text)])
2433 [ Time.zonedTimeToUTC $
2436 (Time.fromGregorian 2000 01 01)
2437 (Time.TimeOfDay 12 34 0))
2439 , "2000/01/01 12:34:56" ~:
2440 (Data.Either.rights $
2441 [P.runParser_with_Error
2442 (Date.Read.date id Nothing <* P.eof)
2443 () "" ("2000/01/01 12:34:56"::Text)])
2445 [ Time.zonedTimeToUTC $
2448 (Time.fromGregorian 2000 01 01)
2449 (Time.TimeOfDay 12 34 56))
2451 , "2000/01/01 12:34 CET" ~:
2452 (Data.Either.rights $
2453 [P.runParser_with_Error
2454 (Date.Read.date id Nothing <* P.eof)
2455 () "" ("2000/01/01 12:34 CET"::Text)])
2457 [ Time.zonedTimeToUTC $
2460 (Time.fromGregorian 2000 01 01)
2461 (Time.TimeOfDay 12 34 0))
2462 (Time.TimeZone 60 True "CET")]
2463 , "2000/01/01 12:34 +0130" ~:
2464 (Data.Either.rights $
2465 [P.runParser_with_Error
2466 (Date.Read.date id Nothing <* P.eof)
2467 () "" ("2000/01/01 12:34 +0130"::Text)])
2469 [ Time.zonedTimeToUTC $
2472 (Time.fromGregorian 2000 01 01)
2473 (Time.TimeOfDay 12 34 0))
2474 (Time.TimeZone 90 False "+0130")]
2475 , "2000/01/01 12:34:56 CET" ~:
2476 (Data.Either.rights $
2477 [P.runParser_with_Error
2478 (Date.Read.date id Nothing <* P.eof)
2479 () "" ("2000/01/01 12:34:56 CET"::Text)])
2481 [ Time.zonedTimeToUTC $
2484 (Time.fromGregorian 2000 01 01)
2485 (Time.TimeOfDay 12 34 56))
2486 (Time.TimeZone 60 True "CET")]
2488 (Data.Either.rights $
2489 [P.runParser_with_Error
2490 (Date.Read.date id Nothing <* P.eof)
2491 () "" ("2001/02/29"::Text)])
2495 (Data.Either.rights $
2496 [P.runParser_with_Error
2497 (Date.Read.date id (Just 2000) <* P.eof)
2498 () "" ("01/01"::Text)])
2500 [ Time.zonedTimeToUTC $
2503 (Time.fromGregorian 2000 01 01)
2504 (Time.TimeOfDay 0 0 0))
2507 , "tag_value" ~: TestList
2509 (Data.Either.rights $
2511 (Format.Ledger.Read.tag_value <* P.eof)
2516 (Data.Either.rights $
2518 (Format.Ledger.Read.tag_value <* P.char '\n' <* P.eof)
2519 () "" (",\n"::Text)])
2523 (Data.Either.rights $
2525 (Format.Ledger.Read.tag_value <* P.eof)
2526 () "" (",x"::Text)])
2530 (Data.Either.rights $
2532 (Format.Ledger.Read.tag_value <* P.string ",x:" <* P.eof)
2533 () "" (",x:"::Text)])
2537 (Data.Either.rights $
2539 (Format.Ledger.Read.tag_value <* P.string ", n:" <* P.eof)
2540 () "" ("v, v, n:"::Text)])
2546 (Data.Either.rights $
2548 (Format.Ledger.Read.tag <* P.eof)
2549 () "" ("Name:"::Text)])
2553 (Data.Either.rights $
2555 (Format.Ledger.Read.tag <* P.eof)
2556 () "" ("Name:Value"::Text)])
2559 , "Name:Value\\n" ~:
2560 (Data.Either.rights $
2562 (Format.Ledger.Read.tag <* P.string "\n" <* P.eof)
2563 () "" ("Name:Value\n"::Text)])
2567 (Data.Either.rights $
2569 (Format.Ledger.Read.tag <* P.eof)
2570 () "" ("Name:Val ue"::Text)])
2572 [("Name", "Val ue")]
2574 (Data.Either.rights $
2576 (Format.Ledger.Read.tag <* P.eof)
2577 () "" ("Name:,"::Text)])
2581 (Data.Either.rights $
2583 (Format.Ledger.Read.tag <* P.eof)
2584 () "" ("Name:Val,ue"::Text)])
2586 [("Name", "Val,ue")]
2588 (Data.Either.rights $
2590 (Format.Ledger.Read.tag <* P.string ",ue:" <* P.eof)
2591 () "" ("Name:Val,ue:"::Text)])
2595 , "tags" ~: TestList
2597 (Data.Either.rights $
2599 (Format.Ledger.Read.tags <* P.eof)
2600 () "" ("Name:"::Text)])
2607 (Data.Either.rights $
2609 (Format.Ledger.Read.tags <* P.eof)
2610 () "" ("Name:,"::Text)])
2617 (Data.Either.rights $
2619 (Format.Ledger.Read.tags <* P.eof)
2620 () "" ("Name:,Name:"::Text)])
2623 [ ("Name", ["", ""])
2627 (Data.Either.rights $
2629 (Format.Ledger.Read.tags <* P.eof)
2630 () "" ("Name:,Name2:"::Text)])
2637 , "Name: , Name2:" ~:
2638 (Data.Either.rights $
2640 (Format.Ledger.Read.tags <* P.eof)
2641 () "" ("Name: , Name2:"::Text)])
2648 , "Name:,Name2:,Name3:" ~:
2649 (Data.Either.rights $
2651 (Format.Ledger.Read.tags <* P.eof)
2652 () "" ("Name:,Name2:,Name3:"::Text)])
2660 , "Name:Val ue,Name2:V a l u e,Name3:V al ue" ~:
2661 (Data.Either.rights $
2663 (Format.Ledger.Read.tags <* P.eof)
2664 () "" ("Name:Val ue,Name2:V a l u e,Name3:V al ue"::Text)])
2667 [ ("Name", ["Val ue"])
2668 , ("Name2", ["V a l u e"])
2669 , ("Name3", ["V al ue"])
2673 , "posting" ~: TestList
2674 [ " A:B:C = Right A:B:C" ~:
2675 (Data.Either.rights $
2676 [P.runParser_with_Error
2677 (Format.Ledger.Read.posting <* P.eof)
2678 Format.Ledger.Read.nil_Context "" (" A:B:C"::Text)])
2680 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
2681 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2683 , Format.Ledger.Posting_Type_Regular
2686 , " !A:B:C = Right !A:B:C" ~:
2687 (Data.List.map fst $
2688 Data.Either.rights $
2689 [P.runParser_with_Error
2690 (Format.Ledger.Read.posting <* P.eof)
2691 Format.Ledger.Read.nil_Context "" (" !A:B:C"::Text)])
2693 [ (Format.Ledger.posting ("A":|["B", "C"]))
2694 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2695 , Format.Ledger.posting_status = True
2698 , " *A:B:C = Right *A:B:C" ~:
2699 (Data.List.map fst $
2700 Data.Either.rights $
2701 [P.runParser_with_Error
2702 (Format.Ledger.Read.posting <* P.eof)
2703 Format.Ledger.Read.nil_Context "" (" *A:B:C"::Text)])
2705 [ (Format.Ledger.posting ("A":|["B", "C"]))
2706 { Format.Ledger.posting_amounts = Data.Map.fromList []
2707 , Format.Ledger.posting_comments = []
2708 , Format.Ledger.posting_dates = []
2709 , Format.Ledger.posting_status = True
2710 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2711 , Format.Ledger.posting_tags = Data.Map.fromList []
2714 , " A:B:C $1 = Right A:B:C $1" ~:
2715 (Data.List.map fst $
2716 Data.Either.rights $
2717 [P.runParser_with_Error
2718 (Format.Ledger.Read.posting <* P.eof)
2719 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
2721 [ (Format.Ledger.posting ("A":|["B","C $1"]))
2722 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2725 , " A:B:C $1 = Right A:B:C $1" ~:
2726 (Data.List.map fst $
2727 Data.Either.rights $
2728 [P.runParser_with_Error
2729 (Format.Ledger.Read.posting <* P.eof)
2730 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
2732 [ (Format.Ledger.posting ("A":|["B", "C"]))
2733 { Format.Ledger.posting_amounts = Data.Map.fromList
2735 { Amount.quantity = 1
2736 , Amount.style = Amount.Style.nil
2737 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2738 , Amount.Style.unit_spaced = Just False
2743 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2746 , " A:B:C $1 + 1€ = Right A:B:C $1 + 1€" ~:
2747 (Data.List.map fst $
2748 Data.Either.rights $
2749 [P.runParser_with_Error
2750 (Format.Ledger.Read.posting <* P.eof)
2751 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1€"::Text)])
2753 [ (Format.Ledger.posting ("A":|["B", "C"]))
2754 { Format.Ledger.posting_amounts = Data.Map.fromList
2756 { Amount.quantity = 1
2757 , Amount.style = Amount.Style.nil
2758 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2759 , Amount.Style.unit_spaced = Just False
2764 { Amount.quantity = 1
2765 , Amount.style = Amount.Style.nil
2766 { Amount.Style.unit_side = Just Amount.Style.Side_Right
2767 , Amount.Style.unit_spaced = Just False
2772 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2775 , " A:B:C $1 + 1$ = Right A:B:C $2" ~:
2776 (Data.List.map fst $
2777 Data.Either.rights $
2778 [P.runParser_with_Error
2779 (Format.Ledger.Read.posting <* P.eof)
2780 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$"::Text)])
2782 [ (Format.Ledger.posting ("A":|["B", "C"]))
2783 { Format.Ledger.posting_amounts = Data.Map.fromList
2785 { Amount.quantity = 2
2786 , Amount.style = Amount.Style.nil
2787 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2788 , Amount.Style.unit_spaced = Just False
2793 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2796 , " A:B:C $1 + 1$ + 1$ = Right A:B:C $3" ~:
2797 (Data.List.map fst $
2798 Data.Either.rights $
2799 [P.runParser_with_Error
2800 (Format.Ledger.Read.posting <* P.eof)
2801 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$ + 1$"::Text)])
2803 [ (Format.Ledger.posting ("A":|["B", "C"]))
2804 { Format.Ledger.posting_amounts = Data.Map.fromList
2806 { Amount.quantity = 3
2807 , Amount.style = Amount.Style.nil
2808 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2809 , Amount.Style.unit_spaced = Just False
2814 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2817 , " A:B:C ; some comment = Right A:B:C ; some comment" ~:
2818 (Data.List.map fst $
2819 Data.Either.rights $
2820 [P.runParser_with_Error
2821 (Format.Ledger.Read.posting <* P.eof)
2822 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment"::Text)])
2824 [ (Format.Ledger.posting ("A":|["B", "C"]))
2825 { Format.Ledger.posting_amounts = Data.Map.fromList []
2826 , Format.Ledger.posting_comments = [" some comment"]
2827 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2830 , " A:B:C ; some comment\\n ; some other comment = Right A:B:C ; some comment\\n ; some other comment" ~:
2831 (Data.List.map fst $
2832 Data.Either.rights $
2833 [P.runParser_with_Error
2834 (Format.Ledger.Read.posting <* P.eof)
2835 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment\n ; some other comment"::Text)])
2837 [ (Format.Ledger.posting ("A":|["B", "C"]))
2838 { Format.Ledger.posting_amounts = Data.Map.fromList []
2839 , Format.Ledger.posting_comments = [" some comment", " some other comment"]
2840 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2843 , " A:B:C $1 ; some comment = Right A:B:C $1 ; some comment" ~:
2844 (Data.List.map fst $
2845 Data.Either.rights $
2846 [P.runParser_with_Error
2847 (Format.Ledger.Read.posting)
2848 Format.Ledger.Read.nil_Context "" (" A:B:C $1 ; some comment"::Text)])
2850 [ (Format.Ledger.posting ("A":|["B", "C"]))
2851 { Format.Ledger.posting_amounts = Data.Map.fromList
2853 { Amount.quantity = 1
2854 , Amount.style = Amount.Style.nil
2855 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2856 , Amount.Style.unit_spaced = Just False
2861 , Format.Ledger.posting_comments = [" some comment"]
2862 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2865 , " A:B:C ; N:V = Right A:B:C ; N:V" ~:
2866 (Data.List.map fst $
2867 Data.Either.rights $
2868 [P.runParser_with_Error
2869 (Format.Ledger.Read.posting <* P.eof)
2870 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V"::Text)])
2872 [ (Format.Ledger.posting ("A":|["B", "C"]))
2873 { Format.Ledger.posting_comments = [" N:V"]
2874 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2875 , Format.Ledger.posting_tags = Data.Map.fromList
2880 , " A:B:C ; some comment N:V = Right A:B:C ; some comment N:V" ~:
2881 (Data.List.map fst $
2882 Data.Either.rights $
2883 [P.runParser_with_Error
2884 (Format.Ledger.Read.posting <* P.eof)
2885 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V"::Text)])
2887 [ (Format.Ledger.posting ("A":|["B", "C"]))
2888 { Format.Ledger.posting_comments = [" some comment N:V"]
2889 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2890 , Format.Ledger.posting_tags = Data.Map.fromList
2895 , " A:B:C ; some comment N:V v, N2:V2 v2 = Right A:B:C ; some comment N:V v, N2:V2 v2" ~:
2896 (Data.List.map fst $
2897 Data.Either.rights $
2898 [P.runParser_with_Error
2899 (Format.Ledger.Read.posting )
2900 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V v, N2:V2 v2"::Text)])
2902 [ (Format.Ledger.posting ("A":|["B", "C"]))
2903 { Format.Ledger.posting_comments = [" some comment N:V v, N2:V2 v2"]
2904 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2905 , Format.Ledger.posting_tags = Data.Map.fromList
2911 , " A:B:C ; N:V\\n ; N:V2 = Right A:B:C ; N:V\\n ; N:V2" ~:
2912 (Data.List.map fst $
2913 Data.Either.rights $
2914 [P.runParser_with_Error
2915 (Format.Ledger.Read.posting <* P.eof)
2916 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N:V2"::Text)])
2918 [ (Format.Ledger.posting ("A":|["B", "C"]))
2919 { Format.Ledger.posting_comments = [" N:V", " N:V2"]
2920 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2921 , Format.Ledger.posting_tags = Data.Map.fromList
2922 [ ("N", ["V", "V2"])
2926 , " A:B:C ; N:V\\n ; N2:V = Right A:B:C ; N:V\\n ; N2:V" ~:
2927 (Data.List.map fst $
2928 Data.Either.rights $
2929 [P.runParser_with_Error
2930 (Format.Ledger.Read.posting <* P.eof)
2931 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N2:V"::Text)])
2933 [ (Format.Ledger.posting ("A":|["B", "C"]))
2934 { Format.Ledger.posting_comments = [" N:V", " N2:V"]
2935 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2936 , Format.Ledger.posting_tags = Data.Map.fromList
2942 , " A:B:C ; date:2001/01/01 = Right A:B:C ; date:2001/01/01" ~:
2943 (Data.List.map fst $
2944 Data.Either.rights $
2945 [P.runParser_with_Error
2946 (Format.Ledger.Read.posting <* P.eof)
2947 Format.Ledger.Read.nil_Context "" (" A:B:C ; date:2001/01/01"::Text)])
2949 [ (Format.Ledger.posting ("A":|["B", "C"]))
2950 { Format.Ledger.posting_comments = [" date:2001/01/01"]
2951 , Format.Ledger.posting_dates =
2952 [ Time.zonedTimeToUTC $
2955 (Time.fromGregorian 2001 01 01)
2956 (Time.TimeOfDay 0 0 0))
2959 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2960 , Format.Ledger.posting_tags = Data.Map.fromList
2961 [ ("date", ["2001/01/01"])
2965 , " (A:B:C) = Right (A:B:C)" ~:
2966 (Data.Either.rights $
2967 [P.runParser_with_Error
2968 (Format.Ledger.Read.posting <* P.eof)
2969 Format.Ledger.Read.nil_Context "" (" (A:B:C)"::Text)])
2971 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
2972 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2974 , Format.Ledger.Posting_Type_Virtual
2977 , " [A:B:C] = Right [A:B:C]" ~:
2978 (Data.Either.rights $
2979 [P.runParser_with_Error
2980 (Format.Ledger.Read.posting <* P.eof)
2981 Format.Ledger.Read.nil_Context "" (" [A:B:C]"::Text)])
2983 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
2984 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2986 , Format.Ledger.Posting_Type_Virtual_Balanced
2990 , "transaction" ~: TestList
2991 [ "2000/01/01 some description\\n A:B:C $1\\n a:b:c" ~:
2992 (Data.Either.rights $
2993 [P.runParser_with_Error
2994 (Format.Ledger.Read.transaction <* P.eof)
2995 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c"::Text)])
2997 [ Format.Ledger.transaction
2998 { Format.Ledger.transaction_dates=
2999 ( Time.zonedTimeToUTC $
3002 (Time.fromGregorian 2000 01 01)
3003 (Time.TimeOfDay 0 0 0))
3006 , Format.Ledger.transaction_description="some description"
3007 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3008 [ (Format.Ledger.posting ("A":|["B", "C"]))
3009 { Format.Ledger.posting_amounts = Data.Map.fromList
3011 { Amount.quantity = 1
3012 , Amount.style = Amount.Style.nil
3013 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3014 , Amount.Style.unit_spaced = Just False
3019 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3021 , (Format.Ledger.posting ("a":|["b", "c"]))
3022 { Format.Ledger.posting_amounts = Data.Map.fromList
3024 { Amount.quantity = -1
3025 , Amount.style = Amount.Style.nil
3026 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3027 , Amount.Style.unit_spaced = Just False
3032 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3035 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3038 , "2000/01/01 some description\\n A:B:C $1\\n a:b:c\\n" ~:
3039 (Data.Either.rights $
3040 [P.runParser_with_Error
3041 (Format.Ledger.Read.transaction <* P.newline <* P.eof)
3042 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c\n"::Text)])
3044 [ Format.Ledger.transaction
3045 { Format.Ledger.transaction_dates=
3046 ( Time.zonedTimeToUTC $
3049 (Time.fromGregorian 2000 01 01)
3050 (Time.TimeOfDay 0 0 0))
3053 , Format.Ledger.transaction_description="some description"
3054 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3055 [ (Format.Ledger.posting ("A":|["B", "C"]))
3056 { Format.Ledger.posting_amounts = Data.Map.fromList
3058 { Amount.quantity = 1
3059 , Amount.style = Amount.Style.nil
3060 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3061 , Amount.Style.unit_spaced = Just False
3066 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3068 , (Format.Ledger.posting ("a":|["b", "c"]))
3069 { Format.Ledger.posting_amounts = Data.Map.fromList
3071 { Amount.quantity = -1
3072 , Amount.style = Amount.Style.nil
3073 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3074 , Amount.Style.unit_spaced = Just False
3079 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3082 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3085 , "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" ~:
3086 (Data.Either.rights $
3087 [P.runParser_with_Error
3088 (Format.Ledger.Read.transaction <* P.eof)
3089 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)])
3091 [ Format.Ledger.transaction
3092 { Format.Ledger.transaction_comments_after =
3094 , " some other;comment"
3096 , " some last comment"
3098 , Format.Ledger.transaction_dates=
3099 ( Time.zonedTimeToUTC $
3102 (Time.fromGregorian 2000 01 01)
3103 (Time.TimeOfDay 0 0 0))
3106 , Format.Ledger.transaction_description="some description"
3107 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3108 [ (Format.Ledger.posting ("A":|["B", "C"]))
3109 { Format.Ledger.posting_amounts = Data.Map.fromList
3111 { Amount.quantity = 1
3112 , Amount.style = Amount.Style.nil
3113 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3114 , Amount.Style.unit_spaced = Just False
3119 , Format.Ledger.posting_sourcepos = P.newPos "" 5 1
3121 , (Format.Ledger.posting ("a":|["b", "c"]))
3122 { Format.Ledger.posting_amounts = Data.Map.fromList
3124 { Amount.quantity = -1
3125 , Amount.style = Amount.Style.nil
3126 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3127 , Amount.Style.unit_spaced = Just False
3132 , Format.Ledger.posting_sourcepos = P.newPos "" 6 1
3135 , Format.Ledger.transaction_tags = Data.Map.fromList
3138 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3142 , "journal" ~: TestList
3143 [ "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
3145 P.runParserT_with_Error
3146 (Format.Ledger.Read.journal "" {-<* P.eof-})
3147 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)
3149 (\j -> j{Format.Ledger.journal_last_read_time=
3150 Format.Ledger.journal_last_read_time Format.Ledger.journal}) $
3151 Data.Either.rights [jnl])
3153 [ Format.Ledger.journal
3154 { Format.Ledger.journal_transactions =
3155 Format.Ledger.transaction_by_Date
3156 [ Format.Ledger.transaction
3157 { Format.Ledger.transaction_dates=
3158 ( Time.zonedTimeToUTC $
3161 (Time.fromGregorian 2000 01 01)
3162 (Time.TimeOfDay 0 0 0))
3165 , Format.Ledger.transaction_description="1° description"
3166 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3167 [ (Format.Ledger.posting ("A":|["B", "C"]))
3168 { Format.Ledger.posting_amounts = Data.Map.fromList
3170 { Amount.quantity = 1
3171 , Amount.style = Amount.Style.nil
3172 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3173 , Amount.Style.unit_spaced = Just False
3178 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3180 , (Format.Ledger.posting ("a":|["b", "c"]))
3181 { Format.Ledger.posting_amounts = Data.Map.fromList
3183 { Amount.quantity = -1
3184 , Amount.style = Amount.Style.nil
3185 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3186 , Amount.Style.unit_spaced = Just False
3191 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3194 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3196 , Format.Ledger.transaction
3197 { Format.Ledger.transaction_dates=
3198 ( Time.zonedTimeToUTC $
3201 (Time.fromGregorian 2000 01 02)
3202 (Time.TimeOfDay 0 0 0))
3205 , Format.Ledger.transaction_description="2° description"
3206 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3207 [ (Format.Ledger.posting ("A":|["B", "C"]))
3208 { Format.Ledger.posting_amounts = Data.Map.fromList
3210 { Amount.quantity = 1
3211 , Amount.style = Amount.Style.nil
3212 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3213 , Amount.Style.unit_spaced = Just False
3218 , Format.Ledger.posting_sourcepos = P.newPos "" 5 1
3220 , (Format.Ledger.posting ("x":|["y", "z"]))
3221 { Format.Ledger.posting_amounts = Data.Map.fromList
3223 { Amount.quantity = -1
3224 , Amount.style = Amount.Style.nil
3225 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3226 , Amount.Style.unit_spaced = Just False
3231 , Format.Ledger.posting_sourcepos = P.newPos "" 6 1
3234 , Format.Ledger.transaction_sourcepos = P.newPos "" 4 1
3241 , "Write" ~: TestList
3242 [ "account" ~: TestList
3244 ((Format.Ledger.Write.show
3245 Format.Ledger.Write.Style
3246 { Format.Ledger.Write.style_color=False
3247 , Format.Ledger.Write.style_align=True
3249 Format.Ledger.Write.account Format.Ledger.Posting_Type_Regular $
3254 ((Format.Ledger.Write.show
3255 Format.Ledger.Write.Style
3256 { Format.Ledger.Write.style_color=False
3257 , Format.Ledger.Write.style_align=True
3259 Format.Ledger.Write.account Format.Ledger.Posting_Type_Regular $
3264 ((Format.Ledger.Write.show
3265 Format.Ledger.Write.Style
3266 { Format.Ledger.Write.style_color=False
3267 , Format.Ledger.Write.style_align=True
3269 Format.Ledger.Write.account Format.Ledger.Posting_Type_Virtual $
3274 ((Format.Ledger.Write.show
3275 Format.Ledger.Write.Style
3276 { Format.Ledger.Write.style_color=False
3277 , Format.Ledger.Write.style_align=True
3279 Format.Ledger.Write.account Format.Ledger.Posting_Type_Virtual_Balanced $
3284 , "amount" ~: TestList
3286 ((Format.Ledger.Write.show
3287 Format.Ledger.Write.Style
3288 { Format.Ledger.Write.style_color=False
3289 , Format.Ledger.Write.style_align=True
3291 Format.Ledger.Write.amount
3296 ((Format.Ledger.Write.show
3297 Format.Ledger.Write.Style
3298 { Format.Ledger.Write.style_color=False
3299 , Format.Ledger.Write.style_align=True
3301 Format.Ledger.Write.amount
3303 { Amount.style = Amount.Style.nil
3304 { Amount.Style.precision = 2 }
3309 ((Format.Ledger.Write.show
3310 Format.Ledger.Write.Style
3311 { Format.Ledger.Write.style_color=False
3312 , Format.Ledger.Write.style_align=True
3314 Format.Ledger.Write.amount
3316 { Amount.quantity = Decimal 0 123
3321 ((Format.Ledger.Write.show
3322 Format.Ledger.Write.Style
3323 { Format.Ledger.Write.style_color=False
3324 , Format.Ledger.Write.style_align=True
3326 Format.Ledger.Write.amount
3328 { Amount.quantity = Decimal 0 (- 123)
3332 , "12.3 @ prec=0" ~:
3333 ((Format.Ledger.Write.show
3334 Format.Ledger.Write.Style
3335 { Format.Ledger.Write.style_color=False
3336 , Format.Ledger.Write.style_align=True
3338 Format.Ledger.Write.amount
3340 { Amount.quantity = Decimal 1 123
3341 , Amount.style = Amount.Style.nil
3342 { Amount.Style.fractioning = Just '.'
3347 , "12.5 @ prec=0" ~:
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.amount
3355 { Amount.quantity = Decimal 1 125
3356 , Amount.style = Amount.Style.nil
3357 { Amount.Style.fractioning = Just '.'
3362 , "12.3 @ prec=1" ~:
3363 ((Format.Ledger.Write.show
3364 Format.Ledger.Write.Style
3365 { Format.Ledger.Write.style_color=False
3366 , Format.Ledger.Write.style_align=True
3368 Format.Ledger.Write.amount
3370 { Amount.quantity = Decimal 1 123
3371 , Amount.style = Amount.Style.nil
3372 { Amount.Style.fractioning = Just '.'
3373 , Amount.Style.precision = 1
3378 , "1,234.56 @ prec=2" ~:
3379 ((Format.Ledger.Write.show
3380 Format.Ledger.Write.Style
3381 { Format.Ledger.Write.style_color=False
3382 , Format.Ledger.Write.style_align=True
3384 Format.Ledger.Write.amount
3386 { Amount.quantity = Decimal 2 123456
3387 , Amount.style = Amount.Style.nil
3388 { Amount.Style.fractioning = Just '.'
3389 , Amount.Style.precision = 2
3390 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
3395 , "123,456,789,01,2.3456789 @ prec=7" ~:
3396 ((Format.Ledger.Write.show
3397 Format.Ledger.Write.Style
3398 { Format.Ledger.Write.style_color=False
3399 , Format.Ledger.Write.style_align=True
3401 Format.Ledger.Write.amount
3403 { Amount.quantity = Decimal 7 1234567890123456789
3404 , Amount.style = Amount.Style.nil
3405 { Amount.Style.fractioning = Just '.'
3406 , Amount.Style.precision = 7
3407 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3411 "123,456,789,01,2.3456789")
3412 , "1234567.8,90,123,456,789 @ prec=12" ~:
3413 ((Format.Ledger.Write.show
3414 Format.Ledger.Write.Style
3415 { Format.Ledger.Write.style_color=False
3416 , Format.Ledger.Write.style_align=True
3418 Format.Ledger.Write.amount
3420 { Amount.quantity = Decimal 12 1234567890123456789
3421 , Amount.style = Amount.Style.nil
3422 { Amount.Style.fractioning = Just '.'
3423 , Amount.Style.precision = 12
3424 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3428 "1234567.8,90,123,456,789")
3429 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
3430 ((Format.Ledger.Write.show
3431 Format.Ledger.Write.Style
3432 { Format.Ledger.Write.style_color=False
3433 , Format.Ledger.Write.style_align=True
3435 Format.Ledger.Write.amount
3437 { Amount.quantity = Decimal 7 1234567890123456789
3438 , Amount.style = Amount.Style.nil
3439 { Amount.Style.fractioning = Just '.'
3440 , Amount.Style.precision = 7
3441 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3445 "1,2,3,4,5,6,7,89,012.3456789")
3446 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
3447 ((Format.Ledger.Write.show
3448 Format.Ledger.Write.Style
3449 { Format.Ledger.Write.style_color=False
3450 , Format.Ledger.Write.style_align=True
3452 Format.Ledger.Write.amount
3454 { Amount.quantity = Decimal 12 1234567890123456789
3455 , Amount.style = Amount.Style.nil
3456 { Amount.Style.fractioning = Just '.'
3457 , Amount.Style.precision = 12
3458 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3462 "1234567.890,12,3,4,5,6,7,8,9")
3464 , "amount_length" ~: TestList
3466 ((Format.Ledger.Write.amount_length
3471 ((Format.Ledger.Write.amount_length
3473 { Amount.style = Amount.Style.nil
3474 { Amount.Style.precision = 2 }
3479 ((Format.Ledger.Write.amount_length
3481 { Amount.quantity = Decimal 0 123
3486 ((Format.Ledger.Write.amount_length
3488 { Amount.quantity = Decimal 0 (- 123)
3492 , "12.3 @ prec=0" ~:
3493 ((Format.Ledger.Write.amount_length
3495 { Amount.quantity = Decimal 1 123
3496 , Amount.style = Amount.Style.nil
3497 { Amount.Style.fractioning = Just '.'
3502 , "12.5 @ prec=0" ~:
3503 ((Format.Ledger.Write.amount_length
3505 { Amount.quantity = Decimal 1 125
3506 , Amount.style = Amount.Style.nil
3507 { Amount.Style.fractioning = Just '.'
3512 , "12.3 @ prec=1" ~:
3513 ((Format.Ledger.Write.amount_length
3515 { Amount.quantity = Decimal 1 123
3516 , Amount.style = Amount.Style.nil
3517 { Amount.Style.fractioning = Just '.'
3518 , Amount.Style.precision = 1
3523 , "1,234.56 @ prec=2" ~:
3524 ((Format.Ledger.Write.amount_length
3526 { Amount.quantity = Decimal 2 123456
3527 , Amount.style = Amount.Style.nil
3528 { Amount.Style.fractioning = Just '.'
3529 , Amount.Style.precision = 2
3530 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
3535 , "123,456,789,01,2.3456789 @ prec=7" ~:
3536 ((Format.Ledger.Write.amount_length
3538 { Amount.quantity = Decimal 7 1234567890123456789
3539 , Amount.style = Amount.Style.nil
3540 { Amount.Style.fractioning = Just '.'
3541 , Amount.Style.precision = 7
3542 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3547 , "1234567.8,90,123,456,789 @ prec=12" ~:
3548 ((Format.Ledger.Write.amount_length
3550 { Amount.quantity = Decimal 12 1234567890123456789
3551 , Amount.style = Amount.Style.nil
3552 { Amount.Style.fractioning = Just '.'
3553 , Amount.Style.precision = 12
3554 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3559 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
3560 ((Format.Ledger.Write.amount_length
3562 { Amount.quantity = Decimal 7 1234567890123456789
3563 , Amount.style = Amount.Style.nil
3564 { Amount.Style.fractioning = Just '.'
3565 , Amount.Style.precision = 7
3566 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3571 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
3572 ((Format.Ledger.Write.amount_length
3574 { Amount.quantity = Decimal 12 1234567890123456789
3575 , Amount.style = Amount.Style.nil
3576 { Amount.Style.fractioning = Just '.'
3577 , Amount.Style.precision = 12
3578 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3583 , "1000000.000,00,0,0,0,0,0,0,0 @ prec=12" ~:
3584 ((Format.Ledger.Write.amount_length
3586 { Amount.quantity = Decimal 12 1000000000000000000
3587 , Amount.style = Amount.Style.nil
3588 { Amount.Style.fractioning = Just '.'
3589 , Amount.Style.precision = 12
3590 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3596 ((Format.Ledger.Write.amount_length $
3598 { Amount.quantity = Decimal 0 999
3599 , Amount.style = Amount.Style.nil
3600 { Amount.Style.precision = 0
3605 , "1000 @ prec=0" ~:
3606 ((Format.Ledger.Write.amount_length $
3608 { Amount.quantity = Decimal 0 1000
3609 , Amount.style = Amount.Style.nil
3610 { Amount.Style.precision = 0
3615 , "10,00€ @ prec=2" ~:
3616 ((Format.Ledger.Write.amount_length $ Amount.eur 10)
3620 , "date" ~: TestList
3622 ((Format.Ledger.Write.show
3623 Format.Ledger.Write.Style
3624 { Format.Ledger.Write.style_color=False
3625 , Format.Ledger.Write.style_align=True
3627 Format.Ledger.Write.date
3631 , "2000/01/01 12:34:51 CET" ~:
3632 (Format.Ledger.Write.show
3633 Format.Ledger.Write.Style
3634 { Format.Ledger.Write.style_color=False
3635 , Format.Ledger.Write.style_align=True
3637 Format.Ledger.Write.date $
3638 Time.zonedTimeToUTC $
3641 (Time.fromGregorian 2000 01 01)
3642 (Time.TimeOfDay 12 34 51))
3643 (Time.TimeZone 60 False "CET"))
3645 "2000/01/01 11:34:51"
3646 , "2000/01/01 12:34:51 +0100" ~:
3647 (Format.Ledger.Write.show
3648 Format.Ledger.Write.Style
3649 { Format.Ledger.Write.style_color=False
3650 , Format.Ledger.Write.style_align=True
3652 Format.Ledger.Write.date $
3653 Time.zonedTimeToUTC $
3656 (Time.fromGregorian 2000 01 01)
3657 (Time.TimeOfDay 12 34 51))
3658 (Time.TimeZone 60 False ""))
3660 "2000/01/01 11:34:51"
3661 , "2000/01/01 01:02:03" ~:
3662 (Format.Ledger.Write.show
3663 Format.Ledger.Write.Style
3664 { Format.Ledger.Write.style_color=False
3665 , Format.Ledger.Write.style_align=True
3667 Format.Ledger.Write.date $
3668 Time.zonedTimeToUTC $
3671 (Time.fromGregorian 2000 01 01)
3672 (Time.TimeOfDay 1 2 3))
3675 "2000/01/01 01:02:03"
3677 (Format.Ledger.Write.show
3678 Format.Ledger.Write.Style
3679 { Format.Ledger.Write.style_color=False
3680 , Format.Ledger.Write.style_align=True
3682 Format.Ledger.Write.date $
3683 Time.zonedTimeToUTC $
3686 (Time.fromGregorian 0 01 01)
3687 (Time.TimeOfDay 1 2 0))
3692 (Format.Ledger.Write.show
3693 Format.Ledger.Write.Style
3694 { Format.Ledger.Write.style_color=False
3695 , Format.Ledger.Write.style_align=True
3697 Format.Ledger.Write.date $
3698 Time.zonedTimeToUTC $
3701 (Time.fromGregorian 0 01 01)
3702 (Time.TimeOfDay 1 0 0))
3707 (Format.Ledger.Write.show
3708 Format.Ledger.Write.Style
3709 { Format.Ledger.Write.style_color=False
3710 , Format.Ledger.Write.style_align=True
3712 Format.Ledger.Write.date $
3713 Time.zonedTimeToUTC $
3716 (Time.fromGregorian 0 01 01)
3717 (Time.TimeOfDay 0 1 0))
3722 (Format.Ledger.Write.show
3723 Format.Ledger.Write.Style
3724 { Format.Ledger.Write.style_color=False
3725 , Format.Ledger.Write.style_align=True
3727 Format.Ledger.Write.date $
3728 Time.zonedTimeToUTC $
3731 (Time.fromGregorian 0 01 01)
3732 (Time.TimeOfDay 0 0 0))
3737 , "transaction" ~: TestList
3739 ((Format.Ledger.Write.show
3740 Format.Ledger.Write.Style
3741 { Format.Ledger.Write.style_color=False
3742 , Format.Ledger.Write.style_align=True
3744 Format.Ledger.Write.transaction
3745 Format.Ledger.transaction)
3748 , "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" ~:
3749 ((Format.Ledger.Write.show
3750 Format.Ledger.Write.Style
3751 { Format.Ledger.Write.style_color=False
3752 , Format.Ledger.Write.style_align=True
3754 Format.Ledger.Write.transaction $
3755 Format.Ledger.transaction
3756 { Format.Ledger.transaction_dates=
3757 ( Time.zonedTimeToUTC $
3760 (Time.fromGregorian 2000 01 01)
3761 (Time.TimeOfDay 0 0 0))
3764 , Format.Ledger.transaction_description="some description"
3765 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3766 [ (Format.Ledger.posting ("A":|["B", "C"]))
3767 { Format.Ledger.posting_amounts = Data.Map.fromList
3769 { Amount.quantity = 1
3770 , Amount.style = Amount.Style.nil
3771 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3772 , Amount.Style.unit_spaced = Just False
3778 , (Format.Ledger.posting ("a":|["b", "c"]))
3779 { Format.Ledger.posting_comments = ["first comment","second comment","third comment"]
3784 "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")
3785 , "2000/01/01 some description\\n\\tA:B:C $1\\n\\tAA:BB:CC $123" ~:
3786 ((Format.Ledger.Write.show
3787 Format.Ledger.Write.Style
3788 { Format.Ledger.Write.style_color=False
3789 , Format.Ledger.Write.style_align=True
3791 Format.Ledger.Write.transaction $
3792 Format.Ledger.transaction
3793 { Format.Ledger.transaction_dates=
3794 ( Time.zonedTimeToUTC $
3797 (Time.fromGregorian 2000 01 01)
3798 (Time.TimeOfDay 0 0 0))
3801 , Format.Ledger.transaction_description="some description"
3802 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3803 [ (Format.Ledger.posting ("A":|["B", "C"]))
3804 { Format.Ledger.posting_amounts = Data.Map.fromList
3806 { Amount.quantity = 1
3807 , Amount.style = Amount.Style.nil
3808 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3809 , Amount.Style.unit_spaced = Just False
3815 , (Format.Ledger.posting ("AA":|["BB", "CC"]))
3816 { Format.Ledger.posting_amounts = Data.Map.fromList
3818 { Amount.quantity = 123
3819 , Amount.style = Amount.Style.nil
3820 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3821 , Amount.Style.unit_spaced = Just False
3830 "2000/01/01 some description\n\tA:B:C $1\n\tAA:BB:CC $123")