diff --git a/.cursor/rules/pr-after-first-push.mdc b/.cursor/rules/pr-after-first-push.mdc new file mode 100644 index 0000000..ee32313 --- /dev/null +++ b/.cursor/rules/pr-after-first-push.mdc @@ -0,0 +1,58 @@ +--- +description: After first branch push, provide copy-ready PR title and body +alwaysApply: true +--- + +# PR Title and Comment After First Push + +The user creates pull requests manually. After the **first push** of a feature branch to remote in a session, always end your response with a copy-ready PR title and PR comment. + +## When to provide it + +- After the first successful `git push` (or `git push -u origin `) for a branch in the current task +- Do **not** create the PR with `gh pr create` unless explicitly asked +- On later pushes to the same branch, only repeat if the user asks or the change set meaningfully updates what the PR should say + +## PR title + +- Use a fitting version-bump prefix when changes touch `python_repositories/`: + - `[patch]` or `[fix]` — bug fix + - `[minor]` or `[feat]` — new feature + - `[major]` or `[breaking]` — breaking change +- Docs-, CI-, or test-only changes: no prefix required +- Keep the title concise and descriptive + +## PR comment format + +Provide two separate fenced code blocks the user can copy directly: + +1. **PR title** — single line in a code block +2. **PR comment** — body with `## Summary` and `## Test plan` sections, checklist items reflecting what was actually run + +Example structure: + +```` +PR title: + +``` +[minor] Short description of the change +``` + +PR comment: + +``` +## Summary + +- Bullet points of what changed and why + +## Test plan + +- [x] Commands or checks that were run +``` +```` + +## Notes + +- Match the repo PR template ([`.gitea/PULL_REQUEST_TEMPLATE.md`](.gitea/PULL_REQUEST_TEMPLATE.md)) +- Be accurate: only mark test-plan items done if they were run +- Keep prose clear; the user copies this verbatim into Gitea diff --git a/.cursor/rules/test-organization.mdc b/.cursor/rules/test-organization.mdc new file mode 100644 index 0000000..9e2474a --- /dev/null +++ b/.cursor/rules/test-organization.mdc @@ -0,0 +1,31 @@ +--- +description: Unit test file naming and placement conventions +globs: tests/**/*.py +alwaysApply: false +--- + +# Test Organization + +Unit tests use a one-to-one mapping between source modules and test files. + +## Naming + +- `python_repositories//.py` → `tests/unit/_test.py` +- Test files must end with `_test.py` (enforced by pre-commit `name-tests-test`) + +## Placement + +- Add tests to the existing `*_test.py` for the module under test +- Do not create cross-cutting test files (e.g. `structural_typing_test.py`); colocate with the relevant interface/adapter/config test file +- Shared fixtures → `tests/conftest.py` +- Module-specific helper classes → the matching test file + +## Examples + +``` +json_repository_interface.py → tests/unit/json_repository_interface_test.py +redis_adapter.py → tests/unit/redis_adapter_test.py +redis_config.py → tests/unit/redis_config_test.py +``` + +Integration tests live under `tests/integration//` with the same `_test.py` suffix. diff --git a/README.md b/README.md index 1939d29..d793889 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,15 @@ uv run pytest -v # full suite (requires Doc Integration tests are marked with `@pytest.mark.integration` and require Docker (testcontainers). Backend-specific markers (`needs_redis`, `needs_minio`) let you run only the containers a test module needs. Run unit tests alone for quick local feedback. +### Test organization + +Unit tests live in `tests/unit/` and follow a one-to-one naming convention: `_test.py` tests `python_repositories/.py`. Examples: + +- `json_repository_interface.py` → `tests/unit/json_repository_interface_test.py` +- `redis_adapter.py` → `tests/unit/redis_adapter_test.py` + +Add new tests to the existing file for that module rather than creating cross-cutting test files. Shared fixtures belong in `tests/conftest.py`; module-specific helpers may live in the matching test file. + ### CI base image Gitea Actions jobs use a pre-built image (`python-repositories-ci`) with Python 3.12,