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.
- data/lib/recommendable.rb +38 -26
- data/lib/recommendable/configuration.rb +47 -0
- data/lib/recommendable/helpers.rb +3 -9
- data/lib/recommendable/helpers/calculations.rb +150 -0
- data/lib/recommendable/helpers/queriers.rb +23 -0
- data/lib/recommendable/helpers/redis_key_mapper.rb +29 -0
- data/lib/recommendable/orm/active_record.rb +6 -0
- data/lib/recommendable/orm/data_mapper.rb +7 -0
- data/lib/recommendable/orm/mongo_mapper.rb +8 -0
- data/lib/recommendable/orm/mongoid.rb +7 -0
- data/lib/recommendable/ratable.rb +83 -0
- data/lib/recommendable/ratable/dislikable.rb +26 -0
- data/lib/recommendable/ratable/likable.rb +26 -0
- data/lib/recommendable/rater.rb +109 -0
- data/lib/recommendable/rater/bookmarker.rb +120 -0
- data/lib/recommendable/rater/disliker.rb +122 -0
- data/lib/recommendable/rater/hider.rb +120 -0
- data/lib/recommendable/rater/liker.rb +122 -0
- data/lib/recommendable/rater/recommender.rb +68 -0
- data/lib/recommendable/version.rb +5 -4
- data/lib/recommendable/workers/delayed_job.rb +16 -0
- data/lib/recommendable/workers/rails.rb +16 -0
- data/lib/recommendable/workers/resque.rb +13 -0
- data/lib/recommendable/workers/sidekiq.rb +13 -0
- metadata +62 -131
- data/.gitignore +0 -57
- data/.travis.yml +0 -3
- data/CHANGELOG.markdown +0 -159
- data/Gemfile +0 -3
- data/Gemfile.lock +0 -112
- data/LICENSE.txt +0 -22
- data/README.markdown +0 -135
- data/Rakefile +0 -26
- data/TODO +0 -7
- data/app/models/recommendable/dislike.rb +0 -19
- data/app/models/recommendable/ignore.rb +0 -19
- data/app/models/recommendable/like.rb +0 -19
- data/app/models/recommendable/stash.rb +0 -19
- data/app/workers/recommendable/delayed_job_worker.rb +0 -17
- data/app/workers/recommendable/rails_worker.rb +0 -17
- data/app/workers/recommendable/resque_worker.rb +0 -14
- data/app/workers/recommendable/sidekiq_worker.rb +0 -14
- data/config/routes.rb +0 -3
- data/db/migrate/20120124193723_create_likes.rb +0 -17
- data/db/migrate/20120124193728_create_dislikes.rb +0 -17
- data/db/migrate/20120127092558_create_ignores.rb +0 -17
- data/db/migrate/20120131173909_create_stashes.rb +0 -17
- data/lib/generators/recommendable/USAGE +0 -8
- data/lib/generators/recommendable/install_generator.rb +0 -40
- data/lib/generators/recommendable/templates/initializer.rb +0 -28
- data/lib/recommendable/acts_as_recommendable.rb +0 -176
- data/lib/recommendable/acts_as_recommended_to.rb +0 -774
- data/lib/recommendable/engine.rb +0 -14
- data/lib/recommendable/exceptions.rb +0 -4
- data/lib/recommendable/railtie.rb +0 -6
- data/lib/sidekiq/middleware/client/unique_jobs.rb +0 -37
- data/lib/sidekiq/middleware/server/unique_jobs.rb +0 -17
- data/lib/tasks/recommendable_tasks.rake +0 -1
- data/recommendable.gemspec +0 -30
- data/script/rails +0 -8
- data/spec/configuration_spec.rb +0 -9
- data/spec/dummy/README.rdoc +0 -261
- data/spec/dummy/Rakefile +0 -7
- data/spec/dummy/app/assets/javascripts/application.js +0 -15
- data/spec/dummy/app/assets/stylesheets/application.css +0 -13
- data/spec/dummy/app/controllers/application_controller.rb +0 -3
- data/spec/dummy/app/helpers/application_helper.rb +0 -2
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/bully.rb +0 -2
- data/spec/dummy/app/models/movie.rb +0 -2
- data/spec/dummy/app/models/php_framework.rb +0 -2
- data/spec/dummy/app/models/user.rb +0 -3
- data/spec/dummy/app/views/layouts/application.html.erb +0 -14
- data/spec/dummy/config.ru +0 -4
- data/spec/dummy/config/application.rb +0 -56
- data/spec/dummy/config/boot.rb +0 -10
- data/spec/dummy/config/database.yml +0 -25
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -37
- data/spec/dummy/config/environments/production.rb +0 -67
- data/spec/dummy/config/environments/test.rb +0 -37
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummy/config/initializers/inflections.rb +0 -15
- data/spec/dummy/config/initializers/mime_types.rb +0 -5
- data/spec/dummy/config/initializers/recommendable.rb +0 -14
- data/spec/dummy/config/initializers/secret_token.rb +0 -7
- data/spec/dummy/config/initializers/session_store.rb +0 -8
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/spec/dummy/config/locales/en.yml +0 -5
- data/spec/dummy/config/routes.rb +0 -4
- data/spec/dummy/db/migrate/20120128005553_create_likes.recommendable.rb +0 -18
- data/spec/dummy/db/migrate/20120128005554_create_dislikes.recommendable.rb +0 -18
- data/spec/dummy/db/migrate/20120128005555_create_ignores.recommendable.rb +0 -18
- data/spec/dummy/db/migrate/20120128020228_create_users.rb +0 -9
- data/spec/dummy/db/migrate/20120128020413_create_movies.rb +0 -10
- data/spec/dummy/db/migrate/20120128024632_create_php_frameworks.rb +0 -9
- data/spec/dummy/db/migrate/20120128024804_create_bullies.rb +0 -9
- data/spec/dummy/db/migrate/20120131195416_create_stashes.recommendable.rb +0 -19
- data/spec/dummy/db/schema.rb +0 -89
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +0 -26
- data/spec/dummy/public/422.html +0 -26
- data/spec/dummy/public/500.html +0 -25
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/recommendable_dummy_development +0 -0
- data/spec/dummy/recommendable_dummy_test +0 -0
- data/spec/dummy/script/rails +0 -6
- data/spec/factories.rb +0 -16
- data/spec/models/dislike_spec.rb +0 -41
- data/spec/models/ignore_spec.rb +0 -27
- data/spec/models/like_spec.rb +0 -42
- data/spec/models/movie_spec.rb +0 -82
- data/spec/models/stash_spec.rb +0 -27
- data/spec/models/user_benchmark_spec.rb +0 -49
- data/spec/models/user_spec.rb +0 -443
- data/spec/spec_helper.rb +0 -28
data/spec/models/stash_spec.rb
DELETED
|
@@ -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
|
data/spec/models/user_spec.rb
DELETED
|
@@ -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
|