tddium-preview 0.0.1 → 0.0.4

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.
data/lib/tddium.rb CHANGED
@@ -1,11 +1,13 @@
1
1
  =begin
2
- Copyright (c) 2010 tddium.com All Rights Reserved
2
+ Copyright (c) 2011 Solano Labs All Rights Reserved
3
3
  =end
4
4
 
5
5
  require "rubygems"
6
6
  require "thor"
7
- require "httparty"
7
+ require "highline/import"
8
8
  require "json"
9
+ require "tddium_client"
10
+ require File.expand_path("../tddium/constant", __FILE__)
9
11
 
10
12
  # Usage:
11
13
  #
@@ -26,204 +28,435 @@ require "json"
26
28
  # tddium help # Print this usage message
27
29
 
28
30
  class Tddium < Thor
29
- API_HOST = "https://api.tddium.com"
30
- API_VERSION = "1"
31
- API_KEY_HEADER = "X-tddium-api-key"
32
- SUITES_PATH = "suites"
33
- SESSIONS_PATH = "sessions"
34
- TEST_EXECUTIONS_PATH = "test_executions"
35
- REGISTER_TEST_EXECUTIONS_PATH = "#{TEST_EXECUTIONS_PATH}/register"
36
- START_TEST_EXECUTIONS_PATH = "#{TEST_EXECUTIONS_PATH}/start"
37
- REPORT_TEST_EXECUTIONS_PATH = "#{TEST_EXECUTIONS_PATH}/report"
38
- GIT_REMOTE_NAME = "tddium"
39
- GIT_REMOTE_SCHEME = "ssh"
40
- GIT_REMOTE_USER = "git"
41
- GIT_REMOTE_ABSOLUTE_PATH = "/home/git/repo"
42
- SLEEP_TIME_BETWEEN_POLLS = 2
43
- TERMINATE_PROCESS_INSTRUCTIONS = "Ctrl-C to terminate the process"
44
- INTERRUPT_TEXT = "Interrupted"
45
- NOT_INITIALIZED_ERROR = "tddium must be initialized. Try 'tddium login'"
46
- INVALID_TDDIUM_FILE = ".tddium config file is corrupt. Try 'tddium login'"
47
-
48
- desc "suite", "Register the suite for this rails app, or manage its settings"
49
- method_option :ssh_key, :type => :string, :default => nil
50
- method_option :test_pattern, :type => :string, :default => nil
51
- method_option :name, :type => :string, :default => nil
52
- def suite
53
- return unless git_repo? && tddium_settings
54
-
55
- # Inputs for API call
56
- params = {}
31
+ include TddiumConstant
57
32
 
58
- default_ssh_file = "~/.ssh/id_rsa.pub"
59
- ssh_file = options[:ssh_key] || ask("Enter your ssh key or press 'Return'. Using #{default_ssh_file} by default:")
60
- ssh_file = default_ssh_file if ssh_file.empty?
61
- params[:ssh_key] = File.open(File.expand_path(ssh_file)) {|file| file.read}
33
+ desc "account", "View/Manage account information"
34
+ method_option :environment, :type => :string, :default => nil
35
+ method_option :email, :type => :string, :default => nil
36
+ method_option :password, :type => :string, :default => nil
37
+ method_option :ssh_key_file, :type => :string, :default => nil
38
+ def account
39
+ set_default_environment(options[:environment])
40
+ if user_logged_in? do |api_response|
41
+ # User is already logged in, so just display the info
42
+ show_user_details(api_response)
43
+ end
44
+ else
45
+ params = get_user_credentials(options.merge(:invited => true))
62
46
 
63
- default_test_pattern = "**/*_spec.rb"
64
- test_pattern = options[:test_pattern] || ask("Enter a test pattern or press 'Return'. Using #{default_test_pattern} by default:")
65
- params[:test_pattern] = test_pattern.empty? ? default_test_pattern : test_pattern
47
+ # Prompt for the password confirmation if password is not from command line
48
+ unless options[:password]
49
+ password_confirmation = HighLine.ask(Text::Prompt::PASSWORD_CONFIRMATION) { |q| q.echo = "*" }
50
+ unless password_confirmation == params[:password]
51
+ say Text::Process::PASSWORD_CONFIRMATION_INCORRECT
52
+ return
53
+ end
54
+ end
66
55
 
