Skip to content

Commit 1e003ed

Browse files
Cover previously-untested dunder methods and edge cases in symilar
Adds focused tests for `LineSetStartCouple.__eq__` NotImplemented branch, `LineSet.__str__` / `__getitem__` / non-LineSet `__eq__`, `append_stream` binary-without-encoding and UnicodeDecodeError paths, `report_similarities` table building, and the `process_module` deprecation warning when `linter.current_name` is None. Takes symilar.py from 96% to 99% coverage. The remaining gaps are an unreachable defensive `except KeyError` in `remove_successive` and the `if __name__ == "__main__"` guard.
1 parent a8bef0e commit 1e003ed

1 file changed

Lines changed: 75 additions & 1 deletion

File tree

tests/checkers/unittest_symilar.py

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@
33
# Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt
44

55
from contextlib import redirect_stdout
6-
from io import StringIO
6+
from io import BytesIO, StringIO
77
from pathlib import Path
88

9+
import astroid
910
import pytest
1011
from _pytest.capture import CaptureFixture
1112

1213
from pylint.checkers import symilar
14+
from pylint.checkers.symilar import LineSet, LineSetStartCouple, Symilar
1315
from pylint.lint import PyLinter
16+
from pylint.reporters.ureports.nodes import Section, Table
1417
from pylint.testutils import GenericTestReporter as Reporter
18+
from pylint.utils import LinterStats
1519

1620
INPUT = Path(__file__).parent / ".." / "input"
1721
SIMILAR1 = str(INPUT / "similar1")
@@ -472,6 +476,76 @@ def test_bad_short_form_option(capsys: CaptureFixture) -> None:
472476
assert "unrecognized arguments: -j=0" in err
473477

474478

479+
def test_line_set_start_couple_eq_non_couple() -> None:
480+
"""``LineSetStartCouple.__eq__`` returns ``NotImplemented`` against an
481+
object that isn't a ``LineSetStartCouple`` so Python falls back to
482+
reflected comparison.
483+
"""
484+
couple = LineSetStartCouple(symilar.Index(0), symilar.Index(1))
485+
assert couple != object()
486+
# pylint: disable-next=unnecessary-dunder-call
487+
assert couple.__eq__(object()) is NotImplemented
488+
489+
490+
def test_line_set_dunder_methods() -> None:
491+
"""Cover LineSet ``__str__``, ``__getitem__`` and non-LineSet ``__eq__``."""
492+
lines = ["a = 1\n", "b = 2\n", "c = 3\n"]
493+
lineset = LineSet("fake.py", lines)
494+
assert str(lineset) == "<Lineset for fake.py>"
495+
assert lineset[0].text == "a = 1"
496+
assert (lineset == "not a lineset") is False
497+
498+
499+
def test_append_stream_binary_requires_encoding() -> None:
500+
"""``append_stream`` raises ValueError when a binary stream is passed
501+
without an encoding.
502+
"""
503+
runner = Symilar()
504+
with pytest.raises(ValueError):
505+
runner.append_stream("bin.py", BytesIO(b"a = 1\n"))
506+
507+
508+
def test_report_similarities_builds_table() -> None:
509+
"""``report_similarities`` appends a stats table to the given section."""
510+
stats = LinterStats()
511+
stats.reset_duplicated_lines()
512+
section = Section()
513+
symilar.report_similarities(section, stats, None)
514+
assert len(section.children) == 1
515+
assert isinstance(section.children[0], Table)
516+
517+
518+
def test_process_module_warns_when_current_name_is_none(tmp_path: Path) -> None:
519+
"""``SimilaritiesChecker.process_module`` warns when
520+
``linter.current_name`` is None (the deprecated state).
521+
"""
522+
linter = PyLinter(reporter=Reporter())
523+
linter.register_checker(symilar.SimilaritiesChecker(linter))
524+
checker = symilar.SimilaritiesChecker(linter)
525+
linter.current_name = None # type: ignore[assignment]
526+
module_file = tmp_path / "m.py"
527+
module_file.write_text("a = 1\n")
528+
529+
module = astroid.parse(module_file.read_text(), module_name="m")
530+
module.file = str(module_file)
531+
module.file_bytes = module_file.read_bytes()
532+
with pytest.warns(DeprecationWarning, match="current_name attribute"):
533+
checker.process_module(module)
534+
535+
536+
def test_append_stream_unicode_error_yields_empty_lineset(tmp_path: Path) -> None:
537+
"""``append_stream`` swallows ``UnicodeDecodeError`` and treats the file
538+
as empty rather than crashing.
539+
"""
540+
bad_file = tmp_path / "bad.py"
541+
bad_file.write_bytes(b"\xff\xfe\xfa not valid utf-8\n")
542+
runner = Symilar()
543+
with bad_file.open("rb") as stream:
544+
runner.append_stream(str(bad_file), stream, encoding="utf-8")
545+
assert len(runner.linesets) == 1
546+
assert runner.linesets[0].stripped_lines == []
547+
548+
475549
def test_hash_bucket_product_limit_fallback(
476550
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
477551
) -> None:

0 commit comments

Comments
 (0)