1 {-# LANGUAGE TupleSections #-}
5 import Test.Framework.Providers.HUnit (hUnitTestToTests)
6 import Test.Framework.Runners.Console (defaultMain)
8 import Control.Applicative ((<*))
9 import qualified Data.List
10 import qualified Data.Map
11 import qualified Data.Either
12 import qualified Text.Parsec
13 import qualified Data.Decimal
14 import Data.Decimal (Decimal(..))
16 import qualified Hcompta.Model as Model
17 import qualified Hcompta.Model.Account as Account
18 import qualified Hcompta.Model.Amount as Amount
19 import qualified Hcompta.Model.Amount.Quantity as Quantity
20 import qualified Hcompta.Model.Amount.Style as Style
21 import qualified Hcompta.Model.Transaction as Transaction
22 import Hcompta.Model.Transaction (Posting)
23 import qualified Hcompta.Model.Transaction.Posting as Posting
24 import qualified Hcompta.Calc as Calc
25 import qualified Hcompta.Calc.Balance as Calc.Balance
26 import qualified Hcompta.Format.Ledger as Format.Ledger
27 import qualified Hcompta.Format.Ledger.Read as Format.Ledger.Read
30 main = defaultMain $ hUnitTestToTests test_Hcompta
36 [ "Account" ~: TestList
39 (reverse $ Account.fold [] (:) []) ~?= []
41 (reverse $ Account.fold ["A"] (:) []) ~?= [["A"]]
42 , "[A, B] = [[A], [A, B]]" ~:
43 (reverse $ Account.fold ["A", "B"] (:) []) ~?= [["A"], ["A", "B"]]
44 , "[A, B, C] = [[A], [A, B], [A, B, C]]" ~:
45 (reverse $ Account.fold ["A", "B", "C"] (:) []) ~?= [["A"], ["A", "B"], ["A", "B", "C"]]
47 , "ascending" ~: TestList
49 Account.ascending [] ~?= []
51 Account.ascending ["A"] ~?= []
53 Account.ascending ["A", "B"] ~?= ["A"]
54 , "[A, B, C] = [A, B]" ~:
55 Account.ascending ["A", "B", "C"] ~?= ["A", "B"]
60 [ "Balance" ~: TestList
61 [ "posting" ~: TestList
62 [ "[A+$1] = A+$1 & $+1" ~:
65 { Posting.account=["A"]
66 , Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
71 { Calc.Balance.by_account =
73 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
74 , Calc.Balance.by_unit =
76 Data.List.map Calc.Balance.assoc_by_amount_unit $
77 [ Calc.Balance.Sum_by_Unit
78 { Calc.Balance.amount = Amount.usd $ 1
79 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
84 , "[A+$1, A-$1] = {A+$0, $+0}" ~:
86 (flip Calc.Balance.posting)
89 { Posting.account=["A"]
90 , Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
93 { Posting.account=["A"]
94 , Posting.amounts=Amount.from_List [ Amount.usd $ -1 ]
99 { Calc.Balance.by_account =
101 [ (["A"], Amount.from_List [ Amount.usd $ 0 ]) ]
102 , Calc.Balance.by_unit =
104 Data.List.map Calc.Balance.assoc_by_amount_unit $
105 [ Calc.Balance.Sum_by_Unit
106 { Calc.Balance.amount = Amount.usd $ 0
107 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
112 , "[A+$1, A-€1] = {A+$1-€1, $+1 €-1}" ~:
114 (flip Calc.Balance.posting)
117 { Posting.account=["A"]
118 , Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
121 { Posting.account=["A"]
122 , Posting.amounts=Amount.from_List [ Amount.eur $ -1 ]
127 { Calc.Balance.by_account =
129 [ (["A"], Amount.from_List [ Amount.usd $ 1, Amount.eur $ -1 ]) ]
130 , Calc.Balance.by_unit =
132 Data.List.map Calc.Balance.assoc_by_amount_unit $
133 [ Calc.Balance.Sum_by_Unit
134 { Calc.Balance.amount = Amount.usd $ 1
135 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
138 , Calc.Balance.Sum_by_Unit
139 { Calc.Balance.amount = Amount.eur $ -1
140 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
145 , "[A+$1, B-$1] = {A+$1 B-$1, $+0}" ~:
147 (flip Calc.Balance.posting)
150 { Posting.account=["A"]
151 , Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
154 { Posting.account=["B"]
155 , Posting.amounts=Amount.from_List [ Amount.usd $ -1 ]
160 { Calc.Balance.by_account =
162 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
163 , (["B"], Amount.from_List [ Amount.usd $ -1 ])
165 , Calc.Balance.by_unit =
167 Data.List.map Calc.Balance.assoc_by_amount_unit $
168 [ Calc.Balance.Sum_by_Unit
169 { Calc.Balance.amount = Amount.usd $ 0
170 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
175 , "[A+$1+€2, A-$1-€2] = {A+$0+€0, $+0 €+0}" ~:
177 (flip Calc.Balance.posting)
180 { Posting.account=["A"]
181 , Posting.amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2 ]
184 { Posting.account=["A"]
185 , Posting.amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2 ]
190 { Calc.Balance.by_account =
192 [ (["A"], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
194 , Calc.Balance.by_unit =
196 Data.List.map Calc.Balance.assoc_by_amount_unit $
197 [ Calc.Balance.Sum_by_Unit
198 { Calc.Balance.amount = Amount.usd $ 0
199 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
202 , Calc.Balance.Sum_by_Unit
203 { Calc.Balance.amount = Amount.eur $ 0
204 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
209 , "[A+$1+€2+£3, B-$1-2€-£3] = {A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~:
211 (flip Calc.Balance.posting)
214 { Posting.account=["A"]
215 , Posting.amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ]
218 { Posting.account=["B"]
219 , Posting.amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ]
224 { Calc.Balance.by_account =
226 [ (["A"], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
227 , (["B"], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
229 , Calc.Balance.by_unit =
231 Data.List.map Calc.Balance.assoc_by_amount_unit $
232 [ Calc.Balance.Sum_by_Unit
233 { Calc.Balance.amount = Amount.usd $ 0
234 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
237 , Calc.Balance.Sum_by_Unit
238 { Calc.Balance.amount = Amount.eur $ 0
239 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
242 , Calc.Balance.Sum_by_Unit
243 { Calc.Balance.amount = Amount.gbp $ 0
244 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
250 , "union" ~: TestList
257 , "{A+$1, $+1} {A+$1, $+1} = {A+$2, $+2}" ~:
259 (Calc.Balance.Balance
260 { Calc.Balance.by_account =
262 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
263 , Calc.Balance.by_unit =
265 Data.List.map Calc.Balance.assoc_by_amount_unit $
266 [ Calc.Balance.Sum_by_Unit
267 { Calc.Balance.amount = Amount.usd $ 1
268 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
273 (Calc.Balance.Balance
274 { Calc.Balance.by_account =
276 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
277 , Calc.Balance.by_unit =
279 Data.List.map Calc.Balance.assoc_by_amount_unit $
280 [ Calc.Balance.Sum_by_Unit
281 { Calc.Balance.amount = Amount.usd $ 1
282 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
289 { Calc.Balance.by_account =
291 [ (["A"], Amount.from_List [ Amount.usd $ 2 ]) ]
292 , Calc.Balance.by_unit =
294 Data.List.map Calc.Balance.assoc_by_amount_unit $
295 [ Calc.Balance.Sum_by_Unit
296 { Calc.Balance.amount = Amount.usd $ 2
297 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
302 , "{A+$1, $+1} {B+$1, $+1} = {A+$1 B+$1, $+2}" ~:
304 (Calc.Balance.Balance
305 { Calc.Balance.by_account =
307 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
308 , Calc.Balance.by_unit =
310 Data.List.map Calc.Balance.assoc_by_amount_unit $
311 [ Calc.Balance.Sum_by_Unit
312 { Calc.Balance.amount = Amount.usd $ 1
313 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
318 (Calc.Balance.Balance
319 { Calc.Balance.by_account =
321 [ (["B"], Amount.from_List [ Amount.usd $ 1 ]) ]
322 , Calc.Balance.by_unit =
324 Data.List.map Calc.Balance.assoc_by_amount_unit $
325 [ Calc.Balance.Sum_by_Unit
326 { Calc.Balance.amount = Amount.usd $ 1
327 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
334 { Calc.Balance.by_account =
336 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
337 , (["B"], Amount.from_List [ Amount.usd $ 1 ]) ]
338 , Calc.Balance.by_unit =
340 Data.List.map Calc.Balance.assoc_by_amount_unit $
341 [ Calc.Balance.Sum_by_Unit
342 { Calc.Balance.amount = Amount.usd $ 2
343 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
348 , "{A+$1, $+1} {B+€1, €+1} = {A+$1 B+€1, $+1 €+1}" ~:
350 (Calc.Balance.Balance
351 { Calc.Balance.by_account =
353 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
354 , Calc.Balance.by_unit =
356 Data.List.map Calc.Balance.assoc_by_amount_unit $
357 [ Calc.Balance.Sum_by_Unit
358 { Calc.Balance.amount = Amount.usd $ 1
359 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
364 (Calc.Balance.Balance
365 { Calc.Balance.by_account =
367 [ (["B"], Amount.from_List [ Amount.eur $ 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.eur $ 1
373 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
380 { Calc.Balance.by_account =
382 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
383 , (["B"], Amount.from_List [ Amount.eur $ 1 ]) ]
384 , Calc.Balance.by_unit =
386 Data.List.map Calc.Balance.assoc_by_amount_unit $
387 [ Calc.Balance.Sum_by_Unit
388 { Calc.Balance.amount = Amount.usd $ 1
389 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
392 , Calc.Balance.Sum_by_Unit
393 { Calc.Balance.amount = Amount.eur $ 1
394 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
400 , "expand" ~: TestList
401 [ "nil_By_Account = nil_By_Account" ~:
403 Calc.Balance.nil_By_Account
405 (Calc.Balance.Expanded $
406 Calc.Balance.nil_By_Account)
410 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ])
412 (Calc.Balance.Expanded $
414 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ])
415 , "A/A+$1 = A+$1 A/A+$1" ~:
418 [ (["A", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
420 (Calc.Balance.Expanded $
422 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
423 , (["A", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
424 , "A/B+$1 = A+$1 A/B+$1" ~:
427 [ (["A", "B"], Amount.from_List [ Amount.usd $ 1 ]) ])
429 (Calc.Balance.Expanded $
431 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
432 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ]) ])
433 , "A/B/C+$1 = A+$1 A/B+$1 A/B/C+$1" ~:
436 [ (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ]) ])
438 (Calc.Balance.Expanded $
440 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
441 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
442 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ]) ])
443 , "A+$1 A/B+$1 = A+$2 A/B+$1" ~:
446 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
447 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ]) ])
449 (Calc.Balance.Expanded $
451 [ (["A"], Amount.from_List [ Amount.usd $ 2 ])
452 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ]) ])
453 , "A+$1 A/B+$1 A/B/C+$1 = A+$3 A/B+$2 A/B/C+$1" ~:
456 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
457 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
458 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ])
461 (Calc.Balance.Expanded $
463 [ (["A"], Amount.from_List [ Amount.usd $ 3 ])
464 , (["A", "B"], Amount.from_List [ Amount.usd $ 2 ])
465 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ])
467 , "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" ~:
470 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
471 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
472 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ])
473 , (["A", "B", "C", "D"], Amount.from_List [ Amount.usd $ 1 ])
476 (Calc.Balance.Expanded $
478 [ (["A"], Amount.from_List [ Amount.usd $ 4 ])
479 , (["A", "B"], Amount.from_List [ Amount.usd $ 3 ])
480 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 2 ])
481 , (["A", "B", "C", "D"], Amount.from_List [ Amount.usd $ 1 ])
483 , "A+$1 A/B+$1 B/A+$1 = A+$2 A/B+$1 B/A+$1" ~:
486 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
487 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
488 , (["B", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
490 (Calc.Balance.Expanded $
492 [ (["A"], Amount.from_List [ Amount.usd $ 2 ])
493 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
494 , (["B"], Amount.from_List [ Amount.usd $ 1 ])
495 , (["B", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
496 , "A+$1 A/B+$1 B/A+$1 = A+$2 A/B+$1 B/A+$1" ~:
499 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
500 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
501 , (["B", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
503 (Calc.Balance.Expanded $
505 [ (["A"], Amount.from_List [ Amount.usd $ 2 ])
506 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
507 , (["B"], Amount.from_List [ Amount.usd $ 1 ])
508 , (["B", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
510 , "is_equilibrated" ~: TestList
511 [ "nil = True" ~: TestCase $
513 Calc.Balance.is_equilibrated $
515 , "{A+$0, $+0} = True" ~: TestCase $
517 Calc.Balance.is_equilibrated $
519 { Calc.Balance.by_account =
521 [ (["A"], Amount.from_List [ Amount.usd $ 0 ])
523 , Calc.Balance.by_unit =
525 Data.List.map Calc.Balance.assoc_by_amount_unit $
526 [ Calc.Balance.Sum_by_Unit
527 { Calc.Balance.amount = Amount.usd $ 0
528 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
533 , "{A+$1, $+1} = False" ~: TestCase $
535 Calc.Balance.is_equilibrated $
537 { Calc.Balance.by_account =
539 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
541 , Calc.Balance.by_unit =
543 Data.List.map Calc.Balance.assoc_by_amount_unit $
544 [ Calc.Balance.Sum_by_Unit
545 { Calc.Balance.amount = Amount.usd $ 1
546 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
551 , "{A+$0+€0, $0 €+0} = True" ~: TestCase $
553 Calc.Balance.is_equilibrated $
555 { Calc.Balance.by_account =
557 [ (["A"], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
559 , Calc.Balance.by_unit =
561 Data.List.map Calc.Balance.assoc_by_amount_unit $
562 [ Calc.Balance.Sum_by_Unit
563 { Calc.Balance.amount = Amount.usd $ 0
564 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
567 , Calc.Balance.Sum_by_Unit
568 { Calc.Balance.amount = Amount.eur $ 0
569 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
574 , "{A+$1, B-$1, $+0} = True" ~: TestCase $
576 Calc.Balance.is_equilibrated $
578 { Calc.Balance.by_account =
580 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
581 , (["B"], Amount.from_List [ Amount.usd $ -1 ])
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 B, $+1} = True" ~: TestCase $
595 Calc.Balance.is_equilibrated $
597 { Calc.Balance.by_account =
599 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
600 , (["B"], Amount.from_List [])
602 , Calc.Balance.by_unit =
604 Data.List.map Calc.Balance.assoc_by_amount_unit $
605 [ Calc.Balance.Sum_by_Unit
606 { Calc.Balance.amount = Amount.usd $ 1
607 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
612 , "{A+$1 B+€1, $+1 €+1} = True" ~: TestCase $
614 Calc.Balance.is_equilibrated $
616 { Calc.Balance.by_account =
618 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
619 , (["B"], Amount.from_List [ Amount.eur $ 1 ])
621 , Calc.Balance.by_unit =
623 Data.List.map Calc.Balance.assoc_by_amount_unit $
624 [ Calc.Balance.Sum_by_Unit
625 { Calc.Balance.amount = Amount.usd $ 1
626 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
629 , Calc.Balance.Sum_by_Unit
630 { Calc.Balance.amount = Amount.eur $ 1
631 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
636 , "{A+$1 B-$1+€1, $+0 €+1} = True" ~: TestCase $
638 Calc.Balance.is_equilibrated $
640 { Calc.Balance.by_account =
642 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
643 , (["B"], Amount.from_List [ Amount.usd $ -1, Amount.eur $ 1 ])
645 , Calc.Balance.by_unit =
647 Data.List.map Calc.Balance.assoc_by_amount_unit $
648 [ Calc.Balance.Sum_by_Unit
649 { Calc.Balance.amount = Amount.usd $ 0
650 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
653 , Calc.Balance.Sum_by_Unit
654 { Calc.Balance.amount = Amount.eur $ 1
655 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
660 , "{A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0} = True" ~: TestCase $
662 Calc.Balance.is_equilibrated $
664 { Calc.Balance.by_account =
666 [ (["A"], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
667 , (["B"], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
669 , Calc.Balance.by_unit =
671 Data.List.map Calc.Balance.assoc_by_amount_unit $
672 [ Calc.Balance.Sum_by_Unit
673 { Calc.Balance.amount = Amount.usd $ 0
674 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
677 , Calc.Balance.Sum_by_Unit
678 { Calc.Balance.amount = Amount.eur $ 0
679 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
682 , Calc.Balance.Sum_by_Unit
683 { Calc.Balance.amount = Amount.gbp $ 0
684 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
692 , "Format" ~: TestList
693 [ "Ledger" ~: TestList
695 [ "account_name" ~: TestList
697 (Data.Either.rights $
698 [Text.Parsec.runParser
699 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
703 , "\"A\" = Right \"A\"" ~:
704 (Data.Either.rights $
705 [Text.Parsec.runParser
706 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
710 , "\"AA\" = Right \"AA\"" ~:
711 (Data.Either.rights $
712 [Text.Parsec.runParser
713 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
718 (Data.Either.rights $
719 [Text.Parsec.runParser
720 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
725 (Data.Either.rights $
726 [Text.Parsec.runParser
727 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
732 (Data.Either.rights $
733 [Text.Parsec.runParser
734 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
739 (Data.Either.rights $
740 [Text.Parsec.runParser
741 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
746 (Data.Either.rights $
747 [Text.Parsec.runParser
748 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
752 , "\"A A\" = Right \"A A\"" ~:
753 (Data.Either.rights $
754 [Text.Parsec.runParser
755 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
760 (Data.Either.rights $
761 [Text.Parsec.runParser
762 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
766 , "\"A \\n\" = Left" ~:
767 (Data.Either.rights $
768 [Text.Parsec.runParser
769 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
774 , "account" ~: TestList
776 (Data.Either.rights $
777 [Text.Parsec.runParser
778 (Format.Ledger.Read.account <* Text.Parsec.eof)
782 , "\"A\" = Right [\"A\"]" ~:
783 (Data.Either.rights $
784 [Text.Parsec.runParser
785 (Format.Ledger.Read.account <* Text.Parsec.eof)
790 (Data.Either.rights $
791 [Text.Parsec.runParser
792 (Format.Ledger.Read.account <* Text.Parsec.eof)
797 (Data.Either.rights $
798 [Text.Parsec.runParser
799 (Format.Ledger.Read.account <* Text.Parsec.eof)
804 (Data.Either.rights $
805 [Text.Parsec.runParser
806 (Format.Ledger.Read.account <* Text.Parsec.eof)
811 (Data.Either.rights $
812 [Text.Parsec.runParser
813 (Format.Ledger.Read.account <* Text.Parsec.eof)
817 , "\"A:B\" = Right [\"A\", \"B\"]" ~:
818 (Data.Either.rights $
819 [Text.Parsec.runParser
820 (Format.Ledger.Read.account <* Text.Parsec.eof)
824 , "\"A:B:C\" = Right [\"A\", \"B\", \"C\"]" ~:
825 (Data.Either.rights $
826 [Text.Parsec.runParser
827 (Format.Ledger.Read.account <* Text.Parsec.eof)
831 , "\"Aa:Bbb:Cccc\" = Right [\"Aa\", \"Bbb\", \":Cccc\"]" ~:
832 (Data.Either.rights $
833 [Text.Parsec.runParser
834 (Format.Ledger.Read.account <* Text.Parsec.eof)
835 () "" "Aa:Bbb:Cccc"])
837 [["Aa", "Bbb", "Cccc"]]
838 , "\"A a : B b b : C c c c\" = Right [\"A a \", \" B b b \", \": C c c c\"]" ~:
839 (Data.Either.rights $
840 [Text.Parsec.runParser
841 (Format.Ledger.Read.account <* Text.Parsec.eof)
842 () "" "A a : B b b : C c c c"])
844 [["A a ", " B b b ", " C c c c"]]
845 , "\"A: :C\" = Right [\"A\", \" \", \"C\"]" ~:
846 (Data.Either.rights $
847 [Text.Parsec.runParser
848 (Format.Ledger.Read.account <* Text.Parsec.eof)
852 , "\"A::C\" = Left" ~:
853 (Data.Either.rights $
854 [Text.Parsec.runParser
855 (Format.Ledger.Read.account <* Text.Parsec.eof)
860 , "amount" ~: TestList
862 (Data.Either.rights $
863 [Text.Parsec.runParser
864 (Format.Ledger.Read.amount <* Text.Parsec.eof)
868 , "\"0\" = Right 0" ~:
869 (Data.Either.rights $
870 [Text.Parsec.runParser
871 (Format.Ledger.Read.amount <* Text.Parsec.eof)
875 { Amount.quantity = Data.Decimal.Decimal 0 0
877 , "\"00\" = Right 0" ~:
878 (Data.Either.rights $
879 [Text.Parsec.runParser
880 (Format.Ledger.Read.amount <* Text.Parsec.eof)
884 { Amount.quantity = Data.Decimal.Decimal 0 0
886 , "\"0.\" = Right 0." ~:
887 (Data.Either.rights $
888 [Text.Parsec.runParser
889 (Format.Ledger.Read.amount <* Text.Parsec.eof)
893 { Amount.quantity = Data.Decimal.Decimal 0 0
896 { Style.fractioning = Just '.'
899 , "\".0\" = Right 0.0" ~:
900 (Data.Either.rights $
901 [Text.Parsec.runParser
902 (Format.Ledger.Read.amount <* Text.Parsec.eof)
906 { Amount.quantity = Data.Decimal.Decimal 0 0
909 { Style.fractioning = Just '.'
910 , Style.precision = 1
913 , "\"0,\" = Right 0," ~:
914 (Data.Either.rights $
915 [Text.Parsec.runParser
916 (Format.Ledger.Read.amount <* Text.Parsec.eof)
920 { Amount.quantity = Data.Decimal.Decimal 0 0
923 { Style.fractioning = Just ','
926 , "\",0\" = Right 0,0" ~:
927 (Data.Either.rights $
928 [Text.Parsec.runParser
929 (Format.Ledger.Read.amount <* Text.Parsec.eof)
933 { Amount.quantity = Data.Decimal.Decimal 0 0
936 { Style.fractioning = Just ','
937 , Style.precision = 1
941 (Data.Either.rights $
942 [Text.Parsec.runParser
943 (Format.Ledger.Read.amount <* Text.Parsec.eof)
948 (Data.Either.rights $
949 [Text.Parsec.runParser
950 (Format.Ledger.Read.amount <* Text.Parsec.eof)
954 , "\"0.0\" = Right 0.0" ~:
955 (Data.Either.rights $
956 [Text.Parsec.runParser
957 (Format.Ledger.Read.amount <* Text.Parsec.eof)
961 { Amount.quantity = Data.Decimal.Decimal 0 0
964 { Style.fractioning = Just '.'
965 , Style.precision = 1
968 , "\"00.00\" = Right 0.00" ~:
969 (Data.Either.rights $
970 [Text.Parsec.runParser
971 (Format.Ledger.Read.amount <* Text.Parsec.eof)
975 { Amount.quantity = Data.Decimal.Decimal 0 0
978 { Style.fractioning = Just '.'
979 , Style.precision = 2
982 , "\"0,0\" = Right 0,0" ~:
983 (Data.Either.rights $
984 [Text.Parsec.runParser
985 (Format.Ledger.Read.amount <* Text.Parsec.eof)
989 { Amount.quantity = Data.Decimal.Decimal 0 0
992 { Style.fractioning = Just ','
993 , Style.precision = 1
996 , "\"00,00\" = Right 0,00" ~:
997 (Data.Either.rights $
998 [Text.Parsec.runParser
999 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1003 { Amount.quantity = Data.Decimal.Decimal 0 0
1006 { Style.fractioning = Just ','
1007 , Style.precision = 2
1010 , "\"0_0\" = Right 0" ~:
1011 (Data.Either.rights $
1012 [Text.Parsec.runParser
1013 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1017 { Amount.quantity = Data.Decimal.Decimal 0 0
1020 { Style.fractioning = Nothing
1021 , Style.grouping_integral = Just $ Style.Grouping '_' [1]
1022 , Style.precision = 0
1025 , "\"00_00\" = Right 0" ~:
1026 (Data.Either.rights $
1027 [Text.Parsec.runParser
1028 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1032 { Amount.quantity = Data.Decimal.Decimal 0 0
1035 { Style.fractioning = Nothing
1036 , Style.grouping_integral = Just $ Style.Grouping '_' [2]
1037 , Style.precision = 0
1040 , "\"0,000.00\" = Right 0,000.00" ~:
1041 (Data.Either.rights $
1042 [Text.Parsec.runParser
1043 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1047 { Amount.quantity = Data.Decimal.Decimal 0 0
1050 { Style.fractioning = Just '.'
1051 , Style.grouping_integral = Just $ Style.Grouping ',' [3]
1052 , Style.precision = 2
1055 , "\"0.000,00\" = Right 0.000,00" ~:
1056 (Data.Either.rights $
1057 [Text.Parsec.runParser
1058 (Format.Ledger.Read.amount)
1062 { Amount.quantity = Data.Decimal.Decimal 0 0
1065 { Style.fractioning = Just ','
1066 , Style.grouping_integral = Just $ Style.Grouping '.' [3]
1067 , Style.precision = 2
1070 , "\"1,000.00\" = Right 1,000.00" ~:
1071 (Data.Either.rights $
1072 [Text.Parsec.runParser
1073 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1077 { Amount.quantity = Data.Decimal.Decimal 0 1000
1080 { Style.fractioning = Just '.'
1081 , Style.grouping_integral = Just $ Style.Grouping ',' [3]
1082 , Style.precision = 2
1085 , "\"1.000,00\" = Right 1.000,00" ~:
1086 (Data.Either.rights $
1087 [Text.Parsec.runParser
1088 (Format.Ledger.Read.amount)
1092 { Amount.quantity = Data.Decimal.Decimal 0 1000
1095 { Style.fractioning = Just ','
1096 , Style.grouping_integral = Just $ Style.Grouping '.' [3]
1097 , Style.precision = 2
1100 , "\"1,000.00.\" = Left" ~:
1101 (Data.Either.rights $
1102 [Text.Parsec.runParser
1103 (Format.Ledger.Read.amount)
1107 , "\"1.000,00,\" = Left" ~:
1108 (Data.Either.rights $
1109 [Text.Parsec.runParser
1110 (Format.Ledger.Read.amount)
1114 , "\"1,000.00_\" = Left" ~:
1115 (Data.Either.rights $
1116 [Text.Parsec.runParser
1117 (Format.Ledger.Read.amount)
1121 , "\"12\" = Right 12" ~:
1122 (Data.Either.rights $
1123 [Text.Parsec.runParser
1124 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1128 { Amount.quantity = Data.Decimal.Decimal 0 123
1130 , "\"1.2\" = Right 1.2" ~:
1131 (Data.Either.rights $
1132 [Text.Parsec.runParser
1133 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1137 { Amount.quantity = Data.Decimal.Decimal 1 12
1140 { Style.fractioning = Just '.'
1141 , Style.precision = 1
1144 , "\"1,2\" = Right 1,2" ~:
1145 (Data.Either.rights $
1146 [Text.Parsec.runParser
1147 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1151 { Amount.quantity = Data.Decimal.Decimal 1 12
1154 { Style.fractioning = Just ','
1155 , Style.precision = 1
1158 , "\"12.23\" = Right 12.23" ~:
1159 (Data.Either.rights $
1160 [Text.Parsec.runParser
1161 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1165 { Amount.quantity = Data.Decimal.Decimal 2 1234
1168 { Style.fractioning = Just '.'
1169 , Style.precision = 2
1172 , "\"12,23\" = Right 12,23" ~:
1173 (Data.Either.rights $
1174 [Text.Parsec.runParser
1175 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1179 { Amount.quantity = Data.Decimal.Decimal 2 1234
1182 { Style.fractioning = Just ','
1183 , Style.precision = 2
1186 , "\"1_2\" = Right 1_2" ~:
1187 (Data.Either.rights $
1188 [Text.Parsec.runParser
1189 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1193 { Amount.quantity = Data.Decimal.Decimal 0 12
1196 { Style.grouping_integral = Just $ Style.Grouping '_' [1]
1197 , Style.precision = 0
1200 , "\"1_23\" = Right 1_23" ~:
1201 (Data.Either.rights $
1202 [Text.Parsec.runParser
1203 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1207 { Amount.quantity = Data.Decimal.Decimal 0 123
1210 { Style.grouping_integral = Just $ Style.Grouping '_' [2]
1211 , Style.precision = 0
1214 , "\"1_23_456\" = Right 1_23_456" ~:
1215 (Data.Either.rights $
1216 [Text.Parsec.runParser
1217 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1221 { Amount.quantity = Data.Decimal.Decimal 0 123456
1224 { Style.grouping_integral = Just $ Style.Grouping '_' [3, 2]
1225 , Style.precision = 0
1228 , "\"1_23_456.7890_12345_678901\" = Right 1_23_456.7890_12345_678901" ~:
1229 (Data.Either.rights $
1230 [Text.Parsec.runParser
1231 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1232 () "" "1_23_456.7890_12345_678901"])
1235 { Amount.quantity = Data.Decimal.Decimal 15 123456789012345678901
1238 { Style.fractioning = Just '.'
1239 , Style.grouping_integral = Just $ Style.Grouping '_' [3, 2]
1240 , Style.grouping_fractional = Just $ Style.Grouping '_' [4, 5, 6]
1241 , Style.precision = 15
1244 , "\"123456_78901_2345.678_90_1\" = Right 123456_78901_2345.678_90_1" ~:
1245 (Data.Either.rights $
1246 [Text.Parsec.runParser
1247 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1248 () "" "123456_78901_2345.678_90_1"])
1251 { Amount.quantity = Data.Decimal.Decimal 6 123456789012345678901
1254 { Style.fractioning = Just '.'
1255 , Style.grouping_integral = Just $ Style.Grouping '_' [4, 5, 6]
1256 , Style.grouping_fractional = Just $ Style.Grouping '_' [3, 2]
1257 , Style.precision = 6
1260 , "\"$1\" = Right $1" ~:
1261 (Data.Either.rights $
1262 [Text.Parsec.runParser
1263 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1267 { Amount.quantity = Data.Decimal.Decimal 0 1
1270 { Style.fractioning = Nothing
1271 , Style.grouping_integral = Nothing
1272 , Style.grouping_fractional = Nothing
1273 , Style.precision = 0
1274 , Style.unit_side = Just Style.Side_Left
1275 , Style.unit_spaced = Just False
1279 , "\"1$\" = Right 1$" ~:
1280 (Data.Either.rights $
1281 [Text.Parsec.runParser
1282 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1286 { Amount.quantity = Data.Decimal.Decimal 0 1
1289 { Style.fractioning = Nothing
1290 , Style.grouping_integral = Nothing
1291 , Style.grouping_fractional = Nothing
1292 , Style.precision = 0
1293 , Style.unit_side = Just Style.Side_Right
1294 , Style.unit_spaced = Just False
1298 , "\"$ 1\" = Right $ 1" ~:
1299 (Data.Either.rights $
1300 [Text.Parsec.runParser
1301 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1305 { Amount.quantity = Data.Decimal.Decimal 0 1
1308 { Style.fractioning = Nothing
1309 , Style.grouping_integral = Nothing
1310 , Style.grouping_fractional = Nothing
1311 , Style.precision = 0
1312 , Style.unit_side = Just Style.Side_Left
1313 , Style.unit_spaced = Just True
1317 , "\"1 $\" = Right 1 $" ~:
1318 (Data.Either.rights $
1319 [Text.Parsec.runParser
1320 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1324 { Amount.quantity = Data.Decimal.Decimal 0 1
1327 { Style.fractioning = Nothing
1328 , Style.grouping_integral = Nothing
1329 , Style.grouping_fractional = Nothing
1330 , Style.precision = 0
1331 , Style.unit_side = Just Style.Side_Right
1332 , Style.unit_spaced = Just True
1336 , "\"-$1\" = Right $-1" ~:
1337 (Data.Either.rights $
1338 [Text.Parsec.runParser
1339 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1343 { Amount.quantity = Data.Decimal.Decimal 0 (-1)
1346 { Style.fractioning = Nothing
1347 , Style.grouping_integral = Nothing
1348 , Style.grouping_fractional = Nothing
1349 , Style.precision = 0
1350 , Style.unit_side = Just Style.Side_Left
1351 , Style.unit_spaced = Just False
1355 , "\"\\\"4 2\\\"1\" = Right \\\"4 2\\\"1" ~:
1356 (Data.Either.rights $
1357 [Text.Parsec.runParser
1358 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1362 { Amount.quantity = Data.Decimal.Decimal 0 1
1365 { Style.fractioning = Nothing
1366 , Style.grouping_integral = Nothing
1367 , Style.grouping_fractional = Nothing
1368 , Style.precision = 0
1369 , Style.unit_side = Just Style.Side_Left
1370 , Style.unit_spaced = Just False
1372 , Amount.unit = "4 2"
1374 , "\"1\\\"4 2\\\"\" = Right 1\\\"4 2\\\"" ~:
1375 (Data.Either.rights $
1376 [Text.Parsec.runParser
1377 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1381 { Amount.quantity = Data.Decimal.Decimal 0 1
1384 { Style.fractioning = Nothing
1385 , Style.grouping_integral = Nothing
1386 , Style.grouping_fractional = Nothing
1387 , Style.precision = 0
1388 , Style.unit_side = Just Style.Side_Right
1389 , Style.unit_spaced = Just False
1391 , Amount.unit = "4 2"
1393 , "\"$1.000,00\" = Right $1.000,00" ~:
1394 (Data.Either.rights $
1395 [Text.Parsec.runParser
1396 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1400 { Amount.quantity = Data.Decimal.Decimal 0 1000
1403 { Style.fractioning = Just ','
1404 , Style.grouping_integral = Just $ Style.Grouping '.' [3]
1405 , Style.grouping_fractional = Nothing
1406 , Style.precision = 2
1407 , Style.unit_side = Just Style.Side_Left
1408 , Style.unit_spaced = Just False
1412 , "\"1.000,00$\" = Right 1.000,00$" ~:
1413 (Data.Either.rights $
1414 [Text.Parsec.runParser
1415 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1419 { Amount.quantity = Data.Decimal.Decimal 0 1000
1422 { Style.fractioning = Just ','
1423 , Style.grouping_integral = Just $ Style.Grouping '.' [3]
1424 , Style.grouping_fractional = Nothing
1425 , Style.precision = 2
1426 , Style.unit_side = Just Style.Side_Right
1427 , Style.unit_spaced = Just False