ratatui_ruby 1.4.0-x86_64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +15 -0
- data/LICENSES/AGPL-3.0-or-later.txt +661 -0
- data/LICENSES/CC-BY-SA-4.0.txt +427 -0
- data/LICENSES/CC0-1.0.txt +121 -0
- data/LICENSES/LGPL-3.0-or-later.txt +304 -0
- data/LICENSES/MIT-0.txt +16 -0
- data/LICENSES/MIT.txt +21 -0
- data/REUSE.toml +42 -0
- data/exe/.gitkeep +0 -0
- data/ext/ratatui_ruby/.cargo/config.toml +13 -0
- data/ext/ratatui_ruby/.gitignore +4 -0
- data/ext/ratatui_ruby/Cargo.lock +1737 -0
- data/ext/ratatui_ruby/Cargo.toml +24 -0
- data/ext/ratatui_ruby/clippy.toml +7 -0
- data/ext/ratatui_ruby/extconf.rb +21 -0
- data/ext/ratatui_ruby/src/color.rs +82 -0
- data/ext/ratatui_ruby/src/errors.rs +28 -0
- data/ext/ratatui_ruby/src/events.rs +700 -0
- data/ext/ratatui_ruby/src/frame.rs +241 -0
- data/ext/ratatui_ruby/src/lib.rs +343 -0
- data/ext/ratatui_ruby/src/lib_header.rs +11 -0
- data/ext/ratatui_ruby/src/rendering.rs +158 -0
- data/ext/ratatui_ruby/src/string_width.rs +101 -0
- data/ext/ratatui_ruby/src/style.rs +469 -0
- data/ext/ratatui_ruby/src/terminal/capabilities.rs +46 -0
- data/ext/ratatui_ruby/src/terminal/init.rs +233 -0
- data/ext/ratatui_ruby/src/terminal/mod.rs +42 -0
- data/ext/ratatui_ruby/src/terminal/mutations.rs +158 -0
- data/ext/ratatui_ruby/src/terminal/queries.rs +231 -0
- data/ext/ratatui_ruby/src/terminal/query.rs +400 -0
- data/ext/ratatui_ruby/src/terminal/storage.rs +109 -0
- data/ext/ratatui_ruby/src/terminal/wrapper.rs +16 -0
- data/ext/ratatui_ruby/src/text.rs +225 -0
- data/ext/ratatui_ruby/src/widgets/barchart.rs +169 -0
- data/ext/ratatui_ruby/src/widgets/block.rs +41 -0
- data/ext/ratatui_ruby/src/widgets/calendar.rs +84 -0
- data/ext/ratatui_ruby/src/widgets/canvas.rs +183 -0
- data/ext/ratatui_ruby/src/widgets/center.rs +79 -0
- data/ext/ratatui_ruby/src/widgets/chart.rs +222 -0
- data/ext/ratatui_ruby/src/widgets/clear.rs +39 -0
- data/ext/ratatui_ruby/src/widgets/cursor.rs +32 -0
- data/ext/ratatui_ruby/src/widgets/gauge.rs +65 -0
- data/ext/ratatui_ruby/src/widgets/layout.rs +379 -0
- data/ext/ratatui_ruby/src/widgets/line_gauge.rs +100 -0
- data/ext/ratatui_ruby/src/widgets/list.rs +378 -0
- data/ext/ratatui_ruby/src/widgets/list_state.rs +173 -0
- data/ext/ratatui_ruby/src/widgets/mod.rs +26 -0
- data/ext/ratatui_ruby/src/widgets/overlay.rs +24 -0
- data/ext/ratatui_ruby/src/widgets/paragraph.rs +87 -0
- data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +40 -0
- data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +55 -0
- data/ext/ratatui_ruby/src/widgets/scrollbar.rs +214 -0
- data/ext/ratatui_ruby/src/widgets/scrollbar_state.rs +169 -0
- data/ext/ratatui_ruby/src/widgets/sparkline.rs +127 -0
- data/ext/ratatui_ruby/src/widgets/table.rs +415 -0
- data/ext/ratatui_ruby/src/widgets/table_state.rs +203 -0
- data/ext/ratatui_ruby/src/widgets/tabs.rs +194 -0
- data/lib/ratatui_ruby/backend/window_size.rb +50 -0
- data/lib/ratatui_ruby/backend.rb +59 -0
- data/lib/ratatui_ruby/buffer/cell.rb +212 -0
- data/lib/ratatui_ruby/buffer.rb +149 -0
- data/lib/ratatui_ruby/cell.rb +208 -0
- data/lib/ratatui_ruby/debug.rb +215 -0
- data/lib/ratatui_ruby/draw.rb +63 -0
- data/lib/ratatui_ruby/event/focus_gained.rb +125 -0
- data/lib/ratatui_ruby/event/focus_lost.rb +127 -0
- data/lib/ratatui_ruby/event/key/character.rb +53 -0
- data/lib/ratatui_ruby/event/key/dwim.rb +301 -0
- data/lib/ratatui_ruby/event/key/media.rb +46 -0
- data/lib/ratatui_ruby/event/key/modifier.rb +107 -0
- data/lib/ratatui_ruby/event/key/navigation.rb +72 -0
- data/lib/ratatui_ruby/event/key/system.rb +47 -0
- data/lib/ratatui_ruby/event/key.rb +479 -0
- data/lib/ratatui_ruby/event/mouse.rb +291 -0
- data/lib/ratatui_ruby/event/none.rb +53 -0
- data/lib/ratatui_ruby/event/paste.rb +130 -0
- data/lib/ratatui_ruby/event/resize.rb +221 -0
- data/lib/ratatui_ruby/event/sync.rb +52 -0
- data/lib/ratatui_ruby/event.rb +163 -0
- data/lib/ratatui_ruby/frame.rb +257 -0
- data/lib/ratatui_ruby/labs/a11y.rb +182 -0
- data/lib/ratatui_ruby/labs/frame_a11y_capture.rb +50 -0
- data/lib/ratatui_ruby/labs.rb +47 -0
- data/lib/ratatui_ruby/layout/alignment.rb +91 -0
- data/lib/ratatui_ruby/layout/constraint.rb +337 -0
- data/lib/ratatui_ruby/layout/layout.rb +258 -0
- data/lib/ratatui_ruby/layout/position.rb +81 -0
- data/lib/ratatui_ruby/layout/rect.rb +733 -0
- data/lib/ratatui_ruby/layout/size.rb +62 -0
- data/lib/ratatui_ruby/layout.rb +29 -0
- data/lib/ratatui_ruby/list_state.rb +201 -0
- data/lib/ratatui_ruby/output_guard.rb +171 -0
- data/lib/ratatui_ruby/ratatui_ruby.so +0 -0
- data/lib/ratatui_ruby/scrollbar_state.rb +122 -0
- data/lib/ratatui_ruby/style/color.rb +149 -0
- data/lib/ratatui_ruby/style/style.rb +147 -0
- data/lib/ratatui_ruby/style.rb +19 -0
- data/lib/ratatui_ruby/symbols.rb +435 -0
- data/lib/ratatui_ruby/synthetic_events.rb +106 -0
- data/lib/ratatui_ruby/table_state.rb +251 -0
- data/lib/ratatui_ruby/terminal/capabilities.rb +316 -0
- data/lib/ratatui_ruby/terminal/viewport.rb +80 -0
- data/lib/ratatui_ruby/terminal.rb +66 -0
- data/lib/ratatui_ruby/terminal_lifecycle.rb +303 -0
- data/lib/ratatui_ruby/terminal_lifecycle.rb.bak +197 -0
- data/lib/ratatui_ruby/test_helper/event_injection.rb +241 -0
- data/lib/ratatui_ruby/test_helper/global_state.rb +111 -0
- data/lib/ratatui_ruby/test_helper/snapshot.rb +568 -0
- data/lib/ratatui_ruby/test_helper/snapshots/axis_labels_alignment.ansi +24 -0
- data/lib/ratatui_ruby/test_helper/snapshots/axis_labels_alignment.txt +24 -0
- data/lib/ratatui_ruby/test_helper/snapshots/barchart_styled_label.ansi +5 -0
- data/lib/ratatui_ruby/test_helper/snapshots/barchart_styled_label.txt +5 -0
- data/lib/ratatui_ruby/test_helper/snapshots/chart_rendering.ansi +24 -0
- data/lib/ratatui_ruby/test_helper/snapshots/chart_rendering.txt +24 -0
- data/lib/ratatui_ruby/test_helper/snapshots/half_block_marker.ansi +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/half_block_marker.txt +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_bottom.ansi +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_bottom.txt +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_left.ansi +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_left.txt +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_right.ansi +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_right.txt +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_top.ansi +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_top.txt +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/my_snapshot.txt +1 -0
- data/lib/ratatui_ruby/test_helper/snapshots/styled_axis_title.ansi +10 -0
- data/lib/ratatui_ruby/test_helper/snapshots/styled_axis_title.txt +10 -0
- data/lib/ratatui_ruby/test_helper/snapshots/styled_dataset_name.ansi +10 -0
- data/lib/ratatui_ruby/test_helper/snapshots/styled_dataset_name.txt +10 -0
- data/lib/ratatui_ruby/test_helper/style_assertions.rb +449 -0
- data/lib/ratatui_ruby/test_helper/subprocess_timeout.rb +35 -0
- data/lib/ratatui_ruby/test_helper/terminal.rb +187 -0
- data/lib/ratatui_ruby/test_helper/test_doubles.rb +86 -0
- data/lib/ratatui_ruby/test_helper.rb +115 -0
- data/lib/ratatui_ruby/text/line.rb +245 -0
- data/lib/ratatui_ruby/text/span.rb +158 -0
- data/lib/ratatui_ruby/text.rb +99 -0
- data/lib/ratatui_ruby/tui/buffer_factories.rb +22 -0
- data/lib/ratatui_ruby/tui/canvas_factories.rb +149 -0
- data/lib/ratatui_ruby/tui/core.rb +67 -0
- data/lib/ratatui_ruby/tui/layout_factories.rb +153 -0
- data/lib/ratatui_ruby/tui/state_factories.rb +77 -0
- data/lib/ratatui_ruby/tui/style_factories.rb +22 -0
- data/lib/ratatui_ruby/tui/text_factories.rb +86 -0
- data/lib/ratatui_ruby/tui/widget_factories.rb +272 -0
- data/lib/ratatui_ruby/tui.rb +106 -0
- data/lib/ratatui_ruby/version.rb +12 -0
- data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +51 -0
- data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +29 -0
- data/lib/ratatui_ruby/widgets/bar_chart.rb +308 -0
- data/lib/ratatui_ruby/widgets/block.rb +266 -0
- data/lib/ratatui_ruby/widgets/calendar.rb +88 -0
- data/lib/ratatui_ruby/widgets/canvas.rb +297 -0
- data/lib/ratatui_ruby/widgets/cell.rb +59 -0
- data/lib/ratatui_ruby/widgets/center.rb +71 -0
- data/lib/ratatui_ruby/widgets/chart.rb +172 -0
- data/lib/ratatui_ruby/widgets/clear.rb +66 -0
- data/lib/ratatui_ruby/widgets/coerceable_widget.rb +77 -0
- data/lib/ratatui_ruby/widgets/cursor.rb +54 -0
- data/lib/ratatui_ruby/widgets/gauge.rb +146 -0
- data/lib/ratatui_ruby/widgets/line_gauge.rb +158 -0
- data/lib/ratatui_ruby/widgets/list.rb +252 -0
- data/lib/ratatui_ruby/widgets/list_item.rb +55 -0
- data/lib/ratatui_ruby/widgets/overlay.rb +55 -0
- data/lib/ratatui_ruby/widgets/paragraph.rb +113 -0
- data/lib/ratatui_ruby/widgets/ratatui_logo.rb +35 -0
- data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +40 -0
- data/lib/ratatui_ruby/widgets/row.rb +123 -0
- data/lib/ratatui_ruby/widgets/scrollbar.rb +147 -0
- data/lib/ratatui_ruby/widgets/shape/label.rb +80 -0
- data/lib/ratatui_ruby/widgets/sparkline.rb +153 -0
- data/lib/ratatui_ruby/widgets/table.rb +213 -0
- data/lib/ratatui_ruby/widgets/tabs.rb +91 -0
- data/lib/ratatui_ruby/widgets.rb +43 -0
- data/lib/ratatui_ruby.rb +555 -0
- data/sig/examples/app_all_events/app.rbs +11 -0
- data/sig/examples/app_all_events/model/app_model.rbs +23 -0
- data/sig/examples/app_all_events/model/event_entry.rbs +23 -0
- data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
- data/sig/examples/app_all_events/view/app_view.rbs +8 -0
- data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
- data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
- data/sig/examples/app_all_events/view/live_view.rbs +6 -0
- data/sig/examples/app_all_events/view/log_view.rbs +6 -0
- data/sig/examples/app_all_events/view.rbs +14 -0
- data/sig/examples/app_cli_rich_moments/app.rbs +12 -0
- data/sig/examples/app_color_picker/app.rbs +17 -0
- data/sig/examples/app_external_editor/app.rbs +12 -0
- data/sig/examples/app_login_form/app.rbs +11 -0
- data/sig/examples/app_stateful_interaction/app.rbs +39 -0
- data/sig/examples/verify_quickstart_dsl/app.rbs +17 -0
- data/sig/examples/verify_quickstart_lifecycle/app.rbs +17 -0
- data/sig/examples/verify_readme_usage/app.rbs +17 -0
- data/sig/examples/widget_block_demo/app.rbs +38 -0
- data/sig/examples/widget_box_demo/app.rbs +17 -0
- data/sig/examples/widget_calendar_demo/app.rbs +17 -0
- data/sig/examples/widget_cell_demo/app.rbs +17 -0
- data/sig/examples/widget_chart_demo/app.rbs +17 -0
- data/sig/examples/widget_gauge_demo/app.rbs +17 -0
- data/sig/examples/widget_layout_split/app.rbs +16 -0
- data/sig/examples/widget_line_gauge_demo/app.rbs +17 -0
- data/sig/examples/widget_list_demo/app.rbs +17 -0
- data/sig/examples/widget_map_demo/app.rbs +17 -0
- data/sig/examples/widget_popup_demo/app.rbs +17 -0
- data/sig/examples/widget_ratatui_logo_demo/app.rbs +17 -0
- data/sig/examples/widget_ratatui_mascot_demo/app.rbs +17 -0
- data/sig/examples/widget_rect/app.rbs +18 -0
- data/sig/examples/widget_render/app.rbs +16 -0
- data/sig/examples/widget_rich_text/app.rbs +17 -0
- data/sig/examples/widget_scroll_text/app.rbs +17 -0
- data/sig/examples/widget_scrollbar_demo/app.rbs +17 -0
- data/sig/examples/widget_sparkline_demo/app.rbs +16 -0
- data/sig/examples/widget_style_colors/app.rbs +20 -0
- data/sig/examples/widget_table_demo/app.rbs +17 -0
- data/sig/examples/widget_text_width/app.rbs +16 -0
- data/sig/generated/event_key_predicates.rbs +1348 -0
- data/sig/manifest.yaml +5 -0
- data/sig/patches/data.rbs +26 -0
- data/sig/patches/debugger__.rbs +8 -0
- data/sig/ratatui_ruby/backend/window_size.rbs +17 -0
- data/sig/ratatui_ruby/backend.rbs +12 -0
- data/sig/ratatui_ruby/buffer/cell.rbs +46 -0
- data/sig/ratatui_ruby/buffer.rbs +18 -0
- data/sig/ratatui_ruby/cell.rbs +44 -0
- data/sig/ratatui_ruby/clear.rbs +18 -0
- data/sig/ratatui_ruby/constraint.rbs +26 -0
- data/sig/ratatui_ruby/debug.rbs +45 -0
- data/sig/ratatui_ruby/draw.rbs +30 -0
- data/sig/ratatui_ruby/event.rbs +249 -0
- data/sig/ratatui_ruby/frame.rbs +23 -0
- data/sig/ratatui_ruby/interfaces.rbs +25 -0
- data/sig/ratatui_ruby/labs.rbs +90 -0
- data/sig/ratatui_ruby/layout/alignment.rbs +26 -0
- data/sig/ratatui_ruby/layout/constraint.rbs +39 -0
- data/sig/ratatui_ruby/layout/layout.rbs +45 -0
- data/sig/ratatui_ruby/layout/position.rbs +18 -0
- data/sig/ratatui_ruby/layout/rect.rbs +64 -0
- data/sig/ratatui_ruby/layout/size.rbs +18 -0
- data/sig/ratatui_ruby/list_state.rbs +23 -0
- data/sig/ratatui_ruby/output_guard.rbs +23 -0
- data/sig/ratatui_ruby/ratatui_ruby.rbs +113 -0
- data/sig/ratatui_ruby/rect.rbs +17 -0
- data/sig/ratatui_ruby/scrollbar_state.rbs +24 -0
- data/sig/ratatui_ruby/session.rbs +93 -0
- data/sig/ratatui_ruby/style/color.rbs +22 -0
- data/sig/ratatui_ruby/style/style.rbs +29 -0
- data/sig/ratatui_ruby/symbols.rbs +141 -0
- data/sig/ratatui_ruby/synthetic_events.rbs +24 -0
- data/sig/ratatui_ruby/table_state.rbs +27 -0
- data/sig/ratatui_ruby/terminal/capabilities.rbs +38 -0
- data/sig/ratatui_ruby/terminal/viewport.rbs +33 -0
- data/sig/ratatui_ruby/terminal_lifecycle.rbs +39 -0
- data/sig/ratatui_ruby/test_helper/event_injection.rbs +22 -0
- data/sig/ratatui_ruby/test_helper/snapshot.rbs +37 -0
- data/sig/ratatui_ruby/test_helper/style_assertions.rbs +77 -0
- data/sig/ratatui_ruby/test_helper/terminal.rbs +20 -0
- data/sig/ratatui_ruby/test_helper/test_doubles.rbs +32 -0
- data/sig/ratatui_ruby/test_helper.rbs +18 -0
- data/sig/ratatui_ruby/text/line.rbs +27 -0
- data/sig/ratatui_ruby/text/span.rbs +23 -0
- data/sig/ratatui_ruby/text.rbs +12 -0
- data/sig/ratatui_ruby/tui/buffer_factories.rbs +16 -0
- data/sig/ratatui_ruby/tui/canvas_factories.rbs +38 -0
- data/sig/ratatui_ruby/tui/core.rbs +23 -0
- data/sig/ratatui_ruby/tui/layout_factories.rbs +39 -0
- data/sig/ratatui_ruby/tui/state_factories.rbs +23 -0
- data/sig/ratatui_ruby/tui/style_factories.rbs +18 -0
- data/sig/ratatui_ruby/tui/text_factories.rbs +23 -0
- data/sig/ratatui_ruby/tui/widget_factories.rbs +138 -0
- data/sig/ratatui_ruby/tui.rbs +25 -0
- data/sig/ratatui_ruby/version.rbs +12 -0
- data/sig/ratatui_ruby/widgets/bar_chart.rbs +95 -0
- data/sig/ratatui_ruby/widgets/block.rbs +51 -0
- data/sig/ratatui_ruby/widgets/calendar.rbs +45 -0
- data/sig/ratatui_ruby/widgets/canvas.rbs +95 -0
- data/sig/ratatui_ruby/widgets/chart.rbs +91 -0
- data/sig/ratatui_ruby/widgets/coerceable_widget.rbs +26 -0
- data/sig/ratatui_ruby/widgets/gauge.rbs +44 -0
- data/sig/ratatui_ruby/widgets/line_gauge.rbs +48 -0
- data/sig/ratatui_ruby/widgets/list.rbs +63 -0
- data/sig/ratatui_ruby/widgets/misc.rbs +158 -0
- data/sig/ratatui_ruby/widgets/paragraph.rbs +45 -0
- data/sig/ratatui_ruby/widgets/row.rbs +43 -0
- data/sig/ratatui_ruby/widgets/scrollbar.rbs +53 -0
- data/sig/ratatui_ruby/widgets/shape/label.rbs +37 -0
- data/sig/ratatui_ruby/widgets/sparkline.rbs +45 -0
- data/sig/ratatui_ruby/widgets/table.rbs +78 -0
- data/sig/ratatui_ruby/widgets/tabs.rbs +44 -0
- data/sig/ratatui_ruby/widgets.rbs +16 -0
- data/vendor/goodcop/base.yml +1047 -0
- metadata +729 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
module RatatuiRuby
|
|
9
|
+
module TestHelper
|
|
10
|
+
##
|
|
11
|
+
# Event injection helpers for testing TUI interactions.
|
|
12
|
+
#
|
|
13
|
+
# Testing keyboard navigation and mouse clicks requires simulating user input.
|
|
14
|
+
# Constructing event objects by hand for every test is verbose and repetitive.
|
|
15
|
+
#
|
|
16
|
+
# This mixin provides convenience methods to inject keys, clicks, and other events
|
|
17
|
+
# into the test terminal's event queue. Events are consumed by the next
|
|
18
|
+
# <tt>poll_event</tt> call.
|
|
19
|
+
#
|
|
20
|
+
# Use it to simulate user interactions: typing, clicking, dragging, pasting.
|
|
21
|
+
#
|
|
22
|
+
# === Examples
|
|
23
|
+
#
|
|
24
|
+
#--
|
|
25
|
+
# SPDX-SnippetBegin
|
|
26
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
27
|
+
# SPDX-License-Identifier: MIT-0
|
|
28
|
+
#++
|
|
29
|
+
# with_test_terminal do
|
|
30
|
+
# inject_keys("h", "e", "l", "l", "o")
|
|
31
|
+
# inject_keys(:enter, :ctrl_s)
|
|
32
|
+
# inject_click(x: 10, y: 5)
|
|
33
|
+
# inject_event(RatatuiRuby::Event::Paste.new(content: "pasted text"))
|
|
34
|
+
#
|
|
35
|
+
# @app.run
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
#--
|
|
39
|
+
# SPDX-SnippetEnd
|
|
40
|
+
#++
|
|
41
|
+
module EventInjection
|
|
42
|
+
##
|
|
43
|
+
# Injects an event into the test terminal's event queue.
|
|
44
|
+
#
|
|
45
|
+
# Pass any <tt>RatatuiRuby::Event</tt> object. The event is returned by
|
|
46
|
+
# the next <tt>poll_event</tt> call.
|
|
47
|
+
#
|
|
48
|
+
# Raises <tt>RuntimeError</tt> if called outside a <tt>with_test_terminal</tt> block.
|
|
49
|
+
#
|
|
50
|
+
# === Examples
|
|
51
|
+
#
|
|
52
|
+
#--
|
|
53
|
+
# SPDX-SnippetBegin
|
|
54
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
55
|
+
# SPDX-License-Identifier: MIT-0
|
|
56
|
+
#++
|
|
57
|
+
# inject_event(RatatuiRuby::Event::Key.new(code: "q"))
|
|
58
|
+
# inject_event(RatatuiRuby::Event::Mouse.new(kind: "down", button: "left", x: 10, y: 5))
|
|
59
|
+
# inject_event(RatatuiRuby::Event::Paste.new(content: "Hello"))
|
|
60
|
+
#
|
|
61
|
+
#--
|
|
62
|
+
# SPDX-SnippetEnd
|
|
63
|
+
#++
|
|
64
|
+
# [event] A <tt>RatatuiRuby::Event</tt> object.
|
|
65
|
+
def inject_event(event)
|
|
66
|
+
unless @_ratatui_test_terminal_active
|
|
67
|
+
raise RatatuiRuby::Error::Invariant, "Events must be injected inside a `with_test_terminal` block. " \
|
|
68
|
+
"Calling this method outside the block causes a race condition where the event " \
|
|
69
|
+
"is flushed before the application starts."
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
case event
|
|
73
|
+
when RatatuiRuby::Event::Key
|
|
74
|
+
RatatuiRuby.inject_test_event("key", { code: event.code, modifiers: event.modifiers })
|
|
75
|
+
when RatatuiRuby::Event::Mouse
|
|
76
|
+
RatatuiRuby.inject_test_event("mouse", {
|
|
77
|
+
kind: event.kind,
|
|
78
|
+
button: event.button,
|
|
79
|
+
x: event.x,
|
|
80
|
+
y: event.y,
|
|
81
|
+
modifiers: event.modifiers,
|
|
82
|
+
})
|
|
83
|
+
when RatatuiRuby::Event::Resize
|
|
84
|
+
RatatuiRuby.inject_test_event("resize", { width: event.width, height: event.height })
|
|
85
|
+
when RatatuiRuby::Event::Paste
|
|
86
|
+
RatatuiRuby.inject_test_event("paste", { content: event.content })
|
|
87
|
+
when RatatuiRuby::Event::FocusGained
|
|
88
|
+
RatatuiRuby.inject_test_event("focus_gained", {})
|
|
89
|
+
when RatatuiRuby::Event::FocusLost
|
|
90
|
+
RatatuiRuby.inject_test_event("focus_lost", {})
|
|
91
|
+
when RatatuiRuby::Event::Sync
|
|
92
|
+
if RatatuiRuby::SyntheticEvents.inline_sync?
|
|
93
|
+
# Route through native queue for deterministic ordering with key events
|
|
94
|
+
RatatuiRuby.inject_test_event("sync", {})
|
|
95
|
+
else
|
|
96
|
+
# Default 1.0 behavior: use the engine-level synthetic queue
|
|
97
|
+
RatatuiRuby::SyntheticEvents.push(event)
|
|
98
|
+
end
|
|
99
|
+
else
|
|
100
|
+
raise ArgumentError, "Unknown event type: #{event.class}"
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
##
|
|
105
|
+
# Injects a mouse event.
|
|
106
|
+
#
|
|
107
|
+
# === Example
|
|
108
|
+
#
|
|
109
|
+
#--
|
|
110
|
+
# SPDX-SnippetBegin
|
|
111
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
112
|
+
# SPDX-License-Identifier: MIT-0
|
|
113
|
+
#++
|
|
114
|
+
# inject_mouse(x: 10, y: 5, kind: :down, button: :left)
|
|
115
|
+
#
|
|
116
|
+
#--
|
|
117
|
+
# SPDX-SnippetEnd
|
|
118
|
+
#++
|
|
119
|
+
# [x] Integer x-coordinate.
|
|
120
|
+
# [y] Integer y-coordinate.
|
|
121
|
+
# [kind] Symbol <tt>:down</tt>, <tt>:up</tt>, or <tt>:drag</tt>.
|
|
122
|
+
# [button] Symbol <tt>:left</tt>, <tt>:right</tt>, or <tt>:middle</tt>.
|
|
123
|
+
# [modifiers] Array of modifier strings.
|
|
124
|
+
def inject_mouse(x:, y:, kind: :down, modifiers: [], button: :left)
|
|
125
|
+
event = RatatuiRuby::Event::Mouse.new(
|
|
126
|
+
kind: kind.to_s,
|
|
127
|
+
x:,
|
|
128
|
+
y:,
|
|
129
|
+
button: button.to_s,
|
|
130
|
+
modifiers:
|
|
131
|
+
)
|
|
132
|
+
inject_event(event)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
##
|
|
136
|
+
# Injects a left mouse click.
|
|
137
|
+
#
|
|
138
|
+
# === Example
|
|
139
|
+
#
|
|
140
|
+
# inject_click(x: 10, y: 5)
|
|
141
|
+
def inject_click(x:, y:, modifiers: [])
|
|
142
|
+
inject_mouse(x:, y:, kind: :down, modifiers:, button: :left)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
##
|
|
146
|
+
# Injects a right mouse click.
|
|
147
|
+
#
|
|
148
|
+
# === Example
|
|
149
|
+
#
|
|
150
|
+
# inject_right_click(x: 10, y: 5)
|
|
151
|
+
def inject_right_click(x:, y:, modifiers: [])
|
|
152
|
+
inject_mouse(x:, y:, kind: :down, modifiers:, button: :right)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
##
|
|
156
|
+
# Injects a mouse drag event.
|
|
157
|
+
#
|
|
158
|
+
# === Example
|
|
159
|
+
#
|
|
160
|
+
# inject_drag(x: 10, y: 5)
|
|
161
|
+
def inject_drag(x:, y:, modifiers: [], button: :left)
|
|
162
|
+
inject_mouse(x:, y:, kind: :drag, modifiers:, button:)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
##
|
|
166
|
+
# Injects one or more key events.
|
|
167
|
+
#
|
|
168
|
+
# Accepts multiple formats for convenience:
|
|
169
|
+
# - String: Character key (e.g., <tt>"a"</tt>, <tt>"q"</tt>)
|
|
170
|
+
# - Symbol: Named key or modifier combo (e.g., <tt>:enter</tt>, <tt>:ctrl_c</tt>)
|
|
171
|
+
# - Hash: Passed to <tt>Key.new</tt>
|
|
172
|
+
# - Key: Passed directly
|
|
173
|
+
#
|
|
174
|
+
# === Examples
|
|
175
|
+
#
|
|
176
|
+
#--
|
|
177
|
+
# SPDX-SnippetBegin
|
|
178
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
179
|
+
# SPDX-License-Identifier: MIT-0
|
|
180
|
+
#++
|
|
181
|
+
# inject_keys("a", "b", "c")
|
|
182
|
+
# inject_keys(:enter, :esc)
|
|
183
|
+
# inject_keys(:ctrl_c, :alt_shift_left)
|
|
184
|
+
# inject_keys("j", { code: "k", modifiers: ["ctrl"] })
|
|
185
|
+
#--
|
|
186
|
+
# SPDX-SnippetEnd
|
|
187
|
+
#++
|
|
188
|
+
def inject_keys(*args)
|
|
189
|
+
args.each do |arg|
|
|
190
|
+
event = case arg
|
|
191
|
+
when String
|
|
192
|
+
RatatuiRuby::Event::Key.new(code: arg)
|
|
193
|
+
when Symbol
|
|
194
|
+
parts = arg.to_s.split("_")
|
|
195
|
+
code = parts.pop
|
|
196
|
+
modifiers = parts
|
|
197
|
+
RatatuiRuby::Event::Key.new(code:, modifiers:)
|
|
198
|
+
when Hash
|
|
199
|
+
RatatuiRuby::Event::Key.new(**arg)
|
|
200
|
+
when RatatuiRuby::Event::Key
|
|
201
|
+
arg
|
|
202
|
+
else
|
|
203
|
+
raise ArgumentError, "Invalid key argument: #{arg.inspect}. Expected String, Symbol, Hash, or Key event."
|
|
204
|
+
end
|
|
205
|
+
inject_event(event)
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
alias inject_key inject_keys
|
|
209
|
+
|
|
210
|
+
##
|
|
211
|
+
# Injects a Sync event.
|
|
212
|
+
#
|
|
213
|
+
# When a runtime (Tea, Kit) encounters this event, it should wait for all
|
|
214
|
+
# pending async operations to complete before processing the next event.
|
|
215
|
+
# This enables deterministic testing of async behavior.
|
|
216
|
+
#
|
|
217
|
+
# *Important*: Sync waits for commands to _complete_. Do not use it
|
|
218
|
+
# with long-running commands that wait indefinitely (e.g., for
|
|
219
|
+
# cancellation). Those commands will block forever, causing a timeout.
|
|
220
|
+
# For cancellation tests, dispatch the cancel command without Sync.
|
|
221
|
+
#
|
|
222
|
+
# === Example
|
|
223
|
+
#
|
|
224
|
+
#--
|
|
225
|
+
# SPDX-SnippetBegin
|
|
226
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
227
|
+
# SPDX-License-Identifier: MIT-0
|
|
228
|
+
#++
|
|
229
|
+
# inject_key("s") # Triggers async command
|
|
230
|
+
# inject_sync # Wait for command to complete
|
|
231
|
+
# inject_key(:q) # Quit after seeing results
|
|
232
|
+
#
|
|
233
|
+
#--
|
|
234
|
+
# SPDX-SnippetEnd
|
|
235
|
+
#++
|
|
236
|
+
def inject_sync
|
|
237
|
+
inject_event(RatatuiRuby::Event::Sync.new)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
module RatatuiRuby
|
|
9
|
+
module TestHelper
|
|
10
|
+
##
|
|
11
|
+
# Helpers for testing code that reads global state.
|
|
12
|
+
#
|
|
13
|
+
# Applications often read +ARGV+ and +ENV+ at startup. Testing these code
|
|
14
|
+
# paths requires stubbing those constants. Doing it manually is brittle —
|
|
15
|
+
# tests that forget to restore the original values leak state.
|
|
16
|
+
#
|
|
17
|
+
# These helpers swap the constants, yield to the block, and restore the
|
|
18
|
+
# originals automatically.
|
|
19
|
+
#
|
|
20
|
+
# == Example
|
|
21
|
+
#
|
|
22
|
+
#--
|
|
23
|
+
# SPDX-SnippetBegin
|
|
24
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
25
|
+
# SPDX-License-Identifier: MIT-0
|
|
26
|
+
#++
|
|
27
|
+
# def test_parses_command_line_flags
|
|
28
|
+
# with_argv(["--verbose", "--log=debug.log"]) do
|
|
29
|
+
# app = MyApp.new
|
|
30
|
+
# assert app.verbose?
|
|
31
|
+
# assert_equal "debug.log", app.log_path
|
|
32
|
+
# end
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# def test_reads_api_key_from_environment
|
|
36
|
+
# with_env("API_KEY", "test-key-1234") do
|
|
37
|
+
# client = APIClient.new
|
|
38
|
+
# assert_equal "test-key-1234", client.api_key
|
|
39
|
+
# end
|
|
40
|
+
# end
|
|
41
|
+
#--
|
|
42
|
+
# SPDX-SnippetEnd
|
|
43
|
+
#++
|
|
44
|
+
module GlobalState
|
|
45
|
+
# Temporarily replaces ARGV for the duration of the block.
|
|
46
|
+
#
|
|
47
|
+
# [argv] An array of strings to use as ARGV.
|
|
48
|
+
#
|
|
49
|
+
# === Example
|
|
50
|
+
#
|
|
51
|
+
#--
|
|
52
|
+
# SPDX-SnippetBegin
|
|
53
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
54
|
+
# SPDX-License-Identifier: MIT-0
|
|
55
|
+
#++
|
|
56
|
+
# with_argv(["--help"]) do
|
|
57
|
+
# # Code here sees ARGV as ["--help"]
|
|
58
|
+
# end
|
|
59
|
+
#--
|
|
60
|
+
# SPDX-SnippetEnd
|
|
61
|
+
#++
|
|
62
|
+
def with_argv(argv)
|
|
63
|
+
original_argv = ARGV.dup
|
|
64
|
+
ARGV.replace(argv)
|
|
65
|
+
yield
|
|
66
|
+
ensure
|
|
67
|
+
ARGV.replace(original_argv)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Temporarily replaces an environment variable for the duration of the block.
|
|
71
|
+
#
|
|
72
|
+
# If +value+ is +nil+, the variable is deleted for the block's duration.
|
|
73
|
+
#
|
|
74
|
+
# [key] The environment variable name (String).
|
|
75
|
+
# [value] The value to set, or +nil+ to delete.
|
|
76
|
+
#
|
|
77
|
+
# === Example
|
|
78
|
+
#
|
|
79
|
+
#--
|
|
80
|
+
# SPDX-SnippetBegin
|
|
81
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
82
|
+
# SPDX-License-Identifier: MIT-0
|
|
83
|
+
#++
|
|
84
|
+
# with_env("DEBUG", "1") do
|
|
85
|
+
# # Code here sees ENV["DEBUG"] as "1"
|
|
86
|
+
# end
|
|
87
|
+
#
|
|
88
|
+
# with_env("DEBUG", nil) do
|
|
89
|
+
# # Code here does not see ENV["DEBUG"]
|
|
90
|
+
# end
|
|
91
|
+
#--
|
|
92
|
+
# SPDX-SnippetEnd
|
|
93
|
+
#++
|
|
94
|
+
def with_env(key, value)
|
|
95
|
+
original_value = ENV[key]
|
|
96
|
+
if value.nil?
|
|
97
|
+
ENV.delete(key)
|
|
98
|
+
else
|
|
99
|
+
ENV[key] = value
|
|
100
|
+
end
|
|
101
|
+
yield
|
|
102
|
+
ensure
|
|
103
|
+
if original_value.nil?
|
|
104
|
+
ENV.delete(key)
|
|
105
|
+
else
|
|
106
|
+
ENV[key] = original_value
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|