from __future__ import annotations import importlib.util from pathlib import Path ROOT = Path(__file__).resolve().parents[2] SCRIPT = ROOT / "scripts" / "get_1c_moxel_next_action.py" SPEC = importlib.util.spec_from_file_location("get_1c_moxel_next_action", SCRIPT) assert SPEC and SPEC.loader next_action = importlib.util.module_from_spec(SPEC) SPEC.loader.exec_module(next_action) def test_choose_action_prefers_rectangular_named_range() -> None: plan = { "experiments": [ {"id": "cell_vertical_align", "target": "cell_or_layout_property"}, {"id": "named_range_rectangular_area", "target": "named_range"}, ] } action = next_action.choose_action(plan) assert action["id"] == "named_range_rectangular_area" def test_choose_action_prefers_presence_probe_over_coordinate_split() -> None: plan = { "experiments": [ {"id": "named_range_rectangular_area", "target": "named_range"}, {"id": "named_range_presence_probe", "target": "named_range"}, ] } action = next_action.choose_action(plan) assert action["id"] == "named_range_presence_probe" def test_render_markdown_adds_run_pipeline_after() -> None: markdown = next_action.render_markdown( { "id": "cell_vertical_align", "target": "cell_or_layout_property", "goal": "Map vertical alignment.", "manual_action": "Change vertical alignment.", "capture_command": "python scripts/watch_1c_moxel_property_experiment.py --property ВертикальноеПоложение", "expected_signal": "One local path changes.", } ) assert "--run-pipeline-after" in markdown assert "Change vertical alignment." in markdown def test_build_payload_exposes_machine_readable_command() -> None: payload = next_action.build_payload( { "id": "named_range_rectangular_area", "target": "named_range", "capture_command": "python scripts/watch_1c_moxel_property_experiment.py --property NamedRangeRectangle", } ) assert payload["schema"] == "codex_1c_moxel_next_action.v1" assert payload["status"] == "ok" assert payload["action"]["id"] == "named_range_rectangular_area" assert payload["action"]["capture_command_with_pipeline"].endswith("--run-pipeline-after")