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
ee0f927b
Commit
ee0f927b
authored
Feb 19, 2019
by
Cheryl Sabella
Committed by
Terry Jan Reedy
Feb 19, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-35689: IDLE: Add docstrings and unittests for colorizer.py (GH-11472)
parent
4371c0a9
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
408 additions
and
16 deletions
+408
-16
Lib/idlelib/NEWS.txt
Lib/idlelib/NEWS.txt
+2
-0
Lib/idlelib/colorizer.py
Lib/idlelib/colorizer.py
+57
-6
Lib/idlelib/idle_test/test_colorizer.py
Lib/idlelib/idle_test/test_colorizer.py
+348
-10
Misc/NEWS.d/next/IDLE/2019-01-08-17-51-44.bpo-35689.LlaqR8.rst
...NEWS.d/next/IDLE/2019-01-08-17-51-44.bpo-35689.LlaqR8.rst
+1
-0
No files found.
Lib/idlelib/NEWS.txt
View file @
ee0f927b
...
...
@@ -3,6 +3,8 @@ Released on 2019-10-20?
======================================
bpo-35689: Add docstrings and tests for colorizer.
bpo-35833: Revise IDLE doc for control codes sent to Shell.
Add a code example block.
...
...
Lib/idlelib/colorizer.py
View file @
ee0f927b
...
...
@@ -53,6 +53,21 @@ def color_config(text):
class
ColorDelegator
(
Delegator
):
"""Delegator for syntax highlighting (text coloring).
Class variables:
after_id: Identifier for scheduled after event.
allow_colorizing: Boolean toggle for applying colorizing.
colorizing: Boolean flag when colorizing is in process.
stop_colorizing: Boolean flag to end an active colorizing
process.
close_when_done: Widget to destroy after colorizing process
completes (doesn't seem to be used by IDLE).
Instance variables:
delegate: Delegator below this one in the stack, meaning the
one this one delegates to.
"""
def
__init__
(
self
):
Delegator
.
__init__
(
self
)
...
...
@@ -61,6 +76,16 @@ class ColorDelegator(Delegator):
self
.
LoadTagDefs
()
def
setdelegate
(
self
,
delegate
):
"""Set the delegate for this instance.
A delegate is an instance of a Delegator class and each
delegate points to the next delegator in the stack. This
allows multiple delegators to be chained together for a
widget. The bottom delegate for a colorizer is a Text
widget.
If there is a delegate, also start the colorizing process.
"""
if
self
.
delegate
is
not
None
:
self
.
unbind
(
"<<toggle-auto-coloring>>"
)
Delegator
.
setdelegate
(
self
,
delegate
)
...
...
@@ -69,17 +94,18 @@ class ColorDelegator(Delegator):
self
.
bind
(
"<<toggle-auto-coloring>>"
,
self
.
toggle_colorize_event
)
self
.
notify_range
(
"1.0"
,
"end"
)
else
:
# No delegate - stop any colorizing
# No delegate - stop any colorizing
.
self
.
stop_colorizing
=
True
self
.
allow_colorizing
=
False
def
config_colors
(
self
):
"Configure text widget tags with colors from tagdefs."
for
tag
,
cnf
in
self
.
tagdefs
.
items
():
if
cnf
:
self
.
tag_configure
(
tag
,
**
cnf
)
self
.
tag_configure
(
tag
,
**
cnf
)
self
.
tag_raise
(
'sel'
)
def
LoadTagDefs
(
self
):
"Create dictionary of tag names to text colors."
theme
=
idleConf
.
CurrentTheme
()
self
.
tagdefs
=
{
"COMMENT"
:
idleConf
.
GetHighlight
(
theme
,
"comment"
),
...
...
@@ -97,20 +123,24 @@ class ColorDelegator(Delegator):
if
DEBUG
:
print
(
'tagdefs'
,
self
.
tagdefs
)
def
insert
(
self
,
index
,
chars
,
tags
=
None
):
"Insert chars into widget at index and mark for colorizing."
index
=
self
.
index
(
index
)
self
.
delegate
.
insert
(
index
,
chars
,
tags
)
self
.
notify_range
(
index
,
index
+
"+%dc"
%
len
(
chars
))
def
delete
(
self
,
index1
,
index2
=
None
):
"Delete chars between indexes and mark for colorizing."
index1
=
self
.
index
(
index1
)
self
.
delegate
.
delete
(
index1
,
index2
)
self
.
notify_range
(
index1
)
after_id
=
None
allow_colorizing
=
True
stop_colorizing
=
False
colorizing
=
False
def
notify_range
(
self
,
index1
,
index2
=
None
):
"Mark text changes for processing and restart colorizing, if active."
self
.
tag_add
(
"TODO"
,
index1
,
index2
)
if
self
.
after_id
:
if
DEBUG
:
print
(
"colorizing already scheduled"
)
...
...
@@ -121,8 +151,9 @@ class ColorDelegator(Delegator):
if
self
.
allow_colorizing
:
if
DEBUG
:
print
(
"schedule colorizing"
)
self
.
after_id
=
self
.
after
(
1
,
self
.
recolorize
)
return
close_when_done
=
None
# Window to be closed when done colorizing
close_when_done
=
None
# Window to be closed when done colorizing.
def
close
(
self
,
close_when_done
=
None
):
if
self
.
after_id
:
...
...
@@ -138,7 +169,14 @@ class ColorDelegator(Delegator):
else
:
self
.
close_when_done
=
close_when_done
def
toggle_colorize_event
(
self
,
event
):
def
toggle_colorize_event
(
self
,
event
=
None
):
"""Toggle colorizing on and off.
When toggling off, if colorizing is scheduled or is in
process, it will be cancelled and/or stopped.
When toggling on, colorizing will be scheduled.
"""
if
self
.
after_id
:
after_id
=
self
.
after_id
self
.
after_id
=
None
...
...
@@ -156,6 +194,17 @@ class ColorDelegator(Delegator):
return
"break"
def
recolorize
(
self
):
"""Timer event (every 1ms) to colorize text.
Colorizing is only attempted when the text widget exists,
when colorizing is toggled on, and when the colorizing
process is not already running.
After colorizing is complete, some cleanup is done to
make sure that all the text has been colorized and to close
the window if the close event had been called while the
process was running.
"""
self
.
after_id
=
None
if
not
self
.
delegate
:
if
DEBUG
:
print
(
"no delegate"
)
...
...
@@ -185,6 +234,7 @@ class ColorDelegator(Delegator):
top
.
destroy
()
def
recolorize_main
(
self
):
"Evaluate text and apply colorizing tags."
next
=
"1.0"
while
True
:
item
=
self
.
tag_nextrange
(
"TODO"
,
next
)
...
...
@@ -250,6 +300,7 @@ class ColorDelegator(Delegator):
return
def
removecolors
(
self
):
"Remove all colorizing tags."
for
tag
in
self
.
tagdefs
:
self
.
tag_remove
(
tag
,
"1.0"
,
"end"
)
...
...
@@ -273,7 +324,7 @@ def _color_delegator(parent): # htest #
"'x', '''x''',
\
"
x
\
"
,
\
"
\
"
\
"
x
\
"
\
"
\
"
\
n
"
"r'x', u'x', R'x', U'x', f'x', F'x'
\
n
"
"fr'x', Fr'x', fR'x', FR'x', rf'x', rF'x', Rf'x', RF'x'
\
n
"
"b'x',B'x', br'x',Br'x',bR'x',BR'x', rb'x'
.
rB'x',Rb'x',RB'x'
\
n
"
"b'x',B'x', br'x',Br'x',bR'x',BR'x', rb'x'
,
rB'x',Rb'x',RB'x'
\
n
"
"# Invalid combinations of legal characters should be half colored.
\
n
"
"ur'x', ru'x', uf'x', fu'x', UR'x', ufr'x', rfu'x', xf'x', fx'x'
\
n
"
)
...
...
Lib/idlelib/idle_test/test_colorizer.py
View file @
ee0f927b
"Test colorizer, coverage
25
%."
"Test colorizer, coverage
93
%."
from
idlelib
import
colorizer
from
test.support
import
requires
from
tkinter
import
Tk
,
Text
import
unittest
from
unittest
import
mock
from
functools
import
partial
from
tkinter
import
Tk
,
Text
from
idlelib
import
config
from
idlelib.percolator
import
Percolator
usercfg
=
colorizer
.
idleConf
.
userCfg
testcfg
=
{
'main'
:
config
.
IdleUserConfParser
(
''
),
'highlight'
:
config
.
IdleUserConfParser
(
''
),
'keys'
:
config
.
IdleUserConfParser
(
''
),
'extensions'
:
config
.
IdleUserConfParser
(
''
),
}
source
=
(
"if True: int ('1') # keyword, builtin, string, comment
\
n
"
"elif False: print(0) # 'string' in comment
\
n
"
"else: float(None) # if in comment
\
n
"
"if iF + If + IF: 'keyword matching must respect case'
\
n
"
"if'': x or'' # valid string-keyword no-space combinations
\
n
"
"async def f(): await g()
\
n
"
"'x', '''x''',
\
"
x
\
"
,
\
"
\
"
\
"
x
\
"
\
"
\
"
\
n
"
)
def
setUpModule
():
colorizer
.
idleConf
.
userCfg
=
testcfg
def
tearDownModule
():
colorizer
.
idleConf
.
userCfg
=
usercfg
class
FunctionTest
(
unittest
.
TestCase
):
def
test_any
(
self
):
self
.
assertTrue
(
colorizer
.
any
(
'test'
,
(
'a'
,
'b'
)))
self
.
assertEqual
(
colorizer
.
any
(
'test'
,
(
'a'
,
'b'
,
'cd'
)),
'(?P<test>a|b|cd)'
)
def
test_make_pat
(
self
):
# Tested in more detail by testing prog.
self
.
assertTrue
(
colorizer
.
make_pat
())
def
test_prog
(
self
):
prog
=
colorizer
.
prog
eq
=
self
.
assertEqual
line
=
'def f():
\
n
print("hello")
\
n
'
m
=
prog
.
search
(
line
)
eq
(
m
.
groupdict
()[
'KEYWORD'
],
'def'
)
m
=
prog
.
search
(
line
,
m
.
end
())
eq
(
m
.
groupdict
()[
'SYNC'
],
'
\
n
'
)
m
=
prog
.
search
(
line
,
m
.
end
())
eq
(
m
.
groupdict
()[
'BUILTIN'
],
'print'
)
m
=
prog
.
search
(
line
,
m
.
end
())
eq
(
m
.
groupdict
()[
'STRING'
],
'"hello"'
)
m
=
prog
.
search
(
line
,
m
.
end
())
eq
(
m
.
groupdict
()[
'SYNC'
],
'
\
n
'
)
def
test_idprog
(
self
):
idprog
=
colorizer
.
idprog
m
=
idprog
.
match
(
'nospace'
)
self
.
assertIsNone
(
m
)
m
=
idprog
.
match
(
' space'
)
self
.
assertEqual
(
m
.
group
(
0
),
' space'
)
class
ColorConfigTest
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
requires
(
'gui'
)
cls
.
root
=
Tk
()
cls
.
text
=
Text
(
cls
.
root
)
root
=
cls
.
root
=
Tk
()
root
.
withdraw
()
cls
.
text
=
Text
(
root
)
@
classmethod
def
tearDownClass
(
cls
):
del
cls
.
text
cls
.
root
.
update_idletasks
()
cls
.
root
.
destroy
()
del
cls
.
root
def
test_colorizer
(
self
):
colorizer
.
color_config
(
self
.
text
)
def
test_color_config
(
self
):
text
=
self
.
text
eq
=
self
.
assertEqual
colorizer
.
color_config
(
text
)
# Uses IDLE Classic theme as default.
eq
(
text
[
'background'
],
'#ffffff'
)
eq
(
text
[
'foreground'
],
'#000000'
)
eq
(
text
[
'selectbackground'
],
'gray'
)
eq
(
text
[
'selectforeground'
],
'#000000'
)
eq
(
text
[
'insertbackground'
],
'black'
)
eq
(
text
[
'inactiveselectbackground'
],
'gray'
)
class
ColorDelegatorTest
(
unittest
.
TestCase
):
...
...
@@ -38,15 +105,286 @@ class ColorDelegatorTest(unittest.TestCase):
@
classmethod
def
setUpClass
(
cls
):
requires
(
'gui'
)
cls
.
root
=
Tk
()
root
=
cls
.
root
=
Tk
()
root
.
withdraw
()
text
=
cls
.
text
=
Text
(
root
)
cls
.
percolator
=
Percolator
(
text
)
# Delegator stack = [Delagator(text)]
@
classmethod
def
tearDownClass
(
cls
):
cls
.
percolator
.
redir
.
close
()
del
cls
.
percolator
,
cls
.
text
cls
.
root
.
update_idletasks
()
cls
.
root
.
destroy
()
del
cls
.
root
def
test_colorizer
(
self
):
colorizer
.
ColorDelegator
()
def
setUp
(
self
):
self
.
color
=
colorizer
.
ColorDelegator
()
self
.
percolator
.
insertfilter
(
self
.
color
)
# Calls color.setdelagate(Delagator(text)).
def
tearDown
(
self
):
self
.
color
.
close
()
self
.
percolator
.
removefilter
(
self
.
color
)
self
.
text
.
delete
(
'1.0'
,
'end'
)
self
.
color
.
resetcache
()
del
self
.
color
def
test_init
(
self
):
color
=
self
.
color
self
.
assertIsInstance
(
color
,
colorizer
.
ColorDelegator
)
# The following are class variables.
self
.
assertTrue
(
color
.
allow_colorizing
)
self
.
assertFalse
(
color
.
colorizing
)
def
test_setdelegate
(
self
):
# Called in setUp.
color
=
self
.
color
self
.
assertIsInstance
(
color
.
delegate
,
colorizer
.
Delegator
)
# It is too late to mock notify_range, so test side effect.
self
.
assertEqual
(
self
.
root
.
tk
.
call
(
'after'
,
'info'
,
color
.
after_id
)[
1
],
'timer'
)
def
test_LoadTagDefs
(
self
):
highlight
=
partial
(
config
.
idleConf
.
GetHighlight
,
theme
=
'IDLE Classic'
)
for
tag
,
colors
in
self
.
color
.
tagdefs
.
items
():
with
self
.
subTest
(
tag
=
tag
):
self
.
assertIn
(
'background'
,
colors
)
self
.
assertIn
(
'foreground'
,
colors
)
if
tag
not
in
(
'SYNC'
,
'TODO'
):
self
.
assertEqual
(
colors
,
highlight
(
element
=
tag
.
lower
()))
def
test_config_colors
(
self
):
text
=
self
.
text
highlight
=
partial
(
config
.
idleConf
.
GetHighlight
,
theme
=
'IDLE Classic'
)
for
tag
in
self
.
color
.
tagdefs
:
for
plane
in
(
'background'
,
'foreground'
):
with
self
.
subTest
(
tag
=
tag
,
plane
=
plane
):
if
tag
in
(
'SYNC'
,
'TODO'
):
self
.
assertEqual
(
text
.
tag_cget
(
tag
,
plane
),
''
)
else
:
self
.
assertEqual
(
text
.
tag_cget
(
tag
,
plane
),
highlight
(
element
=
tag
.
lower
())[
plane
])
# 'sel' is marked as the highest priority.
self
.
assertEqual
(
text
.
tag_names
()[
-
1
],
'sel'
)
@
mock
.
patch
.
object
(
colorizer
.
ColorDelegator
,
'notify_range'
)
def
test_insert
(
self
,
mock_notify
):
text
=
self
.
text
# Initial text.
text
.
insert
(
'insert'
,
'foo'
)
self
.
assertEqual
(
text
.
get
(
'1.0'
,
'end'
),
'foo
\
n
'
)
mock_notify
.
assert_called_with
(
'1.0'
,
'1.0+3c'
)
# Additional text.
text
.
insert
(
'insert'
,
'barbaz'
)
self
.
assertEqual
(
text
.
get
(
'1.0'
,
'end'
),
'foobarbaz
\
n
'
)
mock_notify
.
assert_called_with
(
'1.3'
,
'1.3+6c'
)
@
mock
.
patch
.
object
(
colorizer
.
ColorDelegator
,
'notify_range'
)
def
test_delete
(
self
,
mock_notify
):
text
=
self
.
text
# Initialize text.
text
.
insert
(
'insert'
,
'abcdefghi'
)
self
.
assertEqual
(
text
.
get
(
'1.0'
,
'end'
),
'abcdefghi
\
n
'
)
# Delete single character.
text
.
delete
(
'1.7'
)
self
.
assertEqual
(
text
.
get
(
'1.0'
,
'end'
),
'abcdefgi
\
n
'
)
mock_notify
.
assert_called_with
(
'1.7'
)
# Delete multiple characters.
text
.
delete
(
'1.3'
,
'1.6'
)
self
.
assertEqual
(
text
.
get
(
'1.0'
,
'end'
),
'abcgi
\
n
'
)
mock_notify
.
assert_called_with
(
'1.3'
)
def
test_notify_range
(
self
):
text
=
self
.
text
color
=
self
.
color
eq
=
self
.
assertEqual
# Colorizing already scheduled.
save_id
=
color
.
after_id
eq
(
self
.
root
.
tk
.
call
(
'after'
,
'info'
,
save_id
)[
1
],
'timer'
)
self
.
assertFalse
(
color
.
colorizing
)
self
.
assertFalse
(
color
.
stop_colorizing
)
self
.
assertTrue
(
color
.
allow_colorizing
)
# Coloring scheduled and colorizing in progress.
color
.
colorizing
=
True
color
.
notify_range
(
'1.0'
,
'end'
)
self
.
assertFalse
(
color
.
stop_colorizing
)
eq
(
color
.
after_id
,
save_id
)
# No colorizing scheduled and colorizing in progress.
text
.
after_cancel
(
save_id
)
color
.
after_id
=
None
color
.
notify_range
(
'1.0'
,
'1.0+3c'
)
self
.
assertTrue
(
color
.
stop_colorizing
)
self
.
assertIsNotNone
(
color
.
after_id
)
eq
(
self
.
root
.
tk
.
call
(
'after'
,
'info'
,
color
.
after_id
)[
1
],
'timer'
)
# New event scheduled.
self
.
assertNotEqual
(
color
.
after_id
,
save_id
)
# No colorizing scheduled and colorizing off.
text
.
after_cancel
(
color
.
after_id
)
color
.
after_id
=
None
color
.
allow_colorizing
=
False
color
.
notify_range
(
'1.4'
,
'1.4+10c'
)
# Nothing scheduled when colorizing is off.
self
.
assertIsNone
(
color
.
after_id
)
def
test_toggle_colorize_event
(
self
):
color
=
self
.
color
eq
=
self
.
assertEqual
# Starts with colorizing allowed and scheduled.
self
.
assertFalse
(
color
.
colorizing
)
self
.
assertFalse
(
color
.
stop_colorizing
)
self
.
assertTrue
(
color
.
allow_colorizing
)
eq
(
self
.
root
.
tk
.
call
(
'after'
,
'info'
,
color
.
after_id
)[
1
],
'timer'
)
# Toggle colorizing off.
color
.
toggle_colorize_event
()
self
.
assertIsNone
(
color
.
after_id
)
self
.
assertFalse
(
color
.
colorizing
)
self
.
assertFalse
(
color
.
stop_colorizing
)
self
.
assertFalse
(
color
.
allow_colorizing
)
# Toggle on while colorizing in progress (doesn't add timer).
color
.
colorizing
=
True
color
.
toggle_colorize_event
()
self
.
assertIsNone
(
color
.
after_id
)
self
.
assertTrue
(
color
.
colorizing
)
self
.
assertFalse
(
color
.
stop_colorizing
)
self
.
assertTrue
(
color
.
allow_colorizing
)
# Toggle off while colorizing in progress.
color
.
toggle_colorize_event
()
self
.
assertIsNone
(
color
.
after_id
)
self
.
assertTrue
(
color
.
colorizing
)
self
.
assertTrue
(
color
.
stop_colorizing
)
self
.
assertFalse
(
color
.
allow_colorizing
)
# Toggle on while colorizing not in progress.
color
.
colorizing
=
False
color
.
toggle_colorize_event
()
eq
(
self
.
root
.
tk
.
call
(
'after'
,
'info'
,
color
.
after_id
)[
1
],
'timer'
)
self
.
assertFalse
(
color
.
colorizing
)
self
.
assertTrue
(
color
.
stop_colorizing
)
self
.
assertTrue
(
color
.
allow_colorizing
)
@
mock
.
patch
.
object
(
colorizer
.
ColorDelegator
,
'recolorize_main'
)
def
test_recolorize
(
self
,
mock_recmain
):
text
=
self
.
text
color
=
self
.
color
eq
=
self
.
assertEqual
# Call recolorize manually and not scheduled.
text
.
after_cancel
(
color
.
after_id
)
# No delegate.
save_delegate
=
color
.
delegate
color
.
delegate
=
None
color
.
recolorize
()
mock_recmain
.
assert_not_called
()
color
.
delegate
=
save_delegate
# Toggle off colorizing.
color
.
allow_colorizing
=
False
color
.
recolorize
()
mock_recmain
.
assert_not_called
()
color
.
allow_colorizing
=
True
# Colorizing in progress.
color
.
colorizing
=
True
color
.
recolorize
()
mock_recmain
.
assert_not_called
()
color
.
colorizing
=
False
# Colorizing is done, but not completed, so rescheduled.
color
.
recolorize
()
self
.
assertFalse
(
color
.
stop_colorizing
)
self
.
assertFalse
(
color
.
colorizing
)
mock_recmain
.
assert_called
()
eq
(
mock_recmain
.
call_count
,
1
)
# Rescheduled when TODO tag still exists.
eq
(
self
.
root
.
tk
.
call
(
'after'
,
'info'
,
color
.
after_id
)[
1
],
'timer'
)
# No changes to text, so no scheduling added.
text
.
tag_remove
(
'TODO'
,
'1.0'
,
'end'
)
color
.
recolorize
()
self
.
assertFalse
(
color
.
stop_colorizing
)
self
.
assertFalse
(
color
.
colorizing
)
mock_recmain
.
assert_called
()
eq
(
mock_recmain
.
call_count
,
2
)
self
.
assertIsNone
(
color
.
after_id
)
@
mock
.
patch
.
object
(
colorizer
.
ColorDelegator
,
'notify_range'
)
def
test_recolorize_main
(
self
,
mock_notify
):
text
=
self
.
text
color
=
self
.
color
eq
=
self
.
assertEqual
text
.
insert
(
'insert'
,
source
)
expected
=
((
'1.0'
,
(
'KEYWORD'
,)),
(
'1.2'
,
()),
(
'1.3'
,
(
'KEYWORD'
,)),
(
'1.7'
,
()),
(
'1.9'
,
(
'BUILTIN'
,)),
(
'1.14'
,
(
'STRING'
,)),
(
'1.19'
,
(
'COMMENT'
,)),
(
'2.1'
,
(
'KEYWORD'
,)),
(
'2.18'
,
()),
(
'2.25'
,
(
'COMMENT'
,)),
(
'3.6'
,
(
'BUILTIN'
,)),
(
'3.12'
,
(
'KEYWORD'
,)),
(
'3.21'
,
(
'COMMENT'
,)),
(
'4.0'
,
(
'KEYWORD'
,)),
(
'4.3'
,
()),
(
'4.6'
,
()),
(
'5.2'
,
(
'STRING'
,)),
(
'5.8'
,
(
'KEYWORD'
,)),
(
'5.10'
,
(
'STRING'
,)),
(
'6.0'
,
(
'KEYWORD'
,)),
(
'6.10'
,
(
'DEFINITION'
,)),
(
'6.11'
,
()),
(
'7.0'
,
(
'STRING'
,)),
(
'7.4'
,
()),
(
'7.5'
,
(
'STRING'
,)),
(
'7.12'
,
()),
(
'7.14'
,
(
'STRING'
,)),
# SYNC at the end of every line.
(
'1.55'
,
(
'SYNC'
,)),
(
'2.50'
,
(
'SYNC'
,)),
(
'3.34'
,
(
'SYNC'
,)),
)
# Nothing marked to do therefore no tags in text.
text
.
tag_remove
(
'TODO'
,
'1.0'
,
'end'
)
color
.
recolorize_main
()
for
tag
in
text
.
tag_names
():
with
self
.
subTest
(
tag
=
tag
):
eq
(
text
.
tag_ranges
(
tag
),
())
# Source marked for processing.
text
.
tag_add
(
'TODO'
,
'1.0'
,
'end'
)
# Check some indexes.
color
.
recolorize_main
()
for
index
,
expected_tags
in
expected
:
with
self
.
subTest
(
index
=
index
):
eq
(
text
.
tag_names
(
index
),
expected_tags
)
# Check for some tags for ranges.
eq
(
text
.
tag_nextrange
(
'TODO'
,
'1.0'
),
())
eq
(
text
.
tag_nextrange
(
'KEYWORD'
,
'1.0'
),
(
'1.0'
,
'1.2'
))
eq
(
text
.
tag_nextrange
(
'COMMENT'
,
'2.0'
),
(
'2.22'
,
'2.43'
))
eq
(
text
.
tag_nextrange
(
'SYNC'
,
'2.0'
),
(
'2.43'
,
'3.0'
))
eq
(
text
.
tag_nextrange
(
'STRING'
,
'2.0'
),
(
'4.17'
,
'4.53'
))
eq
(
text
.
tag_nextrange
(
'STRING'
,
'7.0'
),
(
'7.0'
,
'7.3'
))
eq
(
text
.
tag_nextrange
(
'STRING'
,
'7.3'
),
(
'7.5'
,
'7.12'
))
eq
(
text
.
tag_nextrange
(
'STRING'
,
'7.12'
),
(
'7.14'
,
'7.17'
))
eq
(
text
.
tag_nextrange
(
'STRING'
,
'7.17'
),
(
'7.19'
,
'7.26'
))
eq
(
text
.
tag_nextrange
(
'SYNC'
,
'7.0'
),
(
'7.26'
,
'9.0'
))
@
mock
.
patch
.
object
(
colorizer
.
ColorDelegator
,
'recolorize'
)
@
mock
.
patch
.
object
(
colorizer
.
ColorDelegator
,
'notify_range'
)
def
test_removecolors
(
self
,
mock_notify
,
mock_recolorize
):
text
=
self
.
text
color
=
self
.
color
text
.
insert
(
'insert'
,
source
)
color
.
recolorize_main
()
# recolorize_main doesn't add these tags.
text
.
tag_add
(
"ERROR"
,
"1.0"
)
text
.
tag_add
(
"TODO"
,
"1.0"
)
text
.
tag_add
(
"hit"
,
"1.0"
)
for
tag
in
color
.
tagdefs
:
with
self
.
subTest
(
tag
=
tag
):
self
.
assertNotEqual
(
text
.
tag_ranges
(
tag
),
())
color
.
removecolors
()
for
tag
in
color
.
tagdefs
:
with
self
.
subTest
(
tag
=
tag
):
self
.
assertEqual
(
text
.
tag_ranges
(
tag
),
())
if
__name__
==
'__main__'
:
...
...
Misc/NEWS.d/next/IDLE/2019-01-08-17-51-44.bpo-35689.LlaqR8.rst
0 → 100644
View file @
ee0f927b
Add docstrings and unittests for colorizer.py.
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