ratatui_ruby 0.4.0 → 0.5.0

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.
Files changed (351) hide show
  1. checksums.yaml +4 -4
  2. data/.builds/ruby-3.2.yml +1 -1
  3. data/.builds/ruby-3.3.yml +1 -1
  4. data/.builds/ruby-3.4.yml +1 -1
  5. data/.builds/ruby-4.0.0.yml +1 -1
  6. data/AGENTS.md +87 -171
  7. data/CHANGELOG.md +38 -1
  8. data/README.md +8 -3
  9. data/REUSE.toml +20 -0
  10. data/doc/application_architecture.md +105 -45
  11. data/doc/application_testing.md +5 -3
  12. data/doc/contributors/design/ruby_frontend.md +9 -5
  13. data/doc/contributors/developing_examples.md +76 -18
  14. data/doc/contributors/documentation_style.md +7 -0
  15. data/doc/contributors/index.md +2 -0
  16. data/doc/event_handling.md +10 -4
  17. data/doc/images/app_all_events.png +0 -0
  18. data/doc/images/app_color_picker.png +0 -0
  19. data/doc/images/verify_readme_usage.png +0 -0
  20. data/doc/images/widget_barchart_demo.png +0 -0
  21. data/doc/images/widget_block_padding.png +0 -0
  22. data/doc/images/widget_block_titles.png +0 -0
  23. data/doc/images/widget_box_demo.png +0 -0
  24. data/doc/images/widget_calendar_demo.png +0 -0
  25. data/doc/images/widget_cell_demo.png +0 -0
  26. data/doc/images/widget_chart_demo.png +0 -0
  27. data/doc/images/widget_gauge_demo.png +0 -0
  28. data/doc/images/widget_layout_split.png +0 -0
  29. data/doc/images/widget_line_gauge_demo.png +0 -0
  30. data/doc/images/widget_list_demo.png +0 -0
  31. data/doc/images/widget_ratatui_logo_demo.png +0 -0
  32. data/doc/images/widget_ratatui_mascot_demo.png +0 -0
  33. data/doc/images/widget_render.png +0 -0
  34. data/doc/images/widget_scrollbar_demo.png +0 -0
  35. data/doc/images/widget_sparkline_demo.png +0 -0
  36. data/doc/images/widget_style_colors.png +0 -0
  37. data/doc/images/widget_table_flex.png +0 -0
  38. data/doc/images/widget_tabs_demo.png +0 -0
  39. data/doc/interactive_design.md +25 -30
  40. data/doc/quickstart.md +147 -120
  41. data/examples/app_all_events/README.md +81 -0
  42. data/examples/app_all_events/app.rb +93 -0
  43. data/examples/app_all_events/model/event_color_cycle.rb +41 -0
  44. data/examples/app_all_events/model/event_entry.rb +75 -0
  45. data/examples/app_all_events/model/events.rb +180 -0
  46. data/examples/app_all_events/model/highlight.rb +57 -0
  47. data/examples/app_all_events/model/timestamp.rb +54 -0
  48. data/examples/app_all_events/test/snapshots/after_focus_lost.txt +24 -0
  49. data/examples/app_all_events/test/snapshots/after_focus_regained.txt +24 -0
  50. data/examples/app_all_events/test/snapshots/after_horizontal_resize.txt +24 -0
  51. data/examples/app_all_events/test/snapshots/after_key_a.txt +24 -0
  52. data/examples/app_all_events/test/snapshots/after_key_ctrl_x.txt +24 -0
  53. data/examples/app_all_events/test/snapshots/after_mouse_click.txt +24 -0
  54. data/examples/app_all_events/test/snapshots/after_mouse_drag.txt +24 -0
  55. data/examples/app_all_events/test/snapshots/after_multiple_events.txt +24 -0
  56. data/examples/app_all_events/test/snapshots/after_paste.txt +24 -0
  57. data/examples/app_all_events/test/snapshots/after_resize.txt +24 -0
  58. data/examples/app_all_events/test/snapshots/after_right_click.txt +24 -0
  59. data/examples/app_all_events/test/snapshots/after_vertical_resize.txt +24 -0
  60. data/examples/app_all_events/test/snapshots/initial_state.txt +24 -0
  61. data/examples/app_all_events/view/app_view.rb +78 -0
  62. data/examples/app_all_events/view/controls_view.rb +50 -0
  63. data/examples/app_all_events/view/counts_view.rb +55 -0
  64. data/examples/app_all_events/view/live_view.rb +69 -0
  65. data/examples/app_all_events/view/log_view.rb +60 -0
  66. data/examples/app_all_events/view.rb +7 -0
  67. data/examples/app_all_events/view_state.rb +42 -0
  68. data/examples/app_color_picker/README.md +94 -0
  69. data/examples/app_color_picker/app.rb +112 -0
  70. data/examples/app_color_picker/clipboard.rb +84 -0
  71. data/examples/app_color_picker/color.rb +191 -0
  72. data/examples/app_color_picker/copy_dialog.rb +170 -0
  73. data/examples/app_color_picker/harmony.rb +56 -0
  74. data/examples/app_color_picker/input.rb +142 -0
  75. data/examples/app_color_picker/palette.rb +80 -0
  76. data/examples/app_color_picker/scene.rb +201 -0
  77. data/examples/{login_form → app_login_form}/app.rb +39 -42
  78. data/examples/{map_demo → app_map_demo}/app.rb +24 -21
  79. data/examples/{table_select → app_table_select}/app.rb +68 -65
  80. data/examples/{quickstart_dsl → verify_quickstart_dsl}/app.rb +15 -6
  81. data/examples/verify_quickstart_layout/app.rb +69 -0
  82. data/examples/{quickstart_lifecycle → verify_quickstart_lifecycle}/app.rb +19 -10
  83. data/examples/verify_readme_usage/app.rb +34 -0
  84. data/examples/widget_barchart_demo/app.rb +238 -0
  85. data/examples/{block_padding → widget_block_padding}/app.rb +17 -13
  86. data/examples/{block_titles → widget_block_titles}/app.rb +25 -17
  87. data/examples/{box_demo → widget_box_demo}/app.rb +99 -65
  88. data/examples/widget_calendar_demo/app.rb +109 -0
  89. data/examples/widget_cell_demo/app.rb +104 -0
  90. data/examples/widget_chart_demo/app.rb +213 -0
  91. data/examples/widget_gauge_demo/app.rb +212 -0
  92. data/examples/widget_layout_split/app.rb +246 -0
  93. data/examples/widget_line_gauge_demo/app.rb +217 -0
  94. data/examples/widget_list_demo/app.rb +382 -0
  95. data/examples/widget_list_styles/app.rb +141 -0
  96. data/examples/widget_popup_demo/app.rb +104 -0
  97. data/examples/widget_ratatui_logo_demo/app.rb +103 -0
  98. data/examples/widget_ratatui_mascot_demo/app.rb +93 -0
  99. data/examples/widget_rect/app.rb +205 -0
  100. data/examples/widget_render/app.rb +184 -0
  101. data/examples/widget_rich_text/app.rb +137 -0
  102. data/examples/widget_scroll_text/app.rb +108 -0
  103. data/examples/widget_scrollbar_demo/app.rb +153 -0
  104. data/examples/widget_sparkline_demo/app.rb +274 -0
  105. data/examples/widget_style_colors/app.rb +19 -21
  106. data/examples/widget_table_flex/app.rb +95 -0
  107. data/examples/widget_tabs_demo/app.rb +167 -0
  108. data/ext/ratatui_ruby/Cargo.lock +1 -1
  109. data/ext/ratatui_ruby/Cargo.toml +1 -1
  110. data/ext/ratatui_ruby/src/events.rs +121 -36
  111. data/ext/ratatui_ruby/src/frame.rs +115 -0
  112. data/ext/ratatui_ruby/src/lib.rs +79 -26
  113. data/ext/ratatui_ruby/src/rendering.rs +8 -4
  114. data/ext/ratatui_ruby/src/style.rs +138 -57
  115. data/ext/ratatui_ruby/src/terminal.rs +5 -9
  116. data/ext/ratatui_ruby/src/text.rs +13 -6
  117. data/ext/ratatui_ruby/src/widgets/barchart.rs +56 -54
  118. data/ext/ratatui_ruby/src/widgets/block.rs +7 -6
  119. data/ext/ratatui_ruby/src/widgets/canvas.rs +21 -3
  120. data/ext/ratatui_ruby/src/widgets/chart.rs +20 -10
  121. data/ext/ratatui_ruby/src/widgets/layout.rs +9 -4
  122. data/ext/ratatui_ruby/src/widgets/list.rs +32 -9
  123. data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
  124. data/ext/ratatui_ruby/src/widgets/paragraph.rs +1 -1
  125. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +19 -8
  126. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +17 -10
  127. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +4 -2
  128. data/ext/ratatui_ruby/src/widgets/sparkline.rs +14 -11
  129. data/ext/ratatui_ruby/src/widgets/table.rs +8 -4
  130. data/ext/ratatui_ruby/src/widgets/tabs.rs +11 -11
  131. data/lib/ratatui_ruby/cell.rb +3 -3
  132. data/lib/ratatui_ruby/event/key.rb +1 -1
  133. data/lib/ratatui_ruby/event/none.rb +43 -0
  134. data/lib/ratatui_ruby/event.rb +56 -4
  135. data/lib/ratatui_ruby/frame.rb +87 -0
  136. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +11 -11
  137. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +1 -5
  138. data/lib/ratatui_ruby/schema/bar_chart.rb +217 -217
  139. data/lib/ratatui_ruby/schema/block.rb +163 -168
  140. data/lib/ratatui_ruby/schema/calendar.rb +66 -67
  141. data/lib/ratatui_ruby/schema/canvas.rb +63 -63
  142. data/lib/ratatui_ruby/schema/center.rb +46 -46
  143. data/lib/ratatui_ruby/schema/chart.rb +135 -143
  144. data/lib/ratatui_ruby/schema/clear.rb +42 -42
  145. data/lib/ratatui_ruby/schema/constraint.rb +76 -76
  146. data/lib/ratatui_ruby/schema/cursor.rb +25 -25
  147. data/lib/ratatui_ruby/schema/gauge.rb +53 -53
  148. data/lib/ratatui_ruby/schema/layout.rb +87 -87
  149. data/lib/ratatui_ruby/schema/line_gauge.rb +62 -62
  150. data/lib/ratatui_ruby/schema/list.rb +86 -84
  151. data/lib/ratatui_ruby/schema/overlay.rb +31 -31
  152. data/lib/ratatui_ruby/schema/paragraph.rb +80 -80
  153. data/lib/ratatui_ruby/schema/ratatui_logo.rb +10 -6
  154. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +10 -5
  155. data/lib/ratatui_ruby/schema/rect.rb +60 -60
  156. data/lib/ratatui_ruby/schema/scrollbar.rb +119 -119
  157. data/lib/ratatui_ruby/schema/shape/label.rb +1 -1
  158. data/lib/ratatui_ruby/schema/sparkline.rb +111 -110
  159. data/lib/ratatui_ruby/schema/style.rb +46 -46
  160. data/lib/ratatui_ruby/schema/table.rb +112 -119
  161. data/lib/ratatui_ruby/schema/tabs.rb +66 -67
  162. data/lib/ratatui_ruby/session/autodoc.rb +417 -0
  163. data/lib/ratatui_ruby/session.rb +40 -23
  164. data/lib/ratatui_ruby/test_helper.rb +185 -19
  165. data/lib/ratatui_ruby/version.rb +1 -1
  166. data/lib/ratatui_ruby.rb +65 -39
  167. data/{examples/sparkline_demo → sig/examples/app_all_events}/app.rbs +3 -2
  168. data/sig/examples/app_all_events/model/event_entry.rbs +16 -0
  169. data/sig/examples/app_all_events/model/events.rbs +15 -0
  170. data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
  171. data/sig/examples/app_all_events/view/app_view.rbs +8 -0
  172. data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
  173. data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
  174. data/sig/examples/app_all_events/view/live_view.rbs +6 -0
  175. data/sig/examples/app_all_events/view/log_view.rbs +6 -0
  176. data/sig/examples/app_all_events/view.rbs +8 -0
  177. data/sig/examples/app_all_events/view_state.rbs +15 -0
  178. data/{examples/list_demo → sig/examples/app_color_picker}/app.rbs +2 -2
  179. data/sig/examples/app_login_form/app.rbs +11 -0
  180. data/sig/examples/app_map_demo/app.rbs +11 -0
  181. data/sig/examples/app_table_select/app.rbs +11 -0
  182. data/sig/examples/verify_quickstart_dsl/app.rbs +11 -0
  183. data/sig/examples/verify_quickstart_lifecycle/app.rbs +11 -0
  184. data/sig/examples/verify_readme_usage/app.rbs +11 -0
  185. data/sig/examples/widget_block_padding/app.rbs +11 -0
  186. data/sig/examples/widget_block_titles/app.rbs +11 -0
  187. data/sig/examples/widget_box_demo/app.rbs +11 -0
  188. data/sig/examples/widget_calendar_demo/app.rbs +11 -0
  189. data/sig/examples/widget_cell_demo/app.rbs +11 -0
  190. data/sig/examples/widget_chart_demo/app.rbs +11 -0
  191. data/{examples/gauge_demo → sig/examples/widget_gauge_demo}/app.rbs +4 -0
  192. data/sig/examples/widget_layout_split/app.rbs +10 -0
  193. data/sig/examples/widget_line_gauge_demo/app.rbs +11 -0
  194. data/sig/examples/widget_list_demo/app.rbs +12 -0
  195. data/sig/examples/widget_list_styles/app.rbs +11 -0
  196. data/sig/examples/widget_popup_demo/app.rbs +11 -0
  197. data/sig/examples/widget_ratatui_logo_demo/app.rbs +11 -0
  198. data/sig/examples/widget_ratatui_mascot_demo/app.rbs +11 -0
  199. data/sig/examples/widget_rect/app.rbs +12 -0
  200. data/sig/examples/widget_render/app.rbs +10 -0
  201. data/sig/examples/widget_rich_text/app.rbs +11 -0
  202. data/sig/examples/widget_scroll_text/app.rbs +11 -0
  203. data/sig/examples/widget_scrollbar_demo/app.rbs +11 -0
  204. data/sig/examples/widget_sparkline_demo/app.rbs +10 -0
  205. data/{examples → sig/examples}/widget_style_colors/app.rbs +1 -1
  206. data/sig/examples/widget_table_flex/app.rbs +11 -0
  207. data/sig/ratatui_ruby/frame.rbs +9 -0
  208. data/sig/ratatui_ruby/ratatui_ruby.rbs +3 -2
  209. data/sig/ratatui_ruby/schema/draw.rbs +4 -0
  210. data/sig/ratatui_ruby/schema/layout.rbs +1 -1
  211. data/sig/ratatui_ruby/session.rbs +94 -0
  212. data/tasks/autodoc/inventory.rb +61 -0
  213. data/tasks/autodoc/member.rb +56 -0
  214. data/tasks/autodoc/name.rb +19 -0
  215. data/tasks/autodoc/notice.rb +26 -0
  216. data/tasks/autodoc/rbs.rb +38 -0
  217. data/tasks/autodoc/rdoc.rb +45 -0
  218. data/tasks/autodoc.rake +47 -0
  219. data/tasks/bump/history.rb +2 -2
  220. data/tasks/doc.rake +600 -6
  221. data/tasks/example_viewer.html.erb +172 -0
  222. data/tasks/lint.rake +8 -4
  223. data/tasks/resources/index.html.erb +6 -0
  224. data/tasks/sourcehut.rake +4 -4
  225. data/tasks/terminal_preview/app_screenshot.rb +1 -3
  226. data/tasks/terminal_preview/crash_report.rb +7 -9
  227. data/tasks/terminal_preview/launcher_script.rb +4 -6
  228. data/tasks/terminal_preview/preview_collection.rb +4 -6
  229. data/tasks/terminal_preview/safety_confirmation.rb +3 -5
  230. data/tasks/terminal_preview/saved_screenshot.rb +7 -9
  231. data/tasks/terminal_preview/terminal_window.rb +7 -9
  232. data/tasks/test.rake +1 -1
  233. data/tasks/website/index_page.rb +3 -3
  234. data/tasks/website/version.rb +10 -10
  235. data/tasks/website/version_menu.rb +10 -12
  236. data/tasks/website/versioned_documentation.rb +49 -17
  237. data/tasks/website/website.rb +6 -8
  238. data/tasks/website.rake +4 -4
  239. metadata +156 -125
  240. data/LICENSES/BSD-2-Clause.txt +0 -9
  241. data/doc/contributors/better_dx.md +0 -543
  242. data/doc/contributors/example_analysis.md +0 -82
  243. data/doc/images/all_events.png +0 -0
  244. data/doc/images/block_padding.png +0 -0
  245. data/doc/images/block_titles.png +0 -0
  246. data/doc/images/box_demo.png +0 -0
  247. data/doc/images/calendar_demo.png +0 -0
  248. data/doc/images/cell_demo.png +0 -0
  249. data/doc/images/chart_demo.png +0 -0
  250. data/doc/images/flex_layout.png +0 -0
  251. data/doc/images/gauge_demo.png +0 -0
  252. data/doc/images/line_gauge_demo.png +0 -0
  253. data/doc/images/list_demo.png +0 -0
  254. data/doc/images/readme_usage.png +0 -0
  255. data/doc/images/scrollbar_demo.png +0 -0
  256. data/doc/images/sparkline_demo.png +0 -0
  257. data/doc/images/table_flex.png +0 -0
  258. data/examples/all_events/app.rb +0 -169
  259. data/examples/all_events/app.rbs +0 -7
  260. data/examples/all_events/test_app.rb +0 -139
  261. data/examples/analytics/app.rb +0 -258
  262. data/examples/analytics/app.rbs +0 -7
  263. data/examples/analytics/test_app.rb +0 -132
  264. data/examples/block_padding/app.rbs +0 -7
  265. data/examples/block_padding/test_app.rb +0 -31
  266. data/examples/block_titles/app.rbs +0 -7
  267. data/examples/block_titles/test_app.rb +0 -34
  268. data/examples/box_demo/app.rbs +0 -7
  269. data/examples/box_demo/test_app.rb +0 -88
  270. data/examples/calendar_demo/app.rb +0 -101
  271. data/examples/calendar_demo/app.rbs +0 -7
  272. data/examples/calendar_demo/test_app.rb +0 -108
  273. data/examples/cell_demo/app.rb +0 -108
  274. data/examples/cell_demo/app.rbs +0 -7
  275. data/examples/cell_demo/test_app.rb +0 -36
  276. data/examples/chart_demo/app.rb +0 -203
  277. data/examples/chart_demo/app.rbs +0 -7
  278. data/examples/chart_demo/test_app.rb +0 -102
  279. data/examples/custom_widget/app.rb +0 -51
  280. data/examples/custom_widget/app.rbs +0 -7
  281. data/examples/custom_widget/test_app.rb +0 -30
  282. data/examples/flex_layout/app.rb +0 -156
  283. data/examples/flex_layout/app.rbs +0 -7
  284. data/examples/flex_layout/test_app.rb +0 -65
  285. data/examples/gauge_demo/app.rb +0 -182
  286. data/examples/gauge_demo/test_app.rb +0 -120
  287. data/examples/hit_test/app.rb +0 -175
  288. data/examples/hit_test/app.rbs +0 -7
  289. data/examples/hit_test/test_app.rb +0 -102
  290. data/examples/line_gauge_demo/app.rb +0 -190
  291. data/examples/line_gauge_demo/app.rbs +0 -7
  292. data/examples/line_gauge_demo/test_app.rb +0 -129
  293. data/examples/list_demo/app.rb +0 -253
  294. data/examples/list_demo/test_app.rb +0 -237
  295. data/examples/list_styles/app.rb +0 -140
  296. data/examples/list_styles/app.rbs +0 -7
  297. data/examples/list_styles/test_app.rb +0 -157
  298. data/examples/login_form/app.rbs +0 -7
  299. data/examples/login_form/test_app.rb +0 -51
  300. data/examples/map_demo/app.rbs +0 -7
  301. data/examples/map_demo/test_app.rb +0 -149
  302. data/examples/mouse_events/app.rb +0 -97
  303. data/examples/mouse_events/app.rbs +0 -7
  304. data/examples/mouse_events/test_app.rb +0 -53
  305. data/examples/popup_demo/app.rb +0 -103
  306. data/examples/popup_demo/app.rbs +0 -7
  307. data/examples/popup_demo/test_app.rb +0 -54
  308. data/examples/quickstart_dsl/app.rbs +0 -7
  309. data/examples/quickstart_dsl/test_app.rb +0 -29
  310. data/examples/quickstart_lifecycle/app.rbs +0 -7
  311. data/examples/quickstart_lifecycle/test_app.rb +0 -29
  312. data/examples/ratatui_logo_demo/app.rb +0 -79
  313. data/examples/ratatui_logo_demo/app.rbs +0 -7
  314. data/examples/ratatui_logo_demo/test_app.rb +0 -51
  315. data/examples/ratatui_mascot_demo/app.rb +0 -84
  316. data/examples/ratatui_mascot_demo/app.rbs +0 -7
  317. data/examples/ratatui_mascot_demo/test_app.rb +0 -47
  318. data/examples/readme_usage/app.rb +0 -29
  319. data/examples/readme_usage/app.rbs +0 -7
  320. data/examples/readme_usage/test_app.rb +0 -29
  321. data/examples/rich_text/app.rb +0 -141
  322. data/examples/rich_text/app.rbs +0 -7
  323. data/examples/rich_text/test_app.rb +0 -166
  324. data/examples/scroll_text/app.rb +0 -103
  325. data/examples/scroll_text/app.rbs +0 -7
  326. data/examples/scroll_text/test_app.rb +0 -110
  327. data/examples/scrollbar_demo/app.rb +0 -143
  328. data/examples/scrollbar_demo/app.rbs +0 -7
  329. data/examples/scrollbar_demo/test_app.rb +0 -77
  330. data/examples/sparkline_demo/app.rb +0 -240
  331. data/examples/sparkline_demo/test_app.rb +0 -107
  332. data/examples/table_flex/app.rb +0 -65
  333. data/examples/table_flex/app.rbs +0 -7
  334. data/examples/table_flex/test_app.rb +0 -36
  335. data/examples/table_select/app.rbs +0 -7
  336. data/examples/table_select/test_app.rb +0 -180
  337. data/examples/widget_style_colors/test_app.rb +0 -48
  338. /data/doc/images/{analytics.png → app_analytics.png} +0 -0
  339. /data/doc/images/{custom_widget.png → app_custom_widget.png} +0 -0
  340. /data/doc/images/{login_form.png → app_login_form.png} +0 -0
  341. /data/doc/images/{map_demo.png → app_map_demo.png} +0 -0
  342. /data/doc/images/{mouse_events.png → app_mouse_events.png} +0 -0
  343. /data/doc/images/{table_select.png → app_table_select.png} +0 -0
  344. /data/doc/images/{quickstart_dsl.png → verify_quickstart_dsl.png} +0 -0
  345. /data/doc/images/{ratatui_logo_demo.png → verify_quickstart_layout.png} +0 -0
  346. /data/doc/images/{quickstart_lifecycle.png → verify_quickstart_lifecycle.png} +0 -0
  347. /data/doc/images/{list_styles.png → widget_list_styles.png} +0 -0
  348. /data/doc/images/{popup_demo.png → widget_popup_demo.png} +0 -0
  349. /data/doc/images/{hit_test.png → widget_rect.png} +0 -0
  350. /data/doc/images/{rich_text.png → widget_rich_text.png} +0 -0
  351. /data/doc/images/{scroll_text.png → widget_scroll_text.png} +0 -0
