lutaml-model 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,297 @@
1
+ module RootMappingSpec
2
+ class CeramicDetails < Lutaml::Model::Serializable
3
+ attribute :name, :string
4
+ attribute :insignia, :string
5
+
6
+ key_value do
7
+ map "name", to: :name
8
+ map "insignia", to: :insignia
9
+ end
10
+ end
11
+
12
+ class CeramicWithDetails < Lutaml::Model::Serializable
13
+ attribute :ceramic_id, :string
14
+ attribute :ceramic_type, :string
15
+ attribute :ceramic_details, CeramicDetails
16
+ attribute :ceramic_urn, :string
17
+
18
+ key_value do
19
+ map "id", to: :ceramic_id
20
+ map "type", to: :ceramic_type
21
+ map "details", to: :ceramic_details
22
+ map "urn", to: :ceramic_urn
23
+ end
24
+ end
25
+
26
+ class CeramicCollectionWithKeyAndValue < Lutaml::Model::Serializable
27
+ attribute :ceramics, CeramicWithDetails, collection: true
28
+
29
+ key_value do
30
+ map to: :ceramics,
31
+ root_mappings: {
32
+ ceramic_id: :key,
33
+ ceramic_details: :value,
34
+ }
35
+ end
36
+ end
37
+
38
+ class CeramicCollectionWithKeyAndComplexValue < Lutaml::Model::Serializable
39
+ attribute :ceramics, CeramicWithDetails, collection: true
40
+
41
+ key_value do
42
+ map to: :ceramics,
43
+ root_mappings: {
44
+ ceramic_id: :key,
45
+ ceramic_type: :type,
46
+ ceramic_details: "details",
47
+ ceramic_urn: ["urn", "primary"],
48
+ }
49
+ end
50
+ end
51
+
52
+ class Ceramic < Lutaml::Model::Serializable
53
+ attribute :ceramic_id, :string
54
+ attribute :ceramic_name, :string
55
+
56
+ key_value do
57
+ map "id", to: :ceramic_id
58
+ map "name", to: :ceramic_name
59
+ end
60
+ end
61
+
62
+ class CeramicCollectionWithKeyOnly < Lutaml::Model::Serializable
63
+ attribute :ceramics, Ceramic, collection: true
64
+
65
+ key_value do
66
+ map to: :ceramics, root_mappings: { ceramic_id: :key }
67
+ end
68
+ end
69
+
70
+ class CeramicCollectionWithoutCollectionTrue < Lutaml::Model::Serializable
71
+ attribute :ceramics, Ceramic
72
+
73
+ key_value do
74
+ map to: :ceramics, root_mappings: { ceramic_id: :key }
75
+ end
76
+ end
77
+ end
78
+
79
+ RSpec.describe "RootMapping" do
80
+ shared_examples "having root mappings" do |format|
81
+ let(:adapter) do
82
+ Lutaml::Model::Config.public_send(:"#{format}_adapter")
83
+ end
84
+
85
+ let(:input) do
86
+ adapter.new(input_hash).public_send(:"to_#{format}")
87
+ end
88
+
89
+ # 1. Only map to `:key`. Then only override key, the rest of the mappings stay.
90
+ context "when only `key` is mapped" do
91
+ let(:parsed) do
92
+ RootMappingSpec::CeramicCollectionWithKeyOnly.public_send(:"from_#{format}", input)
93
+ end
94
+
95
+ let(:input_hash) do
96
+ {
97
+ "vase1" => { "name" => "Imperial Vase" },
98
+ "bowl2" => { "name" => "18th Century Bowl" },
99
+ }
100
+ end
101
+
102
+ let(:ceramic_vase) do
103
+ RootMappingSpec::Ceramic.new(
104
+ ceramic_id: "vase1",
105
+ ceramic_name: "Imperial Vase",
106
+ )
107
+ end
108
+
109
+ let(:ceramic_bowl) do
110
+ RootMappingSpec::Ceramic.new(
111
+ ceramic_id: "bowl2",
112
+ ceramic_name: "18th Century Bowl",
113
+ )
114
+ end
115
+
116
+ it "parses" do
117
+ expect(parsed.ceramics.count).to eq(2)
118
+ # Because Tomlib reverses the order of the hash, so can not check based on position
119
+ expect(parsed.ceramics).to include(ceramic_vase)
120
+ expect(parsed.ceramics).to include(ceramic_bowl)
121
+ end
122
+
123
+ describe "serialize" do
124
+ let(:collection) do
125
+ RootMappingSpec::CeramicCollectionWithKeyOnly.new(ceramics: [
126
+ ceramic_vase,
127
+ ceramic_bowl,
128
+ ])
129
+ end
130
+
131
+ it "serializes correctly" do
132
+ expect(collection.public_send(:"to_#{format}")).to eq(input)
133
+ end
134
+ end
135
+ end
136
+
137
+ # 2. Maps `:key` and another attribute, then we override all the other mappings (clean slate)
138
+ context "when `key` and `value` are mapped" do
139
+ let(:parsed) do
140
+ RootMappingSpec::CeramicCollectionWithKeyAndValue.public_send(:"from_#{format}", input)
141
+ end
142
+
143
+ let(:input_hash) do
144
+ {
145
+ "vase1" => { "name" => "Imperial Vase", "insignia" => "Tang Tianbao" },
146
+ "bowl2" => { "name" => "18th Century Bowl", "insignia" => "Ming Wanli" },
147
+ }
148
+ end
149
+
150
+ let(:vase_with_details) do
151
+ RootMappingSpec::CeramicWithDetails.new(
152
+ ceramic_id: "vase1",
153
+ ceramic_details: RootMappingSpec::CeramicDetails.new(
154
+ name: "Imperial Vase",
155
+ insignia: "Tang Tianbao",
156
+ ),
157
+ )
158
+ end
159
+
160
+ let(:bowl_with_details) do
161
+ RootMappingSpec::CeramicWithDetails.new(
162
+ ceramic_id: "bowl2",
163
+ ceramic_details: RootMappingSpec::CeramicDetails.new(
164
+ name: "18th Century Bowl",
165
+ insignia: "Ming Wanli",
166
+ ),
167
+ )
168
+ end
169
+
170
+ it "parses" do
171
+ expect(parsed.ceramics.count).to eq(2)
172
+ # Because Tomlib reverses the order of the hash, so can not check based on position
173
+ expect(parsed.ceramics).to include(vase_with_details)
174
+ expect(parsed.ceramics).to include(bowl_with_details)
175
+ end
176
+
177
+ describe "serialize" do
178
+ let(:collection) do
179
+ RootMappingSpec::CeramicCollectionWithKeyAndValue.new(ceramics: [
180
+ vase_with_details,
181
+ bowl_with_details,
182
+ ])
183
+ end
184
+
185
+ it "serializes correctly" do
186
+ expect(collection.public_send(:"to_#{format}")).to eq(input)
187
+ end
188
+ end
189
+ end
190
+
191
+ # 3. Maps `:key` and `:value`, then we map the key and the value body to the new mappings.
192
+ context "when `key` and complex value structure is mapped" do
193
+ let(:parsed) do
194
+ RootMappingSpec::CeramicCollectionWithKeyAndComplexValue.public_send(:"from_#{format}", input)
195
+ end
196
+
197
+ let(:input_hash) do
198
+ {
199
+ "vase1" => {
200
+ "type" => "vase",
201
+ "details" => {
202
+ "name" => "Imperial Vase",
203
+ "insignia" => "Tang Tianbao",
204
+ },
205
+ "urn" => {
206
+ "primary" => "urn:ceramic:vase:vase1",
207
+ },
208
+ },
209
+ "bowl2" => {
210
+ "type" => "bowl",
211
+ "details" => {
212
+ "name" => "18th Century Bowl",
213
+ "insignia" => "Ming Wanli",
214
+ },
215
+ "urn" => {
216
+ "primary" => "urn:ceramic:bowl:bowl2",
217
+ },
218
+ },
219
+ }
220
+ end
221
+
222
+ let(:vase_with_details) do
223
+ RootMappingSpec::CeramicWithDetails.new(
224
+ ceramic_id: "vase1",
225
+ ceramic_type: "vase",
226
+ ceramic_urn: "urn:ceramic:vase:vase1",
227
+ ceramic_details: RootMappingSpec::CeramicDetails.new(
228
+ name: "Imperial Vase",
229
+ insignia: "Tang Tianbao",
230
+ ),
231
+ )
232
+ end
233
+
234
+ let(:bowl_with_details) do
235
+ RootMappingSpec::CeramicWithDetails.new(
236
+ ceramic_id: "bowl2",
237
+ ceramic_type: "bowl",
238
+ ceramic_urn: "urn:ceramic:bowl:bowl2",
239
+ ceramic_details: RootMappingSpec::CeramicDetails.new(
240
+ name: "18th Century Bowl",
241
+ insignia: "Ming Wanli",
242
+ ),
243
+ )
244
+ end
245
+
246
+ it "parses" do
247
+ expect(parsed.ceramics.count).to eq(2)
248
+ # Because Tomlib reverses the order of the hash, so can not check based on position
249
+ expect(parsed.ceramics).to include(vase_with_details)
250
+ expect(parsed.ceramics).to include(bowl_with_details)
251
+ end
252
+
253
+ describe "serialize from object" do
254
+ let(:collection) do
255
+ RootMappingSpec::CeramicCollectionWithKeyAndComplexValue.new(ceramics: [
256
+ vase_with_details,
257
+ bowl_with_details,
258
+ ])
259
+ end
260
+
261
+ it "serializes correctly" do
262
+ expect(collection.public_send(:"to_#{format}")).to eq(input)
263
+ end
264
+ end
265
+ end
266
+
267
+ context "when `collection: true` is missing" do
268
+ let(:input_hash) do
269
+ {
270
+ "vase1" => { "name" => "Imperial Vase" },
271
+ "bowl2" => { "name" => "18th Century Bowl" },
272
+ }
273
+ end
274
+
275
+ it "raises error" do
276
+ expect do
277
+ RootMappingSpec::CeramicCollectionWithoutCollectionTrue.public_send(:"from_#{format}", input)
278
+ end.to raise_error(
279
+ Lutaml::Model::CollectionTrueMissingError,
280
+ "May be `collection: true` is missing for `ceramics` in RootMappingSpec::CeramicCollectionWithoutCollectionTrue",
281
+ )
282
+ end
283
+ end
284
+ end
285
+
286
+ describe Lutaml::Model::YamlAdapter::StandardYamlAdapter do
287
+ it_behaves_like "having root mappings", :yaml
288
+ end
289
+
290
+ describe Lutaml::Model::JsonAdapter::StandardJsonAdapter do
291
+ it_behaves_like "having root mappings", :json
292
+ end
293
+
294
+ describe Lutaml::Model::TomlAdapter::TomlRbAdapter do
295
+ it_behaves_like "having root mappings", :toml
296
+ end
297
+ end
@@ -77,6 +77,25 @@ module SerializeableSpec
77
77
  class GlazeTechnique < Lutaml::Model::Serializable
