Skip to content

Commit

Permalink
Add generator config search & replace substitutions
Browse files Browse the repository at this point in the history
  • Loading branch information
tefra committed Nov 23, 2021
1 parent 4cdf92b commit d192ab6
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 99 deletions.
3 changes: 3 additions & 0 deletions docs/api/codegen.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ like naming conventions and aliases.
OutputFormat
GeneratorConventions
GeneratorAliases
GeneratorSubstitutions
StructureStyle
DocstringStyle
ObjectType
GeneratorAlias
GeneratorSubstitution
NameConvention
NameCase
7 changes: 5 additions & 2 deletions tests/codegen/handlers/test_class_designate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from xsdata.exceptions import CodeGenerationError
from xsdata.models.config import GeneratorAlias
from xsdata.models.config import GeneratorConfig
from xsdata.models.config import ObjectType
from xsdata.models.config import StructureStyle
from xsdata.models.enums import Namespace
from xsdata.utils.testing import AttrFactory
Expand Down Expand Up @@ -190,8 +191,10 @@ def test_combine_ns_package(self):
result = self.handler.combine_ns_package(namespace)
self.assertEqual(["generated", "bar", "foo", "add"], result)

alias = GeneratorAlias(source=namespace, target="add.again")
self.config.aliases.package_name.append(alias)
alias = GeneratorAlias(
type=ObjectType.PACKAGE, source=namespace, target="add.again"
)
self.config.aliases.alias.append(alias)

result = self.handler.combine_ns_package(namespace)
self.assertEqual(["generated", "add", "again"], result)
8 changes: 4 additions & 4 deletions tests/fixtures/calculator/AddRQ.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Body>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns1:Add xmlns:ns1="http://tempuri.org/">
<ns1:intA>1</ns1:intA>
<ns1:intB>3</ns1:intB>
</ns1:Add>
</soap-env:Body>
</soap-env:Envelope>
</soapenv:Body>
</soapenv:Envelope>
8 changes: 4 additions & 4 deletions tests/fixtures/hello/HelloRQ.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Body>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns1:getHelloAsString xmlns:ns1="http://hello/">
<arg0>chris</arg0>
</ns1:getHelloAsString>
</soap-env:Body>
</soap-env:Envelope>
</soapenv:Body>
</soapenv:Envelope>
64 changes: 47 additions & 17 deletions tests/formats/dataclass/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
from xsdata.models.config import DocstringStyle
from xsdata.models.config import GeneratorAlias
from xsdata.models.config import GeneratorConfig
from xsdata.models.config import GeneratorSubstitution
from xsdata.models.config import NameCase
from xsdata.models.config import ObjectType
from xsdata.models.enums import DataType
from xsdata.models.enums import Namespace
from xsdata.models.enums import Tag
Expand All @@ -33,16 +35,19 @@ def setUp(self) -> None:
self.filters = Filters(config)

def test_class_name(self):
self.filters.class_aliases["boom"] = "Bang"
self.filters.aliases[ObjectType.CLASS]["boom"] = "Bang"
self.filters.substitutions[ObjectType.CLASS]["Abc"] = "Cba"

self.assertEqual("XsString", self.filters.class_name("xs:string"))
self.assertEqual("FooBarBam", self.filters.class_name("foo:bar_bam"))
self.assertEqual("ListType", self.filters.class_name("List"))
self.assertEqual("TypeType", self.filters.class_name(".*"))
self.assertEqual("Bang", self.filters.class_name("boom"))
self.assertEqual("Cbad", self.filters.class_name("abcd"))

def test_field_name(self):
self.filters.field_aliases["boom"] = "Bang"
self.filters.aliases[ObjectType.FIELD]["boom"] = "Bang"
self.filters.substitutions[ObjectType.FIELD]["abc"] = "cba"

