lutaml-model 0.6.0 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/dependent-repos.json +2 -1
  3. data/.rubocop_todo.yml +10 -80
  4. data/lib/lutaml/model/attribute.rb +9 -5
  5. data/lib/lutaml/model/schema/xml_compiler.rb +3 -1
  6. data/lib/lutaml/model/serialize.rb +6 -8
  7. data/lib/lutaml/model/type/float.rb +0 -4
  8. data/lib/lutaml/model/version.rb +1 -1
  9. data/lib/lutaml/model/xml_adapter/xml_document.rb +0 -4
  10. data/lib/lutaml/model/xml_adapter/xml_element.rb +1 -3
  11. data/spec/address_spec.rb +3 -3
  12. data/spec/benchmarks/xml_parsing_benchmark_spec.rb +3 -3
  13. data/spec/lutaml/model/collection_spec.rb +0 -16
  14. data/spec/lutaml/model/custom_model_spec.rb +49 -1
  15. data/spec/lutaml/model/json_adapter_spec.rb +26 -24
  16. data/spec/lutaml/model/key_value_mapping_spec.rb +1 -13
  17. data/spec/lutaml/model/schema/json_schema_spec.rb +12 -12
  18. data/spec/lutaml/model/schema/relaxng_schema_spec.rb +12 -12
  19. data/spec/lutaml/model/schema/xml_compiler_spec.rb +447 -147
  20. data/spec/lutaml/model/schema/xsd_schema_spec.rb +12 -12
  21. data/spec/lutaml/model/schema/yaml_schema_spec.rb +12 -12
  22. data/spec/lutaml/model/sequence_spec.rb +129 -113
  23. data/spec/lutaml/model/toml_adapter_spec.rb +27 -25
  24. data/spec/lutaml/model/transformation_spec.rb +80 -80
  25. data/spec/lutaml/model/type/boolean_spec.rb +4 -10
  26. data/spec/lutaml/model/type/decimal_spec.rb +3 -3
  27. data/spec/lutaml/model/type/hash_spec.rb +39 -26
  28. data/spec/lutaml/model/type/integer_spec.rb +2 -2
  29. data/spec/lutaml/model/type/time_without_date_spec.rb +0 -6
  30. data/spec/lutaml/model/type_spec.rb +6 -26
  31. data/spec/lutaml/model/utils_spec.rb +25 -30
  32. data/spec/lutaml/model/validation_spec.rb +9 -6
  33. data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +2 -2
  34. data/spec/lutaml/model/xml_adapter/ox_adapter_spec.rb +2 -2
  35. data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +280 -281
  36. data/spec/lutaml/model/xml_adapter_spec.rb +128 -120
  37. data/spec/lutaml/model/xml_mapping_spec.rb +47 -16
  38. data/spec/person_spec.rb +6 -16
  39. metadata +2 -2
@@ -33,146 +33,154 @@ module XmlAdapterSpec
33
33
  end
34
34
  end
35
35
 
36
- RSpec.shared_examples "an XML adapter" do |adapter_class|
37
- around do |example|
38
- old_adapter = Lutaml::Model::Config.xml_adapter
39
- Lutaml::Model::Config.xml_adapter = adapter_class
40
-
41
- example.run
42
- ensure
43
- Lutaml::Model::Config.xml_adapter = old_adapter
44
- end
45
-
46
- before do
47
- # Ensure BigDecimal is loaded because it is being used in sample model
48
- require "bigdecimal"
49
- end
50
-
51
- let(:attributes) { { name: "John Doe", age: 30 } }
52
- let(:model) { SampleModel.new(attributes) }
53
-
54
- context "with default value" do
55
- it "set display attribute correctly, other attributes default" do
56
- xml = "<math display='true'></math>"
57
-
58
- parsed = XmlAdapterSpec::Maths.from_xml(xml)
59
- expect(parsed.display).to eq("true")
60
- expect(parsed.style.class).to eq(XmlAdapterSpec::Mstyle)
61
- expect(parsed.style.displaystyle).to eq("true")
36
+ RSpec.describe "XmlAdapter" do
37
+ shared_examples "an XML adapter" do |adapter_class|
38
+ around do |example|
39
+ old_adapter = Lutaml::Model::Config.xml_adapter
40
+ Lutaml::Model::Config.xml_adapter = adapter_class
41
+
42
+ example.run
43
+ ensure
44
+ Lutaml::Model::Config.xml_adapter = old_adapter
62
45
  end
