Skip to content

Commit

Permalink
Fix multiline vars add new option for RF 7 (#2814)
Browse files Browse the repository at this point in the history
* Fix multiline vars add new option for RF 7

* Ommit continuation markers in Variables section. WIP Properties editor and Text

* Fix dialog editor for multiline scalars. Separate by pipe.

* Separate multiline variables at Text Editor
  • Loading branch information
HelioGuilherme66 authored Jun 29, 2024
1 parent 3034379 commit 085addf
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 25 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Tools->Preferences->General.

=== Fixed

- Fixed multiline variables in Variables section. In Text Editor they are separated by ... continuation marker.
In Grid Editor use | (pipe) to separate lines.
- Fixed keywords Find Usages in Grid Editor not finding certain values when using Gherkin.
- Fixed plugin Run Anything (Macros) not showing output and broken actions.
- Fixed headers and blank spacing in Templated tests
Expand Down
2 changes: 1 addition & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Likewise, the current version of wxPython, is 4.2.1, but RIDE is known to work w

`pip install -U robotframework-ride`

(3.8 < python &lt;= 3.12) Install current development version (**2.1dev53**) with:
(3.8 < python &lt;= 3.12) Install current development version (**2.1dev54**) with:

`pip install -U https://github.com/robotframework/RIDE/archive/master.zip`

Expand Down
3 changes: 3 additions & 0 deletions src/robotide/application/CHANGELOG.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
</li><li class="listitem">
Colorization for language configured files is working in Text Editor.
</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_fixed"></a>1.2. Fixed</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Fixed multiline variables in Variables section. In Text Editor they are separated by … continuation marker.
In Grid Editor use | (pipe) to separate lines.
</li><li class="listitem">
Fixed keywords Find Usages in Grid Editor not finding certain values when using Gherkin.
</li><li class="listitem">
Fixed plugin Run Anything (Macros) not showing output and broken actions.
Expand Down
4 changes: 3 additions & 1 deletion src/robotide/application/releasenotes.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ def set_content(self, html_win, content):
</ul>
<p><strong>New Features and Fixes Highlights</strong></p>
<ul class="simple">
<li>Fixed multiline variables in Variables section. In Text Editor they are separated by ... continuation marker.
In Grid Editor use | (pipe) to separate lines.</li>
<li>Added support for new VAR marker, since Robot Framework version 7.0.</li>
<li>Added configurable style of the tabs in notebook pages, Edit, Text, Run, etc. Parameter <b>notebook theme</b>
takes values from 0 to 5. See wxPython, demo for agw.aui for details.</li>
Expand Down Expand Up @@ -305,7 +307,7 @@ def set_content(self, html_win, content):
<pre class="literal-block">
python -m robotide.postinstall -install
</pre>
<p>RIDE {VERSION} was released on 23/June/2024.</p>
<p>RIDE {VERSION} was released on 29/June/2024.</p>
<!-- <br/>
<h3>May The Fourth Be With You!</h3>
<h3>Celebrate the bank holiday, 10th June, Day of Portugal, Portuguese Communities and Camões!!</h3>
Expand Down
6 changes: 3 additions & 3 deletions src/robotide/editor/editordialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ def __init__(self, controller, item=None, plugin=None, title=None):

def _get_editors(self, var):
name = var.name if var and var.name else '${}'
value = var.value[0] if var else ''
value = utils.join_value(var.value) if var else ''
# print(f"DEBUG: editor.editordialogs.py ScalarVariableDialog _get_editors value={value}")
validator = ScalarVariableNameValidator(self._controller, name)
return [VariableNameEditor(self, name, _('Name'), validator),
ValueEditor(self, value, _('Value'))]
return [VariableNameEditor(self, name, _('Name'), validator), ValueEditor(self, value, _('Value'), split=True)]

def _execute(self):
""" Just ignore it """
Expand Down
10 changes: 7 additions & 3 deletions src/robotide/editor/fieldeditors.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from ..context import ctrl_or_cmd, bind_keys_to_evt_menu
from ..editor.contentassist import ContentAssistFileButton
from ..namespace.suggesters import SuggestionSource
from ..utils import split_value
from ..widgets import Label

_ = wx.GetTranslation # To keep linter/code analyser happy
Expand All @@ -34,10 +35,10 @@ class ValueEditor(wx.Panel):
_sizer_flags_for_editor = wx.ALL
_sizer_flags_for_label = wx.ALL

def __init__(self, parent, value, label=None, validator=None,
settings=None):
def __init__(self, parent, value, label=None, validator=None, settings=None, split=False):
wx.Panel.__init__(self, parent)
self._label = label
self.split = split
self._sizer = wx.BoxSizer(wx.VERTICAL)
from ..preferences import RideSettings
_settings = RideSettings()
Expand Down Expand Up @@ -80,7 +81,10 @@ def set_validator(self, validator):

def get_value(self):
# print("DEBUG: ValueEditor get_value: %s" % self.source_editor.GetValue())
return self._editor.GetValue()
value = self._editor.GetValue()
if not self.split:
return value
return split_value(value)

def set_focus(self):
self._editor.SetFocus()
Expand Down
10 changes: 9 additions & 1 deletion src/robotide/lib/robot/parsing/tablepopulators.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,14 @@ def __init__(self, setter):
self._value = []
self._comments = Comments()
self._data_added = False
self.row_continue = False

def add(self, row):
if isinstance(self, VariablePopulator):
if row.head == '...':
self.row_continue = True
else:
self.row_continue = False
if not row.is_commented():
self._add(row)
if row.head.startswith('#') and not isinstance(self, VariablePopulator):
Expand All @@ -303,7 +309,7 @@ def add(self, row):
def _add(self, row):
if row.cells == ['...']:
self._deprecate_continuation_without_values()
self._value.extend(row.tail if not self._data_added else row.data)
self._value.extend(row.tail if self.row_continue or not self._data_added else row.data)
# print(f"DEBUG: tablepopulators.py _PropertyPopulator {self._data_added=} _add row.cells={row.cells}"
# f" ADDED value={self._value}")
self._data_added = True
Expand All @@ -325,6 +331,8 @@ def __init__(self, setter, name):
self._name = name

def populate(self):
# print(f"DEBUG: tablepopulators.py VariablePopulator populate {self._data_added=}"
# f" varaible name={self._name} current value={self._value} setter={self._setter}")
self._setter(self._name, self._value, self._comments.value)

def _get_deprecation_location(self):
Expand Down
28 changes: 19 additions & 9 deletions src/robotide/lib/robot/variables/tablesetter.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,17 @@ def read(self, variables):
except DataError as err:
var.report_invalid_syntax(err)

def get_name_and_value(self, name, value, error_reporter):
@staticmethod
def get_name_and_value(name, value, error_reporter):
return name[2:-1], VariableTableValue(value, name, error_reporter)


def VariableTableValue(value, name, error_reporter=None):
validate_var(name)
VariableTableValue = {'$': ScalarVariableTableValue,
variabletablevalue = {'$': ScalarVariableTableValue,
'@': ListVariableTableValue,
'&': DictVariableTableValue}[name[0]]
return VariableTableValue(value, error_reporter)
return variabletablevalue(value, error_reporter)


class VariableTableValueBase(object):
Expand Down Expand Up @@ -95,9 +96,15 @@ def _format_values(self, values):
separator = None
if is_string(values):
values = [values]
elif values and values[0].startswith('SEPARATOR='):
separator = values[0][10:]
values = values[1:]
elif values:
if values[0].startswith('SEPARATOR='):
separator = values[0][10:]
values = values[1:]
elif values[-1].startswith('separator='): # New in RF 7.0
separator = values[-1][10:]
values = values[:-2]
# if '...' in values:
# values = [elem for elem in values if elem != '...']
return separator, values

def _replace_variables(self, values, variables):
Expand All @@ -111,7 +118,8 @@ def _replace_variables(self, values, variables):
values = variables.replace_list(values)
return separator.join(unic(item) for item in values)

def _is_single_value(self, separator, values):
@staticmethod
def _is_single_value(separator, values):
return (separator is None and len(values) == 1 and
not VariableSplitter(values[0]).is_list_variable())

Expand All @@ -127,7 +135,8 @@ class DictVariableTableValue(VariableTableValueBase):
def _format_values(self, values):
return list(self._yield_formatted(values))

def _yield_formatted(self, values):
@staticmethod
def _yield_formatted(values):
for item in values:
if VariableSplitter(item).is_dict_variable():
yield item
Expand All @@ -145,7 +154,8 @@ def _replace_variables(self, values, variables):
except TypeError as err:
raise DataError('Creating dictionary failed: %s' % err)

def _yield_replaced(self, values, replace_scalar):
@staticmethod
def _yield_replaced(values, replace_scalar):
for item in values:
if isinstance(item, tuple):
key, values = item
Expand Down
25 changes: 19 additions & 6 deletions src/robotide/lib/robot/writer/rowsplitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ class RowSplitter(object):
_line_continuation = '...'
setting_table = 'setting'
_indented_tables = ('test case', 'keyword')
_split_from = ('ELSE', 'ELSE IF', 'AND')
_split_from = ('ELSE', 'ELSE IF', 'AND', 'VAR')

def __init__(self, cols=8, split_multiline_doc=False, language=None):
def __init__(self, cols=8, split_multiline_doc=False, split_multiline_var=True, language=None):
self._cols = cols
self._split_multiline_doc = split_multiline_doc
self._split_multiline_var = split_multiline_var
self._language = language
self._table_type = None

def split(self, row, table_type):
self._table_type = table_type
if not row:
return self._split_empty_row()
indent = self._get_indent(row, table_type)
Expand All @@ -44,6 +47,7 @@ def _split_empty_row():

def _get_indent(self, row, table_type):
indent = self._get_first_non_empty_index(row)
# print(f"DEBUG: rowsplitter.py RowSplitter _get_indent indent={indent} row={row} ")
min_indent = 1 if table_type in self._indented_tables else 0
return max(indent, min_indent)

Expand Down Expand Up @@ -78,15 +82,24 @@ def _split_doc(doc):
return doc.split('\\n', 1)

def _split_row(self, row, indent):
if self._table_type == 'variable' and self._split_multiline_var:
# print(f"DEBUG: rowsplitter.py RowSplitter _split_row tabel Variable row={row}")
split_at = 2
else:
split_at = None
while row:
current, row = self._split(row)
# print(f"DEBUG: rowsplitter.py RowSplitter _split_row current={current} row={row}")
current, row = self._split(row, forced_index=split_at)
# print(f"DEBUG: rowsplitter.py RowSplitter _split_row current={current} row={row} table "
# f"type={self._table_type}")
yield self._escape_last_cell_if_empty(current)
if row:
row = self._continue_row(row, indent)

def _split(self, data):
index = min(self._get_possible_split_indices(data))
def _split(self, data, forced_index=None):
if not forced_index:
index = min(self._get_possible_split_indices(data))
else:
index = forced_index if len(data) > forced_index else min(self._get_possible_split_indices(data))
current, rest = data[:index], data[index:]
rest = self._comment_rest_if_needed(current, rest)
return current, rest
Expand Down
2 changes: 1 addition & 1 deletion src/robotide/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
#
# Automatically generated by `tasks.py`.

VERSION = 'v2.1dev53'
VERSION = 'v2.1dev54'

0 comments on commit 085addf

Please sign in to comment.