diff --git a/pyproject.toml b/pyproject.toml index 5cae11c..56fda0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ version_provider = "pep621" update_changelog_on_bump = false [project] name = "pytestomatio" -version = "2.10.2" +version = "2.10.3b8" dependencies = [ diff --git a/pytestomatio/decor/decorator_updater.py b/pytestomatio/decor/decorator_updater.py index b779542..f60cc2a 100644 --- a/pytestomatio/decor/decorator_updater.py +++ b/pytestomatio/decor/decorator_updater.py @@ -4,7 +4,7 @@ def update_tests(file: str, - mapped_tests: list[tuple[str, int]], + mapped_tests: list[tuple[str, int, str]], all_tests: list[str], decorator_name: str, remove=False): diff --git a/pytestomatio/decor/default.py b/pytestomatio/decor/default.py index 3c848c3..5bfe135 100644 --- a/pytestomatio/decor/default.py +++ b/pytestomatio/decor/default.py @@ -1,16 +1,18 @@ import libcst as cst +from pathlib import Path from typing import List, Tuple, Union class DecoratorUpdater(cst.CSTTransformer): - def __init__(self, mapped_tests: List[Tuple[str, int]], all_tests: List[str], decorator_name: str): + def __init__(self, mapped_tests: List[Tuple[str, int, str]], all_tests: List[str], decorator_name: str, file_path: str): self.mapped_tests = mapped_tests self.all_tests = all_tests self.decorator_name = decorator_name + self.filename = Path(file_path).name def _get_id_by_title(self, title: str): for pair in self.mapped_tests: - if pair[0] == title: + if pair[0] == title and pair[2] == self.filename: return pair[1] def _remove_decorator(self, node: cst.FunctionDef) -> cst.FunctionDef: @@ -64,7 +66,7 @@ def leave_Decorator(self, original_node: cst.Decorator, updated_node: cst.Decora def update_tests(file: str, - mapped_tests: List[Tuple[str, int]], + mapped_tests: List[Tuple[str, int, str]], all_tests: List[str], decorator_name: str, remove=False): @@ -72,12 +74,12 @@ def update_tests(file: str, source_code = f.read() tree = cst.parse_module(source_code) - transform = DecoratorUpdater(mapped_tests, all_tests, decorator_name) + transform = DecoratorUpdater(mapped_tests, all_tests, decorator_name, file) if remove: transform = DecoratorRemover(decorator_name) tree = tree.visit(transform) else: - transform = DecoratorUpdater(mapped_tests, all_tests, decorator_name) + transform = DecoratorUpdater(mapped_tests, all_tests, decorator_name, file) tree = tree.visit(transform) updated_source_code = tree.code diff --git a/pytestomatio/decor/pep8.py b/pytestomatio/decor/pep8.py index cc0b595..403ead4 100644 --- a/pytestomatio/decor/pep8.py +++ b/pytestomatio/decor/pep8.py @@ -1,18 +1,21 @@ import ast +from pathlib import Path + import autopep8 pytest_mark = 'pytest', 'mark' class DecoratorUpdater(ast.NodeTransformer): - def __init__(self, mapped_tests: list[tuple[str, int]], all_tests: list[str], decorator_name: str): + def __init__(self, mapped_tests: list[tuple[str, int, str]], all_tests: list[str], decorator_name: str, file_path: str): self.mapped_tests = mapped_tests self.all_tests = all_tests self.decorator_name = decorator_name + self.filename = Path(file_path).name def _get_id_by_title(self, title: str): for pair in self.mapped_tests: - if pair[0] == title: + if pair[0] == title and pair[2] == self.filename: return pair[1] def _remove_decorator(self, node: ast.FunctionDef) -> ast.FunctionDef: @@ -57,7 +60,7 @@ def insert_pytest_mark_import(self, tree: ast.Module, module_name: str, decorato def update_tests(file: str, - mapped_tests: list[tuple[str, int]], + mapped_tests: list[tuple[str, int, str]], all_tests: list[str], decorator_name: str, remove=False): @@ -65,7 +68,7 @@ def update_tests(file: str, source_code = f.read() tree = ast.parse(source_code) - transform = DecoratorUpdater(mapped_tests, all_tests, decorator_name) + transform = DecoratorUpdater(mapped_tests, all_tests, decorator_name, file) if remove: transform.remove_decorators(tree) else: diff --git a/pytestomatio/utils/helper.py b/pytestomatio/utils/helper.py index c8ed658..7c079b0 100644 --- a/pytestomatio/utils/helper.py +++ b/pytestomatio/utils/helper.py @@ -31,8 +31,8 @@ def collect_tests(items: list[Item]): return meta, test_files, test_names -def get_test_mapping(tests: list[TestItem]) -> list[tuple[str, int]]: - return [(test.title, test.id) for test in tests] +def get_test_mapping(tests: list[TestItem]) -> list[tuple[str, int, str]]: + return [(test.title, test.id, test.file_name) for test in tests] def parse_test_list(raw_response: dict) -> list[TestomatItem]: diff --git a/tests/test_decor/test_default.py b/tests/test_decor/test_default.py index fdf618c..603ccbd 100644 --- a/tests/test_decor/test_default.py +++ b/tests/test_decor/test_default.py @@ -11,20 +11,28 @@ class TestDecoratorUpdater: def test_get_id_by_title_found(self): """Test get ID by title""" - mapped_tests = [("test_one", "@T123"), ("test_two", "@T456")] - updater = DecoratorUpdater(mapped_tests, [], "testomatio") + mapped_tests = [("test_one", "@T123", "file1"), ("test_two", "@T456", "file1")] + updater = DecoratorUpdater(mapped_tests, [], "testomatio", "path/file1") result = updater._get_id_by_title("test_one") assert result == "@T123" def test_get_id_by_title_not_found(self): """Test title not found""" - mapped_tests = [("test_one", "@T123")] - updater = DecoratorUpdater(mapped_tests, [], "testomatio") + mapped_tests = [("test_one", "@T123", "file1")] + updater = DecoratorUpdater(mapped_tests, [], "testomatio", "path/file1") result = updater._get_id_by_title("nonexistent") assert result is None + def test_get_id_by_title_not_found_if_file_not_match(self): + """Test title not found""" + mapped_tests = [("test_one", "@T123", "file1")] + updater = DecoratorUpdater(mapped_tests, [], "testomatio", "path/file2") + + result = updater._get_id_by_title("@T123") + assert result is None + def test_basic_decorator_addition(self): """Test add decorator to function""" source_code = ''' @@ -36,7 +44,7 @@ def test_example(): assert '@pytest.mark.testomatio("@T123")' not in tree.code - updater = DecoratorUpdater([("test_example", "@T123")], ["test_example"], "testomatio") + updater = DecoratorUpdater([("test_example", "@T123", "file1")], ["test_example"], "testomatio", "path/file1") modified_tree = tree.visit(updater) result_code = modified_tree.code @@ -52,7 +60,7 @@ def test_example(): ''' tree = cst.parse_module(source_code) - updater = DecoratorUpdater([("test_example", "@T123")], [], "testomatio") # порожній all_tests + updater = DecoratorUpdater([("test_example", "@T123", "file1")], [], "testomatio", "path/file1") # порожній all_tests modified_tree = tree.visit(updater) result_code = modified_tree.code @@ -68,7 +76,7 @@ def test_example(): ''' tree = cst.parse_module(source_code) - updater = DecoratorUpdater([("test_example", "@T456")], ["test_example"], "testomatio") + updater = DecoratorUpdater([("test_example", "@T456", "file1")], ["test_example"], "testomatio", 'path/file1') modified_tree = tree.visit(updater) result_code = modified_tree.code @@ -139,7 +147,8 @@ def test_two(): def test_update_tests_adds_decorators(self, temp_test_file): """Test update_tests adds decorators""" - mapped_tests = [("test_one", "@T123"), ("test_two", "@T456")] + filename = temp_test_file.split('/')[-1] + mapped_tests = [("test_one", "@T123", filename), ("test_two", "@T456", filename)] all_tests = ["test_one", "test_two"] update_tests(temp_test_file, mapped_tests, all_tests, "testomatio", remove=False) diff --git a/tests/test_decor/test_pep8.py b/tests/test_decor/test_pep8.py index 2af3fd6..99d910c 100644 --- a/tests/test_decor/test_pep8.py +++ b/tests/test_decor/test_pep8.py @@ -11,20 +11,28 @@ class TestDecoratorUpdaterPep8: def test_get_id_by_title_found(self): """Test found ID by title""" - mapped_tests = [("test_login", "@T123"), ("test_logout", "@T456")] - updater = DecoratorUpdater(mapped_tests, [], "testomatio") + mapped_tests = [("test_login", "@T123", "file1"), ("test_logout", "@T456", "file1")] + updater = DecoratorUpdater(mapped_tests, [], "testomatio", "path/file1") result = updater._get_id_by_title("test_login") assert result == "@T123" def test_get_id_by_title_not_found(self): """Test title not found""" - mapped_tests = [("test_login", "@T123")] - updater = DecoratorUpdater(mapped_tests, [], "testomatio") + mapped_tests = [("test_login", "@T123", "file1")] + updater = DecoratorUpdater(mapped_tests, [], "testomatio", "path/file1") result = updater._get_id_by_title("missing_test") assert result is None + def test_get_id_by_title_not_found_if_filename_not_match(self): + """Test title not found""" + mapped_tests = [("test_login", "@T123", "file2")] + updater = DecoratorUpdater(mapped_tests, [], "testomatio", "path/file1") + + result = updater._get_id_by_title("@T123") + assert result is None + def test_visit_function_def_adds_decorator(self): """Test add decorator to function""" source_code = ''' @@ -35,7 +43,7 @@ def test_example(): tree = ast.parse(source_code) assert "mark.testomatio('@T123')" not in tree.body - updater = DecoratorUpdater([("test_example", "@T123")], ["test_example"], "testomatio") + updater = DecoratorUpdater([("test_example", "@T123", "file1")], ["test_example"], "testomatio", "path/file1") func_node = tree.body[0] assert isinstance(func_node, ast.FunctionDef) @@ -55,7 +63,7 @@ def test_example(): ''' tree = ast.parse(source_code) - updater = DecoratorUpdater([("test_example", "@T123")], [], "testomatio") # порожній all_tests + updater = DecoratorUpdater([("test_example", "@T123", "file1")], [], "testomatio", "path/file1") # порожній all_tests func_node = tree.body[0] updated_node = updater.visit_FunctionDef(func_node) @@ -70,7 +78,7 @@ def test_example(): assert True ''') - updater = DecoratorUpdater([("test_example", "@T123")], ["test_example"], "testomatio") + updater = DecoratorUpdater([("test_example", "@T123", "file1")], ["test_example"], "testomatio", "path/file1") func_node = tree.body[0] original_decorators_count = len(func_node.decorator_list) @@ -87,7 +95,7 @@ def test_example(): assert True ''') - updater = DecoratorUpdater([], [], "testomatio") + updater = DecoratorUpdater([], [], "testomatio", "path/file1") func_node = tree.body[0] updated_node = updater._remove_decorator(func_node) @@ -107,7 +115,7 @@ def test_two(): assert False ''') - updater = DecoratorUpdater([], [], "testomatio") + updater = DecoratorUpdater([], [], "testomatio", "path/file1") for node in ast.walk(tree): if isinstance(node, ast.FunctionDef): @@ -144,7 +152,8 @@ def test_subtraction(): def test_update_tests_adds_decorators_and_import(self, temp_test_file): """Test update_tests add decorators and import""" - mapped_tests = [("test_addition", "@T123"), ("test_subtraction", "@T456")] + filename = temp_test_file.split('/')[-1] + mapped_tests = [("test_addition", "@T123", filename), ("test_subtraction", "@T456", filename)] all_tests = ["test_addition", "test_subtraction"] update_tests(temp_test_file, mapped_tests, all_tests, "testomatio", remove=False) @@ -198,7 +207,8 @@ def test_bad_formatting( ): with open(temp_test_file, 'w') as f: f.write(badly_formatted) - mapped_tests = [("test_bad_formatting", "@T123")] + filename = temp_test_file.split('/')[-1] + mapped_tests = [("test_bad_formatting", "@T123", filename)] all_tests = ["test_bad_formatting"] update_tests(temp_test_file, mapped_tests, all_tests, "testomatio", remove=False) @@ -225,7 +235,8 @@ def test_with_decorators(): with open(temp_test_file, 'w') as f: f.write(content_with_other_decorators) - mapped_tests = [("test_with_decorators", "@T789")] + filename = temp_test_file.split('/')[-1] + mapped_tests = [("test_with_decorators", "@T789", filename)] all_tests = ["test_with_decorators"] update_tests(temp_test_file, mapped_tests, all_tests, "testomatio", remove=False) diff --git a/tests/test_utils/test_helper.py b/tests/test_utils/test_helper.py index 93a7e3f..1391187 100644 --- a/tests/test_utils/test_helper.py +++ b/tests/test_utils/test_helper.py @@ -178,10 +178,11 @@ def test_get_test_mapping_single_test_item(self): mock_test_item = Mock(spec=TestItem) mock_test_item.title = "Test Addition" mock_test_item.id = "@T12345678" + mock_test_item.file_name = "file1" result = get_test_mapping([mock_test_item]) - assert result == [("Test Addition", "@T12345678")] + assert result == [("Test Addition", "@T12345678", "file1")] assert len(result) == 1 assert isinstance(result[0], tuple) @@ -190,23 +191,24 @@ def test_get_test_mapping_multiple_test_items(self): mock_items = [] test_data = [ - ("Test Login", "@T11111111"), - ("Test Logout", "@T22222222"), - ("Test Registration", "@T33333333") + ("Test Login", "@T11111111", "file1"), + ("Test Logout", "@T22222222", "file1"), + ("Test Registration", "@T33333333", "file2") ] - for title, test_id in test_data: + for title, test_id, filename in test_data: mock_item = Mock(spec=TestItem) mock_item.title = title mock_item.id = test_id + mock_item.file_name = filename mock_items.append(mock_item) result = get_test_mapping(mock_items) expected = [ - ("Test Login", "@T11111111"), - ("Test Logout", "@T22222222"), - ("Test Registration", "@T33333333") + ("Test Login", "@T11111111", "file1"), + ("Test Logout", "@T22222222", "file1"), + ("Test Registration", "@T33333333", "file2") ] assert result == expected @@ -218,10 +220,11 @@ def test_get_test_mapping_test_items_without_id(self): mock_test_item = Mock(spec=TestItem) mock_test_item.title = "Test Without ID" mock_test_item.id = None + mock_test_item.file_name = "file1" result = get_test_mapping([mock_test_item]) - assert result == [("Test Without ID", None)] + assert result == [("Test Without ID", None, "file1")] class TestParseTestList: