lutaml-model 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/dependent-tests.yml +2 -0
  3. data/.rubocop_todo.yml +86 -23
  4. data/Gemfile +2 -0
  5. data/README.adoc +1441 -220
  6. data/lib/lutaml/model/attribute.rb +33 -10
  7. data/lib/lutaml/model/choice.rb +56 -0
  8. data/lib/lutaml/model/config.rb +1 -0
  9. data/lib/lutaml/model/constants.rb +7 -0
  10. data/lib/lutaml/model/error/choice_lower_bound_error.rb +9 -0
  11. data/lib/lutaml/model/error/choice_upper_bound_error.rb +9 -0
  12. data/lib/lutaml/model/error/import_model_with_root_error.rb +9 -0
  13. data/lib/lutaml/model/error/incorrect_sequence_error.rb +9 -0
  14. data/lib/lutaml/model/error/invalid_choice_range_error.rb +20 -0
  15. data/lib/lutaml/model/error/no_root_mapping_error.rb +9 -0
  16. data/lib/lutaml/model/error/no_root_namespace_error.rb +9 -0
  17. data/lib/lutaml/model/error/type/invalid_value_error.rb +19 -0
  18. data/lib/lutaml/model/error/unknown_sequence_mapping_error.rb +9 -0
  19. data/lib/lutaml/model/error.rb +9 -0
  20. data/lib/lutaml/model/json_adapter/standard_json_adapter.rb +6 -1
  21. data/lib/lutaml/model/key_value_mapping.rb +34 -3
  22. data/lib/lutaml/model/key_value_mapping_rule.rb +4 -2
  23. data/lib/lutaml/model/liquefiable.rb +59 -0
  24. data/lib/lutaml/model/mapping_hash.rb +9 -1
  25. data/lib/lutaml/model/mapping_rule.rb +19 -2
  26. data/lib/lutaml/model/schema/templates/simple_type.rb +247 -0
  27. data/lib/lutaml/model/schema/xml_compiler.rb +762 -0
  28. data/lib/lutaml/model/schema.rb +5 -0
  29. data/lib/lutaml/model/schema_location.rb +7 -0
  30. data/lib/lutaml/model/sequence.rb +71 -0
  31. data/lib/lutaml/model/serialize.rb +139 -33
  32. data/lib/lutaml/model/toml_adapter/toml_rb_adapter.rb +1 -2
  33. data/lib/lutaml/model/type/decimal.rb +0 -4
  34. data/lib/lutaml/model/type/hash.rb +11 -11
  35. data/lib/lutaml/model/type/time.rb +3 -3
  36. data/lib/lutaml/model/utils.rb +19 -15
  37. data/lib/lutaml/model/validation.rb +12 -1
  38. data/lib/lutaml/model/version.rb +1 -1
  39. data/lib/lutaml/model/xml_adapter/builder/oga.rb +10 -7
  40. data/lib/lutaml/model/xml_adapter/builder/ox.rb +20 -13
  41. data/lib/lutaml/model/xml_adapter/element.rb +32 -0
  42. data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +13 -9
  43. data/lib/lutaml/model/xml_adapter/oga/element.rb +14 -13
  44. data/lib/lutaml/model/xml_adapter/oga_adapter.rb +86 -19
  45. data/lib/lutaml/model/xml_adapter/ox_adapter.rb +19 -15
  46. data/lib/lutaml/model/xml_adapter/xml_document.rb +82 -25
  47. data/lib/lutaml/model/xml_adapter/xml_element.rb +57 -3
  48. data/lib/lutaml/model/xml_mapping.rb +53 -9
  49. data/lib/lutaml/model/xml_mapping_rule.rb +8 -6
  50. data/lib/lutaml/model.rb +2 -0
  51. data/lutaml-model.gemspec +5 -0
  52. data/spec/benchmarks/xml_parsing_benchmark_spec.rb +75 -0
  53. data/spec/ceramic_spec.rb +39 -0
  54. data/spec/fixtures/ceramic.rb +23 -0
  55. data/spec/fixtures/xml/address_example_260.xsd +9 -0
  56. data/spec/fixtures/xml/invalid_math_document.xml +4 -0
  57. data/spec/fixtures/xml/math_document_schema.xsd +56 -0
  58. data/spec/fixtures/xml/test_schema.xsd +53 -0
  59. data/spec/fixtures/xml/user.xsd +10 -0
  60. data/spec/fixtures/xml/valid_math_document.xml +4 -0
  61. data/spec/lutaml/model/cdata_spec.rb +4 -5
  62. data/spec/lutaml/model/choice_spec.rb +168 -0
  63. data/spec/lutaml/model/collection_spec.rb +1 -1
  64. data/spec/lutaml/model/custom_model_spec.rb +7 -21
  65. data/spec/lutaml/model/custom_serialization_spec.rb +74 -2
  66. data/spec/lutaml/model/defaults_spec.rb +3 -1
  67. data/spec/lutaml/model/delegation_spec.rb +7 -5
  68. data/spec/lutaml/model/enum_spec.rb +35 -0
  69. data/spec/lutaml/model/group_spec.rb +160 -0
  70. data/spec/lutaml/model/inheritance_spec.rb +25 -0
  71. data/spec/lutaml/model/key_value_mapping_spec.rb +27 -0
  72. data/spec/lutaml/model/liquefiable_spec.rb +121 -0
  73. data/spec/lutaml/model/map_all_spec.rb +188 -0
  74. data/spec/lutaml/model/mixed_content_spec.rb +95 -56
  75. data/spec/lutaml/model/multiple_mapping_spec.rb +22 -10
  76. data/spec/lutaml/model/schema/xml_compiler_spec.rb +1624 -0
  77. data/spec/lutaml/model/sequence_spec.rb +216 -0
  78. data/spec/lutaml/model/transformation_spec.rb +230 -0
  79. data/spec/lutaml/model/type_spec.rb +138 -31
  80. data/spec/lutaml/model/utils_spec.rb +32 -0
  81. data/spec/lutaml/model/with_child_mapping_spec.rb +2 -2
  82. data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +11 -7
  83. data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +52 -0
  84. data/spec/lutaml/model/xml_mapping_rule_spec.rb +51 -0
  85. data/spec/lutaml/model/xml_mapping_spec.rb +250 -112
  86. metadata +77 -2
