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
data/lib/lutaml/model/schema.rb
CHANGED
@@ -2,6 +2,7 @@ require_relative "schema/json_schema"
|
|
2
2
|
require_relative "schema/xsd_schema"
|
3
3
|
require_relative "schema/relaxng_schema"
|
4
4
|
require_relative "schema/yaml_schema"
|
5
|
+
require_relative "schema/xml_compiler"
|
5
6
|
|
6
7
|
module Lutaml
|
7
8
|
module Model
|
@@ -21,6 +22,10 @@ module Lutaml
|
|
21
22
|
def self.to_yaml(klass, options = {})
|
22
23
|
YamlSchema.generate(klass, options)
|
23
24
|
end
|
25
|
+
|
26
|
+
def self.from_xml(xml, options = {})
|
27
|
+
XmlCompiler.to_models(xml, options)
|
28
|
+
end
|
24
29
|
end
|
25
30
|
end
|
26
31
|
end
|
@@ -269,17 +269,22 @@ module Lutaml
|
|
269
269
|
|
270
270
|
value = instance.send(name)
|
271
271
|
|
272
|
+
if rule.raw_mapping?
|
273
|
+
adapter = Lutaml::Model::Config.send(:"#{format}_adapter")
|
274
|
+
return adapter.parse(value, options)
|
275
|
+
end
|
276
|
+
|
272
277
|
attribute = attributes[name]
|
273
278
|
|
274
|
-
next hash.merge!(generate_hash_from_child_mappings(value, format, rule.root_mappings)) if rule.root_mapping?
|
279
|
+
next hash.merge!(generate_hash_from_child_mappings(attribute, value, format, rule.root_mappings)) if rule.root_mapping?
|
275
280
|
|
276
281
|
value = if rule.child_mappings
|
277
|
-
generate_hash_from_child_mappings(value, format, rule.child_mappings)
|
282
|
+
generate_hash_from_child_mappings(attribute, value, format, rule.child_mappings)
|
278
283
|
else
|
279
284
|
attribute.serialize(value, format, options)
|
280
285
|
end
|
281
286
|
|
282
|
-
next
|
287
|
+
next unless rule.render?(value)
|
283
288
|
|
284
289
|
rule_from_name = rule.multiple_mappings? ? rule.from.first.to_s : rule.from.to_s
|
285
290
|
hash[rule_from_name] = value
|
@@ -346,7 +351,7 @@ module Lutaml
|
|
346
351
|
end
|
347
352
|
end
|
348
353
|
|
349
|
-
def generate_hash_from_child_mappings(value, format, child_mappings)
|
354
|
+
def generate_hash_from_child_mappings(attr, value, format, child_mappings)
|
350
355
|
return value unless child_mappings
|
351
356
|
|
352
357
|
hash = {}
|
@@ -365,7 +370,11 @@ module Lutaml
|
|
365
370
|
value.each do |child_obj|
|
366
371
|
map_key = nil
|
367
372
|
map_value = {}
|
373
|
+
mapping_rules = attr.type.mappings_for(format)
|
374
|
+
|
368
375
|
child_mappings.each do |attr_name, path|
|
376
|
+
mapping_rule = mapping_rules.find_by_to(attr_name)
|
377
|
+
|
369
378
|
attr_value = child_obj.send(attr_name)
|
370
379
|
|
371
380
|
attr_value = if attr_value.is_a?(Lutaml::Model::Serialize)
|
@@ -376,7 +385,7 @@ module Lutaml
|
|
376
385
|
attr_value
|
377
386
|
end
|
378
387
|
|
379
|
-
next
|
388
|
+
next unless mapping_rule&.render?(attr_value)
|
380
389
|
|
381
390
|
if path == :key
|
382
391
|
map_key = attr_value
|
@@ -446,11 +455,11 @@ module Lutaml
|
|
446
455
|
instance.mixed = mappings_for(:xml).mixed_content? || options[:mixed_content]
|
447
456
|
end
|
448
457
|
|
449
|
-
if doc["__schema_location"
|
458
|
+
if doc["attributes"]&.key?("__schema_location")
|
450
459
|
instance.schema_location = Lutaml::Model::SchemaLocation.new(
|
451
|
-
schema_location: doc["__schema_location"][:schema_location],
|
452
|
-
prefix: doc["__schema_location"][:prefix],
|
453
|
-
namespace: doc["__schema_location"][:namespace],
|
460
|
+
schema_location: doc["attributes"]["__schema_location"][:schema_location],
|
461
|
+
prefix: doc["attributes"]["__schema_location"][:prefix],
|
462
|
+
namespace: doc["attributes"]["__schema_location"][:namespace],
|
454
463
|
)
|
455
464
|
end
|
456
465
|
|
@@ -461,18 +470,17 @@ module Lutaml
|
|
461
470
|
|
462
471
|
attr = attribute_for_rule(rule)
|
463
472
|
|
464
|
-
namespaced_names = rule.namespaced_names(options[:default_namespace])
|
465
|
-
|
466
473
|
value = if rule.raw_mapping?
|
467
474
|
doc.node.inner_xml
|
468
475
|
elsif rule.content_mapping?
|
469
476
|
doc[rule.content_key]
|
470
|
-
elsif
|
471
|
-
|
477
|
+
elsif val = value_for_rule(doc, rule, options)
|
478
|
+
val
|
472
479
|
else
|
473
480
|
defaults_used << rule.to
|
474
481
|
attr&.default || rule.to_value_for(instance)
|
475
482
|
end
|
483
|
+
|
476
484
|
value = normalize_xml_value(value, rule, attr, options)
|
477
485
|
rule.deserialize(instance, value, attributes, self)
|
478
486
|
end
|
@@ -484,6 +492,15 @@ module Lutaml
|
|
484
492
|
instance
|
485
493
|
end
|
486
494
|
|
495
|
+
def value_for_rule(doc, rule, options)
|
496
|
+
rule_names = rule.namespaced_names(options[:default_namespace])
|
497
|
+
hash = rule.attribute? ? doc["attributes"] : doc["elements"]
|
498
|
+
return unless hash
|
499
|
+
|
500
|
+
value_key = rule_names.find { |name| hash.key_exist?(name) }
|
501
|
+
hash.fetch(value_key) if value_key
|
502
|
+
end
|
503
|
+
|
487
504
|
def apply_hash_mapping(doc, instance, format, options = {})
|
488
505
|
mappings = options[:mappings] || mappings_for(format).mappings
|
489
506
|
mappings.each do |rule|
|
@@ -496,6 +513,9 @@ module Lutaml
|
|
496
513
|
value = names.collect do |rule_name|
|
497
514
|
if rule.root_mapping?
|
498
515
|
doc
|
516
|
+
elsif rule.raw_mapping?
|
517
|
+
adapter = Lutaml::Model::Config.public_send(:"#{format}_adapter")
|
518
|
+
adapter.new(doc).public_send(:"to_#{format}")
|
499
519
|
elsif doc.key?(rule_name.to_s)
|
500
520
|
doc[rule_name.to_s]
|
501
521
|
elsif doc.key?(rule_name.to_sym)
|
@@ -19,18 +19,18 @@ module Lutaml
|
|
19
19
|
|
20
20
|
hash = hash.to_h if hash.is_a?(Lutaml::Model::MappingHash)
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
hash.transform_values do |value|
|
25
|
-
if value.is_a?(::Hash)
|
26
|
-
# Only process if value is a Hash
|
27
|
-
nested = normalize_hash(value)
|
28
|
-
# Only include non-text nodes in nested hashes if it's a hash
|
29
|
-
nested.is_a?(::Hash) ? nested.except("text") : nested
|
30
|
-
else
|
31
|
-
value
|
32
|
-
end
|
22
|
+
normalized_hash = hash.transform_values do |value|
|
23
|
+
normalize_value(value)
|
33
24
|
end
|
25
|
+
|
26
|
+
normalized_hash["elements"] || normalized_hash
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.normalize_value(value)
|
30
|
+
return value unless value.is_a?(::Hash)
|
31
|
+
|
32
|
+
nested = normalize_hash(value)
|
33
|
+
nested.is_a?(::Hash) ? nested.except("text") : nested
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.serialize(value)
|
data/lib/lutaml/model/utils.rb
CHANGED
@@ -42,6 +42,13 @@ module Lutaml
|
|
42
42
|
value.respond_to?(:empty?) ? value.empty? : value.nil?
|
43
43
|
end
|
44
44
|
|
45
|
+
def empty_collection?(collection)
|
46
|
+
return false if collection.nil?
|
47
|
+
return false unless [Array, Hash].include?(collection.class)
|
48
|
+
|
49
|
+
collection.empty?
|
50
|
+
end
|
51
|
+
|
45
52
|
def add_method_if_not_defined(klass, method_name, &block)
|
46
53
|
unless klass.method_defined?(method_name)
|
47
54
|
klass.class_eval do
|
data/lib/lutaml/model/version.rb
CHANGED
@@ -124,7 +124,11 @@ module Lutaml
|
|
124
124
|
end
|
125
125
|
|
126
126
|
attributes = {}
|
127
|
-
|
127
|
+
|
128
|
+
# Using `attribute_nodes` instead of `attributes` because
|
129
|
+
# `attribute_nodes` handles name collisions as well
|
130
|
+
# More info: https://devdocs.io/nokogiri/nokogiri/xml/node#method-i-attributes
|
131
|
+
node.attribute_nodes.each do |attr|
|
128
132
|
name = if attr.namespace
|
129
133
|
"#{attr.namespace.prefix}:#{attr.name}"
|
130
134
|
else
|
@@ -77,26 +77,21 @@ module Lutaml
|
|
77
77
|
result.node = element
|
78
78
|
result.item_order = element.order
|
79
79
|
|
80
|
-
element.children.
|
80
|
+
element.children.each do |child|
|
81
81
|
if klass&.<= Serialize
|
82
82
|
attr = klass.attribute_for_child(child.name,
|
83
83
|
format)
|
84
84
|
end
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
hash[child.namespaced_name] = if hash[child.namespaced_name]
|
93
|
-
[hash[child.namespaced_name], value].flatten
|
94
|
-
else
|
95
|
-
value
|
96
|
-
end
|
86
|
+
next result.assign_or_append_value(child.name, child.text) if child.text?
|
87
|
+
|
88
|
+
result["elements"] ||= Lutaml::Model::MappingHash.new
|
89
|
+
result["elements"].assign_or_append_value(child.namespaced_name, parse_element(child, attr&.type || klass, format))
|
97
90
|
end
|
98
91
|
|
99
|
-
result
|
92
|
+
result["attributes"] = attributes_hash(element) if element.attributes&.any?
|
93
|
+
|
94
|
+
result
|
100
95
|
end
|
101
96
|
|
102
97
|
def attributes_hash(element)
|
@@ -167,8 +162,9 @@ module Lutaml
|
|
167
162
|
def add_value(xml, value, attribute, cdata: false)
|
168
163
|
if !value.nil?
|
169
164
|
serialized_value = attribute.type.serialize(value)
|
170
|
-
|
171
|
-
|
165
|
+
if attribute.raw?
|
166
|
+
xml.add_xml_fragment(xml, value)
|
167
|
+
elsif attribute.type == Lutaml::Model::Type::Hash
|
172
168
|
serialized_value.each do |key, val|
|
173
169
|
xml.create_and_add_element(key) do |element|
|
174
170
|
element.text(val)
|
@@ -149,10 +149,10 @@ module Lutaml
|
|
149
149
|
prefix: (prefix_set = false
|
150
150
|
nil)
|
151
151
|
)
|
152
|
-
validate!(
|
152
|
+
validate!(Constants::RAW_MAPPING_KEY, to, with, type: TYPES[:all_content])
|
153
153
|
|
154
154
|
rule = XmlMappingRule.new(
|
155
|
-
|
155
|
+
Constants::RAW_MAPPING_KEY,
|
156
156
|
to: to,
|
157
157
|
render_nil: render_nil,
|
158
158
|
render_default: render_default,
|
@@ -168,6 +168,8 @@ module Lutaml
|
|
168
168
|
@raw_mapping = rule
|
169
169
|
end
|
170
170
|
|
171
|
+
alias map_all_content map_all
|
172
|
+
|
171
173
|
def validate!(key, to, with, type: nil)
|
172
174
|
validate_mappings!(type)
|
173
175
|
|
@@ -59,10 +59,6 @@ module Lutaml
|
|
59
59
|
name.nil?
|
60
60
|
end
|
61
61
|
|
62
|
-
def raw_mapping?
|
63
|
-
name == "__raw_mapping"
|
64
|
-
end
|
65
|
-
|
66
62
|
def content_key
|
67
63
|
cdata ? "#cdata-section" : "text"
|
68
64
|
end
|
@@ -111,6 +107,7 @@ module Lutaml
|
|
111
107
|
prefix: prefix.dup,
|
112
108
|
mixed_content: mixed_content,
|
113
109
|
namespace_set: namespace_set?,
|
110
|
+
attribute: attribute,
|
114
111
|
prefix_set: prefix_set?,
|
115
112
|
default_namespace: default_namespace.dup,
|
116
113
|
)
|
data/lib/lutaml/model.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
<schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.openxmlformats.org/officeDocument/2006/math">
|
2
|
+
<xs:simpleType name="StringDatatype">
|
3
|
+
<xs:annotation>
|
4
|
+
<xs:documentation>
|
5
|
+
A string data type to be used for the example.
|
6
|
+
</xs:documentation>
|
7
|
+
</xs:annotation>
|
8
|
+
<xs:restriction base="xs:string"></xs:restriction>
|
9
|
+
</xs:simpleType>
|
10
|
+
|
11
|
+
<xs:simpleType name="IPV4AddressDatatype">
|
12
|
+
<xs:annotation>
|
13
|
+
<xs:documentation>
|
14
|
+
An Internet Protocol version 4 address represented using dotted-quad syntax as defined in section 3.2 of RFC2673.
|
15
|
+
</xs:documentation>
|
16
|
+
</xs:annotation>
|
17
|
+
<xs:restriction base="StringDatatype">
|
18
|
+
<xs:pattern value="((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]).){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])" />
|
19
|
+
</xs:restriction>
|
20
|
+
</xs:simpleType>
|
21
|
+
|
22
|
+
<xs:simpleType name="whiteSpaces">
|
23
|
+
<xs:annotation>
|
24
|
+
<xs:documentation>
|
25
|
+
A non-empty string of Unicode characters with leading and trailing whitespace
|
26
|
+
disallowed. Whitespace is: U+9, U+10, U+32 or [ \n\t]+
|
27
|
+
</xs:documentation>
|
28
|
+
</xs:annotation>
|
29
|
+
<xs:restriction base="xs:string">
|
30
|
+
<xs:annotation>
|
31
|
+
<xs:documentation>
|
32
|
+
The 'string' datatype restricts the XSD type by prohibiting leading
|
33
|
+
and trailing whitespace, and something (not only whitespace) is required.
|
34
|
+
</xs:documentation>
|
35
|
+
</xs:annotation>
|
36
|
+
<xs:pattern value="\S(.*\S)?">
|
37
|
+
<xs:annotation>
|
38
|
+
<xs:documentation>
|
39
|
+
This pattern ensures that leading and trailing whitespace is
|
40
|
+
disallowed. This helps to even the user experience between implementations
|
41
|
+
related to whitespace.
|
42
|
+
</xs:documentation>
|
43
|
+
</xs:annotation>
|
44
|
+
</xs:pattern>
|
45
|
+
</xs:restriction>
|
46
|
+
</xs:simpleType>
|
47
|
+
|
48
|
+
<xs:complexType name="MathDocument">
|
49
|
+
<xs:choice>
|
50
|
+
<xs:element name="Title" type="whiteSpaces"/>
|
51
|
+
<xs:element name="IPV4Address" type="IPV4AddressDatatype"/>
|
52
|
+
</xs:choice>
|
53
|
+
</xs:complexType>
|
54
|
+
|
55
|
+
<xs:element name="MathDocument" type="MathDocument"/>
|
56
|
+
</schema>
|
@@ -0,0 +1,53 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified" blockDefault="#all" targetNamespace="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
|
3
|
+
<xsd:simpleType name="ST_Integer255">
|
4
|
+
<xsd:annotation>
|
5
|
+
<xsd:documentation>Integer value (1 to 255)</xsd:documentation>
|
6
|
+
</xsd:annotation>
|
7
|
+
<xsd:restriction base="xsd:integer">
|
8
|
+
<xsd:minInclusive value="1" />
|
9
|
+
<xsd:maxInclusive value="255" />
|
10
|
+
</xsd:restriction>
|
11
|
+
</xsd:simpleType>
|
12
|
+
<xsd:complexType name="CT_Integer255">
|
13
|
+
<xsd:attribute name="val" type="ST_Integer255" use="required">
|
14
|
+
<xsd:annotation>
|
15
|
+
<xsd:documentation>Value</xsd:documentation>
|
16
|
+
</xsd:annotation>
|
17
|
+
</xsd:attribute>
|
18
|
+
</xsd:complexType>
|
19
|
+
<xsd:simpleType name="ST_Integer2">
|
20
|
+
<xsd:annotation>
|
21
|
+
<xsd:documentation>Integer value (-2 to 2)</xsd:documentation>
|
22
|
+
</xsd:annotation>
|
23
|
+
<xsd:restriction base="xsd:integer">
|
24
|
+
<xsd:minInclusive value="-2" />
|
25
|
+
<xsd:maxInclusive value="2" />
|
26
|
+
</xsd:restriction>
|
27
|
+
</xsd:simpleType>
|
28
|
+
<xsd:complexType name="CT_Integer2">
|
29
|
+
<xsd:attribute name="val" type="ST_Integer2" use="required">
|
30
|
+
<xsd:annotation>
|
31
|
+
<xsd:documentation>Value</xsd:documentation>
|
32
|
+
</xsd:annotation>
|
33
|
+
</xsd:attribute>
|
34
|
+
</xsd:complexType>
|
35
|
+
<xsd:element name="MathTest" type="CT_Integer255">
|
36
|
+
<xsd:annotation>
|
37
|
+
<xsd:documentation>Main Test class</xsd:documentation>
|
38
|
+
</xsd:annotation>
|
39
|
+
</xsd:element>
|
40
|
+
<xsd:element name="MathTest1" type="CT_Integer2">
|
41
|
+
<xsd:annotation>
|
42
|
+
<xsd:documentation>Main Test class</xsd:documentation>
|
43
|
+
</xsd:annotation>
|
44
|
+
</xsd:element>
|
45
|
+
<xsd:complexType name="CT_MathTest">
|
46
|
+
<xsd:group>
|
47
|
+
<xsd:sequence>
|
48
|
+
<xsd:element ref="MathTest" />
|
49
|
+
<xsd:element ref="MathTest1" />
|
50
|
+
</xsd:sequence>
|
51
|
+
</xsd:group>
|
52
|
+
</xsd:complexType>
|
53
|
+
</xsd:schema>
|
@@ -118,8 +118,8 @@ module CDATA
|
|
118
118
|
def child_from_xml(model, value)
|
119
119
|
model.child_mapper ||= CustomModelChild.new
|
120
120
|
|
121
|
-
model.child_mapper.street = value["street"].text
|
122
|
-
model.child_mapper.city = value["city"].text
|
121
|
+
model.child_mapper.street = value["elements"]["street"].text
|
122
|
+
model.child_mapper.city = value["elements"]["city"].text
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
@@ -56,8 +56,8 @@ class CustomModelParentMapper < Lutaml::Model::Serializable
|
|
56
56
|
def child_from_xml(model, value)
|
57
57
|
model.child_mapper ||= CustomModelChild.new
|
58
58
|
|
59
|
-
model.child_mapper.street = value["street"].text
|
60
|
-
model.child_mapper.city = value["city"].text
|
59
|
+
model.child_mapper.street = value["elements"]["street"].text
|
60
|
+
model.child_mapper.city = value["elements"]["city"].text
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -126,10 +126,10 @@ module CustomModelSpecs
|
|
126
126
|
|
127
127
|
def bibdata_from_xml(model, value)
|
128
128
|
model.bibdata = BibliographicItem.new(
|
129
|
-
"type" => value["type"],
|
130
|
-
"title" => value["title"],
|
131
|
-
"language" => value["title"]["language"],
|
132
|
-
"schema_version" => value["schema-version"],
|
129
|
+
"type" => value["attributes"]["type"],
|
130
|
+
"title" => value["elements"]["title"],
|
131
|
+
"language" => value["elements"]["title"]["attributes"]["language"],
|
132
|
+
"schema_version" => value["attributes"]["schema-version"],
|
133
133
|
)
|
134
134
|
end
|
135
135
|
|
@@ -410,22 +410,9 @@ RSpec.describe "CustomModel" do
|
|
410
410
|
</MixedWithNestedContent>
|
411
411
|
XML
|
412
412
|
|
413
|
-
expected_xml = <<~XML
|
414
|
-
<MixedWithNestedContent>
|
415
|
-
<street>
|
416
|
-
A <p>b</p> B <p>c</p> C
|
417
|
-
</street>
|
418
|
-
<bibdata type="collection" schema-version="v1.2.8">
|
419
|
-
<title language="en">
|
420
|
-
JCGM Collection 1
|
421
|
-
</title>
|
422
|
-
</bibdata>
|
423
|
-
</MixedWithNestedContent>
|
424
|
-
XML
|
425
|
-
|
426
413
|
bibdata = CustomModelSpecs::MixedWithNestedContent.from_xml(xml)
|
427
414
|
|
428
|
-
expect(bibdata.to_xml).to be_equivalent_to(
|
415
|
+
expect(bibdata.to_xml).to be_equivalent_to(xml)
|
429
416
|
end
|
430
417
|
end
|
431
418
|
end
|
@@ -83,4 +83,31 @@ RSpec.describe Lutaml::Model::KeyValueMapping do
|
|
83
83
|
expect(m.custom_methods.object_id).not_to eq(dup_m.custom_methods.object_id)
|
84
84
|
end
|
85
85
|
end
|
86
|
+
|
87
|
+
context "with map_all option" do
|
88
|
+
before do
|
89
|
+
mapping.map_all(
|
90
|
+
render_nil: true,
|
91
|
+
delegate: :container,
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "handles JSON mapping" do
|
96
|
+
expect(mapping.mappings[0].render_nil).to be true
|
97
|
+
expect(mapping.mappings[0].delegate).to eq(:container)
|
98
|
+
expect(mapping.mappings[0].raw_mapping?).to be true
|
99
|
+
end
|
100
|
+
|
101
|
+
it "handles YAML mapping" do
|
102
|
+
expect(mapping.mappings[0].render_nil).to be true
|
103
|
+
expect(mapping.mappings[0].delegate).to eq(:container)
|
104
|
+
expect(mapping.mappings[0].raw_mapping?).to be true
|
105
|
+
end
|
106
|
+
|
107
|
+
it "handles TOML mapping" do
|
108
|
+
expect(mapping.mappings[0].render_nil).to be true
|
109
|
+
expect(mapping.mappings[0].delegate).to eq(:container)
|
110
|
+
expect(mapping.mappings[0].raw_mapping?).to be true
|
111
|
+
end
|
112
|
+
end
|
86
113
|
end
|