78
78
  attribute :name, :string, values: ["Celadon", "Raku", "Majolica"]
79
79
  end
80
+
81
+ class TranslateHelper < Lutaml::Model::Serializable
82
+ attribute :id, :string
83
+ attribute :path, :string
84
+ attribute :name, :string
85
+ end
86
+
87
+ class TranslateMappings < Lutaml::Model::Serializable
88
+ attribute :translate, TranslateHelper, collection: true
89
+
90
+ key_value do
91
+ map "translate", to: :translate, child_mappings:
92
+ {
93
+ id: :key,
94
+ path: %i[path link],
95
+ name: %i[path name],
96
+ }
97
+ end
98
+ end
80
99
  end
81
100
 
82
101
  RSpec.describe Lutaml::Model::Serializable do
@@ -173,7 +192,7 @@ RSpec.describe Lutaml::Model::Serializable do
173
192
  end
174
193
  end
175
194
 
176
- describe ".apply_child_mappings" do
195
+ describe ".translate_mappings" do
177
196
  let(:child_mappings) do
178
197
  {
179
198
  id: :key,
@@ -205,17 +224,33 @@ RSpec.describe Lutaml::Model::Serializable do
205
224
  }
206
225
  end
207
226
 
227
+ let(:attr) { SerializeableSpec::TranslateMappings.attributes[:translate] }
228
+
208
229
  let(:expected_value) do
