berater 0.5.0 → 0.7.1

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/spec/riddle_spec.rb CHANGED
@@ -42,11 +42,15 @@ class ConcurrenyRiddler
42
42
  timeout ||= 1_000 # fake infinity
43
43
 
44
44
  limiter = Berater::RateLimiter.new(:key, capacity, timeout)
45
- limiter.limit
45
+ lock = limiter.limit
46
46
  yield if block_given?
47
47
  ensure
48
48
  # decrement counter
49
- limiter.redis.decr(limiter.send(:cache_key, :key))
49
+ if lock
50
+ key = limiter.send(:cache_key, :key)
51
+ count, ts = limiter.redis.get(key).split ';'
52
+ limiter.redis.set(key, "#{count.to_f - 1};#{ts}")
53
+ end
50
54
  end
51
55
  end
52
56
 
@@ -1,35 +1,24 @@
1
- describe Berater::TestMode, order: :defined do
2
- let(:reset_test_mode) { true }
3
-
1
+ describe Berater::TestMode do
4
2
  after do
5
- Berater.test_mode = nil if reset_test_mode
3
+ Berater.test_mode = nil
6
4
  end
7
5
 
8
- context 'after test_mode.rb was required, but not used' do
9
- let(:reset_test_mode) { false }
10
-
11
- it 'has already been loaded by "berater/rspec", unfortunately' do
12
- expect {
13
- expect { Berater.test_mode }.to raise_error(NoMethodError)
14
- }.to fail
6
+ context 'after test_mode.rb has been loaded' do
7
+ it 'monkey patches Berater' do
8
+ expect(Berater).to respond_to(:test_mode)
15
9
  end
16
10
 
17
11
  it 'defaults to off' do
18
12
  expect(Berater.test_mode).to be nil
19
13
  end
20
14
 
21
- it 'did not prepend .new yet' do
22
- expect(Berater::Limiter.singleton_class.ancestors).not_to include(described_class)
23
- end
24
-
25
- it 'prepends when first turned on' do
26
- Berater.test_mode = :pass
27
-
28
- expect(Berater::Limiter.singleton_class.ancestors).to include(described_class)
15
+ it 'prepends Limiter subclasses' do
16
+ expect(Berater::Unlimiter.ancestors).to include(described_class)
17
+ expect(Berater::Inhibitor.ancestors).to include(described_class)
29
18
  end
30
19
 
31
20
  it 'preserves the original functionality via super' do
32
- expect { Berater::Limiter.new }.to raise_error(NotImplementedError)
21
+ expect { Berater::Limiter.new }.to raise_error(NoMethodError)
33
22
  end
34
23
  end
35
24
 
@@ -50,31 +39,43 @@ describe Berater::TestMode, order: :defined do
50
39
  it 'validates input' do
51
40
  expect { Berater.test_mode = :foo }.to raise_error(ArgumentError)
52
41
  end
53
- end
54
42
 
55
- shared_examples 'it always works, without redis' do
56
- before do
57
- Berater.redis = nil
58
- expect_any_instance_of(Berater::LuaScript).not_to receive(:eval)
59
- end
43
+ it 'works no matter when limiter was created' do
44
+ limiter = Berater::Unlimiter.new
45
+ expect(limiter).not_to be_overloaded
60
46
 
61
- it_behaves_like 'it is not overloaded'
47
+ Berater.test_mode = :fail
48
+ expect(limiter).to be_overloaded
49
+ end
62
50
 
63
- it 'always works' do
64
- 10.times { subject.limit }
51
+ it 'supports a generic expectation' do
52
+ Berater.test_mode = :pass
53
+ expect_any_instance_of(Berater::Limiter).to receive(:limit)
54
+ Berater::Unlimiter.new.limit
65
55
  end
66
56
  end
67
57
 
68
- shared_examples 'it never works, without redis' do
58
+ shared_examples 'it supports test_mode' do
69
59
  before do
60
+ # without hitting Redis
70
61
  Berater.redis = nil
71
62
  expect_any_instance_of(Berater::LuaScript).not_to receive(:eval)
72
63
  end
73
64
 
74
- it_behaves_like 'it is overloaded'
65
+ context 'with test_mode = :pass' do
66
+ before { Berater.test_mode = :pass }
67
+
68
+ it_behaves_like 'it is not overloaded'
69
+
70
+ it 'always works' do
71
+ 10.times { subject.limit }
72
+ end
73
+ end
74
+
75
+ context 'with test_mode = :fail' do
76
+ before { Berater.test_mode = :fail }
75
77
 
76
- it 'never works' do
77
- expect { subject }.to be_overloaded
78
+ it_behaves_like 'it is overloaded'
78
79
  end
79
80
  end
80
81
 
@@ -84,23 +85,10 @@ describe Berater::TestMode, order: :defined do
84
85
  context 'when test_mode = nil' do
85
86
  before { Berater.test_mode = nil }
86
87
 
87
- it { is_expected.to be_a Berater::Unlimiter }
88
- it_behaves_like 'it always works, without redis'
89
- end
90
-
91
- context 'when test_mode = :pass' do
92
- before { Berater.test_mode = :pass }
93
-
94
- it { is_expected.to be_a Berater::Unlimiter }
95
- it_behaves_like 'it always works, without redis'
88
+ it_behaves_like 'it is not overloaded'
96
89
  end
97
90
 
98
- context 'when test_mode = :fail' do
99
- before { Berater.test_mode = :fail }
100
-
101
- it { is_expected.to be_a Berater::Unlimiter }
102
- it_behaves_like 'it never works, without redis'
103
- end
91
+ it_behaves_like 'it supports test_mode'
104
92
  end
105
93
 
106
94
  describe 'Inhibitor' do
@@ -109,42 +97,18 @@ describe Berater::TestMode, order: :defined do
109
97
  context 'when test_mode = nil' do
110
98
  before { Berater.test_mode = nil }
111
99
 
112
- it { is_expected.to be_a Berater::Inhibitor }
113
- it_behaves_like 'it never works, without redis'
100
+ it_behaves_like 'it is overloaded'
114
101
  end
115
102
 
116
- context 'when test_mode = :pass' do
117
- before { Berater.test_mode = :pass }
118
-
119
- it { is_expected.to be_a Berater::Inhibitor }
120
- it_behaves_like 'it always works, without redis'
121
- end
122
-
123
- context 'when test_mode = :fail' do
124
- before { Berater.test_mode = :fail }
125
-
126
- it { is_expected.to be_a Berater::Inhibitor }
127
- it_behaves_like 'it never works, without redis'
128
- end
103
+ it_behaves_like 'it supports test_mode'
129
104
  end
130
105
 
131
106
  describe 'RateLimiter' do
132
107
  subject { Berater::RateLimiter.new(:key, 1, :second) }
133
108
 
134
- shared_examples 'a RateLimiter' do
135
- it { is_expected.to be_a Berater::RateLimiter }
136
-
137
- it 'checks arguments' do
138
- expect {
139
- Berater::RateLimiter.new(:key, 1)
140
- }.to raise_error(ArgumentError)
141
- end
142
- end
143
-
144
109
  context 'when test_mode = nil' do
145
110
  before { Berater.test_mode = nil }
146
111
 
147
- it_behaves_like 'a RateLimiter'
148
112
  it_behaves_like 'it is not overloaded'
149
113
 
150
114
  it 'works per usual' do
@@ -154,38 +118,15 @@ describe Berater::TestMode, order: :defined do
154
118
  end
155
119
  end
156
120
 
157
- context 'when test_mode = :pass' do
158
- before { Berater.test_mode = :pass }
159
-
160
- it_behaves_like 'a RateLimiter'
161
- it_behaves_like 'it always works, without redis'
162
- end
163
-
164
- context 'when test_mode = :fail' do
165
- before { Berater.test_mode = :fail }
166
-
167
- it_behaves_like 'a RateLimiter'
168
- it_behaves_like 'it never works, without redis'
169
- end
121
+ it_behaves_like 'it supports test_mode'
170
122
  end
171
123
 
172
124
  describe 'ConcurrencyLimiter' do
173
125
  subject { Berater::ConcurrencyLimiter.new(:key, 1) }
174
126
 
175
- shared_examples 'a ConcurrencyLimiter' do
176
- it { expect(subject).to be_a Berater::ConcurrencyLimiter }
177
-
178
- it 'checks arguments' do
179
- expect {
180
- Berater::ConcurrencyLimiter.new(:key, 1.0)
181
- }.to raise_error(ArgumentError)
182
- end
183
- end
184
-
185
127
  context 'when test_mode = nil' do
186
128
  before { Berater.test_mode = nil }
187
129
 
188
- it_behaves_like 'a ConcurrencyLimiter'
189
130
  it_behaves_like 'it is not overloaded'
190
131
 
191
132
  it 'works per usual' do
@@ -195,19 +136,7 @@ describe Berater::TestMode, order: :defined do
195
136
  end
196
137
  end
197
138
 
198
- context 'when test_mode = :pass' do
199
- before { Berater.test_mode = :pass }
200
-
201
- it_behaves_like 'a ConcurrencyLimiter'
202
- it_behaves_like 'it always works, without redis'
203
- end
204
-
205
- context 'when test_mode = :fail' do
206
- before { Berater.test_mode = :fail }
207
-
208
- it_behaves_like 'a ConcurrencyLimiter'
209
- it_behaves_like 'it never works, without redis'
210
- end
139
+ it_behaves_like 'it supports test_mode'
211
140
  end