67
- default_suite_name = "#{File.basename(Dir.pwd)}/#{current_git_branch}"
68
- suite_name = options[:name] || ask("Enter a suite name or press 'Return'. Using '#{default_suite_name}' by default:")
69
- params[:suite_name] = suite_name.empty? ? default_suite_name : suite_name
56
+ # Prompt for ssh-key file
57
+ ssh_file = prompt(Text::Prompt::SSH_KEY, options[:ssh_key_file], Default::SSH_FILE)
58
+ params[:user_git_pubkey] = File.open(File.expand_path(ssh_file)) {|file| file.read}
70
59
 
71
- params[:ruby_version] = `ruby -v`.match(/^ruby ([\d\.]+)/)[1]
60
+ # Prompt for accepting license
61
+ content = File.open(File.join(File.dirname(__FILE__), "..", License::FILE_NAME)) do |file|
62
+ file.read
63
+ end
64
+ say content
65
+ license_accepted = ask(Text::Prompt::LICENSE_AGREEMENT)
66
+ return unless license_accepted.downcase == Text::Prompt::Response::AGREE_TO_LICENSE.downcase
72
67
 
73
- call_api(:post, SUITES_PATH, {:suite => params}) do |api_response|
74
- # Manage git
75
- `git remote rm #{GIT_REMOTE_NAME}`
76
- `git remote add #{GIT_REMOTE_NAME} #{tddium_git_repo_uri(params[:suite_name])}`
77
- git_push
68
+ api_result = call_api(:post, Api::Path::USERS, {:user => params}, false, false) do |api_response|
69
+ write_api_key(api_response["user"]["api_key"])
70
+ say Text::Process::ACCOUNT_CREATED % [api_response["user"]["email"], api_response["user"]["recurly_url"]]
71
+ end
72
+ say((api_result.api_status == Api::ErrorCode::INVALID_INVITATION) ? Text::Error::INVALID_INVITATION : api_result.message) unless api_result.success?
73
+ end
74
+ end
78
75
 
79
- # Save the created suite
80
- branches = tddium_settings["branches"] || {}
81
- branches.merge!({current_git_branch => api_response["suite"]["id"]})
82
- File.open(".tddium", "w") do |file|
83
- file.write(tddium_settings.merge({:branches => branches}).to_json)
76
+ desc "login", "Log in to tddium using your email address and password"
77
+ method_option :environment, :type => :string, :default => nil
78
+ method_option :email, :type => :string, :default => nil
79
+ method_option :password, :type => :string, :default => nil
80
+ def login
81
+ set_default_environment(options[:environment])
82
+ if user_logged_in?
83
+ say Text::Process::ALREADY_LOGGED_IN
84
+ else
85
+ login_user(:params => get_user_credentials(options), :show_error => true) do
86
+ say Text::Process::LOGGED_IN_SUCCESSFULLY
84
87
  end
85
88
  end
86
89
  end
87
90
 
91
+ desc "logout", "Log out of tddium"
92
+ method_option :environment, :type => :string, :default => nil
93
+ def logout
94
+ set_default_environment(options[:environment])
95
+ FileUtils.rm(tddium_file_name) if File.exists?(tddium_file_name)
96
+ say Text::Process::LOGGED_OUT_SUCCESSFULLY
97
+ end
98
+
88
99
  desc "spec", "Run the test suite"
100
+ method_option :environment, :type => :string, :default => nil
89
101
  def spec
90
- start_time = Time.now
102
+ set_default_environment(options[:environment])
103
+ return unless git_repo? && tddium_settings && suite_for_current_branch?
91
104
 
92
- return unless git_repo? && tddium_settings
93
- suite_id = tddium_settings["branches"][current_git_branch]
105
+ start_time = Time.now
94
106
 
