recommendable 1.1.7 → 2.0.0

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 (118) hide show
  1. data/lib/recommendable.rb +38 -26
  2. data/lib/recommendable/configuration.rb +47 -0
  3. data/lib/recommendable/helpers.rb +3 -9
  4. data/lib/recommendable/helpers/calculations.rb +150 -0
  5. data/lib/recommendable/helpers/queriers.rb +23 -0
  6. data/lib/recommendable/helpers/redis_key_mapper.rb +29 -0
  7. data/lib/recommendable/orm/active_record.rb +6 -0
  8. data/lib/recommendable/orm/data_mapper.rb +7 -0
  9. data/lib/recommendable/orm/mongo_mapper.rb +8 -0
  10. data/lib/recommendable/orm/mongoid.rb +7 -0
  11. data/lib/recommendable/ratable.rb +83 -0
  12. data/lib/recommendable/ratable/dislikable.rb +26 -0
  13. data/lib/recommendable/ratable/likable.rb +26 -0
  14. data/lib/recommendable/rater.rb +109 -0
  15. data/lib/recommendable/rater/bookmarker.rb +120 -0
  16. data/lib/recommendable/rater/disliker.rb +122 -0
  17. data/lib/recommendable/rater/hider.rb +120 -0
  18. data/lib/recommendable/rater/liker.rb +122 -0
  19. data/lib/recommendable/rater/recommender.rb +68 -0
  20. data/lib/recommendable/version.rb +5 -4
  21. data/lib/recommendable/workers/delayed_job.rb +16 -0
  22. data/lib/recommendable/workers/rails.rb +16 -0
  23. data/lib/recommendable/workers/resque.rb +13 -0
  24. data/lib/recommendable/workers/sidekiq.rb +13 -0
  25. metadata +62 -131
  26. data/.gitignore +0 -57
  27. data/.travis.yml +0 -3
  28. data/CHANGELOG.markdown +0 -159
  29. data/Gemfile +0 -3
  30. data/Gemfile.lock +0 -112
  31. data/LICENSE.txt +0 -22
  32. data/README.markdown +0 -135
  33. data/Rakefile +0 -26
  34. data/TODO +0 -7
  35. data/app/models/recommendable/dislike.rb +0 -19
  36. data/app/models/recommendable/ignore.rb +0 -19
  37. data/app/models/recommendable/like.rb +0 -19
  38. data/app/models/recommendable/stash.rb +0 -19
  39. data/app/workers/recommendable/delayed_job_worker.rb +0 -17
  40. data/app/workers/recommendable/rails_worker.rb +0 -17
  41. data/app/workers/recommendable/resque_worker.rb +0 -14
  42. data/app/workers/recommendable/sidekiq_worker.rb +0 -14
  43. data/config/routes.rb +0 -3
  44. data/db/migrate/20120124193723_create_likes.rb +0 -17
  45. data/db/migrate/20120124193728_create_dislikes.rb +0 -17
  46. data/db/migrate/20120127092558_create_ignores.rb +0 -17
  47. data/db/migrate/20120131173909_create_stashes.rb +0 -17
  48. data/lib/generators/recommendable/USAGE +0 -8
  49. data/lib/generators/recommendable/install_generator.rb +0 -40
  50. data/lib/generators/recommendable/templates/initializer.rb +0 -28
  51. data/lib/recommendable/acts_as_recommendable.rb +0 -176
  52. data/lib/recommendable/acts_as_recommended_to.rb +0 -774
  53. data/lib/recommendable/engine.rb +0 -14
  54. data/lib/recommendable/exceptions.rb +0 -4
  55. data/lib/recommendable/railtie.rb +0 -6
  56. data/lib/sidekiq/middleware/client/unique_jobs.rb +0 -37
  57. data/lib/sidekiq/middleware/server/unique_jobs.rb +0 -17
  58. data/lib/tasks/recommendable_tasks.rake +0 -1
  59. data/recommendable.gemspec +0 -30
  60. data/script/rails +0 -8
  61. data/spec/configuration_spec.rb +0 -9
  62. data/spec/dummy/README.rdoc +0 -261
  63. data/spec/dummy/Rakefile +0 -7
  64. data/spec/dummy/app/assets/javascripts/application.js +0 -15
  65. data/spec/dummy/app/assets/stylesheets/application.css +0 -13
  66. data/spec/dummy/app/controllers/application_controller.rb +0 -3
  67. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  68. data/spec/dummy/app/mailers/.gitkeep +0 -0
  69. data/spec/dummy/app/models/.gitkeep +0 -0
  70. data/spec/dummy/app/models/bully.rb +0 -2
  71. data/spec/dummy/app/models/movie.rb +0 -2
  72. data/spec/dummy/app/models/php_framework.rb +0 -2
  73. data/spec/dummy/app/models/user.rb +0 -3
  74. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  75. data/spec/dummy/config.ru +0 -4
  76. data/spec/dummy/config/application.rb +0 -56
  77. data/spec/dummy/config/boot.rb +0 -10
  78. data/spec/dummy/config/database.yml +0 -25
  79. data/spec/dummy/config/environment.rb +0 -5
  80. data/spec/dummy/config/environments/development.rb +0 -37
  81. data/spec/dummy/config/environments/production.rb +0 -67
  82. data/spec/dummy/config/environments/test.rb +0 -37
  83. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  84. data/spec/dummy/config/initializers/inflections.rb +0 -15
  85. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  86. data/spec/dummy/config/initializers/recommendable.rb +0 -14
  87. data/spec/dummy/config/initializers/secret_token.rb +0 -7
  88. data/spec/dummy/config/initializers/session_store.rb +0 -8
  89. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  90. data/spec/dummy/config/locales/en.yml +0 -5
  91. data/spec/dummy/config/routes.rb +0 -4
  92. data/spec/dummy/db/migrate/20120128005553_create_likes.recommendable.rb +0 -18
  93. data/spec/dummy/db/migrate/20120128005554_create_dislikes.recommendable.rb +0 -18
  94. data/spec/dummy/db/migrate/20120128005555_create_ignores.recommendable.rb +0 -18
  95. data/spec/dummy/db/migrate/20120128020228_create_users.rb +0 -9
  96. data/spec/dummy/db/migrate/20120128020413_create_movies.rb +0 -10
  97. data/spec/dummy/db/migrate/20120128024632_create_php_frameworks.rb +0 -9
  98. data/spec/dummy/db/migrate/20120128024804_create_bullies.rb +0 -9
  99. data/spec/dummy/db/migrate/20120131195416_create_stashes.recommendable.rb +0 -19
  100. data/spec/dummy/db/schema.rb +0 -89
  101. data/spec/dummy/lib/assets/.gitkeep +0 -0
  102. data/spec/dummy/log/.gitkeep +0 -0
  103. data/spec/dummy/public/404.html +0 -26
  104. data/spec/dummy/public/422.html +0 -26
  105. data/spec/dummy/public/500.html +0 -25
  106. data/spec/dummy/public/favicon.ico +0 -0
  107. data/spec/dummy/recommendable_dummy_development +0 -0
  108. data/spec/dummy/recommendable_dummy_test +0 -0
  109. data/spec/dummy/script/rails +0 -6
  110. data/spec/factories.rb +0 -16
  111. data/spec/models/dislike_spec.rb +0 -41
  112. data/spec/models/ignore_spec.rb +0 -27
  113. data/spec/models/like_spec.rb +0 -42
  114. data/spec/models/movie_spec.rb +0 -82
  115. data/spec/models/stash_spec.rb +0 -27
  116. data/spec/models/user_benchmark_spec.rb +0 -49
  117. data/spec/models/user_spec.rb +0 -443
  118. data/spec/spec_helper.rb +0 -28