self.assertEqual("value", self.filters.field_name("", "cls"))
self.assertEqual("foo", self.filters.field_name("foo", "cls"))
Expand All @@ -53,9 +58,11 @@ def test_field_name(self):
self.assertEqual("value_1", self.filters.field_name("1", "cls"))
self.assertEqual("Bang", self.filters.field_name("boom", "cls"))
self.assertEqual("value_minus_1_1", self.filters.field_name("-1.1", "cls"))
self.assertEqual("cbad", self.filters.field_name("abcd", "cls"))

def test_constant_name(self):
self.filters.field_aliases["boom"] = "Bang"
self.filters.aliases[ObjectType.FIELD]["boom"] = "Bang"
self.filters.substitutions[ObjectType.FIELD]["ABC"] = "CBA"

self.assertEqual("VALUE", self.filters.constant_name("", "cls"))
self.assertEqual("FOO", self.filters.constant_name("foo", "cls"))
Expand All @@ -66,9 +73,13 @@ def test_constant_name(self):
self.assertEqual("VALUE_1", self.filters.constant_name("1", "cls"))
self.assertEqual("Bang", self.filters.constant_name("boom", "cls"))
self.assertEqual("VALUE_MINUS_1", self.filters.constant_name("-1", "cls"))
self.assertEqual("CBAD", self.filters.constant_name("ABCD", "cls"))

def test_module_name(self):
self.filters.module_aliases["http://github.com/tefra/xsdata"] = "xsdata"
self.filters.aliases[ObjectType.MODULE].update(
{"http://github.com/tefra/xsdata": "xsdata"}
)
self.filters.substitutions[ObjectType.MODULE].update({"xsdata": "data"})

self.assertEqual("foo_bar", self.filters.module_name("fooBar"))
self.assertEqual("foo_bar_wtf", self.filters.module_name("fooBar.wtf"))
Expand All @@ -77,22 +88,24 @@ def test_module_name(self):
self.assertEqual("foo_bar_bam", self.filters.module_name("foo:bar_bam"))
self.assertEqual("bar_bam", self.filters.module_name("urn:bar_bam"))
self.assertEqual(
"pypi_org_project_xsdata",
"pypi_org_project_data",
self.filters.module_name("http://pypi.org/project/xsdata/"),
)
self.assertEqual(
"xsdata", self.filters.module_name("http://github.com/tefra/xsdata")
"data", self.filters.module_name("http://github.com/tefra/xsdata")
)

def test_package_name(self):
self.filters.package_aliases["boom"] = "bang"
self.filters.package_aliases["boom.boom"] = "booom"
self.filters.aliases[ObjectType.PACKAGE]["boom"] = "bang"
self.filters.aliases[ObjectType.PACKAGE]["boom.boom"] = "booom"
self.filters.substitutions[ObjectType.PACKAGE]["bam"] = "boom"

self.assertEqual(
"foo.bar_bar.pkg_1", self.filters.package_name("Foo.BAR_bar.1")
)
self.assertEqual("foo.bang.pkg_1", self.filters.package_name("Foo.boom.1"))
self.assertEqual("booom", self.filters.package_name("boom.boom"))
self.assertEqual("boom.boom", self.filters.package_name("bam.bam"))
self.assertEqual("", self.filters.package_name(""))

def test_type_name(self):
Expand Down Expand Up @@ -774,11 +787,17 @@ def test__init(self):
config.conventions.field_name.case = NameCase.PASCAL
config.conventions.module_name.safe_prefix = "safe_module"
config.conventions.module_name.case = NameCase.SNAKE
config.aliases.class_name.append(GeneratorAlias("a", "b"))
config.aliases.class_name.append(GeneratorAlias("c", "d"))
config.aliases.field_name.append(GeneratorAlias("e", "f"))
config.aliases.package_name.append(GeneratorAlias("g", "h"))
config.aliases.module_name.append(GeneratorAlias("i", "j"))
config.aliases.alias.append(GeneratorAlias(ObjectType.CLASS, "a", "b"))
config.aliases.alias.append(GeneratorAlias(ObjectType.CLASS, "c", "d"))
config.aliases.alias.append(GeneratorAlias(ObjectType.FIELD, "e", "f"))
config.aliases.alias.append(GeneratorAlias(ObjectType.PACKAGE, "g", "h"))
config.aliases.alias.append(GeneratorAlias(ObjectType.MODULE, "i", "j"))
config.substitutions.substitution.append(
GeneratorSubstitution(ObjectType.FIELD, "k", "l")
)
config.substitutions.substitution.append(
GeneratorSubstitution(ObjectType.PACKAGE, "m", "n")
)

