hub_test.rb 28.9 KB
Newer Older
1 2
$LOAD_PATH.unshift File.dirname(__FILE__)
require 'helper'
3
require 'webmock/test_unit'
4
require 'rbconfig'
C
Chris Wanstrath 已提交
5

6 7 8 9 10 11
WebMock::BodyPattern.class_eval do
  undef normalize_hash
  # override normalizing hash since it otherwise requires JSON
  def normalize_hash(hash) hash end
end

C
Chris Wanstrath 已提交
12
class HubTest < Test::Unit::TestCase
13 14 15 16 17
  if defined? WebMock::API
    include WebMock::API
  else
    include WebMock
  end
C
Chris Wanstrath 已提交
18

19 20
  COMMANDS = []

21 22 23 24
  Hub::Context.class_eval do
    remove_method :which
    define_method :which do |name|
      COMMANDS.include?(name) ? "/usr/bin/#{name}" : nil
25 26 27
    end
  end

28
  def setup
29
    COMMANDS.replace %w[open groff]
30
    Hub::Context::DIRNAME.replace 'hub'
31
    Hub::Context::REMOTES.clear
32

33 34
    Hub::Context::GIT_CONFIG.executable = 'git'

35
    @git = Hub::Context::GIT_CONFIG.replace(Hash.new { |h, k|
M
Mislav Marohnić 已提交
36 37 38
      unless k.index('config alias.') == 0
        raise ArgumentError, "`git #{k}` not stubbed"
      end
39
    }).update(
40
      'remote' => "mislav\norigin",
41 42 43
      'symbolic-ref -q HEAD' => 'refs/heads/master',
      'config github.user'   => 'tpw',
      'config github.token'  => 'abc123',
44 45
      'config --get-all remote.origin.url' => 'git://github.com/defunkt/hub.git',
      'config --get-all remote.mislav.url' => 'git://github.com/mislav/hub.git',
46 47
      'config branch.master.remote'  => 'origin',
      'config branch.master.merge'   => 'refs/heads/master',
48 49
      'config --bool hub.http-clone' => 'false',
      'config core.repositoryformatversion' => '0'
50
    )
51
    super
52 53
  end

C
Chris Wanstrath 已提交
54
  def test_private_clone
55 56
    input   = "clone -p rtomayko/ronn"
    command = "git clone git@github.com:rtomayko/ronn.git"
C
Chris Wanstrath 已提交
57
    assert_command input, command
C
Chris Wanstrath 已提交
58 59 60
  end

  def test_public_clone
61 62
    input   = "clone rtomayko/ronn"
    command = "git clone git://github.com/rtomayko/ronn.git"
C
Chris Wanstrath 已提交
63
    assert_command input, command
C
Chris Wanstrath 已提交
64 65
  end

66 67 68 69 70 71 72 73 74 75 76 77
  def test_your_private_clone
    input   = "clone -p resque"
    command = "git clone git@github.com:tpw/resque.git"
    assert_command input, command
  end

  def test_your_public_clone
    input   = "clone resque"
    command = "git clone git://github.com/tpw/resque.git"
    assert_command input, command
  end

78 79 80
  def test_clone_with_arguments
    input   = "clone --bare -o master resque"
    command = "git clone --bare -o master git://github.com/tpw/resque.git"
81 82 83
    assert_command input, command
  end

84 85 86 87
  def test_clone_with_arguments_and_destination
    assert_forwarded "clone --template=one/two git://github.com/tpw/resque.git --origin master resquetastic"
  end

88 89
  def test_your_private_clone_fails_without_config
    out = hub("clone -p mustache") do
90
      stub_github_user(nil)
91 92
    end

93
    assert_equal "** No GitHub user set. See http://help.github.com/git-email-settings/\n", out
94 95 96 97
  end

  def test_your_public_clone_fails_without_config
    out = hub("clone mustache") do
98
      stub_github_user(nil)
99 100
    end

101
    assert_equal "** No GitHub user set. See http://help.github.com/git-email-settings/\n", out
102 103
  end

104
  def test_private_clone_left_alone
105
    assert_forwarded "clone git@github.com:rtomayko/ronn.git"
106 107 108
  end

  def test_public_clone_left_alone
109
    assert_forwarded "clone git://github.com/rtomayko/ronn.git"
110
  end
C
Chris Wanstrath 已提交
111 112

  def test_normal_public_clone_with_path
113
    assert_forwarded "clone git://github.com/rtomayko/ronn.git ronn-dev"
C
Chris Wanstrath 已提交
114
  end
115 116

  def test_normal_clone_from_path
117
    assert_forwarded "clone ./test"
118
  end
119

