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
|
"""Test the autodoc extension."""
from __future__ import annotations
import abc
import sys
from importlib import import_module
from typing import TypeVar
import pytest
from sphinx.ext.autodoc.mock import _MockModule, _MockObject, ismock, mock, undecorate
def test_MockModule() -> None:
mock = _MockModule('mocked_module')
assert isinstance(mock.some_attr, _MockObject)
assert isinstance(mock.some_method, _MockObject)
assert isinstance(mock.attr1.attr2, _MockObject)
assert isinstance(mock.attr1.attr2.meth(), _MockObject)
assert repr(mock.some_attr) == 'mocked_module.some_attr'
assert repr(mock.some_method) == 'mocked_module.some_method'
assert repr(mock.attr1.attr2) == 'mocked_module.attr1.attr2'
assert repr(mock.attr1.attr2.meth) == 'mocked_module.attr1.attr2.meth'
assert repr(mock) == 'mocked_module'
def test_MockObject():
mock = _MockObject()
assert isinstance(mock.some_attr, _MockObject)
assert isinstance(mock.some_method, _MockObject)
assert isinstance(mock.attr1.attr2, _MockObject)
assert isinstance(mock.attr1.attr2.meth(), _MockObject)
# subclassing
class SubClass(mock.SomeClass):
"""docstring of SubClass"""
def method(self):
return 'string'
obj = SubClass()
assert SubClass.__doc__ == 'docstring of SubClass'
assert isinstance(obj, SubClass)
assert obj.method() == 'string'
assert isinstance(obj.other_method(), SubClass)
# parametrized type
T = TypeVar('T')
class SubClass2(mock.SomeClass[T]):
"""docstring of SubClass"""
obj2 = SubClass2()
assert SubClass2.__doc__ == 'docstring of SubClass'
assert isinstance(obj2, SubClass2)
def test_mock() -> None:
modname = 'sphinx.unknown'
submodule = modname + '.submodule'
assert modname not in sys.modules
with pytest.raises(ImportError):
import_module(modname)
with mock([modname]):
import_module(modname)
assert modname in sys.modules
assert isinstance(sys.modules[modname], _MockModule)
# submodules are also mocked
import_module(submodule)
assert submodule in sys.modules
assert isinstance(sys.modules[submodule], _MockModule)
assert modname not in sys.modules
with pytest.raises(ImportError):
import_module(modname)
def test_mock_does_not_follow_upper_modules() -> None:
with mock(['sphinx.unknown.module']): # NoQA: SIM117
with pytest.raises(ImportError):
import_module('sphinx.unknown')
def test_abc_MockObject():
mock = _MockObject()
class Base:
@abc.abstractmethod
def __init__(self):
pass
class Derived(Base, mock.SubClass):
pass
obj = Derived()
assert isinstance(obj, Base)
assert isinstance(obj, _MockObject)
assert isinstance(obj.some_method(), Derived)
def test_mock_decorator():
mock = _MockObject()
@mock.function_deco
def func():
pass
class Foo:
@mock.method_deco
def meth(self):
pass
@classmethod
@mock.method_deco
def class_meth(cls):
pass
@mock.class_deco
class Bar:
pass
@mock.funcion_deco(Foo)
class Baz:
pass
assert undecorate(func).__name__ == 'func'
assert undecorate(Foo.meth).__name__ == 'meth'
assert undecorate(Foo.class_meth).__name__ == 'class_meth'
assert undecorate(Bar).__name__ == 'Bar'
assert undecorate(Baz).__name__ == 'Baz'
def test_ismock():
with mock(['sphinx.unknown']):
mod1 = import_module('sphinx.unknown')
mod2 = import_module('sphinx.application')
class Inherited(mod1.Class):
pass
assert ismock(mod1) is True
assert ismock(mod1.Class) is True
assert ismock(mod1.submod.Class) is True
assert ismock(Inherited) is False
assert ismock(mod2) is False
assert ismock(mod2.Sphinx) is False
|