]> Git — Sourcephile - comptalang.git/blob - ledger/Test/Main.hs
Modification : sépare hcompta-ledger de hcompta-lib.
[comptalang.git] / ledger / Test / Main.hs
1 {-# LANGUAGE FlexibleInstances #-}
2 {-# LANGUAGE OverloadedStrings #-}
3 {-# LANGUAGE ScopedTypeVariables #-}
4 {-# LANGUAGE StandaloneDeriving #-}
5 {-# LANGUAGE TupleSections #-}
6
7 import Prelude
8 import Test.HUnit hiding ((~?))
9 import Test.Framework.Providers.HUnit (hUnitTestToTests)
10 import Test.Framework.Runners.Console (defaultMain)
11
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
25
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
39
40 deriving instance Eq Ledger.Amount
41
42 main :: IO ()
43 main = defaultMain $ hUnitTestToTests test_Hcompta
44
45 -- (~?) :: String -> Bool -> Test
46 -- (~?) s b = s ~: (b ~?= True)
47
48 test_Hcompta :: Test
49 test_Hcompta =
50 TestList
51 [ "Format" ~: TestList
52 [ "Ledger" ~: TestList
53 [ "Account" ~: TestList
54 [ "Read" ~: TestList
55 [ "section" ~: TestList
56 [ "\"\"" ~:
57 (Data.Either.rights $
58 [P.runParser
59 (Account.Read.section <* P.eof)
60 () "" (""::Text)])
61 ~?=
62 []
63 , "\"A\"" ~:
64 (Data.Either.rights $
65 [P.runParser
66 (Account.Read.section <* P.eof)
67 () "" ("A"::Text)])
68 ~?=
69 ["A"]
70 , "\"AA\"" ~:
71 (Data.Either.rights $
72 [P.runParser
73 (Account.Read.section <* P.eof)
74 () "" ("AA"::Text)])
75 ~?=
76 ["AA"]
77 , "\" \"" ~:
78 (Data.Either.rights $
79 [P.runParser
80 (Account.Read.section <* P.eof)
81 () "" (" "::Text)])
82 ~?=
83 []
84 , "\":\"" ~:
85 (Data.Either.rights $
86 [P.runParser
87 (Account.Read.section <* P.eof)
88 () "" (":"::Text)])
89 ~?=
90 []
91 , "\"A:\"" ~:
92 (Data.Either.rights $
93 [P.runParser
94 (Account.Read.section <* P.eof)
95 () "" ("A:"::Text)])
96 ~?=
97 []
98 , "\":A\"" ~:
99 (Data.Either.rights $
100 [P.runParser
101 (Account.Read.section <* P.eof)
102 () "" (":A"::Text)])
103 ~?=
104 []
105 , "\"A \"" ~:
106 (Data.Either.rights $
107 [P.runParser
108 (Account.Read.section <* P.eof)
109 () "" ("A "::Text)])
110 ~?=
111 []
112 , "\"A \"" ~:
113 (Data.Either.rights $
114 [P.runParser
115 (Account.Read.section)
116 () "" ("A "::Text)])
117 ~?=
118 ["A"]
119 , "\"A A\"" ~:
120 (Data.Either.rights $
121 [P.runParser
122 (Account.Read.section <* P.eof)
123 () "" ("A A"::Text)])
124 ~?=
125 ["A A"]
126 , "\"A \"" ~:
127 (Data.Either.rights $
128 [P.runParser
129 (Account.Read.section <* P.eof)
130 () "" ("A "::Text)])
131 ~?=
132 []
133 , "\"A\t\"" ~:
134 (Data.Either.rights $
135 [P.runParser
136 (Account.Read.section <* P.eof)
137 () "" ("A\t"::Text)])
138 ~?=
139 []
140 , "\"A \\n\"" ~:
141 (Data.Either.rights $
142 [P.runParser
143 (Account.Read.section <* P.eof)
144 () "" ("A \n"::Text)])
145 ~?=
146 []
147 , "\"(A)A\"" ~:
148 (Data.Either.rights $
149 [P.runParser
150 (Account.Read.section <* P.eof)
151 () "" ("(A)A"::Text)])
152 ~?=
153 ["(A)A"]
154 , "\"( )A\"" ~:
155 (Data.Either.rights $
156 [P.runParser
157 (Account.Read.section <* P.eof)
158 () "" ("( )A"::Text)])
159 ~?=
160 ["( )A"]
161 , "\"(A) A\"" ~:
162 (Data.Either.rights $
163 [P.runParser
164 (Account.Read.section <* P.eof)
165 () "" ("(A) A"::Text)])
166 ~?=
167 ["(A) A"]
168 , "\"[ ]A\"" ~:
169 (Data.Either.rights $
170 [P.runParser
171 (Account.Read.section <* P.eof)
172 () "" ("[ ]A"::Text)])
173 ~?=
174 ["[ ]A"]
175 , "\"(A) \"" ~:
176 (Data.Either.rights $
177 [P.runParser
178 (Account.Read.section <* P.eof)
179 () "" ("(A) "::Text)])
180 ~?=
181 []
182 , "\"(A)\"" ~:
183 (Data.Either.rights $
184 [P.runParser
185 (Account.Read.section <* P.eof)
186 () "" ("(A)"::Text)])
187 ~?=
188 ["(A)"]
189 , "\"A(A)\"" ~:
190 (Data.Either.rights $
191 [P.runParser
192 (Account.Read.section <* P.eof)
193 () "" ("A(A)"::Text)])
194 ~?=
195 [("A(A)"::Text)]
196 , "\"[A]A\"" ~:
197 (Data.Either.rights $
198 [P.runParser
199 (Account.Read.section <* P.eof)
200 () "" ("[A]A"::Text)])
201 ~?=
202 ["[A]A"]
203 , "\"[A] A\"" ~:
204 (Data.Either.rights $
205 [P.runParser
206 (Account.Read.section <* P.eof)
207 () "" ("[A] A"::Text)])
208 ~?=
209 ["[A] A"]
210 , "\"[A] \"" ~:
211 (Data.Either.rights $
212 [P.runParser
213 (Account.Read.section <* P.eof)
214 () "" ("[A] "::Text)])
215 ~?=
216 []
217 , "\"[A]\"" ~:
218 (Data.Either.rights $
219 [P.runParser
220 (Account.Read.section <* P.eof)
221 () "" ("[A]"::Text)])
222 ~?=
223 ["[A]"]
224 ]
225 , "account" ~: TestList
226 [ "\"\"" ~:
227 (Data.Either.rights $
228 [P.runParser
229 (Account.Read.account <* P.eof)
230 () "" (""::Text)])
231 ~?=
232 []
233 , "\"A\"" ~:
234 (Data.Either.rights $
235 [P.runParser
236 (Account.Read.account <* P.eof)
237 () "" ("A"::Text)])
238 ~?=
239 ["A":|[]]
240 , "\"A:\"" ~:
241 (Data.Either.rights $
242 [P.runParser
243 (Account.Read.account <* P.eof)
244 () "" ("A:"::Text)])
245 ~?=
246 []
247 , "\":A\"" ~:
248 (Data.Either.rights $
249 [P.runParser
250 (Account.Read.account <* P.eof)
251 () "" (":A"::Text)])
252 ~?=
253 []
254 , "\"A \"" ~:
255 (Data.Either.rights $
256 [P.runParser
257 (Account.Read.account <* P.eof)
258 () "" ("A "::Text)])
259 ~?=
260 []
261 , "\" A\"" ~:
262 (Data.Either.rights $
263 [P.runParser
264 (Account.Read.account <* P.eof)
265 () "" (" A"::Text)])
266 ~?=
267 []
268 , "\"A:B\"" ~:
269 (Data.Either.rights $
270 [P.runParser
271 (Account.Read.account <* P.eof)
272 () "" ("A:B"::Text)])
273 ~?=
274 ["A":|["B"]]
275 , "\"A:B:C\"" ~:
276 (Data.Either.rights $
277 [P.runParser
278 (Account.Read.account <* P.eof)
279 () "" ("A:B:C"::Text)])
280 ~?=
281 ["A":|["B", "C"]]
282 , "\"Aa:Bbb:Cccc\"" ~:
283 (Data.Either.rights $
284 [P.runParser
285 (Account.Read.account <* P.eof)
286 () "" ("Aa:Bbb:Cccc"::Text)])
287 ~?=
288 ["Aa":|["Bbb", "Cccc"]]
289 , "\"A a : B b b : C c c c\"" ~:
290 (Data.Either.rights $
291 [P.runParser
292 (Account.Read.account <* P.eof)
293 () "" ("A a : B b b : C c c c"::Text)])
294 ~?=
295 ["A a ":|[" B b b ", " C c c c"]]
296 , "\"A: :C\"" ~:
297 (Data.Either.rights $
298 [P.runParser
299 (Account.Read.account <* P.eof)
300 () "" ("A: :C"::Text)])
301 ~?=
302 ["A":|[" ", "C"]]
303 , "\"A::C\"" ~:
304 (Data.Either.rights $
305 [P.runParser
306 (Account.Read.account <* P.eof)
307 () "" ("A::C"::Text)])
308 ~?=
309 []
310 , "\"A:B:(C)\"" ~:
311 (Data.Either.rights $
312 [P.runParser
313 (Account.Read.account <* P.eof)
314 () "" ("A:B:(C)"::Text)])
315 ~?=
316 ["A":|["B", "(C)"]]
317 ]
318 ]
319 ]
320 , "Quantity" ~: TestList
321 [ "+" ~: TestList
322 [ "1 + 1 = 2" ~:
323 (+)
324 (Decimal 0 1)
325 (Decimal 0 1)
326 ~?=
327 Decimal 0 2
328 ]
329 ]
330 , "Amount" ~: TestList
331 [ {- "from_List" ~: TestList
332 [ "from_List [$1, 1$] = $2" ~:
333 Amount.from_List
334 [ Amount.amount
335 { Amount.amount_quantity = Decimal 0 1
336 , Amount.amount_style = Amount.Style.empty
337 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
338 }
339 , Amount.amount_unit = "$"
340 }
341 , Amount.amount
342 { Amount.amount_quantity = Decimal 0 1
343 , Amount.amount_style = Amount.Style.empty
344 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
345 }
346 , Amount.amount_unit = "$"
347 }
348 ]
349 ~?=
350 Data.Map.fromList
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
355 }
356 , Amount.amount_unit = "$"
357 })
358 ]
359 ]
360 ,-} "Read" ~: TestList
361 [ "amount" ~: TestList
362 [ "\"\" = Left" ~:
363 (Data.Either.rights $
364 [P.runParser
365 (Amount.Read.amount <* P.eof)
366 () "" (""::Text)])
367 ~?=
368 []
369 , "\"0\" = Right 0" ~:
370 (Data.Either.rights $
371 [P.runParser
372 (Amount.Read.amount <* P.eof)
373 () "" ("0"::Text)])
374 ~?=
375 [
376 ( Amount.Style.empty
377 , Amount.amount
378 { Amount.amount_quantity = Decimal 0 0
379 }
380 )
381 ]
382 , "\"00\" = Right 0" ~:
383 (Data.Either.rights $
384 [P.runParser
385 (Amount.Read.amount <* P.eof)
386 () "" ("00"::Text)])
387 ~?=
388 [
389 ( Amount.Style.empty
390 , Amount.amount
391 { Amount.amount_quantity = Decimal 0 0
392 }
393 )
394 ]
395 , "\"0.\" = Right 0." ~:
396 (Data.Either.rights $
397 [P.runParser
398 (Amount.Read.amount <* P.eof)
399 () "" ("0."::Text)])
400 ~?=
401 [
402 ( Amount.Style.empty
403 { Amount.Style.fractioning = Just '.'
404 }
405 , Amount.amount
406 { Amount.amount_quantity = Decimal 0 0
407 }
408 )
409 ]
410 , "\".0\" = Right 0.0" ~:
411 (Data.Either.rights $
412 [P.runParser
413 (Amount.Read.amount <* P.eof)
414 () "" (".0"::Text)])
415 ~?=
416 [
417 ( Amount.Style.empty
418 { Amount.Style.fractioning = Just '.'
419 }
420 , Amount.amount
421 { Amount.amount_quantity = Decimal 1 0
422 }
423 )
424 ]
425 , "\"0,\" = Right 0," ~:
426 (Data.Either.rights $
427 [P.runParser
428 (Amount.Read.amount <* P.eof)
429 () "" ("0,"::Text)])
430 ~?=
431 [
432 ( Amount.Style.empty
433 { Amount.Style.fractioning = Just ','
434 }
435 , Amount.amount
436 { Amount.amount_quantity = Decimal 0 0
437 }
438 )
439 ]
440 , "\",0\" = Right 0,0" ~:
441 (Data.Either.rights $
442 [P.runParser
443 (Amount.Read.amount <* P.eof)
444 () "" (",0"::Text)])
445 ~?=
446 [
447 ( Amount.Style.empty
448 { Amount.Style.fractioning = Just ','
449 }
450 , Amount.amount
451 { Amount.amount_quantity = Decimal 1 0
452 }
453 )
454 ]
455 , "\"0_\" = Left" ~:
456 (Data.Either.rights $
457 [P.runParser
458 (Amount.Read.amount <* P.eof)
459 () "" ("0_"::Text)])
460 ~?=
461 []
462 , "\"_0\" = Left" ~:
463 (Data.Either.rights $
464 [P.runParser
465 (Amount.Read.amount <* P.eof)
466 () "" ("_0"::Text)])
467 ~?=
468 []
469 , "\"0.0\" = Right 0.0" ~:
470 (Data.Either.rights $
471 [P.runParser
472 (Amount.Read.amount <* P.eof)
473 () "" ("0.0"::Text)])
474 ~?=
475 [
476 ( Amount.Style.empty
477 { Amount.Style.fractioning = Just '.'
478 }
479 , Amount.amount
480 { Amount.amount_quantity = Decimal 1 0
481 }
482 )
483 ]
484 , "\"00.00\" = Right 0.00" ~:
485 (Data.Either.rights $
486 [P.runParser
487 (Amount.Read.amount <* P.eof)
488 () "" ("00.00"::Text)])
489 ~?=
490 [
491 ( Amount.Style.empty
492 { Amount.Style.fractioning = Just '.'
493 }
494 , Amount.amount
495 { Amount.amount_quantity = Decimal 2 0
496 }
497 )
498 ]
499 , "\"0,0\" = Right 0,0" ~:
500 (Data.Either.rights $
501 [P.runParser
502 (Amount.Read.amount <* P.eof)
503 () "" ("0,0"::Text)])
504 ~?=
505 [
506 ( Amount.Style.empty
507 { Amount.Style.fractioning = Just ','
508 }
509 , Amount.amount
510 { Amount.amount_quantity = Decimal 1 0
511 }
512 )
513 ]
514 , "\"00,00\" = Right 0,00" ~:
515 (Data.Either.rights $
516 [P.runParser
517 (Amount.Read.amount <* P.eof)
518 () "" ("00,00"::Text)])
519 ~?=
520 [
521 ( Amount.Style.empty
522 { Amount.Style.fractioning = Just ','
523 }
524 , Amount.amount
525 { Amount.amount_quantity = Decimal 2 0
526 }
527 )
528 ]
529 , "\"0_0\" = Right 0" ~:
530 (Data.Either.rights $
531 [P.runParser
532 (Amount.Read.amount <* P.eof)
533 () "" ("0_0"::Text)])
534 ~?=
535 [
536 ( Amount.Style.empty
537 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
538 }
539 , Amount.amount
540 { Amount.amount_quantity = Decimal 0 0
541 }
542 )
543 ]
544 , "\"00_00\" = Right 0" ~:
545 (Data.Either.rights $
546 [P.runParser
547 (Amount.Read.amount <* P.eof)
548 () "" ("00_00"::Text)])
549 ~?=
550 [
551 ( Amount.Style.empty
552 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
553 }
554 , Amount.amount
555 { Amount.amount_quantity = Decimal 0 0
556 }
557 )
558 ]
559 , "\"0,000.00\" = Right 0,000.00" ~:
560 (Data.Either.rights $
561 [P.runParser
562 (Amount.Read.amount <* P.eof)
563 () "" ("0,000.00"::Text)])
564 ~?=
565 [
566 ( Amount.Style.empty
567 { Amount.Style.fractioning = Just '.'
568 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
569 }
570 , Amount.amount
571 { Amount.amount_quantity = Decimal 2 0
572 }
573 )
574 ]
575 , "\"0.000,00\" = Right 0.000,00" ~:
576 (Data.Either.rights $
577 [P.runParser
578 (Amount.Read.amount)
579 () "" ("0.000,00"::Text)])
580 ~?=
581 [
582 ( Amount.Style.empty
583 { Amount.Style.fractioning = Just ','
584 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
585 }
586 , Amount.amount
587 { Amount.amount_quantity = Decimal 2 0
588 }
589 )
590 ]
591 , "\"1,000.00\" = Right 1,000.00" ~:
592 (Data.Either.rights $
593 [P.runParser
594 (Amount.Read.amount <* P.eof)
595 () "" ("1,000.00"::Text)])
596 ~?=
597 [
598 ( Amount.Style.empty
599 { Amount.Style.fractioning = Just '.'
600 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
601 }
602 , Amount.amount
603 { Amount.amount_quantity = Decimal 2 100000
604 }
605 )
606 ]
607 , "\"1.000,00\" = Right 1.000,00" ~:
608 (Data.Either.rights $
609 [P.runParser
610 (Amount.Read.amount)
611 () "" ("1.000,00"::Text)])
612 ~?=
613 [
614 ( Amount.Style.empty
615 { Amount.Style.fractioning = Just ','
616 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
617 }
618 , Amount.amount
619 { Amount.amount_quantity = Decimal 2 100000
620 }
621 )
622 ]
623 , "\"1,000.00.\" = Left" ~:
624 (Data.Either.rights $
625 [P.runParser
626 (Amount.Read.amount)
627 () "" ("1,000.00."::Text)])
628 ~?=
629 []
630 , "\"1.000,00,\" = Left" ~:
631 (Data.Either.rights $
632 [P.runParser
633 (Amount.Read.amount)
634 () "" ("1.000,00,"::Text)])
635 ~?=
636 []
637 , "\"1,000.00_\" = Left" ~:
638 (Data.Either.rights $
639 [P.runParser
640 (Amount.Read.amount)
641 () "" ("1,000.00_"::Text)])
642 ~?=
643 []
644 , "\"12\" = Right 12" ~:
645 (Data.Either.rights $
646 [P.runParser
647 (Amount.Read.amount <* P.eof)
648 () "" ("123"::Text)])
649 ~?=
650 [
651 ( Amount.Style.empty
652 , Amount.amount
653 { Amount.amount_quantity = Decimal 0 123
654 }
655 )
656 ]
657 , "\"1.2\" = Right 1.2" ~:
658 (Data.Either.rights $
659 [P.runParser
660 (Amount.Read.amount <* P.eof)
661 () "" ("1.2"::Text)])
662 ~?=
663 [
664 ( Amount.Style.empty
665 { Amount.Style.fractioning = Just '.'
666 }
667 , Amount.amount
668 { Amount.amount_quantity = Decimal 1 12
669 }
670 )
671 ]
672 , "\"1,2\" = Right 1,2" ~:
673 (Data.Either.rights $
674 [P.runParser
675 (Amount.Read.amount <* P.eof)
676 () "" ("1,2"::Text)])
677 ~?=
678 [
679 ( Amount.Style.empty
680 { Amount.Style.fractioning = Just ','
681 }
682 , Amount.amount
683 { Amount.amount_quantity = Decimal 1 12
684 }
685 )
686 ]
687 , "\"12.34\" = Right 12.34" ~:
688 (Data.Either.rights $
689 [P.runParser
690 (Amount.Read.amount <* P.eof)
691 () "" ("12.34"::Text)])
692 ~?=
693 [
694 ( Amount.Style.empty
695 { Amount.Style.fractioning = Just '.'
696 }
697 , Amount.amount
698 { Amount.amount_quantity = Decimal 2 1234
699 }
700 )
701 ]
702 , "\"12,34\" = Right 12,34" ~:
703 (Data.Either.rights $
704 [P.runParser
705 (Amount.Read.amount <* P.eof)
706 () "" ("12,34"::Text)])
707 ~?=
708 [
709 ( Amount.Style.empty
710 { Amount.Style.fractioning = Just ','
711 }
712 , Amount.amount
713 { Amount.amount_quantity = Decimal 2 1234
714 }
715 )
716 ]
717 , "\"1_2\" = Right 1_2" ~:
718 (Data.Either.rights $
719 [P.runParser
720 (Amount.Read.amount <* P.eof)
721 () "" ("1_2"::Text)])
722 ~?=
723 [
724 ( Amount.Style.empty
725 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
726 }
727 , Amount.amount
728 { Amount.amount_quantity = Decimal 0 12
729 }
730 )
731 ]
732 , "\"1_23\" = Right 1_23" ~:
733 (Data.Either.rights $
734 [P.runParser
735 (Amount.Read.amount <* P.eof)
736 () "" ("1_23"::Text)])
737 ~?=
738 [
739 ( Amount.Style.empty
740 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
741 }
742 , Amount.amount
743 { Amount.amount_quantity = Decimal 0 123
744 }
745 )
746 ]
747 , "\"1_23_456\" = Right 1_23_456" ~:
748 (Data.Either.rights $
749 [P.runParser
750 (Amount.Read.amount <* P.eof)
751 () "" ("1_23_456"::Text)])
752 ~?=
753 [
754 ( Amount.Style.empty
755 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
756 }
757 , Amount.amount
758 { Amount.amount_quantity = Decimal 0 123456
759 }
760 )
761 ]
762 , "\"1_23_456.7890_12345_678901\" = Right 1_23_456.7890_12345_678901" ~:
763 (Data.Either.rights $
764 [P.runParser
765 (Amount.Read.amount <* P.eof)
766 () "" ("1_23_456.7890_12345_678901"::Text)])
767 ~?=
768 [
769 ( Amount.Style.empty
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]
773 }
774 , Amount.amount
775 { Amount.amount_quantity = Decimal 15 123456789012345678901
776 }
777 )
778 ]
779 , "\"123456_78901_2345.678_90_1\" = Right 123456_78901_2345.678_90_1" ~:
780 (Data.Either.rights $
781 [P.runParser
782 (Amount.Read.amount <* P.eof)
783 () "" ("123456_78901_2345.678_90_1"::Text)])
784 ~?=
785 [
786 ( Amount.Style.empty
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]
790 }
791 , Amount.amount
792 { Amount.amount_quantity = Decimal 6 123456789012345678901
793 }
794 )
795 ]
796 , "\"$1\" = Right $1" ~:
797 (Data.Either.rights $
798 [P.runParser
799 (Amount.Read.amount <* P.eof)
800 () "" ("$1"::Text)])
801 ~?=
802 [
803 ( Amount.Style.empty
804 { Amount.Style.unit_side = Just Amount.Style.Side_Left
805 , Amount.Style.unit_spaced = Just False
806 }
807 , Amount.amount
808 { Amount.amount_quantity = Decimal 0 1
809 , Amount.amount_unit = "$"
810 }
811 )
812 ]
813 , "\"1$\" = Right 1$" ~:
814 (Data.Either.rights $
815 [P.runParser
816 (Amount.Read.amount <* P.eof)
817 () "" ("1$"::Text)])
818 ~?=
819 [
820 ( Amount.Style.empty
821 { Amount.Style.unit_side = Just Amount.Style.Side_Right
822 , Amount.Style.unit_spaced = Just False
823 }
824 , Amount.amount
825 { Amount.amount_quantity = Decimal 0 1
826 , Amount.amount_unit = "$"
827 }
828 )
829 ]
830 , "\"$ 1\" = Right $ 1" ~:
831 (Data.Either.rights $
832 [P.runParser
833 (Amount.Read.amount <* P.eof)
834 () "" ("$ 1"::Text)])
835 ~?=
836 [
837 ( Amount.Style.empty
838 { Amount.Style.unit_side = Just Amount.Style.Side_Left
839 , Amount.Style.unit_spaced = Just True
840 }
841 , Amount.amount
842 { Amount.amount_quantity = Decimal 0 1
843 , Amount.amount_unit = "$"
844 }
845 )
846 ]
847 , "\"1 $\" = Right 1 $" ~:
848 (Data.Either.rights $
849 [P.runParser
850 (Amount.Read.amount <* P.eof)
851 () "" ("1 $"::Text)])
852 ~?=
853 [
854 ( Amount.Style.empty
855 { Amount.Style.unit_side = Just Amount.Style.Side_Right
856 , Amount.Style.unit_spaced = Just True
857 }
858 , Amount.amount
859 { Amount.amount_quantity = Decimal 0 1
860 , Amount.amount_unit = "$"
861 }
862 )
863 ]
864 , "\"-$1\" = Right $-1" ~:
865 (Data.Either.rights $
866 [P.runParser
867 (Amount.Read.amount <* P.eof)
868 () "" ("-$1"::Text)])
869 ~?=
870 [
871 ( Amount.Style.empty
872 { Amount.Style.unit_side = Just Amount.Style.Side_Left
873 , Amount.Style.unit_spaced = Just False
874 }
875 , Amount.amount
876 { Amount.amount_quantity = Decimal 0 (-1)
877 , Amount.amount_unit = "$"
878 }
879 )
880 ]
881 , "\"\\\"4 2\\\"1\" = Right \\\"4 2\\\"1" ~:
882 (Data.Either.rights $
883 [P.runParser
884 (Amount.Read.amount <* P.eof)
885 () "" ("\"4 2\"1"::Text)])
886 ~?=
887 [
888 ( Amount.Style.empty
889 { Amount.Style.unit_side = Just Amount.Style.Side_Left
890 , Amount.Style.unit_spaced = Just False
891 }
892 , Amount.amount
893 { Amount.amount_quantity = Decimal 0 1
894 , Amount.amount_unit = "4 2"
895 }
896 )
897 ]
898 , "\"1\\\"4 2\\\"\" = Right 1\\\"4 2\\\"" ~:
899 (Data.Either.rights $
900 [P.runParser
901 (Amount.Read.amount <* P.eof)
902 () "" ("1\"4 2\""::Text)])
903 ~?=
904 [
905 ( Amount.Style.empty
906 { Amount.Style.unit_side = Just Amount.Style.Side_Right
907 , Amount.Style.unit_spaced = Just False
908 }
909 , Amount.amount
910 { Amount.amount_quantity = Decimal 0 1
911 , Amount.amount_unit = "4 2"
912 }
913 )
914 ]
915 , "\"$1.000,00\" = Right $1.000,00" ~:
916 (Data.Either.rights $
917 [P.runParser
918 (Amount.Read.amount <* P.eof)
919 () "" ("$1.000,00"::Text)])
920 ~?=
921 [
922 ( Amount.Style.empty
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
927 }
928 , Amount.amount
929 { Amount.amount_quantity = Decimal 2 100000
930 , Amount.amount_unit = "$"
931 }
932 )
933 ]
934 , "\"1.000,00$\" = Right 1.000,00$" ~:
935 (Data.Either.rights $
936 [P.runParser
937 (Amount.Read.amount <* P.eof)
938 () "" ("1.000,00$"::Text)])
939 ~?=
940 [
941 ( Amount.Style.empty
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
946 }
947 , Amount.amount
948 { Amount.amount_quantity = Decimal 2 100000
949 , Amount.amount_unit = "$"
950 }
951 )
952 ]
953 ]
954 ]
955 , "Write" ~: TestList
956 [ "amount" ~: TestList
957 [ "empty" ~:
958 ((Ledger.Write.show
959 Ledger.Write.Style
960 { Ledger.Write.style_color=False
961 , Ledger.Write.style_align=True
962 } $
963 Amount.Write.amount $
964 (Amount.Style.empty,)
965 Amount.amount)
966 ~?=
967 "0")
968 , "0.00" ~:
969 ((Ledger.Write.show
970 Ledger.Write.Style
971 { Ledger.Write.style_color=False
972 , Ledger.Write.style_align=True
973 } $
974 Amount.Write.amount $
975 (Amount.Style.empty,)
976 Amount.amount
977 { Amount.amount_quantity = Decimal 2 0
978 })
979 ~?=
980 "0.00")
981 , "123" ~:
982 ((Ledger.Write.show
983 Ledger.Write.Style
984 { Ledger.Write.style_color=False
985 , Ledger.Write.style_align=True
986 } $
987 Amount.Write.amount $
988 (Amount.Style.empty,)
989 Amount.amount
990 { Amount.amount_quantity = Decimal 0 123
991 })
992 ~?=
993 "123")
994 , "-123" ~:
995 ((Ledger.Write.show
996 Ledger.Write.Style
997 { Ledger.Write.style_color=False
998 , Ledger.Write.style_align=True
999 } $
1000 Amount.Write.amount $
1001 (Amount.Style.empty,)
1002 Amount.amount
1003 { Amount.amount_quantity = Decimal 0 (- 123)
1004 })
1005 ~?=
1006 "-123")
1007 , "12.3" ~:
1008 ((Ledger.Write.show
1009 Ledger.Write.Style
1010 { Ledger.Write.style_color=False
1011 , Ledger.Write.style_align=True
1012 } $
1013 Amount.Write.amount $
1014 (Amount.Style.empty
1015 { Amount.Style.fractioning = Just '.'
1016 },)
1017 Amount.amount
1018 { Amount.amount_quantity = Decimal 1 123
1019 })
1020 ~?=
1021 "12.3")
1022 , "12.5" ~:
1023 ((Ledger.Write.show
1024 Ledger.Write.Style
1025 { Ledger.Write.style_color=False
1026 , Ledger.Write.style_align=True
1027 } $
1028 Amount.Write.amount $
1029 (Amount.Style.empty
1030 { Amount.Style.fractioning = Just '.'
1031 },)
1032 Amount.amount
1033 { Amount.amount_quantity = Decimal 1 125
1034 })
1035 ~?=
1036 "12.5")
1037 , "12.3" ~:
1038 ((Ledger.Write.show
1039 Ledger.Write.Style
1040 { Ledger.Write.style_color=False
1041 , Ledger.Write.style_align=True
1042 } $
1043 Amount.Write.amount $
1044 (Amount.Style.empty
1045 { Amount.Style.fractioning = Just '.'
1046 },)
1047 Amount.amount
1048 { Amount.amount_quantity = Decimal 1 123
1049 })
1050 ~?=
1051 "12.3")
1052 , "1,234.56" ~:
1053 ((Ledger.Write.show
1054 Ledger.Write.Style
1055 { Ledger.Write.style_color=False
1056 , Ledger.Write.style_align=True
1057 } $
1058 Amount.Write.amount $
1059 (Amount.Style.empty
1060 { Amount.Style.fractioning = Just '.'
1061 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
1062 },)
1063 Amount.amount
1064 { Amount.amount_quantity = Decimal 2 123456
1065 })
1066 ~?=
1067 "1,234.56")
1068 , "123,456,789,01,2.3456789" ~:
1069 ((Ledger.Write.show
1070 Ledger.Write.Style
1071 { Ledger.Write.style_color=False
1072 , Ledger.Write.style_align=True
1073 } $
1074 Amount.Write.amount $
1075 (Amount.Style.empty
1076 { Amount.Style.fractioning = Just '.'
1077 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1078 },)
1079 Amount.amount
1080 { Amount.amount_quantity = Decimal 7 1234567890123456789
1081 })
1082 ~?=
1083 "123,456,789,01,2.3456789")
1084 , "1234567.8,90,123,456,789" ~:
1085 ((Ledger.Write.show
1086 Ledger.Write.Style
1087 { Ledger.Write.style_color=False
1088 , Ledger.Write.style_align=True
1089 } $
1090 Amount.Write.amount $
1091 (Amount.Style.empty
1092 { Amount.Style.fractioning = Just '.'
1093 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1094 },)
1095 Amount.amount
1096 { Amount.amount_quantity = Decimal 12 1234567890123456789
1097 })
1098 ~?=
1099 "1234567.8,90,123,456,789")
1100 , "1,2,3,4,5,6,7,89,012.3456789" ~:
1101 ((Ledger.Write.show
1102 Ledger.Write.Style
1103 { Ledger.Write.style_color=False
1104 , Ledger.Write.style_align=True
1105 } $
1106 Amount.Write.amount $
1107 (Amount.Style.empty
1108 { Amount.Style.fractioning = Just '.'
1109 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1110 },)
1111 Amount.amount
1112 { Amount.amount_quantity = Decimal 7 1234567890123456789
1113 })
1114 ~?=
1115 "1,2,3,4,5,6,7,89,012.3456789")
1116 , "1234567.890,12,3,4,5,6,7,8,9" ~:
1117 ((Ledger.Write.show
1118 Ledger.Write.Style
1119 { Ledger.Write.style_color=False
1120 , Ledger.Write.style_align=True
1121 } $
1122 Amount.Write.amount $
1123 (Amount.Style.empty
1124 { Amount.Style.fractioning = Just '.'
1125 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1126 },)
1127 Amount.amount
1128 { Amount.amount_quantity = Decimal 12 1234567890123456789
1129 })
1130 ~?=
1131 "1234567.890,12,3,4,5,6,7,8,9")
1132 ]
1133 , "amount_length" ~: TestList
1134 [ "empty" ~:
1135 ((Amount.Write.amount_length $
1136 (Amount.Style.empty,)
1137 Amount.amount)
1138 ~?=
1139 1)
1140 , "0.00" ~:
1141 ((Amount.Write.amount_length $
1142 (Amount.Style.empty,)
1143 Amount.amount
1144 { Amount.amount_quantity = Decimal 2 0
1145 })
1146 ~?=
1147 4)
1148 , "123" ~:
1149 ((Amount.Write.amount_length $
1150 (Amount.Style.empty,)
1151 Amount.amount
1152 { Amount.amount_quantity = Decimal 0 123
1153 })
1154 ~?=
1155 3)
1156 , "-123" ~:
1157 ((Amount.Write.amount_length $
1158 (Amount.Style.empty,)
1159 Amount.amount
1160 { Amount.amount_quantity = Decimal 0 (- 123)
1161 })
1162 ~?=
1163 4)
1164 , "12.3" ~:
1165 ((Amount.Write.amount_length $
1166 (Amount.Style.empty
1167 { Amount.Style.fractioning = Just '.'
1168 },)
1169 Amount.amount
1170 { Amount.amount_quantity = Decimal 1 123
1171 })
1172 ~?=
1173 4)
1174 , "12.5" ~:
1175 ((Amount.Write.amount_length $
1176 (Amount.Style.empty
1177 { Amount.Style.fractioning = Just '.'
1178 },)
1179 Amount.amount
1180 { Amount.amount_quantity = Decimal 1 125
1181 })
1182 ~?=
1183 4)
1184 , "12.3" ~:
1185 ((Amount.Write.amount_length $
1186 (Amount.Style.empty
1187 { Amount.Style.fractioning = Just '.'
1188 },)
1189 Amount.amount
1190 { Amount.amount_quantity = Decimal 1 123
1191 })
1192 ~?=
1193 4)
1194 , "1,234.56" ~:
1195 ((Amount.Write.amount_length $
1196 (Amount.Style.empty
1197 { Amount.Style.fractioning = Just '.'
1198 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
1199 },)
1200 Amount.amount
1201 { Amount.amount_quantity = Decimal 2 123456
1202 })
1203 ~?=
1204 8)
1205 , "123,456,789,01,2.3456789" ~:
1206 ((Amount.Write.amount_length $
1207 (Amount.Style.empty
1208 { Amount.Style.fractioning = Just '.'
1209 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1210 },)
1211 Amount.amount
1212 { Amount.amount_quantity = Decimal 7 1234567890123456789
1213 })
1214 ~?=
1215 24)
1216 , "1234567.8,90,123,456,789" ~:
1217 ((Amount.Write.amount_length $
1218 (Amount.Style.empty
1219 { Amount.Style.fractioning = Just '.'
1220 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1221 },)
1222 Amount.amount
1223 { Amount.amount_quantity = Decimal 12 1234567890123456789
1224 })
1225 ~?=
1226 24)
1227 , "1,2,3,4,5,6,7,89,012.3456789" ~:
1228 ((Amount.Write.amount_length $
1229 (Amount.Style.empty
1230 { Amount.Style.fractioning = Just '.'
1231 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1232 },)
1233 Amount.amount
1234 { Amount.amount_quantity = Decimal 7 1234567890123456789
1235 })
1236 ~?=
1237 28)
1238 , "1234567.890,12,3,4,5,6,7,8,9" ~:
1239 ((Amount.Write.amount_length $
1240 (Amount.Style.empty
1241 { Amount.Style.fractioning = Just '.'
1242 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1243 },)
1244 Amount.amount
1245 { Amount.amount_quantity = Decimal 12 1234567890123456789
1246 })
1247 ~?=
1248 28)
1249 , "1000000.000,00,0,0,0,0,0,0,0" ~:
1250 ((Amount.Write.amount_length $
1251 (Amount.Style.empty
1252 { Amount.Style.fractioning = Just '.'
1253 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1254 },)
1255 Amount.amount
1256 { Amount.amount_quantity = Decimal 12 1000000000000000000
1257 })
1258 ~?=
1259 28)
1260 , "999" ~:
1261 ((Amount.Write.amount_length $
1262 (Amount.Style.empty,)
1263 Amount.amount
1264 { Amount.amount_quantity = Decimal 0 999
1265 })
1266 ~?=
1267 3)
1268 , "1000" ~:
1269 ((Amount.Write.amount_length $
1270 (Amount.Style.empty,)
1271 Amount.amount
1272 { Amount.amount_quantity = Decimal 0 1000
1273 })
1274 ~?=
1275 4)
1276 , "10,00€" ~:
1277 ((Amount.Write.amount_length $
1278 (Amount.Style.empty,)
1279 Amount.amount
1280 { Amount.amount_quantity = Decimal 2 1000
1281 , Amount.amount_unit = "€"
1282 })
1283 ~?=
1284 6)
1285 ]
1286 ]
1287 ]
1288 , "Date" ~: TestList
1289 [ "Read" ~: TestList
1290 [ "date" ~: TestList
1291 [ "2000/01/01" ~:
1292 (Data.Either.rights $
1293 [P.runParser_with_Error
1294 (Date.Read.date id Nothing <* P.eof)
1295 () "" ("2000/01/01"::Text)])
1296 ~?=
1297 [ Time.zonedTimeToUTC $
1298 Time.ZonedTime
1299 (Time.LocalTime
1300 (Time.fromGregorian 2000 01 01)
1301 (Time.TimeOfDay 0 0 0))
1302 (Time.utc)]
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)])
1308 ~?=
1309 [ Time.zonedTimeToUTC $
1310 Time.ZonedTime
1311 (Time.LocalTime
1312 (Time.fromGregorian 2000 01 01)
1313 (Time.TimeOfDay 0 0 0))
1314 (Time.utc)]
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)])
1320 ~?=
1321 [ Time.zonedTimeToUTC $
1322 Time.ZonedTime
1323 (Time.LocalTime
1324 (Time.fromGregorian 2000 01 01)
1325 (Time.TimeOfDay 12 34 0))
1326 (Time.utc)]
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)])
1332 ~?=
1333 [ Time.zonedTimeToUTC $
1334 Time.ZonedTime
1335 (Time.LocalTime
1336 (Time.fromGregorian 2000 01 01)
1337 (Time.TimeOfDay 12 34 56))
1338 (Time.utc)]
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)])
1344 ~?=
1345 [ Time.zonedTimeToUTC $
1346 Time.ZonedTime
1347 (Time.LocalTime
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)])
1356 ~?=
1357 [ Time.zonedTimeToUTC $
1358 Time.ZonedTime
1359 (Time.LocalTime
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)])
1368 ~?=
1369 [ Time.zonedTimeToUTC $
1370 Time.ZonedTime
1371 (Time.LocalTime
1372 (Time.fromGregorian 2000 01 01)
1373 (Time.TimeOfDay 12 34 56))
1374 (Time.TimeZone 60 True "CET")]
1375 , "2001/02/29" ~:
1376 (Data.Either.rights $
1377 [P.runParser_with_Error
1378 (Date.Read.date id Nothing <* P.eof)
1379 () "" ("2001/02/29"::Text)])
1380 ~?=
1381 []
1382 , "01/01" ~:
1383 (Data.Either.rights $
1384 [P.runParser_with_Error
1385 (Date.Read.date id (Just 2000) <* P.eof)
1386 () "" ("01/01"::Text)])
1387 ~?=
1388 [ Time.zonedTimeToUTC $
1389 Time.ZonedTime
1390 (Time.LocalTime
1391 (Time.fromGregorian 2000 01 01)
1392 (Time.TimeOfDay 0 0 0))
1393 (Time.utc)]
1394 ]
1395 ]
1396 , "Write" ~: TestList
1397 [ "date" ~: TestList
1398 [ "nil" ~:
1399 ((Ledger.Write.show
1400 Ledger.Write.Style
1401 { Ledger.Write.style_color=False
1402 , Ledger.Write.style_align=True
1403 } $
1404 Date.Write.date
1405 Date.nil)
1406 ~?=
1407 "1970/01/01")
1408 , "2000/01/01_12:34:51CET" ~:
1409 (Ledger.Write.show
1410 Ledger.Write.Style
1411 { Ledger.Write.style_color=False
1412 , Ledger.Write.style_align=True
1413 } $
1414 Date.Write.date $
1415 Time.zonedTimeToUTC $
1416 Time.ZonedTime
1417 (Time.LocalTime
1418 (Time.fromGregorian 2000 01 01)
1419 (Time.TimeOfDay 12 34 51))
1420 (Time.TimeZone 60 False "CET"))
1421 ~?=
1422 "2000/01/01_11:34:51"
1423 , "2000/01/01_12:34:51+0100" ~:
1424 (Ledger.Write.show
1425 Ledger.Write.Style
1426 { Ledger.Write.style_color=False
1427 , Ledger.Write.style_align=True
1428 } $
1429 Date.Write.date $
1430 Time.zonedTimeToUTC $
1431 Time.ZonedTime
1432 (Time.LocalTime
1433 (Time.fromGregorian 2000 01 01)
1434 (Time.TimeOfDay 12 34 51))
1435 (Time.TimeZone 60 False ""))
1436 ~?=
1437 "2000/01/01_11:34:51"
1438 , "2000/01/01_01:02:03" ~:
1439 (Ledger.Write.show
1440 Ledger.Write.Style
1441 { Ledger.Write.style_color=False
1442 , Ledger.Write.style_align=True
1443 } $
1444 Date.Write.date $
1445 Time.zonedTimeToUTC $
1446 Time.ZonedTime
1447 (Time.LocalTime
1448 (Time.fromGregorian 2000 01 01)
1449 (Time.TimeOfDay 1 2 3))
1450 (Time.utc))
1451 ~?=
1452 "2000/01/01_01:02:03"
1453 , "01/01_01:02" ~:
1454 (Ledger.Write.show
1455 Ledger.Write.Style
1456 { Ledger.Write.style_color=False
1457 , Ledger.Write.style_align=True
1458 } $
1459 Date.Write.date $
1460 Time.zonedTimeToUTC $
1461 Time.ZonedTime
1462 (Time.LocalTime
1463 (Time.fromGregorian 0 01 01)
1464 (Time.TimeOfDay 1 2 0))
1465 (Time.utc))
1466 ~?=
1467 "01/01_01:02"
1468 , "01/01_01:00" ~:
1469 (Ledger.Write.show
1470 Ledger.Write.Style
1471 { Ledger.Write.style_color=False
1472 , Ledger.Write.style_align=True
1473 } $
1474 Date.Write.date $
1475 Time.zonedTimeToUTC $
1476 Time.ZonedTime
1477 (Time.LocalTime
1478 (Time.fromGregorian 0 01 01)
1479 (Time.TimeOfDay 1 0 0))
1480 (Time.utc))
1481 ~?=
1482 "01/01_01:00"
1483 , "01/01_00:01" ~:
1484 (Ledger.Write.show
1485 Ledger.Write.Style
1486 { Ledger.Write.style_color=False
1487 , Ledger.Write.style_align=True
1488 } $
1489 Date.Write.date $
1490 Time.zonedTimeToUTC $
1491 Time.ZonedTime
1492 (Time.LocalTime
1493 (Time.fromGregorian 0 01 01)
1494 (Time.TimeOfDay 0 1 0))
1495 (Time.utc))
1496 ~?=
1497 "01/01_00:01"
1498 , "01/01" ~:
1499 (Ledger.Write.show
1500 Ledger.Write.Style
1501 { Ledger.Write.style_color=False
1502 , Ledger.Write.style_align=True
1503 } $
1504 Date.Write.date $
1505 Time.zonedTimeToUTC $
1506 Time.ZonedTime
1507 (Time.LocalTime
1508 (Time.fromGregorian 0 01 01)
1509 (Time.TimeOfDay 0 0 0))
1510 (Time.utc))
1511 ~?=
1512 "01/01"
1513 ]
1514 ]
1515 ]
1516 , "Read" ~: TestList
1517 [ "posting_type" ~: TestList
1518 [ "A" ~:
1519 Ledger.Read.posting_type
1520 ("A":|[])
1521 ~?=
1522 Ledger.Posting_Typed
1523 (Ledger.Posting_Type_Regular, "A":|[])
1524 , "(" ~:
1525 Ledger.Read.posting_type
1526 ("(":|[])
1527 ~?=
1528 Ledger.Posting_Typed
1529 (Ledger.Posting_Type_Regular, "(":|[])
1530 , ")" ~:
1531 Ledger.Read.posting_type
1532 (")":|[])
1533 ~?=
1534 Ledger.Posting_Typed
1535 (Ledger.Posting_Type_Regular, ")":|[])
1536 , "()" ~:
1537 Ledger.Read.posting_type
1538 ("()":|[])
1539 ~?=
1540 Ledger.Posting_Typed
1541 (Ledger.Posting_Type_Regular, "()":|[])
1542 , "( )" ~:
1543 Ledger.Read.posting_type
1544 ("( )":|[])
1545 ~?=
1546 Ledger.Posting_Typed
1547 (Ledger.Posting_Type_Regular, "( )":|[])
1548 , "(A)" ~:
1549 Ledger.Read.posting_type
1550 ("(A)":|[])
1551 ~?=
1552 Ledger.Posting_Typed
1553 (Ledger.Posting_Type_Virtual, "A":|[])
1554 , "(A:B:C)" ~:
1555 Ledger.Read.posting_type
1556 ("(A":|["B", "C)"])
1557 ~?=
1558 Ledger.Posting_Typed
1559 (Ledger.Posting_Type_Virtual, "A":|["B", "C"])
1560 , "A:B:C" ~:
1561 Ledger.Read.posting_type
1562 ("A":|["B", "C"])
1563 ~?=
1564 Ledger.Posting_Typed
1565 (Ledger.Posting_Type_Regular, "A":|["B", "C"])
1566 , "(A):B:C" ~:
1567 Ledger.Read.posting_type
1568 ("(A)":|["B", "C"])
1569 ~?=
1570 Ledger.Posting_Typed
1571 (Ledger.Posting_Type_Regular, "(A)":|["B", "C"])
1572 , "A:(B):C" ~:
1573 Ledger.Read.posting_type
1574 ("A":|["(B)", "C"])
1575 ~?=
1576 Ledger.Posting_Typed
1577 (Ledger.Posting_Type_Regular, "A":|["(B)", "C"])
1578 , "A:B:(C)" ~:
1579 Ledger.Read.posting_type
1580 ("A":|["B", "(C)"])
1581 ~?=
1582 Ledger.Posting_Typed
1583 (Ledger.Posting_Type_Regular, "A":|["B", "(C)"])
1584 , "[" ~:
1585 Ledger.Read.posting_type
1586 ("[":|[])
1587 ~?=
1588 Ledger.Posting_Typed
1589 (Ledger.Posting_Type_Regular, "[":|[])
1590 , "]" ~:
1591 Ledger.Read.posting_type
1592 ("]":|[])
1593 ~?=
1594 Ledger.Posting_Typed
1595 (Ledger.Posting_Type_Regular, "]":|[])
1596 , "[]" ~:
1597 Ledger.Read.posting_type
1598 ("[]":|[])
1599 ~?=
1600 Ledger.Posting_Typed
1601 (Ledger.Posting_Type_Regular, "[]":|[])
1602 , "[ ]" ~:
1603 Ledger.Read.posting_type
1604 ("[ ]":|[])
1605 ~?=
1606 Ledger.Posting_Typed
1607 (Ledger.Posting_Type_Regular, "[ ]":|[])
1608 , "[A]" ~:
1609 Ledger.Read.posting_type
1610 ("[A]":|[])
1611 ~?=
1612 Ledger.Posting_Typed
1613 (Ledger.Posting_Type_Virtual_Balanced, "A":|[])
1614 , "[A:B:C]" ~:
1615 Ledger.Read.posting_type
1616 ("[A":|["B", "C]"])
1617 ~?=
1618 Ledger.Posting_Typed
1619 (Ledger.Posting_Type_Virtual_Balanced, "A":|["B", "C"])
1620 , "A:B:C" ~:
1621 Ledger.Read.posting_type
1622 ("A":|["B", "C"])
1623 ~?=
1624 Ledger.Posting_Typed
1625 (Ledger.Posting_Type_Regular, "A":|["B", "C"])
1626 , "[A]:B:C" ~:
1627 Ledger.Read.posting_type
1628 ("[A]":|["B", "C"])
1629 ~?=
1630 Ledger.Posting_Typed
1631 (Ledger.Posting_Type_Regular, "[A]":|["B", "C"])
1632 , "A:[B]:C" ~:
1633 Ledger.Read.posting_type
1634 ("A":|["[B]", "C"])
1635 ~?=
1636 Ledger.Posting_Typed
1637 (Ledger.Posting_Type_Regular, "A":|["[B]", "C"])
1638 , "A:B:[C]" ~:
1639 Ledger.Read.posting_type
1640 ("A":|["B", "[C]"])
1641 ~?=
1642 Ledger.Posting_Typed
1643 (Ledger.Posting_Type_Regular, "A":|["B", "[C]"])
1644 ]
1645 , "comment" ~: TestList
1646 [ "; some comment = Right \" some comment\"" ~:
1647 (Data.Either.rights $
1648 [P.runParser
1649 (Ledger.Read.comment <* P.eof)
1650 () "" ("; some comment"::Text)])
1651 ~?=
1652 [ " some comment" ]
1653 , "; some comment \\n = Right \" some comment \"" ~:
1654 (Data.Either.rights $
1655 [P.runParser
1656 (Ledger.Read.comment <* P.newline <* P.eof)
1657 () "" ("; some comment \n"::Text)])
1658 ~?=
1659 [ " some comment " ]
1660 , "; some comment \\r\\n = Right \" some comment \"" ~:
1661 (Data.Either.rights $
1662 [P.runParser
1663 (Ledger.Read.comment <* P.string "\r\n" <* P.eof)
1664 () "" ("; some comment \r\n"::Text)])
1665 ~?=
1666 [ " some comment " ]
1667 ]
1668 , "comments" ~: TestList
1669 [ "; some comment\\n ; some other comment = Right [\" some comment\", \" some other comment\"]" ~:
1670 (Data.Either.rights $
1671 [P.runParser
1672 (Ledger.Read.comments <* P.eof)
1673 () "" ("; some comment\n ; some other comment"::Text)])
1674 ~?=
1675 [ [" some comment", " some other comment"] ]
1676 , "; some comment \\n = Right \" some comment \"" ~:
1677 (Data.Either.rights $
1678 [P.runParser
1679 (Ledger.Read.comments <* P.string "\n" <* P.eof)
1680 () "" ("; some comment \n"::Text)])
1681 ~?=
1682 [ [" some comment "] ]
1683 ]
1684 , "tag_value" ~: TestList
1685 [ "," ~:
1686 (Data.Either.rights $
1687 [P.runParser
1688 (Ledger.Read.tag_value <* P.eof)
1689 () "" (","::Text)])
1690 ~?=
1691 [","]
1692 , ",\\n" ~:
1693 (Data.Either.rights $
1694 [P.runParser
1695 (Ledger.Read.tag_value <* P.char '\n' <* P.eof)
1696 () "" (",\n"::Text)])
1697 ~?=
1698 [","]
1699 , ",x" ~:
1700 (Data.Either.rights $
1701 [P.runParser
1702 (Ledger.Read.tag_value <* P.eof)
1703 () "" (",x"::Text)])
1704 ~?=
1705 [",x"]
1706 , ",x:" ~:
1707 (Data.Either.rights $
1708 [P.runParser
1709 (Ledger.Read.tag_value <* P.string ",x:" <* P.eof)
1710 () "" (",x:"::Text)])
1711 ~?=
1712 [""]
1713 , "v, v, n:" ~:
1714 (Data.Either.rights $
1715 [P.runParser
1716 (Ledger.Read.tag_value <* P.string ", n:" <* P.eof)
1717 () "" ("v, v, n:"::Text)])
1718 ~?=
1719 ["v, v"]
1720 ]
1721 , "tag" ~: TestList
1722 [ "Name:" ~:
1723 (Data.Either.rights $
1724 [P.runParser
1725 (Ledger.Read.tag <* P.eof)
1726 () "" ("Name:"::Text)])
1727 ~?=
1728 [("Name":|[], "")]
1729 , "Name:Value" ~:
1730 (Data.Either.rights $
1731 [P.runParser
1732 (Ledger.Read.tag <* P.eof)
1733 () "" ("Name:Value"::Text)])
1734 ~?=
1735 [("Name":|[], "Value")]
1736 , "Name:Value\\n" ~:
1737 (Data.Either.rights $
1738 [P.runParser
1739 (Ledger.Read.tag <* P.string "\n" <* P.eof)
1740 () "" ("Name:Value\n"::Text)])
1741 ~?=
1742 [("Name":|[], "Value")]
1743 , "Name:Val ue" ~:
1744 (Data.Either.rights $
1745 [P.runParser
1746 (Ledger.Read.tag <* P.eof)
1747 () "" ("Name:Val ue"::Text)])
1748 ~?=
1749 [("Name":|[], "Val ue")]
1750 , "Name:," ~:
1751 (Data.Either.rights $
1752 [P.runParser
1753 (Ledger.Read.tag <* P.eof)
1754 () "" ("Name:,"::Text)])
1755 ~?=
1756 [("Name":|[], ",")]
1757 , "Name:Val,ue" ~:
1758 (Data.Either.rights $
1759 [P.runParser
1760 (Ledger.Read.tag <* P.eof)
1761 () "" ("Name:Val,ue"::Text)])
1762 ~?=
1763 [("Name":|[], "Val,ue")]
1764 , "Name:Val,ue:" ~:
1765 (Data.Either.rights $
1766 [P.runParser
1767 (Ledger.Read.tag <* P.string ",ue:" <* P.eof)
1768 () "" ("Name:Val,ue:"::Text)])
1769 ~?=
1770 [("Name":|[], "Val")]
1771 , "Name:Val,ue :" ~:
1772 (Data.Either.rights $
1773 [P.runParser
1774 (Ledger.Read.tag <* P.eof)
1775 () "" ("Name:Val,ue :"::Text)])
1776 ~?=
1777 [("Name":|[], "Val,ue :")]
1778 ]
1779 , "tags" ~: TestList
1780 [ "Name:" ~:
1781 (Data.Either.rights $
1782 [P.runParser
1783 (Ledger.Read.tags <* P.eof)
1784 () "" ("Name:"::Text)])
1785 ~?=
1786 [Data.Map.fromList
1787 [ ("Name":|[], [""])
1788 ]
1789 ]
1790 , "Name:," ~:
1791 (Data.Either.rights $
1792 [P.runParser
1793 (Ledger.Read.tags <* P.eof)
1794 () "" ("Name:,"::Text)])
1795 ~?=
1796 [Data.Map.fromList
1797 [ ("Name":|[], [","])
1798 ]
1799 ]
1800 , "Name:,Name:" ~:
1801 (Data.Either.rights $
1802 [P.runParser
1803 (Ledger.Read.tags <* P.eof)
1804 () "" ("Name:,Name:"::Text)])
1805 ~?=
1806 [Data.Map.fromList
1807 [ ("Name":|[], ["", ""])
1808 ]
1809 ]
1810 , "Name:,Name2:" ~:
1811 (Data.Either.rights $
1812 [P.runParser
1813 (Ledger.Read.tags <* P.eof)
1814 () "" ("Name:,Name2:"::Text)])
1815 ~?=
1816 [Data.Map.fromList
1817 [ ("Name":|[], [""])
1818 , ("Name2":|[], [""])
1819 ]
1820 ]
1821 , "Name: , Name2:" ~:
1822 (Data.Either.rights $
1823 [P.runParser
1824 (Ledger.Read.tags <* P.eof)
1825 () "" ("Name: , Name2:"::Text)])
1826 ~?=
1827 [Data.Map.fromList
1828 [ ("Name":|[], [" "])
1829 , ("Name2":|[], [""])
1830 ]
1831 ]
1832 , "Name:,Name2:,Name3:" ~:
1833 (Data.Either.rights $
1834 [P.runParser
1835 (Ledger.Read.tags <* P.eof)
1836 () "" ("Name:,Name2:,Name3:"::Text)])
1837 ~?=
1838 [Data.Map.fromList
1839 [ ("Name":|[], [""])
1840 , ("Name2":|[], [""])
1841 , ("Name3":|[], [""])
1842 ]
1843 ]
1844 , "Name:Val ue,Name2:V a l u e,Name3:V al ue" ~:
1845 (Data.Either.rights $
1846 [P.runParser
1847 (Ledger.Read.tags <* P.eof)
1848 () "" ("Name:Val ue,Name2:V a l u e,Name3:V al ue"::Text)])
1849 ~?=
1850 [Data.Map.fromList
1851 [ ("Name":|[], ["Val ue"])
1852 , ("Name2":|[], ["V a l u e"])
1853 , ("Name3":|[], ["V al ue"])
1854 ]
1855 ]
1856 ]
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)])
1865 ~?=
1866 [ Ledger.Posting_Typed
1867 ( Ledger.Posting_Type_Regular
1868 , (Ledger.posting ("A":|["B", "C"]))
1869 { Ledger.posting_sourcepos = P.newPos "" 1 1
1870 }
1871 )
1872 ]
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)])
1881 ~?=
1882 [ (Ledger.posting ("A":|["B", "C"]))
1883 { Ledger.posting_sourcepos = P.newPos "" 1 1
1884 , Ledger.posting_status = True
1885 }
1886 ]
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)])
1895 ~?=
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
1903 }
1904 ]
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)])
1913 ~?=
1914 [ (Ledger.posting ("A":|["B","C $1"]))
1915 { Ledger.posting_sourcepos = P.newPos "" 1 1
1916 }
1917 ]
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)])
1926 ~?=
1927 [ (Ledger.posting ("A":|["B", "C"]))
1928 { Ledger.posting_amounts = Data.Map.fromList
1929 [ ("$", 1)
1930 ]
1931 , Ledger.posting_sourcepos = P.newPos "" 1 1
1932 }
1933 ]
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)])
1942 ~?=
1943 [ (Ledger.posting ("A":|["B", "C"]))
1944 { Ledger.posting_amounts = Data.Map.fromList
1945 [ ("$", 1)
1946 , ("€", 1)
1947 ]
1948 , Ledger.posting_sourcepos = P.newPos "" 1 1
1949 }
1950 ]
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)])
1959 ~?=
1960 [ (Ledger.posting ("A":|["B", "C"]))
1961 { Ledger.posting_amounts = Data.Map.fromList
1962 [ ("$", 2)
1963 ]
1964 , Ledger.posting_sourcepos = P.newPos "" 1 1
1965 }
1966 ]
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)])
1975 ~?=
1976 [ (Ledger.posting ("A":|["B", "C"]))
1977 { Ledger.posting_amounts = Data.Map.fromList
1978 [ ("$", 3)
1979 ]
1980 , Ledger.posting_sourcepos = P.newPos "" 1 1
1981 }
1982 ]
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)])
1991 ~?=
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
1996 }
1997 ]
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)])
2006 ~?=
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
2011 }
2012 ]
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)])
2021 ~?=
2022 [ (Ledger.posting ("A":|["B", "C"]))
2023 { Ledger.posting_amounts = Data.Map.fromList
2024 [ ("$", 1)
2025 ]
2026 , Ledger.posting_comments = [" some comment"]
2027 , Ledger.posting_sourcepos = P.newPos "" 1 1
2028 }
2029 ]
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)])
2038 ~?=
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
2043 [ ("N":|[], "V")
2044 ]
2045 }
2046 ]
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)])
2055 ~?=
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
2060 [ ("N":|[], "V")
2061 ]
2062 }
2063 ]
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)])
2072 ~?=
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
2077 [ ("N":|[], "V v")
2078 , ("N2":|[], "V2 v2")
2079 ]
2080 }
2081 ]
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)])
2090 ~?=
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
2095 [ ("N":|[], "V")
2096 , ("N":|[], "V2")
2097 ]
2098 }
2099 ]
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)])
2108 ~?=
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
2113 [ ("N":|[], "V")
2114 , ("N2":|[], "V")
2115 ]
2116 }
2117 ]
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)])
2126 ~?=
2127 [ (Ledger.posting ("A":|["B", "C"]))
2128 { Ledger.posting_comments = [" date:2001/01/01"]
2129 , Ledger.posting_dates =
2130 [ Time.zonedTimeToUTC $
2131 Time.ZonedTime
2132 (Time.LocalTime
2133 (Time.fromGregorian 2001 01 01)
2134 (Time.TimeOfDay 0 0 0))
2135 Time.utc
2136 ]
2137 , Ledger.posting_sourcepos = P.newPos "" 1 1
2138 , Ledger.posting_tags = Tag.from_List
2139 [ ("date":|[], "2001/01/01")
2140 ]
2141 }
2142 ]
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)])
2150 ~?=
2151 [ Ledger.Posting_Typed
2152 ( Ledger.Posting_Type_Virtual
2153 , (Ledger.posting ("A":|["B", "C"]))
2154 { Ledger.posting_sourcepos = P.newPos "" 1 1
2155 }
2156 )
2157 ]
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)])
2165 ~?=
2166 [ Ledger.Posting_Typed
2167 ( Ledger.Posting_Type_Virtual_Balanced
2168 , (Ledger.posting ("A":|["B", "C"]))
2169 { Ledger.posting_sourcepos = P.newPos "" 1 1
2170 }
2171 )
2172 ]
2173 ]
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)])
2182 ~?=
2183 [ Ledger.transaction
2184 { Ledger.transaction_dates=
2185 ( Time.zonedTimeToUTC $
2186 Time.ZonedTime
2187 (Time.LocalTime
2188 (Time.fromGregorian 2000 01 01)
2189 (Time.TimeOfDay 0 0 0))
2190 (Time.utc)
2191 , [] )
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
2196 [ ("$", 1)
2197 ]
2198 , Ledger.posting_sourcepos = P.newPos "" 2 1
2199 }
2200 , (Ledger.posting ("a":|["b", "c"]))
2201 { Ledger.posting_amounts = Data.Map.fromList
2202 [ ("$", -1)
2203 ]
2204 , Ledger.posting_sourcepos = P.newPos "" 3 1
2205 }
2206 ]
2207 , Ledger.transaction_sourcepos = P.newPos "" 1 1
2208 }
2209 ]
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)])
2217 ~?=
2218 [ Ledger.transaction
2219 { Ledger.transaction_dates=
2220 ( Time.zonedTimeToUTC $
2221 Time.ZonedTime
2222 (Time.LocalTime
2223 (Time.fromGregorian 2000 01 01)
2224 (Time.TimeOfDay 0 0 0))
2225 (Time.utc)
2226 , [] )
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
2231 [ ("$", 1)
2232 ]
2233 , Ledger.posting_sourcepos = P.newPos "" 2 1
2234 }
2235 , (Ledger.posting ("a":|["b", "c"]))
2236 { Ledger.posting_amounts = Data.Map.fromList
2237 [ ("$", -1)
2238 ]
2239 , Ledger.posting_sourcepos = P.newPos "" 3 1
2240 }
2241 ]
2242 , Ledger.transaction_sourcepos = P.newPos "" 1 1
2243 }
2244 ]
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)])
2252 ~?=
2253 [ Ledger.transaction
2254 { Ledger.transaction_comments_after =
2255 [ " some comment"
2256 , " some other;comment"
2257 , " some Tag:"
2258 , " some last comment"
2259 ]
2260 , Ledger.transaction_dates=
2261 ( Time.zonedTimeToUTC $
2262 Time.ZonedTime
2263 (Time.LocalTime
2264 (Time.fromGregorian 2000 01 01)
2265 (Time.TimeOfDay 0 0 0))
2266 (Time.utc)
2267 , [] )
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
2272 [ ("$", 1)
2273 ]
2274 , Ledger.posting_sourcepos = P.newPos "" 5 1
2275 }
2276 , (Ledger.posting ("a":|["b", "c"]))
2277 { Ledger.posting_amounts = Data.Map.fromList
2278 [ ("$", -1)
2279 ]
2280 , Ledger.posting_sourcepos = P.newPos "" 6 1
2281 }
2282 ]
2283 , Ledger.transaction_tags = Tag.from_List
2284 [ ("Tag":|[], "")
2285 ]
2286 , Ledger.transaction_sourcepos = P.newPos "" 1 1
2287 }
2288 ]
2289 ]
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
2292 jnl <- liftIO $
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)
2298 (Data.List.map
2299 (\j -> j{Ledger.journal_last_read_time=Date.nil}) $
2300 Data.Either.rights [jnl])
2301 @?=
2302 [ Ledger.journal
2303 { Ledger.journal_sections =
2304 fmap (Ledger.Chart_With . (mempty,)) $
2305 [ Ledger.transaction
2306 { Ledger.transaction_dates=
2307 ( Time.zonedTimeToUTC $
2308 Time.ZonedTime
2309 (Time.LocalTime
2310 (Time.fromGregorian 2000 01 02)
2311 (Time.TimeOfDay 0 0 0))
2312 (Time.utc)
2313 , [] )
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
2318 [ ("$", 1)
2319 ]
2320 , Ledger.posting_sourcepos = P.newPos "" 5 1
2321 }
2322 , (Ledger.posting ("x":|["y", "z"]))
2323 { Ledger.posting_amounts = Data.Map.fromList
2324 [ ("$", -1)
2325 ]
2326 , Ledger.posting_sourcepos = P.newPos "" 6 1
2327 }
2328 ]
2329 , Ledger.transaction_sourcepos = P.newPos "" 4 1
2330 }
2331 , Ledger.transaction
2332 { Ledger.transaction_dates=
2333 ( Time.zonedTimeToUTC $
2334 Time.ZonedTime
2335 (Time.LocalTime
2336 (Time.fromGregorian 2000 01 01)
2337 (Time.TimeOfDay 0 0 0))
2338 (Time.utc)
2339 , [] )
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
2344 [ ("$", 1)
2345 ]
2346 , Ledger.posting_sourcepos = P.newPos "" 2 1
2347 }
2348 , (Ledger.posting ("a":|["b", "c"]))
2349 { Ledger.posting_amounts = Data.Map.fromList
2350 [ ("$", -1)
2351 ]
2352 , Ledger.posting_sourcepos = P.newPos "" 3 1
2353 }
2354 ]
2355 , Ledger.transaction_sourcepos = P.newPos "" 1 1
2356 }
2357 ]
2358 , Ledger.journal_amount_styles = Amount.Style.Styles $ Data.Map.fromList
2359 [ ( Ledger.Unit "$"
2360 , Amount.Style.empty
2361 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2362 , Amount.Style.unit_spaced = Just False
2363 }
2364 )
2365 ]
2366 }
2367 ]
2368 ]
2369 ]
2370 , "Write" ~: TestList
2371 [ "account" ~: TestList
2372 [ "A" ~:
2373 ((Ledger.Write.show
2374 Ledger.Write.Style
2375 { Ledger.Write.style_color=False
2376 , Ledger.Write.style_align=True
2377 } $
2378 Ledger.Write.account Ledger.Posting_Type_Regular $
2379 "A":|[])
2380 ~?=
2381 "A")
2382 , "A:B:C" ~:
2383 ((Ledger.Write.show
2384 Ledger.Write.Style
2385 { Ledger.Write.style_color=False
2386 , Ledger.Write.style_align=True
2387 } $
2388 Ledger.Write.account Ledger.Posting_Type_Regular $
2389 "A":|["B", "C"])
2390 ~?=
2391 "A:B:C")
2392 , "(A:B:C)" ~:
2393 ((Ledger.Write.show
2394 Ledger.Write.Style
2395 { Ledger.Write.style_color=False
2396 , Ledger.Write.style_align=True
2397 } $
2398 Ledger.Write.account Ledger.Posting_Type_Virtual $
2399 "A":|["B", "C"])
2400 ~?=
2401 "(A:B:C)")
2402 , "[A:B:C]" ~:
2403 ((Ledger.Write.show
2404 Ledger.Write.Style
2405 { Ledger.Write.style_color=False
2406 , Ledger.Write.style_align=True
2407 } $
2408 Ledger.Write.account Ledger.Posting_Type_Virtual_Balanced $
2409 "A":|["B", "C"])
2410 ~?=
2411 "[A:B:C]")
2412 ]
2413 , "transaction" ~: TestList
2414 [ "nil" ~:
2415 ((Ledger.Write.show
2416 Ledger.Write.Style
2417 { Ledger.Write.style_color=False
2418 , Ledger.Write.style_align=True
2419 } $
2420 Ledger.Write.transaction
2421 Amount.Style.styles
2422 Ledger.transaction)
2423 ~?=
2424 "1970/01/01\n\n")
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" ~:
2426 ((Ledger.Write.show
2427 Ledger.Write.Style
2428 { Ledger.Write.style_color=False
2429 , Ledger.Write.style_align=True
2430 } $
2431 Ledger.Write.transaction
2432 Amount.Style.styles
2433 Ledger.transaction
2434 { Ledger.transaction_dates=
2435 ( Time.zonedTimeToUTC $
2436 Time.ZonedTime
2437 (Time.LocalTime
2438 (Time.fromGregorian 2000 01 01)
2439 (Time.TimeOfDay 0 0 0))
2440 (Time.utc)
2441 , [] )
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
2446 [ ("$", 1)
2447 ]
2448 }
2449 , (Ledger.posting ("a":|["b", "c"]))
2450 { Ledger.posting_comments = ["first comment","second comment","third comment"]
2451 }
2452 ]
2453 })
2454 ~?=
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" ~:
2457 ((Ledger.Write.show
2458 Ledger.Write.Style
2459 { Ledger.Write.style_color=False
2460 , Ledger.Write.style_align=True
2461 } $
2462 Ledger.Write.transaction
2463 Amount.Style.styles
2464 Ledger.transaction
2465 { Ledger.transaction_dates=
2466 ( Time.zonedTimeToUTC $
2467 Time.ZonedTime
2468 (Time.LocalTime
2469 (Time.fromGregorian 2000 01 01)
2470 (Time.TimeOfDay 0 0 0))
2471 (Time.utc)
2472 , [] )
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
2477 [ ("$", 1)
2478 ]
2479 }
2480 , (Ledger.posting ("AA":|["BB", "CC"]))
2481 { Ledger.posting_amounts = Data.Map.fromList
2482 [ ("$", 123)
2483 ]
2484 }
2485 ]
2486 })
2487 ~?=
2488 "2000/01/01 some description\n\tA:B:C $1\n\tAA:BB:CC $123\n")
2489 ]
2490 ]
2491 ]
2492 ]
2493 ]