tabstabs 2.0.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.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +421 -0
- data/Rakefile +5 -0
- data/lib/tabs_tabs.rb +26 -0
- data/lib/tabs_tabs/config.rb +65 -0
- data/lib/tabs_tabs/helpers.rb +27 -0
- data/lib/tabs_tabs/metrics/counter.rb +69 -0
- data/lib/tabs_tabs/metrics/counter/stats.rb +51 -0
- data/lib/tabs_tabs/metrics/task.rb +72 -0
- data/lib/tabs_tabs/metrics/task/token.rb +89 -0
- data/lib/tabs_tabs/metrics/value.rb +91 -0
- data/lib/tabs_tabs/metrics/value/stats.rb +55 -0
- data/lib/tabs_tabs/resolution.rb +65 -0
- data/lib/tabs_tabs/resolutionable.rb +48 -0
- data/lib/tabs_tabs/resolutions/day.rb +40 -0
- data/lib/tabs_tabs/resolutions/hour.rb +40 -0
- data/lib/tabs_tabs/resolutions/minute.rb +40 -0
- data/lib/tabs_tabs/resolutions/month.rb +40 -0
- data/lib/tabs_tabs/resolutions/week.rb +40 -0
- data/lib/tabs_tabs/resolutions/year.rb +40 -0
- data/lib/tabs_tabs/storage.rb +105 -0
- data/lib/tabs_tabs/tabs_tabs.rb +117 -0
- data/lib/tabs_tabs/version.rb +3 -0
- data/spec/lib/tabs_tabs/config_spec.rb +60 -0
- data/spec/lib/tabs_tabs/metrics/counter/stats_spec.rb +42 -0
- data/spec/lib/tabs_tabs/metrics/counter_spec.rb +196 -0
- data/spec/lib/tabs_tabs/metrics/task/token_spec.rb +18 -0
- data/spec/lib/tabs_tabs/metrics/task_spec.rb +103 -0
- data/spec/lib/tabs_tabs/metrics/value/stats_spec.rb +61 -0
- data/spec/lib/tabs_tabs/metrics/value_spec.rb +160 -0
- data/spec/lib/tabs_tabs/resolution_spec.rb +52 -0
- data/spec/lib/tabs_tabs/resolutionable_spec.rb +53 -0
- data/spec/lib/tabs_tabs/resolutions/day_spec.rb +23 -0
- data/spec/lib/tabs_tabs/resolutions/hour_spec.rb +23 -0
- data/spec/lib/tabs_tabs/resolutions/minute_spec.rb +23 -0
- data/spec/lib/tabs_tabs/resolutions/month_spec.rb +23 -0
- data/spec/lib/tabs_tabs/resolutions/week_spec.rb +24 -0
- data/spec/lib/tabs_tabs/resolutions/year_spec.rb +23 -0
- data/spec/lib/tabs_tabs/storage_spec.rb +138 -0
- data/spec/lib/tabs_tabs_spec.rb +223 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/support/custom_resolutions.rb +40 -0
- data/tabs_tabs.gemspec +31 -0
- metadata +213 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe TabsTabs::Resolutions::Year do
|
4
|
+
let(:timestamp){ Time.utc(2000, 2) }
|
5
|
+
|
6
|
+
context "#normalize" do
|
7
|
+
it "should normalize the date to year, month" do
|
8
|
+
expect(subject.normalize(timestamp)).to eq(timestamp.change(month: 1))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context "#serialize" do
|
13
|
+
it "should return YYYY" do
|
14
|
+
expect(subject.serialize(timestamp)).to eq("2000")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "#deserialize" do
|
19
|
+
it "should convert string into date" do
|
20
|
+
expect(subject.deserialize("2000")).to eq(timestamp.change(month: 1))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe TabsTabs::Storage do
|
4
|
+
context "#redis" do
|
5
|
+
it "should return the configured Redis" do
|
6
|
+
expect(subject.redis).to eq(TabsTabs::Config.redis)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
context "#tabs_key" do
|
11
|
+
after do
|
12
|
+
TabsTabs::Config.prefix = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should add prefix if configued" do
|
16
|
+
TabsTabs::Config.prefix = "myapp"
|
17
|
+
expect(subject.tabs_key("key")).to eq("tabstabs:myapp:key")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should not add prefix if not there" do
|
21
|
+
expect(subject.tabs_key("key")).to eq("tabstabs:key")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with stubbed redis" do
|
26
|
+
|
27
|
+
let(:stubbed_redis) { double("redis").as_null_object }
|
28
|
+
|
29
|
+
before do
|
30
|
+
allow(subject).to receive(:redis).and_return(stubbed_redis)
|
31
|
+
allow(subject).to receive(:tabs_key).at_least(:once).and_call_original
|
32
|
+
end
|
33
|
+
|
34
|
+
it "#exists calls exists with the expected key" do
|
35
|
+
subject.exists("foo")
|
36
|
+
expect(stubbed_redis).to have_received(:exists).with("tabstabs:foo")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "#expireat calls expireat with expected key and timestamp" do
|
40
|
+
subject.expireat("foo", 1234)
|
41
|
+
expect(stubbed_redis).to have_received(:expireat).with("tabstabs:foo", 1234)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "#ttl calls ttl with expected key" do
|
45
|
+
subject.ttl("foo")
|
46
|
+
expect(stubbed_redis).to have_received(:ttl).with("tabstabs:foo")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "#get calls get with expected key" do
|
50
|
+
subject.get("foo")
|
51
|
+
expect(stubbed_redis).to have_received(:get).with("tabstabs:foo")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "#mget receives prefixed keys" do
|
55
|
+
subject.mget("foo", "bar")
|
56
|
+
expect(stubbed_redis).to have_received(:mget).with("tabstabs:foo", "tabstabs:bar")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "#set calls set with the expected key and arg" do
|
60
|
+
subject.set("foo", "bar")
|
61
|
+
expect(stubbed_redis).to have_received(:set).with("tabstabs:foo", "bar")
|
62
|
+
end
|
63
|
+
|
64
|
+
it "#del" do
|
65
|
+
subject.del("foo")
|
66
|
+
expect(stubbed_redis).to have_received(:del).with("tabstabs:foo")
|
67
|
+
end
|
68
|
+
|
69
|
+
it "#del_by_prefix" do
|
70
|
+
allow(stubbed_redis).to receive(:keys).and_return(["foo:a", "foo:b"])
|
71
|
+
subject.del_by_prefix("foo")
|
72
|
+
expect(stubbed_redis).to have_received(:del).with("foo:a", "foo:b")
|
73
|
+
end
|
74
|
+
|
75
|
+
it "#incr" do
|
76
|
+
subject.incr("foo")
|
77
|
+
expect(stubbed_redis).to have_received(:incr).with("tabstabs:foo")
|
78
|
+
end
|
79
|
+
|
80
|
+
it "#rpush" do
|
81
|
+
subject.rpush("foo", "bar")
|
82
|
+
expect(stubbed_redis).to have_received(:rpush).with("tabstabs:foo", "bar")
|
83
|
+
end
|
84
|
+
|
85
|
+
it "#sadd" do
|
86
|
+
subject.sadd("foo", "bar", "baz")
|
87
|
+
expect(stubbed_redis).to have_received(:sadd).with("tabstabs:foo", "bar", "baz")
|
88
|
+
end
|
89
|
+
|
90
|
+
it "#smembers" do
|
91
|
+
subject.smembers("foo")
|
92
|
+
expect(stubbed_redis).to have_received(:smembers).with("tabstabs:foo")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "#smembers_all" do
|
96
|
+
allow(stubbed_redis).to receive(:pipelined).and_yield
|
97
|
+
subject.smembers_all("foo", "bar")
|
98
|
+
expect(stubbed_redis).to have_received(:smembers).with("tabstabs:foo")
|
99
|
+
expect(stubbed_redis).to have_received(:smembers).with("tabstabs:bar")
|
100
|
+
end
|
101
|
+
|
102
|
+
it "#sismember" do
|
103
|
+
subject.sismember("foo", "bar")
|
104
|
+
expect(stubbed_redis).to have_received(:sismember).with("tabstabs:foo", "bar")
|
105
|
+
end
|
106
|
+
|
107
|
+
it "#hget" do
|
108
|
+
subject.hget("foo", "bar")
|
109
|
+
expect(stubbed_redis).to have_received(:hget).with("tabstabs:foo", "bar")
|
110
|
+
end
|
111
|
+
|
112
|
+
it "#hset" do
|
113
|
+
subject.hset("foo", "bar", "baz")
|
114
|
+
expect(stubbed_redis).to have_received(:hset).with("tabstabs:foo", "bar", "baz")
|
115
|
+
end
|
116
|
+
|
117
|
+
it "#hdel" do
|
118
|
+
subject.hdel("foo", "bar")
|
119
|
+
expect(stubbed_redis).to have_received(:hdel).with("tabstabs:foo", "bar")
|
120
|
+
end
|
121
|
+
|
122
|
+
it "#hkeys" do
|
123
|
+
subject.hkeys("foo")
|
124
|
+
expect(stubbed_redis).to have_received(:hkeys).with("tabstabs:foo")
|
125
|
+
end
|
126
|
+
|
127
|
+
it "#hincrby" do
|
128
|
+
subject.hincrby("foo", "bar", 42)
|
129
|
+
expect(stubbed_redis).to have_received(:hincrby).with("tabstabs:foo", "bar", 42)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "#hgetall" do
|
133
|
+
subject.hgetall("foo")
|
134
|
+
expect(stubbed_redis).to have_received(:hgetall).with("tabstabs:foo")
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe TabsTabs do
|
4
|
+
include TabsTabs::Storage
|
5
|
+
|
6
|
+
describe ".create_metric" do
|
7
|
+
|
8
|
+
it "raises an error if the type is invalid" do
|
9
|
+
expect { TabsTabs.create_metric("foo", "foobar") }.to raise_error(TabsTabs::UnknownTypeError)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "raises an error if the metric already exists" do
|
13
|
+
TabsTabs.create_metric("foo", "counter")
|
14
|
+
expect { TabsTabs.create_metric("foo", "counter") }.to raise_error(TabsTabs::DuplicateMetricError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns a Counter metric if 'counter' was the specified type" do
|
18
|
+
expect(TabsTabs.create_metric("foo", "counter")).to be_a_kind_of(TabsTabs::Metrics::Counter)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns a Value metric if 'value' was the specified type" do
|
22
|
+
expect(TabsTabs.create_metric("foo", "value")).to be_a_kind_of(TabsTabs::Metrics::Value)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "adds the metric's key to the list_metrics" do
|
26
|
+
TabsTabs.create_metric("foo", "value")
|
27
|
+
TabsTabs.create_metric("bar", "counter")
|
28
|
+
TabsTabs.create_metric("baz", "task")
|
29
|
+
expect(TabsTabs.list_metrics).to include("foo")
|
30
|
+
expect(TabsTabs.list_metrics).to include("bar")
|
31
|
+
expect(TabsTabs.list_metrics).to include("baz")
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
describe ".counter_total" do
|
37
|
+
|
38
|
+
it "returns the total for a counter metric" do
|
39
|
+
TabsTabs.increment_counter("foo")
|
40
|
+
expect(TabsTabs.counter_total("foo")).to eq 1
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns the value of the block if given and the metric doesn't exist" do
|
44
|
+
expect(TabsTabs.counter_total("foo") { 42 }).to eq 42
|
45
|
+
end
|
46
|
+
|
47
|
+
it "raises an UnknownMetricError if no block is given and the metric does not exist" do
|
48
|
+
expect { TabsTabs.counter_total("foo") }.to raise_error TabsTabs::UnknownMetricError
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
describe ".get_metric" do
|
54
|
+
|
55
|
+
it "returns the expected metric object" do
|
56
|
+
TabsTabs.create_metric("foo", "counter")
|
57
|
+
expect(TabsTabs.get_metric("foo")).to be_a_kind_of(TabsTabs::Metrics::Counter)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
describe ".list_metrics" do
|
63
|
+
|
64
|
+
it "returns the list_metrics of metric names" do
|
65
|
+
TabsTabs.create_metric("foo", "counter")
|
66
|
+
TabsTabs.create_metric("bar", "value")
|
67
|
+
expect(TabsTabs.list_metrics).to eq(["foo", "bar"])
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
describe ".metric_exists?" do
|
73
|
+
|
74
|
+
it "returns true if the metric exists" do
|
75
|
+
TabsTabs.create_metric("foo", "counter")
|
76
|
+
expect(TabsTabs.metric_exists?("foo")).to be_truthy
|
77
|
+
end
|
78
|
+
|
79
|
+
it "returns false if the metric does not exist" do
|
80
|
+
expect(TabsTabs.metric_exists?("foo")).to be_falsey
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
describe ".drop_metric" do
|
86
|
+
|
87
|
+
before do
|
88
|
+
TabsTabs.create_metric("foo", "counter")
|
89
|
+
end
|
90
|
+
|
91
|
+
it "removes the metric from the list_metrics" do
|
92
|
+
TabsTabs.drop_metric!("foo")
|
93
|
+
expect(TabsTabs.list_metrics).to_not include("foo")
|
94
|
+
end
|
95
|
+
|
96
|
+
it "results in metric_exists? returning false" do
|
97
|
+
TabsTabs.drop_metric!("foo")
|
98
|
+
expect(TabsTabs.metric_exists?("foo")).to be_falsey
|
99
|
+
end
|
100
|
+
|
101
|
+
it "calls drop! on the metric" do
|
102
|
+
metric = double(:metric)
|
103
|
+
allow(TabsTabs).to receive(:get_metric).and_return(metric)
|
104
|
+
expect(metric).to receive(:drop!)
|
105
|
+
TabsTabs.drop_metric!("foo")
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
describe ".drop_all_metrics" do
|
111
|
+
|
112
|
+
it "drops all metrics" do
|
113
|
+
TabsTabs.create_metric("foo", "counter")
|
114
|
+
TabsTabs.create_metric("bar", "value")
|
115
|
+
TabsTabs.drop_all_metrics!
|
116
|
+
expect(TabsTabs.metric_exists?("foo")).to be_falsey
|
117
|
+
expect(TabsTabs.metric_exists?("bar")).to be_falsey
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
describe ".increment_counter" do
|
123
|
+
|
124
|
+
it "raises a Tabs::MetricTypeMismatchError if the metric is the wrong type" do
|
125
|
+
TabsTabs.create_metric("foo", "value")
|
126
|
+
expect { TabsTabs.increment_counter("foo") }.to raise_error(TabsTabs::MetricTypeMismatchError)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "creates the metric if it doesn't exist" do
|
130
|
+
expect(TabsTabs.metric_exists?("foo")).to be_falsey
|
131
|
+
expect { TabsTabs.increment_counter("foo") }.to_not raise_error
|
132
|
+
expect(TabsTabs.metric_exists?("foo")).to be_truthy
|
133
|
+
end
|
134
|
+
|
135
|
+
it "calls increment on the metric" do
|
136
|
+
metric = TabsTabs.create_metric("foo", "counter")
|
137
|
+
allow(TabsTabs).to receive(:get_metric).and_return(metric)
|
138
|
+
expect(metric).to receive(:increment)
|
139
|
+
TabsTabs.increment_counter("foo")
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
describe ".record_value" do
|
145
|
+
|
146
|
+
it "creates the metric if it doesn't exist" do
|
147
|
+
expect(TabsTabs.metric_exists?("foo")).to be_falsey
|
148
|
+
expect { TabsTabs.record_value("foo", 38) }.not_to raise_error
|
149
|
+
expect(TabsTabs.metric_exists?("foo")).to be_truthy
|
150
|
+
end
|
151
|
+
|
152
|
+
it "raises a Tabs::MetricTypeMismatchError if the metric is the wrong type" do
|
153
|
+
TabsTabs.create_metric("foo", "counter")
|
154
|
+
expect { TabsTabs.record_value("foo", 27) }.to raise_error(TabsTabs::MetricTypeMismatchError)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "calls record on the metric" do
|
158
|
+
Timecop.freeze(Time.now.utc)
|
159
|
+
metric = TabsTabs.create_metric("foo", "value")
|
160
|
+
allow(TabsTabs).to receive(:get_metric).and_return(metric)
|
161
|
+
allow(metric).to receive(:record).with(42, Time.now.utc)
|
162
|
+
TabsTabs.record_value("foo", 42)
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
describe ".list_metrics" do
|
168
|
+
|
169
|
+
it "lists all metrics that are defined" do
|
170
|
+
TabsTabs.create_metric("foo", "counter")
|
171
|
+
TabsTabs.create_metric("bar", "counter")
|
172
|
+
TabsTabs.create_metric("baz", "counter")
|
173
|
+
expect(TabsTabs.list_metrics).to eq(["foo", "bar", "baz"])
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
describe ".metric_type" do
|
179
|
+
|
180
|
+
it "returns the type of a counter metric" do
|
181
|
+
TabsTabs.create_metric("foo", "counter")
|
182
|
+
expect(TabsTabs.metric_type("foo")).to eq("counter")
|
183
|
+
end
|
184
|
+
|
185
|
+
it "returns the type of a value metric" do
|
186
|
+
TabsTabs.create_metric("bar", "value")
|
187
|
+
expect(TabsTabs.metric_type("bar")).to eq("value")
|
188
|
+
end
|
189
|
+
|
190
|
+
it "returns the type of a task metric" do
|
191
|
+
TabsTabs.create_metric("baz", "task")
|
192
|
+
expect(TabsTabs.metric_type("baz")).to eq("task")
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
describe ".drop_resolution_for_metric!" do
|
198
|
+
it "raises unknown metric error if metric does not exist" do
|
199
|
+
expect{ TabsTabs.drop_resolution_for_metric!(:invalid, :minute) }.to raise_error(TabsTabs::UnknownMetricError)
|
200
|
+
end
|
201
|
+
|
202
|
+
it "raises resolution missing error if resolution not registered" do
|
203
|
+
TabsTabs.create_metric("baz", "value")
|
204
|
+
expect{ TabsTabs.drop_resolution_for_metric!("baz", :invalid) }.to raise_error(TabsTabs::ResolutionMissingError)
|
205
|
+
end
|
206
|
+
|
207
|
+
it "does not allow you to call drop_by_resolution if task metric" do
|
208
|
+
metric = TabsTabs.create_metric("baz", "task")
|
209
|
+
expect(metric).not_to receive(:drop_by_resolution!)
|
210
|
+
TabsTabs.drop_resolution_for_metric!("baz", :minute)
|
211
|
+
end
|
212
|
+
|
213
|
+
it "drops the metric by resolution" do
|
214
|
+
now = Time.utc(2000,1,1)
|
215
|
+
metric = TabsTabs.create_metric("baz", "value")
|
216
|
+
metric.record(42, now)
|
217
|
+
TabsTabs.drop_resolution_for_metric!("baz", :minute)
|
218
|
+
minute_key = TabsTabs::Metrics::Value.new("baz").storage_key(:minute, now)
|
219
|
+
expect(TabsTabs::Storage.exists(minute_key)).to be_falsey
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "tabs_tabs"
|
3
|
+
require "pry"
|
4
|
+
require "timecop"
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
config.mock_with :rspec
|
8
|
+
|
9
|
+
config.before(:each) do
|
10
|
+
TabsTabs::Resolution.reset_default_resolutions
|
11
|
+
TabsTabs::Storage.del_by_prefix("")
|
12
|
+
end
|
13
|
+
|
14
|
+
config.after(:each) do
|
15
|
+
Timecop.return
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module BadlyFormedResolution
|
2
|
+
include TabsTabs::Resolutionable
|
3
|
+
extend self
|
4
|
+
end
|
5
|
+
|
6
|
+
module WellFormedResolution
|
7
|
+
include TabsTabs::Resolutionable
|
8
|
+
extend self
|
9
|
+
|
10
|
+
PATTERN = "%Y-%m-%d-%H-%M-%S"
|
11
|
+
|
12
|
+
def name
|
13
|
+
:seconds
|
14
|
+
end
|
15
|
+
|
16
|
+
def serialize(timestamp)
|
17
|
+
timestamp.strftime(PATTERN)
|
18
|
+
end
|
19
|
+
|
20
|
+
def deserialize(str)
|
21
|
+
dt = DateTime.strptime(str, PATTERN)
|
22
|
+
self.normalize(dt)
|
23
|
+
end
|
24
|
+
|
25
|
+
def from_seconds(s)
|
26
|
+
s / 1
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_seconds
|
30
|
+
1
|
31
|
+
end
|
32
|
+
|
33
|
+
def add(ts, num)
|
34
|
+
ts + num.seconds
|
35
|
+
end
|
36
|
+
|
37
|
+
def normalize(ts)
|
38
|
+
Time.utc(ts.year, ts.month, ts.day, ts.hour, ts.min, ts.sec)
|
39
|
+
end
|
40
|
+
end
|
data/tabs_tabs.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'tabs_tabs/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
|
8
|
+
gem.name = "tabstabs"
|
9
|
+
gem.version = TabsTabs::VERSION
|
10
|
+
gem.authors = ["Max Kießling", "Michael Prilop", "JC Grubbs"]
|
11
|
+
gem.email = ['max@kopfueber.org', 'michael.prilop@imw.fraunhofer.de']
|
12
|
+
gem.description = %q{A redis-backed metrics tracker for keeping tabstabs on pretty much anything. Fork of Tabs}
|
13
|
+
gem.summary = %q{A redis-backed metrics tracker for keeping tabstabs on pretty much anything ;)}
|
14
|
+
gem.homepage = "https://github.com/FHG-IMW/tabstabs"
|
15
|
+
gem.license = "MIT"
|
16
|
+
|
17
|
+
gem.files = `git ls-files`.split($/)
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
|
+
gem.require_paths = ["lib"]
|
21
|
+
|
22
|
+
gem.add_dependency "activesupport", ">= 3.2"
|
23
|
+
gem.add_dependency "redis", ">= 3.0.0"
|
24
|
+
|
25
|
+
gem.add_development_dependency "pry"
|
26
|
+
gem.add_development_dependency "pry-nav"
|
27
|
+
gem.add_development_dependency "rake"
|
28
|
+
gem.add_development_dependency "rspec"
|
29
|
+
gem.add_development_dependency "timecop"
|
30
|
+
|
31
|
+
end
|