tddium-preview 0.0.1 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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"