def loadTransactions(self, file=None):
     self.ts = TransactionStore()
     if file is not None:
         self.ts.loadTransactions(file)
     self.transactionManagement.ts = self.ts
     self.cashFlowDisplay.ts = self.ts
     self.updateChildren()
    def test_file_operations(self):
        self.assertEqual(len(self.ts.store), 2)

        t1 = next((t for t in self.ts.store if t.amount == 1.00),
                  None)
        self.assertIsNotNone(t1)

        t2 = next((t for t in self.ts.store if t.amount == 1.02),
                  None)
        self.assertIsNotNone(t2)

        self.ts.saveTransactions(self.file)

        ts = TransactionStore()
        ts.loadTransactions(self.file)

        self.assertEqual(len(ts.store), 2)

        t1_l = next((t for t in ts.store if t.amount == 1.00),
                    None)
        self.assertIsNotNone(t1_l)
        self.assertTransactionsEqual(t1_l, t1)

        t2_l = next((t for t in ts.store if t.amount == 1.02),
                    None)
        self.assertIsNotNone(t2_l)
        self.assertTransactionsEqual(t2_l, t2)
    def setUp(self):
        self.ts = TransactionStore()

        origsd1 = date.today()
        origsd2 = date.today()+timedelta(days=2)
        self.t1 = Transaction(
            start=origsd1,
            description="Once, today",
            amount=1.00,
            frequency=Transaction.ONCE)
        self.t2 = Transaction(
            start=origsd2,
            description="Once, in two days",
            amount=1.01,
            frequency=Transaction.ONCE)
        self.t3 = Transaction(
            start=origsd1,
            description="Weekly",
            amount=1.02,
            frequency=Transaction.WEEKLY,
            skip=set([date.today()+timedelta(days=7)]),
            scheduled=True,
            cleared=True)
        self.t4 = Transaction(
            start=origsd2,
            description="Monthly",
            amount=1.03,
            frequency=Transaction.MONTHLY)

        self.ts.addTransactions(self.t1, self.t2, self.t3, self.t4)
    def setUp(self):
        self.ts = TransactionStore()

        t1 = Transaction(
            start=date.today(),
            description="Once",
            amount=1.00,
            frequency=Transaction.ONCE)

        self.ts.addTransactions(t1)
    def test_add_multiple_transactions(self):
        d = date.today()
        ts = TransactionStore()
        t1 = Transaction(
            start=d,
            description="Once, today",
            amount=1.00,
            frequency=Transaction.ONCE)
        t2 = Transaction(
            start=d+timedelta(days=2),
            description="Once, in two days",
            amount=1.01,
            frequency=Transaction.ONCE)
        t3 = Transaction(
            start=d,
            end=d+timedelta(days=56),
            description="Weekly",
            amount=1.02,
            frequency=Transaction.WEEKLY,
            skip=set([d+timedelta(days=7)]),
            scheduled=True,
            cleared=True)

        self.assertEqual(len(ts.store), 0)

        ts.addTransactions(t1, t2, t3)

        t = next((t for t in ts.store if t.amount == 1.00),
                 None)
        self.assertIsNotNone(t)
        self.assertEqual(t.start, d)
        self.assertEqual(t.description, "Once, today")
        self.assertEqual(t.amount, 1.00)
        self.assertEqual(t.frequency, Transaction.ONCE)

        t = next((t for t in ts.store if t.amount == 1.01),
                 None)
        self.assertIsNotNone(t)
        self.assertEqual(t.start, d+timedelta(days=2))
        self.assertEqual(t.description, "Once, in two days")
        self.assertEqual(t.amount, 1.01)
        self.assertEqual(t.frequency, Transaction.ONCE)

        t = next((t for t in ts.store if t.amount == 1.02),
                 None)
        self.assertIsNotNone(t)
        self.assertEqual(t.start, d)
        self.assertEqual(t.description, "Weekly")
        self.assertEqual(t.amount, 1.02)
        self.assertEqual(t.frequency, Transaction.WEEKLY)
    def setUp(self):
        self.ts = TransactionStore()

        t1 = Transaction(
            start=date.today(),
            description="Once, today",
            amount=1.00,
            frequency=Transaction.ONCE)
        t2 = Transaction(
            start=date.today()+timedelta(days=2),
            description="Once, in two days",
            amount=1.01,
            frequency=Transaction.ONCE)

        self.ts.addTransactions(t1, t2)
