1 {-# LANGUAGE FlexibleInstances #-}
2 {-# LANGUAGE OverloadedStrings #-}
3 {-# LANGUAGE ScopedTypeVariables #-}
4 {-# LANGUAGE TupleSections #-}
7 import Test.HUnit hiding ((~?))
8 import Test.Framework.Providers.HUnit (hUnitTestToTests)
9 import Test.Framework.Runners.Console (defaultMain)
11 -- import Control.Applicative ((<*))
12 import Control.Arrow ((***))
13 import Control.Monad.IO.Class (liftIO)
14 import Data.Decimal (DecimalRaw(..))
15 import qualified Data.Either
16 import Data.Function (on)
17 import qualified Data.List
18 import Data.List.NonEmpty (NonEmpty(..))
19 import qualified Data.Map.Strict as Data.Map
20 import Data.Maybe (fromJust)
21 import Data.Text (Text)
22 import qualified Data.Time.Calendar as Time
23 import qualified Data.Time.LocalTime as Time
24 import qualified Text.Parsec as P hiding (char, space, spaces, string)
25 import qualified Text.Parsec.Pos as P
26 -- import qualified Text.PrettyPrint.Leijen.Text as PP
28 import Hcompta.Account (Account)
29 import qualified Hcompta.Account as Account
30 import Hcompta.Amount (Amount)
31 import qualified Hcompta.Amount as Amount
32 import qualified Hcompta.Amount.Read as Amount.Read
33 import qualified Hcompta.Amount.Write as Amount.Write
34 import qualified Hcompta.Amount.Style as Amount.Style
35 import qualified Hcompta.Balance as Balance
36 import qualified Hcompta.Date as Date
37 import qualified Hcompta.Date.Read as Date.Read
38 import qualified Hcompta.Date.Write as Date.Write
39 import qualified Hcompta.Filter as Filter
40 import qualified Hcompta.Filter.Read as Filter.Read
41 import qualified Hcompta.Format.Ledger as Format.Ledger
42 import qualified Hcompta.Format.Ledger.Read as Format.Ledger.Read
43 import qualified Hcompta.Format.Ledger.Write as Format.Ledger.Write
44 import qualified Hcompta.Lib.Foldable as Lib.Foldable
45 import qualified Hcompta.Lib.Interval as Lib.Interval
46 import qualified Hcompta.Lib.Interval.Sieve as Lib.Interval.Sieve
47 import qualified Hcompta.Lib.Parsec as P
48 import qualified Hcompta.Lib.TreeMap as Lib.TreeMap
51 main = defaultMain $ hUnitTestToTests test_Hcompta
53 (~?) :: String -> Bool -> Test
54 (~?) s b = s ~: (b ~?= True)
60 [ "TreeMap" ~: TestList
61 [ "insert" ~: TestList
63 (Lib.TreeMap.insert const ((0::Int):|[]) () Lib.TreeMap.empty)
65 (Lib.TreeMap.TreeMap $
67 [ ((0::Int), Lib.TreeMap.leaf ())
70 (Lib.TreeMap.insert const ((0::Int):|1:[]) () Lib.TreeMap.empty)
72 (Lib.TreeMap.TreeMap $
74 [ ((0::Int), Lib.TreeMap.Node
75 { Lib.TreeMap.node_value = Nothing
76 , Lib.TreeMap.node_size = 1
77 , Lib.TreeMap.node_descendants =
78 Lib.TreeMap.singleton ((1::Int):|[]) ()
85 , "map_by_depth_first" ~: TestList
88 , "flatten" ~: TestList
89 [ "[0, 0/1, 0/1/2]" ~:
90 (Lib.TreeMap.flatten id $
91 Lib.TreeMap.from_List const
92 [ (((0::Integer):|[]), ())
103 , "[1, 1/2, 1/22, 1/2/3, 1/2/33, 11, 11/2, 11/2/3, 11/2/33]" ~:
104 (Lib.TreeMap.flatten id $
105 Lib.TreeMap.from_List const
114 , ((11:|2:33:[]), ())
119 [ (((1::Integer):|[]), ())
127 , ((11:|2:33:[]), ())
131 , "Foldable" ~: TestList
132 [ "accumLeftsAndFoldrRights" ~: TestList
134 (Lib.Foldable.accumLeftsAndFoldrRights (++) [""] $
137 (([(0::Integer)], [(""::String)]))
139 ((take 1 *** take 0) $
140 Lib.Foldable.accumLeftsAndFoldrRights (++) [""] $
141 ( repeat (Left [0]) ))
143 ([(0::Integer)], ([]::[String]))
144 , "Right:Left:Right:Left" ~:
145 (Lib.Foldable.accumLeftsAndFoldrRights (++) ["0"] $
146 ( Right ["2"]:Left [1]:Right ["1"]:Left [0]:[] ))
148 (([1, 0]::[Integer]), (["2", "1", "0"]::[String]))
149 , "Right:Left:Right:repeat Left" ~:
150 ((take 1 *** take 2) $
151 Lib.Foldable.accumLeftsAndFoldrRights (++) ["0"] $
152 ( Right ["2"]:Left [1]:Right ["1"]:repeat (Left [0]) ))
154 (([1]::[Integer]), (["2", "1"]::[String]))
157 , "Interval" ~: TestList
158 [ "position" ~: TestList $
161 let i = fromJust mi in
162 let j = fromJust mj in
165 Lib.Interval.Equal -> (EQ, EQ)
167 [ ((show . Lib.Interval.Pretty) i ++ " " ++ (show . Lib.Interval.Pretty) j) ~: Lib.Interval.position i j ~?= (p, le)
168 , ((show . Lib.Interval.Pretty) j ++ " " ++ (show . Lib.Interval.Pretty) i) ~: Lib.Interval.position j i ~?= (p, ge)
171 [ ( (Lib.Interval.<..<) 0 (4::Integer)
172 , (Lib.Interval.<..<) 5 9
173 , Lib.Interval.Away )
174 , ( (Lib.Interval.<..<) 0 4
175 , (Lib.Interval.<=..<) 4 9
176 , Lib.Interval.Adjacent )
177 , ( (Lib.Interval.<..<) 0 5
178 , (Lib.Interval.<..<) 4 9
179 , Lib.Interval.Overlap )
180 , ( (Lib.Interval.<..<) 0 5
181 , (Lib.Interval.<..<) 0 9
182 , Lib.Interval.Prefix )
183 , ( (Lib.Interval.<..<) 0 9
184 , (Lib.Interval.<..<) 1 8
185 , Lib.Interval.Include )
186 , ( (Lib.Interval.<..<) 0 9
187 , (Lib.Interval.<..<) 5 9
188 , Lib.Interval.Suffixed )
189 , ( (Lib.Interval.<..<) 0 9
190 , (Lib.Interval.<..<) 0 9
191 , Lib.Interval.Equal )
192 , ( (Lib.Interval.<..<) 0 9
193 , (Lib.Interval.<..<=) 0 9
194 , Lib.Interval.Prefix )
195 , ( (Lib.Interval.<=..<) 0 9
196 , (Lib.Interval.<..<) 0 9
197 , Lib.Interval.Suffixed )
198 , ( (Lib.Interval.<=..<=) 0 9
199 , (Lib.Interval.<..<) 0 9
200 , Lib.Interval.Include )
202 , "intersection" ~: TestList $
205 let i = fromJust mi in
206 let j = fromJust mj in
207 [ ((show . Lib.Interval.Pretty) i ++ " " ++ (show . Lib.Interval.Pretty) j) ~: Lib.Interval.intersection i j ~?= e
208 , ((show . Lib.Interval.Pretty) j ++ " " ++ (show . Lib.Interval.Pretty) i) ~: Lib.Interval.intersection j i ~?= e
211 [ ( (Lib.Interval.<..<) 0 (4::Integer)
212 , (Lib.Interval.<..<) 5 9
214 , ( (Lib.Interval.<..<=) 0 5
215 , (Lib.Interval.<=..<) 5 9
216 , (Lib.Interval.<=..<=) 5 5 )
217 , ( (Lib.Interval.<..<) 0 6
218 , (Lib.Interval.<..<) 4 9
219 , (Lib.Interval.<..<) 4 6 )
220 , ( (Lib.Interval.<..<=) 0 6
221 , (Lib.Interval.<=..<) 4 9
222 , (Lib.Interval.<=..<=) 4 6 )
223 , ( (Lib.Interval.<..<) 0 6
224 , (Lib.Interval.<=..<) 4 9
225 , (Lib.Interval.<=..<) 4 6 )
226 , ( (Lib.Interval.<..<=) 0 6
227 , (Lib.Interval.<..<) 4 9
228 , (Lib.Interval.<..<=) 4 6 )
229 , ( (Lib.Interval.<..<) 0 9
230 , (Lib.Interval.<..<) 0 9
231 , (Lib.Interval.<..<) 0 9 )
232 , ( (Lib.Interval.<=..<) 0 9
233 , (Lib.Interval.<..<=) 0 9
234 , (Lib.Interval.<..<) 0 9 )
235 , ( (Lib.Interval.<..<=) 0 9
236 , (Lib.Interval.<=..<) 0 9
237 , (Lib.Interval.<..<) 0 9 )
238 , ( (Lib.Interval.<=..<=) 0 9
239 , (Lib.Interval.<=..<=) 0 9
240 , (Lib.Interval.<=..<=) 0 9 )
242 , "union" ~: TestList $
245 let i = fromJust mi in
246 let j = fromJust mj in
247 [ ((show . Lib.Interval.Pretty) i ++ " " ++ (show . Lib.Interval.Pretty) j) ~: Lib.Interval.union i j ~?= e
248 , ((show . Lib.Interval.Pretty) j ++ " " ++ (show . Lib.Interval.Pretty) i) ~: Lib.Interval.union j i ~?= e
251 [ ( (Lib.Interval.<..<) 0 (4::Integer)
252 , (Lib.Interval.<..<) 5 9
254 , ( (Lib.Interval.<..<=) 0 5
255 , (Lib.Interval.<..<) 5 9
256 , (Lib.Interval.<..<) 0 9 )
257 , ( (Lib.Interval.<..<) 0 5
258 , (Lib.Interval.<=..<) 5 9
259 , (Lib.Interval.<..<) 0 9 )
260 , ( (Lib.Interval.<..<=) 0 5
261 , (Lib.Interval.<=..<) 5 9
262 , (Lib.Interval.<..<) 0 9 )
263 , ( (Lib.Interval.<..<) 0 6
264 , (Lib.Interval.<..<) 4 9
265 , (Lib.Interval.<..<) 0 9 )
266 , ( (Lib.Interval.<..<) 0 9
267 , (Lib.Interval.<..<) 0 9
268 , (Lib.Interval.<..<) 0 9 )
269 , ( (Lib.Interval.<=..<) 0 9
270 , (Lib.Interval.<..<=) 0 9
271 , (Lib.Interval.<=..<=) 0 9 )
272 , ( (Lib.Interval.<..<=) 0 9
273 , (Lib.Interval.<=..<) 0 9
274 , (Lib.Interval.<=..<=) 0 9 )
275 , ( (Lib.Interval.<=..<=) 0 9
276 , (Lib.Interval.<=..<=) 0 9
277 , (Lib.Interval.<=..<=) 0 9 )
279 , "Sieve" ~: TestList $
280 [ "union" ~: TestList $
283 let is = map (fromJust) mis in
284 let e = map (fromJust) me in
286 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
287 Lib.Interval.Sieve.empty is in
289 (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton)
290 Lib.Interval.Sieve.empty is in
291 [ (Data.List.intercalate " " $ map (show . Lib.Interval.Pretty) is) ~:
292 Lib.Interval.Sieve.intervals sil ~?= e
293 , (Data.List.intercalate " " $ map (show . Lib.Interval.Pretty) $ reverse is) ~:
294 Lib.Interval.Sieve.intervals sir ~?= e
297 [ ( [ (Lib.Interval.<=..<) 0 (5::Integer)
298 , (Lib.Interval.<=..<=) 5 9
300 , [ (Lib.Interval.<=..<=) 0 9 ]
302 , ( [ (Lib.Interval.<=..<=) 0 5
303 , (Lib.Interval.<=..<=) 0 9
305 , [ (Lib.Interval.<=..<=) 0 9 ]
307 , ( [ (Lib.Interval.<=..<=) 0 4
308 , (Lib.Interval.<=..<=) 5 9
309 , (Lib.Interval.<=..<=) 3 6
311 , [ (Lib.Interval.<=..<=) 0 9 ]
313 , ( [ (Lib.Interval.<=..<=) 1 4
314 , (Lib.Interval.<=..<=) 5 8
316 , [ (Lib.Interval.<=..<=) 1 4
317 , (Lib.Interval.<=..<=) 5 8
320 , ( [ (Lib.Interval.<=..<=) 1 8
321 , (Lib.Interval.<=..<=) 0 9
323 , [ (Lib.Interval.<=..<=) 0 9 ]
325 , ( [ (Lib.Interval.<=..<=) 1 4
326 , (Lib.Interval.<=..<=) 5 8
327 , (Lib.Interval.<=..<=) 0 9
329 , [ (Lib.Interval.<=..<=) 0 9 ]
332 ++ Data.List.concatMap
334 let is = map fromJust mis in
335 let js = map fromJust mjs in
336 let e = map fromJust me in
338 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
339 Lib.Interval.Sieve.empty is in
341 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
342 Lib.Interval.Sieve.empty js in
343 [ ((Data.List.intercalate " " $ map (show . Lib.Interval.Pretty) is) ++ " u " ++
344 (Data.List.intercalate " " $ map (show . Lib.Interval.Pretty) js)) ~:
345 Lib.Interval.Sieve.intervals (Lib.Interval.Sieve.union iu ju) ~?= e
346 , ((Data.List.intercalate " " $ map (show . Lib.Interval.Pretty) $ js) ++ " u " ++
347 (Data.List.intercalate " " $ map (show . Lib.Interval.Pretty) $ is)) ~:
348 Lib.Interval.Sieve.intervals (Lib.Interval.Sieve.union ju iu) ~?= e
351 [ ( [ (Lib.Interval.<=..<=) 0 (1::Integer)
352 , (Lib.Interval.<=..<=) 2 4
354 , [ (Lib.Interval.<=..<=) 0 3
356 , [ (Lib.Interval.<=..<=) 0 4
359 , ( [ (Lib.Interval.<=..<=) 0 1
360 , (Lib.Interval.<=..<=) 2 3
361 , (Lib.Interval.<=..<=) 4 5
362 , (Lib.Interval.<=..<=) 6 7
364 , [ (Lib.Interval.<=..<=) 1 2
365 , (Lib.Interval.<=..<=) 3 4
366 , (Lib.Interval.<=..<=) 5 6
368 , [ (Lib.Interval.<=..<=) 0 7
371 , ( [ (Lib.Interval.<=..<=) 0 1
372 , (Lib.Interval.<=..<=) 2 3
374 , [ (Lib.Interval.<=..<=) 4 5
376 , [ (Lib.Interval.<=..<=) 0 1
377 , (Lib.Interval.<=..<=) 2 3
378 , (Lib.Interval.<=..<=) 4 5
381 , ( [ (Lib.Interval.<=..<=) 0 1
382 , (Lib.Interval.<=..<=) 4 5
384 , [ (Lib.Interval.<=..<=) 2 3
386 , [ (Lib.Interval.<=..<=) 0 1
387 , (Lib.Interval.<=..<=) 2 3
388 , (Lib.Interval.<=..<=) 4 5
392 , "intersection" ~: TestList $
395 let is = map (fromJust) mis in
396 let js = map (fromJust) mjs in
397 let e = map (fromJust) me in
399 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
400 Lib.Interval.Sieve.empty is in
402 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
403 Lib.Interval.Sieve.empty js in
404 [ ((Data.List.intercalate " " $ map (show . Lib.Interval.Pretty) is) ++ " n " ++
405 (Data.List.intercalate " " $ map (show . Lib.Interval.Pretty) js)) ~:
406 Lib.Interval.Sieve.intervals (Lib.Interval.Sieve.intersection iu ju) ~?= e
407 , ((Data.List.intercalate " " $ map (show . Lib.Interval.Pretty) $ js) ++ " n " ++
408 (Data.List.intercalate " " $ map (show . Lib.Interval.Pretty) $ is)) ~:
409 Lib.Interval.Sieve.intervals (Lib.Interval.Sieve.intersection ju iu) ~?= e
412 [ ( [ (Lib.Interval.<=..<) 0 (5::Integer) ]
413 , [ (Lib.Interval.<=..<=) 5 9 ]
416 , ( [ (Lib.Interval.<=..<=) 0 5 ]
417 , [ (Lib.Interval.<=..<=) 5 9 ]
418 , [ (Lib.Interval.<=..<=) 5 5 ]
420 , ( [ (Lib.Interval.<=..<=) 0 5 ]
421 , [ (Lib.Interval.<=..<=) 0 9 ]
422 , [ (Lib.Interval.<=..<=) 0 5 ]
424 , ( [ (Lib.Interval.<=..<=) 0 4
425 , (Lib.Interval.<=..<=) 5 9
427 , [ (Lib.Interval.<=..<=) 3 6 ]
428 , [ (Lib.Interval.<=..<=) 3 4
429 , (Lib.Interval.<=..<=) 5 6
432 , ( [ (Lib.Interval.<=..<=) 1 4
433 , (Lib.Interval.<=..<=) 6 8
435 , [ (Lib.Interval.<=..<=) 2 3
436 , (Lib.Interval.<=..<=) 5 7
438 , [ (Lib.Interval.<=..<=) 2 3
439 , (Lib.Interval.<=..<=) 6 7
443 , "complement" ~: TestList $
446 let is = map fromJust mis in
447 let e = map fromJust me in
449 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
450 Lib.Interval.Sieve.empty is in
451 [ show (Lib.Interval.Pretty $
452 Lib.Interval.Sieve.fmap_interval
453 (Lib.Interval.fmap_unsafe $ Lib.Interval.Pretty) iu) ~:
454 Lib.Interval.Sieve.intervals (Lib.Interval.Sieve.complement iu) ~?= e
457 [ ( [ ((Lib.Interval.<=..<) `on` Lib.Interval.Limited) 0 (5::Integer)
458 , ((Lib.Interval.<=..<=) `on` Lib.Interval.Limited) 5 9
460 , [ Just $ (Lib.Interval...<) 0
461 , Just $ (Lib.Interval.<..) 9
464 , ( [ Just $ Lib.Interval.unlimited ]
468 , [ Just $ Lib.Interval.unlimited ]
470 , ( [ Just $ (Lib.Interval...<) 0
471 , Just $ (Lib.Interval.<..) 0
473 , [ Just $ Lib.Interval.point $ Lib.Interval.Limited 0
476 , ( [ ((Lib.Interval.<=..<) `on` Lib.Interval.Limited) 0 1
477 , ((Lib.Interval.<=..<) `on` Lib.Interval.Limited) 2 3
478 , ((Lib.Interval.<..<=) `on` Lib.Interval.Limited) 3 4
480 , [ Just $ (Lib.Interval...<) 0
481 , ((Lib.Interval.<=..<) `on` Lib.Interval.Limited) 1 2
482 , Just $ Lib.Interval.point $ Lib.Interval.Limited 3
483 , Just $ (Lib.Interval.<..) 4
487 , "complement_with" ~: TestList $
490 let ib = fromJust mib in
491 let is = map fromJust mis in
492 let e = map fromJust me in
494 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
495 Lib.Interval.Sieve.empty is in
496 [ show (Lib.Interval.Pretty iu) ~:
497 Lib.Interval.Sieve.intervals (Lib.Interval.Sieve.complement_with ib iu) ~?= e
500 [ ( (Lib.Interval.<=..<=) (-10) (10::Integer)
501 , [ (Lib.Interval.<=..<) 0 5
502 , (Lib.Interval.<=..<=) 5 9
504 , [ (Lib.Interval.<=..<) (-10) 0
505 , (Lib.Interval.<..<=) 9 10
508 , ( (Lib.Interval.<=..<=) (-10) 10
509 , [ (Lib.Interval.<=..<=) (-10) 10 ]
512 , ( (Lib.Interval.<=..<=) (-10) 10
514 , [ (Lib.Interval.<=..<=) (-10) 10 ]
516 , ( (Lib.Interval.<=..<=) (-10) 10
517 , [ (Lib.Interval.<=..<) (-10) 0
518 , (Lib.Interval.<..<=) 0 10
520 , [ Just $ Lib.Interval.point 0
523 , ( (Lib.Interval.<=..<=) (-10) 10
524 , [ Just $ Lib.Interval.point 0
526 , [ (Lib.Interval.<=..<) (-10) 0
527 , (Lib.Interval.<..<=) 0 10
530 , ( (Lib.Interval.<=..<=) 0 10
531 , [ (Lib.Interval.<..<=) 0 10
533 , [ Just $ Lib.Interval.point 0
536 , ( (Lib.Interval.<=..<=) 0 10
537 , [ (Lib.Interval.<=..<) 0 10
539 , [ Just $ Lib.Interval.point 10
542 , ( Just $ Lib.Interval.point 0
545 , [ Just $ Lib.Interval.point 0
548 , ( Just $ Lib.Interval.point 0
549 , [ Just $ Lib.Interval.point 0
555 , ( [ ((Lib.Interval.<=..<) `on` Lib.Interval.Limited) 0 1
556 , ((Lib.Interval.<=..<) `on` Lib.Interval.Limited) 2 3
557 , ((Lib.Interval.<..<=) `on` Lib.Interval.Limited) 3 4
559 , [ Just $ (Lib.Interval...<) 0
560 , ((Lib.Interval.<=..<) `on` Lib.Interval.Limited) 1 2
561 , Just $ Lib.Interval.point $ Lib.Interval.Limited 3
562 , Just $ (Lib.Interval.<..) 4
570 , "Account" ~: TestList
571 [ "foldr" ~: TestList
573 (reverse $ Account.foldr ("A":|[]) (:) []) ~?= ["A":|[]]
575 (reverse $ Account.foldr ("A":|["B"]) (:) []) ~?= ["A":|[], "A":|["B"]]
577 (reverse $ Account.foldr ("A":|["B", "C"]) (:) []) ~?= ["A":|[], "A":|["B"], "A":|["B", "C"]]
579 , "ascending" ~: TestList
581 Account.ascending ("A":|[]) ~?= Nothing
583 Account.ascending ("A":|["B"]) ~?= Just ("A":|[])
585 Account.ascending ("A":|["B", "C"]) ~?= Just ("A":|["B"])
588 , "Amount" ~: TestList
593 { Amount.quantity = Decimal 0 1
594 , Amount.style = Amount.Style.nil
595 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
600 { Amount.quantity = Decimal 0 1
601 , Amount.style = Amount.Style.nil
602 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
608 { Amount.quantity = Decimal 0 2
609 , Amount.style = Amount.Style.nil
610 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
615 , "from_List" ~: TestList
616 [ "from_List [$1, 1$] = $2" ~:
619 { Amount.quantity = Decimal 0 1
620 , Amount.style = Amount.Style.nil
621 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
626 { Amount.quantity = Decimal 0 1
627 , Amount.style = Amount.Style.nil
628 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
636 { Amount.quantity = Decimal 0 2
637 , Amount.style = Amount.Style.nil
638 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
645 [ "amount" ~: TestList
647 (Data.Either.rights $
649 (Amount.Read.amount <* P.eof)
653 , "\"0\" = Right 0" ~:
654 (Data.Either.rights $
656 (Amount.Read.amount <* P.eof)
660 { Amount.quantity = Decimal 0 0
662 , "\"00\" = Right 0" ~:
663 (Data.Either.rights $
665 (Amount.Read.amount <* P.eof)
669 { Amount.quantity = Decimal 0 0
671 , "\"0.\" = Right 0." ~:
672 (Data.Either.rights $
674 (Amount.Read.amount <* P.eof)
678 { Amount.quantity = Decimal 0 0
681 { Amount.Style.fractioning = Just '.'
684 , "\".0\" = Right 0.0" ~:
685 (Data.Either.rights $
687 (Amount.Read.amount <* P.eof)
691 { Amount.quantity = Decimal 0 0
694 { Amount.Style.fractioning = Just '.'
695 , Amount.Style.precision = 1
698 , "\"0,\" = Right 0," ~:
699 (Data.Either.rights $
701 (Amount.Read.amount <* P.eof)
705 { Amount.quantity = Decimal 0 0
708 { Amount.Style.fractioning = Just ','
711 , "\",0\" = Right 0,0" ~:
712 (Data.Either.rights $
714 (Amount.Read.amount <* P.eof)
718 { Amount.quantity = Decimal 0 0
721 { Amount.Style.fractioning = Just ','
722 , Amount.Style.precision = 1
726 (Data.Either.rights $
728 (Amount.Read.amount <* P.eof)
733 (Data.Either.rights $
735 (Amount.Read.amount <* P.eof)
739 , "\"0.0\" = Right 0.0" ~:
740 (Data.Either.rights $
742 (Amount.Read.amount <* P.eof)
743 () "" ("0.0"::Text)])
746 { Amount.quantity = Decimal 0 0
749 { Amount.Style.fractioning = Just '.'
750 , Amount.Style.precision = 1
753 , "\"00.00\" = Right 0.00" ~:
754 (Data.Either.rights $
756 (Amount.Read.amount <* P.eof)
757 () "" ("00.00"::Text)])
760 { Amount.quantity = Decimal 0 0
763 { Amount.Style.fractioning = Just '.'
764 , Amount.Style.precision = 2
767 , "\"0,0\" = Right 0,0" ~:
768 (Data.Either.rights $
770 (Amount.Read.amount <* P.eof)
771 () "" ("0,0"::Text)])
774 { Amount.quantity = Decimal 0 0
777 { Amount.Style.fractioning = Just ','
778 , Amount.Style.precision = 1
781 , "\"00,00\" = Right 0,00" ~:
782 (Data.Either.rights $
784 (Amount.Read.amount <* P.eof)
785 () "" ("00,00"::Text)])
788 { Amount.quantity = Decimal 0 0
791 { Amount.Style.fractioning = Just ','
792 , Amount.Style.precision = 2
795 , "\"0_0\" = Right 0" ~:
796 (Data.Either.rights $
798 (Amount.Read.amount <* P.eof)
799 () "" ("0_0"::Text)])
802 { Amount.quantity = Decimal 0 0
805 { Amount.Style.fractioning = Nothing
806 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
807 , Amount.Style.precision = 0
810 , "\"00_00\" = Right 0" ~:
811 (Data.Either.rights $
813 (Amount.Read.amount <* P.eof)
814 () "" ("00_00"::Text)])
817 { Amount.quantity = Decimal 0 0
820 { Amount.Style.fractioning = Nothing
821 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
822 , Amount.Style.precision = 0
825 , "\"0,000.00\" = Right 0,000.00" ~:
826 (Data.Either.rights $
828 (Amount.Read.amount <* P.eof)
829 () "" ("0,000.00"::Text)])
832 { Amount.quantity = Decimal 0 0
835 { Amount.Style.fractioning = Just '.'
836 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
837 , Amount.Style.precision = 2
840 , "\"0.000,00\" = Right 0.000,00" ~:
841 (Data.Either.rights $
844 () "" ("0.000,00"::Text)])
847 { Amount.quantity = Decimal 0 0
850 { Amount.Style.fractioning = Just ','
851 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
852 , Amount.Style.precision = 2
855 , "\"1,000.00\" = Right 1,000.00" ~:
856 (Data.Either.rights $
858 (Amount.Read.amount <* P.eof)
859 () "" ("1,000.00"::Text)])
862 { Amount.quantity = Decimal 0 1000
865 { Amount.Style.fractioning = Just '.'
866 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
867 , Amount.Style.precision = 2
870 , "\"1.000,00\" = Right 1.000,00" ~:
871 (Data.Either.rights $
874 () "" ("1.000,00"::Text)])
877 { Amount.quantity = Decimal 0 1000
880 { Amount.Style.fractioning = Just ','
881 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
882 , Amount.Style.precision = 2
885 , "\"1,000.00.\" = Left" ~:
886 (Data.Either.rights $
889 () "" ("1,000.00."::Text)])
892 , "\"1.000,00,\" = Left" ~:
893 (Data.Either.rights $
896 () "" ("1.000,00,"::Text)])
899 , "\"1,000.00_\" = Left" ~:
900 (Data.Either.rights $
903 () "" ("1,000.00_"::Text)])
906 , "\"12\" = Right 12" ~:
907 (Data.Either.rights $
909 (Amount.Read.amount <* P.eof)
910 () "" ("123"::Text)])
913 { Amount.quantity = Decimal 0 123
915 , "\"1.2\" = Right 1.2" ~:
916 (Data.Either.rights $
918 (Amount.Read.amount <* P.eof)
919 () "" ("1.2"::Text)])
922 { Amount.quantity = Decimal 1 12
925 { Amount.Style.fractioning = Just '.'
926 , Amount.Style.precision = 1
929 , "\"1,2\" = Right 1,2" ~:
930 (Data.Either.rights $
932 (Amount.Read.amount <* P.eof)
933 () "" ("1,2"::Text)])
936 { Amount.quantity = Decimal 1 12
939 { Amount.Style.fractioning = Just ','
940 , Amount.Style.precision = 1
943 , "\"12.23\" = Right 12.23" ~:
944 (Data.Either.rights $
946 (Amount.Read.amount <* P.eof)
947 () "" ("12.34"::Text)])
950 { Amount.quantity = Decimal 2 1234
953 { Amount.Style.fractioning = Just '.'
954 , Amount.Style.precision = 2
957 , "\"12,23\" = Right 12,23" ~:
958 (Data.Either.rights $
960 (Amount.Read.amount <* P.eof)
961 () "" ("12,34"::Text)])
964 { Amount.quantity = Decimal 2 1234
967 { Amount.Style.fractioning = Just ','
968 , Amount.Style.precision = 2
971 , "\"1_2\" = Right 1_2" ~:
972 (Data.Either.rights $
974 (Amount.Read.amount <* P.eof)
975 () "" ("1_2"::Text)])
978 { Amount.quantity = Decimal 0 12
981 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
982 , Amount.Style.precision = 0
985 , "\"1_23\" = Right 1_23" ~:
986 (Data.Either.rights $
988 (Amount.Read.amount <* P.eof)
989 () "" ("1_23"::Text)])
992 { Amount.quantity = Decimal 0 123
995 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
996 , Amount.Style.precision = 0
999 , "\"1_23_456\" = Right 1_23_456" ~:
1000 (Data.Either.rights $
1002 (Amount.Read.amount <* P.eof)
1003 () "" ("1_23_456"::Text)])
1006 { Amount.quantity = Decimal 0 123456
1009 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
1010 , Amount.Style.precision = 0
1013 , "\"1_23_456.7890_12345_678901\" = Right 1_23_456.7890_12345_678901" ~:
1014 (Data.Either.rights $
1016 (Amount.Read.amount <* P.eof)
1017 () "" ("1_23_456.7890_12345_678901"::Text)])
1020 { Amount.quantity = Decimal 15 123456789012345678901
1023 { Amount.Style.fractioning = Just '.'
1024 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
1025 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [4, 5, 6]
1026 , Amount.Style.precision = 15
1029 , "\"123456_78901_2345.678_90_1\" = Right 123456_78901_2345.678_90_1" ~:
1030 (Data.Either.rights $
1032 (Amount.Read.amount <* P.eof)
1033 () "" ("123456_78901_2345.678_90_1"::Text)])
1036 { Amount.quantity = Decimal 6 123456789012345678901
1039 { Amount.Style.fractioning = Just '.'
1040 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [4, 5, 6]
1041 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [3, 2]
1042 , Amount.Style.precision = 6
1045 , "\"$1\" = Right $1" ~:
1046 (Data.Either.rights $
1048 (Amount.Read.amount <* P.eof)
1049 () "" ("$1"::Text)])
1052 { Amount.quantity = Decimal 0 1
1055 { Amount.Style.fractioning = Nothing
1056 , Amount.Style.grouping_integral = Nothing
1057 , Amount.Style.grouping_fractional = Nothing
1058 , Amount.Style.precision = 0
1059 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1060 , Amount.Style.unit_spaced = Just False
1064 , "\"1$\" = Right 1$" ~:
1065 (Data.Either.rights $
1067 (Amount.Read.amount <* P.eof)
1068 () "" ("1$"::Text)])
1071 { Amount.quantity = Decimal 0 1
1074 { Amount.Style.fractioning = Nothing
1075 , Amount.Style.grouping_integral = Nothing
1076 , Amount.Style.grouping_fractional = Nothing
1077 , Amount.Style.precision = 0
1078 , Amount.Style.unit_side = Just Amount.Style.Side_Right
1079 , Amount.Style.unit_spaced = Just False
1083 , "\"$ 1\" = Right $ 1" ~:
1084 (Data.Either.rights $
1086 (Amount.Read.amount <* P.eof)
1087 () "" ("$ 1"::Text)])
1090 { Amount.quantity = Decimal 0 1
1093 { Amount.Style.fractioning = Nothing
1094 , Amount.Style.grouping_integral = Nothing
1095 , Amount.Style.grouping_fractional = Nothing
1096 , Amount.Style.precision = 0
1097 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1098 , Amount.Style.unit_spaced = Just True
1102 , "\"1 $\" = Right 1 $" ~:
1103 (Data.Either.rights $
1105 (Amount.Read.amount <* P.eof)
1106 () "" ("1 $"::Text)])
1109 { Amount.quantity = Decimal 0 1
1112 { Amount.Style.fractioning = Nothing
1113 , Amount.Style.grouping_integral = Nothing
1114 , Amount.Style.grouping_fractional = Nothing
1115 , Amount.Style.precision = 0
1116 , Amount.Style.unit_side = Just Amount.Style.Side_Right
1117 , Amount.Style.unit_spaced = Just True
1121 , "\"-$1\" = Right $-1" ~:
1122 (Data.Either.rights $
1124 (Amount.Read.amount <* P.eof)
1125 () "" ("-$1"::Text)])
1128 { Amount.quantity = Decimal 0 (-1)
1131 { Amount.Style.fractioning = Nothing
1132 , Amount.Style.grouping_integral = Nothing
1133 , Amount.Style.grouping_fractional = Nothing
1134 , Amount.Style.precision = 0
1135 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1136 , Amount.Style.unit_spaced = Just False
1140 , "\"\\\"4 2\\\"1\" = Right \\\"4 2\\\"1" ~:
1141 (Data.Either.rights $
1143 (Amount.Read.amount <* P.eof)
1144 () "" ("\"4 2\"1"::Text)])
1147 { Amount.quantity = Decimal 0 1
1150 { Amount.Style.fractioning = Nothing
1151 , Amount.Style.grouping_integral = Nothing
1152 , Amount.Style.grouping_fractional = Nothing
1153 , Amount.Style.precision = 0
1154 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1155 , Amount.Style.unit_spaced = Just False
1157 , Amount.unit = "4 2"
1159 , "\"1\\\"4 2\\\"\" = Right 1\\\"4 2\\\"" ~:
1160 (Data.Either.rights $
1162 (Amount.Read.amount <* P.eof)
1163 () "" ("1\"4 2\""::Text)])
1166 { Amount.quantity = Decimal 0 1
1169 { Amount.Style.fractioning = Nothing
1170 , Amount.Style.grouping_integral = Nothing
1171 , Amount.Style.grouping_fractional = Nothing
1172 , Amount.Style.precision = 0
1173 , Amount.Style.unit_side = Just Amount.Style.Side_Right
1174 , Amount.Style.unit_spaced = Just False
1176 , Amount.unit = "4 2"
1178 , "\"$1.000,00\" = Right $1.000,00" ~:
1179 (Data.Either.rights $
1181 (Amount.Read.amount <* P.eof)
1182 () "" ("$1.000,00"::Text)])
1185 { Amount.quantity = Decimal 0 1000
1188 { Amount.Style.fractioning = Just ','
1189 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
1190 , Amount.Style.grouping_fractional = Nothing
1191 , Amount.Style.precision = 2
1192 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1193 , Amount.Style.unit_spaced = Just False
1197 , "\"1.000,00$\" = Right 1.000,00$" ~:
1198 (Data.Either.rights $
1200 (Amount.Read.amount <* P.eof)
1201 () "" ("1.000,00$"::Text)])
1204 { Amount.quantity = Decimal 0 1000
1207 { Amount.Style.fractioning = Just ','
1208 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
1209 , Amount.Style.grouping_fractional = Nothing
1210 , Amount.Style.precision = 2
1211 , Amount.Style.unit_side = Just Amount.Style.Side_Right
1212 , Amount.Style.unit_spaced = Just False
1218 , "Write" ~: TestList
1219 [ "amount" ~: TestList
1221 ((Format.Ledger.Write.show
1222 Format.Ledger.Write.Style
1223 { Format.Ledger.Write.style_color=False
1224 , Format.Ledger.Write.style_align=True
1231 ((Format.Ledger.Write.show
1232 Format.Ledger.Write.Style
1233 { Format.Ledger.Write.style_color=False
1234 , Format.Ledger.Write.style_align=True
1238 { Amount.style = Amount.Style.nil
1239 { Amount.Style.precision = 2 }
1244 ((Format.Ledger.Write.show
1245 Format.Ledger.Write.Style
1246 { Format.Ledger.Write.style_color=False
1247 , Format.Ledger.Write.style_align=True
1251 { Amount.quantity = Decimal 0 123
1256 ((Format.Ledger.Write.show
1257 Format.Ledger.Write.Style
1258 { Format.Ledger.Write.style_color=False
1259 , Format.Ledger.Write.style_align=True
1263 { Amount.quantity = Decimal 0 (- 123)
1267 , "12.3 @ prec=0" ~:
1268 ((Format.Ledger.Write.show
1269 Format.Ledger.Write.Style
1270 { Format.Ledger.Write.style_color=False
1271 , Format.Ledger.Write.style_align=True
1275 { Amount.quantity = Decimal 1 123
1276 , Amount.style = Amount.Style.nil
1277 { Amount.Style.fractioning = Just '.'
1282 , "12.5 @ prec=0" ~:
1283 ((Format.Ledger.Write.show
1284 Format.Ledger.Write.Style
1285 { Format.Ledger.Write.style_color=False
1286 , Format.Ledger.Write.style_align=True
1290 { Amount.quantity = Decimal 1 125
1291 , Amount.style = Amount.Style.nil
1292 { Amount.Style.fractioning = Just '.'
1297 , "12.3 @ prec=1" ~:
1298 ((Format.Ledger.Write.show
1299 Format.Ledger.Write.Style
1300 { Format.Ledger.Write.style_color=False
1301 , Format.Ledger.Write.style_align=True
1305 { Amount.quantity = Decimal 1 123
1306 , Amount.style = Amount.Style.nil
1307 { Amount.Style.fractioning = Just '.'
1308 , Amount.Style.precision = 1
1313 , "1,234.56 @ prec=2" ~:
1314 ((Format.Ledger.Write.show
1315 Format.Ledger.Write.Style
1316 { Format.Ledger.Write.style_color=False
1317 , Format.Ledger.Write.style_align=True
1321 { Amount.quantity = Decimal 2 123456
1322 , Amount.style = Amount.Style.nil
1323 { Amount.Style.fractioning = Just '.'
1324 , Amount.Style.precision = 2
1325 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
1330 , "123,456,789,01,2.3456789 @ prec=7" ~:
1331 ((Format.Ledger.Write.show
1332 Format.Ledger.Write.Style
1333 { Format.Ledger.Write.style_color=False
1334 , Format.Ledger.Write.style_align=True
1338 { Amount.quantity = Decimal 7 1234567890123456789
1339 , Amount.style = Amount.Style.nil
1340 { Amount.Style.fractioning = Just '.'
1341 , Amount.Style.precision = 7
1342 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1346 "123,456,789,01,2.3456789")
1347 , "1234567.8,90,123,456,789 @ prec=12" ~:
1348 ((Format.Ledger.Write.show
1349 Format.Ledger.Write.Style
1350 { Format.Ledger.Write.style_color=False
1351 , Format.Ledger.Write.style_align=True
1355 { Amount.quantity = Decimal 12 1234567890123456789
1356 , Amount.style = Amount.Style.nil
1357 { Amount.Style.fractioning = Just '.'
1358 , Amount.Style.precision = 12
1359 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1363 "1234567.8,90,123,456,789")
1364 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
1365 ((Format.Ledger.Write.show
1366 Format.Ledger.Write.Style
1367 { Format.Ledger.Write.style_color=False
1368 , Format.Ledger.Write.style_align=True
1372 { Amount.quantity = Decimal 7 1234567890123456789
1373 , Amount.style = Amount.Style.nil
1374 { Amount.Style.fractioning = Just '.'
1375 , Amount.Style.precision = 7
1376 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1380 "1,2,3,4,5,6,7,89,012.3456789")
1381 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
1382 ((Format.Ledger.Write.show
1383 Format.Ledger.Write.Style
1384 { Format.Ledger.Write.style_color=False
1385 , Format.Ledger.Write.style_align=True
1389 { Amount.quantity = Decimal 12 1234567890123456789
1390 , Amount.style = Amount.Style.nil
1391 { Amount.Style.fractioning = Just '.'
1392 , Amount.Style.precision = 12
1393 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1397 "1234567.890,12,3,4,5,6,7,8,9")
1399 , "amount_length" ~: TestList
1401 ((Amount.Write.amount_length
1406 ((Amount.Write.amount_length
1408 { Amount.style = Amount.Style.nil
1409 { Amount.Style.precision = 2 }
1414 ((Amount.Write.amount_length
1416 { Amount.quantity = Decimal 0 123
1421 ((Amount.Write.amount_length
1423 { Amount.quantity = Decimal 0 (- 123)
1427 , "12.3 @ prec=0" ~:
1428 ((Amount.Write.amount_length
1430 { Amount.quantity = Decimal 1 123
1431 , Amount.style = Amount.Style.nil
1432 { Amount.Style.fractioning = Just '.'
1437 , "12.5 @ prec=0" ~:
1438 ((Amount.Write.amount_length
1440 { Amount.quantity = Decimal 1 125
1441 , Amount.style = Amount.Style.nil
1442 { Amount.Style.fractioning = Just '.'
1447 , "12.3 @ prec=1" ~:
1448 ((Amount.Write.amount_length
1450 { Amount.quantity = Decimal 1 123
1451 , Amount.style = Amount.Style.nil
1452 { Amount.Style.fractioning = Just '.'
1453 , Amount.Style.precision = 1
1458 , "1,234.56 @ prec=2" ~:
1459 ((Amount.Write.amount_length
1461 { Amount.quantity = Decimal 2 123456
1462 , Amount.style = Amount.Style.nil
1463 { Amount.Style.fractioning = Just '.'
1464 , Amount.Style.precision = 2
1465 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
1470 , "123,456,789,01,2.3456789 @ prec=7" ~:
1471 ((Amount.Write.amount_length
1473 { Amount.quantity = Decimal 7 1234567890123456789
1474 , Amount.style = Amount.Style.nil
1475 { Amount.Style.fractioning = Just '.'
1476 , Amount.Style.precision = 7
1477 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1482 , "1234567.8,90,123,456,789 @ prec=12" ~:
1483 ((Amount.Write.amount_length
1485 { Amount.quantity = Decimal 12 1234567890123456789
1486 , Amount.style = Amount.Style.nil
1487 { Amount.Style.fractioning = Just '.'
1488 , Amount.Style.precision = 12
1489 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1494 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
1495 ((Amount.Write.amount_length
1497 { Amount.quantity = Decimal 7 1234567890123456789
1498 , Amount.style = Amount.Style.nil
1499 { Amount.Style.fractioning = Just '.'
1500 , Amount.Style.precision = 7
1501 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1506 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
1507 ((Amount.Write.amount_length
1509 { Amount.quantity = Decimal 12 1234567890123456789
1510 , Amount.style = Amount.Style.nil
1511 { Amount.Style.fractioning = Just '.'
1512 , Amount.Style.precision = 12
1513 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1518 , "1000000.000,00,0,0,0,0,0,0,0 @ prec=12" ~:
1519 ((Amount.Write.amount_length
1521 { Amount.quantity = Decimal 12 1000000000000000000
1522 , Amount.style = Amount.Style.nil
1523 { Amount.Style.fractioning = Just '.'
1524 , Amount.Style.precision = 12
1525 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1531 ((Amount.Write.amount_length $
1533 { Amount.quantity = Decimal 0 999
1534 , Amount.style = Amount.Style.nil
1535 { Amount.Style.precision = 0
1540 , "1000 @ prec=0" ~:
1541 ((Amount.Write.amount_length $
1543 { Amount.quantity = Decimal 0 1000
1544 , Amount.style = Amount.Style.nil
1545 { Amount.Style.precision = 0
1550 , "10,00€ @ prec=2" ~:
1551 ((Amount.Write.amount_length $ Amount.eur 10)
1557 , "Date" ~: TestList
1558 [ "Read" ~: TestList
1559 [ "date" ~: TestList
1561 (Data.Either.rights $
1562 [P.runParser_with_Error
1563 (Date.Read.date id Nothing <* P.eof)
1564 () "" ("2000/01/01"::Text)])
1566 [ Time.zonedTimeToUTC $
1569 (Time.fromGregorian 2000 01 01)
1570 (Time.TimeOfDay 0 0 0))
1572 , "2000/01/01 some text" ~:
1573 (Data.Either.rights $
1574 [P.runParser_with_Error
1575 (Date.Read.date id Nothing)
1576 () "" ("2000/01/01 some text"::Text)])
1578 [ Time.zonedTimeToUTC $
1581 (Time.fromGregorian 2000 01 01)
1582 (Time.TimeOfDay 0 0 0))
1584 , "2000/01/01 12:34" ~:
1585 (Data.Either.rights $
1586 [P.runParser_with_Error
1587 (Date.Read.date id Nothing <* P.eof)
1588 () "" ("2000/01/01 12:34"::Text)])
1590 [ Time.zonedTimeToUTC $
1593 (Time.fromGregorian 2000 01 01)
1594 (Time.TimeOfDay 12 34 0))
1596 , "2000/01/01 12:34:56" ~:
1597 (Data.Either.rights $
1598 [P.runParser_with_Error
1599 (Date.Read.date id Nothing <* P.eof)
1600 () "" ("2000/01/01 12:34:56"::Text)])
1602 [ Time.zonedTimeToUTC $
1605 (Time.fromGregorian 2000 01 01)
1606 (Time.TimeOfDay 12 34 56))
1608 , "2000/01/01 12:34 CET" ~:
1609 (Data.Either.rights $
1610 [P.runParser_with_Error
1611 (Date.Read.date id Nothing <* P.eof)
1612 () "" ("2000/01/01 12:34 CET"::Text)])
1614 [ Time.zonedTimeToUTC $
1617 (Time.fromGregorian 2000 01 01)
1618 (Time.TimeOfDay 12 34 0))
1619 (Time.TimeZone 60 True "CET")]
1620 , "2000/01/01 12:34 +0130" ~:
1621 (Data.Either.rights $
1622 [P.runParser_with_Error
1623 (Date.Read.date id Nothing <* P.eof)
1624 () "" ("2000/01/01 12:34 +0130"::Text)])
1626 [ Time.zonedTimeToUTC $
1629 (Time.fromGregorian 2000 01 01)
1630 (Time.TimeOfDay 12 34 0))
1631 (Time.TimeZone 90 False "+0130")]
1632 , "2000/01/01 12:34:56 CET" ~:
1633 (Data.Either.rights $
1634 [P.runParser_with_Error
1635 (Date.Read.date id Nothing <* P.eof)
1636 () "" ("2000/01/01 12:34:56 CET"::Text)])
1638 [ Time.zonedTimeToUTC $
1641 (Time.fromGregorian 2000 01 01)
1642 (Time.TimeOfDay 12 34 56))
1643 (Time.TimeZone 60 True "CET")]
1645 (Data.Either.rights $
1646 [P.runParser_with_Error
1647 (Date.Read.date id Nothing <* P.eof)
1648 () "" ("2001/02/29"::Text)])
1652 (Data.Either.rights $
1653 [P.runParser_with_Error
1654 (Date.Read.date id (Just 2000) <* P.eof)
1655 () "" ("01/01"::Text)])
1657 [ Time.zonedTimeToUTC $
1660 (Time.fromGregorian 2000 01 01)
1661 (Time.TimeOfDay 0 0 0))
1665 , "Write" ~: TestList
1666 [ "date" ~: TestList
1668 ((Format.Ledger.Write.show
1669 Format.Ledger.Write.Style
1670 { Format.Ledger.Write.style_color=False
1671 , Format.Ledger.Write.style_align=True
1677 , "2000/01/01 12:34:51 CET" ~:
1678 (Format.Ledger.Write.show
1679 Format.Ledger.Write.Style
1680 { Format.Ledger.Write.style_color=False
1681 , Format.Ledger.Write.style_align=True
1684 Time.zonedTimeToUTC $
1687 (Time.fromGregorian 2000 01 01)
1688 (Time.TimeOfDay 12 34 51))
1689 (Time.TimeZone 60 False "CET"))
1691 "2000/01/01 11:34:51"
1692 , "2000/01/01 12:34:51 +0100" ~:
1693 (Format.Ledger.Write.show
1694 Format.Ledger.Write.Style
1695 { Format.Ledger.Write.style_color=False
1696 , Format.Ledger.Write.style_align=True
1699 Time.zonedTimeToUTC $
1702 (Time.fromGregorian 2000 01 01)
1703 (Time.TimeOfDay 12 34 51))
1704 (Time.TimeZone 60 False ""))
1706 "2000/01/01 11:34:51"
1707 , "2000/01/01 01:02:03" ~:
1708 (Format.Ledger.Write.show
1709 Format.Ledger.Write.Style
1710 { Format.Ledger.Write.style_color=False
1711 , Format.Ledger.Write.style_align=True
1714 Time.zonedTimeToUTC $
1717 (Time.fromGregorian 2000 01 01)
1718 (Time.TimeOfDay 1 2 3))
1721 "2000/01/01 01:02:03"
1723 (Format.Ledger.Write.show
1724 Format.Ledger.Write.Style
1725 { Format.Ledger.Write.style_color=False
1726 , Format.Ledger.Write.style_align=True
1729 Time.zonedTimeToUTC $
1732 (Time.fromGregorian 0 01 01)
1733 (Time.TimeOfDay 1 2 0))
1738 (Format.Ledger.Write.show
1739 Format.Ledger.Write.Style
1740 { Format.Ledger.Write.style_color=False
1741 , Format.Ledger.Write.style_align=True
1744 Time.zonedTimeToUTC $
1747 (Time.fromGregorian 0 01 01)
1748 (Time.TimeOfDay 1 0 0))
1753 (Format.Ledger.Write.show
1754 Format.Ledger.Write.Style
1755 { Format.Ledger.Write.style_color=False
1756 , Format.Ledger.Write.style_align=True
1759 Time.zonedTimeToUTC $
1762 (Time.fromGregorian 0 01 01)
1763 (Time.TimeOfDay 0 1 0))
1768 (Format.Ledger.Write.show
1769 Format.Ledger.Write.Style
1770 { Format.Ledger.Write.style_color=False
1771 , Format.Ledger.Write.style_align=True
1774 Time.zonedTimeToUTC $
1777 (Time.fromGregorian 0 01 01)
1778 (Time.TimeOfDay 0 0 0))
1785 , "Filter" ~: TestList
1786 [ "test" ~: TestList
1787 [ "Test_Account" ~: TestList
1790 [ Filter.Test_Account_Section_Text
1791 (Filter.Test_Text_Exact "A")
1793 (("A":|[]::Account))
1796 [ Filter.Test_Account_Section_Any
1798 (("A":|[]::Account))
1801 [ Filter.Test_Account_Section_Many
1803 (("A":|[]::Account))
1806 [ Filter.Test_Account_Section_Many
1807 , Filter.Test_Account_Section_Text
1808 (Filter.Test_Text_Exact "A")
1810 (("A":|[]::Account))
1813 [ Filter.Test_Account_Section_Text
1814 (Filter.Test_Text_Exact "A")
1815 , Filter.Test_Account_Section_Many
1817 (("A":|[]::Account))
1820 [ Filter.Test_Account_Section_Text
1821 (Filter.Test_Text_Exact "A")
1822 , Filter.Test_Account_Section_Many
1824 (("A":|"B":[]::Account))
1827 [ Filter.Test_Account_Section_Text
1828 (Filter.Test_Text_Exact "A")
1829 , Filter.Test_Account_Section_Text
1830 (Filter.Test_Text_Exact "B")
1832 (("A":|"B":[]::Account))
1835 [ Filter.Test_Account_Section_Text
1836 (Filter.Test_Text_Exact "A")
1837 , Filter.Test_Account_Section_Many
1838 , Filter.Test_Account_Section_Text
1839 (Filter.Test_Text_Exact "B")
1841 (("A":|"B":[]::Account))
1844 [ Filter.Test_Account_Section_Many
1845 , Filter.Test_Account_Section_Text
1846 (Filter.Test_Text_Exact "B")
1847 , Filter.Test_Account_Section_Many
1849 (("A":|"B":"C":[]::Account))
1852 [ Filter.Test_Account_Section_Many
1853 , Filter.Test_Account_Section_Text
1854 (Filter.Test_Text_Exact "C")
1856 (("A":|"B":"C":[]::Account))
1858 , "Test_Bool" ~: TestList
1861 (Filter.Any::Filter.Test_Bool Filter.Test_Account)
1862 (("A":|[]::Account))
1864 , "Test_Ord" ~: TestList
1867 (Filter.Test_Ord_Gt (0::Integer))
1868 (fromJust $ (Lib.Interval.<=..<=) 1 2)
1871 (Filter.Test_Ord_Lt (0::Integer))
1872 (fromJust $ (Lib.Interval.<=..<=) (-2) (-1))
1873 , "not (1 < (0, 2))" ~?
1875 (Filter.Test_Ord_Gt (1::Integer))
1876 (fromJust $ (Lib.Interval.<=..<=) 0 2))
1879 , "Read" ~: TestList
1880 [ "test_account_section" ~: TestList
1882 (Data.Either.rights $
1884 (Filter.Read.test_account <* P.eof)
1887 [ [Filter.Test_Account_Section_Any]
1890 (Data.Either.rights $
1892 (Filter.Read.test_account <* P.eof)
1895 [ [Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")]
1898 (Data.Either.rights $
1900 (Filter.Read.test_account <* P.eof)
1901 () "" ("AA"::Text)])
1903 [ [Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "AA")]
1906 (Data.Either.rights $
1908 (Filter.Read.test_account <* P.eof)
1909 () "" ("::A"::Text)])
1911 [ [ Filter.Test_Account_Section_Many
1912 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
1916 (Data.Either.rights $
1918 (Filter.Read.test_account <* P.eof)
1919 () "" (":A"::Text)])
1921 [ [ Filter.Test_Account_Section_Many
1922 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
1926 (Data.Either.rights $
1928 (Filter.Read.test_account <* P.eof)
1929 () "" ("A:"::Text)])
1931 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
1932 , Filter.Test_Account_Section_Many
1936 (Data.Either.rights $
1938 (Filter.Read.test_account <* P.eof)
1939 () "" ("A::"::Text)])
1941 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
1942 , Filter.Test_Account_Section_Many
1946 (Data.Either.rights $
1948 (Filter.Read.test_account <* P.eof)
1949 () "" ("A:B"::Text)])
1951 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
1952 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B") ]
1955 (Data.Either.rights $
1957 (Filter.Read.test_account <* P.eof)
1958 () "" ("A::B"::Text)])
1960 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
1961 , Filter.Test_Account_Section_Many
1962 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B")
1966 (Data.Either.rights $
1968 (Filter.Read.test_account <* P.eof)
1969 () "" ("A:::B"::Text)])
1971 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
1972 , Filter.Test_Account_Section_Many
1973 , Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "B")
1977 (Data.Either.rights $
1979 (Filter.Read.test_account <* P.char ' ' <* P.eof)
1980 () "" ("A: "::Text)])
1982 [ [ Filter.Test_Account_Section_Text (Filter.Test_Text_Exact "A")
1983 , Filter.Test_Account_Section_Many
1987 , "test_bool" ~: TestList
1989 (Data.Either.rights $
1991 (Filter.Read.test_bool
1992 [ P.char 'E' >> return (return True) ]
1994 () "" ("( E )"::Text)])
1996 [ Filter.And (Filter.Bool True) Filter.Any
1999 (Data.Either.rights $
2001 (Filter.Read.test_bool
2002 [ P.char 'E' >> return (return True) ]
2004 () "" ("( ( E ) )"::Text)])
2006 [ Filter.And (Filter.And (Filter.Bool True) Filter.Any) Filter.Any
2008 , "( E ) & ( E )" ~:
2009 (Data.Either.rights $
2011 (Filter.Read.test_bool
2012 [ P.char 'E' >> return (return True) ]
2014 () "" ("( E ) & ( E )"::Text)])
2017 (Filter.And (Filter.Bool True) Filter.Any)
2018 (Filter.And (Filter.Bool True) Filter.Any)
2020 , "( E ) + ( E )" ~:
2021 (Data.Either.rights $
2023 (Filter.Read.test_bool
2024 [ P.char 'E' >> return (return True) ]
2026 () "" ("( E ) + ( E )"::Text)])
2029 (Filter.And (Filter.Bool True) Filter.Any)
2030 (Filter.And (Filter.Bool True) Filter.Any)
2032 , "( E ) - ( E )" ~:
2033 (Data.Either.rights $
2035 (Filter.Read.test_bool
2036 [ P.char 'E' >> return (return True) ]
2038 () "" ("( E ) - ( E )"::Text)])
2041 (Filter.And (Filter.Bool True) Filter.Any)
2042 (Filter.Not (Filter.And (Filter.Bool True) Filter.Any))
2045 (Data.Either.rights $
2047 (Filter.Read.test_bool
2048 [ P.char 'E' >> return (return True) ]
2050 () "" ("(- E )"::Text)])
2052 [ Filter.And (Filter.Not (Filter.Bool True)) Filter.Any
2057 , "Balance" ~: TestList
2058 [ "balance" ~: TestList
2059 [ "[A+$1] = A+$1 & $+1" ~:
2061 (Format.Ledger.posting ("A":|[]))
2062 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
2067 { Balance.balance_by_account =
2068 Lib.TreeMap.from_List const $
2069 Data.List.map (id *** Data.Map.map Amount.sum) $
2070 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2071 , Balance.balance_by_unit =
2073 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2075 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2076 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2081 , "[A+$1, A-$1] = {A+$0, $+0}" ~:
2083 (flip Balance.balance)
2085 [ (Format.Ledger.posting ("A":|[]))
2086 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
2088 , (Format.Ledger.posting ("A":|[]))
2089 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ]
2094 { Balance.balance_by_account =
2095 Lib.TreeMap.from_List const $
2097 , Data.Map.fromListWith const $
2098 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance s, s))
2104 , Balance.balance_by_unit =
2106 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2108 { Balance.unit_sum_amount = Amount.Sum_Both
2111 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2116 , "[A+$1, A-€1] = {A+$1-€1, $+1 €-1}" ~:
2118 (flip Balance.balance)
2120 [ (Format.Ledger.posting ("A":|[]))
2121 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
2123 , (Format.Ledger.posting ("A":|[]))
2124 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1 ]
2129 { Balance.balance_by_account =
2130 Lib.TreeMap.from_List const $
2131 Data.List.map (id *** Data.Map.map Amount.sum) $
2132 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ -1 ]) ]
2133 , Balance.balance_by_unit =
2135 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2137 { Balance.unit_sum_amount = Amount.Sum_Positive (Amount.usd $ 1)
2138 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2142 { Balance.unit_sum_amount = Amount.Sum_Negative (Amount.eur $ -1)
2143 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2148 , "[A+$1, B-$1] = {A+$1 B-$1, $+0}" ~:
2150 (flip Balance.balance)
2152 [ (Format.Ledger.posting ("A":|[]))
2153 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
2155 , (Format.Ledger.posting ("B":|[]))
2156 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ]
2161 { Balance.balance_by_account =
2162 Lib.TreeMap.from_List const $
2163 Data.List.map (id *** Data.Map.map Amount.sum) $
2164 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2165 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
2167 , Balance.balance_by_unit =
2169 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2171 { Balance.unit_sum_amount = Amount.Sum_Both
2174 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2181 (flip Balance.balance)
2183 [ (Format.Ledger.posting ("A":|[]))
2184 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
2186 , (Format.Ledger.posting ("B":|[]))
2187 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
2192 { Balance.balance_by_account =
2193 Lib.TreeMap.from_List const $
2194 Data.List.map (id *** Data.Map.map Amount.sum) $
2195 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2196 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ])
2198 , Balance.balance_by_unit =
2200 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2202 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 2
2203 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2208 , "[A+$1+€2, A-$1-€2] = {A+$0+€0, $+0 €+0}" ~:
2210 (flip Balance.balance)
2212 [ (Format.Ledger.posting ("A":|[]))
2213 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2 ]
2215 , (Format.Ledger.posting ("A":|[]))
2216 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2 ]
2221 { Balance.balance_by_account =
2222 Lib.TreeMap.from_List const $
2224 , Data.Map.fromListWith const $
2225 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance s, s))
2226 [ Amount.Sum_Both (Amount.usd $ -1) (Amount.usd $ 1)
2227 , Amount.Sum_Both (Amount.eur $ -2) (Amount.eur $ 2)
2231 , Balance.balance_by_unit =
2233 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2235 { Balance.unit_sum_amount = Amount.Sum_Both (Amount.usd $ -1) (Amount.usd $ 1)
2236 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2240 { Balance.unit_sum_amount = Amount.Sum_Both (Amount.eur $ -2) (Amount.eur $ 2)
2241 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2246 , "[A+$1+€2+£3, B-$1-2€-£3] = {A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~:
2248 (flip Balance.balance)
2250 [ (Format.Ledger.posting ("A":|[]))
2251 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ]
2253 , (Format.Ledger.posting ("B":|[]))
2254 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ]
2259 { Balance.balance_by_account =
2260 Lib.TreeMap.from_List const $
2261 Data.List.map (id *** Data.Map.map Amount.sum) $
2262 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
2263 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
2265 , Balance.balance_by_unit =
2267 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2269 { Balance.unit_sum_amount = Amount.Sum_Both (Amount.usd $ -1) (Amount.usd $ 1)
2270 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2274 { Balance.unit_sum_amount = Amount.Sum_Both (Amount.eur $ -2) (Amount.eur $ 2)
2275 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2279 { Balance.unit_sum_amount = Amount.Sum_Both (Amount.gbp $ -3) (Amount.gbp $ 3)
2280 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2286 , "union" ~: TestList
2287 [ "nil nil = nil" ~:
2288 Balance.union Balance.nil Balance.nil
2290 (Balance.nil::Balance.Balance Amount)
2291 , "{A+$1, $+1} {A+$1, $+1} = {A+$2, $+2}" ~:
2294 { Balance.balance_by_account =
2295 Lib.TreeMap.from_List const $
2296 Data.List.map (id *** Data.Map.map Amount.sum) $
2297 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2298 , Balance.balance_by_unit =
2300 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2302 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2303 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2309 { Balance.balance_by_account =
2310 Lib.TreeMap.from_List const $
2311 Data.List.map (id *** Data.Map.map Amount.sum) $
2312 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2313 , Balance.balance_by_unit =
2315 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2317 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2318 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2325 { Balance.balance_by_account =
2326 Lib.TreeMap.from_List const $
2327 Data.List.map (id *** Data.Map.map Amount.sum) $
2328 [ ("A":|[], Amount.from_List [ Amount.usd $ 2 ]) ]
2329 , Balance.balance_by_unit =
2331 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2333 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 2
2334 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2339 , "{A+$1, $+1} {B+$1, $+1} = {A+$1 B+$1, $+2}" ~:
2342 { Balance.balance_by_account =
2343 Lib.TreeMap.from_List const $
2344 Data.List.map (id *** Data.Map.map Amount.sum) $
2345 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2346 , Balance.balance_by_unit =
2348 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2350 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2351 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2357 { Balance.balance_by_account =
2358 Lib.TreeMap.from_List const $
2359 Data.List.map (id *** Data.Map.map Amount.sum) $
2360 [ ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2361 , Balance.balance_by_unit =
2363 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2365 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2366 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2373 { Balance.balance_by_account =
2374 Lib.TreeMap.from_List const $
2375 Data.List.map (id *** Data.Map.map Amount.sum) $
2376 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2377 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2378 , Balance.balance_by_unit =
2380 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2382 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 2
2383 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2388 , "{A+$1, $+1} {B+€1, €+1} = {A+$1 B+€1, $+1 €+1}" ~:
2391 { Balance.balance_by_account =
2392 Lib.TreeMap.from_List const $
2393 Data.List.map (id *** Data.Map.map Amount.sum) $
2394 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2395 , Balance.balance_by_unit =
2397 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2399 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2400 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2406 { Balance.balance_by_account =
2407 Lib.TreeMap.from_List const $
2408 Data.List.map (id *** Data.Map.map Amount.sum) $
2409 [ ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
2410 , Balance.balance_by_unit =
2412 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2414 { Balance.unit_sum_amount = Amount.sum $ Amount.eur $ 1
2415 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2422 { Balance.balance_by_account =
2423 Lib.TreeMap.from_List const $
2424 Data.List.map (id *** Data.Map.map Amount.sum) $
2425 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2426 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
2427 , Balance.balance_by_unit =
2429 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2431 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2432 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2436 { Balance.unit_sum_amount = Amount.sum $ Amount.eur $ 1
2437 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2443 , "expanded" ~: TestList
2444 [ "nil_By_Account" ~:
2448 (Lib.TreeMap.empty::Balance.Expanded Amount)
2451 (Lib.TreeMap.from_List const $
2452 Data.List.map (id *** Data.Map.map Amount.sum) $
2453 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ])
2455 (Lib.TreeMap.from_List const $
2456 [ ("A":|[], Balance.Account_Sum_Expanded
2457 { Balance.inclusive =
2458 Data.Map.map Amount.sum $
2459 Amount.from_List [ Amount.usd $ 1 ]
2460 , Balance.exclusive =
2461 Data.Map.map Amount.sum $
2462 Amount.from_List [ Amount.usd $ 1 ]
2465 , "A/A+$1 = A+$1 A/A+$1" ~:
2467 (Lib.TreeMap.from_List const $
2468 Data.List.map (id *** Data.Map.map Amount.sum) $
2469 [ ("A":|["A"], Amount.from_List [ Amount.usd $ 1 ]) ])
2471 (Lib.TreeMap.from_List const
2472 [ ("A":|[], Balance.Account_Sum_Expanded
2473 { Balance.inclusive =
2474 Data.Map.map Amount.sum $
2475 Amount.from_List [ Amount.usd $ 1 ]
2476 , Balance.exclusive =
2477 Data.Map.map Amount.sum $
2480 , ("A":|["A"], Balance.Account_Sum_Expanded
2481 { Balance.inclusive =
2482 Data.Map.map Amount.sum $
2483 Amount.from_List [ Amount.usd $ 1 ]
2484 , Balance.exclusive =
2485 Data.Map.map Amount.sum $
2486 Amount.from_List [ Amount.usd $ 1 ]
2489 , "A/B+$1 = A+$1 A/B+$1" ~:
2491 (Lib.TreeMap.from_List const $
2492 Data.List.map (id *** Data.Map.map Amount.sum) $
2493 [ ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ]) ])
2495 (Lib.TreeMap.from_List const
2496 [ ("A":|[], Balance.Account_Sum_Expanded
2497 { Balance.inclusive =
2498 Data.Map.map Amount.sum $
2499 Amount.from_List [ Amount.usd $ 1 ]
2500 , Balance.exclusive =
2501 Data.Map.map Amount.sum $
2504 , ("A":|["B"], Balance.Account_Sum_Expanded
2505 { Balance.inclusive =
2506 Data.Map.map Amount.sum $
2507 Amount.from_List [ Amount.usd $ 1 ]
2508 , Balance.exclusive =
2509 Data.Map.map Amount.sum $
2510 Amount.from_List [ Amount.usd $ 1 ]
2513 , "A/B/C+$1 = A+$1 A/B+$1 A/B/C+$1" ~:
2515 (Lib.TreeMap.from_List const $
2516 Data.List.map (id *** Data.Map.map Amount.sum) $
2517 [ ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ]) ])
2519 (Lib.TreeMap.from_List const $
2520 [ ("A":|[], Balance.Account_Sum_Expanded
2521 { Balance.inclusive =
2522 Data.Map.map Amount.sum $
2523 Amount.from_List [ Amount.usd $ 1 ]
2524 , Balance.exclusive =
2525 Data.Map.map Amount.sum $
2528 , ("A":|["B"], Balance.Account_Sum_Expanded
2529 { Balance.inclusive =
2530 Data.Map.map Amount.sum $
2531 Amount.from_List [ Amount.usd $ 1 ]
2532 , Balance.exclusive =
2533 Data.Map.map Amount.sum $
2536 , ("A":|["B", "C"], Balance.Account_Sum_Expanded
2537 { Balance.inclusive =
2538 Data.Map.map Amount.sum $
2539 Amount.from_List [ Amount.usd $ 1 ]
2540 , Balance.exclusive =
2541 Data.Map.map Amount.sum $
2542 Amount.from_List [ Amount.usd $ 1 ]
2545 , "A+$1 A/B+$1 = A+$2 A/B+$1" ~:
2547 (Lib.TreeMap.from_List const $
2548 Data.List.map (id *** Data.Map.map Amount.sum) $
2549 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2550 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
2553 (Lib.TreeMap.from_List const
2554 [ ("A":|[], Balance.Account_Sum_Expanded
2555 { Balance.inclusive =
2556 Data.Map.map Amount.sum $
2557 Amount.from_List [ Amount.usd $ 2 ]
2558 , Balance.exclusive =
2559 Data.Map.map Amount.sum $
2560 Amount.from_List [ Amount.usd $ 1 ]
2562 , ("A":|["B"], Balance.Account_Sum_Expanded
2563 { Balance.inclusive =
2564 Data.Map.map Amount.sum $
2565 Amount.from_List [ Amount.usd $ 1 ]
2566 , Balance.exclusive =
2567 Data.Map.map Amount.sum $
2568 Amount.from_List [ Amount.usd $ 1 ]
2571 , "A+$1 A/B+$1 A/B/C+$1 = A+$3 A/B+$2 A/B/C+$1" ~:
2573 (Lib.TreeMap.from_List const $
2574 Data.List.map (id *** Data.Map.map Amount.sum) $
2575 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2576 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
2577 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
2580 (Lib.TreeMap.from_List const
2581 [ ("A":|[], Balance.Account_Sum_Expanded
2582 { Balance.inclusive =
2583 Data.Map.map Amount.sum $
2584 Amount.from_List [ Amount.usd $ 3 ]
2585 , Balance.exclusive =
2586 Data.Map.map Amount.sum $
2587 Amount.from_List [ Amount.usd $ 1 ]
2589 , ("A":|["B"], Balance.Account_Sum_Expanded
2590 { Balance.inclusive =
2591 Data.Map.map Amount.sum $
2592 Amount.from_List [ Amount.usd $ 2 ]
2593 , Balance.exclusive =
2594 Data.Map.map Amount.sum $
2595 Amount.from_List [ Amount.usd $ 1 ]
2597 , ("A":|["B", "C"], Balance.Account_Sum_Expanded
2598 { Balance.inclusive =
2599 Data.Map.map Amount.sum $
2600 Amount.from_List [ Amount.usd $ 1 ]
2601 , Balance.exclusive =
2602 Data.Map.map Amount.sum $
2603 Amount.from_List [ Amount.usd $ 1 ]
2606 , "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" ~:
2608 (Lib.TreeMap.from_List const $
2609 Data.List.map (id *** Data.Map.map Amount.sum) $
2610 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2611 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
2612 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
2613 , ("A":|["B", "C", "D"], Amount.from_List [ Amount.usd $ 1 ])
2616 (Lib.TreeMap.from_List const
2617 [ ("A":|[], Balance.Account_Sum_Expanded
2618 { Balance.inclusive =
2619 Data.Map.map Amount.sum $
2620 Amount.from_List [ Amount.usd $ 4 ]
2621 , Balance.exclusive =
2622 Data.Map.map Amount.sum $
2623 Amount.from_List [ Amount.usd $ 1 ]
2625 , ("A":|["B"], Balance.Account_Sum_Expanded
2626 { Balance.inclusive =
2627 Data.Map.map Amount.sum $
2628 Amount.from_List [ Amount.usd $ 3 ]
2629 , Balance.exclusive =
2630 Data.Map.map Amount.sum $
2631 Amount.from_List [ Amount.usd $ 1 ]
2633 , ("A":|["B", "C"], Balance.Account_Sum_Expanded
2634 { Balance.inclusive =
2635 Data.Map.map Amount.sum $
2636 Amount.from_List [ Amount.usd $ 2 ]
2637 , Balance.exclusive =
2638 Data.Map.map Amount.sum $
2639 Amount.from_List [ Amount.usd $ 1 ]
2641 , ("A":|["B", "C", "D"], Balance.Account_Sum_Expanded
2642 { Balance.inclusive =
2643 Data.Map.map Amount.sum $
2644 Amount.from_List [ Amount.usd $ 1 ]
2645 , Balance.exclusive =
2646 Data.Map.map Amount.sum $
2647 Amount.from_List [ Amount.usd $ 1 ]
2650 , "A+$1 A/B+$1 A/BB+$1 AA/B+$1 = A+$3 A/B+$1 A/BB+$1 AA+$1 AA/B+$1" ~:
2652 (Lib.TreeMap.from_List const $
2653 Data.List.map (id *** Data.Map.map Amount.sum) $
2654 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2655 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
2656 , ("A":|["BB"], Amount.from_List [ Amount.usd $ 1 ])
2657 , ("AA":|["B"], Amount.from_List [ Amount.usd $ 1 ])
2660 (Lib.TreeMap.from_List const
2661 [ ("A":|[], Balance.Account_Sum_Expanded
2662 { Balance.inclusive =
2663 Data.Map.map Amount.sum $
2664 Amount.from_List [ Amount.usd $ 3 ]
2665 , Balance.exclusive =
2666 Data.Map.map Amount.sum $
2667 Amount.from_List [ Amount.usd $ 1 ]
2669 , ("A":|["B"], Balance.Account_Sum_Expanded
2670 { Balance.inclusive =
2671 Data.Map.map Amount.sum $
2672 Amount.from_List [ Amount.usd $ 1 ]
2673 , Balance.exclusive =
2674 Data.Map.map Amount.sum $
2675 Amount.from_List [ Amount.usd $ 1 ]
2677 , ("A":|["BB"], Balance.Account_Sum_Expanded
2678 { Balance.inclusive =
2679 Data.Map.map Amount.sum $
2680 Amount.from_List [ Amount.usd $ 1 ]
2681 , Balance.exclusive =
2682 Data.Map.map Amount.sum $
2683 Amount.from_List [ Amount.usd $ 1 ]
2685 , ("AA":|[], Balance.Account_Sum_Expanded
2686 { Balance.inclusive =
2687 Data.Map.map Amount.sum $
2688 Amount.from_List [ Amount.usd $ 1 ]
2689 , Balance.exclusive =
2690 Data.Map.map Amount.sum $
2693 , ("AA":|["B"], Balance.Account_Sum_Expanded
2694 { Balance.inclusive =
2695 Data.Map.map Amount.sum $
2696 Amount.from_List [ Amount.usd $ 1 ]
2697 , Balance.exclusive =
2698 Data.Map.map Amount.sum $
2699 Amount.from_List [ Amount.usd $ 1 ]
2703 , "deviation" ~: TestList
2705 (Balance.deviation $
2707 { Balance.balance_by_account =
2708 Lib.TreeMap.from_List const $
2709 Data.List.map (id *** Data.Map.map Amount.sum) $
2710 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2711 , ("B":|[], Amount.from_List [])
2713 , Balance.balance_by_unit =
2715 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2717 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2718 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2724 (Balance.Deviation $
2726 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2728 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2729 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2733 , "{A+$1 B+$1, $2}" ~:
2734 (Balance.deviation $
2736 { Balance.balance_by_account =
2737 Lib.TreeMap.from_List const $
2738 Data.List.map (id *** Data.Map.map Amount.sum) $
2739 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2740 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ])
2742 , Balance.balance_by_unit =
2744 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2746 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 2
2747 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2755 (Balance.Deviation $
2757 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2759 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 2
2760 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2766 , "is_equilibrium_inferrable" ~: TestList
2767 [ "nil" ~: TestCase $
2769 Balance.is_equilibrium_inferrable $
2771 (Balance.nil::Balance.Balance Amount.Amount)
2772 , "{A+$0, $+0}" ~: TestCase $
2774 Balance.is_equilibrium_inferrable $
2777 { Balance.balance_by_account =
2778 Lib.TreeMap.from_List const $
2779 Data.List.map (id *** Data.Map.map Amount.sum) $
2780 [ ("A":|[], Amount.from_List [ Amount.usd $ 0 ])
2782 , Balance.balance_by_unit =
2784 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2786 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 0
2787 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2792 , "{A+$1, $+1}" ~: TestCase $
2794 Balance.is_equilibrium_inferrable $
2797 { Balance.balance_by_account =
2798 Lib.TreeMap.from_List const $
2799 Data.List.map (id *** Data.Map.map Amount.sum) $
2800 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2802 , Balance.balance_by_unit =
2804 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2806 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2807 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2812 , "{A+$0+€0, $0 €+0}" ~: TestCase $
2814 Balance.is_equilibrium_inferrable $
2817 { Balance.balance_by_account =
2818 Lib.TreeMap.from_List const $
2819 Data.List.map (id *** Data.Map.map Amount.sum) $
2820 [ ("A":|[], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
2822 , Balance.balance_by_unit =
2824 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2826 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 0
2827 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2831 { Balance.unit_sum_amount = Amount.sum $ Amount.eur $ 0
2832 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2837 , "{A+$1, B-$1, $+0}" ~: TestCase $
2839 Balance.is_equilibrium_inferrable $
2842 { Balance.balance_by_account =
2843 Lib.TreeMap.from_List const $
2844 Data.List.map (id *** Data.Map.map Amount.sum) $
2845 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2846 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
2848 , Balance.balance_by_unit =
2850 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2852 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 0
2853 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2858 , "{A+$1 B, $+1}" ~: TestCase $
2860 Balance.is_equilibrium_inferrable $
2863 { Balance.balance_by_account =
2864 Lib.TreeMap.from_List const $
2865 Data.List.map (id *** Data.Map.map Amount.sum) $
2866 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2867 , ("B":|[], Amount.from_List [])
2869 , Balance.balance_by_unit =
2871 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2873 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2874 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2879 , "{A+$1 B+€1, $+1 €+1}" ~: TestCase $
2881 Balance.is_equilibrium_inferrable $
2884 { Balance.balance_by_account =
2885 Lib.TreeMap.from_List const $
2886 Data.List.map (id *** Data.Map.map Amount.sum) $
2887 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2888 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ])
2890 , Balance.balance_by_unit =
2892 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2894 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2895 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2899 { Balance.unit_sum_amount = Amount.sum $ Amount.eur $ 1
2900 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2905 , "{A+$1 B-$1+€1, $+0 €+1}" ~: TestCase $
2907 Balance.is_equilibrium_inferrable $
2910 { Balance.balance_by_account =
2911 Lib.TreeMap.from_List const $
2912 Data.List.map (id *** Data.Map.map Amount.sum) $
2913 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2914 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ 1 ])
2916 , Balance.balance_by_unit =
2918 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2920 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 0
2921 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2925 { Balance.unit_sum_amount = Amount.sum $ Amount.eur $ 1
2926 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2931 , "{A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~: TestCase $
2933 Balance.is_equilibrium_inferrable $
2936 { Balance.balance_by_account =
2937 Lib.TreeMap.from_List const $
2938 Data.List.map (id *** Data.Map.map Amount.sum) $
2939 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
2940 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
2942 , Balance.balance_by_unit =
2944 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2946 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 0
2947 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2951 { Balance.unit_sum_amount = Amount.sum $ Amount.eur $ 0
2952 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2956 { Balance.unit_sum_amount = Amount.sum $ Amount.gbp $ 0
2957 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2963 , "infer_equilibrium" ~: TestList
2965 (snd $ Balance.infer_equilibrium $
2966 Format.Ledger.posting_by_Account
2967 [ (Format.Ledger.posting ("A":|[]))
2968 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
2969 , (Format.Ledger.posting ("B":|[]))
2970 { Format.Ledger.posting_amounts=Amount.from_List [] }
2974 Format.Ledger.posting_by_Account
2975 [ (Format.Ledger.posting ("A":|[]))
2976 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
2977 , (Format.Ledger.posting ("B":|[]))
2978 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ] }
2981 (snd $ Balance.infer_equilibrium $
2982 Format.Ledger.posting_by_Account
2983 [ (Format.Ledger.posting ("A":|[]))
2984 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
2985 , (Format.Ledger.posting ("B":|[]))
2986 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1 ] }
2990 Format.Ledger.posting_by_Account
2991 [ (Format.Ledger.posting ("A":|[]))
2992 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 1] }
2993 , (Format.Ledger.posting ("B":|[]))
2994 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1, Amount.usd $ -1 ] }
2997 (snd $ Balance.infer_equilibrium $
2998 Format.Ledger.posting_by_Account
2999 [ (Format.Ledger.posting ("A":|[]))
3000 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
3001 , (Format.Ledger.posting ("B":|[]))
3002 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
3007 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 2
3008 , Balance.unit_sum_accounts = Data.Map.fromList []}
3010 , "{A+$1 B-$1 B-1€}" ~:
3011 (snd $ Balance.infer_equilibrium $
3012 Format.Ledger.posting_by_Account
3013 [ (Format.Ledger.posting ("A":|[]))
3014 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
3015 , (Format.Ledger.posting ("B":|[]))
3016 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -1 ] }
3020 Format.Ledger.posting_by_Account
3021 [ (Format.Ledger.posting ("A":|[]))
3022 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 1 ] }
3023 , (Format.Ledger.posting ("B":|[]))
3024 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -1 ] }
3028 , "Format" ~: TestList
3029 [ "Ledger" ~: TestList
3030 [ "Read" ~: TestList
3031 [ "account_name" ~: TestList
3033 (Data.Either.rights $
3035 (Format.Ledger.Read.account_name <* P.eof)
3040 (Data.Either.rights $
3042 (Format.Ledger.Read.account_name <* P.eof)
3047 (Data.Either.rights $
3049 (Format.Ledger.Read.account_name <* P.eof)
3050 () "" ("AA"::Text)])
3054 (Data.Either.rights $
3056 (Format.Ledger.Read.account_name <* P.eof)
3061 (Data.Either.rights $
3063 (Format.Ledger.Read.account_name <* P.eof)
3068 (Data.Either.rights $
3070 (Format.Ledger.Read.account_name <* P.eof)
3071 () "" ("A:"::Text)])
3075 (Data.Either.rights $
3077 (Format.Ledger.Read.account_name <* P.eof)
3078 () "" (":A"::Text)])
3082 (Data.Either.rights $
3084 (Format.Ledger.Read.account_name <* P.eof)
3085 () "" ("A "::Text)])
3089 (Data.Either.rights $
3091 (Format.Ledger.Read.account_name)
3092 () "" ("A "::Text)])
3096 (Data.Either.rights $
3098 (Format.Ledger.Read.account_name <* P.eof)
3099 () "" ("A A"::Text)])
3103 (Data.Either.rights $
3105 (Format.Ledger.Read.account_name <* P.eof)
3106 () "" ("A "::Text)])
3110 (Data.Either.rights $
3112 (Format.Ledger.Read.account_name <* P.eof)
3113 () "" ("A \n"::Text)])
3117 (Data.Either.rights $
3119 (Format.Ledger.Read.account_name <* P.eof)
3120 () "" ("(A)A"::Text)])
3124 (Data.Either.rights $
3126 (Format.Ledger.Read.account_name <* P.eof)
3127 () "" ("( )A"::Text)])
3131 (Data.Either.rights $
3133 (Format.Ledger.Read.account_name <* P.eof)
3134 () "" ("(A) A"::Text)])
3138 (Data.Either.rights $
3140 (Format.Ledger.Read.account_name <* P.eof)
3141 () "" ("[ ]A"::Text)])
3145 (Data.Either.rights $
3147 (Format.Ledger.Read.account_name <* P.eof)
3148 () "" ("(A) "::Text)])
3152 (Data.Either.rights $
3154 (Format.Ledger.Read.account_name <* P.eof)
3155 () "" ("(A)"::Text)])
3159 (Data.Either.rights $
3161 (Format.Ledger.Read.account_name <* P.eof)
3162 () "" ("A(A)"::Text)])
3166 (Data.Either.rights $
3168 (Format.Ledger.Read.account_name <* P.eof)
3169 () "" ("[A]A"::Text)])
3173 (Data.Either.rights $
3175 (Format.Ledger.Read.account_name <* P.eof)
3176 () "" ("[A] A"::Text)])
3180 (Data.Either.rights $
3182 (Format.Ledger.Read.account_name <* P.eof)
3183 () "" ("[A] "::Text)])
3187 (Data.Either.rights $
3189 (Format.Ledger.Read.account_name <* P.eof)
3190 () "" ("[A]"::Text)])
3194 , "account" ~: TestList
3196 (Data.Either.rights $
3198 (Format.Ledger.Read.account <* P.eof)
3203 (Data.Either.rights $
3205 (Format.Ledger.Read.account <* P.eof)
3210 (Data.Either.rights $
3212 (Format.Ledger.Read.account <* P.eof)
3213 () "" ("A:"::Text)])
3217 (Data.Either.rights $
3219 (Format.Ledger.Read.account <* P.eof)
3220 () "" (":A"::Text)])
3224 (Data.Either.rights $
3226 (Format.Ledger.Read.account <* P.eof)
3227 () "" ("A "::Text)])
3231 (Data.Either.rights $
3233 (Format.Ledger.Read.account <* P.eof)
3234 () "" (" A"::Text)])
3238 (Data.Either.rights $
3240 (Format.Ledger.Read.account <* P.eof)
3241 () "" ("A:B"::Text)])
3245 (Data.Either.rights $
3247 (Format.Ledger.Read.account <* P.eof)
3248 () "" ("A:B:C"::Text)])
3251 , "\"Aa:Bbb:Cccc\"" ~:
3252 (Data.Either.rights $
3254 (Format.Ledger.Read.account <* P.eof)
3255 () "" ("Aa:Bbb:Cccc"::Text)])
3257 ["Aa":|["Bbb", "Cccc"]]
3258 , "\"A a : B b b : C c c c\"" ~:
3259 (Data.Either.rights $
3261 (Format.Ledger.Read.account <* P.eof)
3262 () "" ("A a : B b b : C c c c"::Text)])
3264 ["A a ":|[" B b b ", " C c c c"]]
3266 (Data.Either.rights $
3268 (Format.Ledger.Read.account <* P.eof)
3269 () "" ("A: :C"::Text)])
3273 (Data.Either.rights $
3275 (Format.Ledger.Read.account <* P.eof)
3276 () "" ("A::C"::Text)])
3280 (Data.Either.rights $
3282 (Format.Ledger.Read.account <* P.eof)
3283 () "" ("A:B:(C)"::Text)])
3287 , "posting_type" ~: TestList
3289 Format.Ledger.Read.posting_type
3292 (Format.Ledger.Posting_Type_Regular, "A":|[])
3294 Format.Ledger.Read.posting_type
3297 (Format.Ledger.Posting_Type_Regular, "(":|[])
3299 Format.Ledger.Read.posting_type
3302 (Format.Ledger.Posting_Type_Regular, ")":|[])
3304 Format.Ledger.Read.posting_type
3307 (Format.Ledger.Posting_Type_Regular, "()":|[])
3309 Format.Ledger.Read.posting_type
3312 (Format.Ledger.Posting_Type_Regular, "( )":|[])
3314 Format.Ledger.Read.posting_type
3317 (Format.Ledger.Posting_Type_Virtual, "A":|[])
3319 Format.Ledger.Read.posting_type
3322 (Format.Ledger.Posting_Type_Virtual, "A":|["B", "C"])
3324 Format.Ledger.Read.posting_type
3327 (Format.Ledger.Posting_Type_Regular, "A":|["B", "C"])
3329 Format.Ledger.Read.posting_type
3332 (Format.Ledger.Posting_Type_Regular, "(A)":|["B", "C"])
3334 Format.Ledger.Read.posting_type
3337 (Format.Ledger.Posting_Type_Regular, "A":|["(B)", "C"])
3339 Format.Ledger.Read.posting_type
3342 (Format.Ledger.Posting_Type_Regular, "A":|["B", "(C)"])
3344 Format.Ledger.Read.posting_type
3347 (Format.Ledger.Posting_Type_Regular, "[":|[])
3349 Format.Ledger.Read.posting_type
3352 (Format.Ledger.Posting_Type_Regular, "]":|[])
3354 Format.Ledger.Read.posting_type
3357 (Format.Ledger.Posting_Type_Regular, "[]":|[])
3359 Format.Ledger.Read.posting_type
3362 (Format.Ledger.Posting_Type_Regular, "[ ]":|[])
3364 Format.Ledger.Read.posting_type
3367 (Format.Ledger.Posting_Type_Virtual_Balanced, "A":|[])
3369 Format.Ledger.Read.posting_type
3372 (Format.Ledger.Posting_Type_Virtual_Balanced, "A":|["B", "C"])
3374 Format.Ledger.Read.posting_type
3377 (Format.Ledger.Posting_Type_Regular, "A":|["B", "C"])
3379 Format.Ledger.Read.posting_type
3382 (Format.Ledger.Posting_Type_Regular, "[A]":|["B", "C"])
3384 Format.Ledger.Read.posting_type
3387 (Format.Ledger.Posting_Type_Regular, "A":|["[B]", "C"])
3389 Format.Ledger.Read.posting_type
3392 (Format.Ledger.Posting_Type_Regular, "A":|["B", "[C]"])
3394 , "comment" ~: TestList
3395 [ "; some comment = Right \" some comment\"" ~:
3396 (Data.Either.rights $
3398 (Format.Ledger.Read.comment <* P.eof)
3399 () "" ("; some comment"::Text)])
3402 , "; some comment \\n = Right \" some comment \"" ~:
3403 (Data.Either.rights $
3405 (Format.Ledger.Read.comment <* P.newline <* P.eof)
3406 () "" ("; some comment \n"::Text)])
3408 [ " some comment " ]
3409 , "; some comment \\r\\n = Right \" some comment \"" ~:
3410 (Data.Either.rights $
3412 (Format.Ledger.Read.comment <* P.string "\r\n" <* P.eof)
3413 () "" ("; some comment \r\n"::Text)])
3415 [ " some comment " ]
3417 , "comments" ~: TestList
3418 [ "; some comment\\n ; some other comment = Right [\" some comment\", \" some other comment\"]" ~:
3419 (Data.Either.rights $
3421 (Format.Ledger.Read.comments <* P.eof)
3422 () "" ("; some comment\n ; some other comment"::Text)])
3424 [ [" some comment", " some other comment"] ]
3425 , "; some comment \\n = Right \" some comment \"" ~:
3426 (Data.Either.rights $
3428 (Format.Ledger.Read.comments <* P.string "\n" <* P.eof)
3429 () "" ("; some comment \n"::Text)])
3431 [ [" some comment "] ]
3433 , "tag_value" ~: TestList
3435 (Data.Either.rights $
3437 (Format.Ledger.Read.tag_value <* P.eof)
3442 (Data.Either.rights $
3444 (Format.Ledger.Read.tag_value <* P.char '\n' <* P.eof)
3445 () "" (",\n"::Text)])
3449 (Data.Either.rights $
3451 (Format.Ledger.Read.tag_value <* P.eof)
3452 () "" (",x"::Text)])
3456 (Data.Either.rights $
3458 (Format.Ledger.Read.tag_value <* P.string ",x:" <* P.eof)
3459 () "" (",x:"::Text)])
3463 (Data.Either.rights $
3465 (Format.Ledger.Read.tag_value <* P.string ", n:" <* P.eof)
3466 () "" ("v, v, n:"::Text)])
3472 (Data.Either.rights $
3474 (Format.Ledger.Read.tag <* P.eof)
3475 () "" ("Name:"::Text)])
3479 (Data.Either.rights $
3481 (Format.Ledger.Read.tag <* P.eof)
3482 () "" ("Name:Value"::Text)])
3485 , "Name:Value\\n" ~:
3486 (Data.Either.rights $
3488 (Format.Ledger.Read.tag <* P.string "\n" <* P.eof)
3489 () "" ("Name:Value\n"::Text)])
3493 (Data.Either.rights $
3495 (Format.Ledger.Read.tag <* P.eof)
3496 () "" ("Name:Val ue"::Text)])
3498 [("Name", "Val ue")]
3500 (Data.Either.rights $
3502 (Format.Ledger.Read.tag <* P.eof)
3503 () "" ("Name:,"::Text)])
3507 (Data.Either.rights $
3509 (Format.Ledger.Read.tag <* P.eof)
3510 () "" ("Name:Val,ue"::Text)])
3512 [("Name", "Val,ue")]
3514 (Data.Either.rights $
3516 (Format.Ledger.Read.tag <* P.string ",ue:" <* P.eof)
3517 () "" ("Name:Val,ue:"::Text)])
3521 , "tags" ~: TestList
3523 (Data.Either.rights $
3525 (Format.Ledger.Read.tags <* P.eof)
3526 () "" ("Name:"::Text)])
3533 (Data.Either.rights $
3535 (Format.Ledger.Read.tags <* P.eof)
3536 () "" ("Name:,"::Text)])
3543 (Data.Either.rights $
3545 (Format.Ledger.Read.tags <* P.eof)
3546 () "" ("Name:,Name:"::Text)])
3549 [ ("Name", ["", ""])
3553 (Data.Either.rights $
3555 (Format.Ledger.Read.tags <* P.eof)
3556 () "" ("Name:,Name2:"::Text)])
3563 , "Name: , Name2:" ~:
3564 (Data.Either.rights $
3566 (Format.Ledger.Read.tags <* P.eof)
3567 () "" ("Name: , Name2:"::Text)])
3574 , "Name:,Name2:,Name3:" ~:
3575 (Data.Either.rights $
3577 (Format.Ledger.Read.tags <* P.eof)
3578 () "" ("Name:,Name2:,Name3:"::Text)])
3586 , "Name:Val ue,Name2:V a l u e,Name3:V al ue" ~:
3587 (Data.Either.rights $
3589 (Format.Ledger.Read.tags <* P.eof)
3590 () "" ("Name:Val ue,Name2:V a l u e,Name3:V al ue"::Text)])
3593 [ ("Name", ["Val ue"])
3594 , ("Name2", ["V a l u e"])
3595 , ("Name3", ["V al ue"])
3599 , "posting" ~: TestList
3600 [ " A:B:C = Right A:B:C" ~:
3601 (Data.Either.rights $
3602 [P.runParser_with_Error
3603 (Format.Ledger.Read.posting <* P.eof)
3604 Format.Ledger.Read.nil_Context "" (" A:B:C"::Text)])
3606 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
3607 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3609 , Format.Ledger.Posting_Type_Regular
3612 , " !A:B:C = Right !A:B:C" ~:
3613 (Data.List.map fst $
3614 Data.Either.rights $
3615 [P.runParser_with_Error
3616 (Format.Ledger.Read.posting <* P.eof)
3617 Format.Ledger.Read.nil_Context "" (" !A:B:C"::Text)])
3619 [ (Format.Ledger.posting ("A":|["B", "C"]))
3620 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3621 , Format.Ledger.posting_status = True
3624 , " *A:B:C = Right *A:B:C" ~:
3625 (Data.List.map fst $
3626 Data.Either.rights $
3627 [P.runParser_with_Error
3628 (Format.Ledger.Read.posting <* P.eof)
3629 Format.Ledger.Read.nil_Context "" (" *A:B:C"::Text)])
3631 [ (Format.Ledger.posting ("A":|["B", "C"]))
3632 { Format.Ledger.posting_amounts = Data.Map.fromList []
3633 , Format.Ledger.posting_comments = []
3634 , Format.Ledger.posting_dates = []
3635 , Format.Ledger.posting_status = True
3636 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3637 , Format.Ledger.posting_tags = Data.Map.fromList []
3640 , " A:B:C $1 = Right A:B:C $1" ~:
3641 (Data.List.map fst $
3642 Data.Either.rights $
3643 [P.runParser_with_Error
3644 (Format.Ledger.Read.posting <* P.eof)
3645 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
3647 [ (Format.Ledger.posting ("A":|["B","C $1"]))
3648 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3651 , " A:B:C $1 = Right A:B:C $1" ~:
3652 (Data.List.map fst $
3653 Data.Either.rights $
3654 [P.runParser_with_Error
3655 (Format.Ledger.Read.posting <* P.eof)
3656 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
3658 [ (Format.Ledger.posting ("A":|["B", "C"]))
3659 { Format.Ledger.posting_amounts = Data.Map.fromList
3661 { Amount.quantity = 1
3662 , Amount.style = Amount.Style.nil
3663 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3664 , Amount.Style.unit_spaced = Just False
3669 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3672 , " A:B:C $1 + 1€ = Right A:B:C $1 + 1€" ~:
3673 (Data.List.map fst $
3674 Data.Either.rights $
3675 [P.runParser_with_Error
3676 (Format.Ledger.Read.posting <* P.eof)
3677 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1€"::Text)])
3679 [ (Format.Ledger.posting ("A":|["B", "C"]))
3680 { Format.Ledger.posting_amounts = Data.Map.fromList
3682 { Amount.quantity = 1
3683 , Amount.style = Amount.Style.nil
3684 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3685 , Amount.Style.unit_spaced = Just False
3690 { Amount.quantity = 1
3691 , Amount.style = Amount.Style.nil
3692 { Amount.Style.unit_side = Just Amount.Style.Side_Right
3693 , Amount.Style.unit_spaced = Just False
3698 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3701 , " A:B:C $1 + 1$ = Right A:B:C $2" ~:
3702 (Data.List.map fst $
3703 Data.Either.rights $
3704 [P.runParser_with_Error
3705 (Format.Ledger.Read.posting <* P.eof)
3706 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$"::Text)])
3708 [ (Format.Ledger.posting ("A":|["B", "C"]))
3709 { Format.Ledger.posting_amounts = Data.Map.fromList
3711 { Amount.quantity = 2
3712 , Amount.style = Amount.Style.nil
3713 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3714 , Amount.Style.unit_spaced = Just False
3719 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3722 , " A:B:C $1 + 1$ + 1$ = Right A:B:C $3" ~:
3723 (Data.List.map fst $
3724 Data.Either.rights $
3725 [P.runParser_with_Error
3726 (Format.Ledger.Read.posting <* P.eof)
3727 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$ + 1$"::Text)])
3729 [ (Format.Ledger.posting ("A":|["B", "C"]))
3730 { Format.Ledger.posting_amounts = Data.Map.fromList
3732 { Amount.quantity = 3
3733 , Amount.style = Amount.Style.nil
3734 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3735 , Amount.Style.unit_spaced = Just False
3740 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3743 , " A:B:C ; some comment = Right A:B:C ; some comment" ~:
3744 (Data.List.map fst $
3745 Data.Either.rights $
3746 [P.runParser_with_Error
3747 (Format.Ledger.Read.posting <* P.eof)
3748 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment"::Text)])
3750 [ (Format.Ledger.posting ("A":|["B", "C"]))
3751 { Format.Ledger.posting_amounts = Data.Map.fromList []
3752 , Format.Ledger.posting_comments = [" some comment"]
3753 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3756 , " A:B:C ; some comment\\n ; some other comment = Right A:B:C ; some comment\\n ; some other comment" ~:
3757 (Data.List.map fst $
3758 Data.Either.rights $
3759 [P.runParser_with_Error
3760 (Format.Ledger.Read.posting <* P.eof)
3761 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment\n ; some other comment"::Text)])
3763 [ (Format.Ledger.posting ("A":|["B", "C"]))
3764 { Format.Ledger.posting_amounts = Data.Map.fromList []
3765 , Format.Ledger.posting_comments = [" some comment", " some other comment"]
3766 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3769 , " A:B:C $1 ; some comment = Right A:B:C $1 ; some comment" ~:
3770 (Data.List.map fst $
3771 Data.Either.rights $
3772 [P.runParser_with_Error
3773 (Format.Ledger.Read.posting)
3774 Format.Ledger.Read.nil_Context "" (" A:B:C $1 ; some comment"::Text)])
3776 [ (Format.Ledger.posting ("A":|["B", "C"]))
3777 { Format.Ledger.posting_amounts = Data.Map.fromList
3779 { Amount.quantity = 1
3780 , Amount.style = Amount.Style.nil
3781 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3782 , Amount.Style.unit_spaced = Just False
3787 , Format.Ledger.posting_comments = [" some comment"]
3788 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3791 , " A:B:C ; N:V = Right A:B:C ; N:V" ~:
3792 (Data.List.map fst $
3793 Data.Either.rights $
3794 [P.runParser_with_Error
3795 (Format.Ledger.Read.posting <* P.eof)
3796 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V"::Text)])
3798 [ (Format.Ledger.posting ("A":|["B", "C"]))
3799 { Format.Ledger.posting_comments = [" N:V"]
3800 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3801 , Format.Ledger.posting_tags = Data.Map.fromList
3806 , " A:B:C ; some comment N:V = Right A:B:C ; some comment N:V" ~:
3807 (Data.List.map fst $
3808 Data.Either.rights $
3809 [P.runParser_with_Error
3810 (Format.Ledger.Read.posting <* P.eof)
3811 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V"::Text)])
3813 [ (Format.Ledger.posting ("A":|["B", "C"]))
3814 { Format.Ledger.posting_comments = [" some comment N:V"]
3815 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3816 , Format.Ledger.posting_tags = Data.Map.fromList
3821 , " A:B:C ; some comment N:V v, N2:V2 v2 = Right A:B:C ; some comment N:V v, N2:V2 v2" ~:
3822 (Data.List.map fst $
3823 Data.Either.rights $
3824 [P.runParser_with_Error
3825 (Format.Ledger.Read.posting )
3826 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V v, N2:V2 v2"::Text)])
3828 [ (Format.Ledger.posting ("A":|["B", "C"]))
3829 { Format.Ledger.posting_comments = [" some comment N:V v, N2:V2 v2"]
3830 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3831 , Format.Ledger.posting_tags = Data.Map.fromList
3837 , " A:B:C ; N:V\\n ; N:V2 = Right A:B:C ; N:V\\n ; N:V2" ~:
3838 (Data.List.map fst $
3839 Data.Either.rights $
3840 [P.runParser_with_Error
3841 (Format.Ledger.Read.posting <* P.eof)
3842 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N:V2"::Text)])
3844 [ (Format.Ledger.posting ("A":|["B", "C"]))
3845 { Format.Ledger.posting_comments = [" N:V", " N:V2"]
3846 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3847 , Format.Ledger.posting_tags = Data.Map.fromList
3848 [ ("N", ["V", "V2"])
3852 , " A:B:C ; N:V\\n ; N2:V = Right A:B:C ; N:V\\n ; N2:V" ~:
3853 (Data.List.map fst $
3854 Data.Either.rights $
3855 [P.runParser_with_Error
3856 (Format.Ledger.Read.posting <* P.eof)
3857 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N2:V"::Text)])
3859 [ (Format.Ledger.posting ("A":|["B", "C"]))
3860 { Format.Ledger.posting_comments = [" N:V", " N2:V"]
3861 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3862 , Format.Ledger.posting_tags = Data.Map.fromList
3868 , " A:B:C ; date:2001/01/01 = Right A:B:C ; date:2001/01/01" ~:
3869 (Data.List.map fst $
3870 Data.Either.rights $
3871 [P.runParser_with_Error
3872 (Format.Ledger.Read.posting <* P.eof)
3873 Format.Ledger.Read.nil_Context "" (" A:B:C ; date:2001/01/01"::Text)])
3875 [ (Format.Ledger.posting ("A":|["B", "C"]))
3876 { Format.Ledger.posting_comments = [" date:2001/01/01"]
3877 , Format.Ledger.posting_dates =
3878 [ Time.zonedTimeToUTC $
3881 (Time.fromGregorian 2001 01 01)
3882 (Time.TimeOfDay 0 0 0))
3885 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3886 , Format.Ledger.posting_tags = Data.Map.fromList
3887 [ ("date", ["2001/01/01"])
3891 , " (A:B:C) = Right (A:B:C)" ~:
3892 (Data.Either.rights $
3893 [P.runParser_with_Error
3894 (Format.Ledger.Read.posting <* P.eof)
3895 Format.Ledger.Read.nil_Context "" (" (A:B:C)"::Text)])
3897 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
3898 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3900 , Format.Ledger.Posting_Type_Virtual
3903 , " [A:B:C] = Right [A:B:C]" ~:
3904 (Data.Either.rights $
3905 [P.runParser_with_Error
3906 (Format.Ledger.Read.posting <* P.eof)
3907 Format.Ledger.Read.nil_Context "" (" [A:B:C]"::Text)])
3909 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
3910 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3912 , Format.Ledger.Posting_Type_Virtual_Balanced
3916 , "transaction" ~: TestList
3917 [ "2000/01/01 some description\\n A:B:C $1\\n a:b:c" ~:
3918 (Data.Either.rights $
3919 [P.runParser_with_Error
3920 (Format.Ledger.Read.transaction <* P.eof)
3921 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c"::Text)])
3923 [ Format.Ledger.transaction
3924 { Format.Ledger.transaction_dates=
3925 ( Time.zonedTimeToUTC $
3928 (Time.fromGregorian 2000 01 01)
3929 (Time.TimeOfDay 0 0 0))
3932 , Format.Ledger.transaction_description="some description"
3933 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3934 [ (Format.Ledger.posting ("A":|["B", "C"]))
3935 { Format.Ledger.posting_amounts = Data.Map.fromList
3937 { Amount.quantity = 1
3938 , Amount.style = Amount.Style.nil
3939 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3940 , Amount.Style.unit_spaced = Just False
3945 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3947 , (Format.Ledger.posting ("a":|["b", "c"]))
3948 { Format.Ledger.posting_amounts = Data.Map.fromList
3950 { Amount.quantity = -1
3951 , Amount.style = Amount.Style.nil
3952 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3953 , Amount.Style.unit_spaced = Just False
3958 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3961 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3964 , "2000/01/01 some description\\n A:B:C $1\\n a:b:c\\n" ~:
3965 (Data.Either.rights $
3966 [P.runParser_with_Error
3967 (Format.Ledger.Read.transaction <* P.newline <* P.eof)
3968 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c\n"::Text)])
3970 [ Format.Ledger.transaction
3971 { Format.Ledger.transaction_dates=
3972 ( Time.zonedTimeToUTC $
3975 (Time.fromGregorian 2000 01 01)
3976 (Time.TimeOfDay 0 0 0))
3979 , Format.Ledger.transaction_description="some description"
3980 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3981 [ (Format.Ledger.posting ("A":|["B", "C"]))
3982 { Format.Ledger.posting_amounts = Data.Map.fromList
3984 { Amount.quantity = 1
3985 , Amount.style = Amount.Style.nil
3986 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3987 , Amount.Style.unit_spaced = Just False
3992 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3994 , (Format.Ledger.posting ("a":|["b", "c"]))
3995 { Format.Ledger.posting_amounts = Data.Map.fromList
3997 { Amount.quantity = -1
3998 , Amount.style = Amount.Style.nil
3999 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4000 , Amount.Style.unit_spaced = Just False
4005 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
4008 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
4011 , "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" ~:
4012 (Data.Either.rights $
4013 [P.runParser_with_Error
4014 (Format.Ledger.Read.transaction <* P.eof)
4015 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)])
4017 [ Format.Ledger.transaction
4018 { Format.Ledger.transaction_comments_after =
4020 , " some other;comment"
4022 , " some last comment"
4024 , Format.Ledger.transaction_dates=
4025 ( Time.zonedTimeToUTC $
4028 (Time.fromGregorian 2000 01 01)
4029 (Time.TimeOfDay 0 0 0))
4032 , Format.Ledger.transaction_description="some description"
4033 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
4034 [ (Format.Ledger.posting ("A":|["B", "C"]))
4035 { Format.Ledger.posting_amounts = Data.Map.fromList
4037 { Amount.quantity = 1
4038 , Amount.style = Amount.Style.nil
4039 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4040 , Amount.Style.unit_spaced = Just False
4045 , Format.Ledger.posting_sourcepos = P.newPos "" 5 1
4047 , (Format.Ledger.posting ("a":|["b", "c"]))
4048 { Format.Ledger.posting_amounts = Data.Map.fromList
4050 { Amount.quantity = -1
4051 , Amount.style = Amount.Style.nil
4052 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4053 , Amount.Style.unit_spaced = Just False
4058 , Format.Ledger.posting_sourcepos = P.newPos "" 6 1
4061 , Format.Ledger.transaction_tags = Data.Map.fromList
4064 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
4068 , "journal" ~: TestList
4069 [ "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
4071 P.runParserT_with_Error
4072 (Format.Ledger.Read.journal "" {-<* P.eof-})
4073 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)
4075 (\j -> j{Format.Ledger.journal_last_read_time=
4076 Format.Ledger.journal_last_read_time Format.Ledger.journal}) $
4077 Data.Either.rights [jnl])
4079 [ Format.Ledger.journal
4080 { Format.Ledger.journal_transactions =
4081 Format.Ledger.transaction_by_Date
4082 [ Format.Ledger.transaction
4083 { Format.Ledger.transaction_dates=
4084 ( Time.zonedTimeToUTC $
4087 (Time.fromGregorian 2000 01 01)
4088 (Time.TimeOfDay 0 0 0))
4091 , Format.Ledger.transaction_description="1° description"
4092 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
4093 [ (Format.Ledger.posting ("A":|["B", "C"]))
4094 { Format.Ledger.posting_amounts = Data.Map.fromList
4096 { Amount.quantity = 1
4097 , Amount.style = Amount.Style.nil
4098 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4099 , Amount.Style.unit_spaced = Just False
4104 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
4106 , (Format.Ledger.posting ("a":|["b", "c"]))
4107 { Format.Ledger.posting_amounts = Data.Map.fromList
4109 { Amount.quantity = -1
4110 , Amount.style = Amount.Style.nil
4111 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4112 , Amount.Style.unit_spaced = Just False
4117 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
4120 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
4122 , Format.Ledger.transaction
4123 { Format.Ledger.transaction_dates=
4124 ( Time.zonedTimeToUTC $
4127 (Time.fromGregorian 2000 01 02)
4128 (Time.TimeOfDay 0 0 0))
4131 , Format.Ledger.transaction_description="2° description"
4132 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
4133 [ (Format.Ledger.posting ("A":|["B", "C"]))
4134 { Format.Ledger.posting_amounts = Data.Map.fromList
4136 { Amount.quantity = 1
4137 , Amount.style = Amount.Style.nil
4138 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4139 , Amount.Style.unit_spaced = Just False
4144 , Format.Ledger.posting_sourcepos = P.newPos "" 5 1
4146 , (Format.Ledger.posting ("x":|["y", "z"]))
4147 { Format.Ledger.posting_amounts = Data.Map.fromList
4149 { Amount.quantity = -1
4150 , Amount.style = Amount.Style.nil
4151 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4152 , Amount.Style.unit_spaced = Just False
4157 , Format.Ledger.posting_sourcepos = P.newPos "" 6 1
4160 , Format.Ledger.transaction_sourcepos = P.newPos "" 4 1
4167 , "Write" ~: TestList
4168 [ "account" ~: TestList
4170 ((Format.Ledger.Write.show
4171 Format.Ledger.Write.Style
4172 { Format.Ledger.Write.style_color=False
4173 , Format.Ledger.Write.style_align=True
4175 Format.Ledger.Write.account Format.Ledger.Posting_Type_Regular $
4180 ((Format.Ledger.Write.show
4181 Format.Ledger.Write.Style
4182 { Format.Ledger.Write.style_color=False
4183 , Format.Ledger.Write.style_align=True
4185 Format.Ledger.Write.account Format.Ledger.Posting_Type_Regular $
4190 ((Format.Ledger.Write.show
4191 Format.Ledger.Write.Style
4192 { Format.Ledger.Write.style_color=False
4193 , Format.Ledger.Write.style_align=True
4195 Format.Ledger.Write.account Format.Ledger.Posting_Type_Virtual $
4200 ((Format.Ledger.Write.show
4201 Format.Ledger.Write.Style
4202 { Format.Ledger.Write.style_color=False
4203 , Format.Ledger.Write.style_align=True
4205 Format.Ledger.Write.account Format.Ledger.Posting_Type_Virtual_Balanced $
4210 , "transaction" ~: TestList
4212 ((Format.Ledger.Write.show
4213 Format.Ledger.Write.Style
4214 { Format.Ledger.Write.style_color=False
4215 , Format.Ledger.Write.style_align=True
4217 Format.Ledger.Write.transaction
4218 Format.Ledger.transaction)
4221 , "2000/01/01 some description\\n\\ta:b:c\\n\\t ; first comment\\n\\t ; second comment\\n\\t ; third comment\\n\\tA:B:C $1" ~:
4222 ((Format.Ledger.Write.show
4223 Format.Ledger.Write.Style
4224 { Format.Ledger.Write.style_color=False
4225 , Format.Ledger.Write.style_align=True
4227 Format.Ledger.Write.transaction $
4228 Format.Ledger.transaction
4229 { Format.Ledger.transaction_dates=
4230 ( Time.zonedTimeToUTC $
4233 (Time.fromGregorian 2000 01 01)
4234 (Time.TimeOfDay 0 0 0))
4237 , Format.Ledger.transaction_description="some description"
4238 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
4239 [ (Format.Ledger.posting ("A":|["B", "C"]))
4240 { Format.Ledger.posting_amounts = Data.Map.fromList
4242 { Amount.quantity = 1
4243 , Amount.style = Amount.Style.nil
4244 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4245 , Amount.Style.unit_spaced = Just False
4251 , (Format.Ledger.posting ("a":|["b", "c"]))
4252 { Format.Ledger.posting_comments = ["first comment","second comment","third comment"]
4257 "2000/01/01 some description\n\ta:b:c\n\t ; first comment\n\t ; second comment\n\t ; third comment\n\tA:B:C $1")
4258 , "2000/01/01 some description\\n\\tA:B:C $1\\n\\tAA:BB:CC $123" ~:
4259 ((Format.Ledger.Write.show
4260 Format.Ledger.Write.Style
4261 { Format.Ledger.Write.style_color=False
4262 , Format.Ledger.Write.style_align=True
4264 Format.Ledger.Write.transaction $
4265 Format.Ledger.transaction
4266 { Format.Ledger.transaction_dates=
4267 ( Time.zonedTimeToUTC $
4270 (Time.fromGregorian 2000 01 01)
4271 (Time.TimeOfDay 0 0 0))
4274 , Format.Ledger.transaction_description="some description"
4275 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
4276 [ (Format.Ledger.posting ("A":|["B", "C"]))
4277 { Format.Ledger.posting_amounts = Data.Map.fromList
4279 { Amount.quantity = 1
4280 , Amount.style = Amount.Style.nil
4281 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4282 , Amount.Style.unit_spaced = Just False
4288 , (Format.Ledger.posting ("AA":|["BB", "CC"]))
4289 { Format.Ledger.posting_amounts = Data.Map.fromList
4291 { Amount.quantity = 123
4292 , Amount.style = Amount.Style.nil
4293 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4294 , Amount.Style.unit_spaced = Just False
4303 "2000/01/01 some description\n\tA:B:C $1\n\tAA:BB:CC $123")