95
107
  # Push the latest code to git
96
- git_push
108
+ return unless git_push
97
109
 
98
110
  # Call the API to get the suite and its tests
99
- call_api(:get, "#{SUITES_PATH}/#{suite_id}") do |api_response|
111
+ call_api(:get, current_suite_path) do |api_response|
100
112
  test_pattern = api_response["suite"]["test_pattern"]
101
113
  test_files = Dir.glob(test_pattern).collect {|file_path| {:test_name => file_path}}
102
114
 
103
115
  # Create a session
104
- call_api(:post, SESSIONS_PATH) do |api_response|
116
+ call_api(:post, Api::Path::SESSIONS) do |api_response|
105
117
  session_id = api_response["session"]["id"]
106
118
 
107
119
  # Call the API to register the tests
108
- call_api(:post, "#{SESSIONS_PATH}/#{session_id}/#{REGISTER_TEST_EXECUTIONS_PATH}", {:suite_id => suite_id, :tests => test_files}) do |api_response|
120
+ call_api(:post, "#{Api::Path::SESSIONS}/#{session_id}/#{Api::Path::REGISTER_TEST_EXECUTIONS}", {:suite_id => current_suite_id, :tests => test_files}) do |api_response|
109
121
  # Start the tests
110
- call_api(:post, "#{SESSIONS_PATH}/#{session_id}/#{START_TEST_EXECUTIONS_PATH}") do |api_response|
122
+ call_api(:post, "#{Api::Path::SESSIONS}/#{session_id}/#{Api::Path::START_TEST_EXECUTIONS}") do |api_response|
111
123
  tests_not_finished_yet = true
112
124
  finished_tests = {}
113
125
  test_statuses = Hash.new(0)
114
126
  api_call_successful = true
115
- say TERMINATE_PROCESS_INSTRUCTIONS
127
+ get_test_executions_response = {}
128
+
129
+ say Text::Process::STARTING_TEST % test_files.size
130
+ say Text::Process::TERMINATE_INSTRUCTION
116
131
  while tests_not_finished_yet && api_call_successful do
117
132
  # Poll the API to check the status
118
- api_call_successful = call_api(:get, "#{SESSIONS_PATH}/#{session_id}/#{TEST_EXECUTIONS_PATH}") do |api_response|
133
+ call_api_result = call_api(:get, "#{Api::Path::SESSIONS}/#{session_id}/#{Api::Path::TEST_EXECUTIONS}") do |api_response|
134
+ # Catch Ctrl-C to interrupt the test
119
135
  Signal.trap(:INT) do
120
- say INTERRUPT_TEXT
136
+ say Text::Process::INTERRUPT
137
+ say Text::Process::CHECK_TEST_STATUS
121
138
  tests_not_finished_yet = false
122
139
  end
140
+
123
141
  # Print out the progress of running tests
124
142
  api_response["tests"].each do |test_name, result_params|
125
143
  test_status = result_params["status"]
126
144
  if result_params["end_time"] && !finished_tests[test_name]
127
145
  message = case test_status
128
- when "passed" then [".", :green]
129
- when "failed" then ["F", :red]
130
- when "error" then ["E"]
131
- when "pending" then ["*", :yellow]
132
- end
146
+ when "passed" then [".", :green, false]
147
+ when "failed" then ["F", :red, false]
148
+ when "error" then ["E", nil, false]
149
+ when "pending" then ["*", :yellow, false]
150
+ end
133
151
  finished_tests[test_name] = test_status
134
152
  test_statuses[test_status] += 1
135
- say message[0], message[1]
153
+ say *message
136
154
  end
137
155
  end
138
156
 
157
+ # save response for later use
158
+ get_test_executions_response = api_response
159
+
139
160
  # If all tests finished, exit the loop else sleep