class TestRetrieveFromMultipleRecurringTransactions(unittest.TestCase):
    def setUp(self):
        self.ts = TransactionStore()

        sd = date.today()
        skipd = date.today() + timedelta(days=14)
        t1 = Transaction(
            start=sd,
            description="Weekly",
            amount=1.00,
            frequency=Transaction.WEEKLY,
            skip=set([skipd]))
        t2 = Transaction(
            start=sd+timedelta(days=2),
            description="Monthly",
            amount=1.01,
            frequency=Transaction.MONTHLY)

        self.ts.addTransactions(t1, t2)

    def test_retrieve_non_existent_transaction(self):
        t_list = self.ts.getTransaction("Transaction does not exist")
        self.assertEqual(len(t_list), 0)

    def test_retrieve_no_date_given(self):
        t_list = self.ts.getTransaction("Weekly")
        self.assertEqual(len(t_list), 1)
        self.assertEqual(t_list[0].description, "Weekly")

    def test_retrieve_good_start_date_given(self):
        retrieve_date = date.today()
        t_list = self.ts.getTransaction("Weekly",
                                        requested_date=retrieve_date)
        self.assertEqual(len(t_list), 1)
        self.assertEqual(t_list[0].description, "Weekly")
        self.assertEqual(t_list[0].amount, 1.00)

    def test_retrieve_good_future_date_given(self):
        retrieve_date = date.today() + timedelta(days=21)
        t_list = self.ts.getTransaction("Weekly",
                                        requested_date=retrieve_date)
        self.assertEqual(len(t_list), 1)
        self.assertEqual(t_list[0].description, "Weekly")
        self.assertEqual(t_list[0].amount, 1.00)

    def test_retrieve_skip_date_given(self):
        retrieve_date = date.today() + timedelta(days=14)
        t_list = self.ts.getTransaction("Weekly",
                                        requested_date=retrieve_date)
        self.assertEqual(len(t_list), 0)

    def test_retrieve_bad_date_given(self):
        retrieve_date = date.today() + timedelta(days=3)
        t_list = self.ts.getTransaction("Weekly",
                                        requested_date=retrieve_date)
        self.assertEqual(len(t_list), 0)
    def setUp(self):
        self.ts = TransactionStore()

        sd = date.today()
        skipd = date.today() + timedelta(days=14)
        t1 = Transaction(
            start=sd,
            description="Weekly",
            amount=1.00,
            frequency=Transaction.WEEKLY,
            skip=set([skipd]))
        t2 = Transaction(
            start=sd+timedelta(days=2),
            description="Monthly",
            amount=1.01,
            frequency=Transaction.MONTHLY)

        self.ts.addTransactions(t1, t2)
 def test_add_single_transaction(self):
     d = date.today()
     ts = TransactionStore()
     self.assertEqual(len(ts.store), 0)
     t = Transaction(
         start=d,
         description="Once, today",
         amount=1.00,
         frequency=Transaction.ONCE)
     ts.addTransactions(t)
     self.assertEqual(len(ts.store), 1)
     t = next((t for t in ts.store if t.amount == 1.00),
              None)
     self.assertIsNotNone(t)
     self.assertEqual(t.start, d)
     self.assertEqual(t.description, "Once, today")
     self.assertEqual(t.amount, 1.00)
     self.assertEqual(t.frequency, Transaction.ONCE)
 def __init__(self):
     super().__init__(parent=None, title='Cash Flow Calculator')
     self.settingsFile = os.getcwd() + '/data/' + '.cash_flow_settings.yml'
     self.settings = AppSettings()
     self.ts = TransactionStore()
     self.defaultDir = os.getcwd() + '/data'
     self.notebook = wx.Notebook(self)
     self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
                        self.handleNotebookChange)
     self.transactionManagement = TransactionManagement(
         self.notebook, self.ts, self.settings)
     self.notebook.AddPage(self.transactionManagement,
                           "Transaction Management")
     self.cashFlowDisplay = CashFlowDisplay(self.notebook, self.ts,
                                            self.settings)
     self.notebook.AddPage(self.cashFlowDisplay, "Cash Flow")
     self.SetInitialSize(wx.Size(650, 650))
     self.create_menu()
     self.loadSettings()
     self.loadTransactions(self.settings.dataFile)
     self.Show()
    def setUp(self):
        self.file = f'./test-{time.time()}'

        t1 = Transaction(
            start=date.today(),
            description="Once, today",
            amount=1.00,
            frequency=Transaction.ONCE)
        t2 = Transaction(
            start=date.today(),
            original_start=date.today()-timedelta(days=1),
            end=date.today()+timedelta(days=56),
            description="Weekly",
            amount=1.02,
            frequency=Transaction.WEEKLY,
            skip=set([date.today()+timedelta(days=7)]),
            scheduled=True,
            cleared=True)

        self.ts = TransactionStore()
        self.ts.store.append(t1)
        self.ts.store.append(t2)
    def setUp(self):
        self.ts = TransactionStore()

        t1 = Transaction(
            start=date.today(),
            description="Once",
            amount=1.00,
            frequency=Transaction.ONCE)
        t2 = Transaction(
            start=date.today()+timedelta(days=2),
            description="Once, in two days",
            amount=1.01,
            frequency=Transaction.ONCE)
        t3 = Transaction(
            start=date.today(),
            end=date.today()+timedelta(days=56),
            description="Weekly",
            amount=1.02,
            frequency=Transaction.WEEKLY,
            skip=set([date.today()+timedelta(days=7)]),
            scheduled=True,
            cleared=True)

        self.ts.addTransactions(t1, t2, t3)
 def test_contructor_string_balance(self):
     sd = date.today()
     sb = '100.00'
     ts = TransactionStore()
     cf = CashFlow(sd, sb, ts)
     self.assertIsInstance(cf.start_date, date)
     self.assertEqual(cf.start_date, sd)
     self.assertIsInstance(cf.start_balance, Money)
     self.assertEqual(cf.start_balance, Money(sb))
     self.assertIsInstance(cf.transaction_store, TransactionStore)
     self.assertEqual(len(cf.transaction_store.getTransactions()), 0)
     self.assertIsInstance(cf.current_date, date)
     self.assertEqual(cf.current_date, sd)
     self.assertIsInstance(cf.current_balance, Money)
     self.assertEqual(cf.current_balance, Money(sb))
