berater 0.0.1 → 0.1.4

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.
@@ -0,0 +1,166 @@
1
+ describe Berater::RateLimiter do
2
+ before { Berater.mode = :rate }
3
+
4
+ describe '.new' do
5
+ let(:limiter) { described_class.new(1, :second) }
6
+
7
+ it 'initializes' do
8
+ expect(limiter.count).to eq 1
9
+ expect(limiter.interval).to eq 1
10
+ end
11
+
12
+ it 'has default values' do
13
+ expect(limiter.key).to eq described_class.to_s
14
+ expect(limiter.redis).to be Berater.redis
15
+ end
16
+ end
17
+
18
+ describe '#count' do
19
+ def expect_count(count)
20
+ limiter = described_class.new(count, :second)
21
+ expect(limiter.count).to eq count
22
+ end
23
+
24
+ it { expect_count(0) }
25
+ it { expect_count(1) }
26
+ it { expect_count(100) }
27
+
28
+ context 'with erroneous values' do
29
+ def expect_bad_count(count)
30
+ expect do
31
+ described_class.new(count, :second)
32
+ end.to raise_error ArgumentError
33
+ end
34
+
35
+ it { expect_bad_count(0.5) }
36
+ it { expect_bad_count(-1) }
37
+ it { expect_bad_count('1') }
38
+ it { expect_bad_count(:one) }
39
+ end
40
+ end
41
+
42
+ describe '#interval' do
43
+ def expect_interval(interval, expected)
44
+ limiter = described_class.new(1, interval)
45
+ expect(limiter.interval).to eq expected
46
+ end
47
+
48
+ context 'with ints' do
49
+ it { expect_interval(0, 0) }
50
+ it { expect_interval(1, 1) }
51
+ it { expect_interval(33, 33) }
52
+ end
53
+
54
+ context 'with symbols' do
55
+ it { expect_interval(:sec, 1) }
56
+ it { expect_interval(:second, 1) }
57
+ it { expect_interval(:seconds, 1) }
58
+
59
+ it { expect_interval(:min, 60) }
60
+ it { expect_interval(:minute, 60) }
61
+ it { expect_interval(:minutes, 60) }
62
+
63
+ it { expect_interval(:hour, 3600) }
64
+ it { expect_interval(:hours, 3600) }
65
+ end
66
+
67
+ context 'with strings' do
68
+ it { expect_interval('sec', 1) }
69
+ it { expect_interval('minute', 60) }
70
+ it { expect_interval('hours', 3600) }
71
+ end
72
+
73
+ context 'with erroneous values' do
74
+ def expect_bad_interval(interval)
75
+ expect do
76
+ described_class.new(1, interval)
77
+ end.to raise_error(ArgumentError)
78
+ end
79
+
80
+ it { expect_bad_interval(-1) }
81
+ it { expect_bad_interval(:secondz) }
82
+ it { expect_bad_interval('huor') }
83
+ end
84
+ end
85
+
86
+ describe '#limit' do
87
+ let(:limiter) { described_class.new(3, :second) }
88
+
89
+ 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
+ expect {|b| limiter.limit(&b) }.to yield_control
101
+ expect(limiter.limit { 123 }).to eq 123
102
+ end
103
+
104
+ it 'limits excessive calls' do
105
+ 3.times { limiter.limit }
106
+
107
+ expect { limiter.limit }.to be_overrated
108
+ end
109
+
110
+ 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
114
+ expect(limiter).to be_overrated
115
+
116
+ # travel forward a second
117
+ Timecop.freeze(1)
118
+
119
+ expect(limiter.limit).to eq 1
120
+ expect(limiter.limit).to eq 2
121
+ expect(limiter.limit).to eq 3
122
+ expect(limiter).to be_overrated
123
+ end
124
+ end
125
+
126
+ 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) }
140
+
141
+ it 'works as expected' do
142
+ expect { limiter.limit(key: :one) }.not_to be_overrated
143
+ expect { limiter.limit(key: :one) }.to be_overrated
144
+
145
+ expect { limiter.limit(key: :two) }.not_to be_overrated
146
+ expect { limiter.limit(key: :two) }.to be_overrated
147
+ end
148
+ end
149
+
150
+ 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) }
153
+
154
+ it 'works as expected' do
155
+ expect(limiter_one.limit).to eq 1
156
+ expect(limiter_two.limit).to eq 1
157
+
158
+ expect { limiter_one.limit }.to be_overrated
159
+ expect(limiter_two.limit).to eq 2
160
+
161
+ expect { limiter_one.limit }.to be_overrated
162
+ expect { limiter_two.limit }.to be_overrated
163
+ end
164
+ end
165
+
166
+ end
@@ -0,0 +1,61 @@
1
+ describe Berater::Unlimiter do
2
+ before { Berater.mode = :unlimited }
3
+
4
+ describe '.new' do
5
+ it 'initializes without any arguments or options' do
6
+ expect(described_class.new).to be_a described_class
7
+ end
8
+
9
+ it 'initializes with any arguments and options' do
10
+ expect(described_class.new(:abc, x: 123)).to be_a described_class
11
+ end
12
+
13
+ it 'has default values' do
14
+ expect(described_class.new.key).to eq described_class.to_s
15
+ expect(described_class.new.redis).to be Berater.redis
16
+ end
17
+ end
18
+
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
+ describe '#limit' do
40
+ let(:limiter) { described_class.new }
41
+
42
+ it 'works' do
43
+ expect(limiter.limit).to be_nil
44
+ end
45
+
46
+ it 'yields' do
47
+ expect {|b| limiter.limit(&b) }.to yield_control
48
+ end
49
+
50
+ it 'is never overloaded' do
51
+ 10.times do
52
+ expect { limiter.limit }.not_to be_overloaded
53
+ end
54
+ end
55
+
56
+ it 'works with any arguments or options' do
57
+ expect(limiter.limit(x: 123)).to be_nil
58
+ end
59
+ end
60
+
61
+ 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.0.1
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Pepper
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-29 00:00:00.000000000 Z
11
+ date: 2021-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -25,7 +25,21 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: clockwork
28
+ name: byebug
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: codecov
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
@@ -42,42 +56,83 @@ dependencies:
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - "~>"
59
+ - - ">="
46
60
  - !ruby/object:Gem::Version
