Skip to content

Commit 6513ddd

Browse files
committed
style: format test files for CI compatibility
Run ruff format on 8 test files missed in previous commit. CI checks: contribai/ AND tests/ directories.
1 parent 6623155 commit 6513ddd

8 files changed

Lines changed: 151 additions & 65 deletions

File tree

tests/integration/test_pipeline.py

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -87,32 +87,39 @@ async def test_dry_run_skips_pr_creation(
8787
pipeline._discovery.discover = AsyncMock(return_value=[mock_repo])
8888

8989
pipeline._analyzer = AsyncMock()
90-
pipeline._analyzer.analyze = AsyncMock(return_value=AnalysisResult(
91-
repo=mock_repo,
92-
findings=[sample_finding],
93-
analyzed_files=1,
94-
analysis_duration_sec=0.5,
95-
))
90+
pipeline._analyzer.analyze = AsyncMock(
91+
return_value=AnalysisResult(
92+
repo=mock_repo,
93+
findings=[sample_finding],
94+
analyzed_files=1,
95+
analysis_duration_sec=0.5,
96+
)
97+
)
9698

9799
pipeline._generator = AsyncMock()
98100
pipeline._generator.generate = AsyncMock(return_value=sample_contribution)
99101

100102
pipeline._pr_manager = AsyncMock()
101-
pipeline._pr_manager.create_pr = AsyncMock(return_value=PRResult(
102-
repo=mock_repo,
103-
contribution=sample_contribution,
104-
pr_number=42,
105-
pr_url="https://github.com/test/pr/42",
106-
))
103+
pipeline._pr_manager.create_pr = AsyncMock(
104+
return_value=PRResult(
105+
repo=mock_repo,
106+
contribution=sample_contribution,
107+
pr_number=42,
108+
pr_url="https://github.com/test/pr/42",
109+
)
110+
)
107111

108112
# Use real Memory with tmp_path
109113
from contribai.orchestrator.memory import Memory
114+
110115
pipeline._memory = Memory(pipeline_config.storage.resolved_db_path)
111116
await pipeline._memory.init()
112117

113-
pipeline._github.get_file_tree = AsyncMock(return_value=[
114-
FileNode(path="main.py", type="blob", size=500, sha="abc"),
115-
])
118+
pipeline._github.get_file_tree = AsyncMock(
119+
return_value=[
120+
FileNode(path="main.py", type="blob", size=500, sha="abc"),
121+
]
122+
)
116123
pipeline._github.get_file_content = AsyncMock(return_value="import unused\nprint('hello')")
117124

118125
# Patch _init_components to be a no-op (components already set)
@@ -148,12 +155,15 @@ async def test_analyze_only_mode(self, pipeline_config, mock_repo):
148155
)
149156

150157
pipeline._analyzer = AsyncMock()
151-
pipeline._analyzer.analyze = AsyncMock(return_value=AnalysisResult(
152-
repo=mock_repo,
153-
findings=[finding],
154-
))
158+
pipeline._analyzer.analyze = AsyncMock(
159+
return_value=AnalysisResult(
160+
repo=mock_repo,
161+
findings=[finding],
162+
)
163+
)
155164

156165
from contribai.orchestrator.memory import Memory
166+
157167
pipeline._memory = Memory(pipeline_config.storage.resolved_db_path)
158168
await pipeline._memory.init()
159169

tests/unit/test_analyzer.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,20 @@ def test_removes_duplicates(self, analyzer):
113113

