Skip to content

Commit

Permalink
Merge pull request #968 from tefra/move-validator
Browse files Browse the repository at this point in the history
feat: Move analyzer validations to handler
  • Loading branch information
tefra committed Mar 8, 2024
2 parents c94cbb7 + ae00dd0 commit 57e6f92
Show file tree
Hide file tree
Showing 12 changed files with 208 additions and 175 deletions.
70 changes: 70 additions & 0 deletions tests/codegen/handlers/test_validate_references.py
@@ -0,0 +1,70 @@
from xsdata.codegen.container import ClassContainer
from xsdata.codegen.handlers import ValidateReferences
from xsdata.exceptions import AnalyzerValueError
from xsdata.models.config import (
GeneratorConfig,
)
from xsdata.utils.testing import (
AttrFactory,
AttrTypeFactory,
ClassFactory,
ExtensionFactory,
FactoryTestCase,
)


class ValidateReferencesTests(FactoryTestCase):
def setUp(self):
super().setUp()
self.config = GeneratorConfig()
self.container = ClassContainer(config=self.config)
self.handler = ValidateReferences(container=self.container)

def test_validate_unique_qualified_names(self):
first = ClassFactory.create()
second = first.clone()
self.container.extend([first, second])

with self.assertRaises(AnalyzerValueError) as cm:
self.handler.run()

self.assertEqual("Duplicate types found", str(cm.exception))

def test_validate_unique_instances(self):
first = ClassFactory.create()
first.extensions.append(ExtensionFactory.create())
second = ClassFactory.create()
second.extensions = first.extensions
self.container.extend([first, second])

with self.assertRaises(AnalyzerValueError) as cm:
self.handler.run()

self.assertEqual("Cross reference detected", str(cm.exception))

def test_validate_unresolved_references(self):
first = ClassFactory.create()
first.attrs.append(AttrFactory.create())
first.attrs.append(AttrFactory.reference("foo"))
self.container.add(first)

with self.assertRaises(AnalyzerValueError) as cm:
self.handler.run()

self.assertEqual("Unresolved reference detected", str(cm.exception))

def test_validate_misrepresented_references(self):
first = ClassFactory.create()
inner = ClassFactory.create()
first.inner.append(inner)
first.attrs.append(
AttrFactory.create(
types=[AttrTypeFactory.create(qname="foo", reference=inner.ref)]
)
)
self.container.add(first)

with self.assertRaises(AnalyzerValueError) as cm:
self.handler.run()

self.assertEqual("Misrepresented reference", str(cm.exception))
56 changes: 0 additions & 56 deletions tests/codegen/test_analyzer.py

This file was deleted.

13 changes: 3 additions & 10 deletions tests/codegen/test_transformer.py
Expand Up @@ -3,7 +3,6 @@
from pathlib import Path
from unittest import mock

from xsdata.codegen.analyzer import ClassAnalyzer
from xsdata.codegen.container import ClassContainer
from xsdata.codegen.mappers import (
DefinitionsMapper,
Expand Down Expand Up @@ -470,19 +469,13 @@ def test_count_classes(self):

self.assertEqual((2, 16), self.transformer.count_classes(classes))

@mock.patch.object(ClassAnalyzer, "process")
@mock.patch.object(ClassContainer, "process")
def test_analyze_classes(self, mock_process):
classes = ClassFactory.list(2)
mock_process.return_value = classes[1:]

result = self.transformer.analyze_classes(classes)
self.assertEqual(1, len(result))

actual = mock_process.call_args[0][0]

self.assertIsInstance(actual, ClassContainer)
self.assertEqual(2, len(actual.data))
self.assertEqual(self.transformer.config, actual.config)
self.assertEqual(2, len(result))
mock_process.assert_called_once()

def test_get_cache_file(self):
uris = ["a.xml", "b.json"]
Expand Down
91 changes: 0 additions & 91 deletions xsdata/codegen/analyzer.py

This file was deleted.

14 changes: 10 additions & 4 deletions xsdata/codegen/container.py
Expand Up @@ -22,10 +22,12 @@
UpdateAttributesEffectiveChoice,
VacuumInnerClasses,
ValidateAttributesOverrides,
ValidateReferences,
)
from xsdata.codegen.mixins import ContainerInterface
from xsdata.codegen.models import Class, Status
from xsdata.codegen.utils import ClassUtils
from xsdata.codegen.validator import ClassValidator
from xsdata.models.config import GeneratorConfig
from xsdata.utils import collections
from xsdata.utils.constants import return_true
Expand All @@ -49,10 +51,11 @@ class ClassContainer(ContainerInterface):
Attributes:
processors: A step-processors mapping
data: The class qname map
step: The current process step
"""

__slots__ = ("data", "processors", "step")
__slots__ = ("processors", "step")

def __init__(self, config: GeneratorConfig):
"""Initialize the container and all the class processors.
Expand All @@ -64,10 +67,7 @@ def __init__(self, config: GeneratorConfig):
config: The generator configuration instance
"""
super().__init__(config)

self.step: int = 0
self.data: Dict = {}

self.processors: Dict[int, List] = {
Steps.UNGROUP: [
FlattenAttributeGroups(self),
Expand Down Expand Up @@ -176,6 +176,7 @@ def process(self):
5. Create compound fields, cleanup classes and atts
7. Designate final class names, packages and modules
"""
self.validate_classes()
self.process_classes(Steps.UNGROUP)
self.remove_groups()
self.process_classes(Steps.FLATTEN)
Expand All @@ -185,6 +186,10 @@ def process(self):
self.process_classes(Steps.FINALIZE)
self.designate_classes()

def validate_classes(self):
"""Merge redefined classes."""
ClassValidator(self).process()

def process_classes(self, step: int):
"""Run the given step processors for all classes.
Expand Down Expand Up @@ -219,6 +224,7 @@ def designate_classes(self):
"""Designate the final class names, packages and modules."""
designators = [
RenameDuplicateClasses(self),
ValidateReferences(self),
DesignateClassPackages(self),
]

Expand Down
2 changes: 2 additions & 0 deletions xsdata/codegen/handlers/__init__.py
Expand Up @@ -19,6 +19,7 @@
from .update_attributes_effective_choice import UpdateAttributesEffectiveChoice
from .vacuum_inner_classes import VacuumInnerClasses
from .validate_attributes_overrides import ValidateAttributesOverrides
from .validate_references import ValidateReferences

__all__ = [
"AddAttributeSubstitutions",
Expand All @@ -42,4 +43,5 @@
"UpdateAttributesEffectiveChoice",
"VacuumInnerClasses",
"ValidateAttributesOverrides",
"ValidateReferences",
]

0 comments on commit 57e6f92

Please sign in to comment.