mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-29 05:44:14 +02:00
qet-mcp: answer review on naming a conductor by uuid
- An end conductorEnds() reports as "?" is never picked. - An empty "conductor" says why: an older project's conductors have no saved uuid, so qet_conductors reports it empty. - The op description and README say set_conductor still changes the whole potential when given a uuid, and that older projects' conductors are named by element + terminal until #1103. - test_conductor_by_uuid covers move_conductor_segment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -296,7 +296,12 @@ Python, plus the hang guard on `addConductor` and the database refresh in
|
||||
where two conductors meet at a terminal. It is turned at run time into an
|
||||
end whose terminal carries only that conductor; where both of its ends
|
||||
are shared the op fails and its `note` says why. Needs
|
||||
`qet.conductorEnds()` in the build.
|
||||
`qet.conductorEnds()` in the build. A uuid names one wire, but
|
||||
`set_conductor` still changes the whole potential, the same as by
|
||||
terminal. A project saved before conductors carried a uuid has none in
|
||||
the file: QElectroTech makes a new one on every load and does not save
|
||||
it, so `qet_conductors` reports `uuid` as empty and those conductors are
|
||||
named by `element` + `terminal` until wire uuids last (#1103).
|
||||
- **`qet_export` isolates its launch.** SingleApplication keys its socket
|
||||
on `applicationFilePath()`, so a second launch of the same binary path
|
||||
forwards its request to an already-running instance and returns *that*
|
||||
|
||||
+11
-2
@@ -1419,6 +1419,7 @@ def _build_script(operations: list, output: str) -> str:
|
||||
" if (ends && ends.length === 2) {",
|
||||
" var lines = qet.conductors(folio);",
|
||||
" for (var k = 0; k < 2; k++) {",
|
||||
" if (ends[k] === '?') continue;",
|
||||
" var n = 0;",
|
||||
" for (var j = 0; j < lines.length; j++) {",
|
||||
" var p = lines[j].split(' : ')[0].split(' -- ');",
|
||||
@@ -1601,6 +1602,11 @@ def _build_script(operations: list, output: str) -> str:
|
||||
if "element" in op or "terminal" in op:
|
||||
raise ValueError(f"operation {i} ({name}): give either \"conductor\" "
|
||||
f"(its uuid) or \"element\" + \"terminal\", not both")
|
||||
if op["conductor"] == "":
|
||||
raise ValueError(f"operation {i}: \"conductor\" is empty -- a conductor "
|
||||
f"from a project saved before conductors carried a uuid "
|
||||
f"has none in the file; name it by \"element\" + "
|
||||
f"\"terminal\" instead")
|
||||
if not isinstance(op["conductor"], str) or not _UUID_RE.fullmatch(op["conductor"]):
|
||||
raise ValueError(f"operation {i}: \"conductor\" must be a conductor uuid, "
|
||||
f"got {op['conductor']!r}")
|
||||
@@ -2551,8 +2557,11 @@ TOOLS = [
|
||||
"or give \"conductor\": its uuid from qet_conductors in place "
|
||||
"of \"element\" + \"terminal\" (set_conductor, "
|
||||
"move_conductor_segment and delete_conductor all accept it; it "
|
||||
"needs one of the conductor's two terminals to carry only it); "
|
||||
"its \"property\" is one of " + ", ".join(CONDUCTOR_PROPERTIES) +
|
||||
"needs one of the conductor's two terminals to carry only it, "
|
||||
"and a conductor qet_conductors lists with an empty uuid has "
|
||||
"none to give). A uuid names one wire, but set_conductor still "
|
||||
"changes its whole potential, as it does by terminal. "
|
||||
"set_conductor's \"property\" is one of " + ", ".join(CONDUCTOR_PROPERTIES) +
|
||||
". move_conductor_segment reroutes the drawn path itself rather "
|
||||
"than a property of the potential -- addressed the same way (a "
|
||||
"terminal carrying exactly one conductor), plus a segment index "
|
||||
|
||||
@@ -206,6 +206,12 @@ class EditValidation(unittest.TestCase):
|
||||
s = self.build([{"op": "set_conductor", "folio": 0, "conductor": U,
|
||||
"property": "num", "value": "W1"}])
|
||||
self.assertIn('qet.setConductorProperty(0, e0.element, e0.terminal, "num", "W1")', s)
|
||||
s = self.build([{"op": "move_conductor_segment", "folio": 2, "conductor": U,
|
||||
"segment": 1, "dx": 10, "dy": 0}])
|
||||
self.assertIn(f'var e0 = qetMcpConductorEnd(0, 2, "{U}");', s)
|
||||
self.assertIn("(e0 ? qet.moveConductorSegment(2, e0.element, e0.terminal, 1, 10, 0) : false)", s)
|
||||
# an end whose terminal or element is missing is never picked
|
||||
self.assertIn("if (ends[k] === '?') continue;", s)
|
||||
self.assertNotIn('"conductorEnds"', self.build(
|
||||
[{"op": "delete_conductor", "folio": 0, "element": U, "terminal": 0}]))
|
||||
with self.assertRaisesRegex(ValueError, "not both"):
|
||||
@@ -213,6 +219,8 @@ class EditValidation(unittest.TestCase):
|
||||
"element": U, "terminal": 0}])
|
||||
with self.assertRaisesRegex(ValueError, "must be a conductor uuid"):
|
||||
self.build([{"op": "delete_conductor", "folio": 0, "conductor": "W1"}])
|
||||
with self.assertRaisesRegex(ValueError, "saved before conductors carried a uuid"):
|
||||
self.build([{"op": "delete_conductor", "folio": 0, "conductor": ""}])
|
||||
|
||||
def test_every_op_generates_a_script(self):
|
||||
# one minimal valid instance of every op
|
||||
|
||||
Reference in New Issue
Block a user