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)
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.")