class MoneyTrackerMenu:
    def __init__(self, name):
        print(f'Hello, {name}!')
        self.option = 0
        self.parser = Parser("money_tracker.txt")
        self.parser.make_rows()
        self.agg = AggregatedMoneyTraker(self.parser)
        self.agg.generate_categories_from_parser()
        self.mt = MoneyTracker(self.agg)

    def start(self):

        while True:
            self.option = int(input("""Choose one of the following options to continue:
1 - show all data
2 - show data for specific date
3 - show expenses, ordered by categories
4 - add new income
5 - add new expense
6 - exit
"""))
            if type(self.option) is not int:
                raise TypeError
            if self.option < 1 or self.option > 6:
                raise ValueError

            if self.option == 1:
                print(self.mt.show_user_data())
            elif self.option == 2:
                date = input("Enter date: ")
                print(self.mt.show_user_data_for_specific_date(date))
            elif self.option == 3:
                print(self.mt.show_user_expenses_ordered_by_categories())
            elif self.option == 4:
                amount = float(input("New income amount: "))
                name = input("New income type: ")
                date = input("New income date: ")
                self.mt.add_income(amount, name, date)
            elif self.option == 5:
                amount = float(input("New expense amount: "))
                name = input("New expense type: ")
                date = input("New expense date: ")
                self.mt.add_expense(amount, name, date)
            if self.option == 6:
                self.mt.save()
                exit()
class MoneyTrakerTests(unittest.TestCase):
    def setUp(self):
        self.par = Parser("money_tracker.txt")
        self.par.make_rows()
        self.agg = AggregatedMoneyTraker(self.par)
        self.agg.generate_categories_from_parser()
        self.mt = MoneyTracker(self.agg)

    def test_init_money_tracker(self):
        with self.assertRaises(TypeError):
            MoneyTracker(self.par)

    def test_show_user_data(self):
        expected = "\n".join(['=== 22-03-2018 ===', '760, Salary, New Income',
                              '5.5, Eating Out, New Expense',
                              '34, Clothes, New Expense',
                              '41.79, Food, New Expense',
                              '12, Eating Out, New Expense',
                              '7, House, New Expense', '14, Pets, New Expense',
                              '112.4, Bills, New Expense',
                              '21.5, Transport, New Expense',
                              '=== 23-03-2018 ===', '50, Savings, New Income',
                              '15, Food, New Expense',
                              '200, Deposit, New Income',
                              '5, Sports, New Expense'])
        actual = self.mt.show_user_data()
        self.assertEqual(actual, expected)

    def test_show_user_data_for_specific_date(self):
        date = '22-03-2018'
        expected = "\n".join(['760, Salary, New Income',
                              '5.5, Eating Out, New Expense',
                              '34, Clothes, New Expense',
                              '41.79, Food, New Expense',
                              '12, Eating Out, New Expense',
                              '7, House, New Expense', '14, Pets, New Expense',
                              '112.4, Bills, New Expense',
                              '21.5, Transport, New Expense'])
        actual = self.mt.show_user_data_for_specific_date(date)
        self.assertEqual(actual, expected)

    def test_show_user_expenses_ordered_by_categories(self):
        expected = "\n".join(['112.4, Bills, New Expense',
                              '34, Clothes, New Expense',
                              '5.5, Eating Out, New Expense',
                              '12, Eating Out, New Expense',
                              '41.79, Food, New Expense',
                              '15, Food, New Expense',
                              '7, House, New Expense',
                              '14, Pets, New Expense',
                              '5, Sports, New Expense',
                              '21.5, Transport, New Expense'])
        actual = self.mt.show_user_expenses_ordered_by_categories()
        self.assertEqual(actual, expected)

    def test_list_incomes(self):
        expected = "\n".join(['760, Salary, New Income',
                              '50, Savings, New Income',
                              '200, Deposit, New Income'])
        actual = self.mt.list_incomes()
        self.assertEqual(actual, expected)

    def test_list_expenses(self):
        expected = "\n".join(['5.5, Eating Out, New Expense',
                              '34, Clothes, New Expense',
                              '41.79, Food, New Expense',
                              '12, Eating Out, New Expense',
                              '7, House, New Expense',
                              '14, Pets, New Expense',
                              '112.4, Bills, New Expense',
                              '21.5, Transport, New Expense',
                              '15, Food, New Expense',
                              '5, Sports, New Expense'])
        actual = self.mt.list_expenses()
        self.assertEqual(actual, expected)

    def test_add_income(self):
        expected = ['=== 22-03-2018 ===',
                    '350, Savings, New Income',
                    '760, Salary, New Income',
                    '5.5, Eating Out, New Expense',
                    '34, Clothes, New Expense',
                    '41.79, Food, New Expense',
                    '12, Eating Out, New Expense',
                    '7, House, New Expense',
                    '14, Pets, New Expense',
                    '112.4, Bills, New Expense',
                    '21.5, Transport, New Expense',
                    '=== 23-03-2018 ===',
                    '50, Savings, New Income',
                    '15, Food, New Expense',
                    '200, Deposit, New Income',
                    '5, Sports, New Expense']
        amount = 350
        name = "Savings"
        date = '22-03-2018'
        self.mt.add_income(amount, name, date)
        actual = self.mt.aggregated.data
        self.assertEqual(actual, expected)

    def test_add_expense(self):
        expected = ['=== 22-03-2018 ===',
                    '760, Salary, New Income',
                    '5.5, Eating Out, New Expense',
                    '34, Clothes, New Expense',
                    '41.79, Food, New Expense',
                    '12, Eating Out, New Expense',
                    '7, House, New Expense',
                    '14, Pets, New Expense',
                    '112.4, Bills, New Expense',
                    '21.5, Transport, New Expense',
                    '=== 23-03-2018 ===',
                    '50, Food, New Expense',
                    '50, Savings, New Income',
                    '15, Food, New Expense',
                    '200, Deposit, New Income',
                    '5, Sports, New Expense']
        amount = 50
        name = "Food"
        date = '23-03-2018'
        self.mt.add_expense(amount, name, date)
        actual = self.mt.aggregated.data
        self.assertEqual(actual, expected)