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
558 , "Account" ~: TestList
559 [ "foldr" ~: TestList
561 (reverse $ Account.foldr ("A":|[]) (:) []) ~?= ["A":|[]]
563 (reverse $ Account.foldr ("A":|["B"]) (:) []) ~?= ["A":|[], "A":|["B"]]
565 (reverse $ Account.foldr ("A":|["B", "C"]) (:) []) ~?= ["A":|[], "A":|["B"], "A":|["B", "C"]]
567 , "ascending" ~: TestList
569 Account.ascending ("A":|[]) ~?= Nothing
571 Account.ascending ("A":|["B"]) ~?= Just ("A":|[])
573 Account.ascending ("A":|["B", "C"]) ~?= Just ("A":|["B"])
576 , "Amount" ~: TestList
581 { Amount.quantity = Decimal 0 1
582 , Amount.style = Amount.Style.nil
583 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
588 { Amount.quantity = Decimal 0 1
589 , Amount.style = Amount.Style.nil
590 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
596 { Amount.quantity = Decimal 0 2
597 , Amount.style = Amount.Style.nil
598 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
603 , "from_List" ~: TestList
604 [ "from_List [$1, 1$] = $2" ~:
607 { Amount.quantity = Decimal 0 1
608 , Amount.style = Amount.Style.nil
609 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
614 { Amount.quantity = Decimal 0 1
615 , Amount.style = Amount.Style.nil
616 { Amount.Style.unit_side = Just $ Amount.Style.Side_Right
624 { Amount.quantity = Decimal 0 2
625 , Amount.style = Amount.Style.nil
626 { Amount.Style.unit_side = Just $ Amount.Style.Side_Left
633 [ "amount" ~: TestList
635 (Data.Either.rights $
637 (Amount.Read.amount <* P.eof)
641 , "\"0\" = Right 0" ~:
642 (Data.Either.rights $
644 (Amount.Read.amount <* P.eof)
648 { Amount.quantity = Decimal 0 0
650 , "\"00\" = Right 0" ~:
651 (Data.Either.rights $
653 (Amount.Read.amount <* P.eof)
657 { Amount.quantity = Decimal 0 0
659 , "\"0.\" = Right 0." ~:
660 (Data.Either.rights $
662 (Amount.Read.amount <* P.eof)
666 { Amount.quantity = Decimal 0 0
669 { Amount.Style.fractioning = Just '.'
672 , "\".0\" = Right 0.0" ~:
673 (Data.Either.rights $
675 (Amount.Read.amount <* P.eof)
679 { Amount.quantity = Decimal 0 0
682 { Amount.Style.fractioning = Just '.'
683 , Amount.Style.precision = 1
686 , "\"0,\" = Right 0," ~:
687 (Data.Either.rights $
689 (Amount.Read.amount <* P.eof)
693 { Amount.quantity = Decimal 0 0
696 { Amount.Style.fractioning = Just ','
699 , "\",0\" = Right 0,0" ~:
700 (Data.Either.rights $
702 (Amount.Read.amount <* P.eof)
706 { Amount.quantity = Decimal 0 0
709 { Amount.Style.fractioning = Just ','
710 , Amount.Style.precision = 1
714 (Data.Either.rights $
716 (Amount.Read.amount <* P.eof)
721 (Data.Either.rights $
723 (Amount.Read.amount <* P.eof)
727 , "\"0.0\" = Right 0.0" ~:
728 (Data.Either.rights $
730 (Amount.Read.amount <* P.eof)
731 () "" ("0.0"::Text)])
734 { Amount.quantity = Decimal 0 0
737 { Amount.Style.fractioning = Just '.'
738 , Amount.Style.precision = 1
741 , "\"00.00\" = Right 0.00" ~:
742 (Data.Either.rights $
744 (Amount.Read.amount <* P.eof)
745 () "" ("00.00"::Text)])
748 { Amount.quantity = Decimal 0 0
751 { Amount.Style.fractioning = Just '.'
752 , Amount.Style.precision = 2
755 , "\"0,0\" = Right 0,0" ~:
756 (Data.Either.rights $
758 (Amount.Read.amount <* P.eof)
759 () "" ("0,0"::Text)])
762 { Amount.quantity = Decimal 0 0
765 { Amount.Style.fractioning = Just ','
766 , Amount.Style.precision = 1
769 , "\"00,00\" = Right 0,00" ~:
770 (Data.Either.rights $
772 (Amount.Read.amount <* P.eof)
773 () "" ("00,00"::Text)])
776 { Amount.quantity = Decimal 0 0
779 { Amount.Style.fractioning = Just ','
780 , Amount.Style.precision = 2
783 , "\"0_0\" = Right 0" ~:
784 (Data.Either.rights $
786 (Amount.Read.amount <* P.eof)
787 () "" ("0_0"::Text)])
790 { Amount.quantity = Decimal 0 0
793 { Amount.Style.fractioning = Nothing
794 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
795 , Amount.Style.precision = 0
798 , "\"00_00\" = Right 0" ~:
799 (Data.Either.rights $
801 (Amount.Read.amount <* P.eof)
802 () "" ("00_00"::Text)])
805 { Amount.quantity = Decimal 0 0
808 { Amount.Style.fractioning = Nothing
809 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
810 , Amount.Style.precision = 0
813 , "\"0,000.00\" = Right 0,000.00" ~:
814 (Data.Either.rights $
816 (Amount.Read.amount <* P.eof)
817 () "" ("0,000.00"::Text)])
820 { Amount.quantity = Decimal 0 0
823 { Amount.Style.fractioning = Just '.'
824 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
825 , Amount.Style.precision = 2
828 , "\"0.000,00\" = Right 0.000,00" ~:
829 (Data.Either.rights $
832 () "" ("0.000,00"::Text)])
835 { Amount.quantity = Decimal 0 0
838 { Amount.Style.fractioning = Just ','
839 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
840 , Amount.Style.precision = 2
843 , "\"1,000.00\" = Right 1,000.00" ~:
844 (Data.Either.rights $
846 (Amount.Read.amount <* P.eof)
847 () "" ("1,000.00"::Text)])
850 { Amount.quantity = Decimal 0 1000
853 { Amount.Style.fractioning = Just '.'
854 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
855 , Amount.Style.precision = 2
858 , "\"1.000,00\" = Right 1.000,00" ~:
859 (Data.Either.rights $
862 () "" ("1.000,00"::Text)])
865 { Amount.quantity = Decimal 0 1000
868 { Amount.Style.fractioning = Just ','
869 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
870 , Amount.Style.precision = 2
873 , "\"1,000.00.\" = Left" ~:
874 (Data.Either.rights $
877 () "" ("1,000.00."::Text)])
880 , "\"1.000,00,\" = Left" ~:
881 (Data.Either.rights $
884 () "" ("1.000,00,"::Text)])
887 , "\"1,000.00_\" = Left" ~:
888 (Data.Either.rights $
891 () "" ("1,000.00_"::Text)])
894 , "\"12\" = Right 12" ~:
895 (Data.Either.rights $
897 (Amount.Read.amount <* P.eof)
898 () "" ("123"::Text)])
901 { Amount.quantity = Decimal 0 123
903 , "\"1.2\" = Right 1.2" ~:
904 (Data.Either.rights $
906 (Amount.Read.amount <* P.eof)
907 () "" ("1.2"::Text)])
910 { Amount.quantity = Decimal 1 12
913 { Amount.Style.fractioning = Just '.'
914 , Amount.Style.precision = 1
917 , "\"1,2\" = Right 1,2" ~:
918 (Data.Either.rights $
920 (Amount.Read.amount <* P.eof)
921 () "" ("1,2"::Text)])
924 { Amount.quantity = Decimal 1 12
927 { Amount.Style.fractioning = Just ','
928 , Amount.Style.precision = 1
931 , "\"12.23\" = Right 12.23" ~:
932 (Data.Either.rights $
934 (Amount.Read.amount <* P.eof)
935 () "" ("12.34"::Text)])
938 { Amount.quantity = Decimal 2 1234
941 { Amount.Style.fractioning = Just '.'
942 , Amount.Style.precision = 2
945 , "\"12,23\" = Right 12,23" ~:
946 (Data.Either.rights $
948 (Amount.Read.amount <* P.eof)
949 () "" ("12,34"::Text)])
952 { Amount.quantity = Decimal 2 1234
955 { Amount.Style.fractioning = Just ','
956 , Amount.Style.precision = 2
959 , "\"1_2\" = Right 1_2" ~:
960 (Data.Either.rights $
962 (Amount.Read.amount <* P.eof)
963 () "" ("1_2"::Text)])
966 { Amount.quantity = Decimal 0 12
969 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [1]
970 , Amount.Style.precision = 0
973 , "\"1_23\" = Right 1_23" ~:
974 (Data.Either.rights $
976 (Amount.Read.amount <* P.eof)
977 () "" ("1_23"::Text)])
980 { Amount.quantity = Decimal 0 123
983 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [2]
984 , Amount.Style.precision = 0
987 , "\"1_23_456\" = Right 1_23_456" ~:
988 (Data.Either.rights $
990 (Amount.Read.amount <* P.eof)
991 () "" ("1_23_456"::Text)])
994 { Amount.quantity = Decimal 0 123456
997 { Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
998 , Amount.Style.precision = 0
1001 , "\"1_23_456.7890_12345_678901\" = Right 1_23_456.7890_12345_678901" ~:
1002 (Data.Either.rights $
1004 (Amount.Read.amount <* P.eof)
1005 () "" ("1_23_456.7890_12345_678901"::Text)])
1008 { Amount.quantity = Decimal 15 123456789012345678901
1011 { Amount.Style.fractioning = Just '.'
1012 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [3, 2]
1013 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [4, 5, 6]
1014 , Amount.Style.precision = 15
1017 , "\"123456_78901_2345.678_90_1\" = Right 123456_78901_2345.678_90_1" ~:
1018 (Data.Either.rights $
1020 (Amount.Read.amount <* P.eof)
1021 () "" ("123456_78901_2345.678_90_1"::Text)])
1024 { Amount.quantity = Decimal 6 123456789012345678901
1027 { Amount.Style.fractioning = Just '.'
1028 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '_' [4, 5, 6]
1029 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping '_' [3, 2]
1030 , Amount.Style.precision = 6
1033 , "\"$1\" = Right $1" ~:
1034 (Data.Either.rights $
1036 (Amount.Read.amount <* P.eof)
1037 () "" ("$1"::Text)])
1040 { Amount.quantity = Decimal 0 1
1043 { Amount.Style.fractioning = Nothing
1044 , Amount.Style.grouping_integral = Nothing
1045 , Amount.Style.grouping_fractional = Nothing
1046 , Amount.Style.precision = 0
1047 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1048 , Amount.Style.unit_spaced = Just False
1052 , "\"1$\" = Right 1$" ~:
1053 (Data.Either.rights $
1055 (Amount.Read.amount <* P.eof)
1056 () "" ("1$"::Text)])
1059 { Amount.quantity = Decimal 0 1
1062 { Amount.Style.fractioning = Nothing
1063 , Amount.Style.grouping_integral = Nothing
1064 , Amount.Style.grouping_fractional = Nothing
1065 , Amount.Style.precision = 0
1066 , Amount.Style.unit_side = Just Amount.Style.Side_Right
1067 , Amount.Style.unit_spaced = Just False
1071 , "\"$ 1\" = Right $ 1" ~:
1072 (Data.Either.rights $
1074 (Amount.Read.amount <* P.eof)
1075 () "" ("$ 1"::Text)])
1078 { Amount.quantity = Decimal 0 1
1081 { Amount.Style.fractioning = Nothing
1082 , Amount.Style.grouping_integral = Nothing
1083 , Amount.Style.grouping_fractional = Nothing
1084 , Amount.Style.precision = 0
1085 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1086 , Amount.Style.unit_spaced = Just True
1090 , "\"1 $\" = Right 1 $" ~:
1091 (Data.Either.rights $
1093 (Amount.Read.amount <* P.eof)
1094 () "" ("1 $"::Text)])
1097 { Amount.quantity = Decimal 0 1
1100 { Amount.Style.fractioning = Nothing
1101 , Amount.Style.grouping_integral = Nothing
1102 , Amount.Style.grouping_fractional = Nothing
1103 , Amount.Style.precision = 0
1104 , Amount.Style.unit_side = Just Amount.Style.Side_Right
1105 , Amount.Style.unit_spaced = Just True
1109 , "\"-$1\" = Right $-1" ~:
1110 (Data.Either.rights $
1112 (Amount.Read.amount <* P.eof)
1113 () "" ("-$1"::Text)])
1116 { Amount.quantity = Decimal 0 (-1)
1119 { Amount.Style.fractioning = Nothing
1120 , Amount.Style.grouping_integral = Nothing
1121 , Amount.Style.grouping_fractional = Nothing
1122 , Amount.Style.precision = 0
1123 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1124 , Amount.Style.unit_spaced = Just False
1128 , "\"\\\"4 2\\\"1\" = Right \\\"4 2\\\"1" ~:
1129 (Data.Either.rights $
1131 (Amount.Read.amount <* P.eof)
1132 () "" ("\"4 2\"1"::Text)])
1135 { Amount.quantity = Decimal 0 1
1138 { Amount.Style.fractioning = Nothing
1139 , Amount.Style.grouping_integral = Nothing
1140 , Amount.Style.grouping_fractional = Nothing
1141 , Amount.Style.precision = 0
1142 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1143 , Amount.Style.unit_spaced = Just False
1145 , Amount.unit = "4 2"
1147 , "\"1\\\"4 2\\\"\" = Right 1\\\"4 2\\\"" ~:
1148 (Data.Either.rights $
1150 (Amount.Read.amount <* P.eof)
1151 () "" ("1\"4 2\""::Text)])
1154 { Amount.quantity = Decimal 0 1
1157 { Amount.Style.fractioning = Nothing
1158 , Amount.Style.grouping_integral = Nothing
1159 , Amount.Style.grouping_fractional = Nothing
1160 , Amount.Style.precision = 0
1161 , Amount.Style.unit_side = Just Amount.Style.Side_Right
1162 , Amount.Style.unit_spaced = Just False
1164 , Amount.unit = "4 2"
1166 , "\"$1.000,00\" = Right $1.000,00" ~:
1167 (Data.Either.rights $
1169 (Amount.Read.amount <* P.eof)
1170 () "" ("$1.000,00"::Text)])
1173 { Amount.quantity = Decimal 0 1000
1176 { Amount.Style.fractioning = Just ','
1177 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
1178 , Amount.Style.grouping_fractional = Nothing
1179 , Amount.Style.precision = 2
1180 , Amount.Style.unit_side = Just Amount.Style.Side_Left
1181 , Amount.Style.unit_spaced = Just False
1185 , "\"1.000,00$\" = Right 1.000,00$" ~:
1186 (Data.Either.rights $
1188 (Amount.Read.amount <* P.eof)
1189 () "" ("1.000,00$"::Text)])
1192 { Amount.quantity = Decimal 0 1000
1195 { Amount.Style.fractioning = Just ','
1196 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping '.' [3]
1197 , Amount.Style.grouping_fractional = Nothing
1198 , Amount.Style.precision = 2
1199 , Amount.Style.unit_side = Just Amount.Style.Side_Right
1200 , Amount.Style.unit_spaced = Just False
1206 , "Write" ~: TestList
1207 [ "amount" ~: TestList
1209 ((Format.Ledger.Write.show
1210 Format.Ledger.Write.Style
1211 { Format.Ledger.Write.style_color=False
1212 , Format.Ledger.Write.style_align=True
1219 ((Format.Ledger.Write.show
1220 Format.Ledger.Write.Style
1221 { Format.Ledger.Write.style_color=False
1222 , Format.Ledger.Write.style_align=True
1226 { Amount.style = Amount.Style.nil
1227 { Amount.Style.precision = 2 }
1232 ((Format.Ledger.Write.show
1233 Format.Ledger.Write.Style
1234 { Format.Ledger.Write.style_color=False
1235 , Format.Ledger.Write.style_align=True
1239 { Amount.quantity = Decimal 0 123
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)
1255 , "12.3 @ prec=0" ~:
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 1 123
1264 , Amount.style = Amount.Style.nil
1265 { Amount.Style.fractioning = Just '.'
1270 , "12.5 @ prec=0" ~:
1271 ((Format.Ledger.Write.show
1272 Format.Ledger.Write.Style
1273 { Format.Ledger.Write.style_color=False
1274 , Format.Ledger.Write.style_align=True
1278 { Amount.quantity = Decimal 1 125
1279 , Amount.style = Amount.Style.nil
1280 { Amount.Style.fractioning = Just '.'
1285 , "12.3 @ prec=1" ~:
1286 ((Format.Ledger.Write.show
1287 Format.Ledger.Write.Style
1288 { Format.Ledger.Write.style_color=False
1289 , Format.Ledger.Write.style_align=True
1293 { Amount.quantity = Decimal 1 123
1294 , Amount.style = Amount.Style.nil
1295 { Amount.Style.fractioning = Just '.'
1296 , Amount.Style.precision = 1
1301 , "1,234.56 @ prec=2" ~:
1302 ((Format.Ledger.Write.show
1303 Format.Ledger.Write.Style
1304 { Format.Ledger.Write.style_color=False
1305 , Format.Ledger.Write.style_align=True
1309 { Amount.quantity = Decimal 2 123456
1310 , Amount.style = Amount.Style.nil
1311 { Amount.Style.fractioning = Just '.'
1312 , Amount.Style.precision = 2
1313 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
1318 , "123,456,789,01,2.3456789 @ prec=7" ~:
1319 ((Format.Ledger.Write.show
1320 Format.Ledger.Write.Style
1321 { Format.Ledger.Write.style_color=False
1322 , Format.Ledger.Write.style_align=True
1326 { Amount.quantity = Decimal 7 1234567890123456789
1327 , Amount.style = Amount.Style.nil
1328 { Amount.Style.fractioning = Just '.'
1329 , Amount.Style.precision = 7
1330 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1334 "123,456,789,01,2.3456789")
1335 , "1234567.8,90,123,456,789 @ prec=12" ~:
1336 ((Format.Ledger.Write.show
1337 Format.Ledger.Write.Style
1338 { Format.Ledger.Write.style_color=False
1339 , Format.Ledger.Write.style_align=True
1343 { Amount.quantity = Decimal 12 1234567890123456789
1344 , Amount.style = Amount.Style.nil
1345 { Amount.Style.fractioning = Just '.'
1346 , Amount.Style.precision = 12
1347 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1351 "1234567.8,90,123,456,789")
1352 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
1353 ((Format.Ledger.Write.show
1354 Format.Ledger.Write.Style
1355 { Format.Ledger.Write.style_color=False
1356 , Format.Ledger.Write.style_align=True
1360 { Amount.quantity = Decimal 7 1234567890123456789
1361 , Amount.style = Amount.Style.nil
1362 { Amount.Style.fractioning = Just '.'
1363 , Amount.Style.precision = 7
1364 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1368 "1,2,3,4,5,6,7,89,012.3456789")
1369 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
1370 ((Format.Ledger.Write.show
1371 Format.Ledger.Write.Style
1372 { Format.Ledger.Write.style_color=False
1373 , Format.Ledger.Write.style_align=True
1377 { Amount.quantity = Decimal 12 1234567890123456789
1378 , Amount.style = Amount.Style.nil
1379 { Amount.Style.fractioning = Just '.'
1380 , Amount.Style.precision = 12
1381 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1385 "1234567.890,12,3,4,5,6,7,8,9")
1387 , "amount_length" ~: TestList
1389 ((Amount.Write.amount_length
1394 ((Amount.Write.amount_length
1396 { Amount.style = Amount.Style.nil
1397 { Amount.Style.precision = 2 }
1402 ((Amount.Write.amount_length
1404 { Amount.quantity = Decimal 0 123
1409 ((Amount.Write.amount_length
1411 { Amount.quantity = Decimal 0 (- 123)
1415 , "12.3 @ prec=0" ~:
1416 ((Amount.Write.amount_length
1418 { Amount.quantity = Decimal 1 123
1419 , Amount.style = Amount.Style.nil
1420 { Amount.Style.fractioning = Just '.'
1425 , "12.5 @ prec=0" ~:
1426 ((Amount.Write.amount_length
1428 { Amount.quantity = Decimal 1 125
1429 , Amount.style = Amount.Style.nil
1430 { Amount.Style.fractioning = Just '.'
1435 , "12.3 @ prec=1" ~:
1436 ((Amount.Write.amount_length
1438 { Amount.quantity = Decimal 1 123
1439 , Amount.style = Amount.Style.nil
1440 { Amount.Style.fractioning = Just '.'
1441 , Amount.Style.precision = 1
1446 , "1,234.56 @ prec=2" ~:
1447 ((Amount.Write.amount_length
1449 { Amount.quantity = Decimal 2 123456
1450 , Amount.style = Amount.Style.nil
1451 { Amount.Style.fractioning = Just '.'
1452 , Amount.Style.precision = 2
1453 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3]
1458 , "123,456,789,01,2.3456789 @ prec=7" ~:
1459 ((Amount.Write.amount_length
1461 { Amount.quantity = Decimal 7 1234567890123456789
1462 , Amount.style = Amount.Style.nil
1463 { Amount.Style.fractioning = Just '.'
1464 , Amount.Style.precision = 7
1465 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1470 , "1234567.8,90,123,456,789 @ prec=12" ~:
1471 ((Amount.Write.amount_length
1473 { Amount.quantity = Decimal 12 1234567890123456789
1474 , Amount.style = Amount.Style.nil
1475 { Amount.Style.fractioning = Just '.'
1476 , Amount.Style.precision = 12
1477 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [1, 2, 3]
1482 , "1,2,3,4,5,6,7,89,012.3456789 @ prec=7" ~:
1483 ((Amount.Write.amount_length
1485 { Amount.quantity = Decimal 7 1234567890123456789
1486 , Amount.style = Amount.Style.nil
1487 { Amount.Style.fractioning = Just '.'
1488 , Amount.Style.precision = 7
1489 , Amount.Style.grouping_integral = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1494 , "1234567.890,12,3,4,5,6,7,8,9 @ prec=12" ~:
1495 ((Amount.Write.amount_length
1497 { Amount.quantity = Decimal 12 1234567890123456789
1498 , Amount.style = Amount.Style.nil
1499 { Amount.Style.fractioning = Just '.'
1500 , Amount.Style.precision = 12
1501 , Amount.Style.grouping_fractional = Just $ Amount.Style.Grouping ',' [3, 2, 1]
1506 , "1000000.000,00,0,0,0,0,0,0,0 @ prec=12" ~:
1507 ((Amount.Write.amount_length
1509 { Amount.quantity = Decimal 12 1000000000000000000
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]
1519 ((Amount.Write.amount_length $
1521 { Amount.quantity = Decimal 0 999
1522 , Amount.style = Amount.Style.nil
1523 { Amount.Style.precision = 0
1528 , "1000 @ prec=0" ~:
1529 ((Amount.Write.amount_length $
1531 { Amount.quantity = Decimal 0 1000
1532 , Amount.style = Amount.Style.nil
1533 { Amount.Style.precision = 0
1538 , "10,00€ @ prec=2" ~:
1539 ((Amount.Write.amount_length $ Amount.eur 10)
1545 , "Date" ~: TestList
1546 [ "Read" ~: TestList
1547 [ "date" ~: TestList
1549 (Data.Either.rights $
1550 [P.runParser_with_Error
1551 (Date.Read.date id Nothing <* P.eof)
1552 () "" ("2000/01/01"::Text)])
1554 [ Time.zonedTimeToUTC $
1557 (Time.fromGregorian 2000 01 01)
1558 (Time.TimeOfDay 0 0 0))
1560 , "2000/01/01 some text" ~:
1561 (Data.Either.rights $
1562 [P.runParser_with_Error
1563 (Date.Read.date id Nothing)
1564 () "" ("2000/01/01 some text"::Text)])
1566 [ Time.zonedTimeToUTC $
1569 (Time.fromGregorian 2000 01 01)
1570 (Time.TimeOfDay 0 0 0))
1572 , "2000/01/01 12:34" ~:
1573 (Data.Either.rights $
1574 [P.runParser_with_Error
1575 (Date.Read.date id Nothing <* P.eof)
1576 () "" ("2000/01/01 12:34"::Text)])
1578 [ Time.zonedTimeToUTC $
1581 (Time.fromGregorian 2000 01 01)
1582 (Time.TimeOfDay 12 34 0))
1584 , "2000/01/01 12:34:56" ~:
1585 (Data.Either.rights $
1586 [P.runParser_with_Error
1587 (Date.Read.date id Nothing <* P.eof)
1588 () "" ("2000/01/01 12:34:56"::Text)])
1590 [ Time.zonedTimeToUTC $
1593 (Time.fromGregorian 2000 01 01)
1594 (Time.TimeOfDay 12 34 56))
1596 , "2000/01/01 12:34 CET" ~:
1597 (Data.Either.rights $
1598 [P.runParser_with_Error
1599 (Date.Read.date id Nothing <* P.eof)
1600 () "" ("2000/01/01 12:34 CET"::Text)])
1602 [ Time.zonedTimeToUTC $
1605 (Time.fromGregorian 2000 01 01)
1606 (Time.TimeOfDay 12 34 0))
1607 (Time.TimeZone 60 True "CET")]
1608 , "2000/01/01 12:34 +0130" ~:
1609 (Data.Either.rights $
1610 [P.runParser_with_Error
1611 (Date.Read.date id Nothing <* P.eof)
1612 () "" ("2000/01/01 12:34 +0130"::Text)])
1614 [ Time.zonedTimeToUTC $
1617 (Time.fromGregorian 2000 01 01)
1618 (Time.TimeOfDay 12 34 0))
1619 (Time.TimeZone 90 False "+0130")]
1620 , "2000/01/01 12:34:56 CET" ~:
1621 (Data.Either.rights $
1622 [P.runParser_with_Error
1623 (Date.Read.date id Nothing <* P.eof)
1624 () "" ("2000/01/01 12:34:56 CET"::Text)])
1626 [ Time.zonedTimeToUTC $
1629 (Time.fromGregorian 2000 01 01)
1630 (Time.TimeOfDay 12 34 56))
1631 (Time.TimeZone 60 True "CET")]
1633 (Data.Either.rights $
1634 [P.runParser_with_Error
1635 (Date.Read.date id Nothing <* P.eof)
1636 () "" ("2001/02/29"::Text)])
1640 (Data.Either.rights $
1641 [P.runParser_with_Error
1642 (Date.Read.date id (Just 2000) <* P.eof)
1643 () "" ("01/01"::Text)])
1645 [ Time.zonedTimeToUTC $
1648 (Time.fromGregorian 2000 01 01)
1649 (Time.TimeOfDay 0 0 0))
1653 , "Write" ~: TestList
1654 [ "date" ~: TestList
1656 ((Format.Ledger.Write.show
1657 Format.Ledger.Write.Style
1658 { Format.Ledger.Write.style_color=False
1659 , Format.Ledger.Write.style_align=True
1665 , "2000/01/01 12:34:51 CET" ~:
1666 (Format.Ledger.Write.show
1667 Format.Ledger.Write.Style
1668 { Format.Ledger.Write.style_color=False
1669 , Format.Ledger.Write.style_align=True
1672 Time.zonedTimeToUTC $
1675 (Time.fromGregorian 2000 01 01)
1676 (Time.TimeOfDay 12 34 51))
1677 (Time.TimeZone 60 False "CET"))
1679 "2000/01/01 11:34:51"
1680 , "2000/01/01 12:34:51 +0100" ~:
1681 (Format.Ledger.Write.show
1682 Format.Ledger.Write.Style
1683 { Format.Ledger.Write.style_color=False
1684 , Format.Ledger.Write.style_align=True
1687 Time.zonedTimeToUTC $
1690 (Time.fromGregorian 2000 01 01)
1691 (Time.TimeOfDay 12 34 51))
1692 (Time.TimeZone 60 False ""))
1694 "2000/01/01 11:34:51"
1695 , "2000/01/01 01:02:03" ~:
1696 (Format.Ledger.Write.show
1697 Format.Ledger.Write.Style
1698 { Format.Ledger.Write.style_color=False
1699 , Format.Ledger.Write.style_align=True
1702 Time.zonedTimeToUTC $
1705 (Time.fromGregorian 2000 01 01)
1706 (Time.TimeOfDay 1 2 3))
1709 "2000/01/01 01:02:03"
1711 (Format.Ledger.Write.show
1712 Format.Ledger.Write.Style
1713 { Format.Ledger.Write.style_color=False
1714 , Format.Ledger.Write.style_align=True
1717 Time.zonedTimeToUTC $
1720 (Time.fromGregorian 0 01 01)
1721 (Time.TimeOfDay 1 2 0))
1726 (Format.Ledger.Write.show
1727 Format.Ledger.Write.Style
1728 { Format.Ledger.Write.style_color=False
1729 , Format.Ledger.Write.style_align=True
1732 Time.zonedTimeToUTC $
1735 (Time.fromGregorian 0 01 01)
1736 (Time.TimeOfDay 1 0 0))
1741 (Format.Ledger.Write.show
1742 Format.Ledger.Write.Style
1743 { Format.Ledger.Write.style_color=False
1744 , Format.Ledger.Write.style_align=True
1747 Time.zonedTimeToUTC $
1750 (Time.fromGregorian 0 01 01)
1751 (Time.TimeOfDay 0 1 0))
1756 (Format.Ledger.Write.show
1757 Format.Ledger.Write.Style
1758 { Format.Ledger.Write.style_color=False
1759 , Format.Ledger.Write.style_align=True
1762 Time.zonedTimeToUTC $
1765 (Time.fromGregorian 0 01 01)
1766 (Time.TimeOfDay 0 0 0))
1773 , "Filter" ~: TestList
1774 [ "test" ~: TestList
1775 [ "Filter_Account" ~: TestList
1778 [ Filter.Filter_Account_Section_Text
1779 (Filter.Filter_Text_Exact "A")
1781 (("A":|[]::Account))
1784 [ Filter.Filter_Account_Section_Any
1786 (("A":|[]::Account))
1789 [ Filter.Filter_Account_Section_Many
1791 (("A":|[]::Account))
1794 [ Filter.Filter_Account_Section_Many
1795 , Filter.Filter_Account_Section_Text
1796 (Filter.Filter_Text_Exact "A")
1798 (("A":|[]::Account))
1801 [ Filter.Filter_Account_Section_Text
1802 (Filter.Filter_Text_Exact "A")
1803 , Filter.Filter_Account_Section_Many
1805 (("A":|[]::Account))
1808 [ Filter.Filter_Account_Section_Text
1809 (Filter.Filter_Text_Exact "A")
1810 , Filter.Filter_Account_Section_Many
1812 (("A":|"B":[]::Account))
1815 [ Filter.Filter_Account_Section_Text
1816 (Filter.Filter_Text_Exact "A")
1817 , Filter.Filter_Account_Section_Text
1818 (Filter.Filter_Text_Exact "B")
1820 (("A":|"B":[]::Account))
1823 [ Filter.Filter_Account_Section_Text
1824 (Filter.Filter_Text_Exact "A")
1825 , Filter.Filter_Account_Section_Many
1826 , Filter.Filter_Account_Section_Text
1827 (Filter.Filter_Text_Exact "B")
1829 (("A":|"B":[]::Account))
1832 [ Filter.Filter_Account_Section_Many
1833 , Filter.Filter_Account_Section_Text
1834 (Filter.Filter_Text_Exact "B")
1835 , Filter.Filter_Account_Section_Many
1837 (("A":|"B":"C":[]::Account))
1840 [ Filter.Filter_Account_Section_Many
1841 , Filter.Filter_Account_Section_Text
1842 (Filter.Filter_Text_Exact "C")
1844 (("A":|"B":"C":[]::Account))
1846 , "Filter_Bool" ~: TestList
1849 (Filter.Any::Filter.Filter_Bool Filter.Filter_Account)
1850 (("A":|[]::Account))
1852 , "Filter_Ord" ~: TestList
1855 (Filter.Filter_Ord_Gt (0::Integer))
1856 (fromJust $ (Lib.Interval.<=..<=) 1 2)
1859 (Filter.Filter_Ord_Lt (0::Integer))
1860 (fromJust $ (Lib.Interval.<=..<=) (-2) (-1))
1861 , "not (1 < (0, 2))" ~?
1862 (not $ Filter.filter
1863 (Filter.Filter_Ord_Gt (1::Integer))
1864 (fromJust $ (Lib.Interval.<=..<=) 0 2))
1867 , "Read" ~: TestList
1868 [ "filter_account_section" ~: TestList
1870 (Data.Either.rights $
1872 (Filter.Read.filter_account <* P.eof)
1875 [ [Filter.Filter_Account_Section_Any]
1878 (Data.Either.rights $
1880 (Filter.Read.filter_account <* P.eof)
1883 [ [Filter.Filter_Account_Section_Text (Filter.Filter_Text_Exact "A")]
1886 (Data.Either.rights $
1888 (Filter.Read.filter_account <* P.eof)
1889 () "" ("AA"::Text)])
1891 [ [Filter.Filter_Account_Section_Text (Filter.Filter_Text_Exact "AA")]
1894 (Data.Either.rights $
1896 (Filter.Read.filter_account <* P.eof)
1897 () "" ("::A"::Text)])
1899 [ [ Filter.Filter_Account_Section_Many
1900 , Filter.Filter_Account_Section_Text (Filter.Filter_Text_Exact "A")
1904 (Data.Either.rights $
1906 (Filter.Read.filter_account <* P.eof)
1907 () "" (":A"::Text)])
1909 [ [ Filter.Filter_Account_Section_Many
1910 , Filter.Filter_Account_Section_Text (Filter.Filter_Text_Exact "A")
1914 (Data.Either.rights $
1916 (Filter.Read.filter_account <* P.eof)
1917 () "" ("A:"::Text)])
1919 [ [ Filter.Filter_Account_Section_Text (Filter.Filter_Text_Exact "A")
1920 , Filter.Filter_Account_Section_Many
1924 (Data.Either.rights $
1926 (Filter.Read.filter_account <* P.eof)
1927 () "" ("A::"::Text)])
1929 [ [ Filter.Filter_Account_Section_Text (Filter.Filter_Text_Exact "A")
1930 , Filter.Filter_Account_Section_Many
1934 (Data.Either.rights $
1936 (Filter.Read.filter_account <* P.eof)
1937 () "" ("A:B"::Text)])
1939 [ [ Filter.Filter_Account_Section_Text (Filter.Filter_Text_Exact "A")
1940 , Filter.Filter_Account_Section_Text (Filter.Filter_Text_Exact "B") ]
1943 (Data.Either.rights $
1945 (Filter.Read.filter_account <* P.eof)
1946 () "" ("A::B"::Text)])
1948 [ [ Filter.Filter_Account_Section_Text (Filter.Filter_Text_Exact "A")
1949 , Filter.Filter_Account_Section_Many
1950 , Filter.Filter_Account_Section_Text (Filter.Filter_Text_Exact "B")
1954 (Data.Either.rights $
1956 (Filter.Read.filter_account <* P.eof)
1957 () "" ("A:::B"::Text)])
1959 [ [ Filter.Filter_Account_Section_Text (Filter.Filter_Text_Exact "A")
1960 , Filter.Filter_Account_Section_Many
1961 , Filter.Filter_Account_Section_Text (Filter.Filter_Text_Exact "B")
1965 (Data.Either.rights $
1967 (Filter.Read.filter_account <* P.char ' ' <* P.eof)
1968 () "" ("A: "::Text)])
1970 [ [ Filter.Filter_Account_Section_Text (Filter.Filter_Text_Exact "A")
1971 , Filter.Filter_Account_Section_Many
1975 , "filter_bool" ~: TestList
1977 (Data.Either.rights $
1979 (Filter.Read.filter_bool
1980 [ P.char 'E' >> return (return True) ]
1982 () "" ("( E )"::Text)])
1984 [ Filter.And (Filter.Bool True) Filter.Any
1987 (Data.Either.rights $
1989 (Filter.Read.filter_bool
1990 [ P.char 'E' >> return (return True) ]
1992 () "" ("( ( E ) )"::Text)])
1994 [ Filter.And (Filter.And (Filter.Bool True) Filter.Any) Filter.Any
1996 , "( E ) & ( E )" ~:
1997 (Data.Either.rights $
1999 (Filter.Read.filter_bool
2000 [ P.char 'E' >> return (return True) ]
2002 () "" ("( E ) & ( E )"::Text)])
2005 (Filter.And (Filter.Bool True) Filter.Any)
2006 (Filter.And (Filter.Bool True) Filter.Any)
2008 , "( E ) + ( E )" ~:
2009 (Data.Either.rights $
2011 (Filter.Read.filter_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.filter_bool
2024 [ P.char 'E' >> return (return True) ]
2026 () "" ("( E ) - ( E )"::Text)])
2029 (Filter.And (Filter.Bool True) Filter.Any)
2030 (Filter.Not (Filter.And (Filter.Bool True) Filter.Any))
2033 (Data.Either.rights $
2035 (Filter.Read.filter_bool
2036 [ P.char 'E' >> return (return True) ]
2038 () "" ("(- E )"::Text)])
2040 [ Filter.And (Filter.Not (Filter.Bool True)) Filter.Any
2045 , "Balance" ~: TestList
2046 [ "balance" ~: TestList
2047 [ "[A+$1] = A+$1 & $+1" ~:
2049 (Format.Ledger.posting ("A":|[]))
2050 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
2055 { Balance.balance_by_account =
2056 Lib.TreeMap.from_List const $
2057 Data.List.map (id *** Data.Map.map Amount.sum) $
2058 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2059 , Balance.balance_by_unit =
2061 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2063 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2064 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2069 , "[A+$1, A-$1] = {A+$0, $+0}" ~:
2071 (flip Balance.balance)
2073 [ (Format.Ledger.posting ("A":|[]))
2074 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
2076 , (Format.Ledger.posting ("A":|[]))
2077 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ]
2082 { Balance.balance_by_account =
2083 Lib.TreeMap.from_List const $
2085 , Data.Map.fromListWith const $
2086 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance s, s))
2092 , Balance.balance_by_unit =
2094 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2096 { Balance.unit_sum_amount = Amount.Sum_Both
2099 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2104 , "[A+$1, A-€1] = {A+$1-€1, $+1 €-1}" ~:
2106 (flip Balance.balance)
2108 [ (Format.Ledger.posting ("A":|[]))
2109 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
2111 , (Format.Ledger.posting ("A":|[]))
2112 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1 ]
2117 { Balance.balance_by_account =
2118 Lib.TreeMap.from_List const $
2119 Data.List.map (id *** Data.Map.map Amount.sum) $
2120 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ -1 ]) ]
2121 , Balance.balance_by_unit =
2123 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2125 { Balance.unit_sum_amount = Amount.Sum_Positive (Amount.usd $ 1)
2126 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2130 { Balance.unit_sum_amount = Amount.Sum_Negative (Amount.eur $ -1)
2131 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2136 , "[A+$1, B-$1] = {A+$1 B-$1, $+0}" ~:
2138 (flip Balance.balance)
2140 [ (Format.Ledger.posting ("A":|[]))
2141 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
2143 , (Format.Ledger.posting ("B":|[]))
2144 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ]
2149 { Balance.balance_by_account =
2150 Lib.TreeMap.from_List const $
2151 Data.List.map (id *** Data.Map.map Amount.sum) $
2152 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2153 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
2155 , Balance.balance_by_unit =
2157 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2159 { Balance.unit_sum_amount = Amount.Sum_Both
2162 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2169 (flip Balance.balance)
2171 [ (Format.Ledger.posting ("A":|[]))
2172 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
2174 , (Format.Ledger.posting ("B":|[]))
2175 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ]
2180 { Balance.balance_by_account =
2181 Lib.TreeMap.from_List const $
2182 Data.List.map (id *** Data.Map.map Amount.sum) $
2183 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2184 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ])
2186 , Balance.balance_by_unit =
2188 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2190 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 2
2191 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2196 , "[A+$1+€2, A-$1-€2] = {A+$0+€0, $+0 €+0}" ~:
2198 (flip Balance.balance)
2200 [ (Format.Ledger.posting ("A":|[]))
2201 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2 ]
2203 , (Format.Ledger.posting ("A":|[]))
2204 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2 ]
2209 { Balance.balance_by_account =
2210 Lib.TreeMap.from_List const $
2212 , Data.Map.fromListWith const $
2213 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance s, s))
2214 [ Amount.Sum_Both (Amount.usd $ -1) (Amount.usd $ 1)
2215 , Amount.Sum_Both (Amount.eur $ -2) (Amount.eur $ 2)
2219 , Balance.balance_by_unit =
2221 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2223 { Balance.unit_sum_amount = Amount.Sum_Both (Amount.usd $ -1) (Amount.usd $ 1)
2224 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2228 { Balance.unit_sum_amount = Amount.Sum_Both (Amount.eur $ -2) (Amount.eur $ 2)
2229 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2234 , "[A+$1+€2+£3, B-$1-2€-£3] = {A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~:
2236 (flip Balance.balance)
2238 [ (Format.Ledger.posting ("A":|[]))
2239 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ]
2241 , (Format.Ledger.posting ("B":|[]))
2242 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ]
2247 { Balance.balance_by_account =
2248 Lib.TreeMap.from_List const $
2249 Data.List.map (id *** Data.Map.map Amount.sum) $
2250 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
2251 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
2253 , Balance.balance_by_unit =
2255 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2257 { Balance.unit_sum_amount = Amount.Sum_Both (Amount.usd $ -1) (Amount.usd $ 1)
2258 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2262 { Balance.unit_sum_amount = Amount.Sum_Both (Amount.eur $ -2) (Amount.eur $ 2)
2263 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2267 { Balance.unit_sum_amount = Amount.Sum_Both (Amount.gbp $ -3) (Amount.gbp $ 3)
2268 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2274 , "union" ~: TestList
2275 [ "nil nil = nil" ~:
2276 Balance.union Balance.nil Balance.nil
2278 (Balance.nil::Balance.Balance Amount)
2279 , "{A+$1, $+1} {A+$1, $+1} = {A+$2, $+2}" ~:
2282 { Balance.balance_by_account =
2283 Lib.TreeMap.from_List const $
2284 Data.List.map (id *** Data.Map.map Amount.sum) $
2285 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2286 , Balance.balance_by_unit =
2288 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2290 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2291 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2297 { Balance.balance_by_account =
2298 Lib.TreeMap.from_List const $
2299 Data.List.map (id *** Data.Map.map Amount.sum) $
2300 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2301 , Balance.balance_by_unit =
2303 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2305 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2306 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2313 { Balance.balance_by_account =
2314 Lib.TreeMap.from_List const $
2315 Data.List.map (id *** Data.Map.map Amount.sum) $
2316 [ ("A":|[], Amount.from_List [ Amount.usd $ 2 ]) ]
2317 , Balance.balance_by_unit =
2319 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2321 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 2
2322 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2327 , "{A+$1, $+1} {B+$1, $+1} = {A+$1 B+$1, $+2}" ~:
2330 { Balance.balance_by_account =
2331 Lib.TreeMap.from_List const $
2332 Data.List.map (id *** Data.Map.map Amount.sum) $
2333 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2334 , Balance.balance_by_unit =
2336 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2338 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2339 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2345 { Balance.balance_by_account =
2346 Lib.TreeMap.from_List const $
2347 Data.List.map (id *** Data.Map.map Amount.sum) $
2348 [ ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2349 , Balance.balance_by_unit =
2351 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2353 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2354 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2361 { Balance.balance_by_account =
2362 Lib.TreeMap.from_List const $
2363 Data.List.map (id *** Data.Map.map Amount.sum) $
2364 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2365 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2366 , Balance.balance_by_unit =
2368 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2370 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 2
2371 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2376 , "{A+$1, $+1} {B+€1, €+1} = {A+$1 B+€1, $+1 €+1}" ~:
2379 { Balance.balance_by_account =
2380 Lib.TreeMap.from_List const $
2381 Data.List.map (id *** Data.Map.map Amount.sum) $
2382 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ]
2383 , Balance.balance_by_unit =
2385 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2387 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2388 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2394 { Balance.balance_by_account =
2395 Lib.TreeMap.from_List const $
2396 Data.List.map (id *** Data.Map.map Amount.sum) $
2397 [ ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
2398 , Balance.balance_by_unit =
2400 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2402 { Balance.unit_sum_amount = Amount.sum $ Amount.eur $ 1
2403 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2410 { Balance.balance_by_account =
2411 Lib.TreeMap.from_List const $
2412 Data.List.map (id *** Data.Map.map Amount.sum) $
2413 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2414 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ]) ]
2415 , Balance.balance_by_unit =
2417 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2419 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2420 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2424 { Balance.unit_sum_amount = Amount.sum $ Amount.eur $ 1
2425 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2431 , "expanded" ~: TestList
2432 [ "nil_By_Account" ~:
2436 (Lib.TreeMap.empty::Balance.Expanded Amount)
2439 (Lib.TreeMap.from_List const $
2440 Data.List.map (id *** Data.Map.map Amount.sum) $
2441 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ]) ])
2443 (Lib.TreeMap.from_List const $
2444 [ ("A":|[], Balance.Account_Sum_Expanded
2445 { Balance.inclusive =
2446 Data.Map.map Amount.sum $
2447 Amount.from_List [ Amount.usd $ 1 ]
2448 , Balance.exclusive =
2449 Data.Map.map Amount.sum $
2450 Amount.from_List [ Amount.usd $ 1 ]
2453 , "A/A+$1 = A+$1 A/A+$1" ~:
2455 (Lib.TreeMap.from_List const $
2456 Data.List.map (id *** Data.Map.map Amount.sum) $
2457 [ ("A":|["A"], Amount.from_List [ Amount.usd $ 1 ]) ])
2459 (Lib.TreeMap.from_List const
2460 [ ("A":|[], Balance.Account_Sum_Expanded
2461 { Balance.inclusive =
2462 Data.Map.map Amount.sum $
2463 Amount.from_List [ Amount.usd $ 1 ]
2464 , Balance.exclusive =
2465 Data.Map.map Amount.sum $
2468 , ("A":|["A"], Balance.Account_Sum_Expanded
2469 { Balance.inclusive =
2470 Data.Map.map Amount.sum $
2471 Amount.from_List [ Amount.usd $ 1 ]
2472 , Balance.exclusive =
2473 Data.Map.map Amount.sum $
2474 Amount.from_List [ Amount.usd $ 1 ]
2477 , "A/B+$1 = A+$1 A/B+$1" ~:
2479 (Lib.TreeMap.from_List const $
2480 Data.List.map (id *** Data.Map.map Amount.sum) $
2481 [ ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ]) ])
2483 (Lib.TreeMap.from_List const
2484 [ ("A":|[], Balance.Account_Sum_Expanded
2485 { Balance.inclusive =
2486 Data.Map.map Amount.sum $
2487 Amount.from_List [ Amount.usd $ 1 ]
2488 , Balance.exclusive =
2489 Data.Map.map Amount.sum $
2492 , ("A":|["B"], Balance.Account_Sum_Expanded
2493 { Balance.inclusive =
2494 Data.Map.map Amount.sum $
2495 Amount.from_List [ Amount.usd $ 1 ]
2496 , Balance.exclusive =
2497 Data.Map.map Amount.sum $
2498 Amount.from_List [ Amount.usd $ 1 ]
2501 , "A/B/C+$1 = A+$1 A/B+$1 A/B/C+$1" ~:
2503 (Lib.TreeMap.from_List const $
2504 Data.List.map (id *** Data.Map.map Amount.sum) $
2505 [ ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ]) ])
2507 (Lib.TreeMap.from_List const $
2508 [ ("A":|[], Balance.Account_Sum_Expanded
2509 { Balance.inclusive =
2510 Data.Map.map Amount.sum $
2511 Amount.from_List [ Amount.usd $ 1 ]
2512 , Balance.exclusive =
2513 Data.Map.map Amount.sum $
2516 , ("A":|["B"], Balance.Account_Sum_Expanded
2517 { Balance.inclusive =
2518 Data.Map.map Amount.sum $
2519 Amount.from_List [ Amount.usd $ 1 ]
2520 , Balance.exclusive =
2521 Data.Map.map Amount.sum $
2524 , ("A":|["B", "C"], Balance.Account_Sum_Expanded
2525 { Balance.inclusive =
2526 Data.Map.map Amount.sum $
2527 Amount.from_List [ Amount.usd $ 1 ]
2528 , Balance.exclusive =
2529 Data.Map.map Amount.sum $
2530 Amount.from_List [ Amount.usd $ 1 ]
2533 , "A+$1 A/B+$1 = A+$2 A/B+$1" ~:
2535 (Lib.TreeMap.from_List const $
2536 Data.List.map (id *** Data.Map.map Amount.sum) $
2537 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2538 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
2541 (Lib.TreeMap.from_List const
2542 [ ("A":|[], Balance.Account_Sum_Expanded
2543 { Balance.inclusive =
2544 Data.Map.map Amount.sum $
2545 Amount.from_List [ Amount.usd $ 2 ]
2546 , Balance.exclusive =
2547 Data.Map.map Amount.sum $
2548 Amount.from_List [ Amount.usd $ 1 ]
2550 , ("A":|["B"], Balance.Account_Sum_Expanded
2551 { Balance.inclusive =
2552 Data.Map.map Amount.sum $
2553 Amount.from_List [ Amount.usd $ 1 ]
2554 , Balance.exclusive =
2555 Data.Map.map Amount.sum $
2556 Amount.from_List [ Amount.usd $ 1 ]
2559 , "A+$1 A/B+$1 A/B/C+$1 = A+$3 A/B+$2 A/B/C+$1" ~:
2561 (Lib.TreeMap.from_List const $
2562 Data.List.map (id *** Data.Map.map Amount.sum) $
2563 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2564 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
2565 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
2568 (Lib.TreeMap.from_List const
2569 [ ("A":|[], Balance.Account_Sum_Expanded
2570 { Balance.inclusive =
2571 Data.Map.map Amount.sum $
2572 Amount.from_List [ Amount.usd $ 3 ]
2573 , Balance.exclusive =
2574 Data.Map.map Amount.sum $
2575 Amount.from_List [ Amount.usd $ 1 ]
2577 , ("A":|["B"], Balance.Account_Sum_Expanded
2578 { Balance.inclusive =
2579 Data.Map.map Amount.sum $
2580 Amount.from_List [ Amount.usd $ 2 ]
2581 , Balance.exclusive =
2582 Data.Map.map Amount.sum $
2583 Amount.from_List [ Amount.usd $ 1 ]
2585 , ("A":|["B", "C"], Balance.Account_Sum_Expanded
2586 { Balance.inclusive =
2587 Data.Map.map Amount.sum $
2588 Amount.from_List [ Amount.usd $ 1 ]
2589 , Balance.exclusive =
2590 Data.Map.map Amount.sum $
2591 Amount.from_List [ Amount.usd $ 1 ]
2594 , "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" ~:
2596 (Lib.TreeMap.from_List const $
2597 Data.List.map (id *** Data.Map.map Amount.sum) $
2598 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2599 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
2600 , ("A":|["B", "C"], Amount.from_List [ Amount.usd $ 1 ])
2601 , ("A":|["B", "C", "D"], Amount.from_List [ Amount.usd $ 1 ])
2604 (Lib.TreeMap.from_List const
2605 [ ("A":|[], Balance.Account_Sum_Expanded
2606 { Balance.inclusive =
2607 Data.Map.map Amount.sum $
2608 Amount.from_List [ Amount.usd $ 4 ]
2609 , Balance.exclusive =
2610 Data.Map.map Amount.sum $
2611 Amount.from_List [ Amount.usd $ 1 ]
2613 , ("A":|["B"], Balance.Account_Sum_Expanded
2614 { Balance.inclusive =
2615 Data.Map.map Amount.sum $
2616 Amount.from_List [ Amount.usd $ 3 ]
2617 , Balance.exclusive =
2618 Data.Map.map Amount.sum $
2619 Amount.from_List [ Amount.usd $ 1 ]
2621 , ("A":|["B", "C"], Balance.Account_Sum_Expanded
2622 { Balance.inclusive =
2623 Data.Map.map Amount.sum $
2624 Amount.from_List [ Amount.usd $ 2 ]
2625 , Balance.exclusive =
2626 Data.Map.map Amount.sum $
2627 Amount.from_List [ Amount.usd $ 1 ]
2629 , ("A":|["B", "C", "D"], Balance.Account_Sum_Expanded
2630 { Balance.inclusive =
2631 Data.Map.map Amount.sum $
2632 Amount.from_List [ Amount.usd $ 1 ]
2633 , Balance.exclusive =
2634 Data.Map.map Amount.sum $
2635 Amount.from_List [ Amount.usd $ 1 ]
2638 , "A+$1 A/B+$1 A/BB+$1 AA/B+$1 = A+$3 A/B+$1 A/BB+$1 AA+$1 AA/B+$1" ~:
2640 (Lib.TreeMap.from_List const $
2641 Data.List.map (id *** Data.Map.map Amount.sum) $
2642 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2643 , ("A":|["B"], Amount.from_List [ Amount.usd $ 1 ])
2644 , ("A":|["BB"], Amount.from_List [ Amount.usd $ 1 ])
2645 , ("AA":|["B"], Amount.from_List [ Amount.usd $ 1 ])
2648 (Lib.TreeMap.from_List const
2649 [ ("A":|[], Balance.Account_Sum_Expanded
2650 { Balance.inclusive =
2651 Data.Map.map Amount.sum $
2652 Amount.from_List [ Amount.usd $ 3 ]
2653 , Balance.exclusive =
2654 Data.Map.map Amount.sum $
2655 Amount.from_List [ Amount.usd $ 1 ]
2657 , ("A":|["B"], Balance.Account_Sum_Expanded
2658 { Balance.inclusive =
2659 Data.Map.map Amount.sum $
2660 Amount.from_List [ Amount.usd $ 1 ]
2661 , Balance.exclusive =
2662 Data.Map.map Amount.sum $
2663 Amount.from_List [ Amount.usd $ 1 ]
2665 , ("A":|["BB"], Balance.Account_Sum_Expanded
2666 { Balance.inclusive =
2667 Data.Map.map Amount.sum $
2668 Amount.from_List [ Amount.usd $ 1 ]
2669 , Balance.exclusive =
2670 Data.Map.map Amount.sum $
2671 Amount.from_List [ Amount.usd $ 1 ]
2673 , ("AA":|[], Balance.Account_Sum_Expanded
2674 { Balance.inclusive =
2675 Data.Map.map Amount.sum $
2676 Amount.from_List [ Amount.usd $ 1 ]
2677 , Balance.exclusive =
2678 Data.Map.map Amount.sum $
2681 , ("AA":|["B"], Balance.Account_Sum_Expanded
2682 { Balance.inclusive =
2683 Data.Map.map Amount.sum $
2684 Amount.from_List [ Amount.usd $ 1 ]
2685 , Balance.exclusive =
2686 Data.Map.map Amount.sum $
2687 Amount.from_List [ Amount.usd $ 1 ]
2691 , "deviation" ~: TestList
2693 (Balance.deviation $
2695 { Balance.balance_by_account =
2696 Lib.TreeMap.from_List const $
2697 Data.List.map (id *** Data.Map.map Amount.sum) $
2698 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2699 , ("B":|[], Amount.from_List [])
2701 , Balance.balance_by_unit =
2703 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2705 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2706 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2712 (Balance.Deviation $
2714 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2716 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2717 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2721 , "{A+$1 B+$1, $2}" ~:
2722 (Balance.deviation $
2724 { Balance.balance_by_account =
2725 Lib.TreeMap.from_List const $
2726 Data.List.map (id *** Data.Map.map Amount.sum) $
2727 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2728 , ("B":|[], Amount.from_List [ Amount.usd $ 1 ])
2730 , Balance.balance_by_unit =
2732 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2734 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 2
2735 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2743 (Balance.Deviation $
2745 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2747 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 2
2748 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2754 , "is_equilibrium_inferrable" ~: TestList
2755 [ "nil" ~: TestCase $
2757 Balance.is_equilibrium_inferrable $
2759 (Balance.nil::Balance.Balance Amount.Amount)
2760 , "{A+$0, $+0}" ~: TestCase $
2762 Balance.is_equilibrium_inferrable $
2765 { Balance.balance_by_account =
2766 Lib.TreeMap.from_List const $
2767 Data.List.map (id *** Data.Map.map Amount.sum) $
2768 [ ("A":|[], Amount.from_List [ Amount.usd $ 0 ])
2770 , Balance.balance_by_unit =
2772 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2774 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 0
2775 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2780 , "{A+$1, $+1}" ~: TestCase $
2782 Balance.is_equilibrium_inferrable $
2785 { Balance.balance_by_account =
2786 Lib.TreeMap.from_List const $
2787 Data.List.map (id *** Data.Map.map Amount.sum) $
2788 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2790 , Balance.balance_by_unit =
2792 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2794 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2795 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2800 , "{A+$0+€0, $0 €+0}" ~: TestCase $
2802 Balance.is_equilibrium_inferrable $
2805 { Balance.balance_by_account =
2806 Lib.TreeMap.from_List const $
2807 Data.List.map (id *** Data.Map.map Amount.sum) $
2808 [ ("A":|[], Amount.from_List [ Amount.usd $ 0, Amount.eur $ 0 ])
2810 , Balance.balance_by_unit =
2812 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2814 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 0
2815 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2819 { Balance.unit_sum_amount = Amount.sum $ Amount.eur $ 0
2820 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2825 , "{A+$1, B-$1, $+0}" ~: TestCase $
2827 Balance.is_equilibrium_inferrable $
2830 { Balance.balance_by_account =
2831 Lib.TreeMap.from_List const $
2832 Data.List.map (id *** Data.Map.map Amount.sum) $
2833 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2834 , ("B":|[], Amount.from_List [ Amount.usd $ -1 ])
2836 , Balance.balance_by_unit =
2838 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2840 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 0
2841 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2846 , "{A+$1 B, $+1}" ~: TestCase $
2848 Balance.is_equilibrium_inferrable $
2851 { Balance.balance_by_account =
2852 Lib.TreeMap.from_List const $
2853 Data.List.map (id *** Data.Map.map Amount.sum) $
2854 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2855 , ("B":|[], Amount.from_List [])
2857 , Balance.balance_by_unit =
2859 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2861 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2862 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2867 , "{A+$1 B+€1, $+1 €+1}" ~: TestCase $
2869 Balance.is_equilibrium_inferrable $
2872 { Balance.balance_by_account =
2873 Lib.TreeMap.from_List const $
2874 Data.List.map (id *** Data.Map.map Amount.sum) $
2875 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2876 , ("B":|[], Amount.from_List [ Amount.eur $ 1 ])
2878 , Balance.balance_by_unit =
2880 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2882 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 1
2883 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2887 { Balance.unit_sum_amount = Amount.sum $ Amount.eur $ 1
2888 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2893 , "{A+$1 B-$1+€1, $+0 €+1}" ~: TestCase $
2895 Balance.is_equilibrium_inferrable $
2898 { Balance.balance_by_account =
2899 Lib.TreeMap.from_List const $
2900 Data.List.map (id *** Data.Map.map Amount.sum) $
2901 [ ("A":|[], Amount.from_List [ Amount.usd $ 1 ])
2902 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ 1 ])
2904 , Balance.balance_by_unit =
2906 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2908 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 0
2909 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2913 { Balance.unit_sum_amount = Amount.sum $ Amount.eur $ 1
2914 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2919 , "{A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~: TestCase $
2921 Balance.is_equilibrium_inferrable $
2924 { Balance.balance_by_account =
2925 Lib.TreeMap.from_List const $
2926 Data.List.map (id *** Data.Map.map Amount.sum) $
2927 [ ("A":|[], Amount.from_List [ Amount.usd $ 1, Amount.eur $ 2, Amount.gbp $ 3 ])
2928 , ("B":|[], Amount.from_List [ Amount.usd $ -1, Amount.eur $ -2, Amount.gbp $ -3 ])
2930 , Balance.balance_by_unit =
2932 Data.List.map (\s -> (Amount.unit $ Amount.sum_balance $ Balance.unit_sum_amount s, s))
2934 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 0
2935 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2939 { Balance.unit_sum_amount = Amount.sum $ Amount.eur $ 0
2940 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2944 { Balance.unit_sum_amount = Amount.sum $ Amount.gbp $ 0
2945 , Balance.unit_sum_accounts = Data.Map.fromList $ Data.List.map (,())
2951 , "infer_equilibrium" ~: TestList
2953 (snd $ Balance.infer_equilibrium $
2954 Format.Ledger.posting_by_Account
2955 [ (Format.Ledger.posting ("A":|[]))
2956 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
2957 , (Format.Ledger.posting ("B":|[]))
2958 { Format.Ledger.posting_amounts=Amount.from_List [] }
2962 Format.Ledger.posting_by_Account
2963 [ (Format.Ledger.posting ("A":|[]))
2964 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
2965 , (Format.Ledger.posting ("B":|[]))
2966 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1 ] }
2969 (snd $ Balance.infer_equilibrium $
2970 Format.Ledger.posting_by_Account
2971 [ (Format.Ledger.posting ("A":|[]))
2972 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
2973 , (Format.Ledger.posting ("B":|[]))
2974 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1 ] }
2978 Format.Ledger.posting_by_Account
2979 [ (Format.Ledger.posting ("A":|[]))
2980 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 1] }
2981 , (Format.Ledger.posting ("B":|[]))
2982 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.eur $ -1, Amount.usd $ -1 ] }
2985 (snd $ Balance.infer_equilibrium $
2986 Format.Ledger.posting_by_Account
2987 [ (Format.Ledger.posting ("A":|[]))
2988 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
2989 , (Format.Ledger.posting ("B":|[]))
2990 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
2995 { Balance.unit_sum_amount = Amount.sum $ Amount.usd $ 2
2996 , Balance.unit_sum_accounts = Data.Map.fromList []}
2998 , "{A+$1 B-$1 B-1€}" ~:
2999 (snd $ Balance.infer_equilibrium $
3000 Format.Ledger.posting_by_Account
3001 [ (Format.Ledger.posting ("A":|[]))
3002 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1 ] }
3003 , (Format.Ledger.posting ("B":|[]))
3004 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -1 ] }
3008 Format.Ledger.posting_by_Account
3009 [ (Format.Ledger.posting ("A":|[]))
3010 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ 1, Amount.eur $ 1 ] }
3011 , (Format.Ledger.posting ("B":|[]))
3012 { Format.Ledger.posting_amounts=Amount.from_List [ Amount.usd $ -1, Amount.eur $ -1 ] }
3016 , "Format" ~: TestList
3017 [ "Ledger" ~: TestList
3018 [ "Read" ~: TestList
3019 [ "account_name" ~: TestList
3021 (Data.Either.rights $
3023 (Format.Ledger.Read.account_name <* P.eof)
3028 (Data.Either.rights $
3030 (Format.Ledger.Read.account_name <* P.eof)
3035 (Data.Either.rights $
3037 (Format.Ledger.Read.account_name <* P.eof)
3038 () "" ("AA"::Text)])
3042 (Data.Either.rights $
3044 (Format.Ledger.Read.account_name <* P.eof)
3049 (Data.Either.rights $
3051 (Format.Ledger.Read.account_name <* P.eof)
3056 (Data.Either.rights $
3058 (Format.Ledger.Read.account_name <* P.eof)
3059 () "" ("A:"::Text)])
3063 (Data.Either.rights $
3065 (Format.Ledger.Read.account_name <* P.eof)
3066 () "" (":A"::Text)])
3070 (Data.Either.rights $
3072 (Format.Ledger.Read.account_name <* P.eof)
3073 () "" ("A "::Text)])
3077 (Data.Either.rights $
3079 (Format.Ledger.Read.account_name)
3080 () "" ("A "::Text)])
3084 (Data.Either.rights $
3086 (Format.Ledger.Read.account_name <* P.eof)
3087 () "" ("A A"::Text)])
3091 (Data.Either.rights $
3093 (Format.Ledger.Read.account_name <* P.eof)
3094 () "" ("A "::Text)])
3098 (Data.Either.rights $
3100 (Format.Ledger.Read.account_name <* P.eof)
3101 () "" ("A \n"::Text)])
3105 (Data.Either.rights $
3107 (Format.Ledger.Read.account_name <* P.eof)
3108 () "" ("(A)A"::Text)])
3112 (Data.Either.rights $
3114 (Format.Ledger.Read.account_name <* P.eof)
3115 () "" ("( )A"::Text)])
3119 (Data.Either.rights $
3121 (Format.Ledger.Read.account_name <* P.eof)
3122 () "" ("(A) A"::Text)])
3126 (Data.Either.rights $
3128 (Format.Ledger.Read.account_name <* P.eof)
3129 () "" ("[ ]A"::Text)])
3133 (Data.Either.rights $
3135 (Format.Ledger.Read.account_name <* P.eof)
3136 () "" ("(A) "::Text)])
3140 (Data.Either.rights $
3142 (Format.Ledger.Read.account_name <* P.eof)
3143 () "" ("(A)"::Text)])
3147 (Data.Either.rights $
3149 (Format.Ledger.Read.account_name <* P.eof)
3150 () "" ("A(A)"::Text)])
3154 (Data.Either.rights $
3156 (Format.Ledger.Read.account_name <* P.eof)
3157 () "" ("[A]A"::Text)])
3161 (Data.Either.rights $
3163 (Format.Ledger.Read.account_name <* P.eof)
3164 () "" ("[A] A"::Text)])
3168 (Data.Either.rights $
3170 (Format.Ledger.Read.account_name <* P.eof)
3171 () "" ("[A] "::Text)])
3175 (Data.Either.rights $
3177 (Format.Ledger.Read.account_name <* P.eof)
3178 () "" ("[A]"::Text)])
3182 , "account" ~: TestList
3184 (Data.Either.rights $
3186 (Format.Ledger.Read.account <* P.eof)
3191 (Data.Either.rights $
3193 (Format.Ledger.Read.account <* P.eof)
3198 (Data.Either.rights $
3200 (Format.Ledger.Read.account <* P.eof)
3201 () "" ("A:"::Text)])
3205 (Data.Either.rights $
3207 (Format.Ledger.Read.account <* P.eof)
3208 () "" (":A"::Text)])
3212 (Data.Either.rights $
3214 (Format.Ledger.Read.account <* P.eof)
3215 () "" ("A "::Text)])
3219 (Data.Either.rights $
3221 (Format.Ledger.Read.account <* P.eof)
3222 () "" (" A"::Text)])
3226 (Data.Either.rights $
3228 (Format.Ledger.Read.account <* P.eof)
3229 () "" ("A:B"::Text)])
3233 (Data.Either.rights $
3235 (Format.Ledger.Read.account <* P.eof)
3236 () "" ("A:B:C"::Text)])
3239 , "\"Aa:Bbb:Cccc\"" ~:
3240 (Data.Either.rights $
3242 (Format.Ledger.Read.account <* P.eof)
3243 () "" ("Aa:Bbb:Cccc"::Text)])
3245 ["Aa":|["Bbb", "Cccc"]]
3246 , "\"A a : B b b : C c c c\"" ~:
3247 (Data.Either.rights $
3249 (Format.Ledger.Read.account <* P.eof)
3250 () "" ("A a : B b b : C c c c"::Text)])
3252 ["A a ":|[" B b b ", " C c c c"]]
3254 (Data.Either.rights $
3256 (Format.Ledger.Read.account <* P.eof)
3257 () "" ("A: :C"::Text)])
3261 (Data.Either.rights $
3263 (Format.Ledger.Read.account <* P.eof)
3264 () "" ("A::C"::Text)])
3268 (Data.Either.rights $
3270 (Format.Ledger.Read.account <* P.eof)
3271 () "" ("A:B:(C)"::Text)])
3275 , "posting_type" ~: TestList
3277 Format.Ledger.Read.posting_type
3280 (Format.Ledger.Posting_Type_Regular, "A":|[])
3282 Format.Ledger.Read.posting_type
3285 (Format.Ledger.Posting_Type_Regular, "(":|[])
3287 Format.Ledger.Read.posting_type
3290 (Format.Ledger.Posting_Type_Regular, ")":|[])
3292 Format.Ledger.Read.posting_type
3295 (Format.Ledger.Posting_Type_Regular, "()":|[])
3297 Format.Ledger.Read.posting_type
3300 (Format.Ledger.Posting_Type_Regular, "( )":|[])
3302 Format.Ledger.Read.posting_type
3305 (Format.Ledger.Posting_Type_Virtual, "A":|[])
3307 Format.Ledger.Read.posting_type
3310 (Format.Ledger.Posting_Type_Virtual, "A":|["B", "C"])
3312 Format.Ledger.Read.posting_type
3315 (Format.Ledger.Posting_Type_Regular, "A":|["B", "C"])
3317 Format.Ledger.Read.posting_type
3320 (Format.Ledger.Posting_Type_Regular, "(A)":|["B", "C"])
3322 Format.Ledger.Read.posting_type
3325 (Format.Ledger.Posting_Type_Regular, "A":|["(B)", "C"])
3327 Format.Ledger.Read.posting_type
3330 (Format.Ledger.Posting_Type_Regular, "A":|["B", "(C)"])
3332 Format.Ledger.Read.posting_type
3335 (Format.Ledger.Posting_Type_Regular, "[":|[])
3337 Format.Ledger.Read.posting_type
3340 (Format.Ledger.Posting_Type_Regular, "]":|[])
3342 Format.Ledger.Read.posting_type
3345 (Format.Ledger.Posting_Type_Regular, "[]":|[])
3347 Format.Ledger.Read.posting_type
3350 (Format.Ledger.Posting_Type_Regular, "[ ]":|[])
3352 Format.Ledger.Read.posting_type
3355 (Format.Ledger.Posting_Type_Virtual_Balanced, "A":|[])
3357 Format.Ledger.Read.posting_type
3360 (Format.Ledger.Posting_Type_Virtual_Balanced, "A":|["B", "C"])
3362 Format.Ledger.Read.posting_type
3365 (Format.Ledger.Posting_Type_Regular, "A":|["B", "C"])
3367 Format.Ledger.Read.posting_type
3370 (Format.Ledger.Posting_Type_Regular, "[A]":|["B", "C"])
3372 Format.Ledger.Read.posting_type
3375 (Format.Ledger.Posting_Type_Regular, "A":|["[B]", "C"])
3377 Format.Ledger.Read.posting_type
3380 (Format.Ledger.Posting_Type_Regular, "A":|["B", "[C]"])
3382 , "comment" ~: TestList
3383 [ "; some comment = Right \" some comment\"" ~:
3384 (Data.Either.rights $
3386 (Format.Ledger.Read.comment <* P.eof)
3387 () "" ("; some comment"::Text)])
3390 , "; some comment \\n = Right \" some comment \"" ~:
3391 (Data.Either.rights $
3393 (Format.Ledger.Read.comment <* P.newline <* P.eof)
3394 () "" ("; some comment \n"::Text)])
3396 [ " some comment " ]
3397 , "; some comment \\r\\n = Right \" some comment \"" ~:
3398 (Data.Either.rights $
3400 (Format.Ledger.Read.comment <* P.string "\r\n" <* P.eof)
3401 () "" ("; some comment \r\n"::Text)])
3403 [ " some comment " ]
3405 , "comments" ~: TestList
3406 [ "; some comment\\n ; some other comment = Right [\" some comment\", \" some other comment\"]" ~:
3407 (Data.Either.rights $
3409 (Format.Ledger.Read.comments <* P.eof)
3410 () "" ("; some comment\n ; some other comment"::Text)])
3412 [ [" some comment", " some other comment"] ]
3413 , "; some comment \\n = Right \" some comment \"" ~:
3414 (Data.Either.rights $
3416 (Format.Ledger.Read.comments <* P.string "\n" <* P.eof)
3417 () "" ("; some comment \n"::Text)])
3419 [ [" some comment "] ]
3421 , "tag_value" ~: TestList
3423 (Data.Either.rights $
3425 (Format.Ledger.Read.tag_value <* P.eof)
3430 (Data.Either.rights $
3432 (Format.Ledger.Read.tag_value <* P.char '\n' <* P.eof)
3433 () "" (",\n"::Text)])
3437 (Data.Either.rights $
3439 (Format.Ledger.Read.tag_value <* P.eof)
3440 () "" (",x"::Text)])
3444 (Data.Either.rights $
3446 (Format.Ledger.Read.tag_value <* P.string ",x:" <* P.eof)
3447 () "" (",x:"::Text)])
3451 (Data.Either.rights $
3453 (Format.Ledger.Read.tag_value <* P.string ", n:" <* P.eof)
3454 () "" ("v, v, n:"::Text)])
3460 (Data.Either.rights $
3462 (Format.Ledger.Read.tag <* P.eof)
3463 () "" ("Name:"::Text)])
3467 (Data.Either.rights $
3469 (Format.Ledger.Read.tag <* P.eof)
3470 () "" ("Name:Value"::Text)])
3473 , "Name:Value\\n" ~:
3474 (Data.Either.rights $
3476 (Format.Ledger.Read.tag <* P.string "\n" <* P.eof)
3477 () "" ("Name:Value\n"::Text)])
3481 (Data.Either.rights $
3483 (Format.Ledger.Read.tag <* P.eof)
3484 () "" ("Name:Val ue"::Text)])
3486 [("Name", "Val ue")]
3488 (Data.Either.rights $
3490 (Format.Ledger.Read.tag <* P.eof)
3491 () "" ("Name:,"::Text)])
3495 (Data.Either.rights $
3497 (Format.Ledger.Read.tag <* P.eof)
3498 () "" ("Name:Val,ue"::Text)])
3500 [("Name", "Val,ue")]
3502 (Data.Either.rights $
3504 (Format.Ledger.Read.tag <* P.string ",ue:" <* P.eof)
3505 () "" ("Name:Val,ue:"::Text)])
3509 , "tags" ~: TestList
3511 (Data.Either.rights $
3513 (Format.Ledger.Read.tags <* P.eof)
3514 () "" ("Name:"::Text)])
3521 (Data.Either.rights $
3523 (Format.Ledger.Read.tags <* P.eof)
3524 () "" ("Name:,"::Text)])
3531 (Data.Either.rights $
3533 (Format.Ledger.Read.tags <* P.eof)
3534 () "" ("Name:,Name:"::Text)])
3537 [ ("Name", ["", ""])
3541 (Data.Either.rights $
3543 (Format.Ledger.Read.tags <* P.eof)
3544 () "" ("Name:,Name2:"::Text)])
3551 , "Name: , Name2:" ~:
3552 (Data.Either.rights $
3554 (Format.Ledger.Read.tags <* P.eof)
3555 () "" ("Name: , Name2:"::Text)])
3562 , "Name:,Name2:,Name3:" ~:
3563 (Data.Either.rights $
3565 (Format.Ledger.Read.tags <* P.eof)
3566 () "" ("Name:,Name2:,Name3:"::Text)])
3574 , "Name:Val ue,Name2:V a l u e,Name3:V al ue" ~:
3575 (Data.Either.rights $
3577 (Format.Ledger.Read.tags <* P.eof)
3578 () "" ("Name:Val ue,Name2:V a l u e,Name3:V al ue"::Text)])
3581 [ ("Name", ["Val ue"])
3582 , ("Name2", ["V a l u e"])
3583 , ("Name3", ["V al ue"])
3587 , "posting" ~: TestList
3588 [ " A:B:C = Right A:B:C" ~:
3589 (Data.Either.rights $
3590 [P.runParser_with_Error
3591 (Format.Ledger.Read.posting <* P.eof)
3592 Format.Ledger.Read.nil_Context "" (" A:B:C"::Text)])
3594 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
3595 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3597 , Format.Ledger.Posting_Type_Regular
3600 , " !A:B:C = Right !A:B:C" ~:
3601 (Data.List.map fst $
3602 Data.Either.rights $
3603 [P.runParser_with_Error
3604 (Format.Ledger.Read.posting <* P.eof)
3605 Format.Ledger.Read.nil_Context "" (" !A:B:C"::Text)])
3607 [ (Format.Ledger.posting ("A":|["B", "C"]))
3608 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3609 , Format.Ledger.posting_status = True
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_amounts = Data.Map.fromList []
3621 , Format.Ledger.posting_comments = []
3622 , Format.Ledger.posting_dates = []
3623 , Format.Ledger.posting_status = True
3624 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3625 , Format.Ledger.posting_tags = Data.Map.fromList []
3628 , " A:B:C $1 = Right A:B:C $1" ~:
3629 (Data.List.map fst $
3630 Data.Either.rights $
3631 [P.runParser_with_Error
3632 (Format.Ledger.Read.posting <* P.eof)
3633 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
3635 [ (Format.Ledger.posting ("A":|["B","C $1"]))
3636 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3639 , " A:B:C $1 = Right A:B:C $1" ~:
3640 (Data.List.map fst $
3641 Data.Either.rights $
3642 [P.runParser_with_Error
3643 (Format.Ledger.Read.posting <* P.eof)
3644 Format.Ledger.Read.nil_Context "" (" A:B:C $1"::Text)])
3646 [ (Format.Ledger.posting ("A":|["B", "C"]))
3647 { Format.Ledger.posting_amounts = Data.Map.fromList
3649 { Amount.quantity = 1
3650 , Amount.style = Amount.Style.nil
3651 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3652 , Amount.Style.unit_spaced = Just False
3657 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3660 , " A:B:C $1 + 1€ = Right A:B:C $1 + 1€" ~:
3661 (Data.List.map fst $
3662 Data.Either.rights $
3663 [P.runParser_with_Error
3664 (Format.Ledger.Read.posting <* P.eof)
3665 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1€"::Text)])
3667 [ (Format.Ledger.posting ("A":|["B", "C"]))
3668 { Format.Ledger.posting_amounts = Data.Map.fromList
3670 { Amount.quantity = 1
3671 , Amount.style = Amount.Style.nil
3672 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3673 , Amount.Style.unit_spaced = Just False
3678 { Amount.quantity = 1
3679 , Amount.style = Amount.Style.nil
3680 { Amount.Style.unit_side = Just Amount.Style.Side_Right
3681 , Amount.Style.unit_spaced = Just False
3686 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3689 , " A:B:C $1 + 1$ = Right A:B:C $2" ~:
3690 (Data.List.map fst $
3691 Data.Either.rights $
3692 [P.runParser_with_Error
3693 (Format.Ledger.Read.posting <* P.eof)
3694 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$"::Text)])
3696 [ (Format.Ledger.posting ("A":|["B", "C"]))
3697 { Format.Ledger.posting_amounts = Data.Map.fromList
3699 { Amount.quantity = 2
3700 , Amount.style = Amount.Style.nil
3701 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3702 , Amount.Style.unit_spaced = Just False
3707 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3710 , " A:B:C $1 + 1$ + 1$ = Right A:B:C $3" ~:
3711 (Data.List.map fst $
3712 Data.Either.rights $
3713 [P.runParser_with_Error
3714 (Format.Ledger.Read.posting <* P.eof)
3715 Format.Ledger.Read.nil_Context "" (" A:B:C $1 + 1$ + 1$"::Text)])
3717 [ (Format.Ledger.posting ("A":|["B", "C"]))
3718 { Format.Ledger.posting_amounts = Data.Map.fromList
3720 { Amount.quantity = 3
3721 , Amount.style = Amount.Style.nil
3722 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3723 , Amount.Style.unit_spaced = Just False
3728 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3731 , " A:B:C ; some comment = Right A:B:C ; some comment" ~:
3732 (Data.List.map fst $
3733 Data.Either.rights $
3734 [P.runParser_with_Error
3735 (Format.Ledger.Read.posting <* P.eof)
3736 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment"::Text)])
3738 [ (Format.Ledger.posting ("A":|["B", "C"]))
3739 { Format.Ledger.posting_amounts = Data.Map.fromList []
3740 , Format.Ledger.posting_comments = [" some comment"]
3741 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3744 , " A:B:C ; some comment\\n ; some other comment = Right A:B:C ; some comment\\n ; some other comment" ~:
3745 (Data.List.map fst $
3746 Data.Either.rights $
3747 [P.runParser_with_Error
3748 (Format.Ledger.Read.posting <* P.eof)
3749 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment\n ; some other comment"::Text)])
3751 [ (Format.Ledger.posting ("A":|["B", "C"]))
3752 { Format.Ledger.posting_amounts = Data.Map.fromList []
3753 , Format.Ledger.posting_comments = [" some comment", " some other comment"]
3754 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3757 , " A:B:C $1 ; some comment = Right A:B:C $1 ; some comment" ~:
3758 (Data.List.map fst $
3759 Data.Either.rights $
3760 [P.runParser_with_Error
3761 (Format.Ledger.Read.posting)
3762 Format.Ledger.Read.nil_Context "" (" A:B:C $1 ; some comment"::Text)])
3764 [ (Format.Ledger.posting ("A":|["B", "C"]))
3765 { Format.Ledger.posting_amounts = Data.Map.fromList
3767 { Amount.quantity = 1
3768 , Amount.style = Amount.Style.nil
3769 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3770 , Amount.Style.unit_spaced = Just False
3775 , Format.Ledger.posting_comments = [" some comment"]
3776 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3779 , " A:B:C ; N:V = Right A:B:C ; N:V" ~:
3780 (Data.List.map fst $
3781 Data.Either.rights $
3782 [P.runParser_with_Error
3783 (Format.Ledger.Read.posting <* P.eof)
3784 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V"::Text)])
3786 [ (Format.Ledger.posting ("A":|["B", "C"]))
3787 { Format.Ledger.posting_comments = [" N:V"]
3788 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3789 , Format.Ledger.posting_tags = Data.Map.fromList
3794 , " A:B:C ; some comment N:V = Right A:B:C ; some comment N:V" ~:
3795 (Data.List.map fst $
3796 Data.Either.rights $
3797 [P.runParser_with_Error
3798 (Format.Ledger.Read.posting <* P.eof)
3799 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V"::Text)])
3801 [ (Format.Ledger.posting ("A":|["B", "C"]))
3802 { Format.Ledger.posting_comments = [" some comment N:V"]
3803 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3804 , Format.Ledger.posting_tags = Data.Map.fromList
3809 , " A:B:C ; some comment N:V v, N2:V2 v2 = Right A:B:C ; some comment N:V v, N2:V2 v2" ~:
3810 (Data.List.map fst $
3811 Data.Either.rights $
3812 [P.runParser_with_Error
3813 (Format.Ledger.Read.posting )
3814 Format.Ledger.Read.nil_Context "" (" A:B:C ; some comment N:V v, N2:V2 v2"::Text)])
3816 [ (Format.Ledger.posting ("A":|["B", "C"]))
3817 { Format.Ledger.posting_comments = [" some comment N:V v, N2:V2 v2"]
3818 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3819 , Format.Ledger.posting_tags = Data.Map.fromList
3825 , " A:B:C ; N:V\\n ; N:V2 = Right A:B:C ; N:V\\n ; N:V2" ~:
3826 (Data.List.map fst $
3827 Data.Either.rights $
3828 [P.runParser_with_Error
3829 (Format.Ledger.Read.posting <* P.eof)
3830 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N:V2"::Text)])
3832 [ (Format.Ledger.posting ("A":|["B", "C"]))
3833 { Format.Ledger.posting_comments = [" N:V", " N:V2"]
3834 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3835 , Format.Ledger.posting_tags = Data.Map.fromList
3836 [ ("N", ["V", "V2"])
3840 , " A:B:C ; N:V\\n ; N2:V = Right A:B:C ; N:V\\n ; N2:V" ~:
3841 (Data.List.map fst $
3842 Data.Either.rights $
3843 [P.runParser_with_Error
3844 (Format.Ledger.Read.posting <* P.eof)
3845 Format.Ledger.Read.nil_Context "" (" A:B:C ; N:V\n ; N2:V"::Text)])
3847 [ (Format.Ledger.posting ("A":|["B", "C"]))
3848 { Format.Ledger.posting_comments = [" N:V", " N2:V"]
3849 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3850 , Format.Ledger.posting_tags = Data.Map.fromList
3856 , " A:B:C ; date:2001/01/01 = Right A:B:C ; date:2001/01/01" ~:
3857 (Data.List.map fst $
3858 Data.Either.rights $
3859 [P.runParser_with_Error
3860 (Format.Ledger.Read.posting <* P.eof)
3861 Format.Ledger.Read.nil_Context "" (" A:B:C ; date:2001/01/01"::Text)])
3863 [ (Format.Ledger.posting ("A":|["B", "C"]))
3864 { Format.Ledger.posting_comments = [" date:2001/01/01"]
3865 , Format.Ledger.posting_dates =
3866 [ Time.zonedTimeToUTC $
3869 (Time.fromGregorian 2001 01 01)
3870 (Time.TimeOfDay 0 0 0))
3873 , Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3874 , Format.Ledger.posting_tags = Data.Map.fromList
3875 [ ("date", ["2001/01/01"])
3879 , " (A:B:C) = Right (A:B:C)" ~:
3880 (Data.Either.rights $
3881 [P.runParser_with_Error
3882 (Format.Ledger.Read.posting <* P.eof)
3883 Format.Ledger.Read.nil_Context "" (" (A:B:C)"::Text)])
3885 [ ( (Format.Ledger.posting ("A":|["B", "C"]))
3886 { Format.Ledger.posting_sourcepos = P.newPos "" 1 1
3888 , Format.Ledger.Posting_Type_Virtual
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_Balanced
3904 , "transaction" ~: TestList
3905 [ "2000/01/01 some description\\n A:B:C $1\\n a:b:c" ~:
3906 (Data.Either.rights $
3907 [P.runParser_with_Error
3908 (Format.Ledger.Read.transaction <* P.eof)
3909 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c"::Text)])
3911 [ Format.Ledger.transaction
3912 { Format.Ledger.transaction_dates=
3913 ( Time.zonedTimeToUTC $
3916 (Time.fromGregorian 2000 01 01)
3917 (Time.TimeOfDay 0 0 0))
3920 , Format.Ledger.transaction_description="some description"
3921 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3922 [ (Format.Ledger.posting ("A":|["B", "C"]))
3923 { Format.Ledger.posting_amounts = Data.Map.fromList
3925 { Amount.quantity = 1
3926 , Amount.style = Amount.Style.nil
3927 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3928 , Amount.Style.unit_spaced = Just False
3933 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3935 , (Format.Ledger.posting ("a":|["b", "c"]))
3936 { Format.Ledger.posting_amounts = Data.Map.fromList
3938 { Amount.quantity = -1
3939 , Amount.style = Amount.Style.nil
3940 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3941 , Amount.Style.unit_spaced = Just False
3946 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3949 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3952 , "2000/01/01 some description\\n A:B:C $1\\n a:b:c\\n" ~:
3953 (Data.Either.rights $
3954 [P.runParser_with_Error
3955 (Format.Ledger.Read.transaction <* P.newline <* P.eof)
3956 Format.Ledger.Read.nil_Context "" ("2000/01/01 some description\n A:B:C $1\n a:b:c\n"::Text)])
3958 [ Format.Ledger.transaction
3959 { Format.Ledger.transaction_dates=
3960 ( Time.zonedTimeToUTC $
3963 (Time.fromGregorian 2000 01 01)
3964 (Time.TimeOfDay 0 0 0))
3967 , Format.Ledger.transaction_description="some description"
3968 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
3969 [ (Format.Ledger.posting ("A":|["B", "C"]))
3970 { Format.Ledger.posting_amounts = Data.Map.fromList
3972 { Amount.quantity = 1
3973 , Amount.style = Amount.Style.nil
3974 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3975 , Amount.Style.unit_spaced = Just False
3980 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
3982 , (Format.Ledger.posting ("a":|["b", "c"]))
3983 { Format.Ledger.posting_amounts = Data.Map.fromList
3985 { Amount.quantity = -1
3986 , Amount.style = Amount.Style.nil
3987 { Amount.Style.unit_side = Just Amount.Style.Side_Left
3988 , Amount.Style.unit_spaced = Just False
3993 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
3996 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
3999 , "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" ~:
4000 (Data.Either.rights $
4001 [P.runParser_with_Error
4002 (Format.Ledger.Read.transaction <* P.eof)
4003 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)])
4005 [ Format.Ledger.transaction
4006 { Format.Ledger.transaction_comments_after =
4008 , " some other;comment"
4010 , " some last comment"
4012 , Format.Ledger.transaction_dates=
4013 ( Time.zonedTimeToUTC $
4016 (Time.fromGregorian 2000 01 01)
4017 (Time.TimeOfDay 0 0 0))
4020 , Format.Ledger.transaction_description="some description"
4021 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
4022 [ (Format.Ledger.posting ("A":|["B", "C"]))
4023 { Format.Ledger.posting_amounts = Data.Map.fromList
4025 { Amount.quantity = 1
4026 , Amount.style = Amount.Style.nil
4027 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4028 , Amount.Style.unit_spaced = Just False
4033 , Format.Ledger.posting_sourcepos = P.newPos "" 5 1
4035 , (Format.Ledger.posting ("a":|["b", "c"]))
4036 { Format.Ledger.posting_amounts = Data.Map.fromList
4038 { Amount.quantity = -1
4039 , Amount.style = Amount.Style.nil
4040 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4041 , Amount.Style.unit_spaced = Just False
4046 , Format.Ledger.posting_sourcepos = P.newPos "" 6 1
4049 , Format.Ledger.transaction_tags = Data.Map.fromList
4052 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
4056 , "journal" ~: TestList
4057 [ "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
4059 P.runParserT_with_Error
4060 (Format.Ledger.Read.journal "" {-<* P.eof-})
4061 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)
4063 (\j -> j{Format.Ledger.journal_last_read_time=
4064 Format.Ledger.journal_last_read_time Format.Ledger.journal}) $
4065 Data.Either.rights [jnl])
4067 [ Format.Ledger.journal
4068 { Format.Ledger.journal_transactions =
4069 Format.Ledger.transaction_by_Date
4070 [ Format.Ledger.transaction
4071 { Format.Ledger.transaction_dates=
4072 ( Time.zonedTimeToUTC $
4075 (Time.fromGregorian 2000 01 01)
4076 (Time.TimeOfDay 0 0 0))
4079 , Format.Ledger.transaction_description="1° description"
4080 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
4081 [ (Format.Ledger.posting ("A":|["B", "C"]))
4082 { Format.Ledger.posting_amounts = Data.Map.fromList
4084 { Amount.quantity = 1
4085 , Amount.style = Amount.Style.nil
4086 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4087 , Amount.Style.unit_spaced = Just False
4092 , Format.Ledger.posting_sourcepos = P.newPos "" 2 1
4094 , (Format.Ledger.posting ("a":|["b", "c"]))
4095 { Format.Ledger.posting_amounts = Data.Map.fromList
4097 { Amount.quantity = -1
4098 , Amount.style = Amount.Style.nil
4099 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4100 , Amount.Style.unit_spaced = Just False
4105 , Format.Ledger.posting_sourcepos = P.newPos "" 3 1
4108 , Format.Ledger.transaction_sourcepos = P.newPos "" 1 1
4110 , Format.Ledger.transaction
4111 { Format.Ledger.transaction_dates=
4112 ( Time.zonedTimeToUTC $
4115 (Time.fromGregorian 2000 01 02)
4116 (Time.TimeOfDay 0 0 0))
4119 , Format.Ledger.transaction_description="2° description"
4120 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
4121 [ (Format.Ledger.posting ("A":|["B", "C"]))
4122 { Format.Ledger.posting_amounts = Data.Map.fromList
4124 { Amount.quantity = 1
4125 , Amount.style = Amount.Style.nil
4126 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4127 , Amount.Style.unit_spaced = Just False
4132 , Format.Ledger.posting_sourcepos = P.newPos "" 5 1
4134 , (Format.Ledger.posting ("x":|["y", "z"]))
4135 { Format.Ledger.posting_amounts = Data.Map.fromList
4137 { Amount.quantity = -1
4138 , Amount.style = Amount.Style.nil
4139 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4140 , Amount.Style.unit_spaced = Just False
4145 , Format.Ledger.posting_sourcepos = P.newPos "" 6 1
4148 , Format.Ledger.transaction_sourcepos = P.newPos "" 4 1
4155 , "Write" ~: TestList
4156 [ "account" ~: TestList
4158 ((Format.Ledger.Write.show
4159 Format.Ledger.Write.Style
4160 { Format.Ledger.Write.style_color=False
4161 , Format.Ledger.Write.style_align=True
4163 Format.Ledger.Write.account Format.Ledger.Posting_Type_Regular $
4168 ((Format.Ledger.Write.show
4169 Format.Ledger.Write.Style
4170 { Format.Ledger.Write.style_color=False
4171 , Format.Ledger.Write.style_align=True
4173 Format.Ledger.Write.account Format.Ledger.Posting_Type_Regular $
4178 ((Format.Ledger.Write.show
4179 Format.Ledger.Write.Style
4180 { Format.Ledger.Write.style_color=False
4181 , Format.Ledger.Write.style_align=True
4183 Format.Ledger.Write.account Format.Ledger.Posting_Type_Virtual $
4188 ((Format.Ledger.Write.show
4189 Format.Ledger.Write.Style
4190 { Format.Ledger.Write.style_color=False
4191 , Format.Ledger.Write.style_align=True
4193 Format.Ledger.Write.account Format.Ledger.Posting_Type_Virtual_Balanced $
4198 , "transaction" ~: TestList
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.transaction
4206 Format.Ledger.transaction)
4209 , "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" ~:
4210 ((Format.Ledger.Write.show
4211 Format.Ledger.Write.Style
4212 { Format.Ledger.Write.style_color=False
4213 , Format.Ledger.Write.style_align=True
4215 Format.Ledger.Write.transaction $
4216 Format.Ledger.transaction
4217 { Format.Ledger.transaction_dates=
4218 ( Time.zonedTimeToUTC $
4221 (Time.fromGregorian 2000 01 01)
4222 (Time.TimeOfDay 0 0 0))
4225 , Format.Ledger.transaction_description="some description"
4226 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
4227 [ (Format.Ledger.posting ("A":|["B", "C"]))
4228 { Format.Ledger.posting_amounts = Data.Map.fromList
4230 { Amount.quantity = 1
4231 , Amount.style = Amount.Style.nil
4232 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4233 , Amount.Style.unit_spaced = Just False
4239 , (Format.Ledger.posting ("a":|["b", "c"]))
4240 { Format.Ledger.posting_comments = ["first comment","second comment","third comment"]
4245 "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")
4246 , "2000/01/01 some description\\n\\tA:B:C $1\\n\\tAA:BB:CC $123" ~:
4247 ((Format.Ledger.Write.show
4248 Format.Ledger.Write.Style
4249 { Format.Ledger.Write.style_color=False
4250 , Format.Ledger.Write.style_align=True
4252 Format.Ledger.Write.transaction $
4253 Format.Ledger.transaction
4254 { Format.Ledger.transaction_dates=
4255 ( Time.zonedTimeToUTC $
4258 (Time.fromGregorian 2000 01 01)
4259 (Time.TimeOfDay 0 0 0))
4262 , Format.Ledger.transaction_description="some description"
4263 , Format.Ledger.transaction_postings = Format.Ledger.posting_by_Account
4264 [ (Format.Ledger.posting ("A":|["B", "C"]))
4265 { Format.Ledger.posting_amounts = Data.Map.fromList
4267 { Amount.quantity = 1
4268 , Amount.style = Amount.Style.nil
4269 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4270 , Amount.Style.unit_spaced = Just False
4276 , (Format.Ledger.posting ("AA":|["BB", "CC"]))
4277 { Format.Ledger.posting_amounts = Data.Map.fromList
4279 { Amount.quantity = 123
4280 , Amount.style = Amount.Style.nil
4281 { Amount.Style.unit_side = Just Amount.Style.Side_Left
4282 , Amount.Style.unit_spaced = Just False
4291 "2000/01/01 some description\n\tA:B:C $1\n\tAA:BB:CC $123")