af 0.3.22 → 0.5.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +14 -6
  2. data/LICENSE +1277 -24
  3. data/Rakefile +24 -87
  4. data/bin/af +7 -2
  5. data/lib/af/version.rb +3 -0
  6. data/lib/vmc.rb +7 -2
  7. data/lib/vmc/cli.rb +475 -0
  8. data/lib/vmc/cli/app/app.rb +45 -0
  9. data/lib/vmc/cli/app/apps.rb +105 -0
  10. data/lib/vmc/cli/app/base.rb +82 -0
  11. data/lib/vmc/cli/app/crashes.rb +46 -0
  12. data/lib/vmc/cli/app/delete.rb +95 -0
  13. data/lib/vmc/cli/app/deprecated.rb +11 -0
  14. data/lib/vmc/cli/app/env.rb +78 -0
  15. data/lib/vmc/cli/app/files.rb +137 -0
  16. data/lib/vmc/cli/app/health.rb +26 -0
  17. data/lib/vmc/cli/app/instances.rb +53 -0
  18. data/lib/vmc/cli/app/logs.rb +76 -0
  19. data/lib/vmc/cli/app/push.rb +107 -0
  20. data/lib/vmc/cli/app/push/create.rb +150 -0
  21. data/lib/vmc/cli/app/push/interactions.rb +100 -0
  22. data/lib/vmc/cli/app/push/sync.rb +64 -0
  23. data/lib/vmc/cli/app/rename.rb +39 -0
  24. data/lib/vmc/cli/app/restart.rb +20 -0
  25. data/lib/vmc/cli/app/scale.rb +71 -0
  26. data/lib/vmc/cli/app/start.rb +93 -0
  27. data/lib/vmc/cli/app/stats.rb +67 -0
  28. data/lib/vmc/cli/app/stop.rb +27 -0
  29. data/lib/vmc/cli/domain/base.rb +12 -0
  30. data/lib/vmc/cli/domain/domains.rb +40 -0
  31. data/lib/vmc/cli/domain/map.rb +55 -0
  32. data/lib/vmc/cli/domain/unmap.rb +56 -0
  33. data/lib/vmc/cli/help.rb +16 -0
  34. data/lib/vmc/cli/interactive.rb +105 -0
  35. data/lib/vmc/cli/organization/base.rb +14 -0
  36. data/lib/vmc/cli/organization/create.rb +32 -0
  37. data/lib/vmc/cli/organization/delete.rb +73 -0
  38. data/lib/vmc/cli/organization/org.rb +45 -0
  39. data/lib/vmc/cli/organization/orgs.rb +35 -0
  40. data/lib/vmc/cli/organization/rename.rb +36 -0
  41. data/lib/vmc/cli/route/base.rb +12 -0
  42. data/lib/vmc/cli/route/map.rb +80 -0
  43. data/lib/vmc/cli/route/routes.rb +26 -0
  44. data/lib/vmc/cli/route/unmap.rb +94 -0
  45. data/lib/vmc/cli/service/base.rb +8 -0
  46. data/lib/vmc/cli/service/bind.rb +44 -0
  47. data/lib/vmc/cli/service/create.rb +126 -0
  48. data/lib/vmc/cli/service/delete.rb +86 -0
  49. data/lib/vmc/cli/service/rename.rb +35 -0
  50. data/lib/vmc/cli/service/service.rb +42 -0
  51. data/lib/vmc/cli/service/services.rb +115 -0
  52. data/lib/vmc/cli/service/unbind.rb +38 -0
  53. data/lib/vmc/cli/space/base.rb +21 -0
  54. data/lib/vmc/cli/space/create.rb +56 -0
  55. data/lib/vmc/cli/space/delete.rb +95 -0
  56. data/lib/vmc/cli/space/rename.rb +39 -0
  57. data/lib/vmc/cli/space/space.rb +64 -0
  58. data/lib/vmc/cli/space/spaces.rb +55 -0
  59. data/lib/vmc/cli/space/take.rb +16 -0
  60. data/lib/vmc/cli/start/base.rb +80 -0
  61. data/lib/vmc/cli/start/colors.rb +13 -0
  62. data/lib/vmc/cli/start/info.rb +122 -0
  63. data/lib/vmc/cli/start/login.rb +92 -0
  64. data/lib/vmc/cli/start/logout.rb +13 -0
  65. data/lib/vmc/cli/start/target.rb +64 -0
  66. data/lib/vmc/cli/start/target_interactions.rb +37 -0
  67. data/lib/vmc/cli/start/targets.rb +16 -0
  68. data/lib/vmc/cli/user/base.rb +29 -0
  69. data/lib/vmc/cli/user/create.rb +39 -0
  70. data/lib/vmc/cli/user/delete.rb +25 -0
  71. data/lib/vmc/cli/user/passwd.rb +50 -0
  72. data/lib/vmc/cli/user/register.rb +42 -0
  73. data/lib/vmc/cli/user/users.rb +32 -0
  74. data/lib/vmc/constants.rb +13 -0
  75. data/lib/vmc/detect.rb +134 -0
  76. data/lib/vmc/errors.rb +17 -0
  77. data/lib/vmc/plugin.rb +56 -0
  78. data/lib/vmc/spacing.rb +89 -0
  79. data/lib/vmc/spec_helper.rb +1 -0
  80. data/lib/vmc/test_support.rb +4 -0
  81. data/lib/vmc/test_support/command_helper.rb +32 -0
  82. data/lib/vmc/test_support/common_input_examples.rb +14 -0
  83. data/lib/vmc/test_support/fake_home_dir.rb +16 -0
  84. data/lib/vmc/test_support/interact_helper.rb +29 -0
  85. data/lib/vmc/version.rb +3 -0
  86. data/spec/assets/hello-sinatra/Gemfile +3 -0
  87. data/spec/assets/hello-sinatra/main.rb +6 -0
  88. data/spec/features/new_user_flow_spec.rb +71 -0
  89. data/spec/spec_helper.rb +63 -0
  90. data/spec/vmc/cli/app/base_spec.rb +17 -0
  91. data/spec/vmc/cli/app/delete_spec.rb +188 -0
  92. data/spec/vmc/cli/app/instances_spec.rb +65 -0
  93. data/spec/vmc/cli/app/push/create_spec.rb +571 -0
  94. data/spec/vmc/cli/app/push_spec.rb +369 -0
  95. data/spec/vmc/cli/app/rename_spec.rb +104 -0
  96. data/spec/vmc/cli/app/scale_spec.rb +81 -0
  97. data/spec/vmc/cli/app/stats_spec.rb +62 -0
  98. data/spec/vmc/cli/domain/map_spec.rb +140 -0
  99. data/spec/vmc/cli/domain/unmap_spec.rb +73 -0
  100. data/spec/vmc/cli/organization/orgs_spec.rb +108 -0
  101. data/spec/vmc/cli/organization/rename_spec.rb +113 -0
  102. data/spec/vmc/cli/route/map_spec.rb +138 -0
  103. data/spec/vmc/cli/route/unmap_spec.rb +215 -0
  104. data/spec/vmc/cli/service/bind_spec.rb +25 -0
  105. data/spec/vmc/cli/service/delete_spec.rb +22 -0
  106. data/spec/vmc/cli/service/rename_spec.rb +105 -0
  107. data/spec/vmc/cli/service/service_spec.rb +23 -0
  108. data/spec/vmc/cli/service/unbind_spec.rb +25 -0
  109. data/spec/vmc/cli/space/rename_spec.rb +102 -0
  110. data/spec/vmc/cli/space/spaces_spec.rb +104 -0
  111. data/spec/vmc/cli/start/info_spec.rb +153 -0
  112. data/spec/vmc/cli/start/login_spec.rb +71 -0
  113. data/spec/vmc/cli/user/create_spec.rb +54 -0
  114. data/spec/vmc/cli/user/passwd_spec.rb +102 -0
  115. data/spec/vmc/cli/user/register_spec.rb +148 -0
  116. data/spec/vmc/cli_spec.rb +448 -0
  117. data/spec/vmc/detect_spec.rb +54 -0
  118. metadata +231 -124
  119. data/README.md +0 -155
  120. data/caldecott_helper/Gemfile +0 -10
  121. data/caldecott_helper/Gemfile.lock +0 -48
  122. data/caldecott_helper/server.rb +0 -43
  123. data/config/clients.yml +0 -17
  124. data/config/micro/offline.conf +0 -2
  125. data/config/micro/paths.yml +0 -22
  126. data/config/micro/refresh_ip.rb +0 -20
  127. data/lib/cli.rb +0 -48
  128. data/lib/cli/commands/admin.rb +0 -81
  129. data/lib/cli/commands/apps.rb +0 -1358
  130. data/lib/cli/commands/base.rb +0 -233
  131. data/lib/cli/commands/manifest.rb +0 -56
  132. data/lib/cli/commands/micro.rb +0 -115
  133. data/lib/cli/commands/misc.rb +0 -147
  134. data/lib/cli/commands/services.rb +0 -217
  135. data/lib/cli/commands/user.rb +0 -70
  136. data/lib/cli/config.rb +0 -176
  137. data/lib/cli/console_helper.rb +0 -163
  138. data/lib/cli/core_ext.rb +0 -122
  139. data/lib/cli/errors.rb +0 -19
  140. data/lib/cli/file_helper.rb +0 -123
  141. data/lib/cli/frameworks.rb +0 -265
  142. data/lib/cli/manifest_helper.rb +0 -316
  143. data/lib/cli/runner.rb +0 -633
  144. data/lib/cli/services_helper.rb +0 -104
  145. data/lib/cli/tunnel_helper.rb +0 -336
  146. data/lib/cli/usage.rb +0 -129
  147. data/lib/cli/version.rb +0 -7
  148. data/lib/cli/zip_util.rb +0 -102
  149. data/lib/vmc/client.rb +0 -574
  150. data/lib/vmc/const.rb +0 -27
  151. data/lib/vmc/micro.rb +0 -56
  152. data/lib/vmc/micro/switcher/base.rb +0 -97
  153. data/lib/vmc/micro/switcher/darwin.rb +0 -19
  154. data/lib/vmc/micro/switcher/dummy.rb +0 -15
  155. data/lib/vmc/micro/switcher/linux.rb +0 -16
  156. data/lib/vmc/micro/switcher/windows.rb +0 -31
  157. data/lib/vmc/micro/vmrun.rb +0 -158
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+ require 'stringio'
3
+
4
+ describe VMC::App::Stats do
5
+ let(:global) { { :color => false } }
6
+ let(:inputs) { {:app => apps[0]} }
7
+ let(:given) { {} }
8
+ let(:client) { fake_client(:apps => apps) }
9
+ let(:apps) { [fake(:app, :name => "basic_app")] }
10
+ let(:time) { Time.local(2012,11,1,2,30)}
11
+
12
+ before do
13
+ any_instance_of(VMC::CLI) do |cli|
14
+ stub(cli).client { client }
15
+ stub(cli).precondition { nil }
16
+ end
17
+ stub(client).base.stub!.instances(anything) do
18
+ {
19
+ "12" => {:state => "STOPPED", :since => time.to_i, :debug_ip => "foo", :debug_port => "bar", :console_ip => "baz", :console_port => "qux"},
20
+ "1" => {:state => "STOPPED", :since => time.to_i, :debug_ip => "foo", :debug_port => "bar", :console_ip => "baz", :console_port => "qux"},
21
+ "2" => {:state => "STARTED", :since => time.to_i, :debug_ip => "foo", :debug_port => "bar", :console_ip => "baz", :console_port => "qux"}
22
+ }
23
+ end
24
+ end
25
+
26
+ subject do
27
+ capture_output do
28
+ Mothership.new.invoke(:instances, inputs, given, global)
29
+ end
30
+ end
31
+
32
+ describe 'metadata' do
33
+ let(:command) { Mothership.commands[:instances] }
34
+
35
+ describe 'command' do
36
+ subject { command }
37
+ its(:description) { should eq "List an app's instances" }
38
+ it { expect(Mothership::Help.group(:apps, :info)).to include(subject) }
39
+ end
40
+
41
+ include_examples 'inputs must have descriptions'
42
+
43
+ describe 'arguments' do
44
+ subject { command.arguments }
45
+ it 'has no arguments' do
46
+ should eq([{:type=>:splat, :value=>nil, :name=>:apps}])
47
+ end
48
+ end
49
+ end
50
+
51
+ it 'prints out the instances in the correct order' do
52
+ subject
53
+ expect(stdout.string).to match /.*instance \#1.*instance \#2.*instance \#12.*/m
54
+ end
55
+
56
+ it 'prints out one of the instances correctly' do
57
+ subject
58
+ expect(stdout.string).to include <<-OUT.strip_heredoc
59
+ instance #2: started
60
+ started: #{time.strftime("%F %r")}
61
+ debugger: port bar at foo
62
+ console: port qux at baz
63
+ OUT
64
+ end
65
+ end
@@ -0,0 +1,571 @@
1
+ require 'spec_helper'
2
+
3
+ describe VMC::App::Create do
4
+ let(:inputs) { {} }
5
+ let(:given) { {} }
6
+ let(:global) { { :color => false, :quiet => true } }
7
+
8
+ let(:frameworks) { fake_list(:framework, 3) }
9
+ let(:framework) { buildpack }
10
+ let(:buildpack) { fake(:framework, :name => "buildpack") }
11
+ let(:standalone) { fake(:framework, :name => "standalone") }
12
+
13
+ let(:runtimes) { fake_list(:runtime, 3) }
14
+ let(:runtime) { runtimes.first }
15
+
16
+ let(:service_instances) { fake_list(:service_instance, 5) }
17
+
18
+ let(:client) do
19
+ fake_client(
20
+ :frameworks => frameworks,
21
+ :runtimes => runtimes,
22
+ :service_instances => service_instances)
23
+ end
24
+
25
+ before do
26
+ any_instance_of(VMC::CLI) do |cli|
27
+ stub(cli).client { client }
28
+ end
29
+ end
30
+
31
+ let(:create) do
32
+ command = Mothership.commands[:push]
33
+ create = VMC::App::Push.new(command)
34
+ create.path = "some-path"
35
+ create.input = Mothership::Inputs.new(command, create, inputs, given, global)
36
+ create.extend VMC::App::PushInteractions
37
+ create
38
+ end
39
+
40
+ describe '#get_inputs' do
41
+ subject { create.get_inputs }
42
+
43
+ let(:inputs) do
44
+ { :name => "some-name",
45
+ :instances => 1,
46
+ :plan => "p100",
47
+ :framework => framework,
48
+ :runtime => runtime,
49
+ :memory => "1G",
50
+ :command => "ruby main.rb",
51
+ :buildpack => "git://example.com"
52
+ }
53
+ end
54
+
55
+ context 'when all the inputs are given' do
56
+ its([:name]) { should eq "some-name" }
57
+ its([:total_instances]) { should eq 1 }
58
+ its([:space]) { should eq client.current_space }
59
+ its([:production]) { should eq true }
60
+ its([:framework]) { should eq framework }
61
+ its([:command]) { should eq "ruby main.rb" }
62
+ its([:runtime]) { should eq runtime }
63
+ its([:memory]) { should eq 1024 }
64
+ its([:buildpack]) { should eq "git://example.com" }
65
+ end
66
+
67
+ context 'when certain inputs are not given' do
68
+ it 'should ask for the name' do
69
+ inputs.delete(:name)
70
+ mock_ask("Name") { "some-name" }
71
+ subject
72
+ end
73
+
74
+ it 'should ask for the total instances' do
75
+ inputs.delete(:instances)
76
+ mock_ask("Instances", anything) { 1 }
77
+ subject
78
+ end
79
+
80
+ it 'should ask for the framework' do
81
+ inputs.delete(:framework)
82
+ mock_ask('Framework', anything) do |_, options|
83
+ expect(options[:choices]).to eq frameworks.sort_by(&:name)
84
+ framework
85
+ end
86
+ subject
87
+ end
88
+
89
+ context 'when the command is not given' do
90
+ before { inputs.delete(:command) }
91
+
92
+ shared_examples 'an app that can have a custom start command' do
93
+ it 'should ask if there is a custom start command' do
94
+ mock_ask("Use custom startup command?", :default => false) { false }
95
+ subject
96
+ end
97
+
98
+ context 'when the user answers "yes" to the custom start command' do
99
+ before { stub_ask("Use custom startup command?", :default => false) { true } }
100
+
101
+ it 'should ask for the startup command' do
102
+ mock_ask("Startup command") { "foo bar.com" }
103
+ subject[:command].should eq "foo bar.com"
104
+ end
105
+ end
106
+
107
+ context 'when the user answers "no" to the custom start command' do
108
+ before { stub_ask("Use custom startup command?", :default => false) { false } }
109
+
110
+ it 'should not ask for the startup command' do
111
+ dont_allow_ask("Startup command")
112
+ subject
113
+ end
114
+ end
115
+ end
116
+
117
+ context 'when the framework is "buildpack"' do
118
+ let(:framework) { buildpack }
119
+
120
+ include_examples 'an app that can have a custom start command'
121
+ end
122
+
123
+ context 'when the framework is "standalone"' do
124
+ let(:framework) { standalone }
125
+
126
+ include_examples 'an app that can have a custom start command'
127
+ end
128
+
129
+ context 'when the framework is neither "buildpack" nor "standalone"' do
130
+ let(:framework) { fake(:framework, :name => "java") }
131
+
132
+ it 'does not ask if there is a custom start command' do
133
+ dont_allow_ask("Startup command")
134
+ subject
135
+ end
136
+ end
137
+ end
138
+
139
+ it 'should ask for the runtime' do
140
+ inputs.delete(:runtime)
141
+ mock_ask('Runtime', anything) do |_, options|
142
+ expect(options[:choices]).to eq runtimes.sort_by(&:name)
143
+ runtime
144
+ end
145
+ subject
146
+ end
147
+
148
+ it 'should ask for the memory' do
149
+ inputs.delete(:memory)
150
+
151
+ memory_choices = %w(64M 128M 256M 512M 1G)
152
+ stub(create).memory_choices { memory_choices }
153
+
154
+ mock_ask('Memory Limit', anything) do |_, options|
155
+ expect(options[:choices]).to eq memory_choices
156
+ "1G"
157
+ end
158
+
159
+ subject
160
+ end
161
+ end
162
+ end
163
+
164
+ describe '#determine_framework' do
165
+ subject { create.determine_framework }
166
+
167
+ context 'when framework is given' do
168
+ let(:inputs) { { :framework => framework } }
169
+
170
+ it 'does not try to get the frameworks' do
171
+ any_instance_of(VMC::Detector) do |detector|
172
+ dont_allow(detector).detect_framework
173
+ dont_allow(detector).all_frameworks
174
+ end
175
+
176
+ dont_allow_ask
177
+ dont_allow(client).frameworks
178
+
179
+ subject
180
+ end
181
+
182
+ it { should eq framework }
183
+ end
184
+
185
+ context 'when framework is not given' do
186
+ context 'and a framework is detected' do
187
+ it "lists the detected framework and an 'other' option" do
188
+ any_instance_of(VMC::Detector) do |detector|
189
+ mock(detector).detect_framework { framework }
190
+ end
191
+
192
+ mock_ask('Framework', anything) do |_, options|
193
+ expect(options[:choices]).to eq [framework, :other] #frameworks.sort_by(&:name)
194
+ framework
195
+ end
196
+
197
+ subject
198
+ end
199
+ end
200
+
201
+ context 'and a framework is not detected' do
202
+ it "lists all available frameworks" do
203
+ any_instance_of(VMC::Detector) do |detector|
204
+ stub(detector).detect_framework
205
+ end
206
+
207
+ mock_ask('Framework', anything) do |_, options|
208
+ expect(options[:choices]).to eq frameworks.sort_by(&:name)
209
+ framework
210
+ end
211
+
212
+ subject
213
+ end
214
+ end
215
+ end
216
+ end
217
+
218
+ describe '#detect_runtimes' do
219
+ subject { create.determine_runtime(framework) }
220
+
221
+ context 'when runtime is given' do
222
+ let(:inputs) { { :runtime => runtime } }
223
+
224
+ it 'does not try to get the runtime' do
225
+ any_instance_of(VMC::Detector) do |detector|
226
+ dont_allow(detector).detect_runtime
227
+ dont_allow(detector).all_runtimes
228
+ end
229
+
230
+ dont_allow_ask
231
+ dont_allow(client).runtimes
232
+
233
+ subject
234
+ end
235
+
236
+ it { should eq runtime }
237
+ end
238
+
239
+ context 'when runtime is not given' do
240
+ context 'and the framework is standalone' do
241
+ let(:framework) { standalone }
242
+
243
+ it "detects the runtime" do
244
+ any_instance_of(VMC::Detector) do |detector|
245
+ mock(detector).detect_runtimes { runtimes }
246
+ end
247
+
248
+ mock_ask('Runtime', anything) do |_, options|
249
+ expect(options[:choices]).to eq(runtimes.sort_by(&:name) + [:other])
250
+ runtime
251
+ end
252
+
253
+ subject
254
+ end
255
+ end
256
+
257
+ context 'and the framework is not standalone' do
258
+ it "gets the runtimes based on the framework" do
259
+ any_instance_of(VMC::Detector) do |detector|
260
+ mock(detector).runtimes(framework) { runtimes }
261
+ end
262
+
263
+ mock_ask('Runtime', anything) do |_, options|
264
+ expect(options[:choices]).to eq(runtimes.sort_by(&:name) + [:other])
265
+ runtime
266
+ end
267
+
268
+ subject
269
+ end
270
+ end
271
+ end
272
+ end
273
+
274
+ describe '#create_app' do
275
+ before { dont_allow_ask }
276
+
277
+ let(:app) { fake(:app, :guid => nil) }
278
+
279
+ let(:attributes) do
280
+ { :name => "some-app",
281
+ :total_instances => 2,
282
+ :framework => framework,
283
+ :runtime => runtime,
284
+ :production => false,
285
+ :memory => 1024,
286
+ :buildpack => "git://example.com"
287
+ }
288
+ end
289
+
290
+ before { stub(client).app { app } }
291
+
292
+ subject { create.create_app(attributes) }
293
+
294
+ it 'creates an app based on the resulting inputs' do
295
+ mock(create).filter(:create_app, app) { app }
296
+
297
+ mock(app).create!
298
+
299
+ subject
300
+
301
+ attributes.each do |key, val|
302
+ expect(app.send(key)).to eq val
303
+ end
304
+ end
305
+
306
+ context "with an invalid buildpack" do
307
+ before do
308
+ stub(app).create! do
309
+ raise CFoundry::MessageParseError.new(
310
+ "Request invalid due to parse error: Field: buildpack, Error: Value git@github.com:cloudfoundry/heroku-buildpack-ruby.git doesn't match regexp String /GIT_URL_REGEX/",
311
+ 1001)
312
+ end
313
+ end
314
+
315
+ it "fails and prints a pretty message" do
316
+ stub(create).line(anything)
317
+ expect { subject }.to raise_error(
318
+ VMC::UserError, "Buildpack must be a public git repository URI.")
319
+ end
320
+ end
321
+ end
322
+
323
+ describe '#map_url' do
324
+ let(:app) { fake(:app, :space => space) }
325
+ let(:space) { fake(:space, :domains => domains) }
326
+ let(:domains) { [fake(:domain, :name => "foo.com")] }
327
+ let(:hosts) { [app.name] }
328
+
329
+ subject { create.map_route(app) }
330
+
331
+ it "asks for a subdomain with 'none' as an option" do
332
+ mock_ask('Subdomain', anything) do |_, options|
333
+ expect(options[:choices]).to eq(hosts + %w(none))
334
+ expect(options[:default]).to eq hosts.first
335
+ hosts.first
336
+ end
337
+
338
+ stub_ask("Domain", anything) { domains.first }
339
+
340
+ stub(create).invoke
341
+
342
+ subject
343
+ end
344
+
345
+ it "asks for a domain with 'none' as an option" do
346
+ stub_ask("Subdomain", anything) { hosts.first }
347
+
348
+ mock_ask('Domain', anything) do |_, options|
349
+ expect(options[:choices]).to eq(domains + %w(none))
350
+ expect(options[:default]).to eq domains.first
351
+ domains.first
352
+ end
353
+
354
+ stub(create).invoke
355
+
356
+ subject
357
+ end
358
+
359
+ it "maps the host and domain after both are given" do
360
+ stub_ask('Subdomain', anything) { hosts.first }
361
+ stub_ask('Domain', anything) { domains.first }
362
+
363
+ mock(create).invoke(:map,
364
+ :app => app, :host => hosts.first,
365
+ :domain => domains.first)
366
+
367
+ subject
368
+ end
369
+
370
+ context "when 'none' is given as the host" do
371
+ context "and a domain is provided afterwards" do
372
+ it "invokes 'map' with an empty host" do
373
+ mock_ask('Subdomain', anything) { "none" }
374
+ stub_ask('Domain', anything) { domains.first }
375
+
376
+ mock(create).invoke(:map,
377
+ :host => "", :domain => domains.first, :app => app)
378
+
379
+ subject
380
+ end
381
+ end
382
+ end
383
+
384
+ context "when 'none' is given as the domain" do
385
+ it "does not perform any mapping" do
386
+ stub_ask('Subdomain', anything) { "foo" }
387
+ mock_ask('Domain', anything) { "none" }
388
+
389
+ dont_allow(create).invoke(:map, anything)
390
+
391
+ subject
392
+ end
393
+ end
394
+
395
+ context "when mapping fails" do
396
+ before do
397
+ mock_ask('Subdomain', anything) { "foo" }
398
+ mock_ask('Domain', anything) { domains.first }
399
+
400
+ mock(create).invoke(:map,
401
+ :host => "foo", :domain => domains.first, :app => app) do
402
+ raise CFoundry::RouteHostTaken.new("foo", 1234)
403
+ end
404
+ end
405
+
406
+ it "asks again" do
407
+ stub(create).line
408
+
409
+ mock_ask('Subdomain', anything) { hosts.first }
410
+ mock_ask('Domain', anything) { domains.first }
411
+
412
+ stub(create).invoke
413
+
414
+ subject
415
+ end
416
+
417
+ it "reports the failure message" do
418
+ mock(create).line "foo"
419
+ mock(create).line
420
+
421
+ stub_ask('Subdomain', anything) { hosts.first }
422
+ stub_ask('Domain', anything) { domains.first }
423
+
424
+ stub(create).invoke
425
+
426
+ subject
427
+ end
428
+ end
429
+ end
430
+
431
+ describe '#create_services' do
432
+ let(:app) { fake(:app) }
433
+ subject { create.create_services(app) }
434
+
435
+ context 'when forcing' do
436
+ let(:inputs) { {:force => true} }
437
+
438
+ it "does not ask to create any services" do
439
+ dont_allow_ask("Create services for application?", anything)
440
+ subject
441
+ end
442
+
443
+ it "does not create any services" do
444
+ dont_allow(create).invoke(:create_service, anything)
445
+ subject
446
+ end
447
+ end
448
+
449
+ context 'when not forcing' do
450
+ let(:inputs) { { :force => false } }
451
+
452
+ it 'does not create the service if asked not to' do
453
+ mock_ask("Create services for application?", anything) { false }
454
+ dont_allow(create).invoke(:create_service, anything)
455
+
456
+ subject
457
+ end
458
+
459
+ it 'asks again to create a service' do
460
+ mock_ask("Create services for application?", anything) { true }
461
+ mock(create).invoke(:create_service, { :app => app }, :plan => :interact).ordered
462
+
463
+ mock_ask("Create another service?", :default => false) { true }
464
+ mock(create).invoke(:create_service, { :app => app }, :plan => :interact).ordered
465
+
466
+ mock_ask("Create another service?", :default => false) { true }
467
+ mock(create).invoke(:create_service, { :app => app }, :plan => :interact).ordered
468
+
469
+ mock_ask("Create another service?", :default => false) { false }
470
+ dont_allow(create).invoke(:create_service, anything).ordered
471
+
472
+ subject
473
+ end
474
+ end
475
+ end
476
+
477
+ describe '#bind_services' do
478
+ let(:app) { fake(:app) }
479
+
480
+ subject { create.bind_services(app) }
481
+
482
+ context 'when forcing' do
483
+ let(:global) { { :force => true, :color => false, :quiet => true } }
484
+
485
+ it "does not ask to bind any services" do
486
+ dont_allow_ask("Bind other services to application?", anything)
487
+ subject
488
+ end
489
+
490
+ it "does not bind any services" do
491
+ dont_allow(create).invoke(:bind_service, anything)
492
+ subject
493
+ end
494
+ end
495
+
496
+ context 'when not forcing' do
497
+ it 'does not bind the service if asked not to' do
498
+ mock_ask("Bind other services to application?", anything) { false }
499
+ dont_allow(create).invoke(:bind_service, anything)
500
+
501
+ subject
502
+ end
503
+
504
+ it 'asks again to bind a service' do
505
+ bind_times = 3
506
+ call_count = 0
507
+
508
+ mock_ask("Bind other services to application?", anything) { true }
509
+
510
+ mock(create).invoke(:bind_service, :app => app).times(bind_times) do
511
+ call_count += 1
512
+ stub(app).services { service_instances.first(call_count) }
513
+ end
514
+
515
+ mock_ask("Bind another service?", anything).times(bind_times) do
516
+ call_count < bind_times
517
+ end
518
+
519
+ subject
520
+ end
521
+
522
+ it 'stops asking if there are no more services to bind' do
523
+ bind_times = service_instances.size
524
+ call_count = 0
525
+
526
+ mock_ask("Bind other services to application?", anything) { true }
527
+
528
+ mock(create).invoke(:bind_service, :app => app).times(bind_times) do
529
+ call_count += 1
530
+ stub(app).services { service_instances.first(call_count) }
531
+ end
532
+
533
+ mock_ask("Bind another service?", anything).times(bind_times - 1) { true }
534
+
535
+ subject
536
+ end
537
+
538
+ context 'when there are no services' do
539
+ let(:service_instances) { [] }
540
+
541
+ it 'does not ask to bind anything' do
542
+ dont_allow_ask
543
+ subject
544
+ end
545
+ end
546
+ end
547
+ end
548
+
549
+ describe '#start_app' do
550
+ let(:app) { fake(:app) }
551
+ subject { create.start_app(app) }
552
+
553
+ context 'when the start flag is provided' do
554
+ let(:inputs) { {:start => true} }
555
+
556
+ it 'invokes the start command' do
557
+ mock(create).invoke(:start, :app => app)
558
+ subject
559
+ end
560
+ end
561
+
562
+ context 'when the start flag is not provided' do
563
+ let(:inputs) { {:start => false} }
564
+
565
+ it 'invokes the start command' do
566
+ dont_allow(create).invoke(:start, anything)
567
+ subject
568
+ end
569
+ end
570
+ end
571
+ end