209
230
  [
210
- { id: "foo", path: "link one", name: "one" },
211
- { id: "abc", path: "link two", name: "two" },
212
- { id: "hello", path: "link three", name: "three" },
231
+ SerializeableSpec::TranslateHelper.new({
232
+ "id" => "foo",
233
+ "name" => "one",
234
+ "path" => "link one",
235
+ }),
236
+ SerializeableSpec::TranslateHelper.new({
237
+ "id" => "abc",
238
+ "name" => "two",
239
+ "path" => "link two",
240
+ }),
241
+ SerializeableSpec::TranslateHelper.new({
242
+ "id" => "hello",
243
+ "name" => "three",
244
+ "path" => "link three",
245
+ }),
213
246
  ]
214
247
  end
215
248
 
216
249
  it "generates hash based on child_mappings" do
217
- expect(described_class.apply_child_mappings(hash,
218
- child_mappings)).to eq(expected_value)
250
+ actual_value = described_class.translate_mappings(hash, child_mappings, attr, :yaml)
251
+
252
+ expect(actual_value.map { |obj| [obj.id, obj.name, obj.path] })
253
+ .to eq(expected_value.map { |obj| [obj.id, obj.name, obj.path] })
219
254
  end
220
255
  end
221
256
 
@@ -37,6 +37,63 @@ module ChildMapping
37
37
  }