@@ -131,6 +131,45 @@ module XmlMapping
131
131
  end
132
132
  end
133
133
 
134
+ class AnnotatedElement < Lutaml::Model::Serializable
135
+ attribute :idref, :string
136
+
137
+ xml do
138
+ root "annotatedElement"
139
+ map_attribute "idref", to: :idref, namespace: "http://www.omg.org/spec/XMI/20131001", prefix: "xmi"
140
+ end
141
+ end
142
+
143
+ class OwnedComment < Lutaml::Model::Serializable
144
+ attribute :annotated_attribute, :string
145
+ attribute :annotated_element, AnnotatedElement
146
+
147
+ xml do
148
+ root "ownedComment"
149
+ map_attribute "annotatedElement", to: :annotated_attribute
150
+ map_element "annotatedElement", to: :annotated_element, prefix: nil, namespace: nil
151
+ end
152
+ end
153
+
154
+ class Date < Lutaml::Model::Serializable
155
+ attribute :type, :string
156
+ attribute :text, :string
157
+ attribute :content, :string
158
+ attribute :from, :string
159
+ attribute :to, :string
160
+ attribute :on, :string
161
+
162
+ xml do
163
+ root "date", mixed: true
164
+ map_attribute "type", to: :type
165
+ map_attribute "text", to: :text
166
+ map_content to: :content
167
+ map_element "from", to: :from
168
+ map_element "to", to: :to
169
+ map_element "on", to: :on
170
+ end
171
+ end
172
+
134
173
  class OverrideDefaultNamespacePrefix < Lutaml::Model::Serializable
