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 +10 -2
- data/lib/achievements/achievements_agent.rb +5 -0
- data/lib/achievements/achievements_engine.rb +7 -3
- data/lib/achievements/engine.rb +43 -9
- data/lib/achievements/version.rb +1 -1
- data/test/achievements_test.rb +87 -4
- data/test/test_helper.rb +1 -1
- metadata +8 -9
- data/lib/achievements/agent.rb +0 -0
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
|
@@ -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
|
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
|
-
|
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
|
data/lib/achievements/engine.rb
CHANGED
@@ -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
|
-
#
|
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
|
-
#
|
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
|
data/lib/achievements/version.rb
CHANGED
data/test/achievements_test.rb
CHANGED
@@ -1,17 +1,51 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
2
|
|
3
|
-
context "Achievement
|
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
|
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
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:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
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-
|
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/
|
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/
|
56
|
-
- lib/achievements/
|
54
|
+
- lib/achievements/achievements_engine.rb
|
55
|
+
- lib/achievements/counter.rb
|
57
56
|
- lib/achievements/engine.rb
|
58
|
-
- lib/achievements/
|
57
|
+
- lib/achievements/version.rb
|
59
58
|
- lib/achievements.rb
|
60
59
|
- test/achievements_test.rb
|
61
60
|
- test/test_helper.rb
|
data/lib/achievements/agent.rb
DELETED
File without changes
|