63
46
 
64
- it "set style attribute correctly, other attributes default" do
65
- xml = "<math> <mstyle displaystyle='false'> </mstyle> </math>"
66
-
67
- parsed = XmlAdapterSpec::Maths.from_xml(xml)
68
- expect(parsed.display).to eq("block")
69
- expect(parsed.style.class).to eq(XmlAdapterSpec::Mstyle)
70
- expect(parsed.style.displaystyle).to eq("false")
71
- end
72
-
73
- it "sets attributes default values" do
74
- xml = "<math> </math>"
75
-
76
- parsed = XmlAdapterSpec::Maths.from_xml(xml)
77
- expect(parsed.display).to eq("block")
78
- expect(parsed.style.class).to eq(XmlAdapterSpec::Mstyle)
79
- expect(parsed.style.displaystyle).to eq("true")
47
+ before do
48
+ # Ensure BigDecimal is loaded because it is being used in sample model
49
+ require "bigdecimal"
80
50
  end
81
51
 
82
- it "delegate attributes with value" do
83
- xml = "<math color='blue' finish='no'></math>"
84
-
85
- parsed = XmlAdapterSpec::Maths.from_xml(xml)
86
- expect(parsed.style.color).to eq("blue")
87
- expect(parsed.style.finish).to eq("no")
88
- expect(parsed.style.displaystyle).to eq("true")
52
+ let(:attributes) { { name: "John Doe", age: 30 } }
53
+ let(:model) { SampleModel.new(attributes) }
54
+
55
+ context "with default value" do
56
+ it "set display attribute correctly, other attributes default" do
57
+ xml = "<math display='true'></math>"
58
+
59
+ parsed = XmlAdapterSpec::Maths.from_xml(xml)
60
+ expect(parsed.display).to eq("true")
61
+ expect(parsed.style.class).to eq(XmlAdapterSpec::Mstyle)
62
+ expect(parsed.style.displaystyle).to eq("true")
63
+ end
64
+
65
+ it "set style attribute correctly, other attributes default" do
66
+ xml = "<math> <mstyle displaystyle='false'> </mstyle> </math>"
67
+
68
+ parsed = XmlAdapterSpec::Maths.from_xml(xml)
69
+ expect(parsed.display).to eq("block")
70
+ expect(parsed.style.class).to eq(XmlAdapterSpec::Mstyle)
71
+ expect(parsed.style.displaystyle).to eq("false")
72
+ end
73
+
74
+ it "sets attributes default values" do
75
+ xml = "<math> </math>"
76
+
77
+ parsed = XmlAdapterSpec::Maths.from_xml(xml)
78
+ expect(parsed.display).to eq("block")
79
+ expect(parsed.style.class).to eq(XmlAdapterSpec::Mstyle)
80
+ expect(parsed.style.displaystyle).to eq("true")
81
+ end
82
+
83
+ it "delegate attributes with value" do
84
+ xml = "<math color='blue' finish='no'></math>"
85
+
86
+ parsed = XmlAdapterSpec::Maths.from_xml(xml)
87
+ expect(parsed.style.color).to eq("blue")
88
+ expect(parsed.style.finish).to eq("no")
89
+ expect(parsed.style.displaystyle).to eq("true")
90
+ end
91
+
92
+ it "delegate attributes with one value" do
93
+ xml = "<math color='blue'></math>"
94
+
95
+ parsed = XmlAdapterSpec::Maths.from_xml(xml)
96
+ expect(parsed.style.color).to eq("blue")
97
+ expect(parsed.style.finish).to eq("yes")
98
+ expect(parsed.style.displaystyle).to eq("true")
99
+ end
100
+
101
+ it "delegate attributes with no value" do
102
+ xml = "<math></math>"
103
+
104
+ parsed = XmlAdapterSpec::Maths.from_xml(xml)
105
+ expect(parsed.style.color).to be_nil
106
+ expect(parsed.style.finish).to eq("yes")
107
+ expect(parsed.style.displaystyle).to eq("true")
108
+ end
109
+
110
+ context "when round-trips" do
111
+ let(:parsed) do
112
+ XmlAdapterSpec::Maths.from_xml(xml)
113
+ end
114
+
115
+ let(:xml) do
116
+ "<math display='true'></math>"
117
+ end
118
+
119
+ let(:expected_xml) do
120
+ <<~XML
121
+ <math display="true" finish="yes">
122
+ <mstyle displaystyle="true"/>
123
+ </math>
124
+ XML
125
+ end
126
+
127
+ it "add default values" do
128
+ expect(parsed.to_xml.strip).to be_equivalent_to(expected_xml.strip)
129
+ end
130
+ end
89
131
  end
