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.
- checksums.yaml +4 -4
- data/.github/workflows/dependent-repos.json +2 -1
- data/.rubocop_todo.yml +10 -80
- data/lib/lutaml/model/attribute.rb +6 -1
- data/lib/lutaml/model/schema/xml_compiler.rb +3 -1
- data/lib/lutaml/model/type/float.rb +0 -4
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/xml_document.rb +0 -4
- data/lib/lutaml/model/xml_adapter/xml_element.rb +1 -3
- data/spec/address_spec.rb +3 -3
- data/spec/benchmarks/xml_parsing_benchmark_spec.rb +3 -3
- data/spec/lutaml/model/collection_spec.rb +0 -16
- data/spec/lutaml/model/json_adapter_spec.rb +26 -24
- data/spec/lutaml/model/key_value_mapping_spec.rb +1 -13
- data/spec/lutaml/model/schema/json_schema_spec.rb +12 -12
- data/spec/lutaml/model/schema/relaxng_schema_spec.rb +12 -12
- data/spec/lutaml/model/schema/xml_compiler_spec.rb +447 -147
- data/spec/lutaml/model/schema/xsd_schema_spec.rb +12 -12
- data/spec/lutaml/model/schema/yaml_schema_spec.rb +12 -12
- data/spec/lutaml/model/sequence_spec.rb +129 -113
- data/spec/lutaml/model/toml_adapter_spec.rb +27 -25
- data/spec/lutaml/model/transformation_spec.rb +80 -80
- data/spec/lutaml/model/type/boolean_spec.rb +4 -10
- data/spec/lutaml/model/type/decimal_spec.rb +3 -3
- data/spec/lutaml/model/type/hash_spec.rb +39 -26
- data/spec/lutaml/model/type/integer_spec.rb +2 -2
- data/spec/lutaml/model/type/time_without_date_spec.rb +0 -6
- data/spec/lutaml/model/type_spec.rb +6 -26
- data/spec/lutaml/model/utils_spec.rb +25 -30
- data/spec/lutaml/model/validation_spec.rb +9 -6
- data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +2 -2
- data/spec/lutaml/model/xml_adapter/ox_adapter_spec.rb +2 -2
- data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +280 -281
- data/spec/lutaml/model/xml_adapter_spec.rb +128 -120
- data/spec/lutaml/model/xml_mapping_spec.rb +23 -16
- data/spec/person_spec.rb +6 -16
- metadata +2 -2
@@ -1,21 +1,21 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
require "lutaml/model/schema"
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
4
|
+
module SchemaGeneration
|
5
|
+
class Glaze < Lutaml::Model::Serializable
|
6
|
+
attribute :color, Lutaml::Model::Type::String
|
7
|
+
attribute :finish, Lutaml::Model::Type::String
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
10
|
+
class Vase < Lutaml::Model::Serializable
|
11
|
+
attribute :height, Lutaml::Model::Type::Float
|
12
|
+
attribute :diameter, Lutaml::Model::Type::Float
|
13
|
+
attribute :glaze, Glaze
|
14
|
+
attribute :materials, Lutaml::Model::Type::String, collection: true
|
17
15
|
end
|
16
|
+
end
|
18
17
|
|
18
|
+
RSpec.describe Lutaml::Model::Schema::XsdSchema do
|
19
19
|
describe ".generate" do
|
20
20
|
it "generates an XSD schema for nested Serialize objects" do
|
21
21
|
schema = described_class.generate(SchemaGeneration::Vase, pretty: true)
|
@@ -1,21 +1,21 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
require "lutaml/model/schema"
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
4
|
+
module SchemaGeneration
|
5
|
+
class Glaze < Lutaml::Model::Serializable
|
6
|
+
attribute :color, Lutaml::Model::Type::String
|
7
|
+
attribute :finish, Lutaml::Model::Type::String
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
10
|
+
class Vase < Lutaml::Model::Serializable
|
11
|
+
attribute :height, Lutaml::Model::Type::Float
|
12
|
+
attribute :diameter, Lutaml::Model::Type::Float
|
13
|
+
attribute :glaze, Glaze
|
14
|
+
attribute :materials, Lutaml::Model::Type::String, collection: true
|
17
15
|
end
|
16
|
+
end
|
18
17
|
|
18
|
+
RSpec.describe Lutaml::Model::Schema::YamlSchema do
|
19
19
|
describe ".generate" do
|
20
20
|
it "generates a YAML schema for nested Serialize objects" do
|
21
21
|
schema = described_class.generate(SchemaGeneration::Vase)
|
@@ -56,45 +56,10 @@ RSpec.describe "Sequence" do
|
|
56
56
|
context "with nesting sequence" do
|
57
57
|
let(:mapper) { SequenceSpec::Ceramic }
|
58
58
|
|
59
|
-
|
60
|
-
xml
|
61
|
-
|
62
|
-
<
|
63
|
-
<id>1</id>
|
64
|
-
<name>Vase</name>
|
65
|
-
<type>Decorative</type>
|
66
|
-
<color>Blue</color>
|
67
|
-
<bold>Heading</bold>
|
68
|
-
<text>Header</text>
|
69
|
-
<usage>Indoor</usage>
|
70
|
-
<size>Medium</size>
|
71
|
-
<first_name>Dale</first_name>
|
72
|
-
<last_name>Steyn</last_name>
|
73
|
-
<temperature>Normal</temperature>
|
74
|
-
</Ceramic>
|
75
|
-
XML
|
76
|
-
|
77
|
-
expect { mapper.from_xml(xml) }.not_to raise_error
|
78
|
-
end
|
79
|
-
|
80
|
-
it "don't raise error for a valid instance with sequence range, if given attribute for sequence has correct order" do
|
81
|
-
xml = <<~XML
|
82
|
-
<collection>
|
83
|
-
<ceramic>
|
84
|
-
<tag>Nik</tag>
|
85
|
-
<id>1</id>
|
86
|
-
<name>Vase</name>
|
87
|
-
<type>Decorative</type>
|
88
|
-
<color>Blue</color>
|
89
|
-
<bold>Heading</bold>
|
90
|
-
<text>Header</text>
|
91
|
-
<usage>Indoor</usage>
|
92
|
-
<size>Medium</size>
|
93
|
-
<first_name>Dale</first_name>
|
94
|
-
<last_name>Steyn</last_name>
|
95
|
-
<temperature>Normal</temperature>
|
96
|
-
</ceramic>
|
97
|
-
<ceramic>
|
59
|
+
context "when given attribute for sequence has correct order" do
|
60
|
+
let(:xml) do
|
61
|
+
<<~XML
|
62
|
+
<Ceramic>
|
98
63
|
<tag>Nik</tag>
|
99
64
|
<id>1</id>
|
100
65
|
<name>Vase</name>
|
@@ -107,95 +72,146 @@ RSpec.describe "Sequence" do
|
|
107
72
|
<first_name>Dale</first_name>
|
108
73
|
<last_name>Steyn</last_name>
|
109
74
|
<temperature>Normal</temperature>
|
110
|
-
</
|
111
|
-
|
112
|
-
|
75
|
+
</Ceramic>
|
76
|
+
XML
|
77
|
+
end
|
113
78
|
|
114
|
-
|
115
|
-
|
116
|
-
end
|
79
|
+
it "does not raise error" do
|
80
|
+
expect { mapper.from_xml(xml) }.not_to raise_error
|
81
|
+
end
|
117
82
|
end
|
118
83
|
|
119
|
-
|
120
|
-
xml
|
121
|
-
|
122
|
-
<
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
84
|
+
context "when given attribute for sequence collection has correct order" do
|
85
|
+
let(:xml) do
|
86
|
+
<<~XML
|
87
|
+
<collection>
|
88
|
+
<ceramic>
|
89
|
+
<tag>Nik</tag>
|
90
|
+
<id>1</id>
|
91
|
+
<name>Vase</name>
|
92
|
+
<type>Decorative</type>
|
93
|
+
<color>Blue</color>
|
94
|
+
<bold>Heading</bold>
|
95
|
+
<text>Header</text>
|
96
|
+
<usage>Indoor</usage>
|
97
|
+
<size>Medium</size>
|
98
|
+
<first_name>Dale</first_name>
|
99
|
+
<last_name>Steyn</last_name>
|
100
|
+
<temperature>Normal</temperature>
|
101
|
+
</ceramic>
|
102
|
+
<ceramic>
|
103
|
+
<tag>Nik</tag>
|
104
|
+
<id>1</id>
|
105
|
+
<name>Vase</name>
|
106
|
+
<type>Decorative</type>
|
107
|
+
<color>Blue</color>
|
108
|
+
<bold>Heading</bold>
|
109
|
+
<text>Header</text>
|
110
|
+
<usage>Indoor</usage>
|
111
|
+
<size>Medium</size>
|
112
|
+
<first_name>Dale</first_name>
|
113
|
+
<last_name>Steyn</last_name>
|
114
|
+
<temperature>Normal</temperature>
|
115
|
+
</ceramic>
|
116
|
+
</collection>
|
117
|
+
XML
|
118
|
+
end
|
136
119
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
120
|
+
it "does not raise error" do
|
121
|
+
expect do
|
122
|
+
SequenceSpec::CeramicCollection.from_xml(xml)
|
123
|
+
end.not_to raise_error
|
141
124
|
end
|
142
125
|
end
|
143
126
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
<
|
127
|
+
context "when given attributes order is incorrect in sequence" do
|
128
|
+
let(:xml) do
|
129
|
+
<<~XML
|
130
|
+
<Ceramic>
|
131
|
+
<tag>Nik</tag>
|
132
|
+
<temperature>High</temperature>
|
133
|
+
<first_name>Micheal</first_name>
|
148
134
|
<id>1</id>
|
149
135
|
<name>Vase</name>
|
150
136
|
<type>Decorative</type>
|
151
137
|
<color>Blue</color>
|
152
138
|
<bold>Heading</bold>
|
153
|
-
<text>Header</text>
|
154
139
|
<usage>Indoor</usage>
|
155
140
|
<size>Medium</size>
|
156
|
-
<
|
157
|
-
<
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
<ceramic>
|
163
|
-
<id>2</id>
|
164
|
-
<name>Nick</name>
|
165
|
-
<type>Unique</type>
|
166
|
-
<color>Red</color>
|
167
|
-
<bold>Name</bold>
|
168
|
-
<text>Body</text>
|
169
|
-
<usage>Outdoor</usage>
|
170
|
-
<size>Small</size>
|
171
|
-
<first_name>Smith</first_name>
|
172
|
-
<last_name>Ash</last_name>
|
173
|
-
<temperature>High</temperature>
|
174
|
-
<tag>Adid</tag>
|
175
|
-
</ceramic>
|
176
|
-
|
177
|
-
<ceramic>
|
178
|
-
<id>3</id>
|
179
|
-
<name>Starc</name>
|
180
|
-
<type>Int</type>
|
181
|
-
<color>White</color>
|
182
|
-
<bold>Act</bold>
|
183
|
-
<text>Footer</text>
|
184
|
-
<usage>Nothing</usage>
|
185
|
-
<size>Large</size>
|
186
|
-
<first_name>Dale</first_name>
|
187
|
-
<last_name>Steyn</last_name>
|
188
|
-
<temperature>Normal</temperature>
|
189
|
-
<tag>Bet</tag>
|
190
|
-
</ceramic>
|
191
|
-
</collection>
|
192
|
-
XML
|
141
|
+
<last_name>Johnson</last_name>
|
142
|
+
<text>Header</text>
|
143
|
+
</Ceramic>
|
144
|
+
XML
|
145
|
+
end
|
193
146
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
147
|
+
it "raises IncorrectSequenceError error" do
|
148
|
+
expect do
|
149
|
+
mapper.from_xml(xml)
|
150
|
+
end.to raise_error(Lutaml::Model::IncorrectSequenceError) do |error|
|
151
|
+
expect(error.message).to eq("Element `usage` does not match the expected sequence order element `text`")
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context "when given attributes order is incorrect in sequence collection" do
|
157
|
+
let(:xml) do
|
158
|
+
<<~XML
|
159
|
+
<collection>
|
160
|
+
<ceramic>
|
161
|
+
<id>1</id>
|
162
|
+
<name>Vase</name>
|
163
|
+
<type>Decorative</type>
|
164
|
+
<color>Blue</color>
|
165
|
+
<bold>Heading</bold>
|
166
|
+
<text>Header</text>
|
167
|
+
<usage>Indoor</usage>
|
168
|
+
<size>Medium</size>
|
169
|
+
<first_name>Dale</first_name>
|
170
|
+
<last_name>Steyn</last_name>
|
171
|
+
<temperature>Normal</temperature>
|
172
|
+
<tag>Nik</tag>
|
173
|
+
</ceramic>
|
174
|
+
|
175
|
+
<ceramic>
|
176
|
+
<id>2</id>
|
177
|
+
<name>Nick</name>
|
178
|
+
<type>Unique</type>
|
179
|
+
<color>Red</color>
|
180
|
+
<bold>Name</bold>
|
181
|
+
<text>Body</text>
|
182
|
+
<usage>Outdoor</usage>
|
183
|
+
<size>Small</size>
|
184
|
+
<first_name>Smith</first_name>
|
185
|
+
<last_name>Ash</last_name>
|
186
|
+
<temperature>High</temperature>
|
187
|
+
<tag>Adid</tag>
|
188
|
+
</ceramic>
|
189
|
+
|
190
|
+
<ceramic>
|
191
|
+
<id>3</id>
|
192
|
+
<name>Starc</name>
|
193
|
+
<type>Int</type>
|
194
|
+
<color>White</color>
|
195
|
+
<bold>Act</bold>
|
196
|
+
<text>Footer</text>
|
197
|
+
<usage>Nothing</usage>
|
198
|
+
<size>Large</size>
|
199
|
+
<first_name>Dale</first_name>
|
200
|
+
<last_name>Steyn</last_name>
|
201
|
+
<temperature>Normal</temperature>
|
202
|
+
<tag>Bet</tag>
|
203
|
+
</ceramic>
|
204
|
+
</collection>
|
205
|
+
XML
|
206
|
+
end
|
207
|
+
|
208
|
+
it "raises CollectionCountOutOfRangeError error" do
|
209
|
+
expect do
|
210
|
+
SequenceSpec::CeramicCollection.from_xml(xml).validate!
|
211
|
+
end.to raise_error(Lutaml::Model::ValidationError) do |error|
|
212
|
+
expect(error).to include(Lutaml::Model::CollectionCountOutOfRangeError)
|
213
|
+
expect(error.error_messages).to eq(["ceramic count is 3, must be between 1 and 2"])
|
214
|
+
end
|
199
215
|
end
|
200
216
|
end
|
201
217
|
|
@@ -3,37 +3,39 @@ require "lutaml/model/toml_adapter/toml_rb_adapter"
|
|
3
3
|
require "lutaml/model/toml_adapter/tomlib_adapter"
|
4
4
|
require_relative "../../fixtures/sample_model"
|
5
5
|
|
6
|
-
RSpec.
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
6
|
+
RSpec.describe "TomlAdapter" do
|
7
|
+
shared_examples "a TOML adapter" do |adapter_class|
|
8
|
+
let(:attributes) { { name: "John Doe", age: 30 } }
|
9
|
+
let(:model) { SampleModel.new(attributes) }
|
10
|
+
|
11
|
+
let(:expected_toml) do
|
12
|
+
if adapter_class == Lutaml::Model::TomlAdapter::TomlRbAdapter
|
13
|
+
TomlRB.dump(attributes)
|
14
|
+
elsif adapter_class == Lutaml::Model::TomlAdapter::TomlibAdapter
|
15
|
+
Tomlib.dump(attributes)
|
16
|
+
end
|
15
17
|
end
|
16
|
-
end
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
it "serializes to TOML" do
|
20
|
+
toml = adapter_class.new(attributes).to_toml
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
expect(toml).to eq(expected_toml)
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
it "deserializes from TOML" do
|
26
|
+
doc = adapter_class.parse(expected_toml)
|
27
|
+
new_model = SampleModel.new(doc.to_h)
|
27
28
|
|
28
|
-
|
29
|
-
|
29
|
+
expect(new_model.name).to eq("John Doe")
|
30
|
+
expect(new_model.age).to eq(30)
|
31
|
+
end
|
30
32
|
end
|
31
|
-
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
end
|
34
|
+
describe Lutaml::Model::TomlAdapter::TomlRbAdapter do
|
35
|
+
it_behaves_like "a TOML adapter", described_class
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
38
|
+
describe Lutaml::Model::TomlAdapter::TomlibAdapter do
|
39
|
+
it_behaves_like "a TOML adapter", described_class
|
40
|
+
end
|
39
41
|
end
|
@@ -1,97 +1,97 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
module TransformationSpec
|
4
|
+
# Class with only attribute-level transformations
|
5
|
+
class AttributeTransformPerson < Lutaml::Model::Serializable
|
6
|
+
attribute :name, :string, transform: {
|
7
|
+
export: ->(value) { value.to_s.upcase },
|
8
|
+
}
|
9
|
+
attribute :email, :string, transform: {
|
10
|
+
import: ->(value) { "#{value}@example.com" },
|
11
|
+
}
|
12
|
+
attribute :tags, :string, collection: true, transform: {
|
13
|
+
export: ->(value) { value.map(&:upcase) },
|
14
|
+
import: ->(value) { value.map { |v| "#{v}-1" } },
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
# Class with only mapping-level transformations
|
19
|
+
class MappingTransformPerson < Lutaml::Model::Serializable
|
20
|
+
attribute :name, :string
|
21
|
+
attribute :email, :string
|
22
|
+
attribute :tags, :string, collection: true
|
23
|
+
|
24
|
+
json do
|
25
|
+
map "fullName", to: :name, transform: {
|
26
|
+
export: ->(value) { "Dr. #{value}" },
|
9
27
|
}
|
10
|
-
|
11
|
-
import: ->(value) {
|
28
|
+
map "emailAddress", to: :email, transform: {
|
29
|
+
import: ->(value) { value.gsub("at", "@") },
|
12
30
|
}
|
13
|
-
|
14
|
-
export: ->(value) { value.
|
15
|
-
import: ->(value) { value.
|
31
|
+
map "labels", to: :tags, transform: {
|
32
|
+
export: ->(value) { value.join("-|-") },
|
33
|
+
import: ->(value) { value.split("|") },
|
16
34
|
}
|
17
35
|
end
|
18
36
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
attribute :tags, :string, collection: true
|
24
|
-
|
25
|
-
json do
|
26
|
-
map "fullName", to: :name, transform: {
|
27
|
-
export: ->(value) { "Dr. #{value}" },
|
28
|
-
}
|
29
|
-
map "emailAddress", to: :email, transform: {
|
30
|
-
import: ->(value) { value.gsub("at", "@") },
|
31
|
-
}
|
32
|
-
map "labels", to: :tags, transform: {
|
33
|
-
export: ->(value) { value.join("-|-") },
|
34
|
-
import: ->(value) { value.split("|") },
|
35
|
-
}
|
36
|
-
end
|
37
|
-
|
38
|
-
xml do
|
39
|
-
root "person"
|
40
|
-
map_element "full-name", to: :name, transform: {
|
41
|
-
export: ->(value) { "Dr. #{value}" },
|
42
|
-
}
|
43
|
-
map_element "email-address", to: :email, transform: {
|
44
|
-
import: ->(value) { value.gsub("at", "@") },
|
45
|
-
}
|
46
|
-
map_element "labels", to: :tags, transform: {
|
47
|
-
export: ->(value) { value.join("-|-") },
|
48
|
-
import: ->(value) { value.split("|") },
|
49
|
-
}
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# Class with both attribute and mapping transformations
|
54
|
-
class CombinedTransformPerson < Lutaml::Model::Serializable
|
55
|
-
attribute :name, :string, transform: {
|
56
|
-
export: ->(value) { value.to_s.capitalize },
|
57
|
-
import: ->(value) { value.to_s.downcase },
|
37
|
+
xml do
|
38
|
+
root "person"
|
39
|
+
map_element "full-name", to: :name, transform: {
|
40
|
+
export: ->(value) { "Dr. #{value}" },
|
58
41
|
}
|
59
|
-
|
60
|
-
|
61
|
-
|
42
|
+
map_element "email-address", to: :email, transform: {
|
43
|
+
import: ->(value) { value.gsub("at", "@") },
|
44
|
+
}
|
45
|
+
map_element "labels", to: :tags, transform: {
|
46
|
+
export: ->(value) { value.join("-|-") },
|
47
|
+
import: ->(value) { value.split("|") },
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Class with both attribute and mapping transformations
|
53
|
+
class CombinedTransformPerson < Lutaml::Model::Serializable
|
54
|
+
attribute :name, :string, transform: {
|
55
|
+
export: ->(value) { value.to_s.capitalize },
|
56
|
+
import: ->(value) { value.to_s.downcase },
|
57
|
+
}
|
58
|
+
attribute :email, :string, transform: {
|
59
|
+
export: lambda(&:downcase),
|
60
|
+
import: lambda(&:downcase),
|
61
|
+
}
|
62
|
+
attribute :tags, :string, collection: true, transform: {
|
63
|
+
export: ->(value) { value.map(&:upcase) },
|
64
|
+
import: ->(value) { value.map { |v| "#{v}-1" } },
|
65
|
+
}
|
66
|
+
|
67
|
+
json do
|
68
|
+
map "fullName", to: :name, transform: {
|
69
|
+
export: ->(value) { "Prof. #{value}" },
|
70
|
+
import: ->(value) { value.gsub("Prof. ", "") },
|
62
71
|
}
|
63
|
-
|
64
|
-
export: ->(value) { value
|
65
|
-
import: ->(value) { value.
|
72
|
+
map "contactEmail", to: :email, transform: {
|
73
|
+
export: ->(value) { "contact+#{value}" },
|
74
|
+
import: ->(value) { value.gsub("contact+", "") },
|
66
75
|
}
|
76
|
+
map "skills", to: :tags
|
77
|
+
end
|
67
78
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
}
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
}
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
xml do
|
81
|
-
root "person"
|
82
|
-
map_element "full-name", to: :name, transform: {
|
83
|
-
export: ->(value) { "Prof. #{value}" },
|
84
|
-
import: ->(value) { value.gsub("Prof. ", "") },
|
85
|
-
}
|
86
|
-
map_element "contact-email", to: :email, transform: {
|
87
|
-
export: ->(value) { "contact+#{value}" },
|
88
|
-
import: ->(value) { value.gsub("contact+", "") },
|
89
|
-
}
|
90
|
-
map_element "skills", to: :tags
|
91
|
-
end
|
79
|
+
xml do
|
80
|
+
root "person"
|
81
|
+
map_element "full-name", to: :name, transform: {
|
82
|
+
export: ->(value) { "Prof. #{value}" },
|
83
|
+
import: ->(value) { value.gsub("Prof. ", "") },
|
84
|
+
}
|
85
|
+
map_element "contact-email", to: :email, transform: {
|
86
|
+
export: ->(value) { "contact+#{value}" },
|
87
|
+
import: ->(value) { value.gsub("contact+", "") },
|
88
|
+
}
|
89
|
+
map_element "skills", to: :tags
|
92
90
|
end
|
93
91
|
end
|
92
|
+
end
|
94
93
|
|
94
|
+
RSpec.describe "Value Transformations" do
|
95
95
|
describe "Attribute-only transformations" do
|
96
96
|
let(:attribute_person) do
|
97
97
|
TransformationSpec::AttributeTransformPerson.new(
|
@@ -71,14 +71,14 @@ RSpec.describe Lutaml::Model::Type::Boolean do
|
|
71
71
|
end
|
72
72
|
|
73
73
|
context "with key-value serialization" do
|
74
|
-
let(:
|
74
|
+
let(:attrs) do
|
75
75
|
{
|
76
76
|
"name" => "John Smith",
|
77
77
|
"full_time" => true,
|
78
78
|
"on_leave" => false,
|
79
79
|
"remote" => nil,
|
80
80
|
"active" => nil,
|
81
|
-
}
|
81
|
+
}
|
82
82
|
end
|
83
83
|
|
84
84
|
let(:expected_yaml) do
|
@@ -91,7 +91,7 @@ RSpec.describe Lutaml::Model::Type::Boolean do
|
|
91
91
|
end
|
92
92
|
|
93
93
|
it "deserializes boolean values correctly" do
|
94
|
-
employee = BooleanSpec::Employee.from_yaml(
|
94
|
+
employee = BooleanSpec::Employee.from_yaml(attrs.to_yaml)
|
95
95
|
|
96
96
|
expect(employee.name).to eq("John Smith")
|
97
97
|
expect(employee.full_time).to be true
|
@@ -101,13 +101,7 @@ RSpec.describe Lutaml::Model::Type::Boolean do
|
|
101
101
|
end
|
102
102
|
|
103
103
|
it "serializes boolean values correctly" do
|
104
|
-
employee = BooleanSpec::Employee.new(
|
105
|
-
name: "John Smith",
|
106
|
-
full_time: true,
|
107
|
-
on_leave: false,
|
108
|
-
remote: nil,
|
109
|
-
active: nil,
|
110
|
-
)
|
104
|
+
employee = BooleanSpec::Employee.new(attrs)
|
111
105
|
|
112
106
|
yaml_output = employee.to_yaml
|
113
107
|
expect(yaml_output).to eq(expected_yaml)
|
@@ -112,10 +112,10 @@ RSpec.describe Lutaml::Model::Type do
|
|
112
112
|
hide_const("BigDecimal")
|
113
113
|
end
|
114
114
|
|
115
|
+
let(:serialized) { Lutaml::Model::Type::Decimal.serialize("123.45") }
|
116
|
+
|
115
117
|
it "raises TypeNotEnabledError" do
|
116
|
-
expect
|
117
|
-
Lutaml::Model::Type::Decimal.serialize("123.45")
|
118
|
-
end.to raise_error(
|
118
|
+
expect { serialized }.to raise_error(
|
119
119
|
Lutaml::Model::TypeNotEnabledError,
|
120
120
|
/Decimal/,
|
121
121
|
)
|