2018-05-20 09:55:36 -05:00
|
|
|
"""
|
|
|
|
Test the autodoc extension.
|
|
|
|
|
2022-01-01 03:45:03 -06:00
|
|
|
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
2018-05-20 09:55:36 -05:00
|
|
|
:license: BSD, see LICENSE for details.
|
|
|
|
"""
|
|
|
|
|
2019-02-01 10:04:13 -06:00
|
|
|
import abc
|
2018-12-04 07:49:53 -06:00
|
|
|
import sys
|
2019-08-17 13:45:39 -05:00
|
|
|
from importlib import import_module
|
2020-06-29 11:16:38 -05:00
|
|
|
from typing import TypeVar
|
2018-12-04 07:49:53 -06:00
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
2021-01-23 11:08:19 -06:00
|
|
|
from sphinx.ext.autodoc.mock import _MockModule, _MockObject, ismock, mock, undecorate
|
2018-05-20 09:55:36 -05:00
|
|
|
|
|
|
|
|
2019-02-10 10:38:26 -06:00
|
|
|
def test_MockModule():
|
2019-03-29 09:52:32 -05:00
|
|
|
mock = _MockModule('mocked_module')
|
2019-02-10 10:38:26 -06:00
|
|
|
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'
|
2018-05-20 09:55:36 -05:00
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
2020-06-29 11:16:38 -05:00
|
|
|
# subclassing
|
2018-05-20 09:55:36 -05:00
|
|
|
class SubClass(mock.SomeClass):
|
|
|
|
"""docstring of SubClass"""
|
2018-09-07 07:14:01 -05:00
|
|
|
|
2018-05-20 09:55:36 -05:00
|
|
|
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)
|
2018-09-07 07:14:01 -05:00
|
|
|
|
2020-06-29 11:16:38 -05:00
|
|
|
# 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)
|
|
|
|
|
2018-09-07 07:14:01 -05:00
|
|
|
|
2018-12-04 07:49:53 -06:00
|
|
|
def test_mock():
|
|
|
|
modname = 'sphinx.unknown'
|
|
|
|
submodule = modname + '.submodule'
|
|
|
|
assert modname not in sys.modules
|
|
|
|
with pytest.raises(ImportError):
|
2019-08-17 13:45:39 -05:00
|
|
|
import_module(modname)
|
2018-09-07 07:14:01 -05:00
|
|
|
|
2018-12-04 07:49:53 -06:00
|
|
|
with mock([modname]):
|
2019-08-17 13:45:39 -05:00
|
|
|
import_module(modname)
|
2018-12-04 07:49:53 -06:00
|
|
|
assert modname in sys.modules
|
|
|
|
assert isinstance(sys.modules[modname], _MockModule)
|
2018-09-07 07:14:01 -05:00
|
|
|
|
2018-12-04 07:49:53 -06:00
|
|
|
# submodules are also mocked
|
2019-08-17 13:45:39 -05:00
|
|
|
import_module(submodule)
|
2018-12-04 07:49:53 -06:00
|
|
|
assert submodule in sys.modules
|
|
|
|
assert isinstance(sys.modules[submodule], _MockModule)
|
|
|
|
|
|
|
|
assert modname not in sys.modules
|
|
|
|
with pytest.raises(ImportError):
|
2019-08-17 13:45:39 -05:00
|
|
|
import_module(modname)
|
2018-12-04 07:49:53 -06:00
|
|
|
|
|
|
|
|
|
|
|
def test_mock_does_not_follow_upper_modules():
|
|
|
|
with mock(['sphinx.unknown.module']):
|
|
|
|
with pytest.raises(ImportError):
|
2019-08-17 13:45:39 -05:00
|
|
|
import_module('sphinx.unknown')
|
2019-02-03 02:07:13 -06:00
|
|
|
|
|
|
|
|
2019-02-01 10:04:13 -06:00
|
|
|
@pytest.mark.skipif(sys.version_info < (3, 7), reason='Only for py37 or above')
|
|
|
|
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)
|
2019-10-06 09:31:07 -05:00
|
|
|
|
|
|
|
|
|
|
|
def test_mock_decorator():
|
|
|
|
mock = _MockObject()
|
|
|
|
|
|
|
|
@mock.function_deco
|
|
|
|
def func():
|
2021-01-23 11:08:19 -06:00
|
|
|
pass
|
2019-10-06 09:31:07 -05:00
|
|
|
|
|
|
|
class Foo:
|
|
|
|
@mock.method_deco
|
|
|
|
def meth(self):
|
2021-01-23 11:08:19 -06:00
|
|
|
pass
|
2019-10-06 09:31:07 -05:00
|
|
|
|
|
|
|
@mock.class_deco
|
|
|
|
class Bar:
|
2021-01-23 11:08:19 -06:00
|
|
|
pass
|
|
|
|
|
|
|
|
@mock.funcion_deco(Foo)
|
|
|
|
class Baz:
|
|
|
|
pass
|
2019-10-06 09:31:07 -05:00
|
|
|
|
2021-01-23 11:08:19 -06:00
|
|
|
assert undecorate(func).__name__ == "func"
|
|
|
|
assert undecorate(Foo.meth).__name__ == "meth"
|
|
|
|
assert undecorate(Bar).__name__ == "Bar"
|
|
|
|
assert undecorate(Baz).__name__ == "Baz"
|
2020-12-28 06:26:22 -06:00
|
|
|
|
|
|
|
|
|
|
|
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
|
2021-11-25 10:35:40 -06:00
|
|
|
assert ismock(mod1.submod.Class) is True
|
2020-12-28 06:26:22 -06:00
|
|
|
assert ismock(Inherited) is False
|
|
|
|
|
|
|
|
assert ismock(mod2) is False
|
|
|
|
assert ismock(mod2.Sphinx) is False
|