lutaml-model 0.6.1 → 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 +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)
|