class TestRetrieveFromMultipleDuplicateSingleTransactions(unittest.TestCase):
    def setUp(self):
        self.ts = TransactionStore()

        t1 = Transaction(
            start=date.today(),
            description="Once, today",
            amount=1.00,
            frequency=Transaction.ONCE)

        t2 = Transaction(
            start=date.today()+timedelta(days=4),
            description="Once, today",
            amount=1.02,
            frequency=Transaction.ONCE)

        self.ts.addTransactions(t1, t2)

    def test_retrieve_no_date_given(self):
        t_list = self.ts.getTransaction("Once, today")
        self.assertEqual(len(t_list), 2)
        self.assertEqual(t_list[0].description, "Once, today")
        self.assertEqual(t_list[0].description, "Once, today")

    def test_retrieve_good_date_given(self):
        retrieve_date = date.today()
        t_list = self.ts.getTransaction("Once, today",
                                        requested_date=retrieve_date)
        self.assertEqual(len(t_list), 1)
        self.assertEqual(t_list[0].description, "Once, today")
        self.assertEqual(t_list[0].amount, 1.00)

        retrieve_date = date.today()+timedelta(days=4)
        t_list = self.ts.getTransaction("Once, today",
                                        requested_date=retrieve_date)
        self.assertEqual(len(t_list), 1)
        self.assertEqual(t_list[0].description, "Once, today")
        self.assertEqual(t_list[0].amount, 1.02)

    def test_retrieve_bad_date_given(self):
        retrieve_date = date.today() + timedelta(days=3)
        t_list = self.ts.getTransaction("Once, today",
                                        requested_date=retrieve_date)
        self.assertEqual(len(t_list), 0)
