From c2aa99d60ae80d001b3d5386cfedfc882d354632 Mon Sep 17 00:00:00 2001 From: Scott Claiborne Date: Tue, 5 May 2026 09:57:38 -0700 Subject: [PATCH] Fix namespace on newly created XML elements in library and deployment ET.Element calls in addDependency, _createDependencyElement, _createLibraryElement, and _createTaskElement were missing the AS namespace prefix, so newly created elements were invisible to findall queries until the file was written and re-read. Prefix tags with self.nameSpaceFormatted so elements are findable in-memory immediately. Add tests that assert in-memory visibility after each mutating call, with no write+reload roundtrip required. --- aspython/deployment.py | 4 ++-- aspython/library.py | 7 +++---- tests/test_deployment.py | 41 ++++++++++++++++++++++++++++++++++++++++ tests/test_library.py | 28 +++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 tests/test_deployment.py create mode 100644 tests/test_library.py diff --git a/aspython/deployment.py b/aspython/deployment.py index b3b9b83..93fbe59 100644 --- a/aspython/deployment.py +++ b/aspython/deployment.py @@ -60,7 +60,7 @@ def _createLibraryElement(self, libraryFolder, name, memory: str = 'UserROM', at } for attributeName in attributeOverrides: attributes[attributeName] = attributeOverrides[attributeName] - element = ET.Element('LibraryObject', attrib=attributes) + element = ET.Element(self.nameSpaceFormatted + 'LibraryObject', attrib=attributes) element.tail = "\n" return element @@ -83,7 +83,7 @@ def _createTaskElement(self, taskFolder, taskName, memory: str = 'UserROM') -> E 'Language': language, 'Debugging': 'true', } - element = ET.Element('Task', attrib=attributes) + element = ET.Element(self.nameSpaceFormatted + 'Task', attrib=attributes) element.tail = "\n" return element diff --git a/aspython/library.py b/aspython/library.py index 6581d7f..b67783a 100644 --- a/aspython/library.py +++ b/aspython/library.py @@ -85,7 +85,7 @@ def _addObjectElement(self, path): def addDependency(self, *dependency): deps_container = self.find('Dependencies') if deps_container is None: - deps_container = ET.SubElement(self.root, 'Dependencies') + deps_container = ET.SubElement(self.root, self.nameSpaceFormatted + 'Dependencies') for dependent in dependency: if not isinstance(dependent, Dependency): raise TypeError('Expected Dependency class got', type(dependent)) @@ -184,14 +184,13 @@ def _createPkgElement(path: str, tag: str) -> ET.Element: element.tail = "\n" return element - @staticmethod - def _createDependencyElement(dependency: Dependency): + def _createDependencyElement(self, dependency: Dependency): attributes = {'ObjectName': dependency.name} if dependency.minVersion: attributes['FromVersion'] = dependency.minVersion if dependency.maxVersion: attributes['ToVersion'] = dependency.maxVersion - return ET.Element('Dependency', attributes) + return ET.Element(self.nameSpaceFormatted + 'Dependency', attributes) @staticmethod def _getXmlTag(package: ET.ElementTree) -> str: diff --git a/tests/test_deployment.py b/tests/test_deployment.py new file mode 100644 index 0000000..0c51527 --- /dev/null +++ b/tests/test_deployment.py @@ -0,0 +1,41 @@ +"""Tests for aspython.deployment.SwDeploymentTable.""" +from unittest.mock import patch + +import pytest + +from aspython.deployment import SwDeploymentTable + +# Minimal cpu.sw with all 8 TaskClass slots and a Libraries section so that +# SwDeploymentTable.__init__ finds them all and skips its write-and-reload path. +_SW_XML = """\ + + + + + + + + + + + +""" + +_PATCH_PATH = "aspython.deployment.getLibraryPathInPackage" +_PATCH_TYPE = "aspython.deployment.getLibraryType" + + +@pytest.fixture +def sw_table(tmp_path): + sw_path = tmp_path / "cpu.sw" + sw_path.write_text(_SW_XML, encoding="utf-8") + with patch(_PATCH_PATH, return_value="/fake/TestLib"), patch(_PATCH_TYPE, return_value="ANSIC"): + return SwDeploymentTable(str(sw_path)) + + +def test_deploy_library_adds_entry(sw_table): + with patch(_PATCH_PATH, return_value="/fake/TestLib"), patch(_PATCH_TYPE, return_value="ANSIC"): + sw_table.deployLibrary("/some/Libraries/MyLibs", "TestLib") + + # Newly deployed library is visible in-memory without a write+reload roundtrip. + assert "TestLib" in sw_table.libraries diff --git a/tests/test_library.py b/tests/test_library.py new file mode 100644 index 0000000..51b2e7d --- /dev/null +++ b/tests/test_library.py @@ -0,0 +1,28 @@ +"""Tests for aspython.library.Library.""" +import pytest + +from aspython.library import Library +from aspython.models import Dependency + +_LIBRARY_XML = """\ + + + +""" + + +@pytest.fixture +def library_file(tmp_path): + lib_dir = tmp_path / "TestLib" + lib_dir.mkdir() + lby = lib_dir / "ANSIC.lby" + lby.write_text(_LIBRARY_XML, encoding="utf-8") + return Library(str(lby)) + + +def test_add_dependency_roundtrip(library_file): + dep = Dependency(name="runtime", minVersion="", maxVersion="") + library_file.addDependency(dep) + + # Newly added elements are visible in-memory without a write+reload roundtrip. + assert "runtime" in library_file.dependencyNames