38
38
  end
39
39
  end
40
+
41
+ class JS < Lutaml::Model::Serializable
42
+ attribute :prop, :string
43
+ attribute :hook, :string
44
+
45
+ key_value do
46
+ map :prop, to: :prop
47
+ map :hook, to: :hook
48
+ end
49
+ end
50
+
51
+ class Symbol < Lutaml::Model::Serializable
52
+ attribute :ascii, :string
53
+ attribute :html, :string
54
+ attribute :latex, :string
55
+ attribute :unicode, :string
56
+ attribute :js, JS
57
+
58
+ key_value do
59
+ map :ascii, to: :ascii
60
+ map :html, to: :html
61
+ map :latex, to: :latex
62
+ map :unicode, to: :unicode
63
+ map :js, to: :js
64
+ end
65
+ end
66
+
67
+ class Prefix < Lutaml::Model::Serializable
68
+ attribute :id, :string
69
+ attribute :name, :string
70
+ attribute :symbol, Symbol
71
+ attribute :base, :integer
72
+ attribute :power, :integer
73
+
74
+ key_value do
75
+ map :prefix_id, to: :id
76
+ map :name, to: :name
77
+ map :symbol, to: :symbol
78
+ map :base, to: :base
79
+ map :power, to: :power
80
+ end
81
+ end
82
+
83
+ class Prefixes < Lutaml::Model::Serializable
84
+ attribute :prefixes, Prefix, collection: true
85
+
86
+ key_value do
87
+ map "prefixes", to: :prefixes, child_mappings:
88
+ {
89
+ id: :key,
90
+ name: :name,
91
+ symbol: :symbol,
92
+ base: :base,
93
+ power: :power,
94
+ }
95
+ end
96
+ end
40
97
  end
41
98
 
42
99
  RSpec.describe ChildMapping do
@@ -72,11 +129,52 @@ RSpec.describe ChildMapping do
72
129
  let(:expected_paths) { ["link one", "link two", "link three"] }
73
130
  let(:expected_names) { ["one", "two", "three"] }
74
131
 
132
+ let(:prefixes_hash) do
133
+ {
134
+ "prefixes" => {
135
+ "NISTp10_30" => {
136
+ "name" => "quetta",
137
+ "symbol" => {
138
+ "ascii" => "Q",
139
+ "html" => "Q",
140
+ "latex" => "Q",
141
+ "unicode" => "Q",
142
+ "js" => {
143
+ "prop" => "head",
144
+ "hook" => "async",
145
+ },
146
+ },
147
+ "base" => 10,
148
+ "power" => 30,
149
+ },
150
+ "NISTp10_27" => {
151
+ "name" => "ronna",
152
+ "symbol" => {
153
+ "ascii" => "R",
154
+ "html" => "R",
155
+ "latex" => "R",
156
+ "unicode" => "R",
157
+ "js" => {
158
+ "prop" => "head",
159
+ "hook" => "async",
160
+ },
161
+ },
162
+ "base" => 10,
163
+ "power" => 27,
164
+ },
165
+ },
166
+ }
167
+ end
168
+
75
169
  context "with json" do
76
170
  let(:json) do
77
171
  hash.to_json
78
172
  end
79
173
 
