Skip to content

Commit b98739c

Browse files
Kweditor tests (#2595)
* Experimental unit test for kweditor * Increase unit tests, fix 2 issues * Increases tests. One test fails with invoke but not with PyCharm * Try to fix running all tests (no success) * Improve code and unit tests * Increase unit tests * Increase tests, increase fails * Remove debug info
1 parent b3e3794 commit b98739c

File tree

15 files changed

+676
-125
lines changed

15 files changed

+676
-125
lines changed

.coveragerc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ omit =
1515

1616
[report]
1717
skip_empty = True
18+
exclude_lines =
19+
if __name__ == '__main__':
1820

1921
[xml]
2022
output = ./.coverage-reports/coverage.xml

src/robotide/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
import wx
4545
import wx.lib.inspection
4646
from wx import Colour
47-
except ImportError:
47+
except ModuleNotFoundError:
4848
print(errorMessageTemplate.substitute(reason="wxPython not found."))
4949
sys.exit(1)
5050

@@ -86,6 +86,7 @@ def _parse_args(args):
8686

8787

8888
def _run(inpath=None, updatecheck=True, debug_console=False):
89+
# print(f"DEBUG: ENTER _run {inpath=}, {updatecheck=}, {debug_console=}")
8990
try:
9091
from robotide.application import RIDE
9192
from robotide.application import debugconsole
@@ -132,6 +133,7 @@ def writelines(self, sequence):
132133

133134

134135
def _show_old_wxpython_warning_if_needed(parent=None):
136+
# print("DEBUG: ENTER _show_old_wxpython_warning_if_needed")
135137
if wx.VERSION <= (4, 0, 4, '', ''):
136138
title = "Please upgrade your wxPython installation"
137139
message = ("RIDE needs a newer wxPython version. Your current "

src/robotide/controller/filecontrollers.py

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,19 @@ def remove_readonly(self, path=None):
323323
path = path or self.filename
324324
os.chmod(path, stat.S_IWRITE)
325325

326+
@staticmethod
327+
def _explorer_linux(path):
328+
try:
329+
subprocess.Popen(["nautilus", "{}".format(os.path.dirname(path))])
330+
except OSError:
331+
try:
332+
subprocess.Popen(["dolphin", "{}".format(os.path.dirname(path))])
333+
except OSError:
334+
try:
335+
subprocess.Popen(["konqueror", "{}".format(os.path.dirname(path))])
336+
except OSError:
337+
print("Could not launch explorer. Tried nautilus, dolphin and konqueror.")
338+
326339
def open_filemanager(self, path=None):
327340
# tested on Win7 x64
328341
path = path or self.filename
@@ -336,28 +349,12 @@ def open_filemanager(self, path=None):
336349
# nautilus, dolphin, konqueror
337350
# DEBUG: check if explorer exists
338351
# DEBUG: get prefered explorer from preferences
339-
try:
340-
subprocess.Popen(["nautilus", "{}".format(
341-
os.path.dirname(path))])
342-
except OSError:
343-
try:
344-
subprocess.Popen(
345-
["dolphin", "{}".format(os.path.dirname(path))])
346-
except OSError:
347-
try:
348-
subprocess.Popen(
349-
["konqueror", "{}".format(
350-
os.path.dirname(path))])
351-
except OSError:
352-
print("Could not launch explorer. Tried nautilus, "
353-
"dolphin and konqueror.")
352+
self._explorer_linux(path)
354353
else:
355354
try:
356-
subprocess.Popen(["finder", "{}".format(
357-
os.path.dirname(path))])
355+
subprocess.Popen(["finder", "{}".format(os.path.dirname(path))])
358356
except OSError:
359-
subprocess.Popen(["open", "{}".format(
360-
os.path.dirname(path))])
357+
subprocess.Popen(["open", "{}".format(os.path.dirname(path))])
361358

362359
def remove_from_filesystem(self, path=None):
363360
path = path or self.filename

src/robotide/controller/settingcontrollers.py

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,12 @@
1515

1616
import re
1717
from itertools import chain
18-
from os import linesep
1918

2019
from .. import robotapi, utils
2120
from ..robotapi import ALIAS_MARKER
2221
from ..publish.messages import (RideImportSettingChanged, RideImportSettingRemoved, RideVariableUpdated,
2322
RideItemSettingsChanged, RideImportSettingAdded)
24-
from ..utils import variablematcher
23+
from ..utils import variablematcher, unescape_newlines_and_whitespaces
2524
from .basecontroller import ControllerWithParent
2625
from .tags import Tag, ForcedTag, DefaultTag
2726

@@ -138,7 +137,7 @@ def contains_keyword(self, name):
138137
return False
139138

140139
def _get_editable_value(self):
141-
return self._unescape_newlines_and_whitespaces(self.value)
140+
return unescape_newlines_and_whitespaces(self.value)
142141

143142
def _set_editable_value(self, value):
144143
self.set_value(self._escape_newlines_and_leading_hash(value))
@@ -149,27 +148,6 @@ def _set_editable_value(self, value):
149148
def visible_value(self):
150149
return utils.html_format(utils.unescape(self.value))
151150

152-
def _unescape_newlines_and_whitespaces(self, item):
153-
for regexp in self._regexps:
154-
if regexp.pattern.endswith(' '):
155-
item = regexp.sub(self._whitespace_replacer, item)
156-
else:
157-
item = regexp.sub(self._newline_replacer, item)
158-
return item
159-
160-
def _whitespace_replacer(self, match):
161-
return self._replacer(' ', match)
162-
163-
def _newline_replacer(self, match):
164-
return self._replacer(linesep, match)
165-
166-
@staticmethod
167-
def _replacer(char, match):
168-
slashes = len(match.group(1))
169-
if slashes % 2 == 1:
170-
return '\\' * (slashes - 1) + char
171-
return match.group()
172-
173151
@staticmethod
174152
def _escape_newlines_and_leading_hash(item):
175153
for newline in ('\r\n', '\n', '\r'):

src/robotide/editor/gridbase.py

Lines changed: 21 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,14 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
import re
17-
from os import linesep
18-
1916
import wx
2017
from wx import grid, Colour
2118

2219
from .clipboard import ClipboardHandler
2320
from ..context import IS_WINDOWS
21+
from ..utils import unescape_newlines_and_whitespaces
2422
from ..widgets import PopupCreator, PopupMenuItems
2523

26-
# FILTER_NEWLINES = True
27-
2824

2925
class GridEditor(grid.Grid):
3026
_col_add_threshold = 6
@@ -33,10 +29,6 @@ class GridEditor(grid.Grid):
3329
'Insert Rows\tCtrl-I', 'Delete Rows\tCtrl-D', '---',
3430
'Select All\tCtrl-A', '---', 'Cut\tCtrl-X', 'Copy\tCtrl-C',
3531
'Paste\tCtrl-V', 'Insert\tCtrl-Shift-V', '---', 'Delete\tDel']
36-
_regexps = (re.compile(r'(\\+)r\\n'),
37-
re.compile(r'(\\+)n'),
38-
re.compile(r'(\\+)r'),
39-
re.compile(r'(\\+) '))
4032

4133
def __init__(self, parent, num_rows, num_cols, popup_creator=None):
4234
grid.Grid.__init__(self, parent)
@@ -86,35 +78,15 @@ def write_cell(self, row, col, value, update_history=True):
8678
self._expand_if_necessary(row, col)
8779
if self.filter_newlines:
8880
# unescape \n to support multi lines display in grid cells
89-
value = self._unescape_newlines_and_whitespaces(value)
81+
value = unescape_newlines_and_whitespaces(value)
9082
self.SetCellValue(row, col, value)
9183

92-
def _unescape_newlines_and_whitespaces(self, item):
93-
for regexp in self._regexps:
94-
if regexp.pattern.endswith(' '):
95-
item = regexp.sub(self._whitespace_replacer, item)
96-
else:
97-
item = regexp.sub(self._newline_replacer, item)
98-
return item
99-
100-
def _whitespace_replacer(self, match):
101-
return self._replacer(' ', match)
102-
103-
def _newline_replacer(self, match):
104-
return self._replacer(linesep, match)
105-
106-
def _replacer(self, char, match):
107-
slashes = len(match.group(1))
108-
if slashes % 2 == 1:
109-
return '\\' * (slashes - 1) + char
110-
return match.group()
111-
11284
def _expand_if_necessary(self, row, col):
11385
# Changed col and row fill because of blank spacing not changing color
11486
# print(f"DEBUG: GridEditor ENTER_expand_if_necessary row={row}, col={col}")
115-
while self.NumberRows <= max(1, row+1, 10-row): # DEBUG 25 makes slower rendering
87+
while self.NumberRows <= max(1, row+1, 10-row): # DEBUG 25 makes slower rendering
11688
self.AppendRows(1)
117-
while self.NumberCols <= max(1, col+1, 10-col): # DEBUG 40 makes slower rendering
89+
while self.NumberCols <= max(1, col+1, 10-col): # DEBUG 40 makes slower rendering
11890
self.AppendCols(max(1, self._col_add_threshold)) # DEBUG: was infinite when value was 0
11991

12092
def has_focus(self):
@@ -192,9 +164,10 @@ def _current_cell_value(self):
192164

193165
def _get_block_content(self, row_range, col_range):
194166
return [[self.GetCellValue(row, col) for col in col_range]
195-
for row in row_range]
167+
for row in row_range]
196168

