##// END OF EJS Templates
Add tests for completing exported submodules
Daniel Shimon -
Show More
@@ -1,178 +1,194 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for completerlib.
2 """Tests for completerlib.
3
3
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Imports
7 # Imports
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9
9
10 import os
10 import os
11 import shutil
11 import shutil
12 import sys
12 import sys
13 import tempfile
13 import tempfile
14 import unittest
14 import unittest
15 from os.path import join
15 from os.path import join
16
16
17 import nose.tools as nt
17 import nose.tools as nt
18
18
19 from IPython.core.completerlib import magic_run_completer, module_completion, try_import
19 from IPython.core.completerlib import magic_run_completer, module_completion, try_import
20 from IPython.utils.tempdir import TemporaryDirectory
20 from IPython.utils.tempdir import TemporaryDirectory
21 from IPython.testing.decorators import onlyif_unicode_paths
21 from IPython.testing.decorators import onlyif_unicode_paths
22
22
23
23
24 class MockEvent(object):
24 class MockEvent(object):
25 def __init__(self, line):
25 def __init__(self, line):
26 self.line = line
26 self.line = line
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Test functions begin
29 # Test functions begin
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31 class Test_magic_run_completer(unittest.TestCase):
31 class Test_magic_run_completer(unittest.TestCase):
32 files = [u"aao.py", u"a.py", u"b.py", u"aao.txt"]
32 files = [u"aao.py", u"a.py", u"b.py", u"aao.txt"]
33 dirs = [u"adir/", "bdir/"]
33 dirs = [u"adir/", "bdir/"]
34
34
35 def setUp(self):
35 def setUp(self):
36 self.BASETESTDIR = tempfile.mkdtemp()
36 self.BASETESTDIR = tempfile.mkdtemp()
37 for fil in self.files:
37 for fil in self.files:
38 with open(join(self.BASETESTDIR, fil), "w") as sfile:
38 with open(join(self.BASETESTDIR, fil), "w") as sfile:
39 sfile.write("pass\n")
39 sfile.write("pass\n")
40 for d in self.dirs:
40 for d in self.dirs:
41 os.mkdir(join(self.BASETESTDIR, d))
41 os.mkdir(join(self.BASETESTDIR, d))
42
42
43 self.oldpath = os.getcwd()
43 self.oldpath = os.getcwd()
44 os.chdir(self.BASETESTDIR)
44 os.chdir(self.BASETESTDIR)
45
45
46 def tearDown(self):
46 def tearDown(self):
47 os.chdir(self.oldpath)
47 os.chdir(self.oldpath)
48 shutil.rmtree(self.BASETESTDIR)
48 shutil.rmtree(self.BASETESTDIR)
49
49
50 def test_1(self):
50 def test_1(self):
51 """Test magic_run_completer, should match two alternatives
51 """Test magic_run_completer, should match two alternatives
52 """
52 """
53 event = MockEvent(u"%run a")
53 event = MockEvent(u"%run a")
54 mockself = None
54 mockself = None
55 match = set(magic_run_completer(mockself, event))
55 match = set(magic_run_completer(mockself, event))
56 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
56 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
57
57
58 def test_2(self):
58 def test_2(self):
59 """Test magic_run_completer, should match one alternative
59 """Test magic_run_completer, should match one alternative
60 """
60 """
61 event = MockEvent(u"%run aa")
61 event = MockEvent(u"%run aa")
62 mockself = None
62 mockself = None
63 match = set(magic_run_completer(mockself, event))
63 match = set(magic_run_completer(mockself, event))
64 self.assertEqual(match, {u"aao.py"})
64 self.assertEqual(match, {u"aao.py"})
65
65
66 def test_3(self):
66 def test_3(self):
67 """Test magic_run_completer with unterminated " """
67 """Test magic_run_completer with unterminated " """
68 event = MockEvent(u'%run "a')
68 event = MockEvent(u'%run "a')
69 mockself = None
69 mockself = None
70 match = set(magic_run_completer(mockself, event))
70 match = set(magic_run_completer(mockself, event))
71 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
71 self.assertEqual(match, {u"a.py", u"aao.py", u"adir/"})
72
72
73 def test_completion_more_args(self):
73 def test_completion_more_args(self):
74 event = MockEvent(u'%run a.py ')
74 event = MockEvent(u'%run a.py ')
75 match = set(magic_run_completer(None, event))
75 match = set(magic_run_completer(None, event))
76 self.assertEqual(match, set(self.files + self.dirs))
76 self.assertEqual(match, set(self.files + self.dirs))
77
77
78 def test_completion_in_dir(self):
78 def test_completion_in_dir(self):
79 # Github issue #3459
79 # Github issue #3459
80 event = MockEvent(u'%run a.py {}'.format(join(self.BASETESTDIR, 'a')))
80 event = MockEvent(u'%run a.py {}'.format(join(self.BASETESTDIR, 'a')))
81 print(repr(event.line))
81 print(repr(event.line))
82 match = set(magic_run_completer(None, event))
82 match = set(magic_run_completer(None, event))
83 # We specifically use replace here rather than normpath, because
83 # We specifically use replace here rather than normpath, because
84 # at one point there were duplicates 'adir' and 'adir/', and normpath
84 # at one point there were duplicates 'adir' and 'adir/', and normpath
85 # would hide the failure for that.
85 # would hide the failure for that.
86 self.assertEqual(match, {join(self.BASETESTDIR, f).replace('\\','/')
86 self.assertEqual(match, {join(self.BASETESTDIR, f).replace('\\','/')
87 for f in (u'a.py', u'aao.py', u'aao.txt', u'adir/')})
87 for f in (u'a.py', u'aao.py', u'aao.txt', u'adir/')})
88
88
89 class Test_magic_run_completer_nonascii(unittest.TestCase):
89 class Test_magic_run_completer_nonascii(unittest.TestCase):
90 @onlyif_unicode_paths
90 @onlyif_unicode_paths
91 def setUp(self):
91 def setUp(self):
92 self.BASETESTDIR = tempfile.mkdtemp()
92 self.BASETESTDIR = tempfile.mkdtemp()
93 for fil in [u"aaΓΈ.py", u"a.py", u"b.py"]:
93 for fil in [u"aaΓΈ.py", u"a.py", u"b.py"]:
94 with open(join(self.BASETESTDIR, fil), "w") as sfile:
94 with open(join(self.BASETESTDIR, fil), "w") as sfile:
95 sfile.write("pass\n")
95 sfile.write("pass\n")
96 self.oldpath = os.getcwd()
96 self.oldpath = os.getcwd()
97 os.chdir(self.BASETESTDIR)
97 os.chdir(self.BASETESTDIR)
98
98
99 def tearDown(self):
99 def tearDown(self):
100 os.chdir(self.oldpath)
100 os.chdir(self.oldpath)
101 shutil.rmtree(self.BASETESTDIR)
101 shutil.rmtree(self.BASETESTDIR)
102
102
103 @onlyif_unicode_paths
103 @onlyif_unicode_paths
104 def test_1(self):
104 def test_1(self):
105 """Test magic_run_completer, should match two alternatives
105 """Test magic_run_completer, should match two alternatives
106 """
106 """
107 event = MockEvent(u"%run a")
107 event = MockEvent(u"%run a")
108 mockself = None
108 mockself = None
109 match = set(magic_run_completer(mockself, event))
109 match = set(magic_run_completer(mockself, event))
110 self.assertEqual(match, {u"a.py", u"aaΓΈ.py"})
110 self.assertEqual(match, {u"a.py", u"aaΓΈ.py"})
111
111
112 @onlyif_unicode_paths
112 @onlyif_unicode_paths
113 def test_2(self):
113 def test_2(self):
114 """Test magic_run_completer, should match one alternative
114 """Test magic_run_completer, should match one alternative
115 """
115 """
116 event = MockEvent(u"%run aa")
116 event = MockEvent(u"%run aa")
117 mockself = None
117 mockself = None
118 match = set(magic_run_completer(mockself, event))
118 match = set(magic_run_completer(mockself, event))
119 self.assertEqual(match, {u"aaΓΈ.py"})
119 self.assertEqual(match, {u"aaΓΈ.py"})
120
120
121 @onlyif_unicode_paths
121 @onlyif_unicode_paths
122 def test_3(self):
122 def test_3(self):
123 """Test magic_run_completer with unterminated " """
123 """Test magic_run_completer with unterminated " """
124 event = MockEvent(u'%run "a')
124 event = MockEvent(u'%run "a')
125 mockself = None
125 mockself = None
126 match = set(magic_run_completer(mockself, event))
126 match = set(magic_run_completer(mockself, event))
127 self.assertEqual(match, {u"a.py", u"aaΓΈ.py"})
127 self.assertEqual(match, {u"a.py", u"aaΓΈ.py"})
128
128
129 # module_completer:
129 # module_completer:
130
130
131 def test_import_invalid_module():
131 def test_import_invalid_module():
132 """Testing of issue https://github.com/ipython/ipython/issues/1107"""
132 """Testing of issue https://github.com/ipython/ipython/issues/1107"""
133 invalid_module_names = {'foo-bar', 'foo:bar', '10foo'}
133 invalid_module_names = {'foo-bar', 'foo:bar', '10foo'}
134 valid_module_names = {'foobar'}
134 valid_module_names = {'foobar'}
135 with TemporaryDirectory() as tmpdir:
135 with TemporaryDirectory() as tmpdir:
136 sys.path.insert( 0, tmpdir )
136 sys.path.insert( 0, tmpdir )
137 for name in invalid_module_names | valid_module_names:
137 for name in invalid_module_names | valid_module_names:
138 filename = os.path.join(tmpdir, name + '.py')
138 filename = os.path.join(tmpdir, name + '.py')
139 open(filename, 'w').close()
139 open(filename, 'w').close()
140
140
141 s = set( module_completion('import foo') )
141 s = set( module_completion('import foo') )
142 intersection = s.intersection(invalid_module_names)
142 intersection = s.intersection(invalid_module_names)
143 nt.assert_equal(intersection, set())
143 nt.assert_equal(intersection, set())
144
144
145 assert valid_module_names.issubset(s), valid_module_names.intersection(s)
145 assert valid_module_names.issubset(s), valid_module_names.intersection(s)
146
146
147
147
148 def test_bad_module_all():
148 def test_bad_module_all():
149 """Test module with invalid __all__
149 """Test module with invalid __all__
150
150
151 https://github.com/ipython/ipython/issues/9678
151 https://github.com/ipython/ipython/issues/9678
152 """
152 """
153 testsdir = os.path.dirname(__file__)
153 testsdir = os.path.dirname(__file__)
154 sys.path.insert(0, testsdir)
154 sys.path.insert(0, testsdir)
155 try:
155 try:
156 results = module_completion('from bad_all import ')
156 results = module_completion('from bad_all import ')
157 nt.assert_in('puppies', results)
157 nt.assert_in('puppies', results)
158 for r in results:
158 for r in results:
159 nt.assert_is_instance(r, str)
159 nt.assert_is_instance(r, str)
160
161 # bad_all doesn't contain submodules, but this completion
162 # should finish without raising an exception:
163 results = module_completion("import bad_all.")
164 nt.assert_equal(results, [])
160 finally:
165 finally:
161 sys.path.remove(testsdir)
166 sys.path.remove(testsdir)
162
167
163
168
164 def test_module_without_init():
169 def test_module_without_init():
165 """
170 """
166 Test module without __init__.py.
171 Test module without __init__.py.
167
172
168 https://github.com/ipython/ipython/issues/11226
173 https://github.com/ipython/ipython/issues/11226
169 """
174 """
170 fake_module_name = "foo"
175 fake_module_name = "foo"
171 with TemporaryDirectory() as tmpdir:
176 with TemporaryDirectory() as tmpdir:
172 sys.path.insert(0, tmpdir)
177 sys.path.insert(0, tmpdir)
173 try:
178 try:
174 os.makedirs(os.path.join(tmpdir, fake_module_name))
179 os.makedirs(os.path.join(tmpdir, fake_module_name))
175 s = try_import(mod=fake_module_name)
180 s = try_import(mod=fake_module_name)
176 assert s == []
181 assert s == []
177 finally:
182 finally:
178 sys.path.remove(tmpdir)
183 sys.path.remove(tmpdir)
184
185
186 def test_valid_exported_submodules():
187 """
188 Test checking exported (__all__) objects are submodules
189 """
190 results = module_completion("import os.pa")
191 # ensure we get a valid submodule:
192 nt.assert_in("os.path", results)
193 # ensure we don't get objects that aren't submodules:
194 nt.assert_not_in("os.pathconf", results)
General Comments 0
You need to be logged in to leave comments. Login now