140
- finished_tests.size == api_response["tests"].size ? tests_not_finished_yet = false : sleep(SLEEP_TIME_BETWEEN_POLLS)
161
+ if finished_tests.size == api_response["tests"].size
162
+ tests_not_finished_yet = false
163
+ else
164
+ sleep(Default::SLEEP_TIME_BETWEEN_POLLS)
165
+ end
141
166
  end
167
+ api_call_successful = call_api_result.success?
142
168
  end
143
169
 
144
170
  # Print out the result
145
- say "Finished in #{Time.now - start_time} seconds"
171
+ say Text::Process::FINISHED_TEST % (Time.now - start_time)
146
172
  say "#{finished_tests.size} examples, #{test_statuses["failed"]} failures, #{test_statuses["error"]} errors, #{test_statuses["pending"]} pending"
147
- say "You can check out the test report details at #{api_response["report"]}"
173
+ say Text::Process::CHECK_TEST_REPORT % get_test_executions_response["report"]
148
174
  end
149
175
  end
150
176
  end
151
177
  end
152
178
  end
153
179
 
154
- private
180
+ desc "status", "Display information about this suite, and any open dev sessions"
181
+ method_option :environment, :type => :string, :default => nil
182
+ def status
183
+ set_default_environment(options[:environment])
184
+ return unless git_repo? && tddium_settings && suite_for_current_branch?
185
+
186
+ call_api(:get, Api::Path::SUITES) do |api_response|
187
+ if api_response["suites"].size == 0
188
+ say Text::Status::NO_SUITE
189
+ else
190
+ say Text::Status::ALL_SUITES % api_response["suites"].collect {|suite| suite["repo_name"]}.join(", ")
191
+
192
+ if current_suite = api_response["suites"].detect {|suite| suite["id"] == current_suite_id}
193
+ say Text::Status::SEPARATOR
194
+ say Text::Status::CURRENT_SUITE % current_suite["repo_name"]
155
195
 
156
- def call_api(method, api_path, params = {}, &block)
157
- headers = { API_KEY_HEADER => tddium_settings(false)["api_key"] } if tddium_settings(false) && tddium_settings(false)["api_key"]
158
- done = false
159
- tries = 0
160
- while tries < 5 && !done
161
- begin
162
- http = HTTParty.send(method, tddium_uri(api_path), :body => params, :headers => headers)
163
- done = true
164
- rescue Timeout::Error
165
- ensure
166
- tries += 5
196
+ display_attributes(DisplayedAttributes::SUITE, current_suite)
197
+
198
+ show_session_details({:active => true}, Text::Status::NO_ACTIVE_SESSION, Text::Status::ACTIVE_SESSIONS)
199
+ show_session_details({:active => false, :order => "date", :limit => 10}, Text::Status::NO_INACTIVE_SESSION, Text::Status::INACTIVE_SESSIONS)
200
+ else
201
+ say Text::Status::CURRENT_SUITE_UNAVAILABLE
202
+ end
167
203
  end
168
204
  end
205
+ end
169
206
 
170
- response = JSON.parse(http.body) rescue {}
207
+ desc "suite", "Register the suite for this project, or manage its settings"
208
+ method_option :test_pattern, :type => :string, :default => nil
209
+ method_option :name, :type => :string, :default => nil
210
+ method_option :environment, :type => :string, :default => nil
211
+ def suite
212
+ set_default_environment(options[:environment])
213
+ return unless git_repo? && tddium_settings
171
214
 
172
- if http.success?
173
- if response["status"] == 0
174
- yield response
175
- else
176
- message = "An error occured: #{response["explanation"]}"
215
+ params = {}
216
+ if current_suite_id
217
+ call_api(:get, current_suite_path) do |api_response|
218
+ # Get the current test pattern and prompt for updates
219
+ params[:test_pattern] = prompt(Text::Prompt::TEST_PATTERN, options[:test_pattern], api_response["suite"]["test_pattern"])
220
+
221
+ # Update the current suite if it exists already
222
+ call_api(:put, current_suite_path, {:suite => params}) do |api_response|
223
+ say Text::Process::UPDATE_SUITE
224
+ end
177
225
  end
