1"Test autoexpand, coverage 100%."
2
3from idlelib.autoexpand import AutoExpand
4import unittest
5from test.support import requires
6from tkinter import Text, Tk
7
8
9class DummyEditwin:
10    # AutoExpand.__init__ only needs .text
11    def __init__(self, text):
12        self.text = text
13
14class AutoExpandTest(unittest.TestCase):
15
16    @classmethod
17    def setUpClass(cls):
18        requires('gui')
19        cls.tk = Tk()
20        cls.text = Text(cls.tk)
21        cls.auto_expand = AutoExpand(DummyEditwin(cls.text))
22        cls.auto_expand.bell = lambda: None
23
24# If mock_tk.Text._decode understood indexes 'insert' with suffixed 'linestart',
25# 'wordstart', and 'lineend', used by autoexpand, we could use the following
26# to run these test on non-gui machines (but check bell).
27##        try:
28##            requires('gui')
29##            #raise ResourceDenied()  # Uncomment to test mock.
30##        except ResourceDenied:
31##            from idlelib.idle_test.mock_tk import Text
32##            cls.text = Text()
33##            cls.text.bell = lambda: None
34##        else:
35##            from tkinter import Tk, Text
36##            cls.tk = Tk()
37##            cls.text = Text(cls.tk)
38
39    @classmethod
40    def tearDownClass(cls):
41        del cls.text, cls.auto_expand
42        if hasattr(cls, 'tk'):
43            cls.tk.destroy()
44            del cls.tk
45
46    def tearDown(self):
47        self.text.delete('1.0', 'end')
48
49    def test_get_prevword(self):
50        text = self.text
51        previous = self.auto_expand.getprevword
52        equal = self.assertEqual
53
54        equal(previous(), '')
55
56        text.insert('insert', 't')
57        equal(previous(), 't')
58
59        text.insert('insert', 'his')
60        equal(previous(), 'this')
61
62        text.insert('insert', ' ')
63        equal(previous(), '')
64
65        text.insert('insert', 'is')
66        equal(previous(), 'is')
67
68        text.insert('insert', '\nsample\nstring')
69        equal(previous(), 'string')
70
71        text.delete('3.0', 'insert')
72        equal(previous(), '')
73
74        text.delete('1.0', 'end')
75        equal(previous(), '')
76
77    def test_before_only(self):
78        previous = self.auto_expand.getprevword
79        expand = self.auto_expand.expand_word_event
80        equal = self.assertEqual
81
82        self.text.insert('insert', 'ab ac bx ad ab a')
83        equal(self.auto_expand.getwords(), ['ab', 'ad', 'ac', 'a'])
84        expand('event')
85        equal(previous(), 'ab')
86        expand('event')
87        equal(previous(), 'ad')
88        expand('event')
89        equal(previous(), 'ac')
90        expand('event')
91        equal(previous(), 'a')
92
93    def test_after_only(self):
94        # Also add punctuation 'noise' that should be ignored.
95        text = self.text
96        previous = self.auto_expand.getprevword
97        expand = self.auto_expand.expand_word_event
98        equal = self.assertEqual
99
100        text.insert('insert', 'a, [ab] ac: () bx"" cd ac= ad ya')
101        text.mark_set('insert', '1.1')
102        equal(self.auto_expand.getwords(), ['ab', 'ac', 'ad', 'a'])
103        expand('event')
104        equal(previous(), 'ab')
105        expand('event')
106        equal(previous(), 'ac')
107        expand('event')
108        equal(previous(), 'ad')
109        expand('event')
110        equal(previous(), 'a')
111
112    def test_both_before_after(self):
113        text = self.text
114        previous = self.auto_expand.getprevword
115        expand = self.auto_expand.expand_word_event
116        equal = self.assertEqual
117
118        text.insert('insert', 'ab xy yz\n')
119        text.insert('insert', 'a ac by ac')
120
121        text.mark_set('insert', '2.1')
122        equal(self.auto_expand.getwords(), ['ab', 'ac', 'a'])
123        expand('event')
124        equal(previous(), 'ab')
125        expand('event')
126        equal(previous(), 'ac')
127        expand('event')
128        equal(previous(), 'a')
129
130    def test_other_expand_cases(self):
131        text = self.text
132        expand = self.auto_expand.expand_word_event
133        equal = self.assertEqual
134
135        # no expansion candidate found
136        equal(self.auto_expand.getwords(), [])
137        equal(expand('event'), 'break')
138
139        text.insert('insert', 'bx cy dz a')
140        equal(self.auto_expand.getwords(), [])
141
142        # reset state by successfully expanding once
143        # move cursor to another position and expand again
144        text.insert('insert', 'ac xy a ac ad a')
145        text.mark_set('insert', '1.7')
146        expand('event')
147        initial_state = self.auto_expand.state
148        text.mark_set('insert', '1.end')
149        expand('event')
150        new_state = self.auto_expand.state
151        self.assertNotEqual(initial_state, new_state)
152
153
154if __name__ == '__main__':
155    unittest.main(verbosity=2)
156