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/.gitignore +2 -0
- data/CHANGELOG +4 -0
- data/Gemfile.lock +45 -0
- data/LICENSE.txt +12 -1
- data/README.rdoc +1 -3
- data/Rakefile +31 -0
- data/bin/tddium +2 -4
- data/lib/tddium/constant.rb +124 -0
- data/lib/tddium/version.rb +6 -2
- data/lib/tddium.rb +349 -116
- data/spec/spec_helper.rb +8 -7
- data/spec/tddium_spec.rb +812 -247
- data/tddium.gemspec +10 -5
- metadata +31 -35
- data/doc/aws-keypair-example.tiff +0 -0
- data/doc/aws-secgroup-example.tiff +0 -0
- data/spec/fixtures/get_suites_200.json +0 -13
- data/spec/fixtures/get_test_executions_200.json +0 -13
- data/spec/fixtures/get_test_executions_200_all_finished.json +0 -13
- data/spec/fixtures/post_register_test_executions_200.json +0 -14
- data/spec/fixtures/post_register_test_executions_200_json_status_1.json +0 -14
- data/spec/fixtures/post_sessions_201.json +0 -13
- data/spec/fixtures/post_start_test_executions_200.json +0 -14
- data/spec/fixtures/post_suites_201.json +0 -13
- data/spec/fixtures/post_suites_201_json_status_1.json +0 -13
- data/spec/fixtures/post_suites_409.json +0 -13
data/lib/tddium.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
=begin
|
2
|
-
Copyright (c)
|
2
|
+
Copyright (c) 2011 Solano Labs All Rights Reserved
|
3
3
|
=end
|
4
4
|
|
5
5
|
require "rubygems"
|
6
6
|
require "thor"
|
7
|
-
require "
|
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
|
-
|
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
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
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
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
-
|
102
|
+
set_default_environment(options[:environment])
|
103
|
+
return unless git_repo? && tddium_settings && suite_for_current_branch?
|
91
104
|
|
92
|
-
|
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,
|
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,
|
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, "#{
|
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, "#{
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
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
|
-
|
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
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
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
|
-
|
180
|
-
|
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
|
-
|
183
|
-
|
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
|
-
|
347
|
+
system("git push #{Git::REMOTE_NAME} #{current_git_branch}")
|
188
348
|
end
|
189
349
|
|
190
|
-
def
|
191
|
-
|
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
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
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
|
204
|
-
|
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(
|
208
|
-
unless
|
209
|
-
|
210
|
-
|
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
|
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
|
223
|
-
|
224
|
-
|
225
|
-
|
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
|
3
|
-
require "rack/test"
|
8
|
+
require 'rspec'
|
4
9
|
require "fakefs/spec_helpers"
|
5
|
-
|
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"
|