aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/test/executor_test.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/test/executor_test.rb')
-rw-r--r--activesupport/test/executor_test.rb183
1 files changed, 183 insertions, 0 deletions
diff --git a/activesupport/test/executor_test.rb b/activesupport/test/executor_test.rb
new file mode 100644
index 0000000000..d9b389461a
--- /dev/null
+++ b/activesupport/test/executor_test.rb
@@ -0,0 +1,183 @@
+require 'abstract_unit'
+
+class ExecutorTest < ActiveSupport::TestCase
+ class DummyError < RuntimeError
+ end
+
+ def test_wrap_invokes_callbacks
+ called = []
+ executor.to_run { called << :run }
+ executor.to_complete { called << :complete }
+
+ executor.wrap do
+ called << :body
+ end
+
+ assert_equal [:run, :body, :complete], called
+ end
+
+ def test_callbacks_share_state
+ result = false
+ executor.to_run { @foo = true }
+ executor.to_complete { result = @foo }
+
+ executor.wrap { }
+
+ assert result
+ end
+
+ def test_separated_calls_invoke_callbacks
+ called = []
+ executor.to_run { called << :run }
+ executor.to_complete { called << :complete }
+
+ state = executor.run!
+ called << :body
+ state.complete!
+
+ assert_equal [:run, :body, :complete], called
+ end
+
+ def test_exceptions_unwind
+ called = []
+ executor.to_run { called << :run_1 }
+ executor.to_run { raise DummyError }
+ executor.to_run { called << :run_2 }
+ executor.to_complete { called << :complete }
+
+ assert_raises(DummyError) do
+ executor.wrap { called << :body }
+ end
+
+ assert_equal [:run_1, :complete], called
+ end
+
+ def test_avoids_double_wrapping
+ called = []
+ executor.to_run { called << :run }
+ executor.to_complete { called << :complete }
+
+ executor.wrap do
+ called << :early
+ executor.wrap do
+ called << :body
+ end
+ called << :late
+ end
+
+ assert_equal [:run, :early, :body, :late, :complete], called
+ end
+
+ def test_hooks_carry_state
+ supplied_state = :none
+
+ hook = Class.new do
+ define_method(:run) do
+ :some_state
+ end
+
+ define_method(:complete) do |state|
+ supplied_state = state
+ end
+ end.new
+
+ executor.register_hook(hook)
+
+ executor.wrap { }
+
+ assert_equal :some_state, supplied_state
+ end
+
+ def test_nil_state_is_sufficient
+ supplied_state = :none
+
+ hook = Class.new do
+ define_method(:run) do
+ nil
+ end
+
+ define_method(:complete) do |state|
+ supplied_state = state
+ end
+ end.new
+
+ executor.register_hook(hook)
+
+ executor.wrap { }
+
+ assert_equal nil, supplied_state
+ end
+
+ def test_exception_skips_uninvoked_hook
+ supplied_state = :none
+
+ hook = Class.new do
+ define_method(:run) do
+ :some_state
+ end
+
+ define_method(:complete) do |state|
+ supplied_state = state
+ end
+ end.new
+
+ executor.to_run do
+ raise DummyError
+ end
+ executor.register_hook(hook)
+
+ assert_raises(DummyError) do
+ executor.wrap { }
+ end
+
+ assert_equal :none, supplied_state
+ end
+
+ def test_exception_unwinds_invoked_hook
+ supplied_state = :none
+
+ hook = Class.new do
+ define_method(:run) do
+ :some_state
+ end
+
+ define_method(:complete) do |state|
+ supplied_state = state
+ end
+ end.new
+
+ executor.register_hook(hook)
+ executor.to_run do
+ raise DummyError
+ end
+
+ assert_raises(DummyError) do
+ executor.wrap { }
+ end
+
+ assert_equal :some_state, supplied_state
+ end
+
+ def test_separate_classes_can_wrap
+ other_executor = Class.new(ActiveSupport::Executor)
+
+ called = []
+ executor.to_run { called << :run }
+ executor.to_complete { called << :complete }
+ other_executor.to_run { called << :other_run }
+ other_executor.to_complete { called << :other_complete }
+
+ executor.wrap do
+ other_executor.wrap do
+ called << :body
+ end
+ end
+
+ assert_equal [:run, :other_run, :body, :other_complete, :complete], called
+ end
+
+ private
+ def executor
+ @executor ||= Class.new(ActiveSupport::Executor)
+ end
+end