bttests.py
changeset 0 811cd790a493
equal deleted inserted replaced
-1:000000000000 0:811cd790a493
       
     1 from budgettracker import Budget, Transaction, Decimal
       
     2 
       
     3 class Expect:
       
     4     def __init__(self, *cmds, verbose = False):
       
     5         self._cmds = cmds
       
     6         self._index = 0
       
     7         self.verbose = verbose
       
     8     def __call__(self, prompt):
       
     9         assert(self._index < len(self._cmds))
       
    10         idx = self._index
       
    11         self._index += 1
       
    12         if self.verbose:
       
    13             print("{:<20} => {}".format(prompt, self._cmds[idx]))
       
    14         return self._cmds[idx]
       
    15 
       
    16 class Test:
       
    17     def run(self):
       
    18         self.test_load_save()
       
    19         self.test_report(True)
       
    20         self.test_envelops()
       
    21         self.test_read_transaction()
       
    22 
       
    23     def test_read_transaction(self, verbose = False):
       
    24         cmds = [ "Salary", "400",
       
    25                  "Taxes", "100",
       
    26                  "Taxes", "-100",
       
    27                  "Grocery", "200" ]
       
    28         b = self.create_budget()
       
    29         t = b.read_transaction(Expect(verbose = verbose, *(cmds + ["", "n"])))
       
    30         assert(t is None)
       
    31         t = b.read_transaction(Expect(verbose = verbose, *(cmds + ["", "y"])))
       
    32         assert(t.amount == 400)
       
    33         assert(t.budget["Taxes"] == 100)
       
    34         assert(t.budget["Grocery"] == 200)
       
    35         assert(len(t.budget) == 2)
       
    36         assert(t.expenses["Taxes"] == 100)
       
    37         assert(len(t.expenses) == 1)
       
    38         assert(t.balance == 200)
       
    39         t = b.read_transaction(Expect(verbose = verbose, *(cmds + ["Hobbies", "", "y"])))
       
    40         assert(t.amount == 400)
       
    41         assert(t.budget["Taxes"] == 100)
       
    42         assert(t.budget["Grocery"] == 200)
       
    43         assert(t.budget["Hobbies"] == 200)
       
    44         assert(len(t.budget) == 3)
       
    45         assert(t.expenses["Taxes"] == 100)
       
    46         assert(len(t.expenses) == 1)
       
    47         assert(t.balance == 0)
       
    48 
       
    49     def create_budget(self):
       
    50         b = Budget()
       
    51         salary = Decimal(500)
       
    52         taxes = salary * Decimal('0.20')
       
    53         # Salary: 500 - 100 in taxes = 400
       
    54         # Budget: 200$ in Grocery, 100$ for Taxes
       
    55         # Expenses: Taxes 100$
       
    56         # Unassigned: 200$
       
    57         t = Transaction(name="Salary", amount=salary-taxes,
       
    58                         budget = [("Grocery", Decimal(200)),
       
    59                                   ("Taxes", taxes)],
       
    60                         expenses = [("Taxes", taxes)])
       
    61         b.add_transaction(t)
       
    62         # Gift: 100$
       
    63         # Budget: 100$ in Hobbies
       
    64         t = Transaction(name = "Gift", amount = Decimal(100), envelop = "Hobbies")
       
    65         b.add_transaction(t)
       
    66         # Costco: -75$
       
    67         # Expenses: 75$ in Grocery
       
    68         t = Transaction(name="Costco", amount=Decimal(-75))
       
    69         t.rebalance("Grocery")
       
    70         b.add_transaction(t)
       
    71         # Cinema: -50
       
    72         # Expenses: 50$ in Hobbies
       
    73         t = Transaction(name="Cinema", amount=Decimal(-50), envelop="Hobbies")
       
    74         assert(t.balance == 0)
       
    75         b.add_transaction(t)
       
    76         # Missing money: -20$
       
    77         # Unassigned: -20$
       
    78         t = Transaction(name="Missing", amount=Decimal(-20))
       
    79         b.add_transaction(t)
       
    80         # Total:
       
    81         # Budget: 200$ Grocery, 100$ Taxes, 100$ Hobbies = 400$
       
    82         # Expenses: 100$ Taxes, 75$ Grocery, 50$ Hobbies = 225$
       
    83         # Unassigned: 200$ Salary, -20$ Missing = 180$ 
       
    84 
       
    85         b.set_envelop_description("Grocery", "stuff for stomach")
       
    86         b.rename_envelop("Grocery", "Food")
       
    87         return b
       
    88 
       
    89     def test_load_save(self, verbose = False):
       
    90         b = self.create_budget()
       
    91 
       
    92         from io import StringIO
       
    93         fp = StringIO()
       
    94         b.save(fp)
       
    95         saved = fp.getvalue()
       
    96         if verbose: print(saved)
       
    97 
       
    98         b2 = Budget()
       
    99         b2.load(StringIO(saved))
       
   100         fp = StringIO()
       
   101         b2.save(fp)
       
   102         saved2 = fp.getvalue()
       
   103         if verbose: print(saved2)
       
   104         assert(saved == saved2)
       
   105 
       
   106     def test_envelops(self, verbose = False):
       
   107         b = self.create_budget()
       
   108         envelops = list(b.envelops)
       
   109         assert(len(envelops) == 5)
       
   110         total = envelops[-2]
       
   111         unassigned = envelops[-1]
       
   112 
       
   113         assert(total.budget == 400)
       
   114         assert(total.expenses == 225)
       
   115         assert(total.balance == 175)
       
   116         assert(unassigned.budget == 200)
       
   117         assert(unassigned.expenses == 20)
       
   118         assert(unassigned.balance == 180)
       
   119 
       
   120     def test_report(self, verbose = False):
       
   121         b = self.create_budget()
       
   122         for l in b.report():
       
   123             if verbose:
       
   124                 print(l)
       
   125 
       
   126 if __name__ == '__main__':
       
   127     Test().run()