AST-aware, stdlib-only static checks: swallowed-exception-around-write (C1), undefined-name (C2), hardcoded-secret-literal (C3), fail-open-flag (C4), rotated-secret-captured-once (C5). Tests + CI + examples included. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
49 lines
1.4 KiB
Python
49 lines
1.4 KiB
Python
"""Smoke tests: the buggy fixture trips each check; the clean fixture trips none."""
|
|
import os
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from bugclass_detectors import run # noqa: E402
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
EX = os.path.join(HERE, "..", "examples")
|
|
BUGGY = os.path.join(EX, "buggy_sample.py")
|
|
CLEAN = os.path.join(EX, "clean_sample.py")
|
|
|
|
|
|
def _checks(findings):
|
|
return {f["check"].split("_")[0] for f in findings}
|
|
|
|
|
|
def test_buggy_trips_each_class():
|
|
found = _checks(run([BUGGY]))
|
|
for cid in ("C1", "C2", "C3", "C4", "C5"):
|
|
assert cid in found, f"{cid} should have fired on the buggy fixture; got {found}"
|
|
|
|
|
|
def test_clean_has_no_findings():
|
|
findings = run([CLEAN])
|
|
assert findings == [], f"clean fixture should be silent, got: {findings}"
|
|
|
|
|
|
def test_disable_env_suppresses_check():
|
|
os.environ["BUGCLASS_DISABLE"] = "C1,C2,C3,C4,C5"
|
|
try:
|
|
assert run([BUGGY]) == []
|
|
finally:
|
|
del os.environ["BUGCLASS_DISABLE"]
|
|
|
|
|
|
def test_finding_shape():
|
|
for f in run([BUGGY]):
|
|
assert set(f) == {"check", "severity", "file", "lineno", "snippet", "why"}
|
|
assert f["severity"] in ("HIGH", "MED", "LOW")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
test_buggy_trips_each_class()
|
|
test_clean_has_no_findings()
|
|
test_disable_env_suppresses_check()
|
|
test_finding_shape()
|
|
print("all tests passed")
|