ghi 0.2.0

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,29 @@
1
+ class GHI::Issue
2
+ attr_reader :number, :title, :body, :votes, :state, :user, :created_at,
3
+ :updated_at
4
+
5
+ def initialize(options = {})
6
+ @number = options["number"]
7
+ @title = options["title"]
8
+ @body = options["body"]
9
+ @votes = options["votes"]
10
+ @state = options["state"]
11
+ @user = options["user"]
12
+ @created_at = options["created_at"]
13
+ @updated_at = options["updated_at"]
14
+ end
15
+
16
+ #-
17
+ # REFACTOR: This code is duplicated from cli.rb:gets_from_editor.
18
+ #+
19
+ def ==(other_issue)
20
+ case other_issue
21
+ when Array
22
+ other_title = other_issue.first.strip
23
+ other_body = other_issue[1..-1].join.sub(/\b\n\b/, " ").strip
24
+ title == other_title && body == other_body
25
+ else
26
+ super other_issue
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,194 @@
1
+ require "ghi"
2
+ require "ghi/api"
3
+ require "ghi/issue"
4
+
5
+ ISSUES_YAML = <<-YAML
6
+ ---
7
+ issues:
8
+ - number: 1
9
+ votes: 0
10
+ created_at: 2009-04-17 14:55:33 -07:00
11
+ body: my sweet, sweet issue
12
+ title: new issue
13
+ updated_at: 2009-04-17 14:55:33 -07:00
14
+ user: schacon
15
+ state: open
16
+ - number: 2
17
+ votes: 0
18
+ created_at: 2009-04-17 15:16:47 -07:00
19
+ body: the body of a second issue
20
+ title: another issue
21
+ updated_at: 2009-04-17 15:16:47 -07:00
22
+ user: schacon
23
+ state: open
24
+ YAML
25
+
26
+ ISSUE_YAML = <<-YAML
27
+ ---
28
+ issue:
29
+ number: 1
30
+ votes: 0
31
+ created_at: 2009-04-17 14:55:33 -07:00
32
+ body: my sweet, sweet issue
33
+ title: new issue
34
+ updated_at: 2009-04-17 14:55:33 -07:00
35
+ user: schacon
36
+ state: open
37
+ YAML
38
+
39
+ LABELS_YAML = <<-YAML
40
+ ---
41
+ labels:
42
+ - testing
43
+ - test_label
44
+ YAML
45
+
46
+ COMMENT_YAML = <<-YAML
47
+ ---
48
+ comment:
49
+ comment: this is amazing
50
+ status: saved
51
+ YAML
52
+
53
+ describe GHI::API do
54
+ it "should require user and repo" do
55
+ proc { GHI::API.new(nil, nil) }.should raise_error(GHI::API::InvalidConnection)
56
+ proc { GHI::API.new("u", nil) }.should raise_error(GHI::API::InvalidConnection)
57
+ proc { GHI::API.new(nil, "r") }.should raise_error(GHI::API::InvalidConnection)
58
+ proc { GHI::API.new("u", "r") }.should_not raise_error(GHI::API::InvalidConnection)
59
+ end
60
+
61
+ describe "requests" do
62
+ before :all do
63
+ @api = GHI::API.new "stephencelis", "ghi"
64
+ GHI.stub!(:login).and_return "stephencelis"
65
+ GHI.stub!(:token).and_return "token"
66
+ end
67
+
68
+ it "should substitute url tokens" do
69
+ @api.send(:url, :open).should ==
70
+ "http://github.com/api/v2/yaml/issues/open/stephencelis/ghi"
71
+ @api.send(:url, :show, 1).should ==
72
+ "http://github.com/api/v2/yaml/issues/show/stephencelis/ghi/1"
73
+ @api.send(:url, :search, :open, "me").should ==
74
+ "http://github.com/api/v2/yaml/issues/search/stephencelis/ghi/open/me"
75
+ @api.send(:url, "label/add", "me").should ==
76
+ "http://github.com/api/v2/yaml/issues/label/add/stephencelis/ghi/me"
77
+ end
78
+
79
+ it "should process gets" do
80
+ url = "http://github.com/api/v2/yaml/issues/open/stephencelis/ghi"
81
+ query = "?login=stephencelis&token=d1cd249db48d51c9847cbf2b291f5ae9"
82
+ @api.stub!(:url).and_return url
83
+ URI.should_receive(:parse).once.with(url + query).and_return("mock")
84
+ Net::HTTP.should_receive(:get).once.with("mock").and_return ISSUES_YAML
85
+ @api.list
86
+ end
87
+
88
+ it "should process posts" do
89
+ url = "http://github.com/api/v2/yaml/issues/open/stephencelis/ghi"
90
+ query = { :login => "stephencelis",
91
+ :token => "d1cd249db48d51c9847cbf2b291f5ae9",
92
+ :title => "Title",
93
+ :body => "Body" }
94
+ @api.stub!(:url).and_return url
95
+ r = mock(Net::HTTPRequest)
96
+ r.should_receive(:body).once.and_return ISSUE_YAML
97
+ URI.should_receive(:parse).once.with(url).and_return "u"
98
+ Net::HTTP.should_receive(:post_form).once.with("u", query).and_return r
99
+ @api.open "Title", "Body"
100
+ end
101
+
102
+ it "should search open by default" do
103
+ @api.should_receive(:url).with(:search, :open, "me").and_return "u"
104
+ Net::HTTP.stub!(:get).and_return ISSUES_YAML
105
+ issues = @api.search "me"
106
+ issues.should be_an_instance_of(Array)
107
+ issues.each { |issue| issue.should be_an_instance_of(GHI::Issue) }
108
+ end
109
+
110
+ it "should search closed" do
111
+ @api.should_receive(:url).with(:search, :closed, "me").and_return "u"
112
+ Net::HTTP.stub!(:get).and_return ISSUES_YAML
113
+ @api.search "me", :closed
114
+ end
115
+
116
+ it "should list open by default" do
117
+ @api.should_receive(:url).with(:list, :open).and_return "u"
118
+ Net::HTTP.stub!(:get).and_return ISSUES_YAML
119
+ issues = @api.list
120
+ issues.should be_an_instance_of(Array)
121
+ issues.each { |issue| issue.should be_an_instance_of(GHI::Issue) }
122
+ end
123
+
124
+ it "should list closed" do
125
+ @api.should_receive(:url).with(:list, :closed).and_return "u"
126
+ Net::HTTP.stub!(:get).and_return ISSUES_YAML
127
+ @api.list :closed
128
+ end
129
+
130
+ it "should show" do
131
+ @api.should_receive(:url).with(:show, 1).and_return "u"
132
+ Net::HTTP.stub!(:get).and_return ISSUE_YAML
133
+ @api.show(1).should be_an_instance_of(GHI::Issue)
134
+ end
135
+
136
+ it "should open" do
137
+ @api.should_receive(:url).with(:open).and_return "u"
138
+ response = mock(Net::HTTPRequest)
139
+ response.stub!(:body).and_return ISSUE_YAML
140
+ Net::HTTP.stub!(:post_form).and_return response
141
+ @api.open("Title", "Body").should be_an_instance_of(GHI::Issue)
142
+ end
143
+
144
+ it "should edit" do
145
+ @api.should_receive(:url).with(:edit, 1).and_return "u"
146
+ response = mock(Net::HTTPRequest)
147
+ response.stub!(:body).and_return ISSUE_YAML
148
+ Net::HTTP.stub!(:post_form).and_return response
149
+ @api.edit(1, "Title", "Body").should be_an_instance_of(GHI::Issue)
150
+ end
151
+
152
+ it "should close" do
153
+ @api.should_receive(:url).with(:close, 1).and_return "u"
154
+ response = mock(Net::HTTPRequest)
155
+ response.stub!(:body).and_return ISSUE_YAML
156
+ Net::HTTP.stub!(:post_form).and_return response
157
+ @api.close(1).should be_an_instance_of(GHI::Issue)
158
+ end
159
+
160
+ it "should reopen" do
161
+ @api.should_receive(:url).with(:reopen, 1).and_return "u"
162
+ response = mock(Net::HTTPRequest)
163
+ response.stub!(:body).and_return ISSUE_YAML
164
+ Net::HTTP.stub!(:post_form).and_return response
165
+ @api.reopen(1).should be_an_instance_of(GHI::Issue)
166
+ end
167
+
168
+ it "should add labels" do
169
+ @api.should_receive(:url).with("label/add", 1, "l").and_return "u"
170
+ response = mock(Net::HTTPRequest)
171
+ response.stub!(:body).and_return LABELS_YAML
172
+ Net::HTTP.stub!(:post_form).and_return response
173
+ @api.add_label(1, "l").should be_an_instance_of(Array)
174
+ end
175
+
176
+ it "should remove labels" do
177
+ @api.should_receive(:url).with("label/remove", 1, "l").and_return "u"
178
+ response = mock(Net::HTTPRequest)
179
+ response.stub!(:body).and_return LABELS_YAML
180
+ Net::HTTP.stub!(:post_form).and_return response
181
+ @api.remove_label(1, "l").should be_an_instance_of(Array)
182
+ end
183
+
184
+ it "should comment" do
185
+ @api.should_receive(:url).with(:comment, 1).and_return "u"
186
+ URI.stub!(:parse).and_return "u"
187
+ response = mock(Net::HTTPRequest)
188
+ response.stub!(:body).and_return COMMENT_YAML
189
+ Net::HTTP.should_receive(:post_form).with("u",
190
+ hash_including(:comment => "Comment")).and_return response
191
+ @api.comment(1, "Comment").should be_an_instance_of(Hash)
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,258 @@
1
+ require "ghi"
2
+ require "ghi/api"
3
+ require "ghi/cli"
4
+
5
+ describe GHI::CLI::Executable do
6
+ before :each do
7
+ @cli = GHI::CLI::Executable.new
8
+ @cli.stub!(:api).and_return(mock(GHI::API))
9
+ $stdout.stub! :close_write
10
+ IO.stub!(:popen).and_return $stdout
11
+ end
12
+
13
+ describe "parsing" do
14
+ describe "with well-formed arguments" do
15
+ before :each do
16
+ @user, @repo = "localuser", "ghi"
17
+ @action = @state = @number = @term =
18
+ @title = @body = @tag = @comment = nil
19
+ end
20
+
21
+ after :each do
22
+ @cli.should_receive(@action)
23
+ @cli.parse! @args
24
+ @cli.action.should == @action
25
+ @cli.state.should == (@state || :open)
26
+ @cli.number.should == @number
27
+ @cli.search_term.should == @term
28
+ @cli.title.should == @title
29
+ @cli.body.should == @body
30
+ @cli.user.should == @user
31
+ @cli.repo.should == @repo
32
+ @cli.tag.should == @tag
33
+ if @commenting
34
+ @cli.should be_commenting
35
+ else
36
+ @cli.should_not be_commenting
37
+ end
38
+ end
39
+
40
+ it "should always parse -r" do
41
+ @args = ["-rremoteuser/remoterepo", "-l"]
42
+ @action, @state, @user, @repo = :list, :open, "remoteuser", "remoterepo"
43
+ end
44
+
45
+ describe "inside a repository" do
46
+ after :each do
47
+ @cli.stub!(:`).and_return "stub@github.com:localuser/ghi.git"
48
+ end
49
+
50
+ it "should parse -l as list open" do
51
+ @args = ["-l"]
52
+ @action, @state = :list, :open
53
+ end
54
+
55
+ it "should parse -lo as list open" do
56
+ @args = ["-lo"]
57
+ @action, @state = :list, :open
58
+ end
59
+
60
+ it "should parse -lc as list closed" do
61
+ @args = ["-lc"]
62
+ @action, @state = :list, :closed
63
+ end
64
+
65
+ it "should parse -l2 as show issue 2" do
66
+ @args = ["-l2"]
67
+ @action, @number = :show, 2
68
+ end
69
+
70
+ it "should parse -l 'term' as search open for 'term'" do
71
+ @args = ["-l", "term"]
72
+ @action, @state, @term = :search, :open, "term"
73
+ end
74
+
75
+ it "should parse -o as open new issue" do
76
+ @args = ["-o"]
77
+ @action = :open
78
+ end
79
+
80
+ it "should parse -o 'New Issue' as open issue with title 'New Issue'" do
81
+ @args = ["-o", "New Issue"]
82
+ @action, @title = :open, "New Issue"
83
+ end
84
+
85
+ it "should parse -om 'New Issue' as open issue with'New Issue'" do
86
+ @args = ["-om", "New Issue"]
87
+ @action, @title = :open, "New Issue"
88
+ end
89
+
90
+ it "should parse -o 'New Issue' -m as open 'New Issue' in $EDITOR" do
91
+ @args = ["-o", "New Issue", "-m"]
92
+ @action, @title, @commenting = :open, "New Issue", true
93
+ end
94
+
95
+ it "should parse -o 'Issue' -m 'Body' as open 'Issue' with 'Body'" do
96
+ @args = ["-o", "Issue", "-m", "Body"]
97
+ @action, @title, @body = :open, "Issue", "Body"
98
+ end
99
+
100
+ it "should parse -o2 as reopen issue 2" do
101
+ @args = ["-o2"]
102
+ @action, @number = :reopen, 2
103
+ end
104
+
105
+ it "should parse -o2 -m as reopen issue 2 with a comment" do
106
+ @args = ["-o2", "-m"]
107
+ @action, @number, @commenting = :reopen, 2, true
108
+ end
109
+
110
+ it "should parse -o2 -m 'Comment' as reopen issue 2" do
111
+ @args = ["-o2", "-m", "Comment"]
112
+ @action, @number, @body = :reopen, 2, "Comment"
113
+ end
114
+
115
+ it "should parse -ol as list open" do
116
+ @args = ["-ol"]
117
+ @action, @state = :list, :open
118
+ end
119
+
120
+ it "should parse -ou as return open issues url" do
121
+ @args = ["-ou"]
122
+ @action = :url # Should state be :open?
123
+ end
124
+
125
+ it "should parse -cl as list closed" do
126
+ @args = ["-cl"]
127
+ @action, @state = :list, :closed
128
+ end
129
+
130
+ it "should parse -c2 as close issue 2" do
131
+ @args = ["-c2"]
132
+ @action, @number = :close, 2
133
+ end
134
+
135
+ it "should parse -c2 -m as close issue 2 with a comment" do
136
+ @args = ["-c2", "-m"]
137
+ @action, @number, @commenting = :close, 2, true
138
+ end
139
+
140
+ it "should parse -c2 -m 'Fixed' as close issue 2 with 'Fixed'" do
141
+ @args = ["-c2", "-m", "Fixed"]
142
+ @action, @number, @body = :close, 2, "Fixed"
143
+ end
144
+
145
+ it "should parse -m2 -c as close issue 2 with a comment" do
146
+ @args = ["-m2", "-c"]
147
+ @action, @number, @commenting = :close, 2, true
148
+ end
149
+
150
+ it "should parse -cu as return closed issues url" do
151
+ @args = ["-cu"]
152
+ @action, @state = :url, :closed
153
+ end
154
+
155
+ it "should parse -e2 as edit issue 2" do
156
+ @args = ["-e2"]
157
+ @action, @number = :edit, 2
158
+ end
159
+
160
+ it "should parse -rlocalrepo as localuser/localrepo" do
161
+ GHI.stub!(:login).and_return "localuser"
162
+ @args = ["-rlocalrepo", "-l"]
163
+ @action, @state, @user, @repo = :list, :open, "localuser", "localrepo"
164
+ end
165
+
166
+ it "should parse -rremoteuser/remoterepo as remoteuser/remoterepo" do
167
+ @args = ["-rremoteuser/remoterepo", "-l"]
168
+ @action, @state, @user, @repo = :list, :open, "remoteuser", "remoterepo"
169
+ end
170
+
171
+ it "should parse -rremoteuser/remoterepo as a later argument" do
172
+ @args = ["-1", "-rremoteuser/remoterepo"]
173
+ @action, @number, @user, @repo = :show, 1, "remoteuser", "remoterepo"
174
+ end
175
+
176
+ it "should parse -t2 'tag' as label issue 2 with 'tag'" do
177
+ @args = ["-t2", "tag"]
178
+ @action, @number, @tag = :label, 2, "tag"
179
+ end
180
+
181
+ it "should parse -d2 'tag' as remove label 'tag' from issue 2" do
182
+ @args = ["-d2", "tag"]
183
+ @action, @number, @tag = :unlabel, 2, "tag"
184
+ end
185
+
186
+ it "should parse -m2 as comment on issue 2" do
187
+ @args = ["-m2"]
188
+ @action, @number, @commenting = :comment, 2, true
189
+ end
190
+
191
+ it "should parse -m2 'Comment' as comment 'Comment' on issue 2" do
192
+ @args = ["-m2", "Comment"]
193
+ @action, @number, @body = :comment, 2, "Comment"
194
+ end
195
+
196
+ it "should parse -u as return open issues url" do
197
+ @args = ["-u"]
198
+ @action = :url # Should state be :open?
199
+ end
200
+
201
+ it "should parse -uo as return open issues url" do
202
+ @args = ["-uo"]
203
+ @action = :url # Should state be :open?
204
+ end
205
+
206
+ it "should parse -uc as return open issues url" do
207
+ @args = ["-uc"]
208
+ @action, @state = :url, :closed
209
+ end
210
+
211
+ it "should parse -u2 as return issue 2 url" do
212
+ @args = ["-u2"]
213
+ @action, @number = :url, 2
214
+ end
215
+
216
+ it "should parse -uu as return unread issues url" do
217
+ @args = ["-uu"]
218
+ @action, @state = :url, :unread
219
+ end
220
+ end
221
+ end
222
+
223
+ describe "with malformed arguments" do
224
+ before :each do
225
+ @cli.should_receive :warn
226
+ @cli.should_receive(:exit).with 1
227
+ end
228
+
229
+ it "should exit with -e" do
230
+ @cli.should_receive :puts
231
+ @cli.parse! ["-e"]
232
+ end
233
+
234
+ it "should exit with -e 'invalid'" do
235
+ @cli.should_receive :puts
236
+ @cli.parse! ["-e", "invalid"]
237
+ end
238
+
239
+ it "should exit with -c as list closed" do
240
+ @cli.parse! ["-c"]
241
+ end
242
+
243
+ it "should exit with -r" do
244
+ @cli.should_receive :puts
245
+ @cli.parse! ["-r"]
246
+ end
247
+
248
+ it "should exit with -t" do
249
+ @cli.should_receive :puts
250
+ @cli.parse! ["-t"]
251
+ end
252
+
253
+ it "should exit with -t2" do
254
+ @cli.parse! ["-t2"]
255
+ end
256
+ end
257
+ end
258
+ end