]>
crepu.dev Git - config.git/blob - djavu-asus/emacs/elpa/elpy-20230803.1455/elpy/tests/support.py
e2cf687a8d6781a9673bda52e88dfc8e734bddf0
3 """Support classes and functions for the elpy test code.
5 Elpy uses a bit of a peculiar test setup to avoid redundancy. For the
6 tests of the two backends, we provide generic test cases for generic
7 tests and for specific callback tests.
9 These mixins can be included in the actual test classes. We can't add
10 these tests to a BackendTestCase subclass directly because the test
11 discovery would find them there and try to run them, which would fail.
22 from elpy
import jedibackend
23 from elpy
.rpc
import Fault
24 from elpy
.tests
import compat
26 if jedibackend
.JEDISUP18
:
30 class BackendTestCase(unittest
.TestCase
):
31 """Base class for backend tests.
33 This class sets up a project root directory and provides an easy
34 way to create files within the project root.
39 """Create the project root and make sure it gets cleaned up."""
40 super(BackendTestCase
, self
).setUp()
41 self
.project_root
= tempfile
.mkdtemp(prefix
="elpy-test")
42 self
.addCleanup(shutil
.rmtree
, self
.project_root
, True)
44 def project_file(self
, relname
, contents
):
45 """Create a file named relname within the project root.
47 Write contents into that file.
50 full_name
= os
.path
.join(self
.project_root
, relname
)
52 os
.makedirs(os
.path
.dirname(full_name
))
56 fobj
= open(full_name
, "w", encoding
="utf-8")
58 fobj
= open(full_name
, "w")
62 if jedibackend
.JEDISUP18
:
63 return pathlib
.Path(full_name
)
68 class GenericRPCTests(object):
69 """Generic RPC test methods.
71 This is a mixin to add tests that should be run for all RPC
72 methods that follow the generic (filename, source, offset) calling
78 def rpc(self
, filename
, source
, offset
):
79 method
= getattr(self
.backend
, self
.METHOD
)
80 return method(filename
, source
, offset
)
82 def test_should_not_fail_on_inexisting_file(self
):
83 filename
= self
.project_root
+ "/doesnotexist.py"
84 self
.rpc(filename
, "", 0)
86 def test_should_not_fail_on_empty_file(self
):
87 filename
= self
.project_file("test.py", "")
88 self
.rpc(filename
, "", 0)
90 def test_should_not_fail_if_file_is_none(self
):
93 def test_should_not_fail_for_module_syntax_errors(self
):
94 source
, offset
= source_and_offset(
95 "class Foo(object):\n"
118 filename
= self
.project_file("test.py", source
)
120 self
.rpc(filename
, source
, offset
)
122 def test_should_not_fail_for_bad_indentation(self
):
123 source
, offset
= source_and_offset(
127 filename
= self
.project_file("test.py", source
)
129 self
.rpc(filename
, source
, offset
)
131 # @unittest.skipIf((3, 3) <= sys.version_info < (3, 4),
132 # "Bug in jedi for Python 3.3")
133 def test_should_not_fail_for_relative_import(self
):
134 source
, offset
= source_and_offset(
135 "from .. import foo_|_"
137 filename
= self
.project_file("test.py", source
)
139 self
.rpc(filename
, source
, offset
)
141 def test_should_not_fail_on_keyword(self
):
142 source
, offset
= source_and_offset(
147 filename
= self
.project_file("test.py", source
)
149 self
.rpc(filename
, source
, offset
)
151 def test_should_not_fail_with_bad_encoding(self
):
152 source
, offset
= source_and_offset(
153 u
'# coding: utf-8X_|_\n'
155 filename
= self
.project_file("test.py", source
)
157 self
.rpc(filename
, source
, offset
)
159 def test_should_not_fail_with_form_feed_characters(self
):
160 # Bug in Jedi: jedi#424
161 source
, offset
= source_and_offset(
163 "class Test(object):_|_\n"
166 filename
= self
.project_file("test.py", source
)
168 self
.rpc(filename
, source
, offset
)
170 def test_should_not_fail_for_dictionaries_in_weird_places(self
):
171 # Bug in Jedi: jedi#417
172 source
, offset
= source_and_offset(
178 " json.load.return_value = {'foo': [],\n"
183 filename
= self
.project_file("test.py", source
)
185 self
.rpc(filename
, source
, offset
)
187 def test_should_not_break_with_binary_characters_in_docstring(self
):
188 # Bug in Jedi: jedi#427
193 COMMUNITY instance that this conversion belongs to.
194 DISPERSY_VERSION is the dispersy conversion identifier (on the wire version; must be one byte).
195 COMMUNIY_VERSION is the community conversion identifier (on the wire version; must be one byte).
197 COMMUNIY_VERSION may not be '\\x00' or '\\xff'. '\\x00' is used by the DefaultConversion until
198 a proper conversion instance can be made for the Community. '\\xff' is reserved for when
199 more than one byte is needed as a version indicator.
207 source
, offset
= source_and_offset(template
)
208 filename
= self
.project_file("test.py", source
)
210 self
.rpc(filename
, source
, offset
)
212 def test_should_not_fail_for_def_without_name(self
):
214 source
, offset
= source_and_offset(
221 filename
= self
.project_file("project.py", source
)
223 self
.rpc(filename
, source
, offset
)
225 def test_should_not_fail_on_lambda(self
):
226 # Bug #272 / jedi#431, jedi#572
227 source
, offset
= source_and_offset(
230 filename
= self
.project_file("project.py", source
)
232 self
.rpc(filename
, source
, offset
)
234 def test_should_not_fail_on_literals(self
):
235 # Bug #314, #344 / jedi#466
236 source
= u
'lit = u"""\\\n# -*- coding: utf-8 -*-\n"""\n'
238 filename
= self
.project_file("project.py", source
)
240 self
.rpc(filename
, source
, offset
)
242 def test_should_not_fail_with_args_as_args(self
):
243 # Bug #347 in rope_py3k
244 source
, offset
= source_and_offset(
245 "def my_function(*args):\n"
248 filename
= self
.project_file("project.py", source
)
250 self
.rpc(filename
, source
, offset
)
252 def test_should_not_fail_for_unicode_chars_in_string(self
):
253 # Bug #358 / jedi#482
257 logging.info(u"Saving «{}»...".format(title))
258 requests.get(u"https://web.archive.org/save/{}".format(url))
261 filename
= self
.project_file("project.py", source
)
263 self
.rpc(filename
, source
, offset
)
265 def test_should_not_fail_for_bad_escape_sequence(self
):
266 # Bug #360 / jedi#485
269 filename
= self
.project_file("project.py", source
)
271 self
.rpc(filename
, source
, offset
)
273 def test_should_not_fail_for_coding_declarations_in_strings(self
):
274 # Bug #314 / jedi#465 / python#22221
275 source
= u
'lit = """\\\n# -*- coding: utf-8 -*-\n"""'
277 filename
= self
.project_file("project.py", source
)
279 self
.rpc(filename
, source
, offset
)
281 def test_should_not_fail_if_root_vanishes(self
):
283 source
, offset
= source_and_offset(
287 filename
= self
.project_file("project.py", source
)
288 shutil
.rmtree(self
.project_root
)
290 self
.rpc(filename
, source
, offset
)
292 # For some reason, this breaks a lot of other tests. Couldn't
295 # def test_should_not_fail_for_sys_path(self):
296 # # Bug #365 / jedi#486
297 # source, offset = source_and_offset(
300 # "sys.path.index(_|_\n"
302 # filename = self.project_file("project.py", source)
304 # self.rpc(filename, source, offset)
306 def test_should_not_fail_for_key_error(self
):
307 # Bug #561, #564, #570, #588, #593, #599 / jedi#572, jedi#579,
309 source
, offset
= source_and_offset(
312 filename
= self
.project_file("project.py", source
)
314 self
.rpc(filename
, source
, offset
)
316 def test_should_not_fail_for_badly_defined_global_variable(self
):
317 # Bug #519 / jedi#610
318 source
, offset
= source_and_offset(
321 global global_dict_var
322 global_dict_var = dict()
325 global global_dict_var
326 q = global_dict_var.copy_|_()
328 filename
= self
.project_file("project.py", source
)
330 self
.rpc(filename
, source
, offset
)
332 def test_should_not_fail_with_mergednamesdict(self
):
333 # Bug #563 / jedi#589
334 source
, offset
= source_and_offset(
335 u
'from email import message_|_'
337 filename
= self
.project_file("project.py", source
)
339 self
.rpc(filename
, source
, offset
)
342 class RPCGetCompletionsTests(GenericRPCTests
):
343 METHOD
= "rpc_get_completions"
345 def test_should_complete_builtin(self
):
346 source
, offset
= source_and_offset("o_|_")
348 expected
= self
.BUILTINS
349 actual
= [cand
['name'] for cand
in
350 self
.backend
.rpc_get_completions("test.py",
353 for candidate
in expected
:
354 self
.assertIn(candidate
, actual
)
356 if sys
.version_info
>= (3, 5) or sys
.version_info
< (3, 0):
357 JSON_COMPLETIONS
= ["SONDecoder", "SONEncoder", "SONDecodeError"]
359 JSON_COMPLETIONS
= ["SONDecoder", "SONEncoder"]
361 def test_should_complete_imports(self
):
362 source
, offset
= source_and_offset("import json\n"
364 filename
= self
.project_file("test.py", source
)
365 completions
= self
.backend
.rpc_get_completions(filename
,
369 sorted([cand
['suffix'] for cand
in completions
]),
370 sorted(self
.JSON_COMPLETIONS
))
372 def test_should_complete_top_level_modules_for_import(self
):
373 source
, offset
= source_and_offset("import multi_|_")
374 filename
= self
.project_file("test.py", source
)
375 completions
= self
.backend
.rpc_get_completions(filename
,
379 expected
= ["processing"]
381 expected
= ["file", "processing"]
382 self
.assertEqual(sorted([cand
['suffix'] for cand
in completions
]),
385 def test_should_complete_packages_for_import(self
):
386 source
, offset
= source_and_offset("import email.mi_|_")
387 filename
= self
.project_file("test.py", source
)
388 completions
= self
.backend
.rpc_get_completions(filename
,
391 if sys
.version_info
< (3, 0):
392 compl
= [u
'me', u
'METext']
395 self
.assertEqual([cand
['suffix'] for cand
in completions
],
398 def test_should_not_complete_for_import(self
):
399 source
, offset
= source_and_offset("import foo.Conf_|_")
400 filename
= self
.project_file("test.py", source
)
401 completions
= self
.backend
.rpc_get_completions(filename
,
404 self
.assertEqual([cand
['suffix'] for cand
in completions
],
407 # @unittest.skipIf((3, 3) <= sys.version_info < (3, 4),
408 # "Bug in jedi for Python 3.3")
409 def test_should_not_fail_for_short_module(self
):
410 source
, offset
= source_and_offset("from .. import foo_|_")
411 filename
= self
.project_file("test.py", source
)
412 completions
= self
.backend
.rpc_get_completions(filename
,
415 self
.assertIsNotNone(completions
)
417 def test_should_complete_sys(self
):
418 source
, offset
= source_and_offset("import sys\nsys._|_")
419 filename
= self
.project_file("test.py", source
)
420 completions
= self
.backend
.rpc_get_completions(filename
,
423 self
.assertIn('path', [cand
['suffix'] for cand
in completions
])
425 def test_should_find_with_trailing_text(self
):
426 source
, offset
= source_and_offset(
427 "import threading\nthreading.T_|_mumble mumble")
429 expected
= ["Thread", "ThreadError", "Timer"]
430 actual
= [cand
['name'] for cand
in
431 self
.backend
.rpc_get_completions("test.py", source
, offset
)]
433 for candidate
in expected
:
434 self
.assertIn(candidate
, actual
)
436 def test_should_find_completion_different_package(self
):
438 self
.project_file("project/__init__.py", "")
439 source1
= ("class Add:\n"
440 " def add(self, a, b):\n"
442 self
.project_file("project/add.py", source1
)
443 source2
, offset
= source_and_offset(
444 "from project.add import Add\n"
445 "class Calculator:\n"
446 " def add(self, a, b):\n"
449 file2
= self
.project_file("project/calculator.py", source2
)
450 proposals
= self
.backend
.rpc_get_completions(file2
,
453 self
.assertEqual(["add"],
454 [proposal
["name"] for proposal
in proposals
])
456 def test_should_return_nothing_when_no_completion(self
):
457 source
, offset
= source_and_offset("nothingcancompletethis_|_")
458 self
.assertEqual([], self
.backend
.rpc_get_completions("test.py",
462 class RPCGetCompletionDocstringTests(object):
463 def test_should_return_docstring(self
):
464 source
, offset
= source_and_offset("import json\n"
466 filename
= self
.project_file("test.py", source
)
467 completions
= self
.backend
.rpc_get_completions(filename
,
470 completions
.sort(key
=lambda p
: p
["name"])
471 prop
= completions
[0]
472 self
.assertEqual(prop
["name"], "JSONEncoder")
474 docs
= self
.backend
.rpc_get_completion_docstring("JSONEncoder")
476 self
.assertIn("Extensible JSON", docs
)
478 def test_should_return_none_if_unknown(self
):
479 docs
= self
.backend
.rpc_get_completion_docstring("Foo")
481 self
.assertIsNone(docs
)
483 def test_should_return_none_if_on_a_builtin(self
):
484 source
, offset
= source_and_offset("a = 12\n"
486 filename
= self
.project_file("test.py", source
)
487 completions
= self
.backend
.rpc_get_docstring(filename
,
490 self
.assertIsNone(completions
)
493 class RPCGetCompletionLocationTests(object):
494 def test_should_return_location(self
):
495 source
, offset
= source_and_offset("donaudampfschiff = 1\n"
497 filename
= self
.project_file("test.py", source
)
498 completions
= self
.backend
.rpc_get_completions(filename
,
501 prop
= completions
[0]
502 self
.assertEqual(prop
["name"], "donaudampfschiff")
504 loc
= self
.backend
.rpc_get_completion_location("donaudampfschiff")
506 self
.assertEqual((filename
, 1), loc
)
508 def test_should_return_none_if_unknown(self
):
509 docs
= self
.backend
.rpc_get_completion_location("Foo")
511 self
.assertIsNone(docs
)
514 class RPCGetDefinitionTests(GenericRPCTests
):
515 METHOD
= "rpc_get_definition"
517 def test_should_return_definition_location_same_file(self
):
518 source
, offset
= source_and_offset("import threading\n"
519 "def test_function(a, b):\n"
522 "test_func_|_tion(\n")
523 filename
= self
.project_file("test.py", source
)
525 location
= self
.backend
.rpc_get_definition(filename
,
529 self
.assertEqual(location
[0], filename
)
530 # On def or on the function name
531 self
.assertIn(location
[1], (17, 21))
533 def test_should_return_location_in_same_file_if_not_saved(self
):
534 source
, offset
= source_and_offset(
538 "def other_function():\n"
539 " test_f_|_unction(1, 2)\n"
542 "def test_function(a, b):\n"
544 filename
= self
.project_file("test.py", "")
546 location
= self
.backend
.rpc_get_definition(filename
,
550 self
.assertEqual(location
[0], filename
)
551 # def or function name
552 self
.assertIn(location
[1], (67, 71))
554 def test_should_return_location_in_different_file(self
):
555 source1
= ("def test_function(a, b):\n"
557 file1
= self
.project_file("test1.py", source1
)
558 source2
, offset
= source_and_offset("from test1 import test_function\n"
559 "test_funct_|_ion(1, 2)\n")
560 file2
= self
.project_file("test2.py", source2
)
562 definition
= self
.backend
.rpc_get_definition(file2
,
566 self
.assertEqual(definition
[0], file1
)
567 # Either on the def or on the function name
568 self
.assertIn(definition
[1], (0, 4))
570 def test_should_return_none_if_location_not_found(self
):
571 source
, offset
= source_and_offset("test_f_|_unction()\n")
572 filename
= self
.project_file("test.py", source
)
574 definition
= self
.backend
.rpc_get_definition(filename
,
578 self
.assertIsNone(definition
)
580 def test_should_return_none_if_outside_of_symbol(self
):
581 source
, offset
= source_and_offset("test_function(_|_)\n")
582 filename
= self
.project_file("test.py", source
)
584 definition
= self
.backend
.rpc_get_definition(filename
,
588 self
.assertIsNone(definition
)
590 def test_should_return_definition_location_different_package(self
):
592 self
.project_file("project/__init__.py", "")
593 source1
= ("class Add:\n"
594 " def add(self, a, b):\n"
596 file1
= self
.project_file("project/add.py", source1
)
597 source2
, offset
= source_and_offset(
598 "from project.add import Add\n"
599 "class Calculator:\n"
600 " def add(self, a, b):\n"
601 " return Add_|_().add(a, b)\n")
602 file2
= self
.project_file("project/calculator.py", source2
)
604 location
= self
.backend
.rpc_get_definition(file2
,
608 self
.assertEqual(location
[0], file1
)
609 # class or class name
610 self
.assertIn(location
[1], (0, 6))
612 def test_should_find_variable_definition(self
):
613 source
, offset
= source_and_offset("SOME_VALUE = 1\n"
615 "variable = _|_SOME_VALUE\n")
616 filename
= self
.project_file("test.py", source
)
617 self
.assertEqual(self
.backend
.rpc_get_definition(filename
,
623 class RPCGetAssignmentTests():
624 METHOD
= "rpc_get_assignment"
626 def test_should_raise_fault(self
):
627 if jedibackend
.JEDISUP17
:
628 with self
.assertRaises(Fault
):
629 self
.backend
.rpc_get_assignment("test.py", "dummy code", 1)
632 class RPCGetCalltipTests(GenericRPCTests
):
633 METHOD
= "rpc_get_calltip"
635 def test_should_get_calltip(self
):
636 expected
= self
.THREAD_CALLTIP
637 source
, offset
= source_and_offset(
638 "import threading\nthreading.Thread(_|_")
639 filename
= self
.project_file("test.py", source
)
640 calltip
= self
.backend
.rpc_get_calltip(filename
,
643 self
.assertEqual(calltip
, expected
)
644 calltip
= self
.backend
.rpc_get_calltip_or_oneline_docstring(filename
,
648 self
.assertEqual(calltip
, expected
)
650 def test_should_get_calltip_even_after_parens(self
):
651 source
, offset
= source_and_offset(
652 "import threading\nthreading.Thread(foo()_|_")
653 filename
= self
.project_file("test.py", source
)
654 actual
= self
.backend
.rpc_get_calltip(filename
,
657 self
.assertEqual(self
.THREAD_CALLTIP
, actual
)
658 actual
= self
.backend
.rpc_get_calltip_or_oneline_docstring(filename
,
662 self
.assertEqual(self
.THREAD_CALLTIP
, actual
)
664 def test_should_get_calltip_at_closing_paren(self
):
665 source
, offset
= source_and_offset(
666 "import threading\nthreading.Thread(_|_)")
667 filename
= self
.project_file("test.py", source
)
668 actual
= self
.backend
.rpc_get_calltip(filename
,
671 self
.assertEqual(self
.THREAD_CALLTIP
, actual
)
672 actual
= self
.backend
.rpc_get_calltip_or_oneline_docstring(filename
,
675 self
.assertEqual(actual
['kind'], "oneline_doc")
677 def test_should_not_missing_attribute_get_definition(self
):
678 # Bug #627 / jedi#573
679 source
, offset
= source_and_offset(
680 "import threading\nthreading.Thread(_|_)")
681 filename
= self
.project_file("test.py", source
)
683 self
.backend
.rpc_get_calltip(filename
, source
, offset
)
685 def test_should_return_none_for_bad_identifier(self
):
686 source
, offset
= source_and_offset(
688 filename
= self
.project_file("test.py", source
)
689 calltip
= self
.backend
.rpc_get_calltip(filename
,
692 self
.assertIsNone(calltip
)
693 calltip
= self
.backend
.rpc_get_calltip_or_oneline_docstring(filename
,
696 self
.assertIsNone(calltip
)
698 def test_should_remove_self_argument(self
):
699 source
, offset
= source_and_offset(
702 filename
= self
.project_file("test.py", source
)
704 actual
= self
.backend
.rpc_get_calltip(filename
,
707 self
.assertEqual(self
.KEYS_CALLTIP
, actual
)
708 actual
= self
.backend
.rpc_get_calltip_or_oneline_docstring(filename
,
712 self
.assertEqual(self
.KEYS_CALLTIP
, actual
)
714 def test_should_remove_package_prefix(self
):
715 source
, offset
= source_and_offset(
717 "d = decimal.Decimal('1.5')\n"
719 filename
= self
.project_file("test.py", source
)
721 actual
= self
.backend
.rpc_get_calltip(filename
,
724 self
.assertEqual(self
.RADIX_CALLTIP
, actual
)
725 actual
= self
.backend
.rpc_get_calltip_or_oneline_docstring(filename
,
729 self
.assertEqual(self
.RADIX_CALLTIP
, actual
)
731 def test_should_return_none_outside_of_all(self
):
732 filename
= self
.project_file("test.py", "")
733 source
, offset
= source_and_offset("import thr_|_eading\n")
734 calltip
= self
.backend
.rpc_get_calltip(filename
,
736 self
.assertIsNone(calltip
)
737 calltip
= self
.backend
.rpc_get_calltip_or_oneline_docstring(filename
,
740 self
.assertIsNotNone(calltip
)
742 def test_should_find_calltip_different_package(self
):
744 self
.project_file("project/__init__.py", "")
745 source1
= ("class Add:\n"
746 " def add(self, a, b):\n"
748 self
.project_file("project/add.py", source1
)
749 source2
, offset
= source_and_offset(
750 "from project.add import Add\n"
751 "class Calculator:\n"
752 " def add(self, a, b):\n"
755 file2
= self
.project_file("project/calculator.py", source2
)
757 actual
= self
.backend
.rpc_get_calltip(file2
,
760 self
.assertEqual(self
.ADD_CALLTIP
, actual
)
761 actual
= self
.backend
.rpc_get_calltip_or_oneline_docstring(file2
,
765 self
.assertEqual(self
.ADD_CALLTIP
, actual
)
767 def test_should_return_oneline_docstring_if_no_calltip(self
):
768 source
, offset
= source_and_offset(
769 "def foo(a, b):\n fo_|_o(1 + 2)")
770 filename
= self
.project_file("test.py", source
)
771 calltip
= self
.backend
.rpc_get_calltip_or_oneline_docstring(filename
,
774 self
.assertEqual(calltip
['kind'], 'oneline_doc')
775 self
.assertEqual(calltip
['doc'], 'No documentation')
778 class RPCGetDocstringTests(GenericRPCTests
):
779 METHOD
= "rpc_get_docstring"
781 def check_docstring(self
, docstring
):
784 return s
[:s
.index("\n")]
785 match
= re
.match(self
.JSON_LOADS_REGEX
,
786 first_line(docstring
))
787 self
.assertIsNotNone(match
)
789 def test_should_get_docstring(self
):
790 source
, offset
= source_and_offset(
791 "import json\njson.loads_|_(")
792 filename
= self
.project_file("test.py", source
)
793 docstring
= self
.backend
.rpc_get_docstring(filename
,
796 self
.check_docstring(docstring
)
798 def test_should_return_none_for_bad_identifier(self
):
799 source
, offset
= source_and_offset(
801 filename
= self
.project_file("test.py", source
)
802 docstring
= self
.backend
.rpc_get_docstring(filename
,
805 self
.assertIsNone(docstring
)
808 class RPCGetOnelineDocstringTests(GenericRPCTests
):
809 METHOD
= "rpc_get_oneline_docstring"
811 def check_docstring(self
, docstring
):
813 self
.assertEqual(docstring
['doc'],
814 self
.JSON_LOADS_DOCSTRING
)
816 def check_module_docstring(self
, docstring
):
818 self
.assertEqual(docstring
['doc'],
821 def test_should_get_oneline_docstring(self
):
822 source
, offset
= source_and_offset(
823 "import json\njson.loads_|_(")
824 filename
= self
.project_file("test.py", source
)
825 docstring
= self
.backend
.rpc_get_oneline_docstring(filename
,
828 self
.check_docstring(docstring
)
829 docstring
= self
.backend
.rpc_get_calltip_or_oneline_docstring(filename
,
832 docstring
.pop('kind')
833 self
.check_docstring(docstring
)
835 def test_should_get_oneline_docstring_for_modules(self
):
836 source
, offset
= source_and_offset(
837 "import json_|_\njson.loads(")
838 filename
= self
.project_file("test.py", source
)
839 docstring
= self
.backend
.rpc_get_oneline_docstring(filename
,
842 self
.check_module_docstring(docstring
)
843 docstring
= self
.backend
.rpc_get_calltip_or_oneline_docstring(filename
,
846 docstring
.pop('kind')
847 self
.check_module_docstring(docstring
)
849 def test_should_return_none_for_bad_identifier(self
):
850 source
, offset
= source_and_offset(
852 filename
= self
.project_file("test.py", source
)
853 docstring
= self
.backend
.rpc_get_oneline_docstring(filename
,
856 self
.assertIsNone(docstring
)
857 docstring
= self
.backend
.rpc_get_calltip_or_oneline_docstring(filename
,
860 self
.assertIsNone(docstring
)
863 @unittest.skipIf(not jedibackend
.JEDISUP17
,
864 "Refactoring not available with jedi<17")
865 @unittest.skipIf(sys
.version_info
< (3, 6),
866 "Jedi refactoring not available for python < 3.6")
867 class RPCGetRenameDiffTests(object):
868 METHOD
= "rpc_get_rename_diff"
870 def test_should_return_rename_diff(self
):
871 source
, offset
= source_and_offset("def foo(a, b):\n"
875 diff
= self
.backend
.rpc_get_rename_diff("test.py", source
, offset
,
877 assert diff
['success']
878 self
.assertIn("-def foo(a, b):\n"
884 def test_should_fail_for_invalid_symbol_at_point(self
):
885 source
, offset
= source_and_offset("def foo(a, b):\n"
889 diff
= self
.backend
.rpc_get_rename_diff("test.py", source
, offset
,
891 self
.assertFalse(diff
['success'])
894 @unittest.skipIf(not jedibackend
.JEDISUP17
,
895 "Refactoring not available with jedi<17")
896 @unittest.skipIf(sys
.version_info
< (3, 6),
897 "Jedi refactoring not available for python < 3.6")
898 class RPCGetExtractFunctionDiffTests(object):
899 METHOD
= "rpc_get_extract_function_diff"
901 def test_should_return_function_extraction_diff(self
):
902 source
, offset
= source_and_offset("print(a)\n"
905 diff
= self
.backend
.rpc_get_extract_function_diff(
906 "test.py", source
, offset
,
908 line_beg
=1, line_end
=2,
909 col_beg
=0, col_end
=8)
910 assert diff
['success']
911 self
.assertIn('-print(a)\n'
919 @unittest.skipIf(not jedibackend
.JEDISUP17
,
920 "Refactoring not available with jedi<17")
921 @unittest.skipIf(sys
.version_info
< (3, 6),
922 "Jedi refactoring not available for python < 3.6")
923 class RPCGetExtractVariableDiffTests(object):
924 METHOD
= "rpc_get_extract_variable_diff"
926 def test_should_return_variable_extraction_diff(self
):
927 source
, offset
= source_and_offset("b = 12\n"
929 "print_|_(a + 1 + b/2)\n")
931 diff
= self
.backend
.rpc_get_extract_variable_diff(
932 "test.py", source
, offset
,
934 line_beg
=3, line_end
=3,
935 col_beg
=7, col_end
=16)
936 assert diff
['success']
937 self
.assertIn("-print(a + 1 + b/2)\n+c = a + 1 + b/2\n+print(c)\n",
941 @unittest.skipIf(not jedibackend
.JEDISUP17
,
942 "Refactoring not available with jedi<17")
943 @unittest.skipIf(sys
.version_info
< (3, 6),
944 "Jedi refactoring not available for python < 3.6")
945 class RPCGetInlineDiffTests(object):
946 METHOD
= "rpc_get_inline_diff"
948 def test_should_return_inline_diff(self
):
949 source
, offset
= source_and_offset("foo = 3.1\n"
952 diff
= self
.backend
.rpc_get_inline_diff("test.py", source
,
954 assert diff
['success']
955 self
.assertIn("-bar = foo + 1\n-x = int(bar)\n+x = int(foo + 1)",
958 def test_should_error_on_refactoring_failure(self
):
959 source
, offset
= source_and_offset("foo = 3.1\n"
962 diff
= self
.backend
.rpc_get_inline_diff("test.py", source
,
964 self
.assertFalse(diff
['success'])
967 class RPCGetNamesTests(GenericRPCTests
):
968 METHOD
= "rpc_get_names"
970 def test_shouldreturn_names_in_same_file(self
):
971 filename
= self
.project_file("test.py", "")
972 source
, offset
= source_and_offset(
975 "c = _|_foo(5, 2)\n")
977 names
= self
.backend
.rpc_get_names(filename
,
981 self
.assertEqual(names
,
983 'filename': filename
,
986 'filename': filename
,
989 'filename': filename
,
992 'filename': filename
,
995 'filename': filename
,
998 'filename': filename
,
1001 'filename': filename
,
1004 def test_should_not_fail_without_symbol(self
):
1005 filename
= self
.project_file("test.py", "")
1007 names
= self
.backend
.rpc_get_names(filename
,
1011 self
.assertEqual(names
, [])
1014 class RPCGetUsagesTests(GenericRPCTests
):
1015 METHOD
= "rpc_get_usages"
1017 def test_should_return_uses_in_same_file(self
):
1018 filename
= self
.project_file("test.py", "")
1019 source
, offset
= source_and_offset(
1021 " return _|_x + x\n")
1023 usages
= self
.backend
.rpc_get_usages(filename
,
1027 self
.assertEqual(usages
,
1030 'filename': filename
},
1032 'filename': filename
,
1035 'filename': filename
,
1038 def test_should_return_uses_in_other_file(self
):
1039 file1
= self
.project_file("file1.py", "")
1040 file2
= self
.project_file("file2.py", "\n\n\n\n\nx = 5")
1041 source
, offset
= source_and_offset(
1045 usages
= self
.backend
.rpc_get_usages(file1
,
1049 self
.assertEqual(usages
,
1057 def test_should_not_fail_without_symbol(self
):
1058 filename
= self
.project_file("file.py", "")
1060 usages
= self
.backend
.rpc_get_usages(filename
,
1064 self
.assertEqual(usages
, [])
1067 def source_and_offset(source
):
1068 """Return a source and offset from a source description.
1070 >>> source_and_offset("hello, _|_world")
1072 >>> source_and_offset("_|_hello, world")
1074 >>> source_and_offset("hello, world_|_")
1075 ("hello, world", 12)
1077 offset
= source
.index("_|_")
1078 return source
[:offset
] + source
[offset
+ 3:], offset