114114
def test_keeps_different_findings(self, analyzer):
115115
findings = [
116-
Finding(type=ContributionType.SECURITY_FIX, severity=Severity.HIGH,
117-
title="Issue A", description="", file_path="a.py"),
118-
Finding(type=ContributionType.CODE_QUALITY, severity=Severity.MEDIUM,
119-
title="Issue B", description="", file_path="b.py"),
116+
Finding(
117+
type=ContributionType.SECURITY_FIX,
118+
severity=Severity.HIGH,
119+
title="Issue A",
120+
description="",
121+
file_path="a.py",
122+
),
123+
Finding(
124+
type=ContributionType.CODE_QUALITY,
125+
severity=Severity.MEDIUM,
126+
title="Issue B",
127+
description="",
128+
file_path="b.py",
129+
),
120130
]
121131
result = analyzer._deduplicate(findings)
122132
assert len(result) == 2
@@ -125,12 +135,27 @@ def test_keeps_different_findings(self, analyzer):
125135
class TestFilterSeverity:
126136
def test_filters_below_threshold(self, analyzer):
127137
findings = [
128-
Finding(type=ContributionType.SECURITY_FIX, severity=Severity.LOW,
129-
title="Low", description="", file_path="a.py"),
130-
Finding(type=ContributionType.SECURITY_FIX, severity=Severity.MEDIUM,
131-
title="Medium", description="", file_path="b.py"),
132-
Finding(type=ContributionType.SECURITY_FIX, severity=Severity.HIGH,
133-
title="High", description="", file_path="c.py"),
138+
Finding(
139+
type=ContributionType.SECURITY_FIX,
140+
severity=Severity.LOW,
141+
title="Low",
142+
description="",
143+
file_path="a.py",
144+
),
145+
Finding(
146+
type=ContributionType.SECURITY_FIX,
147+
severity=Severity.MEDIUM,
148+
title="Medium",
149+
description="",
150+
file_path="b.py",
151+
),
152+
Finding(
153+
type=ContributionType.SECURITY_FIX,
154+
severity=Severity.HIGH,
155+
title="High",
156+
description="",
157+
file_path="c.py",
158+
),
134159
]
135160
result = analyzer._filter_severity(findings)
136161
assert len(result) == 2 # medium threshold: medium + high

tests/unit/test_generator.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def test_docs_title(self, generator):
9595

9696
class TestParseChanges:
9797
def test_parse_json_response(self, generator):
98-
response = '''Here is the fix:
98+
response = """Here is the fix:
9999
```json
100100
{
101101
"changes": [
@@ -106,16 +106,16 @@ def test_parse_json_response(self, generator):
106106
}
107107
]
108108
}
109-
```'''
109+
```"""
110110
changes = generator._parse_changes(response)
111111
assert len(changes) == 1
112112
assert changes[0].path == "src/config.py"
113113
assert not changes[0].is_new_file
114114

115115
def test_parse_new_file(self, generator):
116-
response = '''```json
116+
response = """```json
117117
{"changes": [{"path": "new_file.py", "content": "print('hello')", "is_new_file": true}]}
118-
```'''
118+
```"""
119119
changes = generator._parse_changes(response)
120120
assert len(changes) == 1
121121
assert changes[0].is_new_file is True

tests/unit/test_github_client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ def test_auth_header(self, client):
7070
class TestContributingGuide:
7171
@pytest.mark.asyncio
7272
async def test_returns_none_when_not_found(self, client):
73-
client.get_file_content = AsyncMock(side_effect=GitHubAPIError("Not found", status_code=404))
73+
client.get_file_content = AsyncMock(
74+
side_effect=GitHubAPIError("Not found", status_code=404)
75+
)
7476
result = await client.get_contributing_guide("owner", "repo")
7577
assert result is None
7678

tests/unit/test_issue_solver.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,26 @@ def solver(mock_llm, mock_github):
1414

1515
@pytest.fixture
1616
def bug_issue():
17-
return Issue(number=1, title="App crashes on login", body="TypeError when user logs in", labels=["bug"])
17+
return Issue(
18+
number=1, title="App crashes on login", body="TypeError when user logs in", labels=["bug"]
19+
)
1820

1921

2022
@pytest.fixture
2123
def feature_issue():
22-
return Issue(number=2, title="Add dark mode support", body="Please add dark theme toggle", labels=["enhancement"])
24+
return Issue(
25+
number=2,
26+
title="Add dark mode support",
27+
body="Please add dark theme toggle",
28+
labels=["enhancement"],
29+
)
2330

