hashme 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,10 +11,10 @@ describe Hashme do
11
11
 
12
12
  describe '.build' do
13
13
  it "should create a Model and give a block to build it" do
14
- @model.should_receive(:call_in_block)
14
+ expect(@model).to receive(:call_in_block)
15
15
  @model.build do |model|
16
16
  @model.call_in_block
17
- model.should be_kind_of(@model)
17
+ expect(model).to be_kind_of(@model)
18
18
  end
19
19
  end
20
20
  end
@@ -29,16 +29,15 @@ describe Hashme do
29
29
 
30
30
  it "should accept and set attributes" do
31
31
  @obj = @model.new(:name => "Sam")
32
- @obj.name.should eql("Sam")
32
+ expect(@obj.name).to eql("Sam")
33
33
  end
34
34
 
35
35
  it "should set default values so they are accessible by hash" do
36
36
  @model.property :surname, String, :default => "Nowl"
37
37
  @obj = @model.new
38
- @obj.to_hash[:surname].should eql('Nowl')
38
+ expect(@obj.to_hash[:surname]).to eql('Nowl')
39
39
  end
40
40
 
41
-
42
41
  end
43
42
 
44
43
  end
@@ -14,41 +14,44 @@ describe Hashme::CastedArray do
14
14
  end
15
15
 
16
16
  describe "#initialize" do
17
+ let :property do
18
+ Hashme::Property.new(:name, String)
19
+ end
17
20
  before :each do
18
- @prop = Hashme::Property.new(:name, String)
19
- @obj = Hashme::CastedArray.new(owner, @prop, ['test'])
21
+ @obj = Hashme::CastedArray.new(property, owner, ['test'])
20
22
  end
21
23
 
22
24
  it "should prepare array" do
23
- @obj.length.should eql(1)
25
+ expect(@obj.length).to eql(1)
24
26
  end
25
27
 
26
28
  it "should set owner and property" do
27
- @obj.casted_by.should eql(owner)
28
- @obj.casted_by_property.should eql(@prop)
29
+ expect(@obj.casted_by).to eql(owner)
30
+ expect(@obj.casted_by_property).to eql(property)
29
31
  end
30
32
 
31
33
  it "should instantiate and cast each value" do
32
- @obj.first.should eql("test")
33
- @obj.first.class.should eql(String)
34
+ expect(@obj.first).to eql("test")
35
+ expect(@obj.first.class).to eql(String)
34
36
  end
35
37
  end
36
38
 
37
39
  describe "adding to array" do
38
-
39
- before :each do
40
- @prop = Hashme::Property.new(:item, submodel)
41
- @obj = Hashme::CastedArray.new(owner, @prop, [{:name => 'test'}])
40
+ subject do
41
+ Hashme::CastedArray.new(property, owner, [{:name => 'test'}])
42
+ end
43
+ let :property do
44
+ Hashme::Property.new(:item, submodel)
42
45
  end
43
46
 
44
47
  it "should cast new items" do
45
- @obj << {:name => 'test2'}
46
- @obj.last.class.should eql(submodel)
47
- @obj.first.name.should eql('test')
48
- @obj.last.name.should eql('test2')
48
+ subject << {:name => 'test2'}
49
+ expect(subject.last.class).to eql(submodel)
50
+ expect(subject.first.name).to eql('test')
51
+ expect(subject.last.name).to eql('test2')
49
52
 
50
- @obj.last.casted_by.should eql(owner)
51
- @obj.last.casted_by_property.should eql(@prop)
53
+ expect(subject.last.casted_by).to be(subject)
54
+ expect(subject.last.casted_by_property).to eql(property)
52
55
  end
53
56
 
54
57
  end
@@ -23,7 +23,7 @@ describe Hashme::Properties do
23
23
  describe "#get_attribute" do
24
24
  it "should provide object in model" do
25
25
  @obj[:key1] = 'value'
26
- @obj.get_attribute(:key1).should eql('value')
26
+ expect(@obj.get_attribute(:key1)).to eql('value')
27
27
  end
28
28
  end
29
29
 
@@ -31,41 +31,41 @@ describe Hashme::Properties do
31
31
  it "should be posible to set attribute not defined as property" do
32
32
  @obj.set_attribute('key1', 'value1')
33
33
  @obj.set_attribute(:key2, 'value2')
