diff --git a/server/galaxyls/constants.py b/server/galaxyls/constants.py
index 13230b34..0e10e865 100644
--- a/server/galaxyls/constants.py
+++ b/server/galaxyls/constants.py
@@ -1,7 +1,5 @@
"""This module contains definitions for constants used by the Galaxy Tools Language Server."""
-SERVER_NAME = "Galaxy Tools LS"
-
class Commands:
AUTO_CLOSE_TAGS = "gls.completion.autoCloseTags"
diff --git a/server/galaxyls/server.py b/server/galaxyls/server.py
index f54b2b93..96f51215 100644
--- a/server/galaxyls/server.py
+++ b/server/galaxyls/server.py
@@ -48,10 +48,7 @@
CompletionMode,
GalaxyToolsConfiguration,
)
-from galaxyls.constants import (
- Commands,
- SERVER_NAME,
-)
+from galaxyls.constants import Commands
from galaxyls.services.language import GalaxyToolLanguageService
from galaxyls.services.validation import DocumentValidator
from galaxyls.services.xml.document import XmlDocument
@@ -72,7 +69,7 @@ class GalaxyToolsLanguageServer(LanguageServer):
def __init__(self) -> None:
super().__init__()
- self.service = GalaxyToolLanguageService(SERVER_NAME)
+ self.service = GalaxyToolLanguageService()
self.configuration: GalaxyToolsConfiguration = GalaxyToolsConfiguration()
diff --git a/server/galaxyls/services/language.py b/server/galaxyls/services/language.py
index aae8582c..46f8193c 100644
--- a/server/galaxyls/services/language.py
+++ b/server/galaxyls/services/language.py
@@ -61,8 +61,8 @@ class GalaxyToolLanguageService:
by the LSP.
"""
- def __init__(self, server_name: str) -> None:
- self.xsd_service = GalaxyToolXsdService(server_name)
+ def __init__(self) -> None:
+ self.xsd_service = GalaxyToolXsdService()
self.format_service = GalaxyToolFormatService()
self.xsd_tree = self.xsd_service.xsd_parser.get_tree()
self.xml_context_service = XmlContextService(self.xsd_tree)
@@ -81,9 +81,7 @@ def set_workspace(self, workspace: Workspace) -> None:
)
def get_diagnostics(self, xml_document: XmlDocument) -> List[Diagnostic]:
- """Validates the Galaxy tool XML document and returns a list
- of diagnostics if there are any problems.
- """
+ """Validates the Galaxy tool XML document and returns a list of diagnostics if there are any problems."""
return self.xsd_service.validate_document(xml_document) + self.linter.lint_document(xml_document)
def get_documentation(self, xml_document: XmlDocument, position: Position) -> Optional[Hover]:
@@ -105,9 +103,7 @@ def get_documentation(self, xml_document: XmlDocument, position: Position) -> Op
return None
def format_document(self, content: str, params: DocumentFormattingParams) -> List[TextEdit]:
- """Given the document contents returns the list of TextEdits
- needed to properly format and layout the document.
- """
+ """Given the document contents returns the list of TextEdits needed to properly format and layout the document."""
return self.format_service.format(content, params)
def get_completion(
diff --git a/server/galaxyls/services/tools/linting.py b/server/galaxyls/services/tools/linting.py
index 8717154e..336c46dd 100644
--- a/server/galaxyls/services/tools/linting.py
+++ b/server/galaxyls/services/tools/linting.py
@@ -1,17 +1,18 @@
-from typing import List, cast
-from lxml import etree
+from typing import List
from galaxy.tool_util.lint import (
- lint_tool_source_with,
+ lint_xml_with,
LintContext,
LintLevel,
XMLLintMessageXPath,
)
-from galaxy.tool_util.parser import get_tool_source
-from galaxy.util import xml_macros
+from pygls.lsp.types import (
+ Diagnostic,
+ DiagnosticSeverity,
+)
+
from galaxyls.services.tools.common import ToolLinter
from galaxyls.services.xml.document import XmlDocument
-from pygls.lsp.types import Diagnostic, Range, DiagnosticSeverity
class GalaxyToolLinter(ToolLinter):
@@ -20,21 +21,20 @@ class GalaxyToolLinter(ToolLinter):
def lint_document(self, xml_document: XmlDocument) -> List[Diagnostic]:
""" """
result: List[Diagnostic] = []
- if xml_document.is_macros_file:
+ xml_tree = xml_document.xml_tree_expanded
+ if not xml_document.is_tool_file or xml_tree is None:
return result
- xml_tree, _ = xml_macros.load_with_references(xml_document.document.path)
- tool_source = get_tool_source(xml_tree=xml_tree)
lint_context = LintContext(level=LintLevel.SILENT, lint_message_class=XMLLintMessageXPath)
- context = lint_tool_source_with(lint_context, tool_source)
+ context = lint_xml_with(lint_context, xml_tree)
result.extend(
[
- self._to_diagnostic(lint_message, xml_tree, xml_document, DiagnosticSeverity.Error)
+ self._to_diagnostic(lint_message, xml_document, DiagnosticSeverity.Error)
for lint_message in context.error_messages
]
)
result.extend(
[
- self._to_diagnostic(lint_message, xml_tree, xml_document, DiagnosticSeverity.Warning)
+ self._to_diagnostic(lint_message, xml_document, DiagnosticSeverity.Warning)
for lint_message in context.warn_messages
]
)
@@ -43,11 +43,10 @@ def lint_document(self, xml_document: XmlDocument) -> List[Diagnostic]:
def _to_diagnostic(
self,
lint_message: XMLLintMessageXPath,
- xml_tree: etree._ElementTree,
xml_document: XmlDocument,
level: DiagnosticSeverity,
) -> Diagnostic:
- range = self._get_range_from_xpath(lint_message.xpath, xml_tree, xml_document)
+ range = xml_document.get_element_range_from_xpath_or_default(lint_message.xpath)
result = Diagnostic(
range=range,
message=lint_message.message,
@@ -55,10 +54,3 @@ def _to_diagnostic(
severity=level,
)
return result
-
- def _get_range_from_xpath(self, xpath: str, xml_tree: etree._ElementTree, xml_document: XmlDocument) -> Range:
- result = None
- found = cast(list, xml_tree.xpath(xpath))[0]
- if found is not None:
- result = xml_document.get_element_name_range_at_line(found.tag, found.sourceline - 1)
- return result or xml_document.get_default_range()
diff --git a/server/galaxyls/services/xml/document.py b/server/galaxyls/services/xml/document.py
index fc930029..cc67c56e 100644
--- a/server/galaxyls/services/xml/document.py
+++ b/server/galaxyls/services/xml/document.py
@@ -1,10 +1,14 @@
from typing import (
+ Any,
+ cast,
Dict,
List,
Optional,
)
from anytree.search import findall
+from galaxy.util import xml_macros
+from lxml import etree
from pygls.lsp.types import (
Position,
Range,
@@ -44,6 +48,8 @@ def __init__(self, document: Document):
"tool": DocumentType.TOOL,
"macros": DocumentType.MACROS,
}
+ self._xml_tree: Optional[etree._ElementTree] = None
+ self._xml_tree_expanded: Optional[etree._ElementTree] = None
@property
def node_type(self) -> NodeType:
@@ -103,6 +109,40 @@ def is_tool_file(self) -> bool:
"""Indicates if the document is a tool definition file."""
return self.document_type == DocumentType.TOOL
+ @property
+ def xml_tree(self) -> Optional[etree._ElementTree]:
+ """Internal XML tree structure."""
+ if self._xml_tree is None:
+ try:
+ tree = etree.parse(self.document.path)
+ self._xml_tree = tree
+ except etree.XMLSyntaxError:
+ pass # Invalid XML document
+ return self._xml_tree
+
+ @property
+ def xml_has_syntax_errors(self) -> bool:
+ return self.xml_tree is None
+
+ @property
+ def xml_tree_expanded(self) -> Optional[etree._ElementTree]:
+ """Internal XML tree structure after expanding macros.
+
+ If there are no macro definitions, it returns the same as `xml_tree` property."""
+ if self._xml_tree_expanded is None:
+ if self.uses_macros:
+ try:
+ expanded_tool_tree, _ = xml_macros.load_with_references(self.document.path)
+ self._xml_tree_expanded = expanded_tool_tree
+ except etree.XMLSyntaxError:
+ pass # Invalid XML document
+ except BaseException:
+ pass # TODO: Errors expanding macros should be catch during validation
+ if self._xml_tree_expanded is None:
+ # Fallback to the non-expanded version if something failed
+ self._xml_tree_expanded = self.xml_tree
+ return self._xml_tree_expanded
+
def get_node_at(self, offset: int) -> Optional[XmlSyntaxNode]:
"""Gets the syntax node a the given offset."""
return self.root.find_node_at(offset) if self.root else None
@@ -231,12 +271,38 @@ def get_default_range(self) -> Range:
return self.get_element_name_range(self.root) or DEFAULT_RANGE
return DEFAULT_RANGE
- def get_element_name_range_at_line(self, name: str, line_number: int) -> Range:
- """Gets the range of the element with the given tag name located at the given line number."""
- line_text = self.document.lines[line_number]
- start = line_text.index(f"<{name}") + 1
- end = start + len(name)
- return Range(
- start=Position(line=line_number, character=start),
- end=Position(line=line_number, character=end),
- )
+ def get_tree_element_from_xpath(self, tree, xpath: Optional[str]) -> Optional[Any]:
+ if xpath is None or tree is None:
+ return None
+ element: Any = tree.xpath(xpath)
+ if element is not None:
+ if isinstance(element, list):
+ element = cast(list, element)
+ if len(element) > 0:
+ return element[0]
+ return None
+
+ def get_element_from_xpath(self, xpath: Optional[str]) -> Optional[Any]:
+ return self.get_tree_element_from_xpath(self.xml_tree, xpath)
+
+ def get_internal_element_range_or_default(self, element: Optional[Any]) -> Range:
+ if element is not None:
+ line_number = element.sourceline - 1
+ line_text = self.document.lines[line_number]
+ if isinstance(element, etree._Comment):
+ text = cast(str, element.text)
+ start = line_text.index(f"{text}")
+ end = start + len(text)
+ else:
+ # Prepend '<' for searching tag names
+ start = line_text.index(f"<{element.tag}") + 1
+ end = start + len(element.tag)
+ return Range(
+ start=Position(line=line_number, character=start),
+ end=Position(line=line_number, character=end),
+ )
+ return self.get_default_range()
+
+ def get_element_range_from_xpath_or_default(self, xpath: Optional[str]) -> Range:
+ element = self.get_element_from_xpath(xpath)
+ return self.get_internal_element_range_or_default(element)
diff --git a/server/galaxyls/services/xsd/service.py b/server/galaxyls/services/xsd/service.py
index 318b334e..649b2e21 100644
--- a/server/galaxyls/services/xsd/service.py
+++ b/server/galaxyls/services/xsd/service.py
@@ -22,7 +22,7 @@
)
from galaxyls.services.xsd.parser import GalaxyToolXsdParser
from galaxyls.services.xsd.types import XsdBase
-from galaxyls.services.xsd.validation import GalaxyToolValidationService
+from galaxyls.services.xsd.validation import GalaxyToolSchemaValidationService
NO_DOC_MARKUP = MarkupContent(kind=MarkupKind.Markdown, value=MSG_NO_DOCUMENTATION_AVAILABLE)
@@ -34,13 +34,12 @@ class GalaxyToolXsdService:
the XSD schema and validate XML files against it.
"""
- def __init__(self, server_name: str) -> None:
+ def __init__(self) -> None:
"""Initializes the validator by loading the XSD."""
- self.server_name = server_name
self.xsd_doc: etree._ElementTree = etree.parse(str(TOOL_XSD_FILE))
self.xsd_schema = etree.XMLSchema(self.xsd_doc)
self.xsd_parser = GalaxyToolXsdParser(self.xsd_doc.getroot())
- self.validator = GalaxyToolValidationService(server_name, self.xsd_schema)
+ self.validator = GalaxyToolSchemaValidationService(self.xsd_schema)
def validate_document(self, xml_document: XmlDocument) -> List[Diagnostic]:
"""Validates the Galaxy tool xml using the XSD schema and returns a list
diff --git a/server/galaxyls/services/xsd/validation.py b/server/galaxyls/services/xsd/validation.py
index 7972fa29..7c51e690 100644
--- a/server/galaxyls/services/xsd/validation.py
+++ b/server/galaxyls/services/xsd/validation.py
@@ -2,12 +2,8 @@
"""
from pathlib import Path
-from typing import (
- List,
- Optional,
-)
+from typing import List
-from galaxy.util import xml_macros
from lxml import etree
from pygls.lsp.types import (
Diagnostic,
@@ -16,23 +12,21 @@
Position,
Range,
)
-from pygls.workspace import Document
from galaxyls.constants import DiagnosticCodes
-from galaxyls.services.format import DEFAULT_INDENTATION
-from galaxyls.services.macros import remove_macros
from galaxyls.services.tools.document import GalaxyToolXmlDocument
from galaxyls.services.xml.document import XmlDocument
EXPAND_DOCUMENT_URI_SUFFIX = "%20%28Expanded%29"
-class GalaxyToolValidationService:
+class GalaxyToolSchemaValidationService:
"""Service providing diagnostics for errors in the XML validation."""
- def __init__(self, server_name: str, xsd_schema: etree.XMLSchema):
+ diagnostics_source = "Galaxy Schema Validator"
+
+ def __init__(self, xsd_schema: etree.XMLSchema):
"""Initializes the validator"""
- self.server_name = server_name
self.xsd_schema = xsd_schema
def validate_document(self, xml_document: XmlDocument) -> List[Diagnostic]:
@@ -47,23 +41,20 @@ def validate_document(self, xml_document: XmlDocument) -> List[Diagnostic]:
List[Diagnostic]: The list of issues found in the document.
"""
- syntax_errors = self._check_syntax(xml_document.document)
+ syntax_errors = self._check_syntax(xml_document)
if syntax_errors:
return syntax_errors
if not xml_document.is_tool_file:
return []
- tool = GalaxyToolXmlDocument.from_xml_document(xml_document)
try:
- xml_tree = etree.fromstring(tool.source)
- return self._validate_tree(xml_tree)
+ return self._validate(xml_document)
except ExpandMacrosFoundException:
- result = self._validate_expanded(tool)
- return result
+ return self._validate_expanded(xml_document)
except etree.XMLSyntaxError as e:
return self._build_diagnostics_from_syntax_error(e)
- def _check_syntax(self, document: Document) -> List[Diagnostic]:
+ def _check_syntax(self, xml_document: XmlDocument) -> List[Diagnostic]:
"""Check if the XML document contains any syntax error and returns it in a list.
Args:
@@ -73,12 +64,12 @@ def _check_syntax(self, document: Document) -> List[Diagnostic]:
List[Diagnostic]: The list containing the syntax error found or an empty list.
"""
try:
- etree.fromstring(document.source)
+ etree.fromstring(xml_document.document.source)
return []
except etree.XMLSyntaxError as e:
return self._build_diagnostics_from_syntax_error(e)
- def _validate_expanded(self, tool: GalaxyToolXmlDocument) -> List[Diagnostic]:
+ def _validate_expanded(self, xml_document: XmlDocument) -> List[Diagnostic]:
"""Validates the document after loading all the macros referenced and expands them.
Args:
@@ -89,39 +80,31 @@ def _validate_expanded(self, tool: GalaxyToolXmlDocument) -> List[Diagnostic]:
List[Diagnostic]: [description]
"""
try:
- expanded_tool_tree, _ = xml_macros.load_with_references(tool.path)
- expanded_xml = remove_macros(expanded_tool_tree)
- root = expanded_xml.getroot()
- etree.indent(root, space=DEFAULT_INDENTATION)
- content = etree.tostring(root, pretty_print=True, encoding=str)
- formatted_xml = etree.fromstring(content)
- self.xsd_schema.assertValid(formatted_xml)
+ if xml_document.xml_tree_expanded:
+ self.xsd_schema.assertValid(xml_document.xml_tree_expanded)
return []
except etree.DocumentInvalid as e:
- diagnostics = self._build_diagnostics_for_expanded_macros(tool, e)
- return diagnostics
+ return self._build_diagnostics_for_expanded_macros(xml_document, e)
except etree.XMLSyntaxError as e:
- return self._build_diagnostics_for_macros_file_syntax_error(tool, e)
+ return self._build_diagnostics_for_macros_file_syntax_error(xml_document, e)
- def _validate_tree(self, xml_tree) -> List[Diagnostic]:
- """Validates an XML tree against the XSD schema.
-
- Args:
- xml_tree (etree.ElementTree): The root element
+ except AssertionError as e:
+ return self._build_diagnostics_for_assertion_error(xml_document, e)
+ def _validate(self, xml_document: XmlDocument) -> List[Diagnostic]:
+ """Validates an XML document against the XSD schema.
Returns:
List[Diagnostic]: The diagnosis results
"""
try:
- self.xsd_schema.assertValid(xml_tree)
+ if xml_document.xml_tree:
+ self.xsd_schema.assertValid(xml_document.xml_tree)
return []
except etree.DocumentInvalid as e:
- return self._build_diagnostics(e.error_log, xml_tree)
+ return self._build_diagnostics(e.error_log, xml_document)
- def _build_diagnostics(
- self, error_log: etree._ListErrorLog, xml_tree: Optional[etree._ElementTree] = None
- ) -> List[Diagnostic]:
+ def _build_diagnostics(self, error_log: etree._ListErrorLog, xml_document: XmlDocument) -> List[Diagnostic]:
"""Gets a list of diagnostics from the XSD validation error log.
Args:
@@ -140,15 +123,13 @@ def _build_diagnostics(
diagnostics = []
for error in error_log.filter_from_errors():
if "expand" in error.message:
- raise ExpandMacrosFoundException(xml_tree)
+ raise ExpandMacrosFoundException()
+ range = xml_document.get_element_range_from_xpath_or_default(error.path)
result = Diagnostic(
- range=Range(
- start=Position(line=error.line - 1, character=error.column),
- end=Position(line=error.line - 1, character=error.column),
- ),
+ range=range,
message=error.message,
- source=self.server_name,
+ source=self.diagnostics_source,
)
diagnostics.append(result)
return diagnostics
@@ -168,15 +149,16 @@ def _build_diagnostics_from_syntax_error(self, error) -> List[Diagnostic]:
end=Position(line=error.lineno - 1, character=error.position[1] - 1),
),
message=error.msg,
- source=self.server_name,
+ source=self.diagnostics_source,
)
return [result]
- def _build_diagnostics_for_macros_file_syntax_error(self, tool: GalaxyToolXmlDocument, syntax_error) -> List[Diagnostic]:
+ def _build_diagnostics_for_macros_file_syntax_error(self, xml_document: XmlDocument, syntax_error) -> List[Diagnostic]:
+ tool = GalaxyToolXmlDocument.from_xml_document(xml_document)
result = Diagnostic(
range=tool.get_import_macro_file_range(syntax_error.filename),
message=syntax_error.msg,
- source=self.server_name,
+ source=self.diagnostics_source,
related_information=[
DiagnosticRelatedInformation(
message="Syntax error found on imported file.",
@@ -192,15 +174,15 @@ def _build_diagnostics_for_macros_file_syntax_error(self, tool: GalaxyToolXmlDoc
)
return [result]
- def _build_diagnostics_for_expanded_macros(self, tool: GalaxyToolXmlDocument, invalid_document_error) -> List[Diagnostic]:
- virtual_uri = tool.xml_document.document.uri.replace("file", "gls-expand")
- diagnostics = [
- Diagnostic(
- range=tool.get_macros_range(),
- message=error.message,
- source=self.server_name,
- code=DiagnosticCodes.INVALID_EXPANDED_TOOL,
- related_information=[
+ def _build_diagnostics_for_expanded_macros(self, xml_document: XmlDocument, invalid_document_error) -> List[Diagnostic]:
+ virtual_uri = xml_document.document.uri.replace("file", "gls-expand")
+ diagnostics = []
+ for error in invalid_document_error.error_log.filter_from_errors():
+ related_info: List[DiagnosticRelatedInformation] = []
+ elem_in_main_doc = xml_document.get_element_from_xpath(error.path)
+ if elem_in_main_doc is None:
+ elem_in_main_doc = xml_document.get_element_from_xpath("/tool/macros")
+ related_info = [
DiagnosticRelatedInformation(
message=(
"The validation error ocurred on the expanded version of "
@@ -215,12 +197,25 @@ def _build_diagnostics_for_expanded_macros(self, tool: GalaxyToolXmlDocument, in
),
),
)
- ],
+ ]
+ result = Diagnostic(
+ range=xml_document.get_internal_element_range_or_default(elem_in_main_doc),
+ message=error.message,
+ source=self.diagnostics_source,
+ code=DiagnosticCodes.INVALID_EXPANDED_TOOL,
+ related_information=related_info,
)
- for error in invalid_document_error.error_log.filter_from_errors()
- ]
+ diagnostics.append(result)
return diagnostics
+ def _build_diagnostics_for_assertion_error(self, xml_document: XmlDocument, error: AssertionError) -> List[Diagnostic]:
+ result = Diagnostic(
+ range=xml_document.get_default_range(),
+ message=str(error),
+ source=self.diagnostics_source,
+ )
+ return [result]
+
class ExpandMacrosFoundException(Exception):
"""This exceptions indicates that the current tool contains
diff --git a/server/galaxyls/tests/files/test_invalid_tool_01.xml b/server/galaxyls/tests/files/test_invalid_tool_01.xml
new file mode 100644
index 00000000..090fae55
--- /dev/null
+++ b/server/galaxyls/tests/files/test_invalid_tool_01.xml
@@ -0,0 +1 @@
+
diff --git a/server/galaxyls/tests/files/test_tool_01.xml b/server/galaxyls/tests/files/test_tool_01.xml
new file mode 100644
index 00000000..6f2f04b6
--- /dev/null
+++ b/server/galaxyls/tests/files/test_tool_01.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/server/galaxyls/tests/integration/test_completion.py b/server/galaxyls/tests/integration/test_completion.py
index 84c7715f..3f7d361a 100644
--- a/server/galaxyls/tests/integration/test_completion.py
+++ b/server/galaxyls/tests/integration/test_completion.py
@@ -18,7 +18,7 @@
@pytest.fixture()
def galaxy_xsd_tree() -> XsdTree:
- xsd_service = GalaxyToolXsdService("Integration Tests")
+ xsd_service = GalaxyToolXsdService()
tree = xsd_service.xsd_parser.get_tree()
return tree
diff --git a/server/galaxyls/tests/integration/test_context.py b/server/galaxyls/tests/integration/test_context.py
index 4954cc56..0701d10c 100644
--- a/server/galaxyls/tests/integration/test_context.py
+++ b/server/galaxyls/tests/integration/test_context.py
@@ -8,7 +8,7 @@
@pytest.fixture()
def galaxy_xsd_tree() -> XsdTree:
- xsd_service = GalaxyToolXsdService("Integration Tests")
+ xsd_service = GalaxyToolXsdService()
tree = xsd_service.xsd_parser.get_tree()
return tree
diff --git a/server/galaxyls/tests/unit/test_validation.py b/server/galaxyls/tests/unit/test_validation.py
index 195f2fc8..237412db 100644
--- a/server/galaxyls/tests/unit/test_validation.py
+++ b/server/galaxyls/tests/unit/test_validation.py
@@ -3,18 +3,14 @@
from galaxyls.services.validation import DocumentValidator
from ...services.xsd.constants import TOOL_XSD_FILE
-from ...services.xsd.validation import GalaxyToolValidationService
+from ...services.xsd.validation import GalaxyToolSchemaValidationService
from .sample_data import (
- TEST_INVALID_TOOL_01_DOCUMENT,
TEST_MACRO_01_DOCUMENT,
TEST_SYNTAX_ERROR_MACRO_01_DOCUMENT,
TEST_SYNTAX_ERROR_TOOL_01_DOCUMENT,
- TEST_TOOL_01_DOCUMENT,
)
from .utils import TestUtils
-TEST_SERVER_NAME = "Test Server"
-
@pytest.fixture(scope="module")
def xsd_schema() -> etree.XMLSchema:
@@ -25,15 +21,15 @@ def xsd_schema() -> etree.XMLSchema:
class TestGalaxyToolValidationServiceClass:
def test_validate_document_returns_empty_diagnostics_when_valid(self, xsd_schema: etree.XMLSchema) -> None:
- service = GalaxyToolValidationService(TEST_SERVER_NAME, xsd_schema)
- xml_document = TestUtils.from_document_to_xml_document(TEST_TOOL_01_DOCUMENT)
+ service = GalaxyToolSchemaValidationService(xsd_schema)
+ xml_document = TestUtils.get_test_xml_document_from_file("test_tool_01.xml")
actual = service.validate_document(xml_document)
assert actual == []
def test_validate_macro_file_returns_empty_diagnostics_when_valid(self, xsd_schema: etree.XMLSchema) -> None:
- service = GalaxyToolValidationService(TEST_SERVER_NAME, xsd_schema)
+ service = GalaxyToolSchemaValidationService(xsd_schema)
xml_document = TestUtils.from_document_to_xml_document(TEST_MACRO_01_DOCUMENT)
actual = service.validate_document(xml_document)
@@ -41,15 +37,15 @@ def test_validate_macro_file_returns_empty_diagnostics_when_valid(self, xsd_sche
assert actual == []
def test_validate_document_returns_diagnostics_when_invalid(self, xsd_schema: etree.XMLSchema) -> None:
- service = GalaxyToolValidationService(TEST_SERVER_NAME, xsd_schema)
- xml_document = TestUtils.from_document_to_xml_document(TEST_INVALID_TOOL_01_DOCUMENT)
+ service = GalaxyToolSchemaValidationService(xsd_schema)
+ xml_document = TestUtils.get_test_xml_document_from_file("test_invalid_tool_01.xml")
actual = service.validate_document(xml_document)
assert len(actual) > 0
def test_validate_document_returns_diagnostics_when_syntax_error(self, xsd_schema: etree.XMLSchema) -> None:
- service = GalaxyToolValidationService(TEST_SERVER_NAME, xsd_schema)
+ service = GalaxyToolSchemaValidationService(xsd_schema)
xml_document = TestUtils.from_document_to_xml_document(TEST_SYNTAX_ERROR_TOOL_01_DOCUMENT)
actual = service.validate_document(xml_document)
@@ -57,7 +53,7 @@ def test_validate_document_returns_diagnostics_when_syntax_error(self, xsd_schem
assert len(actual) == 1
def test_validate_macro_file_returns_diagnostics_when_syntax_error(self, xsd_schema: etree.XMLSchema) -> None:
- service = GalaxyToolValidationService(TEST_SERVER_NAME, xsd_schema)
+ service = GalaxyToolSchemaValidationService(xsd_schema)
xml_document = TestUtils.from_document_to_xml_document(TEST_SYNTAX_ERROR_MACRO_01_DOCUMENT)
actual = service.validate_document(xml_document)
diff --git a/server/galaxyls/tests/unit/test_xsd_service.py b/server/galaxyls/tests/unit/test_xsd_service.py
index f989cec7..7be81305 100644
--- a/server/galaxyls/tests/unit/test_xsd_service.py
+++ b/server/galaxyls/tests/unit/test_xsd_service.py
@@ -6,7 +6,7 @@
class TestGalaxyToolXsdServiceClass:
def test_get_documentation_for_unknown_node_attribute_returns_no_documentation(self, mocker: MockerFixture) -> None:
- service = GalaxyToolXsdService("Test")
+ service = GalaxyToolXsdService()
fake_context = mocker.Mock()
fake_context.xsd_element = None
@@ -15,7 +15,7 @@ def test_get_documentation_for_unknown_node_attribute_returns_no_documentation(s
assert doc.value == MSG_NO_DOCUMENTATION_AVAILABLE
def test_get_documentation_for_annotated_element(self, mocker: MockerFixture) -> None:
- service = GalaxyToolXsdService("Test")
+ service = GalaxyToolXsdService()
fake_context = mocker.Mock()
fake_context.is_tag = True
fake_context.is_attribute_key = False
@@ -27,7 +27,7 @@ def test_get_documentation_for_annotated_element(self, mocker: MockerFixture) ->
assert doc.value != MSG_NO_DOCUMENTATION_AVAILABLE
def test_get_documentation_for_element_using_annotated_type(self, mocker: MockerFixture) -> None:
- service = GalaxyToolXsdService("Test")
+ service = GalaxyToolXsdService()
fake_context = mocker.Mock()
fake_context.is_tag = True
fake_context.is_attribute_key = False
@@ -39,7 +39,7 @@ def test_get_documentation_for_element_using_annotated_type(self, mocker: Mocker
assert doc.value != MSG_NO_DOCUMENTATION_AVAILABLE
def test_get_documentation_for_annotated_attribute(self, mocker: MockerFixture) -> None:
- service = GalaxyToolXsdService("Test")
+ service = GalaxyToolXsdService()
fake_context = mocker.Mock()
fake_context.is_tag = False
fake_context.is_attribute_key = True
diff --git a/server/galaxyls/tests/unit/utils.py b/server/galaxyls/tests/unit/utils.py
index a6bad166..d8d40912 100644
--- a/server/galaxyls/tests/unit/utils.py
+++ b/server/galaxyls/tests/unit/utils.py
@@ -88,6 +88,12 @@ def get_test_document_from_file(filename: str) -> Document:
uri = path.as_uri()
return Document(uri)
+ @staticmethod
+ def get_test_xml_document_from_file(filename: str) -> XmlDocument:
+ """Gets a parsed XML document from the tests/files directory."""
+ document = TestUtils.get_test_document_from_file(filename)
+ return TestUtils.from_document_to_xml_document(document)
+
@staticmethod
def get_test_file_contents(filename: str) -> str:
"""Gets a the text contents of the given filename within the tests/files directory.