couchrest_model 2.1.0.rc1 → 2.2.0.beta1

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +15 -4
  4. data/Gemfile.activesupport-4.x +4 -0
  5. data/Gemfile.activesupport-5.x +4 -0
  6. data/README.md +2 -0
  7. data/VERSION +1 -1
  8. data/couchrest_model.gemspec +3 -2
  9. data/history.md +14 -1
  10. data/lib/couchrest/model/associations.rb +3 -8
  11. data/lib/couchrest/model/base.rb +15 -7
  12. data/lib/couchrest/model/casted_array.rb +22 -34
  13. data/lib/couchrest/model/configuration.rb +2 -0
  14. data/lib/couchrest/model/design.rb +4 -3
  15. data/lib/couchrest/model/designs/view.rb +37 -32
  16. data/lib/couchrest/model/dirty.rb +93 -19
  17. data/lib/couchrest/model/embeddable.rb +2 -14
  18. data/lib/couchrest/model/extended_attachments.rb +2 -4
  19. data/lib/couchrest/model/persistence.rb +14 -17
  20. data/lib/couchrest/model/properties.rb +46 -54
  21. data/lib/couchrest/model/property.rb +0 -3
  22. data/lib/couchrest/model/proxyable.rb +20 -4
  23. data/lib/couchrest/model/validations/uniqueness.rb +4 -1
  24. data/lib/couchrest_model.rb +2 -2
  25. data/spec/fixtures/models/article.rb +1 -1
  26. data/spec/fixtures/models/card.rb +2 -1
  27. data/spec/fixtures/models/person.rb +1 -0
  28. data/spec/fixtures/models/project.rb +3 -0
  29. data/spec/unit/assocations_spec.rb +73 -73
  30. data/spec/unit/attachment_spec.rb +34 -34
  31. data/spec/unit/base_spec.rb +102 -102
  32. data/spec/unit/casted_array_spec.rb +7 -7
  33. data/spec/unit/casted_spec.rb +7 -7
  34. data/spec/unit/configuration_spec.rb +11 -11
  35. data/spec/unit/connection_spec.rb +30 -30
  36. data/spec/unit/core_extensions/{time_parsing.rb → time_parsing_spec.rb} +21 -21
  37. data/spec/unit/design_spec.rb +38 -38
  38. data/spec/unit/designs/design_mapper_spec.rb +26 -26
  39. data/spec/unit/designs/migrations_spec.rb +13 -13
  40. data/spec/unit/designs/view_spec.rb +319 -274
  41. data/spec/unit/designs_spec.rb +39 -39
  42. data/spec/unit/dirty_spec.rb +188 -103
  43. data/spec/unit/embeddable_spec.rb +119 -117
  44. data/spec/unit/inherited_spec.rb +4 -4
  45. data/spec/unit/persistence_spec.rb +122 -122
  46. data/spec/unit/properties_spec.rb +466 -16
  47. data/spec/unit/property_protection_spec.rb +32 -32
  48. data/spec/unit/property_spec.rb +45 -436
  49. data/spec/unit/proxyable_spec.rb +140 -82
  50. data/spec/unit/subclass_spec.rb +14 -14
  51. data/spec/unit/translations_spec.rb +5 -5
  52. data/spec/unit/typecast_spec.rb +131 -131
  53. data/spec/unit/utils/migrate_spec.rb +2 -2
  54. data/spec/unit/validations_spec.rb +31 -31
  55. metadata +27 -12
  56. data/lib/couchrest/model/casted_hash.rb +0 -84
@@ -31,11 +31,11 @@ describe CouchRest::Model::Design do
31
31
 
32
32
  describe ".method_name" do
33
33
  it "should return standard method name" do
34
- @klass.method_name.should eql('design_doc')
34
+ expect(@klass.method_name).to eql('design_doc')
35
35
  end
36
36
 
37
37
  it "should add prefix to standard method name" do
38
- @klass.method_name('stats').should eql('stats_design_doc')
38
+ expect(@klass.method_name('stats')).to eql('stats_design_doc')
39
39
  end
40
40
  end
41
41
 
@@ -45,23 +45,23 @@ describe CouchRest::Model::Design do
45
45
 
46
46
  before :each do
47
47
  @model = double("ModelExample")
48
- @model.stub(:to_s).and_return("ModelExample")
48
+ allow(@model).to receive(:to_s).and_return("ModelExample")
49
49
  @obj = CouchRest::Model::Design.new(@model)
50
50
  end
51
51
 
52
52
 
53
53
  describe "initialisation without prefix" do
54
54
  it "should associate model and set method name" do
55
- @obj.model.should eql(@model)
56
- @obj.method_name.should eql("design_doc")
55
+ expect(@obj.model).to eql(@model)
56
+ expect(@obj.method_name).to eql("design_doc")
57
57
  end
58
58
 
59
59
  it "should generate correct id" do
60
- @obj['_id'].should eql("_design/ModelExample")
60
+ expect(@obj['_id']).to eql("_design/ModelExample")
61
61
  end
62
62
 
63
63
  it "should apply defaults" do
64
- @obj['language'].should eql('javascript')
64
+ expect(@obj['language']).to eql('javascript')
65
65
  end
66
66
  end
67
67
 
@@ -69,13 +69,13 @@ describe CouchRest::Model::Design do
69
69
 
70
70
  it "should associate model and set method name" do
71
71
  @obj = CouchRest::Model::Design.new(@model, 'stats')
72
- @obj.model.should eql(@model)
73
- @obj.method_name.should eql("stats_design_doc")
72
+ expect(@obj.model).to eql(@model)
73
+ expect(@obj.method_name).to eql("stats_design_doc")
74
74
  end
75
75
 
76
76
  it "should generate correct id with prefix" do
77
77
  @obj = CouchRest::Model::Design.new(@model, 'stats')
78
- @obj['_id'].should eql("_design/ModelExample_stats")
78
+ expect(@obj['_id']).to eql("_design/ModelExample_stats")
79
79
  end
80
80
 
81
81
  end
@@ -86,7 +86,7 @@ describe CouchRest::Model::Design do
86
86
 
87
87
  it "should skip if auto update disabled" do
88
88
  @obj.auto_update = false
89
- @obj.should_not_receive(:sync!)
89
+ expect(@obj).not_to receive(:sync!)
90
90
  @obj.sync
91
91
  end
92
92
 
@@ -110,28 +110,28 @@ describe CouchRest::Model::Design do
110
110
  # This would fail if changes were not detected!
111
111
  @doc.sync
112
112
  doc = @db.get(@doc['_id'])
113
- doc['views']['all']['map'].should eql(@doc['views']['all']['map'])
113
+ expect(doc['views']['all']['map']).to eql(@doc['views']['all']['map'])
114
114
  end
115
115
 
116
116
  it "should not save a design that is not in cache and has not changed" do
117
117
  @doc.sync # put doc in cache
118
118
  @doc.send(:set_cache_checksum, @doc.database, nil)
119
119
 
120
- @db.should_not_receive(:save_doc)
121
- @doc.should_receive(:set_cache_checksum)
120
+ expect(@db).not_to receive(:save_doc)
121
+ expect(@doc).to receive(:set_cache_checksum)
122
122
  @doc.sync
123
123
  end
124
124
 
125
125
  it "should not reload a design that is in cache and has not changed" do
126
126
  @doc.sync
127
- @doc.should_not_receive(:load_from_database)
127
+ expect(@doc).not_to receive(:load_from_database)
128
128
  @doc.sync
129
129
  end
130
130
 
131
131
  it "should be re-created if database destroyed" do
132
132
  @doc.sync # saved
133
133
  reset_test_db!
134
- @db.should_receive(:save_doc).with(@doc)
134
+ expect(@db).to receive(:save_doc).with(@doc)
135
135
  @doc.sync
136
136
  end
137
137
 
@@ -142,8 +142,8 @@ describe CouchRest::Model::Design do
142
142
  @db.save_doc(doc)
143
143
  @doc.send(:set_cache_checksum, @doc.database, nil)
144
144
  @doc.sync
145
- @doc['views'].should_not have_key('test')
146
- @doc['_rev'].should be_nil
145
+ expect(@doc['views']).not_to have_key('test')
146
+ expect(@doc['_rev']).to be_nil
147
147
  end
148
148
 
149
149
  it "should save a non existant design" do
@@ -155,8 +155,8 @@ describe CouchRest::Model::Design do
155
155
  @db.delete_doc(doc) if doc
156
156
  @doc.sync!
157
157
  doc = @db.get(@doc['_id'])
158
- doc.should_not be_nil
159
- doc['views']['all'].should eql(@doc['views']['all'])
158
+ expect(doc).not_to be_nil
159
+ expect(doc['views']['all']).to eql(@doc['views']['all'])
160
160
  end
161
161
 
162
162
  end
@@ -172,19 +172,19 @@ describe CouchRest::Model::Design do
172
172
  end
173
173
 
174
174
  it "should return fresh checksum when not calculated earlier" do
175
- @doc.checksum.should_not be_blank
175
+ expect(@doc.checksum).not_to be_blank
176
176
  end
177
177
 
178
178
  it "should provide same checksum without refresh on re-request" do
179
179
  chk = @doc.checksum
180
- @doc.should_not_receive(:checksum!)
181
- @doc.checksum.should eql(chk)
180
+ expect(@doc).not_to receive(:checksum!)
181
+ expect(@doc.checksum).to eql(chk)
182
182
  end
183
183
 
184
184
  it "should provide new checksum if the design has changed" do
185
185
  chk = @doc.checksum
186
186
  @doc['views']['all']['map'] += '// comment'
187
- @doc.checksum.should_not eql(chk)
187
+ expect(@doc.checksum).not_to eql(chk)
188
188
  end
189
189
 
190
190
  end
@@ -193,7 +193,7 @@ describe CouchRest::Model::Design do
193
193
  it "should provide model's database" do
194
194
  @mod = DesignSampleModel
195
195
  @doc = @mod.design_doc
196
- @mod.should_receive(:database)
196
+ expect(@mod).to receive(:database)
197
197
  @doc.database
198
198
  end
199
199
  end
@@ -202,13 +202,13 @@ describe CouchRest::Model::Design do
202
202
  describe "#uri" do
203
203
  it "should provide complete url" do
204
204
  @doc = DesignSampleModel.design_doc
