lutaml-model 0.6.7 → 0.7.1
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-repos-todo.json +7 -0
- data/.github/workflows/dependent-repos.json +17 -9
- data/.rubocop_todo.yml +18 -33
- data/README.adoc +4380 -2557
- data/lib/lutaml/model/attribute.rb +94 -15
- data/lib/lutaml/model/choice.rb +7 -0
- data/lib/lutaml/model/comparable_model.rb +48 -9
- data/lib/lutaml/model/error/collection_count_out_of_range_error.rb +1 -1
- data/lib/lutaml/model/error/polymorphic_error.rb +9 -0
- data/lib/lutaml/model/error.rb +1 -0
- data/lib/lutaml/model/mapping/json_mapping.rb +17 -0
- data/lib/lutaml/model/{key_value_mapping.rb → mapping/key_value_mapping.rb} +58 -14
- data/lib/lutaml/model/{key_value_mapping_rule.rb → mapping/key_value_mapping_rule.rb} +18 -2
- data/lib/lutaml/model/mapping/mapping_rule.rb +299 -0
- data/lib/lutaml/model/mapping/toml_mapping.rb +25 -0
- data/lib/lutaml/model/{xml_mapping.rb → mapping/xml_mapping.rb} +97 -15
- data/lib/lutaml/model/{xml_mapping_rule.rb → mapping/xml_mapping_rule.rb} +20 -3
- data/lib/lutaml/model/mapping/yaml_mapping.rb +17 -0
- data/lib/lutaml/model/mapping.rb +14 -0
- data/lib/lutaml/model/schema/xml_compiler.rb +15 -15
- data/lib/lutaml/model/sequence.rb +2 -2
- data/lib/lutaml/model/serialize.rb +247 -97
- data/lib/lutaml/model/type/date.rb +1 -1
- data/lib/lutaml/model/type/date_time.rb +2 -2
- data/lib/lutaml/model/type/hash.rb +1 -1
- data/lib/lutaml/model/type/time.rb +2 -2
- data/lib/lutaml/model/type/time_without_date.rb +2 -2
- data/lib/lutaml/model/uninitialized_class.rb +64 -0
- data/lib/lutaml/model/utils.rb +14 -0
- data/lib/lutaml/model/validation.rb +1 -0
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +1 -1
- data/lib/lutaml/model/xml_adapter/oga_adapter.rb +1 -1
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +1 -1
- data/lib/lutaml/model/xml_adapter/xml_document.rb +38 -17
- data/lib/lutaml/model/xml_adapter/xml_element.rb +17 -7
- data/lib/lutaml/model.rb +1 -0
- data/spec/benchmarks/xml_parsing_benchmark_spec.rb +3 -3
- data/spec/fixtures/person.rb +5 -5
- data/spec/lutaml/model/attribute_spec.rb +37 -1
- data/spec/lutaml/model/cdata_spec.rb +2 -2
- data/spec/lutaml/model/collection_spec.rb +50 -2
- data/spec/lutaml/model/comparable_model_spec.rb +92 -27
- data/spec/lutaml/model/defaults_spec.rb +1 -1
- data/spec/lutaml/model/enum_spec.rb +1 -1
- data/spec/lutaml/model/group_spec.rb +316 -14
- data/spec/lutaml/model/key_value_mapping_spec.rb +41 -3
- data/spec/lutaml/model/polymorphic_spec.rb +348 -0
- data/spec/lutaml/model/render_empty_spec.rb +194 -0
- data/spec/lutaml/model/render_nil_spec.rb +206 -22
- data/spec/lutaml/model/simple_model_spec.rb +9 -9
- data/spec/lutaml/model/value_map_spec.rb +240 -0
- data/spec/lutaml/model/xml/namespace/nested_with_explicit_namespace_spec.rb +85 -0
- data/spec/lutaml/model/xml/xml_element_spec.rb +93 -0
- data/spec/lutaml/model/xml_mapping_rule_spec.rb +102 -2
- data/spec/lutaml/model/xml_mapping_spec.rb +45 -3
- data/spec/sample_model_spec.rb +3 -3
- metadata +20 -8
- data/lib/lutaml/model/mapping_rule.rb +0 -109
@@ -21,35 +21,80 @@ class RenderNil < Lutaml::Model::Serializable
|
|
21
21
|
attribute :render_nil_nested, RenderNilNested
|
22
22
|
|
23
23
|
json do
|
24
|
-
map "name", to: :name, render_nil: true
|
25
|
-
map "clay_type", to: :clay_type, render_nil: true
|
26
|
-
map "glaze", to: :glaze, render_nil: true
|
27
|
-
map "dimensions", to: :dimensions,
|
24
|
+
map "name", to: :name, render_nil: true, render_empty: true
|
25
|
+
map "clay_type", to: :clay_type, render_nil: true, render_empty: true
|
26
|
+
map "glaze", to: :glaze, render_nil: true, render_empty: true
|
27
|
+
map "dimensions", to: :dimensions, render_empty: false
|
28
28
|
end
|
29
29
|
|
30
30
|
xml do
|
31
31
|
root "render_nil"
|
32
|
-
map_element "name", to: :name, render_nil: true
|
33
|
-
map_element "clay_type", to: :clay_type, render_nil: false
|
34
|
-
map_element "glaze", to: :glaze, render_nil: true
|
32
|
+
map_element "name", to: :name, render_nil: true, render_empty: true
|
33
|
+
map_element "clay_type", to: :clay_type, render_nil: false, render_empty: true
|
34
|
+
map_element "glaze", to: :glaze, render_nil: true, render_empty: true
|
35
35
|
map_element "render_nil_nested", to: :render_nil_nested, render_nil: true,
|
36
36
|
render_default: true
|
37
|
-
map_element "dimensions", to: :dimensions,
|
37
|
+
map_element "dimensions", to: :dimensions, render_empty: false
|
38
38
|
end
|
39
39
|
|
40
40
|
yaml do
|
41
|
-
map "name", to: :name, render_nil: true
|
42
|
-
map "clay_type", to: :clay_type, render_nil: false
|
43
|
-
map "glaze", to: :glaze, render_nil: true
|
44
|
-
map "dimensions", to: :dimensions,
|
41
|
+
map "name", to: :name, render_nil: true, render_empty: true
|
42
|
+
map "clay_type", to: :clay_type, render_nil: false, render_empty: true
|
43
|
+
map "glaze", to: :glaze, render_nil: true, render_empty: true
|
44
|
+
map "dimensions", to: :dimensions, render_empty: false
|
45
45
|
map "render_nil_nested", to: :render_nil_nested, render_nil: false
|
46
46
|
end
|
47
47
|
|
48
48
|
toml do
|
49
|
-
map "name", to: :name, render_nil: true
|
50
|
-
map "clay_type", to: :clay_type, render_nil: false
|
51
|
-
map "glaze", to: :glaze, render_nil: true
|
52
|
-
map "dimensions", to: :dimensions,
|
49
|
+
map "name", to: :name, render_nil: :empty, render_empty: true
|
50
|
+
map "clay_type", to: :clay_type, render_nil: false, render_empty: true
|
51
|
+
map "glaze", to: :glaze, render_nil: false, render_empty: true
|
52
|
+
map "dimensions", to: :dimensions, render_empty: false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
module RenderNilSpec
|
57
|
+
class OmitNilModel < Lutaml::Model::Serializable
|
58
|
+
attribute :items, :string, collection: true
|
59
|
+
|
60
|
+
xml do
|
61
|
+
root "omit-nil-model"
|
62
|
+
map_element "items", to: :items, render_nil: :omit
|
63
|
+
end
|
64
|
+
|
65
|
+
key_value do
|
66
|
+
map "items", to: :items, render_nil: :omit
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class ExplicitNilModel < Lutaml::Model::Serializable
|
71
|
+
attribute :items, :string, collection: true
|
72
|
+
|
73
|
+
xml do
|
74
|
+
root "explicit-nil-model"
|
75
|
+
map_element "items", to: :items, render_nil: :as_nil
|
76
|
+
end
|
77
|
+
|
78
|
+
yaml do
|
79
|
+
map "items", to: :items, render_nil: :as_nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class AsBlankNilModel < Lutaml::Model::Serializable
|
84
|
+
attribute :items, :string, collection: true
|
85
|
+
|
86
|
+
xml do
|
87
|
+
root "omit-nil-model"
|
88
|
+
map_element "items", to: :items, render_nil: :as_blank
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class AsEmptyNilModel < Lutaml::Model::Serializable
|
93
|
+
attribute :items, :string, collection: true
|
94
|
+
|
95
|
+
yaml do
|
96
|
+
map "items", to: :items, render_nil: :as_empty
|
97
|
+
end
|
53
98
|
end
|
54
99
|
end
|
55
100
|
|
@@ -82,14 +127,14 @@ RSpec.describe RenderNil do
|
|
82
127
|
expect(pottery.name).to be_nil
|
83
128
|
expect(pottery.clay_type).to be_nil
|
84
129
|
expect(pottery.glaze).to be_nil
|
85
|
-
expect(pottery.dimensions).to
|
130
|
+
expect(pottery.dimensions).to be_nil
|
86
131
|
end
|
87
132
|
|
88
133
|
it "serializes to XML with render_nil option" do
|
89
134
|
expected_xml = <<~XML
|
90
135
|
<render_nil>
|
91
|
-
<name/>
|
92
|
-
<glaze/>
|
136
|
+
<name xsi:nil="true"/>
|
137
|
+
<glaze xsi:nil="true"/>
|
93
138
|
<render_nil_nested/>
|
94
139
|
</render_nil>
|
95
140
|
XML
|
@@ -100,8 +145,8 @@ RSpec.describe RenderNil do
|
|
100
145
|
it "deserializes from XML with render_nil option" do
|
101
146
|
xml = <<~XML
|
102
147
|
<render_nil>
|
103
|
-
<name/>
|
104
|
-
<glaze/>
|
148
|
+
<name xsi:nil="true" />
|
149
|
+
<glaze xsi:nil="true" />
|
105
150
|
</render_nil>
|
106
151
|
XML
|
107
152
|
|
@@ -148,7 +193,7 @@ RSpec.describe RenderNil do
|
|
148
193
|
}
|
149
194
|
end
|
150
195
|
|
151
|
-
it "does not
|
196
|
+
it "does not treat empty string as nil" do
|
152
197
|
expected_yaml = <<~YAML
|
153
198
|
---
|
154
199
|
name: ''
|
@@ -165,4 +210,143 @@ RSpec.describe RenderNil do
|
|
165
210
|
expect(generated_yaml).to eq(expected_yaml.strip)
|
166
211
|
end
|
167
212
|
end
|
213
|
+
|
214
|
+
describe "render_nil option" do
|
215
|
+
context "when :omit" do
|
216
|
+
let(:model) { RenderNilSpec::OmitNilModel.new(items: nil) }
|
217
|
+
|
218
|
+
describe "YAML" do
|
219
|
+
let(:parsed) do
|
220
|
+
RenderNilSpec::OmitNilModel.from_yaml(yaml)
|
221
|
+
end
|
222
|
+
|
223
|
+
let(:yaml) do
|
224
|
+
<<~YAML
|
225
|
+
---
|
226
|
+
items:
|
227
|
+
YAML
|
228
|
+
end
|
229
|
+
|
230
|
+
it "omits nil collections while deserialize" do
|
231
|
+
expect(model.items).to be_nil
|
232
|
+
end
|
233
|
+
|
234
|
+
it "omits nil collections" do
|
235
|
+
expect(parsed.to_yaml.strip).to eq("--- {}")
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe "XML" do
|
240
|
+
let(:parsed) { RenderNilSpec::OmitNilModel.from_xml(xml) }
|
241
|
+
|
242
|
+
let(:xml) do
|
243
|
+
<<~XML
|
244
|
+
<omit-nil-model/>
|
245
|
+
XML
|
246
|
+
end
|
247
|
+
|
248
|
+
it "omits nil collection" do
|
249
|
+
expect(model.to_xml).not_to include("<items")
|
250
|
+
end
|
251
|
+
|
252
|
+
it "omits nil collections while deserialize" do
|
253
|
+
expect(parsed.items).to be_nil
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
context "when :as_nil" do
|
259
|
+
let(:model) { RenderNilSpec::ExplicitNilModel.new(items: nil) }
|
260
|
+
|
261
|
+
describe "YAML" do
|
262
|
+
let(:yaml) do
|
263
|
+
<<~YAML
|
264
|
+
---
|
265
|
+
items:
|
266
|
+
YAML
|
267
|
+
end
|
268
|
+
|
269
|
+
let(:parsed) do
|
270
|
+
RenderNilSpec::ExplicitNilModel.from_yaml(yaml)
|
271
|
+
end
|
272
|
+
|
273
|
+
it "renders explicit nil" do
|
274
|
+
expect(model.to_yaml).to include("items:")
|
275
|
+
end
|
276
|
+
|
277
|
+
it "sets nil values while deserialize" do
|
278
|
+
expect(parsed.items).to be_nil
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
describe "XML" do
|
283
|
+
let(:xml) do
|
284
|
+
<<~XML
|
285
|
+
<explicit-nil-model>
|
286
|
+
<items xsi:nil="true"/>
|
287
|
+
</explicit-nil-model>
|
288
|
+
XML
|
289
|
+
end
|
290
|
+
|
291
|
+
let(:parsed) do
|
292
|
+
RenderNilSpec::ExplicitNilModel.from_xml(xml)
|
293
|
+
end
|
294
|
+
|
295
|
+
it "renders explicit nil" do
|
296
|
+
expect(model.to_xml).to include('<items xsi:nil="true"/>')
|
297
|
+
end
|
298
|
+
|
299
|
+
it "sets nil values while deserialize" do
|
300
|
+
expect(parsed.items).to be_nil
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
context "when :as_blank" do
|
306
|
+
let(:model) { RenderNilSpec::AsBlankNilModel.new(items: nil) }
|
307
|
+
|
308
|
+
let(:parsed) do
|
309
|
+
RenderNilSpec::AsBlankNilModel.from_xml(xml)
|
310
|
+
end
|
311
|
+
|
312
|
+
let(:xml) do
|
313
|
+
<<~XML
|
314
|
+
<explicit-nil-model>
|
315
|
+
<items/>
|
316
|
+
</explicit-nil-model>
|
317
|
+
XML
|
318
|
+
end
|
319
|
+
|
320
|
+
it "creates blank element from nil collections" do
|
321
|
+
expect(model.to_xml).to include("<items/>")
|
322
|
+
end
|
323
|
+
|
324
|
+
it "sets blank values while deserialize" do
|
325
|
+
expect(parsed.items).to eq([])
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
context "when :as_empty" do
|
330
|
+
let(:model) { RenderNilSpec::AsEmptyNilModel.new(items: nil) }
|
331
|
+
|
332
|
+
let(:parsed) do
|
333
|
+
RenderNilSpec::AsEmptyNilModel.from_yaml(yaml)
|
334
|
+
end
|
335
|
+
|
336
|
+
let(:yaml) do
|
337
|
+
<<~YAML
|
338
|
+
---
|
339
|
+
items:
|
340
|
+
YAML
|
341
|
+
end
|
342
|
+
|
343
|
+
it "creates key and empty collection" do
|
344
|
+
expect(model.to_yaml).to include("items: []")
|
345
|
+
end
|
346
|
+
|
347
|
+
it "sets nil value while deserialize" do
|
348
|
+
expect(parsed.items).to be_nil
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
168
352
|
end
|
@@ -62,26 +62,26 @@ module SimpleModel
|
|
62
62
|
xml do
|
63
63
|
root "building"
|
64
64
|
map_attribute "name", to: :name
|
65
|
-
map_element "address", to: :address
|
66
|
-
map_element "room", to: :rooms
|
65
|
+
map_element "address", to: :address, treat_omitted: :omited
|
66
|
+
map_element "room", to: :rooms, treat_omitted: :omited
|
67
67
|
end
|
68
68
|
|
69
69
|
yaml do
|
70
70
|
map "name", to: :name
|
71
|
-
map "address", to: :address
|
72
|
-
map "rooms", to: :rooms
|
71
|
+
map "address", to: :address, treat_omitted: :omited
|
72
|
+
map "rooms", to: :rooms, treat_omitted: :omited
|
73
73
|
end
|
74
74
|
|
75
75
|
json do
|
76
76
|
map "name", to: :name
|
77
|
-
map "address", to: :address
|
78
|
-
map "rooms", to: :rooms
|
77
|
+
map "address", to: :address, treat_omitted: :omited
|
78
|
+
map "rooms", to: :rooms, treat_omitted: :omited
|
79
79
|
end
|
80
80
|
|
81
81
|
toml do
|
82
82
|
map "name", to: :name
|
83
|
-
map "address", to: :address
|
84
|
-
map "rooms", to: :rooms
|
83
|
+
map "address", to: :address, treat_omitted: :omited
|
84
|
+
map "rooms", to: :rooms, treat_omitted: :omited
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|
@@ -182,7 +182,7 @@ RSpec.describe SimpleModel do
|
|
182
182
|
default_model = SimpleModel::Building.new
|
183
183
|
expect(default_model.name).to eq("Unnamed building")
|
184
184
|
expect(default_model.address).to be_nil
|
185
|
-
expect(default_model.rooms).to
|
185
|
+
expect(default_model.rooms).to be_nil
|
186
186
|
end
|
187
187
|
|
188
188
|
it "serializes to XML" do
|
@@ -0,0 +1,240 @@
|
|
1
|
+
# map :x, to: :y, value_map: {
|
2
|
+
# from_xml: {omitted: :omitted, xsi_nil: nil, empty: [] },
|
3
|
+
# to_xml: {omitted: :omitted, nil: :nil, empty: :empty}
|
4
|
+
# }
|
5
|
+
|
6
|
+
module ValueMapSpec
|
7
|
+
class WithValueMaps < Lutaml::Model::Serializable
|
8
|
+
attribute :omitted_as_omitted, :string
|
9
|
+
attribute :omitted_as_nil, :string
|
10
|
+
attribute :omitted_as_empty, :string
|
11
|
+
|
12
|
+
attribute :nil_as_nil, :string
|
13
|
+
attribute :nil_as_omitted, :string
|
14
|
+
attribute :nil_as_empty, :string
|
15
|
+
|
16
|
+
attribute :empty_as_empty, :string
|
17
|
+
attribute :empty_as_nil, :string
|
18
|
+
attribute :empty_as_omitted, :string
|
19
|
+
|
20
|
+
xml do
|
21
|
+
root "WithValueMaps"
|
22
|
+
|
23
|
+
map_element "omittedAsOmitted", to: :omitted_as_omitted, value_map: {
|
24
|
+
from: { omitted: :omitted },
|
25
|
+
to: { omitted: :omitted },
|
26
|
+
}
|
27
|
+
map_element "omittedAsNil", to: :omitted_as_nil, value_map: {
|
28
|
+
from: { omitted: :nil },
|
29
|
+
to: { omitted: :nil },
|
30
|
+
}
|
31
|
+
map_element "omittedAsEmpty", to: :omitted_as_empty, value_map: {
|
32
|
+
from: { omitted: :empty },
|
33
|
+
to: { omitted: :empty },
|
34
|
+
}
|
35
|
+
|
36
|
+
map_element "nilAsNil", to: :nil_as_nil, value_map: {
|
37
|
+
from: { nil: :nil },
|
38
|
+
to: { nil: :nil },
|
39
|
+
}
|
40
|
+
map_element "nilAsOmitted", to: :nil_as_omitted, value_map: {
|
41
|
+
from: { nil: :omitted },
|
42
|
+
to: { nil: :omitted },
|
43
|
+
}
|
44
|
+
map_element "nilAsEmpty", to: :nil_as_empty, value_map: {
|
45
|
+
from: { nil: :empty },
|
46
|
+
to: { nil: :empty },
|
47
|
+
}
|
48
|
+
|
49
|
+
map_element "emptyAsEmpty", to: :empty_as_empty, value_map: {
|
50
|
+
from: { empty: :empty },
|
51
|
+
to: { empty: :empty },
|
52
|
+
}
|
53
|
+
map_element "emptyAsNil", to: :empty_as_nil, value_map: {
|
54
|
+
from: { empty: :nil },
|
55
|
+
to: { empty: :nil },
|
56
|
+
}
|
57
|
+
map_element "emptyAsOmitted", to: :empty_as_omitted, value_map: {
|
58
|
+
from: { empty: :omitted },
|
59
|
+
to: { empty: :omitted },
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
key_value do
|
64
|
+
map "omitted_as_omitted", to: :omitted_as_omitted, value_map: {
|
65
|
+
from: { omitted: :omitted },
|
66
|
+
to: { omitted: :omitted },
|
67
|
+
}
|
68
|
+
map "omitted_as_nil", to: :omitted_as_nil, value_map: {
|
69
|
+
from: { omitted: :omitted },
|
70
|
+
to: { omitted: :nil },
|
71
|
+
}
|
72
|
+
map "omitted_as_empty", to: :omitted_as_empty, value_map: {
|
73
|
+
from: { omitted: :omitted },
|
74
|
+
to: { omitted: :empty },
|
75
|
+
}
|
76
|
+
|
77
|
+
map "nil_as_nil", to: :nil_as_nil, value_map: {
|
78
|
+
from: { nil: :nil },
|
79
|
+
to: { nil: :nil },
|
80
|
+
}
|
81
|
+
map "nil_as_omitted", to: :nil_as_omitted, value_map: {
|
82
|
+
from: { nil: :nil },
|
83
|
+
to: { nil: :omitted },
|
84
|
+
}
|
85
|
+
map "nil_as_empty", to: :nil_as_empty, value_map: {
|
86
|
+
from: { nil: :nil },
|
87
|
+
to: { nil: :empty },
|
88
|
+
}
|
89
|
+
|
90
|
+
map "empty_as_empty", to: :empty_as_empty, value_map: {
|
91
|
+
from: { empty: :empty },
|
92
|
+
to: { empty: :empty },
|
93
|
+
}
|
94
|
+
map "empty_as_nil", to: :empty_as_nil, value_map: {
|
95
|
+
from: { empty: :empty },
|
96
|
+
to: { empty: :nil },
|
97
|
+
}
|
98
|
+
map "empty_as_omitted", to: :empty_as_omitted, value_map: {
|
99
|
+
from: { empty: :empty },
|
100
|
+
to: { empty: :omitted },
|
101
|
+
}
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
RSpec.describe "ValueMap" do
|
107
|
+
describe "YAML" do
|
108
|
+
let(:model) do
|
109
|
+
uninitialized = Lutaml::Model::UninitializedClass.instance
|
110
|
+
|
111
|
+
ValueMapSpec::WithValueMaps.new(
|
112
|
+
omitted_as_omitted: uninitialized,
|
113
|
+
omitted_as_nil: uninitialized,
|
114
|
+
omitted_as_empty: uninitialized,
|
115
|
+
nil_as_nil: nil,
|
116
|
+
nil_as_omitted: nil,
|
117
|
+
nil_as_empty: nil,
|
118
|
+
empty_as_empty: "",
|
119
|
+
empty_as_nil: "",
|
120
|
+
empty_as_omitted: "",
|
121
|
+
)
|
122
|
+
end
|
123
|
+
|
124
|
+
let(:parsed) { ValueMapSpec::WithValueMaps.from_yaml(yaml) }
|
125
|
+
|
126
|
+
let(:expected_yaml) do
|
127
|
+
<<~YAML
|
128
|
+
---
|
129
|
+
omitted_as_nil:
|
130
|
+
omitted_as_empty: ''
|
131
|
+
nil_as_nil:
|
132
|
+
nil_as_empty: ''
|
133
|
+
empty_as_empty: ''
|
134
|
+
empty_as_nil:
|
135
|
+
YAML
|
136
|
+
end
|
137
|
+
|
138
|
+
let(:yaml) do
|
139
|
+
<<~YAML
|
140
|
+
---
|
141
|
+
nil_as_nil:
|
142
|
+
nil_as_omitted:
|
143
|
+
nil_as_empty:
|
144
|
+
empty_as_empty: ''
|
145
|
+
empty_as_nil: ''
|
146
|
+
empty_as_omitted: ''
|
147
|
+
YAML
|
148
|
+
end
|
149
|
+
|
150
|
+
it "serializes correctly" do
|
151
|
+
expect(parsed.to_yaml).to eq(expected_yaml)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "deserializes correctly" do
|
155
|
+
expected = ValueMapSpec::WithValueMaps.new(
|
156
|
+
{
|
157
|
+
nil_as_nil: nil,
|
158
|
+
nil_as_omitted: nil,
|
159
|
+
nil_as_empty: nil,
|
160
|
+
empty_as_empty: "",
|
161
|
+
empty_as_nil: "",
|
162
|
+
empty_as_omitted: "",
|
163
|
+
},
|
164
|
+
{ omitted: :omitted },
|
165
|
+
)
|
166
|
+
|
167
|
+
expect(parsed).to eq(expected)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "XML" do
|
172
|
+
context "when serializing" do
|
173
|
+
let(:model) do
|
174
|
+
ValueMapSpec::WithValueMaps.new(
|
175
|
+
{
|
176
|
+
nil_as_nil: nil,
|
177
|
+
nil_as_omitted: nil,
|
178
|
+
nil_as_empty: nil,
|
179
|
+
empty_as_empty: "",
|
180
|
+
empty_as_nil: "",
|
181
|
+
empty_as_omitted: "",
|
182
|
+
},
|
183
|
+
{ omitted: :omitted },
|
184
|
+
)
|
185
|
+
end
|
186
|
+
|
187
|
+
let(:expected_xml) do
|
188
|
+
<<~XML.strip
|
189
|
+
<WithValueMaps>
|
190
|
+
<omittedAsNil xsi:nil="true"/>
|
191
|
+
<omittedAsEmpty/>
|
192
|
+
<nilAsNil xsi:nil="true"/>
|
193
|
+
<nilAsEmpty/>
|
194
|
+
<emptyAsEmpty/>
|
195
|
+
<emptyAsNil xsi:nil="true"/>
|
196
|
+
</WithValueMaps>
|
197
|
+
XML
|
198
|
+
end
|
199
|
+
|
200
|
+
it "sets correct values when serializing" do
|
201
|
+
expect(model.to_xml).to eq(expected_xml)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
context "when deserializing" do
|
206
|
+
let(:xml) do
|
207
|
+
<<~XML
|
208
|
+
<WithValueMaps>
|
209
|
+
<nilAsNil xsi:nil="true" />
|
210
|
+
<nilAsOmitted xsi:nil="true" />
|
211
|
+
<nilAsEmpty xsi:nil="true" />
|
212
|
+
<emptyAsEmpty/>
|
213
|
+
<emptyAsNil/>
|
214
|
+
<emptyAsOmitted/>
|
215
|
+
</WithValueMaps>
|
216
|
+
XML
|
217
|
+
end
|
218
|
+
|
219
|
+
let(:parsed) { ValueMapSpec::WithValueMaps.from_xml(xml) }
|
220
|
+
|
221
|
+
let(:expected) do
|
222
|
+
ValueMapSpec::WithValueMaps.new(
|
223
|
+
{
|
224
|
+
nil_as_nil: nil,
|
225
|
+
nil_as_empty: "",
|
226
|
+
empty_as_empty: "",
|
227
|
+
empty_as_nil: nil,
|
228
|
+
omitted_as_nil: nil,
|
229
|
+
omitted_as_empty: "",
|
230
|
+
},
|
231
|
+
{ omitted: :omitted },
|
232
|
+
)
|
233
|
+
end
|
234
|
+
|
235
|
+
it "sets correct values when deserializing" do
|
236
|
+
expect(parsed).to eq(expected)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# <Base xmlns:test="https://test-namespace">
|
2
|
+
# <test:Element1>
|
3
|
+
# <test:Element>Value</test:Element>
|
4
|
+
# <ElementWithoutNamespace>
|
5
|
+
# <NestedElementWithoutNamespace>
|
6
|
+
# Value for nested element without namespace
|
7
|
+
# </NestedElementWithoutNamespace>
|
8
|
+
# </ElementWithoutNamespace>
|
9
|
+
# </test:Element1>
|
10
|
+
# </Base>
|
11
|
+
|
12
|
+
module NestedWithExplicitNamespaceSpec
|
13
|
+
class NestedElementWithoutNamespace < Lutaml::Model::Serializable
|
14
|
+
attribute :nested_element_without_namespace, :string
|
15
|
+
|
16
|
+
xml do
|
17
|
+
map_element "NestedElementWithoutNamespace",
|
18
|
+
to: :nested_element_without_namespace
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class ElementWithoutNamespace < Lutaml::Model::Serializable
|
23
|
+
attribute :nested_element_without_namespace, :string
|
24
|
+
|
25
|
+
xml do
|
26
|
+
map_element "NestedElementWithoutNamespace",
|
27
|
+
to: :nested_element_without_namespace
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Element1 < Lutaml::Model::Serializable
|
32
|
+
attribute :element, :string
|
33
|
+
attribute :element_without_namespace, ElementWithoutNamespace
|
34
|
+
|
35
|
+
xml do
|
36
|
+
map_element "Element", to: :element
|
37
|
+
map_element "ElementWithoutNamespace", to: :element_without_namespace,
|
38
|
+
namespace: nil,
|
39
|
+
prefix: nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Base < Lutaml::Model::Serializable
|
44
|
+
attribute :element1, Element1
|
45
|
+
|
46
|
+
xml do
|
47
|
+
root "Base"
|
48
|
+
namespace "https://test-namespace", "test"
|
49
|
+
|
50
|
+
map_element "Element1", to: :element1
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
RSpec.describe "NestedWithExplicitNamespace" do
|
56
|
+
let(:xml) do
|
57
|
+
<<~XML
|
58
|
+
<Base xmlns:test="https://test-namespace">
|
59
|
+
<test:Element1>
|
60
|
+
<test:Element>Value</test:Element>
|
61
|
+
<ElementWithoutNamespace>
|
62
|
+
<NestedElementWithoutNamespace>
|
63
|
+
Value for nested element without namespace
|
64
|
+
</NestedElementWithoutNamespace>
|
65
|
+
</ElementWithoutNamespace>
|
66
|
+
</test:Element1>
|
67
|
+
</Base>
|
68
|
+
XML
|
69
|
+
end
|
70
|
+
|
71
|
+
let(:parsed) { NestedWithExplicitNamespaceSpec::Base.from_xml(xml) }
|
72
|
+
|
73
|
+
it "parses namespaced element correctly" do
|
74
|
+
expect(parsed.element1.element).to eq("Value")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "parses nested element without namespace correclty" do
|
78
|
+
generated_value = parsed.element1
|
79
|
+
.element_without_namespace
|
80
|
+
.nested_element_without_namespace
|
81
|
+
.strip
|
82
|
+
|
83
|
+
expect(generated_value).to eq("Value for nested element without namespace")
|
84
|
+
end
|
85
|
+
end
|