require "spec_helper"
require "lutaml/model"
module Delegation
class Glaze < Lutaml::Model::Serializable
attribute :color, Lutaml::Model::Type::String
attribute :finish, Lutaml::Model::Type::String
end
class Ceramic < Lutaml::Model::Serializable
attribute :type, Lutaml::Model::Type::String
attribute :glaze, Glaze
json do
map "type", to: :type
map "color", to: :color, delegate: :glaze
map "finish", to: :finish, delegate: :glaze
end
yaml do
map "type", to: :type
map "color", to: :color, delegate: :glaze
map "finish", to: :finish, delegate: :glaze
end
toml do
map "type", to: :type
map "color", to: :color, delegate: :glaze
map "finish", to: :finish, delegate: :glaze
end
xml do
root "delegation"
map_element "type", to: :type
map_element "color", to: :color, delegate: :glaze
map_element "finish", to: :finish, delegate: :glaze
end
end
class NamespacedTypeCeramic < Lutaml::Model::Serializable
attribute :type, Lutaml::Model::Type::String
attribute :glaze, Glaze
yaml do
map "type", to: :type
map "color", to: :color, delegate: :glaze
map "finish", to: :finish, delegate: :glaze
end
xml do
root "delegation"
map_element "type",
to: :type,
namespace: "https://example.com/type/1.2",
prefix: "type"
map_element "color", to: :color, delegate: :glaze
map_element "finish", to: :finish, delegate: :glaze
end
end
end
RSpec.describe Delegation do
let(:yaml_data) do
<<~YAML
type: Vase
color: Blue
finish: Glossy
YAML
end
let(:delegation1) { Delegation::NamespacedTypeCeramic.from_yaml(yaml_data) }
let(:delegation) { Delegation::Ceramic.from_yaml(yaml_data) }
it "deserializes from YAML with delegation" do
expect(delegation.type).to eq("Vase")
expect(delegation.glaze.color).to eq("Blue")
expect(delegation.glaze.finish).to eq("Glossy")
end
it "serializes to YAML with delegation" do
expected_yaml = <<~YAML
---
type: Vase
color: Blue
finish: Glossy
YAML
expect(delegation.to_yaml.strip).to eq(expected_yaml.strip)
end
it "serializes to JSON with delegation and filtering" do
expected_json = {
type: "Vase",
color: "Blue",
}.to_json
generated_json = delegation.to_json(only: %i[type color])
expect(JSON.parse(generated_json)).to eq(JSON.parse(expected_json))
end
it "serializes to JSON with pretty formatting" do
expected_pretty_json = {
type: "Vase",
color: "Blue",
}.to_json
generated_json = delegation.to_json(only: %i[type color], pretty: true)
expect(generated_json.strip).to eq(expected_pretty_json.strip)
end
it "serializes to XML with pretty formatting" do
expected_pretty_xml = <<~XML
Vase
Blue
Glossy
XML
generated_xml = delegation.to_xml(pretty: true).strip
expect(generated_xml).to be_equivalent_to(expected_pretty_xml.strip)
end
it "does not provide XML declaration if no declaration option provided" do
xml_data = delegation.to_xml(pretty: true)
expect(xml_data).not_to include("')
end
it "provides XML declaration with specified version" \
"if declaration: '1.1' option provided" do
xml_data = delegation.to_xml(pretty: true, declaration: "1.1")
expect(xml_data).to include('')
end
it "provides XML declaration without encoding" \
"if encoding option not provided" do
xml_data = delegation.to_xml(pretty: true, declaration: true)
expect(xml_data).to include('')
expect(xml_data).not_to include("encoding=")
end
it "provides XML declaration with UTF-8 encoding" \
"if encoding: 'UTF-8' option provided" do
xml_data = delegation.to_xml(
pretty: true,
declaration: true,
encoding: "UTF-8",
)
expect(xml_data).to include('')
end
it "provides XML declaration with specified encoding" \
"if encoding: 'ASCII' option provided" do
xml_data = delegation.to_xml(
pretty: true,
declaration: true,
encoding: "ASCII",
)
expect(xml_data).to include('')
end
it "sets the namespace of a particular attribute inside " do
Delegation::Ceramic.class_eval do
attribute :date, Lutaml::Model::Type::Date
xml do
root "delegation"
map_attribute "date",
to: :date,
namespace: "https://example.com/delegation/1.2",
prefix: "del"
map_element "type", to: :type
map_element "color", to: :color, delegate: :glaze
map_element "finish", to: :finish, delegate: :glaze
end
end
delegation_class = Delegation::Ceramic
delegation = delegation_class.new(
type: "Vase",
glaze: Delegation::Glaze.new(
color: "Blue",
finish: "Glossy",
),
date: "2024-06-08",
)
xml_data = delegation.to_xml(
pretty: true,
declaration: true,
encoding: "UTF-8",
)
delegation_attributes = [
'xmlns:del="https://example.com/delegation/1.2"',
'del:date="2024-06-08"',
]
expect(xml_data).to include("")
end
it "sets the default namespace of " do
Delegation::Ceramic.class_eval do
xml do
root "delegation"
namespace "https://example.com/delegation/1.2"
map_element "type", to: :type
map_element "color", to: :color, delegate: :glaze
map_element "finish", to: :finish, delegate: :glaze
end
end
delegation_class = Delegation::Ceramic
delegation = delegation_class.from_yaml(yaml_data)
xml_data = delegation.to_xml(
pretty: true,
declaration: true,
encoding: "UTF-8",
)
expect(xml_data).to(
include(''),
)
end
it "sets the namespace of with a prefix" do
Delegation::Ceramic.class_eval do
xml do
root "delegation"
namespace "https://example.com/delegation/1.2", "del"
map_element "type", to: :type
map_element "color", to: :color, delegate: :glaze
map_element "finish", to: :finish, delegate: :glaze
end
end
delegation_class = Delegation::Ceramic
delegation = delegation_class.from_yaml(yaml_data)
xml_data = delegation.to_xml(
pretty: true,
declaration: true,
encoding: "UTF-8",
)
expect(xml_data).to(
include(
'',
),
)
end
it "sets the namespace of and also" \
"a particular element inside using :inherit" do
Delegation::Ceramic.class_eval do
xml do
root "delegation"
namespace "https://example.com/delegation/1.2", "del"
map_element "type", to: :type # , namespace: :inherit
map_element "color", to: :color, delegate: :glaze
map_element "finish", to: :finish, delegate: :glaze
end
end
delegation_class = Delegation::Ceramic
delegation = delegation_class.from_yaml(yaml_data)
xml_data = delegation.to_xml(
pretty: true,
declaration: true,
encoding: "UTF-8",
)
delegation_attribute = 'xmlns:del="https://example.com/delegation/1.2">'
expect(xml_data).to include("Vase")
end
it "sets the namespace of and also" \
"a particular attribute inside using :inherit" do
Delegation::Ceramic.class_eval do
attribute :date, Lutaml::Model::Type::Date
xml do
root "delegation"
namespace "https://example.com/delegation/1.1", "del1"
map_attribute "date",
to: :date,
namespace: "https://example.com/delegation/1.2",
prefix: "del2"
map_element "type", to: :type, namespace: :inherit
map_element "color", to: :color, delegate: :glaze
map_element "finish", to: :finish, delegate: :glaze
end
end
delegation_class = Delegation::Ceramic
delegation = delegation_class.new(
type: "Vase",
glaze: Delegation::Glaze.new(
color: "Blue",
finish: "Glossy",
),
date: "2024-06-08",
)
xml_data = delegation.to_xml(
pretty: true,
declaration: true,
encoding: "UTF-8",
)
delegation_attributes = [
'xmlns:del1="https://example.com/delegation/1.1"',
'xmlns:del2="https://example.com/delegation/1.2"',
'del2:date="2024-06-08"',
]
expect(xml_data).to include("")
expect(xml_data).to include("Vase")
end
it "sets the namespace of a particular element inside Ceramic" do
delegation1 = Delegation::NamespacedTypeCeramic.from_yaml(yaml_data)
xml_data = delegation1.to_xml(
pretty: true,
declaration: true,
encoding: "UTF-8",
)
expect(xml_data).to include('')
expect(xml_data).to include("Vase")
end
end