Module: Rooibos::TestHelper
- Includes:
- RatatuiRuby::TestHelper
- Defined in:
- lib/rooibos/test_helper.rb
Overview
Assertions and test utilities for Rooibos applications.
Custom commands run in background threads. Forgetting to include Command::Custom causes cryptic Ractor errors. Validating protocol compliance manually is tedious.
This module provides Rooibos-specific assertions. It also includes RatatuiRuby::TestHelper, giving you access to with_test_terminal, inject_key, etc.
Use it in Minitest classes to validate commands and control test terminals.
Example
class TestMyApp < Minitest::Test
include Rooibos::TestHelper
def test_app_exits_on_ctrl_c
with_test_terminal do
inject_key(:ctrl_c)
Rooibos.run(MyApp)
end
end
end
Constant Summary collapse
- ClearView =
Simple view that just clears the terminal
-> (_model, tui) { tui.clear }
- ExitOnQUpdate =
Update that exits on ‘q’ key, passes through all other messages
-> (msg, model) do case msg when RatatuiRuby::Event::Key (msg.code == "q") ? [model, Rooibos::Command.exit] : [model, nil] else [model, nil] end end
- ExitOnAnyKeyUpdate =
Update that exits immediately on any key
-> (_msg, model) { [model, Rooibos::Command.exit] }
Instance Method Summary collapse
-
#assert_no_errors(messages, msg = nil) ⇒ Object
Fails if any Message::Error is present in the messages array.
-
#validate_rooibos_command!(command) ⇒ Object
Validates a command implements the Rooibos command protocol.
Instance Method Details
#assert_no_errors(messages, msg = nil) ⇒ Object
Fails if any Message::Error is present in the messages array.
Call after running the runtime and before asserting on expected messages. This ensures tests fail fast with helpful error messages instead of silently passing when errors occur.
- messages
-
Array of messages collected from the update function.
- msg
-
Optional custom failure message prefix.
Example
def test_dashboard_loads_data
= []
update = -> (msg, m) do
# ... handle keys ...
<< msg
[m, nil]
end
with_test_terminal do
inject_key("s")
inject_sync
inject_key("q")
Rooibos::Runtime.run(model:, view:, update:)
end
assert_no_errors()
# ... rest of assertions
end
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/rooibos/test_helper.rb', line 105 def assert_no_errors(, msg = nil) error = .find { |m| m.is_a?(Rooibos::Message::Error) } return unless error error_detail = "#{error.exception.class}: #{error.exception.}" failure_msg = msg ? "#{msg}\n#{error_detail}" : "Unexpected Message::Error: #{error_detail}" if respond_to?(:flunk) # rubocop:disable Style/SendWithLiteralMethodName public_send(:flunk, failure_msg) # rubocop:enable Style/SendWithLiteralMethodName else raise failure_msg end end |
#validate_rooibos_command!(command) ⇒ Object
Validates a command implements the Rooibos command protocol.
Custom commands run in background threads. They dispatch work and send messages. Forgetting to include <tt>Command::Custom</tt> breaks dispatch. The runtime treats <tt>[model, bad_command]</tt> as a model, not a tuple. Tests fail with confusing Ractor shareability errors.
This method checks the protocol. Call it in tests to catch mistakes early.
- command
-
The command object to validate.
Example
def test_websocket_command_protocol
cmd = WebSocketCommand.new("wss://example.com")
validate_rooibos_command!(cmd)
end
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/rooibos/test_helper.rb', line 55 def validate_rooibos_command!(command) unless command.respond_to?(:rooibos_command?) raise Rooibos::Error::Invariant, "#{command.class} does not respond to #rooibos_command?. " \ "Include Command::Custom or implement the rooibos_command? predicate." end unless command.respond_to?(:call) raise Rooibos::Error::Invariant, "#{command.class} does not respond to #call. " \ "Implement call(out, token) to execute the command." end unless command.respond_to?(:rooibos_cancellation_grace_period) raise Rooibos::Error::Invariant, "#{command.class} does not respond to #rooibos_cancellation_grace_period. " \ "Include Command::Custom or implement this method." end end |