3 """Tests for the elpy.server module"""
10 from unittest
import mock
15 from elpy
import server
16 from elpy
.tests
import compat
17 from elpy
.tests
.support
import BackendTestCase
20 class ServerTestCase(unittest
.TestCase
):
22 self
.srv
= server
.ElpyRPCServer()
25 class BackendCallTestCase(ServerTestCase
):
26 def assert_calls_backend(self
, method
, add_args
=[], add_kwargs
={}):
27 with mock
.patch("elpy.server.get_source") as get_source
:
28 with mock
.patch
.object(self
.srv
, "backend") as backend
:
29 get_source
.return_value
= "transformed source"
31 getattr(self
.srv
, method
)("filename", "source", "offset",
35 get_source
.assert_called_with("source")
36 getattr(backend
, method
).assert_called_with(
37 "filename", "transformed source", "offset",
43 class TestInit(ServerTestCase
):
44 def test_should_not_select_a_backend_by_default(self
):
45 self
.assertIsNone(self
.srv
.backend
)
48 class TestRPCEcho(ServerTestCase
):
49 def test_should_return_arguments(self
):
50 self
.assertEqual(("hello", "world"),
51 self
.srv
.rpc_echo("hello", "world"))
54 class TestRPCInit(ServerTestCase
):
55 @mock.patch("elpy.jedibackend.JediBackend")
56 def test_should_set_project_root(self
, JediBackend
):
57 self
.srv
.rpc_init({"project_root": "/project/root",
58 "environment": "/project/env"})
60 self
.assertEqual("/project/root", self
.srv
.project_root
)
62 @mock.patch("jedi.create_environment")
63 def test_should_set_project_env(self
, create_environment
):
64 self
.srv
.rpc_init({"project_root": "/project/root",
65 "environment": "/project/env"})
67 create_environment
.assert_called_with("/project/env", safe
=False)
69 @mock.patch("elpy.jedibackend.JediBackend")
70 def test_should_initialize_jedi(self
, JediBackend
):
71 self
.srv
.rpc_init({"project_root": "/project/root",
72 "environment": "/project/env"})
74 JediBackend
.assert_called_with("/project/root", "/project/env")
77 @mock.patch("elpy.jedibackend.JediBackend")
78 def test_should_use_jedi_if_available(self
, JediBackend
):
79 JediBackend
.return_value
.name
= "jedi"
81 self
.srv
.rpc_init({"project_root": "/project/root",
82 "environment": "/project/env"})
84 self
.assertEqual("jedi", self
.srv
.backend
.name
)
87 @mock.patch("elpy.jedibackend.JediBackend")
88 def test_should_use_none_if_nothing_available(
90 JediBackend
.return_value
.name
= "jedi"
91 old_jedi
= server
.jedibackend
92 server
.jedibackend
= None
95 self
.srv
.rpc_init({"project_root": "/project/root",
96 "environment": "/project/env"})
98 server
.jedibackend
= old_jedi
100 self
.assertIsNone(self
.srv
.backend
)
103 class TestRPCGetCalltip(BackendCallTestCase
):
104 def test_should_call_backend(self
):
105 self
.assert_calls_backend("rpc_get_calltip")
107 def test_should_handle_no_backend(self
):
108 self
.srv
.backend
= None
109 self
.assertIsNone(self
.srv
.rpc_get_calltip("filname", "source",
113 class TestRPCGetCompletions(BackendCallTestCase
):
114 def test_should_call_backend(self
):
115 self
.assert_calls_backend("rpc_get_completions")
117 def test_should_handle_no_backend(self
):
118 self
.srv
.backend
= None
120 self
.srv
.rpc_get_completions("filname", "source",
123 def test_should_sort_results(self
):
124 with mock
.patch
.object(self
.srv
, 'backend') as backend
:
125 backend
.rpc_get_completions
.return_value
= [
132 expected
= list(reversed(backend
.rpc_get_completions
.return_value
))
134 actual
= self
.srv
.rpc_get_completions("filename", "source",
137 self
.assertEqual(expected
, actual
)
139 def test_should_uniquify_results(self
):
140 with mock
.patch
.object(self
.srv
, 'backend') as backend
:
141 backend
.rpc_get_completions
.return_value
= [
145 expected
= [{'name': 'a'}]
147 actual
= self
.srv
.rpc_get_completions("filename", "source",
150 self
.assertEqual(expected
, actual
)
153 class TestRPCGetCompletionDocs(ServerTestCase
):
154 def test_should_call_backend(self
):
155 with mock
.patch
.object(self
.srv
, "backend") as backend
:
156 self
.srv
.rpc_get_completion_docstring("completion")
158 (backend
.rpc_get_completion_docstring
159 .assert_called_with("completion"))
161 def test_should_handle_no_backend(self
):
162 self
.srv
.backend
= None
163 self
.assertIsNone(self
.srv
.rpc_get_completion_docstring("foo"))
166 class TestRPCGetCompletionLocation(ServerTestCase
):
167 def test_should_call_backend(self
):
168 with mock
.patch
.object(self
.srv
, "backend") as backend
:
169 self
.srv
.rpc_get_completion_location("completion")
171 (backend
.rpc_get_completion_location
172 .assert_called_with("completion"))
174 def test_should_handle_no_backend(self
):
175 self
.srv
.backend
= None
176 self
.assertIsNone(self
.srv
.rpc_get_completion_location("foo"))
179 class TestRPCGetDefinition(BackendCallTestCase
):
180 def test_should_call_backend(self
):
181 self
.assert_calls_backend("rpc_get_definition")
183 def test_should_handle_no_backend(self
):
184 self
.srv
.backend
= None
185 self
.assertIsNone(self
.srv
.rpc_get_definition("filname", "source",
189 class TestRPCGetDocstring(BackendCallTestCase
):
190 def test_should_call_backend(self
):
191 self
.assert_calls_backend("rpc_get_docstring")
193 def test_should_handle_no_backend(self
):
194 self
.srv
.backend
= None
195 self
.assertIsNone(self
.srv
.rpc_get_docstring("filname", "source",
199 class TestRPCGetOnelineDocstring(BackendCallTestCase
):
200 def test_should_call_backend(self
):
201 self
.assert_calls_backend("rpc_get_oneline_docstring")
203 def test_should_handle_no_backend(self
):
204 self
.srv
.backend
= None
205 self
.assertIsNone(self
.srv
.rpc_get_oneline_docstring("filname",
210 class TestRPCGetCalltipOrOnelineDocstring(BackendCallTestCase
):
211 def test_should_call_backend(self
):
212 self
.assert_calls_backend("rpc_get_calltip_or_oneline_docstring")
214 def test_should_handle_no_backend(self
):
215 self
.srv
.backend
= None
217 self
.srv
.rpc_get_calltip_or_oneline_docstring("filname",
222 class TestRPCGetRenameDiff(BackendCallTestCase
):
223 def test_should_call_backend(self
):
224 self
.assert_calls_backend("rpc_get_rename_diff",
225 add_args
=['new_name'])
227 def test_should_handle_no_backend(self
):
228 self
.srv
.backend
= None
229 self
.assertIsNone(self
.srv
.rpc_get_rename_diff("filname", "source",
230 "offset", "new_name"))
233 class TestRPCGetExtract_VariableDiff(BackendCallTestCase
):
234 def test_should_call_backend(self
):
235 self
.assert_calls_backend("rpc_get_extract_variable_diff",
236 add_args
=['name', 12, 13, 3, 5])
238 def test_should_handle_no_backend(self
):
239 self
.srv
.backend
= None
240 self
.assertIsNone(self
.srv
.rpc_get_extract_variable_diff(
241 "filname", "source", "offset", "new_name", 1, 1, 0, 3))
244 class TestRPCGetExtract_FunctionDiff(BackendCallTestCase
):
245 def test_should_call_backend(self
):
246 self
.assert_calls_backend("rpc_get_extract_function_diff",
247 add_args
=['name', 12, 13, 3, 5])
250 def test_should_handle_no_backend(self
):
251 self
.srv
.backend
= None
252 self
.assertIsNone(self
.srv
.rpc_get_extract_function_diff(
253 "filname", "source", "offset", "new_name", 1, 1, 0, 4))
256 class TestRPCGetInlineDiff(BackendCallTestCase
):
257 def test_should_call_backend(self
):
258 self
.assert_calls_backend("rpc_get_inline_diff")
260 def test_should_handle_no_backend(self
):
261 self
.srv
.backend
= None
262 self
.assertIsNone(self
.srv
.rpc_get_inline_diff("filname", "source",
266 class TestRPCGetPydocCompletions(ServerTestCase
):
267 @mock.patch
.object(server
, 'get_pydoc_completions')
268 def test_should_call_pydoc_completions(self
, get_pydoc_completions
):
269 srv
= server
.ElpyRPCServer()
270 srv
.rpc_get_pydoc_completions()
271 get_pydoc_completions
.assert_called_with(None)
272 srv
.rpc_get_pydoc_completions("foo")
273 get_pydoc_completions
.assert_called_with("foo")
276 class TestGetPydocDocumentation(ServerTestCase
):
277 @mock.patch("pydoc.render_doc")
278 def test_should_find_documentation(self
, render_doc
):
279 render_doc
.return_value
= "expected"
281 actual
= self
.srv
.rpc_get_pydoc_documentation("open")
283 render_doc
.assert_called_with("open",
284 "Elpy Pydoc Documentation for %s",
286 self
.assertEqual("expected", actual
)
288 def test_should_return_none_for_unknown_module(self
):
289 actual
= self
.srv
.rpc_get_pydoc_documentation("frob.open")
291 self
.assertIsNone(actual
)
293 def test_should_return_valid_unicode(self
):
296 docstring
= self
.srv
.rpc_get_pydoc_documentation("tarfile")
298 json
.dumps(docstring
)
301 class TestRPCGetUsages(BackendCallTestCase
):
302 def test_should_call_backend(self
):
303 self
.assert_calls_backend("rpc_get_usages")
305 def test_should_handle_no_backend(self
):
306 self
.srv
.backend
= None
307 self
.assertIsNone(self
.srv
.rpc_get_usages("filname", "source",
311 class TestRPCGetNames(BackendCallTestCase
):
312 def test_should_call_backend(self
):
313 self
.assert_calls_backend("rpc_get_names")
315 def test_should_handle_no_backend(self
):
316 self
.srv
.backend
= None
317 self
.assertIsNone(self
.srv
.rpc_get_names("filname", "source", 0))
320 class TestGetSource(unittest
.TestCase
):
321 def test_should_return_string_by_default(self
):
322 self
.assertEqual(server
.get_source("foo"),
325 def test_should_return_file_contents(self
):
326 fd
, filename
= tempfile
.mkstemp(prefix
="elpy-test-")
327 self
.addCleanup(os
.remove
, filename
)
328 with
open(filename
, "w") as f
:
329 f
.write("file contents")
331 fileobj
= {'filename': filename
}
333 self
.assertEqual(server
.get_source(fileobj
),
336 def test_should_clean_up_tempfile(self
):
337 fd
, filename
= tempfile
.mkstemp(prefix
="elpy-test-")
338 with
open(filename
, "w") as f
:
339 f
.write("file contents")
341 fileobj
= {'filename': filename
,
342 'delete_after_use': True}
344 self
.assertEqual(server
.get_source(fileobj
),
346 self
.assertFalse(os
.path
.exists(filename
))
348 def test_should_support_utf8(self
):
349 fd
, filename
= tempfile
.mkstemp(prefix
="elpy-test-")
350 self
.addCleanup(os
.remove
, filename
)
351 with
open(filename
, "wb") as f
:
352 f
.write(u
"möp".encode("utf-8"))
354 source
= server
.get_source({'filename': filename
})
356 self
.assertEqual(source
, u
"möp")
359 class TestPysymbolKey(BackendTestCase
):
360 def keyLess(self
, a
, b
):
361 self
.assertLess(b
, a
)
362 self
.assertLess(server
._pysymbol
_key
(a
),
363 server
._pysymbol
_key
(b
))
365 def test_should_be_case_insensitive(self
):
366 self
.keyLess("bar", "Foo")
368 def test_should_sort_private_symbols_after_public_symbols(self
):
369 self
.keyLess("foo", "_bar")
371 def test_should_sort_private_symbols_after_dunder_symbols(self
):
372 self
.assertLess(server
._pysymbol
_key
("__foo__"),
373 server
._pysymbol
_key
("_bar"))
375 def test_should_sort_dunder_symbols_after_public_symbols(self
):
376 self
.keyLess("bar", "__foo")
379 class Autopep8TestCase(ServerTestCase
):
381 def test_rpc_fix_code_should_return_formatted_string(self
):
382 code_block
= 'x= 123\n'
383 new_block
= self
.srv
.rpc_fix_code(code_block
, os
.getcwd())
384 self
.assertEqual(new_block
, 'x = 123\n')