Fix Windows appauthor path doubling and add Windows-specific platform tests - #220
Fix Windows appauthor path doubling and add Windows-specific platform tests#220utkarsha741 wants to merge 2 commits into
Conversation
… tests - platformdirs defaulted appauthor to the app name, producing doubled paths like AppData\Roaming\modeldock\modeldock on Windows. Pass appauthor=False explicitly in user_config_dir/user_cache_dir/user_data_dir. - Add tests/unit/test_platform.py covering platform.py's Windows path resolution, both mocked (cross-platform) and real (Windows-only, skipped elsewhere) assertions, including a regression test for the doubling bug. Closes OpenAgentHQ#115
There was a problem hiding this comment.
Thanks for tracking down the doubling bug — the fix direction is right, but I think it's incomplete. A couple of things to fix before merge:
-
system_config_dir()still has the same bug. It callsplatformdirs.site_config_dir(app_name())withoutappauthor=False(src/modeldock/common/platform.py).site_config_dirhas the exact sameappauthordefault behavior asuser_config_dir/user_cache_dir/user_data_dir, so on Windows it will still produce a doubled path (e.g.ProgramData\modeldock\modeldock). Sincesystem_config_dir()is actually used fromcommon/config.py, this isn't just a theoretical gap — please addappauthor=Falsethere too, and add a real-Windows regression test for it alongside the existing ones. -
The mocked
TestWindowsPathsMockedtests don't actually verify the fix. Each mock lambda declaresappauthor=Falseas its own default parameter value, e.g.:lambda name, appauthor=False, roaming=True: r"C:\Users\test\AppData\Roaming\modeldock"
This means the test passes whether or not
md_platform.user_config_dir()actually passesappauthor=Falsetoplatformdirs— the lambda's own default silently absorbs a missing argument. These tests only check that the return value gets wrapped in aPath, not that the doubling fix is applied. To make them meaningful, assert on the call args, e.g.:captured = {} def fake_user_config_dir(name, **kwargs): captured.update(kwargs) return r"C:\Users\test\AppData\Roaming\modeldock" monkeypatch.setattr(md_platform.platformdirs, "user_config_dir", fake_user_config_dir) md_platform.user_config_dir() assert captured["appauthor"] is False
(or use
unittest.mock.Mock/MagicMockand assert oncall_args). As written, this bug could regress without any non-Windows CI job catching it — only the real Windows job would catch it, and only for the three functions that were actually fixed. -
Minor:
tests/unit/test_platform.pyis missing a trailing newline at EOF.
Since real Windows-only tests are skipped everywhere except the windows-latest CI job, please double check that job is green for this PR (and covers the new system_config_dir case once added).
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 5 advisory finding(s) below merit a look before merge.
Graphify review — findings
Passes appauthor=False to the platformdirs calls in user_config_dir, user_cache_dir, and user_data_dir so paths no longer nest the app name under an author folder (on Windows this stops producing AppData\Roaming\modeldock\modeldock). Adds tests/unit/test_platform.py covering the path wrappers with mocked Windows-style output on any OS, plus Windows-only tests that assert the directories sit under real APPDATA/LOCALAPPDATA, contain modeldock exactly once, and that MODELDOCK_CACHE_DIR still overrides default_cache_dir.
Worth a look
- New test module has unexpected top-level indentation —
tests/unit/test_platform.py:1· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Test file has leading indentation on module-level imports causing IndentationError —
tests/unit/test_platform.py:1· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- test file indented with leading spaces on module-level imports (IndentationError) —
tests/unit/test_platform.py:1· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Test file uses invalid indentation on module-level imports —
tests/unit/test_platform.py:1· Escalate · high- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
- Windows storage directory contract changes without migration —
src/modeldock/common/platform.py:22· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 63 functions depend on the 36 functions this change touches.
Health — this change adds coupling hotspots:
- new:
load_settings()— 13 callers, 6 callees
Verification — 63 functions in the blast radius were not formally verified this run (proofs are advisory here).
Health delta baseline: last indexed commit 50084a7 (diverged from this PR's base — delta is approximate).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 59 function(s) in the blast radius were not formally verified this run
· 1 more finding(s) on lines outside this diff (see the check run).
Code Review SuggestionsThe Critical1. Module-level imports in The first 9 lines of the file have 3 spaces of leading whitespace: from __future__ import annotations # ← IndentationError
import os
...while Fix: remove the leading spaces from lines 1–9. 2. Mocked tests don't verify The lambdas accept lambda name, appauthor=False, roaming=True: r"C:\Users\test\..."
# ^^^^ default — would silently accept missing arg tooThis means the mocked tests would still pass even if the from unittest.mock import MagicMock
mock_fn = MagicMock(return_value=r"C:\Users\test\AppData\Roaming\modeldock")
monkeypatch.setattr(md_platform.platformdirs, "user_config_dir", mock_fn)
result = md_platform.user_config_dir()
mock_fn.assert_called_once_with("modeldock", appauthor=False, roaming=True)
assert result == Path(r"C:\Users\test\AppData\Roaming\modeldock")Important3.
def system_config_dir() -> Path:
return Path(platformdirs.site_config_dir(app_name()))
# ^^^ no appauthor=FalseOn Windows, return Path(platformdirs.site_config_dir(app_name(), appauthor=False))and the 4. The fix adds def test_user_data_dir_not_doubled(self) -> None:
result = md_platform.user_data_dir()
assert str(result).lower().count("modeldock") == 15.
appdata = os.environ.get("APPDATA", "")
assert appdata and str(result).lower().startswith(appdata.lower())Minor
Strengths
|
Closes #115
Background
While adding Windows-specific assertions to the platform/cache tests (per #115),
I found a real cross-platform bug:
platformdirswas defaultingappauthortothe app name on Windows, which doubles the path — e.g.
AppData\Roaming\modeldock\modeldockinstead ofAppData\Roaming\modeldock.Changes
src/modeldock/common/platform.py: passappauthor=Falseexplicitly inuser_config_dir(),user_cache_dir(), anduser_data_dir()to preventthe path doubling on Windows.
tests/unit/test_platform.py(new):platformdirsoutput and verifying our wrappers handle it correctly.
genuine
platformdirsbehavior against realAPPDATA/LOCALAPPDATA,including regression tests for the doubling bug above.
Testing
Full test suite passes locally on Windows:
549 passed, 4 skipped(skips are pre-existing, Ollama-CLI-dependent integration tests unrelated
to this change).