135
174
  attribute :same_element_name, SameNameDifferentNamespace
136
175
 
@@ -187,7 +226,8 @@ module XmlMapping
187
226
  xml do
188
227
  root "MapAllWithCustomMethod"
189
228
 
190
- map_all to: :all_content, with: { to: :content_to_xml, from: :content_from_xml }
229
+ map_all_content to: :all_content,
230
+ with: { to: :content_to_xml, from: :content_from_xml }
191
231
  end
192
232
 
193
233
  def content_to_xml(model, parent, doc)
@@ -305,6 +345,7 @@ RSpec.describe Lutaml::Model::XmlMapping do
305
345
 
306
346
  it "checks the attribute with and without namespace" do
307
347
  parsed = XmlMapping::AttributeNamespace.from_xml(input_xml)
348
+
308
349
  expect(parsed.alpha).to eq("hello")
309
350
  expect(parsed.beta).to eq("bye")
310
351
  expect(parsed.to_xml).to be_equivalent_to(input_xml)
@@ -343,12 +384,12 @@ RSpec.describe Lutaml::Model::XmlMapping do
343
384
  end
344
385
 
345
386
  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>" +
387
+ "<OverrideDefaultNamespacePrefix xmlns:abc=\"http://www.omg.org/spec/XMI/20131001\">" \
388
+ "<abc:SameElementName App=\"hello\" xmlns:GML=\"http://www.sparxsystems.com/profiles/GML/1.0\" xmlns:CityGML=\"http://www.sparxsystems.com/profiles/CityGML/1.0\">" \
389
+ "<GML:ApplicationSchema>GML App</GML:ApplicationSchema>" \
390
+ "<CityGML:ApplicationSchema>CityGML App</CityGML:ApplicationSchema>" \
391
+ "<abc:ApplicationSchema>App</abc:ApplicationSchema>" \
392
+ "</abc:SameElementName>" \
352
393
  "</OverrideDefaultNamespacePrefix>"
353
394
  end
354
395
 
@@ -359,6 +400,69 @@ RSpec.describe Lutaml::Model::XmlMapping do
359
400
  end
360
401
  end
361
402
 
403
+ context "with same element and attribute name" do
404
+ let(:xml_with_element) do
405
+ <<~XML
406
+ <ownedComment xmlns:xmi="http://www.omg.org/spec/XMI/20131001">
407
+ <annotatedElement xmi:idref="ABC"/>
408
+ </ownedComment>
409
+ XML
410
+ end
411
+
412
+ let(:xml_with_attribute) do
413
+ <<~XML
414
+ <ownedComment annotatedElement="test2">
415
+ </ownedComment>
416
+ XML
417
+ end
418
+
419
+ let(:xml_with_same_name_attribute_and_element) do
420
+ <<~XML
421
+ <ownedComment xmlns:xmi="http://www.omg.org/spec/XMI/20131001" annotatedElement="test2">
422
+ <annotatedElement xmi:idref="ABC"/>
423
+ </ownedComment>
424
+ XML
425
+ end
426
+
427
+ let(:xml) do
428
+ <<~XML
429
+ <date type="published">
430
+ End of December
431
+ <on>2020-01</on>
432
+ Start of January
433
+ </date>
434
+ XML
435
+ end
436
+
437
+ it "parse and serializes the input xml correctly # lutaml/issues/217" do
438
+ parsed = XmlMapping::OwnedComment.from_xml(xml_with_element)
439
+ serialized = parsed.to_xml
440
+
441
+ expect(serialized).to be_equivalent_to(xml_with_element.strip)
442
+ end
443
+
444
+ it "parse and serialize model correctly" do
445
+ parsed = XmlMapping::OwnedComment.from_xml(xml_with_attribute)
446
+ serialized = parsed.to_xml
447
+
448
+ expect(serialized).to be_equivalent_to(xml_with_attribute)
449
+ end
450
+
451
+ it "parse and serialize model correctly with both attribute and element" do
452
+ parsed = XmlMapping::OwnedComment.from_xml(xml_with_same_name_attribute_and_element)
453
+ serialized = parsed.to_xml
454
+
455
+ expect(serialized).to be_equivalent_to(xml_with_same_name_attribute_and_element)
456
+ end
457
+
458
+ it "testing parse element" do
459
+ parsed = XmlMapping::Date.from_xml(xml)
460
+ serialized = parsed.to_xml
461
+
462
+ expect(serialized).to be_equivalent_to(xml)
463
+ end
464
+ end
465
+
362
466
  context "with same name elements" do
