1
0
forked from VimPlug/jedi

moved api, parser and evaluate test directories to test_api, test_parser...

This commit is contained in:
Dave Halter
2014-01-29 21:16:18 +01:00
parent 021aae365d
commit 8660555d7b
31 changed files with 2 additions and 2 deletions

View File

52
test/test_api/test_api.py Normal file
View File

@@ -0,0 +1,52 @@
"""
Test all things related to the ``jedi.api`` module.
"""
from jedi import api
from pytest import raises
def test_preload_modules():
def check_loaded(*modules):
# +1 for None module (currently used)
assert len(parser_cache) == len(modules) + 1
for i in modules:
assert [i in k for k in parser_cache.keys() if k is not None]
from jedi import cache
temp_cache, cache.parser_cache = cache.parser_cache, {}
parser_cache = cache.parser_cache
api.preload_module('sys')
check_loaded() # compiled (c_builtin) modules shouldn't be in the cache.
api.preload_module('json', 'token')
check_loaded('json', 'token')
cache.parser_cache = temp_cache
def test_empty_script():
assert api.Script('')
def test_line_number_errors():
"""
Script should raise a ValueError if line/column numbers are not in a
valid range.
"""
s = 'hello'
# lines
with raises(ValueError):
api.Script(s, 2, 0)
with raises(ValueError):
api.Script(s, 0, 0)
# columns
with raises(ValueError):
api.Script(s, 1, len(s) + 1)
with raises(ValueError):
api.Script(s, 1, -1)
# ok
api.Script(s, 1, 0)
api.Script(s, 1, len(s))

View File

@@ -0,0 +1,89 @@
""" Test all things related to the ``jedi.api_classes`` module.
"""
import textwrap
import pytest
from jedi import Script
import jedi
def test_is_keyword():
#results = Script('import ', 1, 1, None).goto_definitions()
#assert len(results) == 1 and results[0].is_keyword is True
results = Script('str', 1, 1, None).goto_definitions()
assert len(results) == 1 and results[0].is_keyword is False
def make_definitions():
"""
Return a list of definitions for parametrized tests.
:rtype: [jedi.api_classes.BaseDefinition]
"""
source = textwrap.dedent("""
import sys
class C:
pass
x = C()
def f():
pass
def g():
yield
h = lambda: None
""")
definitions = []
definitions += jedi.defined_names(source)
source += textwrap.dedent("""
variable = sys or C or x or f or g or g() or h""")
lines = source.splitlines()
script = Script(source, len(lines), len('variable'), None)
definitions += script.goto_definitions()
script2 = Script(source, 4, len('class C'), None)
definitions += script2.usages()
source_param = "def f(a): return a"
script_param = Script(source_param, 1, len(source_param), None)
definitions += script_param.goto_assignments()
return definitions
@pytest.mark.parametrize('definition', make_definitions())
def test_basedefinition_type(definition):
assert definition.type in ('module', 'class', 'instance', 'function',
'generator', 'statement', 'import', 'param')
def test_function_call_signature_in_doc():
defs = Script("""
def f(x, y=1, z='a'):
pass
f""").goto_definitions()
doc = defs[0].doc
assert "f(x, y = 1, z = 'a')" in doc
def test_class_call_signature():
defs = Script("""
class Foo:
def __init__(self, x, y=1, z='a'):
pass
Foo""").goto_definitions()
doc = defs[0].doc
assert "Foo(self, x, y = 1, z = 'a')" in doc
def test_position_none_if_builtin():
gotos = Script('import sys; sys.path').goto_assignments()
assert gotos[0].line is None
assert gotos[0].column is None

View File

