capistrano 1.4.2 → 2.0.0
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/CHANGELOG +140 -4
- data/MIT-LICENSE +1 -1
- data/README +22 -14
- data/bin/cap +1 -8
- data/bin/capify +77 -0
- data/examples/sample.rb +10 -109
- data/lib/capistrano.rb +1 -0
- data/lib/capistrano/callback.rb +41 -0
- data/lib/capistrano/cli.rb +17 -317
- data/lib/capistrano/cli/execute.rb +82 -0
- data/lib/capistrano/cli/help.rb +102 -0
- data/lib/capistrano/cli/help.txt +53 -0
- data/lib/capistrano/cli/options.rb +183 -0
- data/lib/capistrano/cli/ui.rb +28 -0
- data/lib/capistrano/command.rb +62 -29
- data/lib/capistrano/configuration.rb +25 -226
- data/lib/capistrano/configuration/actions/file_transfer.rb +35 -0
- data/lib/capistrano/configuration/actions/inspect.rb +46 -0
- data/lib/capistrano/configuration/actions/invocation.rb +127 -0
- data/lib/capistrano/configuration/callbacks.rb +148 -0
- data/lib/capistrano/configuration/connections.rb +159 -0
- data/lib/capistrano/configuration/execution.rb +126 -0
- data/lib/capistrano/configuration/loading.rb +112 -0
- data/lib/capistrano/configuration/namespaces.rb +190 -0
- data/lib/capistrano/configuration/roles.rb +51 -0
- data/lib/capistrano/configuration/servers.rb +75 -0
- data/lib/capistrano/configuration/variables.rb +127 -0
- data/lib/capistrano/errors.rb +15 -0
- data/lib/capistrano/extensions.rb +27 -8
- data/lib/capistrano/gateway.rb +54 -29
- data/lib/capistrano/logger.rb +11 -11
- data/lib/capistrano/recipes/compat.rb +32 -0
- data/lib/capistrano/recipes/deploy.rb +483 -0
- data/lib/capistrano/recipes/deploy/dependencies.rb +44 -0
- data/lib/capistrano/recipes/deploy/local_dependency.rb +46 -0
- data/lib/capistrano/recipes/deploy/remote_dependency.rb +65 -0
- data/lib/capistrano/recipes/deploy/scm.rb +19 -0
- data/lib/capistrano/recipes/deploy/scm/base.rb +180 -0
- data/lib/capistrano/recipes/deploy/scm/bzr.rb +86 -0
- data/lib/capistrano/recipes/deploy/scm/cvs.rb +151 -0
- data/lib/capistrano/recipes/deploy/scm/darcs.rb +85 -0
- data/lib/capistrano/recipes/deploy/scm/mercurial.rb +129 -0
- data/lib/capistrano/recipes/deploy/scm/perforce.rb +126 -0
- data/lib/capistrano/recipes/deploy/scm/subversion.rb +103 -0
- data/lib/capistrano/recipes/deploy/strategy.rb +19 -0
- data/lib/capistrano/recipes/deploy/strategy/base.rb +64 -0
- data/lib/capistrano/recipes/deploy/strategy/checkout.rb +20 -0
- data/lib/capistrano/recipes/deploy/strategy/copy.rb +143 -0
- data/lib/capistrano/recipes/deploy/strategy/export.rb +20 -0
- data/lib/capistrano/recipes/deploy/strategy/remote.rb +52 -0
- data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +47 -0
- data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +53 -0
- data/lib/capistrano/recipes/standard.rb +26 -276
- data/lib/capistrano/recipes/templates/maintenance.rhtml +1 -1
- data/lib/capistrano/recipes/upgrade.rb +33 -0
- data/lib/capistrano/server_definition.rb +51 -0
- data/lib/capistrano/shell.rb +125 -81
- data/lib/capistrano/ssh.rb +80 -36
- data/lib/capistrano/task_definition.rb +69 -0
- data/lib/capistrano/upload.rb +146 -0
- data/lib/capistrano/version.rb +13 -17
- data/test/cli/execute_test.rb +132 -0
- data/test/cli/help_test.rb +139 -0
- data/test/cli/options_test.rb +226 -0
- data/test/cli/ui_test.rb +28 -0
- data/test/cli_test.rb +17 -0
- data/test/command_test.rb +284 -25
- data/test/configuration/actions/file_transfer_test.rb +40 -0
- data/test/configuration/actions/inspect_test.rb +62 -0
- data/test/configuration/actions/invocation_test.rb +195 -0
- data/test/configuration/callbacks_test.rb +206 -0
- data/test/configuration/connections_test.rb +288 -0
- data/test/configuration/execution_test.rb +159 -0
- data/test/configuration/loading_test.rb +119 -0
- data/test/configuration/namespace_dsl_test.rb +283 -0
- data/test/configuration/roles_test.rb +47 -0
- data/test/configuration/servers_test.rb +90 -0
- data/test/configuration/variables_test.rb +180 -0
- data/test/configuration_test.rb +60 -212
- data/test/deploy/scm/base_test.rb +55 -0
- data/test/deploy/strategy/copy_test.rb +146 -0
- data/test/extensions_test.rb +69 -0
- data/test/fixtures/cli_integration.rb +5 -0
- data/test/fixtures/custom.rb +2 -2
- data/test/gateway_test.rb +167 -0
- data/test/logger_test.rb +123 -0
- data/test/server_definition_test.rb +108 -0
- data/test/shell_test.rb +64 -0
- data/test/ssh_test.rb +67 -154
- data/test/task_definition_test.rb +101 -0
- data/test/upload_test.rb +131 -0
- data/test/utils.rb +31 -39
- data/test/version_test.rb +24 -0
- metadata +145 -98
- data/THANKS +0 -4
- data/lib/capistrano/actor.rb +0 -567
- data/lib/capistrano/generators/rails/deployment/deployment_generator.rb +0 -25
- data/lib/capistrano/generators/rails/deployment/templates/capistrano.rake +0 -49
- data/lib/capistrano/generators/rails/deployment/templates/deploy.rb +0 -122
- data/lib/capistrano/generators/rails/loader.rb +0 -20
- data/lib/capistrano/scm/base.rb +0 -61
- data/lib/capistrano/scm/baz.rb +0 -118
- data/lib/capistrano/scm/bzr.rb +0 -70
- data/lib/capistrano/scm/cvs.rb +0 -129
- data/lib/capistrano/scm/darcs.rb +0 -27
- data/lib/capistrano/scm/mercurial.rb +0 -83
- data/lib/capistrano/scm/perforce.rb +0 -139
- data/lib/capistrano/scm/subversion.rb +0 -128
- data/lib/capistrano/transfer.rb +0 -97
- data/lib/capistrano/utils.rb +0 -26
- data/test/actor_test.rb +0 -402
- data/test/scm/cvs_test.rb +0 -196
- data/test/scm/subversion_test.rb +0 -145
@@ -0,0 +1,283 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../utils"
|
2
|
+
require 'capistrano/configuration/namespaces'
|
3
|
+
|
4
|
+
class ConfigurationNamespacesDSLTest < Test::Unit::TestCase
|
5
|
+
class MockConfig
|
6
|
+
attr_reader :original_initialize_called, :options
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@original_initialize_called = true
|
10
|
+
@options = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
include Capistrano::Configuration::Namespaces
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup
|
17
|
+
@config = MockConfig.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_initialize_should_initialize_collections
|
21
|
+
assert @config.original_initialize_called
|
22
|
+
assert @config.tasks.empty?
|
23
|
+
assert @config.namespaces.empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_unqualified_task_should_define_task_at_top_namespace
|
27
|
+
assert !@config.tasks.key?(:testing)
|
28
|
+
@config.task(:testing) { puts "something" }
|
29
|
+
assert @config.tasks.key?(:testing)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_qualification_should_define_task_within_namespace
|
33
|
+
@config.namespace(:testing) do
|
34
|
+
task(:nested) { puts "nested" }
|
35
|
+
end
|
36
|
+
|
37
|
+
assert !@config.tasks.key?(:nested)
|
38
|
+
assert @config.namespaces.key?(:testing)
|
39
|
+
assert @config.namespaces[:testing].tasks.key?(:nested)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_namespace_within_namespace_should_define_task_within_nested_namespace
|
43
|
+
@config.namespace :outer do
|
44
|
+
namespace :inner do
|
45
|
+
task :nested do
|
46
|
+
puts "nested"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
assert !@config.tasks.key?(:nested)
|
52
|
+
assert @config.namespaces.key?(:outer)
|
53
|
+
assert @config.namespaces[:outer].namespaces.key?(:inner)
|
54
|
+
assert @config.namespaces[:outer].namespaces[:inner].tasks.key?(:nested)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_pending_desc_should_apply_only_to_immediately_subsequent_task
|
58
|
+
@config.desc "A description"
|
59
|
+
@config.task(:testing) { puts "foo" }
|
60
|
+
@config.task(:another) { puts "bar" }
|
61
|
+
assert_equal "A description", @config.tasks[:testing].desc
|
62
|
+
assert_nil @config.tasks[:another].desc
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_pending_desc_should_apply_only_to_next_task_in_any_namespace
|
66
|
+
@config.desc "A description"
|
67
|
+
@config.namespace(:outer) { task(:testing) { puts "foo" } }
|
68
|
+
assert_equal "A description", @config.namespaces[:outer].tasks[:testing].desc
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_defining_task_without_block_should_raise_error
|
72
|
+
assert_raises(ArgumentError) do
|
73
|
+
@config.task(:testing)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_defining_task_that_shadows_existing_method_should_raise_error
|
78
|
+
assert_raises(ArgumentError) do
|
79
|
+
@config.task(:sprintf) { puts "foo" }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_defining_task_that_shadows_existing_namespace_should_raise_error
|
84
|
+
@config.namespace(:outer) {}
|
85
|
+
assert_raises(ArgumentError) do
|
86
|
+
@config.task(:outer) { puts "foo" }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_defining_namespace_that_shadows_existing_method_should_raise_error
|
91
|
+
assert_raises(ArgumentError) do
|
92
|
+
@config.namespace(:sprintf) {}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_defining_namespace_that_shadows_existing_task_should_raise_error
|
97
|
+
@config.task(:testing) { puts "foo" }
|
98
|
+
assert_raises(ArgumentError) do
|
99
|
+
@config.namespace(:testing) {}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_defining_task_that_shadows_existing_task_should_not_raise_error
|
104
|
+
@config.task(:original) { puts "foo" }
|
105
|
+
assert_nothing_raised do
|
106
|
+
@config.task(:original) { puts "bar" }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_defining_ask_should_add_task_as_method
|
111
|
+
assert !@config.methods.include?("original")
|
112
|
+
@config.task(:original) { puts "foo" }
|
113
|
+
assert @config.methods.include?("original")
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_calling_defined_task_should_delegate_to_execute_task
|
117
|
+
@config.task(:original) { puts "foo" }
|
118
|
+
@config.expects(:execute_task).with(@config.tasks[:original])
|
119
|
+
@config.original
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_role_inside_namespace_should_raise_error
|
123
|
+
assert_raises(NotImplementedError) do
|
124
|
+
@config.namespace(:outer) do
|
125
|
+
role :app, "hello"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_name_for_top_level_should_be_nil
|
131
|
+
assert_nil @config.name
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_parent_for_top_level_should_be_nil
|
135
|
+
assert_nil @config.parent
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_fqn_for_top_level_should_be_nil
|
139
|
+
assert_nil @config.fully_qualified_name
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_fqn_for_namespace_should_be_the_name_of_the_namespace
|
143
|
+
@config.namespace(:outer) {}
|
144
|
+
assert_equal "outer", @config.namespaces[:outer].fully_qualified_name
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_parent_for_namespace_should_be_the_top_level
|
148
|
+
@config.namespace(:outer) {}
|
149
|
+
assert_equal @config, @config.namespaces[:outer].parent
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_fqn_for_nested_namespace_should_be_color_delimited
|
153
|
+
@config.namespace(:outer) { namespace(:inner) {} }
|
154
|
+
assert_equal "outer:inner", @config.namespaces[:outer].namespaces[:inner].fully_qualified_name
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_parent_for_nested_namespace_should_be_the_nesting_namespace
|
158
|
+
@config.namespace(:outer) { namespace(:inner) {} }
|
159
|
+
assert_equal @config.namespaces[:outer], @config.namespaces[:outer].namespaces[:inner].parent
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_find_task_should_dereference_nested_tasks
|
163
|
+
@config.namespace(:outer) do
|
164
|
+
namespace(:inner) { task(:nested) { puts "nested" } }
|
165
|
+
end
|
166
|
+
|
167
|
+
task = @config.find_task("outer:inner:nested")
|
168
|
+
assert_not_nil task
|
169
|
+
assert_equal "outer:inner:nested", task.fully_qualified_name
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_find_task_should_return_nil_if_no_task_matches
|
173
|
+
assert_nil @config.find_task("outer:inner:nested")
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_find_task_should_return_default_if_deferences_to_namespace_and_namespace_has_default
|
177
|
+
@config.namespace(:outer) do
|
178
|
+
namespace(:inner) { task(:default) { puts "nested" } }
|
179
|
+
end
|
180
|
+
|
181
|
+
task = @config.find_task("outer:inner")
|
182
|
+
assert_not_nil task
|
183
|
+
assert_equal :default, task.name
|
184
|
+
assert_equal "outer:inner", task.namespace.fully_qualified_name
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_find_task_should_return_nil_if_deferences_to_namespace_and_namespace_has_no_default
|
188
|
+
@config.namespace(:outer) do
|
189
|
+
namespace(:inner) { task(:nested) { puts "nested" } }
|
190
|
+
end
|
191
|
+
|
192
|
+
assert_nil @config.find_task("outer:inner")
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_default_task_should_return_nil_for_top_level
|
196
|
+
@config.task(:default) {}
|
197
|
+
assert_nil @config.default_task
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_default_task_should_return_nil_for_namespace_without_default
|
201
|
+
@config.namespace(:outer) { task(:nested) { puts "nested" } }
|
202
|
+
assert_nil @config.namespaces[:outer].default_task
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_default_task_should_return_task_for_namespace_with_default
|
206
|
+
@config.namespace(:outer) { task(:default) { puts "nested" } }
|
207
|
+
task = @config.namespaces[:outer].default_task
|
208
|
+
assert_not_nil task
|
209
|
+
assert_equal :default, task.name
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_task_list_should_return_only_tasks_immediately_within_namespace
|
213
|
+
@config.task(:first) { puts "here" }
|
214
|
+
@config.namespace(:outer) do
|
215
|
+
task(:second) { puts "here" }
|
216
|
+
namespace(:inner) do
|
217
|
+
task(:third) { puts "here" }
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
assert_equal %w(first), @config.task_list.map { |t| t.fully_qualified_name }
|
222
|
+
end
|
223
|
+
|
224
|
+
def test_task_list_with_all_should_return_all_tasks_under_this_namespace_recursively
|
225
|
+
@config.task(:first) { puts "here" }
|
226
|
+
@config.namespace(:outer) do
|
227
|
+
task(:second) { puts "here" }
|
228
|
+
namespace(:inner) do
|
229
|
+
task(:third) { puts "here" }
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
assert_equal %w(first outer:inner:third outer:second), @config.task_list(:all).map { |t| t.fully_qualified_name }.sort
|
234
|
+
end
|
235
|
+
|
236
|
+
def test_namespace_should_respond_to_its_parents_methods
|
237
|
+
@config.namespace(:outer) {}
|
238
|
+
ns = @config.namespaces[:outer]
|
239
|
+
assert ns.respond_to?(:original_initialize_called)
|
240
|
+
end
|
241
|
+
|
242
|
+
def test_namespace_should_delegate_unknown_messages_to_its_parent
|
243
|
+
@config.namespace(:outer) {}
|
244
|
+
ns = @config.namespaces[:outer]
|
245
|
+
assert ns.original_initialize_called
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_namespace_should_not_understand_messages_that_neither_it_nor_its_parent_understands
|
249
|
+
@config.namespace(:outer) {}
|
250
|
+
ns = @config.namespaces[:outer]
|
251
|
+
assert_raises(NoMethodError) { ns.alskdfjlsf }
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_search_task_should_find_tasks_in_current_namespace
|
255
|
+
@config.namespace(:outer) do
|
256
|
+
namespace(:inner) do
|
257
|
+
task(:third) { puts "here" }
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
inner = @config.namespaces[:outer].namespaces[:inner]
|
262
|
+
assert_equal inner.tasks[:third], inner.search_task(:third)
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_search_task_should_find_tasks_in_parent_namespace
|
266
|
+
@config.task(:first) { puts "here" }
|
267
|
+
@config.namespace(:outer) do
|
268
|
+
task(:second) { puts "here" }
|
269
|
+
namespace(:inner) do
|
270
|
+
task(:third) { puts "here" }
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
inner = @config.namespaces[:outer].namespaces[:inner]
|
275
|
+
assert_equal @config.tasks[:first], inner.search_task(:first)
|
276
|
+
end
|
277
|
+
|
278
|
+
def test_search_task_should_return_nil_if_no_tasks_are_found
|
279
|
+
@config.namespace(:outer) { namespace(:inner) {} }
|
280
|
+
inner = @config.namespaces[:outer].namespaces[:inner]
|
281
|
+
assert_nil inner.search_task(:first)
|
282
|
+
end
|
283
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../utils"
|
2
|
+
require 'capistrano/configuration/roles'
|
3
|
+
|
4
|
+
class ConfigurationRolesTest < Test::Unit::TestCase
|
5
|
+
class MockConfig
|
6
|
+
attr_reader :original_initialize_called
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@original_initialize_called = true
|
10
|
+
end
|
11
|
+
|
12
|
+
include Capistrano::Configuration::Roles
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup
|
16
|
+
@config = MockConfig.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_initialize_should_initialize_roles_collection
|
20
|
+
assert @config.original_initialize_called
|
21
|
+
assert @config.roles.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_role_should_allow_empty_list
|
25
|
+
@config.role :app
|
26
|
+
assert @config.roles[:app].empty?
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_role_with_one_argument_should_add_to_roles_collection
|
30
|
+
@config.role :app, "app1.capistrano.test"
|
31
|
+
assert_equal [:app], @config.roles.keys
|
32
|
+
assert_equal %w(app1.capistrano.test), @config.roles[:app].map { |s| s.host }
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_role_with_multiple_arguments_should_add_each_to_roles_collection
|
36
|
+
@config.role :app, "app1.capistrano.test", "app2.capistrano.test"
|
37
|
+
assert_equal [:app], @config.roles.keys
|
38
|
+
assert_equal %w(app1.capistrano.test app2.capistrano.test), @config.roles[:app].map { |s| s.host }
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_role_with_options_should_apply_options_to_each_argument
|
42
|
+
@config.role :app, "app1.capistrano.test", "app2.capistrano.test", :extra => :value
|
43
|
+
@config.roles[:app].each do |server|
|
44
|
+
assert_equal({:extra => :value}, server.options)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../utils"
|
2
|
+
require 'capistrano/task_definition'
|
3
|
+
require 'capistrano/configuration/servers'
|
4
|
+
|
5
|
+
class ConfigurationServersTest < Test::Unit::TestCase
|
6
|
+
class MockConfig
|
7
|
+
attr_reader :roles
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@roles = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
include Capistrano::Configuration::Servers
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup
|
17
|
+
@config = MockConfig.new
|
18
|
+
role(@config, :app, "app1", :primary => true)
|
19
|
+
role(@config, :app, "app2", "app3")
|
20
|
+
role(@config, :web, "web1", "web2")
|
21
|
+
role(@config, :report, "app2", :no_deploy => true)
|
22
|
+
role(@config, :file, "file", :no_deploy => true)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_task_without_roles_should_apply_to_all_defined_hosts
|
26
|
+
task = new_task(:testing)
|
27
|
+
assert_equal %w(app1 app2 app3 web1 web2 file).sort, @config.find_servers_for_task(task).map { |s| s.host }.sort
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_task_with_explicit_role_list_should_apply_only_to_those_roles
|
31
|
+
task = new_task(:testing, @config, :roles => %w(app web))
|
32
|
+
assert_equal %w(app1 app2 app3 web1 web2).sort, @config.find_servers_for_task(task).map { |s| s.host }.sort
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_task_with_single_role_should_apply_only_to_that_role
|
36
|
+
task = new_task(:testing, @config, :roles => :web)
|
37
|
+
assert_equal %w(web1 web2).sort, @config.find_servers_for_task(task).map { |s| s.host }.sort
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_task_with_hosts_option_should_apply_only_to_those_hosts
|
41
|
+
task = new_task(:testing, @config, :hosts => %w(foo bar))
|
42
|
+
assert_equal %w(foo bar).sort, @config.find_servers_for_task(task).map { |s| s.host }.sort
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_task_with_single_hosts_option_should_apply_only_to_that_host
|
46
|
+
task = new_task(:testing, @config, :hosts => "foo")
|
47
|
+
assert_equal %w(foo).sort, @config.find_servers_for_task(task).map { |s| s.host }.sort
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_task_with_roles_as_environment_variable_should_apply_only_to_that_role
|
51
|
+
ENV['ROLES'] = "app,file"
|
52
|
+
task = new_task(:testing)
|
53
|
+
assert_equal %w(app1 app2 app3 file).sort, @config.find_servers_for_task(task).map { |s| s.host }.sort
|
54
|
+
ensure
|
55
|
+
ENV['ROLES'] = nil
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_task_with_hosts_as_environment_variable_should_apply_only_to_those_hosts
|
59
|
+
ENV['HOSTS'] = "foo,bar"
|
60
|
+
task = new_task(:testing)
|
61
|
+
assert_equal %w(foo bar).sort, @config.find_servers_for_task(task).map { |s| s.host }.sort
|
62
|
+
ensure
|
63
|
+
ENV['HOSTS'] = nil
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_task_with_only_should_apply_only_to_matching_tasks
|
67
|
+
task = new_task(:testing, @config, :roles => :app, :only => { :primary => true })
|
68
|
+
assert_equal %w(app1), @config.find_servers_for_task(task).map { |s| s.host }
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_task_with_except_should_apply_only_to_matching_tasks
|
72
|
+
task = new_task(:testing, @config, :except => { :no_deploy => true })
|
73
|
+
assert_equal %w(app1 app2 app3 web1 web2).sort, @config.find_servers_for_task(task).map { |s| s.host }.sort
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_options_to_find_servers_for_task_should_override_options_in_task
|
77
|
+
task = new_task(:testing, @config, :roles => :web)
|
78
|
+
assert_equal %w(app1 app2 app3).sort, @config.find_servers_for_task(task, :roles => :app).map { |s| s.host }.sort
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_find_servers_with_lambda_for_hosts_should_be_evaluated
|
82
|
+
assert_equal %w(foo), @config.find_servers(:hosts => lambda { "foo" }).map { |s| s.host }.sort
|
83
|
+
assert_equal %w(bar foo), @config.find_servers(:hosts => lambda { %w(foo bar) }).map { |s| s.host }.sort
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_find_servers_with_lambda_for_roles_should_be_evaluated
|
87
|
+
assert_equal %w(app1 app2 app3), @config.find_servers(:roles => lambda { :app }).map { |s| s.host }.sort
|
88
|
+
assert_equal %w(app2 file), @config.find_servers(:roles => lambda { [:report, :file] }).map { |s| s.host }.sort
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../utils"
|
2
|
+
require 'capistrano/configuration/variables'
|
3
|
+
|
4
|
+
class ConfigurationVariablesTest < Test::Unit::TestCase
|
5
|
+
class MockConfig
|
6
|
+
attr_reader :original_initialize_called
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@original_initialize_called = true
|
10
|
+
end
|
11
|
+
|
12
|
+
include Capistrano::Configuration::Variables
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup
|
16
|
+
MockConfig.any_instance.stubs(:logger).returns(stub_everything)
|
17
|
+
@config = MockConfig.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_initialize_should_initialize_variables_hash
|
21
|
+
assert @config.original_initialize_called
|
22
|
+
assert_equal({:ssh_options => {}, :logger => @config.logger}, @config.variables)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_set_should_add_variable_to_hash
|
26
|
+
@config.set :sample, :value
|
27
|
+
assert_equal :value, @config.variables[:sample]
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_set_should_convert_variable_name_to_symbol
|
31
|
+
@config.set "sample", :value
|
32
|
+
assert_equal :value, @config.variables[:sample]
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_set_should_be_aliased_to_square_brackets
|
36
|
+
@config[:sample] = :value
|
37
|
+
assert_equal :value, @config.variables[:sample]
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_variables_should_be_accessible_as_read_accessors
|
41
|
+
@config[:sample] = :value
|
42
|
+
assert_equal :value, @config.sample
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_method_missing_should_raise_error_if_no_variable_matches
|
46
|
+
assert_raises(NoMethodError) do
|
47
|
+
@config.sample
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_respond_to_should_look_for_variables
|
52
|
+
assert !@config.respond_to?(:sample)
|
53
|
+
@config[:sample] = :value
|
54
|
+
assert @config.respond_to?(:sample)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_set_should_require_value
|
58
|
+
assert_raises(ArgumentError) do
|
59
|
+
@config.set(:sample)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_set_should_allow_value_to_be_omitted_if_block_is_given
|
64
|
+
assert_nothing_raised do
|
65
|
+
@config.set(:sample) { :value }
|
66
|
+
end
|
67
|
+
assert_instance_of Proc, @config.variables[:sample]
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_set_should_not_allow_multiple_values
|
71
|
+
assert_raises(ArgumentError) do
|
72
|
+
@config.set(:sample, :value, :another)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_set_should_not_allow_both_a_value_and_a_block
|
77
|
+
assert_raises(ArgumentError) do
|
78
|
+
@config.set(:sample, :value) { :block }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_set_should_not_allow_capitalized_variables
|
83
|
+
assert_raises(ArgumentError) do
|
84
|
+
@config.set :Sample, :value
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_unset_should_remove_variable_from_hash
|
89
|
+
@config.set :sample, :value
|
90
|
+
assert @config.variables.key?(:sample)
|
91
|
+
@config.unset :sample
|
92
|
+
assert !@config.variables.key?(:sample)
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_unset_should_clear_memory_of_original_proc
|
96
|
+
@config.set(:sample) { :value }
|
97
|
+
@config.fetch(:sample)
|
98
|
+
@config.unset(:sample)
|
99
|
+
assert_equal false, @config.reset!(:sample)
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_exists_should_report_existance_of_variable_in_hash
|
103
|
+
assert !@config.exists?(:sample)
|
104
|
+
@config[:sample] = :value
|
105
|
+
assert @config.exists?(:sample)
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_reset_should_do_nothing_if_variable_does_not_exist
|
109
|
+
assert_equal false, @config.reset!(:sample)
|
110
|
+
assert !@config.variables.key?(:sample)
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_reset_should_do_nothing_if_variable_is_not_a_proc
|
114
|
+
@config.set(:sample, :value)
|
115
|
+
assert_equal false, @config.reset!(:sample)
|
116
|
+
assert_equal :value, @config.variables[:sample]
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_reset_should_do_nothing_if_proc_variable_has_not_been_dereferenced
|
120
|
+
@config.set(:sample) { :value }
|
121
|
+
assert_equal false, @config.reset!(:sample)
|
122
|
+
assert_instance_of Proc, @config.variables[:sample]
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_reset_should_restore_variable_to_original_proc_value
|
126
|
+
@config.set(:sample) { :value }
|
127
|
+
assert_instance_of Proc, @config.variables[:sample]
|
128
|
+
@config.fetch(:sample)
|
129
|
+
assert_instance_of Symbol, @config.variables[:sample]
|
130
|
+
assert @config.reset!(:sample)
|
131
|
+
assert_instance_of Proc, @config.variables[:sample]
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_fetch_should_return_stored_non_proc_value
|
135
|
+
@config.set(:sample, :value)
|
136
|
+
assert_equal :value, @config.fetch(:sample)
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_fetch_should_raise_index_error_if_variable_does_not_exist
|
140
|
+
assert_raises(IndexError) do
|
141
|
+
@config.fetch(:sample)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_fetch_should_return_default_if_variable_does_not_exist_and_default_is_given
|
146
|
+
assert_nothing_raised do
|
147
|
+
assert_equal :default_value, @config.fetch(:sample, :default_value)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_fetch_should_invoke_block_if_variable_does_not_exist_and_block_is_given
|
152
|
+
assert_nothing_raised do
|
153
|
+
assert_equal :default_value, @config.fetch(:sample) { :default_value }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_fetch_should_raise_argument_error_if_both_default_and_block_are_given
|
158
|
+
assert_raises(ArgumentError) do
|
159
|
+
@config.fetch(:sample, :default1) { :default2 }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_fetch_should_dereference_proc_values
|
164
|
+
@config.set(:sample) { :value }
|
165
|
+
assert_instance_of Proc, @config.variables[:sample]
|
166
|
+
assert_equal :value, @config.fetch(:sample)
|
167
|
+
assert_instance_of Symbol, @config.variables[:sample]
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_square_brackets_should_alias_fetch
|
171
|
+
@config.set(:sample, :value)
|
172
|
+
assert_equal :value, @config[:sample]
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_square_brackets_should_return_nil_for_non_existant_variable
|
176
|
+
assert_nothing_raised do
|
177
|
+
assert_nil @config[:sample]
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|