hub 1.6.0
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/LICENSE +20 -0
- data/README.md +351 -0
- data/Rakefile +104 -0
- data/bin/hub +7 -0
- data/lib/hub.rb +5 -0
- data/lib/hub/args.rb +99 -0
- data/lib/hub/commands.rb +718 -0
- data/lib/hub/context.rb +159 -0
- data/lib/hub/runner.rb +71 -0
- data/lib/hub/standalone.rb +52 -0
- data/lib/hub/version.rb +3 -0
- data/man/hub.1 +356 -0
- data/man/hub.1.html +370 -0
- data/man/hub.1.ronn +275 -0
- data/test/alias_test.rb +41 -0
- data/test/deps.rip +1 -0
- data/test/fakebin/git +11 -0
- data/test/fakebin/open +3 -0
- data/test/helper.rb +111 -0
- data/test/hub_test.rb +847 -0
- data/test/standalone_test.rb +49 -0
- metadata +106 -0
data/test/alias_test.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
2
|
+
require 'helper'
|
3
|
+
|
4
|
+
class AliasTest < Test::Unit::TestCase
|
5
|
+
def test_alias
|
6
|
+
instructions = hub("alias")
|
7
|
+
assert_includes "bash", instructions
|
8
|
+
assert_includes "sh", instructions
|
9
|
+
assert_includes "csh", instructions
|
10
|
+
assert_includes "zsh", instructions
|
11
|
+
assert_includes "fish", instructions
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_alias_silent
|
15
|
+
assert_equal "alias git=hub\n", hub("alias -s bash")
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_alias_bash
|
19
|
+
assert_alias_command "bash", "alias git=hub"
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_alias_sh
|
23
|
+
assert_alias_command "sh", "alias git=hub"
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_alias_zsh
|
27
|
+
assert_alias_command "zsh", 'function git(){hub "$@"}'
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_alias_csh
|
31
|
+
assert_alias_command "csh", "alias git hub"
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_alias_fish
|
35
|
+
assert_alias_command "fish", "alias git hub"
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_alias_blah
|
39
|
+
assert_alias_command "blah", "fatal: never heard of `blah'"
|
40
|
+
end
|
41
|
+
end
|
data/test/deps.rip
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
webmock 1.3.0
|
data/test/fakebin/git
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
if [ "$1" = "--version" ]; then
|
3
|
+
echo "git version 1.7.0.4"
|
4
|
+
elif [ "$1" = "--exec-path" ]; then
|
5
|
+
echo "/usr/lib/git-core"
|
6
|
+
elif [ "$1" = "--html-path" ]; then
|
7
|
+
echo "/usr/share/doc/git-doc"
|
8
|
+
else
|
9
|
+
echo "ERROR: git was called, but wasn't supposed to:" git $*
|
10
|
+
exit 1
|
11
|
+
fi
|
data/test/fakebin/open
ADDED
data/test/helper.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'redgreen'
|
5
|
+
rescue LoadError
|
6
|
+
end
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
9
|
+
require 'hub'
|
10
|
+
require 'hub/standalone'
|
11
|
+
|
12
|
+
# We're looking for `open` in the tests.
|
13
|
+
ENV['BROWSER'] = 'open'
|
14
|
+
|
15
|
+
# Setup path with fake executables in case a test hits them
|
16
|
+
fakebin_dir = File.expand_path('../fakebin', __FILE__)
|
17
|
+
ENV['PATH'] = "#{fakebin_dir}:#{ENV['PATH']}"
|
18
|
+
|
19
|
+
class Test::Unit::TestCase
|
20
|
+
# Shortcut for creating a `Hub` instance. Pass it what you would
|
21
|
+
# normally pass `hub` on the command line, e.g.
|
22
|
+
#
|
23
|
+
# shell: hub clone rtomayko/tilt
|
24
|
+
# test: Hub("clone rtomayko/tilt")
|
25
|
+
def Hub(args)
|
26
|
+
Hub::Runner.new(*args.split(' '))
|
27
|
+
end
|
28
|
+
|
29
|
+
# Shortcut for running the `hub` command in a subprocess. Returns
|
30
|
+
# STDOUT as a string. Pass it what you would normally pass `hub` on
|
31
|
+
# the command line, e.g.
|
32
|
+
#
|
33
|
+
# shell: hub clone rtomayko/tilt
|
34
|
+
# test: hub("clone rtomayko/tilt")
|
35
|
+
#
|
36
|
+
# If a block is given it will be run in the child process before
|
37
|
+
# execution begins. You can use this to monkeypatch or fudge the
|
38
|
+
# environment before running hub.
|
39
|
+
def hub(args, input = nil)
|
40
|
+
parent_read, child_write = IO.pipe
|
41
|
+
child_read, parent_write = IO.pipe if input
|
42
|
+
|
43
|
+
fork do
|
44
|
+
yield if block_given?
|
45
|
+
$stdin.reopen(child_read) if input
|
46
|
+
$stdout.reopen(child_write)
|
47
|
+
$stderr.reopen(child_write)
|
48
|
+
Hub(args).execute
|
49
|
+
end
|
50
|
+
|
51
|
+
if input
|
52
|
+
parent_write.write input
|
53
|
+
parent_write.close
|
54
|
+
end
|
55
|
+
child_write.close
|
56
|
+
parent_read.read
|
57
|
+
end
|
58
|
+
|
59
|
+
# Asserts that `hub` will run a specific git command based on
|
60
|
+
# certain input.
|
61
|
+
#
|
62
|
+
# e.g.
|
63
|
+
# assert_command "clone git/hub", "git clone git://github.com/git/hub.git"
|
64
|
+
#
|
65
|
+
# Here we are saying that this:
|
66
|
+
# $ hub clone git/hub
|
67
|
+
# Should in turn execute this:
|
68
|
+
# $ git clone git://github.com/git/hub.git
|
69
|
+
def assert_command(input, expected)
|
70
|
+
assert_equal expected, Hub(input).command, "$ git #{input}"
|
71
|
+
end
|
72
|
+
|
73
|
+
def assert_commands(*expected)
|
74
|
+
input = expected.pop
|
75
|
+
assert_equal expected, Hub(input).commands
|
76
|
+
end
|
77
|
+
|
78
|
+
# Asserts that the command will be forwarded to git without changes
|
79
|
+
def assert_forwarded(input)
|
80
|
+
cmd = Hub(input)
|
81
|
+
assert !cmd.args.changed?, "arguments were not supposed to change: #{cmd.args.inspect}"
|
82
|
+
end
|
83
|
+
|
84
|
+
# Asserts that `hub` will show a specific alias command for a
|
85
|
+
# specific shell.
|
86
|
+
#
|
87
|
+
# e.g.
|
88
|
+
# assert_alias_command "sh", "alias git=hub"
|
89
|
+
#
|
90
|
+
# Here we are saying that this:
|
91
|
+
# $ hub alias sh
|
92
|
+
# Should display this:
|
93
|
+
# Run this in your shell to start using `hub` as `git`:
|
94
|
+
# alias git=hub
|
95
|
+
def assert_alias_command(shell, command)
|
96
|
+
expected = "Run this in your shell to start using `hub` as `git`:\n %s\n"
|
97
|
+
assert_equal(expected % command, hub("alias #{shell}"))
|
98
|
+
end
|
99
|
+
|
100
|
+
# Asserts that `haystack` includes `needle`.
|
101
|
+
def assert_includes(needle, haystack)
|
102
|
+
assert haystack.include?(needle),
|
103
|
+
"expected #{needle.inspect} in #{haystack.inspect}"
|
104
|
+
end
|
105
|
+
|
106
|
+
# Asserts that `haystack` does not include `needle`.
|
107
|
+
def assert_not_includes(needle, haystack)
|
108
|
+
assert !haystack.include?(needle),
|
109
|
+
"didn't expect #{needle.inspect} in #{haystack.inspect}"
|
110
|
+
end
|
111
|
+
end
|
data/test/hub_test.rb
ADDED
@@ -0,0 +1,847 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
2
|
+
require 'helper'
|
3
|
+
require 'webmock/test_unit'
|
4
|
+
|
5
|
+
WebMock::BodyPattern.class_eval do
|
6
|
+
undef normalize_hash
|
7
|
+
# override normalizing hash since it otherwise requires JSON
|
8
|
+
def normalize_hash(hash) hash end
|
9
|
+
end
|
10
|
+
|
11
|
+
class HubTest < Test::Unit::TestCase
|
12
|
+
if defined? WebMock::API
|
13
|
+
include WebMock::API
|
14
|
+
else
|
15
|
+
include WebMock
|
16
|
+
end
|
17
|
+
|
18
|
+
COMMANDS = []
|
19
|
+
|
20
|
+
Hub::Commands.class_eval do
|
21
|
+
remove_method :command?
|
22
|
+
define_method :command? do |name|
|
23
|
+
COMMANDS.include?(name)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup
|
28
|
+
COMMANDS.replace %w[open groff]
|
29
|
+
Hub::Context::DIRNAME.replace 'hub'
|
30
|
+
Hub::Context::REMOTES.clear
|
31
|
+
|
32
|
+
@git = Hub::Context::GIT_CONFIG.replace(Hash.new { |h, k|
|
33
|
+
unless k.index('config alias.') == 0
|
34
|
+
raise ArgumentError, "`git #{k}` not stubbed"
|
35
|
+
end
|
36
|
+
}).update(
|
37
|
+
'remote' => "mislav\norigin",
|
38
|
+
'symbolic-ref -q HEAD' => 'refs/heads/master',
|
39
|
+
'config github.user' => 'tpw',
|
40
|
+
'config github.token' => 'abc123',
|
41
|
+
'config --get-all remote.origin.url' => 'git://github.com/defunkt/hub.git',
|
42
|
+
'config --get-all remote.mislav.url' => 'git://github.com/mislav/hub.git',
|
43
|
+
'config branch.master.remote' => 'origin',
|
44
|
+
'config branch.master.merge' => 'refs/heads/master',
|
45
|
+
'config branch.feature.remote' => 'mislav',
|
46
|
+
'config branch.feature.merge' => 'refs/heads/experimental',
|
47
|
+
'config --bool hub.http-clone' => 'false',
|
48
|
+
'config core.repositoryformatversion' => '0'
|
49
|
+
)
|
50
|
+
super
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_private_clone
|
54
|
+
input = "clone -p rtomayko/ronn"
|
55
|
+
command = "git clone git@github.com:rtomayko/ronn.git"
|
56
|
+
assert_command input, command
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_public_clone
|
60
|
+
input = "clone rtomayko/ronn"
|
61
|
+
command = "git clone git://github.com/rtomayko/ronn.git"
|
62
|
+
assert_command input, command
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_your_private_clone
|
66
|
+
input = "clone -p resque"
|
67
|
+
command = "git clone git@github.com:tpw/resque.git"
|
68
|
+
assert_command input, command
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_your_public_clone
|
72
|
+
input = "clone resque"
|
73
|
+
command = "git clone git://github.com/tpw/resque.git"
|
74
|
+
assert_command input, command
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_clone_with_arguments
|
78
|
+
input = "clone --bare -o master resque"
|
79
|
+
command = "git clone --bare -o master git://github.com/tpw/resque.git"
|
80
|
+
assert_command input, command
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_clone_with_arguments_and_destination
|
84
|
+
assert_forwarded "clone --template=one/two git://github.com/tpw/resque.git --origin master resquetastic"
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_your_private_clone_fails_without_config
|
88
|
+
out = hub("clone -p mustache") do
|
89
|
+
stub_github_user(nil)
|
90
|
+
end
|
91
|
+
|
92
|
+
assert_equal "** No GitHub user set. See http://github.com/guides/local-github-config\n", out
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_your_public_clone_fails_without_config
|
96
|
+
out = hub("clone mustache") do
|
97
|
+
stub_github_user(nil)
|
98
|
+
end
|
99
|
+
|
100
|
+
assert_equal "** No GitHub user set. See http://github.com/guides/local-github-config\n", out
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_private_clone_left_alone
|
104
|
+
assert_forwarded "clone git@github.com:rtomayko/ronn.git"
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_public_clone_left_alone
|
108
|
+
assert_forwarded "clone git://github.com/rtomayko/ronn.git"
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_normal_public_clone_with_path
|
112
|
+
assert_forwarded "clone git://github.com/rtomayko/ronn.git ronn-dev"
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_normal_clone_from_path
|
116
|
+
assert_forwarded "clone ./test"
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_alias_expand
|
120
|
+
stub_alias 'c', 'clone --bare'
|
121
|
+
input = "c rtomayko/ronn"
|
122
|
+
command = "git clone --bare git://github.com/rtomayko/ronn.git"
|
123
|
+
assert_command input, command
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_alias_expand_advanced
|
127
|
+
stub_alias 'c', 'clone --template="white space"'
|
128
|
+
input = "c rtomayko/ronn"
|
129
|
+
command = "git clone '--template=white space' git://github.com/rtomayko/ronn.git"
|
130
|
+
assert_command input, command
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_alias_doesnt_expand_for_unknown_commands
|
134
|
+
stub_alias 'c', 'compute --fast'
|
135
|
+
assert_forwarded "c rtomayko/ronn"
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_remote_origin
|
139
|
+
input = "remote add origin"
|
140
|
+
command = "git remote add origin git://github.com/tpw/hub.git"
|
141
|
+
assert_command input, command
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_private_remote_origin
|
145
|
+
input = "remote add -p origin"
|
146
|
+
command = "git remote add origin git@github.com:tpw/hub.git"
|
147
|
+
assert_command input, command
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_public_remote_origin_as_normal
|
151
|
+
input = "remote add origin http://github.com/defunkt/resque.git"
|
152
|
+
command = "git remote add origin http://github.com/defunkt/resque.git"
|
153
|
+
assert_command input, command
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_remote_from_rel_path
|
157
|
+
assert_forwarded "remote add origin ./path"
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_remote_from_abs_path
|
161
|
+
assert_forwarded "remote add origin /path"
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_private_remote_origin_as_normal
|
165
|
+
assert_forwarded "remote add origin git@github.com:defunkt/resque.git"
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_public_submodule
|
169
|
+
input = "submodule add wycats/bundler vendor/bundler"
|
170
|
+
command = "git submodule add git://github.com/wycats/bundler.git vendor/bundler"
|
171
|
+
assert_command input, command
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_private_submodule
|
175
|
+
input = "submodule add -p grit vendor/grit"
|
176
|
+
command = "git submodule add git@github.com:tpw/grit.git vendor/grit"
|
177
|
+
assert_command input, command
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_submodule_branch
|
181
|
+
input = "submodule add -b ryppl ryppl/pip vendor/pip"
|
182
|
+
command = "git submodule add -b ryppl git://github.com/ryppl/pip.git vendor/pip"
|
183
|
+
assert_command input, command
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_submodule_with_args
|
187
|
+
input = "submodule -q add --bare -- grit grit"
|
188
|
+
command = "git submodule -q add --bare -- git://github.com/tpw/grit.git grit"
|
189
|
+
assert_command input, command
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_private_remote
|
193
|
+
input = "remote add -p rtomayko"
|
194
|
+
command = "git remote add rtomayko git@github.com:rtomayko/hub.git"
|
195
|
+
assert_command input, command
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_public_remote
|
199
|
+
input = "remote add rtomayko"
|
200
|
+
command = "git remote add rtomayko git://github.com/rtomayko/hub.git"
|
201
|
+
assert_command input, command
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_public_remote_f
|
205
|
+
input = "remote add -f rtomayko"
|
206
|
+
command = "git remote add -f rtomayko git://github.com/rtomayko/hub.git"
|
207
|
+
assert_command input, command
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_named_public_remote
|
211
|
+
input = "remote add origin rtomayko"
|
212
|
+
command = "git remote add origin git://github.com/rtomayko/hub.git"
|
213
|
+
assert_command input, command
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_named_public_remote_f
|
217
|
+
input = "remote add -f origin rtomayko"
|
218
|
+
command = "git remote add -f origin git://github.com/rtomayko/hub.git"
|
219
|
+
assert_command input, command
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_private_remote_with_repo
|
223
|
+
input = "remote add -p jashkenas/coffee-script"
|
224
|
+
command = "git remote add jashkenas git@github.com:jashkenas/coffee-script.git"
|
225
|
+
assert_command input, command
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_public_remote_with_repo
|
229
|
+
input = "remote add jashkenas/coffee-script"
|
230
|
+
command = "git remote add jashkenas git://github.com/jashkenas/coffee-script.git"
|
231
|
+
assert_command input, command
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_public_remote_f_with_repo
|
235
|
+
input = "remote add -f jashkenas/coffee-script"
|
236
|
+
command = "git remote add -f jashkenas git://github.com/jashkenas/coffee-script.git"
|
237
|
+
assert_command input, command
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_named_private_remote_with_repo
|
241
|
+
input = "remote add -p origin jashkenas/coffee-script"
|
242
|
+
command = "git remote add origin git@github.com:jashkenas/coffee-script.git"
|
243
|
+
assert_command input, command
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_fetch_existing_remote
|
247
|
+
assert_forwarded "fetch mislav"
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_fetch_new_remote
|
251
|
+
stub_remotes_group('xoebus', nil)
|
252
|
+
stub_existing_fork('xoebus')
|
253
|
+
|
254
|
+
assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
|
255
|
+
"git fetch xoebus",
|
256
|
+
"fetch xoebus"
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_fetch_new_remote_with_options
|
260
|
+
stub_remotes_group('xoebus', nil)
|
261
|
+
stub_existing_fork('xoebus')
|
262
|
+
|
263
|
+
assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
|
264
|
+
"git fetch --depth=1 --prune xoebus",
|
265
|
+
"fetch --depth=1 --prune xoebus"
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_fetch_multiple_new_remotes
|
269
|
+
stub_remotes_group('xoebus', nil)
|
270
|
+
stub_remotes_group('rtomayko', nil)
|
271
|
+
stub_existing_fork('xoebus')
|
272
|
+
stub_existing_fork('rtomayko')
|
273
|
+
|
274
|
+
assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
|
275
|
+
"git remote add rtomayko git://github.com/rtomayko/hub.git",
|
276
|
+
"git fetch --multiple xoebus rtomayko",
|
277
|
+
"fetch --multiple xoebus rtomayko"
|
278
|
+
end
|
279
|
+
|
280
|
+
def test_fetch_multiple_comma_separated_remotes
|
281
|
+
stub_remotes_group('xoebus', nil)
|
282
|
+
stub_remotes_group('rtomayko', nil)
|
283
|
+
stub_existing_fork('xoebus')
|
284
|
+
stub_existing_fork('rtomayko')
|
285
|
+
|
286
|
+
assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
|
287
|
+
"git remote add rtomayko git://github.com/rtomayko/hub.git",
|
288
|
+
"git fetch --multiple xoebus rtomayko",
|
289
|
+
"fetch xoebus,rtomayko"
|
290
|
+
end
|
291
|
+
|
292
|
+
def test_fetch_multiple_new_remotes_with_filtering
|
293
|
+
stub_remotes_group('xoebus', nil)
|
294
|
+
stub_remotes_group('mygrp', 'one two')
|
295
|
+
stub_remotes_group('typo', nil)
|
296
|
+
stub_existing_fork('xoebus')
|
297
|
+
stub_nonexisting_fork('typo')
|
298
|
+
|
299
|
+
# mislav: existing remote; skipped
|
300
|
+
# xoebus: new remote, fork exists; added
|
301
|
+
# mygrp: a remotes group; skipped
|
302
|
+
# URL: can't be a username; skipped
|
303
|
+
# typo: fork doesn't exist; skipped
|
304
|
+
assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
|
305
|
+
"git fetch --multiple mislav xoebus mygrp git://example.com typo",
|
306
|
+
"fetch --multiple mislav xoebus mygrp git://example.com typo"
|
307
|
+
end
|
308
|
+
|
309
|
+
def test_cherry_pick
|
310
|
+
assert_forwarded "cherry-pick a319d88"
|
311
|
+
end
|
312
|
+
|
313
|
+
def test_cherry_pick_url
|
314
|
+
url = 'http://github.com/mislav/hub/commit/a319d88'
|
315
|
+
assert_commands "git fetch mislav", "git cherry-pick a319d88", "cherry-pick #{url}"
|
316
|
+
end
|
317
|
+
|
318
|
+
def test_cherry_pick_url_with_fragment
|
319
|
+
url = 'http://github.com/mislav/hub/commit/abcdef0123456789#comments'
|
320
|
+
assert_commands "git fetch mislav", "git cherry-pick abcdef0123456789", "cherry-pick #{url}"
|
321
|
+
end
|
322
|
+
|
323
|
+
def test_cherry_pick_url_with_remote_add
|
324
|
+
url = 'https://github.com/xoebus/hub/commit/a319d88'
|
325
|
+
assert_commands "git remote add -f xoebus git://github.com/xoebus/hub.git",
|
326
|
+
"git cherry-pick a319d88",
|
327
|
+
"cherry-pick #{url}"
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_cherry_pick_origin_url
|
331
|
+
url = 'https://github.com/defunkt/hub/commit/a319d88'
|
332
|
+
assert_commands "git fetch origin", "git cherry-pick a319d88", "cherry-pick #{url}"
|
333
|
+
end
|
334
|
+
|
335
|
+
def test_cherry_pick_github_user_notation
|
336
|
+
assert_commands "git fetch mislav", "git cherry-pick a319d88", "cherry-pick mislav@a319d88"
|
337
|
+
end
|
338
|
+
|
339
|
+
def test_cherry_pick_github_user_repo_notation
|
340
|
+
# not supported
|
341
|
+
assert_forwarded "cherry-pick mislav/hubbub@a319d88"
|
342
|
+
end
|
343
|
+
|
344
|
+
def test_cherry_pick_github_notation_too_short
|
345
|
+
assert_forwarded "cherry-pick mislav@a319"
|
346
|
+
end
|
347
|
+
|
348
|
+
def test_cherry_pick_github_notation_with_remote_add
|
349
|
+
assert_commands "git remote add -f xoebus git://github.com/xoebus/hub.git",
|
350
|
+
"git cherry-pick a319d88",
|
351
|
+
"cherry-pick xoebus@a319d88"
|
352
|
+
end
|
353
|
+
|
354
|
+
def test_am_untouched
|
355
|
+
assert_forwarded "am some.patch"
|
356
|
+
end
|
357
|
+
|
358
|
+
def test_am_pull_request
|
359
|
+
with_tmpdir('/tmp/') do
|
360
|
+
assert_commands "curl -#LA 'hub #{Hub::Version}' https://github.com/defunkt/hub/pull/55.patch -o /tmp/55.patch",
|
361
|
+
"git am --signoff /tmp/55.patch -p2",
|
362
|
+
"am --signoff https://github.com/defunkt/hub/pull/55 -p2"
|
363
|
+
|
364
|
+
cmd = Hub("am https://github.com/defunkt/hub/pull/55/files").command
|
365
|
+
assert_includes '/pull/55.patch', cmd
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def test_am_commit_url
|
370
|
+
with_tmpdir('/tmp/') do
|
371
|
+
url = 'https://github.com/davidbalbert/hub/commit/fdb9921'
|
372
|
+
|
373
|
+
assert_commands "curl -#LA 'hub #{Hub::Version}' #{url}.patch -o /tmp/fdb9921.patch",
|
374
|
+
"git am --signoff /tmp/fdb9921.patch -p2",
|
375
|
+
"am --signoff #{url} -p2"
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
def test_am_gist
|
380
|
+
with_tmpdir('/tmp/') do
|
381
|
+
url = 'https://gist.github.com/8da7fb575debd88c54cf'
|
382
|
+
|
383
|
+
assert_commands "curl -#LA 'hub #{Hub::Version}' #{url}.txt -o /tmp/gist-8da7fb575debd88c54cf.txt",
|
384
|
+
"git am --signoff /tmp/gist-8da7fb575debd88c54cf.txt -p2",
|
385
|
+
"am --signoff #{url} -p2"
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
def test_init
|
390
|
+
assert_commands "git init", "git remote add origin git@github.com:tpw/hub.git", "init -g"
|
391
|
+
end
|
392
|
+
|
393
|
+
def test_init_no_login
|
394
|
+
out = hub("init -g") do
|
395
|
+
stub_github_user(nil)
|
396
|
+
end
|
397
|
+
|
398
|
+
assert_equal "** No GitHub user set. See http://github.com/guides/local-github-config\n", out
|
399
|
+
end
|
400
|
+
|
401
|
+
def test_push_two
|
402
|
+
assert_commands "git push origin cool-feature", "git push staging cool-feature",
|
403
|
+
"push origin,staging cool-feature"
|
404
|
+
end
|
405
|
+
|
406
|
+
def test_push_more
|
407
|
+
assert_commands "git push origin cool-feature",
|
408
|
+
"git push staging cool-feature",
|
409
|
+
"git push qa cool-feature",
|
410
|
+
"push origin,staging,qa cool-feature"
|
411
|
+
end
|
412
|
+
|
413
|
+
def test_create
|
414
|
+
stub_no_remotes
|
415
|
+
stub_nonexisting_fork('tpw')
|
416
|
+
stub_request(:post, "github.com/api/v2/yaml/repos/create").
|
417
|
+
with(:body => { 'login'=>'tpw', 'token'=>'abc123', 'name' => 'hub' })
|
418
|
+
|
419
|
+
expected = "remote add -f origin git@github.com:tpw/hub.git\n"
|
420
|
+
expected << "created repository: tpw/hub\n"
|
421
|
+
assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
|
422
|
+
end
|
423
|
+
|
424
|
+
def test_create_failed
|
425
|
+
stub_no_remotes
|
426
|
+
stub_nonexisting_fork('tpw')
|
427
|
+
stub_request(:post, "github.com/api/v2/yaml/repos/create").
|
428
|
+
to_return(:status => [401, "Your token is fail"])
|
429
|
+
|
430
|
+
expected = "error creating repository: Your token is fail (HTTP 401)\n"
|
431
|
+
assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
|
432
|
+
end
|
433
|
+
|
434
|
+
def test_create_with_env_authentication
|
435
|
+
stub_no_remotes
|
436
|
+
stub_nonexisting_fork('mojombo')
|
437
|
+
|
438
|
+
old_user = ENV['GITHUB_USER']
|
439
|
+
old_token = ENV['GITHUB_TOKEN']
|
440
|
+
ENV['GITHUB_USER'] = 'mojombo'
|
441
|
+
ENV['GITHUB_TOKEN'] = '123abc'
|
442
|
+
|
443
|
+
stub_request(:post, "github.com/api/v2/yaml/repos/create").
|
444
|
+
with(:body => { 'login'=>'mojombo', 'token'=>'123abc', 'name' => 'hub' })
|
445
|
+
|
446
|
+
expected = "remote add -f origin git@github.com:mojombo/hub.git\n"
|
447
|
+
expected << "created repository: mojombo/hub\n"
|
448
|
+
assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
|
449
|
+
|
450
|
+
ensure
|
451
|
+
ENV['GITHUB_USER'] = old_user
|
452
|
+
ENV['GITHUB_TOKEN'] = old_token
|
453
|
+
end
|
454
|
+
|
455
|
+
def test_create_private_repository
|
456
|
+
stub_no_remotes
|
457
|
+
stub_nonexisting_fork('tpw')
|
458
|
+
stub_request(:post, "github.com/api/v2/yaml/repos/create").
|
459
|
+
with(:body => { 'login'=>'tpw', 'token'=>'abc123', 'name' => 'hub', 'public' => '0' })
|
460
|
+
|
461
|
+
expected = "remote add -f origin git@github.com:tpw/hub.git\n"
|
462
|
+
expected << "created repository: tpw/hub\n"
|
463
|
+
assert_equal expected, hub("create -p") { ENV['GIT'] = 'echo' }
|
464
|
+
end
|
465
|
+
|
466
|
+
def test_create_with_description_and_homepage
|
467
|
+
stub_no_remotes
|
468
|
+
stub_nonexisting_fork('tpw')
|
469
|
+
stub_request(:post, "github.com/api/v2/yaml/repos/create").with(:body => {
|
470
|
+
'login'=>'tpw', 'token'=>'abc123', 'name' => 'hub',
|
471
|
+
'description' => 'toyproject', 'homepage' => 'http://example.com'
|
472
|
+
})
|
473
|
+
|
474
|
+
expected = "remote add -f origin git@github.com:tpw/hub.git\n"
|
475
|
+
expected << "created repository: tpw/hub\n"
|
476
|
+
assert_equal expected, hub("create -d toyproject -h http://example.com") { ENV['GIT'] = 'echo' }
|
477
|
+
end
|
478
|
+
|
479
|
+
def test_create_with_existing_repository
|
480
|
+
stub_no_remotes
|
481
|
+
stub_existing_fork('tpw')
|
482
|
+
|
483
|
+
expected = "tpw/hub already exists on GitHub\n"
|
484
|
+
expected << "remote add -f origin git@github.com:tpw/hub.git\n"
|
485
|
+
expected << "set remote origin: tpw/hub\n"
|
486
|
+
assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
|
487
|
+
end
|
488
|
+
|
489
|
+
def test_create_no_user
|
490
|
+
stub_no_remotes
|
491
|
+
out = hub("create") do
|
492
|
+
stub_github_token(nil)
|
493
|
+
end
|
494
|
+
assert_equal "** No GitHub token set. See http://github.com/guides/local-github-config\n", out
|
495
|
+
end
|
496
|
+
|
497
|
+
def test_create_outside_git_repo
|
498
|
+
stub_no_git_repo
|
499
|
+
assert_equal "'create' must be run from inside a git repository\n", hub("create")
|
500
|
+
end
|
501
|
+
|
502
|
+
def test_create_origin_already_exists
|
503
|
+
stub_nonexisting_fork('tpw')
|
504
|
+
stub_request(:post, "github.com/api/v2/yaml/repos/create").
|
505
|
+
with(:body => { 'login'=>'tpw', 'token'=>'abc123', 'name' => 'hub' })
|
506
|
+
|
507
|
+
expected = "remote -v\ncreated repository: tpw/hub\n"
|
508
|
+
assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
|
509
|
+
end
|
510
|
+
|
511
|
+
def test_fork
|
512
|
+
stub_nonexisting_fork('tpw')
|
513
|
+
stub_request(:post, "github.com/api/v2/yaml/repos/fork/defunkt/hub").
|
514
|
+
with(:body => { 'login'=>'tpw', 'token'=>'abc123' })
|
515
|
+
|
516
|
+
expected = "remote add -f tpw git@github.com:tpw/hub.git\n"
|
517
|
+
expected << "new remote: tpw\n"
|
518
|
+
assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
|
519
|
+
end
|
520
|
+
|
521
|
+
def test_fork_failed
|
522
|
+
stub_nonexisting_fork('tpw')
|
523
|
+
stub_request(:post, "github.com/api/v2/yaml/repos/fork/defunkt/hub").
|
524
|
+
to_return(:status => [500, "Your fork is fail"])
|
525
|
+
|
526
|
+
expected = "error creating fork: Your fork is fail (HTTP 500)\n"
|
527
|
+
assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
|
528
|
+
end
|
529
|
+
|
530
|
+
def test_fork_no_remote
|
531
|
+
stub_nonexisting_fork('tpw')
|
532
|
+
stub_request(:post, "github.com/api/v2/yaml/repos/fork/defunkt/hub")
|
533
|
+
|
534
|
+
assert_equal "", hub("fork --no-remote") { ENV['GIT'] = 'echo' }
|
535
|
+
end
|
536
|
+
|
537
|
+
def test_fork_already_exists
|
538
|
+
stub_existing_fork('tpw')
|
539
|
+
|
540
|
+
expected = "tpw/hub already exists on GitHub\n"
|
541
|
+
expected << "remote add -f tpw git@github.com:tpw/hub.git\n"
|
542
|
+
expected << "new remote: tpw\n"
|
543
|
+
assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
|
544
|
+
end
|
545
|
+
|
546
|
+
def test_version
|
547
|
+
out = hub('--version')
|
548
|
+
assert_includes "git version 1.7.0.4", out
|
549
|
+
assert_includes "hub version #{Hub::Version}", out
|
550
|
+
end
|
551
|
+
|
552
|
+
def test_exec_path
|
553
|
+
out = hub('--exec-path')
|
554
|
+
assert_equal "/usr/lib/git-core\n", out
|
555
|
+
end
|
556
|
+
|
557
|
+
def test_exec_path_arg
|
558
|
+
out = hub('--exec-path=/home/wombat/share/my-l33t-git-core')
|
559
|
+
assert_equal Hub::Commands.improved_help_text, hub("")
|
560
|
+
end
|
561
|
+
|
562
|
+
def test_html_path
|
563
|
+
out = hub('--html-path')
|
564
|
+
assert_equal "/usr/share/doc/git-doc\n", out
|
565
|
+
end
|
566
|
+
|
567
|
+
def test_help
|
568
|
+
assert_equal Hub::Commands.improved_help_text, hub("help")
|
569
|
+
end
|
570
|
+
|
571
|
+
def test_help_by_default
|
572
|
+
assert_equal Hub::Commands.improved_help_text, hub("")
|
573
|
+
end
|
574
|
+
|
575
|
+
def test_help_with_pager
|
576
|
+
assert_equal Hub::Commands.improved_help_text, hub("-p")
|
577
|
+
end
|
578
|
+
|
579
|
+
def test_help_hub
|
580
|
+
help_manpage = hub("help hub")
|
581
|
+
assert_includes "git + hub = github", help_manpage
|
582
|
+
assert_includes <<-config, help_manpage
|
583
|
+
Use git-config(1) to display the currently configured GitHub username:
|
584
|
+
config
|
585
|
+
end
|
586
|
+
|
587
|
+
def test_help_hub_no_groff
|
588
|
+
stub_available_commands()
|
589
|
+
assert_equal "** Can't find groff(1)\n", hub("help hub")
|
590
|
+
end
|
591
|
+
|
592
|
+
def test_hub_standalone
|
593
|
+
help_standalone = hub("hub standalone")
|
594
|
+
assert_equal Hub::Standalone.build, help_standalone
|
595
|
+
end
|
596
|
+
|
597
|
+
def test_hub_compare
|
598
|
+
assert_command "compare refactor",
|
599
|
+
"open https://github.com/defunkt/hub/compare/refactor"
|
600
|
+
end
|
601
|
+
|
602
|
+
def test_hub_compare_nothing
|
603
|
+
expected = "Usage: hub compare [USER] [<START>...]<END>\n"
|
604
|
+
assert_equal expected, hub("compare")
|
605
|
+
end
|
606
|
+
|
607
|
+
def test_hub_compare_tracking_nothing
|
608
|
+
stub_tracking_nothing
|
609
|
+
expected = "Usage: hub compare [USER] [<START>...]<END>\n"
|
610
|
+
assert_equal expected, hub("compare")
|
611
|
+
end
|
612
|
+
|
613
|
+
def test_hub_compare_tracking_branch
|
614
|
+
stub_branch('refs/heads/feature')
|
615
|
+
|
616
|
+
assert_command "compare",
|
617
|
+
"open https://github.com/mislav/hub/compare/experimental"
|
618
|
+
end
|
619
|
+
|
620
|
+
def test_hub_compare_range
|
621
|
+
assert_command "compare 1.0...fix",
|
622
|
+
"open https://github.com/defunkt/hub/compare/1.0...fix"
|
623
|
+
end
|
624
|
+
|
625
|
+
def test_hub_compare_on_wiki
|
626
|
+
stub_repo_url 'git://github.com/defunkt/hub.wiki.git'
|
627
|
+
assert_command "compare 1.0...fix",
|
628
|
+
"open https://github.com/defunkt/hub/wiki/_compare/1.0...fix"
|
629
|
+
end
|
630
|
+
|
631
|
+
def test_hub_compare_fork
|
632
|
+
assert_command "compare myfork feature",
|
633
|
+
"open https://github.com/myfork/hub/compare/feature"
|
634
|
+
end
|
635
|
+
|
636
|
+
def test_hub_compare_url
|
637
|
+
assert_command "compare -u 1.0...1.1",
|
638
|
+
"echo https://github.com/defunkt/hub/compare/1.0...1.1"
|
639
|
+
end
|
640
|
+
|
641
|
+
def test_hub_browse
|
642
|
+
assert_command "browse mojombo/bert", "open https://github.com/mojombo/bert"
|
643
|
+
end
|
644
|
+
|
645
|
+
def test_hub_browse_tracking_nothing
|
646
|
+
stub_tracking_nothing
|
647
|
+
assert_command "browse mojombo/bert", "open https://github.com/mojombo/bert"
|
648
|
+
end
|
649
|
+
|
650
|
+
def test_hub_browse_url
|
651
|
+
assert_command "browse -u mojombo/bert", "echo https://github.com/mojombo/bert"
|
652
|
+
end
|
653
|
+
|
654
|
+
def test_hub_browse_self
|
655
|
+
assert_command "browse resque", "open https://github.com/tpw/resque"
|
656
|
+
end
|
657
|
+
|
658
|
+
def test_hub_browse_subpage
|
659
|
+
assert_command "browse resque commits",
|
660
|
+
"open https://github.com/tpw/resque/commits/master"
|
661
|
+
assert_command "browse resque issues",
|
662
|
+
"open https://github.com/tpw/resque/issues"
|
663
|
+
assert_command "browse resque wiki",
|
664
|
+
"open https://github.com/tpw/resque/wiki"
|
665
|
+
end
|
666
|
+
|
667
|
+
def test_hub_browse_on_branch
|
668
|
+
stub_branch('refs/heads/feature')
|
669
|
+
|
670
|
+
assert_command "browse resque", "open https://github.com/tpw/resque"
|
671
|
+
assert_command "browse resque commits",
|
672
|
+
"open https://github.com/tpw/resque/commits/master"
|
673
|
+
|
674
|
+
assert_command "browse",
|
675
|
+
"open https://github.com/mislav/hub/tree/experimental"
|
676
|
+
assert_command "browse -- tree",
|
677
|
+
"open https://github.com/mislav/hub/tree/experimental"
|
678
|
+
assert_command "browse -- commits",
|
679
|
+
"open https://github.com/mislav/hub/commits/experimental"
|
680
|
+
end
|
681
|
+
|
682
|
+
def test_hub_browse_current
|
683
|
+
assert_command "browse", "open https://github.com/defunkt/hub"
|
684
|
+
assert_command "browse --", "open https://github.com/defunkt/hub"
|
685
|
+
end
|
686
|
+
|
687
|
+
def test_hub_browse_current_wiki
|
688
|
+
stub_repo_url 'git://github.com/defunkt/hub.wiki.git'
|
689
|
+
|
690
|
+
assert_command "browse", "open https://github.com/defunkt/hub/wiki"
|
691
|
+
assert_command "browse -- wiki", "open https://github.com/defunkt/hub/wiki"
|
692
|
+
assert_command "browse -- commits", "open https://github.com/defunkt/hub/wiki/_history"
|
693
|
+
assert_command "browse -- pages", "open https://github.com/defunkt/hub/wiki/_pages"
|
694
|
+
end
|
695
|
+
|
696
|
+
def test_hub_browse_current_subpage
|
697
|
+
assert_command "browse -- network",
|
698
|
+
"open https://github.com/defunkt/hub/network"
|
699
|
+
assert_command "browse -- anything/everything",
|
700
|
+
"open https://github.com/defunkt/hub/anything/everything"
|
701
|
+
end
|
702
|
+
|
703
|
+
def test_hub_browse_deprecated_private
|
704
|
+
with_browser_env('echo') do
|
705
|
+
assert_includes "Warning: the `-p` flag has no effect anymore\n", hub("browse -p defunkt/hub")
|
706
|
+
end
|
707
|
+
end
|
708
|
+
|
709
|
+
def test_hub_browse_no_repo
|
710
|
+
stub_repo_url(nil)
|
711
|
+
assert_equal "Usage: hub browse [<USER>/]<REPOSITORY>\n", hub("browse")
|
712
|
+
end
|
713
|
+
|
714
|
+
def test_custom_browser
|
715
|
+
with_browser_env("custom") do
|
716
|
+
assert_browser("custom")
|
717
|
+
end
|
718
|
+
end
|
719
|
+
|
720
|
+
def test_linux_browser
|
721
|
+
stub_available_commands "open", "xdg-open", "cygstart"
|
722
|
+
with_browser_env(nil) do
|
723
|
+
with_ruby_platform("i686-linux") do
|
724
|
+
assert_browser("xdg-open")
|
725
|
+
end
|
726
|
+
end
|
727
|
+
end
|
728
|
+
|
729
|
+
def test_cygwin_browser
|
730
|
+
stub_available_commands "open", "cygstart"
|
731
|
+
with_browser_env(nil) do
|
732
|
+
with_ruby_platform("i686-linux") do
|
733
|
+
assert_browser("cygstart")
|
734
|
+
end
|
735
|
+
end
|
736
|
+
end
|
737
|
+
|
738
|
+
def test_no_browser
|
739
|
+
stub_available_commands()
|
740
|
+
expected = "Please set $BROWSER to a web launcher to use this command.\n"
|
741
|
+
with_browser_env(nil) do
|
742
|
+
with_ruby_platform("i686-linux") do
|
743
|
+
assert_equal expected, hub("browse")
|
744
|
+
end
|
745
|
+
end
|
746
|
+
end
|
747
|
+
|
748
|
+
def test_context_method_doesnt_hijack_git_command
|
749
|
+
assert_forwarded 'remotes'
|
750
|
+
end
|
751
|
+
|
752
|
+
def test_not_choking_on_ruby_methods
|
753
|
+
assert_forwarded 'id'
|
754
|
+
assert_forwarded 'name'
|
755
|
+
end
|
756
|
+
|
757
|
+
def test_multiple_remote_urls
|
758
|
+
stub_repo_url("git://example.com/other.git\ngit://github.com/my/repo.git")
|
759
|
+
assert_command "browse", "open https://github.com/my/repo"
|
760
|
+
end
|
761
|
+
|
762
|
+
protected
|
763
|
+
|
764
|
+
def stub_github_user(name)
|
765
|
+
@git['config github.user'] = name
|
766
|
+
end
|
767
|
+
|
768
|
+
def stub_github_token(token)
|
769
|
+
@git['config github.token'] = token
|
770
|
+
end
|
771
|
+
|
772
|
+
def stub_repo_url(value)
|
773
|
+
@git['config --get-all remote.origin.url'] = value
|
774
|
+
Hub::Context::REMOTES.clear
|
775
|
+
end
|
776
|
+
|
777
|
+
def stub_branch(value)
|
778
|
+
@git['symbolic-ref -q HEAD'] = value
|
779
|
+
end
|
780
|
+
|
781
|
+
def stub_tracking_nothing
|
782
|
+
@git['config branch.master.remote'] = nil
|
783
|
+
@git['config branch.master.merge'] = nil
|
784
|
+
end
|
785
|
+
|
786
|
+
def stub_remotes_group(name, value)
|
787
|
+
@git["config remotes.#{name}"] = value
|
788
|
+
end
|
789
|
+
|
790
|
+
def stub_no_remotes
|
791
|
+
@git['remote'] = ''
|
792
|
+
end
|
793
|
+
|
794
|
+
def stub_no_git_repo
|
795
|
+
@git.replace({})
|
796
|
+
end
|
797
|
+
|
798
|
+
def stub_alias(name, value)
|
799
|
+
@git["config alias.#{name}"] = value
|
800
|
+
end
|
801
|
+
|
802
|
+
def stub_existing_fork(user)
|
803
|
+
stub_fork(user, 200)
|
804
|
+
end
|
805
|
+
|
806
|
+
def stub_nonexisting_fork(user)
|
807
|
+
stub_fork(user, 404)
|
808
|
+
end
|
809
|
+
|
810
|
+
def stub_fork(user, status)
|
811
|
+
stub_request(:get, "github.com/api/v2/yaml/repos/show/#{user}/hub").
|
812
|
+
to_return(:status => status)
|
813
|
+
end
|
814
|
+
|
815
|
+
def stub_available_commands(*names)
|
816
|
+
COMMANDS.replace names
|
817
|
+
end
|
818
|
+
|
819
|
+
def with_browser_env(value)
|
820
|
+
browser, ENV['BROWSER'] = ENV['BROWSER'], value
|
821
|
+
yield
|
822
|
+
ensure
|
823
|
+
ENV['BROWSER'] = browser
|
824
|
+
end
|
825
|
+
|
826
|
+
def with_tmpdir(value)
|
827
|
+
dir, ENV['TMPDIR'] = ENV['TMPDIR'], value
|
828
|
+
yield
|
829
|
+
ensure
|
830
|
+
ENV['TMPDIR'] = dir
|
831
|
+
end
|
832
|
+
|
833
|
+
def assert_browser(browser)
|
834
|
+
assert_command "browse", "#{browser} https://github.com/defunkt/hub"
|
835
|
+
end
|
836
|
+
|
837
|
+
def with_ruby_platform(value)
|
838
|
+
platform = RUBY_PLATFORM
|
839
|
+
Object.send(:remove_const, :RUBY_PLATFORM)
|
840
|
+
Object.const_set(:RUBY_PLATFORM, value)
|
841
|
+
yield
|
842
|
+
ensure
|
843
|
+
Object.send(:remove_const, :RUBY_PLATFORM)
|
844
|
+
Object.const_set(:RUBY_PLATFORM, platform)
|
845
|
+
end
|
846
|
+
|
847
|
+
end
|