@@ -0,0 +1,137 @@
import textwrap
from ..helpers import TestCase
from jedi import Script
class TestCallSignatures(TestCase):
def _run(self, source, expected_name, expected_index=0, line=None, column=None):
signatures = Script(source, line, column).call_signatures()
assert len(signatures) <= 1
if not signatures:
assert expected_name is None
else:
assert signatures[0].call_name == expected_name
assert signatures[0].index == expected_index
def _run_simple(self, source, name, index=0, column=None, line=1):
self._run(source, name, index, line, column)
def test_simple(self):
run = self._run_simple
# simple
s1 = "abs(a, str("
run(s1, 'abs', 0, 4)
run(s1, 'abs', 1, 6)
run(s1, 'abs', 1, 7)
run(s1, 'abs', 1, 8)
run(s1, 'str', 0, 11)
s2 = "abs(), "
run(s2, 'abs', 0, 4)
run(s2, None, column=5)
run(s2, None)
s3 = "abs()."
run(s3, None, column=5)
run(s3, None)
# more complicated
s4 = 'abs(zip(), , set,'
run(s4, None, column=3)
run(s4, 'abs', 0, 4)
run(s4, 'zip', 0, 8)
run(s4, 'abs', 0, 9)
#run(s4, 'abs', 1, 10)
s5 = "abs(1,\nif 2:\n def a():"
run(s5, 'abs', 0, 4)
run(s5, 'abs', 1, 6)
s6 = "str().center("
run(s6, 'center', 0)
run(s6, 'str', 0, 4)
s7 = "str().upper().center("
s8 = "str(int[zip("
run(s7, 'center', 0)
run(s8, 'zip', 0)
run(s8, 'str', 0, 8)
run("import time; abc = time; abc.sleep(", 'sleep', 0)
# jedi #57
s = "def func(alpha, beta): pass\n" \
"func(alpha='101',"
run(s, 'func', 0, column=13, line=2)
def test_flows(self):
# jedi-vim #9
self._run_simple("with open(", 'open', 0)
# jedi-vim #11
self._run_simple("for sorted(", 'sorted', 0)
self._run_simple("for s in sorted(", 'sorted', 0)
def test_complex(self):
s = """
def abc(a,b):
pass
def a(self):
abc(
if 1:
pass
"""
self._run(s, 'abc', 0, line=6, column=24)
s = """
import re
def huhu(it):
re.compile(
return it * 2
"""
self._run(s, 'compile', 0, line=4, column=31)
# jedi-vim #70
s = """def foo("""
assert Script(s).call_signatures() == []
# jedi-vim #116
s = """import functools; test = getattr(functools, 'partial'); test("""
self._run(s, 'partial', 0)
def test_call_signature_on_module(self):
"""github issue #240"""
s = 'import datetime; datetime('
# just don't throw an exception (if numpy doesn't exist, just ignore it)
assert Script(s).call_signatures() == []
def test_call_signatures_empty_parentheses_pre_space(self):
s = textwrap.dedent("""\
def f(a, b):
pass
f( )""")
self._run(s, 'f', 0, line=3, column=3)
def test_multiple_signatures(self):
s = textwrap.dedent("""\
if x:
def f(a, b):
pass
else:
def f(a, b):
pass
f(""")
assert len(Script(s).call_signatures()) == 2
def test_call_signatures_whitespace(self):
s = textwrap.dedent("""\
abs(
def x():
pass
""")
self._run(s, 'abs', 0, line=1, column=5)

View File

@@ -0,0 +1,74 @@
"""
Tests for `api.defined_names`.
"""
import textwrap
from jedi import api
from ..helpers import TestCase
class TestDefinedNames(TestCase):
def assert_definition_names(self, definitions, names):
self.assertEqual([d.name for d in definitions], names)
def check_defined_names(self, source, names):
definitions = api.defined_names(textwrap.dedent(source))
self.assert_definition_names(definitions, names)
return definitions
def test_get_definitions_flat(self):
self.check_defined_names("""
import module
class Class:
pass
def func():
pass
data = None
""", ['module', 'Class', 'func', 'data'])
def test_dotted_assignment(self):
self.check_defined_names("""
x = Class()
x.y.z = None
""", ['x'])
def test_multiple_assignment(self):
self.check_defined_names("""
x = y = None
""", ['x', 'y'])
def test_multiple_imports(self):
self.check_defined_names("""
from module import a, b
from another_module import *
""", ['a', 'b'])
def test_nested_definitions(self):
definitions = self.check_defined_names("""
class Class:
def f():
pass
def g():
pass
""", ['Class'])
subdefinitions = definitions[0].defined_names()
self.assert_definition_names(subdefinitions, ['f', 'g'])
self.assertEqual([d.full_name for d in subdefinitions],
['Class.f', 'Class.g'])
def test_nested_class(self):
definitions = self.check_defined_names("""
class L1:
class L2:
class L3:
def f(): pass
def f(): pass
def f(): pass
def f(): pass
""", ['L1', 'f'])
subdefs = definitions[0].defined_names()
subsubdefs = subdefs[0].defined_names()
self.assert_definition_names(subdefs, ['L2', 'f'])
self.assert_definition_names(subsubdefs, ['L3', 'f'])
self.assert_definition_names(subsubdefs[0].defined_names(), ['f'])

View File

