achievements 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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