diff options
Diffstat (limited to 'Lib/idlelib')
| -rw-r--r-- | Lib/idlelib/configdialog.py | 379 | ||||
| -rw-r--r-- | Lib/idlelib/idle_test/mock_idle.py | 6 | ||||
| -rw-r--r-- | Lib/idlelib/idle_test/test_configdialog.py | 192 | 
3 files changed, 379 insertions, 198 deletions
| diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index f98af4600e..daaa34459e 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -160,7 +160,7 @@ class ConfigDialog(Toplevel):          corresponding aspect of the font sample on this page and          highlight sample on highlight page. -        Load_font_cfg initializes font vars and widgets from +        Funtion load_font_cfg initializes font vars and widgets from          idleConf entries and tk.          Fontlist: mouse button 1 click or up or down key invoke @@ -470,7 +470,7 @@ class ConfigDialog(Toplevel):                  event.widget.winfo_toplevel().highlight_target.set(elem)              text.tag_bind(                      self.theme_elements[element][0], '<ButtonPress-1>', tem) -        text.config(state=DISABLED) +        text['state'] = DISABLED          self.frame_color_set = Frame(frame_custom, relief=SOLID, borderwidth=1)          frame_fg_bg_toggle = Frame(frame_custom)          button_set_color = Button( @@ -650,59 +650,61 @@ class ConfigDialog(Toplevel):          frames[1].pack(side=TOP, fill=X, expand=True, pady=2)          return frame +      def create_page_general(self):          """Return frame of widgets for General tab. -        Tk Variables: -            win_width: Initial window width in characters. -            win_height: Initial window height in characters. -            startup_edit: Selector for opening in editor or shell mode. -            autosave: Selector for save prompt popup when using Run. - -        Methods: -            load_general_config: -            help_source_selected: Bound to list_help button release. -            set_helplist_button_states: Toggle based on list. -            helplist_item_edit: Command for button_helplist_edit. -            helplist_item_add: Command for button_helplist_add. -            helplist_item_remove: Command for button_helplist_remove. -            update_user_help_changed_items: Fill in changes. +        Enable users to provisionally change general options. Function +        load_general_cfg intializes tk variables and helplist using +        idleConf.  Radiobuttons startup_shell_on and startup_editor_on +        set var startup_edit. Radiobuttons save_ask_on and save_auto_on +        set var autosave. Entry boxes win_width_int and win_height_int +        set var win_width and win_height.  Setting var_name invokes the +        var_changed_var_name callback that adds option to changes. + +        Helplist: load_general_cfg loads list user_helplist with +        name, position pairs and copies names to listbox helplist. +        Clicking a name invokes help_source selected. Clicking +        button_helplist_name invokes helplist_item_name, which also +        changes user_helplist.  These functions all call +        set_add_delete_state. All but load call update_help_changes to +        rewrite changes['main']['HelpFiles'].          Widget Structure:  (*) widgets bound to self              frame                  frame_run: LabelFrame                      startup_title: Label -                    (*)radio_startup_edit: Radiobutton - startup_edit -                    (*)radio_startup_shell: Radiobutton - startup_edit +                    (*)startup_editor_on: Radiobutton - startup_edit +                    (*)startup_shell_on: Radiobutton - startup_edit                  frame_save: LabelFrame                      run_save_title: Label -                    (*)radio_save_ask: Radiobutton - autosave -                    (*)radio_save_auto: Radiobutton - autosave +                    (*)save_ask_on: Radiobutton - autosave +                    (*)save_auto_on: Radiobutton - autosave                  frame_win_size: LabelFrame                      win_size_title: Label                      win_width_title: Label -                    (*)entry_win_width: Entry - win_width +                    (*)win_width_int: Entry - win_width                      win_height_title: Label -                    (*)entry_win_height: Entry - win_height +                    (*)win_height_int: Entry - win_height                  frame_help: LabelFrame                      frame_helplist: Frame                          frame_helplist_buttons: Frame                              (*)button_helplist_edit                              (*)button_helplist_add                              (*)button_helplist_remove +                        (*)helplist: ListBox                          scroll_helplist: Scrollbar -                        (*)list_help: ListBox          """          parent = self.parent -        self.win_width = StringVar(parent) -        self.win_height = StringVar(parent)          self.startup_edit = IntVar(parent)          self.autosave = IntVar(parent) +        self.win_width = StringVar(parent) +        self.win_height = StringVar(parent) -        #widget creation -        #body +        # Create widgets: +        # body.          frame = self.tab_pages.pages['General'].frame -        #body section frames +        # body section frames.          frame_run = LabelFrame(frame, borderwidth=2, relief=GROOVE,                                text=' Startup Preferences ')          frame_save = LabelFrame(frame, borderwidth=2, relief=GROOVE, @@ -710,41 +712,41 @@ class ConfigDialog(Toplevel):          frame_win_size = Frame(frame, borderwidth=2, relief=GROOVE)          frame_help = LabelFrame(frame, borderwidth=2, relief=GROOVE,                                 text=' Additional Help Sources ') -        #frame_run +        # frame_run.          startup_title = Label(frame_run, text='At Startup') -        self.radio_startup_edit = Radiobutton( +        self.startup_editor_on = Radiobutton(                  frame_run, variable=self.startup_edit, value=1,                  text="Open Edit Window") -        self.radio_startup_shell = Radiobutton( +        self.startup_shell_on = Radiobutton(                  frame_run, variable=self.startup_edit, value=0,                  text='Open Shell Window') -        #frame_save +        # frame_save.          run_save_title = Label(frame_save, text='At Start of Run (F5)  ') -        self.radio_save_ask = Radiobutton( +        self.save_ask_on = Radiobutton(                  frame_save, variable=self.autosave, value=0,                  text="Prompt to Save") -        self.radio_save_auto = Radiobutton( +        self.save_auto_on = Radiobutton(                  frame_save, variable=self.autosave, value=1,                  text='No Prompt') -        #frame_win_size +        # frame_win_size.          win_size_title = Label(                  frame_win_size, text='Initial Window Size  (in characters)')          win_width_title = Label(frame_win_size, text='Width') -        self.entry_win_width = Entry( +        self.win_width_int = Entry(                  frame_win_size, textvariable=self.win_width, width=3)          win_height_title = Label(frame_win_size, text='Height') -        self.entry_win_height = Entry( +        self.win_height_int = Entry(                  frame_win_size, textvariable=self.win_height, width=3) -        #frame_help +        # frame_help.          frame_helplist = Frame(frame_help)          frame_helplist_buttons = Frame(frame_helplist) -        scroll_helplist = Scrollbar(frame_helplist) -        self.list_help = Listbox( +        self.helplist = Listbox(                  frame_helplist, height=5, takefocus=FALSE,                  exportselection=FALSE) -        scroll_helplist.config(command=self.list_help.yview) -        self.list_help.config(yscrollcommand=scroll_helplist.set) -        self.list_help.bind('<ButtonRelease-1>', self.help_source_selected) +        scroll_helplist = Scrollbar(frame_helplist) +        scroll_helplist['command'] = self.helplist.yview +        self.helplist['yscrollcommand'] = scroll_helplist.set +        self.helplist.bind('<ButtonRelease-1>', self.help_source_selected)          self.button_helplist_edit = Button(                  frame_helplist_buttons, text='Edit', state=DISABLED,                  width=8, command=self.helplist_item_edit) @@ -755,36 +757,146 @@ class ConfigDialog(Toplevel):                  frame_helplist_buttons, text='Remove', state=DISABLED,                  width=8, command=self.helplist_item_remove) -        #widget packing -        #body +        # Pack widgets: +        # body.          frame_run.pack(side=TOP, padx=5, pady=5, fill=X)          frame_save.pack(side=TOP, padx=5, pady=5, fill=X)          frame_win_size.pack(side=TOP, padx=5, pady=5, fill=X)          frame_help.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) -        #frame_run +        # frame_run.          startup_title.pack(side=LEFT, anchor=W, padx=5, pady=5) -        self.radio_startup_shell.pack(side=RIGHT, anchor=W, padx=5, pady=5) -        self.radio_startup_edit.pack(side=RIGHT, anchor=W, padx=5, pady=5) -        #frame_save +        self.startup_shell_on.pack(side=RIGHT, anchor=W, padx=5, pady=5) +        self.startup_editor_on.pack(side=RIGHT, anchor=W, padx=5, pady=5) +        # frame_save.          run_save_title.pack(side=LEFT, anchor=W, padx=5, pady=5) -        self.radio_save_auto.pack(side=RIGHT, anchor=W, padx=5, pady=5) -        self.radio_save_ask.pack(side=RIGHT, anchor=W, padx=5, pady=5) -        #frame_win_size +        self.save_auto_on.pack(side=RIGHT, anchor=W, padx=5, pady=5) +        self.save_ask_on.pack(side=RIGHT, anchor=W, padx=5, pady=5) +        # frame_win_size.          win_size_title.pack(side=LEFT, anchor=W, padx=5, pady=5) -        self.entry_win_height.pack(side=RIGHT, anchor=E, padx=10, pady=5) +        self.win_height_int.pack(side=RIGHT, anchor=E, padx=10, pady=5)          win_height_title.pack(side=RIGHT, anchor=E, pady=5) -        self.entry_win_width.pack(side=RIGHT, anchor=E, padx=10, pady=5) +        self.win_width_int.pack(side=RIGHT, anchor=E, padx=10, pady=5)          win_width_title.pack(side=RIGHT, anchor=E, pady=5) -        #frame_help +        # frame_help.          frame_helplist_buttons.pack(side=RIGHT, padx=5, pady=5, fill=Y)          frame_helplist.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)          scroll_helplist.pack(side=RIGHT, anchor=W, fill=Y) -        self.list_help.pack(side=LEFT, anchor=E, expand=TRUE, fill=BOTH) +        self.helplist.pack(side=LEFT, anchor=E, expand=TRUE, fill=BOTH)          self.button_helplist_edit.pack(side=TOP, anchor=W, pady=5)          self.button_helplist_add.pack(side=TOP, anchor=W)          self.button_helplist_remove.pack(side=TOP, anchor=W, pady=5) +          return frame +    def load_general_cfg(self): +        "Load current configuration settings for the general options." +        # Set startup state. +        self.startup_edit.set(idleConf.GetOption( +                'main', 'General', 'editor-on-startup', default=0, type='bool')) +        # Set autosave state. +        self.autosave.set(idleConf.GetOption( +                'main', 'General', 'autosave', default=0, type='bool')) +        # Set initial window size. +        self.win_width.set(idleConf.GetOption( +                'main', 'EditorWindow', 'width', type='int')) +        self.win_height.set(idleConf.GetOption( +                'main', 'EditorWindow', 'height', type='int')) +        # Set additional help sources. +        self.user_helplist = idleConf.GetAllExtraHelpSourcesList() +        self.helplist.delete(0, 'end') +        for help_item in self.user_helplist: +            self.helplist.insert(END, help_item[0]) +        self.set_add_delete_state() + +    def var_changed_startup_edit(self, *params): +        "Store change to toggle for starting IDLE in the editor or shell." +        value = self.startup_edit.get() +        changes.add_option('main', 'General', 'editor-on-startup', value) + +    def var_changed_autosave(self, *params): +        "Store change to autosave." +        value = self.autosave.get() +        changes.add_option('main', 'General', 'autosave', value) + +    def var_changed_win_width(self, *params): +        "Store change to window width." +        value = self.win_width.get() +        changes.add_option('main', 'EditorWindow', 'width', value) + +    def var_changed_win_height(self, *params): +        "Store change to window height." +        value = self.win_height.get() +        changes.add_option('main', 'EditorWindow', 'height', value) + +    def help_source_selected(self, event): +        "Handle event for selecting additional help." +        self.set_add_delete_state() + +    def set_add_delete_state(self): +        "Toggle the state for the help list buttons based on list entries." +        if self.helplist.size() < 1:  # No entries in list. +            self.button_helplist_edit['state'] = DISABLED +            self.button_helplist_remove['state'] = DISABLED +        else:  # Some entries. +            if self.helplist.curselection():  # There currently is a selection. +                self.button_helplist_edit['state'] = NORMAL +                self.button_helplist_remove['state'] = NORMAL +            else:  # There currently is not a selection. +                self.button_helplist_edit['state'] = DISABLED +                self.button_helplist_remove['state'] = DISABLED + +    def helplist_item_add(self): +        """Handle add button for the help list. + +        Query for name and location of new help sources and add +        them to the list. +        """ +        help_source = HelpSource(self, 'New Help Source').result +        if help_source: +            self.user_helplist.append(help_source) +            self.helplist.insert(END, help_source[0]) +            self.update_help_changes() + +    def helplist_item_edit(self): +        """Handle edit button for the help list. + +        Query with existing help source information and update +        config if the values are changed. +        """ +        item_index = self.helplist.index(ANCHOR) +        help_source = self.user_helplist[item_index] +        new_help_source = HelpSource( +                self, 'Edit Help Source', +                menuitem=help_source[0], +                filepath=help_source[1], +                ).result +        if new_help_source and new_help_source != help_source: +            self.user_helplist[item_index] = new_help_source +            self.helplist.delete(item_index) +            self.helplist.insert(item_index, new_help_source[0]) +            self.update_help_changes() +            self.set_add_delete_state()  # Selected will be un-selected + +    def helplist_item_remove(self): +        """Handle remove button for the help list. + +        Delete the help list item from config. +        """ +        item_index = self.helplist.index(ANCHOR) +        del(self.user_helplist[item_index]) +        self.helplist.delete(item_index) +        self.update_help_changes() +        self.set_add_delete_state() + +    def update_help_changes(self): +        "Clear and rebuild the HelpFiles section in changes" +        changes['main']['HelpFiles'] = {} +        for num in range(1, len(self.user_helplist) + 1): +            changes.add_option( +                    'main', 'HelpFiles', str(num), +                    ';'.join(self.user_helplist[num-1][:2])) + +      def attach_var_callbacks(self):          "Attach callbacks to variables that can be changed."          self.font_size.trace_add('write', self.var_changed_font) @@ -917,26 +1029,6 @@ class ConfigDialog(Toplevel):          else:              self.var_changed_custom_keys() -    def var_changed_win_width(self, *params): -        "Store change to window width." -        value = self.win_width.get() -        changes.add_option('main', 'EditorWindow', 'width', value) - -    def var_changed_win_height(self, *params): -        "Store change to window height." -        value = self.win_height.get() -        changes.add_option('main', 'EditorWindow', 'height', value) - -    def var_changed_startup_edit(self, *params): -        "Store change to toggle for starting IDLE in the editor or shell." -        value = self.startup_edit.get() -        changes.add_option('main', 'General', 'editor-on-startup', value) - -    def var_changed_autosave(self, *params): -        "Store change to autosave." -        value = self.autosave.get() -        changes.add_option('main', 'General', 'autosave', value) -      def set_theme_type(self):          """Set available screen options based on builtin or custom theme. @@ -956,26 +1048,26 @@ class ConfigDialog(Toplevel):              load_theme_cfg          """          if self.is_builtin_theme.get(): -            self.opt_menu_theme_builtin.config(state=NORMAL) -            self.opt_menu_theme_custom.config(state=DISABLED) -            self.button_delete_custom_theme.config(state=DISABLED) +            self.opt_menu_theme_builtin['state'] = NORMAL +            self.opt_menu_theme_custom['state'] = DISABLED +            self.button_delete_custom_theme['state'] = DISABLED          else: -            self.opt_menu_theme_builtin.config(state=DISABLED) -            self.radio_theme_custom.config(state=NORMAL) -            self.opt_menu_theme_custom.config(state=NORMAL) -            self.button_delete_custom_theme.config(state=NORMAL) +            self.opt_menu_theme_builtin['state'] = DISABLED +            self.radio_theme_custom['state'] = NORMAL +            self.opt_menu_theme_custom['state'] = NORMAL +            self.button_delete_custom_theme['state'] = NORMAL      def set_keys_type(self):          "Set available screen options based on builtin or custom key set."          if self.are_keys_builtin.get(): -            self.opt_menu_keys_builtin.config(state=NORMAL) -            self.opt_menu_keys_custom.config(state=DISABLED) -            self.button_delete_custom_keys.config(state=DISABLED) +            self.opt_menu_keys_builtin['state'] = NORMAL +            self.opt_menu_keys_custom['state'] = DISABLED +            self.button_delete_custom_keys['state'] = DISABLED          else: -            self.opt_menu_keys_builtin.config(state=DISABLED) -            self.radio_keys_custom.config(state=NORMAL) -            self.opt_menu_keys_custom.config(state=NORMAL) -            self.button_delete_custom_keys.config(state=NORMAL) +            self.opt_menu_keys_builtin['state'] = DISABLED +            self.radio_keys_custom['state'] = NORMAL +            self.opt_menu_keys_custom['state'] = NORMAL +            self.button_delete_custom_keys['state'] = NORMAL      def get_new_keys(self):          """Handle event to change key binding for selected line. @@ -1037,7 +1129,7 @@ class ConfigDialog(Toplevel):      def keybinding_selected(self, event):          "Activate button to assign new keys to selected action." -        self.button_new_keys.config(state=NORMAL) +        self.button_new_keys['state'] = NORMAL      def create_new_key_set(self, new_key_set_name):          """Create a new custom key set with the given name. @@ -1115,7 +1207,7 @@ class ConfigDialog(Toplevel):          item_list = idleConf.GetSectionList('user', 'keys')          item_list.sort()          if not item_list: -            self.radio_keys_custom.config(state=DISABLED) +            self.radio_keys_custom['state'] = DISABLED              self.opt_menu_keys_custom.SetMenu(item_list, '- no custom keys -')          else:              self.opt_menu_keys_custom.SetMenu(item_list, item_list[0]) @@ -1164,7 +1256,7 @@ class ConfigDialog(Toplevel):          item_list = idleConf.GetSectionList('user', 'highlight')          item_list.sort()          if not item_list: -            self.radio_theme_custom.config(state=DISABLED) +            self.radio_theme_custom['state'] = DISABLED              self.opt_menu_theme_custom.SetMenu(item_list, '- no custom themes -')          else:              self.opt_menu_theme_custom.SetMenu(item_list, item_list[0]) @@ -1303,12 +1395,12 @@ class ConfigDialog(Toplevel):              load_theme_cfg          """          if self.highlight_target.get() == 'Cursor':  # bg not possible -            self.radio_fg.config(state=DISABLED) -            self.radio_bg.config(state=DISABLED) +            self.radio_fg['state'] = DISABLED +            self.radio_bg['state'] = DISABLED              self.fg_bg_toggle.set(1)          else:  # Both fg and bg can be set. -            self.radio_fg.config(state=NORMAL) -            self.radio_bg.config(state=NORMAL) +            self.radio_fg['state'] = NORMAL +            self.radio_bg['state'] = NORMAL              self.fg_bg_toggle.set(1)          self.set_color_sample() @@ -1378,76 +1470,6 @@ class ConfigDialog(Toplevel):              self.highlight_sample.tag_config(element, **colors)          self.set_color_sample() -    def help_source_selected(self, event): -        "Handle event for selecting additional help." -        self.set_helplist_button_states() - -    def set_helplist_button_states(self): -        "Toggle the state for the help list buttons based on list entries." -        if self.list_help.size() < 1:  # No entries in list. -            self.button_helplist_edit.config(state=DISABLED) -            self.button_helplist_remove.config(state=DISABLED) -        else:  # Some entries. -            if self.list_help.curselection():  # There currently is a selection. -                self.button_helplist_edit.config(state=NORMAL) -                self.button_helplist_remove.config(state=NORMAL) -            else:  # There currently is not a selection. -                self.button_helplist_edit.config(state=DISABLED) -                self.button_helplist_remove.config(state=DISABLED) - -    def helplist_item_add(self): -        """Handle add button for the help list. - -        Query for name and location of new help sources and add -        them to the list. -        """ -        help_source = HelpSource(self, 'New Help Source', -                                ).result -        if help_source: -            self.user_helplist.append((help_source[0], help_source[1])) -            self.list_help.insert(END, help_source[0]) -            self.update_user_help_changed_items() -        self.set_helplist_button_states() - -    def helplist_item_edit(self): -        """Handle edit button for the help list. - -        Query with existing help source information and update -        config if the values are changed. -        """ -        item_index = self.list_help.index(ANCHOR) -        help_source = self.user_helplist[item_index] -        new_help_source = HelpSource( -                self, 'Edit Help Source', -                menuitem=help_source[0], -                filepath=help_source[1], -                ).result -        if new_help_source and new_help_source != help_source: -            self.user_helplist[item_index] = new_help_source -            self.list_help.delete(item_index) -            self.list_help.insert(item_index, new_help_source[0]) -            self.update_user_help_changed_items() -            self.set_helplist_button_states() - -    def helplist_item_remove(self): -        """Handle remove button for the help list. - -        Delete the help list item from config. -        """ -        item_index = self.list_help.index(ANCHOR) -        del(self.user_helplist[item_index]) -        self.list_help.delete(item_index) -        self.update_user_help_changed_items() -        self.set_helplist_button_states() - -    def update_user_help_changed_items(self): -        "Clear and rebuild the HelpFiles section in changes" -        changes['main']['HelpFiles'] = {} -        for num in range(1, len(self.user_helplist) + 1): -            changes.add_option( -                    'main', 'HelpFiles', str(num), -                    ';'.join(self.user_helplist[num-1][:2])) -      def load_theme_cfg(self):          """Load current configuration settings for the theme options. @@ -1481,7 +1503,7 @@ class ConfigDialog(Toplevel):              item_list = idleConf.GetSectionList('user', 'highlight')              item_list.sort()              if not item_list: -                self.radio_theme_custom.config(state=DISABLED) +                self.radio_theme_custom['state'] = DISABLED                  self.custom_theme.set('- no custom themes -')              else:                  self.opt_menu_theme_custom.SetMenu(item_list, item_list[0]) @@ -1515,7 +1537,7 @@ class ConfigDialog(Toplevel):              item_list = idleConf.GetSectionList('user', 'keys')              item_list.sort()              if not item_list: -                self.radio_keys_custom.config(state=DISABLED) +                self.radio_keys_custom['state'] = DISABLED                  self.custom_keys.set('- no custom keys -')              else:                  self.opt_menu_keys_custom.SetMenu(item_list, item_list[0]) @@ -1531,25 +1553,6 @@ class ConfigDialog(Toplevel):          keyset_name = idleConf.CurrentKeys()          self.load_keys_list(keyset_name) -    def load_general_cfg(self): -        "Load current configuration settings for the general options." -        # Set startup state. -        self.startup_edit.set(idleConf.GetOption( -                'main', 'General', 'editor-on-startup', default=1, type='bool')) -        # Set autosave state. -        self.autosave.set(idleConf.GetOption( -                'main', 'General', 'autosave', default=0, type='bool')) -        # Set initial window size. -        self.win_width.set(idleConf.GetOption( -                'main', 'EditorWindow', 'width', type='int')) -        self.win_height.set(idleConf.GetOption( -                'main', 'EditorWindow', 'height', type='int')) -        # Set additional help sources. -        self.user_helplist = idleConf.GetAllExtraHelpSourcesList() -        for help_item in self.user_helplist: -            self.list_help.insert(END, help_item[0]) -        self.set_helplist_button_states() -      def load_configs(self):          """Load configuration for each page. diff --git a/Lib/idlelib/idle_test/mock_idle.py b/Lib/idlelib/idle_test/mock_idle.py index 8f3147b1c5..f279a52fd5 100644 --- a/Lib/idlelib/idle_test/mock_idle.py +++ b/Lib/idlelib/idle_test/mock_idle.py @@ -13,14 +13,16 @@ class Func:      self.args - capture positional arguments.      self.kwds - capture keyword arguments.      self.result - return or raise value set in __init__. +    self.return_self - return self instead, to mock query class return.      Most common use will probably be to mock instance methods.      Given class instance, can set and delete as instance attribute.      Mock_tk.Var and Mbox_func are special variants of this.      ''' -    def __init__(self, result=None): +    def __init__(self, result=None, return_self=False):          self.called = 0          self.result = result +        self.return_self = return_self          self.args = None          self.kwds = None      def __call__(self, *args, **kwds): @@ -29,6 +31,8 @@ class Func:          self.kwds = kwds          if isinstance(self.result, BaseException):              raise self.result +        elif self.return_self: +            return self          else:              return self.result diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index ce02ae4a8e..7296075fbe 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -1,16 +1,17 @@  """Test idlelib.configdialog.  Half the class creates dialog, half works with user customizations. -Coverage: 46% just by creating dialog, 60% with current tests. +Coverage: 63%.  """ -from idlelib.configdialog import ConfigDialog, idleConf, changes, VarTrace +from idlelib import configdialog  from test.support import requires  requires('gui') -from tkinter import Tk, IntVar, BooleanVar  import unittest  from unittest import mock -import idlelib.config as config  from idlelib.idle_test.mock_idle import Func +from tkinter import Tk, IntVar, BooleanVar, DISABLED, NORMAL +from idlelib import config +from idlelib.configdialog import ConfigDialog, idleConf, changes, VarTrace  # Tests should not depend on fortuitous user configurations.  # They must not affect actual user .cfg files. @@ -226,27 +227,200 @@ class KeysTest(unittest.TestCase):  class GeneralTest(unittest.TestCase): +    """Test that general tab widgets enable users to make changes. + +    Test that widget actions set vars, that var changes add +    options to changes and that helplist works correctly. +    """ +    @classmethod +    def setUpClass(cls): +        # Mask instance methods used by help functions. +        d = dialog +        d.set = d.set_add_delete_state = Func() +        d.upc = d.update_help_changes = Func() + +    @classmethod +    def tearDownClass(cls): +        d = dialog +        del d.set, d.set_add_delete_state +        del d.upc, d.update_help_changes +        d.helplist.delete(0, 'end') +        d.user_helplist.clear()      def setUp(self):          changes.clear() +    def test_load_general_cfg(self): +        # Set to wrong values, load, check right values. +        eq = self.assertEqual +        d = dialog +        d.startup_edit.set(1) +        d.autosave.set(1) +        d.win_width.set(1) +        d.win_height.set(1) +        d.helplist.insert('end', 'bad') +        d.user_helplist = ['bad', 'worse'] +        idleConf.SetOption('main', 'HelpFiles', '1', 'name;file') +        d.load_general_cfg() +        eq(d.startup_edit.get(), 0) +        eq(d.autosave.get(), 0) +        eq(d.win_width.get(), '80') +        eq(d.win_height.get(), '40') +        eq(d.helplist.get(0, 'end'), ('name',)) +        eq(d.user_helplist, [('name', 'file', '1')]) +      def test_startup(self): -        dialog.radio_startup_edit.invoke() +        dialog.startup_editor_on.invoke()          self.assertEqual(mainpage,                           {'General': {'editor-on-startup': '1'}}) +        changes.clear() +        dialog.startup_shell_on.invoke() +        self.assertEqual(mainpage, +                         {'General': {'editor-on-startup': '0'}})      def test_autosave(self): -        dialog.radio_save_auto.invoke() +        dialog.save_auto_on.invoke()          self.assertEqual(mainpage, {'General': {'autosave': '1'}}) +        dialog.save_ask_on.invoke() +        self.assertEqual(mainpage, {'General': {'autosave': '0'}})      def test_editor_size(self): -        dialog.entry_win_height.insert(0, '1') +        dialog.win_height_int.insert(0, '1')          self.assertEqual(mainpage, {'EditorWindow': {'height': '140'}})          changes.clear() -        dialog.entry_win_width.insert(0, '1') +        dialog.win_width_int.insert(0, '1')          self.assertEqual(mainpage, {'EditorWindow': {'width': '180'}}) -    #def test_help_sources(self): pass  # TODO +    def test_source_selected(self): +        d = dialog +        d.set = d.set_add_delete_state +        d.upc = d.update_help_changes +        helplist = d.helplist +        helplist.insert(0, 'source') +        helplist.activate(0) + +        helplist.focus_force() +        helplist.see(0) +        helplist.update() +        x, y, dx, dy = helplist.bbox(0) +        x += dx // 2 +        y += dy // 2 +        d.set.called = d.upc.called = 0 +        helplist.event_generate('<Button-1>', x=x, y=y) +        helplist.event_generate('<ButtonRelease-1>', x=x, y=y) +        self.assertEqual(helplist.get('anchor'), 'source') +        self.assertTrue(d.set.called) +        self.assertFalse(d.upc.called) + +    def test_set_add_delete_state(self): +        # Call with 0 items, 1 unselected item, 1 selected item. +        eq = self.assertEqual +        d = dialog +        del d.set_add_delete_state  # Unmask method. +        sad = d.set_add_delete_state +        h = d.helplist + +        h.delete(0, 'end') +        sad() +        eq(d.button_helplist_edit['state'], DISABLED) +        eq(d.button_helplist_remove['state'], DISABLED) + +        h.insert(0, 'source') +        sad() +        eq(d.button_helplist_edit['state'], DISABLED) +        eq(d.button_helplist_remove['state'], DISABLED) + +        h.selection_set(0) +        sad() +        eq(d.button_helplist_edit['state'], NORMAL) +        eq(d.button_helplist_remove['state'], NORMAL) +        d.set_add_delete_state = Func()  # Mask method. + +    def test_helplist_item_add(self): +        # Call without and twice with HelpSource result. +        # Double call enables check on order. +        eq = self.assertEqual +        orig_helpsource = configdialog.HelpSource +        hs = configdialog.HelpSource = Func(return_self=True) +        d = dialog +        d.helplist.delete(0, 'end') +        d.user_helplist.clear() +        d.set.called = d.upc.called = 0 + +        hs.result = '' +        d.helplist_item_add() +        self.assertTrue(list(d.helplist.get(0, 'end')) == +                        d.user_helplist == []) +        self.assertFalse(d.upc.called) + +        hs.result = ('name1', 'file1') +        d.helplist_item_add() +        hs.result = ('name2', 'file2') +        d.helplist_item_add() +        eq(d.helplist.get(0, 'end'), ('name1', 'name2')) +        eq(d.user_helplist, [('name1', 'file1'), ('name2', 'file2')]) +        eq(d.upc.called, 2) +        self.assertFalse(d.set.called) + +        configdialog.HelpSource = orig_helpsource + +    def test_helplist_item_edit(self): +        # Call without and with HelpSource change. +        eq = self.assertEqual +        orig_helpsource = configdialog.HelpSource +        hs = configdialog.HelpSource = Func(return_self=True) +        d = dialog +        d.helplist.delete(0, 'end') +        d.helplist.insert(0, 'name1') +        d.helplist.selection_set(0) +        d.helplist.selection_anchor(0) +        d.user_helplist.clear() +        d.user_helplist.append(('name1', 'file1')) +        d.set.called = d.upc.called = 0 + +        hs.result = '' +        d.helplist_item_edit() +        hs.result = ('name1', 'file1') +        d.helplist_item_edit() +        eq(d.helplist.get(0, 'end'), ('name1',)) +        eq(d.user_helplist, [('name1', 'file1')]) +        self.assertFalse(d.upc.called) + +        hs.result = ('name2', 'file2') +        d.helplist_item_edit() +        eq(d.helplist.get(0, 'end'), ('name2',)) +        eq(d.user_helplist, [('name2', 'file2')]) +        self.assertTrue(d.upc.called == d.set.called == 1) + +        configdialog.HelpSource = orig_helpsource + +    def test_helplist_item_remove(self): +        eq = self.assertEqual +        d = dialog +        d.helplist.delete(0, 'end') +        d.helplist.insert(0, 'name1') +        d.helplist.selection_set(0) +        d.helplist.selection_anchor(0) +        d.user_helplist.clear() +        d.user_helplist.append(('name1', 'file1')) +        d.set.called = d.upc.called = 0 + +        d.helplist_item_remove() +        eq(d.helplist.get(0, 'end'), ()) +        eq(d.user_helplist, []) +        self.assertTrue(d.upc.called == d.set.called == 1) + +    def test_update_help_changes(self): +        d = dialog +        del d.update_help_changes +        d.user_helplist.clear() +        d.user_helplist.append(('name1', 'file1')) +        d.user_helplist.append(('name2', 'file2')) + +        d.update_help_changes() +        self.assertEqual(mainpage['HelpFiles'], +                        {'1': 'name1;file1', '2': 'name2;file2'}) +        d.update_help_changes = Func()  class TestVarTrace(unittest.TestCase): | 
