minmb-capistrano 2.15.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. data/.gitignore +10 -0
  2. data/.travis.yml +7 -0
  3. data/CHANGELOG +1170 -0
  4. data/Gemfile +13 -0
  5. data/README.md +94 -0
  6. data/Rakefile +11 -0
  7. data/bin/cap +4 -0
  8. data/bin/capify +92 -0
  9. data/capistrano.gemspec +40 -0
  10. data/lib/capistrano.rb +5 -0
  11. data/lib/capistrano/callback.rb +45 -0
  12. data/lib/capistrano/cli.rb +47 -0
  13. data/lib/capistrano/cli/execute.rb +85 -0
  14. data/lib/capistrano/cli/help.rb +125 -0
  15. data/lib/capistrano/cli/help.txt +81 -0
  16. data/lib/capistrano/cli/options.rb +243 -0
  17. data/lib/capistrano/cli/ui.rb +40 -0
  18. data/lib/capistrano/command.rb +303 -0
  19. data/lib/capistrano/configuration.rb +57 -0
  20. data/lib/capistrano/configuration/actions/file_transfer.rb +50 -0
  21. data/lib/capistrano/configuration/actions/inspect.rb +46 -0
  22. data/lib/capistrano/configuration/actions/invocation.rb +329 -0
  23. data/lib/capistrano/configuration/alias_task.rb +26 -0
  24. data/lib/capistrano/configuration/callbacks.rb +147 -0
  25. data/lib/capistrano/configuration/connections.rb +237 -0
  26. data/lib/capistrano/configuration/execution.rb +142 -0
  27. data/lib/capistrano/configuration/loading.rb +205 -0
  28. data/lib/capistrano/configuration/log_formatters.rb +75 -0
  29. data/lib/capistrano/configuration/namespaces.rb +223 -0
  30. data/lib/capistrano/configuration/roles.rb +77 -0
  31. data/lib/capistrano/configuration/servers.rb +116 -0
  32. data/lib/capistrano/configuration/variables.rb +127 -0
  33. data/lib/capistrano/errors.rb +19 -0
  34. data/lib/capistrano/ext/multistage.rb +64 -0
  35. data/lib/capistrano/ext/string.rb +5 -0
  36. data/lib/capistrano/extensions.rb +57 -0
  37. data/lib/capistrano/fix_rake_deprecated_dsl.rb +8 -0
  38. data/lib/capistrano/logger.rb +166 -0
  39. data/lib/capistrano/processable.rb +57 -0
  40. data/lib/capistrano/recipes/compat.rb +32 -0
  41. data/lib/capistrano/recipes/deploy.rb +625 -0
  42. data/lib/capistrano/recipes/deploy/assets.rb +201 -0
  43. data/lib/capistrano/recipes/deploy/dependencies.rb +44 -0
  44. data/lib/capistrano/recipes/deploy/local_dependency.rb +54 -0
  45. data/lib/capistrano/recipes/deploy/remote_dependency.rb +117 -0
  46. data/lib/capistrano/recipes/deploy/scm.rb +19 -0
  47. data/lib/capistrano/recipes/deploy/scm/accurev.rb +169 -0
  48. data/lib/capistrano/recipes/deploy/scm/base.rb +200 -0
  49. data/lib/capistrano/recipes/deploy/scm/bzr.rb +86 -0
  50. data/lib/capistrano/recipes/deploy/scm/cvs.rb +153 -0
  51. data/lib/capistrano/recipes/deploy/scm/darcs.rb +96 -0
  52. data/lib/capistrano/recipes/deploy/scm/git.rb +293 -0
  53. data/lib/capistrano/recipes/deploy/scm/mercurial.rb +137 -0
  54. data/lib/capistrano/recipes/deploy/scm/none.rb +55 -0
  55. data/lib/capistrano/recipes/deploy/scm/perforce.rb +152 -0
  56. data/lib/capistrano/recipes/deploy/scm/subversion.rb +121 -0
  57. data/lib/capistrano/recipes/deploy/strategy.rb +19 -0
  58. data/lib/capistrano/recipes/deploy/strategy/base.rb +92 -0
  59. data/lib/capistrano/recipes/deploy/strategy/checkout.rb +20 -0
  60. data/lib/capistrano/recipes/deploy/strategy/copy.rb +338 -0
  61. data/lib/capistrano/recipes/deploy/strategy/export.rb +20 -0
  62. data/lib/capistrano/recipes/deploy/strategy/remote.rb +52 -0
  63. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +57 -0
  64. data/lib/capistrano/recipes/deploy/strategy/unshared_remote_cache.rb +21 -0
  65. data/lib/capistrano/recipes/standard.rb +37 -0
  66. data/lib/capistrano/recipes/templates/maintenance.rhtml +53 -0
  67. data/lib/capistrano/role.rb +102 -0
  68. data/lib/capistrano/server_definition.rb +56 -0
  69. data/lib/capistrano/shell.rb +265 -0
  70. data/lib/capistrano/ssh.rb +95 -0
  71. data/lib/capistrano/task_definition.rb +77 -0
  72. data/lib/capistrano/transfer.rb +218 -0
  73. data/lib/capistrano/version.rb +11 -0
  74. data/test/cli/execute_test.rb +132 -0
  75. data/test/cli/help_test.rb +165 -0
  76. data/test/cli/options_test.rb +329 -0
  77. data/test/cli/ui_test.rb +28 -0
  78. data/test/cli_test.rb +17 -0
  79. data/test/command_test.rb +322 -0
  80. data/test/configuration/actions/file_transfer_test.rb +61 -0
  81. data/test/configuration/actions/inspect_test.rb +76 -0
  82. data/test/configuration/actions/invocation_test.rb +288 -0
  83. data/test/configuration/alias_task_test.rb +118 -0
  84. data/test/configuration/callbacks_test.rb +201 -0
  85. data/test/configuration/connections_test.rb +439 -0
  86. data/test/configuration/execution_test.rb +175 -0
  87. data/test/configuration/loading_test.rb +148 -0
  88. data/test/configuration/namespace_dsl_test.rb +332 -0
  89. data/test/configuration/roles_test.rb +157 -0
  90. data/test/configuration/servers_test.rb +183 -0
  91. data/test/configuration/variables_test.rb +190 -0
  92. data/test/configuration_test.rb +77 -0
  93. data/test/deploy/local_dependency_test.rb +76 -0
  94. data/test/deploy/remote_dependency_test.rb +146 -0
  95. data/test/deploy/scm/accurev_test.rb +23 -0
  96. data/test/deploy/scm/base_test.rb +55 -0
  97. data/test/deploy/scm/bzr_test.rb +51 -0
  98. data/test/deploy/scm/darcs_test.rb +37 -0
  99. data/test/deploy/scm/git_test.rb +221 -0
  100. data/test/deploy/scm/mercurial_test.rb +134 -0
  101. data/test/deploy/scm/none_test.rb +35 -0
  102. data/test/deploy/scm/perforce_test.rb +23 -0
  103. data/test/deploy/scm/subversion_test.rb +40 -0
  104. data/test/deploy/strategy/copy_test.rb +360 -0
  105. data/test/extensions_test.rb +69 -0
  106. data/test/fixtures/cli_integration.rb +5 -0
  107. data/test/fixtures/config.rb +5 -0
  108. data/test/fixtures/custom.rb +3 -0
  109. data/test/logger_formatting_test.rb +149 -0
  110. data/test/logger_test.rb +134 -0
  111. data/test/recipes_test.rb +25 -0
  112. data/test/role_test.rb +11 -0
  113. data/test/server_definition_test.rb +121 -0
  114. data/test/shell_test.rb +96 -0
  115. data/test/ssh_test.rb +113 -0
  116. data/test/task_definition_test.rb +117 -0
  117. data/test/transfer_test.rb +168 -0
  118. data/test/utils.rb +37 -0
  119. metadata +316 -0
