Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e3fcfc2

Browse files
committed
Issue #18409: Idle: add unittest for AutoComplete. Patch by Phil Webster.
1 parent 3f9535b commit e3fcfc2

5 files changed

Lines changed: 186 additions & 4 deletions

File tree

Lib/idlelib/AutoComplete.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,8 @@ def get_entity(self, name):
226226
namespace = sys.modules.copy()
227227
namespace.update(__main__.__dict__)
228228
return eval(name, namespace)
229+
230+
231+
if __name__ == '__main__':
232+
from unittest import main
233+
main('idlelib.idle_test.test_autocomplete', verbosity=2)

Lib/idlelib/idle_test/mock_idle.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@
55

66
from idlelib.idle_test.mock_tk import Text
77

8+
class Func:
9+
'''Mock function captures args and returns result set by test.
10+
11+
Most common use will probably be to mock methods.
12+
mock_tk.Var and Mbox_func are special cases of this.
13+
'''
14+
def __init__(self, result=None):
15+
self.result = result
16+
self.args = None
17+
self.kwds = None
18+
def __call__(self, *args, **kwds):
19+
self.args = args
20+
self.kwds = kwds
21+
return self.result
22+
23+
824
class Editor:
925
'''Minimally imitate EditorWindow.EditorWindow class.
1026
'''
@@ -17,6 +33,7 @@ def get_selection_indices(self):
1733
last = self.text.index('end')
1834
return first, last
1935

36+
2037
class UndoDelegator:
2138
'''Minimally imitate UndoDelegator,UndoDelegator class.
2239
'''

Lib/idlelib/idle_test/mock_tk.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
11
"""Classes that replace tkinter gui objects used by an object being tested.
22
3-
A gui object is anything with a master or parent paramenter, which is typically
4-
required in spite of what the doc strings say.
3+
A gui object is anything with a master or parent paramenter, which is
4+
typically required in spite of what the doc strings say.
55
"""
66

