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 Data.Decimal (DecimalRaw(..))
15 import qualified Hcompta.Model.Account as Account
16 import qualified Hcompta.Model.Amount as Amount
17 import qualified Hcompta.Model.Amount.Style as Style
18 import qualified Hcompta.Model.Transaction.Posting as Posting
19 import qualified Hcompta.Calc.Balance as Calc.Balance
20 import qualified Hcompta.Format.Ledger.Read as Format.Ledger.Read
23 main = defaultMain $ hUnitTestToTests test_Hcompta
29 [ "Account" ~: TestList
32 (reverse $ Account.fold [] (:) []) ~?= []
34 (reverse $ Account.fold ["A"] (:) []) ~?= [["A"]]
35 , "[A, B] = [[A], [A, B]]" ~:
36 (reverse $ Account.fold ["A", "B"] (:) []) ~?= [["A"], ["A", "B"]]
37 , "[A, B, C] = [[A], [A, B], [A, B, C]]" ~:
38 (reverse $ Account.fold ["A", "B", "C"] (:) []) ~?= [["A"], ["A", "B"], ["A", "B", "C"]]
40 , "ascending" ~: TestList
42 Account.ascending [] ~?= []
44 Account.ascending ["A"] ~?= []
46 Account.ascending ["A", "B"] ~?= ["A"]
47 , "[A, B, C] = [A, B]" ~:
48 Account.ascending ["A", "B", "C"] ~?= ["A", "B"]
53 [ "Balance" ~: TestList
54 [ "posting" ~: TestList
55 [ "[A+$1] = A+$1 & $+1" ~:
58 { Posting.account=["A"]
59 , Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
64 { Calc.Balance.by_account =
66 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
67 , Calc.Balance.by_unit =
69 Data.List.map Calc.Balance.assoc_by_amount_unit $
70 [ Calc.Balance.Sum_by_Unit
71 { Calc.Balance.amount = Amount.usd $ 1
72 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
77 , "[A+$1, A-$1] = {A+$0, $+0}" ~:
79 (flip Calc.Balance.posting)
82 { Posting.account=["A"]
83 , Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
86 { Posting.account=["A"]
87 , Posting.amounts=Amount.from_List [ Amount.usd $ -1 ]
92 { Calc.Balance.by_account =
94 [ (["A"], Amount.from_List [ Amount.usd $ 0 ]) ]
95 , Calc.Balance.by_unit =
97 Data.List.map Calc.Balance.assoc_by_amount_unit $
98 [ Calc.Balance.Sum_by_Unit
99 { Calc.Balance.amount = Amount.usd $ 0
100 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
105 , "[A+$1, A-€1] = {A+$1-€1, $+1 €-1}" ~:
107 (flip Calc.Balance.posting)
110 { Posting.account=["A"]
111 , Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
114 { Posting.account=["A"]
115 , Posting.amounts=Amount.from_List [ Amount.eur $ -1 ]
120 { Calc.Balance.by_account =
122 [ (["A"], Amount.from_List [ Amount.usd $ 1, Amount.eur $ -1 ]) ]
123 , Calc.Balance.by_unit =
125 Data.List.map Calc.Balance.assoc_by_amount_unit $
126 [ Calc.Balance.Sum_by_Unit
127 { Calc.Balance.amount = Amount.usd $ 1
128 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
131 , Calc.Balance.Sum_by_Unit
132 { Calc.Balance.amount = Amount.eur $ -1
133 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
138 , "[A+$1, B-$1] = {A+$1 B-$1, $+0}" ~:
140 (flip Calc.Balance.posting)
143 { Posting.account=["A"]
144 , Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
147 { Posting.account=["B"]
148 , Posting.amounts=Amount.from_List [ Amount.usd $ -1 ]
153 { Calc.Balance.by_account =
155 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
156 , (["B"], Amount.from_List [ Amount.usd $ -1 ])
158 , Calc.Balance.by_unit =
160 Data.List.map Calc.Balance.assoc_by_amount_unit $
161 [ Calc.Balance.Sum_by_Unit
162 { Calc.Balance.amount = Amount.usd $ 0
163 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
168 , "[A+$1+€2, A-$1-€2] = {A+$0+€0, $+0 €+0}" ~:
170 (flip Calc.Balance.posting)
173 { Posting.account=["A"]
174 , Posting.amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2 ]
177 { Posting.account=["A"]
178 , Posting.amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2 ]
183 { Calc.Balance.by_account =
185 [ (["A"], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
187 , Calc.Balance.by_unit =
189 Data.List.map Calc.Balance.assoc_by_amount_unit $
190 [ Calc.Balance.Sum_by_Unit
191 { Calc.Balance.amount = Amount.usd $ 0
192 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
195 , Calc.Balance.Sum_by_Unit
196 { Calc.Balance.amount = Amount.eur $ 0
197 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
202 , "[A+$1+€2+£3, B-$1-2€-£3] = {A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~:
204 (flip Calc.Balance.posting)
207 { Posting.account=["A"]
208 , Posting.amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ]
211 { Posting.account=["B"]
212 , Posting.amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ]
217 { Calc.Balance.by_account =
219 [ (["A"], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
220 , (["B"], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
222 , Calc.Balance.by_unit =
224 Data.List.map Calc.Balance.assoc_by_amount_unit $
225 [ Calc.Balance.Sum_by_Unit
226 { Calc.Balance.amount = Amount.usd $ 0
227 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
230 , Calc.Balance.Sum_by_Unit
231 { Calc.Balance.amount = Amount.eur $ 0
232 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
235 , Calc.Balance.Sum_by_Unit
236 { Calc.Balance.amount = Amount.gbp $ 0
237 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
243 , "union" ~: TestList
250 , "{A+$1, $+1} {A+$1, $+1} = {A+$2, $+2}" ~:
252 (Calc.Balance.Balance
253 { Calc.Balance.by_account =
255 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
256 , Calc.Balance.by_unit =
258 Data.List.map Calc.Balance.assoc_by_amount_unit $
259 [ Calc.Balance.Sum_by_Unit
260 { Calc.Balance.amount = Amount.usd $ 1
261 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
266 (Calc.Balance.Balance
267 { Calc.Balance.by_account =
269 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
270 , Calc.Balance.by_unit =
272 Data.List.map Calc.Balance.assoc_by_amount_unit $
273 [ Calc.Balance.Sum_by_Unit
274 { Calc.Balance.amount = Amount.usd $ 1
275 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
282 { Calc.Balance.by_account =
284 [ (["A"], Amount.from_List [ Amount.usd $ 2 ]) ]
285 , Calc.Balance.by_unit =
287 Data.List.map Calc.Balance.assoc_by_amount_unit $
288 [ Calc.Balance.Sum_by_Unit
289 { Calc.Balance.amount = Amount.usd $ 2
290 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
295 , "{A+$1, $+1} {B+$1, $+1} = {A+$1 B+$1, $+2}" ~:
297 (Calc.Balance.Balance
298 { Calc.Balance.by_account =
300 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
301 , Calc.Balance.by_unit =
303 Data.List.map Calc.Balance.assoc_by_amount_unit $
304 [ Calc.Balance.Sum_by_Unit
305 { Calc.Balance.amount = Amount.usd $ 1
306 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
311 (Calc.Balance.Balance
312 { Calc.Balance.by_account =
314 [ (["B"], Amount.from_List [ Amount.usd $ 1 ]) ]
315 , Calc.Balance.by_unit =
317 Data.List.map Calc.Balance.assoc_by_amount_unit $
318 [ Calc.Balance.Sum_by_Unit
319 { Calc.Balance.amount = Amount.usd $ 1
320 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
327 { Calc.Balance.by_account =
329 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
330 , (["B"], Amount.from_List [ Amount.usd $ 1 ]) ]
331 , Calc.Balance.by_unit =
333 Data.List.map Calc.Balance.assoc_by_amount_unit $
334 [ Calc.Balance.Sum_by_Unit
335 { Calc.Balance.amount = Amount.usd $ 2
336 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
341 , "{A+$1, $+1} {B+€1, €+1} = {A+$1 B+€1, $+1 €+1}" ~:
343 (Calc.Balance.Balance
344 { Calc.Balance.by_account =
346 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ]
347 , Calc.Balance.by_unit =
349 Data.List.map Calc.Balance.assoc_by_amount_unit $
350 [ Calc.Balance.Sum_by_Unit
351 { Calc.Balance.amount = Amount.usd $ 1
352 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
357 (Calc.Balance.Balance
358 { Calc.Balance.by_account =
360 [ (["B"], Amount.from_List [ Amount.eur $ 1 ]) ]
361 , Calc.Balance.by_unit =
363 Data.List.map Calc.Balance.assoc_by_amount_unit $
364 [ Calc.Balance.Sum_by_Unit
365 { Calc.Balance.amount = Amount.eur $ 1
366 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
373 { Calc.Balance.by_account =
375 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
376 , (["B"], Amount.from_List [ Amount.eur $ 1 ]) ]
377 , Calc.Balance.by_unit =
379 Data.List.map Calc.Balance.assoc_by_amount_unit $
380 [ Calc.Balance.Sum_by_Unit
381 { Calc.Balance.amount = Amount.usd $ 1
382 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
385 , Calc.Balance.Sum_by_Unit
386 { Calc.Balance.amount = Amount.eur $ 1
387 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
393 , "expand" ~: TestList
394 [ "nil_By_Account = nil_By_Account" ~:
396 Calc.Balance.nil_By_Account
398 (Calc.Balance.Expanded $
399 Calc.Balance.nil_By_Account)
403 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ])
405 (Calc.Balance.Expanded $
407 [ (["A"], Amount.from_List [ Amount.usd $ 1 ]) ])
408 , "A/A+$1 = A+$1 A/A+$1" ~:
411 [ (["A", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
413 (Calc.Balance.Expanded $
415 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
416 , (["A", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
417 , "A/B+$1 = A+$1 A/B+$1" ~:
420 [ (["A", "B"], Amount.from_List [ Amount.usd $ 1 ]) ])
422 (Calc.Balance.Expanded $
424 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
425 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ]) ])
426 , "A/B/C+$1 = A+$1 A/B+$1 A/B/C+$1" ~:
429 [ (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ]) ])
431 (Calc.Balance.Expanded $
433 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
434 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
435 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ]) ])
436 , "A+$1 A/B+$1 = A+$2 A/B+$1" ~:
439 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
440 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ]) ])
442 (Calc.Balance.Expanded $
444 [ (["A"], Amount.from_List [ Amount.usd $ 2 ])
445 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ]) ])
446 , "A+$1 A/B+$1 A/B/C+$1 = A+$3 A/B+$2 A/B/C+$1" ~:
449 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
450 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
451 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ])
454 (Calc.Balance.Expanded $
456 [ (["A"], Amount.from_List [ Amount.usd $ 3 ])
457 , (["A", "B"], Amount.from_List [ Amount.usd $ 2 ])
458 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ])
460 , "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" ~:
463 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
464 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
465 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 1 ])
466 , (["A", "B", "C", "D"], Amount.from_List [ Amount.usd $ 1 ])
469 (Calc.Balance.Expanded $
471 [ (["A"], Amount.from_List [ Amount.usd $ 4 ])
472 , (["A", "B"], Amount.from_List [ Amount.usd $ 3 ])
473 , (["A", "B", "C"], Amount.from_List [ Amount.usd $ 2 ])
474 , (["A", "B", "C", "D"], Amount.from_List [ Amount.usd $ 1 ])
476 , "A+$1 A/B+$1 B/A+$1 = A+$2 A/B+$1 B/A+$1" ~:
479 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
480 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
481 , (["B", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
483 (Calc.Balance.Expanded $
485 [ (["A"], Amount.from_List [ Amount.usd $ 2 ])
486 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
487 , (["B"], Amount.from_List [ Amount.usd $ 1 ])
488 , (["B", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
489 , "A+$1 A/B+$1 B/A+$1 = A+$2 A/B+$1 B/A+$1" ~:
492 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
493 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
494 , (["B", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
496 (Calc.Balance.Expanded $
498 [ (["A"], Amount.from_List [ Amount.usd $ 2 ])
499 , (["A", "B"], Amount.from_List [ Amount.usd $ 1 ])
500 , (["B"], Amount.from_List [ Amount.usd $ 1 ])
501 , (["B", "A"], Amount.from_List [ Amount.usd $ 1 ]) ])
503 , "is_equilibrated" ~: TestList
504 [ "nil = True" ~: TestCase $
506 Calc.Balance.is_equilibrated $
508 , "{A+$0, $+0} = True" ~: TestCase $
510 Calc.Balance.is_equilibrated $
512 { Calc.Balance.by_account =
514 [ (["A"], Amount.from_List [ Amount.usd $ 0 ])
516 , Calc.Balance.by_unit =
518 Data.List.map Calc.Balance.assoc_by_amount_unit $
519 [ Calc.Balance.Sum_by_Unit
520 { Calc.Balance.amount = Amount.usd $ 0
521 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
526 , "{A+$1, $+1} = False" ~: TestCase $
528 Calc.Balance.is_equilibrated $
530 { Calc.Balance.by_account =
532 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
534 , Calc.Balance.by_unit =
536 Data.List.map Calc.Balance.assoc_by_amount_unit $
537 [ Calc.Balance.Sum_by_Unit
538 { Calc.Balance.amount = Amount.usd $ 1
539 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
544 , "{A+$0+€0, $0 €+0} = True" ~: TestCase $
546 Calc.Balance.is_equilibrated $
548 { Calc.Balance.by_account =
550 [ (["A"], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
552 , Calc.Balance.by_unit =
554 Data.List.map Calc.Balance.assoc_by_amount_unit $
555 [ Calc.Balance.Sum_by_Unit
556 { Calc.Balance.amount = Amount.usd $ 0
557 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
560 , Calc.Balance.Sum_by_Unit
561 { Calc.Balance.amount = Amount.eur $ 0
562 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
567 , "{A+$1, B-$1, $+0} = True" ~: TestCase $
569 Calc.Balance.is_equilibrated $
571 { Calc.Balance.by_account =
573 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
574 , (["B"], Amount.from_List [ Amount.usd $ -1 ])
576 , Calc.Balance.by_unit =
578 Data.List.map Calc.Balance.assoc_by_amount_unit $
579 [ Calc.Balance.Sum_by_Unit
580 { Calc.Balance.amount = Amount.usd $ 0
581 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
586 , "{A+$1 B, $+1} = True" ~: TestCase $
588 Calc.Balance.is_equilibrated $
590 { Calc.Balance.by_account =
592 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
593 , (["B"], Amount.from_List [])
595 , Calc.Balance.by_unit =
597 Data.List.map Calc.Balance.assoc_by_amount_unit $
598 [ Calc.Balance.Sum_by_Unit
599 { Calc.Balance.amount = Amount.usd $ 1
600 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
605 , "{A+$1 B+€1, $+1 €+1} = True" ~: TestCase $
607 Calc.Balance.is_equilibrated $
609 { Calc.Balance.by_account =
611 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
612 , (["B"], Amount.from_List [ Amount.eur $ 1 ])
614 , Calc.Balance.by_unit =
616 Data.List.map Calc.Balance.assoc_by_amount_unit $
617 [ Calc.Balance.Sum_by_Unit
618 { Calc.Balance.amount = Amount.usd $ 1
619 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
622 , Calc.Balance.Sum_by_Unit
623 { Calc.Balance.amount = Amount.eur $ 1
624 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
629 , "{A+$1 B-$1+€1, $+0 €+1} = True" ~: TestCase $
631 Calc.Balance.is_equilibrated $
633 { Calc.Balance.by_account =
635 [ (["A"], Amount.from_List [ Amount.usd $ 1 ])
636 , (["B"], Amount.from_List [ Amount.usd $ -1, Amount.eur $ 1 ])
638 , Calc.Balance.by_unit =
640 Data.List.map Calc.Balance.assoc_by_amount_unit $
641 [ Calc.Balance.Sum_by_Unit
642 { Calc.Balance.amount = Amount.usd $ 0
643 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
646 , Calc.Balance.Sum_by_Unit
647 { Calc.Balance.amount = Amount.eur $ 1
648 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
653 , "{A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0} = True" ~: TestCase $
655 Calc.Balance.is_equilibrated $
657 { Calc.Balance.by_account =
659 [ (["A"], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
660 , (["B"], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
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 $ 0
667 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
670 , Calc.Balance.Sum_by_Unit
671 { Calc.Balance.amount = Amount.eur $ 0
672 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
675 , Calc.Balance.Sum_by_Unit
676 { Calc.Balance.amount = Amount.gbp $ 0
677 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
685 , "Format" ~: TestList
686 [ "Ledger" ~: TestList
688 [ "account_name" ~: TestList
690 (Data.Either.rights $
691 [Text.Parsec.runParser
692 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
696 , "\"A\" = Right \"A\"" ~:
697 (Data.Either.rights $
698 [Text.Parsec.runParser
699 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
703 , "\"AA\" = Right \"AA\"" ~:
704 (Data.Either.rights $
705 [Text.Parsec.runParser
706 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
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)
745 , "\"A A\" = Right \"A A\"" ~:
746 (Data.Either.rights $
747 [Text.Parsec.runParser
748 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
753 (Data.Either.rights $
754 [Text.Parsec.runParser
755 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
759 , "\"A \\n\" = Left" ~:
760 (Data.Either.rights $
761 [Text.Parsec.runParser
762 (Format.Ledger.Read.account_name <* Text.Parsec.eof)
767 , "account" ~: TestList
769 (Data.Either.rights $
770 [Text.Parsec.runParser
771 (Format.Ledger.Read.account <* Text.Parsec.eof)
775 , "\"A\" = Right [\"A\"]" ~:
776 (Data.Either.rights $
777 [Text.Parsec.runParser
778 (Format.Ledger.Read.account <* Text.Parsec.eof)
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)
810 , "\"A:B\" = Right [\"A\", \"B\"]" ~:
811 (Data.Either.rights $
812 [Text.Parsec.runParser
813 (Format.Ledger.Read.account <* Text.Parsec.eof)
817 , "\"A:B:C\" = Right [\"A\", \"B\", \"C\"]" ~:
818 (Data.Either.rights $
819 [Text.Parsec.runParser
820 (Format.Ledger.Read.account <* Text.Parsec.eof)
824 , "\"Aa:Bbb:Cccc\" = Right [\"Aa\", \"Bbb\", \":Cccc\"]" ~:
825 (Data.Either.rights $
826 [Text.Parsec.runParser
827 (Format.Ledger.Read.account <* Text.Parsec.eof)
828 () "" "Aa:Bbb:Cccc"])
830 [["Aa", "Bbb", "Cccc"]]
831 , "\"A a : B b b : C c c c\" = Right [\"A a \", \" B b b \", \": C c c c\"]" ~:
832 (Data.Either.rights $
833 [Text.Parsec.runParser
834 (Format.Ledger.Read.account <* Text.Parsec.eof)
835 () "" "A a : B b b : C c c c"])
837 [["A a ", " B b b ", " C c c c"]]
838 , "\"A: :C\" = Right [\"A\", \" \", \"C\"]" ~:
839 (Data.Either.rights $
840 [Text.Parsec.runParser
841 (Format.Ledger.Read.account <* Text.Parsec.eof)
845 , "\"A::C\" = Left" ~:
846 (Data.Either.rights $
847 [Text.Parsec.runParser
848 (Format.Ledger.Read.account <* Text.Parsec.eof)
853 , "amount" ~: TestList
855 (Data.Either.rights $
856 [Text.Parsec.runParser
857 (Format.Ledger.Read.amount <* Text.Parsec.eof)
861 , "\"0\" = Right 0" ~:
862 (Data.Either.rights $
863 [Text.Parsec.runParser
864 (Format.Ledger.Read.amount <* Text.Parsec.eof)
868 { Amount.quantity = Decimal 0 0
870 , "\"00\" = Right 0" ~:
871 (Data.Either.rights $
872 [Text.Parsec.runParser
873 (Format.Ledger.Read.amount <* Text.Parsec.eof)
877 { Amount.quantity = Decimal 0 0
879 , "\"0.\" = Right 0." ~:
880 (Data.Either.rights $
881 [Text.Parsec.runParser
882 (Format.Ledger.Read.amount <* Text.Parsec.eof)
886 { Amount.quantity = Decimal 0 0
889 { Style.fractioning = Just '.'
892 , "\".0\" = Right 0.0" ~:
893 (Data.Either.rights $
894 [Text.Parsec.runParser
895 (Format.Ledger.Read.amount <* Text.Parsec.eof)
899 { Amount.quantity = Decimal 0 0
902 { Style.fractioning = Just '.'
903 , Style.precision = 1
906 , "\"0,\" = Right 0," ~:
907 (Data.Either.rights $
908 [Text.Parsec.runParser
909 (Format.Ledger.Read.amount <* Text.Parsec.eof)
913 { Amount.quantity = Decimal 0 0
916 { Style.fractioning = Just ','
919 , "\",0\" = Right 0,0" ~:
920 (Data.Either.rights $
921 [Text.Parsec.runParser
922 (Format.Ledger.Read.amount <* Text.Parsec.eof)
926 { Amount.quantity = Decimal 0 0
929 { Style.fractioning = Just ','
930 , Style.precision = 1
934 (Data.Either.rights $
935 [Text.Parsec.runParser
936 (Format.Ledger.Read.amount <* Text.Parsec.eof)
941 (Data.Either.rights $
942 [Text.Parsec.runParser
943 (Format.Ledger.Read.amount <* Text.Parsec.eof)
947 , "\"0.0\" = Right 0.0" ~:
948 (Data.Either.rights $
949 [Text.Parsec.runParser
950 (Format.Ledger.Read.amount <* Text.Parsec.eof)
954 { Amount.quantity = Decimal 0 0
957 { Style.fractioning = Just '.'
958 , Style.precision = 1
961 , "\"00.00\" = Right 0.00" ~:
962 (Data.Either.rights $
963 [Text.Parsec.runParser
964 (Format.Ledger.Read.amount <* Text.Parsec.eof)
968 { Amount.quantity = Decimal 0 0
971 { Style.fractioning = Just '.'
972 , Style.precision = 2
975 , "\"0,0\" = Right 0,0" ~:
976 (Data.Either.rights $
977 [Text.Parsec.runParser
978 (Format.Ledger.Read.amount <* Text.Parsec.eof)
982 { Amount.quantity = Decimal 0 0
985 { Style.fractioning = Just ','
986 , Style.precision = 1
989 , "\"00,00\" = Right 0,00" ~:
990 (Data.Either.rights $
991 [Text.Parsec.runParser
992 (Format.Ledger.Read.amount <* Text.Parsec.eof)
996 { Amount.quantity = Decimal 0 0
999 { Style.fractioning = Just ','
1000 , Style.precision = 2
1003 , "\"0_0\" = Right 0" ~:
1004 (Data.Either.rights $
1005 [Text.Parsec.runParser
1006 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1010 { Amount.quantity = Decimal 0 0
1013 { Style.fractioning = Nothing
1014 , Style.grouping_integral = Just $ Style.Grouping '_' [1]
1015 , Style.precision = 0
1018 , "\"00_00\" = Right 0" ~:
1019 (Data.Either.rights $
1020 [Text.Parsec.runParser
1021 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1025 { Amount.quantity = Decimal 0 0
1028 { Style.fractioning = Nothing
1029 , Style.grouping_integral = Just $ Style.Grouping '_' [2]
1030 , Style.precision = 0
1033 , "\"0,000.00\" = Right 0,000.00" ~:
1034 (Data.Either.rights $
1035 [Text.Parsec.runParser
1036 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1040 { Amount.quantity = Decimal 0 0
1043 { Style.fractioning = Just '.'
1044 , Style.grouping_integral = Just $ Style.Grouping ',' [3]
1045 , Style.precision = 2
1048 , "\"0.000,00\" = Right 0.000,00" ~:
1049 (Data.Either.rights $
1050 [Text.Parsec.runParser
1051 (Format.Ledger.Read.amount)
1055 { Amount.quantity = Decimal 0 0
1058 { Style.fractioning = Just ','
1059 , Style.grouping_integral = Just $ Style.Grouping '.' [3]
1060 , Style.precision = 2
1063 , "\"1,000.00\" = Right 1,000.00" ~:
1064 (Data.Either.rights $
1065 [Text.Parsec.runParser
1066 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1070 { Amount.quantity = Decimal 0 1000
1073 { Style.fractioning = Just '.'
1074 , Style.grouping_integral = Just $ Style.Grouping ',' [3]
1075 , Style.precision = 2
1078 , "\"1.000,00\" = Right 1.000,00" ~:
1079 (Data.Either.rights $
1080 [Text.Parsec.runParser
1081 (Format.Ledger.Read.amount)
1085 { Amount.quantity = Decimal 0 1000
1088 { Style.fractioning = Just ','
1089 , Style.grouping_integral = Just $ Style.Grouping '.' [3]
1090 , Style.precision = 2
1093 , "\"1,000.00.\" = Left" ~:
1094 (Data.Either.rights $
1095 [Text.Parsec.runParser
1096 (Format.Ledger.Read.amount)
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 , "\"12\" = Right 12" ~:
1115 (Data.Either.rights $
1116 [Text.Parsec.runParser
1117 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1121 { Amount.quantity = Decimal 0 123
1123 , "\"1.2\" = Right 1.2" ~:
1124 (Data.Either.rights $
1125 [Text.Parsec.runParser
1126 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1130 { Amount.quantity = Decimal 1 12
1133 { Style.fractioning = Just '.'
1134 , Style.precision = 1
1137 , "\"1,2\" = Right 1,2" ~:
1138 (Data.Either.rights $
1139 [Text.Parsec.runParser
1140 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1144 { Amount.quantity = Decimal 1 12
1147 { Style.fractioning = Just ','
1148 , Style.precision = 1
1151 , "\"12.23\" = Right 12.23" ~:
1152 (Data.Either.rights $
1153 [Text.Parsec.runParser
1154 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1158 { Amount.quantity = Decimal 2 1234
1161 { Style.fractioning = Just '.'
1162 , Style.precision = 2
1165 , "\"12,23\" = Right 12,23" ~:
1166 (Data.Either.rights $
1167 [Text.Parsec.runParser
1168 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1172 { Amount.quantity = Decimal 2 1234
1175 { Style.fractioning = Just ','
1176 , Style.precision = 2
1179 , "\"1_2\" = Right 1_2" ~:
1180 (Data.Either.rights $
1181 [Text.Parsec.runParser
1182 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1186 { Amount.quantity = Decimal 0 12
1189 { Style.grouping_integral = Just $ Style.Grouping '_' [1]
1190 , Style.precision = 0
1193 , "\"1_23\" = Right 1_23" ~:
1194 (Data.Either.rights $
1195 [Text.Parsec.runParser
1196 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1200 { Amount.quantity = Decimal 0 123
1203 { Style.grouping_integral = Just $ Style.Grouping '_' [2]
1204 , Style.precision = 0
1207 , "\"1_23_456\" = Right 1_23_456" ~:
1208 (Data.Either.rights $
1209 [Text.Parsec.runParser
1210 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1214 { Amount.quantity = Decimal 0 123456
1217 { Style.grouping_integral = Just $ Style.Grouping '_' [3, 2]
1218 , Style.precision = 0
1221 , "\"1_23_456.7890_12345_678901\" = Right 1_23_456.7890_12345_678901" ~:
1222 (Data.Either.rights $
1223 [Text.Parsec.runParser
1224 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1225 () "" "1_23_456.7890_12345_678901"])
1228 { Amount.quantity = Decimal 15 123456789012345678901
1231 { Style.fractioning = Just '.'
1232 , Style.grouping_integral = Just $ Style.Grouping '_' [3, 2]
1233 , Style.grouping_fractional = Just $ Style.Grouping '_' [4, 5, 6]
1234 , Style.precision = 15
1237 , "\"123456_78901_2345.678_90_1\" = Right 123456_78901_2345.678_90_1" ~:
1238 (Data.Either.rights $
1239 [Text.Parsec.runParser
1240 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1241 () "" "123456_78901_2345.678_90_1"])
1244 { Amount.quantity = Decimal 6 123456789012345678901
1247 { Style.fractioning = Just '.'
1248 , Style.grouping_integral = Just $ Style.Grouping '_' [4, 5, 6]
1249 , Style.grouping_fractional = Just $ Style.Grouping '_' [3, 2]
1250 , Style.precision = 6
1253 , "\"$1\" = Right $1" ~:
1254 (Data.Either.rights $
1255 [Text.Parsec.runParser
1256 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1260 { Amount.quantity = Decimal 0 1
1263 { Style.fractioning = Nothing
1264 , Style.grouping_integral = Nothing
1265 , Style.grouping_fractional = Nothing
1266 , Style.precision = 0
1267 , Style.unit_side = Just Style.Side_Left
1268 , Style.unit_spaced = Just False
1272 , "\"1$\" = Right 1$" ~:
1273 (Data.Either.rights $
1274 [Text.Parsec.runParser
1275 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1279 { Amount.quantity = Decimal 0 1
1282 { Style.fractioning = Nothing
1283 , Style.grouping_integral = Nothing
1284 , Style.grouping_fractional = Nothing
1285 , Style.precision = 0
1286 , Style.unit_side = Just Style.Side_Right
1287 , Style.unit_spaced = Just False
1291 , "\"$ 1\" = Right $ 1" ~:
1292 (Data.Either.rights $
1293 [Text.Parsec.runParser
1294 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1298 { Amount.quantity = Decimal 0 1
1301 { Style.fractioning = Nothing
1302 , Style.grouping_integral = Nothing
1303 , Style.grouping_fractional = Nothing
1304 , Style.precision = 0
1305 , Style.unit_side = Just Style.Side_Left
1306 , Style.unit_spaced = Just True
1310 , "\"1 $\" = Right 1 $" ~:
1311 (Data.Either.rights $
1312 [Text.Parsec.runParser
1313 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1317 { Amount.quantity = Decimal 0 1
1320 { Style.fractioning = Nothing
1321 , Style.grouping_integral = Nothing
1322 , Style.grouping_fractional = Nothing
1323 , Style.precision = 0
1324 , Style.unit_side = Just Style.Side_Right
1325 , Style.unit_spaced = Just True
1329 , "\"-$1\" = Right $-1" ~:
1330 (Data.Either.rights $
1331 [Text.Parsec.runParser
1332 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1336 { Amount.quantity = Decimal 0 (-1)
1339 { Style.fractioning = Nothing
1340 , Style.grouping_integral = Nothing
1341 , Style.grouping_fractional = Nothing
1342 , Style.precision = 0
1343 , Style.unit_side = Just Style.Side_Left
1344 , Style.unit_spaced = Just False
1348 , "\"\\\"4 2\\\"1\" = Right \\\"4 2\\\"1" ~:
1349 (Data.Either.rights $
1350 [Text.Parsec.runParser
1351 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1355 { Amount.quantity = Decimal 0 1
1358 { Style.fractioning = Nothing
1359 , Style.grouping_integral = Nothing
1360 , Style.grouping_fractional = Nothing
1361 , Style.precision = 0
1362 , Style.unit_side = Just Style.Side_Left
1363 , Style.unit_spaced = Just False
1365 , Amount.unit = "4 2"
1367 , "\"1\\\"4 2\\\"\" = Right 1\\\"4 2\\\"" ~:
1368 (Data.Either.rights $
1369 [Text.Parsec.runParser
1370 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1374 { Amount.quantity = Decimal 0 1
1377 { Style.fractioning = Nothing
1378 , Style.grouping_integral = Nothing
1379 , Style.grouping_fractional = Nothing
1380 , Style.precision = 0
1381 , Style.unit_side = Just Style.Side_Right
1382 , Style.unit_spaced = Just False
1384 , Amount.unit = "4 2"
1386 , "\"$1.000,00\" = Right $1.000,00" ~:
1387 (Data.Either.rights $
1388 [Text.Parsec.runParser
1389 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1393 { Amount.quantity = Decimal 0 1000
1396 { Style.fractioning = Just ','
1397 , Style.grouping_integral = Just $ Style.Grouping '.' [3]
1398 , Style.grouping_fractional = Nothing
1399 , Style.precision = 2
1400 , Style.unit_side = Just Style.Side_Left
1401 , Style.unit_spaced = Just False
1405 , "\"1.000,00$\" = Right 1.000,00$" ~:
1406 (Data.Either.rights $
1407 [Text.Parsec.runParser
1408 (Format.Ledger.Read.amount <* Text.Parsec.eof)
1412 { Amount.quantity = Decimal 0 1000
1415 { Style.fractioning = Just ','
1416 , Style.grouping_integral = Just $ Style.Grouping '.' [3]
1417 , Style.grouping_fractional = Nothing
1418 , Style.precision = 2
1419 , Style.unit_side = Just Style.Side_Right
1420 , Style.unit_spaced = Just False