fbe 0.5.1 → 0.7.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 +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +9 -10
- data/README.md +4 -4
- data/Rakefile +1 -4
- data/fbe.gemspec +1 -0
- data/lib/fbe/conclude.rb +22 -1
- data/lib/fbe/github_graph.rb +16 -5
- data/lib/fbe/iterate.rb +12 -8
- data/lib/fbe/octo.rb +3 -5
- data/lib/fbe/sec.rb +2 -11
- data/lib/fbe.rb +1 -1
- data/test/fbe/middleware/test_formatter.rb +1 -1
- data/test/fbe/test_award.rb +2 -2
- data/test/fbe/test_bylaws.rb +2 -2
- data/test/fbe/test_conclude.rb +3 -3
- data/test/fbe/test_copy.rb +2 -2
- data/test/fbe/test_delete.rb +2 -2
- data/test/fbe/test_enter.rb +1 -1
- data/test/fbe/test_fb.rb +3 -3
- data/test/fbe/test_github_graph.rb +22 -1
- data/test/fbe/test_if_absent.rb +1 -1
- data/test/fbe/test_issue.rb +1 -1
- data/test/fbe/test_iterate.rb +3 -3
- data/test/fbe/test_just_one.rb +1 -1
- data/test/fbe/test_octo.rb +23 -26
- data/test/fbe/test_overwrite.rb +2 -2
- data/test/fbe/test_pmp.rb +3 -3
- data/test/fbe/test_regularly.rb +3 -3
- data/test/fbe/test_repeatedly.rb +3 -3
- data/test/fbe/test_sec.rb +3 -3
- data/test/fbe/test_unmask_repos.rb +1 -1
- data/test/fbe/test_who.rb +1 -1
- data/test/test__helper.rb +26 -12
- data/test/test_fbe.rb +1 -1
- metadata +16 -5
- data/.simplecov +0 -24
- data/lib/fbe/middleware/quota.rb +0 -64
- data/test/fbe/middleware/test_quota.rb +0 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af8e39332315cd637642316ea61761792955d43688813b75339b112b58747900
|
4
|
+
data.tar.gz: 6a2fa9d6c135c1ec2500872ace2bba09d00a89fe87c1af6435e54e880f361df4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94a48b37c3d821a8c609e99accfc1fb350b1e317f2cb27c7d351a8a472ff1565edec77d4a3bd2a1d39c758c8e6faa71e5706a1a30fe0364bceffd25144466642
|
7
|
+
data.tar.gz: 8073b49266007c50ae6989ffb1b006fbcddce056cb042be19f5ca39c4e99ad97b58ad77c598d51102b51ef77b9545a4f86fd29cf0323edb7fee9920ff6e65227
|
data/Gemfile
CHANGED
@@ -15,8 +15,8 @@ gem 'rubocop', '~>1.75', require: false
|
|
15
15
|
gem 'rubocop-minitest', '>0', require: false
|
16
16
|
gem 'rubocop-performance', '>0', require: false
|
17
17
|
gem 'rubocop-rake', '>0', require: false
|
18
|
-
gem 'rubocop-rspec', '>0', require: false
|
19
18
|
gem 'simplecov', '~>0.22', require: false
|
20
19
|
gem 'simplecov-cobertura', '~>2.1', require: false
|
20
|
+
gem 'veils', '>0', require: false
|
21
21
|
gem 'webmock', '~>3.25', require: false
|
22
22
|
gem 'yard', '~>0.9', require: false
|
data/Gemfile.lock
CHANGED
@@ -17,6 +17,7 @@ PATH
|
|
17
17
|
obk (~> 0)
|
18
18
|
octokit (~> 9)
|
19
19
|
others (~> 0)
|
20
|
+
tago (~> 0)
|
20
21
|
verbose (~> 0)
|
21
22
|
|
22
23
|
GEM
|
@@ -41,7 +42,7 @@ GEM
|
|
41
42
|
ast (2.4.3)
|
42
43
|
backtrace (0.4.0)
|
43
44
|
base64 (0.2.0)
|
44
|
-
baza.rb (0.
|
45
|
+
baza.rb (0.4.0)
|
45
46
|
backtrace (> 0)
|
46
47
|
elapsed (> 0)
|
47
48
|
faraday (> 0)
|
@@ -79,7 +80,7 @@ GEM
|
|
79
80
|
others (~> 0.0)
|
80
81
|
tago (~> 0.0)
|
81
82
|
yaml (~> 0.3)
|
82
|
-
faraday (2.
|
83
|
+
faraday (2.13.0)
|
83
84
|
faraday-net_http (>= 2.0, < 3.5)
|
84
85
|
json
|
85
86
|
logger
|
@@ -98,7 +99,7 @@ GEM
|
|
98
99
|
fiber-storage (1.0.0)
|
99
100
|
gli (2.22.2)
|
100
101
|
ostruct
|
101
|
-
graphql (2.5.
|
102
|
+
graphql (2.5.3)
|
102
103
|
base64
|
103
104
|
fiber-storage
|
104
105
|
logger
|
@@ -157,8 +158,8 @@ GEM
|
|
157
158
|
os (1.1.4)
|
158
159
|
ostruct (0.6.1)
|
159
160
|
others (0.0.3)
|
160
|
-
parallel (1.
|
161
|
-
parser (3.3.
|
161
|
+
parallel (1.27.0)
|
162
|
+
parser (3.3.8.0)
|
162
163
|
ast (~> 2.4.1)
|
163
164
|
racc
|
164
165
|
prism (1.4.0)
|
@@ -185,7 +186,7 @@ GEM
|
|
185
186
|
rubocop-ast (>= 1.44.0, < 2.0)
|
186
187
|
ruby-progressbar (~> 1.7)
|
187
188
|
unicode-display_width (>= 2.4.0, < 4.0)
|
188
|
-
rubocop-ast (1.44.
|
189
|
+
rubocop-ast (1.44.1)
|
189
190
|
parser (>= 3.3.7.2)
|
190
191
|
prism (~> 1.4)
|
191
192
|
rubocop-minitest (0.38.0)
|
@@ -199,9 +200,6 @@ GEM
|
|
199
200
|
rubocop-rake (0.7.1)
|
200
201
|
lint_roller (~> 1.1)
|
201
202
|
rubocop (>= 1.72.1)
|
202
|
-
rubocop-rspec (3.5.0)
|
203
|
-
lint_roller (~> 1.1)
|
204
|
-
rubocop (~> 1.72, >= 1.72.1)
|
205
203
|
ruby-progressbar (1.13.0)
|
206
204
|
sawyer (0.9.2)
|
207
205
|
addressable (>= 2.3.5)
|
@@ -227,6 +225,7 @@ GEM
|
|
227
225
|
unicode-emoji (~> 4.0, >= 4.0.4)
|
228
226
|
unicode-emoji (4.0.4)
|
229
227
|
uri (1.0.3)
|
228
|
+
veils (0.4.0)
|
230
229
|
verbose (0.0.2)
|
231
230
|
loog (~> 0.2)
|
232
231
|
tago (~> 0.0)
|
@@ -257,9 +256,9 @@ DEPENDENCIES
|
|
257
256
|
rubocop-minitest (> 0)
|
258
257
|
rubocop-performance (> 0)
|
259
258
|
rubocop-rake (> 0)
|
260
|
-
rubocop-rspec (> 0)
|
261
259
|
simplecov (~> 0.22)
|
262
260
|
simplecov-cobertura (~> 2.1)
|
261
|
+
veils (> 0)
|
263
262
|
webmock (~> 3.25)
|
264
263
|
yard (~> 0.9)
|
265
264
|
|
data/README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# FactBase Extended (FBE)
|
2
2
|
|
3
|
-
[](https://www.rultor.com/p/zerocracy/fbe)
|
4
4
|
|
5
5
|
[](https://github.com/zerocracy/fbe/actions/workflows/rake.yml)
|
6
|
-
[](
|
6
|
+
[](https://www.0pdd.com/p?name=zerocracy/fbe)
|
7
|
+
[](https://badge.fury.io/rb/fbe)
|
8
8
|
[](https://codecov.io/github/zerocracy/fbe?branch=master)
|
9
|
-
[](https://rubydoc.info/github/zerocracy/fbe/master/frames)
|
10
10
|
[](https://hitsofcode.com/view/github/zerocracy/fbe)
|
11
11
|
[](https://github.com/zerocracy/fbe/blob/master/LICENSE.txt)
|
12
12
|
|
data/Rakefile
CHANGED
@@ -16,14 +16,11 @@ def version
|
|
16
16
|
Gem::Specification.load(Dir['*.gemspec'].first).version
|
17
17
|
end
|
18
18
|
|
19
|
-
ENV['RACK_ENV'] = 'test'
|
20
|
-
|
21
19
|
task default: %i[clean test picks rubocop yard]
|
22
20
|
|
23
21
|
require 'rake/testtask'
|
24
22
|
desc 'Run all unit tests'
|
25
23
|
Rake::TestTask.new(:test) do |test|
|
26
|
-
Rake::Cleaner.cleanup_files(['coverage'])
|
27
24
|
test.libs << 'lib' << 'test'
|
28
25
|
test.pattern = 'test/**/test_*.rb'
|
29
26
|
test.warning = true
|
@@ -33,7 +30,7 @@ end
|
|
33
30
|
desc 'Run them via Ruby, one by one'
|
34
31
|
task :picks do
|
35
32
|
(Dir['test/**/*.rb'] + Dir['lib/**/*.rb']).each do |f|
|
36
|
-
qbash("bundle exec ruby #{Shellwords.escape(f)}", log: $stdout
|
33
|
+
qbash("bundle exec ruby #{Shellwords.escape(f)} -- --no-cov", log: $stdout)
|
37
34
|
end
|
38
35
|
end
|
39
36
|
|
data/fbe.gemspec
CHANGED
data/lib/fbe/conclude.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
|
+
require 'tago'
|
6
7
|
require_relative '../fbe'
|
7
8
|
require_relative 'fb'
|
8
9
|
require_relative 'octo'
|
@@ -61,6 +62,7 @@ class Fbe::Conclude
|
|
61
62
|
@query = nil
|
62
63
|
@follows = []
|
63
64
|
@quota_aware = false
|
65
|
+
@timeout = 60
|
64
66
|
end
|
65
67
|
|
66
68
|
# Make this block aware of GitHub API quota.
|
@@ -74,6 +76,17 @@ class Fbe::Conclude
|
|
74
76
|
@quota_aware = true
|
75
77
|
end
|
76
78
|
|
79
|
+
# Make sure this block runs for less than allowed amount of seconds.
|
80
|
+
#
|
81
|
+
# When the quota is reached, the loop will gracefully stop to avoid.
|
82
|
+
# This helps prevent interruptions in long-running operations.
|
83
|
+
#
|
84
|
+
# @param [Float] sec Seconds
|
85
|
+
# @return [nil] Nothing is returned
|
86
|
+
def timeout(sec)
|
87
|
+
@timeout = sec
|
88
|
+
end
|
89
|
+
|
77
90
|
# Set the query that should find the facts in the factbase.
|
78
91
|
#
|
79
92
|
# @param [String] query The query to execute
|
@@ -146,10 +159,18 @@ class Fbe::Conclude
|
|
146
159
|
# @return [Integer] The count of the facts seen
|
147
160
|
def roll(&)
|
148
161
|
passed = 0
|
162
|
+
start = Time.now
|
149
163
|
catch :stop do
|
150
164
|
@fb.txn do |fbt|
|
151
165
|
fbt.query(@query).each do |a|
|
152
|
-
|
166
|
+
if @quota_aware && Fbe.octo(loog: @loog, options: @options, global: @global).off_quota
|
167
|
+
@loog.debug('We ran out of GitHub quota, must stop here')
|
168
|
+
throw :stop
|
169
|
+
end
|
170
|
+
if Time.now > start + @timeout
|
171
|
+
@loog.debug("We've spent more than #{start.ago}, must stop here")
|
172
|
+
throw :stop
|
173
|
+
end
|
153
174
|
n = yield fbt, a
|
154
175
|
@loog.info("#{n.what}: #{n.details}") unless n.nil?
|
155
176
|
passed += 1
|
data/lib/fbe/github_graph.rb
CHANGED
@@ -32,13 +32,11 @@ end
|
|
32
32
|
class Fbe::Graph
|
33
33
|
def initialize(token:, host: 'api.github.com')
|
34
34
|
@token = token
|
35
|
-
|
36
|
-
@client = GraphQL::Client.new(schema: GraphQL::Client.load_schema(http), execute: http)
|
37
|
-
@client.allow_dynamic_queries = true
|
35
|
+
@host = host
|
38
36
|
end
|
39
37
|
|
40
|
-
def query(
|
41
|
-
result =
|
38
|
+
def query(qry)
|
39
|
+
result = client.query(client.parse(qry))
|
42
40
|
result.data
|
43
41
|
end
|
44
42
|
|
@@ -116,6 +114,19 @@ class Fbe::Graph
|
|
116
114
|
}
|
117
115
|
end
|
118
116
|
|
117
|
+
private
|
118
|
+
|
119
|
+
def client
|
120
|
+
@client ||=
|
121
|
+
begin
|
122
|
+
http = HTTP.new(@token, @host)
|
123
|
+
schema = GraphQL::Client.load_schema(http)
|
124
|
+
c = GraphQL::Client.new(schema:, execute: http)
|
125
|
+
c.allow_dynamic_queries = true
|
126
|
+
c
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
119
130
|
# The HTTP class
|
120
131
|
class HTTP < GraphQL::Client::HTTP
|
121
132
|
def initialize(token, host)
|
data/lib/fbe/iterate.rb
CHANGED
@@ -107,11 +107,23 @@ class Fbe::Iterate
|
|
107
107
|
raise 'Use "by" first' if @query.nil?
|
108
108
|
seen = {}
|
109
109
|
oct = Fbe.octo(loog: @loog, options: @options, global: @global)
|
110
|
+
if oct.off_quota
|
111
|
+
@loog.debug('We are off GitHub quota, cannot even start, sorry')
|
112
|
+
return
|
113
|
+
end
|
110
114
|
repos = Fbe.unmask_repos(loog: @loog, options: @options, global: @global)
|
111
115
|
restarted = []
|
112
116
|
start = Time.now
|
113
117
|
loop do
|
118
|
+
if oct.off_quota
|
119
|
+
@loog.info("We are off GitHub quota, time to stop after #{start.ago}")
|
120
|
+
break
|
121
|
+
end
|
114
122
|
repos.each do |repo|
|
123
|
+
if oct.off_quota
|
124
|
+
@loog.debug("We are off GitHub quota, we must skip #{repo}")
|
125
|
+
break
|
126
|
+
end
|
115
127
|
if Time.now - start > timeout
|
116
128
|
$loog.info("We are doing this for #{start.ago} already, won't check #{repo}")
|
117
129
|
next
|
@@ -152,14 +164,6 @@ class Fbe::Iterate
|
|
152
164
|
end
|
153
165
|
f.what = @label
|
154
166
|
seen[repo] += 1
|
155
|
-
if oct.off_quota
|
156
|
-
@loog.debug('We are off GitHub quota, time to stop')
|
157
|
-
break
|
158
|
-
end
|
159
|
-
end
|
160
|
-
if oct.off_quota
|
161
|
-
@loog.info("We are off GitHub quota, time to stop after #{start.ago}")
|
162
|
-
break
|
163
167
|
end
|
164
168
|
unless seen.any? { |r, v| v < @repeats && !restarted.include?(r) }
|
165
169
|
@loog.debug("No more repos to scan (out of #{repos.size}), quitting after #{start.ago}")
|
data/lib/fbe/octo.rb
CHANGED
@@ -13,7 +13,6 @@ require 'verbose'
|
|
13
13
|
require_relative '../fbe'
|
14
14
|
require_relative 'middleware'
|
15
15
|
require_relative 'middleware/formatter'
|
16
|
-
require_relative 'middleware/quota'
|
17
16
|
|
18
17
|
# Makes a call to the GitHub API.
|
19
18
|
#
|
@@ -71,7 +70,6 @@ def Fbe.octo(options: $options, global: $global, loog: $loog)
|
|
71
70
|
methods: [:get],
|
72
71
|
backoff_factor: 2
|
73
72
|
)
|
74
|
-
builder.use(Fbe::Middleware::Quota, loog:, pause: options.github_api_pause || 60)
|
75
73
|
builder.use(Faraday::HttpCache, serializer: Marshal, shared_cache: false, logger: Loog::NULL)
|
76
74
|
builder.use(Octokit::Response::RaiseError)
|
77
75
|
builder.use(Faraday::Response::Logger, loog, formatter: Fbe::Middleware::Formatter)
|
@@ -84,10 +82,10 @@ def Fbe.octo(options: $options, global: $global, loog: $loog)
|
|
84
82
|
o = Fbe::FakeOctokit.new
|
85
83
|
end
|
86
84
|
decoor(o, loog:) do
|
87
|
-
def off_quota
|
85
|
+
def off_quota(threshold: 50)
|
88
86
|
left = @origin.rate_limit.remaining
|
89
|
-
if left <
|
90
|
-
@loog.info("Too much GitHub API quota consumed already (
|
87
|
+
if left < threshold
|
88
|
+
@loog.info("Too much GitHub API quota consumed already (#{left} < #{threshold}), stopping")
|
91
89
|
true
|
92
90
|
else
|
93
91
|
false
|
data/lib/fbe/sec.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
|
+
require 'tago'
|
6
7
|
require_relative '../fbe'
|
7
8
|
|
8
9
|
# Converts number of seconds into text.
|
@@ -18,15 +19,5 @@ def Fbe.sec(fact, prop = :seconds)
|
|
18
19
|
s = fact[prop.to_s]
|
19
20
|
raise "There is no #{prop.inspect} property" if s.nil?
|
20
21
|
s = s.first.to_i
|
21
|
-
|
22
|
-
format('%d seconds', s)
|
23
|
-
elsif s < 60 * 60
|
24
|
-
format('%d minutes', s / 60)
|
25
|
-
elsif s < 60 * 60 * 24
|
26
|
-
format('%d hours', s / (60 * 60))
|
27
|
-
elsif s < 7 * 60 * 60 * 24
|
28
|
-
format('%d days', s / (60 * 60 * 24))
|
29
|
-
else
|
30
|
-
format('%d weeks', s / (7 * 60 * 60 * 24))
|
31
|
-
end
|
22
|
+
(Time.now + s).ago
|
32
23
|
end
|
data/lib/fbe.rb
CHANGED
@@ -14,7 +14,7 @@ require_relative '../../../lib/fbe/middleware/formatter'
|
|
14
14
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
15
15
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
16
16
|
# License:: MIT
|
17
|
-
class LoggingFormatterTest <
|
17
|
+
class LoggingFormatterTest < Fbe::Test
|
18
18
|
def test_success_response
|
19
19
|
log_it(status: 200) do |loog|
|
20
20
|
assert_empty(loog.to_s)
|
data/test/fbe/test_award.rb
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
6
|
require 'loog'
|
7
|
-
require_relative '../test__helper'
|
8
7
|
require_relative '../../lib/fbe/award'
|
8
|
+
require_relative '../test__helper'
|
9
9
|
|
10
10
|
# Test.
|
11
11
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
12
12
|
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
13
13
|
# License:: MIT
|
14
|
-
class TestAward <
|
14
|
+
class TestAward < Fbe::Test
|
15
15
|
def test_simple
|
16
16
|
a = Fbe::Award.new(
|
17
17
|
'
|
data/test/fbe/test_bylaws.rb
CHANGED
@@ -4,15 +4,15 @@
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
6
|
require 'loog'
|
7
|
-
require_relative '../test__helper'
|
8
7
|
require_relative '../../lib/fbe/award'
|
9
8
|
require_relative '../../lib/fbe/bylaws'
|
9
|
+
require_relative '../test__helper'
|
10
10
|
|
11
11
|
# Test.
|
12
12
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
13
13
|
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
14
14
|
# License:: MIT
|
15
|
-
class TestBylaws <
|
15
|
+
class TestBylaws < Fbe::Test
|
16
16
|
def test_simple
|
17
17
|
laws = Fbe.bylaws
|
18
18
|
assert_operator(laws.size, :>, 1)
|
data/test/fbe/test_conclude.rb
CHANGED
@@ -3,19 +3,19 @@
|
|
3
3
|
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
|
-
require 'loog'
|
7
6
|
require 'factbase'
|
8
7
|
require 'factbase/syntax'
|
9
8
|
require 'judges/options'
|
10
|
-
|
9
|
+
require 'loog'
|
11
10
|
require_relative '../../lib/fbe/conclude'
|
12
11
|
require_relative '../../lib/fbe/fb'
|
12
|
+
require_relative '../test__helper'
|
13
13
|
|
14
14
|
# Test.
|
15
15
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
16
16
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
17
17
|
# License:: MIT
|
18
|
-
class TestConclude <
|
18
|
+
class TestConclude < Fbe::Test
|
19
19
|
def test_with_defaults
|
20
20
|
$fb = Factbase.new
|
21
21
|
$global = {}
|
data/test/fbe/test_copy.rb
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
6
|
require 'factbase'
|
7
|
-
require_relative '../test__helper'
|
8
7
|
require_relative '../../lib/fbe/copy'
|
8
|
+
require_relative '../test__helper'
|
9
9
|
|
10
10
|
# Test.
|
11
11
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
12
12
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
13
13
|
# License:: MIT
|
14
|
-
class TestCopy <
|
14
|
+
class TestCopy < Fbe::Test
|
15
15
|
def test_simple_copy
|
16
16
|
fb = Factbase.new
|
17
17
|
f1 = fb.insert
|
data/test/fbe/test_delete.rb
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
6
|
require 'factbase'
|
7
|
-
require_relative '../test__helper'
|
8
7
|
require_relative '../../lib/fbe/delete'
|
8
|
+
require_relative '../test__helper'
|
9
9
|
|
10
10
|
# Test.
|
11
11
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
12
12
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
13
13
|
# License:: MIT
|
14
|
-
class TestDelete <
|
14
|
+
class TestDelete < Fbe::Test
|
15
15
|
def test_deletes_one_property
|
16
16
|
fb = Factbase.new
|
17
17
|
f = fb.insert
|
data/test/fbe/test_enter.rb
CHANGED
@@ -13,7 +13,7 @@ require_relative '../test__helper'
|
|
13
13
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
14
14
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
15
15
|
# License:: MIT
|
16
|
-
class TestEnter <
|
16
|
+
class TestEnter < Fbe::Test
|
17
17
|
def test_simple
|
18
18
|
WebMock.disable_net_connect!
|
19
19
|
options = Judges::Options.new({ 'zerocracy_token' => '00000-0000-0000-00000' })
|
data/test/fbe/test_fb.rb
CHANGED
@@ -4,17 +4,17 @@
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
6
|
require 'factbase'
|
7
|
-
require 'loog'
|
8
7
|
require 'judges/options'
|
9
|
-
|
8
|
+
require 'loog'
|
10
9
|
require_relative '../../lib/fbe'
|
11
10
|
require_relative '../../lib/fbe/fb'
|
11
|
+
require_relative '../test__helper'
|
12
12
|
|
13
13
|
# Test.
|
14
14
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
15
15
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
16
16
|
# License:: MIT
|
17
|
-
class TestFb <
|
17
|
+
class TestFb < Fbe::Test
|
18
18
|
def test_simple
|
19
19
|
$fb = Factbase.new
|
20
20
|
$global = {}
|
@@ -13,7 +13,7 @@ require_relative '../../lib/fbe/github_graph'
|
|
13
13
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
14
14
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
15
15
|
# License:: MIT
|
16
|
-
class TestGitHubGraph <
|
16
|
+
class TestGitHubGraph < Fbe::Test
|
17
17
|
def test_simple_use
|
18
18
|
WebMock.disable_net_connect!
|
19
19
|
global = {}
|
@@ -72,6 +72,27 @@ class TestGitHubGraph < Minitest::Test
|
|
72
72
|
assert_equal(0, result.count)
|
73
73
|
end
|
74
74
|
|
75
|
+
def test_gets_resolved_conversations_via_http
|
76
|
+
skip('This test does not work, because the JSON returned is not a valid response from GraphQL')
|
77
|
+
WebMock.disallow_net_connect!
|
78
|
+
global = {}
|
79
|
+
options = Judges::Options.new
|
80
|
+
g = Fbe.github_graph(options:, loog: Loog::NULL, global:)
|
81
|
+
stub_request(:post, 'https://api.github.com/graphql').to_return(
|
82
|
+
body: JSON.pretty_generate(
|
83
|
+
{
|
84
|
+
data: {
|
85
|
+
repository: {
|
86
|
+
name: 'foo'
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
)
|
91
|
+
)
|
92
|
+
result = g.resolved_conversations('foo', 'bar', 42)
|
93
|
+
assert_equal(1, result.count)
|
94
|
+
end
|
95
|
+
|
75
96
|
def test_does_not_count_unresolved_conversations
|
76
97
|
skip("it's a live test, run it manually if you need it")
|
77
98
|
WebMock.allow_net_connect!
|
data/test/fbe/test_if_absent.rb
CHANGED
@@ -13,7 +13,7 @@ require_relative '../../lib/fbe/if_absent'
|
|
13
13
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
14
14
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
15
15
|
# License:: MIT
|
16
|
-
class TestIfAbsent <
|
16
|
+
class TestIfAbsent < Fbe::Test
|
17
17
|
def test_ignores
|
18
18
|
fb = Factbase.new
|
19
19
|
fb.insert.foo = 'hello dude'
|
data/test/fbe/test_issue.rb
CHANGED
@@ -13,7 +13,7 @@ require_relative '../test__helper'
|
|
13
13
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
14
14
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
15
15
|
# License:: MIT
|
16
|
-
class TestIssue <
|
16
|
+
class TestIssue < Fbe::Test
|
17
17
|
def test_simple
|
18
18
|
fb = Factbase.new
|
19
19
|
f = fb.insert
|
data/test/fbe/test_iterate.rb
CHANGED
@@ -3,17 +3,17 @@
|
|
3
3
|
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
|
-
require 'loog'
|
7
6
|
require 'factbase'
|
8
7
|
require 'judges/options'
|
9
|
-
|
8
|
+
require 'loog'
|
10
9
|
require_relative '../../lib/fbe/iterate'
|
10
|
+
require_relative '../test__helper'
|
11
11
|
|
12
12
|
# Test.
|
13
13
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
14
14
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
15
15
|
# License:: MIT
|
16
|
-
class TestIterate <
|
16
|
+
class TestIterate < Fbe::Test
|
17
17
|
def test_simple
|
18
18
|
opts = Judges::Options.new(['repositories=foo/bar', 'testing=true'])
|
19
19
|
fb = Factbase.new
|
data/test/fbe/test_just_one.rb
CHANGED
@@ -11,7 +11,7 @@ require_relative '../../lib/fbe/just_one'
|
|
11
11
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
12
12
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
13
13
|
# License:: MIT
|
14
|
-
class TestJustOne <
|
14
|
+
class TestJustOne < Fbe::Test
|
15
15
|
def test_ignores
|
16
16
|
fb = Factbase.new
|
17
17
|
fb.insert.foo = 'hello dude'
|
data/test/fbe/test_octo.rb
CHANGED
@@ -4,16 +4,16 @@
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
6
|
require 'judges/options'
|
7
|
-
require 'webmock/minitest'
|
8
7
|
require 'loog'
|
9
|
-
|
8
|
+
require 'webmock/minitest'
|
10
9
|
require_relative '../../lib/fbe/octo'
|
10
|
+
require_relative '../test__helper'
|
11
11
|
|
12
12
|
# Test.
|
13
13
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
14
14
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
15
15
|
# License:: MIT
|
16
|
-
class TestOcto <
|
16
|
+
class TestOcto < Fbe::Test
|
17
17
|
def test_simple_use
|
18
18
|
global = {}
|
19
19
|
options = Judges::Options.new({ 'testing' => true })
|
@@ -133,29 +133,20 @@ class TestOcto < Minitest::Test
|
|
133
133
|
|
134
134
|
def test_pauses_when_quota_is_exceeded
|
135
135
|
WebMock.disable_net_connect!
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
'x-ratelimit-remaining' => limit.to_s
|
151
|
-
}
|
152
|
-
)
|
153
|
-
.times(1)
|
154
|
-
o.user(user)
|
155
|
-
refute(o.off_quota) if n > 100
|
156
|
-
limit -= 1
|
157
|
-
end
|
158
|
-
assert_in_delta(pause, Time.now - start_time, 5)
|
136
|
+
o = Fbe.octo(loog: Loog::NULL, global: {}, options: Judges::Options.new({ 'github_api_pause' => 0.01 }))
|
137
|
+
stub_request(:get, 'https://api.github.com/users/foo')
|
138
|
+
.to_return(
|
139
|
+
status: 200, body: '{}',
|
140
|
+
headers: { 'x-ratelimit-remaining' => '1' }
|
141
|
+
)
|
142
|
+
.to_return(
|
143
|
+
status: 200, body: '{}',
|
144
|
+
headers: { 'x-ratelimit-remaining' => '10000' }
|
145
|
+
)
|
146
|
+
o.user('foo')
|
147
|
+
assert(o.off_quota)
|
148
|
+
o.user('foo')
|
149
|
+
refute(o.off_quota)
|
159
150
|
end
|
160
151
|
|
161
152
|
def test_fetches_fake_check_runs_for_ref
|
@@ -193,4 +184,10 @@ class TestOcto < Minitest::Test
|
|
193
184
|
result = o.workflow_run_job('zerocracy/baza', 0)
|
194
185
|
assert_equal(0, result[:id])
|
195
186
|
end
|
187
|
+
|
188
|
+
def test_reads_quota
|
189
|
+
WebMock.enable_net_connect!
|
190
|
+
o = Fbe.octo(loog: Loog::VERBOSE, global: {}, options: Judges::Options.new({ 'github_api_pause' => 0.01 }))
|
191
|
+
refute_nil(o.off_quota)
|
192
|
+
end
|
196
193
|
end
|
data/test/fbe/test_overwrite.rb
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
6
|
require 'factbase'
|
7
|
-
require_relative '../test__helper'
|
8
7
|
require_relative '../../lib/fbe/overwrite'
|
8
|
+
require_relative '../test__helper'
|
9
9
|
|
10
10
|
# Test.
|
11
11
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
12
12
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
13
13
|
# License:: MIT
|
14
|
-
class TestOverwrite <
|
14
|
+
class TestOverwrite < Fbe::Test
|
15
15
|
def test_simple_overwrite
|
16
16
|
fb = Factbase.new
|
17
17
|
f = fb.insert
|
data/test/fbe/test_pmp.rb
CHANGED
@@ -3,17 +3,17 @@
|
|
3
3
|
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
|
+
require 'factbase'
|
6
7
|
require 'judges/options'
|
7
8
|
require 'loog'
|
8
|
-
require 'factbase'
|
9
|
-
require_relative '../test__helper'
|
10
9
|
require_relative '../../lib/fbe/pmp'
|
10
|
+
require_relative '../test__helper'
|
11
11
|
|
12
12
|
# Test.
|
13
13
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
14
14
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
15
15
|
# License:: MIT
|
16
|
-
class TestPmp <
|
16
|
+
class TestPmp < Fbe::Test
|
17
17
|
def test_defaults
|
18
18
|
$fb = Factbase.new
|
19
19
|
$global = {}
|
data/test/fbe/test_regularly.rb
CHANGED
@@ -3,16 +3,16 @@
|
|
3
3
|
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
|
-
require 'loog'
|
7
6
|
require 'factbase'
|
8
|
-
|
7
|
+
require 'loog'
|
9
8
|
require_relative '../../lib/fbe/regularly'
|
9
|
+
require_relative '../test__helper'
|
10
10
|
|
11
11
|
# Test.
|
12
12
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
13
13
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
14
14
|
# License:: MIT
|
15
|
-
class TestRegularly <
|
15
|
+
class TestRegularly < Fbe::Test
|
16
16
|
def test_simple
|
17
17
|
fb = Factbase.new
|
18
18
|
loog = Loog::NULL
|
data/test/fbe/test_repeatedly.rb
CHANGED
@@ -3,17 +3,17 @@
|
|
3
3
|
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
|
-
require 'loog'
|
7
6
|
require 'factbase'
|
8
7
|
require 'judges/options'
|
9
|
-
|
8
|
+
require 'loog'
|
10
9
|
require_relative '../../lib/fbe/repeatedly'
|
10
|
+
require_relative '../test__helper'
|
11
11
|
|
12
12
|
# Test.
|
13
13
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
14
14
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
15
15
|
# License:: MIT
|
16
|
-
class TestRepeatedly <
|
16
|
+
class TestRepeatedly < Fbe::Test
|
17
17
|
def test_simple
|
18
18
|
$fb = Factbase.new
|
19
19
|
$loog = Loog::NULL
|
data/test/fbe/test_sec.rb
CHANGED
@@ -4,18 +4,18 @@
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
6
|
require 'factbase'
|
7
|
-
require_relative '../test__helper'
|
8
7
|
require_relative '../../lib/fbe/sec'
|
8
|
+
require_relative '../test__helper'
|
9
9
|
|
10
10
|
# Test.
|
11
11
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
12
12
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
13
13
|
# License:: MIT
|
14
|
-
class TestSec <
|
14
|
+
class TestSec < Fbe::Test
|
15
15
|
def test_simple
|
16
16
|
fb = Factbase.new
|
17
17
|
f = fb.insert
|
18
18
|
f.seconds = 333
|
19
|
-
|
19
|
+
assert(Fbe.sec(f).start_with?('5m'))
|
20
20
|
end
|
21
21
|
end
|
@@ -12,7 +12,7 @@ require_relative '../../lib/fbe/unmask_repos'
|
|
12
12
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
13
13
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
14
14
|
# License:: MIT
|
15
|
-
class TestUnmaskRepos <
|
15
|
+
class TestUnmaskRepos < Fbe::Test
|
16
16
|
def test_simple_use
|
17
17
|
opts = Judges::Options.new(
|
18
18
|
{
|
data/test/fbe/test_who.rb
CHANGED
@@ -13,7 +13,7 @@ require_relative '../test__helper'
|
|
13
13
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
14
14
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
15
15
|
# License:: MIT
|
16
|
-
class TestWho <
|
16
|
+
class TestWho < Fbe::Test
|
17
17
|
def test_simple
|
18
18
|
fb = Factbase.new
|
19
19
|
f = fb.insert
|
data/test/test__helper.rb
CHANGED
@@ -5,22 +5,36 @@
|
|
5
5
|
|
6
6
|
$stdout.sync = true
|
7
7
|
|
8
|
-
|
9
|
-
Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]
|
8
|
+
ENV['RACK_ENV'] = 'test'
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
SimpleCov.
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
require 'simplecov'
|
11
|
+
require 'simplecov-cobertura'
|
12
|
+
unless SimpleCov.running || ARGV.include?('--no-cov')
|
13
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
|
14
|
+
[
|
15
|
+
SimpleCov::Formatter::HTMLFormatter,
|
16
|
+
SimpleCov::Formatter::CoberturaFormatter
|
17
|
+
]
|
18
|
+
)
|
19
|
+
SimpleCov.minimum_coverage 80
|
20
|
+
SimpleCov.minimum_coverage_by_file 80
|
18
21
|
SimpleCov.start do
|
19
|
-
|
22
|
+
add_filter 'vendor/'
|
23
|
+
add_filter 'target/'
|
24
|
+
add_filter 'test/'
|
25
|
+
add_filter 'lib/fbe/github_graph.rb'
|
20
26
|
track_files 'lib/**/*.rb'
|
21
|
-
|
22
|
-
add_filter '/vendor/'
|
27
|
+
track_files '*.rb'
|
23
28
|
end
|
24
29
|
end
|
25
30
|
|
31
|
+
require 'minitest/reporters'
|
32
|
+
Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]
|
33
|
+
|
26
34
|
require 'minitest/autorun'
|
35
|
+
require 'webmock/minitest'
|
36
|
+
require_relative '../lib/fbe'
|
37
|
+
|
38
|
+
# Parent class for all tests.
|
39
|
+
class Fbe::Test < Minitest::Test
|
40
|
+
end
|
data/test/test_fbe.rb
CHANGED
@@ -10,7 +10,7 @@ require_relative '../lib/fbe'
|
|
10
10
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
11
11
|
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
12
12
|
# License:: MIT
|
13
|
-
class TestFbe <
|
13
|
+
class TestFbe < Fbe::Test
|
14
14
|
def test_simple
|
15
15
|
refute_nil(Fbe::VERSION)
|
16
16
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fbe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-04-
|
10
|
+
date: 2025-04-15 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: backtrace
|
@@ -219,6 +219,20 @@ dependencies:
|
|
219
219
|
- - "~>"
|
220
220
|
- !ruby/object:Gem::Version
|
221
221
|
version: '0'
|
222
|
+
- !ruby/object:Gem::Dependency
|
223
|
+
name: tago
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
225
|
+
requirements:
|
226
|
+
- - "~>"
|
227
|
+
- !ruby/object:Gem::Version
|
228
|
+
version: '0'
|
229
|
+
type: :runtime
|
230
|
+
prerelease: false
|
231
|
+
version_requirements: !ruby/object:Gem::Requirement
|
232
|
+
requirements:
|
233
|
+
- - "~>"
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: '0'
|
222
236
|
- !ruby/object:Gem::Dependency
|
223
237
|
name: verbose
|
224
238
|
requirement: !ruby/object:Gem::Requirement
|
@@ -257,7 +271,6 @@ files:
|
|
257
271
|
- ".pdd"
|
258
272
|
- ".rubocop.yml"
|
259
273
|
- ".rultor.yml"
|
260
|
-
- ".simplecov"
|
261
274
|
- ".yamllint.yml"
|
262
275
|
- Gemfile
|
263
276
|
- Gemfile.lock
|
@@ -292,7 +305,6 @@ files:
|
|
292
305
|
- lib/fbe/just_one.rb
|
293
306
|
- lib/fbe/middleware.rb
|
294
307
|
- lib/fbe/middleware/formatter.rb
|
295
|
-
- lib/fbe/middleware/quota.rb
|
296
308
|
- lib/fbe/octo.rb
|
297
309
|
- lib/fbe/overwrite.rb
|
298
310
|
- lib/fbe/pmp.rb
|
@@ -304,7 +316,6 @@ files:
|
|
304
316
|
- renovate.json
|
305
317
|
- rules/basic.fe
|
306
318
|
- test/fbe/middleware/test_formatter.rb
|
307
|
-
- test/fbe/middleware/test_quota.rb
|
308
319
|
- test/fbe/test_award.rb
|
309
320
|
- test/fbe/test_bylaws.rb
|
310
321
|
- test/fbe/test_conclude.rb
|
data/.simplecov
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
#
|
4
|
-
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
5
|
-
# SPDX-License-Identifier: MIT
|
6
|
-
|
7
|
-
if Gem.win_platform?
|
8
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
9
|
-
SimpleCov::Formatter::HTMLFormatter
|
10
|
-
]
|
11
|
-
SimpleCov.start do
|
12
|
-
add_filter '/test/'
|
13
|
-
add_filter '/features/'
|
14
|
-
end
|
15
|
-
else
|
16
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
|
17
|
-
[SimpleCov::Formatter::HTMLFormatter]
|
18
|
-
)
|
19
|
-
SimpleCov.start do
|
20
|
-
add_filter '/test/'
|
21
|
-
add_filter '/features/'
|
22
|
-
minimum_coverage 15
|
23
|
-
end
|
24
|
-
end
|
data/lib/fbe/middleware/quota.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
4
|
-
# SPDX-License-Identifier: MIT
|
5
|
-
|
6
|
-
require 'faraday'
|
7
|
-
require_relative '../middleware'
|
8
|
-
|
9
|
-
# Faraday Middleware that monitors GitHub API rate limits.
|
10
|
-
#
|
11
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
12
|
-
# Copyright:: Copyright (c) 2024-2025 Zerocracy
|
13
|
-
# License:: MIT
|
14
|
-
class Fbe::Middleware::Quota < Faraday::Middleware
|
15
|
-
# Constructor.
|
16
|
-
#
|
17
|
-
# @param [Object] app The Faraday app
|
18
|
-
# @param [Loog] loog The logging facility
|
19
|
-
# @param [Integer] pause Seconds to pause when rate limit is reached
|
20
|
-
# @param [Integer] limit Maximum number of requests before checking rate limit
|
21
|
-
# @param [Integer] rate Minimum remaining requests threshold
|
22
|
-
def initialize(app, loog: Loog::NULL, pause: 60, limit: 100, rate: 5)
|
23
|
-
super(app)
|
24
|
-
@requests = 0
|
25
|
-
@app = app
|
26
|
-
raise 'The "loog" cannot be nil' if loog.nil?
|
27
|
-
@loog = loog
|
28
|
-
raise 'The "pause" cannot be nil' if pause.nil?
|
29
|
-
raise 'The "pause" must be a positive integer' unless pause.positive?
|
30
|
-
@pause = pause
|
31
|
-
raise 'The "limit" cannot be nil' if limit.nil?
|
32
|
-
raise 'The "limit" must be a positive integer' unless limit.positive?
|
33
|
-
@limit = limit
|
34
|
-
raise 'The "rate" cannot be nil' if rate.nil?
|
35
|
-
raise 'The "rate" must be a positive integer' unless rate.positive?
|
36
|
-
@rate = rate
|
37
|
-
end
|
38
|
-
|
39
|
-
# Process the request and handle rate limiting.
|
40
|
-
#
|
41
|
-
# @param [Faraday::Env] env The environment
|
42
|
-
# @return [Faraday::Response] The response
|
43
|
-
def call(env)
|
44
|
-
@requests += 1
|
45
|
-
response = @app.call(env)
|
46
|
-
if out_of_limit?(env)
|
47
|
-
@loog.info("Too much GitHub API quota consumed, pausing for #{@pause} seconds")
|
48
|
-
sleep(@pause)
|
49
|
-
@requests = 0
|
50
|
-
end
|
51
|
-
response
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
# Check if we're approaching the rate limit.
|
57
|
-
#
|
58
|
-
# @param [Faraday::Env] env The environment
|
59
|
-
# @return [Boolean] True if we should pause to avoid hitting rate limits
|
60
|
-
def out_of_limit?(env)
|
61
|
-
remaining = env.response_headers['x-ratelimit-remaining'].to_i
|
62
|
-
(@requests % @limit).zero? && remaining < @rate
|
63
|
-
end
|
64
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
4
|
-
# SPDX-License-Identifier: MIT
|
5
|
-
|
6
|
-
require 'faraday'
|
7
|
-
require 'logger'
|
8
|
-
require 'loog'
|
9
|
-
require 'judges'
|
10
|
-
require 'judges/options'
|
11
|
-
require_relative '../../../lib/fbe/middleware'
|
12
|
-
require_relative '../../../lib/fbe/middleware/quota'
|
13
|
-
require_relative '../../test__helper'
|
14
|
-
|
15
|
-
class QuotaTest < Minitest::Test
|
16
|
-
class FakeApp
|
17
|
-
def initialize
|
18
|
-
@calls = 0
|
19
|
-
end
|
20
|
-
|
21
|
-
def call(env)
|
22
|
-
@calls += 1
|
23
|
-
response_headers = {
|
24
|
-
'x-ratelimit-remaining' => (100 - @calls).to_s
|
25
|
-
}
|
26
|
-
env[:response_headers] = response_headers
|
27
|
-
env
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_quota_middleware_pauses_when_quota_low
|
32
|
-
loog = Loog::NULL
|
33
|
-
pause = 0.1
|
34
|
-
app = FakeApp.new
|
35
|
-
middleware = Fbe::Middleware::Quota.new(app, loog:, pause:)
|
36
|
-
start_time = Time.now
|
37
|
-
105.times do
|
38
|
-
env = Judges::Options.new(
|
39
|
-
'method' => :get,
|
40
|
-
'url' => 'http://example.com',
|
41
|
-
'request_headers' => {},
|
42
|
-
'response_headers' => {}
|
43
|
-
)
|
44
|
-
middleware.call(env)
|
45
|
-
end
|
46
|
-
assert_in_delta pause, Time.now - start_time, 0.4
|
47
|
-
end
|
48
|
-
|
49
|
-
def test_quota_middleware_logs_when_quota_low
|
50
|
-
pause = 0.1
|
51
|
-
log_output = StringIO.new
|
52
|
-
loog = Logger.new(log_output)
|
53
|
-
app = FakeApp.new
|
54
|
-
middleware = Fbe::Middleware::Quota.new(app, loog:, pause:)
|
55
|
-
105.times do
|
56
|
-
env = Judges::Options.new(
|
57
|
-
'method' => :get,
|
58
|
-
'url' => 'http://example.com',
|
59
|
-
'request_headers' => {},
|
60
|
-
'response_headers' => {}
|
61
|
-
)
|
62
|
-
middleware.call(env)
|
63
|
-
end
|
64
|
-
assert_match(/Too much GitHub API quota/, log_output.string)
|
65
|
-
end
|
66
|
-
end
|