205
- @doc.uri.should eql("#{DesignSampleModel.database.root}/_design/DesignSampleModel")
205
+ expect(@doc.uri).to eql("#{DesignSampleModel.database.root}/_design/DesignSampleModel")
206
206
  end
207
207
  end
208
208
 
209
209
  describe "#view" do
210
210
  it "should instantiate a new view and pass options" do
211
- CouchRest::Model::Designs::View.should_receive(:new).with(@obj, @model, {}, 'by_test')
211
+ expect(CouchRest::Model::Designs::View).to receive(:new).with(@obj, @model, {}, 'by_test')
212
212
  @obj.view('by_test', {})
213
213
  end
214
214
  end
@@ -216,7 +216,7 @@ describe CouchRest::Model::Design do
216
216
  describe "#view_names" do
217
217
  it "should provide a list of all the views available" do
218
218
  @doc = DesignSampleModel.design_doc
219
- @doc.view_names.should eql(['by_name', 'all'])
219
+ expect(@doc.view_names).to eql(['by_name', 'all'])
220
220
  end
221
221
  end
222
222
 
@@ -226,15 +226,15 @@ describe CouchRest::Model::Design do
226
226
  end
227
227
 
228
228
  it "should tell us if a view exists" do
229
- @doc.has_view?('by_name').should be_true
229
+ expect(@doc.has_view?('by_name')).to be_truthy
230
230
  end
231
231
 
232
232
  it "should tell us if a view exists as symbol" do
233
- @doc.has_view?(:by_name).should be_true
233
+ expect(@doc.has_view?(:by_name)).to be_truthy
234
234
  end
235
235
 
236
236
  it "should tell us if a view does not exist" do
237
- @doc.has_view?(:by_foobar).should be_false
237
+ expect(@doc.has_view?(:by_foobar)).to be_falsey
238
238
  end
239
239
  end
240
240
 
@@ -245,12 +245,12 @@ describe CouchRest::Model::Design do
245
245
  end
246
246
 
247
247
  it "should forward view creation to View model" do
248
- CouchRest::Model::Designs::View.should_receive(:define_and_create).with(@doc, 'by_other_name', {})
248
+ expect(CouchRest::Model::Designs::View).to receive(:define_and_create).with(@doc, 'by_other_name', {})
249
249
  @doc.create_view('by_other_name')
250
250
  end
251
251
 
252
252
  it "should forward view creation to View model with opts" do
253
- CouchRest::Model::Designs::View.should_receive(:define_and_create).with(@doc, 'by_other_name', {:by => 'name'})
253
+ expect(CouchRest::Model::Designs::View).to receive(:define_and_create).with(@doc, 'by_other_name', {:by => 'name'})
254
254
  @doc.create_view('by_other_name', :by => 'name')
255
255
  end
256
256
  end
@@ -263,7 +263,7 @@ describe CouchRest::Model::Design do
263
263
 
264
264
  it "should add simple filter" do
265
265
  @doc.create_filter('test', 'foobar')
266
- @doc['filters']['test'].should eql('foobar')
266
+ expect(@doc['filters']['test']).to eql('foobar')
267
267
  @doc['filters'] = nil # cleanup
268
268
  end
269
269
  end
@@ -275,7 +275,7 @@ describe CouchRest::Model::Design do
275
275
 
276
276
  it "should add simple view lib" do
277
277
  @doc.create_view_lib('test', 'foobar')
278
- @doc['views']['lib']['test'].should eql('foobar')
278
+ expect(@doc['views']['lib']['test']).to eql('foobar')
279
279
  @doc['views']['lib'] = nil # cleanup
280
280
  end
281
281
  end
@@ -286,17 +286,17 @@ describe CouchRest::Model::Design do
286
286
 
287
287
  it "should calculate a consistent checksum for model" do
288
288
  #WithTemplateAndUniqueID.design_doc.checksum.should eql('caa2b4c27abb82b4e37421de76d96ffc')
289
- WithTemplateAndUniqueID.design_doc.checksum.should eql('7f44e88afbce06204010c49b76f31bcf')
289
+ expect(WithTemplateAndUniqueID.design_doc.checksum).to eql('7f44e88afbce06204010c49b76f31bcf')
290
290
  end
291
291
 
292
292
  it "should calculate checksum for complex model" do
293
293
  #Article.design_doc.checksum.should eql('70dff8caea143bf40fad09adf0701104')
294
- Article.design_doc.checksum.should eql('81f6553c44ecc3fe12a39331b0cdee46')
294
+ expect(Article.design_doc.checksum).to eql('81f6553c44ecc3fe12a39331b0cdee46')
295
295
  end
296
296
 
297
297
  it "should cache the generated checksum value" do
298
298
  Article.design_doc.checksum
299
- Article.design_doc['couchrest-hash'].should_not be_blank
299
+ expect(Article.design_doc['couchrest-hash']).not_to be_blank
300
300
  Article.first
301
301
  end
302
302
 
@@ -15,22 +15,22 @@ describe CouchRest::Model::Designs::DesignMapper do
15
15
  end
16
16
 
17
17
  it "should set basic variables" do
18
- @object.send(:model).should eql(DesignModel)
19
- @object.send(:prefix).should be_nil
20
- @object.send(:method).should eql('design_doc')
18
+ expect(@object.send(:model)).to eql(DesignModel)
19
+ expect(@object.send(:prefix)).to be_nil
20
+ expect(@object.send(:method)).to eql('design_doc')
21
21
  end
22
22
 
23
23
  it "should add design doc to list" do
24
- @object.model.design_docs.should include(@object.model.design_doc)
24
+ expect(@object.model.design_docs).to include(@object.model.design_doc)
25
25
  end
26
26
 
27
27
  it "should create a design doc method" do
28
- @object.model.should respond_to('design_doc')
29
- @object.design_doc.should eql(@object.model.design_doc)
28
+ expect(@object.model).to respond_to('design_doc')
29
+ expect(@object.design_doc).to eql(@object.model.design_doc)
30
30
  end
31
31
 
32
32
  it "should use default for autoupdate" do
33
- @object.design_doc.auto_update.should be_true
33
+ expect(@object.design_doc.auto_update).to be_truthy
34
34
  end
35
35
 
36
36
  end
@@ -41,22 +41,22 @@ describe CouchRest::Model::Designs::DesignMapper do
41
41
  end
42
42
 
43
43
  it "should set basics" do
44
- @object.send(:model).should eql(DesignModel)
45
- @object.send(:prefix).should eql('stats')
46
- @object.send(:method).should eql('stats_design_doc')
44
+ expect(@object.send(:model)).to eql(DesignModel)
45
+ expect(@object.send(:prefix)).to eql('stats')
46
+ expect(@object.send(:method)).to eql('stats_design_doc')
47
47
  end
48
48
 
49
49
  it "should add design doc to list" do
50
- @object.model.design_docs.should include(@object.model.stats_design_doc)
50
+ expect(@object.model.design_docs).to include(@object.model.stats_design_doc)
51
51
  end
52
52
 
53
53
  it "should not create an all method" do
54
- @object.model.should_not respond_to('all')
54
+ expect(@object.model).not_to respond_to('all')
55
55
  end
56
56
 
57
57
  it "should create a design doc method" do
58
- @object.model.should respond_to('stats_design_doc')
59
- @object.design_doc.should eql(@object.model.stats_design_doc)
58
+ expect(@object.model).to respond_to('stats_design_doc')
59
+ expect(@object.design_doc).to eql(@object.model.stats_design_doc)
60
60
  end
61
61
 
62
62
  end
@@ -65,7 +65,7 @@ describe CouchRest::Model::Designs::DesignMapper do
65
65
  it "should disable auto updates" do
66
66
  @object = @klass.new(DesignModel)
67
67
  @object.disable_auto_update
68
- @object.design_doc.auto_update.should be_false
68
+ expect(@object.design_doc.auto_update).to be_falsey
69
69
  end
70
70
  end
71
71
 
@@ -73,14 +73,14 @@ describe CouchRest::Model::Designs::DesignMapper do
73
73
  it "should enable auto updates" do
74
74
  @object = @klass.new(DesignModel)
75
75
  @object.enable_auto_update
76
- @object.design_doc.auto_update.should be_true
76
+ expect(@object.design_doc.auto_update).to be_truthy
77
77
  end
78
78
  end
79
79
 
80
80
  describe "#model_type_key" do
81
81
  it "should return models type key" do
82
82
  @object = @klass.new(DesignModel)
83
- @object.model_type_key.should eql(@object.model.model_type_key)
83
+ expect(@object.model_type_key).to eql(@object.model.model_type_key)
84
84
  end
85
85
  end
86
86
 
@@ -91,18 +91,18 @@ describe CouchRest::Model::Designs::DesignMapper do
91
91
  end
92
92
 
93
93
  it "should call create method on view" do
94
- CouchRest::Model::Designs::View.should_receive(:define).with(@object.design_doc, 'test', {})
94
+ expect(CouchRest::Model::Designs::View).to receive(:define).with(@object.design_doc, 'test', {})
95
95
  @object.view('test')
96
96
  end
97
97
 
98
98
  it "should create a method on parent model" do
99
- CouchRest::Model::Designs::View.stub(:define)
99
+ allow(CouchRest::Model::Designs::View).to receive(:define)
100
100
  @object.view('test_view')
101
- DesignModel.should respond_to(:test_view)
101
+ expect(DesignModel).to respond_to(:test_view)
102
102
  end
103
103
 
104
104
  it "should create a method for view instance" do
105
- @object.design_doc.should_receive(:create_view).with('test', {})
105
+ expect(@object.design_doc).to receive(:create_view).with('test', {})
106
106
  @object.view('test')
107
107
  end
108
108
  end
@@ -115,8 +115,8 @@ describe CouchRest::Model::Designs::DesignMapper do
115
115
 
116
116
  it "should add the provided function to the design doc" do
117
117
  @object.filter(:important, "function(doc, req) { return doc.priority == 'high'; }")
118
- DesignModel.design_doc['filters'].should_not be_empty
119
- DesignModel.design_doc['filters']['important'].should_not be_blank
118
+ expect(DesignModel.design_doc['filters']).not_to be_empty
119
+ expect(DesignModel.design_doc['filters']['important']).not_to be_blank
120
120
  end
121
121
  end
122
122
 
@@ -128,9 +128,9 @@ describe CouchRest::Model::Designs::DesignMapper do
128
128
  it "should add the #view_lib function to the design doc" do
