lutaml-model 0.6.1 → 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 +6 -1
- data/lib/lutaml/model/schema/xml_compiler.rb +3 -1
- 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/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 +23 -16
- data/spec/person_spec.rb +6 -16
- metadata +2 -2
@@ -17,31 +17,44 @@ RSpec.describe Lutaml::Model::Type::Hash do
|
|
17
17
|
expect(described_class.cast(mapping_hash)).to eq({ "key" => "value" })
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
"
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
"
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
20
|
+
context "with nested hashes" do
|
21
|
+
let(:input) do
|
22
|
+
{
|
23
|
+
"key1" => {
|
24
|
+
"text" => "content1",
|
25
|
+
"other" => "value1",
|
26
|
+
},
|
27
|
+
"key2" => {
|
28
|
+
"text" => "content2",
|
29
|
+
"other" => "value2",
|
30
|
+
},
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:expected_hash) do
|
35
|
+
{
|
36
|
+
"key1" => { "other" => "value1" },
|
37
|
+
"key2" => { "other" => "value2" },
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
it "filters out text keys from nested hashes" do
|
42
|
+
expect(described_class.cast(input)).to eq(expected_hash)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "with non-hash values" do
|
47
|
+
let(:input) do
|
48
|
+
{
|
49
|
+
"string" => "value",
|
50
|
+
"number" => 42,
|
51
|
+
"array" => [1, 2, 3],
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
it "preserves non-hash values" do
|
56
|
+
expect(described_class.cast(input)).to eq input
|
57
|
+
end
|
45
58
|
end
|
46
59
|
end
|
47
60
|
|
@@ -56,7 +69,7 @@ RSpec.describe Lutaml::Model::Type::Hash do
|
|
56
69
|
end
|
57
70
|
|
58
71
|
it "converts arbitrary object responding to to_h" do
|
59
|
-
obj =
|
72
|
+
obj = instance_double(Hash, to_h: { "key" => "value" })
|
60
73
|
expect(described_class.serialize(obj)).to eq({ "key" => "value" })
|
61
74
|
end
|
62
75
|
end
|
@@ -89,10 +89,10 @@ RSpec.describe Lutaml::Model::Type::Integer do
|
|
89
89
|
end
|
90
90
|
|
91
91
|
context "with very large integer" do
|
92
|
-
let(:max_value) { ((2**((0.size * 8) - 2))
|
92
|
+
let(:max_value) { ((2**((0.size * 8) - 2))) }
|
93
93
|
let(:value) { max_value.to_s }
|
94
94
|
|
95
|
-
|
95
|
+
it { is_expected.to eq(max_value) }
|
96
96
|
end
|
97
97
|
|
98
98
|
context "with very small integer" do
|
@@ -96,12 +96,6 @@ RSpec.describe Lutaml::Model::Type::TimeWithoutDate do
|
|
96
96
|
it { is_expected.to be_nil }
|
97
97
|
end
|
98
98
|
|
99
|
-
context "with Time object" do
|
100
|
-
let(:value) { Time.new(2024, 1, 1, 13, 45, 30) }
|
101
|
-
|
102
|
-
it { is_expected.to eq("13:45:30") }
|
103
|
-
end
|
104
|
-
|
105
99
|
context "with single-digit values" do
|
106
100
|
let(:value) { Time.new(2024, 1, 1, 9, 5, 3) }
|
107
101
|
|
@@ -191,12 +191,7 @@ RSpec.describe Lutaml::Model::Type do
|
|
191
191
|
|
192
192
|
context "when BigDecimal is not available" do
|
193
193
|
before do
|
194
|
-
|
195
|
-
$LOADED_FEATURES.delete_if { |path| path.include?("bigdecimal") }
|
196
|
-
end
|
197
|
-
|
198
|
-
after do
|
199
|
-
require "bigdecimal"
|
194
|
+
hide_const("BigDecimal") if defined?(BigDecimal)
|
200
195
|
end
|
201
196
|
|
202
197
|
let(:decimal_class) { described_class.lookup(:decimal) }
|
@@ -277,8 +272,8 @@ RSpec.describe Lutaml::Model::Type do
|
|
277
272
|
end
|
278
273
|
|
279
274
|
describe "Serialization" do
|
280
|
-
|
281
|
-
|
275
|
+
let(:xml) do
|
276
|
+
<<~XML
|
282
277
|
<test>
|
283
278
|
<string_symbol>test</string_symbol>
|
284
279
|
<string_class>test</string_class>
|
@@ -294,28 +289,13 @@ RSpec.describe Lutaml::Model::Type do
|
|
294
289
|
</hash>
|
295
290
|
</test>
|
296
291
|
XML
|
292
|
+
end
|
297
293
|
|
298
|
-
|
294
|
+
it "correctly serializes to XML" do
|
295
|
+
expect(test_instance.to_xml).to be_equivalent_to(xml)
|
299
296
|
end
|
300
297
|
|
301
298
|
it "correctly deserializes from XML" do
|
302
|
-
xml = <<~XML
|
303
|
-
<test>
|
304
|
-
<string_symbol>test</string_symbol>
|
305
|
-
<string_class>test</string_class>
|
306
|
-
<integer>123</integer>
|
307
|
-
<float>123.45</float>
|
308
|
-
<date>2024-01-01</date>
|
309
|
-
<time>12:00:00</time>
|
310
|
-
<time_without_date>10:06:15</time_without_date>
|
311
|
-
<date_time>2024-01-01T12:00:00</date_time>
|
312
|
-
<boolean>true</boolean>
|
313
|
-
<hash>
|
314
|
-
<key>value</key>
|
315
|
-
</hash>
|
316
|
-
</test>
|
317
|
-
XML
|
318
|
-
|
319
299
|
deserialized = TypeTestModel.from_xml(xml)
|
320
300
|
expect(deserialized.string_symbol).to eq("test")
|
321
301
|
expect(deserialized.string_class).to eq("test")
|
@@ -69,43 +69,38 @@ RSpec.describe Lutaml::Model::Utils do
|
|
69
69
|
let(:duplicate_array) { utils.deep_dup(original_array) }
|
70
70
|
|
71
71
|
it "creates deep duplicate of hash" do
|
72
|
-
expect(original_hash).to
|
73
|
-
expect(original_hash.object_id).not_to eq(duplicate_hash.object_id)
|
74
|
-
|
75
|
-
expect(original_hash[:one]).to eq(duplicate_hash[:one])
|
76
|
-
expect(original_hash[:one].object_id).not_to eq(duplicate_hash[:one].object_id)
|
77
|
-
|
78
|
-
expect(original_hash[:one][:one_one]).to eq(duplicate_hash[:one][:one_one])
|
79
|
-
expect(original_hash[:one][:one_one].object_id).not_to eq(duplicate_hash[:one][:one_one].object_id)
|
80
|
-
|
81
|
-
expect(original_hash[:one][:one_one][:one_one1]).to eq(duplicate_hash[:one][:one_one][:one_one1])
|
82
|
-
expect(original_hash[:one][:one_one][:one_one1].object_id).not_to eq(duplicate_hash[:one][:one_one][:one_one1].object_id)
|
83
|
-
|
84
|
-
# this is a symbol so the object_id will be same
|
85
|
-
expect(original_hash[:one][:one_one][:one_one2]).to eq(duplicate_hash[:one][:one_one][:one_one2])
|
86
|
-
|
87
|
-
expect(original_hash[:one][:one_two]).to eq(duplicate_hash[:one][:one_two])
|
88
|
-
expect(original_hash[:one][:one_two].object_id).not_to eq(duplicate_hash[:one][:one_two].object_id)
|
72
|
+
expect(compare_duplicate(original_hash, duplicate_hash)).to be_truthy
|
89
73
|
end
|
90
74
|
|
91
|
-
it "creates deep duplicate of array" do
|
92
|
-
expect(original_array).to
|
93
|
-
|
75
|
+
it "creates a deep duplicate of the array" do
|
76
|
+
expect(compare_duplicate(original_array, duplicate_array)).to be_truthy
|
77
|
+
end
|
94
78
|
|
95
|
-
|
96
|
-
|
79
|
+
def compare_duplicate(original, duplicate)
|
80
|
+
return false unless original == duplicate
|
81
|
+
return false if !primitive?(original) && original.equal?(duplicate)
|
97
82
|
|
98
|
-
|
99
|
-
|
83
|
+
case original
|
84
|
+
when Array then compare_array(original, duplicate)
|
85
|
+
when Hash then compare_hash(original, duplicate)
|
86
|
+
else true
|
87
|
+
end
|
88
|
+
end
|
100
89
|
|
101
|
-
|
102
|
-
|
90
|
+
def compare_array(original, duplicate)
|
91
|
+
original.each_with_index.all? do |el, i|
|
92
|
+
compare_duplicate(el, duplicate[i])
|
93
|
+
end
|
94
|
+
end
|
103
95
|
|
104
|
-
|
105
|
-
|
96
|
+
def compare_hash(original, duplicate)
|
97
|
+
original.keys.all? do |key|
|
98
|
+
compare_duplicate(original[key], duplicate[key])
|
99
|
+
end
|
100
|
+
end
|
106
101
|
|
107
|
-
|
108
|
-
|
102
|
+
def primitive?(value)
|
103
|
+
[Symbol, NilClass, TrueClass, FalseClass].include?(value.class)
|
109
104
|
end
|
110
105
|
end
|
111
106
|
end
|
@@ -3,12 +3,15 @@
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
5
|
RSpec.describe Lutaml::Model::Validation do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
before do
|
7
|
+
stub_const("ValidationTestClass", Class.new(Lutaml::Model::Serializable) do
|
8
|
+
attribute :name, :string
|
9
|
+
attribute :age, :integer
|
10
|
+
attribute :email, :string,
|
11
|
+
values: ["test@example.com", "user@example.com"]
|
12
|
+
attribute :tags, :string, collection: true
|
13
|
+
attribute :role, :string, collection: 1..3
|
14
|
+
end)
|
12
15
|
end
|
13
16
|
|
14
17
|
let(:valid_instance) do
|
@@ -13,7 +13,7 @@ RSpec.describe Lutaml::Model::XmlAdapter::OgaAdapter do
|
|
13
13
|
|
14
14
|
let(:document) { described_class.parse(xml_string) }
|
15
15
|
|
16
|
-
context "parsing XML with namespaces" do
|
16
|
+
context "when parsing XML with namespaces" do
|
17
17
|
let(:child) { document.root.children.first }
|
18
18
|
|
19
19
|
it "parses the root element with default namespace" do
|
@@ -37,7 +37,7 @@ RSpec.describe Lutaml::Model::XmlAdapter::OgaAdapter do
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
context "generating XML with namespaces" do
|
40
|
+
context "when generating XML with namespaces" do
|
41
41
|
it "generates XML with namespaces correctly" do
|
42
42
|
xml_output = document.root.to_xml
|
43
43
|
parsed_output = Moxml::Adapter::Oga.parse(xml_output)
|
@@ -14,7 +14,7 @@ RSpec.describe Lutaml::Model::XmlAdapter::OxAdapter do
|
|
14
14
|
|
15
15
|
let(:document) { described_class.parse(xml_string) }
|
16
16
|
|
17
|
-
context "parsing XML with namespaces" do
|
17
|
+
context "when parsing XML with namespaces" do
|
18
18
|
it "parses the root element with default namespace" do
|
19
19
|
expect(document.root.name).to eq("root")
|
20
20
|
expect(document.root.namespace.uri).to eq("http://example.com/default")
|
@@ -42,7 +42,7 @@ RSpec.describe Lutaml::Model::XmlAdapter::OxAdapter do
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
context "generating XML with namespaces" do
|
45
|
+
context "when generating XML with namespaces" do
|
46
46
|
it "generates XML with namespaces correctly" do
|
47
47
|
xml_output = document.to_xml
|
48
48
|
parsed_output = Ox.parse(xml_output)
|