|
3 | 3 | from mxdev.uv import UvPyprojectUpdater |
4 | 4 |
|
5 | 5 | import tomlkit |
| 6 | +import pytest |
| 7 | +import sys |
6 | 8 |
|
7 | 9 |
|
8 | 10 | def test_hook_skips_when_pyproject_toml_missing(mocker, tmp_path, monkeypatch): |
@@ -36,7 +38,8 @@ def test_hook_skips_when_uv_managed_is_false_or_missing(mocker, tmp_path, monkey |
36 | 38 |
|
37 | 39 | hook.write(state) |
38 | 40 | mock_logger.debug.assert_called_with( |
39 | | - "[%s] Project not explicitly managed by uv ([tool.uv] managed=true missing), skipping.", "uv" |
| 41 | + "[%s] Project not explicitly managed by uv ([tool.uv] managed=true missing), skipping.", |
| 42 | + "uv", |
40 | 43 | ) |
41 | 44 |
|
42 | 45 | # Verify the file was not modified |
@@ -65,7 +68,8 @@ def test_hook_skips_when_uv_managed_is_false(mocker, tmp_path, monkeypatch): |
65 | 68 |
|
66 | 69 | hook.write(state) |
67 | 70 | mock_logger.debug.assert_called_with( |
68 | | - "[%s] Project not explicitly managed by uv ([tool.uv] managed=true missing), skipping.", "uv" |
| 71 | + "[%s] Project not explicitly managed by uv ([tool.uv] managed=true missing), skipping.", |
| 72 | + "uv", |
69 | 73 | ) |
70 | 74 |
|
71 | 75 | # Verify the file was not modified |
@@ -277,10 +281,6 @@ def test_hook_handles_oserror_on_write(mocker, tmp_path, monkeypatch): |
277 | 281 | mock_logger.error.assert_called_with("[%s] Failed to write pyproject.toml: %s", "uv", mocker.ANY) |
278 | 282 |
|
279 | 283 |
|
280 | | -import pytest |
281 | | -import sys |
282 | | - |
283 | | - |
284 | 284 | def test_hook_raises_runtime_error_if_tomlkit_missing(mocker, tmp_path, monkeypatch): |
285 | 285 | monkeypatch.chdir(tmp_path) |
286 | 286 | hook = UvPyprojectUpdater() |
@@ -308,3 +308,48 @@ def fake_import(name, *args, **kw): |
308 | 308 | hook.write(state) |
309 | 309 |
|
310 | 310 | assert "tomlkit is required for the uv hook" in str(excinfo.value) |
| 311 | + |
| 312 | + |
| 313 | +def test_hook_resolves_path_relative_to_config(mocker, tmp_path, monkeypatch): |
| 314 | + monkeypatch.chdir(tmp_path) |
| 315 | + |
| 316 | + config_dir = tmp_path / "other" / "path" |
| 317 | + config_dir.mkdir(parents=True) |
| 318 | + |
| 319 | + mx_ini = """ |
| 320 | +[settings] |
| 321 | +[pkg1] |
| 322 | +url = https://example.com/pkg1.git |
| 323 | +target = sources |
| 324 | +install-mode = editable |
| 325 | +""" |
| 326 | + (config_dir / "mx.ini").write_text(mx_ini.strip()) |
| 327 | + |
| 328 | + config = Configuration(str(config_dir / "mx.ini")) |
| 329 | + # Manually mimic the 'directory' injection that happens in including.py |
| 330 | + # during actual execution, because Configuration() constructor alone |
| 331 | + # doesn't inject it if it isn't in the INI file itself, but including.py does. |
| 332 | + config.settings["directory"] = str(config_dir) |
| 333 | + state = State(config) |
| 334 | + |
| 335 | + initial_toml = """ |
| 336 | +[project] |
| 337 | +name = "test" |
| 338 | +
|
| 339 | +[tool.uv] |
| 340 | +managed = true |
| 341 | +""" |
| 342 | + (config_dir / "pyproject.toml").write_text(initial_toml.strip()) |
| 343 | + |
| 344 | + hook = UvPyprojectUpdater() |
| 345 | + mock_logger = mocker.patch("mxdev.uv.logger") |
| 346 | + hook.write(state) |
| 347 | + |
| 348 | + mock_logger.info.assert_any_call("[%s] Successfully updated pyproject.toml", "uv") |
| 349 | + |
| 350 | + # Verify the file was written to the config directory, not CWD |
| 351 | + assert not (tmp_path / "pyproject.toml").exists() |
| 352 | + assert (config_dir / "pyproject.toml").exists() |
| 353 | + |
| 354 | + doc = tomlkit.parse((config_dir / "pyproject.toml").read_text()) |
| 355 | + assert "pkg1" in doc["tool"]["uv"]["sources"] |
0 commit comments