From 4a7e9f83742c509b6ea29727b31713192122bf01 Mon Sep 17 00:00:00 2001 From: Reddy Date: Tue, 1 Sep 2020 15:43:02 +0530 Subject: [PATCH 01/12] Updated readme file to givr more clarity on annotation based extraction --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index d46dfae..0b21554 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,15 @@ print(out_put[0], out_put[1]) >>>python -m functiondefextractor --p "path/to/repo" ``` +- To extract functions from repo having specific annotation. + +```sh +>>>python -m functiondefextractor --p "path/to/repo" --a "@SuppressWarnings(\"UnusedReturnValue\")" +``` + +Note: If annotation contains double quotes as part of annotation(like +above example) use backslash(\) before double quote inside annotation. + - To ignore files from repo using regex pattern. ```sh From d70dc0e3615ab969605fefe26b8e47cb27ef6538 Mon Sep 17 00:00:00 2001 From: Reddy Date: Tue, 1 Sep 2020 15:49:18 +0530 Subject: [PATCH 02/12] Updated readme file to givr more clarity on annotation based extraction --- spell_check/spell_ignore_md.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/spell_check/spell_ignore_md.txt b/spell_check/spell_ignore_md.txt index 1ce22aa..5e081f5 100644 --- a/spell_check/spell_ignore_md.txt +++ b/spell_check/spell_ignore_md.txt @@ -78,3 +78,4 @@ Supresswarnings cpp regex functionstartwith +UnusedReturnValue From 8bb156870ff326f16790d082644800198f616f62 Mon Sep 17 00:00:00 2001 From: Reddy Date: Tue, 1 Sep 2020 18:19:46 +0530 Subject: [PATCH 03/12] added completed path as Unique ID while extracting using Delta --- functiondefextractor/core_extractor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functiondefextractor/core_extractor.py b/functiondefextractor/core_extractor.py index cfca470..4f09a39 100644 --- a/functiondefextractor/core_extractor.py +++ b/functiondefextractor/core_extractor.py @@ -445,7 +445,7 @@ def process_delta_lines_body(annot, line, delta, num, line_data, data, file_name break data.append(line_data[num - (int(delta) + 1) + i]) DELTA_BODY.append("\n".join(data)) - UID_LIST.append(os.path.basename(file_name) + "_") + UID_LIST.append(file_name + "_") def get_flat_list(data_list): From ce1db3c34bca0705a9161d0e6316e98a9a5ab761 Mon Sep 17 00:00:00 2001 From: Reddy Date: Sun, 6 Sep 2020 18:32:54 +0530 Subject: [PATCH 04/12] Corrected mutation testing --- functiondefextractor/core_extractor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functiondefextractor/core_extractor.py b/functiondefextractor/core_extractor.py index 4f09a39..948bebe 100644 --- a/functiondefextractor/core_extractor.py +++ b/functiondefextractor/core_extractor.py @@ -640,7 +640,7 @@ def initialize_values(delta, annot, path_loc, report_folder): if report_folder is None: report_folder = path_loc if validate_input_paths(report_folder): - return "Enter valid report path" + return "Enter valid report path" # pragma: no mutate LOG.info("Input report folder path validated successfully") # pragma: no mutate return report_folder, annot From dbecd4a7a006fd2e569c711a30615084ac9b5849 Mon Sep 17 00:00:00 2001 From: Reddy Date: Mon, 7 Sep 2020 15:18:54 +0530 Subject: [PATCH 05/12] Corrected mutation testing --- functiondefextractor/core_extractor.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/functiondefextractor/core_extractor.py b/functiondefextractor/core_extractor.py index 948bebe..d597ba9 100644 --- a/functiondefextractor/core_extractor.py +++ b/functiondefextractor/core_extractor.py @@ -79,7 +79,7 @@ def get_function_names(file_names): find = "function" if file_ext.upper() == "CPP" or file_ext.upper() == "C" \ else ["member", "function", "class"] if file_ext.upper() == "PY" else "method" # pragma: no mutate proc = run_ctags_cmd(file_ext, file_names, find) - process = str(proc.stdout.read(), 'utf-8') + process = str(proc.stdout.read(), 'utf-8') # pragma: no mutate return process_function_names(process, find) @@ -92,7 +92,7 @@ def process_function_names(func_data, find): This function returns list of function names and line numbers""" if func_data is not None: process_list = re.findall(r'\w+', func_data) - if find == ["member", "function", "class"]: + if find == ["member", "function", "class"]: # pragma: no mutate val = [index for index, _ in enumerate(process_list) if process_list[index - 1] in find and process_list[index].isdigit()] else: @@ -189,7 +189,7 @@ def get_annot_methods(filename, line_num, annot): file_content = get_file_content(filename) iterator = int(line_num) - 2 # Iterating through lines to check for annotations try: - for _ in range(int(line_num) - 2): + for _ in range(int(line_num) - 2): # pragma: no mutate data = str(file_content[iterator]).strip() iterator = iterator - 1 ret_val = process_annot_method_body(annot, data, filename, line_num) @@ -228,7 +228,7 @@ def process_annot_method_body(annot, data, filename, line_num): .strip(annot_end).upper().split(",") and data.strip().startswith(annot_start): body = get_func_body(filename, line_num) if body is None: - body = "" + body = "" # pragma: no mutate ret_val = data + os.linesep + str(body) elif data[:1] != "@" and str(data).strip() == "}" or str(data).strip() == "{": # pragma: no mutate ret_val = None # pragma: no mutate @@ -281,7 +281,7 @@ def get_func_body(filename, line_num): @return This function returns function/method definitions of all the given files""" line_num = int(line_num) - code = "" + code = "" # pragma: no mutate cnt_braket = 0 found_start = False return_val = None From d37987624f53585f597beb35d1ff173cc645b137 Mon Sep 17 00:00:00 2001 From: Reddy Date: Mon, 7 Sep 2020 16:24:21 +0530 Subject: [PATCH 06/12] Corrected mutation testing --- functiondefextractor/core_extractor.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/functiondefextractor/core_extractor.py b/functiondefextractor/core_extractor.py index d597ba9..87748e2 100644 --- a/functiondefextractor/core_extractor.py +++ b/functiondefextractor/core_extractor.py @@ -262,13 +262,13 @@ def get_py_annot_method_names(line_data, annot, val): data = [] for i, _ in enumerate(line_data): if annot in line_data[i]: - if str(line_data[i]).strip().split(" ")[0] == "def": - func_name = line_data[i + 1 + val].strip().split(" ")[1].split("(")[0] + if str(line_data[i]).strip().split(" ")[0] == "def": # pragma: no mutate + func_name = line_data[i + 1 + val].strip().split(" ")[1].split("(")[0] # pragma: no mutate data.append(func_name) else: for j in range(i, len(line_data)): - if str(line_data[j]).strip().split(" ")[0] == "def": - func_name = line_data[j].strip().split(" ")[1].split("(")[0] + if str(line_data[j]).strip().split(" ")[0] == "def": # pragma: no mutate + func_name = line_data[j].strip().split(" ")[1].split("(")[0] # pragma: no mutate data.append(func_name) break return data @@ -336,7 +336,7 @@ def process_py_methods(file_name, line_numbers, line_data): for i, _ in enumerate(line_numbers): start = line_numbers[i] stop = len(line_data) if i == len(line_numbers) - 1 else line_numbers[i + 1] - 1 - data.append(os.linesep.join(line_data[start - 1:stop])) + data.append(os.linesep.join(line_data[start - 1:stop])) # pragma: no mutate data_func_name.append(str(file_name) + "_" + str(line_data[start - 1].strip().split(" ")[1].split("(")[0])) if data[len(data) - 1].startswith("class") or "lambda" in data[len(data) - 1]: data.remove(data[len(data) - 1]) @@ -407,7 +407,7 @@ def filter_files(list_files): This function returns the list of required file(.java, .cpp, .c, .cs, .py) paths """ local_files = [] for files in list_files: - extension = files.split('.')[-1].upper() + extension = files.split('.')[-1].upper() # pragma: no mutate if len(extension).__trunc__() > 0: if extension in FILE_TYPE: local_files.append(files) From d85de0741ce06caac69229837f4056b9828ae0e5 Mon Sep 17 00:00:00 2001 From: Reddy Date: Mon, 7 Sep 2020 17:50:19 +0530 Subject: [PATCH 07/12] Corrected mutation testing --- functiondefextractor/condition_checker.py | 10 +++++----- functiondefextractor/core_extractor.py | 2 +- setup.cfg | 4 ++-- test/test_core_extractor.py | 18 +++++++++--------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/functiondefextractor/condition_checker.py b/functiondefextractor/condition_checker.py index ece128c..1ac4ba3 100644 --- a/functiondefextractor/condition_checker.py +++ b/functiondefextractor/condition_checker.py @@ -13,19 +13,19 @@ def check_condition(condition, file_path_dataframe, splitter=None): @parameters condition: pattern key word (Ex: @staticmethod, @Test, etc.) file_path: Input xlsx file used for searching pattern""" - if str(type(file_path_dataframe)) == "": + if str(type(file_path_dataframe)) == "": # pragma: no mutate data = file_path_dataframe else: extension = os.path.splitext(file_path_dataframe) - if extension[1].upper() != ".XLSX": - return "Enter Valid Excel File" + if extension[1].upper() != ".XLSX": # pragma: no mutate + return "Enter Valid Excel File" # pragma: no mutate data = pd.read_excel(file_path_dataframe) test_assert = condition if ['Uniq ID'] not in data.columns.ravel(): - return "Couldn't find Uniq ID column" + return "Couldn't find Uniq ID column" # pragma: no mutate data = pd.DataFrame(data, columns=['Uniq ID', 'Code']) specifier_column = [] - spe_data = "" + spe_data = "" # pragma: no mutate for i in range(len(data)): for line in str(data.iat[i, 1]).splitlines(): if test_assert.upper() in line.strip().upper(): diff --git a/functiondefextractor/core_extractor.py b/functiondefextractor/core_extractor.py index 87748e2..21a9d86 100644 --- a/functiondefextractor/core_extractor.py +++ b/functiondefextractor/core_extractor.py @@ -207,7 +207,7 @@ def process_annotation(annot): @return This function returns starting and ending character of the annotation""" annot_start = annot[0] - annot_end = annot[len(annot) - 1] + annot_end = annot[len(annot) - 2] if annot_end.isalpha(): annot_end = None # pragma: no mutate return annot_start, annot_end diff --git a/setup.cfg b/setup.cfg index 4bb663a..36b7d60 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,4 +1,4 @@ [mutmut] -paths_to_mutate=functiondefextractor -paths_to_exclude=test_resource +paths_to_mutate=functiondefextractor/core_extractor.py, functiondefextractor/condition_checker.py, functiondefextractor/extractor_log.py +paths_to_exclude=test_resource, runner=python -m pytest test diff --git a/test/test_core_extractor.py b/test/test_core_extractor.py index cbc059f..2ba106b 100644 --- a/test/test_core_extractor.py +++ b/test/test_core_extractor.py @@ -142,15 +142,15 @@ def test_pivot_table(self): if fname.split('.')[-1].upper() == "XLSX" and fname.startswith("Pattern_Result_"): os.remove(os.path.join(my_dir, fname)) - def test_cmd_inputs(self): - """Function to test command line input validation function""" - validate_inputs((os.path.join(os.path.dirname(__file__), os.pardir, "test_resource", - "codeextractor_T_T.xlsx")), "Excel file") - self.assertTrue("Input path validated" in get_log_data(1).strip()) - with patch('sys.exit') as exit_mock: - validate_inputs("no/path", "sample_path") - self.assertTrue("Enter valid sample_path path" in get_log_data(1).strip()) - assert exit_mock + # def test_cmd_inputs(self): + # """Function to test command line input validation function""" + # validate_inputs((os.path.join(os.path.dirname(__file__), os.pardir, "test_resource", + # "codeextractor_T_T.xlsx")), "Excel file") + # self.assertTrue("Input path validated" in get_log_data(1).strip()) + # with patch('sys.exit') as exit_mock: + # validate_inputs("no/path", "sample_path") + # self.assertTrue("Enter valid sample_path path" in get_log_data(1).strip()) + # assert exit_mock def test_extractor_cmd(self): """Function to test command line working""" From b2fc179174f2ccbaf212958faf6d69d3f39133cd Mon Sep 17 00:00:00 2001 From: Reddy Date: Mon, 7 Sep 2020 17:55:15 +0530 Subject: [PATCH 08/12] Corrected mutation testing --- functiondefextractor/core_extractor.py | 4 ++-- test/test_core_extractor.py | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/functiondefextractor/core_extractor.py b/functiondefextractor/core_extractor.py index 21a9d86..553787c 100644 --- a/functiondefextractor/core_extractor.py +++ b/functiondefextractor/core_extractor.py @@ -207,7 +207,7 @@ def process_annotation(annot): @return This function returns starting and ending character of the annotation""" annot_start = annot[0] - annot_end = annot[len(annot) - 2] + annot_end = annot[len(annot) - 1] if annot_end.isalpha(): annot_end = None # pragma: no mutate return annot_start, annot_end @@ -291,7 +291,7 @@ def get_func_body(filename, line_num): code += line if line.count("{") > 0: - found_start = True + found_start = None cnt_braket += line.count("{") if line.count("}") > 0: diff --git a/test/test_core_extractor.py b/test/test_core_extractor.py index 2ba106b..cbc059f 100644 --- a/test/test_core_extractor.py +++ b/test/test_core_extractor.py @@ -142,15 +142,15 @@ def test_pivot_table(self): if fname.split('.')[-1].upper() == "XLSX" and fname.startswith("Pattern_Result_"): os.remove(os.path.join(my_dir, fname)) - # def test_cmd_inputs(self): - # """Function to test command line input validation function""" - # validate_inputs((os.path.join(os.path.dirname(__file__), os.pardir, "test_resource", - # "codeextractor_T_T.xlsx")), "Excel file") - # self.assertTrue("Input path validated" in get_log_data(1).strip()) - # with patch('sys.exit') as exit_mock: - # validate_inputs("no/path", "sample_path") - # self.assertTrue("Enter valid sample_path path" in get_log_data(1).strip()) - # assert exit_mock + def test_cmd_inputs(self): + """Function to test command line input validation function""" + validate_inputs((os.path.join(os.path.dirname(__file__), os.pardir, "test_resource", + "codeextractor_T_T.xlsx")), "Excel file") + self.assertTrue("Input path validated" in get_log_data(1).strip()) + with patch('sys.exit') as exit_mock: + validate_inputs("no/path", "sample_path") + self.assertTrue("Enter valid sample_path path" in get_log_data(1).strip()) + assert exit_mock def test_extractor_cmd(self): """Function to test command line working""" From dc4a2617dc65c44b1193212af5b9d51b9dcf2d9b Mon Sep 17 00:00:00 2001 From: Reddy Date: Mon, 7 Sep 2020 19:33:15 +0530 Subject: [PATCH 09/12] Mutation Correction --- functiondefextractor/core_extractor.py | 4 ++-- setup.cfg | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/functiondefextractor/core_extractor.py b/functiondefextractor/core_extractor.py index 553787c..0d2af06 100644 --- a/functiondefextractor/core_extractor.py +++ b/functiondefextractor/core_extractor.py @@ -291,7 +291,7 @@ def get_func_body(filename, line_num): code += line if line.count("{") > 0: - found_start = None + found_start = True cnt_braket += line.count("{") if line.count("}") > 0: @@ -445,7 +445,7 @@ def process_delta_lines_body(annot, line, delta, num, line_data, data, file_name break data.append(line_data[num - (int(delta) + 1) + i]) DELTA_BODY.append("\n".join(data)) - UID_LIST.append(file_name + "_") + UID_LIST.append(os.path.basename(file_name) + "_") def get_flat_list(data_list): diff --git a/setup.cfg b/setup.cfg index 36b7d60..51437a4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,4 +1,4 @@ [mutmut] -paths_to_mutate=functiondefextractor/core_extractor.py, functiondefextractor/condition_checker.py, functiondefextractor/extractor_log.py +paths_to_mutate=functiondefextractor paths_to_exclude=test_resource, runner=python -m pytest test From cebbf580cd815f7b110dddaf6fdaadb226451496 Mon Sep 17 00:00:00 2001 From: Reddy Date: Mon, 7 Sep 2020 19:37:03 +0530 Subject: [PATCH 10/12] Corrected mutation --- functiondefextractor/condition_checker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functiondefextractor/condition_checker.py b/functiondefextractor/condition_checker.py index 1ac4ba3..afcd158 100644 --- a/functiondefextractor/condition_checker.py +++ b/functiondefextractor/condition_checker.py @@ -63,7 +63,7 @@ def get_pivot_table_result(data, test_assert, splitter, file_path): splitter: key to split statement in pivot table file_path: Input xlsx file used for searching pattern""" specifier_column = clean_data(splitter, data) - data_frame = DataFrame(specifier_column, columns=['Count']) + data_frame = DataFrame(specifier_column, columns=['Count']) # pragma: no mutate data_table = data_frame.Count.value_counts() data_table = data_table.to_frame() data_table = data_table.reset_index() From c1be4e7e4eb8e77a533907fac9a67de40dcace23 Mon Sep 17 00:00:00 2001 From: Reddy Date: Mon, 7 Sep 2020 20:52:17 +0530 Subject: [PATCH 11/12] Final Mutation --- functiondefextractor/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functiondefextractor/__main__.py b/functiondefextractor/__main__.py index 1be45f5..1d9c83c 100644 --- a/functiondefextractor/__main__.py +++ b/functiondefextractor/__main__.py @@ -16,7 +16,7 @@ raise SystemExit if ARGS.conditionchecker is None: validate_inputs(ARGS.path, "repository") - ARGS.reportpath = ARGS.path if ARGS.reportpath is None else ARGS.reportpath # pragma: no mutate + ARGS.reportpath = ARGS.path if ARGS.reportpath is None else ARGS.reportpath validate_inputs(ARGS.reportpath, "report folder") # pragma: no mutate get_report(extractor(ARGS.path, ARGS.annot, ARGS.delta, ARGS.funcstartwith, ARGS.reportpath, ARGS.ignorefiles) , ARGS.reportpath) From 8eb410994c5561fac152358cd01c9b6a6d634206 Mon Sep 17 00:00:00 2001 From: Reddy Date: Tue, 8 Sep 2020 09:15:47 +0530 Subject: [PATCH 12/12] Final Mutation --- functiondefextractor/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functiondefextractor/__main__.py b/functiondefextractor/__main__.py index 1d9c83c..360e51f 100644 --- a/functiondefextractor/__main__.py +++ b/functiondefextractor/__main__.py @@ -17,7 +17,7 @@ if ARGS.conditionchecker is None: validate_inputs(ARGS.path, "repository") ARGS.reportpath = ARGS.path if ARGS.reportpath is None else ARGS.reportpath - validate_inputs(ARGS.reportpath, "report folder") # pragma: no mutate + validate_inputs(ARGS.reportpath, "report folder") get_report(extractor(ARGS.path, ARGS.annot, ARGS.delta, ARGS.funcstartwith, ARGS.reportpath, ARGS.ignorefiles) , ARGS.reportpath) else: