berater 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,36 +1,24 @@
1
1
  describe Berater::Inhibitor do
2
- before { Berater.mode = :inhibited }
3
-
4
2
  describe '.new' do
5
3
  it 'initializes without any arguments or options' do
6
4
  expect(described_class.new).to be_a described_class
7
5
  end
8
6
 
9
7
  it 'initializes with any arguments and options' do
10
- expect(described_class.new(:abc, x: 123)).to be_a described_class
8
+ expect(described_class.new(:abc, :def, x: 123)).to be_a described_class
11
9
  end
12
10
 
13
11
  it 'has default values' do
14
- expect(described_class.new.key).to eq described_class.to_s
12
+ expect(described_class.new.key).to be :inhibitor
15
13
  expect(described_class.new.redis).to be Berater.redis
16
14
  end
17
15
  end
18
16
 
19
- describe '.limit' do
20
- it 'always limits' do
21
- expect { described_class.limit }.to be_inhibited
22
- end
23
-
24
- it 'works with any arguments or options' do
25
- expect { described_class.limit(:abc, x: 123) }.to be_inhibited
26
- end
27
- end
28
-
29
17
  describe '#limit' do
30
18
  let(:limiter) { described_class.new }
31
19
 
32
20
  it 'always limits' do
33
- expect { described_class.limit }.to be_inhibited
21
+ expect { limiter.limit }.to be_inhibited
34
22
  end
35
23
  end
36
24
 
data/spec/matcher_spec.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  describe 'be_overloaded' do
2
2
  context 'Berater::Unlimiter' do
3
- let(:limiter) { Berater.new(:unlimited) }
3
+ let(:limiter) { Berater.new(:key, :unlimited) }
4
4
 
5
5
  it { expect(limiter).not_to be_overloaded }
6
6
  it { expect(limiter).not_to be_inhibited }
@@ -19,7 +19,7 @@ describe 'be_overloaded' do
19
19
  end
20
20
 
21
21
  context 'Berater::Inhibitor' do
22
- let(:limiter) { Berater.new(:inhibited) }
22
+ let(:limiter) { Berater.new(:key, :inhibited) }
23
23
 
24
24
  it { expect(limiter).to be_overloaded }
25
25
  it { expect(limiter).to be_inhibited }
@@ -32,7 +32,7 @@ describe 'be_overloaded' do
32
32
  end
33
33
 
34
34
  context 'Berater::RateLimiter' do
35
- let(:limiter) { Berater.new(:rate, 1, :second) }
35
+ let(:limiter) { Berater.new(:key, :rate, 1, :second) }
36
36
 
37
37
  it { expect(limiter).not_to be_overloaded }
38
38
  it { expect(limiter).not_to be_inhibited }
@@ -67,7 +67,7 @@ describe 'be_overloaded' do
67
67
  end
68
68
 
69
69
  context 'Berater::ConcurrencyLimiter' do
70
- let(:limiter) { Berater.new(:concurrency, 1) }
70
+ let(:limiter) { Berater.new(:key, :concurrency, 1) }
71
71
 
72
72
  it { expect(limiter).not_to be_overloaded }
73
73
  it { expect(limiter).not_to be_inhibited }
@@ -1,23 +1,22 @@
1
1
  describe Berater::RateLimiter do
2
- before { Berater.mode = :rate }
3
2
 
4
3
  describe '.new' do
5
- let(:limiter) { described_class.new(1, :second) }
4
+ let(:limiter) { described_class.new(:key, 1, :second) }
6
5
 
7
6
  it 'initializes' do
7
+ expect(limiter.key).to be :key
8
8
  expect(limiter.count).to eq 1
9
9
  expect(limiter.interval).to eq 1
10
10
  end
11
11
 
12
12
  it 'has default values' do
13
- expect(limiter.key).to eq described_class.to_s
14
13
  expect(limiter.redis).to be Berater.redis
15
14
  end
16
15
  end
17
16
 
18
17
  describe '#count' do
19
18
  def expect_count(count)
20
- limiter = described_class.new(count, :second)
19
+ limiter = described_class.new(:key, count, :second)
21
20
  expect(limiter.count).to eq count
22
21
  end
23
22
 
@@ -28,7 +27,7 @@ describe Berater::RateLimiter do
28
27
  context 'with erroneous values' do
29
28
  def expect_bad_count(count)
30
29
  expect do
31
- described_class.new(count, :second)
30
+ described_class.new(:key, count, :second)
32
31
  end.to raise_error ArgumentError
33
32
  end
34
33
 
@@ -41,7 +40,7 @@ describe Berater::RateLimiter do
41
40
 
