capistrano 1.4.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/CHANGELOG +140 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README +22 -14
  4. data/bin/cap +1 -8
  5. data/bin/capify +77 -0
  6. data/examples/sample.rb +10 -109
  7. data/lib/capistrano.rb +1 -0
  8. data/lib/capistrano/callback.rb +41 -0
  9. data/lib/capistrano/cli.rb +17 -317
  10. data/lib/capistrano/cli/execute.rb +82 -0
  11. data/lib/capistrano/cli/help.rb +102 -0
  12. data/lib/capistrano/cli/help.txt +53 -0
  13. data/lib/capistrano/cli/options.rb +183 -0
  14. data/lib/capistrano/cli/ui.rb +28 -0
  15. data/lib/capistrano/command.rb +62 -29
  16. data/lib/capistrano/configuration.rb +25 -226
  17. data/lib/capistrano/configuration/actions/file_transfer.rb +35 -0
  18. data/lib/capistrano/configuration/actions/inspect.rb +46 -0
  19. data/lib/capistrano/configuration/actions/invocation.rb +127 -0
  20. data/lib/capistrano/configuration/callbacks.rb +148 -0
  21. data/lib/capistrano/configuration/connections.rb +159 -0
  22. data/lib/capistrano/configuration/execution.rb +126 -0
  23. data/lib/capistrano/configuration/loading.rb +112 -0
  24. data/lib/capistrano/configuration/namespaces.rb +190 -0
  25. data/lib/capistrano/configuration/roles.rb +51 -0
  26. data/lib/capistrano/configuration/servers.rb +75 -0
  27. data/lib/capistrano/configuration/variables.rb +127 -0
  28. data/lib/capistrano/errors.rb +15 -0
  29. data/lib/capistrano/extensions.rb +27 -8
  30. data/lib/capistrano/gateway.rb +54 -29
  31. data/lib/capistrano/logger.rb +11 -11
  32. data/lib/capistrano/recipes/compat.rb +32 -0
  33. data/lib/capistrano/recipes/deploy.rb +483 -0
  34. data/lib/capistrano/recipes/deploy/dependencies.rb +44 -0
  35. data/lib/capistrano/recipes/deploy/local_dependency.rb +46 -0
  36. data/lib/capistrano/recipes/deploy/remote_dependency.rb +65 -0
  37. data/lib/capistrano/recipes/deploy/scm.rb +19 -0
  38. data/lib/capistrano/recipes/deploy/scm/base.rb +180 -0
  39. data/lib/capistrano/recipes/deploy/scm/bzr.rb +86 -0
  40. data/lib/capistrano/recipes/deploy/scm/cvs.rb +151 -0
  41. data/lib/capistrano/recipes/deploy/scm/darcs.rb +85 -0
  42. data/lib/capistrano/recipes/deploy/scm/mercurial.rb +129 -0
  43. data/lib/capistrano/recipes/deploy/scm/perforce.rb +126 -0
  44. data/lib/capistrano/recipes/deploy/scm/subversion.rb +103 -0
  45. data/lib/capistrano/recipes/deploy/strategy.rb +19 -0
  46. data/lib/capistrano/recipes/deploy/strategy/base.rb +64 -0
  47. data/lib/capistrano/recipes/deploy/strategy/checkout.rb +20 -0
  48. data/lib/capistrano/recipes/deploy/strategy/copy.rb +143 -0
  49. data/lib/capistrano/recipes/deploy/strategy/export.rb +20 -0
  50. data/lib/capistrano/recipes/deploy/strategy/remote.rb +52 -0
  51. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +47 -0
  52. data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +53 -0
  53. data/lib/capistrano/recipes/standard.rb +26 -276
  54. data/lib/capistrano/recipes/templates/maintenance.rhtml +1 -1
  55. data/lib/capistrano/recipes/upgrade.rb +33 -0
  56. data/lib/capistrano/server_definition.rb +51 -0
  57. data/lib/capistrano/shell.rb +125 -81
  58. data/lib/capistrano/ssh.rb +80 -36
  59. data/lib/capistrano/task_definition.rb +69 -0
  60. data/lib/capistrano/upload.rb +146 -0
  61. data/lib/capistrano/version.rb +13 -17
  62. data/test/cli/execute_test.rb +132 -0
  63. data/test/cli/help_test.rb +139 -0
  64. data/test/cli/options_test.rb +226 -0
  65. data/test/cli/ui_test.rb +28 -0
  66. data/test/cli_test.rb +17 -0
  67. data/test/command_test.rb +284 -25
  68. data/test/configuration/actions/file_transfer_test.rb +40 -0
  69. data/test/configuration/actions/inspect_test.rb +62 -0
  70. data/test/configuration/actions/invocation_test.rb +195 -0
  71. data/test/configuration/callbacks_test.rb +206 -0
  72. data/test/configuration/connections_test.rb +288 -0
  73. data/test/configuration/execution_test.rb +159 -0
  74. data/test/configuration/loading_test.rb +119 -0
  75. data/test/configuration/namespace_dsl_test.rb +283 -0
  76. data/test/configuration/roles_test.rb +47 -0
  77. data/test/configuration/servers_test.rb +90 -0
  78. data/test/configuration/variables_test.rb +180 -0
  79. data/test/configuration_test.rb +60 -212
  80. data/test/deploy/scm/base_test.rb +55 -0
  81. data/test/deploy/strategy/copy_test.rb +146 -0
  82. data/test/extensions_test.rb +69 -0
  83. data/test/fixtures/cli_integration.rb +5 -0
  84. data/test/fixtures/custom.rb +2 -2
  85. data/test/gateway_test.rb +167 -0
  86. data/test/logger_test.rb +123 -0
  87. data/test/server_definition_test.rb +108 -0
  88. data/test/shell_test.rb +64 -0
  89. data/test/ssh_test.rb +67 -154
  90. data/test/task_definition_test.rb +101 -0
  91. data/test/upload_test.rb +131 -0
  92. data/test/utils.rb +31 -39
  93. data/test/version_test.rb +24 -0
  94. metadata +145 -98
  95. data/THANKS +0 -4
  96. data/lib/capistrano/actor.rb +0 -567
  97. data/lib/capistrano/generators/rails/deployment/deployment_generator.rb +0 -25
  98. data/lib/capistrano/generators/rails/deployment/templates/capistrano.rake +0 -49
  99. data/lib/capistrano/generators/rails/deployment/templates/deploy.rb +0 -122
  100. data/lib/capistrano/generators/rails/loader.rb +0 -20
  101. data/lib/capistrano/scm/base.rb +0 -61
  102. data/lib/capistrano/scm/baz.rb +0 -118
  103. data/lib/capistrano/scm/bzr.rb +0 -70
  104. data/lib/capistrano/scm/cvs.rb +0 -129
  105. data/lib/capistrano/scm/darcs.rb +0 -27
  106. data/lib/capistrano/scm/mercurial.rb +0 -83
  107. data/lib/capistrano/scm/perforce.rb +0 -139
  108. data/lib/capistrano/scm/subversion.rb +0 -128
  109. data/lib/capistrano/transfer.rb +0 -97
  110. data/lib/capistrano/utils.rb +0 -26
  111. data/test/actor_test.rb +0 -402
  112. data/test/scm/cvs_test.rb +0 -196
  113. 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