lutaml-model 0.3.24 → 0.3.26

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +36 -17
  3. data/README.adoc +396 -30
  4. data/lib/lutaml/model/attribute.rb +52 -27
  5. data/lib/lutaml/model/error/pattern_not_matched_error.rb +17 -0
  6. data/lib/lutaml/model/error/type_error.rb +9 -0
  7. data/lib/lutaml/model/error/unknown_type_error.rb +9 -0
  8. data/lib/lutaml/model/error/validation_error.rb +0 -1
  9. data/lib/lutaml/model/error.rb +3 -0
  10. data/lib/lutaml/model/mapping_hash.rb +8 -0
  11. data/lib/lutaml/model/serialize.rb +10 -5
  12. data/lib/lutaml/model/type/boolean.rb +38 -0
  13. data/lib/lutaml/model/type/date.rb +35 -0
  14. data/lib/lutaml/model/type/date_time.rb +32 -4
  15. data/lib/lutaml/model/type/decimal.rb +42 -0
  16. data/lib/lutaml/model/type/float.rb +37 -0
  17. data/lib/lutaml/model/type/hash.rb +62 -0
  18. data/lib/lutaml/model/type/integer.rb +41 -0
  19. data/lib/lutaml/model/type/string.rb +49 -0
  20. data/lib/lutaml/model/type/time.rb +49 -0
  21. data/lib/lutaml/model/type/time_without_date.rb +37 -5
  22. data/lib/lutaml/model/type/value.rb +52 -0
  23. data/lib/lutaml/model/type.rb +50 -114
  24. data/lib/lutaml/model/validation.rb +2 -1
  25. data/lib/lutaml/model/version.rb +1 -1
  26. data/lib/lutaml/model/xml_adapter/builder/nokogiri.rb +12 -3
  27. data/lib/lutaml/model/xml_adapter/builder/ox.rb +7 -1
  28. data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +3 -1
  29. data/lib/lutaml/model/xml_adapter/ox_adapter.rb +12 -8
  30. data/lib/lutaml/model/xml_adapter/xml_document.rb +6 -8
  31. data/lib/lutaml/model/xml_mapping.rb +6 -2
  32. data/lib/lutaml/model/xml_mapping_rule.rb +7 -1
  33. data/lutaml-model.gemspec +1 -1
  34. data/spec/address_spec.rb +170 -0
  35. data/spec/fixtures/address.rb +33 -0
  36. data/spec/fixtures/person.rb +73 -0
  37. data/spec/fixtures/sample_model.rb +40 -0
  38. data/spec/fixtures/vase.rb +38 -0
  39. data/spec/fixtures/xml/special_char.xml +13 -0
  40. data/spec/lutaml/model/attribute_spec.rb +139 -0
  41. data/spec/lutaml/model/cdata_spec.rb +520 -0
  42. data/spec/lutaml/model/collection_spec.rb +299 -0
  43. data/spec/lutaml/model/comparable_model_spec.rb +106 -0
  44. data/spec/lutaml/model/custom_model_spec.rb +410 -0
  45. data/spec/lutaml/model/custom_serialization_spec.rb +170 -0
  46. data/spec/lutaml/model/defaults_spec.rb +221 -0
  47. data/spec/lutaml/model/delegation_spec.rb +340 -0
  48. data/spec/lutaml/model/inheritance_spec.rb +92 -0
  49. data/spec/lutaml/model/json_adapter_spec.rb +37 -0
  50. data/spec/lutaml/model/key_value_mapping_spec.rb +86 -0
  51. data/spec/lutaml/model/map_content_spec.rb +118 -0
  52. data/spec/lutaml/model/mixed_content_spec.rb +625 -0
  53. data/spec/lutaml/model/namespace_spec.rb +57 -0
  54. data/spec/lutaml/model/ordered_content_spec.rb +83 -0
  55. data/spec/lutaml/model/render_nil_spec.rb +138 -0
  56. data/spec/lutaml/model/schema/json_schema_spec.rb +79 -0
  57. data/spec/lutaml/model/schema/relaxng_schema_spec.rb +60 -0
  58. data/spec/lutaml/model/schema/xsd_schema_spec.rb +55 -0
  59. data/spec/lutaml/model/schema/yaml_schema_spec.rb +47 -0
  60. data/spec/lutaml/model/serializable_spec.rb +297 -0
  61. data/spec/lutaml/model/serializable_validation_spec.rb +90 -0
  62. data/spec/lutaml/model/simple_model_spec.rb +314 -0
  63. data/spec/lutaml/model/toml_adapter_spec.rb +39 -0
  64. data/spec/lutaml/model/type/boolean_spec.rb +54 -0
  65. data/spec/lutaml/model/type/date_spec.rb +118 -0
  66. data/spec/lutaml/model/type/date_time_spec.rb +127 -0
  67. data/spec/lutaml/model/type/decimal_spec.rb +125 -0
  68. data/spec/lutaml/model/type/float_spec.rb +191 -0
  69. data/spec/lutaml/model/type/hash_spec.rb +63 -0
  70. data/spec/lutaml/model/type/integer_spec.rb +145 -0
  71. data/spec/lutaml/model/type/string_spec.rb +150 -0
  72. data/spec/lutaml/model/type/time_spec.rb +142 -0
  73. data/spec/lutaml/model/type/time_without_date_spec.rb +125 -0
  74. data/spec/lutaml/model/type_spec.rb +276 -0
  75. data/spec/lutaml/model/utils_spec.rb +79 -0
  76. data/spec/lutaml/model/validation_spec.rb +83 -0
  77. data/spec/lutaml/model/with_child_mapping_spec.rb +174 -0
  78. data/spec/lutaml/model/xml_adapter/nokogiri_adapter_spec.rb +56 -0
  79. data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +56 -0
  80. data/spec/lutaml/model/xml_adapter/ox_adapter_spec.rb +61 -0
  81. data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +251 -0
  82. data/spec/lutaml/model/xml_adapter_spec.rb +178 -0
  83. data/spec/lutaml/model/xml_mapping_spec.rb +863 -0
  84. data/spec/lutaml/model/yaml_adapter_spec.rb +30 -0
  85. data/spec/lutaml/model_spec.rb +1 -0
  86. data/spec/person_spec.rb +161 -0
  87. data/spec/spec_helper.rb +33 -0
  88. metadata +68 -2