42
41
  describe '#interval' do
43
42
  def expect_interval(interval, expected)
44
- limiter = described_class.new(1, interval)
43
+ limiter = described_class.new(:key, 1, interval)
45
44
  expect(limiter.interval).to eq expected
46
45
  end
47
46
 
@@ -73,7 +72,7 @@ describe Berater::RateLimiter do
73
72
  context 'with erroneous values' do
74
73
  def expect_bad_interval(interval)
75
74
  expect do
76
- described_class.new(1, interval)
75
+ described_class.new(:key, 1, interval)
77
76
  end.to raise_error(ArgumentError)
78
77
  end
79
78
 
@@ -84,82 +83,60 @@ describe Berater::RateLimiter do
84
83
  end
85
84
 
86
85
  describe '#limit' do
87
- let(:limiter) { described_class.new(3, :second) }
86
+ let(:limiter) { described_class.new(:key, 3, :second) }
88
87
 
89
88
  it 'works' do
90
- expect(limiter.limit).to eq 1
91
- end
92
-
93
- it 'counts' do
94
- expect(limiter.limit).to eq 1
95
- expect(limiter.limit).to eq 2
96
- expect(limiter.limit).to eq 3
97
- end
98
-
99
- it 'yields' do
100
89
  expect {|b| limiter.limit(&b) }.to yield_control
101
90
  expect(limiter.limit { 123 }).to eq 123
102
91
  end
103
92
 
93
+ it 'works without a block' do
94
+ expect(limiter.limit).to be_a Berater::Lock
95
+ end
96
+
104
97
  it 'limits excessive calls' do
105
98
  3.times { limiter.limit }
106
99
 
107
- expect { limiter.limit }.to be_overrated
100
+ expect(limiter).to be_overrated
108
101
  end
109
102
 
110
103
  it 'limit resets over time' do
111
- expect(limiter.limit).to eq 1
112
- expect(limiter.limit).to eq 2
113
- expect(limiter.limit).to eq 3
104
+ 3.times { limiter.limit }
114
105
  expect(limiter).to be_overrated
115
106
 
116
107
  # travel forward a second
117
108
  Timecop.freeze(1)
118
109
 
119
- expect(limiter.limit).to eq 1
120
- expect(limiter.limit).to eq 2
121
- expect(limiter.limit).to eq 3
110
+ 3.times { limiter.limit }
122
111
  expect(limiter).to be_overrated
123
112
  end
124
113
  end
125
114
 
126
115
  context 'with same key, different limiters' do
127
- let(:limiter_one) { described_class.new(1, :second) }
128
- let(:limiter_two) { described_class.new(1, :second) }
129
-
130
- it 'works as expected' do
131
- expect(limiter_one.limit).to eq 1
132
-
133
- expect { limiter_one }.to be_overrated
134
- expect { limiter_two }.to be_overrated
135
- end
136
- end
137
-
138
- context 'with different keys, same limiter' do
139
- let(:limiter) { described_class.new(1, :second) }
116
+ let(:limiter_one) { described_class.new(:key, 1, :second) }
117
+ let(:limiter_two) { described_class.new(:key, 1, :second) }
140
118
 
141
119
  it 'works as expected' do
142
- expect { limiter.limit(key: :one) }.not_to be_overrated
143
- expect { limiter.limit(key: :one) }.to be_overrated
120
+ expect(limiter_one.limit).not_to be_overrated
144
121
 
145
- expect { limiter.limit(key: :two) }.not_to be_overrated
146
- expect { limiter.limit(key: :two) }.to be_overrated
122
+ expect(limiter_one).to be_overrated
123
+ expect(limiter_two).to be_overrated
147
124
  end
148
125
  end
149
126
 
150
127
  context 'with different keys, different limiters' do
151
- let(:limiter_one) { described_class.new(1, :second, key: :one) }
152
- let(:limiter_two) { described_class.new(2, :second, key: :two) }
128
+ let(:limiter_one) { described_class.new(:one, 1, :second) }
129
+ let(:limiter_two) { described_class.new(:two, 2, :second) }
153
130
 
154
131
  it 'works as expected' do
155
- expect(limiter_one.limit).to eq 1
156
- expect(limiter_two.limit).to eq 1
132
+ expect(limiter_one.limit).not_to be_overrated
133
+ expect(limiter_two.limit).not_to be_overrated
157
134
 
158
- expect { limiter_one.limit }.to be_overrated
159
- expect(limiter_two.limit).to eq 2
135
+ expect(limiter_one).to be_overrated
136
+ expect(limiter_two.limit).not_to be_overrated
160
137
 
