File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -238,6 +238,15 @@ def perform(action, data = {})
238238 subscription . perform_action ( data . stringify_keys . merge ( "action" => action . to_s ) )
239239 end
240240
241+ # Advance the virtual clock used by `periodically` timers.
242+ #
243+ # subscribe
244+ # advance_time 5.seconds
245+ # assert_equal 1, subscription.tick_count
246+ def advance_time ( seconds )
247+ testserver . advance_time ( seconds )
248+ end
249+
241250 # Returns messages transmitted into channel
242251 def transmissions
243252 # Return only directly sent message (via #transmit)
Original file line number Diff line number Diff line change @@ -100,19 +100,44 @@ def transmit(data)
100100 def close
101101 @closed = true
102102 end
103+
104+ def perform_work ( receiver , method_name , *args )
105+ receiver . public_send ( method_name , *args )
106+ end
103107 end
104108
105109 class TestTimer
106- def shutdown ; end
110+ attr_reader :interval
111+
112+ def initialize ( interval , &block )
113+ @interval = interval
114+ @block = block
115+ @elapsed = 0
116+ @shutdown = false
117+ end
118+
119+ def shutdown
120+ @shutdown = true
121+ end
122+
123+ def advance ( seconds )
124+ return if @shutdown
125+ @elapsed += seconds
126+ while @elapsed >= @interval
127+ @elapsed -= @interval
128+ @block &.call
129+ end
130+ end
107131 end
108132
109133 # TestServer provides test pub/sub and executor implementations
110134 class TestServer
111- attr_reader :streams , :config
135+ attr_reader :streams , :config , :timers
112136
113137 def initialize ( server )
114138 @streams = Hash . new { |h , k | h [ k ] = [ ] }
115139 @config = server . config
140+ @timers = [ ]
116141 end
117142
118143 alias_method :pubsub , :itself
@@ -122,7 +147,14 @@ def initialize(server)
122147
123148 # Inline async calls
124149 def post ( &work ) = work . call
125- def timer ( _every ) = TestTimer . new
150+
151+ def timer ( every , &block )
152+ TestTimer . new ( every , &block ) . tap { |t | @timers << t }
153+ end
154+
155+ def advance_time ( seconds )
156+ @timers . each { |timer | timer . advance ( seconds ) }
157+ end
126158
127159 #== Pub/sub interface ==
128160 def subscribe ( stream , callback , success_callback = nil )
Original file line number Diff line number Diff line change @@ -115,6 +115,49 @@ def test_reject_does_not_crash_when_periodic_timer_is_registered
115115 end
116116end
117117
118+ class PeriodicCounterChannel < ActionCable ::Channel ::Base
119+ periodically :tick , every : 5
120+
121+ attr_reader :tick_count
122+
123+ def subscribed
124+ @tick_count = 0
125+ end
126+
127+ private
128+ def tick
129+ @tick_count += 1
130+ end
131+ end
132+
133+ class PeriodicCounterChannelTest < ActionCable ::Channel ::TestCase
134+ tests PeriodicCounterChannel
135+
136+ def test_advance_time_fires_periodic_callback_when_interval_is_reached
137+ subscribe
138+ assert_equal 0 , subscription . tick_count
139+
140+ advance_time 4
141+ assert_equal 0 , subscription . tick_count
142+
143+ advance_time 1
144+ assert_equal 1 , subscription . tick_count
145+
146+ advance_time 12
147+ assert_equal 3 , subscription . tick_count
148+ end
149+
150+ def test_shutdown_timer_stops_firing_after_unsubscribe
151+ subscribe
152+ advance_time 5
153+ assert_equal 1 , subscription . tick_count
154+
155+ unsubscribe
156+ advance_time 100
157+ assert_equal 1 , subscription . tick_count
158+ end
159+ end
160+
118161class StreamsTestChannel < ActionCable ::Channel ::Base
119162 def subscribed
120163 stream_from "test_#{ params [ :id ] || 0 } "
You can’t perform that action at this time.
0 commit comments