From 3c63c99cc700129b90dd875515325dc9a25778d0 Mon Sep 17 00:00:00 2001 From: Frank Hoffmann <15r10nk-git@polarbit.de> Date: Thu, 5 Oct 2023 21:24:29 +0200 Subject: [PATCH] feat: support for testing with mutmut --- .gitignore | 1 + pysource_minimize/_minimize.py | 24 ++++++++++++------------ tests/conftest.py | 2 +- tests/test_needle.py | 18 ++++++++++++++---- tests/test_remove_one.py | 14 ++++++++------ 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 5962087..4b27be8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ __pycache__ dist .python-version .coverage* +pysource_minimize_testing/ diff --git a/pysource_minimize/_minimize.py b/pysource_minimize/_minimize.py index 63b5646..505858e 100644 --- a/pysource_minimize/_minimize.py +++ b/pysource_minimize/_minimize.py @@ -71,7 +71,6 @@ def visit(self, node): self.replaced = {} - try: if not self.checker(self.original_source): raise ValueError("checker return False: nothing to minimize here") @@ -187,7 +186,9 @@ def try_with(self, replaced={}): double_defined = self.replaced.keys() & replaced.keys() if TESTING: - assert not double_defined , f"the keys {double_defined} are mapped a second time" + assert ( + not double_defined + ), f"the keys {double_defined} are mapped a second time" source, tree = self.get_source_tree(replaced) @@ -329,7 +330,7 @@ def minimize_expr(self, node): # todo minimize values elif isinstance(node, ast.Slice): - #return # coverage + # return # coverage self.try_only_minimize(node, node.lower, node.upper, node.step) elif isinstance(node, ast.Lambda): if self.try_only_minimize(node, node.body): @@ -350,7 +351,7 @@ def minimize_expr(self, node): elif isinstance(node, ast.Await): self.try_only_minimize(node, node.value) elif isinstance(node, ast.Yield): - #return # coverage + # return # coverage self.try_only_minimize(node, node.value) elif isinstance(node, ast.YieldFrom): self.try_only_minimize(node, node.value) @@ -413,7 +414,7 @@ def minimize_expr(self, node): return if self.try_only(node, gen.iter): - #return # coverage + # return # coverage self.minimize_expr(gen.iter) return @@ -436,7 +437,7 @@ def minimize_expr(self, node): else: raise TypeError(node) # Expr - def minimize_optional(self, node,terminal=None): + def minimize_optional(self, node, terminal=None): if node is not None and not self.try_none(node): if terminal is None: self.minimize(node) @@ -496,7 +497,6 @@ def minimize_args_of(self, func): self.minimize(child) return True - if py38: self.minimize_list(args.posonlyargs, self.minimize_arg) @@ -511,7 +511,6 @@ def minimize_args_of(self, func): self.minimize_optional(args.vararg) self.minimize_optional(args.kwarg) - return False def minimize_stmt(self, node): @@ -685,7 +684,9 @@ def minimize_item(item: ast.withitem): self.minimize_list(node.cases, self.minimize_match_case, 1) elif isinstance(node, ast.Raise): - if not self.try_only(node, node.exc) and not self.try_only(node, node.cause): + if not self.try_only(node, node.exc) and not self.try_only( + node, node.cause + ): self.minimize_optional(node.cause) # cause requires exc # `raise from cause` is not valid @@ -735,8 +736,7 @@ def minimize_except_handler(handler): self.minimize_optional(handler.type) if handler.name: - self.try_attr(handler,"name",None) - + self.try_attr(handler, "name", None) self.minimize_list( node.handlers, minimize_except_handler, 1 # 0 if node.finalbody else 1 @@ -750,7 +750,7 @@ def minimize_except_handler(handler): if self.try_only(node, node.msg): self.minimize(node.msg) return - + self.try_none(node.msg) if self.try_only_minimize(node, node.test): diff --git a/tests/conftest.py b/tests/conftest.py index 8df5acf..07c81d0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -20,7 +20,7 @@ def pytest_addoption(parser, pluginmanager): def pytest_sessionfinish(session, exitstatus): - print("exitstatus",exitstatus) + print("exitstatus", exitstatus) if exitstatus == 0 and session.config.option.generate_samples: from .test_remove_one import generate_remove_one diff --git a/tests/test_needle.py b/tests/test_needle.py index 80b5ed2..05aae28 100644 --- a/tests/test_needle.py +++ b/tests/test_needle.py @@ -7,9 +7,17 @@ import pytest from pysource_codegen import generate +import pysource_minimize._minimize + +try: + import pysource_minimize_testing +except ImportError: + import pysource_minimize as pysource_minimize_testing + + from pysource_minimize import minimize from pysource_minimize._minimize import unparse -import pysource_minimize._minimize + sample_dir = Path(__file__).parent / "needle_samples" @@ -37,7 +45,7 @@ def needle_count(source): def try_find_needle(source): assert contains_one_needle(source) - new_source = minimize(source, contains_one_needle) + new_source = pysource_minimize_testing.minimize(source, contains_one_needle) assert new_source.strip() == needle_name @@ -55,10 +63,10 @@ def test_needle(file): print(f"the following code can not be minimized to needle:") print(source) - if sys.version_info >= (3,9): + if sys.version_info >= (3, 9): print() print("ast:") - print(ast.dump(ast.parse(source),indent=2)) + print(ast.dump(ast.parse(source), indent=2)) try_find_needle(source) @@ -80,8 +88,10 @@ def generic_visit(self, node: ast.AST) -> ast.AST: return super().generic_visit(node) + import sys + def generate_needle(): seed = random.randrange(0, 100000000) print("seed:", seed) diff --git a/tests/test_remove_one.py b/tests/test_remove_one.py index 43b9f90..d4a7fc9 100644 --- a/tests/test_remove_one.py +++ b/tests/test_remove_one.py @@ -6,10 +6,14 @@ import pytest from pysource_codegen import generate -from pysource_minimize import StopMinimization from pysource_minimize import minimize +try: + import pysource_minimize_testing +except ImportError: + import pysource_minimize as pysource_minimize_testing + sample_dir = Path(__file__).parent / "remove_one_samples" sample_dir.mkdir(exist_ok=True) @@ -96,7 +100,7 @@ def weight(node): if isinstance(node, ast.excepthandler): result = 0 if node.name: - result+=1 + result += 1 if isinstance(node, ast.arguments): # kw_defaults and kwonlyargs can only be removed together @@ -106,8 +110,6 @@ def weight(node): if isinstance(node, ast.TypeAlias): result = 0 - - return result return [(n, weight(n)) for n in ast.walk(tree)] @@ -129,14 +131,14 @@ def checker(source): count = count_nodes(source) if count == node_count - 1: - raise StopMinimization + raise pysource_minimize_testing.StopMinimization return count_nodes(source) >= node_count - 1 while node_count > 1: print(node_count) # remove only one "node" from the ast at a time - new_source = minimize(source, checker) + new_source = pysource_minimize_testing.minimize(source, checker) if count_nodes(new_source) != node_count - 1: return False, source