@@ -1,149 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: AGPL-3.0-or-later
5
-
6
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
- require "ratatui_ruby"
8
- require "ratatui_ruby/test_helper"
9
- require "minitest/autorun"
10
- require "minitest/mock"
11
- require_relative "app"
12
-
13
- class TestMapDemoApp < Minitest::Test
14
- include RatatuiRuby::TestHelper
15
-
16
- def setup
17
- @app = MapDemoApp.new
18
- end
19
-
20
- def test_map_demo_renders
21
- with_test_terminal do
22
- # Queue events: turn off labels so buffer matches original, then quit
23
- inject_keys("l", "q")
24
-
25
- # Stub sleep to speed up test
26
- @app.stub :sleep, nil do
27
- @app.run
28
- end
29
-
30
- # Verify the buffer content reflects the rendered map (with labels off)
31
- expected_buffer = [
32
- "┌World Map ['b' bg, 'm' marker: braille, 'l' labels: off]──────────────────────┐",
33
- "│ ⣀⢀⣀⣀⡀ ⢀⣀⡀ ⡀ │",
34
- "│ ⢠⣤⣰⣦⣶⣶⣿⣭⣿⣣⠶⠶⣿⣉⣉⠉⠉⠁ ⠁⠉⢽⠎⠁ ⠲⠶⠶⠖ ⠐⠛⢃⡀⣀⢤ ⢀⣐⣋⣷⠶⡤⣀ ⣀⡀⣀⡀ │",
35
- "│⢖⡀⡀⣤⡖⠒⠒⠤⠤⠤⠤⠶⠿⠿⣿⣹⢿⣿⣿⢿⣭⣽⣿⡒⣦⣀⠘⣷⠄ ⢀⡀⢼⣏⢀ ⡠⠤⠒⠶⡤⢀⣄⡀⢻⠯⠤⢾⣻⡗⠛⠉ ⠈⠉⠈⠈⠙⠒⠚⠋ ⠒⠐⠦⠤⠤⠤⠶│",
36
- "│⠉⠉⠻⣿⣃⣀⣤⡤⣄⣀⡀ ⢠⠒⠛⠳⡟⠳⣿⣏ ⠙⠦⠴⠋⠁ ⠈⠛⠋⠁⢀⡀ ⣖⡉⢰⢾⣥⡄⠙⠉⠁ ⠈ ⢀⣀⣀⡠⣤⣦⢤⠤⠛│",
37
- "│ ⠒⠛⠉⠁ ⠿⣄⡀ ⠉⠓⢖⠎ ⢀⣘⣲⡄ ⠰⣾⣟⣄⠼⠛⠟⠚⠁ ⠺⣶ ⢪⠜⠁ │",
38
- "│ ⠈⡟ ⢸⠭⠿⠛⠛ ⢀⡤⣿⢀⣠⣴⣆⡀⢀⣴⣶⢆ ⡶⣆ ⢀⣀⡔⣽⡅ │",
39
- "│ ⠳⣀ ⢀⣺⠉ ⠘⣧⢴⠧⠼⡿⠟⠻⣿⢭⣬⠉ ⠸⠿ ⢺⠟⣿⣠⣶⡟ │",
40
- "│ ⠘⢿⣄ ⡔⠒⠒⣿⡄ ⢀⡼ ⠈⠙⠋⠉⠛⣿⡀ ⢶⣤⣄⣀⡀ ⢠⡇⠈⠋ │",
41
- "│ ⠐⠦ ⠈⠉⢧⣘⢆⣴⡞⠛⣷⣤⣄ ⣯ ⣸⣷⡊⠉⣉⡽ ⠙⢲ ⢀⡴⠻⣄ ⢰⣶⠚⢙⡁ │",
42
- "│ ⠈⠉⠛⢯⣇⣠⣴⢤⣤⡀ ⢧⡀ ⡠⠔⠊ ⠙⠷⢮⠅ ⠈⣇⣏ ⠉⣷⢄⠵ ⣸⣷⡄ │",
43
- "│ ⢉⡇ ⠙⠲⡄ ⠙⠒⢒⣊⡲⡔⠉ ⣀⠎ ⠈⠋ ⠰⡿⡆⣠⠔⣗⣙⣣ │",
44
- "│ ⢼ ⠉⠓⠲⣄ ⠈⠁⠈⢢ ⡼⠁ ⠘⢽⣝⣒⣻⡯⡛⢻⣮⢒⣦⡶⣄⡀ │",
45
- "│⡀ ⠈⢢⡀ ⢰⠃ ⢸ ⢹⢀⣴ ⠉⠉⣙⣥⠖⣎⣽⡌⠃ ⠙⢀⡀ ⢀│",
46
- "│⠁ ⢸ ⢀⣀⠏ ⠸⡄ ⣲⠁⡝⡞ ⣤⠖⠋ ⠈⠁⠑⣆ ⠶⠁ ⠉│",
47
- "│ ⢸ ⢀⠞ ⢳ ⡰⠃ ⠉⠁ ⢹ ⢀⣀⣀⢀ ⢸⠆ │",
48
- "│ ⡎⢀⣠⠽⠉ ⠈⠉⠉ ⠈⠉⠉ ⠈⠛⠦⣤⠎ ⣷⡄│",
49
- "│ ⢸⠇⢴⠁ ⢀⡀ ⠛ ⠰⠾⠋ │",
50
- "│ ⠘⠶⠧⠐⠛ ⠈⠁ │",
51
- "│ ⢀⣠⡤ ⣀⡀ ⡀ ⣀ ⡀ │",
52
- "│ ⢀⣀⣀⣀⣀⣀⡀⢠⣤⣄⣀⣀⣀⣠⣴⡿⢳ ⣀⡤⠤⠤⠤⠔⠶⠖⠲⠤⠒⠒⠒⠋⠉⠁⠉⠉⠹⠶⠒⠋⠉⠉⠉⠉⠈⠉⠈⠉⠉⠉⠉⠉⠉⠉⠒⠒⠲⢤⣤ │",
53
- "│ ⠰⠶⣶⣶⠏⠉⠉ ⠉ ⠈⠉⠉⠁ ⠶⢞⣩⣥⡄⣤⣶⣶⣀⣶⡶⠉⠉⠉ ⣠⣿ │",
54
- "│⠉⠉⠉⠉⠒⠘⠙⠓⠃ ⠉ ⠈⠁⠉⠉│",
55
- "└──────────────────────────────────────────────────────────────────────────────┘",
56
- ]
57
-
58
- expected_buffer.each_with_index do |line, i|
59
- assert_equal line, buffer_content[i], "Line #{i} should match"
60
- end
61
-
62
- # Verify the background color is set on the view (Unit test of the view method)
63
- view = @app.view(0.0, :braille, nil)
64
- assert_nil view.background_color
65
-
66
- # Verify labels are included in the shapes (default show_labels: true)
67
- label_shapes = view.shapes.select { |s| s.is_a?(RatatuiRuby::Shape::Label) }
68
- assert_equal 5, label_shapes.size, "Should have 5 city labels"
69
- assert label_shapes.any? { |l| l.text == "London" }, "Should have London label"
70
- assert label_shapes.any? { |l| l.text == "Tokyo" }, "Should have Tokyo label"
71
- end
72
- end
73
-
74
- def test_labels_visible
75
- with_test_terminal do
76
- # Don't toggle labels - they're on by default
77
- inject_keys("q")
78
- @app.stub :sleep, nil do
79
- @app.run
80
- end
81
- # Labels should be visible - check for a city name in the buffer
82
- buffer_text = buffer_content.join
83
- assert_includes buffer_text, "London", "London label should be visible"
84
- end
85
- end
86
-
87
- def test_labels_toggle
88
- with_test_terminal do
89
- inject_keys("l", "q")
90
- @app.stub :sleep, nil do
91
- @app.run
92
- end
93
- # After pressing 'l', labels should be off - check title
94
- assert_includes buffer_content[0], "labels: off"
95
- end
96
- end
97
-
98
- def test_background_default
99
- with_test_terminal(timeout: 5) do
100
- inject_keys("q")
101
- @app.stub :sleep, nil do
102
- @app.run
103
- end
104
- # View is roughly at (1,1) to (18,8) inside borders. (10, 5) is safely inside.
105
- assert_cell_style(10, 5, bg: :black)
106
- end
107
- end
108
-
109
- def test_background_blue
110
- with_test_terminal(timeout: 5) do
111
- inject_keys("b", "q")
112
- @app.stub :sleep, nil do
113
- @app.run
114
- end
115
- assert_cell_style(10, 5, bg: :blue)
116
- end
117
- end
118
-
119
- def test_background_white
120
- with_test_terminal(timeout: 5) do
121
- inject_keys("b", "b", "q")
122
- @app.stub :sleep, nil do
123
- @app.run
124
- end
125
- assert_cell_style(10, 5, bg: :white)
126
- end
127
- end
128
-
129
- def test_background_transparent
130
- with_test_terminal(timeout: 5) do
131
- inject_keys("b", "b", "b", "q")
132
- @app.stub :sleep, nil do
133
- @app.run
134
- end
135
- # Transparent typically means no bg color set on the cell
136
- assert_cell_style(10, 5, bg: nil)
137
- end
138
- end
139
-
140
- def test_quit
141
- with_test_terminal do
142
- inject_key(:q)
143
-
144
- @app.stub :sleep, nil do
145
- @app.run
146
- end
147
- end
148
- end
149
- end
@@ -1,97 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: AGPL-3.0-or-later
5
-
6
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
- require "ratatui_ruby"
8
-
9
- class MouseEventsApp
10
- def initialize
11
- @message = "Waiting for Mouse... (q to quit)"
12
- @details = ""
13
- @color = "white"
14
- end
15
-
16
- def run
17
- RatatuiRuby.run do
18
- loop do
19
- render
20
- break if handle_input == :quit
21
- end
22
- end
23
- end
24
-
25
- private
26
-
27
- def render
28
- # Create a centered block with the mouse event details
29
- block = RatatuiRuby::Block.new(
30
- title: "Mouse Event Plumbing",
31
- borders: [:all],
32
- border_color: @color
33
- )
34
-
35
- content = RatatuiRuby::Paragraph.new(
36
- text: "#{@message}\n#{@details}",
37
- alignment: :center,
38
- block:
39
- )
40
-
41
- # Use a layout to center the content
42
- layout = RatatuiRuby::Layout.new(
43
- direction: :vertical,
44
- constraints: [
45
- RatatuiRuby::Constraint.percentage(25),
46
- RatatuiRuby::Constraint.percentage(50),
47
- RatatuiRuby::Constraint.percentage(25),
48
- ],
49
- children: [
50
- RatatuiRuby::Paragraph.new(text: ""),
51
- content,
52
- RatatuiRuby::Paragraph.new(text: ""),
53
- ]
54
- )
55
-
56
- RatatuiRuby.draw(layout)
57
- end
58
-
59
- def handle_input
60
- event = RatatuiRuby.poll_event
61
- return unless event
62
-
63
- case event
64
- in {type: :key, code: "q"} | {type: :key, code: "c", modifiers: ["ctrl"]}
65
- return :quit
66
- in type: :mouse, kind:, button:, x:, y:, modifiers:
67
- @color = "green"
68
- case kind
69
- when "down"
70
- @message = "#{button.capitalize} Click at [#{x}, #{y}]"
71
- @details = "Modifiers: #{modifiers.join(', ')}"
72
- when "up"
73
- @message = "#{button.capitalize} Release at [#{x}, #{y}]"
74
- @details = "Modifiers: #{modifiers.join(', ')}"
75
- when "drag"
76
- @message = "Dragging #{button.capitalize} Button at [#{x}, #{y}]"
77
- @details = "Modifiers: #{modifiers.join(', ')}"
78
- when "moved"
79
- @message = "Mouse Moved to [#{x}, #{y}]"
80
- @details = "Modifiers: #{modifiers.join(', ')}"
81
- when "scroll_down"
82
- @message = "Scrolled Down"
83
- @details = "Position: [#{x}, #{y}]"
84
- when "scroll_up"
85
- @message = "Scrolled Up"
86
- @details = "Position: [#{x}, #{y}]"
87
- else
88
- nil
89
- end
90
- else
91
- nil
92
- end
93
- nil
94
- end
95
- end
96
-
97
- MouseEventsApp.new.run if __FILE__ == $0
@@ -1,7 +0,0 @@
1
- class MouseEventsApp
2
- # @public
3
- def self.new: () -> MouseEventsApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: AGPL-3.0-or-later
5
-
6
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
- require "ratatui_ruby"
8
- require "ratatui_ruby/test_helper"
9
- require "minitest/autorun"
10
- require_relative "app"
11
-
12
- class TestMouseEvents < Minitest::Test
13
- include RatatuiRuby::TestHelper
14
-
15
- def setup
16
- @app = MouseEventsApp.new
17
- end
18
-
19
- def test_initial_render
20
- with_test_terminal do
21
- inject_key(:q)
22
- @app.run
23
-
24
- content = buffer_content.join("\n")
25
- assert_includes content, "Mouse Event Plumbing"
26
- assert_includes content, "Waiting for Mouse..."
27
- end
28
- end
29
-
30
- def test_mouse_click
31
- with_test_terminal do
32
- # Click left button at 10, 5
33
- inject_event(RatatuiRuby::Event::Mouse.new(kind: "down", button: "left", x: 10, y: 5))
34
- inject_key(:q)
35
- @app.run
36
-
37
- content = buffer_content.join("\n")
38
- assert_includes content, "Left Click at [10, 5]"
39
- end
40
- end
41
-
42
- def test_mouse_scroll
43
- with_test_terminal do
44
- inject_event(RatatuiRuby::Event::Mouse.new(kind: "scroll_down", button: "none", x: 20, y: 15))
45
- inject_key(:q)
46
- @app.run
47
-
48
- content = buffer_content.join("\n")
49
- assert_includes content, "Scrolled Down"
50
- assert_includes content, "Position: [20, 15]"
51
- end
52
- end
53
- end
@@ -1,103 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: AGPL-3.0-or-later
5
-
6
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
- require "ratatui_ruby"
8
-
9
- # Popup Demo Example
10
- # Demonstrates the Clear widget for creating opaque popups.
11
-
12
- class PopupDemoApp
13
- def initialize
14
- @clear_enabled = false
15
- end
16
-
17
- def run
18
- RatatuiRuby.run do
19
- loop do
20
- render
21
- break if handle_input == :quit
22
- sleep 0.05
23
- end
24
- end
25
- end
26
-
27
- private
28
-
29
- def render
30
- # 1. Background: Loud Red Background
31
- # This demonstrates "Style Bleed" where the background color persists
32
- # unless explicitly cleared or overwritten.
33
- background = RatatuiRuby::Paragraph.new(
34
- text: "BACKGROUND RED " * 100,
35
- style: RatatuiRuby::Style.new(bg: :red, fg: :white),
36
- wrap: true
37
- )
38
-
39
- # 2. Popup Content: No specific background set (Style.default)
40
- # Without Clear, this will "inherit" the red background from underneath.
41
- popup_text = if @clear_enabled
42
- "✓ Clear is ENABLED\n\nResets background to default\n(Usually Black/Transparent)\n\nPress Space to toggle"
43
- else
44
- "✗ Clear is DISABLED\n\nStyle Bleed: Popup is RED!\n(Inherits background style)\n\nPress Space to toggle"
45
- end
46
-
47
- popup_content = RatatuiRuby::Paragraph.new(
48
- text: popup_text,
49
- alignment: :center,
50
- block: RatatuiRuby::Block.new(
51
- title: "Popup Demo (q to quit, space to toggle)",
52
- borders: [:all]
53
- )
54
- )
55
-
56
- # Build the UI with or without Clear
57
- if @clear_enabled
58
- # With Clear: Resets the style in the popup area before rendering content
59
- ui = RatatuiRuby::Overlay.new(
60
- layers: [
61
- background,
62
- RatatuiRuby::Center.new(
63
- child: RatatuiRuby::Overlay.new(
64
- layers: [
65
- RatatuiRuby::Clear.new,
66
- popup_content
67
- ]
68
- ),
69
- width_percent: 60,
70
- height_percent: 50
71
- )
72
- ]
73
- )
74
- else
75
- # Without Clear: Background style (RED) bleeds through the popup
76
- ui = RatatuiRuby::Overlay.new(
77
- layers: [
78
- background,
79
- RatatuiRuby::Center.new(
80
- child: popup_content,
81
- width_percent: 60,
82
- height_percent: 50
83
- )
84
- ]
85
- )
86
- end
87
-
88
- RatatuiRuby.draw(ui)
89
- end
90
-
91
- def handle_input
92
- case RatatuiRuby.poll_event
93
- in {type: :key, code: "q"} | {type: :key, code: "c", modifiers: ["ctrl"]}
94
- :quit
95
- in type: :key, code: " "
96
- @clear_enabled = !@clear_enabled
97
- else
98
- nil
99
- end
100
- end
101
- end
102
-
103
- PopupDemoApp.new.run if __FILE__ == $0
@@ -1,7 +0,0 @@
1
- class PopupDemoApp
2
- # @public
3
- def self.new: () -> PopupDemoApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: AGPL-3.0-or-later
5
-
6
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
- require "ratatui_ruby"
8
- require "ratatui_ruby/test_helper"
9
- require "minitest/autorun"
10
- require_relative "app"
11
-
12
- class TestPopupDemoApp < Minitest::Test
13
- include RatatuiRuby::TestHelper
14
-
15
- def setup
16
- @app = PopupDemoApp.new
17
- end
18
-
19
- def test_render_initial_state
20
- with_test_terminal do
21
- # Queue quit
22
- inject_key(:q)
23
-
24
- @app.run
25
-
26
- # Should have background text
27
- assert buffer_content.any? { |line| line.include?("BACKGROUND RED") }
28
-
29
- # Should have popup with "Clear is DISABLED" message
30
- assert buffer_content.any? { |line| line.include?("Clear is DISABLED") }
31
- assert buffer_content.any? { |line| line.include?("Style Bleed: Popup is RED!") }
32
- end
33
- end
34
-
35
- def test_toggle_clear
36
- with_test_terminal do
37
- # Toggle Clear on then quit
38
- inject_keys(" ", :q)
39
-
40
- @app.run
41
-
42
- assert buffer_content.any? { |line| line.include?("Clear is ENABLED") }
43
- assert buffer_content.any? { |line| line.include?("Resets background to default") }
44
- end
45
- end
46
-
47
- def test_quit
48
- with_test_terminal do
49
- inject_key(:q)
50
- @app.run
51
- # Success
52
- end
53
- end
54
- end
@@ -1,7 +0,0 @@
1
- class QuickstartDslApp
2
- # @public
3
- def self.new: () -> QuickstartDslApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: AGPL-3.0-or-later
5
-
6
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
- require "ratatui_ruby"
8
- require "ratatui_ruby/test_helper"
9
- require "minitest/autorun"
10
- require_relative "app"
11
-
12
- class TestQuickstartDsl < Minitest::Test
13
- include RatatuiRuby::TestHelper
14
-
15
- def setup
16
- @app = QuickstartDslApp.new
17
- end
18
-
19
- def test_render
20
- with_test_terminal do
21
- inject_key(:q)
22
- @app.run
23
-
24
- content = buffer_content.join("\n")
25
- assert_includes content, "Hello, Ratatui!"
26
- assert_includes content, "My Ruby TUI App"
27
- end
28
- end
29
- end
@@ -1,7 +0,0 @@
1
- class QuickstartLifecycleApp
2
- # @public
3
- def self.new: () -> QuickstartLifecycleApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: AGPL-3.0-or-later
5
-
6
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
- require "ratatui_ruby"
8
- require "ratatui_ruby/test_helper"
9
- require "minitest/autorun"
10
- require_relative "app"
11
-
12
- class TestQuickstartLifecycle < Minitest::Test
13
- include RatatuiRuby::TestHelper
14
-
15
- def setup
16
- @app = QuickstartLifecycleApp.new
17
- end
18
-
19
- def test_render
20
- with_test_terminal do
21
- inject_key(:q)
22
- @app.run
23
-
24
- content = buffer_content.join("\n")
25
- assert_includes content, "Hello, Ratatui!"
26
- assert_includes content, "My Ruby TUI App"
27
- end
28
- end
29
- end
@@ -1,79 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
4
- require "ratatui_ruby"
5
-
6
- class RatatuiLogoDemoApp
7
- def run
8
- RatatuiRuby.run do
9
- loop do
10
- render
11
- break if handle_input == :quit
12
- end
13
- end
14
- end
15
-
16
- private
17
-
18
- def render
19
- # Main content: The Logo
20
- logo = RatatuiRuby::RatatuiLogo.new
21
-
22
- # Center the logo using nested Layouts
23
- # Logo is roughly 47x8
24
- centered_logo = RatatuiRuby::Layout.new(
25
- direction: :vertical,
26
- flex: :center,
27
- constraints: [RatatuiRuby::Constraint.length(10)], # Height + margin
28
- children: [
29
- RatatuiRuby::Layout.new(
30
- direction: :horizontal,
31
- flex: :center,
32
- constraints: [RatatuiRuby::Constraint.length(50)], # Width + margin
33
- children: [logo]
34
- )
35
- ]
36
- )
37
-
38
- # Control Panel
39
- control_text = RatatuiRuby::Text::Line.new(spans: [
40
- RatatuiRuby::Text::Span.new(content: "q", style: RatatuiRuby::Style.new(modifiers: [:bold, :underlined])),
41
- RatatuiRuby::Text::Span.new(content: ": Quit")
42
- ])
43
-
44
- control_panel = RatatuiRuby::Paragraph.new(
45
- text: [control_text],
46
- block: RatatuiRuby::Block.new(
47
- title: "Controls",
48
- borders: [:top],
49
- style: RatatuiRuby::Style.new(fg: :dark_gray)
50
- )
51
- )
52
-
53
- # Layout
54
- layout = RatatuiRuby::Layout.new(
55
- direction: :vertical,
56
- constraints: [
57
- RatatuiRuby::Constraint.fill(1), # Fill remaining space
58
- RatatuiRuby::Constraint.length(3)
59
- ],
60
- children: [
61
- centered_logo,
62
- control_panel
63
- ]
64
- )
65
-
66
- RatatuiRuby.draw(layout)
67
- end
68
-
69
- def handle_input
70
- case RatatuiRuby.poll_event
71
- in {type: :key, code: "q"} | {type: :key, code: "c", modifiers: ["ctrl"]}
72
- :quit
73
- else
74
- nil
75
- end
76
- end
77
- end
78
-
79
- RatatuiLogoDemoApp.new.run if __FILE__ == $0
@@ -1,7 +0,0 @@
1
- class RatatuiLogoDemoApp
2
- # @public
3
- def self.new: () -> RatatuiLogoDemoApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
4
- require "ratatui_ruby"
5
- require "ratatui_ruby/test_helper"
6
- require "minitest/autorun"
7
- require_relative "app"
8
-
9
- class TestRatatuiLogoDemoApp < Minitest::Test
10
- include RatatuiRuby::TestHelper
11
-
12
- def setup
13
- @app = RatatuiLogoDemoApp.new
14
- end
15
-
16
- def test_initial_render
17
- with_test_terminal do
18
- inject_key(:q)
19
- @app.run
20
-
21
- content = buffer_content.join("\n")
22
-
23
- # Verify the logo is rendered.
24
- # The Ratatui logo usually contains "ratatui" text or similar shapes.
25
- # Since we can't easily match the exact ASCII art in a cross-platform/version way without brittleness,
26
- # we verify that the center of the screen is NOT empty.
27
-
28
- # The logo is centered.
29
- center_x = 40
30
- center_y = 10
31
- RatatuiRuby.get_cell_at(center_x, center_y)
32
-
33
- # It might not be exactly at 40, 10, but the logo is large enough that checking a region is safe.
34
- # Or simpler: verify the buffer contains non-whitespace lines in the middle.
35
-
36
- # Checking for "Controls" proves the app rendered.
37
- assert_includes content, "Controls"
38
- assert_includes content, "Quit"
39
-
40
- # Capture the "visual" presence of the logo by ensuring the buffer isn't just known text + whitespace.
41
- # The logo uses unicode block characters or specific letters.
42
- # Let's check for a known character from the logo if possible, or just significant non-whitespace count.
43
- refute_empty content.gsub(/\s+/, ""), "Buffer should not be empty"
44
-
45
- # We know the controls text. Let's ensure there is MORE text than just controls.
46
- controls_length = "Controls".length + "q: Quit".length + 20 # aprox buffer
47
- non_whitespace_count = content.gsub(/\s/, "").length
48
- assert non_whitespace_count > controls_length, "Should render more than just controls (the logo)"
49
- end
50
- end
51
- end