Merge heads.
This commit is contained in:
commit
be856e9a21
|
@ -1,3 +1,17 @@
|
||||||
|
'''Complete the current word before the cursor with words in the editor.
|
||||||
|
|
||||||
|
Each menu selection or shortcut key selection replaces the word with a
|
||||||
|
different word with the same prefix. The search for matches begins
|
||||||
|
before the target and moves toward the top of the editor. It then starts
|
||||||
|
after the cursor and moves down. It then returns to the original word and
|
||||||
|
the cycle starts again.
|
||||||
|
|
||||||
|
Changing the current text line or leaving the cursor in a different
|
||||||
|
place before requesting the next selection causes AutoExpand to reset
|
||||||
|
its state.
|
||||||
|
|
||||||
|
This is an extension file and there is only one instance of AutoExpand.
|
||||||
|
'''
|
||||||
import string
|
import string
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
@ -20,6 +34,7 @@ class AutoExpand:
|
||||||
self.state = None
|
self.state = None
|
||||||
|
|
||||||
def expand_word_event(self, event):
|
def expand_word_event(self, event):
|
||||||
|
"Replace the current word with the next expansion."
|
||||||
curinsert = self.text.index("insert")
|
curinsert = self.text.index("insert")
|
||||||
curline = self.text.get("insert linestart", "insert lineend")
|
curline = self.text.get("insert linestart", "insert lineend")
|
||||||
if not self.state:
|
if not self.state:
|
||||||
|
@ -46,6 +61,7 @@ class AutoExpand:
|
||||||
return "break"
|
return "break"
|
||||||
|
|
||||||
def getwords(self):
|
def getwords(self):
|
||||||
|
"Return a list of words that match the prefix before the cursor."
|
||||||
word = self.getprevword()
|
word = self.getprevword()
|
||||||
if not word:
|
if not word:
|
||||||
return []
|
return []
|
||||||
|
@ -76,8 +92,13 @@ class AutoExpand:
|
||||||
return words
|
return words
|
||||||
|
|
||||||
def getprevword(self):
|
def getprevword(self):
|
||||||
|
"Return the word prefix before the cursor."
|
||||||
line = self.text.get("insert linestart", "insert")
|
line = self.text.get("insert linestart", "insert")
|
||||||
i = len(line)
|
i = len(line)
|
||||||
while i > 0 and line[i-1] in self.wordchars:
|
while i > 0 and line[i-1] in self.wordchars:
|
||||||
i = i-1
|
i = i-1
|
||||||
return line[i:]
|
return line[i:]
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import unittest
|
||||||
|
unittest.main('idlelib.idle_test.test_autoexpand', verbosity=2)
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
"""Unit tests for idlelib.AutoExpand"""
|
||||||
|
import unittest
|
||||||
|
from test.support import requires
|
||||||
|
from tkinter import Text, Tk
|
||||||
|
#from idlelib.idle_test.mock_tk import Text
|
||||||
|
from idlelib.AutoExpand import AutoExpand
|
||||||
|
|
||||||
|
|
||||||
|
class Dummy_Editwin:
|
||||||
|
# AutoExpand.__init__ only needs .text
|
||||||
|
def __init__(self, text):
|
||||||
|
self.text = text
|
||||||
|
|
||||||
|
class AutoExpandTest(unittest.TestCase):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
if 'tkinter' in str(Text):
|
||||||
|
requires('gui')
|
||||||
|
cls.tk = Tk()
|
||||||
|
cls.text = Text(cls.tk)
|
||||||
|
else:
|
||||||
|
cls.text = Text()
|
||||||
|
cls.auto_expand = AutoExpand(Dummy_Editwin(cls.text))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
if hasattr(cls, 'tk'):
|
||||||
|
cls.tk.destroy()
|
||||||
|
del cls.tk
|
||||||
|
del cls.text, cls.auto_expand
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.text.delete('1.0', 'end')
|
||||||
|
|
||||||
|
def test_get_prevword(self):
|
||||||
|
text = self.text
|
||||||
|
previous = self.auto_expand.getprevword
|
||||||
|
equal = self.assertEqual
|
||||||
|
|
||||||
|
equal(previous(), '')
|
||||||
|
|
||||||
|
text.insert('insert', 't')
|
||||||
|
equal(previous(), 't')
|
||||||
|
|
||||||
|
text.insert('insert', 'his')
|
||||||
|
equal(previous(), 'this')
|
||||||
|
|
||||||
|
text.insert('insert', ' ')
|
||||||
|
equal(previous(), '')
|
||||||
|
|
||||||
|
text.insert('insert', 'is')
|
||||||
|
equal(previous(), 'is')
|
||||||
|
|
||||||
|
text.insert('insert', '\nsample\nstring')
|
||||||
|
equal(previous(), 'string')
|
||||||
|
|
||||||
|
text.delete('3.0', 'insert')
|
||||||
|
equal(previous(), '')
|
||||||
|
|
||||||
|
text.delete('1.0', 'end')
|
||||||
|
equal(previous(), '')
|
||||||
|
|
||||||
|
def test_before_only(self):
|
||||||
|
previous = self.auto_expand.getprevword
|
||||||
|
expand = self.auto_expand.expand_word_event
|
||||||
|
equal = self.assertEqual
|
||||||
|
|
||||||
|
self.text.insert('insert', 'ab ac bx ad ab a')
|
||||||
|
equal(self.auto_expand.getwords(), ['ab', 'ad', 'ac', 'a'])
|
||||||
|
expand('event')
|
||||||
|
equal(previous(), 'ab')
|
||||||
|
expand('event')
|
||||||
|
equal(previous(), 'ad')
|
||||||
|
expand('event')
|
||||||
|
equal(previous(), 'ac')
|
||||||
|
expand('event')
|
||||||
|
equal(previous(), 'a')
|
||||||
|
|
||||||
|
def test_after_only(self):
|
||||||
|
# Also add punctuation 'noise' that shoud be ignored.
|
||||||
|
text = self.text
|
||||||
|
previous = self.auto_expand.getprevword
|
||||||
|
expand = self.auto_expand.expand_word_event
|
||||||
|
equal = self.assertEqual
|
||||||
|
|
||||||
|
text.insert('insert', 'a, [ab] ac: () bx"" cd ac= ad ya')
|
||||||
|
text.mark_set('insert', '1.1')
|
||||||
|
equal(self.auto_expand.getwords(), ['ab', 'ac', 'ad', 'a'])
|
||||||
|
expand('event')
|
||||||
|
equal(previous(), 'ab')
|
||||||
|
expand('event')
|
||||||
|
equal(previous(), 'ac')
|
||||||
|
expand('event')
|
||||||
|
equal(previous(), 'ad')
|
||||||
|
expand('event')
|
||||||
|
equal(previous(), 'a')
|
||||||
|
|
||||||
|
def test_both_before_after(self):
|
||||||
|
text = self.text
|
||||||
|
previous = self.auto_expand.getprevword
|
||||||
|
expand = self.auto_expand.expand_word_event
|
||||||
|
equal = self.assertEqual
|
||||||
|
|
||||||
|
text.insert('insert', 'ab xy yz\n')
|
||||||
|
text.insert('insert', 'a ac by ac')
|
||||||
|
|
||||||
|
text.mark_set('insert', '2.1')
|
||||||
|
equal(self.auto_expand.getwords(), ['ab', 'ac', 'a'])
|
||||||
|
expand('event')
|
||||||
|
equal(previous(), 'ab')
|
||||||
|
expand('event')
|
||||||
|
equal(previous(), 'ac')
|
||||||
|
expand('event')
|
||||||
|
equal(previous(), 'a')
|
||||||
|
|
||||||
|
def test_other_expand_cases(self):
|
||||||
|
text = self.text
|
||||||
|
expand = self.auto_expand.expand_word_event
|
||||||
|
equal = self.assertEqual
|
||||||
|
|
||||||
|
# no expansion candidate found
|
||||||
|
equal(self.auto_expand.getwords(), [])
|
||||||
|
equal(expand('event'), 'break')
|
||||||
|
|
||||||
|
text.insert('insert', 'bx cy dz a')
|
||||||
|
equal(self.auto_expand.getwords(), [])
|
||||||
|
|
||||||
|
# reset state by successfully expanding once
|
||||||
|
# move cursor to another position and expand again
|
||||||
|
text.insert('insert', 'ac xy a ac ad a')
|
||||||
|
text.mark_set('insert', '1.7')
|
||||||
|
expand('event')
|
||||||
|
initial_state = self.auto_expand.state
|
||||||
|
text.mark_set('insert', '1.end')
|
||||||
|
expand('event')
|
||||||
|
new_state = self.auto_expand.state
|
||||||
|
self.assertNotEqual(initial_state, new_state)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main(verbosity=2)
|
|
@ -450,6 +450,8 @@ Extension Modules
|
||||||
IDLE
|
IDLE
|
||||||
----
|
----
|
||||||
|
|
||||||
|
- Issue #18292: Add unittest for AutoExpand. Patch by Saihadhav Heblikar.
|
||||||
|
|
||||||
- Issue #18409: Add unittest for AutoComplete. Patch by Phil Webster.
|
- Issue #18409: Add unittest for AutoComplete. Patch by Phil Webster.
|
||||||
|
|
||||||
- Issue #21477: htest.py - Improve framework, complete set of tests.
|
- Issue #21477: htest.py - Improve framework, complete set of tests.
|
||||||
|
|
Loading…
Reference in New Issue