merit 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.markdown +18 -14
- data/app/models/badge.rb +0 -9
- data/app/models/merit_action.rb +1 -1
- data/lib/generators/active_record/templates/add_fields_to_model.rb +2 -0
- data/lib/generators/merit/templates/merit_badge_rules.rb +4 -4
- data/lib/generators/merit/templates/merit_rank_rules.rb +8 -11
- data/lib/merit.rb +1 -1
- data/lib/merit/model_additions.rb +7 -2
- data/lib/merit/models/active_record/sash.rb +1 -1
- data/lib/merit/rule.rb +13 -22
- data/lib/merit/rules_badge.rb +1 -2
- data/lib/merit/rules_rank.rb +21 -27
- data/merit.gemspec +1 -1
- data/test/dummy/app/models/merit_badge_rules.rb +2 -2
- data/test/dummy/app/models/merit_rank_rules.rb +6 -9
- data/test/dummy/db/migrate/20120318022220_add_fields_to_users.rb +2 -0
- data/test/integration/navigation_test.rb +7 -7
- data/test/merit_unit_test.rb +0 -7
- metadata +12 -14
- data/app/models/sash.rb +0 -10
- data/lib/merit/core_extensions.rb +0 -28
data/Gemfile.lock
CHANGED
data/README.markdown
CHANGED
@@ -40,8 +40,8 @@ holds. Badges may have levels, and may be temporary. Define rules on
|
|
40
40
|
|
41
41
|
## Examples
|
42
42
|
|
43
|
-
grant_on 'comments#vote', :badge => 'relevant-commenter', :to => :user do
|
44
|
-
|
43
|
+
grant_on 'comments#vote', :badge => 'relevant-commenter', :to => :user do |comment|
|
44
|
+
comment.votes.count == 5
|
45
45
|
end
|
46
46
|
|
47
47
|
grant_on ['users#create', 'users#update'], :badge => 'autobiographer', :temporary => true do |user|
|
@@ -74,21 +74,18 @@ method(s) defined in the <tt>:to</tt> option. Define rules on
|
|
74
74
|
|
75
75
|
# Defining rank rules
|
76
76
|
|
77
|
-
|
78
|
-
|
79
|
-
rank is granted, lower level ranks are taken off. 5 stars is a common ranking
|
80
|
-
use case.
|
81
|
-
|
82
|
-
They are not given at specified actions like badges, you should define a cron
|
83
|
-
job to test if ranks are to be granted.
|
77
|
+
5 stars is a common ranking use case. They are not given at specified actions
|
78
|
+
like badges, you should define a cron job to test if ranks are to be granted.
|
84
79
|
|
85
80
|
Define rules on <tt>app/models/merit_rank_rules.rb</tt>:
|
86
81
|
|
87
82
|
<tt>set_rank</tt> accepts:
|
88
83
|
|
89
|
-
* <tt>badge_name</tt> name of this ranking
|
90
84
|
* <tt>:level</tt> ranking level (greater is better)
|
91
85
|
* <tt>:to</tt> model or scope to check if new rankings apply
|
86
|
+
* <tt>:level_name</tt> attribute name (default is empty and results in
|
87
|
+
'<tt>level</tt>' attribute, if set it's appended like
|
88
|
+
'<tt>level_#{level_name}</tt>')
|
92
89
|
|
93
90
|
Check for rules on a rake task executed in background like:
|
94
91
|
|
@@ -99,11 +96,11 @@ Check for rules on a rake task executed in background like:
|
|
99
96
|
|
100
97
|
## Examples
|
101
98
|
|
102
|
-
set_rank :
|
99
|
+
set_rank :level => 2, :to => Commiter.active do |commiter|
|
103
100
|
commiter.branches > 1 && commiter.followers >= 10
|
104
101
|
end
|
105
102
|
|
106
|
-
set_rank :
|
103
|
+
set_rank :level => 3, :to => Commiter.active do |commiter|
|
107
104
|
commiter.branches > 2 && commiter.followers >= 20
|
108
105
|
end
|
109
106
|
|
@@ -111,7 +108,7 @@ Check for rules on a rake task executed in background like:
|
|
111
108
|
|
112
109
|
# Grant manually
|
113
110
|
|
114
|
-
You may also add badges
|
111
|
+
You may also add badges "by hand" from controller actions:
|
115
112
|
|
116
113
|
Badge.find(3).grant_to(current_user)
|
117
114
|
|
@@ -128,6 +125,12 @@ installation, and configuring <tt>config.orm = :mongo_mapper</tt> in
|
|
128
125
|
|
129
126
|
# Notes on upgrades
|
130
127
|
|
128
|
+
## to 0.4.0
|
129
|
+
|
130
|
+
Rankings are now integer attributes on "meritable" models ("<tt>level</tt>"),
|
131
|
+
they are not badges anymore. <tt>set_rank</tt> now doesn't accept
|
132
|
+
<tt>badge_name</tt>.
|
133
|
+
|
131
134
|
## to 0.3.0
|
132
135
|
|
133
136
|
Badges data is now stored in <tt>config/initializers/merit.rb</tt> using
|
@@ -142,7 +145,8 @@ Added <tt>had_errors</tt> boolean attribute to <tt>merit_actions</tt> table.
|
|
142
145
|
|
143
146
|
# To-do list
|
144
147
|
|
145
|
-
*
|
148
|
+
* rescue ActiveRecord::... should depend on ORM used (MongoMapper?)
|
149
|
+
* Why 1.8.7 tests are not passing?
|
146
150
|
* Ranking should not be badges, so .badges doesn't return them (2-stars
|
147
151
|
shouldn't be badge).
|
148
152
|
* :value parameter (for star voting for example) should be configurable
|
data/app/models/badge.rb
CHANGED
@@ -36,13 +36,4 @@ class Badge
|
|
36
36
|
sash = object_or_sash.respond_to?(:sash) ? object_or_sash.sash : object_or_sash
|
37
37
|
sash.rm_badge(id) if sash.badge_ids.include?(id)
|
38
38
|
end
|
39
|
-
|
40
|
-
# Give rank to sash if it's greater. Delete lower ranks it may have.
|
41
|
-
def grant_rank_to(sash)
|
42
|
-
# Grant to sash if had lower rank. Do nothing if has same or greater rank.
|
43
|
-
if sash.has_lower_rank_than(self)
|
44
|
-
Badge.by_name(name).keys.each{|id| sash.rm_badge(id) } # Clean up old ranks
|
45
|
-
sash.add_badge(id)
|
46
|
-
end
|
47
|
-
end
|
48
39
|
end
|
data/app/models/merit_action.rb
CHANGED
@@ -2,6 +2,7 @@ class AddFieldsTo<%= table_name.camelize %> < ActiveRecord::Migration
|
|
2
2
|
def self.up
|
3
3
|
add_column :<%= table_name %>, :sash_id, :integer
|
4
4
|
add_column :<%= table_name %>, :points, :integer, :default => 0
|
5
|
+
add_column :<%= table_name %>, :level, :integer, :default => 0
|
5
6
|
<%- resource = table_name.singularize -%>
|
6
7
|
<%= resource.camelize %>.all.each{|<%= resource %>| <%= resource %>.update_attribute(:points, 0) } # Update existing entries
|
7
8
|
end
|
@@ -9,5 +10,6 @@ class AddFieldsTo<%= table_name.camelize %> < ActiveRecord::Migration
|
|
9
10
|
def self.down
|
10
11
|
remove_column :<%= table_name %>, :sash_id
|
11
12
|
remove_column :<%= table_name %>, :points
|
13
|
+
remove_column :<%= table_name %>, :level
|
12
14
|
end
|
13
15
|
end
|
@@ -23,13 +23,13 @@ class MeritBadgeRules
|
|
23
23
|
# grant_on 'users#create', :badge => 'just-registered', :to => :itself
|
24
24
|
|
25
25
|
# If it has 10 comments, grant commenter-10 badge
|
26
|
-
# grant_on 'comments#create', :badge => 'commenter', :level => 10 do
|
27
|
-
#
|
26
|
+
# grant_on 'comments#create', :badge => 'commenter', :level => 10 do |comment|
|
27
|
+
# comment.user.comments.count == 10
|
28
28
|
# end
|
29
29
|
|
30
30
|
# If it has 5 votes, grant relevant-commenter badge
|
31
|
-
# grant_on 'comments#vote', :badge => 'relevant-commenter', :to => :user do
|
32
|
-
#
|
31
|
+
# grant_on 'comments#vote', :badge => 'relevant-commenter', :to => :user do |comment|
|
32
|
+
# comment.votes.count == 5
|
33
33
|
# end
|
34
34
|
|
35
35
|
# Changes his name by one wider than 4 chars (arbitrary ruby code case)
|
@@ -1,29 +1,26 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# granted
|
4
|
-
# case.
|
5
|
-
#
|
6
|
-
# They are not given at specified actions like badges, you should define a cron
|
7
|
-
# job to test if ranks are to be granted.
|
1
|
+
# 5 stars is a common ranking use case. They are not given at specified
|
2
|
+
# actions like badges, you should define a cron job to test if ranks are to be
|
3
|
+
# granted.
|
8
4
|
#
|
9
5
|
# +set_rank+ accepts:
|
10
|
-
# * +badge_name+ name of this ranking
|
11
6
|
# * :+level+ ranking level (greater is better)
|
12
7
|
# * :+to+ model or scope to check if new rankings apply
|
8
|
+
# * :+level_name+ attribute name (default is empty and results in 'level'
|
9
|
+
# attribute, if set it's appended like 'level_#{level_name}')
|
13
10
|
|
14
11
|
class MeritRankRules
|
15
12
|
include Merit::RankRules
|
16
13
|
|
17
14
|
def initialize
|
18
|
-
# set_rank :
|
15
|
+
# set_rank :level => 1, :to => Commiter.active do |commiter|
|
19
16
|
# commiter.repositories.count > 1 && commiter.followers >= 10
|
20
17
|
# end
|
21
18
|
#
|
22
|
-
# set_rank :
|
19
|
+
# set_rank :level => 2, :to => Commiter.active do |commiter|
|
23
20
|
# commiter.branches.count > 1 && commiter.followers >= 10
|
24
21
|
# end
|
25
22
|
#
|
26
|
-
# set_rank :
|
23
|
+
# set_rank :level => 3, :to => Commiter.active do |commiter|
|
27
24
|
# commiter.branches.count > 2 && commiter.followers >= 20
|
28
25
|
# end
|
29
26
|
end
|
data/lib/merit.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'merit/core_extensions'
|
2
1
|
require 'merit/rule'
|
3
2
|
require 'merit/rules_badge'
|
4
3
|
require 'merit/rules_points'
|
@@ -25,6 +24,7 @@ module Merit
|
|
25
24
|
# Merit.orm now set
|
26
25
|
if Merit.orm == :active_record
|
27
26
|
require "merit/models/#{Merit.orm}/badges_sash"
|
27
|
+
require "merit/models/#{Merit.orm}/sash"
|
28
28
|
end
|
29
29
|
|
30
30
|
ActiveSupport.on_load(:action_controller) do
|
@@ -9,6 +9,7 @@ module Merit
|
|
9
9
|
plugin Merit
|
10
10
|
key :sash_id, String
|
11
11
|
key :points, Integer, :default => 0
|
12
|
+
key :level, Integer, :default => 0
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -27,5 +28,9 @@ module Merit
|
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
30
|
-
|
31
|
-
|
31
|
+
if Object.const_defined?('ActiveRecord')
|
32
|
+
ActiveRecord::Base.send :include, Merit
|
33
|
+
end
|
34
|
+
if Object.const_defined?('MongoMapper')
|
35
|
+
MongoMapper::Document.plugin Merit
|
36
|
+
end
|
@@ -15,7 +15,7 @@ class Sash < ActiveRecord::Base
|
|
15
15
|
badges_sash = badges_sashes.first
|
16
16
|
badges_sashes.delete_all
|
17
17
|
# delete doesn't run callbacks, do it by hand
|
18
|
-
if Object.const_defined?('BadgesSashObserver')
|
18
|
+
if Object.const_defined?('BadgesSashObserver') && badges_sash.present?
|
19
19
|
BadgesSashObserver.instance.after_delete(badges_sash)
|
20
20
|
end
|
21
21
|
end
|
data/lib/merit/rule.rb
CHANGED
@@ -1,34 +1,25 @@
|
|
1
1
|
module Merit
|
2
2
|
# Rules has a badge name and level, a target to badge, a conditions block
|
3
3
|
# and a temporary option.
|
4
|
+
# Could split this class between badges and rankings functionality
|
4
5
|
class Rule
|
5
|
-
attr_accessor :badge_name, :level, :to, :temporary, :block, :model_name
|
6
|
+
attr_accessor :badge_name, :level, :to, :temporary, :block, :model_name, :level_name
|
6
7
|
|
7
8
|
# Does this rule's condition block apply?
|
8
9
|
def applies?(target_obj = nil)
|
9
|
-
# no block given: always true
|
10
|
-
no_block_or_true = true
|
11
|
-
unless block.nil?
|
12
|
-
case block.parameters.count
|
13
|
-
when 1
|
14
|
-
# block expects parameter: pass target_object
|
15
|
-
if target_obj.nil?
|
16
|
-
no_block_or_true = false
|
17
|
-
Rails.logger.warn "[merit] no target_obj found on Rule#applies?"
|
18
|
-
else
|
19
|
-
no_block_or_true = block.call(target_obj)
|
20
|
-
end
|
21
|
-
|
22
|
-
when 0
|
23
|
-
# block evaluates to true, or is a hash of methods and expected value
|
24
|
-
called = block.call
|
25
|
-
if called.kind_of?(Hash)
|
26
|
-
no_block_or_true = called.conditions_apply? target_obj
|
27
|
-
end
|
10
|
+
return true if block.nil? # no block given: always true
|
28
11
|
|
12
|
+
case block.parameters.count
|
13
|
+
when 1 # Expects target object
|
14
|
+
if target_obj.present?
|
15
|
+
return block.call(target_obj)
|
16
|
+
else
|
17
|
+
Rails.logger.warn "[merit] no target_obj found on Rule#applies?"
|
18
|
+
return false
|
29
19
|
end
|
20
|
+
when 0 # evaluates to boolean
|
21
|
+
return block.call
|
30
22
|
end
|
31
|
-
no_block_or_true
|
32
23
|
end
|
33
24
|
|
34
25
|
# Is this rule's badge temporary?
|
@@ -58,7 +49,7 @@ module Merit
|
|
58
49
|
else
|
59
50
|
begin
|
60
51
|
action.target_object(model_name).send(to)
|
61
|
-
rescue
|
52
|
+
rescue ActiveRecord::RecordNotFound
|
62
53
|
Rails.logger.warn "[merit] #{action.target_model.singularize}.find(#{action.target_id}) not found, no badges giving today"
|
63
54
|
return
|
64
55
|
end
|
data/lib/merit/rules_badge.rb
CHANGED
@@ -3,8 +3,7 @@ module Merit
|
|
3
3
|
# app/models/merit_rules.rb, con la siguiente sintaxis:
|
4
4
|
#
|
5
5
|
# grant_on 'users#create', :badge => 'just', :level => 'registered' do
|
6
|
-
# # Nothing, or code block which evaluates to
|
7
|
-
# # or with a { methods -> expected_values } hash.
|
6
|
+
# # Nothing, or code block which evaluates to boolean
|
8
7
|
# end
|
9
8
|
#
|
10
9
|
# También se puede asignar medallas desde métodos en controladores:
|
data/lib/merit/rules_rank.rb
CHANGED
@@ -1,51 +1,45 @@
|
|
1
1
|
module Merit
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# granted
|
5
|
-
# case.
|
6
|
-
#
|
7
|
-
# They are not given at specified actions like badges, you should define a cron
|
8
|
-
# job to test if ranks are to be granted.
|
2
|
+
# 5 stars is a common ranking use case. They are not given at specified
|
3
|
+
# actions like badges, you should define a cron job to test if ranks are to be
|
4
|
+
# granted.
|
9
5
|
#
|
10
6
|
# +set_rank+ accepts:
|
11
|
-
# * +badge_name+ name of this ranking
|
12
7
|
# * :+level+ ranking level (greater is better)
|
13
8
|
# * :+to+ model or scope to check if new rankings apply
|
9
|
+
# * :+level_name+ attribute name (default is empty and results in 'level'
|
10
|
+
# attribute, if set it's appended like 'level_#{level_name}')
|
14
11
|
module RankRules
|
15
12
|
# Populates +defined_rules+ hash with following hierarchy:
|
16
|
-
# defined_rules[ModelToRank]
|
17
|
-
def set_rank(
|
13
|
+
# defined_rules[ModelToRank] = { levels => blocks }
|
14
|
+
def set_rank(*args, &block)
|
18
15
|
options = args.extract_options!
|
19
16
|
|
20
17
|
rule = Rule.new
|
21
|
-
rule.
|
22
|
-
rule.
|
23
|
-
rule.block = block
|
18
|
+
rule.block = block
|
19
|
+
rule.level_name = options[:level_name].present? ? "level_#{options[:level_name]}" : 'level'
|
24
20
|
|
25
21
|
defined_rules[options[:to]] ||= {}
|
26
|
-
defined_rules[options[:to]][
|
27
|
-
defined_rules[options[:to]][ranking] << rule
|
22
|
+
defined_rules[options[:to]].merge!({ options[:level] => rule })
|
28
23
|
end
|
29
24
|
|
30
25
|
# Check rules defined for a merit_action
|
31
26
|
def check_rank_rules
|
32
|
-
defined_rules.each do |scoped_model,
|
33
|
-
|
34
|
-
|
35
|
-
|
27
|
+
defined_rules.each do |scoped_model, level_and_rules|
|
28
|
+
level_and_rules = level_and_rules.sort
|
29
|
+
level_and_rules.each do |level, rule|
|
30
|
+
begin
|
31
|
+
scoped_model.where("#{rule.level_name} < #{level}").each do |obj|
|
32
|
+
if rule.applies?(obj)
|
33
|
+
obj.update_attribute rule.level_name, level
|
34
|
+
end
|
35
|
+
end
|
36
|
+
rescue ActiveRecord::StatementInvalid
|
37
|
+
Rails.logger.warn "[merit] Please add #{rule.level_name} column/attribute to #{scoped_model.new.class.name}"
|
36
38
|
end
|
37
39
|
end
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
41
|
-
# Grant rank if rule applies
|
42
|
-
# Badge checks if it's rank is greater than sash's current one.
|
43
|
-
def grant_rank(rule, target_object)
|
44
|
-
if rule.applies? target_object
|
45
|
-
rule.badge.grant_rank_to target_object.sash
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
43
|
# Currently defined rules
|
50
44
|
def defined_rules
|
51
45
|
@defined_rules ||= {}
|
data/merit.gemspec
CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |s|
|
|
5
5
|
s.summary = "General reputation Rails engine."
|
6
6
|
s.description = "General reputation Rails engine."
|
7
7
|
s.files = `git ls-files`.split("\n").reject{|f| f =~ /^\./ }
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
s.authors = ["Tute Costa"]
|
10
10
|
s.email = 'tutecosta@gmail.com'
|
11
11
|
s.add_dependency 'ambry'
|
@@ -23,8 +23,8 @@ class MeritBadgeRules
|
|
23
23
|
grant_on 'users#create', :badge => 'just-registered', :to => :itself
|
24
24
|
|
25
25
|
# If it has 10 comments, grant commenter-10 badge
|
26
|
-
grant_on 'comments#create', :badge => 'commenter', :level => 10 do
|
27
|
-
|
26
|
+
grant_on 'comments#create', :badge => 'commenter', :level => 10 do |comment|
|
27
|
+
comment.user.comments.count == 10
|
28
28
|
end
|
29
29
|
|
30
30
|
# If it has at least 10 votes, grant relevant-commenter badge
|
@@ -1,15 +1,12 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# granted
|
4
|
-
# case.
|
5
|
-
#
|
6
|
-
# They are not given at specified actions like badges, you should define a cron
|
7
|
-
# job to test if ranks are to be granted.
|
1
|
+
# 5 stars is a common ranking use case. They are not given at specified
|
2
|
+
# actions like badges, you should define a cron job to test if ranks are to be
|
3
|
+
# granted.
|
8
4
|
#
|
9
5
|
# +set_rank+ accepts:
|
10
|
-
# * +badge_name+ name of this ranking
|
11
6
|
# * :+level+ ranking level (greater is better)
|
12
7
|
# * :+to+ model or scope to check if new rankings apply
|
8
|
+
# * :+level_name+ attribute name (default is empty and results in 'level'
|
9
|
+
# attribute, if set it's appended like 'level_#{level_name}')
|
13
10
|
|
14
11
|
class MeritRankRules
|
15
12
|
include Merit::RankRules
|
@@ -17,7 +14,7 @@ class MeritRankRules
|
|
17
14
|
def initialize
|
18
15
|
# i stars for i chars name
|
19
16
|
(1..5).each do |i|
|
20
|
-
set_rank :
|
17
|
+
set_rank :level => i, :to => User do |user|
|
21
18
|
user.name.length == i
|
22
19
|
end
|
23
20
|
end
|
@@ -2,11 +2,13 @@ class AddFieldsToUsers < ActiveRecord::Migration
|
|
2
2
|
def self.up
|
3
3
|
add_column :users, :sash_id, :integer
|
4
4
|
add_column :users, :points, :integer, :default => 0
|
5
|
+
add_column :users, :level, :integer, :default => 0
|
5
6
|
User.all.each{|user| user.update_attribute(:points, 0) } # Update existing entries
|
6
7
|
end
|
7
8
|
|
8
9
|
def self.down
|
9
10
|
remove_column :users, :sash_id
|
10
11
|
remove_column :users, :points
|
12
|
+
remove_column :users, :level
|
11
13
|
end
|
12
14
|
end
|
@@ -95,7 +95,7 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
95
95
|
assert_equal 45, user.points, 'Voting comments should grant 5 points'
|
96
96
|
end
|
97
97
|
|
98
|
-
test 'user workflow should grant
|
98
|
+
test 'user workflow should grant levels at some times' do
|
99
99
|
user = User.first
|
100
100
|
assert user.badges.empty?
|
101
101
|
|
@@ -105,9 +105,10 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
105
105
|
click_button('Update User')
|
106
106
|
|
107
107
|
user = User.where(:name => 'ab').first
|
108
|
-
|
108
|
+
assert_equal 0, user.level, "User level should be 0."
|
109
109
|
MeritRankRules.new.check_rank_rules
|
110
|
-
|
110
|
+
user.reload
|
111
|
+
assert_equal 2, user.level, "User level should be 2."
|
111
112
|
|
112
113
|
# Edit user's name by short name. Doesn't go back to previous rank.
|
113
114
|
visit "/users/#{user.id}/edit"
|
@@ -116,7 +117,8 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
116
117
|
|
117
118
|
user = User.where(:name => 'a').first
|
118
119
|
MeritRankRules.new.check_rank_rules
|
119
|
-
|
120
|
+
user.reload
|
121
|
+
assert_equal 2, user.level, "User level should be 2."
|
120
122
|
|
121
123
|
# Edit user's name by 5 chars name
|
122
124
|
visit "/users/#{user.id}/edit"
|
@@ -124,10 +126,8 @@ class NavigationTest < ActiveSupport::IntegrationCase
|
|
124
126
|
click_button('Update User')
|
125
127
|
|
126
128
|
user = User.where(:name => 'abcde').first
|
127
|
-
stars5 = Badge.by_name(:stars).by_level(5).first
|
128
|
-
assert_equal Badge.find_by_id(user.sash.badge_ids).by_name(:stars).count, 1, "Should not contain more than 2 stars ranking."
|
129
129
|
MeritRankRules.new.check_rank_rules
|
130
130
|
user.reload
|
131
|
-
|
131
|
+
assert_equal 5, user.level, "User level should be 5."
|
132
132
|
end
|
133
133
|
end
|
data/test/merit_unit_test.rb
CHANGED
@@ -1,13 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class MeritUnitTest < ActiveSupport::TestCase
|
4
|
-
test "Hash#conditions_apply? tests if object responds what's expected" do
|
5
|
-
hash = { :first => { :odd? => true }, :count => 2 }
|
6
|
-
assert hash.conditions_apply? [1,3]
|
7
|
-
assert not(hash.conditions_apply? [1,2,3])
|
8
|
-
assert not(hash.conditions_apply? [2,3])
|
9
|
-
end
|
10
|
-
|
11
4
|
test "Rule applies?" do
|
12
5
|
rule = Merit::Rule.new
|
13
6
|
assert rule.applies?, 'empty conditions should make rule apply'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: merit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ambry
|
16
|
-
requirement: &
|
16
|
+
requirement: &70321858339760 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70321858339760
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rails
|
27
|
-
requirement: &
|
27
|
+
requirement: &70321858339140 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70321858339140
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: sqlite3
|
38
|
-
requirement: &
|
38
|
+
requirement: &70321858337900 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70321858337900
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: haml
|
49
|
-
requirement: &
|
49
|
+
requirement: &70321858336840 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70321858336840
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: capybara
|
60
|
-
requirement: &
|
60
|
+
requirement: &70321858330240 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70321858330240
|
69
69
|
description: General reputation Rails engine.
|
70
70
|
email: tutecosta@gmail.com
|
71
71
|
executables: []
|
@@ -79,7 +79,6 @@ files:
|
|
79
79
|
- Rakefile
|
80
80
|
- app/models/badge.rb
|
81
81
|
- app/models/merit_action.rb
|
82
|
-
- app/models/sash.rb
|
83
82
|
- lib/generators/active_record/merit_generator.rb
|
84
83
|
- lib/generators/active_record/templates/add_fields_to_model.rb
|
85
84
|
- lib/generators/active_record/templates/create_badges_sashes.rb
|
@@ -93,7 +92,6 @@ files:
|
|
93
92
|
- lib/generators/merit/templates/merit_rank_rules.rb
|
94
93
|
- lib/merit.rb
|
95
94
|
- lib/merit/controller_extensions.rb
|
96
|
-
- lib/merit/core_extensions.rb
|
97
95
|
- lib/merit/model_additions.rb
|
98
96
|
- lib/merit/models/active_record/badges_sash.rb
|
99
97
|
- lib/merit/models/active_record/merit_action.rb
|
data/app/models/sash.rb
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
require "merit/models/#{Merit.orm}/sash"
|
2
|
-
|
3
|
-
class Sash
|
4
|
-
# Decides if sash has lower rank than a given badge
|
5
|
-
def has_lower_rank_than(badge)
|
6
|
-
badges = Badge.find_by_id(badge_ids)
|
7
|
-
levels = badges.by_name(badge.name).collect(&:level)
|
8
|
-
levels.all_lower_than badge.level
|
9
|
-
end
|
10
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# Hash core extensions:
|
2
|
-
# * conditions_apply?(obj)
|
3
|
-
class Hash
|
4
|
-
# Methods over object (applied recursively) respond what's expected?
|
5
|
-
# Example (evaluates to true):
|
6
|
-
# { :first => { :odd? => true }, :count => 2 }.conditions_apply? [1,3]
|
7
|
-
def conditions_apply?(obj)
|
8
|
-
applies = true
|
9
|
-
self.each do |method, value|
|
10
|
-
called_obj = obj.send(method)
|
11
|
-
if value.kind_of?(Hash)
|
12
|
-
applies = applies && value.conditions_apply?(called_obj)
|
13
|
-
else
|
14
|
-
applies = applies && called_obj == value
|
15
|
-
end
|
16
|
-
end
|
17
|
-
applies
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# Array core extensions:
|
22
|
-
# * all_lower_than(value)
|
23
|
-
class Array
|
24
|
-
# All array values are lower than parameter
|
25
|
-
def all_lower_than(value)
|
26
|
-
self.select{|elem| elem >= value }.empty?
|
27
|
-
end
|
28
|
-
end
|