363
467
  let(:input_xml) do
364
468
  <<~XML
@@ -375,34 +479,38 @@ RSpec.describe Lutaml::Model::XmlMapping do
375
479
  end
376
480
 
377
481
  let(:expected_order) do
482
+ nokogiri_pattern = create_pattern_mapping([
483
+ ["Text", "text"],
484
+ ["Element", "ApplicationSchema"],
485
+ ["Text", "text"],
486
+ ["Element", "ApplicationSchema"],
487
+ ["Text", "text"],
488
+ ["Element", "ApplicationSchema"],
489
+ ["Text", "text"],
490
+ ])
491
+
492
+ oga_ox_pattern = create_pattern_mapping([
493
+ ["Element", "ApplicationSchema"],
494
+ ["Element", "ApplicationSchema"],
495
+ ["Element", "ApplicationSchema"],
496
+ ])
497
+
378
498
  {
379
- Lutaml::Model::XmlAdapter::NokogiriAdapter => [
380
- "text",
381
- "ApplicationSchema",
382
- "text",
383
- "ApplicationSchema",
384
- "text",
385
- "ApplicationSchema",
386
- "text",
387
- ],
388
- Lutaml::Model::XmlAdapter::OxAdapter => [
389
- "ApplicationSchema",
390
- "ApplicationSchema",
391
- "ApplicationSchema",
392
- ],
393
- Lutaml::Model::XmlAdapter::OgaAdapter => [
394
- "text",
395
- "ApplicationSchema",
396
- "text",
397
- "ApplicationSchema",
398
- "text",
399
- "ApplicationSchema",
400
- "text",
401
- ],
499
+ Lutaml::Model::XmlAdapter::NokogiriAdapter => nokogiri_pattern,
500
+ Lutaml::Model::XmlAdapter::OxAdapter => oga_ox_pattern,
501
+ Lutaml::Model::XmlAdapter::OgaAdapter => oga_ox_pattern,
402
502
  }
403
503
  end
404
504
 
405
- let(:parsed) { XmlMapping::SameNameDifferentNamespace.from_xml(input_xml) }
505
+ let(:parsed) do
506
+ XmlMapping::SameNameDifferentNamespace.from_xml(input_xml)
507
+ end
508
+
509
+ def create_pattern_mapping(array)
510
+ array.map do |type, text|
511
+ Lutaml::Model::XmlAdapter::Element.new(type, text)
512
+ end
513
+ end
406
514
 
407
515
  it "citygml_application_schema should be correct" do
408
516
  expect(parsed.citygml_application_schema).to eq("CityGML App")
@@ -550,7 +658,8 @@ RSpec.describe Lutaml::Model::XmlMapping do
550
658
 
551
659
  it "sets the namespace for individual elements" do
552
660
  expect(mapping.elements.size).to eq(3)
553
- expect(mapping.elements[0].namespace).to eq("https://example.com/ceramic/1.2")
661
+ expect(mapping.elements[0].namespace)
662
+ .to eq("https://example.com/ceramic/1.2")
554
663
  expect(mapping.elements[0].prefix).to eq("cera")
555
664
  expect(mapping.elements[1].delegate).to eq(:glaze)
556
665
  end
@@ -572,7 +681,8 @@ RSpec.describe Lutaml::Model::XmlMapping do
572
681
 
573
682
  it "sets the namespace for individual attributes" do
574
683
  expect(mapping.attributes.size).to eq(1)
