blob: 208c0545c4405c580bb1adf1fa998fb6f457004a [file] [log] [blame]
Antoine Pitrou482e66a2010-08-04 15:43:16 +00001import unittest
Martin Panter40062a12015-11-28 22:38:24 +00002from unittest.mock import patch
Antoine Pitrou482e66a2010-08-04 15:43:16 +00003import builtins
4import rlcompleter
5
6class CompleteMe:
7 """ Trivial class used in testing rlcompleter.Completer. """
8 spam = 1
Serhiy Storchakaab824222015-09-27 13:43:50 +03009 _ham = 2
Antoine Pitrou482e66a2010-08-04 15:43:16 +000010
11
12class TestRlcompleter(unittest.TestCase):
13 def setUp(self):
14 self.stdcompleter = rlcompleter.Completer()
15 self.completer = rlcompleter.Completer(dict(spam=int,
16 egg=str,
17 CompleteMe=CompleteMe))
18
19 # forces stdcompleter to bind builtins namespace
20 self.stdcompleter.complete('', 0)
21
22 def test_namespace(self):
23 class A(dict):
24 pass
25 class B(list):
26 pass
27
28 self.assertTrue(self.stdcompleter.use_main_ns)
29 self.assertFalse(self.completer.use_main_ns)
30 self.assertFalse(rlcompleter.Completer(A()).use_main_ns)
31 self.assertRaises(TypeError, rlcompleter.Completer, B((1,)))
32
33 def test_global_matches(self):
34 # test with builtins namespace
Georg Brandl50de5f52010-10-21 07:40:03 +000035 self.assertEqual(sorted(self.stdcompleter.global_matches('di')),
Antoine Pitrou482e66a2010-08-04 15:43:16 +000036 [x+'(' for x in dir(builtins) if x.startswith('di')])
Georg Brandl50de5f52010-10-21 07:40:03 +000037 self.assertEqual(sorted(self.stdcompleter.global_matches('st')),
Antoine Pitrou482e66a2010-08-04 15:43:16 +000038 [x+'(' for x in dir(builtins) if x.startswith('st')])
39 self.assertEqual(self.stdcompleter.global_matches('akaksajadhak'), [])
40
41 # test with a customized namespace
42 self.assertEqual(self.completer.global_matches('CompleteM'),
43 ['CompleteMe('])
44 self.assertEqual(self.completer.global_matches('eg'),
45 ['egg('])
46 # XXX: see issue5256
47 self.assertEqual(self.completer.global_matches('CompleteM'),
48 ['CompleteMe('])
49
50 def test_attr_matches(self):
51 # test with builtins namespace
52 self.assertEqual(self.stdcompleter.attr_matches('str.s'),
53 ['str.{}('.format(x) for x in dir(str)
54 if x.startswith('s')])
55 self.assertEqual(self.stdcompleter.attr_matches('tuple.foospamegg'), [])
Serhiy Storchakaab824222015-09-27 13:43:50 +030056 expected = sorted({'None.%s%s' % (x, '(' if x != '__doc__' else '')
57 for x in dir(None)})
58 self.assertEqual(self.stdcompleter.attr_matches('None.'), expected)
59 self.assertEqual(self.stdcompleter.attr_matches('None._'), expected)
60 self.assertEqual(self.stdcompleter.attr_matches('None.__'), expected)
Antoine Pitrou482e66a2010-08-04 15:43:16 +000061
62 # test with a customized namespace
63 self.assertEqual(self.completer.attr_matches('CompleteMe.sp'),
64 ['CompleteMe.spam'])
65 self.assertEqual(self.completer.attr_matches('Completeme.egg'), [])
Serhiy Storchakaab824222015-09-27 13:43:50 +030066 self.assertEqual(self.completer.attr_matches('CompleteMe.'),
67 ['CompleteMe.mro(', 'CompleteMe.spam'])
68 self.assertEqual(self.completer.attr_matches('CompleteMe._'),
69 ['CompleteMe._ham'])
70 matches = self.completer.attr_matches('CompleteMe.__')
71 for x in matches:
72 self.assertTrue(x.startswith('CompleteMe.__'), x)
73 self.assertIn('CompleteMe.__name__', matches)
74 self.assertIn('CompleteMe.__new__(', matches)
Antoine Pitrou482e66a2010-08-04 15:43:16 +000075
Martin Panter40062a12015-11-28 22:38:24 +000076 with patch.object(CompleteMe, "me", CompleteMe, create=True):
77 self.assertEqual(self.completer.attr_matches('CompleteMe.me.me.sp'),
78 ['CompleteMe.me.me.spam'])
79 self.assertEqual(self.completer.attr_matches('egg.s'),
80 ['egg.{}('.format(x) for x in dir(str)
81 if x.startswith('s')])
Antoine Pitrou482e66a2010-08-04 15:43:16 +000082
Martin Panter06622ea2015-11-13 22:47:00 +000083 def test_excessive_getattr(self):
84 # Ensure getattr() is invoked no more than once per attribute
85 class Foo:
86 calls = 0
87 @property
88 def bar(self):
89 self.calls += 1
90 return None
91 f = Foo()
92 completer = rlcompleter.Completer(dict(f=f))
93 self.assertEqual(completer.complete('f.b', 0), 'f.bar')
94 self.assertEqual(f.calls, 1)
95
Martin Panter6fe39262015-11-13 23:54:02 +000096 def test_uncreated_attr(self):
97 # Attributes like properties and slots should be completed even when
98 # they haven't been created on an instance
99 class Foo:
100 __slots__ = ("bar",)
101 completer = rlcompleter.Completer(dict(f=Foo()))
102 self.assertEqual(completer.complete('f.', 0), 'f.bar')
103
Berker Peksagaaf61142015-07-28 00:06:31 +0300104 def test_complete(self):
105 completer = rlcompleter.Completer()
106 self.assertEqual(completer.complete('', 0), '\t')
Serhiy Storchaka8ace8e92015-09-27 13:26:03 +0300107 self.assertEqual(completer.complete('a', 0), 'and ')
108 self.assertEqual(completer.complete('a', 1), 'as ')
109 self.assertEqual(completer.complete('as', 2), 'assert ')
110 self.assertEqual(completer.complete('an', 0), 'and ')
111 self.assertEqual(completer.complete('pa', 0), 'pass')
112 self.assertEqual(completer.complete('Fa', 0), 'False')
113 self.assertEqual(completer.complete('el', 0), 'elif ')
114 self.assertEqual(completer.complete('el', 1), 'else')
115 self.assertEqual(completer.complete('tr', 0), 'try:')
Antoine Pitrou482e66a2010-08-04 15:43:16 +0000116
Martin Pantered929102015-11-23 23:50:26 +0000117 def test_duplicate_globals(self):
118 namespace = {
119 'False': None, # Keyword vs builtin vs namespace
120 'assert': None, # Keyword vs namespace
121 'try': lambda: None, # Keyword vs callable
122 'memoryview': None, # Callable builtin vs non-callable
123 'Ellipsis': lambda: None, # Non-callable builtin vs callable
124 }
125 completer = rlcompleter.Completer(namespace)
126 self.assertEqual(completer.complete('False', 0), 'False')
127 self.assertIsNone(completer.complete('False', 1)) # No duplicates
Martin Panter745f6b32015-11-24 00:20:00 +0000128 # Space or colon added due to being a reserved keyword
129 self.assertEqual(completer.complete('assert', 0), 'assert ')
Martin Pantered929102015-11-23 23:50:26 +0000130 self.assertIsNone(completer.complete('assert', 1))
Martin Panter745f6b32015-11-24 00:20:00 +0000131 self.assertEqual(completer.complete('try', 0), 'try:')
Martin Pantered929102015-11-23 23:50:26 +0000132 self.assertIsNone(completer.complete('try', 1))
133 # No opening bracket "(" because we overrode the built-in class
134 self.assertEqual(completer.complete('memoryview', 0), 'memoryview')
135 self.assertIsNone(completer.complete('memoryview', 1))
136 self.assertEqual(completer.complete('Ellipsis', 0), 'Ellipsis(')
137 self.assertIsNone(completer.complete('Ellipsis', 1))
138
Antoine Pitrou482e66a2010-08-04 15:43:16 +0000139if __name__ == '__main__':
Zachary Ware38c707e2015-04-13 15:00:43 -0500140 unittest.main()