90
132
 
91
- it "delegate attributes with one value" do
92
- xml = "<math color='blue'></math>"
133
+ it "serializes to XML" do
134
+ expected_xml = <<~XML
135
+ <SampleModel>
136
+ <Name>John Doe</Name>
137
+ <Age>30</Age>
138
+ </SampleModel>
139
+ XML
93
140
 
94
- parsed = XmlAdapterSpec::Maths.from_xml(xml)
95
- expect(parsed.style.color).to eq("blue")
96
- expect(parsed.style.finish).to eq("yes")
97
- expect(parsed.style.displaystyle).to eq("true")
141
+ doc = adapter_class.parse(expected_xml)
142
+ xml = doc.to_xml
143
+ expect(xml).to be_equivalent_to(expected_xml)
98
144
  end
99
145
 
100
- it "delegate attributes with no value" do
101
- xml = "<math></math>"
146
+ it "serializes to XML with only content" do
147
+ expected_xml = <<~XML
148
+ <Tag>
149
+ Bug
150
+ </Tag>
151
+ XML
102
152
 
103
- parsed = XmlAdapterSpec::Maths.from_xml(xml)
104
- expect(parsed.style.color).to be_nil
105
- expect(parsed.style.finish).to eq("yes")
106
- expect(parsed.style.displaystyle).to eq("true")
153
+ doc = SampleModelTag.from_xml(expected_xml)
154
+ xml = doc.to_xml
155
+ expect(xml).to be_equivalent_to(expected_xml)
107
156
  end
108
157
 
109
- it "round-trips XML and add default values" do
110
- input_xml = <<~XML
111
- <math display='true'></math>
112
- XML
113
-
114
- output_xml = <<~XML
115
- <math display="true" finish="yes">
116
- <mstyle displaystyle="true"/>
117
- </math>
158
+ it "deserializes from XML" do
159
+ xml = <<~XML
160
+ <SampleModel>
161
+ <Name>John Doe</Name>
162
+ <Age>30</Age>
163
+ </SampleModel>
118
164
  XML
119
165
 
120
- parsed = XmlAdapterSpec::Maths.from_xml(input_xml)
121
-
122
- expect(parsed.to_xml.strip).to be_equivalent_to(output_xml.strip)
166
+ doc = adapter_class.parse(xml)
167
+ new_model = SampleModel.new(doc.root.children.to_h do |child|
168
+ [child.name.downcase.to_sym, child.text]
169
+ end)
170
+ expect(new_model.name).to eq("John Doe")
171
+ expect(new_model.age).to eq(30)
123
172
  end
124
173
  end
125
174
 
126
- it "serializes to XML" do
127
- expected_xml = <<~XML
128
- <SampleModel>
129
- <Name>John Doe</Name>
130
- <Age>30</Age>
131
- </SampleModel>
132
- XML
133
-
134
- doc = adapter_class.parse(expected_xml)
135
- xml = doc.to_xml
136
- expect(xml).to be_equivalent_to(expected_xml)
175
+ describe Lutaml::Model::XmlAdapter::NokogiriAdapter do
176
+ it_behaves_like "an XML adapter", described_class
137
177
  end
138
178
 
139
- it "serializes to XML with only content" do
140
- expected_xml = <<~XML
141
- <Tag>
142
- Bug
143
- </Tag>
144
- XML
145
-
146
- doc = SampleModelTag.from_xml(expected_xml)
147
- xml = doc.to_xml
148
- expect(xml).to be_equivalent_to(expected_xml)
179
+ describe Lutaml::Model::XmlAdapter::OxAdapter do
180
+ it_behaves_like "an XML adapter", described_class
149
181
  end
