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 +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
|