Skip to content

Commit bfc9641

Browse files
committed
Add CONTRIBUTING.md, docs contributing page, and tests badge
- CONTRIBUTING.md with dev setup, testing, linting, code style, and PR guidelines - docs/contributing.md includes repo-root file via MyST directive - Add Contributing grid card and toctree entry in docs/index.md - Add tests CI badge, Running tests section, and Contributing section to README
1 parent 210ffd8 commit bfc9641

4 files changed

Lines changed: 180 additions & 2 deletions

File tree

CONTRIBUTING.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Contributing to respyra
2+
3+
Thanks for your interest in contributing to respyra! This guide covers everything
4+
you need to get started.
5+
6+
## Development setup
7+
8+
respyra requires **Python 3.10** (PsychoPy does not yet support 3.11+).
9+
10+
```bash
11+
git clone https://github.com/embodied-computation-group/respyra.git
12+
cd respyra
13+
14+
# Create a Python 3.10 virtual environment
15+
# Windows (Python Launcher)
16+
py -3.10 -m venv .venv
17+
.venv\Scripts\activate
18+
19+
# macOS / Linux
20+
python3.10 -m venv .venv
21+
source .venv/bin/activate
22+
23+
# Install in editable mode with dev and vis extras
24+
pip install -e ".[dev,vis]"
25+
```
26+
27+
This installs the runtime dependencies plus **ruff** (linter/formatter),
28+
**pytest** and **pytest-cov** (testing), **pandas** and **matplotlib** (visualization).
29+
30+
## Running tests
31+
32+
The test suite lives in `tests/` and covers every module in `respyra/core/`.
33+
34+
```bash
35+
# Run all tests
36+
pytest tests/ -v
37+
38+
# Run with coverage report
39+
pytest tests/ -v --cov=respyra --cov-report=term-missing
40+
```
41+
42+
### Mock strategy
43+
44+
PsychoPy and godirect cannot be installed in most CI environments, so
45+
`tests/conftest.py` patches them out at the `sys.modules` level before any
46+
test module imports `respyra.core.*`. The mock list includes:
47+
48+
- `psychopy` and its subpackages (`psychopy.visual`, `psychopy.core`, etc.)
49+
- `godirect`
50+
51+
This happens at **module level** in `conftest.py` (not inside fixtures) because
52+
Python caches imports — by the time a fixture runs, the import has already
53+
happened. Tests then create focused mocks for the specific objects they need.
54+
55+
## Linting and formatting
56+
57+
respyra uses [ruff](https://docs.astral.sh/ruff/) for both linting and formatting.
58+
Configuration lives in `pyproject.toml` under `[tool.ruff]`.
59+
60+
```bash
61+
# Check for lint errors
62+
ruff check .
63+
64+
# Auto-fix what can be fixed
65+
ruff check . --fix
66+
67+
# Check formatting
68+
ruff format --check .
69+
70+
# Apply formatting
71+
ruff format .
72+
```
73+
74+
**Enabled rule sets:** `E` `F` `W` (pyflakes/pycodestyle), `I` (isort import
75+
ordering), `UP` (pyupgrade), `B` (flake8-bugbear), `SIM` (flake8-simplify).
76+
77+
CI runs `ruff check` and `ruff format --check` on every push and pull request —
78+
both must pass.
79+
80+
## Code style
81+
82+
- **Line length:** 99 characters
83+
- **Quote style:** ruff default (double quotes)
84+
- **Import ordering:** handled by `ruff check` with the `I` (isort) rule
85+
- **Target version:** Python 3.10
86+
87+
## Adding tests
88+
89+
Test files go in `tests/` and follow the naming convention `test_<module>.py`.
90+
Each file tests the corresponding module in `respyra/core/`.
91+
92+
| Test file | Module under test |
93+
|---|---|
94+
| `test_breath_belt.py` | `respyra.core.breath_belt` |
95+
| `test_data_logger.py` | `respyra.core.data_logger` |
96+
| `test_display.py` | `respyra.core.display` |
97+
| `test_events.py` | `respyra.core.events` |
98+
| `test_target_generator.py` | `respyra.core.target_generator` |
99+
100+
### How conftest mocking works
101+
102+
The `conftest.py` at the root of `tests/` inserts `MagicMock` objects into
103+
`sys.modules` for PsychoPy and godirect. This means:
104+
105+
- You can `from respyra.core import <module>` freely in tests — the imports
106+
won't fail even without PsychoPy installed.
107+
- PsychoPy objects (e.g., `visual.Window`, `visual.TextStim`) are `MagicMock`
108+
instances. If your test needs specific return values, mock them explicitly
109+
in the test function.
110+
- Shared fixtures like `simple_segment` and `simple_condition` are defined in
111+
`conftest.py` and available to all test files.
112+
113+
### What to mock
114+
115+
- **PsychoPy objects** — already handled by conftest; add focused patches if
116+
you need specific behavior (e.g., `window.size` returning `(1920, 1080)`).
117+
- **File I/O** — use `tmp_path` (pytest built-in) for tests that write files.
118+
- **gdx / breath belt** — mock the `GdxDevice` or belt reader; never connect
119+
to real hardware in tests.
120+
121+
## Project structure
122+
123+
See the [README](https://github.com/embodied-computation-group/respyra#project-structure) for a full directory tree and the
124+
[documentation](https://embodied-computation-group.github.io/respyra/) for
125+
detailed API reference and user guides.
126+
127+
## Submitting changes
128+
129+
1. **Fork** the repository and create a feature branch from `main`.
130+
2. Make your changes, adding tests for new functionality.
131+
3. Ensure **lint** and **tests** pass locally:
132+
```bash
133+
ruff check .
134+
ruff format --check .
135+
pytest tests/ -v
136+
```
137+
4. Commit with a clear, descriptive message.
138+
5. Open a **pull request** against `main`. CI will run lint and test checks
139+
automatically — both must pass before merging.
140+
141+
## The `gdx/` directory
142+
143+
The `respyra/core/gdx/` directory contains third-party code from
144+
[VernierST/godirect-examples](https://github.com/VernierST/godirect-examples),
145+
licensed under the **BSD 3-Clause License** (see `respyra/core/gdx/LICENSE`).
146+
147+
This directory is:
148+
- **Excluded from ruff linting** (configured in `pyproject.toml`)
149+
- **Not covered by the test suite**
150+
151+
Please do not modify files in `gdx/` unless there is a specific upstream
152+
compatibility issue that requires a patch.

README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
</p>
1010

1111
<p align="center">
12+
<a href="https://github.com/embodied-computation-group/respyra/actions/workflows/test.yml"><img alt="Tests" src="https://github.com/embodied-computation-group/respyra/actions/workflows/test.yml/badge.svg"></a>
1213
<a href="https://pypi.org/project/respyra/"><img alt="PyPI" src="https://img.shields.io/pypi/v/respyra?color=blue"></a>
1314
<a href="https://embodied-computation-group.github.io/respyra/"><img alt="Docs" src="https://img.shields.io/badge/docs-online-brightgreen"></a>
1415
<a href="https://github.com/embodied-computation-group/respyra/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-yellow"></a>
@@ -68,12 +69,22 @@ python3.10 -m venv .venv
6869
source .venv/bin/activate
6970
```
7071

71-
Install in editable mode:
72+
Install in editable mode with dev extras:
7273

7374
```bash
74-
pip install -e ".[vis]"
75+
pip install -e ".[dev,vis]"
7576
```
7677

78+
### Running tests
79+
80+
```bash
81+
pytest tests/ -v
82+
```
83+
84+
PsychoPy and godirect are mocked at the `sys.modules` level so the test suite
85+
runs without hardware or heavy dependencies. See [CONTRIBUTING.md](CONTRIBUTING.md)
86+
for details on the mock strategy and adding new tests.
87+
7788
### Requirements
7889

7990
- **Python 3.10** -- PsychoPy does not yet support 3.11+
@@ -198,6 +209,11 @@ Full documentation is available at **[embodied-computation-group.github.io/respy
198209

199210
**macOS**: Works with both BLE and USB out of the box.
200211

212+
## Contributing
213+
214+
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for development
215+
setup, testing, linting, and pull request guidelines.
216+
201217
## License
202218

203219
[MIT](LICENSE)

docs/contributing.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
```{include} ../CONTRIBUTING.md
2+
```

docs/index.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ BLE issues, sensor saturation, frame drops, and more
111111
Swap in a different respiratory sensor
112112
:::
113113

114+
:::{grid-item-card} Contributing
115+
:link: contributing
116+
:link-type: doc
117+
118+
Development setup, testing, linting, and pull requests
119+
:::
120+
114121
::::
115122

116123
```{toctree}
@@ -125,4 +132,5 @@ examples/index
125132
visualization
126133
troubleshooting
127134
adapting_belt
135+
contributing
128136
```

0 commit comments

Comments
 (0)