34
- @obj[:key1].should eql('value1')
35
- @obj[:key2].should eql('value2')
34
+ expect(@obj[:key1]).to eql('value1')
35
+ expect(@obj[:key2]).to eql('value2')
36
36
  end
37
37
 
38
38
  it "should set and cast attribute with property" do
39
39
  property = @model.send(:properties)[:name]
40
40
  name = "Fred Flinstone"
41
- property.should_receive(:cast).with(@obj, name).and_return(name)
41
+ expect(property).to receive(:build).with(@obj, name).and_return(name)
42
42
  @obj.set_attribute(:name, name)
43
- @obj[:name].should eql(name)
43
+ expect(@obj[:name]).to eql(name)
44
44
  end
45
45
  end
46
46
 
47
47
  describe ".properties" do
48
48
 
49
49
  it "should be instantiated after property set" do
50
- @model.properties.should_not be_nil
51
- @model.properties.class.should eql(Hash)
50
+ expect(@model.properties).to_not be_nil
51
+ expect(@model.properties.class).to eql(Hash)
52
52
  end
53
53
 
54
54
  it "should be empty if no properties" do
55
55
  model = Class.new do
56
56
  include Hashme
57
57
  end
58
- model.properties.should be_empty
58
+ expect(model.properties).to be_empty
59
59
  end
60
60
 
61
61
  it "should be inherited from parent models" do
62
62
  mod = Class.new(@model) do
63
63
  property :surname, String
64
64
  end
65
- mod.properties.keys.should include(:name)
66
- mod.properties.keys.should include(:surname)
65
+ expect(mod.properties.keys).to include(:name)
66
+ expect(mod.properties.keys).to include(:surname)
67
67
  # Make sure we don't update the parent!
68
- @model.properties.keys.should_not include(:surname)
68
+ expect(@model.properties.keys).to_not include(:surname)
69
69
  end
70
70
 
71
71
  end
@@ -73,36 +73,36 @@ describe Hashme::Properties do
73
73
  describe ".property" do
74
74
 
75
75
  it "should fail if no type is defined" do
76
- @model.properties.length.should eql(1)
76
+ expect(@model.properties.length).to eql(1)
77
77
  expect {
78
78
  @model.property :foobar
79
79
  }.to raise_error(ArgumentError)
80
- @model.properties.length.should eql(1)
80
+ expect(@model.properties.length).to eql(1)
81
81
  end
82
82
 
83
83
  it "should create a new property with helper methods" do
84
- @model.properties.length.should eql(1)
84
+ expect(@model.properties.length).to eql(1)
85
85
  @model.property :desc, String
86
- @model.properties.length.should eql(2)
86
+ expect(@model.properties.length).to eql(2)
87
87
 
88
88
  prop = @model.properties[:desc]
89
- prop.class.should eql(Hashme::Property)
89
+ expect(prop.class).to eql(Hashme::Property)
90
90
 
91
- @obj.should respond_to(:desc)
92
- @obj.should respond_to(:desc=)
91
+ expect(@obj).to respond_to(:desc)
92
+ expect(@obj).to respond_to(:desc=)
93
93
 
94
94
  @obj.desc = "test"
95
- @obj.desc.should eql("test")
95
+ expect(@obj.desc).to eql("test")
96
96
  end
97
97
 
98
98
  it "should return nil on property with no default" do
99
99
  @model.property :nickname, String
100
- @obj.nickname.should be_nil
100
+ expect(@obj.nickname).to be_nil
101
101
  end
102
102
 
103
103
  it "should create helper method with support for default values" do
104
104
  @model.property :name, String, :default => "Sam"
105
- @obj.name.should eql("Sam")
105
+ expect(@obj.name).to eql("Sam")
106
106
  end
107
107
 
108
108
  end