@@ -0,0 +1,520 @@
1
+ require "spec_helper"
2
+ require "lutaml/model"
3
+ require "lutaml/model/xml_adapter/nokogiri_adapter"
4
+ require "lutaml/model/xml_adapter/ox_adapter"
5
+
6
+ module CDATA
7
+ class Beta < Lutaml::Model::Serializable
8
+ attribute :element1, :string
9
+
10
+ xml do
11
+ root "beta"
12
+ map_content to: :element1, cdata: true
13
+ end
14
+ end
15
+
16
+ class Alpha < Lutaml::Model::Serializable
17
+ attribute :element1, :string
18
+ attribute :element2, :string
19
+ attribute :element3, :string
20
+ attribute :beta, Beta
21
+
22
+ xml do
23
+ root "alpha"
24
+
25
+ map_element "element1", to: :element1, cdata: false
26
+ map_element "element2", to: :element2, cdata: true
27
+ map_element "element3", to: :element3, cdata: false
28
+ map_element "beta", to: :beta
29
+ end
30
+ end
31
+
32
+ class Address < Lutaml::Model::Serializable
33
+ attribute :street, :string
34
+ attribute :city, :string
35
+ attribute :house, :string
36
+ attribute :address, Address
37
+
38
+ xml do
39
+ root "address"
40
+ map_element "street", to: :street
41
+ map_element "city", with: { from: :city_from_xml, to: :city_to_xml }, cdata: true
42
+ map_element "house", with: { from: :house_from_xml, to: :house_to_xml }, cdata: false
43
+ map_element "address", to: :address
44
+ end
45
+
46
+ def house_from_xml(model, node)
47
+ model.house = node
48
+ end
49
+
50
+ def house_to_xml(model, _parent, doc)
51
+ doc.create_and_add_element("house") do |element|
52
+ element.add_text(element, model.house, cdata: false)
53
+ end
54
+ end
55
+
56
+ def city_from_xml(model, node)
57
+ model.city = node
58
+ end
59
+
60
+ def city_to_xml(model, _parent, doc)
61
+ doc.create_and_add_element("city") do |element|
62
+ element.add_text(element, model.city, cdata: true)
63
+ end
64
+ end
65
+ end
66
+
67
+ class CustomModelChild
68
+ attr_accessor :street, :city
69
+ end
70
+
71
+ class CustomModelParent
72
+ attr_accessor :first_name, :middle_name, :last_name, :child_mapper
73
+
74
+ def name
75
+ "#{first_name} #{last_name}"
76
+ end
77
+ end
78
+
79
+ class CustomModelChildMapper < Lutaml::Model::Serializable
80
+ model CustomModelChild
81
+
82
+ attribute :street, Lutaml::Model::Type::String
83
+ attribute :city, Lutaml::Model::Type::String
84
+
85
+ xml do
86
+ map_element :street, to: :street, cdata: true
87
+ map_element :city, to: :city, cdata: true
88
+ end
89
+ end
90
+
91
+ class CustomModelParentMapper < Lutaml::Model::Serializable
92
+ model CustomModelParent
93
+
94
+ attribute :first_name, Lutaml::Model::Type::String
95
+ attribute :middle_name, Lutaml::Model::Type::String
96
+ attribute :last_name, Lutaml::Model::Type::String
97
+ attribute :child_mapper, CustomModelChildMapper
98
+
99
+ xml do
100
+ root "CustomModelParent"
101
+ map_element :first_name, to: :first_name, cdata: true
102
+ map_element :middle_name, to: :middle_name, cdata: true
103
+ map_element :last_name, to: :last_name, cdata: false
104
+ map_element :CustomModelChild, with: { to: :child_to_xml, from: :child_from_xml }, cdata: true
105
+ end
106
+
107
+ def child_to_xml(model, _parent, doc)
108
+ doc.create_and_add_element("CustomModelChild") do |child_el|
109
+ child_el.create_and_add_element("street") do |street_el|
110
+ street_el.add_text(street_el, model.child_mapper.street, cdata: true)
111
+ end
112
+ child_el.create_and_add_element("city") do |city_el|
113
+ city_el.add_text(city_el, model.child_mapper.city, cdata: true)
114
+ end
115
+ end
116
+ end
117
+
118
+ def child_from_xml(model, value)
119
+ model.child_mapper ||= CustomModelChild.new
120
+
121
+ model.child_mapper.street = value["street"].text
122
+ model.child_mapper.city = value["city"].text
123
+ end
124
+ end
125
+
126
+ class RootMixedContent < Lutaml::Model::Serializable
127
+ attribute :id, :string
128
+ attribute :bold, :string, collection: true
129
+ attribute :italic, :string, collection: true
130
+ attribute :underline, :string
131
+ attribute :content, :string
132
+
133
+ xml do
134
+ root "RootMixedContent", mixed: true
135
+ map_attribute :id, to: :id
136
+ map_element :bold, to: :bold, cdata: true
137
+ map_element :italic, to: :italic, cdata: true
138
+ map_element :underline, to: :underline, cdata: true
139
+ map_content to: :content, cdata: true
140
+ end
141
+ end
142
+
143
+ class RootMixedContentNested < Lutaml::Model::Serializable
144
+ attribute :id, :string
145
+ attribute :data, :string
146
+ attribute :content, RootMixedContent
147
+ attribute :sup, :string, collection: true
148
+ attribute :sub, :string, collection: true
149
+
150
+ xml do
151
+ root "RootMixedContentNested", mixed: true
152
+ map_content to: :data, cdata: true
153
+ map_attribute :id, to: :id
154
+ map_element :sup, to: :sup, cdata: true
155
+ map_element :sub, to: :sub, cdata: false
156
+ map_element "MixedContent", to: :content
157
+ end
158
+ end
159
+
160
+ class DefaultValue < Lutaml::Model::Serializable
161
+ attribute :name, :string, default: -> { "Default Value" }
162
+ attribute :temperature, :integer, default: -> { 1050 }
163
+ attribute :opacity, :string, default: -> { "Opaque" }
164
+ attribute :content, :string, default: -> { " " }
165
+
166
+ xml do
167
+ root "DefaultValue"
168
+ map_element "name", to: :name, render_default: true, cdata: true
169
+ map_element "temperature", to: :temperature, render_default: true, cdata: true
170
+ map_element "opacity", to: :opacity, cdata: false, render_default: true
171
+ map_content to: :content, cdata: true, render_default: true
172
+ end
173
+ end
174
+ end
175
+
176
+ RSpec.describe "CDATA" do
177
+ let(:parent_mapper) { CDATA::CustomModelParentMapper }
178
+ let(:child_mapper) { CDATA::CustomModelChildMapper }
179
+ let(:parent_model) { CDATA::CustomModelParent }
180
+ let(:child_model) { CDATA::CustomModelChild }
181
+
182
+ shared_examples "cdata behavior" do |adapter_class|
183
+ around do |example|
184
+ old_adapter = Lutaml::Model::Config.xml_adapter
185
+ Lutaml::Model::Config.xml_adapter = adapter_class
186
+ example.run
187
+ ensure
188
+ Lutaml::Model::Config.xml_adapter = old_adapter
189
+ end
190
+
191
+ context "with CDATA option" do
192
+ let(:xml) do
193
+ <<~XML.strip
194
+ <alpha>
195
+ <element1><![CDATA[foo]]></element1>
196
+ <element2><![CDATA[one]]></element2>
197
+ <element2><![CDATA[two]]></element2>
198
+ <element2><![CDATA[three]]></element2>
199
+ <element3>bar</element3>
200
+ <beta><![CDATA[child]]></beta>
201
+ </alpha>
202
+ XML
203
+ end
204
+
205
+ let(:expected_xml) do
206
+ <<~XML.strip
207
+ <alpha>
208
+ <element1>foo</element1>
209
+ <element2>
210
+ <![CDATA[one]]>
211
+ </element2>
212
+ <element2>
213
+ <![CDATA[two]]>
214
+ </element2>
215
+ <element2>
216
+ <![CDATA[three]]>
217
+ </element2>
218
+ <element3>bar</element3>
219
+ <beta>
220
+ <![CDATA[child]]>
221
+ </beta>
222
+ </alpha>
223
+ XML
224
+ end
225
+
226
+ it "maps xml to object" do
227
+ instance = CDATA::Alpha.from_xml(xml)
228
+
229
+ expect(instance.element1).to eq("foo")
230
+ expect(instance.element2).to eq(%w[one two three])
231
+ expect(instance.element3).to eq("bar")
232
+ expect(instance.beta.element1).to eq("child")
233
+ end
234
+
235
+ it "converts objects to xml" do
236
+ instance = CDATA::Alpha.new(
237
+ element1: "foo",
238
+ element2: %w[one two three],
239
+ element3: "bar",
240
+ beta: CDATA::Beta.new(element1: "child"),
241
+ )
242
+
243
+ expect(instance.to_xml).to be_equivalent_to(expected_xml)
244
+ end
245
+ end
246
+
247
+ context "with custom methods" do
248
+ let(:xml) do
249
+ <<~XML
250
+ <address>
251
+ <street>A</street>
252
+ <city><![CDATA[B]]></city>
253
+ <house><![CDATA[H]]></house>
254
+ <address>
255
+ <street>C</street>
256
+ <city><![CDATA[D]]></city>
257
+ <house><![CDATA[G]]></house>
258
+ </address>
259
+ </address>
260
+ XML
261
+ end
262
+
263
+ let(:expected_xml) do
264
+ <<~XML
265
+ <address>
266
+ <street>A</street>
267
+ <city>
268
+ <![CDATA[B]]>
269
+ </city>
270
+ <house>H</house>
271
+ <address>
272
+ <street>C</street>
273
+ <city>
274
+ <![CDATA[D]]>
275
+ </city>
276
+ <house>G</house>
277
+ </address>
278
+ </address>
279
+ XML
280
+ end
281
+
282
+ it "round-trips XML" do
283
+ model = CDATA::Address.from_xml(xml)
284
+ expect(model.to_xml).to be_equivalent_to(expected_xml)
285
+ end
286
+ end
287
+
288
+ context "with custom models" do
289
+ let(:input_xml) do
290
+ <<~XML
291
+ <CustomModelParent>
292
+ <first_name><![CDATA[John]]></first_name>
293
+ <last_name><![CDATA[Doe]]></last_name>
294
+ <CustomModelChild>
295
+ <street><![CDATA[Oxford Street]]></street>
296
+ <city><![CDATA[London]]></city>
297
+ </CustomModelChild>
298
+ </CustomModelParent>
299
+ XML
300
+ end
301
+
302
+ let(:expected_nokogiri_xml) do
303
+ <<~XML
304
+ <CustomModelParent>
305
+ <first_name><![CDATA[John]]></first_name>
306
+ <last_name>Doe</last_name>
307
+ <CustomModelChild>
308
+ <street><![CDATA[Oxford Street]]></street>
309
+ <city><![CDATA[London]]></city>
310
+ </CustomModelChild>
311
+ </CustomModelParent>
312
+ XML
313
+ end
314
+
315
+ let(:expected_ox_xml) do
316
+ <<~XML
317
+ <CustomModelParent>
318
+ <first_name>
319
+ <![CDATA[John]]>
320
+ </first_name>
321
+ <last_name>Doe</last_name>
322
+ <CustomModelChild>
323
+ <street>
324
+ <![CDATA[Oxford Street]]>
325
+ </street>
326
+ <city>
327
+ <![CDATA[London]]>
328
+ </city>
329
+ </CustomModelChild>
330
+ </CustomModelParent>
331
+ XML
332
+ end
333
+
334
+ describe ".from_xml" do
335
+ it "maps XML content to custom model using custom methods" do
336
+ instance = parent_mapper.from_xml(input_xml)
337
+
338
+ expect(instance.class).to eq(parent_model)
339
+ expect(instance.first_name).to eq("John")
340
+ expect(instance.last_name).to eq("Doe")
341
+ expect(instance.name).to eq("John Doe")
342
+
343
+ expect(instance.child_mapper.class).to eq(child_model)
344
+ expect(instance.child_mapper.street).to eq("Oxford Street")
345
+ expect(instance.child_mapper.city).to eq("London")
346
+ end
347
+ end
348
+
349
+ describe ".to_xml" do
350
+ it "with correct model converts objects to xml using custom methods" do
351
+ instance = parent_mapper.from_xml(input_xml)
352
+ result_xml = parent_mapper.to_xml(instance)
353
+
354
+ expected_output = adapter_class == Lutaml::Model::XmlAdapter::OxAdapter ? expected_ox_xml : expected_nokogiri_xml
355
+
356
+ expect(result_xml.strip).to eq(expected_output.strip)
357
+ end
358
+ end
359
+ end
360
+
361
+ context "when mixed: true is set for nested content" do
362
+ let(:xml) do
363
+ <<~XML
364
+ <RootMixedContentNested id="outer123">
365
+ <![CDATA[The following text is about the Moon.]]>
366
+ <MixedContent id="inner456">
367
+ <![CDATA[The Earth's Moon rings like a ]]>
368
+ <bold><![CDATA[bell]]></bold>
369
+ <![CDATA[ when struck by meteroids. Distanced from the Earth by ]]>
370
+ <italic><![CDATA[384,400 km]]></italic>,
371
+ <![CDATA[ ,its surface is covered in ]]>
372
+ <underline><![CDATA[craters]]></underline>.
373
+ <![CDATA[ .Ain't that ]]>
374
+ <bold><![CDATA[cool]]></bold>
375
+ <![CDATA[ ? ]]>
376
+ </MixedContent>
377
+ <sup><![CDATA[1]]></sup>: <![CDATA[The Moon is not a planet.]]>
378
+ <sup><![CDATA[2]]></sup>: <![CDATA[The Moon's atmosphere is mainly composed of helium in the form of He]]><sub><![CDATA[2]]></sub>.
379
+ </RootMixedContentNested>
380
+ XML
381
+ end
382
+
383
+ expected_xml = "<RootMixedContentNested id=\"outer123\"><![CDATA[The following text is about the Moon.]]><MixedContent id=\"inner456\"><![CDATA[The Earth's Moon rings like a ]]><bold><![CDATA[bell]]></bold><![CDATA[ when struck by meteroids. Distanced from the Earth by ]]><italic><![CDATA[384,400 km]]></italic><![CDATA[ ,its surface is covered in ]]><underline><![CDATA[craters]]></underline><![CDATA[ .Ain't that ]]><bold><![CDATA[cool]]></bold><![CDATA[ ? ]]></MixedContent><sup><![CDATA[1]]></sup><![CDATA[The Moon is not a planet.]]><sup><![CDATA[2]]></sup><![CDATA[The Moon's atmosphere is mainly composed of helium in the form of He]]><sub>2</sub></RootMixedContentNested>"
384
+
385
+ expected_ox_xml = <<~XML
386
+ <RootMixedContentNested id="outer123">
387
+ <![CDATA[The following text is about the Moon.]]>
388
+ <MixedContent id="inner456">
389
+ <![CDATA[The Earth's Moon rings like a ]]>
390
+ <bold>
391
+ <![CDATA[bell]]>
392
+ </bold>
393
+ <![CDATA[ when struck by meteroids. Distanced from the Earth by ]]>
394
+ <italic>
395
+ <![CDATA[384,400 km]]>
396
+ </italic>
397
+ <![CDATA[ ,its surface is covered in ]]>
398
+ <underline>
399
+ <![CDATA[craters]]>
400
+ </underline>
401
+ <![CDATA[ .Ain't that ]]>
402
+ <bold>
403
+ <![CDATA[cool]]>
404
+ </bold>
405
+ <![CDATA[ ? ]]>
406
+ </MixedContent>
407
+ <sup>
408
+ <![CDATA[1]]>
409
+ </sup>
410
+ <![CDATA[The Moon is not a planet.]]>
411
+ <sup>
412
+ <![CDATA[2]]>
413
+ </sup>
414
+ <![CDATA[The Moon's atmosphere is mainly composed of helium in the form of He]]>
415
+ <sub>2</sub>
416
+ </RootMixedContentNested>
417
+ XML
418
+
419
+ it "deserializes and serializes mixed content correctly" do
420
+ parsed = CDATA::RootMixedContentNested.from_xml(xml)
421
+
422
+ expected_content = [
423
+ "The Earth's Moon rings like a ",
424
+ " when struck by meteroids. Distanced from the Earth by ",
425
+ " ,its surface is covered in ",
426
+ " .Ain't that ",
427
+ " ? ",
428
+ ]
429
+
430
+ expect(parsed.id).to eq("outer123")
431
+ expect(parsed.sup).to eq(["1", "2"])
432
+ expect(parsed.sub).to eq(["2"])
433
+ expect(parsed.content.id).to eq("inner456")
434
+ expect(parsed.content.bold).to eq(["bell", "cool"])
435
+ expect(parsed.content.italic).to eq(["384,400 km"])
436
+ expect(parsed.content.underline).to eq("craters")
437
+
438
+ parsed.content.content.each_with_index do |content, index|
439
+ expected_output = expected_content[index]
440
+
441
+ # due to the difference in capturing
442
+ # newlines in ox and nokogiri adapters
443
+ if adapter_class == Lutaml::Model::XmlAdapter::OxAdapter
444
+ expected_xml = expected_ox_xml
445
+ end
446
+
447
+ expect(content).to eq(expected_output)
448
+ end
449
+
450
+ serialized = parsed.to_xml
451
+ expect(serialized).to eq(expected_xml)
452
+ end
453
+ end
454
+
455
+ context "when defualt: true is set for attributes default values" do
456
+ let(:xml) do
457
+ <<~XML
458
+ <DefaultValue>
459
+ <![CDATA[The following text is about the Moon]]>
460
+ <temperature>
461
+ <![CDATA[500]]>
462
+ </temperature>
463
+ <![CDATA[The Moon's atmosphere is mainly composed of helium in the form]]>
464
+ </DefaultValue>
465
+ XML
466
+ end
467
+
468
+ expected_xml = "<DefaultValue><name><![CDATA[Default Value]]></name><temperature><![CDATA[500]]></temperature><opacity>Opaque</opacity><![CDATA[The following text is about the MoonThe Moon's atmosphere is mainly composed of helium in the form]]></DefaultValue>"
469
+
470
+ expected_ox_xml = <<~XML
471
+ <DefaultValue>
472
+ <name>
473
+ <![CDATA[Default Value]]>
474
+ </name>
475
+ <temperature>
476
+ <![CDATA[500]]>
477
+ </temperature>
478
+ <opacity>Opaque</opacity>
479
+ <![CDATA[The following text is about the MoonThe Moon's atmosphere is mainly composed of helium in the form]]>
480
+ </DefaultValue>
481
+ XML
482
+
483
+ it "deserializes and serializes mixed content correctly" do
484
+ parsed = CDATA::DefaultValue.from_xml(xml)
485
+
486
+ expected_content = [
487
+ "The following text is about the Moon",
488
+ "The Moon's atmosphere is mainly composed of helium in the form",
489
+ ]
490
+
491
+ expect(parsed.name).to eq("Default Value")
492
+ expect(parsed.opacity).to eq("Opaque")
493
+ expect(parsed.temperature).to eq(500)
494
+
495
+ parsed.content.each_with_index do |content, index|
496
+ expected_output = expected_content[index]
497
+
498
+ # due to the difference in capturing
499
+ # newlines in ox and nokogiri adapters
500
+ if adapter_class == Lutaml::Model::XmlAdapter::OxAdapter
501
+ expected_xml = expected_ox_xml
502
+ end
503
+
504
+ expect(content).to eq(expected_output)
505
+ end
506
+
507
+ serialized = parsed.to_xml
508
+ expect(serialized).to eq(expected_xml)
509
+ end
510
+ end
511
+ end
512
+
513
+ describe Lutaml::Model::XmlAdapter::NokogiriAdapter do
514
+ it_behaves_like "cdata behavior", described_class
515
+ end
516
+
517
+ describe Lutaml::Model::XmlAdapter::OxAdapter do
518
+ it_behaves_like "cdata behavior", described_class
519
+ end
520
+ end