Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
113d735e
Commit
113d735e
authored
Mar 25, 2019
by
Louie Lu
Committed by
Terry Jan Reedy
Mar 24, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-30348: IDLE: Add test_autocomplete unittest (GH-2209)
parent
13c1f72c
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
131 additions
and
27 deletions
+131
-27
Lib/idlelib/autocomplete.py
Lib/idlelib/autocomplete.py
+11
-6
Lib/idlelib/idle_test/test_autocomplete.py
Lib/idlelib/idle_test/test_autocomplete.py
+119
-21
Misc/NEWS.d/next/IDLE/2018-06-27-21-18-41.bpo-30348.WbaRJW.rst
...NEWS.d/next/IDLE/2018-06-27-21-18-41.bpo-30348.WbaRJW.rst
+1
-0
No files found.
Lib/idlelib/autocomplete.py
View file @
113d735e
...
...
@@ -104,9 +104,14 @@ class AutoComplete:
def
open_completions
(
self
,
evalfuncs
,
complete
,
userWantsWin
,
mode
=
None
):
"""Find the completions and create the AutoCompleteWindow.
Return True if successful (no syntax error or so found).
i
f complete is True, then if there's nothing to complete and no
I
f complete is True, then if there's nothing to complete and no
start of completion, won't open completions and return False.
If mode is given, will open a completion list only in this mode.
Action Function Eval Complete WantWin Mode
^space force_open_completions True, False, True no
. or / try_open_completions False, False, False yes
tab autocomplete False, True, True no
"""
# Cancel another delayed call, if it exists.
if
self
.
_delayed_completion_id
is
not
None
:
...
...
@@ -117,11 +122,11 @@ class AutoComplete:
curline
=
self
.
text
.
get
(
"insert linestart"
,
"insert"
)
i
=
j
=
len
(
curline
)
if
hp
.
is_in_string
()
and
(
not
mode
or
mode
==
COMPLETE_FILES
):
# Find the beginning of the string
# fetch_completions will look at the file system to determine
whether the
# string value constitutes an actual file name
# XXX could consider raw strings here and unescape the string
value if it's
# not raw.
# Find the beginning of the string
.
# fetch_completions will look at the file system to determine
#
whether the
string value constitutes an actual file name
# XXX could consider raw strings here and unescape the string
#
value if it's
not raw.
self
.
_remove_autocomplete_window
()
mode
=
COMPLETE_FILES
# Find last separator or string start
...
...
Lib/idlelib/idle_test/test_autocomplete.py
View file @
113d735e
"Test autocomplete, coverage
5
7%."
"Test autocomplete, coverage
8
7%."
import
unittest
from
unittest.mock
import
Mock
,
patch
from
test.support
import
requires
from
tkinter
import
Tk
,
Text
import
os
import
__main__
import
idlelib.autocomplete
as
ac
...
...
@@ -26,12 +28,14 @@ class AutoCompleteTest(unittest.TestCase):
def
setUpClass
(
cls
):
requires
(
'gui'
)
cls
.
root
=
Tk
()
cls
.
root
.
withdraw
()
cls
.
text
=
Text
(
cls
.
root
)
cls
.
editor
=
DummyEditwin
(
cls
.
root
,
cls
.
text
)
@
classmethod
def
tearDownClass
(
cls
):
del
cls
.
editor
,
cls
.
text
cls
.
root
.
update_idletasks
()
cls
.
root
.
destroy
()
del
cls
.
root
...
...
@@ -53,7 +57,7 @@ class AutoCompleteTest(unittest.TestCase):
self
.
assertIsNone
(
self
.
autocomplete
.
autocompletewindow
)
def
test_force_open_completions_event
(
self
):
# Test that force_open_completions_event calls _open_completions
# Test that force_open_completions_event calls _open_completions
.
o_cs
=
Func
()
self
.
autocomplete
.
open_completions
=
o_cs
self
.
autocomplete
.
force_open_completions_event
(
'event'
)
...
...
@@ -66,16 +70,16 @@ class AutoCompleteTest(unittest.TestCase):
o_c_l
=
Func
()
autocomplete
.
_open_completions_later
=
o_c_l
# _open_completions_later should not be called with no text in editor
# _open_completions_later should not be called with no text in editor
.
trycompletions
(
'event'
)
Equal
(
o_c_l
.
args
,
None
)
# _open_completions_later should be called with COMPLETE_ATTRIBUTES (1)
# _open_completions_later should be called with COMPLETE_ATTRIBUTES (1)
.
self
.
text
.
insert
(
'1.0'
,
're.'
)
trycompletions
(
'event'
)
Equal
(
o_c_l
.
args
,
(
False
,
False
,
False
,
1
))
# _open_completions_later should be called with COMPLETE_FILES (2)
# _open_completions_later should be called with COMPLETE_FILES (2)
.
self
.
text
.
delete
(
'1.0'
,
'end'
)
self
.
text
.
insert
(
'1.0'
,
'"./Lib/'
)
trycompletions
(
'event'
)
...
...
@@ -86,7 +90,7 @@ class AutoCompleteTest(unittest.TestCase):
autocomplete
=
self
.
autocomplete
# Test that the autocomplete event is ignored if user is pressing a
# modifier key in addition to the tab key
# modifier key in addition to the tab key
.
ev
=
Event
(
mc_state
=
True
)
self
.
assertIsNone
(
autocomplete
.
autocomplete_event
(
ev
))
del
ev
.
mc_state
...
...
@@ -96,15 +100,15 @@ class AutoCompleteTest(unittest.TestCase):
self
.
assertIsNone
(
autocomplete
.
autocomplete_event
(
ev
))
self
.
text
.
delete
(
'1.0'
,
'end'
)
# If autocomplete window is open, complete() method is called
# If autocomplete window is open, complete() method is called
.
self
.
text
.
insert
(
'1.0'
,
're.'
)
# This must call autocomplete._make_autocomplete_window()
# This must call autocomplete._make_autocomplete_window()
.
Equal
(
self
.
autocomplete
.
autocomplete_event
(
ev
),
'break'
)
# If autocomplete window is not active or does not exist,
# open_completions is called. Return depends on its return.
autocomplete
.
_remove_autocomplete_window
()
o_cs
=
Func
()
# .result = None
o_cs
=
Func
()
# .result = None
.
autocomplete
.
open_completions
=
o_cs
Equal
(
self
.
autocomplete
.
autocomplete_event
(
ev
),
None
)
Equal
(
o_cs
.
args
,
(
False
,
True
,
True
))
...
...
@@ -113,36 +117,130 @@ class AutoCompleteTest(unittest.TestCase):
Equal
(
o_cs
.
args
,
(
False
,
True
,
True
))
def
test_open_completions_later
(
self
):
# Test that autocomplete._delayed_completion_id is set
pass
# Test that autocomplete._delayed_completion_id is set.
acp
=
self
.
autocomplete
acp
.
_delayed_completion_id
=
None
acp
.
_open_completions_later
(
False
,
False
,
False
,
ac
.
COMPLETE_ATTRIBUTES
)
cb1
=
acp
.
_delayed_completion_id
self
.
assertTrue
(
cb1
.
startswith
(
'after'
))
# Test that cb1 is cancelled and cb2 is new.
acp
.
_open_completions_later
(
False
,
False
,
False
,
ac
.
COMPLETE_FILES
)
self
.
assertNotIn
(
cb1
,
self
.
root
.
tk
.
call
(
'after'
,
'info'
))
cb2
=
acp
.
_delayed_completion_id
self
.
assertTrue
(
cb2
.
startswith
(
'after'
)
and
cb2
!=
cb1
)
self
.
text
.
after_cancel
(
cb2
)
def
test_delayed_open_completions
(
self
):
# Test that autocomplete._delayed_completion_id set to None and that
# open_completions only called if insertion index is the same as
# _delayed_completion_index
pass
# Test that autocomplete._delayed_completion_id set to None
# and that open_completions is not called if the index is not
# equal to _delayed_completion_index.
acp
=
self
.
autocomplete
acp
.
open_completions
=
Func
()
acp
.
_delayed_completion_id
=
'after'
acp
.
_delayed_completion_index
=
self
.
text
.
index
(
'insert+1c'
)
acp
.
_delayed_open_completions
(
1
,
2
,
3
)
self
.
assertIsNone
(
acp
.
_delayed_completion_id
)
self
.
assertEqual
(
acp
.
open_completions
.
called
,
0
)
# Test that open_completions is called if indexes match.
acp
.
_delayed_completion_index
=
self
.
text
.
index
(
'insert'
)
acp
.
_delayed_open_completions
(
1
,
2
,
3
,
ac
.
COMPLETE_FILES
)
self
.
assertEqual
(
acp
.
open_completions
.
args
,
(
1
,
2
,
3
,
2
))
def
test_open_completions
(
self
):
# Test completions of files and attributes as well as non-completion
# of errors
pass
# of errors.
self
.
text
.
insert
(
'1.0'
,
'pr'
)
self
.
assertTrue
(
self
.
autocomplete
.
open_completions
(
False
,
True
,
True
))
self
.
text
.
delete
(
'1.0'
,
'end'
)
# Test files.
self
.
text
.
insert
(
'1.0'
,
'"t'
)
#self.assertTrue(self.autocomplete.open_completions(False, True, True))
self
.
text
.
delete
(
'1.0'
,
'end'
)
# Test with blank will fail.
self
.
assertFalse
(
self
.
autocomplete
.
open_completions
(
False
,
True
,
True
))
# Test with only string quote will fail.
self
.
text
.
insert
(
'1.0'
,
'"'
)
self
.
assertFalse
(
self
.
autocomplete
.
open_completions
(
False
,
True
,
True
))
self
.
text
.
delete
(
'1.0'
,
'end'
)
def
test_fetch_completions
(
self
):
# Test that fetch_completions returns 2 lists:
# For attribute completion, a large list containing all variables, and
# a small list containing non-private variables.
# For file completion, a large list containing all files in the path,
# and a small list containing files that do not start with '.'
# and a small list containing files that do not start with '.'.
autocomplete
=
self
.
autocomplete
small
,
large
=
self
.
autocomplete
.
fetch_completions
(
''
,
ac
.
COMPLETE_ATTRIBUTES
)
self
.
assertLess
(
len
(
small
),
len
(
large
))
if
__main__
.
__file__
!=
ac
.
__file__
:
self
.
assertNotIn
(
'AutoComplete'
,
small
)
# See issue 36405.
# Test attributes
s
,
b
=
autocomplete
.
fetch_completions
(
''
,
ac
.
COMPLETE_ATTRIBUTES
)
self
.
assertLess
(
len
(
small
),
len
(
large
))
self
.
assertTrue
(
all
(
filter
(
lambda
x
:
x
.
startswith
(
'_'
),
s
)))
self
.
assertTrue
(
any
(
filter
(
lambda
x
:
x
.
startswith
(
'_'
),
b
)))
# Test smalll should respect to __all__.
with
patch
.
dict
(
'__main__.__dict__'
,
{
'__all__'
:
[
'a'
,
'b'
]}):
s
,
b
=
autocomplete
.
fetch_completions
(
''
,
ac
.
COMPLETE_ATTRIBUTES
)
self
.
assertEqual
(
s
,
[
'a'
,
'b'
])
self
.
assertIn
(
'__name__'
,
b
)
# From __main__.__dict__
self
.
assertIn
(
'sum'
,
b
)
# From __main__.__builtins__.__dict__
# Test attributes with name entity.
mock
=
Mock
()
mock
.
_private
=
Mock
()
with
patch
.
dict
(
'__main__.__dict__'
,
{
'foo'
:
mock
}):
s
,
b
=
autocomplete
.
fetch_completions
(
'foo'
,
ac
.
COMPLETE_ATTRIBUTES
)
self
.
assertNotIn
(
'_private'
,
s
)
self
.
assertIn
(
'_private'
,
b
)
self
.
assertEqual
(
s
,
[
i
for
i
in
sorted
(
dir
(
mock
))
if
i
[:
1
]
!=
'_'
])
self
.
assertEqual
(
b
,
sorted
(
dir
(
mock
)))
# Test files
def
_listdir
(
path
):
# This will be patch and used in fetch_completions.
if
path
==
'.'
:
return
[
'foo'
,
'bar'
,
'.hidden'
]
return
[
'monty'
,
'python'
,
'.hidden'
]
with
patch
.
object
(
os
,
'listdir'
,
_listdir
):
s
,
b
=
autocomplete
.
fetch_completions
(
''
,
ac
.
COMPLETE_FILES
)
self
.
assertEqual
(
s
,
[
'bar'
,
'foo'
])
self
.
assertEqual
(
b
,
[
'.hidden'
,
'bar'
,
'foo'
])
s
,
b
=
autocomplete
.
fetch_completions
(
'~'
,
ac
.
COMPLETE_FILES
)
self
.
assertEqual
(
s
,
[
'monty'
,
'python'
])
self
.
assertEqual
(
b
,
[
'.hidden'
,
'monty'
,
'python'
])
def
test_get_entity
(
self
):
# Test that a name is in the namespace of sys.modules and
# __main__.__dict__
self
.
assertEqual
(
self
.
autocomplete
.
get_entity
(
'int'
),
int
)
# __main__.__dict__.
autocomplete
=
self
.
autocomplete
Equal
=
self
.
assertEqual
Equal
(
self
.
autocomplete
.
get_entity
(
'int'
),
int
)
# Test name from sys.modules.
mock
=
Mock
()
with
patch
.
dict
(
'sys.modules'
,
{
'tempfile'
:
mock
}):
Equal
(
autocomplete
.
get_entity
(
'tempfile'
),
mock
)
# Test name from __main__.__dict__.
di
=
{
'foo'
:
10
,
'bar'
:
20
}
with
patch
.
dict
(
'__main__.__dict__'
,
{
'd'
:
di
}):
Equal
(
autocomplete
.
get_entity
(
'd'
),
di
)
# Test name not in namespace.
with
patch
.
dict
(
'__main__.__dict__'
,
{}):
with
self
.
assertRaises
(
NameError
):
autocomplete
.
get_entity
(
'not_exist'
)
if
__name__
==
'__main__'
:
...
...
Misc/NEWS.d/next/IDLE/2018-06-27-21-18-41.bpo-30348.WbaRJW.rst
0 → 100644
View file @
113d735e
Increase test coverage of idlelib.autocomplete by 30%.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment