couchrest_model 1.1.0.beta → 1.1.0.beta2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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")