socialization-cassandra 0.0.1.pre.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG.md +0 -0
  5. data/Gemfile +9 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +144 -0
  8. data/Rakefile +10 -0
  9. data/init.rb +1 -0
  10. data/lib/generators/socialization/socialization_generator.rb +17 -0
  11. data/lib/generators/socialization/templates/cassandra/model_comment.rb +2 -0
  12. data/lib/generators/socialization/templates/cassandra/model_follow.rb +2 -0
  13. data/lib/generators/socialization/templates/cassandra/model_like.rb +2 -0
  14. data/lib/generators/socialization/templates/cassandra/model_share.rb +2 -0
  15. data/lib/generators/socialization/templates/socialization_cassandra_migrations.rake +141 -0
  16. data/lib/socialization/actors/commenter.rb +79 -0
  17. data/lib/socialization/actors/follower.rb +79 -0
  18. data/lib/socialization/actors/liker.rb +79 -0
  19. data/lib/socialization/actors/mentioner.rb +79 -0
  20. data/lib/socialization/actors/sharer.rb +79 -0
  21. data/lib/socialization/config/config.rb +51 -0
  22. data/lib/socialization/helpers/acts_as_helpers.rb +49 -0
  23. data/lib/socialization/helpers/string.rb +17 -0
  24. data/lib/socialization/lib/exceptions.rb +3 -0
  25. data/lib/socialization/stores/cassandra/base.rb +149 -0
  26. data/lib/socialization/stores/cassandra/comment.rb +28 -0
  27. data/lib/socialization/stores/cassandra/config.rb +29 -0
  28. data/lib/socialization/stores/cassandra/follow.rb +36 -0
  29. data/lib/socialization/stores/cassandra/like.rb +35 -0
  30. data/lib/socialization/stores/cassandra/mixins/base.rb +8 -0
  31. data/lib/socialization/stores/cassandra/share.rb +28 -0
  32. data/lib/socialization/stores/mixins/base.rb +22 -0
  33. data/lib/socialization/stores/mixins/follow.rb +39 -0
  34. data/lib/socialization/stores/mixins/like.rb +40 -0
  35. data/lib/socialization/stores/mixins/mention.rb +40 -0
  36. data/lib/socialization/version.rb +3 -0
  37. data/lib/socialization/victims/commentable.rb +51 -0
  38. data/lib/socialization/victims/followable.rb +50 -0
  39. data/lib/socialization/victims/likeable.rb +51 -0
  40. data/lib/socialization/victims/shareable.rb +51 -0
  41. data/lib/socialization.rb +17 -0
  42. data/socialization-cassandra.gemspec +30 -0
  43. data/test/actors/follower_test.rb +129 -0
  44. data/test/actors/liker_test.rb +121 -0
  45. data/test/stores/cassandra/base_test.rb +186 -0
  46. data/test/stores/cassandra/config_test.rb +36 -0
  47. data/test/stores/cassandra/follow_store_test.rb +28 -0
  48. data/test/stores/cassandra/like_store_test.rb +26 -0
  49. data/test/string_test.rb +13 -0
  50. data/test/test_helper.rb +259 -0
  51. data/test/victims/followable_test.rb +65 -0
  52. data/test/victims/likeable_test.rb +67 -0
  53. data/test/world_test.rb +107 -0
  54. metadata +209 -0
