mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Update web-platform-tests and CSS tests.
- Update CSS tests to revision e05bfd5e30ed662c2f8a353577003f8eed230180. - Update web-platform-tests to revision a052787dd5c069a340031011196b73affbd68cd9.
This commit is contained in:
parent
fb4f421c8b
commit
296fa2512b
21852 changed files with 2080936 additions and 892894 deletions
174
tests/wpt/css-tests/tools/pytest/testing/code/test_code.py
Normal file
174
tests/wpt/css-tests/tools/pytest/testing/code/test_code.py
Normal file
|
@ -0,0 +1,174 @@
|
|||
import sys
|
||||
|
||||
import _pytest._code
|
||||
import py
|
||||
import pytest
|
||||
|
||||
|
||||
def test_ne():
|
||||
code1 = _pytest._code.Code(compile('foo = "bar"', '', 'exec'))
|
||||
assert code1 == code1
|
||||
code2 = _pytest._code.Code(compile('foo = "baz"', '', 'exec'))
|
||||
assert code2 != code1
|
||||
|
||||
def test_code_gives_back_name_for_not_existing_file():
|
||||
name = 'abc-123'
|
||||
co_code = compile("pass\n", name, 'exec')
|
||||
assert co_code.co_filename == name
|
||||
code = _pytest._code.Code(co_code)
|
||||
assert str(code.path) == name
|
||||
assert code.fullsource is None
|
||||
|
||||
def test_code_with_class():
|
||||
class A:
|
||||
pass
|
||||
pytest.raises(TypeError, "_pytest._code.Code(A)")
|
||||
|
||||
if True:
|
||||
def x():
|
||||
pass
|
||||
|
||||
def test_code_fullsource():
|
||||
code = _pytest._code.Code(x)
|
||||
full = code.fullsource
|
||||
assert 'test_code_fullsource()' in str(full)
|
||||
|
||||
def test_code_source():
|
||||
code = _pytest._code.Code(x)
|
||||
src = code.source()
|
||||
expected = """def x():
|
||||
pass"""
|
||||
assert str(src) == expected
|
||||
|
||||
def test_frame_getsourcelineno_myself():
|
||||
def func():
|
||||
return sys._getframe(0)
|
||||
f = func()
|
||||
f = _pytest._code.Frame(f)
|
||||
source, lineno = f.code.fullsource, f.lineno
|
||||
assert source[lineno].startswith(" return sys._getframe(0)")
|
||||
|
||||
def test_getstatement_empty_fullsource():
|
||||
def func():
|
||||
return sys._getframe(0)
|
||||
f = func()
|
||||
f = _pytest._code.Frame(f)
|
||||
prop = f.code.__class__.fullsource
|
||||
try:
|
||||
f.code.__class__.fullsource = None
|
||||
assert f.statement == _pytest._code.Source("")
|
||||
finally:
|
||||
f.code.__class__.fullsource = prop
|
||||
|
||||
def test_code_from_func():
|
||||
co = _pytest._code.Code(test_frame_getsourcelineno_myself)
|
||||
assert co.firstlineno
|
||||
assert co.path
|
||||
|
||||
|
||||
|
||||
def test_builtin_patch_unpatch(monkeypatch):
|
||||
cpy_builtin = py.builtin.builtins
|
||||
comp = cpy_builtin.compile
|
||||
def mycompile(*args, **kwargs):
|
||||
return comp(*args, **kwargs)
|
||||
class Sub(AssertionError):
|
||||
pass
|
||||
monkeypatch.setattr(cpy_builtin, 'AssertionError', Sub)
|
||||
monkeypatch.setattr(cpy_builtin, 'compile', mycompile)
|
||||
_pytest._code.patch_builtins()
|
||||
assert cpy_builtin.AssertionError != Sub
|
||||
assert cpy_builtin.compile != mycompile
|
||||
_pytest._code.unpatch_builtins()
|
||||
assert cpy_builtin.AssertionError is Sub
|
||||
assert cpy_builtin.compile == mycompile
|
||||
|
||||
|
||||
def test_unicode_handling():
|
||||
value = py.builtin._totext('\xc4\x85\xc4\x87\n', 'utf-8').encode('utf8')
|
||||
def f():
|
||||
raise Exception(value)
|
||||
excinfo = pytest.raises(Exception, f)
|
||||
str(excinfo)
|
||||
if sys.version_info[0] < 3:
|
||||
unicode(excinfo)
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info[0] >= 3, reason='python 2 only issue')
|
||||
def test_unicode_handling_syntax_error():
|
||||
value = py.builtin._totext('\xc4\x85\xc4\x87\n', 'utf-8').encode('utf8')
|
||||
def f():
|
||||
raise SyntaxError('invalid syntax', (None, 1, 3, value))
|
||||
excinfo = pytest.raises(Exception, f)
|
||||
str(excinfo)
|
||||
if sys.version_info[0] < 3:
|
||||
unicode(excinfo)
|
||||
|
||||
def test_code_getargs():
|
||||
def f1(x):
|
||||
pass
|
||||
c1 = _pytest._code.Code(f1)
|
||||
assert c1.getargs(var=True) == ('x',)
|
||||
|
||||
def f2(x, *y):
|
||||
pass
|
||||
c2 = _pytest._code.Code(f2)
|
||||
assert c2.getargs(var=True) == ('x', 'y')
|
||||
|
||||
def f3(x, **z):
|
||||
pass
|
||||
c3 = _pytest._code.Code(f3)
|
||||
assert c3.getargs(var=True) == ('x', 'z')
|
||||
|
||||
def f4(x, *y, **z):
|
||||
pass
|
||||
c4 = _pytest._code.Code(f4)
|
||||
assert c4.getargs(var=True) == ('x', 'y', 'z')
|
||||
|
||||
|
||||
def test_frame_getargs():
|
||||
def f1(x):
|
||||
return sys._getframe(0)
|
||||
fr1 = _pytest._code.Frame(f1('a'))
|
||||
assert fr1.getargs(var=True) == [('x', 'a')]
|
||||
|
||||
def f2(x, *y):
|
||||
return sys._getframe(0)
|
||||
fr2 = _pytest._code.Frame(f2('a', 'b', 'c'))
|
||||
assert fr2.getargs(var=True) == [('x', 'a'), ('y', ('b', 'c'))]
|
||||
|
||||
def f3(x, **z):
|
||||
return sys._getframe(0)
|
||||
fr3 = _pytest._code.Frame(f3('a', b='c'))
|
||||
assert fr3.getargs(var=True) == [('x', 'a'), ('z', {'b': 'c'})]
|
||||
|
||||
def f4(x, *y, **z):
|
||||
return sys._getframe(0)
|
||||
fr4 = _pytest._code.Frame(f4('a', 'b', c='d'))
|
||||
assert fr4.getargs(var=True) == [('x', 'a'), ('y', ('b',)),
|
||||
('z', {'c': 'd'})]
|
||||
|
||||
|
||||
class TestExceptionInfo:
|
||||
|
||||
def test_bad_getsource(self):
|
||||
try:
|
||||
if False: pass
|
||||
else: assert False
|
||||
except AssertionError:
|
||||
exci = _pytest._code.ExceptionInfo()
|
||||
assert exci.getrepr()
|
||||
|
||||
|
||||
class TestTracebackEntry:
|
||||
|
||||
def test_getsource(self):
|
||||
try:
|
||||
if False: pass
|
||||
else: assert False
|
||||
except AssertionError:
|
||||
exci = _pytest._code.ExceptionInfo()
|
||||
entry = exci.traceback[0]
|
||||
source = entry.getsource()
|
||||
assert len(source) == 4
|
||||
assert 'else: assert False' in source[3]
|
911
tests/wpt/css-tests/tools/pytest/testing/code/test_excinfo.py
Normal file
911
tests/wpt/css-tests/tools/pytest/testing/code/test_excinfo.py
Normal file
|
@ -0,0 +1,911 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import _pytest
|
||||
import py
|
||||
import pytest
|
||||
from _pytest._code.code import FormattedExcinfo, ReprExceptionInfo
|
||||
|
||||
queue = py.builtin._tryimport('queue', 'Queue')
|
||||
|
||||
failsonjython = pytest.mark.xfail("sys.platform.startswith('java')")
|
||||
from test_source import astonly
|
||||
|
||||
try:
|
||||
import importlib
|
||||
except ImportError:
|
||||
invalidate_import_caches = None
|
||||
else:
|
||||
invalidate_import_caches = getattr(importlib, "invalidate_caches", None)
|
||||
|
||||
import pytest
|
||||
pytest_version_info = tuple(map(int, pytest.__version__.split(".")[:3]))
|
||||
|
||||
class TWMock:
|
||||
def __init__(self):
|
||||
self.lines = []
|
||||
def sep(self, sep, line=None):
|
||||
self.lines.append((sep, line))
|
||||
def line(self, line, **kw):
|
||||
self.lines.append(line)
|
||||
def markup(self, text, **kw):
|
||||
return text
|
||||
|
||||
fullwidth = 80
|
||||
|
||||
def test_excinfo_simple():
|
||||
try:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
info = _pytest._code.ExceptionInfo()
|
||||
assert info.type == ValueError
|
||||
|
||||
def test_excinfo_getstatement():
|
||||
def g():
|
||||
raise ValueError
|
||||
def f():
|
||||
g()
|
||||
try:
|
||||
f()
|
||||
except ValueError:
|
||||
excinfo = _pytest._code.ExceptionInfo()
|
||||
linenumbers = [_pytest._code.getrawcode(f).co_firstlineno - 1 + 3,
|
||||
_pytest._code.getrawcode(f).co_firstlineno - 1 + 1,
|
||||
_pytest._code.getrawcode(g).co_firstlineno - 1 + 1, ]
|
||||
l = list(excinfo.traceback)
|
||||
foundlinenumbers = [x.lineno for x in l]
|
||||
assert foundlinenumbers == linenumbers
|
||||
#for x in info:
|
||||
# print "%s:%d %s" %(x.path.relto(root), x.lineno, x.statement)
|
||||
#xxx
|
||||
|
||||
# testchain for getentries test below
|
||||
def f():
|
||||
#
|
||||
raise ValueError
|
||||
#
|
||||
def g():
|
||||
#
|
||||
__tracebackhide__ = True
|
||||
f()
|
||||
#
|
||||
def h():
|
||||
#
|
||||
g()
|
||||
#
|
||||
|
||||
class TestTraceback_f_g_h:
|
||||
def setup_method(self, method):
|
||||
try:
|
||||
h()
|
||||
except ValueError:
|
||||
self.excinfo = _pytest._code.ExceptionInfo()
|
||||
|
||||
def test_traceback_entries(self):
|
||||
tb = self.excinfo.traceback
|
||||
entries = list(tb)
|
||||
assert len(tb) == 4 # maybe fragile test
|
||||
assert len(entries) == 4 # maybe fragile test
|
||||
names = ['f', 'g', 'h']
|
||||
for entry in entries:
|
||||
try:
|
||||
names.remove(entry.frame.code.name)
|
||||
except ValueError:
|
||||
pass
|
||||
assert not names
|
||||
|
||||
def test_traceback_entry_getsource(self):
|
||||
tb = self.excinfo.traceback
|
||||
s = str(tb[-1].getsource() )
|
||||
assert s.startswith("def f():")
|
||||
assert s.endswith("raise ValueError")
|
||||
|
||||
@astonly
|
||||
@failsonjython
|
||||
def test_traceback_entry_getsource_in_construct(self):
|
||||
source = _pytest._code.Source("""\
|
||||
def xyz():
|
||||
try:
|
||||
raise ValueError
|
||||
except somenoname:
|
||||
pass
|
||||
xyz()
|
||||
""")
|
||||
try:
|
||||
exec (source.compile())
|
||||
except NameError:
|
||||
tb = _pytest._code.ExceptionInfo().traceback
|
||||
print (tb[-1].getsource())
|
||||
s = str(tb[-1].getsource())
|
||||
assert s.startswith("def xyz():\n try:")
|
||||
assert s.strip().endswith("except somenoname:")
|
||||
|
||||
def test_traceback_cut(self):
|
||||
co = _pytest._code.Code(f)
|
||||
path, firstlineno = co.path, co.firstlineno
|
||||
traceback = self.excinfo.traceback
|
||||
newtraceback = traceback.cut(path=path, firstlineno=firstlineno)
|
||||
assert len(newtraceback) == 1
|
||||
newtraceback = traceback.cut(path=path, lineno=firstlineno+2)
|
||||
assert len(newtraceback) == 1
|
||||
|
||||
def test_traceback_cut_excludepath(self, testdir):
|
||||
p = testdir.makepyfile("def f(): raise ValueError")
|
||||
excinfo = pytest.raises(ValueError, "p.pyimport().f()")
|
||||
basedir = py.path.local(pytest.__file__).dirpath()
|
||||
newtraceback = excinfo.traceback.cut(excludepath=basedir)
|
||||
for x in newtraceback:
|
||||
if hasattr(x, 'path'):
|
||||
assert not py.path.local(x.path).relto(basedir)
|
||||
assert newtraceback[-1].frame.code.path == p
|
||||
|
||||
def test_traceback_filter(self):
|
||||
traceback = self.excinfo.traceback
|
||||
ntraceback = traceback.filter()
|
||||
assert len(ntraceback) == len(traceback) - 1
|
||||
|
||||
def test_traceback_recursion_index(self):
|
||||
def f(n):
|
||||
if n < 10:
|
||||
n += 1
|
||||
f(n)
|
||||
excinfo = pytest.raises(RuntimeError, f, 8)
|
||||
traceback = excinfo.traceback
|
||||
recindex = traceback.recursionindex()
|
||||
assert recindex == 3
|
||||
|
||||
def test_traceback_only_specific_recursion_errors(self, monkeypatch):
|
||||
def f(n):
|
||||
if n == 0:
|
||||
raise RuntimeError("hello")
|
||||
f(n-1)
|
||||
|
||||
excinfo = pytest.raises(RuntimeError, f, 100)
|
||||
monkeypatch.delattr(excinfo.traceback.__class__, "recursionindex")
|
||||
repr = excinfo.getrepr()
|
||||
assert "RuntimeError: hello" in str(repr.reprcrash)
|
||||
|
||||
def test_traceback_no_recursion_index(self):
|
||||
def do_stuff():
|
||||
raise RuntimeError
|
||||
def reraise_me():
|
||||
import sys
|
||||
exc, val, tb = sys.exc_info()
|
||||
py.builtin._reraise(exc, val, tb)
|
||||
def f(n):
|
||||
try:
|
||||
do_stuff()
|
||||
except:
|
||||
reraise_me()
|
||||
excinfo = pytest.raises(RuntimeError, f, 8)
|
||||
traceback = excinfo.traceback
|
||||
recindex = traceback.recursionindex()
|
||||
assert recindex is None
|
||||
|
||||
def test_traceback_messy_recursion(self):
|
||||
#XXX: simplified locally testable version
|
||||
decorator = pytest.importorskip('decorator').decorator
|
||||
|
||||
def log(f, *k, **kw):
|
||||
print('%s %s' % (k, kw))
|
||||
f(*k, **kw)
|
||||
log = decorator(log)
|
||||
|
||||
def fail():
|
||||
raise ValueError('')
|
||||
|
||||
fail = log(log(fail))
|
||||
|
||||
excinfo = pytest.raises(ValueError, fail)
|
||||
assert excinfo.traceback.recursionindex() is None
|
||||
|
||||
|
||||
|
||||
def test_traceback_getcrashentry(self):
|
||||
def i():
|
||||
__tracebackhide__ = True
|
||||
raise ValueError
|
||||
def h():
|
||||
i()
|
||||
def g():
|
||||
__tracebackhide__ = True
|
||||
h()
|
||||
def f():
|
||||
g()
|
||||
|
||||
excinfo = pytest.raises(ValueError, f)
|
||||
tb = excinfo.traceback
|
||||
entry = tb.getcrashentry()
|
||||
co = _pytest._code.Code(h)
|
||||
assert entry.frame.code.path == co.path
|
||||
assert entry.lineno == co.firstlineno + 1
|
||||
assert entry.frame.code.name == 'h'
|
||||
|
||||
def test_traceback_getcrashentry_empty(self):
|
||||
def g():
|
||||
__tracebackhide__ = True
|
||||
raise ValueError
|
||||
def f():
|
||||
__tracebackhide__ = True
|
||||
g()
|
||||
|
||||
excinfo = pytest.raises(ValueError, f)
|
||||
tb = excinfo.traceback
|
||||
entry = tb.getcrashentry()
|
||||
co = _pytest._code.Code(g)
|
||||
assert entry.frame.code.path == co.path
|
||||
assert entry.lineno == co.firstlineno + 2
|
||||
assert entry.frame.code.name == 'g'
|
||||
|
||||
def hello(x):
|
||||
x + 5
|
||||
|
||||
def test_tbentry_reinterpret():
|
||||
try:
|
||||
hello("hello")
|
||||
except TypeError:
|
||||
excinfo = _pytest._code.ExceptionInfo()
|
||||
tbentry = excinfo.traceback[-1]
|
||||
msg = tbentry.reinterpret()
|
||||
assert msg.startswith("TypeError: ('hello' + 5)")
|
||||
|
||||
def test_excinfo_exconly():
|
||||
excinfo = pytest.raises(ValueError, h)
|
||||
assert excinfo.exconly().startswith('ValueError')
|
||||
excinfo = pytest.raises(ValueError,
|
||||
"raise ValueError('hello\\nworld')")
|
||||
msg = excinfo.exconly(tryshort=True)
|
||||
assert msg.startswith('ValueError')
|
||||
assert msg.endswith("world")
|
||||
|
||||
def test_excinfo_repr():
|
||||
excinfo = pytest.raises(ValueError, h)
|
||||
s = repr(excinfo)
|
||||
assert s == "<ExceptionInfo ValueError tblen=4>"
|
||||
|
||||
def test_excinfo_str():
|
||||
excinfo = pytest.raises(ValueError, h)
|
||||
s = str(excinfo)
|
||||
assert s.startswith(__file__[:-9]) # pyc file and $py.class
|
||||
assert s.endswith("ValueError")
|
||||
assert len(s.split(":")) >= 3 # on windows it's 4
|
||||
|
||||
def test_excinfo_errisinstance():
|
||||
excinfo = pytest.raises(ValueError, h)
|
||||
assert excinfo.errisinstance(ValueError)
|
||||
|
||||
def test_excinfo_no_sourcecode():
|
||||
try:
|
||||
exec ("raise ValueError()")
|
||||
except ValueError:
|
||||
excinfo = _pytest._code.ExceptionInfo()
|
||||
s = str(excinfo.traceback[-1])
|
||||
if py.std.sys.version_info < (2,5):
|
||||
assert s == " File '<string>':1 in ?\n ???\n"
|
||||
else:
|
||||
assert s == " File '<string>':1 in <module>\n ???\n"
|
||||
|
||||
def test_excinfo_no_python_sourcecode(tmpdir):
|
||||
#XXX: simplified locally testable version
|
||||
tmpdir.join('test.txt').write("{{ h()}}:")
|
||||
|
||||
jinja2 = pytest.importorskip('jinja2')
|
||||
loader = jinja2.FileSystemLoader(str(tmpdir))
|
||||
env = jinja2.Environment(loader=loader)
|
||||
template = env.get_template('test.txt')
|
||||
excinfo = pytest.raises(ValueError,
|
||||
template.render, h=h)
|
||||
for item in excinfo.traceback:
|
||||
print(item) #XXX: for some reason jinja.Template.render is printed in full
|
||||
item.source # shouldnt fail
|
||||
if item.path.basename == 'test.txt':
|
||||
assert str(item.source) == '{{ h()}}:'
|
||||
|
||||
|
||||
def test_entrysource_Queue_example():
|
||||
try:
|
||||
queue.Queue().get(timeout=0.001)
|
||||
except queue.Empty:
|
||||
excinfo = _pytest._code.ExceptionInfo()
|
||||
entry = excinfo.traceback[-1]
|
||||
source = entry.getsource()
|
||||
assert source is not None
|
||||
s = str(source).strip()
|
||||
assert s.startswith("def get")
|
||||
|
||||
def test_codepath_Queue_example():
|
||||
try:
|
||||
queue.Queue().get(timeout=0.001)
|
||||
except queue.Empty:
|
||||
excinfo = _pytest._code.ExceptionInfo()
|
||||
entry = excinfo.traceback[-1]
|
||||
path = entry.path
|
||||
assert isinstance(path, py.path.local)
|
||||
assert path.basename.lower() == "queue.py"
|
||||
assert path.check()
|
||||
|
||||
class TestFormattedExcinfo:
|
||||
def pytest_funcarg__importasmod(self, request):
|
||||
def importasmod(source):
|
||||
source = _pytest._code.Source(source)
|
||||
tmpdir = request.getfuncargvalue("tmpdir")
|
||||
modpath = tmpdir.join("mod.py")
|
||||
tmpdir.ensure("__init__.py")
|
||||
modpath.write(source)
|
||||
if invalidate_import_caches is not None:
|
||||
invalidate_import_caches()
|
||||
return modpath.pyimport()
|
||||
return importasmod
|
||||
|
||||
def excinfo_from_exec(self, source):
|
||||
source = _pytest._code.Source(source).strip()
|
||||
try:
|
||||
exec (source.compile())
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
return _pytest._code.ExceptionInfo()
|
||||
assert 0, "did not raise"
|
||||
|
||||
def test_repr_source(self):
|
||||
pr = FormattedExcinfo()
|
||||
source = _pytest._code.Source("""
|
||||
def f(x):
|
||||
pass
|
||||
""").strip()
|
||||
pr.flow_marker = "|"
|
||||
lines = pr.get_source(source, 0)
|
||||
assert len(lines) == 2
|
||||
assert lines[0] == "| def f(x):"
|
||||
assert lines[1] == " pass"
|
||||
|
||||
def test_repr_source_excinfo(self):
|
||||
""" check if indentation is right """
|
||||
pr = FormattedExcinfo()
|
||||
excinfo = self.excinfo_from_exec("""
|
||||
def f():
|
||||
assert 0
|
||||
f()
|
||||
""")
|
||||
pr = FormattedExcinfo()
|
||||
source = pr._getentrysource(excinfo.traceback[-1])
|
||||
lines = pr.get_source(source, 1, excinfo)
|
||||
assert lines == [
|
||||
' def f():',
|
||||
'> assert 0',
|
||||
'E assert 0'
|
||||
]
|
||||
|
||||
|
||||
def test_repr_source_not_existing(self):
|
||||
pr = FormattedExcinfo()
|
||||
co = compile("raise ValueError()", "", "exec")
|
||||
try:
|
||||
exec (co)
|
||||
except ValueError:
|
||||
excinfo = _pytest._code.ExceptionInfo()
|
||||
repr = pr.repr_excinfo(excinfo)
|
||||
assert repr.reprtraceback.reprentries[1].lines[0] == "> ???"
|
||||
|
||||
def test_repr_many_line_source_not_existing(self):
|
||||
pr = FormattedExcinfo()
|
||||
co = compile("""
|
||||
a = 1
|
||||
raise ValueError()
|
||||
""", "", "exec")
|
||||
try:
|
||||
exec (co)
|
||||
except ValueError:
|
||||
excinfo = _pytest._code.ExceptionInfo()
|
||||
repr = pr.repr_excinfo(excinfo)
|
||||
assert repr.reprtraceback.reprentries[1].lines[0] == "> ???"
|
||||
|
||||
def test_repr_source_failing_fullsource(self):
|
||||
pr = FormattedExcinfo()
|
||||
|
||||
class FakeCode(object):
|
||||
class raw:
|
||||
co_filename = '?'
|
||||
path = '?'
|
||||
firstlineno = 5
|
||||
|
||||
def fullsource(self):
|
||||
return None
|
||||
fullsource = property(fullsource)
|
||||
|
||||
class FakeFrame(object):
|
||||
code = FakeCode()
|
||||
f_locals = {}
|
||||
f_globals = {}
|
||||
|
||||
class FakeTracebackEntry(_pytest._code.Traceback.Entry):
|
||||
def __init__(self, tb):
|
||||
self.lineno = 5+3
|
||||
|
||||
@property
|
||||
def frame(self):
|
||||
return FakeFrame()
|
||||
|
||||
class Traceback(_pytest._code.Traceback):
|
||||
Entry = FakeTracebackEntry
|
||||
|
||||
class FakeExcinfo(_pytest._code.ExceptionInfo):
|
||||
typename = "Foo"
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def exconly(self, tryshort):
|
||||
return "EXC"
|
||||
def errisinstance(self, cls):
|
||||
return False
|
||||
|
||||
excinfo = FakeExcinfo()
|
||||
class FakeRawTB(object):
|
||||
tb_next = None
|
||||
tb = FakeRawTB()
|
||||
excinfo.traceback = Traceback(tb)
|
||||
|
||||
fail = IOError() # noqa
|
||||
repr = pr.repr_excinfo(excinfo)
|
||||
assert repr.reprtraceback.reprentries[0].lines[0] == "> ???"
|
||||
|
||||
fail = py.error.ENOENT # noqa
|
||||
repr = pr.repr_excinfo(excinfo)
|
||||
assert repr.reprtraceback.reprentries[0].lines[0] == "> ???"
|
||||
|
||||
|
||||
def test_repr_local(self):
|
||||
p = FormattedExcinfo(showlocals=True)
|
||||
loc = {'y': 5, 'z': 7, 'x': 3, '@x': 2, '__builtins__': {}}
|
||||
reprlocals = p.repr_locals(loc)
|
||||
assert reprlocals.lines
|
||||
assert reprlocals.lines[0] == '__builtins__ = <builtins>'
|
||||
assert reprlocals.lines[1] == 'x = 3'
|
||||
assert reprlocals.lines[2] == 'y = 5'
|
||||
assert reprlocals.lines[3] == 'z = 7'
|
||||
|
||||
def test_repr_tracebackentry_lines(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def func1():
|
||||
raise ValueError("hello\\nworld")
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.func1)
|
||||
excinfo.traceback = excinfo.traceback.filter()
|
||||
p = FormattedExcinfo()
|
||||
reprtb = p.repr_traceback_entry(excinfo.traceback[-1])
|
||||
|
||||
# test as intermittent entry
|
||||
lines = reprtb.lines
|
||||
assert lines[0] == ' def func1():'
|
||||
assert lines[1] == '> raise ValueError("hello\\nworld")'
|
||||
|
||||
# test as last entry
|
||||
p = FormattedExcinfo(showlocals=True)
|
||||
repr_entry = p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
|
||||
lines = repr_entry.lines
|
||||
assert lines[0] == ' def func1():'
|
||||
assert lines[1] == '> raise ValueError("hello\\nworld")'
|
||||
assert lines[2] == 'E ValueError: hello'
|
||||
assert lines[3] == 'E world'
|
||||
assert not lines[4:]
|
||||
|
||||
loc = repr_entry.reprlocals is not None
|
||||
loc = repr_entry.reprfileloc
|
||||
assert loc.path == mod.__file__
|
||||
assert loc.lineno == 3
|
||||
#assert loc.message == "ValueError: hello"
|
||||
|
||||
def test_repr_tracebackentry_lines2(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def func1(m, x, y, z):
|
||||
raise ValueError("hello\\nworld")
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.func1, "m"*90, 5, 13, "z"*120)
|
||||
excinfo.traceback = excinfo.traceback.filter()
|
||||
entry = excinfo.traceback[-1]
|
||||
p = FormattedExcinfo(funcargs=True)
|
||||
reprfuncargs = p.repr_args(entry)
|
||||
assert reprfuncargs.args[0] == ('m', repr("m"*90))
|
||||
assert reprfuncargs.args[1] == ('x', '5')
|
||||
assert reprfuncargs.args[2] == ('y', '13')
|
||||
assert reprfuncargs.args[3] == ('z', repr("z" * 120))
|
||||
|
||||
p = FormattedExcinfo(funcargs=True)
|
||||
repr_entry = p.repr_traceback_entry(entry)
|
||||
assert repr_entry.reprfuncargs.args == reprfuncargs.args
|
||||
tw = TWMock()
|
||||
repr_entry.toterminal(tw)
|
||||
assert tw.lines[0] == "m = " + repr('m' * 90)
|
||||
assert tw.lines[1] == "x = 5, y = 13"
|
||||
assert tw.lines[2] == "z = " + repr('z' * 120)
|
||||
|
||||
def test_repr_tracebackentry_lines_var_kw_args(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def func1(x, *y, **z):
|
||||
raise ValueError("hello\\nworld")
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.func1, 'a', 'b', c='d')
|
||||
excinfo.traceback = excinfo.traceback.filter()
|
||||
entry = excinfo.traceback[-1]
|
||||
p = FormattedExcinfo(funcargs=True)
|
||||
reprfuncargs = p.repr_args(entry)
|
||||
assert reprfuncargs.args[0] == ('x', repr('a'))
|
||||
assert reprfuncargs.args[1] == ('y', repr(('b',)))
|
||||
assert reprfuncargs.args[2] == ('z', repr({'c': 'd'}))
|
||||
|
||||
p = FormattedExcinfo(funcargs=True)
|
||||
repr_entry = p.repr_traceback_entry(entry)
|
||||
assert repr_entry.reprfuncargs.args == reprfuncargs.args
|
||||
tw = TWMock()
|
||||
repr_entry.toterminal(tw)
|
||||
assert tw.lines[0] == "x = 'a', y = ('b',), z = {'c': 'd'}"
|
||||
|
||||
def test_repr_tracebackentry_short(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def func1():
|
||||
raise ValueError("hello")
|
||||
def entry():
|
||||
func1()
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.entry)
|
||||
p = FormattedExcinfo(style="short")
|
||||
reprtb = p.repr_traceback_entry(excinfo.traceback[-2])
|
||||
lines = reprtb.lines
|
||||
basename = py.path.local(mod.__file__).basename
|
||||
assert lines[0] == ' func1()'
|
||||
assert basename in str(reprtb.reprfileloc.path)
|
||||
assert reprtb.reprfileloc.lineno == 5
|
||||
|
||||
# test last entry
|
||||
p = FormattedExcinfo(style="short")
|
||||
reprtb = p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
|
||||
lines = reprtb.lines
|
||||
assert lines[0] == ' raise ValueError("hello")'
|
||||
assert lines[1] == 'E ValueError: hello'
|
||||
assert basename in str(reprtb.reprfileloc.path)
|
||||
assert reprtb.reprfileloc.lineno == 3
|
||||
|
||||
def test_repr_tracebackentry_no(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def func1():
|
||||
raise ValueError("hello")
|
||||
def entry():
|
||||
func1()
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.entry)
|
||||
p = FormattedExcinfo(style="no")
|
||||
p.repr_traceback_entry(excinfo.traceback[-2])
|
||||
|
||||
p = FormattedExcinfo(style="no")
|
||||
reprentry = p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
|
||||
lines = reprentry.lines
|
||||
assert lines[0] == 'E ValueError: hello'
|
||||
assert not lines[1:]
|
||||
|
||||
def test_repr_traceback_tbfilter(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def f(x):
|
||||
raise ValueError(x)
|
||||
def entry():
|
||||
f(0)
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.entry)
|
||||
p = FormattedExcinfo(tbfilter=True)
|
||||
reprtb = p.repr_traceback(excinfo)
|
||||
assert len(reprtb.reprentries) == 2
|
||||
p = FormattedExcinfo(tbfilter=False)
|
||||
reprtb = p.repr_traceback(excinfo)
|
||||
assert len(reprtb.reprentries) == 3
|
||||
|
||||
def test_traceback_short_no_source(self, importasmod, monkeypatch):
|
||||
mod = importasmod("""
|
||||
def func1():
|
||||
raise ValueError("hello")
|
||||
def entry():
|
||||
func1()
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.entry)
|
||||
from _pytest._code.code import Code
|
||||
monkeypatch.setattr(Code, 'path', 'bogus')
|
||||
excinfo.traceback[0].frame.code.path = "bogus"
|
||||
p = FormattedExcinfo(style="short")
|
||||
reprtb = p.repr_traceback_entry(excinfo.traceback[-2])
|
||||
lines = reprtb.lines
|
||||
last_p = FormattedExcinfo(style="short")
|
||||
last_reprtb = last_p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
|
||||
last_lines = last_reprtb.lines
|
||||
monkeypatch.undo()
|
||||
assert lines[0] == ' func1()'
|
||||
|
||||
assert last_lines[0] == ' raise ValueError("hello")'
|
||||
assert last_lines[1] == 'E ValueError: hello'
|
||||
|
||||
def test_repr_traceback_and_excinfo(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def f(x):
|
||||
raise ValueError(x)
|
||||
def entry():
|
||||
f(0)
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.entry)
|
||||
|
||||
for style in ("long", "short"):
|
||||
p = FormattedExcinfo(style=style)
|
||||
reprtb = p.repr_traceback(excinfo)
|
||||
assert len(reprtb.reprentries) == 2
|
||||
assert reprtb.style == style
|
||||
assert not reprtb.extraline
|
||||
repr = p.repr_excinfo(excinfo)
|
||||
assert repr.reprtraceback
|
||||
assert len(repr.reprtraceback.reprentries) == len(reprtb.reprentries)
|
||||
assert repr.reprcrash.path.endswith("mod.py")
|
||||
assert repr.reprcrash.message == "ValueError: 0"
|
||||
|
||||
def test_repr_traceback_with_invalid_cwd(self, importasmod, monkeypatch):
|
||||
mod = importasmod("""
|
||||
def f(x):
|
||||
raise ValueError(x)
|
||||
def entry():
|
||||
f(0)
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.entry)
|
||||
|
||||
p = FormattedExcinfo()
|
||||
def raiseos():
|
||||
raise OSError(2)
|
||||
monkeypatch.setattr(py.std.os, 'getcwd', raiseos)
|
||||
assert p._makepath(__file__) == __file__
|
||||
p.repr_traceback(excinfo)
|
||||
|
||||
def test_repr_excinfo_addouterr(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def entry():
|
||||
raise ValueError()
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.entry)
|
||||
repr = excinfo.getrepr()
|
||||
repr.addsection("title", "content")
|
||||
twmock = TWMock()
|
||||
repr.toterminal(twmock)
|
||||
assert twmock.lines[-1] == "content"
|
||||
assert twmock.lines[-2] == ("-", "title")
|
||||
|
||||
def test_repr_excinfo_reprcrash(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def entry():
|
||||
raise ValueError()
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.entry)
|
||||
repr = excinfo.getrepr()
|
||||
assert repr.reprcrash.path.endswith("mod.py")
|
||||
assert repr.reprcrash.lineno == 3
|
||||
assert repr.reprcrash.message == "ValueError"
|
||||
assert str(repr.reprcrash).endswith("mod.py:3: ValueError")
|
||||
|
||||
def test_repr_traceback_recursion(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def rec2(x):
|
||||
return rec1(x+1)
|
||||
def rec1(x):
|
||||
return rec2(x-1)
|
||||
def entry():
|
||||
rec1(42)
|
||||
""")
|
||||
excinfo = pytest.raises(RuntimeError, mod.entry)
|
||||
|
||||
for style in ("short", "long", "no"):
|
||||
p = FormattedExcinfo(style="short")
|
||||
reprtb = p.repr_traceback(excinfo)
|
||||
assert reprtb.extraline == "!!! Recursion detected (same locals & position)"
|
||||
assert str(reprtb)
|
||||
|
||||
def test_tb_entry_AssertionError(self, importasmod):
|
||||
# probably this test is a bit redundant
|
||||
# as py/magic/testing/test_assertion.py
|
||||
# already tests correctness of
|
||||
# assertion-reinterpretation logic
|
||||
mod = importasmod("""
|
||||
def somefunc():
|
||||
x = 1
|
||||
assert x == 2
|
||||
""")
|
||||
excinfo = pytest.raises(AssertionError, mod.somefunc)
|
||||
|
||||
p = FormattedExcinfo()
|
||||
reprentry = p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
|
||||
lines = reprentry.lines
|
||||
assert lines[-1] == "E assert 1 == 2"
|
||||
|
||||
def test_reprexcinfo_getrepr(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def f(x):
|
||||
raise ValueError(x)
|
||||
def entry():
|
||||
f(0)
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.entry)
|
||||
|
||||
for style in ("short", "long", "no"):
|
||||
for showlocals in (True, False):
|
||||
repr = excinfo.getrepr(style=style, showlocals=showlocals)
|
||||
assert isinstance(repr, ReprExceptionInfo)
|
||||
assert repr.reprtraceback.style == style
|
||||
|
||||
def test_reprexcinfo_unicode(self):
|
||||
from _pytest._code.code import TerminalRepr
|
||||
class MyRepr(TerminalRepr):
|
||||
def toterminal(self, tw):
|
||||
tw.line(py.builtin._totext("я", "utf-8"))
|
||||
x = py.builtin._totext(MyRepr())
|
||||
assert x == py.builtin._totext("я", "utf-8")
|
||||
|
||||
def test_toterminal_long(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def g(x):
|
||||
raise ValueError(x)
|
||||
def f():
|
||||
g(3)
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.f)
|
||||
excinfo.traceback = excinfo.traceback.filter()
|
||||
repr = excinfo.getrepr()
|
||||
tw = TWMock()
|
||||
repr.toterminal(tw)
|
||||
assert tw.lines[0] == ""
|
||||
tw.lines.pop(0)
|
||||
assert tw.lines[0] == " def f():"
|
||||
assert tw.lines[1] == "> g(3)"
|
||||
assert tw.lines[2] == ""
|
||||
assert tw.lines[3].endswith("mod.py:5: ")
|
||||
assert tw.lines[4] == ("_ ", None)
|
||||
assert tw.lines[5] == ""
|
||||
assert tw.lines[6] == " def g(x):"
|
||||
assert tw.lines[7] == "> raise ValueError(x)"
|
||||
assert tw.lines[8] == "E ValueError: 3"
|
||||
assert tw.lines[9] == ""
|
||||
assert tw.lines[10].endswith("mod.py:3: ValueError")
|
||||
|
||||
def test_toterminal_long_missing_source(self, importasmod, tmpdir):
|
||||
mod = importasmod("""
|
||||
def g(x):
|
||||
raise ValueError(x)
|
||||
def f():
|
||||
g(3)
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.f)
|
||||
tmpdir.join('mod.py').remove()
|
||||
excinfo.traceback = excinfo.traceback.filter()
|
||||
repr = excinfo.getrepr()
|
||||
tw = TWMock()
|
||||
repr.toterminal(tw)
|
||||
assert tw.lines[0] == ""
|
||||
tw.lines.pop(0)
|
||||
assert tw.lines[0] == "> ???"
|
||||
assert tw.lines[1] == ""
|
||||
assert tw.lines[2].endswith("mod.py:5: ")
|
||||
assert tw.lines[3] == ("_ ", None)
|
||||
assert tw.lines[4] == ""
|
||||
assert tw.lines[5] == "> ???"
|
||||
assert tw.lines[6] == "E ValueError: 3"
|
||||
assert tw.lines[7] == ""
|
||||
assert tw.lines[8].endswith("mod.py:3: ValueError")
|
||||
|
||||
def test_toterminal_long_incomplete_source(self, importasmod, tmpdir):
|
||||
mod = importasmod("""
|
||||
def g(x):
|
||||
raise ValueError(x)
|
||||
def f():
|
||||
g(3)
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.f)
|
||||
tmpdir.join('mod.py').write('asdf')
|
||||
excinfo.traceback = excinfo.traceback.filter()
|
||||
repr = excinfo.getrepr()
|
||||
tw = TWMock()
|
||||
repr.toterminal(tw)
|
||||
assert tw.lines[0] == ""
|
||||
tw.lines.pop(0)
|
||||
assert tw.lines[0] == "> ???"
|
||||
assert tw.lines[1] == ""
|
||||
assert tw.lines[2].endswith("mod.py:5: ")
|
||||
assert tw.lines[3] == ("_ ", None)
|
||||
assert tw.lines[4] == ""
|
||||
assert tw.lines[5] == "> ???"
|
||||
assert tw.lines[6] == "E ValueError: 3"
|
||||
assert tw.lines[7] == ""
|
||||
assert tw.lines[8].endswith("mod.py:3: ValueError")
|
||||
|
||||
def test_toterminal_long_filenames(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def f():
|
||||
raise ValueError()
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.f)
|
||||
tw = TWMock()
|
||||
path = py.path.local(mod.__file__)
|
||||
old = path.dirpath().chdir()
|
||||
try:
|
||||
repr = excinfo.getrepr(abspath=False)
|
||||
repr.toterminal(tw)
|
||||
line = tw.lines[-1]
|
||||
x = py.path.local().bestrelpath(path)
|
||||
if len(x) < len(str(path)):
|
||||
assert line == "mod.py:3: ValueError"
|
||||
|
||||
repr = excinfo.getrepr(abspath=True)
|
||||
repr.toterminal(tw)
|
||||
line = tw.lines[-1]
|
||||
assert line == "%s:3: ValueError" %(path,)
|
||||
finally:
|
||||
old.chdir()
|
||||
|
||||
@pytest.mark.parametrize('reproptions', [
|
||||
{'style': style, 'showlocals': showlocals,
|
||||
'funcargs': funcargs, 'tbfilter': tbfilter
|
||||
} for style in ("long", "short", "no")
|
||||
for showlocals in (True, False)
|
||||
for tbfilter in (True, False)
|
||||
for funcargs in (True, False)])
|
||||
def test_format_excinfo(self, importasmod, reproptions):
|
||||
mod = importasmod("""
|
||||
def g(x):
|
||||
raise ValueError(x)
|
||||
def f():
|
||||
g(3)
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.f)
|
||||
tw = py.io.TerminalWriter(stringio=True)
|
||||
repr = excinfo.getrepr(**reproptions)
|
||||
repr.toterminal(tw)
|
||||
assert tw.stringio.getvalue()
|
||||
|
||||
|
||||
def test_native_style(self):
|
||||
excinfo = self.excinfo_from_exec("""
|
||||
assert 0
|
||||
""")
|
||||
repr = excinfo.getrepr(style='native')
|
||||
assert "assert 0" in str(repr.reprcrash)
|
||||
s = str(repr)
|
||||
assert s.startswith('Traceback (most recent call last):\n File')
|
||||
assert s.endswith('\nAssertionError: assert 0')
|
||||
assert 'exec (source.compile())' in s
|
||||
# python 2.4 fails to get the source line for the assert
|
||||
if py.std.sys.version_info >= (2, 5):
|
||||
assert s.count('assert 0') == 2
|
||||
|
||||
def test_traceback_repr_style(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def f():
|
||||
g()
|
||||
def g():
|
||||
h()
|
||||
def h():
|
||||
i()
|
||||
def i():
|
||||
raise ValueError()
|
||||
""")
|
||||
excinfo = pytest.raises(ValueError, mod.f)
|
||||
excinfo.traceback = excinfo.traceback.filter()
|
||||
excinfo.traceback[1].set_repr_style("short")
|
||||
excinfo.traceback[2].set_repr_style("short")
|
||||
r = excinfo.getrepr(style="long")
|
||||
tw = TWMock()
|
||||
r.toterminal(tw)
|
||||
for line in tw.lines: print (line)
|
||||
assert tw.lines[0] == ""
|
||||
assert tw.lines[1] == " def f():"
|
||||
assert tw.lines[2] == "> g()"
|
||||
assert tw.lines[3] == ""
|
||||
assert tw.lines[4].endswith("mod.py:3: ")
|
||||
assert tw.lines[5] == ("_ ", None)
|
||||
assert tw.lines[6].endswith("in g")
|
||||
assert tw.lines[7] == " h()"
|
||||
assert tw.lines[8].endswith("in h")
|
||||
assert tw.lines[9] == " i()"
|
||||
assert tw.lines[10] == ("_ ", None)
|
||||
assert tw.lines[11] == ""
|
||||
assert tw.lines[12] == " def i():"
|
||||
assert tw.lines[13] == "> raise ValueError()"
|
||||
assert tw.lines[14] == "E ValueError"
|
||||
assert tw.lines[15] == ""
|
||||
assert tw.lines[16].endswith("mod.py:9: ValueError")
|
659
tests/wpt/css-tests/tools/pytest/testing/code/test_source.py
Normal file
659
tests/wpt/css-tests/tools/pytest/testing/code/test_source.py
Normal file
|
@ -0,0 +1,659 @@
|
|||
# flake8: noqa
|
||||
# disable flake check on this file because some constructs are strange
|
||||
# or redundant on purpose and can't be disable on a line-by-line basis
|
||||
import sys
|
||||
|
||||
import _pytest._code
|
||||
import py
|
||||
import pytest
|
||||
from _pytest._code import Source
|
||||
from _pytest._code.source import _ast
|
||||
|
||||
if _ast is not None:
|
||||
astonly = pytest.mark.nothing
|
||||
else:
|
||||
astonly = pytest.mark.xfail("True", reason="only works with AST-compile")
|
||||
|
||||
failsonjython = pytest.mark.xfail("sys.platform.startswith('java')")
|
||||
|
||||
def test_source_str_function():
|
||||
x = Source("3")
|
||||
assert str(x) == "3"
|
||||
|
||||
x = Source(" 3")
|
||||
assert str(x) == "3"
|
||||
|
||||
x = Source("""
|
||||
3
|
||||
""", rstrip=False)
|
||||
assert str(x) == "\n3\n "
|
||||
|
||||
x = Source("""
|
||||
3
|
||||
""", rstrip=True)
|
||||
assert str(x) == "\n3"
|
||||
|
||||
def test_unicode():
|
||||
try:
|
||||
unicode
|
||||
except NameError:
|
||||
return
|
||||
x = Source(unicode("4"))
|
||||
assert str(x) == "4"
|
||||
co = _pytest._code.compile(unicode('u"\xc3\xa5"', 'utf8'), mode='eval')
|
||||
val = eval(co)
|
||||
assert isinstance(val, unicode)
|
||||
|
||||
def test_source_from_function():
|
||||
source = _pytest._code.Source(test_source_str_function)
|
||||
assert str(source).startswith('def test_source_str_function():')
|
||||
|
||||
def test_source_from_method():
|
||||
class TestClass:
|
||||
def test_method(self):
|
||||
pass
|
||||
source = _pytest._code.Source(TestClass().test_method)
|
||||
assert source.lines == ["def test_method(self):",
|
||||
" pass"]
|
||||
|
||||
def test_source_from_lines():
|
||||
lines = ["a \n", "b\n", "c"]
|
||||
source = _pytest._code.Source(lines)
|
||||
assert source.lines == ['a ', 'b', 'c']
|
||||
|
||||
def test_source_from_inner_function():
|
||||
def f():
|
||||
pass
|
||||
source = _pytest._code.Source(f, deindent=False)
|
||||
assert str(source).startswith(' def f():')
|
||||
source = _pytest._code.Source(f)
|
||||
assert str(source).startswith('def f():')
|
||||
|
||||
def test_source_putaround_simple():
|
||||
source = Source("raise ValueError")
|
||||
source = source.putaround(
|
||||
"try:", """\
|
||||
except ValueError:
|
||||
x = 42
|
||||
else:
|
||||
x = 23""")
|
||||
assert str(source)=="""\
|
||||
try:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
x = 42
|
||||
else:
|
||||
x = 23"""
|
||||
|
||||
def test_source_putaround():
|
||||
source = Source()
|
||||
source = source.putaround("""
|
||||
if 1:
|
||||
x=1
|
||||
""")
|
||||
assert str(source).strip() == "if 1:\n x=1"
|
||||
|
||||
def test_source_strips():
|
||||
source = Source("")
|
||||
assert source == Source()
|
||||
assert str(source) == ''
|
||||
assert source.strip() == source
|
||||
|
||||
def test_source_strip_multiline():
|
||||
source = Source()
|
||||
source.lines = ["", " hello", " "]
|
||||
source2 = source.strip()
|
||||
assert source2.lines == [" hello"]
|
||||
|
||||
def test_syntaxerror_rerepresentation():
|
||||
ex = pytest.raises(SyntaxError, _pytest._code.compile, 'xyz xyz')
|
||||
assert ex.value.lineno == 1
|
||||
assert ex.value.offset in (4,7) # XXX pypy/jython versus cpython?
|
||||
assert ex.value.text.strip(), 'x x'
|
||||
|
||||
def test_isparseable():
|
||||
assert Source("hello").isparseable()
|
||||
assert Source("if 1:\n pass").isparseable()
|
||||
assert Source(" \nif 1:\n pass").isparseable()
|
||||
assert not Source("if 1:\n").isparseable()
|
||||
assert not Source(" \nif 1:\npass").isparseable()
|
||||
assert not Source(chr(0)).isparseable()
|
||||
|
||||
class TestAccesses:
|
||||
source = Source("""\
|
||||
def f(x):
|
||||
pass
|
||||
def g(x):
|
||||
pass
|
||||
""")
|
||||
def test_getrange(self):
|
||||
x = self.source[0:2]
|
||||
assert x.isparseable()
|
||||
assert len(x.lines) == 2
|
||||
assert str(x) == "def f(x):\n pass"
|
||||
|
||||
def test_getline(self):
|
||||
x = self.source[0]
|
||||
assert x == "def f(x):"
|
||||
|
||||
def test_len(self):
|
||||
assert len(self.source) == 4
|
||||
|
||||
def test_iter(self):
|
||||
l = [x for x in self.source]
|
||||
assert len(l) == 4
|
||||
|
||||
class TestSourceParsingAndCompiling:
|
||||
source = Source("""\
|
||||
def f(x):
|
||||
assert (x ==
|
||||
3 +
|
||||
4)
|
||||
""").strip()
|
||||
|
||||
def test_compile(self):
|
||||
co = _pytest._code.compile("x=3")
|
||||
d = {}
|
||||
exec (co, d)
|
||||
assert d['x'] == 3
|
||||
|
||||
def test_compile_and_getsource_simple(self):
|
||||
co = _pytest._code.compile("x=3")
|
||||
exec (co)
|
||||
source = _pytest._code.Source(co)
|
||||
assert str(source) == "x=3"
|
||||
|
||||
def test_compile_and_getsource_through_same_function(self):
|
||||
def gensource(source):
|
||||
return _pytest._code.compile(source)
|
||||
co1 = gensource("""
|
||||
def f():
|
||||
raise KeyError()
|
||||
""")
|
||||
co2 = gensource("""
|
||||
def f():
|
||||
raise ValueError()
|
||||
""")
|
||||
source1 = py.std.inspect.getsource(co1)
|
||||
assert 'KeyError' in source1
|
||||
source2 = py.std.inspect.getsource(co2)
|
||||
assert 'ValueError' in source2
|
||||
|
||||
def test_getstatement(self):
|
||||
#print str(self.source)
|
||||
ass = str(self.source[1:])
|
||||
for i in range(1, 4):
|
||||
#print "trying start in line %r" % self.source[i]
|
||||
s = self.source.getstatement(i)
|
||||
#x = s.deindent()
|
||||
assert str(s) == ass
|
||||
|
||||
def test_getstatementrange_triple_quoted(self):
|
||||
#print str(self.source)
|
||||
source = Source("""hello('''
|
||||
''')""")
|
||||
s = source.getstatement(0)
|
||||
assert s == str(source)
|
||||
s = source.getstatement(1)
|
||||
assert s == str(source)
|
||||
|
||||
@astonly
|
||||
def test_getstatementrange_within_constructs(self):
|
||||
source = Source("""\
|
||||
try:
|
||||
try:
|
||||
raise ValueError
|
||||
except SomeThing:
|
||||
pass
|
||||
finally:
|
||||
42
|
||||
""")
|
||||
assert len(source) == 7
|
||||
# check all lineno's that could occur in a traceback
|
||||
#assert source.getstatementrange(0) == (0, 7)
|
||||
#assert source.getstatementrange(1) == (1, 5)
|
||||
assert source.getstatementrange(2) == (2, 3)
|
||||
assert source.getstatementrange(3) == (3, 4)
|
||||
assert source.getstatementrange(4) == (4, 5)
|
||||
#assert source.getstatementrange(5) == (0, 7)
|
||||
assert source.getstatementrange(6) == (6, 7)
|
||||
|
||||
def test_getstatementrange_bug(self):
|
||||
source = Source("""\
|
||||
try:
|
||||
x = (
|
||||
y +
|
||||
z)
|
||||
except:
|
||||
pass
|
||||
""")
|
||||
assert len(source) == 6
|
||||
assert source.getstatementrange(2) == (1, 4)
|
||||
|
||||
def test_getstatementrange_bug2(self):
|
||||
source = Source("""\
|
||||
assert (
|
||||
33
|
||||
==
|
||||
[
|
||||
X(3,
|
||||
b=1, c=2
|
||||
),
|
||||
]
|
||||
)
|
||||
""")
|
||||
assert len(source) == 9
|
||||
assert source.getstatementrange(5) == (0, 9)
|
||||
|
||||
def test_getstatementrange_ast_issue58(self):
|
||||
source = Source("""\
|
||||
|
||||
def test_some():
|
||||
for a in [a for a in
|
||||
CAUSE_ERROR]: pass
|
||||
|
||||
x = 3
|
||||
""")
|
||||
assert getstatement(2, source).lines == source.lines[2:3]
|
||||
assert getstatement(3, source).lines == source.lines[3:4]
|
||||
|
||||
@pytest.mark.skipif("sys.version_info < (2,6)")
|
||||
def test_getstatementrange_out_of_bounds_py3(self):
|
||||
source = Source("if xxx:\n from .collections import something")
|
||||
r = source.getstatementrange(1)
|
||||
assert r == (1,2)
|
||||
|
||||
def test_getstatementrange_with_syntaxerror_issue7(self):
|
||||
source = Source(":")
|
||||
pytest.raises(SyntaxError, lambda: source.getstatementrange(0))
|
||||
|
||||
@pytest.mark.skipif("sys.version_info < (2,6)")
|
||||
def test_compile_to_ast(self):
|
||||
import ast
|
||||
source = Source("x = 4")
|
||||
mod = source.compile(flag=ast.PyCF_ONLY_AST)
|
||||
assert isinstance(mod, ast.Module)
|
||||
compile(mod, "<filename>", "exec")
|
||||
|
||||
def test_compile_and_getsource(self):
|
||||
co = self.source.compile()
|
||||
py.builtin.exec_(co, globals())
|
||||
f(7)
|
||||
excinfo = pytest.raises(AssertionError, "f(6)")
|
||||
frame = excinfo.traceback[-1].frame
|
||||
stmt = frame.code.fullsource.getstatement(frame.lineno)
|
||||
#print "block", str(block)
|
||||
assert str(stmt).strip().startswith('assert')
|
||||
|
||||
def test_compilefuncs_and_path_sanity(self):
|
||||
def check(comp, name):
|
||||
co = comp(self.source, name)
|
||||
if not name:
|
||||
expected = "codegen %s:%d>" %(mypath, mylineno+2+1)
|
||||
else:
|
||||
expected = "codegen %r %s:%d>" % (name, mypath, mylineno+2+1)
|
||||
fn = co.co_filename
|
||||
assert fn.endswith(expected)
|
||||
|
||||
mycode = _pytest._code.Code(self.test_compilefuncs_and_path_sanity)
|
||||
mylineno = mycode.firstlineno
|
||||
mypath = mycode.path
|
||||
|
||||
for comp in _pytest._code.compile, _pytest._code.Source.compile:
|
||||
for name in '', None, 'my':
|
||||
yield check, comp, name
|
||||
|
||||
def test_offsetless_synerr(self):
|
||||
pytest.raises(SyntaxError, _pytest._code.compile, "lambda a,a: 0", mode='eval')
|
||||
|
||||
def test_getstartingblock_singleline():
|
||||
class A:
|
||||
def __init__(self, *args):
|
||||
frame = sys._getframe(1)
|
||||
self.source = _pytest._code.Frame(frame).statement
|
||||
|
||||
x = A('x', 'y')
|
||||
|
||||
l = [i for i in x.source.lines if i.strip()]
|
||||
assert len(l) == 1
|
||||
|
||||
def test_getstartingblock_multiline():
|
||||
class A:
|
||||
def __init__(self, *args):
|
||||
frame = sys._getframe(1)
|
||||
self.source = _pytest._code.Frame(frame).statement
|
||||
|
||||
x = A('x',
|
||||
'y' \
|
||||
,
|
||||
'z')
|
||||
|
||||
l = [i for i in x.source.lines if i.strip()]
|
||||
assert len(l) == 4
|
||||
|
||||
def test_getline_finally():
|
||||
def c(): pass
|
||||
excinfo = pytest.raises(TypeError, """
|
||||
teardown = None
|
||||
try:
|
||||
c(1)
|
||||
finally:
|
||||
if teardown:
|
||||
teardown()
|
||||
""")
|
||||
source = excinfo.traceback[-1].statement
|
||||
assert str(source).strip() == 'c(1)'
|
||||
|
||||
def test_getfuncsource_dynamic():
|
||||
source = """
|
||||
def f():
|
||||
raise ValueError
|
||||
|
||||
def g(): pass
|
||||
"""
|
||||
co = _pytest._code.compile(source)
|
||||
py.builtin.exec_(co, globals())
|
||||
assert str(_pytest._code.Source(f)).strip() == 'def f():\n raise ValueError'
|
||||
assert str(_pytest._code.Source(g)).strip() == 'def g(): pass'
|
||||
|
||||
|
||||
def test_getfuncsource_with_multine_string():
|
||||
def f():
|
||||
c = '''while True:
|
||||
pass
|
||||
'''
|
||||
assert str(_pytest._code.Source(f)).strip() == "def f():\n c = '''while True:\n pass\n'''"
|
||||
|
||||
|
||||
def test_deindent():
|
||||
from _pytest._code.source import deindent as deindent
|
||||
assert deindent(['\tfoo', '\tbar', ]) == ['foo', 'bar']
|
||||
|
||||
def f():
|
||||
c = '''while True:
|
||||
pass
|
||||
'''
|
||||
import inspect
|
||||
lines = deindent(inspect.getsource(f).splitlines())
|
||||
assert lines == ["def f():", " c = '''while True:", " pass", "'''"]
|
||||
|
||||
source = """
|
||||
def f():
|
||||
def g():
|
||||
pass
|
||||
"""
|
||||
lines = deindent(source.splitlines())
|
||||
assert lines == ['', 'def f():', ' def g():', ' pass', ' ']
|
||||
|
||||
@pytest.mark.xfail("sys.version_info[:3] < (2,7,0) or "
|
||||
"((3,0) <= sys.version_info[:2] < (3,2))")
|
||||
def test_source_of_class_at_eof_without_newline(tmpdir):
|
||||
# this test fails because the implicit inspect.getsource(A) below
|
||||
# does not return the "x = 1" last line.
|
||||
source = _pytest._code.Source('''
|
||||
class A(object):
|
||||
def method(self):
|
||||
x = 1
|
||||
''')
|
||||
path = tmpdir.join("a.py")
|
||||
path.write(source)
|
||||
s2 = _pytest._code.Source(tmpdir.join("a.py").pyimport().A)
|
||||
assert str(source).strip() == str(s2).strip()
|
||||
|
||||
if True:
|
||||
def x():
|
||||
pass
|
||||
|
||||
def test_getsource_fallback():
|
||||
from _pytest._code.source import getsource
|
||||
expected = """def x():
|
||||
pass"""
|
||||
src = getsource(x)
|
||||
assert src == expected
|
||||
|
||||
def test_idem_compile_and_getsource():
|
||||
from _pytest._code.source import getsource
|
||||
expected = "def x(): pass"
|
||||
co = _pytest._code.compile(expected)
|
||||
src = getsource(co)
|
||||
assert src == expected
|
||||
|
||||
def test_findsource_fallback():
|
||||
from _pytest._code.source import findsource
|
||||
src, lineno = findsource(x)
|
||||
assert 'test_findsource_simple' in str(src)
|
||||
assert src[lineno] == ' def x():'
|
||||
|
||||
def test_findsource():
|
||||
from _pytest._code.source import findsource
|
||||
co = _pytest._code.compile("""if 1:
|
||||
def x():
|
||||
pass
|
||||
""")
|
||||
|
||||
src, lineno = findsource(co)
|
||||
assert 'if 1:' in str(src)
|
||||
|
||||
d = {}
|
||||
eval(co, d)
|
||||
src, lineno = findsource(d['x'])
|
||||
assert 'if 1:' in str(src)
|
||||
assert src[lineno] == " def x():"
|
||||
|
||||
|
||||
def test_getfslineno():
|
||||
from _pytest._code import getfslineno
|
||||
|
||||
def f(x):
|
||||
pass
|
||||
|
||||
fspath, lineno = getfslineno(f)
|
||||
|
||||
assert fspath.basename == "test_source.py"
|
||||
assert lineno == _pytest._code.getrawcode(f).co_firstlineno - 1 # see findsource
|
||||
|
||||
class A(object):
|
||||
pass
|
||||
|
||||
fspath, lineno = getfslineno(A)
|
||||
|
||||
_, A_lineno = py.std.inspect.findsource(A)
|
||||
assert fspath.basename == "test_source.py"
|
||||
assert lineno == A_lineno
|
||||
|
||||
assert getfslineno(3) == ("", -1)
|
||||
class B:
|
||||
pass
|
||||
B.__name__ = "B2"
|
||||
assert getfslineno(B)[1] == -1
|
||||
|
||||
def test_code_of_object_instance_with_call():
|
||||
class A:
|
||||
pass
|
||||
pytest.raises(TypeError, lambda: _pytest._code.Source(A()))
|
||||
class WithCall:
|
||||
def __call__(self):
|
||||
pass
|
||||
|
||||
code = _pytest._code.Code(WithCall())
|
||||
assert 'pass' in str(code.source())
|
||||
|
||||
class Hello(object):
|
||||
def __call__(self):
|
||||
pass
|
||||
pytest.raises(TypeError, lambda: _pytest._code.Code(Hello))
|
||||
|
||||
|
||||
def getstatement(lineno, source):
|
||||
from _pytest._code.source import getstatementrange_ast
|
||||
source = _pytest._code.Source(source, deindent=False)
|
||||
ast, start, end = getstatementrange_ast(lineno, source)
|
||||
return source[start:end]
|
||||
|
||||
def test_oneline():
|
||||
source = getstatement(0, "raise ValueError")
|
||||
assert str(source) == "raise ValueError"
|
||||
|
||||
def test_comment_and_no_newline_at_end():
|
||||
from _pytest._code.source import getstatementrange_ast
|
||||
source = Source(['def test_basic_complex():',
|
||||
' assert 1 == 2',
|
||||
'# vim: filetype=pyopencl:fdm=marker'])
|
||||
ast, start, end = getstatementrange_ast(1, source)
|
||||
assert end == 2
|
||||
|
||||
def test_oneline_and_comment():
|
||||
source = getstatement(0, "raise ValueError\n#hello")
|
||||
assert str(source) == "raise ValueError"
|
||||
|
||||
@pytest.mark.xfail(hasattr(sys, "pypy_version_info"),
|
||||
reason='does not work on pypy')
|
||||
def test_comments():
|
||||
source = '''def test():
|
||||
"comment 1"
|
||||
x = 1
|
||||
# comment 2
|
||||
# comment 3
|
||||
|
||||
assert False
|
||||
|
||||
"""
|
||||
comment 4
|
||||
"""
|
||||
'''
|
||||
for line in range(2,6):
|
||||
assert str(getstatement(line, source)) == ' x = 1'
|
||||
for line in range(6,10):
|
||||
assert str(getstatement(line, source)) == ' assert False'
|
||||
assert str(getstatement(10, source)) == '"""'
|
||||
|
||||
def test_comment_in_statement():
|
||||
source = '''test(foo=1,
|
||||
# comment 1
|
||||
bar=2)
|
||||
'''
|
||||
for line in range(1,3):
|
||||
assert str(getstatement(line, source)) == \
|
||||
'test(foo=1,\n # comment 1\n bar=2)'
|
||||
|
||||
def test_single_line_else():
|
||||
source = getstatement(1, "if False: 2\nelse: 3")
|
||||
assert str(source) == "else: 3"
|
||||
|
||||
def test_single_line_finally():
|
||||
source = getstatement(1, "try: 1\nfinally: 3")
|
||||
assert str(source) == "finally: 3"
|
||||
|
||||
def test_issue55():
|
||||
source = ('def round_trip(dinp):\n assert 1 == dinp\n'
|
||||
'def test_rt():\n round_trip("""\n""")\n')
|
||||
s = getstatement(3, source)
|
||||
assert str(s) == ' round_trip("""\n""")'
|
||||
|
||||
|
||||
def XXXtest_multiline():
|
||||
source = getstatement(0, """\
|
||||
raise ValueError(
|
||||
23
|
||||
)
|
||||
x = 3
|
||||
""")
|
||||
assert str(source) == "raise ValueError(\n 23\n)"
|
||||
|
||||
class TestTry:
|
||||
pytestmark = astonly
|
||||
source = """\
|
||||
try:
|
||||
raise ValueError
|
||||
except Something:
|
||||
raise IndexError(1)
|
||||
else:
|
||||
raise KeyError()
|
||||
"""
|
||||
|
||||
def test_body(self):
|
||||
source = getstatement(1, self.source)
|
||||
assert str(source) == " raise ValueError"
|
||||
|
||||
def test_except_line(self):
|
||||
source = getstatement(2, self.source)
|
||||
assert str(source) == "except Something:"
|
||||
|
||||
def test_except_body(self):
|
||||
source = getstatement(3, self.source)
|
||||
assert str(source) == " raise IndexError(1)"
|
||||
|
||||
def test_else(self):
|
||||
source = getstatement(5, self.source)
|
||||
assert str(source) == " raise KeyError()"
|
||||
|
||||
class TestTryFinally:
|
||||
source = """\
|
||||
try:
|
||||
raise ValueError
|
||||
finally:
|
||||
raise IndexError(1)
|
||||
"""
|
||||
|
||||
def test_body(self):
|
||||
source = getstatement(1, self.source)
|
||||
assert str(source) == " raise ValueError"
|
||||
|
||||
def test_finally(self):
|
||||
source = getstatement(3, self.source)
|
||||
assert str(source) == " raise IndexError(1)"
|
||||
|
||||
|
||||
|
||||
class TestIf:
|
||||
pytestmark = astonly
|
||||
source = """\
|
||||
if 1:
|
||||
y = 3
|
||||
elif False:
|
||||
y = 5
|
||||
else:
|
||||
y = 7
|
||||
"""
|
||||
|
||||
def test_body(self):
|
||||
source = getstatement(1, self.source)
|
||||
assert str(source) == " y = 3"
|
||||
|
||||
def test_elif_clause(self):
|
||||
source = getstatement(2, self.source)
|
||||
assert str(source) == "elif False:"
|
||||
|
||||
def test_elif(self):
|
||||
source = getstatement(3, self.source)
|
||||
assert str(source) == " y = 5"
|
||||
|
||||
def test_else(self):
|
||||
source = getstatement(5, self.source)
|
||||
assert str(source) == " y = 7"
|
||||
|
||||
def test_semicolon():
|
||||
s = """\
|
||||
hello ; pytest.skip()
|
||||
"""
|
||||
source = getstatement(0, s)
|
||||
assert str(source) == s.strip()
|
||||
|
||||
def test_def_online():
|
||||
s = """\
|
||||
def func(): raise ValueError(42)
|
||||
|
||||
def something():
|
||||
pass
|
||||
"""
|
||||
source = getstatement(0, s)
|
||||
assert str(source) == "def func(): raise ValueError(42)"
|
||||
|
||||
def XXX_test_expression_multiline():
|
||||
source = """\
|
||||
something
|
||||
'''
|
||||
'''"""
|
||||
result = getstatement(1, source)
|
||||
assert str(result) == "'''\n'''"
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue