mirror of
https://github.com/morluto/rea
synced 2026-10-25 22:08:11 -04:00
fix(cutter): read the active document from core configuration
Read file.path through CutterCore's scalar configuration API instead of invoking the debug-only currentlyOpenFile backup field. Preserve exact string paths and unknowns so existing discovery, generation admission and Evidence consumers receive the owning facts. Validated 11 Python protocol tests, 66 relevant CLI/MCP/provider tests, full static/docs gates, and official Linux Cutter 2.5.0 Qt5 workflows with a Unicode/#? ELF path. Same-path reload identity remains partial and native document switching is unverified. Fixes #4497.
This commit is contained in:
@@ -333,8 +333,8 @@ class _RequestDispatcher(QObject):
|
||||
@staticmethod
|
||||
def _read_current_file() -> str | None:
|
||||
try:
|
||||
value = cutter.core().currentlyOpenFile()
|
||||
return str(value) if value else None
|
||||
value = cutter.core().getConfig("file.path")
|
||||
return value if isinstance(value, str) and value else None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
+60
-1
@@ -14,6 +14,7 @@ import types
|
||||
import unittest
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
|
||||
def _install_host_stubs():
|
||||
@@ -22,7 +23,7 @@ def _install_host_stubs():
|
||||
sys.modules["cutter"] = cutter
|
||||
qtcore = types.ModuleType("PySide6.QtCore")
|
||||
qtcore.QObject = type("QObject", (), {})
|
||||
qtcore.Signal = lambda *_args: object()
|
||||
qtcore.Signal = lambda *_args: types.SimpleNamespace(connect=lambda _handler: None)
|
||||
pyside = types.ModuleType("PySide6")
|
||||
pyside.QtCore = qtcore
|
||||
sys.modules["PySide6"] = pyside
|
||||
@@ -221,6 +222,64 @@ def run_serve_mode():
|
||||
server.join(timeout=3)
|
||||
|
||||
|
||||
class DocumentIdentityTest(unittest.TestCase):
|
||||
def test_document_config_drives_generation_and_command_admission(self):
|
||||
first = "/tmp/Cutter 雪 #1?.elf"
|
||||
second = "/tmp/another document.elf"
|
||||
configuration = {"file.path": first}
|
||||
core = types.SimpleNamespace(
|
||||
getConfig=configuration.__getitem__,
|
||||
getVersionInformation=lambda: "backend fixture",
|
||||
)
|
||||
commands = []
|
||||
with patch.object(bridge.cutter, "core", lambda: core, create=True), patch.object(
|
||||
bridge.cutter, "cmd", lambda command: commands.append(command) or "observed", create=True
|
||||
):
|
||||
dispatcher = bridge._RequestDispatcher()
|
||||
self.assertEqual(dispatcher.current_file, first)
|
||||
self.assertEqual(dispatcher.generation, 0)
|
||||
|
||||
def handle(**values):
|
||||
request = {**values, "_event": threading.Event(), "_cancelled": threading.Event()}
|
||||
reply = {}
|
||||
dispatcher._handle(request, reply)
|
||||
self.assertTrue(request["_event"].is_set())
|
||||
return reply
|
||||
|
||||
same = handle(kind="status")
|
||||
self.assertEqual(same["current_file"], first)
|
||||
self.assertEqual(same["document_generation"], 0)
|
||||
configuration["file.path"] = second
|
||||
changed = handle(kind="status")
|
||||
self.assertEqual(changed["current_file"], second)
|
||||
self.assertEqual(changed["document_generation"], 1)
|
||||
stale = handle(kind="command", request_id=str(uuid.uuid4()), expected_generation=0, command="iI")
|
||||
self.assertEqual(stale["error"], "active-document-generation-changed")
|
||||
self.assertEqual(stale["execution_state"], "not_started")
|
||||
self.assertEqual(commands, [])
|
||||
current = handle(kind="command", request_id=str(uuid.uuid4()), expected_generation=1, command="iI")
|
||||
self.assertEqual(current["output"], "observed")
|
||||
self.assertEqual(current["document_generation"], 1)
|
||||
self.assertEqual(commands, ["iI"])
|
||||
|
||||
def test_absent_or_unreadable_document_config_remains_unknown(self):
|
||||
class UnreadableCore:
|
||||
def getConfig(self, _key):
|
||||
raise RuntimeError("document config unavailable")
|
||||
|
||||
for core in [
|
||||
types.SimpleNamespace(getConfig=lambda _key: ""),
|
||||
types.SimpleNamespace(getConfig=lambda _key: None),
|
||||
types.SimpleNamespace(getConfig=lambda _key: object()),
|
||||
types.SimpleNamespace(),
|
||||
UnreadableCore(),
|
||||
]:
|
||||
with self.subTest(core=type(core).__name__), patch.object(
|
||||
bridge.cutter, "core", lambda: core, create=True
|
||||
):
|
||||
self.assertIsNone(bridge._RequestDispatcher._read_current_file())
|
||||
|
||||
|
||||
class ProtocolProducerTest(unittest.TestCase):
|
||||
def test_rejects_legacy_peers_before_ui_dispatch(self):
|
||||
with socket.create_connection(("127.0.0.1", self.server.port), timeout=2) as connection:
|
||||
|
||||
Reference in New Issue
Block a user