mongoid_rateable 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -70,6 +70,10 @@ And if someone rated it:
70
70
 
71
71
  @post.rated? # True if it rated by someone
72
72
 
73
+ You can get user mark:
74
+
75
+ @post.user_mark(@user) # Mark or nil (if not rated by user)
76
+
73
77
  You can also get a tally of the number of rates cast:
74
78
 
75
79
  @post.rate_count # Just one so far!
@@ -109,6 +113,7 @@ You can get posts with some rating:
109
113
  Post.with_rating(-2..2)
110
114
 
111
115
  You can get most rated and highest rated posts:
116
+ (Sorry, this method doesn't work with embedded documents)
112
117
 
113
118
  Post.highest_rated # 10 (or less) highest rated posts
114
119
  Post.highest_rated(5) # 5 (or less) highest rated posts
data/TODO CHANGED
@@ -1,5 +1,3 @@
1
1
  improve speed (http://cookbook.mongodb.org/patterns/votes/)
2
- rate embedded (indexes?!)
3
2
  add random values to specs
4
- add task for rating update
5
- add bayesian_rating ( https://github.com/mepatterson/acts_as_mongo_rateable )
3
+ add task for rating update
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.2.3
@@ -80,6 +80,11 @@ module Mongoid
80
80
  read_attribute(:weighted_rate_count)
81
81
  end
82
82
 
83
+ def user_mark(rater)
84
+ r = self.rating_marks.where(:rater_id => rater.id, :rater_class => rater.class.to_s).first
85
+ r ? r.mark : nil
86
+ end
87
+
83
88
  protected
84
89
 
85
90
  def validate_rating!(value)
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "mongoid_rateable"
8
- s.version = "0.2.2"
8
+ s.version = "0.2.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Peter Savichev (proton)"]
12
- s.date = "2012-09-11"
12
+ s.date = "2012-09-29"
13
13
  s.description = "Provides fields and methods for the rating manipulation on Mongoid documents."
14
14
  s.email = "psavichev@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
33
33
  "lib/mongoid_rateable/version.rb",
34
34
  "mongoid_rateable.gemspec",
35
35
  "spec/models/article.rb",
36
+ "spec/models/comment.rb",
36
37
  "spec/models/post.rb",
37
38
  "spec/models/user.rb",
38
39
  "spec/rateable_spec.rb",
@@ -0,0 +1,10 @@
1
+ class Comment
2
+ include Mongoid::Document
3
+ include Mongoid::Rateable
4
+
5
+ RATING_RANGE = (-5..7)
6
+
7
+ embedded_in :post
8
+
9
+ field :content
10
+ end
data/spec/models/post.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  class Post
2
2
  include Mongoid::Document
3
3
  include Mongoid::Rateable
4
-
5
- field :name
6
-
4
+
5
+ embeds_many :comments
7
6
  end
@@ -2,356 +2,379 @@ require "spec_helper"
2
2
 
3
3
  describe Post do
4
4
 
5
- before(:each) do
6
- @bob = User.create :name => "Bob"
7
- @alice = User.create :name => "Alice"
8
- @sally = User.create :name => "Sally"
9
- @post = Post.create :name => "Announcement"
10
- @article = Article.create :name => "Article"
11
- end
12
-
13
- it "should have Mongoid::Rateable module" do
14
- #TODO: Refactor this
15
- @post.class.const_get("Mongoid").const_get("Rateable").should be_true
16
- end
17
-
18
- subject { @post }
19
- it { should respond_to :rate }
20
- it { should respond_to :unrate }
21
- it { should respond_to :rate_and_save }
22
- it { should respond_to :unrate_and_save }
23
- it { should respond_to :rated? }
24
- it { should respond_to :rate_count }
25
- it { should respond_to :rates }
26
- it { should respond_to :rating }
27
- it { should respond_to :previous_rating }
28
- it { should respond_to :rating_delta }
29
- it { should respond_to :unweighted_rating }
30
- it { should respond_to :rating_marks }
31
-
32
- describe "#rating_marks" do
33
- it "should be proper Mongoid field" do
34
- @post.rating_marks.should be_an_instance_of Array
35
- end
36
- end
37
-
38
- context "when rated" do
39
- before (:each) { @post.rate 1, @bob }
40
-
41
- describe "#rate" do
42
- it "should track #rates properly" do
43
- @post.rate 1, @sally
44
- @post.rates.should eql 2
45
- end
46
- it "should track weighted #rates properly" do
47
- @post.rate 1, @alice, 4
48
- @post.rates.should eql 5
49
- end
50
-
51
- it "should limit #rates by user properly" do
52
- @post.rate 5, @bob
53
- @post.rates.should eql 5
54
- end
55
-
56
- it "should not raise exception if rate_value in RATING_RANGE" do
57
- lambda { @article.rate 1, @sally }.should_not raise_error
58
- end
59
-
60
- it "should raise exception if rate_value not in RATING_RANGE" do
61
- lambda { @article.rate 7, @sally }.should raise_error(ArgumentError)
62
- end
63
-
64
- #TODO: Rewrite for random values
65
- describe "when using negative values" do
66
- it "should work properly for -3" do
67
- @post.rate -3, @sally
68
- @post.rates.should eql -2
69
- end
70
- it "should work properly for -1 with weight 3" do
71
- @post.rate -1, @sally, 3
72
- @post.rates.should eql -2
73
- end
74
- end
75
- end
76
-
77
- describe "#rated?" do
78
- describe "for anyone" do
79
- specify { @post.rated?().should be_true }
80
- end
81
-
82
- describe "for Bob" do
83
- specify { @post.rated_by?(@bob).should be_true }
84
- end
85
-
86
- describe "when rated by someone else" do
87
- before { @post.rate 1, @alice }
88
-
89
- describe "for Alice" do
90
- specify { @post.rated_by?(@alice).should be_true }
91
- end
92
- end
93
-
94
- describe "when not rated by someone else" do
95
- describe "for Sally" do
96
- specify { @post.rated_by?(@sally).should be_false }
97
- end
98
- end
99
- end
100
-
101
- describe "#unrate" do
102
- before { @post.unrate @bob }
103
-
104
- it "should have null #rate_count" do
105
- @post.rate_count.should eql 0
106
- end
107
-
108
- it "should have null #rates" do
109
- @post.rates.should eql 0
110
- end
111
-
112
- it "should be unrated" do
113
- @post.rated?.should be_false
114
- end
115
- end
116
-
117
- describe "#rate_count" do
118
- it "should know how many rates have been cast" do
119
- @post.rate 1, @sally
120
- @post.rate_count.should eql 2
121
- end
122
- end
123
-
124
- describe "#rating" do
125
- it "should calculate the average rate" do
126
- @post.rate 4, @sally
127
- @post.rating.should eq 2.5
128
- end
129
-
130
- it "should calculate the average rate if the result is zero" do
131
- @post.rate -1, @sally
132
- @post.rating.should eq 0.0
133
- end
134
- end
135
-
136
- describe "#previous_rating" do
137
- it "should store previous value of the average rate" do
138
- @post.rate 4, @sally
139
- @post.previous_rating.should eq 1.0
140
- end
141
-
142
- it "should store previous value of the average rate after two changes" do
143
- @post.rate -1, @sally
144
- @post.rate 4, @sally
145
- @post.previous_rating.should eq 0.0
146
- end
147
- end
148
-
149
- describe "#rating_delta" do
150
- it "should calculate delta of previous and new ratings" do
151
- @post.rate 4, @sally
152
- @post.rating_delta.should eq 1.5
153
- end
154
-
155
- it "should calculate delta of previous and new ratings" do
156
- @post.rate -1, @sally
157
- @post.rating_delta.should eq -1.0
158
- end
159
- end
160
-
161
- describe "#unweighted_rating" do
162
- it "should calculate the unweighted average rate" do
163
- @post.rate 4, @sally
164
- @post.unweighted_rating.should eq 2.5
165
- end
166
-
167
- it "should calculate the unweighted average rate if the result is zero" do
168
- @post.rate -1, @sally
169
- @post.unweighted_rating.should eq 0.0
170
- end
171
- end
172
- end
173
-
174
- context "when not rated" do
175
- describe "#rates" do
176
- specify { @post.rates.should eql 0 }
177
- end
178
-
179
- describe "#rating" do
180
- specify { @post.rating.should be_nil }
181
- end
182
-
183
- describe "#previous_rating" do
184
- specify { @post.previous_rating.should be_nil }
185
- end
186
-
187
- describe "#rating_delta" do
188
- specify { @post.rating_delta.should eq 0.0 }
189
- end
190
-
191
- describe "#unweighted_rating" do
192
- specify { @post.unweighted_rating.should be_nil }
193
- end
194
-
195
- describe "#unrate" do
196
- before { @post.unrate @sally }
5
+ before(:each) do
6
+ @bob = User.create :name => "Bob"
7
+ @alice = User.create :name => "Alice"
8
+ @sally = User.create :name => "Sally"
9
+ @post = Post.create :name => "Announcement"
10
+ @article = Article.create :name => "Article"
11
+ end
12
+
13
+ it "should have Mongoid::Rateable module" do
14
+ #TODO: Refactor this
15
+ @post.class.const_get("Mongoid").const_get("Rateable").should be_true
16
+ end
17
+
18
+ subject { @post }
19
+ it { should respond_to :rate }
20
+ it { should respond_to :unrate }
21
+ it { should respond_to :rate_and_save }
22
+ it { should respond_to :unrate_and_save }
23
+ it { should respond_to :rated? }
24
+ it { should respond_to :rate_count }
25
+ it { should respond_to :rates }
26
+ it { should respond_to :rating }
27
+ it { should respond_to :previous_rating }
28
+ it { should respond_to :rating_delta }
29
+ it { should respond_to :unweighted_rating }
30
+ it { should respond_to :rating_marks }
31
+ it { should respond_to :user_mark }
32
+
33
+ describe "#rating_marks" do
34
+ it "should be proper Mongoid field" do
35
+ @post.rating_marks.should be_an_instance_of Array
36
+ end
37
+ end
38
+
39
+ context "when rated" do
40
+ before (:each) do
41
+ @post.rate 1, @bob
42
+ end
43
+
44
+ describe "#rate" do
45
+ it "should track #rates properly" do
46
+ @post.rate 1, @sally
47
+ @post.rates.should eql 2
48
+ end
49
+
50
+ it "should track weighted #rates properly" do
51
+ @post.rate 1, @alice, 4
52
+ @post.rates.should eql 5
53
+ end
54
+
55
+ it "should limit #rates by user properly" do
56
+ @post.rate 5, @bob
57
+ @post.rates.should eql 5
58
+ end
59
+
60
+ it "should not raise exception if rate_value in RATING_RANGE" do
61
+ lambda { @article.rate 1, @sally }.should_not raise_error
62
+ end
63
+
64
+ it "should raise exception if rate_value not in RATING_RANGE" do
65
+ lambda { @article.rate 7, @sally }.should raise_error(ArgumentError)
66
+ end
67
+
68
+ #TODO: Rewrite for random values
69
+ describe "when using negative values" do
70
+ it "should work properly for -3" do
71
+ @post.rate -3, @sally
72
+ @post.rates.should eql -2
73
+ end
74
+ it "should work properly for -1 with weight 3" do
75
+ @post.rate -1, @sally, 3
76
+ @post.rates.should eql -2
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "#rated?" do
82
+ describe "for anyone" do
83
+ specify { @post.rated?().should be_true }
84
+ end
85
+ describe "for anyone" do
86
+ specify { @article.rated?().should be_false }
87
+ end
88
+
89
+ describe "for Bob" do
90
+ specify { @post.rated_by?(@bob).should be_true }
91
+ end
92
+ describe "for Bob" do
93
+ specify { @article.rated_by?(@bob).should be_false }
94
+ end
95
+
96
+ describe "when rated by someone else" do
97
+ before do
98
+ @post.rate 1, @alice
99
+ end
100
+
101
+ describe "for Alice" do
102
+ specify { @post.rated_by?(@alice).should be_true }
103
+ end
104
+ end
105
+
106
+ describe "when not rated by someone else" do
107
+ describe "for Sally" do
108
+ specify { @post.rated_by?(@sally).should be_false }
109
+ end
110
+ end
111
+ end
112
+
113
+ describe "#unrate" do
114
+ before { @post.unrate @bob }
115
+
116
+ it "should have null #rate_count" do
117
+ @post.rate_count.should eql 0
118
+ end
119
+
120
+ it "should have null #rates" do
121
+ @post.rates.should eql 0
122
+ end
123
+
124
+ it "should be unrated" do
125
+ @post.rated?.should be_false
126
+ end
127
+ end
128
+
129
+ describe "#rate_count" do
130
+ it "should know how many rates have been cast" do
131
+ @post.rate 1, @sally
132
+ @post.rate_count.should eql 2
133
+ end
134
+ end
135
+
136
+ describe "#rating" do
137
+ it "should calculate the average rate" do
138
+ @post.rate 4, @sally
139
+ @post.rating.should eq 2.5
140
+ end
141
+
142
+ it "should calculate the average rate if the result is zero" do
143
+ @post.rate -1, @sally
144
+ @post.rating.should eq 0.0
145
+ end
146
+ end
147
+
148
+ describe "#previous_rating" do
149
+ it "should store previous value of the average rate" do
150
+ @post.rate 4, @sally
151
+ @post.previous_rating.should eq 1.0
152
+ end
153
+
154
+ it "should store previous value of the average rate after two changes" do
155
+ @post.rate -1, @sally
156
+ @post.rate 4, @sally
157
+ @post.previous_rating.should eq 0.0
158
+ end
159
+ end
160
+
161
+ describe "#rating_delta" do
162
+ it "should calculate delta of previous and new ratings" do
163
+ @post.rate 4, @sally
164
+ @post.rating_delta.should eq 1.5
165
+ end
166
+
167
+ it "should calculate delta of previous and new ratings" do
168
+ @post.rate -1, @sally
169
+ @post.rating_delta.should eq -1.0
170
+ end
171
+ end
172
+
173
+ describe "#unweighted_rating" do
174
+ it "should calculate the unweighted average rate" do
175
+ @post.rate 4, @sally
176
+ @post.unweighted_rating.should eq 2.5
177
+ end
178
+
179
+ it "should calculate the unweighted average rate if the result is zero" do
180
+ @post.rate -1, @sally
181
+ @post.unweighted_rating.should eq 0.0
182
+ end
183
+ end
184
+
185
+ describe "#user_mark" do
186
+ describe "should give mark" do
187
+ specify { @post.user_mark(@bob).should eq 1}
188
+ end
189
+ describe "should give nil" do
190
+ specify { @post.user_mark(@alice).should be_nil}
191
+ end
192
+ end
193
+ end
194
+
195
+ context "when not rated" do
196
+ describe "#rates" do
197
+ specify { @post.rates.should eql 0 }
198
+ end
199
+
200
+ describe "#rating" do
201
+ specify { @post.rating.should be_nil }
202
+ end
203
+
204
+ describe "#previous_rating" do
205
+ specify { @post.previous_rating.should be_nil }
206
+ end
207
+
208
+ describe "#rating_delta" do
209
+ specify { @post.rating_delta.should eq 0.0 }
210
+ end
211
+
212
+ describe "#unweighted_rating" do
213
+ specify { @post.unweighted_rating.should be_nil }
214
+ end
215
+
216
+ describe "#unrate" do
217
+ before do
218
+ @post.unrate @sally
219
+ end
197
220
 
198
221
  it "should have null #rate_count" do
199
- @post.rate_count.should eql 0
200
- end
222
+ @post.rate_count.should eql 0
223
+ end
201
224
 
202
225
  it "should have null #rates" do
203
- @post.rates.should eql 0
204
- end
205
- end
206
- end
207
-
208
- context "when saving the collection" do
209
- before (:each) do
210
- @post.rate 8, @bob
211
- @post.rate -10, @sally
212
- @post.save
213
- @finded_post = Post.where(:name => "Announcement").first
214
- end
215
-
216
- describe "#rated_by?" do
217
- describe "for Bob" do
218
- specify { @finded_post.rated_by?(@bob).should be_true }
219
- end
220
-
221
- describe "for Sally" do
222
- specify { @finded_post.rated_by?(@sally).should be_true }
223
- end
224
-
225
- describe "for Alice" do
226
- specify { @finded_post.rated_by?(@alice).should be_false}
227
- end
228
- end
229
-
230
- describe "#rates" do
231
- specify { @finded_post.rates.should eql -2 }
232
- end
233
-
234
- describe "#rate_count" do
235
- specify { @finded_post.rate_count.should eql 2 }
236
- end
237
-
238
- describe "#rating" do
239
- specify { @finded_post.rating.should eq -1.0 }
240
- end
241
-
242
- describe "#previous_rating" do
243
- specify { @finded_post.previous_rating.should eq 8.0 }
244
- end
245
-
246
- describe "#rating_delta" do
247
- specify { @post.rating_delta.should eq -9.0 }
248
- end
249
-
250
- describe "#unweighted_rating" do
251
- specify { @finded_post.unweighted_rating.should eq -1.0 }
252
- end
253
- end
254
-
255
- describe "#rate_and_save" do
256
- before (:each) do
257
- @post.rate_and_save 8, @bob, 2
258
- @post.rate_and_save -10, @sally
259
- @finded_post = Post.where(:name => "Announcement").first
260
- end
261
-
262
- describe "#rated?" do
226
+ @post.rates.should eql 0
227
+ end
228
+ end
229
+ end
230
+
231
+ context "when saving the collection" do
232
+ before (:each) do
233
+ @post.rate 8, @bob
234
+ @post.rate -10, @sally
235
+ @post.save
236
+ @f_post = Post.where(:name => "Announcement").first
237
+ end
238
+
239
+ describe "#rated_by?" do
240
+ describe "for Bob" do
241
+ specify { @f_post.rated_by?(@bob).should be_true }
242
+ end
243
+
244
+ describe "for Sally" do
245
+ specify { @f_post.rated_by?(@sally).should be_true }
246
+ end
247
+
248
+ describe "for Alice" do
249
+ specify { @f_post.rated_by?(@alice).should be_false}
250
+ end
251
+ end
252
+
253
+ describe "#rates" do
254
+ specify { @f_post.rates.should eql -2 }
255
+ end
256
+
257
+ describe "#rate_count" do
258
+ specify { @f_post.rate_count.should eql 2 }
259
+ end
260
+
261
+ describe "#rating" do
262
+ specify { @f_post.rating.should eq -1.0 }
263
+ end
264
+
265
+ describe "#previous_rating" do
266
+ specify { @f_post.previous_rating.should eq 8.0 }
267
+ end
268
+
269
+ describe "#rating_delta" do
270
+ specify { @post.rating_delta.should eq -9.0 }
271
+ end
272
+
273
+ describe "#unweighted_rating" do
274
+ specify { @f_post.unweighted_rating.should eq -1.0 }
275
+ end
276
+ end
277
+
278
+ describe "#rate_and_save" do
279
+ before (:each) do
280
+ @post.rate_and_save 8, @bob, 2
281
+ @post.rate_and_save -10, @sally
282
+ @f_post = Post.where(:name => "Announcement").first
283
+ end
284
+
285
+ describe "#rated?" do
263
286
  it "should be #rated? by Bob" do
264
- @finded_post.rated_by?(@bob).should be_true
287
+ @f_post.rated_by?(@bob).should be_true
265
288
  end
266
289
 
267
290
  it "should be #rated? by Sally" do
268
- @finded_post.rated_by?(@sally).should be_true
291
+ @f_post.rated_by?(@sally).should be_true
269
292
  end
270
293
 
271
294
  it "should be not #rated? by Alice" do
272
- @finded_post.rated_by?(@alice).should be_false
295
+ @f_post.rated_by?(@alice).should be_false
273
296
  end
274
- end
297
+ end
275
298
 
276
- it "should have #rates equal 6" do
277
- @finded_post.rates.should eql 6
278
- end
299
+ it "should have #rates equal 6" do
300
+ @f_post.rates.should eql 6
301
+ end
279
302
 
280
- it "should have #rate_count equal 2" do
281
- @finded_post.rate_count.should eql 2
282
- end
303
+ it "should have #rate_count equal 2" do
304
+ @f_post.rate_count.should eql 2
305
+ end
283
306
 
284
- it "should have #rate_weight equal 3" do
285
- @finded_post.rate_weight.should eql 3
286
- end
307
+ it "should have #rate_weight equal 3" do
308
+ @f_post.rate_weight.should eql 3
309
+ end
287
310
 
288
- it "should have #rating equal 2.0" do
289
- @finded_post.rating.should eq 2.0
290
- end
311
+ it "should have #rating equal 2.0" do
312
+ @f_post.rating.should eq 2.0
313
+ end
291
314
 
292
- it "should have #previous_rating equal 8.0" do
293
- @finded_post.previous_rating.should eq 8.0
294
- end
315
+ it "should have #previous_rating equal 8.0" do
316
+ @f_post.previous_rating.should eq 8.0
317
+ end
295
318
 
296
- it "should have #rating_delta equal -6.0" do
297
- @finded_post.rating_delta.should eq -6.0
298
- end
319
+ it "should have #rating_delta equal -6.0" do
320
+ @f_post.rating_delta.should eq -6.0
321
+ end
299
322
 
300
- it "should have #unweighted_rating equal 2.0" do
301
- @finded_post.unweighted_rating.should eq -1.0
302
- end
323
+ it "should have #unweighted_rating equal -1.0" do
324
+ @f_post.unweighted_rating.should eq -1.0
325
+ end
303
326
 
304
- describe "#unrate_and_save" do
327
+ describe "#unrate_and_save" do
305
328
  before (:each) do
306
329
  @post.unrate_and_save @bob
307
- @finded_post = Post.where(:name => "Announcement").first
330
+ @f_post = Post.where(:name => "Announcement").first
308
331
  end
309
332
 
310
333
  describe "#rated?" do
311
334
  it "should be #rated? by Sally" do
312
- @finded_post.rated_by?(@sally).should be_true
335
+ @f_post.rated_by?(@sally).should be_true
313
336
  end
314
337
 
315
338
  it "should be not #rated? by Bob" do
316
- @finded_post.rated_by?(@bob).should be_false
339
+ @f_post.rated_by?(@bob).should be_false
317
340
  end
318
341
 
319
342
  it "should be #rated?" do
320
- @finded_post.rated?.should be_true
343
+ @f_post.rated?.should be_true
321
344
  end
322
345
  end
323
346
 
324
347
  it "should have #rates equal -10" do
325
- @finded_post.rates.should eql -10
348
+ @f_post.rates.should eql -10
326
349
  end
327
350
 
328
351
  it "should have #rate_count equal 1" do
329
- @finded_post.rate_count.should eql 1
352
+ @f_post.rate_count.should eql 1
330
353
  end
331
354
 
332
355
  it "should have #rate_weight equal 1" do
333
- @finded_post.rate_weight.should eql 1
356
+ @f_post.rate_weight.should eql 1
334
357
  end
335
358
 
336
- it "should have #rating equal -10.0" do
337
- @finded_post.rating.should eq -10.0
338
- end
359
+ it "should have #rating equal -10.0" do
360
+ @f_post.rating.should eq -10.0
361
+ end
339
362
 
340
- it "should have #previous_rating equal 2.0" do
341
- @finded_post.previous_rating.should eq 2.0
342
- end
363
+ it "should have #previous_rating equal 2.0" do
364
+ @f_post.previous_rating.should eq 2.0
365
+ end
343
366
 
344
- it "should have #rating_delta equal -12.0" do
345
- @finded_post.rating_delta.should eq -12.0
346
- end
367
+ it "should have #rating_delta equal -12.0" do
368
+ @f_post.rating_delta.should eq -12.0
369
+ end
347
370
 
348
- it "should have #unweighted_rating equal -10.0" do
349
- @finded_post.unweighted_rating.should eq -10.0
350
- end
351
- end
352
- end
371
+ it "should have #unweighted_rating equal -10.0" do
372
+ @f_post.unweighted_rating.should eq -10.0
373
+ end
374
+ end
375
+ end
353
376
 
354
- describe "#scopes" do
377
+ describe "#scopes" do
355
378
  before (:each) do
356
379
  @post.delete
357
380
  @post1 = Post.create(:name => "Post 1")
@@ -364,19 +387,19 @@ describe Post do
364
387
  @post4.rate_and_save 1, @sally
365
388
  end
366
389
 
367
- describe "#unrated" do
390
+ describe "#unrated" do
368
391
  it "should return proper count of unrated posts" do
369
392
  Post.unrated.size.should eql 3
370
393
  end
371
394
  end
372
395
 
373
- describe "#rated" do
396
+ describe "#rated" do
374
397
  it "should return proper count of rated posts" do
375
398
  Post.rated.size.should eql 2
376
399
  end
377
400
  end
378
401
 
379
- describe "#rated_by" do
402
+ describe "#rated_by" do
380
403
  it "should return proper count of posts rated by Bob" do
381
404
  Post.rated_by(@bob).size.should eql 1
382
405
  end
@@ -386,7 +409,7 @@ describe Post do
386
409
  end
387
410
  end
388
411
 
389
- describe "#with_rating" do
412
+ describe "#with_rating" do
390
413
  before (:each) do
391
414
  @post1.rate_and_save 4, @alice
392
415
  @post2.rate_and_save 2, @alice
@@ -407,7 +430,7 @@ describe Post do
407
430
  end
408
431
  end
409
432
 
410
- describe "#highest_rated" do
433
+ describe "#highest_rated" do
411
434
  it "should return proper count of posts" do
412
435
  #mongoid has problems with returning count of documents (https://github.com/mongoid/mongoid/issues/817)
413
436
  posts_count = 0
@@ -426,5 +449,462 @@ describe Post do
426
449
  Post.highest_rated(1).first.name.should eql "Post 1"
427
450
  end
428
451
  end
429
- end
452
+ end
453
+ end
454
+
455
+ describe Comment do
456
+
457
+ before(:each) do
458
+ @bob = User.create :name => "Bob"
459
+ @alice = User.create :name => "Alice"
460
+ @sally = User.create :name => "Sally"
461
+ @post = Post.create :name => "Announcement"
462
+ @comment1 = @post.comments.create :content => 'Hello!'
463
+ @comment2 = @post.comments.create :content => 'Goodbye!'
464
+ end
465
+
466
+ it "should have Mongoid::Rateable module" do
467
+ #TODO: Refactor this
468
+ @comment1.class.const_get("Mongoid").const_get("Rateable").should be_true
469
+ end
470
+
471
+ subject { @comment1 }
472
+ it { should respond_to :rate }
473
+ it { should respond_to :unrate }
474
+ it { should respond_to :rate_and_save }
475
+ it { should respond_to :unrate_and_save }
476
+ it { should respond_to :rated? }
477
+ it { should respond_to :rate_count }
478
+ it { should respond_to :rates }
479
+ it { should respond_to :rating }
480
+ it { should respond_to :previous_rating }
481
+ it { should respond_to :rating_delta }
482
+ it { should respond_to :unweighted_rating }
483
+ it { should respond_to :rating_marks }
484
+ it { should respond_to :user_mark }
485
+
486
+ describe "#rating_marks" do
487
+ it "should be proper Mongoid field" do
488
+ @comment1.rating_marks.should be_an_instance_of Array
489
+ end
490
+ end
491
+
492
+ context "when rated" do
493
+ before (:each) do
494
+ @comment1.rate 2, @bob
495
+ end
496
+
497
+ describe "#rate" do
498
+ it "should track #rates properly" do
499
+ @comment1.rate 3, @sally
500
+ @comment1.rates.should eql 5
501
+ end
502
+
503
+ it "should track weighted #rates properly" do
504
+ @comment1.rate 1, @alice, 4
505
+ @comment1.rates.should eql 6
506
+ end
507
+
508
+ it "should limit #rates by user properly" do
509
+ @comment1.rate 5, @bob
510
+ @comment1.rates.should eql 5
511
+ end
512
+
513
+ it "should not raise exception if rate_value in RATING_RANGE" do
514
+ lambda { @comment1.rate 1, @sally }.should_not raise_error
515
+ end
516
+
517
+ it "should raise exception if rate_value not in RATING_RANGE" do
518
+ lambda { @comment1.rate 9, @sally }.should raise_error(ArgumentError)
519
+ end
520
+
521
+ #TODO: Rewrite for random values
522
+ describe "when using negative values" do
523
+ it "should work properly for -3" do
524
+ @comment1.rate -3, @sally
525
+ @comment1.rates.should eql -1
526
+ end
527
+ it "should work properly for -1 with weight 3" do
528
+ @comment1.rate -1, @sally, 3
529
+ @comment1.rates.should eql -1
530
+ end
531
+ end
532
+ end
533
+
534
+ describe "#rated?" do
535
+ describe "for anyone" do
536
+ specify { @comment1.rated?().should be_true }
537
+ end
538
+ describe "for anyone" do
539
+ specify { @comment2.rated?().should be_false }
540
+ end
541
+
542
+ describe "for Bob" do
543
+ specify { @comment1.rated_by?(@bob).should be_true }
544
+ end
545
+ describe "for Bob" do
546
+ specify { @comment2.rated_by?(@bob).should be_false }
547
+ end
548
+
549
+ describe "when rated by someone else" do
550
+ before do
551
+ @comment1.rate 1, @alice
552
+ end
553
+
554
+ describe "for Alice" do
555
+ specify { @comment1.rated_by?(@alice).should be_true }
556
+ end
557
+ end
558
+
559
+ describe "when not rated by someone else" do
560
+ describe "for Sally" do
561
+ specify { @comment1.rated_by?(@sally).should be_false }
562
+ end
563
+ end
564
+ end
565
+
566
+ describe "#unrate" do
567
+ before { @comment1.unrate @bob }
568
+
569
+ it "should have null #rate_count" do
570
+ @comment1.rate_count.should eql 0
571
+ end
572
+
573
+ it "should have null #rates" do
574
+ @comment1.rates.should eql 0
575
+ end
576
+
577
+ it "should be unrated" do
578
+ @comment1.rated?.should be_false
579
+ end
580
+ end
581
+
582
+ describe "#rate_count" do
583
+ it "should know how many rates have been cast" do
584
+ @comment1.rate 1, @sally
585
+ @comment1.rate_count.should eql 2
586
+ end
587
+ end
588
+
589
+ describe "#rating" do
590
+ it "should calculate the average rate" do
591
+ @comment1.rate 4, @sally
592
+ @comment1.rating.should eq 3.0
593
+ end
594
+
595
+ it "should calculate the average rate if the result is zero" do
596
+ @comment1.rate -2, @sally
597
+ @comment1.rating.should eq 0.0
598
+ end
599
+ end
600
+
601
+ describe "#previous_rating" do
602
+ it "should store previous value of the average rate" do
603
+ @comment1.rate 4, @sally
604
+ @comment1.previous_rating.should eq 2.0
605
+ end
606
+
607
+ it "should store previous value of the average rate after two changes" do
608
+ @comment1.rate -2, @sally
609
+ @comment1.rate 4, @sally
610
+ @comment1.previous_rating.should eq 0.0
611
+ end
612
+ end
613
+
614
+ describe "#rating_delta" do
615
+ it "should calculate delta of previous and new ratings" do
616
+ @comment1.rate 4, @sally
617
+ @comment1.rating_delta.should eq 1.0
618
+ end
619
+
620
+ it "should calculate delta of previous and new ratings" do
621
+ @comment1.rate -1, @sally
622
+ @comment1.rating_delta.should eq -1.5
623
+ end
624
+ end
625
+
626
+ describe "#unweighted_rating" do
627
+ it "should calculate the unweighted average rate" do
628
+ @comment1.rate 4, @sally
629
+ @comment1.unweighted_rating.should eq 3.0
630
+ end
631
+
632
+ it "should calculate the unweighted average rate if the result is zero" do
633
+ @comment1.rate -2, @sally
634
+ @comment1.unweighted_rating.should eq 0.0
635
+ end
636
+ end
637
+
638
+ describe "#user_mark" do
639
+ describe "should give mark" do
640
+ specify { @comment1.user_mark(@bob).should eq 2}
641
+ end
642
+ describe "should give nil" do
643
+ specify { @comment1.user_mark(@alice).should be_nil}
644
+ end
645
+ end
646
+ end
647
+
648
+ context "when not rated" do
649
+ describe "#rates" do
650
+ specify { @comment1.rates.should eql 0 }
651
+ end
652
+
653
+ describe "#rating" do
654
+ specify { @comment1.rating.should be_nil }
655
+ end
656
+
657
+ describe "#previous_rating" do
658
+ specify { @comment1.previous_rating.should be_nil }
659
+ end
660
+
661
+ describe "#rating_delta" do
662
+ specify { @comment1.rating_delta.should eq 0.0 }
663
+ end
664
+
665
+ describe "#unweighted_rating" do
666
+ specify { @comment1.unweighted_rating.should be_nil }
667
+ end
668
+
669
+ describe "#unrate" do
670
+ before do
671
+ @comment1.unrate @sally
672
+ end
673
+
674
+ it "should have null #rate_count" do
675
+ @comment1.rate_count.should eql 0
676
+ end
677
+
678
+ it "should have null #rates" do
679
+ @comment1 .rates.should eql 0
680
+ end
681
+ end
682
+ end
683
+
684
+ context "when saving the collection" do
685
+ before (:each) do
686
+ @comment1.rate 3, @bob
687
+ @comment1.rate -2, @sally
688
+ @comment1.save
689
+ @f_post = Post.where(:name => "Announcement").first
690
+ @f_comment = @f_post.comments.where(:content => "Hello!").first
691
+ end
692
+
693
+ describe "#rated_by?" do
694
+ describe "for Bob" do
695
+ specify { @f_comment.rated_by?(@bob).should be_true }
696
+ end
697
+
698
+ describe "for Sally" do
699
+ specify { @f_comment.rated_by?(@sally).should be_true }
700
+ end
701
+
702
+ describe "for Alice" do
703
+ specify { @f_comment.rated_by?(@alice).should be_false}
704
+ end
705
+ end
706
+
707
+ describe "#rates" do
708
+ specify { @f_comment.rates.should eql 1 }
709
+ end
710
+
711
+ describe "#rate_count" do
712
+ specify { @f_comment.rate_count.should eql 2 }
713
+ end
714
+
715
+ describe "#rating" do
716
+ specify { @f_comment.rating.should eq 0.5 }
717
+ end
718
+
719
+ describe "#previous_rating" do
720
+ specify { @f_comment.previous_rating.should eq 3.0 }
721
+ end
722
+
723
+ describe "#rating_delta" do
724
+ specify { @f_comment.rating_delta.should eq -2.5 }
725
+ end
726
+
727
+ describe "#unweighted_rating" do
728
+ specify { @f_comment.unweighted_rating.should eq 0.5 }
729
+ end
730
+ end
731
+
732
+ describe "#rate_and_save" do
733
+ before (:each) do
734
+ @comment1.rate_and_save 4, @bob, 2
735
+ @comment1.rate_and_save -2, @sally
736
+ @f_post = Post.where(:name => "Announcement").first
737
+ @f_comment = @f_post.comments.where(:content => "Hello!").first
738
+ end
739
+
740
+ describe "#rated?" do
741
+ it "should be #rated? by Bob" do
742
+ @f_comment.rated_by?(@bob).should be_true
743
+ end
744
+
745
+ it "should be #rated? by Sally" do
746
+ @f_comment.rated_by?(@sally).should be_true
747
+ end
748
+
749
+ it "should be not #rated? by Alice" do
750
+ @f_comment.rated_by?(@alice).should be_false
751
+ end
752
+ end
753
+
754
+ it "should have #rates equal 6" do
755
+ @f_comment.rates.should eql 6
756
+ end
757
+
758
+ it "should have #rate_count equal 2" do
759
+ @f_comment.rate_count.should eql 2
760
+ end
761
+
762
+ it "should have #rate_weight equal 3" do
763
+ @f_comment.rate_weight.should eql 3
764
+ end
765
+
766
+ it "should have #rating equal 2.0" do
767
+ @f_comment.rating.should eq 2.0
768
+ end
769
+
770
+ it "should have #previous_rating equal 4.0" do
771
+ @f_comment.previous_rating.should eq 4.0
772
+ end
773
+
774
+ it "should have #rating_delta equal -2.0" do
775
+ @f_comment.rating_delta.should eq -2.0
776
+ end
777
+
778
+ it "should have #unweighted_rating equal 1.0" do
779
+ @f_comment.unweighted_rating.should eq 1.0
780
+ end
781
+
782
+ describe "#unrate_and_save" do
783
+ before (:each) do
784
+ @comment1.unrate_and_save @bob
785
+ @f_post = Post.where(:name => "Announcement").first
786
+ @f_comment = @f_post.comments.where(:content => "Hello!").first
787
+ end
788
+
789
+ describe "#rated?" do
790
+ it "should be #rated? by Sally" do
791
+ @f_comment.rated_by?(@sally).should be_true
792
+ end
793
+
794
+ it "should be not #rated? by Bob" do
795
+ @f_comment.rated_by?(@bob).should be_false
796
+ end
797
+
798
+ it "should be #rated?" do
799
+ @f_comment.rated?.should be_true
800
+ end
801
+ end
802
+
803
+ it "should have #rates equal -2" do
804
+ @f_comment.rates.should eql -2
805
+ end
806
+
807
+ it "should have #rate_count equal 1" do
808
+ @f_comment.rate_count.should eql 1
809
+ end
810
+
811
+ it "should have #rate_weight equal 1" do
812
+ @f_comment.rate_weight.should eql 1
813
+ end
814
+
815
+ it "should have #rating equal -2.0" do
816
+ @f_comment.rating.should eq -2.0
817
+ end
818
+
819
+ it "should have #previous_rating equal 2.0" do
820
+ @f_comment.previous_rating.should eq 2.0
821
+ end
822
+
823
+ it "should have #rating_delta equal -4.0" do
824
+ @f_comment.rating_delta.should eq -4.0
825
+ end
826
+
827
+ it "should have #unweighted_rating equal -2.0" do
828
+ @f_comment.unweighted_rating.should eq -2.0
829
+ end
830
+ end
831
+ end
832
+
833
+ describe "#scopes" do
834
+ before (:each) do
835
+ @post1 = Post.create(:name => "Post 1")
836
+ @c1 = @post1.comments.create(:content => 'c1')
837
+ @c2 = @post1.comments.create(:content => 'c2')
838
+ @c3 = @post1.comments.create(:content => 'c3')
839
+ @c4 = @post1.comments.create(:content => 'c4')
840
+ @c5 = @post1.comments.create(:content => 'c5')
841
+ @c1.rate_and_save 5, @sally
842
+ @c1.rate_and_save 3, @bob
843
+ @c4.rate_and_save 1, @sally
844
+ end
845
+
846
+ describe "#unrated" do
847
+ it "should return proper count of unrated comments" do
848
+ @post1.comments.unrated.size.should eql 3
849
+ end
850
+ end
851
+
852
+ describe "#rated" do
853
+ it "should return proper count of rated comments" do
854
+ @post1.comments.rated.size.should eql 2
855
+ end
856
+ end
857
+
858
+ describe "#rated_by" do
859
+ it "should return proper count of comments rated by Bob" do
860
+ @post1.comments.rated_by(@bob).size.should eql 1
861
+ end
862
+
863
+ it "should return proper count of comments rated by Sally" do
864
+ @post1.comments.rated_by(@sally).size.should eql 2
865
+ end
866
+ end
867
+
868
+ describe "#with_rating" do
869
+ before (:each) do
870
+ @c1.rate_and_save 4, @alice
871
+ @c2.rate_and_save 2, @alice
872
+ @c3.rate_and_save 5, @alice
873
+ @c4.rate_and_save 2, @alice
874
+ end
875
+
876
+ it "should return proper count of comments with rating 4..5" do
877
+ @post1.comments.with_rating(4..5).size.should eql 2
878
+ end
879
+
880
+ it "should return proper count of comments with rating 0..2" do
881
+ @post1.comments.with_rating(0..2).size.should eql 2
882
+ end
883
+
884
+ it "should return proper count of comments with rating 0..5" do
885
+ @post1.comments.with_rating(0..5).size.should eql 4
886
+ end
887
+ end
888
+
889
+ describe "#highest_rated" do
890
+ it "should return proper count of comments" do
891
+ #mongoid has problems with returning count of documents (https://github.com/mongoid/mongoid/issues/817)
892
+ comments_count = 0
893
+ @post1.comments.highest_rated(1).each {|x| comments_count+=1 }
894
+ comments_count.should eql 1
895
+ end
896
+
897
+ it "should return proper count of comments" do
898
+ #mongoid has problems with returning count of documents (https://github.com/mongoid/mongoid/issues/817)
899
+ comments_count = 0
900
+ @post1.comments.highest_rated(10).each {|x| comments_count+=1 }
901
+ comments_count.should eql 5
902
+ end
903
+
904
+ #Don't work! (Mongoid can't sort embedded documents)
905
+ # it "should return proper document" do
906
+ # @post1.comments.highest_rated(1).first.content.should eql "c1"
907
+ # end
908
+ end
909
+ end
430
910
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_rateable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-11 00:00:00.000000000 Z
12
+ date: 2012-09-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mongoid
@@ -147,6 +147,7 @@ files:
147
147
  - lib/mongoid_rateable/version.rb
148
148
  - mongoid_rateable.gemspec
149
149
  - spec/models/article.rb
150
+ - spec/models/comment.rb
150
151
  - spec/models/post.rb
151
152
  - spec/models/user.rb
152
153
  - spec/rateable_spec.rb
@@ -166,7 +167,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
166
167
  version: '0'
167
168
  segments:
168
169
  - 0
169
- hash: -443413809
170
+ hash: -684544659
170
171
  required_rubygems_version: !ruby/object:Gem::Requirement
171
172
  none: false
172
173
  requirements: