Class: Phronomy::Testing::FakeScheduler

Inherits:
Object
  • Object
show all
Defined in:
lib/phronomy/testing/fake_scheduler.rb

Overview

A deterministic event dispatcher for use in tests.

Wraps a Thread::Queue and dispatches events one at a time via #tick or drains all pending events via #tick_until_idle. Tests can inspect queue depth and verify event ordering without wall-clock sleeps.

Examples:

scheduler = Phronomy::Testing::FakeScheduler.new
scheduler.post(:a)
scheduler.post(:b)
scheduler.queue_depth   # => 2
scheduler.tick          # dispatches :a
scheduler.queue_depth   # => 1
scheduler.tick_until_idle
scheduler.dispatched    # => [:a, :b]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeFakeScheduler

Returns a new instance of FakeScheduler.



24
25
26
27
28
# File 'lib/phronomy/testing/fake_scheduler.rb', line 24

def initialize
  @queue = Thread::Queue.new
  @dispatched = []
  @handlers = {}
end

Instance Attribute Details

#dispatchedArray (readonly)

Returns all events dispatched so far (in order).

Returns:

  • (Array)

    all events dispatched so far (in order)



22
23
24
# File 'lib/phronomy/testing/fake_scheduler.rb', line 22

def dispatched
  @dispatched
end

Instance Method Details

#idle?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns true when the queue is empty.

Returns:

  • (Boolean)


99
100
101
# File 'lib/phronomy/testing/fake_scheduler.rb', line 99

def idle?
  @queue.empty?
end

#on(klass) {|event| ... } ⇒ self

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Register a handler block for events of the given class. Use +:any+ to handle all event types.

Parameters:

  • klass (Class, :any)

Yields:

  • (event)

Returns:

  • (self)


91
92
93
94
# File 'lib/phronomy/testing/fake_scheduler.rb', line 91

def on(klass, &block)
  @handlers[klass] = block
  self
end

#post(event) ⇒ self

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Enqueue an event for later dispatch.

Parameters:

  • event (Object)

Returns:

  • (self)


35
36
37
38
# File 'lib/phronomy/testing/fake_scheduler.rb', line 35

def post(event)
  @queue.push(event)
  self
end

#queue_depthInteger

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the number of events waiting to be dispatched.

Returns:

  • (Integer)


80
81
82
# File 'lib/phronomy/testing/fake_scheduler.rb', line 80

def queue_depth
  @queue.size
end

#tickObject?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Dispatch the next queued event. Calls the registered handler (if any) and records the event. Returns the dispatched event, or +nil+ if the queue is empty.

Returns:

  • (Object, nil)


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/phronomy/testing/fake_scheduler.rb', line 46

def tick
  return nil if @queue.empty?

  event = begin
    @queue.pop(true)
  rescue
    nil
  end
  return nil unless event

  @dispatched << event
  handler = @handlers[event.class] || @handlers[:any]
  handler&.call(event)
  event
end

#tick_until_idle(max_ticks: 1000) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Dispatch events until the queue is empty. Bounded by +max_ticks+ to prevent infinite loops.

Parameters:

  • max_ticks (Integer) (defaults to: 1000)

Returns:

  • (Integer)

    number of events dispatched



68
69
70
71
72
73
74
75
# File 'lib/phronomy/testing/fake_scheduler.rb', line 68

def tick_until_idle(max_ticks: 1000)
  count = 0
  while !@queue.empty? && count < max_ticks
    tick
    count += 1
  end
  count
end