161
- expect { limiter_one.limit }.to be_overrated
162
- expect { limiter_two.limit }.to be_overrated
138
+ expect(limiter_one).to be_overrated
139
+ expect(limiter_two).to be_overrated
163
140
  end
164
141
  end
165
142
 
@@ -0,0 +1,20 @@
1
+ describe Berater::Lock do
2
+ it_behaves_like 'a lock', Berater.new(:key, :rate, 3, :second)
3
+
4
+ let(:limiter) { Berater.new(:key, :rate, 3, :second) }
5
+
6
+ describe '#expired?' do
7
+ let!(:lock) { limiter.limit }
8
+
9
+ it 'never expires' do
10
+ expect(lock.locked?).to be true
11
+ expect(lock.expired?).to be false
12
+
13
+ Timecop.travel(1_000)
14
+
15
+ expect(lock.locked?).to be true
16
+ expect(lock.expired?).to be false
17
+ end
18
+ end
19
+
20
+ end
@@ -1,50 +1,28 @@
1
1
  describe Berater::Unlimiter do
2
- before { Berater.mode = :unlimited }
3
-
4
2
  describe '.new' do
5
3
  it 'initializes without any arguments or options' do
6
4
  expect(described_class.new).to be_a described_class
7
5
  end
8
6
 
9
7
  it 'initializes with any arguments and options' do
10
- expect(described_class.new(:abc, x: 123)).to be_a described_class
8
+ expect(described_class.new(:abc, :def, x: 123)).to be_a described_class
11
9
  end
12
10
 
13
11
  it 'has default values' do
14
- expect(described_class.new.key).to eq described_class.to_s
12
+ expect(described_class.new.key).to be :unlimiter
15
13
  expect(described_class.new.redis).to be Berater.redis
16
14
  end
17
15
  end
18
16
 
19
- describe '.limit' do
20
- it 'works' do
21
- expect(described_class.limit).to be_nil
22
- end
23
-
24
- it 'yields' do
25
- expect {|b| described_class.limit(&b) }.to yield_control
26
- end
27
-
28
- it 'is never overloaded' do
29
- 10.times do
30
- expect { described_class.limit }.not_to be_overloaded
31
- end
32
- end
33
-
34
- it 'works with any arguments or options' do
35
- expect(described_class.limit(:abc, x: 123)).to be_nil
36
- end
37
- end
38
-
39
17
  describe '#limit' do
40
18
  let(:limiter) { described_class.new }
41
19
 
42
20
  it 'works' do
43
- expect(limiter.limit).to be_nil
21
+ expect {|b| limiter.limit(&b) }.to yield_control
44
22
  end
45
23
 
46
- it 'yields' do
47
- expect {|b| limiter.limit(&b) }.to yield_control
24
+ it 'works without a block' do
25
+ expect(limiter.limit).to be_a Berater::Lock
48
26
  end
49
27
 
50
28
  it 'is never overloaded' do
@@ -52,10 +30,8 @@ describe Berater::Unlimiter do
52
30
  expect { limiter.limit }.not_to be_overloaded
53
31
  end
54
32
  end
55
-
56
- it 'works with any arguments or options' do
57
- expect(limiter.limit(x: 123)).to be_nil
58
- end
59
33
  end
60
34
 
35
+ it_behaves_like 'a lock', described_class.new
36
+
61
37
  end
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.1.0
4
+ version: 0.2.0
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-02-04 00:00:00.000000000 Z
11
+ date: 2021-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -118,6 +118,7 @@ files:
118
118
  - lib/berater/base_limiter.rb
119
119
  - lib/berater/concurrency_limiter.rb
120
120
  - lib/berater/inhibitor.rb
121
+ - lib/berater/lock.rb
121
122
  - lib/berater/rate_limiter.rb
122
123
  - lib/berater/unlimiter.rb
123
124
  - lib/berater/version.rb
@@ -127,6 +128,7 @@ files:
127
128
  - spec/inhibitor_spec.rb
128
129
  - spec/matcher_spec.rb
129
130
  - spec/rate_limiter_spec.rb
131
+ - spec/rate_lock_spec.rb
130
132
  - spec/unlimiter_spec.rb
131
133
  homepage: https://github.com/dpep/berater_rb
132
134
  licenses:
@@ -154,6 +156,7 @@ summary: Berater
154
156
  test_files:
155
157
  - spec/rate_limiter_spec.rb
156
158
  - spec/matcher_spec.rb
159
+ - spec/rate_lock_spec.rb
157
160
  - spec/concurrency_limiter_spec.rb
158
161
  - spec/concurrency_lock_spec.rb
159
162
  - spec/berater_spec.rb