socialization 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -0
  3. data/.travis.yml +2 -1
  4. data/Appraisals +13 -1
  5. data/CHANGELOG.md +12 -0
  6. data/Guardfile +12 -0
  7. data/LICENSE +2 -2
  8. data/README.md +46 -1
  9. data/Rakefile +8 -10
  10. data/lib/socialization/stores/active_record/follow.rb +4 -0
  11. data/lib/socialization/stores/active_record/like.rb +4 -0
  12. data/lib/socialization/stores/active_record/mention.rb +4 -0
  13. data/lib/socialization/stores/active_record/mixins/base.rb +4 -0
  14. data/lib/socialization/stores/mixins/follow.rb +1 -1
  15. data/lib/socialization/version.rb +1 -1
  16. data/socialization.gemspec +5 -3
  17. data/spec/actors/follower_spec.rb +113 -0
  18. data/spec/actors/liker_spec.rb +105 -0
  19. data/spec/actors/mentioner_spec.rb +105 -0
  20. data/spec/spec_helper.rb +21 -0
  21. data/{test/test_helper.rb → spec/spec_support/data_stores.rb} +76 -81
  22. data/spec/spec_support/matchers.rb +54 -0
  23. data/spec/stores/active_record/follow_store_spec.rb +147 -0
  24. data/spec/stores/active_record/like_store_spec.rb +146 -0
  25. data/spec/stores/active_record/mention_store_spec.rb +148 -0
  26. data/spec/stores/active_record/mixins/base_spec.rb +25 -0
  27. data/spec/stores/redis/base_spec.rb +195 -0
  28. data/spec/stores/redis/config_spec.rb +28 -0
  29. data/spec/stores/redis/follow_store_spec.rb +26 -0
  30. data/spec/stores/redis/like_store_spec.rb +23 -0
  31. data/spec/stores/redis/mention_store_spec.rb +23 -0
  32. data/spec/string_spec.rb +13 -0
  33. data/spec/victims/followable_spec.rb +59 -0
  34. data/spec/victims/likeable_spec.rb +58 -0
  35. data/spec/victims/mentionable_spec.rb +59 -0
  36. data/spec/world_spec.rb +107 -0
  37. metadata +79 -42
  38. data/test/actors/follower_test.rb +0 -114
  39. data/test/actors/liker_test.rb +0 -106
  40. data/test/actors/mentioner_test.rb +0 -106
  41. data/test/stores/active_record/follow_store_test.rb +0 -138
  42. data/test/stores/active_record/like_store_test.rb +0 -139
  43. data/test/stores/active_record/mention_store_test.rb +0 -138
  44. data/test/stores/redis/base_test.rb +0 -203
  45. data/test/stores/redis/config_test.rb +0 -30
  46. data/test/stores/redis/follow_store_test.rb +0 -27
  47. data/test/stores/redis/like_store_test.rb +0 -25
  48. data/test/stores/redis/mention_store_test.rb +0 -25
  49. data/test/string_test.rb +0 -13
  50. data/test/victims/followable_test.rb +0 -60
  51. data/test/victims/likeable_test.rb +0 -60
  52. data/test/victims/mentionable_test.rb +0 -60
  53. data/test/world_test.rb +0 -112
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ describe Socialization::Mentioner do
4
+ before(:all) do
5
+ use_ar_store
6
+ @mentioner = ImAMentioner.new
7
+ @mentionable = ImAMentionable.create
8
+ end
9
+
10
+ describe "#is_mentioner?" do
11
+ it "returns true" do
12
+ expect(@mentioner.is_mentioner?).to be true
13
+ end
14
+ end
15
+
16
+ describe "#mentioner?" do
17
+ it "returns true" do
18
+ expect(@mentioner.mentioner?).to be true
19
+ end
20
+ end
21
+
22
+ describe "#mention!" do
23
+ it "does not accept non-mentionables" do
24
+ expect { @mentioner.mention!(:foo) }.to raise_error(Socialization::ArgumentError)
25
+ end
26
+
27
+ it "calls $Mention.mention!" do
28
+ expect($Mention).to receive(:mention!).with(@mentioner, @mentionable).once
29
+ @mentioner.mention!(@mentionable)
30
+ end
31
+ end
32
+
33
+ describe "#unmention!" do
34
+ it "does not accept non-mentionables" do
35
+ expect { @mentioner.unmention!(:foo) }.to raise_error(Socialization::ArgumentError)
36
+ end
37
+
38
+ it "calls $Mention.mention!" do
39
+ expect($Mention).to receive(:unmention!).with(@mentioner, @mentionable).once
40
+ @mentioner.unmention!(@mentionable)
41
+ end
42
+ end
43
+
44
+ describe "#toggle_mention!" do
45
+ it "does not accept non-mentionables" do
46
+ expect { @mentioner.unmention!(:foo) }.to raise_error(Socialization::ArgumentError)
47
+ end
48
+
49
+ it "unmentions when mentioning" do
50
+ expect(@mentioner).to receive(:mentions?).with(@mentionable).once.and_return(true)
51
+ expect(@mentioner).to receive(:unmention!).with(@mentionable).once
52
+ @mentioner.toggle_mention!(@mentionable)
53
+ end
54
+
55
+ it "mentions when not mentioning" do
56
+ expect(@mentioner).to receive(:mentions?).with(@mentionable).once.and_return(false)
57
+ expect(@mentioner).to receive(:mention!).with(@mentionable).once
58
+ @mentioner.toggle_mention!(@mentionable)
59
+ end
60
+ end
61
+
62
+ describe "#mentions?" do
63
+ it "does not accept non-mentionables" do
64
+ expect { @mentioner.unmention!(:foo) }.to raise_error(Socialization::ArgumentError)
65
+ end
66
+
67
+ it "calls $Mention.mentions?" do
68
+ expect($Mention).to receive(:mentions?).with(@mentioner, @mentionable).once
69
+ @mentioner.mentions?(@mentionable)
70
+ end
71
+ end
72
+
73
+ describe "#mentionables" do
74
+ it "calls $Mention.mentionables" do
75
+ expect($Mention).to receive(:mentionables).with(@mentioner, @mentionable.class, { :foo => :bar })
76
+ @mentioner.mentionables(@mentionable.class, { :foo => :bar })
77
+ end
78
+ end
79
+
80
+ describe "#mentionees" do
81
+ it "calls $Mention.mentionables" do
82
+ expect($Mention).to receive(:mentionables).with(@mentioner, @mentionable.class, { :foo => :bar })
83
+ @mentioner.mentionees(@mentionable.class, { :foo => :bar })
84
+ end
85
+ end
86
+
87
+ describe "#mentionables_relation" do
88
+ it "calls $Mention.mentionables_relation" do
89
+ expect($Mention).to receive(:mentionables_relation).with(@mentioner, @mentionable.class, { :foo => :bar })
90
+ @mentioner.mentionables_relation(@mentionable.class, { :foo => :bar })
91
+ end
92
+ end
93
+
94
+ describe "#mentionees_relation" do
95
+ it "calls $Mention.mentionables_relation" do
96
+ expect($Mention).to receive(:mentionables_relation).with(@mentioner, @mentionable.class, { :foo => :bar })
97
+ @mentioner.mentionees_relation(@mentionable.class, { :foo => :bar })
98
+ end
99
+ end
100
+
101
+ it "removes mention relationships" do
102
+ expect(Socialization.mention_model).to receive(:remove_mentionables).with(@mentioner)
103
+ @mentioner.destroy
104
+ end
105
+ end
@@ -0,0 +1,21 @@
1
+ $MOCK_REDIS = true
2
+
3
+ require 'bundler/setup'
4
+ Bundler.setup
5
+
6
+ RSpec.configure do |config|
7
+ config.expect_with(:rspec) { |c| c.syntax = :expect }
8
+ config.filter_run focus: true
9
+ config.run_all_when_everything_filtered = true
10
+ end
11
+
12
+ $:.push File.expand_path("../lib", __FILE__)
13
+ require 'active_record'
14
+ require "socialization"
15
+ require 'spec_support/data_stores'
16
+ require 'spec_support/matchers'
17
+ require 'logger'
18
+
19
+ ActiveSupport::Inflector.inflections do |inflect|
20
+ inflect.irregular 'cache', 'caches'
21
+ end
@@ -1,64 +1,10 @@
1
- $MOCK_REDIS = true
2
-
3
- require 'rubygems'
4
- require 'active_record'
5
- require 'shoulda'
6
- require 'test/unit'
7
- require 'logger'
8
1
  require 'mock_redis' if $MOCK_REDIS