@@ -0,0 +1,288 @@
1
+ require "utils"
2
+ require 'capistrano/configuration/actions/invocation'
3
+ require 'capistrano/configuration/actions/file_transfer'
4
+
5
+ class ConfigurationActionsInvocationTest < Test::Unit::TestCase
6
+ class MockConfig
7
+ attr_reader :options
8
+ attr_accessor :debug
9
+ attr_accessor :dry_run
10
+ attr_accessor :preserve_roles
11
+ attr_accessor :servers
12
+ attr_accessor :roles
13
+
14
+ def initialize
15
+ @options = {}
16
+ @servers = []
17
+ end
18
+
19
+ def [](*args)
20
+ @options[*args]
21
+ end
22
+
23
+ def set(name, value)
24
+ @options[name] = value
25
+ end
26
+
27
+ def fetch(*args)
28
+ @options.fetch(*args)
29
+ end
30
+
31
+ def filter_servers(options = {})
32
+ [nil, @servers]
33
+ end
34
+
35
+ def execute_on_servers(options = {})
36
+ yield @servers
37
+ end
38
+
39
+ include Capistrano::Configuration::Actions::Invocation
40
+ include Capistrano::Configuration::Actions::FileTransfer
41
+ end
42
+
43
+ def setup
44
+ @config = make_config
45
+ @original_io_proc = MockConfig.default_io_proc
46
+ end
47
+
48
+ def teardown
49
+ MockConfig.default_io_proc = @original_io_proc
50
+ end
51
+
52
+ def test_run_options_should_be_passed_to_execute_on_servers
53
+ @config.expects(:execute_on_servers).with(:foo => "bar", :eof => true)
54
+ @config.run "ls", :foo => "bar"
55
+ end
56
+
57
+ def test_run_will_return_if_dry_run
58
+ @config.expects(:dry_run).returns(true)
59
+ @config.expects(:execute_on_servers).never
60
+ @config.run "ls", :foo => "bar"
61
+ end
62
+
63
+ def test_put_wont_transfer_if_dry_run
64
+ config = make_config
65
+ config.dry_run = true
66
+ config.servers = %w[ foo ]
67
+ config.expects(:execute_on_servers).never
68
+ ::Capistrano::Transfer.expects(:process).never
69
+ config.put "foo", "bar", :mode => 0644
70
+ end
71
+
72
+ def test_add_default_command_options_should_return_bare_options_if_there_is_no_env_or_shell_specified
73
+ assert_equal({:foo => "bar"}, @config.add_default_command_options(:foo => "bar"))
74
+ end
75
+
76
+ def test_add_default_command_options_should_merge_default_environment_as_env
77
+ @config[:default_environment][:bang] = "baz"
78
+ assert_equal({:foo => "bar", :env => { :bang => "baz" }}, @config.add_default_command_options(:foo => "bar"))
79
+ end
80
+
81
+ def test_add_default_command_options_should_merge_env_with_default_environment
82
+ @config[:default_environment][:bang] = "baz"
83
+ @config[:default_environment][:bacon] = "crunchy"
84
+ assert_equal({:foo => "bar", :env => { :bang => "baz", :bacon => "chunky", :flip => "flop" }}, @config.add_default_command_options(:foo => "bar", :env => {:bacon => "chunky", :flip => "flop"}))
85
+ end
86
+
87
+ def test_add_default_command_options_should_use_default_shell_if_present
88
+ @config.set :default_shell, "/bin/bash"
89
+ assert_equal({:foo => "bar", :shell => "/bin/bash"}, @config.add_default_command_options(:foo => "bar"))
90
+ end
91
+
92
+ def test_add_default_command_options_should_use_default_shell_of_false_if_present
93
+ @config.set :default_shell, false
94
+ assert_equal({:foo => "bar", :shell => false}, @config.add_default_command_options(:foo => "bar"))
95
+ end
96
+
97
+ def test_add_default_command_options_should_use_shell_in_preference_of_default_shell
98
+ @config.set :default_shell, "/bin/bash"
99
+ assert_equal({:foo => "bar", :shell => "/bin/sh"}, @config.add_default_command_options(:foo => "bar", :shell => "/bin/sh"))
100
+ end
101
+
102
+ def test_default_io_proc_should_log_stdout_arguments_as_info
103
+ ch = { :host => "capistrano",
104
+ :server => server("capistrano"),
105
+ :options => { :logger => mock("logger") } }
106
+ ch[:options][:logger].expects(:info).with("data stuff", "out :: capistrano")
107
+ MockConfig.default_io_proc[ch, :out, "data stuff"]
108
+ end
109
+
110
+ def test_default_io_proc_should_log_stderr_arguments_as_important
111
+ ch = { :host => "capistrano",
112
+ :server => server("capistrano"),
113
+ :options => { :logger => mock("logger") } }
114
+ ch[:options][:logger].expects(:important).with("data stuff", "err :: capistrano")
115
+ MockConfig.default_io_proc[ch, :err, "data stuff"]
116
+ end
117
+
118
+ def test_sudo_should_default_to_sudo
119
+ @config.expects(:run).with("sudo -p 'sudo password: ' ls", {})
120
+ @config.sudo "ls"
121
+ end
122
+
123
+ def test_sudo_should_keep_input_stream_open
124
+ @config.expects(:execute_on_servers).with(:foo => "bar")
125
+ @config.sudo "ls", :foo => "bar"
126
+ end
127
+
128
+ def test_sudo_should_use_sudo_variable_definition
129
+ @config.expects(:run).with("/opt/local/bin/sudo -p 'sudo password: ' ls", {})
130
+ @config.options[:sudo] = "/opt/local/bin/sudo"
131
+ @config.sudo "ls"
132
+ end
133
+
134
+ def test_sudo_should_interpret_as_option_as_user
135
+ @config.expects(:run).with("sudo -p 'sudo password: ' -u app ls", {})
136
+ @config.sudo "ls", :as => "app"
137
+ end
138
+
139
+ def test_sudo_should_pass_options_through_to_run
140
+ @config.expects(:run).with("sudo -p 'sudo password: ' ls", :foo => "bar")
141
+ @config.sudo "ls", :foo => "bar"
142
+ end
143
+
144
+ def test_sudo_should_avoid_minus_p_when_sudo_prompt_is_empty
145
+ @config.set :sudo_prompt, ""
146
+ @config.expects(:run).with("sudo ls", {})
147
+ @config.sudo "ls"
148
+ end
149
+
150
+ def test_sudo_should_interpret_sudo_prompt_variable_as_custom_prompt
151
+ @config.set :sudo_prompt, "give it to me: "
152
+ @config.expects(:run).with("sudo -p 'give it to me: ' ls", {})
153
+ @config.sudo "ls"
154
+ end
155
+
156
+ def test_sudo_behavior_callback_should_send_password_when_prompted_with_default_sudo_prompt
157
+ ch = mock("channel")
158
+ ch.expects(:send_data).with("g00b3r\n")
159
+ @config.options[:password] = "g00b3r"
160
+ @config.sudo_behavior_callback(nil)[ch, nil, "sudo password: "]
161
+ end
162
+
163
+ def test_sudo_behavior_callback_should_send_password_when_prompted_with_custom_sudo_prompt
164
+ ch = mock("channel")
165
+ ch.expects(:send_data).with("g00b3r\n")
166
+ @config.set :sudo_prompt, "give it to me: "
167
+ @config.options[:password] = "g00b3r"
168
+ @config.sudo_behavior_callback(nil)[ch, nil, "give it to me: "]
169
+ end
170
+
171
+ def test_sudo_behavior_callback_with_incorrect_password_on_first_prompt
172
+ ch = mock("channel")
173
+ ch.stubs(:[]).with(:host).returns("capistrano")
174
+ ch.stubs(:[]).with(:server).returns(server("capistrano"))
175
+ @config.expects(:reset!).with(:password)
176
+ @config.sudo_behavior_callback(nil)[ch, nil, "Sorry, try again."]
177
+ end
178
+
179
+ def test_sudo_behavior_callback_with_incorrect_password_on_subsequent_prompts
180
+ callback = @config.sudo_behavior_callback(nil)
181
+
182
+ ch = mock("channel")
183
+ ch.stubs(:[]).with(:host).returns("capistrano")
184
+ ch.stubs(:[]).with(:server).returns(server("capistrano"))
185
+ ch2 = mock("channel")
186
+ ch2.stubs(:[]).with(:host).returns("cap2")
187
+ ch2.stubs(:[]).with(:server).returns(server("cap2"))
188
+
189
+ @config.expects(:reset!).with(:password).times(2)
190
+
191
+ callback[ch, nil, "Sorry, try again."]
192
+ callback[ch2, nil, "Sorry, try again."] # shouldn't call reset!
193
+ callback[ch, nil, "Sorry, try again."]
194
+ end
195
+
196
+ def test_sudo_behavior_callback_should_reset_password_and_prompt_again_if_output_includes_both_cues
197
+ ch = mock("channel")
198
+ ch.stubs(:[]).with(:host).returns("capistrano")
199
+ ch.stubs(:[]).with(:server).returns(server("capistrano"))
200
+ ch.expects(:send_data, "password!\n").times(2)
201
+
202
+ @config.set(:password, "password!")
203
+ @config.expects(:reset!).with(:password)
204
+
205
+ callback = @config.sudo_behavior_callback(nil)
206
+ callback[ch, :out, "sudo password: "]
207
+ callback[ch, :out, "Sorry, try again.\nsudo password: "]
208
+ end
209
+
210
+ def test_sudo_behavior_callback_should_defer_to_fallback_for_other_output
211
+ callback = @config.sudo_behavior_callback(inspectable_proc)
212
+
213
+ a = mock("channel", :called => true)
214
+ b = mock("stream", :called => true)
215
+ c = mock("data", :called => true)
216
+
217
+ callback[a, b, c]
218
+ end
219
+
220
+ def test_invoke_command_should_default_to_run
221
+ @config.expects(:run).with("ls", :once => true)
222
+ @config.invoke_command("ls", :once => true)
223
+ end
224
+
225
+ def test_invoke_command_should_delegate_to_method_identified_by_via
226
+ @config.expects(:foobar).with("ls", :once => true)
227
+ @config.invoke_command("ls", :once => true, :via => :foobar)
228
+ end
229
+
230
+ def test_parallel_command_execution_with_no_match
231
+ assert_block("should not raise argument error") do
232
+ begin
233
+ @config.parallel do |session|
234
+ session.when("in?(:app)", "ls") {|ch,stream,data| puts "noop"}
235
+ session.when("in?(:db)", "pwd") {|ch,stream,data| puts "noop"}
236
+ end
237
+ true
238
+ rescue
239
+ false
240
+ end
241
+ end
242
+ end
243
+
244
+ def test_parallel_command_execution_with_matching_servers
245
+ @config.expects(:execute_on_servers)
246
+ assert_block("should not raise Argument error") do
247
+ begin
248
+ @config.servers = [:app, :db]
249
+ @config.roles = {:app => [:app], :db => [:db] }
250
+ @config.parallel do |session|
251
+ session.when("in?(:app)", "ls") {|ch,stream,data| puts "noop"}
252
+ session.when("in?(:db)", "pwd") {|ch,stream,data| puts "noop"}
253
+ end
254
+ true
255
+ rescue
256
+ false
257
+ end
258
+ end
259
+ end
260
+
261
+ private
262
+
263
+ def make_config
264
+ config = MockConfig.new
265
+ config.stubs(:logger).returns(stub_everything)
266
+ config
267
+ end
268
+
269
+ def inspectable_proc
270
+ Proc.new do |ch, stream, data|
271
+ ch.called
272
+ stream.called
273
+ data.called
274
+ end
275
+ end
276
+
277
+ def prepare_command(command, sessions, options)
278
+ a = mock("channel", :called => true)
279
+ b = mock("stream", :called => true)
280
+ c = mock("data", :called => true)
281
+
282
+ compare_args = Proc.new do |tree, sess, opts|
283
+ tree.fallback.command == command && sess == sessions && opts == options
284
+ end
285
+
286
+ Capistrano::Command.expects(:process).with(&compare_args)
287
+ end
288
+ end
@@ -0,0 +1,118 @@
1
+ require 'utils'
2
+ require 'capistrano/configuration/alias_task'
3
+ require 'capistrano/configuration/execution'
4
+ require 'capistrano/configuration/namespaces'
5
+ require 'capistrano/task_definition'
6
+
7
+ class AliasTaskTest < Test::Unit::TestCase
8
+ class MockConfig
9
+ attr_reader :options
10
+ attr_accessor :logger
11
+
12
+ def initialize(options={})
13
+ @options = {}
14
+ @logger = options.delete(:logger)
15
+ end
16
+
17
+ include Capistrano::Configuration::AliasTask
18
+ include Capistrano::Configuration::Execution
19
+ include Capistrano::Configuration::Namespaces
20
+ end
21
+
22
+ def setup
23
+ @config = MockConfig.new( :logger => stub(:debug => nil, :info => nil, :important => nil) )
24
+ end
25
+
26
+ def test_makes_a_copy_of_the_task
27
+ @config.task(:foo) { 42 }
28
+ @config.alias_task 'new_foo', 'foo'
29
+
30
+ assert @config.tasks.key?(:new_foo)
31
+ end
32
+
33
+ def test_original_task_remain_with_same_name
34
+ @config.task(:foo) { 42 }
35
+ @config.alias_task 'new_foo', 'foo'
36
+
37
+ assert_equal :foo, @config.tasks[:foo].name
38
+ assert_equal :new_foo, @config.tasks[:new_foo].name
39
+ end
40
+
41
+ def test_aliased_task_do_the_same
42
+ @config.task(:foo) { 42 }
43
+ @config.alias_task 'new_foo', 'foo'
44
+
45
+ assert_equal 42, @config.find_and_execute_task('new_foo')
46
+ end
47
+
48
+ def test_aliased_task_should_preserve_description
49
+ @config.task(:foo, :desc => "the Ultimate Question of Life, the Universe, and Everything" ) { 42 }
50
+ @config.alias_task 'new_foo', 'foo'
51
+
52
+ task = @config.find_task('foo')
53
+ new_task = @config.find_task('new_foo')
54
+
55
+ assert_equal task.description, new_task.description
56
+ end
57
+
58
+ def test_aliased_task_should_preserve_on_error
59
+ @config.task(:foo, :on_error => :continue) { 42 }
60
+ @config.alias_task 'new_foo', 'foo'
61
+
62
+ task = @config.find_task('foo')
63
+ new_task = @config.find_task('new_foo')
64
+
65
+ assert_equal task.on_error, new_task.on_error
66
+ end
67
+
68
+ def test_aliased_task_should_preserve_max_hosts
69
+ @config.task(:foo, :max_hosts => 5) { 42 }
70
+ @config.alias_task 'new_foo', 'foo'
71
+
72
+ task = @config.find_task('foo')
73
+ new_task = @config.find_task('new_foo')
74
+
75
+ assert_equal task.max_hosts, new_task.max_hosts
76
+ end
77
+
78
+ def test_raise_exception_when_task_doesnt_exist
79
+ assert_raises(Capistrano::NoSuchTaskError) { @config.alias_task 'non_existant_task', 'fail_miserably' }
80
+ end
81
+
82
+ def test_convert_task_names_using_to_str
83
+ @config.task(:foo, :role => :app) { 42 }
84
+
85
+ @config.alias_task 'one', 'foo'
86
+ @config.alias_task :two, 'foo'
87
+ @config.alias_task 'three', :foo
88
+ @config.alias_task :four, :foo
89
+
90
+ assert @config.tasks.key?(:one)
91
+ assert @config.tasks.key?(:two)
92
+ assert @config.tasks.key?(:three)
93
+ assert @config.tasks.key?(:four)
94
+ end
95
+
96
+ def test_raise_an_exception_when_task_names_can_not_be_converted
97
+ @config.task(:foo, :role => :app) { 42 }
98
+
99
+ assert_raises(ArgumentError) { @config.alias_task mock('x'), :foo }
100
+ end
101
+
102
+ def test_should_include_namespace
103
+ @config.namespace(:outer) do
104
+ task(:foo) { 42 }
105
+ alias_task 'new_foo', 'foo'
106
+
107
+ namespace(:inner) do
108
+ task(:foo) { 43 }
109
+ alias_task 'new_foo', 'foo'
110
+ end
111
+ end
112
+
113
+ assert_equal 42, @config.find_and_execute_task('outer:new_foo')
114
+ assert_equal 42, @config.find_and_execute_task('outer:foo')
115
+ assert_equal 43, @config.find_and_execute_task('outer:inner:new_foo')
116
+ assert_equal 43, @config.find_and_execute_task('outer:inner:foo')
117
+ end
118
+ end
@@ -0,0 +1,201 @@
1
+ require "utils"
2
+ require 'capistrano/configuration/callbacks'
3
+
4
+ class ConfigurationCallbacksTest < Test::Unit::TestCase
5
+ class MockConfig
6
+ attr_reader :original_initialize_called
7
+ attr_reader :called
8
+
9
+ def initialize
10
+ @original_initialize_called = true
11
+ @called = []
12
+ end
13
+
14
+ def execute_task(task)
15
+ invoke_task_directly(task)
16
+ end
17
+
18
+ protected
19
+
20
+ def invoke_task_directly(task)
21
+ @called << task
22
+ end
23
+
24
+ include Capistrano::Configuration::Callbacks
25
+ end
26
+
27
+ def setup
28
+ @config = MockConfig.new
29
+ @config.stubs(:logger).returns(stub_everything("logger"))
30
+ end
31
+
32
+ def test_initialize_should_initialize_callbacks_collection
33
+ assert @config.original_initialize_called
34
+ assert @config.callbacks.empty?
35
+ end
36
+
37
+ def test_before_should_delegate_to_on
38
+ @config.expects(:on).with(:before, :foo, "bing:blang", {:only => :bar, :zip => :zing})
39
+ @config.before :bar, :foo, "bing:blang", :zip => :zing
40
+ end
41
+
42
+ def test_before_should_map_before_deploy_symlink
43
+ @config.before "deploy:symlink", "bing:blang", "deploy:symlink"
44
+ assert_equal "bing:blang", @config.callbacks[:before][0].source
45
+ assert_equal "deploy:create_symlink", @config.callbacks[:before][1].source
46
+ assert_equal ["deploy:create_symlink"], @config.callbacks[:before][1].only
47
+ end
48
+
49
+ def test_before_should_map_before_deploy_symlink_array
50
+ @config.before ["deploy:symlink", "bingo:blast"], "bing:blang"
51
+ assert_equal ["deploy:create_symlink", "bingo:blast"], @config.callbacks[:before].last.only
52
+ end
53
+
54
+ def test_after_should_delegate_to_on
55
+ @config.expects(:on).with(:after, :foo, "bing:blang", {:only => :bar, :zip => :zing})
56
+ @config.after :bar, :foo, "bing:blang", :zip => :zing
57
+ end
58
+
59
+ def test_after_should_map_before_deploy_symlink
60
+ @config.after "deploy:symlink", "bing:blang", "deploy:symlink"
61
+ assert_equal "bing:blang", @config.callbacks[:after][0].source
62
+ assert_equal "deploy:create_symlink", @config.callbacks[:after][1].source
63
+ assert_equal ["deploy:create_symlink"], @config.callbacks[:after][1].only
64
+ end
65
+
66
+ def test_after_should_map_before_deploy_symlink_array
67
+ @config.after ["deploy:symlink", "bingo:blast"], "bing:blang"
68
+ assert_equal ["deploy:create_symlink", "bingo:blast"], @config.callbacks[:after].last.only
69
+ end
70
+
71
+ def test_on_with_single_reference_should_add_task_callback
72
+ @config.on :before, :a_test
73
+ assert_equal 1, @config.callbacks[:before].length
74
+ assert_equal :a_test, @config.callbacks[:before][0].source
75
+ @config.expects(:find_and_execute_task).with(:a_test)
76
+ @config.callbacks[:before][0].call
77
+ end
78
+
79
+ def test_on_with_multi_reference_should_add_all_as_task_callback
80
+ @config.on :before, :first, :second, :third
81
+ assert_equal 3, @config.callbacks[:before].length
82
+ assert_equal %w(first second third), @config.callbacks[:before].map { |c| c.source.to_s }
83
+ end
84
+
85
+ def test_on_with_block_should_add_block_as_proc_callback
86
+ called = false
87
+ @config.on(:before) { called = true }
88
+ assert_equal 1, @config.callbacks[:before].length
89
+ assert_instance_of Proc, @config.callbacks[:before][0].source
90
+ @config.callbacks[:before][0].call
91
+ assert called
92
+ end
93
+
94
+ def test_on_with_single_only_should_set_only_as_string_array_on_all_references
95
+ @config.on :before, :first, "second:third", :only => :primary
96
+ assert_equal 2, @config.callbacks[:before].length
97
+ assert @config.callbacks[:before].all? { |c| c.only == %w(primary) }
98
+ end
99
+
100
+ def test_on_with_multi_only_should_set_only_as_string_array_on_all_references
101
+ @config.on :before, :first, "second:third", :only => [:primary, "other:one"]
102
+ assert_equal 2, @config.callbacks[:before].length
103
+ assert @config.callbacks[:before].all? { |c| c.only == %w(primary other:one) }
104
+ end
105
+
106
+ def test_on_with_single_except_should_set_except_as_string_array_on_all_references
107
+ @config.on :before, :first, "second:third", :except => :primary
108
+ assert_equal 2, @config.callbacks[:before].length
109
+ assert @config.callbacks[:before].all? { |c| c.except == %w(primary) }
110
+ end
111
+
112
+ def test_on_with_multi_except_should_set_except_as_string_array_on_all_references
113
+ @config.on :before, :first, "second:third", :except => [:primary, "other:one"]
114
+ assert_equal 2, @config.callbacks[:before].length
115
+ assert @config.callbacks[:before].all? { |c| c.except == %w(primary other:one) }
116
+ end
117
+
118
+ def test_on_with_only_and_block_should_set_only_as_string_array
119
+ @config.on(:before, :only => :primary) { blah }
120
+ assert_equal 1, @config.callbacks[:before].length
121
+ assert_equal %w(primary), @config.callbacks[:before].first.only
122
+ end
123
+
124
+ def test_on_with_except_and_block_should_set_except_as_string_array
125
+ @config.on(:before, :except => :primary) { blah }
126
+ assert_equal 1, @config.callbacks[:before].length
127
+ assert_equal %w(primary), @config.callbacks[:before].first.except
128
+ end
129
+
130
+ def test_on_without_tasks_or_block_should_raise_error
131
+ assert_raises(ArgumentError) { @config.on(:before) }
132
+ end
133
+
134
+ def test_on_with_both_tasks_and_block_should_raise_error
135
+ assert_raises(ArgumentError) { @config.on(:before, :first) { blah } }
136
+ end
137
+
138
+ def test_trigger_without_constraints_should_invoke_all_callbacks
139
+ task = stub(:fully_qualified_name => "any:old:thing")
140
+ @config.on(:before, :first, "second:third")
141
+ @config.on(:after, :another, "and:another")
142
+ @config.expects(:find_and_execute_task).with(:first)
143
+ @config.expects(:find_and_execute_task).with("second:third")
144
+ @config.expects(:find_and_execute_task).with(:another).never
145
+ @config.expects(:find_and_execute_task).with("and:another").never
146
+ @config.trigger(:before, task)
147
+ end
148
+
149
+ def test_trigger_with_only_constraint_should_invoke_only_matching_callbacks
150
+ task = stub(:fully_qualified_name => "any:old:thing")
151
+ @config.on(:before, :first)
152
+ @config.on(:before, "second:third", :only => "any:old:thing")
153
+ @config.on(:before, "this:too", :only => "any:other:thing")
154
+ @config.on(:after, :another, "and:another")
155
+ @config.expects(:find_and_execute_task).with(:first)
156
+ @config.expects(:find_and_execute_task).with("second:third")
157
+ @config.expects(:find_and_execute_task).with("this:too").never
158
+ @config.expects(:find_and_execute_task).with(:another).never
159
+ @config.expects(:find_and_execute_task).with("and:another").never
160
+ @config.trigger(:before, task)
161
+ end
162
+
163
+ def test_trigger_with_except_constraint_should_invoke_anything_but_matching_callbacks
164
+ task = stub(:fully_qualified_name => "any:old:thing")
165
+ @config.on(:before, :first)
166
+ @config.on(:before, "second:third", :except => "any:old:thing")
167
+ @config.on(:before, "this:too", :except => "any:other:thing")
168
+ @config.on(:after, :another, "and:another")
169
+ @config.expects(:find_and_execute_task).with(:first)
170
+ @config.expects(:find_and_execute_task).with("second:third").never
171
+ @config.expects(:find_and_execute_task).with("this:too")
172
+ @config.expects(:find_and_execute_task).with(:another).never
173
+ @config.expects(:find_and_execute_task).with("and:another").never
174
+ @config.trigger(:before, task)
175
+ end
176
+
177
+ def test_trigger_without_task_should_invoke_all_callbacks_for_that_event
178
+ task = stub(:fully_qualified_name => "any:old:thing")
179
+ @config.on(:before, :first)
180
+ @config.on(:before, "second:third", :except => "any:old:thing")
181
+ @config.on(:before, "this:too", :except => "any:other:thing")
182
+ @config.on(:after, :another, "and:another")
183
+ @config.expects(:find_and_execute_task).with(:first)
184
+ @config.expects(:find_and_execute_task).with("second:third")
185
+ @config.expects(:find_and_execute_task).with("this:too")
186
+ @config.expects(:find_and_execute_task).with(:another).never
187
+ @config.expects(:find_and_execute_task).with("and:another").never
188
+ @config.trigger(:before)
189
+ end
190
+
191
+ def test_execute_task_without_named_hooks_should_just_call_task
192
+ ns = stub("namespace", :default_task => nil, :name => "old", :fully_qualified_name => "any:old")
193
+ task = stub(:fully_qualified_name => "any:old:thing", :name => "thing", :namespace => ns)
194
+
195
+ ns.stubs(:search_task).returns(nil)
196
+
197
+ @config.execute_task(task)
198
+ assert_equal [task], @config.called
199
+ end
200
+
201
+ end