11import os
22from unittest .mock import Mock , patch
3- import pytest
3+
44import libcst as cst
5+ import pytest
56
67import mutmut
78from mutmut .__main__ import (
89 CLASS_NAME_SEPARATOR ,
10+ CatchOutput ,
11+ MutmutProgrammaticFailException ,
912 get_diff_for_mutant ,
1013 orig_function_and_class_names_from_key ,
1114 run_forced_fail_test ,
12- Config ,
13- MutmutProgrammaticFailException ,
14- CatchOutput ,
1515)
16- from mutmut .trampoline_templates import trampoline_impl , mangle_function_name
1716from mutmut .file_mutation import create_mutations , mutate_file_contents
17+ from mutmut .trampoline_templates import mangle_function_name , trampoline_impl
18+
1819
1920def mutants_for_source (source : str ) -> list [str ]:
2021 module , mutated_nodes = create_mutations (source )
21- mutants : list [str ] = []
22- for m in mutated_nodes :
23- mutants .append (module .deep_replace (m .original_node , m .mutated_node ).code ) # type: ignore
22+ mutants : list [str ] = [module .deep_replace (m .original_node , m .mutated_node ).code for m in mutated_nodes ] # type: ignore
2423
2524 return mutants
2625
26+
2727def mutated_module (source : str ) -> str :
2828 mutated_code , _ = mutate_file_contents ('' , source )
2929 return mutated_code
@@ -220,7 +220,6 @@ def mutated_module(source: str) -> str:
220220 ('foo.bar' , []),
221221 ('for x in y: pass' , []),
222222 ('def foo(a, *args, **kwargs): pass' , []),
223- ('import foo' , []),
224223 ('isinstance(a, b)' , []),
225224 ('len(a)' , []),
226225 ('deepcopy(obj)' , ['copy(obj)' , 'deepcopy(None)' ]),
@@ -248,6 +247,7 @@ def foo() -> int:
248247
249248 assert not mutants
250249
250+
251251def test_do_not_mutate_specific_functions ():
252252 source = """
253253class A:
@@ -267,6 +267,7 @@ def __setattr__():
267267
268268 assert not mutants
269269
270+
270271def test_match_case ():
271272 source = """
272273match x:
@@ -285,6 +286,7 @@ def test_match_case():
285286
286287 assert sorted (mutants ) == sorted (expected )
287288
289+
288290def test_mach_case_does_not_mutate_bitor ():
289291 source = """
290292def concat():
@@ -344,6 +346,7 @@ def test_pragma_no_mutate_and_no_cover():
344346 mutants = mutants_for_source (source )
345347 assert not mutants
346348
349+
347350def test_pragma_no_mutate_on_function_definition ():
348351 source = """
349352def foo(): # pragma: no mutate
@@ -438,7 +441,8 @@ def foo():
438441
439442
440443def test_orig_function_name_from_key ():
441- assert orig_function_and_class_names_from_key (f'_{ CLASS_NAME_SEPARATOR } Foo{ CLASS_NAME_SEPARATOR } bar__mutmut_1' ) == ('bar' , 'Foo' )
444+ assert orig_function_and_class_names_from_key (
445+ f'_{ CLASS_NAME_SEPARATOR } Foo{ CLASS_NAME_SEPARATOR } bar__mutmut_1' ) == ('bar' , 'Foo' )
442446 assert orig_function_and_class_names_from_key ('x_bar__mutmut_1' ) == ('bar' , None )
443447
444448
@@ -496,6 +500,7 @@ def foo():
496500 assert mutated_source .split ('\n ' )[0 ] == 'from __future__ import annotations'
497501 assert mutated_source .count ('from __future__' ) == 1
498502
503+
499504def test_from_future_with_docstring_still_first ():
500505 source = """
501506'''This documents the module'''
@@ -527,7 +532,7 @@ def test_run_forced_fail_test_with_failing_test(_start, _stop, _dump_output, cap
527532 print (f"out: { out } " )
528533 print (f"err: { err } " )
529534 assert 'done' in out
530- assert os .environ ['MUTANT_UNDER_TEST' ] is ''
535+ assert not os .environ ['MUTANT_UNDER_TEST' ]
531536
532537
533538# Negate the effects of CatchOutput because it does not play nicely with capfd in GitHub Actions
@@ -540,9 +545,9 @@ def test_run_forced_fail_test_with_mutmut_programmatic_fail_exception(_start, _s
540545
541546 run_forced_fail_test (runner )
542547
543- out , err = capfd .readouterr ()
548+ out , _ = capfd .readouterr ()
544549 assert 'done' in out
545- assert os .environ ['MUTANT_UNDER_TEST' ] is ''
550+ assert not os .environ ['MUTANT_UNDER_TEST' ]
546551
547552
548553# Negate the effects of CatchOutput because it does not play nicely with capfd in GitHub Actions
@@ -556,8 +561,8 @@ def test_run_forced_fail_test_with_all_tests_passing(_start, _stop, _dump_output
556561 with pytest .raises (SystemExit ) as error :
557562 run_forced_fail_test (runner )
558563
559- assert error .value .code is 1
560- out , err = capfd .readouterr ()
564+ assert error .value .code == 1
565+ out , _ = capfd .readouterr ()
561566 assert 'FAILED: Unable to force test failures' in out
562567
563568
@@ -569,6 +574,7 @@ def _mocked_runner_run_forced_failed(return_value=None, side_effect=None):
569574 )
570575 return runner
571576
577+
572578def test_do_not_mutate_top_level_decorators ():
573579 # Modifying top-level decorators could influence all mutations
574580 # because they are executed at import time
@@ -591,6 +597,7 @@ def x(self):
591597
592598 assert not mutants
593599
600+
594601# TODO: implement removal of inner decorators
595602@pytest .mark .skip
596603def test_decorated_inner_functions_mutation ():
0 commit comments