/
testutils.py
117 lines (90 loc) · 3.32 KB
/
testutils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import os.path
import shutil
import sys
import logging
logging.basicConfig(format="%(levelname)s:%(funcName)s:%(message)s", level=logging.INFO)
import unittest
import rope.base.project
from rope.contrib import generate
def sample_project(root=None, foldername=None, **kwds):
if root is None:
root = "sample_project"
if foldername:
root = foldername
# HACK: Using ``/dev/shm/`` for faster tests
if os.name == "posix":
if os.path.isdir("/dev/shm") and os.access("/dev/shm", os.W_OK):
root = "/dev/shm/" + root
elif os.path.isdir("/tmp") and os.access("/tmp", os.W_OK):
root = "/tmp/" + root
logging.debug("Using %s as root of the project.", root)
# Using these prefs for faster tests
prefs = {
"save_objectdb": False,
"save_history": False,
"validate_objectdb": False,
"automatic_soa": False,
"ignored_resources": [".ropeproject", "*.pyc"],
"import_dynload_stdmods": False,
}
prefs.update(kwds)
remove_recursively(root)
project = rope.base.project.Project(root, **prefs)
return project
create_module = generate.create_module
create_package = generate.create_package
def remove_project(project):
project.close()
remove_recursively(project.address)
def remove_recursively(path):
import time
# windows sometimes raises exceptions instead of removing files
if os.name == "nt" or sys.platform == "cygwin":
for i in range(12):
try:
_remove_recursively(path)
except OSError as e:
if e.errno not in (13, 16, 32):
raise
time.sleep(0.3)
else:
break
else:
_remove_recursively(path)
def _remove_recursively(path):
if not os.path.exists(path):
return
if os.path.isfile(path):
os.remove(path)
else:
shutil.rmtree(path)
def parse_version(version):
return tuple(map(int, version.split(".")))
def only_for(version):
"""Should be used as a decorator for a unittest.TestCase test method"""
return unittest.skipIf(
sys.version_info < parse_version(version),
f"This test requires at least {version} version of Python.",
)
def only_for_versions_lower(version):
"""Should be used as a decorator for a unittest.TestCase test method"""
return unittest.skipIf(
sys.version_info > parse_version(version),
f"This test requires version of Python lower than {version}",
)
def only_for_versions_higher(version):
"""Should be used as a decorator for a unittest.TestCase test method"""
return unittest.skipIf(
sys.version_info < parse_version(version),
f"This test requires version of Python higher than {version}",
)
def skipNotPOSIX():
return unittest.skipIf(os.name != "posix", "This test works only on POSIX")
def time_limit(timeout):
if not any(procname in sys.argv[0] for procname in {"pytest", "py.test"}):
# no-op when running tests without pytest
return lambda *args, **kwargs: lambda func: func
# do a local import so we don't import pytest when running without pytest
import pytest
# this prevents infinite loop/recursion from taking forever in CI
return pytest.mark.time_limit(timeout)