mutmut 3.0.2__tar.gz → 3.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mutmut-3.0.2 → mutmut-3.0.3}/HISTORY.rst +7 -0
- {mutmut-3.0.2 → mutmut-3.0.3}/MANIFEST.in +2 -2
- {mutmut-3.0.2 → mutmut-3.0.3}/PKG-INFO +2 -1
- {mutmut-3.0.2 → mutmut-3.0.3}/mutmut/__init__.py +1 -1
- {mutmut-3.0.2 → mutmut-3.0.3}/mutmut.egg-info/PKG-INFO +2 -1
- {mutmut-3.0.2 → mutmut-3.0.3}/mutmut.egg-info/SOURCES.txt +1 -6
- {mutmut-3.0.2 → mutmut-3.0.3}/mutmut.egg-info/requires.txt +1 -0
- {mutmut-3.0.2 → mutmut-3.0.3}/requirements.txt +1 -0
- mutmut-3.0.2/test_requirements.txt +0 -4
- mutmut-3.0.2/tests/test_mutation.py +0 -339
- mutmut-3.0.2/tests/test_mutmut3.py +0 -80
- {mutmut-3.0.2 → mutmut-3.0.3}/AUTHORS.rst +0 -0
- {mutmut-3.0.2 → mutmut-3.0.3}/LICENSE +0 -0
- {mutmut-3.0.2 → mutmut-3.0.3}/README.rst +0 -0
- {mutmut-3.0.2 → mutmut-3.0.3}/mutmut/__main__.py +0 -0
- {mutmut-3.0.2 → mutmut-3.0.3}/mutmut/result_browser_layout.tcss +0 -0
- {mutmut-3.0.2 → mutmut-3.0.3}/mutmut.egg-info/dependency_links.txt +0 -0
- {mutmut-3.0.2 → mutmut-3.0.3}/mutmut.egg-info/entry_points.txt +0 -0
- {mutmut-3.0.2 → mutmut-3.0.3}/mutmut.egg-info/not-zip-safe +0 -0
- {mutmut-3.0.2 → mutmut-3.0.3}/mutmut.egg-info/top_level.txt +0 -0
- {mutmut-3.0.2 → mutmut-3.0.3}/setup.cfg +0 -0
- {mutmut-3.0.2 → mutmut-3.0.3}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mutmut
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.3
|
|
4
4
|
Summary: mutation testing for Python 3
|
|
5
5
|
Home-page: https://github.com/boxed/mutmut
|
|
6
6
|
Author: Anders Hovmöller
|
|
@@ -19,6 +19,7 @@ Requires-Dist: parso
|
|
|
19
19
|
Requires-Dist: click
|
|
20
20
|
Requires-Dist: junit-xml==1.8
|
|
21
21
|
Requires-Dist: setproctitle
|
|
22
|
+
Requires-Dist: textual
|
|
22
23
|
Provides-Extra: pytest
|
|
23
24
|
Requires-Dist: pytest; extra == "pytest"
|
|
24
25
|
Provides-Extra: coverage
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mutmut
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.3
|
|
4
4
|
Summary: mutation testing for Python 3
|
|
5
5
|
Home-page: https://github.com/boxed/mutmut
|
|
6
6
|
Author: Anders Hovmöller
|
|
@@ -19,6 +19,7 @@ Requires-Dist: parso
|
|
|
19
19
|
Requires-Dist: click
|
|
20
20
|
Requires-Dist: junit-xml==1.8
|
|
21
21
|
Requires-Dist: setproctitle
|
|
22
|
+
Requires-Dist: textual
|
|
22
23
|
Provides-Extra: pytest
|
|
23
24
|
Requires-Dist: pytest; extra == "pytest"
|
|
24
25
|
Provides-Extra: coverage
|
|
@@ -6,11 +6,8 @@ README.rst
|
|
|
6
6
|
requirements.txt
|
|
7
7
|
setup.cfg
|
|
8
8
|
setup.py
|
|
9
|
-
test_requirements.txt
|
|
10
9
|
./mutmut/__init__.py
|
|
11
10
|
./mutmut/__main__.py
|
|
12
|
-
mutmut/__init__.py
|
|
13
|
-
mutmut/__main__.py
|
|
14
11
|
mutmut/result_browser_layout.tcss
|
|
15
12
|
mutmut.egg-info/PKG-INFO
|
|
16
13
|
mutmut.egg-info/SOURCES.txt
|
|
@@ -18,6 +15,4 @@ mutmut.egg-info/dependency_links.txt
|
|
|
18
15
|
mutmut.egg-info/entry_points.txt
|
|
19
16
|
mutmut.egg-info/not-zip-safe
|
|
20
17
|
mutmut.egg-info/requires.txt
|
|
21
|
-
mutmut.egg-info/top_level.txt
|
|
22
|
-
tests/test_mutation.py
|
|
23
|
-
tests/test_mutmut3.py
|
|
18
|
+
mutmut.egg-info/top_level.txt
|
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
from io import StringIO
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
from parso import parse
|
|
5
|
-
|
|
6
|
-
from mutmut.__main__ import (
|
|
7
|
-
CLASS_NAME_SEPARATOR,
|
|
8
|
-
FuncContext,
|
|
9
|
-
get_diff_for_mutant,
|
|
10
|
-
mangle_function_name,
|
|
11
|
-
orig_function_and_class_names_from_key,
|
|
12
|
-
pragma_no_mutate_lines,
|
|
13
|
-
write_all_mutants_to_file,
|
|
14
|
-
yield_mutants_for_module,
|
|
15
|
-
yield_mutants_for_node,
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@pytest.mark.parametrize(
|
|
20
|
-
'original, expected', [
|
|
21
|
-
('foo(a, *args, **kwargs)', [
|
|
22
|
-
'foo( *args, **kwargs)',
|
|
23
|
-
'foo(None, *args, **kwargs)',
|
|
24
|
-
'foo(a, **kwargs)',
|
|
25
|
-
'foo(a, *args,)',
|
|
26
|
-
]),
|
|
27
|
-
# TODO: Fix these
|
|
28
|
-
# ('break', 'continue'), # probably a bad idea. Can introduce infinite loops.
|
|
29
|
-
('a(b)', 'a(None)'),
|
|
30
|
-
# ("x if a else b", "x if a else b"),
|
|
31
|
-
("dict(a=None)", ["dict(aXX=None)"]),
|
|
32
|
-
("dict(a=b)", ["dict(aXX=b)", 'dict(a=None)']),
|
|
33
|
-
('lambda **kwargs: Variable.integer(**setdefaults(kwargs, dict(show=False)))', [
|
|
34
|
-
'lambda **kwargs: Variable.integer(**setdefaults(kwargs, dict(show=True)))',
|
|
35
|
-
'lambda **kwargs: Variable.integer(**setdefaults(kwargs, dict(showXX=False)))',
|
|
36
|
-
'lambda **kwargs: Variable.integer(**setdefaults(None, dict(show=False)))',
|
|
37
|
-
'lambda **kwargs: Variable.integer(**setdefaults( dict(show=False)))',
|
|
38
|
-
# TODO: this mutant should exist... I guess we need to handle method calls separately from function calls?
|
|
39
|
-
# 'lambda **kwargs: Variable.integer()',
|
|
40
|
-
'lambda **kwargs: None',
|
|
41
|
-
]),
|
|
42
|
-
('a: Optional[int] = None', 'a: Optional[int] = ""'),
|
|
43
|
-
('a: int = 1', ['a: int = 2', 'a: int = None']),
|
|
44
|
-
('lambda: 0', ['lambda: 1', 'lambda: None']),
|
|
45
|
-
("1 in (1, 2)", ['2 in (1, 2)', '1 not in (1, 2)', '1 in (2, 2)', '1 in (1, 3)']),
|
|
46
|
-
('1+1', ['2+1', '1-1', '1+2']),
|
|
47
|
-
('1', '2'),
|
|
48
|
-
('1-1', ['2-1', '1+1', '1-2']),
|
|
49
|
-
('1*1', ['2*1', '1/1', '1*2']),
|
|
50
|
-
('1/1', ['2/1', '1*1', '1/2']),
|
|
51
|
-
# ('1.0', '1.0000000000000002'), # using numpy features
|
|
52
|
-
('1.0', '2.0'),
|
|
53
|
-
('0.1', '1.1'),
|
|
54
|
-
('1e-3', '1.001'),
|
|
55
|
-
('True', 'False'),
|
|
56
|
-
('False', 'True'),
|
|
57
|
-
('"foo"', '"XXfooXX"'),
|
|
58
|
-
("'foo'", "'XXfooXX'"),
|
|
59
|
-
("u'foo'", "u'XXfooXX'"),
|
|
60
|
-
("0", "1"),
|
|
61
|
-
("0o0", "1"),
|
|
62
|
-
("0.", "1.0"),
|
|
63
|
-
("0x0", "1"),
|
|
64
|
-
("0b0", "1"),
|
|
65
|
-
("1<2", ['2<2', '1<=2', '1<3']),
|
|
66
|
-
('(1, 2)', ['(2, 2)', '(1, 3)']),
|
|
67
|
-
("1 not in (1, 2)", ['2 not in (1, 2)', '1 in (1, 2)', '1 not in (2, 2)', '1 not in (1, 3)']), # two spaces here because "not in" is two words
|
|
68
|
-
("foo is foo", "foo is not foo"),
|
|
69
|
-
("foo is not foo", "foo is foo"),
|
|
70
|
-
('a or b', 'a and b'),
|
|
71
|
-
('a and b', 'a or b'),
|
|
72
|
-
('a = b', 'a = None'),
|
|
73
|
-
('a = b = c = x', 'a = b = c = None'),
|
|
74
|
-
|
|
75
|
-
# subscript
|
|
76
|
-
('a[None]', []),
|
|
77
|
-
('a[b]', 'a[None]'),
|
|
78
|
-
('s[0]', ['s[1]', 's[None]']),
|
|
79
|
-
('s[0] = a', ['s[1] = a', 's[None] = a', 's[0] = None']),
|
|
80
|
-
('s[1:]', ['s[2:]', 's[None]']),
|
|
81
|
-
|
|
82
|
-
('1j', '2j'),
|
|
83
|
-
('1.0j', '2.0j'),
|
|
84
|
-
('0o1', '2'),
|
|
85
|
-
('1.0e10', '10000000001.0'),
|
|
86
|
-
('a = {x for x in y}', 'a = None'),
|
|
87
|
-
('x+=1', ['x=1', 'x-=1', 'x+=2']),
|
|
88
|
-
('x-=1', ['x=1', 'x+=1', 'x-=2']),
|
|
89
|
-
('x*=1', ['x=1', 'x/=1', 'x*=2']),
|
|
90
|
-
('x/=1', ['x=1', 'x*=1', 'x/=2']),
|
|
91
|
-
('x//=1', ['x=1', 'x/=1', 'x//=2']),
|
|
92
|
-
('x%=1', ['x=1', 'x/=1', 'x%=2']),
|
|
93
|
-
('x<<=1', ['x=1', 'x>>=1', 'x<<=2']),
|
|
94
|
-
('x>>=1', ['x=1', 'x<<=1', 'x>>=2']),
|
|
95
|
-
('x&=1', ['x=1', 'x|=1', 'x&=2']),
|
|
96
|
-
('x|=1', ['x=1', 'x&=1', 'x|=2']),
|
|
97
|
-
('x^=1', ['x=1', 'x&=1', 'x^=2']),
|
|
98
|
-
('x**=1', ['x=1', 'x*=1', 'x**=2']),
|
|
99
|
-
('def foo(s: Int = 1): pass', 'def foo(s: Int = 2): pass'),
|
|
100
|
-
('a = None', 'a = ""'),
|
|
101
|
-
('lambda **kwargs: None', 'lambda **kwargs: 0'),
|
|
102
|
-
('lambda: None', 'lambda: 0'),
|
|
103
|
-
('def foo(s: str): pass', []),
|
|
104
|
-
('def foo(a, *, b): pass', []),
|
|
105
|
-
('a(None)', []),
|
|
106
|
-
("'''foo'''", []), # don't mutate things we assume to be docstrings
|
|
107
|
-
("r'''foo'''", []), # don't mutate things we assume to be docstrings
|
|
108
|
-
('(x for x in [])', []), # don't mutate 'in' in generators
|
|
109
|
-
("DictSynonym(a=b)", ["DictSynonym(aXX=b)", 'DictSynonym(a=None)']),
|
|
110
|
-
("NotADictSynonym(a=b)", "NotADictSynonym(a=None)"),
|
|
111
|
-
('from foo import *', []),
|
|
112
|
-
('from .foo import *', []),
|
|
113
|
-
('import foo', []),
|
|
114
|
-
('import foo as bar', []),
|
|
115
|
-
('foo.bar', []),
|
|
116
|
-
('for x in y: pass', []),
|
|
117
|
-
('def foo(a, *args, **kwargs): pass', []),
|
|
118
|
-
('import foo', []),
|
|
119
|
-
('isinstance(a, b)', []),
|
|
120
|
-
('len(a)', []),
|
|
121
|
-
]
|
|
122
|
-
)
|
|
123
|
-
def test_basic_mutations(original, expected):
|
|
124
|
-
if isinstance(expected, str):
|
|
125
|
-
expected = [expected]
|
|
126
|
-
func_node = parse(f'def fake():\n {original}').children[0]
|
|
127
|
-
node = func_node.children[-1]
|
|
128
|
-
assert node.get_code().strip() == original.strip()
|
|
129
|
-
mutants = list(yield_mutants_for_node(func_node=func_node, context=FuncContext(dict_synonyms={'DictSynonym'}), node=node))
|
|
130
|
-
actual = sorted([
|
|
131
|
-
parse(mutant).children[0].children[-1].get_code().strip()
|
|
132
|
-
for (type_, mutant, _, _) in mutants
|
|
133
|
-
if type_ == 'mutant'
|
|
134
|
-
])
|
|
135
|
-
expected = sorted(expected)
|
|
136
|
-
assert actual == expected
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
def test_do_not_mutate_annotations():
|
|
140
|
-
source = """
|
|
141
|
-
def foo() -> int:
|
|
142
|
-
bar: Optional[int]
|
|
143
|
-
return
|
|
144
|
-
""".strip()
|
|
145
|
-
|
|
146
|
-
mutants = [
|
|
147
|
-
mutant
|
|
148
|
-
for type_, mutant, _, _ in yield_mutants_for_module(parse(source), {})
|
|
149
|
-
if type_ == 'mutant'
|
|
150
|
-
]
|
|
151
|
-
for m in mutants:
|
|
152
|
-
print(m) # pragma: no cover
|
|
153
|
-
|
|
154
|
-
assert not mutants
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
def test_basic_class():
|
|
158
|
-
source = """
|
|
159
|
-
class Foo:
|
|
160
|
-
def member(self):
|
|
161
|
-
return 1
|
|
162
|
-
""".strip()
|
|
163
|
-
|
|
164
|
-
mutants = [
|
|
165
|
-
mutant
|
|
166
|
-
for type_, mutant, _, _ in yield_mutants_for_module(parse(source), {})
|
|
167
|
-
if type_ == 'mutant'
|
|
168
|
-
]
|
|
169
|
-
for m in mutants:
|
|
170
|
-
print(m)
|
|
171
|
-
|
|
172
|
-
assert len(mutants) == 1
|
|
173
|
-
assert mutants[0] == f' def x{CLASS_NAME_SEPARATOR}Foo{CLASS_NAME_SEPARATOR}member__mutmut_1(self): \n return 2'
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
def mutants_for_source(source):
|
|
177
|
-
no_mutate_lines = pragma_no_mutate_lines(source)
|
|
178
|
-
r = []
|
|
179
|
-
for type_, x, name_and_hash, mutant_name in yield_mutants_for_module(parse(source, error_recovery=False), no_mutate_lines):
|
|
180
|
-
if type_ == 'mutant':
|
|
181
|
-
r.append(x)
|
|
182
|
-
return r
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
def test_function_with_annotation():
|
|
186
|
-
source = "def capitalize(s : str):\n return s[0].upper() + s[1:] if s else s\n".strip()
|
|
187
|
-
mutants = mutants_for_source(source)
|
|
188
|
-
assert mutants == [
|
|
189
|
-
'def capitalize__mutmut_1(s : str):\n return s[1].upper() + s[1:] if s else s',
|
|
190
|
-
'def capitalize__mutmut_2(s : str):\n return s[None].upper() + s[1:] if s else s',
|
|
191
|
-
'def capitalize__mutmut_3(s : str):\n return s[0].upper() - s[1:] if s else s',
|
|
192
|
-
'def capitalize__mutmut_4(s : str):\n return s[0].upper() + s[2:] if s else s',
|
|
193
|
-
'def capitalize__mutmut_5(s : str):\n return s[0].upper() + s[None] if s else s'
|
|
194
|
-
]
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
def test_pragma_no_mutate():
|
|
198
|
-
source = """def foo():\n return 1+1 # pragma: no mutate\n""".strip()
|
|
199
|
-
mutants = mutants_for_source(source)
|
|
200
|
-
assert not mutants
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
def test_pragma_no_mutate_and_no_cover():
|
|
204
|
-
source = """def foo():\n return 1+1 # pragma: no cover, no mutate\n""".strip()
|
|
205
|
-
mutants = mutants_for_source(source)
|
|
206
|
-
assert not mutants
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
def test_mutate_dict():
|
|
210
|
-
source = '''
|
|
211
|
-
def foo():
|
|
212
|
-
dict(a=b, c=d)
|
|
213
|
-
'''
|
|
214
|
-
mutants = mutants_for_source(source)
|
|
215
|
-
assert mutants == [
|
|
216
|
-
'\ndef foo__mutmut_1(): \n dict(a=None, c=d)\n',
|
|
217
|
-
'\ndef foo__mutmut_2(): \n dict(aXX=b, c=d)\n',
|
|
218
|
-
'\ndef foo__mutmut_3(): \n dict(a=b, c=None)\n',
|
|
219
|
-
'\ndef foo__mutmut_4(): \n dict(a=b, cXX=d)\n',
|
|
220
|
-
'\ndef foo__mutmut_5(): \n dict( c=d)\n',
|
|
221
|
-
'\ndef foo__mutmut_6(): \n dict(a=b,)\n',
|
|
222
|
-
]
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
def test_syntax_error():
|
|
226
|
-
with pytest.raises(Exception):
|
|
227
|
-
mutants_for_source(':!')
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
def test_bug_github_issue_18():
|
|
231
|
-
source = """
|
|
232
|
-
@register.simple_tag(name='icon')
|
|
233
|
-
def icon(name):
|
|
234
|
-
if name is None:
|
|
235
|
-
return ''
|
|
236
|
-
tpl = '<span class="glyphicon glyphicon-{}"></span>'
|
|
237
|
-
return format_html(tpl, name)
|
|
238
|
-
""".strip()
|
|
239
|
-
mutants_for_source(source)
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
def test_bug_github_issue_19_argument_mutation_crash():
|
|
243
|
-
source = """key = lambda a: "foo"
|
|
244
|
-
filters = dict((key(field), False) for field in fields)"""
|
|
245
|
-
mutants_for_source(source)
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
def test_bug_github_issue_26():
|
|
249
|
-
source = """
|
|
250
|
-
def wrapper():
|
|
251
|
-
class ConfigurationOptions(Protocol):
|
|
252
|
-
min_name_length: int
|
|
253
|
-
""".strip()
|
|
254
|
-
assert mutants_for_source(source) == []
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
def test_bug_github_issue_30():
|
|
258
|
-
source = """
|
|
259
|
-
def wrapper():
|
|
260
|
-
def from_checker(cls: Type['BaseVisitor'], checker) -> 'BaseVisitor':
|
|
261
|
-
pass
|
|
262
|
-
""".strip()
|
|
263
|
-
assert mutants_for_source(source) == []
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
def test_bug_github_issue_77():
|
|
267
|
-
# Don't crash on this
|
|
268
|
-
assert mutants_for_source('') == []
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
def test_multiline_dunder_whitelist():
|
|
272
|
-
source = """
|
|
273
|
-
__all__ = [
|
|
274
|
-
1,
|
|
275
|
-
2,
|
|
276
|
-
'foo',
|
|
277
|
-
'bar',
|
|
278
|
-
]
|
|
279
|
-
""".strip()
|
|
280
|
-
mutants = mutants_for_source(source)
|
|
281
|
-
assert not mutants
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
def test_bad_mutation_str_type_definition():
|
|
285
|
-
source = """
|
|
286
|
-
def foo():
|
|
287
|
-
foo: 'SomeType'
|
|
288
|
-
""".strip()
|
|
289
|
-
mutants = mutants_for_source(source)
|
|
290
|
-
assert not mutants
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
def test_orig_function_name_from_key():
|
|
294
|
-
assert orig_function_and_class_names_from_key(f'_{CLASS_NAME_SEPARATOR}Foo{CLASS_NAME_SEPARATOR}bar__mutmut_1') == ('bar', 'Foo')
|
|
295
|
-
assert orig_function_and_class_names_from_key('bar__mutmut_1') == ('bar', None)
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
def test_mangle_function_name():
|
|
299
|
-
assert mangle_function_name(name='bar', class_name=None) == 'bar'
|
|
300
|
-
assert mangle_function_name(name='bar', class_name='Foo') == f'x{CLASS_NAME_SEPARATOR}Foo{CLASS_NAME_SEPARATOR}bar'
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
def test_diff_ops():
|
|
304
|
-
source = """
|
|
305
|
-
def foo():
|
|
306
|
-
return 1
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
class Foo:
|
|
310
|
-
def member(self):
|
|
311
|
-
return 3
|
|
312
|
-
|
|
313
|
-
""".strip()
|
|
314
|
-
|
|
315
|
-
out = StringIO()
|
|
316
|
-
mutant_names, hash_by_function_name = write_all_mutants_to_file(out=out, source=source, filename='filename')
|
|
317
|
-
assert len(mutant_names) == 2
|
|
318
|
-
mutants_source = out.getvalue()
|
|
319
|
-
|
|
320
|
-
diff1 = get_diff_for_mutant(mutant_name=mutant_names[0], source=mutants_source, path='test.py').strip()
|
|
321
|
-
diff2 = get_diff_for_mutant(mutant_name=mutant_names[1], source=mutants_source, path='test.py').strip()
|
|
322
|
-
|
|
323
|
-
assert diff1 == '''
|
|
324
|
-
--- test.py
|
|
325
|
-
+++ test.py
|
|
326
|
-
@@ -1,2 +1,2 @@
|
|
327
|
-
def foo():
|
|
328
|
-
- return 1
|
|
329
|
-
+ return 2
|
|
330
|
-
'''.strip()
|
|
331
|
-
|
|
332
|
-
assert diff2 == '''
|
|
333
|
-
--- test.py
|
|
334
|
-
+++ test.py
|
|
335
|
-
@@ -1,2 +1,2 @@
|
|
336
|
-
def member(self):
|
|
337
|
-
- return 3
|
|
338
|
-
+ return 4
|
|
339
|
-
'''.strip()
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
from parso import parse
|
|
2
|
-
|
|
3
|
-
from mutmut.__main__ import (
|
|
4
|
-
trampoline_impl,
|
|
5
|
-
yield_mutants_for_module,
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def test_yield_mutants_for_module():
|
|
10
|
-
source = """
|
|
11
|
-
a + 1
|
|
12
|
-
|
|
13
|
-
def foo(a, b, c):
|
|
14
|
-
return a + b * c
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
expected = trampoline_impl + """
|
|
18
|
-
|
|
19
|
-
a + 1
|
|
20
|
-
|
|
21
|
-
def foo__mutmut_orig(a, b, c):
|
|
22
|
-
return a + b * c
|
|
23
|
-
|
|
24
|
-
def foo__mutmut_1(a, b, c):
|
|
25
|
-
return a - b * c
|
|
26
|
-
|
|
27
|
-
def foo__mutmut_2(a, b, c):
|
|
28
|
-
return a + b / c
|
|
29
|
-
|
|
30
|
-
foo__mutmut_mutants = {
|
|
31
|
-
'foo__mutmut_1': foo__mutmut_1,
|
|
32
|
-
'foo__mutmut_2': foo__mutmut_2
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
def foo(*args, **kwargs):
|
|
36
|
-
return _mutmut_trampoline(foo__mutmut_orig, foo__mutmut_mutants, *args, **kwargs)
|
|
37
|
-
|
|
38
|
-
foo.__signature__ = _mutmut_signature(foo__mutmut_orig)
|
|
39
|
-
foo__mutmut_orig.__name__ = 'foo'
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
node = parse(source)
|
|
45
|
-
result = ''.join([x[1] for x in yield_mutants_for_module(node, no_mutate_lines=[])])
|
|
46
|
-
|
|
47
|
-
assert result == expected
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def test_avoid_annotations():
|
|
51
|
-
source = """
|
|
52
|
-
def foo(a: List[int]) -> int:
|
|
53
|
-
return 1
|
|
54
|
-
"""
|
|
55
|
-
|
|
56
|
-
expected = trampoline_impl + """
|
|
57
|
-
|
|
58
|
-
def foo__mutmut_orig(a: List[int]) -> int:
|
|
59
|
-
return 1
|
|
60
|
-
|
|
61
|
-
def foo__mutmut_1(a: List[int]) -> int:
|
|
62
|
-
return 2
|
|
63
|
-
|
|
64
|
-
foo__mutmut_mutants = {
|
|
65
|
-
'foo__mutmut_1': foo__mutmut_1
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
def foo(*args, **kwargs):
|
|
69
|
-
return _mutmut_trampoline(foo__mutmut_orig, foo__mutmut_mutants, *args, **kwargs)
|
|
70
|
-
|
|
71
|
-
foo.__signature__ = _mutmut_signature(foo__mutmut_orig)
|
|
72
|
-
foo__mutmut_orig.__name__ = 'foo'
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
"""
|
|
76
|
-
|
|
77
|
-
node = parse(source)
|
|
78
|
-
result = ''.join([x[1] for x in yield_mutants_for_module(node, no_mutate_lines=[])])
|
|
79
|
-
|
|
80
|
-
assert result == expected
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|