M
Mislav Marohnić 已提交
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
  def test_alias_expand
    stub_alias 'c', 'clone --bare'
    input   = "c rtomayko/ronn"
    command = "git clone --bare git://github.com/rtomayko/ronn.git"
    assert_command input, command
  end

  def test_alias_expand_advanced
    stub_alias 'c', 'clone --template="white space"'
    input   = "c rtomayko/ronn"
    command = "git clone '--template=white space' git://github.com/rtomayko/ronn.git"
    assert_command input, command
  end

  def test_alias_doesnt_expand_for_unknown_commands
    stub_alias 'c', 'compute --fast'
    assert_forwarded "c rtomayko/ronn"
  end

139 140 141 142 143 144 145 146 147 148 149 150
  def test_remote_origin
    input   = "remote add origin"
    command = "git remote add origin git://github.com/tpw/hub.git"
    assert_command input, command
  end

  def test_private_remote_origin
    input   = "remote add -p origin"
    command = "git remote add origin git@github.com:tpw/hub.git"
    assert_command input, command
  end

151 152 153 154 155 156
  def test_public_remote_origin_as_normal
    input   = "remote add origin http://github.com/defunkt/resque.git"
    command = "git remote add origin http://github.com/defunkt/resque.git"
    assert_command input, command
  end

157
  def test_remote_from_rel_path
158
    assert_forwarded "remote add origin ./path"
159 160 161
  end

  def test_remote_from_abs_path
162
    assert_forwarded "remote add origin /path"
163 164
  end

165
  def test_private_remote_origin_as_normal
166
    assert_forwarded "remote add origin git@github.com:defunkt/resque.git"
C
Chris Wanstrath 已提交
167 168
  end

S
Stephen Celis 已提交
169 170
  def test_public_submodule
    input   = "submodule add wycats/bundler vendor/bundler"
J
Justin Ridgewell 已提交
171 172
    command = "git submodule add git://github.com/wycats/bundler.git vendor/bundler"
    assert_command input, command
S
Stephen Celis 已提交
173 174 175 176
  end

  def test_private_submodule
    input   = "submodule add -p grit vendor/grit"
J
Justin Ridgewell 已提交
177 178 179 180 181 182 183 184
    command = "git submodule add git@github.com:tpw/grit.git vendor/grit"
    assert_command input, command
  end

  def test_submodule_branch
    input   = "submodule add -b ryppl ryppl/pip vendor/pip"
    command = "git submodule add -b ryppl git://github.com/ryppl/pip.git vendor/pip"
    assert_command input, command
S
Stephen Celis 已提交
185 186 187 188 189
  end

  def test_submodule_with_args
    input   = "submodule -q add --bare -- grit grit"
    command = "git submodule -q add --bare -- git://github.com/tpw/grit.git grit"
J
Justin Ridgewell 已提交
190
    assert_command input, command
S
Stephen Celis 已提交
191 192
  end

C
Chris Wanstrath 已提交
193
  def test_private_remote
194
    input   = "remote add -p rtomayko"
C
Chris Wanstrath 已提交
195 196
    command = "git remote add rtomayko git@github.com:rtomayko/hub.git"
    assert_command input, command
C
Chris Wanstrath 已提交
197 198 199
  end

  def test_public_remote
200
    input   = "remote add rtomayko"
C
Chris Wanstrath 已提交
201 202
    command = "git remote add rtomayko git://github.com/rtomayko/hub.git"
    assert_command input, command
C
Chris Wanstrath 已提交
203 204
  end

C
Chris Wanstrath 已提交
205 206 207 208 209 210
  def test_public_remote_f
    input   = "remote add -f rtomayko"
    command = "git remote add -f rtomayko git://github.com/rtomayko/hub.git"
    assert_command input, command
  end

211 212 213 214 215 216
  def test_named_public_remote
    input   = "remote add origin rtomayko"
    command = "git remote add origin git://github.com/rtomayko/hub.git"
    assert_command input, command
  end

217 218 219 220 221 222
  def test_named_public_remote_f
    input   = "remote add -f origin rtomayko"
    command = "git remote add -f origin git://github.com/rtomayko/hub.git"
    assert_command input, command
  end

C
Chris Wanstrath 已提交
223
  def test_private_remote_with_repo
224 225
    input   = "remote add -p jashkenas/coffee-script"
    command = "git remote add jashkenas git@github.com:jashkenas/coffee-script.git"
C
Chris Wanstrath 已提交
226 227 228 229
    assert_command input, command
  end

  def test_public_remote_with_repo
230 231
    input   = "remote add jashkenas/coffee-script"
    command = "git remote add jashkenas git://github.com/jashkenas/coffee-script.git"
232 233 234 235
    assert_command input, command
  end

  def test_public_remote_f_with_repo
