Commit 899cf25d595bcca2b9d2594ba4351a40ef407e38

Authored by tcocca
1 parent 5a4f3582

pulled in arthurgeeks changes to remove trailing white space

@@ -19,7 +19,7 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION @@ -19,7 +19,7 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 19 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 21
22 -The major design pattern of this plugin was abstracted from Peter Jackson's VoteFu, which is subject to the same license. 22 +The major design pattern of this plugin was abstracted from Peter Jackson's VoteFu, which is subject to the same license.
23 Here is the original copyright notice for VoteFu: 23 Here is the original copyright notice for VoteFu:
24 24
25 Copyright (c) 2008 Peter Jackson (peteonrails.com) 25 Copyright (c) 2008 Peter Jackson (peteonrails.com)
@@ -28,7 +28,7 @@ Make your model(s) that you want to allow to be followed acts_as_followable, jus @@ -28,7 +28,7 @@ Make your model(s) that you want to allow to be followed acts_as_followable, jus
28 acts_as_followable 28 acts_as_followable
29 ... 29 ...
30 end 30 end
31 - 31 +
32 class Book < ActiveRecord::Base 32 class Book < ActiveRecord::Base
33 ... 33 ...
34 acts_as_followable 34 acts_as_followable
@@ -64,7 +64,7 @@ To get follow records that have not been blocked use the following @@ -64,7 +64,7 @@ To get follow records that have not been blocked use the following
64 user.all_follows # returns an array of Follow records 64 user.all_follows # returns an array of Follow records
65 65
66 To get all of the records that an object is following that have not been blocked use the following 66 To get all of the records that an object is following that have not been blocked use the following
67 - user.all_following 67 + user.all_following
68 # Returns an array of every followed object for the user, this can be a collection of different object types, eg: User, Book 68 # Returns an array of every followed object for the user, this can be a collection of different object types, eg: User, Book
69 69
70 To get all Follow records by a certain type use the following 70 To get all Follow records by a certain type use the following
@@ -82,18 +82,18 @@ There is also a method_missing to accomplish the exact same thing a following_by @@ -82,18 +82,18 @@ There is also a method_missing to accomplish the exact same thing a following_by
82 82
83 To get all the followers of a model that acts_as_followable 83 To get all the followers of a model that acts_as_followable
84 book.followers # Returns an array of all the followers for that book, a collection of different object types (eg. type User or type Book) 84 book.followers # Returns an array of all the followers for that book, a collection of different object types (eg. type User or type Book)
85 - 85 +
86 To get just the number of follows use 86 To get just the number of follows use
87 book.followers_count 87 book.followers_count
88 - 88 +
89 To see is a model that acts_as_followable is followed by a model that acts_as_follower use the following 89 To see is a model that acts_as_followable is followed by a model that acts_as_follower use the following
90 book.followed_by?(user) 90 book.followed_by?(user)
91 - 91 +
92 # Returns true if the current instance is followed by the passed record 92 # Returns true if the current instance is followed by the passed record
93 # Returns false if the current instance is blocked by the passed record or no follow is found 93 # Returns false if the current instance is blocked by the passed record or no follow is found
94 94
95 To block a follower call the following 95 To block a follower call the following
96 - book.block(user) 96 + book.block(user)
97 # Blocks the user from appearing in the followers list, and blocks the book from appearing in the user.all_follows or user.all_following lists 97 # Blocks the user from appearing in the followers list, and blocks the book from appearing in the user.all_follows or user.all_following lists
98 98
99 To unblock is just as simple 99 To unblock is just as simple
@@ -105,7 +105,7 @@ To get all blocked records @@ -105,7 +105,7 @@ To get all blocked records
105 If you only need the number of blocks use the count method provided 105 If you only need the number of blocks use the count method provided
106 book.blocked_followers_count 106 book.blocked_followers_count
107 107
108 -Unblocking deletes all records of that follow, instead of just the :blocked attribute => false the follow is deleted. So, a user would need to try and follow the book again. 108 +Unblocking deletes all records of that follow, instead of just the :blocked attribute => false the follow is deleted. So, a user would need to try and follow the book again.
109 I would like to hear thoughts on this, I may change this to make the follow as :blocked => false instead of deleting the record. 109 I would like to hear thoughts on this, I may change this to make the follow as :blocked => false instead of deleting the record.
110 110
111 --- 111 ---
@@ -114,12 +114,12 @@ I would like to hear thoughts on this, I may change this to make the follow as : @@ -114,12 +114,12 @@ I would like to hear thoughts on this, I may change this to make the follow as :
114 114
115 The Follow model has a set of named_scope's. In case you want to interface directly with the Follow model you can use them. 115 The Follow model has a set of named_scope's. In case you want to interface directly with the Follow model you can use them.
116 Follow.unblocked # returns all "unblocked" follow records 116 Follow.unblocked # returns all "unblocked" follow records
117 - 117 +
118 Follow.blocked # returns all "blocked" follow records 118 Follow.blocked # returns all "blocked" follow records
119 - 119 +
120 Follow.descending # returns all records in a descending order based on created_at datetime 120 Follow.descending # returns all records in a descending order based on created_at datetime
121 121
122 -This method pulls all records created after a certain date. The default is 2 weeks but it takes an optional parameter. 122 +This method pulls all records created after a certain date. The default is 2 weeks but it takes an optional parameter.
123 Follow.recent 123 Follow.recent
124 Follow.recent(4.weeks.ago) 124 Follow.recent(4.weeks.ago)
125 125
@@ -145,7 +145,7 @@ If you have updates or patches or want to contribute I would love to see what yo @@ -145,7 +145,7 @@ If you have updates or patches or want to contribute I would love to see what yo
145 145
146 146
147 == Note on Patches/Pull Requests 147 == Note on Patches/Pull Requests
148 - 148 +
149 * Fork the project. 149 * Fork the project.
150 * Make your feature addition or bug fix. 150 * Make your feature addition or bug fix.
151 * Add tests for it. This is important so I don't break it in a future version unintentionally (acts_as_follower uses Shoulda and Factory Girl) 151 * Add tests for it. This is important so I don't break it in a future version unintentionally (acts_as_follower uses Shoulda and Factory Girl)
generators/acts_as_follower/USAGE
1 Description: 1 Description:
2 run ./script/generate acts_as_follower 2 run ./script/generate acts_as_follower
3 - 3 +
4 no need to specify a name after acts_as_follower as you can not change the model name from Follow 4 no need to specify a name after acts_as_follower as you can not change the model name from Follow
5 the acts_as_follower_migration file will be created in db/migrate 5 the acts_as_follower_migration file will be created in db/migrate
6 \ No newline at end of file 6 \ No newline at end of file
generators/acts_as_follower/acts_as_follower_generator.rb
@@ -3,11 +3,11 @@ class ActsAsFollowerGenerator &lt; Rails::Generator::Base @@ -3,11 +3,11 @@ class ActsAsFollowerGenerator &lt; Rails::Generator::Base
3 record do |m| 3 record do |m|
4 m.directory "app/models" 4 m.directory "app/models"
5 m.template "model.rb", "app/models/follow.rb" 5 m.template "model.rb", "app/models/follow.rb"
6 - 6 +
7 m.migration_template 'migration.rb', 'db/migrate' 7 m.migration_template 'migration.rb', 'db/migrate'
8 end 8 end
9 end 9 end
10 - 10 +
11 def file_name 11 def file_name
12 "acts_as_follower_migration" 12 "acts_as_follower_migration"
13 end 13 end
generators/acts_as_follower/templates/migration.rb
@@ -10,7 +10,7 @@ class ActsAsFollowerMigration &lt; ActiveRecord::Migration @@ -10,7 +10,7 @@ class ActsAsFollowerMigration &lt; ActiveRecord::Migration
10 add_index :follows, ["follower_id", "follower_type"], :name => "fk_follows" 10 add_index :follows, ["follower_id", "follower_type"], :name => "fk_follows"
11 add_index :follows, ["followable_id", "followable_type"], :name => "fk_followables" 11 add_index :follows, ["followable_id", "followable_type"], :name => "fk_followables"
12 end 12 end
13 - 13 +
14 def self.down 14 def self.down
15 drop_table :follows 15 drop_table :follows
16 end 16 end
generators/acts_as_follower/templates/model.rb
1 class Follow < ActiveRecord::Base 1 class Follow < ActiveRecord::Base
2 - 2 +
3 named_scope :for_follower, lambda { |*args| {:conditions => ["follower_id = ? AND follower_type = ?", args.first.id, args.first.type.name]} } 3 named_scope :for_follower, lambda { |*args| {:conditions => ["follower_id = ? AND follower_type = ?", args.first.id, args.first.type.name]} }
4 named_scope :for_followable, lambda { |*args| {:conditions => ["followable_id = ? AND followable_type = ?", args.first.id, args.first.type.name]} } 4 named_scope :for_followable, lambda { |*args| {:conditions => ["followable_id = ? AND followable_type = ?", args.first.id, args.first.type.name]} }
5 named_scope :recent, lambda { |*args| {:conditions => ["created_at > ?", (args.first || 2.weeks.ago).to_s(:db)]} } 5 named_scope :recent, lambda { |*args| {:conditions => ["created_at > ?", (args.first || 2.weeks.ago).to_s(:db)]} }
6 named_scope :descending, :order => "created_at DESC" 6 named_scope :descending, :order => "created_at DESC"
7 named_scope :unblocked, :conditions => {:blocked => false} 7 named_scope :unblocked, :conditions => {:blocked => false}
8 named_scope :blocked, :conditions => {:blocked => true} 8 named_scope :blocked, :conditions => {:blocked => true}
9 - 9 +
10 # NOTE: Follows belong to the "followable" interface, and also to followers 10 # NOTE: Follows belong to the "followable" interface, and also to followers
11 belongs_to :followable, :polymorphic => true 11 belongs_to :followable, :polymorphic => true
12 belongs_to :follower, :polymorphic => true 12 belongs_to :follower, :polymorphic => true
13 - 13 +
14 def block! 14 def block!
15 self.update_attribute(:blocked, true) 15 self.update_attribute(:blocked, true)
16 end 16 end
17 - 17 +
18 end 18 end
19 19
lib/acts_as_followable.rb
1 -require File.dirname(__FILE__) + '/follower_lib'  
2 -  
3 -module ActiveRecord #:nodoc:  
4 - module Acts #:nodoc:  
5 - module Followable  
6 -  
7 - def self.included(base)  
8 - base.extend ClassMethods  
9 - base.class_eval do  
10 - include FollowerLib  
11 - end  
12 - end  
13 -  
14 - module ClassMethods  
15 - def acts_as_followable  
16 - has_many :followings, :as => :followable, :dependent => :destroy, :class_name => 'Follow'  
17 - include ActiveRecord::Acts::Followable::InstanceMethods  
18 - end  
19 - end  
20 -  
21 -  
22 - module InstanceMethods  
23 -  
24 - # Returns the number of followers a record has.  
25 - def followers_count  
26 - self.followings.unblocked.count 1 +require File.dirname(__FILE__) + '/follower_lib'
  2 +
  3 +module ActiveRecord #:nodoc:
  4 + module Acts #:nodoc:
  5 + module Followable
  6 +
  7 + def self.included(base)
  8 + base.extend ClassMethods
  9 + base.class_eval do
  10 + include FollowerLib
