1
# vim: noexpandtab:ts=4:sw=4
2
# This file is part of ReText
3
# Copyright: Maurice van der Pot 2014
4
# License: GNU GPL v2 or higher
7
from ReText import tablemode
10
class TestTableMode(unittest.TestCase):
12
def performEdit(self, text, offset, editSize, paddingchar=None, fragment=None):
14
text = text[:offset + editSize] + text[offset:]
16
fragment = paddingchar * editSize if not fragment else fragment
17
text = text[:offset] + fragment + text[offset:]
20
def checkDetermineEditLists(self, paddingChars, before, edit, after):
22
def __init__(self, text, separatorLine, paddingChar):
24
self.separatorline = separatorLine
25
self.paddingchar = paddingChar
28
# Do some sanity checks on the test data to catch simple mistakes
29
self.assertEqual(len(paddingChars), len(before),
30
'The number of padding chars should be equal to the number of rows')
31
self.assertEqual(len(before), len(after),
32
'The number of rows before and after should be the same')
33
# Apart from spacing edit only contains a's or d's
34
self.assertTrue(edit[1].strip(' d') == '' or
35
edit[1].strip(' a') == '',
36
"An edit should be a sequence of a's or d's surrounded by spaces")
39
for paddingChar, text in zip(paddingChars, before):
40
rows.append(Row(text, (paddingChar != ' '), paddingChar))
43
editstripped = edit[1].strip()
44
editsize = len(editstripped)
46
# The offset passed to _determineEditLists is the one received from the
47
# contentsChange signal and is always the start of the set of chars
48
# that are added or removed.
49
contentsChangeOffset = edit[1].index(editstripped[0])
51
# However, the editoffset indicates the position before which chars
52
# must be deleted or after which they must be added (just like the
53
# offset used in the edits returned by _determineEditLists),
54
# so for deletions we'll need to add the size of the edit to it
55
if editstripped[0] == 'd':
57
editoffset = contentsChangeOffset + len(editstripped)
59
editoffset = contentsChangeOffset
61
editLists = tablemode._determineEditLists(rows, edit[0], contentsChangeOffset, editsize)
66
self.assertEqual(len(editLists), len(rows))
68
for i, (row, editList) in enumerate(zip(rows, editLists)):
71
for editEntry in editList:
72
editedText = self.performEdit(editedText, editEntry[0], editEntry[1], paddingchar=row.paddingchar)
74
editedRows.append(editedText)
76
editedRows[editedline] = self.performEdit(editedRows[editedline], editoffset, editsize, fragment=editstripped)
78
if editedRows != after:
79
assertMessage = ["Output differs.",
82
["%3d '%s'" % (i, line) for i, line in enumerate(before)] + \
87
"Expected output:"] + \
88
["%3d '%s'" % (i, line) for i, line in enumerate(after)] + \
91
["%3d '%s'" % (i, line) for i, line in enumerate(editedRows)]
93
self.fail('\n'.join(assertMessage))
95
def test_simpleInsert(self):
96
# Insert at the start of a cell so it doesn't need to grow
106
self.checkDetermineEditLists(separatorChars, before, edit, after)
108
# Insert at the last position in a cell where it doesn't need to grow
118
self.checkDetermineEditLists(separatorChars, before, edit, after)
120
# Insert at the end of a cell so it will have to grow
130
self.checkDetermineEditLists(separatorChars, before, edit, after)
132
def test_insertPushAhead(self):
134
# Insert with enough room to push without growing the cell
144
self.checkDetermineEditLists(separatorChars, before, edit, after)
146
# Insert without enough room to push, so the cell will have to grow
156
self.checkDetermineEditLists(separatorChars, before, edit, after)
158
# Insert multiple characters forcing a partial grow
163
edit = (0, ' aaaaaa')
165
after = ['| aaaaaa|',
168
# Insert multiple characters forcing a partial grow through pushing other chars ahead
173
edit = (0, ' aaaaaaa')
175
after = ['| aaaaaaabb|',
179
self.checkDetermineEditLists(separatorChars, before, edit, after)
181
def test_insertInSeparatorCell(self):
183
# Insert in a cell on a separator line
184
separatorChars = ' -'
193
self.checkDetermineEditLists(separatorChars, before, edit, after)
195
# Insert in a cell on a separator line forcing it to grow
196
separatorChars = ' -'
205
self.checkDetermineEditLists(separatorChars, before, edit, after)
207
# Insert in a cell on a separator line with an alignment marker
208
separatorChars = ' -'
217
self.checkDetermineEditLists(separatorChars, before, edit, after)
219
# Insert in a cell on a separator line with an alignment marker forcing it to grow
220
separatorChars = ' -'
229
self.checkDetermineEditLists(separatorChars, before, edit, after)
231
# Insert in a cell on a separator line after the alignment marker forcing it to grow
232
separatorChars = ' -'
241
self.checkDetermineEditLists(separatorChars, before, edit, after)
243
def test_insertAboveSeparatorLine(self):
244
# Insert on another line, without growing the cell
245
separatorChars = ' -'
254
self.checkDetermineEditLists(separatorChars, before, edit, after)
256
# Insert on another line, forcing the separator cell to grow
257
separatorChars = ' -'
266
self.checkDetermineEditLists(separatorChars, before, edit, after)
268
# Insert on another line, without growing the cell with alignment marker
269
separatorChars = ' -'
278
self.checkDetermineEditLists(separatorChars, before, edit, after)
280
# Insert on another line, forcing the separator cell with alignment marker to grow
281
separatorChars = ' -'
290
self.checkDetermineEditLists(separatorChars, before, edit, after)
292
# Insert on another line, forcing the separator cell that ends with a regular char to grow
293
separatorChars = ' -'
302
self.checkDetermineEditLists(separatorChars, before, edit, after)
304
def test_insertCascade(self):
305
# Test if growing of cells cascades onto other lines through edges that are shifted
319
self.checkDetermineEditLists(separatorChars, before, edit, after)
321
# Test if growing of cells cascades onto other lines but does not affect unconnected edges
333
self.checkDetermineEditLists(separatorChars, before, edit, after)
335
def test_simpleDelete(self):
336
# Delete at start of cell
346
self.checkDetermineEditLists(separatorChars, before, edit, after)
348
# Delete at end of cell
358
self.checkDetermineEditLists(separatorChars, before, edit, after)
360
def test_deleteShrinking(self):
361
# Shrinking limited by cell on other row
371
# Shrinking limited by cell on other row (cont'd)
381
self.checkDetermineEditLists(separatorChars, before, edit, after)
383
# Shrinking of next cell limited by cell on other row
385
before = ['|abc | |',
393
self.checkDetermineEditLists(separatorChars, before, edit, after)
395
# Shrink current cell fully, shrink next cell partially
397
before = ['| aabb| |',
405
self.checkDetermineEditLists(separatorChars, before, edit, after)
407
def test_deleteShrinkingSeparatorRow(self):
408
# Shrinking not limited by size of separator cell
409
separatorChars = ' -'
418
self.checkDetermineEditLists(separatorChars, before, edit, after)
420
# Shrinking limited by size of separator cell
421
separatorChars = ' -'
430
self.checkDetermineEditLists(separatorChars, before, edit, after)
432
# Shrinking not limited by size of separator cell with alignment markers
433
separatorChars = ' -'
442
self.checkDetermineEditLists(separatorChars, before, edit, after)
444
# Shrinking limited by size of separator cell with alignment markers
445
separatorChars = ' -'
454
self.checkDetermineEditLists(separatorChars, before, edit, after)
456
# Shrinking partially limited by size of separator cell with alignment markers
457
separatorChars = ' -'
466
self.checkDetermineEditLists(separatorChars, before, edit, after)
468
if __name__ == '__main__':