diff -r 7f17c67b5bf6 Lib/idlelib/idle_test/mock_tk.py --- a/Lib/idlelib/idle_test/mock_tk.py Sun Jul 07 17:35:11 2013 +0200 +++ b/Lib/idlelib/idle_test/mock_tk.py Mon Jul 08 00:25:51 2013 -0400 @@ -61,3 +61,146 @@ showerror = Mbox_func() # None showinfo = Mbox_func() # None showwarning = Mbox_func() # None + + +class Text: + def __init__(self): + self.data = ['', '\n'] + + def setData(self, text): + # First element of data is unused so that line numbers correspond + # to list elements + self.data = [''] + text.splitlines(True) + if self.data[-1][-1] != '\n': + self.data[-1] += '\n' + + def getData(self): + return ''.join(self.data) + + def _decode(self, position): # private helper + """Takes Text index (eg. '2.5') and returns index in self.data""" + position = str(position) # Tkinter allows floats to be passed in + + if position.upper() == 'END': + # corresponds to last line before newline character + line = len(self.data) - 1 + col = len(self.data[-1]) - 1 + return line, col + + line, col = position.split('.') + line = int(line) + + # Out of bounds index corresponds to last line before \n + # or first index if less than 1 + if line > len(self.data) - 1: + line = len(self.data) - 1 + col = len(self.data[-1]) - 1 + return line, col + elif line < 1: + line = 1 + col = 0 + return line, col + + linelength = len(self.data[line]) + if col == '0 lineend' or col.upper() == 'END': + col = linelength - 1 + elif int(col) >= linelength: + col = linelength - 1 + elif int(col) < linelength: + col = int(col) + return line, col + + def get(self, start, end=None): + startline, startcol = self._decode(start) + + if end is None: + if start.upper() == 'END': + return '' + return self.data[startline][startcol] + else: + endline, endcol = self._decode(end) + + if end.upper() == 'END': + endcol += 1 + + if startline == endline: + return self.data[startline][startcol:endcol] + else: + lines = [self.data[startline][startcol:]] + for i in range(startline+1, endline): + lines.append(self.data[i]) + lines.append(self.data[endline][:endcol]) + return ''.join(lines) + + def delete(self, start, end=None): + startline, startcol = self._decode(start) + if end is None: + # delete single character at start index + self.data[startline] = self.data[startline][:startcol] + \ + self.data[startline][startcol+1:] + return + else: + endline, endcol = self._decode(end) + if endline - 1 == startline and endcol == 0: + del self.data[startline] + elif startline == endline: + self.data[startline] = self.data[startline][:startcol] + \ + self.data[endline][endcol:] + else: + self.data[startline] = self.data[startline][:startcol] + \ + self.data[endline][endcol:] + for i in range(startline+1, endline+1): + del self.data[startline+1] + if end == 'end': + self.data[-1] = '\n' + return + + def index(self, position): + if position.upper() == 'END': + return str(len(self.data)) + '.' + '0' + elif position == 'sel.first': + return '1.0' + elif position == 'sel.last': + return 'end' + elif position == 'insert': + return '1.0' + else: + return + # TODO: support other index types (eg. line.column, line.end, ...) + + def insert(self, position, text): + # if position == end, insert on last line + text = text.splitlines(True) + line, col = self._decode(position) + splitline = [self.data[line][:col], self.data[line][col:]] + self.data[line] = splitline[0] + text[0] + for i in range(1, len(text)): + self.data.insert(line+i, text[i]) + self.data[line+len(text)-1] += splitline[1] + + def tag_remove(self, tagName, index1, index2=None): + pass + + def mark_set(self, name, index): + pass + + def bind(sequence=None, func=None, add=None): + pass + + def undo_block_start(self, *args): + pass + + def undo_block_stop(self, *args): + pass + + def see(self, index): + pass + + def compare(self, index1, op, index2): + line1, col1 = self._decode(index1) + line2, col2 = self._decode(index2) + if op == '<': + if line1 == line2: + return col1 < col2 + else: + return line1 < line2 diff -r 7f17c67b5bf6 Lib/idlelib/idle_test/test_text.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/idlelib/idle_test/test_text.py Mon Jul 08 00:25:51 2013 -0400 @@ -0,0 +1,88 @@ +import unittest +from idlelib.idle_test.mock_idle import Editor +import idlelib.EditorWindow as ew +from tkinter.ttk import setup_master +from test.support import requires + +class TextTest(object): + + def test_get(self): + self.text.insert('1.0','hello\nworld') + self.assertEqual(self.text.get('end'),'') + self.assertEqual(self.text.get('1.0'),'h') + self.assertEqual(self.text.get('1.0','1.1'),'h') + self.assertEqual(self.text.get('1.0','1.3'),'hel') + self.assertEqual(self.text.get('1.1','1.3'),'el') + self.assertEqual(self.text.get('1.0','1.0 lineend'),'hello') + self.assertEqual(self.text.get('1.0 lineend'),'\n') + self.assertEqual(self.text.get('1.0','end'),'hello\nworld\n') + self.assertEqual(self.text.get('1.1','2.3'),'ello\nwor') + + def test_insert(self): + self.text.insert('1.0', 'hello\nworld') + self.assertEqual(self.text.get('1.0','end'),'hello\nworld\n') + + self.text.insert('1.0','*') + self.assertEqual(self.text.get('1.0','end'),'*hello\nworld\n') + + self.text.insert('1.0 lineend','*') + self.assertEqual(self.text.get('1.0','end'),'*hello*\nworld\n') + + self.text.insert('2.3','*') + self.assertEqual(self.text.get('1.0','end'),'*hello*\nwor*ld\n') + + self.text.insert('end','x') + self.assertEqual(self.text.get('1.0','end'),'*hello*\nwor*ldx\n') + + def test_delete(self): + self.text.insert('1.0','hello\nworld') + self.text.delete('1.0','1.0 lineend') + self.assertEqual(self.text.get('1.0','end'),'\nworld\n') + + self.text.delete('1.0','end') + self.assertEqual(self.text.get('1.0','end'),'\n') + + self.text.insert('1.0','hello\nworld') + self.text.delete('1.0','2.0') + self.assertEqual(self.text.get('1.0','end'),'world\n') + + self.text.delete('1.0','end') + self.assertEqual(self.text.get('1.0','end'),'\n') + + self.text.insert('1.0','hello\nworld') + self.text.delete('1.2','2.3') + self.assertEqual(self.text.get('1.0','end'),'held\n') + + def test_index(self): + self.text.insert('1.0','hello\nworld') + self.assertEqual(self.text.index('end'),'3.0') + +class MockTextTest(TextTest, unittest.TestCase): + + def setUp(self): + self.editwindow = Editor() + self.text = self.editwindow.text + + def test__decode(self): + self.assertEqual(self.text._decode('end'),(1,0)) + self.text.insert('1.0','hello\nworld') + self.assertEqual(self.text._decode('1.0'), (1,0)) + self.assertEqual(self.text._decode('1.0 lineend'),(1,5)) + self.assertEqual(self.text._decode('end'),(2,5)) + self.assertEqual(self.text._decode('2.end'), (2,5)) + self.assertEqual(self.text._decode('2.2'),(2,2)) + +class TextWidgetTest(TextTest, unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + + def setUp(self): + self.root = setup_master() + self.editwindow = ew.EditorWindow(root=self.root) + self.text = self.editwindow.text + +if __name__ == '__main__': + unittest.main() +