27 end 11 end
28 - 12 + end
  13 +
  14 + module ClassMethods
  15 + def acts_as_followable
  16 + has_many :followings, :as => :followable, :dependent => :destroy, :class_name => 'Follow'
  17 + include ActiveRecord::Acts::Followable::InstanceMethods
  18 + end
  19 + end
  20 +
  21 +
  22 + module InstanceMethods
  23 +
  24 + # Returns the number of followers a record has.
  25 + def followers_count
  26 + self.followings.unblocked.count
  27 + end
  28 +
29 def blocked_followers_count 29 def blocked_followers_count
30 self.followings.blocked.count 30 self.followings.blocked.count
31 - end  
32 -  
33 - # Returns the following records.  
34 - def followers  
35 - self.followings.unblocked.all(:include => [:follower]).collect{|f| f.follower}  
36 end 31 end
37 - 32 +
  33 + # Returns the following records.
  34 + def followers
  35 + self.followings.unblocked.all(:include => [:follower]).collect{|f| f.follower}
  36 + end
  37 +
38 def blocks 38 def blocks
39 self.followings.blocked.all(:include => [:follower]).collect{|f| f.follower} 39 self.followings.blocked.all(:include => [:follower]).collect{|f| f.follower}
40 - end  
41 - 40 + end
  41 +
