• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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