2431

2532
@pytest.fixture
2633
def docs_issue():
27-
return Issue(number=3, title="Fix typo in README", body="Line 42 has a typo", labels=["documentation"])
34+
return Issue(
35+
number=3, title="Fix typo in README", body="Line 42 has a typo", labels=["documentation"]
36+
)
2837

2938

3039
@pytest.fixture
@@ -76,7 +85,8 @@ def test_long_body_complex(self, solver):
7685

7786
def test_many_file_references(self, solver):
7887
issue = Issue(
79-
number=3, title="Fix stuff",
88+
number=3,
89+
title="Fix stuff",
8090
body="Change src/a.py src/b.py src/c.py src/d.py src/e.py",
8191
labels=[],
8292
)
@@ -91,7 +101,8 @@ def test_filters_basic(self, solver, bug_issue, docs_issue):
91101

92102
def test_filters_complex(self, solver):
93103
complex_issue = Issue(
94-
number=99, title="Redesign everything",
104+
number=99,
105+
title="Redesign everything",
95106
body="x" * 10000 + " file1.py file2.py file3.py file4.py",
96107
labels=[],
97108
)
@@ -102,11 +113,13 @@ def test_filters_complex(self, solver):
102113
class TestSolveIssue:
103114
@pytest.mark.asyncio
104115
async def test_solve_returns_finding(self, solver, bug_issue, sample_repo):
105-
solver._llm.complete = AsyncMock(return_value="""FILE_PATH: src/auth.py
116+
solver._llm.complete = AsyncMock(
117+
return_value="""FILE_PATH: src/auth.py
106118
SEVERITY: high
107119
TITLE: Fix TypeError in login handler
108120
DESCRIPTION: The login handler raises TypeError when user object is None
109-
SUGGESTION: Add null check before accessing user properties""")
121+
SUGGESTION: Add null check before accessing user properties"""
122+
)
110123

