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.
- 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
|