diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 06da247..3c6d7cc 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -20,6 +20,7 @@ jobs: verbose: True pylint_args: "--rcfile=.pylintrc --recursive=true" python_dirs: "src test" + exclude_dir: "test/utils/" - name: PyLint uses: ricardochaves/python-lint@v1.4.0 diff --git a/entrypoint_python.sh b/entrypoint_python.sh index e017894..2c7cfd7 100644 --- a/entrypoint_python.sh +++ b/entrypoint_python.sh @@ -15,11 +15,11 @@ if [ -z "$INPUT_PYTHON_DIRS" ]; then fi if [ -z "$INPUT_EXCLUDE_DIR" ]; then + debug_print "Running: files_to_check=\$(python3 /src/get_files_to_check.py -dir=\"$GITHUB_WORKSPACE\" -preselected=\"$preselected_files\" -lang=\"python\")" files_to_check=$(python3 /src/get_files_to_check.py -dir="$GITHUB_WORKSPACE" -preselected="$preselected_files" -lang="python") - debug_print "Running: files_to_check=python3 /src/get_files_to_check.py -dir=\"$GITHUB_WORKSPACE\" -preselected=\"$preselected_files\")" else - files_to_check=$(python3 /src/get_files_to_check.py -exclude="$GITHUB_WORKSPACE/$INPUT_EXCLUDE_DIR" -dir="$GITHUB_WORKSPACE" -preselected="$preselected_files") - debug_print "Running: files_to_check=python3 /src/get_files_to_check.py -exclude=\"$GITHUB_WORKSPACE/$INPUT_EXCLUDE_DIR\" -dir=\"$GITHUB_WORKSPACE\" -preselected=\"$preselected_files\")" + debug_print "Running: files_to_check=\$(python3 /src/get_files_to_check.py -exclude=\"$GITHUB_WORKSPACE/$INPUT_EXCLUDE_DIR\" -dir=\"$GITHUB_WORKSPACE\" -preselected=\"$preselected_files\" -lang=\"python\")" + files_to_check=$(python3 /src/get_files_to_check.py -exclude="$GITHUB_WORKSPACE/$INPUT_EXCLUDE_DIR" -dir="$GITHUB_WORKSPACE" -preselected="$preselected_files" -lang="python") fi debug_print "Files to check = $files_to_check" diff --git a/test/test_static_analysis_cpp.py b/test/test_static_analysis_cpp.py index d7ecf5a..d7fad19 100644 --- a/test/test_static_analysis_cpp.py +++ b/test/test_static_analysis_cpp.py @@ -30,7 +30,7 @@ def to_list_and_sort(string_in): class TestStaticAnalysisCpp(unittest.TestCase): - """Unit tests for run_static_analysis module""" + """Unit tests for static_analysis_cpp""" maxDiff = None diff --git a/test/test_static_analysis_python.py b/test/test_static_analysis_python.py new file mode 100644 index 0000000..a95f59f --- /dev/null +++ b/test/test_static_analysis_python.py @@ -0,0 +1,223 @@ +import json +import unittest +import os +import sys +import utils.helper_functions as utils + +try: + project_path = f"{os.sep}".join(os.path.abspath(__file__).split(os.sep)[:-2]) + sys.path.append(project_path) +except Exception as exception: + print(f"Can not add project path to system path! Exiting!\nERROR: {exception}") + raise SystemExit(1) from exception + +os.environ["GITHUB_WORKSPACE"] = f"{project_path}/test/utils/dummy_project" +os.environ["INPUT_VERBOSE"] = "True" +os.environ["INPUT_REPORT_PR_CHANGES_ONLY"] = "False" +os.environ["INPUT_REPO"] = "RepoName" +os.environ["GITHUB_SHA"] = "1234" +os.environ["INPUT_COMMENT_TITLE"] = "title" + +from src import static_analysis_python + + +def to_list_and_sort(string_in): + # create list (of strings) from space separated string + # and then sort it + list_out = string_in.split(" ") + list_out.sort() + + return list_out + + +class TestStaticAnalysisPython(unittest.TestCase): + """Unit tests for static_analysis_python""" + + maxDiff = None + + def test_create_comment_for_output(self): + """ + Test the `create_comment_for_output()` function. + + This test case checks whether the `create_comment_for_output()` function correctly + generates a GitHub comment that displays static analysis issues for a given set of + files. + + The test case creates a mock set of files and static analysis issues, and expects the + generated GitHub comment to match a pre-defined expected string. + """ + + pylint_content = r""" [ + { + "type": "convention", + "module": "dummy", + "obj": "", + "line": 5, + "column": 0, + "endLine": 5, + "endColumn": 5, + "path": "dummy.py", + "symbol": "invalid-name", + "message": "Constant name \"shift\" doesn't conform to UPPER_CASE naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "dummy", + "obj": "", + "line": 8, + "column": 0, + "endLine": 8, + "endColumn": 7, + "path": "dummy.py", + "symbol": "invalid-name", + "message": "Constant name \"letters\" doesn't conform to UPPER_CASE naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "dummy", + "obj": "", + "line": 9, + "column": 0, + "endLine": 9, + "endColumn": 7, + "path": "dummy.py", + "symbol": "invalid-name", + "message": "Constant name \"encoded\" doesn't conform to UPPER_CASE naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "dummy", + "obj": "", + "line": 13, + "column": 12, + "endLine": 13, + "endColumn": 19, + "path": "dummy.py", + "symbol": "invalid-name", + "message": "Constant name \"encoded\" doesn't conform to UPPER_CASE naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "dummy", + "obj": "", + "line": 15, + "column": 12, + "endLine": 15, + "endColumn": 13, + "path": "dummy.py", + "symbol": "invalid-name", + "message": "Constant name \"x\" doesn't conform to UPPER_CASE naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "dummy", + "obj": "", + "line": 16, + "column": 12, + "endLine": 16, + "endColumn": 19, + "path": "dummy.py", + "symbol": "invalid-name", + "message": "Constant name \"encoded\" doesn't conform to UPPER_CASE naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "dummy", + "obj": "", + "line": 20, + "column": 12, + "endLine": 20, + "endColumn": 19, + "path": "dummy.py", + "symbol": "invalid-name", + "message": "Constant name \"encoded\" doesn't conform to UPPER_CASE naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "dummy", + "obj": "", + "line": 22, + "column": 12, + "endLine": 22, + "endColumn": 13, + "path": "dummy.py", + "symbol": "invalid-name", + "message": "Constant name \"x\" doesn't conform to UPPER_CASE naming style", + "message-id": "C0103" + }, + { + "type": "convention", + "module": "dummy", + "obj": "", + "line": 23, + "column": 12, + "endLine": 23, + "endColumn": 19, + "path": "dummy.py", + "symbol": "invalid-name", + "message": "Constant name \"encoded\" doesn't conform to UPPER_CASE naming style", + "message-id": "C0103" + } + ]""" + + files_changed_in_pr = {"/github/workspace/dummy.py": ("added", (1, 25))} + result = static_analysis_python.create_comment_for_output( + json.loads(pylint_content), files_changed_in_pr, False + ) + + sha = os.getenv("GITHUB_SHA") + repo_name = os.getenv("INPUT_REPO") + expected = ( + "\n\nhttps://github.com/RepoName/blob/1234/dummy.py#L5-L10 \n" + "```diff" + '\n!Line: 5 - Constant name "shift" doesn\'t conform to UPPER_CASE naming style\n' + "``` \n
" + "\n\n\n\nhttps://github.com/RepoName/blob/1234/dummy.py#L8-L13 \n" + "```diff\n" + '!Line: 8 - Constant name "letters" doesn\'t conform to UPPER_CASE naming style\n' + "``` \n
" + "\n\n\n\nhttps://github.com/RepoName/blob/1234/dummy.py#L9-L14 \n" + "```diff\n" + '!Line: 9 - Constant name "encoded" doesn\'t conform to UPPER_CASE naming style\n' + "```" + " \n
" + "\n\n\n\nhttps://github.com/RepoName/blob/1234/dummy.py#L13-L18 \n" + "```diff\n" + '!Line: 13 - Constant name "encoded" doesn\'t conform to UPPER_CASE naming style\n' + "``` \n
" + "\n\n\n\nhttps://github.com/RepoName/blob/1234/dummy.py#L15-L20 \n" + "```diff\n" + '!Line: 15 - Constant name "x" doesn\'t conform to UPPER_CASE naming style\n' + "``` \n
" + "\n\n\n\nhttps://github.com/RepoName/blob/1234/dummy.py#L16-L21 \n" + "```diff\n" + '!Line: 16 - Constant name "encoded" doesn\'t conform to UPPER_CASE naming style\n' + "``` \n
" + "\n\n\n\nhttps://github.com/RepoName/blob/1234/dummy.py#L20-L25 \n" + "```diff\n" + '!Line: 20 - Constant name "encoded" doesn\'t conform to UPPER_CASE naming style\n' + "``` \n
" + "\n\n\n\nhttps://github.com/RepoName/blob/1234/dummy.py#L22-L25 \n" + "```diff\n" + '!Line: 22 - Constant name "x" doesn\'t conform to UPPER_CASE naming style\n' + "``` \n
" + "\n\n\n\nhttps://github.com/RepoName/blob/1234/dummy.py#L23-L25 \n" + "```diff\n" + '!Line: 23 - Constant name "encoded" doesn\'t conform to UPPER_CASE naming style\n' + "``` \n
\n" + ) + + print(result) + + self.assertEqual(result, (expected, 9)) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/utils/dummy_project/dummy.py b/test/utils/dummy_project/dummy.py new file mode 100644 index 0000000..efe2471 --- /dev/null +++ b/test/utils/dummy_project/dummy.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 + +import string + +shift = 3 +choice = input("would you like to encode or decode?") +word = input("Please enter text") +letters = string.ascii_letters + string.punctuation + string.digits +encoded = "" +if choice == "encode": + for letter in word: + if letter == " ": + encoded = encoded + " " + else: + x = letters.index(letter) + shift + encoded = encoded + letters[x] +if choice == "decode": + for letter in word: + if letter == " ": + encoded = encoded + " " + else: + x = letters.index(letter) - shift + encoded = encoded + letters[x] + +print(encoded)