111124
context = RepoContext(
112125
repo=sample_repo,

tests/unit/test_models.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,20 @@ def test_top_findings_sorted(self, sample_repo):
8181

8282
def test_filter_by_type(self, sample_repo):
8383
findings = [
84-
Finding(type=ContributionType.SECURITY_FIX, severity=Severity.HIGH,
85-
title="Sec", description="", file_path="a.py"),
86-
Finding(type=ContributionType.DOCS_IMPROVE, severity=Severity.LOW,
87-
title="Doc", description="", file_path="b.py"),
84+
Finding(
85+
type=ContributionType.SECURITY_FIX,
86+
severity=Severity.HIGH,
87+
title="Sec",
88+
description="",
89+
file_path="a.py",
90+
),
91+
Finding(
92+
type=ContributionType.DOCS_IMPROVE,
93+
severity=Severity.LOW,
94+
title="Doc",
95+
description="",
96+
file_path="b.py",
97+
),
8898
]
8999
result = AnalysisResult(repo=sample_repo, findings=findings)
90100
sec = result.filter_by_type(ContributionType.SECURITY_FIX)
@@ -93,12 +103,27 @@ def test_filter_by_type(self, sample_repo):
93103

94104
def test_filter_by_severity(self, sample_repo):
95105
findings = [
96-
Finding(type=ContributionType.SECURITY_FIX, severity=Severity.LOW,
97-
title="Low", description="", file_path="a.py"),
98-
Finding(type=ContributionType.SECURITY_FIX, severity=Severity.HIGH,
99-
title="High", description="", file_path="b.py"),
100-
Finding(type=ContributionType.SECURITY_FIX, severity=Severity.CRITICAL,
101-
title="Crit", description="", file_path="c.py"),
106+
Finding(
107+
type=ContributionType.SECURITY_FIX,
108+
severity=Severity.LOW,
109+
title="Low",
110+
description="",
111+
file_path="a.py",
112+
),
113+
Finding(
114+
type=ContributionType.SECURITY_FIX,
115+
severity=Severity.HIGH,
116+
title="High",
117+
description="",
118+
file_path="b.py",
119+
),
120+
Finding(
121+
type=ContributionType.SECURITY_FIX,
122+
severity=Severity.CRITICAL,
123+
title="Crit",
124+
description="",
125+
file_path="c.py",
126+
),
102127
]
103128
result = AnalysisResult(repo=sample_repo, findings=findings)
104129
high_plus = result.filter_by_severity(Severity.HIGH)

tests/unit/test_pr_manager.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,24 +98,24 @@ async def test_open_pr(self, pr_manager):
9898

9999
@pytest.mark.asyncio
100100
async def test_merged_pr(self, pr_manager):
101-
pr_manager._github._get = AsyncMock(
102-
return_value={"state": "closed", "merged": True}
103-
)
101+
pr_manager._github._get = AsyncMock(return_value={"state": "closed", "merged": True})
104102
status = await pr_manager.get_pr_status("owner", "repo", 1)
105103
assert status == PRStatus.MERGED
106104

107105
@pytest.mark.asyncio
108106
async def test_closed_pr(self, pr_manager):
109-
pr_manager._github._get = AsyncMock(
110-
return_value={"state": "closed", "merged": False}
111-
)
107+
pr_manager._github._get = AsyncMock(return_value={"state": "closed", "merged": False})
112108
status = await pr_manager.get_pr_status("owner", "repo", 1)
113109
assert status == PRStatus.CLOSED
114110

115111
@pytest.mark.asyncio
116112
async def test_review_requested(self, pr_manager):
117113
pr_manager._github._get = AsyncMock(
118-
return_value={"state": "open", "merged": False, "requested_reviewers": [{"login": "reviewer"}]}
114+
return_value={
115+
"state": "open",
116+
"merged": False,
117+
"requested_reviewers": [{"login": "reviewer"}],
118+
}
119119
)
120120
status = await pr_manager.get_pr_status("owner", "repo", 1)
121121
assert status == PRStatus.REVIEW_REQUESTED

tests/unit/test_scorer.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ def good_contribution():
3030
contribution_type=ContributionType.SECURITY_FIX,
3131
title="Fix SQL injection in db.py",
3232
description="Parameterized all raw SQL queries to prevent SQL injection attacks.",
33-
changes=[FileChange(
34-
path="db.py",
35-
new_content="""import sqlite3\n\ndef query(db, user_id):\n cursor = db.execute('SELECT * FROM users WHERE id = ?', (user_id,))\n return cursor.fetchall()\n""",
36-
)],
33+
changes=[
34+
FileChange(
35+
path="db.py",
36+
new_content="""import sqlite3\n\ndef query(db, user_id):\n cursor = db.execute('SELECT * FROM users WHERE id = ?', (user_id,))\n return cursor.fetchall()\n""",
37+
)
38+
],
3739
commit_message="fix(security): parameterize sql queries to prevent injection",
3840
branch_name="contribai/fix/sql-injection",
3941
)
@@ -69,10 +71,19 @@ def test_bad_contribution_fails(self, scorer, bad_contribution):
6971

7072
def test_empty_changes_fail(self, scorer):
7173
contrib = Contribution(
72-
finding=Finding(type=ContributionType.BUG_FIX if hasattr(ContributionType, "BUG_FIX") else ContributionType.CODE_QUALITY,
73-
severity=Severity.LOW, title="X", description="X", file_path="x.py"),
74+
finding=Finding(
75+
type=ContributionType.BUG_FIX
76+
if hasattr(ContributionType, "BUG_FIX")
77+
else ContributionType.CODE_QUALITY,
78+
severity=Severity.LOW,
79+
title="X",
80+
description="X",
81+
file_path="x.py",
82+
),
7483
contribution_type=ContributionType.CODE_QUALITY,
75-
title="X", description="X", changes=[],
84+
title="X",
85+
description="X",
86+
changes=[],
7687
)
7788
report = scorer.evaluate(contrib)
7889
assert report.checks["has_changes"].passed is False

0 commit comments

Comments
 (0)