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.
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,40 @@
1
+ require "#{File.dirname(__FILE__)}/../../utils"
2
+ require 'capistrano/configuration/actions/file_transfer'
3
+
4
+ class ConfigurationActionsFileTransferTest < Test::Unit::TestCase
5
+ class MockConfig
6
+ include Capistrano::Configuration::Actions::FileTransfer
7
+ end
8
+
9
+ def setup
10
+ @config = MockConfig.new
11
+ @config.stubs(:logger).returns(stub_everything)
12
+ end
13
+
14
+ def test_put_should_pass_options_to_execute_on_servers
15
+ @config.expects(:execute_on_servers).with(:foo => "bar")
16
+ @config.put("some data", "test.txt", :foo => "bar")
17
+ end
18
+
19
+ def test_put_should_delegate_to_Upload_process
20
+ @config.expects(:execute_on_servers).yields(%w(s1 s2 s3).map { |s| mock(:host => s) })
21
+ @config.expects(:sessions).times(3).returns(Hash.new{|h,k| h[k] = k.host.to_sym})
22
+ Capistrano::Upload.expects(:process).with([:s1,:s2,:s3], "test.txt", :data => "some data", :mode => 0777, :logger => @config.logger)
23
+ @config.put("some data", "test.txt", :mode => 0777)
24
+ end
25
+
26
+ def test_get_should_pass_options_execute_on_servers_including_once
27
+ @config.expects(:execute_on_servers).with(:foo => "bar", :once => true)
28
+ @config.get("test.txt", "test.txt", :foo => "bar")
29
+ end
30
+
31
+ def test_get_should_use_sftp_get_file_to_local_path
32
+ sftp = mock("sftp", :state => :closed, :connect => true)
33
+ sftp.expects(:get_file).with("remote.txt", "local.txt")
34
+
35
+ s = server("capistrano")
36
+ @config.expects(:execute_on_servers).yields([s])
37
+ @config.expects(:sessions).returns(s => mock("session", :sftp => sftp))
38
+ @config.get("remote.txt", "local.txt")
39
+ end
40
+ end
@@ -0,0 +1,62 @@
1
+ require "#{File.dirname(__FILE__)}/../../utils"
2
+ require 'capistrano/configuration/actions/inspect'
3
+
4
+ class ConfigurationActionsInspectTest < Test::Unit::TestCase
5
+ class MockConfig
6
+ include Capistrano::Configuration::Actions::Inspect
7
+ end
8
+
9
+ def setup
10
+ @config = MockConfig.new
11
+ @config.stubs(:logger).returns(stub_everything)
12
+ end
13
+
14
+ def test_stream_should_pass_options_through_to_run
15
+ @config.expects(:invoke_command).with("tail -f foo.log", :once => true)
16
+ @config.stream("tail -f foo.log", :once => true)
17
+ end
18
+
19
+ def test_stream_should_emit_stdout_via_puts
20
+ @config.expects(:invoke_command).yields(mock("channel"), :out, "something streamed")
21
+ @config.expects(:puts).with("something streamed")
22
+ @config.expects(:warn).never
23
+ @config.stream("tail -f foo.log")
24
+ end
25
+
26
+ def test_stream_should_emit_stderr_via_warn
27
+ ch = mock("channel")
28
+ ch.expects(:[]).with(:server).returns(server("capistrano"))
29
+ @config.expects(:invoke_command).yields(ch, :err, "something streamed")
30
+ @config.expects(:puts).never
31
+ @config.expects(:warn).with("[err :: capistrano] something streamed")
32
+ @config.stream("tail -f foo.log")
33
+ end
34
+
35
+ def test_capture_should_pass_options_merged_with_once_to_run
36
+ @config.expects(:invoke_command).with("hostname", :foo => "bar", :once => true)
37
+ @config.capture("hostname", :foo => "bar")
38
+ end
39
+
40
+ def test_capture_with_stderr_result_should_raise_capture_error
41
+ @config.expects(:invoke_command).yields(mock("channel"), :err, "boom")
42
+ assert_raises(Capistrano::CaptureError) { @config.capture("hostname") }
43
+ end
44
+
45
+ def test_capture_with_stdout_should_aggregate_and_return_stdout
46
+ config_expects_invoke_command_to_loop_with(mock("channel"), "foo", "bar", "baz")
47
+ assert_equal "foobarbaz", @config.capture("hostname")
48
+ end
49
+
50
+ private
51
+
52
+ def config_expects_invoke_command_to_loop_with(channel, *output)
53
+ class <<@config
54
+ attr_accessor :script, :channel
55
+ def invoke_command(*args)
56
+ script.each { |item| yield channel, :out, item }
57
+ end
58
+ end
59
+ @config.channel = channel
60
+ @config.script = output
61
+ end
62
+ end
@@ -0,0 +1,195 @@
1
+ require "#{File.dirname(__FILE__)}/../../utils"
2
+ require 'capistrano/configuration/actions/invocation'
3
+
4
+ class ConfigurationActionsInvocationTest < Test::Unit::TestCase
5
+ class MockConfig
6
+ attr_reader :options
7
+
8
+ def initialize
9
+ @options = {}
10
+ end
11
+
12
+ def [](*args)
13
+ @options[*args]
14
+ end
15
+
16
+ def set(name, value)
17
+ @options[name] = value
18
+ end
19
+
20
+ def fetch(*args)
21
+ @options.fetch(*args)
22
+ end
23
+
24
+ include Capistrano::Configuration::Actions::Invocation
25
+ end
26
+
27
+ def setup
28
+ @config = MockConfig.new
29
+ @original_io_proc = MockConfig.default_io_proc
30
+ @config.stubs(:logger).returns(stub_everything)
31
+ end
32
+
33
+ def teardown
34
+ MockConfig.default_io_proc = @original_io_proc
35
+ end
36
+
37
+ def test_run_options_should_be_passed_to_execute_on_servers
38
+ @config.expects(:execute_on_servers).with(:foo => "bar")
39
+ @config.run "ls", :foo => "bar"
40
+ end
41
+
42
+ def test_run_without_block_should_use_default_io_proc
43
+ @config.expects(:execute_on_servers).yields(%w(s1 s2 s3).map { |s| server(s) })
44
+ @config.expects(:sessions).returns(Hash.new { |h,k| h[k] = k.host.to_sym }).times(3)
45
+ prepare_command("ls", [:s1, :s2, :s3], {:logger => @config.logger})
46
+ MockConfig.default_io_proc = inspectable_proc
47
+ @config.run "ls"
48
+ end
49
+
50
+ def test_run_with_block_should_use_block
51
+ @config.expects(:execute_on_servers).yields(%w(s1 s2 s3).map { |s| mock(:host => s) })
52
+ @config.expects(:sessions).returns(Hash.new { |h,k| h[k] = k.host.to_sym }).times(3)
53
+ prepare_command("ls", [:s1, :s2, :s3], {:logger => @config.logger})
54
+ MockConfig.default_io_proc = Proc.new { |a,b,c| raise "shouldn't get here" }
55
+ @config.run("ls", &inspectable_proc)
56
+ end
57
+
58
+ def test_add_default_command_options_should_return_bare_options_if_there_is_no_env_or_shell_specified
59
+ assert_equal({:foo => "bar"}, @config.add_default_command_options(:foo => "bar"))
60
+ end
61
+
62
+ def test_add_default_command_options_should_merge_default_environment_as_env
63
+ @config[:default_environment][:bang] = "baz"
64
+ assert_equal({:foo => "bar", :env => { :bang => "baz" }}, @config.add_default_command_options(:foo => "bar"))
65
+ end
66
+
67
+ def test_add_default_command_options_should_merge_env_with_default_environment
68
+ @config[:default_environment][:bang] = "baz"
69
+ @config[:default_environment][:bacon] = "crunchy"
70
+ assert_equal({:foo => "bar", :env => { :bang => "baz", :bacon => "chunky", :flip => "flop" }}, @config.add_default_command_options(:foo => "bar", :env => {:bacon => "chunky", :flip => "flop"}))
71
+ end
72
+
73
+ def test_add_default_command_options_should_use_default_shell_if_present
74
+ @config.set :default_shell, "/bin/bash"
75
+ assert_equal({:foo => "bar", :shell => "/bin/bash"}, @config.add_default_command_options(:foo => "bar"))
76
+ end
77
+
78
+ def test_add_default_command_options_should_use_shell_in_preference_of_default_shell
79
+ @config.set :default_shell, "/bin/bash"
80
+ assert_equal({:foo => "bar", :shell => "/bin/sh"}, @config.add_default_command_options(:foo => "bar", :shell => "/bin/sh"))
81
+ end
82
+
83
+ def test_default_io_proc_should_log_stdout_arguments_as_info
84
+ ch = { :host => "capistrano",
85
+ :server => server("capistrano"),
86
+ :options => { :logger => mock("logger") } }
87
+ ch[:options][:logger].expects(:info).with("data stuff", "out :: capistrano")
88
+ MockConfig.default_io_proc[ch, :out, "data stuff"]
89
+ end
90
+
91
+ def test_default_io_proc_should_log_stderr_arguments_as_important
92
+ ch = { :host => "capistrano",
93
+ :server => server("capistrano"),
94
+ :options => { :logger => mock("logger") } }
95
+ ch[:options][:logger].expects(:important).with("data stuff", "err :: capistrano")
96
+ MockConfig.default_io_proc[ch, :err, "data stuff"]
97
+ end
98
+
99
+ def test_sudo_should_default_to_sudo
100
+ @config.expects(:run).with("sudo ls", {})
101
+ @config.sudo "ls"
102
+ end
103
+
104
+ def test_sudo_should_use_sudo_variable_definition
105
+ @config.expects(:run).with("/opt/local/bin/sudo ls", {})
106
+ @config.options[:sudo] = "/opt/local/bin/sudo"
107
+ @config.sudo "ls"
108
+ end
109
+
110
+ def test_sudo_should_interpret_as_option_as_user
111
+ @config.expects(:run).with("sudo -u app ls", {})
112
+ @config.sudo "ls", :as => "app"
113
+ end
114
+
115
+ def test_sudo_should_pass_options_through_to_run
116
+ @config.expects(:run).with("sudo ls", :foo => "bar")
117
+ @config.sudo "ls", :foo => "bar"
118
+ end
119
+
120
+ def test_sudo_behavior_callback_should_send_password_when_prompted
121
+ ch = mock("channel")
122
+ ch.expects(:send_data).with("g00b3r\n")
123
+ @config.options[:password] = "g00b3r"
124
+ @config.sudo_behavior_callback(nil)[ch, nil, "Password: "]
125
+ end
126
+
127
+ def test_sudo_behavior_callback_should_send_password_when_prompted_with_SuSE_dialect
128
+ ch = mock("channel")
129
+ ch.expects(:send_data).with("g00b3r\n")
130
+ @config.options[:password] = "g00b3r"
131
+ @config.sudo_behavior_callback(nil)[ch, nil, "user's password: "]
132
+ end
133
+
134
+ def test_sudo_behavior_callback_with_incorrect_password_on_first_prompt
135
+ ch = mock("channel")
136
+ ch.stubs(:[]).with(:host).returns("capistrano")
137
+ ch.stubs(:[]).with(:server).returns(server("capistrano"))
138
+ @config.expects(:reset!).with(:password)
139
+ @config.sudo_behavior_callback(nil)[ch, nil, "blah blah try again blah blah"]
140
+ end
141
+
142
+ def test_sudo_behavior_callback_with_incorrect_password_on_subsequent_prompts
143
+ callback = @config.sudo_behavior_callback(nil)
144
+
145
+ ch = mock("channel")
146
+ ch.stubs(:[]).with(:host).returns("capistrano")
147
+ ch.stubs(:[]).with(:server).returns(server("capistrano"))
148
+ ch2 = mock("channel")
149
+ ch2.stubs(:[]).with(:host).returns("cap2")
150
+ ch2.stubs(:[]).with(:server).returns(server("cap2"))
151
+
152
+ @config.expects(:reset!).with(:password).times(2)
153
+
154
+ callback[ch, nil, "blah blah try again blah blah"]
155
+ callback[ch2, nil, "blah blah try again blah blah"] # shouldn't call reset!
156
+ callback[ch, nil, "blah blah try again blah blah"]
157
+ end
158
+
159
+ def test_sudo_behavior_callback_should_defer_to_fallback_for_other_output
160
+ callback = @config.sudo_behavior_callback(inspectable_proc)
161
+
162
+ a = mock("channel", :called => true)
163
+ b = mock("stream", :called => true)
164
+ c = mock("data", :called => true)
165
+
166
+ callback[a, b, c]
167
+ end
168
+
169
+ def test_invoke_command_should_default_to_run
170
+ @config.expects(:run).with("ls", :once => true)
171
+ @config.invoke_command("ls", :once => true)
172
+ end
173
+
174
+ def test_invoke_command_should_delegate_to_method_identified_by_via
175
+ @config.expects(:foobar).with("ls", :once => true)
176
+ @config.invoke_command("ls", :once => true, :via => :foobar)
177
+ end
178
+
179
+ private
180
+
181
+ def inspectable_proc
182
+ Proc.new do |ch, stream, data|
183
+ ch.called
184
+ stream.called
185
+ data.called
186
+ end
187
+ end
188
+
189
+ def prepare_command(command, sessions, options)
190
+ a = mock("channel", :called => true)
191
+ b = mock("stream", :called => true)
192
+ c = mock("data", :called => true)
193
+ Capistrano::Command.expects(:process).with(command, sessions, options).yields(a, b, c)
194
+ end
195
+ end
@@ -0,0 +1,206 @@
1
+ require "#{File.dirname(__FILE__)}/../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
+ @called << task
16
+ end
17
+
18
+ include Capistrano::Configuration::Callbacks
19
+ end
20
+
21
+ def setup
22
+ @config = MockConfig.new
23
+ @config.stubs(:logger).returns(stub_everything("logger"))
24
+ end
25
+
26
+ def test_initialize_should_initialize_callbacks_collection
27
+ assert @config.original_initialize_called
28
+ assert @config.callbacks.empty?
29
+ end
30
+
31
+ def test_before_should_delegate_to_on
32
+ @config.expects(:on).with(:before, :foo, "bing:blang", {:only => :bar, :zip => :zing})
33
+ @config.before :bar, :foo, "bing:blang", :zip => :zing
34
+ end
35
+
36
+ def test_after_should_delegate_to_on
37
+ @config.expects(:on).with(:after, :foo, "bing:blang", {:only => :bar, :zip => :zing})
38
+ @config.after :bar, :foo, "bing:blang", :zip => :zing
39
+ end
40
+
41
+ def test_on_with_single_reference_should_add_task_callback
42
+ @config.on :before, :a_test
43
+ assert_equal 1, @config.callbacks[:before].length
44
+ assert_equal :a_test, @config.callbacks[:before][0].source
45
+ @config.expects(:find_and_execute_task).with(:a_test)
46
+ @config.callbacks[:before][0].call
47
+ end
48
+
49
+ def test_on_with_multi_reference_should_add_all_as_task_callback
50
+ @config.on :before, :first, :second, :third
51
+ assert_equal 3, @config.callbacks[:before].length
52
+ assert_equal %w(first second third), @config.callbacks[:before].map { |c| c.source.to_s }
53
+ end
54
+
55
+ def test_on_with_block_should_add_block_as_proc_callback
56
+ called = false
57
+ @config.on(:before) { called = true }
58
+ assert_equal 1, @config.callbacks[:before].length
59
+ assert_instance_of Proc, @config.callbacks[:before][0].source
60
+ @config.callbacks[:before][0].call
61
+ assert called
62
+ end
63
+
64
+ def test_on_with_single_only_should_set_only_as_string_array_on_all_references
65
+ @config.on :before, :first, "second:third", :only => :primary
66
+ assert_equal 2, @config.callbacks[:before].length
67
+ assert @config.callbacks[:before].all? { |c| c.only == %w(primary) }
68
+ end
69
+
70
+ def test_on_with_multi_only_should_set_only_as_string_array_on_all_references
71
+ @config.on :before, :first, "second:third", :only => [:primary, "other:one"]
72
+ assert_equal 2, @config.callbacks[:before].length
73
+ assert @config.callbacks[:before].all? { |c| c.only == %w(primary other:one) }
74
+ end
75
+
76
+ def test_on_with_single_except_should_set_except_as_string_array_on_all_references
77
+ @config.on :before, :first, "second:third", :except => :primary
78
+ assert_equal 2, @config.callbacks[:before].length
79
+ assert @config.callbacks[:before].all? { |c| c.except == %w(primary) }
80
+ end
81
+
82
+ def test_on_with_multi_except_should_set_except_as_string_array_on_all_references
83
+ @config.on :before, :first, "second:third", :except => [:primary, "other:one"]
84
+ assert_equal 2, @config.callbacks[:before].length
85
+ assert @config.callbacks[:before].all? { |c| c.except == %w(primary other:one) }
86
+ end
87
+
88
+ def test_on_with_only_and_block_should_set_only_as_string_array
89
+ @config.on(:before, :only => :primary) { blah }
90
+ assert_equal 1, @config.callbacks[:before].length
91
+ assert_equal %w(primary), @config.callbacks[:before].first.only
92
+ end
93
+
94
+ def test_on_with_except_and_block_should_set_except_as_string_array
95
+ @config.on(:before, :except => :primary) { blah }
96
+ assert_equal 1, @config.callbacks[:before].length
97
+ assert_equal %w(primary), @config.callbacks[:before].first.except
98
+ end
99
+
100
+ def test_trigger_without_constraints_should_invoke_all_callbacks
101
+ task = stub(:fully_qualified_name => "any:old:thing")
102
+ @config.on(:before, :first, "second:third")
103
+ @config.on(:after, :another, "and:another")
104
+ @config.expects(:find_and_execute_task).with(:first)
105
+ @config.expects(:find_and_execute_task).with("second:third")
106
+ @config.expects(:find_and_execute_task).with(:another).never
107
+ @config.expects(:find_and_execute_task).with("and:another").never
108
+ @config.trigger(:before, task)
109
+ end
110
+
111
+ def test_trigger_with_only_constraint_should_invoke_only_matching_callbacks
112
+ task = stub(:fully_qualified_name => "any:old:thing")
113
+ @config.on(:before, :first)
114
+ @config.on(:before, "second:third", :only => "any:old:thing")
115
+ @config.on(:before, "this:too", :only => "any:other:thing")
116
+ @config.on(:after, :another, "and:another")
117
+ @config.expects(:find_and_execute_task).with(:first)
118
+ @config.expects(:find_and_execute_task).with("second:third")
119
+ @config.expects(:find_and_execute_task).with("this:too").never
120
+ @config.expects(:find_and_execute_task).with(:another).never
121
+ @config.expects(:find_and_execute_task).with("and:another").never
122
+ @config.trigger(:before, task)
123
+ end
124
+
125
+ def test_trigger_with_except_constraint_should_invoke_anything_but_matching_callbacks
126
+ task = stub(:fully_qualified_name => "any:old:thing")
127
+ @config.on(:before, :first)
128
+ @config.on(:before, "second:third", :except => "any:old:thing")
129
+ @config.on(:before, "this:too", :except => "any:other:thing")
130
+ @config.on(:after, :another, "and:another")
131
+ @config.expects(:find_and_execute_task).with(:first)
132
+ @config.expects(:find_and_execute_task).with("second:third").never
133
+ @config.expects(:find_and_execute_task).with("this:too")
134
+ @config.expects(:find_and_execute_task).with(:another).never
135
+ @config.expects(:find_and_execute_task).with("and:another").never
136
+ @config.trigger(:before, task)
137
+ end
138
+
139
+ def test_trigger_without_task_should_invoke_all_callbacks_for_that_event
140
+ task = stub(:fully_qualified_name => "any:old:thing")
141
+ @config.on(:before, :first)
142
+ @config.on(:before, "second:third", :except => "any:old:thing")
143
+ @config.on(:before, "this:too", :except => "any:other:thing")
144
+ @config.on(:after, :another, "and:another")
145
+ @config.expects(:find_and_execute_task).with(:first)
146
+ @config.expects(:find_and_execute_task).with("second:third")
147
+ @config.expects(:find_and_execute_task).with("this:too")
148
+ @config.expects(:find_and_execute_task).with(:another).never
149
+ @config.expects(:find_and_execute_task).with("and:another").never
150
+ @config.trigger(:before)
151
+ end
152
+
153
+ def test_execute_task_without_named_hooks_should_just_call_task
154
+ ns = stub("namespace", :default_task => nil, :name => "old", :fully_qualified_name => "any:old")
155
+ task = stub(:fully_qualified_name => "any:old:thing", :name => "thing", :namespace => ns)
156
+
157
+ ns.stubs(:search_task).returns(nil)
158
+
159
+ @config.execute_task(task)
160
+ assert_equal [task], @config.called
161
+ end
162
+
163
+ def test_execute_task_with_named_before_hook_should_call_named_before_hook
164
+ ns = stub("namespace", :default_task => nil, :name => "old", :fully_qualified_name => "any:old")
165
+ task = stub(:fully_qualified_name => "any:old:thing", :name => "thing", :namespace => ns)
166
+ before_task = stub(:fully_qualified_name => "any:old:before_thing", :name => "before_thing", :namespace => ns)
167
+
168
+ ns.stubs(:search_task).returns(nil)
169
+ ns.expects(:search_task).with("before_thing").returns(before_task)
170
+
171
+ @config.execute_task(task)
172
+ assert_equal [before_task, task], @config.called
173
+ end
174
+
175
+ def test_execute_task_with_named_after_hook_should_call_named_after_hook
176
+ ns = stub("namespace", :default_task => nil, :name => "old", :fully_qualified_name => "any:old")
177
+ task = stub(:fully_qualified_name => "any:old:thing", :name => "thing", :namespace => ns)
178
+ after_task = stub(:fully_qualified_name => "any:old:after_thing", :name => "after_thing", :namespace => ns)
179
+
180
+ ns.stubs(:search_task).returns(nil)
181
+ ns.expects(:search_task).with("after_thing").returns(after_task)
182
+
183
+ @config.execute_task(task)
184
+ assert_equal [task, after_task], @config.called
185
+ end
186
+
187
+ def test_execute_task_with_on_hooks_should_trigger_hooks_around_task
188
+ ns = stub("namespace", :default_task => nil, :name => "old", :fully_qualified_name => "any:old")
189
+ task = stub(:fully_qualified_name => "any:old:thing", :name => "thing", :namespace => ns)
190
+ before_task = stub(:fully_qualified_name => "any:old:before_thing", :name => "before_thing", :namespace => ns)
191
+ after_task = stub(:fully_qualified_name => "any:old:after_thing", :name => "after_thing", :namespace => ns)
192
+
193
+ ns.stubs(:search_task).returns(nil)
194
+ ns.expects(:search_task).with("before_thing").returns(before_task)
195
+ ns.expects(:search_task).with("after_thing").returns(after_task)
196
+
197
+ @config.before("any:old:thing", :first_this, :then_this)
198
+ @config.after("any:old:thing", :and_then_this, :lastly_this)
199
+
200
+ [:first_this, :then_this, :and_then_this, :lastly_this].each do |t|
201
+ @config.expects(:find_and_execute_task).with(t)
202
+ end
203
+
204
+ @config.execute_task(task)
205
+ end
206
+ end