174
+ let(:prefixes_json) do
175
+ prefixes_hash.to_json
176
+ end
177
+
80
178
  describe ".from_json" do
81
179
  it "create model according to json" do
82
180
  instance = mapper.from_json(json)
@@ -86,6 +184,14 @@ RSpec.describe ChildMapping do
86
184
  expect(instance.schemas.map(&:path)).to eq(expected_paths)
87
185
  expect(instance.schemas.map(&:name)).to eq(expected_names)
88
186
  end
187
+
188
+ it "create model according to json with nesting values" do
189
+ instance = ChildMapping::Prefixes.from_json(prefixes_json)
190
+
191
+ expect(instance.prefixes.first.id).to eq("NISTp10_30")
192
+ expect(instance.prefixes.first.symbol.ascii).to eq("Q")
193
+ expect(instance.prefixes.first.symbol.js.hook).to eq("async")
194
+ end
89
195
  end
90
196
 
91
197
  describe ".to_json" do
@@ -98,6 +204,13 @@ RSpec.describe ChildMapping do
98
204
 
99
205
  expect(instance.to_json).to eq(json)
100
206
  end
207
+
208
+ it "converts object to json with nesting values" do
209
+ instance = ChildMapping::Prefixes.from_json(prefixes_json)
210
+ serialized = instance.to_json
211
+
212
+ expect(serialized).to be_equivalent_to(prefixes_json)
213
+ end
101
214
  end
102
215
  end
103
216
 
@@ -106,6 +219,10 @@ RSpec.describe ChildMapping do
106
219
  hash.to_yaml
107
220
  end
108
221
 
222
+ let(:prefixes_yaml) do
223
+ prefixes_hash.to_yaml
224
+ end
225
+
109
226
  describe ".from_yaml" do
110
227
  it "create model according to yaml" do
111
228
  instance = mapper.from_yaml(yaml)
@@ -115,6 +232,14 @@ RSpec.describe ChildMapping do
115
232
  expect(instance.schemas.map(&:path)).to eq(expected_paths)
116
233
  expect(instance.schemas.map(&:name)).to eq(expected_names)
117
234
  end
235
+
236
+ it "create model according to yaml with nesting values" do
237
+ instance = ChildMapping::Prefixes.from_yaml(prefixes_yaml)
238
+
239
+ expect(instance.prefixes.first.id).to eq("NISTp10_30")
240
+ expect(instance.prefixes.first.symbol.ascii).to eq("Q")
241
+ expect(instance.prefixes.first.symbol.js.hook).to eq("async")
242
+ end
118
243
  end
119
244
 
120
245
  describe ".to_yaml" do
@@ -127,6 +252,13 @@ RSpec.describe ChildMapping do
127
252
 
128
253
  expect(instance.to_yaml).to eq(yaml)
129
254
  end
255
+
256
+ it "converts object to yaml with nesting values" do
257
+ instance = ChildMapping::Prefixes.from_yaml(prefixes_yaml)
258
+ serialized = instance.to_yaml
259
+
260
+ expect(YAML.safe_load(serialized)).to eq(YAML.safe_load(prefixes_yaml))
261
+ end
130
262
  end
131
263
  end
132
264
 
@@ -145,6 +277,40 @@ RSpec.describe ChildMapping do
145
277
  TOML
146
278
  end
147
279
 
280
+ let(:prefixes_toml) do
281
+ <<~TOML
282
+ [prefixes.NISTp10_30]
283
+ name = "quetta"
284
+ base = 10
285
+ power = 30
286
+
287
+ [prefixes.NISTp10_30.symbol]
288
+ ascii = "Q"
289
+ html = "Q"
290
+ latex = "Q"
291
+ unicode = "Q"
292
+
293
+ [prefixes.NISTp10_30.symbol.js]
294
+ prop = "head"
295
+ hook = "async"
296
+
297
+ [prefixes.NISTp10_27]
298
+ name = "ronna"
299
+ base = 10
300
+ power = 27
301
+
302
+ [prefixes.NISTp10_27.symbol]
303
+ ascii = "R"
304
+ html = "R"
305
+ latex = "R"
306
+ unicode = "R"
307
+
308
+ [prefixes.NISTp10_27.symbol.js]
309
+ prop = "head"
310
+ hook = "async"
311
+ TOML
312
+ end
313
+
148
314
  describe ".from_toml" do
