abaci 0.1.0 → 0.2.0
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/CHANGELOG.md +7 -0
- data/lib/abaci.rb +31 -0
- data/lib/abaci/counter.rb +11 -13
- data/lib/abaci/date_range.rb +41 -0
- data/lib/abaci/metric.rb +15 -0
- data/lib/abaci/store.rb +23 -3
- data/lib/abaci/version.rb +1 -1
- data/test/counter_test.rb +199 -0
- data/test/date_range_test.rb +95 -0
- data/test/helper.rb +23 -0
- data/test/store_test.rb +81 -0
- metadata +7 -1
data/CHANGELOG.md
CHANGED
data/lib/abaci.rb
CHANGED
@@ -2,6 +2,8 @@ require 'abaci/version'
|
|
2
2
|
|
3
3
|
module Abaci
|
4
4
|
autoload :Counter, 'abaci/counter'
|
5
|
+
autoload :DateRange, 'abaci/date_range'
|
6
|
+
autoload :Metric, 'abaci/metric'
|
5
7
|
autoload :Store, 'abaci/store'
|
6
8
|
|
7
9
|
# Configuration options
|
@@ -10,6 +12,11 @@ module Abaci
|
|
10
12
|
Counter[key]
|
11
13
|
end
|
12
14
|
|
15
|
+
# Gets all specific metrics stored, without date-specific keys
|
16
|
+
def metrics
|
17
|
+
Metric.all
|
18
|
+
end
|
19
|
+
|
13
20
|
def options
|
14
21
|
@options ||= {
|
15
22
|
:redis => nil,
|
@@ -17,12 +24,36 @@ module Abaci
|
|
17
24
|
}
|
18
25
|
end
|
19
26
|
|
27
|
+
def prefix=(value)
|
28
|
+
@store = nil
|
29
|
+
options[:prefix] = value
|
30
|
+
end
|
31
|
+
|
20
32
|
def prefix
|
21
33
|
options[:prefix]
|
22
34
|
end
|
23
35
|
|
36
|
+
def redis=(value)
|
37
|
+
@store = nil
|
38
|
+
options[:redis] = value
|
39
|
+
end
|
40
|
+
|
24
41
|
def store
|
25
42
|
@store ||= Store.new(options)
|
26
43
|
end
|
44
|
+
alias_method :redis, :store
|
45
|
+
|
46
|
+
def summary
|
47
|
+
Counter.all
|
48
|
+
end
|
49
|
+
|
50
|
+
def method_missing(method, *args)
|
51
|
+
Counter.send(method, *args)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Alias Stat to Abaci::Counter if nothing else is using the Stat namespace
|
56
|
+
unless defined?(::Stat)
|
57
|
+
::Stat = Counter
|
27
58
|
end
|
28
59
|
end
|
data/lib/abaci/counter.rb
CHANGED
@@ -18,6 +18,7 @@ module Abaci
|
|
18
18
|
|
19
19
|
def del
|
20
20
|
keys.each { |k| Abaci.store.del(k) }
|
21
|
+
Metric.remove(key)
|
21
22
|
true
|
22
23
|
end
|
23
24
|
|
@@ -27,9 +28,7 @@ module Abaci
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def get_last_days(number_of_days = 30)
|
30
|
-
|
31
|
-
start = (Date.today - Rational(seconds, 86400)).to_date
|
32
|
-
dates = (start..Date.today).map { |d| d.strftime('%Y:%-m:%-d') }
|
31
|
+
dates = DateRange.ago(number_of_days).keys
|
33
32
|
dates.map { |date| Abaci.store.get("#{key}:#{date}" ).to_i }.reduce(:+)
|
34
33
|
end
|
35
34
|
|
@@ -40,6 +39,7 @@ module Abaci
|
|
40
39
|
|
41
40
|
def increment_at(date = nil, by = 1)
|
42
41
|
date = Time.now unless date.respond_to?(:strftime)
|
42
|
+
Metric.add(key)
|
43
43
|
run(:incrby, by, date)
|
44
44
|
end
|
45
45
|
|
@@ -50,9 +50,14 @@ module Abaci
|
|
50
50
|
## Class methods ##
|
51
51
|
############################################################################
|
52
52
|
|
53
|
+
# Alias for Counter#new(key)
|
54
|
+
def self.[](key)
|
55
|
+
Counter.new(key)
|
56
|
+
end
|
57
|
+
|
53
58
|
# Returns a hash of all current values
|
54
59
|
def self.all
|
55
|
-
|
60
|
+
Metric.all.inject({}) { |hash, key| hash[key.to_sym] = Abaci.store.get(key).to_i; hash }
|
56
61
|
end
|
57
62
|
|
58
63
|
# Gets all currently logged stat keys
|
@@ -60,11 +65,6 @@ module Abaci
|
|
60
65
|
Abaci.store.keys(search).sort
|
61
66
|
end
|
62
67
|
|
63
|
-
# Alias for Counter#new(key)
|
64
|
-
def self.[](key)
|
65
|
-
Counter.new(key)
|
66
|
-
end
|
67
|
-
|
68
68
|
def self.method_missing(method, *args)
|
69
69
|
ms = method.to_s.downcase.strip
|
70
70
|
|
@@ -74,11 +74,9 @@ module Abaci
|
|
74
74
|
return self[$2].del
|
75
75
|
elsif ms =~ /^last_(\d*)_days_of_([a-z_]*)$/
|
76
76
|
return self[$2].get_last_days($1)
|
77
|
-
|
78
|
-
|
77
|
+
else
|
78
|
+
self[ms].get(*args)
|
79
79
|
end
|
80
|
-
|
81
|
-
super
|
82
80
|
end
|
83
81
|
|
84
82
|
## Protected methods ##
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Abaci
|
2
|
+
class DateRange
|
3
|
+
attr_reader :start, :finish
|
4
|
+
|
5
|
+
def initialize(start, finish)
|
6
|
+
if start < finish
|
7
|
+
@start = start
|
8
|
+
@finish = finish
|
9
|
+
else
|
10
|
+
@start = finish
|
11
|
+
@finish = start
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def days
|
16
|
+
range.to_a
|
17
|
+
end
|
18
|
+
|
19
|
+
def keys
|
20
|
+
days.map { |d| d.strftime('%Y:%-m:%-d') }
|
21
|
+
end
|
22
|
+
|
23
|
+
def range
|
24
|
+
start..finish
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.ago(days = 30)
|
28
|
+
seconds = days.to_i * 86400
|
29
|
+
start = (Date.today - Rational(seconds, 86400)).to_date
|
30
|
+
new(start, Date.today)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.between(start, finish)
|
34
|
+
new(start, finish)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.since(date)
|
38
|
+
new(date, Date.today)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/abaci/metric.rb
ADDED
data/lib/abaci/store.rb
CHANGED
@@ -4,6 +4,8 @@ module Abaci
|
|
4
4
|
# Common interface for Redis. In the future this could be
|
5
5
|
# swapped out for an alternate datastore.
|
6
6
|
class Store
|
7
|
+
attr_reader :prefix, :redis
|
8
|
+
|
7
9
|
def initialize(options)
|
8
10
|
@redis = options[:redis] || Redis.current
|
9
11
|
@prefix = options[:prefix] || 'ab'
|
@@ -25,8 +27,8 @@ module Abaci
|
|
25
27
|
exec(:incrby, key, by)
|
26
28
|
end
|
27
29
|
|
28
|
-
def keys(pattern)
|
29
|
-
sub = Regexp.new("^#{
|
30
|
+
def keys(pattern = "*")
|
31
|
+
sub = Regexp.new("^#{prefix}:")
|
30
32
|
exec(:keys, pattern).map { |k| k.gsub(sub, '') }
|
31
33
|
end
|
32
34
|
|
@@ -34,6 +36,18 @@ module Abaci
|
|
34
36
|
exec(:set, key, value)
|
35
37
|
end
|
36
38
|
|
39
|
+
def sadd(key, member)
|
40
|
+
exec_without_prefix(:sadd, "#{prefix}-#{key}", member)
|
41
|
+
end
|
42
|
+
|
43
|
+
def smembers(key)
|
44
|
+
exec_without_prefix(:smembers, "#{prefix}-#{key}")
|
45
|
+
end
|
46
|
+
|
47
|
+
def srem(key, member)
|
48
|
+
exec_without_prefix(:srem, "#{prefix}-#{key}", member)
|
49
|
+
end
|
50
|
+
|
37
51
|
protected
|
38
52
|
def exec(command, key, *args)
|
39
53
|
if @redis and @redis.respond_to?(command)
|
@@ -41,8 +55,14 @@ module Abaci
|
|
41
55
|
end
|
42
56
|
end
|
43
57
|
|
58
|
+
def exec_without_prefix(command, key, *args)
|
59
|
+
if @redis and @redis.respond_to?(command)
|
60
|
+
@redis.send(command, key, *args)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
44
64
|
def prefixed_key(key)
|
45
|
-
[
|
65
|
+
[ prefix, key ].compact.join(':')
|
46
66
|
end
|
47
67
|
end
|
48
68
|
end
|
data/lib/abaci/version.rb
CHANGED
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class CounterTest < Test::Unit::TestCase
|
4
|
+
context "A counter" do
|
5
|
+
should "increment a stat" do
|
6
|
+
assert_equal 0, Abaci['testers'].get
|
7
|
+
|
8
|
+
Abaci['testers'].increment
|
9
|
+
|
10
|
+
assert_equal 1, Abaci['testers'].get
|
11
|
+
|
12
|
+
Abaci['testers'].increment(2)
|
13
|
+
|
14
|
+
assert_equal 3, Abaci['testers'].get
|
15
|
+
end
|
16
|
+
|
17
|
+
should "decrement a stat" do
|
18
|
+
assert_equal 0, Abaci['testers'].get
|
19
|
+
|
20
|
+
Abaci['testers'].increment(5)
|
21
|
+
assert_equal 5, Abaci['testers'].get
|
22
|
+
|
23
|
+
Abaci['testers'].decrement
|
24
|
+
assert_equal 4, Abaci['testers'].get
|
25
|
+
|
26
|
+
Abaci['testers'].decrement(2)
|
27
|
+
assert_equal 2, Abaci['testers'].get
|
28
|
+
end
|
29
|
+
|
30
|
+
should "increment a stat down to the minute" do
|
31
|
+
now = Time.now
|
32
|
+
|
33
|
+
Abaci['people'].increment
|
34
|
+
|
35
|
+
expected_keys = [
|
36
|
+
'people',
|
37
|
+
"people:#{now.strftime('%Y')}",
|
38
|
+
"people:#{now.strftime('%Y:%-m')}",
|
39
|
+
"people:#{now.strftime('%Y:%-m:%-d')}",
|
40
|
+
"people:#{now.strftime('%Y:%-m:%-d:%-k')}",
|
41
|
+
"people:#{now.strftime('%Y:%-m:%-d:%-k:%-M')}"
|
42
|
+
].sort
|
43
|
+
|
44
|
+
assert_equal expected_keys, Abaci['people'].keys.sort
|
45
|
+
|
46
|
+
assert_equal 1, Abaci['people'].get
|
47
|
+
assert_equal 1, Abaci['people'].get(now.year)
|
48
|
+
assert_equal 1, Abaci['people'].get(now.year, now.month)
|
49
|
+
assert_equal 1, Abaci['people'].get(now.year, now.month, now.day)
|
50
|
+
assert_equal 1, Abaci['people'].get(now.year, now.month, now.day, now.hour)
|
51
|
+
assert_equal 1, Abaci['people'].get(now.year, now.month, now.day, now.hour, now.min)
|
52
|
+
end
|
53
|
+
|
54
|
+
should "increment a stat at a certain date" do
|
55
|
+
time = Time.new(2012, 2, 29, 23, 29)
|
56
|
+
|
57
|
+
Abaci['people'].increment_at(time)
|
58
|
+
|
59
|
+
expected_keys = [
|
60
|
+
'people',
|
61
|
+
"people:2012",
|
62
|
+
"people:2012:2",
|
63
|
+
"people:2012:2:29",
|
64
|
+
"people:2012:2:29:23",
|
65
|
+
"people:2012:2:29:23:29"
|
66
|
+
].sort
|
67
|
+
|
68
|
+
assert_equal expected_keys, Abaci['people'].keys.sort
|
69
|
+
|
70
|
+
assert_equal 1, Abaci['people'].get
|
71
|
+
assert_equal 1, Abaci['people'].get(2012)
|
72
|
+
assert_equal 1, Abaci['people'].get(2012, 2)
|
73
|
+
assert_equal 1, Abaci['people'].get(2012, 2, 29)
|
74
|
+
assert_equal 1, Abaci['people'].get(2012, 2, 29, 23)
|
75
|
+
assert_equal 1, Abaci['people'].get(2012, 2, 29, 23, 29)
|
76
|
+
end
|
77
|
+
|
78
|
+
should "get stats summary for last 5 days" do
|
79
|
+
time = Time.new(2012, 5, 30, 5, 0)
|
80
|
+
time2 = Time.new(2012, 5, 31, 5, 0)
|
81
|
+
time3 = Time.new(2012, 6, 1, 5, 0)
|
82
|
+
time4 = Time.new(2012, 6, 2, 5, 0)
|
83
|
+
|
84
|
+
Abaci['people'].increment_at(time)
|
85
|
+
Abaci['people'].increment_at(time2)
|
86
|
+
Abaci['people'].increment_at(time3)
|
87
|
+
Abaci['people'].increment_at(time4)
|
88
|
+
Abaci['people'].increment
|
89
|
+
|
90
|
+
Date.stubs(:today).returns(Date.new(2012, 6, 2))
|
91
|
+
|
92
|
+
assert_equal 5, Abaci['people'].get
|
93
|
+
assert_equal 4, Abaci['people'].get_last_days(30)
|
94
|
+
assert_equal 3, Abaci['people'].get_last_days(2)
|
95
|
+
assert_equal 2, Abaci['people'].get_last_days(1)
|
96
|
+
|
97
|
+
Date.unstub(:today)
|
98
|
+
end
|
99
|
+
|
100
|
+
should "delete stats for a given key" do
|
101
|
+
time = Time.new(2012, 2, 29, 23, 29)
|
102
|
+
|
103
|
+
Abaci['people'].increment_at(time)
|
104
|
+
|
105
|
+
expected_keys = [
|
106
|
+
'people',
|
107
|
+
"people:2012",
|
108
|
+
"people:2012:2",
|
109
|
+
"people:2012:2:29",
|
110
|
+
"people:2012:2:29:23",
|
111
|
+
"people:2012:2:29:23:29"
|
112
|
+
].sort
|
113
|
+
|
114
|
+
assert_equal expected_keys, Abaci['people'].keys.sort
|
115
|
+
|
116
|
+
Abaci['people'].del
|
117
|
+
|
118
|
+
assert_equal [], Abaci['people'].keys
|
119
|
+
end
|
120
|
+
|
121
|
+
should "return all stat keys across all metrics" do
|
122
|
+
time = Time.new(2012, 2, 29, 23, 29)
|
123
|
+
|
124
|
+
Abaci['people'].increment_at(time)
|
125
|
+
Abaci['places'].increment_at(time)
|
126
|
+
Abaci['things'].increment_at(time)
|
127
|
+
|
128
|
+
expected_keys = [
|
129
|
+
'people',
|
130
|
+
"people:2012",
|
131
|
+
"people:2012:2",
|
132
|
+
"people:2012:2:29",
|
133
|
+
"people:2012:2:29:23",
|
134
|
+
"people:2012:2:29:23:29",
|
135
|
+
'places',
|
136
|
+
"places:2012",
|
137
|
+
"places:2012:2",
|
138
|
+
"places:2012:2:29",
|
139
|
+
"places:2012:2:29:23",
|
140
|
+
"places:2012:2:29:23:29",
|
141
|
+
'things',
|
142
|
+
"things:2012",
|
143
|
+
"things:2012:2",
|
144
|
+
"things:2012:2:29",
|
145
|
+
"things:2012:2:29:23",
|
146
|
+
"things:2012:2:29:23:29"
|
147
|
+
].sort
|
148
|
+
|
149
|
+
assert_equal expected_keys, Abaci.keys.sort
|
150
|
+
end
|
151
|
+
|
152
|
+
should "return all metrics stores, without date-specific keys" do
|
153
|
+
time = Time.new(2012, 2, 29, 23, 29)
|
154
|
+
|
155
|
+
Abaci['people'].increment_at(time)
|
156
|
+
Abaci['places'].increment_at(time)
|
157
|
+
Abaci['things'].increment_at(time)
|
158
|
+
|
159
|
+
expected_keys = %w( people places things ).sort
|
160
|
+
|
161
|
+
assert_equal expected_keys, Abaci.metrics.sort
|
162
|
+
end
|
163
|
+
|
164
|
+
should "return a hash of all top-level metrics and current values" do
|
165
|
+
Abaci['people'].increment
|
166
|
+
Abaci['places'].increment
|
167
|
+
Abaci['things'].increment(2)
|
168
|
+
|
169
|
+
expected_result = {
|
170
|
+
:people => 1,
|
171
|
+
:places => 1,
|
172
|
+
:things => 2
|
173
|
+
}
|
174
|
+
|
175
|
+
assert_equal expected_result, Abaci.summary
|
176
|
+
end
|
177
|
+
|
178
|
+
should "have handy shortcuts for incrementing simple metrics" do
|
179
|
+
Abaci.increment_people
|
180
|
+
Abaci.increment_places(2)
|
181
|
+
Abaci.increase_things
|
182
|
+
Abaci.incr_people
|
183
|
+
|
184
|
+
assert_equal 2, Abaci.people
|
185
|
+
assert_equal 2, Abaci.places
|
186
|
+
assert_equal 1, Abaci.things
|
187
|
+
|
188
|
+
Abaci.decrease_things
|
189
|
+
|
190
|
+
assert_equal 0, Abaci.things
|
191
|
+
|
192
|
+
Abaci.clear_people!
|
193
|
+
|
194
|
+
assert_equal 0, Abaci.people
|
195
|
+
|
196
|
+
assert_equal 2, Abaci.last_20_days_of_places
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class DateRangeTest < Test::Unit::TestCase
|
4
|
+
context "The date range calculator" do
|
5
|
+
should "get a day X days in the past" do
|
6
|
+
time = Date.new(2012, 11, 6)
|
7
|
+
expected_time = Date.new(2012, 11, 1)
|
8
|
+
|
9
|
+
Date.stubs(:today).returns(time)
|
10
|
+
|
11
|
+
assert_equal expected_time, Abaci::DateRange.ago(5).start
|
12
|
+
|
13
|
+
Date.unstub(:today)
|
14
|
+
end
|
15
|
+
|
16
|
+
should "get days since a given date" do
|
17
|
+
time = Date.new(2012, 11, 6)
|
18
|
+
expected_time = Date.new(2012, 11, 1)
|
19
|
+
|
20
|
+
Date.stubs(:today).returns(time)
|
21
|
+
|
22
|
+
since = Abaci::DateRange.since(expected_time)
|
23
|
+
|
24
|
+
assert_equal expected_time, since.start
|
25
|
+
assert_equal time, since.finish
|
26
|
+
|
27
|
+
Date.unstub(:today)
|
28
|
+
end
|
29
|
+
|
30
|
+
should "get days between a given date range" do
|
31
|
+
day1 = Date.new(2012, 11, 1)
|
32
|
+
day2 = Date.new(2012, 11, 6)
|
33
|
+
|
34
|
+
range = Abaci::DateRange.between(day1, day2)
|
35
|
+
|
36
|
+
assert_equal day1, range.start
|
37
|
+
assert_equal day2, range.finish
|
38
|
+
end
|
39
|
+
|
40
|
+
should "make days are in order" do
|
41
|
+
day1 = Date.new(2012, 11, 1)
|
42
|
+
day2 = Date.new(2012, 11, 6)
|
43
|
+
|
44
|
+
range = Abaci::DateRange.between(day2, day1)
|
45
|
+
|
46
|
+
assert_equal day1, range.start
|
47
|
+
assert_equal day2, range.finish
|
48
|
+
end
|
49
|
+
|
50
|
+
should "have a range of days" do
|
51
|
+
day1 = Date.new(2012, 11, 1)
|
52
|
+
day2 = Date.new(2012, 11, 6)
|
53
|
+
|
54
|
+
range = Abaci::DateRange.between(day2, day1)
|
55
|
+
|
56
|
+
assert_equal (day1..day2), range.range
|
57
|
+
end
|
58
|
+
|
59
|
+
should "have an array of days" do
|
60
|
+
day1 = Date.new(2012, 11, 1)
|
61
|
+
day2 = Date.new(2012, 11, 6)
|
62
|
+
|
63
|
+
range = Abaci::DateRange.between(day2, day1)
|
64
|
+
|
65
|
+
expected_result = [
|
66
|
+
Date.new(2012, 11, 1),
|
67
|
+
Date.new(2012, 11, 2),
|
68
|
+
Date.new(2012, 11, 3),
|
69
|
+
Date.new(2012, 11, 4),
|
70
|
+
Date.new(2012, 11, 5),
|
71
|
+
Date.new(2012, 11, 6)
|
72
|
+
]
|
73
|
+
|
74
|
+
assert_equal expected_result, range.days
|
75
|
+
end
|
76
|
+
|
77
|
+
should "have a list of store keys for a range" do
|
78
|
+
day1 = Date.new(2012, 11, 1)
|
79
|
+
day2 = Date.new(2012, 11, 6)
|
80
|
+
|
81
|
+
range = Abaci::DateRange.between(day2, day1)
|
82
|
+
|
83
|
+
expected_result = [
|
84
|
+
'2012:11:1',
|
85
|
+
'2012:11:2',
|
86
|
+
'2012:11:3',
|
87
|
+
'2012:11:4',
|
88
|
+
'2012:11:5',
|
89
|
+
'2012:11:6'
|
90
|
+
]
|
91
|
+
|
92
|
+
assert_equal expected_result, range.keys
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# SimpleCov provides test coverage in ruby 1.9 environments only, fail silently
|
2
|
+
# if it is not available
|
3
|
+
begin; require 'simplecov'; rescue LoadError; end
|
4
|
+
|
5
|
+
require 'shoulda'
|
6
|
+
require 'test/unit'
|
7
|
+
require 'mocha'
|
8
|
+
require 'redis'
|
9
|
+
require 'abaci'
|
10
|
+
|
11
|
+
# Fail silently if Turn is not available (runs in 1.9+ only)
|
12
|
+
begin; require 'turn/autorun'; rescue LoadError; end
|
13
|
+
|
14
|
+
REDIS = Redis.new(:db => 1)
|
15
|
+
|
16
|
+
Abaci.redis = REDIS
|
17
|
+
|
18
|
+
class Test::Unit::TestCase
|
19
|
+
def setup
|
20
|
+
REDIS.flushdb
|
21
|
+
Abaci.prefix = 'ab-test'
|
22
|
+
end
|
23
|
+
end
|
data/test/store_test.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class StoreTest < Test::Unit::TestCase
|
4
|
+
context "The abaci store" do
|
5
|
+
should "use a prefix for storage" do
|
6
|
+
Abaci.prefix = 'ab-test'
|
7
|
+
assert_equal 'ab-test', Abaci.prefix
|
8
|
+
|
9
|
+
assert_equal 0, Abaci['prefixes'].get
|
10
|
+
|
11
|
+
assert_equal nil, REDIS.get("ab-test:prefixes")
|
12
|
+
|
13
|
+
Abaci['prefixes'].increment
|
14
|
+
assert_equal 1, Abaci['prefixes'].get
|
15
|
+
|
16
|
+
assert_equal "1", REDIS.get("ab-test:prefixes")
|
17
|
+
end
|
18
|
+
|
19
|
+
should "be able to change the prefix" do
|
20
|
+
Abaci.prefix = 'ab-test-too'
|
21
|
+
|
22
|
+
assert_equal nil, REDIS.get("ab-test:prefixes")
|
23
|
+
assert_equal nil, REDIS.get("ab-test-too:prefixes")
|
24
|
+
|
25
|
+
Abaci.store.set 'prefixes', 1
|
26
|
+
|
27
|
+
assert_equal nil, REDIS.get("ab-test:prefixes")
|
28
|
+
assert_equal "1", REDIS.get("ab-test-too:prefixes")
|
29
|
+
end
|
30
|
+
|
31
|
+
should "list out all keys without prefixes" do
|
32
|
+
now = Time.now
|
33
|
+
|
34
|
+
Abaci['people'].increment
|
35
|
+
|
36
|
+
expected_redis_keys = [
|
37
|
+
'ab-test:people',
|
38
|
+
"ab-test:people:#{now.strftime('%Y')}",
|
39
|
+
"ab-test:people:#{now.strftime('%Y:%-m')}",
|
40
|
+
"ab-test:people:#{now.strftime('%Y:%-m:%-d')}",
|
41
|
+
"ab-test:people:#{now.strftime('%Y:%-m:%-d:%-k')}",
|
42
|
+
"ab-test:people:#{now.strftime('%Y:%-m:%-d:%-k:%-M')}"
|
43
|
+
].sort
|
44
|
+
|
45
|
+
assert_equal expected_redis_keys, REDIS.keys("ab-test:*").sort
|
46
|
+
|
47
|
+
expected_abaci_keys = [
|
48
|
+
'people',
|
49
|
+
"people:#{now.strftime('%Y')}",
|
50
|
+
"people:#{now.strftime('%Y:%-m')}",
|
51
|
+
"people:#{now.strftime('%Y:%-m:%-d')}",
|
52
|
+
"people:#{now.strftime('%Y:%-m:%-d:%-k')}",
|
53
|
+
"people:#{now.strftime('%Y:%-m:%-d:%-k:%-M')}"
|
54
|
+
].sort
|
55
|
+
|
56
|
+
assert_equal expected_abaci_keys, Abaci.store.keys.sort
|
57
|
+
end
|
58
|
+
|
59
|
+
should "be able to delete keys" do
|
60
|
+
Abaci['ipods'].increment
|
61
|
+
|
62
|
+
assert_equal 1, Abaci['ipods'].get
|
63
|
+
|
64
|
+
Abaci.store.del('ipods')
|
65
|
+
|
66
|
+
assert_equal 0, Abaci['ipods'].get
|
67
|
+
end
|
68
|
+
|
69
|
+
should "add list and remove items from a set" do
|
70
|
+
Abaci.store.sadd('_metrics', 'people')
|
71
|
+
Abaci.store.sadd('_metrics', 'places')
|
72
|
+
Abaci.store.sadd('_metrics', 'things')
|
73
|
+
|
74
|
+
assert_equal %w( people places things ).sort, Abaci.store.smembers('_metrics').sort
|
75
|
+
|
76
|
+
Abaci.store.srem('_metrics', 'things')
|
77
|
+
|
78
|
+
assert_equal %w( people places ).sort, Abaci.store.smembers('_metrics').sort
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abaci
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -35,7 +35,13 @@ executables: []
|
|
35
35
|
extensions: []
|
36
36
|
extra_rdoc_files: []
|
37
37
|
files:
|
38
|
+
- test/counter_test.rb
|
39
|
+
- test/date_range_test.rb
|
40
|
+
- test/helper.rb
|
41
|
+
- test/store_test.rb
|
38
42
|
- lib/abaci/counter.rb
|
43
|
+
- lib/abaci/date_range.rb
|
44
|
+
- lib/abaci/metric.rb
|
39
45
|
- lib/abaci/store.rb
|
40
46
|
- lib/abaci/version.rb
|
41
47
|
- lib/abaci.rb
|