lutaml-model 0.4.0 → 0.5.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +36 -20
  3. data/README.adoc +1003 -192
  4. data/lib/lutaml/model/attribute.rb +6 -2
  5. data/lib/lutaml/model/error/collection_true_missing_error.rb +16 -0
  6. data/lib/lutaml/model/error/multiple_mappings_error.rb +6 -0
  7. data/lib/lutaml/model/error.rb +2 -0
  8. data/lib/lutaml/model/key_value_mapping.rb +25 -4
  9. data/lib/lutaml/model/key_value_mapping_rule.rb +16 -3
  10. data/lib/lutaml/model/loggable.rb +15 -0
  11. data/lib/lutaml/model/mapping_rule.rb +14 -2
  12. data/lib/lutaml/model/serialize.rb +114 -64
  13. data/lib/lutaml/model/type/decimal.rb +5 -0
  14. data/lib/lutaml/model/version.rb +1 -1
  15. data/lib/lutaml/model/xml_adapter/builder/nokogiri.rb +1 -0
  16. data/lib/lutaml/model/xml_adapter/builder/oga.rb +180 -0
  17. data/lib/lutaml/model/xml_adapter/builder/ox.rb +1 -0
  18. data/lib/lutaml/model/xml_adapter/oga/document.rb +20 -0
  19. data/lib/lutaml/model/xml_adapter/oga/element.rb +117 -0
  20. data/lib/lutaml/model/xml_adapter/oga_adapter.rb +77 -44
  21. data/lib/lutaml/model/xml_adapter/xml_document.rb +14 -12
  22. data/lib/lutaml/model/xml_mapping.rb +3 -0
  23. data/lib/lutaml/model/xml_mapping_rule.rb +13 -4
  24. data/lib/lutaml/model.rb +1 -0
  25. data/spec/address_spec.rb +1 -0
  26. data/spec/fixtures/sample_model.rb +7 -0
  27. data/spec/lutaml/model/custom_model_spec.rb +47 -1
  28. data/spec/lutaml/model/included_spec.rb +192 -0
  29. data/spec/lutaml/model/mixed_content_spec.rb +48 -32
  30. data/spec/lutaml/model/multiple_mapping_spec.rb +329 -0
  31. data/spec/lutaml/model/ordered_content_spec.rb +1 -1
  32. data/spec/lutaml/model/render_nil_spec.rb +3 -0
  33. data/spec/lutaml/model/root_mappings_spec.rb +297 -0
  34. data/spec/lutaml/model/serializable_spec.rb +42 -7
  35. data/spec/lutaml/model/type/boolean_spec.rb +62 -0
  36. data/spec/lutaml/model/with_child_mapping_spec.rb +182 -0
  37. data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +11 -11
  38. data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +67 -1
  39. data/spec/lutaml/model/xml_adapter_spec.rb +2 -2
  40. data/spec/lutaml/model/xml_mapping_spec.rb +32 -9
  41. data/spec/sample_model_spec.rb +114 -0
  42. metadata +12 -2
@@ -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
@@ -87,7 +106,7 @@ RSpec.describe Lutaml::Model::Serializable do
87
106
  end.to change(
88
107
  described_class, :model
89
108
  )
90
- .from(nil)
109
+ .from(described_class)
91
110
  .to(SerializeableSpec::TestModel)
92
111
  end
93
112
  end
@@ -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
 
@@ -1,5 +1,23 @@
1
1
  require "spec_helper"
2
2
 
3
+ module BooleanSpec
4
+ class Employee < Lutaml::Model::Serializable
5
+ attribute :name, :string
6
+ attribute :full_time, :boolean
7
+ attribute :on_leave, :boolean
8
+ attribute :remote, :boolean
9
+ attribute :active, :boolean
10
+
11
+ key_value do
12
+ map "name", to: :name
13
+ map "full_time", to: :full_time
14
+ map "on_leave", to: :on_leave
15
+ map "remote", to: :remote, render_nil: true
16
+ map "active", to: :active, render_nil: false
17
+ end
18
+ end
19
+ end
20
+
3
21
  RSpec.describe Lutaml::Model::Type::Boolean do
4
22
  describe ".cast" do
5
23
  let(:truthy_values) { [true, "true", "t", "yes", "y", "1"] }
@@ -51,4 +69,48 @@ RSpec.describe Lutaml::Model::Type::Boolean do
51
69
  expect(described_class.serialize(true)).to be true
52
70
  end
53
71
  end
