lutaml-model 0.5.2 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/dependent-tests.yml +2 -0
- data/.rubocop_todo.yml +39 -13
- data/Gemfile +1 -0
- data/README.adoc +430 -52
- data/lib/lutaml/model/constants.rb +7 -0
- data/lib/lutaml/model/error/type/invalid_value_error.rb +19 -0
- data/lib/lutaml/model/error.rb +1 -0
- data/lib/lutaml/model/key_value_mapping.rb +31 -2
- data/lib/lutaml/model/mapping_hash.rb +8 -0
- data/lib/lutaml/model/mapping_rule.rb +8 -0
- data/lib/lutaml/model/schema/templates/simple_type.rb +247 -0
- data/lib/lutaml/model/schema/xml_compiler.rb +720 -0
- data/lib/lutaml/model/schema.rb +5 -0
- data/lib/lutaml/model/serialize.rb +33 -13
- data/lib/lutaml/model/toml_adapter/toml_rb_adapter.rb +1 -2
- data/lib/lutaml/model/type/hash.rb +11 -11
- data/lib/lutaml/model/utils.rb +7 -0
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +5 -1
- data/lib/lutaml/model/xml_adapter/xml_document.rb +11 -15
- data/lib/lutaml/model/xml_mapping.rb +4 -2
- data/lib/lutaml/model/xml_mapping_rule.rb +1 -4
- data/lib/lutaml/model.rb +1 -0
- data/spec/fixtures/xml/invalid_math_document.xml +4 -0
- data/spec/fixtures/xml/math_document_schema.xsd +56 -0
- data/spec/fixtures/xml/test_schema.xsd +53 -0
- data/spec/fixtures/xml/valid_math_document.xml +4 -0
- data/spec/lutaml/model/cdata_spec.rb +2 -2
- data/spec/lutaml/model/custom_model_spec.rb +7 -20
- data/spec/lutaml/model/key_value_mapping_spec.rb +27 -0
- data/spec/lutaml/model/map_all_spec.rb +188 -0
- data/spec/lutaml/model/mixed_content_spec.rb +15 -15
- data/spec/lutaml/model/render_nil_spec.rb +29 -0
- data/spec/lutaml/model/schema/xml_compiler_spec.rb +1431 -0
- data/spec/lutaml/model/with_child_mapping_spec.rb +2 -2
- data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +52 -0
- data/spec/lutaml/model/xml_mapping_spec.rb +108 -1
- metadata +12 -2
@@ -0,0 +1,1431 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "lutaml/model/schema"
|
3
|
+
require "lutaml/xsd"
|
4
|
+
require "tmpdir"
|
5
|
+
|
6
|
+
RSpec.describe Lutaml::Model::Schema::XmlCompiler do
|
7
|
+
describe ".to_models" do
|
8
|
+
context "with valid xml schema, it should generate the models" do
|
9
|
+
let(:valid_value_xml_example) do
|
10
|
+
<<~VALID_XML_EXAMPLE
|
11
|
+
<CT_MathTest>
|
12
|
+
<MathTest val="1"/>
|
13
|
+
<MathTest1 val="1"/>
|
14
|
+
</CT_MathTest>
|
15
|
+
VALID_XML_EXAMPLE
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:invalid_value_xml_example) do
|
19
|
+
<<~INVALID_XML_EXAMPLE
|
20
|
+
<CT_MathTest>
|
21
|
+
<MathTest val="0"/>
|
22
|
+
<MathTest1 val="-3"/>
|
23
|
+
</CT_MathTest>
|
24
|
+
INVALID_XML_EXAMPLE
|
25
|
+
end
|
26
|
+
|
27
|
+
Dir.mktmpdir do |dir|
|
28
|
+
it "generates the models, requires them, and tests them with valid and invalid xml" do
|
29
|
+
described_class.to_models(File.read("spec/fixtures/xml/test_schema.xsd"), output_dir: dir)
|
30
|
+
expect(File).to exist("#{dir}/ct_math_test.rb")
|
31
|
+
expect(File).to exist("#{dir}/st_integer255.rb")
|
32
|
+
expect(File).to exist("#{dir}/long.rb")
|
33
|
+
Dir.each_child(dir) { |child| require_relative File.expand_path("#{dir}/#{child}") }
|
34
|
+
expect(defined?(CTMathTest)).to eq("constant")
|
35
|
+
expect(CTMathTest.from_xml(valid_value_xml_example).to_xml).to be_equivalent_to(valid_value_xml_example)
|
36
|
+
expect { CTMathTest.from_xml(invalid_value_xml_example) }.to raise_error(Lutaml::Model::Type::InvalidValueError)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when processing examples from classes generated by valid xml schema" do
|
42
|
+
Dir.mktmpdir do |dir|
|
43
|
+
before do
|
44
|
+
described_class.to_models(
|
45
|
+
File.read("spec/fixtures/xml/math_document_schema.xsd"),
|
46
|
+
output_dir: dir,
|
47
|
+
)
|
48
|
+
require_relative "#{dir}/math_document"
|
49
|
+
end
|
50
|
+
|
51
|
+
let(:valid_example) { File.read("spec/fixtures/xml/valid_math_document.xml") }
|
52
|
+
let(:invalid_example) { File.read("spec/fixtures/xml/invalid_math_document.xml") }
|
53
|
+
|
54
|
+
it "does not raise error with valid example" do
|
55
|
+
expect(defined?(MathDocument)).to eq("constant")
|
56
|
+
parsed = MathDocument.from_xml(valid_example)
|
57
|
+
expect(parsed.title).to eql("Example Title")
|
58
|
+
expect(parsed.ipv4_address).to eql("192.168.1.1")
|
59
|
+
expect(parsed.to_xml).to be_equivalent_to(valid_example)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "raises InvalidValueError" do
|
63
|
+
expect(defined?(MathDocument)).to eq("constant")
|
64
|
+
expect { MathDocument.from_xml(invalid_example) }.to raise_error(Lutaml::Model::Type::InvalidValueError)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "structure setup methods" do
|
71
|
+
describe ".as_models" do
|
72
|
+
context "when the XML adapter is not set" do
|
73
|
+
before do
|
74
|
+
Lutaml::Model::Config.xml_adapter_type = :ox
|
75
|
+
end
|
76
|
+
|
77
|
+
after do
|
78
|
+
Lutaml::Model::Config.xml_adapter_type = :nokogiri
|
79
|
+
end
|
80
|
+
|
81
|
+
it "raises an error" do
|
82
|
+
expect { described_class.send(:as_models, '<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"/>') }.to raise_error(Lutaml::Model::Error)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when the XML adapter is set and schema is given" do
|
87
|
+
let(:schema) { '<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"/>' }
|
88
|
+
|
89
|
+
it "initializes the instance variables with empty MappingHash" do
|
90
|
+
described_class.send(:as_models, schema)
|
91
|
+
variables = %i[@elements @attributes @group_types @simple_types @complex_types @attribute_groups]
|
92
|
+
variables.each do |variable|
|
93
|
+
instance_variable = described_class.instance_variable_get(variable)
|
94
|
+
expect(instance_variable).to be_a(Lutaml::Model::MappingHash)
|
95
|
+
expect(instance_variable).to be_empty
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
it "parses the schema and populates the instance variables" do
|
100
|
+
expect(described_class.send(:as_models, schema)).to be_nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe ".schema_to_models" do
|
106
|
+
context "when given schema element is empty" do
|
107
|
+
let(:schema) { [] }
|
108
|
+
|
109
|
+
it "returns nil if schema array is empty" do
|
110
|
+
expect(described_class.send(:schema_to_models, schema)).to be_nil
|
111
|
+
end
|
112
|
+
|
113
|
+
it "returns nil if schema array contains empty schema instance" do
|
114
|
+
schema << Lutaml::Xsd::Schema.new
|
115
|
+
expect(described_class.send(:schema_to_models, schema)).to be_nil
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "when given schema contains all the elements" do
|
120
|
+
before do
|
121
|
+
variables.each_key do |key|
|
122
|
+
described_class.instance_variable_set(:"@#{key}", to_mapping_hash({}))
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
after do
|
127
|
+
variables.each_key do |key|
|
128
|
+
described_class.instance_variable_set(:"@#{key}", nil)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
let(:schema) do
|
133
|
+
Lutaml::Xsd.parse(<<~XSD)
|
134
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
135
|
+
<xsd:element name="test_element"/>
|
136
|
+
<xsd:attribute name="test_attribute" type="xsd:string"/>
|
137
|
+
<xsd:group name="test_group"/>
|
138
|
+
<xsd:simpleType name="test_simple_type"/>
|
139
|
+
<xsd:complexType name="test_complex_type"/>
|
140
|
+
<xsd:attributeGroup name="test_attribute_group"/>
|
141
|
+
</xsd:schema>
|
142
|
+
XSD
|
143
|
+
end
|
144
|
+
|
145
|
+
let(:variables) do
|
146
|
+
{
|
147
|
+
elements: { "test_element" => { element_name: "test_element", type_name: nil } },
|
148
|
+
attributes: { "test_attribute" => { name: "test_attribute", base_class: "xsd:string" } },
|
149
|
+
group_types: { "test_group" => {} },
|
150
|
+
simple_types: { "test_simple_type" => {} },
|
151
|
+
complex_types: { "test_complex_type" => {} },
|
152
|
+
attribute_groups: { "test_attribute_group" => {} },
|
153
|
+
}
|
154
|
+
end
|
155
|
+
|
156
|
+
it "initializes the instance variables with empty MappingHash" do
|
157
|
+
described_class.send(:schema_to_models, [schema])
|
158
|
+
variables.each do |variable, expected_value|
|
159
|
+
instance_variable = described_class.instance_variable_get(:"@#{variable}")
|
160
|
+
expect(instance_variable).to be_a(Lutaml::Model::MappingHash)
|
161
|
+
expect(instance_variable).to eql(expected_value)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe ".setup_simple_type" do
|
168
|
+
context "when given simple_type contains restriction and union" do
|
169
|
+
let(:simple_type) do
|
170
|
+
Lutaml::Xsd::SimpleType.new.tap do |st|
|
171
|
+
st.restriction = Lutaml::Xsd::RestrictionSimpleType.new(base: "test_base")
|
172
|
+
st.union = Lutaml::Xsd::Union.new(member_types: "")
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
it "initializes the instance variables with empty MappingHash" do
|
177
|
+
expect(described_class.send(:setup_simple_type, simple_type)).to eql({ base_class: "test_base", union: [] })
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context "when simple_type contains nothing" do
|
182
|
+
let(:simple_type) { Lutaml::Xsd::SimpleType.new }
|
183
|
+
|
184
|
+
it "initializes the instance variables with empty MappingHash" do
|
185
|
+
expect(described_class.send(:setup_simple_type, simple_type)).to eql({})
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe ".restriction_content" do
|
191
|
+
context "when given restriction contains max_length, min_length, min_inclusive, max_inclusive, length" do
|
192
|
+
let(:restriction) do
|
193
|
+
Lutaml::Xsd::RestrictionSimpleType.new.tap do |r|
|
194
|
+
r.max_length = [Lutaml::Xsd::MaxLength.new(value: "10")]
|
195
|
+
r.min_length = [Lutaml::Xsd::MinLength.new(value: "1")]
|
196
|
+
r.min_inclusive = [Lutaml::Xsd::MinInclusive.new(value: "1")]
|
197
|
+
r.max_inclusive = [Lutaml::Xsd::MaxInclusive.new(value: "10")]
|
198
|
+
r.length = [Lutaml::Xsd::Length.new(value: "10")]
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
it "initializes the instance variables with empty MappingHash" do
|
203
|
+
described_class.send(:restriction_content, hash = {}, restriction)
|
204
|
+
expect(hash).to eql({ max_length: 10, min_length: 1, min_inclusive: "1", max_inclusive: "10", length: [{ value: 10 }] })
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context "when restriction contains nothing" do
|
209
|
+
let(:restriction) { Lutaml::Xsd::RestrictionSimpleType.new }
|
210
|
+
|
211
|
+
it "initializes the instance variables with empty MappingHash" do
|
212
|
+
described_class.send(:restriction_content, hash = {}, restriction)
|
213
|
+
expect(hash).to be_empty
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
describe ".restriction_length" do
|
219
|
+
context "when given restriction contains max_length, min_length, min_inclusive, max_inclusive, length" do
|
220
|
+
let(:lengths) do
|
221
|
+
[
|
222
|
+
Lutaml::Xsd::Length.new(value: "10", fixed: true),
|
223
|
+
Lutaml::Xsd::Length.new(value: "1"),
|
224
|
+
Lutaml::Xsd::Length.new(value: "1", fixed: true),
|
225
|
+
Lutaml::Xsd::Length.new(value: "10"),
|
226
|
+
Lutaml::Xsd::Length.new(value: "10", fixed: true),
|
227
|
+
]
|
228
|
+
end
|
229
|
+
|
230
|
+
let(:expected_content) do
|
231
|
+
[
|
232
|
+
{ value: 10, fixed: true },
|
233
|
+
{ value: 1 },
|
234
|
+
{ value: 1, fixed: true },
|
235
|
+
{ value: 10 },
|
236
|
+
{ value: 10, fixed: true },
|
237
|
+
]
|
238
|
+
end
|
239
|
+
|
240
|
+
it "initializes the instance variables with empty MappingHash" do
|
241
|
+
expect(described_class.send(:restriction_length, lengths)).to eql(expected_content)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
context "when restriction contains nothing" do
|
246
|
+
it "initializes the instance variables with empty MappingHash" do
|
247
|
+
expect(described_class.send(:restriction_length, [])).to be_empty
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe ".setup_complex_type" do
|
253
|
+
context "when given complex_type contains attribute, sequence, choice, complex_content, attribute_group, group, simple_content" do
|
254
|
+
let(:complex_type) do
|
255
|
+
Lutaml::Xsd::ComplexType.new.tap do |ct|
|
256
|
+
ct.attribute = [Lutaml::Xsd::Attribute.new(type: "test_attribute", name: "test_attribute1")]
|
257
|
+
ct.sequence = [Lutaml::Xsd::Sequence.new(name: "test_sequence")]
|
258
|
+
ct.choice = [Lutaml::Xsd::Choice.new(name: "test_choice")]
|
259
|
+
ct.complex_content = [Lutaml::Xsd::ComplexContent.new(name: "test_complex_content")]
|
260
|
+
ct.attribute_group = [Lutaml::Xsd::AttributeGroup.new(name: "test_attribute_group")]
|
261
|
+
ct.group = [Lutaml::Xsd::Group.new(name: "test_group")]
|
262
|
+
ct.simple_content = [Lutaml::Xsd::SimpleContent.new(name: "test_simple_content")]
|
263
|
+
ct.element_order = ["attribute", "sequence", "choice", "complex_content", "attribute_group", "group", "simple_content"]
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
let(:expected_hash) do
|
268
|
+
{
|
269
|
+
attributes: [{ name: "test_attribute1", base_class: "test_attribute" }],
|
270
|
+
sequence: {},
|
271
|
+
choice: {},
|
272
|
+
complex_content: {},
|
273
|
+
attribute_groups: [{}],
|
274
|
+
group: {},
|
275
|
+
simple_content: nil,
|
276
|
+
}
|
277
|
+
end
|
278
|
+
|
279
|
+
it "initializes the instance variables with empty MappingHash" do
|
280
|
+
expect(described_class.send(:setup_complex_type, complex_type)).to eql(expected_hash)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
context "when restriction contains nothing" do
|
285
|
+
let(:complex_type) do
|
286
|
+
Lutaml::Xsd::ComplexType.new.tap do |ct|
|
287
|
+
ct.element_order = []
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
it "initializes the instance variables with empty MappingHash" do
|
292
|
+
expect(described_class.send(:setup_complex_type, complex_type)).to be_empty
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
describe ".setup_simple_content" do
|
298
|
+
context "when given complex_type contains extension" do
|
299
|
+
let(:complex_type) do
|
300
|
+
Lutaml::Xsd::SimpleContent.new.tap do |ct|
|
301
|
+
ct.extension = Lutaml::Xsd::ExtensionSimpleContent.new(base: "test_extension")
|
302
|
+
ct.element_order = ["extension"]
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
let(:expected_hash) { { extension_base: "test_extension" } }
|
307
|
+
|
308
|
+
it "initializes the instance variables with empty MappingHash" do
|
309
|
+
expect(described_class.send(:setup_simple_content, complex_type)).to eql(expected_hash)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
context "when complex_type contains restriction" do
|
314
|
+
let(:complex_type) do
|
315
|
+
Lutaml::Xsd::SimpleContent.new.tap do |ct|
|
316
|
+
ct.restriction = Lutaml::Xsd::RestrictionSimpleContent.new(base: "test_restriction")
|
317
|
+
ct.element_order = ["restriction"]
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
it "initializes the instance variables with empty MappingHash" do
|
322
|
+
expect(described_class.send(:setup_simple_content, complex_type)).to eql({ base_class: "test_restriction" })
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
describe ".setup_sequence" do
|
328
|
+
context "when given sequence contains sequence, element, choice, group" do
|
329
|
+
let(:sequence) do
|
330
|
+
Lutaml::Xsd::Sequence.new.tap do |ct|
|
331
|
+
ct.sequence = [Lutaml::Xsd::Sequence.new(name: "test_sequence")]
|
332
|
+
ct.element = [
|
333
|
+
Lutaml::Xsd::Element.new(name: "test_element"),
|
334
|
+
Lutaml::Xsd::Element.new(ref: "test_ref"),
|
335
|
+
]
|
336
|
+
ct.choice = [Lutaml::Xsd::Choice.new(name: "test_choice")]
|
337
|
+
ct.group = [
|
338
|
+
Lutaml::Xsd::Group.new(name: "test_group"),
|
339
|
+
Lutaml::Xsd::Group.new(ref: "test_ref"),
|
340
|
+
]
|
341
|
+
ct.element_order = ["sequence", "group", "element", "choice", "element", "group"]
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
let(:expected_hash) do
|
346
|
+
{
|
347
|
+
sequences: [{}],
|
348
|
+
elements: [{ element_name: "test_element", type_name: nil }, { ref_class: "test_ref" }],
|
349
|
+
choice: [{}],
|
350
|
+
groups: [{}, { ref_class: "test_ref" }],
|
351
|
+
}
|
352
|
+
end
|
353
|
+
|
354
|
+
it "initializes the instance variables with empty MappingHash" do
|
355
|
+
expect(described_class.send(:setup_sequence, sequence)).to eql(expected_hash)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
context "when sequence contains nothing" do
|
360
|
+
let(:sequence) do
|
361
|
+
Lutaml::Xsd::Sequence.new.tap do |ct|
|
362
|
+
ct.element_order = []
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
it "initializes the instance variables with empty MappingHash" do
|
367
|
+
expect(described_class.send(:setup_sequence, sequence)).to be_empty
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
describe ".setup_group_type" do
|
373
|
+
context "when given group contains sequence, choice" do
|
374
|
+
let(:group) do
|
375
|
+
Lutaml::Xsd::Group.new.tap do |ct|
|
376
|
+
ct.sequence = [Lutaml::Xsd::Sequence.new(name: "test_sequence")]
|
377
|
+
ct.choice = [Lutaml::Xsd::Choice.new(name: "test_choice")]
|
378
|
+
ct.element_order = ["sequence", "choice"]
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
let(:expected_hash) { { sequence: {}, choice: {} } }
|
383
|
+
|
384
|
+
it "initializes the instance variables with empty MappingHash" do
|
385
|
+
expect(described_class.send(:setup_group_type, group)).to eql(expected_hash)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
context "when sequence contains nothing" do
|
390
|
+
let(:group) do
|
391
|
+
Lutaml::Xsd::Group.new.tap do |ct|
|
392
|
+
ct.element_order = []
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
it "initializes the instance variables with empty MappingHash" do
|
397
|
+
expect(described_class.send(:setup_group_type, group)).to be_empty
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
describe ".setup_choice" do
|
403
|
+
context "when given choice contains sequence, choice" do
|
404
|
+
let(:choice) do
|
405
|
+
Lutaml::Xsd::Choice.new.tap do |ct|
|
406
|
+
ct.element = [Lutaml::Xsd::Element.new(name: "test_element")]
|
407
|
+
ct.sequence = [Lutaml::Xsd::Sequence.new(name: "test_sequence")]
|
408
|
+
ct.choice = [Lutaml::Xsd::Choice.new(name: "test_choice")]
|
409
|
+
ct.group = [Lutaml::Xsd::Group.new(name: "test_group")]
|
410
|
+
ct.element_order = ["sequence", "choice", "group", "element"]
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
let(:expected_hash) { { sequence: {}, choice: {}, group: {}, "test_element" => { element_name: "test_element", type_name: nil } } }
|
415
|
+
|
416
|
+
it "initializes the instance variables with empty MappingHash" do
|
417
|
+
expect(described_class.send(:setup_choice, choice)).to eql(expected_hash)
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
context "when choice contains nothing" do
|
422
|
+
let(:choice) do
|
423
|
+
Lutaml::Xsd::Choice.new.tap do |ct|
|
424
|
+
ct.element_order = []
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
it "initializes the instance variables with empty MappingHash" do
|
429
|
+
expect(described_class.send(:setup_choice, choice)).to be_empty
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
describe ".setup_union" do
|
435
|
+
context "when given union contains member_types" do
|
436
|
+
before do
|
437
|
+
described_class.instance_variable_set(:@simple_types, simple_types)
|
438
|
+
end
|
439
|
+
|
440
|
+
after do
|
441
|
+
described_class.instance_variable_set(:@simple_types, nil)
|
442
|
+
end
|
443
|
+
|
444
|
+
let(:simple_types) do
|
445
|
+
{
|
446
|
+
"test_member_type" => { name: "test_member_type" },
|
447
|
+
"test_member_type1" => { name: "test_member_type1" },
|
448
|
+
}
|
449
|
+
end
|
450
|
+
|
451
|
+
let(:union) do
|
452
|
+
Lutaml::Xsd::Union.new.tap do |ct|
|
453
|
+
ct.member_types = "test_member_type test_member_type1"
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
let(:expected_hash) { [{ name: "test_member_type" }, { name: "test_member_type1" }] }
|
458
|
+
|
459
|
+
it "returns the expected hash" do
|
460
|
+
expect(described_class.send(:setup_union, union)).to eql(expected_hash)
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
464
|
+
context "when union contains nothing" do
|
465
|
+
let(:union) { Lutaml::Xsd::Union.new }
|
466
|
+
|
467
|
+
it "returns the empty hash" do
|
468
|
+
expect(described_class.send(:setup_union, union)).to be_empty
|
469
|
+
end
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
describe ".setup_attribute" do
|
474
|
+
context "when given attribute contains name and type" do
|
475
|
+
let(:attribute) do
|
476
|
+
Lutaml::Xsd::Attribute.new.tap do |attr|
|
477
|
+
attr.name = "test_name"
|
478
|
+
attr.type = "test_type"
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
let(:expected_hash) { { name: "test_name", base_class: "test_type" } }
|
483
|
+
|
484
|
+
it "returns the expected hash" do
|
485
|
+
expect(described_class.send(:setup_attribute, attribute)).to eql(expected_hash)
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
context "when given attribute contains ref" do
|
490
|
+
let(:attribute) do
|
491
|
+
Lutaml::Xsd::Attribute.new.tap do |attr|
|
492
|
+
attr.ref = "test_ref"
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
let(:expected_hash) { { ref_class: "test_ref" } }
|
497
|
+
|
498
|
+
it "returns the expected hash" do
|
499
|
+
expect(described_class.send(:setup_attribute, attribute)).to eql(expected_hash)
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
context "when attribute contains nothing" do
|
504
|
+
let(:attribute) { Lutaml::Xsd::Attribute.new }
|
505
|
+
let(:expected_hash) { { name: nil, base_class: nil } }
|
506
|
+
|
507
|
+
it "returns the empty hash" do
|
508
|
+
expect(described_class.send(:setup_attribute, attribute)).to eql(expected_hash)
|
509
|
+
end
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
describe ".setup_attribute_groups" do
|
514
|
+
context "when given attribute_group contains attribute and attribute_group" do
|
515
|
+
let(:attribute_group) do
|
516
|
+
Lutaml::Xsd::AttributeGroup.new.tap do |attr_group|
|
517
|
+
attr_group.attribute = [Lutaml::Xsd::Attribute.new(name: "test_name", type: "test_type")]
|
518
|
+
attr_group.attribute_group = [Lutaml::Xsd::AttributeGroup.new(name: "test_name", type: "test_type")]
|
519
|
+
attr_group.element_order = ["attribute", "attribute_group"]
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
523
|
+
let(:expected_hash) { { attributes: [{ name: "test_name", base_class: "test_type" }], attribute_groups: [{}] } }
|
524
|
+
|
525
|
+
it "returns the expected hash" do
|
526
|
+
expect(described_class.send(:setup_attribute_groups, attribute_group)).to eql(expected_hash)
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
context "when given attribute_group contains ref" do
|
531
|
+
let(:attribute_group) do
|
532
|
+
Lutaml::Xsd::AttributeGroup.new.tap do |attr_group|
|
533
|
+
attr_group.ref = "test_ref"
|
534
|
+
end
|
535
|
+
end
|
536
|
+
|
537
|
+
let(:expected_hash) { { ref_class: "test_ref" } }
|
538
|
+
|
539
|
+
it "returns the expected hash" do
|
540
|
+
expect(described_class.send(:setup_attribute_groups, attribute_group)).to eql(expected_hash)
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
context "when attribute_group contains nothing" do
|
545
|
+
let(:attribute_group) { Lutaml::Xsd::AttributeGroup.new }
|
546
|
+
|
547
|
+
it "returns the empty hash" do
|
548
|
+
expect(described_class.send(:setup_attribute_groups, attribute_group)).to be_empty
|
549
|
+
end
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
describe ".create_mapping_hash" do
|
554
|
+
context "when given value is a string and hash_key is :class_name" do
|
555
|
+
let(:value) { "test_value" }
|
556
|
+
let(:expected_hash) { { class_name: "test_value" } }
|
557
|
+
|
558
|
+
it "returns the expected hash" do
|
559
|
+
expect(described_class.send(:create_mapping_hash, value, hash_key: :class_name)).to eql(expected_hash)
|
560
|
+
end
|
561
|
+
end
|
562
|
+
|
563
|
+
context "when given value is a string and hash_key is :element_name" do
|
564
|
+
let(:value) { "test_value" }
|
565
|
+
let(:expected_hash) { { element_name: "test_value" } }
|
566
|
+
|
567
|
+
it "returns the expected hash" do
|
568
|
+
expect(described_class.send(:create_mapping_hash, value, hash_key: :element_name)).to eql(expected_hash)
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
572
|
+
context "when given value is a array and hash_key is :ref_class" do
|
573
|
+
let(:value) { ["test_value"] }
|
574
|
+
let(:expected_hash) { { ref_class: ["test_value"] } }
|
575
|
+
|
576
|
+
it "returns the expected hash" do
|
577
|
+
expect(described_class.send(:create_mapping_hash, value, hash_key: :ref_class)).to eql(expected_hash)
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
581
|
+
context "when given value is a string and hash_key is not given" do
|
582
|
+
let(:value) { "test_value" }
|
583
|
+
let(:expected_hash) { { class_name: "test_value" } }
|
584
|
+
|
585
|
+
it "returns the expected hash" do
|
586
|
+
expect(described_class.send(:create_mapping_hash, value)).to eql(expected_hash)
|
587
|
+
end
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
describe ".setup_element" do
|
592
|
+
before do
|
593
|
+
described_class.instance_variable_set(:@complex_types, complex_types)
|
594
|
+
end
|
595
|
+
|
596
|
+
after do
|
597
|
+
described_class.instance_variable_set(:@complex_types, nil)
|
598
|
+
end
|
599
|
+
|
600
|
+
let(:complex_types) { { "test_complex_type" => {} } }
|
601
|
+
|
602
|
+
context "when given element contains ref" do
|
603
|
+
let(:element) do
|
604
|
+
Lutaml::Xsd::Element.new.tap do |element|
|
605
|
+
element.ref = "test_ref"
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
let(:expected_hash) { { ref_class: "test_ref" } }
|
610
|
+
|
611
|
+
it "returns the expected hash" do
|
612
|
+
expect(described_class.send(:setup_element, element)).to eql(expected_hash)
|
613
|
+
end
|
614
|
+
end
|
615
|
+
|
616
|
+
context "when given element contains ref with other attributes/elements" do
|
617
|
+
let(:element) do
|
618
|
+
Lutaml::Xsd::Element.new.tap do |element|
|
619
|
+
element.ref = "test_ref"
|
620
|
+
element.type = "test_type"
|
621
|
+
element.name = "test_name"
|
622
|
+
element.min_occurs = 0
|
623
|
+
element.max_occurs = 1
|
624
|
+
element.complex_type = Lutaml::Xsd::ComplexType.new(name: "test_complex_type")
|
625
|
+
element.element_order = ["complex_type"]
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
629
|
+
let(:expected_hash) { { ref_class: "test_ref" } }
|
630
|
+
|
631
|
+
it "returns the expected hash" do
|
632
|
+
expect(described_class.send(:setup_element, element)).to eql(expected_hash)
|
633
|
+
end
|
634
|
+
end
|
635
|
+
|
636
|
+
context "when given element contains type, name and min/max_occurs" do
|
637
|
+
let(:element) do
|
638
|
+
Lutaml::Xsd::Element.new.tap do |element|
|
639
|
+
element.type = "test_type"
|
640
|
+
element.name = "test_name"
|
641
|
+
element.min_occurs = 0
|
642
|
+
element.max_occurs = 1
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
646
|
+
let(:expected_hash) { { type_name: "test_type", element_name: "test_name", arguments: { min_occurs: "0", max_occurs: "1" } } }
|
647
|
+
|
648
|
+
it "returns the expected hash" do
|
649
|
+
expect(described_class.send(:setup_element, element)).to eql(expected_hash)
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
653
|
+
context "when given element contains name, type, and complex_type and no min/max_occurs" do
|
654
|
+
let(:element) do
|
655
|
+
Lutaml::Xsd::Element.new.tap do |element|
|
656
|
+
element.type = "test_type"
|
657
|
+
element.name = "test_name"
|
658
|
+
element.complex_type = Lutaml::Xsd::ComplexType.new(name: "test_complex_type")
|
659
|
+
element.element_order = ["complex_type"]
|
660
|
+
end
|
661
|
+
end
|
662
|
+
|
663
|
+
let(:expected_hash) { { type_name: "test_type", element_name: "test_name", complex_type: {} } }
|
664
|
+
|
665
|
+
it "returns the expected hash" do
|
666
|
+
expect(described_class.send(:setup_element, element)).to eql(expected_hash)
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
670
|
+
context "when given element contains nothing" do
|
671
|
+
let(:element) { Lutaml::Xsd::Element.new }
|
672
|
+
let(:expected_hash) { { type_name: nil, element_name: nil } }
|
673
|
+
|
674
|
+
it "returns the expected hash" do
|
675
|
+
expect(described_class.send(:setup_element, element)).to eql(expected_hash)
|
676
|
+
end
|
677
|
+
end
|
678
|
+
end
|
679
|
+
|
680
|
+
describe ".setup_restriction" do
|
681
|
+
context "when given restriction contains base and pattern" do
|
682
|
+
let(:restriction) do
|
683
|
+
Lutaml::Xsd::RestrictionSimpleType.new.tap do |restriction|
|
684
|
+
restriction.base = "test_base"
|
685
|
+
restriction.pattern = [
|
686
|
+
Lutaml::Xsd::Pattern.new(value: /test_pattern/),
|
687
|
+
Lutaml::Xsd::Pattern.new(value: /test_pattern1/),
|
688
|
+
]
|
689
|
+
restriction.enumeration = [
|
690
|
+
Lutaml::Xsd::Enumeration.new(value: "test_value"),
|
691
|
+
Lutaml::Xsd::Enumeration.new(value: "test_value1"),
|
692
|
+
]
|
693
|
+
end
|
694
|
+
end
|
695
|
+
|
696
|
+
let(:expected_hash) { { base_class: "test_base", pattern: "((?-mix:test_pattern))|((?-mix:test_pattern1))", values: ["test_value", "test_value1"] } }
|
697
|
+
|
698
|
+
it "returns the expected hash" do
|
699
|
+
expect(described_class.send(:setup_restriction, restriction, {})).to eql(expected_hash)
|
700
|
+
end
|
701
|
+
end
|
702
|
+
|
703
|
+
context "when given restriction contains nothing" do
|
704
|
+
let(:restriction) { Lutaml::Xsd::RestrictionSimpleType.new }
|
705
|
+
|
706
|
+
it "returns the expected hash" do
|
707
|
+
expect(described_class.send(:setup_restriction, restriction, {})).to eql({ base_class: nil })
|
708
|
+
end
|
709
|
+
end
|
710
|
+
end
|
711
|
+
|
712
|
+
describe ".restriction_patterns" do
|
713
|
+
context "when given patterns are not empty" do
|
714
|
+
let(:patterns) do
|
715
|
+
[
|
716
|
+
Lutaml::Xsd::Pattern.new(value: /test_pattern/),
|
717
|
+
Lutaml::Xsd::Pattern.new(value: /test_pattern1/),
|
718
|
+
]
|
719
|
+
end
|
720
|
+
|
721
|
+
let(:expected_hash) { { pattern: "((?-mix:test_pattern))|((?-mix:test_pattern1))" } }
|
722
|
+
|
723
|
+
it "returns the expected hash" do
|
724
|
+
expect(described_class.send(:restriction_patterns, patterns, {})).to eql(expected_hash)
|
725
|
+
end
|
726
|
+
end
|
727
|
+
|
728
|
+
context "when given patterns are empty" do
|
729
|
+
let(:patterns) { [] }
|
730
|
+
|
731
|
+
it "returns the expected hash" do
|
732
|
+
expect(described_class.send(:restriction_patterns, patterns, {})).to be_nil
|
733
|
+
end
|
734
|
+
end
|
735
|
+
end
|
736
|
+
|
737
|
+
describe ".setup_complex_content" do
|
738
|
+
context "when given complex_content contains extension with mixed attribute" do
|
739
|
+
let(:complex_content) do
|
740
|
+
Lutaml::Xsd::ComplexContent.new.tap do |complex_content|
|
741
|
+
complex_content.mixed = true
|
742
|
+
complex_content.extension = Lutaml::Xsd::ExtensionComplexContent.new(base: "test_base")
|
743
|
+
end
|
744
|
+
end
|
745
|
+
|
746
|
+
let(:expected_hash) { { mixed: true, extension: { extension_base: "test_base" } } }
|
747
|
+
|
748
|
+
it "returns the expected hash" do
|
749
|
+
expect(described_class.send(:setup_complex_content, complex_content)).to eql(expected_hash)
|
750
|
+
end
|
751
|
+
end
|
752
|
+
|
753
|
+
context "when given complex_content contains restriction" do
|
754
|
+
let(:complex_content) do
|
755
|
+
Lutaml::Xsd::ComplexContent.new.tap do |complex_content|
|
756
|
+
complex_content.restriction = Lutaml::Xsd::RestrictionComplexContent.new(base: "test_base")
|
757
|
+
end
|
758
|
+
end
|
759
|
+
|
760
|
+
let(:expected_hash) { { base_class: "test_base" } }
|
761
|
+
|
762
|
+
it "returns the expected hash" do
|
763
|
+
expect(described_class.send(:setup_complex_content, complex_content)).to eql(expected_hash)
|
764
|
+
end
|
765
|
+
end
|
766
|
+
end
|
767
|
+
|
768
|
+
describe ".setup_extension" do
|
769
|
+
context "when given extension contains attributes" do
|
770
|
+
let(:extension) do
|
771
|
+
Lutaml::Xsd::ExtensionComplexContent.new.tap do |extension|
|
772
|
+
extension.base = "test_base"
|
773
|
+
extension.attribute = [
|
774
|
+
Lutaml::Xsd::Attribute.new(type: "ST_Attr1", name: "Attr1", default: "1"),
|
775
|
+
Lutaml::Xsd::Attribute.new(type: "ST_Attr2", name: "Attr2", default: "2"),
|
776
|
+
]
|
777
|
+
extension.sequence = Lutaml::Xsd::Sequence.new
|
778
|
+
extension.choice = Lutaml::Xsd::Choice.new
|
779
|
+
extension.element_order = ["attribute", "sequence", "choice", "attribute"]
|
780
|
+
end
|
781
|
+
end
|
782
|
+
|
783
|
+
let(:expected_hash) do
|
784
|
+
{
|
785
|
+
extension_base: "test_base",
|
786
|
+
attributes: [{ base_class: "ST_Attr1", name: "Attr1", default: "1" }, { base_class: "ST_Attr2", name: "Attr2", default: "2" }],
|
787
|
+
sequence: {},
|
788
|
+
choice: {},
|
789
|
+
}
|
790
|
+
end
|
791
|
+
|
792
|
+
it "returns the expected hash" do
|
793
|
+
expect(described_class.send(:setup_extension, extension)).to eql(expected_hash)
|
794
|
+
end
|
795
|
+
end
|
796
|
+
|
797
|
+
context "when given extension contains nothing" do
|
798
|
+
let(:extension) { Lutaml::Xsd::ExtensionComplexContent.new }
|
799
|
+
|
800
|
+
it "returns the expected hash" do
|
801
|
+
expect(described_class.send(:setup_extension, extension)).to eql({ extension_base: nil })
|
802
|
+
end
|
803
|
+
end
|
804
|
+
end
|
805
|
+
|
806
|
+
describe ".element_arguments" do
|
807
|
+
context "when given element contains min_occurs and max_occurs" do
|
808
|
+
let(:element) do
|
809
|
+
Lutaml::Xsd::Element.new.tap do |element|
|
810
|
+
element.min_occurs = "0"
|
811
|
+
element.max_occurs = "1"
|
812
|
+
end
|
813
|
+
end
|
814
|
+
|
815
|
+
let(:expected_hash) { { min_occurs: "0", max_occurs: "1" } }
|
816
|
+
|
817
|
+
it "returns the expected hash" do
|
818
|
+
expect(described_class.send(:element_arguments, element, {})).to eql(expected_hash)
|
819
|
+
end
|
820
|
+
end
|
821
|
+
|
822
|
+
context "when given element contains nothing" do
|
823
|
+
let(:element) { Lutaml::Xsd::Element.new }
|
824
|
+
|
825
|
+
it "returns the expected hash" do
|
826
|
+
expect(described_class.send(:element_arguments, element, {})).to be_empty
|
827
|
+
end
|
828
|
+
end
|
829
|
+
end
|
830
|
+
|
831
|
+
describe ".resolved_element_order" do
|
832
|
+
context "when given element contains element_order but no instance relevant elements/instances" do
|
833
|
+
let(:element) do
|
834
|
+
Lutaml::Xsd::Element.new.tap do |element|
|
835
|
+
element.element_order = ["annotation", "simple_type", "complex_type", "key"]
|
836
|
+
end
|
837
|
+
end
|
838
|
+
|
839
|
+
it "raises an error when element_order contains elements that isn't an attribute of the instance" do
|
840
|
+
element.element_order << "test_element"
|
841
|
+
expect { described_class.send(:resolved_element_order, element) }.to raise_error(NoMethodError)
|
842
|
+
end
|
843
|
+
|
844
|
+
it "returns the array with nil values" do
|
845
|
+
expected_hash = [nil, nil, nil, nil]
|
846
|
+
expect(described_class.send(:resolved_element_order, element)).to eql(expected_hash)
|
847
|
+
end
|
848
|
+
end
|
849
|
+
|
850
|
+
context "when given element contains element_order but with relevant elements/instances" do
|
851
|
+
let(:element) do
|
852
|
+
Lutaml::Xsd::Element.new.tap do |element|
|
853
|
+
element.annotation = Lutaml::Xsd::Annotation.new
|
854
|
+
element.simple_type = Lutaml::Xsd::SimpleType.new
|
855
|
+
element.complex_type = Lutaml::Xsd::ComplexType.new
|
856
|
+
element.key = Lutaml::Xsd::Key.new
|
857
|
+
element.element_order = ["annotation", "simple_type", "complex_type", "key"]
|
858
|
+
end
|
859
|
+
end
|
860
|
+
|
861
|
+
let(:expected_hash) { [element.annotation, element.simple_type, element.complex_type, element.key] }
|
862
|
+
|
863
|
+
it "returns the expected hash" do
|
864
|
+
expect(described_class.send(:resolved_element_order, element)).to eql(expected_hash)
|
865
|
+
end
|
866
|
+
end
|
867
|
+
|
868
|
+
context "when given element contains empty element_order with elements/instances" do
|
869
|
+
let(:element) do
|
870
|
+
Lutaml::Xsd::Element.new.tap do |element|
|
871
|
+
element.element_order = []
|
872
|
+
end
|
873
|
+
end
|
874
|
+
|
875
|
+
it "returns the expected hash" do
|
876
|
+
expect(described_class.send(:resolved_element_order, element)).to be_empty
|
877
|
+
end
|
878
|
+
end
|
879
|
+
end
|
880
|
+
end
|
881
|
+
|
882
|
+
describe "structure to template content resolving methods" do
|
883
|
+
describe ".resolve_parent_class" do
|
884
|
+
context "when complex_content.extension is not present" do
|
885
|
+
it "returns Lutaml::Model::Serializable" do
|
886
|
+
expect(described_class.send(:resolve_parent_class, {})).to eql("Lutaml::Model::Serializable")
|
887
|
+
end
|
888
|
+
end
|
889
|
+
|
890
|
+
context "when complex_content.extension is present" do
|
891
|
+
it "returns the extension_base value" do
|
892
|
+
content = { complex_content: { extension: { extension_base: "ST_Parent" } } }
|
893
|
+
expect(described_class.send(:resolve_parent_class, content)).to eql("STParent")
|
894
|
+
end
|
895
|
+
end
|
896
|
+
end
|
897
|
+
|
898
|
+
describe ".resolve_attribute_class" do
|
899
|
+
context "when attribute.base_class is one of the standard classes" do
|
900
|
+
described_class::DEFAULT_CLASSES.each do |standard_class|
|
901
|
+
it "returns the attribute_class value for #{standard_class.capitalize}" do
|
902
|
+
base_class_hash = to_mapping_hash({ base_class: "xsd:#{standard_class}" })
|
903
|
+
expect(described_class.send(:resolve_attribute_class, base_class_hash)).to eql(":#{standard_class}")
|
904
|
+
end
|
905
|
+
end
|
906
|
+
end
|
907
|
+
|
908
|
+
context "when attribute.base_class is not one of the standard classes" do
|
909
|
+
it "returns the attribute_class value" do
|
910
|
+
base_class_hash = to_mapping_hash({ base_class: "test_st_attr1" })
|
911
|
+
expect(described_class.send(:resolve_attribute_class, base_class_hash)).to eql("TestStAttr1")
|
912
|
+
end
|
913
|
+
end
|
914
|
+
end
|
915
|
+
|
916
|
+
describe ".resolve_occurs" do
|
917
|
+
context "when min_occurs and max_occurs are present" do
|
918
|
+
it "returns the collection: true" do
|
919
|
+
base_class_hash = to_mapping_hash({ min_occurs: 0, max_occurs: "unbounded" })
|
920
|
+
expect(described_class.send(:resolve_occurs, base_class_hash)).to eql(", collection: true")
|
921
|
+
end
|
922
|
+
|
923
|
+
it "returns the collection: 0..1" do
|
924
|
+
base_class_hash = to_mapping_hash({ min_occurs: 0, max_occurs: 1 })
|
925
|
+
expect(described_class.send(:resolve_occurs, base_class_hash)).to eql(", collection: 0..1")
|
926
|
+
end
|
927
|
+
end
|
928
|
+
|
929
|
+
context "when min_occurs/max_occurs are not present" do
|
930
|
+
it "returns the collection: 0.." do
|
931
|
+
base_class_hash = to_mapping_hash({ min_occurs: 0, max_occurs: 1 })
|
932
|
+
expect(described_class.send(:resolve_occurs, base_class_hash)).to eql(", collection: 0..1")
|
933
|
+
end
|
934
|
+
end
|
935
|
+
end
|
936
|
+
|
937
|
+
describe ".resolve_elements" do
|
938
|
+
before do
|
939
|
+
described_class.instance_variable_set(:@elements, elements)
|
940
|
+
end
|
941
|
+
|
942
|
+
after do
|
943
|
+
described_class.instance_variable_set(:@elements, nil)
|
944
|
+
end
|
945
|
+
|
946
|
+
let(:elements) do
|
947
|
+
to_mapping_hash({ "testRef" => to_mapping_hash({ element_name: "testElement" }) })
|
948
|
+
end
|
949
|
+
|
950
|
+
context "when elements contain ref_class and base_class elements" do
|
951
|
+
it "returns the elements hash" do
|
952
|
+
content = [to_mapping_hash({ ref_class: "testRef" }), to_mapping_hash({ element_name: "testElement1" })]
|
953
|
+
expected_elements = { "testElement" => { element_name: "testElement" }, "testElement1" => { element_name: "testElement1" } }
|
954
|
+
expect(described_class.send(:resolve_elements, content)).to eql(expected_elements)
|
955
|
+
end
|
956
|
+
end
|
957
|
+
end
|
958
|
+
|
959
|
+
describe ".resolve_content" do
|
960
|
+
let(:content) do
|
961
|
+
{
|
962
|
+
sequence: [],
|
963
|
+
choice: [],
|
964
|
+
group: [],
|
965
|
+
}
|
966
|
+
end
|
967
|
+
|
968
|
+
context "when content contain empty sequence, choice and group" do
|
969
|
+
it "returns the elements hash" do
|
970
|
+
expect(described_class.send(:resolve_content, content)).to be_empty
|
971
|
+
end
|
972
|
+
end
|
973
|
+
end
|
974
|
+
|
975
|
+
describe ".resolve_sequence" do
|
976
|
+
let(:sequence) do
|
977
|
+
{
|
978
|
+
sequence: [],
|
979
|
+
elements: [],
|
980
|
+
groups: [],
|
981
|
+
choice: [],
|
982
|
+
}
|
983
|
+
end
|
984
|
+
|
985
|
+
context "when sequence contain empty elements and other empty attributes" do
|
986
|
+
it "returns the elements empty hash" do
|
987
|
+
expect(described_class.send(:resolve_sequence, sequence)).to be_empty
|
988
|
+
end
|
989
|
+
end
|
990
|
+
end
|
991
|
+
|
992
|
+
describe ".resolve_choice" do
|
993
|
+
let(:choice) do
|
994
|
+
{
|
995
|
+
"string" => to_mapping_hash({ element_name: "testElement" }),
|
996
|
+
sequence: [],
|
997
|
+
element: [],
|
998
|
+
group: [],
|
999
|
+
}
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
context "when choice contain empty elements and other empty attributes" do
|
1003
|
+
it "returns the one element hash" do
|
1004
|
+
expect(described_class.send(:resolve_choice, choice)).to eql({ "string" => { element_name: "testElement" } })
|
1005
|
+
end
|
1006
|
+
end
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
describe ".resolve_group" do
|
1010
|
+
before do
|
1011
|
+
described_class.instance_variable_set(:@group_types, group_types)
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
after do
|
1015
|
+
described_class.instance_variable_set(:@group_types, nil)
|
1016
|
+
end
|
1017
|
+
|
1018
|
+
let(:group_types) { { "testRef" => {} } }
|
1019
|
+
|
1020
|
+
let(:group) do
|
1021
|
+
{
|
1022
|
+
ref_class: "testRef",
|
1023
|
+
sequence: [],
|
1024
|
+
choice: [],
|
1025
|
+
group: [],
|
1026
|
+
}
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
context "when group contain ref_class and other empty attributes" do
|
1030
|
+
it "returns the one element hash" do
|
1031
|
+
expect(described_class.send(:resolve_group, group)).to be_empty
|
1032
|
+
end
|
1033
|
+
end
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
describe ".resolve_complex_content" do
|
1037
|
+
let(:complex_content) do
|
1038
|
+
{
|
1039
|
+
extension: {},
|
1040
|
+
restriction: {},
|
1041
|
+
}
|
1042
|
+
end
|
1043
|
+
|
1044
|
+
context "when complex_content contain extension and restriction" do
|
1045
|
+
it "returns the one element hash" do
|
1046
|
+
expect(described_class.send(:resolve_complex_content, complex_content)).to be_empty
|
1047
|
+
end
|
1048
|
+
end
|
1049
|
+
end
|
1050
|
+
|
1051
|
+
describe ".resolve_extension" do
|
1052
|
+
let(:extension) do
|
1053
|
+
{
|
1054
|
+
attributes: [{ base_class: "ST_Attr1", default: "1" }, { base_class: "ST_Attr2", default: "2" }],
|
1055
|
+
sequence: {},
|
1056
|
+
choice: {},
|
1057
|
+
}
|
1058
|
+
end
|
1059
|
+
|
1060
|
+
context "when extension contain attributes, sequence and choice" do
|
1061
|
+
it "returns the one element hash" do
|
1062
|
+
expect(described_class.send(:resolve_extension, to_mapping_hash(extension))).to eql({ attributes: extension[:attributes] })
|
1063
|
+
end
|
1064
|
+
end
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
describe ".resolve_attribute_default" do
|
1068
|
+
context "when attribute contain default" do
|
1069
|
+
it "returns the string with default value" do
|
1070
|
+
attribute = to_mapping_hash({ base_class: "ST_Attr1", default: "1" })
|
1071
|
+
expect(described_class.send(:resolve_attribute_default, attribute)).to eql(", default: \"1\"")
|
1072
|
+
end
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
context "when attribute contain no default" do
|
1076
|
+
it "returns the string with nil as default value" do
|
1077
|
+
attribute = to_mapping_hash({ base_class: "ST_Attr1" })
|
1078
|
+
expect(described_class.send(:resolve_attribute_default, attribute)).to eql(", default: nil")
|
1079
|
+
end
|
1080
|
+
end
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
describe ".resolve_attribute_default_value" do
|
1084
|
+
context "when attribute data type is one of the standard classes" do
|
1085
|
+
let(:standard_class_value) do
|
1086
|
+
{
|
1087
|
+
"int" => { input: "1", output: 1 },
|
1088
|
+
"integer" => { input: "12", output: 12 },
|
1089
|
+
"string" => { input: "test_string", output: "test_string" },
|
1090
|
+
"boolean" => { input: "false", output: false },
|
1091
|
+
}
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
described_class::DEFAULT_CLASSES.each do |standard_class|
|
1095
|
+
it "returns the value as the #{standard_class.capitalize} class instance" do
|
1096
|
+
default_value = standard_class_value[standard_class]
|
1097
|
+
expect(described_class.send(:resolve_attribute_default_value, standard_class, default_value[:input])).to eql(default_value[:output])
|
1098
|
+
end
|
1099
|
+
end
|
1100
|
+
end
|
1101
|
+
|
1102
|
+
context "when attribute data type is not one of the standard classes" do
|
1103
|
+
it "returns the string with default value" do
|
1104
|
+
expect(described_class.send(:resolve_attribute_default_value, "BooleanTestClass", "1")).to eql("\"1\"")
|
1105
|
+
end
|
1106
|
+
end
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
describe ".resolve_namespace" do
|
1110
|
+
context "when namespace is given" do
|
1111
|
+
it "returns the string with namespace" do
|
1112
|
+
expect(described_class.send(:resolve_namespace, { namespace: "testNamespace" })).to eql("namespace \"testNamespace\"\n")
|
1113
|
+
end
|
1114
|
+
end
|
1115
|
+
|
1116
|
+
context "when namespace and prefix are given" do
|
1117
|
+
it "returns the string with namespace and prefix" do
|
1118
|
+
expect(described_class.send(:resolve_namespace, { namespace: "testNamespace", prefix: "testPrefix" })).to eql("namespace \"testNamespace\", \"testPrefix\"\n")
|
1119
|
+
end
|
1120
|
+
end
|
1121
|
+
|
1122
|
+
context "when namespace and prefix are not given" do
|
1123
|
+
it "returns the string with nil" do
|
1124
|
+
expect(described_class.send(:resolve_namespace, {})).to be_nil
|
1125
|
+
end
|
1126
|
+
end
|
1127
|
+
end
|
1128
|
+
end
|
1129
|
+
|
1130
|
+
describe "required files list compiler methods" do
|
1131
|
+
describe ".resolve_required_files" do
|
1132
|
+
context "when elements are given" do
|
1133
|
+
before do
|
1134
|
+
described_class.instance_variable_set(:@required_files, [])
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
after do
|
1138
|
+
described_class.instance_variable_set(:@required_files, nil)
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
let(:content) do
|
1142
|
+
{
|
1143
|
+
attribute_groups: {},
|
1144
|
+
complex_content: {},
|
1145
|
+
simple_content: {},
|
1146
|
+
attributes: {},
|
1147
|
+
sequence: {},
|
1148
|
+
choice: {},
|
1149
|
+
group: {},
|
1150
|
+
}
|
1151
|
+
end
|
1152
|
+
|
1153
|
+
it "populates @required_files variable with the names of the required files" do
|
1154
|
+
described_class.send(:resolve_required_files, content)
|
1155
|
+
expect(described_class.instance_variable_get(:@required_files)).to eql([])
|
1156
|
+
end
|
1157
|
+
end
|
1158
|
+
end
|
1159
|
+
|
1160
|
+
describe ".required_files_simple_content" do
|
1161
|
+
context "when elements are given" do
|
1162
|
+
before do
|
1163
|
+
described_class.instance_variable_set(:@required_files, [])
|
1164
|
+
end
|
1165
|
+
|
1166
|
+
after do
|
1167
|
+
described_class.instance_variable_set(:@required_files, nil)
|
1168
|
+
end
|
1169
|
+
|
1170
|
+
let(:content) do
|
1171
|
+
{
|
1172
|
+
extension_base: {},
|
1173
|
+
attributes: {},
|
1174
|
+
extension: {},
|
1175
|
+
restriction: {},
|
1176
|
+
}
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
it "populates @required_files variable with the names of the required files" do
|
1180
|
+
described_class.send(:required_files_simple_content, content)
|
1181
|
+
expect(described_class.instance_variable_get(:@required_files)).to eql([])
|
1182
|
+
end
|
1183
|
+
end
|
1184
|
+
end
|
1185
|
+
|
1186
|
+
describe ".required_files_complex_content" do
|
1187
|
+
context "when elements are given" do
|
1188
|
+
before do
|
1189
|
+
described_class.instance_variable_set(:@required_files, [])
|
1190
|
+
end
|
1191
|
+
|
1192
|
+
after do
|
1193
|
+
described_class.instance_variable_set(:@required_files, nil)
|
1194
|
+
end
|
1195
|
+
|
1196
|
+
let(:content) do
|
1197
|
+
{
|
1198
|
+
extension: {},
|
1199
|
+
restriction: {},
|
1200
|
+
}
|
1201
|
+
end
|
1202
|
+
|
1203
|
+
it "populates @required_files variable with the names of the required files" do
|
1204
|
+
described_class.send(:required_files_complex_content, content)
|
1205
|
+
expect(described_class.instance_variable_get(:@required_files)).to eql([])
|
1206
|
+
end
|
1207
|
+
end
|
1208
|
+
end
|
1209
|
+
|
1210
|
+
describe ".required_files_extension" do
|
1211
|
+
context "when elements are given" do
|
1212
|
+
before do
|
1213
|
+
described_class.instance_variable_set(:@required_files, [])
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
after do
|
1217
|
+
described_class.instance_variable_set(:@required_files, nil)
|
1218
|
+
end
|
1219
|
+
|
1220
|
+
let(:content) do
|
1221
|
+
{
|
1222
|
+
attribute_group: {},
|
1223
|
+
extension_base: {},
|
1224
|
+
attributes: {},
|
1225
|
+
attribute: {},
|
1226
|
+
sequence: {},
|
1227
|
+
choice: {},
|
1228
|
+
}
|
1229
|
+
end
|
1230
|
+
|
1231
|
+
it "populates @required_files variable with the names of the required files" do
|
1232
|
+
described_class.send(:required_files_extension, content)
|
1233
|
+
expect(described_class.instance_variable_get(:@required_files)).to eql([])
|
1234
|
+
end
|
1235
|
+
end
|
1236
|
+
end
|
1237
|
+
|
1238
|
+
describe ".required_files_restriction" do
|
1239
|
+
context "when elements are given" do
|
1240
|
+
before do
|
1241
|
+
described_class.instance_variable_set(:@required_files, [])
|
1242
|
+
end
|
1243
|
+
|
1244
|
+
after do
|
1245
|
+
described_class.instance_variable_set(:@required_files, nil)
|
1246
|
+
end
|
1247
|
+
|
1248
|
+
let(:content) { { base: "testId" } }
|
1249
|
+
|
1250
|
+
it "populates @required_files variable with the names of the required files" do
|
1251
|
+
described_class.send(:required_files_restriction, content)
|
1252
|
+
expect(described_class.instance_variable_get(:@required_files)).to eql(["test_id"])
|
1253
|
+
end
|
1254
|
+
end
|
1255
|
+
end
|
1256
|
+
|
1257
|
+
describe ".required_files_attribute_groups" do
|
1258
|
+
context "when elements are given" do
|
1259
|
+
before do
|
1260
|
+
described_class.instance_variable_set(:@required_files, [])
|
1261
|
+
described_class.instance_variable_set(:@attribute_groups, attribute_groups)
|
1262
|
+
end
|
1263
|
+
|
1264
|
+
after do
|
1265
|
+
described_class.instance_variable_set(:@required_files, nil)
|
1266
|
+
described_class.instance_variable_set(:@attribute_groups, nil)
|
1267
|
+
end
|
1268
|
+
|
1269
|
+
let(:attribute_groups) { { "testId" => {} } }
|
1270
|
+
|
1271
|
+
let(:content) do
|
1272
|
+
{
|
1273
|
+
ref_class: "testId",
|
1274
|
+
attributes: {},
|
1275
|
+
attribute: {},
|
1276
|
+
}
|
1277
|
+
end
|
1278
|
+
|
1279
|
+
it "populates @required_files variable with the names of the required files" do
|
1280
|
+
described_class.send(:required_files_attribute_groups, content)
|
1281
|
+
expect(described_class.instance_variable_get(:@required_files)).to eql([])
|
1282
|
+
end
|
1283
|
+
end
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
describe ".required_files_attribute" do
|
1287
|
+
context "when elements are given" do
|
1288
|
+
before do
|
1289
|
+
described_class.instance_variable_set(:@required_files, [])
|
1290
|
+
described_class.instance_variable_set(:@attributes, attributes)
|
1291
|
+
end
|
1292
|
+
|
1293
|
+
after do
|
1294
|
+
described_class.instance_variable_set(:@required_files, nil)
|
1295
|
+
described_class.instance_variable_set(:@attributes, nil)
|
1296
|
+
end
|
1297
|
+
|
1298
|
+
let(:attributes) do
|
1299
|
+
{
|
1300
|
+
"testRef" => to_mapping_hash({ base_class: "ST_Attr1" }),
|
1301
|
+
}
|
1302
|
+
end
|
1303
|
+
|
1304
|
+
let(:content) do
|
1305
|
+
[
|
1306
|
+
to_mapping_hash({ ref_class: "testRef" }),
|
1307
|
+
to_mapping_hash({ base_class: "ST_Attr2" }),
|
1308
|
+
]
|
1309
|
+
end
|
1310
|
+
|
1311
|
+
it "populates @required_files variable with the names of the required files" do
|
1312
|
+
described_class.send(:required_files_attribute, content)
|
1313
|
+
expect(described_class.instance_variable_get(:@required_files)).to eql(["st_attr1", "st_attr2"])
|
1314
|
+
end
|
1315
|
+
end
|
1316
|
+
end
|
1317
|
+
|
1318
|
+
describe ".required_files_choice" do
|
1319
|
+
context "when elements are given" do
|
1320
|
+
before { described_class.instance_variable_set(:@required_files, []) }
|
1321
|
+
after { described_class.instance_variable_set(:@required_files, nil) }
|
1322
|
+
|
1323
|
+
let(:content) do
|
1324
|
+
{
|
1325
|
+
"testRef" => to_mapping_hash({ type_name: "ST_Attr1" }),
|
1326
|
+
sequence: {},
|
1327
|
+
element: {},
|
1328
|
+
choice: {},
|
1329
|
+
group: {},
|
1330
|
+
}
|
1331
|
+
end
|
1332
|
+
|
1333
|
+
it "populates @required_files variable with the names of the required files" do
|
1334
|
+
described_class.send(:required_files_choice, content)
|
1335
|
+
expect(described_class.instance_variable_get(:@required_files)).to eql(["st_attr1"])
|
1336
|
+
end
|
1337
|
+
end
|
1338
|
+
end
|
1339
|
+
|
1340
|
+
describe ".required_files_group" do
|
1341
|
+
context "when elements are given" do
|
1342
|
+
before do
|
1343
|
+
described_class.instance_variable_set(:@required_files, [])
|
1344
|
+
described_class.instance_variable_set(:@group_types, group_types)
|
1345
|
+
end
|
1346
|
+
|
1347
|
+
after do
|
1348
|
+
described_class.instance_variable_set(:@required_files, nil)
|
1349
|
+
described_class.instance_variable_set(:@group_types, nil)
|
1350
|
+
end
|
1351
|
+
|
1352
|
+
let(:group_types) { { "testRef" => {} } }
|
1353
|
+
let(:content) do
|
1354
|
+
{
|
1355
|
+
ref_class: "testRef",
|
1356
|
+
sequence: {},
|
1357
|
+
choice: {},
|
1358
|
+
}
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
it "populates @required_files variable with the names of the required files" do
|
1362
|
+
described_class.send(:required_files_group, content)
|
1363
|
+
expect(described_class.instance_variable_get(:@required_files)).to eql([])
|
1364
|
+
end
|
1365
|
+
end
|
1366
|
+
end
|
1367
|
+
|
1368
|
+
describe ".required_files_sequence" do
|
1369
|
+
context "when elements are given" do
|
1370
|
+
before do
|
1371
|
+
described_class.instance_variable_set(:@required_files, [])
|
1372
|
+
end
|
1373
|
+
|
1374
|
+
after do
|
1375
|
+
described_class.instance_variable_set(:@required_files, nil)
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
let(:content) do
|
1379
|
+
{
|
1380
|
+
elements: {},
|
1381
|
+
sequence: {},
|
1382
|
+
groups: {},
|
1383
|
+
choice: {},
|
1384
|
+
}
|
1385
|
+
end
|
1386
|
+
|
1387
|
+
it "populates @required_files variable with the names of the required files" do
|
1388
|
+
described_class.send(:required_files_sequence, content)
|
1389
|
+
expect(described_class.instance_variable_get(:@required_files)).to eql([])
|
1390
|
+
end
|
1391
|
+
end
|
1392
|
+
end
|
1393
|
+
|
1394
|
+
describe ".required_files_elements" do
|
1395
|
+
context "when elements are given" do
|
1396
|
+
before do
|
1397
|
+
described_class.instance_variable_set(:@required_files, [])
|
1398
|
+
described_class.instance_variable_set(:@elements, elements)
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
after do
|
1402
|
+
described_class.instance_variable_set(:@required_files, nil)
|
1403
|
+
described_class.instance_variable_set(:@elements, nil)
|
1404
|
+
end
|
1405
|
+
|
1406
|
+
let(:elements) do
|
1407
|
+
{
|
1408
|
+
"CT_Element1" => to_mapping_hash({ type_name: "w:CT_Element1" }),
|
1409
|
+
}
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
let(:content) do
|
1413
|
+
[
|
1414
|
+
to_mapping_hash({ ref_class: "CT_Element1" }),
|
1415
|
+
to_mapping_hash({ type_name: "CT_Element2" }),
|
1416
|
+
]
|
1417
|
+
end
|
1418
|
+
|
1419
|
+
it "populates @required_files variable with the names of the required files" do
|
1420
|
+
described_class.send(:required_files_elements, content)
|
1421
|
+
expect(described_class.instance_variable_get(:@required_files)).to eql(["ct_element1", "ct_element2"])
|
1422
|
+
end
|
1423
|
+
end
|
1424
|
+
end
|
1425
|
+
end
|
1426
|
+
end
|
1427
|
+
|
1428
|
+
def to_mapping_hash(content)
|
1429
|
+
@hash ||= Lutaml::Model::MappingHash.new
|
1430
|
+
@hash.merge(content)
|
1431
|
+
end
|