Files
2026-07-13 13:22:34 +08:00

203 lines
6.0 KiB
Python

from pathlib import Path
from clint.config import Config
from clint.index import SymbolIndex
from clint.linter import Position, Range, lint_file
from clint.rules.nested_mock_patch import NestedMockPatch
def test_nested_mock_patch_unittest_mock(index: SymbolIndex) -> None:
code = """
import unittest.mock
def test_foo():
with unittest.mock.patch("foo.bar"):
with unittest.mock.patch("foo.baz"):
...
"""
config = Config(select={NestedMockPatch.name})
violations = lint_file(Path("test_nested_mock_patch.py"), code, config, index)
assert len(violations) == 1
assert all(isinstance(v.rule, NestedMockPatch) for v in violations)
assert violations[0].range == Range(Position(4, 4))
def test_nested_mock_patch_from_unittest_import_mock(index: SymbolIndex) -> None:
code = """
from unittest import mock
def test_foo():
with mock.patch("foo.bar"):
with mock.patch("foo.baz"):
...
"""
config = Config(select={NestedMockPatch.name})
violations = lint_file(Path("test_nested_mock_patch.py"), code, config, index)
assert len(violations) == 1
assert all(isinstance(v.rule, NestedMockPatch) for v in violations)
assert violations[0].range == Range(Position(4, 4))
def test_nested_mock_patch_object(index: SymbolIndex) -> None:
code = """
from unittest import mock
def test_foo():
with mock.patch.object(SomeClass, "method"):
with mock.patch.object(AnotherClass, "method"):
...
"""
config = Config(select={NestedMockPatch.name})
violations = lint_file(Path("test_nested_mock_patch.py"), code, config, index)
assert len(violations) == 1
assert all(isinstance(v.rule, NestedMockPatch) for v in violations)
assert violations[0].range == Range(Position(4, 4))
def test_nested_mock_patch_dict(index: SymbolIndex) -> None:
code = """
from unittest import mock
def test_foo():
with mock.patch.dict("os.environ", {"FOO": "bar"}):
with mock.patch.dict("os.environ", {"BAZ": "qux"}):
...
"""
config = Config(select={NestedMockPatch.name})
violations = lint_file(Path("test_nested_mock_patch.py"), code, config, index)
assert len(violations) == 1
assert all(isinstance(v.rule, NestedMockPatch) for v in violations)
assert violations[0].range == Range(Position(4, 4))
def test_nested_mock_patch_mixed(index: SymbolIndex) -> None:
code = """
from unittest import mock
def test_foo():
with mock.patch("foo.bar"):
with mock.patch.object(SomeClass, "method"):
...
"""
config = Config(select={NestedMockPatch.name})
violations = lint_file(Path("test_nested_mock_patch.py"), code, config, index)
assert len(violations) == 1
assert all(isinstance(v.rule, NestedMockPatch) for v in violations)
assert violations[0].range == Range(Position(4, 4))
def test_multiple_context_managers_is_ok(index: SymbolIndex) -> None:
code = """
from unittest import mock
def test_foo():
with mock.patch("foo.bar"), mock.patch("foo.baz"):
...
"""
config = Config(select={NestedMockPatch.name})
violations = lint_file(Path("test_nested_mock_patch.py"), code, config, index)
assert len(violations) == 0
def test_multiple_context_managers_with_object_is_ok(index: SymbolIndex) -> None:
code = """
from unittest import mock
def test_foo():
with mock.patch("foo.bar"), mock.patch.object(SomeClass, "method"):
...
"""
config = Config(select={NestedMockPatch.name})
violations = lint_file(Path("test_nested_mock_patch.py"), code, config, index)
assert len(violations) == 0
def test_nested_with_but_not_mock_patch_is_ok(index: SymbolIndex) -> None:
code = """
def test_foo():
with open("file.txt"):
with open("file2.txt"):
...
"""
config = Config(select={NestedMockPatch.name})
violations = lint_file(Path("test_nested_mock_patch.py"), code, config, index)
assert len(violations) == 0
def test_nested_with_only_one_mock_patch_is_ok(index: SymbolIndex) -> None:
code = """
from unittest import mock
def test_foo():
with mock.patch("foo.bar"):
with open("file.txt"):
...
"""
config = Config(select={NestedMockPatch.name})
violations = lint_file(Path("test_nested_mock_patch.py"), code, config, index)
assert len(violations) == 0
def test_non_nested_mock_patches_are_ok(index: SymbolIndex) -> None:
code = """
from unittest import mock
def test_foo():
with mock.patch("foo.bar"):
pass
with mock.patch("foo.baz"):
pass
"""
config = Config(select={NestedMockPatch.name})
violations = lint_file(Path("test_nested_mock_patch.py"), code, config, index)
assert len(violations) == 0
def test_non_test_file_not_checked(index: SymbolIndex) -> None:
code = """
from unittest import mock
def foo():
with mock.patch("foo.bar"):
with mock.patch("foo.baz"):
...
"""
config = Config(select={NestedMockPatch.name})
violations = lint_file(Path("nested_mock_patch.py"), code, config, index)
assert len(violations) == 0
def test_nested_with_code_after_is_ok(index: SymbolIndex) -> None:
code = """
from unittest import mock
def test_foo():
with mock.patch("foo.bar"):
with mock.patch("foo.baz"):
...
assert True
"""
config = Config(select={NestedMockPatch.name})
violations = lint_file(Path("test_nested_mock_patch.py"), code, config, index)
assert len(violations) == 0
def test_deeply_nested_mock_patch(index: SymbolIndex) -> None:
code = """
from unittest import mock
def test_foo():
with mock.patch("foo.bar"):
with mock.patch("foo.baz"):
with mock.patch("foo.qux"):
...
"""
config = Config(select={NestedMockPatch.name})
violations = lint_file(Path("test_nested_mock_patch.py"), code, config, index)
# Should detect both levels of nesting
assert len(violations) == 2
assert all(isinstance(v.rule, NestedMockPatch) for v in violations)
assert violations[0].range == Range(Position(4, 4))
assert violations[1].range == Range(Position(5, 8))