diff --git a/.gitignore b/.gitignore index 30f4ed6..5750084 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -test/debug.log \ No newline at end of file +test/debug.log +coverage \ No newline at end of file diff --git a/Rakefile b/Rakefile index ac3710d..d8699a0 100644 --- a/Rakefile +++ b/Rakefile @@ -20,3 +20,17 @@ Rake::RDocTask.new(:rdoc) do |rdoc| rdoc.rdoc_files.include('README') rdoc.rdoc_files.include('lib/**/*.rb') end + +namespace :rcov do + + desc "Generate a coverage report in coverage/" + task :gen do + sh "rcov --output coverage test/*_test.rb" + end + + desc "Remove generated coverage files." + task :clobber do + sh "rm -rdf coverage" + end + +end \ No newline at end of file diff --git a/init.rb b/init.rb index 324c978..83ca2a2 100644 --- a/init.rb +++ b/init.rb @@ -1,6 +1,6 @@ -require 'acts_as_follower' -require 'acts_as_followable' -require 'follow.rb' +require 'lib/acts_as_follower' +require 'lib/acts_as_followable' +require 'lib/follow' ActiveRecord::Base.send(:include, ActiveRecord::Acts::Follower) ActiveRecord::Base.send(:include, ActiveRecord::Acts::Followable) diff --git a/lib/acts_as_follower.rb b/lib/acts_as_follower.rb index 0afa0e1..70baa05 100644 --- a/lib/acts_as_follower.rb +++ b/lib/acts_as_follower.rb @@ -10,18 +10,13 @@ module ActiveRecord def acts_as_follower has_many :follows, :as => :follower, :dependent => :nullify # If a following entity is deleted, keep the follows. include ActiveRecord::Acts::Follower::InstanceMethods - extend ActiveRecord::Acts::Follower::SingletonMethods end end - # This module contains class methods - module SingletonMethods - - end - # This module contains instance methods module InstanceMethods + # Returns true if this instance is following the object passed as an argument. def following?(followable) 0 < Follow.count(:all, :conditions => [ "follower_id = ? AND follower_type = ? AND followable_id = ? AND followable_type = ?", @@ -29,10 +24,13 @@ module ActiveRecord ]) end + # Returns the number of objects this instance is following. def follow_count Follow.count(:all, :conditions => ["follower_id = ? AND follower_type = ?", self.id, self.class.name]) end + # Creates a new follow record for this instance to follow the passed object. + # Does not allow duplicate records to be created. def follow(followable) follow = get_follow(followable) unless follow @@ -40,6 +38,7 @@ module ActiveRecord end end + # Deletes the follow record if it exists. def stop_following(followable) follow = get_follow(followable) if follow @@ -47,16 +46,19 @@ module ActiveRecord end end + # Returns the follow records related to this instance by type. def follows_by_type(followable_type) Follow.find(:all, :conditions => ["follower_id = ? AND follower_type = ? AND followable_type = ?", self.id, self.class.name, followable_type]) end + # Returns the follow records related to this instance by type. def all_follows Follow.find(:all, :conditions => ["follower_id = ? AND follower_type = ?", self.id, self.class.name]) end private + # Returns a follow record for the current instance and followable object. def get_follow(followable) Follow.find(:first, :conditions => ["follower_id = ? AND follower_type = ? AND followable_id = ? AND followable_type = ?", self.id, self.class.name, followable.id, followable.class.name]) end diff --git a/test/acts_as_follower_test.rb b/test/acts_as_follower_test.rb new file mode 100644 index 0000000..eb9c774 --- /dev/null +++ b/test/acts_as_follower_test.rb @@ -0,0 +1,55 @@ +require File.dirname(__FILE__) + '/test_helper' + +class ActsAsFollowerTest < Test::Unit::TestCase + fixtures :users, :follows + + def test_instance_methods_should_be_defined + assert users(:sam).respond_to?(:following?) + assert users(:sam).respond_to?(:follow_count) + assert users(:sam).respond_to?(:follow) + assert users(:sam).respond_to?(:stop_following) + assert users(:sam).respond_to?(:follows_by_type) + assert users(:sam).respond_to?(:all_follows) + end + + def test_following_should_returns_following_status + assert_equal true, users(:sam).following?(users(:jon)) + assert_equal false, users(:jon).following?(users(:sam)) + end + + def test_follow_count_should_return_count_of_followed_users + assert_equal 2, users(:sam).follow_count + assert_equal 0, users(:jon).follow_count + end + + def test_follow_should_create_relevant_follow_record + assert_difference "Follow.count", 1 do + assert_difference "users(:jon).follow_count", 1 do + users(:jon).follow(users(:sam)) + end + end + assert_equal users(:jon), Follow.last.follower + assert_equal users(:sam), Follow.last.followable + end + + def test_stop_following_should_create_relevant_follow_record + assert_difference "Follow.count", -1 do + assert_difference "users(:sam).follow_count", -1 do + users(:sam).stop_following(users(:jon)) + end + end + end + + def test_follows_by_type_should_return_only_requested_records + assert_equal [follows(:band)], users(:sam).follows_by_type('Band') + assert_equal [follows(:user)], users(:sam).follows_by_type('User') + end + + def test_all_follows_should_return_all_folows + follows = users(:sam).all_follows + assert_equal 2, follows.size + assert follows.include?(follows(:band)) + assert follows.include?(follows(:user)) + end + +end diff --git a/test/fixtures/band.rb b/test/fixtures/band.rb new file mode 100644 index 0000000..7f94535 --- /dev/null +++ b/test/fixtures/band.rb @@ -0,0 +1,4 @@ +class Band < ActiveRecord::Base + validates_presence_of :name + acts_as_followable +end diff --git a/test/fixtures/bands.yml b/test/fixtures/bands.yml new file mode 100644 index 0000000..da27ffa --- /dev/null +++ b/test/fixtures/bands.yml @@ -0,0 +1,3 @@ +oasis: + id: 1 + name: Oasis \ No newline at end of file diff --git a/test/fixtures/follows.yml b/test/fixtures/follows.yml index b017d4d..b746676 100644 --- a/test/fixtures/follows.yml +++ b/test/fixtures/follows.yml @@ -1,6 +1,13 @@ -one: +user: id: 1 followable_id: 1 followable_type: User follower_id: 2 + follower_type: User + +band: + id: 2 + followable_id: 1 + followable_type: Band + follower_id: 2 follower_type: User \ No newline at end of file diff --git a/test/follow_test.rb b/test/follow_test.rb new file mode 100644 index 0000000..258c461 --- /dev/null +++ b/test/follow_test.rb @@ -0,0 +1,10 @@ +require File.dirname(__FILE__) + '/test_helper' + +class FollowTest < Test::Unit::TestCase + + # Replace with real tests + def test_assert_true_should_be_true + assert true + end + +end diff --git a/test/schema.rb b/test/schema.rb index 412c5bb..4c4dcd1 100644 --- a/test/schema.rb +++ b/test/schema.rb @@ -5,6 +5,8 @@ ActiveRecord::Schema.define :version => 0 do t.string "followable_type", :null => false t.integer "follower_id", :null => false t.string "follower_type", :null => false + t.datetime "created_at" + t.datetime "updated_at" end create_table :users, :force => true do |t| -- libgit2 0.21.0