9
2
  require 'redis' unless $MOCK_REDIS
10
- require 'mocha' # mocha always needs to be loaded last! http://stackoverflow.com/questions/3118866/mocha-mock-carries-to-another-test/4375296#4375296
11
- # require 'pry'
12
-
13
- $:.push File.expand_path("../lib", __FILE__)
14
- require "socialization"
15
3
 
16
4
  silence_warnings do
17
5
  Redis = MockRedis if $MOCK_REDIS # Magic!
18
6
  end
19
7
 
20
- module Test::Unit::Assertions
21
- def assert_true(object, message="")
22
- assert_equal(true, object, message)
23
- end
24
-
25
- def assert_false(object, message="")
26
- assert_equal(false, object, message)
27
- end
28
-
29
- def assert_array_similarity(expected, actual, message=nil)
30
- full_message = build_message(message, "<?> expected but was\n<?>.\n", expected, actual)
31
- assert_block(full_message) { (expected.size == actual.size) && (expected - actual == []) }
32
- end
33
-
34
- def assert_empty(obj, msg = nil)
35
- msg = "Expected #{obj.inspect} to be empty" unless msg
36
- assert_respond_to obj, :empty?
37
- assert obj.empty?, msg
38
- end
39
-
40
- def assert_method_public(obj, method, msg = nil)
41
- msg = "Expected method #{obj}.#{method} to be public."
42
- method = if RUBY_VERSION.match(/^1\.8/)
43
- method.to_s
44
- else
45
- method.to_s.to_sym
46
- end
47
-
48
- assert obj.public_methods.include?(method), msg
49
- end
50
- end
51
-
52
- class Test::Unit::TestCase
53
- def setup
54
- use_ar_store
55
- end
56
-
57
- def teardown
58
- clear_redis
59
- end
60
- end
61
-
62
8
  def use_redis_store