class TestBasicUpdate(unittest.TestCase):
    def setUp(self):
        self.ts = TransactionStore()

        t1 = Transaction(
            start=date.today(),
            description="Once",
            amount=1.00,
            frequency=Transaction.ONCE)

        self.ts.addTransactions(t1)

    def test_replace(self):
        ts = self.ts.getTransaction("Once")
        self.assertEqual(len(ts), 1)
        t1 = ts[0]
        t2 = t1.duplicate()
        t2.description = "Once replaced"
        self.ts.replaceTransaction(t1, t2)
        t_old = self.ts.getTransaction("Once")
        self.assertEqual(len(t_old), 0)
        t_new = self.ts.getTransaction("Once replaced")
        self.assertEqual(len(t_new), 1)
class MainFrame(wx.Frame):
    WILDCARD = "YAML (*.yml)|*.yml|"     \
               "All files (*.*)|*.*"

    def __init__(self):
        super().__init__(parent=None, title='Cash Flow Calculator')
        self.settingsFile = os.getcwd() + '/data/' + '.cash_flow_settings.yml'
        self.settings = AppSettings()
        self.ts = TransactionStore()
        self.defaultDir = os.getcwd() + '/data'
        self.notebook = wx.Notebook(self)
        self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
                           self.handleNotebookChange)
        self.transactionManagement = TransactionManagement(
            self.notebook, self.ts, self.settings)
        self.notebook.AddPage(self.transactionManagement,
                              "Transaction Management")
        self.cashFlowDisplay = CashFlowDisplay(self.notebook, self.ts,
                                               self.settings)
        self.notebook.AddPage(self.cashFlowDisplay, "Cash Flow")
        self.SetInitialSize(wx.Size(650, 650))
        self.create_menu()
        self.loadSettings()
        self.loadTransactions(self.settings.dataFile)
        self.Show()

    def handleNotebookChange(self, event):
        self.updateChildren()
        event.Skip()

    def updateChildren(self):
        self.transactionManagement.loadSettings()
        self.transactionManagement.redraw()
        self.cashFlowDisplay.loadSettings()
        self.cashFlowDisplay.updateList()

    def create_menu(self):
        menu_bar = wx.MenuBar()
        file_menu = wx.Menu()
        new_file_menu_item = file_menu.Append(wx.ID_ANY, "New File",
                                              "Create a new file")
        open_file_menu_item = file_menu.Append(wx.ID_ANY, "Open...",
                                               "Open a file")
        save_menu_item = file_menu.Append(wx.ID_ANY, "Save",
                                          "Save to current file")
        save_as_menu_item = file_menu.Append(wx.ID_ANY, "Save As",
                                             "Save file with new name")
        menu_bar.Append(file_menu, "&File")
        self.Bind(
            event=wx.EVT_MENU,
            handler=self.on_new_file,
            source=new_file_menu_item,
        )
        self.Bind(
            event=wx.EVT_MENU,
            handler=self.on_open_file,
            source=open_file_menu_item,
        )
        self.Bind(
            event=wx.EVT_MENU,
            handler=self.on_save,
            source=save_menu_item,
        )
        self.Bind(
            event=wx.EVT_MENU,
            handler=self.on_save_as,
            source=save_as_menu_item,
        )
        self.SetMenuBar(menu_bar)

    def on_new_file(self, event):
        self.loadSettings()
        self.settings.dataFile = None
        self.saveSettings()
        self.loadTransactions()

    def on_open_file(self, event):
        dlg = wx.FileDialog(self,
                            message="Choose a file",
                            defaultDir=self.defaultDir,
                            defaultFile="",
                            wildcard=MainFrame.WILDCARD,
                            style=wx.FD_OPEN | wx.FD_CHANGE_DIR
                            | wx.FD_FILE_MUST_EXIST | wx.FD_PREVIEW)
        if dlg.ShowModal() == wx.ID_OK:
            self.loadSettings()
            self.settings.dataFile = dlg.GetPath()
            self.loadTransactions(self.settings.dataFile)
            self.saveSettings()
        dlg.Destroy()

    def on_save(self, event):
        if self.settings.dataFile is not None:
            self.saveTransactions()
            self.saveSettings()
        else:
            self.on_save_as(event)

    def on_save_as(self, event):
        if self.settings.dataFile is not None:
            defaultDir = os.path.dirname(self.settings.dataFile)
            defaultFile = os.path.basename(self.settings.dataFile)
        else:
            defaultDir = self.defaultDir
            defaultFile = ""
        dlg = wx.FileDialog(self,
                            message="Save file as ...",
                            defaultDir=defaultDir,
                            defaultFile=defaultFile,
                            wildcard=MainFrame.WILDCARD,
                            style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        if dlg.ShowModal() == wx.ID_OK:
            self.settings.dataFile = dlg.GetPath()
            self.saveTransactions(self.settings.dataFile)
            self.saveSettings()
        dlg.Destroy()

    def loadTransactions(self, file=None):
        self.ts = TransactionStore()
        if file is not None:
            self.ts.loadTransactions(file)
        self.transactionManagement.ts = self.ts
        self.cashFlowDisplay.ts = self.ts
        self.updateChildren()

    def saveTransactions(self, file=None):
        if file is None:
            file = self.settings.dataFile
        self.settings.dataFile = file
        self.ts.saveTransactions(file)

    def saveSettings(self):
        try:
            with open(self.settingsFile, "w") as f:
                yaml.dump(self.settings, f)
        except:
            print("Can't save settings for some reason.")

    def loadSettings(self):
        try:
            with open(self.settingsFile, "r") as f:
                self.settings = yaml.load(f, Loader=yaml.Loader)
            self.transactionManagement.settings = self.settings
            self.cashFlowDisplay.settings = self.settings
            self.updateChildren()
        except:
            print("Can't load settings file. Using defaults.")
 def setUp(self):
     sd = date.today()
     sd2 = date.today()+timedelta(days=2)
     self.o1 = Transaction(
         start=sd,
         description="Once 1",
         amount=1.00,
         frequency=Transaction.ONCE)
     self.o2 = Transaction(
         start=sd2,
         description="Once 2",
         amount=1.01,
         frequency=Transaction.ONCE)
     self.w1 = Transaction(
         start=sd,
         description="Weekly 1",
         amount=1.03,
         frequency=Transaction.WEEKLY)
     self.w2 = Transaction(
         start=sd2,
         description="Weekly 2",
         amount=1.04,
         frequency=Transaction.WEEKLY)
     self.bw1 = Transaction(
         start=sd,
         description="BiWeekly 1",
         amount=1.05,
         frequency=Transaction.BIWEEKLY)
     self.bw2 = Transaction(
         start=sd2,
         description="BiWeekly 2",
         amount=1.06,
         frequency=Transaction.BIWEEKLY)
     self.m1 = Transaction(
         start=sd,
         description="Monthly 1",
         amount=1.07,
         frequency=Transaction.MONTHLY)
     self.m2 = Transaction(
         start=sd2,
         description="Monthly 2",
         amount=1.08,
         frequency=Transaction.MONTHLY)
     self.q1 = Transaction(
         start=sd,
         description="Quarterly 1",
         amount=1.09,
         frequency=Transaction.QUARTERLY)
     self.q2 = Transaction(
         start=sd2,
         description="Quarterly 2",
         amount=1.10,
         frequency=Transaction.QUARTERLY)
     self.a1 = Transaction(
         start=sd,
         description="Annually 1",
         amount=1.11,
         frequency=Transaction.ANNUALLY)
     self.a2 = Transaction(
         start=sd2,
         description="Annually 2",
         amount=1.12,
         frequency=Transaction.ANNUALLY)
     self.ts = TransactionStore()
     self.ts.addTransactions(self.o1, self.o2, self.w1, self.w2,
                             self.bw1, self.bw2, self.m1, self.m2,
                             self.q1, self.q2, self.a1, self.a2)
     random.shuffle(self.ts.store)
class TestTransactionListRetrieval(unittest.TestCase):
    def setUp(self):
        sd = date.today()
        sd2 = date.today()+timedelta(days=2)
        self.o1 = Transaction(
            start=sd,
            description="Once 1",
            amount=1.00,
            frequency=Transaction.ONCE)
        self.o2 = Transaction(
            start=sd2,
            description="Once 2",
            amount=1.01,
            frequency=Transaction.ONCE)
        self.w1 = Transaction(
            start=sd,
            description="Weekly 1",
            amount=1.03,
            frequency=Transaction.WEEKLY)
        self.w2 = Transaction(
            start=sd2,
            description="Weekly 2",
            amount=1.04,
            frequency=Transaction.WEEKLY)
        self.bw1 = Transaction(
            start=sd,
            description="BiWeekly 1",
            amount=1.05,
            frequency=Transaction.BIWEEKLY)
        self.bw2 = Transaction(
            start=sd2,
            description="BiWeekly 2",
            amount=1.06,
            frequency=Transaction.BIWEEKLY)
        self.m1 = Transaction(
            start=sd,
            description="Monthly 1",
            amount=1.07,
            frequency=Transaction.MONTHLY)
        self.m2 = Transaction(
            start=sd2,
            description="Monthly 2",
            amount=1.08,
            frequency=Transaction.MONTHLY)
        self.q1 = Transaction(
            start=sd,
            description="Quarterly 1",
            amount=1.09,
            frequency=Transaction.QUARTERLY)
        self.q2 = Transaction(
            start=sd2,
            description="Quarterly 2",
            amount=1.10,
            frequency=Transaction.QUARTERLY)
        self.a1 = Transaction(
            start=sd,
            description="Annually 1",
            amount=1.11,
            frequency=Transaction.ANNUALLY)
        self.a2 = Transaction(
            start=sd2,
            description="Annually 2",
            amount=1.12,
            frequency=Transaction.ANNUALLY)
        self.ts = TransactionStore()
        self.ts.addTransactions(self.o1, self.o2, self.w1, self.w2,
                                self.bw1, self.bw2, self.m1, self.m2,
                                self.q1, self.q2, self.a1, self.a2)
        random.shuffle(self.ts.store)

    def _transaction_list_test(self, transactions, expected_transactions):
        self.assertEqual(len(transactions), len(expected_transactions))
        for t in expected_transactions:
            self.assertTrue(t in transactions)

    def test_get_all_transations(self):
        transactions = self.ts.getTransactions()
        self._transaction_list_test(transactions, self.ts.store)

    def test_get_one_time_transactions(self):
        transactions = self.ts.getTransactions(frequency=Transaction.ONCE)
        self._transaction_list_test(transactions, [self.o1, self.o2])

    def test_get_weekly_transactions(self):
        transactions = self.ts.getTransactions(frequency=Transaction.WEEKLY)
        self._transaction_list_test(transactions, [self.w1, self.w2])

    def test_get_biweekly_transactions(self):
        transactions = self.ts.getTransactions(frequency=Transaction.BIWEEKLY)
        self._transaction_list_test(transactions, [self.bw1, self.bw2])

    def test_get_monthly_transactions(self):
        transactions = self.ts.getTransactions(frequency=Transaction.MONTHLY)
        self._transaction_list_test(transactions, [self.m1, self.m2])

    def test_get_quarterly_transactions(self):
        transactions = self.ts.getTransactions(frequency=Transaction.QUARTERLY)
        self._transaction_list_test(transactions, [self.q1, self.q2])

    def test_get_annual_transactions(self):
        transactions = self.ts.getTransactions(frequency=Transaction.ANNUALLY)
        self._transaction_list_test(transactions, [self.a1, self.a2])
class TestUtilityFunctions(unittest.TestCase):
    def setUp(self):
        self.ts = TransactionStore()

        origsd1 = date.today()
        origsd2 = date.today()+timedelta(days=2)
        self.t1 = Transaction(
            start=origsd1,
            description="Once, today",
            amount=1.00,
            frequency=Transaction.ONCE)
        self.t2 = Transaction(
            start=origsd2,
            description="Once, in two days",
            amount=1.01,
            frequency=Transaction.ONCE)
        self.t3 = Transaction(
            start=origsd1,
            description="Weekly",
            amount=1.02,
            frequency=Transaction.WEEKLY,
            skip=set([date.today()+timedelta(days=7)]),
            scheduled=True,
            cleared=True)
        self.t4 = Transaction(
            start=origsd2,
            description="Monthly",
            amount=1.03,
            frequency=Transaction.MONTHLY)

        self.ts.addTransactions(self.t1, self.t2, self.t3, self.t4)

    def test_update_all_recurring_start_dates(self):
        origsd1 = date.today()
        origsd2 = date.today()+timedelta(days=2)
        new_sd = date.today() + timedelta(days=10)
        new_weekly_sd = origsd1 + timedelta(days=14)
        new_monthly_sd = origsd2 + relativedelta(months=1)

        self.ts.updateRecurringStartDates(new_sd)

        self.assertEqual(self.t1.start, origsd1)
        self.assertEqual(self.t1.original_start, origsd1)
        self.assertEqual(self.t2.start, origsd2)
        self.assertEqual(self.t2.original_start, origsd2)
        self.assertEqual(self.t3.start, new_weekly_sd)
        self.assertEqual(self.t3.original_start, origsd1)
        self.assertEqual(self.t4.start, new_monthly_sd)
        self.assertEqual(self.t4.original_start, origsd2)

    def test_purge_outdated_single_transactions(self):
        purge_date = date.today() + timedelta(days=1)

        self.assertEqual(len(self.ts.store), 4)
        self.ts.purgeSingleBefore(purge_date)
        self.assertEqual(len(self.ts.store), 3)
        exp_set = set([self.t2, self.t3, self.t4])
        act_set = set(self.ts.store)
        self.assertEqual(exp_set.symmetric_difference(act_set), set())
        t_list = self.ts.getTransaction("Once, in two days")
        self.assertEqual(len(t_list), 1)
class TestBasicDelete(unittest.TestCase):
    def setUp(self):
        self.ts = TransactionStore()

        t1 = Transaction(
            start=date.today(),
            description="Once",
            amount=1.00,
            frequency=Transaction.ONCE)
        t2 = Transaction(
            start=date.today()+timedelta(days=2),
            description="Once, in two days",
            amount=1.01,
            frequency=Transaction.ONCE)
        t3 = Transaction(
            start=date.today(),
            end=date.today()+timedelta(days=56),
            description="Weekly",
            amount=1.02,
            frequency=Transaction.WEEKLY,
            skip=set([date.today()+timedelta(days=7)]),
            scheduled=True,
            cleared=True)

        self.ts.addTransactions(t1, t2, t3)

    def test_remove_existing_single_transaction(self):
        self.assertEqual(len(self.ts.store), 3)
        t_list = self.ts.getTransaction("Once")
        self.assertEqual(len(t_list), 1)
        t1 = t_list[0]
        self.ts.removeTransactions(t1)
        self.assertEqual(len(self.ts.store), 2)
        t_list = self.ts.getTransaction("Once")
        self.assertEqual(len(t_list), 0)

    def test_remove_existing_multiple_transactions(self):
        self.assertEqual(len(self.ts.store), 3)
        t_list = self.ts.getTransaction("Once")
        self.assertEqual(len(t_list), 1)
        t1 = t_list[0]
        t_list = self.ts.getTransaction("Weekly")
        self.assertEqual(len(t_list), 1)
        t2 = t_list[0]
        self.ts.removeTransactions(t1, t2)
        self.assertEqual(len(self.ts.store), 1)
        t_list = self.ts.getTransaction("Once")
        self.assertEqual(len(t_list), 0)
        t_list = self.ts.getTransaction("Weekly")
        self.assertEqual(len(t_list), 0)

    def test_remove_non_existent_single_transaction(self):
        t_missing = Transaction(
                start=date.today(),
                description="Missing",
                amount=1.00,
                frequency=Transaction.ONCE)
        self.assertEqual(len(self.ts.store), 3)
        self.ts.removeTransactions(t_missing)
        self.assertEqual(len(self.ts.store), 3)

    def test_remove_multiple_transactions_with_some_missing(self):
        t_missing = Transaction(
                start=date.today(),
                description="Missing",
                amount=1.00,
                frequency=Transaction.ONCE)

        self.assertEqual(len(self.ts.store), 3)
        t_list = self.ts.getTransaction("Once")
        self.assertEqual(len(t_list), 1)
        t1 = t_list[0]
        t_list = self.ts.getTransaction("Weekly")
        self.assertEqual(len(t_list), 1)
        t2 = t_list[0]
        self.ts.removeTransactions(t1, t2, t_missing)
        self.assertEqual(len(self.ts.store), 1)
        t_list = self.ts.getTransaction("Once")
        self.assertEqual(len(t_list), 0)
        t_list = self.ts.getTransaction("Weekly")
        self.assertEqual(len(t_list), 0)
 def setUp(self):
     sd = date.today()
     sb = 100.00
     ts = TransactionStore()
     self.cf = CashFlow(sd, sb, ts)
class TestFileOperations(unittest.TestCase):
    def setUp(self):
        self.file = f'./test-{time.time()}'

        t1 = Transaction(
            start=date.today(),
            description="Once, today",
            amount=1.00,
            frequency=Transaction.ONCE)
        t2 = Transaction(
            start=date.today(),
            original_start=date.today()-timedelta(days=1),
            end=date.today()+timedelta(days=56),
            description="Weekly",
            amount=1.02,
            frequency=Transaction.WEEKLY,
            skip=set([date.today()+timedelta(days=7)]),
            scheduled=True,
            cleared=True)

        self.ts = TransactionStore()
        self.ts.store.append(t1)
        self.ts.store.append(t2)

    def tearDown(self):
        os.remove(self.file)

    def assertTransactionsEqual(self, t1, t2):
        self.assertEqual(t1.start, t2.start)
        self.assertEqual(t1.original_start, t2.original_start)
        self.assertEqual(t1.end, t2.end)
        self.assertEqual(t1.description, t2.description)
        self.assertEqual(t1.amount, t2.amount)
        self.assertEqual(t1.frequency, t2.frequency)
        self.assertEqual(t1.skip.symmetric_difference(t2.skip), set())
        self.assertEqual(t1.scheduled, t2.scheduled)
        self.assertEqual(t1.cleared, t2.cleared)

    def test_file_operations(self):
        self.assertEqual(len(self.ts.store), 2)

        t1 = next((t for t in self.ts.store if t.amount == 1.00),
                  None)
        self.assertIsNotNone(t1)

        t2 = next((t for t in self.ts.store if t.amount == 1.02),
                  None)
        self.assertIsNotNone(t2)

        self.ts.saveTransactions(self.file)

        ts = TransactionStore()
        ts.loadTransactions(self.file)

        self.assertEqual(len(ts.store), 2)

        t1_l = next((t for t in ts.store if t.amount == 1.00),
                    None)
        self.assertIsNotNone(t1_l)
        self.assertTransactionsEqual(t1_l, t1)

        t2_l = next((t for t in ts.store if t.amount == 1.02),
                    None)
        self.assertIsNotNone(t2_l)
        self.assertTransactionsEqual(t2_l, t2)
 def test_constructor(self):
     ts = TransactionStore()
     self.assertIsInstance(ts.store, list)