178
226
  else
179
- message = "An error occured: #{http.response.header.msg}"
180
- message << " #{response["explanation"]}" if response["status"].to_i > 0
227
+ params[:branch] = current_git_branch
228
+ default_suite_name = File.basename(Dir.pwd)
229
+ params[:repo_name] = options[:name] || default_suite_name
230
+
231
+ existing_suite = nil
232
+ use_existing_suite = false
233
+ suite_name_resolved = false
234
+ api_call_successful = true
235
+ while !suite_name_resolved && api_call_successful
236
+ # Check to see if there is an existing suite
237
+ api_call_successful = call_api(:get, Api::Path::SUITES, params) do |api_response|
238
+ existing_suite = api_response["suites"].first
239
+
240
+ # Get the suite name
241
+ current_suite_name = params[:repo_name]
242
+ if existing_suite
243
+ # Prompt for using existing suite (unless suite name is passed from command line) or entering new one
244
+ params[:repo_name] = prompt(Text::Prompt::USE_EXISTING_SUITE, options[:name], current_suite_name)
245
+ if options[:name] || params[:repo_name] == Text::Prompt::Response::YES
246
+ # Use the existing suite, so assign the value back and exit the loop
247
+ params[:repo_name] = current_suite_name
248
+ use_existing_suite = true
249
+ suite_name_resolved = true
250
+ end
251
+ elsif current_suite_name == default_suite_name
252
+ # Prompt for using default suite name or entering new one
253
+ params[:repo_name] = prompt(Text::Prompt::SUITE_NAME, options[:name], current_suite_name)
254
+ suite_name_resolved = true if params[:repo_name] == default_suite_name
255
+ else
256
+ # Suite name does not exist yet and already prompted
257
+ suite_name_resolved = true
258
+ end
259
+ end.success?
260
+ end
261
+
262
+ if api_call_successful
263
+ if use_existing_suite
264
+ # Write to file and exit when using the existing suite
265
+ write_suite(existing_suite["id"])
266
+ say Text::Status::USING_SUITE % [existing_suite["repo_name"], existing_suite["branch"]]
267
+ return
268
+ end
269
+
270
+ params[:ruby_version] = dependency_version(:ruby)
271
+ params[:bundler_version] = dependency_version(:bundle)
272
+ params[:rubygems_version] = dependency_version(:gem)
273
+
274
+ params[:test_pattern] = prompt(Text::Prompt::TEST_PATTERN, options[:test_pattern], Default::TEST_PATTERN)
275
+
276
+ # Create new suite if it does not exist yet
277
+ call_api(:post, Api::Path::SUITES, {:suite => params}) do |api_response|
278
+ # Save the created suite
279
+ write_suite(api_response["suite"]["id"])
280
+
281
+ # Manage git
282
+ `git remote rm #{Git::REMOTE_NAME}`
283
+ `git remote add #{Git::REMOTE_NAME} #{api_response["suite"]["git_repo_uri"]}`
284
+ git_push
285
+ end
286
+ end
181
287
  end
