1import unittest 2from unittest.mock import patch 3import builtins 4import rlcompleter 5 6class CompleteMe: 7 """ Trivial class used in testing rlcompleter.Completer. """ 8 spam = 1 9 _ham = 2 10 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 35 self.assertEqual(sorted(self.stdcompleter.global_matches('di')), 36 [x+'(' for x in dir(builtins) if x.startswith('di')]) 37 self.assertEqual(sorted(self.stdcompleter.global_matches('st')), 38 [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'), []) 56 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) 61 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'), []) 66 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) 75 76 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')]) 82 83 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 96 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 104 @unittest.mock.patch('rlcompleter._readline_available', False) 105 def test_complete(self): 106 completer = rlcompleter.Completer() 107 self.assertEqual(completer.complete('', 0), '\t') 108 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:') 117 118 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 129 # Space or colon added due to being a reserved keyword 130 self.assertEqual(completer.complete('assert', 0), 'assert ') 131 self.assertIsNone(completer.complete('assert', 1)) 132 self.assertEqual(completer.complete('try', 0), 'try:') 133 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 140if __name__ == '__main__': 141 unittest.main() 142