badgeable 0.0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg
2
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :gemcutter
2
+
3
+ # Specify your gem's dependencies in badgeable.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,42 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ badgeable (0.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ builder (2.1.2)
10
+ cucumber (0.9.2)
11
+ builder (~> 2.1.2)
12
+ diff-lcs (~> 1.1.2)
13
+ gherkin (~> 2.2.5)
14
+ json (~> 1.4.6)
15
+ term-ansicolor (~> 1.0.5)
16
+ diff-lcs (1.1.2)
17
+ factory_girl (1.3.2)
18
+ gherkin (2.2.8)
19
+ json (~> 1.4.6)
20
+ term-ansicolor (~> 1.0.5)
21
+ json (1.4.6)
22
+ rspec (2.0.0.rc)
23
+ rspec-core (= 2.0.0.rc)
24
+ rspec-expectations (= 2.0.0.rc)
25
+ rspec-mocks (= 2.0.0.rc)
26
+ rspec-core (2.0.0.rc)
27
+ rspec-expectations (2.0.0.rc)
28
+ diff-lcs (>= 1.1.2)
29
+ rspec-mocks (2.0.0.rc)
30
+ rspec-core (= 2.0.0.rc)
31
+ rspec-expectations (= 2.0.0.rc)
32
+ term-ansicolor (1.0.5)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ badgeable!
39
+ bundler (>= 1.0.0)
40
+ cucumber
41
+ factory_girl (>= 1.3.2)
42
+ rspec (>= 2.0.0.rc)
data/README.rdoc CHANGED
@@ -15,10 +15,11 @@ and the name constant of the awarding class:
15
15
 
16
16
  class Person
17
17
  include Mongoid::Document
18
- include Badgeable
18
+ include Badgeable::Subject
19
+ embeds_many :nachos
19
20
  end
20
21
 
21
- badge "Big Eater" do
22
+ badge "Nacho Nacho Man" do
22
23
  thing Nacho
23
24
  count 40
24
25
  subject :person
@@ -27,7 +28,28 @@ and the name constant of the awarding class:
27
28
  end
28
29
  end
29
30
 
30
- would award the "Big Eater" badge to each Person who eats 40 spicy nachos.
31
+ would award the "Nacho Nacho Man" badge to each Person who eats 40
32
+ nachos, and the last one was spicy.
33
+
34
+ class Person
35
+ include Mongoid::Document
36
+ include Badgeable::Subject
37
+ references_many :meals
38
+ end
39
+
40
+ badge "Fancy Pants" do
41
+ thing Meal
42
+ subject :person
43
+ count
44
+ Meal.where(:price_cents.gte => 10000).count >= 12
45
+ end
46
+ conditions do |meal|
47
+ meal.restaurant.city != meal.eater.city
48
+ end
49
+ end
50
+
51
+ would award the "Fancy Pants" badge to the diner who has eaten 12
52
+ expensive meals where the awarding meal was out of town.
31
53
 
32
54
  You can also award arbitrary badges using your own business logic by
33
55
  calling #award_badge(badge_name) on any Badgeable instance:
@@ -35,6 +57,16 @@ calling #award_badge(badge_name) on any Badgeable instance:
35
57
  yehuda = Person.create(:name => "Yehuda Katz")
36
58
  yehuda.award_badge("Total Badass")
37
59
 
60
+ == Setup
61
+
62
+ Badge recipient classes should include Badgeable::Subject.
63
+ Extending an awarding class with Badgeable::Award will allow you
64
+ to define badge blocks in the awarding class definition. You may
65
+ also eval a separate file of badge definitions in the context of
66
+ Badgeable::Award.
67
+
68
+ When used with Rails, Badgeable will look for badging definitions
69
+ in Rails.root/lib/badges.rb
38
70
 
39
71
  == Requirements
