]> Git — Sourcephile - comptalang.git/blob - lib/Test/Main.hs
Ajout : Lib.TreeMap pour Calc.Balance.Expanded
[comptalang.git] / lib / Test / Main.hs
1 {-# LANGUAGE TupleSections #-}
2 {-# LANGUAGE OverloadedStrings #-}
3
4 import Prelude
5 import Test.HUnit
6 import Test.Framework.Providers.HUnit (hUnitTestToTests)
7 import Test.Framework.Runners.Console (defaultMain)
8
9 import Control.Applicative ((<*))
10 import Control.Monad.IO.Class (liftIO)
11 import Data.Decimal (DecimalRaw(..))
12 import qualified Data.Either
13 import qualified Data.List
14 import Data.List.NonEmpty (NonEmpty(..))
15 import qualified Data.Map.Strict as Data.Map
16 import Data.Text (Text)
17 import qualified Data.Time.Calendar as Time
18 import qualified Data.Time.LocalTime as Time
19 import qualified Text.Parsec as P
20 import qualified Text.Parsec.Pos as P
21 -- import qualified Text.PrettyPrint.Leijen.Text as PP
22
23 import qualified Hcompta.Model.Account as Account
24 import qualified Hcompta.Model.Amount as Amount
25 import qualified Hcompta.Model.Amount.Style as Amount.Style
26 import qualified Hcompta.Model.Date as Date
27 import qualified Hcompta.Model.Transaction as Transaction
28 import qualified Hcompta.Model.Transaction.Posting as Posting
29 import qualified Hcompta.Calc.Balance as Calc.Balance
30 import qualified Hcompta.Format.Ledger.Read as Format.Ledger.Read
31 import qualified Hcompta.Format.Ledger.Journal as Format.Ledger.Journal
32 import qualified Hcompta.Format.Ledger.Write as Format.Ledger.Write
33 import qualified Hcompta.Lib.TreeMap as Lib.TreeMap
34
35 --instance Eq Text.Parsec.ParseError where
36 -- (==) = const (const False)
37
38 main :: IO ()
39 main = defaultMain $ hUnitTestToTests test_Hcompta
40
41 test_Hcompta :: Test
42 test_Hcompta =
43 TestList
44 [ "Model" ~: TestList
45 [ "Account" ~: TestList
46 [ "foldr" ~: TestList
47 [ "[A]" ~:
48 (reverse $ Account.foldr ("A":|[]) (:) []) ~?= ["A":|[]]
49 , "[A, B]" ~:
50 (reverse $ Account.foldr ("A":|["B"]) (:) []) ~?= ["A":|[], "A":|["B"]]
51 , "[A, B, C]" ~:
52 (reverse $ Account.foldr ("A":|["B", "C"]) (:) []) ~?= ["A":|[], "A":|["B"], "A":|["B", "C"]]
53 ]
54 , "ascending" ~: TestList
55 [ "[A]" ~:
56 Account.ascending ("A":|[]) ~?= Nothing
57 , "[A, B]" ~:
58 Account.ascending ("A":|["B"]) ~?= Just ("A":|[])
59 , "[A, B, C]" ~:
60 Account.ascending ("A":|["B", "C"]) ~?= Just ("A":|["B"])
61 ]
62 ]
63 , "Amount" ~: TestList
64 [ "+" ~: TestList
65 [ "$1 + 1$ = $2" ~:
66 (+)
67 (Amount.nil
68 { Amount.quantity = Decimal 0 1
69 , Amount.style = Amount.Style.nil
70 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
71 }
72 , Amount.unit = "$"
73 })
74 (Amount.nil
75 { Amount.quantity = Decimal 0 1
76 , Amount.style = Amount.Style.nil
77 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
78 }
79 , Amount.unit = "$"
80 })
81 ~?=
82 (Amount.nil
83 { Amount.quantity = Decimal 0 2
84 , Amount.style = Amount.Style.nil
85 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
86 }
87 , Amount.unit = "$"
88 })
89 ]
90 , "from_List" ~: TestList
91 [ "from_List [$1, 1$] = $2" ~:
92 Amount.from_List
93 [ Amount.nil
94 { Amount.quantity = Decimal 0 1
95 , Amount.style = Amount.Style.nil
96 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
97 }
98 , Amount.unit = "$"
99 }
100 , Amount.nil
101 { Amount.quantity = Decimal 0 1
102 , Amount.style = Amount.Style.nil
103 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
104 }
105 , Amount.unit = "$"
106 }
107 ]
108 ~?=
109 Data.Map.fromList
110 [ ("$", Amount.nil
111 { Amount.quantity = Decimal 0 2
112 , Amount.style = Amount.Style.nil
113 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
114 }
115 , Amount.unit = "$"
116 })
117 ]
118 ]
119 ]
120 ]
121 , "Calc" ~: TestList
122 [ "Balance" ~: TestList
123 [ "posting" ~: TestList
124 [ "[A+$1] = A+$1 & $+1" ~:
125 (Calc.Balance.posting
126 (Posting.nil ("A":|[]))
127 { Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
128 }
129 Calc.Balance.nil)
130 ~?=
131 Calc.Balance.Balance
132 { Calc.Balance.by_account =
133 Lib.TreeMap.from_List const
134 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
135 , Calc.Balance.by_unit =
136 Data.Map.fromList $
137 Data.List.map Calc.Balance.assoc_unit_sum $
138 [ Calc.Balance.Unit_Sum
139 { Calc.Balance.amount = Amount.usd $ 1
140 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
141 ["A":|[]]
142 }
143 ]
144 }
145 , "[A+$1, A-$1] = {A+$0, $+0}" ~:
146 (Data.List.foldl
147 (flip Calc.Balance.posting)
148 Calc.Balance.nil
149 [ (Posting.nil ("A":|[]))
150 { Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
151 }
152 , (Posting.nil ("A":|[]))
153 { Posting.amounts=Amount.from_List [ Amount.usd $ -1 ]
154 }
155 ])
156 ~?=
157 Calc.Balance.Balance
158 { Calc.Balance.by_account =
159 Lib.TreeMap.from_List const
160 [ ("A":|[], Amount.from_List [ Amount.usd $ 0 ]) ]
161 , Calc.Balance.by_unit =
162 Data.Map.fromList $
163 Data.List.map Calc.Balance.assoc_unit_sum $
164 [ Calc.Balance.Unit_Sum
165 { Calc.Balance.amount = Amount.usd $ 0
166 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
167 ["A":|[]]
168 }
169 ]
170 }
171 , "[A+$1, A-€1] = {A+$1-€1, $+1 €-1}" ~:
172 (Data.List.foldl
173 (flip Calc.Balance.posting)
174 Calc.Balance.nil
175 [ (Posting.nil ("A":|[]))
176 { Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
177 }
178 , (Posting.nil ("A":|[]))
179 { Posting.amounts=Amount.from_List [ Amount.eur $ -1 ]
180 }
181 ])
182 ~?=
183 Calc.Balance.Balance
184 { Calc.Balance.by_account =
185 Lib.TreeMap.from_List const
186 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ -1 ]) ]
187 , Calc.Balance.by_unit =
188 Data.Map.fromList $
189 Data.List.map Calc.Balance.assoc_unit_sum $
190 [ Calc.Balance.Unit_Sum
191 { Calc.Balance.amount = Amount.usd $ 1
192 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
193 ["A":|[]]
194 }
195 , Calc.Balance.Unit_Sum
196 { Calc.Balance.amount = Amount.eur $ -1
197 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
198 ["A":|[]]
199 }
200 ]
201 }
202 , "[A+$1, B-$1] = {A+$1 B-$1, $+0}" ~:
203 (Data.List.foldl
204 (flip Calc.Balance.posting)
205 Calc.Balance.nil
206 [ (Posting.nil ("A":|[]))
207 { Posting.amounts=Amount.from_List [ Amount.usd $ 1 ]
208 }
209 , (Posting.nil ("B":|[]))
210 { Posting.amounts=Amount.from_List [ Amount.usd $ -1 ]
211 }
212 ])
213 ~?=
214 Calc.Balance.Balance
215 { Calc.Balance.by_account =
216 Lib.TreeMap.from_List const
217 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
218 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
219 ]
220 , Calc.Balance.by_unit =
221 Data.Map.fromList $
222 Data.List.map Calc.Balance.assoc_unit_sum $
223 [ Calc.Balance.Unit_Sum
224 { Calc.Balance.amount = Amount.usd $ 0
225 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
226 ["A":|[], "B":|[]]
227 }
228 ]
229 }
230 , "[A+$1+€2, A-$1-€2] = {A+$0+€0, $+0 €+0}" ~:
231 (Data.List.foldl
232 (flip Calc.Balance.posting)
233 Calc.Balance.nil
234 [ (Posting.nil ("A":|[]))
235 { Posting.amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2 ]
236 }
237 , (Posting.nil ("A":|[]))
238 { Posting.amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2 ]
239 }
240 ])
241 ~?=
242 Calc.Balance.Balance
243 { Calc.Balance.by_account =
244 Lib.TreeMap.from_List const
245 [ ("A":|[], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
246 ]
247 , Calc.Balance.by_unit =
248 Data.Map.fromList $
249 Data.List.map Calc.Balance.assoc_unit_sum $
250 [ Calc.Balance.Unit_Sum
251 { Calc.Balance.amount = Amount.usd $ 0
252 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
253 ["A":|[]]
254 }
255 , Calc.Balance.Unit_Sum
256 { Calc.Balance.amount = Amount.eur $ 0
257 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
258 ["A":|[]]
259 }
260 ]
261 }
262 , "[A+$1+€2+£3, B-$1-2€-£3] = {A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~:
263 (Data.List.foldl
264 (flip Calc.Balance.posting)
265 Calc.Balance.nil
266 [ (Posting.nil ("A":|[]))
267 { Posting.amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ]
268 }
269 , (Posting.nil ("B":|[]))
270 { Posting.amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ]
271 }
272 ])
273 ~?=
274 Calc.Balance.Balance
275 { Calc.Balance.by_account =
276 Lib.TreeMap.from_List const
277 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
278 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
279 ]
280 , Calc.Balance.by_unit =
281 Data.Map.fromList $
282 Data.List.map Calc.Balance.assoc_unit_sum $
283 [ Calc.Balance.Unit_Sum
284 { Calc.Balance.amount = Amount.usd $ 0
285 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
286 ["A":|[], "B":|[]]
287 }
288 , Calc.Balance.Unit_Sum
289 { Calc.Balance.amount = Amount.eur $ 0
290 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
291 ["A":|[], "B":|[]]
292 }
293 , Calc.Balance.Unit_Sum
294 { Calc.Balance.amount = Amount.gbp $ 0
295 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
296 ["A":|[], "B":|[]]
297 }
298 ]
299 }
300 ]
301 , "union" ~: TestList
302 [ "nil nil = nil" ~:
303 Calc.Balance.union
304 Calc.Balance.nil
305 Calc.Balance.nil
306 ~?=
307 Calc.Balance.nil
308 , "{A+$1, $+1} {A+$1, $+1} = {A+$2, $+2}" ~:
309 Calc.Balance.union
310 (Calc.Balance.Balance
311 { Calc.Balance.by_account =
312 Lib.TreeMap.from_List const
313 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
314 , Calc.Balance.by_unit =
315 Data.Map.fromList $
316 Data.List.map Calc.Balance.assoc_unit_sum $
317 [ Calc.Balance.Unit_Sum
318 { Calc.Balance.amount = Amount.usd $ 1
319 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
320 ["A":|[]]
321 }
322 ]
323 })
324 (Calc.Balance.Balance
325 { Calc.Balance.by_account =
326 Lib.TreeMap.from_List const
327 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
328 , Calc.Balance.by_unit =
329 Data.Map.fromList $
330 Data.List.map Calc.Balance.assoc_unit_sum $
331 [ Calc.Balance.Unit_Sum
332 { Calc.Balance.amount = Amount.usd $ 1
333 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
334 ["A":|[]]
335 }
336 ]
337 })
338 ~?=
339 Calc.Balance.Balance
340 { Calc.Balance.by_account =
341 Lib.TreeMap.from_List const
342 [ ("A":|[], Amount.from_List [ Amount.usd $ 2 ]) ]
343 , Calc.Balance.by_unit =
344 Data.Map.fromList $
345 Data.List.map Calc.Balance.assoc_unit_sum $
346 [ Calc.Balance.Unit_Sum
347 { Calc.Balance.amount = Amount.usd $ 2
348 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
349 ["A":|[]]
350 }
351 ]
352 }
353 , "{A+$1, $+1} {B+$1, $+1} = {A+$1 B+$1, $+2}" ~:
354 Calc.Balance.union
355 (Calc.Balance.Balance
356 { Calc.Balance.by_account =
357 Lib.TreeMap.from_List const
358 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
359 , Calc.Balance.by_unit =
360 Data.Map.fromList $
361 Data.List.map Calc.Balance.assoc_unit_sum $
362 [ Calc.Balance.Unit_Sum
363 { Calc.Balance.amount = Amount.usd $ 1
364 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
365 ["A":|[]]
366 }
367 ]
368 })
369 (Calc.Balance.Balance
370 { Calc.Balance.by_account =
371 Lib.TreeMap.from_List const
372 [ ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
373 , Calc.Balance.by_unit =
374 Data.Map.fromList $
375 Data.List.map Calc.Balance.assoc_unit_sum $
376 [ Calc.Balance.Unit_Sum
377 { Calc.Balance.amount = Amount.usd $ 1
378 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
379 ["B":|[]]
380 }
381 ]
382 })
383 ~?=
384 Calc.Balance.Balance
385 { Calc.Balance.by_account =
386 Lib.TreeMap.from_List const
387 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
388 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
389 , Calc.Balance.by_unit =
390 Data.Map.fromList $
391 Data.List.map Calc.Balance.assoc_unit_sum $
392 [ Calc.Balance.Unit_Sum
393 { Calc.Balance.amount = Amount.usd $ 2
394 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
395 ["A":|[], "B":|[]]
396 }
397 ]
398 }
399 , "{A+$1, $+1} {B+€1, €+1} = {A+$1 B+€1, $+1 €+1}" ~:
400 Calc.Balance.union
401 (Calc.Balance.Balance
402 { Calc.Balance.by_account =
403 Lib.TreeMap.from_List const
404 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
405 , Calc.Balance.by_unit =
406 Data.Map.fromList $
407 Data.List.map Calc.Balance.assoc_unit_sum $
408 [ Calc.Balance.Unit_Sum
409 { Calc.Balance.amount = Amount.usd $ 1
410 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
411 ["A":|[]]
412 }
413 ]
414 })
415 (Calc.Balance.Balance
416 { Calc.Balance.by_account =
417 Lib.TreeMap.from_List const
418 [ ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
419 , Calc.Balance.by_unit =
420 Data.Map.fromList $
421 Data.List.map Calc.Balance.assoc_unit_sum $
422 [ Calc.Balance.Unit_Sum
423 { Calc.Balance.amount = Amount.eur $ 1
424 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
425 ["B":|[]]
426 }
427 ]
428 })
429 ~?=
430 Calc.Balance.Balance
431 { Calc.Balance.by_account =
432 Lib.TreeMap.from_List const
433 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
434 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
435 , Calc.Balance.by_unit =
436 Data.Map.fromList $
437 Data.List.map Calc.Balance.assoc_unit_sum $
438 [ Calc.Balance.Unit_Sum
439 { Calc.Balance.amount = Amount.usd $ 1
440 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
441 ["A":|[]]
442 }
443 , Calc.Balance.Unit_Sum
444 { Calc.Balance.amount = Amount.eur $ 1
445 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
446 ["B":|[]]
447 }
448 ]
449 }
450 ]
451 , "expand" ~: TestList
452 [ "nil_By_Account" ~:
453 Calc.Balance.expand
454 Calc.Balance.nil_By_Account
455 ~?=
456 Lib.TreeMap.empty
457 , "A+$1 = A+$1" ~:
458 Calc.Balance.expand
459 (Lib.TreeMap.from_List const
460 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ])
461 ~?=
462 (Lib.TreeMap.from_List const
463 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
464 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
465 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
466 })
467 ])
468 , "A/A+$1 = A+$1 A/A+$1" ~:
469 Calc.Balance.expand
470 (Lib.TreeMap.from_List const
471 [ ("A":|["A"], Amount.from_List [ Amount.usd $ 1 ]) ])
472 ~?=
473 (Lib.TreeMap.from_List const
474 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
475 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
476 , Calc.Balance.exclusive = Amount.from_List []
477 })
478 , ("A":|["A"], Calc.Balance.Account_Sum_Expanded
479 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
480 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
481 })
482 ])
483 , "A/B+$1 = A+$1 A/B+$1" ~:
484 Calc.Balance.expand
485 (Lib.TreeMap.from_List const
486 [ ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ]) ])
487 ~?=
488 (Lib.TreeMap.from_List const
489 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
490 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
491 , Calc.Balance.exclusive = Amount.from_List []
492 })
493 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
494 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
495 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
496 })
497 ])
498 , "A/B/C+$1 = A+$1 A/B+$1 A/B/C+$1" ~:
499 Calc.Balance.expand
500 (Lib.TreeMap.from_List const
501 [ ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ]) ])
502 ~?=
503 (Lib.TreeMap.from_List const
504 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
505 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
506 , Calc.Balance.exclusive = Amount.from_List []
507 })
508 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
509 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
510 , Calc.Balance.exclusive = Amount.from_List []
511 })
512 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
513 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
514 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
515 })
516 ])
517 , "A+$1 A/B+$1 = A+$2 A/B+$1" ~:
518 Calc.Balance.expand
519 (Lib.TreeMap.from_List const
520 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
521 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
522 ])
523 ~?=
524 (Lib.TreeMap.from_List const
525 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
526 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 2 ]
527 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
528 })
529 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
530 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
531 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
532 })
533 ])
534 , "A+$1 A/B+$1 A/B/C+$1 = A+$3 A/B+$2 A/B/C+$1" ~:
535 Calc.Balance.expand
536 (Lib.TreeMap.from_List const
537 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
538 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
539 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
540 ])
541 ~?=
542 (Lib.TreeMap.from_List const
543 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
544 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 3 ]
545 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
546 })
547 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
548 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 2 ]
549 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
550 })
551 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
552 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
553 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
554 })
555 ])
556 , "A+$1 A/B+$1 A/B/C+$1 A/B/C/D+$1 = A+$4 A/B+$3 A/B/C+$2 A/B/C/D+$1" ~:
557 Calc.Balance.expand
558 (Lib.TreeMap.from_List const
559 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
560 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
561 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
562 , ("A":|["B", "C", "D"], Amount.from_List [ Amount.usd $ 1 ])
563 ])
564 ~?=
565 (Lib.TreeMap.from_List const
566 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
567 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 4 ]
568 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
569 })
570 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
571 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 3 ]
572 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
573 })
574 , ("A":|["B", "C"], Calc.Balance.Account_Sum_Expanded
575 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 2 ]
576 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
577 })
578 , ("A":|["B", "C", "D"], Calc.Balance.Account_Sum_Expanded
579 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
580 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
581 })
582 ])
583 , "A+$1 A/B+$1 A/BB+$1 AA/B+$1 = A+$3 A/B+$1 A/BB+$1 AA+$1 AA/B+$1" ~:
584 Calc.Balance.expand
585 (Lib.TreeMap.from_List const
586 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
587 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
588 , ("A":|["BB"], Amount.from_List [ Amount.usd $ 1 ])
589 , ("AA":|["B"], Amount.from_List [ Amount.usd $ 1 ])
590 ])
591 ~?=
592 (Lib.TreeMap.from_List const
593 [ ("A":|[], Calc.Balance.Account_Sum_Expanded
594 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 3 ]
595 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
596 })
597 , ("A":|["B"], Calc.Balance.Account_Sum_Expanded
598 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
599 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
600 })
601 , ("A":|["BB"], Calc.Balance.Account_Sum_Expanded
602 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
603 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
604 })
605 , ("AA":|[], Calc.Balance.Account_Sum_Expanded
606 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
607 , Calc.Balance.exclusive = Amount.from_List []
608 })
609 , ("AA":|["B"], Calc.Balance.Account_Sum_Expanded
610 { Calc.Balance.inclusive = Amount.from_List [ Amount.usd $ 1 ]
611 , Calc.Balance.exclusive = Amount.from_List [ Amount.usd $ 1 ]
612 })
613 ])
614 ]
615 , "is_equilibrable" ~: TestList
616 [ "nil" ~: TestCase $
617 (@=?) True $
618 Calc.Balance.is_equilibrable $
619 Calc.Balance.equilibre $
620 Calc.Balance.nil
621 , "{A+$0, $+0}" ~: TestCase $
622 (@=?) True $
623 Calc.Balance.is_equilibrable $
624 Calc.Balance.equilibre $
625 Calc.Balance.Balance
626 { Calc.Balance.by_account =
627 Lib.TreeMap.from_List const
628 [ ("A":|[], Amount.from_List [ Amount.usd $ 0 ])
629 ]
630 , Calc.Balance.by_unit =
631 Data.Map.fromList $
632 Data.List.map Calc.Balance.assoc_unit_sum $
633 [ Calc.Balance.Unit_Sum
634 { Calc.Balance.amount = Amount.usd $ 0
635 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
636 ["A":|[]]
637 }
638 ]
639 }
640 , "{A+$1, $+1}" ~: TestCase $
641 (@=?) False $
642 Calc.Balance.is_equilibrable $
643 Calc.Balance.equilibre $
644 Calc.Balance.Balance
645 { Calc.Balance.by_account =
646 Lib.TreeMap.from_List const
647 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
648 ]
649 , Calc.Balance.by_unit =
650 Data.Map.fromList $
651 Data.List.map Calc.Balance.assoc_unit_sum $
652 [ Calc.Balance.Unit_Sum
653 { Calc.Balance.amount = Amount.usd $ 1
654 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
655 ["A":|[]]
656 }
657 ]
658 }
659 , "{A+$0+€0, $0 €+0}" ~: TestCase $
660 (@=?) True $
661 Calc.Balance.is_equilibrable $
662 Calc.Balance.equilibre $
663 Calc.Balance.Balance
664 { Calc.Balance.by_account =
665 Lib.TreeMap.from_List const
666 [ ("A":|[], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
667 ]
668 , Calc.Balance.by_unit =
669 Data.Map.fromList $
670 Data.List.map Calc.Balance.assoc_unit_sum $
671 [ Calc.Balance.Unit_Sum
672 { Calc.Balance.amount = Amount.usd $ 0
673 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
674 ["A":|[]]
675 }
676 , Calc.Balance.Unit_Sum
677 { Calc.Balance.amount = Amount.eur $ 0
678 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
679 ["A":|[]]
680 }
681 ]
682 }
683 , "{A+$1, B-$1, $+0}" ~: TestCase $
684 (@=?) True $
685 Calc.Balance.is_equilibrable $
686 Calc.Balance.equilibre $
687 Calc.Balance.Balance
688 { Calc.Balance.by_account =
689 Lib.TreeMap.from_List const
690 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
691 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
692 ]
693 , Calc.Balance.by_unit =
694 Data.Map.fromList $
695 Data.List.map Calc.Balance.assoc_unit_sum $
696 [ Calc.Balance.Unit_Sum
697 { Calc.Balance.amount = Amount.usd $ 0
698 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
699 ["A":|[], "B":|[]]
700 }
701 ]
702 }
703 , "{A+$1 B, $+1}" ~: TestCase $
704 (@=?) True $
705 Calc.Balance.is_equilibrable $
706 Calc.Balance.equilibre $
707 Calc.Balance.Balance
708 { Calc.Balance.by_account =
709 Lib.TreeMap.from_List const
710 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
711 , ("B":|[], Amount.from_List [])
712 ]
713 , Calc.Balance.by_unit =
714 Data.Map.fromList $
715 Data.List.map Calc.Balance.assoc_unit_sum $
716 [ Calc.Balance.Unit_Sum
717 { Calc.Balance.amount = Amount.usd $ 1
718 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
719 ["A":|[]]
720 }
721 ]
722 }
723 , "{A+$1 B+€1, $+1 €+1}" ~: TestCase $
724 (@=?) True $
725 Calc.Balance.is_equilibrable $
726 Calc.Balance.equilibre $
727 Calc.Balance.Balance
728 { Calc.Balance.by_account =
729 Lib.TreeMap.from_List const
730 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
731 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ])
732 ]
733 , Calc.Balance.by_unit =
734 Data.Map.fromList $
735 Data.List.map Calc.Balance.assoc_unit_sum $
736 [ Calc.Balance.Unit_Sum
737 { Calc.Balance.amount = Amount.usd $ 1
738 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
739 ["A":|[]]
740 }
741 , Calc.Balance.Unit_Sum
742 { Calc.Balance.amount = Amount.eur $ 1
743 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
744 ["B":|[]]
745 }
746 ]
747 }
748 , "{A+$1 B-$1+€1, $+0 €+1}" ~: TestCase $
749 (@=?) True $
750 Calc.Balance.is_equilibrable $
751 Calc.Balance.equilibre $
752 Calc.Balance.Balance
753 { Calc.Balance.by_account =
754 Lib.TreeMap.from_List const
755 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
756 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ 1 ])
757 ]
758 , Calc.Balance.by_unit =
759 Data.Map.fromList $
760 Data.List.map Calc.Balance.assoc_unit_sum $
761 [ Calc.Balance.Unit_Sum
762 { Calc.Balance.amount = Amount.usd $ 0
763 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
764 ["A":|[], "B":|[]]
765 }
766 , Calc.Balance.Unit_Sum
767 { Calc.Balance.amount = Amount.eur $ 1
768 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
769 ["B":|[]]
770 }
771 ]
772 }
773 , "{A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~: TestCase $
774 (@=?) True $
775 Calc.Balance.is_equilibrable $
776 Calc.Balance.equilibre $
777 Calc.Balance.Balance
778 { Calc.Balance.by_account =
779 Lib.TreeMap.from_List const
780 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
781 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
782 ]
783 , Calc.Balance.by_unit =
784 Data.Map.fromList $
785 Data.List.map Calc.Balance.assoc_unit_sum $
786 [ Calc.Balance.Unit_Sum
787 { Calc.Balance.amount = Amount.usd $ 0
788 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
789 ["A":|[], "B":|[]]
790 }
791 , Calc.Balance.Unit_Sum
792 { Calc.Balance.amount = Amount.eur $ 0
793 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
794 ["A":|[], "B":|[]]
795 }
796 , Calc.Balance.Unit_Sum
797 { Calc.Balance.amount = Amount.gbp $ 0
798 , Calc.Balance.accounts = Data.Map.fromList $ Data.List.map (,())
799 ["A":|[], "B":|[]]
800 }
801 ]
802 }
803 ]
804 ]
805 ]
806 , "Format" ~: TestList
807 [ "Ledger" ~: TestList
808 [ "Read" ~: TestList
809 [ "account_name" ~: TestList
810 [ "\"\" = Left" ~:
811 (Data.Either.rights $
812 [P.runParser
813 (Format.Ledger.Read.account_name <* P.eof)
814 () "" (""::Text)])
815 ~?=
816 []
817 , "\"A\" = Right \"A\"" ~:
818 (Data.Either.rights $
819 [P.runParser
820 (Format.Ledger.Read.account_name <* P.eof)
821 () "" ("A"::Text)])
822 ~?=
823 ["A"]
824 , "\"AA\" = Right \"AA\"" ~:
825 (Data.Either.rights $
826 [P.runParser
827 (Format.Ledger.Read.account_name <* P.eof)
828 () "" ("AA"::Text)])
829 ~?=
830 ["AA"]
831 , "\" \" = Left" ~:
832 (Data.Either.rights $
833 [P.runParser
834 (Format.Ledger.Read.account_name <* P.eof)
835 () "" (" "::Text)])
836 ~?=
837 []
838 , "\":\" = Left" ~:
839 (Data.Either.rights $
840 [P.runParser
841 (Format.Ledger.Read.account_name <* P.eof)
842 () "" (":"::Text)])
843 ~?=
844 []
845 , "\"A:\" = Left" ~:
846 (Data.Either.rights $
847 [P.runParser
848 (Format.Ledger.Read.account_name <* P.eof)
849 () "" ("A:"::Text)])
850 ~?=
851 []
852 , "\":A\" = Left" ~:
853 (Data.Either.rights $
854 [P.runParser
855 (Format.Ledger.Read.account_name <* P.eof)
856 () "" (":A"::Text)])
857 ~?=
858 []
859 , "\"A \" = Left" ~:
860 (Data.Either.rights $
861 [P.runParser
862 (Format.Ledger.Read.account_name <* P.eof)
863 () "" ("A "::Text)])
864 ~?=
865 []
866 , "\"A \" ^= Right" ~:
867 (Data.Either.rights $
868 [P.runParser
869 (Format.Ledger.Read.account_name)
870 () "" ("A "::Text)])
871 ~?=
872 ["A"]
873 , "\"A A\" = Right \"A A\"" ~:
874 (Data.Either.rights $
875 [P.runParser
876 (Format.Ledger.Read.account_name <* P.eof)
877 () "" ("A A"::Text)])
878 ~?=
879 ["A A"]
880 , "\"A \" = Left" ~:
881 (Data.Either.rights $
882 [P.runParser
883 (Format.Ledger.Read.account_name <* P.eof)
884 () "" ("A "::Text)])
885 ~?=
886 []
887 , "\"A \\n\" = Left" ~:
888 (Data.Either.rights $
889 [P.runParser
890 (Format.Ledger.Read.account_name <* P.eof)
891 () "" ("A \n"::Text)])
892 ~?=
893 []
894 , "\"(A)A\" = Right \"(A)A\"" ~:
895 (Data.Either.rights $
896 [P.runParser
897 (Format.Ledger.Read.account_name <* P.eof)
898 () "" ("(A)A"::Text)])
899 ~?=
900 ["(A)A"]
901 , "\"( )A\" = Right \"( )A\"" ~:
902 (Data.Either.rights $
903 [P.runParser
904 (Format.Ledger.Read.account_name <* P.eof)
905 () "" ("( )A"::Text)])
906 ~?=
907 ["( )A"]
908 , "\"(A) A\" = Right \"(A) A\"" ~:
909 (Data.Either.rights $
910 [P.runParser
911 (Format.Ledger.Read.account_name <* P.eof)
912 () "" ("(A) A"::Text)])
913 ~?=
914 ["(A) A"]
915 , "\"[ ]A\" = Right \"[ ]A\"" ~:
916 (Data.Either.rights $
917 [P.runParser
918 (Format.Ledger.Read.account_name <* P.eof)
919 () "" ("[ ]A"::Text)])
920 ~?=
921 ["[ ]A"]
922 , "\"(A) \" = Left" ~:
923 (Data.Either.rights $
924 [P.runParser
925 (Format.Ledger.Read.account_name <* P.eof)
926 () "" ("(A) "::Text)])
927 ~?=
928 []
929 , "\"(A)\" = Left" ~:
930 (Data.Either.rights $
931 [P.runParser
932 (Format.Ledger.Read.account_name <* P.eof)
933 () "" ("(A)"::Text)])
934 ~?=
935 []
936 , "\"[A]A\" = Right \"(A)A\"" ~:
937 (Data.Either.rights $
938 [P.runParser
939 (Format.Ledger.Read.account_name <* P.eof)
940 () "" ("[A]A"::Text)])
941 ~?=
942 ["[A]A"]
943 , "\"[A] A\" = Right \"[A] A\"" ~:
944 (Data.Either.rights $
945 [P.runParser
946 (Format.Ledger.Read.account_name <* P.eof)
947 () "" ("[A] A"::Text)])
948 ~?=
949 ["[A] A"]
950 , "\"[A] \" = Left" ~:
951 (Data.Either.rights $
952 [P.runParser
953 (Format.Ledger.Read.account_name <* P.eof)
954 () "" ("[A] "::Text)])
955 ~?=
956 []
957 , "\"[A]\" = Left" ~:
958 (Data.Either.rights $
959 [P.runParser
960 (Format.Ledger.Read.account_name <* P.eof)
961 () "" ("[A]"::Text)])
962 ~?=
963 []
964 ]
965 , "account" ~: TestList
966 [ "\"\" = Left" ~:
967 (Data.Either.rights $
968 [P.runParser
969 (Format.Ledger.Read.account <* P.eof)
970 () "" (""::Text)])
971 ~?=
972 []
973 , "\"A\" = Right [\"A\"]" ~:
974 (Data.Either.rights $
975 [P.runParser
976 (Format.Ledger.Read.account <* P.eof)
977 () "" ("A"::Text)])
978 ~?=
979 ["A":|[]]
980 , "\"A:\" = Left" ~:
981 (Data.Either.rights $
982 [P.runParser
983 (Format.Ledger.Read.account <* P.eof)
984 () "" ("A:"::Text)])
985 ~?=
986 []
987 , "\":A\" = Left" ~:
988 (Data.Either.rights $
989 [P.runParser
990 (Format.Ledger.Read.account <* P.eof)
991 () "" (":A"::Text)])
992 ~?=
993 []
994 , "\"A \" = Left" ~:
995 (Data.Either.rights $
996 [P.runParser
997 (Format.Ledger.Read.account <* P.eof)
998 () "" ("A "::Text)])
999 ~?=
1000 []
1001 , "\" A\" = Left" ~:
1002 (Data.Either.rights $
1003 [P.runParser
1004 (Format.Ledger.Read.account <* P.eof)
1005 () "" (" A"::Text)])
1006 ~?=
1007 []
1008 , "\"A:B\" = Right [\"A\", \"B\"]" ~:
1009 (Data.Either.rights $
1010 [P.runParser
1011 (Format.Ledger.Read.account <* P.eof)
1012 () "" ("A:B"::Text)])
1013 ~?=
1014 ["A":|["B"]]
1015 , "\"A:B:C\" = Right [\"A\", \"B\", \"C\"]" ~:
1016 (Data.Either.rights $
1017 [P.runParser
1018 (Format.Ledger.Read.account <* P.eof)
1019 () "" ("A:B:C"::Text)])
1020 ~?=
1021 ["A":|["B", "C"]]
1022 , "\"Aa:Bbb:Cccc\" = Right [\"Aa\", \"Bbb\", \":Cccc\"]" ~:
1023 (Data.Either.rights $
1024 [P.runParser
1025 (Format.Ledger.Read.account <* P.eof)
1026 () "" ("Aa:Bbb:Cccc"::Text)])
1027 ~?=
1028 ["Aa":|["Bbb", "Cccc"]]
1029 , "\"A a : B b b : C c c c\" = Right [\"A a \", \" B b b \", \": C c c c\"]" ~:
1030 (Data.Either.rights $
1031 [P.runParser
1032 (Format.Ledger.Read.account <* P.eof)
1033 () "" ("A a : B b b : C c c c"::Text)])
1034 ~?=
1035 ["A a ":|[" B b b ", " C c c c"]]
1036 , "\"A: :C\" = Right [\"A\", \" \", \"C\"]" ~:
1037 (Data.Either.rights $
1038 [P.runParser
1039 (Format.Ledger.Read.account <* P.eof)
1040 () "" ("A: :C"::Text)])
1041 ~?=
1042 ["A":|[" ", "C"]]
1043 , "\"A::C\" = Left" ~:
1044 (Data.Either.rights $
1045 [P.runParser
1046 (Format.Ledger.Read.account <* P.eof)
1047 () "" ("A::C"::Text)])
1048 ~?=
1049 []
1050 ]
1051 , "amount" ~: TestList
1052 [ "\"\" = Left" ~:
1053 (Data.Either.rights $
1054 [P.runParser
1055 (Format.Ledger.Read.amount <* P.eof)
1056 () "" (""::Text)])
1057 ~?=
1058 []
1059 , "\"0\" = Right 0" ~:
1060 (Data.Either.rights $
1061 [P.runParser
1062 (Format.Ledger.Read.amount <* P.eof)
1063 () "" ("0"::Text)])
1064 ~?=
1065 [Amount.nil
1066 { Amount.quantity = Decimal 0 0
1067 }]
1068 , "\"00\" = Right 0" ~:
1069 (Data.Either.rights $
1070 [P.runParser
1071 (Format.Ledger.Read.amount <* P.eof)
1072 () "" ("00"::Text)])
1073 ~?=
1074 [Amount.nil
1075 { Amount.quantity = Decimal 0 0
1076 }]
1077 , "\"0.\" = Right 0." ~:
1078 (Data.Either.rights $
1079 [P.runParser
1080 (Format.Ledger.Read.amount <* P.eof)
1081 () "" ("0."::Text)])
1082 ~?=
1083 [Amount.nil
1084 { Amount.quantity = Decimal 0 0
1085 , Amount.style =
1086 Amount.Style.nil
1087 { Amount.Style.fractioning = Just '.'
1088 }
1089 }]
1090 , "\".0\" = Right 0.0" ~:
1091 (Data.Either.rights $
1092 [P.runParser
1093 (Format.Ledger.Read.amount <* P.eof)
1094 () "" (".0"::Text)])
1095 ~?=
1096 [Amount.nil
1097 { Amount.quantity = Decimal 0 0
1098 , Amount.style =
1099 Amount.Style.nil
1100 { Amount.Style.fractioning = Just '.'
1101 , Amount.Style.precision = 1
1102 }
1103 }]
1104 , "\"0,\" = Right 0," ~:
1105 (Data.Either.rights $
1106 [P.runParser
1107 (Format.Ledger.Read.amount <* P.eof)
1108 () "" ("0,"::Text)])
1109 ~?=
1110 [Amount.nil
1111 { Amount.quantity = Decimal 0 0
1112 , Amount.style =
1113 Amount.Style.nil
1114 { Amount.Style.fractioning = Just ','
1115 }
1116 }]
1117 , "\",0\" = Right 0,0" ~:
1118 (Data.Either.rights $
1119 [P.runParser
1120 (Format.Ledger.Read.amount <* P.eof)
1121 () "" (",0"::Text)])
1122 ~?=
1123 [Amount.nil
1124 { Amount.quantity = Decimal 0 0
1125 , Amount.style =
1126 Amount.Style.nil
1127 { Amount.Style.fractioning = Just ','
1128 , Amount.Style.precision = 1
1129 }
1130 }]
1131 , "\"0_\" = Left" ~:
1132 (Data.Either.rights $
1133 [P.runParser
1134 (Format.Ledger.Read.amount <* P.eof)
1135 () "" ("0_"::Text)])
1136 ~?=
1137 []
1138 , "\"_0\" = Left" ~:
1139 (Data.Either.rights $
1140 [P.runParser
1141 (Format.Ledger.Read.amount <* P.eof)
1142 () "" ("_0"::Text)])
1143 ~?=
1144 []
1145 , "\"0.0\" = Right 0.0" ~:
1146 (Data.Either.rights $
1147 [P.runParser
1148 (Format.Ledger.Read.amount <* P.eof)
1149 () "" ("0.0"::Text)])
1150 ~?=
1151 [Amount.nil
1152 { Amount.quantity = Decimal 0 0
1153 , Amount.style =
1154 Amount.Style.nil
1155 { Amount.Style.fractioning = Just '.'
1156 , Amount.Style.precision = 1
1157 }
1158 }]
1159 , "\"00.00\" = Right 0.00" ~:
1160 (Data.Either.rights $
1161 [P.runParser
1162 (Format.Ledger.Read.amount <* P.eof)
1163 () "" ("00.00"::Text)])
1164 ~?=
1165 [Amount.nil
1166 { Amount.quantity = Decimal 0 0
1167 , Amount.style =
1168 Amount.Style.nil
1169 { Amount.Style.fractioning = Just '.'
1170 , Amount.Style.precision = 2
1171 }
1172 }]
1173 , "\"0,0\" = Right 0,0" ~:
1174 (Data.Either.rights $
1175 [P.runParser
1176 (Format.Ledger.Read.amount <* P.eof)
1177 () "" ("0,0"::Text)])
1178 ~?=
1179 [Amount.nil
1180 { Amount.quantity = Decimal 0 0
1181 , Amount.style =
1182 Amount.Style.nil
1183 { Amount.Style.fractioning = Just ','
1184 , Amount.Style.precision = 1
1185 }
1186 }]
1187 , "\"00,00\" = Right 0,00" ~:
1188 (Data.Either.rights $
1189 [P.runParser
1190 (Format.Ledger.Read.amount <* P.eof)
1191 () "" ("00,00"::Text)])
1192 ~?=
1193 [Amount.nil
1194 { Amount.quantity = Decimal 0 0
1195 , Amount.style =
1196 Amount.Style.nil
1197 { Amount.Style.fractioning = Just ','
1198 , Amount.Style.precision = 2
1199 }
1200 }]
1201 , "\"0_0\" = Right 0" ~:
1202 (Data.Either.rights $
1203 [P.runParser
1204 (Format.Ledger.Read.amount <* P.eof)
1205 () "" ("0_0"::Text)])
1206 ~?=
1207 [Amount.nil
1208 { Amount.quantity = Decimal 0 0
1209 , Amount.style =
1210 Amount.Style.nil
1211 { Amount.Style.fractioning = Nothing
1212 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
1213 , Amount.Style.precision = 0
1214 }
1215 }]
1216 , "\"00_00\" = Right 0" ~:
1217 (Data.Either.rights $
1218 [P.runParser
1219 (Format.Ledger.Read.amount <* P.eof)
1220 () "" ("00_00"::Text)])
1221 ~?=
1222 [Amount.nil
1223 { Amount.quantity = Decimal 0 0
1224 , Amount.style =
1225 Amount.Style.nil
1226 { Amount.Style.fractioning = Nothing
1227 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
1228 , Amount.Style.precision = 0
1229 }
1230 }]
1231 , "\"0,000.00\" = Right 0,000.00" ~:
1232 (Data.Either.rights $
1233 [P.runParser
1234 (Format.Ledger.Read.amount <* P.eof)
1235 () "" ("0,000.00"::Text)])
1236 ~?=
1237 [Amount.nil
1238 { Amount.quantity = Decimal 0 0
1239 , Amount.style =
1240 Amount.Style.nil
1241 { Amount.Style.fractioning = Just '.'
1242 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
1243 , Amount.Style.precision = 2
1244 }
1245 }]
1246 , "\"0.000,00\" = Right 0.000,00" ~:
1247 (Data.Either.rights $
1248 [P.runParser
1249 (Format.Ledger.Read.amount)
1250 () "" ("0.000,00"::Text)])
1251 ~?=
1252 [Amount.nil
1253 { Amount.quantity = Decimal 0 0
1254 , Amount.style =
1255 Amount.Style.nil
1256 { Amount.Style.fractioning = Just ','
1257 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
1258 , Amount.Style.precision = 2
1259 }
1260 }]
1261 , "\"1,000.00\" = Right 1,000.00" ~:
1262 (Data.Either.rights $
1263 [P.runParser
1264 (Format.Ledger.Read.amount <* P.eof)
1265 () "" ("1,000.00"::Text)])
1266 ~?=
1267 [Amount.nil
1268 { Amount.quantity = Decimal 0 1000
1269 , Amount.style =
1270 Amount.Style.nil
1271 { Amount.Style.fractioning = Just '.'
1272 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
1273 , Amount.Style.precision = 2
1274 }
1275 }]
1276 , "\"1.000,00\" = Right 1.000,00" ~:
1277 (Data.Either.rights $
1278 [P.runParser
1279 (Format.Ledger.Read.amount)
1280 () "" ("1.000,00"::Text)])
1281 ~?=
1282 [Amount.nil
1283 { Amount.quantity = Decimal 0 1000
1284 , Amount.style =
1285 Amount.Style.nil
1286 { Amount.Style.fractioning = Just ','
1287 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
1288 , Amount.Style.precision = 2
1289 }
1290 }]
1291 , "\"1,000.00.\" = Left" ~:
1292 (Data.Either.rights $
1293 [P.runParser
1294 (Format.Ledger.Read.amount)
1295 () "" ("1,000.00."::Text)])
1296 ~?=
1297 []
1298 , "\"1.000,00,\" = Left" ~:
1299 (Data.Either.rights $
1300 [P.runParser
1301 (Format.Ledger.Read.amount)
1302 () "" ("1.000,00,"::Text)])
1303 ~?=
1304 []
1305 , "\"1,000.00_\" = Left" ~:
1306 (Data.Either.rights $
1307 [P.runParser
1308 (Format.Ledger.Read.amount)
1309 () "" ("1,000.00_"::Text)])
1310 ~?=
1311 []
1312 , "\"12\" = Right 12" ~:
1313 (Data.Either.rights $
1314 [P.runParser
1315 (Format.Ledger.Read.amount <* P.eof)
1316 () "" ("123"::Text)])
1317 ~?=
1318 [Amount.nil
1319 { Amount.quantity = Decimal 0 123
1320 }]
1321 , "\"1.2\" = Right 1.2" ~:
1322 (Data.Either.rights $
1323 [P.runParser
1324 (Format.Ledger.Read.amount <* P.eof)
1325 () "" ("1.2"::Text)])
1326 ~?=
1327 [Amount.nil
1328 { Amount.quantity = Decimal 1 12
1329 , Amount.style =
1330 Amount.Style.nil
1331 { Amount.Style.fractioning = Just '.'
1332 , Amount.Style.precision = 1
1333 }
1334 }]
1335 , "\"1,2\" = Right 1,2" ~:
1336 (Data.Either.rights $
1337 [P.runParser
1338 (Format.Ledger.Read.amount <* P.eof)
1339 () "" ("1,2"::Text)])
1340 ~?=
1341 [Amount.nil
1342 { Amount.quantity = Decimal 1 12
1343 , Amount.style =
1344 Amount.Style.nil
1345 { Amount.Style.fractioning = Just ','
1346 , Amount.Style.precision = 1
1347 }
1348 }]
1349 , "\"12.23\" = Right 12.23" ~:
1350 (Data.Either.rights $
1351 [P.runParser
1352 (Format.Ledger.Read.amount <* P.eof)
1353 () "" ("12.34"::Text)])
1354 ~?=
1355 [Amount.nil
1356 { Amount.quantity = Decimal 2 1234
1357 , Amount.style =
1358 Amount.Style.nil
1359 { Amount.Style.fractioning = Just '.'
1360 , Amount.Style.precision = 2
1361 }
1362 }]
1363 , "\"12,23\" = Right 12,23" ~:
1364 (Data.Either.rights $
1365 [P.runParser
1366 (Format.Ledger.Read.amount <* P.eof)
1367 () "" ("12,34"::Text)])
1368 ~?=
1369 [Amount.nil
1370 { Amount.quantity = Decimal 2 1234
1371 , Amount.style =
1372 Amount.Style.nil
1373 { Amount.Style.fractioning = Just ','
1374 , Amount.Style.precision = 2
1375 }
1376 }]
1377 , "\"1_2\" = Right 1_2" ~:
1378 (Data.Either.rights $
1379 [P.runParser
1380 (Format.Ledger.Read.amount <* P.eof)
1381 () "" ("1_2"::Text)])
1382 ~?=
1383 [Amount.nil
1384 { Amount.quantity = Decimal 0 12
1385 , Amount.style =
1386 Amount.Style.nil
1387 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
1388 , Amount.Style.precision = 0
1389 }
1390 }]
1391 , "\"1_23\" = Right 1_23" ~:
1392 (Data.Either.rights $
1393 [P.runParser
1394 (Format.Ledger.Read.amount <* P.eof)
1395 () "" ("1_23"::Text)])
1396 ~?=
1397 [Amount.nil
1398 { Amount.quantity = Decimal 0 123
1399 , Amount.style =
1400 Amount.Style.nil
1401 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
1402 , Amount.Style.precision = 0
1403 }
1404 }]
1405 , "\"1_23_456\" = Right 1_23_456" ~:
1406 (Data.Either.rights $
1407 [P.runParser
1408 (Format.Ledger.Read.amount <* P.eof)
1409 () "" ("1_23_456"::Text)])
1410 ~?=
1411 [Amount.nil
1412 { Amount.quantity = Decimal 0 123456
1413 , Amount.style =
1414 Amount.Style.nil
1415 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
1416 , Amount.Style.precision = 0
1417 }
1418 }]
1419 , "\"1_23_456.7890_12345_678901\" = Right 1_23_456.7890_12345_678901" ~:
1420 (Data.Either.rights $
1421 [P.runParser
1422 (Format.Ledger.Read.amount <* P.eof)
1423 () "" ("1_23_456.7890_12345_678901"::Text)])
1424 ~?=
1425 [Amount.nil
1426 { Amount.quantity = Decimal 15 123456789012345678901
1427 , Amount.style =
1428 Amount.Style.nil
1429 { Amount.Style.fractioning = Just '.'
1430 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
1431 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [4, 5, 6]
1432 , Amount.Style.precision = 15
1433 }
1434 }]
1435 , "\"123456_78901_2345.678_90_1\" = Right 123456_78901_2345.678_90_1" ~:
1436 (Data.Either.rights $
1437 [P.runParser
1438 (Format.Ledger.Read.amount <* P.eof)
1439 () "" ("123456_78901_2345.678_90_1"::Text)])
1440 ~?=
1441 [Amount.nil
1442 { Amount.quantity = Decimal 6 123456789012345678901
1443 , Amount.style =
1444 Amount.Style.nil
1445 { Amount.Style.fractioning = Just '.'
1446 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [4, 5, 6]
1447 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [3, 2]
1448 , Amount.Style.precision = 6
1449 }
1450 }]
1451 , "\"$1\" = Right $1" ~:
1452 (Data.Either.rights $
1453 [P.runParser
1454 (Format.Ledger.Read.amount <* P.eof)
1455 () "" ("$1"::Text)])
1456 ~?=
1457 [Amount.nil
1458 { Amount.quantity = Decimal 0 1
1459 , Amount.style =
1460 Amount.Style.nil
1461 { Amount.Style.fractioning = Nothing
1462 , Amount.Style.grouping_integral = Nothing
1463 , Amount.Style.grouping_fractional = Nothing
1464 , Amount.Style.precision = 0
1465 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1466 , Amount.Style.unit_spaced = Just False
1467 }
1468 , Amount.unit = "$"
1469 }]
1470 , "\"1$\" = Right 1$" ~:
1471 (Data.Either.rights $
1472 [P.runParser
1473 (Format.Ledger.Read.amount <* P.eof)
1474 () "" ("1$"::Text)])
1475 ~?=
1476 [Amount.nil
1477 { Amount.quantity = Decimal 0 1
1478 , Amount.style =
1479 Amount.Style.nil
1480 { Amount.Style.fractioning = Nothing
1481 , Amount.Style.grouping_integral = Nothing
1482 , Amount.Style.grouping_fractional = Nothing
1483 , Amount.Style.precision = 0
1484 , Amount.Style.unit_side = Just Amount.Style.Side_Right
1485 , Amount.Style.unit_spaced = Just False
1486 }
1487 , Amount.unit = "$"
1488 }]
1489 , "\"$ 1\" = Right $ 1" ~:
1490 (Data.Either.rights $
1491 [P.runParser
1492 (Format.Ledger.Read.amount <* P.eof)
1493 () "" ("$ 1"::Text)])
1494 ~?=
1495 [Amount.nil
1496 { Amount.quantity = Decimal 0 1
1497 , Amount.style =
1498 Amount.Style.nil
1499 { Amount.Style.fractioning = Nothing
1500 , Amount.Style.grouping_integral = Nothing
1501 , Amount.Style.grouping_fractional = Nothing
1502 , Amount.Style.precision = 0
1503 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1504 , Amount.Style.unit_spaced = Just True
1505 }
1506 , Amount.unit = "$"
1507 }]
1508 , "\"1 $\" = Right 1 $" ~:
1509 (Data.Either.rights $
1510 [P.runParser
1511 (Format.Ledger.Read.amount <* P.eof)
1512 () "" ("1 $"::Text)])
1513 ~?=
1514 [Amount.nil
1515 { Amount.quantity = Decimal 0 1
1516 , Amount.style =
1517 Amount.Style.nil
1518 { Amount.Style.fractioning = Nothing
1519 , Amount.Style.grouping_integral = Nothing
1520 , Amount.Style.grouping_fractional = Nothing
1521 , Amount.Style.precision = 0
1522 , Amount.Style.unit_side = Just Amount.Style.Side_Right
1523 , Amount.Style.unit_spaced = Just True
1524 }
1525 , Amount.unit = "$"
1526 }]
1527 , "\"-$1\" = Right $-1" ~:
1528 (Data.Either.rights $
1529 [P.runParser
1530 (Format.Ledger.Read.amount <* P.eof)
1531 () "" ("-$1"::Text)])
1532 ~?=
1533 [Amount.nil
1534 { Amount.quantity = Decimal 0 (-1)
1535 , Amount.style =
1536 Amount.Style.nil
1537 { Amount.Style.fractioning = Nothing
1538 , Amount.Style.grouping_integral = Nothing
1539 , Amount.Style.grouping_fractional = Nothing
1540 , Amount.Style.precision = 0
1541 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1542 , Amount.Style.unit_spaced = Just False
1543 }
1544 , Amount.unit = "$"
1545 }]
1546 , "\"\\\"4 2\\\"1\" = Right \\\"4 2\\\"1" ~:
1547 (Data.Either.rights $
1548 [P.runParser
1549 (Format.Ledger.Read.amount <* P.eof)
1550 () "" ("\"4 2\"1"::Text)])
1551 ~?=
1552 [Amount.nil
1553 { Amount.quantity = Decimal 0 1
1554 , Amount.style =
1555 Amount.Style.nil
1556 { Amount.Style.fractioning = Nothing
1557 , Amount.Style.grouping_integral = Nothing
1558 , Amount.Style.grouping_fractional = Nothing
1559 , Amount.Style.precision = 0
1560 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1561 , Amount.Style.unit_spaced = Just False
1562 }
1563 , Amount.unit = "4 2"
1564 }]
1565 , "\"1\\\"4 2\\\"\" = Right 1\\\"4 2\\\"" ~:
1566 (Data.Either.rights $
1567 [P.runParser
1568 (Format.Ledger.Read.amount <* P.eof)
1569 () "" ("1\"4 2\""::Text)])
1570 ~?=
1571 [Amount.nil
1572 { Amount.quantity = Decimal 0 1
1573 , Amount.style =
1574 Amount.Style.nil
1575 { Amount.Style.fractioning = Nothing
1576 , Amount.Style.grouping_integral = Nothing
1577 , Amount.Style.grouping_fractional = Nothing
1578 , Amount.Style.precision = 0
1579 , Amount.Style.unit_side = Just Amount.Style.Side_Right
1580 , Amount.Style.unit_spaced = Just False
1581 }
1582 , Amount.unit = "4 2"
1583 }]
1584 , "\"$1.000,00\" = Right $1.000,00" ~:
1585 (Data.Either.rights $
1586 [P.runParser
1587 (Format.Ledger.Read.amount <* P.eof)
1588 () "" ("$1.000,00"::Text)])
1589 ~?=
1590 [Amount.nil
1591 { Amount.quantity = Decimal 0 1000
1592 , Amount.style =
1593 Amount.Style.nil
1594 { Amount.Style.fractioning = Just ','
1595 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
1596 , Amount.Style.grouping_fractional = Nothing
1597 , Amount.Style.precision = 2
1598 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1599 , Amount.Style.unit_spaced = Just False
1600 }
1601 , Amount.unit = "$"
1602 }]
1603 , "\"1.000,00$\" = Right 1.000,00$" ~:
1604 (Data.Either.rights $
1605 [P.runParser
1606 (Format.Ledger.Read.amount <* P.eof)
1607 () "" ("1.000,00$"::Text)])
1608 ~?=
1609 [Amount.nil
1610 { Amount.quantity = Decimal 0 1000
1611 , Amount.style =
1612 Amount.Style.nil
1613 { Amount.Style.fractioning = Just ','
1614 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
1615 , Amount.Style.grouping_fractional = Nothing
1616 , Amount.Style.precision = 2
1617 , Amount.Style.unit_side = Just Amount.Style.Side_Right
1618 , Amount.Style.unit_spaced = Just False
1619 }
1620 , Amount.unit = "$"
1621 }]
1622 ]
1623 , "comment" ~: TestList
1624 [ "; some comment = Right \" some comment\"" ~:
1625 (Data.Either.rights $
1626 [P.runParser
1627 (Format.Ledger.Read.comment <* P.eof)
1628 () "" ("; some comment"::Text)])
1629 ~?=
1630 [ " some comment" ]
1631 , "; some comment \\n = Right \" some comment \"" ~:
1632 (Data.Either.rights $
1633 [P.runParser
1634 (Format.Ledger.Read.comment <* P.newline <* P.eof)
1635 () "" ("; some comment \n"::Text)])
1636 ~?=
1637 [ " some comment " ]
1638 , "; some comment \\r\\n = Right \" some comment \"" ~:
1639 (Data.Either.rights $
1640 [P.runParser
1641 (Format.Ledger.Read.comment <* P.string "\r\n" <* P.eof)
1642 () "" ("; some comment \r\n"::Text)])
1643 ~?=
1644 [ " some comment " ]
1645 ]
1646 , "comments" ~: TestList
1647 [ "; some comment\\n ; some other comment = Right [\" some comment\", \" some other comment\"]" ~:
1648 (Data.Either.rights $
1649 [P.runParser
1650 (Format.Ledger.Read.comments <* P.eof)
1651 () "" ("; some comment\n ; some other comment"::Text)])
1652 ~?=
1653 [ [" some comment", " some other comment"] ]
1654 , "; some comment \\n = Right \" some comment \"" ~:
1655 (Data.Either.rights $
1656 [P.runParser
1657 (Format.Ledger.Read.comments <* P.string "\n" <* P.eof)
1658 () "" ("; some comment \n"::Text)])
1659 ~?=
1660 [ [" some comment "] ]
1661 ]
1662 , "date" ~: TestList
1663 [ "2000/01/01" ~:
1664 (Data.Either.rights $
1665 [P.runParser
1666 (Format.Ledger.Read.date Nothing <* P.eof)
1667 () "" ("2000/01/01"::Text)])
1668 ~?=
1669 [ Time.ZonedTime
1670 (Time.LocalTime
1671 (Time.fromGregorian 2000 01 01)
1672 (Time.TimeOfDay 0 0 0))
1673 (Time.utc)]
1674 , "2000/01/01 some text" ~:
1675 (Data.Either.rights $
1676 [P.runParser
1677 (Format.Ledger.Read.date Nothing)
1678 () "" ("2000/01/01 some text"::Text)])
1679 ~?=
1680 [ Time.ZonedTime
1681 (Time.LocalTime
1682 (Time.fromGregorian 2000 01 01)
1683 (Time.TimeOfDay 0 0 0))
1684 (Time.utc)]
1685 , "2000/01/01 12:34" ~:
1686 (Data.Either.rights $
1687 [P.runParser
1688 (Format.Ledger.Read.date Nothing <* P.eof)
1689 () "" ("2000/01/01 12:34"::Text)])
1690 ~?=
1691 [ Time.ZonedTime
1692 (Time.LocalTime
1693 (Time.fromGregorian 2000 01 01)
1694 (Time.TimeOfDay 12 34 0))
1695 (Time.utc)]
1696 , "2000/01/01 12:34:56" ~:
1697 (Data.Either.rights $
1698 [P.runParser
1699 (Format.Ledger.Read.date Nothing <* P.eof)
1700 () "" ("2000/01/01 12:34:56"::Text)])
1701 ~?=
1702 [ Time.ZonedTime
1703 (Time.LocalTime
1704 (Time.fromGregorian 2000 01 01)
1705 (Time.TimeOfDay 12 34 56))
1706 (Time.utc)]
1707 , "2000/01/01 12:34 CET" ~:
1708 (Data.Either.rights $
1709 [P.runParser
1710 (Format.Ledger.Read.date Nothing <* P.eof)
1711 () "" ("2000/01/01 12:34 CET"::Text)])
1712 ~?=
1713 [ Time.ZonedTime
1714 (Time.LocalTime
1715 (Time.fromGregorian 2000 01 01)
1716 (Time.TimeOfDay 12 34 0))
1717 (Time.TimeZone 60 True "CET")]
1718 , "2000/01/01 12:34 +0130" ~:
1719 (Data.Either.rights $
1720 [P.runParser
1721 (Format.Ledger.Read.date Nothing <* P.eof)
1722 () "" ("2000/01/01 12:34 +0130"::Text)])
1723 ~?=
1724 [ Time.ZonedTime
1725 (Time.LocalTime
1726 (Time.fromGregorian 2000 01 01)
1727 (Time.TimeOfDay 12 34 0))
1728 (Time.TimeZone 90 False "+0130")]
1729 , "2000/01/01 12:34:56 CET" ~:
1730 (Data.Either.rights $
1731 [P.runParser
1732 (Format.Ledger.Read.date Nothing <* P.eof)
1733 () "" ("2000/01/01 12:34:56 CET"::Text)])
1734 ~?=
1735 [ Time.ZonedTime
1736 (Time.LocalTime
1737 (Time.fromGregorian 2000 01 01)
1738 (Time.TimeOfDay 12 34 56))
1739 (Time.TimeZone 60 True "CET")]
1740 , "2001/02/29" ~:
1741 (Data.Either.rights $
1742 [P.runParser
1743 (Format.Ledger.Read.date Nothing <* P.eof)
1744 () "" ("2001/02/29"::Text)])
1745 ~?=
1746 []
1747 , "01/01" ~:
1748 (Data.Either.rights $
1749 [P.runParser
1750 (Format.Ledger.Read.date (Just 2000) <* P.eof)
1751 () "" ("01/01"::Text)])
1752 ~?=
1753 [ Time.ZonedTime
1754 (Time.LocalTime
1755 (Time.fromGregorian 2000 01 01)
1756 (Time.TimeOfDay 0 0 0))
1757 (Time.utc)]
1758 ]
1759 , "tag_value" ~: TestList
1760 [ "," ~:
1761 (Data.Either.rights $
1762 [P.runParser
1763 (Format.Ledger.Read.tag_value <* P.eof)
1764 () "" (","::Text)])
1765 ~?=
1766 [","]
1767 , ",\\n" ~:
1768 (Data.Either.rights $
1769 [P.runParser
1770 (Format.Ledger.Read.tag_value <* P.char '\n' <* P.eof)
1771 () "" (",\n"::Text)])
1772 ~?=
1773 [","]
1774 , ",x" ~:
1775 (Data.Either.rights $
1776 [P.runParser
1777 (Format.Ledger.Read.tag_value <* P.eof)
1778 () "" (",x"::Text)])
1779 ~?=
1780 [",x"]
1781 , ",x:" ~:
1782 (Data.Either.rights $
1783 [P.runParser
1784 (Format.Ledger.Read.tag_value <* P.string ",x:" <* P.eof)
1785 () "" (",x:"::Text)])
1786 ~?=
1787 [""]
1788 , "v, v, n:" ~:
1789 (Data.Either.rights $
1790 [P.runParser
1791 (Format.Ledger.Read.tag_value <* P.string ", n:" <* P.eof)
1792 () "" ("v, v, n:"::Text)])
1793 ~?=
1794 ["v, v"]
1795 ]
1796 , "tag" ~: TestList
1797 [ "Name:" ~:
1798 (Data.Either.rights $
1799 [P.runParser
1800 (Format.Ledger.Read.tag <* P.eof)
1801 () "" ("Name:"::Text)])
1802 ~?=
1803 [("Name", "")]
1804 , "Name:Value" ~:
1805 (Data.Either.rights $
1806 [P.runParser
1807 (Format.Ledger.Read.tag <* P.eof)
1808 () "" ("Name:Value"::Text)])
1809 ~?=
1810 [("Name", "Value")]
1811 , "Name:Value\\n" ~:
1812 (Data.Either.rights $
1813 [P.runParser
1814 (Format.Ledger.Read.tag <* P.string "\n" <* P.eof)
1815 () "" ("Name:Value\n"::Text)])
1816 ~?=
1817 [("Name", "Value")]
1818 , "Name:Val ue" ~:
1819 (Data.Either.rights $
1820 [P.runParser
1821 (Format.Ledger.Read.tag <* P.eof)
1822 () "" ("Name:Val ue"::Text)])
1823 ~?=
1824 [("Name", "Val ue")]
1825 , "Name:," ~:
1826 (Data.Either.rights $
1827 [P.runParser
1828 (Format.Ledger.Read.tag <* P.eof)
1829 () "" ("Name:,"::Text)])
1830 ~?=
1831 [("Name", ",")]
1832 , "Name:Val,ue" ~:
1833 (Data.Either.rights $
1834 [P.runParser
1835 (Format.Ledger.Read.tag <* P.eof)
1836 () "" ("Name:Val,ue"::Text)])
1837 ~?=
1838 [("Name", "Val,ue")]
1839 , "Name:Val,ue:" ~:
1840 (Data.Either.rights $
1841 [P.runParser
1842 (Format.Ledger.Read.tag <* P.string ",ue:" <* P.eof)
1843 () "" ("Name:Val,ue:"::Text)])
1844 ~?=
1845 [("Name", "Val")]
1846 ]
1847 , "tags" ~: TestList
1848 [ "Name:" ~:
1849 (Data.Either.rights $
1850 [P.runParser
1851 (Format.Ledger.Read.tags <* P.eof)
1852 () "" ("Name:"::Text)])
1853 ~?=
1854 [Data.Map.fromList
1855 [ ("Name", [""])
1856 ]
1857 ]
1858 , "Name:," ~:
1859 (Data.Either.rights $
1860 [P.runParser
1861 (Format.Ledger.Read.tags <* P.eof)
1862 () "" ("Name:,"::Text)])
1863 ~?=
1864 [Data.Map.fromList
1865 [ ("Name", [","])
1866 ]
1867 ]
1868 , "Name:,Name:" ~:
1869 (Data.Either.rights $
1870 [P.runParser
1871 (Format.Ledger.Read.tags <* P.eof)
1872 () "" ("Name:,Name:"::Text)])
1873 ~?=
1874 [Data.Map.fromList
1875 [ ("Name", ["", ""])
1876 ]
1877 ]
1878 , "Name:,Name2:" ~:
1879 (Data.Either.rights $
1880 [P.runParser
1881 (Format.Ledger.Read.tags <* P.eof)
1882 () "" ("Name:,Name2:"::Text)])
1883 ~?=
1884 [Data.Map.fromList
1885 [ ("Name", [""])
1886 , ("Name2", [""])
1887 ]
1888 ]
1889 , "Name: , Name2:" ~:
1890 (Data.Either.rights $
1891 [P.runParser
1892 (Format.Ledger.Read.tags <* P.eof)
1893 () "" ("Name: , Name2:"::Text)])
1894 ~?=
1895 [Data.Map.fromList
1896 [ ("Name", [" "])
1897 , ("Name2", [""])
1898 ]
1899 ]
1900 , "Name:,Name2:,Name3:" ~:
1901 (Data.Either.rights $
1902 [P.runParser
1903 (Format.Ledger.Read.tags <* P.eof)
1904 () "" ("Name:,Name2:,Name3:"::Text)])
1905 ~?=
1906 [Data.Map.fromList
1907 [ ("Name", [""])
1908 , ("Name2", [""])
1909 , ("Name3", [""])
1910 ]
1911 ]
1912 , "Name:Val ue,Name2:V a l u e,Name3:V al ue" ~:
1913 (Data.Either.rights $
1914 [P.runParser
1915 (Format.Ledger.Read.tags <* P.eof)
1916 () "" ("Name:Val ue,Name2:V a l u e,Name3:V al ue"::Text)])
1917 ~?=
1918 [Data.Map.fromList
1919 [ ("Name", ["Val ue"])
1920 , ("Name2", ["V a l u e"])
1921 , ("Name3", ["V al ue"])
1922 ]
1923 ]
1924 ]
1925 , "posting" ~: TestList
1926 [ " A:B:C = Right A:B:C" ~:
1927 (Data.Either.rights $
1928 [P.runParser
1929 (Format.Ledger.Read.posting <* P.eof)
1930 Format.Ledger.Read.nil_Context "" (" A:B:C"::Text)])
1931 ~?=
1932 [ ( (Posting.nil ("A":|["B", "C"]))
1933 { Posting.sourcepos = P.newPos "" 1 1
1934 }
1935 , Posting.Type_Regular
1936 )
1937 ]
1938 , " !A:B:C = Right !A:B:C" ~:
1939 (Data.List.map fst $
1940 Data.Either.rights $
1941 [P.runParser
1942 (Format.Ledger.Read.posting <* P.eof)
1943 Format.Ledger.Read.nil_Context "" (" !A:B:C"::Text)])
1944 ~?=
1945 [ (Posting.nil ("A":|["B", "C"]))
1946 { Posting.sourcepos = P.newPos "" 1 1
1947 , Posting.status = True
1948 }
1949 ]
1950 , " *A:B:C = Right *A:B:C" ~:
1951 (Data.List.map fst $
1952 Data.Either.rights $
1953 [P.runParser
1954 (Format.Ledger.Read.posting <* P.eof)
1955 Format.Ledger.Read.nil_Context "" (" *A:B:C"::Text)])
1956 ~?=
1957 [ (Posting.nil ("A":|["B", "C"]))
1958 { Posting.amounts = Data.Map.fromList []
1959 , Posting.comments = []
1960 , Posting.dates = []
1961 , Posting.status = True
1962 , Posting.sourcepos = P.newPos "" 1 1
1963 , Posting.tags = Data.Map.fromList []
1964 }
1965 ]
1966 , " A:B:C $1 = Right A:B:C $1" ~:
1967 (Data.List.map fst $
1968 Data.Either.rights $
1969 [P.runParser
1970 (Format.Ledger.Read.posting <* P.eof)
1971 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
1972 ~?=
1973 [ (Posting.nil ("A":|["B","C $1"]))
1974 { Posting.sourcepos = P.newPos "" 1 1
1975 }
1976 ]
1977 , " A:B:C $1 = Right A:B:C $1" ~:
1978 (Data.List.map fst $
1979 Data.Either.rights $
1980 [P.runParser
1981 (Format.Ledger.Read.posting <* P.eof)
1982 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
1983 ~?=
1984 [ (Posting.nil ("A":|["B", "C"]))
1985 { Posting.amounts = Data.Map.fromList
1986 [ ("$", Amount.nil
1987 { Amount.quantity = 1
1988 , Amount.style = Amount.Style.nil
1989 { Amount.Style.unit_side = Just Amount.Style.Side_Left
1990 , Amount.Style.unit_spaced = Just False
1991 }
1992 , Amount.unit = "$"
1993 })
1994 ]
1995 , Posting.sourcepos = P.newPos "" 1 1
1996 }
1997 ]
1998 , " A:B:C $1 + 1€ = Right A:B:C $1 + 1€" ~:
1999 (Data.List.map fst $
2000 Data.Either.rights $
2001 [P.runParser
2002 (Format.Ledger.Read.posting <* P.eof)
2003 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1€"::Text)])
2004 ~?=
2005 [ (Posting.nil ("A":|["B", "C"]))
2006 { Posting.amounts = Data.Map.fromList
2007 [ ("$", Amount.nil
2008 { Amount.quantity = 1
2009 , Amount.style = Amount.Style.nil
2010 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2011 , Amount.Style.unit_spaced = Just False
2012 }
2013 , Amount.unit = "$"
2014 })
2015 , ("€", Amount.nil
2016 { Amount.quantity = 1
2017 , Amount.style = Amount.Style.nil
2018 { Amount.Style.unit_side = Just Amount.Style.Side_Right
2019 , Amount.Style.unit_spaced = Just False
2020 }
2021 , Amount.unit = "€"
2022 })
2023 ]
2024 , Posting.sourcepos = P.newPos "" 1 1
2025 }
2026 ]
2027 , " A:B:C $1 + 1$ = Right A:B:C $2" ~:
2028 (Data.List.map fst $
2029 Data.Either.rights $
2030 [P.runParser
2031 (Format.Ledger.Read.posting <* P.eof)
2032 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$"::Text)])
2033 ~?=
2034 [ (Posting.nil ("A":|["B", "C"]))
2035 { Posting.amounts = Data.Map.fromList
2036 [ ("$", Amount.nil
2037 { Amount.quantity = 2
2038 , Amount.style = Amount.Style.nil
2039 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2040 , Amount.Style.unit_spaced = Just False
2041 }
2042 , Amount.unit = "$"
2043 })
2044 ]
2045 , Posting.sourcepos = P.newPos "" 1 1
2046 }
2047 ]
2048 , " A:B:C $1 + 1$ + 1$ = Right A:B:C $3" ~:
2049 (Data.List.map fst $
2050 Data.Either.rights $
2051 [P.runParser
2052 (Format.Ledger.Read.posting <* P.eof)
2053 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$ + 1$"::Text)])
2054 ~?=
2055 [ (Posting.nil ("A":|["B", "C"]))
2056 { Posting.amounts = Data.Map.fromList
2057 [ ("$", Amount.nil
2058 { Amount.quantity = 3
2059 , Amount.style = Amount.Style.nil
2060 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2061 , Amount.Style.unit_spaced = Just False
2062 }
2063 , Amount.unit = "$"
2064 })
2065 ]
2066 , Posting.sourcepos = P.newPos "" 1 1
2067 }
2068 ]
2069 , " A:B:C ; some comment = Right A:B:C ; some comment" ~:
2070 (Data.List.map fst $
2071 Data.Either.rights $
2072 [P.runParser
2073 (Format.Ledger.Read.posting <* P.eof)
2074 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment"::Text)])
2075 ~?=
2076 [ (Posting.nil ("A":|["B", "C"]))
2077 { Posting.amounts = Data.Map.fromList []
2078 , Posting.comments = [" some comment"]
2079 , Posting.sourcepos = P.newPos "" 1 1
2080 }
2081 ]
2082 , " A:B:C ; some comment\\n ; some other comment = Right A:B:C ; some comment\\n ; some other comment" ~:
2083 (Data.List.map fst $
2084 Data.Either.rights $
2085 [P.runParser
2086 (Format.Ledger.Read.posting <* P.eof)
2087 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment\n ; some other comment"::Text)])
2088 ~?=
2089 [ (Posting.nil ("A":|["B", "C"]))
2090 { Posting.amounts = Data.Map.fromList []
2091 , Posting.comments = [" some comment", " some other comment"]
2092 , Posting.sourcepos = P.newPos "" 1 1
2093 }
2094 ]
2095 , " A:B:C $1 ; some comment = Right A:B:C $1 ; some comment" ~:
2096 (Data.List.map fst $
2097 Data.Either.rights $
2098 [P.runParser
2099 (Format.Ledger.Read.posting)
2100 Format.Ledger.Read.nil_Context "" (" A:B:C $1 ; some comment"::Text)])
2101 ~?=
2102 [ (Posting.nil ("A":|["B", "C"]))
2103 { Posting.amounts = Data.Map.fromList
2104 [ ("$", Amount.nil
2105 { Amount.quantity = 1
2106 , Amount.style = Amount.Style.nil
2107 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2108 , Amount.Style.unit_spaced = Just False
2109 }
2110 , Amount.unit = "$"
2111 })
2112 ]
2113 , Posting.comments = [" some comment"]
2114 , Posting.sourcepos = P.newPos "" 1 1
2115 }
2116 ]
2117 , " A:B:C ; N:V = Right A:B:C ; N:V" ~:
2118 (Data.List.map fst $
2119 Data.Either.rights $
2120 [P.runParser
2121 (Format.Ledger.Read.posting <* P.eof)
2122 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V"::Text)])
2123 ~?=
2124 [ (Posting.nil ("A":|["B", "C"]))
2125 { Posting.comments = [" N:V"]
2126 , Posting.sourcepos = P.newPos "" 1 1
2127 , Posting.tags = Data.Map.fromList
2128 [ ("N", ["V"])
2129 ]
2130 }
2131 ]
2132 , " A:B:C ; some comment N:V = Right A:B:C ; some comment N:V" ~:
2133 (Data.List.map fst $
2134 Data.Either.rights $
2135 [P.runParser
2136 (Format.Ledger.Read.posting <* P.eof)
2137 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V"::Text)])
2138 ~?=
2139 [ (Posting.nil ("A":|["B", "C"]))
2140 { Posting.comments = [" some comment N:V"]
2141 , Posting.sourcepos = P.newPos "" 1 1
2142 , Posting.tags = Data.Map.fromList
2143 [ ("N", ["V"])
2144 ]
2145 }
2146 ]
2147 , " A:B:C ; some comment N:V v, N2:V2 v2 = Right A:B:C ; some comment N:V v, N2:V2 v2" ~:
2148 (Data.List.map fst $
2149 Data.Either.rights $
2150 [P.runParser
2151 (Format.Ledger.Read.posting )
2152 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V v, N2:V2 v2"::Text)])
2153 ~?=
2154 [ (Posting.nil ("A":|["B", "C"]))
2155 { Posting.comments = [" some comment N:V v, N2:V2 v2"]
2156 , Posting.sourcepos = P.newPos "" 1 1
2157 , Posting.tags = Data.Map.fromList
2158 [ ("N", ["V v"])
2159 , ("N2", ["V2 v2"])
2160 ]
2161 }
2162 ]
2163 , " A:B:C ; N:V\\n ; N:V2 = Right A:B:C ; N:V\\n ; N:V2" ~:
2164 (Data.List.map fst $
2165 Data.Either.rights $
2166 [P.runParser
2167 (Format.Ledger.Read.posting <* P.eof)
2168 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N:V2"::Text)])
2169 ~?=
2170 [ (Posting.nil ("A":|["B", "C"]))
2171 { Posting.comments = [" N:V", " N:V2"]
2172 , Posting.sourcepos = P.newPos "" 1 1
2173 , Posting.tags = Data.Map.fromList
2174 [ ("N", ["V", "V2"])
2175 ]
2176 }
2177 ]
2178 , " A:B:C ; N:V\\n ; N2:V = Right A:B:C ; N:V\\n ; N2:V" ~:
2179 (Data.List.map fst $
2180 Data.Either.rights $
2181 [P.runParser
2182 (Format.Ledger.Read.posting <* P.eof)
2183 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N2:V"::Text)])
2184 ~?=
2185 [ (Posting.nil ("A":|["B", "C"]))
2186 { Posting.comments = [" N:V", " N2:V"]
2187 , Posting.sourcepos = P.newPos "" 1 1
2188 , Posting.tags = Data.Map.fromList
2189 [ ("N", ["V"])
2190 , ("N2", ["V"])
2191 ]
2192 }
2193 ]
2194 , " A:B:C ; date:2001/01/01 = Right A:B:C ; date:2001/01/01" ~:
2195 (Data.List.map fst $
2196 Data.Either.rights $
2197 [P.runParser
2198 (Format.Ledger.Read.posting <* P.eof)
2199 Format.Ledger.Read.nil_Context "" (" A:B:C ; date:2001/01/01"::Text)])
2200 ~?=
2201 [ (Posting.nil ("A":|["B", "C"]))
2202 { Posting.comments = [" date:2001/01/01"]
2203 , Posting.dates =
2204 [ Time.ZonedTime
2205 (Time.LocalTime
2206 (Time.fromGregorian 2001 01 01)
2207 (Time.TimeOfDay 0 0 0))
2208 Time.utc
2209 ]
2210 , Posting.sourcepos = P.newPos "" 1 1
2211 , Posting.tags = Data.Map.fromList
2212 [ ("date", ["2001/01/01"])
2213 ]
2214 }
2215 ]
2216 , " (A:B:C) = Right (A:B:C)" ~:
2217 (Data.Either.rights $
2218 [P.runParser
2219 (Format.Ledger.Read.posting <* P.eof)
2220 Format.Ledger.Read.nil_Context "" (" (A:B:C)"::Text)])
2221 ~?=
2222 [ ( (Posting.nil ("A":|["B", "C"]))
2223 { Posting.sourcepos = P.newPos "" 1 1
2224 }
2225 , Posting.Type_Virtual
2226 )
2227 ]
2228 , " [A:B:C] = Right [A:B:C]" ~:
2229 (Data.Either.rights $
2230 [P.runParser
2231 (Format.Ledger.Read.posting <* P.eof)
2232 Format.Ledger.Read.nil_Context "" (" [A:B:C]"::Text)])
2233 ~?=
2234 [ ( (Posting.nil ("A":|["B", "C"]))
2235 { Posting.sourcepos = P.newPos "" 1 1
2236 }
2237 , Posting.Type_Virtual_Balanced
2238 )
2239 ]
2240 ]
2241 , "transaction" ~: TestList
2242 [ "2000/01/01 some description\\n A:B:C $1\\n a:b:c" ~:
2243 (Data.Either.rights $
2244 [P.runParser
2245 (Format.Ledger.Read.transaction <* P.eof)
2246 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c"::Text)])
2247 ~?=
2248 [ Transaction.nil
2249 { Transaction.dates=
2250 ( Time.ZonedTime
2251 (Time.LocalTime
2252 (Time.fromGregorian 2000 01 01)
2253 (Time.TimeOfDay 0 0 0))
2254 (Time.utc)
2255 , [] )
2256 , Transaction.description="some description"
2257 , Transaction.postings = Posting.from_List
2258 [ (Posting.nil ("A":|["B", "C"]))
2259 { Posting.amounts = Data.Map.fromList
2260 [ ("$", Amount.nil
2261 { Amount.quantity = 1
2262 , Amount.style = Amount.Style.nil
2263 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2264 , Amount.Style.unit_spaced = Just False
2265 }
2266 , Amount.unit = "$"
2267 })
2268 ]
2269 , Posting.sourcepos = P.newPos "" 2 1
2270 }
2271 , (Posting.nil ("a":|["b", "c"]))
2272 { Posting.sourcepos = P.newPos "" 3 1
2273 }
2274 ]
2275 , Transaction.sourcepos = P.newPos "" 1 1
2276 }
2277 ]
2278 , "2000/01/01 some description\\n A:B:C $1\\n a:b:c\\n" ~:
2279 (Data.Either.rights $
2280 [P.runParser
2281 (Format.Ledger.Read.transaction <* P.newline <* P.eof)
2282 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c\n"::Text)])
2283 ~?=
2284 [ Transaction.nil
2285 { Transaction.dates=
2286 ( Time.ZonedTime
2287 (Time.LocalTime
2288 (Time.fromGregorian 2000 01 01)
2289 (Time.TimeOfDay 0 0 0))
2290 (Time.utc)
2291 , [] )
2292 , Transaction.description="some description"
2293 , Transaction.postings = Posting.from_List
2294 [ (Posting.nil ("A":|["B", "C"]))
2295 { Posting.amounts = Data.Map.fromList
2296 [ ("$", Amount.nil
2297 { Amount.quantity = 1
2298 , Amount.style = Amount.Style.nil
2299 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2300 , Amount.Style.unit_spaced = Just False
2301 }
2302 , Amount.unit = "$"
2303 })
2304 ]
2305 , Posting.sourcepos = P.newPos "" 2 1
2306 }
2307 , (Posting.nil ("a":|["b", "c"]))
2308 { Posting.sourcepos = P.newPos "" 3 1
2309 }
2310 ]
2311 , Transaction.sourcepos = P.newPos "" 1 1
2312 }
2313 ]
2314 , "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" ~:
2315 (Data.Either.rights $
2316 [P.runParser
2317 (Format.Ledger.Read.transaction <* P.eof)
2318 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description ; some comment\n ; some other;comment\n ; some Tag:\n ; some last comment\n A:B:C $1\n a:b:c"::Text)])
2319 ~?=
2320 [ Transaction.nil
2321 { Transaction.comments_after =
2322 [ " some comment"
2323 , " some other;comment"
2324 , " some Tag:"
2325 , " some last comment"
2326 ]
2327 , Transaction.dates=
2328 ( Time.ZonedTime
2329 (Time.LocalTime
2330 (Time.fromGregorian 2000 01 01)
2331 (Time.TimeOfDay 0 0 0))
2332 (Time.utc)
2333 , [] )
2334 , Transaction.description="some description"
2335 , Transaction.postings = Posting.from_List
2336 [ (Posting.nil ("A":|["B", "C"]))
2337 { Posting.amounts = Data.Map.fromList
2338 [ ("$", Amount.nil
2339 { Amount.quantity = 1
2340 , Amount.style = Amount.Style.nil
2341 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2342 , Amount.Style.unit_spaced = Just False
2343 }
2344 , Amount.unit = "$"
2345 })
2346 ]
2347 , Posting.sourcepos = P.newPos "" 5 1
2348 }
2349 , (Posting.nil ("a":|["b", "c"]))
2350 { Posting.sourcepos = P.newPos "" 6 1
2351 , Posting.tags = Data.Map.fromList []
2352 }
2353 ]
2354 , Transaction.sourcepos = P.newPos "" 1 1
2355 , Transaction.tags = Data.Map.fromList
2356 [ ("Tag", [""])
2357 ]
2358 }
2359 ]
2360 ]
2361 , "journal" ~: TestList
2362 [ "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
2363 jnl <- liftIO $
2364 P.runParserT
2365 (Format.Ledger.Read.journal "" {-<* P.eof-})
2366 Format.Ledger.Read.nil_Context "" ("2000/01/01 1° description\n A:B:C $1\n a:b:c\n2000/01/02 2° description\n A:B:C $1\n x:y:z"::Text)
2367 (Data.List.map
2368 (\j -> j{Format.Ledger.Journal.last_read_time=
2369 Format.Ledger.Journal.last_read_time Format.Ledger.Journal.nil}) $
2370 Data.Either.rights [jnl])
2371 @?=
2372 [ Format.Ledger.Journal.nil
2373 { Format.Ledger.Journal.transactions = Transaction.from_List
2374 [ Transaction.nil
2375 { Transaction.dates=
2376 ( Time.ZonedTime
2377 (Time.LocalTime
2378 (Time.fromGregorian 2000 01 01)
2379 (Time.TimeOfDay 0 0 0))
2380 (Time.utc)
2381 , [] )
2382 , Transaction.description="1° description"
2383 , Transaction.postings = Posting.from_List
2384 [ (Posting.nil ("A":|["B", "C"]))
2385 { Posting.amounts = Data.Map.fromList
2386 [ ("$", Amount.nil
2387 { Amount.quantity = 1
2388 , Amount.style = Amount.Style.nil
2389 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2390 , Amount.Style.unit_spaced = Just False
2391 }
2392 , Amount.unit = "$"
2393 })
2394 ]
2395 , Posting.sourcepos = P.newPos "" 2 1
2396 }
2397 , (Posting.nil ("a":|["b", "c"]))
2398 { Posting.sourcepos = P.newPos "" 3 1
2399 }
2400 ]
2401 , Transaction.sourcepos = P.newPos "" 1 1
2402 }
2403 , Transaction.nil
2404 { Transaction.dates=
2405 ( Time.ZonedTime
2406 (Time.LocalTime
2407 (Time.fromGregorian 2000 01 02)
2408 (Time.TimeOfDay 0 0 0))
2409 (Time.utc)
2410 , [] )
2411 , Transaction.description="2° description"
2412 , Transaction.postings = Posting.from_List
2413 [ (Posting.nil ("A":|["B", "C"]))
2414 { Posting.amounts = Data.Map.fromList
2415 [ ("$", Amount.nil
2416 { Amount.quantity = 1
2417 , Amount.style = Amount.Style.nil
2418 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2419 , Amount.Style.unit_spaced = Just False
2420 }
2421 , Amount.unit = "$"
2422 })
2423 ]
2424 , Posting.sourcepos = P.newPos "" 5 1
2425 }
2426 , (Posting.nil ("x":|["y", "z"]))
2427 { Posting.sourcepos = P.newPos "" 6 1
2428 }
2429 ]
2430 , Transaction.sourcepos = P.newPos "" 4 1
2431 }
2432 ]
2433 }
2434 ]
2435 ]
2436 ]
2437 , "Write" ~: TestList
2438 [ "account" ~: TestList
2439 [ "A" ~:
2440 ((Format.Ledger.Write.show False $
2441 Format.Ledger.Write.account Posting.Type_Regular $
2442 "A":|[])
2443 ~?=
2444 "A")
2445 , "A:B:C" ~:
2446 ((Format.Ledger.Write.show False $
2447 Format.Ledger.Write.account Posting.Type_Regular $
2448 "A":|["B", "C"])
2449 ~?=
2450 "A:B:C")
2451 , "(A:B:C)" ~:
2452 ((Format.Ledger.Write.show False $
2453 Format.Ledger.Write.account Posting.Type_Virtual $
2454 "A":|["B", "C"])
2455 ~?=
2456 "(A:B:C)")
2457 , "[A:B:C]" ~:
2458 ((Format.Ledger.Write.show False $
2459 Format.Ledger.Write.account Posting.Type_Virtual_Balanced $
2460 "A":|["B", "C"])
2461 ~?=
2462 "[A:B:C]")
2463 ]
2464 , "amount" ~: TestList
2465 [ "nil" ~:
2466 ((Format.Ledger.Write.show False $
2467 Format.Ledger.Write.amount
2468 Amount.nil)
2469 ~?=
2470 "0")
2471 , "nil @ prec=2" ~:
2472 ((Format.Ledger.Write.show False $
2473 Format.Ledger.Write.amount
2474 Amount.nil
2475 { Amount.style = Amount.Style.nil
2476 { Amount.Style.precision = 2 }
2477 })
2478 ~?=
2479 "0.00")
2480 , "123" ~:
2481 ((Format.Ledger.Write.show False $
2482 Format.Ledger.Write.amount
2483 Amount.nil
2484 { Amount.quantity = Decimal 0 123
2485 })
2486 ~?=
2487 "123")
2488 , "-123" ~:
2489 ((Format.Ledger.Write.show False $
2490 Format.Ledger.Write.amount
2491 Amount.nil
2492 { Amount.quantity = Decimal 0 (- 123)
2493 })
2494 ~?=
2495 "-123")
2496 , "12.3 @ prec=0" ~:
2497 ((Format.Ledger.Write.show False $
2498 Format.Ledger.Write.amount
2499 Amount.nil
2500 { Amount.quantity = Decimal 1 123
2501 , Amount.style = Amount.Style.nil
2502 { Amount.Style.fractioning = Just '.'
2503 }
2504 })
2505 ~?=
2506 "12")
2507 , "12.5 @ prec=0" ~:
2508 ((Format.Ledger.Write.show False $
2509 Format.Ledger.Write.amount
2510 Amount.nil
2511 { Amount.quantity = Decimal 1 125
2512 , Amount.style = Amount.Style.nil
2513 { Amount.Style.fractioning = Just '.'
2514 }
2515 })
2516 ~?=
2517 "13")
2518 , "12.3 @ prec=1" ~:
2519 ((Format.Ledger.Write.show False $
2520 Format.Ledger.Write.amount
2521 Amount.nil
2522 { Amount.quantity = Decimal 1 123
2523 , Amount.style = Amount.Style.nil
2524 { Amount.Style.fractioning = Just '.'
2525 , Amount.Style.precision = 1
2526 }
2527 })
2528 ~?=
2529 "12.3")
2530 , "1,234.56 @ prec=2" ~:
2531 ((Format.Ledger.Write.show False $
2532 Format.Ledger.Write.amount
2533 Amount.nil
2534 { Amount.quantity = Decimal 2 123456
2535 , Amount.style = Amount.Style.nil
2536 { Amount.Style.fractioning = Just '.'
2537 , Amount.Style.precision = 2
2538 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
2539 }
2540 })
2541 ~?=
2542 "1,234.56")
2543 , "123,456,789,01,2.3456789 @ prec=7" ~:
2544 ((Format.Ledger.Write.show False $
2545 Format.Ledger.Write.amount
2546 Amount.nil
2547 { Amount.quantity = Decimal 7 1234567890123456789
2548 , Amount.style = Amount.Style.nil
2549 { Amount.Style.fractioning = Just '.'
2550 , Amount.Style.precision = 7
2551 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
2552 }
2553 })
2554 ~?=
2555 "123,456,789,01,2.3456789")
2556 , "1234567.8,90,123,456,789 @ prec=12" ~:
2557 ((Format.Ledger.Write.show False $
2558 Format.Ledger.Write.amount
2559 Amount.nil
2560 { Amount.quantity = Decimal 12 1234567890123456789
2561 , Amount.style = Amount.Style.nil
2562 { Amount.Style.fractioning = Just '.'
2563 , Amount.Style.precision = 12
2564 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
2565 }
2566 })
2567 ~?=
2568 "1234567.8,90,123,456,789")
2569 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
2570 ((Format.Ledger.Write.show False $
2571 Format.Ledger.Write.amount
2572 Amount.nil
2573 { Amount.quantity = Decimal 7 1234567890123456789
2574 , Amount.style = Amount.Style.nil
2575 { Amount.Style.fractioning = Just '.'
2576 , Amount.Style.precision = 7
2577 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
2578 }
2579 })
2580 ~?=
2581 "1,2,3,4,5,6,7,89,012.3456789")
2582 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
2583 ((Format.Ledger.Write.show False $
2584 Format.Ledger.Write.amount
2585 Amount.nil
2586 { Amount.quantity = Decimal 12 1234567890123456789
2587 , Amount.style = Amount.Style.nil
2588 { Amount.Style.fractioning = Just '.'
2589 , Amount.Style.precision = 12
2590 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
2591 }
2592 })
2593 ~?=
2594 "1234567.890,12,3,4,5,6,7,8,9")
2595 ]
2596 , "amount_length" ~: TestList
2597 [ "nil" ~:
2598 ((Format.Ledger.Write.amount_length
2599 Amount.nil)
2600 ~?=
2601 1)
2602 , "nil @ prec=2" ~:
2603 ((Format.Ledger.Write.amount_length
2604 Amount.nil
2605 { Amount.style = Amount.Style.nil
2606 { Amount.Style.precision = 2 }
2607 })
2608 ~?=
2609 4)
2610 , "123" ~:
2611 ((Format.Ledger.Write.amount_length
2612 Amount.nil
2613 { Amount.quantity = Decimal 0 123
2614 })
2615 ~?=
2616 3)
2617 , "-123" ~:
2618 ((Format.Ledger.Write.amount_length
2619 Amount.nil
2620 { Amount.quantity = Decimal 0 (- 123)
2621 })
2622 ~?=
2623 4)
2624 , "12.3 @ prec=0" ~:
2625 ((Format.Ledger.Write.amount_length
2626 Amount.nil
2627 { Amount.quantity = Decimal 1 123
2628 , Amount.style = Amount.Style.nil
2629 { Amount.Style.fractioning = Just '.'
2630 }
2631 })
2632 ~?=
2633 2)
2634 , "12.5 @ prec=0" ~:
2635 ((Format.Ledger.Write.amount_length
2636 Amount.nil
2637 { Amount.quantity = Decimal 1 125
2638 , Amount.style = Amount.Style.nil
2639 { Amount.Style.fractioning = Just '.'
2640 }
2641 })
2642 ~?=
2643 2)
2644 , "12.3 @ prec=1" ~:
2645 ((Format.Ledger.Write.amount_length
2646 Amount.nil
2647 { Amount.quantity = Decimal 1 123
2648 , Amount.style = Amount.Style.nil
2649 { Amount.Style.fractioning = Just '.'
2650 , Amount.Style.precision = 1
2651 }
2652 })
2653 ~?=
2654 4)
2655 , "1,234.56 @ prec=2" ~:
2656 ((Format.Ledger.Write.amount_length
2657 Amount.nil
2658 { Amount.quantity = Decimal 2 123456
2659 , Amount.style = Amount.Style.nil
2660 { Amount.Style.fractioning = Just '.'
2661 , Amount.Style.precision = 2
2662 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
2663 }
2664 })
2665 ~?=
2666 8)
2667 , "123,456,789,01,2.3456789 @ prec=7" ~:
2668 ((Format.Ledger.Write.amount_length
2669 Amount.nil
2670 { Amount.quantity = Decimal 7 1234567890123456789
2671 , Amount.style = Amount.Style.nil
2672 { Amount.Style.fractioning = Just '.'
2673 , Amount.Style.precision = 7
2674 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
2675 }
2676 })
2677 ~?=
2678 24)
2679 , "1234567.8,90,123,456,789 @ prec=12" ~:
2680 ((Format.Ledger.Write.amount_length
2681 Amount.nil
2682 { Amount.quantity = Decimal 12 1234567890123456789
2683 , Amount.style = Amount.Style.nil
2684 { Amount.Style.fractioning = Just '.'
2685 , Amount.Style.precision = 12
2686 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
2687 }
2688 })
2689 ~?=
2690 24)
2691 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
2692 ((Format.Ledger.Write.amount_length
2693 Amount.nil
2694 { Amount.quantity = Decimal 7 1234567890123456789
2695 , Amount.style = Amount.Style.nil
2696 { Amount.Style.fractioning = Just '.'
2697 , Amount.Style.precision = 7
2698 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
2699 }
2700 })
2701 ~?=
2702 28)
2703 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
2704 ((Format.Ledger.Write.amount_length
2705 Amount.nil
2706 { Amount.quantity = Decimal 12 1234567890123456789
2707 , Amount.style = Amount.Style.nil
2708 { Amount.Style.fractioning = Just '.'
2709 , Amount.Style.precision = 12
2710 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
2711 }
2712 })
2713 ~?=
2714 28)
2715 ]
2716 , "date" ~: TestList
2717 [ "nil" ~:
2718 ((Format.Ledger.Write.show False $
2719 Format.Ledger.Write.date
2720 Date.nil)
2721 ~?=
2722 "1970/01/01")
2723 , "2000/01/01 12:34:51 CET" ~:
2724 (Format.Ledger.Write.show False $
2725 Format.Ledger.Write.date $
2726 Time.ZonedTime
2727 (Time.LocalTime
2728 (Time.fromGregorian 2000 01 01)
2729 (Time.TimeOfDay 12 34 51))
2730 (Time.TimeZone 60 False "CET"))
2731 ~?=
2732 "2000/01/01 12:34:51 CET"
2733 , "2000/01/01 12:34:51 +0100" ~:
2734 (Format.Ledger.Write.show False $
2735 Format.Ledger.Write.date $
2736 Time.ZonedTime
2737 (Time.LocalTime
2738 (Time.fromGregorian 2000 01 01)
2739 (Time.TimeOfDay 12 34 51))
2740 (Time.TimeZone 60 False ""))
2741 ~?=
2742 "2000/01/01 12:34:51 +0100"
2743 , "2000/01/01 01:02:03" ~:
2744 (Format.Ledger.Write.show False $
2745 Format.Ledger.Write.date $
2746 Time.ZonedTime
2747 (Time.LocalTime
2748 (Time.fromGregorian 2000 01 01)
2749 (Time.TimeOfDay 1 2 3))
2750 (Time.utc))
2751 ~?=
2752 "2000/01/01 01:02:03"
2753 , "01/01 01:02" ~:
2754 (Format.Ledger.Write.show False $
2755 Format.Ledger.Write.date $
2756 Time.ZonedTime
2757 (Time.LocalTime
2758 (Time.fromGregorian 0 01 01)
2759 (Time.TimeOfDay 1 2 0))
2760 (Time.utc))
2761 ~?=
2762 "01/01 01:02"
2763 , "01/01 01:00" ~:
2764 (Format.Ledger.Write.show False $
2765 Format.Ledger.Write.date $
2766 Time.ZonedTime
2767 (Time.LocalTime
2768 (Time.fromGregorian 0 01 01)
2769 (Time.TimeOfDay 1 0 0))
2770 (Time.utc))
2771 ~?=
2772 "01/01 01:00"
2773 , "01/01 00:01" ~:
2774 (Format.Ledger.Write.show False $
2775 Format.Ledger.Write.date $
2776 Time.ZonedTime
2777 (Time.LocalTime
2778 (Time.fromGregorian 0 01 01)
2779 (Time.TimeOfDay 0 1 0))
2780 (Time.utc))
2781 ~?=
2782 "01/01 00:01"
2783 , "01/01" ~:
2784 (Format.Ledger.Write.show False $
2785 Format.Ledger.Write.date $
2786 Time.ZonedTime
2787 (Time.LocalTime
2788 (Time.fromGregorian 0 01 01)
2789 (Time.TimeOfDay 0 0 0))
2790 (Time.utc))
2791 ~?=
2792 "01/01"
2793 ]
2794 , "transaction" ~: TestList
2795 [ "nil" ~:
2796 ((Format.Ledger.Write.show False $
2797 Format.Ledger.Write.transaction
2798 Transaction.nil)
2799 ~?=
2800 "1970/01/01\n")
2801 , "2000/01/01 some description\\n\\ta:b:c\\n\\t\\t; first comment\\n\\t\\t; second comment\\n\\t\\t; third comment\\n\\tA:B:C $1" ~:
2802 ((Format.Ledger.Write.show False $
2803 Format.Ledger.Write.transaction $
2804 Transaction.nil
2805 { Transaction.dates=
2806 ( Time.ZonedTime
2807 (Time.LocalTime
2808 (Time.fromGregorian 2000 01 01)
2809 (Time.TimeOfDay 0 0 0))
2810 (Time.utc)
2811 , [] )
2812 , Transaction.description="some description"
2813 , Transaction.postings = Posting.from_List
2814 [ (Posting.nil ("A":|["B", "C"]))
2815 { Posting.amounts = Data.Map.fromList
2816 [ ("$", Amount.nil
2817 { Amount.quantity = 1
2818 , Amount.style = Amount.Style.nil
2819 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2820 , Amount.Style.unit_spaced = Just False
2821 }
2822 , Amount.unit = "$"
2823 })
2824 ]
2825 }
2826 , (Posting.nil ("a":|["b", "c"]))
2827 { Posting.comments = ["first comment","second comment","third comment"]
2828 }
2829 ]
2830 })
2831 ~?=
2832 "2000/01/01 some description\n\ta:b:c\n\t\t; first comment\n\t\t; second comment\n\t\t; third comment\n\tA:B:C $1")
2833 , "2000/01/01 some description\\n\\tA:B:C $1\\n\\tAA:BB:CC $123" ~:
2834 ((Format.Ledger.Write.show False $
2835 Format.Ledger.Write.transaction $
2836 Transaction.nil
2837 { Transaction.dates=
2838 ( Time.ZonedTime
2839 (Time.LocalTime
2840 (Time.fromGregorian 2000 01 01)
2841 (Time.TimeOfDay 0 0 0))
2842 (Time.utc)
2843 , [] )
2844 , Transaction.description="some description"
2845 , Transaction.postings = Posting.from_List
2846 [ (Posting.nil ("A":|["B", "C"]))
2847 { Posting.amounts = Data.Map.fromList
2848 [ ("$", Amount.nil
2849 { Amount.quantity = 1
2850 , Amount.style = Amount.Style.nil
2851 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2852 , Amount.Style.unit_spaced = Just False
2853 }
2854 , Amount.unit = "$"
2855 })
2856 ]
2857 }
2858 , (Posting.nil ("AA":|["BB", "CC"]))
2859 { Posting.amounts = Data.Map.fromList
2860 [ ("$", Amount.nil
2861 { Amount.quantity = 123
2862 , Amount.style = Amount.Style.nil
2863 { Amount.Style.unit_side = Just Amount.Style.Side_Left
2864 , Amount.Style.unit_spaced = Just False
2865 }
2866 , Amount.unit = "$"
2867 })
2868 ]
2869 }
2870 ]
2871 })
2872 ~?=
2873 "2000/01/01 some description\n\tA:B:C $1\n\tAA:BB:CC $123")
2874 ]
2875 ]
2876 ]
2877 ]
2878 ]