watson-ruby 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +28 -0
- data/LICENSE +19 -0
- data/README.md +147 -0
- data/Rakefile +21 -0
- data/assets/defaultConf +21 -0
- data/assets/watson.svg +25 -0
- data/bin/watson +18 -0
- data/lib/watson.rb +69 -0
- data/lib/watson/bitbucket.rb +373 -0
- data/lib/watson/command.rb +470 -0
- data/lib/watson/config.rb +493 -0
- data/lib/watson/fs.rb +69 -0
- data/lib/watson/github.rb +369 -0
- data/lib/watson/parser.rb +405 -0
- data/lib/watson/printer.rb +293 -0
- data/lib/watson/remote.rb +120 -0
- data/lib/watson/version.rb +3 -0
- data/spec/config_spec.rb +119 -0
- data/spec/fs_spec.rb +56 -0
- data/spec/helper_spec.rb +32 -0
- data/spec/parser_spec.rb +128 -0
- data/watson.gemspec +33 -0
- metadata +116 -0
@@ -0,0 +1,293 @@
|
|
1
|
+
module Watson
|
2
|
+
|
3
|
+
# Color definitions for pretty printing
|
4
|
+
# Defined here because we need Global scope but makes sense to have them
|
5
|
+
# in the printer.rb file at least
|
6
|
+
|
7
|
+
BOLD = "\e[01m"
|
8
|
+
UNDERLINE = "\e[4m"
|
9
|
+
RESET = "\e[00m"
|
10
|
+
|
11
|
+
GRAY = "\e[38;5;0m"
|
12
|
+
RED = "\e[38;5;1m"
|
13
|
+
GREEN = "\e[38;5;2m"
|
14
|
+
YELLOW = "\e[38;5;3m"
|
15
|
+
BLUE = "\e[38;5;4m"
|
16
|
+
MAGENTA = "\e[38;5;5m"
|
17
|
+
CYAN = "\e[38;5;6m"
|
18
|
+
WHITE = "\e[38;5;7m"
|
19
|
+
|
20
|
+
|
21
|
+
# Printer class that handles all formatting and printing of parsed dir/file structure
|
22
|
+
class Printer
|
23
|
+
# [review] - Not sure if the way static methods are defined is correct
|
24
|
+
# Ok to have same name as instance methods?
|
25
|
+
# Only difference is where the output gets printed to
|
26
|
+
# [review] - No real setup in initialize method, combine it and run method?
|
27
|
+
|
28
|
+
# Include for debug_print (for class methods)
|
29
|
+
include Watson
|
30
|
+
|
31
|
+
# Debug printing for this class
|
32
|
+
DEBUG = false
|
33
|
+
|
34
|
+
class << self
|
35
|
+
|
36
|
+
# Include for debug_print (for static methods)
|
37
|
+
include Watson
|
38
|
+
|
39
|
+
###########################################################
|
40
|
+
# Custom color print for static call (only writes to STDOUT)
|
41
|
+
def cprint (msg = "", color = "")
|
42
|
+
|
43
|
+
# Identify method entry
|
44
|
+
debug_print "#{ self } : #{ __method__ }\n"
|
45
|
+
|
46
|
+
# This little check will allow us to take a Constant defined color
|
47
|
+
# As well as a [0-256] value if specified
|
48
|
+
if (color.is_a?(String))
|
49
|
+
debug_print "Custom color specified for cprint\n"
|
50
|
+
STDOUT.write(color)
|
51
|
+
elsif (color.between?(0, 256))
|
52
|
+
debug_print "No or Default color specified for cprint\n"
|
53
|
+
STDOUT.write("\e[38;5;#{ color }m")
|
54
|
+
end
|
55
|
+
|
56
|
+
STDOUT.write(msg)
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
###########################################################
|
61
|
+
# Standard header print for static call (uses static cprint)
|
62
|
+
def print_header
|
63
|
+
|
64
|
+
# Identify method entry
|
65
|
+
debug_print "#{ self } : #{ __method__ }\n"
|
66
|
+
|
67
|
+
# Header
|
68
|
+
cprint BOLD + "------------------------------\n" + RESET
|
69
|
+
cprint BOLD + "watson" + RESET
|
70
|
+
cprint " - " + RESET
|
71
|
+
cprint BOLD + YELLOW + "inline issue manager\n" + RESET
|
72
|
+
cprint BOLD + "------------------------------\n\n" + RESET
|
73
|
+
|
74
|
+
return true
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
###########################################################
|
79
|
+
# Status printer for static call (uses static cprint)
|
80
|
+
# Print status block in standard format
|
81
|
+
def print_status(msg, color)
|
82
|
+
cprint RESET + BOLD
|
83
|
+
cprint WHITE + "[ "
|
84
|
+
cprint "#{ msg } ", color
|
85
|
+
cprint WHITE + "] " + RESET
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
###########################################################
|
91
|
+
# Printer initialization method to setup necessary parameters, states, and vars
|
92
|
+
def initialize(config)
|
93
|
+
|
94
|
+
# Identify method entry
|
95
|
+
debug_print "#{ self } : #{ __method__ }\n"
|
96
|
+
|
97
|
+
@config = config
|
98
|
+
return true
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
###########################################################
|
103
|
+
# Take parsed structure and print out in specified formatting
|
104
|
+
def run(structure)
|
105
|
+
|
106
|
+
# Identify method entry
|
107
|
+
debug_print "#{ self } : #{ __method__ }\n"
|
108
|
+
|
109
|
+
# Check Config to see if we have access to less for printing
|
110
|
+
# If so, open our temp file as the output to write to
|
111
|
+
# Else, just print out to STDOUT
|
112
|
+
if @config.use_less
|
113
|
+
debug_print "Unix less avaliable, setting output to #{ @config.tmp_file }\n"
|
114
|
+
@output = File.open(@config.tmp_file, 'w')
|
115
|
+
elsif
|
116
|
+
debug_print "Unix less is unavaliable, setting output to STDOUT\n"
|
117
|
+
@output = STDOUT
|
118
|
+
end
|
119
|
+
|
120
|
+
# Print header for output
|
121
|
+
debug_print "Printing Header\n"
|
122
|
+
print_header
|
123
|
+
|
124
|
+
# Print out structure that was passed to this Printer
|
125
|
+
debug_print "Starting structure printing\n"
|
126
|
+
print_structure(structure)
|
127
|
+
|
128
|
+
# If we are using less, close the output file, display with less, then delete
|
129
|
+
if @config.use_less
|
130
|
+
@output.close
|
131
|
+
# [review] - Way of calling a native Ruby less?
|
132
|
+
system("less #{ @config.tmp_file }")
|
133
|
+
debug_print "File displayed with less, now deleting...\n"
|
134
|
+
File.delete(@config.tmp_file)
|
135
|
+
end
|
136
|
+
|
137
|
+
return true
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
###########################################################
|
142
|
+
# Custom color print for member call
|
143
|
+
# Allows not only for custom color printing but writing to file vs STDOUT
|
144
|
+
def cprint (msg = "", color = "")
|
145
|
+
|
146
|
+
# Identify method entry
|
147
|
+
debug_print "#{ self } : #{ __method__ }\n"
|
148
|
+
|
149
|
+
# This little check will allow us to take a Constant defined color
|
150
|
+
# As well as a [0-256] value if specified
|
151
|
+
if (color.is_a?(String))
|
152
|
+
debug_print "Custom color specified for cprint\n"
|
153
|
+
@output.write(color)
|
154
|
+
elsif (color.between?(0, 256))
|
155
|
+
debug_print "No or Default color specified for cprint\n"
|
156
|
+
@output.write("\e[38;5;#{ color }m")
|
157
|
+
end
|
158
|
+
|
159
|
+
@output.write(msg)
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
###########################################################
|
164
|
+
# Standard header print for class call (uses member cprint)
|
165
|
+
def print_header
|
166
|
+
# Identify method entry
|
167
|
+
|
168
|
+
debug_print "#{ self } : #{ __method__ }\n"
|
169
|
+
|
170
|
+
# Header
|
171
|
+
cprint BOLD + "------------------------------\n" + RESET
|
172
|
+
cprint BOLD + "watson" + RESET
|
173
|
+
cprint " - " + RESET
|
174
|
+
cprint BOLD + YELLOW + "inline issue manager\n\n" + RESET
|
175
|
+
cprint "Run in: #{ Dir.pwd }\n"
|
176
|
+
cprint "Run @ #{ Time.now.asctime }\n"
|
177
|
+
cprint BOLD + "------------------------------\n\n" + RESET
|
178
|
+
|
179
|
+
return true
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
###########################################################
|
184
|
+
# Status printer for member call (uses member cprint)
|
185
|
+
# Print status block in standard format
|
186
|
+
def print_status(msg, color)
|
187
|
+
cprint RESET + BOLD
|
188
|
+
cprint WHITE + "[ "
|
189
|
+
cprint "#{ msg } ", color
|
190
|
+
cprint WHITE + "] " + RESET
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
###########################################################
|
195
|
+
# Go through all files and directories and call necessary printing methods
|
196
|
+
# Print all individual entries, call print_structure on each subdir
|
197
|
+
def print_structure(structure)
|
198
|
+
|
199
|
+
# Identify method entry
|
200
|
+
debug_print "#{ self } : #{ __method__ }\n"
|
201
|
+
|
202
|
+
# First go through all the files in the current structure
|
203
|
+
# The current "structure" should reflect a dir/subdir
|
204
|
+
structure[:files].each do | _file |
|
205
|
+
debug_print "Printing info for #{ _file }\n"
|
206
|
+
print_entry(_file)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Next go through all the subdirs and pass them to print_structure
|
210
|
+
structure[:subdirs].each do | _subdir |
|
211
|
+
debug_print "Entering #{ _subdir } to print further\n"
|
212
|
+
print_structure(_subdir)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
###########################################################
|
218
|
+
# Individual entry printer
|
219
|
+
# Uses issue hash to format printed output
|
220
|
+
def print_entry(entry)
|
221
|
+
|
222
|
+
# Identify method entry
|
223
|
+
debug_print "#{ self } : #{ __method__ }\n"
|
224
|
+
|
225
|
+
# If no issues for this file, print that and break
|
226
|
+
# The filename print is repetative, but reduces another check later
|
227
|
+
if entry[:has_issues] == false
|
228
|
+
debug_print "No issues for #{ entry }\n"
|
229
|
+
print_status "o", GREEN
|
230
|
+
cprint BOLD + UNDERLINE + GREEN + "#{ entry[:relative_path] }" + RESET + "\n"
|
231
|
+
return true
|
232
|
+
else
|
233
|
+
debug_print "Issues found for #{ entry }\n"
|
234
|
+
cprint "\n"
|
235
|
+
print_status "x", RED
|
236
|
+
cprint BOLD + UNDERLINE + RED + "#{entry[:relative_path]}" + RESET + "\n"
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
# [review] - Should the tag structure be self contained in the hash
|
241
|
+
# Or is it ok to reference @config to figure out the tags
|
242
|
+
@config.tag_list.each do | _tag |
|
243
|
+
debug_print "Checking for #{ _tag }\n"
|
244
|
+
|
245
|
+
# [review] - Better way to ignore tags through structure (hash) data
|
246
|
+
# Maybe have individual has_issues for each one?
|
247
|
+
if entry[_tag].size.zero?
|
248
|
+
debug_print "#{ _tag } has no issues, skipping\n"
|
249
|
+
cprint "\n"
|
250
|
+
next
|
251
|
+
end
|
252
|
+
|
253
|
+
debug_print "#{ _tag } has issues in it, print!\n"
|
254
|
+
print_status "#{ _tag }", BLUE
|
255
|
+
cprint "\n"
|
256
|
+
|
257
|
+
# Go through each issue in tag
|
258
|
+
entry[_tag].each do | _issue |
|
259
|
+
cprint WHITE + " line #{ _issue[:line_number] } - " + RESET
|
260
|
+
cprint BOLD + "#{ _issue[:title] }" + RESET
|
261
|
+
|
262
|
+
|
263
|
+
# Check to see if it has been resolved on GitHub/Bitbucket
|
264
|
+
debug_print "Checking if issue has been resolved\n"
|
265
|
+
@config.github_issues[:closed].each do | _closed |
|
266
|
+
if _closed["body"].include?(_issue[:md5])
|
267
|
+
debug_print "Found in #{ _closed[:comment] }, not posting\n"
|
268
|
+
cprint BOLD + " [" + RESET
|
269
|
+
cprint GREEN + BOLD + "Resolved on GitHub" + RESET
|
270
|
+
cprint BOLD + "]" + RESET
|
271
|
+
end
|
272
|
+
debug_print "Did not find in #{ _closed[:comment] }\n"
|
273
|
+
end
|
274
|
+
|
275
|
+
debug_print "Checking if issue has been resolved\n"
|
276
|
+
@config.bitbucket_issues[:closed].each do | _closed |
|
277
|
+
if _closed["content"].include?(_issue[:md5])
|
278
|
+
debug_print "Found in #{ _closed["content"] }, not posting\n"
|
279
|
+
cprint BOLD + " [" + RESET
|
280
|
+
cprint GREEN + BOLD + "Resolved on Bitbucket" + RESET
|
281
|
+
cprint BOLD + "]\n" + RESET
|
282
|
+
end
|
283
|
+
debug_print "Did not find in #{ _closed["title"] }\n"
|
284
|
+
end
|
285
|
+
cprint "\n"
|
286
|
+
|
287
|
+
end
|
288
|
+
cprint "\n"
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
end
|
293
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Watson
|
2
|
+
# Remote class that handles all remote HTTP calls to Bitbucket and GitHub
|
3
|
+
class Remote
|
4
|
+
|
5
|
+
# Debug printing for this class
|
6
|
+
DEBUG = false
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
# Include for debug_print
|
11
|
+
include Watson
|
12
|
+
|
13
|
+
# Required libs
|
14
|
+
require 'net/https'
|
15
|
+
require 'uri'
|
16
|
+
require 'json'
|
17
|
+
|
18
|
+
|
19
|
+
# Default options hash for http_call
|
20
|
+
# Will get merged with input argument hash to maintain defaults
|
21
|
+
HTTP_opts = {
|
22
|
+
:url => nil, #--> URL of endpoint [String]
|
23
|
+
:ssl => false, #--> Use SSL in connection (HTTPS) (True/False]
|
24
|
+
:method => nil, #--> GET or POST for respective HTTP method [String]
|
25
|
+
:basic_auth => Array.new(0), #--> Array of username and pw to use for basic authentication
|
26
|
+
# If empty, assume no user authentication [Array]
|
27
|
+
:auth => nil, #--> Authentication token [String]
|
28
|
+
:data => nil, #--> Hash of data to be POST'd in HTTP request [Hash]
|
29
|
+
:verbose => false #--> Turn on verbose debug for this call [True/False]
|
30
|
+
}
|
31
|
+
|
32
|
+
###########################################################
|
33
|
+
# Generic HTTP call method
|
34
|
+
# Accepts input hash of options that dictate how the HTTP call is to be made
|
35
|
+
def http_call( opts )
|
36
|
+
# [review] - Don't use DEBUG inside Remote class but pull from calling method's class?
|
37
|
+
# [review] - Not sure if this is the best/proper way to do things but it works...
|
38
|
+
|
39
|
+
# Identify method entry
|
40
|
+
debug_print "#{ self.class } : #{ __method__ }\n"
|
41
|
+
|
42
|
+
# Merge default options with those passed in by user to form complete opt list
|
43
|
+
opts = HTTP_opts.merge(opts)
|
44
|
+
|
45
|
+
|
46
|
+
# Check URL in hash and get URI from it, then set up HTTP connection
|
47
|
+
if opts[:url] =~ /^#{URI::regexp}$/
|
48
|
+
_uri = URI(opts[:url])
|
49
|
+
else
|
50
|
+
debug_print "No URL specified in input opts, exiting HTTP call\n"
|
51
|
+
return false
|
52
|
+
end
|
53
|
+
|
54
|
+
_http = Net::HTTP.new(_uri.host, _uri.port)
|
55
|
+
|
56
|
+
# Print out verbose HTTP request if :verbose is set
|
57
|
+
# For hardcore debugging when shit really doesn't work
|
58
|
+
_http.set_debug_output $stderr if opts[:verbose] == true
|
59
|
+
|
60
|
+
# If SSL is set in hash, set HTTP connection to use SSL
|
61
|
+
_http.use_ssl = true if opts[:ssl] == true
|
62
|
+
|
63
|
+
# Create request based on HTTP method
|
64
|
+
# [review] - Not sure if to fail with no method or default to GET?
|
65
|
+
case opts[:method].upcase
|
66
|
+
when "GET"
|
67
|
+
_req = Net::HTTP::Get.new(_uri.request_uri)
|
68
|
+
|
69
|
+
when "POST"
|
70
|
+
_req = Net::HTTP::Post.new(_uri.request_uri)
|
71
|
+
|
72
|
+
else
|
73
|
+
debug_print "No method specified, cannot make HTTP request\n"
|
74
|
+
return false
|
75
|
+
end
|
76
|
+
|
77
|
+
# Check for basic authentication key in hash
|
78
|
+
if opts[:basic_auth].size == 2
|
79
|
+
_req.basic_auth(opts[:basic_auth][0], opts[:basic_auth][1])
|
80
|
+
end
|
81
|
+
|
82
|
+
# Check for Authentication token key in hash to be used in header
|
83
|
+
# I think this is pretty universal, but specifically works for GitHub
|
84
|
+
if opts[:auth]
|
85
|
+
_req["Authorization"] = "token #{ opts[:auth] }"
|
86
|
+
end
|
87
|
+
|
88
|
+
# [review] - Add :data_format to use set_form_data vs json body?
|
89
|
+
# For now, use Hash or Array, this is to differentiate between
|
90
|
+
# putting post data in body vs putting it in the form
|
91
|
+
|
92
|
+
# If a POST method, :data is present, and is a Hash, fill request body with data
|
93
|
+
if opts[:method].upcase == "POST" && opts[:data] && opts[:data].is_a?(Hash)
|
94
|
+
_req.body = opts[:data].to_json
|
95
|
+
end
|
96
|
+
|
97
|
+
# If a POST method, :data is present, and is an Array, use set_form_data
|
98
|
+
if opts[:method].upcase == "POST" && opts[:data] && opts[:data].is_a?(Array)
|
99
|
+
_req.set_form_data(opts[:data][0])
|
100
|
+
end
|
101
|
+
|
102
|
+
# Make HTTP request
|
103
|
+
_resp = _http.request(_req)
|
104
|
+
|
105
|
+
# Debug prints for status and message
|
106
|
+
debug_print "HTTP Response Code: #{ _resp.code }\n"
|
107
|
+
debug_print "HTTP Response Msg: #{ _resp.message }\n"
|
108
|
+
|
109
|
+
# [fix] - Not sure if 401 is the only code that gives nonparseable body?
|
110
|
+
# Figure out what other response codes are bad news for JSON.parse
|
111
|
+
_json = _resp.code == "401" ? Hash.new : JSON.parse(_resp.body)
|
112
|
+
debug_print "JSON: \n #{ _json }\n"
|
113
|
+
|
114
|
+
# [review] - Returning hash of json + response the right thing to do?
|
115
|
+
# return {:json => _json, :resp => _resp}
|
116
|
+
return _json, _resp
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
module Watson
|
2
|
+
require_relative 'helper_spec'
|
3
|
+
|
4
|
+
describe Config do
|
5
|
+
before(:each) do
|
6
|
+
@config = Config.new
|
7
|
+
@file = @config.instance_variable_get(:@rc_file)
|
8
|
+
silence_output
|
9
|
+
end
|
10
|
+
|
11
|
+
after(:each) do
|
12
|
+
File.delete(@file) if File.exists?(@file)
|
13
|
+
enable_output
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
describe '#create_conf' do
|
18
|
+
it 'create config file, return true' do
|
19
|
+
@config.create_conf.should be_true
|
20
|
+
File.exists?(@file).should be_true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#check_conf' do
|
25
|
+
context 'config does not exist' do
|
26
|
+
it 'create config file, return true' do
|
27
|
+
@config.check_conf.should be_true
|
28
|
+
File.exists?(@file).should be_true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'config does exist' do
|
33
|
+
it 'should return true' do
|
34
|
+
@config.check_conf.should be_true
|
35
|
+
File.exists?(@file).should be_true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#read_conf' do
|
41
|
+
context 'config does not exist' do
|
42
|
+
it 'no config, return false' do
|
43
|
+
@config.read_conf.should be_false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'config does exist' do
|
48
|
+
before { @config.create_conf }
|
49
|
+
|
50
|
+
it 'return true, values match default config' do
|
51
|
+
@config.create_conf.should be_true
|
52
|
+
@config.read_conf.should be_true
|
53
|
+
@config.dir_list.should include('.')
|
54
|
+
@config.tag_list.should include('fix', 'review', 'todo')
|
55
|
+
@config.ignore_list.should include('.git', '*.swp')
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#update_conf' do
|
62
|
+
before do
|
63
|
+
@config.check_conf
|
64
|
+
@config.parse_depth = 1000
|
65
|
+
@config.update_conf('parse_depth')
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'updated config.parse_depth should be 1000' do
|
69
|
+
@new_config = Config.new
|
70
|
+
@new_config.check_conf.should be_true
|
71
|
+
@new_config.read_conf.should be_true
|
72
|
+
@new_config.parse_depth.to_i.should eql 1000
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# [review] - Should this be #initialize or #new?
|
77
|
+
describe '#initialize' do
|
78
|
+
it 'should initialize all member vars' do
|
79
|
+
@config.cl_entry_set.should be_false
|
80
|
+
@config.cl_tag_set.should be_false
|
81
|
+
@config.cl_ignore_set.should be_false
|
82
|
+
|
83
|
+
@config.use_less.should be_false
|
84
|
+
|
85
|
+
@config.ignore_list.should == []
|
86
|
+
@config.dir_list.should == []
|
87
|
+
@config.file_list.should == []
|
88
|
+
@config.tag_list.should == []
|
89
|
+
|
90
|
+
@config.remote_valid.should be_false
|
91
|
+
|
92
|
+
@config.github_valid.should be_false
|
93
|
+
@config.github_api.should == ''
|
94
|
+
@config.github_repo.should == ''
|
95
|
+
@config.github_issues.should == {:open => Hash.new(),
|
96
|
+
:closed => Hash.new() }
|
97
|
+
|
98
|
+
@config.bitbucket_valid.should be_false
|
99
|
+
@config.bitbucket_api.should == ''
|
100
|
+
@config.bitbucket_repo.should == ''
|
101
|
+
@config.bitbucket_issues.should == {:open => Hash.new(),
|
102
|
+
:closed => Hash.new() }
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe '#run' do
|
108
|
+
it 'should populate all member vars' do
|
109
|
+
@config.run
|
110
|
+
@config.ignore_list.should include('.git', '*.swp')
|
111
|
+
@config.tag_list.should include('fix', 'review', 'todo')
|
112
|
+
@config.dir_list.should include('.')
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|