achievements 0.0.2 → 0.0.3

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/README.markdown CHANGED
@@ -39,14 +39,17 @@ Here's how you get achievements into your application:
39
39
  # now this relies on the existence of a class which responds to
40
40
  # id, name, and achievement methods:
41
41
  achievements Achievement.all
42
-
43
42
  end
44
43
 
45
44
  Here's how you could interact with it in a session with the above
46
45
  class loaded:
47
46
 
48
-
47
+ # Grab the engine
48
+ @engine = Achievements.engine
49
49
 
50
+ # Achieve something!
51
+ @engine.achieve(:context1, 1, :one_time)
52
+ => [[:context1,:one_time,"1"]]
50
53
 
51
54
  For the most up to date look at what this library is supposed to do,
52
55
  please refer to the test directory.
@@ -82,6 +85,11 @@ class directly.
82
85
 
83
86
  ## Project Metainfo
84
87
 
88
+ ### Dependencies
89
+
90
+ * A running Redis server
91
+ * The Redis Ruby Gem
92
+
85
93
  ### TODO
86
94
 
87
95
  * Better Redis interface methods for making/closing/keeping conneciton
@@ -23,5 +23,10 @@ module Achievements
23
23
  def achieve(context,name)
24
24
  self.class.engine.achieve context, @id, name
25
25
  end
26
+
27
+ # Determine a user's 'score'
28
+ def score(context=nil,name=nil)
29
+ self.class.engine.score(@id, context, name)
30
+ end
26
31
  end
27
32
  end
@@ -51,7 +51,7 @@ module Achievements
51
51
  def achievements(object_array)
52
52
  object_array.each do |object|
53
53
  make_engine(context) if !@engine
54
- @engine.achievement object.context, object.name, object.threshold
54
+ @engine.achievement(object.context, object.name, object.threshold)
55
55
  end
56
56
  end
57
57
 
@@ -67,11 +67,15 @@ module Achievements
67
67
 
68
68
  def achieves(context_name_array)
69
69
  context_name_array.each do |cna|
70
- Achievements.engine.achieve cna[0], @id, cna[1]
70
+ @engine.achieve cna[0], @id, cna[1]
71
71
  end
72
72
  end
73
-
74
73
 
74
+ #
75
+ def score(agent_id,context,name)
76
+ @engine.score(agent_id,context,name)
77
+ end
78
+
75
79
  end
76
80
  end
77
81
  end
@@ -1,17 +1,17 @@
1
1
  module Achievements
2
- # Triggering multiple at once
3
-
4
2
  class Engine
5
3
  attr_accessor :achievements
6
4
  attr_accessor :contexts
7
5
  attr_accessor :redis
8
-
6
+
7
+ # Initialize an Achievements Engine by passing a connected redis instance
9
8
  def initialize(redis)
10
9
  @contexts = []
11
10
  @redis = redis
12
11
  @achievements = {}
13
12
  end
14
-
13
+
14
+ # Bind one achievement at a time. Accepts context, name, and threshold.
15
15
  def achievement(context,name,threshold)
16
16
  @contexts << context if !@contexts.include?(context)
17
17
  if achievement = Achievement.new(context,name,threshold)
@@ -20,6 +20,15 @@ module Achievements
20
20
  end
21
21
  end
22
22
  end
23
+
24
+ # Bind multiple achievements at a time. Accepts an array of
25
+ # objects which respond to the context, name, and threshold methods.
26
+ def achievements(achievement_array)
27
+ return unless achievement_array.is_a?(Array)
28
+ achievement_array.each do |achievement|
29
+ achievement(achievement.context, achievement.name, achievement.threshold)
30
+ end
31
+ end
23
32
 
24
33
  # The trigger method accepts:
25
34
  # context, agent_id, name
@@ -29,6 +38,10 @@ module Achievements
29
38
  def achieve(context, agent_id, name)
30
39
  achieved = []
31
40
 
41
+ # Increment user counter
42
+ counter = "agent:#{agent_id}"
43
+ incr counter
44
+
32
45
  # Increment parent counter
33
46
  counter = Counter.make(context,agent_id,"parent")
34
47
  incr counter
@@ -38,32 +51,53 @@ module Achievements
38
51
  result = incr counter
39
52
 
40
53
  # Check Threshold
41
-
42
54
  if @redis.sismember("#{context}:#{name}:threshold", result) == true