197-
def _strip_trailing_empty_cells(self, rowdata):
169+
@staticmethod
170+
def _strip_trailing_empty_cells(rowdata):
198171
while rowdata and not rowdata[-1]:
199172
rowdata.pop()
200173
return rowdata
@@ -234,23 +207,23 @@ def OnRangeSelect(self, event):
234207
self._ensure_selected_row_is_visible(event.BottomRow)
235208

236209
def _ensure_selected_row_is_visible(self, bottom_row):
237-
if not self.IsVisible(bottom_row , 0) and bottom_row < self.NumberRows and \
210+
if not self.IsVisible(bottom_row, 0) and bottom_row < self.NumberRows and \
238211
self._is_whole_row_selection():
239212
self.MakeCellVisible(bottom_row, 0)
240213

241214
def OnCellRightClick(self, event):
242215
if hasattr(event, 'Row') and hasattr(event, 'Col'):
243-
if not (event.Row, event.Col) in self.selection.cells():
216+
if (event.Row, event.Col) not in self.selection.cells():
244217
self.select(event.Row, event.Col)
245218
self.selection.set_from_single_selection(event)
246219
self._popup_creator.show(self, PopupMenuItems(self, self._popup_items),
247220
self.get_selected_content())
248221

249-
# TODO This code is overriden at fieldeditors
222+
# DEBUG: This code is overriden at fieldeditors
250223
def OnInsertCells(self, event):
251224
self._insert_or_delete_cells(self._insert_cells, event)
252225