236 237
    input   = "remote add -f jashkenas/coffee-script"
    command = "git remote add -f jashkenas git://github.com/jashkenas/coffee-script.git"
C
Chris Wanstrath 已提交
238 239 240
    assert_command input, command
  end

241
  def test_named_private_remote_with_repo
242 243
    input   = "remote add -p origin jashkenas/coffee-script"
    command = "git remote add origin git@github.com:jashkenas/coffee-script.git"
244 245 246
    assert_command input, command
  end

247
  def test_fetch_existing_remote
248
    assert_forwarded "fetch mislav"
249 250 251 252 253 254
  end

  def test_fetch_new_remote
    stub_remotes_group('xoebus', nil)
    stub_existing_fork('xoebus')

255 256 257
    assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
                    "git fetch xoebus",
                    "fetch xoebus"
258 259 260 261 262 263
  end

  def test_fetch_new_remote_with_options
    stub_remotes_group('xoebus', nil)
    stub_existing_fork('xoebus')

264 265 266
    assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
                    "git fetch --depth=1 --prune xoebus",
                    "fetch --depth=1 --prune xoebus"
267 268 269 270 271 272 273 274
  end

  def test_fetch_multiple_new_remotes
    stub_remotes_group('xoebus', nil)
    stub_remotes_group('rtomayko', nil)
    stub_existing_fork('xoebus')
    stub_existing_fork('rtomayko')

275 276 277 278
    assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
                    "git remote add rtomayko git://github.com/rtomayko/hub.git",
                    "git fetch --multiple xoebus rtomayko",
                    "fetch --multiple xoebus rtomayko"
279 280 281 282 283 284 285 286
  end

  def test_fetch_multiple_comma_separated_remotes
    stub_remotes_group('xoebus', nil)
    stub_remotes_group('rtomayko', nil)
    stub_existing_fork('xoebus')
    stub_existing_fork('rtomayko')

287 288 289 290
    assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
                    "git remote add rtomayko git://github.com/rtomayko/hub.git",
                    "git fetch --multiple xoebus rtomayko",
                    "fetch xoebus,rtomayko"
291 292 293 294 295 296 297 298 299 300 301 302 303 304
  end

  def test_fetch_multiple_new_remotes_with_filtering
    stub_remotes_group('xoebus', nil)
    stub_remotes_group('mygrp', 'one two')
    stub_remotes_group('typo', nil)
    stub_existing_fork('xoebus')
    stub_nonexisting_fork('typo')

    # mislav: existing remote; skipped
    # xoebus: new remote, fork exists; added
    # mygrp:  a remotes group; skipped
    # URL:    can't be a username; skipped
    # typo:   fork doesn't exist; skipped
305 306 307
    assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
                    "git fetch --multiple mislav xoebus mygrp git://example.com typo",
                    "fetch --multiple mislav xoebus mygrp git://example.com typo"
308 309
  end

310
  def test_cherry_pick
311
    assert_forwarded "cherry-pick a319d88"
312 313 314
  end

  def test_cherry_pick_url
315
    url = 'http://github.com/mislav/hub/commit/a319d88'
316
    assert_commands "git fetch mislav", "git cherry-pick a319d88", "cherry-pick #{url}"
317 318
  end

319 320
  def test_cherry_pick_url_with_fragment
    url = 'http://github.com/mislav/hub/commit/abcdef0123456789#comments'
321
    assert_commands "git fetch mislav", "git cherry-pick abcdef0123456789", "cherry-pick #{url}"
322 323
  end

324 325
  def test_cherry_pick_url_with_remote_add
    url = 'https://github.com/xoebus/hub/commit/a319d88'
326
    assert_commands "git remote add -f xoebus git://github.com/xoebus/hub.git",
327 328
                    "git cherry-pick a319d88",
                    "cherry-pick #{url}"
329 330 331 332
  end

  def test_cherry_pick_origin_url
    url = 'https://github.com/defunkt/hub/commit/a319d88'
333
    assert_commands "git fetch origin", "git cherry-pick a319d88", "cherry-pick #{url}"
334 335 336
  end

  def test_cherry_pick_github_user_notation
337
    assert_commands "git fetch mislav", "git cherry-pick a319d88", "cherry-pick mislav@a319d88"
338 339 340 341
  end

  def test_cherry_pick_github_user_repo_notation
    # not supported
342
    assert_forwarded "cherry-pick mislav/hubbub@a319d88"
343 344 345
  end

  def test_cherry_pick_github_notation_too_short
346
    assert_forwarded "cherry-pick mislav@a319"
347 348 349
  end

  def test_cherry_pick_github_notation_with_remote_add
350 351 352
    assert_commands "git remote add -f xoebus git://github.com/xoebus/hub.git",
                    "git cherry-pick a319d88",
                    "cherry-pick xoebus@a319d88"
