import json from scripts.adapters.interrogate import parse_interrogate_output def test_parses_missing_public_docstring(): payload = { "files": { "src/foo.py": { "missing": [ {"name": "src/foo.py:my_public_fn", "type": "function", "lineno": 12, "private": False} ] } } } findings = parse_interrogate_output(json.dumps(payload)) assert len(findings) == 1 f = findings[0] assert f.tool == "interrogate" assert f.file == "src/foo.py" assert f.line == 12 assert "my_public_fn" in f.message assert f.rule_id == "interrogate:missing-docstring" def test_skips_private_symbol(): payload = { "files": { "src/foo.py": { "missing": [ {"name": "src/foo.py:_helper", "type": "function", "lineno": 30, "private": True} ] } } } assert parse_interrogate_output(json.dumps(payload)) == [] def test_skips_underscore_named_symbol_even_if_private_false(): payload = { "files": { "src/foo.py": { "missing": [ {"name": "src/foo.py:_internal", "type": "function", "lineno": 5, "private": False} ] } } } assert parse_interrogate_output(json.dumps(payload)) == [] def test_low_severity_always(): payload = { "files": { "src/foo.py": { "missing": [ {"name": "src/foo.py:pub_fn", "type": "function", "lineno": 1, "private": False} ] } } } findings = parse_interrogate_output(json.dumps(payload)) assert findings[0].severity == "low" def test_empty_or_malformed_input(): assert parse_interrogate_output("") == [] assert parse_interrogate_output("not json") == [] assert parse_interrogate_output("{}") == []