1 {-# LANGUAGE TupleSections #-}
2 {-# LANGUAGE OverloadedStrings #-}
6 import Test.Framework.Providers.HUnit (hUnitTestToTests)
7 import Test.Framework.Runners.Console (defaultMain)
9 import Control.Applicative ((<*))
10 import Control.Monad.IO.Class (liftIO)
11 import Data.Decimal (DecimalRaw(..))
12 import qualified Data.Either
13 import qualified Data.List
14 import qualified Data.Map.Strict as Data.Map
15 import qualified Data.Time.Calendar as Time
16 import qualified Data.Time.LocalTime as Time
17 import qualified Text.Parsec as P
18 import qualified Text.Parsec.Pos as P
20 import qualified Hcompta.Model.Account as Account
21 import qualified Hcompta.Model.Amount as Amount
22 import qualified Hcompta.Model.Amount.Style as Style
23 import qualified Hcompta.Model.Transaction as Transaction
24 import qualified Hcompta.Model.Transaction.Posting as Posting
25 import qualified Hcompta.Calc.Balance as Calc.Balance
26 import qualified Hcompta.Format.Ledger.Read as Format.Ledger.Read
27 import qualified Hcompta.Format.Ledger.Journal as Format.Ledger.Journal
29 --instance Eq Text.Parsec.ParseError where
30 -- (==) = const (const False)
33 main = defaultMain $ hUnitTestToTests test_Hcompta
39 [ "Account" ~: TestList
42 (reverse $ Account.fold [] (:) []) ~?= []
44 (reverse $ Account.fold ["A"] (:) []) ~?= [["A"]]
45 , "[A, B] = [[A], [A, B]]" ~:
46 (reverse $ Account.fold ["A", "B"] (:) []) ~?= [["A"], ["A", "B"]]
47 , "[A, B, C] = [[A], [A, B], [A, B, C]]" ~:
48 (reverse $ Account.fold ["A", "B", "C"] (:) []) ~?= [["A"], ["A", "B"], ["A", "B", "C"]]
50 , "ascending" ~: TestList
52 Account.ascending [] ~?= []
54 Account.ascending ["A"] ~?= []
56 Account.ascending ["A", "B"] ~?= ["A"]
57 , "[A, B, C] = [A, B]" ~:
58 Account.ascending ["A", "B", "C"] ~?= ["A", "B"]
61 , "Amount" ~: TestList
66 { Amount.quantity = Decimal 0 1
67 , Amount.style = Style.nil
68 { Style.unit_side = Just $ Style.Side_Left
73 { Amount.quantity = Decimal 0 1
74 , Amount.style = Style.nil
75 { Style.unit_side = Just $ Style.Side_Right
81 { Amount.quantity = Decimal 0 2
82 , Amount.style = Style.nil
83 { Style.unit_side = Just $ Style.Side_Left
88 , "from_List" ~: TestList
89 [ "from_List [$1, 1$] = $2" ~:
92 { Amount.quantity = Decimal 0 1
93 , Amount.style = Style.nil
94 { Style.unit_side = Just $ Style.Side_Left
99 { Amount.quantity = Decimal 0 1
100 , Amount.style = Style.nil
101 { Style.unit_side = Just $ Style.Side_Right
109 { Amount.quantity = Decimal 0 2
110 , Amount.style = Style.nil
111 { Style.unit_side = Just $ Style.Side_Left
120 [ "Balance" ~: TestList
121 [ "posting" ~: TestList
122 [ "[A+$1] = A+$1 & $+1" ~:
123 (Calc.Balance.posting
125 { Posting.account=["A"]
126 , Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
131 { Calc.Balance.by_account =
133 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
134 , Calc.Balance.by_unit =
136 Data.List.map Calc.Balance.assoc_by_amount_unit $
137 [ Calc.Balance.Sum_by_Unit
138 { Calc.Balance.amount = Amount.usd $ 1
139 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
144 , "[A+$1, A-$1] = {A+$0, $+0}" ~:
146 (flip Calc.Balance.posting)
149 { Posting.account=["A"]
150 , Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
153 { Posting.account=["A"]
154 , Posting.amounts=Amount.from_List [ Amount.usd $ -1 ]
159 { Calc.Balance.by_account =
161 [ (["A"], Amount.from_List [ Amount.usd $ 0 ]) ]
162 , Calc.Balance.by_unit =
164 Data.List.map Calc.Balance.assoc_by_amount_unit $
165 [ Calc.Balance.Sum_by_Unit
166 { Calc.Balance.amount = Amount.usd $ 0
167 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
172 , "[A+$1, A-€1] = {A+$1-€1, $+1 €-1}" ~:
174 (flip Calc.Balance.posting)
177 { Posting.account=["A"]
178 , Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
181 { Posting.account=["A"]
182 , Posting.amounts=Amount.from_List [ Amount.eur $ -1 ]
187 { Calc.Balance.by_account =
189 [ (["A"], Amount.from_List [ Amount.usd $ 1, Amount.eur $ -1 ]) ]
190 , Calc.Balance.by_unit =
192 Data.List.map Calc.Balance.assoc_by_amount_unit $
193 [ Calc.Balance.Sum_by_Unit
194 { Calc.Balance.amount = Amount.usd $ 1
195 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
198 , Calc.Balance.Sum_by_Unit
199 { Calc.Balance.amount = Amount.eur $ -1
200 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
205 , "[A+$1, B-$1] = {A+$1 B-$1, $+0}" ~:
207 (flip Calc.Balance.posting)
210 { Posting.account=["A"]
211 , Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
214 { Posting.account=["B"]
215 , Posting.amounts=Amount.from_List [ Amount.usd $ -1 ]
220 { Calc.Balance.by_account =
222 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
223 , (["B"], Amount.from_List [ Amount.usd $ -1 ])
225 , Calc.Balance.by_unit =
227 Data.List.map Calc.Balance.assoc_by_amount_unit $
228 [ Calc.Balance.Sum_by_Unit
229 { Calc.Balance.amount = Amount.usd $ 0
230 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
235 , "[A+$1+€2, A-$1-€2] = {A+$0+€0, $+0 €+0}" ~:
237 (flip Calc.Balance.posting)
240 { Posting.account=["A"]
241 , Posting.amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2 ]
244 { Posting.account=["A"]
245 , Posting.amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2 ]
250 { Calc.Balance.by_account =
252 [ (["A"], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
254 , Calc.Balance.by_unit =
256 Data.List.map Calc.Balance.assoc_by_amount_unit $
257 [ Calc.Balance.Sum_by_Unit
258 { Calc.Balance.amount = Amount.usd $ 0
259 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
262 , Calc.Balance.Sum_by_Unit
263 { Calc.Balance.amount = Amount.eur $ 0
264 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
269 , "[A+$1+€2+£3, B-$1-2€-£3] = {A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~:
271 (flip Calc.Balance.posting)
274 { Posting.account=["A"]
275 , Posting.amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ]
278 { Posting.account=["B"]
279 , Posting.amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ]
284 { Calc.Balance.by_account =
286 [ (["A"], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
287 , (["B"], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
289 , Calc.Balance.by_unit =
291 Data.List.map Calc.Balance.assoc_by_amount_unit $
292 [ Calc.Balance.Sum_by_Unit
293 { Calc.Balance.amount = Amount.usd $ 0
294 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
297 , Calc.Balance.Sum_by_Unit
298 { Calc.Balance.amount = Amount.eur $ 0
299 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
302 , Calc.Balance.Sum_by_Unit
303 { Calc.Balance.amount = Amount.gbp $ 0
304 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
310 , "union" ~: TestList
317 , "{A+$1, $+1} {A+$1, $+1} = {A+$2, $+2}" ~:
319 (Calc.Balance.Balance
320 { Calc.Balance.by_account =
322 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
323 , Calc.Balance.by_unit =
325 Data.List.map Calc.Balance.assoc_by_amount_unit $
326 [ Calc.Balance.Sum_by_Unit
327 { Calc.Balance.amount = Amount.usd $ 1
328 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
333 (Calc.Balance.Balance
334 { Calc.Balance.by_account =
336 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
337 , Calc.Balance.by_unit =
339 Data.List.map Calc.Balance.assoc_by_amount_unit $
340 [ Calc.Balance.Sum_by_Unit
341 { Calc.Balance.amount = Amount.usd $ 1
342 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
349 { Calc.Balance.by_account =
351 [ (["A"], Amount.from_List [ Amount.usd $ 2 ]) ]
352 , Calc.Balance.by_unit =
354 Data.List.map Calc.Balance.assoc_by_amount_unit $
355 [ Calc.Balance.Sum_by_Unit
356 { Calc.Balance.amount = Amount.usd $ 2
357 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
362 , "{A+$1, $+1} {B+$1, $+1} = {A+$1 B+$1, $+2}" ~:
364 (Calc.Balance.Balance
365 { Calc.Balance.by_account =
367 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
368 , Calc.Balance.by_unit =
370 Data.List.map Calc.Balance.assoc_by_amount_unit $
371 [ Calc.Balance.Sum_by_Unit
372 { Calc.Balance.amount = Amount.usd $ 1
373 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
378 (Calc.Balance.Balance
379 { Calc.Balance.by_account =
381 [ (["B"], Amount.from_List [ Amount.usd $ 1 ]) ]
382 , Calc.Balance.by_unit =
384 Data.List.map Calc.Balance.assoc_by_amount_unit $
385 [ Calc.Balance.Sum_by_Unit
386 { Calc.Balance.amount = Amount.usd $ 1
387 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
394 { Calc.Balance.by_account =
396 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
397 , (["B"], Amount.from_List [ Amount.usd $ 1 ]) ]
398 , Calc.Balance.by_unit =
400 Data.List.map Calc.Balance.assoc_by_amount_unit $
401 [ Calc.Balance.Sum_by_Unit
402 { Calc.Balance.amount = Amount.usd $ 2
403 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
408 , "{A+$1, $+1} {B+€1, €+1} = {A+$1 B+€1, $+1 €+1}" ~:
410 (Calc.Balance.Balance
411 { Calc.Balance.by_account =
413 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
414 , Calc.Balance.by_unit =
416 Data.List.map Calc.Balance.assoc_by_amount_unit $
417 [ Calc.Balance.Sum_by_Unit
418 { Calc.Balance.amount = Amount.usd $ 1
419 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
424 (Calc.Balance.Balance
425 { Calc.Balance.by_account =
427 [ (["B"], Amount.from_List [ Amount.eur $ 1 ]) ]
428 , Calc.Balance.by_unit =
430 Data.List.map Calc.Balance.assoc_by_amount_unit $
431 [ Calc.Balance.Sum_by_Unit
432 { Calc.Balance.amount = Amount.eur $ 1
433 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
440 { Calc.Balance.by_account =
442 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
443 , (["B"], Amount.from_List [ Amount.eur $ 1 ]) ]
444 , Calc.Balance.by_unit =
446 Data.List.map Calc.Balance.assoc_by_amount_unit $
447 [ Calc.Balance.Sum_by_Unit
448 { Calc.Balance.amount = Amount.usd $ 1
449 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
452 , Calc.Balance.Sum_by_Unit
453 { Calc.Balance.amount = Amount.eur $ 1
454 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
460 , "expand" ~: TestList
461 [ "nil_By_Account = nil_By_Account" ~:
463 Calc.Balance.nil_By_Account
465 (Calc.Balance.Expanded $
466 Calc.Balance.nil_By_Account)
470 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ])
472 (Calc.Balance.Expanded $
474 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ])
475 , "A/A+$1 = A+$1 A/A+$1" ~:
478 [ (["A", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
480 (Calc.Balance.Expanded $
482 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
483 , (["A", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
484 , "A/B+$1 = A+$1 A/B+$1" ~:
487 [ (["A", "B"], Amount.from_List [ Amount.usd $ 1 ]) ])
489 (Calc.Balance.Expanded $
491 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
492 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ]) ])
493 , "A/B/C+$1 = A+$1 A/B+$1 A/B/C+$1" ~:
496 [ (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ]) ])
498 (Calc.Balance.Expanded $
500 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
501 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
502 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ]) ])
503 , "A+$1 A/B+$1 = A+$2 A/B+$1" ~:
506 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
507 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ]) ])
509 (Calc.Balance.Expanded $
511 [ (["A"], Amount.from_List [ Amount.usd $ 2 ])
512 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ]) ])
513 , "A+$1 A/B+$1 A/B/C+$1 = A+$3 A/B+$2 A/B/C+$1" ~:
516 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
517 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
518 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ])
521 (Calc.Balance.Expanded $
523 [ (["A"], Amount.from_List [ Amount.usd $ 3 ])
524 , (["A", "B"], Amount.from_List [ Amount.usd $ 2 ])
525 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ])
527 , "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" ~:
530 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
531 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
532 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ])
533 , (["A", "B", "C", "D"], Amount.from_List [ Amount.usd $ 1 ])
536 (Calc.Balance.Expanded $
538 [ (["A"], Amount.from_List [ Amount.usd $ 4 ])
539 , (["A", "B"], Amount.from_List [ Amount.usd $ 3 ])
540 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 2 ])
541 , (["A", "B", "C", "D"], Amount.from_List [ Amount.usd $ 1 ])
543 , "A+$1 A/B+$1 B/A+$1 = A+$2 A/B+$1 B/A+$1" ~:
546 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
547 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
548 , (["B", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
550 (Calc.Balance.Expanded $
552 [ (["A"], Amount.from_List [ Amount.usd $ 2 ])
553 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
554 , (["B"], Amount.from_List [ Amount.usd $ 1 ])
555 , (["B", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
556 , "A+$1 A/B+$1 B/A+$1 = A+$2 A/B+$1 B/A+$1" ~:
559 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
560 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
561 , (["B", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
563 (Calc.Balance.Expanded $
565 [ (["A"], Amount.from_List [ Amount.usd $ 2 ])
566 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
567 , (["B"], Amount.from_List [ Amount.usd $ 1 ])
568 , (["B", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
570 , "is_equilibrated" ~: TestList
571 [ "nil = True" ~: TestCase $
573 Calc.Balance.is_equilibrated $
575 , "{A+$0, $+0} = True" ~: TestCase $
577 Calc.Balance.is_equilibrated $
579 { Calc.Balance.by_account =
581 [ (["A"], Amount.from_List [ Amount.usd $ 0 ])
583 , Calc.Balance.by_unit =
585 Data.List.map Calc.Balance.assoc_by_amount_unit $
586 [ Calc.Balance.Sum_by_Unit
587 { Calc.Balance.amount = Amount.usd $ 0
588 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
593 , "{A+$1, $+1} = False" ~: TestCase $
595 Calc.Balance.is_equilibrated $
597 { Calc.Balance.by_account =
599 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
601 , Calc.Balance.by_unit =
603 Data.List.map Calc.Balance.assoc_by_amount_unit $
604 [ Calc.Balance.Sum_by_Unit
605 { Calc.Balance.amount = Amount.usd $ 1
606 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
611 , "{A+$0+€0, $0 €+0} = True" ~: TestCase $
613 Calc.Balance.is_equilibrated $
615 { Calc.Balance.by_account =
617 [ (["A"], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
619 , Calc.Balance.by_unit =
621 Data.List.map Calc.Balance.assoc_by_amount_unit $
622 [ Calc.Balance.Sum_by_Unit
623 { Calc.Balance.amount = Amount.usd $ 0
624 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
627 , Calc.Balance.Sum_by_Unit
628 { Calc.Balance.amount = Amount.eur $ 0
629 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
634 , "{A+$1, B-$1, $+0} = True" ~: TestCase $
636 Calc.Balance.is_equilibrated $
638 { Calc.Balance.by_account =
640 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
641 , (["B"], Amount.from_List [ Amount.usd $ -1 ])
643 , Calc.Balance.by_unit =
645 Data.List.map Calc.Balance.assoc_by_amount_unit $
646 [ Calc.Balance.Sum_by_Unit
647 { Calc.Balance.amount = Amount.usd $ 0
648 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
653 , "{A+$1 B, $+1} = True" ~: TestCase $
655 Calc.Balance.is_equilibrated $
657 { Calc.Balance.by_account =
659 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
660 , (["B"], Amount.from_List [])
662 , Calc.Balance.by_unit =
664 Data.List.map Calc.Balance.assoc_by_amount_unit $
665 [ Calc.Balance.Sum_by_Unit
666 { Calc.Balance.amount = Amount.usd $ 1
667 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
672 , "{A+$1 B+€1, $+1 €+1} = True" ~: TestCase $
674 Calc.Balance.is_equilibrated $
676 { Calc.Balance.by_account =
678 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
679 , (["B"], Amount.from_List [ Amount.eur $ 1 ])
681 , Calc.Balance.by_unit =
683 Data.List.map Calc.Balance.assoc_by_amount_unit $
684 [ Calc.Balance.Sum_by_Unit
685 { Calc.Balance.amount = Amount.usd $ 1
686 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
689 , Calc.Balance.Sum_by_Unit
690 { Calc.Balance.amount = Amount.eur $ 1
691 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
696 , "{A+$1 B-$1+€1, $+0 €+1} = True" ~: TestCase $
698 Calc.Balance.is_equilibrated $
700 { Calc.Balance.by_account =
702 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
703 , (["B"], Amount.from_List [ Amount.usd $ -1, Amount.eur $ 1 ])
705 , Calc.Balance.by_unit =
707 Data.List.map Calc.Balance.assoc_by_amount_unit $
708 [ Calc.Balance.Sum_by_Unit
709 { Calc.Balance.amount = Amount.usd $ 0
710 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
713 , Calc.Balance.Sum_by_Unit
714 { Calc.Balance.amount = Amount.eur $ 1
715 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
720 , "{A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0} = True" ~: TestCase $
722 Calc.Balance.is_equilibrated $
724 { Calc.Balance.by_account =
726 [ (["A"], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
727 , (["B"], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
729 , Calc.Balance.by_unit =
731 Data.List.map Calc.Balance.assoc_by_amount_unit $
732 [ Calc.Balance.Sum_by_Unit
733 { Calc.Balance.amount = Amount.usd $ 0
734 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
737 , Calc.Balance.Sum_by_Unit
738 { Calc.Balance.amount = Amount.eur $ 0
739 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
742 , Calc.Balance.Sum_by_Unit
743 { Calc.Balance.amount = Amount.gbp $ 0
744 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
752 , "Format" ~: TestList
753 [ "Ledger" ~: TestList
755 [ "account_name" ~: TestList
757 (Data.Either.rights $
759 (Format.Ledger.Read.account_name <* P.eof)
763 , "\"A\" = Right \"A\"" ~:
764 (Data.Either.rights $
766 (Format.Ledger.Read.account_name <* P.eof)
770 , "\"AA\" = Right \"AA\"" ~:
771 (Data.Either.rights $
773 (Format.Ledger.Read.account_name <* P.eof)
778 (Data.Either.rights $
780 (Format.Ledger.Read.account_name <* P.eof)
785 (Data.Either.rights $
787 (Format.Ledger.Read.account_name <* P.eof)
792 (Data.Either.rights $
794 (Format.Ledger.Read.account_name <* P.eof)
799 (Data.Either.rights $
801 (Format.Ledger.Read.account_name <* P.eof)
806 (Data.Either.rights $
808 (Format.Ledger.Read.account_name <* P.eof)
812 , "\"A \" ^= Right" ~:
813 (Data.Either.rights $
815 (Format.Ledger.Read.account_name)
819 , "\"A A\" = Right \"A A\"" ~:
820 (Data.Either.rights $
822 (Format.Ledger.Read.account_name <* P.eof)
827 (Data.Either.rights $
829 (Format.Ledger.Read.account_name <* P.eof)
833 , "\"A \\n\" = Left" ~:
834 (Data.Either.rights $
836 (Format.Ledger.Read.account_name <* P.eof)
840 , "\"(A)A\" = Right \"(A)A\"" ~:
841 (Data.Either.rights $
843 (Format.Ledger.Read.account_name <* P.eof)
847 , "\"( )A\" = Right \"( )A\"" ~:
848 (Data.Either.rights $
850 (Format.Ledger.Read.account_name <* P.eof)
854 , "\"(A) A\" = Right \"(A) A\"" ~:
855 (Data.Either.rights $
857 (Format.Ledger.Read.account_name <* P.eof)
861 , "\"[ ]A\" = Right \"[ ]A\"" ~:
862 (Data.Either.rights $
864 (Format.Ledger.Read.account_name <* P.eof)
868 , "\"(A) \" = Left" ~:
869 (Data.Either.rights $
871 (Format.Ledger.Read.account_name <* P.eof)
875 , "\"(A)\" = Left" ~:
876 (Data.Either.rights $
878 (Format.Ledger.Read.account_name <* P.eof)
882 , "\"[A]A\" = Right \"(A)A\"" ~:
883 (Data.Either.rights $
885 (Format.Ledger.Read.account_name <* P.eof)
889 , "\"[A] A\" = Right \"[A] A\"" ~:
890 (Data.Either.rights $
892 (Format.Ledger.Read.account_name <* P.eof)
896 , "\"[A] \" = Left" ~:
897 (Data.Either.rights $
899 (Format.Ledger.Read.account_name <* P.eof)
903 , "\"[A]\" = Left" ~:
904 (Data.Either.rights $
906 (Format.Ledger.Read.account_name <* P.eof)
911 , "account" ~: TestList
913 (Data.Either.rights $
915 (Format.Ledger.Read.account <* P.eof)
919 , "\"A\" = Right [\"A\"]" ~:
920 (Data.Either.rights $
922 (Format.Ledger.Read.account <* P.eof)
927 (Data.Either.rights $
929 (Format.Ledger.Read.account <* P.eof)
934 (Data.Either.rights $
936 (Format.Ledger.Read.account <* P.eof)
941 (Data.Either.rights $
943 (Format.Ledger.Read.account <* P.eof)
948 (Data.Either.rights $
950 (Format.Ledger.Read.account <* P.eof)
954 , "\"A:B\" = Right [\"A\", \"B\"]" ~:
955 (Data.Either.rights $
957 (Format.Ledger.Read.account <* P.eof)
961 , "\"A:B:C\" = Right [\"A\", \"B\", \"C\"]" ~:
962 (Data.Either.rights $
964 (Format.Ledger.Read.account <* P.eof)
968 , "\"Aa:Bbb:Cccc\" = Right [\"Aa\", \"Bbb\", \":Cccc\"]" ~:
969 (Data.Either.rights $
971 (Format.Ledger.Read.account <* P.eof)
972 () "" "Aa:Bbb:Cccc"])
974 [["Aa", "Bbb", "Cccc"]]
975 , "\"A a : B b b : C c c c\" = Right [\"A a \", \" B b b \", \": C c c c\"]" ~:
976 (Data.Either.rights $
978 (Format.Ledger.Read.account <* P.eof)
979 () "" "A a : B b b : C c c c"])
981 [["A a ", " B b b ", " C c c c"]]
982 , "\"A: :C\" = Right [\"A\", \" \", \"C\"]" ~:
983 (Data.Either.rights $
985 (Format.Ledger.Read.account <* P.eof)
989 , "\"A::C\" = Left" ~:
990 (Data.Either.rights $
992 (Format.Ledger.Read.account <* P.eof)
997 , "amount" ~: TestList
999 (Data.Either.rights $
1001 (Format.Ledger.Read.amount <* P.eof)
1005 , "\"0\" = Right 0" ~:
1006 (Data.Either.rights $
1008 (Format.Ledger.Read.amount <* P.eof)
1012 { Amount.quantity = Decimal 0 0
1014 , "\"00\" = Right 0" ~:
1015 (Data.Either.rights $
1017 (Format.Ledger.Read.amount <* P.eof)
1021 { Amount.quantity = Decimal 0 0
1023 , "\"0.\" = Right 0." ~:
1024 (Data.Either.rights $
1026 (Format.Ledger.Read.amount <* P.eof)
1030 { Amount.quantity = Decimal 0 0
1033 { Style.fractioning = Just '.'
1036 , "\".0\" = Right 0.0" ~:
1037 (Data.Either.rights $
1039 (Format.Ledger.Read.amount <* P.eof)
1043 { Amount.quantity = Decimal 0 0
1046 { Style.fractioning = Just '.'
1047 , Style.precision = 1
1050 , "\"0,\" = Right 0," ~:
1051 (Data.Either.rights $
1053 (Format.Ledger.Read.amount <* P.eof)
1057 { Amount.quantity = Decimal 0 0
1060 { Style.fractioning = Just ','
1063 , "\",0\" = Right 0,0" ~:
1064 (Data.Either.rights $
1066 (Format.Ledger.Read.amount <* P.eof)
1070 { Amount.quantity = Decimal 0 0
1073 { Style.fractioning = Just ','
1074 , Style.precision = 1
1077 , "\"0_\" = Left" ~:
1078 (Data.Either.rights $
1080 (Format.Ledger.Read.amount <* P.eof)
1084 , "\"_0\" = Left" ~:
1085 (Data.Either.rights $
1087 (Format.Ledger.Read.amount <* P.eof)
1091 , "\"0.0\" = Right 0.0" ~:
1092 (Data.Either.rights $
1094 (Format.Ledger.Read.amount <* P.eof)
1098 { Amount.quantity = Decimal 0 0
1101 { Style.fractioning = Just '.'
1102 , Style.precision = 1
1105 , "\"00.00\" = Right 0.00" ~:
1106 (Data.Either.rights $
1108 (Format.Ledger.Read.amount <* P.eof)
1112 { Amount.quantity = Decimal 0 0
1115 { Style.fractioning = Just '.'
1116 , Style.precision = 2
1119 , "\"0,0\" = Right 0,0" ~:
1120 (Data.Either.rights $
1122 (Format.Ledger.Read.amount <* P.eof)
1126 { Amount.quantity = Decimal 0 0
1129 { Style.fractioning = Just ','
1130 , Style.precision = 1
1133 , "\"00,00\" = Right 0,00" ~:
1134 (Data.Either.rights $
1136 (Format.Ledger.Read.amount <* P.eof)
1140 { Amount.quantity = Decimal 0 0
1143 { Style.fractioning = Just ','
1144 , Style.precision = 2
1147 , "\"0_0\" = Right 0" ~:
1148 (Data.Either.rights $
1150 (Format.Ledger.Read.amount <* P.eof)
1154 { Amount.quantity = Decimal 0 0
1157 { Style.fractioning = Nothing
1158 , Style.grouping_integral = Just $ Style.Grouping '_' [1]
1159 , Style.precision = 0
1162 , "\"00_00\" = Right 0" ~:
1163 (Data.Either.rights $
1165 (Format.Ledger.Read.amount <* P.eof)
1169 { Amount.quantity = Decimal 0 0
1172 { Style.fractioning = Nothing
1173 , Style.grouping_integral = Just $ Style.Grouping '_' [2]
1174 , Style.precision = 0
1177 , "\"0,000.00\" = Right 0,000.00" ~:
1178 (Data.Either.rights $
1180 (Format.Ledger.Read.amount <* P.eof)
1184 { Amount.quantity = Decimal 0 0
1187 { Style.fractioning = Just '.'
1188 , Style.grouping_integral = Just $ Style.Grouping ',' [3]
1189 , Style.precision = 2
1192 , "\"0.000,00\" = Right 0.000,00" ~:
1193 (Data.Either.rights $
1195 (Format.Ledger.Read.amount)
1199 { Amount.quantity = Decimal 0 0
1202 { Style.fractioning = Just ','
1203 , Style.grouping_integral = Just $ Style.Grouping '.' [3]
1204 , Style.precision = 2
1207 , "\"1,000.00\" = Right 1,000.00" ~:
1208 (Data.Either.rights $
1210 (Format.Ledger.Read.amount <* P.eof)
1214 { Amount.quantity = Decimal 0 1000
1217 { Style.fractioning = Just '.'
1218 , Style.grouping_integral = Just $ Style.Grouping ',' [3]
1219 , Style.precision = 2
1222 , "\"1.000,00\" = Right 1.000,00" ~:
1223 (Data.Either.rights $
1225 (Format.Ledger.Read.amount)
1229 { Amount.quantity = Decimal 0 1000
1232 { Style.fractioning = Just ','
1233 , Style.grouping_integral = Just $ Style.Grouping '.' [3]
1234 , Style.precision = 2
1237 , "\"1,000.00.\" = Left" ~:
1238 (Data.Either.rights $
1240 (Format.Ledger.Read.amount)
1244 , "\"1.000,00,\" = Left" ~:
1245 (Data.Either.rights $
1247 (Format.Ledger.Read.amount)
1251 , "\"1,000.00_\" = Left" ~:
1252 (Data.Either.rights $
1254 (Format.Ledger.Read.amount)
1258 , "\"12\" = Right 12" ~:
1259 (Data.Either.rights $
1261 (Format.Ledger.Read.amount <* P.eof)
1265 { Amount.quantity = Decimal 0 123
1267 , "\"1.2\" = Right 1.2" ~:
1268 (Data.Either.rights $
1270 (Format.Ledger.Read.amount <* P.eof)
1274 { Amount.quantity = Decimal 1 12
1277 { Style.fractioning = Just '.'
1278 , Style.precision = 1
1281 , "\"1,2\" = Right 1,2" ~:
1282 (Data.Either.rights $
1284 (Format.Ledger.Read.amount <* P.eof)
1288 { Amount.quantity = Decimal 1 12
1291 { Style.fractioning = Just ','
1292 , Style.precision = 1
1295 , "\"12.23\" = Right 12.23" ~:
1296 (Data.Either.rights $
1298 (Format.Ledger.Read.amount <* P.eof)
1302 { Amount.quantity = Decimal 2 1234
1305 { Style.fractioning = Just '.'
1306 , Style.precision = 2
1309 , "\"12,23\" = Right 12,23" ~:
1310 (Data.Either.rights $
1312 (Format.Ledger.Read.amount <* P.eof)
1316 { Amount.quantity = Decimal 2 1234
1319 { Style.fractioning = Just ','
1320 , Style.precision = 2
1323 , "\"1_2\" = Right 1_2" ~:
1324 (Data.Either.rights $
1326 (Format.Ledger.Read.amount <* P.eof)
1330 { Amount.quantity = Decimal 0 12
1333 { Style.grouping_integral = Just $ Style.Grouping '_' [1]
1334 , Style.precision = 0
1337 , "\"1_23\" = Right 1_23" ~:
1338 (Data.Either.rights $
1340 (Format.Ledger.Read.amount <* P.eof)
1344 { Amount.quantity = Decimal 0 123
1347 { Style.grouping_integral = Just $ Style.Grouping '_' [2]
1348 , Style.precision = 0
1351 , "\"1_23_456\" = Right 1_23_456" ~:
1352 (Data.Either.rights $
1354 (Format.Ledger.Read.amount <* P.eof)
1358 { Amount.quantity = Decimal 0 123456
1361 { Style.grouping_integral = Just $ Style.Grouping '_' [3, 2]
1362 , Style.precision = 0
1365 , "\"1_23_456.7890_12345_678901\" = Right 1_23_456.7890_12345_678901" ~:
1366 (Data.Either.rights $
1368 (Format.Ledger.Read.amount <* P.eof)
1369 () "" "1_23_456.7890_12345_678901"])
1372 { Amount.quantity = Decimal 15 123456789012345678901
1375 { Style.fractioning = Just '.'
1376 , Style.grouping_integral = Just $ Style.Grouping '_' [3, 2]
1377 , Style.grouping_fractional = Just $ Style.Grouping '_' [4, 5, 6]
1378 , Style.precision = 15
1381 , "\"123456_78901_2345.678_90_1\" = Right 123456_78901_2345.678_90_1" ~:
1382 (Data.Either.rights $
1384 (Format.Ledger.Read.amount <* P.eof)
1385 () "" "123456_78901_2345.678_90_1"])
1388 { Amount.quantity = Decimal 6 123456789012345678901
1391 { Style.fractioning = Just '.'
1392 , Style.grouping_integral = Just $ Style.Grouping '_' [4, 5, 6]
1393 , Style.grouping_fractional = Just $ Style.Grouping '_' [3, 2]
1394 , Style.precision = 6
1397 , "\"$1\" = Right $1" ~:
1398 (Data.Either.rights $
1400 (Format.Ledger.Read.amount <* P.eof)
1404 { Amount.quantity = Decimal 0 1
1407 { Style.fractioning = Nothing
1408 , Style.grouping_integral = Nothing
1409 , Style.grouping_fractional = Nothing
1410 , Style.precision = 0
1411 , Style.unit_side = Just Style.Side_Left
1412 , Style.unit_spaced = Just False
1416 , "\"1$\" = Right 1$" ~:
1417 (Data.Either.rights $
1419 (Format.Ledger.Read.amount <* P.eof)
1423 { Amount.quantity = Decimal 0 1
1426 { Style.fractioning = Nothing
1427 , Style.grouping_integral = Nothing
1428 , Style.grouping_fractional = Nothing
1429 , Style.precision = 0
1430 , Style.unit_side = Just Style.Side_Right
1431 , Style.unit_spaced = Just False
1435 , "\"$ 1\" = Right $ 1" ~:
1436 (Data.Either.rights $
1438 (Format.Ledger.Read.amount <* P.eof)
1442 { Amount.quantity = Decimal 0 1
1445 { Style.fractioning = Nothing
1446 , Style.grouping_integral = Nothing
1447 , Style.grouping_fractional = Nothing
1448 , Style.precision = 0
1449 , Style.unit_side = Just Style.Side_Left
1450 , Style.unit_spaced = Just True
1454 , "\"1 $\" = Right 1 $" ~:
1455 (Data.Either.rights $
1457 (Format.Ledger.Read.amount <* P.eof)
1461 { Amount.quantity = Decimal 0 1
1464 { Style.fractioning = Nothing
1465 , Style.grouping_integral = Nothing
1466 , Style.grouping_fractional = Nothing
1467 , Style.precision = 0
1468 , Style.unit_side = Just Style.Side_Right
1469 , Style.unit_spaced = Just True
1473 , "\"-$1\" = Right $-1" ~:
1474 (Data.Either.rights $
1476 (Format.Ledger.Read.amount <* P.eof)
1480 { Amount.quantity = Decimal 0 (-1)
1483 { Style.fractioning = Nothing
1484 , Style.grouping_integral = Nothing
1485 , Style.grouping_fractional = Nothing
1486 , Style.precision = 0
1487 , Style.unit_side = Just Style.Side_Left
1488 , Style.unit_spaced = Just False
1492 , "\"\\\"4 2\\\"1\" = Right \\\"4 2\\\"1" ~:
1493 (Data.Either.rights $
1495 (Format.Ledger.Read.amount <* P.eof)
1499 { Amount.quantity = Decimal 0 1
1502 { Style.fractioning = Nothing
1503 , Style.grouping_integral = Nothing
1504 , Style.grouping_fractional = Nothing
1505 , Style.precision = 0
1506 , Style.unit_side = Just Style.Side_Left
1507 , Style.unit_spaced = Just False
1509 , Amount.unit = "4 2"
1511 , "\"1\\\"4 2\\\"\" = Right 1\\\"4 2\\\"" ~:
1512 (Data.Either.rights $
1514 (Format.Ledger.Read.amount <* P.eof)
1518 { Amount.quantity = Decimal 0 1
1521 { Style.fractioning = Nothing
1522 , Style.grouping_integral = Nothing
1523 , Style.grouping_fractional = Nothing
1524 , Style.precision = 0
1525 , Style.unit_side = Just Style.Side_Right
1526 , Style.unit_spaced = Just False
1528 , Amount.unit = "4 2"
1530 , "\"$1.000,00\" = Right $1.000,00" ~:
1531 (Data.Either.rights $
1533 (Format.Ledger.Read.amount <* P.eof)
1537 { Amount.quantity = Decimal 0 1000
1540 { Style.fractioning = Just ','
1541 , Style.grouping_integral = Just $ Style.Grouping '.' [3]
1542 , Style.grouping_fractional = Nothing
1543 , Style.precision = 2
1544 , Style.unit_side = Just Style.Side_Left
1545 , Style.unit_spaced = Just False
1549 , "\"1.000,00$\" = Right 1.000,00$" ~:
1550 (Data.Either.rights $
1552 (Format.Ledger.Read.amount <* P.eof)
1556 { Amount.quantity = Decimal 0 1000
1559 { Style.fractioning = Just ','
1560 , Style.grouping_integral = Just $ Style.Grouping '.' [3]
1561 , Style.grouping_fractional = Nothing
1562 , Style.precision = 2
1563 , Style.unit_side = Just Style.Side_Right
1564 , Style.unit_spaced = Just False
1569 , "comment" ~: TestList
1570 [ "; some comment = Right \" some comment\"" ~:
1571 (Data.Either.rights $
1573 (Format.Ledger.Read.comment <* P.eof)
1574 () "" "; some comment"])
1577 , "; some comment \\n = Right \" some comment \"" ~:
1578 (Data.Either.rights $
1580 (Format.Ledger.Read.comment <* P.newline <* P.eof)
1581 () "" "; some comment \n"])
1583 [ " some comment " ]
1584 , "; some comment \\r\\n = Right \" some comment \"" ~:
1585 (Data.Either.rights $
1587 (Format.Ledger.Read.comment <* P.string "\r\n" <* P.eof)
1588 () "" "; some comment \r\n"])
1590 [ " some comment " ]
1592 , "comments" ~: TestList
1593 [ "; some comment\\n ; some other comment = Right [\" some comment\", \" some other comment\"]" ~:
1594 (Data.Either.rights $
1596 (Format.Ledger.Read.comments <* P.eof)
1597 () "" "; some comment\n ; some other comment"])
1599 [ [" some comment", " some other comment"] ]
1600 , "; some comment \\n = Right \" some comment \"" ~:
1601 (Data.Either.rights $
1603 (Format.Ledger.Read.comments <* P.string "\n" <* P.eof)
1604 () "" "; some comment \n"])
1606 [ [" some comment "] ]
1608 , "date" ~: TestList
1609 [ "2000/01/01 = Right 2000/01/01" ~:
1610 (Data.Either.rights $
1612 (Format.Ledger.Read.date Nothing <* P.eof)
1613 () "" "2000/01/01"])
1617 (Time.fromGregorian 2000 01 01)
1618 (Time.TimeOfDay 0 0 0))
1620 , "2000/01/01 some text = Right 2000/01/01" ~:
1621 (Data.Either.rights $
1623 (Format.Ledger.Read.date Nothing)
1624 () "" "2000/01/01 some text"])
1628 (Time.fromGregorian 2000 01 01)
1629 (Time.TimeOfDay 0 0 0))
1631 , "2000/01/01 12:34 = Right 2000/01/01 12:34" ~:
1632 (Data.Either.rights $
1634 (Format.Ledger.Read.date Nothing <* P.eof)
1635 () "" "2000/01/01 12:34"])
1639 (Time.fromGregorian 2000 01 01)
1640 (Time.TimeOfDay 12 34 0))
1642 , "2000/01/01 12:34:56 = Right 2000/01/01 12:34:56" ~:
1643 (Data.Either.rights $
1645 (Format.Ledger.Read.date Nothing <* P.eof)
1646 () "" "2000/01/01 12:34:56"])
1650 (Time.fromGregorian 2000 01 01)
1651 (Time.TimeOfDay 12 34 56))
1653 , "2000/01/01 12:34 CET = Right 2000/01/01 12:34 CET" ~:
1654 (Data.Either.rights $
1656 (Format.Ledger.Read.date Nothing <* P.eof)
1657 () "" "2000/01/01 12:34 CET"])
1661 (Time.fromGregorian 2000 01 01)
1662 (Time.TimeOfDay 12 34 0))
1663 (Time.TimeZone 60 False "CET")]
1664 , "2000/01/01 12:34 +0130 = Right 2000/01/01 12:34 +0130" ~:
1665 (Data.Either.rights $
1667 (Format.Ledger.Read.date Nothing <* P.eof)
1668 () "" "2000/01/01 12:34 +0130"])
1672 (Time.fromGregorian 2000 01 01)
1673 (Time.TimeOfDay 12 34 0))
1674 (Time.TimeZone 90 False "+0130")]
1675 , "2000/01/01 12:34:56 CET = Right 2000/01/01 12:34:56 CET" ~:
1676 (Data.Either.rights $
1678 (Format.Ledger.Read.date Nothing <* P.eof)
1679 () "" "2000/01/01 12:34:56 CET"])
1683 (Time.fromGregorian 2000 01 01)
1684 (Time.TimeOfDay 12 34 56))
1685 (Time.TimeZone 60 False "CET")]
1686 , "2001/02/29 = Left" ~:
1687 (Data.Either.rights $
1689 (Format.Ledger.Read.date Nothing <* P.eof)
1690 () "" "2001/02/29"])
1693 , "01/01 = Right default_year/01/01" ~:
1694 (Data.Either.rights $
1696 (Format.Ledger.Read.date (Just 2000) <* P.eof)
1701 (Time.fromGregorian 2000 01 01)
1702 (Time.TimeOfDay 0 0 0))
1706 [ "Name: = Right Name:" ~:
1707 (Data.Either.rights $
1709 (Format.Ledger.Read.tag <* P.eof)
1713 , "Name:Value = Right Name:Value" ~:
1714 (Data.Either.rights $
1716 (Format.Ledger.Read.tag <* P.eof)
1717 () "" "Name:Value"])
1720 , "Name:Val ue = Right Name:Val ue" ~:
1721 (Data.Either.rights $
1723 (Format.Ledger.Read.tag <* P.eof)
1724 () "" "Name:Val ue"])
1726 [("Name", "Val ue")]
1728 , "tags" ~: TestList
1729 [ "Name: = Right Name:" ~:
1730 (Data.Either.rights $
1732 (Format.Ledger.Read.tags <* P.eof)
1739 , "Name:, = Right Name:" ~:
1740 (Data.Either.rights $
1742 (Format.Ledger.Read.tags <* P.char ',' <* P.eof)
1749 , "Name:,Name: = Right Name:,Name:" ~:
1750 (Data.Either.rights $
1752 (Format.Ledger.Read.tags <* P.eof)
1753 () "" "Name:,Name:"])
1756 [ ("Name", ["", ""])
1759 , "Name:,Name2: = Right Name:,Name2:" ~:
1760 (Data.Either.rights $
1762 (Format.Ledger.Read.tags <* P.eof)
1763 () "" "Name:,Name2:"])
1770 , "Name: , Name2: = Right Name: ,Name2:" ~:
1771 (Data.Either.rights $
1773 (Format.Ledger.Read.tags <* P.eof)
1774 () "" "Name: , Name2:"])
1781 , "Name:,Name2:,Name3: = Right Name:,Name2:,Name3:" ~:
1782 (Data.Either.rights $
1784 (Format.Ledger.Read.tags <* P.eof)
1785 () "" "Name:,Name2:,Name3:"])
1793 , "Name:Val ue,Name2:V a l u e,Name3:V al ue = Right Name:Val ue,Name2:V a l u e,Name3:V al ue" ~:
1794 (Data.Either.rights $
1796 (Format.Ledger.Read.tags <* P.eof)
1797 () "" "Name:Val ue,Name2:V a l u e,Name3:V al ue"])
1800 [ ("Name", ["Val ue"])
1801 , ("Name2", ["V a l u e"])
1802 , ("Name3", ["V al ue"])
1806 , "posting" ~: TestList
1807 [ " A:B:C = Right A:B:C" ~:
1808 (Data.Either.rights $
1810 (Format.Ledger.Read.posting <* P.eof)
1811 Format.Ledger.Read.nil_Context "" " A:B:C"])
1814 { Posting.account = ["A","B","C"]
1815 , Posting.sourcepos = P.newPos "" 1 1
1818 , " !A:B:C = Right !A:B:C" ~:
1819 (Data.Either.rights $
1821 (Format.Ledger.Read.posting <* P.eof)
1822 Format.Ledger.Read.nil_Context "" " !A:B:C"])
1825 { Posting.account = ["A","B","C"]
1826 , Posting.sourcepos = P.newPos "" 1 1
1827 , Posting.status = True
1830 , " *A:B:C = Right *A:B:C" ~:
1831 (Data.Either.rights $
1833 (Format.Ledger.Read.posting <* P.eof)
1834 Format.Ledger.Read.nil_Context "" " *A:B:C"])
1837 { Posting.account = ["A","B","C"]
1838 , Posting.amounts = Data.Map.fromList []
1839 , Posting.comments = []
1840 , Posting.dates = []
1841 , Posting.status = True
1842 , Posting.sourcepos = P.newPos "" 1 1
1843 , Posting.tags = Data.Map.fromList []
1844 , Posting.type_ = Posting.Type_Regular
1847 , " A:B:C $1 = Right A:B:C $1" ~:
1848 (Data.Either.rights $
1850 (Format.Ledger.Read.posting <* P.eof)
1851 Format.Ledger.Read.nil_Context "" " A:B:C $1"])
1854 { Posting.account = ["A","B","C $1"]
1855 , Posting.sourcepos = P.newPos "" 1 1
1858 , " A:B:C $1 = Right A:B:C $1" ~:
1859 (Data.Either.rights $
1861 (Format.Ledger.Read.posting <* P.eof)
1862 Format.Ledger.Read.nil_Context "" " A:B:C $1"])
1865 { Posting.account = ["A","B","C"]
1866 , Posting.amounts = Data.Map.fromList
1868 { Amount.quantity = 1
1869 , Amount.style = Style.nil
1870 { Style.unit_side = Just Style.Side_Left
1871 , Style.unit_spaced = Just False
1876 , Posting.sourcepos = P.newPos "" 1 1
1879 , " A:B:C $1 + 1€ = Right A:B:C $1 + 1€" ~:
1880 (Data.Either.rights $
1882 (Format.Ledger.Read.posting <* P.eof)
1883 Format.Ledger.Read.nil_Context "" " A:B:C $1 + 1€"])
1886 { Posting.account = ["A","B","C"]
1887 , Posting.amounts = Data.Map.fromList
1889 { Amount.quantity = 1
1890 , Amount.style = Style.nil
1891 { Style.unit_side = Just Style.Side_Left
1892 , Style.unit_spaced = Just False
1897 { Amount.quantity = 1
1898 , Amount.style = Style.nil
1899 { Style.unit_side = Just Style.Side_Right
1900 , Style.unit_spaced = Just False
1905 , Posting.sourcepos = P.newPos "" 1 1
1908 , " A:B:C $1 + 1$ = Right A:B:C $2" ~:
1909 (Data.Either.rights $
1911 (Format.Ledger.Read.posting <* P.eof)
1912 Format.Ledger.Read.nil_Context "" " A:B:C $1 + 1$"])
1915 { Posting.account = ["A","B","C"]
1916 , Posting.amounts = Data.Map.fromList
1918 { Amount.quantity = 2
1919 , Amount.style = Style.nil
1920 { Style.unit_side = Just Style.Side_Left
1921 , Style.unit_spaced = Just False
1926 , Posting.sourcepos = P.newPos "" 1 1
1929 , " A:B:C $1 + 1$ + 1$ = Right A:B:C $3" ~:
1930 (Data.Either.rights $
1932 (Format.Ledger.Read.posting <* P.eof)
1933 Format.Ledger.Read.nil_Context "" " A:B:C $1 + 1$ + 1$"])
1936 { Posting.account = ["A","B","C"]
1937 , Posting.amounts = Data.Map.fromList
1939 { Amount.quantity = 3
1940 , Amount.style = Style.nil
1941 { Style.unit_side = Just Style.Side_Left
1942 , Style.unit_spaced = Just False
1947 , Posting.sourcepos = P.newPos "" 1 1
1950 , " A:B:C ; some comment = Right A:B:C ; some comment" ~:
1951 (Data.Either.rights $
1953 (Format.Ledger.Read.posting <* P.eof)
1954 Format.Ledger.Read.nil_Context "" " A:B:C ; some comment"])
1957 { Posting.account = ["A","B","C"]
1958 , Posting.amounts = Data.Map.fromList []
1959 , Posting.comments = [" some comment"]
1960 , Posting.sourcepos = P.newPos "" 1 1
1963 , " A:B:C ; some comment\\n ; some other comment = Right A:B:C ; some comment\\n ; some other comment" ~:
1964 (Data.Either.rights $
1966 (Format.Ledger.Read.posting <* P.eof)
1967 Format.Ledger.Read.nil_Context "" " A:B:C ; some comment\n ; some other comment"])
1970 { Posting.account = ["A","B","C"]
1971 , Posting.amounts = Data.Map.fromList []
1972 , Posting.comments = [" some comment", " some other comment"]
1973 , Posting.sourcepos = P.newPos "" 1 1
1976 , " A:B:C $1 ; some comment = Right A:B:C $1 ; some comment" ~:
1977 (Data.Either.rights $
1979 (Format.Ledger.Read.posting)
1980 Format.Ledger.Read.nil_Context "" " A:B:C $1 ; some comment"])
1983 { Posting.account = ["A","B","C"]
1984 , Posting.amounts = Data.Map.fromList
1986 { Amount.quantity = 1
1987 , Amount.style = Style.nil
1988 { Style.unit_side = Just Style.Side_Left
1989 , Style.unit_spaced = Just False
1994 , Posting.comments = [" some comment"]
1995 , Posting.sourcepos = P.newPos "" 1 1
1998 , " A:B:C ; N:V = Right A:B:C ; N:V" ~:
1999 (Data.Either.rights $
2001 (Format.Ledger.Read.posting <* P.eof)
2002 Format.Ledger.Read.nil_Context "" " A:B:C ; N:V"])
2005 { Posting.account = ["A","B","C"]
2006 , Posting.comments = [" N:V"]
2007 , Posting.sourcepos = P.newPos "" 1 1
2008 , Posting.tags = Data.Map.fromList
2013 , " A:B:C ; some comment N:V = Right A:B:C ; some comment N:V" ~:
2014 (Data.Either.rights $
2016 (Format.Ledger.Read.posting <* P.eof)
2017 Format.Ledger.Read.nil_Context "" " A:B:C ; some comment N:V"])
2020 { Posting.account = ["A","B","C"]
2021 , Posting.comments = [" some comment N:V"]
2022 , Posting.sourcepos = P.newPos "" 1 1
2023 , Posting.tags = Data.Map.fromList
2028 , " A:B:C ; some comment N:V v, N2:V2 v2 = Right A:B:C ; some comment N:V v, N2:V2 v2" ~:
2029 (Data.Either.rights $
2031 (Format.Ledger.Read.posting )
2032 Format.Ledger.Read.nil_Context "" " A:B:C ; some comment N:V v, N2:V2 v2"])
2035 { Posting.account = ["A","B","C"]
2036 , Posting.comments = [" some comment N:V v, N2:V2 v2"]
2037 , Posting.sourcepos = P.newPos "" 1 1
2038 , Posting.tags = Data.Map.fromList
2044 , " A:B:C ; N:V\\n ; N:V2 = Right A:B:C ; N:V\\n ; N:V2" ~:
2045 (Data.Either.rights $
2047 (Format.Ledger.Read.posting <* P.eof)
2048 Format.Ledger.Read.nil_Context "" " A:B:C ; N:V\n ; N:V2"])
2051 { Posting.account = ["A","B","C"]
2052 , Posting.comments = [" N:V", " N:V2"]
2053 , Posting.sourcepos = P.newPos "" 1 1
2054 , Posting.tags = Data.Map.fromList
2055 [ ("N", ["V", "V2"])
2059 , " A:B:C ; N:V\\n ; N2:V = Right A:B:C ; N:V\\n ; N2:V" ~:
2060 (Data.Either.rights $
2062 (Format.Ledger.Read.posting <* P.eof)
2063 Format.Ledger.Read.nil_Context "" " A:B:C ; N:V\n ; N2:V"])
2066 { Posting.account = ["A","B","C"]
2067 , Posting.comments = [" N:V", " N2:V"]
2068 , Posting.sourcepos = P.newPos "" 1 1
2069 , Posting.tags = Data.Map.fromList
2075 , " A:B:C ; date:2001/01/01 = Right A:B:C ; date:2001/01/01" ~:
2076 (Data.Either.rights $
2078 (Format.Ledger.Read.posting <* P.eof)
2079 Format.Ledger.Read.nil_Context "" " A:B:C ; date:2001/01/01"])
2082 { Posting.account = ["A","B","C"]
2083 , Posting.comments = [" date:2001/01/01"]
2087 (Time.fromGregorian 2001 01 01)
2088 (Time.TimeOfDay 0 0 0))
2091 , Posting.sourcepos = P.newPos "" 1 1
2092 , Posting.tags = Data.Map.fromList
2093 [ ("date", ["2001/01/01"])
2097 , " (A:B:C) = Right (A:B:C)" ~:
2098 (Data.Either.rights $
2100 (Format.Ledger.Read.posting <* P.eof)
2101 Format.Ledger.Read.nil_Context "" " (A:B:C)"])
2104 { Posting.account = ["A","B","C"]
2105 , Posting.sourcepos = P.newPos "" 1 1
2106 , Posting.type_ = Posting.Type_Virtual
2109 , " [A:B:C] = Right [A:B:C]" ~:
2110 (Data.Either.rights $
2112 (Format.Ledger.Read.posting <* P.eof)
2113 Format.Ledger.Read.nil_Context "" " [A:B:C]"])
2116 { Posting.account = ["A","B","C"]
2117 , Posting.sourcepos = P.newPos "" 1 1
2118 , Posting.type_ = Posting.Type_Virtual_Balanced
2122 , "transaction" ~: TestList
2123 [ "2000/01/01 some description\\n A:B:C $1\\n a:b:c" ~:
2124 (Data.Either.rights $
2126 (Format.Ledger.Read.transaction <* P.eof)
2127 Format.Ledger.Read.nil_Context "" "2000/01/01 some description\n A:B:C $1\n a:b:c"])
2130 { Transaction.dates=
2133 (Time.fromGregorian 2000 01 01)
2134 (Time.TimeOfDay 0 0 0))
2137 , Transaction.description="some description"
2138 , Transaction.postings = Posting.from_List
2140 { Posting.account = ["A","B","C"]
2141 , Posting.amounts = Data.Map.fromList
2143 { Amount.quantity = 1
2144 , Amount.style = Style.nil
2145 { Style.unit_side = Just Style.Side_Left
2146 , Style.unit_spaced = Just False
2151 , Posting.sourcepos = P.newPos "" 2 1
2154 { Posting.account = ["a","b","c"]
2155 , Posting.sourcepos = P.newPos "" 3 1
2158 , Transaction.sourcepos = P.newPos "" 1 1
2161 , "2000/01/01 some description\\n A:B:C $1\\n a:b:c\\n" ~:
2162 (Data.Either.rights $
2164 (Format.Ledger.Read.transaction <* P.newline <* P.eof)
2165 Format.Ledger.Read.nil_Context "" "2000/01/01 some description\n A:B:C $1\n a:b:c\n"])
2168 { Transaction.dates=
2171 (Time.fromGregorian 2000 01 01)
2172 (Time.TimeOfDay 0 0 0))
2175 , Transaction.description="some description"
2176 , Transaction.postings = Posting.from_List
2178 { Posting.account = ["A","B","C"]
2179 , Posting.amounts = Data.Map.fromList
2181 { Amount.quantity = 1
2182 , Amount.style = Style.nil
2183 { Style.unit_side = Just Style.Side_Left
2184 , Style.unit_spaced = Just False
2189 , Posting.sourcepos = P.newPos "" 2 1
2192 { Posting.account = ["a","b","c"]
2193 , Posting.sourcepos = P.newPos "" 3 1
2196 , Transaction.sourcepos = P.newPos "" 1 1
2199 , "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" ~:
2200 (Data.Either.rights $
2202 (Format.Ledger.Read.transaction <* P.eof)
2203 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"])
2206 { Transaction.comments_after =
2208 , " some other;comment"
2210 , " some last comment"
2212 , Transaction.dates=
2215 (Time.fromGregorian 2000 01 01)
2216 (Time.TimeOfDay 0 0 0))
2219 , Transaction.description="some description"
2220 , Transaction.postings = Posting.from_List
2222 { Posting.account = ["A","B","C"]
2223 , Posting.amounts = Data.Map.fromList
2225 { Amount.quantity = 1
2226 , Amount.style = Style.nil
2227 { Style.unit_side = Just Style.Side_Left
2228 , Style.unit_spaced = Just False
2233 , Posting.sourcepos = P.newPos "" 5 1
2236 { Posting.account = ["a","b","c"]
2237 , Posting.sourcepos = P.newPos "" 6 1
2238 , Posting.tags = Data.Map.fromList []
2241 , Transaction.sourcepos = P.newPos "" 1 1
2242 , Transaction.tags = Data.Map.fromList
2248 , "journal" ~: TestList
2249 [ "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
2252 (Format.Ledger.Read.journal "" {-<* P.eof-})
2253 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"
2255 (\j -> j{Format.Ledger.Journal.last_read_time=
2256 Format.Ledger.Journal.last_read_time Format.Ledger.Journal.nil}) $
2257 Data.Either.rights [jnl])
2259 [ Format.Ledger.Journal.nil
2260 { Format.Ledger.Journal.transactions = Transaction.from_List
2262 { Transaction.dates=
2265 (Time.fromGregorian 2000 01 01)
2266 (Time.TimeOfDay 0 0 0))
2269 , Transaction.description="1° description"
2270 , Transaction.postings = Posting.from_List
2272 { Posting.account = ["A","B","C"]
2273 , Posting.amounts = Data.Map.fromList
2275 { Amount.quantity = 1
2276 , Amount.style = Style.nil
2277 { Style.unit_side = Just Style.Side_Left
2278 , Style.unit_spaced = Just False
2283 , Posting.sourcepos = P.newPos "" 2 1
2286 { Posting.account = ["a","b","c"]
2287 , Posting.sourcepos = P.newPos "" 3 1
2290 , Transaction.sourcepos = P.newPos "" 1 1
2293 { Transaction.dates=
2296 (Time.fromGregorian 2000 01 02)
2297 (Time.TimeOfDay 0 0 0))
2300 , Transaction.description="2° description"
2301 , Transaction.postings = Posting.from_List
2303 { Posting.account = ["A","B","C"]
2304 , Posting.amounts = Data.Map.fromList
2306 { Amount.quantity = 1
2307 , Amount.style = Style.nil
2308 { Style.unit_side = Just Style.Side_Left
2309 , Style.unit_spaced = Just False
2314 , Posting.sourcepos = P.newPos "" 5 1
2317 { Posting.account = ["x","y","z"]
2318 , Posting.sourcepos = P.newPos "" 6 1
2321 , Transaction.sourcepos = P.newPos "" 4 1