seymour 0.0.7 → 0.0.8
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/.gitignore +2 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +13 -15
- data/Gemfile.ci +4 -0
- data/README.md +3 -0
- data/lib/seymour.rb +2 -0
- data/lib/seymour/acts_as_activity.rb +0 -2
- data/lib/seymour/feed.rb +20 -56
- data/lib/seymour/railtie.rb +20 -0
- data/lib/seymour/redis.rb +11 -6
- data/lib/seymour/store.rb +7 -0
- data/lib/seymour/store/base.rb +35 -0
- data/lib/seymour/store/list.rb +104 -0
- data/lib/seymour/store/zset.rb +75 -0
- data/lib/{tasks/seymour_tasks.rake → seymour/tasks/seymour_tasks.rb} +0 -0
- data/lib/seymour/version.rb +1 -1
- data/seymour.gemspec +6 -8
- data/spec/dummy/db/schema.rb +3 -2
- data/spec/seymour/distributable_spec.rb +13 -6
- data/spec/seymour/feed_spec.rb +266 -76
- metadata +87 -159
- data/Gemfile.lock +0 -195
File without changes
|
data/lib/seymour/version.rb
CHANGED
data/seymour.gemspec
CHANGED
@@ -21,14 +21,12 @@ Gem::Specification.new do |s|
|
|
21
21
|
# s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
22
|
|
23
23
|
s.add_dependency "rails", "~> 3.0"
|
24
|
-
s.add_dependency "redis-namespace"
|
24
|
+
# s.add_dependency "redis-namespace"
|
25
25
|
|
26
|
-
s.add_development_dependency "rspec"
|
27
|
-
s.add_development_dependency
|
28
|
-
s.add_development_dependency '
|
29
|
-
s.add_development_dependency '
|
30
|
-
s.add_development_dependency '
|
31
|
-
s.add_development_dependency 'database_cleaner'
|
32
|
-
s.add_development_dependency 'factory_girl_rails'
|
26
|
+
s.add_development_dependency "rspec-rails", '~> 2.8.0'
|
27
|
+
s.add_development_dependency 'capybara', '~> 1.1.0'
|
28
|
+
s.add_development_dependency 'ammeter', '~> 0.2.0'
|
29
|
+
s.add_development_dependency 'database_cleaner', '~> 0.7.1'
|
30
|
+
s.add_development_dependency 'factory_girl_rails', '~> 1.2.0'
|
33
31
|
s.add_development_dependency "sqlite3"
|
34
32
|
end
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
# This file is auto-generated from the current state of the database. Instead
|
2
3
|
# of editing this file, please use the migrations feature of Active Record to
|
3
4
|
# incrementally modify your database, and then regenerate this schema definition.
|
@@ -13,8 +14,8 @@
|
|
13
14
|
ActiveRecord::Schema.define(:version => 20111015001158) do
|
14
15
|
|
15
16
|
create_table "activities", :force => true do |t|
|
16
|
-
t.integer "
|
17
|
-
t.string "
|
17
|
+
t.integer "auditable_id"
|
18
|
+
t.string "auditable_type"
|
18
19
|
t.integer "actor_id"
|
19
20
|
t.datetime "created_at"
|
20
21
|
t.datetime "updated_at"
|
@@ -61,12 +61,19 @@ describe Seymour::Distributable do
|
|
61
61
|
DistributableActivity.feeds_for(activity).size.should == 2
|
62
62
|
end
|
63
63
|
|
64
|
-
it "should
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
64
|
+
it "should return all assigned feed types" do
|
65
|
+
feed_classes = DistributableActivity.feeds_for(activity).map(&:class)
|
66
|
+
feed_classes.should include(UserFeed)
|
67
|
+
feed_classes.should include(AdminFeed)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should assign owners to correct feed type" do
|
71
|
+
feeds = DistributableActivity.feeds_for(activity)
|
72
|
+
user_feed = feeds.detect { |feed| feed.is_a?(UserFeed) }
|
73
|
+
admin_feed = feeds.detect { |feed| feed.is_a?(AdminFeed) }
|
74
|
+
|
75
|
+
user_feed.owner.should == @user
|
76
|
+
admin_feed.owner.should == @admin
|
70
77
|
end
|
71
78
|
|
72
79
|
it "should use default batch size if iterating on arel scope" do
|
data/spec/seymour/feed_spec.rb
CHANGED
@@ -2,9 +2,32 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Seymour::Feed do
|
4
4
|
|
5
|
-
|
5
|
+
module FactoryHelper
|
6
|
+
def new_owner
|
7
|
+
stub_model(User)
|
8
|
+
end
|
9
|
+
|
10
|
+
def new_activity(attrs = {})
|
11
|
+
mock_model(Activity, attrs)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
include FactoryHelper
|
15
|
+
|
16
|
+
let(:owner) { new_owner }
|
6
17
|
let(:feed) { Seymour::Feed.new(owner) }
|
7
18
|
|
19
|
+
class ListFeed < Seymour::Feed
|
20
|
+
key do
|
21
|
+
"feed::#{owner.id}"
|
22
|
+
end
|
23
|
+
|
24
|
+
store :list
|
25
|
+
end
|
26
|
+
|
27
|
+
class ZsetFeed < Seymour::Feed
|
28
|
+
store :zset
|
29
|
+
end
|
30
|
+
|
8
31
|
describe "class methods" do
|
9
32
|
describe "feed_classes" do
|
10
33
|
it "should provide a list of feed sub classes" do
|
@@ -14,11 +37,34 @@ describe Seymour::Feed do
|
|
14
37
|
|
15
38
|
describe "distribute" do
|
16
39
|
it "should call activity distribute on activity" do
|
17
|
-
activity =
|
40
|
+
activity = new_activity
|
18
41
|
activity.should_receive(:distribute)
|
19
42
|
Seymour::Feed.distribute(activity)
|
20
43
|
end
|
21
44
|
end
|
45
|
+
|
46
|
+
describe "key" do
|
47
|
+
it "should override default feed key" do
|
48
|
+
feed = ListFeed.new(owner)
|
49
|
+
feed.key.should == "feed::#{owner.id}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "store" do
|
54
|
+
it "should default to list feed" do
|
55
|
+
feed.store.should be_a(Seymour::Store::List)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should set type of storage to list" do
|
59
|
+
feed = ListFeed.new(owner)
|
60
|
+
feed.store.should be_a(Seymour::Store::List)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should set type of storage to zset" do
|
64
|
+
feed = ZsetFeed.new(owner)
|
65
|
+
feed.store.should be_a(Seymour::Store::Zset)
|
66
|
+
end
|
67
|
+
end
|
22
68
|
end
|
23
69
|
|
24
70
|
describe "activity_ids" do
|
@@ -27,118 +73,262 @@ describe Seymour::Feed do
|
|
27
73
|
end
|
28
74
|
end
|
29
75
|
|
30
|
-
describe "
|
31
|
-
it "
|
32
|
-
feed.
|
33
|
-
|
76
|
+
describe "owner" do
|
77
|
+
it "should return given owner" do
|
78
|
+
feed.owner.should == owner
|
79
|
+
end
|
80
|
+
end
|
34
81
|
|
35
|
-
|
36
|
-
|
82
|
+
describe "key" do
|
83
|
+
it "should return default" do
|
84
|
+
feed.send(:key).should == "#{owner.class.name}:#{owner.id}/seymour::feed"
|
37
85
|
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "list feed" do
|
89
|
+
describe "push" do
|
90
|
+
it "prepends id of given activity to activity_ids" do
|
91
|
+
feed.push new_activity(:id => 123)
|
92
|
+
feed.activity_ids.should == [123]
|
93
|
+
|
94
|
+
feed.push new_activity(:id => 456)
|
95
|
+
feed.activity_ids.should == [456, 123]
|
96
|
+
end
|
97
|
+
|
98
|
+
it "new feed with same owner pushes to same list" do
|
99
|
+
new_feed = Seymour::Feed.new(owner)
|
38
100
|
|
39
|
-
|
40
|
-
|
101
|
+
feed.push new_activity(:id => 123)
|
102
|
+
new_feed.push new_activity(:id => 456)
|
41
103
|
|
42
|
-
|
43
|
-
|
104
|
+
feed.activity_ids.should == [456, 123]
|
105
|
+
new_feed.activity_ids.should == [456, 123]
|
106
|
+
end
|
107
|
+
|
108
|
+
it "new feed with different owner pushes to different list" do
|
109
|
+
new_owner = mock_model(User)
|
110
|
+
new_feed = Seymour::Feed.new(new_owner)
|
111
|
+
|
112
|
+
feed.push new_activity(:id => 123)
|
113
|
+
new_feed.push new_activity(:id => 456)
|
114
|
+
|
115
|
+
feed.activity_ids.should == [123]
|
116
|
+
new_feed.activity_ids.should == [456]
|
117
|
+
end
|
44
118
|
|
45
|
-
feed.activity_ids.should == [456, 123]
|
46
|
-
new_feed.activity_ids.should == [456, 123]
|
47
119
|
end
|
48
120
|
|
49
|
-
|
50
|
-
|
51
|
-
|
121
|
+
describe "bulk_push" do
|
122
|
+
it "should accept multiple values" do
|
123
|
+
feed.bulk_push [new_activity(:id => 123), new_activity(:id => 456)]
|
124
|
+
feed.activity_ids.should == [456, 123]
|
125
|
+
end
|
52
126
|
|
53
|
-
|
54
|
-
|
127
|
+
it "should not append duplicates" do
|
128
|
+
feed.bulk_push [new_activity(:id => 123), new_activity(:id => 456), new_activity(:id => 123)]
|
129
|
+
feed.activity_ids.should == [456, 123]
|
130
|
+
end
|
131
|
+
end
|
55
132
|
|
56
|
-
|
57
|
-
|
133
|
+
describe "sort" do
|
134
|
+
it "should sort list in desc order by default" do
|
135
|
+
feed.bulk_push [new_activity(:id => 456), new_activity(:id => 123)]
|
136
|
+
feed.sort!
|
137
|
+
feed.activity_ids.should == [456, 123]
|
138
|
+
end
|
58
139
|
end
|
59
140
|
|
60
|
-
|
141
|
+
describe "insert_and_order" do
|
142
|
+
it "should insert activities into the list" do
|
143
|
+
activities = [new_activity(:id => 123), new_activity(:id => 456)]
|
144
|
+
feed.insert_and_order(activities)
|
61
145
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
146
|
+
feed.activity_ids.should == [456, 123]
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should reorder activities by id" do
|
150
|
+
feed.push new_activity(:id => 123)
|
151
|
+
feed.push new_activity(:id => 456)
|
152
|
+
|
153
|
+
activities = [new_activity(:id => 234), new_activity(:id => 789)]
|
154
|
+
|
155
|
+
feed.insert_and_order(activities)
|
156
|
+
|
157
|
+
feed.activity_ids.should == [789, 456, 234, 123]
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should not allow duplicates" do
|
161
|
+
feed.push new_activity(:id => 123)
|
162
|
+
feed.push new_activity(:id => 456)
|
163
|
+
|
164
|
+
activities = [new_activity(:id => 123), new_activity(:id => 789)]
|
165
|
+
|
166
|
+
feed.insert_and_order(activities)
|
167
|
+
|
168
|
+
feed.activity_ids.should == [789, 456, 123]
|
169
|
+
end
|
66
170
|
end
|
67
171
|
|
68
|
-
|
69
|
-
|
70
|
-
|
172
|
+
describe "remove" do
|
173
|
+
it "removes activity from list by id" do
|
174
|
+
activity_1 = new_activity(:id => 456)
|
175
|
+
activity_2 = new_activity(:id => 789)
|
176
|
+
feed.push activity_1
|
177
|
+
feed.push activity_2
|
178
|
+
|
179
|
+
feed.remove activity_1
|
180
|
+
|
181
|
+
feed.activity_ids.should == [activity_2.id]
|
182
|
+
end
|
71
183
|
end
|
72
|
-
end
|
73
184
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
185
|
+
describe "remove_id" do
|
186
|
+
it "removes activity_id from list" do
|
187
|
+
activity_1 = new_activity(:id => 456)
|
188
|
+
activity_2 = new_activity(:id => 789)
|
189
|
+
feed.push activity_1
|
190
|
+
feed.push activity_2
|
191
|
+
|
192
|
+
feed.remove_id activity_1.id
|
193
|
+
|
194
|
+
feed.activity_ids.should == [activity_2.id]
|
195
|
+
end
|
79
196
|
end
|
80
197
|
end
|
81
198
|
|
82
|
-
describe "
|
83
|
-
|
84
|
-
activities = [mock_model(Activity, :id => 123), mock_model(Activity, :id => 456)]
|
85
|
-
feed.insert_and_order(activities)
|
199
|
+
describe "zset" do
|
200
|
+
let(:feed) { ZsetFeed.new(owner) }
|
86
201
|
|
87
|
-
|
88
|
-
|
202
|
+
describe "push" do
|
203
|
+
it "returns ids sorted by score, highest to lowest" do
|
204
|
+
feed.push new_activity(:id => 123, :score => 1)
|
205
|
+
feed.push new_activity(:id => 456, :score => 3)
|
206
|
+
feed.activity_ids.should == [456, 123]
|
207
|
+
end
|
89
208
|
|
90
|
-
|
91
|
-
|
92
|
-
|
209
|
+
it "returns accepts score as second arg" do
|
210
|
+
feed.push new_activity(:id => 123), 2
|
211
|
+
feed.push new_activity(:id => 456), 1
|
212
|
+
feed.activity_ids.should == [123, 456]
|
213
|
+
end
|
214
|
+
|
215
|
+
it "returns ordered by id when scores equal" do
|
216
|
+
feed.push new_activity(:id => 456), 1
|
217
|
+
feed.push new_activity(:id => 123), 1
|
218
|
+
feed.activity_ids.should == [456, 123]
|
219
|
+
end
|
93
220
|
|
94
|
-
|
221
|
+
it "does not add duplicates but updates score" do
|
222
|
+
feed.push new_activity(:id => 123), 2
|
223
|
+
feed.push new_activity(:id => 456), 1
|
224
|
+
feed.push new_activity(:id => 456), 3
|
225
|
+
feed.activity_ids.should == [456, 123]
|
226
|
+
end
|
227
|
+
end
|
95
228
|
|
96
|
-
|
229
|
+
describe "bulk_push" do
|
230
|
+
it "should accept multiple values" do
|
231
|
+
feed.bulk_push [new_activity(:id => 123, :score => 1), new_activity(:id => 456, :score => 3)]
|
232
|
+
feed.activity_ids.should == [456, 123]
|
233
|
+
end
|
97
234
|
|
98
|
-
|
235
|
+
it "should not append duplicates" do
|
236
|
+
feed.bulk_push [new_activity(:id => 123, :score => 2),
|
237
|
+
new_activity(:id => 456, :score => 1), new_activity(:id => 123, :score => 3)]
|
238
|
+
feed.activity_ids.should == [123, 456]
|
239
|
+
end
|
99
240
|
end
|
100
241
|
|
101
|
-
|
102
|
-
|
103
|
-
|
242
|
+
describe "union" do
|
243
|
+
it "should store union of given feeds" do
|
244
|
+
feed_1 = ZsetFeed.new(new_owner)
|
245
|
+
feed_2 = ZsetFeed.new(new_owner)
|
104
246
|
|
105
|
-
|
247
|
+
feed_1.push new_activity(:id => 456), 2
|
248
|
+
feed_2.push new_activity(:id => 123), 1
|
249
|
+
feed_2.push new_activity(:id => 789), 3
|
106
250
|
|
107
|
-
|
251
|
+
feed_1.activity_ids.should == [456]
|
252
|
+
feed_2.activity_ids.should == [789, 123]
|
108
253
|
|
109
|
-
|
254
|
+
feed.union([feed_1, feed_2]).should == 3
|
255
|
+
feed.activity_ids.should == [789, 456, 123]
|
256
|
+
end
|
110
257
|
end
|
111
|
-
end
|
112
258
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
259
|
+
describe "intersect" do
|
260
|
+
it "should store intersection of given feeds" do
|
261
|
+
feed_1 = ZsetFeed.new(new_owner)
|
262
|
+
feed_2 = ZsetFeed.new(new_owner)
|
263
|
+
|
264
|
+
feed_1.push new_activity(:id => 456), 2
|
265
|
+
feed_2.push new_activity(:id => 456), 1
|
266
|
+
feed_2.push new_activity(:id => 789), 3
|
119
267
|
|
120
|
-
|
268
|
+
feed_1.activity_ids.should == [456]
|
269
|
+
feed_2.activity_ids.should == [789, 456]
|
121
270
|
|
122
|
-
|
271
|
+
feed.intersect([feed_1, feed_2])
|
272
|
+
feed.activity_ids.should == [456]
|
273
|
+
end
|
123
274
|
end
|
124
|
-
end
|
125
275
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
276
|
+
#
|
277
|
+
# describe "insert_and_order" do
|
278
|
+
# it "should insert activities into the list" do
|
279
|
+
# activities = [new_activity(:id => 123), new_activity(:id => 456)]
|
280
|
+
# feed.insert_and_order(activities)
|
281
|
+
#
|
282
|
+
# feed.activity_ids.should == [456, 123]
|
283
|
+
# end
|
284
|
+
#
|
285
|
+
# it "should reorder activities by id" do
|
286
|
+
# feed.push new_activity(:id => 123)
|
287
|
+
# feed.push new_activity(:id => 456)
|
288
|
+
#
|
289
|
+
# activities = [new_activity(:id => 234), new_activity(:id => 789)]
|
290
|
+
#
|
291
|
+
# feed.insert_and_order(activities)
|
292
|
+
#
|
293
|
+
# feed.activity_ids.should == [789, 456, 234, 123]
|
294
|
+
# end
|
295
|
+
#
|
296
|
+
# it "should not allow duplicates" do
|
297
|
+
# feed.push new_activity(:id => 123)
|
298
|
+
# feed.push new_activity(:id => 456)
|
299
|
+
#
|
300
|
+
# activities = [new_activity(:id => 123), new_activity(:id => 789)]
|
301
|
+
#
|
302
|
+
# feed.insert_and_order(activities)
|
303
|
+
#
|
304
|
+
# feed.activity_ids.should == [789, 456, 123]
|
305
|
+
# end
|
306
|
+
# end
|
307
|
+
#
|
308
|
+
describe "remove" do
|
309
|
+
it "removes activity from list by id" do
|
310
|
+
activity_1 = new_activity(:id => 456)
|
311
|
+
activity_2 = new_activity(:id => 789)
|
312
|
+
feed.push activity_1, 2
|
313
|
+
feed.push activity_2, 1
|
314
|
+
|
315
|
+
feed.remove activity_1
|
316
|
+
|
317
|
+
feed.activity_ids.should == [activity_2.id]
|
318
|
+
end
|
319
|
+
end
|
132
320
|
|
133
|
-
|
321
|
+
describe "remove_id" do
|
322
|
+
it "removes activity_id from list" do
|
323
|
+
activity_1 = new_activity(:id => 456)
|
324
|
+
activity_2 = new_activity(:id => 789)
|
325
|
+
feed.push activity_1, 2
|
326
|
+
feed.push activity_2, 1
|
134
327
|
|
135
|
-
|
136
|
-
end
|
137
|
-
end
|
328
|
+
feed.remove_id activity_1.id
|
138
329
|
|
139
|
-
|
140
|
-
|
141
|
-
feed.owner.should == owner
|
330
|
+
feed.activity_ids.should == [activity_2.id]
|
331
|
+
end
|
142
332
|
end
|
143
333
|
end
|
144
334
|
end
|