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.
Files changed (37) 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 +6 -1
  5. data/lib/lutaml/model/schema/xml_compiler.rb +3 -1
  6. data/lib/lutaml/model/type/float.rb +0 -4
  7. data/lib/lutaml/model/version.rb +1 -1
  8. data/lib/lutaml/model/xml_adapter/xml_document.rb +0 -4
  9. data/lib/lutaml/model/xml_adapter/xml_element.rb +1 -3
  10. data/spec/address_spec.rb +3 -3
  11. data/spec/benchmarks/xml_parsing_benchmark_spec.rb +3 -3
  12. data/spec/lutaml/model/collection_spec.rb +0 -16
  13. data/spec/lutaml/model/json_adapter_spec.rb +26 -24
  14. data/spec/lutaml/model/key_value_mapping_spec.rb +1 -13
  15. data/spec/lutaml/model/schema/json_schema_spec.rb +12 -12
  16. data/spec/lutaml/model/schema/relaxng_schema_spec.rb +12 -12
  17. data/spec/lutaml/model/schema/xml_compiler_spec.rb +447 -147
  18. data/spec/lutaml/model/schema/xsd_schema_spec.rb +12 -12
  19. data/spec/lutaml/model/schema/yaml_schema_spec.rb +12 -12
  20. data/spec/lutaml/model/sequence_spec.rb +129 -113
  21. data/spec/lutaml/model/toml_adapter_spec.rb +27 -25
  22. data/spec/lutaml/model/transformation_spec.rb +80 -80
  23. data/spec/lutaml/model/type/boolean_spec.rb +4 -10
  24. data/spec/lutaml/model/type/decimal_spec.rb +3 -3
  25. data/spec/lutaml/model/type/hash_spec.rb +39 -26
  26. data/spec/lutaml/model/type/integer_spec.rb +2 -2
  27. data/spec/lutaml/model/type/time_without_date_spec.rb +0 -6
  28. data/spec/lutaml/model/type_spec.rb +6 -26
  29. data/spec/lutaml/model/utils_spec.rb +25 -30
  30. data/spec/lutaml/model/validation_spec.rb +9 -6
  31. data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +2 -2
  32. data/spec/lutaml/model/xml_adapter/ox_adapter_spec.rb +2 -2
  33. data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +280 -281
  34. data/spec/lutaml/model/xml_adapter_spec.rb +128 -120
  35. data/spec/lutaml/model/xml_mapping_spec.rb +23 -16
  36. data/spec/person_spec.rb +6 -16
  37. 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
- it "filters out text keys from nested hashes" do
21
- hash = {
22
- "key1" => {
23
- "text" => "content1",
24
- "other" => "value1",
25
- },
26
- "key2" => {
27
- "text" => "content2",
28
- "other" => "value2",
29
- },
30
- }
31
- expected = {
32
- "key1" => { "other" => "value1" },
33
- "key2" => { "other" => "value2" },
34
- }
35
- expect(described_class.cast(hash)).to eq expected
36
- end
37
-
38
- it "preserves non-hash values" do
39
- input = {
40
- "string" => "value",
41
- "number" => 42,
42
- "array" => [1, 2, 3],
43
- }
44
- expect(described_class.cast(input)).to eq input
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 = double(to_h: { "key" => "value" })
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)) - 1) }
92
+ let(:max_value) { ((2**((0.size * 8) - 2))) }
93
93
  let(:value) { max_value.to_s }
94
94
 
95
- xit { is_expected.to eq(max_value) }
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
- Object.send(:remove_const, :BigDecimal) if defined?(BigDecimal)
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
- it "correctly serializes to XML" do
281
- expected_xml = <<~XML
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
- expect(test_instance.to_xml).to be_equivalent_to(expected_xml)
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 eq(duplicate_hash)
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 eq(duplicate_array)
93
- expect(original_array.object_id).not_to eq(duplicate_array.object_id)
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
- expect(original_array[0]).to eq(duplicate_array[0])
96
- expect(original_array[0].object_id).not_to eq(duplicate_array[0].object_id)
79
+ def compare_duplicate(original, duplicate)
80
+ return false unless original == duplicate
81
+ return false if !primitive?(original) && original.equal?(duplicate)
97
82
 
98
- expect(original_array[1][0]).to eq(duplicate_array[1][0])
99
- expect(original_array[1][0].object_id).not_to eq(duplicate_array[1][0].object_id)
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
- expect(original_array[1][1][0]).to eq(duplicate_array[1][1][0])
102
- expect(original_array[1][1][0].object_id).not_to eq(duplicate_array[1][1][0].object_id)
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
- expect(original_array[1][1][1]).to eq(duplicate_array[1][1][1])
105
- expect(original_array[1][1][1].object_id).not_to eq(duplicate_array[1][1][1].object_id)
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
- expect(original_array[1][2]).to eq(duplicate_array[1][2])
108
- expect(original_array[1][2].object_id).not_to eq(duplicate_array[1][2].object_id)
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
- class ValidationTestClass < Lutaml::Model::Serializable
7
- attribute :name, :string
8
- attribute :age, :integer
9
- attribute :email, :string, values: ["test@example.com", "user@example.com"]
10
- attribute :tags, :string, collection: true
11
- attribute :role, :string, collection: 1..3
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)