40
72
 
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/badgeable.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/badgeable/version", __FILE__)
3
+
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "badgeable"
7
+ s.version = Badgeable::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Scott Burton"]
10
+ s.email = ["scottburton11@gmail.com"]
11
+ s.homepage = "http://rubygems.org/gems/badgeable"
12
+ s.summary = "Badgeable is an elegant DSL for awarding badges"
13
+ s.description = "Badgeable provides an elegant DSL for describing and awarding badges to your Ruby objects."
14
+
15
+ s.required_rubygems_version = ">= 1.3.6"
16
+ s.rubyforge_project = "badgeable"
17
+
18
+ s.add_development_dependency "bundler", ">= 1.0.0"
19
+ s.add_development_dependency "rspec", ">= 2.0.0.rc"
20
+ s.add_development_dependency "cucumber"
21
+ s.add_development_dependency "factory_girl", ">= 1.3.2"
22
+
23
+ s.files = `git ls-files`.split("\n")
24
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
25
+ s.require_path = 'lib'
26
+ end
@@ -0,0 +1,9 @@
1
+ Feature: Easily award badges to any Ruby class (given enough effort on your part)
2
+ In order to make somebody feel super awesome about themselves
3
+ A class that extends Badgeable::Award
4
+ Wants to award a badge recipient after they've created a certain number of them
5
+
6
+ Scenario: A restaurant meal awards the "Hog Wild" badge to a regular diner
7
+ Given a Meal awards the "Hog Wild" badge to an Diner after 3 times
8
+ When a diner creates 3 meals
9
+ Then the diner should have the "Hog Wild" badge
@@ -0,0 +1,20 @@
1
+ Given /^a Meal awards the "([^\"]*)" badge to an? Diner after (\d+) times$/ do |badge_name, threshold|
2
+ Meal.class_eval %Q{
3
+ badge "#{badge_name}" do
4
+ count #{threshold}
5
+ subject :diner
6
+ thing Meal
7
+ end
8
+ }
9
+ end
10
+
11
+ When /^a diner creates (\d+) meals$/ do |num|
12
+ @diner = Diner.create
13
+ num.to_i.times do
14
+ @diner.meals.create
15
+ end
16
+ end
17
+
18
+ Then /^the diner should have the "([^\"]*)" badge$/ do |badge_name|
19
+ @diner.should have_badge_named(badge_name)
20
+ end
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__),'..', '..', 'lib'))
3
+
4
+ require 'cucumber'
5
+ require 'rspec/expectations'
6
+ require 'badgeable'
7
+
8
+ Mongoid.configure do |config|
9
+ config.master = Mongo::Connection.new.db("badgeable_test")
10
+ end
11
+
12
+ # factory_girl Factory definitions
13
+ Dir[(File.expand_path(File.dirname(__FILE__), "..") + "spec/factories/**/*.rb").to_s].each {|factory| require factory}
14
+
15
+ Dir[(File.expand_path(File.dirname(__FILE__)) + "test_models/**/*.rb")].each {|model| require model }
16
+
17
+ Before do
18
+ Mongoid.master.collections.select{|c| !c.name.starts_with?("system")}.each(&:drop)
19
+ end
@@ -0,0 +1,5 @@
1
+ class Diner
2
+ include Mongoid::Document
3
+ include Badgeable::Subject
4
+ references_many :meals
5
+ end
@@ -0,0 +1,5 @@
1
+ class Meal
2
+ include Mongoid::Document
3
+ extend Badgeable::Award
4
+ referenced_in :diner, :inverse_of => :meals
5
+ end
@@ -0,0 +1,44 @@
1
+ module Badgeable
2
+ module Award
3
+ # Configure a class to automatically award badges after creation.
4
+ # Assign a badge name and a block with configuration
5
+ # directives.
6
+ #
7
+ # Valid directives:
8
+ #
9
+ # thing (Required) a class constant in this namespace that
10
+ # awards the badge.
11
+ # subject (Optional, default = :user) a symbol that references
12
+ # the object to which the badge is awarded. This should
13
+ # be a related object that includes Badgeable, and will
14
+ # usually have referenced_in :thing, belongs_to :thing etc.
15
+ # count (Optional, default = 1) either an integer threshold value
16
+ # of :things related to :subject, or a block. If a block
17
+ # is given, the created instance of :thing is passed as
18
+ # the first block argument, and the block must return
19
+ # return true for the badge to be awarded.
20
+ # conditions (Optional) provide a block; if your block returns
21
+ # returns true, the badge is awarded. The first block
22
+ # argument is the created instance of :thing. The
23
+ # conditions directive may be called any number of times,
24
+ # and all conditions and the count block must return true.
25
+ # Also note that the conditions and count directives are
26
+ # evaluated separately.
27
+ #
28
+ # See README for usage examples
29
+ #
30
+ def badge(name, &block)
31
+ config = Badgeable::Config.new
32
+ config.instance_eval(&block)
33
+ method_name = name.titleize.gsub(/\s/, "").underscore
34
+ config.klass.class_eval do
35
+ set_callback :create, :after, "award_#{method_name}_badge".to_sym
36
+ define_method "award_#{method_name}_badge".to_sym, Proc.new {
37
+ if config.conditions_array.all? {|p| p.call(self) }
38
+ self.send(config.subject_name).award_badge(name)
39
+ end
40
+ }
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,42 +1,10 @@
1
1
  module Badgeable
