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/spec/tddium_spec.rb
CHANGED
@@ -1,100 +1,156 @@
|
|
1
|
+
=begin
|
2
|
+
#foo
|
3
|
+
Copyright (c) 2011 Solano Labs All Rights Reserved
|
4
|
+
=end
|
5
|
+
|
1
6
|
require 'spec_helper'
|
2
7
|
|
3
|
-
# TODO: Test what happens if an error occurs in the POST and GET requests
|
4
8
|
describe Tddium do
|
5
9
|
include FakeFS::SpecHelpers
|
10
|
+
include TddiumSpecHelpers
|
11
|
+
|
12
|
+
SAMPLE_API_KEY = "afb12412bdafe124124asfasfabebafeabwbawf1312342erbfasbb"
|
13
|
+
SAMPLE_APP_NAME = "tddelicious"
|
14
|
+
SAMPLE_BRANCH_NAME = "test"
|
15
|
+
SAMPLE_BUNDLER_VERSION = "1.10.10"
|
16
|
+
SAMPLE_CALL_API_RESPONSE = [0, 200, nil]
|
17
|
+
SAMPLE_CALL_API_ERROR = [1, 501, "an error"]
|
18
|
+
SAMPLE_DATE_TIME = "2011-03-11T08:43:02Z"
|
19
|
+
SAMPLE_EMAIL = "someone@example.com"
|
20
|
+
SAMPLE_INVITATION_TOKEN = "TZce3NueiXp2lMTmaeRr"
|
21
|
+
SAMPLE_GIT_REPO_URI = "ssh://git@api.tddium.com/home/git/repo/#{SAMPLE_APP_NAME}"
|
22
|
+
SAMPLE_LICENSE_TEXT = "LICENSE"
|
23
|
+
SAMPLE_PASSWORD = "foobar"
|
24
|
+
SAMPLE_REPORT_URL = "http://api.tddium.com/1/sessions/1/test_executions/report"
|
25
|
+
SAMPLE_RUBYGEMS_VERSION = "1.3.7"
|
26
|
+
SAMPLE_RUBY_VERSION = "1.8.7"
|
27
|
+
SAMPLE_RECURLY_URL = "https://tddium.recurly.com/account/1"
|
28
|
+
SAMPLE_SESSION_ID = 1
|
29
|
+
SAMPLE_SUITE_ID = 1
|
30
|
+
SAMPLE_SUITES_RESPONSE = {"suites" => [{"repo_name" => SAMPLE_APP_NAME, "branch" => SAMPLE_BRANCH_NAME, "id" => SAMPLE_SUITE_ID}]}
|
31
|
+
SAMPLE_TDDIUM_CONFIG_FILE = ".tddium.test"
|
32
|
+
SAMPLE_TEST_PATTERN = "**/*_spec.rb"
|
33
|
+
SAMPLE_USER_RESPONSE = {"user"=> {"api_key" => SAMPLE_API_KEY, "email" => SAMPLE_EMAIL, "created_at" => SAMPLE_DATE_TIME, "recurly_url" => SAMPLE_RECURLY_URL}}
|
34
|
+
|
35
|
+
def call_api_should_receive(options = {})
|
36
|
+
params = [options[:method] || anything, options[:path] || anything, options[:params] || anything, (options[:api_key] || options[:api_key] == false) ? options[:api_key] : anything]
|
37
|
+
tddium_client.stub(:call_api).with(*params) # To prevent the yield
|
38
|
+
tddium_client.should_receive(:call_api).with(*params).and_return(SAMPLE_CALL_API_ERROR)
|
39
|
+
end
|
6
40
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
41
|
+
def extract_options!(array, *option_keys)
|
42
|
+
is_options = false
|
43
|
+
option_keys.each do |option_key|
|
44
|
+
is_options ||= array.last.include?(option_key.to_sym)
|
45
|
+
end
|
46
|
+
(array.last.is_a?(Hash) && is_options) ? array.pop : {}
|
47
|
+
end
|
13
48
|
|
14
|
-
def run(tddium)
|
15
|
-
send("run_#{example.example_group.ancestors.map(&:description)[-2][1..-1]}", tddium)
|
49
|
+
def run(tddium, options = {:environment => "test"})
|
50
|
+
send("run_#{example.example_group.ancestors.map(&:description)[-2][1..-1]}", tddium, options)
|
16
51
|
end
|
17
52
|
|
18
|
-
|
19
|
-
tddium
|
53
|
+
[:suite, :spec, :status, :account, :login, :logout].each do |method|
|
54
|
+
define_method("run_#{method}") do |tddium, *params|
|
55
|
+
options = params.first || {}
|
56
|
+
options[:environment] = "test" unless options.has_key?(:environment)
|
57
|
+
stub_cli_options(tddium, options)
|
58
|
+
tddium.send(method)
|
59
|
+
end
|
20
60
|
end
|
21
61
|
|
22
|
-
def
|
23
|
-
tddium.
|
62
|
+
def stub_bundler_version(tddium, version = SAMPLE_BUNDLER_VERSION)
|
63
|
+
tddium.stub(:`).with("bundle -v").and_return("Bundler version #{version}")
|
24
64
|
end
|
25
65
|
|
26
|
-
def
|
27
|
-
|
66
|
+
def stub_call_api_response(method, path, *response)
|
67
|
+
options = extract_options!(response, :and_return, :and_yield)
|
68
|
+
options[:and_yield] = true unless options[:and_yield] == false
|
69
|
+
result = tddium_client.stub(:call_api).with(method, path, anything, anything)
|
70
|
+
result = result.and_yield(response.first) if options[:and_yield]
|
71
|
+
result.and_return(options[:and_return] || SAMPLE_CALL_API_ERROR)
|
72
|
+
response.each_with_index do |current_response, index|
|
73
|
+
result = result.and_yield(current_response) unless index.zero? || !options[:and_yield]
|
74
|
+
end
|
28
75
|
end
|
29
76
|
|
30
|
-
def
|
31
|
-
|
77
|
+
def stub_cli_options(tddium, options = {})
|
78
|
+
tddium.stub(:options).and_return(options)
|
32
79
|
end
|
33
80
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
81
|
+
def stub_config_file(options = {})
|
82
|
+
params = {}
|
83
|
+
params.merge!(:branches => (options[:branches].is_a?(Hash)) ? options[:branches] : {SAMPLE_BRANCH_NAME => SAMPLE_SUITE_ID}) if options[:branches]
|
84
|
+
params.merge!(:api_key => (options[:api_key].is_a?(String)) ? options[:api_key] : SAMPLE_API_KEY) if options[:api_key]
|
85
|
+
json = params.to_json unless params.empty?
|
86
|
+
create_file(SAMPLE_TDDIUM_CONFIG_FILE, json)
|
37
87
|
end
|
38
88
|
|
39
|
-
def
|
40
|
-
|
89
|
+
def stub_default_suite_name
|
90
|
+
Dir.stub(:pwd).and_return(SAMPLE_APP_NAME)
|
91
|
+
end
|
92
|
+
|
93
|
+
def stub_defaults
|
94
|
+
tddium.stub(:say)
|
95
|
+
stub_git_branch(tddium)
|
96
|
+
stub_tddium_client
|
97
|
+
create_file(File.join(".git", "something"), "something")
|
41
98
|
end
|
42
99
|
|
43
|
-
def stub_git_branch(tddium, default_branch_name =
|
100
|
+
def stub_git_branch(tddium, default_branch_name = SAMPLE_BRANCH_NAME)
|
44
101
|
tddium.stub(:`).with("git symbolic-ref HEAD").and_return(default_branch_name)
|
45
102
|
end
|
46
103
|
|
47
|
-
def
|
48
|
-
|
104
|
+
def stub_git_push(tddium, success = true)
|
105
|
+
tddium.stub(:system).with(/^git push/).and_return(success)
|
49
106
|
end
|
50
107
|
|
51
|
-
def
|
52
|
-
|
53
|
-
File.open(path, 'w') do |f|
|
54
|
-
f.write(content)
|
55
|
-
end
|
108
|
+
def stub_ruby_version(tddium, version = SAMPLE_RUBY_VERSION)
|
109
|
+
tddium.stub(:`).with("ruby -v").and_return("ruby #{version} (2010-08-16 patchlevel 302) [i686-darwin10.5.0]")
|
56
110
|
end
|
57
111
|
|
58
|
-
def
|
59
|
-
|
60
|
-
options_array = []
|
61
|
-
options.each do |sub_options|
|
62
|
-
options_array << register_uri_options(sub_options)
|
63
|
-
end
|
64
|
-
options_array
|
65
|
-
else
|
66
|
-
options_for_fake_web = {:body => options[:body], :status => options[:status]}
|
67
|
-
if options[:response]
|
68
|
-
FakeFS.deactivate!
|
69
|
-
response = File.open(options[:response]) { |f| f.read }
|
70
|
-
FakeFS.activate!
|
71
|
-
options_for_fake_web.merge!(:response => response)
|
72
|
-
end
|
73
|
-
options_for_fake_web
|
74
|
-
end
|
112
|
+
def stub_rubygems_version(tddium, version = SAMPLE_RUBYGEMS_VERSION)
|
113
|
+
tddium.stub(:`).with("gem -v").and_return(version)
|
75
114
|
end
|
76
115
|
|
77
|
-
def
|
78
|
-
|
116
|
+
def stub_sleep(tddium)
|
117
|
+
tddium.stub(:sleep).with(Tddium::Default::SLEEP_TIME_BETWEEN_POLLS)
|
79
118
|
end
|
80
119
|
|
81
|
-
def
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
create_file(".git/something", "something")
|
86
|
-
create_file(".tddium", {:branches => {DEFAULT_BRANCH_NAME => DEFAULT_SUITE_ID}, :api_key => DEFAULT_API_KEY}.to_json)
|
120
|
+
def stub_tddium_client
|
121
|
+
TddiumClient.stub(:new).and_return(tddium_client)
|
122
|
+
tddium_client.stub(:environment).and_return(:test)
|
123
|
+
tddium_client.stub(:call_api).and_return(SAMPLE_CALL_API_ERROR)
|
87
124
|
end
|
88
125
|
|
89
|
-
|
90
|
-
|
126
|
+
let(:tddium) { Tddium.new }
|
127
|
+
let(:tddium_client) { mock(TddiumClient).as_null_object }
|
128
|
+
|
129
|
+
|
130
|
+
shared_examples_for "a password prompt" do
|
131
|
+
context "--password was not passed in" do
|
132
|
+
it "should prompt for a password or confirmation" do
|
133
|
+
highline = mock(HighLine)
|
134
|
+
HighLine.should_receive(:ask).with(password_prompt).and_yield(highline)
|
135
|
+
highline.should_receive(:echo=).with("*")
|
136
|
+
run(tddium)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
context "--password was passed in" do
|
140
|
+
it "should not prompt for a password or confirmation" do
|
141
|
+
HighLine.should_not_receive(:ask).with(password_prompt)
|
142
|
+
run(tddium, :password => SAMPLE_PASSWORD)
|
143
|
+
end
|
144
|
+
end
|
91
145
|
end
|
92
146
|
|
93
|
-
|
94
|
-
|
147
|
+
shared_examples_for "an unsuccessful api call" do
|
148
|
+
it "should show the error" do
|
149
|
+
tddium_client.stub(:call_api).and_return(SAMPLE_CALL_API_ERROR)
|
150
|
+
tddium.should_receive(:say).with(SAMPLE_CALL_API_ERROR[2])
|
151
|
+
run(tddium)
|
152
|
+
end
|
95
153
|
end
|
96
|
-
|
97
|
-
let(:tddium) { Tddium.new }
|
98
154
|
|
99
155
|
shared_examples_for "git repo has not been initialized" do
|
100
156
|
context "git repo has not been initialized" do
|
@@ -103,338 +159,453 @@ describe Tddium do
|
|
103
159
|
end
|
104
160
|
|
105
161
|
it "should return git is uninitialized" do
|
106
|
-
tddium.should_receive(:say).with(
|
162
|
+
tddium.should_receive(:say).with(Tddium::Text::Error::GIT_NOT_INITIALIZED)
|
107
163
|
run(tddium)
|
108
164
|
end
|
109
165
|
end
|
110
166
|
end
|
111
167
|
|
112
|
-
shared_examples_for "
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
168
|
+
shared_examples_for "getting the current suite from the API" do
|
169
|
+
it "should send a 'GET' request to '#{Tddium::Api::Path::SUITES}/#{SAMPLE_SUITE_ID}'" do
|
170
|
+
call_api_should_receive(:method => :get, :path => "#{Tddium::Api::Path::SUITES}/#{SAMPLE_SUITE_ID}")
|
171
|
+
run(tddium)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
shared_examples_for "logging in a user" do
|
176
|
+
context "there is a tddium config file with an api key" do
|
177
|
+
before {stub_config_file(:api_key => "some api key")}
|
117
178
|
|
118
|
-
it "should
|
119
|
-
|
179
|
+
it "should send a 'GET' request to '#{Tddium::Api::Path::USERS}'" do
|
180
|
+
call_api_should_receive(:method => :get, :path => /#{Tddium::Api::Path::USERS}$/)
|
120
181
|
run(tddium)
|
121
182
|
end
|
122
183
|
end
|
123
184
|
|
124
|
-
context "
|
125
|
-
|
126
|
-
|
185
|
+
context "the tddium config file is missing or corrupt or the api key is invalid" do
|
186
|
+
context "--email was not passed in" do
|
187
|
+
it "should prompt for the user's email address" do
|
188
|
+
tddium.should_receive(:ask).with(Tddium::Text::Prompt::EMAIL)
|
189
|
+
run(tddium)
|
190
|
+
end
|
127
191
|
end
|
128
192
|
|
129
|
-
|
130
|
-
|
193
|
+
context "--email was passed in" do
|
194
|
+
it "should not prompt for the user's email address" do
|
195
|
+
tddium.should_not_receive(:ask).with(Tddium::Text::Prompt::EMAIL)
|
196
|
+
run(tddium, :email => SAMPLE_EMAIL)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
it_should_behave_like "a password prompt" do
|
201
|
+
let(:password_prompt) {Tddium::Text::Prompt::PASSWORD}
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should try to sign in the user with their email & password" do
|
205
|
+
tddium.stub(:ask).with(Tddium::Text::Prompt::EMAIL).and_return(SAMPLE_EMAIL)
|
206
|
+
HighLine.stub(:ask).with(Tddium::Text::Prompt::PASSWORD).and_return(SAMPLE_PASSWORD)
|
207
|
+
call_api_should_receive(:method => :post, :path => /#{Tddium::Api::Path::SIGN_IN}$/, :params => {:user => {:email => SAMPLE_EMAIL, :password => SAMPLE_PASSWORD}}, :api_key => false)
|
131
208
|
run(tddium)
|
132
209
|
end
|
133
210
|
end
|
211
|
+
|
212
|
+
context "the user logs in successfully with their email and password" do
|
213
|
+
before{stub_call_api_response(:post, Tddium::Api::Path::SIGN_IN, {"api_key" => SAMPLE_API_KEY})}
|
214
|
+
it_should_behave_like "writing the api key to the .tddium file"
|
215
|
+
end
|
134
216
|
end
|
135
217
|
|
136
218
|
shared_examples_for "sending the api key" do
|
137
|
-
it "should
|
219
|
+
it "should call the api with the api key" do
|
220
|
+
call_api_should_receive(:api_key => SAMPLE_API_KEY)
|
138
221
|
run(tddium)
|
139
|
-
FakeWeb.last_request[Tddium::API_KEY_HEADER].should == DEFAULT_API_KEY
|
140
222
|
end
|
141
223
|
end
|
142
224
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
create_file("~/.ssh/id_rsa.pub", "ssh-rsa blah")
|
225
|
+
shared_examples_for "set the default environment" do
|
226
|
+
context "with environment parameter" do
|
227
|
+
it "should should set the environment as the parameter of environment" do
|
228
|
+
tddium_client.should_receive(:environment=).with(:test)
|
229
|
+
run(tddium, :environment => "test")
|
230
|
+
end
|
150
231
|
end
|
151
232
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
233
|
+
context "without environment parameter" do
|
234
|
+
before do
|
235
|
+
FileUtils.rm_rf(".tddium")
|
236
|
+
FileUtils.rm_rf(".tddium.development")
|
237
|
+
tddium_client.stub(:environment).and_return(:development)
|
238
|
+
end
|
156
239
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
end
|
240
|
+
it "should should set the environment as production if the file '.tddium.development' does not exist" do
|
241
|
+
tddium_client.should_receive(:environment=).with(:production)
|
242
|
+
run(tddium, :environment => nil)
|
243
|
+
end
|
162
244
|
|
163
|
-
|
164
|
-
|
165
|
-
|
245
|
+
it "should should set the environment as development if the file '.tddium.development' exists" do
|
246
|
+
create_file(".tddium.development")
|
247
|
+
tddium_client.should_receive(:environment=).with(:development)
|
248
|
+
tddium_client.should_not_receive(:environment=).with(:production)
|
249
|
+
run(tddium, :environment => nil)
|
250
|
+
end
|
166
251
|
end
|
252
|
+
end
|
167
253
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
254
|
+
shared_examples_for "suite has not been initialized" do
|
255
|
+
context ".tddium file is missing" do
|
256
|
+
before do
|
257
|
+
stub_config_file(:api_key => true)
|
258
|
+
end
|
173
259
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
260
|
+
it "should tell the user '#{Tddium::Text::Error::NO_SUITE_EXISTS % SAMPLE_BRANCH_NAME}'" do
|
261
|
+
tddium.should_receive(:say).with(Tddium::Text::Error::NO_SUITE_EXISTS % SAMPLE_BRANCH_NAME)
|
262
|
+
run(tddium)
|
263
|
+
end
|
178
264
|
end
|
265
|
+
end
|
179
266
|
|
180
|
-
|
181
|
-
|
182
|
-
it_should_behave_like "git repo has not been initialized"
|
183
|
-
it_should_behave_like ".tddium file is missing or corrupt"
|
184
|
-
|
185
|
-
context "using defaults" do
|
267
|
+
shared_examples_for ".tddium file is missing or corrupt" do
|
268
|
+
context ".tddium file is missing" do
|
186
269
|
before do
|
187
|
-
|
270
|
+
FileUtils.rm_rf(SAMPLE_TDDIUM_CONFIG_FILE)
|
188
271
|
end
|
189
272
|
|
190
|
-
it "should
|
191
|
-
|
192
|
-
|
193
|
-
"test_pattern" => "**/*_spec.rb")
|
273
|
+
it "should tell the user '#{Tddium::Text::Error::NOT_INITIALIZED}'" do
|
274
|
+
tddium.should_receive(:say).with(Tddium::Text::Error::NOT_INITIALIZED)
|
275
|
+
run(tddium)
|
194
276
|
end
|
195
|
-
|
196
277
|
end
|
197
278
|
|
198
|
-
context "
|
279
|
+
context ".tddium file is corrupt" do
|
199
280
|
before do
|
200
|
-
|
201
|
-
tddium.stub(:options).and_return(
|
202
|
-
:ssh_key => ssh_key_file,
|
203
|
-
:name => "my_suite_name",
|
204
|
-
:test_pattern => "**/*_test.rb"
|
205
|
-
)
|
206
|
-
create_file(ssh_key_file, "ssh-rsa 1234")
|
281
|
+
create_file(SAMPLE_TDDIUM_CONFIG_FILE, "corrupt file")
|
207
282
|
end
|
208
283
|
|
209
|
-
it "should
|
210
|
-
|
211
|
-
|
212
|
-
"test_pattern" => "**/*_test.rb")
|
284
|
+
it "should tell the user '#{Tddium::Text::Error::INVALID_TDDIUM_FILE % 'test'}'" do
|
285
|
+
tddium.should_receive(:say).with(Tddium::Text::Error::INVALID_TDDIUM_FILE % 'test')
|
286
|
+
run(tddium)
|
213
287
|
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
shared_examples_for "writing the api key to the .tddium file" do
|
292
|
+
it "should write the api key to the .tddium file" do
|
293
|
+
run(tddium)
|
294
|
+
tddium_file = File.open(SAMPLE_TDDIUM_CONFIG_FILE) { |file| file.read }
|
295
|
+
JSON.parse(tddium_file)["api_key"].should == SAMPLE_API_KEY
|
296
|
+
end
|
297
|
+
end
|
214
298
|
|
299
|
+
describe "#account" do
|
300
|
+
before do
|
301
|
+
stub_defaults
|
302
|
+
tddium.stub(:ask).and_return("")
|
303
|
+
HighLine.stub(:ask).and_return("")
|
304
|
+
create_file(File.join(File.dirname(__FILE__), "..", Tddium::License::FILE_NAME), SAMPLE_LICENSE_TEXT)
|
305
|
+
create_file(Tddium::Default::SSH_FILE, "ssh-rsa blah")
|
215
306
|
end
|
216
307
|
|
217
|
-
|
308
|
+
it_should_behave_like "set the default environment"
|
309
|
+
|
310
|
+
context "the user is already logged in" do
|
218
311
|
before do
|
219
|
-
|
220
|
-
|
221
|
-
tddium.stub(:ask).with(TEST_PATTERN_PROMPT).and_return("**/*_selenium.rb")
|
222
|
-
tddium.stub(:ask).with(suite_name_prompt).and_return("foobar")
|
223
|
-
stub_default_suite_name(tddium)
|
224
|
-
create_file(ssh_key_file, "ssh-rsa 65431")
|
312
|
+
stub_config_file(:api_key => SAMPLE_API_KEY)
|
313
|
+
stub_call_api_response(:get, Tddium::Api::Path::USERS, SAMPLE_USER_RESPONSE)
|
225
314
|
end
|
226
315
|
|
227
|
-
it "should
|
228
|
-
|
229
|
-
|
230
|
-
"test_pattern" => "**/*_selenium.rb")
|
316
|
+
it "should show the user's email address" do
|
317
|
+
tddium.should_receive(:say).with(SAMPLE_EMAIL)
|
318
|
+
run_account(tddium)
|
231
319
|
end
|
232
|
-
end
|
233
320
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
tddium.stub(:`).with(/^git remote/)
|
238
|
-
stub_git_push(tddium)
|
321
|
+
it "should show the user's account creation date" do
|
322
|
+
tddium.should_receive(:say).with(SAMPLE_DATE_TIME)
|
323
|
+
run_account(tddium)
|
239
324
|
end
|
240
325
|
|
241
|
-
it "should
|
242
|
-
tddium.should_receive(
|
243
|
-
|
326
|
+
it "should show the user's recurly account url" do
|
327
|
+
tddium.should_receive(:say).with(SAMPLE_RECURLY_URL)
|
328
|
+
run_account(tddium)
|
329
|
+
end
|
330
|
+
|
331
|
+
end
|
332
|
+
|
333
|
+
context "the user is not already logged in" do
|
334
|
+
let(:call_api_result) {[403, "Forbidden"]}
|
335
|
+
|
336
|
+
it_should_behave_like "a password prompt" do
|
337
|
+
let(:password_prompt) {Tddium::Text::Prompt::PASSWORD_CONFIRMATION}
|
244
338
|
end
|
245
339
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
340
|
+
context "the user does not confirm their password correctly" do
|
341
|
+
before {HighLine.stub(:ask).with(Tddium::Text::Prompt::PASSWORD_CONFIRMATION).and_return("wrong confirmation")}
|
342
|
+
it "should tell the user '#{Tddium::Text::Process::PASSWORD_CONFIRMATION_INCORRECT}'" do
|
343
|
+
tddium.should_receive(:say).with(Tddium::Text::Process::PASSWORD_CONFIRMATION_INCORRECT)
|
344
|
+
run_account(tddium)
|
345
|
+
end
|
250
346
|
end
|
251
347
|
|
252
|
-
context "
|
348
|
+
context "the user confirms their password correctly" do
|
253
349
|
before do
|
254
|
-
|
350
|
+
HighLine.stub(:ask).with(Tddium::Text::Prompt::PASSWORD).and_return(SAMPLE_PASSWORD)
|
351
|
+
HighLine.stub(:ask).with(Tddium::Text::Prompt::PASSWORD_CONFIRMATION).and_return(SAMPLE_PASSWORD)
|
255
352
|
end
|
256
353
|
|
257
|
-
|
258
|
-
|
259
|
-
|
354
|
+
context "--ssh-key-file is not supplied" do
|
355
|
+
it "should prompt the user for their ssh key file" do
|
356
|
+
tddium.should_receive(:ask).with(Tddium::Text::Prompt::SSH_KEY % Tddium::Default::SSH_FILE)
|
357
|
+
run_account(tddium)
|
358
|
+
end
|
260
359
|
end
|
261
360
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
361
|
+
context "--ssh-key-file is supplied" do
|
362
|
+
it "should not prompt the user for their ssh key file" do
|
363
|
+
tddium.should_not_receive(:ask).with(Tddium::Text::Prompt::SSH_KEY % Tddium::Default::SSH_FILE)
|
364
|
+
run_account(tddium, :ssh_key_file => Tddium::Default::SSH_FILE)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
it "should show the user the license" do
|
369
|
+
tddium.should_receive(:say).with(SAMPLE_LICENSE_TEXT)
|
370
|
+
run_account(tddium)
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should ask the user to accept the license" do
|
374
|
+
tddium.should_receive(:ask).with(Tddium::Text::Prompt::LICENSE_AGREEMENT)
|
375
|
+
run_account(tddium)
|
376
|
+
end
|
377
|
+
|
378
|
+
context "accepting the license" do
|
379
|
+
before do
|
380
|
+
tddium.stub(:ask).with(Tddium::Text::Prompt::LICENSE_AGREEMENT).and_return(Tddium::Text::Prompt::Response::AGREE_TO_LICENSE)
|
381
|
+
tddium.stub(:ask).with(Tddium::Text::Prompt::INVITATION_TOKEN).and_return(SAMPLE_INVITATION_TOKEN)
|
382
|
+
create_file(Tddium::Default::SSH_FILE, "ssh-rsa 1234")
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should send a 'POST' request to '#{Tddium::Api::Path::USERS}' with the user's invitation token, password and ssh key" do
|
386
|
+
call_api_should_receive(:method => :post, :path => /#{Tddium::Api::Path::USERS}$/, :params => {:user => {:invitation_token => SAMPLE_INVITATION_TOKEN, :password => SAMPLE_PASSWORD, :user_git_pubkey => "ssh-rsa 1234"}}, :api_key => false)
|
387
|
+
run_account(tddium)
|
388
|
+
end
|
389
|
+
|
390
|
+
context "'POST #{Tddium::Api::Path::USERS}' is successful" do
|
391
|
+
before{stub_call_api_response(:post, Tddium::Api::Path::USERS, SAMPLE_USER_RESPONSE)}
|
392
|
+
|
393
|
+
it_should_behave_like "writing the api key to the .tddium file"
|
394
|
+
|
395
|
+
it "should show the user '#{Tddium::Text::Process::ACCOUNT_CREATED % [SAMPLE_EMAIL, SAMPLE_RECURLY_URL]}'" do
|
396
|
+
tddium.should_receive(:say).with(Tddium::Text::Process::ACCOUNT_CREATED % [SAMPLE_EMAIL, SAMPLE_RECURLY_URL])
|
397
|
+
run_account(tddium)
|
398
|
+
end
|
399
|
+
end
|
400
|
+
context "'POST #{Tddium::Api::Path::USERS}' is unsuccessful" do
|
401
|
+
|
402
|
+
it_should_behave_like "an unsuccessful api call"
|
403
|
+
|
404
|
+
context "because the invitation is invalid" do
|
405
|
+
before { stub_call_api_response(:post, Tddium::Api::Path::USERS, :and_yield => false, :and_return => [Tddium::Api::ErrorCode::INVALID_INVITATION, 409, "Invitation is invalid"]) }
|
406
|
+
it "should show the user: '#{Tddium::Text::Error::INVALID_INVITATION}'" do
|
407
|
+
tddium.should_receive(:say).with(Tddium::Text::Error::INVALID_INVITATION)
|
408
|
+
run_account(tddium)
|
409
|
+
end
|
410
|
+
end
|
411
|
+
end
|
266
412
|
end
|
267
413
|
end
|
268
414
|
end
|
415
|
+
end
|
416
|
+
|
417
|
+
describe "#login" do
|
418
|
+
before do
|
419
|
+
stub_defaults
|
420
|
+
tddium.stub(:ask).and_return("")
|
421
|
+
HighLine.stub(:ask).and_return("")
|
422
|
+
end
|
423
|
+
|
424
|
+
it_should_behave_like "set the default environment"
|
425
|
+
it_should_behave_like "logging in a user"
|
269
426
|
|
270
|
-
context "
|
427
|
+
context "user is already logged in" do
|
271
428
|
before do
|
272
|
-
|
429
|
+
stub_config_file(:api_key => SAMPLE_API_KEY)
|
430
|
+
stub_call_api_response(:get, Tddium::Api::Path::USERS, :and_yield => false, :and_return => SAMPLE_CALL_API_RESPONSE)
|
273
431
|
end
|
274
432
|
|
275
|
-
it "should
|
276
|
-
tddium.should_receive(:say).with(
|
277
|
-
|
433
|
+
it "should show the user: '#{Tddium::Text::Process::ALREADY_LOGGED_IN}'" do
|
434
|
+
tddium.should_receive(:say).with(Tddium::Text::Process::ALREADY_LOGGED_IN)
|
435
|
+
run_login(tddium)
|
278
436
|
end
|
279
437
|
end
|
280
438
|
|
281
|
-
context "
|
282
|
-
before
|
283
|
-
|
439
|
+
context "the user logs in successfully" do
|
440
|
+
before{stub_call_api_response(:post, Tddium::Api::Path::SIGN_IN, {})}
|
441
|
+
it "should show the user: '#{Tddium::Text::Process::LOGGED_IN_SUCCESSFULLY}'" do
|
442
|
+
tddium.should_receive(:say).with(Tddium::Text::Process::LOGGED_IN_SUCCESSFULLY)
|
443
|
+
run_login(tddium)
|
284
444
|
end
|
445
|
+
end
|
285
446
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
447
|
+
context "the user does not sign in successfully" do
|
448
|
+
it_should_behave_like "an unsuccessful api call"
|
449
|
+
end
|
450
|
+
end
|
290
451
|
|
291
|
-
|
292
|
-
|
293
|
-
stub_http_response(:post, Tddium::SUITES_PATH, :response => fixture_path("post_suites_409.json"))
|
294
|
-
end
|
452
|
+
describe "#logout" do
|
453
|
+
before { tddium.stub(:say) }
|
295
454
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
455
|
+
context ".tddium file exists" do
|
456
|
+
before { stub_config_file }
|
457
|
+
it "should delete the file" do
|
458
|
+
run_logout(tddium)
|
459
|
+
File.should_not be_exists(SAMPLE_TDDIUM_CONFIG_FILE)
|
300
460
|
end
|
461
|
+
end
|
301
462
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
it "should show the HTTP error message" do
|
308
|
-
tddium.should_receive(:say).with(/Internal Server Error$/)
|
309
|
-
run_suite(tddium)
|
310
|
-
end
|
463
|
+
context ".tddium file does not exists" do
|
464
|
+
it "should do nothing" do
|
465
|
+
FileUtils.should_not_receive(:rm)
|
466
|
+
run_logout(tddium)
|
311
467
|
end
|
312
468
|
end
|
469
|
+
|
470
|
+
it "should show the user: '#{Tddium::Text::Process::LOGGED_OUT_SUCCESSFULLY}'" do
|
471
|
+
tddium.should_receive(:say).with(Tddium::Text::Process::LOGGED_OUT_SUCCESSFULLY)
|
472
|
+
run_logout(tddium)
|
473
|
+
end
|
313
474
|
end
|
314
475
|
|
315
476
|
describe "#spec" do
|
316
477
|
before do
|
317
478
|
stub_defaults
|
479
|
+
stub_config_file(:api_key => true, :branches => true)
|
318
480
|
stub_git_push(tddium)
|
319
|
-
stub_http_response(:get, "#{Tddium::SUITES_PATH}/#{DEFAULT_SUITE_ID}")
|
320
481
|
end
|
321
|
-
|
482
|
+
|
483
|
+
it_should_behave_like "set the default environment"
|
322
484
|
it_should_behave_like "git repo has not been initialized"
|
323
485
|
it_should_behave_like ".tddium file is missing or corrupt"
|
486
|
+
it_should_behave_like "suite has not been initialized"
|
324
487
|
|
325
488
|
it "should push the latest code to tddium" do
|
326
|
-
tddium.should_receive(
|
489
|
+
tddium.should_receive(:system).with("git push #{Tddium::Git::REMOTE_NAME} #{SAMPLE_BRANCH_NAME}")
|
327
490
|
run_spec(tddium)
|
328
491
|
end
|
329
492
|
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
493
|
+
context "git push was unsuccessful" do
|
494
|
+
before { stub_git_push(tddium, false) }
|
495
|
+
it "should not try to contact the api" do
|
496
|
+
tddium_client.should_not_receive(:call_api)
|
497
|
+
run_spec(tddium)
|
498
|
+
end
|
334
499
|
end
|
335
500
|
|
501
|
+
it_should_behave_like "getting the current suite from the API"
|
336
502
|
it_should_behave_like "sending the api key"
|
337
503
|
|
338
|
-
context "'GET #{Tddium::
|
504
|
+
context "'GET #{Tddium::Api::Path::SUITES}/#{SAMPLE_SUITE_ID}' is successful" do
|
339
505
|
before do
|
340
|
-
|
341
|
-
|
506
|
+
response = {"suite"=>{"test_pattern"=>SAMPLE_TEST_PATTERN, "id"=>SAMPLE_SUITE_ID, "suite_name"=>"tddium/demo", "ruby_version"=>SAMPLE_RUBY_VERSION}}
|
507
|
+
stub_call_api_response(:get, "#{Tddium::Api::Path::SUITES}/#{SAMPLE_SUITE_ID}", response)
|
342
508
|
create_file("spec/mouse_spec.rb")
|
343
509
|
create_file("spec/cat_spec.rb")
|
344
510
|
create_file("spec/dog_spec.rb")
|
345
511
|
end
|
346
512
|
|
347
|
-
it "should send a 'POST' request to '#{Tddium::
|
513
|
+
it "should send a 'POST' request to '#{Tddium::Api::Path::SESSIONS}'" do
|
514
|
+
call_api_should_receive(:method => :post, :path => Tddium::Api::Path::SESSIONS)
|
348
515
|
run_spec(tddium)
|
349
|
-
FakeWeb.last_request.method.should == "POST"
|
350
|
-
FakeWeb.last_request.path.should =~ /#{Tddium::SESSIONS_PATH}$/
|
351
516
|
end
|
352
517
|
|
353
518
|
it_should_behave_like "sending the api key"
|
354
519
|
|
355
|
-
context "'POST #{Tddium::
|
356
|
-
let(:session_id) {7} # from the fixture 'post_sessions_201.json'
|
520
|
+
context "'POST #{Tddium::Api::Path::SESSIONS}' is successful" do
|
357
521
|
before do
|
358
|
-
|
359
|
-
|
522
|
+
response = {"session"=>{"id"=>SAMPLE_SESSION_ID}}
|
523
|
+
stub_call_api_response(:post, "#{Tddium::Api::Path::SESSIONS}", response)
|
360
524
|
end
|
361
525
|
|
362
|
-
it "should send a 'POST' request to '#{Tddium::
|
526
|
+
it "should send a 'POST' request to '#{Tddium::Api::Path::REGISTER_TEST_EXECUTIONS}'" do
|
527
|
+
call_api_should_receive(:method => :post, :path => /#{Tddium::Api::Path::REGISTER_TEST_EXECUTIONS}$/)
|
363
528
|
run_spec(tddium)
|
364
|
-
FakeWeb.last_request.method.should == "POST"
|
365
|
-
FakeWeb.last_request.path.should =~ /#{Tddium::REGISTER_TEST_EXECUTIONS_PATH}$/
|
366
529
|
end
|
367
530
|
|
368
531
|
it_should_behave_like "sending the api key"
|
369
532
|
|
370
533
|
it "should POST the names of the file names extracted from the suite's test_pattern" do
|
534
|
+
current_dir = Dir.pwd
|
535
|
+
call_api_should_receive(:params => {:suite_id => SAMPLE_SUITE_ID,
|
536
|
+
:tests => [{:test_name => "#{current_dir}/spec/cat_spec.rb"},
|
537
|
+
{:test_name => "#{current_dir}/spec/dog_spec.rb"},
|
538
|
+
{:test_name => "#{current_dir}/spec/mouse_spec.rb"}]})
|
371
539
|
run_spec(tddium)
|
372
|
-
request_params = parse_request_params
|
373
|
-
request_params.should include({"suite_id" => DEFAULT_SUITE_ID})
|
374
|
-
request_params["tests"][0]["test_name"].should =~ /spec\/cat_spec.rb$/
|
375
|
-
request_params["tests"][1]["test_name"].should =~ /spec\/dog_spec.rb$/
|
376
|
-
request_params["tests"][2]["test_name"].should =~ /spec\/mouse_spec.rb$/
|
377
|
-
request_params["tests"].size.should == 3
|
378
540
|
end
|
379
541
|
|
380
|
-
context "'POST #{Tddium::
|
542
|
+
context "'POST #{Tddium::Api::Path::REGISTER_TEST_EXECUTIONS}' is successful" do
|
381
543
|
before do
|
382
|
-
|
383
|
-
|
544
|
+
response = {"added"=>0, "existing"=>1, "errors"=>0, "status"=>0}
|
545
|
+
stub_call_api_response(:post, "#{Tddium::Api::Path::SESSIONS}/#{SAMPLE_SESSION_ID}/#{Tddium::Api::Path::REGISTER_TEST_EXECUTIONS}", response)
|
384
546
|
end
|
385
547
|
|
386
|
-
it "should send a 'POST' request to '#{Tddium::
|
548
|
+
it "should send a 'POST' request to '#{Tddium::Api::Path::START_TEST_EXECUTIONS}'" do
|
549
|
+
call_api_should_receive(:method => :post, :path => /#{Tddium::Api::Path::START_TEST_EXECUTIONS}$/)
|
387
550
|
run_spec(tddium)
|
388
|
-
FakeWeb.last_request.method.should == "POST"
|
389
|
-
FakeWeb.last_request.path.should =~ /#{Tddium::START_TEST_EXECUTIONS_PATH}$/
|
390
551
|
end
|
391
552
|
|
392
553
|
it_should_behave_like "sending the api key"
|
393
554
|
|
394
|
-
context "'POST #{Tddium::
|
555
|
+
context "'POST #{Tddium::Api::Path::START_TEST_EXECUTIONS}' is successful" do
|
556
|
+
let(:get_test_executions_response) { {"report"=>SAMPLE_REPORT_URL, "tests"=>{"spec/mouse_spec.rb"=>{"end_time"=>SAMPLE_DATE_TIME, "status"=>"pending"}, "spec/pig_spec.rb"=>{"end_time"=>nil, "status"=>"started"}, "spec/dog_spec.rb"=>{"end_time"=>SAMPLE_DATE_TIME, "status"=>"failed"}, "spec/cat_spec.rb"=>{"end_time"=>SAMPLE_DATE_TIME, "status"=>"passed"}}} }
|
395
557
|
before do
|
396
|
-
|
397
|
-
|
558
|
+
response = {"started"=>1, "status"=>0}
|
559
|
+
stub_call_api_response(:post, "#{Tddium::Api::Path::SESSIONS}/#{SAMPLE_SESSION_ID}/#{Tddium::Api::Path::START_TEST_EXECUTIONS}", response)
|
398
560
|
end
|
399
561
|
|
400
|
-
it "should tell the user to '#{Tddium::
|
401
|
-
tddium.should_receive(:say).with(Tddium::
|
562
|
+
it "should tell the user to '#{Tddium::Text::Process::TERMINATE_INSTRUCTION}'" do
|
563
|
+
tddium.should_receive(:say).with(Tddium::Text::Process::TERMINATE_INSTRUCTION)
|
402
564
|
run_spec(tddium)
|
403
565
|
end
|
404
566
|
|
405
|
-
it "should
|
567
|
+
it "should tell the user '#{Tddium::Text::Process::STARTING_TEST % 3}'" do
|
568
|
+
tddium.should_receive(:say).with(Tddium::Text::Process::STARTING_TEST % 3)
|
569
|
+
run_spec(tddium)
|
570
|
+
end
|
571
|
+
|
572
|
+
it "should send a 'GET' request to '#{Tddium::Api::Path::TEST_EXECUTIONS}'" do
|
573
|
+
call_api_should_receive(:method => :get, :path => /#{Tddium::Api::Path::TEST_EXECUTIONS}$/)
|
406
574
|
run_spec(tddium)
|
407
|
-
FakeWeb.last_request.method.should == "GET"
|
408
|
-
FakeWeb.last_request.path.should =~ /#{Tddium::TEST_EXECUTIONS_PATH}$/
|
409
575
|
end
|
410
576
|
|
411
577
|
it_should_behave_like "sending the api key"
|
412
578
|
|
413
579
|
shared_examples_for("test output summary") do
|
414
|
-
it "should
|
415
|
-
tddium.should_receive(:say).with(
|
580
|
+
it "should show the user a link to the report" do
|
581
|
+
tddium.should_receive(:say).with(Tddium::Text::Process::CHECK_TEST_REPORT % SAMPLE_REPORT_URL)
|
416
582
|
run_spec(tddium)
|
417
583
|
end
|
418
584
|
|
419
|
-
it "should
|
420
|
-
tddium.should_receive(:say).with(
|
585
|
+
it "should show the user the time taken" do
|
586
|
+
tddium.should_receive(:say).with(/^#{Tddium::Text::Process::FINISHED_TEST % "[\\d\\.]+"}$/)
|
421
587
|
run_spec(tddium)
|
422
588
|
end
|
423
589
|
end
|
424
590
|
|
425
591
|
context "user presses 'Ctrl-C' during the process" do
|
426
592
|
before do
|
427
|
-
|
593
|
+
stub_call_api_response(:get, "#{Tddium::Api::Path::SESSIONS}/#{SAMPLE_SESSION_ID}/#{Tddium::Api::Path::TEST_EXECUTIONS}", get_test_executions_response)
|
428
594
|
Signal.stub(:trap).with(:INT).and_yield
|
429
595
|
stub_sleep(tddium)
|
430
596
|
end
|
431
597
|
|
432
|
-
it "should
|
433
|
-
tddium.should_receive(:say).with(Tddium::
|
598
|
+
it "should show the user '#{Tddium::Text::Process::INTERRUPT}'" do
|
599
|
+
tddium.should_receive(:say).with(Tddium::Text::Process::INTERRUPT)
|
434
600
|
run_spec(tddium)
|
435
601
|
end
|
436
602
|
|
437
|
-
it "should
|
603
|
+
it "should show the user '#{Tddium::Text::Process::CHECK_TEST_STATUS}'" do
|
604
|
+
tddium.should_receive(:say).with(Tddium::Text::Process::CHECK_TEST_STATUS)
|
605
|
+
run_spec(tddium)
|
606
|
+
end
|
607
|
+
|
608
|
+
it "should show the user a summary of all the tests" do
|
438
609
|
tddium.should_receive(:say).with("3 examples, 1 failures, 0 errors, 1 pending")
|
439
610
|
run_spec(tddium)
|
440
611
|
end
|
@@ -442,34 +613,35 @@ describe Tddium do
|
|
442
613
|
it_should_behave_like("test output summary")
|
443
614
|
end
|
444
615
|
|
445
|
-
context "'GET #{Tddium::
|
616
|
+
context "'GET #{Tddium::Api::Path::TEST_EXECUTIONS}' is successful" do
|
446
617
|
before do
|
447
|
-
|
618
|
+
get_test_executions_response_all_finished = {"report"=>SAMPLE_REPORT_URL, "tests"=>{"spec/mouse_spec.rb"=>{"end_time"=>SAMPLE_DATE_TIME, "status"=>"pending"}, "spec/pig_spec.rb"=>{"end_time"=>SAMPLE_DATE_TIME, "status"=>"error"}, "spec/dog_spec.rb"=>{"end_time"=>SAMPLE_DATE_TIME, "status"=>"failed"}, "spec/cat_spec.rb"=>{"end_time"=>SAMPLE_DATE_TIME, "status"=>"passed"}}}
|
619
|
+
stub_call_api_response(:get, "#{Tddium::Api::Path::SESSIONS}/#{SAMPLE_SESSION_ID}/#{Tddium::Api::Path::TEST_EXECUTIONS}", get_test_executions_response, get_test_executions_response_all_finished)
|
448
620
|
stub_sleep(tddium)
|
449
621
|
end
|
450
622
|
|
451
|
-
it "should sleep for #{Tddium::SLEEP_TIME_BETWEEN_POLLS} seconds" do
|
452
|
-
tddium.should_receive(:sleep).exactly(1).times.with(Tddium::SLEEP_TIME_BETWEEN_POLLS)
|
623
|
+
it "should sleep for #{Tddium::Default::SLEEP_TIME_BETWEEN_POLLS} seconds" do
|
624
|
+
tddium.should_receive(:sleep).exactly(1).times.with(Tddium::Default::SLEEP_TIME_BETWEEN_POLLS)
|
453
625
|
run_spec(tddium)
|
454
626
|
end
|
455
627
|
|
456
628
|
it "should display a green '.'" do
|
457
|
-
tddium.should_receive(:say).with(".", :green)
|
629
|
+
tddium.should_receive(:say).with(".", :green, false)
|
458
630
|
run_spec(tddium)
|
459
631
|
end
|
460
632
|
|
461
633
|
it "should display a red 'F'" do
|
462
|
-
tddium.should_receive(:say).with("F", :red)
|
634
|
+
tddium.should_receive(:say).with("F", :red, false)
|
463
635
|
run_spec(tddium)
|
464
636
|
end
|
465
637
|
|
466
638
|
it "should display a yellow '*'" do
|
467
|
-
tddium.should_receive(:say).with("*", :yellow)
|
639
|
+
tddium.should_receive(:say).with("*", :yellow, false)
|
468
640
|
run_spec(tddium)
|
469
641
|
end
|
470
642
|
|
471
643
|
it "should display 'E' with no color" do
|
472
|
-
tddium.should_receive(:say).with("E", nil)
|
644
|
+
tddium.should_receive(:say).with("E", nil, false)
|
473
645
|
run_spec(tddium)
|
474
646
|
end
|
475
647
|
|
@@ -479,11 +651,404 @@ describe Tddium do
|
|
479
651
|
end
|
480
652
|
|
481
653
|
it_should_behave_like("test output summary")
|
654
|
+
end
|
655
|
+
|
656
|
+
it_should_behave_like "an unsuccessful api call"
|
657
|
+
end
|
658
|
+
|
659
|
+
it_should_behave_like "an unsuccessful api call"
|
660
|
+
end
|
661
|
+
|
662
|
+
it_should_behave_like "an unsuccessful api call"
|
663
|
+
end
|
664
|
+
|
665
|
+
it_should_behave_like "an unsuccessful api call"
|
666
|
+
end
|
667
|
+
|
668
|
+
it_should_behave_like "an unsuccessful api call"
|
669
|
+
end
|
670
|
+
|
671
|
+
describe "#status" do
|
672
|
+
before do
|
673
|
+
stub_defaults
|
674
|
+
stub_config_file(:api_key => true, :branches => true)
|
675
|
+
end
|
482
676
|
|
677
|
+
it_should_behave_like "set the default environment"
|
678
|
+
it_should_behave_like "git repo has not been initialized"
|
679
|
+
it_should_behave_like ".tddium file is missing or corrupt"
|
680
|
+
it_should_behave_like "suite has not been initialized"
|
681
|
+
|
682
|
+
context "'GET #{Tddium::Api::Path::SUITES}' is successful" do
|
683
|
+
context "returns no suites" do
|
684
|
+
before { stub_call_api_response(:get, Tddium::Api::Path::SUITES, {"suites" => []}) }
|
685
|
+
|
686
|
+
it "should show the user '#{Tddium::Text::Status::NO_SUITE}'" do
|
687
|
+
tddium.should_receive(:say).with(Tddium::Text::Status::NO_SUITE)
|
688
|
+
run_status(tddium)
|
689
|
+
end
|
690
|
+
end
|
691
|
+
|
692
|
+
context "returns some suites" do
|
693
|
+
let(:suite_attributes) { {"id"=>SAMPLE_SUITE_ID, "repo_name"=>SAMPLE_APP_NAME, "ruby_version"=>SAMPLE_RUBY_VERSION, "branch" => SAMPLE_BRANCH_NAME, "test_pattern" => SAMPLE_TEST_PATTERN, "bundler_version" => SAMPLE_BUNDLER_VERSION, "rubygems_version" => SAMPLE_RUBYGEMS_VERSION}}
|
694
|
+
before do
|
695
|
+
suites_response = {"suites"=>[suite_attributes], "status"=>0}
|
696
|
+
stub_call_api_response(:get, Tddium::Api::Path::SUITES, suites_response)
|
697
|
+
end
|
698
|
+
|
699
|
+
it "should show all suites" do
|
700
|
+
tddium.should_receive(:say).with(Tddium::Text::Status::ALL_SUITES % SAMPLE_APP_NAME)
|
701
|
+
run_status(tddium)
|
702
|
+
end
|
703
|
+
|
704
|
+
context "without current suite" do
|
705
|
+
before { stub_config_file(:branches => {SAMPLE_BRANCH_NAME => 0}) }
|
706
|
+
it "should show the user '#{Tddium::Text::Status::CURRENT_SUITE_UNAVAILABLE}'" do
|
707
|
+
tddium.should_receive(:say).with(Tddium::Text::Status::CURRENT_SUITE_UNAVAILABLE)
|
708
|
+
run_status(tddium)
|
709
|
+
end
|
710
|
+
end
|
711
|
+
|
712
|
+
context "with current suite" do
|
713
|
+
shared_examples_for "attribute details" do
|
714
|
+
it "should show the user the attribute details" do
|
715
|
+
attributes_to_display.each do |attr|
|
716
|
+
if attributes[attr]
|
717
|
+
tddium.should_receive(:say).with(Tddium::Text::Status::ATTRIBUTE_DETAIL % [attr.gsub("_", " ").capitalize, attributes[attr]])
|
718
|
+
else
|
719
|
+
tddium.should_not_receive(:say).with(/#{attr.gsub("_", " ").capitalize}/)
|
720
|
+
end
|
721
|
+
end
|
722
|
+
run_status(tddium)
|
723
|
+
end
|
724
|
+
|
725
|
+
it "should not show the user irrelevent attributes" do
|
726
|
+
attributes_to_hide.each do |regexp|
|
727
|
+
tddium.should_not_receive(:say).with(regexp)
|
728
|
+
end
|
729
|
+
run_status(tddium)
|
730
|
+
end
|
731
|
+
end
|
732
|
+
|
733
|
+
it "should show the separator" do
|
734
|
+
tddium.should_receive(:say).with(Tddium::Text::Status::SEPARATOR)
|
735
|
+
run_status(tddium)
|
736
|
+
end
|
737
|
+
|
738
|
+
it "should show user the current suite name" do
|
739
|
+
tddium.should_receive(:say).with(Tddium::Text::Status::CURRENT_SUITE % SAMPLE_APP_NAME)
|
740
|
+
run_status(tddium)
|
741
|
+
end
|
742
|
+
|
743
|
+
it_should_behave_like "attribute details" do
|
744
|
+
let(:attributes_to_display) {Tddium::DisplayedAttributes::SUITE}
|
745
|
+
let(:attributes_to_hide) { [/id/] }
|
746
|
+
let(:attributes) { suite_attributes }
|
747
|
+
end
|
748
|
+
|
749
|
+
context "show active sessions" do
|
750
|
+
context "without any session" do
|
751
|
+
before do
|
752
|
+
sessions_response = {"status"=>0, "sessions"=>[]}
|
753
|
+
stub_call_api_response(:get, Tddium::Api::Path::SESSIONS, sessions_response)
|
754
|
+
end
|
755
|
+
|
756
|
+
it "should display no active session message" do
|
757
|
+
tddium.should_receive(:say).with(Tddium::Text::Status::NO_ACTIVE_SESSION)
|
758
|
+
run_status(tddium)
|
759
|
+
end
|
760
|
+
end
|
761
|
+
|
762
|
+
context "with some sessions" do
|
763
|
+
let(:session_attributes) { {"id"=>SAMPLE_SESSION_ID, "user_id"=>3} }
|
764
|
+
before do
|
765
|
+
sessions_response = {"status"=>0, "sessions"=>[session_attributes]}
|
766
|
+
stub_call_api_response(:get, Tddium::Api::Path::SESSIONS, sessions_response)
|
767
|
+
end
|
768
|
+
|
769
|
+
it "should display the active sessions prompt" do
|
770
|
+
tddium.should_receive(:say).with(Tddium::Text::Status::ACTIVE_SESSIONS)
|
771
|
+
run_status(tddium)
|
772
|
+
end
|
773
|
+
|
774
|
+
it_should_behave_like "attribute details" do
|
775
|
+
let(:attributes_to_display) {Tddium::DisplayedAttributes::TEST_EXECUTION}
|
776
|
+
let(:attributes_to_hide) { [/id/] }
|
777
|
+
let(:attributes) { session_attributes }
|
778
|
+
end
|
779
|
+
end
|
780
|
+
end
|
781
|
+
end
|
782
|
+
end
|
783
|
+
end
|
784
|
+
|
785
|
+
it_should_behave_like "an unsuccessful api call"
|
786
|
+
end
|
787
|
+
|
788
|
+
describe "#suite" do
|
789
|
+
before do
|
790
|
+
stub_defaults
|
791
|
+
stub_config_file(:api_key => true)
|
792
|
+
stub_ruby_version(tddium)
|
793
|
+
stub_rubygems_version(tddium)
|
794
|
+
stub_bundler_version(tddium)
|
795
|
+
tddium.stub(:ask).and_return("")
|
796
|
+
end
|
797
|
+
|
798
|
+
it_should_behave_like "set the default environment"
|
799
|
+
it_should_behave_like "sending the api key"
|
800
|
+
it_should_behave_like "git repo has not been initialized"
|
801
|
+
it_should_behave_like ".tddium file is missing or corrupt"
|
802
|
+
|
803
|
+
context ".tddium file contains no suites" do
|
804
|
+
before do
|
805
|
+
stub_default_suite_name
|
806
|
+
stub_call_api_response(:get, Tddium::Api::Path::SUITES, {"suites" => []}, :and_return => SAMPLE_CALL_API_RESPONSE)
|
807
|
+
end
|
808
|
+
|
809
|
+
context "using defaults" do
|
810
|
+
it "should send a 'GET' request to '#{Tddium::Api::Path::SUITES} with the repo name and branch name'" do
|
811
|
+
call_api_should_receive(:method => :get, :path => Tddium::Api::Path::SUITES, :params => hash_including(:repo_name => SAMPLE_APP_NAME, :branch => SAMPLE_BRANCH_NAME))
|
812
|
+
run_suite(tddium)
|
813
|
+
end
|
814
|
+
end
|
815
|
+
|
816
|
+
context "passing '--name=my_suite'" do
|
817
|
+
let(:cli_args) { { :name => "my_suite" } }
|
818
|
+
|
819
|
+
it "should not ask for a suite name" do
|
820
|
+
tddium.should_not_receive(:ask).with(Tddium::Text::Prompt::SUITE_NAME % SAMPLE_APP_NAME)
|
821
|
+
run_suite(tddium, cli_args)
|
822
|
+
end
|
823
|
+
|
824
|
+
it "should send a GET request with the passed in values to the API" do
|
825
|
+
call_api_should_receive(:method => :get, :path => Tddium::Api::Path::SUITES, :params => hash_including(:repo_name => "my_suite"))
|
826
|
+
run_suite(tddium, cli_args)
|
827
|
+
end
|
828
|
+
end
|
829
|
+
|
830
|
+
context "interactive mode" do
|
831
|
+
before { tddium.stub(:ask).with(Tddium::Text::Prompt::SUITE_NAME % SAMPLE_APP_NAME).and_return("some_other_suite") }
|
832
|
+
|
833
|
+
it "should ask for a suite name" do
|
834
|
+
tddium.should_receive(:ask).with(Tddium::Text::Prompt::SUITE_NAME % SAMPLE_APP_NAME)
|
835
|
+
run_suite(tddium)
|
836
|
+
end
|
837
|
+
|
838
|
+
it "should send a GET request with the user's entries to the API" do
|
839
|
+
call_api_should_receive(:method => :get, :path => Tddium::Api::Path::SUITES, :params => hash_including(:repo_name => "some_other_suite"))
|
840
|
+
run_suite(tddium)
|
841
|
+
end
|
842
|
+
end
|
843
|
+
|
844
|
+
context "passing '--name=my_suite --test-pattern=**/*_selenium.rb'" do
|
845
|
+
it "should POST request with the passed in values to the API" do
|
846
|
+
call_api_should_receive(:method => :post, :path => Tddium::Api::Path::SUITES, :params => {:suite => hash_including(:repo_name => "my_suite", :test_pattern => "**/*_selenium.rb")})
|
847
|
+
run_suite(tddium, :name => "my_suite", :test_pattern => "**/*_selenium.rb")
|
848
|
+
end
|
849
|
+
end
|
850
|
+
|
851
|
+
context "but this user has already registered some suites" do
|
852
|
+
before do
|
853
|
+
stub_call_api_response(:get, Tddium::Api::Path::SUITES, SAMPLE_SUITES_RESPONSE, {"suites" => []}, :and_return => SAMPLE_CALL_API_RESPONSE)
|
854
|
+
tddium.stub(:ask).with(Tddium::Text::Prompt::USE_EXISTING_SUITE % SAMPLE_APP_NAME).and_return(Tddium::Text::Prompt::Response::YES)
|
855
|
+
end
|
856
|
+
|
857
|
+
shared_examples_for "writing the suite to file" do
|
858
|
+
it "should write the suite id and branch name to the .tddium file" do
|
859
|
+
run_suite(tddium)
|
860
|
+
tddium_file = File.open(SAMPLE_TDDIUM_CONFIG_FILE) { |file| file.read }
|
861
|
+
JSON.parse(tddium_file)["branches"][SAMPLE_BRANCH_NAME].should == SAMPLE_SUITE_ID
|
862
|
+
end
|
863
|
+
end
|
864
|
+
|
865
|
+
context "passing no cli options" do
|
866
|
+
it "should ask the user: '#{Tddium::Text::Prompt::USE_EXISTING_SUITE % SAMPLE_APP_NAME}' " do
|
867
|
+
tddium.should_receive(:ask).with(Tddium::Text::Prompt::USE_EXISTING_SUITE % SAMPLE_APP_NAME).and_return("something")
|
868
|
+
run_suite(tddium)
|
869
|
+
end
|
870
|
+
end
|
871
|
+
|
872
|
+
context "passing --name=my_suite" do
|
873
|
+
before do
|
874
|
+
stub_call_api_response(:get, Tddium::Api::Path::SUITES, SAMPLE_SUITES_RESPONSE, :and_return => SAMPLE_CALL_API_RESPONSE)
|
875
|
+
end
|
876
|
+
|
877
|
+
it "should not ask the user if they want to use the existing suite" do
|
878
|
+
tddium_client.should_not_receive(:ask).with(Tddium::Text::Prompt::USE_EXISTING_SUITE % "my_suite")
|
879
|
+
run_suite(tddium, :name => "my_suite")
|
880
|
+
end
|
881
|
+
|
882
|
+
it "should not POST the passed in values to the API" do
|
883
|
+
tddium_client.should_not_receive(:call_api).with(:post)
|
884
|
+
run_suite(tddium, :name => "my_suite")
|
885
|
+
end
|
886
|
+
|
887
|
+
it_should_behave_like "writing the suite to file"
|
888
|
+
|
889
|
+
end
|
890
|
+
|
891
|
+
context "the user wants to use the existing suite" do
|
892
|
+
before do
|
893
|
+
stub_call_api_response(:get, Tddium::Api::Path::SUITES, SAMPLE_SUITES_RESPONSE, :and_return => SAMPLE_CALL_API_RESPONSE)
|
894
|
+
end
|
895
|
+
|
896
|
+
it "should not send a 'POST' request to '#{Tddium::Api::Path::SUITES}'" do
|
897
|
+
tddium_client.should_not_receive(:call_api).with(:method => :post, :path => Tddium::Api::Path::SUITES)
|
898
|
+
run_suite(tddium)
|
899
|
+
end
|
900
|
+
|
901
|
+
it_should_behave_like "writing the suite to file"
|
902
|
+
|
903
|
+
it "should show the user: '#{Tddium::Text::Status::USING_SUITE % [SAMPLE_APP_NAME, SAMPLE_BRANCH_NAME]}'" do
|
904
|
+
tddium.should_receive(:say).with(Tddium::Text::Status::USING_SUITE % [SAMPLE_APP_NAME, SAMPLE_BRANCH_NAME])
|
905
|
+
run_suite(tddium)
|
906
|
+
end
|
907
|
+
end
|
908
|
+
|
909
|
+
context "the user does not want to use the existing suite" do
|
910
|
+
before{ tddium.stub(:ask).with(Tddium::Text::Prompt::USE_EXISTING_SUITE % SAMPLE_APP_NAME).and_return("some_other_suite") }
|
911
|
+
|
912
|
+
it "should ask for a test file pattern" do
|
913
|
+
tddium.should_receive(:ask).with(Tddium::Text::Prompt::TEST_PATTERN % Tddium::Default::TEST_PATTERN)
|
914
|
+
run_suite(tddium)
|
915
|
+
end
|
916
|
+
|
917
|
+
it "should send a 'POST' request to '#{Tddium::Api::Path::SUITES}'" do
|
918
|
+
call_api_should_receive(:method => :post, :path => Tddium::Api::Path::SUITES)
|
919
|
+
run_suite(tddium)
|
920
|
+
end
|
921
|
+
|
922
|
+
it "should post the user's current ruby version to the API" do
|
923
|
+
stub_ruby_version(tddium)
|
924
|
+
call_api_should_receive(:params => {:suite => hash_including(:ruby_version => SAMPLE_RUBY_VERSION)})
|
925
|
+
run_suite(tddium)
|
926
|
+
end
|
927
|
+
|
928
|
+
it "should post the user's current branch to the API" do
|
929
|
+
stub_ruby_version(tddium)
|
930
|
+
call_api_should_receive(:params => {:suite => hash_including(:branch => SAMPLE_BRANCH_NAME)})
|
931
|
+
run_suite(tddium)
|
932
|
+
end
|
933
|
+
|
934
|
+
it "should post the user's bundler version to the API" do
|
935
|
+
stub_ruby_version(tddium)
|
936
|
+
call_api_should_receive(:params => {:suite => hash_including(:bundler_version => SAMPLE_BUNDLER_VERSION)})
|
937
|
+
run_suite(tddium)
|
938
|
+
end
|
939
|
+
|
940
|
+
it "should post the user's rubygems version to the API" do
|
941
|
+
stub_ruby_version(tddium)
|
942
|
+
call_api_should_receive(:params => {:suite => hash_including(:rubygems_version => SAMPLE_RUBYGEMS_VERSION)})
|
943
|
+
run_suite(tddium)
|
944
|
+
end
|
945
|
+
|
946
|
+
context "using defaults" do
|
947
|
+
it "should POST the default test pattern to the API" do
|
948
|
+
call_api_should_receive(:params => {:suite => hash_including(:test_pattern => SAMPLE_TEST_PATTERN)})
|
949
|
+
run_suite(tddium)
|
950
|
+
end
|
951
|
+
end
|
952
|
+
|
953
|
+
context "interactive mode" do
|
954
|
+
before do
|
955
|
+
tddium.stub(:ask).with(Tddium::Text::Prompt::USE_EXISTING_SUITE % SAMPLE_APP_NAME).and_return("foobar")
|
956
|
+
tddium.stub(:ask).with(Tddium::Text::Prompt::TEST_PATTERN % Tddium::Default::TEST_PATTERN).and_return("**/*_test")
|
957
|
+
stub_default_suite_name
|
958
|
+
end
|
959
|
+
|
960
|
+
it "should POST the user's entered values to the API" do
|
961
|
+
call_api_should_receive(:method => :post, :params => {:suite => hash_including(:repo_name => "foobar", :test_pattern => "**/*_test")})
|
962
|
+
run_suite(tddium)
|
963
|
+
end
|
964
|
+
end
|
965
|
+
|
966
|
+
context "API response successful" do
|
967
|
+
before do
|
968
|
+
stub_call_api_response(:post, Tddium::Api::Path::SUITES, {"suite"=>{"id"=>SAMPLE_SUITE_ID, "git_repo_uri" => SAMPLE_GIT_REPO_URI}})
|
969
|
+
tddium.stub(:`).with(/^git remote/)
|
970
|
+
stub_git_push(tddium)
|
971
|
+
end
|
972
|
+
|
973
|
+
it_should_behave_like("writing the suite to file")
|
974
|
+
|
975
|
+
it "should remove any existing remotes named 'tddium'" do
|
976
|
+
tddium.should_receive(:`).with("git remote rm tddium")
|
977
|
+
run_suite(tddium)
|
978
|
+
end
|
979
|
+
|
980
|
+
it "should add a new remote called '#{Tddium::Git::REMOTE_NAME}'" do
|
981
|
+
stub_default_suite_name
|
982
|
+
tddium.should_receive(:`).with("git remote add #{Tddium::Git::REMOTE_NAME} #{SAMPLE_GIT_REPO_URI}")
|
983
|
+
run_suite(tddium)
|
984
|
+
end
|
985
|
+
|
986
|
+
context "in the branch 'oaktree'" do
|
987
|
+
before do
|
988
|
+
tddium.stub(:current_git_branch).and_return("oaktree")
|
989
|
+
end
|
990
|
+
|
991
|
+
it "should push the current git branch to tddium oaktree" do
|
992
|
+
tddium.should_receive(:system).with("git push tddium oaktree")
|
993
|
+
run_suite(tddium)
|
994
|
+
end
|
483
995
|
end
|
484
996
|
end
|
485
|
-
|
997
|
+
it_should_behave_like "an unsuccessful api call"
|
998
|
+
end
|
486
999
|
end
|
487
1000
|
end
|
1001
|
+
|
1002
|
+
context "suite has already been registered" do
|
1003
|
+
before do
|
1004
|
+
stub_config_file(:api_key => true, :branches => true)
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
context "'GET #{Tddium::Api::Path::SUITES}/#{SAMPLE_SUITE_ID}' is successful" do
|
1008
|
+
before do
|
1009
|
+
response = {
|
1010
|
+
"suite" => {
|
1011
|
+
"test_pattern" => "**/*_test.rb",
|
1012
|
+
"id" => SAMPLE_SUITE_ID
|
1013
|
+
}
|
1014
|
+
}
|
1015
|
+
stub_call_api_response(:get, "#{Tddium::Api::Path::SUITES}/#{SAMPLE_SUITE_ID}", response)
|
1016
|
+
end
|
1017
|
+
|
1018
|
+
it "should not ask for a suite name" do
|
1019
|
+
stub_default_suite_name
|
1020
|
+
tddium.should_not_receive(:ask).with(Tddium::Text::Prompt::SUITE_NAME % SAMPLE_APP_NAME)
|
1021
|
+
run_suite(tddium)
|
1022
|
+
end
|
1023
|
+
|
1024
|
+
it "should not look for the current ruby version" do
|
1025
|
+
tddium.should_not_receive(:`).with("ruby -v")
|
1026
|
+
run_suite(tddium)
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
it "should prompt for a test pattern using the current test pattern as the default" do
|
1030
|
+
tddium.should_receive(:ask).with(/\*\*\/\*\_test\.rb/)
|
1031
|
+
run_suite(tddium)
|
1032
|
+
end
|
1033
|
+
|
1034
|
+
it "should send a 'PUT' request to '#{Tddium::Api::Path::SUITES}/#{SAMPLE_SUITE_ID}'" do
|
1035
|
+
call_api_should_receive(:method => :put, :path => "#{Tddium::Api::Path::SUITES}/#{SAMPLE_SUITE_ID}")
|
1036
|
+
run_suite(tddium)
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
context "'PUT #{Tddium::Api::Path::SUITES}/#{SAMPLE_SUITE_ID}' is successful" do
|
1040
|
+
before { stub_call_api_response(:put, "#{Tddium::Api::Path::SUITES}/#{SAMPLE_SUITE_ID}", {}) }
|
1041
|
+
it "should display '#{Tddium::Text::Process::UPDATE_SUITE}'" do
|
1042
|
+
tddium.should_receive(:say).with(Tddium::Text::Process::UPDATE_SUITE)
|
1043
|
+
run_suite(tddium)
|
1044
|
+
end
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
it_should_behave_like "sending the api key"
|
1048
|
+
it_should_behave_like "an unsuccessful api call"
|
1049
|
+
end
|
1050
|
+
|
1051
|
+
it_should_behave_like "an unsuccessful api call"
|
1052
|
+
end
|
488
1053
|
end
|
489
1054
|
end
|