summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/eventmachine-1.2.7/tests/test_futures.rb
diff options
context:
space:
mode:
authorBenjamin Sanders <ben@Benjamins-MacBook-Pro.local>2025-10-11 10:34:24 -0400
committerBenjamin Sanders <ben@Benjamins-MacBook-Pro.local>2025-10-11 10:34:24 -0400
commit5571dc766e2143e39762ff0b47c41d1c2e154f4c (patch)
treef4f124d314a7e76c04484515aa0fd1f2e271a601 /vendor/bundle/ruby/3.4.0/gems/eventmachine-1.2.7/tests/test_futures.rb
parent359f3309c97fc894b63e0a295c76ab298504d635 (diff)
Vendor bundled gems for deployment
Diffstat (limited to 'vendor/bundle/ruby/3.4.0/gems/eventmachine-1.2.7/tests/test_futures.rb')
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/eventmachine-1.2.7/tests/test_futures.rb170
1 files changed, 170 insertions, 0 deletions
diff --git a/vendor/bundle/ruby/3.4.0/gems/eventmachine-1.2.7/tests/test_futures.rb b/vendor/bundle/ruby/3.4.0/gems/eventmachine-1.2.7/tests/test_futures.rb
new file mode 100644
index 0000000..b494856
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/eventmachine-1.2.7/tests/test_futures.rb
@@ -0,0 +1,170 @@
+require 'em_test_helper'
+
+class TestFutures < Test::Unit::TestCase
+
+ def setup
+ end
+
+ def teardown
+ end
+
+ def test_future
+ assert_equal(100, EM::Deferrable.future(100) )
+
+ p1 = proc { 100 + 1 }
+ assert_equal(101, EM::Deferrable.future(p1) )
+ end
+
+ class MyFuture
+ include EM::Deferrable
+ def initialize *args
+ super
+ set_deferred_status :succeeded, 40
+ end
+ end
+
+ class MyErrorFuture
+ include EM::Deferrable
+ def initialize *args
+ super
+ set_deferred_status :failed, 41
+ end
+ end
+
+
+ def test_future_1
+ # Call future with one additional argument and it will be treated as a callback.
+ def my_future
+ MyFuture.new
+ end
+
+ value = nil
+ EM::Deferrable.future my_future, proc {|v| value=v}
+ assert_equal( 40, value )
+ end
+
+
+ def test_future_2
+ # Call future with two additional arguments and they will be treated as a callback
+ # and an errback.
+ value = nil
+ EM::Deferrable.future MyErrorFuture.new, nil, proc {|v| value=v}
+ assert_equal( 41, value )
+ end
+
+
+ def test_future_3
+ # Call future with no additional arguments but with a block, and the block will be
+ # treated as a callback.
+ value = nil
+ EM::Deferrable.future MyFuture.new do |v|
+ value=v
+ end
+ assert_equal( 40, value )
+ end
+
+
+ class RecursiveCallback
+ include EM::Deferrable
+ end
+
+ # A Deferrable callback can call #set_deferred_status to change the values
+ # passed to subsequent callbacks.
+ #
+ def test_recursive_callbacks
+ n = 0 # counter assures that all the tests actually run.
+ rc = RecursiveCallback.new
+ rc.callback {|a|
+ assert_equal(100, a)
+ n += 1
+ rc.set_deferred_status :succeeded, 101, 101
+ }
+ rc.callback {|a,b|
+ assert_equal(101, a)
+ assert_equal(101, b)
+ n += 1
+ rc.set_deferred_status :succeeded, 102, 102, 102
+ }
+ rc.callback {|a,b,c|
+ assert_equal(102, a)
+ assert_equal(102, b)
+ assert_equal(102, c)
+ n += 1
+ }
+ rc.set_deferred_status :succeeded, 100
+ assert_equal(3, n)
+ end
+
+ def test_syntactic_sugar
+ rc = RecursiveCallback.new
+ rc.set_deferred_success 100
+ rc.set_deferred_failure 200
+ end
+
+ # It doesn't raise an error to set deferred status more than once.
+ # In fact, this is a desired and useful idiom when it happens INSIDE
+ # a callback or errback.
+ # However, it's less useful otherwise, and in fact would generally be
+ # indicative of a programming error. However, we would like to be resistant
+ # to such errors. So whenever we set deferred status, we also clear BOTH
+ # stacks of handlers.
+ #
+ def test_double_calls
+ s = 0
+ e = 0
+
+ d = EM::DefaultDeferrable.new
+ d.callback {s += 1}
+ d.errback {e += 1}
+
+ d.succeed # We expect the callback to be called, and the errback to be DISCARDED.
+ d.fail # Presumably an error. We expect the errback NOT to be called.
+ d.succeed # We expect the callback to have been discarded and NOT to be called again.
+
+ assert_equal(1, s)
+ assert_equal(0, e)
+ end
+
+ # Adding a callback to a Deferrable that is already in a success state executes the callback
+ # immediately. The same applies to a an errback added to an already-failed Deferrable.
+ # HOWEVER, we expect NOT to be able to add errbacks to succeeded Deferrables, or callbacks
+ # to failed ones.
+ #
+ # We illustrate this with a rather contrived test. The test calls #fail after #succeed,
+ # which ordinarily would not happen in a real program.
+ #
+ # What we're NOT attempting to specify is what happens if a Deferrable is succeeded and then
+ # failed (or vice-versa). Should we then be able to add callbacks/errbacks of the appropriate
+ # type for immediate execution? For now at least, the official answer is "don't do that."
+ #
+ def test_delayed_callbacks
+ s1 = 0
+ s2 = 0
+ e = 0
+
+ d = EM::DefaultDeferrable.new
+ d.callback {s1 += 1}
+
+ d.succeed # Triggers and discards the callback.
+
+ d.callback {s2 += 1} # This callback is executed immediately and discarded.
+
+ d.errback {e += 1} # This errback should be DISCARDED and never execute.
+ d.fail # To prove it, fail and assert e is 0
+
+ assert_equal( [1,1], [s1,s2] )
+ assert_equal( 0, e )
+ end
+
+ def test_timeout
+ n = 0
+ EM.run {
+ d = EM::DefaultDeferrable.new
+ d.callback {n = 1; EM.stop}
+ d.errback {n = 2; EM.stop}
+ d.timeout(0.01)
+ }
+ assert_equal( 2, n )
+ end
+
+end