72
+
73
+ context "with key-value serialization" do
74
+ let(:yaml) do
75
+ {
76
+ "name" => "John Smith",
77
+ "full_time" => true,
78
+ "on_leave" => false,
79
+ "remote" => nil,
80
+ "active" => nil,
81
+ }.to_yaml
82
+ end
83
+
84
+ let(:expected_yaml) do
85
+ {
86
+ "name" => "John Smith",
87
+ "full_time" => true,
88
+ "on_leave" => false,
89
+ "remote" => nil,
90
+ }.to_yaml
91
+ end
92
+
93
+ it "deserializes boolean values correctly" do
94
+ employee = BooleanSpec::Employee.from_yaml(yaml)
95
+
96
+ expect(employee.name).to eq("John Smith")
97
+ expect(employee.full_time).to be true
98
+ expect(employee.on_leave).to be false
99
+ expect(employee.remote).to be_nil
100
+ expect(employee.active).to be_nil
101
+ end
102
+
103
+ it "serializes boolean values correctly" do
104
+ employee = BooleanSpec::Employee.new(
105
+ name: "John Smith",
106
+ full_time: true,
107
+ on_leave: false,
108
+ remote: nil,
109
+ active: nil,
110
+ )
111
+
112
+ yaml_output = employee.to_yaml
113
+ expect(yaml_output).to eq(expected_yaml)
114
+ end
115
+ end
54
116
  end
@@ -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
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
  require "oga"
3
3
  require_relative "../../../../lib/lutaml/model/xml_adapter/oga_adapter"
4
4
 
5
- RSpec.xdescribe Lutaml::Model::XmlAdapter::OgaAdapter do
5
+ RSpec.describe Lutaml::Model::XmlAdapter::OgaAdapter do
6
6
  let(:xml_string) do
7
7
  <<~XML
8
8
  <root xmlns="http://example.com/default" xmlns:prefix="http://example.com/prefixed">
@@ -14,21 +14,21 @@ RSpec.xdescribe Lutaml::Model::XmlAdapter::OgaAdapter do
14
14
  let(:document) { described_class.parse(xml_string) }
15
15
 
16
16
  context "parsing XML with namespaces" do
17
+ let(:child) { document.root.children[1] }
18
+
17
19
  it "parses the root element with default namespace" do
18
20
  expect(document.root.name).to eq("root")
19
- expect(document.root.namespace).to eq("http://example.com/default")
20
- expect(document.root.namespace_prefix).to be_nil
21
+ expect(document.root.namespace.uri).to eq("http://example.com/default")
22
+ expect(document.root.namespace.prefix).to be_nil
21
23
  end
22
24
 
23
25
  it "parses child element with prefixed namespace" do
24
- child = document.root.children.first
25
- expect(child.name).to eq("child")
26
- expect(child.namespace).to eq("http://example.com/prefixed")
27
- expect(child.namespace_prefix).to eq("prefix")
26
+ expect(child.name).to eq("prefix:child")
27
+ expect(child.namespace.uri).to eq("http://example.com/prefixed")
28
+ expect(child.namespace.prefix).to eq("prefix")
28
29
  end
29
30
 
30
31
  it "parses attributes with and without namespaces" do
31
- child = document.root.children.first
32
32
  expect(child.attributes["attr"].value).to eq("value")
33
33
  expect(child.attributes["attr"].namespace).to be_nil
34
34
  expect(child.attributes["prefix:attr"].value).to eq("prefixed_value")
@@ -42,12 +42,12 @@ RSpec.xdescribe Lutaml::Model::XmlAdapter::OgaAdapter do
42
42
  xml_output = document.to_xml
43
43
  parsed_output = Oga.parse_xml(xml_output)
44
44
 
45
- root = parsed_output.root
45
+ root = parsed_output.children.first
46
46
  expect(root.name).to eq("root")
47
47
  expect(root.namespace.uri).to eq("http://example.com/default")
48
48
 
49
- child = root.children.first
50
- expect(child.name).to eq("child")
49
+ child = root.children[1]
50
+ expect(child.expanded_name).to eq("prefix:child")
51
51
  expect(child.namespace.uri).to eq("http://example.com/prefixed")
52
52
  expect(child.get("attr")).to eq("value")
53
53
  expect(child.get("prefix:attr")).to eq("prefixed_value")
@@ -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
@@ -246,6 +312,6 @@ RSpec.describe Lutaml::Model::XmlAdapter::OxAdapter do
246
312
  it_behaves_like "an XML namespace parser", described_class
247
313
  end
248
314
 
249
- RSpec.xdescribe Lutaml::Model::XmlAdapter::OgaAdapter do
315
+ RSpec.describe Lutaml::Model::XmlAdapter::OgaAdapter do
250
316
  it_behaves_like "an XML namespace parser", described_class
251
317
  end
@@ -119,7 +119,7 @@ RSpec.shared_examples "an XML adapter" do |adapter_class|
119
119
 
120
120
  parsed = XmlAdapterSpec::Maths.from_xml(input_xml)
121
121
 
122
- expect(parsed.to_xml.strip).to eq(output_xml.strip)
122
+ expect(parsed.to_xml.strip).to be_equivalent_to(output_xml.strip)
123
123
  end
124
124
  end
125
125
 
@@ -173,6 +173,6 @@ RSpec.describe Lutaml::Model::XmlAdapter::OxAdapter do
173
173
  it_behaves_like "an XML adapter", described_class