43
55
  achieved << [context,name, result.to_s]
44
56
  return achieved
45
57
  else
46
58
  return []
47
59
  end
48
-
49
60
  end
50
61
 
51
- # incr key
62
+ # Submit multiple achievements to the engine at one time, as an
63
+ # array of arrays.
64
+ def achieves(achievements)
65
+ response = []
66
+ achievements.each do |a|
67
+ response << achieve(a[0],a[1],a[2]).flatten
68
+ end
69
+ response
70
+ end
71
+
72
+ # Increment a given counter
52
73
  def incr(counter)
53
74
  @redis.incr counter
54
75
  end
55
76
 
56
- # decr key
77
+ # Decrement a given counter
57
78
  def decr(counter)
58
79
  @redis.decr counter
59
80
  end
60
81
 
82
+ # Deactivate a counter by setting it to "ACHIEVED," this making it
83
+ # incapable of being incremented or decremented
61
84
  def deactiveate(counter)
62
85
  @redis.set counter, "ACHIEVED"
63
86
  end
87
+
88
+ # Retrieve the score of:
89
+ # - specific counter (provide user_id, context, name)
90
+ # - context counter (provide user_id, context)
91
+ # - user counter (provide user_id)
92
+ def score(user_id, context = nil, name = nil)
93
+ scores = []
94
+ scores << @redis.get("agent:#{user_id}")
95
+ scores << @redis.get("#{context}:agent:#{user_id}:parent") unless context.nil?
96
+ scores << @redis.get("#{context}:agent:#{user_id}:#{name}") unless name.nil?
97
+ scores
98
+ end
64
99
 
65
100
  ## Class Methods
66
101
 
67
-
68
102
  end
69
103
  end
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Achievements
3
- Version = VERSION = '0.0.2'
3
+ Version = VERSION = '0.0.3'
4
4
  end
@@ -1,17 +1,51 @@
1
1
  require File.dirname(__FILE__) + '/test_helper'
2
2
 
3
- context "Achievement Restructure Test" do
3
+ context "Achievement Test" do
4
4
 
5
5
  setup do
6
6
  # Flush redis before each test
7
7
  Achievements.redis.flushall
8
8
 
9
+ # A sample achievement class. The instances implement the
10
+ # appropriate methods to be consumed by the engine class, and the
11
+ # class implements a ".all" method to emulate popular ORMs. This
12
+ # intends to show that it's easy to store your achievements in a
13
+ # database and load them in from there.
14
+ class Achievement
15
+ attr_accessor :context, :name, :threshold
16
+
17
+ def self.all
18
+ @all
19
+ end
20
+
21
+ def self.all=(a)
22
+ @all ||= []
23
+ @all << a
24
+ end
25
+
26
+ def initialize(context,name,threshold)
27
+ self.context = context
28
+ @name = name
29
+ @threshold = threshold
30
+ self.class.all = self
31
+ end
32
+ end
33
+
34
+ # Make some achievements for the achievements method demonstration
35
+ [[:context4,:five_times,5],[:context5,:two_times,2],[:context6,:once,1]].each do |a|
36
+ Achievement.new(a[0],a[1],a[2])
37
+ end
38
+
9
39
  # A sample engine class that demonstrates how to use the
10
40
  # AchievementsEngine include to instantiate the engine, make
11
41
  # achievements, etc.
12
42
  class Engine
13
43
  include Achievements::AchievementsEngine
14
-
44
+
45
+ # You can either add one achievement at a time with the
46
+ # achievement method which accepts the name of the achievement's
47
+ # context, name, and threshold:
48
+
15
49
  # One achievement, one level
16
50
  achievement :context1, :one_time, 1
17
51
 
@@ -21,6 +55,16 @@ context "Achievement Restructure Test" do
21
55
 
22
56
  # One achievement, multiple levels
23
57
  achievement :context3, :multiple_levels, [1, 5, 10]
58
+
59
+ # Or you can add multiple achievements at once with the
60
+ # achievements method, which accepts an array. This array must
61
+ # contain objects which implement id, name, and context
62
+ # methods. The example below assumes that you have an "all"
63
+ # class method on the Achievement class which returns an array
64
+ # of all instances of that class:
65
+
66
+ # Passing an array of compliant objects to the achievements method
67
+ achievements Achievement.all
24
68
  end
25
69
 
26
70
  # A sample agent class that demonstrates how to use the