353 354
  end

355 356 357 358 359 360 361 362 363
  def test_am_untouched
    assert_forwarded "am some.patch"
  end

  def test_am_pull_request
    with_tmpdir('/tmp/') do
      assert_commands "curl -#LA 'hub #{Hub::Version}' https://github.com/defunkt/hub/pull/55.patch -o /tmp/55.patch",
                      "git am --signoff /tmp/55.patch -p2",
                      "am --signoff https://github.com/defunkt/hub/pull/55 -p2"
364 365 366

      cmd = Hub("am https://github.com/defunkt/hub/pull/55/files").command
      assert_includes '/pull/55.patch', cmd
367 368 369 370 371 372 373 374 375 376 377 378 379
    end
  end

  def test_am_commit_url
    with_tmpdir('/tmp/') do
      url = 'https://github.com/davidbalbert/hub/commit/fdb9921'

      assert_commands "curl -#LA 'hub #{Hub::Version}' #{url}.patch -o /tmp/fdb9921.patch",
                      "git am --signoff /tmp/fdb9921.patch -p2",
                      "am --signoff #{url} -p2"
    end
  end

380 381 382 383 384 385 386 387 388 389
  def test_am_gist
    with_tmpdir('/tmp/') do
      url = 'https://gist.github.com/8da7fb575debd88c54cf'

      assert_commands "curl -#LA 'hub #{Hub::Version}' #{url}.txt -o /tmp/gist-8da7fb575debd88c54cf.txt",
                      "git am --signoff /tmp/gist-8da7fb575debd88c54cf.txt -p2",
                      "am --signoff #{url} -p2"
    end
  end

C
Chris Wanstrath 已提交
390
  def test_init
391
    assert_commands "git init", "git remote add origin git@github.com:tpw/hub.git", "init -g"
392 393 394 395
  end

  def test_init_no_login
    out = hub("init -g") do
396
      stub_github_user(nil)
397 398
    end

399
    assert_equal "** No GitHub user set. See http://help.github.com/git-email-settings/\n", out
C
Chris Wanstrath 已提交
400 401
  end

402 403 404 405
  def test_push_untouched
    assert_forwarded "push"
  end

406
  def test_push_two
407 408
    assert_commands "git push origin cool-feature", "git push staging cool-feature",
                    "push origin,staging cool-feature"
409 410
  end

411 412 413 414 415 416
  def test_push_current_branch
    stub_branch('refs/heads/cool-feature')
    assert_commands "git push origin cool-feature", "git push staging cool-feature",
                    "push origin,staging"
  end

C
Chris Wanstrath 已提交
417
  def test_push_more
418 419 420 421
    assert_commands "git push origin cool-feature",
                    "git push staging cool-feature",
                    "git push qa cool-feature",
                    "push origin,staging,qa cool-feature"
C
Chris Wanstrath 已提交
422
  end
C
Chris Wanstrath 已提交
423

424
  def test_create
425
    stub_no_remotes
426
    stub_nonexisting_fork('tpw')
427 428
    stub_request(:post, "https://#{auth}github.com/api/v2/yaml/repos/create").
      with(:body => { 'name' => 'hub' })
429

430
    expected = "remote add -f origin git@github.com:tpw/hub.git\n"
431
    expected << "created repository: tpw/hub\n"
432 433 434
    assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
  end

435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
  def test_create_custom_name
    stub_no_remotes
    stub_nonexisting_fork('tpw', 'hubbub')
    stub_request(:post, "https://#{auth}github.com/api/v2/yaml/repos/create").
      with(:body => { 'name' => 'hubbub' })

    expected = "remote add -f origin git@github.com:tpw/hubbub.git\n"
    expected << "created repository: tpw/hubbub\n"
    assert_equal expected, hub("create hubbub") { ENV['GIT'] = 'echo' }
  end

  def test_create_in_organization
    stub_no_remotes
    stub_nonexisting_fork('acme', 'hubbub')
    stub_request(:post, "https://#{auth}github.com/api/v2/yaml/repos/create").
      with(:body => { 'name' => 'acme/hubbub' })

    expected = "remote add -f origin git@github.com:acme/hubbub.git\n"
    expected << "created repository: acme/hubbub\n"
    assert_equal expected, hub("create acme/hubbub") { ENV['GIT'] = 'echo' }
  end

457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
  def test_create_no_openssl
    stub_no_remotes
    stub_nonexisting_fork('tpw')
    stub_request(:post, "http://#{auth}github.com/api/v2/yaml/repos/create").
      with(:body => { 'name' => 'hub' })

    expected = "remote add -f origin git@github.com:tpw/hub.git\n"
    expected << "created repository: tpw/hub\n"

    assert_equal expected, hub("create") {
      ENV['GIT'] = 'echo'
      require 'net/https'
      Object.send :remove_const, :OpenSSL
    }
  end

