1 {-# LANGUAGE OverloadedStrings #-}
2 {-# LANGUAGE TupleSections #-}
5 import Test.HUnit hiding ((~?))
6 import Test.Framework.Providers.HUnit (hUnitTestToTests)
7 import Test.Framework.Runners.Console (defaultMain)
9 import Control.Applicative ((<*))
10 import Control.Arrow ((***))
11 import Control.Monad.IO.Class (liftIO)
12 import Data.Decimal (DecimalRaw(..))
13 import qualified Data.Either
14 import qualified Data.List
15 import Data.List.NonEmpty (NonEmpty(..))
16 import qualified Data.Map.Strict as Data.Map
17 import Data.Text (Text)
18 import qualified Data.Time.Calendar as Time
19 import qualified Data.Time.LocalTime as Time
20 import qualified Text.Parsec as P hiding (char, string, space)
21 import qualified Text.Parsec.Pos as P
22 -- import qualified Text.PrettyPrint.Leijen.Text as PP
24 import qualified Hcompta.Model.Account as Account
25 import Hcompta.Model.Account (Account)
26 import qualified Hcompta.Model.Amount as Amount
27 import Hcompta.Model.Amount (Amount)
28 import qualified Hcompta.Model.Amount.Style as Amount.Style
29 import qualified Hcompta.Model.Date as Date
30 import qualified Hcompta.Model.Filter as Filter
31 import qualified Hcompta.Model.Filter.Read as Filter.Read
32 import qualified Hcompta.Calc.Balance as Calc.Balance
33 import qualified Hcompta.Format.Ledger as Format.Ledger
34 import qualified Hcompta.Format.Ledger.Read as Format.Ledger.Read
35 import qualified Hcompta.Format.Ledger.Write as Format.Ledger.Write
36 import qualified Hcompta.Lib.TreeMap as Lib.TreeMap
37 import qualified Hcompta.Lib.Parsec as P
38 import qualified Hcompta.Lib.Foldable as Lib.Foldable
41 main = defaultMain $ hUnitTestToTests test_Hcompta
43 (~?) :: String -> Bool -> Test
44 (~?) s b = s ~: (b ~?= True)
50 [ "TreeMap" ~: TestList
51 [ "insert" ~: TestList
53 (Lib.TreeMap.insert const ((0::Int):|[]) () Lib.TreeMap.empty)
55 (Lib.TreeMap.TreeMap $
57 [ ((0::Int), Lib.TreeMap.leaf ())
60 (Lib.TreeMap.insert const ((0::Int):|1:[]) () Lib.TreeMap.empty)
62 (Lib.TreeMap.TreeMap $
64 [ ((0::Int), Lib.TreeMap.Node
65 { Lib.TreeMap.node_value = Nothing
66 , Lib.TreeMap.node_size = 1
67 , Lib.TreeMap.node_descendants =
68 Lib.TreeMap.singleton ((1::Int):|[]) ()
75 , "map_by_depth_first" ~: TestList
78 , "flatten" ~: TestList
79 [ "[0, 0/1, 0/1/2]" ~:
80 (Lib.TreeMap.flatten id $
81 Lib.TreeMap.from_List const
82 [ (((0::Integer):|[]), ())
93 , "[1, 1/2, 1/22, 1/2/3, 1/2/33, 11, 11/2, 11/2/3, 11/2/33]" ~:
94 (Lib.TreeMap.flatten id $
95 Lib.TreeMap.from_List const
104 , ((11:|2:33:[]), ())
109 [ (((1::Integer):|[]), ())
117 , ((11:|2:33:[]), ())
121 , "Foldable" ~: TestList
122 [ "accumLeftsAndFoldrRights" ~: TestList
124 (Lib.Foldable.accumLeftsAndFoldrRights (++) [""] $
127 (([(0::Integer)], [(""::String)]))
129 ((take 1 *** take 0) $
130 Lib.Foldable.accumLeftsAndFoldrRights (++) [""] $
131 ( repeat (Left [0]) ))
133 ([(0::Integer)], ([]::[String]))
134 , "Right:Left:Right:Left" ~:
135 (Lib.Foldable.accumLeftsAndFoldrRights (++) ["0"] $
136 ( Right ["2"]:Left [1]:Right ["1"]:Left [0]:[] ))
138 (([1, 0]::[Integer]), (["2", "1", "0"]::[String]))
139 , "Right:Left:Right:repeat Left" ~:
140 ((take 1 *** take 2) $
141 Lib.Foldable.accumLeftsAndFoldrRights (++) ["0"] $
142 ( Right ["2"]:Left [1]:Right ["1"]:repeat (Left [0]) ))
144 (([1]::[Integer]), (["2", "1"]::[String]))
148 , "Model" ~: TestList
149 [ "Account" ~: TestList
150 [ "foldr" ~: TestList
152 (reverse $ Account.foldr ("A":|[]) (:) []) ~?= ["A":|[]]
154 (reverse $ Account.foldr ("A":|["B"]) (:) []) ~?= ["A":|[], "A":|["B"]]
156 (reverse $ Account.foldr ("A":|["B", "C"]) (:) []) ~?= ["A":|[], "A":|["B"], "A":|["B", "C"]]
158 , "ascending" ~: TestList
160 Account.ascending ("A":|[]) ~?= Nothing
162 Account.ascending ("A":|["B"]) ~?= Just ("A":|[])
164 Account.ascending ("A":|["B", "C"]) ~?= Just ("A":|["B"])
167 , "Amount" ~: TestList
172 { Amount.quantity = Decimal 0 1
173 , Amount.style = Amount.Style.nil
174 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
179 { Amount.quantity = Decimal 0 1
180 , Amount.style = Amount.Style.nil
181 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
187 { Amount.quantity = Decimal 0 2
188 , Amount.style = Amount.Style.nil
189 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
194 , "from_List" ~: TestList
195 [ "from_List [$1, 1$] = $2" ~:
198 { Amount.quantity = Decimal 0 1
199 , Amount.style = Amount.Style.nil
200 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
205 { Amount.quantity = Decimal 0 1
206 , Amount.style = Amount.Style.nil
207 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
215 { Amount.quantity = Decimal 0 2
216 , Amount.style = Amount.Style.nil
217 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
224 , "Filter" ~: TestList
225 [ "filter" ~: TestList
226 [ "Test_Account" ~: TestList
229 [ Filter.Test_Account_Section_Text
230 (Filter.Test_Text_Exact "A")
235 [ Filter.Test_Account_Section_Any
240 [ Filter.Test_Account_Section_Many
245 [ Filter.Test_Account_Section_Many
246 , Filter.Test_Account_Section_Text
247 (Filter.Test_Text_Exact "A")
252 [ Filter.Test_Account_Section_Text
253 (Filter.Test_Text_Exact "A")
254 , Filter.Test_Account_Section_Many
259 [ Filter.Test_Account_Section_Text
260 (Filter.Test_Text_Exact "A")
261 , Filter.Test_Account_Section_Many
263 (("A":|"B":[]::Account))
266 [ Filter.Test_Account_Section_Text
267 (Filter.Test_Text_Exact "A")
268 , Filter.Test_Account_Section_Text
269 (Filter.Test_Text_Exact "B")
271 (("A":|"B":[]::Account))
274 [ Filter.Test_Account_Section_Text
275 (Filter.Test_Text_Exact "A")
276 , Filter.Test_Account_Section_Many
277 , Filter.Test_Account_Section_Text
278 (Filter.Test_Text_Exact "B")
280 (("A":|"B":[]::Account))
283 [ Filter.Test_Account_Section_Many
284 , Filter.Test_Account_Section_Text
285 (Filter.Test_Text_Exact "B")
286 , Filter.Test_Account_Section_Many
288 (("A":|"B":"C":[]::Account))
291 [ Filter.Test_Account_Section_Many
292 , Filter.Test_Account_Section_Text
293 (Filter.Test_Text_Exact "C")
295 (("A":|"B":"C":[]::Account))
299 [ "filter_account_section" ~: TestList
301 (Data.Either.rights $
303 (Filter.Read.test_account <* P.eof)
306 [ [Filter.Test_Account_Section_Any]
309 (Data.Either.rights $
311 (Filter.Read.test_account <* P.eof)
314 [ [Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")]
317 (Data.Either.rights $
319 (Filter.Read.test_account <* P.eof)
322 [ [Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "AA")]
325 (Data.Either.rights $
327 (Filter.Read.test_account <* P.eof)
328 () "" ("::A"::Text)])
330 [ [ Filter.Test_Account_Section_Many
331 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
335 (Data.Either.rights $
337 (Filter.Read.test_account <* P.eof)
340 [ [ Filter.Test_Account_Section_Many
341 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
345 (Data.Either.rights $
347 (Filter.Read.test_account <* P.eof)
350 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
351 , Filter.Test_Account_Section_Many
355 (Data.Either.rights $
357 (Filter.Read.test_account <* P.eof)
358 () "" ("A::"::Text)])
360 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
361 , Filter.Test_Account_Section_Many
365 (Data.Either.rights $
367 (Filter.Read.test_account <* P.eof)
368 () "" ("A:B"::Text)])
370 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
371 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B") ]
374 (Data.Either.rights $
376 (Filter.Read.test_account <* P.eof)
377 () "" ("A::B"::Text)])
379 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
380 , Filter.Test_Account_Section_Many
381 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B")
385 (Data.Either.rights $
387 (Filter.Read.test_account <* P.eof)
388 () "" ("A:::B"::Text)])
390 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
391 , Filter.Test_Account_Section_Many
392 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B")
396 (Data.Either.rights $
398 (Filter.Read.test_account <* P.char ' ' <* P.eof)
399 () "" ("A: "::Text)])
401 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
402 , Filter.Test_Account_Section_Many
410 [ "Balance" ~: TestList
411 [ "balance" ~: TestList
412 [ "[A+$1] = A+$1 & $+1" ~:
413 (Calc.Balance.balance
414 (Format.Ledger.posting ("A":|[]))
415 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
420 { Calc.Balance.balance_by_account =
421 Lib.TreeMap.from_List const $
422 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
423 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
424 , Calc.Balance.balance_by_unit =
426 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
427 [ Calc.Balance.Unit_Sum
428 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
429 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
434 , "[A+$1, A-$1] = {A+$0, $+0}" ~:
436 (flip Calc.Balance.balance)
438 [ (Format.Ledger.posting ("A":|[]))
439 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
441 , (Format.Ledger.posting ("A":|[]))
442 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ]
447 { Calc.Balance.balance_by_account =
448 Lib.TreeMap.from_List const $
450 , Data.Map.fromListWith const $
451 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance s, s))
452 [ Calc.Balance.Amount_Sum
453 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
454 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
455 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
459 , Calc.Balance.balance_by_unit =
461 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
462 [ Calc.Balance.Unit_Sum
463 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
464 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
465 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
466 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
468 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
473 , "[A+$1, A-€1] = {A+$1-€1, $+1 €-1}" ~:
475 (flip Calc.Balance.balance)
477 [ (Format.Ledger.posting ("A":|[]))
478 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
480 , (Format.Ledger.posting ("A":|[]))
481 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1 ]
486 { Calc.Balance.balance_by_account =
487 Lib.TreeMap.from_List const $
488 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
489 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ -1 ]) ]
490 , Calc.Balance.balance_by_unit =
492 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
493 [ Calc.Balance.Unit_Sum
494 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
495 { Calc.Balance.amount_sum_negative = Nothing
496 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
497 , Calc.Balance.amount_sum_balance = Amount.usd $ 1
499 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
502 , Calc.Balance.Unit_Sum
503 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
504 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -1
505 , Calc.Balance.amount_sum_positive = Nothing
506 , Calc.Balance.amount_sum_balance = Amount.eur $ -1
508 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
513 , "[A+$1, B-$1] = {A+$1 B-$1, $+0}" ~:
515 (flip Calc.Balance.balance)
517 [ (Format.Ledger.posting ("A":|[]))
518 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
520 , (Format.Ledger.posting ("B":|[]))
521 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ]
526 { Calc.Balance.balance_by_account =
527 Lib.TreeMap.from_List const $
528 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
529 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
530 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
532 , Calc.Balance.balance_by_unit =
534 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
535 [ Calc.Balance.Unit_Sum
536 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
537 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
538 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
539 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
541 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
548 (flip Calc.Balance.balance)
550 [ (Format.Ledger.posting ("A":|[]))
551 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
553 , (Format.Ledger.posting ("B":|[]))
554 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
559 { Calc.Balance.balance_by_account =
560 Lib.TreeMap.from_List const $
561 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
562 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
563 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ])
565 , Calc.Balance.balance_by_unit =
567 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
568 [ Calc.Balance.Unit_Sum
569 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
570 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
575 , "[A+$1+€2, A-$1-€2] = {A+$0+€0, $+0 €+0}" ~:
577 (flip Calc.Balance.balance)
579 [ (Format.Ledger.posting ("A":|[]))
580 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2 ]
582 , (Format.Ledger.posting ("A":|[]))
583 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2 ]
588 { Calc.Balance.balance_by_account =
589 Lib.TreeMap.from_List const $
591 , Data.Map.fromListWith const $
592 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance s, s))
593 [ Calc.Balance.Amount_Sum
594 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
595 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
596 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
598 , Calc.Balance.Amount_Sum
599 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -2
600 , Calc.Balance.amount_sum_positive = Just $ Amount.eur $ 2
601 , Calc.Balance.amount_sum_balance = Amount.eur $ 0
606 , Calc.Balance.balance_by_unit =
608 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
609 [ Calc.Balance.Unit_Sum
610 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
611 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
612 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
613 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
615 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
618 , Calc.Balance.Unit_Sum
619 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
620 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -2
621 , Calc.Balance.amount_sum_positive = Just $ Amount.eur $ 2
622 , Calc.Balance.amount_sum_balance = Amount.eur $ 0
624 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
629 , "[A+$1+€2+£3, B-$1-2€-£3] = {A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~:
631 (flip Calc.Balance.balance)
633 [ (Format.Ledger.posting ("A":|[]))
634 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ]
636 , (Format.Ledger.posting ("B":|[]))
637 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ]
642 { Calc.Balance.balance_by_account =
643 Lib.TreeMap.from_List const $
644 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
645 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
646 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
648 , Calc.Balance.balance_by_unit =
650 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
651 [ Calc.Balance.Unit_Sum
652 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
653 { Calc.Balance.amount_sum_negative = Just $ Amount.usd $ -1
654 , Calc.Balance.amount_sum_positive = Just $ Amount.usd $ 1
655 , Calc.Balance.amount_sum_balance = Amount.usd $ 0
657 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
660 , Calc.Balance.Unit_Sum
661 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
662 { Calc.Balance.amount_sum_negative = Just $ Amount.eur $ -2
663 , Calc.Balance.amount_sum_positive = Just $ Amount.eur $ 2
664 , Calc.Balance.amount_sum_balance = Amount.eur $ 0
666 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
669 , Calc.Balance.Unit_Sum
670 { Calc.Balance.unit_sum_amount = Calc.Balance.Amount_Sum
671 { Calc.Balance.amount_sum_negative = Just $ Amount.gbp $ -3
672 , Calc.Balance.amount_sum_positive = Just $ Amount.gbp $ 3
673 , Calc.Balance.amount_sum_balance = Amount.gbp $ 0
675 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
681 , "union" ~: TestList
683 Calc.Balance.union Calc.Balance.nil Calc.Balance.nil
685 (Calc.Balance.nil::Calc.Balance.Balance Amount)
686 , "{A+$1, $+1} {A+$1, $+1} = {A+$2, $+2}" ~:
688 (Calc.Balance.Balance
689 { Calc.Balance.balance_by_account =
690 Lib.TreeMap.from_List const $
691 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
692 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
693 , Calc.Balance.balance_by_unit =
695 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
696 [ Calc.Balance.Unit_Sum
697 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
698 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
703 (Calc.Balance.Balance
704 { Calc.Balance.balance_by_account =
705 Lib.TreeMap.from_List const $
706 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
707 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
708 , Calc.Balance.balance_by_unit =
710 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
711 [ Calc.Balance.Unit_Sum
712 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
713 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
720 { Calc.Balance.balance_by_account =
721 Lib.TreeMap.from_List const $
722 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
723 [ ("A":|[], Amount.from_List [ Amount.usd $ 2 ]) ]
724 , Calc.Balance.balance_by_unit =
726 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
727 [ Calc.Balance.Unit_Sum
728 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
729 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
734 , "{A+$1, $+1} {B+$1, $+1} = {A+$1 B+$1, $+2}" ~:
736 (Calc.Balance.Balance
737 { Calc.Balance.balance_by_account =
738 Lib.TreeMap.from_List const $
739 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
740 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
741 , Calc.Balance.balance_by_unit =
743 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
744 [ Calc.Balance.Unit_Sum
745 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
746 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
751 (Calc.Balance.Balance
752 { Calc.Balance.balance_by_account =
753 Lib.TreeMap.from_List const $
754 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
755 [ ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
756 , Calc.Balance.balance_by_unit =
758 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
759 [ Calc.Balance.Unit_Sum
760 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
761 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
768 { Calc.Balance.balance_by_account =
769 Lib.TreeMap.from_List const $
770 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
771 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
772 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
773 , Calc.Balance.balance_by_unit =
775 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
776 [ Calc.Balance.Unit_Sum
777 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
778 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
783 , "{A+$1, $+1} {B+€1, €+1} = {A+$1 B+€1, $+1 €+1}" ~:
785 (Calc.Balance.Balance
786 { Calc.Balance.balance_by_account =
787 Lib.TreeMap.from_List const $
788 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
789 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
790 , Calc.Balance.balance_by_unit =
792 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
793 [ Calc.Balance.Unit_Sum
794 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
795 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
800 (Calc.Balance.Balance
801 { Calc.Balance.balance_by_account =
802 Lib.TreeMap.from_List const $
803 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
804 [ ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
805 , Calc.Balance.balance_by_unit =
807 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
808 [ Calc.Balance.Unit_Sum
809 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
810 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
817 { Calc.Balance.balance_by_account =
818 Lib.TreeMap.from_List const $
819 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
820 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
821 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
822 , Calc.Balance.balance_by_unit =
824 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
825 [ Calc.Balance.Unit_Sum
826 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
827 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
830 , Calc.Balance.Unit_Sum
831 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
832 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
838 , "expanded" ~: TestList
839 [ "nil_By_Account" ~:
840 Calc.Balance.expanded
843 (Lib.TreeMap.empty::Calc.Balance.Expanded Amount)
845 Calc.Balance.expanded
846 (Lib.TreeMap.from_List const $
847 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
848 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ])
850 (Lib.TreeMap.from_List const $
851 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
852 { Calc.Balance.inclusive =
853 Data.Map.map Calc.Balance.amount_sum $
854 Amount.from_List [ Amount.usd $ 1 ]
855 , Calc.Balance.exclusive =
856 Data.Map.map Calc.Balance.amount_sum $
857 Amount.from_List [ Amount.usd $ 1 ]
860 , "A/A+$1 = A+$1 A/A+$1" ~:
861 Calc.Balance.expanded
862 (Lib.TreeMap.from_List const $
863 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
864 [ ("A":|["A"], Amount.from_List [ Amount.usd $ 1 ]) ])
866 (Lib.TreeMap.from_List const
867 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
868 { Calc.Balance.inclusive =
869 Data.Map.map Calc.Balance.amount_sum $
870 Amount.from_List [ Amount.usd $ 1 ]
871 , Calc.Balance.exclusive =
872 Data.Map.map Calc.Balance.amount_sum $
875 , ("A":|["A"], Calc.Balance.Account_Sum_Expanded
876 { Calc.Balance.inclusive =
877 Data.Map.map Calc.Balance.amount_sum $
878 Amount.from_List [ Amount.usd $ 1 ]
879 , Calc.Balance.exclusive =
880 Data.Map.map Calc.Balance.amount_sum $
881 Amount.from_List [ Amount.usd $ 1 ]
884 , "A/B+$1 = A+$1 A/B+$1" ~:
885 Calc.Balance.expanded
886 (Lib.TreeMap.from_List const $
887 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
888 [ ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ]) ])
890 (Lib.TreeMap.from_List const
891 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
892 { Calc.Balance.inclusive =
893 Data.Map.map Calc.Balance.amount_sum $
894 Amount.from_List [ Amount.usd $ 1 ]
895 , Calc.Balance.exclusive =
896 Data.Map.map Calc.Balance.amount_sum $
899 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
900 { Calc.Balance.inclusive =
901 Data.Map.map Calc.Balance.amount_sum $
902 Amount.from_List [ Amount.usd $ 1 ]
903 , Calc.Balance.exclusive =
904 Data.Map.map Calc.Balance.amount_sum $
905 Amount.from_List [ Amount.usd $ 1 ]
908 , "A/B/C+$1 = A+$1 A/B+$1 A/B/C+$1" ~:
909 Calc.Balance.expanded
910 (Lib.TreeMap.from_List const $
911 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
912 [ ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ]) ])
914 (Lib.TreeMap.from_List const $
915 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
916 { Calc.Balance.inclusive =
917 Data.Map.map Calc.Balance.amount_sum $
918 Amount.from_List [ Amount.usd $ 1 ]
919 , Calc.Balance.exclusive =
920 Data.Map.map Calc.Balance.amount_sum $
923 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
924 { Calc.Balance.inclusive =
925 Data.Map.map Calc.Balance.amount_sum $
926 Amount.from_List [ Amount.usd $ 1 ]
927 , Calc.Balance.exclusive =
928 Data.Map.map Calc.Balance.amount_sum $
931 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
932 { Calc.Balance.inclusive =
933 Data.Map.map Calc.Balance.amount_sum $
934 Amount.from_List [ Amount.usd $ 1 ]
935 , Calc.Balance.exclusive =
936 Data.Map.map Calc.Balance.amount_sum $
937 Amount.from_List [ Amount.usd $ 1 ]
940 , "A+$1 A/B+$1 = A+$2 A/B+$1" ~:
941 Calc.Balance.expanded
942 (Lib.TreeMap.from_List const $
943 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
944 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
945 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
948 (Lib.TreeMap.from_List const
949 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
950 { Calc.Balance.inclusive =
951 Data.Map.map Calc.Balance.amount_sum $
952 Amount.from_List [ Amount.usd $ 2 ]
953 , Calc.Balance.exclusive =
954 Data.Map.map Calc.Balance.amount_sum $
955 Amount.from_List [ Amount.usd $ 1 ]
957 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
958 { Calc.Balance.inclusive =
959 Data.Map.map Calc.Balance.amount_sum $
960 Amount.from_List [ Amount.usd $ 1 ]
961 , Calc.Balance.exclusive =
962 Data.Map.map Calc.Balance.amount_sum $
963 Amount.from_List [ Amount.usd $ 1 ]
966 , "A+$1 A/B+$1 A/B/C+$1 = A+$3 A/B+$2 A/B/C+$1" ~:
967 Calc.Balance.expanded
968 (Lib.TreeMap.from_List const $
969 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
970 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
971 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
972 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
975 (Lib.TreeMap.from_List const
976 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
977 { Calc.Balance.inclusive =
978 Data.Map.map Calc.Balance.amount_sum $
979 Amount.from_List [ Amount.usd $ 3 ]
980 , Calc.Balance.exclusive =
981 Data.Map.map Calc.Balance.amount_sum $
982 Amount.from_List [ Amount.usd $ 1 ]
984 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
985 { Calc.Balance.inclusive =
986 Data.Map.map Calc.Balance.amount_sum $
987 Amount.from_List [ Amount.usd $ 2 ]
988 , Calc.Balance.exclusive =
989 Data.Map.map Calc.Balance.amount_sum $
990 Amount.from_List [ Amount.usd $ 1 ]
992 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
993 { Calc.Balance.inclusive =
994 Data.Map.map Calc.Balance.amount_sum $
995 Amount.from_List [ Amount.usd $ 1 ]
996 , Calc.Balance.exclusive =
997 Data.Map.map Calc.Balance.amount_sum $
998 Amount.from_List [ Amount.usd $ 1 ]
1001 , "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" ~:
1002 Calc.Balance.expanded
1003 (Lib.TreeMap.from_List const $
1004 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1005 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1006 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
1007 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
1008 , ("A":|["B", "C", "D"], Amount.from_List [ Amount.usd $ 1 ])
1011 (Lib.TreeMap.from_List const
1012 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
1013 { Calc.Balance.inclusive =
1014 Data.Map.map Calc.Balance.amount_sum $
1015 Amount.from_List [ Amount.usd $ 4 ]
1016 , Calc.Balance.exclusive =
1017 Data.Map.map Calc.Balance.amount_sum $
1018 Amount.from_List [ Amount.usd $ 1 ]
1020 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
1021 { Calc.Balance.inclusive =
1022 Data.Map.map Calc.Balance.amount_sum $
1023 Amount.from_List [ Amount.usd $ 3 ]
1024 , Calc.Balance.exclusive =
1025 Data.Map.map Calc.Balance.amount_sum $
1026 Amount.from_List [ Amount.usd $ 1 ]
1028 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
1029 { Calc.Balance.inclusive =
1030 Data.Map.map Calc.Balance.amount_sum $
1031 Amount.from_List [ Amount.usd $ 2 ]
1032 , Calc.Balance.exclusive =
1033 Data.Map.map Calc.Balance.amount_sum $
1034 Amount.from_List [ Amount.usd $ 1 ]
1036 , ("A":|["B", "C", "D"], Calc.Balance.Account_Sum_Expanded
1037 { Calc.Balance.inclusive =
1038 Data.Map.map Calc.Balance.amount_sum $
1039 Amount.from_List [ Amount.usd $ 1 ]
1040 , Calc.Balance.exclusive =
1041 Data.Map.map Calc.Balance.amount_sum $
1042 Amount.from_List [ Amount.usd $ 1 ]
1045 , "A+$1 A/B+$1 A/BB+$1 AA/B+$1 = A+$3 A/B+$1 A/BB+$1 AA+$1 AA/B+$1" ~:
1046 Calc.Balance.expanded
1047 (Lib.TreeMap.from_List const $
1048 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1049 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1050 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
1051 , ("A":|["BB"], Amount.from_List [ Amount.usd $ 1 ])
1052 , ("AA":|["B"], Amount.from_List [ Amount.usd $ 1 ])
1055 (Lib.TreeMap.from_List const
1056 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
1057 { Calc.Balance.inclusive =
1058 Data.Map.map Calc.Balance.amount_sum $
1059 Amount.from_List [ Amount.usd $ 3 ]
1060 , Calc.Balance.exclusive =
1061 Data.Map.map Calc.Balance.amount_sum $
1062 Amount.from_List [ Amount.usd $ 1 ]
1064 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
1065 { Calc.Balance.inclusive =
1066 Data.Map.map Calc.Balance.amount_sum $
1067 Amount.from_List [ Amount.usd $ 1 ]
1068 , Calc.Balance.exclusive =
1069 Data.Map.map Calc.Balance.amount_sum $
1070 Amount.from_List [ Amount.usd $ 1 ]
1072 , ("A":|["BB"], Calc.Balance.Account_Sum_Expanded
1073 { Calc.Balance.inclusive =
1074 Data.Map.map Calc.Balance.amount_sum $
1075 Amount.from_List [ Amount.usd $ 1 ]
1076 , Calc.Balance.exclusive =
1077 Data.Map.map Calc.Balance.amount_sum $
1078 Amount.from_List [ Amount.usd $ 1 ]
1080 , ("AA":|[], Calc.Balance.Account_Sum_Expanded
1081 { Calc.Balance.inclusive =
1082 Data.Map.map Calc.Balance.amount_sum $
1083 Amount.from_List [ Amount.usd $ 1 ]
1084 , Calc.Balance.exclusive =
1085 Data.Map.map Calc.Balance.amount_sum $
1088 , ("AA":|["B"], Calc.Balance.Account_Sum_Expanded
1089 { Calc.Balance.inclusive =
1090 Data.Map.map Calc.Balance.amount_sum $
1091 Amount.from_List [ Amount.usd $ 1 ]
1092 , Calc.Balance.exclusive =
1093 Data.Map.map Calc.Balance.amount_sum $
1094 Amount.from_List [ Amount.usd $ 1 ]
1098 , "deviation" ~: TestList
1100 (Calc.Balance.deviation $
1101 Calc.Balance.Balance
1102 { Calc.Balance.balance_by_account =
1103 Lib.TreeMap.from_List const $
1104 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1105 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1106 , ("B":|[], Amount.from_List [])
1108 , Calc.Balance.balance_by_unit =
1110 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1111 [ Calc.Balance.Unit_Sum
1112 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1113 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1119 (Calc.Balance.Deviation $
1121 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1122 [ Calc.Balance.Unit_Sum
1123 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1124 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1128 , "{A+$1 B+$1, $2}" ~:
1129 (Calc.Balance.deviation $
1130 Calc.Balance.Balance
1131 { Calc.Balance.balance_by_account =
1132 Lib.TreeMap.from_List const $
1133 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1134 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1135 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ])
1137 , Calc.Balance.balance_by_unit =
1139 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1140 [ Calc.Balance.Unit_Sum
1141 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
1142 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1150 (Calc.Balance.Deviation $
1152 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1153 [ Calc.Balance.Unit_Sum
1154 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
1155 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1161 , "is_equilibrium_inferrable" ~: TestList
1162 [ "nil" ~: TestCase $
1164 Calc.Balance.is_equilibrium_inferrable $
1165 Calc.Balance.deviation $
1166 (Calc.Balance.nil::Calc.Balance.Balance Amount.Amount)
1167 , "{A+$0, $+0}" ~: TestCase $
1169 Calc.Balance.is_equilibrium_inferrable $
1170 Calc.Balance.deviation $
1171 Calc.Balance.Balance
1172 { Calc.Balance.balance_by_account =
1173 Lib.TreeMap.from_List const $
1174 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1175 [ ("A":|[], Amount.from_List [ Amount.usd $ 0 ])
1177 , Calc.Balance.balance_by_unit =
1179 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1180 [ Calc.Balance.Unit_Sum
1181 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1182 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1187 , "{A+$1, $+1}" ~: TestCase $
1189 Calc.Balance.is_equilibrium_inferrable $
1190 Calc.Balance.deviation $
1191 Calc.Balance.Balance
1192 { Calc.Balance.balance_by_account =
1193 Lib.TreeMap.from_List const $
1194 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1195 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1197 , Calc.Balance.balance_by_unit =
1199 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1200 [ Calc.Balance.Unit_Sum
1201 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1202 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1207 , "{A+$0+€0, $0 €+0}" ~: TestCase $
1209 Calc.Balance.is_equilibrium_inferrable $
1210 Calc.Balance.deviation $
1211 Calc.Balance.Balance
1212 { Calc.Balance.balance_by_account =
1213 Lib.TreeMap.from_List const $
1214 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1215 [ ("A":|[], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
1217 , Calc.Balance.balance_by_unit =
1219 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1220 [ Calc.Balance.Unit_Sum
1221 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1222 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1225 , Calc.Balance.Unit_Sum
1226 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 0
1227 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1232 , "{A+$1, B-$1, $+0}" ~: TestCase $
1234 Calc.Balance.is_equilibrium_inferrable $
1235 Calc.Balance.deviation $
1236 Calc.Balance.Balance
1237 { Calc.Balance.balance_by_account =
1238 Lib.TreeMap.from_List const $
1239 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1240 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1241 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
1243 , Calc.Balance.balance_by_unit =
1245 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1246 [ Calc.Balance.Unit_Sum
1247 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1248 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1253 , "{A+$1 B, $+1}" ~: TestCase $
1255 Calc.Balance.is_equilibrium_inferrable $
1256 Calc.Balance.deviation $
1257 Calc.Balance.Balance
1258 { Calc.Balance.balance_by_account =
1259 Lib.TreeMap.from_List const $
1260 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1261 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1262 , ("B":|[], Amount.from_List [])
1264 , Calc.Balance.balance_by_unit =
1266 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1267 [ Calc.Balance.Unit_Sum
1268 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1269 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1274 , "{A+$1 B+€1, $+1 €+1}" ~: TestCase $
1276 Calc.Balance.is_equilibrium_inferrable $
1277 Calc.Balance.deviation $
1278 Calc.Balance.Balance
1279 { Calc.Balance.balance_by_account =
1280 Lib.TreeMap.from_List const $
1281 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1282 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1283 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ])
1285 , Calc.Balance.balance_by_unit =
1287 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1288 [ Calc.Balance.Unit_Sum
1289 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 1
1290 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1293 , Calc.Balance.Unit_Sum
1294 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
1295 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1300 , "{A+$1 B-$1+€1, $+0 €+1}" ~: TestCase $
1302 Calc.Balance.is_equilibrium_inferrable $
1303 Calc.Balance.deviation $
1304 Calc.Balance.Balance
1305 { Calc.Balance.balance_by_account =
1306 Lib.TreeMap.from_List const $
1307 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1308 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
1309 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ 1 ])
1311 , Calc.Balance.balance_by_unit =
1313 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1314 [ Calc.Balance.Unit_Sum
1315 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1316 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1319 , Calc.Balance.Unit_Sum
1320 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 1
1321 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1326 , "{A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~: TestCase $
1328 Calc.Balance.is_equilibrium_inferrable $
1329 Calc.Balance.deviation $
1330 Calc.Balance.Balance
1331 { Calc.Balance.balance_by_account =
1332 Lib.TreeMap.from_List const $
1333 Data.List.map (id *** Data.Map.map Calc.Balance.amount_sum) $
1334 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
1335 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
1337 , Calc.Balance.balance_by_unit =
1339 Data.List.map (\s -> (Amount.unit $ Calc.Balance.amount_sum_balance $ Calc.Balance.unit_sum_amount s, s))
1340 [ Calc.Balance.Unit_Sum
1341 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 0
1342 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1345 , Calc.Balance.Unit_Sum
1346 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.eur $ 0
1347 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1350 , Calc.Balance.Unit_Sum
1351 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.gbp $ 0
1352 , Calc.Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
1358 , "infer_equilibrium" ~: TestList
1360 (snd $ Calc.Balance.infer_equilibrium $
1361 Format.Ledger.posting_by_Account
1362 [ (Format.Ledger.posting ("A":|[]))
1363 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1364 , (Format.Ledger.posting ("B":|[]))
1365 { Format.Ledger.posting_amounts=Amount.from_List [] }
1369 Format.Ledger.posting_by_Account
1370 [ (Format.Ledger.posting ("A":|[]))
1371 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1372 , (Format.Ledger.posting ("B":|[]))
1373 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ] }
1376 (snd $ Calc.Balance.infer_equilibrium $
1377 Format.Ledger.posting_by_Account
1378 [ (Format.Ledger.posting ("A":|[]))
1379 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1380 , (Format.Ledger.posting ("B":|[]))
1381 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1 ] }
1385 Format.Ledger.posting_by_Account
1386 [ (Format.Ledger.posting ("A":|[]))
1387 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 1] }
1388 , (Format.Ledger.posting ("B":|[]))
1389 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1, Amount.usd $ -1 ] }
1392 (snd $ Calc.Balance.infer_equilibrium $
1393 Format.Ledger.posting_by_Account
1394 [ (Format.Ledger.posting ("A":|[]))
1395 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1396 , (Format.Ledger.posting ("B":|[]))
1397 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1401 [ Calc.Balance.Unit_Sum
1402 { Calc.Balance.unit_sum_amount = Calc.Balance.amount_sum $ Amount.usd $ 2
1403 , Calc.Balance.unit_sum_accounts = Data.Map.fromList []}
1405 , "{A+$1 B-$1 B-1€}" ~:
1406 (snd $ Calc.Balance.infer_equilibrium $
1407 Format.Ledger.posting_by_Account
1408 [ (Format.Ledger.posting ("A":|[]))
1409 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
1410 , (Format.Ledger.posting ("B":|[]))
1411 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -1 ] }
1415 Format.Ledger.posting_by_Account
1416 [ (Format.Ledger.posting ("A":|[]))
1417 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 1 ] }
1418 , (Format.Ledger.posting ("B":|[]))
1419 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -1 ] }
1424 , "Format" ~: TestList
1425 [ "Ledger" ~: TestList
1426 [ "Read" ~: TestList
1427 [ "account_name" ~: TestList
1429 (Data.Either.rights $
1431 (Format.Ledger.Read.account_name <* P.eof)
1436 (Data.Either.rights $
1438 (Format.Ledger.Read.account_name <* P.eof)
1443 (Data.Either.rights $
1445 (Format.Ledger.Read.account_name <* P.eof)
1446 () "" ("AA"::Text)])
1450 (Data.Either.rights $
1452 (Format.Ledger.Read.account_name <* P.eof)
1457 (Data.Either.rights $
1459 (Format.Ledger.Read.account_name <* P.eof)
1464 (Data.Either.rights $
1466 (Format.Ledger.Read.account_name <* P.eof)
1467 () "" ("A:"::Text)])
1471 (Data.Either.rights $
1473 (Format.Ledger.Read.account_name <* P.eof)
1474 () "" (":A"::Text)])
1478 (Data.Either.rights $
1480 (Format.Ledger.Read.account_name <* P.eof)
1481 () "" ("A "::Text)])
1485 (Data.Either.rights $
1487 (Format.Ledger.Read.account_name)
1488 () "" ("A "::Text)])
1492 (Data.Either.rights $
1494 (Format.Ledger.Read.account_name <* P.eof)
1495 () "" ("A A"::Text)])
1499 (Data.Either.rights $
1501 (Format.Ledger.Read.account_name <* P.eof)
1502 () "" ("A "::Text)])
1506 (Data.Either.rights $
1508 (Format.Ledger.Read.account_name <* P.eof)
1509 () "" ("A \n"::Text)])
1513 (Data.Either.rights $
1515 (Format.Ledger.Read.account_name <* P.eof)
1516 () "" ("(A)A"::Text)])
1520 (Data.Either.rights $
1522 (Format.Ledger.Read.account_name <* P.eof)
1523 () "" ("( )A"::Text)])
1527 (Data.Either.rights $
1529 (Format.Ledger.Read.account_name <* P.eof)
1530 () "" ("(A) A"::Text)])
1534 (Data.Either.rights $
1536 (Format.Ledger.Read.account_name <* P.eof)
1537 () "" ("[ ]A"::Text)])
1541 (Data.Either.rights $
1543 (Format.Ledger.Read.account_name <* P.eof)
1544 () "" ("(A) "::Text)])
1548 (Data.Either.rights $
1550 (Format.Ledger.Read.account_name <* P.eof)
1551 () "" ("(A)"::Text)])
1555 (Data.Either.rights $
1557 (Format.Ledger.Read.account_name <* P.eof)
1558 () "" ("A(A)"::Text)])
1562 (Data.Either.rights $
1564 (Format.Ledger.Read.account_name <* P.eof)
1565 () "" ("[A]A"::Text)])
1569 (Data.Either.rights $
1571 (Format.Ledger.Read.account_name <* P.eof)
1572 () "" ("[A] A"::Text)])
1576 (Data.Either.rights $
1578 (Format.Ledger.Read.account_name <* P.eof)
1579 () "" ("[A] "::Text)])
1583 (Data.Either.rights $
1585 (Format.Ledger.Read.account_name <* P.eof)
1586 () "" ("[A]"::Text)])
1590 , "account" ~: TestList
1592 (Data.Either.rights $
1594 (Format.Ledger.Read.account <* P.eof)
1599 (Data.Either.rights $
1601 (Format.Ledger.Read.account <* P.eof)
1606 (Data.Either.rights $
1608 (Format.Ledger.Read.account <* P.eof)
1609 () "" ("A:"::Text)])
1613 (Data.Either.rights $
1615 (Format.Ledger.Read.account <* P.eof)
1616 () "" (":A"::Text)])
1620 (Data.Either.rights $
1622 (Format.Ledger.Read.account <* P.eof)
1623 () "" ("A "::Text)])
1627 (Data.Either.rights $
1629 (Format.Ledger.Read.account <* P.eof)
1630 () "" (" A"::Text)])
1634 (Data.Either.rights $
1636 (Format.Ledger.Read.account <* P.eof)
1637 () "" ("A:B"::Text)])
1641 (Data.Either.rights $
1643 (Format.Ledger.Read.account <* P.eof)
1644 () "" ("A:B:C"::Text)])
1647 , "\"Aa:Bbb:Cccc\"" ~:
1648 (Data.Either.rights $
1650 (Format.Ledger.Read.account <* P.eof)
1651 () "" ("Aa:Bbb:Cccc"::Text)])
1653 ["Aa":|["Bbb", "Cccc"]]
1654 , "\"A a : B b b : C c c c\"" ~:
1655 (Data.Either.rights $
1657 (Format.Ledger.Read.account <* P.eof)
1658 () "" ("A a : B b b : C c c c"::Text)])
1660 ["A a ":|[" B b b ", " C c c c"]]
1662 (Data.Either.rights $
1664 (Format.Ledger.Read.account <* P.eof)
1665 () "" ("A: :C"::Text)])
1669 (Data.Either.rights $
1671 (Format.Ledger.Read.account <* P.eof)
1672 () "" ("A::C"::Text)])
1676 (Data.Either.rights $
1678 (Format.Ledger.Read.account <* P.eof)
1679 () "" ("A:B:(C)"::Text)])
1683 , "posting_type" ~: TestList
1685 Format.Ledger.Read.posting_type
1688 (Format.Ledger.Posting_Type_Regular, "A":|[])
1690 Format.Ledger.Read.posting_type
1693 (Format.Ledger.Posting_Type_Regular, "(":|[])
1695 Format.Ledger.Read.posting_type
1698 (Format.Ledger.Posting_Type_Regular, ")":|[])
1700 Format.Ledger.Read.posting_type
1703 (Format.Ledger.Posting_Type_Regular, "()":|[])
1705 Format.Ledger.Read.posting_type
1708 (Format.Ledger.Posting_Type_Regular, "( )":|[])
1710 Format.Ledger.Read.posting_type
1713 (Format.Ledger.Posting_Type_Virtual, "A":|[])
1715 Format.Ledger.Read.posting_type
1718 (Format.Ledger.Posting_Type_Virtual, "A":|["B", "C"])
1720 Format.Ledger.Read.posting_type
1723 (Format.Ledger.Posting_Type_Regular, "A":|["B", "C"])
1725 Format.Ledger.Read.posting_type
1728 (Format.Ledger.Posting_Type_Regular, "(A)":|["B", "C"])
1730 Format.Ledger.Read.posting_type
1733 (Format.Ledger.Posting_Type_Regular, "A":|["(B)", "C"])
1735 Format.Ledger.Read.posting_type
1738 (Format.Ledger.Posting_Type_Regular, "A":|["B", "(C)"])
1740 Format.Ledger.Read.posting_type
1743 (Format.Ledger.Posting_Type_Regular, "[":|[])
1745 Format.Ledger.Read.posting_type
1748 (Format.Ledger.Posting_Type_Regular, "]":|[])
1750 Format.Ledger.Read.posting_type
1753 (Format.Ledger.Posting_Type_Regular, "[]":|[])
1755 Format.Ledger.Read.posting_type
1758 (Format.Ledger.Posting_Type_Regular, "[ ]":|[])
1760 Format.Ledger.Read.posting_type
1763 (Format.Ledger.Posting_Type_Virtual_Balanced, "A":|[])
1765 Format.Ledger.Read.posting_type
1768 (Format.Ledger.Posting_Type_Virtual_Balanced, "A":|["B", "C"])
1770 Format.Ledger.Read.posting_type
1773 (Format.Ledger.Posting_Type_Regular, "A":|["B", "C"])
1775 Format.Ledger.Read.posting_type
1778 (Format.Ledger.Posting_Type_Regular, "[A]":|["B", "C"])
1780 Format.Ledger.Read.posting_type
1783 (Format.Ledger.Posting_Type_Regular, "A":|["[B]", "C"])
1785 Format.Ledger.Read.posting_type
1788 (Format.Ledger.Posting_Type_Regular, "A":|["B", "[C]"])
1790 , "amount" ~: TestList
1792 (Data.Either.rights $
1794 (Format.Ledger.Read.amount <* P.eof)
1798 , "\"0\" = Right 0" ~:
1799 (Data.Either.rights $
1801 (Format.Ledger.Read.amount <* P.eof)
1805 { Amount.quantity = Decimal 0 0
1807 , "\"00\" = Right 0" ~:
1808 (Data.Either.rights $
1810 (Format.Ledger.Read.amount <* P.eof)
1811 () "" ("00"::Text)])
1814 { Amount.quantity = Decimal 0 0
1816 , "\"0.\" = Right 0." ~:
1817 (Data.Either.rights $
1819 (Format.Ledger.Read.amount <* P.eof)
1820 () "" ("0."::Text)])
1823 { Amount.quantity = Decimal 0 0
1826 { Amount.Style.fractioning = Just '.'
1829 , "\".0\" = Right 0.0" ~:
1830 (Data.Either.rights $
1832 (Format.Ledger.Read.amount <* P.eof)
1833 () "" (".0"::Text)])
1836 { Amount.quantity = Decimal 0 0
1839 { Amount.Style.fractioning = Just '.'
1840 , Amount.Style.precision = 1
1843 , "\"0,\" = Right 0," ~:
1844 (Data.Either.rights $
1846 (Format.Ledger.Read.amount <* P.eof)
1847 () "" ("0,"::Text)])
1850 { Amount.quantity = Decimal 0 0
1853 { Amount.Style.fractioning = Just ','
1856 , "\",0\" = Right 0,0" ~:
1857 (Data.Either.rights $
1859 (Format.Ledger.Read.amount <* P.eof)
1860 () "" (",0"::Text)])
1863 { Amount.quantity = Decimal 0 0
1866 { Amount.Style.fractioning = Just ','
1867 , Amount.Style.precision = 1
1870 , "\"0_\" = Left" ~:
1871 (Data.Either.rights $
1873 (Format.Ledger.Read.amount <* P.eof)
1874 () "" ("0_"::Text)])
1877 , "\"_0\" = Left" ~:
1878 (Data.Either.rights $
1880 (Format.Ledger.Read.amount <* P.eof)
1881 () "" ("_0"::Text)])
1884 , "\"0.0\" = Right 0.0" ~:
1885 (Data.Either.rights $
1887 (Format.Ledger.Read.amount <* P.eof)
1888 () "" ("0.0"::Text)])
1891 { Amount.quantity = Decimal 0 0
1894 { Amount.Style.fractioning = Just '.'
1895 , Amount.Style.precision = 1
1898 , "\"00.00\" = Right 0.00" ~:
1899 (Data.Either.rights $
1901 (Format.Ledger.Read.amount <* P.eof)
1902 () "" ("00.00"::Text)])
1905 { Amount.quantity = Decimal 0 0
1908 { Amount.Style.fractioning = Just '.'
1909 , Amount.Style.precision = 2
1912 , "\"0,0\" = Right 0,0" ~:
1913 (Data.Either.rights $
1915 (Format.Ledger.Read.amount <* P.eof)
1916 () "" ("0,0"::Text)])
1919 { Amount.quantity = Decimal 0 0
1922 { Amount.Style.fractioning = Just ','
1923 , Amount.Style.precision = 1
1926 , "\"00,00\" = Right 0,00" ~:
1927 (Data.Either.rights $
1929 (Format.Ledger.Read.amount <* P.eof)
1930 () "" ("00,00"::Text)])
1933 { Amount.quantity = Decimal 0 0
1936 { Amount.Style.fractioning = Just ','
1937 , Amount.Style.precision = 2
1940 , "\"0_0\" = Right 0" ~:
1941 (Data.Either.rights $
1943 (Format.Ledger.Read.amount <* P.eof)
1944 () "" ("0_0"::Text)])
1947 { Amount.quantity = Decimal 0 0
1950 { Amount.Style.fractioning = Nothing
1951 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
1952 , Amount.Style.precision = 0
1955 , "\"00_00\" = Right 0" ~:
1956 (Data.Either.rights $
1958 (Format.Ledger.Read.amount <* P.eof)
1959 () "" ("00_00"::Text)])
1962 { Amount.quantity = Decimal 0 0
1965 { Amount.Style.fractioning = Nothing
1966 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
1967 , Amount.Style.precision = 0
1970 , "\"0,000.00\" = Right 0,000.00" ~:
1971 (Data.Either.rights $
1973 (Format.Ledger.Read.amount <* P.eof)
1974 () "" ("0,000.00"::Text)])
1977 { Amount.quantity = Decimal 0 0
1980 { Amount.Style.fractioning = Just '.'
1981 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
1982 , Amount.Style.precision = 2
1985 , "\"0.000,00\" = Right 0.000,00" ~:
1986 (Data.Either.rights $
1988 (Format.Ledger.Read.amount)
1989 () "" ("0.000,00"::Text)])
1992 { Amount.quantity = Decimal 0 0
1995 { Amount.Style.fractioning = Just ','
1996 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
1997 , Amount.Style.precision = 2
2000 , "\"1,000.00\" = Right 1,000.00" ~:
2001 (Data.Either.rights $
2003 (Format.Ledger.Read.amount <* P.eof)
2004 () "" ("1,000.00"::Text)])
2007 { Amount.quantity = Decimal 0 1000
2010 { Amount.Style.fractioning = Just '.'
2011 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
2012 , Amount.Style.precision = 2
2015 , "\"1.000,00\" = Right 1.000,00" ~:
2016 (Data.Either.rights $
2018 (Format.Ledger.Read.amount)
2019 () "" ("1.000,00"::Text)])
2022 { Amount.quantity = Decimal 0 1000
2025 { Amount.Style.fractioning = Just ','
2026 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
2027 , Amount.Style.precision = 2
2030 , "\"1,000.00.\" = Left" ~:
2031 (Data.Either.rights $
2033 (Format.Ledger.Read.amount)
2034 () "" ("1,000.00."::Text)])
2037 , "\"1.000,00,\" = Left" ~:
2038 (Data.Either.rights $
2040 (Format.Ledger.Read.amount)
2041 () "" ("1.000,00,"::Text)])
2044 , "\"1,000.00_\" = Left" ~:
2045 (Data.Either.rights $
2047 (Format.Ledger.Read.amount)
2048 () "" ("1,000.00_"::Text)])
2051 , "\"12\" = Right 12" ~:
2052 (Data.Either.rights $
2054 (Format.Ledger.Read.amount <* P.eof)
2055 () "" ("123"::Text)])
2058 { Amount.quantity = Decimal 0 123
2060 , "\"1.2\" = Right 1.2" ~:
2061 (Data.Either.rights $
2063 (Format.Ledger.Read.amount <* P.eof)
2064 () "" ("1.2"::Text)])
2067 { Amount.quantity = Decimal 1 12
2070 { Amount.Style.fractioning = Just '.'
2071 , Amount.Style.precision = 1
2074 , "\"1,2\" = Right 1,2" ~:
2075 (Data.Either.rights $
2077 (Format.Ledger.Read.amount <* P.eof)
2078 () "" ("1,2"::Text)])
2081 { Amount.quantity = Decimal 1 12
2084 { Amount.Style.fractioning = Just ','
2085 , Amount.Style.precision = 1
2088 , "\"12.23\" = Right 12.23" ~:
2089 (Data.Either.rights $
2091 (Format.Ledger.Read.amount <* P.eof)
2092 () "" ("12.34"::Text)])
2095 { Amount.quantity = Decimal 2 1234
2098 { Amount.Style.fractioning = Just '.'
2099 , Amount.Style.precision = 2
2102 , "\"12,23\" = Right 12,23" ~:
2103 (Data.Either.rights $
2105 (Format.Ledger.Read.amount <* P.eof)
2106 () "" ("12,34"::Text)])
2109 { Amount.quantity = Decimal 2 1234
2112 { Amount.Style.fractioning = Just ','
2113 , Amount.Style.precision = 2
2116 , "\"1_2\" = Right 1_2" ~:
2117 (Data.Either.rights $
2119 (Format.Ledger.Read.amount <* P.eof)
2120 () "" ("1_2"::Text)])
2123 { Amount.quantity = Decimal 0 12
2126 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
2127 , Amount.Style.precision = 0
2130 , "\"1_23\" = Right 1_23" ~:
2131 (Data.Either.rights $
2133 (Format.Ledger.Read.amount <* P.eof)
2134 () "" ("1_23"::Text)])
2137 { Amount.quantity = Decimal 0 123
2140 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
2141 , Amount.Style.precision = 0
2144 , "\"1_23_456\" = Right 1_23_456" ~:
2145 (Data.Either.rights $
2147 (Format.Ledger.Read.amount <* P.eof)
2148 () "" ("1_23_456"::Text)])
2151 { Amount.quantity = Decimal 0 123456
2154 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
2155 , Amount.Style.precision = 0
2158 , "\"1_23_456.7890_12345_678901\" = Right 1_23_456.7890_12345_678901" ~:
2159 (Data.Either.rights $
2161 (Format.Ledger.Read.amount <* P.eof)
2162 () "" ("1_23_456.7890_12345_678901"::Text)])
2165 { Amount.quantity = Decimal 15 123456789012345678901
2168 { Amount.Style.fractioning = Just '.'
2169 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
2170 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [4, 5, 6]
2171 , Amount.Style.precision = 15
2174 , "\"123456_78901_2345.678_90_1\" = Right 123456_78901_2345.678_90_1" ~:
2175 (Data.Either.rights $
2177 (Format.Ledger.Read.amount <* P.eof)
2178 () "" ("123456_78901_2345.678_90_1"::Text)])
2181 { Amount.quantity = Decimal 6 123456789012345678901
2184 { Amount.Style.fractioning = Just '.'
2185 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [4, 5, 6]
2186 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [3, 2]
2187 , Amount.Style.precision = 6
2190 , "\"$1\" = Right $1" ~:
2191 (Data.Either.rights $
2193 (Format.Ledger.Read.amount <* P.eof)
2194 () "" ("$1"::Text)])
2197 { Amount.quantity = Decimal 0 1
2200 { Amount.Style.fractioning = Nothing
2201 , Amount.Style.grouping_integral = Nothing
2202 , Amount.Style.grouping_fractional = Nothing
2203 , Amount.Style.precision = 0
2204 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2205 , Amount.Style.unit_spaced = Just False
2209 , "\"1$\" = Right 1$" ~:
2210 (Data.Either.rights $
2212 (Format.Ledger.Read.amount <* P.eof)
2213 () "" ("1$"::Text)])
2216 { Amount.quantity = Decimal 0 1
2219 { Amount.Style.fractioning = Nothing
2220 , Amount.Style.grouping_integral = Nothing
2221 , Amount.Style.grouping_fractional = Nothing
2222 , Amount.Style.precision = 0
2223 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2224 , Amount.Style.unit_spaced = Just False
2228 , "\"$ 1\" = Right $ 1" ~:
2229 (Data.Either.rights $
2231 (Format.Ledger.Read.amount <* P.eof)
2232 () "" ("$ 1"::Text)])
2235 { Amount.quantity = Decimal 0 1
2238 { Amount.Style.fractioning = Nothing
2239 , Amount.Style.grouping_integral = Nothing
2240 , Amount.Style.grouping_fractional = Nothing
2241 , Amount.Style.precision = 0
2242 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2243 , Amount.Style.unit_spaced = Just True
2247 , "\"1 $\" = Right 1 $" ~:
2248 (Data.Either.rights $
2250 (Format.Ledger.Read.amount <* P.eof)
2251 () "" ("1 $"::Text)])
2254 { Amount.quantity = Decimal 0 1
2257 { Amount.Style.fractioning = Nothing
2258 , Amount.Style.grouping_integral = Nothing
2259 , Amount.Style.grouping_fractional = Nothing
2260 , Amount.Style.precision = 0
2261 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2262 , Amount.Style.unit_spaced = Just True
2266 , "\"-$1\" = Right $-1" ~:
2267 (Data.Either.rights $
2269 (Format.Ledger.Read.amount <* P.eof)
2270 () "" ("-$1"::Text)])
2273 { Amount.quantity = Decimal 0 (-1)
2276 { Amount.Style.fractioning = Nothing
2277 , Amount.Style.grouping_integral = Nothing
2278 , Amount.Style.grouping_fractional = Nothing
2279 , Amount.Style.precision = 0
2280 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2281 , Amount.Style.unit_spaced = Just False
2285 , "\"\\\"4 2\\\"1\" = Right \\\"4 2\\\"1" ~:
2286 (Data.Either.rights $
2288 (Format.Ledger.Read.amount <* P.eof)
2289 () "" ("\"4 2\"1"::Text)])
2292 { Amount.quantity = Decimal 0 1
2295 { Amount.Style.fractioning = Nothing
2296 , Amount.Style.grouping_integral = Nothing
2297 , Amount.Style.grouping_fractional = Nothing
2298 , Amount.Style.precision = 0
2299 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2300 , Amount.Style.unit_spaced = Just False
2302 , Amount.unit = "4 2"
2304 , "\"1\\\"4 2\\\"\" = Right 1\\\"4 2\\\"" ~:
2305 (Data.Either.rights $
2307 (Format.Ledger.Read.amount <* P.eof)
2308 () "" ("1\"4 2\""::Text)])
2311 { Amount.quantity = Decimal 0 1
2314 { Amount.Style.fractioning = Nothing
2315 , Amount.Style.grouping_integral = Nothing
2316 , Amount.Style.grouping_fractional = Nothing
2317 , Amount.Style.precision = 0
2318 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2319 , Amount.Style.unit_spaced = Just False
2321 , Amount.unit = "4 2"
2323 , "\"$1.000,00\" = Right $1.000,00" ~:
2324 (Data.Either.rights $
2326 (Format.Ledger.Read.amount <* P.eof)
2327 () "" ("$1.000,00"::Text)])
2330 { Amount.quantity = Decimal 0 1000
2333 { Amount.Style.fractioning = Just ','
2334 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
2335 , Amount.Style.grouping_fractional = Nothing
2336 , Amount.Style.precision = 2
2337 , Amount.Style.unit_side = Just Amount.Style.Side_Left
2338 , Amount.Style.unit_spaced = Just False
2342 , "\"1.000,00$\" = Right 1.000,00$" ~:
2343 (Data.Either.rights $
2345 (Format.Ledger.Read.amount <* P.eof)
2346 () "" ("1.000,00$"::Text)])
2349 { Amount.quantity = Decimal 0 1000
2352 { Amount.Style.fractioning = Just ','
2353 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
2354 , Amount.Style.grouping_fractional = Nothing
2355 , Amount.Style.precision = 2
2356 , Amount.Style.unit_side = Just Amount.Style.Side_Right
2357 , Amount.Style.unit_spaced = Just False
2362 , "comment" ~: TestList
2363 [ "; some comment = Right \" some comment\"" ~:
2364 (Data.Either.rights $
2366 (Format.Ledger.Read.comment <* P.eof)
2367 () "" ("; some comment"::Text)])
2370 , "; some comment \\n = Right \" some comment \"" ~:
2371 (Data.Either.rights $
2373 (Format.Ledger.Read.comment <* P.newline <* P.eof)
2374 () "" ("; some comment \n"::Text)])
2376 [ " some comment " ]
2377 , "; some comment \\r\\n = Right \" some comment \"" ~:
2378 (Data.Either.rights $
2380 (Format.Ledger.Read.comment <* P.string "\r\n" <* P.eof)
2381 () "" ("; some comment \r\n"::Text)])
2383 [ " some comment " ]
2385 , "comments" ~: TestList
2386 [ "; some comment\\n ; some other comment = Right [\" some comment\", \" some other comment\"]" ~:
2387 (Data.Either.rights $
2389 (Format.Ledger.Read.comments <* P.eof)
2390 () "" ("; some comment\n ; some other comment"::Text)])
2392 [ [" some comment", " some other comment"] ]
2393 , "; some comment \\n = Right \" some comment \"" ~:
2394 (Data.Either.rights $
2396 (Format.Ledger.Read.comments <* P.string "\n" <* P.eof)
2397 () "" ("; some comment \n"::Text)])
2399 [ [" some comment "] ]
2401 , "date" ~: TestList
2403 (Data.Either.rights $
2404 [P.runParser_with_Error
2405 (Format.Ledger.Read.date Nothing <* P.eof)
2406 () "" ("2000/01/01"::Text)])
2410 (Time.fromGregorian 2000 01 01)
2411 (Time.TimeOfDay 0 0 0))
2413 , "2000/01/01 some text" ~:
2414 (Data.Either.rights $
2415 [P.runParser_with_Error
2416 (Format.Ledger.Read.date Nothing)
2417 () "" ("2000/01/01 some text"::Text)])
2421 (Time.fromGregorian 2000 01 01)
2422 (Time.TimeOfDay 0 0 0))
2424 , "2000/01/01 12:34" ~:
2425 (Data.Either.rights $
2426 [P.runParser_with_Error
2427 (Format.Ledger.Read.date Nothing <* P.eof)
2428 () "" ("2000/01/01 12:34"::Text)])
2432 (Time.fromGregorian 2000 01 01)
2433 (Time.TimeOfDay 12 34 0))
2435 , "2000/01/01 12:34:56" ~:
2436 (Data.Either.rights $
2437 [P.runParser_with_Error
2438 (Format.Ledger.Read.date Nothing <* P.eof)
2439 () "" ("2000/01/01 12:34:56"::Text)])
2443 (Time.fromGregorian 2000 01 01)
2444 (Time.TimeOfDay 12 34 56))
2446 , "2000/01/01 12:34 CET" ~:
2447 (Data.Either.rights $
2448 [P.runParser_with_Error
2449 (Format.Ledger.Read.date Nothing <* P.eof)
2450 () "" ("2000/01/01 12:34 CET"::Text)])
2454 (Time.fromGregorian 2000 01 01)
2455 (Time.TimeOfDay 12 34 0))
2456 (Time.TimeZone 60 True "CET")]
2457 , "2000/01/01 12:34 +0130" ~:
2458 (Data.Either.rights $
2459 [P.runParser_with_Error
2460 (Format.Ledger.Read.date Nothing <* P.eof)
2461 () "" ("2000/01/01 12:34 +0130"::Text)])
2465 (Time.fromGregorian 2000 01 01)
2466 (Time.TimeOfDay 12 34 0))
2467 (Time.TimeZone 90 False "+0130")]
2468 , "2000/01/01 12:34:56 CET" ~:
2469 (Data.Either.rights $
2470 [P.runParser_with_Error
2471 (Format.Ledger.Read.date Nothing <* P.eof)
2472 () "" ("2000/01/01 12:34:56 CET"::Text)])
2476 (Time.fromGregorian 2000 01 01)
2477 (Time.TimeOfDay 12 34 56))
2478 (Time.TimeZone 60 True "CET")]
2480 (Data.Either.rights $
2481 [P.runParser_with_Error
2482 (Format.Ledger.Read.date Nothing <* P.eof)
2483 () "" ("2001/02/29"::Text)])
2487 (Data.Either.rights $
2488 [P.runParser_with_Error
2489 (Format.Ledger.Read.date (Just 2000) <* P.eof)
2490 () "" ("01/01"::Text)])
2494 (Time.fromGregorian 2000 01 01)
2495 (Time.TimeOfDay 0 0 0))
2498 , "tag_value" ~: TestList
2500 (Data.Either.rights $
2502 (Format.Ledger.Read.tag_value <* P.eof)
2507 (Data.Either.rights $
2509 (Format.Ledger.Read.tag_value <* P.char '\n' <* P.eof)
2510 () "" (",\n"::Text)])
2514 (Data.Either.rights $
2516 (Format.Ledger.Read.tag_value <* P.eof)
2517 () "" (",x"::Text)])
2521 (Data.Either.rights $
2523 (Format.Ledger.Read.tag_value <* P.string ",x:" <* P.eof)
2524 () "" (",x:"::Text)])
2528 (Data.Either.rights $
2530 (Format.Ledger.Read.tag_value <* P.string ", n:" <* P.eof)
2531 () "" ("v, v, n:"::Text)])
2537 (Data.Either.rights $
2539 (Format.Ledger.Read.tag <* P.eof)
2540 () "" ("Name:"::Text)])
2544 (Data.Either.rights $
2546 (Format.Ledger.Read.tag <* P.eof)
2547 () "" ("Name:Value"::Text)])
2550 , "Name:Value\\n" ~:
2551 (Data.Either.rights $
2553 (Format.Ledger.Read.tag <* P.string "\n" <* P.eof)
2554 () "" ("Name:Value\n"::Text)])
2558 (Data.Either.rights $
2560 (Format.Ledger.Read.tag <* P.eof)
2561 () "" ("Name:Val ue"::Text)])
2563 [("Name", "Val ue")]
2565 (Data.Either.rights $
2567 (Format.Ledger.Read.tag <* P.eof)
2568 () "" ("Name:,"::Text)])
2572 (Data.Either.rights $
2574 (Format.Ledger.Read.tag <* P.eof)
2575 () "" ("Name:Val,ue"::Text)])
2577 [("Name", "Val,ue")]
2579 (Data.Either.rights $
2581 (Format.Ledger.Read.tag <* P.string ",ue:" <* P.eof)
2582 () "" ("Name:Val,ue:"::Text)])
2586 , "tags" ~: TestList
2588 (Data.Either.rights $
2590 (Format.Ledger.Read.tags <* P.eof)
2591 () "" ("Name:"::Text)])
2598 (Data.Either.rights $
2600 (Format.Ledger.Read.tags <* P.eof)
2601 () "" ("Name:,"::Text)])
2608 (Data.Either.rights $
2610 (Format.Ledger.Read.tags <* P.eof)
2611 () "" ("Name:,Name:"::Text)])
2614 [ ("Name", ["", ""])
2618 (Data.Either.rights $
2620 (Format.Ledger.Read.tags <* P.eof)
2621 () "" ("Name:,Name2:"::Text)])
2628 , "Name: , Name2:" ~:
2629 (Data.Either.rights $
2631 (Format.Ledger.Read.tags <* P.eof)
2632 () "" ("Name: , Name2:"::Text)])
2639 , "Name:,Name2:,Name3:" ~:
2640 (Data.Either.rights $
2642 (Format.Ledger.Read.tags <* P.eof)
2643 () "" ("Name:,Name2:,Name3:"::Text)])
2651 , "Name:Val ue,Name2:V a l u e,Name3:V al ue" ~:
2652 (Data.Either.rights $
2654 (Format.Ledger.Read.tags <* P.eof)
2655 () "" ("Name:Val ue,Name2:V a l u e,Name3:V al ue"::Text)])
2658 [ ("Name", ["Val ue"])
2659 , ("Name2", ["V a l u e"])
2660 , ("Name3", ["V al ue"])
2664 , "posting" ~: TestList
2665 [ " A:B:C = Right A:B:C" ~:
2666 (Data.Either.rights $
2667 [P.runParser_with_Error
2668 (Format.Ledger.Read.posting <* P.eof)
2669 Format.Ledger.Read.nil_Context "" (" A:B:C"::Text)])
2671 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
2672 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2674 , Format.Ledger.Posting_Type_Regular
2677 , " !A:B:C = Right !A:B:C" ~:
2678 (Data.List.map fst $
2679 Data.Either.rights $
2680 [P.runParser_with_Error
2681 (Format.Ledger.Read.posting <* P.eof)
2682 Format.Ledger.Read.nil_Context "" (" !A:B:C"::Text)])
2684 [ (Format.Ledger.posting ("A":|["B", "C"]))
2685 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2686 , Format.Ledger.posting_status = True
2689 , " *A:B:C = Right *A:B:C" ~:
2690 (Data.List.map fst $
2691 Data.Either.rights $
2692 [P.runParser_with_Error
2693 (Format.Ledger.Read.posting <* P.eof)
2694 Format.Ledger.Read.nil_Context "" (" *A:B:C"::Text)])
2696 [ (Format.Ledger.posting ("A":|["B", "C"]))
2697 { Format.Ledger.posting_amounts = Data.Map.fromList []
2698 , Format.Ledger.posting_comments = []
2699 , Format.Ledger.posting_dates = []
2700 , Format.Ledger.posting_status = True
2701 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2702 , Format.Ledger.posting_tags = Data.Map.fromList []
2705 , " A:B:C $1 = Right A:B:C $1" ~:
2706 (Data.List.map fst $
2707 Data.Either.rights $
2708 [P.runParser_with_Error
2709 (Format.Ledger.Read.posting <* P.eof)
2710 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
2712 [ (Format.Ledger.posting ("A":|["B","C $1"]))
2713 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2716 , " A:B:C $1 = Right A:B:C $1" ~:
2717 (Data.List.map fst $
2718 Data.Either.rights $
2719 [P.runParser_with_Error
2720 (Format.Ledger.Read.posting <* P.eof)
2721 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
2723 [ (Format.Ledger.posting ("A":|["B", "C"]))
2724 { Format.Ledger.posting_amounts = Data.Map.fromList
2726 { Amount.quantity = 1
2727 , Amount.style = Amount.Style.nil
2728 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2729 , Amount.Style.unit_spaced = Just False
2734 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2737 , " A:B:C $1 + 1€ = Right A:B:C $1 + 1€" ~:
2738 (Data.List.map fst $
2739 Data.Either.rights $
2740 [P.runParser_with_Error
2741 (Format.Ledger.Read.posting <* P.eof)
2742 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1€"::Text)])
2744 [ (Format.Ledger.posting ("A":|["B", "C"]))
2745 { Format.Ledger.posting_amounts = Data.Map.fromList
2747 { Amount.quantity = 1
2748 , Amount.style = Amount.Style.nil
2749 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2750 , Amount.Style.unit_spaced = Just False
2755 { Amount.quantity = 1
2756 , Amount.style = Amount.Style.nil
2757 { Amount.Style.unit_side = Just Amount.Style.Side_Right
2758 , Amount.Style.unit_spaced = Just False
2763 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2766 , " A:B:C $1 + 1$ = Right A:B:C $2" ~:
2767 (Data.List.map fst $
2768 Data.Either.rights $
2769 [P.runParser_with_Error
2770 (Format.Ledger.Read.posting <* P.eof)
2771 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$"::Text)])
2773 [ (Format.Ledger.posting ("A":|["B", "C"]))
2774 { Format.Ledger.posting_amounts = Data.Map.fromList
2776 { Amount.quantity = 2
2777 , Amount.style = Amount.Style.nil
2778 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2779 , Amount.Style.unit_spaced = Just False
2784 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2787 , " A:B:C $1 + 1$ + 1$ = Right A:B:C $3" ~:
2788 (Data.List.map fst $
2789 Data.Either.rights $
2790 [P.runParser_with_Error
2791 (Format.Ledger.Read.posting <* P.eof)
2792 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$ + 1$"::Text)])
2794 [ (Format.Ledger.posting ("A":|["B", "C"]))
2795 { Format.Ledger.posting_amounts = Data.Map.fromList
2797 { Amount.quantity = 3
2798 , Amount.style = Amount.Style.nil
2799 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2800 , Amount.Style.unit_spaced = Just False
2805 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2808 , " A:B:C ; some comment = Right A:B:C ; some comment" ~:
2809 (Data.List.map fst $
2810 Data.Either.rights $
2811 [P.runParser_with_Error
2812 (Format.Ledger.Read.posting <* P.eof)
2813 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment"::Text)])
2815 [ (Format.Ledger.posting ("A":|["B", "C"]))
2816 { Format.Ledger.posting_amounts = Data.Map.fromList []
2817 , Format.Ledger.posting_comments = [" some comment"]
2818 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2821 , " A:B:C ; some comment\\n ; some other comment = Right A:B:C ; some comment\\n ; some other comment" ~:
2822 (Data.List.map fst $
2823 Data.Either.rights $
2824 [P.runParser_with_Error
2825 (Format.Ledger.Read.posting <* P.eof)
2826 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment\n ; some other comment"::Text)])
2828 [ (Format.Ledger.posting ("A":|["B", "C"]))
2829 { Format.Ledger.posting_amounts = Data.Map.fromList []
2830 , Format.Ledger.posting_comments = [" some comment", " some other comment"]
2831 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2834 , " A:B:C $1 ; some comment = Right A:B:C $1 ; some comment" ~:
2835 (Data.List.map fst $
2836 Data.Either.rights $
2837 [P.runParser_with_Error
2838 (Format.Ledger.Read.posting)
2839 Format.Ledger.Read.nil_Context "" (" A:B:C $1 ; some comment"::Text)])
2841 [ (Format.Ledger.posting ("A":|["B", "C"]))
2842 { Format.Ledger.posting_amounts = Data.Map.fromList
2844 { Amount.quantity = 1
2845 , Amount.style = Amount.Style.nil
2846 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2847 , Amount.Style.unit_spaced = Just False
2852 , Format.Ledger.posting_comments = [" some comment"]
2853 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2856 , " A:B:C ; N:V = Right A:B:C ; N:V" ~:
2857 (Data.List.map fst $
2858 Data.Either.rights $
2859 [P.runParser_with_Error
2860 (Format.Ledger.Read.posting <* P.eof)
2861 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V"::Text)])
2863 [ (Format.Ledger.posting ("A":|["B", "C"]))
2864 { Format.Ledger.posting_comments = [" N:V"]
2865 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2866 , Format.Ledger.posting_tags = Data.Map.fromList
2871 , " A:B:C ; some comment N:V = Right A:B:C ; some comment N:V" ~:
2872 (Data.List.map fst $
2873 Data.Either.rights $
2874 [P.runParser_with_Error
2875 (Format.Ledger.Read.posting <* P.eof)
2876 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V"::Text)])
2878 [ (Format.Ledger.posting ("A":|["B", "C"]))
2879 { Format.Ledger.posting_comments = [" some comment N:V"]
2880 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2881 , Format.Ledger.posting_tags = Data.Map.fromList
2886 , " A:B:C ; some comment N:V v, N2:V2 v2 = Right A:B:C ; some comment N:V v, N2:V2 v2" ~:
2887 (Data.List.map fst $
2888 Data.Either.rights $
2889 [P.runParser_with_Error
2890 (Format.Ledger.Read.posting )
2891 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V v, N2:V2 v2"::Text)])
2893 [ (Format.Ledger.posting ("A":|["B", "C"]))
2894 { Format.Ledger.posting_comments = [" some comment N:V v, N2:V2 v2"]
2895 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2896 , Format.Ledger.posting_tags = Data.Map.fromList
2902 , " A:B:C ; N:V\\n ; N:V2 = Right A:B:C ; N:V\\n ; N:V2" ~:
2903 (Data.List.map fst $
2904 Data.Either.rights $
2905 [P.runParser_with_Error
2906 (Format.Ledger.Read.posting <* P.eof)
2907 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N:V2"::Text)])
2909 [ (Format.Ledger.posting ("A":|["B", "C"]))
2910 { Format.Ledger.posting_comments = [" N:V", " N:V2"]
2911 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2912 , Format.Ledger.posting_tags = Data.Map.fromList
2913 [ ("N", ["V", "V2"])
2917 , " A:B:C ; N:V\\n ; N2:V = Right A:B:C ; N:V\\n ; N2:V" ~:
2918 (Data.List.map fst $
2919 Data.Either.rights $
2920 [P.runParser_with_Error
2921 (Format.Ledger.Read.posting <* P.eof)
2922 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N2:V"::Text)])
2924 [ (Format.Ledger.posting ("A":|["B", "C"]))
2925 { Format.Ledger.posting_comments = [" N:V", " N2:V"]
2926 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2927 , Format.Ledger.posting_tags = Data.Map.fromList
2933 , " A:B:C ; date:2001/01/01 = Right A:B:C ; date:2001/01/01" ~:
2934 (Data.List.map fst $
2935 Data.Either.rights $
2936 [P.runParser_with_Error
2937 (Format.Ledger.Read.posting <* P.eof)
2938 Format.Ledger.Read.nil_Context "" (" A:B:C ; date:2001/01/01"::Text)])
2940 [ (Format.Ledger.posting ("A":|["B", "C"]))
2941 { Format.Ledger.posting_comments = [" date:2001/01/01"]
2942 , Format.Ledger.posting_dates =
2945 (Time.fromGregorian 2001 01 01)
2946 (Time.TimeOfDay 0 0 0))
2949 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2950 , Format.Ledger.posting_tags = Data.Map.fromList
2951 [ ("date", ["2001/01/01"])
2955 , " (A:B:C) = Right (A:B:C)" ~:
2956 (Data.Either.rights $
2957 [P.runParser_with_Error
2958 (Format.Ledger.Read.posting <* P.eof)
2959 Format.Ledger.Read.nil_Context "" (" (A:B:C)"::Text)])
2961 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
2962 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2964 , Format.Ledger.Posting_Type_Virtual
2967 , " [A:B:C] = Right [A:B:C]" ~:
2968 (Data.Either.rights $
2969 [P.runParser_with_Error
2970 (Format.Ledger.Read.posting <* P.eof)
2971 Format.Ledger.Read.nil_Context "" (" [A:B:C]"::Text)])
2973 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
2974 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
2976 , Format.Ledger.Posting_Type_Virtual_Balanced
2980 , "transaction" ~: TestList
2981 [ "2000/01/01 some description\\n A:B:C $1\\n a:b:c" ~:
2982 (Data.Either.rights $
2983 [P.runParser_with_Error
2984 (Format.Ledger.Read.transaction <* P.eof)
2985 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c"::Text)])
2987 [ Format.Ledger.transaction
2988 { Format.Ledger.transaction_dates=
2991 (Time.fromGregorian 2000 01 01)
2992 (Time.TimeOfDay 0 0 0))
2995 , Format.Ledger.transaction_description="some description"
2996 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
2997 [ (Format.Ledger.posting ("A":|["B", "C"]))
2998 { Format.Ledger.posting_amounts = Data.Map.fromList
3000 { Amount.quantity = 1
3001 , Amount.style = Amount.Style.nil
3002 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3003 , Amount.Style.unit_spaced = Just False
3008 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3010 , (Format.Ledger.posting ("a":|["b", "c"]))
3011 { Format.Ledger.posting_amounts = Data.Map.fromList
3013 { Amount.quantity = -1
3014 , Amount.style = Amount.Style.nil
3015 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3016 , Amount.Style.unit_spaced = Just False
3021 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3024 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3027 , "2000/01/01 some description\\n A:B:C $1\\n a:b:c\\n" ~:
3028 (Data.Either.rights $
3029 [P.runParser_with_Error
3030 (Format.Ledger.Read.transaction <* P.newline <* P.eof)
3031 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c\n"::Text)])
3033 [ Format.Ledger.transaction
3034 { Format.Ledger.transaction_dates=
3037 (Time.fromGregorian 2000 01 01)
3038 (Time.TimeOfDay 0 0 0))
3041 , Format.Ledger.transaction_description="some description"
3042 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3043 [ (Format.Ledger.posting ("A":|["B", "C"]))
3044 { Format.Ledger.posting_amounts = Data.Map.fromList
3046 { Amount.quantity = 1
3047 , Amount.style = Amount.Style.nil
3048 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3049 , Amount.Style.unit_spaced = Just False
3054 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3056 , (Format.Ledger.posting ("a":|["b", "c"]))
3057 { Format.Ledger.posting_amounts = Data.Map.fromList
3059 { Amount.quantity = -1
3060 , Amount.style = Amount.Style.nil
3061 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3062 , Amount.Style.unit_spaced = Just False
3067 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3070 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3073 , "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" ~:
3074 (Data.Either.rights $
3075 [P.runParser_with_Error
3076 (Format.Ledger.Read.transaction <* P.eof)
3077 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)])
3079 [ Format.Ledger.transaction
3080 { Format.Ledger.transaction_comments_after =
3082 , " some other;comment"
3084 , " some last comment"
3086 , Format.Ledger.transaction_dates=
3089 (Time.fromGregorian 2000 01 01)
3090 (Time.TimeOfDay 0 0 0))
3093 , Format.Ledger.transaction_description="some description"
3094 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3095 [ (Format.Ledger.posting ("A":|["B", "C"]))
3096 { Format.Ledger.posting_amounts = Data.Map.fromList
3098 { Amount.quantity = 1
3099 , Amount.style = Amount.Style.nil
3100 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3101 , Amount.Style.unit_spaced = Just False
3106 , Format.Ledger.posting_sourcepos = P.newPos "" 5 1
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 "" 6 1
3122 , Format.Ledger.transaction_tags = Data.Map.fromList
3125 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3129 , "journal" ~: TestList
3130 [ "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
3132 P.runParserT_with_Error
3133 (Format.Ledger.Read.journal "" {-<* P.eof-})
3134 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)
3136 (\j -> j{Format.Ledger.journal_last_read_time=
3137 Format.Ledger.journal_last_read_time Format.Ledger.journal}) $
3138 Data.Either.rights [jnl])
3140 [ Format.Ledger.journal
3141 { Format.Ledger.journal_transactions =
3142 Format.Ledger.transaction_by_Date
3143 [ Format.Ledger.transaction
3144 { Format.Ledger.transaction_dates=
3147 (Time.fromGregorian 2000 01 01)
3148 (Time.TimeOfDay 0 0 0))
3151 , Format.Ledger.transaction_description="1° description"
3152 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3153 [ (Format.Ledger.posting ("A":|["B", "C"]))
3154 { Format.Ledger.posting_amounts = Data.Map.fromList
3156 { Amount.quantity = 1
3157 , Amount.style = Amount.Style.nil
3158 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3159 , Amount.Style.unit_spaced = Just False
3164 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3166 , (Format.Ledger.posting ("a":|["b", "c"]))
3167 { Format.Ledger.posting_amounts = Data.Map.fromList
3169 { Amount.quantity = -1
3170 , Amount.style = Amount.Style.nil
3171 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3172 , Amount.Style.unit_spaced = Just False
3177 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3180 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3182 , Format.Ledger.transaction
3183 { Format.Ledger.transaction_dates=
3186 (Time.fromGregorian 2000 01 02)
3187 (Time.TimeOfDay 0 0 0))
3190 , Format.Ledger.transaction_description="2° description"
3191 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3192 [ (Format.Ledger.posting ("A":|["B", "C"]))
3193 { Format.Ledger.posting_amounts = Data.Map.fromList
3195 { Amount.quantity = 1
3196 , Amount.style = Amount.Style.nil
3197 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3198 , Amount.Style.unit_spaced = Just False
3203 , Format.Ledger.posting_sourcepos = P.newPos "" 5 1
3205 , (Format.Ledger.posting ("x":|["y", "z"]))
3206 { Format.Ledger.posting_amounts = Data.Map.fromList
3208 { Amount.quantity = -1
3209 , Amount.style = Amount.Style.nil
3210 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3211 , Amount.Style.unit_spaced = Just False
3216 , Format.Ledger.posting_sourcepos = P.newPos "" 6 1
3219 , Format.Ledger.transaction_sourcepos = P.newPos "" 4 1
3226 , "Write" ~: TestList
3227 [ "account" ~: TestList
3229 ((Format.Ledger.Write.show
3230 Format.Ledger.Write.Style
3231 { Format.Ledger.Write.style_color=False
3232 , Format.Ledger.Write.style_align=True
3234 Format.Ledger.Write.account Format.Ledger.Posting_Type_Regular $
3239 ((Format.Ledger.Write.show
3240 Format.Ledger.Write.Style
3241 { Format.Ledger.Write.style_color=False
3242 , Format.Ledger.Write.style_align=True
3244 Format.Ledger.Write.account Format.Ledger.Posting_Type_Regular $
3249 ((Format.Ledger.Write.show
3250 Format.Ledger.Write.Style
3251 { Format.Ledger.Write.style_color=False
3252 , Format.Ledger.Write.style_align=True
3254 Format.Ledger.Write.account Format.Ledger.Posting_Type_Virtual $
3259 ((Format.Ledger.Write.show
3260 Format.Ledger.Write.Style
3261 { Format.Ledger.Write.style_color=False
3262 , Format.Ledger.Write.style_align=True
3264 Format.Ledger.Write.account Format.Ledger.Posting_Type_Virtual_Balanced $
3269 , "amount" ~: TestList
3271 ((Format.Ledger.Write.show
3272 Format.Ledger.Write.Style
3273 { Format.Ledger.Write.style_color=False
3274 , Format.Ledger.Write.style_align=True
3276 Format.Ledger.Write.amount
3281 ((Format.Ledger.Write.show
3282 Format.Ledger.Write.Style
3283 { Format.Ledger.Write.style_color=False
3284 , Format.Ledger.Write.style_align=True
3286 Format.Ledger.Write.amount
3288 { Amount.style = Amount.Style.nil
3289 { Amount.Style.precision = 2 }
3294 ((Format.Ledger.Write.show
3295 Format.Ledger.Write.Style
3296 { Format.Ledger.Write.style_color=False
3297 , Format.Ledger.Write.style_align=True
3299 Format.Ledger.Write.amount
3301 { Amount.quantity = Decimal 0 123
3306 ((Format.Ledger.Write.show
3307 Format.Ledger.Write.Style
3308 { Format.Ledger.Write.style_color=False
3309 , Format.Ledger.Write.style_align=True
3311 Format.Ledger.Write.amount
3313 { Amount.quantity = Decimal 0 (- 123)
3317 , "12.3 @ prec=0" ~:
3318 ((Format.Ledger.Write.show
3319 Format.Ledger.Write.Style
3320 { Format.Ledger.Write.style_color=False
3321 , Format.Ledger.Write.style_align=True
3323 Format.Ledger.Write.amount
3325 { Amount.quantity = Decimal 1 123
3326 , Amount.style = Amount.Style.nil
3327 { Amount.Style.fractioning = Just '.'
3332 , "12.5 @ 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 125
3341 , Amount.style = Amount.Style.nil
3342 { Amount.Style.fractioning = Just '.'
3347 , "12.3 @ prec=1" ~:
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 123
3356 , Amount.style = Amount.Style.nil
3357 { Amount.Style.fractioning = Just '.'
3358 , Amount.Style.precision = 1
3363 , "1,234.56 @ prec=2" ~:
3364 ((Format.Ledger.Write.show
3365 Format.Ledger.Write.Style
3366 { Format.Ledger.Write.style_color=False
3367 , Format.Ledger.Write.style_align=True
3369 Format.Ledger.Write.amount
3371 { Amount.quantity = Decimal 2 123456
3372 , Amount.style = Amount.Style.nil
3373 { Amount.Style.fractioning = Just '.'
3374 , Amount.Style.precision = 2
3375 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
3380 , "123,456,789,01,2.3456789 @ prec=7" ~:
3381 ((Format.Ledger.Write.show
3382 Format.Ledger.Write.Style
3383 { Format.Ledger.Write.style_color=False
3384 , Format.Ledger.Write.style_align=True
3386 Format.Ledger.Write.amount
3388 { Amount.quantity = Decimal 7 1234567890123456789
3389 , Amount.style = Amount.Style.nil
3390 { Amount.Style.fractioning = Just '.'
3391 , Amount.Style.precision = 7
3392 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3396 "123,456,789,01,2.3456789")
3397 , "1234567.8,90,123,456,789 @ prec=12" ~:
3398 ((Format.Ledger.Write.show
3399 Format.Ledger.Write.Style
3400 { Format.Ledger.Write.style_color=False
3401 , Format.Ledger.Write.style_align=True
3403 Format.Ledger.Write.amount
3405 { Amount.quantity = Decimal 12 1234567890123456789
3406 , Amount.style = Amount.Style.nil
3407 { Amount.Style.fractioning = Just '.'
3408 , Amount.Style.precision = 12
3409 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3413 "1234567.8,90,123,456,789")
3414 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
3415 ((Format.Ledger.Write.show
3416 Format.Ledger.Write.Style
3417 { Format.Ledger.Write.style_color=False
3418 , Format.Ledger.Write.style_align=True
3420 Format.Ledger.Write.amount
3422 { Amount.quantity = Decimal 7 1234567890123456789
3423 , Amount.style = Amount.Style.nil
3424 { Amount.Style.fractioning = Just '.'
3425 , Amount.Style.precision = 7
3426 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3430 "1,2,3,4,5,6,7,89,012.3456789")
3431 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
3432 ((Format.Ledger.Write.show
3433 Format.Ledger.Write.Style
3434 { Format.Ledger.Write.style_color=False
3435 , Format.Ledger.Write.style_align=True
3437 Format.Ledger.Write.amount
3439 { Amount.quantity = Decimal 12 1234567890123456789
3440 , Amount.style = Amount.Style.nil
3441 { Amount.Style.fractioning = Just '.'
3442 , Amount.Style.precision = 12
3443 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3447 "1234567.890,12,3,4,5,6,7,8,9")
3449 , "amount_length" ~: TestList
3451 ((Format.Ledger.Write.amount_length
3456 ((Format.Ledger.Write.amount_length
3458 { Amount.style = Amount.Style.nil
3459 { Amount.Style.precision = 2 }
3464 ((Format.Ledger.Write.amount_length
3466 { Amount.quantity = Decimal 0 123
3471 ((Format.Ledger.Write.amount_length
3473 { Amount.quantity = Decimal 0 (- 123)
3477 , "12.3 @ prec=0" ~:
3478 ((Format.Ledger.Write.amount_length
3480 { Amount.quantity = Decimal 1 123
3481 , Amount.style = Amount.Style.nil
3482 { Amount.Style.fractioning = Just '.'
3487 , "12.5 @ prec=0" ~:
3488 ((Format.Ledger.Write.amount_length
3490 { Amount.quantity = Decimal 1 125
3491 , Amount.style = Amount.Style.nil
3492 { Amount.Style.fractioning = Just '.'
3497 , "12.3 @ prec=1" ~:
3498 ((Format.Ledger.Write.amount_length
3500 { Amount.quantity = Decimal 1 123
3501 , Amount.style = Amount.Style.nil
3502 { Amount.Style.fractioning = Just '.'
3503 , Amount.Style.precision = 1
3508 , "1,234.56 @ prec=2" ~:
3509 ((Format.Ledger.Write.amount_length
3511 { Amount.quantity = Decimal 2 123456
3512 , Amount.style = Amount.Style.nil
3513 { Amount.Style.fractioning = Just '.'
3514 , Amount.Style.precision = 2
3515 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
3520 , "123,456,789,01,2.3456789 @ prec=7" ~:
3521 ((Format.Ledger.Write.amount_length
3523 { Amount.quantity = Decimal 7 1234567890123456789
3524 , Amount.style = Amount.Style.nil
3525 { Amount.Style.fractioning = Just '.'
3526 , Amount.Style.precision = 7
3527 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3532 , "1234567.8,90,123,456,789 @ prec=12" ~:
3533 ((Format.Ledger.Write.amount_length
3535 { Amount.quantity = Decimal 12 1234567890123456789
3536 , Amount.style = Amount.Style.nil
3537 { Amount.Style.fractioning = Just '.'
3538 , Amount.Style.precision = 12
3539 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
3544 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
3545 ((Format.Ledger.Write.amount_length
3547 { Amount.quantity = Decimal 7 1234567890123456789
3548 , Amount.style = Amount.Style.nil
3549 { Amount.Style.fractioning = Just '.'
3550 , Amount.Style.precision = 7
3551 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3556 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
3557 ((Format.Ledger.Write.amount_length
3559 { Amount.quantity = Decimal 12 1234567890123456789
3560 , Amount.style = Amount.Style.nil
3561 { Amount.Style.fractioning = Just '.'
3562 , Amount.Style.precision = 12
3563 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3568 , "1000000.000,00,0,0,0,0,0,0,0 @ prec=12" ~:
3569 ((Format.Ledger.Write.amount_length
3571 { Amount.quantity = Decimal 12 1000000000000000000
3572 , Amount.style = Amount.Style.nil
3573 { Amount.Style.fractioning = Just '.'
3574 , Amount.Style.precision = 12
3575 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
3581 ((Format.Ledger.Write.amount_length $
3583 { Amount.quantity = Decimal 0 999
3584 , Amount.style = Amount.Style.nil
3585 { Amount.Style.precision = 0
3590 , "1000 @ prec=0" ~:
3591 ((Format.Ledger.Write.amount_length $
3593 { Amount.quantity = Decimal 0 1000
3594 , Amount.style = Amount.Style.nil
3595 { Amount.Style.precision = 0
3600 , "10,00€ @ prec=2" ~:
3601 ((Format.Ledger.Write.amount_length $ Amount.eur 10)
3605 , "date" ~: TestList
3607 ((Format.Ledger.Write.show
3608 Format.Ledger.Write.Style
3609 { Format.Ledger.Write.style_color=False
3610 , Format.Ledger.Write.style_align=True
3612 Format.Ledger.Write.date
3616 , "2000/01/01 12:34:51 CET" ~:
3617 (Format.Ledger.Write.show
3618 Format.Ledger.Write.Style
3619 { Format.Ledger.Write.style_color=False
3620 , Format.Ledger.Write.style_align=True
3622 Format.Ledger.Write.date $
3625 (Time.fromGregorian 2000 01 01)
3626 (Time.TimeOfDay 12 34 51))
3627 (Time.TimeZone 60 False "CET"))
3629 "2000/01/01 12:34:51 CET"
3630 , "2000/01/01 12:34:51 +0100" ~:
3631 (Format.Ledger.Write.show
3632 Format.Ledger.Write.Style
3633 { Format.Ledger.Write.style_color=False
3634 , Format.Ledger.Write.style_align=True
3636 Format.Ledger.Write.date $
3639 (Time.fromGregorian 2000 01 01)
3640 (Time.TimeOfDay 12 34 51))
3641 (Time.TimeZone 60 False ""))
3643 "2000/01/01 12:34:51 +0100"
3644 , "2000/01/01 01:02:03" ~:
3645 (Format.Ledger.Write.show
3646 Format.Ledger.Write.Style
3647 { Format.Ledger.Write.style_color=False
3648 , Format.Ledger.Write.style_align=True
3650 Format.Ledger.Write.date $
3653 (Time.fromGregorian 2000 01 01)
3654 (Time.TimeOfDay 1 2 3))
3657 "2000/01/01 01:02:03"
3659 (Format.Ledger.Write.show
3660 Format.Ledger.Write.Style
3661 { Format.Ledger.Write.style_color=False
3662 , Format.Ledger.Write.style_align=True
3664 Format.Ledger.Write.date $
3667 (Time.fromGregorian 0 01 01)
3668 (Time.TimeOfDay 1 2 0))
3673 (Format.Ledger.Write.show
3674 Format.Ledger.Write.Style
3675 { Format.Ledger.Write.style_color=False
3676 , Format.Ledger.Write.style_align=True
3678 Format.Ledger.Write.date $
3681 (Time.fromGregorian 0 01 01)
3682 (Time.TimeOfDay 1 0 0))
3687 (Format.Ledger.Write.show
3688 Format.Ledger.Write.Style
3689 { Format.Ledger.Write.style_color=False
3690 , Format.Ledger.Write.style_align=True
3692 Format.Ledger.Write.date $
3695 (Time.fromGregorian 0 01 01)
3696 (Time.TimeOfDay 0 1 0))
3701 (Format.Ledger.Write.show
3702 Format.Ledger.Write.Style
3703 { Format.Ledger.Write.style_color=False
3704 , Format.Ledger.Write.style_align=True
3706 Format.Ledger.Write.date $
3709 (Time.fromGregorian 0 01 01)
3710 (Time.TimeOfDay 0 0 0))
3715 , "transaction" ~: TestList
3717 ((Format.Ledger.Write.show
3718 Format.Ledger.Write.Style
3719 { Format.Ledger.Write.style_color=False
3720 , Format.Ledger.Write.style_align=True
3722 Format.Ledger.Write.transaction
3723 Format.Ledger.transaction)
3726 , "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" ~:
3727 ((Format.Ledger.Write.show
3728 Format.Ledger.Write.Style
3729 { Format.Ledger.Write.style_color=False
3730 , Format.Ledger.Write.style_align=True
3732 Format.Ledger.Write.transaction $
3733 Format.Ledger.transaction
3734 { Format.Ledger.transaction_dates=
3737 (Time.fromGregorian 2000 01 01)
3738 (Time.TimeOfDay 0 0 0))
3741 , Format.Ledger.transaction_description="some description"
3742 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3743 [ (Format.Ledger.posting ("A":|["B", "C"]))
3744 { Format.Ledger.posting_amounts = Data.Map.fromList
3746 { Amount.quantity = 1
3747 , Amount.style = Amount.Style.nil
3748 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3749 , Amount.Style.unit_spaced = Just False
3755 , (Format.Ledger.posting ("a":|["b", "c"]))
3756 { Format.Ledger.posting_comments = ["first comment","second comment","third comment"]
3761 "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")
3762 , "2000/01/01 some description\\n\\tA:B:C $1\\n\\tAA:BB:CC $123" ~:
3763 ((Format.Ledger.Write.show
3764 Format.Ledger.Write.Style
3765 { Format.Ledger.Write.style_color=False
3766 , Format.Ledger.Write.style_align=True
3768 Format.Ledger.Write.transaction $
3769 Format.Ledger.transaction
3770 { Format.Ledger.transaction_dates=
3773 (Time.fromGregorian 2000 01 01)
3774 (Time.TimeOfDay 0 0 0))
3777 , Format.Ledger.transaction_description="some description"
3778 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3779 [ (Format.Ledger.posting ("A":|["B", "C"]))
3780 { Format.Ledger.posting_amounts = Data.Map.fromList
3782 { Amount.quantity = 1
3783 , Amount.style = Amount.Style.nil
3784 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3785 , Amount.Style.unit_spaced = Just False
3791 , (Format.Ledger.posting ("AA":|["BB", "CC"]))
3792 { Format.Ledger.posting_amounts = Data.Map.fromList
3794 { Amount.quantity = 123
3795 , Amount.style = Amount.Style.nil
3796 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3797 , Amount.Style.unit_spaced = Just False
3806 "2000/01/01 some description\n\tA:B:C $1\n\tAA:BB:CC $123")