17db96d56Sopenharmony_ciimport unittest 27db96d56Sopenharmony_cifrom unittest.mock import patch 37db96d56Sopenharmony_ciimport builtins 47db96d56Sopenharmony_ciimport rlcompleter 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ciclass CompleteMe: 77db96d56Sopenharmony_ci """ Trivial class used in testing rlcompleter.Completer. """ 87db96d56Sopenharmony_ci spam = 1 97db96d56Sopenharmony_ci _ham = 2 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ciclass TestRlcompleter(unittest.TestCase): 137db96d56Sopenharmony_ci def setUp(self): 147db96d56Sopenharmony_ci self.stdcompleter = rlcompleter.Completer() 157db96d56Sopenharmony_ci self.completer = rlcompleter.Completer(dict(spam=int, 167db96d56Sopenharmony_ci egg=str, 177db96d56Sopenharmony_ci CompleteMe=CompleteMe)) 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ci # forces stdcompleter to bind builtins namespace 207db96d56Sopenharmony_ci self.stdcompleter.complete('', 0) 217db96d56Sopenharmony_ci 227db96d56Sopenharmony_ci def test_namespace(self): 237db96d56Sopenharmony_ci class A(dict): 247db96d56Sopenharmony_ci pass 257db96d56Sopenharmony_ci class B(list): 267db96d56Sopenharmony_ci pass 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ci self.assertTrue(self.stdcompleter.use_main_ns) 297db96d56Sopenharmony_ci self.assertFalse(self.completer.use_main_ns) 307db96d56Sopenharmony_ci self.assertFalse(rlcompleter.Completer(A()).use_main_ns) 317db96d56Sopenharmony_ci self.assertRaises(TypeError, rlcompleter.Completer, B((1,))) 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci def test_global_matches(self): 347db96d56Sopenharmony_ci # test with builtins namespace 357db96d56Sopenharmony_ci self.assertEqual(sorted(self.stdcompleter.global_matches('di')), 367db96d56Sopenharmony_ci [x+'(' for x in dir(builtins) if x.startswith('di')]) 377db96d56Sopenharmony_ci self.assertEqual(sorted(self.stdcompleter.global_matches('st')), 387db96d56Sopenharmony_ci [x+'(' for x in dir(builtins) if x.startswith('st')]) 397db96d56Sopenharmony_ci self.assertEqual(self.stdcompleter.global_matches('akaksajadhak'), []) 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_ci # test with a customized namespace 427db96d56Sopenharmony_ci self.assertEqual(self.completer.global_matches('CompleteM'), 437db96d56Sopenharmony_ci ['CompleteMe()']) 447db96d56Sopenharmony_ci self.assertEqual(self.completer.global_matches('eg'), 457db96d56Sopenharmony_ci ['egg(']) 467db96d56Sopenharmony_ci # XXX: see issue5256 477db96d56Sopenharmony_ci self.assertEqual(self.completer.global_matches('CompleteM'), 487db96d56Sopenharmony_ci ['CompleteMe()']) 497db96d56Sopenharmony_ci 507db96d56Sopenharmony_ci def test_attr_matches(self): 517db96d56Sopenharmony_ci # test with builtins namespace 527db96d56Sopenharmony_ci self.assertEqual(self.stdcompleter.attr_matches('str.s'), 537db96d56Sopenharmony_ci ['str.{}('.format(x) for x in dir(str) 547db96d56Sopenharmony_ci if x.startswith('s')]) 557db96d56Sopenharmony_ci self.assertEqual(self.stdcompleter.attr_matches('tuple.foospamegg'), []) 567db96d56Sopenharmony_ci expected = sorted({'None.%s%s' % (x, '(' if x != '__doc__' else '') 577db96d56Sopenharmony_ci for x in dir(None)}) 587db96d56Sopenharmony_ci self.assertEqual(self.stdcompleter.attr_matches('None.'), expected) 597db96d56Sopenharmony_ci self.assertEqual(self.stdcompleter.attr_matches('None._'), expected) 607db96d56Sopenharmony_ci self.assertEqual(self.stdcompleter.attr_matches('None.__'), expected) 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci # test with a customized namespace 637db96d56Sopenharmony_ci self.assertEqual(self.completer.attr_matches('CompleteMe.sp'), 647db96d56Sopenharmony_ci ['CompleteMe.spam']) 657db96d56Sopenharmony_ci self.assertEqual(self.completer.attr_matches('Completeme.egg'), []) 667db96d56Sopenharmony_ci self.assertEqual(self.completer.attr_matches('CompleteMe.'), 677db96d56Sopenharmony_ci ['CompleteMe.mro()', 'CompleteMe.spam']) 687db96d56Sopenharmony_ci self.assertEqual(self.completer.attr_matches('CompleteMe._'), 697db96d56Sopenharmony_ci ['CompleteMe._ham']) 707db96d56Sopenharmony_ci matches = self.completer.attr_matches('CompleteMe.__') 717db96d56Sopenharmony_ci for x in matches: 727db96d56Sopenharmony_ci self.assertTrue(x.startswith('CompleteMe.__'), x) 737db96d56Sopenharmony_ci self.assertIn('CompleteMe.__name__', matches) 747db96d56Sopenharmony_ci self.assertIn('CompleteMe.__new__(', matches) 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_ci with patch.object(CompleteMe, "me", CompleteMe, create=True): 777db96d56Sopenharmony_ci self.assertEqual(self.completer.attr_matches('CompleteMe.me.me.sp'), 787db96d56Sopenharmony_ci ['CompleteMe.me.me.spam']) 797db96d56Sopenharmony_ci self.assertEqual(self.completer.attr_matches('egg.s'), 807db96d56Sopenharmony_ci ['egg.{}('.format(x) for x in dir(str) 817db96d56Sopenharmony_ci if x.startswith('s')]) 827db96d56Sopenharmony_ci 837db96d56Sopenharmony_ci def test_excessive_getattr(self): 847db96d56Sopenharmony_ci """Ensure getattr() is invoked no more than once per attribute""" 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci # note the special case for @property methods below; that is why 877db96d56Sopenharmony_ci # we use __dir__ and __getattr__ in class Foo to create a "magic" 887db96d56Sopenharmony_ci # class attribute 'bar'. This forces `getattr` to call __getattr__ 897db96d56Sopenharmony_ci # (which is doesn't necessarily do). 907db96d56Sopenharmony_ci class Foo: 917db96d56Sopenharmony_ci calls = 0 927db96d56Sopenharmony_ci bar = '' 937db96d56Sopenharmony_ci def __getattribute__(self, name): 947db96d56Sopenharmony_ci if name == 'bar': 957db96d56Sopenharmony_ci self.calls += 1 967db96d56Sopenharmony_ci return None 977db96d56Sopenharmony_ci return super().__getattribute__(name) 987db96d56Sopenharmony_ci 997db96d56Sopenharmony_ci f = Foo() 1007db96d56Sopenharmony_ci completer = rlcompleter.Completer(dict(f=f)) 1017db96d56Sopenharmony_ci self.assertEqual(completer.complete('f.b', 0), 'f.bar') 1027db96d56Sopenharmony_ci self.assertEqual(f.calls, 1) 1037db96d56Sopenharmony_ci 1047db96d56Sopenharmony_ci def test_property_method_not_called(self): 1057db96d56Sopenharmony_ci class Foo: 1067db96d56Sopenharmony_ci _bar = 0 1077db96d56Sopenharmony_ci property_called = False 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_ci @property 1107db96d56Sopenharmony_ci def bar(self): 1117db96d56Sopenharmony_ci self.property_called = True 1127db96d56Sopenharmony_ci return self._bar 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_ci f = Foo() 1157db96d56Sopenharmony_ci completer = rlcompleter.Completer(dict(f=f)) 1167db96d56Sopenharmony_ci self.assertEqual(completer.complete('f.b', 0), 'f.bar') 1177db96d56Sopenharmony_ci self.assertFalse(f.property_called) 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_ci def test_uncreated_attr(self): 1217db96d56Sopenharmony_ci # Attributes like properties and slots should be completed even when 1227db96d56Sopenharmony_ci # they haven't been created on an instance 1237db96d56Sopenharmony_ci class Foo: 1247db96d56Sopenharmony_ci __slots__ = ("bar",) 1257db96d56Sopenharmony_ci completer = rlcompleter.Completer(dict(f=Foo())) 1267db96d56Sopenharmony_ci self.assertEqual(completer.complete('f.', 0), 'f.bar') 1277db96d56Sopenharmony_ci 1287db96d56Sopenharmony_ci @unittest.mock.patch('rlcompleter._readline_available', False) 1297db96d56Sopenharmony_ci def test_complete(self): 1307db96d56Sopenharmony_ci completer = rlcompleter.Completer() 1317db96d56Sopenharmony_ci self.assertEqual(completer.complete('', 0), '\t') 1327db96d56Sopenharmony_ci self.assertEqual(completer.complete('a', 0), 'and ') 1337db96d56Sopenharmony_ci self.assertEqual(completer.complete('a', 1), 'as ') 1347db96d56Sopenharmony_ci self.assertEqual(completer.complete('as', 2), 'assert ') 1357db96d56Sopenharmony_ci self.assertEqual(completer.complete('an', 0), 'and ') 1367db96d56Sopenharmony_ci self.assertEqual(completer.complete('pa', 0), 'pass') 1377db96d56Sopenharmony_ci self.assertEqual(completer.complete('Fa', 0), 'False') 1387db96d56Sopenharmony_ci self.assertEqual(completer.complete('el', 0), 'elif ') 1397db96d56Sopenharmony_ci self.assertEqual(completer.complete('el', 1), 'else') 1407db96d56Sopenharmony_ci self.assertEqual(completer.complete('tr', 0), 'try:') 1417db96d56Sopenharmony_ci self.assertEqual(completer.complete('_', 0), '_') 1427db96d56Sopenharmony_ci self.assertEqual(completer.complete('match', 0), 'match ') 1437db96d56Sopenharmony_ci self.assertEqual(completer.complete('case', 0), 'case ') 1447db96d56Sopenharmony_ci 1457db96d56Sopenharmony_ci def test_duplicate_globals(self): 1467db96d56Sopenharmony_ci namespace = { 1477db96d56Sopenharmony_ci 'False': None, # Keyword vs builtin vs namespace 1487db96d56Sopenharmony_ci 'assert': None, # Keyword vs namespace 1497db96d56Sopenharmony_ci 'try': lambda: None, # Keyword vs callable 1507db96d56Sopenharmony_ci 'memoryview': None, # Callable builtin vs non-callable 1517db96d56Sopenharmony_ci 'Ellipsis': lambda: None, # Non-callable builtin vs callable 1527db96d56Sopenharmony_ci } 1537db96d56Sopenharmony_ci completer = rlcompleter.Completer(namespace) 1547db96d56Sopenharmony_ci self.assertEqual(completer.complete('False', 0), 'False') 1557db96d56Sopenharmony_ci self.assertIsNone(completer.complete('False', 1)) # No duplicates 1567db96d56Sopenharmony_ci # Space or colon added due to being a reserved keyword 1577db96d56Sopenharmony_ci self.assertEqual(completer.complete('assert', 0), 'assert ') 1587db96d56Sopenharmony_ci self.assertIsNone(completer.complete('assert', 1)) 1597db96d56Sopenharmony_ci self.assertEqual(completer.complete('try', 0), 'try:') 1607db96d56Sopenharmony_ci self.assertIsNone(completer.complete('try', 1)) 1617db96d56Sopenharmony_ci # No opening bracket "(" because we overrode the built-in class 1627db96d56Sopenharmony_ci self.assertEqual(completer.complete('memoryview', 0), 'memoryview') 1637db96d56Sopenharmony_ci self.assertIsNone(completer.complete('memoryview', 1)) 1647db96d56Sopenharmony_ci self.assertEqual(completer.complete('Ellipsis', 0), 'Ellipsis()') 1657db96d56Sopenharmony_ci self.assertIsNone(completer.complete('Ellipsis', 1)) 1667db96d56Sopenharmony_ci 1677db96d56Sopenharmony_ciif __name__ == '__main__': 1687db96d56Sopenharmony_ci unittest.main() 169