couch_potato 0.6.0 → 0.7.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/.travis.yml +9 -1
- data/CHANGES.md +12 -0
- data/Gemfile.lock +29 -23
- data/MIT-LICENSE.txt +1 -1
- data/README.md +68 -38
- data/Rakefile +19 -60
- data/active_support_3_0.lock +4 -0
- data/active_support_3_1.lock +4 -0
- data/active_support_3_2 +4 -0
- data/active_support_3_2.lock +55 -0
- data/couch_potato.gemspec +1 -0
- data/lib/couch_potato/database.rb +55 -27
- data/lib/couch_potato/persistence/active_model_compliance.rb +6 -2
- data/lib/couch_potato/persistence/callbacks.rb +0 -1
- data/lib/couch_potato/persistence/dirty_attributes.rb +8 -17
- data/lib/couch_potato/persistence/json.rb +3 -2
- data/lib/couch_potato/persistence/properties.rb +19 -8
- data/lib/couch_potato/persistence/simple_property.rb +1 -3
- data/lib/couch_potato/persistence/type_caster.rb +7 -2
- data/lib/couch_potato/persistence.rb +27 -13
- data/lib/couch_potato/railtie.rb +1 -1
- data/lib/couch_potato/rspec/matchers/list_as_matcher.rb +12 -12
- data/lib/couch_potato/rspec/matchers/map_to_matcher.rb +8 -8
- data/lib/couch_potato/rspec/matchers/reduce_to_matcher.rb +10 -10
- data/lib/couch_potato/rspec/matchers.rb +8 -7
- data/lib/couch_potato/validation.rb +15 -11
- data/lib/couch_potato/version.rb +1 -1
- data/lib/couch_potato/view/base_view_spec.rb +14 -12
- data/lib/couch_potato/view/model_view_spec.rb +134 -39
- data/lib/couch_potato/view/properties_view_spec.rb +11 -7
- data/lib/couch_potato/view/view_query.rb +10 -9
- data/lib/couch_potato.rb +25 -10
- data/spec/callbacks_spec.rb +88 -0
- data/spec/create_spec.rb +22 -4
- data/spec/default_property_spec.rb +6 -0
- data/spec/property_spec.rb +81 -44
- data/spec/railtie_spec.rb +20 -18
- data/spec/spec_helper.rb +19 -1
- data/spec/unit/active_model_compliance_spec.rb +17 -11
- data/spec/unit/attributes_spec.rb +33 -10
- data/spec/unit/base_view_spec_spec.rb +19 -5
- data/spec/unit/couch_potato_spec.rb +1 -20
- data/spec/unit/create_spec.rb +2 -2
- data/spec/unit/database_spec.rb +113 -47
- data/spec/unit/dirty_attributes_spec.rb +19 -19
- data/spec/unit/model_view_spec_spec.rb +78 -1
- data/spec/unit/properties_view_spec_spec.rb +18 -5
- data/spec/unit/validation_spec.rb +1 -55
- data/spec/unit/view_query_spec.rb +48 -26
- data/spec/{custom_view_spec.rb → views_spec.rb} +59 -17
- metadata +88 -90
- data/.rvmrc +0 -1
- data/lib/core_ext/object.rb +0 -5
- data/lib/core_ext/string.rb +0 -12
- data/lib/core_ext/symbol.rb +0 -15
- data/lib/couch_potato/validation/with_active_model.rb +0 -27
- data/lib/couch_potato/validation/with_validatable.rb +0 -41
@@ -26,23 +26,4 @@ describe CouchPotato, '.models' do
|
|
26
26
|
|
27
27
|
CouchPotato.models.should include(clazz)
|
28
28
|
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe CouchPotato, 'validation_framework' do
|
32
|
-
before(:each) do
|
33
|
-
@original_validation_framework = CouchPotato::Config.validation_framework
|
34
|
-
end
|
35
|
-
after(:each) do
|
36
|
-
CouchPotato::Config.validation_framework = @original_validation_framework
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should allow setting the validation_framework to :active_model" do
|
40
|
-
CouchPotato::Config.validation_framework = :active_model
|
41
|
-
CouchPotato::Config.validation_framework.should == :active_model
|
42
|
-
end
|
43
|
-
|
44
|
-
it "should allow setting the validation_framework to :validatable" do
|
45
|
-
CouchPotato::Config.validation_framework = :validatable
|
46
|
-
CouchPotato::Config.validation_framework.should == :validatable
|
47
|
-
end
|
48
|
-
end
|
29
|
+
end
|
data/spec/unit/create_spec.rb
CHANGED
@@ -23,14 +23,14 @@ describe "create" do
|
|
23
23
|
|
24
24
|
it "should set created at in the current time zone" do
|
25
25
|
Time.zone = 'Europe/Berlin'
|
26
|
-
Timecop.travel 2010
|
26
|
+
Timecop.travel Time.zone.parse('2010-01-01 12:00 +0100') do
|
27
27
|
create_comment.created_at.to_s.should == '2010-01-01 12:00:00 +0100'
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
it "should set updated at in the current time zone" do
|
32
32
|
Time.zone = 'Europe/Berlin'
|
33
|
-
Timecop.travel 2010
|
33
|
+
Timecop.travel Time.zone.parse('2010-01-01 12:00 +0100') do
|
34
34
|
create_comment.updated_at.to_s.should == '2010-01-01 12:00:00 +0100'
|
35
35
|
end
|
36
36
|
end
|
data/spec/unit/database_spec.rb
CHANGED
@@ -27,17 +27,17 @@ describe CouchPotato::Database, 'full_url_to_database' do
|
|
27
27
|
after(:all) do
|
28
28
|
CouchPotato::Config.database_name = @database_url
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
it "should return the full URL when it starts with https" do
|
32
32
|
CouchPotato::Config.database_name = "https://example.com/database"
|
33
33
|
CouchPotato.full_url_to_database.should == 'https://example.com/database'
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
it "should return the full URL when it starts with http" do
|
37
37
|
CouchPotato::Config.database_name = "http://example.com/database"
|
38
38
|
CouchPotato.full_url_to_database.should == 'http://example.com/database'
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
it "should use localhost when no protocol was specified" do
|
42
42
|
CouchPotato::Config.database_name = "database"
|
43
43
|
CouchPotato.full_url_to_database.should == 'http://127.0.0.1:5984/database'
|
@@ -45,8 +45,11 @@ describe CouchPotato::Database, 'full_url_to_database' do
|
|
45
45
|
end
|
46
46
|
|
47
47
|
describe CouchPotato::Database, 'load' do
|
48
|
+
|
49
|
+
let(:couchrest_db) { stub('couchrest db', :info => nil) }
|
50
|
+
let(:db) { CouchPotato::Database.new couchrest_db }
|
51
|
+
|
48
52
|
it "should raise an exception if nil given" do
|
49
|
-
db = CouchPotato::Database.new(stub('couchrest db', :info => nil))
|
50
53
|
lambda {
|
51
54
|
db.load nil
|
52
55
|
}.should raise_error("Can't load a document without an id (got nil)")
|
@@ -55,33 +58,95 @@ describe CouchPotato::Database, 'load' do
|
|
55
58
|
it "should set itself on the model" do
|
56
59
|
user = mock('user').as_null_object
|
57
60
|
DbTestUser.stub!(:new).and_return(user)
|
58
|
-
|
61
|
+
couchrest_db.stub(:get).and_return DbTestUser.json_create({JSON.create_id => 'DbTestUser'})
|
59
62
|
user.should_receive(:database=).with(db)
|
60
63
|
db.load '1'
|
61
64
|
end
|
62
65
|
|
63
66
|
it "should load namespaced models" do
|
64
|
-
|
67
|
+
couchrest_db.stub(:get).and_return Parent::Child.json_create({JSON.create_id => 'Parent::Child'})
|
65
68
|
db.load('1').class.should == Parent::Child
|
66
69
|
end
|
70
|
+
|
71
|
+
context "when several ids given" do
|
72
|
+
|
73
|
+
let(:doc1) { DbTestUser.new }
|
74
|
+
let(:doc2) { DbTestUser.new }
|
75
|
+
let(:response) do
|
76
|
+
{"rows" => [{}, {"doc" => doc1}, {"doc" => doc2}]}
|
77
|
+
end
|
78
|
+
|
79
|
+
before(:each) do
|
80
|
+
couchrest_db.stub(:bulk_load).and_return response
|
81
|
+
end
|
82
|
+
|
83
|
+
it "requests the couchrest bulk method" do
|
84
|
+
couchrest_db.should_receive(:bulk_load).with(['1', '2', '3'])
|
85
|
+
db.load ['1', '2', '3']
|
86
|
+
end
|
87
|
+
|
88
|
+
it "returns only found documents" do
|
89
|
+
db.load(['1', '2', '3']).should have(2).items
|
90
|
+
end
|
91
|
+
|
92
|
+
it "writes itself to each of the documents" do
|
93
|
+
db.load(['1', '2', '3']).each do |doc|
|
94
|
+
doc.database.should eql(db)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
67
98
|
end
|
68
99
|
|
69
100
|
describe CouchPotato::Database, 'load!' do
|
101
|
+
|
102
|
+
let(:db) { CouchPotato::Database.new(stub('couchrest db', :info => nil).as_null_object) }
|
103
|
+
|
70
104
|
it "should raise an error if no document found" do
|
71
|
-
|
72
|
-
couchrest_db.stub(:get).and_raise(RestClient::ResourceNotFound)
|
73
|
-
db = CouchPotato::Database.new(couchrest_db)
|
105
|
+
db.couchrest_database.stub(:get).and_raise(RestClient::ResourceNotFound)
|
74
106
|
lambda {
|
75
107
|
db.load! '1'
|
76
108
|
}.should raise_error(CouchPotato::NotFound)
|
77
109
|
end
|
110
|
+
|
111
|
+
it 'returns the found document' do
|
112
|
+
doc = stub(:doc).as_null_object
|
113
|
+
db.couchrest_database.stub(:get) {doc}
|
114
|
+
db.load!('1').should == doc
|
115
|
+
end
|
116
|
+
|
117
|
+
context "when several ids given" do
|
118
|
+
|
119
|
+
let(:docs) do
|
120
|
+
[
|
121
|
+
DbTestUser.new(:id => '1'),
|
122
|
+
DbTestUser.new(:id => '2')
|
123
|
+
]
|
124
|
+
end
|
125
|
+
|
126
|
+
before(:each) do
|
127
|
+
db.stub(:load).and_return(docs)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "raises an exception when not all documents could be found" do
|
131
|
+
lambda {
|
132
|
+
db.load! ['1', '2', '3', '4']
|
133
|
+
}.should raise_error(CouchPotato::NotFound, '3, 4')
|
134
|
+
end
|
135
|
+
|
136
|
+
it "raises no exception when all documents are found" do
|
137
|
+
docs << DbTestUser.new(:id => '3')
|
138
|
+
lambda {
|
139
|
+
db.load! ['1', '2', '3']
|
140
|
+
}.should_not raise_error(CouchPotato::NotFound)
|
141
|
+
end
|
142
|
+
end
|
78
143
|
end
|
79
144
|
|
80
145
|
describe CouchPotato::Database, 'save_document' do
|
81
146
|
before(:each) do
|
82
147
|
@db = CouchPotato::Database.new(stub('couchrest db').as_null_object)
|
83
148
|
end
|
84
|
-
|
149
|
+
|
85
150
|
it "should set itself on the model for a new object before doing anything else" do
|
86
151
|
@db.stub(:valid_document?).and_return false
|
87
152
|
user = stub('user', :new? => true).as_null_object
|
@@ -94,18 +159,18 @@ describe CouchPotato::Database, 'save_document' do
|
|
94
159
|
property :name
|
95
160
|
validates_presence_of :name
|
96
161
|
end
|
97
|
-
|
162
|
+
|
98
163
|
it "should return false when creating a new document and the validations failed" do
|
99
164
|
CouchPotato.database.save_document(Category.new).should == false
|
100
165
|
end
|
101
|
-
|
166
|
+
|
102
167
|
it "should return false when saving an existing document and the validations failed" do
|
103
168
|
category = Category.new(:name => "pizza")
|
104
169
|
CouchPotato.database.save_document(category).should == true
|
105
170
|
category.name = nil
|
106
171
|
CouchPotato.database.save_document(category).should == false
|
107
172
|
end
|
108
|
-
|
173
|
+
|
109
174
|
describe "when creating with validate options" do
|
110
175
|
it "should not run the validations when saved with false" do
|
111
176
|
category = Category.new
|
@@ -155,27 +220,27 @@ describe CouchPotato::Database, 'save_document' do
|
|
155
220
|
category.dirty?.should == true
|
156
221
|
end
|
157
222
|
end
|
158
|
-
|
223
|
+
|
159
224
|
describe "when saving documents with errors set in callbacks" do
|
160
225
|
class Vulcan
|
161
226
|
include CouchPotato::Persistence
|
162
227
|
before_validation_on_create :set_errors
|
163
228
|
before_validation_on_update :set_errors
|
164
|
-
|
229
|
+
|
165
230
|
property :name
|
166
231
|
validates_presence_of :name
|
167
|
-
|
232
|
+
|
168
233
|
def set_errors
|
169
234
|
errors.add(:validation, "failed")
|
170
235
|
end
|
171
236
|
end
|
172
|
-
|
237
|
+
|
173
238
|
it "should keep errors added in before_validation_on_* callbacks when creating a new object" do
|
174
239
|
spock = Vulcan.new(:name => 'spock')
|
175
240
|
@db.save_document(spock)
|
176
241
|
spock.errors[:validation].should == ['failed']
|
177
242
|
end
|
178
|
-
|
243
|
+
|
179
244
|
it "should keep errors added in before_validation_on_* callbacks when creating a new object" do
|
180
245
|
spock = Vulcan.new(:name => 'spock')
|
181
246
|
@db.save_document(spock, false)
|
@@ -184,36 +249,36 @@ describe CouchPotato::Database, 'save_document' do
|
|
184
249
|
@db.save_document(spock)
|
185
250
|
spock.errors[:validation].should == ['failed']
|
186
251
|
end
|
187
|
-
|
252
|
+
|
188
253
|
it "should keep errors generated from normal validations together with errors set in normal validations" do
|
189
254
|
spock = Vulcan.new
|
190
255
|
@db.save_document(spock)
|
191
256
|
spock.errors[:validation].should == ['failed']
|
192
257
|
spock.errors[:name].first.should =~ /can't be (empty|blank)/
|
193
258
|
end
|
194
|
-
|
259
|
+
|
195
260
|
it "should clear errors on subsequent, valid saves when creating" do
|
196
261
|
spock = Vulcan.new
|
197
262
|
@db.save_document(spock)
|
198
|
-
|
263
|
+
|
199
264
|
spock.name = 'Spock'
|
200
265
|
@db.save_document(spock)
|
201
266
|
spock.errors[:name].should == []
|
202
267
|
end
|
203
|
-
|
268
|
+
|
204
269
|
it "should clear errors on subsequent, valid saves when updating" do
|
205
270
|
spock = Vulcan.new(:name => 'spock')
|
206
271
|
@db.save_document(spock, false)
|
207
|
-
|
272
|
+
|
208
273
|
spock.name = nil
|
209
274
|
@db.save_document(spock)
|
210
275
|
spock.errors[:name].first.should =~ /can't be (empty|blank)/
|
211
|
-
|
276
|
+
|
212
277
|
spock.name = 'Spock'
|
213
278
|
@db.save_document(spock)
|
214
279
|
spock.errors[:name].should == []
|
215
280
|
end
|
216
|
-
|
281
|
+
|
217
282
|
end
|
218
283
|
end
|
219
284
|
|
@@ -225,11 +290,11 @@ describe CouchPotato::Database, 'first' do
|
|
225
290
|
@spec = stub('view spec', :process_results => [@result]).as_null_object
|
226
291
|
CouchPotato::View::ViewQuery.stub(:new => stub('view query', :query_view! => {'rows' => [@result]}))
|
227
292
|
end
|
228
|
-
|
293
|
+
|
229
294
|
it "should return the first result from a view query" do
|
230
295
|
@db.first(@spec).should == @result
|
231
296
|
end
|
232
|
-
|
297
|
+
|
233
298
|
it "should return nil if there are no results" do
|
234
299
|
@spec.stub(:process_results => [])
|
235
300
|
@db.first(@spec).should be_nil
|
@@ -244,12 +309,12 @@ describe CouchPotato::Database, 'first!' do
|
|
244
309
|
@spec = stub('view spec', :process_results => [@result]).as_null_object
|
245
310
|
CouchPotato::View::ViewQuery.stub(:new => stub('view query', :query_view! => {'rows' => [@result]}))
|
246
311
|
end
|
247
|
-
|
248
|
-
it "
|
312
|
+
|
313
|
+
it "returns the first result from a view query" do
|
249
314
|
@db.first!(@spec).should == @result
|
250
315
|
end
|
251
|
-
|
252
|
-
it "
|
316
|
+
|
317
|
+
it "raises an error if there are no results" do
|
253
318
|
@spec.stub(:process_results => [])
|
254
319
|
lambda {
|
255
320
|
@db.first!(@spec)
|
@@ -265,11 +330,11 @@ describe CouchPotato::Database, 'view' do
|
|
265
330
|
@spec = stub('view spec', :process_results => [@result]).as_null_object
|
266
331
|
CouchPotato::View::ViewQuery.stub(:new => stub('view query', :query_view! => {'rows' => [@result]}))
|
267
332
|
end
|
268
|
-
|
269
|
-
it "
|
333
|
+
|
334
|
+
it "initialzes a view query with map/reduce/list funtions" do
|
270
335
|
@spec.stub(:design_document => 'design_doc', :view_name => 'my_view',
|
271
336
|
:map_function => '<map_code>', :reduce_function => '<reduce_code>',
|
272
|
-
:list_name => 'my_list', :list_function => '<list_code>')
|
337
|
+
:list_name => 'my_list', :list_function => '<list_code>', :language => 'javascript')
|
273
338
|
CouchPotato::View::ViewQuery.should_receive(:new).with(
|
274
339
|
@couchrest_db,
|
275
340
|
'design_doc',
|
@@ -277,41 +342,42 @@ describe CouchPotato::Database, 'view' do
|
|
277
342
|
:map => '<map_code>',
|
278
343
|
:reduce => '<reduce_code>'
|
279
344
|
}},
|
280
|
-
{'my_list' => '<list_code>'}
|
345
|
+
{'my_list' => '<list_code>'},
|
346
|
+
'javascript')
|
281
347
|
@db.view(@spec)
|
282
348
|
end
|
283
|
-
|
284
|
-
it "
|
349
|
+
|
350
|
+
it "initialzes a view query with only map/reduce functions" do
|
285
351
|
@spec.stub(:design_document => 'design_doc', :view_name => 'my_view',
|
286
352
|
:map_function => '<map_code>', :reduce_function => '<reduce_code>',
|
287
|
-
:list_name => nil, :list_function => nil)
|
353
|
+
:list_name => nil, :list_function => nil).as_null_object
|
288
354
|
CouchPotato::View::ViewQuery.should_receive(:new).with(
|
289
355
|
@couchrest_db,
|
290
356
|
'design_doc',
|
291
357
|
{'my_view' => {
|
292
358
|
:map => '<map_code>',
|
293
359
|
:reduce => '<reduce_code>'
|
294
|
-
}}, nil)
|
360
|
+
}}, nil, anything)
|
295
361
|
@db.view(@spec)
|
296
362
|
end
|
297
|
-
|
298
|
-
it "
|
363
|
+
|
364
|
+
it "sets itself on returned results that have an accessor" do
|
299
365
|
@result.stub(:respond_to?).with(:database=).and_return(true)
|
300
366
|
@result.should_receive(:database=).with(@db)
|
301
367
|
@db.view(@spec)
|
302
368
|
end
|
303
|
-
|
304
|
-
it "
|
369
|
+
|
370
|
+
it "does not set itself on returned results that don't have an accessor" do
|
305
371
|
@result.stub(:respond_to?).with(:database=).and_return(false)
|
306
372
|
@result.should_not_receive(:database=).with(@db)
|
307
373
|
@db.view(@spec)
|
308
374
|
end
|
309
|
-
|
310
|
-
it "
|
375
|
+
|
376
|
+
it "does not try to set itself on result sets that are not collections" do
|
311
377
|
lambda {
|
312
378
|
@spec.stub(:process_results => 1)
|
313
379
|
}.should_not raise_error
|
314
|
-
|
380
|
+
|
315
381
|
@db.view(@spec)
|
316
382
|
end
|
317
|
-
end
|
383
|
+
end
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
class Plate
|
4
4
|
include CouchPotato::Persistence
|
5
|
-
|
5
|
+
|
6
6
|
property :food
|
7
7
|
end
|
8
8
|
|
@@ -11,7 +11,7 @@ describe 'dirty attribute tracking' do
|
|
11
11
|
@couchrest_db = stub('database', :save_doc => {'id' => '1', 'rev' => '2'}, :info => nil)
|
12
12
|
@db = CouchPotato::Database.new(@couchrest_db)
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
describe "save" do
|
16
16
|
it "should not save when nothing dirty" do
|
17
17
|
plate = Plate.new :food => 'sushi'
|
@@ -19,13 +19,13 @@ describe 'dirty attribute tracking' do
|
|
19
19
|
@couchrest_db.should_not_receive(:save_doc)
|
20
20
|
@db.save_document(plate)
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
it "should return true when not dirty" do
|
24
24
|
plate = Plate.new :food => 'sushi'
|
25
25
|
@db.save_document!(plate)
|
26
26
|
@db.save_document(plate).should be_true
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
it "should save when there are dirty attributes" do
|
30
30
|
plate = Plate.new :food => 'sushi'
|
31
31
|
@db.save_document!(plate)
|
@@ -34,19 +34,19 @@ describe 'dirty attribute tracking' do
|
|
34
34
|
@db.save_document(plate)
|
35
35
|
end
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
describe "newly created object" do
|
39
|
-
|
39
|
+
|
40
40
|
before(:each) do
|
41
41
|
@plate = Plate.new :food => 'sushi'
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
describe "access old values" do
|
45
45
|
it "should return the old value" do
|
46
46
|
@plate.food = 'burger'
|
47
47
|
@plate.food_was.should == 'sushi'
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
describe "with type BigDecimal" do
|
51
51
|
before(:each) do
|
52
52
|
class Bowl
|
@@ -57,16 +57,16 @@ describe 'dirty attribute tracking' do
|
|
57
57
|
it "should not dup BigDecimal" do
|
58
58
|
|
59
59
|
lambda {
|
60
|
-
Bowl.new :price => BigDecimal.new("5.23")
|
60
|
+
Bowl.new :price => BigDecimal.new("5.23")
|
61
61
|
}.should_not raise_error(TypeError)
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
it "should return the old value" do
|
65
|
-
bowl = Bowl.new :price => BigDecimal.new("5.23")
|
65
|
+
bowl = Bowl.new :price => BigDecimal.new("5.23")
|
66
66
|
bowl.price = BigDecimal.new("2.23")
|
67
67
|
bowl.price_was.should == 5.23
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -79,20 +79,20 @@ describe 'dirty attribute tracking' do
|
|
79
79
|
it "should return false if attribute not changed" do
|
80
80
|
Plate.new.should_not be_food_changed
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
it "should return true if forced dirty" do
|
84
84
|
@plate.is_dirty
|
85
85
|
@plate.should be_dirty
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
describe "object loaded from database" do
|
91
91
|
before(:each) do
|
92
92
|
couchrest_db = stub('database', :get => Plate.json_create({'_id' => '1', '_rev' => '2', 'food' => 'sushi', JSON.create_id => 'Plate'}), :info => nil)
|
93
93
|
@plate = CouchPotato::Database.new(couchrest_db).load_document '1'
|
94
94
|
end
|
95
|
-
|
95
|
+
|
96
96
|
describe "access old values" do
|
97
97
|
it "should return the old value" do
|
98
98
|
@plate.food = 'burger'
|
@@ -111,8 +111,8 @@ describe 'dirty attribute tracking' do
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
end
|
114
|
-
|
115
|
-
|
114
|
+
|
115
|
+
|
116
116
|
describe "after save" do
|
117
117
|
it "should reset all attributes to not dirty" do
|
118
118
|
couchrest_db = stub('database', :get => Plate.json_create({'_id' => '1', '_rev' => '2', 'food' => 'sushi', JSON.create_id => 'Plate'}), :info => nil, :save_doc => {})
|
@@ -122,7 +122,7 @@ describe 'dirty attribute tracking' do
|
|
122
122
|
db.save! @plate
|
123
123
|
@plate.should_not be_food_changed
|
124
124
|
end
|
125
|
-
|
125
|
+
|
126
126
|
it "should reset a forced dirty state" do
|
127
127
|
couchrest_db = stub('database', :get => Plate.json_create({'_id' => '1', '_rev' => '2', 'food' => 'sushi', JSON.create_id => 'Plate'}), :info => nil, :save_doc => {'rev' => '3'})
|
128
128
|
db = CouchPotato::Database.new(couchrest_db)
|
@@ -132,5 +132,5 @@ describe 'dirty attribute tracking' do
|
|
132
132
|
@plate.should_not be_dirty
|
133
133
|
end
|
134
134
|
end
|
135
|
-
|
135
|
+
|
136
136
|
end
|
@@ -5,9 +5,86 @@ describe CouchPotato::View::ModelViewSpec, 'map_function' do
|
|
5
5
|
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {:conditions => 'doc.closed = true'}, {}
|
6
6
|
spec.map_function.should include('if(doc.ruby_class && doc.ruby_class == \'Object\' && (doc.closed = true))')
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
|
+
it 'generates an erlang map function with a single key if the language is erlang' do
|
10
|
+
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {:key => :name, :language => :erlang}, {}
|
11
|
+
spec.map_function.should eql_ignoring_indentation(<<-ERL
|
12
|
+
fun({Doc}) ->
|
13
|
+
case proplists:get_value(<<"ruby_class">>, Doc) of
|
14
|
+
<<"Object">> ->
|
15
|
+
Key = proplists:get_value(<<"name">>, Doc, null),
|
16
|
+
Emit(Key, 1);
|
17
|
+
_ ->
|
18
|
+
ok
|
19
|
+
end
|
20
|
+
end.
|
21
|
+
ERL
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'generates an erlang map function with a composite key if the language is erlang' do
|
26
|
+
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {:key => [:code, :name], :language => :erlang}, {}
|
27
|
+
spec.map_function.should eql_ignoring_indentation(<<-ERL
|
28
|
+
fun({Doc}) ->
|
29
|
+
case proplists:get_value(<<"ruby_class">>, Doc) of
|
30
|
+
<<"Object">> ->
|
31
|
+
Key_0 = proplists:get_value(<<"code">>, Doc, null),
|
32
|
+
Key_1 = proplists:get_value(<<"name">>, Doc, null),
|
33
|
+
Emit([Key_0, Key_1], 1);
|
34
|
+
_ ->
|
35
|
+
ok
|
36
|
+
end
|
37
|
+
end.
|
38
|
+
ERL
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'does not support conditions in erlang' do
|
43
|
+
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {:language => :erlang, :conditions => 'abc'}, {}
|
44
|
+
lambda {
|
45
|
+
spec.map_function
|
46
|
+
}.should raise_error(NotImplementedError)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'does not support a custom emit value in erlang' do
|
50
|
+
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {:language => :erlang, :emit_value => :count}, {}
|
51
|
+
lambda {
|
52
|
+
spec.map_function
|
53
|
+
}.should raise_error(NotImplementedError)
|
54
|
+
end
|
55
|
+
|
9
56
|
it "should not include conditions when they are nil" do
|
10
57
|
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {}, {}
|
11
58
|
spec.map_function.should include('if(doc.ruby_class && doc.ruby_class == \'Object\')')
|
12
59
|
end
|
60
|
+
|
61
|
+
it "should have a custom emit value when specified as symbol" do
|
62
|
+
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {:emit_value => :count}, {}
|
63
|
+
spec.map_function.should include(%{emit(doc[''], doc['count'])})
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should have a custom emit value when specified as string" do
|
67
|
+
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {:emit_value => "doc['a'] + doc['b']"}, {}
|
68
|
+
spec.map_function.should include("emit(doc[''], doc['a'] + doc['b'])")
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should have a custom emit value when specified as integer" do
|
72
|
+
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {:emit_value => 7}, {}
|
73
|
+
spec.map_function.should include("emit(doc[''], 7)")
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should have a custom emit value when specified as float" do
|
77
|
+
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {:emit_value => 7.2}, {}
|
78
|
+
spec.map_function.should include("emit(doc[''], 7.2")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should have a emit value of 1 when nothing is specified" do
|
82
|
+
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {}, {}
|
83
|
+
spec.map_function.should include("emit(doc[''], 1")
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should raise exception when emit value cannot be handled" do
|
87
|
+
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {:emit_value => []}, {}
|
88
|
+
lambda { spec.map_function }.should raise_error
|
89
|
+
end
|
13
90
|
end
|
@@ -3,29 +3,42 @@ require 'couch_potato/rspec'
|
|
3
3
|
|
4
4
|
class Contract
|
5
5
|
include CouchPotato::Persistence
|
6
|
-
|
6
|
+
|
7
7
|
property :date
|
8
8
|
property :terms
|
9
|
-
|
9
|
+
|
10
10
|
view :by_date, :type => :properties, :key => :_id, :properties => [:date]
|
11
11
|
end
|
12
12
|
|
13
13
|
describe CouchPotato::View::PropertiesViewSpec do
|
14
|
+
before(:each) do
|
15
|
+
@default_language = CouchPotato::Config.default_language
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:each) do
|
19
|
+
CouchPotato::Config.default_language = @default_language
|
20
|
+
end
|
21
|
+
|
14
22
|
it "should map the given properties" do
|
15
23
|
Contract.by_date.should map(
|
16
24
|
Contract.new(:date => '2010-01-01', :_id => '1')
|
17
25
|
).to(['1', {"date" => "2010-01-01"}])
|
18
26
|
end
|
19
|
-
|
27
|
+
|
20
28
|
it "should reduce to the number of documents" do
|
21
29
|
Contract.by_date.should reduce(
|
22
30
|
['1', {"date" => "2010-01-01"}], ['2', {"date" => "2010-01-02"}]
|
23
31
|
).to(2)
|
24
32
|
end
|
25
|
-
|
33
|
+
|
26
34
|
it "should rereduce the number of documents" do
|
27
35
|
Contract.by_date.should rereduce(
|
28
36
|
nil, [12, 13]
|
29
37
|
).to(25)
|
30
38
|
end
|
31
|
-
|
39
|
+
|
40
|
+
it 'always uses javascript' do
|
41
|
+
CouchPotato::Config.default_language = :erlang
|
42
|
+
CouchPotato::View::PropertiesViewSpec.new(Contract, 'all', {}, {}).language.should == :javascript
|
43
|
+
end
|
44
|
+
end
|