@@ -35,7 +79,7 @@ context "Achievement Restructure Test" do
35
79
  @id = id
36
80
  end
37
81
  end
38
-
82
+
39
83
  # Make a new user with an ID different from the one used in most tests
40
84
  @user = User.new(10)
41
85
 
@@ -45,7 +89,8 @@ context "Achievement Restructure Test" do
45
89
  end
46
90
 
47
91
  test "Engine gets assigned appropriate contexts" do
48
- assert_equal @engine.contexts, [:context1,:context2,:context3]
92
+ assert_equal @engine.contexts, [:context1, :context2, :context3,
93
+ :context4, :context5, :context6]
49
94
  end
50
95
 
51
96
  test "Contexts get threshold sets" do
@@ -79,6 +124,7 @@ context "Achievement Restructure Test" do
79
124
  results << @engine.achieve(:context3,1,:multiple_levels)
80
125
  end
81
126
  assert_equal results, [[[:context3, :multiple_levels, "1"]], [], [], [], [[:context3, :multiple_levels, "5"]], [], [], [], [], [[:context3, :multiple_levels, "10"]]]
127
+ assert_equal @redis.get("agent:1"), "10"
82
128
  end
83
129
 
84
130
  test "Achieving from the agent class" do
@@ -92,4 +138,41 @@ context "Achievement Restructure Test" do
92
138
  @engine.achieve(:context1,1,:one_time)
93
139
  assert_equal @engine.achieve(:context1,1,:one_time),[]
94
140
  end
141
+
142
+ test "Members of achievement class should implement methods" do
143
+ Achievement.all.each do |a|
144
+ assert a.respond_to?(:context)
145
+ assert a.respond_to?(:name)
146
+ assert a.respond_to?(:id)
147
+ end
148
+ end
149
+
150
+ test "Achievement class should have three members" do
151
+ assert_equal Achievement.all.length, 3
152
+ end
153
+
154
+ test "Achieving more than one achievement at a time, no thresholds crossed" do
155
+ assert_equal @engine.achieves([[:context4,1,:five_times],[:context4,1,:five_times]]), [[],[]]
156
+ end
157
+
158
+ test "Achieving more than one at a time, threshold crosssed" do
159
+ assert_equal @engine.achieves([[:context1,1,:one_time],[:context2,1,:three_times]]), [[:context1,:one_time,"1"],[]]
160
+ end
161
+
162
+ test "Any trigger should increment agent counter" do
163
+ 20.times do
164
+ @engine.achieve(:context1,20,:one_time)
165
+ end
166
+ assert_equal @redis.get("agent:20"), "20"
167
+ end
168
+
169
+ test "Score retrieval" do
170
+ 20.times do
171
+ @user.achieve(:context1,:one_time)
172
+ end
173
+
174
+ assert_equal @user.score, ["20"]
175
+ assert_equal @user.score(:context1), ["20","20"]
176
+ assert_equal @user.score(:context1,:one_time), ["20","20","20"]
177
+ end
95
178
  end
data/test/test_helper.rb CHANGED
@@ -39,7 +39,7 @@ at_exit do
39
39
  end
40
40
 
41
41
  puts "Starting redis for testing at localhost:9736..."
42
- `redis-server #{dir}/redis-test.conf`
42
+ 'redis-server #{dir}/redis-test.conf'
43
43
  # AchievementEngine.redis = 'localhost:9736'
44
44
 
45
45
  ##
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: achievements
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Michael R. Bernstein
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-02 00:00:00 -04:00
18
+ date: 2010-11-03 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -48,14 +48,13 @@ files:
48
48
  - Rakefile
49
49
  - LICENSE
50
50
  - HISTORY.markdown
51
- - lib/achievements/counter.rb
52
- - lib/achievements/achievements_engine.rb
51
+ - lib/achievements/achievement.rb
53
52
  - lib/achievements/achievements_achievement.rb
54
53
  - lib/achievements/achievements_agent.rb
55
- - lib/achievements/version.rb
56
- - lib/achievements/agent.rb
54
+ - lib/achievements/achievements_engine.rb
55
+ - lib/achievements/counter.rb
57
56
  - lib/achievements/engine.rb
58
- - lib/achievements/achievement.rb
57
+ - lib/achievements/version.rb
59
58
  - lib/achievements.rb
60
59
  - test/achievements_test.rb
61
60
  - test/test_helper.rb
File without changes