Files
example-code-2e/17-it-generator/tree/classtree/classtree_test.py
Luciano Ramalho f5e3cb8ad3 minor refactorings
2021-10-22 14:59:04 -03:00

182 lines
4.4 KiB
Python

from textwrap import dedent
from typing import SupportsBytes
from classtree import tree, render_lines, main, subclasses
from abc import ABCMeta
def test_subclasses():
result = subclasses(UnicodeError)
assert set(result) >= {UnicodeEncodeError, UnicodeDecodeError}
def test_subclasses_of_type():
"""
The `type` class is a special case because `type.__subclasses__()`
is an unbound method when called on it, so we must call it as
`type.__subclasses__(type)` just for `type`.
This test does not verify the full list of results, but just
checks that `abc.ABCMeta` is included, because that's the only
subclass of `type` (i.e. metaclass) I we get when I run
`$ classtree.py type` at the command line.
However, the Python console and `pytest` both load other modules,
so `subclasses` may find more subclasses of `type`—for example,
`enum.EnumMeta`.
"""
result = subclasses(type)
assert ABCMeta in result
def test_tree_1_level():
result = list(tree(TabError))
assert result == [(TabError, 0, True)]
def test_tree_2_levels():
result = list(tree(IndentationError))
assert result == [
(IndentationError, 0, True),
(TabError, 1, True),
]
def test_render_lines_1_level():
result = list(render_lines(tree(TabError)))
assert result == ['TabError']
def test_render_lines_2_levels_1_leaf():
result = list(render_lines(tree(IndentationError)))
expected = [
'IndentationError',
'└── TabError',
]
assert expected == result
def test_render_lines_3_levels_1_leaf():
class X: pass
class Y(X): pass
class Z(Y): pass
result = list(render_lines(tree(X)))
expected = [
'X',
'└── Y',
' └── Z',
]
assert expected == result
def test_render_lines_4_levels_1_leaf():
class Level0: pass
class Level1(Level0): pass
class Level2(Level1): pass
class Level3(Level2): pass
result = list(render_lines(tree(Level0)))
expected = [
'Level0',
'└── Level1',
' └── Level2',
' └── Level3',
]
assert expected == result
def test_render_lines_2_levels_2_leaves():
class Branch: pass
class Leaf1(Branch): pass
class Leaf2(Branch): pass
result = list(render_lines(tree(Branch)))
expected = [
'Branch',
'├── Leaf1',
'└── Leaf2',
]
assert expected == result
def test_render_lines_3_levels_2_leaves_dedent():
class A: pass
class B(A): pass
class C(B): pass
class D(A): pass
class E(D): pass
result = list(render_lines(tree(A)))
expected = [
'A',
'├── B',
'│ └── C',
'└── D',
' └── E',
]
assert expected == result
def test_render_lines_4_levels_4_leaves_dedent():
class A: pass
class B1(A): pass
class C1(B1): pass
class D1(C1): pass
class D2(C1): pass
class C2(B1): pass
class B2(A): pass
expected = [
'A',
'├── B1',
'│ ├── C1',
'│ │ ├── D1',
'│ │ └── D2',
'│ └── C2',
'└── B2',
]
result = list(render_lines(tree(A)))
assert expected == result
def test_main_simple(capsys):
main('IndentationError')
expected = dedent("""
IndentationError
└── TabError
""").lstrip()
captured = capsys.readouterr()
assert captured.out == expected
def test_main_dotted(capsys):
main('collections.abc.Sequence')
expected = dedent("""
Sequence
├── ByteString
├── MutableSequence
│ └── UserList
""").lstrip()
captured = capsys.readouterr()
assert captured.out.startswith(expected)
def test_main_class_not_found(capsys):
main('NoSuchClass')
expected = "*** 'NoSuchClass' not found in 'builtins'.\n"
captured = capsys.readouterr()
assert captured.out == expected
def test_main_module_not_found(capsys):
main('nosuch.module')
expected = "*** Could not import 'nosuch'.\n"
captured = capsys.readouterr()
assert captured.out == expected
def test_main_not_a_class(capsys):
main('collections.abc')
expected = "*** 'abc' is not a class.\n"
captured = capsys.readouterr()
assert captured.out == expected