diff --git a/test/test_integration_import.py b/test/test_integration_import.py new file mode 100644 index 00000000..16e044cb --- /dev/null +++ b/test/test_integration_import.py @@ -0,0 +1,48 @@ +from .base import cwd_at + +import itertools + +from jedi import Script + + +def test_goto_definition_on_import(): + assert Script("import sys_blabla", 1, 8).goto_definitions() == [] + assert len(Script("import sys", 1, 8).goto_definitions()) == 1 + + +@cwd_at('jedi') +def test_complete_on_empty_import(): + # should just list the files in the directory + assert 10 < len(Script("from .", source_path='').completions()) < 30 + assert 10 < len(Script("from . import", 1, 5, '').completions()) < 30 + assert 10 < len(Script("from . import classes", 1, 5, '').completions()) < 30 + assert len(Script("import").completions()) == 0 + assert len(Script("import import", source_path='').completions()) > 0 + + # 111 + assert Script("from datetime import").completions()[0].name == 'import' + assert Script("from datetime import ").completions() + + +def test_named_import(): + """named import - jedi-vim issue #8""" + s = "import time as dt" + assert len(Script(s, 1, 15, '/').goto_definitions()) == 1 + assert len(Script(s, 1, 10, '/').goto_definitions()) == 1 + + +def test_goto_following_on_imports(): + s = "import multiprocessing.dummy; multiprocessing.dummy" + g = Script(s).goto_assignments() + assert len(g) == 1 + assert g[0].start_pos != (0, 0) + + +def test_follow_definition(): + """ github issue #45 """ + c = Script("from datetime import timedelta; timedelta").completions() + # type can also point to import, but there will be additional + # attributes + objs = itertools.chain.from_iterable(r.follow_definition() for r in c) + types = [o.type for o in objs] + assert 'import' not in types and 'class' in types diff --git a/test/test_jedi_system.py b/test/test_jedi_system.py new file mode 100644 index 00000000..ea0d1e9d --- /dev/null +++ b/test/test_jedi_system.py @@ -0,0 +1,61 @@ +""" +Test the Jedi "System" which means for example to test if imports are +correctly used. +""" + +import os +import inspect + +import jedi + + +def test_settings_module(): + """ + jedi.settings and jedi.cache.settings must be the same module. + """ + from jedi import cache + from jedi import settings + assert cache.settings is settings + + +def test_no_duplicate_modules(): + """ + Make sure that import hack works as expected. + + Jedi does an import hack (see: jedi/__init__.py) to have submodules + with circular dependencies. The modules in this circular dependency + "loop" must be imported by ``import `` rather than normal + ``from jedi import `` (or ``from . jedi ...``). This test + make sure that this is satisfied. + + See also: + + - `#160 `_ + - `#161 `_ + """ + import sys + jedipath = os.path.dirname(os.path.abspath(jedi.__file__)) + + def is_submodule(m): + try: + filepath = m.__file__ + except AttributeError: + return False + return os.path.abspath(filepath).startswith(jedipath) + + modules = list(filter(is_submodule, sys.modules.values())) + top_modules = [m for m in modules if not m.__name__.startswith('jedi.')] + for m in modules: + if m is jedi: + # py.test automatically improts `jedi.*` when --doctest-modules + # is given. So this test cannot succeeds. + continue + for tm in top_modules: + try: + imported = getattr(m, tm.__name__) + except AttributeError: + continue + if inspect.ismodule(imported): + # module could have a function with the same name, e.g. + # `keywords.keywords`. + assert imported is tm diff --git a/test/test_regression.py b/test/test_regression.py index 4f08a13c..1e39fad3 100755 --- a/test/test_regression.py +++ b/test/test_regression.py @@ -104,24 +104,6 @@ class TestRegression(TestBase): s = self.completions("", (1, 0)) assert len(s) > 0 - def test_goto_definition_on_import(self): - assert self.goto_definitions("import sys_blabla", (1, 8)) == [] - assert len(self.goto_definitions("import sys", (1, 8))) == 1 - - @cwd_at('jedi') - def test_complete_on_empty_import(self): - # should just list the files in the directory - assert 10 < len(self.completions("from .", path='')) < 30 - assert 10 < len(self.completions("from . import", (1, 5), '')) < 30 - assert 10 < len(self.completions("from . import classes", - (1, 5), '')) < 30 - assert len(self.completions("import")) == 0 - assert len(self.completions("import import", path='')) > 0 - - # 111 - assert self.completions("from datetime import")[0].name == 'import' - assert self.completions("from datetime import ") - @cwd_at('jedi') def test_add_dynamic_mods(self): api.settings.additional_dynamic_modules = ['dynamic.py'] @@ -136,12 +118,6 @@ class TestRegression(TestBase): assert len(result) == 1 assert result[0].description == 'class int' - def test_named_import(self): - """ named import - jedi-vim issue #8 """ - s = "import time as dt" - assert len(jedi.Script(s, 1, 15, '/').goto_definitions()) == 1 - assert len(jedi.Script(s, 1, 10, '/').goto_definitions()) == 1 - def test_unicode_script(self): """ normally no unicode objects are being used. (<=2.7) """ s = unicode("import datetime; datetime.timedelta") @@ -186,15 +162,6 @@ class TestRegression(TestBase): s = self.completions("import os; os.P_") assert 'P_NOWAIT' in [i.name for i in s] - def test_follow_definition(self): - """ github issue #45 """ - c = self.completions("from datetime import timedelta; timedelta") - # type can also point to import, but there will be additional - # attributes - objs = itertools.chain.from_iterable(r.follow_definition() for r in c) - types = [o.type for o in objs] - assert 'import' not in types and 'class' in types - def test_keyword(self): """ github jedi-vim issue #44 """ defs = self.goto_definitions("print") @@ -219,12 +186,6 @@ class TestRegression(TestBase): """ self.goto_assignments('in') - def test_goto_following_on_imports(self): - s = "import multiprocessing.dummy; multiprocessing.dummy" - g = self.goto_assignments(s) - assert len(g) == 1 - assert g[0].start_pos != (0, 0) - def test_points_in_completion(self): """At some point, points were inserted into the completions, this caused problems, sometimes. @@ -233,27 +194,6 @@ class TestRegression(TestBase): assert c[0].name == 'IndentationError' self.assertEqual(c[0].complete, 'or') - def test_docstrings_type_str(self): - s = """ - def func(arg): - ''' - :type arg: str - ''' - arg.""" - - names = [c.name for c in self.completions(s)] - assert 'join' in names - - def test_docstrings_type_dotted_import(self): - s = """ - def func(arg): - ''' - :type arg: threading.Thread - ''' - arg.""" - names = [c.name for c in self.completions(s)] - assert 'start' in names - def test_no_statement_parent(self): source = textwrap.dedent(""" def f():