Skip to content

Commit eb74a7b

Browse files
committed
Some refactoring
1 parent ba2e76d commit eb74a7b

File tree

1 file changed

+66
-103
lines changed

1 file changed

+66
-103
lines changed

src/codemodder/codemods/test/integration_utils.py

Lines changed: 66 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,66 @@ def check_dependencies_after(self):
3636
assert new_requirements_txt == self.expected_requirements
3737

3838

39-
class BaseRemediationIntegrationTest:
39+
class BaseIntegrationTestMixin:
40+
def _assert_sonar_fields(self, result):
41+
del result
42+
43+
def _assert_codetf_output(self, codetf_schema):
44+
with open(self.output_path, "r", encoding="utf-8") as f:
45+
codetf = json.load(f)
46+
47+
jsonschema.validate(codetf, codetf_schema)
48+
49+
assert sorted(codetf.keys()) == ["results", "run"]
50+
run = codetf["run"]
51+
self._assert_run_fields(run, self.output_path)
52+
results = codetf["results"]
53+
# CodeTf2 spec requires relative paths
54+
self._assert_results_fields(results, self.code_filename)
55+
56+
def write_original_code(self):
57+
with open(self.code_path, "w", encoding="utf-8") as f:
58+
f.write(self.original_code)
59+
60+
def _assert_results_fields(self, results, output_path):
61+
assert len(results) == 1
62+
result = results[0]
63+
assert result["codemod"] == self.codemod_instance.id
64+
assert result["references"] == [
65+
ref.model_dump(exclude_none=True)
66+
for ref in self.codemod_instance.references
67+
]
68+
69+
assert ("detectionTool" in result) == bool(self.sonar_issues_json)
70+
assert ("detectionTool" in result) == bool(self.sonar_hotspots_json)
71+
72+
# TODO: if/when we add description for each url
73+
for reference in result["references"][
74+
# Last references for Sonar has a different description
75+
: (
76+
-len(self.codemod.requested_rules)
77+
if self.sonar_issues_json or self.sonar_hotspots_json
78+
else None
79+
)
80+
]:
81+
assert reference["url"] == reference["description"]
82+
83+
self._assert_sonar_fields(result)
84+
85+
def _assert_command_line(self, run, output_path):
86+
pass
87+
88+
def _assert_run_fields(self, run, output_path):
89+
self._assert_command_line(run, output_path)
90+
assert run["vendor"] == "pixee"
91+
assert run["tool"] == "codemodder-python"
92+
assert run["version"] == __version__
93+
assert run["elapsed"] != ""
94+
assert run["directory"] == os.path.abspath(self.code_dir)
95+
assert run["sarifs"] == []
96+
97+
98+
class BaseRemediationIntegrationTest(BaseIntegrationTestMixin):
4099
codemod = NotImplementedError
41100
original_code = NotImplementedError
42101
expected_diff_per_change = NotImplementedError
@@ -77,11 +136,7 @@ def setup_class(cls):
77136
with open(cls.code_path, "r", encoding="utf-8") as f: # type: ignore
78137
cls.original_code = f.read()
79138

80-
def _assert_run_fields(self, run, output_path):
81-
assert run["vendor"] == "pixee"
82-
assert run["tool"] == "codemodder-python"
83-
assert run["version"] == __version__
84-
assert run["elapsed"] != ""
139+
def _assert_command_line(self, run, output_path):
85140
assert run[
86141
"commandLine"
87142
] == f'codemodder {self.code_dir} --output {output_path} --codemod-include={self.codemod_instance.id} --path-include={self.code_filename} --path-exclude=""' + (
@@ -93,35 +148,10 @@ def _assert_run_fields(self, run, output_path):
93148
if self.sonar_hotspots_json
94149
else ""
95150
)
96-
assert run["directory"] == os.path.abspath(self.code_dir)
97-
assert run["sarifs"] == []
98151

99152
def _assert_results_fields(self, results, output_path):
100-
assert len(results) == 1
153+
super()._assert_results_fields(results, output_path)
101154
result = results[0]
102-
assert result["codemod"] == self.codemod_instance.id
103-
assert result["references"] == [
104-
ref.model_dump(exclude_none=True)
105-
for ref in self.codemod_instance.references
106-
]
107-
108-
assert ("detectionTool" in result) == bool(self.sonar_issues_json)
109-
assert ("detectionTool" in result) == bool(self.sonar_hotspots_json)
110-
111-
# TODO: if/when we add description for each url
112-
for reference in result["references"][
113-
# Last references for Sonar has a different description
114-
: (
115-
-len(self.codemod.requested_rules)
116-
if self.sonar_issues_json or self.sonar_hotspots_json
117-
else None
118-
)
119-
]:
120-
assert reference["url"] == reference["description"]
121-
122-
self._assert_sonar_fields(result)
123-
124-
# There should be a changeset for every expected change
125155
assert len(result["changeset"]) == self.num_changes
126156
# gather all the change files and test against the expected number
127157
assert len({c["path"] for c in result["changeset"]}) == self.num_changed_files
@@ -143,26 +173,6 @@ def _assert_results_fields(self, results, output_path):
143173
self.change_description
144174
}
145175

