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