47
- version: '10'
61
+ version: '0'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - "~>"
66
+ - - ">="
53
67
  - !ruby/object:Gem::Version
54
- version: '10'
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
- name: minitest
70
+ name: rspec
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - "~>"
73
+ - - ">="
60
74
  - !ruby/object:Gem::Version
61
- version: '5'
75
+ version: '0'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - "~>"
80
+ - - ">="
67
81
  - !ruby/object:Gem::Version
68
- version: '5'
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: timecop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
69
111
  description: rate limiter
70
- email:
112
+ email:
71
113
  executables: []
72
114
  extensions: []
73
115
  extra_rdoc_files: []
74
116
  files:
75
117
  - lib/berater.rb
76
- homepage: https://github.com/dpep/berater
118
+ - lib/berater/base_limiter.rb
119
+ - lib/berater/concurrency_limiter.rb
120
+ - lib/berater/inhibitor.rb
121
+ - lib/berater/rate_limiter.rb
122
+ - lib/berater/unlimiter.rb
123
+ - lib/berater/version.rb
124
+ - spec/berater_spec.rb
125
+ - spec/concurrency_limiter_spec.rb
126
+ - spec/concurrency_lock_spec.rb
127
+ - spec/inhibitor_spec.rb
128
+ - spec/matcher_spec.rb
129
+ - spec/rate_limiter_spec.rb
130
+ - spec/unlimiter_spec.rb
131
+ homepage: https://github.com/dpep/berater_rb
77
132
  licenses:
78
133
  - MIT
79
134
  metadata: {}
80
- post_install_message:
135
+ post_install_message:
81
136
  rdoc_options: []
82
137
  require_paths:
83
138
  - lib
@@ -92,9 +147,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
147
  - !ruby/object:Gem::Version
93
148
  version: '0'
94
149
  requirements: []
95
- rubyforge_project:
96
- rubygems_version: 2.6.11
97
- signing_key:
150
+ rubygems_version: 3.0.8
151
+ signing_key:
98
152
  specification_version: 4
99
153
  summary: Berater
100
- test_files: []
154
+ test_files:
155
+ - spec/rate_limiter_spec.rb
156
+ - spec/matcher_spec.rb
157
+ - spec/concurrency_limiter_spec.rb
158
+ - spec/concurrency_lock_spec.rb
159
+ - spec/berater_spec.rb
160
+ - spec/inhibitor_spec.rb
161
+ - spec/unlimiter_spec.rb