Skip to content

Commit 6618c8e

Browse files
committed
cursor(rules) More cursor rules for libvcs
1 parent f8fc79a commit 6618c8e

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
description:
3+
globs: tests/**/*.py
4+
alwaysApply: false
5+
---
6+
# Ground Rules for Writing vcspull Tests
7+
8+
## 1. Study First, Be Homogenous
9+
- **Analyze Existing Tests:** Before writing new tests, study `tests/test_sync.py`, `tests/test_config.py`, and other relevant test files to understand existing patterns, fixture usage, and assertion styles.
10+
- **Maintain Consistency:** Strive for homogeneity in test structure, naming conventions, and overall style.
11+
- **Project Conventions:** Adhere to project-specific conventions like using `typing as t` and `pathlib.Path` for all path manipulations.
12+
13+
## 2. Fixture Prioritization and Usage
14+
- **`libvcs` Fixtures First:** For any VCS-related operations (creating repos, committing, checking status), **always** prioritize using fixtures from `libvcs.pytest_plugin` (available via `vcspull/conftest.py`). Examples:
15+
- `create_git_remote_repo`, `create_svn_remote_repo`, `create_hg_remote_repo` (and their `mercurial`/`subversion` counterparts if using those directly) for setting up test repositories.
16+
- `git_repo`, `svn_repo`, `hg_repo` for pre-configured `Sync` objects.
17+
- `git_commit_envvars` for environment variables needed for git commits.
18+
- **Pytest Built-in Fixtures:** Utilize standard `pytest` fixtures like `tmp_path` for temporary files and directories.
19+
- **Custom Project Fixtures:**
20+
- For common non-VCS setup (e.g., mocked home/CWD, config file setup), use or create well-defined fixtures.
21+
- Place shared fixtures in `vcspull/conftest.py` or `vcspull/tests/conftest.py`. Module-specific fixtures can reside in the test file itself.
22+
- Example: `home_path`, `cwd_path` (refactored to use `monkeypatch`), `setup_teardown_test_config_dir`.
23+
- **`autouse=True`:** Use sparingly, only for fixtures that genuinely apply to *all* tests within their scope.
24+
25+
## 3. Mocking Strategy: `monkeypatch` vs. `mocker`
26+
- **`monkeypatch` (pytest built-in):**
27+
- **Environment & Globals:** Use for modifying global settings, environment variables (`monkeypatch.setenv()`, `monkeypatch.delenv()`), the current working directory (`monkeypatch.chdir()`), or `sys.path`.
28+
- **Patching Attributes/Builtins:** Use `monkeypatch.setattr()` to modify attributes of classes/objects (e.g., `pathlib.Path.home`) or to replace functions/methods in external libraries or Python builtins.
29+
- **Dictionary Items:** Use `monkeypatch.setitem()` and `monkeypatch.delitem()` for modifying dictionaries.
30+
- Refer to [Pytest Monkeypatch Documentation](https://docs.pytest.org/en/stable/how-to/monkeypatch.html).
31+
- **`mocker` (from `pytest-mock`):**
32+
- **Application Code:** Primarily use for patching functions, methods, or objects *within the `vcspull` application code itself* (e.g., `mocker.patch('vcspull.cli.add.some_function')`).
33+
- **Assertions:** Use `mocker` when you need to assert how a mock was called, its return values, or to simulate side effects for your application's internal logic.
34+
- **Clarity in Mocking (CRITICAL):**
35+
- For **every** use of `mocker.patch()`, `mocker.patch.object()`, `monkeypatch.setattr()`, `monkeypatch.setenv()`, etc., include comments explaining:
36+
- **`# WHAT:`**: What specific function, method, attribute, or environment variable is being simulated or altered.
37+
- **`# WHY:`**: The reason for the mock – what behavior is being controlled or isolated for the test's purpose.
38+
39+
## 4. Test Structure and Assertions
40+
- **Atomic Tests:** Each test function should verify a single, specific piece of functionality or scenario.
41+
- **Clear Naming:** Test functions and fixtures should have descriptive names (e.g., `test_add_repo_new_config_cwd`).
42+
- **Docstrings:** Test functions should have a concise docstring explaining what is being tested.
43+
- **Plain Assertions:** Use standard `assert` statements for verifications.
44+
- **Logging:** Use the `caplog` fixture to assert specific log messages when testing command output or internal logging.
45+
- **Error Handling:** Explicitly test for expected exceptions using `pytest.raises()`.
46+
47+
## 5. Code Coverage and Quality
48+
- **100% Coverage:** Aim for 100% test coverage for all new or modified code in `cli/add.py` and `cli/add_from_fs.py` (and any other modules).
49+
- **Test All Paths:** Ensure tests cover success cases, failure cases, edge conditions, and all logical branches within the code.
50+
- **Development Workflow:** Adhere to the project's quality assurance process:
51+
```
52+
uv run ruff check . --fix
53+
uv run ruff format .
54+
uv run mypy
55+
uv run py.test --cov -v
56+
```
57+
(Run these commands locally to verify changes).
58+
59+
## 6. `vcspull`-Specific Considerations
60+
- **Configuration Files:**
61+
- When testing config loading, mock `find_home_config_files` appropriately.
62+
- Use helpers like `vcspull.tests.helpers.save_config_yaml` (which internally uses `write_config`) for creating test configuration files in a controlled manner.
63+
- **Path Expansion:** Be mindful of `expand_dir`. If testing logic that depends on its behavior, provide controlled mocks for it or ensure `home_path` / `cwd_path` fixtures correctly influence its resolution.
64+
- **Avoid Manual VCS Subprocesses:**
65+
- **Do not** use `subprocess.run(["git", ...])` or similar direct VCS command calls for setting up repository states in tests if a `libvcs` fixture or library function can achieve the same result.
66+
- The only exception is when testing a function that *itself* directly uses `subprocess` (e.g., `get_git_origin_url`).
67+
- Refactor tests like `test_add_from_fs_integration_with_libvcs` to use `create_git_remote_repo` from `libvcs` instead of manual `git init` calls via `subprocess`.
68+
69+
By following these rules, we can ensure that new tests are robust, maintainable, consistent with the existing test suite, and effectively leverage the capabilities of `pytest` and `libvcs`.

0 commit comments

Comments
 (0)