hub 1.11.0 → 1.11.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of hub might be problematic. Click here for more details.

data/test/hub_test.rb DELETED
@@ -1,607 +0,0 @@
1
- require 'helper'
2
- require 'webmock/minitest'
3
- require 'rbconfig'
4
- require 'yaml'
5
- require 'forwardable'
6
- require 'fileutils'
7
- require 'tempfile'
8
-
9
- WebMock::BodyPattern.class_eval do
10
- undef normalize_hash
11
- # override normalizing hash since it otherwise requires JSON
12
- def normalize_hash(hash) hash end
13
-
14
- # strip out the "charset" directive from Content-type value
15
- alias matches_with_dumb_content_type matches?
16
- def matches?(body, content_type = "")
17
- content_type = content_type.split(';').first if content_type.respond_to? :split
18
- matches_with_dumb_content_type(body, content_type)
19
- end
20
- end
21
-
22
- class HubTest < Minitest::Test
23
- extend Forwardable
24
-
25
- if defined? WebMock::API
26
- include WebMock::API
27
- else
28
- include WebMock
29
- end
30
-
31
- COMMANDS = []
32
-
33
- Hub::Context::System.class_eval do
34
- remove_method :which
35
- define_method :which do |name|
36
- COMMANDS.include?(name) ? "/usr/bin/#{name}" : nil
37
- end
38
- end
39
-
40
- attr_reader :git_reader
41
- include Hub::Context::GitReaderMethods
42
- def_delegators :git_reader, :stub_config_value, :stub_command_output
43
-
44
- def setup
45
- super
46
- COMMANDS.replace %w[open groff]
47
- Hub::Context::PWD.replace '/path/to/hub'
48
- Hub::SshConfig::CONFIG_FILES.replace []
49
-
50
- @prompt_stubs = prompt_stubs = []
51
- @password_prompt_stubs = password_prompt_stubs = []
52
-
53
- Hub::GitHubAPI::Configuration.class_eval do
54
- undef prompt
55
- undef prompt_password
56
-
57
- define_method :prompt do |what|
58
- prompt_stubs.shift.call(what)
59
- end
60
- define_method :prompt_password do |host, user|
61
- password_prompt_stubs.shift.call(host, user)
62
- end
63
- end
64
-
65
- @git_reader = Hub::Context::GitReader.new 'git' do |cache, cmd|
66
- unless cmd.index('config --get alias.') == 0
67
- raise ArgumentError, "`git #{cmd}` not stubbed"
68
- end
69
- end
70
-
71
- Hub::Commands.instance_variable_set :@git_reader, @git_reader
72
- Hub::Commands.instance_variable_set :@local_repo, nil
73
- Hub::Commands.instance_variable_set :@api_client, nil
74
-
75
- FileUtils.rm_rf ENV['HUB_CONFIG']
76
-
77
- edit_hub_config do |data|
78
- data['github.com'] = [{'user' => 'tpw', 'oauth_token' => 'OTOKEN'}]
79
- end
80
-
81
- @git_reader.stub! \
82
- 'remote' => "mislav\norigin",
83
- 'symbolic-ref -q HEAD' => 'refs/heads/master',
84
- 'remote -v' => "origin\tgit://github.com/defunkt/hub.git (fetch)\nmislav\tgit://github.com/mislav/hub.git (fetch)",
85
- 'rev-parse --symbolic-full-name master@{upstream}' => 'refs/remotes/origin/master',
86
- 'rev-parse --symbolic-full-name origin' => 'refs/remotes/origin/master',
87
- 'config --get --bool hub.http-clone' => 'false',
88
- 'config --get hub.protocol' => nil,
89
- 'config --get-all hub.host' => nil,
90
- 'config --get push.default' => nil,
91
- 'rev-parse -q --git-dir' => '.git'
92
-
93
- stub_remote_branch('origin/master')
94
- end
95
-
96
- def teardown
97
- super
98
- WebMock.reset!
99
- end
100
-
101
- def test_cherry_pick
102
- assert_forwarded "cherry-pick a319d88"
103
- end
104
-
105
- def test_cherry_pick_url
106
- url = 'http://github.com/mislav/hub/commit/a319d88'
107
- assert_commands "git fetch mislav", "git cherry-pick a319d88", "cherry-pick #{url}"
108
- end
109
-
110
- def test_cherry_pick_url_with_fragment
111
- url = 'http://github.com/mislav/hub/commit/abcdef0123456789#comments'
112
- assert_commands "git fetch mislav", "git cherry-pick abcdef0123456789", "cherry-pick #{url}"
113
- end
114
-
115
- def test_cherry_pick_url_with_remote_add
116
- url = 'https://github.com/xoebus/hub/commit/a319d88'
117
- assert_commands "git remote add -f xoebus git://github.com/xoebus/hub.git",
118
- "git cherry-pick a319d88",
119
- "cherry-pick #{url}"
120
- end
121
-
122
- def test_cherry_pick_origin_url
123
- url = 'https://github.com/defunkt/hub/commit/a319d88'
124
- assert_commands "git fetch origin", "git cherry-pick a319d88", "cherry-pick #{url}"
125
- end
126
-
127
- def test_cherry_pick_github_user_notation
128
- assert_commands "git fetch mislav", "git cherry-pick 368af20", "cherry-pick mislav@368af20"
129
- end
130
-
131
- def test_cherry_pick_github_user_repo_notation
132
- # not supported
133
- assert_forwarded "cherry-pick mislav/hubbub@a319d88"
134
- end
135
-
136
- def test_cherry_pick_github_notation_too_short
137
- assert_forwarded "cherry-pick mislav@a319"
138
- end
139
-
140
- def test_cherry_pick_github_notation_with_remote_add
141
- assert_commands "git remote add -f xoebus git://github.com/xoebus/hub.git",
142
- "git cherry-pick a319d88",
143
- "cherry-pick xoebus@a319d88"
144
- end
145
-
146
- def test_am_untouched
147
- assert_forwarded "am some.patch"
148
- end
149
-
150
- def test_am_pull_request
151
- stub_request(:get, "https://api.github.com/repos/defunkt/hub/pulls/55").
152
- with(:headers => {'Accept'=>'application/vnd.github.v3.patch', 'Authorization'=>'token OTOKEN'}).
153
- to_return(:status => 200)
154
-
155
- with_tmpdir('/tmp/') do
156
- assert_commands "git am --signoff /tmp/55.patch -p2",
157
- "am --signoff https://github.com/defunkt/hub/pull/55#comment_123 -p2"
158
-
159
- cmd = Hub("am https://github.com/defunkt/hub/pull/55/files").command
160
- assert_includes '/tmp/55.patch', cmd
161
- end
162
- end
163
-
164
- def test_am_no_tmpdir
165
- stub_request(:get, "https://api.github.com/repos/defunkt/hub/pulls/55").
166
- to_return(:status => 200)
167
-
168
- with_tmpdir(nil) do
169
- cmd = Hub("am https://github.com/defunkt/hub/pull/55").command
170
- assert_includes '/tmp/55.patch', cmd
171
- end
172
- end
173
-
174
- def test_am_commit_url
175
- stub_request(:get, "https://api.github.com/repos/davidbalbert/hub/commits/fdb9921").
176
- with(:headers => {'Accept'=>'application/vnd.github.v3.patch', 'Authorization'=>'token OTOKEN'}).
177
- to_return(:status => 200)
178
-
179
- with_tmpdir('/tmp/') do
180
- url = 'https://github.com/davidbalbert/hub/commit/fdb9921'
181
- assert_commands "git am --signoff /tmp/fdb9921.patch -p2",
182
- "am --signoff #{url} -p2"
183
- end
184
- end
185
-
186
- def test_am_gist
187
- stub_request(:get, "https://api.github.com/gists/8da7fb575debd88c54cf").
188
- with(:headers => {'Authorization'=>'token OTOKEN'}).
189
- to_return(:body => Hub::JSON.generate(:files => {
190
- 'file.diff' => {
191
- :raw_url => "https://gist.github.com/raw/8da7fb575debd88c54cf/SHA/file.diff"
192
- }
193
- }))
194
-
195
- stub_request(:get, "https://gist.github.com/raw/8da7fb575debd88c54cf/SHA/file.diff").
196
- with(:headers => {'Accept'=>'text/plain'}).
197
- to_return(:status => 200)
198
-
199
- with_tmpdir('/tmp/') do
200
- url = 'https://gist.github.com/8da7fb575debd88c54cf'
201
-
202
- assert_commands "git am --signoff /tmp/gist-8da7fb575debd88c54cf.txt -p2",
203
- "am --signoff #{url} -p2"
204
- end
205
- end
206
-
207
- def test_apply_untouched
208
- assert_forwarded "apply some.patch"
209
- end
210
-
211
- def test_apply_pull_request
212
- stub_request(:get, "https://api.github.com/repos/defunkt/hub/pulls/55").
213
- to_return(:status => 200)
214
-
215
- with_tmpdir('/tmp/') do
216
- assert_commands "git apply /tmp/55.patch -p2",
217
- "apply https://github.com/defunkt/hub/pull/55 -p2"
218
-
219
- cmd = Hub("apply https://github.com/defunkt/hub/pull/55/files").command
220
- assert_includes '/tmp/55.patch', cmd
221
- end
222
- end
223
-
224
- def test_apply_commit_url
225
- stub_request(:get, "https://api.github.com/repos/davidbalbert/hub/commits/fdb9921").
226
- to_return(:status => 200)
227
-
228
- with_tmpdir('/tmp/') do
229
- url = 'https://github.com/davidbalbert/hub/commit/fdb9921'
230
-
231
- assert_commands "git apply /tmp/fdb9921.patch -p2",
232
- "apply #{url} -p2"
233
- end
234
- end
235
-
236
- def test_apply_gist
237
- stub_request(:get, "https://api.github.com/gists/8da7fb575debd88c54cf").
238
- with(:headers => {'Authorization'=>'token OTOKEN'}).
239
- to_return(:body => Hub::JSON.generate(:files => {
240
- 'file.diff' => {
241
- :raw_url => "https://gist.github.com/raw/8da7fb575debd88c54cf/SHA/file.diff"
242
- }
243
- }))
244
-
245
- stub_request(:get, "https://gist.github.com/raw/8da7fb575debd88c54cf/SHA/file.diff").
246
- to_return(:status => 200)
247
-
248
- with_tmpdir('/tmp/') do
249
- url = 'https://gist.github.com/mislav/8da7fb575debd88c54cf'
250
-
251
- assert_commands "git apply /tmp/gist-8da7fb575debd88c54cf.txt -p2",
252
- "apply #{url} -p2"
253
- end
254
- end
255
-
256
- def test_init
257
- stub_no_remotes
258
- stub_no_git_repo
259
- assert_commands "git init", "git remote add origin git@github.com:tpw/hub.git", "init -g"
260
- end
261
-
262
- def test_init_enterprise
263
- stub_no_remotes
264
- stub_no_git_repo
265
- edit_hub_config do |data|
266
- data['git.my.org'] = [{'user'=>'myfiname'}]
267
- end
268
-
269
- with_host_env('git.my.org') do
270
- assert_commands "git init", "git remote add origin git@git.my.org:myfiname/hub.git", "init -g"
271
- end
272
- end
273
-
274
- def test_push_untouched
275
- assert_forwarded "push"
276
- end
277
-
278
- def test_push_two
279
- assert_commands "git push origin cool-feature", "git push staging cool-feature",
280
- "push origin,staging cool-feature"
281
- end
282
-
283
- def test_push_current_branch
284
- stub_branch('refs/heads/cool-feature')
285
- assert_commands "git push origin cool-feature", "git push staging cool-feature",
286
- "push origin,staging"
287
- end
288
-
289
- def test_push_more
290
- assert_commands "git push origin cool-feature",
291
- "git push staging cool-feature",
292
- "git push qa cool-feature",
293
- "push origin,staging,qa cool-feature"
294
- end
295
-
296
- def test_push_multiple_refs
297
- assert_commands "git push origin master new-feature",
298
- "git push staging master new-feature",
299
- "push origin,staging master new-feature"
300
- end
301
-
302
- def test_pullrequest_from_branch_tracking_local
303
- stub_config_value 'push.default', 'upstream'
304
- stub_branch('refs/heads/feature')
305
- stub_tracking('feature', 'refs/heads/master')
306
-
307
- stub_request(:post, "https://api.github.com/repos/defunkt/hub/pulls").
308
- with(:body => {'base' => "master", 'head' => "defunkt:feature", 'title' => "hereyougo" }).
309
- to_return(:body => mock_pullreq_response(1))
310
-
311
- expected = "https://github.com/defunkt/hub/pull/1\n"
312
- assert_output expected, "pull-request -m hereyougo -f"
313
- end
314
-
315
- def test_pullrequest_enterprise_no_tracking
316
- stub_hub_host('git.my.org')
317
- stub_repo_url('git@git.my.org:defunkt/hub.git')
318
- stub_branch('refs/heads/feature')
319
- stub_remote_branch('origin/feature')
320
- stub_tracking_nothing('feature')
321
- stub_command_output "rev-list --cherry-pick --right-only --no-merges origin/feature...", nil
322
- edit_hub_config do |data|
323
- data['git.my.org'] = [{'user'=>'myfiname', 'oauth_token' => 'FITOKEN'}]
324
- end
325
-
326
- stub_request(:post, "https://git.my.org/api/v3/repos/defunkt/hub/pulls").
327
- with(:body => {'base' => "master", 'head' => "defunkt:feature", 'title' => "hereyougo" }).
328
- to_return(:body => mock_pullreq_response(1, 'api/v3/defunkt/hub', 'git.my.org'))
329
-
330
- expected = "https://git.my.org/api/v3/defunkt/hub/pull/1\n"
331
- assert_output expected, "pull-request -m hereyougo -f"
332
- end
333
-
334
- def test_pullrequest_alias
335
- out = hub('e-note')
336
- assert_equal hub('pull-request'), out
337
- end
338
-
339
- def test_version
340
- out = hub('--version')
341
- assert_includes "git version 1.7.0.4", out
342
- assert_includes "hub version #{Hub::Version}", out
343
- end
344
-
345
- def test_exec_path
346
- out = hub('--exec-path')
347
- assert_equal "/usr/lib/git-core\n", out
348
- end
349
-
350
- def test_exec_path_arg
351
- out = hub('--exec-path=/home/wombat/share/my-l33t-git-core')
352
- assert_equal improved_help_text, out
353
- end
354
-
355
- def test_html_path
356
- out = hub('--html-path')
357
- assert_equal "/usr/share/doc/git-doc\n", out
358
- end
359
-
360
- def test_help
361
- assert_equal improved_help_text, hub("help")
362
- end
363
-
364
- def test_help_by_default
365
- assert_equal improved_help_text, hub("")
366
- end
367
-
368
- def test_help_with_pager
369
- assert_equal improved_help_text, hub("-p")
370
- end
371
-
372
- def test_help_hub
373
- help_manpage = strip_man_escapes hub("help hub")
374
- assert_includes "git + hub = github", help_manpage
375
- assert_includes "Hub will prompt for GitHub username & password", help_manpage.gsub(/ {2,}/, ' ')
376
- end
377
-
378
- def test_help_flag_on_command
379
- help_manpage = strip_man_escapes hub("browse --help")
380
- assert_includes "git + hub = github", help_manpage
381
- assert_includes "git browse", help_manpage
382
- end
383
-
384
- def test_help_custom_command
385
- help_manpage = strip_man_escapes hub("help fork")
386
- assert_includes "git fork [--no-remote]", help_manpage
387
- end
388
-
389
- def test_help_short_flag_on_command
390
- usage_help = hub("create -h")
391
- expected = "Usage: git create [NAME] [-p] [-d DESCRIPTION] [-h HOMEPAGE]\n"
392
- assert_equal expected, usage_help
393
-
394
- usage_help = hub("pull-request -h")
395
- expected = "Usage: git pull-request [-f] [-m MESSAGE|-F FILE|-i ISSUE|ISSUE-URL] [-b BASE] [-h HEAD]\n"
396
- assert_equal expected, usage_help
397
- end
398
-
399
- def test_help_hub_no_groff
400
- stub_available_commands()
401
- assert_equal "** Can't find groff(1)\n", hub("help hub")
402
- end
403
-
404
- def test_hub_standalone
405
- assert_includes 'This file is generated code', hub("hub standalone")
406
- end
407
-
408
- def test_hub_browse_no_repo
409
- stub_repo_url(nil)
410
- assert_equal "Usage: hub browse [<USER>/]<REPOSITORY>\n", hub("browse")
411
- end
412
-
413
- def test_hub_browse_ssh_alias
414
- with_ssh_config "Host gh\n User git\n HostName github.com" do
415
- stub_repo_url "gh:singingwolfboy/sekrit.git"
416
- assert_command "browse", "open https://github.com/singingwolfboy/sekrit"
417
- end
418
- end
419
-
420
- def test_hub_browse_ssh_github_alias
421
- with_ssh_config "Host github.com\n HostName ssh.github.com" do
422
- stub_repo_url "git@github.com:suan/git-sanity.git"
423
- assert_command "browse", "open https://github.com/suan/git-sanity"
424
- end
425
- end
426
-
427
- def test_custom_browser
428
- with_browser_env("custom") do
429
- assert_browser("custom")
430
- end
431
- end
432
-
433
- def test_linux_browser
434
- stub_available_commands "open", "xdg-open", "cygstart"
435
- with_browser_env(nil) do
436
- with_host_os("i686-linux") do
437
- assert_browser("xdg-open")
438
- end
439
- end
440
- end
441
-
442
- def test_cygwin_browser
443
- stub_available_commands "open", "cygstart"
444
- with_browser_env(nil) do
445
- with_host_os("i686-linux") do
446
- assert_browser("cygstart")
447
- end
448
- end
449
- end
450
-
451
- def test_no_browser
452
- stub_available_commands()
453
- expected = "Please set $BROWSER to a web launcher to use this command.\n"
454
- with_browser_env(nil) do
455
- with_host_os("i686-linux") do
456
- assert_equal expected, hub("browse")
457
- end
458
- end
459
- end
460
-
461
- def test_context_method_doesnt_hijack_git_command
462
- assert_forwarded 'remotes'
463
- end
464
-
465
- def test_not_choking_on_ruby_methods
466
- assert_forwarded 'id'
467
- assert_forwarded 'name'
468
- end
469
-
470
- def test_global_flags_preserved
471
- cmd = '--no-pager --bare -c core.awesome=true -c name=value --git-dir=/srv/www perform'
472
- assert_command cmd, 'git --bare -c core.awesome=true -c name=value --git-dir=/srv/www --no-pager perform'
473
- assert_equal %w[git --bare -c core.awesome=true -c name=value --git-dir=/srv/www], git_reader.executable
474
- end
475
-
476
- private
477
-
478
- def stub_repo_url(value, remote_name = 'origin')
479
- stub_command_output 'remote -v', "#{remote_name}\t#{value} (fetch)"
480
- end
481
-
482
- def stub_branch(value)
483
- stub_command_output 'symbolic-ref -q HEAD', value
484
- end
485
-
486
- def stub_tracking(from, upstream, remote_branch = nil)
487
- stub_command_output "rev-parse --symbolic-full-name #{from}@{upstream}",
488
- remote_branch ? "refs/remotes/#{upstream}/#{remote_branch}" : upstream
489
- end
490
-
491
- def stub_tracking_nothing(from = 'master')
492
- stub_tracking(from, nil)
493
- end
494
-
495
- def stub_remote_branch(branch, sha = 'abc123')
496
- stub_command_output "rev-parse -q --verify refs/remotes/#{branch}", sha
497
- end
498
-
499
- def stub_remotes_group(name, value)
500
- stub_config_value "remotes.#{name}", value
501
- end
502
-
503
- def stub_no_remotes
504
- stub_command_output 'remote', nil
505
- end
506
-
507
- def stub_no_git_repo
508
- stub_command_output 'rev-parse -q --git-dir', nil
509
- end
510
-
511
- def stub_alias(name, value)
512
- stub_config_value "alias.#{name}", value
513
- end
514
-
515
- def stub_existing_fork(user, repo = 'hub')
516
- stub_fork(user, repo, 200)
517
- end
518
-
519
- def stub_nonexisting_fork(user, repo = 'hub')
520
- stub_fork(user, repo, 404)
521
- end
522
-
523
- def stub_fork(user, repo, status)
524
- stub_request(:get, "https://api.github.com/repos/#{user}/#{repo}").
525
- to_return(:status => status)
526
- end
527
-
528
- def stub_available_commands(*names)
529
- COMMANDS.replace names
530
- end
531
-
532
- def stub_https_is_preferred
533
- stub_config_value 'hub.protocol', 'https'
534
- end
535
-
536
- def stub_hub_host(names)
537
- stub_config_value "hub.host", Array(names).join("\n"), '--get-all'
538
- end
539
-
540
- def with_browser_env(value)
541
- browser, ENV['BROWSER'] = ENV['BROWSER'], value
542
- yield
543
- ensure
544
- ENV['BROWSER'] = browser
545
- end
546
-
547
- def with_tmpdir(value)
548
- dir, ENV['TMPDIR'] = ENV['TMPDIR'], value
549
- yield
550
- ensure
551
- ENV['TMPDIR'] = dir
552
- end
553
-
554
- def with_host_env(value)
555
- host, ENV['GITHUB_HOST'] = ENV['GITHUB_HOST'], value
556
- yield
557
- ensure
558
- ENV['GITHUB_HOST'] = host
559
- end
560
-
561
- def assert_browser(browser)
562
- assert_command "browse", "#{browser} https://github.com/defunkt/hub"
563
- end
564
-
565
- def with_host_os(value)
566
- host_os = RbConfig::CONFIG['host_os']
567
- RbConfig::CONFIG['host_os'] = value
568
- begin
569
- yield
570
- ensure
571
- RbConfig::CONFIG['host_os'] = host_os
572
- end
573
- end
574
-
575
- def mock_pullreq_response(id, name_with_owner = 'defunkt/hub', host = 'github.com')
576
- Hub::JSON.generate :html_url => "https://#{host}/#{name_with_owner}/pull/#{id}"
577
- end
578
-
579
- def mock_pull_response(label, priv = false)
580
- Hub::JSON.generate :head => {
581
- :label => label,
582
- :repo => {:private => !!priv}
583
- }
584
- end
585
-
586
- def improved_help_text
587
- Hub::Commands.send :improved_help_text
588
- end
589
-
590
- def with_ssh_config content
591
- config_file = Tempfile.open 'ssh_config'
592
- config_file << content
593
- config_file.close
594
-
595
- begin
596
- Hub::SshConfig::CONFIG_FILES.replace [config_file.path]
597
- yield
598
- ensure
599
- config_file.unlink
600
- end
601
- end
602
-
603
- def strip_man_escapes(manpage)
604
- manpage.gsub(/_\010/, '').gsub(/\010./, '')
605
- end
606
-
607
- end