150
182
 
151
- it "deserializes from XML" do
152
- xml = <<~XML
153
- <SampleModel>
154
- <Name>John Doe</Name>
155
- <Age>30</Age>
156
- </SampleModel>
157
- XML
158
-
159
- doc = adapter_class.parse(xml)
160
- new_model = SampleModel.new(doc.root.children.to_h do |child|
161
- [child.name.downcase.to_sym, child.text]
162
- end)
163
- expect(new_model.name).to eq("John Doe")
164
- expect(new_model.age).to eq(30)
183
+ describe Lutaml::Model::XmlAdapter::OgaAdapter do
184
+ it_behaves_like "an XML adapter", described_class
165
185
  end
166
186
  end
167
-
168
- RSpec.describe Lutaml::Model::XmlAdapter::NokogiriAdapter do
169
- it_behaves_like "an XML adapter", described_class
170
- end
171
-
172
- RSpec.describe Lutaml::Model::XmlAdapter::OxAdapter do
173
- it_behaves_like "an XML adapter", described_class
174
- end
175
-
176
- RSpec.describe Lutaml::Model::XmlAdapter::OgaAdapter do
177
- it_behaves_like "an XML adapter", described_class
178
- end
@@ -57,6 +57,7 @@ module XmlMapping
57
57
  class Address < Lutaml::Model::Serializable
58
58
  attribute :street, ::Lutaml::Model::Type::String, raw: true
59
59
  attribute :city, :string, raw: true
60
+ attribute :text, :string
60
61
  attribute :address, Address
61
62
 
62
63
  xml do
@@ -64,6 +65,7 @@ module XmlMapping
64
65
 
65
66
  map_element "street", to: :street
66
67
  map_element "city", to: :city
68
+ map_element "text", to: :text
67
69
  end
68
70
  end
69
71
 
@@ -334,7 +336,7 @@ RSpec.describe Lutaml::Model::XmlMapping do
334
336
 
335
337
  let(:mapping) { Lutaml::Model::XmlMapping.new }
336
338
 
337
- context "attribute namespace" do
339
+ context "with attribute having namespace" do
338
340
  input_xml = <<~XML
339
341
  <ns1:example ex1:alpha="hello"
340
342
  beta="bye"
@@ -352,7 +354,7 @@ RSpec.describe Lutaml::Model::XmlMapping do
352
354
  end
353
355
  end
354
356
 
355
- context "explicit namespace" do
357
+ context "with explicit namespace" do
356
358
  mml = <<~XML
357
359
  <math xmlns="http://www.w3.org/1998/Math/MathML">
358
360
  <mfenced open="("></mfenced>
@@ -366,7 +368,7 @@ RSpec.describe Lutaml::Model::XmlMapping do
366
368
  end
367
369
 
368
370
  # Skipping for OX because it does not handle namespaces
369
- context "overriding child namespace prefix", skip: adapter_class == Lutaml::Model::XmlAdapter::OxAdapter do
371
+ context "when overriding child namespace prefix", skip: adapter_class == Lutaml::Model::XmlAdapter::OxAdapter do
370
372
  let(:input_xml) do
371
373
  <<~XML
372
374
  <OverrideDefaultNamespacePrefix
@@ -838,6 +840,7 @@ RSpec.describe Lutaml::Model::XmlMapping do
838
840
  <p>adf</p>
839
841
  </street>
840
842
  <city><a>M</a></city>
843
+ <text>Building near ABC</text>
841
844
  </address>
842
845
  </person>
843
846
  XML
@@ -859,6 +862,27 @@ RSpec.describe Lutaml::Model::XmlMapping do
859
862
  end
860
863
  end
861
864
 
865
+ context "with element named `text`" do
866
+ let(:input_xml) do
867
+ <<~XML
868
+ <address>
869
+ <street>
870
+ <a>N</a>
871
+ <p>adf</p>
872
+ </street>
873
+ <city><a>M</a></city>
874
+ <text>Building near ABC</text>
875
+ </address>
876
+ XML
877
+ end
878
+
879
+ let(:model) { XmlMapping::Address.from_xml(input_xml) }
880
+
881
+ it "expect to contain raw xml" do
882
+ expect(model.text).to eq("Building near ABC")
883
+ end
884
+ end
885
+
862
886
  context "with content mapping" do
