1''' Test mock_tk.Text class against tkinter.Text class
2
3Run same tests with both by creating a mixin class.
4'''
5import unittest
6from test.support import requires
7from _tkinter import TclError
8
9class TextTest(object):
10    "Define items common to both sets of tests."
11
12    hw = 'hello\nworld'  # Several tests insert this after initialization.
13    hwn = hw+'\n'  # \n present at initialization, before insert
14
15    # setUpClass defines cls.Text and maybe cls.root.
16    # setUp defines self.text from Text and maybe root.
17
18    def test_init(self):
19        self.assertEqual(self.text.get('1.0'), '\n')
20        self.assertEqual(self.text.get('end'), '')
21
22    def test_index_empty(self):
23        index = self.text.index
24
25        for dex in (-1.0, 0.3, '1.-1', '1.0', '1.0 lineend', '1.end', '1.33',
26                'insert'):
27            self.assertEqual(index(dex), '1.0')
28
29        for dex in 'end', 2.0, '2.1', '33.44':
30            self.assertEqual(index(dex), '2.0')
31
32    def test_index_data(self):
33        index = self.text.index
34        self.text.insert('1.0', self.hw)
35
36        for dex in -1.0, 0.3, '1.-1', '1.0':
37            self.assertEqual(index(dex), '1.0')
38
39        for dex in '1.0 lineend', '1.end', '1.33':
40            self.assertEqual(index(dex), '1.5')
41
42        for dex in 'end',  '33.44':
43            self.assertEqual(index(dex), '3.0')
44
45    def test_get(self):
46        get = self.text.get
47        Equal = self.assertEqual
48        self.text.insert('1.0', self.hw)
49
50        Equal(get('end'), '')
51        Equal(get('end', 'end'), '')
52        Equal(get('1.0'), 'h')
53        Equal(get('1.0', '1.1'), 'h')
54        Equal(get('1.0', '1.3'), 'hel')
55        Equal(get('1.1', '1.3'), 'el')
56        Equal(get('1.0', '1.0 lineend'), 'hello')
57        Equal(get('1.0', '1.10'), 'hello')
58        Equal(get('1.0 lineend'), '\n')
59        Equal(get('1.1', '2.3'), 'ello\nwor')
60        Equal(get('1.0', '2.5'), self.hw)
61        Equal(get('1.0', 'end'), self.hwn)
62        Equal(get('0.0', '5.0'), self.hwn)
63
64    def test_insert(self):
65        insert = self.text.insert
66        get = self.text.get
67        Equal = self.assertEqual
68
69        insert('1.0', self.hw)
70        Equal(get('1.0', 'end'), self.hwn)
71
72        insert('1.0', '')  # nothing
73        Equal(get('1.0', 'end'), self.hwn)
74
75        insert('1.0', '*')
76        Equal(get('1.0', 'end'), '*hello\nworld\n')
77
78        insert('1.0 lineend', '*')
79        Equal(get('1.0', 'end'), '*hello*\nworld\n')
80
81        insert('2.3', '*')
82        Equal(get('1.0', 'end'), '*hello*\nwor*ld\n')
83
84        insert('end', 'x')
85        Equal(get('1.0', 'end'), '*hello*\nwor*ldx\n')
86
87        insert('1.4', 'x\n')
88        Equal(get('1.0', 'end'), '*helx\nlo*\nwor*ldx\n')
89
90    def test_no_delete(self):
91        # if index1 == 'insert' or 'end' or >= end, there is no deletion
92        delete = self.text.delete
93        get = self.text.get
94        Equal = self.assertEqual
95        self.text.insert('1.0', self.hw)
96
97        delete('insert')
98        Equal(get('1.0', 'end'), self.hwn)
99
100        delete('end')
101        Equal(get('1.0', 'end'), self.hwn)
102
103        delete('insert', 'end')
104        Equal(get('1.0', 'end'), self.hwn)
105
106        delete('insert', '5.5')
107        Equal(get('1.0', 'end'), self.hwn)
108
109        delete('1.4', '1.0')
110        Equal(get('1.0', 'end'), self.hwn)
111
112        delete('1.4', '1.4')
113        Equal(get('1.0', 'end'), self.hwn)
114
115    def test_delete_char(self):
116        delete = self.text.delete
117        get = self.text.get
118        Equal = self.assertEqual
119        self.text.insert('1.0', self.hw)
120
121        delete('1.0')
122        Equal(get('1.0', '1.end'), 'ello')
123
124        delete('1.0', '1.1')
125        Equal(get('1.0', '1.end'), 'llo')
126
127        # delete \n and combine 2 lines into 1
128        delete('1.end')
129        Equal(get('1.0', '1.end'), 'lloworld')
130
131        self.text.insert('1.3', '\n')
132        delete('1.10')
133        Equal(get('1.0', '1.end'), 'lloworld')
134
135        self.text.insert('1.3', '\n')
136        delete('1.3', '2.0')
137        Equal(get('1.0', '1.end'), 'lloworld')
138
139    def test_delete_slice(self):
140        delete = self.text.delete
141        get = self.text.get
142        Equal = self.assertEqual
143        self.text.insert('1.0', self.hw)
144
145        delete('1.0', '1.0 lineend')
146        Equal(get('1.0', 'end'), '\nworld\n')
147
148        delete('1.0', 'end')
149        Equal(get('1.0', 'end'), '\n')
150
151        self.text.insert('1.0', self.hw)
152        delete('1.0', '2.0')
153        Equal(get('1.0', 'end'), 'world\n')
154
155        delete('1.0', 'end')
156        Equal(get('1.0', 'end'), '\n')
157
158        self.text.insert('1.0', self.hw)
159        delete('1.2', '2.3')
160        Equal(get('1.0', 'end'), 'held\n')
161
162    def test_multiple_lines(self):  # insert and delete
163        self.text.insert('1.0', 'hello')
164
165        self.text.insert('1.3', '1\n2\n3\n4\n5')
166        self.assertEqual(self.text.get('1.0', 'end'), 'hel1\n2\n3\n4\n5lo\n')
167
168        self.text.delete('1.3', '5.1')
169        self.assertEqual(self.text.get('1.0', 'end'), 'hello\n')
170
171    def test_compare(self):
172        compare = self.text.compare
173        Equal = self.assertEqual
174        # need data so indexes not squished to 1,0
175        self.text.insert('1.0', 'First\nSecond\nThird\n')
176
177        self.assertRaises(TclError, compare, '2.2', 'op', '2.2')
178
179        for op, less1, less0, equal, greater0, greater1 in (
180                ('<', True, True, False, False, False),
181                ('<=', True, True, True, False, False),
182                ('>', False, False, False, True, True),
183                ('>=', False, False, True, True, True),
184                ('==', False, False, True, False, False),
185                ('!=', True, True, False, True, True),
186                ):
187            Equal(compare('1.1', op, '2.2'), less1, op)
188            Equal(compare('2.1', op, '2.2'), less0, op)
189            Equal(compare('2.2', op, '2.2'), equal, op)
190            Equal(compare('2.3', op, '2.2'), greater0, op)
191            Equal(compare('3.3', op, '2.2'), greater1, op)
192
193
194class MockTextTest(TextTest, unittest.TestCase):
195
196    @classmethod
197    def setUpClass(cls):
198        from idlelib.idle_test.mock_tk import Text
199        cls.Text = Text
200
201    def setUp(self):
202        self.text = self.Text()
203
204
205    def test_decode(self):
206        # test endflags (-1, 0) not tested by test_index (which uses +1)
207        decode = self.text._decode
208        Equal = self.assertEqual
209        self.text.insert('1.0', self.hw)
210
211        Equal(decode('end', -1), (2, 5))
212        Equal(decode('3.1', -1), (2, 5))
213        Equal(decode('end',  0), (2, 6))
214        Equal(decode('3.1', 0), (2, 6))
215
216
217class TkTextTest(TextTest, unittest.TestCase):
218
219    @classmethod
220    def setUpClass(cls):
221        requires('gui')
222        from tkinter import Tk, Text
223        cls.Text = Text
224        cls.root = Tk()
225
226    @classmethod
227    def tearDownClass(cls):
228        cls.root.destroy()
229        del cls.root
230
231    def setUp(self):
232        self.text = self.Text(self.root)
233
234
235if __name__ == '__main__':
236    unittest.main(verbosity=2, exit=False)
237