212
141
 
213
142
  end
data/spec/utils_spec.rb CHANGED
@@ -1,63 +1,63 @@
1
1
  describe Berater::Utils do
2
2
  using Berater::Utils
3
3
 
4
- describe '.to_usec' do
4
+ describe '.to_msec' do
5
5
  def f(val)
6
- (val * 10**6).to_i
6
+ (val * 10**3).to_i
7
7
  end
8
8
 
9
9
  it 'works with integers' do
10
- expect(0.to_usec).to be f(0)
11
- expect(3.to_usec).to be f(3)
10
+ expect(0.to_msec).to be f(0)
11
+ expect(3.to_msec).to be f(3)
12
12
  end
13
13
 
14
14
  it 'works with floats' do
15
- expect(0.1.to_usec).to be f(0.1)
16
- expect(3.0.to_usec).to be f(3)
15
+ expect(0.1.to_msec).to be f(0.1)
16
+ expect(3.0.to_msec).to be f(3)
17
17
  end
18
18
 
19
- it 'has great precision' do
20
- expect(0.123456.to_usec).to be 123456
21
- expect(123456.654321.to_usec).to be 123456654321
19
+ it 'truncates excessive precision' do
20
+ expect(0.123456.to_msec).to be 123
21
+ expect(123456.654321.to_msec).to be 123456654
22
22
  end
23
23
 
24
24
  it 'works with symbols that are keywords' do
25
- expect(:sec.to_usec).to be f(1)
26
- expect(:second.to_usec).to be f(1)
27
- expect(:seconds.to_usec).to be f(1)
25
+ expect(:sec.to_msec).to be f(1)
26
+ expect(:second.to_msec).to be f(1)
27
+ expect(:seconds.to_msec).to be f(1)
28
28
 
29
- expect(:min.to_usec).to be f(60)
30
- expect(:minute.to_usec).to be f(60)
31
- expect(:minutes.to_usec).to be f(60)
29
+ expect(:min.to_msec).to be f(60)
30
+ expect(:minute.to_msec).to be f(60)
31
+ expect(:minutes.to_msec).to be f(60)
32
32
 
33
- expect(:hour.to_usec).to be f(60 * 60)
34
- expect(:hours.to_usec).to be f(60 * 60)
33
+ expect(:hour.to_msec).to be f(60 * 60)
34
+ expect(:hours.to_msec).to be f(60 * 60)
35
35
  end
36
36
 
37
37
  it 'works with strings that are keywords' do
38
- expect('sec'.to_usec).to be f(1)
39
- expect('second'.to_usec).to be f(1)
40
- expect('seconds'.to_usec).to be f(1)
38
+ expect('sec'.to_msec).to be f(1)
39
+ expect('second'.to_msec).to be f(1)
40
+ expect('seconds'.to_msec).to be f(1)
41
41
 
42
- expect('min'.to_usec).to be f(60)
43
- expect('minute'.to_usec).to be f(60)
44
- expect('minutes'.to_usec).to be f(60)
42
+ expect('min'.to_msec).to be f(60)
43
+ expect('minute'.to_msec).to be f(60)
44
+ expect('minutes'.to_msec).to be f(60)
45
45
 
46
- expect('hour'.to_usec).to be f(60 * 60)
47
- expect('hours'.to_usec).to be f(60 * 60)
46
+ expect('hour'.to_msec).to be f(60 * 60)
47
+ expect('hours'.to_msec).to be f(60 * 60)
48
48
  end
49
49
 
50
50
  it 'works with strings that are numeric' do
51
- expect('0'.to_usec).to be f(0)
52
- expect('3'.to_usec).to be f(3)
51
+ expect('0'.to_msec).to be f(0)
52
+ expect('3'.to_msec).to be f(3)
53
53
 
54
- expect('0.1'.to_usec).to be f(0.1)
55
- expect('3.0'.to_usec).to be f(3)
54
+ expect('0.1'.to_msec).to be f(0.1)
55
+ expect('3.0'.to_msec).to be f(3)
56
56
  end
57
57
 
58
58
  context 'with erroneous values' do
59
59
  def e(val)
60
- expect { val.to_usec }.to raise_error(ArgumentError)
60
+ expect { val.to_msec }.to raise_error(ArgumentError)
61
61
  end
62
62
 
63
63
  it 'rejects negative numbers' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: berater
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Pepper
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-06 00:00:00.000000000 Z
11
+ date: 2021-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis