couchrest_model 1.1.0.beta → 1.1.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
@@ -211,510 +211,6 @@ describe "Model properties" do
211
211
  end
212
212
  end
213
213
 
214
- describe "casting" do
215
- before(:each) do
216
- @course = Course.new(:title => 'Relaxation')
217
- end
218
-
219
- describe "when value is nil" do
220
- it "leaves the value unchanged" do
221
- @course.title = nil
222
- @course['title'].should == nil
223
- end
224
- end
225
-
226
- describe "when type primitive is an Object" do
227
- it "it should not cast given value" do
228
- @course.participants = [{}, 'q', 1]
229
- @course['participants'].should == [{}, 'q', 1]
230
- end
231
-
232
- it "should cast started_on to Date" do
233
- @course.started_on = Date.today
234
- @course['started_on'].should be_an_instance_of(Date)
235
- end
236
- end
237
-
238
- describe "when type primitive is a String" do
239
- it "keeps string value unchanged" do
240
- value = "1.0"
241
- @course.title = value
242
- @course['title'].should equal(value)
243
- end
244
-
245
- it "it casts to string representation of the value" do
246
- @course.title = 1.0
247
- @course['title'].should eql("1.0")
248
- end
249
- end
250
-
251
- describe 'when type primitive is a Float' do
252
- it 'returns same value if a float' do
253
- value = 24.0
254
- @course.estimate = value
255
- @course['estimate'].should equal(value)
256
- end
257
-
258
- it 'returns float representation of a zero string integer' do
259
- @course.estimate = '0'
260
- @course['estimate'].should eql(0.0)
261
- end
262
-
263
- it 'returns float representation of a positive string integer' do
264
- @course.estimate = '24'
265
- @course['estimate'].should eql(24.0)
266
- end
267
-
268
- it 'returns float representation of a negative string integer' do
269
- @course.estimate = '-24'
270
- @course['estimate'].should eql(-24.0)
271
- end
272
-
273
- it 'returns float representation of a zero string float' do
274
- @course.estimate = '0.0'
275
- @course['estimate'].should eql(0.0)
276
- end
277
-
278
- it 'returns float representation of a positive string float' do
279
- @course.estimate = '24.35'
280
- @course['estimate'].should eql(24.35)
281
- end
282
-
283
- it 'returns float representation of a negative string float' do
284
- @course.estimate = '-24.35'
285
- @course['estimate'].should eql(-24.35)
286
- end
287
-
288
- it 'returns float representation of a zero string float, with no leading digits' do
289
- @course.estimate = '.0'
290
- @course['estimate'].should eql(0.0)
291
- end
292
-
293
- it 'returns float representation of a positive string float, with no leading digits' do
294
- @course.estimate = '.41'
295
- @course['estimate'].should eql(0.41)
296
- end
297
-
298
- it 'returns float representation of a zero integer' do
299
- @course.estimate = 0
300
- @course['estimate'].should eql(0.0)
301
- end
302
-
303
- it 'returns float representation of a positive integer' do
304
- @course.estimate = 24
305
- @course['estimate'].should eql(24.0)
306
- end
307
-
308
- it 'returns float representation of a negative integer' do
309
- @course.estimate = -24
310
- @course['estimate'].should eql(-24.0)
311
- end
312
-
313
- it 'returns float representation of a zero decimal' do
314
- @course.estimate = BigDecimal('0.0')
315
- @course['estimate'].should eql(0.0)
316
- end
317
-
318
- it 'returns float representation of a positive decimal' do
319
- @course.estimate = BigDecimal('24.35')
320
- @course['estimate'].should eql(24.35)
321
- end
322
-
323
- it 'returns float representation of a negative decimal' do
324
- @course.estimate = BigDecimal('-24.35')
325
- @course['estimate'].should eql(-24.35)
326
- end
327
-
328
- it 'return float of a number with commas instead of points for decimals' do
329
- @course.estimate = '23,35'
330
- @course['estimate'].should eql(23.35)
331
- end
332
-
333
- it "should handle numbers with commas and points" do
334
- @course.estimate = '1,234.00'
335
- @course.estimate.should eql(1234.00)
336
- end
337
-
338
- it "should handle a mis-match of commas and points and maintain the last one" do
339
- @course.estimate = "1,232.434.123,323"
340
- @course.estimate.should eql(1232434123.323)
341
- end
342
-
343
- it "should handle numbers with whitespace" do
344
- @course.estimate = " 24.35 "
345
- @course.estimate.should eql(24.35)
346
- end
347
-
348
- [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
349
- it "does not typecast non-numeric value #{value.inspect}" do
350
- @course.estimate = value
351
- @course['estimate'].should equal(value)
352
- end
353
- end
354
-
355
- end
356
-
357
- describe 'when type primitive is a Integer' do
358
- it 'returns same value if an integer' do
359
- value = 24
360
- @course.hours = value
361
- @course['hours'].should equal(value)
362
- end
363
-
364
- it 'returns integer representation of a zero string integer' do
365
- @course.hours = '0'
366
- @course['hours'].should eql(0)
367
- end
368
-
369
- it 'returns integer representation of a positive string integer' do
370
- @course.hours = '24'
371
- @course['hours'].should eql(24)
372
- end
373
-
374
- it 'returns integer representation of a negative string integer' do
375
- @course.hours = '-24'
376
- @course['hours'].should eql(-24)
377
- end
378
-
379
- it 'returns integer representation of a zero string float' do
380
- @course.hours = '0.0'
381
- @course['hours'].should eql(0)
382
- end
383
-
384
- it 'returns integer representation of a positive string float' do
385
- @course.hours = '24.35'
386
- @course['hours'].should eql(24)
387
- end
388
-
389
- it 'returns integer representation of a negative string float' do
390
- @course.hours = '-24.35'
391
- @course['hours'].should eql(-24)
392
- end
393
-
394
- it 'returns integer representation of a zero string float, with no leading digits' do
395
- @course.hours = '.0'
396
- @course['hours'].should eql(0)
397
- end
398
-
399
- it 'returns integer representation of a positive string float, with no leading digits' do
400
- @course.hours = '.41'
401
- @course['hours'].should eql(0)
402
- end
403
-
404
- it 'returns integer representation of a zero float' do
405
- @course.hours = 0.0
406
- @course['hours'].should eql(0)
407
- end
408
-
409
- it 'returns integer representation of a positive float' do
410
- @course.hours = 24.35
411
- @course['hours'].should eql(24)
412
- end
413
-
414
- it 'returns integer representation of a negative float' do
415
- @course.hours = -24.35
416
- @course['hours'].should eql(-24)
417
- end
418
-
419
- it 'returns integer representation of a zero decimal' do
420
- @course.hours = '0.0'
421
- @course['hours'].should eql(0)
422
- end
423
-
424
- it 'returns integer representation of a positive decimal' do
425
- @course.hours = '24.35'
426
- @course['hours'].should eql(24)
427
- end
428
-
429
- it 'returns integer representation of a negative decimal' do
430
- @course.hours = '-24.35'
431
- @course['hours'].should eql(-24)
432
- end
433
-
434
- it "should handle numbers with whitespace" do
435
- @course.hours = " 24 "
436
- @course['hours'].should eql(24)
437
- end
438
-
439
- [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
440
- it "does not typecast non-numeric value #{value.inspect}" do
441
- @course.hours = value
442
- @course['hours'].should equal(value)
443
- end
444
- end
445
- end
446
-
447
- describe 'when type primitive is a BigDecimal' do
448
- it 'returns same value if a decimal' do
449
- value = BigDecimal('24.0')
450
- @course.profit = value
451
- @course['profit'].should equal(value)
452
- end
453
-
454
- it 'returns decimal representation of a zero string integer' do
455
- @course.profit = '0'
456
- @course['profit'].should eql(BigDecimal('0.0'))
457
- end
458
-
459
- it 'returns decimal representation of a positive string integer' do
460
- @course.profit = '24'
461
- @course['profit'].should eql(BigDecimal('24.0'))
462
- end
463
-
464
- it 'returns decimal representation of a negative string integer' do
465
- @course.profit = '-24'
466
- @course['profit'].should eql(BigDecimal('-24.0'))
467
- end
468
-
469
- it 'returns decimal representation of a zero string float' do
470
- @course.profit = '0.0'
471
- @course['profit'].should eql(BigDecimal('0.0'))
472
- end
473
-
474
- it 'returns decimal representation of a positive string float' do
475
- @course.profit = '24.35'
476
- @course['profit'].should eql(BigDecimal('24.35'))
477
- end
478
-
479
- it 'returns decimal representation of a negative string float' do
480
- @course.profit = '-24.35'
481
- @course['profit'].should eql(BigDecimal('-24.35'))
482
- end
483
-
484
- it 'returns decimal representation of a zero string float, with no leading digits' do
485
- @course.profit = '.0'
486
- @course['profit'].should eql(BigDecimal('0.0'))
487
- end
488
-
489
- it 'returns decimal representation of a positive string float, with no leading digits' do
490
- @course.profit = '.41'
491
- @course['profit'].should eql(BigDecimal('0.41'))
492
- end
493
-
494
- it 'returns decimal representation of a zero integer' do
495
- @course.profit = 0
496
- @course['profit'].should eql(BigDecimal('0.0'))
497
- end
498
-
499
- it 'returns decimal representation of a positive integer' do
500
- @course.profit = 24
501
- @course['profit'].should eql(BigDecimal('24.0'))
502
- end
503
-
504
- it 'returns decimal representation of a negative integer' do
505
- @course.profit = -24
506
- @course['profit'].should eql(BigDecimal('-24.0'))
507
- end
508
-
509
- it 'returns decimal representation of a zero float' do
510
- @course.profit = 0.0
511
- @course['profit'].should eql(BigDecimal('0.0'))
512
- end
513
-
514
- it 'returns decimal representation of a positive float' do
515
- @course.profit = 24.35
516
- @course['profit'].should eql(BigDecimal('24.35'))
517
- end
518
-
519
- it 'returns decimal representation of a negative float' do
520
- @course.profit = -24.35
521
- @course['profit'].should eql(BigDecimal('-24.35'))
522
- end
523
-
524
- it "should handle numbers with whitespace" do
525
- @course.profit = " 24.35 "
526
- @course['profit'].should eql(BigDecimal('24.35'))
527
- end
528
-
529
- [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
530
- it "does not typecast non-numeric value #{value.inspect}" do
531
- @course.profit = value
532
- @course['profit'].should equal(value)
533
- end
534
- end
535
- end
536
-
537
- describe 'when type primitive is a DateTime' do
538
- describe 'and value given as a hash with keys like :year, :month, etc' do
539
- it 'builds a DateTime instance from hash values' do
540
- @course.updated_at = {
541
- :year => '2006',
542
- :month => '11',
543
- :day => '23',
544
- :hour => '12',
545
- :min => '0',
546
- :sec => '0'
547
- }
548
- result = @course['updated_at']
549
-
550
- result.should be_kind_of(DateTime)
551
- result.year.should eql(2006)
552
- result.month.should eql(11)
553
- result.day.should eql(23)
554
- result.hour.should eql(12)
555
- result.min.should eql(0)
556
- result.sec.should eql(0)
557
- end
558
- end
559
-
560
- describe 'and value is a string' do
561
- it 'parses the string' do
562
- @course.updated_at = 'Dec, 2006'
563
- @course['updated_at'].month.should == 12
564
- end
565
- end
566
-
567
- it 'does not typecast non-datetime values' do
568
- @course.updated_at = 'not-datetime'
569
- @course['updated_at'].should eql('not-datetime')
570
- end
571
- end
572
-
573
- describe 'when type primitive is a Date' do
574
- describe 'and value given as a hash with keys like :year, :month, etc' do
575
- it 'builds a Date instance from hash values' do
576
- @course.started_on = {
577
- :year => '2007',
578
- :month => '3',
579
- :day => '25'
580
- }
581
- result = @course['started_on']
582
-
583
- result.should be_kind_of(Date)
584
- result.year.should eql(2007)
585
- result.month.should eql(3)
586
- result.day.should eql(25)
587
- end
588
- end
589
-
590
- describe 'and value is a string' do
591
- it 'parses the string' do
592
- @course.started_on = 'Dec 20th, 2006'
593
- @course.started_on.month.should == 12
594
- @course.started_on.day.should == 20
595
- @course.started_on.year.should == 2006
596
- end
597
- end
598
-
599
- it 'does not typecast non-date values' do
600
- @course.started_on = 'not-date'
601
- @course['started_on'].should eql('not-date')
602
- end
603
- end
604
-
605
- describe 'when type primitive is a Time' do
606
- describe 'and value given as a hash with keys like :year, :month, etc' do
607
- it 'builds a Time instance from hash values' do
608
- @course.ends_at = {
609
- :year => '2006',
610
- :month => '11',
611
- :day => '23',
612
- :hour => '12',
613
- :min => '0',
614
- :sec => '0'
615
- }
616
- result = @course['ends_at']
617
-
618
- result.should be_kind_of(Time)
619
- result.year.should eql(2006)
620
- result.month.should eql(11)
621
- result.day.should eql(23)
622
- result.hour.should eql(12)
623
- result.min.should eql(0)
624
- result.sec.should eql(0)
625
- end
626
- end
627
-
628
- describe 'and value is a string' do
629
- it 'parses the string' do
630
- t = Time.now
631
- @course.ends_at = t.strftime('%Y/%m/%d %H:%M:%S %z')
632
- @course['ends_at'].year.should eql(t.year)
633
- @course['ends_at'].month.should eql(t.month)
634
- @course['ends_at'].day.should eql(t.day)
635
- @course['ends_at'].hour.should eql(t.hour)
636
- @course['ends_at'].min.should eql(t.min)
637
- @course['ends_at'].sec.should eql(t.sec)
638
- end
639
- it 'parses the string without offset' do
640
- t = Time.now
641
- @course.ends_at = t.strftime("%Y-%m-%d %H:%M:%S")
642
- @course['ends_at'].year.should eql(t.year)
643
- @course['ends_at'].month.should eql(t.month)
644
- @course['ends_at'].day.should eql(t.day)
645
- @course['ends_at'].hour.should eql(t.hour)
646
- @course['ends_at'].min.should eql(t.min)
647
- @course['ends_at'].sec.should eql(t.sec)
648
- end
649
- end
650
-
651
- it 'does not typecast non-time values' do
652
- @course.ends_at = 'not-time'
653
- @course['ends_at'].should eql('not-time')
654
- end
655
- end
656
-
657
- describe 'when type primitive is a Class' do
658
- it 'returns same value if a class' do
659
- value = Course
660
- @course.klass = value
661
- @course['klass'].should equal(value)
662
- end
663
-
664
- it 'returns the class if found' do
665
- @course.klass = 'Course'
666
- @course['klass'].should eql(Course)
667
- end
668
-
669
- it 'does not typecast non-class values' do
670
- @course.klass = 'NoClass'
671
- @course['klass'].should eql('NoClass')
672
- end
673
- end
674
-
675
- describe 'when type primitive is a Boolean' do
676
-
677
- [ true, 'true', 'TRUE', '1', 1, 't', 'T' ].each do |value|
678
- it "returns true when value is #{value.inspect}" do
679
- @course.active = value
680
- @course['active'].should be_true
681
- end
682
- end
683
-
684
- [ false, 'false', 'FALSE', '0', 0, 'f', 'F' ].each do |value|
685
- it "returns false when value is #{value.inspect}" do
686
- @course.active = value
687
- @course['active'].should be_false
688
- end
689
- end
690
-
691
- [ 'string', 2, 1.0, BigDecimal('1.0'), DateTime.now, Time.now, Date.today, Class, Object.new, ].each do |value|
692
- it "does not typecast value #{value.inspect}" do
693
- @course.active = value
694
- @course['active'].should equal(value)
695
- end
696
- end
697
-
698
- it "should respond to requests with ? modifier" do
699
- @course.active = nil
700
- @course.active?.should be_false
701
- @course.active = false
702
- @course.active?.should be_false
703
- @course.active = true
704
- @course.active?.should be_true
705
- end
706
-
707
- it "should respond to requests with ? modifier on TrueClass" do
708
- @course.very_active = nil
709
- @course.very_active?.should be_false
710
- @course.very_active = false
711
- @course.very_active?.should be_false
712
- @course.very_active = true
713
- @course.very_active?.should be_true
714
- end
715
- end
716
-
717
- end
718
214
  end
719
215
 
720
216
  describe "properties of array of casted models" do
@@ -836,7 +332,7 @@ describe "Property Class" do
836
332
  property.init_method.should eql('parse')
837
333
  end
838
334
 
839
- ## Property Casting method. More thoroughly tested earlier.
335
+ ## Property Casting method. More thoroughly tested in typecast_spec.
840
336
 
841
337
  describe "casting" do
842
338
  it "should cast a value" do
@@ -13,16 +13,27 @@ end
13
13
 
14
14
  describe "Proxyable" do
15
15
 
16
- it "should provide #model_proxy method" do
17
- DummyProxyable.new.should respond_to(:model_proxy)
18
- end
19
-
20
16
  describe "class methods" do
21
17
 
18
+ before(:each) do
19
+ @class = DummyProxyable.clone
20
+ end
21
+
22
+ describe ".proxy_owner_method" do
23
+ it "should provide proxy_owner_method accessors" do
24
+ @class.should respond_to(:proxy_owner_method)
25
+ @class.should respond_to(:proxy_owner_method=)
26
+ end
27
+ it "should work as expected" do
28
+ @class.proxy_owner_method = "foo"
29
+ @class.proxy_owner_method.should eql("foo")
30
+ end
31
+ end
32
+
22
33
  describe ".proxy_for" do
23
34
 
24
35
  it "should be provided" do
25
- DummyProxyable.should respond_to(:proxy_for)
36
+ @class.should respond_to(:proxy_for)
26
37
  end
27
38
 
28
39
  it "should create a new method" do
@@ -54,42 +65,53 @@ describe "Proxyable" do
54
65
  end
55
66
 
56
67
  it "should raise an error if the database method is missing" do
57
- DummyProxyable.proxy_for(:cats)
58
- @obj = DummyProxyable.new
68
+ @class.proxy_for(:cats)
69
+ @obj = @class.new
59
70
  @obj.should_receive(:respond_to?).with('proxy_database').and_return(false)
60
71
  lambda { @obj.cats }.should raise_error(StandardError, "Missing #proxy_database method for proxy")
61
72
  end
62
73
 
63
74
  it "should raise an error if custom database method missing" do
64
- DummyProxyable.proxy_for(:proxy_kittens, :database_method => "foobardom")
65
- @obj = DummyProxyable.new
75
+ @class.proxy_for(:proxy_kittens, :database_method => "foobardom")
76
+ @obj = @class.new
66
77
  lambda { @obj.proxy_kittens }.should raise_error(StandardError, "Missing #foobardom method for proxy")
67
78
  end
68
-
69
-
70
79
  end
71
-
72
80
  end
73
81
 
74
82
  describe ".proxied_by" do
75
83
  it "should be provided" do
76
- DummyProxyable.should respond_to(:proxied_by)
84
+ @class.should respond_to(:proxied_by)
77
85
  end
78
86
 
79
87
  it "should add an attribute accessor" do
80
- DummyProxyable.proxied_by(:foobar)
81
- DummyProxyable.new.should respond_to(:foobar)
88
+ @class.proxied_by(:foobar)
89
+ @class.new.should respond_to(:foobar)
90
+ end
91
+
92
+ it "should provide #model_proxy method" do
93
+ @class.proxied_by(:foobar)
94
+ @class.new.should respond_to(:model_proxy)
95
+ end
96
+
97
+ it "should set the proxy_owner_method" do
98
+ @class.proxied_by(:foobar)
99
+ @class.proxy_owner_method.should eql(:foobar)
82
100
  end
83
101
 
84
102
  it "should raise an error if model name pre-defined" do
85
- lambda { DummyProxyable.proxied_by(:object_id) }.should raise_error
103
+ lambda { @class.proxied_by(:object_id) }.should raise_error
86
104
  end
87
- end
88
105
 
106
+ it "should raise an error if object already has a proxy" do
107
+ @class.proxied_by(:department)
108
+ lambda { @class.proxied_by(:company) }.should raise_error
109
+ end
110
+ end
89
111
  end
90
112
 
91
113
  describe "ModelProxy" do
92
-
114
+
93
115
  before :all do
94
116
  @klass = CouchRest::Model::Proxyable::ModelProxy
95
117
  end
@@ -241,22 +263,18 @@ describe "Proxyable" do
241
263
  describe "#proxy_update" do
242
264
  it "should set returned doc fields" do
243
265
  doc = mock(:Document)
244
- doc.should_receive(:respond_to?).with(:database=).and_return(true)
266
+ doc.should_receive(:is_a?).with(Cat).and_return(true)
245
267
  doc.should_receive(:database=).with('database')
246
- doc.should_receive(:respond_to?).with(:model_proxy=).and_return(true)
247
268
  doc.should_receive(:model_proxy=).with(@obj)
248
- doc.should_receive(:respond_to?).with('owner_name=').and_return(true)
249
269
  doc.should_receive(:send).with('owner_name=', 'owner')
250
270
  @obj.send(:proxy_update, doc).should eql(doc)
251
271
  end
252
272
 
253
- it "should not fail if some fields missing" do
254
- doc = mock(:Document)
255
- doc.should_receive(:respond_to?).with(:database=).and_return(true)
256
- doc.should_receive(:database=).with('database')
257
- doc.should_receive(:respond_to?).with(:model_proxy=).and_return(false)
273
+ it "should not set anything if matching document not provided" do
274
+ doc = mock(:DocumentFoo)
275
+ doc.should_receive(:is_a?).with(Cat).and_return(false)
276
+ doc.should_not_receive(:database=)
258
277
  doc.should_not_receive(:model_proxy=)
259
- doc.should_receive(:respond_to?).with('owner_name=').and_return(false)
260
278
  doc.should_not_receive(:owner_name=)
261
279
  @obj.send(:proxy_update, doc).should eql(doc)
262
280
  end
@@ -309,6 +327,7 @@ describe "Proxyable" do
309
327
 
310
328
  it "should allow creation of new entries" do
311
329
  inv = @company.proxyable_invoices.new(:client => "Lorena", :total => 35)
330
+ inv.database.should_not be_nil
312
331
  inv.save.should be_true
313
332
  @company.proxyable_invoices.count.should eql(1)
314
333
  @company.proxyable_invoices.first.client.should eql("Lorena")