fcoury-octopi 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +51 -1
- data/VERSION.yml +2 -2
- data/lib/octopi.rb +82 -26
- data/lib/octopi/base.rb +39 -2
- data/lib/octopi/blob.rb +2 -1
- data/lib/octopi/commit.rb +3 -1
- data/lib/octopi/error.rb +15 -0
- data/lib/octopi/file_object.rb +2 -1
- data/lib/octopi/issue.rb +58 -9
- data/lib/octopi/repository.rb +15 -1
- data/lib/octopi/resource.rb +1 -1
- data/lib/octopi/tag.rb +2 -1
- data/lib/octopi/user.rb +12 -1
- data/test/octopi_test.rb +41 -2
- metadata +4 -3
data/README.rdoc
CHANGED
@@ -2,7 +2,53 @@
|
|
2
2
|
|
3
3
|
Octopi is a Ruby interface to GitHub API v2 (http://develop.github.com). It's under early but active development and already works.
|
4
4
|
|
5
|
-
==
|
5
|
+
== Authenticated Usage
|
6
|
+
|
7
|
+
The following examples requires a valid user authenticated with GitHub using login and API token. This information can be found on our profile (the link is inside the "badge" that is displayed on the upper right corner when you're logged in).
|
8
|
+
|
9
|
+
Once you found your login and token you can run authenticated commands using:
|
10
|
+
|
11
|
+
authenticated_with "mylogin", "mytoken" do |g|
|
12
|
+
repo = g.repository("api-labrat")
|
13
|
+
issue = repo.open_issue :title => "Sample issue",
|
14
|
+
:body => "This issue was opened using GitHub API and Octopi"
|
15
|
+
puts issue.number
|
16
|
+
end
|
17
|
+
|
18
|
+
You can also create a YAML file with your information, with the following format:
|
19
|
+
|
20
|
+
#
|
21
|
+
# Octopi GitHub API configuration file
|
22
|
+
#
|
23
|
+
|
24
|
+
# GitHub user login and token
|
25
|
+
login: github-username
|
26
|
+
token: github-token
|
27
|
+
|
28
|
+
# Trace level
|
29
|
+
# Possible values:
|
30
|
+
# false - no tracing, same as if the param is ommited
|
31
|
+
# true - will output each POST or GET operation to the stdout
|
32
|
+
# curl - same as true, but in addition will output the curl equivalent of each command (for debugging)
|
33
|
+
trace: curl
|
34
|
+
|
35
|
+
And change the way you connect to:
|
36
|
+
|
37
|
+
authenticated_with :config => "github.yml" do |g|
|
38
|
+
(...)
|
39
|
+
end
|
40
|
+
|
41
|
+
This way you can benefit from better debugging when something goes wrong. If you choose curl tracing, the curl command equivalent to each command sent to GitHub will be output to the stdout, like this example:
|
42
|
+
|
43
|
+
=> Trace on: curl
|
44
|
+
POST: /issues/open/webbynode/api-labrat params: body=This issue was opened using GitHub API and Octopi, title=Sample issue
|
45
|
+
===== curl version
|
46
|
+
curl -F 'body=This issue was opened using GitHub API and Octopi' -F 'login=mylogin' -F 'token=mytoken' -F 'title=Sample issue' http://github.com/api/v2/issues/open/webbynode/api-labrat
|
47
|
+
==================
|
48
|
+
|
49
|
+
== Anonymous Usage
|
50
|
+
|
51
|
+
This reflects the usage of the API to retrieve information, on a read-only mode where the user doesn't have to be authenticated.
|
6
52
|
|
7
53
|
=== Users API
|
8
54
|
|
@@ -44,6 +90,10 @@ Issues API integrated into the Repository object:
|
|
44
90
|
issue = repo.issues.first
|
45
91
|
puts "First open issue: #{issue.number} - #{issue.title} - Created at: #{issue.created_at}"
|
46
92
|
|
93
|
+
Single issue information:
|
94
|
+
|
95
|
+
issue = repo.issue(11)
|
96
|
+
|
47
97
|
Commits API information from a Repository object:
|
48
98
|
|
49
99
|
first_commit = repo.commits.first
|
data/VERSION.yml
CHANGED
data/lib/octopi.rb
CHANGED
@@ -1,13 +1,30 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'httparty'
|
3
|
+
require 'yaml'
|
3
4
|
require 'pp'
|
4
5
|
|
5
6
|
module Octopi
|
6
7
|
class Api; end
|
7
8
|
ANONYMOUS_API = Api.new
|
8
9
|
|
9
|
-
def
|
10
|
-
|
10
|
+
def authenticated_with(*args, &block)
|
11
|
+
opts = args.last.is_a?(Hash) ? args.last : {}
|
12
|
+
if opts[:config]
|
13
|
+
config = File.open(opts[:config]) { |yf| YAML::load(yf) }
|
14
|
+
raise "Missing config #{opts[:config]}" unless config
|
15
|
+
|
16
|
+
login = config["login"]
|
17
|
+
token = config["token"]
|
18
|
+
trace = config["trace"]
|
19
|
+
else
|
20
|
+
login, token = *args
|
21
|
+
end
|
22
|
+
|
23
|
+
puts "=> Trace on: #{trace}" if trace
|
24
|
+
|
25
|
+
api = Api.new(login, token)
|
26
|
+
api.trace = trace if trace
|
27
|
+
yield api
|
11
28
|
end
|
12
29
|
|
13
30
|
class Api
|
@@ -19,11 +36,17 @@ module Octopi
|
|
19
36
|
}
|
20
37
|
base_uri "http://github.com/api/v2"
|
21
38
|
|
22
|
-
attr_accessor :format
|
39
|
+
attr_accessor :format, :login, :token, :trace, :read_only
|
23
40
|
|
24
|
-
def initialize(login = nil, token = nil, format = "
|
25
|
-
self.class.default_params(:login => login, :token => token) if login
|
41
|
+
def initialize(login = nil, token = nil, format = "yaml")
|
26
42
|
@format = format
|
43
|
+
@read_only = true
|
44
|
+
|
45
|
+
if login
|
46
|
+
@login = login
|
47
|
+
@token = token
|
48
|
+
@read_only = false
|
49
|
+
end
|
27
50
|
end
|
28
51
|
|
29
52
|
%w[keys emails].each do |action|
|
@@ -33,11 +56,22 @@ module Octopi
|
|
33
56
|
end
|
34
57
|
|
35
58
|
def user
|
36
|
-
user_data = get("/user/show/#{
|
59
|
+
user_data = get("/user/show/#{login}")
|
37
60
|
raise "Unexpected response for user command" unless user_data and user_data['user']
|
38
61
|
User.new(self, user_data['user'])
|
39
62
|
end
|
40
63
|
|
64
|
+
def open_issue(user, repo, params)
|
65
|
+
Issue.open(user, repo, params, self)
|
66
|
+
end
|
67
|
+
|
68
|
+
def repository(name)
|
69
|
+
repo = Repository.find(login, name)
|
70
|
+
repo.api = self
|
71
|
+
repo
|
72
|
+
end
|
73
|
+
alias_method :repo, :repository
|
74
|
+
|
41
75
|
def save(resource_path, data)
|
42
76
|
traslate resource_path, data
|
43
77
|
#still can't figure out on what format values are expected
|
@@ -55,39 +89,61 @@ module Octopi
|
|
55
89
|
def get_raw(path, params)
|
56
90
|
get(path, params, 'plain')
|
57
91
|
end
|
92
|
+
|
93
|
+
def post(path, params = {}, format = "yaml")
|
94
|
+
trace "POST", path, params
|
95
|
+
submit(path, params, format) do |path, params, format|
|
96
|
+
resp = self.class.post "/#{format}#{path}", :query => params
|
97
|
+
resp
|
98
|
+
end
|
99
|
+
end
|
58
100
|
|
59
101
|
private
|
60
|
-
def
|
61
|
-
params.each_pair
|
62
|
-
|
102
|
+
def submit(path, params = {}, format = "yaml", &block)
|
103
|
+
params.each_pair { |k,v| path = path.gsub(":#{k.to_s}", v) }
|
104
|
+
query = login ? { :login => login, :token => token } : {}
|
105
|
+
query.merge!(params)
|
106
|
+
|
107
|
+
if @trace
|
108
|
+
case @trace
|
109
|
+
when "curl"
|
110
|
+
query_trace = []
|
111
|
+
query.each_pair { |k,v| query_trace << "-F '#{k}=#{v}'" }
|
112
|
+
puts "===== [curl version]"
|
113
|
+
puts "curl #{query_trace.join(" ")} #{self.class.base_uri}#{path}"
|
114
|
+
puts "==================="
|
115
|
+
end
|
63
116
|
end
|
64
|
-
|
117
|
+
|
118
|
+
resp = yield(path, query, format)
|
119
|
+
raise APIError,
|
120
|
+
"GitHub returned status #{resp.code}" unless resp.code.to_i == 200
|
65
121
|
# FIXME: This fails for showing raw Git data because that call returns
|
66
122
|
# text/html as the content type. This issue has been reported.
|
67
123
|
ctype = resp.headers['content-type'].first
|
68
124
|
raise FormatError, [ctype, format] unless
|
69
125
|
ctype.match(/^#{CONTENT_TYPE[format]};/)
|
70
|
-
raise APIError,
|
71
|
-
"GitHub returned status #{resp.code}" unless resp.code.to_i == 200
|
72
126
|
if format == 'yaml' && resp['error']
|
73
127
|
raise APIError, resp['error'].first['error']
|
74
128
|
end
|
75
129
|
resp
|
76
130
|
end
|
131
|
+
|
132
|
+
def get(path, params = {}, format = "yaml")
|
133
|
+
trace "GET", path, params
|
134
|
+
submit(path, params, format) do |path, params, format|
|
135
|
+
self.class.get "/#{format}#{path}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def trace(oper, url, params)
|
140
|
+
return unless @trace
|
141
|
+
par_str = " params: " + params.map { |p| "#{p[0]}=#{p[1]}" }.join(", ") if params and !params.empty?
|
142
|
+
puts "#{oper}: #{url}#{par_str}"
|
143
|
+
end
|
77
144
|
end
|
78
|
-
|
79
|
-
%w{base resource user tag repository issue file_object blob commit}.
|
80
|
-
each{|f| require "#{File.dirname(__FILE__)}/octopi/#{f}"}
|
81
145
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
class APIError < StandardError
|
89
|
-
def initialize(m)
|
90
|
-
$stderr.puts m
|
91
|
-
end
|
92
|
-
end
|
146
|
+
%w{error base resource user tag repository issue file_object blob commit}.
|
147
|
+
each{|f| require "#{File.dirname(__FILE__)}/octopi/#{f}"}
|
148
|
+
|
93
149
|
end
|
data/lib/octopi/base.rb
CHANGED
@@ -1,5 +1,29 @@
|
|
1
|
+
class String
|
2
|
+
def camel_case
|
3
|
+
self.gsub(/(^|_)(.)/) { $2.upcase }
|
4
|
+
end
|
5
|
+
end
|
1
6
|
module Octopi
|
2
7
|
class Base
|
8
|
+
VALID = {
|
9
|
+
:repo => {
|
10
|
+
# FIXME: API currently chokes on repository names containing periods,
|
11
|
+
# but presumably this will be fixed.
|
12
|
+
:pat => /^[a-z0-9_\.-]+$/,
|
13
|
+
:msg => "%s is an invalid repository name"},
|
14
|
+
:user => {
|
15
|
+
:pat => /^[A-Za-z0-9_\.-]+$/,
|
16
|
+
:msg => "%s is an invalid username"},
|
17
|
+
:file => {
|
18
|
+
:pat => /^[^ \/]+$/,
|
19
|
+
:msg => "%s is an invalid filename"},
|
20
|
+
:sha => {
|
21
|
+
:pat => /^[a-f0-9]{40}$/,
|
22
|
+
:msg => "%s is an invalid SHA hash"}
|
23
|
+
}
|
24
|
+
|
25
|
+
attr_accessor :api
|
26
|
+
|
3
27
|
def initialize(api, hash)
|
4
28
|
@api = api
|
5
29
|
@keys = []
|
@@ -36,7 +60,8 @@ module Octopi
|
|
36
60
|
def self.extract_user_repository(*args)
|
37
61
|
opts = args.last.is_a?(Hash) ? args.pop : {}
|
38
62
|
if opts.empty?
|
39
|
-
user, repo = *args
|
63
|
+
user, repo = *args if args.length > 1
|
64
|
+
repo ||= args.first
|
40
65
|
else
|
41
66
|
opts[:repo] = opts[:repository] if opts[:repository]
|
42
67
|
repo = args.pop || opts[:repo]
|
@@ -61,5 +86,17 @@ module Octopi
|
|
61
86
|
v
|
62
87
|
end
|
63
88
|
end
|
89
|
+
|
90
|
+
def self.validate_args(spec)
|
91
|
+
m = caller[0].match(/\/([a-z0-9_]+)\.rb:\d+:in `([a-z_0-9]+)'/)
|
92
|
+
meth = m ? "#{m[1].camel_case}.#{m[2]}" : 'method'
|
93
|
+
raise ArgumentError, "Invalid spec" unless
|
94
|
+
spec.values.all? { |s| VALID.key? s }
|
95
|
+
errors = spec.reject{|arg, spec| arg.nil?}.
|
96
|
+
reject{|arg, spec| arg.to_s.match(VALID[spec][:pat])}.
|
97
|
+
map {|arg, spec| "Invalid argument '%s' for %s (%s)" %
|
98
|
+
[arg, meth, VALID[spec][:msg] % arg]}
|
99
|
+
raise ArgumentError, "\n" + errors.join("\n") unless errors.empty?
|
100
|
+
end
|
64
101
|
end
|
65
|
-
end
|
102
|
+
end
|
data/lib/octopi/blob.rb
CHANGED
@@ -8,6 +8,7 @@ module Octopi
|
|
8
8
|
def self.find(user, repo, sha, path=nil)
|
9
9
|
user = user.login if user.is_a? User
|
10
10
|
repo = repo.name if repo.is_a? Repository
|
11
|
+
self.class.validate_args(sha => :sha, user => :user, path => :file)
|
11
12
|
if path
|
12
13
|
super [user,repo,sha,path]
|
13
14
|
else
|
@@ -17,4 +18,4 @@ module Octopi
|
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
20
|
-
end
|
21
|
+
end
|
data/lib/octopi/commit.rb
CHANGED
@@ -24,6 +24,7 @@ module Octopi
|
|
24
24
|
repo = args.first
|
25
25
|
user ||= repo.owner if repo.is_a? Repository
|
26
26
|
user, repo_name, opts = extract_user_repository(*args)
|
27
|
+
self.validate_args(user => :user, repo_name => :repo)
|
27
28
|
branch = opts[:branch] || "master"
|
28
29
|
|
29
30
|
commits = super user, repo_name, branch
|
@@ -40,6 +41,7 @@ module Octopi
|
|
40
41
|
user, name, sha = *args
|
41
42
|
user = user.login if user.is_a? User
|
42
43
|
name = repo.name if name.is_a? Repository
|
44
|
+
self.validate_args(user => :user, name => :repo, sha => :sha)
|
43
45
|
super [user, name, sha]
|
44
46
|
end
|
45
47
|
end
|
@@ -59,4 +61,4 @@ module Octopi
|
|
59
61
|
parts.join('/')
|
60
62
|
end
|
61
63
|
end
|
62
|
-
end
|
64
|
+
end
|
data/lib/octopi/error.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Octopi
|
2
|
+
|
3
|
+
class FormatError < StandardError
|
4
|
+
def initialize(f)
|
5
|
+
$stderr.puts "Got unexpected format (got #{f.first} for #{f.last})"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class APIError < StandardError
|
10
|
+
def initialize(m)
|
11
|
+
$stderr.puts m
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/lib/octopi/file_object.rb
CHANGED
data/lib/octopi/issue.rb
CHANGED
@@ -3,7 +3,7 @@ module Octopi
|
|
3
3
|
include Resource
|
4
4
|
|
5
5
|
find_path "/issues/list/:query"
|
6
|
-
resource_path "/
|
6
|
+
resource_path "/issues/show/:id"
|
7
7
|
|
8
8
|
attr_accessor :repository
|
9
9
|
|
@@ -24,6 +24,7 @@ module Octopi
|
|
24
24
|
def self.find_all(*args)
|
25
25
|
repo = args.first
|
26
26
|
user, repo_name, opts = extract_user_repository(*args)
|
27
|
+
validate_args(user => :user, repo_name => :repo)
|
27
28
|
state = opts[:state] || "open"
|
28
29
|
state.downcase! if state
|
29
30
|
|
@@ -36,15 +37,63 @@ module Octopi
|
|
36
37
|
|
37
38
|
# TODO: Make find use hashes like find_all
|
38
39
|
def self.find(*args)
|
39
|
-
if args.
|
40
|
-
|
41
|
-
|
40
|
+
if args.length < 2
|
41
|
+
raise "Issue.find needs user, repository and issue number"
|
42
|
+
end
|
43
|
+
|
44
|
+
number = args.pop.to_i if args.last.respond_to?(:to_i)
|
45
|
+
number = args.pop if args.last.is_a?(Integer)
|
46
|
+
|
47
|
+
raise "Issue.find needs issue number as the last argument" unless number
|
48
|
+
|
49
|
+
if args.length > 1
|
50
|
+
user, repo = *args
|
42
51
|
else
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
52
|
+
repo = args.pop
|
53
|
+
raise "Issue.find needs at least a Repository object and issue number" unless repo.is_a? Repository
|
54
|
+
user, repo = repo.owner, repo.name
|
55
|
+
end
|
56
|
+
|
57
|
+
user, repo = extract_names(user, repo)
|
58
|
+
validate_args(user => :user, repo => :repo)
|
59
|
+
super user, repo, number
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.open(user, repo, params, api = ANONYMOUS_API)
|
63
|
+
user, repo_name = extract_names(user, repo)
|
64
|
+
data = api.post("/issues/open/#{user}/#{repo_name}", params)
|
65
|
+
issue = new(api, data['issue'])
|
66
|
+
issue.repository = repo if repo.is_a? Repository
|
67
|
+
issue
|
68
|
+
end
|
69
|
+
|
70
|
+
def reopen(*args)
|
71
|
+
data = @api.post(command_path("reopen"))
|
72
|
+
end
|
73
|
+
|
74
|
+
def close(*args)
|
75
|
+
data = @api.post(command_path("close"))
|
76
|
+
end
|
77
|
+
|
78
|
+
def save
|
79
|
+
data = @api.post(command_path("edit"), { :title => self.title, :body => self.body })
|
80
|
+
end
|
81
|
+
|
82
|
+
%[add remove].each do |oper|
|
83
|
+
define_method("#{oper}_label") do |*labels|
|
84
|
+
labels.each do |label|
|
85
|
+
@api.post("#{prefix("label/#{oper}")}/#{label}/#{number}")
|
86
|
+
end
|
47
87
|
end
|
48
88
|
end
|
89
|
+
|
90
|
+
private
|
91
|
+
def prefix(command)
|
92
|
+
"/issues/#{command}/#{repository.owner}/#{repository.name}"
|
93
|
+
end
|
94
|
+
|
95
|
+
def command_path(command)
|
96
|
+
"#{prefix(command)}/#{number}"
|
97
|
+
end
|
49
98
|
end
|
50
|
-
end
|
99
|
+
end
|
data/lib/octopi/repository.rb
CHANGED
@@ -18,13 +18,15 @@ module Octopi
|
|
18
18
|
|
19
19
|
def self.find_by_user(user)
|
20
20
|
user = user.login if user.is_a? User
|
21
|
+
self.validate_args(user => :user)
|
21
22
|
find_plural(user, :resource)
|
22
23
|
end
|
23
24
|
|
24
25
|
def self.find(user, name)
|
25
26
|
user = user.login if user.is_a? User
|
26
27
|
name = repo.name if name.is_a? Repository
|
27
|
-
|
28
|
+
self.validate_args(user => :user, name => :repo)
|
29
|
+
super [user, name]
|
28
30
|
end
|
29
31
|
|
30
32
|
def self.find_all(*args)
|
@@ -33,6 +35,14 @@ module Octopi
|
|
33
35
|
super args.join(" ").gsub(/ /,'+')
|
34
36
|
end
|
35
37
|
|
38
|
+
def self.open_issue(args)
|
39
|
+
Issue.open(args[:user], args[:repo], args)
|
40
|
+
end
|
41
|
+
|
42
|
+
def open_issue(args)
|
43
|
+
Issue.open(self.owner, self, args, @api)
|
44
|
+
end
|
45
|
+
|
36
46
|
def commits(branch = "master")
|
37
47
|
Commit.find_all(self, :branch => branch)
|
38
48
|
end
|
@@ -40,5 +50,9 @@ module Octopi
|
|
40
50
|
def issues(state = "open")
|
41
51
|
Issue.find_all(self, :state => state)
|
42
52
|
end
|
53
|
+
|
54
|
+
def issue(number)
|
55
|
+
Issue.find(self, number)
|
56
|
+
end
|
43
57
|
end
|
44
58
|
end
|
data/lib/octopi/resource.rb
CHANGED
data/lib/octopi/tag.rb
CHANGED
@@ -8,9 +8,10 @@ module Octopi
|
|
8
8
|
def self.find(user, repo)
|
9
9
|
user = user.login if user.is_a? User
|
10
10
|
repo = repo.name if repo.is_a? Repository
|
11
|
+
self.validate_args(user => :user, repo => :repo)
|
11
12
|
find_plural([user,repo,'tags'], :resource){
|
12
13
|
|i| {:name => i.first, :hash => i.last }
|
13
14
|
}
|
14
15
|
end
|
15
16
|
end
|
16
|
-
end
|
17
|
+
end
|
data/lib/octopi/user.rb
CHANGED
@@ -5,11 +5,22 @@ module Octopi
|
|
5
5
|
find_path "/user/search/:query"
|
6
6
|
resource_path "/user/show/:id"
|
7
7
|
|
8
|
+
def self.find(username)
|
9
|
+
self.validate_args(username => :user)
|
10
|
+
super username
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find_all(username)
|
14
|
+
self.validate_args(username => :user)
|
15
|
+
super username
|
16
|
+
end
|
17
|
+
|
8
18
|
def repositories
|
9
19
|
Repository.find_by_user(login)
|
10
20
|
end
|
11
21
|
|
12
22
|
def repository(name)
|
23
|
+
self.class.validate_args(name => :repo)
|
13
24
|
Repository.find(login, name)
|
14
25
|
end
|
15
26
|
|
@@ -35,4 +46,4 @@ module Octopi
|
|
35
46
|
users
|
36
47
|
end
|
37
48
|
end
|
38
|
-
end
|
49
|
+
end
|
data/test/octopi_test.rb
CHANGED
@@ -1,7 +1,46 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class OctopiTest < Test::Unit::TestCase
|
4
|
-
|
5
|
-
|
4
|
+
include Octopi
|
5
|
+
|
6
|
+
# TODO: Those tests are obviously brittle. Need to stub/mock it.
|
7
|
+
|
8
|
+
def assert_find_all(cls, check_method, repo, user)
|
9
|
+
repo_method = cls.resource_name(:plural)
|
10
|
+
|
11
|
+
item1 = cls.find_all(user.login, repo.name).first
|
12
|
+
item2 = cls.find_all(repo).first
|
13
|
+
item3 = repo.send(repo_method).first
|
14
|
+
|
15
|
+
assert_equal item1.send(check_method), item2.send(check_method)
|
16
|
+
assert_equal item1.send(check_method), item3.send(check_method)
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup
|
20
|
+
@user = User.find("fcoury")
|
21
|
+
@repo = @user.repository("octopi")
|
22
|
+
@issue = @repo.issues.first
|
23
|
+
end
|
24
|
+
|
25
|
+
context Issue do
|
26
|
+
should "return the correct issue by number" do
|
27
|
+
assert_equal @issue.number, Issue.find(@repo, @issue.number).number
|
28
|
+
assert_equal @issue.number, Issue.find(@user, @repo, @issue.number).number
|
29
|
+
assert_equal @issue.number, Issue.find(@repo.owner, @repo.name, @issue.number).number
|
30
|
+
end
|
31
|
+
|
32
|
+
should "return the correct issue by using repo.issue number" do
|
33
|
+
assert_equal @issue.number, @repo.issue(@issue.number).number
|
34
|
+
end
|
35
|
+
|
36
|
+
should "fetch the same issue using different but equivalent find_all params" do
|
37
|
+
assert_find_all Issue, :number, @repo, @user
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context Commit do
|
42
|
+
should "fetch the same commit using different but equivalent find_all params" do
|
43
|
+
assert_find_all Commit, :id, @repo, @user
|
44
|
+
end
|
6
45
|
end
|
7
46
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fcoury-octopi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felipe Coury
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-04-
|
12
|
+
date: 2009-04-21 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -29,6 +29,7 @@ files:
|
|
29
29
|
- lib/octopi/base.rb
|
30
30
|
- lib/octopi/blob.rb
|
31
31
|
- lib/octopi/commit.rb
|
32
|
+
- lib/octopi/error.rb
|
32
33
|
- lib/octopi/file_object.rb
|
33
34
|
- lib/octopi/issue.rb
|
34
35
|
- lib/octopi/repository.rb
|
@@ -64,7 +65,7 @@ requirements: []
|
|
64
65
|
rubyforge_project:
|
65
66
|
rubygems_version: 1.2.0
|
66
67
|
signing_key:
|
67
|
-
specification_version:
|
68
|
+
specification_version: 2
|
68
69
|
summary: A Ruby interface to GitHub API v2
|
69
70
|
test_files: []
|
70
71
|
|