From 87800a0dd09311f75228fab0ffdd00882c89c5e5 Mon Sep 17 00:00:00 2001 From: clavedeluna Date: Mon, 11 Mar 2024 14:26:02 -0300 Subject: [PATCH] test sonar fix missing self or cls codemod --- .../test_fix_missing_self_or_cls.py | 7 +- .../test_sonar_fix_missing_self_or_cls.py | 45 +++++++++++++ src/codemodder/scripts/generate_docs.py | 5 ++ src/core_codemods/__init__.py | 2 + .../sonar/sonar_fix_missing_self_or_cls.py | 2 +- .../test_sonar_fix_missing_self_or_cls.py | 65 +++++++++++++++++++ 6 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 integration_tests/test_sonar_fix_missing_self_or_cls.py create mode 100644 tests/codemods/test_sonar_fix_missing_self_or_cls.py diff --git a/integration_tests/test_fix_missing_self_or_cls.py b/integration_tests/test_fix_missing_self_or_cls.py index a830a4b5a..afe6bac57 100644 --- a/integration_tests/test_fix_missing_self_or_cls.py +++ b/integration_tests/test_fix_missing_self_or_cls.py @@ -2,7 +2,10 @@ BaseIntegrationTest, original_and_expected_from_code_path, ) -from core_codemods.fix_missing_self_or_cls import FixMissingSelfOrCls +from core_codemods.fix_missing_self_or_cls import ( + FixMissingSelfOrCls, + FixMissingSelfOrClsTransformer, +) class TestFixMissingSelfOrCls(BaseIntegrationTest): @@ -40,5 +43,5 @@ class TestFixMissingSelfOrCls(BaseIntegrationTest): # fmt: on expected_line_change = "2" - change_description = FixMissingSelfOrCls.change_description + change_description = FixMissingSelfOrClsTransformer.change_description num_changes = 2 diff --git a/integration_tests/test_sonar_fix_missing_self_or_cls.py b/integration_tests/test_sonar_fix_missing_self_or_cls.py new file mode 100644 index 000000000..01bcc6b5e --- /dev/null +++ b/integration_tests/test_sonar_fix_missing_self_or_cls.py @@ -0,0 +1,45 @@ +from codemodder.codemods.test import ( + BaseIntegrationTest, + original_and_expected_from_code_path, +) +from core_codemods.fix_missing_self_or_cls import FixMissingSelfOrClsTransformer +from core_codemods.sonar.sonar_fix_missing_self_or_cls import SonarFixMissingSelfOrCls + + +class TestSonarFixMissingSelfOrCls(BaseIntegrationTest): + codemod = SonarFixMissingSelfOrCls + code_path = "tests/samples/fix_missing_self_or_cls.py" + original_code, expected_new_code = original_and_expected_from_code_path( + code_path, + [ + ( + 1, + """ def instance_method(self):\n""", + ), + ( + 5, + """ def class_method(cls):\n""", + ), + ], + ) + sonar_issues_json = "tests/samples/sonar_issues.json" + # fmt: off + expected_diff = ( + """--- \n""" + """+++ \n""" + """@@ -1,7 +1,7 @@\n""" + """ class MyClass:\n""" + """- def instance_method():\n""" + """+ def instance_method(self):\n""" + """ print("instance_method")\n""" + """ \n""" + """ @classmethod\n""" + """- def class_method():\n""" + """+ def class_method(cls):\n""" + """ print("class_method")\n""" + ) + # fmt: on + + expected_line_change = "2" + change_description = FixMissingSelfOrClsTransformer.change_description + num_changes = 2 diff --git a/src/codemodder/scripts/generate_docs.py b/src/codemodder/scripts/generate_docs.py index 98937eb57..975773a88 100644 --- a/src/codemodder/scripts/generate_docs.py +++ b/src/codemodder/scripts/generate_docs.py @@ -309,6 +309,11 @@ class DocMetadata: guidance_explained=CORE_METADATA["jwt-decode-verify"].guidance_explained, need_sarif="Yes (Sonar)", ), + "fix-missing-self-or-cls-S5719": DocMetadata( + importance=CORE_METADATA["fix-missing-self-or-cls"].importance, + guidance_explained=CORE_METADATA["fix-missing-self-or-cls"].guidance_explained, + need_sarif="Yes (Sonar)", + ), } diff --git a/src/core_codemods/__init__.py b/src/core_codemods/__init__.py index d3f5270f1..f5a731f5c 100644 --- a/src/core_codemods/__init__.py +++ b/src/core_codemods/__init__.py @@ -49,6 +49,7 @@ from .sonar.sonar_django_receiver_on_top import SonarDjangoReceiverOnTop from .sonar.sonar_exception_without_raise import SonarExceptionWithoutRaise from .sonar.sonar_fix_assert_tuple import SonarFixAssertTuple +from .sonar.sonar_fix_missing_self_or_cls import SonarFixMissingSelfOrCls from .sonar.sonar_flask_json_response_type import SonarFlaskJsonResponseType from .sonar.sonar_jwt_decode_verify import SonarJwtDecodeVerify from .sonar.sonar_literal_or_new_object_identity import SonarLiteralOrNewObjectIdentity @@ -144,5 +145,6 @@ SonarFlaskJsonResponseType, SonarDjangoJsonResponseType, SonarJwtDecodeVerify, + SonarFixMissingSelfOrCls, ], ) diff --git a/src/core_codemods/sonar/sonar_fix_missing_self_or_cls.py b/src/core_codemods/sonar/sonar_fix_missing_self_or_cls.py index 8ab6dea72..44c58c521 100644 --- a/src/core_codemods/sonar/sonar_fix_missing_self_or_cls.py +++ b/src/core_codemods/sonar/sonar_fix_missing_self_or_cls.py @@ -2,7 +2,7 @@ from codemodder.codemods.sonar import SonarCodemod from core_codemods.fix_missing_self_or_cls import FixMissingSelfOrCls -SonarNumpyNanEquality = SonarCodemod.from_core_codemod( +SonarFixMissingSelfOrCls = SonarCodemod.from_core_codemod( name="fix-missing-self-or-cls-S5719", other=FixMissingSelfOrCls, rules=["python:S5719"], diff --git a/tests/codemods/test_sonar_fix_missing_self_or_cls.py b/tests/codemods/test_sonar_fix_missing_self_or_cls.py new file mode 100644 index 000000000..39bda2ecd --- /dev/null +++ b/tests/codemods/test_sonar_fix_missing_self_or_cls.py @@ -0,0 +1,65 @@ +import json + +from codemodder.codemods.test import BaseSASTCodemodTest +from core_codemods.sonar.sonar_fix_missing_self_or_cls import SonarFixMissingSelfOrCls + + +class TestSonarFixMissingSelfOrCls(BaseSASTCodemodTest): + codemod = SonarFixMissingSelfOrCls + tool = "sonar" + + def test_name(self): + assert self.codemod.name == "fix-missing-self-or-cls-S5719" + + def test_simple(self, tmpdir): + input_code = """ + class A: + def method(): + pass + + @classmethod + def clsmethod(): + pass + """ + expected_output = """ + class A: + def method(self): + pass + + @classmethod + def clsmethod(cls): + pass + """ + issues = { + "issues": [ + { + "rule": "python:S5719", + "status": "OPEN", + "component": "code.py", + "textRange": { + "startLine": 2, + "endLine": 2, + "startOffset": 4, + "endOffset": 25, + }, + }, + { + "rule": "python:S5719", + "status": "OPEN", + "component": "code.py", + "textRange": { + "startLine": 6, + "endLine": 6, + "startOffset": 4, + "endOffset": 22, + }, + }, + ] + } + self.run_and_assert( + tmpdir, + input_code, + expected_output, + results=json.dumps(issues), + num_changes=2, + )