Skip to content

Commit 0a88bdb

Browse files
Merge pull request #37 from richardkoehler/feat/update-tests
- Update tests - Add test coverage - Add tests to cover at least 50 % lines of code - Add testing in CI
2 parents 182f4d0 + 22595e8 commit 0a88bdb

30 files changed

Lines changed: 1915 additions & 1503 deletions

.github/workflows/ci.yml

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,11 @@ jobs:
2929
3030
- name: Lint
3131
run: |
32-
uv run ruff check --exclude tests .
32+
uv run ruff check .
3333
3434
- name: Format
3535
run: |
36-
uv run ruff format --check --exclude tests .
37-
38-
# Tests are temporarily disabled in CI until they are ready.
39-
# To re-enable, uncomment the step below once tests are stable.
40-
# - name: Run pytest
41-
# run: |
42-
# uv run pytest
36+
uv run ruff format --check .
4337
4438
type-check:
4539
name: Type Check
@@ -61,5 +55,47 @@ jobs:
6155
6256
- name: Type check
6357
run: |
64-
uv run ty check src
58+
uv run ty check .
59+
60+
test:
61+
name: Tests (${{ matrix.os }})
62+
runs-on: ${{ matrix.os }}
63+
strategy:
64+
fail-fast: false
65+
matrix:
66+
include:
67+
- os: ubuntu-latest
68+
- os: windows-latest
69+
# Apple Silicon (arm64); see https://github.com/actions/runner-images
70+
- os: macos-14
71+
72+
steps:
73+
- name: Checkout repository
74+
uses: actions/checkout@v6
6575

76+
- name: Set up uv
77+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57
78+
with:
79+
python-version: "3.14"
80+
enable-cache: true
81+
82+
- name: Sync dependencies
83+
run: |
84+
uv sync --locked --dev
85+
86+
# PySide6 links libEGL even for offscreen; ubuntu-latest images omit it by default.
87+
- name: Install Qt EGL/XCB dependencies (Ubuntu only)
88+
if: matrix.os == 'ubuntu-latest'
89+
run: |
90+
sudo apt-get update
91+
sudo apt-get install -y --no-install-recommends \
92+
libegl1 \
93+
libgl1 \
94+
libxkbcommon0 \
95+
libdbus-1-3
96+
97+
- name: Run pytest
98+
env:
99+
QT_QPA_PLATFORM: offscreen
100+
run: |
101+
uv run pytest --cov-fail-under=48

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ repos:
99
hooks:
1010
- id: ruff-format
1111
- id: ruff-check
12-
args: ["--fix", "--exclude", "tests"]
12+
args: ["--fix"]
1313

1414
- repo: local
1515
hooks:
1616
- id: ty-check
17-
name: ty check (src)
18-
entry: uv run ty check src
17+
name: ty check
18+
entry: uv run ty check .
1919
language: system
2020
pass_filenames: false

pyproject.toml

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ dependencies = [
3333
dev = [
3434
"pytest>=8.0.0",
3535
"pytest-qt>=4.4.0",
36+
"pytest-timeout>=2.3.0",
3637
"pytest-cov>=4.1.0",
3738
"ruff>=0.1.0",
38-
# "mypy>=1.8.0",
3939
"pre-commit>=3.6",
4040
"ty>=0.0.30",
4141
"pandas-stubs>=3.0.0.260204",
@@ -76,10 +76,26 @@ python_classes = ["Test*"]
7676
python_functions = ["test_*"]
7777
addopts = [
7878
"--verbose",
79+
"--timeout=3",
7980
"--cov=dbs_annotator",
8081
"--cov-report=html",
8182
"--cov-report=term-missing",
8283
]
84+
filterwarnings = [
85+
"ignore::DeprecationWarning",
86+
]
87+
markers = [
88+
"gui: Qt GUI / widget tests",
89+
"integration: cross-module behavior",
90+
"slow: longer GUI or lazy-loaded wizard flows; skip locally with pytest -m \"not slow\"",
91+
]
92+
93+
[tool.coverage.run]
94+
source = ["src"]
95+
omit = ["*/tests/*"]
96+
97+
[tool.coverage.report]
98+
omit = ["*/tests/*"]
8399

84100
[tool.ruff]
85101
line-length = 88
@@ -107,21 +123,3 @@ select = [
107123
ignore = [
108124
"E501", # line too long (handled by formatter/line-length)
109125
]
110-
111-
[tool.mypy]
112-
python_version = "3.11"
113-
warn_return_any = true
114-
warn_unused_configs = true
115-
disallow_untyped_defs = false
116-
disallow_incomplete_defs = false
117-
check_untyped_defs = true
118-
no_implicit_optional = true
119-
warn_redundant_casts = true
120-
warn_unused_ignores = true
121-
warn_no_return = true
122-
strict_optional = true
123-
124-
[[tool.mypy.overrides]]
125-
module = "PySide6.*"
126-
ignore_missing_imports = true
127-

src/dbs_annotator/utils/report_chart_utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@ def parse_scale_targets(
5454
targets[name] = {"type": "max", "value": float(smax) if smax else 0.0}
5555
elif mode == "custom":
5656
try:
57-
targets[name] = {"type": "custom", "value": float(custom_val)}
57+
custom_num = float(custom_val)
5858
except ValueError, TypeError:
59-
targets[name] = {"type": "custom", "value": 0.0}
59+
custom_num = 0.0
60+
targets[name] = {"type": "custom", "value": custom_num}
6061
return targets
6162

6263

tests/conftest.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""Shared pytest fixtures for Qt and the main wizard."""
2+
3+
from __future__ import annotations
4+
5+
import os
6+
7+
# Headless-friendly Qt before any QWidget is constructed (pytest loads conftest early).
8+
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
9+
10+
import pytest
11+
12+
from dbs_annotator.views.wizard_window import WizardWindow
13+
14+
15+
@pytest.fixture
16+
def wizard(qtbot, qapp):
17+
"""Main wizard window bound to the session QApplication."""
18+
w = WizardWindow(qapp)
19+
qtbot.addWidget(w)
20+
w.show()
21+
return w
22+
23+
24+
@pytest.fixture
25+
def bids_like_tsv(tmp_path):
26+
"""Minimal TSV path suitable for SessionData.open_file (new file)."""
27+
path = tmp_path / "sub-01_ses-20250101_task-prog_run-01_events.tsv"
28+
path.write_text("", encoding="utf-8")
29+
return path

0 commit comments

Comments
 (0)