ratatui_ruby 0.4.0 → 0.6.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 (441) 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 +98 -176
  7. data/CHANGELOG.md +80 -6
  8. data/README.md +19 -7
  9. data/REUSE.toml +15 -0
  10. data/doc/application_architecture.md +179 -45
  11. data/doc/application_testing.md +80 -32
  12. data/doc/contributors/design/ruby_frontend.md +48 -8
  13. data/doc/contributors/design/rust_backend.md +1 -0
  14. data/doc/contributors/developing_examples.md +191 -48
  15. data/doc/contributors/documentation_style.md +7 -0
  16. data/doc/contributors/examples_audit/p1_high.md +21 -0
  17. data/doc/contributors/examples_audit/p2_moderate.md +81 -0
  18. data/doc/contributors/examples_audit.md +41 -0
  19. data/doc/contributors/index.md +2 -0
  20. data/doc/event_handling.md +21 -7
  21. data/doc/images/app_all_events.png +0 -0
  22. data/doc/images/app_color_picker.png +0 -0
  23. data/doc/images/app_login_form.png +0 -0
  24. data/doc/images/app_stateful_interaction.png +0 -0
  25. data/doc/images/verify_quickstart_dsl.png +0 -0
  26. data/doc/images/verify_quickstart_layout.png +0 -0
  27. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  28. data/doc/images/verify_readme_usage.png +0 -0
  29. data/doc/images/widget_barchart_demo.png +0 -0
  30. data/doc/images/widget_block_demo.png +0 -0
  31. data/doc/images/widget_box_demo.png +0 -0
  32. data/doc/images/widget_calendar_demo.png +0 -0
  33. data/doc/images/widget_canvas_demo.png +0 -0
  34. data/doc/images/widget_cell_demo.png +0 -0
  35. data/doc/images/widget_center_demo.png +0 -0
  36. data/doc/images/widget_chart_demo.png +0 -0
  37. data/doc/images/widget_gauge_demo.png +0 -0
  38. data/doc/images/widget_layout_split.png +0 -0
  39. data/doc/images/widget_line_gauge_demo.png +0 -0
  40. data/doc/images/widget_list_demo.png +0 -0
  41. data/doc/images/widget_overlay_demo.png +0 -0
  42. data/doc/images/widget_ratatui_logo_demo.png +0 -0
  43. data/doc/images/widget_ratatui_mascot_demo.png +0 -0
  44. data/doc/images/widget_render.png +0 -0
  45. data/doc/images/widget_rich_text.png +0 -0
  46. data/doc/images/widget_scroll_text.png +0 -0
  47. data/doc/images/widget_scrollbar_demo.png +0 -0
  48. data/doc/images/widget_sparkline_demo.png +0 -0
  49. data/doc/images/widget_style_colors.png +0 -0
  50. data/doc/images/widget_table_demo.png +0 -0
  51. data/doc/images/widget_table_flex.png +0 -0
  52. data/doc/images/widget_tabs_demo.png +0 -0
  53. data/doc/images/widget_text_width.png +0 -0
  54. data/doc/interactive_design.md +25 -30
  55. data/doc/quickstart.md +150 -130
  56. data/doc/terminal_limitations.md +92 -0
  57. data/examples/app_all_events/README.md +99 -0
  58. data/examples/app_all_events/app.rb +96 -0
  59. data/examples/app_all_events/model/app_model.rb +157 -0
  60. data/examples/app_all_events/model/event_color_cycle.rb +41 -0
  61. data/examples/app_all_events/model/event_entry.rb +92 -0
  62. data/examples/app_all_events/model/msg.rb +37 -0
  63. data/examples/app_all_events/model/timestamp.rb +54 -0
  64. data/examples/app_all_events/update.rb +73 -0
  65. data/examples/app_all_events/view/app_view.rb +78 -0
  66. data/examples/app_all_events/view/controls_view.rb +52 -0
  67. data/examples/app_all_events/view/counts_view.rb +59 -0
  68. data/examples/app_all_events/view/live_view.rb +70 -0
  69. data/examples/app_all_events/view/log_view.rb +55 -0
  70. data/examples/app_all_events/view.rb +7 -0
  71. data/examples/app_color_picker/README.md +134 -0
  72. data/examples/app_color_picker/app.rb +74 -0
  73. data/examples/app_color_picker/clipboard.rb +84 -0
  74. data/examples/app_color_picker/color.rb +191 -0
  75. data/examples/app_color_picker/controls.rb +90 -0
  76. data/examples/app_color_picker/copy_dialog.rb +166 -0
  77. data/examples/app_color_picker/export_pane.rb +126 -0
  78. data/examples/app_color_picker/harmony.rb +56 -0
  79. data/examples/app_color_picker/input.rb +174 -0
  80. data/examples/app_color_picker/main_container.rb +178 -0
  81. data/examples/app_color_picker/palette.rb +109 -0
  82. data/examples/app_login_form/README.md +47 -0
  83. data/examples/{login_form → app_login_form}/app.rb +38 -42
  84. data/examples/app_stateful_interaction/README.md +31 -0
  85. data/examples/app_stateful_interaction/app.rb +272 -0
  86. data/examples/timeout_demo.rb +43 -0
  87. data/examples/verify_quickstart_dsl/README.md +48 -0
  88. data/examples/{quickstart_dsl → verify_quickstart_dsl}/app.rb +17 -6
  89. data/examples/verify_quickstart_layout/README.md +71 -0
  90. data/examples/verify_quickstart_layout/app.rb +71 -0
  91. data/examples/verify_quickstart_lifecycle/README.md +56 -0
  92. data/examples/verify_quickstart_lifecycle/app.rb +54 -0
  93. data/examples/verify_readme_usage/README.md +43 -0
  94. data/examples/verify_readme_usage/app.rb +40 -0
  95. data/examples/widget_barchart_demo/README.md +49 -0
  96. data/examples/widget_barchart_demo/app.rb +238 -0
  97. data/examples/widget_block_demo/README.md +34 -0
  98. data/examples/widget_block_demo/app.rb +256 -0
  99. data/examples/widget_box_demo/README.md +45 -0
  100. data/examples/{box_demo → widget_box_demo}/app.rb +99 -65
  101. data/examples/widget_calendar_demo/README.md +39 -0
  102. data/examples/widget_calendar_demo/app.rb +109 -0
  103. data/examples/widget_canvas_demo/README.md +27 -0
  104. data/examples/widget_canvas_demo/app.rb +123 -0
  105. data/examples/widget_cell_demo/README.md +36 -0
  106. data/examples/widget_cell_demo/app.rb +111 -0
  107. data/examples/widget_center_demo/README.md +29 -0
  108. data/examples/widget_center_demo/app.rb +116 -0
  109. data/examples/widget_chart_demo/README.md +41 -0
  110. data/examples/widget_chart_demo/app.rb +218 -0
  111. data/examples/widget_gauge_demo/README.md +41 -0
  112. data/examples/widget_gauge_demo/app.rb +212 -0
  113. data/examples/widget_layout_split/README.md +44 -0
  114. data/examples/widget_layout_split/app.rb +246 -0
  115. data/examples/widget_line_gauge_demo/README.md +41 -0
  116. data/examples/widget_line_gauge_demo/app.rb +217 -0
  117. data/examples/widget_list_demo/README.md +49 -0
  118. data/examples/widget_list_demo/app.rb +366 -0
  119. data/examples/widget_map_demo/README.md +39 -0
  120. data/examples/{map_demo → widget_map_demo}/app.rb +24 -21
  121. data/examples/widget_overlay_demo/app.rb +248 -0
  122. data/examples/widget_popup_demo/README.md +36 -0
  123. data/examples/widget_popup_demo/app.rb +104 -0
  124. data/examples/widget_ratatui_logo_demo/README.md +34 -0
  125. data/examples/widget_ratatui_logo_demo/app.rb +103 -0
  126. data/examples/widget_ratatui_mascot_demo/README.md +34 -0
  127. data/examples/widget_ratatui_mascot_demo/app.rb +93 -0
  128. data/examples/widget_rect/README.md +38 -0
  129. data/examples/widget_rect/app.rb +205 -0
  130. data/examples/widget_render/README.md +37 -0
  131. data/examples/widget_render/app.rb +184 -0
  132. data/examples/widget_rich_text/README.md +35 -0
  133. data/examples/widget_rich_text/app.rb +166 -0
  134. data/examples/widget_scroll_text/README.md +37 -0
  135. data/examples/widget_scroll_text/app.rb +107 -0
  136. data/examples/widget_scrollbar_demo/README.md +37 -0
  137. data/examples/widget_scrollbar_demo/app.rb +153 -0
  138. data/examples/widget_sparkline_demo/README.md +42 -0
  139. data/examples/widget_sparkline_demo/app.rb +275 -0
  140. data/examples/widget_style_colors/README.md +34 -0
  141. data/examples/widget_style_colors/app.rb +19 -21
  142. data/examples/widget_table_demo/README.md +48 -0
  143. data/examples/widget_table_demo/app.rb +239 -0
  144. data/examples/widget_tabs_demo/README.md +41 -0
  145. data/examples/widget_tabs_demo/app.rb +181 -0
  146. data/examples/widget_text_width/README.md +35 -0
  147. data/examples/widget_text_width/app.rb +106 -0
  148. data/ext/ratatui_ruby/Cargo.lock +11 -4
  149. data/ext/ratatui_ruby/Cargo.toml +2 -1
  150. data/ext/ratatui_ruby/src/events.rs +359 -62
  151. data/ext/ratatui_ruby/src/frame.rs +227 -0
  152. data/ext/ratatui_ruby/src/lib.rs +110 -27
  153. data/ext/ratatui_ruby/src/rendering.rs +8 -4
  154. data/ext/ratatui_ruby/src/string_width.rs +101 -0
  155. data/ext/ratatui_ruby/src/style.rs +138 -57
  156. data/ext/ratatui_ruby/src/terminal.rs +42 -22
  157. data/ext/ratatui_ruby/src/text.rs +14 -7
  158. data/ext/ratatui_ruby/src/widgets/barchart.rs +74 -54
  159. data/ext/ratatui_ruby/src/widgets/block.rs +7 -6
  160. data/ext/ratatui_ruby/src/widgets/canvas.rs +21 -3
  161. data/ext/ratatui_ruby/src/widgets/chart.rs +20 -10
  162. data/ext/ratatui_ruby/src/widgets/gauge.rs +9 -2
  163. data/ext/ratatui_ruby/src/widgets/layout.rs +9 -4
  164. data/ext/ratatui_ruby/src/widgets/line_gauge.rs +9 -2
  165. data/ext/ratatui_ruby/src/widgets/list.rs +211 -12
  166. data/ext/ratatui_ruby/src/widgets/list_state.rs +137 -0
  167. data/ext/ratatui_ruby/src/widgets/mod.rs +3 -0
  168. data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
  169. data/ext/ratatui_ruby/src/widgets/paragraph.rs +1 -1
  170. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +19 -8
  171. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +17 -10
  172. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +97 -3
  173. data/ext/ratatui_ruby/src/widgets/scrollbar_state.rs +169 -0
  174. data/ext/ratatui_ruby/src/widgets/sparkline.rs +14 -11
  175. data/ext/ratatui_ruby/src/widgets/table.rs +121 -5
  176. data/ext/ratatui_ruby/src/widgets/table_state.rs +121 -0
  177. data/ext/ratatui_ruby/src/widgets/tabs.rs +11 -11
  178. data/lib/ratatui_ruby/cell.rb +7 -7
  179. data/lib/ratatui_ruby/event/key/character.rb +35 -0
  180. data/lib/ratatui_ruby/event/key/media.rb +44 -0
  181. data/lib/ratatui_ruby/event/key/modifier.rb +95 -0
  182. data/lib/ratatui_ruby/event/key/navigation.rb +55 -0
  183. data/lib/ratatui_ruby/event/key/system.rb +45 -0
  184. data/lib/ratatui_ruby/event/key.rb +112 -52
  185. data/lib/ratatui_ruby/event/mouse.rb +3 -3
  186. data/lib/ratatui_ruby/event/none.rb +43 -0
  187. data/lib/ratatui_ruby/event/paste.rb +1 -1
  188. data/lib/ratatui_ruby/event.rb +56 -4
  189. data/lib/ratatui_ruby/frame.rb +183 -0
  190. data/lib/ratatui_ruby/list_state.rb +88 -0
  191. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +13 -13
  192. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +1 -5
  193. data/lib/ratatui_ruby/schema/bar_chart.rb +217 -217
  194. data/lib/ratatui_ruby/schema/block.rb +163 -168
  195. data/lib/ratatui_ruby/schema/calendar.rb +66 -67
  196. data/lib/ratatui_ruby/schema/canvas.rb +63 -63
  197. data/lib/ratatui_ruby/schema/center.rb +46 -46
  198. data/lib/ratatui_ruby/schema/chart.rb +135 -143
  199. data/lib/ratatui_ruby/schema/clear.rb +42 -42
  200. data/lib/ratatui_ruby/schema/constraint.rb +76 -76
  201. data/lib/ratatui_ruby/schema/cursor.rb +30 -25
  202. data/lib/ratatui_ruby/schema/gauge.rb +54 -52
  203. data/lib/ratatui_ruby/schema/layout.rb +87 -87
  204. data/lib/ratatui_ruby/schema/line_gauge.rb +62 -62
  205. data/lib/ratatui_ruby/schema/list.rb +103 -80
  206. data/lib/ratatui_ruby/schema/list_item.rb +41 -0
  207. data/lib/ratatui_ruby/schema/overlay.rb +31 -31
  208. data/lib/ratatui_ruby/schema/paragraph.rb +80 -80
  209. data/lib/ratatui_ruby/schema/ratatui_logo.rb +10 -6
  210. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +10 -5
  211. data/lib/ratatui_ruby/schema/rect.rb +99 -56
  212. data/lib/ratatui_ruby/schema/scrollbar.rb +119 -119
  213. data/lib/ratatui_ruby/schema/shape/label.rb +1 -1
  214. data/lib/ratatui_ruby/schema/sparkline.rb +111 -110
  215. data/lib/ratatui_ruby/schema/style.rb +66 -46
  216. data/lib/ratatui_ruby/schema/table.rb +126 -115
  217. data/lib/ratatui_ruby/schema/tabs.rb +66 -67
  218. data/lib/ratatui_ruby/schema/text.rb +69 -1
  219. data/lib/ratatui_ruby/scrollbar_state.rb +112 -0
  220. data/lib/ratatui_ruby/session/autodoc.rb +482 -0
  221. data/lib/ratatui_ruby/session.rb +55 -23
  222. data/lib/ratatui_ruby/table_state.rb +90 -0
  223. data/lib/ratatui_ruby/test_helper/event_injection.rb +169 -0
  224. data/lib/ratatui_ruby/test_helper/snapshot.rb +390 -0
  225. data/lib/ratatui_ruby/test_helper/style_assertions.rb +351 -0
  226. data/lib/ratatui_ruby/test_helper/terminal.rb +127 -0
  227. data/lib/ratatui_ruby/test_helper/test_doubles.rb +68 -0
  228. data/lib/ratatui_ruby/test_helper.rb +66 -193
  229. data/lib/ratatui_ruby/version.rb +1 -1
  230. data/lib/ratatui_ruby.rb +100 -51
  231. data/{examples/sparkline_demo → sig/examples/app_all_events}/app.rbs +3 -2
  232. data/sig/examples/app_all_events/model/event_entry.rbs +16 -0
  233. data/sig/examples/app_all_events/model/events.rbs +15 -0
  234. data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
  235. data/sig/examples/app_all_events/view/app_view.rbs +8 -0
  236. data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
  237. data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
  238. data/sig/examples/app_all_events/view/live_view.rbs +6 -0
  239. data/sig/examples/app_all_events/view/log_view.rbs +6 -0
  240. data/sig/examples/app_all_events/view.rbs +8 -0
  241. data/sig/examples/app_all_events/view_state.rbs +15 -0
  242. data/{examples/list_demo → sig/examples/app_color_picker}/app.rbs +2 -2
  243. data/sig/examples/app_login_form/app.rbs +11 -0
  244. data/sig/examples/app_stateful_interaction/app.rbs +33 -0
  245. data/sig/examples/verify_quickstart_dsl/app.rbs +11 -0
  246. data/sig/examples/verify_quickstart_lifecycle/app.rbs +11 -0
  247. data/sig/examples/verify_readme_usage/app.rbs +11 -0
  248. data/sig/examples/widget_block_demo/app.rbs +32 -0
  249. data/sig/examples/widget_box_demo/app.rbs +11 -0
  250. data/sig/examples/widget_calendar_demo/app.rbs +11 -0
  251. data/sig/examples/widget_cell_demo/app.rbs +11 -0
  252. data/sig/examples/widget_chart_demo/app.rbs +11 -0
  253. data/{examples/gauge_demo → sig/examples/widget_gauge_demo}/app.rbs +4 -0
  254. data/sig/examples/widget_layout_split/app.rbs +10 -0
  255. data/sig/examples/widget_line_gauge_demo/app.rbs +11 -0
  256. data/sig/examples/widget_list_demo/app.rbs +12 -0
  257. data/sig/examples/widget_map_demo/app.rbs +11 -0
  258. data/sig/examples/widget_popup_demo/app.rbs +11 -0
  259. data/sig/examples/widget_ratatui_logo_demo/app.rbs +11 -0
  260. data/sig/examples/widget_ratatui_mascot_demo/app.rbs +11 -0
  261. data/sig/examples/widget_rect/app.rbs +12 -0
  262. data/sig/examples/widget_render/app.rbs +10 -0
  263. data/sig/examples/widget_rich_text/app.rbs +11 -0
  264. data/sig/examples/widget_scroll_text/app.rbs +11 -0
  265. data/sig/examples/widget_scrollbar_demo/app.rbs +11 -0
  266. data/sig/examples/widget_sparkline_demo/app.rbs +10 -0
  267. data/{examples → sig/examples}/widget_style_colors/app.rbs +1 -1
  268. data/sig/examples/widget_table_demo/app.rbs +11 -0
  269. data/sig/examples/widget_text_width/app.rbs +10 -0
  270. data/sig/ratatui_ruby/event.rbs +11 -1
  271. data/sig/ratatui_ruby/frame.rbs +11 -0
  272. data/sig/ratatui_ruby/list_state.rbs +13 -0
  273. data/sig/ratatui_ruby/ratatui_ruby.rbs +5 -4
  274. data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +3 -3
  275. data/sig/ratatui_ruby/schema/draw.rbs +4 -0
  276. data/sig/ratatui_ruby/schema/gauge.rbs +2 -2
  277. data/sig/ratatui_ruby/schema/layout.rbs +1 -1
  278. data/sig/ratatui_ruby/schema/line_gauge.rbs +2 -2
  279. data/sig/ratatui_ruby/schema/list.rbs +4 -2
  280. data/sig/ratatui_ruby/schema/list_item.rbs +10 -0
  281. data/sig/ratatui_ruby/schema/rect.rbs +3 -0
  282. data/sig/ratatui_ruby/schema/style.rbs +3 -3
  283. data/sig/ratatui_ruby/schema/table.rbs +3 -1
  284. data/sig/ratatui_ruby/schema/text.rbs +8 -6
  285. data/sig/ratatui_ruby/scrollbar_state.rbs +18 -0
  286. data/sig/ratatui_ruby/session.rbs +107 -0
  287. data/sig/ratatui_ruby/table_state.rbs +15 -0
  288. data/sig/ratatui_ruby/test_helper/event_injection.rbs +16 -0
  289. data/sig/ratatui_ruby/test_helper/snapshot.rbs +12 -0
  290. data/sig/ratatui_ruby/test_helper/style_assertions.rbs +64 -0
  291. data/sig/ratatui_ruby/test_helper/terminal.rbs +14 -0
  292. data/sig/ratatui_ruby/test_helper/test_doubles.rbs +22 -0
  293. data/sig/ratatui_ruby/test_helper.rbs +5 -4
  294. data/tasks/autodoc/examples.rb +79 -0
  295. data/tasks/autodoc/inventory.rb +63 -0
  296. data/tasks/autodoc/member.rb +56 -0
  297. data/tasks/autodoc/name.rb +19 -0
  298. data/tasks/autodoc/notice.rb +26 -0
  299. data/tasks/autodoc/rbs.rb +38 -0
  300. data/tasks/autodoc/rdoc.rb +45 -0
  301. data/tasks/autodoc.rake +53 -0
  302. data/tasks/bump/changelog.rb +3 -3
  303. data/tasks/bump/history.rb +2 -2
  304. data/tasks/bump/links.rb +67 -0
  305. data/tasks/doc.rake +600 -6
  306. data/tasks/example_viewer.html.erb +172 -0
  307. data/tasks/lint.rake +8 -4
  308. data/tasks/resources/index.html.erb +6 -0
  309. data/tasks/sourcehut.rake +70 -30
  310. data/tasks/terminal_preview/app_screenshot.rb +14 -6
  311. data/tasks/terminal_preview/crash_report.rb +7 -9
  312. data/tasks/terminal_preview/launcher_script.rb +4 -6
  313. data/tasks/terminal_preview/preview_collection.rb +4 -6
  314. data/tasks/terminal_preview/safety_confirmation.rb +3 -5
  315. data/tasks/terminal_preview/saved_screenshot.rb +10 -11
  316. data/tasks/terminal_preview/terminal_window.rb +7 -9
  317. data/tasks/test.rake +1 -1
  318. data/tasks/website/index_page.rb +3 -3
  319. data/tasks/website/version.rb +10 -10
  320. data/tasks/website/version_menu.rb +10 -12
  321. data/tasks/website/versioned_documentation.rb +49 -17
  322. data/tasks/website/website.rb +6 -8
  323. data/tasks/website.rake +4 -4
  324. metadata +232 -127
  325. data/LICENSES/BSD-2-Clause.txt +0 -9
  326. data/doc/contributors/better_dx.md +0 -543
  327. data/doc/contributors/example_analysis.md +0 -82
  328. data/doc/images/all_events.png +0 -0
  329. data/doc/images/block_padding.png +0 -0
  330. data/doc/images/block_titles.png +0 -0
  331. data/doc/images/box_demo.png +0 -0
  332. data/doc/images/calendar_demo.png +0 -0
  333. data/doc/images/cell_demo.png +0 -0
  334. data/doc/images/chart_demo.png +0 -0
  335. data/doc/images/flex_layout.png +0 -0
  336. data/doc/images/gauge_demo.png +0 -0
  337. data/doc/images/line_gauge_demo.png +0 -0
  338. data/doc/images/list_demo.png +0 -0
  339. data/doc/images/list_styles.png +0 -0
  340. data/doc/images/login_form.png +0 -0
  341. data/doc/images/quickstart_dsl.png +0 -0
  342. data/doc/images/quickstart_lifecycle.png +0 -0
  343. data/doc/images/readme_usage.png +0 -0
  344. data/doc/images/rich_text.png +0 -0
  345. data/doc/images/scroll_text.png +0 -0
  346. data/doc/images/scrollbar_demo.png +0 -0
  347. data/doc/images/sparkline_demo.png +0 -0
  348. data/doc/images/table_flex.png +0 -0
  349. data/doc/images/table_select.png +0 -0
  350. data/examples/all_events/app.rb +0 -169
  351. data/examples/all_events/app.rbs +0 -7
  352. data/examples/all_events/test_app.rb +0 -139
  353. data/examples/analytics/app.rb +0 -258
  354. data/examples/analytics/app.rbs +0 -7
  355. data/examples/analytics/test_app.rb +0 -132
  356. data/examples/block_padding/app.rb +0 -63
  357. data/examples/block_padding/app.rbs +0 -7
  358. data/examples/block_padding/test_app.rb +0 -31
  359. data/examples/block_titles/app.rb +0 -61
  360. data/examples/block_titles/app.rbs +0 -7
  361. data/examples/block_titles/test_app.rb +0 -34
  362. data/examples/box_demo/app.rbs +0 -7
  363. data/examples/box_demo/test_app.rb +0 -88
  364. data/examples/calendar_demo/app.rb +0 -101
  365. data/examples/calendar_demo/app.rbs +0 -7
  366. data/examples/calendar_demo/test_app.rb +0 -108
  367. data/examples/cell_demo/app.rb +0 -108
  368. data/examples/cell_demo/app.rbs +0 -7
  369. data/examples/cell_demo/test_app.rb +0 -36
  370. data/examples/chart_demo/app.rb +0 -203
  371. data/examples/chart_demo/app.rbs +0 -7
  372. data/examples/chart_demo/test_app.rb +0 -102
  373. data/examples/custom_widget/app.rb +0 -51
  374. data/examples/custom_widget/app.rbs +0 -7
  375. data/examples/custom_widget/test_app.rb +0 -30
  376. data/examples/flex_layout/app.rb +0 -156
  377. data/examples/flex_layout/app.rbs +0 -7
  378. data/examples/flex_layout/test_app.rb +0 -65
  379. data/examples/gauge_demo/app.rb +0 -182
  380. data/examples/gauge_demo/test_app.rb +0 -120
  381. data/examples/hit_test/app.rb +0 -175
  382. data/examples/hit_test/app.rbs +0 -7
  383. data/examples/hit_test/test_app.rb +0 -102
  384. data/examples/line_gauge_demo/app.rb +0 -190
  385. data/examples/line_gauge_demo/app.rbs +0 -7
  386. data/examples/line_gauge_demo/test_app.rb +0 -129
  387. data/examples/list_demo/app.rb +0 -253
  388. data/examples/list_demo/test_app.rb +0 -237
  389. data/examples/list_styles/app.rb +0 -140
  390. data/examples/list_styles/app.rbs +0 -7
  391. data/examples/list_styles/test_app.rb +0 -157
  392. data/examples/login_form/app.rbs +0 -7
  393. data/examples/login_form/test_app.rb +0 -51
  394. data/examples/map_demo/app.rbs +0 -7
  395. data/examples/map_demo/test_app.rb +0 -149
  396. data/examples/mouse_events/app.rb +0 -97
  397. data/examples/mouse_events/app.rbs +0 -7
  398. data/examples/mouse_events/test_app.rb +0 -53
  399. data/examples/popup_demo/app.rb +0 -103
  400. data/examples/popup_demo/app.rbs +0 -7
  401. data/examples/popup_demo/test_app.rb +0 -54
  402. data/examples/quickstart_dsl/app.rbs +0 -7
  403. data/examples/quickstart_dsl/test_app.rb +0 -29
  404. data/examples/quickstart_lifecycle/app.rb +0 -39
  405. data/examples/quickstart_lifecycle/app.rbs +0 -7
  406. data/examples/quickstart_lifecycle/test_app.rb +0 -29
  407. data/examples/ratatui_logo_demo/app.rb +0 -79
  408. data/examples/ratatui_logo_demo/app.rbs +0 -7
  409. data/examples/ratatui_logo_demo/test_app.rb +0 -51
  410. data/examples/ratatui_mascot_demo/app.rb +0 -84
  411. data/examples/ratatui_mascot_demo/app.rbs +0 -7
  412. data/examples/ratatui_mascot_demo/test_app.rb +0 -47
  413. data/examples/readme_usage/app.rb +0 -29
  414. data/examples/readme_usage/app.rbs +0 -7
  415. data/examples/readme_usage/test_app.rb +0 -29
  416. data/examples/rich_text/app.rb +0 -141
  417. data/examples/rich_text/app.rbs +0 -7
  418. data/examples/rich_text/test_app.rb +0 -166
  419. data/examples/scroll_text/app.rb +0 -103
  420. data/examples/scroll_text/app.rbs +0 -7
  421. data/examples/scroll_text/test_app.rb +0 -110
  422. data/examples/scrollbar_demo/app.rb +0 -143
  423. data/examples/scrollbar_demo/app.rbs +0 -7
  424. data/examples/scrollbar_demo/test_app.rb +0 -77
  425. data/examples/sparkline_demo/app.rb +0 -240
  426. data/examples/sparkline_demo/test_app.rb +0 -107
  427. data/examples/table_flex/app.rb +0 -65
  428. data/examples/table_flex/app.rbs +0 -7
  429. data/examples/table_flex/test_app.rb +0 -36
  430. data/examples/table_select/app.rb +0 -198
  431. data/examples/table_select/app.rbs +0 -7
  432. data/examples/table_select/test_app.rb +0 -180
  433. data/examples/widget_style_colors/test_app.rb +0 -48
  434. data/tasks/bump/comparison_links.rb +0 -41
  435. /data/doc/images/{analytics.png → app_analytics.png} +0 -0
  436. /data/doc/images/{custom_widget.png → app_custom_widget.png} +0 -0
  437. /data/doc/images/{mouse_events.png → app_mouse_events.png} +0 -0
  438. /data/doc/images/{map_demo.png → widget_map_demo.png} +0 -0
  439. /data/doc/images/{popup_demo.png → widget_popup_demo.png} +0 -0
  440. /data/doc/images/{hit_test.png → widget_rect.png} +0 -0
  441. /data/{doc/images/ratatui_logo_demo.png → exe/.gitkeep} +0 -0