174
174
  end
175
175
 
176
- RSpec.xdescribe Lutaml::Model::XmlAdapter::OgaAdapter do
176
+ RSpec.describe Lutaml::Model::XmlAdapter::OgaAdapter do
177
177
  it_behaves_like "an XML adapter", described_class
178
178
  end
@@ -325,7 +325,7 @@ RSpec.describe Lutaml::Model::XmlMapping do
325
325
  end
326
326
 
327
327
  # Skipping for OX because it does not handle namespaces
328
- context "overriding child namespace prefix", skip: adapter_class != Lutaml::Model::XmlAdapter::NokogiriAdapter do
328
+ context "overriding child namespace prefix", skip: adapter_class == Lutaml::Model::XmlAdapter::OxAdapter do
329
329
  let(:input_xml) do
330
330
  <<~XML
331
331
  <OverrideDefaultNamespacePrefix
@@ -342,9 +342,20 @@ RSpec.describe Lutaml::Model::XmlMapping do
342
342
  XML
343
343
  end
344
344
 
345
+ let(:oga_expected_xml) do
346
+ "<OverrideDefaultNamespacePrefix xmlns:abc=\"http://www.omg.org/spec/XMI/20131001\">" +
347
+ "<abc:SameElementName App=\"hello\" xmlns:GML=\"http://www.sparxsystems.com/profiles/GML/1.0\" xmlns:CityGML=\"http://www.sparxsystems.com/profiles/CityGML/1.0\">" +
348
+ "<GML:ApplicationSchema>GML App</GML:ApplicationSchema>" +
349
+ "<CityGML:ApplicationSchema>CityGML App</CityGML:ApplicationSchema>" +
350
+ "<abc:ApplicationSchema>App</abc:ApplicationSchema>" +
351
+ "</abc:SameElementName>" +
352
+ "</OverrideDefaultNamespacePrefix>"
353
+ end
354
+
345
355
  it "expect to round-trips" do
346
356
  parsed = XmlMapping::OverrideDefaultNamespacePrefix.from_xml(input_xml)
347
- expect(parsed.to_xml).to be_equivalent_to(input_xml)
357
+ expected_xml = adapter_class.type == "oga" ? oga_expected_xml : input_xml
358
+ expect(parsed.to_xml).to be_equivalent_to(expected_xml)
348
359
  end
349
360
  end
350
361
 
@@ -379,6 +390,15 @@ RSpec.describe Lutaml::Model::XmlMapping do
379
390
  "ApplicationSchema",
380
391
  "ApplicationSchema",
381
392
  ],
393
+ Lutaml::Model::XmlAdapter::OgaAdapter => [
394
+ "text",
395
+ "ApplicationSchema",
396
+ "text",
397
+ "ApplicationSchema",
398
+ "text",
399
+ "ApplicationSchema",
400
+ "text",
401
+ ],
382
402
  }
383
403
  end
384
404
 
@@ -600,6 +620,14 @@ RSpec.describe Lutaml::Model::XmlMapping do
600
620
  it "contain schemaLocation attributes" do
601
621
  expect(Paragraph.from_xml(xml).to_xml).to be_equivalent_to(xml)
602
622
  end
623
+
624
+ it "prints warning if defined explicitly in class" do
625
+ error_regex = /\[Lutaml::Model\] WARN: `schemaLocation` is handled by default\. No need to explecitly define at `xml_mapping_spec.rb:\d+`/
626
+
627
+ expect do
628
+ Lutaml::Model::XmlMapping.new.map_attribute("schemaLocation", to: :schema_location)
629
+ end.to output(error_regex).to_stderr
630
+ end
603
631
  end
604
632
 
605
633
  context "when mixed: true" do
@@ -1032,12 +1060,7 @@ RSpec.describe Lutaml::Model::XmlMapping do
1032
1060
  end
1033
1061
 
1034
1062
  it "round-trips xml" do
1035
- expected_xml = if adapter_class == Lutaml::Model::XmlAdapter::NokogiriAdapter
1036
- expected_nokogiri_xml
1037
- else
1038
- expected_ox_xml
1039
- end
1040
-
1063
+ expected_xml = adapter_class.type == "ox" ? expected_ox_xml : expected_nokogiri_xml
1041
1064
  expect(XmlMapping::SpecialCharContentWithMapAll.from_xml(xml).to_xml).to eq(expected_xml)
1042
1065
  end
1043
1066
  end
@@ -1066,7 +1089,7 @@ RSpec.describe Lutaml::Model::XmlMapping do
1066
1089
  it_behaves_like "having XML Mappings", described_class
1067
1090
  end
1068
1091
 
1069
- describe Lutaml::Model::XmlAdapter::OgaAdapter, skip: "Not implemented yet" do
1092
+ describe Lutaml::Model::XmlAdapter::OgaAdapter do
1070
1093
  it_behaves_like "having XML Mappings", described_class
1071
1094
  end
1072
1095
  end