This commit is contained in:
ton
2024-10-07 10:13:40 +07:00
parent aa1631742f
commit 3a7d696db6
9729 changed files with 1832837 additions and 161742 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+19 -5
View File
@@ -84,9 +84,13 @@ class TestLoader(object):
raise TypeError("Test cases should not be derived from "
"TestSuite. Maybe you meant to derive from "
"TestCase?")
testCaseNames = self.getTestCaseNames(testCaseClass)
if not testCaseNames and hasattr(testCaseClass, 'runTest'):
testCaseNames = ['runTest']
if testCaseClass in (case.TestCase, case.FunctionTestCase):
# We don't load any tests from base types that should not be loaded.
testCaseNames = []
else:
testCaseNames = self.getTestCaseNames(testCaseClass)
if not testCaseNames and hasattr(testCaseClass, 'runTest'):
testCaseNames = ['runTest']
loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
return loaded_suite
@@ -95,7 +99,11 @@ class TestLoader(object):
tests = []
for name in dir(module):
obj = getattr(module, name)
if isinstance(obj, type) and issubclass(obj, case.TestCase):
if (
isinstance(obj, type)
and issubclass(obj, case.TestCase)
and obj not in (case.TestCase, case.FunctionTestCase)
):
tests.append(self.loadTestsFromTestCase(obj))
load_tests = getattr(module, 'load_tests', None)
@@ -164,7 +172,11 @@ class TestLoader(object):
if isinstance(obj, types.ModuleType):
return self.loadTestsFromModule(obj)
elif isinstance(obj, type) and issubclass(obj, case.TestCase):
elif (
isinstance(obj, type)
and issubclass(obj, case.TestCase)
and obj not in (case.TestCase, case.FunctionTestCase)
):
return self.loadTestsFromTestCase(obj)
elif (isinstance(obj, types.FunctionType) and
isinstance(parent, type) and
@@ -242,6 +254,7 @@ class TestLoader(object):
Paths are sorted before being imported to ensure reproducible execution
order even on filesystems with non-alphabetical ordering like ext3/4.
"""
original_top_level_dir = self._top_level_dir
set_implicit_top = False
if top_level_dir is None and self._top_level_dir is not None:
# make top_level_dir optional if called from load_tests in a package
@@ -295,6 +308,7 @@ class TestLoader(object):
raise ImportError('Start directory is not importable: %r' % start_dir)
tests = list(self._find_tests(start_dir, pattern))
self._top_level_dir = original_top_level_dir
return self.suiteClass(tests)
def _get_directory_containing_module(self, module_name):
+1 -1
View File
@@ -280,7 +280,7 @@ class TestProgram(object):
testRunner = self.testRunner
self.result = testRunner.run(self.test)
if self.exit:
if self.result.testsRun == 0:
if self.result.testsRun == 0 and len(self.result.skipped) == 0:
sys.exit(_NO_TESTS_EXITCODE)
elif self.result.wasSuccessful():
sys.exit(0)
+66 -28
View File
@@ -543,7 +543,7 @@ class NonCallableMock(Base):
if self._mock_delegate is not None:
ret = self._mock_delegate.return_value
if ret is DEFAULT:
if ret is DEFAULT and self._mock_wraps is None:
ret = self._get_child_mock(
_new_parent=self, _new_name='()'
)
@@ -598,7 +598,9 @@ class NonCallableMock(Base):
side_effect = property(__get_side_effect, __set_side_effect)
def reset_mock(self, visited=None,*, return_value=False, side_effect=False):
def reset_mock(self, visited=None, *,
return_value: bool = False,
side_effect: bool = False):
"Restore the mock object to its initial state."
if visited is None:
visited = []
@@ -800,6 +802,9 @@ class NonCallableMock(Base):
mock_name = f'{self._extract_mock_name()}.{name}'
raise AttributeError(f'Cannot set {mock_name}')
if isinstance(value, PropertyMock):
self.__dict__[name] = value
return
return object.__setattr__(self, name, value)
@@ -827,7 +832,7 @@ class NonCallableMock(Base):
def _format_mock_failure_message(self, args, kwargs, action='call'):
message = 'expected %s not found.\nExpected: %s\nActual: %s'
message = 'expected %s not found.\nExpected: %s\n Actual: %s'
expected_string = self._format_mock_call_signature(args, kwargs)
call_args = self.call_args
actual_string = self._format_mock_call_signature(*call_args)
@@ -930,7 +935,7 @@ class NonCallableMock(Base):
if self.call_args is None:
expected = self._format_mock_call_signature(args, kwargs)
actual = 'not called.'
error_message = ('expected call not found.\nExpected: %s\nActual: %s'
error_message = ('expected call not found.\nExpected: %s\n Actual: %s'
% (expected, actual))
raise AssertionError(error_message)
@@ -981,7 +986,7 @@ class NonCallableMock(Base):
raise AssertionError(
f'{problem}\n'
f'Expected: {_CallList(calls)}'
f'{self._calls_repr(prefix="Actual").rstrip(".")}'
f'{self._calls_repr(prefix=" Actual").rstrip(".")}'
) from cause
return
@@ -1204,6 +1209,9 @@ class CallableMixin(Base):
if self._mock_return_value is not DEFAULT:
return self.return_value
if self._mock_delegate and self._mock_delegate.return_value is not DEFAULT:
return self.return_value
if self._mock_wraps is not None:
return self._mock_wraps(*args, **kwargs)
@@ -1475,13 +1483,12 @@ class _patch(object):
if isinstance(original, type):
# If we're patching out a class and there is a spec
inherit = True
if spec is None and _is_async_obj(original):
Klass = AsyncMock
else:
Klass = MagicMock
_kwargs = {}
# Determine the Klass to use
if new_callable is not None:
Klass = new_callable
elif spec is None and _is_async_obj(original):
Klass = AsyncMock
elif spec is not None or spec_set is not None:
this_spec = spec
if spec_set is not None:
@@ -1494,7 +1501,12 @@ class _patch(object):
Klass = AsyncMock
elif not_callable:
Klass = NonCallableMagicMock
else:
Klass = MagicMock
else:
Klass = MagicMock
_kwargs = {}
if spec is not None:
_kwargs['spec'] = spec
if spec_set is not None:
@@ -2179,6 +2191,17 @@ class MagicMock(MagicMixin, Mock):
self._mock_add_spec(spec, spec_set)
self._mock_set_magics()
def reset_mock(self, /, *args, return_value: bool = False, **kwargs):
if (
return_value
and self._mock_name
and _is_magic(self._mock_name)
):
# Don't reset return values for magic methods,
# otherwise `m.__str__` will start
# to return `MagicMock` instances, instead of `str` instances.
return_value = False
super().reset_mock(*args, return_value=return_value, **kwargs)
class MagicProxy(Base):
@@ -2199,8 +2222,11 @@ class MagicProxy(Base):
return self.create_mock()
_CODE_ATTRS = dir(CodeType)
_CODE_SIG = inspect.signature(partial(CodeType.__init__, None))
try:
_CODE_SIG = inspect.signature(partial(CodeType.__init__, None))
_CODE_ATTRS = dir(CodeType)
except ValueError:
_CODE_SIG = None
class AsyncMockMixin(Base):
@@ -2220,9 +2246,12 @@ class AsyncMockMixin(Base):
self.__dict__['_mock_await_count'] = 0
self.__dict__['_mock_await_args'] = None
self.__dict__['_mock_await_args_list'] = _CallList()
code_mock = NonCallableMock(spec_set=_CODE_ATTRS)
code_mock.__dict__["_spec_class"] = CodeType
code_mock.__dict__["_spec_signature"] = _CODE_SIG
if _CODE_SIG:
code_mock = NonCallableMock(spec_set=_CODE_ATTRS)
code_mock.__dict__["_spec_class"] = CodeType
code_mock.__dict__["_spec_signature"] = _CODE_SIG
else:
code_mock = NonCallableMock(spec_set=CodeType)
code_mock.co_flags = (
inspect.CO_COROUTINE
+ inspect.CO_VARARGS
@@ -2709,6 +2738,12 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
if not unsafe:
_check_spec_arg_typos(kwargs)
_name = kwargs.pop('name', _name)
_new_name = _name
if _parent is None:
# for a top level object no _new_name should be set
_new_name = ''
_kwargs.update(kwargs)
Klass = MagicMock
@@ -2726,13 +2761,6 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
elif is_type and instance and not _instance_callable(spec):
Klass = NonCallableMagicMock
_name = _kwargs.pop('name', _name)
_new_name = _name
if _parent is None:
# for a top level object no _new_name should be set
_new_name = ''
mock = Klass(parent=_parent, _new_parent=_parent, _new_name=_new_name,
name=_name, **_kwargs)
@@ -2748,9 +2776,12 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
if _parent is not None and not instance:
_parent._mock_children[_name] = mock
# Pop wraps from kwargs because it must not be passed to configure_mock.
wrapped = kwargs.pop('wraps', None)
if is_type and not instance and 'return_value' not in kwargs:
mock.return_value = create_autospec(spec, spec_set, instance=True,
_name='()', _parent=mock)
_name='()', _parent=mock,
wraps=wrapped)
for entry in dir(spec):
if _is_magic(entry):
@@ -2771,9 +2802,12 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
except AttributeError:
continue
kwargs = {'spec': original}
child_kwargs = {'spec': original}
# Wrap child attributes also.
if wrapped and hasattr(wrapped, entry):
child_kwargs.update(wraps=original)
if spec_set:
kwargs = {'spec_set': original}
child_kwargs = {'spec_set': original}
if not isinstance(original, FunctionTypes):
new = _SpecState(original, spec_set, mock, entry, instance)
@@ -2784,14 +2818,13 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
parent = mock.mock
skipfirst = _must_skip(spec, entry, is_type)
kwargs['_eat_self'] = skipfirst
child_kwargs['_eat_self'] = skipfirst
if iscoroutinefunction(original):
child_klass = AsyncMock
else:
child_klass = MagicMock
new = child_klass(parent=parent, name=entry, _new_name=entry,
_new_parent=parent,
**kwargs)
_new_parent=parent, **child_kwargs)
mock._mock_children[entry] = new
new.return_value = child_klass()
_check_signature(original, new, skipfirst=skipfirst)
@@ -2802,6 +2835,11 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
# setting as an instance attribute?
if isinstance(new, FunctionTypes):
setattr(mock, entry, new)
# kwargs are passed with respect to the parent mock so, they are not used
# for creating return_value of the parent mock. So, this condition
# should be true only for the parent mock if kwargs are given.
if _is_instance_mock(mock) and kwargs:
mock.configure_mock(**kwargs)
return mock
+1 -1
View File
@@ -274,7 +274,7 @@ class TextTestRunner(object):
infos.append("failures=%d" % failed)
if errored:
infos.append("errors=%d" % errored)
elif run == 0:
elif run == 0 and not skipped:
self.stream.write("NO TESTS RAN")
else:
self.stream.write("OK")