@@ -1,132 +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 TestAnalytics < Minitest::Test
13
- include RatatuiRuby::TestHelper
14
-
15
- def setup
16
- @app = AnalyticsApp.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
- # Check Tabs
27
- assert buffer_content.any? { |line| line.include?("Revenue") }
28
- assert buffer_content.any? { |line| line.include?("Traffic") }
29
- assert buffer_content.any? { |line| line.include?("Errors") }
30
-
31
- # Check initial selected tab content
32
- assert buffer_content.any? { |line| line.include?("Analytics: Revenue") }
33
-
34
- # Check help text visibility (join to handle potential wrapping)
35
- content_str = buffer_content.join("\n")
36
- assert_includes content_str, "q: Quit"
37
- end
38
- end
39
-
40
- def test_navigation_right
41
- with_test_terminal do
42
- inject_keys(:right, :q)
43
-
44
- @app.run
45
-
46
- assert buffer_content.any? { |line| line.include?("Analytics: Traffic") }
47
- end
48
- end
49
-
50
- def test_navigation_left
51
- with_test_terminal do
52
- # Move right to Traffic
53
- inject_keys(:a, :b, :c)
54
-
55
- # Then queue quit
56
- inject_key(:q)
57
-
58
- @app.run
59
-
60
- assert buffer_content.any? { |line| line.include?("Analytics: Revenue") }
61
- end
62
- end
63
-
64
- def test_quit
65
- with_test_terminal do
66
- inject_key(:q)
67
- @app.run
68
- # Success if returns
69
- end
70
- end
71
-
72
- def test_switch_divider
73
- with_test_terminal do
74
- # Switch divider (d) then quit (q)
75
- inject_keys(:d, :q)
76
- @app.run
77
-
78
- # Default is " | ", next is " • "
79
- assert buffer_content.any? { |line| line.include?(" • ") }
80
- end
81
- end
82
-
83
- def test_switch_style
84
- with_test_terminal do
85
- # Switch style (space) then quit (q)
86
- inject_keys(:" ", :q)
87
- @app.run
88
-
89
- # Verify it runs without error.
90
- # Style visual verification is limited with simple string buffer checks,
91
- # but this ensures the event handling works.
92
- end
93
- end
94
-
95
- def test_padding_controls
96
- with_test_terminal do
97
- # Increase padding_left (l) and padding_right (k) then quit
98
- inject_keys(:l, :l, :k, :k, :k, :q)
99
- @app.run
100
-
101
- # Verify that padding values are shown in status with hotkeys
102
- # Use join to match even if wrapped or if "Pad Left" logic changed
103
- content_str = buffer_content.join("\n")
104
- assert_includes content_str, "h/l: Pad Left (2)"
105
- assert_includes content_str, "j/k: Pad Right (3)"
106
- end
107
- end
108
-
109
- def test_styling_controls
110
- with_test_terminal do
111
- # Cycle label style (x) and value style (z)
112
- inject_keys(:x, :z, :z, :q)
113
- @app.run
114
- # Verify expected content
115
- content = buffer_content.join
116
- assert_includes content, "Analytics: Revenue"
117
- assert_includes content, "Views"
118
- assert_includes content, "Controls"
119
- assert_includes content, "Width:"
120
- end
121
- end
122
-
123
- def test_direction_toggle
124
- with_test_terminal do
125
- # Switch to horizontal (v) then quit
126
- inject_keys(:v, :q)
127
- @app.run
128
-
129
- assert buffer_content.any? { |line| line.include?("v: Direction (horizontal)") }
130
- end
131
- end
132
- end
@@ -1,63 +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
- # A demo showing Block padding capabilities
10
- class BlockPaddingApp
11
- def run
12
- RatatuiRuby.run do |tui|
13
- loop do
14
- # 1. Uniform Padding
15
- block1 = RatatuiRuby::Block.new(
16
- title: "Uniform Padding (2)",
17
- borders: [:all],
18
- padding: 2
19
- )
20
- para1 = RatatuiRuby::Paragraph.new(
21
- text: "This text is padded by 2 on all sides.\nNotice the space between the border and this text.",
22
- block: block1
23
- )
24
-
25
- # 2. Directional Padding
26
- block2 = RatatuiRuby::Block.new(
27
- title: "Directional Padding [Left: 4, Right: 0, Top: 2, Bottom: 0]",
28
- borders: [:all],
29
- padding: [4, 0, 2, 0]
30
- )
31
- para2 = RatatuiRuby::Paragraph.new(
32
- text: "This text has different padding per side.\nLeft: 4, Top: 2.",
33
- block: block2
34
- )
35
-
36
- # Instructions
37
- para3 = RatatuiRuby::Paragraph.new(
38
- text: "Press 'q' to quit."
39
- )
40
-
41
- # Layout
42
- layout = RatatuiRuby::Layout.new(
43
- direction: :vertical,
44
- constraints: [
45
- RatatuiRuby::Constraint.length(10), # Uniform Padding
46
- RatatuiRuby::Constraint.length(10), # Directional Padding
47
- RatatuiRuby::Constraint.min(0)
48
- ],
49
- children: [para1, para2, para3]
50
- )
51
-
52
- tui.draw(layout)
53
-
54
- event = tui.poll_event
55
- break if event == "q" || event == :ctrl_c
56
- end
57
- end
58
- end
59
- end
60
-
61
- if __FILE__ == $0
62
- BlockPaddingApp.new.run
63
- end
@@ -1,7 +0,0 @@
1
- class BlockPaddingApp
2
- # @public
3
- def self.new: () -> BlockPaddingApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,31 +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 TestBlockPadding < Minitest::Test
13
- include RatatuiRuby::TestHelper
14
-
15
- def setup
16
- @app = BlockPaddingApp.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, "Uniform Padding (2)"
26
- assert_includes content, "This text is padded by 2 on all sides."
27
- assert_includes content, "Directional Padding [Left: 4, Right: 0, Top: 2, Bottom: 0]"
28
- assert_includes content, "Left: 4, Top: 2."
29
- end
30
- end
31
- end
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
4
- require "ratatui_ruby"
5
-
6
- # Initialize the terminal
7
- class BlockTitlesApp
8
- def run
9
- RatatuiRuby.run do |tui|
10
- loop do
11
- # Create a layout with multiple blocks demonstrating titles
12
- blocks = [
13
- tui.block(
14
- titles: [
15
- { content: "Top Left", alignment: :left, position: :top },
16
- { content: "Top Right", alignment: :right, position: :top }
17
- ],
18
- borders: [:all],
19
- border_color: "cyan"
20
- ),
21
- tui.block(
22
- titles: [
23
- { content: "Bottom Left", alignment: :left, position: :bottom },
24
- { content: "Bottom Center", alignment: :center, position: :bottom },
25
- { content: "Bottom Right", alignment: :right, position: :bottom }
26
- ],
27
- borders: [:all],
28
- border_color: "magenta"
29
- ),
30
- tui.block(
31
- titles: [
32
- "Simple String Title (Top Left Default)",
33
- { content: "Mixed Title", alignment: :center, position: :bottom }
34
- ],
35
- borders: [:all],
36
- border_color: "green"
37
- )
38
- ]
39
-
40
- layout = tui.layout(
41
- direction: :vertical,
42
- constraints: [
43
- tui.constraint(:length, 10),
44
- tui.constraint(:length, 10),
45
- tui.constraint(:length, 10)
46
- ],
47
- children: blocks
48
- )
49
-
50
- tui.draw(layout)
51
-
52
- event = tui.poll_event
53
- break if event == "q" || event == :ctrl_c
54
- end
55
- end
56
- end
57
- end
58
-
59
- if __FILE__ == $0
60
- BlockTitlesApp.new.run
61
- end
@@ -1,7 +0,0 @@
1
- class BlockTitlesApp
2
- # @public
3
- def self.new: () -> BlockTitlesApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,34 +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 TestBlockTitles < Minitest::Test
13
- include RatatuiRuby::TestHelper
14
-
15
- def setup
16
- @app = BlockTitlesApp.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, "Top Left"
26
- assert_includes content, "Top Right"
27
- assert_includes content, "Bottom Left"
28
- assert_includes content, "Bottom Center"
29
- assert_includes content, "Bottom Right"
30
- assert_includes content, "Simple String Title (Top Left Default)"
31
- assert_includes content, "Mixed Title"
32
- end
33
- end
34
- end
@@ -1,7 +0,0 @@
1
- class BoxDemoApp
2
- # @public
3
- def self.new: () -> BoxDemoApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,88 +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 TestBoxDemo < Minitest::Test
13
- include RatatuiRuby::TestHelper
14
-
15
- def setup
16
- @app = BoxDemoApp.new
17
- end
18
-
19
- def test_render_initial_state
20
- with_test_terminal do
21
- inject_key(:q)
22
- @app.run
23
-
24
- assert buffer_content.any? { |line| line.include?("Box Demo") }
25
- assert buffer_content.any? { |line| line.include?("Controls") }
26
- assert buffer_content.any? { |line| line.include?("Green") }
27
- end
28
- end
29
-
30
- def test_color_cycling_changes_color
31
- with_test_terminal do
32
- # Pressing up should cycle colors backwards
33
- inject_keys(:up, :q)
34
- @app.run
35
-
36
- # At least the Controls section should be rendered
37
- assert buffer_content.any? { |line| line.include?("Controls") }
38
- end
39
- end
40
-
41
- def test_border_type_cycling
42
- with_test_terminal do
43
- inject_keys(" ", :q)
44
- @app.run
45
-
46
- assert buffer_content.any? { |line| line.include?("Rounded") }
47
- end
48
- end
49
-
50
- def test_title_alignment_cycling
51
- with_test_terminal do
52
- inject_keys(:enter, :q)
53
- @app.run
54
-
55
- assert buffer_content.any? { |line| line.include?("Center") }
56
- end
57
- end
58
-
59
- def test_content_style_changes
60
- with_test_terminal do
61
- inject_keys(:s, :q)
62
- @app.run
63
-
64
- # At least the Controls section should be rendered
65
- assert buffer_content.any? { |line| line.include?("Controls") }
66
- end
67
- end
68
-
69
- def test_title_style_changes
70
- with_test_terminal do
71
- inject_keys(:t, :q)
72
- @app.run
73
-
74
- # At least the Controls section should be rendered
75
- assert buffer_content.any? { |line| line.include?("Controls") }
76
- end
77
- end
78
-
79
- def test_border_style_cycling
80
- with_test_terminal do
81
- inject_keys(:b, :q)
82
- @app.run
83
-
84
- # At least the Controls section should be rendered
85
- assert buffer_content.any? { |line| line.include?("Controls") }
86
- end
87
- end
88
- end
@@ -1,101 +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
- # A demo application for the Calendar widget.
10
- class CalendarDemoApp
11
- def run
12
- RatatuiRuby.run do
13
- show_header = true
14
- show_weekdays = true
15
- show_surrounding = false
16
- show_events = true
17
-
18
- loop do
19
- now = Time.now
20
- surrounding_style = if show_surrounding
21
- RatatuiRuby::Style.new(fg: "gray", modifiers: [:dim])
22
- else
23
- nil
24
- end
25
-
26
- events_map = if show_events
27
- {
28
- now => RatatuiRuby::Style.new(fg: "green", modifiers: [:bold]),
29
- (now + 86400 * 2) => RatatuiRuby::Style.new(fg: "red", modifiers: [:underlined]),
30
- (now - 86400 * 5) => RatatuiRuby::Style.new(fg: "blue", bg: "white"),
31
- }
32
- else
33
- {}
34
- end
35
-
36
- calendar = RatatuiRuby::Calendar.new(
37
- year: now.year,
38
- month: now.month,
39
- events: events_map,
40
- header_style: RatatuiRuby::Style.new(fg: "yellow", modifiers: [:bold]),
41
- show_month_header: show_header,
42
- show_weekdays_header: show_weekdays,
43
- show_surrounding: surrounding_style,
44
- block: RatatuiRuby::Block.new(borders: [:top, :left, :right])
45
- )
46
-
47
- controls_text = [
48
- RatatuiRuby::Text::Line.new(
49
- spans: [
50
- RatatuiRuby::Text::Span.new(content: " h/w/s/e", style: RatatuiRuby::Style.new(modifiers: [:bold])),
51
- RatatuiRuby::Text::Span.new(content: ": Toggle Header/Weekdays/Surrounding/Events "),
52
- RatatuiRuby::Text::Span.new(content: "q", style: RatatuiRuby::Style.new(modifiers: [:bold])),
53
- RatatuiRuby::Text::Span.new(content: ": Quit"),
54
- ]
55
- ),
56
- RatatuiRuby::Text::Line.new(
57
- spans: [
58
- RatatuiRuby::Text::Span.new(content: " Events: ", style: RatatuiRuby::Style.new(modifiers: [:bold])),
59
- RatatuiRuby::Text::Span.new(content: "Today (Green), +2d (Red), -5d (Blue) (#{show_events ? "On" : "Off"})"),
60
- ]
61
- )
62
- ]
63
- controls = RatatuiRuby::Paragraph.new(
64
- text: controls_text,
65
- block: RatatuiRuby::Block.new(title: " Controls ", borders: [:all])
66
- )
67
-
68
- RatatuiRuby.draw(
69
- RatatuiRuby::Layout.new(
70
- direction: :vertical,
71
- constraints: [
72
- RatatuiRuby::Constraint.min(0),
73
- RatatuiRuby::Constraint.length(4),
74
- ],
75
- children: [calendar, controls]
76
- )
77
- )
78
-
79
- event = RatatuiRuby.poll_event
80
- case event
81
- in {type: :key, code: "q"} | {type: :key, code: "c", modifiers: ["ctrl"]}
82
- break
83
- in type: :key, code: "h"
84
- show_header = !show_header
85
- in type: :key, code: "w"
86
- show_weekdays = !show_weekdays
87
- in type: :key, code: "s"
88
- show_surrounding = !show_surrounding
89
- in type: :key, code: "e"
90
- show_events = !show_events
91
- else
92
- nil
93
- end
94
-
95
- sleep 0.05
96
- end
97
- end
98
- end
99
- end
100
-
101
- CalendarDemoApp.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,7 +0,0 @@
1
- class CalendarDemoApp
2
- # @public
3
- def self.new: () -> CalendarDemoApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,108 +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 "minitest/autorun"
8
- require "ratatui_ruby"
9
- require "ratatui_ruby/test_helper"
10
- require_relative "app"
11
-
12
- class TestCalendarDemoApp < Minitest::Test
13
- include RatatuiRuby::TestHelper
14
-
15
- def setup
16
- @app = CalendarDemoApp.new
17
- end
18
-
19
- def test_demo_renders
20
- with_test_terminal do
21
- inject_keys(:down, :down, :q)
22
-
23
- @app.run
24
-
25
- content = buffer_content
26
- rendered_text = content.join("\n")
27
-
28
- # Verify the bottom controls are present
29
- assert_match(/h\/w\/s\/e: Toggle Header\/Weekdays\/Surrounding\/Events/, rendered_text)
30
- assert_match(/q: Quit/, rendered_text)
31
-
32
- # Verify the calendar content is present
33
- assert_match(/#{Time.now.year}/, rendered_text)
34
-
35
- # Verify layout structure (calendar taking up most space, controls at bottom)
36
- # The controls are on the last line (index 23 for 24 lines) if the terminal is 24 lines high
37
- # but standard terminal might be different. with_test_terminal defaults to 80x24.
38
- # assert_match(/q: Quit/, content[23]) if content[23]
39
- end
40
- end
41
-
42
- def test_toggle_weekdays_header
43
- with_test_terminal do
44
- inject_keys("w", :q)
45
-
46
- @app.run
47
-
48
- content = buffer_content
49
- rendered_text = content.join("\n")
50
-
51
- # The app should render successfully with weekdays toggled
52
- assert_match(/#{Time.now.year}/, rendered_text)
53
- end
54
- end
55
-
56
- def test_toggle_header
57
- with_test_terminal do
58
- inject_keys("h", :q)
59
-
60
- @app.run
61
-
62
- content = buffer_content
63
- rendered_text = content.join("\n")
64
-
65
- # The app should render successfully with header toggled (hidden)
66
- refute_match(/#{Time.now.year}/, rendered_text)
67
-
68
- # Inject h again to show it (h -> off, h -> on)
69
- inject_keys("h", "h", :q)
70
- @app.run
71
- content = buffer_content
72
- rendered_text = content.join("\n")
73
- assert_match(/#{Time.now.year}/, rendered_text)
74
- end
75
- end
76
-
77
- def test_toggle_surrounding
78
- with_test_terminal do
79
- inject_keys("s", :q)
80
-
81
- @app.run
82
-
83
- content = buffer_content
84
- rendered_text = content.join("\n")
85
-
86
- # The app should render successfully with surrounding toggled
87
- assert_match(/#{Time.now.year}/, rendered_text)
88
- end
89
- end
90
-
91
- def test_events_render
92
- with_test_terminal do
93
- inject_keys("e", :q)
94
-
95
- @app.run
96
-
97
- content = buffer_content
98
- # We just check that the app runs without crashing and renders the calendar.
99
- # Verifying specific color codes in the buffer content is harder without
100
- # exposing the underlying buffer cells' style.
101
- # But we can at least assert the content is still correct.
102
- assert_match(/#{Time.now.year}/, content.join("\n"))
103
-
104
- # Verify the legend is present and shows Off status after toggle
105
- assert_match(/Events: .* \(Off\)/, content.join("\n"))
106
- end
107
- end
108
- end