863
887
  let(:xml_data) { "<i>my text <b>bold</b> is in italics</i>" }
864
888
  let(:italic) { Italic.from_xml(xml_data) }
@@ -1083,23 +1107,30 @@ RSpec.describe Lutaml::Model::XmlMapping do
1083
1107
  end
1084
1108
  end
1085
1109
 
1086
- it "maps all the content including tags" do
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
1092
- xml = "<WithMapAll>#{inner_xml}</WithMapAll>"
1110
+ context "without custom methods" do
1111
+ let(:inner_xml) do
1112
+ if adapter_class.type == "ox"
1113
+ "Str<sub>2</sub> text<sup>1</sup> 123"
1114
+ else
1115
+ "Str<sub>2</sub>text<sup>1</sup>123"
1116
+ end
1117
+ end
1093
1118
 
1094
- parsed = XmlMapping::WithMapAll.from_xml(xml)
1119
+ let(:xml) do
1120
+ "<WithMapAll>#{inner_xml}</WithMapAll>"
1121
+ end
1095
1122
 
1096
- expect(parsed.all_content).to eq(inner_xml)
1097
- end
1123
+ let(:parsed) do
1124
+ XmlMapping::WithMapAll.from_xml(xml)
1125
+ end
1098
1126
 
1099
- it "round-trips xml" do
1100
- xml = "<WithMapAll>Str<sub>2</sub>text<sup>1</sup>123</WithMapAll>"
1127
+ it "maps all the content including tags" do
1128
+ expect(parsed.all_content).to eq(inner_xml)
1129
+ end
1101
1130
 
1102
- expect(XmlMapping::WithMapAll.from_xml(xml).to_xml.chomp).to eq(xml)
1131
+ it "round-trips xml" do
1132
+ expect(parsed.to_xml.chomp).to eq(xml)
1133
+ end
1103
1134
  end
1104
1135
 
1105
1136
  context "when nested content has map_all" do
data/spec/person_spec.rb CHANGED
@@ -29,6 +29,7 @@ RSpec.describe Person do
29
29
  "active" => true,
30
30
  }
31
31
  end
32
+
32
33
  let(:attributes_json) do
33
34
  {
34
35
  firstName: "John",
@@ -42,8 +43,8 @@ RSpec.describe Person do
42
43
  }
43
44
  end
44
45
 
45
- it "serializes to XML" do
46
- expected_xml = <<~XML
46
+ let(:xml) do
47
+ <<~XML
47
48
  <p:Person xmlns:p="http://example.com/person" xmlns:nsp1="http://example.com/nsp1">
48
49
  <nsp1:FirstName>John</nsp1:FirstName>
49
50
  <nsp1:LastName>Doe</nsp1:LastName>
@@ -55,24 +56,13 @@ RSpec.describe Person do
55
56
  <p:Active>true</p:Active>
56
57
  </p:Person>
57
58
  XML
59
+ end
58
60
 
59
- expect(model.to_xml).to be_equivalent_to(expected_xml)
61
+ it "serializes to XML" do
62
+ expect(model.to_xml).to be_equivalent_to(xml)
60
63
  end
61
64
 
62
65
  it "deserializes from XML" do
63
- xml = <<~XML
64
- <p:Person xmlns:p="http://example.com/person" xmlns:nsp1="http://example.com/nsp1">
65
- <nsp1:FirstName>John</nsp1:FirstName>
66
- <nsp1:LastName>Doe</nsp1:LastName>
67
- <p:Age>30</p:Age>
68
- <p:Height>5.9</p:Height>
69
- <p:Birthdate>1990-01-01</p:Birthdate>
70
- <p:LastLogin>2023-06-08T10:00:00+00:00</p:LastLogin>
71
- <p:WakeupTime>07:00:00</p:WakeupTime>
72
- <p:Active>true</p:Active>
73
- </p:Person>
74
- XML
75
-
76
66
  person = described_class.from_xml(xml)
77
67
  expect(person.first_name).to eq("John")
78
68
  expect(person.age).to eq(30)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lutaml-model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-02-10 00:00:00.000000000 Z
11
+ date: 2025-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64