Skip to content

Commit 1793928

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 1793928

1 file changed

Lines changed: 74 additions & 1 deletion

File tree

tests/checkers/unittest_symilar.py

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

0 commit comments

Comments
 (0)