0
0
Fork 0
Codesys-MCP-SP21-plus/tests
Karstein Phobic Nyvold Kvistad d414c779a5 fix(add_library): refuse to save unresolvable placeholders
Prior behaviour: lm.add_library(LIBRARY_NAME) was called with a string,
which always hits the placeholder overload of ScriptLibManObject.add_library
(see helpme-codesys.com "ScriptLibManObject" / local SP22 stub
ScriptLib/Stubs/scriptengine/ScriptLibManObject.pyi). If the named
placeholder is not registered in the IDE, the resulting reference fails
to resolve at load time and the next project open throws

  Library Manager: Error: Could not open library 'X'.
  (Reason: The placeholder library 'X' could not be resolved.)

after which script_engine.projects.primary returns None and the project
is effectively bricked until the binary is reverted. add_library reported
SUCCESS in this scenario.

Fix:
  1. Pre-resolve LIBRARY_NAME via the IDE-level
     library_manager.find_library(name) global. If found, pass the
     resulting ManagedLib to lm.add_library(...) -- the V3.5.5.0 ManagedLib
     overload which produces a managed reference instead of a placeholder.
  2. After the add, walk lm.references to locate the new entry and verify
     it resolved (managed -> always; placeholder -> non-empty
     effective_resolution per ScriptPlaceholderReference in the stub).
  3. If the reference did not resolve, call lm.remove_library(name) to back
     out the bad reference and refuse to save the project, returning an
     actionable error instead.

Also tightened the libman lookup to use the documented
has_library_manager / get_library_manager() container API
(ScriptLibManObjectContainer in the stub) instead of name-searching for
"Library Manager" as a tree node, matching what list_project_libraries.py
already does. The legacy name-search fallback is preserved for older SPs.

Regression test added in tests/integration/e2e.test.ts asserting the
rendered script template carries the resolution gate, the managed-overload
preference, the back-out call, and that primary_project.save() in the
add_library body lives downstream of the _is_resolved gate.

Followup: lm.remove_library(name) is documented for SP22 and is the
clean back-out path. On SPs that lack remove_library (none observed in
the 3.5.21+ docs but possible on truly old branches) the script reports
the constraint and exits non-zero rather than silently saving a bad
reference.
2026-04-26 19:44:00 +02:00
..
integration fix(add_library): refuse to save unresolvable placeholders 2026-04-26 19:44:00 +02:00
unit fix(create_folder): try project.create_folder(name, SV_POU) first; drop ScriptManager cache 2026-04-26 17:16:44 +02:00
bench-results-v5.json test(bench): v5 sweep -- fix set_pou_code params, all 10 cases pass 2026-04-26 19:30:48 +02:00
bench-results.json fix: 4 broken-tool fixes (compile json long, connect_to_device LoginMode, 2026-04-26 16:53:25 +02:00
bench.mjs test(bench): v5 sweep -- fix set_pou_code params, all 10 cases pass 2026-04-26 19:30:48 +02:00
mock_watcher.py Initial release: MCP server for CODESYS with persistent UI instance 2026-02-08 18:59:16 +10:00
test-fixes.mjs fix(create_folder): try project.create_folder(name, SV_POU) first; drop ScriptManager cache 2026-04-26 17:16:44 +02:00
TEST_OVERVIEW.md test(bench): v5 sweep -- fix set_pou_code params, all 10 cases pass 2026-04-26 19:30:48 +02:00