@@ -0,0 +1,612 @@
1
+ require 'spec_helper'
2
+
3
+ class Course
4
+ include Hashme
5
+
6
+ property :title, String
7
+ property :participants, [Object]
8
+ property :ends_at, Time
9
+ property :estimate, Float
10
+ property :hours, Integer
11
+ property :profit, BigDecimal
12
+ property :started_on, Date
13
+ property :updated_at, DateTime
14
+ property :active, TrueClass
15
+ property :very_active, TrueClass
16
+ property :klass, Class
17
+ property :currency, String, :default => 'EUR'
18
+ property :symbol, Symbol
19
+ end
20
+
21
+ describe Hashme::PropertyCasting do
22
+
23
+ let :property do
24
+ double(:property)
25
+ end
26
+
27
+ describe "#cast" do
28
+ it "should respond" do
29
+ expect(subject).to respond_to(:cast)
30
+ end
31
+ end
32
+
33
+ let :course do
34
+ Course.new(:title => 'Relaxation')
35
+ end
36
+
37
+ describe "when value is nil" do
38
+ it "leaves the value unchanged" do
39
+ course.title = nil
40
+ expect(course['title']).to be_nil
41
+ end
42
+ end
43
+
44
+ describe "when value is empty string" do
45
+ it "leaves the value unchanged" do
46
+ course.title = ""
47
+ expect(course['title']).to eql("")
48
+ end
49
+ end
50
+
51
+ describe "when type primitive is an Object" do
52
+ it "it should not cast given value" do
53
+ course.participants = [{}, 'q', 1]
54
+ expect(course['participants']).to eql([{}, 'q', 1])
55
+ end
56
+
57
+ it "should cast started_on to Date" do
58
+ course.started_on = Date.today
59
+ expect(course['started_on']).to be_an_instance_of(Date)
60
+ end
61
+ end
62
+
63
+ describe "when type primitive is a String" do
64
+ it "keeps string value unchanged" do
65
+ value = "1.0"
66
+ course.title = value
67
+ expect(course['title']).to equal(value)
68
+ end
69
+
70
+ it "it casts to string representation of the value" do
71
+ course.title = 1.0
72
+ expect(course['title']).to eql("1.0")
73
+ end
74
+ end
75
+
76
+ describe "when type primitive is a Symbol" do
77
+ it "keeps symbol value unchanged" do
78
+ value = :a_symbol
79
+ course.symbol = value
80
+ expect(course['symbol']).to be(value)
81
+ end
82
+
83
+ it "it casts to symbol representation of the value" do
84
+ course.symbol = "a_symbol"
85
+ expect(course['symbol']).to be(:a_symbol)
86
+ end
87
+
88
+ it "turns blank value into nil" do
89
+ course.symbol = ""
90
+ expect(course.symbol).to be_nil
91
+ end
92
+ end
93
+
94
+
95
+ describe 'when type primitive is a Float' do
96
+ it 'returns same value if a float' do
97
+ value = 24.0
98
+ course.estimate = value
99
+ expect(course['estimate']).to equal(value)
100
+ end
101
+
102
+ it 'returns float representation of a zero string integer' do
103
+ course.estimate = '0'
104
+ expect(course['estimate']).to eql(0.0)
105
+ end
106
+
107
+ it 'returns float representation of a positive string integer' do
108
+ course.estimate = '24'
109
+ expect(course['estimate']).to eql(24.0)
110
+ end
111
+
112
+ it 'returns float representation of a negative string integer' do
113
+ course.estimate = '-24'
114
+ expect(course['estimate']).to eql(-24.0)
115
+ end
116
+
117
+ it 'returns float representation of a zero string float' do
118
+ course.estimate = '0.0'
119
+ expect(course['estimate']).to eql(0.0)
120
+ end
121
+
122
+ it 'returns float representation of a positive string float' do
123
+ course.estimate = '24.35'
124
+ expect(course['estimate']).to eql(24.35)
125
+ end
126
+
127
+ it 'returns float representation of a negative string float' do
128
+ course.estimate = '-24.35'
129
+ expect(course['estimate']).to eql(-24.35)
130
+ end
131
+
132
+ it 'returns float representation of a zero string float, with no leading digits' do
133
+ course.estimate = '.0'
134
+ expect(course['estimate']).to eql(0.0)
135
+ end
136
+
137
+ it 'returns float representation of a positive string float, with no leading digits' do
138
+ course.estimate = '.41'
139
+ expect(course['estimate']).to eql(0.41)
140
+ end
141
+
142
+ it 'returns float representation of a zero integer' do
143
+ course.estimate = 0
144
+ expect(course['estimate']).to eql(0.0)
145
+ end
146
+
147
+ it 'returns float representation of a positive integer' do
148
+ course.estimate = 24
149
+ expect(course['estimate']).to eql(24.0)
150
+ end
151
+
152
+ it 'returns float representation of a negative integer' do
153
+ course.estimate = -24
154
+ expect(course['estimate']).to eql(-24.0)
155
+ end
156
+
157
+ it 'returns float representation of a zero decimal' do
158
+ course.estimate = BigDecimal('0.0')
159
+ expect(course['estimate']).to eql(0.0)
160
+ end
161
+
162
+ it 'returns float representation of a positive decimal' do
163
+ course.estimate = BigDecimal('24.35')
164
+ expect(course['estimate']).to eql(24.35)
165
+ end
166
+
167
+ it 'returns float representation of a negative decimal' do
168
+ course.estimate = BigDecimal('-24.35')
169
+ expect(course['estimate']).to eql(-24.35)
170
+ end
171
+
172
+ it 'return float of a number with commas instead of points for decimals' do
173
+ course.estimate = '23,35'
174
+ expect(course['estimate']).to eql(23.35)
175
+ end
176
+
177
+ it "should handle numbers with commas and points" do
178
+ course.estimate = '1,234.00'
179
+ expect(course.estimate).to eql(1234.00)
180
+ end
181
+
182
+ it "should handle a mis-match of commas and points and maintain the last one" do
183
+ course.estimate = "1,232.434.123,323"
184
+ expect(course.estimate).to eql(1232434123.323)
185
+ end
186
+
187
+ it "should handle numbers with whitespace" do
188
+ course.estimate = " 24.35 "
189
+ expect(course.estimate).to eql(24.35)
190
+ end
191
+
192
+ it "should handle numbers with unit strings" do
193
+ course.estimate = "23.21 points"
194
+ expect(course['estimate']).to eql(23.21)
195
+ end
196
+
197
+ [ '', 'string', ' foo ' ].each do |value|
198
+ it "should typecast string without a number to nil (#{value.inspect})" do
199
+ course.estimate = value
200
+ expect(course['estimate']).to be_nil
201
+ end
202
+ end
203
+
204
+ [ '00.0', '0.', '-.0' ].each do |value|
205
+ it "should typecast strings with strange numbers to zero (#{value.inspect})" do
206
+ course.estimate = value
207
+ expect(course['estimate']).to eql(0.0)
208
+ end
209
+ end
210
+
211
+ [ Object.new, true ].each do |value|
212
+ it "should not typecast non-numeric value that won't respond to #to_f (#{value.inspect})" do
213
+ course.estimate = value
214
+ expect(course['estimate']).to equal(nil)
215
+ end
216
+ end
217
+
218
+ end
219
+
220
+ describe 'when type primitive is a Integer' do
221
+ it 'returns same value if an integer' do
222
+ value = 24
223
+ course.hours = value
224
+ expect(course['hours']).to equal(value)
225
+ end
226
+
227
+ it 'returns integer representation of a zero string integer' do
228
+ course.hours = '0'
229
+ expect(course['hours']).to eql(0)
230
+ end
231
+
232
+ it 'returns integer representation of a positive string integer' do
233
+ course.hours = '24'
234
+ expect(course['hours']).to eql(24)
235
+ end
236
+
237
+ it 'returns integer representation of a negative string integer' do
238
+ course.hours = '-24'
239
+ expect(course['hours']).to eql(-24)
240
+ end
241
+
242
+ it 'returns integer representation of a zero string float' do
243
+ course.hours = '0.0'
244
+ expect(course['hours']).to eql(0)
245
+ end
246
+
247
+ it 'returns integer representation of a positive string float' do
248
+ course.hours = '24.35'
249
+ expect(course['hours']).to eql(24)
250
+ end
251
+
252
+ it 'returns integer representation of a negative string float' do
253
+ course.hours = '-24.35'
254
+ expect(course['hours']).to eql(-24)
255
+ end
256
+
257
+ it 'returns integer representation of a zero string float, with no leading digits' do
258
+ course.hours = '.0'
259
+ expect(course['hours']).to eql(0)
260
+ end
261
+
262
+ it 'returns integer representation of a positive string float, with no leading digits' do
263
+ course.hours = '.41'
264
+ expect(course['hours']).to eql(0)
265
+ end
266
+
267
+ it 'returns integer representation of a zero float' do
268
+ course.hours = 0.0
269
+ expect(course['hours']).to eql(0)
270
+ end
271
+
272
+ it 'returns integer representation of a positive float' do
273
+ course.hours = 24.35
274
+ expect(course['hours']).to eql(24)
275
+ end
276
+
277
+ it 'returns integer representation of a negative float' do
278
+ course.hours = -24.35
279
+ expect(course['hours']).to eql(-24)
280
+ end
281
+
282
+ it 'returns integer representation of a zero decimal' do
283
+ course.hours = '0.0'
284
+ expect(course['hours']).to eql(0)
285
+ end
286
+
287
+ it 'returns integer representation of a positive decimal' do
288
+ course.hours = '24.35'
289
+ expect(course['hours']).to eql(24)
290
+ end
291
+
292
+ it 'returns integer representation of a negative decimal' do
293
+ course.hours = '-24.35'
294
+ expect(course['hours']).to eql(-24)
295
+ end
296
+
297
+ it "should handle numbers with whitespace" do
298
+ course.hours = " 24 "
299
+ expect(course['hours']).to eql(24)
300
+ end
301
+
302
+ it "should handle numbers with string units" do
303
+ course.hours = "23 hours"
304
+ expect(course['hours']).to eql(23)
305
+ end
306
+
307
+ it "should typecast an empty string to nil" do
308
+ course.hours = ""
309
+ expect(course['hours']).to be_nil
310
+ end
311
+
312
+ [ '', 'string', ' foo ' ].each do |value|
313
+ it "should typecast string without a number to nil (#{value.inspect})" do
314
+ course.hours = value
315
+ expect(course['hours']).to be_nil
316
+ end
317
+ end
318
+
319
+ [ '00.0', '0.', '-.0' ].each do |value|
320
+ it "should typecast strings with strange numbers to zero (#{value.inspect})" do
321
+ course.hours = value
322
+ expect(course['hours']).to eql(0)
323
+ end
324
+ end
325
+
326
+ [ Object.new, true ].each do |value|
327
+ it "should not typecast non-numeric value that won't respond to #to_i (#{value.inspect})" do
328
+ course.hours = value
329
+ expect(course['hours']).to equal(nil)
330
+ end
331
+ end
332
+
333
+ end
334
+
335
+ describe 'when type primitive is a BigDecimal' do
336
+ it 'returns same value if a decimal' do
337
+ value = BigDecimal('24.0')
338
+ course.profit = value
339
+ expect(course['profit']).to equal(value)
340
+ end
341
+
342
+ it 'returns decimal representation of a zero string integer' do
343
+ course.profit = '0'
344
+ expect(course['profit']).to eql(BigDecimal('0.0'))
345
+ end
346
+
347
+ it 'returns decimal representation of a positive string integer' do
348
+ course.profit = '24'
349
+ expect(course['profit']).to eql(BigDecimal('24.0'))
350
+ end
351
+
352
+ it 'returns decimal representation of a negative string integer' do
353
+ course.profit = '-24'
354
+ expect(course['profit']).to eql(BigDecimal('-24.0'))
355
+ end
356
+
357
+ it 'returns decimal representation of a zero string float' do
358
+ course.profit = '0.0'
359
+ expect(course['profit']).to eql(BigDecimal('0.0'))
360
+ end
361
+
362
+ it 'returns decimal representation of a positive string float' do
363
+ course.profit = '24.35'
364
+ expect(course['profit']).to eql(BigDecimal('24.35'))
365
+ end
366
+
367
+ it 'returns decimal representation of a negative string float' do
368
+ course.profit = '-24.35'
369
+ expect(course['profit']).to eql(BigDecimal('-24.35'))
370
+ end
371
+
372
+ it 'returns decimal representation of a zero string float, with no leading digits' do
373
+ course.profit = '.0'
374
+ expect(course['profit']).to eql(BigDecimal('0.0'))
375
+ end
376
+
377
+ it 'returns decimal representation of a positive string float, with no leading digits' do
378
+ course.profit = '.41'
379
+ expect(course['profit']).to eql(BigDecimal('0.41'))
380
+ end
381
+
382
+ it 'returns decimal representation of a zero integer' do
383
+ course.profit = 0
384
+ expect(course['profit']).to eql(BigDecimal('0.0'))
385
+ end
386
+
387
+ it 'returns decimal representation of a positive integer' do
388
+ course.profit = 24
389
+ expect(course['profit']).to eql(BigDecimal('24.0'))
390
+ end
391
+
392
+ it 'returns decimal representation of a negative integer' do
393
+ course.profit = -24
394
+ expect(course['profit']).to eql(BigDecimal('-24.0'))
395
+ end
396
+
397
+ it 'returns decimal representation of a zero float' do
398
+ course.profit = 0.0
399
+ expect(course['profit']).to eql(BigDecimal('0.0'))
400
+ end
401
+
402
+ it 'returns decimal representation of a positive float' do
403
+ course.profit = 24.35
404
+ expect(course['profit']).to eql(BigDecimal('24.35'))
405
+ end
406
+
407
+ it 'returns decimal representation of a negative float' do
408
+ course.profit = -24.35
409
+ expect(course['profit']).to eql(BigDecimal('-24.35'))
410
+ end
411
+
412
+ it "should handle numbers with whitespace" do
413
+ course.profit = " 24.35 "
414
+ expect(course['profit']).to eql(BigDecimal('24.35'))
415
+ end
416
+
417
+ it "should handle numbers with strings" do
418
+ course.profit = "22.23 euros"
419
+ expect(course['profit']).to eql(BigDecimal('22.23'))
420
+ end
421
+
422
+ it "should typecast an empty string to nil" do
423
+ course.profit = ""
424
+ expect(course['profit']).to be_nil
425
+ end
426
+
427
+ [ '', 'string', ' foo ' ].each do |value|
428
+ it "should typecast string without a number to nil (#{value.inspect})" do
429
+ course.profit = value
430
+ expect(course['profit']).to be_nil
431
+ end
432
+ end
433
+
434
+ [ '00.0', '0.', '-.0' ].each do |value|
435
+ it "should typecast strings with strange numbers to zero (#{value.inspect})" do
436
+ course.profit = value
437
+ expect(course['profit']).to eql(0.0)
438
+ end
439
+ end
440
+
441
+ [ Object.new, true ].each do |value|
442
+ it "should typecast non-numeric value that won't respond to to_d (#{value.inspect}) as nil" do
443
+ course.profit = value
444
+ expect(course['profit']).to equal(nil)
445
+ end
446
+ end
447
+
448
+ end
449
+
450
+ describe 'when type primitive is a DateTime' do
451
+ describe 'and value given as a hash with keys like :year, :month, etc' do
452
+ it 'builds a DateTime instance from hash values' do
453
+ course.updated_at = {
454
+ :year => '2006',
455
+ :month => '11',
456
+ :day => '23',
457
+ :hour => '12',
458
+ :min => '0',
459
+ :sec => '0'
460
+ }
461
+ result = course['updated_at']
462
+
463
+ expect(result).to be_kind_of(DateTime)
464
+ expect(result.year).to eql(2006)
465
+ expect(result.month).to eql(11)
466
+ expect(result.day).to eql(23)
467
+ expect(result.hour).to eql(12)
468
+ expect(result.min).to eql(0)
469
+ expect(result.sec).to eql(0)
470
+ end
471
+ end
472
+
473
+ describe 'and value is a string' do
474
+ it 'parses the string' do
475
+ course.updated_at = 'Dec, 2006'
476
+ expect(course['updated_at'].month).to eql(12)
477
+ end
478
+ end
479
+
480
+ it 'does not typecast non-datetime values' do
481
+ course.updated_at = 'not-datetime'
482
+ expect(course['updated_at']).to be_nil
483
+ end
484
+ end
485
+
486
+ describe 'when type primitive is a Date' do
487
+ describe 'and value given as a hash with keys like :year, :month, etc' do
488
+ it 'builds a Date instance from hash values' do
489
+ course.started_on = {
490
+ :year => '2007',
491
+ :month => '3',
492
+ :day => '25'
493
+ }
494
+ result = course['started_on']
495
+
496
+ expect(result).to be_kind_of(Date)
497
+ expect(result.year).to eql(2007)
498
+ expect(result.month).to eql(3)
499
+ expect(result.day).to eql(25)
500
+ end
501
+ end
502
+
503
+ describe 'and value is a string' do
504
+ it 'parses the string' do
505
+ course.started_on = 'Dec 20th, 2006'
506
+ expect(course.started_on.month).to eql(12)
507
+ expect(course.started_on.day).to eql(20)
508
+ expect(course.started_on.year).to eql(2006)
509
+ end
510
+ end
511
+
512
+ it 'does not typecast non-date values' do
513
+ course.started_on = 'not-date'
514
+ expect(course['started_on']).to be_nil
515
+ end
516
+ end
517
+
518
+ describe 'when type primitive is a Time' do
519
+ describe 'and value given as a hash with keys like :year, :month, etc' do
520
+ it 'builds a Time instance from hash values' do
521
+ course.ends_at = {
522
+ :year => '2006',
523
+ :month => '11',
524
+ :day => '23',
525
+ :hour => '12',
526
+ :min => '0',
527
+ :sec => '0'
528
+ }
529
+ result = course['ends_at']
530
+
531
+ expect(result).to be_kind_of(Time)
532
+ expect(result.year).to eql(2006)
533
+ expect(result.month).to eql(11)
534
+ expect(result.day).to eql(23)
535
+ expect(result.hour).to eql(12)
536
+ expect(result.min).to eql(0)
537
+ expect(result.sec).to eql(0)
538
+ end
539
+ end
540
+
541
+ describe 'and value is a string' do
542
+ it 'parses the string' do
543
+ t = Time.new(2011, 4, 1, 18, 50, 32, "+02:00")
544
+ course.ends_at = t.strftime('%Y/%m/%d %H:%M:%S %z')
545
+ expect(course['ends_at'].year).to eql(t.year)
546
+ expect(course['ends_at'].month).to eql(t.month)
547
+ expect(course['ends_at'].day).to eql(t.day)
548
+ expect(course['ends_at'].hour).to eql(t.hour)
549
+ expect(course['ends_at'].min).to eql(t.min)
550
+ expect(course['ends_at'].sec).to eql(t.sec)
551
+ end
552
+ it 'parses the string without offset as UTC' do
553
+ t = Time.now.utc
554
+ course.ends_at = t.strftime("%Y-%m-%d %H:%M:%S")
555
+ expect(course.ends_at.utc?).to be_truthy
556
+ expect(course['ends_at'].year).to eql(t.year)
557
+ expect(course['ends_at'].month).to eql(t.month)
558
+ expect(course['ends_at'].day).to eql(t.day)
559
+ expect(course['ends_at'].hour).to eql(t.hour)
560
+ expect(course['ends_at'].min).to eql(t.min)
561
+ expect(course['ends_at'].sec).to eql(t.sec)
562
+ end
563
+ end
564
+
565
+ it 'does not typecast non-time values' do
566
+ course.ends_at = 'not-time'
567
+ expect(course['ends_at']).to be_nil
568
+ end
569
+ end
570
+
571
+ describe 'when type primitive is a Class' do
572
+ it 'returns same value if a class' do
573
+ value = Course
574
+ course.klass = value
575
+ expect(course['klass']).to equal(value)
576
+ end
577
+
578
+ it 'returns the class if found' do
579
+ course.klass = 'Course'
580
+ expect(course['klass']).to eql(Course)
581
+ end
582
+
583
+ it 'does not typecast non-class values' do
584
+ course.klass = 'NoClass'
585
+ expect(course['klass']).to be_nil
586
+ end
587
+ end
588
+
589
+ describe 'when type primitive is a Boolean' do
590
+
591
+ [ true, 'true', 'TRUE', '1', 1, 't', 'T' ].each do |value|
592
+ it "returns true when value is #{value.inspect}" do
593
+ course.active = value
594
+ expect(course['active']).to be_truthy
595
+ end
596
+ end
597
+
598
+ [ false, 'false', 'FALSE', '0', 0, 'f', 'F' ].each do |value|
599
+ it "returns false when value is #{value.inspect}" do
600
+ course.active = value
601
+ expect(course['active']).to be_falsey
602
+ end
603
+ end
604
+
605
+ [ 'string', 2, 1.0, BigDecimal('1.0'), DateTime.now, Time.now, Date.today, Class, Object.new, ].each do |value|
606
+ it "does not typecast value #{value.inspect}" do
607
+ course.active = value
608
+ expect(course['active']).to be_nil
609
+ end
610
+ end
611
+ end
612
+ end