filters = Filters(config)

Expand All @@ -794,7 +813,18 @@ def test__init(self):
self.assertEqual("cAB", filters.package_name("cAB"))
self.assertEqual("c_ab", filters.module_name("cAB"))

self.assertEqual({"a": "b", "c": "d"}, filters.class_aliases)
self.assertEqual({"e": "f"}, filters.field_aliases)
self.assertEqual({"g": "h"}, filters.package_aliases)
self.assertEqual({"i": "j"}, filters.module_aliases)
expected_aliases = {
ObjectType.CLASS: {"a": "b", "c": "d"},
ObjectType.FIELD: {"e": "f"},
ObjectType.MODULE: {"i": "j"},
ObjectType.PACKAGE: {"g": "h"},
}
self.assertEqual(expected_aliases, filters.aliases)

expected_substitutions = {
ObjectType.CLASS: {},
ObjectType.FIELD: {"k": "l"},
ObjectType.MODULE: {},
ObjectType.PACKAGE: {"m": "n"},
}
self.assertEqual(expected_substitutions, filters.substitutions)
23 changes: 15 additions & 8 deletions tests/models/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ def test_create(self):

expected = (
'<?xml version="1.0" encoding="UTF-8"?>\n'
f'<Config xmlns="http://pypi.org/project/xsdata" version="{__version__}">\n'
'<Config xmlns="http://pypi.org/project/xsdata" version="21.11">\n'
' <Output maxLineLength="79">\n'
" <Package>generated</Package>\n"
' <Format repr="true" eq="true" order="false" unsafeHash="false"'
' frozen="false" slots="false" kwOnly="false">dataclasses</Format>\n'
' <Format repr="true" eq="true" order="false" unsafeHash="false" frozen="false" slots="false" kwOnly="false">dataclasses</Format>\n'
" <Structure>filenames</Structure>\n"
" <DocstringStyle>reStructuredText</DocstringStyle>\n"
" <RelativeImports>false</RelativeImports>\n"
Expand All @@ -41,12 +40,18 @@ def test_create(self):
' <PackageName case="snakeCase" safePrefix="pkg"/>\n'
" </Conventions>\n"
" <Aliases>\n"
' <ClassName source="fooType" target="Foo"/>\n'
' <ClassName source="ABCSomething" target="ABCSomething"/>\n'
' <FieldName source="ChangeofGauge" target="change_of_gauge"/>\n'
' <PackageName source="http://www.w3.org/1999/xhtml" target="xtml"/>\n'
' <ModuleName source="2010.1" target="2020a"/>\n'
' <Alias type="package" source="http://www.w3.org/2001/XMLSchema" target="xs"/>\n'
' <Alias type="package" source="http://www.w3.org/XML/1998/namespace" target="xml"/>\n'
' <Alias type="package" source="http://www.w3.org/2001/XMLSchema-instance" target="xsi"/>\n'
' <Alias type="package" source="http://www.w3.org/1999/xlink" target="xlink"/>\n'
' <Alias type="package" source="http://www.w3.org/1999/xhtml" target="xhtml"/>\n'
' <Alias type="package" source="http://schemas.xmlsoap.org/wsdl/soap/" target="soap"/>\n'
' <Alias type="package" source="http://schemas.xmlsoap.org/wsdl/soap12/" target="soap12"/>\n'
' <Alias type="package" source="http://schemas.xmlsoap.org/soap/envelope/" target="soapenv"/>\n'
" </Aliases>\n"
" <Substitutions>\n"
' <Substitution type="class" search="Class" replace="Type"/>\n'
" </Substitutions>\n"
"</Config>\n"
)
self.assertEqual(expected, file_path.read_text())
Expand All @@ -63,6 +68,7 @@ def test_read(self):
' <ClassName case="pascalCase" safePrefix="type"/>\n'
" </Conventions>\n"
" <Aliases/>\n"
" <Substitutions/>\n"
"</Config>\n"
)
file_path = Path(tempfile.mktemp())
Expand Down Expand Up @@ -91,6 +97,7 @@ def test_read(self):
' <PackageName case="snakeCase" safePrefix="pkg"/>\n'
" </Conventions>\n"
" <Aliases/>\n"
" <Substitutions/>\n"
"</Config>\n"
)
self.assertEqual(expected, file_path.read_text())
Expand Down
8 changes: 4 additions & 4 deletions tests/utils/test_namespaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ def test_load_prefix(self):
self.assertEqual("ns0", load_prefix("a", ns_map))
self.assertEqual("ns0", load_prefix("a", ns_map))
self.assertEqual("xs", load_prefix(Namespace.XS.uri, ns_map))
self.assertEqual("soap-env", load_prefix(Namespace.SOAP_ENV.uri, ns_map))
self.assertEqual("soapenv", load_prefix(Namespace.SOAP_ENV.uri, ns_map))