@@ -0,0 +1,40 @@
1
+ module Socialization
2
+ module Stores
3
+ module Mixins
4
+ module Like
5
+
6
+ public
7
+ def touch(what = nil)
8
+ if what.nil?
9
+ @touch || false
10
+ else
11
+ raise Socialization::ArgumentError unless [:all, :liker, :likeable, false, nil].include?(what)
12
+ @touch = what
13
+ end
14
+ end
15
+
16
+ def after_like(method)
17
+ raise Socialization::ArgumentError unless method.is_a?(Symbol) || method.nil?
18
+ @after_create_hook = method
19
+ end
20
+
21
+ def after_unlike(method)
22
+ raise Socialization::ArgumentError unless method.is_a?(Symbol) || method.nil?
23
+ @after_destroy_hook = method
24
+ end
25
+
26
+ protected
27
+ def call_after_create_hooks(liker, likeable)
28
+ self.send(@after_create_hook, liker, likeable) if @after_create_hook
29
+ touch_dependents(liker, likeable)
30
+ end
31
+
32
+ def call_after_destroy_hooks(liker, likeable)
33
+ self.send(@after_destroy_hook, liker, likeable) if @after_destroy_hook
34
+ touch_dependents(liker, likeable)
35
+ end
36
+
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ module Socialization
2
+ module Stores
3
+ module Mixins
4
+ module Mention
5
+
6
+ public
7
+ def touch(what = nil)
8
+ if what.nil?
9
+ @touch || false
10
+ else
11
+ raise Socialization::ArgumentError unless [:all, :mentioner, :mentionable, false, nil].include?(what)
12
+ @touch = what
13
+ end
14
+ end
15
+
16
+ def after_mention(method)
17
+ raise Socialization::ArgumentError unless method.is_a?(Symbol) || method.nil?
18
+ @after_create_hook = method
19
+ end
20
+
21
+ def after_unmention(method)
22
+ raise Socialization::ArgumentError unless method.is_a?(Symbol) || method.nil?
23
+ @after_destroy_hook = method
24
+ end
25
+
26
+ protected
27
+ def call_after_create_hooks(mentioner, mentionable)
28
+ self.send(@after_create_hook, mentioner, mentionable) if @after_create_hook
29
+ touch_dependents(mentioner, mentionable)
30
+ end
31
+
32
+ def call_after_destroy_hooks(mentioner, mentionable)
33
+ self.send(@after_destroy_hook, mentioner, mentionable) if @after_destroy_hook
34
+ touch_dependents(mentioner, mentionable)
35
+ end
36
+
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module Socialization
2
+ VERSION = "0.0.1-alpha"
3
+ end
@@ -0,0 +1,51 @@
1
+ module ActiveRecord
2
+ class Base
3
+ def is_commentable?
4
+ false
5
+ end
6
+ alias commentable? is_commentable?
7
+ end
8
+ end
9
+
10
+ module Socialization
11
+ module Commentable
12
+ extend ActiveSupport::Concern
13
+
14
+ included do
15
+ after_destroy { Socialization.comment_model.remove_commenters(self) }
16
+
17
+ # Specifies if self can be commented.
18
+ #
19
+ # @return [Boolean]
20
+ def is_commentable?
21
+ true
22
+ end
23
+ alias commentable? is_commentable?
24
+
25
+ # Specifies if self is commented by a {commenter} object.
26
+ #
27
+ # @return [Boolean]
28
+ def commented_by?(commenter)
29
+ raise Socialization::ArgumentError, "#{commenter} is not commenter!" unless commenter.respond_to?(:is_commenter?) && commenter.is_commenter?
30
+ Socialization.comment_model.comments?(commenter, self)
31
+ end
32
+
33
+ # Returns an array of {commenter}s commenting self.
34
+ #
35
+ # @param [Class] klass the {commenter} class to be included. e.g. `User`
36
+ # @return [Array<commenter, Numeric>] An array of commenter objects or IDs
37
+ def commenters(klass, opts = {})
38
+ Socialization.comment_model.commenters(self, klass, opts)
39
+ end
40
+
41
+ # Returns a scope of the {commenter}s commenting self.
42
+ #
43
+ # @param [Class] klass the {commenter} class to be included in the scope. e.g. `User`
44
+ # @return ActiveRecord::Relation
45
+ def commenters_relation(klass, opts = {})
46
+ Socialization.comment_model.commenters_relation(self, klass, opts)
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,50 @@
1
+ module ActiveRecord
2
+ class Base
3
+ def is_followable?
4
+ false
5
+ end
6
+ alias followable? is_followable?
7
+ end
8
+ end
9
+
10
+ module Socialization
11
+ module Followable
12
+ extend ActiveSupport::Concern
13
+
14
+ included do
15
+ after_destroy { Socialization.follow_model.remove_followers(self) }
16
+
17
+ # Specifies if self can be followed.
18
+ #
19
+ # @return [Boolean]
20
+ def is_followable?
21
+ true
22
+ end
23
+ alias followable? is_followable?
24
+
25
+ # Specifies if self is followed by a {Follower} object.
26
+ #
27
+ # @return [Boolean]
28
+ def followed_by?(follower)
29
+ raise Socialization::ArgumentError, "#{follower} is not follower!" unless follower.respond_to?(:is_follower?) && follower.is_follower?
30
+ Socialization.follow_model.follows?(follower, self)
31
+ end
32
+
33
+ # Returns an array of {Follower}s following self.
34
+ #
35
+ # @param [Class] klass the {Follower} class to be included. e.g. `User`
36
+ # @return [Array<Follower, Numeric>] An array of Follower objects or IDs
37
+ def followers(klass, opts = {})
38
+ Socialization.follow_model.followers(self, klass, opts)
39
+ end
40
+
41
+ # Returns a scope of the {Follower}s following self.
42
+ #
43
+ # @param [Class] klass the {Follower} class to be included in the scope. e.g. `User`
44
+ # @return ActiveRecord::Relation
45
+ def followers_relation(klass, opts = {})
46
+ Socialization.follow_model.followers_relation(self, klass, opts)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,51 @@
1
+ module ActiveRecord
2
+ class Base
3
+ def is_likeable?
4
+ false
5
+ end
6
+ alias likeable? is_likeable?
7
+ end
8
+ end
9
+
10
+ module Socialization
11
+ module Likeable
12
+ extend ActiveSupport::Concern
13
+
14
+ included do
15
+ after_destroy { Socialization.like_model.remove_likers(self) }
16
+
17
+ # Specifies if self can be liked.
18
+ #
19
+ # @return [Boolean]
20
+ def is_likeable?
21
+ true
22
+ end
23
+ alias likeable? is_likeable?
24
+
25
+ # Specifies if self is liked by a {Liker} object.
26
+ #
27
+ # @return [Boolean]
28
+ def liked_by?(liker)
29
+ raise Socialization::ArgumentError, "#{liker} is not liker!" unless liker.respond_to?(:is_liker?) && liker.is_liker?
30
+ Socialization.like_model.likes?(liker, self)
31
+ end
32
+
33
+ # Returns an array of {Liker}s liking self.
34
+ #
35
+ # @param [Class] klass the {Liker} class to be included. e.g. `User`
36
+ # @return [Array<Liker, Numeric>] An array of Liker objects or IDs
37
+ def likers(klass, opts = {})
38
+ Socialization.like_model.likers(self, klass, opts)
39
+ end
40
+
41
+ # Returns a scope of the {Liker}s liking self.
42
+ #
43
+ # @param [Class] klass the {Liker} class to be included in the scope. e.g. `User`
44
+ # @return ActiveRecord::Relation
45
+ def likers_relation(klass, opts = {})
46
+ Socialization.like_model.likers_relation(self, klass, opts)
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,51 @@
1
+ module ActiveRecord
2
+ class Base
3
+ def is_shareable?
4
+ false
5
+ end
6
+ alias shareable? is_shareable?
7
+ end
8
+ end
9
+
10
+ module Socialization
11
+ module Shareable
12
+ extend ActiveSupport::Concern
13
+
14
+ included do
15
+ after_destroy { Socialization.share_model.remove_sharers(self) }
16
+
17
+ # Specifies if self can be shared.
18
+ #
19
+ # @return [Boolean]
20
+ def is_shareable?
21
+ true
22
+ end
23
+ alias shareable? is_shareable?
24
+
25
+ # Specifies if self is shared by a {sharer} object.
26
+ #
27
+ # @return [Boolean]
28
+ def shared_by?(sharer)
29
+ raise Socialization::ArgumentError, "#{sharer} is not sharer!" unless sharer.respond_to?(:is_sharer?) && sharer.is_sharer?
30
+ Socialization.share_model.shares?(sharer, self)
31
+ end
32
+
33
+ # Returns an array of {sharer}s shareing self.
34
+ #
35
+ # @param [Class] klass the {sharer} class to be included. e.g. `User`
36
+ # @return [Array<sharer, Numeric>] An array of sharer objects or IDs
37
+ def sharers(klass, opts = {})
38
+ Socialization.share_model.sharers(self, klass, opts)
39
+ end
40
+
41
+ # Returns a scope of the {sharer}s sharing self.
42
+ #
43
+ # @param [Class] klass the {sharer} class to be included in the scope. e.g. `User`
44
+ # @return ActiveRecord::Relation
45
+ def sharers_relation(klass, opts = {})
46
+ Socialization.share_model.sharers_relation(self, klass, opts)
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,17 @@
1
+ %w(
2
+ lib/*.rb
3
+ stores/mixins/base.rb
4
+ stores/mixins/**/*.rb
5
+ stores/cassandra/mixins/base.rb
6
+ stores/cassandra/mixins/**/*.rb
7
+ stores/cassandra/base.rb
8
+ stores/cassandra/**/*.rb
9
+ actors/**/*.rb
10
+ victims/**/*.rb
11
+ helpers/**/*.rb
12
+ config/**/*.rb
13
+ ).each do |path|
14
+ Dir["#{File.dirname(__FILE__)}/socialization/#{path}"].each { |f| require(f) }
15
+ end
16
+
17
+ ActiveRecord::Base.send :include, Socialization::ActsAsHelpers
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "socialization/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "socialization-cassandra"
7
+ s.version = Socialization::VERSION
8
+ s.authors = ["Amrit Singh"]
9
+ s.email = "amrit0403@gmail.com"
10
+ s.homepage = "https://github.com/amritsingh/socialization-cassandra"
11
+ s.summary = "Easily socialize your app with Likes and Follows"
12
+ s.description = "Socialization allows any model to Follow and/or Like any other model. This is accomplished through a double polymorphic relationship on the Follow and Like models. But you don't need to know that since all the complexity is hidden from you."
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.has_rdoc = false
20
+
21
+ s.add_runtime_dependency "activerecord"
22
+ s.add_runtime_dependency "cassandra-driver"
23
+
24
+ s.add_development_dependency "logger"
25
+ s.add_development_dependency "mocha"
26
+ s.add_development_dependency "shoulda"
27
+ s.add_development_dependency "sqlite3"
28
+ s.add_development_dependency "yard"
29
+ s.add_development_dependency "minitest", "~> 4.0"
30
+ end
@@ -0,0 +1,129 @@
1
+ require File.expand_path(File.dirname(__FILE__))+'/../test_helper'
2
+
3
+ class FollowerTest < TestCase
4
+ include Assertions
5
+ context "Follower" do
6
+ setup do
7
+ # @follower = ImAFollower.new
8
+ @follower = ImAFollower.create
9
+ @followable = ImAFollowable.create
10
+ end
11
+
12
+ context "#is_follower?" do
13
+ should "return true" do
14
+ assert_true @follower.is_follower?
15
+ end
16
+ end
17
+
18
+ context "#follower?" do
19
+ should "return true" do
20
+ assert_true @follower.follower?
21
+ end
22
+ end
23
+
24
+ context "#follow!" do
25
+ should "not accept non-followables" do
26
+ assert_raises(Socialization::ArgumentError) { @follower.follow!(:foo) }
27
+ end
28
+
29
+ should "call $Follow.follow!" do
30
+ assert_send([$Follow, :follow!, *[@follower, @followable]])
31
+ @follower.follow!(@followable)
32
+ end
33
+ end
34
+
35
+ context "#unfollow!" do
36
+ should "not accept non-followables" do
37
+ assert_raises(Socialization::ArgumentError) { @follower.unfollow!(:foo) }
38
+ end
39
+
40
+ should "call $Follow.follow!" do
41
+ Minitest::Mock.new.expect(:check, true) do
42
+ $Follow.unfollows!(@follower, @followable)
43
+ end
44
+ @follower.unfollow!(@followable)
45
+ end
46
+ end
47
+
48
+ context "#toggle_follow!" do
49
+ should "not accept non-followables" do
50
+ assert_raises(Socialization::ArgumentError) { @follower.unfollow!(:foo) }
51
+ end
52
+
53
+ should "unfollow when following" do
54
+ @follower.follow!(@followable)
55
+ Minitest::Mock.new.expect(:check, true) do
56
+ @follower.follows?(@followable)
57
+ end
58
+ # @follower.expect :follows?, true, *[@followable]
59
+ # assert_send([@follower, :follows?, *[@followable]])
60
+ assert_send([@follower, :unfollow!, *[@followable]])
61
+ @follower.toggle_follow!(@followable)
62
+ end
63
+
64
+ should "follow when not following" do
65
+ Minitest::Mock.new.expect(:check, false) do
66
+ @follower.follows?(@followable)
67
+ end
68
+ # !assert_send([@follower, :follows?, *[@followable]])
69
+ # assert_send([@follower, :follows?, *[@followable]])
70
+ @follower.toggle_follow!(@followable)
71
+ end
72
+ end
73
+
74
+ context "#follows?" do
75
+ should "not accept non-followables" do
76
+ assert_raises(Socialization::ArgumentError) { @follower.unfollow!(:foo) }
77
+ end
78
+
79
+ should "call $Follow.follows?" do
80
+ Minitest::Mock.new.expect(:check, false) do
81
+ $Follow.follows?(@follower, @followable)
82
+ end
83
+ # assert_send([$Follow, :follows?, *[@follower, @followable]])
84
+ @follower.follows?(@followable)
85
+ end
86
+ end
87
+
88
+ context "#followables" do
89
+ should "call $Follow.followables" do
90
+ assert_send([$Follow, :followables, *[@follower, @followable.class, { :foo => :bar }]])
91
+ @follower.followables(@followable.class, { :foo => :bar })
92
+ end
93
+ end
94
+
95
+ context "#followees" do
96
+ should "call $Follow.followables" do
97
+ assert_send([$Follow, :followables, *[@follower, @followable.class, { :foo => :bar }]])
98
+ @follower.followees(@followable.class, { :foo => :bar })
99
+ end
100
+ end
101
+
102
+ context "#followables_relation" do
103
+ should "call $Follow.followables_relation" do
104
+ assert_send([$Follow, :followables_relation, *[@follower, @followable.class, { :foo => :bar }]])
105
+ @follower.followables_relation(@followable.class, { :foo => :bar })
106
+ end
107
+ end
108
+
109
+ context "#followees_relation" do
110
+ should "call $Follow.followables_relation" do
111
+ assert_send([$Follow, :followables_relation, *[@follower, @followable.class, { :foo => :bar }]])
112
+ @follower.followees_relation(@followable.class, { :foo => :bar })
113
+ end
114
+ end
115
+
116
+ context "deleting a follower" do
117
+ setup do
118
+ @follower = ImAFollower.create
119
+ @follower.follow!(@followable)
120
+ end
121
+
122
+ should "remove follow relationships" do
123
+ assert_send([Socialization.follow_model, :remove_followables, *[@follower]])
124
+ @follower.destroy
125
+ end
126
+ end
127
+
128
+ end
129
+ end
@@ -0,0 +1,121 @@
1
+ require File.expand_path(File.dirname(__FILE__))+'/../test_helper'
2
+
3
+ class LikerTest < TestCase
4
+ include Assertions
5
+ context "Liker" do
6
+ setup do
7
+ # @liker = ImALiker.new
8
+ @liker = ImALiker.create
9
+ @likeable = ImALikeable.create
10
+ end
11
+
12
+ context "#is_liker?" do
13
+ should "return true" do
14
+ assert_true @liker.is_liker?
15
+ end
16
+ end
17
+
18
+ context "#liker?" do
19
+ should "return true" do
20
+ assert_true @liker.liker?
21
+ end
22
+ end
23
+
24
+ context "#like!" do
25
+ should "not accept non-likeables" do
26
+ assert_raises(Socialization::ArgumentError) { @liker.like!(:foo) }
27
+ end
28
+
29
+ should "call $Like.like!" do
30
+ assert_send([$Like, :like!, *[@liker, @likeable]])
31
+ @liker.like!(@likeable)
32
+ end
33
+ end
34
+
35
+ context "#unlike!" do
36
+ should "not accept non-likeables" do
37
+ assert_raises(Socialization::ArgumentError) { @liker.unlike!(:foo) }
38
+ end
39
+
40
+ should "call $Like.like!" do
41
+ Minitest::Mock.new.expect(:check, false) do
42
+ $Like.unlike!(@liker, @likeables)
43
+ end
44
+ @liker.unlike!(@likeable)
45
+ end
46
+ end
47
+
48
+ context "#toggle_like!" do
49
+ should "not accept non-likeables" do
50
+ assert_raises(Socialization::ArgumentError) { @liker.unlike!(:foo) }
51
+ end
52
+
53
+ should "unlike when likeing" do
54
+ @liker.like!(@likeable)
55
+ Minitest::Mock.new.expect(:check, true) do
56
+ @liker.likes?(@likeables)
57
+ end
58
+ Minitest::Mock.new.expect(:check, true) do
59
+ @liker.unlike!(@likeables)
60
+ end
61
+ # assert_send([@liker, :unlike!, *[@likeable]])
62
+ @liker.toggle_like!(@likeable)
63
+ end
64
+
65
+ should "like when not likeing" do
66
+ Minitest::Mock.new.expect(:check, false) do
67
+ @liker.likes?(@likeables)
68
+ end
69
+ assert_send([@liker, :like!, *[@likeable]])
70
+ @liker.toggle_like!(@likeable)
71
+ end
72
+ end
73
+
74
+ context "#likes?" do
75
+ should "not accept non-likeables" do
76
+ assert_raises(Socialization::ArgumentError) { @liker.unlike!(:foo) }
77
+ end
78
+
79
+ should "call $Like.likes?" do
80
+ Minitest::Mock.new.expect(:check, false) do
81
+ $Like.likes?(@liker, @likeables)
82
+ end
83
+ # assert_send([$Like, :likes?, *[@liker, @likeable]])
84
+ @liker.likes?(@likeable)
85
+ end
86
+ end
87
+
88
+ context "#likeables" do
89
+ should "call $Like.likeables" do
90
+ assert_send([$Like, :likeables, *[@liker, @likeable.class, { :foo => :bar }]])
91
+ @liker.likeables(@likeable.class, { :foo => :bar })
92
+ end
93
+ end
94
+
95
+ context "#likees" do
96
+ should "call $Like.likeables" do
97
+ assert_send([$Like, :likeables, *[@liker, @likeable.class, { :foo => :bar }]])
98
+ @liker.likees(@likeable.class, { :foo => :bar })
99
+ end
100
+ end
101
+
102
+ context "#likeables_relation" do
103
+ should "call $Follow.likeables_relation" do
104
+ assert_send([$Like, :likeables_relation, *[@liker, @likeable.class, { :foo => :bar }]])
105
+ @liker.likeables_relation(@likeable.class, { :foo => :bar })
106
+ end
107
+ end
108
+
109
+ context "#likees_relation" do
110
+ should "call $Follow.likeables_relation" do
111
+ assert_send([$Like, :likeables_relation, *[@liker, @likeable.class, { :foo => :bar }]])
112
+ @liker.likees_relation(@likeable.class, { :foo => :bar })
113
+ end
114
+ end
115
+
116
+ should "remove like relationships" do
117
+ assert_send([Socialization.like_model, :remove_likeables, *[@liker]])
118
+ @liker.destroy
119
+ end
120
+ end
121
+ end