forked from pyimgui/pyimgui
-
Notifications
You must be signed in to change notification settings - Fork 3
/
conftest.py
169 lines (135 loc) · 4.88 KB
/
conftest.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# -*- coding: utf-8 -*-
import os
import sys
from traceback import print_exc
import pytest
from inspect import currentframe, getframeinfo
from _pytest.outcomes import Skipped
from sphinx.application import Sphinx
from pathlib import Path
import inspect
PROJECT_ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
sphinx = None
if 'FROM_APPVEYOR' in os.environ:
# We need to trick the import mechanism in order to load the
# builded wheel instead of the local src directory
init_file_path = os.path.join(PROJECT_ROOT_DIR, 'imgui','__init__.py')
init_file_path_tmp = os.path.join(PROJECT_ROOT_DIR, 'imgui','__init__TMP.py')
os.rename(init_file_path, init_file_path_tmp)
import imgui
os.rename(init_file_path_tmp, init_file_path)
else:
import imgui
def project_path(*paths):
return os.path.join(PROJECT_ROOT_DIR, *paths)
def _ns(locals_, globals_):
ns = {}
ns.update(locals_)
ns.update(globals_)
return ns
class SphinxDoc(pytest.File):
@classmethod
def from_parent(cls, parent, *, fspath):
path = Path(fspath)
# yuck!
global sphinx
if sphinx is None:
os.environ['SPHINX_DISABLE_RENDER'] = '1'
sphinx = Sphinx(
srcdir=project_path('doc', 'source'),
confdir=project_path('doc', 'source'),
outdir=project_path('doc', 'build', 'vistest'),
doctreedir=project_path('doc', 'build', 'doctree'),
buildername='vistest',
)
# Check the signature of the from_parent method
# Note(Sam): This hack won't be needed once we drop p3.7 support
# it is required because Sphinx6 requires p3.8
sig = inspect.signature(super().from_parent)
if 'path' in sig.parameters:
# Sphinx version >= 6, use path
return super().from_parent(parent, path=path)
else:
# Sphinx version < 6, use fspath
return super().from_parent(parent, fspath=fspath)
def collect(self):
# build only specified file
sphinx.build(filenames=[self.fspath.relto(project_path())])
return [
DocItem.from_parent(self, name=name or "anonymous", code=code)
for (name, code) in sphinx.builder.snippets
]
class DocItem(pytest.Item):
@classmethod
def from_parent(cls, parent, *, name, code):
self = super().from_parent(parent, name=name)
self.code = code
return self
def runtest(self):
self.exec_snippet(self.code)
def exec_snippet(self, source):
# Strip out new_frame/end_frame from source
if "# later" in source:
raise Skipped(msg="multi-stage snippet, can't comprehend")
lines = [
line
if all([
"imgui.new_frame()" not in line,
"imgui.render()" not in line,
"imgui.end_frame()" not in line,
"fonts.get_tex_data_as_rgba32()" not in line,
]) else ""
for line in
source.split('\n')
]
source = "\n".join(lines)
if (
"import array" in source
and sys.version_info < (3, 0)
):
pytest.skip(
"array.array does not work properly under py27 as memory view"
)
code = compile(source, '<str>', 'exec')
frameinfo = getframeinfo(currentframe())
imgui.create_context()
io = imgui.get_io()
io.delta_time = 1.0 / 60.0
io.display_size = 300, 300
# setup default font
io.fonts.get_tex_data_as_rgba32()
io.fonts.add_font_default()
io.fonts.texture_id = 0 # set any texture ID to avoid segfaults
imgui.new_frame()
exec_ns = _ns(locals(), globals())
try:
exec(code, exec_ns, exec_ns)
except Exception as err:
# note: quick and dirty way to annotate sources with error marker
print_exc()
lines = source.split('\n')
lines.insert(sys.exc_info()[2].tb_next.tb_lineno, "^^^")
self.code = "\n".join(lines)
imgui.end_frame()
raise
imgui.render()
@staticmethod
def indent(text, width=4):
return "\n".join(
">" + " " * width + line
for line in text.split('\n')
)
def repr_failure(self, excinfo):
""" called when self.runtest() raises an exception. """
return "Visual example fail: {}\n\n{}\n\n{}".format(
excinfo,
self.indent(self.code),
excinfo.getrepr(funcargs=True, style='short')
)
def reportinfo(self):
return self.fspath, 0, "testcase: %s" % self.name
class ExecException(Exception):
pass
def pytest_collect_file(parent, path):
if path.ext == '.rst' and 'source' in path.dirname:
return SphinxDoc.from_parent(parent, fspath=path)