quelltest 0.1.0__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.
Files changed (50) hide show
  1. quelltest-0.1.0/.claude/settings.local.json +26 -0
  2. quelltest-0.1.0/.github/workflows/ci.yml +38 -0
  3. quelltest-0.1.0/.github/workflows/release.yml +23 -0
  4. quelltest-0.1.0/CLAUDE.md +38 -0
  5. quelltest-0.1.0/PKG-INFO +104 -0
  6. quelltest-0.1.0/QUELL_SPEC.md +1910 -0
  7. quelltest-0.1.0/README.md +68 -0
  8. quelltest-0.1.0/docs/configuration.md +36 -0
  9. quelltest-0.1.0/docs/index.md +19 -0
  10. quelltest-0.1.0/docs/quickstart.md +47 -0
  11. quelltest-0.1.0/pyproject.toml +73 -0
  12. quelltest-0.1.0/quell/__init__.py +21 -0
  13. quelltest-0.1.0/quell/adapters/__init__.py +0 -0
  14. quelltest-0.1.0/quell/adapters/base.py +12 -0
  15. quelltest-0.1.0/quell/adapters/mutmut_adapter.py +104 -0
  16. quelltest-0.1.0/quell/adapters/stryker_adapter.py +65 -0
  17. quelltest-0.1.0/quell/cli.py +333 -0
  18. quelltest-0.1.0/quell/core/__init__.py +0 -0
  19. quelltest-0.1.0/quell/core/analyzer.py +160 -0
  20. quelltest-0.1.0/quell/core/generator.py +261 -0
  21. quelltest-0.1.0/quell/core/models.py +100 -0
  22. quelltest-0.1.0/quell/core/verifier.py +170 -0
  23. quelltest-0.1.0/quell/core/writer.py +95 -0
  24. quelltest-0.1.0/quell/llm/__init__.py +0 -0
  25. quelltest-0.1.0/quell/llm/client.py +30 -0
  26. quelltest-0.1.0/quell/llm/prompts.py +61 -0
  27. quelltest-0.1.0/quell/llm/providers/__init__.py +0 -0
  28. quelltest-0.1.0/quell/llm/providers/anthropic_provider.py +18 -0
  29. quelltest-0.1.0/quell/llm/providers/ollama_provider.py +20 -0
  30. quelltest-0.1.0/quell/llm/providers/openai_provider.py +18 -0
  31. quelltest-0.1.0/quell/ui/__init__.py +0 -0
  32. quelltest-0.1.0/quell/ui/console.py +4 -0
  33. quelltest-0.1.0/quell/ui/diff.py +18 -0
  34. quelltest-0.1.0/quell/ui/progress.py +12 -0
  35. quelltest-0.1.0/tests/adapters/__init__.py +0 -0
  36. quelltest-0.1.0/tests/adapters/test_mutmut_adapter.py +130 -0
  37. quelltest-0.1.0/tests/adapters/test_stryker_adapter.py +76 -0
  38. quelltest-0.1.0/tests/conftest.py +120 -0
  39. quelltest-0.1.0/tests/fixtures/sample_project/src/__init__.py +0 -0
  40. quelltest-0.1.0/tests/fixtures/sample_project/src/calculator.py +20 -0
  41. quelltest-0.1.0/tests/fixtures/sample_project/tests/test_calculator.py +24 -0
  42. quelltest-0.1.0/tests/fixtures/stryker_report.json +45 -0
  43. quelltest-0.1.0/tests/integration/__init__.py +0 -0
  44. quelltest-0.1.0/tests/integration/test_end_to_end.py +137 -0
  45. quelltest-0.1.0/tests/unit/__init__.py +0 -0
  46. quelltest-0.1.0/tests/unit/test_analyzer.py +128 -0
  47. quelltest-0.1.0/tests/unit/test_generator.py +151 -0
  48. quelltest-0.1.0/tests/unit/test_verifier.py +198 -0
  49. quelltest-0.1.0/tests/unit/test_writer.py +105 -0
  50. quelltest-0.1.0/uv.lock +1201 -0