146-
def _assert_sonar_fields(self, result):
147-
del result
148-
149-
def _assert_codetf_output(self, codetf_schema):
150-
with open(self.output_path, "r", encoding="utf-8") as f:
151-
codetf = json.load(f)
152-
153-
jsonschema.validate(codetf, codetf_schema)
154-
155-
assert sorted(codetf.keys()) == ["results", "run"]
156-
run = codetf["run"]
157-
self._assert_run_fields(run, self.output_path)
158-
results = codetf["results"]
159-
# CodeTf2 spec requires relative paths
160-
self._assert_results_fields(results, self.code_filename)
161-
162-
def write_original_code(self):
163-
with open(self.code_path, "w", encoding="utf-8") as f:
164-
f.write(self.original_code)
165-
166176
def test_codetf_output(self, codetf_schema):
167177
"""
168178
Tests correct codetf output.
@@ -296,7 +306,7 @@ def _check_code_after(self, patched_codes):
296306
)
297307

298308

299-
class BaseIntegrationTest(DependencyTestMixin):
309+
class BaseIntegrationTest(BaseIntegrationTestMixin, DependencyTestMixin):
300310
codemod = NotImplementedError
301311
original_code = NotImplementedError
302312
replacement_lines = NotImplementedError
@@ -352,11 +362,7 @@ def teardown_class(cls):
352362
if cls.requirements_file_name:
353363
pathlib.Path(cls.dependency_path).unlink(missing_ok=True)
354364

355-
def _assert_run_fields(self, run, output_path):
356-
assert run["vendor"] == "pixee"
357-
assert run["tool"] == "codemodder-python"
358-
assert run["version"] == __version__
359-
assert run["elapsed"] != ""
365+
def _assert_command_line(self, run, output_path):
360366
assert run[
361367
"commandLine"
362368
] == f'codemodder_hardening {self.code_dir} --output {output_path} --codemod-include={self.codemod_instance.id} --path-include={self.code_filename} --path-exclude=""' + (
@@ -368,34 +374,11 @@ def _assert_run_fields(self, run, output_path):
368374
if self.sonar_hotspots_json
369375
else ""
370376
)
371-
assert run["directory"] == os.path.abspath(self.code_dir)
372-
assert run["sarifs"] == []
373377

374378
def _assert_results_fields(self, results, output_path):
375-
assert len(results) == 1
376-
result = results[0]
377-
assert result["codemod"] == self.codemod_instance.id
378-
assert result["references"] == [
379-
ref.model_dump(exclude_none=True)
380-
for ref in self.codemod_instance.references
381-
]
382-
383-
assert ("detectionTool" in result) == bool(self.sonar_issues_json)
384-
assert ("detectionTool" in result) == bool(self.sonar_hotspots_json)
385-
386-
# TODO: if/when we add description for each url
387-
for reference in result["references"][
388-
# Last references for Sonar has a different description
389-
: (
390-
-len(self.codemod.requested_rules)
391-
if self.sonar_issues_json or self.sonar_hotspots_json
392-
else None
393-
)
394-
]:
395-
assert reference["url"] == reference["description"]
396-
397-
self._assert_sonar_fields(result)
379+
super()._assert_results_fields(results, output_path)
398380

381+
result = results[0]
399382
assert len(result["changeset"]) == self.num_changed_files
400383

401384
# A codemod may change multiple files. For now we will
@@ -411,22 +394,6 @@ def _assert_results_fields(self, results, output_path):
411394
assert line_change["lineNumber"] == int(self.expected_line_change)
412395
assert line_change["description"] == self.change_description
413396

414-
def _assert_sonar_fields(self, result):
415-
del result
416-
417-
def _assert_codetf_output(self, codetf_schema):
418-
with open(self.output_path, "r", encoding="utf-8") as f:
419-
codetf = json.load(f)
420-
421-
jsonschema.validate(codetf, codetf_schema)
422-
423-
assert sorted(codetf.keys()) == ["results", "run"]
424-
run = codetf["run"]
425-
self._assert_run_fields(run, self.output_path)
426-
results = codetf["results"]
427-
# CodeTf2 spec requires relative paths
428-
self._assert_results_fields(results, self.code_filename)
429-
430397
def check_code_after(self) -> ModuleType:
431398
with open(self.code_path, "r", encoding="utf-8") as f: # type: ignore
432399
new_code = f.read()
@@ -435,10 +402,6 @@ def check_code_after(self) -> ModuleType:
435402
path=self.code_path, allowed_exceptions=self.allowed_exceptions # type: ignore
436403
)
437404

438-
def write_original_code(self):
439-
with open(self.code_path, "w", encoding="utf-8") as f:
440-
f.write(self.original_code)
441-
442405
def test_file_rewritten(self, codetf_schema):
443406
"""
444407
Tests that file is re-written correctly with new code and correct codetf output.

0 commit comments

Comments
 (0)