473 474 475
  def test_create_failed
    stub_no_remotes
    stub_nonexisting_fork('tpw')
476
    stub_request(:post, "https://#{auth}github.com/api/v2/yaml/repos/create").
477 478
      to_return(:status => [401, "Your token is fail"])

479 480
    expected = "Error creating repository: Your token is fail (HTTP 401)\n"
    expected << "Check your token configuration (`git config github.token`)\n"
481 482 483
    assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
  end

484 485 486 487 488 489 490 491 492
  def test_create_with_env_authentication
    stub_no_remotes
    stub_nonexisting_fork('mojombo')

    old_user  = ENV['GITHUB_USER']
    old_token = ENV['GITHUB_TOKEN']
    ENV['GITHUB_USER']  = 'mojombo'
    ENV['GITHUB_TOKEN'] = '123abc'

493 494
    stub_request(:post, "https://#{auth('mojombo', '123abc')}github.com/api/v2/yaml/repos/create").
      with(:body => { 'name' => 'hub' })
495 496 497 498 499 500 501 502 503 504

    expected = "remote add -f origin git@github.com:mojombo/hub.git\n"
    expected << "created repository: mojombo/hub\n"
    assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }

  ensure
    ENV['GITHUB_USER']  = old_user
    ENV['GITHUB_TOKEN'] = old_token
  end

505
  def test_create_private_repository
506
    stub_no_remotes
507
    stub_nonexisting_fork('tpw')
508 509
    stub_request(:post, "https://#{auth}github.com/api/v2/yaml/repos/create").
      with(:body => { 'name' => 'hub', 'public' => '0' })
510

511
    expected = "remote add -f origin git@github.com:tpw/hub.git\n"
512
    expected << "created repository: tpw/hub\n"
513 514 515
    assert_equal expected, hub("create -p") { ENV['GIT'] = 'echo' }
  end

516
  def test_create_with_description_and_homepage
517
    stub_no_remotes
518
    stub_nonexisting_fork('tpw')
519 520
    stub_request(:post, "https://#{auth}github.com/api/v2/yaml/repos/create").with(:body => {
      'name' => 'hub', 'description' => 'toyproject', 'homepage' => 'http://example.com'
521 522
    })

523
    expected = "remote add -f origin git@github.com:tpw/hub.git\n"
524
    expected << "created repository: tpw/hub\n"
525
    assert_equal expected, hub("create -d toyproject -h http://example.com") { ENV['GIT'] = 'echo' }
526 527
  end

528 529 530 531 532
  def test_create_with_invalid_arguments
    assert_equal "invalid argument: -a\n",   hub("create -a blah")   { ENV['GIT'] = 'echo' }
    assert_equal "invalid argument: bleh\n", hub("create blah bleh") { ENV['GIT'] = 'echo' }
  end

533
  def test_create_with_existing_repository
534
    stub_no_remotes
535 536 537 538
    stub_existing_fork('tpw')

    expected = "tpw/hub already exists on GitHub\n"
    expected << "remote add -f origin git@github.com:tpw/hub.git\n"
539
    expected << "set remote origin: tpw/hub\n"
540 541 542
    assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
  end

543
  def test_create_no_user
544
    stub_no_remotes
545 546 547
    out = hub("create") do
      stub_github_token(nil)
    end
548
    assert_equal "** No GitHub token set. See http://help.github.com/git-email-settings/\n", out
549 550
  end

551
  def test_create_outside_git_repo
552
    stub_no_git_repo
553 554
    assert_equal "'create' must be run from inside a git repository\n", hub("create")
  end
555 556

  def test_create_origin_already_exists
C
Chris Wanstrath 已提交
557
    stub_nonexisting_fork('tpw')
558 559
    stub_request(:post, "https://#{auth}github.com/api/v2/yaml/repos/create").
      with(:body => { 'name' => 'hub' })
C
Chris Wanstrath 已提交
560 561

    expected = "remote -v\ncreated repository: tpw/hub\n"
562 563
    assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
  end
C
Chris Wanstrath 已提交
564

565
  def test_fork
C
Chris Wanstrath 已提交
566
    stub_nonexisting_fork('tpw')
567
    stub_request(:post, "https://#{auth}github.com/api/v2/yaml/repos/fork/defunkt/hub")
C
Chris Wanstrath 已提交
568

C
Chris Wanstrath 已提交
569
    expected = "remote add -f tpw git@github.com:tpw/hub.git\n"
570 571 572 573
    expected << "new remote: tpw\n"
    assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
  end

574 575
  def test_fork_failed
    stub_nonexisting_fork('tpw')
