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
223dd8d7
Commit
223dd8d7
authored
Jul 11, 2014
by
Terry Jan Reedy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
#21940: Add unittest for WidgetRedirector. Initial patch by Saimadhav Heblikar.
parent
737c34fa
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
145 additions
and
13 deletions
+145
-13
Lib/idlelib/WidgetRedirector.py
Lib/idlelib/WidgetRedirector.py
+19
-12
Lib/idlelib/idle_test/mock_idle.py
Lib/idlelib/idle_test/mock_idle.py
+4
-1
Lib/idlelib/idle_test/test_widgetredir.py
Lib/idlelib/idle_test/test_widgetredir.py
+122
-0
No files found.
Lib/idlelib/WidgetRedirector.py
View file @
223dd8d7
...
...
@@ -3,19 +3,21 @@ from tkinter import TclError
class
WidgetRedirector
:
"""Support for redirecting arbitrary widget subcommands.
Some Tk operations don't normally pass through
T
kinter. For example, if a
Some Tk operations don't normally pass through
t
kinter. For example, if a
character is inserted into a Text widget by pressing a key, a default Tk
binding to the widget's 'insert' operation is activated, and the Tk library
processes the insert without calling back into
T
kinter.
processes the insert without calling back into
t
kinter.
Although a binding to <Key> could be made via Tkinter, what we really want
to do is to hook the Tk 'insert' operation itself.
Although a binding to <Key> could be made via tkinter, what we really want
to do is to hook the Tk 'insert' operation itself. For one thing, we want
a text.insert call in idle code to have the same effect as a key press.
When a widget is instantiated, a Tcl command is created whose name is the
same as the pathname widget._w. This command is used to invoke the various
widget operations, e.g. insert (for a Text widget). We are going to hook
this command and provide a facility ('register') to intercept the widget
operation.
operation. We will also intercept method calls on the tkinter class
instance that represents the tk widget.
In IDLE, WidgetRedirector is used in Percolator to intercept Text
commands. The function being registered provides access to the top
...
...
@@ -64,9 +66,13 @@ class WidgetRedirector:
def
register
(
self
,
operation
,
function
):
'''Return OriginalCommand(operation) after registering function.
Registration adds an instance function attribute that masks the
class instance method attribute. If a second function is
registered for the same operation, the first function is replaced.
Registration adds an operation: function pair to ._operations.
It also adds an widget function attribute that masks the tkinter
class instance method. Method masking operates independently
from command dispatch.
If a second function is registered for the same operation, the
first function is replaced in both places.
'''
self
.
_operations
[
operation
]
=
function
setattr
(
self
.
widget
,
operation
,
function
)
...
...
@@ -80,8 +86,10 @@ class WidgetRedirector:
if
operation
in
self
.
_operations
:
function
=
self
.
_operations
[
operation
]
del
self
.
_operations
[
operation
]
if
hasattr
(
self
.
widget
,
operation
)
:
try
:
delattr
(
self
.
widget
,
operation
)
except
AttributeError
:
pass
return
function
else
:
return
None
...
...
@@ -160,8 +168,7 @@ def _widget_redirector(parent): # htest #
if
__name__
==
"__main__"
:
import
unittest
## unittest.main('idlelib.idle_test.test_widgetredir',
## verbosity=2, exit=False)
unittest
.
main
(
'idlelib.idle_test.test_widgetredir'
,
verbosity
=
2
,
exit
=
False
)
from
idlelib.idle_test.htest
import
run
run
(
_widget_redirector
)
Lib/idlelib/idle_test/mock_idle.py
View file @
223dd8d7
...
...
@@ -26,7 +26,10 @@ class Func:
self
.
called
=
True
self
.
args
=
args
self
.
kwds
=
kwds
return
self
.
result
if
isinstance
(
self
.
result
,
BaseException
):
raise
self
.
result
else
:
return
self
.
result
class
Editor
:
...
...
Lib/idlelib/idle_test/test_widgetredir.py
0 → 100644
View file @
223dd8d7
"""Unittest for idlelib.WidgetRedirector
100% coverage
"""
from
test.support
import
requires
import
unittest
from
idlelib.idle_test.mock_idle
import
Func
from
tkinter
import
Tk
,
Text
,
TclError
from
idlelib.WidgetRedirector
import
WidgetRedirector
class
InitCloseTest
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
requires
(
'gui'
)
cls
.
tk
=
Tk
()
cls
.
text
=
Text
(
cls
.
tk
)
@
classmethod
def
tearDownClass
(
cls
):
cls
.
text
.
destroy
()
cls
.
tk
.
destroy
()
del
cls
.
text
,
cls
.
tk
def
test_init
(
self
):
redir
=
WidgetRedirector
(
self
.
text
)
self
.
assertEqual
(
redir
.
widget
,
self
.
text
)
self
.
assertEqual
(
redir
.
tk
,
self
.
text
.
tk
)
self
.
assertRaises
(
TclError
,
WidgetRedirector
,
self
.
text
)
redir
.
close
()
# restore self.tk, self.text
def
test_close
(
self
):
redir
=
WidgetRedirector
(
self
.
text
)
redir
.
register
(
'insert'
,
Func
)
redir
.
close
()
self
.
assertEqual
(
redir
.
_operations
,
{})
self
.
assertFalse
(
hasattr
(
self
.
text
,
'widget'
))
class
WidgetRedirectorTest
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
requires
(
'gui'
)
cls
.
tk
=
Tk
()
cls
.
text
=
Text
(
cls
.
tk
)
@
classmethod
def
tearDownClass
(
cls
):
cls
.
text
.
destroy
()
cls
.
tk
.
destroy
()
del
cls
.
text
,
cls
.
tk
def
setUp
(
self
):
self
.
redir
=
WidgetRedirector
(
self
.
text
)
self
.
func
=
Func
()
self
.
orig_insert
=
self
.
redir
.
register
(
'insert'
,
self
.
func
)
self
.
text
.
insert
(
'insert'
,
'asdf'
)
# leaves self.text empty
def
tearDown
(
self
):
self
.
text
.
delete
(
'1.0'
,
'end'
)
self
.
redir
.
close
()
def
test_repr
(
self
):
# partly for 100% coverage
self
.
assertIn
(
'Redirector'
,
repr
(
self
.
redir
))
self
.
assertIn
(
'Original'
,
repr
(
self
.
orig_insert
))
def
test_register
(
self
):
self
.
assertEqual
(
self
.
text
.
get
(
'1.0'
,
'end'
),
'
\
n
'
)
self
.
assertEqual
(
self
.
func
.
args
,
(
'insert'
,
'asdf'
))
self
.
assertIn
(
'insert'
,
self
.
redir
.
_operations
)
self
.
assertIn
(
'insert'
,
self
.
text
.
__dict__
)
self
.
assertEqual
(
self
.
text
.
insert
,
self
.
func
)
def
test_original_command
(
self
):
self
.
assertEqual
(
self
.
orig_insert
.
operation
,
'insert'
)
self
.
assertEqual
(
self
.
orig_insert
.
tk_call
,
self
.
text
.
tk
.
call
)
self
.
orig_insert
(
'insert'
,
'asdf'
)
self
.
assertEqual
(
self
.
text
.
get
(
'1.0'
,
'end'
),
'asdf
\
n
'
)
def
test_unregister
(
self
):
self
.
assertIsNone
(
self
.
redir
.
unregister
(
'invalid operation name'
))
self
.
assertEqual
(
self
.
redir
.
unregister
(
'insert'
),
self
.
func
)
self
.
assertNotIn
(
'insert'
,
self
.
redir
.
_operations
)
self
.
assertNotIn
(
'insert'
,
self
.
text
.
__dict__
)
def
test_unregister_no_attribute
(
self
):
del
self
.
text
.
insert
self
.
assertEqual
(
self
.
redir
.
unregister
(
'insert'
),
self
.
func
)
def
test_dispatch_intercept
(
self
):
self
.
func
.
__init__
(
True
)
self
.
assertTrue
(
self
.
redir
.
dispatch
(
'insert'
,
False
))
self
.
assertFalse
(
self
.
func
.
args
[
0
])
def
test_dispatch_bypass
(
self
):
self
.
orig_insert
(
'insert'
,
'asdf'
)
# tk.call returns '' where Python would return None
self
.
assertEqual
(
self
.
redir
.
dispatch
(
'delete'
,
'1.0'
,
'end'
),
''
)
self
.
assertEqual
(
self
.
text
.
get
(
'1.0'
,
'end'
),
'
\
n
'
)
def
test_dispatch_error
(
self
):
self
.
func
.
__init__
(
TclError
())
self
.
assertEqual
(
self
.
redir
.
dispatch
(
'insert'
,
False
),
''
)
self
.
assertEqual
(
self
.
redir
.
dispatch
(
'invalid'
),
''
)
def
test_command_dispatch
(
self
):
# Test that .__init__ causes redirection of tk calls
# through redir.dispatch
self
.
tk
.
call
(
self
.
text
.
_w
,
'insert'
,
'hello'
)
self
.
assertEqual
(
self
.
func
.
args
,
(
'hello'
,))
self
.
assertEqual
(
self
.
text
.
get
(
'1.0'
,
'end'
),
'
\
n
'
)
# Ensure that called through redir .dispatch and not through
# self.text.insert by having mock raise TclError.
self
.
func
.
__init__
(
TclError
())
self
.
assertEqual
(
self
.
tk
.
call
(
self
.
text
.
_w
,
'insert'
,
'boo'
),
''
)
if
__name__
==
'__main__'
:
unittest
.
main
(
verbosity
=
2
)
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