182
- say message if message
183
- message.nil?
288
+ end
289
+
290
+ private
291
+
292
+ def call_api(method, api_path, params = {}, api_key = nil, show_error = true, &block)
293
+ api_key = tddium_settings(:fail_with_message => false)["api_key"] if tddium_settings(:fail_with_message => false) && api_key != false
294
+ api_status, http_status, error_message = tddium_client.call_api(method, api_path, params, api_key, &block)
295
+ say error_message if error_message && show_error
296
+ response = Struct.new(:api_status, :http_status, :message) do
297
+ def success?
298
+ self.api_status.to_i.zero?
299
+ end
300
+ end
301
+ response.new(api_status, http_status, error_message)
302
+ end
303
+
304
+ def current_git_branch
305
+ @current_git_branch ||= File.basename(`git symbolic-ref HEAD`.gsub("\n", ""))
306
+ end
307
+
308
+ def current_suite_id
309
+ tddium_settings["branches"][current_git_branch] if tddium_settings["branches"]
310
+ end
311
+
312
+ def current_suite_path
313
+ "#{Api::Path::SUITES}/#{current_suite_id}"
314
+ end
315
+
316
+ def dependency_version(command)
317
+ `#{command} -v`.match(Dependency::VERSION_REGEXP)[1]
318
+ end
319
+
320
+ def display_attributes(names_to_display, attributes)
321
+ names_to_display.each do |attr|
322
+ say Text::Status::ATTRIBUTE_DETAIL % [attr.gsub("_", " ").capitalize, attributes[attr]] if attributes[attr]
323
+ end
324
+ end
325
+
326
+ def environment
327
+ tddium_client.environment
328
+ end
329
+
330
+ def get_user(&block)
331
+ call_api(:get, Api::Path::USERS, {}, nil, false, &block)
332
+ end
333
+
334
+ def get_user_credentials(options = {})
335
+ params = {}
336
+ # prompt for email/invitation and password
337
+ if options[:invited]
338
+ params[:invitation_token] = options[:invitation_token] || ask(Text::Prompt::INVITATION_TOKEN)
339
+ else
340
+ params[:email] = options[:email] || ask(Text::Prompt::EMAIL)
341
+ end
342
+ params[:password] = options[:password] || HighLine.ask(Text::Prompt::PASSWORD) { |q| q.echo = "*" }
343
+ params
184
344
  end
185
345
 
186
346
  def git_push
187
- `git push #{GIT_REMOTE_NAME} #{current_git_branch}`
347
+ system("git push #{Git::REMOTE_NAME} #{current_git_branch}")
188
348
  end
189
349
 
190
- def tddium_uri(path, api_version = API_VERSION)
191
- URI.join(API_HOST, "#{api_version}/#{path}").to_s
350
+ def git_repo?
351
+ unless File.exists?(".git")
352
+ message = Text::Error::GIT_NOT_INITIALIZED
353
+ say message
354
+ end
355
+ message.nil?
192
356
  end
193
357
 
194
- def tddium_git_repo_uri(suite_name)
195
- repo_name = suite_name.split("/").first
196
- git_uri = URI.parse(API_HOST)
197
- git_uri.scheme = GIT_REMOTE_SCHEME
198
- git_uri.userinfo = GIT_REMOTE_USER
199
- git_uri.path = "#{GIT_REMOTE_ABSOLUTE_PATH}/#{repo_name}"
200
- git_uri.to_s
358
+ def login_user(options = {}, &block)
359
+ # POST (email, password) to /users/sign_in to retrieve an API key
360
+ login_result = call_api(:post, Api::Path::SIGN_IN, {:user => options[:params]}, false, options[:show_error]) do |api_response|
361
+ # On success, write the API key to "~/.tddium.<environment>"
362
+ write_api_key(api_response["api_key"])
363
+ yield api_response if block_given?
364
+ end
365
+ login_result
201
366
  end
202
367
 