42 # Returns true if the current instance is followed by the passed record 42 # Returns true if the current instance is followed by the passed record
43 - # Returns false if the current instance is blocked by the passed record or no follow is found  
44 - def followed_by?(follower) 43 + # Returns false if the current instance is blocked by the passed record or no follow is found
  44 + def followed_by?(follower)
45 f = get_follow_for(follower) 45 f = get_follow_for(follower)
46 - (f && !f.blocked?) ? true : false 46 + (f && !f.blocked?) ? true : false
47 end 47 end
48 - 48 +
49 def block(follower) 49 def block(follower)
50 get_follow_for(follower) ? block_existing_follow(follower) : block_future_follow(follower) 50 get_follow_for(follower) ? block_existing_follow(follower) : block_future_follow(follower)
51 end 51 end
52 - 52 +
53 def unblock(follower) 53 def unblock(follower)
54 get_follow_for(follower).try(:delete) 54 get_follow_for(follower).try(:delete)
55 end 55 end
56 - 56 +
57 private 57 private
58 - 58 +
59 def get_follow_for(follower) 59 def get_follow_for(follower)
60 Follow.find(:first, :conditions => ["followable_id = ? AND followable_type = ? AND follower_id = ? AND follower_type = ?", self.id, parent_class_name(self), follower.id, parent_class_name(follower)]) 60 Follow.find(:first, :conditions => ["followable_id = ? AND followable_type = ? AND follower_id = ? AND follower_type = ?", self.id, parent_class_name(self), follower.id, parent_class_name(follower)])
61 - end  
62 - 61 + end
  62 +
63 def block_future_follow(follower) 63 def block_future_follow(follower)
64 follows.create(:followable => self, :follower => follower, :blocked => true) 64 follows.create(:followable => self, :follower => follower, :blocked => true)
65 end 65 end
66 - 66 +
67 def block_existing_follow(follower) 67 def block_existing_follow(follower)
68 get_follow_for(follower).block! 68 get_follow_for(follower).block!
69 end 69 end
70 -  
71 - end  
72 -  
73 - end  
74 - end 70 +
  71 + end
  72 +
  73 + end
  74 + end
75 end 75 end
lib/acts_as_follower.rb
1 -require File.dirname(__FILE__) + '/follower_lib'  
2 -  
3 -module ActiveRecord #:nodoc:  
4 - module Acts #:nodoc:  
5 - module Follower  
6 -  
7 - def self.included(base)  
8 - base.extend ClassMethods  
9 - base.class_eval do  
10 - include FollowerLib  
11 - end  
12 - end  
13 -  
14 - module ClassMethods  
15 - def acts_as_follower  
16 - has_many :follows, :as => :follower, :dependent => :destroy  
17 - include ActiveRecord::Acts::Follower::InstanceMethods  
18 - end  
19 - end  
20 -  
21 - module InstanceMethods  
22 -  
23 - # Returns true if this instance is following the object passed as an argument.  
24 - def following?(followable)  
25 - 0 < Follow.unblocked.count(:all, :conditions => [  
26 - "follower_id = ? AND follower_type = ? AND followable_id = ? AND followable_type = ?",  
27 - self.id, parent_class_name(self), followable.id, parent_class_name(followable)  
28 - ])  
29 - end  
30 -  
31 - # Returns the number of objects this instance is following.  
32 - def follow_count  
33 - Follow.unblocked.count(:all, :conditions => ["follower_id = ? AND follower_type = ?", self.id, parent_class_name(self)])  
34 - end  
35 -  
36 - # Creates a new follow record for this instance to follow the passed object.  
37 - # Does not allow duplicate records to be created.  
38 - def follow(followable)  
39 - follow = get_follow(followable)  
40 - unless follow  
41 - Follow.create(:followable => followable, :follower => self)  
42 - end  
43 - end  
44 -  
45 - # Deletes the follow record if it exists.  
46 - def stop_following(followable)  
47 - follow = get_follow(followable)  
48 - if follow  
49 - follow.destroy  
50 - end  
51 - end  
52 -  
53 - # Returns the follow records related to this instance by type.  
54 - def follows_by_type(followable_type)  
55 - Follow.unblocked.find(:all, :include => [:followable], :conditions => ["follower_id = ? AND follower_type = ? AND followable_type = ?", self.id, parent_class_name(self), followable_type])  
56 - end  
57 -  
58 - # Returns the follow records related to this instance with the followable included.  
59 - def all_follows  
60 - self.follows.unblocked.all(:include => :followable)  
61 - end  
62 -  
63 - # Returns the actual records which this instance is following.  
64 - def all_following  
65 - all_follows.collect{ |f| f.followable }  
66 - end  
67 -  
68 - # Returns the actual records of a particular type which this record is following.  
69 - def following_by_type(followable_type)  
70 - follows_by_type(followable_type).collect{ |f| f.followable }  
71 - end  
72 -  
73 - def following_by_type_count(followable_type)  
74 - Follow.unblocked.count(:all, :conditions => ["follower_id = ? AND follower_type = ? AND followable_type = ?", self.id, parent_class_name(self), followable_type])  
75 - end  
76 -  
77 - # Allows magic names on following_by_type  
78 - # e.g. following_users == following_by_type('User')  
79 - def method_missing(m, *args)  
80 - if m.to_s[/following_(.+)_count/]  
81 - following_by_type_count($1.singularize.classify)  
82 - elsif m.to_s[/following_(.+)/]  
83 - following_by_type($1.singularize.classify)  
84 - else  
85 - super  
86 - end  
87 - end  
88 -  
89 - private  
90 -  
91 - # Returns a follow record for the current instance and followable object.  
92 - def get_follow(followable)  
93 - Follow.unblocked.find(:first, :conditions => ["follower_id = ? AND follower_type = ? AND followable_id = ? AND followable_type = ?", self.id, parent_class_name(self), followable.id, parent_class_name(followable)])  
94 - end  
95 -  
96 - end  
97 -  
98 - end  
99 - end  
100 -end 1 +require File.dirname(__FILE__) + '/follower_lib'
  2 +
  3 +module ActiveRecord #:nodoc:
  4 + module Acts #:nodoc:
  5 + module Follower
  6 +
  7 + def self.included(base)
  8 + base.extend ClassMethods
  9 + base.class_eval do
  10 + include FollowerLib
  11 + end
  12 + end
  13 +
  14 + module ClassMethods
  15 + def acts_as_follower
  16 + has_many :follows, :as => :follower, :dependent => :destroy
  17 + include ActiveRecord::Acts::Follower::InstanceMethods
  18 + end
  19 + end
  20 +
  21 + module InstanceMethods
  22 +
  23 + # Returns true if this instance is following the object passed as an argument.
  24 + def following?(followable)
  25 + 0 < Follow.unblocked.count(:all, :conditions => [
  26 + "follower_id = ? AND follower_type = ? AND followable_id = ? AND followable_type = ?",
  27 + self.id, parent_class_name(self), followable.id, parent_class_name(followable)
  28 + ])
  29 + end
  30 +
  31 + # Returns the number of objects this instance is following.
  32 + def follow_count
  33 + Follow.unblocked.count(:all, :conditions => ["follower_id = ? AND follower_type = ?", self.id, parent_class_name(self)])
  34 + end
  35 +
  36 + # Creates a new follow record for this instance to follow the passed object.
  37 + # Does not allow duplicate records to be created.
  38 + def follow(followable)
  39 + follow = get_follow(followable)
  40 + unless follow
  41 + Follow.create(:followable => followable, :follower => self)
  42 + end
  43 + end
  44 +
  45 + # Deletes the follow record if it exists.
  46 + def stop_following(followable)
  47 + follow = get_follow(followable)
  48 + if follow
  49 + follow.destroy
  50 + end
  51 + end
  52 +
  53 + # Returns the follow records related to this instance by type.
  54 + def follows_by_type(followable_type)
  55 + Follow.unblocked.find(:all, :include => [:followable], :conditions => ["follower_id = ? AND follower_type = ? AND followable_type = ?", self.id, parent_class_name(self), followable_type])
  56 + end
  57 +
  58 + # Returns the follow records related to this instance with the followable included.
  59 + def all_follows
  60 + self.follows.unblocked.all(:include => :followable)
  61 + end
  62 +
  63 + # Returns the actual records which this instance is following.
  64 + def all_following
  65 + all_follows.collect{ |f| f.followable }
  66 + end
  67 +
  68 + # Returns the actual records of a particular type which this record is following.
  69 + def following_by_type(followable_type)
  70 + follows_by_type(followable_type).collect{ |f| f.followable }
  71 + end
  72 +
  73 + # Allows magic names on following_by_type
  74 + # e.g. following_users == following_by_type('User')
  75 + def method_missing(m, *args)
  76 + if m.to_s[/following_(.+)/]
  77 + following_by_type($1.singularize.classify)
  78 + else
  79 + super
  80 + end
  81 + end
  82 +
  83 + private
  84 +
  85 + # Returns a follow record for the current instance and followable object.
  86 + def get_follow(followable)
  87 + Follow.unblocked.find(:first, :conditions => ["follower_id = ? AND follower_type = ? AND followable_id = ? AND followable_type = ?", self.id, parent_class_name(self), followable.id, parent_class_name(followable)])
  88 + end
  89 +
  90 + end
  91 +
  92 + end
  93 + end
  94 +end
