mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 22:14:27 +08:00
Refactor test_interpreter.
This commit is contained in:
@@ -314,6 +314,20 @@ class CompiledContextName(ContextNameMixin, AbstractNameDefinition):
|
||||
self.parent_context = context.parent_context
|
||||
|
||||
|
||||
class EmptyCompiledName(AbstractNameDefinition):
|
||||
"""
|
||||
Accessing some names will raise an exception. To avoid not having any
|
||||
completions, just give Jedi the option to return this object. It infers to
|
||||
nothing.
|
||||
"""
|
||||
def __init__(self, evaluator, name):
|
||||
self.parent_context = evaluator.BUILTINS
|
||||
self.string_name = name
|
||||
|
||||
def infer(self):
|
||||
return []
|
||||
|
||||
|
||||
class CompiledObjectFilter(AbstractFilter):
|
||||
"""
|
||||
A names_dict instance for compiled objects, resembles the parser.tree.
|
||||
@@ -340,7 +354,7 @@ class CompiledObjectFilter(AbstractFilter):
|
||||
# This is a bit ugly. We're basically returning this to make
|
||||
# lookups possible without having the actual attribute. However
|
||||
# this makes proper completion possible.
|
||||
return [FakeName(name, create(self._evaluator, None), is_definition=True)]
|
||||
return [EmptyCompiledName(self._evaluator, name)]
|
||||
return [self._create_name(name)]
|
||||
|
||||
def values(self):
|
||||
|
||||
@@ -83,9 +83,9 @@ def _break_check(context, context_scope, flow_scope, node):
|
||||
break
|
||||
reachable = reachable.invert()
|
||||
else:
|
||||
node = flow_scope.node_in_which_check_node(node)
|
||||
if node is not None:
|
||||
reachable = _check_if(context, node)
|
||||
flow_node = flow_scope.node_in_which_check_node(node)
|
||||
if flow_node is not None:
|
||||
reachable = _check_if(context, flow_node)
|
||||
elif flow_scope.type in ('try_stmt', 'while_stmt'):
|
||||
return UNSURE
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import jedi
|
||||
from jedi._compatibility import is_py33
|
||||
from jedi.evaluate.compiled import mixed
|
||||
|
||||
|
||||
class _GlobalNameSpace():
|
||||
class SideEffectContainer():
|
||||
pass
|
||||
@@ -66,96 +67,104 @@ def test_side_effect_completion():
|
||||
assert foo.name == 'foo'
|
||||
|
||||
|
||||
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 _assert_interpreter_complete(source, namespace, completions,
|
||||
**kwds):
|
||||
script = jedi.Interpreter(source, [namespace], **kwds)
|
||||
cs = script.completions()
|
||||
actual = [c.name for c in cs]
|
||||
assert 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_function():
|
||||
from os.path import join
|
||||
_assert_interpreter_complete('join("").up',
|
||||
locals(),
|
||||
['upper'])
|
||||
|
||||
def test_complete_raw_module(self):
|
||||
import os
|
||||
self.check_interpreter_complete('os.path.join("a").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)
|
||||
def test_complete_raw_function_different_name():
|
||||
from os.path import join as pjoin
|
||||
_assert_interpreter_complete('pjoin("").up',
|
||||
locals(),
|
||||
['upper'])
|
||||
|
||||
def test_list(self):
|
||||
array = ['haha', 1]
|
||||
self.check_interpreter_complete('array[0].uppe',
|
||||
locals(),
|
||||
['upper'])
|
||||
self.check_interpreter_complete('array[0].real',
|
||||
locals(),
|
||||
[])
|
||||
|
||||
# something different, no index given, still just return the right
|
||||
self.check_interpreter_complete('array[int].real',
|
||||
locals(),
|
||||
['real'])
|
||||
self.check_interpreter_complete('array[int()].real',
|
||||
locals(),
|
||||
['real'])
|
||||
# inexistent index
|
||||
self.check_interpreter_complete('array[2].upper',
|
||||
locals(),
|
||||
['upper'])
|
||||
def test_complete_raw_module():
|
||||
import os
|
||||
_assert_interpreter_complete('os.path.join("a").up',
|
||||
locals(),
|
||||
['upper'])
|
||||
|
||||
def test_slice(self):
|
||||
class Foo():
|
||||
bar = []
|
||||
baz = 'xbarx'
|
||||
self.check_interpreter_complete('getattr(Foo, baz[1:-1]).append',
|
||||
locals(),
|
||||
['append'])
|
||||
|
||||
def test_getitem_side_effects(self):
|
||||
class Foo():
|
||||
def __getitem__(self, index):
|
||||
# possible side effects here, should therefore not call this.
|
||||
return index
|
||||
def test_complete_raw_instance():
|
||||
import datetime
|
||||
dt = datetime.datetime(2013, 1, 1)
|
||||
completions = ['time', 'timetz', 'timetuple']
|
||||
if is_py33:
|
||||
completions += ['timestamp']
|
||||
_assert_interpreter_complete('(dt - dt).ti',
|
||||
locals(),
|
||||
completions)
|
||||
|
||||
foo = Foo()
|
||||
self.check_interpreter_complete('foo[0].', locals(), [])
|
||||
|
||||
def test_property_error(self):
|
||||
class Foo():
|
||||
@property
|
||||
def bar(self):
|
||||
raise ValueError
|
||||
def test_list():
|
||||
array = ['haha', 1]
|
||||
_assert_interpreter_complete('array[0].uppe',
|
||||
locals(),
|
||||
['upper'])
|
||||
_assert_interpreter_complete('array[0].real',
|
||||
locals(),
|
||||
[])
|
||||
|
||||
foo = Foo()
|
||||
self.check_interpreter_complete('foo.bar', locals(), ['bar'])
|
||||
self.check_interpreter_complete('foo.bar.baz', locals(), [])
|
||||
# something different, no index given, still just return the right
|
||||
_assert_interpreter_complete('array[int].real',
|
||||
locals(),
|
||||
['real'])
|
||||
_assert_interpreter_complete('array[int()].real',
|
||||
locals(),
|
||||
['real'])
|
||||
# inexistent index
|
||||
_assert_interpreter_complete('array[2].upper',
|
||||
locals(),
|
||||
['upper'])
|
||||
|
||||
def test_param_completion(self):
|
||||
def foo(bar):
|
||||
pass
|
||||
|
||||
lambd = lambda xyz: 3
|
||||
def test_slice():
|
||||
class Foo():
|
||||
bar = []
|
||||
baz = 'xbarx'
|
||||
_assert_interpreter_complete('getattr(Foo, baz[1:-1]).append',
|
||||
locals(),
|
||||
['append'])
|
||||
|
||||
self.check_interpreter_complete('foo(bar', locals(), ['bar'])
|
||||
# TODO we're not yet using the Python3.5 inspect.signature, yet.
|
||||
assert not jedi.Interpreter('lambd(xyz', [locals()]).completions()
|
||||
|
||||
def test_getitem_side_effects():
|
||||
class Foo():
|
||||
def __getitem__(self, index):
|
||||
# possible side effects here, should therefore not call this.
|
||||
return index
|
||||
|
||||
foo = Foo()
|
||||
_assert_interpreter_complete('foo[0].', locals(), [])
|
||||
|
||||
|
||||
def test_property_error():
|
||||
class Foo():
|
||||
@property
|
||||
def bar(self):
|
||||
raise ValueError
|
||||
|
||||
foo = Foo()
|
||||
_assert_interpreter_complete('foo.bar', locals(), ['bar'])
|
||||
_assert_interpreter_complete('foo.bar.baz', locals(), [])
|
||||
|
||||
|
||||
def test_param_completion():
|
||||
def foo(bar):
|
||||
pass
|
||||
|
||||
lambd = lambda xyz: 3
|
||||
|
||||
_assert_interpreter_complete('foo(bar', locals(), ['bar'])
|
||||
# TODO we're not yet using the Python3.5 inspect.signature, yet.
|
||||
assert not jedi.Interpreter('lambd(xyz', [locals()]).completions()
|
||||
|
||||
Reference in New Issue
Block a user