""" Unit tests to avoid errors of the past. These are also all tests that didn't found a good place in any other testing module. """ import os import sys import textwrap import pytest from jedi import api from jedi.evaluate import imports from .helpers import cwd_at def test_goto_definition_cursor(Script): s = ("class A():\n" " def _something(self):\n" " return\n" " def different_line(self,\n" " b):\n" " return\n" "A._something\n" "A.different_line" ) in_name = 2, 9 under_score = 2, 8 cls = 2, 7 should1 = 7, 10 diff_line = 4, 10 should2 = 8, 10 def get_def(pos): return [d.description for d in Script(s, *pos).goto_definitions()] in_name = get_def(in_name) under_score = get_def(under_score) should1 = get_def(should1) should2 = get_def(should2) diff_line = get_def(diff_line) assert should1 == in_name assert should1 == under_score assert should2 == diff_line assert get_def(cls) == [] @pytest.mark.skipif('True', reason='Skip for now, test case is not really supported.') @cwd_at('jedi') def test_add_dynamic_mods(Script): fname = '__main__.py' api.settings.additional_dynamic_modules = [fname] # Fictional module that defines a function. src1 = "def r(a): return a" # Other fictional modules in another place in the fs. src2 = 'from .. import setup; setup.r(1)' script = Script(src1, path='../setup.py') imports.load_module(script._evaluator, os.path.abspath(fname), src2) result = script.goto_definitions() assert len(result) == 1 assert result[0].description == 'class int' def test_os_nowait(Script): """ github issue #45 """ s = Script("import os; os.P_").completions() assert 'P_NOWAIT' in [i.name for i in s] def test_points_in_completion(Script): """At some point, points were inserted into the completions, this caused problems, sometimes. """ c = Script("if IndentationErr").completions() assert c[0].name == 'IndentationError' assert c[0].complete == 'or' def test_no_statement_parent(Script): source = textwrap.dedent(""" def f(): pass class C: pass variable = f if random.choice([0, 1]) else C""") defs = Script(source, column=3).goto_definitions() defs = sorted(defs, key=lambda d: d.line) assert [d.description for d in defs] == ['def f', 'class C'] def check_definition_by_marker(Script, source, after_cursor, names): r""" Find definitions specified by `after_cursor` and check what found For example, for the following configuration, you can pass ``after_cursor = 'y)'``.:: function( x, y) \ `- You want cursor to be here """ source = textwrap.dedent(source) for (i, line) in enumerate(source.splitlines()): if after_cursor in line: break column = len(line) - len(after_cursor) defs = Script(source, i + 1, column).goto_definitions() assert [d.name for d in defs] == names def test_backslash_continuation(Script): """ Test that ModuleWithCursor.get_path_until_cursor handles continuation """ check_definition_by_marker(Script, r""" x = 0 a = \ [1, 2, 3, 4, 5, 6, 7, 8, 9, x] # <-- here """, '] # <-- here', ['int']) # completion in whitespace s = 'asdfxyxxxxxxxx sds\\\n hello' assert Script(s, 2, 4).goto_assignments() == [] def test_backslash_continuation_and_bracket(Script): check_definition_by_marker(Script, r""" x = 0 a = \ [1, 2, 3, 4, 5, 6, 7, 8, 9, (x)] # <-- here """, '(x)] # <-- here', ['int']) def test_generator(Script): # Did have some problems with the usage of generator completions this # way. s = "def abc():\n" \ " yield 1\n" \ "abc()." assert Script(s).completions() def test_fake_subnodes(Script): """ Test the number of subnodes of a fake object. There was a bug where the number of child nodes would grow on every call to :func:``jedi.evaluate.compiled.fake.get_faked``. See Github PR#649 and isseu #591. """ def get_str_completion(values): for c in values: if c.name == 'str': return c limit = None for i in range(2): completions = Script('').completions() c = get_str_completion(completions) str_context, = c._name.infer() n = len(str_context.tree_node.children[-1].children) if i == 0: limit = n else: assert n == limit def test_loading_unicode_files_with_bad_global_charset(Script, monkeypatch, tmpdir): dirname = str(tmpdir.mkdir('jedi-test')) filename1 = os.path.join(dirname, 'test1.py') filename2 = os.path.join(dirname, 'test2.py') if sys.version_info < (3, 0): data = "# coding: latin-1\nfoo = 'm\xf6p'\n" else: data = "# coding: latin-1\nfoo = 'm\xf6p'\n".encode("latin-1") with open(filename1, "wb") as f: f.write(data) s = Script("from test1 import foo\nfoo.", line=2, column=4, path=filename2) s.completions()