63
9
  Socialization.follow_model = Socialization::RedisStores::Follow
64
10
  Socialization.mention_model = Socialization::RedisStores::Mention
@@ -86,7 +32,7 @@ def clear_redis
86
32
  end
87
33
 
88
34
  ActiveRecord::Base.configurations = {'sqlite3' => {:adapter => 'sqlite3', :database => ':memory:'}}
89
- ActiveRecord::Base.establish_connection('sqlite3')
35
+ ActiveRecord::Base.establish_connection(:sqlite3)
90
36
 
91
37
  ActiveRecord::Base.logger = Logger.new(STDERR)
92
38
  ActiveRecord::Base.logger.level = Logger::WARN
@@ -136,44 +82,74 @@ ActiveRecord::Schema.define(:version => 0) do
136
82
  end
137
83
 
138
84
  create_table :im_a_followers do |t|
139
- t.timestamps
85
+ t.timestamps null: true
86
+ end
87
+
88
+ create_table :im_a_follower_with_counter_caches do |t|
89
+ t.integer :followees_count, default: 0
90
+ t.timestamps null: true
140
91
  end
141
92
 
142
93
  create_table :im_a_followables do |t|
143
- t.timestamps
94
+ t.timestamps null: true
95
+ end
96
+
97
+ create_table :im_a_followable_with_counter_caches do |t|
98
+ t.integer :followers_count, default: 0
99
+ t.timestamps null: true
144
100
  end
145
101
 
146
102
  create_table :im_a_likers do |t|
147
- t.timestamps
103
+ t.timestamps null: true
104
+ end
105
+
106
+ create_table :im_a_liker_with_counter_caches do |t|
107
+ t.integer :likees_count, default: 0
108
+ t.timestamps null: true
148
109
  end
149
110
 
150
111
  create_table :im_a_likeables do |t|
151
- t.timestamps
112
+ t.timestamps null: true
113
+ end
114
+
115
+ create_table :im_a_likeable_with_counter_caches do |t|
116
+ t.integer :likers_count, default: 0
117
+ t.timestamps null: true
152
118
  end
153
119
 
154
120
  create_table :im_a_mentioners do |t|
155
- t.timestamps
121
+ t.timestamps null: true
122
+ end
123
+
124
+ create_table :im_a_mentioner_with_counter_caches do |t|
125
+ t.integer :mentionees_count, default: 0
126
+ t.timestamps null: true
156
127
  end