2
2
  class Config
3
- # Configure a class to automatically award badges after creation.
4
- # Assign a badge name and a block with configuration
5
- # directives.
6
- #
7
- # Valid directives:
8
- #
9
- # thing (Required) a class constant in this namespace that
10
- # awards the badge.
11
- # subject (Optional, default = :user) a symbol that references
12
- # the object to which the badge is awarded. This should
13
- # be a related object that includes Badgeable, and will
14
- # usually have referenced_in :thing, belongs_to :thing etc.
15
- # count (Optional, default = 1) either an integer threshold value
16
- # of :things related to :subject, or a block. If a block
17
- # is given, the created instance of :thing is passed as
18
- # the first block argument, and the block must return
19
- # return true for the badge to be awarded.
20
- # conditions (Optional) provide a block; if your block returns
21
- # returns true, the badge is awarded. Works in
22
- # conjunction with #count
23
- #
24
- # See README for usage examples
25
- #
26
- def self.badge(name, &block)
27
- config = new
28
- config.instance_eval(&block)
29
- method_name = name.titleize.gsub(/\s/, "").underscore
30
- config.klass.class_eval do
31
- set_callback :create, :after, "award_#{method_name}_badge".to_sym
32
- define_method "award_#{method_name}_badge".to_sym, Proc.new {
33
- if config.conditions_array.all? {|p| p.call(self) }
34
- self.send(config.subject_name).award_badge(name)
35
- end
36
- }
37
- end
3
+
4
+ class << self
5
+ attr_accessor :badge_definitions
38
6
  end
39
-
7
+
40
8
  attr_reader :threshold, :klass, :conditions_array, :subject_name
41
9
 
42
10
  def initialize
@@ -71,8 +39,6 @@ module Badgeable
71
39
  @conditions_array << Proc.new {|instance|
72
40
  block.call(instance)
73
41
  }
74
- end
75
-
76
-
42
+ end
77
43
  end
78
44
  end
@@ -0,0 +1,5 @@
1
+ module Badgeable
2
+ class Dsl
3
+ extend Badgeable::Award
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ module Badgeable
2
+ class Railtie < ::Rails::Railtie
3
+ initializer "badgeable.load_badges" do
4
+ Badgeable::Config.badge_definitions = Pathname.new("#{Rails.root}/lib/badges.rb")
5
+ Badgeable::Dsl.class_eval(File.read(Badgeable::Config.badge_definitions))
6
+ end
7
+ end
8
+ end
@@ -14,5 +14,19 @@ module Badgeable
14
14
  def has_badge_named?(name)
15
15
  badges.map(&:name).include?(name)
16
16
  end
17
+
18
+ def self.included(receiver)
19
+ receiver.class_eval %Q{
20
+ references_many :badges, :stored_as => :array, :class_name => "Badgeable::Badge", :inverse_of => :#{receiver.to_s.tableize}
21
+ }
22
+
23
+ Badgeable::Badge.class_eval %Q{
24
+ references_many :#{receiver.to_s.tableize}, :inverse_of => :badges, :stored_as => :array, :inverse_of => :badges
25
+
26
+ def recipients
27
+ #{receiver}.where(:badge_ids => id)
28
+ end
29
+ }
30
+ end
17
31
  end
18
32
  end
@@ -0,0 +1,3 @@
1
+ module Badgeable
2
+ VERSION = "0.1.1"
3
+ end
data/lib/badgeable.rb CHANGED
@@ -2,27 +2,12 @@ require 'active_support/core_ext'
2
2
  require 'active_support/callbacks'
