minuteman 1.0.2 → 1.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/Gemfile +1 -1
- data/Gemfile.lock +12 -5
- data/HUGS +15 -0
- data/README.md +4 -1
- data/Rakefile +1 -1
- data/lib/minuteman.rb +24 -37
- data/lib/minuteman/time_events.rb +2 -2
- data/minuteman.gemspec +5 -4
- data/test/bench/minuteman_bench.rb +3 -3
- data/test/test_helper.rb +1 -0
- data/test/unit/minuteman_test.rb +171 -163
- metadata +24 -6
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,23 +1,30 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
minuteman (1.0.
|
5
|
-
redis (~> 3.0.
|
4
|
+
minuteman (1.0.3)
|
5
|
+
redis (~> 3.0.3)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: http://rubygems.org/
|
9
9
|
specs:
|
10
|
-
|
10
|
+
given_core (3.0.0)
|
11
|
+
sorcerer (>= 0.3.7)
|
12
|
+
minitest (4.3.2)
|
13
|
+
minitest-given (3.0.0)
|
14
|
+
given_core (= 3.0.0)
|
15
|
+
minitest (> 4.3)
|
11
16
|
rake (0.9.2.2)
|
12
|
-
redis (3.0.
|
17
|
+
redis (3.0.3)
|
13
18
|
redis-namespace (1.2.1)
|
14
19
|
redis (~> 3.0.0)
|
20
|
+
sorcerer (1.0.0)
|
15
21
|
|
16
22
|
PLATFORMS
|
17
23
|
ruby
|
18
24
|
|
19
25
|
DEPENDENCIES
|
20
|
-
minitest (~> 4.
|
26
|
+
minitest (~> 4.3.0)
|
27
|
+
minitest-given (~> 3.0.0)
|
21
28
|
minuteman!
|
22
29
|
rake
|
23
30
|
redis-namespace (~> 1.2.1)
|
data/HUGS
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
THE HUGWARE LICENSE
|
2
|
+
|
3
|
+
LICENSE
|
4
|
+
|
5
|
+
If there is no other license you can do whatever you want with this while you
|
6
|
+
retain the attribution to the author.
|
7
|
+
|
8
|
+
HUGS
|
9
|
+
|
10
|
+
The author spent time to make this software so please show some grattitude,
|
11
|
+
in any
|
12
|
+
form. A hug, a tweet, a beer on a conference or just a plain old email. Your
|
13
|
+
choice.
|
14
|
+
|
15
|
+
Less hate, more hugs.
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|

|
2
2
|
|
3
3
|
# Minuteman
|
4
|
-
[](https://codeclimate.com/github/elcuervo/minuteman)
|
5
5
|
[](https://travis-ci.org/elcuervo/minuteman)
|
6
6
|
|
7
7
|
_Wikipedia_: Minutemen were members of teams from Massachusetts that were well-prepared
|
@@ -63,6 +63,9 @@ Currently Minutemen supports two options `:silent (default: false)` and `:redis
|
|
63
63
|
|
64
64
|
**silent**: when `true` the operations will not raise errors to prevent failures
|
65
65
|
|
66
|
+
**time_spans**: an `Array` of Minuteman compatible `TimeSpan`. Eg. `%w[year month
|
67
|
+
day]` will only track events on that timespans. Ignoring the rest
|
68
|
+
|
66
69
|
**redis**: can be a Hash with the options to be sent to `Redis.new` or a `Redis`
|
67
70
|
connection already established (`Redis::Namespace` works as well).
|
68
71
|
|
data/Rakefile
CHANGED
data/lib/minuteman.rb
CHANGED
@@ -3,21 +3,6 @@ require "time"
|
|
3
3
|
require "forwardable"
|
4
4
|
require "minuteman/time_events"
|
5
5
|
|
6
|
-
# Until redis gem gets updated
|
7
|
-
class Redis
|
8
|
-
def bitop(operation, destkey, *keys)
|
9
|
-
synchronize do |client|
|
10
|
-
client.call([:bitop, operation, destkey] + keys)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def bitcount(key, start = 0, stop = -1)
|
15
|
-
synchronize do |client|
|
16
|
-
client.call([:bitcount, key, start, stop])
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
6
|
# Public: Minuteman core classs
|
22
7
|
#
|
23
8
|
class Minuteman
|
@@ -48,21 +33,9 @@ class Minuteman
|
|
48
33
|
|
49
34
|
self.options = default_options.merge!(options)
|
50
35
|
self.redis = define_connection(redis_options)
|
51
|
-
end
|
52
|
-
|
53
|
-
# Public: Generates the methods to fech data
|
54
|
-
#
|
55
|
-
# event_name - The event name to be searched for
|
56
|
-
# date - A Time object used to do the search
|
57
|
-
#
|
58
|
-
%w[year month week day hour minute].each do |method_name|
|
59
|
-
define_method(method_name) do |*args|
|
60
|
-
event_name, date = *args
|
61
|
-
date ||= Time.now.utc
|
62
36
|
|
63
|
-
|
64
|
-
|
65
|
-
end
|
37
|
+
spans = self.options.fetch(:time_spans, %w[year month week day hour minute])
|
38
|
+
@time_spans = generate_spans(spans)
|
66
39
|
end
|
67
40
|
|
68
41
|
# Public: Marks an id to a given event on a given time
|
@@ -78,7 +51,7 @@ class Minuteman
|
|
78
51
|
#
|
79
52
|
def track(event_name, ids, time = Time.now.utc)
|
80
53
|
event_time = time.kind_of?(Time) ? time : Time.parse(time.to_s)
|
81
|
-
time_events = TimeEvents.start(event_name, event_time)
|
54
|
+
time_events = TimeEvents.start(@time_spans, event_name, event_time)
|
82
55
|
|
83
56
|
track_events(time_events, Array(ids))
|
84
57
|
end
|
@@ -112,13 +85,29 @@ class Minuteman
|
|
112
85
|
|
113
86
|
private
|
114
87
|
|
88
|
+
# Public: Generates the methods to fech data
|
89
|
+
#
|
90
|
+
# spans: An array of timespans corresponding to a TimeSpan class
|
91
|
+
#
|
92
|
+
def generate_spans(spans)
|
93
|
+
spans.map do |method_name|
|
94
|
+
constructor = self.class.const_get(method_name.capitalize)
|
95
|
+
|
96
|
+
define_singleton_method(method_name) do |*args|
|
97
|
+
event_name, date = *args
|
98
|
+
date ||= Time.now.utc
|
99
|
+
|
100
|
+
constructor.new(event_name, date)
|
101
|
+
end
|
102
|
+
|
103
|
+
constructor
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
115
107
|
# Private: Default configuration options
|
116
108
|
#
|
117
109
|
def default_options
|
118
|
-
{
|
119
|
-
cache: true,
|
120
|
-
silent: false
|
121
|
-
}
|
110
|
+
{ cache: true, silent: false }
|
122
111
|
end
|
123
112
|
|
124
113
|
# Private: Determines to use or instance a Redis connection
|
@@ -157,8 +146,6 @@ class Minuteman
|
|
157
146
|
# Private: The prefix key of all the operations
|
158
147
|
#
|
159
148
|
def operations_cache_key_prefix
|
160
|
-
[
|
161
|
-
PREFIX, Minuteman::KeysMethods::BIT_OPERATION_PREFIX
|
162
|
-
].join("_")
|
149
|
+
[ PREFIX, Minuteman::KeysMethods::BIT_OPERATION_PREFIX ].join("_")
|
163
150
|
end
|
164
151
|
end
|
@@ -9,8 +9,8 @@ class Minuteman
|
|
9
9
|
# event_name - The event to be tracked
|
10
10
|
# date - A given Time object
|
11
11
|
#
|
12
|
-
def self.start(event_name, time)
|
13
|
-
|
12
|
+
def self.start(time_spans, event_name, time)
|
13
|
+
time_spans.map do |t|
|
14
14
|
t.new(event_name, time)
|
15
15
|
end
|
16
16
|
end
|
data/minuteman.gemspec
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "minuteman"
|
3
|
-
s.version = "1.0.
|
3
|
+
s.version = "1.0.3"
|
4
4
|
s.summary = "Bit Analytics"
|
5
5
|
s.description = "Fast and furious tracking system using Redis bitwise operations"
|
6
6
|
s.authors = ["elcuervo"]
|
7
|
-
s.licenses = ["MIT"]
|
7
|
+
s.licenses = ["MIT", "HUGWARE"]
|
8
8
|
s.email = ["yo@brunoaguirre.com"]
|
9
9
|
s.homepage = "http://github.com/elcuervo/minuteman"
|
10
10
|
s.files = `git ls-files`.split("\n")
|
11
11
|
s.test_files = `git ls-files test`.split("\n")
|
12
12
|
|
13
|
-
s.add_dependency("redis", "~> 3.0.
|
13
|
+
s.add_dependency("redis", "~> 3.0.3")
|
14
14
|
|
15
|
-
s.add_development_dependency("minitest", "~> 4.
|
15
|
+
s.add_development_dependency("minitest", "~> 4.3.0")
|
16
|
+
s.add_development_dependency("minitest-given", "~> 3.0.0")
|
16
17
|
s.add_development_dependency("redis-namespace", "~> 1.2.1")
|
17
18
|
end
|
@@ -7,9 +7,9 @@ describe Minuteman do
|
|
7
7
|
last_week = today - (3600 * 24 * 7)
|
8
8
|
|
9
9
|
@analytics = Minuteman.new
|
10
|
-
@analytics.
|
11
|
-
@analytics.
|
12
|
-
@analytics.
|
10
|
+
@analytics.track("login", 12)
|
11
|
+
@analytics.track("login", [2, 42])
|
12
|
+
@analytics.track("login:successful", 567, last_week)
|
13
13
|
|
14
14
|
@week_events = @analytics.week("login")
|
15
15
|
@last_week_events = @analytics.week("login", last_week)
|
data/test/test_helper.rb
CHANGED
data/test/unit/minuteman_test.rb
CHANGED
@@ -1,217 +1,225 @@
|
|
1
1
|
require_relative "../test_helper"
|
2
2
|
|
3
3
|
describe Minuteman do
|
4
|
-
|
5
|
-
@analytics = Minuteman.new
|
6
|
-
|
7
|
-
today = Time.now.utc
|
8
|
-
last_month = today - (3600 * 24 * 30)
|
9
|
-
last_week = today - (3600 * 24 * 7)
|
10
|
-
last_minute = today - 120
|
11
|
-
|
12
|
-
@analytics.track("login", 12)
|
13
|
-
@analytics.track("login", [2, 42])
|
14
|
-
@analytics.track("login", 2, last_week)
|
15
|
-
@analytics.track("login:successful", 567, last_month)
|
16
|
-
|
17
|
-
@year_events = @analytics.year("login", today)
|
18
|
-
@week_events = @analytics.week("login", today)
|
19
|
-
@month_events = @analytics.month("login", today)
|
20
|
-
@day_events = @analytics.day("login", today)
|
21
|
-
@hour_events = @analytics.hour("login", today)
|
22
|
-
@minute_events = @analytics.minute("login", today)
|
23
|
-
|
24
|
-
@last_week_events = @analytics.week("login", last_week)
|
25
|
-
@last_minute_events = @analytics.minute("login", last_minute)
|
26
|
-
@last_month_events = @analytics.month("login:successful", last_month)
|
27
|
-
end
|
28
|
-
|
29
|
-
after { @analytics.reset_all }
|
4
|
+
Given(:analytics) { Minuteman.new }
|
30
5
|
|
31
|
-
|
32
|
-
assert @analytics.redis
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should track an event on a time" do
|
36
|
-
assert_equal 3, @year_events.length
|
37
|
-
assert_equal 3, @week_events.length
|
38
|
-
assert_equal 1, @last_week_events.length
|
39
|
-
assert_equal 1, @last_month_events.length
|
40
|
-
assert_equal [true, true, false], @week_events.include?(12, 2, 1)
|
41
|
-
|
42
|
-
assert @year_events.include?(12)
|
43
|
-
assert @month_events.include?(12)
|
44
|
-
assert @day_events.include?(12)
|
45
|
-
assert @hour_events.include?(12)
|
46
|
-
assert @minute_events.include?(12)
|
47
|
-
|
48
|
-
assert @last_week_events.include?(2)
|
49
|
-
assert !@month_events.include?(5)
|
50
|
-
assert !@last_minute_events.include?(12)
|
51
|
-
assert @last_month_events.include?(567)
|
52
|
-
end
|
6
|
+
after { analytics.reset_all }
|
53
7
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
8
|
+
context "configuration" do
|
9
|
+
Then { analytics.redis }
|
10
|
+
Then { analytics.options[:cache] == true }
|
58
11
|
|
59
|
-
|
60
|
-
|
12
|
+
context "switching options" do
|
13
|
+
Given(:minuteman) { Minuteman.new }
|
61
14
|
|
62
|
-
|
15
|
+
When { minuteman.options[:cache] = false }
|
16
|
+
Then { minuteman.options[:cache] == false }
|
17
|
+
end
|
63
18
|
|
64
|
-
|
65
|
-
|
19
|
+
context "changing time spans" do
|
20
|
+
Given(:time_spans) { %w[year month day hour] }
|
21
|
+
Given(:minuteman) { Minuteman.new(time_spans: time_spans) }
|
66
22
|
|
67
|
-
|
68
|
-
@week_events & @last_week_events
|
69
|
-
assert_equal 1, @analytics.operations.size
|
23
|
+
When { minuteman.track("login", 12) }
|
70
24
|
|
71
|
-
|
25
|
+
Then { minuteman.respond_to?(:year) }
|
26
|
+
Then { minuteman.respond_to?(:month) }
|
27
|
+
Then { minuteman.respond_to?(:day) }
|
28
|
+
Then { minuteman.respond_to?(:hour) }
|
72
29
|
|
73
|
-
|
74
|
-
|
30
|
+
Then { !minuteman.respond_to?(:minute) }
|
31
|
+
Then { !minuteman.respond_to?(:week) }
|
75
32
|
|
76
|
-
|
77
|
-
|
33
|
+
Then { minuteman.redis.keys.size == 4 }
|
34
|
+
Then { minuteman.options[:time_spans] == time_spans }
|
35
|
+
end
|
78
36
|
|
79
|
-
|
80
|
-
|
37
|
+
context "fail silently" do
|
38
|
+
Given(:minuteman) { Minuteman.new(silent: true, redis: { port: 1234 }) }
|
39
|
+
When(:result) { minuteman.track("test", 1) }
|
40
|
+
Then { result == nil }
|
41
|
+
end
|
81
42
|
|
82
|
-
|
83
|
-
|
43
|
+
context "fail loudly" do
|
44
|
+
Given(:minuteman) { Minuteman.new(redis: { port: 1234 }) }
|
45
|
+
When(:result) { minuteman.track("test", 1) }
|
46
|
+
Then { result == Failure(Redis::CannotConnectError) }
|
47
|
+
end
|
84
48
|
|
85
|
-
|
49
|
+
context "changing Redis connection" do
|
50
|
+
Given(:redis) { Redis.new }
|
51
|
+
Then { Minuteman.redis != redis }
|
86
52
|
|
87
|
-
|
88
|
-
|
89
|
-
end
|
53
|
+
context "return the correct connection" do
|
54
|
+
When(:minuteman) { Minuteman.new(redis: redis) }
|
90
55
|
|
91
|
-
|
92
|
-
|
56
|
+
Then { minuteman.redis == redis }
|
57
|
+
end
|
93
58
|
|
94
|
-
|
95
|
-
|
96
|
-
|
59
|
+
context "switching the connection" do
|
60
|
+
Given(:minuteman) { Minuteman.new }
|
61
|
+
When { minuteman.redis = redis }
|
62
|
+
Then { redis == Minuteman.redis }
|
63
|
+
end
|
97
64
|
|
98
|
-
|
65
|
+
context "using Redis::Namespace" do
|
66
|
+
Given(:namespace) { Redis::Namespace.new(:ns, redis: Redis.new) }
|
67
|
+
Given(:minuteman) { Minuteman.new(redis: namespace) }
|
99
68
|
|
100
|
-
|
101
|
-
|
69
|
+
Then { minuteman.redis == namespace }
|
70
|
+
end
|
71
|
+
end
|
102
72
|
end
|
103
73
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
74
|
+
context "event tracking" do
|
75
|
+
Given(:today) { Time.now.utc }
|
76
|
+
Given(:last_month) { today - (3600 * 24 * 30) }
|
77
|
+
Given(:last_week) { today - (3600 * 24 * 7) }
|
78
|
+
Given(:last_minute) { today - 120 }
|
79
|
+
|
80
|
+
Given(:year_events) { analytics.year("login", today) }
|
81
|
+
Given(:week_events) { analytics.week("login", today) }
|
82
|
+
Given(:month_events) { analytics.month("login", today) }
|
83
|
+
Given(:day_events) { analytics.day("login", today) }
|
84
|
+
Given(:hour_events) { analytics.hour("login", today) }
|
85
|
+
Given(:minute_events) { analytics.minute("login", today) }
|
86
|
+
Given(:last_week_events) { analytics.week("login", last_week) }
|
87
|
+
Given(:last_minute_events) { analytics.minute("login", last_minute) }
|
88
|
+
Given(:last_month_events) { analytics.month("login:successful", last_month) }
|
89
|
+
|
90
|
+
before do
|
91
|
+
analytics.track("login", 12)
|
92
|
+
analytics.track("login", [2, 42])
|
93
|
+
analytics.track("login", 2, last_week)
|
94
|
+
analytics.track("login:successful", 567, last_month)
|
95
|
+
end
|
113
96
|
|
114
|
-
|
115
|
-
|
97
|
+
Then { analytics.events.size == 2 }
|
98
|
+
Then { year_events.length == 3 }
|
99
|
+
Then { week_events.length == 3 }
|
100
|
+
Then { last_week_events.length == 1 }
|
101
|
+
Then { last_month_events.length == 1 }
|
116
102
|
|
117
|
-
|
118
|
-
|
119
|
-
|
103
|
+
context "reseting" do
|
104
|
+
before { analytics.reset_all }
|
105
|
+
Then { analytics.events.size == 0 }
|
120
106
|
|
121
|
-
|
107
|
+
context "bit operations" do
|
108
|
+
before { week_events & last_week_events }
|
122
109
|
|
123
|
-
|
124
|
-
|
125
|
-
|
110
|
+
When { analytics.reset_operations_cache }
|
111
|
+
Then { analytics.operations.size == 0 }
|
112
|
+
end
|
113
|
+
end
|
126
114
|
|
127
|
-
|
128
|
-
|
115
|
+
context "on a given time" do
|
116
|
+
Then { year_events.length == 3 }
|
117
|
+
Then { week_events.length == 3 }
|
118
|
+
|
119
|
+
Then { week_events.include?(12, 2, 1) == [true, true, false] }
|
120
|
+
Then { year_events.include?(12) }
|
121
|
+
Then { month_events.include?(12) }
|
122
|
+
Then { day_events.include?(12) }
|
123
|
+
Then { hour_events.include?(12) }
|
124
|
+
Then { minute_events.include?(12) }
|
125
|
+
|
126
|
+
Then { last_week_events.include?(2) }
|
127
|
+
Then { !month_events.include?(5) }
|
128
|
+
Then { !last_minute_events.include?(12) }
|
129
|
+
Then { last_month_events.include?(567) }
|
130
|
+
end
|
129
131
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
132
|
+
context "listing events" do
|
133
|
+
Then { analytics.events.size == 2 }
|
134
|
+
Then { analytics.events.sort == ["login", "login:successful"] }
|
135
|
+
end
|
134
136
|
|
135
|
-
|
136
|
-
|
137
|
+
context "composing" do
|
138
|
+
context "using AND" do
|
139
|
+
Given(:and_operation) { week_events & last_week_events }
|
137
140
|
|
138
|
-
|
139
|
-
|
141
|
+
Then { week_events.include?(2) }
|
142
|
+
Then { week_events.include?(12) }
|
140
143
|
|
141
|
-
|
142
|
-
|
144
|
+
Then { last_week_events.include?(2) }
|
145
|
+
Then { !last_week_events.include?(12) }
|
143
146
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
it "should return the ids that do not belong to the given set" do
|
149
|
-
ids = @week_events - [2, 12, 43]
|
147
|
+
Then { !and_operation.include?(12) }
|
148
|
+
Then { and_operation.include?(2) }
|
149
|
+
Then { and_operation.length == 1 }
|
150
|
+
end
|
150
151
|
|
151
|
-
|
152
|
-
|
153
|
-
end
|
152
|
+
context "using OR" do
|
153
|
+
Given(:or_operation) { week_events | last_week_events }
|
154
154
|
|
155
|
-
|
156
|
-
|
155
|
+
Then { week_events.include?(2) }
|
156
|
+
Then { last_week_events.include?(2) }
|
157
|
+
Then { !last_week_events.include?(12) }
|
157
158
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
end
|
159
|
+
Then { or_operation.include?(12) }
|
160
|
+
Then { or_operation.include?(2) }
|
161
|
+
Then { or_operation.length == 3 }
|
162
|
+
end
|
163
163
|
|
164
|
-
|
165
|
-
|
166
|
-
minuteman = Minuteman.new
|
167
|
-
assert_equal true, minuteman.options[:cache]
|
164
|
+
context "using NOT" do
|
165
|
+
Given(:not_operation) { ~week_events }
|
168
166
|
|
169
|
-
|
167
|
+
Then { week_events.include?(2) }
|
168
|
+
Then { week_events.include?(12) }
|
170
169
|
|
171
|
-
|
172
|
-
|
173
|
-
end
|
170
|
+
Then { !not_operation.include?(12) }
|
171
|
+
Then { !not_operation.include?(2) }
|
172
|
+
end
|
174
173
|
|
175
|
-
|
176
|
-
|
177
|
-
redis = Redis.new
|
178
|
-
minuteman = Minuteman.new(redis: redis)
|
174
|
+
context "using OR alias (+)" do
|
175
|
+
Given(:or_operation) { week_events + last_week_events }
|
179
176
|
|
180
|
-
|
181
|
-
|
182
|
-
|
177
|
+
Then { week_events.include?(2) }
|
178
|
+
Then { last_week_events.include?(2) }
|
179
|
+
Then { !last_week_events.include?(12) }
|
183
180
|
|
184
|
-
|
185
|
-
|
186
|
-
|
181
|
+
Then { or_operation.include?(12) }
|
182
|
+
Then { or_operation.include?(2) }
|
183
|
+
Then { or_operation.length == 3 }
|
184
|
+
end
|
187
185
|
|
188
|
-
|
186
|
+
context "using MINUS" do
|
187
|
+
Given(:substract_operation) { year_events - week_events }
|
189
188
|
|
190
|
-
|
189
|
+
Then { week_events.include?(2) }
|
190
|
+
Then { year_events.include?(2) }
|
191
|
+
Then { !substract_operation.include?(2) }
|
192
|
+
end
|
193
|
+
end
|
191
194
|
|
192
|
-
|
193
|
-
|
195
|
+
context "composing multiple operations" do
|
196
|
+
Given(:multi_operation) { week_events & last_week_events | year_events }
|
197
|
+
Then { multi_operation.is_a?(Minuteman::BitOperations::Result) }
|
198
|
+
end
|
194
199
|
|
195
|
-
|
196
|
-
|
200
|
+
context "composing against arrays" do
|
201
|
+
context "using AND returns the intersection" do
|
202
|
+
Given(:ids) { week_events & [2, 12, 43] }
|
197
203
|
|
198
|
-
|
204
|
+
Then { ids.is_a?(Minuteman::BitOperations::Data) }
|
205
|
+
Then { ids == [2, 12] }
|
206
|
+
end
|
199
207
|
|
200
|
-
|
201
|
-
|
202
|
-
end
|
208
|
+
context "using MINUS returns the difference" do
|
209
|
+
Given(:ids) { week_events - [2, 12, 43] }
|
203
210
|
|
204
|
-
|
205
|
-
|
211
|
+
Then { ids.is_a?(Minuteman::BitOperations::Data) }
|
212
|
+
Then { ids == [43] }
|
213
|
+
end
|
206
214
|
|
207
|
-
|
208
|
-
|
215
|
+
context "returns an object that behaves like Array" do
|
216
|
+
Given(:ids) { week_events & [2, 12, 43] }
|
209
217
|
|
210
|
-
|
211
|
-
|
218
|
+
Then { ids.each.is_a?(Enumerator) }
|
219
|
+
Then { ids.map.is_a?(Enumerator) }
|
220
|
+
Then { ids.size == 2 }
|
221
|
+
end
|
212
222
|
|
213
|
-
assert_raises Redis::CannotConnectError do
|
214
|
-
minuteman.track("test", 1)
|
215
223
|
end
|
216
224
|
end
|
217
225
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minuteman
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-10-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 3.0.
|
21
|
+
version: 3.0.3
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 3.0.
|
29
|
+
version: 3.0.3
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: minitest
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 4.
|
37
|
+
version: 4.3.0
|
38
38
|
type: :development
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,23 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 4.
|
45
|
+
version: 4.3.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: minitest-given
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 3.0.0
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.0.0
|
46
62
|
- !ruby/object:Gem::Dependency
|
47
63
|
name: redis-namespace
|
48
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -69,6 +85,7 @@ files:
|
|
69
85
|
- .travis.yml
|
70
86
|
- Gemfile
|
71
87
|
- Gemfile.lock
|
88
|
+
- HUGS
|
72
89
|
- LICENSE
|
73
90
|
- README.md
|
74
91
|
- Rakefile
|
@@ -96,6 +113,7 @@ files:
|
|
96
113
|
homepage: http://github.com/elcuervo/minuteman
|
97
114
|
licenses:
|
98
115
|
- MIT
|
116
|
+
- HUGWARE
|
99
117
|
post_install_message:
|
100
118
|
rdoc_options: []
|
101
119
|
require_paths:
|