You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

205 lines
6.7 KiB

"""Tests for elpy.ropebackend."""
import os
import shutil
import sys
import tempfile
import mock
from elpy import ropebackend
from elpy import rpc
from elpy.tests import compat
from elpy.tests.support import BackendTestCase
from elpy.tests.support import RPCGetCompletionsTests
from elpy.tests.support import RPCGetCompletionDocstringTests
from elpy.tests.support import RPCGetCompletionLocationTests
from elpy.tests.support import RPCGetDefinitionTests
from elpy.tests.support import RPCGetCalltipTests
from elpy.tests.support import RPCGetDocstringTests
class RopeBackendTestCase(BackendTestCase):
def setUp(self):
super(RopeBackendTestCase, self).setUp()
self.backend = ropebackend.RopeBackend(self.project_root)
class ShouldCallValidateTest(object):
def test_should_call_validate(self):
with mock.patch.object(self.backend, 'validate') as validate:
self.rpc(None, "", 0)
self.assertTrue(validate.called)
class TestInit(RopeBackendTestCase):
def test_should_have_rope_as_name(self):
self.assertEqual(self.backend.name, "rope")
def test_should_patch_project_files(self):
self.project_file("foo.txt", "")
self.project_file("baddir/file.py", "")
self.backend.project.validate()
actual = [f.real_path for f in
self.backend.project.file_list.get_files()]
self.assertEqual([os.path.join(self.project_root, "foo.txt")],
actual)
def test_should_fail_for_inexisting_project_root(self):
with self.assertRaises(rpc.Fault):
ropebackend.RopeBackend("/does/not/exist/")
class TestValidate(RopeBackendTestCase):
def test_should_call_validate_after_timeout(self):
with mock.patch("time.time") as t:
t.return_value = 10
self.backend.validate()
with mock.patch.object(self.backend, 'project') as project:
t.return_value = 10 + ropebackend.VALIDATE_EVERY_SECONDS + 1
self.backend.validate()
self.assertTrue(project.validate.called)
def test_should_not_call_validate_before_timeout(self):
with mock.patch("time.time") as t:
t.return_value = 10
self.backend.validate()
with mock.patch.object(self.backend, 'project') as project:
t.return_value = 10 + ropebackend.VALIDATE_EVERY_SECONDS - 1
self.backend.validate()
self.assertFalse(project.validate.called)
def test_should_not_fail_if_root_vanishes(self):
# Bug #353
tmpdir = tempfile.mkdtemp(prefix="elpy-test-validate-")
try:
backend = ropebackend.RopeBackend(tmpdir)
finally:
shutil.rmtree(tmpdir)
backend.validate()
class TestRPCGetCompletions(RPCGetCompletionsTests,
RopeBackendTestCase):
pass
class TestRPCGetCompletionDocstring(RPCGetCompletionDocstringTests,
RopeBackendTestCase):
pass
class TestRPCGetCompletionLocation(RPCGetCompletionLocationTests,
RopeBackendTestCase):
pass
class TestRPCGetDefinition(RPCGetDefinitionTests,
ShouldCallValidateTest,
RopeBackendTestCase):
pass
class TestRPCGetCalltip(RPCGetCalltipTests,
ShouldCallValidateTest,
RopeBackendTestCase):
ADD_CALLTIP = 'Add.add(a, b)'
RADIX_CALLTIP = "Decimal.radix()"
if compat.PYTHON3:
THREAD_CALLTIP = (
"threading.Thread(group=None, target=None, "
"name=None, args=(), kwargs=None, daemon=None, *)"
)
KEYS_CALLTIP = "builtins.keys()"
else:
THREAD_CALLTIP = (
"threading.Thread(group=None, target=None, "
"name=None, args=(), kwargs=None, verbose=None)"
)
KEYS_CALLTIP = "__builtin__.keys()"
class TestRPCGetDocstring(RPCGetDocstringTests,
ShouldCallValidateTest,
RopeBackendTestCase):
if sys.version_info < (2, 7):
JSON_LOADS_DOCSTRING = (
'loads(s, encoding=None, cls=None, object_hook=None, '
'parse_float=None, parse_int=None, parse_constant=None, '
'**kw):'
)
else:
JSON_LOADS_DOCSTRING = (
'loads(s, encoding=None, cls=None, object_hook=None, '
'parse_float=None, parse_int=None, parse_constant=None, '
'object_pairs_hook=None, **kw):'
)
class TestGetPythonProjectFiles(RopeBackendTestCase):
def test(self):
self.project_file("foo.txt", "")
self.project_file("gooddir/__init__.py", "")
self.project_file("gooddir/file.py", "")
self.project_file("baddir/file.py", "")
expected = set(os.path.join(self.project_root, name)
for name in ["foo.txt", "gooddir/__init__.py",
"gooddir/file.py"])
project = self.backend.project
actual = set(resource.real_path
for resource
in ropebackend.get_python_project_files(project))
self.assertEqual(expected, actual)
class TestPatchProjectFiles(RopeBackendTestCase):
def test(self):
self.project_file("foo.txt", "")
self.project_file("gooddir/__init__.py", "")
self.project_file("gooddir/file.py", "")
self.project_file("baddir/file.py", "")
expected = set(os.path.join(self.project_root, name)
for name in ["foo.txt", "gooddir/__init__.py",
"gooddir/file.py"])
actual = set(resource.real_path
for resource
in self.backend.project.get_files())
self.assertEqual(expected, actual)
class TestCallRope(RopeBackendTestCase):
def test_should_return_value(self):
func = mock.MagicMock()
func.return_value = 23
actual = self.backend.call_rope(
func, "foo.py", "", 0
)
self.assertEqual(23, actual)
def test_should_raise_fault_with_data_on_exception(self):
func = mock.MagicMock()
func.side_effect = RuntimeError("Stuff!")
func.__module__ = "rope.test"
func.__name__ = "test_function"
try:
self.backend.call_rope(
func, "foo.py", "", 0
)
except rpc.Fault as e:
self.assertEqual(500, e.code)
self.assertEqual("Stuff!", e.message)
self.assertIn("traceback", e.data)
self.assertIn("rope_debug_info", e.data)
self.assertEqual("rope.test.test_function",
e.data["rope_debug_info"]["function_name"])