expected = {
"ns0": "a",
"soap-env": "http://schemas.xmlsoap.org/soap/envelope/",
"soapenv": "http://schemas.xmlsoap.org/soap/envelope/",
"xs": "http://www.w3.org/2001/XMLSchema",
}
self.assertEqual(expected, ns_map)
Expand All @@ -35,13 +35,13 @@ def test_generate_prefix(self):
ns_map: Dict = {}
self.assertEqual("ns0", generate_prefix("a", ns_map))
self.assertEqual("xs", generate_prefix(Namespace.XS.uri, ns_map))
self.assertEqual("soap-env", generate_prefix(Namespace.SOAP_ENV.uri, ns_map))
self.assertEqual("soapenv", generate_prefix(Namespace.SOAP_ENV.uri, ns_map))
self.assertEqual("ns3", generate_prefix("b", ns_map))

expected = {
"ns0": "a",
"ns3": "b",
"soap-env": "http://schemas.xmlsoap.org/soap/envelope/",
"soapenv": "http://schemas.xmlsoap.org/soap/envelope/",
"xs": "http://www.w3.org/2001/XMLSchema",
}
self.assertEqual(expected, ns_map)
Expand Down
8 changes: 6 additions & 2 deletions xsdata/codegen/handlers/class_designate.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from xsdata.codegen.models import get_location
from xsdata.codegen.models import get_target_namespace
from xsdata.exceptions import CodeGenerationError
from xsdata.models.config import ObjectType
from xsdata.models.config import StructureStyle
from xsdata.models.enums import COMMON_SCHEMA_DIR
from xsdata.utils import collections
Expand Down Expand Up @@ -141,8 +142,11 @@ def group_common_paths(cls, paths: Iterable[str]) -> List[List[str]]:

def combine_ns_package(self, namespace: Optional[str]) -> List[str]:
result = self.container.config.output.package.split(".")
aliases = self.container.config.aliases.package_name
alias = collections.first(x.target for x in aliases if x.source == namespace)
alias = collections.first(
alias.target
for alias in self.container.config.aliases.alias
if alias.type == ObjectType.PACKAGE and alias.source == namespace
)

if alias:
result.extend(alias.split("."))
Expand Down
Loading

0 comments on commit d192ab6

Please sign in to comment.