lutaml-model 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/dependent-tests.yml +2 -0
  3. data/.rubocop_todo.yml +86 -23
  4. data/Gemfile +2 -0
  5. data/README.adoc +1441 -220
  6. data/lib/lutaml/model/attribute.rb +33 -10
  7. data/lib/lutaml/model/choice.rb +56 -0
  8. data/lib/lutaml/model/config.rb +1 -0
  9. data/lib/lutaml/model/constants.rb +7 -0
  10. data/lib/lutaml/model/error/choice_lower_bound_error.rb +9 -0
  11. data/lib/lutaml/model/error/choice_upper_bound_error.rb +9 -0
  12. data/lib/lutaml/model/error/import_model_with_root_error.rb +9 -0
  13. data/lib/lutaml/model/error/incorrect_sequence_error.rb +9 -0
  14. data/lib/lutaml/model/error/invalid_choice_range_error.rb +20 -0
  15. data/lib/lutaml/model/error/no_root_mapping_error.rb +9 -0
  16. data/lib/lutaml/model/error/no_root_namespace_error.rb +9 -0
  17. data/lib/lutaml/model/error/type/invalid_value_error.rb +19 -0
  18. data/lib/lutaml/model/error/unknown_sequence_mapping_error.rb +9 -0
  19. data/lib/lutaml/model/error.rb +9 -0
  20. data/lib/lutaml/model/json_adapter/standard_json_adapter.rb +6 -1
  21. data/lib/lutaml/model/key_value_mapping.rb +34 -3
  22. data/lib/lutaml/model/key_value_mapping_rule.rb +4 -2
  23. data/lib/lutaml/model/liquefiable.rb +59 -0
  24. data/lib/lutaml/model/mapping_hash.rb +9 -1
  25. data/lib/lutaml/model/mapping_rule.rb +19 -2
  26. data/lib/lutaml/model/schema/templates/simple_type.rb +247 -0
  27. data/lib/lutaml/model/schema/xml_compiler.rb +762 -0
  28. data/lib/lutaml/model/schema.rb +5 -0
  29. data/lib/lutaml/model/schema_location.rb +7 -0
  30. data/lib/lutaml/model/sequence.rb +71 -0
  31. data/lib/lutaml/model/serialize.rb +139 -33
  32. data/lib/lutaml/model/toml_adapter/toml_rb_adapter.rb +1 -2
  33. data/lib/lutaml/model/type/decimal.rb +0 -4
  34. data/lib/lutaml/model/type/hash.rb +11 -11
  35. data/lib/lutaml/model/type/time.rb +3 -3
  36. data/lib/lutaml/model/utils.rb +19 -15
  37. data/lib/lutaml/model/validation.rb +12 -1
  38. data/lib/lutaml/model/version.rb +1 -1
  39. data/lib/lutaml/model/xml_adapter/builder/oga.rb +10 -7
  40. data/lib/lutaml/model/xml_adapter/builder/ox.rb +20 -13
  41. data/lib/lutaml/model/xml_adapter/element.rb +32 -0
  42. data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +13 -9
  43. data/lib/lutaml/model/xml_adapter/oga/element.rb +14 -13
  44. data/lib/lutaml/model/xml_adapter/oga_adapter.rb +86 -19
  45. data/lib/lutaml/model/xml_adapter/ox_adapter.rb +19 -15
  46. data/lib/lutaml/model/xml_adapter/xml_document.rb +82 -25
  47. data/lib/lutaml/model/xml_adapter/xml_element.rb +57 -3
  48. data/lib/lutaml/model/xml_mapping.rb +53 -9
  49. data/lib/lutaml/model/xml_mapping_rule.rb +8 -6
  50. data/lib/lutaml/model.rb +2 -0
  51. data/lutaml-model.gemspec +5 -0
  52. data/spec/benchmarks/xml_parsing_benchmark_spec.rb +75 -0
  53. data/spec/ceramic_spec.rb +39 -0
  54. data/spec/fixtures/ceramic.rb +23 -0
  55. data/spec/fixtures/xml/address_example_260.xsd +9 -0
  56. data/spec/fixtures/xml/invalid_math_document.xml +4 -0
  57. data/spec/fixtures/xml/math_document_schema.xsd +56 -0
  58. data/spec/fixtures/xml/test_schema.xsd +53 -0
  59. data/spec/fixtures/xml/user.xsd +10 -0
  60. data/spec/fixtures/xml/valid_math_document.xml +4 -0
  61. data/spec/lutaml/model/cdata_spec.rb +4 -5
  62. data/spec/lutaml/model/choice_spec.rb +168 -0
  63. data/spec/lutaml/model/collection_spec.rb +1 -1
  64. data/spec/lutaml/model/custom_model_spec.rb +7 -21
  65. data/spec/lutaml/model/custom_serialization_spec.rb +74 -2
  66. data/spec/lutaml/model/defaults_spec.rb +3 -1
  67. data/spec/lutaml/model/delegation_spec.rb +7 -5
  68. data/spec/lutaml/model/enum_spec.rb +35 -0
  69. data/spec/lutaml/model/group_spec.rb +160 -0
  70. data/spec/lutaml/model/inheritance_spec.rb +25 -0
  71. data/spec/lutaml/model/key_value_mapping_spec.rb +27 -0
  72. data/spec/lutaml/model/liquefiable_spec.rb +121 -0
  73. data/spec/lutaml/model/map_all_spec.rb +188 -0
  74. data/spec/lutaml/model/mixed_content_spec.rb +95 -56
  75. data/spec/lutaml/model/multiple_mapping_spec.rb +22 -10
  76. data/spec/lutaml/model/schema/xml_compiler_spec.rb +1624 -0
  77. data/spec/lutaml/model/sequence_spec.rb +216 -0
  78. data/spec/lutaml/model/transformation_spec.rb +230 -0
  79. data/spec/lutaml/model/type_spec.rb +138 -31
  80. data/spec/lutaml/model/utils_spec.rb +32 -0
  81. data/spec/lutaml/model/with_child_mapping_spec.rb +2 -2
  82. data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +11 -7
  83. data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +52 -0
  84. data/spec/lutaml/model/xml_mapping_rule_spec.rb +51 -0
  85. data/spec/lutaml/model/xml_mapping_spec.rb +250 -112
  86. metadata +77 -2
