lutaml-model 0.3.23 → 0.3.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +35 -16
- data/README.adoc +274 -28
- data/lib/lutaml/model/attribute.rb +18 -8
- data/lib/lutaml/model/error/type_error.rb +9 -0
- data/lib/lutaml/model/error/unknown_type_error.rb +9 -0
- data/lib/lutaml/model/error/validation_error.rb +0 -1
- data/lib/lutaml/model/error.rb +2 -0
- data/lib/lutaml/model/serialize.rb +7 -2
- data/lib/lutaml/model/type/boolean.rb +38 -0
- data/lib/lutaml/model/type/date.rb +35 -0
- data/lib/lutaml/model/type/date_time.rb +32 -4
- data/lib/lutaml/model/type/decimal.rb +42 -0
- data/lib/lutaml/model/type/float.rb +37 -0
- data/lib/lutaml/model/type/hash.rb +62 -0
- data/lib/lutaml/model/type/integer.rb +41 -0
- data/lib/lutaml/model/type/string.rb +49 -0
- data/lib/lutaml/model/type/time.rb +49 -0
- data/lib/lutaml/model/type/time_without_date.rb +37 -5
- data/lib/lutaml/model/type/value.rb +52 -0
- data/lib/lutaml/model/type.rb +50 -114
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/builder/nokogiri.rb +5 -2
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +2 -1
- data/lib/lutaml/model/xml_adapter/xml_document.rb +0 -2
- data/lutaml-model.gemspec +1 -1
- data/spec/address_spec.rb +170 -0
- data/spec/fixtures/address.rb +33 -0
- data/spec/fixtures/person.rb +73 -0
- data/spec/fixtures/sample_model.rb +40 -0
- data/spec/fixtures/vase.rb +38 -0
- data/spec/fixtures/xml/special_char.xml +13 -0
- data/spec/lutaml/model/attribute_spec.rb +112 -0
- data/spec/lutaml/model/collection_spec.rb +299 -0
- data/spec/lutaml/model/comparable_model_spec.rb +106 -0
- data/spec/lutaml/model/custom_model_spec.rb +410 -0
- data/spec/lutaml/model/custom_serialization_spec.rb +170 -0
- data/spec/lutaml/model/defaults_spec.rb +221 -0
- data/spec/lutaml/model/delegation_spec.rb +340 -0
- data/spec/lutaml/model/inheritance_spec.rb +92 -0
- data/spec/lutaml/model/json_adapter_spec.rb +37 -0
- data/spec/lutaml/model/key_value_mapping_spec.rb +86 -0
- data/spec/lutaml/model/map_content_spec.rb +118 -0
- data/spec/lutaml/model/mixed_content_spec.rb +625 -0
- data/spec/lutaml/model/namespace_spec.rb +57 -0
- data/spec/lutaml/model/ordered_content_spec.rb +83 -0
- data/spec/lutaml/model/render_nil_spec.rb +138 -0
- data/spec/lutaml/model/schema/json_schema_spec.rb +79 -0
- data/spec/lutaml/model/schema/relaxng_schema_spec.rb +60 -0
- data/spec/lutaml/model/schema/xsd_schema_spec.rb +55 -0
- data/spec/lutaml/model/schema/yaml_schema_spec.rb +47 -0
- data/spec/lutaml/model/serializable_spec.rb +297 -0
- data/spec/lutaml/model/serializable_validation_spec.rb +85 -0
- data/spec/lutaml/model/simple_model_spec.rb +314 -0
- data/spec/lutaml/model/toml_adapter_spec.rb +39 -0
- data/spec/lutaml/model/type/boolean_spec.rb +54 -0
- data/spec/lutaml/model/type/date_spec.rb +118 -0
- data/spec/lutaml/model/type/date_time_spec.rb +127 -0
- data/spec/lutaml/model/type/decimal_spec.rb +125 -0
- data/spec/lutaml/model/type/float_spec.rb +191 -0
- data/spec/lutaml/model/type/hash_spec.rb +63 -0
- data/spec/lutaml/model/type/integer_spec.rb +145 -0
- data/spec/lutaml/model/type/string_spec.rb +150 -0
- data/spec/lutaml/model/type/time_spec.rb +142 -0
- data/spec/lutaml/model/type/time_without_date_spec.rb +125 -0
- data/spec/lutaml/model/type_spec.rb +276 -0
- data/spec/lutaml/model/utils_spec.rb +79 -0
- data/spec/lutaml/model/validation_spec.rb +83 -0
- data/spec/lutaml/model/with_child_mapping_spec.rb +174 -0
- data/spec/lutaml/model/xml_adapter/nokogiri_adapter_spec.rb +56 -0
- data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +56 -0
- data/spec/lutaml/model/xml_adapter/ox_adapter_spec.rb +61 -0
- data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +251 -0
- data/spec/lutaml/model/xml_adapter_spec.rb +178 -0
- data/spec/lutaml/model/xml_mapping_spec.rb +863 -0
- data/spec/lutaml/model/yaml_adapter_spec.rb +30 -0
- data/spec/lutaml/model_spec.rb +1 -0
- data/spec/person_spec.rb +161 -0
- data/spec/spec_helper.rb +33 -0
- metadata +66 -2
@@ -0,0 +1,83 @@
|
|
1
|
+
# spec/lutaml/model/ordered_content_spec.rb
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "lutaml/model"
|
5
|
+
require "lutaml/model/xml_adapter/nokogiri_adapter"
|
6
|
+
require "lutaml/model/xml_adapter/ox_adapter"
|
7
|
+
require "lutaml/model/xml_adapter/oga_adapter"
|
8
|
+
require_relative "../../fixtures/sample_model"
|
9
|
+
|
10
|
+
module OrderedContentSpec
|
11
|
+
class RootOrderedContent < Lutaml::Model::Serializable
|
12
|
+
attribute :id, :string
|
13
|
+
attribute :bold, :string, collection: true
|
14
|
+
attribute :italic, :string, collection: true
|
15
|
+
attribute :underline, :string
|
16
|
+
attribute :content, :string
|
17
|
+
|
18
|
+
xml do
|
19
|
+
root "RootOrderedContent", ordered: true
|
20
|
+
map_attribute :id, to: :id
|
21
|
+
map_element :bold, to: :bold
|
22
|
+
map_element :italic, to: :italic
|
23
|
+
map_element :underline, to: :underline
|
24
|
+
map_content to: :content
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
RSpec.describe "OrderedContent" do
|
30
|
+
shared_examples "ordered content behavior" do |adapter_class|
|
31
|
+
around do |example|
|
32
|
+
old_adapter = Lutaml::Model::Config.xml_adapter
|
33
|
+
Lutaml::Model::Config.xml_adapter = adapter_class
|
34
|
+
example.run
|
35
|
+
ensure
|
36
|
+
Lutaml::Model::Config.xml_adapter = old_adapter
|
37
|
+
end
|
38
|
+
|
39
|
+
context "when ordered: true is set at root" do
|
40
|
+
let(:xml) do
|
41
|
+
<<~XML
|
42
|
+
<RootOrderedContent id="123">
|
43
|
+
The Earth's Moon rings like a <bold>bell</bold> when struck by
|
44
|
+
meteroids. Distanced from the Earth by <italic>384,400 km</italic>,
|
45
|
+
its surface is covered in <underline>craters</underline>.
|
46
|
+
Ain't that <bold>cool</bold>?
|
47
|
+
</RootOrderedContent>
|
48
|
+
XML
|
49
|
+
end
|
50
|
+
|
51
|
+
let(:expected_xml) do
|
52
|
+
<<~XML
|
53
|
+
<RootOrderedContent id="123">
|
54
|
+
<bold>bell</bold>
|
55
|
+
<italic>384,400 km</italic>
|
56
|
+
<underline>craters</underline>
|
57
|
+
<bold>cool</bold>
|
58
|
+
The Earth's Moon rings like a when struck by
|
59
|
+
meteroids. Distanced from the Earth by ,
|
60
|
+
its surface is covered in . Ain't that ?
|
61
|
+
</RootOrderedContent>
|
62
|
+
XML
|
63
|
+
end
|
64
|
+
|
65
|
+
it "deserializes and serializes ordered content correctly" do
|
66
|
+
serialized = OrderedContentSpec::RootOrderedContent.from_xml(xml).to_xml
|
67
|
+
expect(serialized).to be_equivalent_to(expected_xml)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe Lutaml::Model::XmlAdapter::NokogiriAdapter do
|
73
|
+
it_behaves_like "ordered content behavior", described_class
|
74
|
+
end
|
75
|
+
|
76
|
+
describe Lutaml::Model::XmlAdapter::OxAdapter do
|
77
|
+
it_behaves_like "ordered content behavior", described_class
|
78
|
+
end
|
79
|
+
|
80
|
+
describe Lutaml::Model::XmlAdapter::OgaAdapter, skip: "Not implemented yet" do
|
81
|
+
it_behaves_like "ordered content behavior", described_class
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "lutaml/model"
|
3
|
+
|
4
|
+
class RenderNilNested < Lutaml::Model::Serializable
|
5
|
+
attribute :name, Lutaml::Model::Type::String
|
6
|
+
|
7
|
+
xml do
|
8
|
+
root "render_nil_nested"
|
9
|
+
|
10
|
+
map_element "name", to: :name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class RenderNil < Lutaml::Model::Serializable
|
15
|
+
attribute :name, Lutaml::Model::Type::String, default: -> {
|
16
|
+
"Unnamed Pottery"
|
17
|
+
}
|
18
|
+
attribute :clay_type, Lutaml::Model::Type::String
|
19
|
+
attribute :glaze, Lutaml::Model::Type::String
|
20
|
+
attribute :dimensions, Lutaml::Model::Type::String, collection: true
|
21
|
+
attribute :render_nil_nested, RenderNilNested
|
22
|
+
|
23
|
+
json do
|
24
|
+
map "name", to: :name, render_nil: true
|
25
|
+
map "clay_type", to: :clay_type, render_nil: true
|
26
|
+
map "glaze", to: :glaze, render_nil: true
|
27
|
+
map "dimensions", to: :dimensions, render_nil: false
|
28
|
+
end
|
29
|
+
|
30
|
+
xml do
|
31
|
+
root "render_nil"
|
32
|
+
map_element "name", to: :name, render_nil: true
|
33
|
+
map_element "clay_type", to: :clay_type, render_nil: false
|
34
|
+
map_element "glaze", to: :glaze, render_nil: true
|
35
|
+
map_element "render_nil_nested", to: :render_nil_nested, render_nil: true,
|
36
|
+
render_default: true
|
37
|
+
map_element "dimensions", to: :dimensions, render_nil: false
|
38
|
+
end
|
39
|
+
|
40
|
+
yaml do
|
41
|
+
map "name", to: :name, render_nil: true
|
42
|
+
map "clay_type", to: :clay_type, render_nil: false
|
43
|
+
map "glaze", to: :glaze, render_nil: true
|
44
|
+
map "dimensions", to: :dimensions, render_nil: false
|
45
|
+
end
|
46
|
+
|
47
|
+
toml do
|
48
|
+
map "name", to: :name, render_nil: true
|
49
|
+
map "clay_type", to: :clay_type, render_nil: false
|
50
|
+
map "glaze", to: :glaze, render_nil: true
|
51
|
+
map "dimensions", to: :dimensions, render_nil: false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
RSpec.describe RenderNil do
|
56
|
+
let(:attributes) do
|
57
|
+
{
|
58
|
+
name: nil,
|
59
|
+
clay_type: nil,
|
60
|
+
glaze: nil,
|
61
|
+
dimensions: nil,
|
62
|
+
}
|
63
|
+
end
|
64
|
+
let(:model) { described_class.new(attributes) }
|
65
|
+
|
66
|
+
it "serializes to JSON with render_nil option" do
|
67
|
+
expected_json = {
|
68
|
+
name: nil,
|
69
|
+
clay_type: nil,
|
70
|
+
glaze: nil,
|
71
|
+
dimensions: [],
|
72
|
+
}.to_json
|
73
|
+
|
74
|
+
expect(model.to_json).to eq(expected_json)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "deserializes from JSON with render_nil option" do
|
78
|
+
json = attributes.to_json
|
79
|
+
pottery = described_class.from_json(json)
|
80
|
+
expect(pottery.name).to be_nil
|
81
|
+
expect(pottery.clay_type).to be_nil
|
82
|
+
expect(pottery.glaze).to be_nil
|
83
|
+
expect(pottery.dimensions).to eq([])
|
84
|
+
end
|
85
|
+
|
86
|
+
it "serializes to XML with render_nil option" do
|
87
|
+
expected_xml = <<~XML
|
88
|
+
<render_nil>
|
89
|
+
<name/>
|
90
|
+
<glaze/>
|
91
|
+
<render_nil_nested/>
|
92
|
+
</render_nil>
|
93
|
+
XML
|
94
|
+
|
95
|
+
expect(model.to_xml).to be_equivalent_to(expected_xml)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "deserializes from XML with render_nil option" do
|
99
|
+
xml = <<~XML
|
100
|
+
<render_nil>
|
101
|
+
<name/>
|
102
|
+
<glaze/>
|
103
|
+
</render_nil>
|
104
|
+
XML
|
105
|
+
|
106
|
+
pottery = described_class.from_xml(xml)
|
107
|
+
expect(pottery.name).to be_nil
|
108
|
+
expect(pottery.glaze).to be_nil
|
109
|
+
end
|
110
|
+
|
111
|
+
it "serializes to YAML with render_nil option" do
|
112
|
+
expected_yaml = <<~YAML
|
113
|
+
---
|
114
|
+
name:
|
115
|
+
glaze:
|
116
|
+
dimensions: []
|
117
|
+
YAML
|
118
|
+
|
119
|
+
generated_yaml = model.to_yaml.strip
|
120
|
+
|
121
|
+
# Removing empty spaces from the end of the line because of and issue in
|
122
|
+
# libyaml -> https://github.com/yaml/libyaml/issues/46
|
123
|
+
generated_yaml = generated_yaml.gsub(": \n", ":\n")
|
124
|
+
|
125
|
+
expect(generated_yaml).to eq(expected_yaml.strip)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "deserializes from YAML with render_nil option" do
|
129
|
+
yaml = <<~YAML
|
130
|
+
---
|
131
|
+
glaze:
|
132
|
+
YAML
|
133
|
+
|
134
|
+
pottery = described_class.from_yaml(yaml)
|
135
|
+
expect(pottery.name).to eq("Unnamed Pottery")
|
136
|
+
expect(pottery.glaze).to be_nil
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "lutaml/model/schema"
|
3
|
+
|
4
|
+
RSpec.describe Lutaml::Model::Schema::JsonSchema do
|
5
|
+
module SchemaGeneration
|
6
|
+
class Glaze < Lutaml::Model::Serializable
|
7
|
+
attribute :color, Lutaml::Model::Type::String
|
8
|
+
attribute :finish, Lutaml::Model::Type::String
|
9
|
+
end
|
10
|
+
|
11
|
+
class Vase < Lutaml::Model::Serializable
|
12
|
+
attribute :height, Lutaml::Model::Type::Float
|
13
|
+
attribute :diameter, Lutaml::Model::Type::Float
|
14
|
+
attribute :glaze, Glaze
|
15
|
+
attribute :materials, Lutaml::Model::Type::String, collection: true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ".generate" do
|
20
|
+
it "generates a JSON schema for nested Serialize objects" do
|
21
|
+
schema = described_class.generate(SchemaGeneration::Vase,
|
22
|
+
id: "https://example.com/vase.schema.json", description: "A vase schema", pretty: true)
|
23
|
+
|
24
|
+
expected_schema = <<~JSON.chomp
|
25
|
+
{
|
26
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
27
|
+
"$id": "https://example.com/vase.schema.json",
|
28
|
+
"description": "A vase schema",
|
29
|
+
"$ref": "#/$defs/SchemaGeneration::Vase",
|
30
|
+
"$defs": {
|
31
|
+
"SchemaGeneration::Vase": {
|
32
|
+
"type": "object",
|
33
|
+
"properties": {
|
34
|
+
"height": {
|
35
|
+
"type": "number"
|
36
|
+
},
|
37
|
+
"diameter": {
|
38
|
+
"type": "number"
|
39
|
+
},
|
40
|
+
"glaze": {
|
41
|
+
"$ref": "#/$defs/SchemaGeneration::Glaze"
|
42
|
+
},
|
43
|
+
"materials": {
|
44
|
+
"type": "array",
|
45
|
+
"items": {
|
46
|
+
"type": "string"
|
47
|
+
}
|
48
|
+
}
|
49
|
+
},
|
50
|
+
"required": [
|
51
|
+
"height",
|
52
|
+
"diameter",
|
53
|
+
"glaze",
|
54
|
+
"materials"
|
55
|
+
]
|
56
|
+
},
|
57
|
+
"SchemaGeneration::Glaze": {
|
58
|
+
"type": "object",
|
59
|
+
"properties": {
|
60
|
+
"color": {
|
61
|
+
"type": "string"
|
62
|
+
},
|
63
|
+
"finish": {
|
64
|
+
"type": "string"
|
65
|
+
}
|
66
|
+
},
|
67
|
+
"required": [
|
68
|
+
"color",
|
69
|
+
"finish"
|
70
|
+
]
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
JSON
|
75
|
+
|
76
|
+
expect(schema).to eq(expected_schema)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "lutaml/model/schema"
|
3
|
+
|
4
|
+
RSpec.describe Lutaml::Model::Schema::RelaxngSchema do
|
5
|
+
module SchemaGeneration
|
6
|
+
class Glaze < Lutaml::Model::Serializable
|
7
|
+
attribute :color, Lutaml::Model::Type::String
|
8
|
+
attribute :finish, Lutaml::Model::Type::String
|
9
|
+
end
|
10
|
+
|
11
|
+
class Vase < Lutaml::Model::Serializable
|
12
|
+
attribute :height, Lutaml::Model::Type::Float
|
13
|
+
attribute :diameter, Lutaml::Model::Type::Float
|
14
|
+
attribute :glaze, Glaze
|
15
|
+
attribute :materials, Lutaml::Model::Type::String, collection: true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ".generate" do
|
20
|
+
it "generates a RELAX NG schema for nested Serialize objects" do
|
21
|
+
schema = described_class.generate(SchemaGeneration::Vase, pretty: true)
|
22
|
+
|
23
|
+
expected_schema = <<~RELAXNG
|
24
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
25
|
+
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
|
26
|
+
<start>
|
27
|
+
<ref name="SchemaGeneration::Vase"/>
|
28
|
+
</start>
|
29
|
+
<define name="SchemaGeneration::Vase">
|
30
|
+
<element name="SchemaGeneration::Vase">
|
31
|
+
<element name="height">
|
32
|
+
<data type="float"/>
|
33
|
+
</element>
|
34
|
+
<element name="diameter">
|
35
|
+
<data type="float"/>
|
36
|
+
</element>
|
37
|
+
<ref name="SchemaGeneration::Glaze"/>
|
38
|
+
<zeroOrMore>
|
39
|
+
<element name="materials">
|
40
|
+
<data type="string"/>
|
41
|
+
</element>
|
42
|
+
</zeroOrMore>
|
43
|
+
</element>
|
44
|
+
</define>
|
45
|
+
<define name="SchemaGeneration::Glaze">
|
46
|
+
<element name="SchemaGeneration::Glaze">
|
47
|
+
<element name="color">
|
48
|
+
<data type="string"/>
|
49
|
+
</element>
|
50
|
+
<element name="finish">
|
51
|
+
<data type="string"/>
|
52
|
+
</element>
|
53
|
+
</element>
|
54
|
+
</define>
|
55
|
+
</grammar>
|
56
|
+
RELAXNG
|
57
|
+
expect(schema).to eq(expected_schema)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "lutaml/model/schema"
|
3
|
+
|
4
|
+
RSpec.describe Lutaml::Model::Schema::XsdSchema do
|
5
|
+
module SchemaGeneration
|
6
|
+
class Glaze < Lutaml::Model::Serializable
|
7
|
+
attribute :color, Lutaml::Model::Type::String
|
8
|
+
attribute :finish, Lutaml::Model::Type::String
|
9
|
+
end
|
10
|
+
|
11
|
+
class Vase < Lutaml::Model::Serializable
|
12
|
+
attribute :height, Lutaml::Model::Type::Float
|
13
|
+
attribute :diameter, Lutaml::Model::Type::Float
|
14
|
+
attribute :glaze, Glaze
|
15
|
+
attribute :materials, Lutaml::Model::Type::String, collection: true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ".generate" do
|
20
|
+
it "generates an XSD schema for nested Serialize objects" do
|
21
|
+
schema = described_class.generate(SchemaGeneration::Vase, pretty: true)
|
22
|
+
|
23
|
+
expected_schema = <<~XSD
|
24
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
25
|
+
<schema xmlns="http://www.w3.org/2001/XMLSchema">
|
26
|
+
<element name="SchemaGeneration::Vase">
|
27
|
+
<complexType>
|
28
|
+
<sequence>
|
29
|
+
<element name="height" type="xs:float"/>
|
30
|
+
<element name="diameter" type="xs:float"/>
|
31
|
+
<element name="glaze">
|
32
|
+
<complexType>
|
33
|
+
<sequence>
|
34
|
+
<element name="color" type="xs:string"/>
|
35
|
+
<element name="finish" type="xs:string"/>
|
36
|
+
</sequence>
|
37
|
+
</complexType>
|
38
|
+
</element>
|
39
|
+
<element name="materials" minOccurs="0" maxOccurs="unbounded">
|
40
|
+
<complexType>
|
41
|
+
<sequence>
|
42
|
+
<element name="item" type="xs:string"/>
|
43
|
+
</sequence>
|
44
|
+
</complexType>
|
45
|
+
</element>
|
46
|
+
</sequence>
|
47
|
+
</complexType>
|
48
|
+
</element>
|
49
|
+
</schema>
|
50
|
+
XSD
|
51
|
+
|
52
|
+
expect(schema).to eq(expected_schema)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "lutaml/model/schema"
|
3
|
+
|
4
|
+
RSpec.describe Lutaml::Model::Schema::YamlSchema do
|
5
|
+
module SchemaGeneration
|
6
|
+
class Glaze < Lutaml::Model::Serializable
|
7
|
+
attribute :color, Lutaml::Model::Type::String
|
8
|
+
attribute :finish, Lutaml::Model::Type::String
|
9
|
+
end
|
10
|
+
|
11
|
+
class Vase < Lutaml::Model::Serializable
|
12
|
+
attribute :height, Lutaml::Model::Type::Float
|
13
|
+
attribute :diameter, Lutaml::Model::Type::Float
|
14
|
+
attribute :glaze, Glaze
|
15
|
+
attribute :materials, Lutaml::Model::Type::String, collection: true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ".generate" do
|
20
|
+
it "generates a YAML schema for nested Serialize objects" do
|
21
|
+
schema = described_class.generate(SchemaGeneration::Vase)
|
22
|
+
|
23
|
+
expected_schema = <<~YAML
|
24
|
+
---
|
25
|
+
type: map
|
26
|
+
mapping:
|
27
|
+
height:
|
28
|
+
type: float
|
29
|
+
diameter:
|
30
|
+
type: float
|
31
|
+
glaze:
|
32
|
+
type: map
|
33
|
+
mapping:
|
34
|
+
color:
|
35
|
+
type: str
|
36
|
+
finish:
|
37
|
+
type: str
|
38
|
+
materials:
|
39
|
+
type: seq
|
40
|
+
sequence:
|
41
|
+
- type: str
|
42
|
+
YAML
|
43
|
+
|
44
|
+
expect(schema).to eq(expected_schema)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|