-
-
Notifications
You must be signed in to change notification settings - Fork 55
/
test_validate_attributes_overrides.py
206 lines (170 loc) · 7.48 KB
/
test_validate_attributes_overrides.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
import sys
from unittest import mock
from xsdata.codegen.container import ClassContainer
from xsdata.codegen.handlers import ValidateAttributesOverrides
from xsdata.codegen.models import Status
from xsdata.models.config import GeneratorConfig
from xsdata.models.enums import DataType, Tag
from xsdata.utils.testing import (
AttrFactory,
ClassFactory,
ExtensionFactory,
FactoryTestCase,
)
class ValidateAttributesOverridesTests(FactoryTestCase):
def setUp(self):
super().setUp()
self.container = ClassContainer(config=GeneratorConfig())
self.processor = ValidateAttributesOverrides(container=self.container)
def test_prohibit_parent_attrs(self):
child = ClassFactory.create(
status=Status.FLATTENING,
attrs=[
AttrFactory.create(name="el", tag=Tag.ELEMENT),
AttrFactory.create(name="at", tag=Tag.ATTRIBUTE),
],
)
parent = ClassFactory.create(
status=Status.FLATTENED,
attrs=[
AttrFactory.element(default="foo"),
AttrFactory.attribute(),
AttrFactory.extension(),
AttrFactory.element(default="bar"),
],
)
child.extensions.append(
ExtensionFactory.reference(parent.qname, tag=Tag.RESTRICTION)
)
self.container.extend((parent, child))
self.processor.process(child)
self.assertEqual(4, len(child.attrs))
self.assertEqual(parent.attrs[0].name, child.attrs[0].name)
self.assertEqual([], child.attrs[0].types)
self.assertIsNone(child.attrs[0].default)
self.assertTrue(child.attrs[0].is_prohibited)
self.assertEqual(parent.attrs[3].name, child.attrs[1].name)
self.assertEqual([], child.attrs[1].types)
self.assertIsNone(child.attrs[1].default)
self.assertTrue(child.attrs[1].is_prohibited)
@mock.patch.object(ValidateAttributesOverrides, "resolve_conflict")
@mock.patch.object(ValidateAttributesOverrides, "validate_override")
def test_validate_attrs(self, mock_validate_override, mock_resolve_conflict):
class_a = ClassFactory.create(
status=Status.FLATTENING,
attrs=[
AttrFactory.create(name="el", tag=Tag.ELEMENT),
AttrFactory.create(name="at", tag=Tag.ATTRIBUTE),
],
)
class_b = ClassFactory.elements(2, status=Status.FLATTENED)
class_c = ClassFactory.create(status=Status.FLATTENED)
class_b.extensions.append(
ExtensionFactory.reference(class_c.qname, tag=Tag.EXTENSION)
)
class_a.extensions.append(
ExtensionFactory.reference(class_b.qname, tag=Tag.EXTENSION)
)
class_c.attrs.append(class_a.attrs[0].clone())
class_c.attrs.append(class_a.attrs[1].clone())
class_c.attrs[1].tag = Tag.ELEMENT
self.container.extend((class_a, class_b, class_c))
self.processor.process(class_a)
mock_validate_override.assert_called_once_with(
class_a, class_a.attrs[0], class_c.attrs[0]
)
mock_resolve_conflict.assert_called_once_with(
class_a.attrs[1], class_c.attrs[1]
)
def test_validate_attrs_remove_non_overriding_prohibited_attrs(self):
target = ClassFactory.elements(1)
target.attrs[0].restrictions.max_occurs = 0
self.processor.process(target)
self.assertEqual(0, len(target.attrs))
def test_overrides(self):
a = AttrFactory.create(tag=Tag.SIMPLE_TYPE)
b = a.clone()
self.assertTrue(self.processor.overrides(a, b))
b.tag = Tag.EXTENSION
self.assertTrue(self.processor.overrides(a, b))
b.namespace = "foo"
self.assertFalse(self.processor.overrides(a, b))
def test_validate_override(self):
attr_a = AttrFactory.create()
attr_b = attr_a.clone()
attr_b.parent = ClassFactory.create().qname
target = ClassFactory.create()
target.attrs.append(attr_a)
# 100 Match remove override attrs
self.processor.validate_override(target, attr_a, attr_b)
self.assertEqual(0, len(target.attrs))
# default doesn't match
target.attrs.append(attr_a)
attr_b.default = "1"
self.processor.validate_override(target, attr_a, attr_b)
self.assertEqual(1, len(target.attrs))
# mixed doesn't match
attr_b.default = attr_a.default
attr_b.mixed = True
self.processor.validate_override(target, attr_a, attr_b)
self.assertEqual(1, len(target.attrs))
# fixed doesn't match
attr_b.mixed = attr_a.mixed
attr_b.fixed = True
self.processor.validate_override(target, attr_a, attr_b)
self.assertEqual(1, len(target.attrs))
# Restrictions don't match
attr_b.fixed = attr_a.fixed
attr_a.restrictions.tokens = not attr_b.restrictions.tokens
attr_a.restrictions.nillable = not attr_b.restrictions.nillable
attr_a.restrictions.min_occurs = 0
attr_b.restrictions.min_occurs = 1
attr_a.restrictions.max_occurs = 0
attr_b.restrictions.max_occurs = 1
self.processor.validate_override(target, attr_a, attr_b)
self.assertEqual(1, len(target.attrs))
# Restrictions are compatible again
attr_a.restrictions.tokens = attr_b.restrictions.tokens
attr_a.restrictions.nillable = attr_b.restrictions.nillable
attr_a.restrictions.min_occurs = attr_b.restrictions.min_occurs = 1
attr_a.restrictions.max_occurs = attr_b.restrictions.max_occurs = 1
self.processor.validate_override(target, attr_a, attr_b)
self.assertEqual(0, len(target.attrs))
# Source is list, parent is not
target.attrs.append(attr_a)
attr_a.restrictions.min_occurs = None
attr_a.restrictions.max_occurs = 10
attr_b.restrictions.min_occurs = None
attr_b.restrictions.max_occurs = None
self.processor.validate_override(target, attr_a, attr_b)
self.assertEqual(sys.maxsize, attr_b.restrictions.max_occurs)
# Parent is list, source is not
target.attrs = [attr_a]
attr_a.restrictions.min_occurs = 0
attr_a.restrictions.max_occurs = 1
attr_b.restrictions.min_occurs = 0
attr_b.restrictions.max_occurs = 2
self.processor.validate_override(target, attr_a, attr_b)
self.assertEqual(2, attr_b.restrictions.max_occurs)
# Source is list, parent is prohibited
target.attrs = [attr_a]
attr_a.restrictions.min_occurs = None
attr_a.restrictions.max_occurs = 10
attr_b.restrictions.min_occurs = 0
attr_b.restrictions.max_occurs = 0
self.processor.validate_override(target, attr_a, attr_b)
self.assertEqual(0, attr_b.restrictions.max_occurs)
self.assertIn(attr_a, target.attrs)
# Parent is any type, source isn't, skip
attr_a = AttrFactory.native(DataType.STRING)
attr_b = AttrFactory.native(DataType.ANY_SIMPLE_TYPE)
target = ClassFactory.create(attrs=[attr_a])
self.processor.validate_override(target, attr_a.clone(), attr_b)
self.assertEqual(attr_a, target.attrs[0])
def test_resolve_conflicts(self):
a = AttrFactory.create(name="foo", tag=Tag.ATTRIBUTE)
b = a.clone()
b.tag = Tag.ELEMENT
self.processor.resolve_conflict(a, b)
self.assertEqual("foo_Attribute", a.name)
self.assertEqual("foo", b.name)