@@ -1,27 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class StashSpec < MiniTest::Spec
4
- describe Recommendable::Stash do
5
- before :each do
6
- @user = User.create(:username => "dave")
7
- end
8
-
9
- it "should not be created for an object that does not act_as_recommendedable" do
10
- web2py = PhpFramework.create(:name => "web2py")
11
- proc { @user.stash(web2py) }.must_raise Recommendable::UnrecommendableError
12
- end
13
-
14
- it "should be created for an object that does act_as_recommendable" do
15
- movie = Movie.create(:title => "Star Wars: Episode I - The Phantom Menace", :year => 1999)
16
- @user.stash(movie).must_equal true
17
- end
18
-
19
- it "should not be created twice for the same user-object pair" do
20
- movie = Movie.create(:title => "Star Wars: Episode I - The Phantom Menace", :year => 1999)
21
-
22
- @user.stash(movie).must_equal true
23
- @user.stash(movie).must_be_nil
24
- Recommendable::Stash.count.must_equal 1
25
- end
26
- end
27
- end
@@ -1,49 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class UserBenchmarkSpec < MiniTest::Unit::TestCase
4
- def test_update_recommendations
5
- if ENV["BENCH"] then
6
- Recommendable.redis.flushdb
7
- @actions = [:like, :dislike]
8
-
9
- puts "\n"
10
-
11
- assert_performance_exponential do |n|
12
- @user = Factory(:user)
13
- @users = []
14
- @movies = []
15
-
16
- # Make n users, 5n movies
17
- n.times do
18
- @users << Factory(:user)
19
- @movies << Factory(:movie)
20
- @movies << Factory(:movie)
21
- @movies << Factory(:movie)
22
- @movies << Factory(:movie)
23
- @movies << Factory(:movie)
24
- end
25
-
26
- # Main user randomly likes/dislikes 1/4 of the movies
27
- @movies.sample(n/4).each do |m|
28
- @user.send(@actions.sample, m)
29
- end
30
-
31
- # Other users randomly like/dislike some movies
32
- @movies.sample(n/2).each do |m|
33
- @users.sample.send(@actions.sample, m)
34
- @users.sample.send(@actions.sample, m)
35
- @users.sample.send(@actions.sample, m)
36
- end
37
-
38
- @user.send :update_similarities
39
- @user.send :update_recommendations
40
- Recommendable.redis.flushdb
41
-
42
- User.delete_all
43
- Movie.delete_all
44
- Recommendable::Like.delete_all
45
- Recommendable::Dislike.delete_all
46
- end
47
- end
48
- end
49
- end
@@ -1,443 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class UserSpec < MiniTest::Spec
4
- # User and Bully are skeleton classes defined in the dummy application for
5
- # the sole purpose of running these tests. They're in spec/dummy/models/ but
6
- # really, there's nothing there of note.
7
-
8
- describe User do
9
- describe "before_destroy filters" do
10
- before :each do
11
- Recommendable.redis.flushdb
12
- @user1 = Factory(:user)
13
- @user2 = Factory(:user)
14
- @movie1 = Factory(:movie)
15
- @movie2 = Factory(:movie)
16
- end
17
-
18
- it "should no longer be involved in similarities or predictions" do
19
- @user1.like @movie1
20
- @user1.like @movie2
21
- @user2.like @movie1
22
-
23
- @user1.send :update_similarities
24
- @user2.send :update_similarities
25
- @user2.send :update_recommendations
26
-
27
- similarity_set = @user2.send :similarity_set
28
- predictions_set = @user2.send :predictions_set_for, Movie
29
- @user2.destroy
30
-
31
- @user1.similar_raters.wont_include @user2
32
- Recommendable.redis.get(similarity_set).must_be_nil
33
- Recommendable.redis.get(predictions_set).must_be_nil
34
- end
35
- end
36
-
37
- describe "that does not act_as_recommended_to" do
38
- before :each do
39
- @user = Factory(:bully)
40
- @movie = Factory(:movie)
41
- end
42
-
43
- it "should not be able to rate, ignore, or stash an item, and trying should not be enough to get Redis keys" do
44
- proc { @user.like(@movie) }.must_raise NoMethodError
45
- proc { @user.dislike(@movie) }.must_raise NoMethodError
46
- proc { @user.ignore(@movie) }.must_raise NoMethodError
47
- proc { @user.stash(@movie) }.must_raise NoMethodError
48
-
49
- @movie.liked_by.must_be_empty
50
- @movie.disliked_by.must_be_empty
51
-
52
- proc { @user.create_recommended_to_sets }.must_raise NoMethodError
53
-
54
- proc { @user.likes_set_for(Movie) }.must_raise NoMethodError
55
- proc { @user.dislikes_set_for(Movie) }.must_raise NoMethodError
56
-
57
- Recommendable.redis.smembers("Bully:#{@user.id}:likes:Movie").must_be_empty
58
- Recommendable.redis.smembers("Bully:#{@user.id}:dislikes:Movie").must_be_empty
59
- Recommendable.redis.smembers("Bully:#{@user.id}:similarities").must_be_empty
60
- Recommendable.redis.smembers("Bully:#{@user.id}:predictions:Movie").must_be_empty
61
- end
62
- end
63
-
64
- describe "that does act_as_recommendable" do
65
- before :each do
66
- @user = Factory(:user)
67
- @movie = Factory(:movie)
68
- end
69
-
70
- after :each do
71
- Recommendable.redis.flushdb
72
- end
73
-
74
- it "should be able to like a recommendable item" do
75
- @user.like(@movie).must_equal true
76
- @user.send(:create_recommended_to_sets)
77
- Recommendable.redis.smembers("User:#{@user.id}:likes:Movie").must_include @movie.id.to_s
78
- @user.send(:destroy_recommended_to_sets)
79
- end
80
-
81
- it "should not dislike an item after liking it" do
82
- @user.dislike(@movie)
83
- @user.like(@movie).must_equal true
84
- @user.dislikes?(@movie).must_equal false
85
- @user.likes?(@movie).must_equal true
86
-
87
- @user.send(:create_recommended_to_sets)
88
- Recommendable.redis.smembers("User:#{@user.id}:dislikes:Movie").wont_include @movie.id.to_s
89
- @user.send(:destroy_recommended_to_sets)
90
- end
91
-
92
- it "should not be ignoring an item after liking it" do
93
- @user.ignore(@movie)
94
- @user.like(@movie).must_equal true
95
- @user.ignored?(@movie).must_equal false
96
- @user.likes?(@movie).must_equal true
97
- end
98
-
99
- it "should not have an item stashed after liking it" do
100
- @user.stash(@movie)
101
- @user.like(@movie).must_equal true
102
- @user.stashed?(@movie).must_equal false
103
- @user.likes?(@movie).must_equal true
104
- end
105
-
106
- it "should be able to dislike a recommendable item" do
107
- @user.dislike(@movie).must_equal true
108
- @user.send(:create_recommended_to_sets)
109
- Recommendable.redis.smembers("User:#{@user.id}:dislikes:Movie").must_include @movie.id.to_s
110
- @user.send(:destroy_recommended_to_sets)
111
- end
112
-
113
- it "should not like an item after disliking it" do
114
- @user.like(@movie)
115
- @user.dislike(@movie).must_equal true
116
- @user.likes?(@movie).must_equal false
117
- @user.dislikes?(@movie).must_equal true
118
-
119
- @user.send(:create_recommended_to_sets)
120
- Recommendable.redis.smembers("User:#{@user.id}:dislikes:Movie").must_include @movie.id.to_s
121
- Recommendable.redis.smembers("User:#{@user.id}:likes:Movie").wont_include @movie.id.to_s
122
- @user.send(:destroy_recommended_to_sets)
123
- end
124
-
125
- it "should not be ignoring an item after disliking it" do
126
- @user.ignore(@movie)
127
- @user.dislike(@movie).must_equal true
128
- @user.ignored?(@movie).must_equal false
129
- @user.dislikes?(@movie).must_equal true
130
- end
131
-
132
- it "should not have an item stashed after disliking it" do
133
- @user.stash(@movie)
134
- @user.dislike(@movie).must_equal true
135
- @user.stashed?(@movie).must_equal false
136
- @user.dislikes?(@movie).must_equal true
137
- end
138
-
139
- it "should be able to ignore a recommendable item" do
140
- @user.ignore(@movie).must_equal true
141
- end
142
-
143
- it "should not like an item after ignoring it" do
144
- @user.like(@movie)
145
- @user.ignore(@movie).must_equal true
146
- @user.likes?(@movie).must_equal false
147
- @user.ignored?(@movie).must_equal true
148
- end
149
-
150
- it "should not dislike an item after ignoring it" do
151
- @user.dislike(@movie)
152
- @user.ignore(@movie).must_equal true
153
- @user.dislikes?(@movie).must_equal false
154
- @user.ignored?(@movie).must_equal true
155
- end
156
-
157
- it "should not have an item stashed after ignoring it" do
158
- @user.stash(@movie)
159
- @user.ignore(@movie).must_equal true
160
- @user.stashed?(@movie).must_equal false
161
- @user.ignored?(@movie).must_equal true
162
- end
163
-
164
- it "should be able to stash a recommendable item" do
165
- @user.stash(@movie).must_equal true
166
- end
167
-
168
- it "should not stash a liked item" do
169
- @user.like(@movie)
170
- @user.stash(@movie).must_be_nil
171
- @user.likes?(@movie).must_equal true
172
- @user.stashed?(@movie).must_equal false
173
- end
174
-
175
- it "should not stash a disliked item" do
176
- @user.dislike(@movie)
177
- @user.stash(@movie).must_be_nil
178
- @user.dislikes?(@movie).must_equal true
179
- @user.stashed?(@movie).must_equal false
180
- end
181
-
182
- it "should not have an item ignored after stashing it" do
183
- @user.ignore(@movie)
184
- @user.stash(@movie).must_equal true
185
- @user.ignored?(@movie).must_equal false
186
- @user.stashed?(@movie).must_equal true
187
- end
188
-
189
- it "should not be able to rate or ignore an item that is not recommendable." do
190
- @cakephp = Factory(:php_framework)
191
-
192
- proc { @user.like(@cakephp) }.must_raise Recommendable::UnrecommendableError
193
- proc { @user.dislike(@cakephp) }.must_raise Recommendable::UnrecommendableError
194
- proc { @user.ignore(@cakephp) }.must_raise Recommendable::UnrecommendableError
195
- proc { @user.stash(@cakephp) }.must_raise Recommendable::UnrecommendableError
196
-
197
- proc { @cakephp.liked_by }.must_raise NoMethodError
198
- proc { @cakephp.disliked_by }.must_raise NoMethodError
199
-
200
- @user.send(:create_recommended_to_sets)
201
-
202
- Recommendable.redis.smembers("User:#{@user.id}:likes:PhpFramework").must_be_empty
203
- Recommendable.redis.smembers("User:#{@user.id}:dislikes:PhpFramework").must_be_empty
204
- Recommendable.redis.smembers("User:#{@user.id}:similarities").must_be_empty
205
- Recommendable.redis.smembers("User:#{@user.id}:predictions:Movie").must_be_empty
206
-
207
- @user.send(:destroy_recommended_to_sets)
208
- end
209
-
210
- it "should not freak out when re-rating, re-ignoring, or re-stashing items" do
211
- @user.like(@movie)
212
- @user.like(@movie).must_be_nil
213
-
214
- @user.dislike(@movie)
215
- @user.dislike(@movie).must_be_nil
216
-
217
- @user.ignore(@movie)
218
- @user.ignore(@movie).must_be_nil
219
-
220
- @user.stash(@movie)
221
- @user.stash(@movie).must_be_nil
222
- end
223
-
224
- it "should be able to unrate, unignore or unstash items" do
225
- @user.like(@movie)
226
- @user.unlike(@movie).must_equal true
227
-
228
- @user.dislike(@movie)
229
- @user.undislike(@movie).must_equal true
230
-
231
- @user.ignore(@movie)
232
- @user.unignore(@movie).must_equal true
233
-
234
- @user.stash(@movie)
235
- @user.unstash(@movie).must_equal true
236
- end
237
- end
238
-
239
- describe "while using finders" do
240
- it "should return ActiveRecord::Relations" do
241
- @user = Factory(:user)
242
- @movie1 = Factory(:movie)
243
- @movie2 = Factory(:movie)
244
- @movie3 = Factory(:movie)
245
- @movie4 = Factory(:movie)
246
- @movie5 = Factory(:movie)
247
-
248
- @user.like @movie1
249
- @user.like @movie2
250
- @user.dislike @movie3
251
-
252
- @user.liked_movies.must_be_instance_of ActiveRecord::Relation
253
- @user.liked_movies.where(:title => @movie1.title).must_include @movie1
254
- @user.liked_movies.where(:title => @movie2.title).wont_include @movie1
255
- @user.liked_movies.limit(1).size.must_equal 1
256
- @user.disliked_movies.where(:title => @movie5.title).must_be_empty
257
- end
258
- end
259
-
260
- describe "while getting recommendations" do
261
- before :each do
262
- @dave = Factory(:user)
263
- @frank = Factory(:user)
264
- @hal = Factory(:user)
265
- @movie1 = Factory(:movie)
266
- @movie2 = Factory(:movie)
267
- @movie3 = Factory(:movie)
268
- @movie4 = Factory(:movie)
269
- @movie5 = Factory(:movie)
270
- end
271
-
272
- after :each do
273
- Recommendable.redis.del "User:#{@dave.id}:similarities"
274
- Recommendable.redis.del "User:#{@dave.id}:predictions:Movie"
275
- Recommendable.redis.del "User:#{@frank.id}:similarities"
276
- Recommendable.redis.del "User:#{@frank.id}:predictions:Movie"
277
- end
278
-
279
- it "should respect passed counts" do
280
- @dave.like @movie1
281
- @frank.like @movie1
282
- @frank.like @movie2
283
- @frank.like @movie3
284
- @frank.like @movie4
285
- @frank.like @movie5
286
-
287
- @dave.send :update_similarities and @dave.send :update_recommendations
288
-
289
- @dave.recommendations.size.must_equal 4
290
- @dave.recommendations(2).size.must_equal 2
291
- end
292
-
293
- it "should return an ActiveRecord::Relation when using the dynamic finder" do
294
- @dave.like @movie1
295
- @frank.like @movie1
296
- @frank.like @movie2
297
- @frank.like @movie3
298
- @frank.like @movie4
299
- @frank.like @movie5
300
-
301
- @dave.send :update_similarities and @dave.send :update_recommendations
302
-
303
- @dave.recommended_movies.limit(2).size.must_equal 2
304
- @dave.recommended_movies.where(:title => @movie3.title).must_include @movie3
305
- @dave.recommended_movies.where(:title => @movie3.title).wont_include @movie2
306
- @dave.recommended_movies.where(:title => @movie3.title).wont_include @movie4
307
- @dave.recommended_movies.where(:title => @movie3.title).wont_include @movie5
308
- end
309
-
310
- it "should have common likes with a friend" do
311
- @dave.like @movie1
312
- @dave.like @movie2
313
- @dave.like @movie4
314
-
315
- @frank.like @movie2
316
- @frank.like @movie3
317
- @frank.like @movie4
318
-
319
- @dave.liked_movies_in_common_with(@frank).must_include @movie2
320
- @dave.liked_movies_in_common_with(@frank).must_include @movie4
321
- @dave.liked_movies_in_common_with(@frank).wont_include @movie1
322
- @dave.liked_movies_in_common_with(@frank).wont_include @movie3
323
- end
324
-
325
- it "should have common dislikes with a friend" do
326
- @dave.dislike @movie1
327
- @dave.dislike @movie3
328
- @dave.like @movie4
329
-
330
- @frank.dislike @movie2
331
- @frank.dislike @movie3
332
- @frank.dislike @movie4
333
-
334
- @dave.disliked_movies_in_common_with(@frank).wont_include @movie2
335
- @dave.disliked_movies_in_common_with(@frank).wont_include @movie4
336
- @dave.disliked_movies_in_common_with(@frank).wont_include @movie1
337
- @dave.disliked_movies_in_common_with(@frank).must_include @movie3
338
- end
339
-
340
- it "should get populated sorted sets for similarities and recommendations" do
341
- @dave.like(@movie1)
342
- @frank.like(@movie1)
343
- @frank.like(@movie2)
344
- @dave.send :update_similarities
345
- @dave.send :update_recommendations
346
-
347
- @dave.similar_raters.must_include @frank
348
- @dave.recommended_movies.must_include @movie2
349
- end
350
-
351
- it "should return only the number of specified recommendations" do
352
- @dave.like(@movie1)
353
- @frank.like(@movie1)
354
- @frank.like(@movie2)
355
- @frank.like(@movie3)
356
- @frank.like(@movie4)
357
- @dave.send :update_similarities
358
- @dave.send :update_recommendations
359
-
360
- @dave.recommendations(2).size.must_equal 2
361
- @dave.recommended_movies(1).size.must_equal 1
362
- end
363
-
364
- it "should order similar users by similarity" do
365
- @dave.like(@movie1)
366
- @dave.like(@movie2)
367
- @frank.like(@movie1)
368
- @frank.dislike(@movie2)
369
- @hal.like(@movie1)
370
- @hal.like(@movie2)
371
-
372
- # hal should be more similar to dave than frank
373
- @dave.send :update_similarities
374
- @dave.send :update_recommendations
375
-
376
- @dave.similar_raters.must_equal [@hal, @frank]
377
- end
378
-
379
- it "should correctly recommend an awesome movie or two. In the correct order, of course." do
380
- @dave.like(@movie1)
381
- @dave.like(@movie2)
382
- @frank.like(@movie1)
383
- @frank.like(@movie2)
384
- @frank.like(@movie4)
385
- @hal.like(@movie1)
386
- @hal.like(@movie3)
387
-
388
- @dave.send :update_similarities
389
- @dave.send :update_recommendations
390
-
391
- @dave.recommendations.must_equal [@movie4, @movie3]
392
- end
393
-
394
- it "should not recommend rated items" do
395
- @dave.like(@movie1)
396
- @dave.dislike(@movie2)
397
- @frank.like(@movie1)
398
- @frank.like(@movie2)
399
- @frank.like(@movie4)
400
- @hal.like(@movie1)
401
- @hal.like(@movie3)
402
-
403
- @dave.send :update_similarities
404
- @dave.send :update_recommendations
405
-
406
- @dave.recommendations.wont_include @movie1
407
- @dave.recommendations.wont_include @movie2
408
- end
409
-
410
- it "should not recommend ignored items" do
411
- @dave.like(@movie1)
412
- @dave.like(@movie2)
413
- @dave.ignore(@movie4)
414
- @frank.like(@movie1)
415
- @frank.like(@movie2)
416
- @frank.like(@movie4)
417
- @hal.like(@movie1)
418
- @hal.like(@movie3)
419
-
420
- @dave.send :update_similarities
421
- @dave.send :update_recommendations
422
-
423
- @dave.recommendations.wont_include @movie4
424
- end
425
-
426
- it "should not recommend stashed items" do
427
- @dave.like(@movie1)
428
- @dave.like(@movie2)
429
- @dave.stash(@movie4)
430
- @frank.like(@movie1)
431
- @frank.like(@movie2)
432
- @frank.like(@movie4)
433
- @hal.like(@movie1)
434
- @hal.like(@movie3)
435
-
436
- @dave.send :update_similarities
437
- @dave.send :update_recommendations
438
-
439
- @dave.recommendations.wont_include @movie4
440
- end
441
- end
442
- end
443
- end