575
- expect(mapping.attributes[0].namespace).to eq("https://example.com/ceramic/1.2")
684
+ expect(mapping.attributes[0].namespace)
685
+ .to eq("https://example.com/ceramic/1.2")
576
686
  expect(mapping.attributes[0].prefix).to eq("cera")
577
687
  end
578
688
  end
@@ -625,7 +735,7 @@ RSpec.describe Lutaml::Model::XmlMapping do
625
735
  error_regex = /\[Lutaml::Model\] WARN: `schemaLocation` is handled by default\. No need to explecitly define at `xml_mapping_spec.rb:\d+`/
626
736
 
627
737
  expect do
628
- Lutaml::Model::XmlMapping.new.map_attribute("schemaLocation", to: :schema_location)
738
+ mapping.map_attribute("schemaLocation", to: :schema_location)
629
739
  end.to output(error_regex).to_stderr
630
740
  end
631
741
  end
@@ -643,13 +753,32 @@ RSpec.describe Lutaml::Model::XmlMapping do
643
753
  XML
644
754
  end
645
755
 
756
+ let(:generated_xml) do
757
+ XmlMapping::SchemaLocationOrdered.from_xml(xml).to_xml
758
+ end
759
+
646
760
  it "contain schemaLocation attributes" do
647
- expect(XmlMapping::SchemaLocationOrdered.from_xml(xml).to_xml).to be_equivalent_to(xml)
761
+ expect(generated_xml).to be_equivalent_to(xml)
648
762
  end
649
763
  end
650
764
  end
651
765
 
652
766
  context "with multiple schemaLocations" do
767
+ let(:nested_schema_location) do
768
+ Lutaml::Model::SchemaLocation.new(
769
+ schema_location: "http://www.opengis.net/gml/3.7 http://schemas.opengis.net/gml/3.7.1/gml.xsd http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd",
770
+ prefix: "xsi",
771
+ namespace: "http://another-instance",
772
+ )
773
+ end
774
+
775
+ let(:schema_location) do
776
+ Lutaml::Model::SchemaLocation.new(
777
+ schema_location: "http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd",
778
+ prefix: "xsi",
779
+ )
780
+ end
781
+
653
782
  let(:xml) do
654
783
  <<~XML
655
784
  <p xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -662,60 +791,39 @@ RSpec.describe Lutaml::Model::XmlMapping do
662
791
  XML
663
792
  end
664
793
 
665
- it "parses and serializes multiple schemaLocation attributes" do
666
- parsed = Paragraph.from_xml(xml)
667
- expect(parsed.schema_location.size).to eq(2)
668
- expect(parsed.schema_location[0].namespace).to eq("http://www.opengis.net/gml/3.2")
669
- expect(parsed.schema_location[0].location).to eq("http://schemas.opengis.net/gml/3.2.1/gml.xsd")
670
- expect(parsed.schema_location[1].namespace).to eq("http://www.w3.org/1999/xlink")
671
- expect(parsed.schema_location[1].location).to eq("http://www.w3.org/1999/xlink.xsd")
794
+ context "when deserializing" do
795
+ let(:parsed) { Paragraph.from_xml(xml) }
672
796
 
673
- serialized = parsed.to_xml
674
- expect(serialized).to be_equivalent_to(xml)
675
- expect(serialized).to include('xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"')
676
- expect(serialized).to include('xsi:schemaLocation="http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd"')
677
- end
797
+ it "parses correctly" do
798
+ expect(parsed.schema_location.size).to eq(2)
799
+ expect(parsed.schema_location[0]).to eq(schema_location[0])
800
+ expect(parsed.schema_location[1]).to eq(schema_location[1])
801
+ end
678
802
 
679
- it "handles nested elements with different schemaLocations" do
680
- parsed = Paragraph.from_xml(xml)
681
- nested_p = parsed.paragraph
803
+ it "parses nested correctly" do
804
+ nested_p = parsed.paragraph
682
805
 