157
128
 
158
129
  create_table :im_a_mentionables do |t|
159
- t.timestamps
130
+ t.timestamps null: true
131
+ end
132
+
133
+ create_table :im_a_mentionable_with_counter_caches do |t|
134
+ t.integer :mentioners_count, default: 0
135
+ t.timestamps null: true
160
136
  end
161
137
 
162
138
  create_table :im_a_mentioner_and_mentionables do |t|
163
- t.timestamps
139
+ t.timestamps null: true
164
140
  end
165
141
 
166
142
  create_table :vanillas do |t|
167
- t.timestamps
143
+ t.timestamps null: true
168
144
  end
169
145
  end
170
146
 
171
- class Celebrity < ActiveRecord::Base
147
+ class ::Celebrity < ActiveRecord::Base
172
148
  acts_as_followable
173
149
  acts_as_mentionable
174
150
  end
175
151
 
176
- class User < ActiveRecord::Base
152
+ class ::User < ActiveRecord::Base
177
153
  acts_as_follower
178
154
  acts_as_followable
179
155
  acts_as_liker
@@ -183,13 +159,13 @@ class User < ActiveRecord::Base
183
159
  has_many :comments
184
160
  end
185
161
 
186
- class Comment < ActiveRecord::Base
162
+ class ::Comment < ActiveRecord::Base
187
163
  acts_as_mentioner
188
164
  belongs_to :user
189
165
  belongs_to :movie
190
166
  end
191
167
 
192
- class Movie < ActiveRecord::Base
168
+ class ::Movie < ActiveRecord::Base
193
169
  acts_as_likeable
194
170
  has_many :comments
195
171
  end
@@ -198,40 +174,59 @@ end
198
174
  # class Like < Socialization::ActiveRecordStores::Like; end
199
175
  # class Mention < Socialization::ActiveRecordStores::Mention; end
200
176
 
201
- class ImAFollower < ActiveRecord::Base
177
+ class ::ImAFollower < ActiveRecord::Base
178
+ acts_as_follower
179
+ end
180
+ class ::ImAFollowerWithCounterCache < ActiveRecord::Base
202
181
  acts_as_follower
203
182
  end
204
- class ImAFollowerChild < ImAFollower; end
183
+ class ::ImAFollowerChild < ImAFollower; end
205
184
 
206
- class ImAFollowable < ActiveRecord::Base
185
+ class ::ImAFollowable < ActiveRecord::Base
207
186
  acts_as_followable
208
187
  end
209
- class ImAFollowableChild < ImAFollowable; end
188
+ class ::ImAFollowableWithCounterCache < ActiveRecord::Base
189
+ acts_as_followable
190
+ end
191
+ class ::ImAFollowableChild < ImAFollowable; end
210
192
 
211
- class ImALiker < ActiveRecord::Base
193
+ class ::ImALiker < ActiveRecord::Base
194
+ acts_as_liker
195
+ end
196
+ class ::ImALikerWithCounterCache < ActiveRecord::Base
212
197
  acts_as_liker
213
198
  end
214
- class ImALikerChild < ImALiker; end
199
+ class ::ImALikerChild < ImALiker; end
215
200
 
216
- class ImALikeable < ActiveRecord::Base
201
+ class ::ImALikeable < ActiveRecord::Base
202
+ acts_as_likeable
203
+ end
204
+ class ::ImALikeableWithCounterCache < ActiveRecord::Base
217
205
  acts_as_likeable
218
206
  end
219
- class ImALikeableChild < ImALikeable; end
207
+ class ::ImALikeableChild < ImALikeable; end
220
208
 
221
- class ImAMentioner < ActiveRecord::Base
209
+ class ::ImAMentioner < ActiveRecord::Base
222
210
  acts_as_mentioner
223
211
  end
224
- class ImAMentionerChild < ImAMentioner; end
212
+ class ::ImAMentionerWithCounterCache < ActiveRecord::Base
213
+ acts_as_mentioner
214
+ end
215
+ class ::ImAMentionerChild < ImAMentioner; end
225
216
 
226
- class ImAMentionable < ActiveRecord::Base
217
+ class ::ImAMentionable < ActiveRecord::Base
227
218
  acts_as_mentionable
