af 0.3.22 → 0.5.0.beta.1

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.
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