3
3
  require 'active_support/inflector'
4
4
  require 'mongoid'
5
+ require 'badgeable/award'
5
6
  require 'badgeable/badge'
6
7
  require 'badgeable/config'
8
+ require 'badgeable/dsl'
7
9
  require 'badgeable/subject'
10
+ require 'badgeable/version'
11
+ require 'badgeable/railtie' if defined?(Rails)
8
12
 
9
- module Badgeable
10
-
11
- VERSION = "0.0.1"
12
-
13
- def self.included(receiver)
14
- receiver.class_eval %Q{
15
- references_many :badges, :stored_as => :array, :class_name => "Badgeable::Badge", :inverse_of => :#{receiver.to_s.tableize}
16
- }
17
-
18
- Badgeable::Badge.class_eval %Q{
19
- references_many :#{receiver.to_s.tableize}, :inverse_of => :badges, :stored_as => :array, :inverse_of => :badges
20
-
21
- def recipients
22
- #{receiver}.where(:badge_ids => id)
23
- end
24
- }
25
-
26
- receiver.send :include, Badgeable::Subject
27
- end
28
- end
13
+ module Badgeable; end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: badgeable
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
- - 0
9
7
  - 1
10
- version: 0.0.1
8
+ - 1
9
+ version: 0.1.1
11
10
  platform: ruby
12
11
  authors:
13
12
  - Scott Burton
@@ -15,10 +14,68 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-10-08 00:00:00 -07:00
17
+ date: 2010-10-09 00:00:00 -07:00
19
18
  default_executable:
20
- dependencies: []
21
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: bundler
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 0
31
+ - 0
32
+ version: 1.0.0
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 2
45
+ - 0
46
+ - 0
47
+ - rc
48
+ version: 2.0.0.rc
49
+ type: :development
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: cucumber
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ type: :development
63
+ version_requirements: *id003
64
+ - !ruby/object:Gem::Dependency
65
+ name: factory_girl
66
+ prerelease: false
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 1
74
+ - 3
75
+ - 2
76
+ version: 1.3.2
77
+ type: :development
78
+ version_requirements: *id004
22
79
  description: Badgeable provides an elegant DSL for describing and awarding badges to your Ruby objects.
23
80
  email:
24
81
  - scottburton11@gmail.com
@@ -29,14 +86,28 @@ extensions: []
29
86
  extra_rdoc_files: []
30
87
 
31
88
  files:
89
+ - .gitignore
90
+ - Gemfile
91
+ - Gemfile.lock
92
+ - LICENSE
93
+ - README.rdoc
94
+ - Rakefile
95
+ - badgeable.gemspec
96
+ - features/award_badges.feature
97
+ - features/step_definitions/badging_steps.rb
98
+ - features/support/env.rb
99
+ - features/support/test_models/diner.rb
100
+ - features/support/test_models/meal.rb
101
+ - lib/badgeable.rb
102
+ - lib/badgeable/award.rb
32
103
  - lib/badgeable/badge.rb
33
104
  - lib/badgeable/config.rb
105
+ - lib/badgeable/dsl.rb
106
+ - lib/badgeable/railtie.rb
34
107
  - lib/badgeable/subject.rb
35
- - lib/badgeable.rb
36
- - LICENSE
37
- - README.rdoc
108
+ - lib/badgeable/version.rb
38
109
  has_rdoc: true
39
- homepage: http://github.com/scottburton11/badgeable
110
+ homepage: http://rubygems.org/gems/badgeable
40
111
  licenses: []
41
112
 
42
113
  post_install_message:
@@ -49,7 +120,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
49
120
  requirements:
50
121
  - - ">="
51
122
  - !ruby/object:Gem::Version
52
- hash: 3
53
123
  segments:
54
124
  - 0
55
125
  version: "0"
@@ -58,7 +128,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
128
  requirements:
59
129
  - - ">="
60
130
  - !ruby/object:Gem::Version
61
- hash: 23
62
131
  segments:
63
132
  - 1
64
133
  - 3
@@ -66,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
135
  version: 1.3.6
67
136
  requirements: []
68
137
 
69
- rubyforge_project:
138
+ rubyforge_project: badgeable
70
139
  rubygems_version: 1.3.7
71
140
  signing_key:
72
141
  specification_version: 3