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 (Const(..))
12 import Control.Arrow ((***))
14 import qualified Data.Either
15 import Data.Function (on)
16 -- import Data.Functor.Compose (Compose(..))
17 import qualified Data.List as List
18 import Data.List.NonEmpty (NonEmpty(..))
19 import qualified Data.Map.Strict as Map
20 import Data.Maybe (fromJust)
21 import qualified Data.Strict.Maybe as Strict
22 import Data.Text (Text)
23 import qualified Text.Parsec as P hiding (char, space, spaces, string)
25 import qualified Hcompta.Account as Account
26 import qualified Hcompta.Balance as Balance
27 import qualified Hcompta.Filter as Filter
28 import qualified Hcompta.Filter.Read as Filter.Read
29 import qualified Hcompta.Lib.Foldable as Lib.Foldable
30 import qualified Hcompta.Lib.Interval as Lib.Interval
31 import qualified Hcompta.Lib.Interval.Sieve as Lib.Interval.Sieve
32 import qualified Hcompta.Lib.Parsec as P
33 import qualified Hcompta.Lib.TreeMap as TreeMap
34 import qualified Hcompta.Polarize as Polarize
35 import qualified Hcompta.Quantity as Quantity
36 import qualified Hcompta.Tag as Tag
39 main = defaultMain $ hUnitTestToTests test_Hcompta
41 (~?) :: String -> Bool -> Test
42 (~?) s b = s ~: (b ~?= True)
44 amounts :: (Quantity.Addable q, Ord u) => [(u, q)] -> Map.Map u q
45 amounts = Map.fromListWith Quantity.quantity_add
46 amount_usd = (("$"::Text),)
47 amount_eur = (("€"::Text),)
48 amount_gbp = (("£"::Text),)
54 [ "TreeMap" ~: TestList
55 [ "insert" ~: TestList
57 (TreeMap.insert const ((0::Int):|[]) () TreeMap.empty)
61 [ ((0::Int), TreeMap.leaf ())
64 (TreeMap.insert const ((0::Int):|1:[]) () TreeMap.empty)
68 [ ((0::Int), TreeMap.Node
69 { TreeMap.node_value = Strict.Nothing
70 , TreeMap.node_size = 1
71 , TreeMap.node_descendants =
72 TreeMap.singleton ((1::Int):|[]) ()
79 , "map_by_depth_first" ~: TestList
80 [ "[0, 0/1, 0/1/2, 1, 1/2/3]" ~:
81 (TreeMap.map_by_depth_first
82 (\descendants value ->
85 Strict.fromMaybe undefined $
88 (Strict.fromMaybe [] value)
89 (TreeMap.nodes descendants)
91 TreeMap.from_List const
92 [ (((0::Integer):|[]), [0])
94 , ((0:|1:2:[]), [0,1,2])
96 , ((1:|2:3:[]), [1,2,3])
100 (TreeMap.from_List const
101 [ ((0:|[]), [0,0,1,0,1,2])
102 , ((0:|1:[]), [0,1,0,1,2])
103 , ((0:|1:2:[]), [0,1,2])
104 , ((1:|[]), [1,1,2,3])
105 , ((1:|2:[]), [1,2,3])
106 , ((1:|2:3:[]), [1,2,3])
109 (TreeMap.map_by_depth_first
110 (\descendants value ->
112 (\acc v -> (++) acc $
113 Strict.fromMaybe undefined $
116 (Strict.fromMaybe [] value)
117 (TreeMap.nodes descendants)
119 TreeMap.from_List const
120 [ (((0::Integer):|0:[]), [0,0])
124 (TreeMap.from_List const
129 , "flatten" ~: TestList
130 [ "[0, 0/1, 0/1/2]" ~:
131 (TreeMap.flatten id $
132 TreeMap.from_List const
133 [ (((0::Integer):|[]), ())
144 , "[1, 1/2, 1/22, 1/2/3, 1/2/33, 11, 11/2, 11/2/3, 11/2/33]" ~:
145 (TreeMap.flatten id $
146 TreeMap.from_List const
155 , ((11:|2:33:[]), ())
160 [ (((1::Integer):|[]), ())
168 , ((11:|2:33:[]), ())
171 , "find_along" ~: TestList
172 [ "0/1/2/3 [0, 0/1, 0/1/2, 0/1/2/3]" ~:
175 TreeMap.from_List const
176 [ (((0::Integer):|[]), [0])
178 , ((0:|1:2:[]), [0,1,2])
179 , ((0:|1:2:3:[]), [0,1,2,3])
188 , "0/1/2/3 [0, 0/1]" ~:
191 TreeMap.from_List const
192 [ (((0::Integer):|[]), [0])
202 , "Foldable" ~: TestList
203 [ "accumLeftsAndFoldrRights" ~: TestList
205 (Lib.Foldable.accumLeftsAndFoldrRights (++) [""] $
208 (([(0::Integer)], [(""::String)]))
210 ((take 1 *** take 0) $
211 Lib.Foldable.accumLeftsAndFoldrRights (++) [""] $
212 ( repeat (Left [0]) ))
214 ([(0::Integer)], ([]::[String]))
215 , "Right:Left:Right:Left" ~:
216 (Lib.Foldable.accumLeftsAndFoldrRights (++) ["0"] $
217 ( Right ["2"]:Left [1]:Right ["1"]:Left [0]:[] ))
219 (([1, 0]::[Integer]), (["2", "1", "0"]::[String]))
220 , "Right:Left:Right:repeat Left" ~:
221 ((take 1 *** take 2) $
222 Lib.Foldable.accumLeftsAndFoldrRights (++) ["0"] $
223 ( Right ["2"]:Left [1]:Right ["1"]:repeat (Left [0]) ))
225 (([1]::[Integer]), (["2", "1"]::[String]))
228 , "Interval" ~: TestList
229 [ "position" ~: TestList $
232 let i = fromJust mi in
233 let j = fromJust mj in
236 Lib.Interval.Equal -> (EQ, EQ)
238 [ ((show . Lib.Interval.Pretty) i ++ " " ++ (show . Lib.Interval.Pretty) j) ~: Lib.Interval.position i j ~?= (p, le)
239 , ((show . Lib.Interval.Pretty) j ++ " " ++ (show . Lib.Interval.Pretty) i) ~: Lib.Interval.position j i ~?= (p, ge)
242 [ ( (Lib.Interval.<..<) 0 (4::Integer)
243 , (Lib.Interval.<..<) 5 9
244 , Lib.Interval.Away )
245 , ( (Lib.Interval.<..<) 0 4
246 , (Lib.Interval.<=..<) 4 9
247 , Lib.Interval.Adjacent )
248 , ( (Lib.Interval.<..<) 0 5
249 , (Lib.Interval.<..<) 4 9
250 , Lib.Interval.Overlap )
251 , ( (Lib.Interval.<..<) 0 5
252 , (Lib.Interval.<..<) 0 9
253 , Lib.Interval.Prefix )
254 , ( (Lib.Interval.<..<) 0 9
255 , (Lib.Interval.<..<) 1 8
256 , Lib.Interval.Include )
257 , ( (Lib.Interval.<..<) 0 9
258 , (Lib.Interval.<..<) 5 9
259 , Lib.Interval.Suffixed )
260 , ( (Lib.Interval.<..<) 0 9
261 , (Lib.Interval.<..<) 0 9
262 , Lib.Interval.Equal )
263 , ( (Lib.Interval.<..<) 0 9
264 , (Lib.Interval.<..<=) 0 9
265 , Lib.Interval.Prefix )
266 , ( (Lib.Interval.<=..<) 0 9
267 , (Lib.Interval.<..<) 0 9
268 , Lib.Interval.Suffixed )
269 , ( (Lib.Interval.<=..<=) 0 9
270 , (Lib.Interval.<..<) 0 9
271 , Lib.Interval.Include )
273 , "intersection" ~: TestList $
276 let i = fromJust mi in
277 let j = fromJust mj in
278 [ ((show . Lib.Interval.Pretty) i ++ " " ++ (show . Lib.Interval.Pretty) j) ~: Lib.Interval.intersection i j ~?= e
279 , ((show . Lib.Interval.Pretty) j ++ " " ++ (show . Lib.Interval.Pretty) i) ~: Lib.Interval.intersection j i ~?= e
282 [ ( (Lib.Interval.<..<) 0 (4::Integer)
283 , (Lib.Interval.<..<) 5 9
285 , ( (Lib.Interval.<..<=) 0 5
286 , (Lib.Interval.<=..<) 5 9
287 , (Lib.Interval.<=..<=) 5 5 )
288 , ( (Lib.Interval.<..<) 0 6
289 , (Lib.Interval.<..<) 4 9
290 , (Lib.Interval.<..<) 4 6 )
291 , ( (Lib.Interval.<..<=) 0 6
292 , (Lib.Interval.<=..<) 4 9
293 , (Lib.Interval.<=..<=) 4 6 )
294 , ( (Lib.Interval.<..<) 0 6
295 , (Lib.Interval.<=..<) 4 9
296 , (Lib.Interval.<=..<) 4 6 )
297 , ( (Lib.Interval.<..<=) 0 6
298 , (Lib.Interval.<..<) 4 9
299 , (Lib.Interval.<..<=) 4 6 )
300 , ( (Lib.Interval.<..<) 0 9
301 , (Lib.Interval.<..<) 0 9
302 , (Lib.Interval.<..<) 0 9 )
303 , ( (Lib.Interval.<=..<) 0 9
304 , (Lib.Interval.<..<=) 0 9
305 , (Lib.Interval.<..<) 0 9 )
306 , ( (Lib.Interval.<..<=) 0 9
307 , (Lib.Interval.<=..<) 0 9
308 , (Lib.Interval.<..<) 0 9 )
309 , ( (Lib.Interval.<=..<=) 0 9
310 , (Lib.Interval.<=..<=) 0 9
311 , (Lib.Interval.<=..<=) 0 9 )
313 , "union" ~: TestList $
316 let i = fromJust mi in
317 let j = fromJust mj in
318 [ ((show . Lib.Interval.Pretty) i ++ " " ++ (show . Lib.Interval.Pretty) j) ~: Lib.Interval.union i j ~?= e
319 , ((show . Lib.Interval.Pretty) j ++ " " ++ (show . Lib.Interval.Pretty) i) ~: Lib.Interval.union j i ~?= e
322 [ ( (Lib.Interval.<..<) 0 (4::Integer)
323 , (Lib.Interval.<..<) 5 9
325 , ( (Lib.Interval.<..<=) 0 5
326 , (Lib.Interval.<..<) 5 9
327 , (Lib.Interval.<..<) 0 9 )
328 , ( (Lib.Interval.<..<) 0 5
329 , (Lib.Interval.<=..<) 5 9
330 , (Lib.Interval.<..<) 0 9 )
331 , ( (Lib.Interval.<..<=) 0 5
332 , (Lib.Interval.<=..<) 5 9
333 , (Lib.Interval.<..<) 0 9 )
334 , ( (Lib.Interval.<..<) 0 6
335 , (Lib.Interval.<..<) 4 9
336 , (Lib.Interval.<..<) 0 9 )
337 , ( (Lib.Interval.<..<) 0 9
338 , (Lib.Interval.<..<) 0 9
339 , (Lib.Interval.<..<) 0 9 )
340 , ( (Lib.Interval.<=..<) 0 9
341 , (Lib.Interval.<..<=) 0 9
342 , (Lib.Interval.<=..<=) 0 9 )
343 , ( (Lib.Interval.<..<=) 0 9
344 , (Lib.Interval.<=..<) 0 9
345 , (Lib.Interval.<=..<=) 0 9 )
346 , ( (Lib.Interval.<=..<=) 0 9
347 , (Lib.Interval.<=..<=) 0 9
348 , (Lib.Interval.<=..<=) 0 9 )
350 , "Sieve" ~: TestList $
351 [ "union" ~: TestList $
354 let is = map (fromJust) mis in
355 let e = map (fromJust) me in
357 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
358 Lib.Interval.Sieve.empty is in
360 (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton)
361 Lib.Interval.Sieve.empty is in
362 [ (List.intercalate " " $ map (show . Lib.Interval.Pretty) is) ~:
363 Lib.Interval.Sieve.intervals sil ~?= e
364 , (List.intercalate " " $ map (show . Lib.Interval.Pretty) $ reverse is) ~:
365 Lib.Interval.Sieve.intervals sir ~?= e
368 [ ( [ (Lib.Interval.<=..<) 0 (5::Integer)
369 , (Lib.Interval.<=..<=) 5 9
371 , [ (Lib.Interval.<=..<=) 0 9 ]
373 , ( [ (Lib.Interval.<=..<=) 0 5
374 , (Lib.Interval.<=..<=) 0 9
376 , [ (Lib.Interval.<=..<=) 0 9 ]
378 , ( [ (Lib.Interval.<=..<=) 0 4
379 , (Lib.Interval.<=..<=) 5 9
380 , (Lib.Interval.<=..<=) 3 6
382 , [ (Lib.Interval.<=..<=) 0 9 ]
384 , ( [ (Lib.Interval.<=..<=) 1 4
385 , (Lib.Interval.<=..<=) 5 8
387 , [ (Lib.Interval.<=..<=) 1 4
388 , (Lib.Interval.<=..<=) 5 8
391 , ( [ (Lib.Interval.<=..<=) 1 8
392 , (Lib.Interval.<=..<=) 0 9
394 , [ (Lib.Interval.<=..<=) 0 9 ]
396 , ( [ (Lib.Interval.<=..<=) 1 4
397 , (Lib.Interval.<=..<=) 5 8
398 , (Lib.Interval.<=..<=) 0 9
400 , [ (Lib.Interval.<=..<=) 0 9 ]
405 let is = map fromJust mis in
406 let js = map fromJust mjs in
407 let e = map fromJust me in
409 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
410 Lib.Interval.Sieve.empty is in
412 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
413 Lib.Interval.Sieve.empty js in
414 [ ((List.intercalate " " $ map (show . Lib.Interval.Pretty) is) ++ " u " ++
415 (List.intercalate " " $ map (show . Lib.Interval.Pretty) js)) ~:
416 Lib.Interval.Sieve.intervals (Lib.Interval.Sieve.union iu ju) ~?= e
417 , ((List.intercalate " " $ map (show . Lib.Interval.Pretty) $ js) ++ " u " ++
418 (List.intercalate " " $ map (show . Lib.Interval.Pretty) $ is)) ~:
419 Lib.Interval.Sieve.intervals (Lib.Interval.Sieve.union ju iu) ~?= e
422 [ ( [ (Lib.Interval.<=..<=) 0 (1::Integer)
423 , (Lib.Interval.<=..<=) 2 4
425 , [ (Lib.Interval.<=..<=) 0 3
427 , [ (Lib.Interval.<=..<=) 0 4
430 , ( [ (Lib.Interval.<=..<=) 0 1
431 , (Lib.Interval.<=..<=) 2 3
432 , (Lib.Interval.<=..<=) 4 5
433 , (Lib.Interval.<=..<=) 6 7
435 , [ (Lib.Interval.<=..<=) 1 2
436 , (Lib.Interval.<=..<=) 3 4
437 , (Lib.Interval.<=..<=) 5 6
439 , [ (Lib.Interval.<=..<=) 0 7
442 , ( [ (Lib.Interval.<=..<=) 0 1
443 , (Lib.Interval.<=..<=) 2 3
445 , [ (Lib.Interval.<=..<=) 4 5
447 , [ (Lib.Interval.<=..<=) 0 1
448 , (Lib.Interval.<=..<=) 2 3
449 , (Lib.Interval.<=..<=) 4 5
452 , ( [ (Lib.Interval.<=..<=) 0 1
453 , (Lib.Interval.<=..<=) 4 5
455 , [ (Lib.Interval.<=..<=) 2 3
457 , [ (Lib.Interval.<=..<=) 0 1
458 , (Lib.Interval.<=..<=) 2 3
459 , (Lib.Interval.<=..<=) 4 5
463 , "intersection" ~: TestList $
466 let is = map (fromJust) mis in
467 let js = map (fromJust) mjs in
468 let e = map (fromJust) me in
470 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
471 Lib.Interval.Sieve.empty is in
473 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
474 Lib.Interval.Sieve.empty js in
475 [ ((List.intercalate " " $ map (show . Lib.Interval.Pretty) is) ++ " n " ++
476 (List.intercalate " " $ map (show . Lib.Interval.Pretty) js)) ~:
477 Lib.Interval.Sieve.intervals (Lib.Interval.Sieve.intersection iu ju) ~?= e
478 , ((List.intercalate " " $ map (show . Lib.Interval.Pretty) $ js) ++ " n " ++
479 (List.intercalate " " $ map (show . Lib.Interval.Pretty) $ is)) ~:
480 Lib.Interval.Sieve.intervals (Lib.Interval.Sieve.intersection ju iu) ~?= e
483 [ ( [ (Lib.Interval.<=..<) 0 (5::Integer) ]
484 , [ (Lib.Interval.<=..<=) 5 9 ]
487 , ( [ (Lib.Interval.<=..<=) 0 5 ]
488 , [ (Lib.Interval.<=..<=) 5 9 ]
489 , [ (Lib.Interval.<=..<=) 5 5 ]
491 , ( [ (Lib.Interval.<=..<=) 0 5 ]
492 , [ (Lib.Interval.<=..<=) 0 9 ]
493 , [ (Lib.Interval.<=..<=) 0 5 ]
495 , ( [ (Lib.Interval.<=..<=) 0 4
496 , (Lib.Interval.<=..<=) 5 9
498 , [ (Lib.Interval.<=..<=) 3 6 ]
499 , [ (Lib.Interval.<=..<=) 3 4
500 , (Lib.Interval.<=..<=) 5 6
503 , ( [ (Lib.Interval.<=..<=) 1 4
504 , (Lib.Interval.<=..<=) 6 8
506 , [ (Lib.Interval.<=..<=) 2 3
507 , (Lib.Interval.<=..<=) 5 7
509 , [ (Lib.Interval.<=..<=) 2 3
510 , (Lib.Interval.<=..<=) 6 7
514 , "complement" ~: TestList $
517 let is = map fromJust mis in
518 let e = map fromJust me in
520 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
521 Lib.Interval.Sieve.empty is in
522 [ show (Lib.Interval.Pretty $
523 Lib.Interval.Sieve.fmap_interval
524 (Lib.Interval.fmap_unsafe $ Lib.Interval.Pretty) iu) ~:
525 Lib.Interval.Sieve.intervals (Lib.Interval.Sieve.complement iu) ~?= e
528 [ ( [ ((Lib.Interval.<=..<) `on` Lib.Interval.Limited) 0 (5::Integer)
529 , ((Lib.Interval.<=..<=) `on` Lib.Interval.Limited) 5 9
531 , [ Just $ (Lib.Interval...<) 0
532 , Just $ (Lib.Interval.<..) 9
535 , ( [ Just $ Lib.Interval.unlimited ]
539 , [ Just $ Lib.Interval.unlimited ]
541 , ( [ Just $ (Lib.Interval...<) 0
542 , Just $ (Lib.Interval.<..) 0
544 , [ Just $ Lib.Interval.point $ Lib.Interval.Limited 0
547 , ( [ ((Lib.Interval.<=..<) `on` Lib.Interval.Limited) 0 1
548 , ((Lib.Interval.<=..<) `on` Lib.Interval.Limited) 2 3
549 , ((Lib.Interval.<..<=) `on` Lib.Interval.Limited) 3 4
551 , [ Just $ (Lib.Interval...<) 0
552 , ((Lib.Interval.<=..<) `on` Lib.Interval.Limited) 1 2
553 , Just $ Lib.Interval.point $ Lib.Interval.Limited 3
554 , Just $ (Lib.Interval.<..) 4
558 , "complement_with" ~: TestList $
561 let ib = fromJust mib in
562 let is = map fromJust mis in
563 let e = map fromJust me in
565 (flip (Lib.Interval.Sieve.union . Lib.Interval.Sieve.singleton))
566 Lib.Interval.Sieve.empty is in
567 [ show (Lib.Interval.Pretty iu) ~:
568 Lib.Interval.Sieve.intervals (Lib.Interval.Sieve.complement_with ib iu) ~?= e
571 [ ( (Lib.Interval.<=..<=) (-10) (10::Integer)
572 , [ (Lib.Interval.<=..<) 0 5
573 , (Lib.Interval.<=..<=) 5 9
575 , [ (Lib.Interval.<=..<) (-10) 0
576 , (Lib.Interval.<..<=) 9 10
579 , ( (Lib.Interval.<=..<=) (-10) 10
580 , [ (Lib.Interval.<=..<=) (-10) 10 ]
583 , ( (Lib.Interval.<=..<=) (-10) 10
585 , [ (Lib.Interval.<=..<=) (-10) 10 ]
587 , ( (Lib.Interval.<=..<=) (-10) 10
588 , [ (Lib.Interval.<=..<) (-10) 0
589 , (Lib.Interval.<..<=) 0 10
591 , [ Just $ Lib.Interval.point 0
594 , ( (Lib.Interval.<=..<=) (-10) 10
595 , [ Just $ Lib.Interval.point 0
597 , [ (Lib.Interval.<=..<) (-10) 0
598 , (Lib.Interval.<..<=) 0 10
601 , ( (Lib.Interval.<=..<=) 0 10
602 , [ (Lib.Interval.<..<=) 0 10
604 , [ Just $ Lib.Interval.point 0
607 , ( (Lib.Interval.<=..<=) 0 10
608 , [ (Lib.Interval.<=..<) 0 10
610 , [ Just $ Lib.Interval.point 10
613 , ( Just $ Lib.Interval.point 0
616 , [ Just $ Lib.Interval.point 0
619 , ( Just $ Lib.Interval.point 0
620 , [ Just $ Lib.Interval.point 0
629 , "Account" ~: TestList
630 [ "foldr" ~: TestList
632 (reverse $ Account.foldr ("A":|[]) (:) []) ~?= ["A":|[]]
634 (reverse $ Account.foldr ("A":|["B"]) (:) []) ~?= ["A":|[], "A":|["B"]]
636 (reverse $ Account.foldr ("A":|["B", "C"]) (:) []) ~?= ["A":|[], "A":|["B"], "A":|["B", "C"]]
638 , "ascending" ~: TestList
640 Account.ascending ("A":|[]) ~?= Nothing
642 Account.ascending ("A":|["B"]) ~?= Just ("A":|[])
644 Account.ascending ("A":|["B", "C"]) ~?= Just ("A":|["B"])
647 , "Filter" ~: TestList
649 [ "Filter_Path" ~: TestList
652 (Filter.Filter_Path Filter.Eq
653 [ Filter.Filter_Path_Section_Text
654 (Filter.Filter_Text_Exact "A")
659 (Filter.Filter_Path Filter.Eq
660 [ Filter.Filter_Path_Section_Any
665 (Filter.Filter_Path Filter.Eq
666 [ Filter.Filter_Path_Section_Many
671 (Filter.Filter_Path Filter.Eq
672 [ Filter.Filter_Path_Section_Many
673 , Filter.Filter_Path_Section_Text
674 (Filter.Filter_Text_Exact "A")
679 (Filter.Filter_Path Filter.Eq
680 [ Filter.Filter_Path_Section_Text
681 (Filter.Filter_Text_Exact "A")
682 , Filter.Filter_Path_Section_Many
687 (Filter.Filter_Path Filter.Eq
688 [ Filter.Filter_Path_Section_Text
689 (Filter.Filter_Text_Exact "A")
690 , Filter.Filter_Path_Section_Many
692 ((("A"::Text):|"B":[]))
695 (Filter.Filter_Path Filter.Eq
696 [ Filter.Filter_Path_Section_Text
697 (Filter.Filter_Text_Exact "A")
698 , Filter.Filter_Path_Section_Text
699 (Filter.Filter_Text_Exact "B")
701 ((("A"::Text):|"B":[]))
704 (Filter.Filter_Path Filter.Eq
705 [ Filter.Filter_Path_Section_Text
706 (Filter.Filter_Text_Exact "A")
707 , Filter.Filter_Path_Section_Many
708 , Filter.Filter_Path_Section_Many
709 , Filter.Filter_Path_Section_Text
710 (Filter.Filter_Text_Exact "B")
712 ((("A"::Text):|"B":[]))
715 (Filter.Filter_Path Filter.Eq
716 [ Filter.Filter_Path_Section_Many
717 , Filter.Filter_Path_Section_Text
718 (Filter.Filter_Text_Exact "B")
719 , Filter.Filter_Path_Section_Many
721 ((("A"::Text):|"B":"C":[]))
724 (Filter.Filter_Path Filter.Eq
725 [ Filter.Filter_Path_Section_Many
726 , Filter.Filter_Path_Section_Text
727 (Filter.Filter_Text_Exact "C")
729 ((("A"::Text):|"B":"C":[]))
732 (Filter.Filter_Path Filter.Lt
733 [ Filter.Filter_Path_Section_Text
734 (Filter.Filter_Text_Exact "A")
735 , Filter.Filter_Path_Section_Text
736 (Filter.Filter_Text_Exact "B")
737 , Filter.Filter_Path_Section_Text
738 (Filter.Filter_Text_Exact "C")
739 , Filter.Filter_Path_Section_Many
740 , Filter.Filter_Path_Section_Text
741 (Filter.Filter_Text_Exact "D")
743 ((("A"::Text):|"B":[]))
744 , ">A:B:C::D A:B:C:CC:CCC:D:E" ~?
746 (Filter.Filter_Path Filter.Gt
747 [ Filter.Filter_Path_Section_Text
748 (Filter.Filter_Text_Exact "A")
749 , Filter.Filter_Path_Section_Text
750 (Filter.Filter_Text_Exact "B")
751 , Filter.Filter_Path_Section_Text
752 (Filter.Filter_Text_Exact "C")
753 , Filter.Filter_Path_Section_Many
754 , Filter.Filter_Path_Section_Text
755 (Filter.Filter_Text_Exact "D")
757 ((("A"::Text):|"B":"C":"CC":"CCC":"D":"E":[]))
759 , "Filter_Bool" ~: TestList
762 (Filter.Any::Filter.Filter_Bool (Filter.Filter_Account (Tag.Tags, NonEmpty Text)))
765 , "Filter_Ord" ~: TestList
768 (Filter.With_Interval $ Filter.Filter_Ord Filter.Gt (0::Integer))
769 (fromJust $ (Lib.Interval.<=..<=) 1 2)
772 (Filter.With_Interval $ Filter.Filter_Ord Filter.Lt (0::Integer))
773 (fromJust $ (Lib.Interval.<=..<=) (-2) (-1))
774 , "not (1 < (0, 2))" ~?
776 (Filter.With_Interval $ Filter.Filter_Ord Filter.Gt (1::Integer))
777 (fromJust $ (Lib.Interval.<=..<=) 0 2))
781 [ "filter_account" ~: TestList
783 (Data.Either.rights $
785 (Filter.Read.filter_account_path <* P.eof)
788 [ Filter.Filter_Path Filter.Eq
789 [ Filter.Filter_Path_Section_Any ]
792 (Data.Either.rights $
794 (Filter.Read.filter_account_path <* P.eof)
797 [ Filter.Filter_Path Filter.Eq
798 [ Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "A") ]
801 (Data.Either.rights $
803 (Filter.Read.filter_account_path <* P.eof)
806 [ Filter.Filter_Path Filter.Eq
807 [ Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "AA") ]
810 (Data.Either.rights $
812 (Filter.Read.filter_account_path <* P.eof)
813 () "" ("::A"::Text)])
815 [ Filter.Filter_Path Filter.Eq
816 [ Filter.Filter_Path_Section_Many
817 , Filter.Filter_Path_Section_Many
818 , Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "A")
822 (Data.Either.rights $
824 (Filter.Read.filter_account_path <* P.eof)
827 [ Filter.Filter_Path Filter.Eq
828 [ Filter.Filter_Path_Section_Many
829 , Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "A")
833 (Data.Either.rights $
835 (Filter.Read.filter_account_path <* P.eof)
838 [ Filter.Filter_Path Filter.Eq
839 [ Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "A")
840 , Filter.Filter_Path_Section_Many
844 (Data.Either.rights $
846 (Filter.Read.filter_account_path <* P.eof)
847 () "" ("A::"::Text)])
849 [ Filter.Filter_Path Filter.Eq
850 [ Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "A")
851 , Filter.Filter_Path_Section_Many
852 , Filter.Filter_Path_Section_Many
856 (Data.Either.rights $
858 (Filter.Read.filter_account_path <* P.eof)
859 () "" ("A:B"::Text)])
861 [ Filter.Filter_Path Filter.Eq
862 [ Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "A")
863 , Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "B")
867 (Data.Either.rights $
869 (Filter.Read.filter_account_path <* P.eof)
870 () "" ("A::B"::Text)])
872 [ Filter.Filter_Path Filter.Eq
873 [ Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "A")
874 , Filter.Filter_Path_Section_Many
875 , Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "B")
879 (Data.Either.rights $
881 (Filter.Read.filter_account_path <* P.eof)
882 () "" ("A:::B"::Text)])
884 [ Filter.Filter_Path Filter.Eq
885 [ Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "A")
886 , Filter.Filter_Path_Section_Many
887 , Filter.Filter_Path_Section_Many
888 , Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "B")
892 (Data.Either.rights $
894 (Filter.Read.filter_account_path <* P.char ' ' <* P.eof)
895 () "" ("A: "::Text)])
897 [ Filter.Filter_Path Filter.Eq
898 [ Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "A")
899 , Filter.Filter_Path_Section_Many
903 (Data.Either.rights $
905 (Filter.Read.filter_account_path <* P.eof)
906 () "" ("<=A:B"::Text)])
908 [ Filter.Filter_Path Filter.Le
909 [ Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "A")
910 , Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "B")
914 (Data.Either.rights $
916 (Filter.Read.filter_account_path <* P.eof)
917 () "" (">=A:B"::Text)])
919 [ Filter.Filter_Path Filter.Ge
920 [ Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "A")
921 , Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "B")
925 (Data.Either.rights $
927 (Filter.Read.filter_account_path <* P.eof)
928 () "" ("<A:B"::Text)])
930 [ Filter.Filter_Path Filter.Lt
931 [ Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "A")
932 , Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "B")
936 (Data.Either.rights $
938 (Filter.Read.filter_account_path <* P.eof)
939 () "" (">A:B"::Text)])
941 [ Filter.Filter_Path Filter.Gt
942 [ Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "A")
943 , Filter.Filter_Path_Section_Text (Filter.Filter_Text_Exact "B")
947 , "filter_bool" ~: TestList
949 (Data.Either.rights $
951 (Filter.Read.filter_bool
952 [ P.char 'E' >> return (return $ Filter.Bool True) ]
954 () "" ("( E )"::Text)])
956 [ Filter.And (Filter.Bool True) Filter.Any
959 (Data.Either.rights $
961 (Filter.Read.filter_bool
962 [ P.char 'E' >> return (return $ Filter.Bool True) ]
964 () "" ("( ( E ) )"::Text)])
966 [ Filter.And (Filter.And (Filter.Bool True) Filter.Any) Filter.Any
969 (Data.Either.rights $
971 (Filter.Read.filter_bool
972 [ P.char 'E' >> return (return $ Filter.Bool True) ]
974 () "" ("( E ) & ( E )"::Text)])
977 (Filter.And (Filter.Bool True) Filter.Any)
978 (Filter.And (Filter.Bool True) Filter.Any)
981 (Data.Either.rights $
983 (Filter.Read.filter_bool
984 [ P.char 'E' >> return (return $ Filter.Bool True) ]
986 () "" ("( E ) + ( E )"::Text)])
989 (Filter.And (Filter.Bool True) Filter.Any)
990 (Filter.And (Filter.Bool True) Filter.Any)
993 (Data.Either.rights $
995 (Filter.Read.filter_bool
996 [ P.char 'E' >> return (return $ Filter.Bool True) ]
998 () "" ("( E ) - ( E )"::Text)])
1001 (Filter.And (Filter.Bool True) Filter.Any)
1002 (Filter.Not (Filter.And (Filter.Bool True) Filter.Any))
1005 (Data.Either.rights $
1007 (Filter.Read.filter_bool
1008 [ P.char 'E' >> return (return $ Filter.Bool True) ]
1010 () "" ("(- E )"::Text)])
1012 [ Filter.And (Filter.Not (Filter.Bool True)) Filter.Any
1017 , "Balance" ~: TestList
1020 [ "[A+$1] = A+$1 & $+1" ~:
1023 , Map.map Polarize.polarize $ amounts [ amount_usd $ (1::Integer) ]
1028 { Balance.balance_by_account =
1029 TreeMap.from_List const $
1030 List.map (id *** Balance.Account_Sum . Map.map Polarize.polarize) $
1031 [ ("A":|[], amounts [ amount_usd $ 1 ]) ]
1032 , Balance.balance_by_unit =
1033 Balance.Balance_by_Unit $
1035 [ amount_usd $ Balance.Unit_Sum
1036 { Balance.unit_sum_quantity = Polarize.polarize $ 1
1037 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1043 , "[A+$1, A-$1] = {A+$0, $+0}" ~:
1044 (List.foldl (flip Balance.cons)
1046 [ ( (("A"::Text):|[])
1047 , Map.map Polarize.polarize $ amounts [ amount_usd $ (1::Integer) ]
1050 , Map.map Polarize.polarize $ amounts [ amount_usd $ -1 ]
1055 { Balance.balance_by_account =
1056 TreeMap.from_List const $
1058 , Balance.Account_Sum $
1059 Map.fromListWith const $
1060 [ amount_usd $ Polarize.Polarized_Both (-1) ( 1)
1063 , Balance.balance_by_unit =
1064 Balance.Balance_by_Unit $ Map.fromList $
1065 [ amount_usd $ Balance.Unit_Sum
1066 { Balance.unit_sum_quantity = Polarize.Polarized_Both (-1) ( 1)
1067 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1072 , "[A+$1, A-€1] = {A+$1-€1, $+1 €-1}" ~:
1073 (List.foldl (flip Balance.cons)
1075 [ ( (("A"::Text):|[])
1076 , Map.map Polarize.polarize $ amounts [ amount_usd $ (1::Integer) ]
1079 , Map.map Polarize.polarize $ amounts [ amount_eur $ -1 ]
1084 { Balance.balance_by_account =
1085 TreeMap.from_List const $
1086 List.map (id *** Balance.Account_Sum . Map.map Polarize.polarize) $
1087 [ ("A":|[], amounts [ amount_usd $ 1, amount_eur $ -1 ]) ]
1088 , Balance.balance_by_unit =
1089 Balance.Balance_by_Unit $ Map.fromList $
1090 [ amount_usd $ Balance.Unit_Sum
1091 { Balance.unit_sum_quantity = Polarize.Polarized_Positive 1
1092 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1095 , amount_eur $ Balance.Unit_Sum
1096 { Balance.unit_sum_quantity = Polarize.Polarized_Negative (-1)
1097 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1102 , "[A+$1, B-$1] = {A+$1 B-$1, $+0}" ~:
1103 (List.foldl (flip Balance.cons)
1105 [ ( (("A"::Text):|[])
1106 , Map.map Polarize.polarize $ amounts [ amount_usd $ (1::Integer) ]
1109 , Map.map Polarize.polarize $ amounts [ amount_usd $ -1 ]
1114 { Balance.balance_by_account =
1115 TreeMap.from_List const $
1116 List.map (id *** Balance.Account_Sum . Map.map Polarize.polarize) $
1117 [ ("A":|[], amounts [ amount_usd $ 1 ])
1118 , ("B":|[], amounts [ amount_usd $ -1 ])
1120 , Balance.balance_by_unit =
1121 Balance.Balance_by_Unit $ Map.fromList $
1122 [ amount_usd $ Balance.Unit_Sum
1123 { Balance.unit_sum_quantity = Polarize.Polarized_Both (-1) 1
1124 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1130 (List.foldl (flip Balance.cons)
1132 [ ( (("A"::Text):|[])
1133 , Map.map Polarize.polarize $ amounts [ amount_usd $ (1::Integer) ]
1136 , Map.map Polarize.polarize $ amounts [ amount_usd $ 1 ]
1141 { Balance.balance_by_account =
1142 TreeMap.from_List const $
1143 List.map (id *** Balance.Account_Sum . Map.map Polarize.polarize) $
1144 [ ("A":|[], amounts [ amount_usd $ 1 ])
1145 , ("B":|[], amounts [ amount_usd $ 1 ])
1147 , Balance.balance_by_unit =
1148 Balance.Balance_by_Unit $ Map.fromList $
1149 [ amount_usd $ Balance.Unit_Sum
1150 { Balance.unit_sum_quantity = Polarize.polarize 2
1151 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1156 , "[A+$1+€2, A-$1-€2] = {A+$0+€0, $+0 €+0}" ~:
1157 (List.foldl (flip Balance.cons)
1159 [ ( (("A"::Text):|[])
1160 , Map.map Polarize.polarize $ amounts [ amount_usd $ 1, amount_eur $ (2::Integer) ]
1163 , Map.map Polarize.polarize $ amounts [ amount_usd $ -1, amount_eur $ -2 ]
1168 { Balance.balance_by_account =
1169 TreeMap.from_List const $
1171 , Balance.Account_Sum $
1172 Map.fromListWith const $
1173 [ amount_usd $ Polarize.Polarized_Both (-1) 1
1174 , amount_eur $ Polarize.Polarized_Both (-2) 2
1178 , Balance.balance_by_unit =
1179 Balance.Balance_by_Unit $ Map.fromList $
1180 [ amount_usd $ Balance.Unit_Sum
1181 { Balance.unit_sum_quantity = Polarize.Polarized_Both (-1) 1
1182 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1185 , amount_eur $ Balance.Unit_Sum
1186 { Balance.unit_sum_quantity = Polarize.Polarized_Both (-2) 2
1187 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1192 , "[A+$1+€2+£3, B-$1-2€-£3] = {A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~:
1193 (List.foldl (flip Balance.cons)
1195 [ ( (("A"::Text):|[])
1196 , Map.map Polarize.polarize $ amounts [ amount_usd $ (1::Integer), amount_eur $ 2, amount_gbp $ 3 ]
1199 , Map.map Polarize.polarize $ amounts [ amount_usd $ -1, amount_eur $ -2, amount_gbp $ -3 ]
1204 { Balance.balance_by_account =
1205 TreeMap.from_List const $
1206 List.map (id *** Balance.Account_Sum . Map.map Polarize.polarize) $
1207 [ ("A":|[], amounts [ amount_usd $ 1, amount_eur $ 2, amount_gbp $ 3 ])
1208 , ("B":|[], amounts [ amount_usd $ -1, amount_eur $ -2, amount_gbp $ -3 ])
1210 , Balance.balance_by_unit =
1211 Balance.Balance_by_Unit $
1213 [ amount_usd $ Balance.Unit_Sum
1214 { Balance.unit_sum_quantity = Polarize.Polarized_Both (-1) 1
1215 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1218 , amount_eur $ Balance.Unit_Sum
1219 { Balance.unit_sum_quantity = Polarize.Polarized_Both (-2) 2
1220 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1223 , amount_gbp $ Balance.Unit_Sum
1224 { Balance.unit_sum_quantity = Polarize.Polarized_Both (-3) 3
1225 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1231 , "union" ~: TestList
1232 [ "{A+$1, $+1} {A+$1, $+1} = {A+$2, $+2}" ~:
1235 { Balance.balance_by_account =
1236 TreeMap.from_List const $
1238 , Balance.Account_Sum $
1239 Map.fromListWith const $
1240 [ amount_usd $ Polarize.polarize 1 ]
1243 , Balance.balance_by_unit =
1244 Balance.Balance_by_Unit $ Map.fromList $
1245 [ amount_usd $ Balance.Unit_Sum
1246 { Balance.unit_sum_quantity = Polarize.polarize 1
1247 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1251 }::Balance.Balance (NonEmpty Text) Text (Polarize.Polarized Integer))
1253 { Balance.balance_by_account =
1254 TreeMap.from_List const $
1256 , Balance.Account_Sum $
1257 Map.fromListWith const $
1258 [ amount_usd $ Polarize.polarize 1 ]
1261 , Balance.balance_by_unit =
1262 Balance.Balance_by_Unit $ Map.fromList $
1263 [ amount_usd $ Balance.Unit_Sum
1264 { Balance.unit_sum_quantity = Polarize.polarize 1
1265 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1272 { Balance.balance_by_account =
1273 TreeMap.from_List const $
1275 , Balance.Account_Sum $
1276 Map.fromListWith const $
1277 [ amount_usd $ Polarize.polarize 2 ]
1280 , Balance.balance_by_unit =
1281 Balance.Balance_by_Unit $ Map.fromList $
1282 [ amount_usd $ Balance.Unit_Sum
1283 { Balance.unit_sum_quantity = Polarize.polarize 2
1284 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1289 , "{A+$1, $+1} {B+$1, $+1} = {A+$1 B+$1, $+2}" ~:
1292 { Balance.balance_by_account =
1293 TreeMap.from_List const $
1295 , Balance.Account_Sum $
1296 Map.fromListWith const $
1297 [ amount_usd $ Polarize.polarize 1 ]
1300 , Balance.balance_by_unit =
1301 Balance.Balance_by_Unit $ Map.fromList $
1302 [ amount_usd $ Balance.Unit_Sum
1303 { Balance.unit_sum_quantity = Polarize.polarize 1
1304 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1308 }::Balance.Balance (NonEmpty Text) Text (Polarize.Polarized Integer))
1310 { Balance.balance_by_account =
1311 TreeMap.from_List const $
1313 , Balance.Account_Sum $
1314 Map.fromListWith const $
1315 [ amount_usd $ Polarize.polarize 1 ]
1318 , Balance.balance_by_unit =
1319 Balance.Balance_by_Unit $ Map.fromList $
1320 [ amount_usd $ Balance.Unit_Sum
1321 { Balance.unit_sum_quantity = Polarize.polarize 1
1322 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1329 { Balance.balance_by_account =
1330 TreeMap.from_List const $
1332 , Balance.Account_Sum $
1333 Map.fromListWith const $
1334 [ amount_usd $ Polarize.polarize 1 ]
1337 , Balance.Account_Sum $
1338 Map.fromListWith const $
1339 [ amount_usd $ Polarize.polarize 1 ]
1342 , Balance.balance_by_unit =
1343 Balance.Balance_by_Unit $ Map.fromList $
1344 [ amount_usd $ Balance.Unit_Sum
1345 { Balance.unit_sum_quantity = Polarize.polarize 2
1346 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1351 , "{A+$1, $+1} {B+€1, €+1} = {A+$1 B+€1, $+1 €+1}" ~:
1354 { Balance.balance_by_account =
1355 TreeMap.from_List const $
1357 , Balance.Account_Sum $
1358 Map.fromListWith const $
1359 [ amount_usd $ Polarize.polarize 1 ]
1362 , Balance.balance_by_unit =
1363 Balance.Balance_by_Unit $ Map.fromList $
1364 [ amount_usd $ Balance.Unit_Sum
1365 { Balance.unit_sum_quantity = Polarize.polarize 1
1366 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1370 }::Balance.Balance (NonEmpty Text) Text (Polarize.Polarized Integer))
1372 { Balance.balance_by_account =
1373 TreeMap.from_List const $
1375 , Balance.Account_Sum $
1376 Map.fromListWith const $
1377 [ amount_eur $ Polarize.polarize 1 ]
1380 , Balance.balance_by_unit =
1381 Balance.Balance_by_Unit $ Map.fromList $
1382 [ amount_eur $ Balance.Unit_Sum
1383 { Balance.unit_sum_quantity = Polarize.polarize 1
1384 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1391 { Balance.balance_by_account =
1392 TreeMap.from_List const $
1394 , Balance.Account_Sum $
1395 Map.fromListWith const $
1396 [ amount_usd $ Polarize.polarize 1 ]
1399 , Balance.Account_Sum $
1400 Map.fromListWith const $
1401 [ amount_eur $ Polarize.polarize 1 ]
1404 , Balance.balance_by_unit =
1405 Balance.Balance_by_Unit $ Map.fromList $
1406 [ amount_usd $ Balance.Unit_Sum
1407 { Balance.unit_sum_quantity = Polarize.polarize 1
1408 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1411 , amount_eur $ Balance.Unit_Sum
1412 { Balance.unit_sum_quantity = Polarize.polarize 1
1413 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1419 , "expanded" ~: TestList
1421 Balance.expanded TreeMap.empty
1423 (TreeMap.empty::Balance.Expanded (NonEmpty Text) Text Integer)
1426 (TreeMap.from_List const $
1428 , Balance.Account_Sum $
1429 Map.fromListWith const $
1430 [ amount_usd $ Polarize.polarize 1 ]
1432 ]::Balance.Balance_by_Account Text Text (Polarize.Polarized Integer))
1434 (TreeMap.from_List const $
1435 [ ("A":|[], Balance.Account_Sum_Expanded
1436 { Balance.inclusive =
1437 Balance.Account_Sum $
1438 Map.map Polarize.polarize $
1439 amounts [ amount_usd $ 1 ]
1440 , Balance.exclusive =
1441 Balance.Account_Sum $
1442 Map.map Polarize.polarize $
1443 amounts [ amount_usd $ 1 ]
1446 , "A/A+$1 = A+$1 A/A+$1" ~:
1448 (TreeMap.from_List const $
1450 , Balance.Account_Sum $
1451 Map.fromListWith const $
1452 [ amount_usd $ Polarize.polarize 1 ]
1454 ]::Balance.Balance_by_Account Text Text (Polarize.Polarized Integer))
1456 (TreeMap.from_List const
1457 [ ("A":|[], Balance.Account_Sum_Expanded
1458 { Balance.inclusive =
1459 Balance.Account_Sum $
1460 Map.map Polarize.polarize $
1461 amounts [ amount_usd $ 1 ]
1462 , Balance.exclusive =
1463 Balance.Account_Sum $
1464 Map.map Polarize.polarize $
1467 , ("A":|["A"], Balance.Account_Sum_Expanded
1468 { Balance.inclusive =
1469 Balance.Account_Sum $
1470 Map.map Polarize.polarize $
1471 amounts [ amount_usd $ 1 ]
1472 , Balance.exclusive =
1473 Balance.Account_Sum $
1474 Map.map Polarize.polarize $
1475 amounts [ amount_usd $ 1 ]
1478 , "A/B+$1 = A+$1 A/B+$1" ~:
1480 (TreeMap.from_List const $
1482 , Balance.Account_Sum $
1483 Map.fromListWith const $
1484 [ amount_usd $ Polarize.polarize 1 ]
1486 ]::Balance.Balance_by_Account Text Text (Polarize.Polarized Integer))
1488 (TreeMap.from_List const
1489 [ ("A":|[], Balance.Account_Sum_Expanded
1490 { Balance.inclusive =
1491 Balance.Account_Sum $
1492 Map.map Polarize.polarize $
1493 amounts [ amount_usd $ 1 ]
1494 , Balance.exclusive =
1495 Balance.Account_Sum $
1496 Map.map Polarize.polarize $
1499 , ("A":|["B"], Balance.Account_Sum_Expanded
1500 { Balance.inclusive =
1501 Balance.Account_Sum $
1502 Map.map Polarize.polarize $
1503 amounts [ amount_usd $ 1 ]
1504 , Balance.exclusive =
1505 Balance.Account_Sum $
1506 Map.map Polarize.polarize $
1507 amounts [ amount_usd $ 1 ]
1510 , "A/B/C+$1 = A+$1 A/B+$1 A/B/C+$1" ~:
1512 (TreeMap.from_List const $
1513 [ ( ("A":|["B", "C"])
1514 , Balance.Account_Sum $
1515 Map.fromListWith const $
1516 [ amount_usd $ Polarize.polarize 1 ]
1518 ]::Balance.Balance_by_Account Text Text (Polarize.Polarized Integer))
1520 (TreeMap.from_List const $
1521 [ ("A":|[], Balance.Account_Sum_Expanded
1522 { Balance.inclusive =
1523 Balance.Account_Sum $
1524 Map.map Polarize.polarize $
1525 amounts [ amount_usd $ 1 ]
1526 , Balance.exclusive =
1527 Balance.Account_Sum $
1528 Map.map Polarize.polarize $
1531 , ("A":|["B"], Balance.Account_Sum_Expanded
1532 { Balance.inclusive =
1533 Balance.Account_Sum $
1534 Map.map Polarize.polarize $
1535 amounts [ amount_usd $ 1 ]
1536 , Balance.exclusive =
1537 Balance.Account_Sum $
1538 Map.map Polarize.polarize $
1541 , ("A":|["B", "C"], Balance.Account_Sum_Expanded
1542 { Balance.inclusive =
1543 Balance.Account_Sum $
1544 Map.map Polarize.polarize $
1545 amounts [ amount_usd $ 1 ]
1546 , Balance.exclusive =
1547 Balance.Account_Sum $
1548 Map.map Polarize.polarize $
1549 amounts [ amount_usd $ 1 ]
1552 , "A+$1 A/B+$1 = A+$2 A/B+$1" ~:
1554 (TreeMap.from_List const $
1556 , Balance.Account_Sum $
1557 Map.fromListWith const $
1558 [ amount_usd $ Polarize.polarize 1 ]
1561 , Balance.Account_Sum $
1562 Map.fromListWith const $
1563 [ amount_usd $ Polarize.polarize 1 ]
1565 ]::Balance.Balance_by_Account Text Text (Polarize.Polarized Integer))
1567 (TreeMap.from_List const
1568 [ ("A":|[], Balance.Account_Sum_Expanded
1569 { Balance.inclusive =
1570 Balance.Account_Sum $
1571 Map.map Polarize.polarize $
1572 amounts [ amount_usd $ 2 ]
1573 , Balance.exclusive =
1574 Balance.Account_Sum $
1575 Map.map Polarize.polarize $
1576 amounts [ amount_usd $ 1 ]
1578 , ("A":|["B"], Balance.Account_Sum_Expanded
1579 { Balance.inclusive =
1580 Balance.Account_Sum $
1581 Map.map Polarize.polarize $
1582 amounts [ amount_usd $ 1 ]
1583 , Balance.exclusive =
1584 Balance.Account_Sum $
1585 Map.map Polarize.polarize $
1586 amounts [ amount_usd $ 1 ]
1589 , "A+$1 A/B+$1 A/B/C+$1 = A+$3 A/B+$2 A/B/C+$1" ~:
1591 (TreeMap.from_List const $
1593 , Balance.Account_Sum $
1594 Map.fromListWith const $
1595 [ amount_usd $ Polarize.polarize 1 ]
1598 , Balance.Account_Sum $
1599 Map.fromListWith const $
1600 [ amount_usd $ Polarize.polarize 1 ]
1602 , ( ("A":|["B", "C"])
1603 , Balance.Account_Sum $
1604 Map.fromListWith const $
1605 [ amount_usd $ Polarize.polarize 1 ]
1607 ]::Balance.Balance_by_Account Text Text (Polarize.Polarized Integer))
1609 (TreeMap.from_List const
1610 [ ("A":|[], Balance.Account_Sum_Expanded
1611 { Balance.inclusive =
1612 Balance.Account_Sum $
1613 Map.map Polarize.polarize $
1614 amounts [ amount_usd $ 3 ]
1615 , Balance.exclusive =
1616 Balance.Account_Sum $
1617 Map.map Polarize.polarize $
1618 amounts [ amount_usd $ 1 ]
1620 , ("A":|["B"], Balance.Account_Sum_Expanded
1621 { Balance.inclusive =
1622 Balance.Account_Sum $
1623 Map.map Polarize.polarize $
1624 amounts [ amount_usd $ 2 ]
1625 , Balance.exclusive =
1626 Balance.Account_Sum $
1627 Map.map Polarize.polarize $
1628 amounts [ amount_usd $ 1 ]
1630 , ("A":|["B", "C"], Balance.Account_Sum_Expanded
1631 { Balance.inclusive =
1632 Balance.Account_Sum $
1633 Map.map Polarize.polarize $
1634 amounts [ amount_usd $ 1 ]
1635 , Balance.exclusive =
1636 Balance.Account_Sum $
1637 Map.map Polarize.polarize $
1638 amounts [ amount_usd $ 1 ]
1641 , "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" ~:
1643 (TreeMap.from_List const $
1645 , Balance.Account_Sum $
1646 Map.fromListWith const $
1647 [ amount_usd $ Polarize.polarize 1 ]
1650 , Balance.Account_Sum $
1651 Map.fromListWith const $
1652 [ amount_usd $ Polarize.polarize 1 ]
1654 , ( ("A":|["B", "C"])
1655 , Balance.Account_Sum $
1656 Map.fromListWith const $
1657 [ amount_usd $ Polarize.polarize 1 ]
1659 , ( ("A":|["B", "C", "D"])
1660 , Balance.Account_Sum $
1661 Map.fromListWith const $
1662 [ amount_usd $ Polarize.polarize 1 ]
1664 ]::Balance.Balance_by_Account Text Text (Polarize.Polarized Integer))
1666 (TreeMap.from_List const
1667 [ ("A":|[], Balance.Account_Sum_Expanded
1668 { Balance.inclusive =
1669 Balance.Account_Sum $
1670 Map.map Polarize.polarize $
1671 amounts [ amount_usd $ 4 ]
1672 , Balance.exclusive =
1673 Balance.Account_Sum $
1674 Map.map Polarize.polarize $
1675 amounts [ amount_usd $ 1 ]
1677 , ("A":|["B"], Balance.Account_Sum_Expanded
1678 { Balance.inclusive =
1679 Balance.Account_Sum $
1680 Map.map Polarize.polarize $
1681 amounts [ amount_usd $ 3 ]
1682 , Balance.exclusive =
1683 Balance.Account_Sum $
1684 Map.map Polarize.polarize $
1685 amounts [ amount_usd $ 1 ]
1687 , ("A":|["B", "C"], Balance.Account_Sum_Expanded
1688 { Balance.inclusive =
1689 Balance.Account_Sum $
1690 Map.map Polarize.polarize $
1691 amounts [ amount_usd $ 2 ]
1692 , Balance.exclusive =
1693 Balance.Account_Sum $
1694 Map.map Polarize.polarize $
1695 amounts [ amount_usd $ 1 ]
1697 , ("A":|["B", "C", "D"], Balance.Account_Sum_Expanded
1698 { Balance.inclusive =
1699 Balance.Account_Sum $
1700 Map.map Polarize.polarize $
1701 amounts [ amount_usd $ 1 ]
1702 , Balance.exclusive =
1703 Balance.Account_Sum $
1704 Map.map Polarize.polarize $
1705 amounts [ amount_usd $ 1 ]
1708 , "A+$1 A/B+$1 A/BB+$1 AA/B+$1 = A+$3 A/B+$1 A/BB+$1 AA+$1 AA/B+$1" ~:
1710 (TreeMap.from_List const $
1712 , Balance.Account_Sum $
1713 Map.fromListWith const $
1714 [ amount_usd $ Polarize.polarize 1 ]
1717 , Balance.Account_Sum $
1718 Map.fromListWith const $
1719 [ amount_usd $ Polarize.polarize 1 ]
1722 , Balance.Account_Sum $
1723 Map.fromListWith const $
1724 [ amount_usd $ Polarize.polarize 1 ]
1727 , Balance.Account_Sum $
1728 Map.fromListWith const $
1729 [ amount_usd $ Polarize.polarize 1 ]
1731 ]::Balance.Balance_by_Account Text Text (Polarize.Polarized Integer))
1733 (TreeMap.from_List const
1734 [ ("A":|[], Balance.Account_Sum_Expanded
1735 { Balance.inclusive =
1736 Balance.Account_Sum $
1737 Map.map Polarize.polarize $
1738 amounts [ amount_usd $ 3 ]
1739 , Balance.exclusive =
1740 Balance.Account_Sum $
1741 Map.map Polarize.polarize $
1742 amounts [ amount_usd $ 1 ]
1744 , ("A":|["B"], Balance.Account_Sum_Expanded
1745 { Balance.inclusive =
1746 Balance.Account_Sum $
1747 Map.map Polarize.polarize $
1748 amounts [ amount_usd $ 1 ]
1749 , Balance.exclusive =
1750 Balance.Account_Sum $
1751 Map.map Polarize.polarize $
1752 amounts [ amount_usd $ 1 ]
1754 , ("A":|["BB"], Balance.Account_Sum_Expanded
1755 { Balance.inclusive =
1756 Balance.Account_Sum $
1757 Map.map Polarize.polarize $
1758 amounts [ amount_usd $ 1 ]
1759 , Balance.exclusive =
1760 Balance.Account_Sum $
1761 Map.map Polarize.polarize $
1762 amounts [ amount_usd $ 1 ]
1764 , ("AA":|[], Balance.Account_Sum_Expanded
1765 { Balance.inclusive =
1766 Balance.Account_Sum $
1767 Map.map Polarize.polarize $
1768 amounts [ amount_usd $ 1 ]
1769 , Balance.exclusive =
1770 Balance.Account_Sum $
1771 Map.map Polarize.polarize $
1774 , ("AA":|["B"], Balance.Account_Sum_Expanded
1775 { Balance.inclusive =
1776 Balance.Account_Sum $
1777 Map.map Polarize.polarize $
1778 amounts [ amount_usd $ 1 ]
1779 , Balance.exclusive =
1780 Balance.Account_Sum $
1781 Map.map Polarize.polarize $
1782 amounts [ amount_usd $ 1 ]
1786 , "deviation" ~: TestList
1788 (Balance.deviation $
1790 { Balance.balance_by_account =
1791 TreeMap.from_List const $
1793 , Balance.Account_Sum $
1794 Map.fromListWith const $
1795 [ amount_usd $ Polarize.polarize 1 ]
1798 , Balance.Account_Sum $
1799 Map.fromListWith const $
1803 , Balance.balance_by_unit =
1804 Balance.Balance_by_Unit $ Map.fromList $
1805 [ amount_usd $ Balance.Unit_Sum
1806 { Balance.unit_sum_quantity = Polarize.polarize 1
1807 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1811 }::Balance.Deviation (NonEmpty Text) Text (Polarize.Polarized Integer))
1813 (Balance.Deviation $
1814 Balance.Balance_by_Unit $ Map.fromList $
1815 [ amount_usd $ Balance.Unit_Sum
1816 { Balance.unit_sum_quantity = Polarize.polarize 1
1817 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1821 , "{A+$1 B+$1, $2}" ~:
1822 (Balance.deviation $
1824 { Balance.balance_by_account =
1825 TreeMap.from_List const $
1827 , Balance.Account_Sum $
1828 Map.fromListWith const $
1829 [ amount_usd $ Polarize.polarize 1 ]
1832 , Balance.Account_Sum $
1833 Map.fromListWith const $
1834 [ amount_usd $ Polarize.polarize 1 ]
1837 , Balance.balance_by_unit =
1838 Balance.Balance_by_Unit $ Map.fromList $
1839 [ amount_usd $ Balance.Unit_Sum
1840 { Balance.unit_sum_quantity = Polarize.polarize 2
1841 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1847 }::Balance.Deviation (NonEmpty Text) Text (Polarize.Polarized Integer))
1849 (Balance.Deviation $
1850 Balance.Balance_by_Unit $ Map.fromList $
1851 [ amount_usd $ Balance.Unit_Sum
1852 { Balance.unit_sum_quantity = Polarize.polarize 2
1853 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1859 , "is_equilibrium_inferrable" ~: TestList
1860 [ "empty" ~: TestCase $
1862 Balance.is_equilibrium_inferrable $
1864 (Balance.empty::Balance.Balance (NonEmpty Text) Text Integer)
1865 , "{A+$0, $+0}" ~: TestCase $
1867 Balance.is_equilibrium_inferrable $
1870 { Balance.balance_by_account =
1871 TreeMap.from_List const $
1873 , Balance.Account_Sum $
1874 Map.fromListWith const $
1875 [ amount_usd $ Polarize.polarize 0 ]
1878 , Balance.balance_by_unit =
1879 Balance.Balance_by_Unit $ Map.fromList $
1880 [ amount_usd $ Balance.Unit_Sum
1881 { Balance.unit_sum_quantity = Polarize.polarize 0
1882 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1886 }::Balance.Balance (NonEmpty Text) Text (Polarize.Polarized Integer))
1887 , "{A+$1, $+1}" ~: TestCase $
1889 Balance.is_equilibrium_inferrable $
1892 { Balance.balance_by_account =
1893 TreeMap.from_List const $
1895 , Balance.Account_Sum $
1896 Map.fromListWith const $
1897 [ amount_usd $ Polarize.polarize 1 ]
1900 , Balance.balance_by_unit =
1901 Balance.Balance_by_Unit $ Map.fromList $
1902 [ amount_usd $ Balance.Unit_Sum
1903 { Balance.unit_sum_quantity = Polarize.polarize 1
1904 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1908 }::Balance.Balance (NonEmpty Text) Text (Polarize.Polarized Integer))
1909 , "{A+$0+€0, $0 €+0}" ~: TestCase $
1911 Balance.is_equilibrium_inferrable $
1914 { Balance.balance_by_account =
1915 TreeMap.from_List const $
1917 , Balance.Account_Sum $
1918 Map.fromListWith const $
1919 [ amount_usd $ Polarize.polarize 0
1920 , amount_eur $ Polarize.polarize 0
1924 , Balance.balance_by_unit =
1925 Balance.Balance_by_Unit $ Map.fromList $
1926 [ amount_usd $ Balance.Unit_Sum
1927 { Balance.unit_sum_quantity = Polarize.polarize 0
1928 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1931 , amount_eur $ Balance.Unit_Sum
1932 { Balance.unit_sum_quantity = Polarize.polarize 0
1933 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1937 }::Balance.Balance (NonEmpty Text) Text (Polarize.Polarized Integer))
1938 , "{A+$1, B-$1, $+0}" ~: TestCase $
1940 Balance.is_equilibrium_inferrable $
1943 { Balance.balance_by_account =
1944 TreeMap.from_List const $
1946 , Balance.Account_Sum $
1947 Map.fromListWith const $
1948 [ amount_usd $ Polarize.polarize 1 ]
1951 , Balance.Account_Sum $
1952 Map.fromListWith const $
1953 [ amount_usd $ Polarize.polarize (-1) ]
1956 , Balance.balance_by_unit =
1957 Balance.Balance_by_Unit $ Map.fromList $
1958 [ amount_usd $ Balance.Unit_Sum
1959 { Balance.unit_sum_quantity = Polarize.polarize 0
1960 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1964 }::Balance.Balance (NonEmpty Text) Text (Polarize.Polarized Integer))
1965 , "{A+$1 B, $+1}" ~: TestCase $
1967 Balance.is_equilibrium_inferrable $
1970 { Balance.balance_by_account =
1971 TreeMap.from_List const $
1973 , Balance.Account_Sum $
1974 Map.fromListWith const $
1975 [ amount_usd $ Polarize.polarize 1 ]
1978 , Balance.Account_Sum $
1979 Map.fromListWith const $
1983 , Balance.balance_by_unit =
1984 Balance.Balance_by_Unit $ Map.fromList $
1985 [ amount_usd $ Balance.Unit_Sum
1986 { Balance.unit_sum_quantity = Polarize.polarize 1
1987 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
1991 }::Balance.Balance (NonEmpty Text) Text (Polarize.Polarized Integer))
1992 , "{A+$1 B+€1, $+1 €+1}" ~: TestCase $
1994 Balance.is_equilibrium_inferrable $
1997 { Balance.balance_by_account =
1998 TreeMap.from_List const $
2000 , Balance.Account_Sum $
2001 Map.fromListWith const $
2002 [ amount_usd $ Polarize.polarize 1 ]
2005 , Balance.Account_Sum $
2006 Map.fromListWith const $
2007 [ amount_eur $ Polarize.polarize 1 ]
2010 , Balance.balance_by_unit =
2011 Balance.Balance_by_Unit $ Map.fromList $
2012 [ amount_usd $ Balance.Unit_Sum
2013 { Balance.unit_sum_quantity = Polarize.polarize 1
2014 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
2017 , amount_eur $ Balance.Unit_Sum
2018 { Balance.unit_sum_quantity = Polarize.polarize 1
2019 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
2023 }::Balance.Balance (NonEmpty Text) Text (Polarize.Polarized Integer))
2024 , "{A+$1 B-$1+€1, $+0 €+1}" ~: TestCase $
2026 Balance.is_equilibrium_inferrable $
2029 { Balance.balance_by_account =
2030 TreeMap.from_List const $
2032 , Balance.Account_Sum $
2033 Map.fromListWith const $
2034 [ amount_usd $ Polarize.polarize 1 ]
2037 , Balance.Account_Sum $
2038 Map.fromListWith const $
2039 [ amount_usd $ Polarize.polarize (-1)
2040 , amount_eur $ Polarize.polarize 1
2044 , Balance.balance_by_unit =
2045 Balance.Balance_by_Unit $ Map.fromList $
2046 [ amount_usd $ Balance.Unit_Sum
2047 { Balance.unit_sum_quantity = Polarize.polarize 0
2048 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
2051 , amount_eur $ Balance.Unit_Sum
2052 { Balance.unit_sum_quantity = Polarize.polarize 1
2053 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
2057 }::Balance.Balance (NonEmpty Text) Text (Polarize.Polarized Integer))
2058 , "{A+$1+€2+£3 B-$1-€2-£3, $+0 €+0 £+0}" ~: TestCase $
2060 Balance.is_equilibrium_inferrable $
2063 { Balance.balance_by_account =
2064 TreeMap.from_List const $
2066 , Balance.Account_Sum $
2067 Map.fromListWith const $
2068 [ amount_usd $ Polarize.polarize 1
2069 , amount_eur $ Polarize.polarize 2
2070 , amount_gbp $ Polarize.polarize 3
2074 , Balance.Account_Sum $
2075 Map.fromListWith const $
2076 [ amount_usd $ Polarize.polarize (-1)
2077 , amount_eur $ Polarize.polarize (-2)
2078 , amount_gbp $ Polarize.polarize (-3)
2082 , Balance.balance_by_unit =
2083 Balance.Balance_by_Unit $ Map.fromList $
2084 [ amount_usd $ Balance.Unit_Sum
2085 { Balance.unit_sum_quantity = Polarize.polarize 0
2086 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
2089 , amount_eur $ Balance.Unit_Sum
2090 { Balance.unit_sum_quantity = Polarize.polarize 0
2091 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
2094 , amount_gbp $ Balance.Unit_Sum
2095 { Balance.unit_sum_quantity = Polarize.polarize 0
2096 , Balance.unit_sum_accounts = Map.fromList $ List.map (,())
2100 }::Balance.Balance (NonEmpty Text) Text (Polarize.Polarized Integer))
2102 , "infer_equilibrium" ~: TestList
2104 (snd $ Balance.infer_equilibrium $
2106 List.map (\(acct, amts) -> (acct, [(acct, amts)])) $
2108 , amounts [ amount_usd $ (1::Integer) ] )
2115 List.map (\(acct, amts) -> (acct, [(acct, amts)])) $
2117 , amounts [ amount_usd $ 1 ] )
2119 , amounts [ amount_usd $ -1 ] )
2122 (snd $ Balance.infer_equilibrium $
2124 List.map (\(acct, amts) -> (acct, [(acct, amts)])) $
2126 , amounts [ amount_usd $ (1::Integer) ] )
2128 , amounts [ amount_eur $ -1 ] )
2133 List.map (\(acct, amts) -> (acct, [(acct, amts)])) $
2135 , amounts [ amount_usd $ 1, amount_eur $ (1::Integer)] )
2137 , amounts [ amount_eur $ -1, amount_usd $ -1 ] )
2140 (snd $ Balance.infer_equilibrium $
2142 List.map (\(acct, amts) -> (acct, [(acct, amts)])) $
2144 , amounts [ amount_usd $ (1::Integer) ] )
2146 , amounts [ amount_usd $ 1 ] )
2150 [ amount_usd $ Balance.Unit_Sum
2151 { Balance.unit_sum_quantity = 2
2152 , Balance.unit_sum_accounts = Map.fromList []}
2154 , "{A+$1 B-$1 B-1€}" ~:
2155 (snd $ Balance.infer_equilibrium $
2157 List.map (\(acct, amts) -> (acct, [(acct, amts)])) $
2159 , amounts [ amount_usd $ (1::Integer) ] )
2161 , amounts [ amount_usd $ -1, amount_eur $ -1 ] )
2166 List.map (\(acct, amts) -> (acct, [(acct, amts)])) $
2168 , amounts [ amount_usd $ 1, amount_eur $ 1 ] )
2170 , amounts [ amount_usd $ -1, amount_eur $ -1 ] )