lutaml-model 0.6.0 → 0.6.2
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.json +2 -1
- data/.rubocop_todo.yml +10 -80
- data/lib/lutaml/model/attribute.rb +9 -5
- data/lib/lutaml/model/schema/xml_compiler.rb +3 -1
- data/lib/lutaml/model/serialize.rb +6 -8
- data/lib/lutaml/model/type/float.rb +0 -4
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/xml_document.rb +0 -4
- data/lib/lutaml/model/xml_adapter/xml_element.rb +1 -3
- data/spec/address_spec.rb +3 -3
- data/spec/benchmarks/xml_parsing_benchmark_spec.rb +3 -3
- data/spec/lutaml/model/collection_spec.rb +0 -16
- data/spec/lutaml/model/custom_model_spec.rb +49 -1
- data/spec/lutaml/model/json_adapter_spec.rb +26 -24
- data/spec/lutaml/model/key_value_mapping_spec.rb +1 -13
- data/spec/lutaml/model/schema/json_schema_spec.rb +12 -12
- data/spec/lutaml/model/schema/relaxng_schema_spec.rb +12 -12
- data/spec/lutaml/model/schema/xml_compiler_spec.rb +447 -147
- data/spec/lutaml/model/schema/xsd_schema_spec.rb +12 -12
- data/spec/lutaml/model/schema/yaml_schema_spec.rb +12 -12
- data/spec/lutaml/model/sequence_spec.rb +129 -113
- data/spec/lutaml/model/toml_adapter_spec.rb +27 -25
- data/spec/lutaml/model/transformation_spec.rb +80 -80
- data/spec/lutaml/model/type/boolean_spec.rb +4 -10
- data/spec/lutaml/model/type/decimal_spec.rb +3 -3
- data/spec/lutaml/model/type/hash_spec.rb +39 -26
- data/spec/lutaml/model/type/integer_spec.rb +2 -2
- data/spec/lutaml/model/type/time_without_date_spec.rb +0 -6
- data/spec/lutaml/model/type_spec.rb +6 -26
- data/spec/lutaml/model/utils_spec.rb +25 -30
- data/spec/lutaml/model/validation_spec.rb +9 -6
- data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +2 -2
- data/spec/lutaml/model/xml_adapter/ox_adapter_spec.rb +2 -2
- data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +280 -281
- data/spec/lutaml/model/xml_adapter_spec.rb +128 -120
- data/spec/lutaml/model/xml_mapping_spec.rb +47 -16
- data/spec/person_spec.rb +6 -16
- metadata +2 -2
@@ -33,146 +33,154 @@ module XmlAdapterSpec
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
RSpec.
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
65
|
-
|
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
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
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 "
|
92
|
-
|
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
|
-
|
95
|
-
|
96
|
-
expect(
|
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 "
|
101
|
-
|
146
|
+
it "serializes to XML with only content" do
|
147
|
+
expected_xml = <<~XML
|
148
|
+
<Tag>
|
149
|
+
Bug
|
150
|
+
</Tag>
|
151
|
+
XML
|
102
152
|
|
103
|
-
|
104
|
-
|
105
|
-
expect(
|
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 "
|
110
|
-
|
111
|
-
<
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
-
|
121
|
-
|
122
|
-
|
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
|
-
|
127
|
-
|
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
|
-
|
140
|
-
|
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
|
-
|
152
|
-
|
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
|
-
|
1087
|
-
inner_xml
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
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
|
-
|
1119
|
+
let(:xml) do
|
1120
|
+
"<WithMapAll>#{inner_xml}</WithMapAll>"
|
1121
|
+
end
|
1095
1122
|
|
1096
|
-
|
1097
|
-
|
1123
|
+
let(:parsed) do
|
1124
|
+
XmlMapping::WithMapAll.from_xml(xml)
|
1125
|
+
end
|
1098
1126
|
|
1099
|
-
|
1100
|
-
|
1127
|
+
it "maps all the content including tags" do
|
1128
|
+
expect(parsed.all_content).to eq(inner_xml)
|
1129
|
+
end
|
1101
1130
|
|
1102
|
-
|
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
|
-
|
46
|
-
|
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
|
-
|
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.
|
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-
|
11
|
+
date: 2025-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: base64
|