149
315
  it "create model according to toml" do
150
316
  instance = mapper.from_toml(toml)
@@ -154,6 +320,14 @@ RSpec.describe ChildMapping do
154
320
  expect(instance.schemas.map(&:path)).to eq(expected_paths)
155
321
  expect(instance.schemas.map(&:name)).to eq(expected_names)
156
322
  end
323
+
324
+ it "create model according to toml with nesting values" do
325
+ instance = ChildMapping::Prefixes.from_toml(prefixes_toml)
326
+
327
+ expect(instance.prefixes.first.id).to eq("NISTp10_30")
328
+ expect(instance.prefixes.first.symbol.ascii).to eq("Q")
329
+ expect(instance.prefixes.first.symbol.js.hook).to eq("async")
330
+ end
157
331
  end
158
332
 
159
333
  describe ".to_toml" do
@@ -169,6 +343,14 @@ RSpec.describe ChildMapping do
169
343
 
170
344
  expect(actual.attributes).to eq(expected.attributes)
171
345
  end
346
+
347
+ it "converts object to toml with nesting values" do
348
+ instance = ChildMapping::Prefixes.from_toml(prefixes_toml)
349
+ actual = Lutaml::Model::Config.toml_adapter.parse(instance.to_toml)
350
+ expected = Lutaml::Model::Config.toml_adapter.parse(prefixes_toml)
351
+
352
+ expect(actual.attributes).to eq(expected.attributes)
353
+ end
172
354
  end
173
355
  end
174
356
  end
@@ -86,6 +86,43 @@ RSpec.shared_context "XML namespace models" do
86
86
  prefix: nil
87
87
  end
88
88
  end
89
+
90
+ class Body < Lutaml::Model::Serializable
91
+ attribute :paragraph, :string
92
+
93
+ xml do
94
+ map_element "p", to: :paragraph
95
+ end
96
+ end
97
+
98
+ class Element < Lutaml::Model::Serializable
99
+ attribute :text, :string
100
+ xml do
101
+ root "test-element"
102
+ namespace "http://www.test.com/schemas/test/1.0/", "test"
103
+ map_content to: :text
104
+ end
105
+ end
106
+
107
+ class Front < Lutaml::Model::Serializable
108
+ attribute :test_element, Element
109
+
110
+ xml do
111
+ namespace "http://www.test.com/schemas/test/1.0/", "test"
112
+ map_element "test-element", to: :test_element
113
+ end
114
+ end
115
+
116
+ class Article < Lutaml::Model::Serializable
117
+ attribute :front, Front
118
+ attribute :body, Body
119
+
120
+ xml do
121
+ root "article"
122
+ map_element "front", to: :front, prefix: "test", namespace: "http://www.test.com/schemas/test/1.0/"
123
+ map_element "body", to: :body
124
+ end
125
+ end
89
126
  end
90
127
 
91
128
  RSpec.shared_examples "XML serialization with namespace" do |model_class, xml_string|
@@ -236,6 +273,35 @@ RSpec.shared_examples "an XML namespace parser" do |adapter_class|
236
273
  expect(generated_xml).to be_equivalent_to(xml)
237
274
  end
238
275
  end
276
+
277
+ context "when custom namespace is used" do
278
+ let(:xml_input) do
279
+ <<~XML
280
+ <article xmlns:test="http://www.test.com/schemas/test/1.0/">
281
+ <test:front>
282
+ <test:test-element>Text Here</test:test-element>
283
+ </test:front>
284
+ <body>
285
+ <p>This is a paragraph</p>
286
+ </body>
287
+ </article>
288
+ XML
289
+ end
290
+
291
+ describe "XML serialization" do
292
+ it "correctly deserializes from XML" do
293
+ article = Article.from_xml(xml_input)
294
+ expect(article.body.paragraph).to eq("This is a paragraph")
295
+ end
296
+
297
+ it "round-trips XML" do
298
+ article = Article.from_xml(xml_input)
299
+ output_xml = article.to_xml(pretty: true)
300
+
301
+ expect(output_xml).to be_equivalent_to(xml_input)
302
+ end
303
+ end
304
+ end
239
305
  end
240
306
 
241
307
  RSpec.describe Lutaml::Model::XmlAdapter::NokogiriAdapter do