ibham 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -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 ibham.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Jamal El Milahi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Ibham
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'ibham'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install ibham
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ desc 'Default: run specs.'
5
+ task :default => :rspec
6
+
7
+ RSpec::Core::RakeTask.new(:rspec) do |test|
8
+ test.rspec_opts = ['--color']
9
+ test.pattern = './spec/**/*_spec.rb'
10
+ end
data/ibham.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ibham/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'ibham'
8
+ gem.version = Ibham::VERSION
9
+ gem.authors = ['Jamal El Milahi']
10
+ gem.email = ['jamal@elmilahi.com']
11
+ gem.description = %q{Voting System for Rails applications}
12
+ gem.summary = %q{Ibham is a gem that allows Rails apps to compute and display voting scores for active records models.}
13
+ gem.homepage = 'https://github.com/bloc40/ibham'
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_development_dependency 'activerecord'
21
+ gem.add_development_dependency 'rake'
22
+ gem.add_development_dependency 'rspec'
23
+ gem.add_development_dependency 'database_cleaner'
24
+ gem.add_development_dependency 'sqlite3'
25
+ end
@@ -0,0 +1,20 @@
1
+ require 'rails/generators/migration'
2
+ require 'rails/generators/active_record'
3
+
4
+ module Ibham
5
+ class InstallGenerator < Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def self.next_migration_number(path)
10
+ ActiveRecord::Generators::Base.next_migration_number(path)
11
+ end
12
+
13
+ desc 'Create migration file required by ibham gem.'
14
+ def create_migration_file
15
+ unless self.class.migration_exists?(File.dirname(File.expand_path('db/migrate/ibham_create_votes')), 'ibham_create_votes')
16
+ migration_template 'migration.rb', 'db/migrate/ibham_create_votes.rb'
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ class IbhamCreateVotes < ActiveRecord::Migration
2
+ def change
3
+ create_table :votes do |t|
4
+ t.references :voter, polymorphic: true
5
+ t.references :voteable, polymorphic: true
6
+ t.integer :value
7
+
8
+ t.timestamps
9
+ end
10
+
11
+ add_index :votes, [:voter_id, :voter_type]
12
+ add_index :votes, [:voteable_id, :voteable_type]
13
+ end
14
+ end
@@ -0,0 +1,37 @@
1
+ module Ibham
2
+ module ActsAsVoteable
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def acts_as_voteable
7
+ class_eval do
8
+ include Voteable
9
+ end
10
+ end
11
+ end
12
+
13
+ module Voteable
14
+ extend ActiveSupport::Concern
15
+
16
+ included do
17
+ has_many :votes, as: :voteable, dependent: :destroy
18
+ end
19
+
20
+ def up_votes
21
+ votes.where(value: 1).count
22
+ end
23
+
24
+ def down_votes
25
+ votes.where(value: -1).count
26
+ end
27
+
28
+ def up_percentage
29
+ up_votes * 100 / votes.count.to_f
30
+ end
31
+
32
+ def down_percentage
33
+ 100 - up_percentage
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+ module Ibham
2
+ module ActsAsVoter
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def acts_as_voter
7
+ class_eval do
8
+ include Voter
9
+ end
10
+ end
11
+ end
12
+
13
+ module Voter
14
+ extend ActiveSupport::Concern
15
+
16
+ included do
17
+ has_many :votes, as: :voter, dependent: :destroy
18
+ end
19
+
20
+ def can_vote_for?(voteable)
21
+ votes.build(voteable: voteable, value: 1).valid?
22
+ end
23
+
24
+ def vote_up(voteable)
25
+ votes.create(voteable: voteable, value: 1)
26
+ end
27
+
28
+ def vote_down(voteable)
29
+ votes.create(voteable: voteable, value: -1)
30
+ end
31
+
32
+ def cast_vote(voteable, value)
33
+ votes.build(voteable: voteable, value: value)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module Ibham
2
+ VERSION = '0.1.0'
3
+ end
data/lib/ibham.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'ibham/version'
2
+ require 'ibham/acts_as_voter'
3
+ require 'ibham/acts_as_voteable'
4
+ require 'models/vote'
5
+
6
+ module Ibham
7
+ # Your code goes here...
8
+ end
9
+
10
+ ActiveRecord::Base.class_eval do
11
+ include Ibham::ActsAsVoter
12
+ include Ibham::ActsAsVoteable
13
+ end
@@ -0,0 +1,9 @@
1
+ class Vote < ActiveRecord::Base
2
+ attr_accessible :value, :voteable
3
+
4
+ belongs_to :voteable, polymorphic: true
5
+ belongs_to :voter, polymorphic: true
6
+
7
+ validates_uniqueness_of :voteable_id, scope: :voter_id
8
+ validates :value, inclusion: { in: [1, -1] }
9
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Vote do
4
+ let(:user) { User.create!(email: 'foo@example.com') }
5
+ let(:item) { Item.create!(name: 'item') }
6
+
7
+ describe 'Validations' do
8
+ it 'should be valid if the value is 1' do
9
+ vote = Vote.new(value: 1)
10
+ vote.should be_valid
11
+ end
12
+
13
+ it 'should be valid if the value is -1' do
14
+ vote = Vote.new(value: -1)
15
+ vote.should be_valid
16
+ end
17
+
18
+ it 'should fail if the value is other than 1 or -1' do
19
+ vote = Vote.new(value: 2)
20
+ vote.should_not be_valid
21
+ end
22
+
23
+ it 'should validate uniqueness of vote for voter and voteable' do
24
+ user.vote_up(item)
25
+ expect {
26
+ user.vote_up(item)
27
+ }.to change(Vote, :count).by(0)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'ActsAsVoteable' do
4
+ let(:user1) { User.create! }
5
+ let(:user2) { User.create! }
6
+ let(:user3) { User.create! }
7
+ let(:item) { Item.create! }
8
+ let(:item2) { Item.create! }
9
+
10
+ before do
11
+ user1.vote_up(item)
12
+ user2.vote_down(item)
13
+ user3.vote_up(item)
14
+ user1.vote_down(item2)
15
+ end
16
+
17
+ describe '#up_votes' do
18
+ it 'should return the number of positive votes for voteable' do
19
+ item.up_votes.should == 2
20
+ end
21
+ end
22
+
23
+ describe '#down_votes' do
24
+ it 'should return the number of negative votes for voteable' do
25
+ item.down_votes.should == 1
26
+ end
27
+ end
28
+
29
+ describe '#up_percentage' do
30
+ it 'should return the percentage of positive votes' do
31
+ item.up_percentage.should be_within(0.1).of(66.6)
32
+ end
33
+ end
34
+
35
+ describe '#down_percentage' do
36
+ it 'should return the percentage of negative votes' do
37
+ item.down_percentage.should be_within(0.1).of(33.3)
38
+ end
39
+
40
+ it 'should return 100% if the item has 1 negative vote' do
41
+ item2.down_percentage.should == 100
42
+ end
43
+
44
+ it 'should return 0 if the item has 0 positive vote' do
45
+ item2.up_percentage.should == 0
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'ActsAsVoter' do
4
+ let(:user) { User.create!(email: 'foo@example.com') }
5
+ let(:item) { Item.create!(name: 'item') }
6
+
7
+ describe '#can_vote_for?' do
8
+ it 'should return true if the voter can vote for an item' do
9
+ user.can_vote_for?(item).should be_true
10
+ end
11
+
12
+ it 'should return false if the voter can not vote for an item' do
13
+ user.vote_down(item)
14
+ user.can_vote_for?(item).should be_false
15
+ end
16
+ end
17
+
18
+ describe '#vote_up' do
19
+ it 'should create a positive vote' do
20
+ expect { user.vote_up(item) }.to change { Vote.count }.by(1)
21
+ Vote.last.value.should == 1
22
+ end
23
+ end
24
+
25
+ describe '#vote_down' do
26
+ it 'should create a positive vote' do
27
+ expect { user.vote_down(item) }.to change { Vote.count }.by(1)
28
+ Vote.last.value.should == -1
29
+ end
30
+ end
31
+
32
+ describe '#cast_vote' do
33
+ it 'should create a positive vote' do
34
+ Vote.count.should == 0
35
+ expect do
36
+ vote = user.cast_vote(item, 1)
37
+ vote.save
38
+ end.to change { Vote.count }.by(1)
39
+ Vote.last.value.should == 1
40
+ end
41
+
42
+ it 'should create a negative vote' do
43
+ Vote.count.should == 0
44
+ expect do
45
+ vote = user.cast_vote(item, -1)
46
+ vote.save
47
+ end.to change { Vote.count }.by(1)
48
+ Vote.last.value.should == -1
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,51 @@
1
+ require 'active_record'
2
+ require 'database_cleaner'
3
+ require 'sqlite3'
4
+ require 'ibham'
5
+
6
+ db_config = {
7
+ :adapter => 'sqlite3',
8
+ :database => ':memory:'
9
+ }
10
+
11
+ ActiveRecord::Base.establish_connection(db_config)
12
+
13
+ ActiveRecord::Migration.verbose = false
14
+
15
+ RSpec.configure do |config|
16
+ config.before(:each) { DatabaseCleaner.start }
17
+ config.after(:each) { DatabaseCleaner.clean }
18
+ end
19
+
20
+ ActiveRecord::Schema.define do
21
+ create_table :votes do |t|
22
+ t.references :voter, polymorphic: true
23
+ t.references :voteable, polymorphic: true
24
+ t.integer :value
25
+
26
+ t.timestamps
27
+ end
28
+
29
+ add_index :votes, [:voter_id, :voter_type]
30
+ add_index :votes, [:voteable_id, :voteable_type]
31
+
32
+ create_table :users do |t|
33
+ t.string :email
34
+ t.timestamps
35
+ end
36
+
37
+ create_table :items do |t|
38
+ t.string :name
39
+ t.timestamps
40
+ end
41
+ end
42
+
43
+ class User < ActiveRecord::Base
44
+ has_many :items
45
+ acts_as_voter
46
+ end
47
+
48
+ class Item < ActiveRecord::Base
49
+ belongs_to :user
50
+ acts_as_voteable
51
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ibham
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jamal El Milahi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: &70263820298980 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70263820298980
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ requirement: &70263820298200 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70263820298200
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70263820313380 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70263820313380
47
+ - !ruby/object:Gem::Dependency
48
+ name: database_cleaner
49
+ requirement: &70263820312720 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70263820312720
58
+ - !ruby/object:Gem::Dependency
59
+ name: sqlite3
60
+ requirement: &70263820312040 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70263820312040
69
+ description: Voting System for Rails applications
70
+ email:
71
+ - jamal@elmilahi.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - ibham.gemspec
82
+ - lib/generators/ibham/install_generator.rb
83
+ - lib/generators/ibham/templates/migration.rb
84
+ - lib/ibham.rb
85
+ - lib/ibham/acts_as_voteable.rb
86
+ - lib/ibham/acts_as_voter.rb
87
+ - lib/ibham/version.rb
88
+ - lib/models/vote.rb
89
+ - spec/models/vote_spec.rb
90
+ - spec/modules/acts_as_voteable_spec.rb
91
+ - spec/modules/acts_as_voter_spec.rb
92
+ - spec/spec_helper.rb
93
+ homepage: https://github.com/bloc40/ibham
94
+ licenses: []
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 1.8.17
114
+ signing_key:
115
+ specification_version: 3
116
+ summary: Ibham is a gem that allows Rails apps to compute and display voting scores
117
+ for active records models.
118
+ test_files:
119
+ - spec/models/vote_spec.rb
120
+ - spec/modules/acts_as_voteable_spec.rb
121
+ - spec/modules/acts_as_voter_spec.rb
122
+ - spec/spec_helper.rb