@@ -0,0 +1,87 @@
"""
Tests for :attr:`.BaseDefinition.full_name`.
There are three kinds of test:
#. Test classes derived from :class:`MixinTestFullName`.
Child class defines :attr:`.operation` to alter how
the api definition instance is created.
#. :class:`TestFullDefinedName` is to test combination of
``obj.full_name`` and ``jedi.defined_names``.
#. Misc single-function tests.
"""
import textwrap
import jedi
from jedi.api import classes
from jedi.evaluate import Evaluator
from ..helpers import TestCase
class MixinTestFullName(object):
operation = None
def check(self, source, desired):
script = jedi.Script(textwrap.dedent(source))
definitions = getattr(script, type(self).operation)()
self.assertEqual(definitions[0].full_name, desired)
def test_os_path_join(self):
self.check('import os; os.path.join', 'os.path.join')
def test_builtin(self):
self.check('type', 'type')
def test_from_import(self):
self.check('from os import path', 'os.path')
class TestFullNameWithGotoDefinitions(MixinTestFullName, TestCase):
operation = 'goto_definitions'
def test_tuple_mapping(self):
self.check("""
import re
any_re = re.compile('.*')
any_re""", 're.RegexObject')
class TestFullNameWithCompletions(MixinTestFullName, TestCase):
operation = 'completions'
class TestFullDefinedName(TestCase):
"""
Test combination of ``obj.full_name`` and ``jedi.defined_names``.
"""
def check(self, source, desired):
definitions = jedi.defined_names(textwrap.dedent(source))
full_names = [d.full_name for d in definitions]
self.assertEqual(full_names, desired)
def test_local_names(self):
self.check("""
def f(): pass
class C: pass
""", ['f', 'C'])
def test_imports(self):
self.check("""
import os
from os import path
from os.path import join
from os import path as opath
""", ['os', 'os.path', 'os.path.join', 'os.path'])
def test_keyword_full_name_should_be_none():
"""issue #94"""
# Using `from jedi.keywords import Keyword` here does NOT work
# in Python 3. This is due to the import hack jedi using.
Keyword = classes.keywords.Keyword
d = classes.Definition(Evaluator(), Keyword('(', (0, 0)))
assert d.full_name is None

View File

@@ -0,0 +1,44 @@
"""
Tests of ``jedi.api.Interpreter``.
"""
from ..helpers import TestCase
import jedi
from jedi._compatibility import is_py33
class TestInterpreterAPI(TestCase):
def check_interpreter_complete(self, source, namespace, completions,
**kwds):
script = jedi.Interpreter(source, [namespace], **kwds)
cs = script.completions()
actual = [c.name for c in cs]
self.assertEqual(sorted(actual), sorted(completions))
def test_complete_raw_function(self):
from os.path import join
self.check_interpreter_complete('join().up',
locals(),
['upper'])
def test_complete_raw_function_different_name(self):
from os.path import join as pjoin
self.check_interpreter_complete('pjoin().up',
locals(),
['upper'])
def test_complete_raw_module(self):
import os
self.check_interpreter_complete('os.path.join().up',
locals(),
['upper'])
def test_complete_raw_instance(self):
import datetime
dt = datetime.datetime(2013, 1, 1)
completions = ['time', 'timetz', 'timetuple']
if is_py33:
completions += ['timestamp']
self.check_interpreter_complete('(dt - dt).ti',
locals(),
completions)

View File

@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
"""
All character set and unicode related tests.
"""
from jedi import Script
from jedi._compatibility import utf8, unicode
def test_unicode_script():
""" normally no unicode objects are being used. (<=2.7) """
s = unicode("import datetime; datetime.timedelta")
completions = Script(s).completions()
assert len(completions)
assert type(completions[0].description) is unicode
s = utf8("author='öä'; author")
completions = Script(s).completions()
x = completions[0].description
assert type(x) is unicode
s = utf8("#-*- coding: iso-8859-1 -*-\nauthor='öä'; author")
s = s.encode('latin-1')
completions = Script(s).completions()
assert type(completions[0].description) is unicode
def test_unicode_attribute():
""" github jedi-vim issue #94 """
s1 = utf8('#-*- coding: utf-8 -*-\nclass Person():\n'
' name = "e"\n\nPerson().name.')
completions1 = Script(s1).completions()
assert 'strip' in [c.name for c in completions1]
s2 = utf8('#-*- coding: utf-8 -*-\nclass Person():\n'
' name = "é"\n\nPerson().name.')
completions2 = Script(s2).completions()
assert 'strip' in [c.name for c in completions2]
def test_multibyte_script():
""" `jedi.Script` must accept multi-byte string source. """
try:
code = unicode("import datetime; datetime.d")
comment = utf8("# multi-byte comment あいうえおä")
s = (unicode('%s\n%s') % (code, comment)).encode('utf-8')
except NameError:
pass # python 3 has no unicode method
else:
assert len(Script(s, 1, len(code)).completions())