@@ -0,0 +1,26 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(uv sync *)",
5
+ "Bash(pip3 --version)",
6
+ "Bash(pip --version)",
7
+ "Bash(pip install *)",
8
+ "Bash(python -m uv --version)",
9
+ "Bash(python -m uv sync --dev)",
10
+ "Bash(python -m uv sync --extra dev)",
11
+ "Bash(python -m uv run pytest tests/ -v)",
12
+ "Bash(python -m uv venv /tmp/quell-verify --python 3.11)",
13
+ "Bash(python -m uv venv /tmp/quell-verify)",
14
+ "Bash(python -m uv pip install --python .venv/Scripts/python.exe -e \".[dev]\")",
15
+ "Bash(cat /tmp/quell-verify/bvenkzlwk.output 2>/dev/null || true)",
16
+ "Read(//tmp/quell-verify/**)",
17
+ "Bash(python -m uv venv /tmp/quell-verify --seed)",
18
+ "Bash(python -m uv pip install --python /c/Users/binda/AppData/Local/Temp/quell-verify/Scripts/python.exe -e '.[dev]')",
19
+ "Bash(/c/Users/binda/AppData/Local/Temp/quell-verify/Scripts/python.exe -m pytest tests/ -v --tb=short)",
20
+ "Bash(python -m uv build)",
21
+ "Bash(python -m uv publish --token \"pypi-AgEIcHlwaS5vcmcCJDIxMTZiMzk1LTFkYWItNDk3Yy1hOTI5LWYzYTFiNDRjZDc0NwACKlszLCI1MGNiOWNiNy1hOGFiLTRmYjctOTM0YS1jMGUyZWIzNmU2OWYiXQAABiByWgSJydXoe_mWeESQi1vIFCiYJPowsRqv9I_DpOmzsg\")",
22
+ "Bash(python -m uv pip show quell)",
23
+ "Bash(python -m pip index versions quell)"
24
+ ]
25
+ }
26
+ }
@@ -0,0 +1,38 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.11", "3.12"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Install uv
20
+ uses: astral-sh/setup-uv@v2
21
+
22
+ - name: Set up Python ${{ matrix.python-version }}
23
+ run: uv python install ${{ matrix.python-version }}
24
+
25
+ - name: Install dependencies
26
+ run: uv sync --all-extras --dev
27
+
28
+ - name: Lint
29
+ run: uv run ruff check .
30
+
31
+ - name: Type check
32
+ run: uv run mypy quell/
33
+
34
+ - name: Test
35
+ run: uv run pytest tests/ -v --cov=quell --cov-report=xml
36
+
37
+ - name: Upload coverage
38
+ uses: codecov/codecov-action@v4
@@ -0,0 +1,23 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ release:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - name: Install uv
15
+ uses: astral-sh/setup-uv@v2
16
+
17
+ - name: Build
18
+ run: uv build
19
+
20
+ - name: Publish to PyPI
21
+ run: uv publish
22
+ env:
23
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
@@ -0,0 +1,38 @@
1
+ # Quell — AI Assistant Instructions
2
+
3
+ ## What this project is
4
+ Quell auto-generates verified killing tests for survived mutants from mutmut and Stryker.
5
+ It reads mutation testing results, generates pytest assertions using rule-based logic + LLMs,
6
+ verifies each test actually kills the mutant, and injects it into test files via libcst.
7
+
8
+ ## Tech Stack
9
+ - Python 3.11+, Typer CLI, Rich terminal UI, Pydantic v2, libcst, pytest
10
+
11
+ ## Key invariants — NEVER violate these
12
+ 1. `verifier.py`: ALWAYS restore source files in a `finally` block
13
+ 2. `writer.py`: ALWAYS backup before writing, ALWAYS restore on failure
14
+ 3. `writer.py`: ALWAYS validate CST parses correctly before writing to disk
15
+ 4. NO code is transmitted to any server except the configured LLM provider
16
+ 5. The LLM is ONLY called when rule-based generation is insufficient
17
+
18
+ ## Running tests
19
+ ```bash
20
+ uv run pytest tests/ -v
21
+ ```
22
+
23
+ ## Adding a new mutation operator
24
+ 1. Add the enum value to `MutationOperator` in `core/models.py`
25
+ 2. Add classification logic to `_classify_operator` in `core/analyzer.py`
26
+ 3. Add generator method `_generate_<operator>_test` in `core/generator.py`
27
+ 4. Add route in `generate()` method in `core/generator.py`
28
+ 5. Add tests in `tests/unit/test_generator.py`
29
+
30
+ ## Adding a new mutation adapter (e.g., PIT for Java)
31
+ 1. Create `adapters/pit_adapter.py` implementing `MutationAdapter` protocol
32
+ 2. Add it to `_get_adapter()` in `cli.py`
33
+ 3. Add integration tests in `tests/adapters/`
34
+
35
+ ## Code style
36
+ - Run `ruff check . --fix` before committing
37
+ - All public functions must have docstrings
38
+ - Pydantic models for all data structures (no raw dicts crossing module boundaries)
@@ -0,0 +1,104 @@
1
+ Metadata-Version: 2.4
2
+ Name: quelltest
3
+ Version: 0.1.0
4
+ Summary: Auto-generates verified killing tests for survived mutants from mutmut and Stryker
5
+ Project-URL: Homepage, https://github.com/shashank7109/quell
6
+ Project-URL: Documentation, https://quell.dev
7
+ Project-URL: Repository, https://github.com/shashank7109/quell
8
+ Project-URL: Issues, https://github.com/shashank7109/quell/issues
9
+ Author-email: Shashank Bindal <bindalshashank.89@gmail.com>
10
+ License: MIT
11
+ Keywords: mutation-testing,mutmut,pytest,stryker,test-generation,testing
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Testing
19
+ Requires-Python: >=3.11
20
+ Requires-Dist: anthropic>=0.28.0
21
+ Requires-Dist: httpx>=0.27.0
22
+ Requires-Dist: libcst>=1.3.0
23
+ Requires-Dist: openai>=1.30.0
24
+ Requires-Dist: pydantic>=2.6.0
25
+ Requires-Dist: rich>=13.7.0
26
+ Requires-Dist: tomli>=2.0.0; python_version < '3.11'
27
+ Requires-Dist: typer>=0.12.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: mypy>=1.10.0; extra == 'dev'
30
+ Requires-Dist: pre-commit>=3.7.0; extra == 'dev'
31
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
32
+ Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
33
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
34
+ Requires-Dist: ruff>=0.4.0; extra == 'dev'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # Quell
38
+
39
+ > *Quell your survivors. Strengthen your tests.*
40
+
41
+ Quell auto-generates verified, killing tests for survived mutants from mutmut and Stryker.
42
+
43
+ ## What it does
44
+
45
+ Quell reads surviving mutants from mutation testing tools (mutmut for Python, Stryker for JS/TS), analyzes each surviving mutant using Python's AST (via libcst), generates a targeted pytest assertion that would catch the mutation, verifies the generated test actually kills the mutant by applying the mutant and running the test in a subprocess, then writes only verified tests to the test file using libcst (preserving formatting and comments).
46
+
47
+ - Code never leaves the machine (unless you configure an LLM provider)
48
+ - Every write is auto-restored on failure
49
+ - Full audit log is maintained
50
+
51
+ ## Installation
52
+
53
+ ```bash
54
+ pip install quell
55
+ ```
56
+
57
+ ## Quick Start
58
+
59
+ ```bash
60
+ # Step 1: Run your mutation testing tool first
61
+ mutmut run # for Python projects
62
+ npx stryker run --reporters=json # for JS/TS projects
63
+
64
+ # Step 2: Let quell scan survivors
65
+ quell scan # see what survived
66
+
67
+ # Step 3: Fix interactively
68
+ quell fix # review + apply one by one
69
+
70
+ # Step 4: Or auto-fix everything
71
+ quell auto --dry-run # preview
72
+ quell auto # apply all verified tests
73
+
74
+ # Config (optional)
75
+ quell init # adds [tool.quell] to pyproject.toml
76
+
77
+ # Use local LLM (privacy-first)
78
+ quell fix --llm ollama # requires ollama running locally
79
+ ```
80
+
81
+ ## Configuration
82
+
83
+ Add `[tool.quell]` to your `pyproject.toml`:
84
+
85
+ ```toml
86
+ [tool.quell]
87
+ llm_provider = "anthropic" # "anthropic" | "openai" | "ollama"
88
+ llm_model = "claude-sonnet-4-5"
89
+ max_verification_attempts = 3
90
+ verification_timeout_seconds = 30
91
+ auto_write = false
92
+ ```
93
+
94
+ Set your API key:
95
+
96
+ ```bash
97
+ export ANTHROPIC_API_KEY=sk-...
98
+ # or
99
+ export OPENAI_API_KEY=sk-...
100
+ ```
101
+
102
+ ## License
103
+
104
+ MIT