blob: 0dc1080ca32093cf0e82455ec81cebbed72a9566 [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
Yury Selivanov46f77852016-02-04 14:00:26 -0500104 @unittest.mock.patch('rlcompleter._readline_available', False)
Berker Peksagaaf61142015-07-28 00:06:31 +0300105 def test_complete(self):
106 completer = rlcompleter.Completer()
107 self.assertEqual(completer.complete('', 0), '\t')
Serhiy Storchaka8ace8e92015-09-27 13:26:03 +0300108 self.assertEqual(completer.complete('a', 0), 'and ')
109 self.assertEqual(completer.complete('a', 1), 'as ')
110 self.assertEqual(completer.complete('as', 2), 'assert ')
111 self.assertEqual(completer.complete('an', 0), 'and ')
112 self.assertEqual(completer.complete('pa', 0), 'pass')
113 self.assertEqual(completer.complete('Fa', 0), 'False')
114 self.assertEqual(completer.complete('el', 0), 'elif ')
115 self.assertEqual(completer.complete('el', 1), 'else')
116 self.assertEqual(completer.complete('tr', 0), 'try:')
Antoine Pitrou482e66a2010-08-04 15:43:16 +0000117
Martin Pantered929102015-11-23 23:50:26 +0000118 def test_duplicate_globals(self):
119 namespace = {
120 'False': None, # Keyword vs builtin vs namespace
121 'assert': None, # Keyword vs namespace
122 'try': lambda: None, # Keyword vs callable
123 'memoryview': None, # Callable builtin vs non-callable
124 'Ellipsis': lambda: None, # Non-callable builtin vs callable
125 }
126 completer = rlcompleter.Completer(namespace)
127 self.assertEqual(completer.complete('False', 0), 'False')
128 self.assertIsNone(completer.complete('False', 1)) # No duplicates
Martin Panter745f6b32015-11-24 00:20:00 +0000129 # Space or colon added due to being a reserved keyword
130 self.assertEqual(completer.complete('assert', 0), 'assert ')
Martin Pantered929102015-11-23 23:50:26 +0000131 self.assertIsNone(completer.complete('assert', 1))
Martin Panter745f6b32015-11-24 00:20:00 +0000132 self.assertEqual(completer.complete('try', 0), 'try:')
Martin Pantered929102015-11-23 23:50:26 +0000133 self.assertIsNone(completer.complete('try', 1))
134 # No opening bracket "(" because we overrode the built-in class
135 self.assertEqual(completer.complete('memoryview', 0), 'memoryview')
136 self.assertIsNone(completer.complete('memoryview', 1))
137 self.assertEqual(completer.complete('Ellipsis', 0), 'Ellipsis(')
138 self.assertIsNone(completer.complete('Ellipsis', 1))
139
Antoine Pitrou482e66a2010-08-04 15:43:16 +0000140if __name__ == '__main__':
Zachary Ware38c707e2015-04-13 15:00:43 -0500141 unittest.main()