lib/follower_lib.rb
1 module FollowerLib 1 module FollowerLib
2 - 2 +
3 private 3 private
4 - 4 +
5 # Retrieves the parent class name if using STI. 5 # Retrieves the parent class name if using STI.
6 def parent_class_name(obj) 6 def parent_class_name(obj)
7 if obj.class.superclass != ActiveRecord::Base 7 if obj.class.superclass != ActiveRecord::Base
@@ -9,5 +9,5 @@ module FollowerLib @@ -9,5 +9,5 @@ module FollowerLib
9 end 9 end
10 return obj.class.name 10 return obj.class.name
11 end 11 end
12 - 12 +
13 end 13 end
1 -Testing  
2 -==============  
3 -  
4 -Tests are written with Shoulda on top of Test::Unit and Factory Girl is used instead of fixtures. Tests are run using rake.  
5 -Test can either be run against a MySQL database or the faster in-memory SQLite3.  
6 -  
7 -  
8 -MySQL  
9 -=======  
10 -  
11 -1. Create a new Rails app.  
12 -2. Install acts_as_follower as a plugin.  
13 -3. Copy the database config within the plugin:  
14 - cp test/database.yml.example test/database.yml  
15 -4. Create a database as specified in test/database.yml.  
16 -5. Run the tests:  
17 - rake test  
18 -  
19 -  
20 -SQLite3  
21 -=======  
22 -  
23 -1. Create a new Rails app.  
24 -2. Install acts_as_follower as a plugin.  
25 -3. Copy the database config within the plugin:  
26 - cp test/database.yml.example test/database.yml  
27 -4. Install the sqlite3 library (if you don't have it already):  
28 - sudo gem install sqlite3-ruby  
29 -5. Run the tests:  
30 - DB=sqlite3 rake test  
31 -  
32 -  
33 -Coverage  
34 -=======  
35 -  
36 -Test coverage can be calculated using Rcov. Make sure you have the rcov gem installed.  
37 -  
38 -Again in the acts_as_follower directory:  
39 -  
40 -rake rcov:gen # For mysql  
41 -  
42 -or:  
43 -  
44 -rake rcov:gen DB=sqlite3 # For sqlite  
45 -  
46 -The coverage will now be available in the test/coverage directory.  
47 -  
48 -rake rcov:clobber will delete the coverage directory. 1 +Testing
  2 +==============
  3 +
  4 +Tests are written with Shoulda on top of Test::Unit and Factory Girl is used instead of fixtures. Tests are run using rake.
  5 +Test can either be run against a MySQL database or the faster in-memory SQLite3.
  6 +
  7 +
  8 +MySQL
  9 +=======
  10 +
  11 +1. Create a new Rails app.
  12 +2. Install acts_as_follower as a plugin.
  13 +3. Copy the database config within the plugin:
  14 + cp test/database.yml.example test/database.yml
  15 +4. Create a database as specified in test/database.yml.
  16 +5. Run the tests:
  17 + rake test
  18 +
  19 +
  20 +SQLite3
  21 +=======
  22 +
  23 +1. Create a new Rails app.
  24 +2. Install acts_as_follower as a plugin.
  25 +3. Copy the database config within the plugin:
  26 + cp test/database.yml.example test/database.yml
  27 +4. Install the sqlite3 library (if you don't have it already):
  28 + sudo gem install sqlite3-ruby
  29 +5. Run the tests:
  30 + DB=sqlite3 rake test
  31 +
  32 +
  33 +Coverage
  34 +=======
  35 +
  36 +Test coverage can be calculated using Rcov. Make sure you have the rcov gem installed.
  37 +
  38 +Again in the acts_as_follower directory:
  39 +
  40 +rake rcov:gen # For mysql
  41 +
  42 +or:
  43 +
  44 +rake rcov:gen DB=sqlite3 # For sqlite
  45 +
  46 +The coverage will now be available in the test/coverage directory.
  47 +
  48 +rake rcov:clobber will delete the coverage directory.
test/acts_as_followable_test.rb
1 -require File.dirname(__FILE__) + '/test_helper'  
2 -  
3 -class ActsAsFollowableTest < Test::Unit::TestCase  
4 -  
5 - context "instance methods" do  
6 - setup do  
7 - @sam = Factory(:sam)  
8 - end  
9 -  
10 - should "be defined" do  
11 - assert @sam.respond_to?(:followers_count)  
12 - assert @sam.respond_to?(:followers)  
13 - assert @sam.respond_to?(:followed_by?)  
14 - end  
15 - end  
16 -  
17 - context "acts_as_followable" do  
18 - setup do  
19 - @sam = Factory(:sam)  
20 - @jon = Factory(:jon)  
21 - @sam.follow(@jon)  
22 - end  
23 -  
24 - context "followers_count" do  
25 - should "return the number of followers" do  
26 - assert_equal 0, @sam.followers_count  
27 - assert_equal 1, @jon.followers_count  
28 - end  
29 - should "return the proper number of multiple followers" do  
30 - @bob = Factory(:bob)  
31 - @sam.follow(@bob)  
32 - assert_equal 0, @sam.followers_count  
33 - assert_equal 1, @jon.followers_count  
34 - assert_equal 1, @bob.followers_count  
35 - end  
36 - end  
37 -  
38 - context "followers" do  
39 - should "return users" do  
40 - assert_equal [], @sam.followers  
41 - assert_equal [@sam], @jon.followers  
42 - end  
43 - should "return users (multiple followers)" do  
44 - @bob = Factory(:bob)  
45 - @sam.follow(@bob)  
46 - assert_equal [], @sam.followers  
47 - assert_equal [@sam], @jon.followers  
48 - assert_equal [@sam], @bob.followers  
49 - end  
50 - should "return users (multiple followers, complex)" do  
51 - @bob = Factory(:bob)  
52 - @sam.follow(@bob)  
53 - @jon.follow(@bob)  
54 - assert_equal [], @sam.followers  
55 - assert_equal [@sam], @jon.followers  
56 - assert_equal [@sam, @jon], @bob.followers  
57 - end  
58 - end  
59 -  
60 - context "followed_by" do  
61 - should "return_follower_status" do  
62 - assert_equal true, @jon.followed_by?(@sam)  
63 - assert_equal false, @sam.followed_by?(@jon)  
64 - end  
65 - end  
66 -  
67 - context "destroying a followable" do  
68 - setup do  
69 - @jon.destroy  
70 - end  
71 -  
72 - should_change("follow count", :by => -1) { Follow.count }  
73 - should_change("@sam.all_following.size", :by => -1) { @sam.all_following.size } 1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class ActsAsFollowableTest < Test::Unit::TestCase
  4 +
  5 + context "instance methods" do
  6 + setup do
  7 + @sam = Factory(:sam)
74 end 8 end
75 - 9 +
  10 + should "be defined" do
  11 + assert @sam.respond_to?(:followers_count)
  12 + assert @sam.respond_to?(:followers)
  13 + assert @sam.respond_to?(:followed_by?)
  14 + end
  15 + end
  16 +
  17 + context "acts_as_followable" do
  18 + setup do
  19 + @sam = Factory(:sam)
  20 + @jon = Factory(:jon)
  21 + @sam.follow(@jon)
  22 + end
  23 +
  24 + context "followers_count" do
  25 + should "return the number of followers" do
  26 + assert_equal 0, @sam.followers_count
  27 + assert_equal 1, @jon.followers_count
  28 + end
  29 + should "return the proper number of multiple followers" do
  30 + @bob = Factory(:bob)
  31 + @sam.follow(@bob)
  32 + assert_equal 0, @sam.followers_count
  33 + assert_equal 1, @jon.followers_count
  34 + assert_equal 1, @bob.followers_count
  35 + end
  36 + end
  37 +
  38 + context "followers" do
  39 + should "return users" do
  40 + assert_equal [], @sam.followers
  41 + assert_equal [@sam], @jon.followers
  42 + end
  43 + should "return users (multiple followers)" do
  44 + @bob = Factory(:bob)
  45 + @sam.follow(@bob)
  46 + assert_equal [], @sam.followers
  47 + assert_equal [@sam], @jon.followers
  48 + assert_equal [@sam], @bob.followers
  49 + end
  50 + should "return users (multiple followers, complex)" do
  51 + @bob = Factory(:bob)
  52 + @sam.follow(@bob)
  53 + @jon.follow(@bob)
  54 + assert_equal [], @sam.followers
  55 + assert_equal [@sam], @jon.followers
  56 + assert_equal [@sam, @jon], @bob.followers
  57 + end
  58 + end
  59 +
  60 + context "followed_by" do
  61 + should "return_follower_status" do
  62 + assert_equal true, @jon.followed_by?(@sam)
  63 + assert_equal false, @sam.followed_by?(@jon)
  64 + end
  65 + end
  66 +
  67 + context "destroying a followable" do
  68 + setup do
  69 + @jon.destroy
  70 + end
  71 +
  72 + should_change("follow count", :by => -1) { Follow.count }
  73 + should_change("@sam.all_following.size", :by => -1) { @sam.all_following.size }
  74 + end
  75 +
76 context "blocking a follower" do 76 context "blocking a follower" do
77 setup do 77 setup do
78 @jon.block(@sam) 78 @jon.block(@sam)
79 end 79 end
80 - 80 +
81 should "remove him from followers" do 81 should "remove him from followers" do
82 assert_equal 0, @jon.followers_count 82 assert_equal 0, @jon.followers_count
83 end 83 end
84 - 84 +
85 should "add him to the blocked followers" do 85 should "add him to the blocked followers" do
86 assert_equal 1, @jon.blocked_followers_count 86 assert_equal 1, @jon.blocked_followers_count
87 end 87 end
88 - 88 +
89 should "not be able to follow again" do 89 should "not be able to follow again" do
90 assert_equal 0, @jon.followers_count 90 assert_equal 0, @jon.followers_count
91 end 91 end
92 - 92 +
93 should "not be present when listing followers" do 93 should "not be present when listing followers" do
94 assert_equal [], @jon.followers 94 assert_equal [], @jon.followers
95 end 95 end
96 - 96 +
97 should "be in the list of blocks" do 97 should "be in the list of blocks" do
98 assert_equal [@sam], @jon.blocks 98 assert_equal [@sam], @jon.blocks
99 end 99 end
100 end 100 end
101 - 101 +
102 context "unblocking a blocked follow" do 102 context "unblocking a blocked follow" do
103 setup do 103 setup do
104 @jon.block(@sam) 104 @jon.block(@sam)
105 @jon.unblock(@sam) 105 @jon.unblock(@sam)
106 end 106 end
107 - 107 +
108 should "not include the unblocked user in the list of followers" do 108 should "not include the unblocked user in the list of followers" do
109 assert_equal [], @jon.followers 109 assert_equal [], @jon.followers
110 end 110 end
111 - 111 +
112 should "remove him from the blocked followers" do 112 should "remove him from the blocked followers" do
113 assert_equal 0, @jon.blocked_followers_count 113 assert_equal 0, @jon.blocked_followers_count
114 assert_equal [], @jon.blocks 114 assert_equal [], @jon.blocks
115 end 115 end
116 end 116 end
117 - 117 +
118 context "unblock a non-existent follow" do 118 context "unblock a non-existent follow" do
119 setup do 119 setup do
120 @sam.stop_following(@jon) 120 @sam.stop_following(@jon)
121 @jon.unblock(@sam) 121 @jon.unblock(@sam)
122 end 122 end
123 - 123 +
124 should "not be in the list of followers" do 124 should "not be in the list of followers" do
125 assert_equal [], @jon.followers 125 assert_equal [], @jon.followers
126 end 126 end
127 - 127 +
128 should "not be in the blockked followers count" do 128 should "not be in the blockked followers count" do
129 assert_equal 0, @jon.blocked_followers_count 129 assert_equal 0, @jon.blocked_followers_count
130 end 130 end
131 - 131 +
132 should "not be in the blocks list" do 132 should "not be in the blocks list" do
133 assert_equal [], @jon.blocks 133 assert_equal [], @jon.blocks
134 end 134 end
135 end 135 end
136 -  
137 - end  
138 -  
139 -end 136 +
  137 + end
  138 +
  139 +end
test/acts_as_follower_test.rb
1 -require File.dirname(__FILE__) + '/test_helper'  
2 -  
3 -class ActsAsFollowerTest < Test::Unit::TestCase  
4 -  
5 - context "instance methods" do  
6 - setup do  
7 - @sam = Factory(:sam)  
8 - end  
9 -  
10 - should "be defined" do  
11 - assert @sam.respond_to?(:following?)  
12 - assert @sam.respond_to?(:follow_count)  
13 - assert @sam.respond_to?(:follow)  
14 - assert @sam.respond_to?(:stop_following)  
15 - assert @sam.respond_to?(:follows_by_type)  
16 - assert @sam.respond_to?(:all_follows)  
17 - end  
18 - end  
19 -  
20 - context "acts_as_follower" do  
21 - setup do  
22 - @sam = Factory(:sam)  
23 - @jon = Factory(:jon)  
24 - @oasis = Factory(:oasis)  
25 - @sam.follow(@jon)  
26 - @sam.follow(@oasis)  
27 - end  
28 -  
29 - context "following" do  
30 - should "return following_status" do  
31 - assert_equal true, @sam.following?(@jon)  
32 - assert_equal false, @jon.following?(@sam)  
33 - end  
34 -  
35 - should "return follow_count" do  
36 - assert_equal 2, @sam.follow_count  
37 - assert_equal 0, @jon.follow_count  
38 - end  
39 - end  
40 -  
41 - context "follow" do  
42 - setup do  
43 - @jon.follow(@sam)  
44 - end  
45 -  
46 - should_change("Follow count", :by => 1) { Follow.count }  
47 - should_change("@jon.follow_count", :by => 1) { @jon.follow_count }  
48 -  
49 - should "set the follower" do  
50 - assert_equal @jon, Follow.last.follower  
51 - end  
52 -  
53 - should "set the followable" do  
54 - assert_equal @sam, Follow.last.followable  
55 - end  
56 - end  
57 -  
58 - context "stop_following" do  
59 - setup do  
60 - @sam.stop_following(@jon)  
61 - end  
62 -  
63 - should_change("Follow count", :by => -1) { Follow.count }  
64 - should_change("@sam.follow_count", :by => -1) { @sam.follow_count }  
65 - end  
66 -  
67 - context "follows" do  
68 - setup do  
69 - @band_follow = Follow.find(:first, :conditions => ["follower_id = ? and follower_type = 'User' and followable_id = ? and followable_type = 'Band'", @sam.id, @oasis.id])  
70 - @user_follow = Follow.find(:first, :conditions => ["follower_id = ? and follower_type = 'User' and followable_id = ? and followable_type = 'User'", @sam.id, @jon.id])  
71 - end  
72 -  
73 - context "follows_by_type" do  
74 - should "only return requested follows" do  
75 - assert_equal [@band_follow], @sam.follows_by_type('Band')  
76 - assert_equal [@user_follow], @sam.follows_by_type('User')  
77 - end  
78 - end  
79 -  
80 - context "all_follows" do  
81 - should "return all follows" do  
82 - assert_equal 2, @sam.all_follows.size  
83 - assert @sam.all_follows.include?(@band_follow)  
84 - assert @sam.all_follows.include?(@user_follow)  
85 - assert_equal [], @jon.all_follows  
86 - end  
87 - end  
88 - end  
89 -  
90 - context "all_following" do  
91 - should "return the actual follow records" do  
92 - assert_equal 2, @sam.all_following.size  
93 - assert @sam.all_following.include?(@oasis)  
94 - assert @sam.all_following.include?(@jon)  
95 - assert_equal [], @jon.all_following  
96 - end  
97 - end  
98 -  
99 - context "following_by_type" do  
100 - should "return only requested records" do  
101 - assert_equal [@oasis], @sam.following_by_type('Band')  
102 - assert_equal [@jon], @sam.following_by_type('User')  
103 - end  
104 - end  
105 -  
106 - context "following_by_type_count" do  
107 - should "return the count of the requested type" do  
108 - assert_equal 1, @sam.following_by_type_count('Band')  
109 - assert_equal 1, @sam.following_by_type_count('User')  
110 - assert_equal 0, @jon.following_by_type_count('Band')  
111 - @jon.block(@sam)  
112 - assert_equal 0, @sam.following_by_type_count('User')  
113 - end  
114 - end  
115 -  
116 - context "method_missing" do  
117 - should "call following_by_type" do  
118 - assert_equal [@oasis], @sam.following_bands  
119 - assert_equal [@jon], @sam.following_users  
120 - end  
121 -  
122 - should "call following_by_type_count" do  
123 - assert_equal 1, @sam.following_bands_count  
124 - assert_equal 1, @sam.following_users_count  
125 - assert_equal 0, @jon.following_bands_count  
126 - @jon.block(@sam)  
127 - assert_equal 0, @sam.following_users_count  
128 - end  
129 -  
130 - should "raise on no method" do  
131 - assert_raises (NoMethodError){ @sam.foobar }  
132 - end  
133 - end  
134 -  
135 - context "destroying follower" do  
136 - setup do  
137 - @jon.destroy  
138 - end  
139 -  
140 - should_change("Follow.count", :by => -1) { Follow.count }  
141 - should_change("@sam.follow_count", :by => -1) { @sam.follow_count }  
142 - end  
143 -  
144 - context "blocked by followable" do  
145 - setup do  
146 - @jon.block(@sam)  
147 - end  
148 -  
149 - should "return following_status" do  
150 - assert_equal false, @sam.following?(@jon)  
151 - end  
152 -  
153 - should "return follow_count" do  
154 - assert_equal 1, @sam.follow_count  
155 - end  
156 -  
157 - should "not return record of the blocked follows" do  
158 - assert_equal 1, @sam.all_follows.size  
159 - assert !@sam.all_follows.include?(@user_follow)  
160 - assert !@sam.all_following.include?(@jon)  
161 - assert_equal [], @sam.following_by_type('User')  
162 - assert_equal [], @sam.follows_by_type('User')  
163 - assert_equal [], @sam.following_users  
164 - end  
165 - end  
166 - end  
167 -  
168 -end 1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class ActsAsFollowerTest < Test::Unit::TestCase
  4 +
  5 + context "instance methods" do
  6 + setup do
  7 + @sam = Factory(:sam)
  8 + end
  9 +
  10 + should "be defined" do
  11 + assert @sam.respond_to?(:following?)
  12 + assert @sam.respond_to?(:follow_count)
  13 + assert @sam.respond_to?(:follow)
  14 + assert @sam.respond_to?(:stop_following)
  15 + assert @sam.respond_to?(:follows_by_type)
  16 + assert @sam.respond_to?(:all_follows)
  17 + end
  18 + end
  19 +
  20 + context "acts_as_follower" do
  21 + setup do
  22 + @sam = Factory(:sam)
  23 + @jon = Factory(:jon)
  24 + @oasis = Factory(:oasis)
  25 + @sam.follow(@jon)
  26 + @sam.follow(@oasis)
  27 + end
  28 +
  29 + context "following" do
  30 + should "return following_status" do
  31 + assert_equal true, @sam.following?(@jon)
  32 + assert_equal false, @jon.following?(@sam)
  33 + end
  34 +
  35 + should "return follow_count" do
  36 + assert_equal 2, @sam.follow_count
  37 + assert_equal 0, @jon.follow_count
  38 + end
  39 + end
  40 +
  41 + context "follow" do
  42 + setup do
  43 + @jon.follow(@sam)
  44 + end
  45 +
  46 + should_change("Follow count", :by => 1) { Follow.count }
  47 + should_change("@jon.follow_count", :by => 1) { @jon.follow_count }
  48 +
  49 + should "set the follower" do
  50 + assert_equal @jon, Follow.last.follower
  51 + end
  52 +
  53 + should "set the followable" do
  54 + assert_equal @sam, Follow.last.followable
  55 + end
  56 + end
  57 +
  58 + context "stop_following" do
  59 + setup do
  60 + @sam.stop_following(@jon)
  61 + end
  62 +
  63 + should_change("Follow count", :by => -1) { Follow.count }
  64 + should_change("@sam.follow_count", :by => -1) { @sam.follow_count }
  65 + end
  66 +
  67 + context "follows" do
  68 + setup do
  69 + @band_follow = Follow.find(:first, :conditions => ["follower_id = ? and follower_type = 'User' and followable_id = ? and followable_type = 'Band'", @sam.id, @oasis.id])
  70 + @user_follow = Follow.find(:first, :conditions => ["follower_id = ? and follower_type = 'User' and followable_id = ? and followable_type = 'User'", @sam.id, @jon.id])
  71 + end
  72 +
  73 + context "follows_by_type" do
  74 + should "only return requested follows" do
  75 + assert_equal [@band_follow], @sam.follows_by_type('Band')
  76 + assert_equal [@user_follow], @sam.follows_by_type('User')
  77 + end
  78 + end
  79 +
  80 + context "all_follows" do
  81 + should "return all follows" do
  82 + assert_equal 2, @sam.all_follows.size
  83 + assert @sam.all_follows.include?(@band_follow)
  84 + assert @sam.all_follows.include?(@user_follow)
  85 + assert_equal [], @jon.all_follows
  86 + end
  87 + end
  88 + end
  89 +
  90 + context "all_following" do
  91 + should "return the actual follow records" do
  92 + assert_equal 2, @sam.all_following.size
  93 + assert @sam.all_following.include?(@oasis)
  94 + assert @sam.all_following.include?(@jon)
  95 + assert_equal [], @jon.all_following
  96 + end
  97 + end
  98 +
  99 + context "following_by_type" do
  100 + should "return only requested records" do
  101 + assert_equal [@oasis], @sam.following_by_type('Band')
  102 + assert_equal [@jon], @sam.following_by_type('User')
  103 + end
  104 + end
  105 +
  106 + context "method_missing" do
  107 + should "call following_by_type" do
  108 + assert_equal [@oasis], @sam.following_bands
  109 + assert_equal [@jon], @sam.following_users
  110 + end
  111 +
  112 + should "raise on no method" do
  113 + assert_raises (NoMethodError){ @sam.foobar }
  114 + end
  115 + end
  116 +
  117 + context "destroying follower" do
  118 + setup do
  119 + @jon.destroy
  120 + end
  121 +
  122 + should_change("Follow.count", :by => -1) { Follow.count }
  123 + should_change("@sam.follow_count", :by => -1) { @sam.follow_count }
  124 + end
  125 +
  126 + context "blocked by followable" do
  127 + setup do
  128 + @jon.block(@sam)
  129 + end
  130 +
  131 + should "return following_status" do
  132 + assert_equal false, @sam.following?(@jon)
  133 + end
  134 +
  135 + should "return follow_count" do
  136 + assert_equal 1, @sam.follow_count
  137 + end
  138 +
  139 + should "not return record of the blocked follows" do
  140 + assert_equal 1, @sam.all_follows.size
  141 + assert !@sam.all_follows.include?(@user_follow)
  142 + assert !@sam.all_following.include?(@jon)
  143 + assert_equal [], @sam.following_by_type('User')
  144 + assert_equal [], @sam.follows_by_type('User')
  145 + assert_equal [], @sam.following_users
  146 + end
  147 + end
  148 + end
  149 +
  150 +end
test/database.yml.example
@@ -2,7 +2,7 @@ mysql: @@ -2,7 +2,7 @@ mysql:
2 adapter: mysql 2 adapter: mysql
3 host: localhost 3 host: localhost
4 username: root 4 username: root
5 - password: 5 + password:
6 database: rails_plugin_test 6 database: rails_plugin_test
7 7
8 sqlite3: 8 sqlite3:
test/factories/bands.rb
1 -Factory.define :oasis, :class => Band do |b|  
2 - b.name 'Oasis'  
3 -end 1 +Factory.define :oasis, :class => Band do |b|
  2 + b.name 'Oasis'
  3 +end
test/factories/users.rb
1 -Factory.define :jon, :class => User do |u|  
2 - u.name 'Jon'  
3 -end  
4 -  
5 -Factory.define :sam, :class => User do |u|  
6 - u.name 'Sam'  
7 -end  
8 -  
9 -Factory.define :bob, :class => User do |u|  
10 - u.name 'Bob'  
11 -end 1 +Factory.define :jon, :class => User do |u|
  2 + u.name 'Jon'
  3 +end
  4 +
  5 +Factory.define :sam, :class => User do |u|
  6 + u.name 'Sam'
  7 +end
  8 +
  9 +Factory.define :bob, :class => User do |u|
  10 + u.name 'Bob'
  11 +end
test/follow_test.rb
1 -require File.dirname(__FILE__) + '/test_helper'  
2 -  
3 -class FollowTest < Test::Unit::TestCase  
4 -  
5 - # Replace with real tests  
6 - def test_assert_true_should_be_true  
7 - assert true  
8 - end  
9 -  
10 -end 1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class FollowTest < Test::Unit::TestCase
  4 +
  5 + # Replace with real tests
  6 + def test_assert_true_should_be_true
  7 + assert true
  8 + end
  9 +
  10 +end
test/models/band.rb
1 -class Band < ActiveRecord::Base  
2 - validates_presence_of :name  
3 - acts_as_followable  
4 -end 1 +class Band < ActiveRecord::Base
  2 + validates_presence_of :name
  3 + acts_as_followable
  4 +end
test/models/user.rb
1 -class User < ActiveRecord::Base  
2 - validates_presence_of :name  
3 - acts_as_follower  
4 - acts_as_followable  
5 -end 1 +class User < ActiveRecord::Base
  2 + validates_presence_of :name
  3 + acts_as_follower
  4 + acts_as_followable
  5 +end
test/schema.rb
1 ActiveRecord::Schema.define :version => 0 do 1 ActiveRecord::Schema.define :version => 0 do
2 - 2 +
3 create_table :follows, :force => true do |t| 3 create_table :follows, :force => true do |t|
4 t.integer "followable_id", :null => false 4 t.integer "followable_id", :null => false
5 t.string "followable_type", :null => false 5 t.string "followable_type", :null => false
@@ -9,13 +9,13 @@ ActiveRecord::Schema.define :version =&gt; 0 do @@ -9,13 +9,13 @@ ActiveRecord::Schema.define :version =&gt; 0 do
9 t.datetime "created_at" 9 t.datetime "created_at"
10 t.datetime "updated_at" 10 t.datetime "updated_at"
11 end 11 end
12 - 12 +
13 create_table :users, :force => true do |t| 13 create_table :users, :force => true do |t|
14 t.column :name, :string 14 t.column :name, :string
15 end 15 end
16 - 16 +
17 create_table :bands, :force => true do |t| 17 create_table :bands, :force => true do |t|
18 t.column :name, :string 18 t.column :name, :string
19 end 19 end
20 - 20 +
21 end 21 end
test/test_helper.rb
1 -require 'rubygems'  
2 -require 'active_record'  
3 -require 'active_record/base'  
4 -  
5 -require File.dirname(__FILE__) + '/../init.rb'  
6 -require File.dirname(__FILE__) + '/models/band'  
7 -require File.dirname(__FILE__) + '/models/user'  
8 -require File.dirname(__FILE__) + '/../generators/acts_as_follower/templates/model.rb'  
9 -  
10 -require 'test/unit'  
11 -require 'shoulda'  
12 -require 'factory_girl'  
13 -  
14 -ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/debug.log')  
15 -ActiveRecord::Base.configurations = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))  
16 -ActiveRecord::Base.establish_connection(ENV['DB'] || 'mysql')  
17 -  
18 -load(File.dirname(__FILE__) + '/schema.rb') 1 +require 'rubygems'
  2 +require 'active_record'
  3 +require 'active_record/base'
  4 +
  5 +require File.dirname(__FILE__) + '/../init.rb'
  6 +require File.dirname(__FILE__) + '/models/band'
  7 +require File.dirname(__FILE__) + '/models/user'
  8 +require File.dirname(__FILE__) + '/../generators/acts_as_follower/templates/model.rb'
  9 +
  10 +require 'test/unit'
  11 +require 'shoulda'
  12 +require 'factory_girl'
  13 +
  14 +ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/debug.log')
  15 +ActiveRecord::Base.configurations = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
  16 +ActiveRecord::Base.establish_connection(ENV['DB'] || 'mysql')
  17 +
  18 +load(File.dirname(__FILE__) + '/schema.rb')