576
    stub_request(:post, "https://#{auth}github.com/api/v2/yaml/repos/fork/defunkt/hub").
577 578
      to_return(:status => [500, "Your fork is fail"])

579
    expected = "Error creating fork: Your fork is fail (HTTP 500)\n"
580 581 582
    assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
  end

583
  def test_fork_no_remote
584
    stub_nonexisting_fork('tpw')
585
    stub_request(:post, "https://#{auth}github.com/api/v2/yaml/repos/fork/defunkt/hub")
C
Chris Wanstrath 已提交
586

587 588 589 590
    assert_equal "", hub("fork --no-remote") { ENV['GIT'] = 'echo' }
  end

  def test_fork_already_exists
591
    stub_existing_fork('tpw')
C
Chris Wanstrath 已提交
592

593
    expected = "tpw/hub already exists on GitHub\n"
C
Chris Wanstrath 已提交
594
    expected << "remote add -f tpw git@github.com:tpw/hub.git\n"
595 596 597
    expected << "new remote: tpw\n"
    assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
  end
C
Chris Wanstrath 已提交
598

C
Chris Wanstrath 已提交
599
  def test_version
600
    out = hub('--version')
601
    assert_includes "git version 1.7.0.4", out
C
Chris Wanstrath 已提交
602
    assert_includes "hub version #{Hub::Version}", out
C
Chris Wanstrath 已提交
603
  end
C
Chris Wanstrath 已提交
604

605 606 607 608 609 610 611
  def test_exec_path
    out = hub('--exec-path')
    assert_equal "/usr/lib/git-core\n", out
  end

  def test_exec_path_arg
    out = hub('--exec-path=/home/wombat/share/my-l33t-git-core')
612
    assert_equal Hub::Commands.improved_help_text, out
613 614 615 616 617 618 619
  end

  def test_html_path
    out = hub('--html-path')
    assert_equal "/usr/share/doc/git-doc\n", out
  end

C
Chris Wanstrath 已提交
620 621 622 623 624 625 626
  def test_help
    assert_equal Hub::Commands.improved_help_text, hub("help")
  end

  def test_help_by_default
    assert_equal Hub::Commands.improved_help_text, hub("")
  end
C
Chris Wanstrath 已提交
627

S
Stephen Celis 已提交
628 629 630 631
  def test_help_with_pager
    assert_equal Hub::Commands.improved_help_text, hub("-p")
  end

C
Chris Wanstrath 已提交
632 633 634 635
  def test_help_hub
    help_manpage = hub("help hub")
    assert_includes "git + hub = github", help_manpage
    assert_includes <<-config, help_manpage
C
Chris Wanstrath 已提交
636
Use git-config(1) to display the currently configured GitHub username:
C
Chris Wanstrath 已提交
637 638 639 640
config
  end

  def test_help_hub_no_groff
641 642
    stub_available_commands()
    assert_equal "** Can't find groff(1)\n", hub("help hub")
C
Chris Wanstrath 已提交
643
  end
644

645 646 647 648 649
  def test_hub_standalone
    help_standalone = hub("hub standalone")
    assert_equal Hub::Standalone.build, help_standalone
  end

C
Chris Wanstrath 已提交
650 651
  def test_hub_compare
    assert_command "compare refactor",
652
      "open https://github.com/defunkt/hub/compare/refactor"
653
  end
C
Chris Wanstrath 已提交
654

655 656 657 658
  def test_hub_compare_nothing
    expected = "Usage: hub compare [USER] [<START>...]<END>\n"
    assert_equal expected, hub("compare")
  end
C
Chris Wanstrath 已提交
659

660 661 662 663 664 665 666 667
  def test_hub_compare_tracking_nothing
    stub_tracking_nothing
    expected = "Usage: hub compare [USER] [<START>...]<END>\n"
    assert_equal expected, hub("compare")
  end

  def test_hub_compare_tracking_branch
    stub_branch('refs/heads/feature')
668
    stub_tracking('feature', 'mislav', 'refs/heads/experimental')
669 670

    assert_command "compare",
671
      "open https://github.com/mislav/hub/compare/experimental"
672 673
  end

674
  def test_hub_compare_range
C
Chris Wanstrath 已提交
675
    assert_command "compare 1.0...fix",
676
      "open https://github.com/defunkt/hub/compare/1.0...fix"
677
  end
C
Chris Wanstrath 已提交
678

679 680 681 682 683 684 685 686 687 688 689 690 691 692 693
  def test_hub_compare_range_fixes_two_dots_for_tags
    assert_command "compare 1.0..fix",
      "open https://github.com/defunkt/hub/compare/1.0...fix"
  end

  def test_hub_compare_range_fixes_two_dots_for_shas
    assert_command "compare 1234abc..3456cde",
      "open https://github.com/defunkt/hub/compare/1234abc...3456cde"
  end

  def test_hub_compare_range_ignores_two_dots_for_complex_ranges
    assert_command "compare @{a..b}..@{c..d}",
      "open https://github.com/defunkt/hub/compare/@{a..b}..@{c..d}"
  end