@@ -341,7 +341,7 @@ RSpec.describe ChildMapping do
341
341
  actual = Lutaml::Model::Config.toml_adapter.parse(instance.to_toml)
342
342
  expected = Lutaml::Model::Config.toml_adapter.parse(toml)
343
343
 
344
- expect(actual.attributes).to eq(expected.attributes)
344
+ expect(actual).to eq(expected)
345
345
  end
346
346
 
347
347
  it "converts object to toml with nesting values" do
@@ -349,7 +349,7 @@ RSpec.describe ChildMapping do
349
349
  actual = Lutaml::Model::Config.toml_adapter.parse(instance.to_toml)
350
350
  expected = Lutaml::Model::Config.toml_adapter.parse(prefixes_toml)
351
351
 
352
- expect(actual.attributes).to eq(expected.attributes)
352
+ expect(actual).to eq(expected)
353
353
  end
354
354
  end
355
355
  end
@@ -14,7 +14,7 @@ RSpec.describe Lutaml::Model::XmlAdapter::OgaAdapter do
14
14
  let(:document) { described_class.parse(xml_string) }
15
15
 
16
16
  context "parsing XML with namespaces" do
17
- let(:child) { document.root.children[1] }
17
+ let(:child) { document.root.children.first }
18
18
 
19
19
  it "parses the root element with default namespace" do
20
20
  expect(document.root.name).to eq("root")
@@ -39,18 +39,22 @@ RSpec.describe Lutaml::Model::XmlAdapter::OgaAdapter do
39
39
 
40
40
  context "generating XML with namespaces" do
41
41
  it "generates XML with namespaces correctly" do
42
- xml_output = document.to_xml
43
- parsed_output = Oga.parse_xml(xml_output)
42
+ xml_output = document.root.to_xml
43
+ parsed_output = Moxml::Adapter::Oga.parse(xml_output)
44
44
 
45
45
  root = parsed_output.children.first
46
46
  expect(root.name).to eq("root")
47
47
  expect(root.namespace.uri).to eq("http://example.com/default")
48
48
 
49
- child = root.children[1]
50
- expect(child.expanded_name).to eq("prefix:child")
49
+ child = root.children.first
50
+ expect(described_class.prefixed_name_of(child)).to eq("prefix:child")
51
51
  expect(child.namespace.uri).to eq("http://example.com/prefixed")
52
- expect(child.get("attr")).to eq("value")
53
- expect(child.get("prefix:attr")).to eq("prefixed_value")
52
+ unprefixed_attr = child.attributes.find { |attr| attr.name == "attr" }
53
+ expect(unprefixed_attr.value).to eq("value")
54
+ prefixed_attr = child.attributes.find do |attr|
55
+ described_class.prefixed_name_of(attr) == "prefix:attr"
56
+ end
57
+ expect(prefixed_attr.value).to eq("prefixed_value")
54
58
  end
