From 879433efe769e5117d73451b58d4a95bc29a146a Mon Sep 17 00:00:00 2001 From: HelioGuilherme66 Date: Mon, 20 Jan 2025 02:01:15 +0000 Subject: [PATCH] Better results from steps in test but not resource. WIP many debugs --- src/robotide/controller/ctrlcommands.py | 93 ++++++++++++++++--- src/robotide/controller/macrocontrollers.py | 6 +- src/robotide/controller/settingcontrollers.py | 2 + src/robotide/controller/stepcontrollers.py | 9 +- src/robotide/namespace/namespace.py | 16 ++-- src/robotide/publish/messages.py | 2 +- src/robotide/spec/iteminfo.py | 1 + src/robotide/ui/treenodehandlers.py | 2 + src/robotide/ui/treeplugin.py | 27 ++++-- src/robotide/usages/UsageRunner.py | 21 ++++- src/robotide/usages/commands.py | 9 +- src/robotide/usages/usagesdialog.py | 18 ++-- utest/controller/test_occurrences.py | 5 +- utest/controller/test_z_rename_keywords.py | 70 +++++++++++++- .../TestCases/Sub/resources/res02.resource | 2 +- .../robotdata/TestCases/suite01.robot | 1 + .../robotdata/resources/external_res.resource | 6 ++ 17 files changed, 237 insertions(+), 53 deletions(-) diff --git a/src/robotide/controller/ctrlcommands.py b/src/robotide/controller/ctrlcommands.py index a568b8232..344d909a6 100644 --- a/src/robotide/controller/ctrlcommands.py +++ b/src/robotide/controller/ctrlcommands.py @@ -347,7 +347,7 @@ def _notify_values_changed(self, occurrences, old_name=None): f"oc= {oc.source} {oc.item} {oc.usage} {oc._value}") except AttributeError: print(f"DEBUG: ctlcommands.py RenameKeywordOccurrences _notify_values_changed: " - f" in AttributeError oc= {oc.item} {oc.usage} {oc._value}") + f" in AttributeError oc= {oc}") oc.notify_value_changed(old_name) self._observer.notify() @@ -367,7 +367,7 @@ def _params(self): def _execute(self, context): old_name = context.name context.test_name.rename(self._new_name) - context.test_name._item.notify_name_changed(old_name) + context.test_name._item.notify_name_changed(old_name=old_name, new_name=self._new_name) def _get_undo_command(self): return self @@ -654,21 +654,38 @@ def execute(self, context): def normalize_kw_name(name): name = re.sub('(.)([A-Z][a-z]+)', r'\1 \2', name) - return re.sub('([a-z0-9])([A-Z])', r'\1 \2', name).lower().replace('_', ' ') + # print(f"DEBUG: ctlcommands.py normalize_kw_name First step keyword_name={name}") + name = re.sub('([a-z0-9])([A-Z])', r'\1 \2', name).lower().replace('_', ' ') + # print(f"DEBUG: ctlcommands.py normalize_kw_name RETURN keyword_name={name}") + return name class FindOccurrences(_Command): modifying = False - def __init__(self, keyword_name, keyword_info=None): + def __init__(self, keyword_name, keyword_info=None, prefix=None): if keyword_name.strip() == '': raise ValueError('Keyword name can not be "%s"' % keyword_name) self.normalized_name = normalize_kw_name(keyword_name) print(f"DEBUG: ctlcommands.py FindOccurrences INIT keyword_name={keyword_name}") self._keyword_name = keyword_name self._keyword_info = keyword_info + self.normalized_name_res = None + if self._keyword_info: + self.normalized_name_res = (keyword_name if '.' in keyword_name + else (self._keyword_info.source.replace('.robot', '').replace('.resource', '') + +"."+keyword_name)) + self._keyword_source = self._keyword_info.source + # if keyword_name == self.normalized_name_res: + # self.normalized_name_res = None + else: + self._keyword_source = None + self.prefix = prefix + if self.prefix and not self.normalized_name_res: + self.normalized_name_res = f"{self.prefix}.{self._keyword_name}" + print(f"DEBUG: ctlcommands.py FindOccurrences INIT normalized_name_res={self.normalized_name_res}" + f"\nSOURCE={self._keyword_source} PREFIX={self.prefix}") self._keyword_regexp = self._create_regexp(keyword_name) - self._keyword_source = None @staticmethod def _create_regexp(keyword_name): @@ -684,9 +701,16 @@ def _create_regexp(keyword_name): return name def execute(self, context): + print(f"DEBUG: ctrlcommands FindOccurrences EXECUTE context={context}") self._keyword_source = \ self._keyword_info and self._keyword_info.source or \ self._find_keyword_source(context.datafile_controller) + if not self.normalized_name_res: + self.normalized_name_res = (self._keyword_name if '.' in self._keyword_name + else (self._keyword_source.replace('.robot', '').replace('.resource', '') + +"."+self._keyword_name)) + if self._keyword_name == self.normalized_name_res and '.' in self._keyword_name: + self._keyword_name = self._keyword_name.split('.')[-1] return self._find_occurrences_in(self._items_from(context)) def _items_from(self, context): @@ -710,11 +734,13 @@ def _items_from_datafile(self, df): yield item for kw_items in (self._items_from_keyword(kw) for kw in df.keywords): for item in kw_items: + # print(f"DEBUG: ctrlcommands FindOccurrences _items_from_datafile kw_items yield {item}" + # f"\nself._keyword_source = {self._keyword_source}") yield item def _items_from_keyword(self, kw): return chain([kw.keyword_name] if kw.source == self._keyword_source - else [], kw.steps, [kw.teardown] if kw.teardown else []) + else [], kw.steps, [kw.setup] if kw.setup else [], [kw.teardown] if kw.teardown else []) @staticmethod def _items_from_test(test): @@ -722,17 +748,58 @@ def _items_from_test(test): def _find_keyword_source(self, datafile_controller): item_info = datafile_controller.keyword_info(None, self._keyword_name) + print(f"DEBUG: ctrlcommands _find_keyword_source datafile_controller={datafile_controller}" + f"item_info={item_info}") return item_info.source if item_info else None def _find_occurrences_in(self, items): + # print(f"DEBUG: ctrlcommands _find_occurrences_in ENTER normalized_name={self.normalized_name} WITH resource" + # f" {self.normalized_name_res} PREFIX={self.prefix}\n" + # f"LIST OF ITEMS={items}") + if not self._keyword_source.startswith(self.prefix): + print(f"DEBUG: ctrlcommands FindOccurrences _find_occurrences_in SKIP SEARCH" + f" self._keyword_source={self._keyword_source}\n" + f"prefix={self.prefix}") + yield None + else: + for item in items: + # print(f"DEBUG: ctrlcommands _find_occurrences_in searching item={item}") + if (self.normalized_name_res and (self.normalized_name_res.startswith(self.prefix) + and item.contains_keyword(self.normalized_name_res) + or item.contains_keyword(self._keyword_name))): + # This block is active when finding from a cell with resource prefix + print(f"DEBUG: ctrlcommands _find_occurrences_in searching item={item} ADD TO OCCURRENCES: FOUND " + f"{self.normalized_name_res}") + yield Occurrence(item, self._keyword_name) + elif self._contains_exact_item(item): + # print(f"DEBUG: ctrlcommands _find_occurrences_in searching item={item} NAME={self._keyword_name}" + # f" source={self._keyword_source}\n" + # f"self.normalized_name_res={self.normalized_name_res} parent={item.parent}\n" + # f" PREFIX={self.prefix}") + # print(f"DEBUG: ctrlcommands _find_occurrences_in searching item type = {type(item)}" + # f" kwsource={self._keyword_source}") + # if self._keyword_source.startswith(self.prefix): + print(f"DEBUG: ctrlcommands _find_occurrences_in searching ADD TO OCCURRENCES: {self._keyword_name}") + yield Occurrence(item, self._keyword_name) + + def _contains_exact_item(self, item): from .tablecontrollers import VariableTableController - print(f"DEBUG: ctrlcommands _find_occurrences_in NORMALIZED NAME {self.normalized_name}") - for item in items: - # print(f"DEBUG: ctrlcommands _find_occurrences_in searching item={item}") - if self._contains_item(item) or (not isinstance(item, VariableTableController) - and (item.contains_keyword(self.normalized_name) or - item.contains_keyword(self.normalized_name.replace(' ', '_')))): - yield Occurrence(item, self._keyword_name) + match_name = self._contains_item(item) + if match_name and isinstance(match_name, re.Match) and '.' in match_name.string: + # print(f"DEBUG: ctrlcommands _find_occurrences_in _contains_exact_item PREFIXED Name={match_name}" + # f"\n groups={match_name.groups()} string={match_name.string}" + # f" RETURNS {match_name.string.startswith(self.prefix)}") + return match_name.string.startswith(self.prefix) # Avoid false positive for res prefixed + elif match_name or (not isinstance(item, VariableTableController) and + (item.contains_keyword(self.normalized_name) or + item.contains_keyword(self.normalized_name.replace(' ', '_')))): + if match_name and isinstance(match_name, re.Match): + print(f"DEBUG: ctrlcommands _find_occurrences_in _contains_exact_item Matching Name={match_name}") + else: + print(f"DEBUG: ctrlcommands _find_occurrences_in _contains_exact_item item={item}" + f"self.normalized_name={self.normalized_name} OR " + f"underscore={self.normalized_name.replace(' ', '_')}") + return True def _contains_item(self, item): self._yield_for_other_threads() diff --git a/src/robotide/controller/macrocontrollers.py b/src/robotide/controller/macrocontrollers.py index ab6dfcff3..e234e3c69 100644 --- a/src/robotide/controller/macrocontrollers.py +++ b/src/robotide/controller/macrocontrollers.py @@ -61,7 +61,7 @@ def rename(self, new_name): def notify_value_changed(self, old_name=None): print(f"DEBUG: macrocontrollers.py notify_value_changed item={self._item.name} old_name={old_name}") - self._item.notify_name_changed(old_name) + self._item.notify_name_changed(old_name=old_name, new_name=self._item.name) @property def parent(self): @@ -287,10 +287,10 @@ def _create_extracted_kw(self, name, argstr, extracted_steps): def validate_name(self, name): return self._parent.validate_name(name, self) - def notify_name_changed(self, old_name=None): + def notify_name_changed(self, old_name=None, new_name=None): self.update_namespace() self.mark_dirty() - RideItemNameChanged(item=self, old_name=old_name).publish() + RideItemNameChanged(item=self, old_name=old_name, new_name=new_name).publish() def notify_keyword_removed(self): self.update_namespace() diff --git a/src/robotide/controller/settingcontrollers.py b/src/robotide/controller/settingcontrollers.py index dab0092b1..09f44b896 100644 --- a/src/robotide/controller/settingcontrollers.py +++ b/src/robotide/controller/settingcontrollers.py @@ -640,6 +640,8 @@ def contains_filename(self, filename): return self.name.endswith(filename) def change_name(self, old_name, new_name): + print(f"DEBUG: settingcontrollers.py ResourceImportController change_name ENTER\n" + f"old_name={old_name} new_name={new_name}") if self.contains_filename(old_name): self.set_value(self.name[:-len(old_name)] + new_name) else: diff --git a/src/robotide/controller/stepcontrollers.py b/src/robotide/controller/stepcontrollers.py index a162c1c43..e406e7eaa 100644 --- a/src/robotide/controller/stepcontrollers.py +++ b/src/robotide/controller/stepcontrollers.py @@ -282,8 +282,15 @@ def contains_variable_assignment(self, name): for item in self.as_list()) def contains_keyword(self, name): + for item in [self.keyword or ''] + self.args: + matching = self._kw_name_match(item, name) + if matching is not None: + return matching + return False + """ return any(self._kw_name_match(item, name) for item in [self.keyword or ''] + self.args) + """ def _kw_name_match(self, item, expected): if isinstance(expected, str): @@ -566,7 +573,7 @@ def notify_value_changed(self, old_name=None): print(f"DEBUG: stepcontrollers.py StepController notify_value_changed: ENTER old_name={old_name}" f" parent={self.parent.name} calling self.parent.notify_steps_changed()") if old_name is not None: - RideItemNameChanged(item=self, old_name=old_name).publish() + RideItemNameChanged(item=self, old_name=old_name, new_name=None).publish() self.parent.notify_steps_changed(old_name) def increase_indent(self): diff --git a/src/robotide/namespace/namespace.py b/src/robotide/namespace/namespace.py index 20a38e427..6bc11f192 100644 --- a/src/robotide/namespace/namespace.py +++ b/src/robotide/namespace/namespace.py @@ -203,8 +203,6 @@ def new_resource(self, path, directory=''): def find_user_keyword(self, datafile, kw_name): kw = self.find_keyword(datafile, kw_name) - # print(f"DEBUG: namespace.py Namespace find_user_keyword datafile={datafile} " - # f" kw_name={kw_name} keyword={kw}") return kw if isinstance(kw, UserKeywordInfo) else None def is_user_keyword(self, datafile, kw_name): @@ -229,13 +227,14 @@ def find_keyword(self, datafile, kw_name): casesensitive = (kw_name.upper() != kw_name and kw_name.upper() in UPPERCASE_KWS) kwds = self._retriever.get_keywords_cached(datafile, self._context_factory, caseless=not casesensitive) # print(f"DEBUG: namespace.py Namespace find_keyword will GET kw_name=={kw_name} casesensitive={casesensitive}") - return kwds.get(kw_name) + return kwds.get(kw_name, origin=datafile) def is_library_keyword(self, datafile, kw_name): return bool(self.find_library_keyword(datafile, kw_name)) def keyword_details(self, datafile, name): - # print(f"DEBUG: namespace.py Namespace keyword_details ENTER will look for name=={name}") + # print(f"DEBUG: namespace.py Namespace keyword_details ENTER will look for name=={name} " + # f"in datafile={datafile.source}") kw = self.find_keyword(datafile, name) return kw.details if kw else None @@ -548,7 +547,9 @@ def get_keywords_cached(self, datafile, context_factory, caseless=False): words.extend(self.default_kws) values = _Keywords(words, caseless=caseless) self.keyword_cache.put(datafile.source, values) - # print(f"DEBUG: namespace.py DatafileRetrieve get_keywords_cached returning cached keywords values=={values}") + # print(f"DEBUG: namespace.py DatafileRetrieve get_keywords_cached returning cached keywords values=={values}" + # f"\ndatafile={datafile.source}") + # print(f"DEBUG: namespace.py DatafileRetrieve get_keywords_cached datafile = {datafile.source}") return values def _get_user_keywords_from(self, datafile): @@ -642,8 +643,11 @@ def _add_embedded(self, kw): except TypeError: pass - def get(self, kw_name): + def get(self, kw_name, origin=None): if kw_name in self.keywords: + filename = os.path.basename(origin.source) + # print(f"DEBUG: namespace.py _Keywords get keywords in loop FOUND {kw_name} @ {filename}" + # f" RETURNING {self.keywords[kw_name]} {self.keywords[kw_name].source == filename}") return self.keywords[kw_name] # print(f"DEBUG: namespace.py _Keywords get keywords {self.keywords}") bdd_name = self._get_bdd_name(kw_name) diff --git a/src/robotide/publish/messages.py b/src/robotide/publish/messages.py index 49fb95e7d..251b4b47d 100644 --- a/src/robotide/publish/messages.py +++ b/src/robotide/publish/messages.py @@ -409,7 +409,7 @@ class RideItemStepsChanged(RideItem): class RideItemNameChanged(RideItem): """""" - data = ['item', 'old_name'] + data = ['item', 'old_name', 'new_name'] class RideItemSettingsChanged(RideItem): diff --git a/src/robotide/spec/iteminfo.py b/src/robotide/spec/iteminfo.py index bc65ea3f6..8e1f08ba7 100644 --- a/src/robotide/spec/iteminfo.py +++ b/src/robotide/spec/iteminfo.py @@ -38,6 +38,7 @@ def __init__(self, name, source, details): """ self.name = name self.source = source + # print(f"DEBUG: iteminfo.py ItemInfo {name=} {source=}") if details is not None: self.details = details self._priority = PRIORITIES.get(self.__class__, PRIORITIES[ItemInfo]) diff --git a/src/robotide/ui/treenodehandlers.py b/src/robotide/ui/treenodehandlers.py index 5c877fab2..ca8450ef0 100644 --- a/src/robotide/ui/treenodehandlers.py +++ b/src/robotide/ui/treenodehandlers.py @@ -748,6 +748,8 @@ def _add_copy_to_tree(self, parent_node, copied): self._tree.add_keyword(parent_node, copied) def _create_rename_command(self, new_name): + print(f"DEBUG: treenodehandlers.py UserKeywodHandler _create_rename_command controller.name={self.controller.name}" + f", new_name={new_name} info={self.controller.info}") return ctrlcommands.RenameKeywordOccurrences( self.controller.name, new_name, RenameProgressObserver(self._tree.GetParent()), diff --git a/src/robotide/ui/treeplugin.py b/src/robotide/ui/treeplugin.py index d7b990ce5..59c1cacaa 100644 --- a/src/robotide/ui/treeplugin.py +++ b/src/robotide/ui/treeplugin.py @@ -24,6 +24,7 @@ from wx.lib.mixins import treemixin from ..context import IS_WINDOWS +from ..controller import ResourceFileController from ..publish.messages import (RideTestRunning, RideTestPaused, RideTestPassed, RideTestFailed, RideTestSkipped, RideTestExecutionStarted, RideTestStopped, RideImportSetting, RideExcludesChanged, RideIncludesChanged, RideOpenSuite, RideNewProject) @@ -686,7 +687,12 @@ def _filename_changed(self, message): node = self.controller.find_node_by_controller(df) if not node: raise AssertionError('No node found with controller "%s"' % df) + old_name = node.GetText() + print(f"DEBUG: treeplugin.py Tree _filename_changed message={message} df={df}" + f" node={node} {old_name=} df.display_name={df.display_name}") wx.CallAfter(self.SetItemText, node, df.display_name) + if isinstance(df, ResourceFileController): + RideItemNameChanged(item=node, old_name=old_name, new_name=df.display_name).publish() def add_keyword_controller(self, controller): parent = self._get_datafile_node(self.get_selected_datafile()) @@ -1086,6 +1092,7 @@ def on_move_down(self, event): handler.on_move_down(event) def _item_changed(self, message): + print(f"DEBUG: treeplugin.py Tree _item_changed ENTER message={message}") if isinstance(message, RideItemNameChanged): return controller = message.item @@ -1099,25 +1106,31 @@ def _item_changed(self, message): def _item_renamed(self, message): from ..lib.robot.parsing.settings import Resource + print(f"DEBUG: treeplugin.py Tree _item_renamed ENTER message={message}") if not isinstance(message, RideItemNameChanged): return controller = message.item - print(f"DEBUG: treeplugin.py Tree _item_renamed ENTER controller={controller.display_name}") - node = self.controller.find_node_by_controller(controller) - if hasattr(controller.datafile, 'setting_table'): + node = (self.controller.find_node_by_controller(controller) or + self.controller.find_node_with_label(controller, message.old_name)) + print(f"DEBUG: treeplugin.py Tree _item_renamed ENTER controller={controller}" + f" NODE={node}") + if hasattr(controller, 'datafile') and hasattr(controller.datafile, 'setting_table'): imports = controller.datafile.setting_table.imports print(f"DEBUG: treeplugin.py Tree _item_renamed HAS IMPORTS imports={imports}") for imp in imports: - if isinstance(imp, Resource): + if isinstance(imp, Resource) and hasattr(message.item, 'keyword'): print(f"DEBUG: treeplugin.py Tree _item_renamed IMPORT message.item.name={message.item.keyword}," f" old_name={message.old_name} resource name={imp.name}") # print(f"DEBUG: treeplugin.py Tree _item_renamed IMPORT message.item.name={message}," # f" old_name={message.old_name} import={imp}") self._rename_resource_kw(new_name=message.item.keyword, old_name=message.old_name, resource=imp) - # if node and hasattr(message, 'old_name'): - # print(f"DEBUG: treeplugin.py Tree _item_renamed RENAMED node={node}, old_name={message.old_name}") + if node and hasattr(message, 'old_name'): + print(f"DEBUG: treeplugin.py Tree _item_renamed RENAMED node={node}, old_name={message.old_name}\n" + f"new_name={message.new_name}") + # Here we need to rename all resourc prefixed occurrencees + self.Refresh() - if node: + if node and hasattr(message.item, 'name'): self.EnsureVisible(node) self.SelectItem(node) self.SetItemText(node, message.item.name) diff --git a/src/robotide/usages/UsageRunner.py b/src/robotide/usages/UsageRunner.py index a03125f6f..bfa1cdc28 100644 --- a/src/robotide/usages/UsageRunner.py +++ b/src/robotide/usages/UsageRunner.py @@ -20,23 +20,33 @@ from robotide.usages import commands from . import usagesdialog +from ..controller.filecontrollers import ResourceFileController class Usages(object): def __init__(self, controller, highlight, name=None, kw_info=None): self._name = name or controller.name - self._kw_info = kw_info self._controller = controller self._highlight = highlight + if kw_info is None and not isinstance(controller, ResourceFileController): + self._kw_info = self._controller.get_keyword_info(name) + else: + self._kw_info = kw_info # self.prefix = (os.path.basename(self._controller.data.source) # .replace('robot', '').replace('resource', '')).split('.') + if self._kw_info: + self.prefix = self._kw_info.source.replace('robot', '').replace('resource', '').split('.')[0] + else: + self.prefix = os.path.basename(controller.source).split('.')[0] + """ DEBUG self.prefix = os.path.basename(self._controller.data.source).split('.') if len(self.prefix) == 2 and self.prefix[-1] in ['resource', 'robot']: self.prefix = self.prefix[0] else: self.prefix = '' - print(f"DEBUG: UsageRunner.py Usages INIT prefix={self.prefix}") + """ + print(f"DEBUG: UsageRunner.py Usages INIT prefix={self.prefix} {self._kw_info=}") self._dlg = self._usages_dialog() self._worker = Thread(target=self._run) self._dialog_closed = False @@ -45,8 +55,9 @@ def _usages_dialog(self): print(f"DEBUG: UsageRunner.py Usages _usages_dialog ENTER name={self._name}," f" controller_name={self._controller.name} prefix={self.prefix}") if self._controller.name == self._name: - return usagesdialog.UsagesDialogWithUserKwNavigation(self._name, self._highlight, self._controller) - return usagesdialog.UsagesDialog(self._name) + return usagesdialog.UsagesDialogWithUserKwNavigation(self._name, self._highlight, self._controller, + prefix=self.prefix) + return usagesdialog.UsagesDialog(self._name, prefix=self.prefix) def show(self): self._dlg.add_selection_listener(self._highlight) @@ -70,7 +81,7 @@ def _run(self): def _find_usages(self, name): print(f"DEBUG: UsageRunner.py Usages _find_usages ENTER name={name} kw_info={self._kw_info}") - return self._controller.execute(commands.FindUsages(name, self._kw_info)) + return self._controller.execute(commands.FindUsages(name, self._kw_info, prefix=self.prefix)) def _begin_search(self): if not self._dialog_closed: diff --git a/src/robotide/usages/commands.py b/src/robotide/usages/commands.py index 891f35d2f..0190f814a 100644 --- a/src/robotide/usages/commands.py +++ b/src/robotide/usages/commands.py @@ -22,10 +22,15 @@ class FindUsages(FindOccurrences): def execute(self, context): from ..controller.macrocontrollers import KeywordNameController - + print(f"DEBUG: usages/commands.py FindUsages execute context={context}") prev = None for occ in FindOccurrences.execute(self, context): - if isinstance(occ.item, KeywordNameController): + if hasattr(occ, 'item'): + print(f"DEBUG: usages/commands.py FindUsages execute in loop occ={occ.item}") + else: + print(f"DEBUG: usages/commands.py FindUsages execute in loop NOT occ.item occ={occ}") + continue + if hasattr(occ, 'item') and isinstance(occ.item, KeywordNameController): continue if prev == occ: prev.count += 1 diff --git a/src/robotide/usages/usagesdialog.py b/src/robotide/usages/usagesdialog.py index 816853681..3b3315f9e 100644 --- a/src/robotide/usages/usagesdialog.py +++ b/src/robotide/usages/usagesdialog.py @@ -26,7 +26,7 @@ class UsagesDialog(RIDEDialog): - def __init__(self, name, usages=None): + def __init__(self, name, usages=None, prefix=None): self._dots = None self._name = name self._selection_listeners = [] @@ -39,9 +39,8 @@ def __init__(self, name, usages=None): self.SetForegroundColour(Colour(self.color_foreground)) self._add_view_components() self.usages = usages or UsagesListModel([]) - print(f"DEBUG: usagesdialog.py UsagesDialog INIT: usages={self.usages} NAME={name}") - self.usage_list = VirtualList(self, self.usages.headers, - self.usages) + print(f"DEBUG: usagesdialog.py UsagesDialog INIT: usages={self.usages} NAME={name} prefix={prefix}") + self.usage_list = VirtualList(self, self.usages.headers, self.usages) self.usage_list.SetBackgroundColour(Colour(self.color_secondary_background)) self.usage_list.SetForegroundColour(Colour(self.color_secondary_foreground)) self.usage_list.add_selection_listener(self._usage_selected) @@ -78,12 +77,17 @@ def _add_view_components(self): class UsagesDialogWithUserKwNavigation(UsagesDialog): - def __init__(self, name, highlight, controller, usages=None): + def __init__(self, name, highlight, controller, usages=None, prefix=None): + """ import os + if not prefix: + prefix = os.path.basename(controller.source).split('.')[0] + """ print(f"DEBUG: usagesdialog.py UsagesDialogWithUserKwNavigation ENTER name={name}," - f" controller_name={controller.name} usages={usages}") + f" controller_name={controller.name} usages={usages}" + f" source={controller.source} prefix={prefix}") self.on_go_to_definition = lambda evt: highlight(controller, name) - UsagesDialog.__init__(self, name, usages=usages) + UsagesDialog.__init__(self, name, usages=usages, prefix=prefix) def _add_view_components(self): button = ButtonWithHandler(self, _('Go to definition'), mk_handler='Go to definition', diff --git a/utest/controller/test_occurrences.py b/utest/controller/test_occurrences.py index ac2b0abab..be2d6ea56 100644 --- a/utest/controller/test_occurrences.py +++ b/utest/controller/test_occurrences.py @@ -167,11 +167,12 @@ def test_finds_occurrences_that_override_builtin(self): """ # TODO This test fails in Python 3 because of order or returned item @unittest.skip("Sometimes FAILS with Python 3") + """ def test_ignores_definition_in_base_resource(self): self.assert_occurrences(self.resu, 'Keyword In Both Resources', 1) occ = _first_occurrence(self.resu, 'Keyword In Both Resources') - assert_equal(occ.item.parent.source, 'inner_resource.robot') - """ + assert occ.item.parent.source == 'testdata_resource.robot' # was 'inner_resource.robot' + def test_rename_resu_occurrence_in_case_of_double_definition(self): old_name = 'Keyword In Both Resources' diff --git a/utest/controller/test_z_rename_keywords.py b/utest/controller/test_z_rename_keywords.py index fd6e7f747..fa9f979e6 100644 --- a/utest/controller/test_z_rename_keywords.py +++ b/utest/controller/test_z_rename_keywords.py @@ -16,7 +16,10 @@ import os import sys import unittest -from robotide.controller.ctrlcommands import RenameKeywordOccurrences, NullObserver +from robotide.controller.ctrlcommands import (Undo, FindOccurrences, FindVariableOccurrences, NullObserver, + RenameKeywordOccurrences, ChangeCellValue) +from robotide.controller.macrocontrollers import KeywordNameController + from .base_command_test import TestCaseCommandTest from utest.resources import datafilereader @@ -216,6 +219,15 @@ def OnExit(self): # Overrides wx method # self.Destroy() +def _first_occurrence(test_ctrl, kw_name): + occurrences = test_ctrl.execute(FindOccurrences(kw_name)) + if not occurrences: + raise AssertionError('No occurrences found for "%s"' % kw_name) + return next(occurrences) + # see https://stackoverflow.com/questions/21622193/ + # python-3-2-coroutine-attributeerror-generator-object-has-no-attribute-next + + class TestRenameResourcePrefixedKeywords(unittest.TestCase): def setUp(self): @@ -254,8 +266,11 @@ def setUp(self): # self.editor = self.plugin.get_editor(TestCase) # Moved to test # self.plugin.enable() - self.project_ctrl = self.app.project.load_datafile(datafilereader.RESOURCE_PREFIXED_KEYWORDS_PATH, - MessageRecordingLoadObserver()) + # self.project_ctrl = self.app.project.load_datafile(datafilereader.RESOURCE_PREFIXED_KEYWORDS_PATH, + # MessageRecordingLoadObserver()) + self.app.project.load_datafile(datafilereader.RESOURCE_PREFIXED_KEYWORDS_PATH, MessageRecordingLoadObserver()) + testcase = TestDataDirectory(source=datafilereader.RESOURCE_PREFIXED_KEYWORDS_PATH, language=['English']) + self.project_ctrl = TestDataDirectoryController(testcase, self.app.project) # self.app.tree.set_editor(self.plugin._editor_component) print(f"DEBUG: setUp() dir self.project_ctrl ={dir(self.project_ctrl)}" f"\nself.app.project={dir(self.app.project)} ") @@ -323,6 +338,7 @@ def tearDown(self): shutil.rmtree(DATADIR, ignore_errors=True) def test_rename_suite_setup_kw(self): + """ ts_list = [] if isinstance(self.ts1, list): for x in self.ts1: @@ -335,11 +351,11 @@ def test_rename_suite_setup_kw(self): print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw" f" type(x)={type(x)} res_list={self.res00}\n") for y in x.keywords: - res_list.append(y) + res_list.append(y) else: for x in self.res00.keywords: print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw" - f" NOT LIST BRANCH type(x)={type(x)} res_list={x.steps}\n") + f" NOT LIST BRANCH type(x)={type(x)} res_list={x.steps}\n") res_list.append(x) if isinstance(self.res01, list): for x in self.res01: @@ -368,6 +384,7 @@ def test_rename_suite_setup_kw(self): ts_list.extend([s for s in x.tests.items]) else: ts_list.append(self.ts3.tests.items) + """ # settings = self.suites[0].setting_table # suite_setup = settings.suite_setup.as_list() # print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw" @@ -380,6 +397,7 @@ def test_rename_suite_setup_kw(self): print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw" f" type(ts3_list)={type(ts3_list)} ts3_list={ts3_list}\n") """ + """ assert ts_list is not None assert res_list is not None steps = [] @@ -391,6 +409,7 @@ def test_rename_suite_setup_kw(self): print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw" f" all steps ={steps[:]}\n") """ + """ for test in self.ts1: print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw ts1 ={test.name} " f"source ={test.source}") @@ -399,8 +418,47 @@ def test_rename_suite_setup_kw(self): for kw in res_list: print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw resource kw={kw}") """ + occ_list = [] + print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw controller={self.project_ctrl.datafiles}") + for obj in self.project_ctrl.datafiles: + print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw retrieve_test_controllers" + f" obj={obj.display_name} source={obj.source} type={type(obj)}") + occurrences = obj.execute(FindOccurrences("keyword2")) + # print(occurrences) + occ_list.extend(occurrences) + + print(f"Before Rename occ_list={occ_list}\n" + f" len={len(occ_list)}") + # for occ in occ_list: + # print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw FindOccurrences occ={occ}") + # f" {occ.item}") + observer = NullObserver() myobject = RenameKeywordOccurrences("keyword2", "kywd2", observer) + print(f"Result from Rename myobject={myobject}") # self.project_ctrl.datafiles: self.app.project.datafiles + for obj in self.app.project.datafiles: + myobject.execute(obj) + print(f"DEBUG: TestRenameResourcePrefixedKeywords AFTER RENAME\n" + f"is_dirty? {self.app.project.is_dirty()}") + + rocc_list = [] + for obj in self.project_ctrl.datafiles: + occurrences = obj.execute(FindOccurrences("keyword2")) + rocc_list.extend(occurrences) + print(f"After Result from Rename rocc_list={rocc_list} len={len(rocc_list)}") + for occ in rocc_list: + print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw FindOccurrences occ={occ}") + + """ + occurrences = self.project_ctrl.execute(FindOccurrences("keyword2")) + occ = _first_occurrence(self.project_ctrl, 'keyword2') + print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw Called _first_occurrence_first_occurrence" + 3 f" occ={occ.item}") + # assert occ.item.parent.source == 'testdata_resource.robot' + print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw Called FindOccurrences occurrences={occurrences}") + for occ in occurrences: + print(f"DEBUG: TestRenameResourcePrefixedKeywords test_rename_suite_setup_kw FindOccurrences occ={occ}" + f" {occ.source}") myobject.execute(self.ts1[0]) myobject.execute(self.ts1[1]) @@ -408,7 +466,9 @@ def test_rename_suite_setup_kw(self): myobject.execute(self.res00) myobject.execute(self.res01) myobject.execute(self.res02) + """ + exit(0) # myobject.execute(self.project_ctrl.setting_table) # After Rename self._get_controllers() diff --git a/utest/resources/robotdata/TestCases/Sub/resources/res02.resource b/utest/resources/robotdata/TestCases/Sub/resources/res02.resource index 9838b522e..bc3be8cab 100644 --- a/utest/resources/robotdata/TestCases/Sub/resources/res02.resource +++ b/utest/resources/robotdata/TestCases/Sub/resources/res02.resource @@ -4,7 +4,7 @@ Library ./res.py *** Keywords *** keyword1 [Arguments] ${a} - log ${a} + log ${a} This is at Sub/Resources/res02.resource Run Keyword keyword3 keyword2 diff --git a/utest/resources/robotdata/TestCases/suite01.robot b/utest/resources/robotdata/TestCases/suite01.robot index 9fabf2516..03e9a36ca 100644 --- a/utest/resources/robotdata/TestCases/suite01.robot +++ b/utest/resources/robotdata/TestCases/suite01.robot @@ -21,3 +21,4 @@ case03 res02.keyword3 res01.keyword3 Run Keyword external_res.keyword3 + external_res.keyword1 teste diff --git a/utest/resources/robotdata/resources/external_res.resource b/utest/resources/robotdata/resources/external_res.resource index 20ca61cd0..d8935ab57 100644 --- a/utest/resources/robotdata/resources/external_res.resource +++ b/utest/resources/robotdata/resources/external_res.resource @@ -14,7 +14,13 @@ keyword2 [Arguments] ${a} log ${a} Log To Console This is the argument \${a} = ${a} ! + [Teardown] keyword1 Called from external_resource at Teardown kw2 keyword3 + [Setup] res02.keyword3 keyword1 Called from external_resource res02.keyword1 Called from external_resource # Kw from res2 with a space in calling + +unusedkw + [Arguments] ${notused}=None + Log This is not used