morf 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,384 @@
1
+ require 'spec_helper'
2
+
3
+ describe Morf::Caster do
4
+ describe "#cast" do
5
+
6
+ class ContactCaster
7
+ include Morf::Caster
8
+
9
+ attributes do
10
+ hash :contact do
11
+ string :name
12
+ integer :age, optional: true
13
+ float :weight
14
+ date :birthday
15
+ datetime :last_logged_in
16
+ time :last_visited_at
17
+ hash :company do
18
+ string :name
19
+ end
20
+ array :emails, each: :string
21
+ array :social_accounts, each: :hash do
22
+ string :name
23
+ symbol :type
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ it "should cast hash attributes" do
30
+ input_hash = {
31
+ contact: {
32
+ name: "John Smith",
33
+ age: "22",
34
+ weight: "65.5",
35
+ birthday: "2014-02-02",
36
+ last_logged_in: "2014-02-02 10:10:00",
37
+ last_visited_at: "2014-02-02 10:10:00",
38
+ company: {
39
+ name: "MyCo",
40
+ },
41
+ emails: [ "test@example.com", "test2@example.com" ],
42
+ social_accounts: [
43
+ {
44
+ name: "john_smith",
45
+ type: 'twitter',
46
+ },
47
+ {
48
+ name: "John",
49
+ type: :facebook,
50
+ },
51
+ ]
52
+ }
53
+ }
54
+
55
+ casted_hash = ContactCaster.cast(input_hash)
56
+
57
+ casted_hash.should == {
58
+ contact: {
59
+ name: "John Smith",
60
+ age: 22,
61
+ weight: 65.5,
62
+ birthday: Date.parse("2014-02-02"),
63
+ last_logged_in: DateTime.parse("2014-02-02 10:10:00"),
64
+ last_visited_at: Time.parse("2014-02-02 10:10:00"),
65
+ company: {
66
+ name: "MyCo",
67
+ },
68
+ emails: [ "test@example.com", "test2@example.com" ],
69
+ social_accounts: [
70
+ {
71
+ name: "john_smith",
72
+ type: :twitter,
73
+ },
74
+ {
75
+ name: "John",
76
+ type: :facebook,
77
+ },
78
+ ]
79
+ }
80
+ }
81
+ end
82
+
83
+ describe "Custom casters" do
84
+ class SettingsCaster
85
+ include Morf::Caster
86
+
87
+ attributes do
88
+ string :account
89
+ end
90
+ end
91
+
92
+ class EmailCaster
93
+ include Morf::Caster
94
+
95
+ attributes do
96
+ string :address
97
+ end
98
+ end
99
+
100
+ class CompanyCaster
101
+ include Morf::Caster
102
+
103
+ attributes do
104
+ string :name
105
+ hash :settings, caster: SettingsCaster
106
+ array :emails, caster: EmailCaster
107
+ end
108
+ end
109
+
110
+ it "should allow specify caster for nested hash attribute" do
111
+ casted_hash = CompanyCaster.cast(
112
+ name: 'Might & Magic',
113
+ settings: {
114
+ account: :'migthy_lord'
115
+ },
116
+ emails: [
117
+ { address: :'test1@example.com' },
118
+ { address: :'test2@example.com' },
119
+ ]
120
+ )
121
+
122
+ casted_hash.should == {
123
+ name: "Might & Magic",
124
+ settings: { account: "migthy_lord" },
125
+ emails: [
126
+ { address: "test1@example.com" },
127
+ { address: "test2@example.com" }
128
+ ]
129
+ }
130
+ end
131
+ end
132
+
133
+ it "should raise error if some attribute can't be casted" do
134
+ input_hash = {
135
+ contact: {
136
+ name: {},
137
+ age: 22,
138
+ weight: 65.5,
139
+ birthday: Date.today,
140
+ last_logged_in: DateTime.now,
141
+ last_visited_at: Time.now,
142
+ company: {
143
+ name: "MyCo",
144
+ },
145
+ emails: [ "test@example.com", "test2@example.com" ],
146
+ social_accounts: [
147
+ {
148
+ name: "john_smith",
149
+ type: :twitter,
150
+ },
151
+ {
152
+ name: "John",
153
+ type: :facebook,
154
+ }
155
+ ]
156
+ }
157
+ }
158
+
159
+ expect do
160
+ ContactCaster.cast(input_hash)
161
+ end.to raise_error(Morf::Errors::CastingError, "contact[name] should be a string")
162
+ end
163
+
164
+ it "should raise error if some attribute wasn't given" do
165
+ input_hash = {
166
+ contact: {
167
+ age: 22,
168
+ weight: 65.5,
169
+ birthday: Date.today,
170
+ last_logged_in: DateTime.now,
171
+ last_visited_at: Time.now,
172
+ company: {
173
+ name: "MyCo",
174
+ },
175
+ emails: [ "test@example.com", "test2@example.com" ],
176
+ social_accounts: [
177
+ {
178
+ name: "john_smith",
179
+ type: :twitter,
180
+ },
181
+ {
182
+ name: "John",
183
+ type: :facebook,
184
+ }
185
+ ]
186
+ }
187
+ }
188
+
189
+ expect do
190
+ ContactCaster.cast(input_hash)
191
+ end.to raise_error(Morf::Errors::MissingAttributeError, "contact[name] should be given")
192
+ end
193
+
194
+ it "should not raise error if attribute is optional" do
195
+ input_hash = {
196
+ contact: {
197
+ name: "Jim",
198
+ weight: 65.5,
199
+ birthday: Date.today,
200
+ last_logged_in: DateTime.now,
201
+ last_visited_at: Time.now,
202
+ company: {
203
+ name: "MyCo",
204
+ },
205
+ emails: [ "test@example.com", "test2@example.com" ],
206
+ social_accounts: [
207
+ {
208
+ name: "john_smith",
209
+ type: :twitter,
210
+ },
211
+ {
212
+ name: "John",
213
+ type: :facebook,
214
+ },
215
+ ]
216
+ }
217
+ }
218
+
219
+ expect do
220
+ ContactCaster.cast(input_hash)
221
+ end.to_not raise_error
222
+ end
223
+
224
+ it "should raise error if unexpected attribute was given" do
225
+ input_hash = {
226
+ contact: {
227
+ wrong_attribute: 'foo',
228
+ name: "Jim",
229
+ weight: 65.5,
230
+ birthday: Date.today,
231
+ last_logged_in: DateTime.now,
232
+ last_visited_at: Time.now,
233
+ company: {
234
+ name: "MyCo",
235
+ },
236
+ emails: [ "test@example.com", "test2@example.com" ],
237
+ social_accounts: [
238
+ {
239
+ name: "john_smith",
240
+ type: :twitter,
241
+ },
242
+ {
243
+ name: "John",
244
+ type: :facebook,
245
+ },
246
+ ]
247
+ }
248
+ }
249
+
250
+ expect do
251
+ ContactCaster.cast(input_hash)
252
+ end.to raise_error(Morf::Errors::UnexpectedAttributeError, "contact[wrong_attribute] is not valid attribute name")
253
+ end
254
+
255
+ it "shouldn't unexpected attributes error if skip_unexpected_attributes flag is set to true" do
256
+ input_hash = {
257
+ contact: {
258
+ wrong_attribute: 'foo',
259
+ name: "Jim",
260
+ weight: 65.5,
261
+ birthday: Date.today,
262
+ last_logged_in: DateTime.now,
263
+ last_visited_at: Time.now,
264
+ company: {
265
+ name: "MyCo",
266
+ },
267
+ emails: [ "test@example.com", "test2@example.com" ],
268
+ social_accounts: [
269
+ {
270
+ name: "john_smith",
271
+ type: :twitter,
272
+ },
273
+ {
274
+ name: "John",
275
+ type: :facebook,
276
+ },
277
+ ]
278
+ }
279
+ }
280
+
281
+ expect do
282
+ ContactCaster.cast(input_hash, skip_unexpected_attributes: true)
283
+ end.not_to raise_error(Morf::Errors::UnexpectedAttributeError)
284
+
285
+ end
286
+
287
+ it "should convert accept hash with string keys and cast them to symbol keys" do
288
+ input_hash = {
289
+ 'contact' => {
290
+ 'name' => "John Smith",
291
+ 'age' => "22",
292
+ 'weight' => "65.5",
293
+ 'birthday' => "2014-02-02",
294
+ 'last_logged_in' => "2014-02-02 10:10:00",
295
+ 'last_visited_at' => "2014-02-02 10:10:00",
296
+ 'company' => {
297
+ 'name' => "MyCo",
298
+ },
299
+ 'emails' => [ "test@example.com", "test2@example.com" ],
300
+ 'social_accounts' => [
301
+ {
302
+ 'name' => "john_smith",
303
+ 'type' => 'twitter',
304
+ },
305
+ {
306
+ 'name' => "John",
307
+ 'type' => :facebook,
308
+ },
309
+ ]
310
+ }
311
+ }
312
+
313
+ casted_hash = ContactCaster.cast(input_hash, input_keys: :string, output_keys: :symbol)
314
+
315
+ casted_hash.should == {
316
+ contact: {
317
+ name: "John Smith",
318
+ age: 22,
319
+ weight: 65.5,
320
+ birthday: Date.parse("2014-02-02"),
321
+ last_logged_in: DateTime.parse("2014-02-02 10:10:00"),
322
+ last_visited_at: Time.parse("2014-02-02 10:10:00"),
323
+ company: {
324
+ name: "MyCo",
325
+ },
326
+ emails: [ "test@example.com", "test2@example.com" ],
327
+ social_accounts: [
328
+ {
329
+ name: "john_smith",
330
+ type: :twitter,
331
+ },
332
+ {
333
+ name: "John",
334
+ type: :facebook,
335
+ },
336
+ ]
337
+ }
338
+ }
339
+ end
340
+ end
341
+
342
+ context "checking invalid parameters" do
343
+ it "should raise CaterNotFound exception if caster name is invalid" do
344
+ expect do
345
+ class WrongCaster
346
+ include Morf::Caster
347
+
348
+ attributes do
349
+ integr :name
350
+ end
351
+ end
352
+ end.to raise_error(Morf::Errors::CasterNotFoundError)
353
+ end
354
+ end
355
+
356
+ context "allow nil values" do
357
+ before(:all) do
358
+ class HomeCaster
359
+ include Morf::Caster
360
+
361
+ attributes do
362
+ string :city
363
+ integer :zip, allow_nil: true
364
+ end
365
+ end
366
+ end
367
+
368
+ it "should allow nil values if allow_nil is set to true" do
369
+ HomeCaster.cast(
370
+ city: 'Kazan',
371
+ zip: nil
372
+ )
373
+ end
374
+
375
+ it "should allow nil values unless allow_nil is set to true" do
376
+ expect do
377
+ HomeCaster.cast(
378
+ city: nil,
379
+ zip: nil
380
+ )
381
+ end.to raise_error(Morf::Errors::CastingError, "city should be a string")
382
+ end
383
+ end
384
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Morf do
4
+
5
+ describe ".create" do
6
+ it "should cast hash attributes" do
7
+ pending "NOT YET IMPLEMENTED"
8
+ input_hash = {
9
+ contact: {
10
+ name: "John Smith",
11
+ age: "22",
12
+ company: {
13
+ name: "MyCo",
14
+ }
15
+ }
16
+ }
17
+
18
+ caster = Morf.create do
19
+ hash :contact do
20
+ string :name
21
+ integer :age
22
+ hash :company do
23
+ string :name
24
+ end
25
+ end
26
+
27
+ def registered?
28
+ true
29
+ end
30
+ end
31
+
32
+ casted_hash = caster.cast(input_hash)
33
+ casted_hash.object_id.should_not == hash.object_id
34
+ caster_hash.should == hash
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'morf'
4
+
5
+ RSpec.configure do |config|
6
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: morf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Droid Labs LLC
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-12-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Declarative object morpher
56
+ email:
57
+ - droid@droidlabs.pro
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".travis.yml"
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - lib/morf.rb
70
+ - lib/morf/attributes_caster.rb
71
+ - lib/morf/attributes_parser.rb
72
+ - lib/morf/caster.rb
73
+ - lib/morf/casters.rb
74
+ - lib/morf/casters/array_caster.rb
75
+ - lib/morf/casters/boolean_caster.rb
76
+ - lib/morf/casters/date_caster.rb
77
+ - lib/morf/casters/datetime_caster.rb
78
+ - lib/morf/casters/float_caster.rb
79
+ - lib/morf/casters/hash_caster.rb
80
+ - lib/morf/casters/integer_caster.rb
81
+ - lib/morf/casters/string_caster.rb
82
+ - lib/morf/casters/symbol_caster.rb
83
+ - lib/morf/casters/time_caster.rb
84
+ - lib/morf/concern.rb
85
+ - lib/morf/config.rb
86
+ - lib/morf/errors.rb
87
+ - lib/morf/metadata/attribute.rb
88
+ - lib/morf/version.rb
89
+ - morf.gemspec
90
+ - spec/morf/caster_spec.rb
91
+ - spec/morf/morf_spec.rb
92
+ - spec/spec_helper.rb
93
+ homepage: https://github.com/droidlabs/morf
94
+ licenses:
95
+ - MIT
96
+ metadata: {}
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 2.6.12
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Declarative object morher
117
+ test_files:
118
+ - spec/morf/caster_spec.rb
119
+ - spec/morf/morf_spec.rb
120
+ - spec/spec_helper.rb