git-trend 1.3.0 → 1.4.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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +42 -0
- data/.rubocop.yml +85 -2
- data/.rubocop_todo.yml +15 -0
- data/CHANGELOG.md +13 -6
- data/Gemfile +11 -0
- data/README.md +6 -4
- data/git-trend.gemspec +6 -20
- data/lib/git-trend.rb +1 -1
- data/lib/git_trend/cli.rb +6 -4
- data/lib/git_trend/core_ext/string.rb +27 -0
- data/lib/git_trend/formatter.rb +1 -0
- data/lib/git_trend/formatters/json_formatter.rb +2 -2
- data/lib/git_trend/formatters/text_formatter.rb +8 -5
- data/lib/git_trend/scraper.rb +8 -6
- data/lib/git_trend/version.rb +1 -1
- data/lib/git_trend.rb +1 -0
- data/spec/git_trend/cli_spec.rb +47 -33
- data/spec/git_trend/core_ext/string_spec.rb +36 -0
- data/spec/git_trend/scraper_spec.rb +8 -3
- data/spec/git_trend_spec.rb +65 -48
- data/spec/spec_helper.rb +3 -14
- metadata +15 -195
- data/.coveralls.yml +0 -1
- data/.travis.yml +0 -16
data/spec/git_trend/cli_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require "git_trend/scraper"
|
2
|
+
|
3
3
|
RSpec.describe GitTrend::CLI do
|
4
4
|
shared_examples "since daily ranking" do |since|
|
5
5
|
it "display daily ranking" do
|
@@ -20,28 +20,32 @@ RSpec.describe GitTrend::CLI do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
describe "#list" do
|
23
|
-
let(:cli) {
|
23
|
+
let(:cli) { described_class.new }
|
24
24
|
|
25
25
|
describe "with -n option" do
|
26
26
|
context "with 3" do
|
27
27
|
before { stub_request_get("trending") }
|
28
|
+
|
28
29
|
let(:number) { 3 }
|
30
|
+
|
29
31
|
it "display top 3 daily ranking" do
|
30
|
-
res = <<-
|
32
|
+
res = <<-OUTPUT.unindent
|
31
33
|
|No. Name Lang Star
|
32
34
|
|--- ---------------------------------------- ---------------- ------
|
33
35
|
| 1 linexjlin/GPTs 445
|
34
36
|
| 2 ml-explore/mlx-examples Python 161
|
35
37
|
| 3 PRIS-CV/DemoFusion Jupyter Notebook 169
|
36
38
|
|
37
|
-
|
39
|
+
OUTPUT
|
38
40
|
expect { cli.invoke(:list, [], number: number, description: false) }.to output(res).to_stdout
|
39
41
|
end
|
40
42
|
end
|
41
43
|
|
42
44
|
context "with over 25" do
|
43
45
|
before { stub_request_get("trending") }
|
46
|
+
|
44
47
|
let(:number) { 26 }
|
48
|
+
|
45
49
|
it "display daily ranking" do
|
46
50
|
expect { cli.invoke(:list, [], number: number, description: false) }.to output(dummy_result_without_description).to_stdout
|
47
51
|
end
|
@@ -51,10 +55,11 @@ RSpec.describe GitTrend::CLI do
|
|
51
55
|
describe "with -l option" do
|
52
56
|
context "with ruby" do
|
53
57
|
before { stub_request_get("trending/#{language}") }
|
58
|
+
|
54
59
|
let(:language) { "ruby" }
|
55
60
|
|
56
61
|
it "display daily ranking by language" do
|
57
|
-
res = <<-
|
62
|
+
res = <<-OUTPUT.unindent
|
58
63
|
|No. Name Lang Star
|
59
64
|
|--- ---------------------------------------- ---------- ------
|
60
65
|
| 1 greatghoul/remote-working Ruby 34
|
@@ -83,20 +88,21 @@ RSpec.describe GitTrend::CLI do
|
|
83
88
|
| 24 chef/chef Ruby 0
|
84
89
|
| 25 instructure/canvas-lms Ruby 0
|
85
90
|
|
86
|
-
|
91
|
+
OUTPUT
|
87
92
|
expect { cli.invoke(:list, [], language: language, description: false) }.to output(res).to_stdout
|
88
93
|
end
|
89
94
|
end
|
90
95
|
|
91
96
|
context "with alloy : when trending is nothing" do
|
92
97
|
before { stub_request_get("trending/#{language}") }
|
98
|
+
|
93
99
|
let(:language) { "alloy" }
|
94
100
|
|
95
101
|
it "display the 0cases message" do
|
96
|
-
res = <<-
|
102
|
+
res = <<-OUTPUT.unindent
|
97
103
|
|It looks like we don’t have any trending repositories.
|
98
104
|
|
99
|
-
|
105
|
+
OUTPUT
|
100
106
|
expect { cli.invoke(:list, [], language: language, description: false) }.to output(res).to_stdout
|
101
107
|
end
|
102
108
|
end
|
@@ -105,51 +111,55 @@ RSpec.describe GitTrend::CLI do
|
|
105
111
|
describe "with -s option" do
|
106
112
|
context "with no option" do
|
107
113
|
before { stub_request_get("trending?since=") }
|
108
|
-
|
114
|
+
|
115
|
+
it_behaves_like "since daily ranking", ""
|
109
116
|
end
|
110
117
|
|
111
118
|
describe "since daily" do
|
112
119
|
before { stub_request_get("trending?since=daily") }
|
120
|
+
|
113
121
|
context "with d" do
|
114
|
-
|
122
|
+
it_behaves_like "since daily ranking", "d"
|
115
123
|
end
|
116
124
|
|
117
125
|
context "with day" do
|
118
|
-
|
126
|
+
it_behaves_like "since daily ranking", "day"
|
119
127
|
end
|
120
128
|
|
121
129
|
context "with daily" do
|
122
|
-
|
130
|
+
it_behaves_like "since daily ranking", "daily"
|
123
131
|
end
|
124
132
|
end
|
125
133
|
|
126
134
|
describe "since weekly" do
|
127
135
|
before { stub_request_get("trending?since=weekly") }
|
136
|
+
|
128
137
|
context "with w" do
|
129
|
-
|
138
|
+
it_behaves_like "since weekly ranking", "w"
|
130
139
|
end
|
131
140
|
|
132
141
|
context "with week" do
|
133
|
-
|
142
|
+
it_behaves_like "since weekly ranking", "week"
|
134
143
|
end
|
135
144
|
|
136
145
|
context "with weekly" do
|
137
|
-
|
146
|
+
it_behaves_like "since weekly ranking", "weekly"
|
138
147
|
end
|
139
148
|
end
|
140
149
|
|
141
150
|
describe "since monthly" do
|
142
151
|
before { stub_request_get("trending?since=monthly") }
|
152
|
+
|
143
153
|
context "with m" do
|
144
|
-
|
154
|
+
it_behaves_like "since monthly ranking", "m"
|
145
155
|
end
|
146
156
|
|
147
157
|
context "with month" do
|
148
|
-
|
158
|
+
it_behaves_like "since monthly ranking", "month"
|
149
159
|
end
|
150
160
|
|
151
161
|
context "with monthly" do
|
152
|
-
|
162
|
+
it_behaves_like "since monthly ranking", "monthly"
|
153
163
|
end
|
154
164
|
end
|
155
165
|
end
|
@@ -193,11 +203,12 @@ RSpec.describe GitTrend::CLI do
|
|
193
203
|
describe "with -l and -s option" do
|
194
204
|
context "with ruby and weekly" do
|
195
205
|
before { stub_request_get("trending/#{language}?since=#{since}") }
|
206
|
+
|
196
207
|
let(:language) { "ruby" }
|
197
208
|
let(:since) { "weekly" }
|
198
209
|
|
199
210
|
it "display weekly ranking by language" do
|
200
|
-
res = <<-
|
211
|
+
res = <<-OUTPUT.unindent
|
201
212
|
|No. Name Lang Star
|
202
213
|
|--- ---------------------------------------- ---------- ------
|
203
214
|
| 1 mastodon/mastodon Ruby 115
|
@@ -226,7 +237,7 @@ RSpec.describe GitTrend::CLI do
|
|
226
237
|
| 24 rubocop/rubocop Ruby 10
|
227
238
|
| 25 paper-trail-gem/paper_trail Ruby 3
|
228
239
|
|
229
|
-
|
240
|
+
OUTPUT
|
230
241
|
expect { cli.invoke(:list, [], language: language, since: since, description: false) }.to output(res).to_stdout
|
231
242
|
end
|
232
243
|
end
|
@@ -235,18 +246,20 @@ RSpec.describe GitTrend::CLI do
|
|
235
246
|
|
236
247
|
describe "#languages" do
|
237
248
|
before { stub_request_get("trending") }
|
238
|
-
|
249
|
+
|
250
|
+
let(:cli) { described_class.new }
|
239
251
|
|
240
252
|
context "with no option" do
|
241
253
|
it "display languages" do
|
242
|
-
expect { cli.languages }.to output(
|
254
|
+
expect { cli.languages }.to output(include("C++", "HTML", "Ruby")).to_stdout
|
243
255
|
end
|
244
256
|
end
|
245
257
|
end
|
246
258
|
|
247
259
|
private
|
260
|
+
|
248
261
|
def stub_request_get(stub_url_path, stub_file_name = nil)
|
249
|
-
url = Scraper::BASE_HOST.dup
|
262
|
+
url = GitTrend::Scraper::BASE_HOST.dup
|
250
263
|
url << "/#{stub_url_path}" if stub_url_path
|
251
264
|
uri = URI.parse(url)
|
252
265
|
stub_file = stub_file_name || stub_url_path
|
@@ -254,11 +267,12 @@ RSpec.describe GitTrend::CLI do
|
|
254
267
|
.to_return(
|
255
268
|
status: 200,
|
256
269
|
headers: { content_type: "text/html" },
|
257
|
-
body: load_http_stub(stub_file)
|
270
|
+
body: load_http_stub(stub_file)
|
271
|
+
)
|
258
272
|
end
|
259
273
|
|
260
274
|
def dummy_result_without_description
|
261
|
-
<<-
|
275
|
+
<<-OUTPUT.unindent
|
262
276
|
|No. Name Lang Star
|
263
277
|
|--- ------------------------------------------ ---------------- ------
|
264
278
|
| 1 linexjlin/GPTs 445
|
@@ -287,11 +301,11 @@ RSpec.describe GitTrend::CLI do
|
|
287
301
|
| 24 ytdl-org/youtube-dl Python 24
|
288
302
|
| 25 dunglas/frankenphp Go 53
|
289
303
|
|
290
|
-
|
304
|
+
OUTPUT
|
291
305
|
end
|
292
306
|
|
293
307
|
def dummy_result_no_options
|
294
|
-
<<-
|
308
|
+
<<-OUTPUT.unindent
|
295
309
|
|No. Name Lang Star Description
|
296
310
|
|--- ------------------------------------------ ---------------- ------ ---------------------------------------------------------------------
|
297
311
|
| 1 linexjlin/GPTs 445 leaked prompts of GPTs
|
@@ -320,11 +334,11 @@ RSpec.describe GitTrend::CLI do
|
|
320
334
|
| 24 ytdl-org/youtube-dl Python 24 Command-line program to download videos from YouTube.com and other...
|
321
335
|
| 25 dunglas/frankenphp Go 53 The modern PHP app server
|
322
336
|
|
323
|
-
|
337
|
+
OUTPUT
|
324
338
|
end
|
325
339
|
|
326
340
|
def dummy_weekly_result
|
327
|
-
<<-
|
341
|
+
<<-OUTPUT.unindent
|
328
342
|
|No. Name Lang Star
|
329
343
|
|--- ------------------------------------------ ---------------- ------
|
330
344
|
| 1 LC044/WeChatMsg Python 10719
|
@@ -353,11 +367,11 @@ RSpec.describe GitTrend::CLI do
|
|
353
367
|
| 24 coolsnowwolf/lede C 132
|
354
368
|
| 25 QwenLM/Qwen Python 377
|
355
369
|
|
356
|
-
|
370
|
+
OUTPUT
|
357
371
|
end
|
358
372
|
|
359
373
|
def dummy_monthly_result
|
360
|
-
<<-
|
374
|
+
<<-OUTPUT.unindent
|
361
375
|
|No. Name Lang Star
|
362
376
|
|--- ---------------------------------------- ---------------- ------
|
363
377
|
| 1 SawyerHood/draw-a-ui TypeScript 11761
|
@@ -386,6 +400,6 @@ RSpec.describe GitTrend::CLI do
|
|
386
400
|
| 24 SillyTavern/SillyTavern JavaScript 1566
|
387
401
|
| 25 1Panel-dev/1Panel Go 1950
|
388
402
|
|
389
|
-
|
403
|
+
OUTPUT
|
390
404
|
end
|
391
405
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.shared_examples_for "without_options" do |examples|
|
4
|
+
examples.each do |example|
|
5
|
+
input = example[:inputs]
|
6
|
+
it "#{example[:object].inspect}.mb_truncate(#{input}) should return #{example[:expected].inspect}" do
|
7
|
+
expect(example[:object].send(:mb_truncate, input)).to eq example[:expected]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec.describe String do
|
13
|
+
describe "#mb_truncate" do
|
14
|
+
context "ascii strings" do
|
15
|
+
examples = [
|
16
|
+
{ object: "abc", inputs: 2, expected: "..." },
|
17
|
+
{ object: "abc", inputs: 3, expected: "abc" },
|
18
|
+
{ object: "abcde", inputs: 3, expected: "..." },
|
19
|
+
{ object: "abcde", inputs: 4, expected: "a..." },
|
20
|
+
{ object: "abcde", inputs: 5, expected: "abcde" },
|
21
|
+
]
|
22
|
+
it_behaves_like "without_options", examples
|
23
|
+
end
|
24
|
+
|
25
|
+
context "multi-bytes strings" do
|
26
|
+
examples = [
|
27
|
+
{ object: "あいう", inputs: 2, expected: "..." },
|
28
|
+
{ object: "あいう", inputs: 3, expected: "..." },
|
29
|
+
{ object: "あいう", inputs: 4, expected: "..." },
|
30
|
+
{ object: "あいう", inputs: 5, expected: "あ..." },
|
31
|
+
{ object: "あいう", inputs: 6, expected: "あいう" },
|
32
|
+
]
|
33
|
+
it_behaves_like "without_options", examples
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,17 +1,21 @@
|
|
1
|
-
include GitTrend
|
1
|
+
include GitTrend # rubocop:disable Style/MixinUsage
|
2
|
+
|
2
3
|
RSpec.describe GitTrend::Scraper do
|
3
4
|
let(:scraper) { Scraper.new }
|
4
5
|
|
5
6
|
describe "settings" do
|
7
|
+
subject { scraper.instance_variable_get(:@agent) }
|
8
|
+
|
6
9
|
before do
|
7
10
|
allow(ENV).to receive(:[]).with("http_proxy").and_return("http://#{proxy_user}:#{proxy_pass}@#{proxy_addr}:#{proxy_port}")
|
8
11
|
end
|
12
|
+
|
9
13
|
let(:proxy_addr) { "192.168.1.99" }
|
10
14
|
let(:proxy_port) { 9999 }
|
11
15
|
let(:proxy_user) { "proxy_user" }
|
12
16
|
let(:proxy_pass) { "proxy_pass" }
|
13
|
-
|
14
|
-
it "
|
17
|
+
|
18
|
+
it "uses proxy settings of ENV" do
|
15
19
|
aggregate_failures do
|
16
20
|
expect(subject.proxy_addr).to eq proxy_addr
|
17
21
|
expect(subject.proxy_user).to eq proxy_user
|
@@ -28,6 +32,7 @@ RSpec.describe GitTrend::Scraper do
|
|
28
32
|
stub_request(:get, Scraper::BASE_URL)
|
29
33
|
.to_return(status: 500, body: "[]")
|
30
34
|
end
|
35
|
+
|
31
36
|
it { expect { scraper.get }.to raise_error(Exception) }
|
32
37
|
end
|
33
38
|
end
|
data/spec/git_trend_spec.rb
CHANGED
@@ -1,81 +1,98 @@
|
|
1
1
|
RSpec.describe GitTrend do
|
2
|
+
include described_class
|
3
|
+
|
4
|
+
let(:scraper_mock) { instance_double(Scraper) }
|
5
|
+
|
2
6
|
before do
|
7
|
+
allow(Scraper).to receive(:new).and_return(scraper_mock)
|
3
8
|
stub_request(:get, /.*/)
|
4
9
|
.to_return(status: 200, headers: { content_type: "text/html" }, body: load_http_stub("trending"))
|
5
10
|
end
|
6
11
|
|
7
12
|
describe "#get" do
|
8
|
-
context "
|
9
|
-
|
10
|
-
|
11
|
-
GitTrend.get
|
13
|
+
context "normal" do
|
14
|
+
before do
|
15
|
+
allow(scraper_mock).to receive(:get)
|
12
16
|
end
|
13
|
-
end
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
18
|
+
context "without options" do
|
19
|
+
it "Scraper#get call without options" do
|
20
|
+
described_class.get
|
21
|
+
expect(scraper_mock).to have_received(:get).with(no_args)
|
22
|
+
end
|
19
23
|
end
|
20
|
-
end
|
21
24
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
25
|
+
context "parameter is 'ruby'" do
|
26
|
+
it "Scraper#get call with 'ruby'" do
|
27
|
+
described_class.get("ruby")
|
28
|
+
expect(scraper_mock).to have_received(:get).with("ruby")
|
29
|
+
end
|
26
30
|
end
|
27
|
-
end
|
28
31
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
context "parameter is :ruby" do
|
33
|
+
it "Scraper#get call with :ruby" do
|
34
|
+
described_class.get(:ruby)
|
35
|
+
expect(scraper_mock).to have_received(:get).with(:ruby)
|
36
|
+
end
|
33
37
|
end
|
34
|
-
end
|
35
38
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
39
|
+
context "parameter is since: :weekly" do
|
40
|
+
it "Scraper#get call with [nil, :weekly]" do
|
41
|
+
described_class.get(since: :weekly)
|
42
|
+
expect(scraper_mock).to have_received(:get).with(nil, :weekly)
|
43
|
+
end
|
40
44
|
end
|
41
|
-
end
|
42
45
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
46
|
+
context "parameter is since: :week" do
|
47
|
+
it "Scraper#get call with [nil, :week]" do
|
48
|
+
described_class.get(since: :week)
|
49
|
+
expect(scraper_mock).to have_received(:get).with(nil, :week)
|
50
|
+
end
|
47
51
|
end
|
48
|
-
end
|
49
52
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
53
|
+
context "parameter is since: :w" do
|
54
|
+
it "Scraper#get call with [nil, :w]" do
|
55
|
+
described_class.get(since: :w)
|
56
|
+
expect(scraper_mock).to have_received(:get).with(nil, :w)
|
57
|
+
end
|
54
58
|
end
|
55
|
-
end
|
56
59
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
60
|
+
context "parameters are 'ruby', 'weekly'" do
|
61
|
+
it "Scraper#get call with ['ruby', 'weekly']" do
|
62
|
+
described_class.get("ruby", "weekly")
|
63
|
+
expect(scraper_mock).to have_received(:get).with("ruby", "weekly")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "parameters are :ruby, :weekly" do
|
68
|
+
it "Scraper#get call with [:ruby, :weekly]" do
|
69
|
+
described_class.get(:ruby, :weekly)
|
70
|
+
expect(scraper_mock).to have_received(:get).with(:ruby, :weekly)
|
71
|
+
end
|
61
72
|
end
|
62
|
-
end
|
63
73
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
74
|
+
context "parameters are language: :ruby, since: :weekly" do
|
75
|
+
it "Scraper#get call with [:ruby, :weekly]" do
|
76
|
+
described_class.get(language: :ruby, since: :weekly)
|
77
|
+
expect(scraper_mock).to have_received(:get).with(:ruby, :weekly)
|
78
|
+
end
|
68
79
|
end
|
69
80
|
end
|
70
81
|
|
71
|
-
context "
|
72
|
-
|
82
|
+
context "abnormal" do
|
83
|
+
context "when too many parameters" do
|
84
|
+
it { expect { described_class.get("ruby", "weekly", "many_params") }.to raise_error(Exception) }
|
85
|
+
end
|
73
86
|
end
|
74
87
|
|
75
88
|
describe "#languages" do
|
89
|
+
before do
|
90
|
+
allow(scraper_mock).to receive(:languages)
|
91
|
+
end
|
92
|
+
|
76
93
|
it "Scraper#languages call" do
|
77
|
-
|
78
|
-
|
94
|
+
described_class.languages
|
95
|
+
expect(scraper_mock).to have_received(:languages).with(no_args)
|
79
96
|
end
|
80
97
|
end
|
81
98
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -14,25 +14,14 @@
|
|
14
14
|
# users commonly want.
|
15
15
|
#
|
16
16
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
17
|
-
# require "coveralls"
|
18
|
-
# Coveralls.wear!
|
19
|
-
|
20
17
|
require "simplecov"
|
21
|
-
require "webmock/rspec"
|
22
|
-
require "git_trend"
|
23
|
-
|
24
|
-
# require "codeclimate-test-reporter"
|
25
|
-
dir = File.join(ENV["CIRCLE_ARTIFACTS"] || "coverage")
|
26
|
-
SimpleCov.coverage_dir(dir)
|
27
18
|
SimpleCov.start do
|
28
19
|
add_filter "/spec/"
|
29
|
-
|
30
|
-
formatter SimpleCov::Formatter::MultiFormatter.new([
|
31
|
-
SimpleCov::Formatter::HTMLFormatter,
|
32
|
-
# Coveralls::SimpleCov::Formatter
|
33
|
-
])
|
34
20
|
end
|
35
21
|
|
22
|
+
require "webmock/rspec"
|
23
|
+
require "git_trend"
|
24
|
+
|
36
25
|
RSpec.configure do |config|
|
37
26
|
config.expect_with :rspec do |expectations|
|
38
27
|
expectations.syntax = :expect
|