Skip to content

Commit d1adfc2

Browse files
authored
Merge pull request #374 from Otto-AA/libcst
Use LibCST instead of parso
2 parents b6fc4bc + fa78294 commit d1adfc2

File tree

18 files changed

+1321
-876
lines changed

18 files changed

+1321
-876
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Mutant files
2+
e2e_projects/**/mutants
3+
14
*.py[cod]
25
examples/db.sqlite3
36
venv

CONTRIBUTING.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ Running the tests
1919
2020
pytest
2121
22+
This also runs E2E tests that verify that `mutmut run` produces the same output as before. If your code changes should change the output of `mutmut run` and this test fails, try to delete the `snapshots/*.json` files (as described in the test errors).
23+
24+
If pytest terminates before reporting the test failures, it likely hit a case where mutmut calls `os._exit(...)`. Try looking at these calls first for troubleshooting.
25+
2226
Running your local version of Mutmut against a test codebase
2327
------------------------------------------------------------
2428

e2e_projects/my_lib/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This project will be E2E tested. It mainly serves as a "canary" that alerts you when code changes affect which mutants survive.

e2e_projects/my_lib/pyproject.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[project]
2+
name = "my-lib"
3+
version = "0.1.0"
4+
description = "Add your description here"
5+
readme = "README.md"
6+
authors = []
7+
requires-python = ">=3.10"
8+
dependencies = []
9+
10+
[build-system]
11+
requires = ["hatchling"]
12+
build-backend = "hatchling.build"
13+
14+
[dependency-groups]
15+
dev = [
16+
"pytest>=8.3.5",
17+
]
18+
19+
[tool.mutmut]
20+
debug = true
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from collections.abc import Callable
2+
from functools import cache
3+
from typing import Union
4+
5+
6+
def hello() -> str:
7+
return "Hello from my-lib!"
8+
9+
def badly_tested() -> str:
10+
return "Mutants for this method should survive"
11+
12+
def untested() -> str:
13+
return "Mutants for this method should survive"
14+
15+
def make_greeter(name: Union[str, None]) -> Callable[[], str]:
16+
def hi():
17+
if name:
18+
return "Hi " + name
19+
else:
20+
return "Hey there!"
21+
22+
return hi
23+
24+
def fibonacci(n: int) -> int:
25+
if n <= 1:
26+
return n
27+
return fibonacci(n - 1) + fibonacci(n - 2)
28+
29+
@cache
30+
def cached_fibonacci(n: int) -> int:
31+
if n <= 1:
32+
return n
33+
return fibonacci(n - 1) + fibonacci(n - 2)
34+
35+
class Point:
36+
def __init__(self, x: int, y: int) -> None:
37+
self.x = x
38+
self.y = y
39+
40+
def abs(self) -> 'Point':
41+
return Point(abs(self.x), abs(self.y))
42+
43+
def add(self, other: 'Point'):
44+
self.x += other.x
45+
self.y += other.y
46+
47+
def to_origin(self):
48+
self.x = 0
49+
self.y = 0
50+
51+
def ignored(self):
52+
self.foo = 'bar' # pragma: no mutate
53+
54+
@staticmethod
55+
def from_coords(coords) -> 'Point':
56+
return Point(coords[0], coords[1])
57+
58+
@property
59+
def coords(self):
60+
return self.x, self.y
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from my_lib import hello, Point, badly_tested, make_greeter, fibonacci, cached_fibonacci
2+
3+
"""These tests are flawed on purpose, some mutants survive and some are killed."""
4+
5+
def test_hello():
6+
assert hello() == 'Hello from my-lib!'
7+
8+
def test_badly_tested():
9+
assert badly_tested()
10+
11+
def test_greeter():
12+
greet = make_greeter("mut")
13+
assert greet() == "Hi mut"
14+
15+
def test_point():
16+
p = Point(0, 1)
17+
p.add(Point(1, 0))
18+
19+
assert p.x == 1
20+
assert p.y == 1
21+
22+
p.to_origin()
23+
24+
assert p.x == 0
25+
26+
assert isinstance(p.coords, tuple)
27+
28+
def test_point_from_coords():
29+
assert Point.from_coords((1, 2)).x == 1
30+
31+
def test_fibonacci():
32+
assert fibonacci(1) == 1
33+
assert cached_fibonacci(1) == 1

e2e_projects/my_lib/uv.lock

Lines changed: 119 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)