3
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
4
__cvsid__ = "$Id: test_introspect.py,v 1.3 2004/02/13 02:52:06 PKO Exp $"
5
__revision__ = "$Revision: 1.3 $"[11:-2]
9
# Import from this module's parent directory.
12
sys.path.insert(0, os.pardir)
20
These unittest methods are preferred:
21
-------------------------------------
22
self.assert_(expr, msg=None)
23
self.assertEqual(first, second, msg=None)
24
self.assertRaises(excClass, callableObj, *args, **kwargs)
26
self.failIf(expr, msg=None)
30
class ModuleTestCase(unittest.TestCase):
32
def test_module(self):
34
self.assert_(module.__author__)
35
self.assert_(module.__cvsid__)
36
self.assert_(module.__revision__)
37
self.assert_(module.getAllAttributeNames)
38
self.assert_(module.getAttributeNames)
39
self.assert_(module.getAutoCompleteList)
40
self.assert_(module.getBaseObject)
41
self.assert_(module.getCallTip)
42
self.assert_(module.getConstructor)
43
self.assert_(module.getRoot)
44
self.assert_(module.rtrimTerminus)
47
class RtrimTerminusTestCase(unittest.TestCase):
49
def test_rtrimTerminus(self):
67
('spam', None, 'spam'),
68
('spam', '.', 'spam'),
69
('spam', '(', 'spam'),
71
('spam.', '', 'spam.'),
72
('spam.', None, 'spam.'),
73
('spam.', '.', 'spam.'),
74
('spam.', '(', 'spam.'),
76
('spam(', '', 'spam('),
77
('spam(', None, 'spam('),
78
('spam(', '.', 'spam('),
79
('spam(', '(', 'spam('),
81
('spam.eggs', '.', 'spam.'),
82
('spam.eggs.', '.', 'spam.eggs.'),
83
('spam.eggs(', '(', 'spam.eggs('),
84
('spam.eggs.', '(', 'spam.eggs.'),
85
('spam.eggs(', '.', 'spam.'),
87
('x = spam.', '.', 'x = spam.'),
88
('x = spam.eggs', '.', 'x = spam.'),
89
('x = spam.eggs.', '.', 'x = spam.eggs.'),
90
('x = spam.eggs(', '(', 'x = spam.eggs('),
92
for input, terminator, output in values:
93
result = introspect.rtrimTerminus(input, terminator)
94
self.assertEqual(result, output,
95
':in: %r :t: %r :out: %r :result: %r' %
96
(input, terminator, output, result))
99
class GetRootTestCase(unittest.TestCase):
101
def _checkRoot(self, input, terminator, output):
102
root = introspect.getRoot(command=input, terminator=terminator)
103
self.assertEqual(root, output,
104
':in: %r :t: %r :out: %r :root: %r' %
105
(input, terminator, output, root))
107
def test_getRoot(self):
124
('spam', '', 'spam'),
125
('spam', None, 'spam'),
127
('spam', '(', 'spam'),
129
('spam.', '', 'spam.'),
130
('spam.', None, 'spam.'),
131
('spam.', '.', 'spam'),
132
('spam.', '(', 'spam.'),
137
('spam(', '(', 'spam'),
139
('spam.eggs', '.', 'spam'),
140
('spam.eggs.', '.', 'spam.eggs'),
141
('spam.eggs(', '(', 'spam.eggs'),
142
('spam.eggs.', '(', 'spam.eggs.'),
143
('spam.eggs(', '.', 'spam'),
145
('x = spam.', '.', 'spam'),
146
('x = spam.eggs', '.', 'spam'),
147
('x = spam.eggs.', '.', 'spam.eggs'),
148
('x = spam.eggs(', '(', 'spam.eggs'),
150
('for n in range(3):\n d.', '.', 'd'),
151
('for n in range(3):\n... d.', '.', 'd'),
153
for input, terminator, output in values:
154
self._checkRoot(input, terminator, output)
156
def test_getRoot_Advanced(self):
158
('spam_', '', 'spam_'),
159
('spam_', None, 'spam_'),
161
('spam_', '(', 'spam_'),
163
('_spam', '', '_spam'),
164
('_spam', None, '_spam'),
166
('_spam', '(', '_spam'),
168
('spam_eggs', '', 'spam_eggs'),
169
('spam_eggs', None, 'spam_eggs'),
170
('spam_eggs', '.', ''),
171
('spam_eggs', '(', 'spam_eggs'),
173
('spam123', '', 'spam123'),
174
('spam123', None, 'spam123'),
175
('spam123', '.', ''),
176
('spam123', '(', 'spam123'),
178
('spam_123', '', 'spam_123'),
179
('spam_123', None, 'spam_123'),
180
('spam_123', '.', ''),
181
('spam_123', '(', 'spam_123'),
183
for input, terminator, output in values:
184
self._checkRoot(input, terminator, output)
186
## The original intent was to detect when we were inside a string.
187
## That has proven to be very difficult, for little benefit.
188
## The fact that autocomplete or calltips might be triggered inside
189
## a string is not a big deal. Sometimes it is even helpful.
191
## def test_getRoot_InsideStrings(self):
193
## ('x = ".', '.', ''),
194
## ("x = '.", '.', ''),
195
## ('x = """.', '.', ''),
196
## ("x = '''.", '.', ''),
198
## ('x = "(', '(', ''),
199
## ("x = '(", '(', ''),
200
## ('x = """(', '(', ''),
201
## ("x = '''(", '(', ''),
203
## ('x = "spam', '.', ''),
204
## ('x = "spam.', '.', ''),
205
## ("x = 'spam.", '.', ''),
206
## ('x = """spam.', '.', ''),
207
## ("x = '''spam.", '.', ''),
209
## ('x = "spam', '(', ''),
210
## ('x = "spam(', '(', ''),
211
## ("x = 'spam(", '(', ''),
212
## ('x = """spam(', '(', ''),
213
## ("x = '''spam(", '(', ''),
215
## ('x = "spam.eggs.', '.', ''),
216
## ("x = 'spam.eggs.", '.', ''),
217
## ('x = """spam.eggs.', '.', ''),
218
## ("x = '''spam.eggs.", '.', ''),
220
## ('x = "spam.eggs(', '(', ''),
221
## ("x = 'spam.eggs(", '(', ''),
222
## ('x = """spam.eggs(', '(', ''),
223
## ("x = '''spam.eggs(", '(', ''),
225
## for input, terminator, output in values:
226
## self._checkRoot(input, terminator, output)
228
def test_getRoot_EmptyTypes(self):
232
('"""""".', '.', '""""""'),
233
("''''''.", '.', "''''''"),
243
("x = ''.", '.', "''"),
244
('x = "".', '.', '""'),
245
('x = """""".', '.', '""""""'),
246
("x = ''''''.", '.', "''''''"),
248
('x = [].', '.', '[]'),
249
('x = ().', '.', '()'),
250
('x = {}.', '.', '{}'),
252
('x = [](', '(', '[]'),
253
('x = ()(', '(', '()'),
254
('x = {}(', '(', '{}'),
256
('print [].', '.', '[]'),
257
('print ().', '.', '()'),
258
('print {}.', '.', '{}'),
260
('print [](', '(', '[]'),
261
('print ()(', '(', '()'),
262
('print {}(', '(', '{}'),
264
("''.attr.", '.', "''.attr"),
265
('"".attr.', '.', '"".attr'),
266
('"""""".attr.', '.', '"""""".attr'),
267
("''''''.attr.", '.', "''''''.attr"),
269
('[].attr.', '.', '[].attr'),
270
('().attr.', '.', '().attr'),
271
('{}.attr.', '.', '{}.attr'),
273
('[].attr(', '(', '[].attr'),
274
('().attr(', '(', '().attr'),
275
('{}.attr(', '(', '{}.attr'),
277
('spam().', '.', ''),
278
('spam_().', '.', ''),
279
('spam5().', '.', ''),
280
('spam[]().', '.', ''),
281
('spam()[].', '.', ''),
282
('spam[]{}.', '.', ''),
284
("spam(''.", '.', "''"),
285
('spam("".', '.', '""'),
286
('spam("""""".', '.', '""""""'),
287
("spam(''''''.", '.', "''''''"),
289
('spam([].', '.', '[]'),
290
('spam(().', '.', '()'),
291
('spam({}.', '.', '{}'),
292
('spam[[].', '.', '[]'),
293
('spam[().', '.', '()'),
294
('spam[{}.', '.', '{}'),
295
('x = {[].', '.', '[]'),
296
('x = {().', '.', '()'),
297
('x = {{}.', '.', '{}'),
299
('spam,[].', '.', '[]'),
300
('spam+[].', '.', '[]'),
301
('spam-[].', '.', '[]'),
302
('spam*[].', '.', '[]'),
303
('spam/[].', '.', '[]'),
304
('spam=[].', '.', '[]'),
305
('spam%[].', '.', '[]'),
306
('spam<[].', '.', '[]'),
307
('spam>[].', '.', '[]'),
308
('spam&[].', '.', '[]'),
309
('spam|[].', '.', '[]'),
310
('spam^[].', '.', '[]'),
311
('spam~[].', '.', '[]'),
312
('spam:[].', '.', '[]'),
314
('spam,().', '.', '()'),
315
('spam+().', '.', '()'),
316
('spam-().', '.', '()'),
317
('spam*().', '.', '()'),
318
('spam/().', '.', '()'),
319
('spam=().', '.', '()'),
320
('spam%().', '.', '()'),
321
('spam<().', '.', '()'),
322
('spam>().', '.', '()'),
323
('spam&().', '.', '()'),
324
('spam|().', '.', '()'),
325
('spam^().', '.', '()'),
326
('spam~().', '.', '()'),
327
('spam:().', '.', '()'),
329
('spam,{}.', '.', '{}'),
330
('spam+{}.', '.', '{}'),
331
('spam-{}.', '.', '{}'),
332
('spam*{}.', '.', '{}'),
333
('spam/{}.', '.', '{}'),
334
('spam={}.', '.', '{}'),
335
('spam%{}.', '.', '{}'),
336
('spam<{}.', '.', '{}'),
337
('spam>{}.', '.', '{}'),
338
('spam&{}.', '.', '{}'),
339
('spam|{}.', '.', '{}'),
340
('spam^{}.', '.', '{}'),
341
('spam~{}.', '.', '{}'),
342
('spam:{}.', '.', '{}'),
344
for input, terminator, output in values:
345
self._checkRoot(input, terminator, output)
348
# Support for GetBaseObjectTestCase and GetAttributeNamesTestCase.
371
# It shouldn't matter what we call "self".
380
class GetBaseObjectTestCase(unittest.TestCase):
382
def test_getBaseObject(self):
385
listappend = [].append
386
spamda = lambda: None
397
(listappend, listappend, 0),
400
# Byte-compiled code.
401
(ham.func_code, ham.func_code, 0),
405
(Foo, Foo.__init__.im_func, 1),
406
# Class with no init.
409
(spam.foo, spam.foo.im_func, 1),
410
# Bound method with self named something else (spam).
411
(spam.bar, spam.bar.im_func, 1),
412
# Unbound method. (Do not drop the self argument.)
413
(eggs, eggs.im_func, 0),
415
(spam, spam.__call__.im_func, 1),
417
for object, baseObject, dropSelf in values:
418
result = introspect.getBaseObject(object)
419
self.assertEqual(result, (baseObject, dropSelf))
422
class GetAttributeTestCase(unittest.TestCase):
423
"""Base class for other test case classes."""
513
'__warningregistry__',
621
# Since getAllAttributeNames() calls str(object),
622
# we need to test for a broken __str__ method.
627
brokenStr = BrokenStr()
629
class GetAttributeNamesTestCase(GetAttributeTestCase):
632
GetAttributeTestCase.setUp(self)
635
self.f = open('test_introspect.py')
654
# Byte-compiled code.
658
# Class with no init.
660
# Instance with no init.
662
# Class with init and del.
664
# Instance with init and del.
686
# BrokenStr instance.
694
def test_getAttributeNames(self):
695
for item in self.items:
696
self._checkAttributeNames(item)
697
if __builtins__.has_key('object'):
698
self._checkAttributeNames(object)
700
def test_getAttributeNames_NoSingle(self):
701
for item in self.items:
702
result = introspect.getAttributeNames(item, includeSingle=0)
703
attributes = [attribute for attribute in result \
704
if attribute[0] != '_' or attribute[:2] == '__']
705
self.assertEqual(result, attributes,
706
':item: %r' % (item,))
708
def test_getAttributeNames_NoDouble(self):
709
for item in self.items:
710
result = introspect.getAttributeNames(item, includeDouble=0)
711
attributes = [attribute for attribute in result \
712
if attribute[:2] != '__']
713
self.assertEqual(result, attributes,
714
':item: %r' % (item,))
716
def test_getAttributeNames_NoSingleOrDouble(self):
717
for item in self.items:
718
result = introspect.getAttributeNames(item, includeSingle=0,
720
attributes = [attribute for attribute in result \
721
if attribute[0] != '_']
722
self.assertEqual(result, attributes,
723
':item: %r' % (item,))
725
def _checkAttributeNames(self, item):
726
result = introspect.getAttributeNames(item)
727
attributes = [attribute for attribute in self.values \
728
if hasattr(item, attribute)]
729
for attribute in attributes:
730
self.assert_(attribute in result,
731
':item: %r :attribute: %r' % (item, attribute))
734
class GetAutoCompleteListTestCase(GetAttributeTestCase):
737
GetAttributeTestCase.setUp(self)
751
def test_getAutoCompleteList(self):
752
for item in self.items:
753
result = introspect.getAutoCompleteList(item)
754
object = eval(item[:-1])
755
attributes = [attribute for attribute in self.values \
756
if hasattr(object, attribute)]
757
for attribute in attributes:
758
self.assert_(attribute in result,
759
':item: %r :attribute: %r' % (item, attribute))
761
def test_getAutoCompleteList_NoSingle(self):
762
for item in self.items:
763
result = introspect.getAutoCompleteList(item, includeSingle=0)
764
attributes = [attribute for attribute in result \
765
if attribute[0] != '_' or attribute[:2] == '__']
766
self.assertEqual(result, attributes,
767
':item: %r' % (item,))
769
def test_getAutoCompleteList_NoDouble(self):
770
for item in self.items:
771
result = introspect.getAutoCompleteList(item, includeDouble=0)
772
attributes = [attribute for attribute in result \
773
if attribute[:2] != '__']
774
self.assertEqual(result, attributes,
775
':item: %r' % (item,))
777
def test_getAutoCompleteList_NoSingleOrDouble(self):
778
for item in self.items:
779
result = introspect.getAutoCompleteList(item, includeSingle=0,
781
attributes = [attribute for attribute in result \
782
if attribute[0] != '_']
783
self.assertEqual(result, attributes,
784
':item: %r' % (item,))
787
# Support for GetConstructorTestCase.
790
def __init__(self, a):
794
def __init__(self, b):
803
if __builtins__.has_key('object'):
805
def __init__(self, a):
809
def __init__(self, b):
822
def __init__(self, a, b=2, *args, **kwargs):
829
def __init__(self, c, d=4):
832
class GetConstructorTestCase(unittest.TestCase):
834
def test_getConstructor(self):
835
args = ('self', 'a', 'b', 'args', 'kwargs')
836
varnames = introspect.getConstructor(O).func_code.co_varnames
837
self.assertEqual(varnames, args)
838
varnames = introspect.getConstructor(P).func_code.co_varnames
839
self.assertEqual(varnames, args)
840
args = ('self', 'c', 'd')
841
varnames = introspect.getConstructor(Q).func_code.co_varnames
842
self.assertEqual(varnames, args)
844
def test_getConstructor_None(self):
845
values = (N, 1, 'spam', {}, [], (), dir)
847
self.assertEqual(introspect.getConstructor(N), None)
849
def test_getConstructor_MultipleInheritance(self):
850
# Test old style inheritance rules.
852
varnames = introspect.getConstructor(D1).func_code.co_varnames
853
self.assertEqual(varnames, args)
854
if __builtins__.has_key('object'):
855
# Test new style inheritance rules as well.
857
varnames = introspect.getConstructor(D2).func_code.co_varnames
858
self.assertEqual(varnames, args)
861
if __name__ == '__main__':