couchrest_model 1.0.0 → 1.1.0.beta
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.
- data/.gitignore +1 -1
- data/Gemfile.lock +19 -20
- data/README.md +145 -20
- data/VERSION +1 -1
- data/couchrest_model.gemspec +2 -3
- data/history.txt +14 -0
- data/lib/couchrest/model/associations.rb +4 -4
- data/lib/couchrest/model/base.rb +5 -0
- data/lib/couchrest/model/callbacks.rb +1 -2
- data/lib/couchrest/model/collection.rb +1 -1
- data/lib/couchrest/model/designs/view.rb +486 -0
- data/lib/couchrest/model/designs.rb +81 -0
- data/lib/couchrest/model/document_queries.rb +1 -1
- data/lib/couchrest/model/persistence.rb +25 -16
- data/lib/couchrest/model/properties.rb +5 -1
- data/lib/couchrest/model/property.rb +2 -2
- data/lib/couchrest/model/proxyable.rb +152 -0
- data/lib/couchrest/model/typecast.rb +1 -1
- data/lib/couchrest/model/validations/casted_model.rb +3 -1
- data/lib/couchrest/model/validations/locale/en.yml +1 -1
- data/lib/couchrest/model/validations/uniqueness.rb +6 -7
- data/lib/couchrest/model/validations.rb +1 -0
- data/lib/couchrest/model/views.rb +11 -9
- data/lib/couchrest_model.rb +3 -0
- data/spec/couchrest/assocations_spec.rb +2 -2
- data/spec/couchrest/base_spec.rb +15 -1
- data/spec/couchrest/casted_model_spec.rb +30 -12
- data/spec/couchrest/class_proxy_spec.rb +2 -2
- data/spec/couchrest/collection_spec.rb +89 -0
- data/spec/couchrest/designs/view_spec.rb +766 -0
- data/spec/couchrest/designs_spec.rb +110 -0
- data/spec/couchrest/persistence_spec.rb +36 -7
- data/spec/couchrest/property_spec.rb +15 -0
- data/spec/couchrest/proxyable_spec.rb +329 -0
- data/spec/couchrest/{validations.rb → validations_spec.rb} +1 -3
- data/spec/couchrest/view_spec.rb +19 -91
- data/spec/fixtures/base.rb +8 -6
- data/spec/fixtures/more/article.rb +1 -1
- data/spec/fixtures/more/course.rb +4 -2
- metadata +21 -76
- data/lib/couchrest/model/view.rb +0 -190
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
|
3
|
+
class DesignModel < CouchRest::Model::Base
|
4
|
+
|
5
|
+
end
|
6
|
+
|
7
|
+
describe "Design" do
|
8
|
+
|
9
|
+
it "should accessable from model" do
|
10
|
+
DesignModel.respond_to?(:design).should be_true
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "class methods" do
|
14
|
+
|
15
|
+
describe ".design" do
|
16
|
+
before :each do
|
17
|
+
@mapper = mock('DesignMapper')
|
18
|
+
@mapper.stub!(:create_view_method)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should instantiate a new DesignMapper" do
|
22
|
+
CouchRest::Model::Designs::DesignMapper.should_receive(:new).with(DesignModel).and_return(@mapper)
|
23
|
+
@mapper.should_receive(:create_view_method).with(:all)
|
24
|
+
@mapper.should_receive(:instance_eval)
|
25
|
+
DesignModel.design() { }
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should allow methods to be called in mapper" do
|
29
|
+
@mapper.should_receive(:foo)
|
30
|
+
CouchRest::Model::Designs::DesignMapper.stub!(:new).and_return(@mapper)
|
31
|
+
DesignModel.design { foo }
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should request a design refresh" do
|
35
|
+
DesignModel.should_receive(:req_design_doc_refresh)
|
36
|
+
DesignModel.design() { }
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should work even if a block is not provided" do
|
40
|
+
lambda { DesignModel.design }.should_not raise_error
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "default_per_page" do
|
46
|
+
it "should return 25 default" do
|
47
|
+
DesignModel.default_per_page.should eql(25)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe ".paginates_per" do
|
52
|
+
it "should set the default per page value" do
|
53
|
+
DesignModel.paginates_per(21)
|
54
|
+
DesignModel.default_per_page.should eql(21)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "DesignMapper" do
|
60
|
+
|
61
|
+
before :all do
|
62
|
+
@klass = CouchRest::Model::Designs::DesignMapper
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should initialize and set model" do
|
66
|
+
object = @klass.new(DesignModel)
|
67
|
+
object.send(:model).should eql(DesignModel)
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#view" do
|
71
|
+
|
72
|
+
before :each do
|
73
|
+
@object = @klass.new(DesignModel)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should call create method on view" do
|
77
|
+
CouchRest::Model::Designs::View.should_receive(:create).with(DesignModel, 'test', {})
|
78
|
+
@object.view('test')
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should create a method on parent model" do
|
82
|
+
CouchRest::Model::Designs::View.stub!(:create)
|
83
|
+
@object.view('test_view')
|
84
|
+
DesignModel.should respond_to(:test_view)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should create a method for view instance" do
|
88
|
+
CouchRest::Model::Designs::View.stub!(:create)
|
89
|
+
@object.should_receive(:create_view_method).with('test')
|
90
|
+
@object.view('test')
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "#create_view_method" do
|
96
|
+
before :each do
|
97
|
+
@object = @klass.new(DesignModel)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should create a method that returns view instance" do
|
101
|
+
CouchRest::Model::Designs::View.should_receive(:new).with(DesignModel, {}, 'test_view').and_return(nil)
|
102
|
+
@object.create_view_method('test_view')
|
103
|
+
DesignModel.test_view
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -15,17 +15,17 @@ describe "Model Persistence" do
|
|
15
15
|
describe "creating a new document from database" do
|
16
16
|
|
17
17
|
it "should instantialize" do
|
18
|
-
doc = Article.
|
18
|
+
doc = Article.build_from_database({'_id' => 'testitem1', '_rev' => 123, 'couchrest-type' => 'Article', 'name' => 'my test'})
|
19
19
|
doc.class.should eql(Article)
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should instantialize of same class if no couchrest-type included from DB" do
|
23
|
-
doc = Article.
|
23
|
+
doc = Article.build_from_database({'_id' => 'testitem1', '_rev' => 123, 'name' => 'my test'})
|
24
24
|
doc.class.should eql(Article)
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should instantialize document of different type" do
|
28
|
-
doc = Article.
|
28
|
+
doc = Article.build_from_database({'_id' => 'testitem2', '_rev' => 123, Article.model_type_key => 'WithTemplateAndUniqueID', 'name' => 'my test'})
|
29
29
|
doc.class.should eql(WithTemplateAndUniqueID)
|
30
30
|
end
|
31
31
|
|
@@ -329,14 +329,14 @@ describe "Model Persistence" do
|
|
329
329
|
|
330
330
|
describe "validation" do
|
331
331
|
it "should run before_validation before validating" do
|
332
|
-
@doc.
|
332
|
+
@doc.run_before_validation.should be_nil
|
333
333
|
@doc.should be_valid
|
334
|
-
@doc.
|
334
|
+
@doc.run_before_validation.should be_true
|
335
335
|
end
|
336
336
|
it "should run after_validation after validating" do
|
337
|
-
@doc.
|
337
|
+
@doc.run_after_validation.should be_nil
|
338
338
|
@doc.should be_valid
|
339
|
-
@doc.
|
339
|
+
@doc.run_after_validation.should be_true
|
340
340
|
end
|
341
341
|
end
|
342
342
|
|
@@ -412,4 +412,33 @@ describe "Model Persistence" do
|
|
412
412
|
end
|
413
413
|
|
414
414
|
|
415
|
+
describe "#reload" do
|
416
|
+
it "reloads defined attributes" do
|
417
|
+
i = Article.create!(:title => "Reload when changed")
|
418
|
+
i.title.should == "Reload when changed"
|
419
|
+
|
420
|
+
i.title = "..."
|
421
|
+
i.title.should == "..."
|
422
|
+
|
423
|
+
i.reload
|
424
|
+
i.title.should == "Reload when changed"
|
425
|
+
end
|
426
|
+
|
427
|
+
it "reloads defined attributes set to nil" do
|
428
|
+
i = Article.create!(:title => "Reload when nil")
|
429
|
+
i.title.should == "Reload when nil"
|
430
|
+
|
431
|
+
i.title = nil
|
432
|
+
i.title.should be_nil
|
433
|
+
|
434
|
+
i.reload
|
435
|
+
i.title.should == "Reload when nil"
|
436
|
+
end
|
437
|
+
|
438
|
+
it "returns self" do
|
439
|
+
i = Article.create!(:title => "Reload return self")
|
440
|
+
i.reload.should be(i)
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
415
444
|
end
|
@@ -340,6 +340,11 @@ describe "Model properties" do
|
|
340
340
|
@course.estimate.should eql(1232434123.323)
|
341
341
|
end
|
342
342
|
|
343
|
+
it "should handle numbers with whitespace" do
|
344
|
+
@course.estimate = " 24.35 "
|
345
|
+
@course.estimate.should eql(24.35)
|
346
|
+
end
|
347
|
+
|
343
348
|
[ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
|
344
349
|
it "does not typecast non-numeric value #{value.inspect}" do
|
345
350
|
@course.estimate = value
|
@@ -426,6 +431,11 @@ describe "Model properties" do
|
|
426
431
|
@course['hours'].should eql(-24)
|
427
432
|
end
|
428
433
|
|
434
|
+
it "should handle numbers with whitespace" do
|
435
|
+
@course.hours = " 24 "
|
436
|
+
@course['hours'].should eql(24)
|
437
|
+
end
|
438
|
+
|
429
439
|
[ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
|
430
440
|
it "does not typecast non-numeric value #{value.inspect}" do
|
431
441
|
@course.hours = value
|
@@ -511,6 +521,11 @@ describe "Model properties" do
|
|
511
521
|
@course['profit'].should eql(BigDecimal('-24.35'))
|
512
522
|
end
|
513
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
|
+
|
514
529
|
[ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
|
515
530
|
it "does not typecast non-numeric value #{value.inspect}" do
|
516
531
|
@course.profit = value
|
@@ -0,0 +1,329 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
|
3
|
+
require File.join(FIXTURE_PATH, 'more', 'cat')
|
4
|
+
|
5
|
+
class DummyProxyable < CouchRest::Model::Base
|
6
|
+
def proxy_database
|
7
|
+
'db' # Do not use this!
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class ProxyKitten < CouchRest::Model::Base
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "Proxyable" do
|
15
|
+
|
16
|
+
it "should provide #model_proxy method" do
|
17
|
+
DummyProxyable.new.should respond_to(:model_proxy)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "class methods" do
|
21
|
+
|
22
|
+
describe ".proxy_for" do
|
23
|
+
|
24
|
+
it "should be provided" do
|
25
|
+
DummyProxyable.should respond_to(:proxy_for)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should create a new method" do
|
29
|
+
DummyProxyable.stub!(:method_defined?).and_return(true)
|
30
|
+
DummyProxyable.proxy_for(:cats)
|
31
|
+
DummyProxyable.new.should respond_to(:cats)
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "generated method" do
|
35
|
+
it "should call ModelProxy" do
|
36
|
+
DummyProxyable.proxy_for(:cats)
|
37
|
+
@obj = DummyProxyable.new
|
38
|
+
CouchRest::Model::Proxyable::ModelProxy.should_receive(:new).with(Cat, @obj, 'dummy_proxyable', 'db').and_return(true)
|
39
|
+
@obj.should_receive('proxy_database').and_return('db')
|
40
|
+
@obj.should_receive(:respond_to?).with('proxy_database').and_return(true)
|
41
|
+
@obj.cats
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should call class on root namespace" do
|
45
|
+
class ::Document < CouchRest::Model::Base
|
46
|
+
def self.foo; puts 'bar'; end
|
47
|
+
end
|
48
|
+
DummyProxyable.proxy_for(:documents)
|
49
|
+
@obj = DummyProxyable.new
|
50
|
+
CouchRest::Model::Proxyable::ModelProxy.should_receive(:new).with(::Document, @obj, 'dummy_proxyable', 'db').and_return(true)
|
51
|
+
@obj.should_receive('proxy_database').and_return('db')
|
52
|
+
@obj.should_receive(:respond_to?).with('proxy_database').and_return(true)
|
53
|
+
@obj.documents
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should raise an error if the database method is missing" do
|
57
|
+
DummyProxyable.proxy_for(:cats)
|
58
|
+
@obj = DummyProxyable.new
|
59
|
+
@obj.should_receive(:respond_to?).with('proxy_database').and_return(false)
|
60
|
+
lambda { @obj.cats }.should raise_error(StandardError, "Missing #proxy_database method for proxy")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should raise an error if custom database method missing" do
|
64
|
+
DummyProxyable.proxy_for(:proxy_kittens, :database_method => "foobardom")
|
65
|
+
@obj = DummyProxyable.new
|
66
|
+
lambda { @obj.proxy_kittens }.should raise_error(StandardError, "Missing #foobardom method for proxy")
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
describe ".proxied_by" do
|
75
|
+
it "should be provided" do
|
76
|
+
DummyProxyable.should respond_to(:proxied_by)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should add an attribute accessor" do
|
80
|
+
DummyProxyable.proxied_by(:foobar)
|
81
|
+
DummyProxyable.new.should respond_to(:foobar)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should raise an error if model name pre-defined" do
|
85
|
+
lambda { DummyProxyable.proxied_by(:object_id) }.should raise_error
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "ModelProxy" do
|
92
|
+
|
93
|
+
before :all do
|
94
|
+
@klass = CouchRest::Model::Proxyable::ModelProxy
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should initialize and set variables" do
|
98
|
+
@obj = @klass.new(Cat, 'owner', 'owner_name', 'database')
|
99
|
+
@obj.model.should eql(Cat)
|
100
|
+
@obj.owner.should eql('owner')
|
101
|
+
@obj.owner_name.should eql('owner_name')
|
102
|
+
@obj.database.should eql('database')
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "instance" do
|
106
|
+
|
107
|
+
before :each do
|
108
|
+
@obj = @klass.new(Cat, 'owner', 'owner_name', 'database')
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should proxy new call" do
|
112
|
+
Cat.should_receive(:new).and_return({})
|
113
|
+
@obj.should_receive(:proxy_update).and_return(true)
|
114
|
+
@obj.new
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should proxy build_from_database" do
|
118
|
+
Cat.should_receive(:build_from_database).and_return({})
|
119
|
+
@obj.should_receive(:proxy_update).with({}).and_return(true)
|
120
|
+
@obj.build_from_database
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "#method_missing" do
|
124
|
+
it "should return design view object" do
|
125
|
+
m = "by_some_property"
|
126
|
+
inst = mock('DesignView')
|
127
|
+
inst.stub!(:proxy).and_return(inst)
|
128
|
+
@obj.should_receive(:has_view?).with(m).and_return(true)
|
129
|
+
Cat.should_receive(:respond_to?).with(m).and_return(true)
|
130
|
+
Cat.should_receive(:send).with(m).and_return(inst)
|
131
|
+
@obj.method_missing(m).should eql(inst)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should call view if necessary" do
|
135
|
+
m = "by_some_property"
|
136
|
+
@obj.should_receive(:has_view?).with(m).and_return(true)
|
137
|
+
Cat.should_receive(:respond_to?).with(m).and_return(false)
|
138
|
+
@obj.should_receive(:view).with(m, {}).and_return('view')
|
139
|
+
@obj.method_missing(m).should eql('view')
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should provide wrapper for #first_from_view" do
|
143
|
+
m = "find_by_some_property"
|
144
|
+
view = "by_some_property"
|
145
|
+
@obj.should_receive(:has_view?).with(m).and_return(false)
|
146
|
+
@obj.should_receive(:has_view?).with(view).and_return(true)
|
147
|
+
@obj.should_receive(:first_from_view).with(view).and_return('view')
|
148
|
+
@obj.method_missing(m).should eql('view')
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should proxy #all" do
|
154
|
+
Cat.should_receive(:all).with({:database => 'database'})
|
155
|
+
@obj.should_receive(:proxy_update_all)
|
156
|
+
@obj.all
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should proxy #count" do
|
160
|
+
Cat.should_receive(:all).with({:database => 'database', :raw => true, :limit => 0}).and_return({'total_rows' => 3})
|
161
|
+
@obj.count.should eql(3)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should proxy #first" do
|
165
|
+
Cat.should_receive(:first).with({:database => 'database'})
|
166
|
+
@obj.should_receive(:proxy_update)
|
167
|
+
@obj.first
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should proxy #last" do
|
171
|
+
Cat.should_receive(:last).with({:database => 'database'})
|
172
|
+
@obj.should_receive(:proxy_update)
|
173
|
+
@obj.last
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should proxy #get" do
|
177
|
+
Cat.should_receive(:get).with(32, 'database')
|
178
|
+
@obj.should_receive(:proxy_update)
|
179
|
+
@obj.get(32)
|
180
|
+
end
|
181
|
+
it "should proxy #find" do
|
182
|
+
Cat.should_receive(:get).with(32, 'database')
|
183
|
+
@obj.should_receive(:proxy_update)
|
184
|
+
@obj.find(32)
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should proxy #has_view?" do
|
188
|
+
Cat.should_receive(:has_view?).with('view').and_return(false)
|
189
|
+
@obj.has_view?('view')
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should proxy #view_by" do
|
193
|
+
Cat.should_receive(:view_by).with('name').and_return(false)
|
194
|
+
@obj.view_by('name')
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should proxy #view" do
|
198
|
+
Cat.should_receive(:view).with('view', {:database => 'database'})
|
199
|
+
@obj.should_receive(:proxy_update_all)
|
200
|
+
@obj.view('view')
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should proxy #first_from_view" do
|
204
|
+
Cat.should_receive(:first_from_view).with('view', {:database => 'database'})
|
205
|
+
@obj.should_receive(:proxy_update)
|
206
|
+
@obj.first_from_view('view')
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should proxy design_doc" do
|
210
|
+
Cat.should_receive(:design_doc)
|
211
|
+
@obj.design_doc
|
212
|
+
end
|
213
|
+
|
214
|
+
describe "#refresh_design_doc" do
|
215
|
+
it "should be proxied without database arg" do
|
216
|
+
Cat.should_receive(:refresh_design_doc).with('database')
|
217
|
+
@obj.refresh_design_doc
|
218
|
+
end
|
219
|
+
it "should be proxied with database arg" do
|
220
|
+
Cat.should_receive(:refresh_design_doc).with('db')
|
221
|
+
@obj.refresh_design_doc('db')
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
describe "#save_design_doc" do
|
226
|
+
it "should be proxied without args" do
|
227
|
+
Cat.should_receive(:save_design_doc).with('database')
|
228
|
+
@obj.save_design_doc
|
229
|
+
end
|
230
|
+
|
231
|
+
it "should be proxied with database arg" do
|
232
|
+
Cat.should_receive(:save_design_doc).with('db')
|
233
|
+
@obj.save_design_doc('db')
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
|
239
|
+
### Updating methods
|
240
|
+
|
241
|
+
describe "#proxy_update" do
|
242
|
+
it "should set returned doc fields" do
|
243
|
+
doc = mock(:Document)
|
244
|
+
doc.should_receive(:respond_to?).with(:database=).and_return(true)
|
245
|
+
doc.should_receive(:database=).with('database')
|
246
|
+
doc.should_receive(:respond_to?).with(:model_proxy=).and_return(true)
|
247
|
+
doc.should_receive(:model_proxy=).with(@obj)
|
248
|
+
doc.should_receive(:respond_to?).with('owner_name=').and_return(true)
|
249
|
+
doc.should_receive(:send).with('owner_name=', 'owner')
|
250
|
+
@obj.send(:proxy_update, doc).should eql(doc)
|
251
|
+
end
|
252
|
+
|
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)
|
258
|
+
doc.should_not_receive(:model_proxy=)
|
259
|
+
doc.should_receive(:respond_to?).with('owner_name=').and_return(false)
|
260
|
+
doc.should_not_receive(:owner_name=)
|
261
|
+
@obj.send(:proxy_update, doc).should eql(doc)
|
262
|
+
end
|
263
|
+
|
264
|
+
it "should pass nil straight through without errors" do
|
265
|
+
lambda { @obj.send(:proxy_update, nil).should eql(nil) }.should_not raise_error
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
it "#proxy_update_all should update array of docs" do
|
270
|
+
docs = [{}, {}]
|
271
|
+
@obj.should_receive(:proxy_update).twice.with({})
|
272
|
+
@obj.send(:proxy_update_all, docs)
|
273
|
+
end
|
274
|
+
|
275
|
+
end
|
276
|
+
|
277
|
+
end
|
278
|
+
|
279
|
+
describe "scenarios" do
|
280
|
+
|
281
|
+
before :all do
|
282
|
+
class ProxyableCompany < CouchRest::Model::Base
|
283
|
+
use_database DB
|
284
|
+
property :slug
|
285
|
+
proxy_for :proxyable_invoices
|
286
|
+
def proxy_database
|
287
|
+
@db ||= TEST_SERVER.database!(TESTDB + "-#{slug}")
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
class ProxyableInvoice < CouchRest::Model::Base
|
292
|
+
property :client
|
293
|
+
property :total
|
294
|
+
proxied_by :proxyable_company
|
295
|
+
validates_uniqueness_of :client
|
296
|
+
design do
|
297
|
+
view :by_total
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
|
302
|
+
@company = ProxyableCompany.create(:slug => 'samco')
|
303
|
+
end
|
304
|
+
|
305
|
+
it "should create the new database" do
|
306
|
+
@company.proxyable_invoices.all.should be_empty
|
307
|
+
TEST_SERVER.databases.find{|db| db =~ /#{TESTDB}-samco/}.should_not be_nil
|
308
|
+
end
|
309
|
+
|
310
|
+
it "should allow creation of new entries" do
|
311
|
+
inv = @company.proxyable_invoices.new(:client => "Lorena", :total => 35)
|
312
|
+
inv.save.should be_true
|
313
|
+
@company.proxyable_invoices.count.should eql(1)
|
314
|
+
@company.proxyable_invoices.first.client.should eql("Lorena")
|
315
|
+
end
|
316
|
+
|
317
|
+
it "should validate uniqueness" do
|
318
|
+
inv = @company.proxyable_invoices.new(:client => "Lorena", :total => 40)
|
319
|
+
inv.save.should be_false
|
320
|
+
end
|
321
|
+
|
322
|
+
it "should allow design views" do
|
323
|
+
item = @company.proxyable_invoices.by_total.key(35).first
|
324
|
+
item.client.should eql('Lorena')
|
325
|
+
end
|
326
|
+
|
327
|
+
end
|
328
|
+
|
329
|
+
end
|
@@ -25,7 +25,7 @@ describe "Validations" do
|
|
25
25
|
it "should not validate a non-unique document" do
|
26
26
|
@obj = WithUniqueValidation.create(:title => 'title 1')
|
27
27
|
@obj.should_not be_valid
|
28
|
-
@obj.errors[:title].should
|
28
|
+
@obj.errors[:title].should == ["has already been taken"]
|
29
29
|
end
|
30
30
|
|
31
31
|
it "should save already created document" do
|
@@ -57,7 +57,6 @@ describe "Validations" do
|
|
57
57
|
@obj.class.should_receive('view').and_return({'rows' => [ ]})
|
58
58
|
@obj.valid?
|
59
59
|
end
|
60
|
-
|
61
60
|
end
|
62
61
|
|
63
62
|
context "with a proxy parameter" do
|
@@ -76,7 +75,6 @@ describe "Validations" do
|
|
76
75
|
proxy.should_receive('view').and_return({'rows' => [ ]})
|
77
76
|
@obj.valid?
|
78
77
|
end
|
79
|
-
|
80
78
|
end
|
81
79
|
|
82
80
|
|