Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ The project uses extremely strict mypy settings including `disallow_any_expr=tru
**Testing Requirements:**
All changes must maintain 100% branch coverage. Test both runtime and compiled behavior, plus async and thread-safe variants where applicable. Use descriptive test names: `test_<feature>_<scenario>_<expected_behavior>()`.
Comment thread
alganet marked this conversation as resolved.

**Testing Conventions:**
- **Compiled Objects**: Use `wired = execd["compiled"]` from `exec(code, execd)`. Do not instantiate `Compiled` manually.
Comment thread
alganet marked this conversation as resolved.
- **Type Safety**: Use `typing.Protocol` for dynamic/compiled objects. Avoid `Any` and `type: ignore`.
- **Module Mocking**: Use `sys.modules` injection with `try...finally` cleanup for custom classes.
- **Async Tests**: Use `asyncio.run()` explicitly within test functions.

**Common Gotchas:**
- SPDX headers required on all files (run `make format` to auto-add)
- 79-character line limit enforced by `black`
Expand Down
26 changes: 26 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,32 @@ pytest -xvs

The project enforces 95% test coverage or higher. New code should include comprehensive tests.

#### Testing Conventions

- **Compiled Code Testing**: When testing compiled code, use the pre-instantiated `compiled` object from the execution namespace instead of manually instantiating the class.
```python
exec(code, execd)
wired = execd["compiled"] # Use this instance
```
- **Type Safety in Tests**: Avoid `Any` and `type: ignore`. Use `typing.Protocol` to define the expected interface of dynamic or compiled objects.
```python
class MockConfig(Protocol):
def config(self) -> Config: ...

execd: dict[str, MockConfig] = {}
```
- **Coverage**: Aim for 100% branch coverage.
Comment thread
alganet marked this conversation as resolved.
- **Naming**: Use descriptive test names: `test_<feature>_<scenario>_<expected_behavior>()`.
- **Module Mocking**: When testing custom classes, inject them into `sys.modules` using a `try...finally` block to ensure cleanup.
```python
class MockModule(ModuleType): ...
sys.modules["mymod"] = MockModule()
try:
# test code
finally:
del sys.modules["mymod"]
```
Comment thread
alganet marked this conversation as resolved.

### Code Formatting

The project uses `black` and `isort` for code formatting:
Expand Down