683
- expect(nested_p).to be_a(Paragraph)
684
- expect(nested_p.schema_location.size).to eq(2)
685
- expect(nested_p.schema_location[0].namespace).to eq("http://www.opengis.net/gml/3.7")
686
- expect(nested_p.schema_location[0].location).to eq("http://schemas.opengis.net/gml/3.7.1/gml.xsd")
687
- expect(nested_p.schema_location[1].namespace).to eq("http://www.isotc211.org/2005/gmd")
688
- expect(nested_p.schema_location[1].location).to eq("http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd")
806
+ expect(nested_p.schema_location.size).to eq(2)
807
+ expect(nested_p.schema_location[0]).to eq(nested_schema_location[0])
808
+ expect(nested_p.schema_location[1]).to eq(nested_schema_location[1])
809
+ end
810
+ end
689
811
 
690
- serialized = parsed.to_xml
691
- expect(serialized).to include('xmlns:xsi="http://another-instance"')
692
- expect(serialized).to include('xsi:schemaLocation="http://www.opengis.net/gml/3.7 http://schemas.opengis.net/gml/3.7.1/gml.xsd http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd"')
693
- end
694
-
695
- it "creates XML with multiple schemaLocations" do
696
- paragraph = Paragraph.new(
697
- schema_location: Lutaml::Model::SchemaLocation.new(
698
- schema_location: {
699
- "http://www.opengis.net/gml/3.2" => "http://schemas.opengis.net/gml/3.2.1/gml.xsd",
700
- "http://www.w3.org/1999/xlink" => "http://www.w3.org/1999/xlink.xsd",
701
- },
702
- prefix: "xsi",
703
- ),
704
- paragraph: Paragraph.new(
705
- schema_location: Lutaml::Model::SchemaLocation.new(
706
- schema_location: {
707
- "http://www.opengis.net/gml/3.7" => "http://schemas.opengis.net/gml/3.7.1/gml.xsd",
708
- "http://www.isotc211.org/2005/gmd" => "http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd",
709
- },
710
- prefix: "xsi",
711
- namespace: "http://another-instance",
812
+ context "when serializing" do
813
+ let(:paragraph) do
814
+ Paragraph.new(
815
+ schema_location: schema_location,
816
+ paragraph: Paragraph.new(
817
+ schema_location: nested_schema_location,
818
+ text: ["Some text inside paragraph"],
712
819
  ),
713
- text: ["Some text inside paragraph"],
714
- ),
715
- )
820
+ )
821
+ end
716
822
 
717
- serialized = paragraph.to_xml
718
- expect(serialized).to be_equivalent_to(xml)
823
+ it "creates XML with multiple schemaLocations" do
824
+ serialized = paragraph.to_xml
825
+ expect(serialized).to be_equivalent_to(xml)
826
+ end
719
827
  end
720
828
  end
721
829
 
@@ -736,10 +844,10 @@ RSpec.describe Lutaml::Model::XmlMapping do
736
844
  end
737
845
 
738
846
  let(:expected_street) do
739
- if Lutaml::Model::Config.xml_adapter == Lutaml::Model::XmlAdapter::OxAdapter
740
- "<a>N</a>\n<p>adf</p>\n"
741
- else
847
+ if Lutaml::Model::Config.xml_adapter == Lutaml::Model::XmlAdapter::NokogiriAdapter
742
848
  "\n <a>N</a>\n <p>adf</p>\n "
849
+ else
850
+ "<a>N</a><p>adf</p>"
743
851
  end
744
852
  end
745
853
 
@@ -789,6 +897,16 @@ RSpec.describe Lutaml::Model::XmlMapping do
789
897
  orig_mappings.deep_dup
790
898
  end
791
899
 
900
+ XmlMapping::WithMapAll.mappings_for(:xml).instance_variables.each do |var|
901
+ it "duplicates #{var} correctly" do
902
+ orig_mapping = XmlMapping::WithMapAll.mappings_for(:xml)
903
+ dup_mappings = orig_mapping.deep_dup
904
+
905
+ expect(orig_mapping.instance_variable_get(var))
906
+ .to eq(dup_mappings.instance_variable_get(var))
907
+ end
908
+ end
909
+
792
910
  it "duplicates root_element" do
793
911
  orig_root = orig_mappings.root_element
794
912
  dup_root = dup_mappings.root_element
@@ -802,7 +920,8 @@ RSpec.describe Lutaml::Model::XmlMapping do
802
920
  dup_namespace_uri = dup_mappings.namespace_uri
803
921
 
804
922
  expect(orig_namespace_uri).to eq(dup_namespace_uri)
805
- expect(orig_namespace_uri.object_id).not_to eq(dup_namespace_uri.object_id)
923
+ expect(orig_namespace_uri.object_id)
924
+ .not_to eq(dup_namespace_uri.object_id)
806
925
  end
807
926
 
808
927
  it "duplicates namespace_prefix" do
@@ -810,7 +929,8 @@ RSpec.describe Lutaml::Model::XmlMapping do
810
929
  dup_namespace_prefix = dup_mappings.namespace_prefix
811
930
 
812
931
  expect(orig_namespace_prefix).to eq(dup_namespace_prefix)
813
- expect(orig_namespace_prefix.object_id).not_to eq(dup_namespace_prefix.object_id)
932
+ expect(orig_namespace_prefix.object_id)
933
+ .not_to eq(dup_namespace_prefix.object_id)
814
934
  end
815
935
 
816
936
  context "when duplicating mapping" do
@@ -822,7 +942,8 @@ RSpec.describe Lutaml::Model::XmlMapping do
822
942
  dup_custom_methods = dup_mapping.custom_methods
823
943
 
824
944
  expect(orig_custom_methods).to eq(dup_custom_methods)
825
- expect(orig_custom_methods.object_id).not_to eq(dup_custom_methods.object_id)
945
+ expect(orig_custom_methods.object_id)
946
+ .not_to eq(dup_custom_methods.object_id)
826
947
  end
827
948
 
828
949
  it "duplicates default_namespace" do
@@ -830,7 +951,8 @@ RSpec.describe Lutaml::Model::XmlMapping do
830
951
  dup_default_namespace = dup_mapping.default_namespace
831
952
 
832
953
  expect(orig_default_namespace).to eq(dup_default_namespace)
833
- expect(orig_default_namespace.object_id).not_to eq(dup_default_namespace.object_id)
954
+ expect(orig_default_namespace.object_id)
955
+ .not_to eq(dup_default_namespace.object_id)
834
956
  end
835
957
 
836
958
  it "duplicates delegate" do
@@ -886,6 +1008,11 @@ RSpec.describe Lutaml::Model::XmlMapping do
886
1008
  # `to` is symbol which are constant so object_id will be same
887
1009
  expect(orig_mapping.to).to eq(dup_mapping.to)
888
1010
  end
1011
+
1012
+ it "duplicates attribute" do
1013
+ # boolean value is constant so object_id will be same
1014
+ expect(orig_mappings.attributes.first.attribute?).to eq(dup_mappings.attributes.first.attribute?)
1015
+ end
889
1016
  end
890
1017
  end
891
1018
 
@@ -957,7 +1084,11 @@ RSpec.describe Lutaml::Model::XmlMapping do
957
1084
  end
958
1085
 
959
1086
  it "maps all the content including tags" do
960
- inner_xml = "Str<sub>2</sub>text<sup>1</sup>123"
1087
+ inner_xml = if adapter_class.type == "ox"
1088
+ "Str<sub>2</sub> text<sup>1</sup> 123"
1089
+ else
1090
+ "Str<sub>2</sub>text<sup>1</sup>123"
1091
+ end
961
1092
  xml = "<WithMapAll>#{inner_xml}</WithMapAll>"
962
1093
 
963
1094
  parsed = XmlMapping::WithMapAll.from_xml(xml)
@@ -978,12 +1109,6 @@ RSpec.describe Lutaml::Model::XmlMapping do
978
1109
  DESCRIPTION
979
1110
  end
980
1111
 
981
- let(:expected_description) do
982
- <<~DESCRIPTION
983
- I'm a <b>web developer</b> with <strong>years</strong> of <i>experience</i> in many programing languages.
984
- DESCRIPTION
985
- end
986
-
987
1112
  let(:xml) do
988
1113
  <<~XML
989
1114
  <WithNestedMapAll age="23">
@@ -995,17 +1120,6 @@ RSpec.describe Lutaml::Model::XmlMapping do
995
1120
  XML
996
1121
  end
997
1122
 
998
- let(:expected_xml) do
999
- <<~XML
1000
- <WithNestedMapAll age="23">
1001
- <name>John Doe</name>
1002
- <description>
1003
- #{expected_description}
1004
- </description>
1005
- </WithNestedMapAll>
1006
- XML
1007
- end
1008
-
1009
1123
  let(:parsed) do
1010
1124
  XmlMapping::WithNestedMapAll.from_xml(xml)
1011
1125
  end
@@ -1023,7 +1137,7 @@ RSpec.describe Lutaml::Model::XmlMapping do
1023
1137
  end
1024
1138
 
1025
1139
  it "round-trips xml" do
1026
- expect(parsed.to_xml).to be_equivalent_to(expected_xml)
1140
+ expect(parsed.to_xml).to be_equivalent_to(xml)
1027
1141
  end
1028
1142
  end
1029
1143
 
@@ -1050,6 +1164,16 @@ RSpec.describe Lutaml::Model::XmlMapping do
1050
1164
  XML
1051
1165
  end
1052
1166
 
1167
+ let(:expected_oga_xml) do
1168
+ <<~XML.strip
1169
+ <SpecialCharContentWithMapAll>
1170
+ B <p>R&amp;C</p>
1171
+ C <p>J—C</p>
1172
+ O <p>A &amp; B </p>
1173
+ F <p>Z © </p></SpecialCharContentWithMapAll>
1174
+ XML
1175
+ end
1176
+
1053
1177
  let(:expected_ox_xml) do
1054
1178
  "<SpecialCharContentWithMapAll> " \
1055
1179
  "B <p>R&amp;C</p> " \
@@ -1059,9 +1183,19 @@ RSpec.describe Lutaml::Model::XmlMapping do
1059
1183
  "</SpecialCharContentWithMapAll>\n"
1060
1184
  end
1061
1185
 
1186
+ let(:expected_xml) do
1187
+ if adapter_class.type == "ox"
1188
+ expected_ox_xml
1189
+ elsif adapter_class.type == "oga"
1190
+ expected_oga_xml
1191
+ else
1192
+ expected_nokogiri_xml
1193
+ end
1194
+ end
1195
+
1062
1196
  it "round-trips xml" do
1063
- expected_xml = adapter_class.type == "ox" ? expected_ox_xml : expected_nokogiri_xml
1064
- expect(XmlMapping::SpecialCharContentWithMapAll.from_xml(xml).to_xml).to eq(expected_xml)
1197
+ parsed = XmlMapping::SpecialCharContentWithMapAll.from_xml(xml)
1198
+ expect(parsed.to_xml).to eq(expected_xml)
1065
1199
  end
1066
1200
  end
1067
1201
 
@@ -1074,8 +1208,12 @@ RSpec.describe Lutaml::Model::XmlMapping do
1074
1208
  XML
1075
1209
  end
1076
1210
 
1211
+ let(:generated_xml) do
1212
+ XmlMapping::Schema.from_xml(xml).to_xml
1213
+ end
1214
+
1077
1215
  it "round-trips xml" do
1078
- expect(XmlMapping::Schema.from_xml(xml).to_xml).to be_equivalent_to(xml)
1216
+ expect(generated_xml).to be_equivalent_to(xml)
1079
1217
  end
1080
1218
  end
1081
1219
  end