203
- def current_git_branch
204
- @current_git_branch ||= File.basename(`git symbolic-ref HEAD`.gsub("\n", ""))
368
+ def prompt(text, current_value, default_value)
369
+ value = current_value || ask(text % default_value)
370
+ value.empty? ? default_value : value
371
+ end
372
+
373
+ def set_default_environment(env)
374
+ if env.nil?
375
+ tddium_client.environment = :development
376
+ tddium_client.environment = :production unless File.exists?(tddium_file_name)
377
+ else
378
+ tddium_client.environment = env.to_sym
379
+ end
380
+ end
381
+
382
+ def show_session_details(params, no_session_prompt, all_session_prompt)
383
+ call_api(:get, Api::Path::SESSIONS, params) do |api_response|
384
+ say Text::Status::SEPARATOR
385
+ if api_response["sessions"].size == 0
386
+ say no_session_prompt
387
+ else
388
+ say all_session_prompt
389
+ api_response["sessions"].each do |session|
390
+ session_id = session["id"]
391
+ say Text::Status::SESSION_TITLE % session_id
392
+ call_api(:get, "#{Api::Path::SESSIONS}/#{session_id}/#{Api::Path::TEST_EXECUTIONS}") do |api_response|
393
+ display_attributes(DisplayedAttributes::TEST_EXECUTION, api_response)
394
+ end
395
+ end
396
+ end
397
+ end
398
+ end
399
+
400
+ def show_user_details(api_response)
401
+ # Given the user is logged in, she should be able to use "tddium account" to display information about her account:
402
+ # Email address
403
+ # Account creation date
404
+ say api_response["user"]["email"]
405
+ say api_response["user"]["created_at"]
406
+ say api_response["user"]["recurly_url"]
407
+ end
408
+
409
+ def suite_for_current_branch?
410
+ unless current_suite_id
411
+ message = Text::Error::NO_SUITE_EXISTS % current_git_branch
412
+ say message
413
+ end
414
+ message.nil?
415
+ end
416
+
417
+ def tddium_client
418
+ @tddium_client ||= TddiumClient.new
419
+ end
420
+
421
+ def tddium_file_name
422
+ extension = ".#{environment}" unless environment == :production
423
+ ".tddium#{extension}"
205
424
  end
206
425
 
207
- def tddium_settings(fail_with_message = true)
208
- unless @tddium_settings
209
- if File.exists?(".tddium")
210
- tddium_config = File.open(".tddium") do |file|
426
+ def tddium_settings(options = {})
427
+ options[:fail_with_message] = true unless options[:fail_with_message] == false
428
+ if @tddium_settings.nil? || options[:force_reload]
429
+ if File.exists?(tddium_file_name)
430
+ tddium_config = File.open(tddium_file_name) do |file|
211
431
  file.read
212
432
  end
213
433
  @tddium_settings = JSON.parse(tddium_config) rescue nil
214
- say INVALID_TDDIUM_FILE if @tddium_settings.nil? && fail_with_message
434
+ say (Text::Error::INVALID_TDDIUM_FILE % environment) if @tddium_settings.nil? && options[:fail_with_message]
215
435
  else
216
- say NOT_INITIALIZED_ERROR if fail_with_message
436
+ say Text::Error::NOT_INITIALIZED if options[:fail_with_message]
217
437
  end
218
438
  end
219
439
  @tddium_settings
220
440
  end
221
441
 
222
- def git_repo?
223
- unless File.exists?(".git")
224
- message = "git repo must be initialized. Try 'git init'."
225
- say message
442
+ def user_logged_in?(active = true, &block)
443
+ result = tddium_settings(:fail_with_message => false) && tddium_settings["api_key"]
444
+ (result && active) ? get_user(&block).success? : result
445
+ end
446
+
447
+ def write_api_key(api_key)
448
+ settings = tddium_settings(:fail_with_message => false) || {}
449
+ File.open(tddium_file_name, "w") do |file|
450
+ file.write(settings.merge({"api_key" => api_key}).to_json)
226
451
  end
227
- message.nil?
228
452
  end
453
+
454
+ def write_suite(suite_id)
455
+ branches = tddium_settings["branches"] || {}
456
+ branches.merge!({current_git_branch => suite_id})
457
+ File.open(tddium_file_name, "w") do |file|
458
+ file.write(tddium_settings.merge({"branches" => branches}).to_json)
459
+ end
460
+ end
461
+
229
462
  end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,10 @@
1
+ =begin
2
+ Copyright (c) 2011 Solano Labs All Rights Reserved
3
+ =end
4
+
5
+ require 'simplecov'
6
+ SimpleCov.start
1
7
  require "tddium"
2
- require "fakeweb"
3
- require "rack/test"
8
+ require 'rspec'
4
9
  require "fakefs/spec_helpers"
5
- FakeWeb.allow_net_connect = false
6
-
7
- def fixture_path(fixture_name)
8
- File.join File.dirname(__FILE__), "fixtures", fixture_name
9
- end
10
+ require "tddium_client/tddium_spec_helpers"