694 695 696 697 698 699
  def test_hub_compare_on_wiki
    stub_repo_url 'git://github.com/defunkt/hub.wiki.git'
    assert_command "compare 1.0...fix",
      "open https://github.com/defunkt/hub/wiki/_compare/1.0...fix"
  end

700
  def test_hub_compare_fork
C
Chris Wanstrath 已提交
701
    assert_command "compare myfork feature",
702
      "open https://github.com/myfork/hub/compare/feature"
703 704 705 706
  end

  def test_hub_compare_url
    assert_command "compare -u 1.0...1.1",
707
      "echo https://github.com/defunkt/hub/compare/1.0...1.1"
708 709 710
  end

  def test_hub_browse
711
    assert_command "browse mojombo/bert", "open https://github.com/mojombo/bert"
712 713
  end

714 715 716 717
  def test_hub_browse_commit
    assert_command "browse mojombo/bert commit/5d5582", "open https://github.com/mojombo/bert/commit/5d5582"
  end

718 719
  def test_hub_browse_tracking_nothing
    stub_tracking_nothing
720
    assert_command "browse mojombo/bert", "open https://github.com/mojombo/bert"
721 722
  end

723
  def test_hub_browse_url
724
    assert_command "browse -u mojombo/bert", "echo https://github.com/mojombo/bert"
725 726
  end

727
  def test_hub_browse_self
728
    assert_command "browse resque", "open https://github.com/tpw/resque"
729 730
  end

731 732
  def test_hub_browse_subpage
    assert_command "browse resque commits",
733
      "open https://github.com/tpw/resque/commits/master"
734
    assert_command "browse resque issues",
735
      "open https://github.com/tpw/resque/issues"
736
    assert_command "browse resque wiki",
737
      "open https://github.com/tpw/resque/wiki"
738 739 740 741
  end

  def test_hub_browse_on_branch
    stub_branch('refs/heads/feature')
742
    stub_tracking('feature', 'mislav', 'refs/heads/experimental')
743

744
    assert_command "browse resque", "open https://github.com/tpw/resque"
745
    assert_command "browse resque commits",
746
      "open https://github.com/tpw/resque/commits/master"
747 748

    assert_command "browse",
749
      "open https://github.com/mislav/hub/tree/experimental"
750
    assert_command "browse -- tree",
751
      "open https://github.com/mislav/hub/tree/experimental"
752
    assert_command "browse -- commits",
753
      "open https://github.com/mislav/hub/commits/experimental"
754
  end
755

756
  def test_hub_browse_current
757 758
    assert_command "browse", "open https://github.com/defunkt/hub"
    assert_command "browse --", "open https://github.com/defunkt/hub"
759 760
  end

761 762 763 764
  def test_hub_browse_commit_from_current
    assert_command "browse -- commit/6616e4", "open https://github.com/defunkt/hub/commit/6616e4"
  end

765 766 767 768 769 770 771 772 773 774 775
  def test_hub_browse_no_tracking
    stub_tracking_nothing
    assert_command "browse", "open https://github.com/defunkt/hub"
  end

  def test_hub_browse_no_tracking_on_branch
    stub_branch('refs/heads/feature')
    stub_tracking('feature', nil, nil)
    assert_command "browse", "open https://github.com/defunkt/hub"
  end

776 777 778 779 780 781 782 783 784
  def test_hub_browse_current_wiki
    stub_repo_url 'git://github.com/defunkt/hub.wiki.git'

    assert_command "browse", "open https://github.com/defunkt/hub/wiki"
    assert_command "browse -- wiki", "open https://github.com/defunkt/hub/wiki"
    assert_command "browse -- commits", "open https://github.com/defunkt/hub/wiki/_history"
    assert_command "browse -- pages", "open https://github.com/defunkt/hub/wiki/_pages"
  end

785 786
  def test_hub_browse_current_subpage
    assert_command "browse -- network",
787
      "open https://github.com/defunkt/hub/network"
788
    assert_command "browse -- anything/everything",
789
      "open https://github.com/defunkt/hub/anything/everything"
790 791
  end

792 793 794 795
  def test_hub_browse_deprecated_private
    with_browser_env('echo') do
      assert_includes "Warning: the `-p` flag has no effect anymore\n", hub("browse -p defunkt/hub")
    end
796 797
  end

798 799 800
  def test_hub_browse_no_repo
    stub_repo_url(nil)
    assert_equal "Usage: hub browse [<USER>/]<REPOSITORY>\n", hub("browse")
