Skip to content

Commit

Permalink
fix: delegate issue for text element in xml
Browse files Browse the repository at this point in the history
  • Loading branch information
HassanAkbar authored and ronaldtse committed Sep 19, 2024
1 parent 93e7694 commit ac6faaa
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 7 deletions.
8 changes: 5 additions & 3 deletions lib/lutaml/model/mapping_rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ def serialize_attribute(model, element, doc)
end
end

def serialize(model, value)
def serialize(model, parent = nil, doc = nil)
if custom_methods[:to]
model.send(custom_methods[:to], model, value)
model.send(custom_methods[:to], model, parent, doc)
elsif delegate
model.public_send(delegate).public_send(to)
else
value
model.public_send(to)
end
end

Expand Down
19 changes: 19 additions & 0 deletions lib/lutaml/model/serialize.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,30 @@ def inherited(subclass)
def model(klass = nil)
if klass
@model = klass
add_order_handling_methods_to_model(klass)
else
@model
end
end

def add_order_handling_methods_to_model(klass)
Utils.add_method_if_not_defined(klass, :ordered=) do |ordered|
@ordered = ordered
end

Utils.add_method_if_not_defined(klass, :ordered?) do
!!@ordered
end

Utils.add_method_if_not_defined(klass, :element_order=) do |order|
@element_order = order
end

Utils.add_method_if_not_defined(klass, :element_order) do
@element_order
end
end

def cast(value)
value
end
Expand Down
8 changes: 8 additions & 0 deletions lib/lutaml/model/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ def blank?(value)
value.respond_to?(:empty?) ? value.empty? : !value
end

def add_method_if_not_defined(klass, method_name, &block)
unless klass.method_defined?(method_name)
klass.class_eval do
define_method(method_name, &block)
end
end
end

private

def camelize_part(part)
Expand Down
2 changes: 1 addition & 1 deletion lib/lutaml/model/xml_adapter/nokogiri_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def build_ordered_element(xml, element, options = {})
value = attribute_value_for(element, element_rule)

if element_rule == xml_mapping.content_mapping
text = element.send(xml_mapping.content_mapping.to)
text = xml_mapping.content_mapping.serialize(element)
text = text[curr_index] if text.is_a?(Array)

prefixed_xml.text text
Expand Down
2 changes: 1 addition & 1 deletion lib/lutaml/model/xml_adapter/xml_document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def build_unordered_element(xml, element, options = {})
@root.send(content_rule.custom_methods[:to], element,
prefixed_xml.parent, prefixed_xml)
else
text = element.send(content_rule.to)
text = content_rule.serialize(element)
text = text.join if text.is_a?(Array)
prefixed_xml.add_text(xml, text)
end
Expand Down
42 changes: 42 additions & 0 deletions spec/lutaml/model/custom_model_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,40 @@ def child_from_xml(model, value)
end
end

module CustomModelSpecs
class TextElement < Lutaml::Model::Serializable
attribute :sup, :string
attribute :sub, :string
attribute :text, :string

xml do
root "text-element"

map_content to: :text

map_element "sup", to: :sup
map_element "sub", to: :sub
end
end

class Id
attr_accessor :id
end

class Docid < Lutaml::Model::Serializable
model Id
attribute :id, TextElement

xml do
root "docid", mixed: true

map_content to: :text, delegate: :id
map_element :sub, to: :sub, delegate: :id
map_element :sup, to: :sup, delegate: :id
end
end
end

RSpec.describe "CustomModel" do
let(:parent_mapper) { CustomModelParentMapper }
let(:child_mapper) { CustomModelChildMapper }
Expand Down Expand Up @@ -272,6 +306,14 @@ def child_from_xml(model, value)
expect(instance.child_mapper.street).to eq("Custom Avenue")
expect(instance.child_mapper.city).to eq("New City")
end

it "uses delegate to for child mapper class" do
xml = "<docid>Str<sub>2</sub>text<sup>1</sup>123</docid>"

docid = CustomModelSpecs::Docid.from_xml(xml)

expect(CustomModelSpecs::Docid.to_xml(docid)).to eq(xml)
end
end
end
end
4 changes: 2 additions & 2 deletions spec/lutaml/model/serializable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ class GlazeTechnique < Lutaml::Model::Serializable
RSpec.describe Lutaml::Model::Serializable do
describe ".model" do
it "sets the model for the class" do
expect { described_class.model("Foo") }.to change(described_class, :model)
expect { described_class.model(TestModel) }.to change(described_class, :model)
.from(nil)
.to("Foo")
.to(TestModel)
end
end

Expand Down

0 comments on commit ac6faaa

Please sign in to comment.