flocks 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9670cef0827448591a9929ae6b1e29e9a10907d8
4
+ data.tar.gz: f44b3a80e9ba291f79472cb32f207de3e3fd2fda
5
+ SHA512:
6
+ metadata.gz: b1bee72695582429793848aa7ae8694c6f05e5f8710ae2cf14e9f79baf0ecf62afc395e4fc1c316676f57a393f70a0dbc74413ddc7167480e630b3c9b56c460d
7
+ data.tar.gz: ac2b6281eb80f9853680c5312358035be1af26e6794aafa4f25695470a7ccd1d69e9fe4722ca45f5ab7e6c8b1963fe1e374771f40e5aa1cff145744132cc768b
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in flocks.gemspec
4
+ gemspec
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2014, Byliner, Inc
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice, this
10
+ list of conditions and the following disclaimer in the documentation and/or
11
+ other materials provided with the distribution.
12
+ * Neither the name of the DUO Interactive, LLC nor the names of its contributors
13
+ may be used to endorse or promote products derived from this software without
14
+ specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,142 @@
1
+ # Flocks
2
+
3
+ Flocks is a lightweight searchable social graph that tracks a user's followers, who they are following, and who they have blocked.
4
+
5
+ Flocks uses [Redis](http://redis.io/documentation) to store the relationships.
6
+
7
+ User lists are sorted alphabetically and can be searched!
8
+
9
+ Flocks uses usernames (or any unique string identifier) when following in order to sort the following/followers lists.
10
+ By requiring usernames when establishing relationships, Flocks becomes searchable.
11
+ Flocks will return all user ids with user_ids matching the query string.
12
+ Flocks search capabilities can be used to autocomplete text fields with usernames in a user's social graph.
13
+
14
+ For example, if a user is following: 'Adam', 'Aaron', 'Addison', and 'John'
15
+
16
+ Searching for 'a' will return the ids associated with Adam, Aaron, and Addison
17
+ Searching for 'ad' will return the id associated with Adam
18
+
19
+
20
+ ## Installation
21
+
22
+ Add this line to your application's Gemfile:
23
+
24
+ gem 'flocks'
25
+
26
+ And then execute:
27
+
28
+ $ bundle
29
+
30
+ Or install it yourself as:
31
+
32
+ $ gem install flocks
33
+
34
+ ## Usage
35
+
36
+ Configure flocks:
37
+
38
+ ```ruby
39
+ Flocks.configure do |configuration|
40
+ configuration.redis = Redis.new
41
+ configuration.namespace = 'flocks'
42
+ configuration.following_key = 'following'
43
+ configuration.followers_key = 'followers'
44
+ configuration.blocked_key = 'blocked'
45
+ configuration.page_size = 25
46
+ end
47
+ ```
48
+
49
+ Use flocks:
50
+
51
+ ```ruby
52
+ require 'flocks'
53
+ => true
54
+
55
+ Flocks.configure do |configuration|
56
+ configuration.redis = Redis.new
57
+ configuration.namespace = 'flocks'
58
+ configuration.following_key = 'following'
59
+ configuration.followers_key = 'followers'
60
+ configuration.blocked_key = 'blocked'
61
+ configuration.page_size = 25
62
+ end
63
+
64
+ Flocks.new(1, 'username').follow(11, 'other_username')
65
+ => true
66
+
67
+ Flocks.new(1, 'username').following?(11)
68
+ => true
69
+
70
+ Flocks.new(11, 'other_username').following?(1)
71
+ => false
72
+
73
+ Flocks.new(11, 'other_username').follow(1, 'username')
74
+ => true
75
+
76
+ Flocks.new(11, 'other_username').following?(1)
77
+ => true
78
+
79
+ Flocks.new(1, 'username').following_count
80
+ => 1
81
+
82
+ Flocks.new(1, 'username').followers_count
83
+ => 1
84
+
85
+ Flocks.new(11, 'other_username').unfollow(1)
86
+ => true
87
+
88
+ Flocks.new(11, 'other_username').following_count
89
+ => 0
90
+
91
+ Flocks.new(1, 'username').following_count
92
+ => 1
93
+
94
+ Flocks.new(1, 'username').following
95
+ => ["11"]
96
+
97
+ Flocks.new(1, 'username').block(11)
98
+ => true
99
+
100
+ Flocks.new(11, 'username').following?(1)
101
+ => false
102
+
103
+ Flocks.new(1, 'username').blocked?(11)
104
+ => true
105
+
106
+ Flocks.new(11, 'other_username').follow(1)
107
+ => nil
108
+
109
+ Flocks.new(1, 'username').unblock(11)
110
+ => true
111
+
112
+ Flocks.new(1, 'username').blocked?(11)
113
+ => false
114
+
115
+ Flocks.new(11, 'other_username').follow(1)
116
+ => true
117
+
118
+ Flocks.new(1, 'username').follow(11)
119
+ => true
120
+
121
+ Flocks.new(1, 'username').search_following('other')
122
+ => ["11"]
123
+
124
+ Flocks.new(1, 'username').search_followers('other')
125
+ => ["11"]
126
+
127
+ Flocks.new(1, 'username').search_graph('other')
128
+ => ["11"]
129
+
130
+ ```
131
+
132
+ ## Thanks
133
+
134
+ Many thanks to [amico](https://github.com/agoragames/amico) creator [agoragames](https://github.com/agoragames). A lot of the code used was inspired by the [amico gem](https://github.com/agoragames/amico).
135
+
136
+ ## Contributing
137
+
138
+ 1. Fork it ( http://github.com/<my-github-username>/flocks/fork )
139
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
140
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
141
+ 4. Push to the branch (`git push origin my-new-feature`)
142
+ 5. Create new Pull Request
@@ -0,0 +1,11 @@
1
+ require 'bundler'
2
+ require 'bundler/gem_tasks'
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ require 'rake/testtask'
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << 'test'
8
+ t.pattern = 'test/**/*_test.rb'
9
+ end
10
+
11
+ task :default => :test
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'flocks/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "flocks"
8
+ spec.version = Flocks::VERSION
9
+ spec.authors = ["Adam Ryan"]
10
+ spec.email = ["adam.g.ryan@gmail.com"]
11
+ spec.summary = %q{Single node social relationships using redis.}
12
+ spec.description = %q{Single node social relationships using redis.}
13
+ spec.homepage = "https://github.com/byliner/flocks"
14
+ spec.license = "BSD"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "redis"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.5"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "minitest"
26
+ end
@@ -0,0 +1,23 @@
1
+ require 'redis'
2
+ require 'flocks/configuration'
3
+ require 'flocks/ordering'
4
+ require 'flocks/relationships'
5
+ require 'flocks/search'
6
+ require 'flocks/version'
7
+
8
+ module Flocks
9
+ class << self
10
+ include Configuration
11
+ include Ordering
12
+ include Search
13
+ include Relationships
14
+
15
+ attr_accessor :user_id, :username_score
16
+
17
+ def new(user_id, username = nil)
18
+ self.user_id = user_id
19
+ self.username_score = rank_username(username)
20
+ self
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,113 @@
1
+ module Flocks
2
+ # Configuration settings for Flocks.
3
+ module Configuration
4
+ # Redis instance.
5
+ attr_accessor :redis
6
+
7
+ # Flocks namespace for Redis.
8
+ attr_writer :namespace
9
+
10
+ # Key used in Redis for tracking who an individual is following.
11
+ attr_writer :following_key
12
+
13
+ # Key used in Redis for tracking the followers of an individual.
14
+ attr_writer :followers_key
15
+
16
+ # Key used in Redis for tracking who an individual blocks.
17
+ attr_writer :blocked_key
18
+
19
+ # Key used in Redis for tracking who has blocked an individual.
20
+ attr_writer :blocked_by_key
21
+
22
+ # Key used in Redis for tracking who has reciprocated a follow for an individual.
23
+ attr_writer :reciprocated_key
24
+
25
+ # Key used in Redis for tracking pending follow relationships for an individual.
26
+ attr_writer :pending_key
27
+
28
+ # Key used in Redis for tracking who an individual is awaiting approval from.
29
+ attr_writer :pending_with_key
30
+
31
+ # Key used to indicate whether or not a follow should be pending or not.
32
+ attr_writer :pending_follow
33
+
34
+ # Page size to be used when paging through the various types of relationships.
35
+ attr_writer :page_size
36
+
37
+ # Set the percision for relationship sorting granularity
38
+ attr_writer :string_score_percision
39
+
40
+ # Yield self to be able to configure Flocks with block-style configuration.
41
+ #
42
+ # Example:
43
+ #
44
+ # Flocks.configure do |configuration|
45
+ # configuration.redis = Redis.new
46
+ # configuration.namespace = 'flocks'
47
+ # configuration.following_key = 'following'
48
+ # configuration.followers_key = 'followers'
49
+ # configuration.blocked_key = 'blocked'
50
+ # configuration.blocked_by_key = 'blocked_by'
51
+ # configuration.page_size = 25
52
+ # end
53
+ def configure
54
+ yield self
55
+ end
56
+
57
+ # Flocks namespace for Redis.
58
+ #
59
+ # @return the Flocks namespace or the default of 'flocks' if not set.
60
+ def namespace
61
+ @namespace ||= 'flocks'
62
+ end
63
+
64
+ # Key used in Redis for tracking who an individual is following.
65
+ #
66
+ # @return the key used in Redis for tracking who an individual is following or the default of 'following' if not set.
67
+ def following_key
68
+ @following_key ||= 'following'
69
+ end
70
+
71
+ # Key used in Redis for tracking the followers of an individual.
72
+ #
73
+ # @return the key used in Redis for tracking the followers of an individual or the default of 'followers' if not set.
74
+ def followers_key
75
+ @followers_key ||= 'followers'
76
+ end
77
+
78
+ # Key used in Redis for tracking who an individual blocks.
79
+ #
80
+ # @return the key used in Redis for tracking who an individual blocks or the default of 'blocked' if not set.
81
+ def blocked_key
82
+ @blocked_key ||= 'blocked'
83
+ end
84
+
85
+ # Key used in Redis for tracking who has blocked an individual.
86
+ #
87
+ # @return the key used in Redis for tracking who has blocked an individual or the default of 'blocked_by' if not set.
88
+ def blocked_by_key
89
+ @blocked_by_key ||= 'blocked_by'
90
+ end
91
+
92
+ # Key used in Redis for tracking who has reciprocated a follow for an individual.
93
+ #
94
+ # @return the key used in Redis for tracking who has reciprocated a follow for an individual or the default of 'reciprocated' if not set.
95
+ def reciprocated_key
96
+ @reciprocated_key ||= 'reciprocated'
97
+ end
98
+
99
+ # Page size to be used when paging through the various types of relationships.
100
+ #
101
+ # @return the page size to be used when paging through the various types of relationships or the default of 25 if not set.
102
+ def page_size
103
+ @page_size ||= 25
104
+ end
105
+
106
+ # Number of characters to be used when scoring a username for indexing in redis
107
+ #
108
+ # @return the scoring percision
109
+ def string_score_percision
110
+ @string_score_percision ||= 5
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,33 @@
1
+ module Flocks
2
+ module Ordering
3
+ def rank_username(username)
4
+ # Selects the number of characters to be evaluated for sorting
5
+ percision_index = string_score_percision - 1
6
+
7
+ # Base score
8
+ score = 0
9
+
10
+ # Get the first 5 characters in an array
11
+ characters = username.to_s.downcase[0..percision_index].split('')
12
+
13
+ # If the username is short, tack on the lowest ascii value
14
+ characters << '0' until characters.size == string_score_percision
15
+
16
+ # Reverse them for easy multiplication scoring
17
+ characters.reverse.each_with_index do |char, i|
18
+
19
+ # Use the mutiplier, increase magnitude for weighting first letters more
20
+ # multiplier = (character_multiplier[0..(i + 1)].to_i)
21
+
22
+ multiplier = 10 ** i
23
+ # Square the multiplier to avoid large ascii values from thwrowing off calculations
24
+ char_score = "#{char}"[0].ord * multiplier * multiplier
25
+
26
+ # Aggregate the swcore
27
+ score += char_score
28
+ end
29
+
30
+ score
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,87 @@
1
+ module Flocks
2
+ module Relationships
3
+
4
+ def relationship_following_key
5
+ "#{following_key}/#{user_id}"
6
+ end
7
+
8
+ def relationship_followers_key(id = user_id)
9
+ "#{followers_key}/#{id}"
10
+ end
11
+
12
+ def relationship_blocked_key
13
+ "#{blocked_key}/#{user_id}"
14
+ end
15
+
16
+ def follow(other_user_id, other_username)
17
+ return if (user_id == other_user_id) || (blocked? other_user_id)
18
+
19
+ other_username_score = rank_username(other_username)
20
+ redis.zadd relationship_following_key, other_username_score, other_user_id
21
+ redis.zadd relationship_followers_key(other_user_id), username_score, user_id
22
+ end
23
+
24
+ def unfollow(other_user_id)
25
+ redis.zrem relationship_following_key, other_user_id
26
+ redis.zrem relationship_followers_key(other_user_id), user_id
27
+ end
28
+
29
+ def following(page = 0, limit = 0)
30
+ # Without arguments returns the full set
31
+ start, stop = bounds(page, limit)
32
+ redis.zrange relationship_following_key, start, stop
33
+ end
34
+
35
+ def followers(page = 0, limit= 0)
36
+ start, stop = bounds(page, limit)
37
+ redis.zrange relationship_followers_key(user_id), start, stop
38
+ end
39
+
40
+ def following?(other_user_id)
41
+ following.include? other_user_id.to_s
42
+ end
43
+
44
+ def following_count
45
+ redis.zcard relationship_following_key
46
+ end
47
+
48
+ def followers_count
49
+ redis.zcard relationship_followers_key
50
+ end
51
+
52
+ def following_page_count(limit = page_size)
53
+ (following_count.to_f / limit.to_f).ceil
54
+ end
55
+
56
+ def followers_page_count(limit = page_size)
57
+ (followers_count.to_f / limit.to_f).ceil
58
+ end
59
+
60
+ def block(other_user_id)
61
+ # Unfollow
62
+ unfollow other_user_id
63
+ self.new(other_user_id).unfollow user_id
64
+
65
+ # Block
66
+ redis.sadd relationship_blocked_key, other_user_id
67
+ end
68
+
69
+ def unblock(other_user_id)
70
+ redis.srem relationship_blocked_key, other_user_id
71
+ end
72
+
73
+ def blocked
74
+ redis.smembers relationship_blocked_key
75
+ end
76
+
77
+ def blocked?(other_user_id)
78
+ blocked.include? other_user_id.to_s
79
+ end
80
+
81
+ protected
82
+
83
+ def bounds(page, limit)
84
+ [(page - 1) * limit, (page * limit) - 1]
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,37 @@
1
+ module Flocks
2
+ module Search
3
+
4
+ # Search a user's list of following
5
+ def search_following(query)
6
+ redis.zrangebyscore relationship_following_key, start_score(query), stop_score(query)
7
+ end
8
+
9
+ # Search a user's list of followers
10
+ def search_followers(query)
11
+ redis.zrangebyscore relationship_followers_key, start_score(query), stop_score(query)
12
+ end
13
+
14
+ # Search a user's entire social graph
15
+ def search_graph(query)
16
+ (search_following(query) + search_followers(query)).uniq
17
+ end
18
+
19
+ protected
20
+
21
+ # Set constraints to return relevent results
22
+ # Starting score for redis zrangebyscore
23
+ def start_score(query)
24
+ rank_username(query)
25
+ end
26
+
27
+ # 'aaa' -> 'aab'
28
+ # Ending score for redis zrangebyscore
29
+ def stop_score(query)
30
+ query_array = query.chars
31
+ last_char = (query_array.pop.ord + 1).chr
32
+ stop_name = query_array.push(last_char).join('')
33
+ rank_username(stop_name)
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module Flocks
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ class ConfigurationTest < MiniTest::Test
4
+
5
+ def test_configuration
6
+ Flocks.configure do |config|
7
+ config.redis = Redis.new
8
+ config.namespace = 'flocks_test'
9
+ config.following_key = 'following_test'
10
+ config.followers_key = 'followers_test'
11
+ config.blocked_key = 'blocked_test'
12
+ config.blocked_by_key = 'blocked_by_test'
13
+ config.page_size = 50
14
+ end
15
+
16
+ assert_equal 'flocks_test', Flocks.namespace
17
+ assert_equal 'following_test', Flocks.following_key
18
+ assert_equal 'followers_test', Flocks.followers_key
19
+ assert_equal 'blocked_test', Flocks.blocked_key
20
+ assert_equal 'blocked_by_test', Flocks.blocked_by_key
21
+ assert_equal 50, Flocks.page_size
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ require 'test_helper'
2
+
3
+ class FlocksTest < MiniTest::Test
4
+
5
+ def test_initialization
6
+ flock = Flocks.new(1, 1)
7
+ assert_equal 1, flock.user_id
8
+ assert_equal 4948484848, flock.username_score
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ require 'test_helper'
2
+
3
+ class OrderingTest < MiniTest::Test
4
+ include Flocks::Ordering
5
+ include Flocks::Configuration
6
+
7
+ def test_score_string_extension
8
+ # ASCII 'd' == 100, summed up in the scorer == 10101010100
9
+ assert_equal 10101010100, rank_username('ddddd')
10
+ end
11
+
12
+ end
@@ -0,0 +1,55 @@
1
+ require 'test_helper'
2
+
3
+ class RelationshipsTest < MiniTest::Test
4
+
5
+ def test_follow_and_unfollow
6
+ flock = Flocks.new(1, 'username')
7
+ flock.follow(2, 'other_username')
8
+ assert flock.following?(2)
9
+
10
+ flock.unfollow(2)
11
+ refute flock.following?(2)
12
+ end
13
+
14
+ def test_following_and_following_count
15
+ flock = Flocks.new(1, 'username')
16
+ flock.follow(2, 'other_username')
17
+ assert_equal ['2'], flock.following
18
+ assert_equal 1, flock.following_count
19
+ end
20
+
21
+ def test_followers_and_followers_count
22
+ flock = Flocks.new(1, 'username')
23
+ flock.follow(2, 'other_username')
24
+
25
+ other_flock = Flocks.new(2, 'other_username')
26
+ assert_equal ['1'], other_flock.followers
27
+ assert_equal 1, other_flock.followers_count
28
+ end
29
+
30
+ def test_following_page_count
31
+ flock = Flocks.new(1, 'username')
32
+ (2..40).to_a.each { |i| flock.follow(i, "#{i}") }
33
+ assert_equal 2, flock.following_page_count
34
+ end
35
+
36
+ def test_followers_page_count
37
+ (2..40).to_a.each { |i| Flocks.new(i, "#{i}").follow(1, "username") }
38
+ flock = Flocks.new(1, 'username')
39
+ assert_equal 2, flock.followers_page_count
40
+ end
41
+
42
+ def test_block_blocked_and_unblock
43
+ flock = Flocks.new(1, 'username')
44
+ flock.follow(2, 'other_username')
45
+
46
+ flock.block(2)
47
+ assert_equal ['2'], flock.blocked
48
+ assert flock.blocked? 2
49
+ refute Flocks.new(2).following? 1
50
+
51
+ flock.unblock(2)
52
+ assert_equal ([]), flock.blocked
53
+ end
54
+
55
+ end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ class SearchTest < MiniTest::Test
4
+
5
+ def test_search_following
6
+ flock = Flocks.new(1, 'username')
7
+ flock.follow(2, 'other_username')
8
+ flock.follow(3, 'other_username2')
9
+ flock.follow(4, 'dissimilar_username')
10
+ results = flock.search_following('other')
11
+
12
+ assert_equal ['2', '3'], results
13
+ end
14
+
15
+ def test_search_followers
16
+ Flocks.new(2, 'other_username').follow(1, 'username')
17
+ Flocks.new(3, 'other_username2').follow(1, 'username')
18
+ Flocks.new(4, 'disssimilar_username').follow(1, 'username')
19
+
20
+ flock = Flocks.new(1, 'username')
21
+ results = flock.search_followers('other')
22
+ assert_equal ['2', '3'], results
23
+ end
24
+
25
+ def test_search_graph
26
+ Flocks.new(1, 'username').follow(2, 'other_username')
27
+ Flocks.new(2, 'other_username').follow(1, 'username')
28
+ Flocks.new(1, 'username').follow(3, 'other_username3')
29
+ Flocks.new(4, 'other_username4').follow(1, 'username')
30
+ Flocks.new(5, 'disssimilar_username').follow(1, 'username')
31
+
32
+ flock = Flocks.new(1, 'username')
33
+ results = flock.search_graph('other')
34
+ assert_equal ['2', '3', '4'], results
35
+ end
36
+ end
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.require :test
4
+
5
+ require 'minitest/autorun'
6
+ require 'redis'
7
+ require 'flocks'
8
+
9
+ # Support files
10
+ Dir["#{File.expand_path(File.dirname(__FILE__))}/support/*.rb"].each do |file|
11
+ require file
12
+ end
13
+
14
+ class MiniTest::Test
15
+ def setup
16
+ Flocks.configure do |config|
17
+ config.redis = Redis.new
18
+ config.namespace = 'flocks'
19
+ config.following_key = 'following'
20
+ config.followers_key = 'followers'
21
+ config.blocked_key = 'blocked'
22
+ config.blocked_by_key = 'blocked_by'
23
+ config.page_size = 25
24
+ end
25
+
26
+ Flocks.redis.flushdb
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flocks
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Adam Ryan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: redis
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Single node social relationships using redis.
70
+ email:
71
+ - adam.g.ryan@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - flocks.gemspec
82
+ - lib/flocks.rb
83
+ - lib/flocks/configuration.rb
84
+ - lib/flocks/ordering.rb
85
+ - lib/flocks/relationships.rb
86
+ - lib/flocks/search.rb
87
+ - lib/flocks/version.rb
88
+ - test/flocks/configuration_test.rb
89
+ - test/flocks/flocks_test.rb
90
+ - test/flocks/ordering_test.rb
91
+ - test/flocks/relationships_test.rb
92
+ - test/flocks/search_test.rb
93
+ - test/test_helper.rb
94
+ homepage: https://github.com/byliner/flocks
95
+ licenses:
96
+ - BSD
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 2.2.0
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Single node social relationships using redis.
118
+ test_files:
119
+ - test/flocks/configuration_test.rb
120
+ - test/flocks/flocks_test.rb
121
+ - test/flocks/ordering_test.rb
122
+ - test/flocks/relationships_test.rb
123
+ - test/flocks/search_test.rb
124
+ - test/test_helper.rb