couch_potato 0.6.0 → 0.7.0.pre.1

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.
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