rich/tests/test_inspect.py

206 lines
9.0 KiB
Python
Raw Normal View History

2020-09-07 15:44:31 +00:00
import io
2020-09-07 15:54:17 +00:00
import sys
2020-09-07 15:44:31 +00:00
2020-09-07 15:54:17 +00:00
import pytest
2020-09-07 15:44:31 +00:00
from rich import inspect
from rich.console import Console
2020-09-07 15:54:17 +00:00
skip_py36 = pytest.mark.skipif(
2020-09-07 15:57:35 +00:00
sys.version_info.minor == 6 and sys.version_info.major == 3,
reason="rendered differently on py3.6",
2020-09-07 15:54:17 +00:00
)
skip_py37 = pytest.mark.skipif(
sys.version_info.minor == 7 and sys.version_info.major == 3,
reason="rendered differently on py3.7",
)
2021-01-13 16:51:38 +00:00
def render(obj, methods=False, value=False, width=50) -> str:
console = Console(file=io.StringIO(), width=width, legacy_windows=False)
2020-12-29 15:43:57 +00:00
inspect(obj, console=console, methods=methods, value=value)
2020-09-20 23:02:49 +00:00
return console.file.getvalue()
2020-09-07 15:49:45 +00:00
class InspectError(Exception):
def __str__(self) -> str:
return "INSPECT ERROR"
2020-09-07 15:44:31 +00:00
class Foo:
"""Foo test
Second line
"""
def __init__(self, foo: int) -> None:
"""constructor docs."""
self.foo = foo
@property
def broken(self):
2020-09-07 15:49:45 +00:00
raise InspectError()
2020-09-07 15:44:31 +00:00
def method(self, a, b) -> str:
"""Multi line
docs.
"""
return "test"
def __dir__(self):
return ["__init__", "broken", "method"]
2020-09-07 15:54:17 +00:00
@skip_py36
2020-09-07 15:44:31 +00:00
def test_render():
console = Console(width=100, file=io.StringIO(), legacy_windows=False)
foo = Foo("hello")
2020-12-29 15:43:57 +00:00
inspect(foo, console=console, all=True, value=False)
2020-09-07 15:44:31 +00:00
result = console.file.getvalue()
print(repr(result))
2020-09-07 17:04:56 +00:00
expected = "╭────────────── <class 'tests.test_inspect.Foo'> ──────────────╮\n│ Foo test │\n│ │\n│ broken = InspectError() │\n│ __init__ = def __init__(foo: int) -> None: constructor docs. │\n│ method = def method(a, b) -> str: Multi line │\n╰──────────────────────────────────────────────────────────────╯\n"
2020-09-07 15:44:31 +00:00
assert expected == result
2020-09-20 23:02:49 +00:00
def test_inspect_text():
expected = (
2020-09-21 17:00:01 +00:00
"╭──────────────── <class 'str'> ─────────────────╮\n"
"│ str(object='') -> str │\n"
"│ str(bytes_or_buffer[, encoding[, errors]]) -> │\n"
"│ str │\n"
"│ │\n"
2020-12-29 15:43:57 +00:00
"│ 33 attribute(s) not shown. Run │\n"
"│ inspect(inspect) for options. │\n"
2020-09-21 17:00:01 +00:00
"╰────────────────────────────────────────────────╯\n"
2020-09-20 23:02:49 +00:00
)
2020-12-29 15:43:57 +00:00
print(repr(expected))
2020-09-21 17:00:01 +00:00
assert expected == render("Hello")
2020-09-20 23:02:49 +00:00
2020-09-20 23:15:17 +00:00
@skip_py36
@skip_py37
2020-09-20 23:02:49 +00:00
def test_inspect_empty_dict():
expected = (
"╭──────────────── <class 'dict'> ────────────────╮\n"
"│ dict() -> new empty dictionary │\n"
"│ dict(mapping) -> new dictionary initialized │\n"
"│ from a mapping object's │\n"
"│ (key, value) pairs │\n"
"│ dict(iterable) -> new dictionary initialized │\n"
"│ as if via: │\n"
"│ d = {}\n"
"│ for k, v in iterable: │\n"
"│ d[k] = v │\n"
"│ dict(**kwargs) -> new dictionary initialized │\n"
"│ with the name=value pairs │\n"
"│ in the keyword argument list. For │\n"
"│ example: dict(one=1, two=2) │\n"
"│ │\n"
)
2020-10-07 09:59:53 +00:00
assert render({}).startswith(expected)
2020-09-20 23:02:49 +00:00
def test_inspect_builtin_function():
expected = (
"╭────────── <built-in function print> ───────────╮\n"
"│ def print(...) │\n"
"│ │\n"
"│ print(value, ..., sep=' ', end='\\n', │\n"
"│ file=sys.stdout, flush=False) │\n"
"│ │\n"
2020-12-29 15:43:57 +00:00
"│ 29 attribute(s) not shown. Run │\n"
"│ inspect(inspect) for options. │\n"
2020-09-20 23:02:49 +00:00
"╰────────────────────────────────────────────────╯\n"
)
assert expected == render(print)
2020-09-20 23:15:17 +00:00
@skip_py36
2020-09-20 23:02:49 +00:00
def test_inspect_integer():
expected = (
"╭────── <class 'int'> ───────╮\n"
"│ int([x]) -> integer │\n"
"│ int(x, base=10) -> integer │\n"
"│ │\n"
"│ denominator = 1 │\n"
"│ imag = 0 │\n"
"│ numerator = 1 │\n"
"│ real = 1 │\n"
"╰────────────────────────────╯\n"
)
assert expected == render(1)
2020-12-29 15:43:57 +00:00
@skip_py36
def test_inspect_integer_with_value():
2020-12-30 15:21:48 +00:00
expected = "╭────── <class 'int'> ───────╮\n│ int([x]) -> integer │\n│ int(x, base=10) -> integer │\n│ │\n│ ╭────────────────────────╮ │\n│ │ 1 │ │\n│ ╰────────────────────────╯ │\n│ │\n│ denominator = 1 │\n│ imag = 0 │\n│ numerator = 1 │\n│ real = 1 │\n╰────────────────────────────╯\n"
value = render(1, value=True)
print(repr(value))
assert expected == value
2020-12-29 15:43:57 +00:00
2020-09-20 23:15:17 +00:00
@skip_py36
@skip_py37
2020-09-20 23:02:49 +00:00
def test_inspect_integer_with_methods():
expected = (
"╭──────────────── <class 'int'> ─────────────────╮\n"
"│ int([x]) -> integer │\n"
"│ int(x, base=10) -> integer │\n"
"│ │\n"
"│ denominator = 1 │\n"
"│ imag = 0 │\n"
"│ numerator = 1 │\n"
"│ real = 1 │\n"
"│ as_integer_ratio = def as_integer_ratio(): │\n"
"│ Return integer ratio. │\n"
"│ bit_length = def bit_length(): Number of │\n"
"│ bits necessary to represent │\n"
"│ self in binary. │\n"
"│ conjugate = def conjugate(...) Returns │\n"
"│ self, the complex conjugate │\n"
"│ of any int. │\n"
"│ from_bytes = def from_bytes(bytes, │\n"
"│ byteorder, *, │\n"
"│ signed=False): Return the │\n"
"│ integer represented by the │\n"
"│ given array of bytes. │\n"
"│ to_bytes = def to_bytes(length, │\n"
"│ byteorder, *, │\n"
"│ signed=False): Return an │\n"
"│ array of bytes representing │\n"
"│ an integer. │\n"
"╰────────────────────────────────────────────────╯\n"
)
assert expected == render(1, methods=True)
2021-01-13 16:51:38 +00:00
@skip_py36
@skip_py37
def test_broken_call_attr():
class NotCallable:
__call__ = 5 # Passes callable() but isn't really callable
def __repr__(self):
return "NotCallable()"
class Foo:
foo = NotCallable()
foo = Foo()
assert callable(foo.foo)
expected = "╭─ <class 'tests.test_inspect.test_broken_call_attr.<locals>.Foo'> ─╮\n│ foo = NotCallable() │\n╰───────────────────────────────────────────────────────────────────╯\n"
result = render(foo, methods=True, width=100)
print(repr(result))
assert expected == result