253-
# TODO This code is overriden at fieldeditors
226+
# DEBUG:This code is overriden at fieldeditors
254227
def OnDeleteCells(self, event):
255228
# print("DEBUG delete cells %s" % event)
256229
self._insert_or_delete_cells(self._delete_cells, event)
@@ -291,13 +264,13 @@ def _refresh_layout(self):
291264
self.GetParent().Sizer.Layout()
292265

293266

294-
# TODO: refactor this internal state away if possible
267+
# DEBUG: refactor this internal state away if possible
295268
class _GridSelection(object):
296269
cell = property(lambda self: (self.topleft.row, self.topleft.col))
297270

298-
def __init__(self, grid):
271+
def __init__(self, gridd):
299272
self._set((0, 0))
300-
self._grid = grid
273+
self._grid = gridd
301274

302275
def _set(self, topleft, bottomright=None):
303276
self.topleft = _Cell(topleft[0], topleft[1])
@@ -312,18 +285,19 @@ def _count_bottomright(self, topleft, bottomright):
312285
def set_from_single_selection(self, event):
313286
self._set((event.Row, event.Col))
314287

315-
def set_from_range_selection(self, grid, event):
316-
self._set(*self._get_bounding_coordinates(grid, event))
288+
def set_from_range_selection(self, gridd, event):
289+
self._set(*self._get_bounding_coordinates(gridd, event))
317290