228
219
  end
229
- class ImAMentionableChild < ImAMentionable; end
220
+ class ::ImAMentionableWithCounterCache < ActiveRecord::Base
221
+ acts_as_mentionable
222
+ end
223
+ class ::ImAMentionableChild < ImAMentionable; end
230
224
 
231
- class ImAMentionerAndMentionable < ActiveRecord::Base
225
+ class ::ImAMentionerAndMentionable < ActiveRecord::Base
232
226
  acts_as_mentioner
233
227
  acts_as_mentionable
234
228
  end
235
229
 
236
- class Vanilla < ActiveRecord::Base
230
+ class ::Vanilla < ActiveRecord::Base
237
231
  end
232
+
@@ -0,0 +1,54 @@
1
+ RSpec::Matchers.define :be_a_public_method_of do |obj|
2
+ match do |actual|
3
+ method = RUBY_VERSION.match(/^1\.8/) ? actual.to_s : actual.to_s.to_sym
4
+ obj.public_methods.include?(method)
5
+ end
6
+
7
+ failure_message do |actual|
8
+ "expected that #{actual} would be a public method of #{actual.class}"
9
+ end
10
+
11
+ failure_message_when_negated do |actual|
12
+ "expected that #{actual} would not be a public method of #{actual.class}"
13
+ end
14
+
15
+ description do
16
+ "be a public method"
17
+ end
18
+ end
19
+
20
+ RSpec::Matchers.define :match_follower do |expected|
21
+ match do |actual|
22
+ expected.follower_type == actual.class.to_s && expected.follower_id == actual.id
23
+ end
24
+ end
25
+
26
+ RSpec::Matchers.define :match_followable do |expected|
27
+ match do |actual|
28
+ expected.followable_type == actual.class.to_s && expected.followable_id == actual.id
29
+ end
30
+ end
31
+
32
+ RSpec::Matchers.define :match_liker do |expected|
33
+ match do |actual|
34
+ expected.liker_type == actual.class.to_s && expected.liker_id == actual.id
35
+ end
36
+ end
37
+
38
+ RSpec::Matchers.define :match_likeable do |expected|
39
+ match do |actual|
40
+ expected.likeable_type == actual.class.to_s && expected.likeable_id == actual.id
41
+ end
42
+ end
43
+
44
+ RSpec::Matchers.define :match_mentioner do |expected|
45
+ match do |actual|
46
+ expected.mentioner_type == actual.class.to_s && expected.mentioner_id == actual.id
47
+ end
48
+ end
49
+
50
+ RSpec::Matchers.define :match_mentionable do |expected|
51
+ match do |actual|
52
+ expected.mentionable_type == actual.class.to_s && expected.mentionable_id == actual.id
53
+ end
54
+ end
@@ -0,0 +1,147 @@
1
+ require 'spec_helper'
2
+
3
+ describe Socialization::ActiveRecordStores::Follow do
4
+ before do
5
+ @klass = Socialization::ActiveRecordStores::Follow
6
+ @klass.touch nil
7
+ @klass.after_follow nil
8
+ @klass.after_unfollow nil
9
+ @follower = ImAFollower.create
10
+ @followable = ImAFollowable.create
11
+ end
12
+
13
+ describe "data store" do
14
+ it "inherits Socialization::ActiveRecordStores::Follow" do
15
+ expect(Socialization.follow_model).to eq(Socialization::ActiveRecordStores::Follow)
16
+ end
17
+ end
18
+
19
+ describe "#follow!" do
20
+ it "creates a Follow record" do
21
+ @klass.follow!(@follower, @followable)
22
+ expect(@follower).to match_follower(@klass.last)
23
+ expect(@followable).to match_followable(@klass.last)
24
+ end
25
+
26
+ it "increments counter caches" do
27
+ follower = ImAFollowerWithCounterCache.create
28
+ followable = ImAFollowableWithCounterCache.create
29
+ @klass.follow!(follower, followable)
30
+ expect(follower.reload.followees_count).to eq(1)
31
+ expect(followable.reload.followers_count).to eq(1)
32
+ end
33
+
34
+ it "touches follower when instructed" do
35
+ @klass.touch :follower
36
+ expect(@follower).to receive(:touch).once
37
+ expect(@followable).to receive(:touch).never
38
+ @klass.follow!(@follower, @followable)
39
+ end
40
+
41
+ it "touches followable when instructed" do
42
+ @klass.touch :followable
43
+ expect(@follower).to receive(:touch).never
44
+ expect(@followable).to receive(:touch).once
45
+ @klass.follow!(@follower, @followable)
46
+ end
47
+
48
+ it "touches all when instructed" do
49
+ @klass.touch :all
50
+ expect(@follower).to receive(:touch).once
51
+ expect(@followable).to receive(:touch).once
52
+ @klass.follow!(@follower, @followable)
53
+ end
54
+
55
+ it "calls after follow hook" do
56
+ @klass.after_follow :after_follow
57
+ expect(@klass).to receive(:after_follow).once
58
+ @klass.follow!(@follower, @followable)
59
+ end
60
+
61
+ it "calls after unfollow hook" do
62
+ @klass.after_follow :after_unfollow
63
+ expect(@klass).to receive(:after_unfollow).once
64
+ @klass.follow!(@follower, @followable)
65
+ end
66
+ end
67
+
68
+ describe "#unfollow!" do
69
+ it "decrements counter caches" do
70
+ follower = ImAFollowerWithCounterCache.create
71
+ followable = ImAFollowableWithCounterCache.create
72
+ @klass.follow!(follower, followable)
73
+ @klass.unfollow!(follower, followable)
74
+ expect(follower.reload.followees_count).to eq(0)
75
+ expect(followable.reload.followers_count).to eq(0)
76
+ end
77
+ end
78
+
79
+ describe "#follows?" do
80
+ it "returns true when follow exists" do
81
+ @klass.create! do |f|
82
+ f.follower = @follower
83
+ f.followable = @followable
84
+ end
85
+ expect(@klass.follows?(@follower, @followable)).to be true
86
+ end
87
+
88
+ it "returns false when follow doesn't exist" do
89
+ expect(@klass.follows?(@follower, @followable)).to be false
90
+ end
91
+ end
92
+
93
+ describe "#followers" do
94
+ it "returns an array of followers" do
95
+ follower1 = ImAFollower.create
96
+ follower2 = ImAFollower.create
97
+ follower1.follow!(@followable)
98
+ follower2.follow!(@followable)
99
+ expect(@klass.followers(@followable, follower1.class)).to eq([follower1, follower2])
100
+ end
101
+
102
+ it "returns an array of follower ids when plucking" do
103
+ follower1 = ImAFollower.create
104
+ follower2 = ImAFollower.create
105
+ follower1.follow!(@followable)
106
+ follower2.follow!(@followable)
107
+ expect(@klass.followers(@followable, follower1.class, :pluck => :id)).to eq([follower1.id, follower2.id])
108
+ end
109
+ end
110
+
111
+ describe "#followables" do
112
+ it "returns an array of followers" do
113
+ followable1 = ImAFollowable.create
114
+ followable2 = ImAFollowable.create
115
+ @follower.follow!(followable1)
116
+ @follower.follow!(followable2)
117
+ expect(@klass.followables(@follower, followable1.class)).to eq([followable1, followable2])
118
+ end
119
+
120
+ it "returns an array of follower ids when plucking" do
121
+ followable1 = ImAFollowable.create
122
+ followable2 = ImAFollowable.create
123
+ @follower.follow!(followable1)
124
+ @follower.follow!(followable2)
125
+ expect(@klass.followables(@follower, followable1.class, :pluck => :id)).to eq([followable1.id, followable2.id])
126
+ end
127
+ end
128
+
129
+ describe "#remove_followers" do
130
+ it "deletes all followers relationships for a followable" do
131
+ @follower.follow!(@followable)
132
+ expect(@followable.followers(@follower.class).count).to eq(1)
133
+ @klass.remove_followers(@followable)
134
+ expect(@followable.followers(@follower.class).count).to eq(0)
135
+ end
136
+ end
137
+
138
+ describe "#remove_followables" do
139
+ it "deletes all followables relationships for a follower" do
140
+ @follower.follow!(@followable)
141
+ expect(@follower.followables(@followable.class).count).to eq(1)
142
+ @klass.remove_followables(@follower)
143
+ expect(@follower.followables(@followable.class).count).to eq(0)
144
+ end
145
+ end
146
+ end
147
+