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.
Files changed (58) hide show
  1. data/.gitignore +0 -1
  2. data/.travis.yml +9 -1
  3. data/CHANGES.md +12 -0
  4. data/Gemfile.lock +29 -23
  5. data/MIT-LICENSE.txt +1 -1
  6. data/README.md +68 -38
  7. data/Rakefile +19 -60
  8. data/active_support_3_0.lock +4 -0
  9. data/active_support_3_1.lock +4 -0
  10. data/active_support_3_2 +4 -0
  11. data/active_support_3_2.lock +55 -0
  12. data/couch_potato.gemspec +1 -0
  13. data/lib/couch_potato/database.rb +55 -27
  14. data/lib/couch_potato/persistence/active_model_compliance.rb +6 -2
  15. data/lib/couch_potato/persistence/callbacks.rb +0 -1
  16. data/lib/couch_potato/persistence/dirty_attributes.rb +8 -17
  17. data/lib/couch_potato/persistence/json.rb +3 -2
  18. data/lib/couch_potato/persistence/properties.rb +19 -8
  19. data/lib/couch_potato/persistence/simple_property.rb +1 -3
  20. data/lib/couch_potato/persistence/type_caster.rb +7 -2
  21. data/lib/couch_potato/persistence.rb +27 -13
  22. data/lib/couch_potato/railtie.rb +1 -1
  23. data/lib/couch_potato/rspec/matchers/list_as_matcher.rb +12 -12
  24. data/lib/couch_potato/rspec/matchers/map_to_matcher.rb +8 -8
  25. data/lib/couch_potato/rspec/matchers/reduce_to_matcher.rb +10 -10
  26. data/lib/couch_potato/rspec/matchers.rb +8 -7
  27. data/lib/couch_potato/validation.rb +15 -11
  28. data/lib/couch_potato/version.rb +1 -1
  29. data/lib/couch_potato/view/base_view_spec.rb +14 -12
  30. data/lib/couch_potato/view/model_view_spec.rb +134 -39
  31. data/lib/couch_potato/view/properties_view_spec.rb +11 -7
  32. data/lib/couch_potato/view/view_query.rb +10 -9
  33. data/lib/couch_potato.rb +25 -10
  34. data/spec/callbacks_spec.rb +88 -0
  35. data/spec/create_spec.rb +22 -4
  36. data/spec/default_property_spec.rb +6 -0
  37. data/spec/property_spec.rb +81 -44
  38. data/spec/railtie_spec.rb +20 -18
  39. data/spec/spec_helper.rb +19 -1
  40. data/spec/unit/active_model_compliance_spec.rb +17 -11
  41. data/spec/unit/attributes_spec.rb +33 -10
  42. data/spec/unit/base_view_spec_spec.rb +19 -5
  43. data/spec/unit/couch_potato_spec.rb +1 -20
  44. data/spec/unit/create_spec.rb +2 -2
  45. data/spec/unit/database_spec.rb +113 -47
  46. data/spec/unit/dirty_attributes_spec.rb +19 -19
  47. data/spec/unit/model_view_spec_spec.rb +78 -1
  48. data/spec/unit/properties_view_spec_spec.rb +18 -5
  49. data/spec/unit/validation_spec.rb +1 -55
  50. data/spec/unit/view_query_spec.rb +48 -26
  51. data/spec/{custom_view_spec.rb → views_spec.rb} +59 -17
  52. metadata +88 -90
  53. data/.rvmrc +0 -1
  54. data/lib/core_ext/object.rb +0 -5
  55. data/lib/core_ext/string.rb +0 -12
  56. data/lib/core_ext/symbol.rb +0 -15
  57. data/lib/couch_potato/validation/with_active_model.rb +0 -27
  58. 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
@@ -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, 1, 1, 12 do
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, 1, 1, 12 do
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
@@ -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
- db = CouchPotato::Database.new(stub('couchrest db', :info => nil, :get => DbTestUser.json_create({JSON.create_id => 'DbTestUser'})))
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
- db = CouchPotato::Database.new(stub('couchrest db', :info => nil, :get => Parent::Child.json_create({JSON.create_id => 'Parent::Child'})))
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
- couchrest_db = stub('couchrest db', :info => nil)
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 "should return the first result from a view query" do
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 "should raise an error if there are no results" do
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 "should initialze a view query with map/reduce/list funtions" do
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 "should initialze a view query with only map/reduce functions" do
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 "should set itself on returned results that have an accessor" do
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 "should not set itself on returned results that don't have an accessor" do
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 "should not try to set itself on result sets that are not collections" do
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
- end
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