55
59
  end
56
60
  end
@@ -123,6 +123,20 @@ RSpec.shared_context "XML namespace models" do
123
123
  map_element "body", to: :body
124
124
  end
125
125
  end
126
+
127
+ class OwnedEnd < Lutaml::Model::Serializable
128
+ attribute :id, :string
129
+ attribute :type, :string
130
+ attribute :uml_type, :string
131
+
132
+ xml do
133
+ root "ownedEnd"
134
+
135
+ map_attribute "id", to: :id, namespace: "http://www.omg.org/spec/XMI/20131001", prefix: "xmi"
136
+ map_attribute "type", to: :type, namespace: "http://www.omg.org/spec/XMI/20131001", prefix: "xmi"
137
+ map_attribute "type", to: :uml_type
138
+ end
139
+ end
126
140
  end
127
141
 
128
142
  RSpec.shared_examples "XML serialization with namespace" do |model_class, xml_string|
@@ -302,6 +316,44 @@ RSpec.shared_examples "an XML namespace parser" do |adapter_class|
302
316
  end
303
317
  end
304
318
  end
319
+
320
+ context "when two attributes have same name but different prefix" do
321
+ let(:xml_input) do
322
+ <<~XML
323
+ <ownedEnd xmlns:xmi="http://www.omg.org/spec/XMI/20131001"
324
+ xmi:type="xmi_type"
325
+ xmi:id="my_id"
326
+ type="test" />
327
+ XML
328
+ end
329
+
330
+ describe "XML serialization" do
331
+ it "correctly deserializes from XML" do
332
+ owned_end = OwnedEnd.from_xml(xml_input)
333
+
334
+ expect(owned_end.id).to eq("my_id")
335
+ expect(owned_end.type).to eq("xmi_type")
336
+ expect(owned_end.uml_type).to eq("test")
337
+ end
338
+
339
+ it "correctly serializes to XML" do
340
+ owned_end = OwnedEnd.new(
341
+ id: "my_id",
342
+ type: "xmi_type",
343
+ uml_type: "test",
344
+ )
345
+
346
+ expect(owned_end.to_xml).to be_equivalent_to(xml_input)
347
+ end
348
+
349
+ it "round-trips XML" do
350
+ owned_end = OwnedEnd.from_xml(xml_input)
351
+ output_xml = owned_end.to_xml
352
+
353
+ expect(output_xml).to be_equivalent_to(xml_input)
354
+ end
355
+ end
356
+ end
305
357
  end
306
358
 
307
359
  RSpec.describe Lutaml::Model::XmlAdapter::NokogiriAdapter do
@@ -0,0 +1,51 @@
1
+ require "spec_helper"
2
+
3
+ require "lutaml/model/xml_adapter/ox_adapter"
4
+ require "lutaml/model/xml_adapter/oga_adapter"
5
+
6
+ require_relative "../../../lib/lutaml/model/xml_mapping_rule"
7
+
8
+ def content_to_xml(model, parent, doc)
9
+ content = model.all_content.sub(/^<div>/, "").sub(/<\/div>$/, "")
10
+ doc.add_xml_fragment(parent, content)
11
+ end
12
+
13
+ def content_from_xml(model, value)
14
+ model.all_content = "<div>#{value}</div>"
15
+ end
16
+
17
+ RSpec.describe Lutaml::Model::XmlMappingRule do
18
+ context "with Xml Mapping Rule" do
19
+ let(:orig_mapping_rule) do
20
+ described_class.new(
21
+ "name",
22
+ to: :name,
23
+ render_nil: true,
24
+ render_default: true,
25
+ with: { to: :content_to_xml, from: :content_from_xml },
26
+ delegate: true,
27
+ namespace: "http://child-namespace",
28
+ prefix: "cn",
29
+ mixed_content: true,
30
+ cdata: true,
31
+ namespace_set: true,
32
+ prefix_set: true,
33
+ attribute: true,
34
+ default_namespace: "http://parent-namespace",
35
+ )
36
+ end
37
+
38
+ let(:dup_mapping_rule) do
39
+ orig_mapping_rule.deep_dup
40
+ end
41
+
42
+ it "duplicates all instance variables" do
43
+ orig_mapping_rule.instance_variables.each do |variable|
44
+ orig_var = orig_mapping_rule.instance_variable_get(variable)
45
+ dup_var = dup_mapping_rule.instance_variable_get(variable)
46
+
47
+ expect(orig_var).to eq(dup_var)
48
+ end
49
+ end
50
+ end
51
+ end