129
129
  val = "exports.bar = 42;"
130
130
  @object.view_lib(:foo, val)
131
- DesignModel.design_doc['views']['lib'].should_not be_empty
132
- DesignModel.design_doc['views']['lib'].should_not be_blank
133
- DesignModel.design_doc['views']['lib']['foo'].should eql(val)
131
+ expect(DesignModel.design_doc['views']['lib']).not_to be_empty
132
+ expect(DesignModel.design_doc['views']['lib']).not_to be_blank
133
+ expect(DesignModel.design_doc['views']['lib']['foo']).to eql(val)
134
134
  end
135
135
  end
136
136
 
@@ -34,24 +34,24 @@ describe CouchRest::Model::Designs::Migrations do
34
34
  end
35
35
 
36
36
  it "should create new design if non exists" do
37
- @db.should_receive(:view).with("#{@doc.name}/#{@doc['views'].keys.first}", {
37
+ expect(@db).to receive(:view).with("#{@doc.name}/#{@doc['views'].keys.first}", {
38
38
  :limit => 1, :stale => 'update_after', :reduce => false
39
39
  })
40
40
  callback = @doc.migrate do |res|
41
- res.should eql(:created)
41
+ expect(res).to eql(:created)
42
42
  end
43
43
  doc = @db.get(@doc['_id'])
44
- doc['views']['all'].should eql(@doc['views']['all'])
45
- callback.should be_nil
44
+ expect(doc['views']['all']).to eql(@doc['views']['all'])
45
+ expect(callback).to be_nil
46
46
  end
47
47
 
48
48
  it "should not change anything if design is up to date" do
49
49
  @doc.sync
50
- @db.should_not_receive(:view)
50
+ expect(@db).not_to receive(:view)
51
51
  callback = @doc.migrate do |res|
52
- res.should eql(:no_change)
52
+ expect(res).to eql(:no_change)
53
53
  end
54
- callback.should be_nil
54
+ expect(callback).to be_nil
55
55
  end
56
56
 
57
57
  end
@@ -72,28 +72,28 @@ describe CouchRest::Model::Designs::Migrations do
72
72
  end
73
73
 
74
74
  it "should save new migration design doc" do
75
- @db.should_receive(:view).with("#{@doc.name}_migration/by_name", {
75
+ expect(@db).to receive(:view).with("#{@doc.name}_migration/by_name", {
76
76
  :limit => 1, :reduce => false, :stale => 'update_after'
77
77
  })
78
78
  @callback = @doc.migrate do |res|
79
- res.should eql(:migrated)
79
+ expect(res).to eql(:migrated)
80
80
  end
81
- @callback.should_not be_nil
81
+ expect(@callback).not_to be_nil
82
82
 
83
83
  # should not have updated original view until cleanup
84
84
  doc = @db.get(@doc['_id'])
85
- doc['views'].should_not have_key('by_name_and_surname')
85
+ expect(doc['views']).not_to have_key('by_name_and_surname')
86
86
 
87
87
  # Should have created the migration
88
88
  new_doc = @db.get(@doc_id)
89
- new_doc.should_not be_nil
89
+ expect(new_doc).not_to be_nil
90
90
 
91
91
  # should be possible to perform cleanup
92
92
  @callback.call
93
93
  expect(@db.get(@doc_id)).to be_nil
94
94
 
95
95
  doc = @db.get(@doc['_id'])
96
- doc['views'].should have_key('by_name_and_surname')
96
+ expect(doc['views']).to have_key('by_name_and_surname')
97
97
  end
98
98
 
99
99
  end
@@ -24,7 +24,7 @@ describe "Design View" do
24
24
 
25
25
  describe "with invalid parent model" do
26
26
  it "should burn" do
27
- lambda { @klass.new(String) }.should raise_exception
27
+ expect { @klass.new(String, nil) }.to raise_error(/View cannot be initialized without a parent Model/)
28
28
  end
29
29
  end
30
30
 
@@ -32,14 +32,14 @@ describe "Design View" do
32
32
 
33
33
  it "should setup attributes" do
34
34
  @obj = @klass.new(@mod.design_doc, @mod, {}, 'test_view')
35
- @obj.design_doc.should eql(@mod.design_doc)
36
- @obj.model.should eql(@mod)
37
- @obj.name.should eql('test_view')
38
- @obj.query.should be_empty
35
+ expect(@obj.design_doc).to eql(@mod.design_doc)
36
+ expect(@obj.model).to eql(@mod)
37
+ expect(@obj.name).to eql('test_view')
38
+ expect(@obj.query).to be_empty
39
39
  end
40
40
 
41
41
  it "should complain if there is no name" do
42
- lambda { @klass.new(@mod.design_doc, @mod, {}, nil) }.should raise_error(/Name must be provided/)
42
+ expect { @klass.new(@mod.design_doc, @mod, {}, nil) }.to raise_error(/Name must be provided/)
43
43
  end
44
44
 
45
45
  end
@@ -52,14 +52,14 @@ describe "Design View" do
52
52
  end
53
53
 
54
54
  it "should copy attributes" do
55
- @obj.model.should eql(@mod)
56
- @obj.name.should eql('test_view')
57
- @obj.query.should eql({:foo => :bar})
55
+ expect(@obj.model).to eql(@mod)
56
+ expect(@obj.name).to eql('test_view')
57
+ expect(@obj.query).to eql({:foo => :bar})
58
58
  end
59
59
 
60
60
  it "should delete query keys if :delete defined" do
61
61
  @obj2 = @klass.new(@mod.design_doc, @obj, {:delete => [:foo]})
62
- @obj2.query.should_not include(:foo)
62
+ expect(@obj2.query).not_to include(:foo)
63
63
  end
64
64
 
65
65
  end
@@ -68,7 +68,7 @@ describe "Design View" do
68
68
  it "should set model to proxy object and remove from query" do
69
69
  proxy = double("Proxy")
70
70
  @obj = @klass.new(@mod.design_doc, @mod, {:proxy => proxy}, 'test_view')
71
- @obj.model.should eql(proxy)
71
+ expect(@obj.model).to eql(proxy)
72
72
  end
73
73
  end
74
74
 
@@ -76,9 +76,9 @@ describe "Design View" do
76
76
  it "should set the model to proxy object instead of parents model" do
77
77
  proxy = double("Proxy")
78
78
  @obj = @klass.new(@mod.design_doc, @mod, {}, 'test_view')
79
- @obj.model.should eql(@mod)
79
+ expect(@obj.model).to eql(@mod)
80
80
  @obj = @obj.proxy(proxy)
81
- @obj.model.should eql(proxy)
81
+ expect(@obj.model).to eql(proxy)
82
82
  end
83
83
  end
84
84
 
@@ -90,14 +90,14 @@ describe "Design View" do
90
90
  end
91
91
 
92
92
  it "should call define and create_model_methods method" do
93
- @klass.should_receive(:define).with(@design_doc, 'test', {}).and_return(nil)
94
- @klass.should_receive(:create_model_methods).with(@design_doc, 'test', {}).and_return(nil)
93
+ expect(@klass).to receive(:define).with(@design_doc, 'test', {}).and_return(nil)
94
+ expect(@klass).to receive(:create_model_methods).with(@design_doc, 'test', {}).and_return(nil)
95
95
  @klass.define_and_create(@design_doc, 'test')
96
96
  end
97
97
 
98
98
  it "should call define and create_model_methods method with opts" do
99
- @klass.should_receive(:define).with(@design_doc, 'test', {:foo => :bar}).and_return(nil)
100
- @klass.should_receive(:create_model_methods).with(@design_doc, 'test', {:foo => :bar}).and_return(nil)
99
+ expect(@klass).to receive(:define).with(@design_doc, 'test', {:foo => :bar}).and_return(nil)
100
+ expect(@klass).to receive(:create_model_methods).with(@design_doc, 'test', {:foo => :bar}).and_return(nil)
101
101
  @klass.define_and_create(@design_doc, 'test', {:foo => :bar})
102
102
  end
103
103
 
@@ -109,53 +109,71 @@ describe "Design View" do
109
109
 
110
110
  before :each do
111
111
  @design_doc = { }
112
- @design_doc.stub(:model).and_return(DesignViewModel)
112
+ allow(@design_doc).to receive(:model).and_return(DesignViewModel)
113
113
  end
114
114
 
115
115
  it "should add a basic view" do
116
116
  @klass.define(@design_doc, 'test_view', :map => 'foo')
117
- @design_doc['views']['test_view'].should_not be_nil
117
+ expect(@design_doc['views']['test_view']).not_to be_nil
118
118
  end
119
119
 
120
120
  it "should not overwrite reduce if set" do
121
121
  @klass.define(@design_doc, 'by_title', :reduce => true)
122
- @design_doc['views']['by_title']['map'].should_not be_blank
123
- @design_doc['views']['by_title']['reduce'].should eql(true)
122
+ expect(@design_doc['views']['by_title']['map']).not_to be_blank
123
+ expect(@design_doc['views']['by_title']['reduce']).to eql(true)
124
124
  end
125
125
 
126
126
  it "should replace reduce symbol with string name" do
127
127
  @klass.define(@design_doc, 'by_title', :reduce => :sum)
128
- @design_doc['views']['by_title']['map'].should_not be_blank
129
- @design_doc['views']['by_title']['reduce'].should eql('_sum')
128
+ expect(@design_doc['views']['by_title']['map']).not_to be_blank
129
+ expect(@design_doc['views']['by_title']['reduce']).to eql('_sum')
130
130
  end
131
131
 
132
132
  it "should replace reduce symbol with string if map function present" do
133
133
  @klass.define(@design_doc, 'by_title', :map => "function(d) { }", :reduce => :sum)
134
- @design_doc['views']['by_title']['map'].should_not be_blank
135
- @design_doc['views']['by_title']['reduce'].should eql('_sum')
134
+ expect(@design_doc['views']['by_title']['map']).not_to be_blank
135
+ expect(@design_doc['views']['by_title']['reduce']).to eql('_sum')
136
136
  end
137
137
 
138
138
  it "should auto generate mapping from name" do
139
- lambda { @klass.define(@design_doc, 'by_title') }.should_not raise_error
139
+ expect { @klass.define(@design_doc, 'by_title') }.not_to raise_error
140
140
  str = @design_doc['views']['by_title']['map']
141
- str.should include("((doc['#{DesignViewModel.model_type_key}'] == 'DesignViewModel') && (doc['title'] != null))")
142
- str.should include("emit(doc['title'], 1);")
141
+ expect(str).to include("((doc['#{DesignViewModel.model_type_key}'] == 'DesignViewModel') && (doc['title'] != null))")
142
+ expect(str).to include("emit(doc['title'], 1);")
143
143
  str = @design_doc['views']['by_title']['reduce']
144
- str.should include("_sum")
144
+ expect(str).to include("_sum")
145
145
  end
146
146
 
147
147
  it "should auto generate mapping from name with and" do
148
148
  @klass.define(@design_doc, 'by_title_and_name')
149
149
  str = @design_doc['views']['by_title_and_name']['map']
150
- str.should include("(doc['title'] != null) && (doc['name'] != null)")
151
- str.should include("emit([doc['title'], doc['name']], 1);")
150
+ expect(str).to include("(doc['title'] != null) && (doc['name'] != null)")
151
+ expect(str).to include("emit([doc['title'], doc['name']], 1);")
152
152
  str = @design_doc['views']['by_title_and_name']['reduce']
153
- str.should include("_sum")
153
+ expect(str).to include("_sum")
154
154
  end
155
155
 
156
156
  it "should allow reduce methods as symbols" do
157
157
  @klass.define(@design_doc, 'by_title', :reduce => :stats)
158
- @design_doc['views']['by_title']['reduce'].should eql('_stats')
158
+ expect(@design_doc['views']['by_title']['reduce']).to eql('_stats')
159
+ end
160
+
161
+ it "should allow the emit value to be overridden" do
162
+ @klass.define(@design_doc, 'by_title', :emit => :name)
163
+ str = @design_doc['views']['by_title']['map']
164
+ expect(str).to include("emit(doc['title'], doc['name']);")
165
+ end
166
+
167
+ it "should forward a non-symbol emit value straight into the view" do
168
+ @klass.define(@design_doc, 'by_title', :emit => 3)
169
+ str = @design_doc['views']['by_title']['map']
170
+ expect(str).to include("emit(doc['title'], 3);")
171
+ end
172
+
173
+ it "should support emitting an array" do
174
+ @klass.define(@design_doc, 'by_title', :emit => [1, :name])
175
+ str = @design_doc['views']['by_title']['map']
176
+ expect(str).to include("emit(doc['title'], [1, doc['name']]);")
159
177
  end
160
178
  end
161
179
 
@@ -163,42 +181,42 @@ describe "Design View" do
163
181
  before :each do
164
182
  @model = DesignViewModel
165
183
  @design_doc = { }
166
- @design_doc.stub(:model).and_return(@model)
167
- @design_doc.stub(:method_name).and_return("design_doc")
168
- @model.stub('design_doc').and_return(@design_doc)
184
+ allow(@design_doc).to receive(:model).and_return(@model)
185
+ allow(@design_doc).to receive(:method_name).and_return("design_doc")
186
+ allow(@model).to receive('design_doc').and_return(@design_doc)
169
187
  end
170
188
  it "should create standard view method" do
171
189
  @klass.create_model_methods(@design_doc, 'by_name')
172
- @model.should respond_to('by_name')
173
- @design_doc.should_receive('view').with('by_name', {})
190
+ expect(@model).to respond_to('by_name')
191
+ expect(@design_doc).to receive('view').with('by_name', {})
174
192
  @model.by_name
175
193
  end
176
194
  it "should create find_ view method" do
177
195
  @klass.create_model_methods(@design_doc, 'by_name')
178
- @model.should respond_to('find_by_name')
196
+ expect(@model).to respond_to('find_by_name')
179
197
  view = double("View")
180
- view.should_receive('key').with('fred').and_return(view)
181
- view.should_receive('first').and_return(nil)
182
- @design_doc.should_receive('view').and_return(view)
198
+ expect(view).to receive('key').with('fred').and_return(view)
199
+ expect(view).to receive('first').and_return(nil)
200
+ expect(@design_doc).to receive('view').and_return(view)
183
201
  @model.find_by_name('fred')
184
202
  end
185
203
  it "should create find_! view method" do
186
204
  @klass.create_model_methods(@design_doc, 'by_name')
187
- @model.should respond_to('find_by_name!')
205
+ expect(@model).to respond_to('find_by_name!')
188
206
  obj = double("SomeKlass")
189
207
  view = double("View")
190
- view.should_receive('key').with('fred').and_return(view)
191
- view.should_receive('first').and_return(obj)
192
- @design_doc.should_receive('view').and_return(view)
193
- @model.find_by_name!('fred').should eql(obj)
208
+ expect(view).to receive('key').with('fred').and_return(view)
209
+ expect(view).to receive('first').and_return(obj)
210
+ expect(@design_doc).to receive('view').and_return(view)
211
+ expect(@model.find_by_name!('fred')).to eql(obj)
194
212
  end
195
213
  it "should create find_! view method and raise error when nil" do
196
214
  @klass.create_model_methods(@design_doc, 'by_name')
197
215
  view = double("View")
198
- view.should_receive('key').with('fred').and_return(view)
199
- view.should_receive('first').and_return(nil)
200
- @design_doc.should_receive('view').and_return(view)
201
- lambda { @model.find_by_name!('fred') }.should raise_error(CouchRest::Model::DocumentNotFound)
216
+ expect(view).to receive('key').with('fred').and_return(view)
217
+ expect(view).to receive('first').and_return(nil)
218
+ expect(@design_doc).to receive('view').and_return(view)
219
+ expect { @model.find_by_name!('fred') }.to raise_error(CouchRest::Model::DocumentNotFound)
202
220
  end
203
221
 
204
222
  end
@@ -213,15 +231,15 @@ describe "Design View" do
213
231
 
214
232
  describe "#rows" do
215
233
  it "should execute query" do
216
- @obj.should_receive(:execute).and_return(true)
217
- @obj.should_receive(:result).twice.and_return({'rows' => []})
218
- @obj.rows.should be_empty
234
+ expect(@obj).to receive(:execute).and_return(true)
235
+ expect(@obj).to receive(:result).twice.and_return({'rows' => []})
236
+ expect(@obj.rows).to be_empty
219
237
  end
220
238
 
221
239
  it "should wrap rows in ViewRow class" do
222
- @obj.should_receive(:execute).and_return(true)
223
- @obj.should_receive(:result).twice.and_return({'rows' => [{:foo => :bar}]})
224
- CouchRest::Model::Designs::ViewRow.should_receive(:new).with({:foo => :bar}, @obj.model, DB)
240
+ expect(@obj).to receive(:execute).and_return(true)
241
+ expect(@obj).to receive(:result).twice.and_return({'rows' => [{:foo => :bar}]})
242
+ expect(CouchRest::Model::Designs::ViewRow).to receive(:new).with({:foo => :bar}, @obj.model, DB)
225
243
  @obj.rows
226
244
  end
227
245
 
@@ -250,24 +268,24 @@ describe "Design View" do
250
268
 
251
269
  describe "#all" do
252
270
  it "should ensure docs included and call docs" do
253
- @obj.should_receive(:include_docs!)
254
- @obj.should_receive(:docs)
271
+ expect(@obj).to receive(:include_docs!)
272
+ expect(@obj).to receive(:docs)
255
273
  @obj.all
256
274
  end
257
275
  it "should pass on a block" do
258
- block = lambda { }
259
- expect(@obj).to receive(:docs).with(&block)
260
- @obj.all(&block)
276
+ block = lambda { 'ok' }
277
+ expect(@obj).to receive(:docs) { block.call() }
278
+ expect(@obj.all(&block)).to eql('ok')
261
279
  end
262
280
  end
263
281
 
264
282
  describe "#docs" do
265
283
  it "should provide docs from rows" do
266
- @obj.should_receive(:rows).and_return([])
284
+ expect(@obj).to receive(:rows).and_return([])
267
285
  @obj.docs
268
286
  end
269
287
  it "should cache the results" do
270
- @obj.should_receive(:rows).once.and_return([])
288
+ expect(@obj).to receive(:rows).once.and_return([])
271
289
  @obj.docs
272
290
  @obj.docs
273
291
  end
@@ -296,369 +314,369 @@ describe "Design View" do
296
314
 
297
315
  describe "#first" do
298
316
  it "should provide the first result of loaded query" do
299
- @obj.should_receive(:result).and_return(true)
300
- @obj.should_receive(:all).and_return([:foo])
301
- @obj.first.should eql(:foo)
317
+ expect(@obj).to receive(:result).and_return(true)
318
+ expect(@obj).to receive(:all).and_return([:foo])
319
+ expect(@obj.first).to eql(:foo)
302
320
  end
303
321
  it "should perform a query if no results cached" do
304
322
  view = double('SubView')
305
- @obj.should_receive(:result).and_return(nil)
306
- @obj.should_receive(:limit).with(1).and_return(view)
307
- view.should_receive(:all).and_return([:foo])
308
- @obj.first.should eql(:foo)
323
+ expect(@obj).to receive(:result).and_return(nil)
324
+ expect(@obj).to receive(:limit).with(1).and_return(view)
325
+ expect(view).to receive(:all).and_return([:foo])
326
+ expect(@obj.first).to eql(:foo)
309
327
  end
310
328
  end
311
329
 
312
330
  describe "#last" do
313
331
  it "should provide the last result of loaded query" do
314
- @obj.should_receive(:result).and_return(true)
315
- @obj.should_receive(:all).and_return([:foo, :bar])
316
- @obj.first.should eql(:foo)
332
+ expect(@obj).to receive(:result).and_return(true)
333
+ expect(@obj).to receive(:all).and_return([:foo, :bar])
334
+ expect(@obj.first).to eql(:foo)
317
335
  end
318
336
  it "should perform a query if no results cached" do
319
337
  view = double('SubView')
320
- @obj.should_receive(:result).and_return(nil)
321
- @obj.should_receive(:limit).with(1).and_return(view)
322
- view.should_receive(:descending).and_return(view)
323
- view.should_receive(:all).and_return([:foo, :bar])
324
- @obj.last.should eql(:bar)
338
+ expect(@obj).to receive(:result).and_return(nil)
339
+ expect(@obj).to receive(:limit).with(1).and_return(view)
340
+ expect(view).to receive(:descending).and_return(view)
341
+ expect(view).to receive(:all).and_return([:foo, :bar])
342
+ expect(@obj.last).to eql(:bar)
325
343
  end
326
344
  end
327
345
 
328
346
  describe "#length" do
329
347
  it "should provide a length from the docs array" do
330
- @obj.should_receive(:docs).and_return([1, 2, 3])
331
- @obj.length.should eql(3)
348
+ expect(@obj).to receive(:docs).and_return([1, 2, 3])
349
+ expect(@obj.length).to eql(3)
332
350
  end
333
351
  end
334
352
 
335
353
  describe "#count" do
336
354
  it "should raise an error if view prepared for group" do
337
- @obj.should_receive(:query).and_return({:group => true})
338
- lambda { @obj.count }.should raise_error(/group/)
355
+ expect(@obj).to receive(:query).and_return({:group => true})
356
+ expect { @obj.count }.to raise_error(/group/)
339
357
  end
340
358
 
341
359
  it "should return first row value if reduce possible" do
342
360
  view = double("SubView")
343
361
  row = double("Row")
344
- @obj.should_receive(:can_reduce?).and_return(true)
345
- @obj.should_receive(:reduce).and_return(view)
346
- view.should_receive(:skip).with(0).and_return(view)
347
- view.should_receive(:limit).with(1).and_return(view)
348
- view.should_receive(:rows).and_return([row])
349
- row.should_receive(:value).and_return(2)
350
- @obj.count.should eql(2)
362
+ expect(@obj).to receive(:can_reduce?).and_return(true)
363
+ expect(@obj).to receive(:reduce).and_return(view)
364
+ expect(view).to receive(:skip).with(0).and_return(view)
365
+ expect(view).to receive(:limit).with(1).and_return(view)
366
+ expect(view).to receive(:rows).and_return([row])
367
+ expect(row).to receive(:value).and_return(2)
368
+ expect(@obj.count).to eql(2)
351
369
  end
352
370
  it "should return 0 if no rows and reduce possible" do
353
371
  view = double("SubView")
354
- @obj.should_receive(:can_reduce?).and_return(true)
355
- @obj.should_receive(:reduce).and_return(view)
356
- view.should_receive(:skip).with(0).and_return(view)
357
- view.should_receive(:limit).with(1).and_return(view)
358
- view.should_receive(:rows).and_return([])
359
- @obj.count.should eql(0)
372
+ expect(@obj).to receive(:can_reduce?).and_return(true)
373
+ expect(@obj).to receive(:reduce).and_return(view)
374
+ expect(view).to receive(:skip).with(0).and_return(view)
375
+ expect(view).to receive(:limit).with(1).and_return(view)
376
+ expect(view).to receive(:rows).and_return([])
377
+ expect(@obj.count).to eql(0)
360
378
  end
361
379
 
362
380
  it "should perform limit request for total_rows" do
363
381
  view = double("SubView")
364
- @obj.should_receive(:limit).with(0).and_return(view)
365
- view.should_receive(:total_rows).and_return(4)
366
- @obj.should_receive(:can_reduce?).and_return(false)
367
- @obj.count.should eql(4)
382
+ expect(@obj).to receive(:limit).with(0).and_return(view)
383
+ expect(view).to receive(:total_rows).and_return(4)
384
+ expect(@obj).to receive(:can_reduce?).and_return(false)
385
+ expect(@obj.count).to eql(4)
368
386
  end
369
387
  end
370
388
 
371
389
  describe "#empty?" do
372
390
  it "should check the #all method for any results" do
373
391
  all = double("All")
374
- all.should_receive(:empty?).and_return('win')
375
- @obj.should_receive(:all).and_return(all)
376
- @obj.empty?.should eql('win')
392
+ expect(all).to receive(:empty?).and_return('win')
393
+ expect(@obj).to receive(:all).and_return(all)
394
+ expect(@obj.empty?).to eql('win')
377
395
  end
378
396
  end
379
397
 
380
398
  describe "#each" do
381
399
  it "should call each method on all" do
382
- @obj.should_receive(:all).and_return([])
400
+ expect(@obj).to receive(:all).and_return([])
383
401
  @obj.each
384
402
  end
385
403
  it "should call each and pass block" do
386
404
  set = [:foo, :bar]
387
- @obj.should_receive(:all).and_return(set)
405
+ expect(@obj).to receive(:all).and_return(set)
388
406
  result = []
389
407
  @obj.each do |s|
390
408
  result << s
391
409
  end
392
- result.should eql(set)
410
+ expect(result).to eql(set)
393
411
  end
394
412
  end
395
413
 
396
414
  describe "#offset" do
397
415
  it "should excute" do
398
- @obj.should_receive(:execute).and_return({'offset' => 3})
399
- @obj.offset.should eql(3)
416
+ expect(@obj).to receive(:execute).and_return({'offset' => 3})
417
+ expect(@obj.offset).to eql(3)
400
418
  end
401
419
  end
402
420
 
403
421
  describe "#total_rows" do
404
422
  it "should excute" do
405
- @obj.should_receive(:execute).and_return({'total_rows' => 3})
406
- @obj.total_rows.should eql(3)
423
+ expect(@obj).to receive(:execute).and_return({'total_rows' => 3})
424
+ expect(@obj.total_rows).to eql(3)
407
425
  end
408
426
  end
409
427
 
410
428
  describe "#values" do
411
429
  it "should request each row and provide value" do
412
430
  row = double("Row")
413
- row.should_receive(:value).twice.and_return('foo')
414
- @obj.should_receive(:rows).and_return([row, row])
415
- @obj.values.should eql(['foo', 'foo'])
431
+ expect(row).to receive(:value).twice.and_return('foo')
432
+ expect(@obj).to receive(:rows).and_return([row, row])
433
+ expect(@obj.values).to eql(['foo', 'foo'])
416
434
  end
417
435
  end
418
436
 
419
437
  describe "#[]" do
420
438
  it "should execute and provide requested field" do
421
- @obj.should_receive(:execute).and_return({'total_rows' => 2})
422
- @obj['total_rows'].should eql(2)
439
+ expect(@obj).to receive(:execute).and_return({'total_rows' => 2})
440
+ expect(@obj['total_rows']).to eql(2)
423
441
  end
424
442
  end
425
443
 
426
444
  describe "#info" do
427
445
  it "should raise error" do
428
- lambda { @obj.info }.should raise_error
446
+ expect { @obj.info }.to raise_error(/Not yet implemented/)
429
447
  end
430
448
  end
431
449
 
432
450
  describe "#database" do
433
451
  it "should update query with value" do
434
- @obj.should_receive(:update_query).with({:database => 'foo'})
452
+ expect(@obj).to receive(:update_query).with({:database => 'foo'})
435
453
  @obj.database('foo')
436
454
  end
437
455
  end
438
456
 
439
457
  describe "#key" do
440
458
  it "should update query with value" do
441
- @obj.should_receive(:update_query).with({:key => 'foo'})
459
+ expect(@obj).to receive(:update_query).with({:key => 'foo'})
442
460
  @obj.key('foo')
443
461
  end
444
462
  it "should raise error if startkey set" do
445
463
  @obj.query[:startkey] = 'bar'
446
- lambda { @obj.key('foo') }.should raise_error
464
+ expect { @obj.key('foo') }.to raise_error(/View#key cannot be used/)
447
465
  end
448
466
  it "should raise error if endkey set" do
449
467
  @obj.query[:endkey] = 'bar'
450
- lambda { @obj.key('foo') }.should raise_error
468
+ expect { @obj.key('foo') }.to raise_error(/View#key cannot be used/)
451
469
  end
452
470
  it "should raise error if both startkey and endkey set" do
453
471
  @obj.query[:startkey] = 'bar'
454
472
  @obj.query[:endkey] = 'bar'
455
- lambda { @obj.key('foo') }.should raise_error
473
+ expect { @obj.key('foo') }.to raise_error(/View#key cannot be used/)
456
474
  end
457
475
  it "should raise error if keys set" do
458
476
  @obj.query[:keys] = 'bar'
459
- lambda { @obj.key('foo') }.should raise_error
477
+ expect { @obj.key('foo') }.to raise_error(/View#key cannot be used/)
460
478
  end
461
479
  end
462
480
 
463
481
  describe "#startkey" do
464
482
  it "should update query with value" do
465
- @obj.should_receive(:update_query).with({:startkey => 'foo'})
483
+ expect(@obj).to receive(:update_query).with({:startkey => 'foo'})
466
484
  @obj.startkey('foo')
467
485
  end
468
486
  it "should raise and error if key set" do
469
487
  @obj.query[:key] = 'bar'
470
- lambda { @obj.startkey('foo') }.should raise_error(/View#startkey/)
488
+ expect { @obj.startkey('foo') }.to raise_error(/View#startkey/)
471
489
  end
472
490
  it "should raise and error if keys set" do
473
491
  @obj.query[:keys] = 'bar'
474
- lambda { @obj.startkey('foo') }.should raise_error(/View#startkey/)
492
+ expect { @obj.startkey('foo') }.to raise_error(/View#startkey/)
475
493
  end
476
494
  end
477
495
 
478
496
  describe "#startkey_doc" do
479
497
  it "should update query with value" do
480
- @obj.should_receive(:update_query).with({:startkey_docid => 'foo'})
498
+ expect(@obj).to receive(:update_query).with({:startkey_docid => 'foo'})
481
499
  @obj.startkey_doc('foo')
482
500
  end
483
501
  it "should update query with object id if available" do
484
502
  doc = double("Document")
485
- doc.should_receive(:id).and_return(44)
486
- @obj.should_receive(:update_query).with({:startkey_docid => 44})
503
+ expect(doc).to receive(:id).and_return(44)
504
+ expect(@obj).to receive(:update_query).with({:startkey_docid => 44})
487
505
  @obj.startkey_doc(doc)
488
506
  end
489
507
  end
490
508
 
491
509
  describe "#endkey" do
492
510
  it "should update query with value" do
493
- @obj.should_receive(:update_query).with({:endkey => 'foo'})
511
+ expect(@obj).to receive(:update_query).with({:endkey => 'foo'})
494
512
  @obj.endkey('foo')
495
513
  end
496
514
  it "should raise and error if key set" do
497
515
  @obj.query[:key] = 'bar'
498
- lambda { @obj.endkey('foo') }.should raise_error(/View#endkey/)
516
+ expect { @obj.endkey('foo') }.to raise_error(/View#endkey/)
499
517
  end
500
518
  it "should raise and error if keys set" do
501
519
  @obj.query[:keys] = 'bar'
502
- lambda { @obj.endkey('foo') }.should raise_error(/View#endkey/)
520
+ expect { @obj.endkey('foo') }.to raise_error(/View#endkey/)
503
521
  end
504
522
  end
505
523
 
506
524
  describe "#endkey_doc" do
507
525
  it "should update query with value" do
508
- @obj.should_receive(:update_query).with({:endkey_docid => 'foo'})
526
+ expect(@obj).to receive(:update_query).with({:endkey_docid => 'foo'})
509
527
  @obj.endkey_doc('foo')
510
528
  end
511
529
  it "should update query with object id if available" do
512
530
  doc = double("Document")
513
- doc.should_receive(:id).and_return(44)
514
- @obj.should_receive(:update_query).with({:endkey_docid => 44})
531
+ expect(doc).to receive(:id).and_return(44)
532
+ expect(@obj).to receive(:update_query).with({:endkey_docid => 44})
515
533
  @obj.endkey_doc(doc)
516
534
  end
517
535
  end
518
536
 
519
537
  describe "#keys" do
520
538
  it "should update the query" do
521
- @obj.should_receive(:update_query).with({:keys => ['foo', 'bar']})
539
+ expect(@obj).to receive(:update_query).with({:keys => ['foo', 'bar']})
522
540
  @obj.keys(['foo', 'bar'])
523
541
  end
524
542
  it "should raise and error if key set" do
525
543
  @obj.query[:key] = 'bar'
526
- lambda { @obj.keys('foo') }.should raise_error(/View#keys/)
544
+ expect { @obj.keys('foo') }.to raise_error(/View#keys/)
527
545
  end
528
546
  it "should raise and error if startkey or endkey set" do
529
547
  @obj.query[:startkey] = 'bar'
530
- lambda { @obj.keys('foo') }.should raise_error(/View#keys/)
548
+ expect { @obj.keys('foo') }.to raise_error(/View#keys/)
531
549
  @obj.query.delete(:startkey)
532
550
  @obj.query[:endkey] = 'bar'
533
- lambda { @obj.keys('foo') }.should raise_error(/View#keys/)
551
+ expect { @obj.keys('foo') }.to raise_error(/View#keys/)
534
552
  end
535
553
  end
536
554
 
537
555
  describe "#keys (without parameters)" do
538
556
  it "should request each row and provide key value" do
539
557
  row = double("Row")
540
- row.should_receive(:key).twice.and_return('foo')
541
- @obj.should_receive(:rows).and_return([row, row])
542
- @obj.keys.should eql(['foo', 'foo'])
558
+ expect(row).to receive(:key).twice.and_return('foo')
559
+ expect(@obj).to receive(:rows).and_return([row, row])
560
+ expect(@obj.keys).to eql(['foo', 'foo'])
543
561
  end
544
562
  end
545
563
 
546
564
  describe "#descending" do
547
565
  it "should update query" do
548
- @obj.should_receive(:update_query).with({:descending => true})
566
+ expect(@obj).to receive(:update_query).with({:descending => true})
549
567
  @obj.descending
550
568
  end
551
569
  it "should reverse start and end keys if given" do
552
570
  @obj = @obj.startkey('a').endkey('z')
553
571
  @obj = @obj.descending
554
- @obj.query[:endkey].should eql('a')
555
- @obj.query[:startkey].should eql('z')
572
+ expect(@obj.query[:endkey]).to eql('a')
573
+ expect(@obj.query[:startkey]).to eql('z')
556
574
  end
557
575
  it "should reverse even if start or end nil" do
558
576
  @obj = @obj.startkey('a')
559
577
  @obj = @obj.descending
560
- @obj.query[:endkey].should eql('a')
561
- @obj.query[:startkey].should be_nil
578
+ expect(@obj.query[:endkey]).to eql('a')
579
+ expect(@obj.query[:startkey]).to be_nil
562
580
  end
563
581
  it "should reverse start_doc and end_doc keys if given" do
564
582
  @obj = @obj.startkey_doc('a').endkey_doc('z')
565
583
  @obj = @obj.descending
566
- @obj.query[:endkey_docid].should eql('a')
567
- @obj.query[:startkey_docid].should eql('z')
584
+ expect(@obj.query[:endkey_docid]).to eql('a')
585
+ expect(@obj.query[:startkey_docid]).to eql('z')
568
586
  end
569
587
  end
570
588
 
571
589
  describe "#limit" do
572
590
  it "should update query with value" do
573
- @obj.should_receive(:update_query).with({:limit => 3})
591
+ expect(@obj).to receive(:update_query).with({:limit => 3})
574
592
  @obj.limit(3)
575
593
  end
576
594
  end
577
595
 
578
596
  describe "#skip" do
579
- it "should update query with value" do
580
- @obj.should_receive(:update_query).with({:skip => 3})
597
+ it "should update query with value" do
598
+ expect(@obj).to receive(:update_query).with({:skip => 3})
581
599
  @obj.skip(3)
582
600
  end
583
- it "should update query with default value" do
584
- @obj.should_receive(:update_query).with({:skip => 0})
601
+ it "should update query with default value" do
602
+ expect(@obj).to receive(:update_query).with({:skip => 0})
585
603
  @obj.skip
586
604
  end
587
605
  end
588
606
 
589
607
  describe "#reduce" do
590
608
  it "should update query" do
591
- @obj.should_receive(:can_reduce?).and_return(true)
592
- @obj.should_receive(:update_query).with({:reduce => true, :delete => [:include_docs]})
609
+ expect(@obj).to receive(:can_reduce?).and_return(true)
610
+ expect(@obj).to receive(:update_query).with({:reduce => true, :delete => [:include_docs]})
593
611
  @obj.reduce
594
612
  end
595
613
  it "should raise error if query cannot be reduced" do
596
- @obj.should_receive(:can_reduce?).and_return(false)
597
- lambda { @obj.reduce }.should raise_error
614
+ expect(@obj).to receive(:can_reduce?).and_return(false)
615
+ expect { @obj.reduce }.to raise_error(/Cannot reduce a view without a reduce method/)
598
616
  end
599
617
  end
600
618
 
601
619
  describe "#group" do
602
620
  it "should update query" do
603
- @obj.should_receive(:query).and_return({:reduce => true})
604
- @obj.should_receive(:update_query).with({:group => true})
621
+ expect(@obj).to receive(:query).and_return({:reduce => true})
622
+ expect(@obj).to receive(:update_query).with({:group => true})
605
623
  @obj.group
606
624
  end
607
625
  it "should raise error if query not prepared for reduce" do
608
- @obj.should_receive(:query).and_return({:reduce => false})
609
- lambda { @obj.group }.should raise_error
626
+ expect(@obj).to receive(:query).and_return({:reduce => false})
627
+ expect { @obj.group }.to raise_error(/View#reduce must have been set before grouping is permitted/)
610
628
  end
611
629
  end
612
630
 
613
631
  describe "#group" do
614
632
  it "should update query" do
615
- @obj.should_receive(:query).and_return({:reduce => true})
616
- @obj.should_receive(:update_query).with({:group => true})
633
+ expect(@obj).to receive(:query).and_return({:reduce => true})
634
+ expect(@obj).to receive(:update_query).with({:group => true})
617
635
  @obj.group
618
636
  end
619
637
  it "should raise error if query not prepared for reduce" do
620
- @obj.should_receive(:query).and_return({:reduce => false})
621
- lambda { @obj.group }.should raise_error
638
+ expect(@obj).to receive(:query).and_return({:reduce => false})
639
+ expect { @obj.group }.to raise_error(/View#reduce must have been set before grouping is permitted/)
622
640
  end
623
641
  end
624
642
 
625
643
  describe "#group_level" do
626
644
  it "should update query" do
627
- @obj.should_receive(:group).and_return(@obj)
628
- @obj.should_receive(:update_query).with({:group_level => 3})
645
+ expect(@obj).to receive(:group).and_return(@obj)
646
+ expect(@obj).to receive(:update_query).with({:group_level => 3})
629
647
  @obj.group_level(3)
630
648
  end
631
649
  end
632
650
 
633
651
  describe "#stale" do
634
652
  it "should update query with ok" do
635
- @obj.should_receive(:update_query).with(:stale => 'ok')
653
+ expect(@obj).to receive(:update_query).with(:stale => 'ok')
636
654
  @obj.stale('ok')
637
655
  end
638
656
  it "should update query with update_after" do
639
- @obj.should_receive(:update_query).with(:stale => 'update_after')
657
+ expect(@obj).to receive(:update_query).with(:stale => 'update_after')
640
658
  @obj.stale('update_after')
641
659
  end
642
660
  it "should fail if anything else is provided" do
643
- lambda { @obj.stale('yes') }.should raise_error(/can only be set with/)
661
+ expect { @obj.stale('yes') }.to raise_error(/can only be set with/)
644
662
  end
645
663
  end
646
664
 
647
665
  describe "#include_docs" do
648
666
  it "should call include_docs! on new view" do
649
- @obj.should_receive(:update_query).and_return(@obj)
650
- @obj.should_receive(:include_docs!)
667
+ expect(@obj).to receive(:update_query).and_return(@obj)
668
+ expect(@obj).to receive(:include_docs!)
651
669
  @obj.include_docs
652
670
  end
653
671
  end
654
672
 
655
673
  describe "#reset!" do
656
674
  it "should empty all cached data" do
657
- @obj.should_receive(:result=).with(nil)
675
+ expect(@obj).to receive(:result=).with(nil)
658
676
  @obj.instance_exec { @rows = 'foo'; @docs = 'foo' }
659
677
  @obj.reset!
660
- @obj.instance_exec { @rows }.should be_nil
661
- @obj.instance_exec { @docs }.should be_nil
678
+ expect(@obj.instance_exec { @rows }).to be_nil
679
+ expect(@obj.instance_exec { @docs }).to be_nil
662
680
  end
663
681
  end
664
682
 
@@ -666,58 +684,58 @@ describe "Design View" do
666
684
 
667
685
  describe "#include_docs!" do
668
686
  it "should set query value" do
669
- @obj.should_receive(:result).and_return(false)
670
- @obj.should_not_receive(:reset!)
687
+ expect(@obj).to receive(:result).and_return(false)
688
+ expect(@obj).not_to receive(:reset!)
671
689
  @obj.send(:include_docs!)
672
- @obj.query[:include_docs].should be_true
690
+ expect(@obj.query[:include_docs]).to be_truthy
673
691
  end
674
692
  it "should reset if result and no docs" do
675
- @obj.should_receive(:result).and_return(true)
676
- @obj.should_receive(:include_docs?).and_return(false)
677
- @obj.should_receive(:reset!)
693
+ expect(@obj).to receive(:result).and_return(true)
694
+ expect(@obj).to receive(:include_docs?).and_return(false)
695
+ expect(@obj).to receive(:reset!)
678
696
  @obj.send(:include_docs!)
679
- @obj.query[:include_docs].should be_true
697
+ expect(@obj.query[:include_docs]).to be_truthy
680
698
  end
681
699
  it "should raise an error if view is reduced" do
682
700
  @obj.query[:reduce] = true
683
- lambda { @obj.send(:include_docs!) }.should raise_error
701
+ expect { @obj.send(:include_docs!) }.to raise_error(/Cannot include documents in view that has been reduced/)
684
702
  end
685
703
  end
686
704
 
687
705
  describe "#include_docs?" do
688
706
  it "should return true if set" do
689
- @obj.should_receive(:query).and_return({:include_docs => true})
690
- @obj.send(:include_docs?).should be_true
707
+ expect(@obj).to receive(:query).and_return({:include_docs => true})
708
+ expect(@obj.send(:include_docs?)).to be_truthy
691
709
  end
692
710
  it "should return false if not set" do
693
- @obj.should_receive(:query).and_return({})
694
- @obj.send(:include_docs?).should be_false
695
- @obj.should_receive(:query).and_return({:include_docs => false})
696
- @obj.send(:include_docs?).should be_false
711
+ expect(@obj).to receive(:query).and_return({})
712
+ expect(@obj.send(:include_docs?)).to be_falsey
713
+ expect(@obj).to receive(:query).and_return({:include_docs => false})
714
+ expect(@obj.send(:include_docs?)).to be_falsey
697
715
  end
698
716
  end
699
717
 
700
718
  describe "#update_query" do
701
719
  it "returns a new instance of view" do
702
- @obj.send(:update_query).object_id.should_not eql(@obj.object_id)
720
+ expect(@obj.send(:update_query).object_id).not_to eql(@obj.object_id)
703
721
  end
704
722
 
705
723
  it "returns a new instance of view with extra parameters" do
706
724
  new_obj = @obj.send(:update_query, {:foo => :bar})
707
- new_obj.query[:foo].should eql(:bar)
725
+ expect(new_obj.query[:foo]).to eql(:bar)
708
726
  end
709
727
  end
710
728
 
711
729
  describe "#can_reduce?" do
712
730
  it "should check and prove true" do
713
- @obj.should_receive(:name).and_return('test_view')
714
- @obj.should_receive(:design_doc).and_return({'views' => {'test_view' => {'reduce' => 'foo'}}})
715
- @obj.send(:can_reduce?).should be_true
731
+ expect(@obj).to receive(:name).and_return('test_view')
732
+ expect(@obj).to receive(:design_doc).and_return({'views' => {'test_view' => {'reduce' => 'foo'}}})
733
+ expect(@obj.send(:can_reduce?)).to be_truthy
716
734
  end
717
735
  it "should check and prove false" do
718
- @obj.should_receive(:name).and_return('test_view')
719
- @obj.should_receive(:design_doc).and_return({'views' => {'test_view' => {'reduce' => nil}}})
720
- @obj.send(:can_reduce?).should be_false
736
+ expect(@obj).to receive(:name).and_return('test_view')
737
+ expect(@obj).to receive(:design_doc).and_return({'views' => {'test_view' => {'reduce' => nil}}})
738
+ expect(@obj.send(:can_reduce?)).to be_falsey
721
739
  end
722
740
  end
723
741
 
@@ -725,48 +743,48 @@ describe "Design View" do
725
743
  before :each do
726
744
  # disable real execution!
727
745
  @design_doc = double("DesignDoc")
728
- @design_doc.stub(:view_on)
729
- @design_doc.stub(:sync)
730
- @obj.stub(:design_doc).and_return(@design_doc)
746
+ allow(@design_doc).to receive(:view_on)
747
+ allow(@design_doc).to receive(:sync)
748
+ allow(@obj).to receive(:design_doc).and_return(@design_doc)
731
749
  end
732
750
 
733
751
  it "should return previous result if set" do
734
752
  @obj.result = "foo"
735
- @obj.send(:execute).should eql('foo')
753
+ expect(@obj.send(:execute)).to eql('foo')
736
754
  end
737
755
 
738
756
  it "should raise issue if no database" do
739
- @obj.should_receive(:query).and_return({:database => nil})
757
+ expect(@obj).to receive(:query).and_return({:database => nil})
740
758
  model = double("SomeModel")
741
- model.should_receive(:database).and_return(nil)
742
- @obj.should_receive(:model).and_return(model)
743
- lambda { @obj.send(:execute) }.should raise_error
759
+ expect(model).to receive(:database).and_return(nil)
760
+ expect(@obj).to receive(:model).and_return(model)
761
+ expect { @obj.send(:execute) }.to raise_error(CouchRest::Model::DatabaseNotDefined)
744
762
  end
745
763
 
746
764
  it "should delete the reduce option if not going to be used" do
747
- @obj.should_receive(:can_reduce?).and_return(false)
748
- @obj.query.should_receive(:delete).with(:reduce)
765
+ expect(@obj).to receive(:can_reduce?).and_return(false)
766
+ expect(@obj.query).to receive(:delete).with(:reduce)
749
767
  @obj.send(:execute)
750
768
  end
751
769
 
752
770
  it "should call to save the design document" do
753
- @obj.should_receive(:can_reduce?).and_return(false)
754
- @design_doc.should_receive(:sync).with(DB)
771
+ expect(@obj).to receive(:can_reduce?).and_return(false)
772
+ expect(@design_doc).to receive(:sync).with(DB)
755
773
  @obj.send(:execute)
756
774
  end
757
775
 
758
776
  it "should populate the results" do
759
- @obj.should_receive(:can_reduce?).and_return(true)
760
- @design_doc.should_receive(:view_on).and_return('foos')
777
+ expect(@obj).to receive(:can_reduce?).and_return(true)
778
+ expect(@design_doc).to receive(:view_on).and_return('foos')
761
779
  @obj.send(:execute)
762
- @obj.result.should eql('foos')
780
+ expect(@obj.result).to eql('foos')
763
781
  end
764
782
 
765
783
  it "should not remove nil values from query" do
766
- @obj.should_receive(:can_reduce?).and_return(true)
767
- @obj.stub(:use_database).and_return(@mod.database)
784
+ expect(@obj).to receive(:can_reduce?).and_return(true)
785
+ allow(@obj).to receive(:use_database).and_return(@mod.database)
768
786
  @obj.query = {:reduce => true, :limit => nil, :skip => nil}
769
- @design_doc.should_receive(:view_on).with(@mod.database, 'test_view', {:reduce => true, :limit => nil, :skip => nil})
787
+ expect(@design_doc).to receive(:view_on).with(@mod.database, 'test_view', {:reduce => true, :limit => nil, :skip => nil})
770
788
  @obj.send(:execute)
771
789
  end
772
790
 
@@ -785,59 +803,59 @@ describe "Design View" do
785
803
 
786
804
  describe "#page" do
787
805
  it "should call limit and skip" do
788
- @obj.should_receive(:limit).with(25).and_return(@obj)
789
- @obj.should_receive(:skip).with(25).and_return(@obj)
806
+ expect(@obj).to receive(:limit).with(25).and_return(@obj)
807
+ expect(@obj).to receive(:skip).with(25).and_return(@obj)
790
808
  @obj.page(2)
791
809
  end
792
810
  end
793
811
 
794
812
  describe "#per" do
795
813
  it "should raise an error if page not called before hand" do
796
- lambda { @obj.per(12) }.should raise_error
814
+ expect { @obj.per(12) }.to raise_error(/View#page must be called before #per/)
797
815
  end
798
816
  it "should not do anything if number less than or eql 0" do
799
817
  view = @obj.page(1)
800
- view.per(0).should eql(view)
818
+ expect(view.per(0)).to eql(view)
801
819
  end
802
820
  it "should set limit and update skip" do
803
821
  view = @obj.page(2).per(10)
804
- view.query[:skip].should eql(10)
805
- view.query[:limit].should eql(10)
822
+ expect(view.query[:skip]).to eql(10)
823
+ expect(view.query[:limit]).to eql(10)
806
824
  end
807
825
  end
808
826
 
809
827
  describe "#total_count" do
810
828
  it "set limit and skip to nill and perform count" do
811
- @obj.should_receive(:limit).with(nil).and_return(@obj)
812
- @obj.should_receive(:skip).with(nil).and_return(@obj)
813
- @obj.should_receive(:count).and_return(5)
814
- @obj.total_count.should eql(5)
815
- @obj.total_count.should eql(5) # Second to test caching
829
+ expect(@obj).to receive(:limit).with(nil).and_return(@obj)
830
+ expect(@obj).to receive(:skip).with(nil).and_return(@obj)
831
+ expect(@obj).to receive(:count).and_return(5)
832
+ expect(@obj.total_count).to eql(5)
833
+ expect(@obj.total_count).to eql(5) # Second to test caching
816
834
  end
817
835
  end
818
836
 
819
837
  describe "#total_pages" do
820
838
  it "should use total_count and limit_value" do
821
- @obj.should_receive(:total_count).and_return(200)
822
- @obj.should_receive(:limit_value).and_return(25)
823
- @obj.total_pages.should eql(8)
839
+ expect(@obj).to receive(:total_count).and_return(200)
840
+ expect(@obj).to receive(:limit_value).and_return(25)
841
+ expect(@obj.total_pages).to eql(8)
824
842
  end
825
843
  end
826
844
 
827
845
  # `num_pages` aliases to `total_pages` for compatibility for Kaminari '< 0.14'
828
846
  describe "#num_pages" do
829
847
  it "should use total_count and limit_value" do
830
- @obj.should_receive(:total_count).and_return(200)
831
- @obj.should_receive(:limit_value).and_return(25)
832
- @obj.num_pages.should eql(8)
848
+ expect(@obj).to receive(:total_count).and_return(200)
849
+ expect(@obj).to receive(:limit_value).and_return(25)
850
+ expect(@obj.num_pages).to eql(8)
833
851
  end
834
852
  end
835
853
 
836
854
  describe "#current_page" do
837
855
  it "should use offset and limit" do
838
- @obj.should_receive(:offset_value).and_return(25)
839
- @obj.should_receive(:limit_value).and_return(25)
840
- @obj.current_page.should eql(2)
856
+ expect(@obj).to receive(:offset_value).and_return(25)
857
+ expect(@obj).to receive(:limit_value).and_return(25)
858
+ expect(@obj.current_page).to eql(2)
841
859
  end
842
860
  end
843
861
  end
@@ -852,19 +870,19 @@ describe "Design View" do
852
870
 
853
871
  let :model do
854
872
  m = double()
855
- m.stub(:database).and_return(DB)
873
+ allow(m).to receive(:database).and_return(DB)
856
874
  m
857
875
  end
858
876
 
859
877
  describe "intialize" do
860
878
  it "should store reference to model" do
861
879
  obj = @klass.new({}, model)
862
- obj.model.should eql(model)
880
+ expect(obj.model).to eql(model)
863
881
  end
864
882
  it "should copy details from hash" do
865
883
  obj = @klass.new({:foo => :bar, :test => :example}, model)
866
- obj[:foo].should eql(:bar)
867
- obj[:test].should eql(:example)
884
+ expect(obj[:foo]).to eql(:bar)
885
+ expect(obj[:test]).to eql(:example)
868
886
  end
869
887
  end
870
888
 
@@ -874,7 +892,7 @@ describe "Design View" do
874
892
 
875
893
  it "should provide id" do
876
894
  obj = @klass.new({'id' => '123456'}, model)
877
- obj.id.should eql('123456')
895
+ expect(obj.id).to eql('123456')
878
896
  end
879
897
 
880
898
  it "may be instantiated with a database" do
@@ -889,24 +907,24 @@ describe "Design View" do
889
907
 
890
908
  it "should provide key" do
891
909
  obj = @klass.new({'key' => 'thekey'}, model)
892
- obj.key.should eql('thekey')
910
+ expect(obj.key).to eql('thekey')
893
911
  end
894
912
 
895
913
  it "should provide the value" do
896
914
  obj = @klass.new({'value' => 'thevalue'}, model)
897
- obj.value.should eql('thevalue')
915
+ expect(obj.value).to eql('thevalue')
898
916
  end
899
917
 
900
918
  it "should provide the raw document" do
901
919
  obj = @klass.new({'doc' => 'thedoc'}, model)
902
- obj.raw_doc.should eql('thedoc')
920
+ expect(obj.raw_doc).to eql('thedoc')
903
921
  end
904
922
 
905
923
  it "should instantiate a new document" do
906
924
  hash = {'doc' => {'_id' => '12345', 'name' => 'sam'}}
907
925
  obj = @klass.new(hash, DesignViewModel)
908
926
  doc = double('DesignViewDoc')
909
- doc.stub(:database).and_return(DB)
927
+ allow(doc).to receive(:database).and_return(DB)
910
928
  expect(obj.model).to receive(:build_from_database).with(hash['doc']).and_return(doc)
911
929
  expect(obj.doc).to eql(doc)
912
930
  end
@@ -915,31 +933,31 @@ describe "Design View" do
915
933
  hash = {'id' => '12345', 'value' => 5}
916
934
  obj = @klass.new(hash, DesignViewModel)
917
935
  doc = double('DesignViewModel')
918
- doc.stub(:database).and_return(DB)
919
- obj.model.should_receive(:get).with('12345', DB).and_return(doc)
920
- obj.doc.should eql(doc)
936
+ allow(doc).to receive(:database).and_return(DB)
937
+ expect(obj.model).to receive(:get).with('12345', DB).and_return(doc)
938
+ expect(obj.doc).to eql(doc)
921
939
  end
922
940
 
923
941
  it "should try to load linked document if available" do
924
942
  hash = {'id' => '12345', 'value' => {'_id' => '54321'}}
925
943
  obj = @klass.new(hash, DesignViewModel)
926
944
  doc = double('DesignViewModel')
927
- doc.stub(:database).and_return(DB)
928
- obj.model.should_receive(:get).with('54321', DB).and_return(doc)
929
- obj.doc.should eql(doc)
945
+ allow(doc).to receive(:database).and_return(DB)
946
+ expect(obj.model).to receive(:get).with('54321', DB).and_return(doc)
947
+ expect(obj.doc).to eql(doc)
930
948
  end
931
949
 
932
950
  it "should try to return nil for document if none available" do
933
951
  hash = {'value' => 23} # simulate reduce
934
952
  obj = @klass.new(hash, DesignViewModel)
935
953
  doc = double('DesignViewModel')
936
- obj.model.should_not_receive(:get)
937
- obj.doc.should be_nil
954
+ expect(obj.model).not_to receive(:get)
955
+ expect(obj.doc).to be_nil
938
956
  end
939
957
 
940
958
 
941
959
  end
942
-
960
+
943
961
  end
944
962
 
945
963
 
@@ -957,53 +975,53 @@ describe "Design View" do
957
975
 
958
976
  describe "loading documents" do
959
977
  it "should return first" do
960
- DesignViewModel.by_name.first.name.should eql("Judith")
978
+ expect(DesignViewModel.by_name.first.name).to eql("Judith")
961
979
  end
962
980
 
963
981
  it "should return last" do
964
- DesignViewModel.by_name.last.name.should eql("Vilma")
982
+ expect(DesignViewModel.by_name.last.name).to eql("Vilma")
965
983
  end
966
984
 
967
985
  it "should allow multiple results" do
968
986
  view = DesignViewModel.by_name.limit(3)
969
- view.total_rows.should eql(5)
970
- view.last.name.should eql("Peter")
971
- view.all.length.should eql(3)
987
+ expect(view.total_rows).to eql(5)
988
+ expect(view.last.name).to eql("Peter")
989
+ expect(view.all.length).to eql(3)
972
990
  end
973
991
 
974
992
  it "should not return document if nil key provided" do
975
- DesignViewModel.by_name.key(nil).first.should be_nil
993
+ expect(DesignViewModel.by_name.key(nil).first).to be_nil
976
994
  end
977
995
  end
978
996
 
979
997
  describe "index information" do
980
998
  it "should provide total_rows" do
981
- DesignViewModel.by_name.total_rows.should eql(5)
999
+ expect(DesignViewModel.by_name.total_rows).to eql(5)
982
1000
  end
983
1001
  it "should provide total_rows" do
984
- DesignViewModel.by_name.total_rows.should eql(5)
1002
+ expect(DesignViewModel.by_name.total_rows).to eql(5)
985
1003
  end
986
1004
  it "should provide an offset" do
987
- DesignViewModel.by_name.offset.should eql(0)
1005
+ expect(DesignViewModel.by_name.offset).to eql(0)
988
1006
  end
989
1007
  it "should provide a set of keys" do
990
- DesignViewModel.by_name.limit(2).keys.should eql(["Judith", "Lorena"])
1008
+ expect(DesignViewModel.by_name.limit(2).keys).to eql(["Judith", "Lorena"])
991
1009
  end
992
1010
  end
993
1011
 
994
1012
  describe "viewing" do
995
1013
  it "should load views with no reduce method" do
996
1014
  docs = DesignViewModel.by_just_name.all
997
- docs.length.should eql(5)
1015
+ expect(docs.length).to eql(5)
998
1016
  end
999
1017
  it "should load documents by specific keys" do
1000
1018
  docs = DesignViewModel.by_name.keys(["Judith", "Peter"]).all
1001
- docs[0].name.should eql("Judith")
1002
- docs[1].name.should eql("Peter")
1019
+ expect(docs[0].name).to eql("Judith")
1020
+ expect(docs[1].name).to eql("Peter")
1003
1021
  end
1004
1022
  it "should provide count even if limit or skip set" do
1005
1023
  docs = DesignViewModel.by_name.limit(20).skip(2)
1006
- docs.count.should eql(5)
1024
+ expect(docs.count).to eql(5)
1007
1025
  end
1008
1026
  end
1009
1027
 
@@ -1016,24 +1034,51 @@ describe "Design View" do
1016
1034
  end
1017
1035
 
1018
1036
  it "should calculate number of pages" do
1019
- @view.total_pages.should eql(2)
1037
+ expect(@view.total_pages).to eql(2)
1020
1038
  end
1021
1039
  it "should return results from first page" do
1022
- @view.all.first.name.should eql('Judith')
1023
- @view.all.last.name.should eql('Peter')
1040
+ expect(@view.all.first.name).to eql('Judith')
1041
+ expect(@view.all.last.name).to eql('Peter')
1024
1042
  end
1025
1043
  it "should return results from second page" do
1026
- @view.page(2).all.first.name.should eql('Sam')
1027
- @view.page(2).all.last.name.should eql('Vilma')
1044
+ expect(@view.page(2).all.first.name).to eql('Sam')
1045
+ expect(@view.page(2).all.last.name).to eql('Vilma')
1028
1046
  end
1029
1047
 
1030
1048
  it "should allow overriding per page count" do
1031
1049
  @view = @view.per(10)
1032
- @view.total_pages.should eql(1)
1033
- @view.all.last.name.should eql('Vilma')
1050
+ expect(@view.total_pages).to eql(1)
1051
+ expect(@view.all.last.name).to eql('Vilma')
1034
1052
  end
1035
1053
  end
1036
1054
 
1055
+ describe "concurrent view accesses" do
1056
+
1057
+ # NOTE: must use `DesignViewModel2` instead of `DesignViewModel` to mimic
1058
+ # a "cold" start of a multi-threaded application (as the checksum is
1059
+ # stored at the class level)
1060
+ class DesignViewModel2 < CouchRest::Model::Base
1061
+ use_database DB
1062
+ property :name
1063
+
1064
+ design do
1065
+ view :by_name
1066
+ end
1067
+ end
1068
+
1069
+ it "should not conflict" do
1070
+ expect {
1071
+ threads = 2.times.map {
1072
+ Thread.new {
1073
+ DesignViewModel2.by_name.page(1).to_a
1074
+ }
1075
+ }
1076
+ threads.each(&:join)
1077
+ }.to_not raise_error
1078
+ end
1079
+
1080
+ end
1081
+
1037
1082
  end
1038
1083
 
1039
1084