diff -r 47394ceeaba1 Lib/idlelib/configHelpSourceEdit.py --- a/Lib/idlelib/configHelpSourceEdit.py Sun Feb 16 14:51:17 2014 -0500 +++ b/Lib/idlelib/configHelpSourceEdit.py Tue Feb 18 08:50:58 2014 +0530 @@ -8,7 +8,7 @@ import tkFileDialog class GetHelpSourceDialog(Toplevel): - def __init__(self, parent, title, menuItem='', filePath=''): + def __init__(self, parent, title, menu_item='', file_path=''): """Get menu entry and url/ local file location for Additional Help User selects a name for the Help resource and provides a web url @@ -22,12 +22,12 @@ self.title(title) self.transient(parent) self.grab_set() - self.protocol("WM_DELETE_WINDOW", self.Cancel) + self.protocol("WM_DELETE_WINDOW", self.cancel) self.parent = parent self.result = None - self.CreateWidgets() - self.menu.set(menuItem) - self.path.set(filePath) + self.create_widgets() + self.menu.set(menu_item) + self.path.set(file_path) self.withdraw() #hide while setting geometry #needs to be done here so that the winfo_reqwidth is valid self.update_idletasks() @@ -38,10 +38,10 @@ parent.winfo_rooty() + ((parent.winfo_height()/2) -(self.winfo_reqheight()/2))))) self.deiconify() #geometry set, unhide - self.bind('', self.Ok) + self.bind('', self.ok) self.wait_window() - def CreateWidgets(self): + def create_widgets(self): self.menu = StringVar(self) self.path = StringVar(self) self.fontSize = StringVar(self) @@ -62,18 +62,18 @@ labelPath.pack(anchor=W, padx=5, pady=3) self.entryPath.pack(anchor=W, padx=5, pady=3) browseButton = Button(self.frameMain, text='Browse', width=8, - command=self.browseFile) + command=self.browse_file) browseButton.pack(pady=3) frameButtons = Frame(self) frameButtons.pack(side=BOTTOM, fill=X) self.buttonOk = Button(frameButtons, text='OK', - width=8, default=ACTIVE, command=self.Ok) + width=8, default=ACTIVE, command=self.ok) self.buttonOk.grid(row=0, column=0, padx=5,pady=5) self.buttonCancel = Button(frameButtons, text='Cancel', - width=8, command=self.Cancel) + width=8, command=self.cancel) self.buttonCancel.grid(row=0, column=1, padx=5, pady=5) - def browseFile(self): + def browse_file(self): filetypes = [ ("HTML Files", "*.htm *.html", "TEXT"), ("PDF Files", "*.pdf", "TEXT"), @@ -96,9 +96,9 @@ if file: self.path.set(file) - def MenuOk(self): + def menu_ok(self): "Simple validity check for a sensible menu item name" - menuOk = True + menu_ok = True menu = self.menu.get() menu.strip() if not menu: @@ -106,19 +106,19 @@ message='No menu item specified', parent=self) self.entryMenu.focus_set() - menuOk = False + menu_ok = False elif len(menu) > 30: tkMessageBox.showerror(title='Menu Item Error', message='Menu item too long:' '\nLimit 30 characters.', parent=self) self.entryMenu.focus_set() - menuOk = False - return menuOk + menu_ok = False + return menu_ok - def PathOk(self): + def path_ok(self): "Simple validity check for menu file path" - pathOk = True + path_ok = True path = self.path.get() path.strip() if not path: #no path specified @@ -126,7 +126,7 @@ message='No help file path specified.', parent=self) self.entryPath.focus_set() - pathOk = False + path_ok = False elif path.startswith(('www.', 'http')): pass else: @@ -137,11 +137,11 @@ message='Help file path does not exist.', parent=self) self.entryPath.focus_set() - pathOk = False - return pathOk + path_ok = False + return path_ok - def Ok(self, event=None): - if self.MenuOk() and self.PathOk(): + def ok(self, event=None): + if self.menu_ok() and self.path_ok(): self.result = (self.menu.get().strip(), self.path.get().strip()) if sys.platform == 'darwin': @@ -154,11 +154,14 @@ self.result[1] = "file://" + path self.destroy() - def Cancel(self, event=None): + def cancel(self, event=None): self.result = None self.destroy() if __name__ == '__main__': + import unittest + unittest.main('idlelib.idle_test.test_config_helpsource', verbosity=2, exit=False) + #test the dialog root = Tk() def run(): diff -r 47394ceeaba1 Lib/idlelib/idle_test/mock_tk.py --- a/Lib/idlelib/idle_test/mock_tk.py Sun Feb 16 14:51:17 2014 -0500 +++ b/Lib/idlelib/idle_test/mock_tk.py Tue Feb 18 08:50:58 2014 +0530 @@ -67,6 +67,10 @@ showwarning = Mbox_func() # None from _tkinter import TclError +class Entry: + """Mock for tkinter.Entry. Expand as needed""" + def focus_set(self): + pass class Text(object): """A semi-functional non-gui replacement for tkinter.Text text editors. diff -r 47394ceeaba1 Lib/idlelib/idle_test/test_config_helpsource.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/idlelib/idle_test/test_config_helpsource.py Tue Feb 18 08:50:58 2014 +0530 @@ -0,0 +1,105 @@ +"""Unit test for idlelib.configHelpSourceEdit""" +import unittest +from idlelib.idle_test.mock_tk import Var, Mbox, Entry +from idlelib import configHelpSourceEdit as helpsource_dialog_module + +helpsource_dialog = helpsource_dialog_module.GetHelpSourceDialog + + +class dummy_helpsource_dialog(object): + # Mock for testing the following methods + menu_ok = helpsource_dialog.menu_ok.im_func + path_ok = helpsource_dialog.path_ok.im_func + cancel = helpsource_dialog.cancel.im_func + ok = helpsource_dialog.ok.im_func + # Attributes required by path_ok and menu_ok + entryMenu = Entry() + entryPath = Entry() + # Attributes, constant or variable required for tests. + menu = Var() + path = Var() + result = None + destroyed = False + + def destroy(self): + self.destroyed = True + +# name_ok calls Mbox.showerror if name is not ok +orig_mbox = helpsource_dialog_module.tkMessageBox +showerror = Mbox.showerror + + +class ConfigNameTest(unittest.TestCase): + dialog = dummy_helpsource_dialog() + + @classmethod + def setUpClass(cls): + helpsource_dialog_module.tkMessageBox = Mbox + + @classmethod + def tearDownClass(cls): + helpsource_dialog_module.tkMessageBox = orig_mbox + + def test_blank_menu(self): + self.dialog.menu.set('') + self.assertEqual(self.dialog.menu_ok(), False) + self.assertEqual(showerror.title, 'Menu Item Error') + self.assertIn('No', showerror.message) + + def test_long_menu(self): + self.dialog.menu.set('foobar' * 8) + self.assertEqual(self.dialog.menu_ok(), False) + self.assertEqual(showerror.title, 'Menu Item Error') + self.assertIn('too long', showerror.message) + + def test_good_menu(self): + self.dialog.menu.set(' this name is good') + self.assertEqual(self.dialog.menu_ok(), True) + + def test_blank_path(self): + self.dialog.path.set('') + self.assertEqual(self.dialog.path_ok(), False) + self.assertEqual(showerror.title, 'File Path Error') + self.assertIn('No', showerror.message) + + def test_invalid_paths(self): + # Test for invalid url path + self.dialog.path.set('ww.python.org') + self.assertEqual(self.dialog.path_ok(), False) + self.assertEqual(showerror.title, 'File Path Error') + self.assertIn('not', showerror.message) + + # Test for invalid file path + self.dialog.path.set('testfile' * 8) + self.assertEqual(self.dialog.path_ok(), False) + self.assertEqual(showerror.title, 'File Path Error') + self.assertIn('not', showerror.message) + + def test_good_path(self): + # Test for valid url path + self.dialog.path.set('www.python.org') + self.assertEqual(self.dialog.path_ok(), True) + + # Test for valid file path + self.dialog.path.set('/') + self.assertEqual(self.dialog.path_ok(), True) + + def test_ok(self): + self.dialog.destroyed = False + self.dialog.menu.set('good') + self.dialog.path.set('www.python.org') + self.dialog.ok() + self.assertEqual(self.dialog.result, ('good', 'www.python.org')) + self.assertTrue(self.dialog.destroyed) + + def test_cancel(self): + self.dialog.destroyed = False + self.dialog.menu.set('good') + self.dialog.path.set('www.python.org') + self.dialog.cancel() + self.assertEqual(self.dialog.result, None) + self.assertTrue(self.dialog.destroyed) + + +if __name__ == '__main__': + unittest.main(verbosity=2, exit=False)