801
  end
802 803 804 805 806 807 808 809 810 811

  def test_custom_browser
    with_browser_env("custom") do
      assert_browser("custom")
    end
  end

  def test_linux_browser
    stub_available_commands "open", "xdg-open", "cygstart"
    with_browser_env(nil) do
812
      with_host_os("i686-linux") do
813 814 815 816 817 818 819 820
        assert_browser("xdg-open")
      end
    end
  end

  def test_cygwin_browser
    stub_available_commands "open", "cygstart"
    with_browser_env(nil) do
821
      with_host_os("i686-linux") do
822 823 824 825 826 827 828 829 830
        assert_browser("cygstart")
      end
    end
  end

  def test_no_browser
    stub_available_commands()
    expected = "Please set $BROWSER to a web launcher to use this command.\n"
    with_browser_env(nil) do
831
      with_host_os("i686-linux") do
832 833 834 835 836
        assert_equal expected, hub("browse")
      end
    end
  end

837
  def test_context_method_doesnt_hijack_git_command
838
    assert_forwarded 'remotes'
839 840
  end

841 842 843 844 845
  def test_not_choking_on_ruby_methods
    assert_forwarded 'id'
    assert_forwarded 'name'
  end

846 847
  def test_multiple_remote_urls
    stub_repo_url("git://example.com/other.git\ngit://github.com/my/repo.git")
848
    assert_command "browse", "open https://github.com/my/repo"
849 850
  end

851 852 853 854 855 856
  def test_global_flags_preserved
    cmd = '--no-pager --bare -c core.awesome=true -c name=value --git-dir=/srv/www perform'
    assert_command cmd, 'git --bare -c core.awesome=true -c name=value --git-dir=/srv/www --no-pager perform'
    assert_equal %w[git --bare -c core.awesome=true -c name=value --git-dir=/srv/www], @git.executable
  end

857 858
  protected

859 860 861 862
    def stub_github_user(name)
      @git['config github.user'] = name
    end

863 864 865 866
    def stub_github_token(token)
      @git['config github.token'] = token
    end

867
    def stub_repo_url(value)
868
      @git['config --get-all remote.origin.url'] = value
869 870 871 872 873 874 875
      Hub::Context::REMOTES.clear
    end

    def stub_branch(value)
      @git['symbolic-ref -q HEAD'] = value
    end

876 877 878 879 880
    def stub_tracking(from, remote_name, remote_branch)
      @git["config branch.#{from}.remote"] = remote_name
      @git["config branch.#{from}.merge"] = remote_branch
    end

881
    def stub_tracking_nothing
882
      stub_tracking('master', nil, nil)
883 884
    end

885 886 887 888
    def stub_remotes_group(name, value)
      @git["config remotes.#{name}"] = value
    end

889 890 891 892 893 894 895 896
    def stub_no_remotes
      @git['remote'] = ''
    end

    def stub_no_git_repo
      @git.replace({})
    end

M
Mislav Marohnić 已提交
897 898 899 900
    def stub_alias(name, value)
      @git["config alias.#{name}"] = value
    end

901 902
    def stub_existing_fork(user, repo = 'hub')
      stub_fork(user, repo, 200)
903 904
    end

905 906
    def stub_nonexisting_fork(user, repo = 'hub')
      stub_fork(user, repo, 404)
907 908
    end

909 910
    def stub_fork(user, repo, status)
      stub_request(:get, "github.com/api/v2/yaml/repos/show/#{user}/#{repo}").
911 912 913
        to_return(:status => status)
    end

914 915 916 917 918 919 920 921 922 923 924
    def stub_available_commands(*names)
      COMMANDS.replace names
    end

    def with_browser_env(value)
      browser, ENV['BROWSER'] = ENV['BROWSER'], value
      yield
    ensure
      ENV['BROWSER'] = browser
    end

925 926 927 928 929 930 931
    def with_tmpdir(value)
      dir, ENV['TMPDIR'] = ENV['TMPDIR'], value
      yield
    ensure
      ENV['TMPDIR'] = dir
    end

932
    def assert_browser(browser)
933
      assert_command "browse", "#{browser} https://github.com/defunkt/hub"
934 935
    end

936 937 938 939 940 941 942 943
    def with_host_os(value)
      host_os = RbConfig::CONFIG['host_os']
      RbConfig::CONFIG['host_os'] = value
      begin
        yield
      ensure
        RbConfig::CONFIG['host_os'] = host_os
      end
944 945
    end

946 947 948 949
    def auth(user = @git['config github.user'], password = @git['config github.token'])
      "#{user}%2Ftoken:#{password}@"
    end

C
Chris Wanstrath 已提交
950
end