drnic-github 0.3.9

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.
@@ -0,0 +1,82 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe GitHub::Command do
4
+ before(:each) do
5
+ @command = GitHub::Command.new(proc { |x| puts x })
6
+ end
7
+
8
+ it "should return a GitHub::Helper" do
9
+ @command.helper.should be_instance_of(GitHub::Helper)
10
+ end
11
+
12
+ it "should call successfully" do
13
+ @command.should_receive(:puts).with("test").once
14
+ @command.call("test")
15
+ end
16
+
17
+ it "should return options" do
18
+ GitHub.should_receive(:options).with().once.and_return({:ssh => true})
19
+ @command.options.should == {:ssh => true}
20
+ end
21
+
22
+ it "should successfully call out to the shell" do
23
+ unguard(Kernel, :fork)
24
+ unguard(Kernel, :exec)
25
+ hi = @command.sh("echo hi")
26
+ hi.should == "hi"
27
+ hi.out.should == "hi"
28
+ hi.out?.should be(true)
29
+ hi.error.should be_nil
30
+ hi.error?.should be(false)
31
+ hi.command.should == "echo hi"
32
+ if RUBY_PLATFORM =~ /mingw|mswin/
33
+ command = "cmd /c echo bye >&2"
34
+ else
35
+ command = "echo bye >&2"
36
+ end
37
+ bye = @command.sh(command)
38
+ bye.should == "bye"
39
+ bye.out.should be_nil
40
+ bye.out?.should be(false)
41
+ bye.error.should == "bye"
42
+ bye.error?.should be(true)
43
+ bye.command.should == command
44
+ hi_and_bye = @command.sh("echo hi; echo bye >&2")
45
+ hi_and_bye.should == "hi"
46
+ hi_and_bye.out.should == "hi"
47
+ hi_and_bye.out?.should be(true)
48
+ hi_and_bye.error.should == "bye"
49
+ hi_and_bye.error?.should be(true)
50
+ hi_and_bye.command.should == "echo hi; echo bye >&2"
51
+ end
52
+
53
+ it "should return the results of a git operation" do
54
+ GitHub::Command::Shell.should_receive(:new).with("git rev-parse master").once.and_return do |*cmds|
55
+ s = mock("GitHub::Commands::Shell")
56
+ s.should_receive(:run).once.and_return("sha1")
57
+ s
58
+ end
59
+ @command.git("rev-parse master").should == "sha1"
60
+ end
61
+
62
+ it "should print the results of a git operation" do
63
+ @command.should_receive(:puts).with("sha1").once
64
+ GitHub::Command::Shell.should_receive(:new).with("git rev-parse master").once.and_return do |*cmds|
65
+ s = mock("GitHub::Commands::Shell")
66
+ s.should_receive(:run).once.and_return("sha1")
67
+ s
68
+ end
69
+ @command.pgit("rev-parse master")
70
+ end
71
+
72
+ it "should exec a git command" do
73
+ @command.should_receive(:exec).with("git rev-parse master").once
74
+ @command.git_exec "rev-parse master"
75
+ end
76
+
77
+ it "should die" do
78
+ @command.should_receive(:puts).once.with("=> message")
79
+ @command.should_receive(:exit!).once
80
+ @command.die "message"
81
+ end
82
+ end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+
3
+ describe "When calling #try" do
4
+ specify "objects should return themselves" do
5
+ obj = 1; obj.try.should equal(obj)
6
+ obj = "foo"; obj.try.should equal(obj)
7
+ obj = { :foo => "bar" }; obj.try.should equal(obj)
8
+ end
9
+
10
+ specify "objects should behave as if #try wasn't called" do
11
+ "foo".try.size.should == 3
12
+ { :foo => :bar }.try.fetch(:foo).should == :bar
13
+ [1, 2, 3].try.map { |x| x + 1 }.should == [2, 3, 4]
14
+ end
15
+
16
+ specify "nil should return the singleton NilClass::NilProxy" do
17
+ nil.try.should equal(NilClass::NilProxy)
18
+ end
19
+
20
+ specify "nil should ignore any calls made past #try" do
21
+ nil.try.size.should equal(NilClass::NilProxy)
22
+ nil.try.sdlfj.should equal(NilClass::NilProxy)
23
+ nil.try.one.two.three.should equal(NilClass::NilProxy)
24
+ end
25
+
26
+ specify "classes should respond just like objects" do
27
+ String.try.should equal(String)
28
+ end
29
+ end
30
+
31
+ describe "When calling #tap" do
32
+ specify "objects should behave like Ruby 1.9's #tap" do
33
+ obj = "foo"
34
+ obj.tap { |obj| obj.size.should == 3 }.should equal(obj)
35
+ end
36
+ end
@@ -0,0 +1,85 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "GitHub.parse_options" do
4
+ it "should parse --bare options" do
5
+ args = ["--bare", "--test"]
6
+ GitHub.parse_options(args).should == {:bare => true, :test => true}
7
+ args.should == []
8
+ end
9
+
10
+ it "should parse options intermixed with non-options" do
11
+ args = ["text", "--bare", "more text", "--option", "--foo"]
12
+ GitHub.parse_options(args).should == {:bare => true, :option => true, :foo => true}
13
+ args.should == ["text", "more text"]
14
+ end
15
+
16
+ it "should parse --foo=bar style options" do
17
+ args = ["--foo=bar", "--bare"]
18
+ GitHub.parse_options(args).should == {:bare => true, :foo => "bar"}
19
+ args.should == []
20
+ end
21
+
22
+ it "should stop parsing options at --" do
23
+ args = ["text", "--bare", "--", "--foo"]
24
+ GitHub.parse_options(args).should == {:bare => true}
25
+ args.should == ["text", "--foo"]
26
+ end
27
+
28
+ it "should handle duplicate options" do
29
+ args = ["text", "--foo=bar", "--bare", "--foo=baz"]
30
+ GitHub.parse_options(args).should == {:foo => "baz", :bare => true}
31
+ args.should == ["text"]
32
+ end
33
+
34
+ it "should handle duplicate --bare options surrounding --" do
35
+ args = ["text", "--bare", "--", "--bare"]
36
+ GitHub.parse_options(args).should == {:bare => true}
37
+ args.should == ["text", "--bare"]
38
+ end
39
+
40
+ it "should handle no options" do
41
+ args = ["text", "more text"]
42
+ GitHub.parse_options(args).should == {}
43
+ args.should == ["text", "more text"]
44
+ end
45
+
46
+ it "should handle no args" do
47
+ args = []
48
+ GitHub.parse_options(args).should == {}
49
+ args.should == []
50
+ end
51
+
52
+ it "should not set up debugging when --debug not passed" do
53
+ GitHub.stub!(:load)
54
+ GitHub.stub!(:invoke)
55
+ GitHub.activate(['default'])
56
+ GitHub.should_not be_debug
57
+ end
58
+
59
+ it "should set up debugging when passed --debug" do
60
+ GitHub.stub!(:load)
61
+ GitHub.stub!(:invoke)
62
+ GitHub.activate(['default', '--debug'])
63
+ GitHub.should be_debug
64
+ end
65
+
66
+ it "should allow for an alias on a commad" do
67
+ GitHub.command 'some-command', :aliases => 'an-alias' do
68
+ end
69
+ GitHub.commands['an-alias'].should_not be_nil
70
+ GitHub.commands['an-alias'].should_not == GitHub.commands['non-existant-command']
71
+ GitHub.commands['an-alias'].should == GitHub.commands['some-command']
72
+ end
73
+
74
+ it "should allow for an array of aliases on a commad" do
75
+ GitHub.command 'another-command', :aliases => ['some-alias-1', 'some-alias-2'] do
76
+ end
77
+ GitHub.commands['some-alias-1'].should_not be_nil
78
+ GitHub.commands['some-alias-1'].should_not == GitHub.commands['non-existant-command']
79
+ GitHub.commands['some-alias-1'].should_not be_nil
80
+ GitHub.commands['some-alias-1'].should_not == GitHub.commands['non-existant-command']
81
+ GitHub.commands['some-alias-1'].should == GitHub.commands['another-command']
82
+ GitHub.commands['some-alias-2'].should == GitHub.commands['another-command']
83
+ end
84
+
85
+ end
@@ -0,0 +1,352 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ class HelperRunner
4
+ def initialize(parent, name)
5
+ @parent = parent
6
+ @name = name
7
+ end
8
+
9
+ def run(&block)
10
+ self.instance_eval(&block)
11
+ end
12
+
13
+ def it(str, &block)
14
+ @parent.send :it, "#{@name} #{str}", &block
15
+ end
16
+ alias specify it
17
+
18
+ def before(symbol=:each, &block)
19
+ @parent.send :before, symbol, &block
20
+ end
21
+ end
22
+
23
+ describe GitHub::Helper do
24
+ include SetupMethods
25
+
26
+ def self.helper(name, &block)
27
+ HelperRunner.new(self, name).run(&block)
28
+ end
29
+
30
+ before(:each) do
31
+ @helper = GitHub::Helper.new
32
+ end
33
+
34
+ helper :print_issues_help do
35
+ it "should exist" do
36
+ @helper.should respond_to(:print_issues_help)
37
+ end
38
+ end
39
+
40
+ helper :format_issue do
41
+ before(:each) do
42
+ @issue = {}
43
+ @issue['number'] = 1234
44
+ @issue['title'] = "Isaac Asimov's Science Fiction Magazine"
45
+ @issue['votes'] = 99
46
+ end
47
+
48
+ specify "the title, number of votes and ticket number should appear" do
49
+ @helper.format_issue(@issue, {}).should =~ /Issue #1234 \(99 votes\): Isaac Asimov's Science Fiction Magazine/
50
+ end
51
+
52
+ specify "the url should appear" do
53
+ setup_url_for("origin", "hamilton", "foo")
54
+ @helper.format_issue(@issue, {:user => 'hamilton'}).should =~ /http:\/\/github.com\/hamilton\/foo\/issues\/#issue\/#{@issue['number']}/
55
+ end
56
+
57
+ specify "created_at should appear" do
58
+ @issue['created_at'] = Time.now - 3600
59
+ @issue['user'] = 'Ray Bradbury'
60
+ @helper.format_issue(@issue, {}).should =~ /Opened about 1 hour ago by Ray Bradbury/
61
+ end
62
+
63
+ specify "closed_at should appear" do
64
+ @issue['closed_at'] = Time.now - 3600
65
+ @helper.format_issue(@issue, {}).should =~ /Closed about 1 hour ago/
66
+ end
67
+
68
+ specify "updated_at should appear" do
69
+ @issue['updated_at'] = Time.now - 3600
70
+ @helper.format_issue(@issue, {}).should =~ /Last updated about 1 hour ago/
71
+ end
72
+
73
+ specify "labels should appear" do
74
+ @issue['labels'] = ['Horror','Sci-Fi','Fan Fic']
75
+ @helper.format_issue(@issue, {}).should =~ /Labels: Horror, Sci-Fi, Fan Fic/
76
+ end
77
+
78
+ specify "the body should appear" do
79
+ @issue['body'] = <<-EOF
80
+ It was the best of times,
81
+ It was the worst of times.
82
+ EOF
83
+ report = @helper.format_issue(@issue, {})
84
+ report.should =~ /It was the best of times,/
85
+ report.should =~ /It was the worst of times\./
86
+ end
87
+ end
88
+
89
+ helper :filter_issue do
90
+ specify "when the after option is present, show only issues updated on or after that date" do
91
+ issue = {'updated_at' => Time.parse('2009-01-02 12:00:00')}
92
+ @helper.filter_issue(issue, :after => '2009-01-02').should be_false
93
+ @helper.filter_issue(issue, :after => '2009-01-03').should be_true
94
+ end
95
+
96
+ specify "when a label is specified, show only issues that have that label" do
97
+ @helper.filter_issue({'labels' => nil}, :label => 'foo').should be_true
98
+ @helper.filter_issue({'labels' => []}, :label => 'foo').should be_true
99
+ @helper.filter_issue({'labels' => ['foo']}, :label => 'foo').should be_false
100
+ @helper.filter_issue({'labels' => ['quux','foo','bar']}, :label => 'foo').should be_false
101
+ end
102
+ end
103
+
104
+ helper :owner do
105
+ it "should return repo owner" do
106
+ setup_url_for "origin", "hacker"
107
+ @helper.owner.should == "hacker"
108
+ end
109
+ end
110
+
111
+ helper :private_url_for do
112
+ it "should return an ssh-style url" do
113
+ setup_url_for "origin", "user", "merb-core"
114
+ @helper.private_url_for("wycats").should == "git@github.com:wycats/merb-core.git"
115
+ end
116
+ end
117
+
118
+ helper :private_url_for_user_and_repo do
119
+ it "should return an ssh-style url" do
120
+ @helper.should_not_receive(:project)
121
+ @helper.private_url_for_user_and_repo("defunkt", "github-gem").should == "git@github.com:defunkt/github-gem.git"
122
+ end
123
+ end
124
+
125
+ helper :public_url_for do
126
+ it "should return a git:// URL" do
127
+ setup_url_for "origin", "user", "merb-core"
128
+ @helper.public_url_for("wycats").should == "git://github.com/wycats/merb-core.git"
129
+ end
130
+ end
131
+
132
+ helper :public_url_for_user_and_repo do
133
+ it "should return a git:// URL" do
134
+ @helper.should_not_receive(:project)
135
+ @helper.public_url_for_user_and_repo("defunkt", "github-gem").should == "git://github.com/defunkt/github-gem.git"
136
+ end
137
+ end
138
+
139
+ helper :project do
140
+ it "should return project-awesome" do
141
+ setup_url_for "origin", "user", "project-awesome"
142
+ @helper.project.should == "project-awesome"
143
+ end
144
+
145
+ it "should exit due to missing origin" do
146
+ @helper.should_receive(:url_for).twice.with("origin").and_return("")
147
+ @helper.should_receive(:origin).twice.and_return("origin")
148
+ STDERR.should_receive(:puts).with("Error: missing remote 'origin'")
149
+ lambda { @helper.project }.should raise_error(SystemExit)
150
+ end
151
+
152
+ it "should exit due to non-github origin" do
153
+ @helper.should_receive(:url_for).twice.with("origin").and_return("home:path/to/repo.git")
154
+ @helper.should_receive(:origin).twice.and_return("origin")
155
+ STDERR.should_receive(:puts).with("Error: remote 'origin' is not a github URL")
156
+ lambda { @helper.project }.should raise_error(SystemExit)
157
+ end
158
+ end
159
+
160
+ helper :repo_for do
161
+ it "should return mephisto.git" do
162
+ setup_url_for "mojombo", "mojombo", "mephisto"
163
+ @helper.repo_for("mojombo").should == "mephisto.git"
164
+ end
165
+ end
166
+
167
+ helper :user_and_repo_from do
168
+ it "should parse a git:// url" do
169
+ @helper.user_and_repo_from("git://github.com/defunkt/github.git").should == ["defunkt", "github.git"]
170
+ end
171
+
172
+ it "should parse a ssh-based url" do
173
+ @helper.user_and_repo_from("git@github.com:mojombo/god.git").should == ["mojombo", "god.git"]
174
+ end
175
+
176
+ it "should parse a non-standard ssh-based url" do
177
+ @helper.user_and_repo_from("ssh://git@github.com:mojombo/god.git").should == ["mojombo", "god.git"]
178
+ @helper.user_and_repo_from("github.com:mojombo/god.git").should == ["mojombo", "god.git"]
179
+ @helper.user_and_repo_from("ssh://github.com:mojombo/god.git").should == ["mojombo", "god.git"]
180
+ end
181
+
182
+ it "should return nothing for other urls" do
183
+ @helper.user_and_repo_from("home:path/to/repo.git").should == nil
184
+ end
185
+
186
+ it "should return nothing for invalid git:// urls" do
187
+ @helper.user_and_repo_from("git://github.com/foo").should == nil
188
+ end
189
+
190
+ it "should return nothing for invalid ssh-based urls" do
191
+ @helper.user_and_repo_from("git@github.com:kballard").should == nil
192
+ @helper.user_and_repo_from("git@github.com:kballard/test/repo.git").should == nil
193
+ @helper.user_and_repo_from("ssh://git@github.com:kballard").should == nil
194
+ @helper.user_and_repo_from("github.com:kballard").should == nil
195
+ @helper.user_and_repo_from("ssh://github.com:kballard").should == nil
196
+ end
197
+ end
198
+
199
+ helper :user_for do
200
+ it "should return defunkt" do
201
+ setup_url_for "origin", "defunkt"
202
+ @helper.user_for("origin").should == "defunkt"
203
+ end
204
+ end
205
+
206
+ helper :url_for do
207
+ it "should call out to the shell" do
208
+ @helper.should_receive(:`).with("git config --get remote.origin.url").and_return "git://github.com/user/project.git\n"
209
+ @helper.url_for("origin").should == "git://github.com/user/project.git"
210
+ end
211
+ end
212
+
213
+ helper :remotes do
214
+ it "should return a list of remotes" do
215
+ @helper.should_receive(:`).with('git config --get-regexp \'^remote\.(.+)\.url$\'').and_return <<-EOF
216
+ remote.origin.url git@github.com:kballard/github-gem.git
217
+ remote.defunkt.url git://github.com/defunkt/github-gem.git
218
+ remote.nex3.url git://github.com/nex3/github-gem.git
219
+ EOF
220
+ @helper.remotes.should == {
221
+ :origin => "git@github.com:kballard/github-gem.git",
222
+ :defunkt => "git://github.com/defunkt/github-gem.git",
223
+ :nex3 => "git://github.com/nex3/github-gem.git"
224
+ }
225
+ end
226
+ end
227
+
228
+ helper :remote_branches_for do
229
+ it "should return an empty list because no user was provided" do
230
+ @helper.remote_branches_for(nil).should == nil
231
+ end
232
+
233
+ it "should return a list of remote branches for defunkt" do
234
+ @helper.should_receive(:`).with('git ls-remote -h defunkt 2> /dev/null').and_return <<-EOF
235
+ fe1f852f3cf719c7cd86147031732f570ad89619 refs/heads/kballard/master
236
+ f8a6bb42b0ed43ac7336bfcda246e59a9da949d6 refs/heads/master
237
+ 624d9c2f742ff24a79353a7e02bf289235c72ff1 refs/heads/restart
238
+ EOF
239
+ @helper.remote_branches_for("defunkt").should == {
240
+ "master" => "f8a6bb42b0ed43ac7336bfcda246e59a9da949d6",
241
+ "kballard/master" => "fe1f852f3cf719c7cd86147031732f570ad89619",
242
+ "restart" => "624d9c2f742ff24a79353a7e02bf289235c72ff1"
243
+ }
244
+ end
245
+
246
+ it "should return an empty list of remote branches for nex3 and nex4" do
247
+ # the following use-case should never happen as the -h parameter should only return heads on remote branches
248
+ # however, we are testing this particular case to verify how remote_branches_for would respond if random
249
+ # git results
250
+ @helper.should_receive(:`).with('git ls-remote -h nex3 2> /dev/null').and_return <<-EOF
251
+ fe1f852f3cf719c7cd86147031732f570ad89619 HEAD
252
+ a1a392369e5b7842d01cce965272d4b96c2fd343 refs/tags/v0.1.3
253
+ 624d9c2f742ff24a79353a7e02bf289235c72ff1 refs/remotes/origin/master
254
+ random
255
+ random_again
256
+ EOF
257
+ @helper.remote_branches_for("nex3").should be_empty
258
+
259
+ @helper.should_receive(:`).with('git ls-remote -h nex4 2> /dev/null').and_return ""
260
+ @helper.remote_branches_for("nex4").should be_empty
261
+ end
262
+ end
263
+
264
+ helper :remote_branch? do
265
+ it "should return whether the branch exists at the remote user" do
266
+ @helper.should_receive(:remote_branches_for).with("defunkt").any_number_of_times.and_return({
267
+ "master" => "f8a6bb42b0ed43ac7336bfcda246e59a9da949d6",
268
+ "kballard/master" => "fe1f852f3cf719c7cd86147031732f570ad89619",
269
+ "restart" => "624d9c2f742ff24a79353a7e02bf289235c72ff1"
270
+ })
271
+ @helper.remote_branch?("defunkt", "master").should == true
272
+ @helper.remote_branch?("defunkt", "not_master").should == false
273
+ end
274
+ end
275
+
276
+ helper :branch_dirty? do
277
+ it "should return false" do
278
+ @helper.should_receive(:system).with(/^git diff/).and_return(true)
279
+ @helper.branch_dirty?.should == false
280
+ end
281
+
282
+ it "should return true" do
283
+ @helper.should_receive(:system).with(/^git diff/).and_return(false, true)
284
+ @helper.branch_dirty?.should == true
285
+ end
286
+ end
287
+
288
+ helper :tracking do
289
+ it "should return a list of remote/user_or_url pairs" do
290
+ @helper.should_receive(:remotes).and_return({
291
+ :origin => "git@github.com:kballard/github-gem.git",
292
+ :defunkt => "git://github.com/defunkt/github-gem.git",
293
+ :external => "server:path/to/github-gem.git"
294
+ })
295
+ @helper.tracking.should == {
296
+ :origin => "kballard",
297
+ :defunkt => "defunkt",
298
+ :external => "server:path/to/github-gem.git"
299
+ }
300
+ end
301
+ end
302
+
303
+ helper :tracking? do
304
+ it "should return whether the user is tracked" do
305
+ @helper.should_receive(:tracking).any_number_of_times.and_return({
306
+ :origin => "kballard",
307
+ :defunkt => "defunkt",
308
+ :external => "server:path/to/github-gem.git"
309
+ })
310
+ @helper.tracking?("kballard").should == true
311
+ @helper.tracking?("defunkt").should == true
312
+ @helper.tracking?("nex3").should == false
313
+ end
314
+ end
315
+
316
+ helper :user_and_branch do
317
+ it "should return owner and branch for unqualified branches" do
318
+ setup_url_for
319
+ @helper.should_receive(:`).with("git rev-parse --symbolic-full-name HEAD").and_return "refs/heads/master"
320
+ @helper.user_and_branch.should == ["user", "master"]
321
+ end
322
+
323
+ it "should return user and branch for user/branch-style branches" do
324
+ @helper.should_receive(:`).with("git rev-parse --symbolic-full-name HEAD").and_return "refs/heads/defunkt/wip"
325
+ @helper.user_and_branch.should == ["defunkt", "wip"]
326
+ end
327
+ end
328
+
329
+ helper :open do
330
+ it "should launch the URL when Launchy is installed" do
331
+ begin
332
+ # tricking launchy into thinking there is always a browser
333
+ ENV['LAUNCHY_BROWSER'] = dummy_browser = __FILE__
334
+ require 'launchy'
335
+
336
+ @helper.should_receive(:gem).with('launchy')
337
+ Launchy::Browser.next_instance.tap do |browser|
338
+ browser.should_receive(:run).with(dummy_browser, "http://www.google.com")
339
+ @helper.open "http://www.google.com"
340
+ end
341
+ rescue LoadError
342
+ fail "Launchy is required for this spec"
343
+ end
344
+ end
345
+
346
+ it "should fail when Launchy is not installed" do
347
+ @helper.should_receive(:gem).with('launchy').and_raise(Gem::LoadError)
348
+ STDERR.should_receive(:puts).with("Sorry, you need to install launchy: `gem install launchy`")
349
+ @helper.open "http://www.google.com"
350
+ end
351
+ end
352
+ end