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.
- quelltest-0.1.0/.claude/settings.local.json +26 -0
- quelltest-0.1.0/.github/workflows/ci.yml +38 -0
- quelltest-0.1.0/.github/workflows/release.yml +23 -0
- quelltest-0.1.0/CLAUDE.md +38 -0
- quelltest-0.1.0/PKG-INFO +104 -0
- quelltest-0.1.0/QUELL_SPEC.md +1910 -0
- quelltest-0.1.0/README.md +68 -0
- quelltest-0.1.0/docs/configuration.md +36 -0
- quelltest-0.1.0/docs/index.md +19 -0
- quelltest-0.1.0/docs/quickstart.md +47 -0
- quelltest-0.1.0/pyproject.toml +73 -0
- quelltest-0.1.0/quell/__init__.py +21 -0
- quelltest-0.1.0/quell/adapters/__init__.py +0 -0
- quelltest-0.1.0/quell/adapters/base.py +12 -0
- quelltest-0.1.0/quell/adapters/mutmut_adapter.py +104 -0
- quelltest-0.1.0/quell/adapters/stryker_adapter.py +65 -0
- quelltest-0.1.0/quell/cli.py +333 -0
- quelltest-0.1.0/quell/core/__init__.py +0 -0
- quelltest-0.1.0/quell/core/analyzer.py +160 -0
- quelltest-0.1.0/quell/core/generator.py +261 -0
- quelltest-0.1.0/quell/core/models.py +100 -0
- quelltest-0.1.0/quell/core/verifier.py +170 -0
- quelltest-0.1.0/quell/core/writer.py +95 -0
- quelltest-0.1.0/quell/llm/__init__.py +0 -0
- quelltest-0.1.0/quell/llm/client.py +30 -0
- quelltest-0.1.0/quell/llm/prompts.py +61 -0
- quelltest-0.1.0/quell/llm/providers/__init__.py +0 -0
- quelltest-0.1.0/quell/llm/providers/anthropic_provider.py +18 -0
- quelltest-0.1.0/quell/llm/providers/ollama_provider.py +20 -0
- quelltest-0.1.0/quell/llm/providers/openai_provider.py +18 -0
- quelltest-0.1.0/quell/ui/__init__.py +0 -0
- quelltest-0.1.0/quell/ui/console.py +4 -0
- quelltest-0.1.0/quell/ui/diff.py +18 -0
- quelltest-0.1.0/quell/ui/progress.py +12 -0
- quelltest-0.1.0/tests/adapters/__init__.py +0 -0
- quelltest-0.1.0/tests/adapters/test_mutmut_adapter.py +130 -0
- quelltest-0.1.0/tests/adapters/test_stryker_adapter.py +76 -0
- quelltest-0.1.0/tests/conftest.py +120 -0
- quelltest-0.1.0/tests/fixtures/sample_project/src/__init__.py +0 -0
- quelltest-0.1.0/tests/fixtures/sample_project/src/calculator.py +20 -0
- quelltest-0.1.0/tests/fixtures/sample_project/tests/test_calculator.py +24 -0
- quelltest-0.1.0/tests/fixtures/stryker_report.json +45 -0
- quelltest-0.1.0/tests/integration/__init__.py +0 -0
- quelltest-0.1.0/tests/integration/test_end_to_end.py +137 -0
- quelltest-0.1.0/tests/unit/__init__.py +0 -0
- quelltest-0.1.0/tests/unit/test_analyzer.py +128 -0
- quelltest-0.1.0/tests/unit/test_generator.py +151 -0
- quelltest-0.1.0/tests/unit/test_verifier.py +198 -0
- quelltest-0.1.0/tests/unit/test_writer.py +105 -0
- 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)
|
quelltest-0.1.0/PKG-INFO
ADDED
|
@@ -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
|