318291
def clear(self):
319292
selection = (self._grid.GetGridCursorRow(), self._grid.GetGridCursorCol())
320293
self._set(selection)
321294

322-
def _get_bounding_coordinates(self, grid, event):
323-
whole_row_selection = sorted(grid.SelectedRows)
295+
@staticmethod
296+
def _get_bounding_coordinates(gridd, event):
297+
whole_row_selection = sorted(gridd.SelectedRows)
324298
if whole_row_selection:
325299
return (whole_row_selection[0], 0), \
326-
(whole_row_selection[-1], grid.NumberCols - 1)
300+
(whole_row_selection[-1], gridd.NumberCols - 1)
327301
return (event.TopLeftCoords.Row, event.TopLeftCoords.Col), \
328302
(event.BottomRightCoords.Row, event.BottomRightCoords.Col)
329303

@@ -338,7 +312,7 @@ def cols(self):
338312
def cells(self):
339313
"""Return selected cells as a list of tuples (row, column)."""
340314
return [(row, col) for col in self.cols()
341-
for row in self.rows()]
315+
for row in self.rows()]
342316

343317

344318
class _Cell(object):

src/robotide/editor/kweditor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
from wx import grid
2121
from wx.grid import GridCellEditor
2222

23+
from os import linesep
2324
from .contentassist import ExpandingContentAssistTextCtrl
2425
from .editordialogs import UserKeywordNameDialog, ScalarVariableDialog, ListVariableDialog
25-
from .gridbase import GridEditor, linesep
26+
from .gridbase import GridEditor
2627
from .gridcolorizer import Colorizer
2728
from .tooltips import GridToolTips
2829
from .. import robotapi
@@ -42,7 +43,6 @@
4243
from ..widgets import RIDEDialog, PopupMenu, PopupMenuItems
4344

4445
_DEFAULT_FONT_SIZE = 11
45-
# FILTER_NEWLINES = True
4646

4747

4848
def requires_focus(function):

src/robotide/utils/__init__.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# limitations under the License.
1515

1616
import os
17+
import re
1718
import sys
1819
import inspect
1920
import subprocess
@@ -106,7 +107,7 @@ def is_same_drive(path1, path2):
106107

107108
def run_python_command(command, mode='c'):
108109
cmd = [sys.executable, '-{0}'.format(mode)] + command
109-
# TODO Let the user select which robot to use
110+
# DEBUG: Let the user select which robot to use
110111
process = subprocess.Popen(
111112
cmd,
112113
stdout=subprocess.PIPE,
@@ -132,3 +133,33 @@ def converttypes(data, prefer_str=True):
132133
if data_type == dict:
133134
data = data.items()
134135
return data_type(map(converttypes, data))
136+
137+
138+
_regexps = (re.compile(r'(\\+)r\\n'),
139+
re.compile(r'(\\+)n'),
140+
re.compile(r'(\\+)r'),
141+
re.compile(r'(\\+) '))
142+
143+
144+
def unescape_newlines_and_whitespaces(item):
145+
for regexp in _regexps:
146+
if regexp.pattern.endswith(' '):
147+
item = regexp.sub(_whitespace_replacer, item)
148+
else:
149+
item = regexp.sub(_newline_replacer, item)
150+
return item
151+
152+
153+
def _whitespace_replacer(match):
154+
return _replacer(' ', match)
155+
156+
157+
def _newline_replacer(match):
158+
return _replacer(os.linesep, match)
159+
160+
161+
def _replacer(char, match):
162+
slashes = len(match.group(1))
163+
if slashes % 2 == 1:
164+
return '\\' * (slashes - 1) + char
165+
return match.group()

src/robotide/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414
# limitations under the License.
1515
#
1616
# Automatically generated by `tasks.py`.
17-
VERSION = 'v2.0.6dev3'
17+
VERSION = 'v2.0.6dev4'

0 commit comments

Comments
 (0)