7+
class Event:
8+
'''Minimal mock with attributes for testing event handlers.
9+
10+
This is not a gui object, but is used as an argument for callbacks
11+
that access attributes of the event passed. If a callback ignores
12+
the event, other than the fact that is happened, pass 'event'.
13+
14+
Keyboard, mouse, window, and other sources generate Event instances.
15+
Event instances have the following attributes: serial (number of
16+
event), time (of event), type (of event as number), widget (in which
17+
event occurred), and x,y (position of mouse). There are other
18+
attributes for specific events, such as keycode for key events.
19+
tkinter.Event.__doc__ has more but is still not complete.
20+
'''
21+
def __init__(self, **kwds):
22+
"Create event with attributes needed for test"
23+
self.__dict__.update(kwds)
24+
725
class Var:
826
"Use for String/Int/BooleanVar: incomplete"
927
def __init__(self, master=None, value=None, name=None):
@@ -20,9 +38,10 @@ class Mbox_func:
2038
2139
Instead of displaying a message box, the mock's call method saves the
2240
arguments as instance attributes, which test functions can then examime.
41+
The test can set the result returned to ask function
2342
"""
24-
def __init__(self):
25-
self.result = None # The return for all show funcs
43+
def __init__(self, result=None):
44+
self.result = result # Return None for all show funcs
2645
def __call__(self, title, message, *args, **kwds):
2746
# Save all args for possible examination by tester
2847
self.title = title
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import unittest
2+
from test.support import requires
3+
from tkinter import Tk, Text, TclError
4+
5+
import idlelib.AutoComplete as ac
6+
import idlelib.AutoCompleteWindow as acw
7+
import idlelib.macosxSupport as mac
8+
from idlelib.EditorWindow import EditorWindow
9+
from idlelib.idle_test.mock_idle import Func
10+
from idlelib.idle_test.mock_tk import Event
11+
12+
class AutoCompleteWindow:
13+
def complete():
14+
return
15+
16+
17+
class AutoCompleteTest(unittest.TestCase):
18+
19+
@classmethod
20+
def setUpClass(cls):
21+
requires('gui')
22+
cls.root = Tk()
23+
mac.setupApp(cls.root, None)
24+
cls.editor = EditorWindow(root=cls.root)
25+
cls.text = cls.editor.text
26+
27+
@classmethod
28+
def tearDownClass(cls):
29+
cls.root.destroy()
30+
del cls.text
31+
del cls.editor
32+
del cls.root
33+
34+
def setUp(self):
35+
self.editor.text.delete('1.0', 'end')
36+
self.autocomplete = ac.AutoComplete(self.editor)
37+
38+
def test_init(self):
39+
self.assertEqual(self.autocomplete.editwin, self.editor)
40+
41+
def test_make_autocomplete_window(self):
42+
testwin = self.autocomplete._make_autocomplete_window()
43+
self.assertIsInstance(testwin, acw.AutoCompleteWindow)
44+
45+
def test_remove_autocomplete_window(self):
46+
self.autocomplete.autocompletewindow = (
47+
self.autocomplete._make_autocomplete_window())
48+
self.autocomplete._remove_autocomplete_window()
49+
self.assertIsNone(self.autocomplete.autocompletewindow)
50+
51+
def test_force_open_completions_event(self):
52+
# Test that force_open_completions_event calls _open_completions
53+
o_cs = Func()
54+
self.autocomplete.open_completions = o_cs
55+
self.autocomplete.force_open_completions_event('event')
56+
self.assertEqual(o_cs.args, (True, False, True))
57+
58+
def test_try_open_completions_event(self):
59+
Equal = self.assertEqual
60+
autocomplete = self.autocomplete
61+
trycompletions = self.autocomplete.try_open_completions_event
62+
o_c_l = Func()
63+
autocomplete._open_completions_later = o_c_l
64+
65+
# _open_completions_later should not be called with no text in editor
66+
trycompletions('event')
67+
Equal(o_c_l.args, None)
68+
69+
# _open_completions_later should be called with COMPLETE_ATTRIBUTES (1)
70+
self.text.insert('1.0', 're.')
71+
trycompletions('event')
72+
Equal(o_c_l.args, (False, False, False, 1))
73+
74+
# _open_completions_later should be called with COMPLETE_FILES (2)
75+
self.text.delete('1.0', 'end')
76+
self.text.insert('1.0', '"./Lib/')
77+
trycompletions('event')
78+
Equal(o_c_l.args, (False, False, False, 2))
79+
80+
def test_autocomplete_event(self):
81+
Equal = self.assertEqual
82+
autocomplete = self.autocomplete
83+
84+
# Test that the autocomplete event is ignored if user is pressing a
85+
# modifier key in addition to the tab key
86+
ev = Event(mc_state=True)
87+
self.assertIsNone(autocomplete.autocomplete_event(ev))
88+
del ev.mc_state
89+
90+
# If autocomplete window is open, complete() method is called
91+
testwin = self.autocomplete._make_autocomplete_window()
92+
self.text.insert('1.0', 're.')
93+
Equal(self.autocomplete.autocomplete_event(ev), 'break')
94+
95+
# If autocomplete window is not active or does not exist,
96+
# open_completions is called. Return depends on its return.
97+
autocomplete._remove_autocomplete_window()
98+
o_cs = Func() # .result = None
99+
autocomplete.open_completions = o_cs
100+
Equal(self.autocomplete.autocomplete_event(ev), None)
101+
Equal(o_cs.args, (False, True, True))
102+
o_cs.result = True
103+
Equal(self.autocomplete.autocomplete_event(ev), 'break')
104+
Equal(o_cs.args, (False, True, True))
105+
106+
def test_open_completions_later(self):
107+
# Test that autocomplete._delayed_completion_id is set
108+
pass
109+
110+
def test_delayed_open_completions(self):
111+
# Test that autocomplete._delayed_completion_id set to None and that
112+
# open_completions only called if insertion index is the same as
113+
# _delayed_completion_index
114+
pass
115+
116+
def test_open_completions(self):
117+
# Test completions of files and attributes as well as non-completion
118+
# of errors
119+
pass
120+
121+
def test_fetch_completions(self):
122+
# Test that fetch_completions returns 2 lists:
123+
# For attribute completion, a large list containing all variables, and
124+
# a small list containing non-private variables.
125+
# For file completion, a large list containing all files in the path,
126+
# and a small list containing files that do not start with '.'
127+
pass
128+
129+
def test_get_entity(self):
130+
# Test that a name is in the namespace of sys.modules and
131+
# __main__.__dict__
132+
pass
133+
134+
135+
if __name__ == '__main__':
136+
unittest.main(verbosity=2)

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ Build
6363

6464
- Issue #17095: Fix Modules/Setup *shared* support.
6565

66+
IDLE
67+
----
68+
69+
- Issue #18409: Add unittest for AutoComplete. Patch by Phil Webster.
70+
6671
Tests
6772
-----
6873

0 commit comments

Comments
 (0)