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

Skip to content

Commit 31e4d32

Browse files
committed
Issue #18489: Add complete, gui-free tests for idlelib.SearchEngine.
Patch import and initialization in SearchEngine to make testing easier. Improve docstrings, especially to clarify the double role of 'ok' parameters. Original patch by Phil Webster.
1 parent a839271 commit 31e4d32

3 files changed

Lines changed: 366 additions & 34 deletions

File tree

Lib/idlelib/SearchEngine.py

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'''Define SearchEngine for search dialogs.'''
22
import re
3-
from tkinter import *
3+
from tkinter import StringVar, BooleanVar, TclError
44
import tkinter.messagebox as tkMessageBox
55

66
def get(root):
@@ -22,14 +22,13 @@ def __init__(self, root):
2222
2323
The dialogs bind these to the UI elements present in the dialogs.
2424
'''
25-
self.root = root
26-
self.patvar = StringVar(root) # search pattern
27-
self.revar = BooleanVar(root) # regular expression?
28-
self.casevar = BooleanVar(root) # match case?
29-
self.wordvar = BooleanVar(root) # match whole word?
30-
self.wrapvar = BooleanVar(root) # wrap around buffer?
31-
self.wrapvar.set(1) # (on by default)
32-
self.backvar = BooleanVar(root) # search backwards?
25+
self.root = root # need for report_error()
26+
self.patvar = StringVar(root, '') # search pattern
27+
self.revar = BooleanVar(root, False) # regular expression?
28+
self.casevar = BooleanVar(root, False) # match case?
29+
self.wordvar = BooleanVar(root, False) # match whole word?
30+
self.wrapvar = BooleanVar(root, True) # wrap around buffer?
31+
self.backvar = BooleanVar(root, False) # search backwards?
3332

3433
# Access methods
3534

@@ -56,9 +55,16 @@ def isback(self):
5655

5756
# Higher level access methods
5857

58+
def setcookedpat(self, pat):
59+
"Set pattern after escaping if re."
60+
# called only in SearchDialog.py: 66
61+
if self.isre():
62+
pat = re.escape(pat)
63+
self.setpat(pat)
64+
5965
def getcookedpat(self):
6066
pat = self.getpat()
61-
if not self.isre():
67+
if not self.isre(): # if True, see setcookedpat
6268
pat = re.escape(pat)
6369
if self.isword():
6470
pat = r"\b%s\b" % pat
@@ -90,33 +96,28 @@ def report_error(self, pat, msg, col=-1):
9096
# Derived class could override this with something fancier
9197
msg = "Error: " + str(msg)
9298
if pat:
93-
msg = msg + "\np\Pattern: " + str(pat)
99+
msg = msg + "\nPattern: " + str(pat)
94100
if col >= 0:
95101
msg = msg + "\nOffset: " + str(col)
96102
tkMessageBox.showerror("Regular expression error",
97103
msg, master=self.root)
98104

99-
def setcookedpat(self, pat):
100-
if self.isre():
101-
pat = re.escape(pat)
102-
self.setpat(pat)
103-
104105
def search_text(self, text, prog=None, ok=0):
105-
'''Return (lineno, matchobj) for prog in text widget, or None.
106+
'''Return (lineno, matchobj) or None for forward/backward search.
107+
108+
This function calls the right function with the right arguments.
109+
It directly return the result of that call.
106110
107-
If prog is given, it should be a precompiled pattern.
108-
Wrap (yes/no) and direction (forward/back) settings are used.
111+
Text is a text widget. Prog is a precompiled pattern.
112+
The ok parameteris a bit complicated as it has two effects.
109113
110-
The search starts at the selection (if there is one) or at the
111-
insert mark (otherwise). If the search is forward, it starts
112-
at the right of the selection; for a backward search, it
113-
starts at the left end. An empty match exactly at either end
114-
of the selection (or at the insert mark if there is no
115-
selection) is ignored unless the ok flag is true -- this is
116-
done to guarantee progress.
114+
If there is a selection, the search begin at either end,
115+
depending on the direction setting and ok, with ok meaning that
116+
the search starts with the selection. Otherwise, search begins
117+
at the insert mark.
117118
118-
If the search is allowed to wrap around, it will return the
119-
original selection if (and only if) it is the only match.
119+
To aid progress, the search functions do not return an empty
120+
match at the starting position unless ok is True.
120121
'''
121122

122123
if not prog:
@@ -188,15 +189,18 @@ def search_backward(self, text, prog, line, col, wrap, ok=0):
188189
return None
189190

190191
def search_reverse(prog, chars, col):
191-
'''Search backwards in a string (line of text).
192+
'''Search backwards and return an re match object or None.
192193
193194
This is done by searching forwards until there is no match.
195+
Prog: compiled re object with a search method returning a match.
196+
Chars: line of text, without \n.
197+
Col: stop index for the search; the limit for match.end().
194198
'''
195199
m = prog.search(chars)
196200
if not m:
197201
return None
198202
found = None
199-
i, j = m.span()
203+
i, j = m.span() # m.start(), m.end() == match slice indexes
200204
while i < col and j <= col:
201205
found = m
202206
if i == j:
@@ -226,7 +230,7 @@ def get_line_col(index):
226230
line, col = map(int, index.split(".")) # Fails on invalid index
227231
return line, col
228232

229-
##if __name__ == "__main__":
230-
## from test import support; support.use_resources = ['gui']
231-
## import unittest
232-
## unittest.main('idlelib.idle_test.test_searchengine', verbosity=2, exit=False)
233+
if __name__ == "__main__":
234+
from test import support; support.use_resources = ['gui']
235+
import unittest
236+
unittest.main('idlelib.idle_test.test_searchengine', verbosity=2, exit=False)

0 commit comments

Comments
 (0)