1 {-# LANGUAGE FlexibleInstances #-}
2 {-# LANGUAGE OverloadedStrings #-}
3 {-# LANGUAGE ScopedTypeVariables #-}
4 {-# LANGUAGE StandaloneDeriving #-}
5 {-# LANGUAGE TupleSections #-}
8 import Test.HUnit hiding ((~?))
9 import Test.Framework.Providers.HUnit (hUnitTestToTests)
10 import Test.Framework.Runners.Console (defaultMain)
12 -- import Control.Applicative (Const(..))
13 import Control.Monad.IO.Class (liftIO)
14 import Data.Decimal (DecimalRaw(..))
15 import qualified Data.Either
16 -- import Data.Functor.Compose (Compose(..))
17 import qualified Data.List
18 import Data.List.NonEmpty (NonEmpty(..))
19 import qualified Data.Map.Strict as Data.Map
20 import Data.Text (Text)
21 import qualified Data.Time.Calendar as Time
22 import qualified Data.Time.LocalTime as Time
23 import qualified Text.Parsec as P hiding (char, space, spaces, string)
24 import qualified Text.Parsec.Pos as P
26 import qualified Hcompta.Format.Ledger.Account.Read as Account.Read
27 import qualified Hcompta.Format.Ledger.Amount as Amount
28 import qualified Hcompta.Format.Ledger.Amount.Read as Amount.Read
29 import qualified Hcompta.Format.Ledger.Amount.Style as Amount.Style
30 import qualified Hcompta.Format.Ledger.Amount.Write as Amount.Write
31 import qualified Hcompta.Date as Date
32 import qualified Hcompta.Format.Ledger.Date.Read as Date.Read
33 import qualified Hcompta.Format.Ledger.Date.Write as Date.Write
34 import qualified Hcompta.Format.Ledger as Ledger
35 import qualified Hcompta.Format.Ledger.Read as Ledger.Read
36 import qualified Hcompta.Format.Ledger.Write as Ledger.Write
37 import qualified Hcompta.Lib.Parsec as P
38 import qualified Hcompta.Tag as Tag
40 deriving instance Eq Ledger.Amount
43 main = defaultMain $ hUnitTestToTests test_Hcompta
45 -- (~?) :: String -> Bool -> Test
46 -- (~?) s b = s ~: (b ~?= True)
51 [ "Format" ~: TestList
52 [ "Ledger" ~: TestList
53 [ "Account" ~: TestList
55 [ "section" ~: TestList
59 (Account.Read.section <* P.eof)
66 (Account.Read.section <* P.eof)
73 (Account.Read.section <* P.eof)
80 (Account.Read.section <* P.eof)
87 (Account.Read.section <* P.eof)
94 (Account.Read.section <* P.eof)
101 (Account.Read.section <* P.eof)
106 (Data.Either.rights $
108 (Account.Read.section <* P.eof)
113 (Data.Either.rights $
115 (Account.Read.section)
120 (Data.Either.rights $
122 (Account.Read.section <* P.eof)
123 () "" ("A A"::Text)])
127 (Data.Either.rights $
129 (Account.Read.section <* P.eof)
134 (Data.Either.rights $
136 (Account.Read.section <* P.eof)
137 () "" ("A\t"::Text)])
141 (Data.Either.rights $
143 (Account.Read.section <* P.eof)
144 () "" ("A \n"::Text)])
148 (Data.Either.rights $
150 (Account.Read.section <* P.eof)
151 () "" ("(A)A"::Text)])
155 (Data.Either.rights $
157 (Account.Read.section <* P.eof)
158 () "" ("( )A"::Text)])
162 (Data.Either.rights $
164 (Account.Read.section <* P.eof)
165 () "" ("(A) A"::Text)])
169 (Data.Either.rights $
171 (Account.Read.section <* P.eof)
172 () "" ("[ ]A"::Text)])
176 (Data.Either.rights $
178 (Account.Read.section <* P.eof)
179 () "" ("(A) "::Text)])
183 (Data.Either.rights $
185 (Account.Read.section <* P.eof)
186 () "" ("(A)"::Text)])
190 (Data.Either.rights $
192 (Account.Read.section <* P.eof)
193 () "" ("A(A)"::Text)])
197 (Data.Either.rights $
199 (Account.Read.section <* P.eof)
200 () "" ("[A]A"::Text)])
204 (Data.Either.rights $
206 (Account.Read.section <* P.eof)
207 () "" ("[A] A"::Text)])
211 (Data.Either.rights $
213 (Account.Read.section <* P.eof)
214 () "" ("[A] "::Text)])
218 (Data.Either.rights $
220 (Account.Read.section <* P.eof)
221 () "" ("[A]"::Text)])
225 , "account" ~: TestList
227 (Data.Either.rights $
229 (Account.Read.account <* P.eof)
234 (Data.Either.rights $
236 (Account.Read.account <* P.eof)
241 (Data.Either.rights $
243 (Account.Read.account <* P.eof)
248 (Data.Either.rights $
250 (Account.Read.account <* P.eof)
255 (Data.Either.rights $
257 (Account.Read.account <* P.eof)
262 (Data.Either.rights $
264 (Account.Read.account <* P.eof)
269 (Data.Either.rights $
271 (Account.Read.account <* P.eof)
272 () "" ("A:B"::Text)])
276 (Data.Either.rights $
278 (Account.Read.account <* P.eof)
279 () "" ("A:B:C"::Text)])
282 , "\"Aa:Bbb:Cccc\"" ~:
283 (Data.Either.rights $
285 (Account.Read.account <* P.eof)
286 () "" ("Aa:Bbb:Cccc"::Text)])
288 ["Aa":|["Bbb", "Cccc"]]
289 , "\"A a : B b b : C c c c\"" ~:
290 (Data.Either.rights $
292 (Account.Read.account <* P.eof)
293 () "" ("A a : B b b : C c c c"::Text)])
295 ["A a ":|[" B b b ", " C c c c"]]
297 (Data.Either.rights $
299 (Account.Read.account <* P.eof)
300 () "" ("A: :C"::Text)])
304 (Data.Either.rights $
306 (Account.Read.account <* P.eof)
307 () "" ("A::C"::Text)])
311 (Data.Either.rights $
313 (Account.Read.account <* P.eof)
314 () "" ("A:B:(C)"::Text)])
320 , "Quantity" ~: TestList
330 , "Amount" ~: TestList
331 [ {- "from_List" ~: TestList
332 [ "from_List [$1, 1$] = $2" ~:
335 { Amount.amount_quantity = Decimal 0 1
336 , Amount.amount_style = Amount.Style.empty
337 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
339 , Amount.amount_unit = "$"
342 { Amount.amount_quantity = Decimal 0 1
343 , Amount.amount_style = Amount.Style.empty
344 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
346 , Amount.amount_unit = "$"
351 [ ("$", Amount.amount
352 { Amount.amount_quantity = Decimal 0 2
353 , Amount.amount_style = Amount.Style.empty
354 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
356 , Amount.amount_unit = "$"
360 ,-} "Read" ~: TestList
361 [ "amount" ~: TestList
363 (Data.Either.rights $
365 (Amount.Read.amount <* P.eof)
369 , "\"0\" = Right 0" ~:
370 (Data.Either.rights $
372 (Amount.Read.amount <* P.eof)
378 { Amount.amount_quantity = Decimal 0 0
382 , "\"00\" = Right 0" ~:
383 (Data.Either.rights $
385 (Amount.Read.amount <* P.eof)
391 { Amount.amount_quantity = Decimal 0 0
395 , "\"0.\" = Right 0." ~:
396 (Data.Either.rights $
398 (Amount.Read.amount <* P.eof)
403 { Amount.Style.fractioning = Just '.'
406 { Amount.amount_quantity = Decimal 0 0
410 , "\".0\" = Right 0.0" ~:
411 (Data.Either.rights $
413 (Amount.Read.amount <* P.eof)
418 { Amount.Style.fractioning = Just '.'
421 { Amount.amount_quantity = Decimal 1 0
425 , "\"0,\" = Right 0," ~:
426 (Data.Either.rights $
428 (Amount.Read.amount <* P.eof)
433 { Amount.Style.fractioning = Just ','
436 { Amount.amount_quantity = Decimal 0 0
440 , "\",0\" = Right 0,0" ~:
441 (Data.Either.rights $
443 (Amount.Read.amount <* P.eof)
448 { Amount.Style.fractioning = Just ','
451 { Amount.amount_quantity = Decimal 1 0
456 (Data.Either.rights $
458 (Amount.Read.amount <* P.eof)
463 (Data.Either.rights $
465 (Amount.Read.amount <* P.eof)
469 , "\"0.0\" = Right 0.0" ~:
470 (Data.Either.rights $
472 (Amount.Read.amount <* P.eof)
473 () "" ("0.0"::Text)])
477 { Amount.Style.fractioning = Just '.'
480 { Amount.amount_quantity = Decimal 1 0
484 , "\"00.00\" = Right 0.00" ~:
485 (Data.Either.rights $
487 (Amount.Read.amount <* P.eof)
488 () "" ("00.00"::Text)])
492 { Amount.Style.fractioning = Just '.'
495 { Amount.amount_quantity = Decimal 2 0
499 , "\"0,0\" = Right 0,0" ~:
500 (Data.Either.rights $
502 (Amount.Read.amount <* P.eof)
503 () "" ("0,0"::Text)])
507 { Amount.Style.fractioning = Just ','
510 { Amount.amount_quantity = Decimal 1 0
514 , "\"00,00\" = Right 0,00" ~:
515 (Data.Either.rights $
517 (Amount.Read.amount <* P.eof)
518 () "" ("00,00"::Text)])
522 { Amount.Style.fractioning = Just ','
525 { Amount.amount_quantity = Decimal 2 0
529 , "\"0_0\" = Right 0" ~:
530 (Data.Either.rights $
532 (Amount.Read.amount <* P.eof)
533 () "" ("0_0"::Text)])
537 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
540 { Amount.amount_quantity = Decimal 0 0
544 , "\"00_00\" = Right 0" ~:
545 (Data.Either.rights $
547 (Amount.Read.amount <* P.eof)
548 () "" ("00_00"::Text)])
552 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
555 { Amount.amount_quantity = Decimal 0 0
559 , "\"0,000.00\" = Right 0,000.00" ~:
560 (Data.Either.rights $
562 (Amount.Read.amount <* P.eof)
563 () "" ("0,000.00"::Text)])
567 { Amount.Style.fractioning = Just '.'
568 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
571 { Amount.amount_quantity = Decimal 2 0
575 , "\"0.000,00\" = Right 0.000,00" ~:
576 (Data.Either.rights $
579 () "" ("0.000,00"::Text)])
583 { Amount.Style.fractioning = Just ','
584 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
587 { Amount.amount_quantity = Decimal 2 0
591 , "\"1,000.00\" = Right 1,000.00" ~:
592 (Data.Either.rights $
594 (Amount.Read.amount <* P.eof)
595 () "" ("1,000.00"::Text)])
599 { Amount.Style.fractioning = Just '.'
600 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
603 { Amount.amount_quantity = Decimal 2 100000
607 , "\"1.000,00\" = Right 1.000,00" ~:
608 (Data.Either.rights $
611 () "" ("1.000,00"::Text)])
615 { Amount.Style.fractioning = Just ','
616 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
619 { Amount.amount_quantity = Decimal 2 100000
623 , "\"1,000.00.\" = Left" ~:
624 (Data.Either.rights $
627 () "" ("1,000.00."::Text)])
630 , "\"1.000,00,\" = Left" ~:
631 (Data.Either.rights $
634 () "" ("1.000,00,"::Text)])
637 , "\"1,000.00_\" = Left" ~:
638 (Data.Either.rights $
641 () "" ("1,000.00_"::Text)])
644 , "\"12\" = Right 12" ~:
645 (Data.Either.rights $
647 (Amount.Read.amount <* P.eof)
648 () "" ("123"::Text)])
653 { Amount.amount_quantity = Decimal 0 123
657 , "\"1.2\" = Right 1.2" ~:
658 (Data.Either.rights $
660 (Amount.Read.amount <* P.eof)
661 () "" ("1.2"::Text)])
665 { Amount.Style.fractioning = Just '.'
668 { Amount.amount_quantity = Decimal 1 12
672 , "\"1,2\" = Right 1,2" ~:
673 (Data.Either.rights $
675 (Amount.Read.amount <* P.eof)
676 () "" ("1,2"::Text)])
680 { Amount.Style.fractioning = Just ','
683 { Amount.amount_quantity = Decimal 1 12
687 , "\"12.34\" = Right 12.34" ~:
688 (Data.Either.rights $
690 (Amount.Read.amount <* P.eof)
691 () "" ("12.34"::Text)])
695 { Amount.Style.fractioning = Just '.'
698 { Amount.amount_quantity = Decimal 2 1234
702 , "\"12,34\" = Right 12,34" ~:
703 (Data.Either.rights $
705 (Amount.Read.amount <* P.eof)
706 () "" ("12,34"::Text)])
710 { Amount.Style.fractioning = Just ','
713 { Amount.amount_quantity = Decimal 2 1234
717 , "\"1_2\" = Right 1_2" ~:
718 (Data.Either.rights $
720 (Amount.Read.amount <* P.eof)
721 () "" ("1_2"::Text)])
725 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
728 { Amount.amount_quantity = Decimal 0 12
732 , "\"1_23\" = Right 1_23" ~:
733 (Data.Either.rights $
735 (Amount.Read.amount <* P.eof)
736 () "" ("1_23"::Text)])
740 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
743 { Amount.amount_quantity = Decimal 0 123
747 , "\"1_23_456\" = Right 1_23_456" ~:
748 (Data.Either.rights $
750 (Amount.Read.amount <* P.eof)
751 () "" ("1_23_456"::Text)])
755 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
758 { Amount.amount_quantity = Decimal 0 123456
762 , "\"1_23_456.7890_12345_678901\" = Right 1_23_456.7890_12345_678901" ~:
763 (Data.Either.rights $
765 (Amount.Read.amount <* P.eof)
766 () "" ("1_23_456.7890_12345_678901"::Text)])
770 { Amount.Style.fractioning = Just '.'
771 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
772 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [4, 5, 6]
775 { Amount.amount_quantity = Decimal 15 123456789012345678901
779 , "\"123456_78901_2345.678_90_1\" = Right 123456_78901_2345.678_90_1" ~:
780 (Data.Either.rights $
782 (Amount.Read.amount <* P.eof)
783 () "" ("123456_78901_2345.678_90_1"::Text)])
787 { Amount.Style.fractioning = Just '.'
788 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [4, 5, 6]
789 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [3, 2]
792 { Amount.amount_quantity = Decimal 6 123456789012345678901
796 , "\"$1\" = Right $1" ~:
797 (Data.Either.rights $
799 (Amount.Read.amount <* P.eof)
804 { Amount.Style.unit_side = Just Amount.Style.Side_Left
805 , Amount.Style.unit_spaced = Just False
808 { Amount.amount_quantity = Decimal 0 1
809 , Amount.amount_unit = "$"
813 , "\"1$\" = Right 1$" ~:
814 (Data.Either.rights $
816 (Amount.Read.amount <* P.eof)
821 { Amount.Style.unit_side = Just Amount.Style.Side_Right
822 , Amount.Style.unit_spaced = Just False
825 { Amount.amount_quantity = Decimal 0 1
826 , Amount.amount_unit = "$"
830 , "\"$ 1\" = Right $ 1" ~:
831 (Data.Either.rights $
833 (Amount.Read.amount <* P.eof)
834 () "" ("$ 1"::Text)])
838 { Amount.Style.unit_side = Just Amount.Style.Side_Left
839 , Amount.Style.unit_spaced = Just True
842 { Amount.amount_quantity = Decimal 0 1
843 , Amount.amount_unit = "$"
847 , "\"1 $\" = Right 1 $" ~:
848 (Data.Either.rights $
850 (Amount.Read.amount <* P.eof)
851 () "" ("1 $"::Text)])
855 { Amount.Style.unit_side = Just Amount.Style.Side_Right
856 , Amount.Style.unit_spaced = Just True
859 { Amount.amount_quantity = Decimal 0 1
860 , Amount.amount_unit = "$"
864 , "\"-$1\" = Right $-1" ~:
865 (Data.Either.rights $
867 (Amount.Read.amount <* P.eof)
868 () "" ("-$1"::Text)])
872 { Amount.Style.unit_side = Just Amount.Style.Side_Left
873 , Amount.Style.unit_spaced = Just False
876 { Amount.amount_quantity = Decimal 0 (-1)
877 , Amount.amount_unit = "$"
881 , "\"\\\"4 2\\\"1\" = Right \\\"4 2\\\"1" ~:
882 (Data.Either.rights $
884 (Amount.Read.amount <* P.eof)
885 () "" ("\"4 2\"1"::Text)])
889 { Amount.Style.unit_side = Just Amount.Style.Side_Left
890 , Amount.Style.unit_spaced = Just False
893 { Amount.amount_quantity = Decimal 0 1
894 , Amount.amount_unit = "4 2"
898 , "\"1\\\"4 2\\\"\" = Right 1\\\"4 2\\\"" ~:
899 (Data.Either.rights $
901 (Amount.Read.amount <* P.eof)
902 () "" ("1\"4 2\""::Text)])
906 { Amount.Style.unit_side = Just Amount.Style.Side_Right
907 , Amount.Style.unit_spaced = Just False
910 { Amount.amount_quantity = Decimal 0 1
911 , Amount.amount_unit = "4 2"
915 , "\"$1.000,00\" = Right $1.000,00" ~:
916 (Data.Either.rights $
918 (Amount.Read.amount <* P.eof)
919 () "" ("$1.000,00"::Text)])
923 { Amount.Style.fractioning = Just ','
924 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
925 , Amount.Style.unit_side = Just Amount.Style.Side_Left
926 , Amount.Style.unit_spaced = Just False
929 { Amount.amount_quantity = Decimal 2 100000
930 , Amount.amount_unit = "$"
934 , "\"1.000,00$\" = Right 1.000,00$" ~:
935 (Data.Either.rights $
937 (Amount.Read.amount <* P.eof)
938 () "" ("1.000,00$"::Text)])
942 { Amount.Style.fractioning = Just ','
943 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
944 , Amount.Style.unit_side = Just Amount.Style.Side_Right
945 , Amount.Style.unit_spaced = Just False
948 { Amount.amount_quantity = Decimal 2 100000
949 , Amount.amount_unit = "$"
955 , "Write" ~: TestList
956 [ "amount" ~: TestList
960 { Ledger.Write.style_color=False
961 , Ledger.Write.style_align=True
963 Amount.Write.amount $
964 (Amount.Style.empty,)
971 { Ledger.Write.style_color=False
972 , Ledger.Write.style_align=True
974 Amount.Write.amount $
975 (Amount.Style.empty,)
977 { Amount.amount_quantity = Decimal 2 0
984 { Ledger.Write.style_color=False
985 , Ledger.Write.style_align=True
987 Amount.Write.amount $
988 (Amount.Style.empty,)
990 { Amount.amount_quantity = Decimal 0 123
997 { Ledger.Write.style_color=False
998 , Ledger.Write.style_align=True
1000 Amount.Write.amount $
1001 (Amount.Style.empty,)
1003 { Amount.amount_quantity = Decimal 0 (- 123)
1010 { Ledger.Write.style_color=False
1011 , Ledger.Write.style_align=True
1013 Amount.Write.amount $
1015 { Amount.Style.fractioning = Just '.'
1018 { Amount.amount_quantity = Decimal 1 123
1025 { Ledger.Write.style_color=False
1026 , Ledger.Write.style_align=True
1028 Amount.Write.amount $
1030 { Amount.Style.fractioning = Just '.'
1033 { Amount.amount_quantity = Decimal 1 125
1040 { Ledger.Write.style_color=False
1041 , Ledger.Write.style_align=True
1043 Amount.Write.amount $
1045 { Amount.Style.fractioning = Just '.'
1048 { Amount.amount_quantity = Decimal 1 123
1055 { Ledger.Write.style_color=False
1056 , Ledger.Write.style_align=True
1058 Amount.Write.amount $
1060 { Amount.Style.fractioning = Just '.'
1061 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
1064 { Amount.amount_quantity = Decimal 2 123456
1068 , "123,456,789,01,2.3456789" ~:
1071 { Ledger.Write.style_color=False
1072 , Ledger.Write.style_align=True
1074 Amount.Write.amount $
1076 { Amount.Style.fractioning = Just '.'
1077 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1080 { Amount.amount_quantity = Decimal 7 1234567890123456789
1083 "123,456,789,01,2.3456789")
1084 , "1234567.8,90,123,456,789" ~:
1087 { Ledger.Write.style_color=False
1088 , Ledger.Write.style_align=True
1090 Amount.Write.amount $
1092 { Amount.Style.fractioning = Just '.'
1093 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1096 { Amount.amount_quantity = Decimal 12 1234567890123456789
1099 "1234567.8,90,123,456,789")
1100 , "1,2,3,4,5,6,7,89,012.3456789" ~:
1103 { Ledger.Write.style_color=False
1104 , Ledger.Write.style_align=True
1106 Amount.Write.amount $
1108 { Amount.Style.fractioning = Just '.'
1109 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1112 { Amount.amount_quantity = Decimal 7 1234567890123456789
1115 "1,2,3,4,5,6,7,89,012.3456789")
1116 , "1234567.890,12,3,4,5,6,7,8,9" ~:
1119 { Ledger.Write.style_color=False
1120 , Ledger.Write.style_align=True
1122 Amount.Write.amount $
1124 { Amount.Style.fractioning = Just '.'
1125 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1128 { Amount.amount_quantity = Decimal 12 1234567890123456789
1131 "1234567.890,12,3,4,5,6,7,8,9")
1133 , "amount_length" ~: TestList
1135 ((Amount.Write.amount_length $
1136 (Amount.Style.empty,)
1141 ((Amount.Write.amount_length $
1142 (Amount.Style.empty,)
1144 { Amount.amount_quantity = Decimal 2 0
1149 ((Amount.Write.amount_length $
1150 (Amount.Style.empty,)
1152 { Amount.amount_quantity = Decimal 0 123
1157 ((Amount.Write.amount_length $
1158 (Amount.Style.empty,)
1160 { Amount.amount_quantity = Decimal 0 (- 123)
1165 ((Amount.Write.amount_length $
1167 { Amount.Style.fractioning = Just '.'
1170 { Amount.amount_quantity = Decimal 1 123
1175 ((Amount.Write.amount_length $
1177 { Amount.Style.fractioning = Just '.'
1180 { Amount.amount_quantity = Decimal 1 125
1185 ((Amount.Write.amount_length $
1187 { Amount.Style.fractioning = Just '.'
1190 { Amount.amount_quantity = Decimal 1 123
1195 ((Amount.Write.amount_length $
1197 { Amount.Style.fractioning = Just '.'
1198 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
1201 { Amount.amount_quantity = Decimal 2 123456
1205 , "123,456,789,01,2.3456789" ~:
1206 ((Amount.Write.amount_length $
1208 { Amount.Style.fractioning = Just '.'
1209 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1212 { Amount.amount_quantity = Decimal 7 1234567890123456789
1216 , "1234567.8,90,123,456,789" ~:
1217 ((Amount.Write.amount_length $
1219 { Amount.Style.fractioning = Just '.'
1220 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1223 { Amount.amount_quantity = Decimal 12 1234567890123456789
1227 , "1,2,3,4,5,6,7,89,012.3456789" ~:
1228 ((Amount.Write.amount_length $
1230 { Amount.Style.fractioning = Just '.'
1231 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1234 { Amount.amount_quantity = Decimal 7 1234567890123456789
1238 , "1234567.890,12,3,4,5,6,7,8,9" ~:
1239 ((Amount.Write.amount_length $
1241 { Amount.Style.fractioning = Just '.'
1242 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1245 { Amount.amount_quantity = Decimal 12 1234567890123456789
1249 , "1000000.000,00,0,0,0,0,0,0,0" ~:
1250 ((Amount.Write.amount_length $
1252 { Amount.Style.fractioning = Just '.'
1253 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1256 { Amount.amount_quantity = Decimal 12 1000000000000000000
1261 ((Amount.Write.amount_length $
1262 (Amount.Style.empty,)
1264 { Amount.amount_quantity = Decimal 0 999
1269 ((Amount.Write.amount_length $
1270 (Amount.Style.empty,)
1272 { Amount.amount_quantity = Decimal 0 1000
1277 ((Amount.Write.amount_length $
1278 (Amount.Style.empty,)
1280 { Amount.amount_quantity = Decimal 2 1000
1281 , Amount.amount_unit = "€"
1288 , "Date" ~: TestList
1289 [ "Read" ~: TestList
1290 [ "date" ~: TestList
1292 (Data.Either.rights $
1293 [P.runParser_with_Error
1294 (Date.Read.date id Nothing <* P.eof)
1295 () "" ("2000/01/01"::Text)])
1297 [ Time.zonedTimeToUTC $
1300 (Time.fromGregorian 2000 01 01)
1301 (Time.TimeOfDay 0 0 0))
1303 , "2000/01/01 some text" ~:
1304 (Data.Either.rights $
1305 [P.runParser_with_Error
1306 (Date.Read.date id Nothing)
1307 () "" ("2000/01/01 some text"::Text)])
1309 [ Time.zonedTimeToUTC $
1312 (Time.fromGregorian 2000 01 01)
1313 (Time.TimeOfDay 0 0 0))
1315 , "2000/01/01_12:34" ~:
1316 (Data.Either.rights $
1317 [P.runParser_with_Error
1318 (Date.Read.date id Nothing <* P.eof)
1319 () "" ("2000/01/01_12:34"::Text)])
1321 [ Time.zonedTimeToUTC $
1324 (Time.fromGregorian 2000 01 01)
1325 (Time.TimeOfDay 12 34 0))
1327 , "2000/01/01_12:34:56" ~:
1328 (Data.Either.rights $
1329 [P.runParser_with_Error
1330 (Date.Read.date id Nothing <* P.eof)
1331 () "" ("2000/01/01_12:34:56"::Text)])
1333 [ Time.zonedTimeToUTC $
1336 (Time.fromGregorian 2000 01 01)
1337 (Time.TimeOfDay 12 34 56))
1339 , "2000/01/01_12:34CET" ~:
1340 (Data.Either.rights $
1341 [P.runParser_with_Error
1342 (Date.Read.date id Nothing <* P.eof)
1343 () "" ("2000/01/01_12:34CET"::Text)])
1345 [ Time.zonedTimeToUTC $
1348 (Time.fromGregorian 2000 01 01)
1349 (Time.TimeOfDay 12 34 0))
1350 (Time.TimeZone 60 True "CET")]
1351 , "2000/01/01_12:34+0130" ~:
1352 (Data.Either.rights $
1353 [P.runParser_with_Error
1354 (Date.Read.date id Nothing <* P.eof)
1355 () "" ("2000/01/01_12:34+0130"::Text)])
1357 [ Time.zonedTimeToUTC $
1360 (Time.fromGregorian 2000 01 01)
1361 (Time.TimeOfDay 12 34 0))
1362 (Time.TimeZone 90 False "+0130")]
1363 , "2000/01/01_12:34:56CET" ~:
1364 (Data.Either.rights $
1365 [P.runParser_with_Error
1366 (Date.Read.date id Nothing <* P.eof)
1367 () "" ("2000/01/01_12:34:56CET"::Text)])
1369 [ Time.zonedTimeToUTC $
1372 (Time.fromGregorian 2000 01 01)
1373 (Time.TimeOfDay 12 34 56))
1374 (Time.TimeZone 60 True "CET")]
1376 (Data.Either.rights $
1377 [P.runParser_with_Error
1378 (Date.Read.date id Nothing <* P.eof)
1379 () "" ("2001/02/29"::Text)])
1383 (Data.Either.rights $
1384 [P.runParser_with_Error
1385 (Date.Read.date id (Just 2000) <* P.eof)
1386 () "" ("01/01"::Text)])
1388 [ Time.zonedTimeToUTC $
1391 (Time.fromGregorian 2000 01 01)
1392 (Time.TimeOfDay 0 0 0))
1396 , "Write" ~: TestList
1397 [ "date" ~: TestList
1401 { Ledger.Write.style_color=False
1402 , Ledger.Write.style_align=True
1408 , "2000/01/01_12:34:51CET" ~:
1411 { Ledger.Write.style_color=False
1412 , Ledger.Write.style_align=True
1415 Time.zonedTimeToUTC $
1418 (Time.fromGregorian 2000 01 01)
1419 (Time.TimeOfDay 12 34 51))
1420 (Time.TimeZone 60 False "CET"))
1422 "2000/01/01_11:34:51"
1423 , "2000/01/01_12:34:51+0100" ~:
1426 { Ledger.Write.style_color=False
1427 , Ledger.Write.style_align=True
1430 Time.zonedTimeToUTC $
1433 (Time.fromGregorian 2000 01 01)
1434 (Time.TimeOfDay 12 34 51))
1435 (Time.TimeZone 60 False ""))
1437 "2000/01/01_11:34:51"
1438 , "2000/01/01_01:02:03" ~:
1441 { Ledger.Write.style_color=False
1442 , Ledger.Write.style_align=True
1445 Time.zonedTimeToUTC $
1448 (Time.fromGregorian 2000 01 01)
1449 (Time.TimeOfDay 1 2 3))
1452 "2000/01/01_01:02:03"
1456 { Ledger.Write.style_color=False
1457 , Ledger.Write.style_align=True
1460 Time.zonedTimeToUTC $
1463 (Time.fromGregorian 0 01 01)
1464 (Time.TimeOfDay 1 2 0))
1471 { Ledger.Write.style_color=False
1472 , Ledger.Write.style_align=True
1475 Time.zonedTimeToUTC $
1478 (Time.fromGregorian 0 01 01)
1479 (Time.TimeOfDay 1 0 0))
1486 { Ledger.Write.style_color=False
1487 , Ledger.Write.style_align=True
1490 Time.zonedTimeToUTC $
1493 (Time.fromGregorian 0 01 01)
1494 (Time.TimeOfDay 0 1 0))
1501 { Ledger.Write.style_color=False
1502 , Ledger.Write.style_align=True
1505 Time.zonedTimeToUTC $
1508 (Time.fromGregorian 0 01 01)
1509 (Time.TimeOfDay 0 0 0))
1516 , "Read" ~: TestList
1517 [ "posting_type" ~: TestList
1519 Ledger.Read.posting_type
1522 Ledger.Posting_Typed
1523 (Ledger.Posting_Type_Regular, "A":|[])
1525 Ledger.Read.posting_type
1528 Ledger.Posting_Typed
1529 (Ledger.Posting_Type_Regular, "(":|[])
1531 Ledger.Read.posting_type
1534 Ledger.Posting_Typed
1535 (Ledger.Posting_Type_Regular, ")":|[])
1537 Ledger.Read.posting_type
1540 Ledger.Posting_Typed
1541 (Ledger.Posting_Type_Regular, "()":|[])
1543 Ledger.Read.posting_type
1546 Ledger.Posting_Typed
1547 (Ledger.Posting_Type_Regular, "( )":|[])
1549 Ledger.Read.posting_type
1552 Ledger.Posting_Typed
1553 (Ledger.Posting_Type_Virtual, "A":|[])
1555 Ledger.Read.posting_type
1558 Ledger.Posting_Typed
1559 (Ledger.Posting_Type_Virtual, "A":|["B", "C"])
1561 Ledger.Read.posting_type
1564 Ledger.Posting_Typed
1565 (Ledger.Posting_Type_Regular, "A":|["B", "C"])
1567 Ledger.Read.posting_type
1570 Ledger.Posting_Typed
1571 (Ledger.Posting_Type_Regular, "(A)":|["B", "C"])
1573 Ledger.Read.posting_type
1576 Ledger.Posting_Typed
1577 (Ledger.Posting_Type_Regular, "A":|["(B)", "C"])
1579 Ledger.Read.posting_type
1582 Ledger.Posting_Typed
1583 (Ledger.Posting_Type_Regular, "A":|["B", "(C)"])
1585 Ledger.Read.posting_type
1588 Ledger.Posting_Typed
1589 (Ledger.Posting_Type_Regular, "[":|[])
1591 Ledger.Read.posting_type
1594 Ledger.Posting_Typed
1595 (Ledger.Posting_Type_Regular, "]":|[])
1597 Ledger.Read.posting_type
1600 Ledger.Posting_Typed
1601 (Ledger.Posting_Type_Regular, "[]":|[])
1603 Ledger.Read.posting_type
1606 Ledger.Posting_Typed
1607 (Ledger.Posting_Type_Regular, "[ ]":|[])
1609 Ledger.Read.posting_type
1612 Ledger.Posting_Typed
1613 (Ledger.Posting_Type_Virtual_Balanced, "A":|[])
1615 Ledger.Read.posting_type
1618 Ledger.Posting_Typed
1619 (Ledger.Posting_Type_Virtual_Balanced, "A":|["B", "C"])
1621 Ledger.Read.posting_type
1624 Ledger.Posting_Typed
1625 (Ledger.Posting_Type_Regular, "A":|["B", "C"])
1627 Ledger.Read.posting_type
1630 Ledger.Posting_Typed
1631 (Ledger.Posting_Type_Regular, "[A]":|["B", "C"])
1633 Ledger.Read.posting_type
1636 Ledger.Posting_Typed
1637 (Ledger.Posting_Type_Regular, "A":|["[B]", "C"])
1639 Ledger.Read.posting_type
1642 Ledger.Posting_Typed
1643 (Ledger.Posting_Type_Regular, "A":|["B", "[C]"])
1645 , "comment" ~: TestList
1646 [ "; some comment = Right \" some comment\"" ~:
1647 (Data.Either.rights $
1649 (Ledger.Read.comment <* P.eof)
1650 () "" ("; some comment"::Text)])
1653 , "; some comment \\n = Right \" some comment \"" ~:
1654 (Data.Either.rights $
1656 (Ledger.Read.comment <* P.newline <* P.eof)
1657 () "" ("; some comment \n"::Text)])
1659 [ " some comment " ]
1660 , "; some comment \\r\\n = Right \" some comment \"" ~:
1661 (Data.Either.rights $
1663 (Ledger.Read.comment <* P.string "\r\n" <* P.eof)
1664 () "" ("; some comment \r\n"::Text)])
1666 [ " some comment " ]
1668 , "comments" ~: TestList
1669 [ "; some comment\\n ; some other comment = Right [\" some comment\", \" some other comment\"]" ~:
1670 (Data.Either.rights $
1672 (Ledger.Read.comments <* P.eof)
1673 () "" ("; some comment\n ; some other comment"::Text)])
1675 [ [" some comment", " some other comment"] ]
1676 , "; some comment \\n = Right \" some comment \"" ~:
1677 (Data.Either.rights $
1679 (Ledger.Read.comments <* P.string "\n" <* P.eof)
1680 () "" ("; some comment \n"::Text)])
1682 [ [" some comment "] ]
1684 , "tag_value" ~: TestList
1686 (Data.Either.rights $
1688 (Ledger.Read.tag_value <* P.eof)
1693 (Data.Either.rights $
1695 (Ledger.Read.tag_value <* P.char '\n' <* P.eof)
1696 () "" (",\n"::Text)])
1700 (Data.Either.rights $
1702 (Ledger.Read.tag_value <* P.eof)
1703 () "" (",x"::Text)])
1707 (Data.Either.rights $
1709 (Ledger.Read.tag_value <* P.string ",x:" <* P.eof)
1710 () "" (",x:"::Text)])
1714 (Data.Either.rights $
1716 (Ledger.Read.tag_value <* P.string ", n:" <* P.eof)
1717 () "" ("v, v, n:"::Text)])
1723 (Data.Either.rights $
1725 (Ledger.Read.tag <* P.eof)
1726 () "" ("Name:"::Text)])
1730 (Data.Either.rights $
1732 (Ledger.Read.tag <* P.eof)
1733 () "" ("Name:Value"::Text)])
1735 [("Name":|[], "Value")]
1736 , "Name:Value\\n" ~:
1737 (Data.Either.rights $
1739 (Ledger.Read.tag <* P.string "\n" <* P.eof)
1740 () "" ("Name:Value\n"::Text)])
1742 [("Name":|[], "Value")]
1744 (Data.Either.rights $
1746 (Ledger.Read.tag <* P.eof)
1747 () "" ("Name:Val ue"::Text)])
1749 [("Name":|[], "Val ue")]
1751 (Data.Either.rights $
1753 (Ledger.Read.tag <* P.eof)
1754 () "" ("Name:,"::Text)])
1758 (Data.Either.rights $
1760 (Ledger.Read.tag <* P.eof)
1761 () "" ("Name:Val,ue"::Text)])
1763 [("Name":|[], "Val,ue")]
1765 (Data.Either.rights $
1767 (Ledger.Read.tag <* P.string ",ue:" <* P.eof)
1768 () "" ("Name:Val,ue:"::Text)])
1770 [("Name":|[], "Val")]
1771 , "Name:Val,ue :" ~:
1772 (Data.Either.rights $
1774 (Ledger.Read.tag <* P.eof)
1775 () "" ("Name:Val,ue :"::Text)])
1777 [("Name":|[], "Val,ue :")]
1779 , "tags" ~: TestList
1781 (Data.Either.rights $
1783 (Ledger.Read.tags <* P.eof)
1784 () "" ("Name:"::Text)])
1787 [ ("Name":|[], [""])
1791 (Data.Either.rights $
1793 (Ledger.Read.tags <* P.eof)
1794 () "" ("Name:,"::Text)])
1797 [ ("Name":|[], [","])
1801 (Data.Either.rights $
1803 (Ledger.Read.tags <* P.eof)
1804 () "" ("Name:,Name:"::Text)])
1807 [ ("Name":|[], ["", ""])
1811 (Data.Either.rights $
1813 (Ledger.Read.tags <* P.eof)
1814 () "" ("Name:,Name2:"::Text)])
1817 [ ("Name":|[], [""])
1818 , ("Name2":|[], [""])
1821 , "Name: , Name2:" ~:
1822 (Data.Either.rights $
1824 (Ledger.Read.tags <* P.eof)
1825 () "" ("Name: , Name2:"::Text)])
1828 [ ("Name":|[], [" "])
1829 , ("Name2":|[], [""])
1832 , "Name:,Name2:,Name3:" ~:
1833 (Data.Either.rights $
1835 (Ledger.Read.tags <* P.eof)
1836 () "" ("Name:,Name2:,Name3:"::Text)])
1839 [ ("Name":|[], [""])
1840 , ("Name2":|[], [""])
1841 , ("Name3":|[], [""])
1844 , "Name:Val ue,Name2:V a l u e,Name3:V al ue" ~:
1845 (Data.Either.rights $
1847 (Ledger.Read.tags <* P.eof)
1848 () "" ("Name:Val ue,Name2:V a l u e,Name3:V al ue"::Text)])
1851 [ ("Name":|[], ["Val ue"])
1852 , ("Name2":|[], ["V a l u e"])
1853 , ("Name3":|[], ["V al ue"])
1857 , "posting" ~: TestList
1858 [ " A:B:C = Right A:B:C" ~:
1859 (Data.Either.rights $
1860 [P.runParser_with_Error
1861 (Ledger.Read.posting <* P.eof)
1862 ( Ledger.Read.context () Ledger.journal
1863 ::Ledger.Read.Context () [] Ledger.Transaction)
1864 "" (" A:B:C"::Text)])
1866 [ Ledger.Posting_Typed
1867 ( Ledger.Posting_Type_Regular
1868 , (Ledger.posting ("A":|["B", "C"]))
1869 { Ledger.posting_sourcepos = P.newPos "" 1 1
1873 , " !A:B:C = Right !A:B:C" ~:
1874 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
1875 Data.Either.rights $
1876 [P.runParser_with_Error
1877 (Ledger.Read.posting <* P.eof)
1878 ( Ledger.Read.context () Ledger.journal
1879 ::Ledger.Read.Context () [] Ledger.Transaction)
1880 "" (" !A:B:C"::Text)])
1882 [ (Ledger.posting ("A":|["B", "C"]))
1883 { Ledger.posting_sourcepos = P.newPos "" 1 1
1884 , Ledger.posting_status = True
1887 , " *A:B:C = Right *A:B:C" ~:
1888 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
1889 Data.Either.rights $
1890 [P.runParser_with_Error
1891 (Ledger.Read.posting <* P.eof)
1892 ( Ledger.Read.context () Ledger.journal
1893 ::Ledger.Read.Context () [] Ledger.Transaction)
1894 "" (" *A:B:C"::Text)])
1896 [ (Ledger.posting ("A":|["B", "C"]))
1897 { Ledger.posting_amounts = Data.Map.fromList []
1898 , Ledger.posting_comments = []
1899 , Ledger.posting_dates = []
1900 , Ledger.posting_status = True
1901 , Ledger.posting_sourcepos = P.newPos "" 1 1
1902 , Ledger.posting_tags = mempty
1905 , " A:B:C $1 = Right A:B:C $1" ~:
1906 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
1907 Data.Either.rights $
1908 [P.runParser_with_Error
1909 (Ledger.Read.posting <* P.eof)
1910 ( Ledger.Read.context () Ledger.journal
1911 ::Ledger.Read.Context () [] Ledger.Transaction)
1912 "" (" A:B:C $1"::Text)])
1914 [ (Ledger.posting ("A":|["B","C $1"]))
1915 { Ledger.posting_sourcepos = P.newPos "" 1 1
1918 , " A:B:C $1 = Right A:B:C $1" ~:
1919 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
1920 Data.Either.rights $
1921 [P.runParser_with_Error
1922 (Ledger.Read.posting <* P.eof)
1923 ( Ledger.Read.context () Ledger.journal
1924 ::Ledger.Read.Context () [] Ledger.Transaction)
1925 "" (" A:B:C $1"::Text)])
1927 [ (Ledger.posting ("A":|["B", "C"]))
1928 { Ledger.posting_amounts = Data.Map.fromList
1931 , Ledger.posting_sourcepos = P.newPos "" 1 1
1934 , " A:B:C $1 + 1€ = Right A:B:C $1 + 1€" ~:
1935 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
1936 Data.Either.rights $
1937 [P.runParser_with_Error
1938 (Ledger.Read.posting <* P.eof)
1939 ( Ledger.Read.context () Ledger.journal
1940 ::Ledger.Read.Context () [] Ledger.Transaction)
1941 "" (" A:B:C $1 + 1€"::Text)])
1943 [ (Ledger.posting ("A":|["B", "C"]))
1944 { Ledger.posting_amounts = Data.Map.fromList
1948 , Ledger.posting_sourcepos = P.newPos "" 1 1
1951 , " A:B:C $1 + 1$ = Right A:B:C $2" ~:
1952 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
1953 Data.Either.rights $
1954 [P.runParser_with_Error
1955 (Ledger.Read.posting <* P.eof)
1956 ( Ledger.Read.context () Ledger.journal
1957 ::Ledger.Read.Context () [] Ledger.Transaction)
1958 "" (" A:B:C $1 + 1$"::Text)])
1960 [ (Ledger.posting ("A":|["B", "C"]))
1961 { Ledger.posting_amounts = Data.Map.fromList
1964 , Ledger.posting_sourcepos = P.newPos "" 1 1
1967 , " A:B:C $1 + 1$ + 1$ = Right A:B:C $3" ~:
1968 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
1969 Data.Either.rights $
1970 [P.runParser_with_Error
1971 (Ledger.Read.posting <* P.eof)
1972 ( Ledger.Read.context () Ledger.journal
1973 ::Ledger.Read.Context () [] Ledger.Transaction)
1974 "" (" A:B:C $1 + 1$ + 1$"::Text)])
1976 [ (Ledger.posting ("A":|["B", "C"]))
1977 { Ledger.posting_amounts = Data.Map.fromList
1980 , Ledger.posting_sourcepos = P.newPos "" 1 1
1983 , " A:B:C ; some comment = Right A:B:C ; some comment" ~:
1984 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
1985 Data.Either.rights $
1986 [P.runParser_with_Error
1987 (Ledger.Read.posting <* P.eof)
1988 ( Ledger.Read.context () Ledger.journal
1989 ::Ledger.Read.Context () [] Ledger.Transaction)
1990 "" (" A:B:C ; some comment"::Text)])
1992 [ (Ledger.posting ("A":|["B", "C"]))
1993 { Ledger.posting_amounts = Data.Map.fromList []
1994 , Ledger.posting_comments = [" some comment"]
1995 , Ledger.posting_sourcepos = P.newPos "" 1 1
1998 , " A:B:C ; some comment\\n ; some other comment = Right A:B:C ; some comment\\n ; some other comment" ~:
1999 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
2000 Data.Either.rights $
2001 [P.runParser_with_Error
2002 (Ledger.Read.posting <* P.eof)
2003 ( Ledger.Read.context () Ledger.journal
2004 ::Ledger.Read.Context () [] Ledger.Transaction)
2005 "" (" A:B:C ; some comment\n ; some other comment"::Text)])
2007 [ (Ledger.posting ("A":|["B", "C"]))
2008 { Ledger.posting_amounts = Data.Map.fromList []
2009 , Ledger.posting_comments = [" some comment", " some other comment"]
2010 , Ledger.posting_sourcepos = P.newPos "" 1 1
2013 , " A:B:C $1 ; some comment = Right A:B:C $1 ; some comment" ~:
2014 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
2015 Data.Either.rights $
2016 [P.runParser_with_Error
2017 (Ledger.Read.posting)
2018 ( Ledger.Read.context () Ledger.journal
2019 ::Ledger.Read.Context () [] Ledger.Transaction)
2020 "" (" A:B:C $1 ; some comment"::Text)])
2022 [ (Ledger.posting ("A":|["B", "C"]))
2023 { Ledger.posting_amounts = Data.Map.fromList
2026 , Ledger.posting_comments = [" some comment"]
2027 , Ledger.posting_sourcepos = P.newPos "" 1 1
2030 , " A:B:C ; N:V = Right A:B:C ; N:V" ~:
2031 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
2032 Data.Either.rights $
2033 [P.runParser_with_Error
2034 (Ledger.Read.posting <* P.eof)
2035 ( Ledger.Read.context () Ledger.journal
2036 ::Ledger.Read.Context () [] Ledger.Transaction)
2037 "" (" A:B:C ; N:V"::Text)])
2039 [ (Ledger.posting ("A":|["B", "C"]))
2040 { Ledger.posting_comments = [" N:V"]
2041 , Ledger.posting_sourcepos = P.newPos "" 1 1
2042 , Ledger.posting_tags = Tag.from_List
2047 , " A:B:C ; some comment N:V = Right A:B:C ; some comment N:V" ~:
2048 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
2049 Data.Either.rights $
2050 [P.runParser_with_Error
2051 (Ledger.Read.posting <* P.eof)
2052 ( Ledger.Read.context () Ledger.journal
2053 ::Ledger.Read.Context () [] Ledger.Transaction)
2054 "" (" A:B:C ; some comment N:V"::Text)])
2056 [ (Ledger.posting ("A":|["B", "C"]))
2057 { Ledger.posting_comments = [" some comment N:V"]
2058 , Ledger.posting_sourcepos = P.newPos "" 1 1
2059 , Ledger.posting_tags = Tag.from_List
2064 , " A:B:C ; some comment N:V v, N2:V2 v2 = Right A:B:C ; some comment N:V v, N2:V2 v2" ~:
2065 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
2066 Data.Either.rights $
2067 [P.runParser_with_Error
2068 (Ledger.Read.posting )
2069 ( Ledger.Read.context () Ledger.journal
2070 ::Ledger.Read.Context () [] Ledger.Transaction)
2071 "" (" A:B:C ; some comment N:V v, N2:V2 v2"::Text)])
2073 [ (Ledger.posting ("A":|["B", "C"]))
2074 { Ledger.posting_comments = [" some comment N:V v, N2:V2 v2"]
2075 , Ledger.posting_sourcepos = P.newPos "" 1 1
2076 , Ledger.posting_tags = Tag.from_List
2078 , ("N2":|[], "V2 v2")
2082 , " A:B:C ; N:V\\n ; N:V2 = Right A:B:C ; N:V\\n ; N:V2" ~:
2083 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
2084 Data.Either.rights $
2085 [P.runParser_with_Error
2086 (Ledger.Read.posting <* P.eof)
2087 ( Ledger.Read.context () Ledger.journal
2088 ::Ledger.Read.Context () [] Ledger.Transaction)
2089 "" (" A:B:C ; N:V\n ; N:V2"::Text)])
2091 [ (Ledger.posting ("A":|["B", "C"]))
2092 { Ledger.posting_comments = [" N:V", " N:V2"]
2093 , Ledger.posting_sourcepos = P.newPos "" 1 1
2094 , Ledger.posting_tags = Tag.from_List
2100 , " A:B:C ; N:V\\n ; N2:V = Right A:B:C ; N:V\\n ; N2:V" ~:
2101 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
2102 Data.Either.rights $
2103 [P.runParser_with_Error
2104 (Ledger.Read.posting <* P.eof)
2105 ( Ledger.Read.context () Ledger.journal
2106 ::Ledger.Read.Context () [] Ledger.Transaction)
2107 "" (" A:B:C ; N:V\n ; N2:V"::Text)])
2109 [ (Ledger.posting ("A":|["B", "C"]))
2110 { Ledger.posting_comments = [" N:V", " N2:V"]
2111 , Ledger.posting_sourcepos = P.newPos "" 1 1
2112 , Ledger.posting_tags = Tag.from_List
2118 , " A:B:C ; date:2001/01/01 = Right A:B:C ; date:2001/01/01" ~:
2119 (Data.List.map (\(Ledger.Posting_Typed (_pt, p)) -> p) $
2120 Data.Either.rights $
2121 [P.runParser_with_Error
2122 (Ledger.Read.posting <* P.eof)
2123 ( Ledger.Read.context () Ledger.journal
2124 ::Ledger.Read.Context () [] Ledger.Transaction)
2125 "" (" A:B:C ; date:2001/01/01"::Text)])
2127 [ (Ledger.posting ("A":|["B", "C"]))
2128 { Ledger.posting_comments = [" date:2001/01/01"]
2129 , Ledger.posting_dates =
2130 [ Time.zonedTimeToUTC $
2133 (Time.fromGregorian 2001 01 01)
2134 (Time.TimeOfDay 0 0 0))
2137 , Ledger.posting_sourcepos = P.newPos "" 1 1
2138 , Ledger.posting_tags = Tag.from_List
2139 [ ("date":|[], "2001/01/01")
2143 , " (A:B:C) = Right (A:B:C)" ~:
2144 (Data.Either.rights $
2145 [P.runParser_with_Error
2146 (Ledger.Read.posting <* P.eof)
2147 ( Ledger.Read.context () Ledger.journal
2148 ::Ledger.Read.Context () [] Ledger.Transaction)
2149 "" (" (A:B:C)"::Text)])
2151 [ Ledger.Posting_Typed
2152 ( Ledger.Posting_Type_Virtual
2153 , (Ledger.posting ("A":|["B", "C"]))
2154 { Ledger.posting_sourcepos = P.newPos "" 1 1
2158 , " [A:B:C] = Right [A:B:C]" ~:
2159 (Data.Either.rights $
2160 [P.runParser_with_Error
2161 (Ledger.Read.posting <* P.eof)
2162 ( Ledger.Read.context () Ledger.journal
2163 ::Ledger.Read.Context () [] Ledger.Transaction)
2164 "" (" [A:B:C]"::Text)])
2166 [ Ledger.Posting_Typed
2167 ( Ledger.Posting_Type_Virtual_Balanced
2168 , (Ledger.posting ("A":|["B", "C"]))
2169 { Ledger.posting_sourcepos = P.newPos "" 1 1
2174 , "transaction" ~: TestList
2175 [ "2000/01/01 some description\\n A:B:C $1\\n a:b:c" ~:
2176 (Data.Either.rights $
2177 [P.runParser_with_Error
2178 (Ledger.Read.transaction <* P.eof)
2179 ( Ledger.Read.context () Ledger.journal
2180 ::Ledger.Read.Context () [] Ledger.Transaction)
2181 "" ("2000/01/01 some description\n A:B:C $1\n a:b:c"::Text)])
2183 [ Ledger.transaction
2184 { Ledger.transaction_dates=
2185 ( Time.zonedTimeToUTC $
2188 (Time.fromGregorian 2000 01 01)
2189 (Time.TimeOfDay 0 0 0))
2192 , Ledger.transaction_description="some description"
2193 , Ledger.transaction_postings = Ledger.map_Postings_by_Account
2194 [ (Ledger.posting ("A":|["B", "C"]))
2195 { Ledger.posting_amounts = Data.Map.fromList
2198 , Ledger.posting_sourcepos = P.newPos "" 2 1
2200 , (Ledger.posting ("a":|["b", "c"]))
2201 { Ledger.posting_amounts = Data.Map.fromList
2204 , Ledger.posting_sourcepos = P.newPos "" 3 1
2207 , Ledger.transaction_sourcepos = P.newPos "" 1 1
2210 , "2000/01/01 some description\\n A:B:C $1\\n a:b:c\\n" ~:
2211 (Data.Either.rights $
2212 [P.runParser_with_Error
2213 (Ledger.Read.transaction <* P.newline <* P.eof)
2214 ( Ledger.Read.context () Ledger.journal
2215 ::Ledger.Read.Context () [] Ledger.Transaction)
2216 "" ("2000/01/01 some description\n A:B:C $1\n a:b:c\n"::Text)])
2218 [ Ledger.transaction
2219 { Ledger.transaction_dates=
2220 ( Time.zonedTimeToUTC $
2223 (Time.fromGregorian 2000 01 01)
2224 (Time.TimeOfDay 0 0 0))
2227 , Ledger.transaction_description="some description"
2228 , Ledger.transaction_postings = Ledger.map_Postings_by_Account
2229 [ (Ledger.posting ("A":|["B", "C"]))
2230 { Ledger.posting_amounts = Data.Map.fromList
2233 , Ledger.posting_sourcepos = P.newPos "" 2 1
2235 , (Ledger.posting ("a":|["b", "c"]))
2236 { Ledger.posting_amounts = Data.Map.fromList
2239 , Ledger.posting_sourcepos = P.newPos "" 3 1
2242 , Ledger.transaction_sourcepos = P.newPos "" 1 1
2245 , "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" ~:
2246 (Data.Either.rights $
2247 [P.runParser_with_Error
2248 (Ledger.Read.transaction <* P.eof)
2249 ( Ledger.Read.context () Ledger.journal
2250 ::Ledger.Read.Context () [] Ledger.Transaction)
2251 "" ("2000/01/01 some description ; some comment\n ; some other;comment\n ; some Tag:\n ; some last comment\n A:B:C $1\n a:b:c"::Text)])
2253 [ Ledger.transaction
2254 { Ledger.transaction_comments_after =
2256 , " some other;comment"
2258 , " some last comment"
2260 , Ledger.transaction_dates=
2261 ( Time.zonedTimeToUTC $
2264 (Time.fromGregorian 2000 01 01)
2265 (Time.TimeOfDay 0 0 0))
2268 , Ledger.transaction_description="some description"
2269 , Ledger.transaction_postings = Ledger.map_Postings_by_Account
2270 [ (Ledger.posting ("A":|["B", "C"]))
2271 { Ledger.posting_amounts = Data.Map.fromList
2274 , Ledger.posting_sourcepos = P.newPos "" 5 1
2276 , (Ledger.posting ("a":|["b", "c"]))
2277 { Ledger.posting_amounts = Data.Map.fromList
2280 , Ledger.posting_sourcepos = P.newPos "" 6 1
2283 , Ledger.transaction_tags = Tag.from_List
2286 , Ledger.transaction_sourcepos = P.newPos "" 1 1
2290 , "journal" ~: TestList
2291 [ "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
2293 P.runParserT_with_Error
2294 (Ledger.Read.journal "" {-<* P.eof-})
2295 ( Ledger.Read.context () Ledger.journal
2296 ::Ledger.Read.Context () [] Ledger.Transaction)
2297 "" ("2000/01/01 1° description\n A:B:C $1\n a:b:c\n2000/01/02 2° description\n A:B:C $1\n x:y:z"::Text)
2299 (\j -> j{Ledger.journal_last_read_time=Date.nil}) $
2300 Data.Either.rights [jnl])
2303 { Ledger.journal_sections =
2304 fmap (Ledger.Chart_With . (mempty,)) $
2305 [ Ledger.transaction
2306 { Ledger.transaction_dates=
2307 ( Time.zonedTimeToUTC $
2310 (Time.fromGregorian 2000 01 02)
2311 (Time.TimeOfDay 0 0 0))
2314 , Ledger.transaction_description="2° description"
2315 , Ledger.transaction_postings = Ledger.map_Postings_by_Account
2316 [ (Ledger.posting ("A":|["B", "C"]))
2317 { Ledger.posting_amounts = Data.Map.fromList
2320 , Ledger.posting_sourcepos = P.newPos "" 5 1
2322 , (Ledger.posting ("x":|["y", "z"]))
2323 { Ledger.posting_amounts = Data.Map.fromList
2326 , Ledger.posting_sourcepos = P.newPos "" 6 1
2329 , Ledger.transaction_sourcepos = P.newPos "" 4 1
2331 , Ledger.transaction
2332 { Ledger.transaction_dates=
2333 ( Time.zonedTimeToUTC $
2336 (Time.fromGregorian 2000 01 01)
2337 (Time.TimeOfDay 0 0 0))
2340 , Ledger.transaction_description="1° description"
2341 , Ledger.transaction_postings = Ledger.map_Postings_by_Account
2342 [ (Ledger.posting ("A":|["B", "C"]))
2343 { Ledger.posting_amounts = Data.Map.fromList
2346 , Ledger.posting_sourcepos = P.newPos "" 2 1
2348 , (Ledger.posting ("a":|["b", "c"]))
2349 { Ledger.posting_amounts = Data.Map.fromList
2352 , Ledger.posting_sourcepos = P.newPos "" 3 1
2355 , Ledger.transaction_sourcepos = P.newPos "" 1 1
2358 , Ledger.journal_amount_styles = Amount.Style.Styles $ Data.Map.fromList
2360 , Amount.Style.empty
2361 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2362 , Amount.Style.unit_spaced = Just False
2370 , "Write" ~: TestList
2371 [ "account" ~: TestList
2375 { Ledger.Write.style_color=False
2376 , Ledger.Write.style_align=True
2378 Ledger.Write.account Ledger.Posting_Type_Regular $
2385 { Ledger.Write.style_color=False
2386 , Ledger.Write.style_align=True
2388 Ledger.Write.account Ledger.Posting_Type_Regular $
2395 { Ledger.Write.style_color=False
2396 , Ledger.Write.style_align=True
2398 Ledger.Write.account Ledger.Posting_Type_Virtual $
2405 { Ledger.Write.style_color=False
2406 , Ledger.Write.style_align=True
2408 Ledger.Write.account Ledger.Posting_Type_Virtual_Balanced $
2413 , "transaction" ~: TestList
2417 { Ledger.Write.style_color=False
2418 , Ledger.Write.style_align=True
2420 Ledger.Write.transaction
2425 , "2000/01/01 some description\\n\\tA:B:C $1\\n\\ta:b:c\\n\\t ; first comment\\n\\t ; second comment\\n\\t ; third comment\\n" ~:
2428 { Ledger.Write.style_color=False
2429 , Ledger.Write.style_align=True
2431 Ledger.Write.transaction
2434 { Ledger.transaction_dates=
2435 ( Time.zonedTimeToUTC $
2438 (Time.fromGregorian 2000 01 01)
2439 (Time.TimeOfDay 0 0 0))
2442 , Ledger.transaction_description="some description"
2443 , Ledger.transaction_postings = Ledger.map_Postings_by_Account
2444 [ (Ledger.posting ("A":|["B", "C"]))
2445 { Ledger.posting_amounts = Data.Map.fromList
2449 , (Ledger.posting ("a":|["b", "c"]))
2450 { Ledger.posting_comments = ["first comment","second comment","third comment"]
2455 "2000/01/01 some description\n\tA:B:C $1\n\ta:b:c\n\t ; first comment\n\t ; second comment\n\t ; third comment\n")
2456 , "2000/01/01 some description\\n\\tA:B:C $1\\n\\tAA:BB:CC $123" ~:
2459 { Ledger.Write.style_color=False
2460 , Ledger.Write.style_align=True
2462 Ledger.Write.transaction
2465 { Ledger.transaction_dates=
2466 ( Time.zonedTimeToUTC $
2469 (Time.fromGregorian 2000 01 01)
2470 (Time.TimeOfDay 0 0 0))
2473 , Ledger.transaction_description="some description"
2474 , Ledger.transaction_postings = Ledger.map_Postings_by_Account
2475 [ (Ledger.posting ("A":|["B", "C"]))
2476 { Ledger.posting_amounts = Data.Map.fromList
2480 , (Ledger.posting ("AA":|["BB", "CC"]))
2481 { Ledger.posting_amounts = Data.Map.fromList
2488 "2000/01/01 some description\n\tA:B:C $1\n\tAA:BB:CC $123\n")