rtrac 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +5 -0
- data/Manifest.txt +14 -0
- data/README.txt +54 -0
- data/Rakefile +15 -0
- data/bin/rtrac +7 -0
- data/lib/rtrac.rb +15 -0
- data/lib/rtrac/base.rb +190 -0
- data/lib/rtrac/ticket.rb +96 -0
- data/lib/rtrac/util.rb +165 -0
- data/test/test_base.rb +49 -0
- data/test/test_helper.rb +4 -0
- data/test/test_rtrac.rb +0 -0
- data/test/test_ticket.rb +37 -0
- metadata +79 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
rtrac
|
2
|
+
by Josh Stephenson
|
3
|
+
http://rtrac.rubyforge.org
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Trac API wrappers
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
Ticket access for Trac
|
12
|
+
|
13
|
+
== SYNOPSIS:
|
14
|
+
|
15
|
+
Rtrac::Base.get_by_milestone(milestone).each do |id|
|
16
|
+
# grab the ticket's data
|
17
|
+
tick = Rtrac::Ticket.new(id)
|
18
|
+
iteration_hash[:total] += tick.severity.to_i
|
19
|
+
iteration_hash[:tickets] << {:id => id, :points => tick.severity.to_i, :status => tick.status, :updated_at =>Time.parse(tick.updated_at.to_s)}
|
20
|
+
end
|
21
|
+
|
22
|
+
== REQUIREMENTS:
|
23
|
+
|
24
|
+
active_support
|
25
|
+
hoe
|
26
|
+
|
27
|
+
== INSTALL:
|
28
|
+
|
29
|
+
sudo gem install rtrac
|
30
|
+
|
31
|
+
== LICENSE:
|
32
|
+
|
33
|
+
(The MIT License)
|
34
|
+
|
35
|
+
Copyright (c) 2007 Josh Stephenson
|
36
|
+
|
37
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
38
|
+
a copy of this software and associated documentation files (the
|
39
|
+
'Software'), to deal in the Software without restriction, including
|
40
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
41
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
42
|
+
permit persons to whom the Software is furnished to do so, subject to
|
43
|
+
the following conditions:
|
44
|
+
|
45
|
+
The above copyright notice and this permission notice shall be
|
46
|
+
included in all copies or substantial portions of the Software.
|
47
|
+
|
48
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
49
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
50
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
51
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
52
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
53
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
54
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'hoe'
|
3
|
+
require './lib/rtrac.rb'
|
4
|
+
|
5
|
+
Hoe.new('rtrac', Rtrac::Config.version) do |p|
|
6
|
+
p.rubyforge_name = 'rtrac'
|
7
|
+
p.author = 'Josh Stephenson'
|
8
|
+
p.email = 'josh@elctech.com'
|
9
|
+
p.summary = 'Trac wrapper with command line tool'
|
10
|
+
p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
|
11
|
+
p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
12
|
+
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
13
|
+
end
|
14
|
+
|
15
|
+
# vim: syntax=Ruby
|
data/bin/rtrac
ADDED
data/lib/rtrac.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
module Rtrac
|
3
|
+
class Config
|
4
|
+
def self.version
|
5
|
+
'1.0.1'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
require 'rubygems'
|
10
|
+
require 'yaml'
|
11
|
+
require 'active_support'
|
12
|
+
require 'xmlrpc/client'
|
13
|
+
require 'rtrac/base'
|
14
|
+
require 'rtrac/ticket'
|
15
|
+
require 'rtrac/util'
|
data/lib/rtrac/base.rb
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
module Rtrac
|
2
|
+
class Base
|
3
|
+
|
4
|
+
cattr_accessor :connection, :config
|
5
|
+
|
6
|
+
class << self
|
7
|
+
# handles the sending of queries to Trac with exception handling
|
8
|
+
def send_query(*args)
|
9
|
+
begin
|
10
|
+
connection.call(*args)
|
11
|
+
rescue
|
12
|
+
# print a standard error
|
13
|
+
logger.error "Error connecting to Trac API"
|
14
|
+
if logger.level > Logger::INFO
|
15
|
+
logger.error $@
|
16
|
+
end
|
17
|
+
exit
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def connection
|
22
|
+
@connection ||= self.open_connection
|
23
|
+
end
|
24
|
+
|
25
|
+
# list all methods supported by the trac api
|
26
|
+
def list_methods
|
27
|
+
send_query('system.listMethods')
|
28
|
+
end
|
29
|
+
|
30
|
+
def custom(*args)
|
31
|
+
send_query(*args)
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_by_milestone(milestone)
|
35
|
+
send_query('ticket.query', "milestone=#{milestone.strip}")
|
36
|
+
end
|
37
|
+
|
38
|
+
# returns method help
|
39
|
+
def method_help(method)
|
40
|
+
send_query('system.methodHelp', method)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns an array of ticket ids
|
44
|
+
# Valid order types include:
|
45
|
+
def get_tickets(count, order = :priority)
|
46
|
+
extract_account_info
|
47
|
+
order = :priority unless columns.include?(order)
|
48
|
+
send_query('ticket.query', "order=#{order.to_s}")[0,count].collect{ |id| id }
|
49
|
+
end
|
50
|
+
|
51
|
+
#:stopdoc:
|
52
|
+
def open_connection
|
53
|
+
if (options = extract_account_info)
|
54
|
+
@username, @password, @url = options
|
55
|
+
uri = URI.parse @url
|
56
|
+
#puts "Connecting to \"#{@url}\" using username \"#{@username}\" and password \"#{@password}\""
|
57
|
+
@connection = XMLRPC::Client.new3(:host => uri.host, :path => "#{uri.path}/login/xmlrpc", :user => @username, :password => @password, :use_ssl => true)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def extract_account_info
|
62
|
+
username = password = url = columns = nil
|
63
|
+
configuration_options.each do |key, value|
|
64
|
+
if key.to_sym == :username
|
65
|
+
username = value.to_s
|
66
|
+
elsif key.to_sym == :password
|
67
|
+
password = value.to_s
|
68
|
+
elsif key.to_sym == :url
|
69
|
+
url = value.to_s
|
70
|
+
elsif key.to_sym == :columns
|
71
|
+
@columns = value.to_a
|
72
|
+
end
|
73
|
+
end
|
74
|
+
if invalid_config?(username, password, url, @columns)
|
75
|
+
logger.error "Invalid configuration options. Please edit your #{config_path} file accordingly."
|
76
|
+
return false
|
77
|
+
end
|
78
|
+
[username, password, url, @columns]
|
79
|
+
end
|
80
|
+
|
81
|
+
def configuration_options
|
82
|
+
return @configuration_options unless @configuration_options.nil?
|
83
|
+
if self.config.nil?
|
84
|
+
@configuration_options = find_or_create_config
|
85
|
+
else
|
86
|
+
if File.exist?(config)
|
87
|
+
@configuration_options = YAML::load(open(config))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
@configuration_options
|
91
|
+
end
|
92
|
+
|
93
|
+
def invalid_config?(username, password, url, columns)
|
94
|
+
username.empty? || password.empty? || columns.empty? || ![url =~ /^http(s|):\/\/.+/i].any?
|
95
|
+
end
|
96
|
+
|
97
|
+
def columns
|
98
|
+
extract_account_info
|
99
|
+
@columns ||= required_columns + optional_columns
|
100
|
+
end
|
101
|
+
|
102
|
+
def required_columns
|
103
|
+
extract_account_info
|
104
|
+
@configuration_options["columns"]["required"]
|
105
|
+
end
|
106
|
+
|
107
|
+
def optional_columns
|
108
|
+
extract_account_info
|
109
|
+
@configuration_options["columns"]["optional"]
|
110
|
+
end
|
111
|
+
|
112
|
+
def find_or_create_config
|
113
|
+
begin
|
114
|
+
config = YAML::load(open(config_path))
|
115
|
+
rescue
|
116
|
+
create_new_config
|
117
|
+
end
|
118
|
+
config
|
119
|
+
end
|
120
|
+
|
121
|
+
def home_dir
|
122
|
+
ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH']
|
123
|
+
end
|
124
|
+
|
125
|
+
def config_path
|
126
|
+
if RAILS_ROOT
|
127
|
+
File.join(RAILS_ROOT, 'config', Rtrac::Configuration.options[:config_filename])
|
128
|
+
else
|
129
|
+
File.join(home_dir, ".#{Rtrac::Configuration.options[:config_filename]}") # hide it if it goes in home
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def create_new_config
|
134
|
+
file = File.open(config_path, "w+")
|
135
|
+
file.write(Rtrac::Configuration.options[:default_config_file])
|
136
|
+
file.flush
|
137
|
+
file.close
|
138
|
+
logger.info "No config file found in #{home_dir}
|
139
|
+
A new one has been created. Please edit it before continuing
|
140
|
+
#{config_path}
|
141
|
+
"
|
142
|
+
exit
|
143
|
+
end
|
144
|
+
|
145
|
+
def logger
|
146
|
+
if @logger.nil?
|
147
|
+
@logger = Logger.new(STDERR)
|
148
|
+
@logger.level = Logger::INFO
|
149
|
+
end
|
150
|
+
@logger
|
151
|
+
end
|
152
|
+
#:start_doc:
|
153
|
+
end
|
154
|
+
end
|
155
|
+
class Configuration
|
156
|
+
class << self
|
157
|
+
def options
|
158
|
+
{:default_config_file => default_config_file, :config_filename => 'rtrac.yml'}
|
159
|
+
end
|
160
|
+
|
161
|
+
def default_config_file
|
162
|
+
default_config_file=<<CONFIG
|
163
|
+
username:
|
164
|
+
password:
|
165
|
+
url:
|
166
|
+
columns:
|
167
|
+
required:
|
168
|
+
- :summary
|
169
|
+
- :description
|
170
|
+
optional:
|
171
|
+
- :type
|
172
|
+
- :time
|
173
|
+
- :changetime
|
174
|
+
- :component
|
175
|
+
- :severity
|
176
|
+
- :priority
|
177
|
+
- :owner
|
178
|
+
- :reporter
|
179
|
+
- :cc
|
180
|
+
- :version
|
181
|
+
- :milestone
|
182
|
+
- :status
|
183
|
+
- :resolution
|
184
|
+
- :keywords
|
185
|
+
CONFIG
|
186
|
+
default_config_file
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
data/lib/rtrac/ticket.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
module Rtrac
|
2
|
+
class TicketError < StandardError; end
|
3
|
+
class Ticket < Rtrac::Base
|
4
|
+
|
5
|
+
attr_accessor :trac_id
|
6
|
+
|
7
|
+
def initialize(trac_id, logger = nil)
|
8
|
+
@logger = logger
|
9
|
+
@trac_id = trac_id
|
10
|
+
end
|
11
|
+
|
12
|
+
def created_at
|
13
|
+
Time.at(ticket_attributes[1].to_i)
|
14
|
+
end
|
15
|
+
|
16
|
+
def updated_at
|
17
|
+
Time.at(+ticket_attributes[2].to_i)
|
18
|
+
end
|
19
|
+
|
20
|
+
def attributes
|
21
|
+
extended_attributes = ticket_attributes[3].symbolize_keys!
|
22
|
+
{:id => ticket_attributes[0], :created_at => ticket_attributes[1], :updated_at => ticket_attributes[2]}.merge(extended_attributes)
|
23
|
+
end
|
24
|
+
|
25
|
+
def attributes=(attributes)
|
26
|
+
@ticket_attributes = attributes
|
27
|
+
end
|
28
|
+
|
29
|
+
# ticket description
|
30
|
+
def description
|
31
|
+
method_missing(:description)
|
32
|
+
end
|
33
|
+
alias_method :body, :description
|
34
|
+
|
35
|
+
# ticket summary
|
36
|
+
def summary
|
37
|
+
method_missing(:summary)
|
38
|
+
end
|
39
|
+
alias_method :title, :summary
|
40
|
+
|
41
|
+
# update a ticket with a comment and attributes
|
42
|
+
def update(comment, attributes = {})
|
43
|
+
sendable_attributes = attributes
|
44
|
+
sendable_attributes.delete(:created_at) && sendable_attributes.delete(:updated_at)
|
45
|
+
self.class.send_query('ticket.update', @trac_id, comment, sendable_attributes)
|
46
|
+
end
|
47
|
+
|
48
|
+
# create a new ticket
|
49
|
+
def self.create(title, description, attributes = {})
|
50
|
+
send_query('ticket.create', title, description, attributes)
|
51
|
+
end
|
52
|
+
|
53
|
+
# delete a ticket forever
|
54
|
+
def self.destroy(trac_id)
|
55
|
+
send_query('ticket.delete', trac_id)
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_s
|
59
|
+
"#{summary}"
|
60
|
+
end
|
61
|
+
|
62
|
+
protected
|
63
|
+
|
64
|
+
def method_missing(method)
|
65
|
+
if attributes.has_key?(method)
|
66
|
+
attributes[method]
|
67
|
+
else
|
68
|
+
logger.debug "No attribute found for #{method}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# returns a hash of ticket attributes
|
73
|
+
def get
|
74
|
+
self.class.send_query('ticket.get', @trac_id)
|
75
|
+
end
|
76
|
+
|
77
|
+
def ticket_attributes
|
78
|
+
@ticket_attributes ||= get
|
79
|
+
end
|
80
|
+
|
81
|
+
def logger
|
82
|
+
@logger ||= Logger.new(STDERR)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
class Hash
|
87
|
+
def symbolize_keys!
|
88
|
+
keys.each do |key|
|
89
|
+
unless key.is_a?(Symbol) || (new_key = key.to_sym).nil?
|
90
|
+
self[new_key] = self[key]
|
91
|
+
delete(key)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
self
|
95
|
+
end
|
96
|
+
end
|
data/lib/rtrac/util.rb
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
module Rtrac
|
2
|
+
class Util < Rtrac::Base
|
3
|
+
VALID_COMMANDS = [:list, :show, :update, :delete, :create]
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def run!
|
7
|
+
if ARGV.include?('--debug')
|
8
|
+
@logger = Logger.new(STDERR)
|
9
|
+
@logger.level = Logger::DEBUG
|
10
|
+
ARGV.delete('--debug')
|
11
|
+
end
|
12
|
+
command = ARGV.shift
|
13
|
+
if command.nil?
|
14
|
+
usage
|
15
|
+
else
|
16
|
+
case command.to_sym
|
17
|
+
when :list
|
18
|
+
list(ARGV.shift, ARGV.shift)
|
19
|
+
when :show
|
20
|
+
show(ARGV.shift)
|
21
|
+
when :update
|
22
|
+
update(ARGV.shift)
|
23
|
+
when :delete
|
24
|
+
delete(ARGV.shift)
|
25
|
+
when :close
|
26
|
+
close(ARGV.shift)
|
27
|
+
when :create
|
28
|
+
create
|
29
|
+
else
|
30
|
+
usage
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def list(count, order = 'priority')
|
36
|
+
Rtrac::Base.get_tickets(count.to_i, order).each do |id|
|
37
|
+
tick = Rtrac::Ticket.new(id)
|
38
|
+
keys = tick.attributes.keys.reject{|k| k == :id || k == :type }
|
39
|
+
|
40
|
+
keys.each do |key|
|
41
|
+
puts "#{key.to_s[0,16].rjust(16, ' ')}: #{tick.send(key).to_s[0,60].rjust(60, ' ')}"
|
42
|
+
end
|
43
|
+
puts ""
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def show(id)
|
48
|
+
usage if id.nil?
|
49
|
+
tick = get_ticket(id)
|
50
|
+
display(tick)
|
51
|
+
end
|
52
|
+
|
53
|
+
def delete(id)
|
54
|
+
if(Rtrac::Ticket.destroy(id)).to_i.zero?
|
55
|
+
puts 'Deleted'
|
56
|
+
else
|
57
|
+
puts 'Error deleting ticket.'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def create
|
62
|
+
required_attributes = {}
|
63
|
+
optional_attributes = {}
|
64
|
+
read_required_attributes(required_attributes)
|
65
|
+
read_optional_attributes(optional_attributes)
|
66
|
+
required_attributes = required_attributes.values
|
67
|
+
puts Rtrac::Ticket.create(required_attributes.shift, required_attributes.shift, optional_attributes)
|
68
|
+
end
|
69
|
+
|
70
|
+
def update(id)
|
71
|
+
tick = get_ticket(id)
|
72
|
+
all_attributes = tick.attributes
|
73
|
+
read_optional_attributes(all_attributes, true)
|
74
|
+
comment = read_value(:comment)
|
75
|
+
resp = tick.update(comment, all_attributes)
|
76
|
+
# tick.attributes = all_attributes
|
77
|
+
# display(tick)
|
78
|
+
end
|
79
|
+
|
80
|
+
def read_required_attributes(attribute_hash)
|
81
|
+
self.required_columns.each do |attr|
|
82
|
+
while attribute_hash[attr].nil?
|
83
|
+
puts "#{attr.to_s.capitalize}: "
|
84
|
+
value = STDIN.readline
|
85
|
+
attribute_hash[attr] = value
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def read_optional_attributes(attribute_hash, conflate = false)
|
91
|
+
cols = conflate ? self.required_columns + self.optional_columns : self.optional_columns
|
92
|
+
display_menu(attribute_hash, cols)
|
93
|
+
until (num = STDIN.readline.strip).empty?
|
94
|
+
num = num.to_i
|
95
|
+
attribute = cols[num-1]
|
96
|
+
attribute_hash[cols[num-1]] = read_value(attribute)
|
97
|
+
display_menu(attribute_hash, cols)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def read_value(attribute)
|
102
|
+
puts "#{attribute.to_s.capitalize}: "
|
103
|
+
STDIN.readline.strip
|
104
|
+
end
|
105
|
+
|
106
|
+
def display_menu(attribute_hash, cols)
|
107
|
+
puts "Enter the number of an attribute to fill in or <Enter> to submit"
|
108
|
+
cols.each_with_index do |attr, idx|
|
109
|
+
puts "#{idx+1}. #{attr.to_s.capitalize} => #{attribute_hash[attr]}"
|
110
|
+
end
|
111
|
+
puts ""
|
112
|
+
end
|
113
|
+
|
114
|
+
def close(id, comment = nil)
|
115
|
+
raise NotImplementedError
|
116
|
+
end
|
117
|
+
|
118
|
+
def get_ticket(id)
|
119
|
+
@tick ||= Rtrac::Ticket.new(id, @logger)
|
120
|
+
end
|
121
|
+
|
122
|
+
def display(tick)
|
123
|
+
if tick.is_a?(Rtrac::Ticket)
|
124
|
+
display_ticket(tick)
|
125
|
+
else
|
126
|
+
display_ticket_from_hash(tick)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def display_ticket(tick)
|
131
|
+
# reject #id and #type or ruby will choke!
|
132
|
+
keys = tick.attributes.keys.reject{|k| k == :id || k == :type }
|
133
|
+
|
134
|
+
keys.each do |key|
|
135
|
+
# we'll send the method to the ticket so dates are parsed
|
136
|
+
puts "#{key.to_s[0,16].rjust(16, ' ')}: #{tick.send(key).to_s[0,60].rjust(60, ' ')}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def display_ticket_from_hash(attributes)
|
141
|
+
# reject #id and #type or ruby will choke!
|
142
|
+
keys = attributes.keys.reject{|k| k == :id || k == :type }
|
143
|
+
|
144
|
+
keys.each do |key|
|
145
|
+
# we'll send the method to the ticket so dates are parsed
|
146
|
+
puts "#{key.to_s[0,16].rjust(16, ' ')}: #{tick.attributes[key].to_s[0,60].rjust(60, ' ')}"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def usage
|
151
|
+
usage=<<USAGE
|
152
|
+
rtrac COMMAND [OPTIONS]
|
153
|
+
COMMANDS:
|
154
|
+
list [COUNT] [PRIORITY]
|
155
|
+
show ID
|
156
|
+
create
|
157
|
+
update ID
|
158
|
+
delete ID
|
159
|
+
USAGE
|
160
|
+
puts usage
|
161
|
+
exit
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
data/test/test_base.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class RtracBaseTest < Test::Unit::TestCase
|
4
|
+
# def test_send_query_should_open_connection
|
5
|
+
# XMLRPC::Client.expects(:new3).returns(stub())
|
6
|
+
# Rtrac::Base.expects(:open_connection).returns(stub(:call => ''))
|
7
|
+
# Rtrac::Base.send_query('foo')
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# def test_open_connection_should_hit_xmlrpc
|
11
|
+
# Rtrac::Base.send_query('foo')
|
12
|
+
# end
|
13
|
+
|
14
|
+
def test_connection
|
15
|
+
Rtrac::Base.expects(:open_connection)
|
16
|
+
Rtrac::Base.connection
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_list_methods
|
20
|
+
Rtrac::Base.expects(:send_query)
|
21
|
+
Rtrac::Base.list_methods
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_get_tickets
|
25
|
+
Rtrac::Base.expects(:send_query)
|
26
|
+
Rtrac::Base.list_methods
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_open_connection
|
30
|
+
XMLRPC::Client.expects(:new3)
|
31
|
+
URI.expects(:parse).returns(stub(:host => 'foo.com', :path => 'foo'))
|
32
|
+
Rtrac::Base.send(:open_connection)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_extract_account_info
|
36
|
+
Rtrac::Base.expects(:configuration_options).returns({:username => 'foo', :password => '123', :url => 'http://wush.net/trac/foo'})
|
37
|
+
Rtrac::Base.expects(:invalid_config?).returns(false)
|
38
|
+
Rtrac::Base.send(:extract_account_info)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_valid_config
|
42
|
+
assert_equal false, Rtrac::Base.send(:invalid_config?, 'foo', 'bar', 'http://wush.net/trac/foo', ['foo'])
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_invalid_config
|
46
|
+
assert Rtrac::Base.send(:invalid_config?, 'foo', 'bar', 'ttp://wush.net/trac/foo', ['foo'])
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/test/test_helper.rb
ADDED
data/test/test_rtrac.rb
ADDED
File without changes
|
data/test/test_ticket.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class TestTicket < Test::Unit::TestCase
|
4
|
+
def test_attributes
|
5
|
+
tick = Rtrac::Ticket.new(1)
|
6
|
+
tick.stubs(:ticket_attributes).returns(['1', 1195317367, 1195317367, {'summary' => 'test summary', 'description' => 'test description'}])
|
7
|
+
assert_equal tick.attributes, {:id => '1', :created_at => 1195317367, :updated_at => 1195317367, :summary => 'test summary', :description => 'test description'}
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_setting_attributes
|
11
|
+
tick = Rtrac::Ticket.new(1)
|
12
|
+
tick.attributes = {:foo => 'foo'}
|
13
|
+
assert_equal tick.instance_variable_get(:@ticket_attributes), {:foo => 'foo'}
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_update_should_remove_updated_at_and_created_at
|
17
|
+
tick = Rtrac::Ticket.new(1, {:summary => 'foo', :created_at => 'foo', :updated_at => 'foo'})
|
18
|
+
Rtrac::Ticket.expects(:send_query).with('ticket.update', 1, 'Testing Comment', {:summary => 'foo'}).returns(true)
|
19
|
+
tick.update('Testing Comment', {:summary => 'foo', :created_at => 'foo', :updated_at => 'foo'})
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_create
|
23
|
+
Rtrac::Ticket.expects(:send_query).with('ticket.create', 'Test Title', 'Test Description', {:foo => 'foo'})
|
24
|
+
Rtrac::Ticket.create('Test Title', 'Test Description', {:foo => 'foo'})
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_destroy
|
28
|
+
Rtrac::Ticket.expects(:send_query).with('ticket.delete', 1)
|
29
|
+
Rtrac::Ticket.destroy(1)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_get
|
33
|
+
tick = Rtrac::Ticket.new(1)
|
34
|
+
Rtrac::Ticket.expects(:send_query).with('ticket.get', 1)
|
35
|
+
tick.send(:get)
|
36
|
+
end
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rtrac
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Josh Stephenson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-03-08 23:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.5.0
|
23
|
+
version:
|
24
|
+
description: "== FEATURES/PROBLEMS: Ticket access for Trac == SYNOPSIS: Rtrac::Base.get_by_milestone(milestone).each do |id| # grab the ticket's data tick = Rtrac::Ticket.new(id) iteration_hash[:total] += tick.severity.to_i iteration_hash[:tickets] << {:id => id, :points => tick.severity.to_i, :status => tick.status, :updated_at =>Time.parse(tick.updated_at.to_s)} end == REQUIREMENTS: active_support hoe"
|
25
|
+
email: josh@elctech.com
|
26
|
+
executables:
|
27
|
+
- rtrac
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- History.txt
|
32
|
+
- Manifest.txt
|
33
|
+
- README.txt
|
34
|
+
files:
|
35
|
+
- History.txt
|
36
|
+
- Manifest.txt
|
37
|
+
- README.txt
|
38
|
+
- Rakefile
|
39
|
+
- bin/rtrac
|
40
|
+
- lib/rtrac.rb
|
41
|
+
- lib/rtrac/util.rb
|
42
|
+
- lib/rtrac/base.rb
|
43
|
+
- lib/rtrac/ticket.rb
|
44
|
+
- test/test_helper.rb
|
45
|
+
- test/test_rtrac.rb
|
46
|
+
- test/test_base.rb
|
47
|
+
- test/test_ticket.rb
|
48
|
+
has_rdoc: true
|
49
|
+
homepage: " by Josh Stephenson"
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options:
|
52
|
+
- --main
|
53
|
+
- README.txt
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
version:
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
requirements: []
|
69
|
+
|
70
|
+
rubyforge_project: rtrac
|
71
|
+
rubygems_version: 1.0.1
|
72
|
+
signing_key:
|
73
|
+
specification_version: 2
|
74
|
+
summary: Trac wrapper with command line tool
|
75
|
+
test_files:
|
76
|
+
- test/test_base.rb
|
77
|
+
- test/test_helper.rb
|
78
|
+
- test/test_rtrac.rb
|
79
|
+
- test/test_ticket.rb
|